@assistkick/create 1.6.0 → 1.8.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 (214) hide show
  1. package/package.json +2 -2
  2. package/templates/assistkick-product-system/.env.example +1 -0
  3. package/templates/assistkick-product-system/local.db +0 -0
  4. package/templates/assistkick-product-system/package.json +4 -2
  5. package/templates/assistkick-product-system/packages/backend/package.json +2 -0
  6. package/templates/assistkick-product-system/packages/backend/src/routes/agents.ts +165 -0
  7. package/templates/assistkick-product-system/packages/backend/src/routes/files.test.ts +358 -0
  8. package/templates/assistkick-product-system/packages/backend/src/routes/files.ts +356 -0
  9. package/templates/assistkick-product-system/packages/backend/src/routes/git.ts +96 -1
  10. package/templates/assistkick-product-system/packages/backend/src/routes/graph.ts +1 -0
  11. package/templates/assistkick-product-system/packages/backend/src/routes/kanban.ts +43 -4
  12. package/templates/assistkick-product-system/packages/backend/src/routes/pipeline.ts +200 -84
  13. package/templates/assistkick-product-system/packages/backend/src/routes/projects.ts +6 -3
  14. package/templates/assistkick-product-system/packages/backend/src/routes/terminal.ts +53 -17
  15. package/templates/assistkick-product-system/packages/backend/src/routes/video.ts +218 -0
  16. package/templates/assistkick-product-system/packages/backend/src/routes/workflow_groups.ts +119 -0
  17. package/templates/assistkick-product-system/packages/backend/src/routes/workflows.ts +154 -0
  18. package/templates/assistkick-product-system/packages/backend/src/server.ts +81 -9
  19. package/templates/assistkick-product-system/packages/backend/src/services/agent_service.test.ts +489 -0
  20. package/templates/assistkick-product-system/packages/backend/src/services/agent_service.ts +416 -0
  21. package/templates/assistkick-product-system/packages/backend/src/services/bundle_service.test.ts +189 -0
  22. package/templates/assistkick-product-system/packages/backend/src/services/bundle_service.ts +182 -0
  23. package/templates/assistkick-product-system/packages/backend/src/services/init.ts +28 -78
  24. package/templates/assistkick-product-system/packages/backend/src/services/project_service.test.ts +16 -0
  25. package/templates/assistkick-product-system/packages/backend/src/services/project_service.ts +73 -2
  26. package/templates/assistkick-product-system/packages/backend/src/services/project_workspace_service.test.ts +4 -4
  27. package/templates/assistkick-product-system/packages/backend/src/services/project_workspace_service.ts +87 -11
  28. package/templates/assistkick-product-system/packages/backend/src/services/pty_session_manager.test.ts +210 -69
  29. package/templates/assistkick-product-system/packages/backend/src/services/pty_session_manager.ts +210 -215
  30. package/templates/assistkick-product-system/packages/backend/src/services/ssh_key_service.test.ts +162 -0
  31. package/templates/assistkick-product-system/packages/backend/src/services/ssh_key_service.ts +148 -0
  32. package/templates/assistkick-product-system/packages/backend/src/services/terminal_ws_handler.ts +11 -5
  33. package/templates/assistkick-product-system/packages/backend/src/services/tts_service.test.ts +64 -0
  34. package/templates/assistkick-product-system/packages/backend/src/services/tts_service.ts +134 -0
  35. package/templates/assistkick-product-system/packages/backend/src/services/video_render_service.test.ts +256 -0
  36. package/templates/assistkick-product-system/packages/backend/src/services/video_render_service.ts +258 -0
  37. package/templates/assistkick-product-system/packages/backend/src/services/workflow_group_service.ts +106 -0
  38. package/templates/assistkick-product-system/packages/backend/src/services/workflow_service.test.ts +275 -0
  39. package/templates/assistkick-product-system/packages/backend/src/services/workflow_service.ts +222 -0
  40. package/templates/assistkick-product-system/packages/frontend/index.html +3 -0
  41. package/templates/assistkick-product-system/packages/frontend/package-lock.json +800 -11
  42. package/templates/assistkick-product-system/packages/frontend/package.json +11 -1
  43. package/templates/assistkick-product-system/packages/frontend/src/App.tsx +24 -7
  44. package/templates/assistkick-product-system/packages/frontend/src/api/client.ts +456 -16
  45. package/templates/assistkick-product-system/packages/frontend/src/api/client_files.test.ts +172 -0
  46. package/templates/assistkick-product-system/packages/frontend/src/api/client_video.test.ts +238 -0
  47. package/templates/assistkick-product-system/packages/frontend/src/components/AgentsView.tsx +307 -0
  48. package/templates/assistkick-product-system/packages/frontend/src/components/CoherenceView.tsx +82 -66
  49. package/templates/assistkick-product-system/packages/frontend/src/components/CompositionPlaceholder.tsx +97 -0
  50. package/templates/assistkick-product-system/packages/frontend/src/components/DesignSystemView.tsx +383 -0
  51. package/templates/assistkick-product-system/packages/frontend/src/components/EditorTabBar.tsx +57 -0
  52. package/templates/assistkick-product-system/packages/frontend/src/components/FileTree.tsx +313 -0
  53. package/templates/assistkick-product-system/packages/frontend/src/components/FileTreeContextMenu.tsx +61 -0
  54. package/templates/assistkick-product-system/packages/frontend/src/components/FileTreeInlineInput.tsx +73 -0
  55. package/templates/assistkick-product-system/packages/frontend/src/components/FilesView.tsx +404 -0
  56. package/templates/assistkick-product-system/packages/frontend/src/components/GitRepoModal.tsx +193 -64
  57. package/templates/assistkick-product-system/packages/frontend/src/components/GraphLegend.tsx +71 -73
  58. package/templates/assistkick-product-system/packages/frontend/src/components/GraphSettings.tsx +8 -8
  59. package/templates/assistkick-product-system/packages/frontend/src/components/GraphView.tsx +1 -1
  60. package/templates/assistkick-product-system/packages/frontend/src/components/InviteUserDialog.tsx +15 -11
  61. package/templates/assistkick-product-system/packages/frontend/src/components/KanbanView.tsx +226 -291
  62. package/templates/assistkick-product-system/packages/frontend/src/components/LoginPage.tsx +14 -14
  63. package/templates/assistkick-product-system/packages/frontend/src/components/ProjectSelector.tsx +54 -33
  64. package/templates/assistkick-product-system/packages/frontend/src/components/QaIssueSheet.tsx +40 -66
  65. package/templates/assistkick-product-system/packages/frontend/src/components/SidePanel.tsx +55 -115
  66. package/templates/assistkick-product-system/packages/frontend/src/components/TerminalView.tsx +121 -52
  67. package/templates/assistkick-product-system/packages/frontend/src/components/Toolbar.tsx +155 -77
  68. package/templates/assistkick-product-system/packages/frontend/src/components/UsersView.tsx +52 -52
  69. package/templates/assistkick-product-system/packages/frontend/src/components/VideoGallery.tsx +313 -0
  70. package/templates/assistkick-product-system/packages/frontend/src/components/VideographyView.tsx +250 -0
  71. package/templates/assistkick-product-system/packages/frontend/src/components/WorkflowsView.tsx +474 -0
  72. package/templates/assistkick-product-system/packages/frontend/src/components/ds/AccentBorderList.tsx +53 -0
  73. package/templates/assistkick-product-system/packages/frontend/src/components/ds/Button.tsx +87 -0
  74. package/templates/assistkick-product-system/packages/frontend/src/components/ds/ButtonGroup.tsx +29 -0
  75. package/templates/assistkick-product-system/packages/frontend/src/components/ds/ButtonShowcase.tsx +221 -0
  76. package/templates/assistkick-product-system/packages/frontend/src/components/ds/CardGlass.tsx +141 -0
  77. package/templates/assistkick-product-system/packages/frontend/src/components/ds/CompletionRing.tsx +30 -0
  78. package/templates/assistkick-product-system/packages/frontend/src/components/ds/ContentCard.tsx +34 -0
  79. package/templates/assistkick-product-system/packages/frontend/src/components/ds/IconButton.tsx +74 -0
  80. package/templates/assistkick-product-system/packages/frontend/src/components/ds/KanbanCard.tsx +270 -0
  81. package/templates/assistkick-product-system/packages/frontend/src/components/ds/KanbanCardShowcase.tsx +37 -0
  82. package/templates/assistkick-product-system/packages/frontend/src/components/ds/Kbd.tsx +11 -0
  83. package/templates/assistkick-product-system/packages/frontend/src/components/ds/KindBadge.tsx +21 -0
  84. package/templates/assistkick-product-system/packages/frontend/src/components/ds/NavBarSidekick.tsx +207 -0
  85. package/templates/assistkick-product-system/packages/frontend/src/components/ds/SidePanelShowcase.tsx +370 -0
  86. package/templates/assistkick-product-system/packages/frontend/src/components/ds/SideSheet.tsx +64 -0
  87. package/templates/assistkick-product-system/packages/frontend/src/components/ds/StatusDot.tsx +18 -0
  88. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/CheckCardPositionNode.tsx +36 -0
  89. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/CheckCycleCountNode.tsx +60 -0
  90. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/EndNode.tsx +42 -0
  91. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/GroupNode.tsx +189 -0
  92. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/NodePalette.tsx +123 -0
  93. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/RunAgentNode.tsx +51 -0
  94. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/SetCardMetadataNode.tsx +53 -0
  95. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/StartNode.tsx +18 -0
  96. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/TransitionCardNode.tsx +59 -0
  97. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/WorkflowCanvas.tsx +335 -0
  98. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/WorkflowMonitorModal.tsx +634 -0
  99. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/autoLayout.ts +103 -0
  100. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/edgeColors.ts +35 -0
  101. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/monitor_nodes.tsx +208 -0
  102. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/workflow_types.test.ts +119 -0
  103. package/templates/assistkick-product-system/packages/frontend/src/components/workflow/workflow_types.ts +107 -0
  104. package/templates/assistkick-product-system/packages/frontend/src/constants/graph.ts +13 -11
  105. package/templates/assistkick-product-system/packages/frontend/src/hooks/useAutoSave.ts +75 -0
  106. package/templates/assistkick-product-system/packages/frontend/src/hooks/useGraph.ts +6 -21
  107. package/templates/assistkick-product-system/packages/frontend/src/hooks/useProjects.ts +15 -80
  108. package/templates/assistkick-product-system/packages/frontend/src/hooks/useToast.tsx +16 -3
  109. package/templates/assistkick-product-system/packages/frontend/src/pages/accept_invitation_page.tsx +30 -27
  110. package/templates/assistkick-product-system/packages/frontend/src/pages/forgot_password_page.tsx +18 -15
  111. package/templates/assistkick-product-system/packages/frontend/src/pages/register_page.tsx +21 -18
  112. package/templates/assistkick-product-system/packages/frontend/src/pages/reset_password_page.tsx +28 -25
  113. package/templates/assistkick-product-system/packages/frontend/src/routes/AgentsRoute.tsx +6 -0
  114. package/templates/assistkick-product-system/packages/frontend/src/routes/CoherenceRoute.tsx +19 -0
  115. package/templates/assistkick-product-system/packages/frontend/src/routes/DashboardLayout.tsx +54 -0
  116. package/templates/assistkick-product-system/packages/frontend/src/routes/DesignSystemRoute.tsx +6 -0
  117. package/templates/assistkick-product-system/packages/frontend/src/routes/FilesRoute.tsx +13 -0
  118. package/templates/assistkick-product-system/packages/frontend/src/routes/GraphRoute.tsx +93 -0
  119. package/templates/assistkick-product-system/packages/frontend/src/routes/KanbanRoute.tsx +30 -0
  120. package/templates/assistkick-product-system/packages/frontend/src/routes/TerminalRoute.tsx +9 -0
  121. package/templates/assistkick-product-system/packages/frontend/src/routes/UsersRoute.tsx +6 -0
  122. package/templates/assistkick-product-system/packages/frontend/src/routes/VideographyRoute.tsx +13 -0
  123. package/templates/assistkick-product-system/packages/frontend/src/routes/WorkflowsRoute.tsx +6 -0
  124. package/templates/assistkick-product-system/packages/frontend/src/stores/useGitModalStore.ts +14 -0
  125. package/templates/assistkick-product-system/packages/frontend/src/stores/useGraphStore.ts +36 -0
  126. package/templates/assistkick-product-system/packages/frontend/src/stores/useGraphUIStore.ts +25 -0
  127. package/templates/assistkick-product-system/packages/frontend/src/stores/useProjectStore.ts +90 -0
  128. package/templates/assistkick-product-system/packages/frontend/src/stores/useQaSheetStore.ts +27 -0
  129. package/templates/assistkick-product-system/packages/frontend/src/stores/useSidePanelStore.ts +76 -0
  130. package/templates/assistkick-product-system/packages/frontend/src/styles/index.css +336 -3632
  131. package/templates/assistkick-product-system/packages/frontend/src/utils/auto_save_service.test.ts +167 -0
  132. package/templates/assistkick-product-system/packages/frontend/src/utils/auto_save_service.ts +101 -0
  133. package/templates/assistkick-product-system/packages/frontend/src/utils/composition_matcher.test.ts +42 -0
  134. package/templates/assistkick-product-system/packages/frontend/src/utils/composition_matcher.ts +17 -0
  135. package/templates/assistkick-product-system/packages/frontend/src/utils/file_utils.test.ts +145 -0
  136. package/templates/assistkick-product-system/packages/frontend/src/utils/file_utils.ts +42 -0
  137. package/templates/assistkick-product-system/packages/frontend/src/utils/task_status.test.ts +4 -10
  138. package/templates/assistkick-product-system/packages/frontend/src/utils/task_status.ts +19 -1
  139. package/templates/assistkick-product-system/packages/frontend/vite.config.ts +7 -1
  140. package/templates/assistkick-product-system/packages/shared/db/local.db +0 -0
  141. package/templates/assistkick-product-system/packages/shared/db/migrations/0004_tidy_matthew_murdock.sql +9 -0
  142. package/templates/assistkick-product-system/packages/shared/db/migrations/0005_mysterious_falcon.sql +692 -0
  143. package/templates/assistkick-product-system/packages/shared/db/migrations/0006_next_venom.sql +9 -0
  144. package/templates/assistkick-product-system/packages/shared/db/migrations/0007_deep_barracuda.sql +39 -0
  145. package/templates/assistkick-product-system/packages/shared/db/migrations/0008_puzzling_hannibal_king.sql +1 -0
  146. package/templates/assistkick-product-system/packages/shared/db/migrations/0009_amused_beast.sql +8 -0
  147. package/templates/assistkick-product-system/packages/shared/db/migrations/0010_spotty_moira_mactaggert.sql +9 -0
  148. package/templates/assistkick-product-system/packages/shared/db/migrations/0011_goofy_snowbird.sql +3 -0
  149. package/templates/assistkick-product-system/packages/shared/db/migrations/0011_supreme_doctor_octopus.sql +3 -0
  150. package/templates/assistkick-product-system/packages/shared/db/migrations/0013_reflective_prowler.sql +15 -0
  151. package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0004_snapshot.json +921 -0
  152. package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0005_snapshot.json +1042 -0
  153. package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0006_snapshot.json +1101 -0
  154. package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0007_snapshot.json +1336 -0
  155. package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0008_snapshot.json +1275 -0
  156. package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0009_snapshot.json +1327 -0
  157. package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0010_snapshot.json +1393 -0
  158. package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0011_snapshot.json +1436 -0
  159. package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0013_snapshot.json +1538 -0
  160. package/templates/assistkick-product-system/packages/shared/db/migrations/meta/_journal.json +70 -0
  161. package/templates/assistkick-product-system/packages/shared/db/schema.ts +113 -0
  162. package/templates/assistkick-product-system/packages/shared/lib/claude-service.ts +32 -7
  163. package/templates/assistkick-product-system/packages/shared/lib/constants.ts +9 -0
  164. package/templates/assistkick-product-system/packages/shared/lib/git_workflow.ts +12 -4
  165. package/templates/assistkick-product-system/packages/shared/lib/graph.ts +16 -5
  166. package/templates/assistkick-product-system/packages/shared/lib/workflow_engine.test.ts +1753 -0
  167. package/templates/assistkick-product-system/packages/shared/lib/workflow_engine.ts +1281 -0
  168. package/templates/assistkick-product-system/packages/shared/lib/workflow_orchestrator.ts +211 -0
  169. package/templates/assistkick-product-system/packages/shared/tools/add_node.test.ts +43 -0
  170. package/templates/assistkick-product-system/packages/shared/tools/add_node.ts +13 -2
  171. package/templates/assistkick-product-system/packages/shared/tools/get_kanban.ts +1 -1
  172. package/templates/assistkick-product-system/packages/shared/tools/migrate_epics.test.ts +226 -0
  173. package/templates/assistkick-product-system/packages/shared/tools/migrate_epics.ts +251 -0
  174. package/templates/assistkick-product-system/packages/shared/tools/update_node.ts +2 -2
  175. package/templates/assistkick-product-system/packages/shared/utils/hello_workflow.test.ts +10 -0
  176. package/templates/assistkick-product-system/packages/shared/utils/hello_workflow.ts +6 -0
  177. package/templates/assistkick-product-system/packages/video/Root.tsx +85 -0
  178. package/templates/assistkick-product-system/packages/video/components/email_scene.tsx +231 -0
  179. package/templates/assistkick-product-system/packages/video/components/outro_scene.tsx +153 -0
  180. package/templates/assistkick-product-system/packages/video/components/part_divider.tsx +90 -0
  181. package/templates/assistkick-product-system/packages/video/components/scene.tsx +226 -0
  182. package/templates/assistkick-product-system/packages/video/components/theme.ts +22 -0
  183. package/templates/assistkick-product-system/packages/video/components/title_scene.tsx +169 -0
  184. package/templates/assistkick-product-system/packages/video/components/video_split_layout.tsx +84 -0
  185. package/templates/assistkick-product-system/packages/video/compositions/.gitkeep +0 -0
  186. package/templates/assistkick-product-system/packages/video/index.ts +4 -0
  187. package/templates/assistkick-product-system/packages/video/package.json +28 -0
  188. package/templates/assistkick-product-system/packages/video/remotion.config.ts +11 -0
  189. package/templates/assistkick-product-system/packages/video/scripts/process_script.test.ts +326 -0
  190. package/templates/assistkick-product-system/packages/video/scripts/process_script.ts +630 -0
  191. package/templates/assistkick-product-system/packages/video/style.css +1 -0
  192. package/templates/assistkick-product-system/packages/video/tsconfig.json +18 -0
  193. package/templates/assistkick-product-system/tests/graph_legend.test.ts +2 -1
  194. package/templates/assistkick-product-system/tests/video_render_service.test.ts +179 -0
  195. package/templates/assistkick-product-system/tests/web_terminal.test.ts +219 -455
  196. package/templates/assistkick-product-system/tests/workflow_integration.test.ts +341 -0
  197. package/templates/skills/assistkick-bootstrap/SKILL.md +3 -3
  198. package/templates/skills/assistkick-code-reviewer/SKILL.md +2 -2
  199. package/templates/skills/assistkick-debugger/SKILL.md +2 -2
  200. package/templates/skills/assistkick-developer/SKILL.md +6 -3
  201. package/templates/skills/assistkick-developer/references/react_development_guidelines.md +225 -0
  202. package/templates/skills/assistkick-interview/SKILL.md +2 -2
  203. package/templates/skills/product-system/graph.json +1890 -0
  204. package/templates/skills/product-system/kanban.json +304 -0
  205. package/templates/skills/product-system/nodes/comp_001.md +56 -0
  206. package/templates/skills/product-system/nodes/comp_002.md +57 -0
  207. package/templates/skills/product-system/nodes/data_001.md +51 -0
  208. package/templates/skills/product-system/nodes/data_002.md +40 -0
  209. package/templates/skills/product-system/nodes/data_004.md +38 -0
  210. package/templates/skills/product-system/nodes/dec_001.md +34 -0
  211. package/templates/skills/product-system/nodes/dec_016.md +32 -0
  212. package/templates/skills/product-system/nodes/feat_008.md +30 -0
  213. package/templates/skills/video-composition-agent/SKILL.md +232 -0
  214. package/templates/skills/video-script-writer/SKILL.md +136 -0
@@ -29,6 +29,76 @@
29
29
  "when": 1772812820535,
30
30
  "tag": "0003_lonely_cyclops",
31
31
  "breakpoints": true
32
+ },
33
+ {
34
+ "idx": 4,
35
+ "version": "6",
36
+ "when": 1772975082564,
37
+ "tag": "0004_tidy_matthew_murdock",
38
+ "breakpoints": true
39
+ },
40
+ {
41
+ "idx": 5,
42
+ "version": "6",
43
+ "when": 1772982318304,
44
+ "tag": "0005_mysterious_falcon",
45
+ "breakpoints": true
46
+ },
47
+ {
48
+ "idx": 6,
49
+ "version": "6",
50
+ "when": 1772984904854,
51
+ "tag": "0006_next_venom",
52
+ "breakpoints": true
53
+ },
54
+ {
55
+ "idx": 7,
56
+ "version": "6",
57
+ "when": 1773003174080,
58
+ "tag": "0007_deep_barracuda",
59
+ "breakpoints": true
60
+ },
61
+ {
62
+ "idx": 8,
63
+ "version": "6",
64
+ "when": 1773122459461,
65
+ "tag": "0008_puzzling_hannibal_king",
66
+ "breakpoints": true
67
+ },
68
+ {
69
+ "idx": 9,
70
+ "version": "6",
71
+ "when": 1773127312138,
72
+ "tag": "0009_amused_beast",
73
+ "breakpoints": true
74
+ },
75
+ {
76
+ "idx": 10,
77
+ "version": "6",
78
+ "when": 1773143546640,
79
+ "tag": "0010_spotty_moira_mactaggert",
80
+ "breakpoints": true
81
+ },
82
+ {
83
+ "idx": 11,
84
+ "version": "6",
85
+ "when": 1773169770877,
86
+ "tag": "0011_supreme_doctor_octopus",
87
+ "breakpoints": true
88
+ },
89
+ {
90
+ "idx": 12,
91
+ "version": "6",
92
+ "when": 1773170271654,
93
+ "tag": "0011_goofy_snowbird",
94
+ "breakpoints": true
95
+ },
96
+ {
97
+ "idx": 13,
98
+ "version": "6",
99
+ "when": 1773179139368,
100
+ "tag": "0013_reflective_prowler",
101
+ "breakpoints": true
32
102
  }
33
103
  ]
34
104
  }
@@ -10,6 +10,7 @@ export const nodes = sqliteTable('nodes', {
10
10
  completeness: real('completeness').notNull().default(0),
11
11
  openQuestionsCount: integer('open_questions_count').notNull().default(0),
12
12
  kind: text('kind'),
13
+ featureType: text('feature_type'),
13
14
  createdAt: text('created_at').notNull(),
14
15
  updatedAt: text('updated_at').notNull(),
15
16
  body: text('body'),
@@ -119,16 +120,31 @@ export const invitations = sqliteTable('invitations', {
119
120
  export const projects = sqliteTable('projects', {
120
121
  id: text('id').primaryKey(),
121
122
  name: text('name').notNull(),
123
+ type: text('type').notNull().default('software'),
122
124
  isDefault: integer('is_default').notNull().default(0),
123
125
  archivedAt: text('archived_at'),
124
126
  repoUrl: text('repo_url'),
125
127
  githubInstallationId: text('github_installation_id'),
126
128
  githubRepoFullName: text('github_repo_full_name'),
127
129
  baseBranch: text('base_branch'),
130
+ gitAuthMethod: text('git_auth_method'),
131
+ sshPrivateKeyEncrypted: text('ssh_private_key_encrypted'),
132
+ sshPublicKey: text('ssh_public_key'),
128
133
  createdAt: text('created_at').notNull(),
129
134
  updatedAt: text('updated_at').notNull(),
130
135
  });
131
136
 
137
+ // --- terminal_sessions table ---
138
+ export const terminalSessions = sqliteTable('terminal_sessions', {
139
+ id: text('id').primaryKey(),
140
+ claudeSessionId: text('claude_session_id').notNull(),
141
+ projectId: text('project_id').notNull(),
142
+ projectName: text('project_name').notNull(),
143
+ name: text('name').notNull(),
144
+ createdAt: text('created_at').notNull(),
145
+ lastUsedAt: text('last_used_at').notNull(),
146
+ });
147
+
132
148
  // --- pipeline_state table ---
133
149
  export const pipelineState = sqliteTable('pipeline_state', {
134
150
  featureId: text('feature_id').primaryKey(),
@@ -142,3 +158,100 @@ export const pipelineState = sqliteTable('pipeline_state', {
142
158
  updatedAt: text('updated_at').notNull(),
143
159
  projectId: text('project_id'),
144
160
  });
161
+
162
+ // --- pipeline_outputs table ---
163
+ export const pipelineOutputs = sqliteTable('pipeline_outputs', {
164
+ id: text('id').primaryKey(),
165
+ featureId: text('feature_id').notNull(),
166
+ stage: text('stage').notNull(),
167
+ cycle: integer('cycle').notNull(),
168
+ output: text('output').notNull(),
169
+ createdAt: text('created_at').notNull(),
170
+ projectId: text('project_id'),
171
+ });
172
+
173
+ // --- agents table ---
174
+ export const agents = sqliteTable('agents', {
175
+ id: text('id').primaryKey(),
176
+ name: text('name').notNull(),
177
+ promptTemplate: text('prompt_template').notNull(),
178
+ projectId: text('project_id'),
179
+ isDefault: integer('is_default').notNull().default(0),
180
+ createdAt: text('created_at').notNull(),
181
+ updatedAt: text('updated_at').notNull(),
182
+ });
183
+
184
+ // --- workflows table ---
185
+ export const workflows = sqliteTable('workflows', {
186
+ id: text('id').primaryKey(),
187
+ name: text('name').notNull(),
188
+ description: text('description'),
189
+ projectId: text('project_id'),
190
+ featureType: text('feature_type'),
191
+ isDefault: integer('is_default').notNull().default(0),
192
+ graphData: text('graph_data').notNull(),
193
+ createdAt: text('created_at').notNull(),
194
+ updatedAt: text('updated_at').notNull(),
195
+ });
196
+
197
+ // --- workflow_executions table ---
198
+ export const workflowExecutions = sqliteTable('workflow_executions', {
199
+ id: text('id').primaryKey(),
200
+ workflowId: text('workflow_id').notNull().references(() => workflows.id),
201
+ featureId: text('feature_id').notNull(),
202
+ status: text('status').notNull(),
203
+ currentNodeId: text('current_node_id'),
204
+ context: text('context').notNull(),
205
+ startedAt: text('started_at').notNull(),
206
+ updatedAt: text('updated_at').notNull(),
207
+ });
208
+
209
+ // --- workflow_groups table ---
210
+ export const workflowGroups = sqliteTable('workflow_groups', {
211
+ id: text('id').primaryKey(),
212
+ name: text('name').notNull(),
213
+ projectId: text('project_id'),
214
+ graphData: text('graph_data').notNull(),
215
+ createdAt: text('created_at').notNull(),
216
+ updatedAt: text('updated_at').notNull(),
217
+ });
218
+
219
+ // --- workflow_node_executions table ---
220
+ export const workflowNodeExecutions = sqliteTable('workflow_node_executions', {
221
+ id: text('id').primaryKey(),
222
+ executionId: text('execution_id').notNull().references(() => workflowExecutions.id),
223
+ nodeId: text('node_id').notNull(),
224
+ status: text('status').notNull(),
225
+ startedAt: text('started_at'),
226
+ completedAt: text('completed_at'),
227
+ outputData: text('output_data'),
228
+ error: text('error'),
229
+ attempt: integer('attempt').notNull().default(1),
230
+ });
231
+
232
+ // --- workflow_tool_calls table ---
233
+ export const workflowToolCalls = sqliteTable('workflow_tool_calls', {
234
+ id: text('id').primaryKey(),
235
+ nodeExecutionId: text('node_execution_id').notNull().references(() => workflowNodeExecutions.id),
236
+ timestamp: text('timestamp').notNull(),
237
+ toolName: text('tool_name').notNull(),
238
+ target: text('target').notNull(),
239
+ createdAt: text('created_at').notNull(),
240
+ });
241
+
242
+ // --- video_renders table ---
243
+ export const videoRenders = sqliteTable('video_renders', {
244
+ id: text('id').primaryKey(),
245
+ projectId: text('project_id').notNull(),
246
+ featureId: text('feature_id'),
247
+ compositionId: text('composition_id').notNull(),
248
+ status: text('status').notNull(), // queued, rendering, complete, failed
249
+ progress: real('progress').notNull().default(0),
250
+ filePath: text('file_path'),
251
+ fileSize: integer('file_size'),
252
+ durationSeconds: real('duration_seconds'),
253
+ error: text('error'),
254
+ resolution: text('resolution'), // e.g. "1920x1080"
255
+ createdAt: text('created_at').notNull(),
256
+ completedAt: text('completed_at'),
257
+ });
@@ -131,6 +131,25 @@ export const emitToolUseEvents = (jsonStr, callback) => {
131
131
  }
132
132
  };
133
133
 
134
+ /**
135
+ * Extract assistant text blocks from a stream-json line and invoke a callback.
136
+ * Fires for each text block found in assistant messages.
137
+ */
138
+ export const emitAssistantTextEvents = (jsonStr, callback) => {
139
+ try {
140
+ const event = JSON.parse(jsonStr);
141
+ if (event.type === 'assistant' && event.message?.content) {
142
+ for (const block of event.message.content) {
143
+ if (block.type === 'text' && block.text) {
144
+ callback(block.text);
145
+ }
146
+ }
147
+ }
148
+ } catch {
149
+ // Not valid JSON — skip silently
150
+ }
151
+ };
152
+
134
153
  /**
135
154
  * Extract result event metadata from a stream-json line and invoke a callback.
136
155
  * Fires once when the result event is encountered, providing usage stats.
@@ -186,13 +205,17 @@ export const emitAssistantUsage = (jsonStr, callback) => {
186
205
  * @returns {{ spawnClaude: function, spawnCommand: function }}
187
206
  */
188
207
  export const createClaudeService = ({ verbose = false, log: logFn }) => {
189
- const spawnClaude = (prompt, cwd, label = 'claude', { onToolUse, onResult, onTurnUsage } = {}) => new Promise((resolve, reject) => {
208
+ const spawnClaude = (prompt, cwd, label = 'claude', { onToolUse, onResult, onTurnUsage, onAssistantText } = {}) => new Promise((resolve, reject) => {
190
209
  const promptPreview = prompt.slice(0, 100).replace(/\n/g, '\\n');
191
210
  logFn('CLAUDE', `Spawning ${label} in ${cwd} — prompt length: ${prompt.length} chars`);
192
211
  logFn('CLAUDE', `Prompt preview: "${promptPreview}..."`);
193
212
 
213
+ // Use stream-json when verbose OR when any callback needs structured events
214
+ const hasCallbacks = !!(onToolUse || onResult || onTurnUsage || onAssistantText);
215
+ const useStreamJson = verbose || hasCallbacks;
216
+
194
217
  const claudeArgs = ['--dangerously-skip-permissions', '-p', '-'];
195
- if (verbose) {
218
+ if (useStreamJson) {
196
219
  claudeArgs.push('--verbose', '--output-format', 'stream-json');
197
220
  }
198
221
 
@@ -210,16 +233,17 @@ export const createClaudeService = ({ verbose = false, log: logFn }) => {
210
233
  child.stdout.on('data', d => {
211
234
  const chunk = d.toString();
212
235
  stdout += chunk;
213
- if (verbose) {
236
+ if (useStreamJson) {
214
237
  lineBuf += chunk;
215
238
  const lines = lineBuf.split('\n');
216
239
  lineBuf = lines.pop();
217
240
  for (const line of lines) {
218
241
  if (line.trim()) {
219
- formatStreamEvent(line.trim(), tag);
242
+ if (verbose) formatStreamEvent(line.trim(), tag);
220
243
  if (onToolUse) emitToolUseEvents(line.trim(), onToolUse);
221
244
  if (onResult) emitResultEvent(line.trim(), onResult);
222
245
  if (onTurnUsage) emitAssistantUsage(line.trim(), onTurnUsage);
246
+ if (onAssistantText) emitAssistantTextEvents(line.trim(), onAssistantText);
223
247
  }
224
248
  }
225
249
  }
@@ -240,14 +264,15 @@ export const createClaudeService = ({ verbose = false, log: logFn }) => {
240
264
  logFn('CLAUDE', `Prompt written to stdin, waiting for ${label} to complete...`);
241
265
 
242
266
  child.on('close', code => {
243
- if (verbose && lineBuf.trim()) {
244
- formatStreamEvent(lineBuf.trim(), tag);
267
+ if (useStreamJson && lineBuf.trim()) {
268
+ if (verbose) formatStreamEvent(lineBuf.trim(), tag);
245
269
  if (onToolUse) emitToolUseEvents(lineBuf.trim(), onToolUse);
246
270
  if (onResult) emitResultEvent(lineBuf.trim(), onResult);
271
+ if (onAssistantText) emitAssistantTextEvents(lineBuf.trim(), onAssistantText);
247
272
  if (onTurnUsage) emitAssistantUsage(lineBuf.trim(), onTurnUsage);
248
273
  }
249
274
  if (code === 0) {
250
- const result = verbose ? extractResultText(stdout) : stdout;
275
+ const result = useStreamJson ? extractResultText(stdout) : stdout;
251
276
  logFn('CLAUDE', `${label} OK — result length: ${result.length} chars`);
252
277
  resolve(result);
253
278
  } else {
@@ -7,6 +7,7 @@
7
7
  // All valid node types with their ID prefixes
8
8
  export const NODE_TYPES = {
9
9
  feature: 'feat',
10
+ epic: 'epic',
10
11
  component: 'comp',
11
12
  data_entity: 'data',
12
13
  decision: 'dec',
@@ -23,6 +24,7 @@ export const NODE_TYPES = {
23
24
  // Required sections per node type — completeness scoring checks these
24
25
  export const REQUIRED_SECTIONS = {
25
26
  feature: ['Description', 'Acceptance Criteria', 'Open Questions'],
27
+ epic: ['Description', 'Scope'],
26
28
  component: ['Description', 'Responsibilities', 'Tech', 'Exposes', 'Consumes'],
27
29
  data_entity: ['Description', 'Fields', 'Used By'],
28
30
  decision: ['Description', 'Rationale', 'Alternatives Considered', 'Affects'],
@@ -94,6 +96,13 @@ export const SCORING_RULES = {
94
96
  check: (fm, _sections) => fm.status === 'defined',
95
97
  },
96
98
  ],
99
+ epic: [
100
+ {
101
+ weight: 1.0,
102
+ description: 'Epics always have full completeness',
103
+ check: () => true,
104
+ },
105
+ ],
97
106
  component: [
98
107
  {
99
108
  weight: 0.2,
@@ -26,10 +26,18 @@ export class GitWorkflow {
26
26
  this.log('DEVELOP', `Creating worktree at ${worktreePath} (branch: feature/${featureId})`);
27
27
  this.log('DEVELOP', `PROJECT_ROOT=${this.projectRoot}`);
28
28
 
29
- // Remove leftover worktree from a previous failed/aborted pipeline
30
- await this.claudeService.spawnCommand('git', ['worktree', 'remove', '--force', worktreePath], this.projectRoot).catch(() => {});
31
- // Delete leftover branch
32
- await this.claudeService.spawnCommand('git', ['branch', '-D', `feature/${featureId}`], this.projectRoot).catch(() => {});
29
+ // Remove leftover worktree from a previous failed/aborted pipeline (only if it exists)
30
+ const worktreeList = await this.claudeService.spawnCommand('git', ['worktree', 'list', '--porcelain'], this.projectRoot);
31
+ if (worktreeList.includes(worktreePath)) {
32
+ this.log('DEVELOP', `Removing leftover worktree at ${worktreePath}`);
33
+ await this.claudeService.spawnCommand('git', ['worktree', 'remove', '--force', worktreePath], this.projectRoot).catch(() => {});
34
+ }
35
+ // Delete leftover branch (only if it exists)
36
+ const branchList = await this.claudeService.spawnCommand('git', ['branch', '--list', `feature/${featureId}`], this.projectRoot);
37
+ if (branchList.trim()) {
38
+ this.log('DEVELOP', `Deleting leftover branch feature/${featureId}`);
39
+ await this.claudeService.spawnCommand('git', ['branch', '-D', `feature/${featureId}`], this.projectRoot).catch(() => {});
40
+ }
33
41
 
34
42
  await this.claudeService.spawnCommand('git', ['worktree', 'add', worktreePath, '-b', `feature/${featureId}`], this.projectRoot);
35
43
  this.log('DEVELOP', `Worktree created successfully`);
@@ -6,7 +6,7 @@
6
6
 
7
7
  import { eq, and } from 'drizzle-orm';
8
8
  import { getDb, getProjectRoot as _getProjectRoot } from './db.js';
9
- import { nodes, edges } from '../db/schema.js';
9
+ import { nodes, edges, projects } from '../db/schema.js';
10
10
 
11
11
  export { getProjectRoot } from './db.js';
12
12
 
@@ -26,13 +26,20 @@ export const readGraph = async (projectId?: string) => {
26
26
  ? (() => { const ids = new Set(allNodes.map(n => n.id)); return allEdges.filter(e => ids.has(e.fromId) && ids.has(e.toId)); })()
27
27
  : allEdges;
28
28
 
29
+ let projectRow;
30
+ if (projectId) {
31
+ const rows = await db.select().from(projects).where(eq(projects.id, projectId));
32
+ projectRow = rows[0];
33
+ }
34
+
29
35
  return {
30
36
  version: '1.0',
31
37
  project: {
32
- name: '',
38
+ name: projectRow?.name || '',
39
+ type: projectRow?.type || 'software',
33
40
  description: '',
34
- created_at: '',
35
- updated_at: '',
41
+ created_at: projectRow?.createdAt || '',
42
+ updated_at: projectRow?.updatedAt || '',
36
43
  },
37
44
  nodes: allNodes.map(n => ({
38
45
  id: n.id,
@@ -42,6 +49,7 @@ export const readGraph = async (projectId?: string) => {
42
49
  completeness: n.completeness,
43
50
  open_questions_count: n.openQuestionsCount,
44
51
  ...(n.kind ? { kind: n.kind } : {}),
52
+ ...(n.featureType ? { feature_type: n.featureType } : {}),
45
53
  created_at: n.createdAt,
46
54
  updated_at: n.updatedAt,
47
55
  })),
@@ -76,6 +84,7 @@ export const writeGraph = async (graph, projectId?: string) => {
76
84
  completeness: n.completeness,
77
85
  openQuestionsCount: n.open_questions_count,
78
86
  kind: n.kind || null,
87
+ featureType: n.feature_type || null,
79
88
  createdAt: n.created_at,
80
89
  updatedAt: n.updated_at,
81
90
  body: n.body || null,
@@ -107,11 +116,12 @@ export const patchNode = async (id, fields) => {
107
116
  throw new Error(`Node not found in graph: ${id}`);
108
117
  }
109
118
 
110
- const updates = {};
119
+ const updates: Record<string, unknown> = {};
111
120
  if (fields.status !== undefined) updates.status = fields.status;
112
121
  if (fields.completeness !== undefined) updates.completeness = fields.completeness;
113
122
  if (fields.open_questions_count !== undefined) updates.openQuestionsCount = fields.open_questions_count;
114
123
  if (fields.kind !== undefined) updates.kind = fields.kind;
124
+ if (fields.feature_type !== undefined) updates.featureType = fields.feature_type;
115
125
  if (fields.name !== undefined) updates.name = fields.name;
116
126
  if (fields.priority !== undefined) updates.priority = fields.priority;
117
127
  if (fields.body !== undefined) updates.body = fields.body;
@@ -179,6 +189,7 @@ export const getNode = async (id) => {
179
189
  completeness: row.completeness,
180
190
  open_questions_count: row.openQuestionsCount,
181
191
  ...(row.kind ? { kind: row.kind } : {}),
192
+ ...(row.featureType ? { feature_type: row.featureType } : {}),
182
193
  created_at: row.createdAt,
183
194
  updated_at: row.updatedAt,
184
195
  project_id: row.projectId,