stagent 0.1.0

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 (333) hide show
  1. package/LICENSE +191 -0
  2. package/README.md +399 -0
  3. package/components.json +21 -0
  4. package/dist/cli.js +171 -0
  5. package/drizzle.config.ts +12 -0
  6. package/next.config.mjs +15 -0
  7. package/package.json +114 -0
  8. package/postcss.config.mjs +8 -0
  9. package/public/icon-512.png +0 -0
  10. package/public/icon.svg +13 -0
  11. package/public/readme/home-workspace.png +0 -0
  12. package/public/readme/inbox-approvals.png +0 -0
  13. package/public/readme/workflow-blueprints.png +0 -0
  14. package/public/stagent-s-128.png +0 -0
  15. package/public/stagent-s-64.png +0 -0
  16. package/src/app/api/blueprints/[id]/instantiate/route.ts +27 -0
  17. package/src/app/api/blueprints/[id]/route.ts +39 -0
  18. package/src/app/api/blueprints/import/route.ts +68 -0
  19. package/src/app/api/blueprints/route.ts +29 -0
  20. package/src/app/api/command-palette/recent/route.ts +31 -0
  21. package/src/app/api/data/clear/route.ts +22 -0
  22. package/src/app/api/data/seed/route.ts +22 -0
  23. package/src/app/api/documents/[id]/file/route.ts +44 -0
  24. package/src/app/api/documents/[id]/route.ts +123 -0
  25. package/src/app/api/documents/route.ts +59 -0
  26. package/src/app/api/logs/stream/route.ts +101 -0
  27. package/src/app/api/notifications/[id]/route.ts +36 -0
  28. package/src/app/api/notifications/mark-all-read/route.ts +13 -0
  29. package/src/app/api/notifications/pending-approvals/route.ts +10 -0
  30. package/src/app/api/notifications/pending-approvals/stream/route.ts +101 -0
  31. package/src/app/api/notifications/route.ts +34 -0
  32. package/src/app/api/permissions/route.ts +46 -0
  33. package/src/app/api/profiles/[id]/route.ts +79 -0
  34. package/src/app/api/profiles/[id]/test/route.ts +42 -0
  35. package/src/app/api/profiles/import/route.ts +108 -0
  36. package/src/app/api/profiles/route.ts +50 -0
  37. package/src/app/api/projects/[id]/route.ts +72 -0
  38. package/src/app/api/projects/route.ts +53 -0
  39. package/src/app/api/schedules/[id]/route.ts +185 -0
  40. package/src/app/api/schedules/route.ts +117 -0
  41. package/src/app/api/settings/budgets/route.ts +24 -0
  42. package/src/app/api/settings/openai/route.ts +24 -0
  43. package/src/app/api/settings/route.ts +21 -0
  44. package/src/app/api/settings/test/route.ts +26 -0
  45. package/src/app/api/tasks/[id]/cancel/route.ts +21 -0
  46. package/src/app/api/tasks/[id]/execute/route.ts +90 -0
  47. package/src/app/api/tasks/[id]/logs/route.ts +95 -0
  48. package/src/app/api/tasks/[id]/output/route.ts +47 -0
  49. package/src/app/api/tasks/[id]/respond/route.ts +64 -0
  50. package/src/app/api/tasks/[id]/resume/route.ts +76 -0
  51. package/src/app/api/tasks/[id]/route.ts +77 -0
  52. package/src/app/api/tasks/assist/route.ts +35 -0
  53. package/src/app/api/tasks/route.ts +82 -0
  54. package/src/app/api/uploads/[id]/route.ts +81 -0
  55. package/src/app/api/uploads/cleanup/route.ts +7 -0
  56. package/src/app/api/uploads/route.ts +66 -0
  57. package/src/app/api/workflows/[id]/execute/route.ts +82 -0
  58. package/src/app/api/workflows/[id]/route.ts +133 -0
  59. package/src/app/api/workflows/[id]/status/route.ts +54 -0
  60. package/src/app/api/workflows/[id]/steps/[stepId]/retry/route.ts +22 -0
  61. package/src/app/api/workflows/route.ts +61 -0
  62. package/src/app/apple-icon.tsx +31 -0
  63. package/src/app/costs/page.tsx +256 -0
  64. package/src/app/dashboard/page.tsx +44 -0
  65. package/src/app/documents/[id]/page.tsx +46 -0
  66. package/src/app/documents/page.tsx +45 -0
  67. package/src/app/error.tsx +26 -0
  68. package/src/app/global-error.tsx +23 -0
  69. package/src/app/globals.css +733 -0
  70. package/src/app/icon.tsx +30 -0
  71. package/src/app/inbox/loading.tsx +15 -0
  72. package/src/app/inbox/page.tsx +35 -0
  73. package/src/app/layout.tsx +78 -0
  74. package/src/app/manifest.ts +32 -0
  75. package/src/app/monitor/page.tsx +37 -0
  76. package/src/app/page.tsx +162 -0
  77. package/src/app/profiles/[id]/edit/page.tsx +39 -0
  78. package/src/app/profiles/[id]/page.tsx +33 -0
  79. package/src/app/profiles/new/page.tsx +22 -0
  80. package/src/app/profiles/page.tsx +19 -0
  81. package/src/app/projects/[id]/page.tsx +134 -0
  82. package/src/app/projects/loading.tsx +17 -0
  83. package/src/app/projects/page.tsx +32 -0
  84. package/src/app/schedules/[id]/page.tsx +47 -0
  85. package/src/app/schedules/page.tsx +18 -0
  86. package/src/app/settings/loading.tsx +24 -0
  87. package/src/app/settings/page.tsx +27 -0
  88. package/src/app/tasks/[id]/page.tsx +45 -0
  89. package/src/app/tasks/new/page.tsx +27 -0
  90. package/src/app/workflows/[id]/edit/page.tsx +66 -0
  91. package/src/app/workflows/[id]/page.tsx +37 -0
  92. package/src/app/workflows/blueprints/[id]/page.tsx +40 -0
  93. package/src/app/workflows/blueprints/new/page.tsx +20 -0
  94. package/src/app/workflows/blueprints/page.tsx +11 -0
  95. package/src/app/workflows/new/page.tsx +36 -0
  96. package/src/app/workflows/page.tsx +18 -0
  97. package/src/components/charts/donut-ring.tsx +64 -0
  98. package/src/components/charts/mini-bar.tsx +75 -0
  99. package/src/components/charts/sparkline.tsx +107 -0
  100. package/src/components/costs/cost-dashboard.tsx +877 -0
  101. package/src/components/costs/cost-filters.tsx +179 -0
  102. package/src/components/dashboard/activity-feed.tsx +95 -0
  103. package/src/components/dashboard/greeting.tsx +30 -0
  104. package/src/components/dashboard/priority-queue.tsx +79 -0
  105. package/src/components/dashboard/quick-actions.tsx +62 -0
  106. package/src/components/dashboard/recent-projects.tsx +79 -0
  107. package/src/components/dashboard/stats-cards.tsx +114 -0
  108. package/src/components/documents/document-browser.tsx +235 -0
  109. package/src/components/documents/document-detail-view.tsx +367 -0
  110. package/src/components/documents/document-grid.tsx +78 -0
  111. package/src/components/documents/document-preview.tsx +68 -0
  112. package/src/components/documents/document-table.tsx +119 -0
  113. package/src/components/documents/document-upload-dialog.tsx +153 -0
  114. package/src/components/documents/types.ts +6 -0
  115. package/src/components/documents/utils.ts +57 -0
  116. package/src/components/monitoring/connection-indicator.tsx +14 -0
  117. package/src/components/monitoring/log-entry.tsx +79 -0
  118. package/src/components/monitoring/log-filters.tsx +57 -0
  119. package/src/components/monitoring/log-stream.tsx +144 -0
  120. package/src/components/monitoring/monitor-overview-wrapper.tsx +64 -0
  121. package/src/components/monitoring/monitor-overview.tsx +119 -0
  122. package/src/components/notifications/failure-action.tsx +38 -0
  123. package/src/components/notifications/inbox-list.tsx +165 -0
  124. package/src/components/notifications/message-response.tsx +196 -0
  125. package/src/components/notifications/notification-item.tsx +250 -0
  126. package/src/components/notifications/pending-approval-host.tsx +478 -0
  127. package/src/components/notifications/permission-action.tsx +37 -0
  128. package/src/components/notifications/permission-response-actions.tsx +126 -0
  129. package/src/components/notifications/unread-badge.tsx +35 -0
  130. package/src/components/profiles/profile-browser.tsx +117 -0
  131. package/src/components/profiles/profile-card.tsx +78 -0
  132. package/src/components/profiles/profile-detail-view.tsx +564 -0
  133. package/src/components/profiles/profile-form-view.tsx +480 -0
  134. package/src/components/profiles/profile-import-dialog.tsx +113 -0
  135. package/src/components/projects/project-card.tsx +58 -0
  136. package/src/components/projects/project-create-dialog.tsx +140 -0
  137. package/src/components/projects/project-detail.tsx +68 -0
  138. package/src/components/projects/project-edit-dialog.tsx +219 -0
  139. package/src/components/projects/project-list.tsx +108 -0
  140. package/src/components/schedules/schedule-create-dialog.tsx +403 -0
  141. package/src/components/schedules/schedule-detail-view.tsx +274 -0
  142. package/src/components/schedules/schedule-list.tsx +242 -0
  143. package/src/components/schedules/schedule-status-badge.tsx +16 -0
  144. package/src/components/settings/api-key-form.tsx +141 -0
  145. package/src/components/settings/auth-config-section.tsx +141 -0
  146. package/src/components/settings/auth-method-selector.tsx +67 -0
  147. package/src/components/settings/auth-status-badge.tsx +40 -0
  148. package/src/components/settings/auth-status-dot.tsx +59 -0
  149. package/src/components/settings/budget-guardrails-section.tsx +842 -0
  150. package/src/components/settings/data-management-section.tsx +141 -0
  151. package/src/components/settings/openai-runtime-section.tsx +104 -0
  152. package/src/components/settings/permissions-section.tsx +91 -0
  153. package/src/components/shared/app-sidebar.tsx +123 -0
  154. package/src/components/shared/card-skeleton.tsx +42 -0
  155. package/src/components/shared/command-palette.tsx +250 -0
  156. package/src/components/shared/confirm-dialog.tsx +52 -0
  157. package/src/components/shared/empty-state.tsx +24 -0
  158. package/src/components/shared/error-state.tsx +32 -0
  159. package/src/components/shared/form-section-card.tsx +33 -0
  160. package/src/components/shared/section-heading.tsx +14 -0
  161. package/src/components/shared/stagent-logo.tsx +21 -0
  162. package/src/components/shared/theme-toggle.tsx +46 -0
  163. package/src/components/tasks/ai-assist-panel.tsx +210 -0
  164. package/src/components/tasks/content-preview.tsx +89 -0
  165. package/src/components/tasks/empty-board.tsx +12 -0
  166. package/src/components/tasks/file-upload.tsx +120 -0
  167. package/src/components/tasks/kanban-board.tsx +275 -0
  168. package/src/components/tasks/kanban-column.tsx +75 -0
  169. package/src/components/tasks/skeleton-board.tsx +21 -0
  170. package/src/components/tasks/task-attachments.tsx +114 -0
  171. package/src/components/tasks/task-card.tsx +101 -0
  172. package/src/components/tasks/task-create-panel.tsx +360 -0
  173. package/src/components/tasks/task-detail-view.tsx +356 -0
  174. package/src/components/ui/alert-dialog.tsx +196 -0
  175. package/src/components/ui/badge.tsx +50 -0
  176. package/src/components/ui/button.tsx +71 -0
  177. package/src/components/ui/card.tsx +92 -0
  178. package/src/components/ui/checkbox.tsx +32 -0
  179. package/src/components/ui/command.tsx +184 -0
  180. package/src/components/ui/dialog.tsx +158 -0
  181. package/src/components/ui/dropdown-menu.tsx +257 -0
  182. package/src/components/ui/form.tsx +167 -0
  183. package/src/components/ui/input.tsx +21 -0
  184. package/src/components/ui/label.tsx +24 -0
  185. package/src/components/ui/popover.tsx +89 -0
  186. package/src/components/ui/progress.tsx +31 -0
  187. package/src/components/ui/radio-group.tsx +45 -0
  188. package/src/components/ui/scroll-area.tsx +58 -0
  189. package/src/components/ui/select.tsx +190 -0
  190. package/src/components/ui/separator.tsx +28 -0
  191. package/src/components/ui/sheet.tsx +143 -0
  192. package/src/components/ui/sidebar.tsx +726 -0
  193. package/src/components/ui/skeleton.tsx +13 -0
  194. package/src/components/ui/slider.tsx +63 -0
  195. package/src/components/ui/sonner.tsx +36 -0
  196. package/src/components/ui/switch.tsx +35 -0
  197. package/src/components/ui/table.tsx +116 -0
  198. package/src/components/ui/tabs.tsx +91 -0
  199. package/src/components/ui/textarea.tsx +18 -0
  200. package/src/components/ui/tooltip.tsx +57 -0
  201. package/src/components/workflows/blueprint-editor.tsx +109 -0
  202. package/src/components/workflows/blueprint-gallery.tsx +155 -0
  203. package/src/components/workflows/blueprint-preview.tsx +240 -0
  204. package/src/components/workflows/loop-status-view.tsx +272 -0
  205. package/src/components/workflows/swarm-dashboard.tsx +185 -0
  206. package/src/components/workflows/workflow-form-view.tsx +1376 -0
  207. package/src/components/workflows/workflow-list.tsx +230 -0
  208. package/src/components/workflows/workflow-status-view.tsx +477 -0
  209. package/src/hooks/use-mobile.ts +19 -0
  210. package/src/instrumentation.ts +7 -0
  211. package/src/lib/agents/claude-agent.ts +737 -0
  212. package/src/lib/agents/execution-manager.ts +27 -0
  213. package/src/lib/agents/profiles/assignment-validation.ts +75 -0
  214. package/src/lib/agents/profiles/builtins/code-reviewer/SKILL.md +21 -0
  215. package/src/lib/agents/profiles/builtins/code-reviewer/profile.yaml +28 -0
  216. package/src/lib/agents/profiles/builtins/data-analyst/SKILL.md +25 -0
  217. package/src/lib/agents/profiles/builtins/data-analyst/profile.yaml +27 -0
  218. package/src/lib/agents/profiles/builtins/devops-engineer/SKILL.md +34 -0
  219. package/src/lib/agents/profiles/builtins/devops-engineer/profile.yaml +27 -0
  220. package/src/lib/agents/profiles/builtins/document-writer/SKILL.md +16 -0
  221. package/src/lib/agents/profiles/builtins/document-writer/profile.yaml +27 -0
  222. package/src/lib/agents/profiles/builtins/general/SKILL.md +13 -0
  223. package/src/lib/agents/profiles/builtins/general/profile.yaml +18 -0
  224. package/src/lib/agents/profiles/builtins/health-fitness-coach/SKILL.md +34 -0
  225. package/src/lib/agents/profiles/builtins/health-fitness-coach/profile.yaml +26 -0
  226. package/src/lib/agents/profiles/builtins/learning-coach/SKILL.md +35 -0
  227. package/src/lib/agents/profiles/builtins/learning-coach/profile.yaml +26 -0
  228. package/src/lib/agents/profiles/builtins/project-manager/SKILL.md +26 -0
  229. package/src/lib/agents/profiles/builtins/project-manager/profile.yaml +26 -0
  230. package/src/lib/agents/profiles/builtins/researcher/SKILL.md +15 -0
  231. package/src/lib/agents/profiles/builtins/researcher/profile.yaml +27 -0
  232. package/src/lib/agents/profiles/builtins/shopping-assistant/SKILL.md +34 -0
  233. package/src/lib/agents/profiles/builtins/shopping-assistant/profile.yaml +26 -0
  234. package/src/lib/agents/profiles/builtins/technical-writer/SKILL.md +31 -0
  235. package/src/lib/agents/profiles/builtins/technical-writer/profile.yaml +29 -0
  236. package/src/lib/agents/profiles/builtins/travel-planner/SKILL.md +23 -0
  237. package/src/lib/agents/profiles/builtins/travel-planner/profile.yaml +26 -0
  238. package/src/lib/agents/profiles/builtins/wealth-manager/SKILL.md +24 -0
  239. package/src/lib/agents/profiles/builtins/wealth-manager/profile.yaml +26 -0
  240. package/src/lib/agents/profiles/compatibility.ts +109 -0
  241. package/src/lib/agents/profiles/registry.ts +293 -0
  242. package/src/lib/agents/profiles/test-runner.ts +18 -0
  243. package/src/lib/agents/profiles/test-types.ts +20 -0
  244. package/src/lib/agents/profiles/types.ts +43 -0
  245. package/src/lib/agents/router.ts +56 -0
  246. package/src/lib/agents/runtime/catalog.ts +85 -0
  247. package/src/lib/agents/runtime/claude-sdk.ts +12 -0
  248. package/src/lib/agents/runtime/claude.ts +370 -0
  249. package/src/lib/agents/runtime/codex-app-server-client.ts +289 -0
  250. package/src/lib/agents/runtime/index.ts +167 -0
  251. package/src/lib/agents/runtime/openai-codex.ts +1089 -0
  252. package/src/lib/agents/runtime/task-assist-types.ts +8 -0
  253. package/src/lib/agents/runtime/types.ts +30 -0
  254. package/src/lib/constants/settings.ts +13 -0
  255. package/src/lib/constants/status-colors.ts +44 -0
  256. package/src/lib/constants/task-status.ts +49 -0
  257. package/src/lib/data/clear.ts +63 -0
  258. package/src/lib/data/seed-data/documents.ts +715 -0
  259. package/src/lib/data/seed-data/logs.ts +195 -0
  260. package/src/lib/data/seed-data/notifications.ts +141 -0
  261. package/src/lib/data/seed-data/profiles.ts +175 -0
  262. package/src/lib/data/seed-data/projects.ts +61 -0
  263. package/src/lib/data/seed-data/schedules.ts +108 -0
  264. package/src/lib/data/seed-data/tasks.ts +341 -0
  265. package/src/lib/data/seed-data/usage-ledger.ts +130 -0
  266. package/src/lib/data/seed-data/workflows.ts +213 -0
  267. package/src/lib/data/seed.ts +129 -0
  268. package/src/lib/db/index.ts +221 -0
  269. package/src/lib/db/migrations/0000_aromatic_gargoyle.sql +59 -0
  270. package/src/lib/db/migrations/0001_first_iron_patriot.sql +6 -0
  271. package/src/lib/db/migrations/0002_add_resume_count.sql +1 -0
  272. package/src/lib/db/migrations/0003_add_settings.sql +5 -0
  273. package/src/lib/db/migrations/0004_add_documents.sql +20 -0
  274. package/src/lib/db/migrations/0005_add_document_preprocessing.sql +4 -0
  275. package/src/lib/db/migrations/0006_add_agent_profile.sql +2 -0
  276. package/src/lib/db/migrations/0007_add_usage_metering_ledger.sql +30 -0
  277. package/src/lib/db/migrations/0008_add_document_version.sql +1 -0
  278. package/src/lib/db/migrations/meta/0000_snapshot.json +416 -0
  279. package/src/lib/db/migrations/meta/0001_snapshot.json +461 -0
  280. package/src/lib/db/migrations/meta/0002_snapshot.json +469 -0
  281. package/src/lib/db/migrations/meta/_journal.json +27 -0
  282. package/src/lib/db/schema.ts +227 -0
  283. package/src/lib/documents/cleanup.ts +50 -0
  284. package/src/lib/documents/context-builder.ts +75 -0
  285. package/src/lib/documents/output-scanner.ts +166 -0
  286. package/src/lib/documents/processor.ts +120 -0
  287. package/src/lib/documents/processors/image.ts +21 -0
  288. package/src/lib/documents/processors/office.ts +36 -0
  289. package/src/lib/documents/processors/pdf.ts +12 -0
  290. package/src/lib/documents/processors/spreadsheet.ts +18 -0
  291. package/src/lib/documents/processors/text.ts +8 -0
  292. package/src/lib/documents/registry.ts +25 -0
  293. package/src/lib/notifications/actionable.ts +108 -0
  294. package/src/lib/notifications/permissions.ts +169 -0
  295. package/src/lib/queries/chart-data.ts +184 -0
  296. package/src/lib/schedules/interval-parser.ts +110 -0
  297. package/src/lib/schedules/scheduler.ts +220 -0
  298. package/src/lib/settings/auth.ts +98 -0
  299. package/src/lib/settings/budget-guardrails.ts +590 -0
  300. package/src/lib/settings/helpers.ts +23 -0
  301. package/src/lib/settings/openai-auth.ts +80 -0
  302. package/src/lib/settings/permissions.ts +102 -0
  303. package/src/lib/usage/ledger.ts +489 -0
  304. package/src/lib/usage/pricing.ts +68 -0
  305. package/src/lib/utils/crypto.ts +90 -0
  306. package/src/lib/utils/format-timestamp.ts +46 -0
  307. package/src/lib/utils/session-cleanup.ts +26 -0
  308. package/src/lib/utils/stagent-paths.ts +18 -0
  309. package/src/lib/utils.ts +6 -0
  310. package/src/lib/validators/blueprint.ts +43 -0
  311. package/src/lib/validators/profile.ts +64 -0
  312. package/src/lib/validators/project.ts +17 -0
  313. package/src/lib/validators/settings.ts +57 -0
  314. package/src/lib/validators/task.ts +30 -0
  315. package/src/lib/workflows/blueprints/builtins/code-review-pipeline.yaml +72 -0
  316. package/src/lib/workflows/blueprints/builtins/documentation-generation.yaml +62 -0
  317. package/src/lib/workflows/blueprints/builtins/investment-research.yaml +81 -0
  318. package/src/lib/workflows/blueprints/builtins/meal-planning.yaml +73 -0
  319. package/src/lib/workflows/blueprints/builtins/product-research.yaml +72 -0
  320. package/src/lib/workflows/blueprints/builtins/research-report.yaml +77 -0
  321. package/src/lib/workflows/blueprints/builtins/sprint-planning.yaml +77 -0
  322. package/src/lib/workflows/blueprints/builtins/travel-planning.yaml +80 -0
  323. package/src/lib/workflows/blueprints/instantiator.ts +131 -0
  324. package/src/lib/workflows/blueprints/registry.ts +128 -0
  325. package/src/lib/workflows/blueprints/template.ts +58 -0
  326. package/src/lib/workflows/blueprints/types.ts +38 -0
  327. package/src/lib/workflows/definition-validation.ts +121 -0
  328. package/src/lib/workflows/engine.ts +1113 -0
  329. package/src/lib/workflows/loop-executor.ts +270 -0
  330. package/src/lib/workflows/parallel.ts +55 -0
  331. package/src/lib/workflows/swarm.ts +97 -0
  332. package/src/lib/workflows/types.ts +112 -0
  333. package/tsconfig.json +41 -0
@@ -0,0 +1,73 @@
1
+ id: meal-planning
2
+ name: Meal Planning
3
+ description: Assess goals, create a weekly meal plan, and generate a shopping list
4
+ version: "1.0.0"
5
+ domain: personal
6
+ tags: [health, nutrition, meal-prep, shopping]
7
+ pattern: sequence
8
+ estimatedDuration: "5-10 min"
9
+ difficulty: beginner
10
+ author: stagent
11
+
12
+ variables:
13
+ - id: goal
14
+ type: select
15
+ label: Health Goal
16
+ description: Primary nutrition goal
17
+ required: true
18
+ default: balanced
19
+ options:
20
+ - { value: balanced, label: "Balanced eating" }
21
+ - { value: weight-loss, label: "Weight loss" }
22
+ - { value: muscle-gain, label: "Muscle gain" }
23
+ - { value: energy, label: "More energy" }
24
+ - id: restrictions
25
+ type: text
26
+ label: Dietary Restrictions
27
+ description: Allergies, preferences, or restrictions
28
+ required: false
29
+ placeholder: "e.g., vegetarian, gluten-free, no nuts"
30
+ - id: days
31
+ type: number
32
+ label: Days to Plan
33
+ description: Number of days to plan meals for
34
+ required: true
35
+ default: 7
36
+ min: 1
37
+ max: 14
38
+
39
+ steps:
40
+ - name: Goal Assessment
41
+ profileId: health-fitness-coach
42
+ promptTemplate: |
43
+ Assess nutritional needs for the goal: {{goal}}
44
+ {{#if restrictions}}Dietary restrictions: {{restrictions}}{{/if}}
45
+ Planning for {{days}} days.
46
+
47
+ Determine: daily calorie target, macro breakdown (protein/carbs/fat),
48
+ key nutrients to focus on, and foods to prioritize or avoid.
49
+ requiresApproval: false
50
+ expectedOutput: nutrition-plan
51
+
52
+ - name: Meal Plan Creation
53
+ profileId: health-fitness-coach
54
+ promptTemplate: |
55
+ Create a {{days}}-day meal plan for the goal: {{goal}}
56
+ {{#if restrictions}}Restrictions: {{restrictions}}{{/if}}
57
+
58
+ Use the nutritional assessment from the previous step.
59
+ Include breakfast, lunch, dinner, and snacks for each day.
60
+ Vary meals to avoid repetition. Include prep time estimates.
61
+ requiresApproval: false
62
+ expectedOutput: meal-plan
63
+
64
+ - name: Shopping List
65
+ profileId: document-writer
66
+ promptTemplate: |
67
+ Generate a complete shopping list from the {{days}}-day meal plan.
68
+
69
+ Organize by grocery section (produce, proteins, dairy, pantry, frozen).
70
+ Combine ingredients across meals to minimize waste.
71
+ Include quantities and optional budget-friendly substitutions.
72
+ requiresApproval: true
73
+ expectedOutput: shopping-list
@@ -0,0 +1,72 @@
1
+ id: product-research
2
+ name: Product Research
3
+ description: Research options, compare reviews, and get a purchase recommendation
4
+ version: "1.0.0"
5
+ domain: personal
6
+ tags: [shopping, comparison, reviews, recommendation]
7
+ pattern: sequence
8
+ estimatedDuration: "5-15 min"
9
+ difficulty: beginner
10
+ author: stagent
11
+
12
+ variables:
13
+ - id: product
14
+ type: text
15
+ label: Product Category
16
+ description: What you're looking to buy
17
+ required: true
18
+ placeholder: "e.g., wireless noise-canceling headphones"
19
+ - id: budget
20
+ type: text
21
+ label: Budget Range
22
+ description: How much you want to spend
23
+ required: false
24
+ placeholder: "e.g., $100-300"
25
+ - id: priorities
26
+ type: textarea
27
+ label: Priorities
28
+ description: What matters most to you
29
+ required: false
30
+ placeholder: "e.g., comfort for long flights, good microphone, ANC quality"
31
+
32
+ steps:
33
+ - name: Research Options
34
+ profileId: researcher
35
+ promptTemplate: |
36
+ Research the best options for: {{product}}
37
+ {{#if budget}}Budget: {{budget}}{{/if}}
38
+ {{#if priorities}}Priorities: {{priorities}}{{/if}}
39
+
40
+ Find the top 5-8 options currently available. For each, note:
41
+ key specs, price, standout features, and known issues.
42
+ requiresApproval: false
43
+ expectedOutput: product-list
44
+
45
+ - name: Compare Reviews
46
+ profileId: shopping-assistant
47
+ promptTemplate: |
48
+ Compare the top options for: {{product}}
49
+ {{#if budget}}Budget: {{budget}}{{/if}}
50
+ {{#if priorities}}Priorities: {{priorities}}{{/if}}
51
+
52
+ Analyze reviews and ratings for each option from the research step.
53
+ Create a comparison table with: price, rating, pros, cons, best for.
54
+ Identify any deal-breakers or red flags.
55
+ requiresApproval: false
56
+ expectedOutput: comparison-table
57
+
58
+ - name: Recommendation
59
+ profileId: shopping-assistant
60
+ promptTemplate: |
61
+ Provide a final purchase recommendation for: {{product}}
62
+ {{#if budget}}Budget: {{budget}}{{/if}}
63
+ {{#if priorities}}Priorities: {{priorities}}{{/if}}
64
+
65
+ Based on the research and comparison, recommend:
66
+ 1. Best overall pick
67
+ 2. Best value pick
68
+ 3. Premium pick (if applicable)
69
+
70
+ Explain why each is recommended and who it's best for.
71
+ requiresApproval: true
72
+ expectedOutput: recommendation
@@ -0,0 +1,77 @@
1
+ id: research-report
2
+ name: Research Report
3
+ description: Multi-step research pipeline — gather sources, analyze data, write structured report
4
+ version: "1.0.0"
5
+ domain: work
6
+ tags: [research, analysis, report, writing]
7
+ pattern: sequence
8
+ estimatedDuration: "15-30 min"
9
+ difficulty: intermediate
10
+ author: stagent
11
+
12
+ variables:
13
+ - id: topic
14
+ type: text
15
+ label: Research Topic
16
+ description: The main topic or question to research
17
+ required: true
18
+ placeholder: "e.g., Impact of AI on healthcare diagnostics"
19
+ - id: depth
20
+ type: select
21
+ label: Research Depth
22
+ description: How thorough the research should be
23
+ required: true
24
+ default: standard
25
+ options:
26
+ - { value: quick, label: "Quick overview (5 sources)" }
27
+ - { value: standard, label: "Standard (10-15 sources)" }
28
+ - { value: deep, label: "Deep dive (20+ sources)" }
29
+ - id: audience
30
+ type: text
31
+ label: Target Audience
32
+ description: Who will read this report
33
+ required: false
34
+ default: "General technical audience"
35
+ - id: includeData
36
+ type: boolean
37
+ label: Include Data Analysis
38
+ description: Whether to include statistical analysis section
39
+ required: false
40
+ default: false
41
+
42
+ steps:
43
+ - name: Research Gathering
44
+ profileId: researcher
45
+ promptTemplate: |
46
+ Research the following topic thoroughly: {{topic}}
47
+
48
+ Depth level: {{depth}}
49
+ {{#if audience}}Target audience: {{audience}}{{/if}}
50
+
51
+ Find credible sources, extract key findings, and compile a structured summary
52
+ with full citations. Focus on recent publications (last 2 years).
53
+ requiresApproval: false
54
+ expectedOutput: structured-summary
55
+
56
+ - name: Data Analysis
57
+ profileId: data-analyst
58
+ promptTemplate: |
59
+ Analyze the research findings from the previous step about: {{topic}}
60
+
61
+ Identify key trends, statistical patterns, and data-driven insights.
62
+ Create summary statistics and recommend visualization approaches.
63
+ requiresApproval: false
64
+ expectedOutput: analysis-report
65
+ condition: "{{includeData}}"
66
+
67
+ - name: Report Writing
68
+ profileId: document-writer
69
+ promptTemplate: |
70
+ Write a comprehensive research report on: {{topic}}
71
+
72
+ {{#if audience}}Target audience: {{audience}}{{/if}}
73
+
74
+ Use the research findings and {{#if includeData}}data analysis{{/if}} from previous steps.
75
+ Structure with: Executive Summary, Key Findings, {{#if includeData}}Data Analysis, {{/if}}Recommendations, References.
76
+ requiresApproval: true
77
+ expectedOutput: markdown-report
@@ -0,0 +1,77 @@
1
+ id: sprint-planning
2
+ name: Sprint Planning
3
+ description: Decompose epics into tasks, estimate effort, and create a sprint schedule
4
+ version: "1.0.0"
5
+ domain: work
6
+ tags: [planning, estimation, sprint, project-management]
7
+ pattern: sequence
8
+ estimatedDuration: "10-20 min"
9
+ difficulty: beginner
10
+ author: stagent
11
+
12
+ variables:
13
+ - id: goal
14
+ type: textarea
15
+ label: Sprint Goal
16
+ description: What this sprint should achieve
17
+ required: true
18
+ placeholder: "e.g., Implement user authentication and profile management"
19
+ - id: duration
20
+ type: select
21
+ label: Sprint Duration
22
+ description: How long is this sprint
23
+ required: true
24
+ default: 2-weeks
25
+ options:
26
+ - { value: 1-week, label: "1 week" }
27
+ - { value: 2-weeks, label: "2 weeks" }
28
+ - { value: 3-weeks, label: "3 weeks" }
29
+ - id: teamSize
30
+ type: number
31
+ label: Team Size
32
+ description: Number of developers
33
+ required: false
34
+ default: 1
35
+ min: 1
36
+ max: 20
37
+
38
+ steps:
39
+ - name: Epic Decomposition
40
+ profileId: project-manager
41
+ promptTemplate: |
42
+ Decompose the following sprint goal into actionable tasks:
43
+
44
+ Goal: {{goal}}
45
+ Sprint duration: {{duration}}
46
+ {{#if teamSize}}Team size: {{teamSize}}{{/if}}
47
+
48
+ Break down into epics, then into individual tasks. Each task should be
49
+ independently completable in 1-3 days. Include dependencies between tasks.
50
+ requiresApproval: false
51
+ expectedOutput: task-list
52
+
53
+ - name: Estimation
54
+ profileId: project-manager
55
+ promptTemplate: |
56
+ Estimate the effort for each task from the decomposition of: {{goal}}
57
+
58
+ Sprint duration: {{duration}}
59
+ {{#if teamSize}}Team size: {{teamSize}}{{/if}}
60
+
61
+ For each task, provide: story points (1/2/3/5/8), time estimate, risk level,
62
+ and any blockers. Flag tasks that don't fit in the sprint.
63
+ requiresApproval: false
64
+ expectedOutput: estimation-report
65
+
66
+ - name: Sprint Schedule
67
+ profileId: project-manager
68
+ promptTemplate: |
69
+ Create a sprint schedule from the estimated tasks for: {{goal}}
70
+
71
+ Sprint duration: {{duration}}
72
+ {{#if teamSize}}Team size: {{teamSize}}{{/if}}
73
+
74
+ Sequence tasks respecting dependencies. Identify the critical path.
75
+ Produce a day-by-day schedule with task assignments and milestones.
76
+ requiresApproval: true
77
+ expectedOutput: schedule
@@ -0,0 +1,80 @@
1
+ id: travel-planning
2
+ name: Travel Planning
3
+ description: Research destinations, find deals, and build a complete itinerary
4
+ version: "1.0.0"
5
+ domain: personal
6
+ tags: [travel, itinerary, budget, booking]
7
+ pattern: sequence
8
+ estimatedDuration: "10-20 min"
9
+ difficulty: beginner
10
+ author: stagent
11
+
12
+ variables:
13
+ - id: destination
14
+ type: text
15
+ label: Destination
16
+ description: Where you want to travel
17
+ required: true
18
+ placeholder: "e.g., Tokyo, Japan for 10 days"
19
+ - id: dates
20
+ type: text
21
+ label: Travel Dates
22
+ description: When you plan to travel
23
+ required: true
24
+ placeholder: "e.g., March 15-25, 2026"
25
+ - id: budget
26
+ type: select
27
+ label: Budget Level
28
+ description: Overall budget per person
29
+ required: true
30
+ default: moderate
31
+ options:
32
+ - { value: budget, label: "Budget ($50-100/day)" }
33
+ - { value: moderate, label: "Moderate ($100-250/day)" }
34
+ - { value: luxury, label: "Luxury ($250+/day)" }
35
+ - id: interests
36
+ type: textarea
37
+ label: Interests
38
+ description: Activities and experiences you enjoy
39
+ required: false
40
+ placeholder: "e.g., food, temples, hiking, nightlife"
41
+
42
+ steps:
43
+ - name: Destination Research
44
+ profileId: travel-planner
45
+ promptTemplate: |
46
+ Research travel to: {{destination}}
47
+ Dates: {{dates}}
48
+ Budget: {{budget}}
49
+ {{#if interests}}Interests: {{interests}}{{/if}}
50
+
51
+ Cover: best neighborhoods to stay, transport options, must-see attractions,
52
+ local customs and tips, weather expectations, and safety considerations.
53
+ requiresApproval: false
54
+ expectedOutput: research-summary
55
+
56
+ - name: Deal Finding
57
+ profileId: shopping-assistant
58
+ promptTemplate: |
59
+ Find the best travel deals for: {{destination}}
60
+ Dates: {{dates}}
61
+ Budget: {{budget}}
62
+
63
+ Research: flight options, accommodation deals, activity passes,
64
+ and money-saving tips. Compare prices across budget levels.
65
+ requiresApproval: false
66
+ expectedOutput: deal-list
67
+
68
+ - name: Itinerary Building
69
+ profileId: travel-planner
70
+ promptTemplate: |
71
+ Create a detailed day-by-day itinerary for: {{destination}}
72
+ Dates: {{dates}}
73
+ Budget: {{budget}}
74
+ {{#if interests}}Interests: {{interests}}{{/if}}
75
+
76
+ Use the research and deals from previous steps. Include:
77
+ daily schedule, meal recommendations, transport between activities,
78
+ estimated costs per day, and backup options for bad weather.
79
+ requiresApproval: true
80
+ expectedOutput: itinerary
@@ -0,0 +1,131 @@
1
+ import { db } from "@/lib/db";
2
+ import { workflows } from "@/lib/db/schema";
3
+ import { getBlueprint } from "./registry";
4
+ import { resolveTemplate, evaluateCondition } from "./template";
5
+ import type { BlueprintVariable, WorkflowBlueprint } from "./types";
6
+ import type { WorkflowStep } from "../types";
7
+
8
+ interface InstantiateResult {
9
+ workflowId: string;
10
+ name: string;
11
+ stepsCount: number;
12
+ skippedSteps: string[];
13
+ }
14
+
15
+ /**
16
+ * Instantiate a blueprint into a concrete draft workflow.
17
+ *
18
+ * 1. Validate all required variables
19
+ * 2. Resolve {{variable}} in prompt templates
20
+ * 3. Process {{#if}} conditional blocks
21
+ * 4. Evaluate step conditions, filter skipped steps
22
+ * 5. Create workflow with blueprintId lineage
23
+ */
24
+ export async function instantiateBlueprint(
25
+ blueprintId: string,
26
+ variables: Record<string, unknown>,
27
+ projectId?: string
28
+ ): Promise<InstantiateResult> {
29
+ const blueprint = getBlueprint(blueprintId);
30
+ if (!blueprint) {
31
+ throw new Error(`Blueprint "${blueprintId}" not found`);
32
+ }
33
+
34
+ // Validate required variables
35
+ validateVariables(blueprint.variables, variables);
36
+
37
+ // Apply defaults for unset optional variables
38
+ const resolvedVars = applyDefaults(blueprint.variables, variables);
39
+
40
+ // Process steps: resolve templates, evaluate conditions
41
+ const resolvedSteps: WorkflowStep[] = [];
42
+ const skippedSteps: string[] = [];
43
+
44
+ for (const step of blueprint.steps) {
45
+ // Check condition — skip if evaluates to falsy
46
+ if (step.condition && !evaluateCondition(step.condition, resolvedVars)) {
47
+ skippedSteps.push(step.name);
48
+ continue;
49
+ }
50
+
51
+ const resolvedPrompt = resolveTemplate(step.promptTemplate, resolvedVars);
52
+
53
+ resolvedSteps.push({
54
+ id: crypto.randomUUID(),
55
+ name: step.name,
56
+ prompt: resolvedPrompt,
57
+ requiresApproval: step.requiresApproval,
58
+ agentProfile: step.profileId,
59
+ });
60
+ }
61
+
62
+ if (resolvedSteps.length === 0) {
63
+ throw new Error("All steps were skipped by conditions — at least one step must remain");
64
+ }
65
+
66
+ // Create the workflow
67
+ const workflowId = crypto.randomUUID();
68
+ const now = new Date();
69
+ const workflowName = resolveTemplate(
70
+ `${blueprint.name}: {{${blueprint.variables[0]?.id ?? "topic"}}}`,
71
+ resolvedVars
72
+ ) || blueprint.name;
73
+
74
+ const definition = {
75
+ pattern: blueprint.pattern,
76
+ steps: resolvedSteps,
77
+ _blueprintId: blueprintId,
78
+ };
79
+
80
+ await db.insert(workflows).values({
81
+ id: workflowId,
82
+ projectId: projectId ?? null,
83
+ name: workflowName.slice(0, 100),
84
+ definition: JSON.stringify(definition),
85
+ status: "draft",
86
+ createdAt: now,
87
+ updatedAt: now,
88
+ });
89
+
90
+ return {
91
+ workflowId,
92
+ name: workflowName,
93
+ stepsCount: resolvedSteps.length,
94
+ skippedSteps,
95
+ };
96
+ }
97
+
98
+ function validateVariables(
99
+ definitions: BlueprintVariable[],
100
+ provided: Record<string, unknown>
101
+ ): void {
102
+ const errors: string[] = [];
103
+
104
+ for (const def of definitions) {
105
+ if (def.required) {
106
+ const value = provided[def.id];
107
+ if (value === undefined || value === null || value === "") {
108
+ errors.push(`"${def.label}" is required`);
109
+ }
110
+ }
111
+ }
112
+
113
+ if (errors.length > 0) {
114
+ throw new Error(`Missing required variables: ${errors.join(", ")}`);
115
+ }
116
+ }
117
+
118
+ function applyDefaults(
119
+ definitions: BlueprintVariable[],
120
+ provided: Record<string, unknown>
121
+ ): Record<string, unknown> {
122
+ const result = { ...provided };
123
+
124
+ for (const def of definitions) {
125
+ if (result[def.id] === undefined && def.default !== undefined) {
126
+ result[def.id] = def.default;
127
+ }
128
+ }
129
+
130
+ return result;
131
+ }
@@ -0,0 +1,128 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import yaml from "js-yaml";
4
+ import { BlueprintSchema } from "@/lib/validators/blueprint";
5
+ import { getStagentBlueprintsDir } from "@/lib/utils/stagent-paths";
6
+ import type { WorkflowBlueprint } from "./types";
7
+
8
+ // Use fileURLToPath for ESM compatibility in Next.js
9
+ const BUILTINS_DIR = path.resolve(
10
+ import.meta.dirname ?? path.dirname(new URL(import.meta.url).pathname),
11
+ "builtins"
12
+ );
13
+
14
+ const USER_BLUEPRINTS_DIR = getStagentBlueprintsDir();
15
+
16
+ let blueprintCache: Map<string, WorkflowBlueprint> | null = null;
17
+
18
+ function scanDirectory(
19
+ dir: string,
20
+ isBuiltin: boolean
21
+ ): Map<string, WorkflowBlueprint> {
22
+ const blueprints = new Map<string, WorkflowBlueprint>();
23
+
24
+ if (!fs.existsSync(dir)) return blueprints;
25
+
26
+ for (const file of fs.readdirSync(dir)) {
27
+ if (!file.endsWith(".yaml") && !file.endsWith(".yml")) continue;
28
+
29
+ try {
30
+ const content = fs.readFileSync(path.join(dir, file), "utf-8");
31
+ const parsed = yaml.load(content);
32
+ const result = BlueprintSchema.safeParse(parsed);
33
+
34
+ if (!result.success) {
35
+ console.warn(
36
+ `[blueprints] Invalid blueprint ${file}:`,
37
+ result.error.issues.map((i) => i.message).join(", ")
38
+ );
39
+ continue;
40
+ }
41
+
42
+ blueprints.set(result.data.id, { ...result.data, isBuiltin });
43
+ } catch (err) {
44
+ console.warn(`[blueprints] Error loading ${file}:`, err);
45
+ }
46
+ }
47
+
48
+ return blueprints;
49
+ }
50
+
51
+ function loadAll(): Map<string, WorkflowBlueprint> {
52
+ const all = new Map<string, WorkflowBlueprint>();
53
+
54
+ // Load built-ins first
55
+ for (const [id, bp] of scanDirectory(BUILTINS_DIR, true)) {
56
+ all.set(id, bp);
57
+ }
58
+
59
+ // User blueprints can override built-ins
60
+ for (const [id, bp] of scanDirectory(USER_BLUEPRINTS_DIR, false)) {
61
+ all.set(id, bp);
62
+ }
63
+
64
+ return all;
65
+ }
66
+
67
+ function ensureLoaded(): Map<string, WorkflowBlueprint> {
68
+ if (!blueprintCache) {
69
+ blueprintCache = loadAll();
70
+ }
71
+ return blueprintCache;
72
+ }
73
+
74
+ export function getBlueprint(id: string): WorkflowBlueprint | undefined {
75
+ return ensureLoaded().get(id);
76
+ }
77
+
78
+ export function listBlueprints(): WorkflowBlueprint[] {
79
+ return Array.from(ensureLoaded().values());
80
+ }
81
+
82
+ export function reloadBlueprints(): void {
83
+ blueprintCache = null;
84
+ }
85
+
86
+ export function isBuiltinBlueprint(id: string): boolean {
87
+ const bp = ensureLoaded().get(id);
88
+ return bp?.isBuiltin ?? false;
89
+ }
90
+
91
+ export function createBlueprint(yamlContent: string): WorkflowBlueprint {
92
+ const parsed = yaml.load(yamlContent);
93
+ const result = BlueprintSchema.safeParse(parsed);
94
+ if (!result.success) {
95
+ throw new Error(
96
+ `Invalid blueprint: ${result.error.issues.map((i) => i.message).join(", ")}`
97
+ );
98
+ }
99
+
100
+ fs.mkdirSync(USER_BLUEPRINTS_DIR, { recursive: true });
101
+ const filePath = path.join(USER_BLUEPRINTS_DIR, `${result.data.id}.yaml`);
102
+ if (fs.existsSync(filePath)) {
103
+ throw new Error(`Blueprint "${result.data.id}" already exists`);
104
+ }
105
+
106
+ fs.writeFileSync(filePath, yamlContent);
107
+ reloadBlueprints();
108
+ return { ...result.data, isBuiltin: false };
109
+ }
110
+
111
+ export function deleteBlueprint(id: string): void {
112
+ if (isBuiltinBlueprint(id)) {
113
+ throw new Error("Cannot delete built-in blueprints");
114
+ }
115
+
116
+ const filePath = path.join(USER_BLUEPRINTS_DIR, `${id}.yaml`);
117
+ if (!fs.existsSync(filePath)) {
118
+ throw new Error(`Blueprint "${id}" not found`);
119
+ }
120
+
121
+ fs.unlinkSync(filePath);
122
+ reloadBlueprints();
123
+ }
124
+
125
+ /** Get the user blueprints directory path */
126
+ export function getUserBlueprintsDir(): string {
127
+ return USER_BLUEPRINTS_DIR;
128
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Template resolution for blueprint prompt templates.
3
+ *
4
+ * Supports:
5
+ * - {{variable}} — simple substitution
6
+ * - {{#if variable}}...{{/if}} — conditional blocks
7
+ */
8
+
9
+ /**
10
+ * Resolve all template expressions in a string.
11
+ */
12
+ export function resolveTemplate(
13
+ template: string,
14
+ variables: Record<string, unknown>
15
+ ): string {
16
+ let result = template;
17
+
18
+ // Process {{#if variable}}...{{/if}} blocks first
19
+ result = result.replace(
20
+ /\{\{#if\s+(\w+)\}\}([\s\S]*?)\{\{\/if\}\}/g,
21
+ (_match, varName: string, content: string) => {
22
+ const value = variables[varName];
23
+ return isTruthy(value) ? content : "";
24
+ }
25
+ );
26
+
27
+ // Then substitute {{variable}} references
28
+ result = result.replace(/\{\{(\w+)\}\}/g, (_match, varName: string) => {
29
+ const value = variables[varName];
30
+ if (value === undefined || value === null) return "";
31
+ return String(value);
32
+ });
33
+
34
+ // Clean up multiple consecutive blank lines left by removed conditionals
35
+ result = result.replace(/\n{3,}/g, "\n\n");
36
+
37
+ return result.trim();
38
+ }
39
+
40
+ /**
41
+ * Evaluate a condition string (a template expression like "{{variable}}").
42
+ * Returns true if the resolved value is truthy.
43
+ */
44
+ export function evaluateCondition(
45
+ condition: string,
46
+ variables: Record<string, unknown>
47
+ ): boolean {
48
+ // Strip template syntax to get the variable name
49
+ const varName = condition.replace(/\{\{|\}\}/g, "").trim();
50
+ return isTruthy(variables[varName]);
51
+ }
52
+
53
+ function isTruthy(value: unknown): boolean {
54
+ if (value === undefined || value === null || value === "" || value === false) {
55
+ return false;
56
+ }
57
+ return true;
58
+ }