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.
Files changed (43) hide show
  1. package/dist/cli.d.ts +3 -0
  2. package/dist/cli.js +22 -0
  3. package/dist/index.js +3 -2
  4. package/dist/public/assets/{index-DJC-p914.js → index-CLr9LKtA.js} +1679 -1682
  5. package/dist/public/index.html +1 -1
  6. package/node_modules/@neovate/code/LICENSE +21 -0
  7. package/node_modules/@neovate/code/README.md +56 -0
  8. package/node_modules/@neovate/code/dist/cli.mjs +714 -716
  9. package/node_modules/@neovate/code/dist/index.d.ts +0 -373
  10. package/node_modules/@neovate/code/dist/index.mjs +790 -792
  11. package/node_modules/@neovate/code/package.json +138 -2
  12. package/node_modules/@neovate/code/vendor/ripgrep/COPYING +3 -0
  13. package/node_modules/@neovate/code/vendor/ripgrep/arm64-darwin/rg +0 -0
  14. package/node_modules/@neovate/code/vendor/ripgrep/arm64-linux/rg +0 -0
  15. package/node_modules/@neovate/code/vendor/ripgrep/x64-darwin/rg +0 -0
  16. package/node_modules/@neovate/code/vendor/ripgrep/x64-linux/rg +0 -0
  17. package/node_modules/@neovate/code/vendor/ripgrep/x64-win32/rg.exe +0 -0
  18. package/package.json +2 -2
  19. package/dist/managers/ConversationManager.d.ts +0 -83
  20. package/dist/managers/ConversationManager.js +0 -129
  21. package/dist/managers/GitManager.d.ts +0 -133
  22. package/dist/managers/GitManager.js +0 -330
  23. package/dist/managers/MetadataManager.d.ts +0 -139
  24. package/dist/managers/MetadataManager.js +0 -309
  25. package/dist/managers/ModelManager.d.ts +0 -57
  26. package/dist/managers/ModelManager.js +0 -129
  27. package/dist/managers/NeovateExecutor.d.ts +0 -40
  28. package/dist/managers/NeovateExecutor.js +0 -138
  29. package/dist/managers/ProjectManager.d.ts +0 -162
  30. package/dist/managers/ProjectManager.js +0 -353
  31. package/dist/managers/ThreadManager.d.ts +0 -181
  32. package/dist/managers/ThreadManager.js +0 -325
  33. package/dist/model-info-openai.d.ts +0 -17
  34. package/dist/model-info-openai.js +0 -59
  35. package/dist/public/assets/index-B443aj9k.js +0 -8506
  36. package/dist/routes/chat-old.d.ts +0 -21
  37. package/dist/routes/chat-old.js +0 -251
  38. package/dist/routes/projects-old.d.ts +0 -20
  39. package/dist/routes/projects-old.js +0 -297
  40. package/dist/routes/threads-old.d.ts +0 -14
  41. package/dist/routes/threads-old.js +0 -393
  42. package/dist/utils/openai-pricing-scraper.d.ts +0 -17
  43. package/dist/utils/openai-pricing-scraper.js +0 -185
@@ -1,325 +0,0 @@
1
- /**
2
- * ThreadManager handles thread lifecycle and metadata management
3
- *
4
- * This manager is responsible for:
5
- * - Creating new threads for existing projects
6
- * - Managing thread metadata
7
- * - Coordinating with GitManager for repository cloning
8
- * - Providing CRUD operations for threads
9
- * - Ensuring thread path uniqueness
10
- */
11
- import { randomUUID } from 'crypto';
12
- import { join } from 'path';
13
- /**
14
- * ThreadManagerImpl provides the implementation for thread operations
15
- */
16
- export class ThreadManagerImpl {
17
- metadataManager;
18
- gitManager;
19
- /**
20
- * Create a new ThreadManager
21
- * @param metadataManager - Manager for persisting metadata
22
- * @param gitManager - Manager for git operations
23
- *
24
- * Requirements:
25
- * - 2.1 - WHEN a user creates a new Thread for a Project, THE CLI SHALL create a new clone of the Project's git repository
26
- * - 2.4 - THE System SHALL maintain a title for each Thread
27
- */
28
- constructor(metadataManager, gitManager) {
29
- this.metadataManager = metadataManager;
30
- this.gitManager = gitManager;
31
- }
32
- /**
33
- * Creates a new thread for an existing project
34
- *
35
- * This method:
36
- * 1. Validates that the project exists
37
- * 2. Generates a unique thread ID
38
- * 3. Gets the project's git URL
39
- * 4. Generates a unique thread path
40
- * 5. Delegates to GitManager for cloning
41
- * 6. Saves thread metadata
42
- * 7. Updates the project's thread list
43
- * 8. Yields progress events during the operation
44
- *
45
- * @param projectId - The parent project ID
46
- * @param title - Optional thread title (auto-generated if not provided)
47
- * @yields ThreadEvent objects during the creation process
48
- *
49
- * Requirements:
50
- * - 2.1 - WHEN a user creates a new Thread for a Project, THE CLI SHALL create a new clone of the Project's git repository
51
- * - 2.2 - WHEN a Thread is created, THE App SHALL display it under its parent Project in the Side_Panel
52
- * - 2.4 - THE System SHALL maintain a title for each Thread
53
- * - 7.4 - THE CLI SHALL ensure each Thread clone is stored in a unique directory path
54
- */
55
- async *createThread(projectId, title) {
56
- try {
57
- // Load project to verify it exists and get git URL
58
- const projects = await this.metadataManager.loadProjects();
59
- const project = projects.find(p => p.id === projectId);
60
- if (!project) {
61
- yield {
62
- type: 'error',
63
- message: `Project not found: ${projectId}`
64
- };
65
- return;
66
- }
67
- // Generate unique thread ID
68
- const threadId = randomUUID();
69
- // Generate thread path: {projectPath}/{threadId}
70
- const threadPath = this.generateThreadPath(project.path, threadId);
71
- // Generate thread title if not provided
72
- const existingThreads = await this.metadataManager.loadThreads();
73
- const existingTitles = new Set(existingThreads
74
- .filter(t => t.projectId === projectId)
75
- .map(t => t.title));
76
- const threadTitle = title || this.generateThreadTitle(existingTitles, threadId, project.name);
77
- yield {
78
- type: 'progress',
79
- message: `Creating thread "${threadTitle}" for project "${project.name}"...`
80
- };
81
- yield {
82
- type: 'progress',
83
- message: `Cloning repository to ${threadPath}...`
84
- };
85
- // Stream git clone events
86
- for await (const gitEvent of this.gitManager.cloneRepository(project.gitUrl, threadPath)) {
87
- if (gitEvent.type === 'error') {
88
- yield {
89
- type: 'error',
90
- message: `Git clone failed: ${gitEvent.message}`
91
- };
92
- return;
93
- }
94
- else if (gitEvent.type === 'stdout' || gitEvent.type === 'stderr') {
95
- yield {
96
- type: 'progress',
97
- message: gitEvent.data
98
- };
99
- }
100
- }
101
- // Sanitize the thread title to create a valid branch name
102
- let branchName = this.gitManager.sanitizeBranchName(threadTitle);
103
- yield {
104
- type: 'progress',
105
- message: `Creating branch "${branchName}"...`
106
- };
107
- // Check if branch exists and find a unique name if needed
108
- let branchExists = await this.gitManager.checkBranchExists(threadPath, branchName);
109
- let counter = 2;
110
- const baseBranchName = branchName;
111
- while (branchExists) {
112
- branchName = `${baseBranchName}-${counter}`;
113
- branchExists = await this.gitManager.checkBranchExists(threadPath, branchName);
114
- counter++;
115
- }
116
- if (branchName !== baseBranchName) {
117
- yield {
118
- type: 'progress',
119
- message: `Branch "${baseBranchName}" exists, using "${branchName}" instead`
120
- };
121
- }
122
- // Create and checkout the new branch
123
- for await (const gitEvent of this.gitManager.createAndCheckoutBranch(threadPath, branchName)) {
124
- if (gitEvent.type === 'error') {
125
- yield {
126
- type: 'error',
127
- message: `Failed to create branch: ${gitEvent.message}`
128
- };
129
- return;
130
- }
131
- else if (gitEvent.type === 'stdout' || gitEvent.type === 'stderr') {
132
- yield {
133
- type: 'progress',
134
- message: gitEvent.data
135
- };
136
- }
137
- }
138
- yield {
139
- type: 'progress',
140
- message: `Branch "${branchName}" created and checked out`
141
- };
142
- // Create thread metadata
143
- const thread = {
144
- id: threadId,
145
- projectId,
146
- title: threadTitle,
147
- path: threadPath,
148
- currentBranch: branchName,
149
- createdAt: new Date()
150
- };
151
- // Save thread metadata
152
- const threads = await this.metadataManager.loadThreads();
153
- threads.push(thread);
154
- await this.metadataManager.saveThreads(threads);
155
- // Update project's thread list
156
- project.threads.push(threadId);
157
- const updatedProjects = projects.map(p => p.id === projectId ? project : p);
158
- await this.metadataManager.saveProjects(updatedProjects);
159
- yield {
160
- type: 'progress',
161
- message: `Thread "${threadTitle}" created successfully`
162
- };
163
- // Yield complete event with thread data
164
- yield {
165
- type: 'complete',
166
- message: 'Thread creation complete',
167
- thread
168
- };
169
- }
170
- catch (error) {
171
- yield {
172
- type: 'error',
173
- message: `Failed to create thread: ${error instanceof Error ? error.message : String(error)}`
174
- };
175
- }
176
- }
177
- /**
178
- * Gets a thread by ID
179
- * @param threadId - The thread ID
180
- * @returns The thread or null if not found
181
- */
182
- async getThread(threadId) {
183
- const threads = await this.metadataManager.loadThreads();
184
- return threads.find(t => t.id === threadId) || null;
185
- }
186
- /**
187
- * Lists all threads for a specific project
188
- * @param projectId - The project ID to filter threads
189
- * @returns Array of threads for the project
190
- *
191
- * Requirements:
192
- * - 2.1 - WHEN a Thread is created, THE App SHALL display it under its parent Project in the Side_Panel
193
- */
194
- async listThreads(projectId) {
195
- const threads = await this.metadataManager.loadThreads();
196
- return threads.filter(t => t.projectId === projectId);
197
- }
198
- /**
199
- * Deletes a thread and removes its directory
200
- *
201
- * This method:
202
- * 1. Finds the thread by ID
203
- * 2. Removes the thread directory from filesystem
204
- * 3. Removes the thread from metadata
205
- * 4. Updates the parent project's thread list
206
- *
207
- * @param threadId - The thread ID to delete
208
- * @throws Error if thread not found
209
- *
210
- * Requirements:
211
- * - 2.3 - WHEN a user deletes a Thread, THE System SHALL remove the Thread's folder and update the Side_Panel display
212
- * - 7.5 - WHEN a Thread is deleted, THE CLI SHALL remove the associated git repository clone from the filesystem
213
- */
214
- async deleteThread(threadId) {
215
- const threads = await this.metadataManager.loadThreads();
216
- const threadIndex = threads.findIndex(t => t.id === threadId);
217
- if (threadIndex === -1) {
218
- throw new Error(`Thread not found: ${threadId}`);
219
- }
220
- const thread = threads[threadIndex];
221
- // Remove thread directory from filesystem
222
- try {
223
- const { rm } = await import('fs/promises');
224
- await rm(thread.path, { recursive: true, force: true });
225
- }
226
- catch (error) {
227
- throw new Error(`Failed to remove thread directory: ${error instanceof Error ? error.message : String(error)}`);
228
- }
229
- // Remove thread from metadata
230
- threads.splice(threadIndex, 1);
231
- await this.metadataManager.saveThreads(threads);
232
- // Update parent project's thread list
233
- const projects = await this.metadataManager.loadProjects();
234
- const project = projects.find(p => p.id === thread.projectId);
235
- if (project) {
236
- project.threads = project.threads.filter(id => id !== threadId);
237
- await this.metadataManager.saveProjects(projects);
238
- }
239
- }
240
- /**
241
- * Updates a thread's metadata with partial data
242
- *
243
- * This method loads all threads, finds the target, merges the updates,
244
- * and persists the result.
245
- *
246
- * @param threadId - The thread ID to update
247
- * @param updates - Partial thread data to merge
248
- * @throws Error if thread not found
249
- */
250
- async updateThread(threadId, updates) {
251
- const threads = await this.metadataManager.loadThreads();
252
- const threadIndex = threads.findIndex(t => t.id === threadId);
253
- if (threadIndex === -1) {
254
- throw new Error(`Thread not found: ${threadId}`);
255
- }
256
- threads[threadIndex] = { ...threads[threadIndex], ...updates };
257
- await this.metadataManager.saveThreads(threads);
258
- }
259
- /**
260
- * Selects a thread as the active thread
261
- *
262
- * @param threadId - The thread ID to select
263
- */
264
- async selectThread(threadId) {
265
- await this.metadataManager.setSelectedThread(threadId);
266
- }
267
- /**
268
- * Gets the currently selected thread ID
269
- *
270
- * @returns The selected thread ID or null
271
- */
272
- async getSelectedThreadId() {
273
- return await this.metadataManager.getSelectedThread();
274
- }
275
- /**
276
- * Generates a unique thread path
277
- *
278
- * Path format: {projectPath}/{threadId}
279
- *
280
- * This ensures thread paths are unique across all projects and threads.
281
- *
282
- * @param projectPath - The parent project path
283
- * @param threadId - The thread ID
284
- * @returns The absolute path to the thread folder
285
- *
286
- * Requirements:
287
- * - 7.4 - THE CLI SHALL ensure each Thread clone is stored in a unique directory path
288
- */
289
- generateThreadPath(projectPath, threadId) {
290
- return join(projectPath, threadId);
291
- }
292
- /**
293
- * Generates a thread title if not provided
294
- *
295
- * Format: project-name Thread word1-word2
296
- *
297
- * @param existingTitles - Set of titles already in use
298
- * @param threadId - Thread ID used as a fallback
299
- * @param projectName - Optional project name to include in title
300
- * @returns The generated thread title
301
- */
302
- generateThreadTitle(existingTitles, threadId, projectName) {
303
- const wordsA = [
304
- 'amber', 'brisk', 'calm', 'drift', 'ember', 'frost', 'glow', 'hollow',
305
- 'ivory', 'jolly', 'keen', 'lucid', 'mellow', 'noble', 'opal', 'prism',
306
- 'quiet', 'ripple', 'sunny', 'timber', 'ultra', 'vivid', 'wisp', 'zen'
307
- ];
308
- const wordsB = [
309
- 'arch', 'bay', 'crest', 'dune', 'echo', 'fjord', 'glen', 'harbor',
310
- 'isle', 'jewel', 'knoll', 'lagoon', 'mesa', 'nest', 'oasis', 'peak',
311
- 'quarry', 'reef', 'strand', 'trail', 'vale', 'wharf', 'yard', 'zephyr'
312
- ];
313
- const prefix = projectName ? `${projectName} Thread ` : 'Thread ';
314
- for (let attempt = 0; attempt < 12; attempt += 1) {
315
- const word1 = wordsA[Math.floor(Math.random() * wordsA.length)];
316
- const word2 = wordsB[Math.floor(Math.random() * wordsB.length)];
317
- const candidate = `${prefix}${word1}-${word2}`;
318
- if (!existingTitles.has(candidate)) {
319
- return candidate;
320
- }
321
- }
322
- return `${prefix}${threadId.slice(0, 8)}`;
323
- }
324
- }
325
- //# sourceMappingURL=ThreadManager.js.map
@@ -1,17 +0,0 @@
1
- /**
2
- * OpenAI model info
3
- *
4
- * Provides model information (name, description) for OpenAI models.
5
- * Pricing is scraped from OpenAI's pricing page and cached locally for 24 hours.
6
- * Model names and descriptions are generated from model IDs (no API call needed).
7
- */
8
- import type { ModelInfo } from './model-info.js';
9
- /**
10
- * Get model info for OpenAI models
11
- *
12
- * @param modelIds - List of model IDs to get info for
13
- * @param cacheDir - Directory for caching pricing data (e.g., .metadata)
14
- * @returns Map of model ID -> ModelInfo (with name, description, and pricing if available)
15
- */
16
- export declare function getOpenAIModelInfo(modelIds: string[], cacheDir?: string): Promise<Map<string, ModelInfo>>;
17
- //# sourceMappingURL=model-info-openai.d.ts.map
@@ -1,59 +0,0 @@
1
- /**
2
- * OpenAI model info
3
- *
4
- * Provides model information (name, description) for OpenAI models.
5
- * Pricing is scraped from OpenAI's pricing page and cached locally for 24 hours.
6
- * Model names and descriptions are generated from model IDs (no API call needed).
7
- */
8
- import { getOpenAIPricing } from './utils/openai-pricing-scraper.js';
9
- /** Format OpenAI model id to a readable name (e.g. "gpt-4-turbo" -> "GPT-4 Turbo") */
10
- function formatOpenAIModelName(modelId) {
11
- return modelId
12
- .split('-')
13
- .map((part) => {
14
- if (part === 'gpt')
15
- return 'GPT';
16
- if (part === 'o')
17
- return 'O';
18
- if (part === part.toLowerCase() && /^\d+/.test(part)) {
19
- return part.charAt(0).toUpperCase() + part.slice(1);
20
- }
21
- return part.charAt(0).toUpperCase() + part.slice(1).toLowerCase();
22
- })
23
- .join(' ')
24
- .replace(/\s+/g, ' ');
25
- }
26
- /**
27
- * Get model info for OpenAI models
28
- *
29
- * @param modelIds - List of model IDs to get info for
30
- * @param cacheDir - Directory for caching pricing data (e.g., .metadata)
31
- * @returns Map of model ID -> ModelInfo (with name, description, and pricing if available)
32
- */
33
- export async function getOpenAIModelInfo(modelIds, cacheDir) {
34
- const result = new Map();
35
- // Fetch pricing from scraper if cache directory provided
36
- let pricingByModel = new Map();
37
- if (cacheDir) {
38
- try {
39
- pricingByModel = await getOpenAIPricing(cacheDir);
40
- console.log('[OpenAI Models] Loaded pricing for', pricingByModel.size, 'models');
41
- }
42
- catch (error) {
43
- console.error('[OpenAI Models] Error fetching pricing:', error);
44
- }
45
- }
46
- // Generate model info for each requested model ID
47
- for (const id of modelIds) {
48
- const modelInfo = {
49
- name: formatOpenAIModelName(id),
50
- description: `OpenAI model: ${id}`,
51
- pricing: pricingByModel.get(id),
52
- };
53
- console.log(`[OpenAI Models] Model ${id}:`, modelInfo);
54
- result.set(id, modelInfo);
55
- }
56
- console.log('[OpenAI Models] Generated info for', result.size, 'models');
57
- return result;
58
- }
59
- //# sourceMappingURL=model-info-openai.js.map