@xopcai/xopc 0.0.88 → 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 (275) hide show
  1. package/README.md +8 -1
  2. package/README.zh-CN.md +8 -1
  3. package/dist/browser-ext/manifest.json +1 -1
  4. package/dist/extensions/telegram/xopc.extension.json +1 -1
  5. package/dist/gateway/static/root/assets/agents-cPvvYLXo.js +222 -0
  6. package/dist/gateway/static/root/assets/apps-page-Bk1_P5FJ.js +1 -0
  7. package/dist/gateway/static/root/assets/channels-settings-CZoeQwHz.js +1 -0
  8. package/dist/gateway/static/root/assets/{channels-status-swr-DIsl75Y3.js → channels-status-swr-BrtH2VzC.js} +1 -1
  9. package/dist/gateway/static/root/assets/circle-check-C23XjkUj.js +1 -0
  10. package/dist/gateway/static/root/assets/cron-api-CyqbgfHM.js +1 -0
  11. package/dist/gateway/static/root/assets/cron-dreaming-jobs-Ip703-qM.js +2 -0
  12. package/dist/gateway/static/root/assets/cron-page-BpLdiQN8.js +1 -0
  13. package/dist/gateway/static/root/assets/dist-BpAiK86n.js +1 -0
  14. package/dist/gateway/static/root/assets/{extension-debug-page-BVJohZoZ.js → extension-debug-page-D6Ak0STa.js} +1 -1
  15. package/dist/gateway/static/root/assets/{extension-page-BT2tmElC.js → extension-page-Q0P3d6DW.js} +1 -1
  16. package/dist/gateway/static/root/assets/{extension-settings-page-BSS47c2j.js → extension-settings-page-CL55LwU_.js} +1 -1
  17. package/dist/gateway/static/root/assets/eye-DAfL1U7M.js +1 -0
  18. package/dist/gateway/static/root/assets/{fetch-BaFNUtkE.js → fetch-Dqa9iTWl.js} +1 -1
  19. package/dist/gateway/static/root/assets/{field-primitives-QwYEq6Hz.js → field-primitives-HUR6JElP.js} +1 -1
  20. package/dist/gateway/static/root/assets/{heartbeat-config-api-BVSidEDJ.js → heartbeat-config-api-DusckjUX.js} +1 -1
  21. package/dist/gateway/static/root/assets/{index-qNrVJp-y.js → index-BYcGfwcE.js} +97 -97
  22. package/dist/gateway/static/root/assets/index-V7MQ7834.css +1 -0
  23. package/dist/gateway/static/root/assets/{logs-page-DDonPVLn.js → logs-page-_HcZ2fgK.js} +1 -1
  24. package/dist/gateway/static/root/assets/sessions-page-iezSMjho.js +1 -0
  25. package/dist/gateway/static/root/assets/{settings-form-section-B8N3A3Zo.js → settings-form-section-a0qGVOlr.js} +1 -1
  26. package/dist/gateway/static/root/assets/settings-page-C9_nYQwM.js +3 -0
  27. package/dist/gateway/static/root/assets/{share-preview-page-Q7KqkO-u.js → share-preview-page-DExl7CJy.js} +1 -1
  28. package/dist/gateway/static/root/assets/skills-page-BlgGD93t.js +2 -0
  29. package/dist/gateway/static/root/assets/{theme-store-BbRc5ugR.js → theme-store-C0Ehmdo5.js} +1 -1
  30. package/dist/gateway/static/root/assets/url-fxyYANfA.js +3 -0
  31. package/dist/gateway/static/root/assets/{utils-CxDGduqK.js → utils-DRQryzdn.js} +1 -1
  32. package/dist/gateway/static/root/assets/voice-api-key-field-D0viACE2.js +1 -0
  33. package/dist/gateway/static/root/assets/workflow-page.utils-DnG8JBhV.js +1 -0
  34. package/dist/gateway/static/root/assets/workflows-page-BvMobnJP.js +27 -0
  35. package/dist/gateway/static/root/index.html +7 -6
  36. package/dist/package.js +1 -1
  37. package/dist/src/agent/agent-manager.d.ts +2 -0
  38. package/dist/src/agent/agent-manager.js +1 -0
  39. package/dist/src/agent/agent-manager.js.map +1 -1
  40. package/dist/src/agent/service.js +2 -1
  41. package/dist/src/agent/service.js.map +1 -1
  42. package/dist/src/agent/service.types.d.ts +3 -1
  43. package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js +20 -18
  44. package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js.map +1 -1
  45. package/dist/src/agent/tools/cronjob-tool.d.ts +6 -0
  46. package/dist/src/agent/tools/cronjob-tool.js +76 -10
  47. package/dist/src/agent/tools/cronjob-tool.js.map +1 -1
  48. package/dist/src/agent/tools/edit.d.ts +5 -1
  49. package/dist/src/agent/tools/edit.js +7 -5
  50. package/dist/src/agent/tools/edit.js.map +1 -1
  51. package/dist/src/agent/tools/factory.d.ts +3 -0
  52. package/dist/src/agent/tools/factory.js +4 -25
  53. package/dist/src/agent/tools/factory.js.map +1 -1
  54. package/dist/src/agent/tools/workflow-tool.d.ts +6 -28
  55. package/dist/src/agent/tools/workflow-tool.js +60 -260
  56. package/dist/src/agent/tools/workflow-tool.js.map +1 -1
  57. package/dist/src/agent/tools/write.d.ts +5 -1
  58. package/dist/src/agent/tools/write.js +7 -5
  59. package/dist/src/agent/tools/write.js.map +1 -1
  60. package/dist/src/agent/workflow/agent-progress.js +2 -0
  61. package/dist/src/agent/workflow/agent-progress.js.map +1 -1
  62. package/dist/src/agent/workflow/builtins/client-proposal.d.ts +12 -0
  63. package/dist/src/agent/workflow/builtins/client-proposal.js +155 -0
  64. package/dist/src/agent/workflow/builtins/client-proposal.js.map +1 -0
  65. package/dist/src/agent/workflow/builtins/competitor-scan.d.ts +12 -0
  66. package/dist/src/agent/workflow/builtins/competitor-scan.js +150 -0
  67. package/dist/src/agent/workflow/builtins/competitor-scan.js.map +1 -0
  68. package/dist/src/agent/workflow/builtins/content-draft.d.ts +13 -0
  69. package/dist/src/agent/workflow/builtins/content-draft.js +146 -0
  70. package/dist/src/agent/workflow/builtins/content-draft.js.map +1 -0
  71. package/dist/src/agent/workflow/builtins/content-repurpose.d.ts +11 -0
  72. package/dist/src/agent/workflow/builtins/content-repurpose.js +137 -0
  73. package/dist/src/agent/workflow/builtins/content-repurpose.js.map +1 -0
  74. package/dist/src/agent/workflow/builtins/decision-compare.d.ts +13 -0
  75. package/dist/src/agent/workflow/builtins/decision-compare.js +173 -0
  76. package/dist/src/agent/workflow/builtins/decision-compare.js.map +1 -0
  77. package/dist/src/agent/workflow/builtins/inbox-triage.d.ts +11 -0
  78. package/dist/src/agent/workflow/builtins/inbox-triage.js +148 -0
  79. package/dist/src/agent/workflow/builtins/inbox-triage.js.map +1 -0
  80. package/dist/src/agent/workflow/builtins/index.d.ts +10 -1
  81. package/dist/src/agent/workflow/builtins/index.js +46 -1
  82. package/dist/src/agent/workflow/builtins/index.js.map +1 -1
  83. package/dist/src/agent/workflow/builtins/meeting-prep.d.ts +12 -0
  84. package/dist/src/agent/workflow/builtins/meeting-prep.js +144 -0
  85. package/dist/src/agent/workflow/builtins/meeting-prep.js.map +1 -0
  86. package/dist/src/agent/workflow/builtins/offer-design.d.ts +12 -0
  87. package/dist/src/agent/workflow/builtins/offer-design.js +161 -0
  88. package/dist/src/agent/workflow/builtins/offer-design.js.map +1 -0
  89. package/dist/src/agent/workflow/builtins/weekly-review.d.ts +12 -0
  90. package/dist/src/agent/workflow/builtins/weekly-review.js +131 -0
  91. package/dist/src/agent/workflow/builtins/weekly-review.js.map +1 -0
  92. package/dist/src/agent/workflow/step-labels.js +2 -2
  93. package/dist/src/agent/workflow/step-labels.js.map +1 -1
  94. package/dist/src/agent/workflow/subagent-runner.js +3 -1
  95. package/dist/src/agent/workflow/subagent-runner.js.map +1 -1
  96. package/dist/src/agent/workflow/types.d.ts +4 -0
  97. package/dist/src/agent/workflow/workflow-child-tools.d.ts +4 -0
  98. package/dist/src/agent/workflow/workflow-child-tools.js +21 -0
  99. package/dist/src/agent/workflow/workflow-child-tools.js.map +1 -0
  100. package/dist/src/auth/credentials.d.ts +14 -2
  101. package/dist/src/auth/credentials.js +38 -13
  102. package/dist/src/auth/credentials.js.map +1 -1
  103. package/dist/src/auth/oauth/types.d.ts +16 -0
  104. package/dist/src/chat-commands/agent-edit.d.ts +4 -0
  105. package/dist/src/chat-commands/agent-edit.js +136 -0
  106. package/dist/src/chat-commands/agent-edit.js.map +1 -0
  107. package/dist/src/chat-commands/index.d.ts +1 -0
  108. package/dist/src/chat-commands/index.js +3 -1
  109. package/dist/src/chat-commands/index.js.map +1 -1
  110. package/dist/src/cli/bin.js +2 -0
  111. package/dist/src/cli/bin.js.map +1 -1
  112. package/dist/src/cli/commands/auth.js +6 -0
  113. package/dist/src/cli/commands/auth.js.map +1 -1
  114. package/dist/src/cli/commands/cron.js +42 -3
  115. package/dist/src/cli/commands/cron.js.map +1 -1
  116. package/dist/src/cli/commands/doctor/checks/session-integrity.js +79 -56
  117. package/dist/src/cli/commands/doctor/checks/session-integrity.js.map +1 -1
  118. package/dist/src/cli/commands/onboard/model.js +6 -0
  119. package/dist/src/cli/commands/onboard/model.js.map +1 -1
  120. package/dist/src/cli/commands/update.js +86 -79
  121. package/dist/src/cli/commands/update.js.map +1 -1
  122. package/dist/src/commands/agents.config.d.ts +3 -2
  123. package/dist/src/commands/agents.config.js +5 -2
  124. package/dist/src/commands/agents.config.js.map +1 -1
  125. package/dist/src/config/agent-typed-models.d.ts +2 -7
  126. package/dist/src/config/agent-typed-models.js +3 -14
  127. package/dist/src/config/agent-typed-models.js.map +1 -1
  128. package/dist/src/config/localized-text.d.ts +6 -0
  129. package/dist/src/config/localized-text.js +42 -0
  130. package/dist/src/config/localized-text.js.map +1 -0
  131. package/dist/src/config/models-json.d.ts +6 -6
  132. package/dist/src/config/schema.d.ts +6 -21
  133. package/dist/src/config/schema.js +4 -4
  134. package/dist/src/config/schema.js.map +1 -1
  135. package/dist/src/cron/executor.d.ts +4 -0
  136. package/dist/src/cron/executor.js +169 -5
  137. package/dist/src/cron/executor.js.map +1 -1
  138. package/dist/src/cron/job-content.js +2 -1
  139. package/dist/src/cron/job-content.js.map +1 -1
  140. package/dist/src/cron/types.d.ts +28 -1
  141. package/dist/src/cron/validation.d.ts +80 -0
  142. package/dist/src/cron/validation.js +30 -4
  143. package/dist/src/cron/validation.js.map +1 -1
  144. package/dist/src/cron/workflow-run-completion.d.ts +23 -0
  145. package/dist/src/cron/workflow-run-completion.js +72 -0
  146. package/dist/src/cron/workflow-run-completion.js.map +1 -0
  147. package/dist/src/extensions/update.d.ts +51 -0
  148. package/dist/src/extensions/update.js +260 -0
  149. package/dist/src/extensions/update.js.map +1 -0
  150. package/dist/src/gateway/agents-admin.d.ts +15 -8
  151. package/dist/src/gateway/agents-admin.js +77 -28
  152. package/dist/src/gateway/agents-admin.js.map +1 -1
  153. package/dist/src/gateway/gateway-workflow-host.types.d.ts +17 -0
  154. package/dist/src/gateway/gateway-workflow-host.types.js +1 -0
  155. package/dist/src/gateway/heartbeat/service.js +1 -1
  156. package/dist/src/gateway/hono/lib/config-payload.d.ts +5 -0
  157. package/dist/src/gateway/hono/lib/config-payload.js +2 -1
  158. package/dist/src/gateway/hono/lib/config-payload.js.map +1 -1
  159. package/dist/src/gateway/hono/middleware/auth.d.ts +2 -0
  160. package/dist/src/gateway/hono/middleware/auth.js +12 -7
  161. package/dist/src/gateway/hono/middleware/auth.js.map +1 -1
  162. package/dist/src/gateway/hono/oauth-async.js +40 -15
  163. package/dist/src/gateway/hono/oauth-async.js.map +1 -1
  164. package/dist/src/gateway/hono/oauth.js +31 -6
  165. package/dist/src/gateway/hono/oauth.js.map +1 -1
  166. package/dist/src/gateway/hono/routes/agents.js +55 -12
  167. package/dist/src/gateway/hono/routes/agents.js.map +1 -1
  168. package/dist/src/gateway/hono/routes/config-patch/agents.js +1 -1
  169. package/dist/src/gateway/hono/routes/models.js +11 -5
  170. package/dist/src/gateway/hono/routes/models.js.map +1 -1
  171. package/dist/src/gateway/hono/routes/update.js +55 -107
  172. package/dist/src/gateway/hono/routes/update.js.map +1 -1
  173. package/dist/src/gateway/hono/routes/workflows.js +72 -191
  174. package/dist/src/gateway/hono/routes/workflows.js.map +1 -1
  175. package/dist/src/gateway/server.js +2 -0
  176. package/dist/src/gateway/server.js.map +1 -1
  177. package/dist/src/gateway/service.d.ts +5 -0
  178. package/dist/src/gateway/service.js +24 -3
  179. package/dist/src/gateway/service.js.map +1 -1
  180. package/dist/src/heartbeat/index.js +1 -1
  181. package/dist/src/infra/brew.d.ts +4 -0
  182. package/dist/src/infra/brew.js +20 -0
  183. package/dist/src/infra/brew.js.map +1 -0
  184. package/dist/src/infra/package-json.d.ts +2 -0
  185. package/dist/src/infra/package-json.js +23 -0
  186. package/dist/src/infra/package-json.js.map +1 -0
  187. package/dist/src/infra/package-update-steps.d.ts +35 -0
  188. package/dist/src/infra/package-update-steps.js +304 -0
  189. package/dist/src/infra/package-update-steps.js.map +1 -0
  190. package/dist/src/infra/path-env.d.ts +11 -0
  191. package/dist/src/infra/path-env.js +90 -0
  192. package/dist/src/infra/path-env.js.map +1 -0
  193. package/dist/src/infra/path-prepend.d.ts +7 -0
  194. package/dist/src/infra/path-prepend.js +44 -0
  195. package/dist/src/infra/path-prepend.js.map +1 -0
  196. package/dist/src/infra/stable-node-path.d.ts +2 -0
  197. package/dist/src/infra/stable-node-path.js +28 -0
  198. package/dist/src/infra/stable-node-path.js.map +1 -0
  199. package/dist/src/infra/update-global.d.ts +30 -23
  200. package/dist/src/infra/update-global.js +113 -64
  201. package/dist/src/infra/update-global.js.map +1 -1
  202. package/dist/src/infra/update-log.d.ts +1 -0
  203. package/dist/src/infra/update-log.js +12 -0
  204. package/dist/src/infra/update-log.js.map +1 -0
  205. package/dist/src/infra/update-restart.d.ts +20 -0
  206. package/dist/src/infra/update-restart.js +165 -0
  207. package/dist/src/infra/update-restart.js.map +1 -0
  208. package/dist/src/infra/update-runner.d.ts +89 -1
  209. package/dist/src/infra/update-runner.js +604 -173
  210. package/dist/src/infra/update-runner.js.map +1 -1
  211. package/dist/src/infra/update-startup.d.ts +3 -0
  212. package/dist/src/infra/update-startup.js +8 -4
  213. package/dist/src/infra/update-startup.js.map +1 -1
  214. package/dist/src/providers/index.d.ts +8 -0
  215. package/dist/src/providers/index.js +51 -12
  216. package/dist/src/providers/index.js.map +1 -1
  217. package/dist/src/routing/resolve-route.d.ts +3 -1
  218. package/dist/src/routing/resolve-route.js.map +1 -1
  219. package/dist/src/session/store.d.ts +5 -3
  220. package/dist/src/session/store.js +66 -20
  221. package/dist/src/session/store.js.map +1 -1
  222. package/dist/src/share/site-share-config.d.ts +3 -2
  223. package/dist/src/share/site-share-config.js.map +1 -1
  224. package/dist/src/utils/logger/stats.d.ts +1 -1
  225. package/dist/src/workflows/domain/command.d.ts +2 -1
  226. package/dist/src/workflows/domain/definition-utils.d.ts +14 -0
  227. package/dist/src/workflows/domain/definition-utils.js +50 -0
  228. package/dist/src/workflows/domain/definition-utils.js.map +1 -0
  229. package/dist/src/workflows/domain/event.d.ts +3 -0
  230. package/dist/src/workflows/domain/index.d.ts +2 -0
  231. package/dist/src/workflows/domain/index.js +3 -1
  232. package/dist/src/workflows/domain/run.d.ts +60 -0
  233. package/dist/src/workflows/domain/run.js.map +1 -1
  234. package/dist/src/workflows/domain/validation.d.ts +19 -0
  235. package/dist/src/workflows/domain/validation.js +66 -0
  236. package/dist/src/workflows/domain/validation.js.map +1 -0
  237. package/dist/src/workflows/engine/projector.js +17 -0
  238. package/dist/src/workflows/engine/projector.js.map +1 -1
  239. package/dist/src/workflows/engine/workflow-engine.d.ts +2 -1
  240. package/dist/src/workflows/engine/workflow-engine.js +128 -0
  241. package/dist/src/workflows/engine/workflow-engine.js.map +1 -1
  242. package/dist/src/workflows/index.d.ts +4 -0
  243. package/dist/src/workflows/index.js +9 -2
  244. package/dist/src/workflows/service/run-view-to-snapshot.d.ts +4 -0
  245. package/dist/src/workflows/service/run-view-to-snapshot.js +63 -0
  246. package/dist/src/workflows/service/run-view-to-snapshot.js.map +1 -0
  247. package/dist/src/workflows/service/workflow-run-service.d.ts +37 -0
  248. package/dist/src/workflows/service/workflow-run-service.js +282 -0
  249. package/dist/src/workflows/service/workflow-run-service.js.map +1 -0
  250. package/dist/src/workflows/service/workflow-run-service.types.d.ts +47 -0
  251. package/dist/src/workflows/service/workflow-run-service.types.js +1 -0
  252. package/dist/src/workflows/service/workflow-session-bridge.d.ts +29 -0
  253. package/dist/src/workflows/service/workflow-session-bridge.js +177 -0
  254. package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -0
  255. package/dist/src/workflows/service/workflow-session-key.d.ts +3 -0
  256. package/dist/src/workflows/service/workflow-session-key.js +21 -0
  257. package/dist/src/workflows/service/workflow-session-key.js.map +1 -0
  258. package/dist/src/workflows/store/run-store.js +1 -0
  259. package/dist/src/workflows/store/run-store.js.map +1 -1
  260. package/package.json +1 -1
  261. package/dist/gateway/static/root/assets/agents-CRxETUZx.js +0 -222
  262. package/dist/gateway/static/root/assets/apps-page-wKWf3l57.js +0 -1
  263. package/dist/gateway/static/root/assets/channels-settings-DDbqVNkx.js +0 -1
  264. package/dist/gateway/static/root/assets/copy-SxMW6Xpc.js +0 -1
  265. package/dist/gateway/static/root/assets/cron-api-N9hvuRrn.js +0 -1
  266. package/dist/gateway/static/root/assets/cron-dreaming-jobs-DueM3rBz.js +0 -2
  267. package/dist/gateway/static/root/assets/cron-page-tlNGNxhP.js +0 -1
  268. package/dist/gateway/static/root/assets/dist-CJwfHYvT.js +0 -1
  269. package/dist/gateway/static/root/assets/index-CqZzHNEg.css +0 -1
  270. package/dist/gateway/static/root/assets/sessions-page-DKt-Wmib.js +0 -1
  271. package/dist/gateway/static/root/assets/settings-page-DcJjvvw4.js +0 -3
  272. package/dist/gateway/static/root/assets/skills-page-DuJ4BTO3.js +0 -2
  273. package/dist/gateway/static/root/assets/url-D6jvVYIA.js +0 -7
  274. package/dist/gateway/static/root/assets/voice-api-key-field-CTyHz7L_.js +0 -1
  275. package/dist/gateway/static/root/assets/workflows-page-GacJ41Fv.js +0 -27
@@ -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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Built-in workflow: `content_repurpose`
3
+ *
4
+ * Repurpose one source piece into multi-platform formats — threads, LinkedIn,
5
+ * short video script, newsletter blurb. For personal-brand solopreneurs.
6
+ *
7
+ * Args:
8
+ * - source: original article, notes, or talking points
9
+ * - platforms: target platforms (optional)
10
+ */
11
+ export declare const CONTENT_REPURPOSE_SCRIPT = "export const meta = {\n name: 'content_repurpose',\n description: 'Repurpose one source into platform-specific content (threads, posts, scripts, newsletter).',\n whenToUse: 'User has existing content and wants multi-platform distribution without rewriting from scratch.',\n examplePrompts: [\n { field: 'source', text: '2000-word blog post on building a one-person AI business' },\n { field: 'platforms', text: 'X thread, LinkedIn, 60s video script, newsletter teaser' },\n ],\n i18n: {\n zh: {\n description: '\u5C06\u4E00\u4EFD\u6838\u5FC3\u5185\u5BB9\u6539\u7F16\u4E3A\u591A\u5E73\u53F0\u683C\u5F0F\uFF08\u63A8\u6587\u4E32\u3001\u9886\u82F1\u5E16\u3001\u77ED\u89C6\u9891\u811A\u672C\u3001Newsletter \u6458\u8981\uFF09\u3002',\n whenToUse: '\u7528\u6237\u5DF2\u6709\u5185\u5BB9\u7D20\u6750\uFF0C\u9700\u8981\u4E00\u6E90\u591A\u7528\u3001\u591A\u5E73\u53F0\u5206\u53D1\u65F6\u3002',\n examplePrompts: [\n { field: 'source', text: '\u4E00\u7BC7 2000 \u5B57\u5173\u4E8E\u4E00\u4EBA AI \u516C\u53F8\u7684\u535A\u5BA2' },\n { field: 'platforms', text: 'X \u63A8\u6587\u4E32\u3001LinkedIn\u300160 \u79D2\u53E3\u64AD\u7A3F\u3001Newsletter \u5BFC\u8BED' },\n ],\n },\n },\n tags: ['writing', 'content'],\n estimatedAgents: { min: 4, max: 6 },\n phases: [\n { title: 'Extract' },\n { title: 'Adapt' },\n { title: 'Package' },\n ],\n}\n\nconst source = args && typeof args === 'object' && args.source\n ? String(args.source)\n : 'Infer the source content from the most recent user turn.'\n\nconst platformsRaw = args && typeof args === 'object' && args.platforms\n ? String(args.platforms)\n : ''\n\nconst DEFAULT_PLATFORMS = [\n { id: 'x_thread', label: 'X / Twitter thread', format: '5\u20138 tweets, hook-first, one idea per tweet' },\n { id: 'linkedin', label: 'LinkedIn post', format: 'Professional post, 150\u2013250 words, clear CTA' },\n { id: 'short_video', label: 'Short video script', format: '60-second spoken script with hook and CTA' },\n { id: 'newsletter', label: 'Newsletter teaser', format: 'Subject line + 2\u20133 sentence teaser + bullet highlights' },\n]\n\nphase('Extract')\nconst extracted = await agent(\n 'Extract reusable content atoms from this source: core thesis, 3\u20135 key points, best quotes/stats, audience hook, and CTA.\\n\\nSOURCE:\\n' + source,\n {\n label: 'extract',\n schema: {\n type: 'object',\n properties: {\n thesis: { type: 'string' },\n keyPoints: { type: 'array', items: { type: 'string' } },\n hooks: { type: 'array', items: { type: 'string' } },\n quotesOrStats: { type: 'array', items: { type: 'string' } },\n cta: { type: 'string' },\n },\n required: ['thesis', 'keyPoints', 'cta'],\n },\n },\n)\n\nconst targets = platformsRaw\n ? platformsRaw\n .split(/[,\uFF0C\\n]/)\n .map((s) => s.trim())\n .filter(Boolean)\n .map((label, index) => ({\n id: 'custom_' + index,\n label,\n format: 'Native format and length for ' + label,\n }))\n : DEFAULT_PLATFORMS\n\nphase('Adapt')\nconst adaptations = await parallel(\n targets.map((p) => () =>\n agent(\n 'Adapt the extracted content for this platform. Match native tone and length. Return ready-to-publish copy.\\n\\n' +\n 'PLATFORM: ' + p.label + '\\nFORMAT: ' + p.format + '\\n\\n' +\n JSON.stringify(extracted, null, 2),\n {\n label: p.label,\n schema: {\n type: 'object',\n properties: {\n platform: { type: 'string' },\n copy: { type: 'string' },\n notes: { type: 'string' },\n },\n required: ['platform', 'copy'],\n },\n },\n ),\n ),\n)\n\nphase('Package')\nconst packaged = await agent(\n 'Package all platform adaptations with a publishing checklist: suggested order, cross-links between posts, and one optional bonus format (e.g. carousel outline).\\n\\n' +\n JSON.stringify({ extracted, adaptations: adaptations.filter(Boolean) }, null, 2),\n {\n label: 'package',\n schema: {\n type: 'object',\n properties: {\n publishingOrder: { type: 'array', items: { type: 'string' } },\n crossLinks: { type: 'array', items: { type: 'string' } },\n bonusFormat: { type: 'string' },\n summary: { type: 'string' },\n },\n required: ['publishingOrder', 'summary'],\n },\n },\n)\n\nreturn {\n ok: true,\n extracted,\n adaptations: adaptations.filter(Boolean),\n ...(packaged ?? { publishingOrder: [], summary: 'packaging failed' }),\n}\n";