clawdbot 2026.1.4

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 (503) hide show
  1. package/CHANGELOG.md +115 -0
  2. package/LICENSE +21 -0
  3. package/README-header.png +0 -0
  4. package/README.md +297 -0
  5. package/dist/agents/agent-paths.js +17 -0
  6. package/dist/agents/bash-process-registry.js +126 -0
  7. package/dist/agents/bash-tools.js +837 -0
  8. package/dist/agents/clawdbot-tools.js +30 -0
  9. package/dist/agents/clawdis-tools.js +27 -0
  10. package/dist/agents/context.js +34 -0
  11. package/dist/agents/defaults.js +6 -0
  12. package/dist/agents/model-auth.js +112 -0
  13. package/dist/agents/model-catalog.js +55 -0
  14. package/dist/agents/model-fallback.js +191 -0
  15. package/dist/agents/model-scan.js +263 -0
  16. package/dist/agents/model-selection.js +116 -0
  17. package/dist/agents/models-config.js +49 -0
  18. package/dist/agents/pi-embedded-helpers.js +74 -0
  19. package/dist/agents/pi-embedded-runner.js +407 -0
  20. package/dist/agents/pi-embedded-subscribe.js +568 -0
  21. package/dist/agents/pi-embedded-utils.js +20 -0
  22. package/dist/agents/pi-embedded.js +1 -0
  23. package/dist/agents/pi-oauth.js +88 -0
  24. package/dist/agents/pi-tools.js +433 -0
  25. package/dist/agents/sandbox-paths.js +68 -0
  26. package/dist/agents/sandbox.js +644 -0
  27. package/dist/agents/shell-utils.js +53 -0
  28. package/dist/agents/skills-install.js +244 -0
  29. package/dist/agents/skills-status.js +157 -0
  30. package/dist/agents/skills.js +470 -0
  31. package/dist/agents/steerable-agent-loop.js +338 -0
  32. package/dist/agents/steerable-provider-transport.js +48 -0
  33. package/dist/agents/system-prompt.js +104 -0
  34. package/dist/agents/tool-display.js +162 -0
  35. package/dist/agents/tool-images.js +138 -0
  36. package/dist/agents/tools/browser-tool.js +339 -0
  37. package/dist/agents/tools/canvas-tool.js +193 -0
  38. package/dist/agents/tools/common.js +88 -0
  39. package/dist/agents/tools/cron-tool.js +124 -0
  40. package/dist/agents/tools/discord-actions-guild.js +186 -0
  41. package/dist/agents/tools/discord-actions-messaging.js +285 -0
  42. package/dist/agents/tools/discord-actions-moderation.js +70 -0
  43. package/dist/agents/tools/discord-actions.js +56 -0
  44. package/dist/agents/tools/discord-schema.js +199 -0
  45. package/dist/agents/tools/discord-tool.js +16 -0
  46. package/dist/agents/tools/gateway-tool.js +46 -0
  47. package/dist/agents/tools/gateway.js +27 -0
  48. package/dist/agents/tools/image-tool.js +132 -0
  49. package/dist/agents/tools/nodes-tool.js +413 -0
  50. package/dist/agents/tools/nodes-utils.js +92 -0
  51. package/dist/agents/tools/sessions-helpers.js +88 -0
  52. package/dist/agents/tools/sessions-history-tool.js +53 -0
  53. package/dist/agents/tools/sessions-list-tool.js +143 -0
  54. package/dist/agents/tools/sessions-send-helpers.js +100 -0
  55. package/dist/agents/tools/sessions-send-tool.js +347 -0
  56. package/dist/agents/tools/slack-actions.js +129 -0
  57. package/dist/agents/tools/slack-schema.js +59 -0
  58. package/dist/agents/tools/slack-tool.js +16 -0
  59. package/dist/agents/usage.js +39 -0
  60. package/dist/agents/workspace.js +241 -0
  61. package/dist/auto-reply/chunk.js +76 -0
  62. package/dist/auto-reply/envelope.js +38 -0
  63. package/dist/auto-reply/group-activation.js +20 -0
  64. package/dist/auto-reply/heartbeat.js +57 -0
  65. package/dist/auto-reply/model.js +14 -0
  66. package/dist/auto-reply/reply/abort.js +14 -0
  67. package/dist/auto-reply/reply/agent-runner.js +371 -0
  68. package/dist/auto-reply/reply/block-streaming.js +34 -0
  69. package/dist/auto-reply/reply/body.js +29 -0
  70. package/dist/auto-reply/reply/commands.js +207 -0
  71. package/dist/auto-reply/reply/directive-handling.js +361 -0
  72. package/dist/auto-reply/reply/directives.js +47 -0
  73. package/dist/auto-reply/reply/followup-runner.js +149 -0
  74. package/dist/auto-reply/reply/groups.js +91 -0
  75. package/dist/auto-reply/reply/mentions.js +38 -0
  76. package/dist/auto-reply/reply/model-selection.js +114 -0
  77. package/dist/auto-reply/reply/queue.js +399 -0
  78. package/dist/auto-reply/reply/reply-tags.js +26 -0
  79. package/dist/auto-reply/reply/session-updates.js +87 -0
  80. package/dist/auto-reply/reply/session.js +160 -0
  81. package/dist/auto-reply/reply/typing.js +75 -0
  82. package/dist/auto-reply/reply.js +535 -0
  83. package/dist/auto-reply/send-policy.js +28 -0
  84. package/dist/auto-reply/status.js +158 -0
  85. package/dist/auto-reply/templating.js +9 -0
  86. package/dist/auto-reply/thinking.js +49 -0
  87. package/dist/auto-reply/tokens.js +2 -0
  88. package/dist/auto-reply/tool-meta.js +74 -0
  89. package/dist/auto-reply/transcription.js +57 -0
  90. package/dist/auto-reply/types.js +1 -0
  91. package/dist/browser/bridge-server.js +37 -0
  92. package/dist/browser/cdp.js +382 -0
  93. package/dist/browser/chrome.js +432 -0
  94. package/dist/browser/client-actions-core.js +67 -0
  95. package/dist/browser/client-actions-observe.js +24 -0
  96. package/dist/browser/client-actions-types.js +1 -0
  97. package/dist/browser/client-actions.js +3 -0
  98. package/dist/browser/client-fetch.js +43 -0
  99. package/dist/browser/client.js +105 -0
  100. package/dist/browser/config.js +140 -0
  101. package/dist/browser/constants.js +4 -0
  102. package/dist/browser/profiles-service.js +122 -0
  103. package/dist/browser/profiles.js +85 -0
  104. package/dist/browser/pw-ai.js +2 -0
  105. package/dist/browser/pw-session.js +144 -0
  106. package/dist/browser/pw-tools-core.js +363 -0
  107. package/dist/browser/routes/agent.js +535 -0
  108. package/dist/browser/routes/basic.js +155 -0
  109. package/dist/browser/routes/index.js +8 -0
  110. package/dist/browser/routes/tabs.js +105 -0
  111. package/dist/browser/routes/utils.js +62 -0
  112. package/dist/browser/screenshot.js +40 -0
  113. package/dist/browser/server-context.js +377 -0
  114. package/dist/browser/server.js +81 -0
  115. package/dist/browser/target-id.js +18 -0
  116. package/dist/browser/trash.js +21 -0
  117. package/dist/canvas-host/a2ui/.bundle.hash +1 -0
  118. package/dist/canvas-host/a2ui/a2ui.bundle.js +17768 -0
  119. package/dist/canvas-host/a2ui/index.html +246 -0
  120. package/dist/canvas-host/a2ui.js +187 -0
  121. package/dist/canvas-host/server.js +382 -0
  122. package/dist/cli/browser-cli-actions-input.js +459 -0
  123. package/dist/cli/browser-cli-actions-observe.js +56 -0
  124. package/dist/cli/browser-cli-examples.js +31 -0
  125. package/dist/cli/browser-cli-inspect.js +97 -0
  126. package/dist/cli/browser-cli-manage.js +286 -0
  127. package/dist/cli/browser-cli-shared.js +1 -0
  128. package/dist/cli/browser-cli.js +26 -0
  129. package/dist/cli/canvas-cli.js +416 -0
  130. package/dist/cli/cron-cli.js +454 -0
  131. package/dist/cli/deps.js +17 -0
  132. package/dist/cli/dns-cli.js +180 -0
  133. package/dist/cli/gateway-cli.js +489 -0
  134. package/dist/cli/gateway-rpc.js +20 -0
  135. package/dist/cli/hooks-cli.js +135 -0
  136. package/dist/cli/models-cli.js +248 -0
  137. package/dist/cli/nodes-camera.js +57 -0
  138. package/dist/cli/nodes-canvas.js +26 -0
  139. package/dist/cli/nodes-cli.js +946 -0
  140. package/dist/cli/nodes-screen.js +37 -0
  141. package/dist/cli/parse-duration.js +20 -0
  142. package/dist/cli/ports.js +97 -0
  143. package/dist/cli/program.js +406 -0
  144. package/dist/cli/prompt.js +19 -0
  145. package/dist/cli/tui-cli.js +35 -0
  146. package/dist/cli/wait.js +8 -0
  147. package/dist/commands/agent.js +645 -0
  148. package/dist/commands/antigravity-oauth.js +327 -0
  149. package/dist/commands/configure.js +480 -0
  150. package/dist/commands/doctor.js +484 -0
  151. package/dist/commands/health.js +108 -0
  152. package/dist/commands/models/aliases.js +64 -0
  153. package/dist/commands/models/fallbacks.js +99 -0
  154. package/dist/commands/models/image-fallbacks.js +99 -0
  155. package/dist/commands/models/list.js +323 -0
  156. package/dist/commands/models/scan.js +266 -0
  157. package/dist/commands/models/set-image.js +23 -0
  158. package/dist/commands/models/set.js +23 -0
  159. package/dist/commands/models/shared.js +72 -0
  160. package/dist/commands/models.js +7 -0
  161. package/dist/commands/onboard-auth.js +70 -0
  162. package/dist/commands/onboard-helpers.js +295 -0
  163. package/dist/commands/onboard-interactive.js +17 -0
  164. package/dist/commands/onboard-non-interactive.js +202 -0
  165. package/dist/commands/onboard-providers.js +634 -0
  166. package/dist/commands/onboard-remote.js +120 -0
  167. package/dist/commands/onboard-skills.js +148 -0
  168. package/dist/commands/onboard-types.js +1 -0
  169. package/dist/commands/onboard.js +12 -0
  170. package/dist/commands/send.js +124 -0
  171. package/dist/commands/sessions.js +212 -0
  172. package/dist/commands/setup.js +58 -0
  173. package/dist/commands/signal-install.js +135 -0
  174. package/dist/commands/status.js +207 -0
  175. package/dist/commands/update.js +16 -0
  176. package/dist/config/config.js +6 -0
  177. package/dist/config/defaults.js +61 -0
  178. package/dist/config/io.js +147 -0
  179. package/dist/config/legacy-migrate.js +13 -0
  180. package/dist/config/legacy.js +159 -0
  181. package/dist/config/paths.js +71 -0
  182. package/dist/config/schema.js +150 -0
  183. package/dist/config/sessions.js +282 -0
  184. package/dist/config/talk.js +31 -0
  185. package/dist/config/types.js +1 -0
  186. package/dist/config/validation.js +29 -0
  187. package/dist/config/zod-schema.js +831 -0
  188. package/dist/cron/isolated-agent.js +499 -0
  189. package/dist/cron/run-log.js +72 -0
  190. package/dist/cron/schedule.js +24 -0
  191. package/dist/cron/service.js +471 -0
  192. package/dist/cron/store.js +43 -0
  193. package/dist/cron/types.js +1 -0
  194. package/dist/discord/index.js +2 -0
  195. package/dist/discord/monitor.js +1188 -0
  196. package/dist/discord/probe.js +54 -0
  197. package/dist/discord/send.js +577 -0
  198. package/dist/discord/token.js +8 -0
  199. package/dist/gateway/auth.js +121 -0
  200. package/dist/gateway/call.js +94 -0
  201. package/dist/gateway/chat-attachments.js +41 -0
  202. package/dist/gateway/client.js +180 -0
  203. package/dist/gateway/config-reload.js +274 -0
  204. package/dist/gateway/control-ui.js +184 -0
  205. package/dist/gateway/hooks-mapping.js +282 -0
  206. package/dist/gateway/hooks.js +168 -0
  207. package/dist/gateway/net.js +29 -0
  208. package/dist/gateway/protocol/index.js +61 -0
  209. package/dist/gateway/protocol/schema.js +560 -0
  210. package/dist/gateway/server-bridge-subscriptions.js +93 -0
  211. package/dist/gateway/server-bridge.js +1013 -0
  212. package/dist/gateway/server-browser.js +12 -0
  213. package/dist/gateway/server-chat.js +159 -0
  214. package/dist/gateway/server-constants.js +8 -0
  215. package/dist/gateway/server-discovery.js +62 -0
  216. package/dist/gateway/server-http.js +165 -0
  217. package/dist/gateway/server-methods/agent-job.js +125 -0
  218. package/dist/gateway/server-methods/agent.js +250 -0
  219. package/dist/gateway/server-methods/chat.js +200 -0
  220. package/dist/gateway/server-methods/config.js +50 -0
  221. package/dist/gateway/server-methods/connect.js +6 -0
  222. package/dist/gateway/server-methods/cron.js +83 -0
  223. package/dist/gateway/server-methods/health.js +28 -0
  224. package/dist/gateway/server-methods/models.js +16 -0
  225. package/dist/gateway/server-methods/nodes.js +294 -0
  226. package/dist/gateway/server-methods/providers.js +217 -0
  227. package/dist/gateway/server-methods/send.js +166 -0
  228. package/dist/gateway/server-methods/sessions.js +305 -0
  229. package/dist/gateway/server-methods/skills.js +83 -0
  230. package/dist/gateway/server-methods/system.js +118 -0
  231. package/dist/gateway/server-methods/talk.js +22 -0
  232. package/dist/gateway/server-methods/types.js +1 -0
  233. package/dist/gateway/server-methods/voicewake.js +30 -0
  234. package/dist/gateway/server-methods/web.js +58 -0
  235. package/dist/gateway/server-methods/wizard.js +100 -0
  236. package/dist/gateway/server-methods.js +53 -0
  237. package/dist/gateway/server-providers.js +644 -0
  238. package/dist/gateway/server-shared.js +1 -0
  239. package/dist/gateway/server-utils.js +35 -0
  240. package/dist/gateway/server.js +1437 -0
  241. package/dist/gateway/session-utils.js +216 -0
  242. package/dist/gateway/ws-log.js +349 -0
  243. package/dist/gateway/ws-logging.js +8 -0
  244. package/dist/globals.js +41 -0
  245. package/dist/hooks/gmail-ops.js +236 -0
  246. package/dist/hooks/gmail-setup-utils.js +278 -0
  247. package/dist/hooks/gmail-watcher.js +175 -0
  248. package/dist/hooks/gmail.js +177 -0
  249. package/dist/index.js +50 -0
  250. package/dist/infra/agent-events.js +46 -0
  251. package/dist/infra/binaries.js +9 -0
  252. package/dist/infra/bonjour-discovery.js +163 -0
  253. package/dist/infra/bonjour.js +200 -0
  254. package/dist/infra/bridge/server.js +562 -0
  255. package/dist/infra/canvas-host-url.js +54 -0
  256. package/dist/infra/env.js +8 -0
  257. package/dist/infra/errors.js +28 -0
  258. package/dist/infra/gateway-lock.js +8 -0
  259. package/dist/infra/heartbeat-events.js +21 -0
  260. package/dist/infra/heartbeat-runner.js +453 -0
  261. package/dist/infra/heartbeat-wake.js +61 -0
  262. package/dist/infra/is-main.js +37 -0
  263. package/dist/infra/machine-name.js +40 -0
  264. package/dist/infra/node-pairing.js +211 -0
  265. package/dist/infra/pam.js +42 -0
  266. package/dist/infra/path-env.js +92 -0
  267. package/dist/infra/ports.js +87 -0
  268. package/dist/infra/provider-summary.js +80 -0
  269. package/dist/infra/restart.js +29 -0
  270. package/dist/infra/retry.js +16 -0
  271. package/dist/infra/runtime-guard.js +59 -0
  272. package/dist/infra/system-events.js +44 -0
  273. package/dist/infra/system-presence.js +216 -0
  274. package/dist/infra/tailnet.js +46 -0
  275. package/dist/infra/tailscale.js +149 -0
  276. package/dist/infra/voicewake.js +77 -0
  277. package/dist/infra/widearea-dns.js +123 -0
  278. package/dist/infra/ws.js +13 -0
  279. package/dist/logger.js +52 -0
  280. package/dist/logging.js +490 -0
  281. package/dist/macos/gateway-daemon.js +141 -0
  282. package/dist/macos/relay.js +46 -0
  283. package/dist/media/constants.js +33 -0
  284. package/dist/media/host.js +42 -0
  285. package/dist/media/image-ops.js +121 -0
  286. package/dist/media/mime.js +115 -0
  287. package/dist/media/parse.js +81 -0
  288. package/dist/media/server.js +64 -0
  289. package/dist/media/store.js +139 -0
  290. package/dist/process/command-queue.js +97 -0
  291. package/dist/process/exec.js +75 -0
  292. package/dist/protocol.schema.json +2918 -0
  293. package/dist/provider-web.js +8 -0
  294. package/dist/providers/web/index.js +2 -0
  295. package/dist/runtime.js +8 -0
  296. package/dist/telegram/bot.js +394 -0
  297. package/dist/telegram/download.js +34 -0
  298. package/dist/telegram/index.js +4 -0
  299. package/dist/telegram/monitor.js +47 -0
  300. package/dist/telegram/probe.js +63 -0
  301. package/dist/telegram/proxy.js +9 -0
  302. package/dist/telegram/send.js +138 -0
  303. package/dist/telegram/token.js +30 -0
  304. package/dist/telegram/webhook-set.js +12 -0
  305. package/dist/telegram/webhook.js +56 -0
  306. package/dist/utils.js +133 -0
  307. package/dist/version.js +18 -0
  308. package/dist/web/active-listener.js +7 -0
  309. package/dist/web/auto-reply.js +1203 -0
  310. package/dist/web/inbound.js +481 -0
  311. package/dist/web/login-qr.js +204 -0
  312. package/dist/web/login.js +59 -0
  313. package/dist/web/media.js +148 -0
  314. package/dist/web/outbound.js +67 -0
  315. package/dist/web/qr-image.js +97 -0
  316. package/dist/web/reconnect.js +60 -0
  317. package/dist/web/reply-heartbeat-wake.js +61 -0
  318. package/dist/web/session.js +346 -0
  319. package/docs/AGENTS.default.md +116 -0
  320. package/docs/CNAME +1 -0
  321. package/docs/RELEASING.md +64 -0
  322. package/docs/_config.yml +51 -0
  323. package/docs/_layouts/default.html +145 -0
  324. package/docs/agent-send.md +21 -0
  325. package/docs/agent.md +104 -0
  326. package/docs/android/connect.md +131 -0
  327. package/docs/architecture.md +89 -0
  328. package/docs/assets/markdown.css +130 -0
  329. package/docs/assets/pixel-lobster.svg +60 -0
  330. package/docs/assets/terminal.css +497 -0
  331. package/docs/assets/theme.js +55 -0
  332. package/docs/audio.md +50 -0
  333. package/docs/background-process.md +74 -0
  334. package/docs/bash.md +32 -0
  335. package/docs/bonjour.md +159 -0
  336. package/docs/browser.md +289 -0
  337. package/docs/camera.md +152 -0
  338. package/docs/clawd.md +199 -0
  339. package/docs/clawdbot-mac.md +104 -0
  340. package/docs/configuration.md +1177 -0
  341. package/docs/control-api.md +49 -0
  342. package/docs/control-ui.md +83 -0
  343. package/docs/cron.md +374 -0
  344. package/docs/dashboard.md +17 -0
  345. package/docs/device-models.md +46 -0
  346. package/docs/discord.md +293 -0
  347. package/docs/discovery.md +112 -0
  348. package/docs/docker.md +251 -0
  349. package/docs/docs.json +86 -0
  350. package/docs/doctor.md +47 -0
  351. package/docs/elevated.md +31 -0
  352. package/docs/faq.md +640 -0
  353. package/docs/gateway/pairing.md +109 -0
  354. package/docs/gateway-lock.md +28 -0
  355. package/docs/gateway.md +174 -0
  356. package/docs/gmail-pubsub.md +191 -0
  357. package/docs/grammy.md +27 -0
  358. package/docs/group-messages.md +71 -0
  359. package/docs/groups.md +78 -0
  360. package/docs/health.md +28 -0
  361. package/docs/heartbeat.md +64 -0
  362. package/docs/images.md +52 -0
  363. package/docs/imessage.md +63 -0
  364. package/docs/index.md +182 -0
  365. package/docs/ios/connect.md +177 -0
  366. package/docs/ios/spec.md +236 -0
  367. package/docs/location-command.md +95 -0
  368. package/docs/logging.md +99 -0
  369. package/docs/lore.md +131 -0
  370. package/docs/mac/bun.md +133 -0
  371. package/docs/mac/canvas.md +161 -0
  372. package/docs/mac/child-process.md +72 -0
  373. package/docs/mac/dev-setup.md +81 -0
  374. package/docs/mac/health.md +28 -0
  375. package/docs/mac/icon.md +26 -0
  376. package/docs/mac/logging.md +51 -0
  377. package/docs/mac/menu-bar.md +69 -0
  378. package/docs/mac/peekaboo.md +170 -0
  379. package/docs/mac/permissions.md +40 -0
  380. package/docs/mac/release.md +76 -0
  381. package/docs/mac/remote.md +57 -0
  382. package/docs/mac/signing.md +41 -0
  383. package/docs/mac/skills.md +27 -0
  384. package/docs/mac/voice-overlay.md +52 -0
  385. package/docs/mac/voicewake.md +56 -0
  386. package/docs/mac/webchat.md +27 -0
  387. package/docs/mac/xpc.md +40 -0
  388. package/docs/models.md +90 -0
  389. package/docs/nix.md +49 -0
  390. package/docs/nodes.md +157 -0
  391. package/docs/onboarding-config-protocol.md +29 -0
  392. package/docs/onboarding.md +185 -0
  393. package/docs/presence.md +133 -0
  394. package/docs/queue.md +78 -0
  395. package/docs/refactor/browser-control-simplification.md +58 -0
  396. package/docs/refactor/canvas-a2ui.md +93 -0
  397. package/docs/refactor/cli-unification.md +64 -0
  398. package/docs/refactor/gateway-client.md +31 -0
  399. package/docs/refactor/gateway.md +99 -0
  400. package/docs/refactor/new-arch.md +171 -0
  401. package/docs/refactor/tui.md +26 -0
  402. package/docs/refactor/web-gateway-troubleshooting.md +37 -0
  403. package/docs/refactor/webagent-session.md +46 -0
  404. package/docs/remote-gateway-readme.md +148 -0
  405. package/docs/remote.md +66 -0
  406. package/docs/research/memory.md +227 -0
  407. package/docs/rpc.md +35 -0
  408. package/docs/security.md +168 -0
  409. package/docs/session-tool.md +119 -0
  410. package/docs/session.md +84 -0
  411. package/docs/sessions.md +8 -0
  412. package/docs/setup.md +118 -0
  413. package/docs/signal.md +113 -0
  414. package/docs/skills-config.md +58 -0
  415. package/docs/skills.md +149 -0
  416. package/docs/slack.md +158 -0
  417. package/docs/surface.md +20 -0
  418. package/docs/tailscale.md +71 -0
  419. package/docs/talk.md +79 -0
  420. package/docs/telegram.md +90 -0
  421. package/docs/templates/AGENTS.md +126 -0
  422. package/docs/templates/BOOTSTRAP.md +53 -0
  423. package/docs/templates/IDENTITY.md +17 -0
  424. package/docs/templates/SOUL.md +41 -0
  425. package/docs/templates/TOOLS.md +41 -0
  426. package/docs/templates/USER.md +22 -0
  427. package/docs/test.md +35 -0
  428. package/docs/thinking.md +46 -0
  429. package/docs/tools.md +248 -0
  430. package/docs/troubleshooting.md +227 -0
  431. package/docs/tui.md +69 -0
  432. package/docs/typebox.md +42 -0
  433. package/docs/voicewake.md +61 -0
  434. package/docs/web.md +115 -0
  435. package/docs/webchat.md +34 -0
  436. package/docs/webhook.md +132 -0
  437. package/docs/whatsapp-clawd.jpg +0 -0
  438. package/docs/whatsapp.md +142 -0
  439. package/docs/wizard.md +158 -0
  440. package/package.json +178 -0
  441. package/skills/apple-notes/SKILL.md +50 -0
  442. package/skills/apple-reminders/SKILL.md +67 -0
  443. package/skills/bear-notes/SKILL.md +79 -0
  444. package/skills/bird/SKILL.md +25 -0
  445. package/skills/blogwatcher/SKILL.md +46 -0
  446. package/skills/blucli/SKILL.md +27 -0
  447. package/skills/brave-search/SKILL.md +30 -0
  448. package/skills/brave-search/scripts/content.mjs +53 -0
  449. package/skills/brave-search/scripts/search.mjs +79 -0
  450. package/skills/camsnap/SKILL.md +25 -0
  451. package/skills/clawdhub/SKILL.md +53 -0
  452. package/skills/coding-agent/SKILL.md +275 -0
  453. package/skills/discord/SKILL.md +369 -0
  454. package/skills/eightctl/SKILL.md +29 -0
  455. package/skills/food-order/SKILL.md +41 -0
  456. package/skills/gemini/SKILL.md +23 -0
  457. package/skills/gifgrep/SKILL.md +47 -0
  458. package/skills/github/SKILL.md +47 -0
  459. package/skills/gog/SKILL.md +36 -0
  460. package/skills/goplaces/SKILL.md +30 -0
  461. package/skills/imsg/SKILL.md +25 -0
  462. package/skills/local-places/SERVER_README.md +101 -0
  463. package/skills/local-places/SKILL.md +91 -0
  464. package/skills/local-places/pyproject.toml +27 -0
  465. package/skills/local-places/src/local_places/__init__.py +2 -0
  466. package/skills/local-places/src/local_places/__pycache__/__init__.cpython-314.pyc +0 -0
  467. package/skills/local-places/src/local_places/__pycache__/google_places.cpython-314.pyc +0 -0
  468. package/skills/local-places/src/local_places/__pycache__/main.cpython-314.pyc +0 -0
  469. package/skills/local-places/src/local_places/__pycache__/schemas.cpython-314.pyc +0 -0
  470. package/skills/local-places/src/local_places/google_places.py +314 -0
  471. package/skills/local-places/src/local_places/main.py +65 -0
  472. package/skills/local-places/src/local_places/schemas.py +107 -0
  473. package/skills/mcporter/SKILL.md +38 -0
  474. package/skills/nano-banana-pro/SKILL.md +29 -0
  475. package/skills/nano-banana-pro/scripts/generate_image.py +167 -0
  476. package/skills/nano-pdf/SKILL.md +20 -0
  477. package/skills/notion/SKILL.md +156 -0
  478. package/skills/obsidian/SKILL.md +55 -0
  479. package/skills/openai-image-gen/SKILL.md +31 -0
  480. package/skills/openai-image-gen/scripts/gen.py +173 -0
  481. package/skills/openai-whisper/SKILL.md +19 -0
  482. package/skills/openai-whisper-api/SKILL.md +43 -0
  483. package/skills/openai-whisper-api/scripts/transcribe.sh +85 -0
  484. package/skills/openhue/SKILL.md +30 -0
  485. package/skills/oracle/SKILL.md +105 -0
  486. package/skills/ordercli/SKILL.md +47 -0
  487. package/skills/peekaboo/SKILL.md +153 -0
  488. package/skills/qmd/SKILL.md +26 -0
  489. package/skills/sag/SKILL.md +62 -0
  490. package/skills/slack/SKILL.md +143 -0
  491. package/skills/songsee/SKILL.md +29 -0
  492. package/skills/sonoscli/SKILL.md +26 -0
  493. package/skills/spotify-player/SKILL.md +34 -0
  494. package/skills/summarize/SKILL.md +49 -0
  495. package/skills/things-mac/SKILL.md +61 -0
  496. package/skills/tmux/SKILL.md +121 -0
  497. package/skills/tmux/scripts/find-sessions.sh +112 -0
  498. package/skills/tmux/scripts/wait-for-text.sh +83 -0
  499. package/skills/trello/SKILL.md +84 -0
  500. package/skills/video-frames/SKILL.md +29 -0
  501. package/skills/video-frames/scripts/frame.sh +81 -0
  502. package/skills/wacli/SKILL.md +42 -0
  503. package/skills/weather/SKILL.md +49 -0
@@ -0,0 +1,568 @@
1
+ import { formatToolAggregate } from "../auto-reply/tool-meta.js";
2
+ import { emitAgentEvent } from "../infra/agent-events.js";
3
+ import { createSubsystemLogger } from "../logging.js";
4
+ import { splitMediaFromOutput } from "../media/parse.js";
5
+ import { extractAssistantText, inferToolMetaFromArgs, } from "./pi-embedded-utils.js";
6
+ const THINKING_TAG_RE = /<\s*\/?\s*think(?:ing)?\s*>/gi;
7
+ const THINKING_OPEN_RE = /<\s*think(?:ing)?\s*>/i;
8
+ const THINKING_CLOSE_RE = /<\s*\/\s*think(?:ing)?\s*>/i;
9
+ const TOOL_RESULT_MAX_CHARS = 8000;
10
+ const log = createSubsystemLogger("agent/embedded");
11
+ function truncateToolText(text) {
12
+ if (text.length <= TOOL_RESULT_MAX_CHARS)
13
+ return text;
14
+ return `${text.slice(0, TOOL_RESULT_MAX_CHARS)}\n…(truncated)…`;
15
+ }
16
+ function sanitizeToolResult(result) {
17
+ if (!result || typeof result !== "object")
18
+ return result;
19
+ const record = result;
20
+ const content = Array.isArray(record.content) ? record.content : null;
21
+ if (!content)
22
+ return record;
23
+ const sanitized = content.map((item) => {
24
+ if (!item || typeof item !== "object")
25
+ return item;
26
+ const entry = item;
27
+ const type = typeof entry.type === "string" ? entry.type : undefined;
28
+ if (type === "text" && typeof entry.text === "string") {
29
+ return { ...entry, text: truncateToolText(entry.text) };
30
+ }
31
+ if (type === "image") {
32
+ const data = typeof entry.data === "string" ? entry.data : undefined;
33
+ const bytes = data ? data.length : undefined;
34
+ const cleaned = { ...entry };
35
+ delete cleaned.data;
36
+ return { ...cleaned, bytes, omitted: true };
37
+ }
38
+ return entry;
39
+ });
40
+ return { ...record, content: sanitized };
41
+ }
42
+ function stripThinkingSegments(text) {
43
+ if (!text || !THINKING_TAG_RE.test(text))
44
+ return text;
45
+ THINKING_TAG_RE.lastIndex = 0;
46
+ let result = "";
47
+ let lastIndex = 0;
48
+ let inThinking = false;
49
+ for (const match of text.matchAll(THINKING_TAG_RE)) {
50
+ const idx = match.index ?? 0;
51
+ if (!inThinking) {
52
+ result += text.slice(lastIndex, idx);
53
+ }
54
+ const tag = match[0].toLowerCase();
55
+ inThinking = !tag.includes("/");
56
+ lastIndex = idx + match[0].length;
57
+ }
58
+ if (!inThinking) {
59
+ result += text.slice(lastIndex);
60
+ }
61
+ return result;
62
+ }
63
+ function stripUnpairedThinkingTags(text) {
64
+ if (!text)
65
+ return text;
66
+ const hasOpen = THINKING_OPEN_RE.test(text);
67
+ const hasClose = THINKING_CLOSE_RE.test(text);
68
+ if (hasOpen && hasClose)
69
+ return text;
70
+ if (!hasOpen)
71
+ return text.replace(THINKING_CLOSE_RE, "");
72
+ if (!hasClose)
73
+ return text.replace(THINKING_OPEN_RE, "");
74
+ return text;
75
+ }
76
+ export function subscribeEmbeddedPiSession(params) {
77
+ const assistantTexts = [];
78
+ const toolMetas = [];
79
+ const toolMetaById = new Map();
80
+ const toolSummaryById = new Set();
81
+ const blockReplyBreak = params.blockReplyBreak ?? "text_end";
82
+ let deltaBuffer = "";
83
+ let blockBuffer = "";
84
+ let lastStreamedAssistant;
85
+ let lastBlockReplyText;
86
+ let assistantTextBaseline = 0;
87
+ let compactionInFlight = false;
88
+ let pendingCompactionRetry = 0;
89
+ let compactionRetryResolve;
90
+ let compactionRetryPromise = null;
91
+ const ensureCompactionPromise = () => {
92
+ if (!compactionRetryPromise) {
93
+ compactionRetryPromise = new Promise((resolve) => {
94
+ compactionRetryResolve = resolve;
95
+ });
96
+ }
97
+ };
98
+ const noteCompactionRetry = () => {
99
+ pendingCompactionRetry += 1;
100
+ ensureCompactionPromise();
101
+ };
102
+ const resolveCompactionRetry = () => {
103
+ if (pendingCompactionRetry <= 0)
104
+ return;
105
+ pendingCompactionRetry -= 1;
106
+ if (pendingCompactionRetry === 0 && !compactionInFlight) {
107
+ compactionRetryResolve?.();
108
+ compactionRetryResolve = undefined;
109
+ compactionRetryPromise = null;
110
+ }
111
+ };
112
+ const maybeResolveCompactionWait = () => {
113
+ if (pendingCompactionRetry === 0 && !compactionInFlight) {
114
+ compactionRetryResolve?.();
115
+ compactionRetryResolve = undefined;
116
+ compactionRetryPromise = null;
117
+ }
118
+ };
119
+ const FINAL_START_RE = /<\s*final\s*>/i;
120
+ const FINAL_END_RE = /<\s*\/\s*final\s*>/i;
121
+ // Local providers sometimes emit malformed tags; normalize before filtering.
122
+ const sanitizeFinalText = (text) => {
123
+ if (!text)
124
+ return text;
125
+ const hasStart = FINAL_START_RE.test(text);
126
+ const hasEnd = FINAL_END_RE.test(text);
127
+ if (hasStart && !hasEnd)
128
+ return text.replace(FINAL_START_RE, "");
129
+ if (!hasStart && hasEnd)
130
+ return text.replace(FINAL_END_RE, "");
131
+ return text;
132
+ };
133
+ const extractFinalText = (text) => {
134
+ const cleaned = sanitizeFinalText(text);
135
+ const startMatch = FINAL_START_RE.exec(cleaned);
136
+ if (!startMatch)
137
+ return undefined;
138
+ const startIndex = startMatch.index + startMatch[0].length;
139
+ const afterStart = cleaned.slice(startIndex);
140
+ const endMatch = FINAL_END_RE.exec(afterStart);
141
+ const endIndex = endMatch ? endMatch.index : afterStart.length;
142
+ return afterStart.slice(0, endIndex);
143
+ };
144
+ const blockChunking = params.blockReplyChunking;
145
+ const shouldEmitToolResult = () => typeof params.shouldEmitToolResult === "function"
146
+ ? params.shouldEmitToolResult()
147
+ : params.verboseLevel === "on";
148
+ const emitToolSummary = (toolName, meta) => {
149
+ if (!params.onToolResult)
150
+ return;
151
+ const agg = formatToolAggregate(toolName, meta ? [meta] : undefined);
152
+ const { text: cleanedText, mediaUrls } = splitMediaFromOutput(agg);
153
+ if (!cleanedText && (!mediaUrls || mediaUrls.length === 0))
154
+ return;
155
+ try {
156
+ void params.onToolResult({
157
+ text: cleanedText,
158
+ mediaUrls: mediaUrls?.length ? mediaUrls : undefined,
159
+ });
160
+ }
161
+ catch {
162
+ // ignore tool result delivery failures
163
+ }
164
+ };
165
+ const findSentenceBreak = (window, minChars) => {
166
+ if (!window)
167
+ return -1;
168
+ const matches = window.matchAll(/[.!?](?=\s|$)/g);
169
+ let idx = -1;
170
+ for (const match of matches) {
171
+ const at = match.index ?? -1;
172
+ if (at < minChars)
173
+ continue;
174
+ idx = at + 1;
175
+ }
176
+ return idx;
177
+ };
178
+ const findWhitespaceBreak = (window, minChars) => {
179
+ for (let i = window.length - 1; i >= minChars; i--) {
180
+ if (/\s/.test(window[i]))
181
+ return i;
182
+ }
183
+ return -1;
184
+ };
185
+ const pickBreakIndex = (buffer) => {
186
+ if (!blockChunking)
187
+ return -1;
188
+ const minChars = Math.max(1, Math.floor(blockChunking.minChars));
189
+ const maxChars = Math.max(minChars, Math.floor(blockChunking.maxChars));
190
+ if (buffer.length < minChars)
191
+ return -1;
192
+ const window = buffer.slice(0, Math.min(maxChars, buffer.length));
193
+ const preference = blockChunking.breakPreference ?? "paragraph";
194
+ const paragraphIdx = window.lastIndexOf("\n\n");
195
+ if (preference === "paragraph" && paragraphIdx >= minChars) {
196
+ return paragraphIdx;
197
+ }
198
+ const newlineIdx = window.lastIndexOf("\n");
199
+ if ((preference === "paragraph" || preference === "newline") &&
200
+ newlineIdx >= minChars) {
201
+ return newlineIdx;
202
+ }
203
+ if (preference !== "newline") {
204
+ const sentenceIdx = findSentenceBreak(window, minChars);
205
+ if (sentenceIdx >= minChars)
206
+ return sentenceIdx;
207
+ }
208
+ const whitespaceIdx = findWhitespaceBreak(window, minChars);
209
+ if (whitespaceIdx >= minChars)
210
+ return whitespaceIdx;
211
+ if (buffer.length >= maxChars)
212
+ return maxChars;
213
+ return -1;
214
+ };
215
+ const emitBlockChunk = (text) => {
216
+ // Strip any <thinking> tags that may have leaked into the output (e.g., from Gemini mimicking history)
217
+ const strippedText = stripThinkingSegments(stripUnpairedThinkingTags(text));
218
+ const chunk = strippedText.trimEnd();
219
+ if (!chunk)
220
+ return;
221
+ if (chunk === lastBlockReplyText)
222
+ return;
223
+ lastBlockReplyText = chunk;
224
+ assistantTexts.push(chunk);
225
+ if (!params.onBlockReply)
226
+ return;
227
+ const { text: cleanedText, mediaUrls } = splitMediaFromOutput(chunk);
228
+ if (!cleanedText && (!mediaUrls || mediaUrls.length === 0))
229
+ return;
230
+ void params.onBlockReply({
231
+ text: cleanedText,
232
+ mediaUrls: mediaUrls?.length ? mediaUrls : undefined,
233
+ });
234
+ };
235
+ const drainBlockBuffer = (force) => {
236
+ if (!blockChunking)
237
+ return;
238
+ const minChars = Math.max(1, Math.floor(blockChunking.minChars));
239
+ const maxChars = Math.max(minChars, Math.floor(blockChunking.maxChars));
240
+ // Force flush small remainders as a single chunk to avoid re-splitting.
241
+ if (force && blockBuffer.length > 0 && blockBuffer.length <= maxChars) {
242
+ emitBlockChunk(blockBuffer);
243
+ blockBuffer = "";
244
+ return;
245
+ }
246
+ if (blockBuffer.length < minChars && !force)
247
+ return;
248
+ while (blockBuffer.length >= minChars ||
249
+ (force && blockBuffer.length > 0)) {
250
+ const breakIdx = pickBreakIndex(blockBuffer);
251
+ if (breakIdx <= 0) {
252
+ if (force) {
253
+ emitBlockChunk(blockBuffer);
254
+ blockBuffer = "";
255
+ }
256
+ return;
257
+ }
258
+ const rawChunk = blockBuffer.slice(0, breakIdx);
259
+ if (rawChunk.trim().length === 0) {
260
+ blockBuffer = blockBuffer.slice(breakIdx).trimStart();
261
+ continue;
262
+ }
263
+ emitBlockChunk(rawChunk);
264
+ const nextStart = breakIdx < blockBuffer.length && /\s/.test(blockBuffer[breakIdx])
265
+ ? breakIdx + 1
266
+ : breakIdx;
267
+ blockBuffer = blockBuffer.slice(nextStart).trimStart();
268
+ if (blockBuffer.length < minChars && !force)
269
+ return;
270
+ if (blockBuffer.length < maxChars && !force)
271
+ return;
272
+ }
273
+ };
274
+ const resetForCompactionRetry = () => {
275
+ assistantTexts.length = 0;
276
+ toolMetas.length = 0;
277
+ toolMetaById.clear();
278
+ toolSummaryById.clear();
279
+ deltaBuffer = "";
280
+ blockBuffer = "";
281
+ lastStreamedAssistant = undefined;
282
+ lastBlockReplyText = undefined;
283
+ assistantTextBaseline = 0;
284
+ };
285
+ const unsubscribe = params.session.subscribe((evt) => {
286
+ if (evt.type === "tool_execution_start") {
287
+ const toolName = String(evt.toolName);
288
+ const toolCallId = String(evt.toolCallId);
289
+ const args = evt.args;
290
+ const meta = inferToolMetaFromArgs(toolName, args);
291
+ toolMetaById.set(toolCallId, meta);
292
+ log.debug(`embedded run tool start: runId=${params.runId} tool=${toolName} toolCallId=${toolCallId}`);
293
+ emitAgentEvent({
294
+ runId: params.runId,
295
+ stream: "tool",
296
+ data: {
297
+ phase: "start",
298
+ name: toolName,
299
+ toolCallId,
300
+ args: args,
301
+ },
302
+ });
303
+ params.onAgentEvent?.({
304
+ stream: "tool",
305
+ data: { phase: "start", name: toolName, toolCallId },
306
+ });
307
+ if (params.onToolResult &&
308
+ shouldEmitToolResult() &&
309
+ !toolSummaryById.has(toolCallId)) {
310
+ toolSummaryById.add(toolCallId);
311
+ emitToolSummary(toolName, meta);
312
+ }
313
+ }
314
+ if (evt.type === "tool_execution_update") {
315
+ const toolName = String(evt.toolName);
316
+ const toolCallId = String(evt.toolCallId);
317
+ const partial = evt
318
+ .partialResult;
319
+ const sanitized = sanitizeToolResult(partial);
320
+ emitAgentEvent({
321
+ runId: params.runId,
322
+ stream: "tool",
323
+ data: {
324
+ phase: "update",
325
+ name: toolName,
326
+ toolCallId,
327
+ partialResult: sanitized,
328
+ },
329
+ });
330
+ params.onAgentEvent?.({
331
+ stream: "tool",
332
+ data: {
333
+ phase: "update",
334
+ name: toolName,
335
+ toolCallId,
336
+ },
337
+ });
338
+ }
339
+ if (evt.type === "tool_execution_end") {
340
+ const toolName = String(evt.toolName);
341
+ const toolCallId = String(evt.toolCallId);
342
+ const isError = Boolean(evt.isError);
343
+ const result = evt.result;
344
+ const sanitizedResult = sanitizeToolResult(result);
345
+ const meta = toolMetaById.get(toolCallId);
346
+ toolMetas.push({ toolName, meta });
347
+ toolMetaById.delete(toolCallId);
348
+ toolSummaryById.delete(toolCallId);
349
+ emitAgentEvent({
350
+ runId: params.runId,
351
+ stream: "tool",
352
+ data: {
353
+ phase: "result",
354
+ name: toolName,
355
+ toolCallId,
356
+ meta,
357
+ isError,
358
+ result: sanitizedResult,
359
+ },
360
+ });
361
+ params.onAgentEvent?.({
362
+ stream: "tool",
363
+ data: {
364
+ phase: "result",
365
+ name: toolName,
366
+ toolCallId,
367
+ meta,
368
+ isError,
369
+ },
370
+ });
371
+ }
372
+ if (evt.type === "message_update") {
373
+ const msg = evt.message;
374
+ if (msg?.role === "assistant") {
375
+ const assistantEvent = evt.assistantMessageEvent;
376
+ const assistantRecord = assistantEvent && typeof assistantEvent === "object"
377
+ ? assistantEvent
378
+ : undefined;
379
+ const evtType = typeof assistantRecord?.type === "string"
380
+ ? assistantRecord.type
381
+ : "";
382
+ if (evtType === "text_delta" ||
383
+ evtType === "text_start" ||
384
+ evtType === "text_end") {
385
+ const delta = typeof assistantRecord?.delta === "string"
386
+ ? assistantRecord.delta
387
+ : "";
388
+ const content = typeof assistantRecord?.content === "string"
389
+ ? assistantRecord.content
390
+ : "";
391
+ let chunk = "";
392
+ if (evtType === "text_delta") {
393
+ chunk = delta;
394
+ }
395
+ else if (evtType === "text_start" || evtType === "text_end") {
396
+ if (delta) {
397
+ chunk = delta;
398
+ }
399
+ else if (content) {
400
+ // Providers may resend full content on text_end; append only the suffix.
401
+ if (content.startsWith(deltaBuffer)) {
402
+ chunk = content.slice(deltaBuffer.length);
403
+ }
404
+ else if (deltaBuffer.startsWith(content)) {
405
+ chunk = "";
406
+ }
407
+ else if (!deltaBuffer.includes(content)) {
408
+ chunk = content;
409
+ }
410
+ }
411
+ }
412
+ if (chunk) {
413
+ deltaBuffer += chunk;
414
+ blockBuffer += chunk;
415
+ }
416
+ const cleaned = params.enforceFinalTag
417
+ ? stripThinkingSegments(stripUnpairedThinkingTags(deltaBuffer))
418
+ : stripThinkingSegments(deltaBuffer);
419
+ const next = params.enforceFinalTag
420
+ ? (extractFinalText(cleaned)?.trim() ?? cleaned.trim())
421
+ : cleaned.trim();
422
+ if (next && next !== lastStreamedAssistant) {
423
+ lastStreamedAssistant = next;
424
+ const { text: cleanedText, mediaUrls } = splitMediaFromOutput(next);
425
+ emitAgentEvent({
426
+ runId: params.runId,
427
+ stream: "assistant",
428
+ data: {
429
+ text: cleanedText,
430
+ mediaUrls: mediaUrls?.length ? mediaUrls : undefined,
431
+ },
432
+ });
433
+ params.onAgentEvent?.({
434
+ stream: "assistant",
435
+ data: {
436
+ text: cleanedText,
437
+ mediaUrls: mediaUrls?.length ? mediaUrls : undefined,
438
+ },
439
+ });
440
+ if (params.onPartialReply) {
441
+ void params.onPartialReply({
442
+ text: cleanedText,
443
+ mediaUrls: mediaUrls?.length ? mediaUrls : undefined,
444
+ });
445
+ }
446
+ }
447
+ if (params.onBlockReply && blockChunking) {
448
+ drainBlockBuffer(false);
449
+ }
450
+ if (evtType === "text_end" && blockReplyBreak === "text_end") {
451
+ if (blockChunking && blockBuffer.length > 0) {
452
+ drainBlockBuffer(true);
453
+ }
454
+ else if (next && next !== lastBlockReplyText) {
455
+ lastBlockReplyText = next || undefined;
456
+ if (next)
457
+ assistantTexts.push(next);
458
+ if (next && params.onBlockReply) {
459
+ const { text: cleanedText, mediaUrls } = splitMediaFromOutput(next);
460
+ if (cleanedText || (mediaUrls && mediaUrls.length > 0)) {
461
+ void params.onBlockReply({
462
+ text: cleanedText,
463
+ mediaUrls: mediaUrls?.length ? mediaUrls : undefined,
464
+ });
465
+ }
466
+ }
467
+ }
468
+ deltaBuffer = "";
469
+ blockBuffer = "";
470
+ lastStreamedAssistant = undefined;
471
+ }
472
+ }
473
+ }
474
+ }
475
+ if (evt.type === "message_end") {
476
+ const msg = evt.message;
477
+ if (msg?.role === "assistant") {
478
+ const cleaned = params.enforceFinalTag
479
+ ? stripThinkingSegments(stripUnpairedThinkingTags(extractAssistantText(msg)))
480
+ : stripThinkingSegments(extractAssistantText(msg));
481
+ const text = params.enforceFinalTag && cleaned
482
+ ? (extractFinalText(cleaned)?.trim() ?? cleaned)
483
+ : cleaned;
484
+ const addedDuringMessage = assistantTexts.length > assistantTextBaseline;
485
+ if (!addedDuringMessage && text)
486
+ assistantTexts.push(text);
487
+ assistantTextBaseline = assistantTexts.length;
488
+ if ((blockReplyBreak === "message_end" || blockBuffer.length > 0) &&
489
+ text &&
490
+ params.onBlockReply) {
491
+ if (blockChunking && blockBuffer.length > 0) {
492
+ drainBlockBuffer(true);
493
+ }
494
+ else if (text !== lastBlockReplyText) {
495
+ lastBlockReplyText = text;
496
+ const { text: cleanedText, mediaUrls } = splitMediaFromOutput(text);
497
+ if (cleanedText || (mediaUrls && mediaUrls.length > 0)) {
498
+ void params.onBlockReply({
499
+ text: cleanedText,
500
+ mediaUrls: mediaUrls?.length ? mediaUrls : undefined,
501
+ });
502
+ }
503
+ }
504
+ }
505
+ deltaBuffer = "";
506
+ blockBuffer = "";
507
+ lastStreamedAssistant = undefined;
508
+ lastBlockReplyText = undefined;
509
+ }
510
+ }
511
+ if (evt.type === "tool_execution_end") {
512
+ const toolName = String(evt.toolName);
513
+ const toolCallId = String(evt.toolCallId);
514
+ log.debug(`embedded run tool end: runId=${params.runId} tool=${toolName} toolCallId=${toolCallId}`);
515
+ }
516
+ if (evt.type === "agent_start") {
517
+ log.debug(`embedded run agent start: runId=${params.runId}`);
518
+ }
519
+ if (evt.type === "auto_compaction_start") {
520
+ compactionInFlight = true;
521
+ ensureCompactionPromise();
522
+ log.debug(`embedded run compaction start: runId=${params.runId}`);
523
+ }
524
+ if (evt.type === "auto_compaction_end") {
525
+ compactionInFlight = false;
526
+ const willRetry = Boolean(evt.willRetry);
527
+ if (willRetry) {
528
+ noteCompactionRetry();
529
+ resetForCompactionRetry();
530
+ log.debug(`embedded run compaction retry: runId=${params.runId}`);
531
+ }
532
+ else {
533
+ maybeResolveCompactionWait();
534
+ }
535
+ }
536
+ if (evt.type === "agent_end") {
537
+ log.debug(`embedded run agent end: runId=${params.runId}`);
538
+ if (pendingCompactionRetry > 0) {
539
+ resolveCompactionRetry();
540
+ }
541
+ else {
542
+ maybeResolveCompactionWait();
543
+ }
544
+ }
545
+ });
546
+ return {
547
+ assistantTexts,
548
+ toolMetas,
549
+ unsubscribe,
550
+ waitForCompactionRetry: () => {
551
+ if (compactionInFlight || pendingCompactionRetry > 0) {
552
+ ensureCompactionPromise();
553
+ return compactionRetryPromise ?? Promise.resolve();
554
+ }
555
+ return new Promise((resolve) => {
556
+ queueMicrotask(() => {
557
+ if (compactionInFlight || pendingCompactionRetry > 0) {
558
+ ensureCompactionPromise();
559
+ void (compactionRetryPromise ?? Promise.resolve()).then(resolve);
560
+ }
561
+ else {
562
+ resolve();
563
+ }
564
+ });
565
+ });
566
+ },
567
+ };
568
+ }
@@ -0,0 +1,20 @@
1
+ import { formatToolDetail, resolveToolDisplay } from "./tool-display.js";
2
+ export function extractAssistantText(msg) {
3
+ const isTextBlock = (block) => {
4
+ if (!block || typeof block !== "object")
5
+ return false;
6
+ const rec = block;
7
+ return rec.type === "text" && typeof rec.text === "string";
8
+ };
9
+ const blocks = Array.isArray(msg.content)
10
+ ? msg.content
11
+ .filter(isTextBlock)
12
+ .map((c) => c.text.trim())
13
+ .filter(Boolean)
14
+ : [];
15
+ return blocks.join("\n").trim();
16
+ }
17
+ export function inferToolMetaFromArgs(toolName, args) {
18
+ const display = resolveToolDisplay({ name: toolName, args });
19
+ return formatToolDetail(display);
20
+ }
@@ -0,0 +1 @@
1
+ export { abortEmbeddedPiRun, isEmbeddedPiRunActive, isEmbeddedPiRunStreaming, queueEmbeddedPiMessage, resolveEmbeddedSessionLane, runEmbeddedPiAgent, waitForEmbeddedPiRunEnd, } from "./pi-embedded-runner.js";
@@ -0,0 +1,88 @@
1
+ import fs from "node:fs/promises";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ const PI_AGENT_DIR_ENV = "PI_CODING_AGENT_DIR";
5
+ const ANTHROPIC_CLIENT_ID = "9d1c250a-e61b-44d9-88ed-5944d1962f5e";
6
+ const ANTHROPIC_TOKEN_URL = "https://console.anthropic.com/v1/oauth/token";
7
+ function getPiAgentDir() {
8
+ const override = process.env[PI_AGENT_DIR_ENV];
9
+ if (override?.trim())
10
+ return override.trim();
11
+ return path.join(os.homedir(), ".pi", "agent");
12
+ }
13
+ function getPiOAuthPath() {
14
+ return path.join(getPiAgentDir(), "oauth.json");
15
+ }
16
+ async function loadOAuthStorage() {
17
+ const filePath = getPiOAuthPath();
18
+ try {
19
+ const raw = await fs.readFile(filePath, "utf-8");
20
+ const parsed = JSON.parse(raw);
21
+ if (parsed && typeof parsed === "object") {
22
+ return parsed;
23
+ }
24
+ }
25
+ catch {
26
+ // missing/invalid: treat as empty
27
+ }
28
+ return {};
29
+ }
30
+ async function saveOAuthStorage(storage) {
31
+ const filePath = getPiOAuthPath();
32
+ await fs.mkdir(path.dirname(filePath), { recursive: true, mode: 0o700 });
33
+ await fs.writeFile(filePath, JSON.stringify(storage, null, 2), {
34
+ encoding: "utf-8",
35
+ mode: 0o600,
36
+ });
37
+ try {
38
+ await fs.chmod(filePath, 0o600);
39
+ }
40
+ catch {
41
+ // best effort (windows / restricted fs)
42
+ }
43
+ }
44
+ async function refreshAnthropicToken(refreshToken) {
45
+ const tokenResponse = await fetch(ANTHROPIC_TOKEN_URL, {
46
+ method: "POST",
47
+ headers: { "Content-Type": "application/json" },
48
+ body: JSON.stringify({
49
+ grant_type: "refresh_token",
50
+ client_id: ANTHROPIC_CLIENT_ID,
51
+ refresh_token: refreshToken,
52
+ }),
53
+ });
54
+ if (!tokenResponse.ok) {
55
+ const error = await tokenResponse.text();
56
+ throw new Error(`Anthropic OAuth token refresh failed: ${error}`);
57
+ }
58
+ const tokenData = (await tokenResponse.json());
59
+ // 5 min buffer
60
+ const expiresAt = Date.now() + tokenData.expires_in * 1000 - 5 * 60 * 1000;
61
+ return {
62
+ type: "oauth",
63
+ refresh: tokenData.refresh_token,
64
+ access: tokenData.access_token,
65
+ expires: expiresAt,
66
+ };
67
+ }
68
+ export async function getAnthropicOAuthToken() {
69
+ const storage = await loadOAuthStorage();
70
+ const creds = storage.anthropic;
71
+ if (!creds)
72
+ return null;
73
+ // If expired, attempt refresh; on failure, remove creds.
74
+ if (Date.now() >= creds.expires) {
75
+ try {
76
+ const refreshed = await refreshAnthropicToken(creds.refresh);
77
+ storage.anthropic = refreshed;
78
+ await saveOAuthStorage(storage);
79
+ return refreshed.access;
80
+ }
81
+ catch {
82
+ delete storage.anthropic;
83
+ await saveOAuthStorage(storage);
84
+ return null;
85
+ }
86
+ }
87
+ return creds.access;
88
+ }