@assistkick/create 1.0.1 → 1.3.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 (194) hide show
  1. package/dist/src/scaffolder.d.ts +6 -1
  2. package/dist/src/scaffolder.js +20 -9
  3. package/dist/src/scaffolder.js.map +1 -1
  4. package/package.json +3 -2
  5. package/templates/{product-system → assistkick-product-system}/CLAUDE.md +4 -4
  6. package/templates/{product-system → assistkick-product-system}/package.json +5 -5
  7. package/templates/{product-system → assistkick-product-system}/packages/backend/package.json +2 -2
  8. package/templates/{product-system → assistkick-product-system}/packages/backend/src/routes/auth.ts +1 -1
  9. package/templates/{product-system → assistkick-product-system}/packages/backend/src/routes/coherence.ts +1 -1
  10. package/templates/assistkick-product-system/packages/backend/src/routes/git.ts +231 -0
  11. package/templates/{product-system → assistkick-product-system}/packages/backend/src/routes/graph.ts +3 -3
  12. package/templates/{product-system → assistkick-product-system}/packages/backend/src/routes/kanban.ts +6 -6
  13. package/templates/assistkick-product-system/packages/backend/src/routes/pipeline.ts +88 -0
  14. package/templates/assistkick-product-system/packages/backend/src/routes/terminal.ts +82 -0
  15. package/templates/{product-system → assistkick-product-system}/packages/backend/src/server.ts +23 -10
  16. package/templates/{product-system → assistkick-product-system}/packages/backend/src/services/coherence-review.ts +4 -4
  17. package/templates/assistkick-product-system/packages/backend/src/services/github_app_service.ts +146 -0
  18. package/templates/assistkick-product-system/packages/backend/src/services/init.ts +147 -0
  19. package/templates/{product-system → assistkick-product-system}/packages/backend/src/services/invitation_service.ts +1 -1
  20. package/templates/{product-system → assistkick-product-system}/packages/backend/src/services/password_reset_service.ts +1 -1
  21. package/templates/{product-system → assistkick-product-system}/packages/backend/src/services/project_service.ts +72 -1
  22. package/templates/assistkick-product-system/packages/backend/src/services/project_workspace_service.test.ts +87 -0
  23. package/templates/assistkick-product-system/packages/backend/src/services/project_workspace_service.ts +194 -0
  24. package/templates/assistkick-product-system/packages/backend/src/services/pty_session_manager.test.ts +159 -0
  25. package/templates/{product-system → assistkick-product-system}/packages/backend/src/services/pty_session_manager.ts +114 -39
  26. package/templates/{product-system → assistkick-product-system}/packages/backend/src/services/terminal_ws_handler.ts +28 -14
  27. package/templates/{product-system → assistkick-product-system}/packages/backend/src/services/user_management_service.ts +1 -1
  28. package/templates/{product-system → assistkick-product-system}/packages/frontend/package.json +1 -1
  29. package/templates/{product-system → assistkick-product-system}/packages/frontend/src/App.tsx +1 -1
  30. package/templates/{product-system → assistkick-product-system}/packages/frontend/src/api/client.ts +151 -0
  31. package/templates/assistkick-product-system/packages/frontend/src/components/GitRepoModal.tsx +352 -0
  32. package/templates/{product-system → assistkick-product-system}/packages/frontend/src/components/KanbanView.tsx +208 -95
  33. package/templates/{product-system → assistkick-product-system}/packages/frontend/src/components/ProjectSelector.tsx +17 -1
  34. package/templates/assistkick-product-system/packages/frontend/src/components/TerminalView.tsx +333 -0
  35. package/templates/{product-system → assistkick-product-system}/packages/frontend/src/components/Toolbar.tsx +15 -13
  36. package/templates/{product-system → assistkick-product-system}/packages/frontend/src/constants/graph.ts +1 -0
  37. package/templates/{product-system → assistkick-product-system}/packages/frontend/src/hooks/useProjects.ts +4 -0
  38. package/templates/{product-system → assistkick-product-system}/packages/frontend/src/routes/dashboard.tsx +22 -4
  39. package/templates/{product-system → assistkick-product-system}/packages/frontend/src/styles/index.css +486 -38
  40. package/templates/assistkick-product-system/packages/frontend/vite.config.ts +31 -0
  41. package/templates/assistkick-product-system/packages/shared/db/migrations/0001_vengeful_wallop.sql +1 -0
  42. package/templates/assistkick-product-system/packages/shared/db/migrations/0002_greedy_excalibur.sql +4 -0
  43. package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0001_snapshot.json +826 -0
  44. package/templates/assistkick-product-system/packages/shared/db/migrations/meta/0002_snapshot.json +854 -0
  45. package/templates/assistkick-product-system/packages/shared/db/migrations/meta/_journal.json +27 -0
  46. package/templates/{product-system → assistkick-product-system}/packages/shared/db/schema.ts +5 -0
  47. package/templates/{product-system → assistkick-product-system}/packages/shared/lib/claude-service.ts +54 -1
  48. package/templates/{product-system → assistkick-product-system}/packages/shared/lib/db.ts +1 -1
  49. package/templates/{product-system → assistkick-product-system}/packages/shared/lib/git_workflow.ts +25 -0
  50. package/templates/{product-system → assistkick-product-system}/packages/shared/lib/pipeline-state-store.ts +4 -0
  51. package/templates/{product-system → assistkick-product-system}/packages/shared/lib/pipeline.ts +329 -89
  52. package/templates/assistkick-product-system/packages/shared/lib/pipeline_orchestrator.ts +186 -0
  53. package/templates/{product-system → assistkick-product-system}/packages/shared/lib/prompt_builder.ts +2 -2
  54. package/templates/{product-system → assistkick-product-system}/packages/shared/package.json +1 -1
  55. package/templates/assistkick-product-system/packages/shared/tools/db_explorer.ts +275 -0
  56. package/templates/{product-system → assistkick-product-system}/packages/shared/tools/get_kanban.ts +2 -1
  57. package/templates/{product-system → assistkick-product-system}/packages/shared/tools/move_card.ts +3 -2
  58. package/templates/{product-system → assistkick-product-system}/packages/shared/tools/update_node.ts +2 -2
  59. package/templates/{product-system → assistkick-product-system}/tests/db_sqlite_fallback.test.ts +1 -1
  60. package/templates/{product-system → assistkick-product-system}/tests/kanban.test.ts +1 -1
  61. package/templates/{product-system → assistkick-product-system}/tests/pipeline_stats_all_cards.test.ts +1 -1
  62. package/templates/{product-system → assistkick-product-system}/tests/web_terminal.test.ts +189 -150
  63. package/templates/skills/{product-bootstrap → assistkick-bootstrap}/SKILL.md +36 -28
  64. package/templates/skills/{product-code-reviewer → assistkick-code-reviewer}/SKILL.md +26 -18
  65. package/templates/skills/assistkick-db-explorer/SKILL.md +86 -0
  66. package/templates/skills/{product-debugger → assistkick-debugger}/SKILL.md +35 -27
  67. package/templates/skills/{product-developer → assistkick-developer}/SKILL.md +40 -32
  68. package/templates/skills/{product-interview → assistkick-interview}/SKILL.md +37 -29
  69. package/templates/product-system/packages/backend/src/routes/pipeline.ts +0 -41
  70. package/templates/product-system/packages/backend/src/services/init.ts +0 -80
  71. package/templates/product-system/packages/backend/src/services/pty_session_manager.test.ts +0 -88
  72. package/templates/product-system/packages/frontend/src/components/TerminalView.tsx +0 -200
  73. package/templates/product-system/packages/frontend/vite.config.ts +0 -20
  74. package/templates/product-system/packages/shared/db/migrations/meta/_journal.json +0 -13
  75. /package/templates/{product-system → assistkick-product-system}/.env.example +0 -0
  76. /package/templates/{product-system → assistkick-product-system}/packages/backend/src/middleware/auth_middleware.test.ts +0 -0
  77. /package/templates/{product-system → assistkick-product-system}/packages/backend/src/middleware/auth_middleware.ts +0 -0
  78. /package/templates/{product-system → assistkick-product-system}/packages/backend/src/routes/projects.ts +0 -0
  79. /package/templates/{product-system → assistkick-product-system}/packages/backend/src/routes/users.ts +0 -0
  80. /package/templates/{product-system → assistkick-product-system}/packages/backend/src/services/auth_service.test.ts +0 -0
  81. /package/templates/{product-system → assistkick-product-system}/packages/backend/src/services/auth_service.ts +0 -0
  82. /package/templates/{product-system → assistkick-product-system}/packages/backend/src/services/email_service.ts +0 -0
  83. /package/templates/{product-system → assistkick-product-system}/packages/backend/src/services/invitation_service.test.ts +0 -0
  84. /package/templates/{product-system → assistkick-product-system}/packages/backend/src/services/password_reset_service.test.ts +0 -0
  85. /package/templates/{product-system → assistkick-product-system}/packages/backend/src/services/project_service.test.ts +0 -0
  86. /package/templates/{product-system → assistkick-product-system}/packages/backend/src/services/user_management_service.test.ts +0 -0
  87. /package/templates/{product-system → assistkick-product-system}/packages/backend/tsconfig.json +0 -0
  88. /package/templates/{product-system → assistkick-product-system}/packages/frontend/index.html +0 -0
  89. /package/templates/{product-system → assistkick-product-system}/packages/frontend/package-lock.json +0 -0
  90. /package/templates/{product-system → assistkick-product-system}/packages/frontend/public/favicon.svg +0 -0
  91. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/api/client_projects.test.ts +0 -0
  92. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/api/client_refresh.test.ts +0 -0
  93. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/components/CoherenceView.tsx +0 -0
  94. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/components/GraphLegend.tsx +0 -0
  95. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/components/GraphSettings.tsx +0 -0
  96. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/components/GraphView.tsx +0 -0
  97. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/components/InviteUserDialog.tsx +0 -0
  98. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/components/LoginPage.tsx +0 -0
  99. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/components/QaIssueSheet.tsx +0 -0
  100. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/components/SidePanel.tsx +0 -0
  101. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/components/UsersView.tsx +0 -0
  102. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/hooks/useAuth.tsx +0 -0
  103. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/hooks/useGraph.ts +0 -0
  104. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/hooks/useKanban.ts +0 -0
  105. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/hooks/useTheme.ts +0 -0
  106. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/hooks/useToast.tsx +0 -0
  107. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/hooks/use_projects_logic.test.ts +0 -0
  108. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/main.tsx +0 -0
  109. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/pages/accept_invitation_page.tsx +0 -0
  110. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/pages/forgot_password_page.tsx +0 -0
  111. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/pages/register_page.tsx +0 -0
  112. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/pages/reset_password_page.tsx +0 -0
  113. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/routes/ProtectedRoute.tsx +0 -0
  114. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/routes/accept_invitation.tsx +0 -0
  115. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/routes/forgot_password.tsx +0 -0
  116. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/routes/login.tsx +0 -0
  117. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/routes/register.tsx +0 -0
  118. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/routes/reset_password.tsx +0 -0
  119. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/utils/auth_validation.test.ts +0 -0
  120. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/utils/auth_validation.ts +0 -0
  121. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/utils/login_validation.test.ts +0 -0
  122. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/utils/login_validation.ts +0 -0
  123. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/utils/logout.test.ts +0 -0
  124. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/utils/node_sizing.test.ts +0 -0
  125. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/utils/node_sizing.ts +0 -0
  126. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/utils/task_status.test.ts +0 -0
  127. /package/templates/{product-system → assistkick-product-system}/packages/frontend/src/utils/task_status.ts +0 -0
  128. /package/templates/{product-system → assistkick-product-system}/packages/frontend/tsconfig.json +0 -0
  129. /package/templates/{product-system → assistkick-product-system}/packages/shared/.env.example +0 -0
  130. /package/templates/{product-system → assistkick-product-system}/packages/shared/README.md +0 -0
  131. /package/templates/{product-system → assistkick-product-system}/packages/shared/db/migrate.ts +0 -0
  132. /package/templates/{product-system → assistkick-product-system}/packages/shared/db/migrations/0000_dashing_gorgon.sql +0 -0
  133. /package/templates/{product-system → assistkick-product-system}/packages/shared/db/migrations/meta/0000_snapshot.json +0 -0
  134. /package/templates/{product-system → assistkick-product-system}/packages/shared/drizzle.config.js +0 -0
  135. /package/templates/{product-system → assistkick-product-system}/packages/shared/lib/coherence.ts +0 -0
  136. /package/templates/{product-system → assistkick-product-system}/packages/shared/lib/completeness.ts +0 -0
  137. /package/templates/{product-system → assistkick-product-system}/packages/shared/lib/constants.ts +0 -0
  138. /package/templates/{product-system → assistkick-product-system}/packages/shared/lib/graph.ts +0 -0
  139. /package/templates/{product-system → assistkick-product-system}/packages/shared/lib/kanban.ts +0 -0
  140. /package/templates/{product-system → assistkick-product-system}/packages/shared/lib/markdown.ts +0 -0
  141. /package/templates/{product-system → assistkick-product-system}/packages/shared/lib/relevance_search.ts +0 -0
  142. /package/templates/{product-system → assistkick-product-system}/packages/shared/lib/session.ts +0 -0
  143. /package/templates/{product-system → assistkick-product-system}/packages/shared/lib/validator.ts +0 -0
  144. /package/templates/{product-system → assistkick-product-system}/packages/shared/lib/work_summary_parser.ts +0 -0
  145. /package/templates/{product-system → assistkick-product-system}/packages/shared/scripts/assign-project.ts +0 -0
  146. /package/templates/{product-system → assistkick-product-system}/packages/shared/tools/add_edge.ts +0 -0
  147. /package/templates/{product-system → assistkick-product-system}/packages/shared/tools/add_node.ts +0 -0
  148. /package/templates/{product-system → assistkick-product-system}/packages/shared/tools/end_session.ts +0 -0
  149. /package/templates/{product-system → assistkick-product-system}/packages/shared/tools/get_gaps.ts +0 -0
  150. /package/templates/{product-system → assistkick-product-system}/packages/shared/tools/get_node.ts +0 -0
  151. /package/templates/{product-system → assistkick-product-system}/packages/shared/tools/get_status.ts +0 -0
  152. /package/templates/{product-system → assistkick-product-system}/packages/shared/tools/migrate_to_turso.ts +0 -0
  153. /package/templates/{product-system → assistkick-product-system}/packages/shared/tools/rebuild_index.ts +0 -0
  154. /package/templates/{product-system → assistkick-product-system}/packages/shared/tools/remove_edge.ts +0 -0
  155. /package/templates/{product-system → assistkick-product-system}/packages/shared/tools/remove_node.ts +0 -0
  156. /package/templates/{product-system → assistkick-product-system}/packages/shared/tools/resolve_question.ts +0 -0
  157. /package/templates/{product-system → assistkick-product-system}/packages/shared/tools/search_nodes.ts +0 -0
  158. /package/templates/{product-system → assistkick-product-system}/packages/shared/tools/start_session.ts +0 -0
  159. /package/templates/{product-system → assistkick-product-system}/packages/shared/tsconfig.json +0 -0
  160. /package/templates/{product-system → assistkick-product-system}/pnpm-workspace.yaml +0 -0
  161. /package/templates/{product-system → assistkick-product-system}/smoke_test.ts +0 -0
  162. /package/templates/{product-system → assistkick-product-system}/tests/coherence_review.test.ts +0 -0
  163. /package/templates/{product-system → assistkick-product-system}/tests/edge_type_color_coding.test.ts +0 -0
  164. /package/templates/{product-system → assistkick-product-system}/tests/emit-tool-use-events.test.ts +0 -0
  165. /package/templates/{product-system → assistkick-product-system}/tests/feature_kind.test.ts +0 -0
  166. /package/templates/{product-system → assistkick-product-system}/tests/gap_indicators.test.ts +0 -0
  167. /package/templates/{product-system → assistkick-product-system}/tests/graceful_init.test.ts +0 -0
  168. /package/templates/{product-system → assistkick-product-system}/tests/graph_legend.test.ts +0 -0
  169. /package/templates/{product-system → assistkick-product-system}/tests/graph_settings_sheet.test.ts +0 -0
  170. /package/templates/{product-system → assistkick-product-system}/tests/hide_defined_filter.test.ts +0 -0
  171. /package/templates/{product-system → assistkick-product-system}/tests/neighborhood_focus.test.ts +0 -0
  172. /package/templates/{product-system → assistkick-product-system}/tests/node_search.test.ts +0 -0
  173. /package/templates/{product-system → assistkick-product-system}/tests/node_sizing.test.ts +0 -0
  174. /package/templates/{product-system → assistkick-product-system}/tests/node_type_toggle_filters.test.ts +0 -0
  175. /package/templates/{product-system → assistkick-product-system}/tests/node_type_visual_encoding.test.ts +0 -0
  176. /package/templates/{product-system → assistkick-product-system}/tests/pipeline-state-store.test.ts +0 -0
  177. /package/templates/{product-system → assistkick-product-system}/tests/pipeline-unit.test.ts +0 -0
  178. /package/templates/{product-system → assistkick-product-system}/tests/pipeline.test.ts +0 -0
  179. /package/templates/{product-system → assistkick-product-system}/tests/play_all.test.ts +0 -0
  180. /package/templates/{product-system → assistkick-product-system}/tests/qa_issue_sheet.test.ts +0 -0
  181. /package/templates/{product-system → assistkick-product-system}/tests/relevance_search.test.ts +0 -0
  182. /package/templates/{product-system → assistkick-product-system}/tests/search_reorder.test.ts +0 -0
  183. /package/templates/{product-system → assistkick-product-system}/tests/serve_ui.test.ts +0 -0
  184. /package/templates/{product-system → assistkick-product-system}/tests/serve_ui_drizzle.test.ts +0 -0
  185. /package/templates/{product-system → assistkick-product-system}/tests/session_context_recall.test.ts +0 -0
  186. /package/templates/{product-system → assistkick-product-system}/tests/side_panel.test.ts +0 -0
  187. /package/templates/{product-system → assistkick-product-system}/tests/spec_completeness_label.test.ts +0 -0
  188. /package/templates/{product-system → assistkick-product-system}/tests/url_routing_test.ts +0 -0
  189. /package/templates/{product-system → assistkick-product-system}/tests/user_login.test.ts +0 -0
  190. /package/templates/{product-system → assistkick-product-system}/tests/user_registration.test.ts +0 -0
  191. /package/templates/{product-system → assistkick-product-system}/tests/work_summary.test.ts +0 -0
  192. /package/templates/{product-system → assistkick-product-system}/tests/zoom_pan.test.ts +0 -0
  193. /package/templates/{product-system → assistkick-product-system}/tsconfig.json +0 -0
  194. /package/templates/skills/{product-debugger → assistkick-debugger}/references/agent-browser.md +0 -0
@@ -0,0 +1,27 @@
1
+ {
2
+ "version": "7",
3
+ "dialect": "sqlite",
4
+ "entries": [
5
+ {
6
+ "idx": 0,
7
+ "version": "6",
8
+ "when": 1772730355833,
9
+ "tag": "0000_dashing_gorgon",
10
+ "breakpoints": true
11
+ },
12
+ {
13
+ "idx": 1,
14
+ "version": "6",
15
+ "when": 1772802625250,
16
+ "tag": "0001_vengeful_wallop",
17
+ "breakpoints": true
18
+ },
19
+ {
20
+ "idx": 2,
21
+ "version": "6",
22
+ "when": 1772807644324,
23
+ "tag": "0002_greedy_excalibur",
24
+ "breakpoints": true
25
+ }
26
+ ]
27
+ }
@@ -119,6 +119,10 @@ export const projects = sqliteTable('projects', {
119
119
  name: text('name').notNull(),
120
120
  isDefault: integer('is_default').notNull().default(0),
121
121
  archivedAt: text('archived_at'),
122
+ repoUrl: text('repo_url'),
123
+ githubInstallationId: text('github_installation_id'),
124
+ githubRepoFullName: text('github_repo_full_name'),
125
+ baseBranch: text('base_branch'),
122
126
  createdAt: text('created_at').notNull(),
123
127
  updatedAt: text('updated_at').notNull(),
124
128
  });
@@ -131,6 +135,7 @@ export const pipelineState = sqliteTable('pipeline_state', {
131
135
  tasksJson: text('tasks_json'),
132
136
  toolCallsJson: text('tool_calls_json'),
133
137
  workSummariesJson: text('work_summaries_json'),
138
+ stageStatsJson: text('stage_stats_json'),
134
139
  error: text('error'),
135
140
  updatedAt: text('updated_at').notNull(),
136
141
  projectId: text('project_id'),
@@ -131,13 +131,62 @@ export const emitToolUseEvents = (jsonStr, callback) => {
131
131
  }
132
132
  };
133
133
 
134
+ /**
135
+ * Extract result event metadata from a stream-json line and invoke a callback.
136
+ * Fires once when the result event is encountered, providing usage stats.
137
+ */
138
+ export const emitResultEvent = (jsonStr, callback) => {
139
+ try {
140
+ const event = JSON.parse(jsonStr);
141
+ if (event.type === 'result') {
142
+ const model = event.model
143
+ ?? (event.modelUsage ? Object.keys(event.modelUsage)[0] : null);
144
+ // Extract contextWindow from modelUsage (e.g. modelUsage["claude-..."].contextWindow)
145
+ let contextWindow: number | null = null;
146
+ if (event.modelUsage) {
147
+ const modelKey = model ?? Object.keys(event.modelUsage)[0];
148
+ if (modelKey && event.modelUsage[modelKey]?.contextWindow) {
149
+ contextWindow = event.modelUsage[modelKey].contextWindow;
150
+ }
151
+ }
152
+ callback({
153
+ costUsd: event.cost_usd ?? event.total_cost_usd ?? null,
154
+ durationMs: event.duration_ms ?? null,
155
+ numTurns: event.num_turns ?? null,
156
+ stopReason: event.stop_reason ?? null,
157
+ usage: event.usage ?? null,
158
+ model: model ?? null,
159
+ contextWindow,
160
+ });
161
+ }
162
+ } catch {
163
+ // Not valid JSON — skip silently
164
+ }
165
+ };
166
+
167
+ /**
168
+ * Extract per-turn usage from an assistant event's message.usage and invoke a callback.
169
+ * Each assistant event contains usage for THAT turn only. The callback is called
170
+ * for every assistant event, so the last call represents the final turn's usage.
171
+ */
172
+ export const emitAssistantUsage = (jsonStr, callback) => {
173
+ try {
174
+ const event = JSON.parse(jsonStr);
175
+ if (event.type === 'assistant' && event.message?.usage) {
176
+ callback(event.message.usage);
177
+ }
178
+ } catch {
179
+ // Not valid JSON — skip silently
180
+ }
181
+ };
182
+
134
183
  /**
135
184
  * Create a Claude CLI invocation service.
136
185
  * @param {{ verbose: boolean, log: function }} opts
137
186
  * @returns {{ spawnClaude: function, spawnCommand: function }}
138
187
  */
139
188
  export const createClaudeService = ({ verbose = false, log: logFn }) => {
140
- const spawnClaude = (prompt, cwd, label = 'claude', { onToolUse } = {}) => new Promise((resolve, reject) => {
189
+ const spawnClaude = (prompt, cwd, label = 'claude', { onToolUse, onResult, onTurnUsage } = {}) => new Promise((resolve, reject) => {
141
190
  const promptPreview = prompt.slice(0, 100).replace(/\n/g, '\\n');
142
191
  logFn('CLAUDE', `Spawning ${label} in ${cwd} — prompt length: ${prompt.length} chars`);
143
192
  logFn('CLAUDE', `Prompt preview: "${promptPreview}..."`);
@@ -169,6 +218,8 @@ export const createClaudeService = ({ verbose = false, log: logFn }) => {
169
218
  if (line.trim()) {
170
219
  formatStreamEvent(line.trim(), tag);
171
220
  if (onToolUse) emitToolUseEvents(line.trim(), onToolUse);
221
+ if (onResult) emitResultEvent(line.trim(), onResult);
222
+ if (onTurnUsage) emitAssistantUsage(line.trim(), onTurnUsage);
172
223
  }
173
224
  }
174
225
  }
@@ -192,6 +243,8 @@ export const createClaudeService = ({ verbose = false, log: logFn }) => {
192
243
  if (verbose && lineBuf.trim()) {
193
244
  formatStreamEvent(lineBuf.trim(), tag);
194
245
  if (onToolUse) emitToolUseEvents(lineBuf.trim(), onToolUse);
246
+ if (onResult) emitResultEvent(lineBuf.trim(), onResult);
247
+ if (onTurnUsage) emitAssistantUsage(lineBuf.trim(), onTurnUsage);
195
248
  }
196
249
  if (code === 0) {
197
250
  const result = verbose ? extractResultText(stdout) : stdout;
@@ -14,7 +14,7 @@ import { existsSync, mkdirSync } from 'node:fs';
14
14
  import * as schema from '../db/schema.js';
15
15
 
16
16
  const __dirname = dirname(fileURLToPath(import.meta.url));
17
- // Walk up from packages/shared/lib/ (or build/lib/) to find product-system/
17
+ // Walk up from packages/shared/lib/ (or build/lib/) to find assistkick-product-system/
18
18
  let PROJECT_ROOT = join(__dirname, '..');
19
19
  while (PROJECT_ROOT !== dirname(PROJECT_ROOT)) {
20
20
  if (existsSync(join(PROJECT_ROOT, 'pnpm-workspace.yaml'))) break;
@@ -107,4 +107,29 @@ export class GitWorkflow {
107
107
  await this.claudeService.spawnCommand('git', ['stash', 'pop'], this.projectRoot);
108
108
  this.log('PIPELINE', `Restored stashed local changes`);
109
109
  };
110
+
111
+ /** Pull the default branch before creating a worktree to ensure up-to-date base. */
112
+ pullDefaultBranch = async (branch?: string) => {
113
+ const targetBranch = branch || 'main';
114
+ this.log('PIPELINE', `Pulling ${targetBranch} to ensure up-to-date base...`);
115
+ try {
116
+ await this.claudeService.spawnCommand('git', ['pull', 'origin', targetBranch], this.projectRoot);
117
+ this.log('PIPELINE', `Pull succeeded for ${targetBranch}`);
118
+ } catch (err: any) {
119
+ this.log('PIPELINE', `Pull failed (non-fatal): ${err.message}`);
120
+ }
121
+ };
122
+
123
+ /** Push the current branch to the remote after a successful merge. */
124
+ pushToRemote = async (branch?: string) => {
125
+ const targetBranch = branch || 'main';
126
+ this.log('PIPELINE', `Pushing ${targetBranch} to remote...`);
127
+ await this.claudeService.spawnCommand('git', ['push', 'origin', targetBranch], this.projectRoot);
128
+ this.log('PIPELINE', `Push succeeded for ${targetBranch}`);
129
+ };
130
+
131
+ /** Set the remote URL (used for authenticated push/pull with tokens). */
132
+ setRemoteUrl = async (url: string, remote = 'origin') => {
133
+ await this.claudeService.spawnCommand('git', ['remote', 'set-url', remote, url], this.projectRoot);
134
+ };
110
135
  }
@@ -25,6 +25,7 @@ export class PipelineStateStore {
25
25
  tasksJson: state.tasks ? JSON.stringify(state.tasks.items || []) : null,
26
26
  toolCallsJson: state.toolCalls ? JSON.stringify(state.toolCalls) : null,
27
27
  workSummariesJson: state.workSummaries ? JSON.stringify(state.workSummaries) : null,
28
+ stageStatsJson: state.stageStats ? JSON.stringify(state.stageStats) : null,
28
29
  error: state.error || null,
29
30
  updatedAt: new Date().toISOString(),
30
31
  projectId: projectId || null,
@@ -40,6 +41,7 @@ export class PipelineStateStore {
40
41
  tasksJson: row.tasksJson,
41
42
  toolCallsJson: row.toolCallsJson,
42
43
  workSummariesJson: row.workSummariesJson,
44
+ stageStatsJson: row.stageStatsJson,
43
45
  error: row.error,
44
46
  updatedAt: row.updatedAt,
45
47
  projectId: row.projectId,
@@ -62,6 +64,7 @@ export class PipelineStateStore {
62
64
  const tasks = row.tasksJson ? JSON.parse(row.tasksJson) : [];
63
65
  const toolCalls = row.toolCallsJson ? JSON.parse(row.toolCallsJson) : null;
64
66
  const rawSummaries = row.workSummariesJson ? JSON.parse(row.workSummariesJson) : [];
67
+ const stageStats = row.stageStatsJson ? JSON.parse(row.stageStatsJson) : null;
65
68
 
66
69
  // Migrate old flat filesChanged format to categorized format
67
70
  const workSummaries = rawSummaries.map((ws) => {
@@ -89,6 +92,7 @@ export class PipelineStateStore {
89
92
  } : undefined,
90
93
  toolCalls: toolCalls && toolCalls.total > 0 ? toolCalls : undefined,
91
94
  workSummaries: workSummaries.length > 0 ? workSummaries : undefined,
95
+ stageStats: stageStats || undefined,
92
96
  updatedAt: row.updatedAt,
93
97
  };
94
98
  };