clitrigger 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 (201) hide show
  1. package/.env.example +9 -0
  2. package/LICENSE +21 -0
  3. package/README.md +186 -0
  4. package/bin/clitrigger.js +106 -0
  5. package/dist/client/assets/index-BkOCv65b.css +1 -0
  6. package/dist/client/assets/index-Fbf16Lh1.js +129 -0
  7. package/dist/client/index.html +24 -0
  8. package/dist/server/db/connection.d.ts +4 -0
  9. package/dist/server/db/connection.d.ts.map +1 -0
  10. package/dist/server/db/connection.js +24 -0
  11. package/dist/server/db/connection.js.map +1 -0
  12. package/dist/server/db/queries.d.ts +265 -0
  13. package/dist/server/db/queries.d.ts.map +1 -0
  14. package/dist/server/db/queries.js +836 -0
  15. package/dist/server/db/queries.js.map +1 -0
  16. package/dist/server/db/schema.d.ts +3 -0
  17. package/dist/server/db/schema.d.ts.map +1 -0
  18. package/dist/server/db/schema.js +325 -0
  19. package/dist/server/db/schema.js.map +1 -0
  20. package/dist/server/index.d.ts +5 -0
  21. package/dist/server/index.d.ts.map +1 -0
  22. package/dist/server/index.js +207 -0
  23. package/dist/server/index.js.map +1 -0
  24. package/dist/server/middleware/auth.d.ts +5 -0
  25. package/dist/server/middleware/auth.d.ts.map +1 -0
  26. package/dist/server/middleware/auth.js +45 -0
  27. package/dist/server/middleware/auth.js.map +1 -0
  28. package/dist/server/plugins/github/index.d.ts +3 -0
  29. package/dist/server/plugins/github/index.d.ts.map +1 -0
  30. package/dist/server/plugins/github/index.js +18 -0
  31. package/dist/server/plugins/github/index.js.map +1 -0
  32. package/dist/server/plugins/github/router.d.ts +4 -0
  33. package/dist/server/plugins/github/router.d.ts.map +1 -0
  34. package/dist/server/plugins/github/router.js +250 -0
  35. package/dist/server/plugins/github/router.js.map +1 -0
  36. package/dist/server/plugins/gstack/index.d.ts +3 -0
  37. package/dist/server/plugins/gstack/index.d.ts.map +1 -0
  38. package/dist/server/plugins/gstack/index.js +36 -0
  39. package/dist/server/plugins/gstack/index.js.map +1 -0
  40. package/dist/server/plugins/jira/index.d.ts +3 -0
  41. package/dist/server/plugins/jira/index.d.ts.map +1 -0
  42. package/dist/server/plugins/jira/index.js +19 -0
  43. package/dist/server/plugins/jira/index.js.map +1 -0
  44. package/dist/server/plugins/jira/router.d.ts +4 -0
  45. package/dist/server/plugins/jira/router.d.ts.map +1 -0
  46. package/dist/server/plugins/jira/router.js +332 -0
  47. package/dist/server/plugins/jira/router.js.map +1 -0
  48. package/dist/server/plugins/notion/index.d.ts +3 -0
  49. package/dist/server/plugins/notion/index.d.ts.map +1 -0
  50. package/dist/server/plugins/notion/index.js +17 -0
  51. package/dist/server/plugins/notion/index.js.map +1 -0
  52. package/dist/server/plugins/notion/router.d.ts +4 -0
  53. package/dist/server/plugins/notion/router.d.ts.map +1 -0
  54. package/dist/server/plugins/notion/router.js +313 -0
  55. package/dist/server/plugins/notion/router.js.map +1 -0
  56. package/dist/server/plugins/registry.d.ts +8 -0
  57. package/dist/server/plugins/registry.d.ts.map +1 -0
  58. package/dist/server/plugins/registry.js +31 -0
  59. package/dist/server/plugins/registry.js.map +1 -0
  60. package/dist/server/plugins/types.d.ts +32 -0
  61. package/dist/server/plugins/types.d.ts.map +1 -0
  62. package/dist/server/plugins/types.js +2 -0
  63. package/dist/server/plugins/types.js.map +1 -0
  64. package/dist/server/resources/gstack-skills/LICENSE +21 -0
  65. package/dist/server/resources/gstack-skills/benchmark/SKILL.md +528 -0
  66. package/dist/server/resources/gstack-skills/careful/SKILL.md +59 -0
  67. package/dist/server/resources/gstack-skills/cso/SKILL.md +898 -0
  68. package/dist/server/resources/gstack-skills/investigate/SKILL.md +474 -0
  69. package/dist/server/resources/gstack-skills/qa/SKILL.md +1055 -0
  70. package/dist/server/resources/gstack-skills/qa-only/SKILL.md +672 -0
  71. package/dist/server/resources/gstack-skills/review/SKILL.md +1044 -0
  72. package/dist/server/resources/gstack-skills/skills-manifest.d.ts +9 -0
  73. package/dist/server/resources/gstack-skills/skills-manifest.d.ts.map +1 -0
  74. package/dist/server/resources/gstack-skills/skills-manifest.js +52 -0
  75. package/dist/server/resources/gstack-skills/skills-manifest.js.map +1 -0
  76. package/dist/server/resources/gstack-skills/skills-manifest.ts +59 -0
  77. package/dist/server/routes/auth.d.ts +3 -0
  78. package/dist/server/routes/auth.d.ts.map +1 -0
  79. package/dist/server/routes/auth.js +70 -0
  80. package/dist/server/routes/auth.js.map +1 -0
  81. package/dist/server/routes/debug-logs.d.ts +3 -0
  82. package/dist/server/routes/debug-logs.d.ts.map +1 -0
  83. package/dist/server/routes/debug-logs.js +43 -0
  84. package/dist/server/routes/debug-logs.js.map +1 -0
  85. package/dist/server/routes/discussions.d.ts +3 -0
  86. package/dist/server/routes/discussions.d.ts.map +1 -0
  87. package/dist/server/routes/discussions.js +544 -0
  88. package/dist/server/routes/discussions.js.map +1 -0
  89. package/dist/server/routes/execution.d.ts +3 -0
  90. package/dist/server/routes/execution.d.ts.map +1 -0
  91. package/dist/server/routes/execution.js +339 -0
  92. package/dist/server/routes/execution.js.map +1 -0
  93. package/dist/server/routes/github.d.ts +3 -0
  94. package/dist/server/routes/github.d.ts.map +1 -0
  95. package/dist/server/routes/github.js +251 -0
  96. package/dist/server/routes/github.js.map +1 -0
  97. package/dist/server/routes/images.d.ts +17 -0
  98. package/dist/server/routes/images.d.ts.map +1 -0
  99. package/dist/server/routes/images.js +152 -0
  100. package/dist/server/routes/images.js.map +1 -0
  101. package/dist/server/routes/jira.d.ts +3 -0
  102. package/dist/server/routes/jira.d.ts.map +1 -0
  103. package/dist/server/routes/jira.js +333 -0
  104. package/dist/server/routes/jira.js.map +1 -0
  105. package/dist/server/routes/logs.d.ts +3 -0
  106. package/dist/server/routes/logs.d.ts.map +1 -0
  107. package/dist/server/routes/logs.js +156 -0
  108. package/dist/server/routes/logs.js.map +1 -0
  109. package/dist/server/routes/models.d.ts +3 -0
  110. package/dist/server/routes/models.d.ts.map +1 -0
  111. package/dist/server/routes/models.js +65 -0
  112. package/dist/server/routes/models.js.map +1 -0
  113. package/dist/server/routes/notion.d.ts +3 -0
  114. package/dist/server/routes/notion.d.ts.map +1 -0
  115. package/dist/server/routes/notion.js +312 -0
  116. package/dist/server/routes/notion.js.map +1 -0
  117. package/dist/server/routes/pipelines.d.ts +3 -0
  118. package/dist/server/routes/pipelines.d.ts.map +1 -0
  119. package/dist/server/routes/pipelines.js +315 -0
  120. package/dist/server/routes/pipelines.js.map +1 -0
  121. package/dist/server/routes/plugins.d.ts +3 -0
  122. package/dist/server/routes/plugins.d.ts.map +1 -0
  123. package/dist/server/routes/plugins.js +71 -0
  124. package/dist/server/routes/plugins.js.map +1 -0
  125. package/dist/server/routes/projects.d.ts +3 -0
  126. package/dist/server/routes/projects.d.ts.map +1 -0
  127. package/dist/server/routes/projects.js +557 -0
  128. package/dist/server/routes/projects.js.map +1 -0
  129. package/dist/server/routes/schedules.d.ts +3 -0
  130. package/dist/server/routes/schedules.d.ts.map +1 -0
  131. package/dist/server/routes/schedules.js +247 -0
  132. package/dist/server/routes/schedules.js.map +1 -0
  133. package/dist/server/routes/todos.d.ts +3 -0
  134. package/dist/server/routes/todos.d.ts.map +1 -0
  135. package/dist/server/routes/todos.js +103 -0
  136. package/dist/server/routes/todos.js.map +1 -0
  137. package/dist/server/routes/tunnel.d.ts +3 -0
  138. package/dist/server/routes/tunnel.d.ts.map +1 -0
  139. package/dist/server/routes/tunnel.js +44 -0
  140. package/dist/server/routes/tunnel.js.map +1 -0
  141. package/dist/server/services/claude-manager.d.ts +42 -0
  142. package/dist/server/services/claude-manager.d.ts.map +1 -0
  143. package/dist/server/services/claude-manager.js +275 -0
  144. package/dist/server/services/claude-manager.js.map +1 -0
  145. package/dist/server/services/cli-adapters.d.ts +35 -0
  146. package/dist/server/services/cli-adapters.d.ts.map +1 -0
  147. package/dist/server/services/cli-adapters.js +139 -0
  148. package/dist/server/services/cli-adapters.js.map +1 -0
  149. package/dist/server/services/debug-logger.d.ts +35 -0
  150. package/dist/server/services/debug-logger.d.ts.map +1 -0
  151. package/dist/server/services/debug-logger.js +168 -0
  152. package/dist/server/services/debug-logger.js.map +1 -0
  153. package/dist/server/services/discussion-orchestrator.d.ts +47 -0
  154. package/dist/server/services/discussion-orchestrator.d.ts.map +1 -0
  155. package/dist/server/services/discussion-orchestrator.js +599 -0
  156. package/dist/server/services/discussion-orchestrator.js.map +1 -0
  157. package/dist/server/services/log-streamer.d.ts +45 -0
  158. package/dist/server/services/log-streamer.d.ts.map +1 -0
  159. package/dist/server/services/log-streamer.js +348 -0
  160. package/dist/server/services/log-streamer.js.map +1 -0
  161. package/dist/server/services/orchestrator.d.ts +69 -0
  162. package/dist/server/services/orchestrator.d.ts.map +1 -0
  163. package/dist/server/services/orchestrator.js +642 -0
  164. package/dist/server/services/orchestrator.js.map +1 -0
  165. package/dist/server/services/pipeline-orchestrator.d.ts +43 -0
  166. package/dist/server/services/pipeline-orchestrator.d.ts.map +1 -0
  167. package/dist/server/services/pipeline-orchestrator.js +503 -0
  168. package/dist/server/services/pipeline-orchestrator.js.map +1 -0
  169. package/dist/server/services/prompt-guard.d.ts +19 -0
  170. package/dist/server/services/prompt-guard.d.ts.map +1 -0
  171. package/dist/server/services/prompt-guard.js +43 -0
  172. package/dist/server/services/prompt-guard.js.map +1 -0
  173. package/dist/server/services/scheduler.d.ts +43 -0
  174. package/dist/server/services/scheduler.d.ts.map +1 -0
  175. package/dist/server/services/scheduler.js +199 -0
  176. package/dist/server/services/scheduler.js.map +1 -0
  177. package/dist/server/services/skill-injector.d.ts +17 -0
  178. package/dist/server/services/skill-injector.d.ts.map +1 -0
  179. package/dist/server/services/skill-injector.js +60 -0
  180. package/dist/server/services/skill-injector.js.map +1 -0
  181. package/dist/server/services/tunnel-manager.d.ts +42 -0
  182. package/dist/server/services/tunnel-manager.d.ts.map +1 -0
  183. package/dist/server/services/tunnel-manager.js +265 -0
  184. package/dist/server/services/tunnel-manager.js.map +1 -0
  185. package/dist/server/services/worktree-manager.d.ts +117 -0
  186. package/dist/server/services/worktree-manager.d.ts.map +1 -0
  187. package/dist/server/services/worktree-manager.js +400 -0
  188. package/dist/server/services/worktree-manager.js.map +1 -0
  189. package/dist/server/websocket/broadcaster.d.ts +12 -0
  190. package/dist/server/websocket/broadcaster.d.ts.map +1 -0
  191. package/dist/server/websocket/broadcaster.js +23 -0
  192. package/dist/server/websocket/broadcaster.js.map +1 -0
  193. package/dist/server/websocket/events.d.ts +94 -0
  194. package/dist/server/websocket/events.d.ts.map +1 -0
  195. package/dist/server/websocket/events.js +2 -0
  196. package/dist/server/websocket/events.js.map +1 -0
  197. package/dist/server/websocket/index.d.ts +3 -0
  198. package/dist/server/websocket/index.d.ts.map +1 -0
  199. package/dist/server/websocket/index.js +82 -0
  200. package/dist/server/websocket/index.js.map +1 -0
  201. package/package.json +68 -0
@@ -0,0 +1,247 @@
1
+ import { Router } from 'express';
2
+ import cron from 'node-cron';
3
+ import * as queries from '../db/queries.js';
4
+ import { scheduler } from '../services/scheduler.js';
5
+ const router = Router();
6
+ // POST /api/projects/:id/schedules - create schedule
7
+ router.post('/projects/:id/schedules', (req, res) => {
8
+ try {
9
+ const project = queries.getProjectById(req.params.id);
10
+ if (!project) {
11
+ res.status(404).json({ error: 'Project not found' });
12
+ return;
13
+ }
14
+ const { title, description, cron_expression, cli_tool, cli_model, skip_if_running, schedule_type, run_at } = req.body;
15
+ const isOnce = schedule_type === 'once';
16
+ if (!title) {
17
+ res.status(400).json({ error: 'Title is required' });
18
+ return;
19
+ }
20
+ if (isOnce) {
21
+ if (!run_at) {
22
+ res.status(400).json({ error: 'run_at is required for one-time schedules' });
23
+ return;
24
+ }
25
+ }
26
+ else {
27
+ if (!cron_expression) {
28
+ res.status(400).json({ error: 'cron_expression is required for recurring schedules' });
29
+ return;
30
+ }
31
+ if (!cron.validate(cron_expression)) {
32
+ res.status(400).json({ error: 'Invalid cron expression' });
33
+ return;
34
+ }
35
+ }
36
+ const schedule = queries.createSchedule(req.params.id, title, description, isOnce ? '* * * * *' : cron_expression, cli_tool, cli_model, skip_if_running !== undefined ? (skip_if_running ? 1 : 0) : 1, isOnce ? 'once' : 'recurring', isOnce ? run_at : undefined);
37
+ // Auto-register the job since new schedules are active by default
38
+ if (isOnce) {
39
+ scheduler.registerOnceJob(schedule);
40
+ }
41
+ else {
42
+ scheduler.registerJob(schedule);
43
+ }
44
+ res.status(201).json(schedule);
45
+ }
46
+ catch (err) {
47
+ const message = err instanceof Error ? err.message : 'Unknown error';
48
+ res.status(500).json({ error: message });
49
+ }
50
+ });
51
+ // GET /api/projects/:id/schedules - list schedules for project
52
+ router.get('/projects/:id/schedules', (req, res) => {
53
+ try {
54
+ const project = queries.getProjectById(req.params.id);
55
+ if (!project) {
56
+ res.status(404).json({ error: 'Project not found' });
57
+ return;
58
+ }
59
+ const schedules = queries.getSchedulesByProjectId(req.params.id);
60
+ res.json(schedules);
61
+ }
62
+ catch (err) {
63
+ const message = err instanceof Error ? err.message : 'Unknown error';
64
+ res.status(500).json({ error: message });
65
+ }
66
+ });
67
+ // GET /api/schedules/:id - get single schedule
68
+ router.get('/schedules/:id', (req, res) => {
69
+ try {
70
+ const schedule = queries.getScheduleById(req.params.id);
71
+ if (!schedule) {
72
+ res.status(404).json({ error: 'Schedule not found' });
73
+ return;
74
+ }
75
+ res.json(schedule);
76
+ }
77
+ catch (err) {
78
+ const message = err instanceof Error ? err.message : 'Unknown error';
79
+ res.status(500).json({ error: message });
80
+ }
81
+ });
82
+ // PUT /api/schedules/:id - update schedule
83
+ router.put('/schedules/:id', (req, res) => {
84
+ try {
85
+ const existing = queries.getScheduleById(req.params.id);
86
+ if (!existing) {
87
+ res.status(404).json({ error: 'Schedule not found' });
88
+ return;
89
+ }
90
+ const { title, description, cron_expression, cli_tool, cli_model, skip_if_running, schedule_type, run_at } = req.body;
91
+ const effectiveType = schedule_type ?? existing.schedule_type;
92
+ const isOnce = effectiveType === 'once';
93
+ if (!isOnce && cron_expression !== undefined && !cron.validate(cron_expression)) {
94
+ res.status(400).json({ error: 'Invalid cron expression' });
95
+ return;
96
+ }
97
+ const updates = {};
98
+ if (title !== undefined)
99
+ updates.title = title;
100
+ if (description !== undefined)
101
+ updates.description = description;
102
+ if (schedule_type !== undefined)
103
+ updates.schedule_type = schedule_type;
104
+ if (run_at !== undefined)
105
+ updates.run_at = run_at;
106
+ if (isOnce) {
107
+ updates.cron_expression = '* * * * *';
108
+ }
109
+ else if (cron_expression !== undefined) {
110
+ updates.cron_expression = cron_expression;
111
+ }
112
+ if (cli_tool !== undefined)
113
+ updates.cli_tool = cli_tool;
114
+ if (cli_model !== undefined)
115
+ updates.cli_model = cli_model;
116
+ if (skip_if_running !== undefined)
117
+ updates.skip_if_running = skip_if_running ? 1 : 0;
118
+ const schedule = queries.updateSchedule(req.params.id, updates);
119
+ // Re-register job if schedule is active and timing changed
120
+ if (schedule && schedule.is_active) {
121
+ if (schedule.schedule_type === 'once') {
122
+ scheduler.registerOnceJob(schedule);
123
+ }
124
+ else if (cron_expression !== undefined || schedule_type !== undefined) {
125
+ scheduler.registerJob(schedule);
126
+ }
127
+ }
128
+ res.json(schedule);
129
+ }
130
+ catch (err) {
131
+ const message = err instanceof Error ? err.message : 'Unknown error';
132
+ res.status(500).json({ error: message });
133
+ }
134
+ });
135
+ // DELETE /api/schedules/:id - delete schedule
136
+ router.delete('/schedules/:id', (req, res) => {
137
+ try {
138
+ const schedule = queries.getScheduleById(req.params.id);
139
+ if (!schedule) {
140
+ res.status(404).json({ error: 'Schedule not found' });
141
+ return;
142
+ }
143
+ scheduler.unregisterJob(req.params.id);
144
+ queries.deleteSchedule(req.params.id);
145
+ res.status(204).send();
146
+ }
147
+ catch (err) {
148
+ const message = err instanceof Error ? err.message : 'Unknown error';
149
+ res.status(500).json({ error: message });
150
+ }
151
+ });
152
+ // POST /api/schedules/:id/activate - activate schedule
153
+ router.post('/schedules/:id/activate', (req, res) => {
154
+ try {
155
+ const schedule = scheduler.activateSchedule(req.params.id);
156
+ if (!schedule) {
157
+ res.status(404).json({ error: 'Schedule not found' });
158
+ return;
159
+ }
160
+ res.json(schedule);
161
+ }
162
+ catch (err) {
163
+ const message = err instanceof Error ? err.message : 'Unknown error';
164
+ res.status(500).json({ error: message });
165
+ }
166
+ });
167
+ // POST /api/schedules/:id/pause - pause schedule
168
+ router.post('/schedules/:id/pause', (req, res) => {
169
+ try {
170
+ const schedule = scheduler.pauseSchedule(req.params.id);
171
+ if (!schedule) {
172
+ res.status(404).json({ error: 'Schedule not found' });
173
+ return;
174
+ }
175
+ res.json(schedule);
176
+ }
177
+ catch (err) {
178
+ const message = err instanceof Error ? err.message : 'Unknown error';
179
+ res.status(500).json({ error: message });
180
+ }
181
+ });
182
+ // GET /api/schedules/:id/runs - get execution history
183
+ router.get('/schedules/:id/runs', (req, res) => {
184
+ try {
185
+ const schedule = queries.getScheduleById(req.params.id);
186
+ if (!schedule) {
187
+ res.status(404).json({ error: 'Schedule not found' });
188
+ return;
189
+ }
190
+ const limit = parseInt(req.query.limit || '50', 10);
191
+ const runs = queries.getScheduleRunsByScheduleId(req.params.id, limit);
192
+ res.json(runs);
193
+ }
194
+ catch (err) {
195
+ const message = err instanceof Error ? err.message : 'Unknown error';
196
+ res.status(500).json({ error: message });
197
+ }
198
+ });
199
+ // POST /api/schedules/:id/trigger - manually trigger a schedule run
200
+ router.post('/schedules/:id/trigger', async (req, res) => {
201
+ try {
202
+ const run = await scheduler.triggerSchedule(req.params.id);
203
+ if (!run) {
204
+ res.status(404).json({ error: 'Schedule not found' });
205
+ return;
206
+ }
207
+ res.json(run);
208
+ }
209
+ catch (err) {
210
+ const message = err instanceof Error ? err.message : 'Unknown error';
211
+ res.status(500).json({ error: message });
212
+ }
213
+ });
214
+ // POST /api/todos/:id/schedule - convert a todo into a one-time schedule
215
+ router.post('/todos/:id/schedule', (req, res) => {
216
+ try {
217
+ const todo = queries.getTodoById(req.params.id);
218
+ if (!todo) {
219
+ res.status(404).json({ error: 'Todo not found' });
220
+ return;
221
+ }
222
+ if (todo.status !== 'pending' && todo.status !== 'failed' && todo.status !== 'stopped') {
223
+ res.status(400).json({ error: 'Only pending, failed, or stopped tasks can be scheduled' });
224
+ return;
225
+ }
226
+ const { run_at, keep_original } = req.body;
227
+ if (!run_at) {
228
+ res.status(400).json({ error: 'run_at is required' });
229
+ return;
230
+ }
231
+ // Create a one-time schedule from the todo
232
+ const schedule = queries.createSchedule(todo.project_id, todo.title, todo.description ?? undefined, '* * * * *', todo.cli_tool ?? undefined, todo.cli_model ?? undefined, 1, 'once', run_at);
233
+ let originalDeleted = false;
234
+ if (!keep_original) {
235
+ originalDeleted = queries.deleteTodo(req.params.id);
236
+ }
237
+ // Register the one-time job
238
+ scheduler.registerOnceJob(schedule);
239
+ res.status(201).json({ schedule, original_deleted: originalDeleted });
240
+ }
241
+ catch (err) {
242
+ const message = err instanceof Error ? err.message : 'Unknown error';
243
+ res.status(500).json({ error: message });
244
+ }
245
+ });
246
+ export default router;
247
+ //# sourceMappingURL=schedules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedules.js","sourceRoot":"","sources":["../../../src/server/routes/schedules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAqB,MAAM,SAAS,CAAC;AACpD,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAErD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;AAExB,qDAAqD;AACrD,MAAM,CAAC,IAAI,CAAC,yBAAyB,EAAE,CAAC,GAA4B,EAAE,GAAa,EAAE,EAAE;IACrF,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAC;YACrD,OAAO;QACT,CAAC;QAED,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;QACtH,MAAM,MAAM,GAAG,aAAa,KAAK,MAAM,CAAC;QAExC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAC;YACrD,OAAO;QACT,CAAC;QAED,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,2CAA2C,EAAE,CAAC,CAAC;gBAC7E,OAAO;YACT,CAAC;QACH,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,eAAe,EAAE,CAAC;gBACrB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,qDAAqD,EAAE,CAAC,CAAC;gBACvF,OAAO;YACT,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;gBACpC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC,CAAC;gBAC3D,OAAO;YACT,CAAC;QACH,CAAC;QAED,MAAM,QAAQ,GAAG,OAAO,CAAC,cAAc,CACrC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,WAAW,EACjC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,eAAe,EACtC,QAAQ,EAAE,SAAS,EACnB,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAC7D,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,EAC7B,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAC5B,CAAC;QAEF,kEAAkE;QAClE,IAAI,MAAM,EAAE,CAAC;YACX,SAAS,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;QACtC,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QAClC,CAAC;QAED,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QACrE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,+DAA+D;AAC/D,MAAM,CAAC,GAAG,CAAC,yBAAyB,EAAE,CAAC,GAA4B,EAAE,GAAa,EAAE,EAAE;IACpF,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAC;YACrD,OAAO;QACT,CAAC;QAED,MAAM,SAAS,GAAG,OAAO,CAAC,uBAAuB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACjE,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACtB,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QACrE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,+CAA+C;AAC/C,MAAM,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC,GAA4B,EAAE,GAAa,EAAE,EAAE;IAC3E,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACxD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,CAAC;YACtD,OAAO;QACT,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrB,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QACrE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,2CAA2C;AAC3C,MAAM,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC,GAA4B,EAAE,GAAa,EAAE,EAAE;IAC3E,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACxD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,CAAC;YACtD,OAAO;QACT,CAAC;QAED,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;QACtH,MAAM,aAAa,GAAG,aAAa,IAAI,QAAQ,CAAC,aAAa,CAAC;QAC9D,MAAM,MAAM,GAAG,aAAa,KAAK,MAAM,CAAC;QAExC,IAAI,CAAC,MAAM,IAAI,eAAe,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;YAChF,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC,CAAC;YAC3D,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAA4B,EAAE,CAAC;QAC5C,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC;QAC/C,IAAI,WAAW,KAAK,SAAS;YAAE,OAAO,CAAC,WAAW,GAAG,WAAW,CAAC;QACjE,IAAI,aAAa,KAAK,SAAS;YAAE,OAAO,CAAC,aAAa,GAAG,aAAa,CAAC;QACvE,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC;QAClD,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,CAAC,eAAe,GAAG,WAAW,CAAC;QACxC,CAAC;aAAM,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;YACzC,OAAO,CAAC,eAAe,GAAG,eAAe,CAAC;QAC5C,CAAC;QACD,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACxD,IAAI,SAAS,KAAK,SAAS;YAAE,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3D,IAAI,eAAe,KAAK,SAAS;YAAE,OAAO,CAAC,eAAe,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAErF,MAAM,QAAQ,GAAG,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAEhE,2DAA2D;QAC3D,IAAI,QAAQ,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;YACnC,IAAI,QAAQ,CAAC,aAAa,KAAK,MAAM,EAAE,CAAC;gBACtC,SAAS,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;YACtC,CAAC;iBAAM,IAAI,eAAe,KAAK,SAAS,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;gBACxE,SAAS,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;QAED,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrB,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QACrE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,8CAA8C;AAC9C,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC,GAA4B,EAAE,GAAa,EAAE,EAAE;IAC9E,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACxD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,CAAC;YACtD,OAAO;QACT,CAAC;QAED,SAAS,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACvC,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACtC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACzB,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QACrE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,uDAAuD;AACvD,MAAM,CAAC,IAAI,CAAC,yBAAyB,EAAE,CAAC,GAA4B,EAAE,GAAa,EAAE,EAAE;IACrF,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,SAAS,CAAC,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC3D,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,CAAC;YACtD,OAAO;QACT,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrB,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QACrE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,iDAAiD;AACjD,MAAM,CAAC,IAAI,CAAC,sBAAsB,EAAE,CAAC,GAA4B,EAAE,GAAa,EAAE,EAAE;IAClF,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,SAAS,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACxD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,CAAC;YACtD,OAAO;QACT,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACrB,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QACrE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,sDAAsD;AACtD,MAAM,CAAC,GAAG,CAAC,qBAAqB,EAAE,CAAC,GAA4B,EAAE,GAAa,EAAE,EAAE;IAChF,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,OAAO,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACxD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,CAAC;YACtD,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,KAAe,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;QAC9D,MAAM,IAAI,GAAG,OAAO,CAAC,2BAA2B,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QACvE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjB,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QACrE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,oEAAoE;AACpE,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE,KAAK,EAAE,GAA4B,EAAE,GAAa,EAAE,EAAE;IAC1F,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC3D,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,CAAC;YACtD,OAAO;QACT,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChB,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QACrE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,yEAAyE;AACzE,MAAM,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,GAA4B,EAAE,GAAa,EAAE,EAAE;IACjF,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAChD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC,CAAC;YAClD,OAAO;QACT,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACvF,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,yDAAyD,EAAE,CAAC,CAAC;YAC3F,OAAO;QACT,CAAC;QAED,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;QAC3C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,CAAC;YACtD,OAAO;QACT,CAAC;QAED,2CAA2C;QAC3C,MAAM,QAAQ,GAAG,OAAO,CAAC,cAAc,CACrC,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,WAAW,IAAI,SAAS,EAC7B,WAAW,EACX,IAAI,CAAC,QAAQ,IAAI,SAAS,EAC1B,IAAI,CAAC,SAAS,IAAI,SAAS,EAC3B,CAAC,EACD,MAAM,EACN,MAAM,CACP,CAAC;QAEF,IAAI,eAAe,GAAG,KAAK,CAAC;QAC5B,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACtD,CAAC;QAED,4BAA4B;QAC5B,SAAS,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;QAEpC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,gBAAgB,EAAE,eAAe,EAAE,CAAC,CAAC;IACxE,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QACrE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,eAAe,MAAM,CAAC"}
@@ -0,0 +1,3 @@
1
+ declare const router: import("express-serve-static-core").Router;
2
+ export default router;
3
+ //# sourceMappingURL=todos.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"todos.d.ts","sourceRoot":"","sources":["../../../src/server/routes/todos.ts"],"names":[],"mappings":"AAKA,QAAA,MAAM,MAAM,4CAAW,CAAC;AAwGxB,eAAe,MAAM,CAAC"}
@@ -0,0 +1,103 @@
1
+ import { Router } from 'express';
2
+ import { createTodo, getTodosByProjectId, getTodoById, updateTodo, deleteTodo } from '../db/queries.js';
3
+ import { getProjectById } from '../db/queries.js';
4
+ import { validatePromptContent, MAX_TITLE_LENGTH, MAX_DESCRIPTION_LENGTH } from '../services/prompt-guard.js';
5
+ const router = Router();
6
+ // POST /api/projects/:id/todos - create todo for project
7
+ router.post('/projects/:id/todos', (req, res) => {
8
+ try {
9
+ const projectId = req.params.id;
10
+ const project = getProjectById(projectId);
11
+ if (!project) {
12
+ res.status(404).json({ error: 'Project not found' });
13
+ return;
14
+ }
15
+ const { title, description, priority, cli_tool, cli_model, depends_on, max_turns } = req.body;
16
+ if (!title) {
17
+ res.status(400).json({ error: 'title is required' });
18
+ return;
19
+ }
20
+ // Prompt injection detection (warn only, do not block)
21
+ const titleCheck = validatePromptContent(title, MAX_TITLE_LENGTH);
22
+ const descCheck = description ? validatePromptContent(description, MAX_DESCRIPTION_LENGTH) : null;
23
+ for (const w of [...titleCheck.warnings, ...(descCheck?.warnings || [])]) {
24
+ console.warn(`[prompt-guard] Todo "${title}": ${w}`);
25
+ }
26
+ // Validate depends_on if provided
27
+ if (depends_on) {
28
+ const depTodo = getTodoById(depends_on);
29
+ if (!depTodo || depTodo.project_id !== projectId) {
30
+ res.status(400).json({ error: 'Invalid depends_on: task not found in this project' });
31
+ return;
32
+ }
33
+ }
34
+ const parsedMaxTurns = max_turns != null ? parseInt(max_turns, 10) : undefined;
35
+ const todo = createTodo(projectId, title, description, priority, cli_tool, cli_model, undefined, depends_on, parsedMaxTurns || undefined);
36
+ res.status(201).json(todo);
37
+ }
38
+ catch (err) {
39
+ const message = err instanceof Error ? err.message : 'Unknown error';
40
+ res.status(500).json({ error: message });
41
+ }
42
+ });
43
+ // GET /api/projects/:id/todos - list todos for project
44
+ router.get('/projects/:id/todos', (req, res) => {
45
+ try {
46
+ const projectId = req.params.id;
47
+ const project = getProjectById(projectId);
48
+ if (!project) {
49
+ res.status(404).json({ error: 'Project not found' });
50
+ return;
51
+ }
52
+ const todos = getTodosByProjectId(projectId);
53
+ res.json(todos);
54
+ }
55
+ catch (err) {
56
+ const message = err instanceof Error ? err.message : 'Unknown error';
57
+ res.status(500).json({ error: message });
58
+ }
59
+ });
60
+ // PUT /api/todos/:id - update todo
61
+ router.put('/todos/:id', (req, res) => {
62
+ try {
63
+ const existing = getTodoById(req.params.id);
64
+ if (!existing) {
65
+ res.status(404).json({ error: 'Todo not found' });
66
+ return;
67
+ }
68
+ const { title, description, priority, cli_tool, cli_model, depends_on, max_turns, position_x, position_y } = req.body;
69
+ const parsedMaxTurns = max_turns !== undefined ? (max_turns != null ? parseInt(max_turns, 10) || null : null) : undefined;
70
+ const todo = updateTodo(req.params.id, { title, description, priority, cli_tool, cli_model, depends_on, position_x, position_y, ...(parsedMaxTurns !== undefined ? { max_turns: parsedMaxTurns } : {}) });
71
+ res.json(todo);
72
+ }
73
+ catch (err) {
74
+ const message = err instanceof Error ? err.message : 'Unknown error';
75
+ res.status(500).json({ error: message });
76
+ }
77
+ });
78
+ // DELETE /api/todos/:id - delete todo
79
+ router.delete('/todos/:id', (req, res) => {
80
+ try {
81
+ const todo = getTodoById(req.params.id);
82
+ if (!todo) {
83
+ res.status(404).json({ error: 'Todo not found' });
84
+ return;
85
+ }
86
+ if (todo.status === 'running') {
87
+ res.status(400).json({ error: 'Cannot delete a running todo. Stop it first.' });
88
+ return;
89
+ }
90
+ const deleted = deleteTodo(req.params.id);
91
+ if (!deleted) {
92
+ res.status(404).json({ error: 'Todo not found' });
93
+ return;
94
+ }
95
+ res.status(204).send();
96
+ }
97
+ catch (err) {
98
+ const message = err instanceof Error ? err.message : 'Unknown error';
99
+ res.status(500).json({ error: message });
100
+ }
101
+ });
102
+ export default router;
103
+ //# sourceMappingURL=todos.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"todos.js","sourceRoot":"","sources":["../../../src/server/routes/todos.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ declare const router: import("express-serve-static-core").Router;
2
+ export default router;
3
+ //# sourceMappingURL=tunnel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tunnel.d.ts","sourceRoot":"","sources":["../../../src/server/routes/tunnel.ts"],"names":[],"mappings":"AAGA,QAAA,MAAM,MAAM,4CAAW,CAAC;AA2CxB,eAAe,MAAM,CAAC"}
@@ -0,0 +1,44 @@
1
+ import { Router } from 'express';
2
+ import { tunnelManager } from '../services/tunnel-manager.js';
3
+ const router = Router();
4
+ // GET /api/tunnel/status
5
+ // Returns { status, url }
6
+ router.get('/status', (_req, res) => {
7
+ const status = tunnelManager.getTunnelStatus();
8
+ res.json(status);
9
+ });
10
+ // POST /api/tunnel/start
11
+ // Body: { port?: number }
12
+ // Manually start the tunnel
13
+ router.post('/start', async (req, res) => {
14
+ try {
15
+ const port = req.body.port || Number(process.env.PORT) || 3000;
16
+ const tunnelName = process.env.TUNNEL_NAME;
17
+ let url;
18
+ if (tunnelName) {
19
+ url = await tunnelManager.startNamedTunnel(tunnelName, port);
20
+ }
21
+ else {
22
+ url = await tunnelManager.startTunnel(port);
23
+ }
24
+ res.json({ success: true, url });
25
+ }
26
+ catch (err) {
27
+ const message = err instanceof Error ? err.message : 'Failed to start tunnel';
28
+ res.status(500).json({ error: message });
29
+ }
30
+ });
31
+ // POST /api/tunnel/stop
32
+ // Manually stop the tunnel
33
+ router.post('/stop', async (_req, res) => {
34
+ try {
35
+ await tunnelManager.stopTunnel();
36
+ res.json({ success: true });
37
+ }
38
+ catch (err) {
39
+ const message = err instanceof Error ? err.message : 'Failed to stop tunnel';
40
+ res.status(500).json({ error: message });
41
+ }
42
+ });
43
+ export default router;
44
+ //# sourceMappingURL=tunnel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tunnel.js","sourceRoot":"","sources":["../../../src/server/routes/tunnel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAE9D,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;AAExB,yBAAyB;AACzB,0BAA0B;AAC1B,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;IAClC,MAAM,MAAM,GAAG,aAAa,CAAC,eAAe,EAAE,CAAC;IAC/C,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACnB,CAAC,CAAC,CAAC;AAEH,yBAAyB;AACzB,0BAA0B;AAC1B,4BAA4B;AAC5B,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IACvC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;QAC/D,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;QAE3C,IAAI,GAAW,CAAC;QAChB,IAAI,UAAU,EAAE,CAAC;YACf,GAAG,GAAG,MAAM,aAAa,CAAC,gBAAgB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAC/D,CAAC;aAAM,CAAC;YACN,GAAG,GAAG,MAAM,aAAa,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAC9C,CAAC;QAED,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;IACnC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC;QAC9E,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,wBAAwB;AACxB,2BAA2B;AAC3B,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;IACvC,IAAI,CAAC;QACH,MAAM,aAAa,CAAC,UAAU,EAAE,CAAC;QACjC,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC;QAC7E,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,eAAe,MAAM,CAAC"}
@@ -0,0 +1,42 @@
1
+ import { type CliTool, type CliMode, type SandboxMode } from './cli-adapters.js';
2
+ export type ClaudeMode = CliMode;
3
+ export declare class ClaudeManager {
4
+ private processes;
5
+ private stdinStreams;
6
+ /**
7
+ * Start a CLI tool in a worktree directory.
8
+ * Uses node-pty for tools that require a TTY (e.g. Codex),
9
+ * falls back to child_process.spawn for others.
10
+ */
11
+ startClaude(worktreePath: string, prompt: string, model?: string, extraOptions?: string, mode?: CliMode, tool?: CliTool, maxTurns?: number, projectPath?: string, sandboxMode?: SandboxMode): Promise<{
12
+ pid: number;
13
+ stdout: NodeJS.ReadableStream;
14
+ stderr: NodeJS.ReadableStream;
15
+ stdin: NodeJS.WritableStream | null;
16
+ exitPromise: Promise<number>;
17
+ command: string;
18
+ args: string[];
19
+ }>;
20
+ /**
21
+ * Spawn using node-pty for CLIs that require a TTY.
22
+ */
23
+ private startWithPty;
24
+ /**
25
+ * Spawn using child_process for standard CLIs.
26
+ */
27
+ private startWithSpawn;
28
+ /**
29
+ * Write data to the stdin of an interactive process.
30
+ */
31
+ writeToStdin(pid: number, data: string): boolean;
32
+ /**
33
+ * Stop a CLI process. Uses tree-kill to kill the entire process tree
34
+ * (necessary on Windows where shell: true wraps CLIs in cmd.exe).
35
+ * Sends SIGTERM first, escalates to SIGKILL after 5 seconds.
36
+ */
37
+ stopClaude(pid: number): Promise<void>;
38
+ isRunning(pid: number): boolean;
39
+ killAll(): Promise<void>;
40
+ }
41
+ export declare const claudeManager: ClaudeManager;
42
+ //# sourceMappingURL=claude-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-manager.d.ts","sourceRoot":"","sources":["../../../src/server/services/claude-manager.ts"],"names":[],"mappings":"AAIA,OAAO,EAAc,KAAK,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAE7F,MAAM,MAAM,UAAU,GAAG,OAAO,CAAC;AAOjC,qBAAa,aAAa;IACxB,OAAO,CAAC,SAAS,CAA0C;IAC3D,OAAO,CAAC,YAAY,CAAiD;IAErE;;;;OAIG;IACG,WAAW,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,IAAI,GAAE,OAAoB,EAAE,IAAI,GAAE,OAAkB,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC;QAChO,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;QAC9B,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;QAC9B,KAAK,EAAE,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC;QACpC,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAC7B,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,EAAE,CAAC;KAChB,CAAC;IAaF;;OAEG;IACH,OAAO,CAAC,YAAY;IAsHpB;;OAEG;IACH,OAAO,CAAC,cAAc;IA6EtB;;OAEG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO;IAOhD;;;;OAIG;IACG,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0C5C,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAI/B;AAED,eAAO,MAAM,aAAa,eAAsB,CAAC"}