tarsk 0.2.5 → 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 +1 -7
- package/dist/index.d.ts +3 -0
- package/dist/index.js +92 -32
- package/dist/lib/response-builder.d.ts +50 -0
- package/dist/lib/response-builder.js +56 -0
- package/dist/lib/stream-helper.d.ts +39 -0
- package/dist/lib/stream-helper.js +43 -0
- package/dist/managers/ConversationManager.d.ts +83 -0
- package/dist/managers/ConversationManager.js +129 -0
- package/dist/managers/GitManager.d.ts +133 -0
- package/dist/managers/GitManager.js +330 -0
- package/dist/managers/MetadataManager.d.ts +139 -0
- package/dist/managers/MetadataManager.js +309 -0
- package/dist/managers/ModelManager.d.ts +57 -0
- package/dist/managers/ModelManager.js +129 -0
- package/dist/managers/NeovateExecutor.d.ts +40 -0
- package/dist/managers/NeovateExecutor.js +138 -0
- package/dist/managers/ProjectManager.d.ts +162 -0
- package/dist/managers/ProjectManager.js +353 -0
- package/dist/managers/ThreadManager.d.ts +181 -0
- package/dist/managers/ThreadManager.js +325 -0
- package/dist/managers/conversation-manager.d.ts +83 -0
- package/dist/managers/conversation-manager.js +129 -0
- package/dist/managers/git-manager.d.ts +133 -0
- package/dist/managers/git-manager.js +330 -0
- package/dist/managers/metadata-manager.d.ts +139 -0
- package/dist/managers/metadata-manager.js +305 -0
- package/dist/managers/model-manager.d.ts +59 -0
- package/dist/managers/model-manager.js +144 -0
- package/dist/managers/neovate-executor.d.ts +43 -0
- package/dist/managers/neovate-executor.js +205 -0
- package/dist/managers/processing-state-manager.d.ts +40 -0
- package/dist/managers/processing-state-manager.js +27 -0
- package/dist/managers/project-manager.d.ts +199 -0
- package/dist/managers/project-manager.js +465 -0
- package/dist/managers/thread-manager.d.ts +193 -0
- package/dist/managers/thread-manager.js +368 -0
- package/dist/model-info-aihubmix.d.ts +25 -0
- package/dist/model-info-aihubmix.js +117 -0
- package/dist/model-info-openai.d.ts +17 -0
- package/dist/model-info-openai.js +59 -0
- package/dist/model-info-openrouter.d.ts +25 -0
- package/dist/model-info-openrouter.js +101 -0
- package/dist/model-info.d.ts +37 -0
- package/dist/model-info.js +39 -0
- package/dist/provider-data.d.ts +101 -0
- package/dist/provider-data.js +471 -0
- package/dist/provider.d.ts +10 -0
- package/dist/provider.js +192 -0
- package/dist/public/android-chrome-192x192.png +0 -0
- package/dist/public/android-chrome-512x512.png +0 -0
- package/dist/public/apple-touch-icon.png +0 -0
- package/dist/public/assets/index-B443aj9k.js +8506 -0
- package/dist/public/assets/index-CjXGVbI7.css +1 -0
- package/dist/public/assets/index-DJC-p914.js +8506 -0
- package/dist/public/favicon-16x16.png +0 -0
- package/dist/public/favicon-32x32.png +0 -0
- package/dist/public/favicon.ico +0 -0
- package/dist/public/index.html +28 -0
- package/dist/public/manifest.json +82 -0
- package/dist/public/placeholder-logo.svg +1 -0
- package/dist/public/placeholder.svg +1 -0
- package/dist/public/snpro.woff2 +0 -0
- package/dist/public/tarsk-color.svg +12 -0
- package/dist/public/tarsk.png +0 -0
- package/dist/public/tarsk.svg +12 -0
- package/dist/public/zalando-sans.woff2 +0 -0
- package/dist/routes/chat-old.d.ts +21 -0
- package/dist/routes/chat-old.js +251 -0
- package/dist/routes/chat.d.ts +21 -0
- package/dist/routes/chat.js +217 -0
- package/dist/routes/git.d.ts +4 -0
- package/dist/routes/git.js +668 -0
- package/dist/routes/models.d.ts +18 -0
- package/dist/routes/models.js +128 -0
- package/dist/routes/projects-old.d.ts +20 -0
- package/dist/routes/projects-old.js +297 -0
- package/dist/routes/projects.d.ts +20 -0
- package/dist/routes/projects.js +365 -0
- package/dist/routes/providers.d.ts +15 -0
- package/dist/routes/providers.js +130 -0
- package/dist/routes/threads-old.d.ts +14 -0
- package/dist/routes/threads-old.js +393 -0
- package/dist/routes/threads.d.ts +14 -0
- package/dist/routes/threads.js +352 -0
- package/dist/types/models.d.ts +315 -0
- package/dist/types/models.js +11 -0
- package/dist/utils/env-manager.d.ts +3 -0
- package/dist/utils/env-manager.js +60 -0
- package/dist/utils/open-router-models.d.ts +45 -0
- package/dist/utils/open-router-models.js +103 -0
- package/dist/utils/openai-models.d.ts +63 -0
- package/dist/utils/openai-models.js +152 -0
- package/dist/utils/openai-pricing-scraper.d.ts +17 -0
- package/dist/utils/openai-pricing-scraper.js +185 -0
- package/dist/utils/validation.d.ts +10 -0
- package/dist/utils/validation.js +20 -0
- package/dist/utils.d.ts +10 -0
- package/dist/utils.js +12 -0
- package/package.json +36 -22
- package/LICENSE.md +0 -7
- package/dist/agent/agent.js +0 -131
- package/dist/agent/interfaces.js +0 -1
- package/dist/api/encryption.js +0 -41
- package/dist/api/models.js +0 -169
- package/dist/api/prompt.js +0 -12
- package/dist/api/settings.js +0 -43
- package/dist/api/test.js +0 -29
- package/dist/api/tools.js +0 -287
- package/dist/api/utils.js +0 -18
- package/dist/interfaces/meta.js +0 -1
- package/dist/interfaces/model.js +0 -1
- package/dist/interfaces/settings.js +0 -1
- package/dist/log/log.js +0 -33
- package/dist/prompt.js +0 -49
- package/dist/tools.js +0 -84
- package/dist/utils/files.js +0 -14
- package/dist/utils/json-file.js +0 -28
- package/dist/utils/strip-markdown.js +0 -5
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NeovateExecutor handles execution of neovate commands via the @neovate/code SDK
|
|
3
|
+
*
|
|
4
|
+
* This manager is responsible for:
|
|
5
|
+
* - Executing streaming sessions via the SDK
|
|
6
|
+
* - Streaming result messages back to the caller
|
|
7
|
+
* - Handling execution errors
|
|
8
|
+
*/
|
|
9
|
+
import { createSession, } from "@neovate/code";
|
|
10
|
+
import { resolve } from "path";
|
|
11
|
+
import { PROVIDERS } from "../provider.js";
|
|
12
|
+
const getErrorCode = (error) => {
|
|
13
|
+
if (error && typeof error === "object" && "code" in error) {
|
|
14
|
+
const code = error.code;
|
|
15
|
+
if (typeof code === "string") {
|
|
16
|
+
return code;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return undefined;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* NeovateExecutorImpl provides the implementation for neovate command execution
|
|
23
|
+
* using the @neovate/code SDK with streaming sessions.
|
|
24
|
+
*/
|
|
25
|
+
export class NeovateExecutorImpl {
|
|
26
|
+
metadataManager;
|
|
27
|
+
constructor(metadataManager) {
|
|
28
|
+
this.metadataManager = metadataManager;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Executes a neovate prompt using the SDK via streaming sessions
|
|
32
|
+
*
|
|
33
|
+
* @param userPrompt - The user's message/prompt to send to neovate
|
|
34
|
+
* @param context - ExecutionContext with threadId, threadPath, model, and attachments
|
|
35
|
+
* @yields NeovateEvent objects for message, result, and error events
|
|
36
|
+
*
|
|
37
|
+
* Requirements:
|
|
38
|
+
* - 5.2 - WHEN the CLI receives a chat message, THE CLI SHALL execute the Neovate command
|
|
39
|
+
* - 5.4 - WHEN the Neovate command executes, THE CLI SHALL stream the output back to the App
|
|
40
|
+
*/
|
|
41
|
+
async *execute(userPrompt, context) {
|
|
42
|
+
let session = null;
|
|
43
|
+
try {
|
|
44
|
+
// Get the provider name from context (defaults to 'openrouter')
|
|
45
|
+
const providerName = context.provider;
|
|
46
|
+
if (!providerName) {
|
|
47
|
+
console.error(`[ai] No provider specified in context`);
|
|
48
|
+
throw new Error("No provider specified in execution context");
|
|
49
|
+
}
|
|
50
|
+
// Ensure model is always defined
|
|
51
|
+
// The model is passed from the frontend (e.g., "openrouter/minimax/minimax-m2.1")
|
|
52
|
+
// We'll validate and ensure it's properly formatted for the SDK
|
|
53
|
+
let model = context.model?.trim();
|
|
54
|
+
if (!model) {
|
|
55
|
+
console.warn("[ai] No model provided in context, using default");
|
|
56
|
+
throw new Error("No model specified in execution context");
|
|
57
|
+
}
|
|
58
|
+
model = model.replace(`${providerName.toLowerCase()}/`, ""); // Remove provider prefix if present
|
|
59
|
+
const cwd = resolve(context.threadPath);
|
|
60
|
+
console.log("[ai] Execution context:", {
|
|
61
|
+
model,
|
|
62
|
+
cwd,
|
|
63
|
+
providerName,
|
|
64
|
+
promptLength: userPrompt.length,
|
|
65
|
+
});
|
|
66
|
+
// Get the provider configuration first to access environment variable name
|
|
67
|
+
const providerConfig = PROVIDERS.find((p) => p.name.toLowerCase() === providerName.toLowerCase());
|
|
68
|
+
if (!providerConfig) {
|
|
69
|
+
throw new Error(`Unknown provider: ${providerName}`);
|
|
70
|
+
}
|
|
71
|
+
// Try to get API key from environment variables first (takes precedence)
|
|
72
|
+
let apiKey = providerConfig.keyName ? process.env[providerConfig.keyName] : undefined;
|
|
73
|
+
let apiKeySource = 'environment';
|
|
74
|
+
// Fall back to metadata manager if not in environment
|
|
75
|
+
if (!apiKey) {
|
|
76
|
+
const providerKeys = await this.metadataManager.getProviderKeys();
|
|
77
|
+
apiKey = providerKeys[providerConfig.name];
|
|
78
|
+
apiKeySource = 'configuration';
|
|
79
|
+
}
|
|
80
|
+
if (!apiKey) {
|
|
81
|
+
throw new Error(`No API key found for provider: ${providerName}. ` +
|
|
82
|
+
`Set ${providerConfig.keyName || 'an API key'} in environment variables or configuration.`);
|
|
83
|
+
}
|
|
84
|
+
console.log(`[ai] API key source for ${providerName}: ${apiKeySource}`);
|
|
85
|
+
const api = providerConfig.api;
|
|
86
|
+
if (!api) {
|
|
87
|
+
throw new Error(`No API URL configured for provider: ${providerName}`);
|
|
88
|
+
}
|
|
89
|
+
const providers = {
|
|
90
|
+
tarsk: {
|
|
91
|
+
api,
|
|
92
|
+
options: { apiKey: apiKey },
|
|
93
|
+
models: { [model]: model },
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
const sessionConfig = {
|
|
97
|
+
model: `tarsk/${model}`,
|
|
98
|
+
cwd,
|
|
99
|
+
productName: "Tarsk.io",
|
|
100
|
+
providers,
|
|
101
|
+
};
|
|
102
|
+
console.log("[ai] Creating session:", JSON.stringify(sessionConfig));
|
|
103
|
+
console.log("[ai] Creating session with model:", model);
|
|
104
|
+
console.log("[ai] Session config has model:", !!sessionConfig.model);
|
|
105
|
+
// Create a streaming session - MUST have model defined
|
|
106
|
+
session = await createSession(sessionConfig);
|
|
107
|
+
if (!session) {
|
|
108
|
+
throw new Error("Failed to create session: createSession returned falsy value");
|
|
109
|
+
}
|
|
110
|
+
console.log("[ai] Session created:", session.sessionId);
|
|
111
|
+
// Send the user prompt to the session
|
|
112
|
+
console.log("[ai] Sending prompt to session...");
|
|
113
|
+
await session.send(userPrompt);
|
|
114
|
+
console.log("[ai] Prompt sent, waiting for responses...");
|
|
115
|
+
// Stream messages from the session
|
|
116
|
+
let lastMessageContent = null;
|
|
117
|
+
for await (const msg of session.receive()) {
|
|
118
|
+
const contentLength = typeof msg?.content === "string" ? msg.content.length : undefined;
|
|
119
|
+
console.log("[ai] Received msg:", { type: msg?.type, contentLength });
|
|
120
|
+
console.log("[ai] Msg:", msg);
|
|
121
|
+
if (msg?.type === "message") {
|
|
122
|
+
// Yield conversation messages (assistant responses)
|
|
123
|
+
// Use .text property if available (SDK provides both .content and .text)
|
|
124
|
+
const messageContent = typeof msg.text === "string"
|
|
125
|
+
? msg.text
|
|
126
|
+
: typeof msg.content === "string"
|
|
127
|
+
? msg.content
|
|
128
|
+
: JSON.stringify(msg.content);
|
|
129
|
+
lastMessageContent = messageContent;
|
|
130
|
+
yield {
|
|
131
|
+
type: "message",
|
|
132
|
+
role: msg.role || "assistant",
|
|
133
|
+
content: messageContent,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
else if (msg?.type === "result") {
|
|
137
|
+
// Check if result content is a duplicate of the last message
|
|
138
|
+
const resultContent = typeof msg.content === "string"
|
|
139
|
+
? msg.content
|
|
140
|
+
: JSON.stringify(msg.content);
|
|
141
|
+
// Skip result if it's identical to the last message (avoid duplicate)
|
|
142
|
+
if (resultContent !== lastMessageContent) {
|
|
143
|
+
// Yield the final result only if it's different from the message
|
|
144
|
+
yield {
|
|
145
|
+
type: "result",
|
|
146
|
+
content: resultContent,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
console.log("[ai] Skipping duplicate result event (same as message)");
|
|
151
|
+
}
|
|
152
|
+
break; // Exit the loop after receiving the result
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
console.error("[ai] Error during execution:", error);
|
|
158
|
+
let errCode;
|
|
159
|
+
let errMessage;
|
|
160
|
+
let errStack;
|
|
161
|
+
let errDetails;
|
|
162
|
+
if (error instanceof Error) {
|
|
163
|
+
errMessage = error.message || "Unknown error";
|
|
164
|
+
errStack = error.stack;
|
|
165
|
+
errCode = getErrorCode(error);
|
|
166
|
+
}
|
|
167
|
+
else if (typeof error === "object" && error !== null) {
|
|
168
|
+
errMessage = error.message
|
|
169
|
+
? String(error.message)
|
|
170
|
+
: JSON.stringify(error);
|
|
171
|
+
errCode = getErrorCode(error);
|
|
172
|
+
errDetails = error;
|
|
173
|
+
}
|
|
174
|
+
else if (typeof error === "string") {
|
|
175
|
+
errMessage = error;
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
errMessage = String(error);
|
|
179
|
+
}
|
|
180
|
+
console.error("[ai] Error details:", { errCode, errMessage, errStack });
|
|
181
|
+
yield {
|
|
182
|
+
type: "error",
|
|
183
|
+
content: errMessage,
|
|
184
|
+
error: {
|
|
185
|
+
code: errCode || "EXECUTION_ERROR",
|
|
186
|
+
message: errMessage || "An error occurred during execution",
|
|
187
|
+
details: { stack: errStack, originalError: errDetails },
|
|
188
|
+
},
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
finally {
|
|
192
|
+
// Ensure the session is properly closed
|
|
193
|
+
if (session) {
|
|
194
|
+
try {
|
|
195
|
+
await session.close?.();
|
|
196
|
+
console.log("[ai] Session closed");
|
|
197
|
+
}
|
|
198
|
+
catch (closeError) {
|
|
199
|
+
console.error("[ai] Error closing session:", closeError);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=neovate-executor.js.map
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProcessingStateManager tracks which threads currently have active chat processing
|
|
3
|
+
*
|
|
4
|
+
* This is an in-memory store that tracks thread IDs that are currently
|
|
5
|
+
* processing chat messages. The frontend can poll this to show/hide spinners.
|
|
6
|
+
*/
|
|
7
|
+
export interface ProcessingStateManager {
|
|
8
|
+
/**
|
|
9
|
+
* Mark a thread as currently processing
|
|
10
|
+
* @param threadId - The thread ID that started processing
|
|
11
|
+
*/
|
|
12
|
+
setProcessing(threadId: string): void;
|
|
13
|
+
/**
|
|
14
|
+
* Mark a thread as no longer processing
|
|
15
|
+
* @param threadId - The thread ID that finished processing
|
|
16
|
+
*/
|
|
17
|
+
clearProcessing(threadId: string): void;
|
|
18
|
+
/**
|
|
19
|
+
* Check if a thread is currently processing
|
|
20
|
+
* @param threadId - The thread ID to check
|
|
21
|
+
* @returns true if the thread is processing
|
|
22
|
+
*/
|
|
23
|
+
isProcessing(threadId: string): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Get all thread IDs that are currently processing
|
|
26
|
+
* @returns Array of thread IDs
|
|
27
|
+
*/
|
|
28
|
+
getProcessingThreadIds(): string[];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Implementation of ProcessingStateManager using an in-memory Set
|
|
32
|
+
*/
|
|
33
|
+
export declare class ProcessingStateManagerImpl implements ProcessingStateManager {
|
|
34
|
+
private processingThreads;
|
|
35
|
+
setProcessing(threadId: string): void;
|
|
36
|
+
clearProcessing(threadId: string): void;
|
|
37
|
+
isProcessing(threadId: string): boolean;
|
|
38
|
+
getProcessingThreadIds(): string[];
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=processing-state-manager.d.ts.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProcessingStateManager tracks which threads currently have active chat processing
|
|
3
|
+
*
|
|
4
|
+
* This is an in-memory store that tracks thread IDs that are currently
|
|
5
|
+
* processing chat messages. The frontend can poll this to show/hide spinners.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Implementation of ProcessingStateManager using an in-memory Set
|
|
9
|
+
*/
|
|
10
|
+
export class ProcessingStateManagerImpl {
|
|
11
|
+
processingThreads = new Set();
|
|
12
|
+
setProcessing(threadId) {
|
|
13
|
+
this.processingThreads.add(threadId);
|
|
14
|
+
console.log(`[ProcessingState] Thread ${threadId} started processing. Active: ${this.processingThreads.size}`);
|
|
15
|
+
}
|
|
16
|
+
clearProcessing(threadId) {
|
|
17
|
+
this.processingThreads.delete(threadId);
|
|
18
|
+
console.log(`[ProcessingState] Thread ${threadId} finished processing. Active: ${this.processingThreads.size}`);
|
|
19
|
+
}
|
|
20
|
+
isProcessing(threadId) {
|
|
21
|
+
return this.processingThreads.has(threadId);
|
|
22
|
+
}
|
|
23
|
+
getProcessingThreadIds() {
|
|
24
|
+
return Array.from(this.processingThreads);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=processing-state-manager.js.map
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProjectManager handles project lifecycle and metadata management
|
|
3
|
+
*
|
|
4
|
+
* This manager is responsible for:
|
|
5
|
+
* - Creating new projects from git URLs
|
|
6
|
+
* - Managing project metadata
|
|
7
|
+
* - Coordinating with GitManager for repository cloning
|
|
8
|
+
* - Providing CRUD operations for projects
|
|
9
|
+
*/
|
|
10
|
+
import { Project, ProjectEvent, Command } from '../types/models.js';
|
|
11
|
+
import { MetadataManager } from './metadata-manager.js';
|
|
12
|
+
import { GitManager } from './git-manager.js';
|
|
13
|
+
/**
|
|
14
|
+
* ProjectManager interface defines the contract for project operations
|
|
15
|
+
*/
|
|
16
|
+
export interface ProjectManager {
|
|
17
|
+
/**
|
|
18
|
+
* Creates a new project from a git URL
|
|
19
|
+
* @param gitUrl - The git repository URL
|
|
20
|
+
* @yields ProjectEvent objects during the creation process
|
|
21
|
+
*/
|
|
22
|
+
createProject(gitUrl: string): AsyncGenerator<ProjectEvent>;
|
|
23
|
+
/**
|
|
24
|
+
* Gets a project by ID
|
|
25
|
+
* @param projectId - The project ID
|
|
26
|
+
* @returns The project or null if not found
|
|
27
|
+
*/
|
|
28
|
+
getProject(projectId: string): Promise<Project | null>;
|
|
29
|
+
/**
|
|
30
|
+
* Lists all projects
|
|
31
|
+
* @returns Array of all projects
|
|
32
|
+
*/
|
|
33
|
+
listProjects(): Promise<Project[]>;
|
|
34
|
+
/**
|
|
35
|
+
* Deletes a project and all its threads
|
|
36
|
+
* @param projectId - The project ID to delete
|
|
37
|
+
*/
|
|
38
|
+
deleteProject(projectId: string): Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* Opens a project in the specified program
|
|
41
|
+
* @param projectId - The project ID
|
|
42
|
+
* @param program - The program to open the project in
|
|
43
|
+
*/
|
|
44
|
+
openWith(projectId: string, program: string): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Updates the project's open-with program preference
|
|
47
|
+
* @param projectId - The project ID
|
|
48
|
+
* @param program - The program name to set
|
|
49
|
+
*/
|
|
50
|
+
updateOpenWith(projectId: string, program: string): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Saves (adds or updates) a command for a project
|
|
53
|
+
* @param projectId - The project ID
|
|
54
|
+
* @param command - The command to save
|
|
55
|
+
*/
|
|
56
|
+
saveCommand(projectId: string, command: Command): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* Deletes a command from a project
|
|
59
|
+
* @param projectId - The project ID
|
|
60
|
+
* @param commandId - The ID of the command to delete
|
|
61
|
+
*/
|
|
62
|
+
deleteCommand(projectId: string, commandId: string): Promise<void>;
|
|
63
|
+
/**
|
|
64
|
+
* Runs a command in a thread's directory
|
|
65
|
+
* @param threadId - The thread ID where to run the command
|
|
66
|
+
* @param commandLine - The command line to execute
|
|
67
|
+
* @param cwd - Optional working directory relative to thread path
|
|
68
|
+
*/
|
|
69
|
+
runCommand(threadId: string, commandLine: string, cwd?: string): AsyncGenerator<unknown>;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* ProjectManagerImpl provides the implementation for project operations
|
|
73
|
+
*/
|
|
74
|
+
export declare class ProjectManagerImpl implements ProjectManager {
|
|
75
|
+
private rootFolder;
|
|
76
|
+
private metadataManager;
|
|
77
|
+
private gitManager;
|
|
78
|
+
/**
|
|
79
|
+
* Create a new ProjectManager
|
|
80
|
+
* @param rootFolder - Base directory where projects will be stored
|
|
81
|
+
* @param metadataManager - Manager for persisting metadata
|
|
82
|
+
* @param gitManager - Manager for git operations
|
|
83
|
+
*
|
|
84
|
+
* Requirements:
|
|
85
|
+
* - 1.1 - WHEN a user provides a git URL to create a new Project, THE CLI SHALL clone the repository into a folder under the Root_Folder
|
|
86
|
+
* - 1.4 - THE CLI SHALL determine the storage path for each Project folder
|
|
87
|
+
*/
|
|
88
|
+
constructor(rootFolder: string, metadataManager: MetadataManager, gitManager: GitManager);
|
|
89
|
+
/**
|
|
90
|
+
* Creates a new project from a git URL
|
|
91
|
+
*
|
|
92
|
+
* This method:
|
|
93
|
+
* 1. Validates the git URL
|
|
94
|
+
* 2. Generates a unique project ID
|
|
95
|
+
* 3. Derives the project name from the git URL
|
|
96
|
+
* 4. Generates the project path
|
|
97
|
+
* 5. Delegates to GitManager for cloning
|
|
98
|
+
* 6. Saves project metadata
|
|
99
|
+
* 7. Yields progress events during the operation
|
|
100
|
+
* 8. Creates an initial thread automatically
|
|
101
|
+
*
|
|
102
|
+
* @param gitUrl - The git repository URL
|
|
103
|
+
* @yields ProjectEvent objects during the creation process
|
|
104
|
+
*
|
|
105
|
+
* Requirements:
|
|
106
|
+
* - 1.1 - WHEN a user provides a git URL to create a new Project, THE CLI SHALL clone the repository into a folder under the Root_Folder
|
|
107
|
+
* - 1.2 - WHEN a Project is created, THE App SHALL display the Project in the Side_Panel with its associated Thread
|
|
108
|
+
* - 1.4 - THE CLI SHALL determine the storage path for each Project folder
|
|
109
|
+
* - 1.5 - WHEN a Project folder is created, THE System SHALL associate it with the provided git URL
|
|
110
|
+
*/
|
|
111
|
+
createProject(gitUrl: string): AsyncGenerator<ProjectEvent>;
|
|
112
|
+
/**
|
|
113
|
+
* Gets a project by ID
|
|
114
|
+
* @param projectId - The project ID
|
|
115
|
+
* @returns The project or null if not found
|
|
116
|
+
*/
|
|
117
|
+
getProject(projectId: string): Promise<Project | null>;
|
|
118
|
+
/**
|
|
119
|
+
* Lists all projects
|
|
120
|
+
* @returns Array of all projects
|
|
121
|
+
*/
|
|
122
|
+
listProjects(): Promise<Project[]>;
|
|
123
|
+
/**
|
|
124
|
+
* Deletes a project and all its threads (cascade delete)
|
|
125
|
+
*
|
|
126
|
+
* This method:
|
|
127
|
+
* 1. Finds the project by ID
|
|
128
|
+
* 2. Removes all associated threads from metadata
|
|
129
|
+
* 3. Removes the project directory from filesystem
|
|
130
|
+
* 4. Removes the project from metadata
|
|
131
|
+
*
|
|
132
|
+
* @param projectId - The project ID to delete
|
|
133
|
+
* @throws Error if project not found
|
|
134
|
+
*
|
|
135
|
+
* Requirements:
|
|
136
|
+
* - 1.1 - Cascade delete for projects (remove all threads)
|
|
137
|
+
*/
|
|
138
|
+
deleteProject(projectId: string): Promise<void>;
|
|
139
|
+
/**
|
|
140
|
+
* Derives a project name from a git URL
|
|
141
|
+
*
|
|
142
|
+
* Examples:
|
|
143
|
+
* - https://github.com/user/repo.git -> repo
|
|
144
|
+
* - https://github.com/user/repo -> repo
|
|
145
|
+
* - git@github.com:user/repo.git -> repo
|
|
146
|
+
*
|
|
147
|
+
* @param gitUrl - The git URL
|
|
148
|
+
* @returns The derived project name
|
|
149
|
+
*/
|
|
150
|
+
private deriveProjectName;
|
|
151
|
+
/**
|
|
152
|
+
* Generates a project path under the root folder
|
|
153
|
+
*
|
|
154
|
+
* @param projectName - The project name
|
|
155
|
+
* @returns The absolute path to the project folder
|
|
156
|
+
*
|
|
157
|
+
* Requirements:
|
|
158
|
+
* - 1.4 - THE CLI SHALL determine the storage path for each Project folder
|
|
159
|
+
*/
|
|
160
|
+
private generateProjectPath;
|
|
161
|
+
/**
|
|
162
|
+
* Gets the root folder path
|
|
163
|
+
* @returns The root folder path
|
|
164
|
+
*/
|
|
165
|
+
getRootFolder(): string;
|
|
166
|
+
/**
|
|
167
|
+
* Opens a project in the specified program
|
|
168
|
+
*
|
|
169
|
+
* @param projectId - The project ID
|
|
170
|
+
* @param program - The program to open the project in (VS Code, Cursor, Windsurf, Xcode, Android Studio, Kiro)
|
|
171
|
+
*/
|
|
172
|
+
openWith(projectId: string, program: string): Promise<void>;
|
|
173
|
+
/**
|
|
174
|
+
* Updates the project's open-with program preference
|
|
175
|
+
*
|
|
176
|
+
* @param projectId - The project ID
|
|
177
|
+
* @param program - The program name to set
|
|
178
|
+
*/
|
|
179
|
+
updateOpenWith(projectId: string, program: string): Promise<void>;
|
|
180
|
+
/**
|
|
181
|
+
* Saves (adds or updates) a command for a project
|
|
182
|
+
* @param projectId - The project ID
|
|
183
|
+
* @param command - The command to save
|
|
184
|
+
*/
|
|
185
|
+
saveCommand(projectId: string, command: Command): Promise<void>;
|
|
186
|
+
/**
|
|
187
|
+
* Deletes a command from a project
|
|
188
|
+
* @param projectId - The project ID
|
|
189
|
+
* @param commandId - The ID of the command to delete
|
|
190
|
+
*/
|
|
191
|
+
deleteCommand(projectId: string, commandId: string): Promise<void>;
|
|
192
|
+
/**
|
|
193
|
+
* Runs a command in a thread's directory
|
|
194
|
+
* @param threadId - The thread ID where to run the command
|
|
195
|
+
* @param commandLine - The command line to execute
|
|
196
|
+
*/
|
|
197
|
+
runCommand(threadId: string, commandLine: string, cwd?: string): AsyncGenerator<unknown>;
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=project-manager.d.ts.map
|