@xopcai/xopc 0.0.89 → 0.0.90

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 (384) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/feishu/src/outbound/media-load.js +1 -1
  3. package/dist/extensions/feishu/src/workflow-progress.js +1 -1
  4. package/dist/extensions/telegram/src/plugin.js +1 -1
  5. package/dist/extensions/telegram/src/routing-integration.js +2 -2
  6. package/dist/extensions/telegram/src/workflow-progress.js +1 -1
  7. package/dist/extensions/telegram/xopc.extension.json +1 -1
  8. package/dist/extensions/weixin/src/api/api.js +2 -2
  9. package/dist/extensions/weixin/src/auth/accounts.js +1 -1
  10. package/dist/extensions/weixin/src/cdn/upload.js +1 -1
  11. package/dist/extensions/weixin/src/media/data-url.js +1 -1
  12. package/dist/extensions/weixin/src/messaging/debug-mode.js +1 -1
  13. package/dist/extensions/weixin/src/messaging/inbound.js +1 -1
  14. package/dist/extensions/weixin/src/messaging/process-message.js +1 -1
  15. package/dist/extensions/weixin/src/plugin.js +1 -1
  16. package/dist/extensions/weixin/src/storage/sync-buf.js +1 -1
  17. package/dist/extensions/weixin/src/workflow-progress.js +1 -1
  18. package/dist/gateway/static/root/assets/agents-cPvvYLXo.js +222 -0
  19. package/dist/gateway/static/root/assets/apps-page-Bk1_P5FJ.js +1 -0
  20. package/dist/gateway/static/root/assets/channels-settings-CZoeQwHz.js +1 -0
  21. package/dist/gateway/static/root/assets/{channels-status-swr-DaHGkRF1.js → channels-status-swr-BrtH2VzC.js} +1 -1
  22. package/dist/gateway/static/root/assets/circle-check-C23XjkUj.js +1 -0
  23. package/dist/gateway/static/root/assets/cron-api-CyqbgfHM.js +1 -0
  24. package/dist/gateway/static/root/assets/cron-dreaming-jobs-Ip703-qM.js +2 -0
  25. package/dist/gateway/static/root/assets/cron-page-BpLdiQN8.js +1 -0
  26. package/dist/gateway/static/root/assets/dist-BpAiK86n.js +1 -0
  27. package/dist/gateway/static/root/assets/{extension-debug-page-CtuKJ9tE.js → extension-debug-page-D6Ak0STa.js} +1 -1
  28. package/dist/gateway/static/root/assets/{extension-page-ykzjOkR5.js → extension-page-Q0P3d6DW.js} +1 -1
  29. package/dist/gateway/static/root/assets/{extension-settings-page-Ce2qrdpO.js → extension-settings-page-CL55LwU_.js} +1 -1
  30. package/dist/gateway/static/root/assets/eye-DAfL1U7M.js +1 -0
  31. package/dist/gateway/static/root/assets/{fetch-C9FFJjuH.js → fetch-Dqa9iTWl.js} +1 -1
  32. package/dist/gateway/static/root/assets/{field-primitives-BFcrNeTU.js → field-primitives-HUR6JElP.js} +1 -1
  33. package/dist/gateway/static/root/assets/{heartbeat-config-api-CEg4Vr9R.js → heartbeat-config-api-DusckjUX.js} +1 -1
  34. package/dist/gateway/static/root/assets/{index-CZfy9oxs.js → index-BYcGfwcE.js} +97 -97
  35. package/dist/gateway/static/root/assets/index-V7MQ7834.css +1 -0
  36. package/dist/gateway/static/root/assets/logs-page-_HcZ2fgK.js +1 -0
  37. package/dist/gateway/static/root/assets/sessions-page-iezSMjho.js +1 -0
  38. package/dist/gateway/static/root/assets/{settings-form-section-BqdzA28u.js → settings-form-section-a0qGVOlr.js} +1 -1
  39. package/dist/gateway/static/root/assets/settings-page-C9_nYQwM.js +3 -0
  40. package/dist/gateway/static/root/assets/{share-preview-page-Di5Bzh4g.js → share-preview-page-DExl7CJy.js} +1 -1
  41. package/dist/gateway/static/root/assets/skills-page-BlgGD93t.js +2 -0
  42. package/dist/gateway/static/root/assets/{theme-store-CNqbmTNV.js → theme-store-C0Ehmdo5.js} +1 -1
  43. package/dist/gateway/static/root/assets/url-fxyYANfA.js +3 -0
  44. package/dist/gateway/static/root/assets/{utils-BWm2tG2w.js → utils-DRQryzdn.js} +1 -1
  45. package/dist/gateway/static/root/assets/voice-api-key-field-D0viACE2.js +1 -0
  46. package/dist/gateway/static/root/assets/workflow-page.utils-DnG8JBhV.js +1 -0
  47. package/dist/gateway/static/root/assets/workflows-page-BvMobnJP.js +27 -0
  48. package/dist/gateway/static/root/index.html +7 -5
  49. package/dist/package.js +1 -1
  50. package/dist/src/agent/agent-manager.js +7 -7
  51. package/dist/src/agent/agent-scope.js +1 -1
  52. package/dist/src/agent/bootstrap/load-bootstrap-files.js +1 -1
  53. package/dist/src/agent/context/workspace-seed.js +2 -2
  54. package/dist/src/agent/goals/goal-run-store.js +4 -4
  55. package/dist/src/agent/goals/persistent-goal-service.js +1 -1
  56. package/dist/src/agent/goals/post-turn.js +2 -2
  57. package/dist/src/agent/image/load-image-media.js +2 -2
  58. package/dist/src/agent/ipc/bus.js +1 -1
  59. package/dist/src/agent/ipc/inbox.js +2 -2
  60. package/dist/src/agent/ipc/socket.js +1 -1
  61. package/dist/src/agent/mcp/bundle-mcp-materialize.js +1 -1
  62. package/dist/src/agent/mcp/bundle-mcp-runtime.js +1 -1
  63. package/dist/src/agent/mcp/mcp-transport-config.js +1 -1
  64. package/dist/src/agent/mcp/mcp-transport.js +1 -1
  65. package/dist/src/agent/memory/builtin-memory-store.js +1 -1
  66. package/dist/src/agent/memory/dreaming/deep-promotion.js +1 -1
  67. package/dist/src/agent/memory/dreaming/events.js +1 -1
  68. package/dist/src/agent/memory/dreaming/last-run.js +1 -1
  69. package/dist/src/agent/memory/dreaming/light-sweep.js +1 -1
  70. package/dist/src/agent/memory/dreaming/preview.js +1 -1
  71. package/dist/src/agent/memory/dreaming/rem-patterns.js +1 -1
  72. package/dist/src/agent/memory/dreaming/short-term-store.js +1 -1
  73. package/dist/src/agent/memory/dreaming/utils.js +1 -1
  74. package/dist/src/agent/memory/plugin-discovery.js +1 -1
  75. package/dist/src/agent/models/manager.js +1 -1
  76. package/dist/src/agent/prompt/service-prompt-builder.js +2 -2
  77. package/dist/src/agent/reply/post-compaction-context.js +1 -1
  78. package/dist/src/agent/reply/workspace-boundary-read.js +1 -1
  79. package/dist/src/agent/sandbox/path-policy.js +2 -2
  80. package/dist/src/agent/service/build-direct-message-content.js +1 -1
  81. package/dist/src/agent/service.js +4 -4
  82. package/dist/src/agent/session/session-inspector.js +1 -1
  83. package/dist/src/agent/skills/config.js +1 -1
  84. package/dist/src/agent/skills/hub-hash.js +2 -2
  85. package/dist/src/agent/skills/hub-lock.js +1 -1
  86. package/dist/src/agent/skills/hub-pull.js +2 -2
  87. package/dist/src/agent/skills/index.js +1 -1
  88. package/dist/src/agent/skills/managed-store.js +1 -1
  89. package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js +20 -18
  90. package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js.map +1 -1
  91. package/dist/src/agent/skills/scanner.js +1 -1
  92. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  93. package/dist/src/agent/skills/skill-manager.js +1 -1
  94. package/dist/src/agent/tools/cronjob-tool.d.ts +6 -0
  95. package/dist/src/agent/tools/cronjob-tool.js +74 -9
  96. package/dist/src/agent/tools/cronjob-tool.js.map +1 -1
  97. package/dist/src/agent/tools/dreaming-tool.js +1 -1
  98. package/dist/src/agent/tools/edit.d.ts +5 -1
  99. package/dist/src/agent/tools/edit.js +7 -5
  100. package/dist/src/agent/tools/edit.js.map +1 -1
  101. package/dist/src/agent/tools/factory.js +3 -3
  102. package/dist/src/agent/tools/factory.js.map +1 -1
  103. package/dist/src/agent/tools/image-generate-tool.js +1 -1
  104. package/dist/src/agent/tools/send-media.js +1 -1
  105. package/dist/src/agent/tools/skill-manage-tool.js +1 -1
  106. package/dist/src/agent/tools/workflow-tool.js +1 -1
  107. package/dist/src/agent/tools/write.d.ts +5 -1
  108. package/dist/src/agent/tools/write.js +8 -6
  109. package/dist/src/agent/tools/write.js.map +1 -1
  110. package/dist/src/agent/workflow/agent-progress.js +2 -0
  111. package/dist/src/agent/workflow/agent-progress.js.map +1 -1
  112. package/dist/src/agent/workflow/builtins/client-proposal.d.ts +12 -0
  113. package/dist/src/agent/workflow/builtins/client-proposal.js +155 -0
  114. package/dist/src/agent/workflow/builtins/client-proposal.js.map +1 -0
  115. package/dist/src/agent/workflow/builtins/competitor-scan.d.ts +12 -0
  116. package/dist/src/agent/workflow/builtins/competitor-scan.js +150 -0
  117. package/dist/src/agent/workflow/builtins/competitor-scan.js.map +1 -0
  118. package/dist/src/agent/workflow/builtins/content-draft.d.ts +13 -0
  119. package/dist/src/agent/workflow/builtins/content-draft.js +146 -0
  120. package/dist/src/agent/workflow/builtins/content-draft.js.map +1 -0
  121. package/dist/src/agent/workflow/builtins/content-repurpose.d.ts +11 -0
  122. package/dist/src/agent/workflow/builtins/content-repurpose.js +137 -0
  123. package/dist/src/agent/workflow/builtins/content-repurpose.js.map +1 -0
  124. package/dist/src/agent/workflow/builtins/decision-compare.d.ts +13 -0
  125. package/dist/src/agent/workflow/builtins/decision-compare.js +173 -0
  126. package/dist/src/agent/workflow/builtins/decision-compare.js.map +1 -0
  127. package/dist/src/agent/workflow/builtins/inbox-triage.d.ts +11 -0
  128. package/dist/src/agent/workflow/builtins/inbox-triage.js +148 -0
  129. package/dist/src/agent/workflow/builtins/inbox-triage.js.map +1 -0
  130. package/dist/src/agent/workflow/builtins/index.d.ts +10 -1
  131. package/dist/src/agent/workflow/builtins/index.js +46 -1
  132. package/dist/src/agent/workflow/builtins/index.js.map +1 -1
  133. package/dist/src/agent/workflow/builtins/meeting-prep.d.ts +12 -0
  134. package/dist/src/agent/workflow/builtins/meeting-prep.js +144 -0
  135. package/dist/src/agent/workflow/builtins/meeting-prep.js.map +1 -0
  136. package/dist/src/agent/workflow/builtins/offer-design.d.ts +12 -0
  137. package/dist/src/agent/workflow/builtins/offer-design.js +161 -0
  138. package/dist/src/agent/workflow/builtins/offer-design.js.map +1 -0
  139. package/dist/src/agent/workflow/builtins/weekly-review.d.ts +12 -0
  140. package/dist/src/agent/workflow/builtins/weekly-review.js +131 -0
  141. package/dist/src/agent/workflow/builtins/weekly-review.js.map +1 -0
  142. package/dist/src/agent/workflow/catalog.js +1 -1
  143. package/dist/src/agent/workflow/step-labels.js +2 -2
  144. package/dist/src/agent/workflow/step-labels.js.map +1 -1
  145. package/dist/src/agent/workflow/subagent-runner.js +3 -1
  146. package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
  147. package/dist/src/agent/workflow/types.d.ts +4 -0
  148. package/dist/src/auth/credentials.js +3 -3
  149. package/dist/src/auth/profiles/store.js +1 -1
  150. package/dist/src/auth/sync-provider-auth.js +1 -1
  151. package/dist/src/browser/cache-dir-policy.js +1 -1
  152. package/dist/src/browser/cdp-local-launcher.js +2 -2
  153. package/dist/src/browser/providers/browser-ext-install.js +3 -3
  154. package/dist/src/browser/providers/cloakbrowser.js +4 -4
  155. package/dist/src/browser/providers/playwright-doctor.js +1 -1
  156. package/dist/src/browser/stealth.js +1 -1
  157. package/dist/src/channels/attachments/inbound-persist.js +1 -1
  158. package/dist/src/channels/attachments/outbound-tts-persist.js +1 -1
  159. package/dist/src/channels/outbound/persist-store.js +1 -1
  160. package/dist/src/channels/pairing/allow-from-file.js +1 -1
  161. package/dist/src/channels/pairing/pairing-store.js +2 -2
  162. package/dist/src/chat-commands/agent-edit.d.ts +4 -0
  163. package/dist/src/chat-commands/agent-edit.js +136 -0
  164. package/dist/src/chat-commands/agent-edit.js.map +1 -0
  165. package/dist/src/chat-commands/builtins/config.js +2 -2
  166. package/dist/src/chat-commands/context.js +1 -1
  167. package/dist/src/chat-commands/index.d.ts +1 -0
  168. package/dist/src/chat-commands/index.js +3 -1
  169. package/dist/src/chat-commands/index.js.map +1 -1
  170. package/dist/src/cli/bin.js +2 -0
  171. package/dist/src/cli/bin.js.map +1 -1
  172. package/dist/src/cli/commands/config.js +1 -1
  173. package/dist/src/cli/commands/cron.js +42 -3
  174. package/dist/src/cli/commands/cron.js.map +1 -1
  175. package/dist/src/cli/commands/doctor/checks/config-health.js +1 -1
  176. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
  177. package/dist/src/cli/commands/doctor/checks/session-integrity.js +79 -56
  178. package/dist/src/cli/commands/doctor/checks/session-integrity.js.map +1 -1
  179. package/dist/src/cli/commands/doctor/checks/state-integrity.js +1 -1
  180. package/dist/src/cli/commands/doctor/checks/workspace-status.js +1 -1
  181. package/dist/src/cli/commands/extension-dev.js +1 -1
  182. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  183. package/dist/src/cli/commands/extension-pack.js +1 -1
  184. package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
  185. package/dist/src/cli/commands/gateway/logs.js +1 -1
  186. package/dist/src/cli/commands/image.js +1 -1
  187. package/dist/src/cli/commands/init.js +4 -4
  188. package/dist/src/cli/commands/onboard.js +1 -1
  189. package/dist/src/cli/commands/update.js +86 -79
  190. package/dist/src/cli/commands/update.js.map +1 -1
  191. package/dist/src/cli/utils/init-workspace-core.js +2 -2
  192. package/dist/src/commands/agents.config.d.ts +3 -2
  193. package/dist/src/commands/agents.config.js +5 -2
  194. package/dist/src/commands/agents.config.js.map +1 -1
  195. package/dist/src/config/agent-profile.js +1 -1
  196. package/dist/src/config/agent-typed-models.d.ts +2 -7
  197. package/dist/src/config/agent-typed-models.js +3 -14
  198. package/dist/src/config/agent-typed-models.js.map +1 -1
  199. package/dist/src/config/gateway-bind.js +1 -1
  200. package/dist/src/config/index.js +5 -5
  201. package/dist/src/config/loader.js +2 -2
  202. package/dist/src/config/localized-text.d.ts +6 -0
  203. package/dist/src/config/localized-text.js +42 -0
  204. package/dist/src/config/localized-text.js.map +1 -0
  205. package/dist/src/config/models-json.d.ts +6 -6
  206. package/dist/src/config/models-json.js +2 -2
  207. package/dist/src/config/paths-state.js +1 -1
  208. package/dist/src/config/profile.js +2 -2
  209. package/dist/src/config/schema.d.ts +6 -21
  210. package/dist/src/config/schema.js +4 -4
  211. package/dist/src/config/schema.js.map +1 -1
  212. package/dist/src/config/workspace-path.js +1 -1
  213. package/dist/src/cron/executor.d.ts +2 -0
  214. package/dist/src/cron/executor.js +113 -3
  215. package/dist/src/cron/executor.js.map +1 -1
  216. package/dist/src/cron/persistence.js +1 -1
  217. package/dist/src/cron/run-log-store.js +1 -1
  218. package/dist/src/cron/types.d.ts +8 -1
  219. package/dist/src/cron/validation.d.ts +4 -0
  220. package/dist/src/cron/validation.js +4 -3
  221. package/dist/src/cron/validation.js.map +1 -1
  222. package/dist/src/cron/workflow-run-completion.d.ts +23 -0
  223. package/dist/src/cron/workflow-run-completion.js +72 -0
  224. package/dist/src/cron/workflow-run-completion.js.map +1 -0
  225. package/dist/src/daemon/constants.js +1 -1
  226. package/dist/src/daemon/install-plan.js +2 -2
  227. package/dist/src/daemon/launchd.js +2 -2
  228. package/dist/src/daemon/schtasks.js +2 -2
  229. package/dist/src/daemon/systemd.js +2 -2
  230. package/dist/src/extensions/bundle-mcp.js +1 -1
  231. package/dist/src/extensions/discover-extensions.js +1 -1
  232. package/dist/src/extensions/health.js +1 -1
  233. package/dist/src/extensions/loader.js +1 -1
  234. package/dist/src/extensions/lockfile.js +2 -2
  235. package/dist/src/extensions/update.d.ts +51 -0
  236. package/dist/src/extensions/update.js +260 -0
  237. package/dist/src/extensions/update.js.map +1 -0
  238. package/dist/src/gateway/agents-admin.d.ts +15 -8
  239. package/dist/src/gateway/agents-admin.js +78 -29
  240. package/dist/src/gateway/agents-admin.js.map +1 -1
  241. package/dist/src/gateway/file-path-classifier.js +2 -2
  242. package/dist/src/gateway/heartbeat/service.js +1 -1
  243. package/dist/src/gateway/hono/lib/config-payload.d.ts +5 -0
  244. package/dist/src/gateway/hono/lib/config-payload.js +3 -2
  245. package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
  246. package/dist/src/gateway/hono/lib/extension-store.js +2 -2
  247. package/dist/src/gateway/hono/lib/static-ui.js +2 -2
  248. package/dist/src/gateway/hono/middleware/auth.d.ts +2 -0
  249. package/dist/src/gateway/hono/middleware/auth.js +12 -7
  250. package/dist/src/gateway/hono/middleware/auth.js.map +1 -1
  251. package/dist/src/gateway/hono/oauth.js +1 -1
  252. package/dist/src/gateway/hono/routes/agents.js +56 -13
  253. package/dist/src/gateway/hono/routes/agents.js.map +1 -1
  254. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
  255. package/dist/src/gateway/hono/routes/config-patch/agents.js +1 -1
  256. package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
  257. package/dist/src/gateway/hono/routes/dreaming.js +1 -1
  258. package/dist/src/gateway/hono/routes/host-fs.js +2 -2
  259. package/dist/src/gateway/hono/routes/models.js +1 -1
  260. package/dist/src/gateway/hono/routes/shares.js +1 -1
  261. package/dist/src/gateway/hono/routes/update.js +55 -107
  262. package/dist/src/gateway/hono/routes/update.js.map +1 -1
  263. package/dist/src/gateway/hono/routes/workflows.js +3 -1
  264. package/dist/src/gateway/hono/routes/workflows.js.map +1 -1
  265. package/dist/src/gateway/hono/routes/workspace.js +4 -4
  266. package/dist/src/gateway/lock.js +3 -3
  267. package/dist/src/gateway/ports.js +1 -1
  268. package/dist/src/gateway/server.js +2 -0
  269. package/dist/src/gateway/server.js.map +1 -1
  270. package/dist/src/gateway/service/agent-runner.js +2 -2
  271. package/dist/src/gateway/service/marketplace-service.js +2 -2
  272. package/dist/src/gateway/service.js +3 -2
  273. package/dist/src/gateway/service.js.map +1 -1
  274. package/dist/src/gateway/workspace-fs-file-list.js +1 -1
  275. package/dist/src/heartbeat/index.js +1 -1
  276. package/dist/src/infra/brew.d.ts +4 -0
  277. package/dist/src/infra/brew.js +20 -0
  278. package/dist/src/infra/brew.js.map +1 -0
  279. package/dist/src/infra/package-json.d.ts +2 -0
  280. package/dist/src/infra/package-json.js +23 -0
  281. package/dist/src/infra/package-json.js.map +1 -0
  282. package/dist/src/infra/package-update-steps.d.ts +35 -0
  283. package/dist/src/infra/package-update-steps.js +304 -0
  284. package/dist/src/infra/package-update-steps.js.map +1 -0
  285. package/dist/src/infra/path-env.d.ts +11 -0
  286. package/dist/src/infra/path-env.js +90 -0
  287. package/dist/src/infra/path-env.js.map +1 -0
  288. package/dist/src/infra/path-prepend.d.ts +7 -0
  289. package/dist/src/infra/path-prepend.js +44 -0
  290. package/dist/src/infra/path-prepend.js.map +1 -0
  291. package/dist/src/infra/restart.js +2 -2
  292. package/dist/src/infra/stable-node-path.d.ts +2 -0
  293. package/dist/src/infra/stable-node-path.js +28 -0
  294. package/dist/src/infra/stable-node-path.js.map +1 -0
  295. package/dist/src/infra/update-check.js +1 -1
  296. package/dist/src/infra/update-global.d.ts +30 -23
  297. package/dist/src/infra/update-global.js +114 -65
  298. package/dist/src/infra/update-global.js.map +1 -1
  299. package/dist/src/infra/update-lock.js +3 -3
  300. package/dist/src/infra/update-log.d.ts +1 -0
  301. package/dist/src/infra/update-log.js +12 -0
  302. package/dist/src/infra/update-log.js.map +1 -0
  303. package/dist/src/infra/update-restart.d.ts +20 -0
  304. package/dist/src/infra/update-restart.js +165 -0
  305. package/dist/src/infra/update-restart.js.map +1 -0
  306. package/dist/src/infra/update-runner.d.ts +89 -1
  307. package/dist/src/infra/update-runner.js +604 -173
  308. package/dist/src/infra/update-runner.js.map +1 -1
  309. package/dist/src/infra/update-startup.d.ts +3 -0
  310. package/dist/src/infra/update-startup.js +10 -6
  311. package/dist/src/infra/update-startup.js.map +1 -1
  312. package/dist/src/infra/write-file-atomic.js +2 -2
  313. package/dist/src/providers/auth-runtime/auth-profile-store.js +1 -1
  314. package/dist/src/providers/index.js +2 -2
  315. package/dist/src/providers/model-registry.js +1 -1
  316. package/dist/src/routing/resolve-route.d.ts +3 -1
  317. package/dist/src/routing/resolve-route.js.map +1 -1
  318. package/dist/src/session/config-store.js +2 -2
  319. package/dist/src/session/init-session-turn.js +2 -2
  320. package/dist/src/session/parity/jsonl-transcript-io.js +2 -2
  321. package/dist/src/session/parity/sessions-json-file.js +1 -1
  322. package/dist/src/session/parity/transcript-file-lock.js +2 -2
  323. package/dist/src/session/parity/transcript-paths.js +1 -1
  324. package/dist/src/session/resolve-session.js +4 -4
  325. package/dist/src/session/search-index-cache.js +1 -1
  326. package/dist/src/session/search-index.js +1 -1
  327. package/dist/src/session/session-title.js +2 -2
  328. package/dist/src/session/store.d.ts +5 -3
  329. package/dist/src/session/store.js +71 -25
  330. package/dist/src/session/store.js.map +1 -1
  331. package/dist/src/share/share-auto.js +2 -2
  332. package/dist/src/share/share-store.js +3 -3
  333. package/dist/src/share/share-thumbnail.js +2 -2
  334. package/dist/src/share/share-zip.js +1 -1
  335. package/dist/src/share/site-share-store.js +3 -3
  336. package/dist/src/share/site-static-serve.js +1 -1
  337. package/dist/src/tui/clipboard-image.js +3 -3
  338. package/dist/src/tui/theme-manager.js +1 -1
  339. package/dist/src/tui/tui-keybindings-file.js +1 -1
  340. package/dist/src/tui/tui-scoped-models.js +2 -2
  341. package/dist/src/tui/tui-settings.js +1 -1
  342. package/dist/src/tui/tui.js +3 -3
  343. package/dist/src/tunnel/frpc-binary.js +3 -3
  344. package/dist/src/tunnel/frpc-config.js +1 -1
  345. package/dist/src/tunnel/frpc-extract.js +1 -1
  346. package/dist/src/tunnel/tunnel-state.js +1 -1
  347. package/dist/src/utils/logger/audit.js +1 -1
  348. package/dist/src/utils/logger/log-store.js +1 -1
  349. package/dist/src/utils/logger/rotation.js +1 -1
  350. package/dist/src/utils/logger/stats.d.ts +1 -1
  351. package/dist/src/voice/tts/audio.js +1 -1
  352. package/dist/src/voice/tts/providers/edge-speech.js +2 -2
  353. package/dist/src/workflows/domain/event.d.ts +3 -0
  354. package/dist/src/workflows/domain/run.d.ts +3 -0
  355. package/dist/src/workflows/domain/run.js.map +1 -1
  356. package/dist/src/workflows/engine/projector.js +17 -0
  357. package/dist/src/workflows/engine/projector.js.map +1 -1
  358. package/dist/src/workflows/engine/workflow-engine.js +127 -0
  359. package/dist/src/workflows/engine/workflow-engine.js.map +1 -1
  360. package/dist/src/workflows/index.js +1 -1
  361. package/dist/src/workflows/service/run-view-to-snapshot.js +3 -1
  362. package/dist/src/workflows/service/run-view-to-snapshot.js.map +1 -1
  363. package/dist/src/workflows/service/workflow-run-service.d.ts +1 -0
  364. package/dist/src/workflows/service/workflow-run-service.js +4 -1
  365. package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
  366. package/dist/src/workflows/service/workflow-session-bridge.js +1 -1
  367. package/dist/src/workflows/store/event-store.js +1 -1
  368. package/dist/src/workflows/store/run-store.js +1 -1
  369. package/package.json +1 -1
  370. package/dist/gateway/static/root/assets/agents-B6PJB07W.js +0 -222
  371. package/dist/gateway/static/root/assets/apps-page-BOr0B1wv.js +0 -1
  372. package/dist/gateway/static/root/assets/channels-settings-BelUKggl.js +0 -1
  373. package/dist/gateway/static/root/assets/cron-api-CjOg-BIj.js +0 -1
  374. package/dist/gateway/static/root/assets/cron-dreaming-jobs-DueM3rBz.js +0 -2
  375. package/dist/gateway/static/root/assets/cron-page-DhoZmZXb.js +0 -1
  376. package/dist/gateway/static/root/assets/dist-6LecgDx5.js +0 -1
  377. package/dist/gateway/static/root/assets/index-CiN1cQiQ.css +0 -1
  378. package/dist/gateway/static/root/assets/logs-page-BwWLfqvd.js +0 -1
  379. package/dist/gateway/static/root/assets/sessions-page-DV5WN8uk.js +0 -1
  380. package/dist/gateway/static/root/assets/settings-page-CfOBRbPX.js +0 -3
  381. package/dist/gateway/static/root/assets/skills-page-D0H5Kaxg.js +0 -2
  382. package/dist/gateway/static/root/assets/url-aYn-Rj1C.js +0 -7
  383. package/dist/gateway/static/root/assets/voice-api-key-field-X2UfnHeq.js +0 -1
  384. package/dist/gateway/static/root/assets/workflows-page-BOPpO3NG.js +0 -27
@@ -1 +1 @@
1
- {"version":3,"file":"write.js","names":[],"sources":["../../../../src/agent/tools/write.ts"],"sourcesContent":["// Write file tool\nimport { Type } from '@sinclair/typebox';\nimport type { AgentTool, AgentToolResult } from '@earendil-works/pi-agent-core';\nimport { writeFile, mkdir } from 'fs/promises';\nimport { dirname } from 'path';\nimport { checkFileSafety } from '../prompt/safety.js';\nimport { resolvePathUnderWorkspace } from './tool-paths.js';\nimport { evaluateFilePolicy } from '../sandbox/exec-policy.js';\n\nconst MAX_FILE_SIZE = 10 * 1024 * 1024;\n\nconst WriteFileSchema = Type.Object({\n path: Type.String({ description: 'File path to write' }),\n content: Type.String({ description: 'Content to write' }),\n});\n\ntype WriteFileParams = { path: string; content: string };\n\nexport function createWriteFileTool(workspace: string): AgentTool {\n return {\n name: 'write_file',\n description: 'Create or overwrite a file. Relative paths are under the current agent workspace.',\n parameters: WriteFileSchema,\n label: '📝 Write',\n\n async execute(\n _toolCallId: string,\n params: any,\n _signal?: AbortSignal,\n ): Promise<AgentToolResult<{}>> {\n try {\n const p = params as WriteFileParams;\n const safety = checkFileSafety('write', p.path);\n if (!safety.allowed) {\n return { content: [{ type: 'text', text: `🚫 ${safety.message}` }], details: {} };\n }\n\n // Sandbox path-policy check (blocked dirs, symlink escape, config protection)\n const pathPolicy = evaluateFilePolicy({\n operation: 'write',\n path: p.path,\n workspaceRoot: workspace,\n });\n if (!pathPolicy.allowed) {\n return { content: [{ type: 'text', text: `🚫 Sandbox: ${pathPolicy.reason}` }], details: {} };\n }\n\n const contentBytes = Buffer.byteLength(p.content, 'utf-8');\n if (contentBytes > MAX_FILE_SIZE) {\n return { content: [{ type: 'text', text: `🚫 File too large: ${contentBytes} bytes` }], details: {} };\n }\n\n const target = resolvePathUnderWorkspace(p.path, workspace);\n await mkdir(dirname(target), { recursive: true });\n await writeFile(target, p.content, 'utf-8');\n return { content: [{ type: 'text', text: `File written: ${target}` }], details: { size: contentBytes } };\n } catch (error) {\n return { content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : String(error)}` }], details: {} };\n }\n },\n } as any;\n}\n\nexport const writeFileTool: AgentTool = createWriteFileTool(process.cwd());\n"],"mappings":";;;;;;;AASA,MAAM,gBAAgB,KAAK,OAAO;AAElC,MAAM,kBAAkB,KAAK,OAAO;CAClC,MAAM,KAAK,OAAO,EAAE,aAAa,sBAAsB,CAAC;CACxD,SAAS,KAAK,OAAO,EAAE,aAAa,oBAAoB,CAAC;CAC1D,CAAC;AAIF,SAAgB,oBAAoB,WAA8B;AAChE,QAAO;EACL,MAAM;EACN,aAAa;EACb,YAAY;EACZ,OAAO;EAEP,MAAM,QACJ,aACA,QACA,SAC8B;AAC9B,OAAI;IACF,MAAM,IAAI;IACV,MAAM,SAAS,gBAAgB,SAAS,EAAE,KAAK;AAC/C,QAAI,CAAC,OAAO,QACV,QAAO;KAAE,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM,MAAM,OAAO;MAAW,CAAC;KAAE,SAAS,EAAE;KAAE;IAInF,MAAM,aAAa,mBAAmB;KACpC,WAAW;KACX,MAAM,EAAE;KACR,eAAe;KAChB,CAAC;AACF,QAAI,CAAC,WAAW,QACd,QAAO;KAAE,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM,eAAe,WAAW;MAAU,CAAC;KAAE,SAAS,EAAE;KAAE;IAG/F,MAAM,eAAe,OAAO,WAAW,EAAE,SAAS,QAAQ;AAC1D,QAAI,eAAe,cACjB,QAAO;KAAE,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM,sBAAsB,aAAa;MAAS,CAAC;KAAE,SAAS,EAAE;KAAE;IAGvG,MAAM,SAAS,0BAA0B,EAAE,MAAM,UAAU;AAC3D,UAAM,MAAM,QAAQ,OAAO,EAAE,EAAE,WAAW,MAAM,CAAC;AACjD,UAAM,UAAU,QAAQ,EAAE,SAAS,QAAQ;AAC3C,WAAO;KAAE,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM,iBAAiB;MAAU,CAAC;KAAE,SAAS,EAAE,MAAM,cAAc;KAAE;YACjG,OAAO;AACd,WAAO;KAAE,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;MAAI,CAAC;KAAE,SAAS,EAAE;KAAE;;;EAGlI;;AAGH,MAAa,gBAA2B,oBAAoB,QAAQ,KAAK,CAAC"}
1
+ {"version":3,"file":"write.js","names":[],"sources":["../../../../src/agent/tools/write.ts"],"sourcesContent":["// Write file tool\nimport { Type } from '@sinclair/typebox';\nimport type { AgentTool, AgentToolResult } from '@earendil-works/pi-agent-core';\nimport { writeFile, mkdir } from 'fs/promises';\nimport { dirname } from 'path';\nimport { checkFileSafety } from '../prompt/safety.js';\nimport {\n isBareProfileMarkdownFileName,\n resolveProfileMarkdownPathIfBareName,\n resolvePathUnderWorkspace,\n} from './tool-paths.js';\nimport { evaluateFilePolicy } from '../sandbox/exec-policy.js';\n\nconst MAX_FILE_SIZE = 10 * 1024 * 1024;\n\nconst WriteFileSchema = Type.Object({\n path: Type.String({ description: 'File path to write' }),\n content: Type.String({ description: 'Content to write' }),\n});\n\ntype WriteFileParams = { path: string; content: string };\n\nexport interface CreateWriteFileToolOptions {\n /** When set and the path is a bare profile filename (e.g. SOUL.md), write to this root. */\n profileMarkdownRoot?: string;\n}\n\nexport function createWriteFileTool(\n workspace: string,\n options?: CreateWriteFileToolOptions,\n): AgentTool {\n return {\n name: 'write_file',\n description:\n 'Create or overwrite a file. Relative paths are under the current agent workspace; profile Markdown (SOUL.md, etc.) is written automatically when given by filename.',\n parameters: WriteFileSchema,\n label: '📝 Write',\n\n async execute(\n _toolCallId: string,\n params: any,\n _signal?: AbortSignal,\n ): Promise<AgentToolResult<{}>> {\n try {\n const p = params as WriteFileParams;\n const safety = checkFileSafety('write', p.path);\n if (!safety.allowed) {\n return { content: [{ type: 'text', text: `🚫 ${safety.message}` }], details: {} };\n }\n\n const writesProfileFile = Boolean(\n options?.profileMarkdownRoot && isBareProfileMarkdownFileName(p.path),\n );\n const workspaceRoot = writesProfileFile ? options!.profileMarkdownRoot! : workspace;\n\n // Sandbox path-policy check (blocked dirs, symlink escape, config protection)\n const pathPolicy = evaluateFilePolicy({\n operation: 'write',\n path: p.path,\n workspaceRoot,\n });\n if (!pathPolicy.allowed) {\n return { content: [{ type: 'text', text: `🚫 Sandbox: ${pathPolicy.reason}` }], details: {} };\n }\n\n const contentBytes = Buffer.byteLength(p.content, 'utf-8');\n if (contentBytes > MAX_FILE_SIZE) {\n return { content: [{ type: 'text', text: `🚫 File too large: ${contentBytes} bytes` }], details: {} };\n }\n\n const target = writesProfileFile\n ? resolveProfileMarkdownPathIfBareName(p.path, options!.profileMarkdownRoot!)\n : resolvePathUnderWorkspace(p.path, workspace);\n await mkdir(dirname(target), { recursive: true });\n await writeFile(target, p.content, 'utf-8');\n return { content: [{ type: 'text', text: `File written: ${target}` }], details: { size: contentBytes } };\n } catch (error) {\n return { content: [{ type: 'text', text: `Error: ${error instanceof Error ? error.message : String(error)}` }], details: {} };\n }\n },\n } as any;\n}\n\nexport const writeFileTool: AgentTool = createWriteFileTool(process.cwd());\n"],"mappings":";;;;;;;AAaA,MAAM,gBAAgB,KAAK,OAAO;AAElC,MAAM,kBAAkB,KAAK,OAAO;CAClC,MAAM,KAAK,OAAO,EAAE,aAAa,sBAAsB,CAAC;CACxD,SAAS,KAAK,OAAO,EAAE,aAAa,oBAAoB,CAAC;CAC1D,CAAC;AASF,SAAgB,oBACd,WACA,SACW;AACX,QAAO;EACL,MAAM;EACN,aACE;EACF,YAAY;EACZ,OAAO;EAEP,MAAM,QACJ,aACA,QACA,SAC8B;AAC9B,OAAI;IACF,MAAM,IAAI;IACV,MAAM,SAAS,gBAAgB,SAAS,EAAE,KAAK;AAC/C,QAAI,CAAC,OAAO,QACV,QAAO;KAAE,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM,MAAM,OAAO;MAAW,CAAC;KAAE,SAAS,EAAE;KAAE;IAGnF,MAAM,oBAAoB,QACxB,SAAS,uBAAuB,8BAA8B,EAAE,KAAK,CACtE;IACD,MAAM,gBAAgB,oBAAoB,QAAS,sBAAuB;IAG1E,MAAM,aAAa,mBAAmB;KACpC,WAAW;KACX,MAAM,EAAE;KACR;KACD,CAAC;AACF,QAAI,CAAC,WAAW,QACd,QAAO;KAAE,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM,eAAe,WAAW;MAAU,CAAC;KAAE,SAAS,EAAE;KAAE;IAG/F,MAAM,eAAe,OAAO,WAAW,EAAE,SAAS,QAAQ;AAC1D,QAAI,eAAe,cACjB,QAAO;KAAE,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM,sBAAsB,aAAa;MAAS,CAAC;KAAE,SAAS,EAAE;KAAE;IAGvG,MAAM,SAAS,oBACX,qCAAqC,EAAE,MAAM,QAAS,oBAAqB,GAC3E,0BAA0B,EAAE,MAAM,UAAU;AAChD,UAAM,MAAM,QAAQ,OAAO,EAAE,EAAE,WAAW,MAAM,CAAC;AACjD,UAAM,UAAU,QAAQ,EAAE,SAAS,QAAQ;AAC3C,WAAO;KAAE,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM,iBAAiB;MAAU,CAAC;KAAE,SAAS,EAAE,MAAM,cAAc;KAAE;YACjG,OAAO;AACd,WAAO;KAAE,SAAS,CAAC;MAAE,MAAM;MAAQ,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;MAAI,CAAC;KAAE,SAAS,EAAE;KAAE;;;EAGlI;;AAGH,MAAa,gBAA2B,oBAAoB,QAAQ,KAAK,CAAC"}
@@ -25,6 +25,8 @@ function applySubagentProgress(agent, event) {
25
25
  const step = findStep(agent, event.toolCallId);
26
26
  if (!step) return false;
27
27
  step.status = event.isError ? "error" : "done";
28
+ step.resultPreview = event.resultPreview;
29
+ step.error = event.error;
28
30
  if (step.startedAtMs != null) step.durationMs = Date.now() - step.startedAtMs;
29
31
  if (agent.currentStep === formatCurrentStep(step)) agent.currentStep = void 0;
30
32
  return true;
@@ -1 +1 @@
1
- {"version":3,"file":"agent-progress.js","names":[],"sources":["../../../../src/agent/workflow/agent-progress.ts"],"sourcesContent":["/**\n * Apply live subagent progress events onto a {@link WorkflowAgentSnapshot}.\n */\n\nimport type {\n SubagentProgressEvent,\n WorkflowAgentSnapshot,\n WorkflowAgentStep,\n} from './types.js';\nimport { workflowStepLabel } from './step-labels.js';\n\nconst MAX_STEPS = 50;\nconst MAX_STREAM_TEXT = 32_000;\n\nexport function applySubagentProgress(\n agent: WorkflowAgentSnapshot,\n event: SubagentProgressEvent,\n): boolean {\n switch (event.type) {\n case 'tool_start': {\n if (!agent.steps) agent.steps = [];\n const { label, detail } = workflowStepLabel(event.toolName, event.args);\n const step: WorkflowAgentStep = {\n id: event.toolCallId,\n kind: 'tool',\n toolName: event.toolName,\n label,\n detail,\n status: 'running',\n startedAtMs: Date.now(),\n };\n agent.steps.push(step);\n trimSteps(agent);\n agent.currentStep = formatCurrentStep(step);\n return true;\n }\n case 'tool_end': {\n const step = findStep(agent, event.toolCallId);\n if (!step) return false;\n step.status = event.isError ? 'error' : 'done';\n if (step.startedAtMs != null) step.durationMs = Date.now() - step.startedAtMs;\n if (agent.currentStep === formatCurrentStep(step)) {\n agent.currentStep = undefined;\n }\n return true;\n }\n case 'iteration': {\n agent.iteration = event.count;\n agent.maxIterations = event.max;\n return true;\n }\n case 'text_delta': {\n if (!event.delta) return false;\n agent.streamText = appendStreamText(agent.streamText, event.delta);\n return true;\n }\n case 'thinking_delta': {\n if (!event.delta) return false;\n agent.streamText = appendStreamText(agent.streamText, event.delta);\n return true;\n }\n default:\n return false;\n }\n}\n\nfunction findStep(agent: WorkflowAgentSnapshot, id: string): WorkflowAgentStep | undefined {\n return agent.steps?.find((s) => s.id === id);\n}\n\nfunction formatCurrentStep(step: WorkflowAgentStep): string {\n return step.detail ? `${step.label}: ${step.detail}` : step.label;\n}\n\nfunction trimSteps(agent: WorkflowAgentSnapshot): void {\n if (!agent.steps || agent.steps.length <= MAX_STEPS) return;\n agent.steps = agent.steps.slice(-MAX_STEPS);\n}\n\nfunction appendStreamText(existing: string | undefined, delta: string): string {\n const next = (existing ?? '') + delta;\n if (next.length <= MAX_STREAM_TEXT) return next;\n return next.slice(-MAX_STREAM_TEXT);\n}\n"],"mappings":";;AAWA,MAAM,YAAY;AAClB,MAAM,kBAAkB;AAExB,SAAgB,sBACd,OACA,OACS;AACT,SAAQ,MAAM,MAAd;EACE,KAAK,cAAc;AACjB,OAAI,CAAC,MAAM,MAAO,OAAM,QAAQ,EAAE;GAClC,MAAM,EAAE,OAAO,WAAW,kBAAkB,MAAM,UAAU,MAAM,KAAK;GACvE,MAAM,OAA0B;IAC9B,IAAI,MAAM;IACV,MAAM;IACN,UAAU,MAAM;IAChB;IACA;IACA,QAAQ;IACR,aAAa,KAAK,KAAK;IACxB;AACD,SAAM,MAAM,KAAK,KAAK;AACtB,aAAU,MAAM;AAChB,SAAM,cAAc,kBAAkB,KAAK;AAC3C,UAAO;;EAET,KAAK,YAAY;GACf,MAAM,OAAO,SAAS,OAAO,MAAM,WAAW;AAC9C,OAAI,CAAC,KAAM,QAAO;AAClB,QAAK,SAAS,MAAM,UAAU,UAAU;AACxC,OAAI,KAAK,eAAe,KAAM,MAAK,aAAa,KAAK,KAAK,GAAG,KAAK;AAClE,OAAI,MAAM,gBAAgB,kBAAkB,KAAK,CAC/C,OAAM,cAAc,KAAA;AAEtB,UAAO;;EAET,KAAK;AACH,SAAM,YAAY,MAAM;AACxB,SAAM,gBAAgB,MAAM;AAC5B,UAAO;EAET,KAAK;AACH,OAAI,CAAC,MAAM,MAAO,QAAO;AACzB,SAAM,aAAa,iBAAiB,MAAM,YAAY,MAAM,MAAM;AAClE,UAAO;EAET,KAAK;AACH,OAAI,CAAC,MAAM,MAAO,QAAO;AACzB,SAAM,aAAa,iBAAiB,MAAM,YAAY,MAAM,MAAM;AAClE,UAAO;EAET,QACE,QAAO;;;AAIb,SAAS,SAAS,OAA8B,IAA2C;AACzF,QAAO,MAAM,OAAO,MAAM,MAAM,EAAE,OAAO,GAAG;;AAG9C,SAAS,kBAAkB,MAAiC;AAC1D,QAAO,KAAK,SAAS,GAAG,KAAK,MAAM,IAAI,KAAK,WAAW,KAAK;;AAG9D,SAAS,UAAU,OAAoC;AACrD,KAAI,CAAC,MAAM,SAAS,MAAM,MAAM,UAAU,UAAW;AACrD,OAAM,QAAQ,MAAM,MAAM,MAAM,CAAC,UAAU;;AAG7C,SAAS,iBAAiB,UAA8B,OAAuB;CAC7E,MAAM,QAAQ,YAAY,MAAM;AAChC,KAAI,KAAK,UAAU,gBAAiB,QAAO;AAC3C,QAAO,KAAK,MAAM,CAAC,gBAAgB"}
1
+ {"version":3,"file":"agent-progress.js","names":[],"sources":["../../../../src/agent/workflow/agent-progress.ts"],"sourcesContent":["/**\n * Apply live subagent progress events onto a {@link WorkflowAgentSnapshot}.\n */\n\nimport type {\n SubagentProgressEvent,\n WorkflowAgentSnapshot,\n WorkflowAgentStep,\n} from './types.js';\nimport { workflowStepLabel } from './step-labels.js';\n\nconst MAX_STEPS = 50;\nconst MAX_STREAM_TEXT = 32_000;\n\nexport function applySubagentProgress(\n agent: WorkflowAgentSnapshot,\n event: SubagentProgressEvent,\n): boolean {\n switch (event.type) {\n case 'tool_start': {\n if (!agent.steps) agent.steps = [];\n const { label, detail } = workflowStepLabel(event.toolName, event.args);\n const step: WorkflowAgentStep = {\n id: event.toolCallId,\n kind: 'tool',\n toolName: event.toolName,\n label,\n detail,\n status: 'running',\n startedAtMs: Date.now(),\n };\n agent.steps.push(step);\n trimSteps(agent);\n agent.currentStep = formatCurrentStep(step);\n return true;\n }\n case 'tool_end': {\n const step = findStep(agent, event.toolCallId);\n if (!step) return false;\n step.status = event.isError ? 'error' : 'done';\n step.resultPreview = event.resultPreview;\n step.error = event.error;\n if (step.startedAtMs != null) step.durationMs = Date.now() - step.startedAtMs;\n if (agent.currentStep === formatCurrentStep(step)) {\n agent.currentStep = undefined;\n }\n return true;\n }\n case 'iteration': {\n agent.iteration = event.count;\n agent.maxIterations = event.max;\n return true;\n }\n case 'text_delta': {\n if (!event.delta) return false;\n agent.streamText = appendStreamText(agent.streamText, event.delta);\n return true;\n }\n case 'thinking_delta': {\n if (!event.delta) return false;\n agent.streamText = appendStreamText(agent.streamText, event.delta);\n return true;\n }\n default:\n return false;\n }\n}\n\nfunction findStep(agent: WorkflowAgentSnapshot, id: string): WorkflowAgentStep | undefined {\n return agent.steps?.find((s) => s.id === id);\n}\n\nfunction formatCurrentStep(step: WorkflowAgentStep): string {\n return step.detail ? `${step.label}: ${step.detail}` : step.label;\n}\n\nfunction trimSteps(agent: WorkflowAgentSnapshot): void {\n if (!agent.steps || agent.steps.length <= MAX_STEPS) return;\n agent.steps = agent.steps.slice(-MAX_STEPS);\n}\n\nfunction appendStreamText(existing: string | undefined, delta: string): string {\n const next = (existing ?? '') + delta;\n if (next.length <= MAX_STREAM_TEXT) return next;\n return next.slice(-MAX_STREAM_TEXT);\n}\n"],"mappings":";;AAWA,MAAM,YAAY;AAClB,MAAM,kBAAkB;AAExB,SAAgB,sBACd,OACA,OACS;AACT,SAAQ,MAAM,MAAd;EACE,KAAK,cAAc;AACjB,OAAI,CAAC,MAAM,MAAO,OAAM,QAAQ,EAAE;GAClC,MAAM,EAAE,OAAO,WAAW,kBAAkB,MAAM,UAAU,MAAM,KAAK;GACvE,MAAM,OAA0B;IAC9B,IAAI,MAAM;IACV,MAAM;IACN,UAAU,MAAM;IAChB;IACA;IACA,QAAQ;IACR,aAAa,KAAK,KAAK;IACxB;AACD,SAAM,MAAM,KAAK,KAAK;AACtB,aAAU,MAAM;AAChB,SAAM,cAAc,kBAAkB,KAAK;AAC3C,UAAO;;EAET,KAAK,YAAY;GACf,MAAM,OAAO,SAAS,OAAO,MAAM,WAAW;AAC9C,OAAI,CAAC,KAAM,QAAO;AAClB,QAAK,SAAS,MAAM,UAAU,UAAU;AACxC,QAAK,gBAAgB,MAAM;AAC3B,QAAK,QAAQ,MAAM;AACnB,OAAI,KAAK,eAAe,KAAM,MAAK,aAAa,KAAK,KAAK,GAAG,KAAK;AAClE,OAAI,MAAM,gBAAgB,kBAAkB,KAAK,CAC/C,OAAM,cAAc,KAAA;AAEtB,UAAO;;EAET,KAAK;AACH,SAAM,YAAY,MAAM;AACxB,SAAM,gBAAgB,MAAM;AAC5B,UAAO;EAET,KAAK;AACH,OAAI,CAAC,MAAM,MAAO,QAAO;AACzB,SAAM,aAAa,iBAAiB,MAAM,YAAY,MAAM,MAAM;AAClE,UAAO;EAET,KAAK;AACH,OAAI,CAAC,MAAM,MAAO,QAAO;AACzB,SAAM,aAAa,iBAAiB,MAAM,YAAY,MAAM,MAAM;AAClE,UAAO;EAET,QACE,QAAO;;;AAIb,SAAS,SAAS,OAA8B,IAA2C;AACzF,QAAO,MAAM,OAAO,MAAM,MAAM,EAAE,OAAO,GAAG;;AAG9C,SAAS,kBAAkB,MAAiC;AAC1D,QAAO,KAAK,SAAS,GAAG,KAAK,MAAM,IAAI,KAAK,WAAW,KAAK;;AAG9D,SAAS,UAAU,OAAoC;AACrD,KAAI,CAAC,MAAM,SAAS,MAAM,MAAM,UAAU,UAAW;AACrD,OAAM,QAAQ,MAAM,MAAM,MAAM,CAAC,UAAU;;AAG7C,SAAS,iBAAiB,UAA8B,OAAuB;CAC7E,MAAM,QAAQ,YAAY,MAAM;AAChC,KAAI,KAAK,UAAU,gBAAiB,QAAO;AAC3C,QAAO,KAAK,MAAM,CAAC,gBAAgB"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Built-in workflow: `client_proposal`
3
+ *
4
+ * Draft a client-facing proposal from a brief — scope, timeline, pricing logic,
5
+ * risks, and next steps. For freelancers, consultants, and solo service providers.
6
+ *
7
+ * Args:
8
+ * - client_brief: what the client wants
9
+ * - offer: what you provide
10
+ * - budget_hint: budget range or constraints (optional)
11
+ */
12
+ export declare const CLIENT_PROPOSAL_SCRIPT = "export const meta = {\n name: 'client_proposal',\n description: 'Turn a client brief into a structured proposal with scope, timeline, pricing logic, and risks.',\n whenToUse: 'Freelancer or solo consultant needs a client-ready proposal or SOW draft.',\n examplePrompts: [\n { field: 'client_brief', text: 'SaaS startup wants 3-month growth consulting, budget 50\u201380k CNY' },\n { field: 'offer', text: 'Audit funnel, weekly strategy calls, async Slack support' },\n ],\n i18n: {\n zh: {\n description: '\u5C06\u5BA2\u6237\u9700\u6C42\u8F6C\u5316\u4E3A\u542B\u8303\u56F4\u3001\u65F6\u95F4\u7EBF\u3001\u62A5\u4EF7\u903B\u8F91\u4E0E\u98CE\u9669\u8BF4\u660E\u7684\u5BA2\u6237\u65B9\u6848\u3002',\n whenToUse: '\u81EA\u7531\u804C\u4E1A\u8005\u6216\u72EC\u7ACB\u987E\u95EE\u9700\u8981\u8D77\u8349\u5BA2\u6237\u65B9\u6848 / SOW \u65F6\u3002',\n examplePrompts: [\n { field: 'client_brief', text: 'SaaS \u521B\u4E1A\u516C\u53F8\u8981 3 \u4E2A\u6708\u589E\u957F\u54A8\u8BE2\uFF0C\u9884\u7B97 5\u20138 \u4E07' },\n { field: 'offer', text: '\u6F0F\u6597\u5BA1\u8BA1\u3001\u6BCF\u5468\u7B56\u7565\u4F1A\u3001Slack \u5F02\u6B65\u652F\u6301' },\n ],\n },\n },\n tags: ['writing', 'content', 'document'],\n estimatedAgents: { min: 4, max: 5 },\n phases: [\n { title: 'Understand' },\n { title: 'Structure' },\n { title: 'Draft' },\n { title: 'Polish' },\n ],\n}\n\nconst clientBrief = args && typeof args === 'object' && args.client_brief\n ? String(args.client_brief)\n : 'Infer the client brief from the most recent user turn.'\n\nconst offer = args && typeof args === 'object' && args.offer\n ? String(args.offer)\n : 'Infer your offer from context.'\n\nconst budgetHint = args && typeof args === 'object' && args.budget_hint\n ? String(args.budget_hint)\n : ''\n\nphase('Understand')\nconst understanding = await agent(\n 'Extract client needs, implicit constraints, success criteria, red flags, and what is out of scope.\\n\\n' +\n 'CLIENT BRIEF:\\n' + clientBrief + '\\nYOUR OFFER:\\n' + offer +\n (budgetHint ? '\\nBUDGET HINT:\\n' + budgetHint : ''),\n {\n label: 'understand',\n schema: {\n type: 'object',\n properties: {\n clientGoals: { type: 'array', items: { type: 'string' } },\n constraints: { type: 'array', items: { type: 'string' } },\n successCriteria: { type: 'array', items: { type: 'string' } },\n redFlags: { type: 'array', items: { type: 'string' } },\n outOfScope: { type: 'array', items: { type: 'string' } },\n },\n required: ['clientGoals', 'successCriteria'],\n },\n },\n)\n\nphase('Structure')\nconst structure = await agent(\n 'Design proposal structure: deliverables, milestones, timeline, pricing tiers or logic, assumptions, and exclusions. Fit a solo operator capacity.\\n\\n' +\n JSON.stringify({ clientBrief, offer, budgetHint, understanding }, null, 2),\n {\n label: 'structure',\n schema: {\n type: 'object',\n properties: {\n deliverables: { type: 'array', items: { type: 'string' } },\n milestones: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n name: { type: 'string' },\n duration: { type: 'string' },\n output: { type: 'string' },\n },\n required: ['name', 'output'],\n },\n },\n pricingApproach: { type: 'string' },\n assumptions: { type: 'array', items: { type: 'string' } },\n },\n required: ['deliverables', 'milestones', 'pricingApproach'],\n },\n },\n)\n\nphase('Draft')\nconst draft = await agent(\n 'Write a client-ready proposal draft in professional but warm tone. Include executive summary, scope, timeline, pricing section (with rationale), risks, and next steps.\\n\\n' +\n JSON.stringify({ understanding, structure }, null, 2),\n {\n label: 'draft',\n schema: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n executiveSummary: { type: 'string' },\n scope: { type: 'string' },\n timeline: { type: 'string' },\n pricing: { type: 'string' },\n risks: { type: 'array', items: { type: 'string' } },\n nextSteps: { type: 'array', items: { type: 'string' } },\n },\n required: ['executiveSummary', 'scope', 'pricing', 'nextSteps'],\n },\n },\n)\n\nphase('Polish')\nconst polished = await agent(\n 'Polish the proposal: tighten language, add a one-line value prop, flag anything that could scare the client, and suggest 2 negotiation flex points.\\n\\n' +\n JSON.stringify(draft, null, 2),\n {\n label: 'polish',\n schema: {\n type: 'object',\n properties: {\n valueProp: { type: 'string' },\n fullProposal: { type: 'string' },\n clientConcerns: { type: 'array', items: { type: 'string' } },\n flexPoints: { type: 'array', items: { type: 'string' } },\n },\n required: ['valueProp', 'fullProposal'],\n },\n },\n)\n\nreturn {\n ok: true,\n understanding,\n structure,\n ...(polished ?? { valueProp: '', fullProposal: 'draft failed' }),\n}\n";
@@ -0,0 +1,155 @@
1
+ //#region src/agent/workflow/builtins/client-proposal.ts
2
+ /**
3
+ * Built-in workflow: `client_proposal`
4
+ *
5
+ * Draft a client-facing proposal from a brief — scope, timeline, pricing logic,
6
+ * risks, and next steps. For freelancers, consultants, and solo service providers.
7
+ *
8
+ * Args:
9
+ * - client_brief: what the client wants
10
+ * - offer: what you provide
11
+ * - budget_hint: budget range or constraints (optional)
12
+ */
13
+ const CLIENT_PROPOSAL_SCRIPT = `export const meta = {
14
+ name: 'client_proposal',
15
+ description: 'Turn a client brief into a structured proposal with scope, timeline, pricing logic, and risks.',
16
+ whenToUse: 'Freelancer or solo consultant needs a client-ready proposal or SOW draft.',
17
+ examplePrompts: [
18
+ { field: 'client_brief', text: 'SaaS startup wants 3-month growth consulting, budget 50–80k CNY' },
19
+ { field: 'offer', text: 'Audit funnel, weekly strategy calls, async Slack support' },
20
+ ],
21
+ i18n: {
22
+ zh: {
23
+ description: '将客户需求转化为含范围、时间线、报价逻辑与风险说明的客户方案。',
24
+ whenToUse: '自由职业者或独立顾问需要起草客户方案 / SOW 时。',
25
+ examplePrompts: [
26
+ { field: 'client_brief', text: 'SaaS 创业公司要 3 个月增长咨询,预算 5–8 万' },
27
+ { field: 'offer', text: '漏斗审计、每周策略会、Slack 异步支持' },
28
+ ],
29
+ },
30
+ },
31
+ tags: ['writing', 'content', 'document'],
32
+ estimatedAgents: { min: 4, max: 5 },
33
+ phases: [
34
+ { title: 'Understand' },
35
+ { title: 'Structure' },
36
+ { title: 'Draft' },
37
+ { title: 'Polish' },
38
+ ],
39
+ }
40
+
41
+ const clientBrief = args && typeof args === 'object' && args.client_brief
42
+ ? String(args.client_brief)
43
+ : 'Infer the client brief from the most recent user turn.'
44
+
45
+ const offer = args && typeof args === 'object' && args.offer
46
+ ? String(args.offer)
47
+ : 'Infer your offer from context.'
48
+
49
+ const budgetHint = args && typeof args === 'object' && args.budget_hint
50
+ ? String(args.budget_hint)
51
+ : ''
52
+
53
+ phase('Understand')
54
+ const understanding = await agent(
55
+ 'Extract client needs, implicit constraints, success criteria, red flags, and what is out of scope.\\n\\n' +
56
+ 'CLIENT BRIEF:\\n' + clientBrief + '\\nYOUR OFFER:\\n' + offer +
57
+ (budgetHint ? '\\nBUDGET HINT:\\n' + budgetHint : ''),
58
+ {
59
+ label: 'understand',
60
+ schema: {
61
+ type: 'object',
62
+ properties: {
63
+ clientGoals: { type: 'array', items: { type: 'string' } },
64
+ constraints: { type: 'array', items: { type: 'string' } },
65
+ successCriteria: { type: 'array', items: { type: 'string' } },
66
+ redFlags: { type: 'array', items: { type: 'string' } },
67
+ outOfScope: { type: 'array', items: { type: 'string' } },
68
+ },
69
+ required: ['clientGoals', 'successCriteria'],
70
+ },
71
+ },
72
+ )
73
+
74
+ phase('Structure')
75
+ const structure = await agent(
76
+ 'Design proposal structure: deliverables, milestones, timeline, pricing tiers or logic, assumptions, and exclusions. Fit a solo operator capacity.\\n\\n' +
77
+ JSON.stringify({ clientBrief, offer, budgetHint, understanding }, null, 2),
78
+ {
79
+ label: 'structure',
80
+ schema: {
81
+ type: 'object',
82
+ properties: {
83
+ deliverables: { type: 'array', items: { type: 'string' } },
84
+ milestones: {
85
+ type: 'array',
86
+ items: {
87
+ type: 'object',
88
+ properties: {
89
+ name: { type: 'string' },
90
+ duration: { type: 'string' },
91
+ output: { type: 'string' },
92
+ },
93
+ required: ['name', 'output'],
94
+ },
95
+ },
96
+ pricingApproach: { type: 'string' },
97
+ assumptions: { type: 'array', items: { type: 'string' } },
98
+ },
99
+ required: ['deliverables', 'milestones', 'pricingApproach'],
100
+ },
101
+ },
102
+ )
103
+
104
+ phase('Draft')
105
+ const draft = await agent(
106
+ 'Write a client-ready proposal draft in professional but warm tone. Include executive summary, scope, timeline, pricing section (with rationale), risks, and next steps.\\n\\n' +
107
+ JSON.stringify({ understanding, structure }, null, 2),
108
+ {
109
+ label: 'draft',
110
+ schema: {
111
+ type: 'object',
112
+ properties: {
113
+ title: { type: 'string' },
114
+ executiveSummary: { type: 'string' },
115
+ scope: { type: 'string' },
116
+ timeline: { type: 'string' },
117
+ pricing: { type: 'string' },
118
+ risks: { type: 'array', items: { type: 'string' } },
119
+ nextSteps: { type: 'array', items: { type: 'string' } },
120
+ },
121
+ required: ['executiveSummary', 'scope', 'pricing', 'nextSteps'],
122
+ },
123
+ },
124
+ )
125
+
126
+ phase('Polish')
127
+ const polished = await agent(
128
+ 'Polish the proposal: tighten language, add a one-line value prop, flag anything that could scare the client, and suggest 2 negotiation flex points.\\n\\n' +
129
+ JSON.stringify(draft, null, 2),
130
+ {
131
+ label: 'polish',
132
+ schema: {
133
+ type: 'object',
134
+ properties: {
135
+ valueProp: { type: 'string' },
136
+ fullProposal: { type: 'string' },
137
+ clientConcerns: { type: 'array', items: { type: 'string' } },
138
+ flexPoints: { type: 'array', items: { type: 'string' } },
139
+ },
140
+ required: ['valueProp', 'fullProposal'],
141
+ },
142
+ },
143
+ )
144
+
145
+ return {
146
+ ok: true,
147
+ understanding,
148
+ structure,
149
+ ...(polished ?? { valueProp: '', fullProposal: 'draft failed' }),
150
+ }
151
+ `;
152
+ //#endregion
153
+ export { CLIENT_PROPOSAL_SCRIPT };
154
+
155
+ //# sourceMappingURL=client-proposal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-proposal.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/client-proposal.ts"],"sourcesContent":["/**\n * Built-in workflow: `client_proposal`\n *\n * Draft a client-facing proposal from a brief — scope, timeline, pricing logic,\n * risks, and next steps. For freelancers, consultants, and solo service providers.\n *\n * Args:\n * - client_brief: what the client wants\n * - offer: what you provide\n * - budget_hint: budget range or constraints (optional)\n */\n\nexport const CLIENT_PROPOSAL_SCRIPT = `export const meta = {\n name: 'client_proposal',\n description: 'Turn a client brief into a structured proposal with scope, timeline, pricing logic, and risks.',\n whenToUse: 'Freelancer or solo consultant needs a client-ready proposal or SOW draft.',\n examplePrompts: [\n { field: 'client_brief', text: 'SaaS startup wants 3-month growth consulting, budget 50–80k CNY' },\n { field: 'offer', text: 'Audit funnel, weekly strategy calls, async Slack support' },\n ],\n i18n: {\n zh: {\n description: '将客户需求转化为含范围、时间线、报价逻辑与风险说明的客户方案。',\n whenToUse: '自由职业者或独立顾问需要起草客户方案 / SOW 时。',\n examplePrompts: [\n { field: 'client_brief', text: 'SaaS 创业公司要 3 个月增长咨询,预算 5–8 万' },\n { field: 'offer', text: '漏斗审计、每周策略会、Slack 异步支持' },\n ],\n },\n },\n tags: ['writing', 'content', 'document'],\n estimatedAgents: { min: 4, max: 5 },\n phases: [\n { title: 'Understand' },\n { title: 'Structure' },\n { title: 'Draft' },\n { title: 'Polish' },\n ],\n}\n\nconst clientBrief = args && typeof args === 'object' && args.client_brief\n ? String(args.client_brief)\n : 'Infer the client brief from the most recent user turn.'\n\nconst offer = args && typeof args === 'object' && args.offer\n ? String(args.offer)\n : 'Infer your offer from context.'\n\nconst budgetHint = args && typeof args === 'object' && args.budget_hint\n ? String(args.budget_hint)\n : ''\n\nphase('Understand')\nconst understanding = await agent(\n 'Extract client needs, implicit constraints, success criteria, red flags, and what is out of scope.\\\\n\\\\n' +\n 'CLIENT BRIEF:\\\\n' + clientBrief + '\\\\nYOUR OFFER:\\\\n' + offer +\n (budgetHint ? '\\\\nBUDGET HINT:\\\\n' + budgetHint : ''),\n {\n label: 'understand',\n schema: {\n type: 'object',\n properties: {\n clientGoals: { type: 'array', items: { type: 'string' } },\n constraints: { type: 'array', items: { type: 'string' } },\n successCriteria: { type: 'array', items: { type: 'string' } },\n redFlags: { type: 'array', items: { type: 'string' } },\n outOfScope: { type: 'array', items: { type: 'string' } },\n },\n required: ['clientGoals', 'successCriteria'],\n },\n },\n)\n\nphase('Structure')\nconst structure = await agent(\n 'Design proposal structure: deliverables, milestones, timeline, pricing tiers or logic, assumptions, and exclusions. Fit a solo operator capacity.\\\\n\\\\n' +\n JSON.stringify({ clientBrief, offer, budgetHint, understanding }, null, 2),\n {\n label: 'structure',\n schema: {\n type: 'object',\n properties: {\n deliverables: { type: 'array', items: { type: 'string' } },\n milestones: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n name: { type: 'string' },\n duration: { type: 'string' },\n output: { type: 'string' },\n },\n required: ['name', 'output'],\n },\n },\n pricingApproach: { type: 'string' },\n assumptions: { type: 'array', items: { type: 'string' } },\n },\n required: ['deliverables', 'milestones', 'pricingApproach'],\n },\n },\n)\n\nphase('Draft')\nconst draft = await agent(\n 'Write a client-ready proposal draft in professional but warm tone. Include executive summary, scope, timeline, pricing section (with rationale), risks, and next steps.\\\\n\\\\n' +\n JSON.stringify({ understanding, structure }, null, 2),\n {\n label: 'draft',\n schema: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n executiveSummary: { type: 'string' },\n scope: { type: 'string' },\n timeline: { type: 'string' },\n pricing: { type: 'string' },\n risks: { type: 'array', items: { type: 'string' } },\n nextSteps: { type: 'array', items: { type: 'string' } },\n },\n required: ['executiveSummary', 'scope', 'pricing', 'nextSteps'],\n },\n },\n)\n\nphase('Polish')\nconst polished = await agent(\n 'Polish the proposal: tighten language, add a one-line value prop, flag anything that could scare the client, and suggest 2 negotiation flex points.\\\\n\\\\n' +\n JSON.stringify(draft, null, 2),\n {\n label: 'polish',\n schema: {\n type: 'object',\n properties: {\n valueProp: { type: 'string' },\n fullProposal: { type: 'string' },\n clientConcerns: { type: 'array', items: { type: 'string' } },\n flexPoints: { type: 'array', items: { type: 'string' } },\n },\n required: ['valueProp', 'fullProposal'],\n },\n },\n)\n\nreturn {\n ok: true,\n understanding,\n structure,\n ...(polished ?? { valueProp: '', fullProposal: 'draft failed' }),\n}\n`\n"],"mappings":";;;;;;;;;;;;AAYA,MAAa,yBAAyB"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Built-in workflow: `competitor_scan`
3
+ *
4
+ * Parallel competitor scan for solopreneurs — positioning, pricing, strengths,
5
+ * weaknesses, and differentiation opportunities.
6
+ *
7
+ * Args:
8
+ * - market: what you are building or selling
9
+ * - competitors: competitor names (optional)
10
+ * - focus: what you care most about (optional)
11
+ */
12
+ export declare const COMPETITOR_SCAN_SCRIPT = "export const meta = {\n name: 'competitor_scan',\n description: 'Scan competitors in parallel and synthesize positioning, pricing, and differentiation opportunities.',\n whenToUse: 'Solo founder comparing alternatives before pricing, positioning, or go-to-market decisions.',\n examplePrompts: [\n { field: 'market', text: 'AI writing assistant for solo creators' },\n { field: 'competitors', text: 'Notion AI, Jasper, Cursor' },\n ],\n i18n: {\n zh: {\n description: '\u5E76\u884C\u626B\u63CF\u7ADE\u54C1\uFF0C\u7EFC\u5408\u5B9A\u4F4D\u3001\u5B9A\u4EF7\u4E0E\u5DEE\u5F02\u5316\u673A\u4F1A\u3002',\n whenToUse: '\u4E00\u4EBA\u516C\u53F8\u5728\u5B9A\u4EF7\u3001\u5B9A\u4F4D\u6216\u8FDB\u5165\u5E02\u573A\u524D\u9700\u8981\u7ADE\u54C1\u5BF9\u6BD4\u65F6\u3002',\n examplePrompts: [\n { field: 'market', text: '\u9762\u5411\u72EC\u7ACB\u521B\u4F5C\u8005\u7684 AI \u5199\u4F5C\u52A9\u624B' },\n { field: 'competitors', text: 'Notion AI\u3001Jasper\u3001Cursor' },\n ],\n },\n },\n tags: ['research', 'investigation'],\n estimatedAgents: { min: 4, max: 7 },\n phases: [\n { title: 'Frame' },\n { title: 'Scan' },\n { title: 'Synthesize' },\n ],\n}\n\nconst RESEARCH_TOOLS = ['web_search', 'web_fetch']\n\nconst market = args && typeof args === 'object' && args.market\n ? String(args.market)\n : 'Infer the market from the most recent user turn.'\n\nconst competitorsRaw = args && typeof args === 'object' && args.competitors\n ? String(args.competitors)\n : ''\n\nconst focus = args && typeof args === 'object' && args.focus\n ? String(args.focus)\n : 'positioning and pricing'\n\nphase('Frame')\nconst frame = await agent(\n 'Frame this competitor scan. If competitors are not listed, propose 3\u20134 realistic competitors. Return scan criteria and your assumed buyer persona.\\n\\n' +\n 'MARKET:\\n' + market + '\\n' +\n (competitorsRaw ? 'COMPETITORS:\\n' + competitorsRaw + '\\n' : '') +\n 'FOCUS:\\n' + focus,\n {\n label: 'frame',\n toolset: RESEARCH_TOOLS,\n schema: {\n type: 'object',\n properties: {\n competitors: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n name: { type: 'string' },\n oneLiner: { type: 'string' },\n },\n required: ['name'],\n },\n },\n criteria: { type: 'array', items: { type: 'string' } },\n buyerPersona: { type: 'string' },\n },\n required: ['competitors', 'criteria'],\n },\n },\n)\n\nif (!frame || !frame.competitors?.length) {\n return { ok: false, reason: 'framing failed', market }\n}\n\nconst competitors = frame.competitors.slice(0, 4)\n\nphase('Scan')\nconst scans = await parallel(\n competitors.map((c) => () =>\n agent(\n 'Research this competitor for a solo founder. Use web search. Return positioning, pricing model, strengths, weaknesses, and target customer \u2014 cite sources where possible.\\n\\n' +\n 'COMPETITOR: ' + c.name + '\\nMARKET: ' + market + '\\nFOCUS: ' + focus,\n {\n label: c.name,\n toolset: RESEARCH_TOOLS,\n maxIterations: 25,\n schema: {\n type: 'object',\n properties: {\n name: { type: 'string' },\n positioning: { type: 'string' },\n pricing: { type: 'string' },\n strengths: { type: 'array', items: { type: 'string' } },\n weaknesses: { type: 'array', items: { type: 'string' } },\n targetCustomer: { type: 'string' },\n sources: { type: 'array', items: { type: 'string' } },\n },\n required: ['name', 'positioning', 'strengths', 'weaknesses'],\n },\n },\n ),\n ),\n)\n\nphase('Synthesize')\nconst synthesis = await agent(\n 'Synthesize a competitor matrix and differentiation playbook for a one-person company. Include whitespace opportunities, pricing band recommendation, and 3 positioning angles to test.\\n\\n' +\n JSON.stringify({ market, focus, frame, scans: scans.filter(Boolean) }, null, 2),\n {\n label: 'synthesis',\n schema: {\n type: 'object',\n properties: {\n matrixSummary: { type: 'string' },\n whitespace: { type: 'array', items: { type: 'string' } },\n pricingBand: { type: 'string' },\n positioningAngles: { type: 'array', items: { type: 'string' } },\n avoidCompetingOn: { type: 'array', items: { type: 'string' } },\n },\n required: ['matrixSummary', 'whitespace', 'positioningAngles'],\n },\n },\n)\n\nreturn {\n ok: true,\n market,\n competitorCount: competitors.length,\n scans: scans.filter(Boolean),\n ...(synthesis ?? { matrixSummary: 'synthesis failed', whitespace: [], positioningAngles: [] }),\n}\n";
@@ -0,0 +1,150 @@
1
+ //#region src/agent/workflow/builtins/competitor-scan.ts
2
+ /**
3
+ * Built-in workflow: `competitor_scan`
4
+ *
5
+ * Parallel competitor scan for solopreneurs — positioning, pricing, strengths,
6
+ * weaknesses, and differentiation opportunities.
7
+ *
8
+ * Args:
9
+ * - market: what you are building or selling
10
+ * - competitors: competitor names (optional)
11
+ * - focus: what you care most about (optional)
12
+ */
13
+ const COMPETITOR_SCAN_SCRIPT = `export const meta = {
14
+ name: 'competitor_scan',
15
+ description: 'Scan competitors in parallel and synthesize positioning, pricing, and differentiation opportunities.',
16
+ whenToUse: 'Solo founder comparing alternatives before pricing, positioning, or go-to-market decisions.',
17
+ examplePrompts: [
18
+ { field: 'market', text: 'AI writing assistant for solo creators' },
19
+ { field: 'competitors', text: 'Notion AI, Jasper, Cursor' },
20
+ ],
21
+ i18n: {
22
+ zh: {
23
+ description: '并行扫描竞品,综合定位、定价与差异化机会。',
24
+ whenToUse: '一人公司在定价、定位或进入市场前需要竞品对比时。',
25
+ examplePrompts: [
26
+ { field: 'market', text: '面向独立创作者的 AI 写作助手' },
27
+ { field: 'competitors', text: 'Notion AI、Jasper、Cursor' },
28
+ ],
29
+ },
30
+ },
31
+ tags: ['research', 'investigation'],
32
+ estimatedAgents: { min: 4, max: 7 },
33
+ phases: [
34
+ { title: 'Frame' },
35
+ { title: 'Scan' },
36
+ { title: 'Synthesize' },
37
+ ],
38
+ }
39
+
40
+ const RESEARCH_TOOLS = ['web_search', 'web_fetch']
41
+
42
+ const market = args && typeof args === 'object' && args.market
43
+ ? String(args.market)
44
+ : 'Infer the market from the most recent user turn.'
45
+
46
+ const competitorsRaw = args && typeof args === 'object' && args.competitors
47
+ ? String(args.competitors)
48
+ : ''
49
+
50
+ const focus = args && typeof args === 'object' && args.focus
51
+ ? String(args.focus)
52
+ : 'positioning and pricing'
53
+
54
+ phase('Frame')
55
+ const frame = await agent(
56
+ 'Frame this competitor scan. If competitors are not listed, propose 3–4 realistic competitors. Return scan criteria and your assumed buyer persona.\\n\\n' +
57
+ 'MARKET:\\n' + market + '\\n' +
58
+ (competitorsRaw ? 'COMPETITORS:\\n' + competitorsRaw + '\\n' : '') +
59
+ 'FOCUS:\\n' + focus,
60
+ {
61
+ label: 'frame',
62
+ toolset: RESEARCH_TOOLS,
63
+ schema: {
64
+ type: 'object',
65
+ properties: {
66
+ competitors: {
67
+ type: 'array',
68
+ items: {
69
+ type: 'object',
70
+ properties: {
71
+ name: { type: 'string' },
72
+ oneLiner: { type: 'string' },
73
+ },
74
+ required: ['name'],
75
+ },
76
+ },
77
+ criteria: { type: 'array', items: { type: 'string' } },
78
+ buyerPersona: { type: 'string' },
79
+ },
80
+ required: ['competitors', 'criteria'],
81
+ },
82
+ },
83
+ )
84
+
85
+ if (!frame || !frame.competitors?.length) {
86
+ return { ok: false, reason: 'framing failed', market }
87
+ }
88
+
89
+ const competitors = frame.competitors.slice(0, 4)
90
+
91
+ phase('Scan')
92
+ const scans = await parallel(
93
+ competitors.map((c) => () =>
94
+ agent(
95
+ 'Research this competitor for a solo founder. Use web search. Return positioning, pricing model, strengths, weaknesses, and target customer — cite sources where possible.\\n\\n' +
96
+ 'COMPETITOR: ' + c.name + '\\nMARKET: ' + market + '\\nFOCUS: ' + focus,
97
+ {
98
+ label: c.name,
99
+ toolset: RESEARCH_TOOLS,
100
+ maxIterations: 25,
101
+ schema: {
102
+ type: 'object',
103
+ properties: {
104
+ name: { type: 'string' },
105
+ positioning: { type: 'string' },
106
+ pricing: { type: 'string' },
107
+ strengths: { type: 'array', items: { type: 'string' } },
108
+ weaknesses: { type: 'array', items: { type: 'string' } },
109
+ targetCustomer: { type: 'string' },
110
+ sources: { type: 'array', items: { type: 'string' } },
111
+ },
112
+ required: ['name', 'positioning', 'strengths', 'weaknesses'],
113
+ },
114
+ },
115
+ ),
116
+ ),
117
+ )
118
+
119
+ phase('Synthesize')
120
+ const synthesis = await agent(
121
+ 'Synthesize a competitor matrix and differentiation playbook for a one-person company. Include whitespace opportunities, pricing band recommendation, and 3 positioning angles to test.\\n\\n' +
122
+ JSON.stringify({ market, focus, frame, scans: scans.filter(Boolean) }, null, 2),
123
+ {
124
+ label: 'synthesis',
125
+ schema: {
126
+ type: 'object',
127
+ properties: {
128
+ matrixSummary: { type: 'string' },
129
+ whitespace: { type: 'array', items: { type: 'string' } },
130
+ pricingBand: { type: 'string' },
131
+ positioningAngles: { type: 'array', items: { type: 'string' } },
132
+ avoidCompetingOn: { type: 'array', items: { type: 'string' } },
133
+ },
134
+ required: ['matrixSummary', 'whitespace', 'positioningAngles'],
135
+ },
136
+ },
137
+ )
138
+
139
+ return {
140
+ ok: true,
141
+ market,
142
+ competitorCount: competitors.length,
143
+ scans: scans.filter(Boolean),
144
+ ...(synthesis ?? { matrixSummary: 'synthesis failed', whitespace: [], positioningAngles: [] }),
145
+ }
146
+ `;
147
+ //#endregion
148
+ export { COMPETITOR_SCAN_SCRIPT };
149
+
150
+ //# sourceMappingURL=competitor-scan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"competitor-scan.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/competitor-scan.ts"],"sourcesContent":["/**\n * Built-in workflow: `competitor_scan`\n *\n * Parallel competitor scan for solopreneurs — positioning, pricing, strengths,\n * weaknesses, and differentiation opportunities.\n *\n * Args:\n * - market: what you are building or selling\n * - competitors: competitor names (optional)\n * - focus: what you care most about (optional)\n */\n\nexport const COMPETITOR_SCAN_SCRIPT = `export const meta = {\n name: 'competitor_scan',\n description: 'Scan competitors in parallel and synthesize positioning, pricing, and differentiation opportunities.',\n whenToUse: 'Solo founder comparing alternatives before pricing, positioning, or go-to-market decisions.',\n examplePrompts: [\n { field: 'market', text: 'AI writing assistant for solo creators' },\n { field: 'competitors', text: 'Notion AI, Jasper, Cursor' },\n ],\n i18n: {\n zh: {\n description: '并行扫描竞品,综合定位、定价与差异化机会。',\n whenToUse: '一人公司在定价、定位或进入市场前需要竞品对比时。',\n examplePrompts: [\n { field: 'market', text: '面向独立创作者的 AI 写作助手' },\n { field: 'competitors', text: 'Notion AI、Jasper、Cursor' },\n ],\n },\n },\n tags: ['research', 'investigation'],\n estimatedAgents: { min: 4, max: 7 },\n phases: [\n { title: 'Frame' },\n { title: 'Scan' },\n { title: 'Synthesize' },\n ],\n}\n\nconst RESEARCH_TOOLS = ['web_search', 'web_fetch']\n\nconst market = args && typeof args === 'object' && args.market\n ? String(args.market)\n : 'Infer the market from the most recent user turn.'\n\nconst competitorsRaw = args && typeof args === 'object' && args.competitors\n ? String(args.competitors)\n : ''\n\nconst focus = args && typeof args === 'object' && args.focus\n ? String(args.focus)\n : 'positioning and pricing'\n\nphase('Frame')\nconst frame = await agent(\n 'Frame this competitor scan. If competitors are not listed, propose 3–4 realistic competitors. Return scan criteria and your assumed buyer persona.\\\\n\\\\n' +\n 'MARKET:\\\\n' + market + '\\\\n' +\n (competitorsRaw ? 'COMPETITORS:\\\\n' + competitorsRaw + '\\\\n' : '') +\n 'FOCUS:\\\\n' + focus,\n {\n label: 'frame',\n toolset: RESEARCH_TOOLS,\n schema: {\n type: 'object',\n properties: {\n competitors: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n name: { type: 'string' },\n oneLiner: { type: 'string' },\n },\n required: ['name'],\n },\n },\n criteria: { type: 'array', items: { type: 'string' } },\n buyerPersona: { type: 'string' },\n },\n required: ['competitors', 'criteria'],\n },\n },\n)\n\nif (!frame || !frame.competitors?.length) {\n return { ok: false, reason: 'framing failed', market }\n}\n\nconst competitors = frame.competitors.slice(0, 4)\n\nphase('Scan')\nconst scans = await parallel(\n competitors.map((c) => () =>\n agent(\n 'Research this competitor for a solo founder. Use web search. Return positioning, pricing model, strengths, weaknesses, and target customer — cite sources where possible.\\\\n\\\\n' +\n 'COMPETITOR: ' + c.name + '\\\\nMARKET: ' + market + '\\\\nFOCUS: ' + focus,\n {\n label: c.name,\n toolset: RESEARCH_TOOLS,\n maxIterations: 25,\n schema: {\n type: 'object',\n properties: {\n name: { type: 'string' },\n positioning: { type: 'string' },\n pricing: { type: 'string' },\n strengths: { type: 'array', items: { type: 'string' } },\n weaknesses: { type: 'array', items: { type: 'string' } },\n targetCustomer: { type: 'string' },\n sources: { type: 'array', items: { type: 'string' } },\n },\n required: ['name', 'positioning', 'strengths', 'weaknesses'],\n },\n },\n ),\n ),\n)\n\nphase('Synthesize')\nconst synthesis = await agent(\n 'Synthesize a competitor matrix and differentiation playbook for a one-person company. Include whitespace opportunities, pricing band recommendation, and 3 positioning angles to test.\\\\n\\\\n' +\n JSON.stringify({ market, focus, frame, scans: scans.filter(Boolean) }, null, 2),\n {\n label: 'synthesis',\n schema: {\n type: 'object',\n properties: {\n matrixSummary: { type: 'string' },\n whitespace: { type: 'array', items: { type: 'string' } },\n pricingBand: { type: 'string' },\n positioningAngles: { type: 'array', items: { type: 'string' } },\n avoidCompetingOn: { type: 'array', items: { type: 'string' } },\n },\n required: ['matrixSummary', 'whitespace', 'positioningAngles'],\n },\n },\n)\n\nreturn {\n ok: true,\n market,\n competitorCount: competitors.length,\n scans: scans.filter(Boolean),\n ...(synthesis ?? { matrixSummary: 'synthesis failed', whitespace: [], positioningAngles: [] }),\n}\n`\n"],"mappings":";;;;;;;;;;;;AAYA,MAAa,yBAAyB"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Built-in workflow: `content_draft`
3
+ *
4
+ * Multi-angle content drafting for non-code writing tasks — emails, posts,
5
+ * announcements, docs, or messages. Fans out tone/audience angles in parallel,
6
+ * then synthesizes a polished draft with variants.
7
+ *
8
+ * Args:
9
+ * - topic: what to write about
10
+ * - audience: who will read it (optional)
11
+ * - format: email | post | announcement | document | message (optional)
12
+ */
13
+ export declare const CONTENT_DRAFT_SCRIPT = "export const meta = {\n name: 'content_draft',\n description: 'Draft polished content from multiple tone and audience angles, then synthesize the best version.',\n whenToUse: 'User needs help writing an email, post, announcement, doc section, or message \u2014 not code.',\n examplePrompts: [\n { field: 'topic', text: 'Write a product launch announcement for our mobile app update' },\n { field: 'topic', text: 'Draft a polite follow-up email after a missed meeting' },\n ],\n i18n: {\n zh: {\n description: '\u4ECE\u591A\u4E2A\u8BED\u6C14\u4E0E\u53D7\u4F17\u89D2\u5EA6\u8D77\u8349\u5185\u5BB9\uFF0C\u5E76\u7EFC\u5408\u4EA7\u51FA\u6700\u4F73\u7248\u672C\u3002',\n whenToUse: '\u7528\u6237\u9700\u8981\u5199\u90AE\u4EF6\u3001\u5E16\u5B50\u3001\u516C\u544A\u3001\u6587\u6863\u6BB5\u843D\u6216\u6D88\u606F\u7B49\u975E\u4EE3\u7801\u5185\u5BB9\u65F6\u3002',\n examplePrompts: [\n { field: 'topic', text: '\u5199\u4E00\u4EFD\u79FB\u52A8\u7AEF\u5E94\u7528\u66F4\u65B0\u7684\u4EA7\u54C1\u53D1\u5E03\u516C\u544A' },\n { field: 'topic', text: '\u8D77\u8349\u4E00\u5C01\u9519\u8FC7\u4F1A\u8BAE\u540E\u7684\u793C\u8C8C\u8DDF\u8FDB\u90AE\u4EF6' },\n ],\n },\n },\n tags: ['writing', 'content', 'communication'],\n estimatedAgents: { min: 4, max: 6 },\n phases: [\n { title: 'Brief' },\n { title: 'Angles' },\n { title: 'Draft' },\n ],\n}\n\nconst topic = args && typeof args === 'object' && args.topic\n ? String(args.topic)\n : 'Infer the writing topic from the most recent user turn.'\n\nconst audience = args && typeof args === 'object' && args.audience\n ? String(args.audience)\n : 'general professional audience'\n\nconst format = args && typeof args === 'object' && args.format\n ? String(args.format)\n : 'document'\n\nphase('Brief')\nconst brief = await agent(\n 'Clarify this writing brief. Return the core message, constraints, tone guidance, and 3 distinct angles worth exploring (each with a hook and key point).\\n\\n' +\n 'TOPIC:\\n' + topic + '\\nAUDIENCE:\\n' + audience + '\\nFORMAT:\\n' + format,\n {\n label: 'brief',\n schema: {\n type: 'object',\n properties: {\n coreMessage: { type: 'string' },\n tone: { type: 'string' },\n constraints: { type: 'array', items: { type: 'string' } },\n angles: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n hook: { type: 'string' },\n keyPoint: { type: 'string' },\n },\n required: ['title', 'hook', 'keyPoint'],\n },\n },\n },\n required: ['coreMessage', 'angles'],\n },\n },\n)\n\nif (!brief || !brief.angles?.length) {\n return { ok: false, reason: 'briefing failed', topic, audience, format }\n}\n\nconst angles = brief.angles.slice(0, 3)\n\nphase('Angles')\nconst angleDrafts = await parallel(\n angles.map((a) => () =>\n agent(\n 'Write a complete draft for this angle. Match the requested format and audience. Keep it ready to send or publish with minimal edits.\\n\\n' +\n 'FORMAT: ' + format + '\\nAUDIENCE: ' + audience + '\\nCORE MESSAGE: ' + brief.coreMessage + '\\n' +\n 'ANGLE: ' + a.title + '\\nHOOK: ' + a.hook + '\\nKEY POINT: ' + a.keyPoint,\n {\n label: a.title,\n schema: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n body: { type: 'string' },\n subject: { type: 'string' },\n },\n required: ['title', 'body'],\n },\n },\n ),\n ),\n)\n\nphase('Draft')\nconst live = angleDrafts.filter(Boolean)\nconst finalDraft = await agent(\n 'Synthesize the best final draft from these angle-level versions. Pick the strongest hook and structure, merge the best lines, and remove redundancy. ' +\n 'Return the polished draft plus a one-line rationale and two optional shorter variants (e.g. social / SMS length).\\n\\n' +\n JSON.stringify({ brief, drafts: live }, null, 2),\n {\n label: 'final draft',\n schema: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n subject: { type: 'string' },\n body: { type: 'string' },\n rationale: { type: 'string' },\n shortVariants: { type: 'array', items: { type: 'string' } },\n },\n required: ['body', 'rationale'],\n },\n },\n)\n\nreturn {\n ok: true,\n topic,\n audience,\n format,\n angleCount: angles.length,\n ...(finalDraft ?? { body: 'draft synthesis failed', rationale: '' }),\n}\n";
@@ -0,0 +1,146 @@
1
+ //#region src/agent/workflow/builtins/content-draft.ts
2
+ /**
3
+ * Built-in workflow: `content_draft`
4
+ *
5
+ * Multi-angle content drafting for non-code writing tasks — emails, posts,
6
+ * announcements, docs, or messages. Fans out tone/audience angles in parallel,
7
+ * then synthesizes a polished draft with variants.
8
+ *
9
+ * Args:
10
+ * - topic: what to write about
11
+ * - audience: who will read it (optional)
12
+ * - format: email | post | announcement | document | message (optional)
13
+ */
14
+ const CONTENT_DRAFT_SCRIPT = `export const meta = {
15
+ name: 'content_draft',
16
+ description: 'Draft polished content from multiple tone and audience angles, then synthesize the best version.',
17
+ whenToUse: 'User needs help writing an email, post, announcement, doc section, or message — not code.',
18
+ examplePrompts: [
19
+ { field: 'topic', text: 'Write a product launch announcement for our mobile app update' },
20
+ { field: 'topic', text: 'Draft a polite follow-up email after a missed meeting' },
21
+ ],
22
+ i18n: {
23
+ zh: {
24
+ description: '从多个语气与受众角度起草内容,并综合产出最佳版本。',
25
+ whenToUse: '用户需要写邮件、帖子、公告、文档段落或消息等非代码内容时。',
26
+ examplePrompts: [
27
+ { field: 'topic', text: '写一份移动端应用更新的产品发布公告' },
28
+ { field: 'topic', text: '起草一封错过会议后的礼貌跟进邮件' },
29
+ ],
30
+ },
31
+ },
32
+ tags: ['writing', 'content', 'communication'],
33
+ estimatedAgents: { min: 4, max: 6 },
34
+ phases: [
35
+ { title: 'Brief' },
36
+ { title: 'Angles' },
37
+ { title: 'Draft' },
38
+ ],
39
+ }
40
+
41
+ const topic = args && typeof args === 'object' && args.topic
42
+ ? String(args.topic)
43
+ : 'Infer the writing topic from the most recent user turn.'
44
+
45
+ const audience = args && typeof args === 'object' && args.audience
46
+ ? String(args.audience)
47
+ : 'general professional audience'
48
+
49
+ const format = args && typeof args === 'object' && args.format
50
+ ? String(args.format)
51
+ : 'document'
52
+
53
+ phase('Brief')
54
+ const brief = await agent(
55
+ 'Clarify this writing brief. Return the core message, constraints, tone guidance, and 3 distinct angles worth exploring (each with a hook and key point).\\n\\n' +
56
+ 'TOPIC:\\n' + topic + '\\nAUDIENCE:\\n' + audience + '\\nFORMAT:\\n' + format,
57
+ {
58
+ label: 'brief',
59
+ schema: {
60
+ type: 'object',
61
+ properties: {
62
+ coreMessage: { type: 'string' },
63
+ tone: { type: 'string' },
64
+ constraints: { type: 'array', items: { type: 'string' } },
65
+ angles: {
66
+ type: 'array',
67
+ items: {
68
+ type: 'object',
69
+ properties: {
70
+ title: { type: 'string' },
71
+ hook: { type: 'string' },
72
+ keyPoint: { type: 'string' },
73
+ },
74
+ required: ['title', 'hook', 'keyPoint'],
75
+ },
76
+ },
77
+ },
78
+ required: ['coreMessage', 'angles'],
79
+ },
80
+ },
81
+ )
82
+
83
+ if (!brief || !brief.angles?.length) {
84
+ return { ok: false, reason: 'briefing failed', topic, audience, format }
85
+ }
86
+
87
+ const angles = brief.angles.slice(0, 3)
88
+
89
+ phase('Angles')
90
+ const angleDrafts = await parallel(
91
+ angles.map((a) => () =>
92
+ agent(
93
+ 'Write a complete draft for this angle. Match the requested format and audience. Keep it ready to send or publish with minimal edits.\\n\\n' +
94
+ 'FORMAT: ' + format + '\\nAUDIENCE: ' + audience + '\\nCORE MESSAGE: ' + brief.coreMessage + '\\n' +
95
+ 'ANGLE: ' + a.title + '\\nHOOK: ' + a.hook + '\\nKEY POINT: ' + a.keyPoint,
96
+ {
97
+ label: a.title,
98
+ schema: {
99
+ type: 'object',
100
+ properties: {
101
+ title: { type: 'string' },
102
+ body: { type: 'string' },
103
+ subject: { type: 'string' },
104
+ },
105
+ required: ['title', 'body'],
106
+ },
107
+ },
108
+ ),
109
+ ),
110
+ )
111
+
112
+ phase('Draft')
113
+ const live = angleDrafts.filter(Boolean)
114
+ const finalDraft = await agent(
115
+ 'Synthesize the best final draft from these angle-level versions. Pick the strongest hook and structure, merge the best lines, and remove redundancy. ' +
116
+ 'Return the polished draft plus a one-line rationale and two optional shorter variants (e.g. social / SMS length).\\n\\n' +
117
+ JSON.stringify({ brief, drafts: live }, null, 2),
118
+ {
119
+ label: 'final draft',
120
+ schema: {
121
+ type: 'object',
122
+ properties: {
123
+ title: { type: 'string' },
124
+ subject: { type: 'string' },
125
+ body: { type: 'string' },
126
+ rationale: { type: 'string' },
127
+ shortVariants: { type: 'array', items: { type: 'string' } },
128
+ },
129
+ required: ['body', 'rationale'],
130
+ },
131
+ },
132
+ )
133
+
134
+ return {
135
+ ok: true,
136
+ topic,
137
+ audience,
138
+ format,
139
+ angleCount: angles.length,
140
+ ...(finalDraft ?? { body: 'draft synthesis failed', rationale: '' }),
141
+ }
142
+ `;
143
+ //#endregion
144
+ export { CONTENT_DRAFT_SCRIPT };
145
+
146
+ //# sourceMappingURL=content-draft.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-draft.js","names":[],"sources":["../../../../../src/agent/workflow/builtins/content-draft.ts"],"sourcesContent":["/**\n * Built-in workflow: `content_draft`\n *\n * Multi-angle content drafting for non-code writing tasks — emails, posts,\n * announcements, docs, or messages. Fans out tone/audience angles in parallel,\n * then synthesizes a polished draft with variants.\n *\n * Args:\n * - topic: what to write about\n * - audience: who will read it (optional)\n * - format: email | post | announcement | document | message (optional)\n */\n\nexport const CONTENT_DRAFT_SCRIPT = `export const meta = {\n name: 'content_draft',\n description: 'Draft polished content from multiple tone and audience angles, then synthesize the best version.',\n whenToUse: 'User needs help writing an email, post, announcement, doc section, or message — not code.',\n examplePrompts: [\n { field: 'topic', text: 'Write a product launch announcement for our mobile app update' },\n { field: 'topic', text: 'Draft a polite follow-up email after a missed meeting' },\n ],\n i18n: {\n zh: {\n description: '从多个语气与受众角度起草内容,并综合产出最佳版本。',\n whenToUse: '用户需要写邮件、帖子、公告、文档段落或消息等非代码内容时。',\n examplePrompts: [\n { field: 'topic', text: '写一份移动端应用更新的产品发布公告' },\n { field: 'topic', text: '起草一封错过会议后的礼貌跟进邮件' },\n ],\n },\n },\n tags: ['writing', 'content', 'communication'],\n estimatedAgents: { min: 4, max: 6 },\n phases: [\n { title: 'Brief' },\n { title: 'Angles' },\n { title: 'Draft' },\n ],\n}\n\nconst topic = args && typeof args === 'object' && args.topic\n ? String(args.topic)\n : 'Infer the writing topic from the most recent user turn.'\n\nconst audience = args && typeof args === 'object' && args.audience\n ? String(args.audience)\n : 'general professional audience'\n\nconst format = args && typeof args === 'object' && args.format\n ? String(args.format)\n : 'document'\n\nphase('Brief')\nconst brief = await agent(\n 'Clarify this writing brief. Return the core message, constraints, tone guidance, and 3 distinct angles worth exploring (each with a hook and key point).\\\\n\\\\n' +\n 'TOPIC:\\\\n' + topic + '\\\\nAUDIENCE:\\\\n' + audience + '\\\\nFORMAT:\\\\n' + format,\n {\n label: 'brief',\n schema: {\n type: 'object',\n properties: {\n coreMessage: { type: 'string' },\n tone: { type: 'string' },\n constraints: { type: 'array', items: { type: 'string' } },\n angles: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n hook: { type: 'string' },\n keyPoint: { type: 'string' },\n },\n required: ['title', 'hook', 'keyPoint'],\n },\n },\n },\n required: ['coreMessage', 'angles'],\n },\n },\n)\n\nif (!brief || !brief.angles?.length) {\n return { ok: false, reason: 'briefing failed', topic, audience, format }\n}\n\nconst angles = brief.angles.slice(0, 3)\n\nphase('Angles')\nconst angleDrafts = await parallel(\n angles.map((a) => () =>\n agent(\n 'Write a complete draft for this angle. Match the requested format and audience. Keep it ready to send or publish with minimal edits.\\\\n\\\\n' +\n 'FORMAT: ' + format + '\\\\nAUDIENCE: ' + audience + '\\\\nCORE MESSAGE: ' + brief.coreMessage + '\\\\n' +\n 'ANGLE: ' + a.title + '\\\\nHOOK: ' + a.hook + '\\\\nKEY POINT: ' + a.keyPoint,\n {\n label: a.title,\n schema: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n body: { type: 'string' },\n subject: { type: 'string' },\n },\n required: ['title', 'body'],\n },\n },\n ),\n ),\n)\n\nphase('Draft')\nconst live = angleDrafts.filter(Boolean)\nconst finalDraft = await agent(\n 'Synthesize the best final draft from these angle-level versions. Pick the strongest hook and structure, merge the best lines, and remove redundancy. ' +\n 'Return the polished draft plus a one-line rationale and two optional shorter variants (e.g. social / SMS length).\\\\n\\\\n' +\n JSON.stringify({ brief, drafts: live }, null, 2),\n {\n label: 'final draft',\n schema: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n subject: { type: 'string' },\n body: { type: 'string' },\n rationale: { type: 'string' },\n shortVariants: { type: 'array', items: { type: 'string' } },\n },\n required: ['body', 'rationale'],\n },\n },\n)\n\nreturn {\n ok: true,\n topic,\n audience,\n format,\n angleCount: angles.length,\n ...(finalDraft ?? { body: 'draft synthesis failed', rationale: '' }),\n}\n`\n"],"mappings":";;;;;;;;;;;;;AAaA,MAAa,uBAAuB"}