aicodeman 0.2.8 → 0.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.
- package/README.md +91 -0
- package/dist/ai-idle-checker.d.ts.map +1 -1
- package/dist/ai-idle-checker.js +3 -2
- package/dist/ai-idle-checker.js.map +1 -1
- package/dist/ai-plan-checker.d.ts.map +1 -1
- package/dist/ai-plan-checker.js +3 -2
- package/dist/ai-plan-checker.js.map +1 -1
- package/dist/bash-tool-parser.d.ts +2 -3
- package/dist/bash-tool-parser.d.ts.map +1 -1
- package/dist/bash-tool-parser.js +14 -31
- package/dist/bash-tool-parser.js.map +1 -1
- package/dist/config/ai-defaults.d.ts +16 -0
- package/dist/config/ai-defaults.d.ts.map +1 -0
- package/dist/config/ai-defaults.js +16 -0
- package/dist/config/ai-defaults.js.map +1 -0
- package/dist/config/auth-config.d.ts +19 -0
- package/dist/config/auth-config.d.ts.map +1 -0
- package/dist/config/auth-config.js +28 -0
- package/dist/config/auth-config.js.map +1 -0
- package/dist/config/exec-timeout.d.ts +10 -0
- package/dist/config/exec-timeout.d.ts.map +1 -0
- package/dist/config/exec-timeout.js +10 -0
- package/dist/config/exec-timeout.js.map +1 -0
- package/dist/config/map-limits.d.ts +4 -0
- package/dist/config/map-limits.d.ts.map +1 -1
- package/dist/config/map-limits.js +7 -0
- package/dist/config/map-limits.js.map +1 -1
- package/dist/config/server-timing.d.ts +36 -0
- package/dist/config/server-timing.d.ts.map +1 -0
- package/dist/config/server-timing.js +51 -0
- package/dist/config/server-timing.js.map +1 -0
- package/dist/config/team-config.d.ts +16 -0
- package/dist/config/team-config.d.ts.map +1 -0
- package/dist/config/team-config.js +16 -0
- package/dist/config/team-config.js.map +1 -0
- package/dist/config/terminal-limits.d.ts +18 -0
- package/dist/config/terminal-limits.d.ts.map +1 -0
- package/dist/config/terminal-limits.js +18 -0
- package/dist/config/terminal-limits.js.map +1 -0
- package/dist/config/tunnel-config.d.ts +27 -0
- package/dist/config/tunnel-config.d.ts.map +1 -0
- package/dist/config/tunnel-config.js +36 -0
- package/dist/config/tunnel-config.js.map +1 -0
- package/dist/hooks-config.d.ts.map +1 -1
- package/dist/hooks-config.js +7 -6
- package/dist/hooks-config.js.map +1 -1
- package/dist/image-watcher.d.ts +4 -4
- package/dist/image-watcher.d.ts.map +1 -1
- package/dist/image-watcher.js +17 -30
- package/dist/image-watcher.js.map +1 -1
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/dist/plan-orchestrator.d.ts +2 -24
- package/dist/plan-orchestrator.d.ts.map +1 -1
- package/dist/plan-orchestrator.js.map +1 -1
- package/dist/push-store.d.ts +1 -1
- package/dist/push-store.d.ts.map +1 -1
- package/dist/push-store.js +4 -12
- package/dist/push-store.js.map +1 -1
- package/dist/ralph-fix-plan-watcher.d.ts +91 -0
- package/dist/ralph-fix-plan-watcher.d.ts.map +1 -0
- package/dist/ralph-fix-plan-watcher.js +326 -0
- package/dist/ralph-fix-plan-watcher.js.map +1 -0
- package/dist/ralph-plan-tracker.d.ts +201 -0
- package/dist/ralph-plan-tracker.d.ts.map +1 -0
- package/dist/ralph-plan-tracker.js +325 -0
- package/dist/ralph-plan-tracker.js.map +1 -0
- package/dist/ralph-stall-detector.d.ts +84 -0
- package/dist/ralph-stall-detector.d.ts.map +1 -0
- package/dist/ralph-stall-detector.js +139 -0
- package/dist/ralph-stall-detector.js.map +1 -0
- package/dist/ralph-status-parser.d.ts +141 -0
- package/dist/ralph-status-parser.d.ts.map +1 -0
- package/dist/ralph-status-parser.js +478 -0
- package/dist/ralph-status-parser.js.map +1 -0
- package/dist/ralph-tracker.d.ts +194 -685
- package/dist/ralph-tracker.d.ts.map +1 -1
- package/dist/ralph-tracker.js +349 -1713
- package/dist/ralph-tracker.js.map +1 -1
- package/dist/respawn-adaptive-timing.d.ts +61 -0
- package/dist/respawn-adaptive-timing.d.ts.map +1 -0
- package/dist/respawn-adaptive-timing.js +105 -0
- package/dist/respawn-adaptive-timing.js.map +1 -0
- package/dist/respawn-controller.d.ts +14 -101
- package/dist/respawn-controller.d.ts.map +1 -1
- package/dist/respawn-controller.js +155 -594
- package/dist/respawn-controller.js.map +1 -1
- package/dist/respawn-health.d.ts +54 -0
- package/dist/respawn-health.d.ts.map +1 -0
- package/dist/respawn-health.js +183 -0
- package/dist/respawn-health.js.map +1 -0
- package/dist/respawn-metrics.d.ts +81 -0
- package/dist/respawn-metrics.d.ts.map +1 -0
- package/dist/respawn-metrics.js +198 -0
- package/dist/respawn-metrics.js.map +1 -0
- package/dist/respawn-patterns.d.ts +45 -0
- package/dist/respawn-patterns.d.ts.map +1 -0
- package/dist/respawn-patterns.js +125 -0
- package/dist/respawn-patterns.js.map +1 -0
- package/dist/session-auto-ops.d.ts +89 -0
- package/dist/session-auto-ops.d.ts.map +1 -0
- package/dist/session-auto-ops.js +224 -0
- package/dist/session-auto-ops.js.map +1 -0
- package/dist/session-cli-builder.d.ts +62 -0
- package/dist/session-cli-builder.d.ts.map +1 -0
- package/dist/session-cli-builder.js +121 -0
- package/dist/session-cli-builder.js.map +1 -0
- package/dist/session-task-cache.d.ts +52 -0
- package/dist/session-task-cache.d.ts.map +1 -0
- package/dist/session-task-cache.js +90 -0
- package/dist/session-task-cache.js.map +1 -0
- package/dist/session.d.ts +2 -33
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +58 -309
- package/dist/session.js.map +1 -1
- package/dist/state-store.d.ts +9 -2
- package/dist/state-store.d.ts.map +1 -1
- package/dist/state-store.js +112 -39
- package/dist/state-store.js.map +1 -1
- package/dist/subagent-watcher.d.ts +16 -9
- package/dist/subagent-watcher.d.ts.map +1 -1
- package/dist/subagent-watcher.js +126 -147
- package/dist/subagent-watcher.js.map +1 -1
- package/dist/team-watcher.d.ts +3 -0
- package/dist/team-watcher.d.ts.map +1 -1
- package/dist/team-watcher.js +54 -5
- package/dist/team-watcher.js.map +1 -1
- package/dist/tmux-manager.d.ts.map +1 -1
- package/dist/tmux-manager.js +1 -2
- package/dist/tmux-manager.js.map +1 -1
- package/dist/tunnel-manager.d.ts +26 -0
- package/dist/tunnel-manager.d.ts.map +1 -1
- package/dist/tunnel-manager.js +127 -7
- package/dist/tunnel-manager.js.map +1 -1
- package/dist/types/api.d.ts +93 -0
- package/dist/types/api.d.ts.map +1 -0
- package/dist/types/api.js +83 -0
- package/dist/types/api.js.map +1 -0
- package/dist/types/app-state.d.ts +100 -0
- package/dist/types/app-state.d.ts.map +1 -0
- package/dist/types/app-state.js +59 -0
- package/dist/types/app-state.js.map +1 -0
- package/dist/types/common.d.ts +70 -0
- package/dist/types/common.d.ts.map +1 -0
- package/dist/types/common.js +8 -0
- package/dist/types/common.js.map +1 -0
- package/dist/types/index.d.ts +18 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +18 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/lifecycle.d.ts +17 -0
- package/dist/types/lifecycle.d.ts.map +1 -0
- package/dist/types/lifecycle.js +5 -0
- package/dist/types/lifecycle.js.map +1 -0
- package/dist/types/plan.d.ts +32 -0
- package/dist/types/plan.d.ts.map +1 -0
- package/dist/types/plan.js +5 -0
- package/dist/types/plan.js.map +1 -0
- package/dist/types/push.d.ts +23 -0
- package/dist/types/push.d.ts.map +1 -0
- package/dist/types/push.js +5 -0
- package/dist/types/push.js.map +1 -0
- package/dist/types/ralph.d.ts +241 -0
- package/dist/types/ralph.d.ts.map +1 -0
- package/dist/types/ralph.js +49 -0
- package/dist/types/ralph.js.map +1 -0
- package/dist/types/respawn.d.ts +250 -0
- package/dist/types/respawn.d.ts.map +1 -0
- package/dist/types/respawn.js +5 -0
- package/dist/types/respawn.js.map +1 -0
- package/dist/types/run-summary.d.ts +81 -0
- package/dist/types/run-summary.d.ts.map +1 -0
- package/dist/types/run-summary.js +22 -0
- package/dist/types/run-summary.js.map +1 -0
- package/dist/types/session.d.ts +130 -0
- package/dist/types/session.d.ts.map +1 -0
- package/dist/types/session.js +5 -0
- package/dist/types/session.js.map +1 -0
- package/dist/types/task.d.ts +58 -0
- package/dist/types/task.d.ts.map +1 -0
- package/dist/types/task.js +5 -0
- package/dist/types/task.js.map +1 -0
- package/dist/types/teams.d.ts +55 -0
- package/dist/types/teams.d.ts.map +1 -0
- package/dist/types/teams.js +5 -0
- package/dist/types/teams.js.map +1 -0
- package/dist/types/tools.d.ts +46 -0
- package/dist/types/tools.d.ts.map +1 -0
- package/dist/types/tools.js +5 -0
- package/dist/types/tools.js.map +1 -0
- package/dist/types.d.ts +1 -1138
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -214
- package/dist/types.js.map +1 -1
- package/dist/utils/claude-cli-resolver.d.ts.map +1 -1
- package/dist/utils/claude-cli-resolver.js +1 -2
- package/dist/utils/claude-cli-resolver.js.map +1 -1
- package/dist/utils/debouncer.d.ts +111 -0
- package/dist/utils/debouncer.d.ts.map +1 -0
- package/dist/utils/debouncer.js +162 -0
- package/dist/utils/debouncer.js.map +1 -0
- package/dist/utils/index.d.ts +3 -2
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +3 -2
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/opencode-cli-resolver.d.ts.map +1 -1
- package/dist/utils/opencode-cli-resolver.js +1 -2
- package/dist/utils/opencode-cli-resolver.js.map +1 -1
- package/dist/utils/string-similarity.d.ts +0 -57
- package/dist/utils/string-similarity.d.ts.map +1 -1
- package/dist/utils/string-similarity.js +3 -18
- package/dist/utils/string-similarity.js.map +1 -1
- package/dist/web/middleware/auth.d.ts +31 -0
- package/dist/web/middleware/auth.d.ts.map +1 -0
- package/dist/web/middleware/auth.js +154 -0
- package/dist/web/middleware/auth.js.map +1 -0
- package/dist/web/ports/auth-port.d.ts +18 -0
- package/dist/web/ports/auth-port.d.ts.map +1 -0
- package/dist/web/ports/auth-port.js +6 -0
- package/dist/web/ports/auth-port.js.map +1 -0
- package/dist/web/ports/config-port.d.ts +28 -0
- package/dist/web/ports/config-port.d.ts.map +1 -0
- package/dist/web/ports/config-port.js +6 -0
- package/dist/web/ports/config-port.js.map +1 -0
- package/dist/web/ports/event-port.d.ts +13 -0
- package/dist/web/ports/event-port.d.ts.map +1 -0
- package/dist/web/ports/event-port.js +6 -0
- package/dist/web/ports/event-port.js.map +1 -0
- package/dist/web/ports/index.d.ts +14 -0
- package/dist/web/ports/index.d.ts.map +1 -0
- package/dist/web/ports/index.js +9 -0
- package/dist/web/ports/index.js.map +1 -0
- package/dist/web/ports/infra-port.d.ts +36 -0
- package/dist/web/ports/infra-port.d.ts.map +1 -0
- package/dist/web/ports/infra-port.js +6 -0
- package/dist/web/ports/infra-port.js.map +1 -0
- package/dist/web/ports/respawn-port.d.ts +20 -0
- package/dist/web/ports/respawn-port.d.ts.map +1 -0
- package/dist/web/ports/respawn-port.js +6 -0
- package/dist/web/ports/respawn-port.js.map +1 -0
- package/dist/web/ports/session-port.d.ts +15 -0
- package/dist/web/ports/session-port.d.ts.map +1 -0
- package/dist/web/ports/session-port.js +6 -0
- package/dist/web/ports/session-port.js.map +1 -0
- package/dist/web/public/api-client.js +70 -0
- package/dist/web/public/api-client.js.br +0 -0
- package/dist/web/public/api-client.js.gz +0 -0
- package/dist/web/public/app.js +152 -236
- package/dist/web/public/app.js.br +0 -0
- package/dist/web/public/app.js.gz +0 -0
- package/dist/web/public/constants.js +238 -0
- package/dist/web/public/constants.js.br +0 -0
- package/dist/web/public/constants.js.gz +0 -0
- package/dist/web/public/index.html +11 -3
- package/dist/web/public/index.html.br +0 -0
- package/dist/web/public/index.html.gz +0 -0
- package/dist/web/public/keyboard-accessory.js +279 -0
- package/dist/web/public/keyboard-accessory.js.br +0 -0
- package/dist/web/public/keyboard-accessory.js.gz +0 -0
- package/dist/web/public/mobile-handlers.js +467 -0
- package/dist/web/public/mobile-handlers.js.br +0 -0
- package/dist/web/public/mobile-handlers.js.gz +0 -0
- package/dist/web/public/mobile.css.gz +0 -0
- package/dist/web/public/notification-manager.js +445 -0
- package/dist/web/public/notification-manager.js.br +0 -0
- package/dist/web/public/notification-manager.js.gz +0 -0
- package/dist/web/public/ralph-wizard.js +3 -3
- package/dist/web/public/ralph-wizard.js.br +0 -0
- package/dist/web/public/ralph-wizard.js.gz +0 -0
- package/dist/web/public/styles.css.gz +0 -0
- package/dist/web/public/subagent-windows.js +1115 -0
- package/dist/web/public/subagent-windows.js.br +0 -0
- package/dist/web/public/subagent-windows.js.gz +0 -0
- package/dist/web/public/sw.js.gz +0 -0
- package/dist/web/public/upload.html.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-fit.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-unicode11.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-webgl.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm.css.gz +0 -0
- package/dist/web/public/vendor/xterm.min.js.gz +0 -0
- package/dist/web/public/voice-input.js +858 -0
- package/dist/web/public/voice-input.js.br +0 -0
- package/dist/web/public/voice-input.js.gz +0 -0
- package/dist/web/route-helpers.d.ts +38 -0
- package/dist/web/route-helpers.d.ts.map +1 -0
- package/dist/web/route-helpers.js +143 -0
- package/dist/web/route-helpers.js.map +1 -0
- package/dist/web/routes/case-routes.d.ts +9 -0
- package/dist/web/routes/case-routes.d.ts.map +1 -0
- package/dist/web/routes/case-routes.js +419 -0
- package/dist/web/routes/case-routes.js.map +1 -0
- package/dist/web/routes/file-routes.d.ts +8 -0
- package/dist/web/routes/file-routes.d.ts.map +1 -0
- package/dist/web/routes/file-routes.js +337 -0
- package/dist/web/routes/file-routes.js.map +1 -0
- package/dist/web/routes/hook-event-routes.d.ts +9 -0
- package/dist/web/routes/hook-event-routes.d.ts.map +1 -0
- package/dist/web/routes/hook-event-routes.js +57 -0
- package/dist/web/routes/hook-event-routes.js.map +1 -0
- package/dist/web/routes/index.d.ts +16 -0
- package/dist/web/routes/index.d.ts.map +1 -0
- package/dist/web/routes/index.js +16 -0
- package/dist/web/routes/index.js.map +1 -0
- package/dist/web/routes/mux-routes.d.ts +8 -0
- package/dist/web/routes/mux-routes.d.ts.map +1 -0
- package/dist/web/routes/mux-routes.js +32 -0
- package/dist/web/routes/mux-routes.js.map +1 -0
- package/dist/web/routes/plan-routes.d.ts +9 -0
- package/dist/web/routes/plan-routes.d.ts.map +1 -0
- package/dist/web/routes/plan-routes.js +381 -0
- package/dist/web/routes/plan-routes.js.map +1 -0
- package/dist/web/routes/push-routes.d.ts +8 -0
- package/dist/web/routes/push-routes.d.ts.map +1 -0
- package/dist/web/routes/push-routes.js +49 -0
- package/dist/web/routes/push-routes.js.map +1 -0
- package/dist/web/routes/ralph-routes.d.ts +9 -0
- package/dist/web/routes/ralph-routes.d.ts.map +1 -0
- package/dist/web/routes/ralph-routes.js +475 -0
- package/dist/web/routes/ralph-routes.js.map +1 -0
- package/dist/web/routes/respawn-routes.d.ts +8 -0
- package/dist/web/routes/respawn-routes.d.ts.map +1 -0
- package/dist/web/routes/respawn-routes.js +260 -0
- package/dist/web/routes/respawn-routes.js.map +1 -0
- package/dist/web/routes/scheduled-routes.d.ts +8 -0
- package/dist/web/routes/scheduled-routes.d.ts.map +1 -0
- package/dist/web/routes/scheduled-routes.js +51 -0
- package/dist/web/routes/scheduled-routes.js.map +1 -0
- package/dist/web/routes/session-routes.d.ts +9 -0
- package/dist/web/routes/session-routes.d.ts.map +1 -0
- package/dist/web/routes/session-routes.js +729 -0
- package/dist/web/routes/session-routes.js.map +1 -0
- package/dist/web/routes/system-routes.d.ts +9 -0
- package/dist/web/routes/system-routes.d.ts.map +1 -0
- package/dist/web/routes/system-routes.js +678 -0
- package/dist/web/routes/system-routes.js.map +1 -0
- package/dist/web/routes/team-routes.d.ts +8 -0
- package/dist/web/routes/team-routes.d.ts.map +1 -0
- package/dist/web/routes/team-routes.js +14 -0
- package/dist/web/routes/team-routes.js.map +1 -0
- package/dist/web/schemas.d.ts +43 -3
- package/dist/web/schemas.d.ts.map +1 -1
- package/dist/web/schemas.js +6 -2
- package/dist/web/schemas.js.map +1 -1
- package/dist/web/server.d.ts +10 -9
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +342 -3829
- package/dist/web/server.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Plan generation and management routes.
|
|
3
|
+
* Covers AI-powered plan generation (simple + detailed orchestration),
|
|
4
|
+
* plan task CRUD, checkpoints, version history, and rollback.
|
|
5
|
+
*/
|
|
6
|
+
import { join, resolve, relative, isAbsolute } from 'node:path';
|
|
7
|
+
import { existsSync, rmSync } from 'node:fs';
|
|
8
|
+
import { Session } from '../../session.js';
|
|
9
|
+
import { ApiErrorCode, createErrorResponse, getErrorMessage } from '../../types.js';
|
|
10
|
+
import { PlanOrchestrator } from '../../plan-orchestrator.js';
|
|
11
|
+
import { GeneratePlanSchema, GeneratePlanDetailedSchema, CancelPlanSchema, PlanTaskUpdateSchema, PlanTaskAddSchema, } from '../schemas.js';
|
|
12
|
+
import { findSessionOrFail, CASES_DIR } from '../route-helpers.js';
|
|
13
|
+
export function registerPlanRoutes(app, ctx) {
|
|
14
|
+
// ============ Plan Generation Endpoints ============
|
|
15
|
+
app.post('/api/generate-plan', async (req) => {
|
|
16
|
+
const gpResult = GeneratePlanSchema.safeParse(req.body);
|
|
17
|
+
if (!gpResult.success) {
|
|
18
|
+
return createErrorResponse(ApiErrorCode.INVALID_INPUT, 'Invalid request body');
|
|
19
|
+
}
|
|
20
|
+
const { taskDescription, detailLevel = 'standard' } = gpResult.data;
|
|
21
|
+
// Build sophisticated prompt based on Ralph Wiggum methodology
|
|
22
|
+
const detailConfig = {
|
|
23
|
+
brief: { style: 'high-level milestones', testDepth: 'basic' },
|
|
24
|
+
standard: { style: 'balanced implementation steps', testDepth: 'thorough' },
|
|
25
|
+
detailed: {
|
|
26
|
+
style: 'granular sub-tasks with full TDD coverage',
|
|
27
|
+
testDepth: 'comprehensive',
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
const levelConfig = detailConfig[detailLevel] || detailConfig.standard;
|
|
31
|
+
const prompt = `You are an expert software architect breaking down a task into a thorough implementation plan.
|
|
32
|
+
|
|
33
|
+
## TASK TO IMPLEMENT
|
|
34
|
+
${taskDescription}
|
|
35
|
+
|
|
36
|
+
## YOUR MISSION
|
|
37
|
+
Create a detailed, actionable implementation plan following Test-Driven Development (TDD) methodology.
|
|
38
|
+
Think deeply about:
|
|
39
|
+
- What are ALL the components, modules, and features needed?
|
|
40
|
+
- What could go wrong? Add defensive steps for error handling.
|
|
41
|
+
- How will we verify each part works? Tests before implementation.
|
|
42
|
+
- What edge cases need handling?
|
|
43
|
+
- What's the logical order of dependencies?
|
|
44
|
+
|
|
45
|
+
## DETAIL LEVEL: ${detailLevel.toUpperCase()}
|
|
46
|
+
Style: ${levelConfig.style}
|
|
47
|
+
Generate as many steps as needed to properly cover the task - don't artificially limit yourself.
|
|
48
|
+
For complex projects, this could be 30, 50, or even 100+ steps. Quality over brevity.
|
|
49
|
+
|
|
50
|
+
## PLAN STRUCTURE
|
|
51
|
+
|
|
52
|
+
Your plan MUST include these phases in order:
|
|
53
|
+
|
|
54
|
+
### Phase 1: Foundation & Setup
|
|
55
|
+
- Project structure, dependencies, configuration
|
|
56
|
+
- Database schemas, type definitions, interfaces
|
|
57
|
+
|
|
58
|
+
### Phase 2: Core Implementation (TDD Cycle)
|
|
59
|
+
For EACH feature:
|
|
60
|
+
1. Write failing tests first (unit tests)
|
|
61
|
+
2. Implement the feature
|
|
62
|
+
3. Run tests, debug until passing
|
|
63
|
+
4. Refactor if needed
|
|
64
|
+
|
|
65
|
+
### Phase 3: Integration & Edge Cases
|
|
66
|
+
- Integration tests for feature interactions
|
|
67
|
+
- Edge case handling (errors, boundaries, invalid input)
|
|
68
|
+
- Error messages and user feedback
|
|
69
|
+
|
|
70
|
+
### Phase 4: Verification & Hardening
|
|
71
|
+
- Run full test suite
|
|
72
|
+
- Fix any failing tests
|
|
73
|
+
- Add missing test coverage
|
|
74
|
+
- Final verification that ALL requirements are met
|
|
75
|
+
|
|
76
|
+
## OUTPUT FORMAT
|
|
77
|
+
Return ONLY a JSON array. Each item MUST have:
|
|
78
|
+
- id: unique identifier (e.g., "P0-001", "P1-002")
|
|
79
|
+
- content: specific action (verb phrase, 15-120 chars, be descriptive!)
|
|
80
|
+
- priority: "P0" (critical/blocking), "P1" (required), "P2" (enhancement)
|
|
81
|
+
- verificationCriteria: HOW to verify this step is complete (required!)
|
|
82
|
+
- tddPhase: "setup" | "test" | "impl" | "verify"
|
|
83
|
+
- dependencies: array of task IDs this depends on (empty if none)
|
|
84
|
+
|
|
85
|
+
## EXAMPLE OUTPUT
|
|
86
|
+
[
|
|
87
|
+
{"id": "P0-001", "content": "Create project structure with src/, tests/, and config directories", "priority": "P0", "verificationCriteria": "Directories exist, package.json initialized", "tddPhase": "setup", "dependencies": []},
|
|
88
|
+
{"id": "P0-002", "content": "Define TypeScript interfaces for User, Session, and AuthToken types", "priority": "P0", "verificationCriteria": "Types compile without errors, exported from types.ts", "tddPhase": "setup", "dependencies": ["P0-001"]},
|
|
89
|
+
{"id": "P0-003", "content": "Write failing unit tests for password hashing (valid password, empty, too short)", "priority": "P0", "verificationCriteria": "Tests exist, fail with 'not implemented'", "tddPhase": "test", "dependencies": ["P0-002"]},
|
|
90
|
+
{"id": "P0-004", "content": "Implement password hashing with bcrypt, configurable salt rounds", "priority": "P0", "verificationCriteria": "npm test -- --grep='password' passes", "tddPhase": "impl", "dependencies": ["P0-003"]},
|
|
91
|
+
{"id": "P0-005", "content": "Write failing tests for JWT token generation and validation", "priority": "P0", "verificationCriteria": "Tests exist, fail with 'not implemented'", "tddPhase": "test", "dependencies": ["P0-004"]},
|
|
92
|
+
{"id": "P0-006", "content": "Implement JWT service with access/refresh token support", "priority": "P0", "verificationCriteria": "npm test -- --grep='JWT' passes", "tddPhase": "impl", "dependencies": ["P0-005"]},
|
|
93
|
+
{"id": "P1-001", "content": "Write integration tests for login flow (valid creds, invalid, locked account)", "priority": "P1", "verificationCriteria": "Integration tests exist, fail until endpoint implemented", "tddPhase": "test", "dependencies": ["P0-006"]},
|
|
94
|
+
{"id": "P1-002", "content": "Implement login endpoint with rate limiting and audit logging", "priority": "P1", "verificationCriteria": "All login tests pass, endpoint returns 200/401 correctly", "tddPhase": "impl", "dependencies": ["P1-001"]},
|
|
95
|
+
{"id": "P1-003", "content": "Run full test suite and verify all tests pass", "priority": "P1", "verificationCriteria": "npm test exits with code 0, coverage > 80%", "tddPhase": "verify", "dependencies": ["P1-002"]}
|
|
96
|
+
]
|
|
97
|
+
|
|
98
|
+
## CRITICAL RULES
|
|
99
|
+
1. EVERY task MUST have verificationCriteria - this is non-negotiable!
|
|
100
|
+
2. EVERY implementation step should have a corresponding test step BEFORE it
|
|
101
|
+
3. Use tddPhase: "test" for writing tests, "impl" for implementation
|
|
102
|
+
4. Dependencies must form a valid DAG - no cycles
|
|
103
|
+
5. Be SPECIFIC - not "Add tests" but "Write tests for X covering Y and Z"
|
|
104
|
+
6. End with verification that ALL original requirements are met
|
|
105
|
+
7. Use P0 for foundation and core features, P1 for required work, P2 for nice-to-have
|
|
106
|
+
|
|
107
|
+
NOW: Generate the implementation plan for the task above. Think step by step.`;
|
|
108
|
+
// Create temporary session for the AI call using Opus 4.5 for deep reasoning
|
|
109
|
+
const session = new Session({
|
|
110
|
+
workingDir: process.cwd(),
|
|
111
|
+
mux: ctx.mux,
|
|
112
|
+
useMux: false, // No mux needed for one-shot
|
|
113
|
+
mode: 'claude',
|
|
114
|
+
});
|
|
115
|
+
// Use configured model for plan generation, falling back to opus
|
|
116
|
+
const planModelConfig = await ctx.getModelConfig();
|
|
117
|
+
const modelToUse = planModelConfig?.agentTypeOverrides?.implement || planModelConfig?.defaultModel || 'opus';
|
|
118
|
+
try {
|
|
119
|
+
const { result, cost } = await session.runPrompt(prompt, { model: modelToUse });
|
|
120
|
+
// Parse JSON from result
|
|
121
|
+
const jsonMatch = result.match(/\[[\s\S]*\]/);
|
|
122
|
+
if (!jsonMatch) {
|
|
123
|
+
return createErrorResponse(ApiErrorCode.OPERATION_FAILED, 'Failed to parse plan - no JSON array found');
|
|
124
|
+
}
|
|
125
|
+
let items;
|
|
126
|
+
try {
|
|
127
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
128
|
+
if (!Array.isArray(parsed)) {
|
|
129
|
+
return createErrorResponse(ApiErrorCode.OPERATION_FAILED, 'Invalid response - expected array');
|
|
130
|
+
}
|
|
131
|
+
// Validate and normalize items with enhanced fields
|
|
132
|
+
items = parsed.map((item, idx) => {
|
|
133
|
+
if (typeof item !== 'object' || item === null) {
|
|
134
|
+
return {
|
|
135
|
+
id: `task-${idx}`,
|
|
136
|
+
content: `Step ${idx + 1}`,
|
|
137
|
+
priority: null,
|
|
138
|
+
verificationCriteria: 'Task completed successfully',
|
|
139
|
+
status: 'pending',
|
|
140
|
+
attempts: 0,
|
|
141
|
+
version: 1,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
const obj = item;
|
|
145
|
+
const content = typeof obj.content === 'string' ? obj.content.slice(0, 200) : `Step ${idx + 1}`;
|
|
146
|
+
let priority = null;
|
|
147
|
+
if (obj.priority === 'P0' || obj.priority === 'P1' || obj.priority === 'P2') {
|
|
148
|
+
priority = obj.priority;
|
|
149
|
+
}
|
|
150
|
+
// Parse tddPhase
|
|
151
|
+
let tddPhase;
|
|
152
|
+
if (obj.tddPhase === 'setup' ||
|
|
153
|
+
obj.tddPhase === 'test' ||
|
|
154
|
+
obj.tddPhase === 'impl' ||
|
|
155
|
+
obj.tddPhase === 'verify') {
|
|
156
|
+
tddPhase = obj.tddPhase;
|
|
157
|
+
}
|
|
158
|
+
return {
|
|
159
|
+
id: obj.id ? String(obj.id) : `task-${idx}`,
|
|
160
|
+
content,
|
|
161
|
+
priority,
|
|
162
|
+
verificationCriteria: typeof obj.verificationCriteria === 'string' ? obj.verificationCriteria : 'Task completed successfully',
|
|
163
|
+
tddPhase,
|
|
164
|
+
dependencies: Array.isArray(obj.dependencies) ? obj.dependencies.map(String) : [],
|
|
165
|
+
status: 'pending',
|
|
166
|
+
attempts: 0,
|
|
167
|
+
version: 1,
|
|
168
|
+
};
|
|
169
|
+
});
|
|
170
|
+
// No artificial limit - let Claude generate what's needed
|
|
171
|
+
}
|
|
172
|
+
catch (parseErr) {
|
|
173
|
+
return createErrorResponse(ApiErrorCode.OPERATION_FAILED, 'Failed to parse plan JSON: ' + getErrorMessage(parseErr));
|
|
174
|
+
}
|
|
175
|
+
return {
|
|
176
|
+
success: true,
|
|
177
|
+
data: { items, costUsd: cost },
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
catch (err) {
|
|
181
|
+
return createErrorResponse(ApiErrorCode.OPERATION_FAILED, 'Plan generation failed: ' + getErrorMessage(err));
|
|
182
|
+
}
|
|
183
|
+
finally {
|
|
184
|
+
// Clean up the temporary session
|
|
185
|
+
try {
|
|
186
|
+
await session.stop();
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
// Ignore cleanup errors
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
// Generate detailed implementation plan using subagent orchestration
|
|
194
|
+
// This spawns multiple specialist subagents in parallel for thorough analysis
|
|
195
|
+
app.post('/api/generate-plan-detailed', async (req) => {
|
|
196
|
+
const gpdResult = GeneratePlanDetailedSchema.safeParse(req.body);
|
|
197
|
+
if (!gpdResult.success) {
|
|
198
|
+
return createErrorResponse(ApiErrorCode.INVALID_INPUT, 'Invalid request body');
|
|
199
|
+
}
|
|
200
|
+
const { taskDescription, caseName } = gpdResult.data;
|
|
201
|
+
// Determine output directory for saving wizard results
|
|
202
|
+
let outputDir;
|
|
203
|
+
if (caseName) {
|
|
204
|
+
const casePath = join(CASES_DIR, caseName);
|
|
205
|
+
// Security: Path traversal protection - use relative path check
|
|
206
|
+
const resolvedCase = resolve(casePath);
|
|
207
|
+
const resolvedBase = resolve(CASES_DIR);
|
|
208
|
+
const relPath = relative(resolvedBase, resolvedCase);
|
|
209
|
+
if (!relPath.startsWith('..') && !isAbsolute(relPath) && existsSync(casePath)) {
|
|
210
|
+
outputDir = join(casePath, 'ralph-wizard');
|
|
211
|
+
// Clear old ralph-wizard directory to ensure fresh prompts for each generation
|
|
212
|
+
// This prevents stale prompts from previous runs being shown when clicking on agents
|
|
213
|
+
if (existsSync(outputDir)) {
|
|
214
|
+
try {
|
|
215
|
+
rmSync(outputDir, { recursive: true, force: true });
|
|
216
|
+
console.log(`[API] Cleared old ralph-wizard directory: ${outputDir}`);
|
|
217
|
+
}
|
|
218
|
+
catch (err) {
|
|
219
|
+
console.warn(`[API] Failed to clear ralph-wizard directory:`, err);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
const detailedModelConfig = await ctx.getModelConfig();
|
|
225
|
+
const orchestrator = new PlanOrchestrator(ctx.mux, process.cwd(), outputDir, detailedModelConfig ?? undefined);
|
|
226
|
+
// Store orchestrator for potential cancellation via API (not on disconnect)
|
|
227
|
+
// Plan generation continues even if browser disconnects - only explicit cancel stops it
|
|
228
|
+
const orchestratorId = `plan-${Date.now()}`;
|
|
229
|
+
ctx.activePlanOrchestrators.set(orchestratorId, orchestrator);
|
|
230
|
+
// Broadcast the orchestrator ID so frontend can cancel if needed
|
|
231
|
+
ctx.broadcast('plan:started', { orchestratorId });
|
|
232
|
+
// Track progress for SSE updates
|
|
233
|
+
const progressUpdates = [];
|
|
234
|
+
const onProgress = (phase, detail) => {
|
|
235
|
+
const update = { phase, detail, timestamp: Date.now() };
|
|
236
|
+
progressUpdates.push(update);
|
|
237
|
+
// Broadcast progress to connected clients
|
|
238
|
+
ctx.broadcast('plan:progress', update);
|
|
239
|
+
};
|
|
240
|
+
// Broadcast plan subagent events for UI visibility
|
|
241
|
+
const onSubagent = (event) => {
|
|
242
|
+
ctx.broadcast('plan:subagent', event);
|
|
243
|
+
};
|
|
244
|
+
try {
|
|
245
|
+
const result = await orchestrator.generateDetailedPlan(taskDescription, onProgress, onSubagent);
|
|
246
|
+
// Clean up orchestrator from active map
|
|
247
|
+
ctx.activePlanOrchestrators.delete(orchestratorId);
|
|
248
|
+
ctx.broadcast('plan:completed', { orchestratorId, success: result.success });
|
|
249
|
+
if (!result.success) {
|
|
250
|
+
return createErrorResponse(ApiErrorCode.OPERATION_FAILED, result.error || 'Plan generation failed');
|
|
251
|
+
}
|
|
252
|
+
return {
|
|
253
|
+
success: true,
|
|
254
|
+
data: {
|
|
255
|
+
items: result.items,
|
|
256
|
+
costUsd: result.costUsd,
|
|
257
|
+
metadata: result.metadata,
|
|
258
|
+
progressLog: progressUpdates,
|
|
259
|
+
orchestratorId,
|
|
260
|
+
},
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
catch (err) {
|
|
264
|
+
// Clean up on error too
|
|
265
|
+
ctx.activePlanOrchestrators.delete(orchestratorId);
|
|
266
|
+
ctx.broadcast('plan:completed', {
|
|
267
|
+
orchestratorId,
|
|
268
|
+
success: false,
|
|
269
|
+
error: getErrorMessage(err),
|
|
270
|
+
});
|
|
271
|
+
return createErrorResponse(ApiErrorCode.OPERATION_FAILED, 'Detailed plan generation failed: ' + getErrorMessage(err));
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
// Cancel active plan generation
|
|
275
|
+
app.post('/api/cancel-plan-generation', async (req) => {
|
|
276
|
+
const cpResult = CancelPlanSchema.safeParse(req.body);
|
|
277
|
+
if (!cpResult.success) {
|
|
278
|
+
return createErrorResponse(ApiErrorCode.INVALID_INPUT, 'Invalid request body');
|
|
279
|
+
}
|
|
280
|
+
const { orchestratorId } = cpResult.data;
|
|
281
|
+
// If specific orchestrator ID provided, cancel just that one
|
|
282
|
+
if (orchestratorId) {
|
|
283
|
+
const orchestrator = ctx.activePlanOrchestrators.get(orchestratorId);
|
|
284
|
+
if (!orchestrator) {
|
|
285
|
+
return createErrorResponse(ApiErrorCode.NOT_FOUND, 'Plan generation not found or already completed');
|
|
286
|
+
}
|
|
287
|
+
console.log(`[API] Cancelling plan generation ${orchestratorId}`);
|
|
288
|
+
await orchestrator.cancel();
|
|
289
|
+
ctx.activePlanOrchestrators.delete(orchestratorId);
|
|
290
|
+
ctx.broadcast('plan:cancelled', { orchestratorId });
|
|
291
|
+
return { success: true, data: { cancelled: orchestratorId } };
|
|
292
|
+
}
|
|
293
|
+
// Otherwise cancel all active plan generations
|
|
294
|
+
const cancelled = [];
|
|
295
|
+
for (const [id, orchestrator] of ctx.activePlanOrchestrators) {
|
|
296
|
+
console.log(`[API] Cancelling plan generation ${id}`);
|
|
297
|
+
await orchestrator.cancel();
|
|
298
|
+
cancelled.push(id);
|
|
299
|
+
ctx.broadcast('plan:cancelled', { orchestratorId: id });
|
|
300
|
+
}
|
|
301
|
+
ctx.activePlanOrchestrators.clear();
|
|
302
|
+
return { success: true, data: { cancelled } };
|
|
303
|
+
});
|
|
304
|
+
// ============ Plan Management Endpoints ============
|
|
305
|
+
// These endpoints support runtime plan adaptation with checkpoints, failure tracking, and versioning
|
|
306
|
+
// Update a specific plan task (status, attempts, errors)
|
|
307
|
+
app.patch('/api/sessions/:id/plan/task/:taskId', async (req) => {
|
|
308
|
+
const { id, taskId } = req.params;
|
|
309
|
+
const session = findSessionOrFail(ctx, id);
|
|
310
|
+
const tracker = session.ralphTracker;
|
|
311
|
+
if (!tracker) {
|
|
312
|
+
return createErrorResponse(ApiErrorCode.OPERATION_FAILED, 'Ralph tracker not available');
|
|
313
|
+
}
|
|
314
|
+
const ptuResult = PlanTaskUpdateSchema.safeParse(req.body);
|
|
315
|
+
if (!ptuResult.success) {
|
|
316
|
+
return createErrorResponse(ApiErrorCode.INVALID_INPUT, 'Invalid request body');
|
|
317
|
+
}
|
|
318
|
+
const update = ptuResult.data;
|
|
319
|
+
const result = tracker.updatePlanTask(taskId, update);
|
|
320
|
+
if (!result.success) {
|
|
321
|
+
return createErrorResponse(ApiErrorCode.NOT_FOUND, result.error || 'Task not found');
|
|
322
|
+
}
|
|
323
|
+
ctx.broadcast('session:planTaskUpdate', { sessionId: id, taskId, update: result.task });
|
|
324
|
+
return { success: true, data: result.task };
|
|
325
|
+
});
|
|
326
|
+
// Trigger a checkpoint review (at iterations 5, 10, 20, etc.)
|
|
327
|
+
app.post('/api/sessions/:id/plan/checkpoint', async (req) => {
|
|
328
|
+
const { id } = req.params;
|
|
329
|
+
const session = findSessionOrFail(ctx, id);
|
|
330
|
+
const tracker = session.ralphTracker;
|
|
331
|
+
if (!tracker) {
|
|
332
|
+
return createErrorResponse(ApiErrorCode.OPERATION_FAILED, 'Ralph tracker not available');
|
|
333
|
+
}
|
|
334
|
+
const checkpoint = tracker.generateCheckpointReview();
|
|
335
|
+
ctx.broadcast('session:planCheckpoint', { sessionId: id, checkpoint });
|
|
336
|
+
return { success: true, data: checkpoint };
|
|
337
|
+
});
|
|
338
|
+
// Get plan version history
|
|
339
|
+
app.get('/api/sessions/:id/plan/history', async (req) => {
|
|
340
|
+
const { id } = req.params;
|
|
341
|
+
const session = findSessionOrFail(ctx, id);
|
|
342
|
+
const tracker = session.ralphTracker;
|
|
343
|
+
if (!tracker) {
|
|
344
|
+
return createErrorResponse(ApiErrorCode.OPERATION_FAILED, 'Ralph tracker not available');
|
|
345
|
+
}
|
|
346
|
+
return { success: true, data: tracker.getPlanHistory() };
|
|
347
|
+
});
|
|
348
|
+
// Rollback to a previous plan version
|
|
349
|
+
app.post('/api/sessions/:id/plan/rollback/:version', async (req) => {
|
|
350
|
+
const { id, version } = req.params;
|
|
351
|
+
const session = findSessionOrFail(ctx, id);
|
|
352
|
+
const tracker = session.ralphTracker;
|
|
353
|
+
if (!tracker) {
|
|
354
|
+
return createErrorResponse(ApiErrorCode.OPERATION_FAILED, 'Ralph tracker not available');
|
|
355
|
+
}
|
|
356
|
+
const result = tracker.rollbackToVersion(parseInt(version, 10));
|
|
357
|
+
if (!result.success) {
|
|
358
|
+
return createErrorResponse(ApiErrorCode.NOT_FOUND, result.error || 'Version not found');
|
|
359
|
+
}
|
|
360
|
+
ctx.broadcast('session:planRollback', { sessionId: id, version: parseInt(version, 10) });
|
|
361
|
+
return { success: true, data: result.plan };
|
|
362
|
+
});
|
|
363
|
+
// Add a new task to the plan (for runtime adaptation)
|
|
364
|
+
app.post('/api/sessions/:id/plan/task', async (req) => {
|
|
365
|
+
const { id } = req.params;
|
|
366
|
+
const session = findSessionOrFail(ctx, id);
|
|
367
|
+
const tracker = session.ralphTracker;
|
|
368
|
+
if (!tracker) {
|
|
369
|
+
return createErrorResponse(ApiErrorCode.OPERATION_FAILED, 'Ralph tracker not available');
|
|
370
|
+
}
|
|
371
|
+
const ptaResult = PlanTaskAddSchema.safeParse(req.body);
|
|
372
|
+
if (!ptaResult.success) {
|
|
373
|
+
return createErrorResponse(ApiErrorCode.INVALID_INPUT, 'Invalid request body');
|
|
374
|
+
}
|
|
375
|
+
const task = ptaResult.data;
|
|
376
|
+
const result = tracker.addPlanTask(task);
|
|
377
|
+
ctx.broadcast('session:planTaskAdded', { sessionId: id, task: result.task });
|
|
378
|
+
return { success: true, data: result.task };
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
//# sourceMappingURL=plan-routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-routes.js","sourceRoot":"","sources":["../../../src/web/routes/plan-routes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Push notification routes.
|
|
3
|
+
* Manages VAPID keys, push subscriptions, and preference updates.
|
|
4
|
+
*/
|
|
5
|
+
import { FastifyInstance } from 'fastify';
|
|
6
|
+
import type { InfraPort } from '../ports/index.js';
|
|
7
|
+
export declare function registerPushRoutes(app: FastifyInstance, ctx: InfraPort): void;
|
|
8
|
+
//# sourceMappingURL=push-routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"push-routes.d.ts","sourceRoot":"","sources":["../../../src/web/routes/push-routes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAI1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,SAAS,GAAG,IAAI,CA2C7E"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Push notification routes.
|
|
3
|
+
* Manages VAPID keys, push subscriptions, and preference updates.
|
|
4
|
+
*/
|
|
5
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
6
|
+
import { ApiErrorCode, createErrorResponse } from '../../types.js';
|
|
7
|
+
import { PushSubscribeSchema, PushPreferencesUpdateSchema } from '../schemas.js';
|
|
8
|
+
export function registerPushRoutes(app, ctx) {
|
|
9
|
+
app.get('/api/push/vapid-key', async () => {
|
|
10
|
+
return { success: true, data: { publicKey: ctx.pushStore.getPublicKey() } };
|
|
11
|
+
});
|
|
12
|
+
app.post('/api/push/subscribe', async (req) => {
|
|
13
|
+
const result = PushSubscribeSchema.safeParse(req.body);
|
|
14
|
+
if (!result.success) {
|
|
15
|
+
return createErrorResponse(ApiErrorCode.INVALID_INPUT, result.error.issues[0]?.message ?? 'Validation failed');
|
|
16
|
+
}
|
|
17
|
+
const { endpoint, keys, userAgent, pushPreferences } = result.data;
|
|
18
|
+
const record = ctx.pushStore.addSubscription({
|
|
19
|
+
id: uuidv4(),
|
|
20
|
+
endpoint,
|
|
21
|
+
keys,
|
|
22
|
+
userAgent: userAgent ?? req.headers['user-agent'] ?? '',
|
|
23
|
+
createdAt: Date.now(),
|
|
24
|
+
pushPreferences: pushPreferences ?? {},
|
|
25
|
+
});
|
|
26
|
+
return { success: true, data: { id: record.id } };
|
|
27
|
+
});
|
|
28
|
+
app.put('/api/push/subscribe/:id', async (req) => {
|
|
29
|
+
const { id } = req.params;
|
|
30
|
+
const result = PushPreferencesUpdateSchema.safeParse(req.body);
|
|
31
|
+
if (!result.success) {
|
|
32
|
+
return createErrorResponse(ApiErrorCode.INVALID_INPUT, result.error.issues[0]?.message ?? 'Validation failed');
|
|
33
|
+
}
|
|
34
|
+
const updated = ctx.pushStore.updatePreferences(id, result.data.pushPreferences);
|
|
35
|
+
if (!updated) {
|
|
36
|
+
return createErrorResponse(ApiErrorCode.NOT_FOUND, 'Subscription not found');
|
|
37
|
+
}
|
|
38
|
+
return { success: true };
|
|
39
|
+
});
|
|
40
|
+
app.delete('/api/push/subscribe/:id', async (req) => {
|
|
41
|
+
const { id } = req.params;
|
|
42
|
+
const removed = ctx.pushStore.removeSubscription(id);
|
|
43
|
+
if (!removed) {
|
|
44
|
+
return createErrorResponse(ApiErrorCode.NOT_FOUND, 'Subscription not found');
|
|
45
|
+
}
|
|
46
|
+
return { success: true };
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=push-routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"push-routes.js","sourceRoot":"","sources":["../../../src/web/routes/push-routes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Ralph/todo-related routes.
|
|
3
|
+
* Ralph tracker config, circuit breaker, fix plan CRUD, ralph prompt writing,
|
|
4
|
+
* and the Ralph Loop start endpoint (autonomous task execution).
|
|
5
|
+
*/
|
|
6
|
+
import { FastifyInstance } from 'fastify';
|
|
7
|
+
import type { SessionPort, EventPort, RespawnPort, ConfigPort, InfraPort } from '../ports/index.js';
|
|
8
|
+
export declare function registerRalphRoutes(app: FastifyInstance, ctx: SessionPort & EventPort & RespawnPort & ConfigPort & InfraPort): void;
|
|
9
|
+
//# sourceMappingURL=ralph-routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ralph-routes.d.ts","sourceRoot":"","sources":["../../../src/web/routes/ralph-routes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAY1C,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAGpG,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,WAAW,GAAG,SAAS,GAAG,WAAW,GAAG,UAAU,GAAG,SAAS,GAClE,IAAI,CA4fN"}
|