tarsk 0.3.3 → 0.3.16
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/dist/cli.d.ts +3 -0
- package/dist/cli.js +22 -0
- package/dist/index.js +3 -2
- package/dist/public/assets/{index-DJC-p914.js → index-CLr9LKtA.js} +1679 -1682
- package/dist/public/index.html +1 -1
- package/node_modules/@neovate/code/LICENSE +21 -0
- package/node_modules/@neovate/code/README.md +56 -0
- package/node_modules/@neovate/code/dist/cli.mjs +714 -716
- package/node_modules/@neovate/code/dist/index.d.ts +0 -373
- package/node_modules/@neovate/code/dist/index.mjs +790 -792
- package/node_modules/@neovate/code/package.json +138 -2
- package/node_modules/@neovate/code/vendor/ripgrep/COPYING +3 -0
- package/node_modules/@neovate/code/vendor/ripgrep/arm64-darwin/rg +0 -0
- package/node_modules/@neovate/code/vendor/ripgrep/arm64-linux/rg +0 -0
- package/node_modules/@neovate/code/vendor/ripgrep/x64-darwin/rg +0 -0
- package/node_modules/@neovate/code/vendor/ripgrep/x64-linux/rg +0 -0
- package/node_modules/@neovate/code/vendor/ripgrep/x64-win32/rg.exe +0 -0
- package/package.json +2 -2
- package/dist/managers/ConversationManager.d.ts +0 -83
- package/dist/managers/ConversationManager.js +0 -129
- package/dist/managers/GitManager.d.ts +0 -133
- package/dist/managers/GitManager.js +0 -330
- package/dist/managers/MetadataManager.d.ts +0 -139
- package/dist/managers/MetadataManager.js +0 -309
- package/dist/managers/ModelManager.d.ts +0 -57
- package/dist/managers/ModelManager.js +0 -129
- package/dist/managers/NeovateExecutor.d.ts +0 -40
- package/dist/managers/NeovateExecutor.js +0 -138
- package/dist/managers/ProjectManager.d.ts +0 -162
- package/dist/managers/ProjectManager.js +0 -353
- package/dist/managers/ThreadManager.d.ts +0 -181
- package/dist/managers/ThreadManager.js +0 -325
- package/dist/model-info-openai.d.ts +0 -17
- package/dist/model-info-openai.js +0 -59
- package/dist/public/assets/index-B443aj9k.js +0 -8506
- package/dist/routes/chat-old.d.ts +0 -21
- package/dist/routes/chat-old.js +0 -251
- package/dist/routes/projects-old.d.ts +0 -20
- package/dist/routes/projects-old.js +0 -297
- package/dist/routes/threads-old.d.ts +0 -14
- package/dist/routes/threads-old.js +0 -393
- package/dist/utils/openai-pricing-scraper.d.ts +0 -17
- package/dist/utils/openai-pricing-scraper.js +0 -185
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Chat routes for the REST API
|
|
3
|
-
*
|
|
4
|
-
* Handles chat message processing:
|
|
5
|
-
* - POST /api/chat - Send a message to the agent
|
|
6
|
-
*/
|
|
7
|
-
import { Hono } from 'hono';
|
|
8
|
-
import { ThreadManager } from '../managers/thread-manager.js';
|
|
9
|
-
import { NeovateExecutor } from '../managers/neovate-executor.js';
|
|
10
|
-
import { ConversationManager } from '../managers/conversation-manager.js';
|
|
11
|
-
import { ProcessingStateManager } from '../managers/processing-state-manager.js';
|
|
12
|
-
/**
|
|
13
|
-
* Creates chat routes
|
|
14
|
-
* @param threadManager - The ThreadManager instance
|
|
15
|
-
* @param neovateExecutor - The NeovateExecutor instance
|
|
16
|
-
* @param conversationManager - The ConversationManager instance
|
|
17
|
-
* @param processingStateManager - The ProcessingStateManager instance
|
|
18
|
-
* @returns Hono router with chat routes
|
|
19
|
-
*/
|
|
20
|
-
export declare function createChatRoutes(threadManager: ThreadManager, neovateExecutor: NeovateExecutor, conversationManager: ConversationManager, processingStateManager: ProcessingStateManager): Hono;
|
|
21
|
-
//# sourceMappingURL=chat-old.d.ts.map
|
package/dist/routes/chat-old.js
DELETED
|
@@ -1,251 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Chat routes for the REST API
|
|
3
|
-
*
|
|
4
|
-
* Handles chat message processing:
|
|
5
|
-
* - POST /api/chat - Send a message to the agent
|
|
6
|
-
*/
|
|
7
|
-
import { Hono } from 'hono';
|
|
8
|
-
import { delay } from '../utils.js';
|
|
9
|
-
import { streamAsyncGenerator } from '../lib/stream-helper.js';
|
|
10
|
-
/**
|
|
11
|
-
* Creates chat routes
|
|
12
|
-
* @param threadManager - The ThreadManager instance
|
|
13
|
-
* @param neovateExecutor - The NeovateExecutor instance
|
|
14
|
-
* @param conversationManager - The ConversationManager instance
|
|
15
|
-
* @param processingStateManager - The ProcessingStateManager instance
|
|
16
|
-
* @returns Hono router with chat routes
|
|
17
|
-
*/
|
|
18
|
-
export function createChatRoutes(threadManager, neovateExecutor, conversationManager, processingStateManager) {
|
|
19
|
-
const router = new Hono();
|
|
20
|
-
/**
|
|
21
|
-
* POST /api/chat
|
|
22
|
-
* Send a message to the agent
|
|
23
|
-
*
|
|
24
|
-
* Request body:
|
|
25
|
-
* {
|
|
26
|
-
* "threadId": "uuid",
|
|
27
|
-
* "message": "User message content",
|
|
28
|
-
* "model": "model-name",
|
|
29
|
-
* "attachments": [
|
|
30
|
-
* {
|
|
31
|
-
* "name": "file.txt",
|
|
32
|
-
* "content": "base64-encoded-content",
|
|
33
|
-
* "size": 1024,
|
|
34
|
-
* "mimeType": "text/plain"
|
|
35
|
-
* }
|
|
36
|
-
* ]
|
|
37
|
-
* }
|
|
38
|
-
*
|
|
39
|
-
* Response: Newline-delimited JSON stream of NeovateEvent objects
|
|
40
|
-
*
|
|
41
|
-
* Requirements:
|
|
42
|
-
* - 6.4 - THE CLI SHALL expose REST API endpoints for chat message processing
|
|
43
|
-
* - 8.5 - WHEN sending a chat message, THE App SHALL send a POST request with the message content and Selected_Thread context to the CLI
|
|
44
|
-
* - 5.4 - WHEN the Neovate command executes, THE CLI SHALL stream the output back to the App
|
|
45
|
-
*/
|
|
46
|
-
router.post('/', async (c) => {
|
|
47
|
-
try {
|
|
48
|
-
const body = await c.req.json();
|
|
49
|
-
const { threadId, content, model: baseModel, provider, attachments, planMode } = body;
|
|
50
|
-
// Prepend provider name (lowercased) to the model if provider is provided
|
|
51
|
-
let model = baseModel;
|
|
52
|
-
if (provider && typeof provider === 'string') {
|
|
53
|
-
const providerPrefix = provider.toLowerCase();
|
|
54
|
-
// Only prepend if the model doesn't already start with this provider prefix
|
|
55
|
-
if (!model.startsWith(providerPrefix + '/')) {
|
|
56
|
-
model = `${providerPrefix}/${model}`;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
// Validate required fields
|
|
60
|
-
if (!threadId || typeof threadId !== 'string') {
|
|
61
|
-
const errorResponse = {
|
|
62
|
-
error: {
|
|
63
|
-
code: 'INVALID_REQUEST',
|
|
64
|
-
message: 'threadId is required and must be a string',
|
|
65
|
-
timestamp: new Date().toISOString()
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
return c.json(errorResponse, 400);
|
|
69
|
-
}
|
|
70
|
-
if (!content || typeof content !== 'string') {
|
|
71
|
-
const errorResponse = {
|
|
72
|
-
error: {
|
|
73
|
-
code: 'INVALID_REQUEST',
|
|
74
|
-
message: 'content is required and must be a string',
|
|
75
|
-
timestamp: new Date().toISOString()
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
return c.json(errorResponse, 400);
|
|
79
|
-
}
|
|
80
|
-
if (!model || typeof model !== 'string') {
|
|
81
|
-
const errorResponse = {
|
|
82
|
-
error: {
|
|
83
|
-
code: 'INVALID_REQUEST',
|
|
84
|
-
message: 'model is required and must be a string',
|
|
85
|
-
timestamp: new Date().toISOString()
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
return c.json(errorResponse, 400);
|
|
89
|
-
}
|
|
90
|
-
// Get thread metadata to build execution context
|
|
91
|
-
const thread = await threadManager.getThread(threadId);
|
|
92
|
-
if (!thread) {
|
|
93
|
-
const errorResponse = {
|
|
94
|
-
error: {
|
|
95
|
-
code: 'THREAD_NOT_FOUND',
|
|
96
|
-
message: `Thread not found: ${threadId}`,
|
|
97
|
-
timestamp: new Date().toISOString()
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
|
-
return c.json(errorResponse, 404);
|
|
101
|
-
}
|
|
102
|
-
// Capture thread path for use in generators
|
|
103
|
-
const threadPath = thread.path;
|
|
104
|
-
// Check if this is a replay request
|
|
105
|
-
if (content.trim().toLowerCase() === 'replay') {
|
|
106
|
-
console.log('[ChatRoute] Replay request detected');
|
|
107
|
-
// Get the last message from conversation history
|
|
108
|
-
const lastMessages = await conversationManager.getLastMessages(threadPath, 1);
|
|
109
|
-
if (lastMessages.length === 0) {
|
|
110
|
-
const errorResponse = {
|
|
111
|
-
error: {
|
|
112
|
-
code: 'NO_HISTORY',
|
|
113
|
-
message: 'No previous conversation found to replay',
|
|
114
|
-
timestamp: new Date().toISOString()
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
return c.json(errorResponse, 404);
|
|
118
|
-
}
|
|
119
|
-
const lastMessage = lastMessages[0];
|
|
120
|
-
// Check if message has a completed response
|
|
121
|
-
if (!lastMessage.response) {
|
|
122
|
-
const errorResponse = {
|
|
123
|
-
data: null,
|
|
124
|
-
error: {
|
|
125
|
-
code: 'NO_RESPONSE',
|
|
126
|
-
message: 'Previous message has no completed response to replay',
|
|
127
|
-
timestamp: new Date().toISOString()
|
|
128
|
-
}
|
|
129
|
-
};
|
|
130
|
-
return c.json(errorResponse, 404);
|
|
131
|
-
}
|
|
132
|
-
console.log('[ChatRoute] Replaying message:', {
|
|
133
|
-
messageId: lastMessage.id,
|
|
134
|
-
timestamp: lastMessage.timestamp,
|
|
135
|
-
eventCount: lastMessage.response.events.length,
|
|
136
|
-
});
|
|
137
|
-
// Extract response to ensure TypeScript narrowing
|
|
138
|
-
const response = lastMessage.response;
|
|
139
|
-
// Create a generator for replay events
|
|
140
|
-
async function* replayGenerator() {
|
|
141
|
-
// First, send a replay indicator event
|
|
142
|
-
const replayEvent = {
|
|
143
|
-
type: 'message',
|
|
144
|
-
role: 'system',
|
|
145
|
-
content: `🔄 Replaying previous conversation from ${lastMessage.timestamp}`
|
|
146
|
-
};
|
|
147
|
-
await delay(1000);
|
|
148
|
-
yield replayEvent;
|
|
149
|
-
// Then stream all the captured events
|
|
150
|
-
for (const event of response.events) {
|
|
151
|
-
console.log('[ChatRoute] Replaying event:', event);
|
|
152
|
-
await delay(1000);
|
|
153
|
-
yield event;
|
|
154
|
-
}
|
|
155
|
-
// Finally, send a completion indicator
|
|
156
|
-
const completeEvent = {
|
|
157
|
-
type: 'message',
|
|
158
|
-
role: 'system',
|
|
159
|
-
content: '✅ Replay complete'
|
|
160
|
-
};
|
|
161
|
-
await delay(1000);
|
|
162
|
-
yield completeEvent;
|
|
163
|
-
}
|
|
164
|
-
return streamAsyncGenerator(c, replayGenerator());
|
|
165
|
-
}
|
|
166
|
-
// Normal chat flow - capture and execute
|
|
167
|
-
// Build execution context
|
|
168
|
-
const context = {
|
|
169
|
-
threadId,
|
|
170
|
-
threadPath,
|
|
171
|
-
model,
|
|
172
|
-
provider,
|
|
173
|
-
attachments,
|
|
174
|
-
planMode,
|
|
175
|
-
};
|
|
176
|
-
console.log('[ChatRoute] Execution context:', {
|
|
177
|
-
threadId,
|
|
178
|
-
threadPath,
|
|
179
|
-
model,
|
|
180
|
-
planMode,
|
|
181
|
-
attachmentCount: attachments?.length || 0,
|
|
182
|
-
});
|
|
183
|
-
// Start capturing the conversation
|
|
184
|
-
const messageId = await conversationManager.startMessage(threadId, threadPath, content, model, attachments, planMode);
|
|
185
|
-
// Mark thread as processing
|
|
186
|
-
processingStateManager.setProcessing(threadId);
|
|
187
|
-
// Create a generator for chat execution events
|
|
188
|
-
async function* chatExecutionGenerator() {
|
|
189
|
-
const capturedEvents = [];
|
|
190
|
-
let fullContent = '';
|
|
191
|
-
try {
|
|
192
|
-
for await (const event of neovateExecutor.execute(content, context)) {
|
|
193
|
-
// Capture the event
|
|
194
|
-
capturedEvents.push(event);
|
|
195
|
-
// Accumulate content from message events
|
|
196
|
-
if (event.type === 'message' && event.content) {
|
|
197
|
-
fullContent += event.content;
|
|
198
|
-
}
|
|
199
|
-
// Yield the event for streaming
|
|
200
|
-
yield event;
|
|
201
|
-
}
|
|
202
|
-
// Complete the conversation message with captured data
|
|
203
|
-
await conversationManager.completeMessage(threadPath, messageId, fullContent, capturedEvents);
|
|
204
|
-
console.log('[ChatRoute] Conversation captured:', {
|
|
205
|
-
messageId,
|
|
206
|
-
eventCount: capturedEvents.length,
|
|
207
|
-
contentLength: fullContent.length,
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
catch (error) {
|
|
211
|
-
const errorEvent = {
|
|
212
|
-
type: 'error',
|
|
213
|
-
error: {
|
|
214
|
-
code: 'STREAM_ERROR',
|
|
215
|
-
message: error instanceof Error ? error.message : String(error),
|
|
216
|
-
details: error instanceof Error ? { stack: error.stack } : undefined
|
|
217
|
-
}
|
|
218
|
-
};
|
|
219
|
-
// Capture the error event too
|
|
220
|
-
capturedEvents.push(errorEvent);
|
|
221
|
-
yield errorEvent;
|
|
222
|
-
// Try to save the partial conversation even on error
|
|
223
|
-
try {
|
|
224
|
-
await conversationManager.completeMessage(threadPath, messageId, fullContent, capturedEvents);
|
|
225
|
-
}
|
|
226
|
-
catch (saveError) {
|
|
227
|
-
console.error('[ChatRoute] Failed to save partial conversation:', saveError);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
finally {
|
|
231
|
-
// Clear processing state when done
|
|
232
|
-
processingStateManager.clearProcessing(threadId);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
return streamAsyncGenerator(c, chatExecutionGenerator());
|
|
236
|
-
}
|
|
237
|
-
catch (error) {
|
|
238
|
-
const errorResponse = {
|
|
239
|
-
error: {
|
|
240
|
-
code: 'REQUEST_PARSE_ERROR',
|
|
241
|
-
message: 'Failed to parse request body',
|
|
242
|
-
details: error instanceof Error ? error.message : String(error),
|
|
243
|
-
timestamp: new Date().toISOString()
|
|
244
|
-
}
|
|
245
|
-
};
|
|
246
|
-
return c.json(errorResponse, 400);
|
|
247
|
-
}
|
|
248
|
-
});
|
|
249
|
-
return router;
|
|
250
|
-
}
|
|
251
|
-
//# sourceMappingURL=chat-old.js.map
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Project routes for the REST API
|
|
3
|
-
*
|
|
4
|
-
* Handles all project-related operations:
|
|
5
|
-
* - POST /api/projects - Create a new project
|
|
6
|
-
* - GET /api/projects - List all projects
|
|
7
|
-
* - GET /api/projects/:id - Get project details
|
|
8
|
-
* - DELETE /api/projects/:id - Delete a project
|
|
9
|
-
*/
|
|
10
|
-
import { Hono } from 'hono';
|
|
11
|
-
import { ProjectManager } from '../managers/project-manager.js';
|
|
12
|
-
import { ThreadManager } from '../managers/thread-manager.js';
|
|
13
|
-
/**
|
|
14
|
-
* Creates project routes
|
|
15
|
-
* @param projectManager - The ProjectManager instance
|
|
16
|
-
* @param threadManager - The ThreadManager instance
|
|
17
|
-
* @returns Hono router with project routes
|
|
18
|
-
*/
|
|
19
|
-
export declare function createProjectRoutes(projectManager: ProjectManager, threadManager: ThreadManager): Hono;
|
|
20
|
-
//# sourceMappingURL=projects-old.d.ts.map
|
|
@@ -1,297 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Project routes for the REST API
|
|
3
|
-
*
|
|
4
|
-
* Handles all project-related operations:
|
|
5
|
-
* - POST /api/projects - Create a new project
|
|
6
|
-
* - GET /api/projects - List all projects
|
|
7
|
-
* - GET /api/projects/:id - Get project details
|
|
8
|
-
* - DELETE /api/projects/:id - Delete a project
|
|
9
|
-
*/
|
|
10
|
-
import { Hono } from 'hono';
|
|
11
|
-
import { AVAILABLE_PROGRAMS } from '../types/models.js';
|
|
12
|
-
import { streamAsyncGenerator } from '../lib/stream-helper.js';
|
|
13
|
-
import { ResponseBuilder } from '../lib/response-builder.js';
|
|
14
|
-
/**
|
|
15
|
-
* Creates project routes
|
|
16
|
-
* @param projectManager - The ProjectManager instance
|
|
17
|
-
* @param threadManager - The ThreadManager instance
|
|
18
|
-
* @returns Hono router with project routes
|
|
19
|
-
*/
|
|
20
|
-
export function createProjectRoutes(projectManager, threadManager) {
|
|
21
|
-
const router = new Hono();
|
|
22
|
-
/**
|
|
23
|
-
* POST /api/projects
|
|
24
|
-
* Create a new project from a git URL
|
|
25
|
-
*
|
|
26
|
-
* Request body:
|
|
27
|
-
* {
|
|
28
|
-
* "gitUrl": "https://github.com/user/repo.git"
|
|
29
|
-
* }
|
|
30
|
-
*
|
|
31
|
-
* Response: Newline-delimited JSON stream of ProjectEvent objects
|
|
32
|
-
*
|
|
33
|
-
* Requirements:
|
|
34
|
-
* - 6.2 - THE App SHALL send a POST request with the git URL to the CLI
|
|
35
|
-
* - 8.2 - THE CLI SHALL support streaming responses to the client
|
|
36
|
-
*/
|
|
37
|
-
router.post('/', async (c) => {
|
|
38
|
-
try {
|
|
39
|
-
const body = await c.req.json();
|
|
40
|
-
const { gitUrl } = body;
|
|
41
|
-
// Validate gitUrl is provided
|
|
42
|
-
if (!gitUrl || typeof gitUrl !== 'string') {
|
|
43
|
-
const { response, statusCode } = ResponseBuilder.error('INVALID_REQUEST', 'gitUrl is required and must be a string', 400);
|
|
44
|
-
return c.json(response, statusCode);
|
|
45
|
-
}
|
|
46
|
-
// Stream the project creation events
|
|
47
|
-
return streamAsyncGenerator(c, projectManager.createProject(gitUrl));
|
|
48
|
-
}
|
|
49
|
-
catch (error) {
|
|
50
|
-
const { response, statusCode } = ResponseBuilder.error('REQUEST_PARSE_ERROR', 'Failed to parse request body', 400, error instanceof Error ? error.message : String(error));
|
|
51
|
-
return c.json(response, statusCode);
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
/**
|
|
55
|
-
* GET /api/projects
|
|
56
|
-
* List all projects with expanded threads
|
|
57
|
-
*
|
|
58
|
-
* Response:
|
|
59
|
-
* [
|
|
60
|
-
* {
|
|
61
|
-
* "projectId": "uuid",
|
|
62
|
-
* "gitUrl": "https://github.com/user/repo.git",
|
|
63
|
-
* "projectPath": "/path/to/project",
|
|
64
|
-
* "threads": [
|
|
65
|
-
* {
|
|
66
|
-
* "threadId": "uuid",
|
|
67
|
-
* "title": "thread-title",
|
|
68
|
-
* "path": "/path/to/thread",
|
|
69
|
-
* "isSelected": false
|
|
70
|
-
* }
|
|
71
|
-
* ]
|
|
72
|
-
* }
|
|
73
|
-
* ]
|
|
74
|
-
*
|
|
75
|
-
* Requirements:
|
|
76
|
-
* - 6.2 - THE CLI SHALL expose REST API endpoints for Project operations
|
|
77
|
-
*/
|
|
78
|
-
router.get('/', async (c) => {
|
|
79
|
-
try {
|
|
80
|
-
const projects = await projectManager.listProjects();
|
|
81
|
-
// Get the currently selected thread
|
|
82
|
-
const selectedThreadId = await threadManager.getSelectedThreadId();
|
|
83
|
-
// Expand threads for each project
|
|
84
|
-
const expandedProjects = await Promise.all(projects.map(async (project) => {
|
|
85
|
-
const threads = await threadManager.listThreads(project.id);
|
|
86
|
-
return {
|
|
87
|
-
projectId: project.id,
|
|
88
|
-
gitUrl: project.gitUrl,
|
|
89
|
-
projectPath: project.path,
|
|
90
|
-
openWith: project.openWith,
|
|
91
|
-
threads: threads.map(thread => ({
|
|
92
|
-
threadId: thread.id,
|
|
93
|
-
title: thread.title,
|
|
94
|
-
path: thread.path,
|
|
95
|
-
isSelected: thread.id === selectedThreadId
|
|
96
|
-
}))
|
|
97
|
-
};
|
|
98
|
-
}));
|
|
99
|
-
return c.json(expandedProjects);
|
|
100
|
-
}
|
|
101
|
-
catch (error) {
|
|
102
|
-
const { response, statusCode } = ResponseBuilder.error('LIST_PROJECTS_ERROR', 'Failed to list projects', 500, error instanceof Error ? error.message : String(error));
|
|
103
|
-
return c.json(response, statusCode);
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
/**
|
|
107
|
-
* GET /api/projects/:id
|
|
108
|
-
* Get project details by ID
|
|
109
|
-
*
|
|
110
|
-
* Response:
|
|
111
|
-
* {
|
|
112
|
-
* "id": "uuid",
|
|
113
|
-
* "name": "project-name",
|
|
114
|
-
* "gitUrl": "https://github.com/user/repo.git",
|
|
115
|
-
* "path": "/path/to/project",
|
|
116
|
-
* "createdAt": "2024-01-01T00:00:00Z",
|
|
117
|
-
* "threads": ["thread-id-1", "thread-id-2"]
|
|
118
|
-
* }
|
|
119
|
-
*
|
|
120
|
-
* Requirements:
|
|
121
|
-
* - 6.2 - THE CLI SHALL expose REST API endpoints for Project operations
|
|
122
|
-
*/
|
|
123
|
-
router.get('/:id', async (c) => {
|
|
124
|
-
try {
|
|
125
|
-
const projectId = c.req.param('id');
|
|
126
|
-
if (!projectId) {
|
|
127
|
-
const { response, statusCode } = ResponseBuilder.error('INVALID_REQUEST', 'Project ID is required', 400);
|
|
128
|
-
return c.json(response, statusCode);
|
|
129
|
-
}
|
|
130
|
-
const project = await projectManager.getProject(projectId);
|
|
131
|
-
if (!project) {
|
|
132
|
-
const { response, statusCode } = ResponseBuilder.error('PROJECT_NOT_FOUND', `Project not found: ${projectId}`, 404);
|
|
133
|
-
return c.json(response, statusCode);
|
|
134
|
-
}
|
|
135
|
-
return c.json(project);
|
|
136
|
-
}
|
|
137
|
-
catch (error) {
|
|
138
|
-
const { response, statusCode } = ResponseBuilder.error('GET_PROJECT_ERROR', 'Failed to get project', 500, error instanceof Error ? error.message : String(error));
|
|
139
|
-
return c.json(response, statusCode);
|
|
140
|
-
}
|
|
141
|
-
});
|
|
142
|
-
/**
|
|
143
|
-
* DELETE /api/projects/:id
|
|
144
|
-
* Delete a project and all its threads
|
|
145
|
-
*
|
|
146
|
-
* Response:
|
|
147
|
-
* {
|
|
148
|
-
* "success": true,
|
|
149
|
-
* "message": "Project deleted successfully"
|
|
150
|
-
* }
|
|
151
|
-
*
|
|
152
|
-
* Requirements:
|
|
153
|
-
* - 6.2 - THE CLI SHALL expose REST API endpoints for Project operations
|
|
154
|
-
*/
|
|
155
|
-
router.delete('/:id', async (c) => {
|
|
156
|
-
try {
|
|
157
|
-
const projectId = c.req.param('id');
|
|
158
|
-
if (!projectId) {
|
|
159
|
-
const { response, statusCode } = ResponseBuilder.error('INVALID_REQUEST', 'Project ID is required', 400);
|
|
160
|
-
return c.json(response, statusCode);
|
|
161
|
-
}
|
|
162
|
-
await projectManager.deleteProject(projectId);
|
|
163
|
-
const { response, statusCode } = ResponseBuilder.success({ success: true, message: 'Project deleted successfully' });
|
|
164
|
-
return c.json(response, statusCode);
|
|
165
|
-
}
|
|
166
|
-
catch (error) {
|
|
167
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
168
|
-
// Check if it's a "not found" error
|
|
169
|
-
if (errorMessage.includes('not found')) {
|
|
170
|
-
const { response, statusCode } = ResponseBuilder.error('PROJECT_NOT_FOUND', errorMessage, 404);
|
|
171
|
-
return c.json(response, statusCode);
|
|
172
|
-
}
|
|
173
|
-
const { response, statusCode } = ResponseBuilder.error('DELETE_PROJECT_ERROR', 'Failed to delete project', 500, errorMessage);
|
|
174
|
-
return c.json(response, statusCode);
|
|
175
|
-
}
|
|
176
|
-
});
|
|
177
|
-
/**
|
|
178
|
-
* POST /api/projects/:id/open
|
|
179
|
-
* Open a project in the specified program
|
|
180
|
-
*
|
|
181
|
-
* Request body:
|
|
182
|
-
* {
|
|
183
|
-
* "program": "VS Code" | "Cursor" | "Windsurf" | "Xcode" | "Android Studio" | "Kiro"
|
|
184
|
-
* }
|
|
185
|
-
*
|
|
186
|
-
* Response:
|
|
187
|
-
* {
|
|
188
|
-
* "success": true,
|
|
189
|
-
* "message": "Project opened in VS Code"
|
|
190
|
-
* }
|
|
191
|
-
*/
|
|
192
|
-
router.post('/:id/open', async (c) => {
|
|
193
|
-
try {
|
|
194
|
-
const projectId = c.req.param('id');
|
|
195
|
-
const body = await c.req.json();
|
|
196
|
-
const { program } = body;
|
|
197
|
-
if (!projectId) {
|
|
198
|
-
const errorResponse = {
|
|
199
|
-
error: {
|
|
200
|
-
code: 'INVALID_REQUEST',
|
|
201
|
-
message: 'Project ID is required',
|
|
202
|
-
timestamp: new Date().toISOString()
|
|
203
|
-
}
|
|
204
|
-
};
|
|
205
|
-
return c.json(errorResponse, 400);
|
|
206
|
-
}
|
|
207
|
-
if (!program) {
|
|
208
|
-
const errorResponse = {
|
|
209
|
-
error: {
|
|
210
|
-
code: 'INVALID_REQUEST',
|
|
211
|
-
message: 'Program is required',
|
|
212
|
-
timestamp: new Date().toISOString()
|
|
213
|
-
}
|
|
214
|
-
};
|
|
215
|
-
return c.json(errorResponse, 400);
|
|
216
|
-
}
|
|
217
|
-
if (!AVAILABLE_PROGRAMS.includes(program)) {
|
|
218
|
-
const errorResponse = {
|
|
219
|
-
error: {
|
|
220
|
-
code: 'INVALID_REQUEST',
|
|
221
|
-
message: `Invalid program. Must be one of: ${AVAILABLE_PROGRAMS.join(', ')}`,
|
|
222
|
-
timestamp: new Date().toISOString()
|
|
223
|
-
}
|
|
224
|
-
};
|
|
225
|
-
return c.json(errorResponse, 400);
|
|
226
|
-
}
|
|
227
|
-
const project = await projectManager.getProject(projectId);
|
|
228
|
-
if (!project) {
|
|
229
|
-
const errorResponse = {
|
|
230
|
-
error: {
|
|
231
|
-
code: 'PROJECT_NOT_FOUND',
|
|
232
|
-
message: `Project not found: ${projectId}`,
|
|
233
|
-
timestamp: new Date().toISOString()
|
|
234
|
-
}
|
|
235
|
-
};
|
|
236
|
-
return c.json(errorResponse, 404);
|
|
237
|
-
}
|
|
238
|
-
await projectManager.openWith(projectId, program);
|
|
239
|
-
const { response, statusCode } = ResponseBuilder.success({ success: true, message: `Project opened in ${program}` });
|
|
240
|
-
return c.json(response, statusCode);
|
|
241
|
-
}
|
|
242
|
-
catch (error) {
|
|
243
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
244
|
-
const { response, statusCode } = ResponseBuilder.error('OPEN_PROGRAM_ERROR', 'Failed to open project', 500, errorMessage);
|
|
245
|
-
return c.json(response, statusCode);
|
|
246
|
-
}
|
|
247
|
-
});
|
|
248
|
-
/**
|
|
249
|
-
* PUT /api/projects/:id/open-with
|
|
250
|
-
* Update the project's open-with program preference
|
|
251
|
-
*
|
|
252
|
-
* Request body:
|
|
253
|
-
* {
|
|
254
|
-
* "program": "VS Code" | "Cursor" | "Windsurf" | "Xcode" | "Android Studio" | "Kiro"
|
|
255
|
-
* }
|
|
256
|
-
*
|
|
257
|
-
* Response:
|
|
258
|
-
* {
|
|
259
|
-
* "success": true,
|
|
260
|
-
* "message": "Open-with program updated"
|
|
261
|
-
* }
|
|
262
|
-
*/
|
|
263
|
-
router.put('/:id/open-with', async (c) => {
|
|
264
|
-
try {
|
|
265
|
-
const projectId = c.req.param('id');
|
|
266
|
-
const body = await c.req.json();
|
|
267
|
-
const { program } = body;
|
|
268
|
-
if (!projectId) {
|
|
269
|
-
const { response, statusCode } = ResponseBuilder.error('INVALID_REQUEST', 'Project ID is required', 400);
|
|
270
|
-
return c.json(response, statusCode);
|
|
271
|
-
}
|
|
272
|
-
if (!program) {
|
|
273
|
-
const { response, statusCode } = ResponseBuilder.error('INVALID_REQUEST', 'Program is required', 400);
|
|
274
|
-
return c.json(response, statusCode);
|
|
275
|
-
}
|
|
276
|
-
if (!AVAILABLE_PROGRAMS.includes(program)) {
|
|
277
|
-
const { response, statusCode } = ResponseBuilder.error('INVALID_REQUEST', `Invalid program. Must be one of: ${AVAILABLE_PROGRAMS.join(', ')}`, 400);
|
|
278
|
-
return c.json(response, statusCode);
|
|
279
|
-
}
|
|
280
|
-
const project = await projectManager.getProject(projectId);
|
|
281
|
-
if (!project) {
|
|
282
|
-
const { response, statusCode } = ResponseBuilder.error('PROJECT_NOT_FOUND', `Project not found: ${projectId}`, 404);
|
|
283
|
-
return c.json(response, statusCode);
|
|
284
|
-
}
|
|
285
|
-
await projectManager.updateOpenWith(projectId, program);
|
|
286
|
-
const { response, statusCode } = ResponseBuilder.success({ success: true, message: 'Open-with program updated' });
|
|
287
|
-
return c.json(response, statusCode);
|
|
288
|
-
}
|
|
289
|
-
catch (error) {
|
|
290
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
291
|
-
const { response, statusCode } = ResponseBuilder.error('UPDATE_PROGRAM_ERROR', 'Failed to update open-with program', 500, errorMessage);
|
|
292
|
-
return c.json(response, statusCode);
|
|
293
|
-
}
|
|
294
|
-
});
|
|
295
|
-
return router;
|
|
296
|
-
}
|
|
297
|
-
//# sourceMappingURL=projects-old.js.map
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Thread routes for the REST API
|
|
3
|
-
*
|
|
4
|
-
* Handles all thread-related operations:
|
|
5
|
-
* - POST /api/threads - Create a new thread
|
|
6
|
-
* - GET /api/threads?projectId=xxx - List threads for a project
|
|
7
|
-
* - DELETE /api/threads/:id - Delete a thread
|
|
8
|
-
*/
|
|
9
|
-
import { Hono } from 'hono';
|
|
10
|
-
import type { ThreadManager } from '../managers/thread-manager.js';
|
|
11
|
-
import type { ConversationManager } from '../managers/conversation-manager.js';
|
|
12
|
-
import type { GitManager } from '../managers/git-manager.js';
|
|
13
|
-
export declare function createThreadRoutes(threadManager: ThreadManager, gitManager: GitManager, conversationManager: ConversationManager): Hono;
|
|
14
|
-
//# sourceMappingURL=threads-old.d.ts.map
|