@chrishdx/llm-dev-server 1.0.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/LICENSE +21 -0
- package/README.md +164 -0
- package/backend/bin/llm-dev-server.js +3 -0
- package/backend/dist/cli.d.ts +15 -0
- package/backend/dist/cli.d.ts.map +1 -0
- package/backend/dist/cli.js +326 -0
- package/backend/dist/cli.js.map +1 -0
- package/backend/dist/config/database.d.ts +10 -0
- package/backend/dist/config/database.d.ts.map +1 -0
- package/backend/dist/config/database.js +61 -0
- package/backend/dist/config/database.js.map +1 -0
- package/backend/dist/config/environment.d.ts +20 -0
- package/backend/dist/config/environment.d.ts.map +1 -0
- package/backend/dist/config/environment.js +77 -0
- package/backend/dist/config/environment.js.map +1 -0
- package/backend/dist/controllers/AuthController.d.ts +18 -0
- package/backend/dist/controllers/AuthController.d.ts.map +1 -0
- package/backend/dist/controllers/AuthController.js +282 -0
- package/backend/dist/controllers/AuthController.js.map +1 -0
- package/backend/dist/controllers/ConversationController.d.ts +44 -0
- package/backend/dist/controllers/ConversationController.d.ts.map +1 -0
- package/backend/dist/controllers/ConversationController.js +193 -0
- package/backend/dist/controllers/ConversationController.js.map +1 -0
- package/backend/dist/controllers/JobController.d.ts +49 -0
- package/backend/dist/controllers/JobController.d.ts.map +1 -0
- package/backend/dist/controllers/JobController.js +227 -0
- package/backend/dist/controllers/JobController.js.map +1 -0
- package/backend/dist/index.d.ts +2 -0
- package/backend/dist/index.d.ts.map +1 -0
- package/backend/dist/index.js +160 -0
- package/backend/dist/index.js.map +1 -0
- package/backend/dist/middleware/auth.middleware.d.ts +25 -0
- package/backend/dist/middleware/auth.middleware.d.ts.map +1 -0
- package/backend/dist/middleware/auth.middleware.js +116 -0
- package/backend/dist/middleware/auth.middleware.js.map +1 -0
- package/backend/dist/middleware/authelia.middleware.d.ts +26 -0
- package/backend/dist/middleware/authelia.middleware.d.ts.map +1 -0
- package/backend/dist/middleware/authelia.middleware.js +165 -0
- package/backend/dist/middleware/authelia.middleware.js.map +1 -0
- package/backend/dist/middleware/error.middleware.d.ts +23 -0
- package/backend/dist/middleware/error.middleware.d.ts.map +1 -0
- package/backend/dist/middleware/error.middleware.js +59 -0
- package/backend/dist/middleware/error.middleware.js.map +1 -0
- package/backend/dist/models/AuthToken.d.ts +42 -0
- package/backend/dist/models/AuthToken.d.ts.map +1 -0
- package/backend/dist/models/AuthToken.js +97 -0
- package/backend/dist/models/AuthToken.js.map +1 -0
- package/backend/dist/models/Conversation.d.ts +36 -0
- package/backend/dist/models/Conversation.d.ts.map +1 -0
- package/backend/dist/models/Conversation.js +100 -0
- package/backend/dist/models/Conversation.js.map +1 -0
- package/backend/dist/models/FileOperation.d.ts +36 -0
- package/backend/dist/models/FileOperation.d.ts.map +1 -0
- package/backend/dist/models/FileOperation.js +117 -0
- package/backend/dist/models/FileOperation.js.map +1 -0
- package/backend/dist/models/Job.d.ts +48 -0
- package/backend/dist/models/Job.d.ts.map +1 -0
- package/backend/dist/models/Job.js +87 -0
- package/backend/dist/models/Job.js.map +1 -0
- package/backend/dist/models/Message.d.ts +38 -0
- package/backend/dist/models/Message.d.ts.map +1 -0
- package/backend/dist/models/Message.js +87 -0
- package/backend/dist/models/Message.js.map +1 -0
- package/backend/dist/models/User.d.ts +26 -0
- package/backend/dist/models/User.d.ts.map +1 -0
- package/backend/dist/models/User.js +67 -0
- package/backend/dist/models/User.js.map +1 -0
- package/backend/dist/models/index.d.ts +13 -0
- package/backend/dist/models/index.d.ts.map +1 -0
- package/backend/dist/models/index.js +24 -0
- package/backend/dist/models/index.js.map +1 -0
- package/backend/dist/routes/auth.routes.d.ts +3 -0
- package/backend/dist/routes/auth.routes.d.ts.map +1 -0
- package/backend/dist/routes/auth.routes.js +27 -0
- package/backend/dist/routes/auth.routes.js.map +1 -0
- package/backend/dist/routes/conversation.routes.d.ts +3 -0
- package/backend/dist/routes/conversation.routes.d.ts.map +1 -0
- package/backend/dist/routes/conversation.routes.js +17 -0
- package/backend/dist/routes/conversation.routes.js.map +1 -0
- package/backend/dist/routes/filesystem.routes.d.ts +3 -0
- package/backend/dist/routes/filesystem.routes.d.ts.map +1 -0
- package/backend/dist/routes/filesystem.routes.js +64 -0
- package/backend/dist/routes/filesystem.routes.js.map +1 -0
- package/backend/dist/routes/index.d.ts +3 -0
- package/backend/dist/routes/index.d.ts.map +1 -0
- package/backend/dist/routes/index.js +27 -0
- package/backend/dist/routes/index.js.map +1 -0
- package/backend/dist/routes/job.routes.d.ts +3 -0
- package/backend/dist/routes/job.routes.d.ts.map +1 -0
- package/backend/dist/routes/job.routes.js +18 -0
- package/backend/dist/routes/job.routes.js.map +1 -0
- package/backend/dist/services/auth/BaseAuthService.d.ts +49 -0
- package/backend/dist/services/auth/BaseAuthService.d.ts.map +1 -0
- package/backend/dist/services/auth/BaseAuthService.js +97 -0
- package/backend/dist/services/auth/BaseAuthService.js.map +1 -0
- package/backend/dist/services/auth/ClaudeAuthService.d.ts +69 -0
- package/backend/dist/services/auth/ClaudeAuthService.d.ts.map +1 -0
- package/backend/dist/services/auth/ClaudeAuthService.js +401 -0
- package/backend/dist/services/auth/ClaudeAuthService.js.map +1 -0
- package/backend/dist/services/auth/CodexAuthService.d.ts +37 -0
- package/backend/dist/services/auth/CodexAuthService.d.ts.map +1 -0
- package/backend/dist/services/auth/CodexAuthService.js +186 -0
- package/backend/dist/services/auth/CodexAuthService.js.map +1 -0
- package/backend/dist/services/auth/GeminiAuthService.d.ts +50 -0
- package/backend/dist/services/auth/GeminiAuthService.d.ts.map +1 -0
- package/backend/dist/services/auth/GeminiAuthService.js +284 -0
- package/backend/dist/services/auth/GeminiAuthService.js.map +1 -0
- package/backend/dist/services/auth/JwtService.d.ts +27 -0
- package/backend/dist/services/auth/JwtService.d.ts.map +1 -0
- package/backend/dist/services/auth/JwtService.js +65 -0
- package/backend/dist/services/auth/JwtService.js.map +1 -0
- package/backend/dist/services/auth/TokenRefreshService.d.ts +36 -0
- package/backend/dist/services/auth/TokenRefreshService.d.ts.map +1 -0
- package/backend/dist/services/auth/TokenRefreshService.js +178 -0
- package/backend/dist/services/auth/TokenRefreshService.js.map +1 -0
- package/backend/dist/services/conversation/ConversationService.d.ts +89 -0
- package/backend/dist/services/conversation/ConversationService.d.ts.map +1 -0
- package/backend/dist/services/conversation/ConversationService.js +255 -0
- package/backend/dist/services/conversation/ConversationService.js.map +1 -0
- package/backend/dist/services/job/JobService.d.ts +83 -0
- package/backend/dist/services/job/JobService.d.ts.map +1 -0
- package/backend/dist/services/job/JobService.js +213 -0
- package/backend/dist/services/job/JobService.js.map +1 -0
- package/backend/dist/services/job/WorkingDirectoryService.d.ts +73 -0
- package/backend/dist/services/job/WorkingDirectoryService.d.ts.map +1 -0
- package/backend/dist/services/job/WorkingDirectoryService.js +289 -0
- package/backend/dist/services/job/WorkingDirectoryService.js.map +1 -0
- package/backend/dist/services/llm/ClaudeProvider.d.ts +16 -0
- package/backend/dist/services/llm/ClaudeProvider.d.ts.map +1 -0
- package/backend/dist/services/llm/ClaudeProvider.js +229 -0
- package/backend/dist/services/llm/ClaudeProvider.js.map +1 -0
- package/backend/dist/services/llm/CodexProvider.d.ts +15 -0
- package/backend/dist/services/llm/CodexProvider.d.ts.map +1 -0
- package/backend/dist/services/llm/CodexProvider.js +301 -0
- package/backend/dist/services/llm/CodexProvider.js.map +1 -0
- package/backend/dist/services/llm/GeminiProvider.d.ts +17 -0
- package/backend/dist/services/llm/GeminiProvider.d.ts.map +1 -0
- package/backend/dist/services/llm/GeminiProvider.js +190 -0
- package/backend/dist/services/llm/GeminiProvider.js.map +1 -0
- package/backend/dist/services/llm/LLMProviderBase.d.ts +76 -0
- package/backend/dist/services/llm/LLMProviderBase.d.ts.map +1 -0
- package/backend/dist/services/llm/LLMProviderBase.js +34 -0
- package/backend/dist/services/llm/LLMProviderBase.js.map +1 -0
- package/backend/dist/services/llm/ProviderFactory.d.ts +17 -0
- package/backend/dist/services/llm/ProviderFactory.d.ts.map +1 -0
- package/backend/dist/services/llm/ProviderFactory.js +58 -0
- package/backend/dist/services/llm/ProviderFactory.js.map +1 -0
- package/backend/dist/utils/crypto.d.ts +33 -0
- package/backend/dist/utils/crypto.d.ts.map +1 -0
- package/backend/dist/utils/crypto.js +165 -0
- package/backend/dist/utils/crypto.js.map +1 -0
- package/backend/dist/utils/logger.d.ts +4 -0
- package/backend/dist/utils/logger.d.ts.map +1 -0
- package/backend/dist/utils/logger.js +44 -0
- package/backend/dist/utils/logger.js.map +1 -0
- package/backend/dist/utils/validators.d.ts +22 -0
- package/backend/dist/utils/validators.d.ts.map +1 -0
- package/backend/dist/utils/validators.js +127 -0
- package/backend/dist/utils/validators.js.map +1 -0
- package/backend/package.json +45 -0
- package/backend/public/assets/index-C207-KqP.js +188 -0
- package/backend/public/index.html +12 -0
- package/package.json +96 -0
- package/shared/dist/index.d.ts +5 -0
- package/shared/dist/index.d.ts.map +1 -0
- package/shared/dist/index.js +25 -0
- package/shared/dist/index.js.map +1 -0
- package/shared/dist/types/api.d.ts +27 -0
- package/shared/dist/types/api.d.ts.map +1 -0
- package/shared/dist/types/api.js +3 -0
- package/shared/dist/types/api.js.map +1 -0
- package/shared/dist/types/auth.d.ts +62 -0
- package/shared/dist/types/auth.d.ts.map +1 -0
- package/shared/dist/types/auth.js +3 -0
- package/shared/dist/types/auth.js.map +1 -0
- package/shared/dist/types/conversation.d.ts +98 -0
- package/shared/dist/types/conversation.d.ts.map +1 -0
- package/shared/dist/types/conversation.js +3 -0
- package/shared/dist/types/conversation.js.map +1 -0
- package/shared/dist/types/job.d.ts +93 -0
- package/shared/dist/types/job.d.ts.map +1 -0
- package/shared/dist/types/job.js +3 -0
- package/shared/dist/types/job.js.map +1 -0
- package/shared/package.json +15 -0
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.JobService = void 0;
|
|
7
|
+
const models_1 = require("../../models");
|
|
8
|
+
const WorkingDirectoryService_1 = require("./WorkingDirectoryService");
|
|
9
|
+
const logger_1 = __importDefault(require("../../utils/logger"));
|
|
10
|
+
class JobService {
|
|
11
|
+
/**
|
|
12
|
+
* Create a new job
|
|
13
|
+
*/
|
|
14
|
+
static async createJob(params) {
|
|
15
|
+
// Validate and create working directory
|
|
16
|
+
const workingDir = await WorkingDirectoryService_1.WorkingDirectoryService.validateAndCreate(params.workingDirectory);
|
|
17
|
+
// Create job
|
|
18
|
+
const job = await models_1.Job.create({
|
|
19
|
+
name: params.name,
|
|
20
|
+
description: params.description,
|
|
21
|
+
workingDirectory: workingDir,
|
|
22
|
+
systemPrompt: params.systemPrompt,
|
|
23
|
+
maxBudgetUsd: params.maxBudgetUsd,
|
|
24
|
+
status: "pending",
|
|
25
|
+
conversationCount: 0,
|
|
26
|
+
messageCount: 0,
|
|
27
|
+
});
|
|
28
|
+
logger_1.default.info(`Created job: ${job.id} (${job.name})`);
|
|
29
|
+
return job;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Get job by ID
|
|
33
|
+
*/
|
|
34
|
+
static async getJob(jobId) {
|
|
35
|
+
return await models_1.Job.findByPk(jobId);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Get job with conversations
|
|
39
|
+
*/
|
|
40
|
+
static async getJobWithConversations(jobId) {
|
|
41
|
+
const job = await models_1.Job.findByPk(jobId);
|
|
42
|
+
if (!job)
|
|
43
|
+
return null;
|
|
44
|
+
const conversations = await models_1.Conversation.findAll({
|
|
45
|
+
where: { jobId },
|
|
46
|
+
order: [["updatedAt", "DESC"]],
|
|
47
|
+
});
|
|
48
|
+
return { job, conversations };
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* List jobs
|
|
52
|
+
*/
|
|
53
|
+
static async listJobs(params) {
|
|
54
|
+
const { status, provider, limit = 20, offset = 0, search } = params;
|
|
55
|
+
const where = {};
|
|
56
|
+
if (status)
|
|
57
|
+
where.status = status;
|
|
58
|
+
if (search) {
|
|
59
|
+
where.name = { $like: `%${search}%` };
|
|
60
|
+
}
|
|
61
|
+
// Build query to filter by provider if specified
|
|
62
|
+
const include = provider
|
|
63
|
+
? [
|
|
64
|
+
{
|
|
65
|
+
model: models_1.Conversation,
|
|
66
|
+
where: { provider },
|
|
67
|
+
attributes: [],
|
|
68
|
+
required: true,
|
|
69
|
+
},
|
|
70
|
+
]
|
|
71
|
+
: [];
|
|
72
|
+
const { rows, count } = await models_1.Job.findAndCountAll({
|
|
73
|
+
where,
|
|
74
|
+
include,
|
|
75
|
+
limit,
|
|
76
|
+
offset,
|
|
77
|
+
order: [["createdAt", "DESC"]],
|
|
78
|
+
distinct: true, // Important when using include with hasMany
|
|
79
|
+
});
|
|
80
|
+
return { jobs: rows, total: count };
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Update job
|
|
84
|
+
*/
|
|
85
|
+
static async updateJob(jobId, params) {
|
|
86
|
+
const job = await models_1.Job.findByPk(jobId);
|
|
87
|
+
if (!job) {
|
|
88
|
+
throw new Error("Job not found");
|
|
89
|
+
}
|
|
90
|
+
const updates = {};
|
|
91
|
+
if (params.name !== undefined)
|
|
92
|
+
updates.name = params.name;
|
|
93
|
+
if (params.description !== undefined)
|
|
94
|
+
updates.description = params.description;
|
|
95
|
+
if (params.status !== undefined) {
|
|
96
|
+
updates.status = params.status;
|
|
97
|
+
// Update timestamps based on status
|
|
98
|
+
if (params.status === "running" && !job.startedAt) {
|
|
99
|
+
updates.startedAt = new Date();
|
|
100
|
+
}
|
|
101
|
+
if (["completed", "failed", "cancelled"].includes(params.status)) {
|
|
102
|
+
updates.completedAt = new Date();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (params.systemPrompt !== undefined)
|
|
106
|
+
updates.systemPrompt = params.systemPrompt;
|
|
107
|
+
if (params.maxBudgetUsd !== undefined)
|
|
108
|
+
updates.maxBudgetUsd = params.maxBudgetUsd;
|
|
109
|
+
await job.update(updates);
|
|
110
|
+
logger_1.default.info(`Updated job: ${jobId}`);
|
|
111
|
+
return job;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Update job statistics (conversation and message counts)
|
|
115
|
+
*/
|
|
116
|
+
static async updateJobStatistics(jobId) {
|
|
117
|
+
const job = await models_1.Job.findByPk(jobId);
|
|
118
|
+
if (!job)
|
|
119
|
+
return;
|
|
120
|
+
const conversationCount = await models_1.Conversation.count({ where: { jobId } });
|
|
121
|
+
const messageCount = await models_1.Message.count({
|
|
122
|
+
include: [
|
|
123
|
+
{
|
|
124
|
+
model: models_1.Conversation,
|
|
125
|
+
where: { jobId },
|
|
126
|
+
attributes: [],
|
|
127
|
+
as: "conversation",
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
});
|
|
131
|
+
await job.update({ conversationCount, messageCount });
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Delete job
|
|
135
|
+
*/
|
|
136
|
+
static async deleteJob(jobId) {
|
|
137
|
+
const job = await models_1.Job.findByPk(jobId);
|
|
138
|
+
if (!job) {
|
|
139
|
+
throw new Error("Job not found");
|
|
140
|
+
}
|
|
141
|
+
await job.destroy();
|
|
142
|
+
logger_1.default.info(`Deleted job: ${jobId}`);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Get job statistics
|
|
146
|
+
*/
|
|
147
|
+
static async getJobStatistics(jobId) {
|
|
148
|
+
const [messageCount, conversationCount, fileOpCount] = await Promise.all([
|
|
149
|
+
models_1.Message.count({
|
|
150
|
+
include: [
|
|
151
|
+
{
|
|
152
|
+
model: models_1.Conversation,
|
|
153
|
+
where: { jobId },
|
|
154
|
+
attributes: [],
|
|
155
|
+
as: "conversation",
|
|
156
|
+
},
|
|
157
|
+
],
|
|
158
|
+
}),
|
|
159
|
+
models_1.Conversation.count({ where: { jobId } }),
|
|
160
|
+
models_1.FileOperation.count({ where: { jobId } }),
|
|
161
|
+
]);
|
|
162
|
+
// Calculate total token usage from all conversations
|
|
163
|
+
const conversations = await models_1.Conversation.findAll({
|
|
164
|
+
where: { jobId },
|
|
165
|
+
attributes: ["totalTokens", "provider"],
|
|
166
|
+
});
|
|
167
|
+
const totalTokens = conversations.reduce((sum, conv) => sum + (conv.totalTokens || 0), 0);
|
|
168
|
+
// Calculate provider breakdown
|
|
169
|
+
const providerMap = new Map();
|
|
170
|
+
for (const conv of conversations) {
|
|
171
|
+
const existing = providerMap.get(conv.provider) || {
|
|
172
|
+
conversationCount: 0,
|
|
173
|
+
messageCount: 0,
|
|
174
|
+
};
|
|
175
|
+
existing.conversationCount++;
|
|
176
|
+
providerMap.set(conv.provider, existing);
|
|
177
|
+
}
|
|
178
|
+
// Get message counts per provider
|
|
179
|
+
for (const [provider, stats] of providerMap) {
|
|
180
|
+
const providerConversations = conversations.filter((c) => c.provider === provider);
|
|
181
|
+
const providerMessageCount = await models_1.Message.count({
|
|
182
|
+
where: {
|
|
183
|
+
conversationId: providerConversations.map((c) => c.id),
|
|
184
|
+
},
|
|
185
|
+
});
|
|
186
|
+
stats.messageCount = providerMessageCount;
|
|
187
|
+
}
|
|
188
|
+
const providerBreakdown = Array.from(providerMap.entries()).map(([provider, stats]) => ({
|
|
189
|
+
provider,
|
|
190
|
+
...stats,
|
|
191
|
+
}));
|
|
192
|
+
return {
|
|
193
|
+
messageCount,
|
|
194
|
+
conversationCount,
|
|
195
|
+
fileOperations: fileOpCount,
|
|
196
|
+
tokenUsage: {
|
|
197
|
+
input: 0, // Would need to aggregate from messages
|
|
198
|
+
output: 0,
|
|
199
|
+
total: totalTokens,
|
|
200
|
+
},
|
|
201
|
+
providerBreakdown,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Cancel job
|
|
206
|
+
*/
|
|
207
|
+
static async cancelJob(jobId) {
|
|
208
|
+
return await this.updateJob(jobId, { status: "cancelled" });
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
exports.JobService = JobService;
|
|
212
|
+
exports.default = JobService;
|
|
213
|
+
//# sourceMappingURL=JobService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JobService.js","sourceRoot":"","sources":["../../../src/services/job/JobService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
export interface FileInfo {
|
|
2
|
+
name: string;
|
|
3
|
+
path: string;
|
|
4
|
+
size: number;
|
|
5
|
+
modified: Date;
|
|
6
|
+
}
|
|
7
|
+
export interface DirectoryEntry {
|
|
8
|
+
name: string;
|
|
9
|
+
path: string;
|
|
10
|
+
isDirectory: boolean;
|
|
11
|
+
size?: number;
|
|
12
|
+
modified?: string;
|
|
13
|
+
isReadable: boolean;
|
|
14
|
+
isWritable: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface BrowseResult {
|
|
17
|
+
currentPath: string;
|
|
18
|
+
parentPath: string | null;
|
|
19
|
+
entries: DirectoryEntry[];
|
|
20
|
+
roots: {
|
|
21
|
+
name: string;
|
|
22
|
+
path: string;
|
|
23
|
+
}[];
|
|
24
|
+
}
|
|
25
|
+
export declare class WorkingDirectoryService {
|
|
26
|
+
/**
|
|
27
|
+
* Get available root directories for browsing
|
|
28
|
+
*/
|
|
29
|
+
static getRoots(): {
|
|
30
|
+
name: string;
|
|
31
|
+
path: string;
|
|
32
|
+
}[];
|
|
33
|
+
/**
|
|
34
|
+
* Check if a path is allowed for browsing
|
|
35
|
+
*/
|
|
36
|
+
static isPathAllowed(targetPath: string): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Browse directory on the server
|
|
39
|
+
*/
|
|
40
|
+
static browse(targetPath?: string): Promise<BrowseResult>;
|
|
41
|
+
/**
|
|
42
|
+
* Create a new directory
|
|
43
|
+
*/
|
|
44
|
+
static createDirectory(parentPath: string, name: string): Promise<string>;
|
|
45
|
+
/**
|
|
46
|
+
* Validate and create working directory
|
|
47
|
+
*/
|
|
48
|
+
static validateAndCreate(workingDir: string): Promise<string>;
|
|
49
|
+
/**
|
|
50
|
+
* List files in directory
|
|
51
|
+
*/
|
|
52
|
+
static listFiles(workingDir: string, subPath?: string, recursive?: boolean): Promise<{
|
|
53
|
+
files: FileInfo[];
|
|
54
|
+
directories: string[];
|
|
55
|
+
}>;
|
|
56
|
+
/**
|
|
57
|
+
* Read file content
|
|
58
|
+
*/
|
|
59
|
+
static readFile(workingDir: string, filePath: string): Promise<{
|
|
60
|
+
content: string;
|
|
61
|
+
mimeType: string;
|
|
62
|
+
}>;
|
|
63
|
+
/**
|
|
64
|
+
* Write file
|
|
65
|
+
*/
|
|
66
|
+
static writeFile(workingDir: string, filePath: string, content: string | Buffer): Promise<string>;
|
|
67
|
+
/**
|
|
68
|
+
* Get MIME type from file path
|
|
69
|
+
*/
|
|
70
|
+
private static getMimeType;
|
|
71
|
+
}
|
|
72
|
+
export default WorkingDirectoryService;
|
|
73
|
+
//# sourceMappingURL=WorkingDirectoryService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkingDirectoryService.d.ts","sourceRoot":"","sources":["../../../src/services/job/WorkingDirectoryService.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,IAAI,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACzC;AAED,qBAAa,uBAAuB;IAClC;;OAEG;IACH,MAAM,CAAC,QAAQ,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE;IAQnD;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAajD;;OAEG;WACU,MAAM,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IA4F/D;;OAEG;WACU,eAAe,CAC1B,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,CAAC;IA6BlB;;OAEG;WACU,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAgCnE;;OAEG;WACU,SAAS,CACpB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,EAChB,SAAS,UAAQ,GAChB,OAAO,CAAC;QAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;QAAC,WAAW,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IA4CxD;;OAEG;WACU,QAAQ,CACnB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAoBjD;;OAEG;WACU,SAAS,CACpB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GAAG,MAAM,GACvB,OAAO,CAAC,MAAM,CAAC;IAoBlB;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;CAqB3B;AAED,eAAe,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.WorkingDirectoryService = void 0;
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const promises_1 = __importDefault(require("fs/promises"));
|
|
9
|
+
const os_1 = __importDefault(require("os"));
|
|
10
|
+
const logger_1 = __importDefault(require("../../utils/logger"));
|
|
11
|
+
const environment_1 = __importDefault(require("../../config/environment"));
|
|
12
|
+
// Directories that are completely forbidden
|
|
13
|
+
const FORBIDDEN_DIRECTORIES = [
|
|
14
|
+
"/etc",
|
|
15
|
+
"/usr",
|
|
16
|
+
"/System",
|
|
17
|
+
"/bin",
|
|
18
|
+
"/sbin",
|
|
19
|
+
"/var",
|
|
20
|
+
"/private",
|
|
21
|
+
];
|
|
22
|
+
// Base directories that users can browse from
|
|
23
|
+
const ALLOWED_BROWSE_ROOTS = [environment_1.default.WORKING_DIR_BASE, os_1.default.homedir(), "/tmp"];
|
|
24
|
+
class WorkingDirectoryService {
|
|
25
|
+
/**
|
|
26
|
+
* Get available root directories for browsing
|
|
27
|
+
*/
|
|
28
|
+
static getRoots() {
|
|
29
|
+
return [
|
|
30
|
+
{ name: "Workspaces", path: path_1.default.resolve(environment_1.default.WORKING_DIR_BASE) },
|
|
31
|
+
{ name: "Home", path: os_1.default.homedir() },
|
|
32
|
+
{ name: "Temp", path: "/tmp" },
|
|
33
|
+
];
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Check if a path is allowed for browsing
|
|
37
|
+
*/
|
|
38
|
+
static isPathAllowed(targetPath) {
|
|
39
|
+
const absolutePath = path_1.default.resolve(targetPath);
|
|
40
|
+
// Check against forbidden directories
|
|
41
|
+
for (const forbidden of FORBIDDEN_DIRECTORIES) {
|
|
42
|
+
if (absolutePath.startsWith(forbidden) && absolutePath !== os_1.default.homedir()) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Browse directory on the server
|
|
50
|
+
*/
|
|
51
|
+
static async browse(targetPath) {
|
|
52
|
+
const roots = this.getRoots();
|
|
53
|
+
// Default to workspaces directory
|
|
54
|
+
let currentPath = targetPath
|
|
55
|
+
? path_1.default.resolve(targetPath)
|
|
56
|
+
: path_1.default.resolve(environment_1.default.WORKING_DIR_BASE);
|
|
57
|
+
// Security check
|
|
58
|
+
if (!this.isPathAllowed(currentPath)) {
|
|
59
|
+
throw new Error(`Access to ${currentPath} is not allowed`);
|
|
60
|
+
}
|
|
61
|
+
// Check if directory exists, if not fall back to workspaces
|
|
62
|
+
try {
|
|
63
|
+
const stats = await promises_1.default.stat(currentPath);
|
|
64
|
+
if (!stats.isDirectory()) {
|
|
65
|
+
currentPath = path_1.default.dirname(currentPath);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
currentPath = path_1.default.resolve(environment_1.default.WORKING_DIR_BASE);
|
|
70
|
+
// Create if doesn't exist
|
|
71
|
+
await promises_1.default.mkdir(currentPath, { recursive: true, mode: 0o755 });
|
|
72
|
+
}
|
|
73
|
+
// Get parent path
|
|
74
|
+
const parentPath = path_1.default.dirname(currentPath);
|
|
75
|
+
const hasParent = parentPath !== currentPath && this.isPathAllowed(parentPath);
|
|
76
|
+
// Read directory entries
|
|
77
|
+
const entries = [];
|
|
78
|
+
try {
|
|
79
|
+
const dirEntries = await promises_1.default.readdir(currentPath, { withFileTypes: true });
|
|
80
|
+
for (const entry of dirEntries) {
|
|
81
|
+
// Skip hidden files/directories (starting with .)
|
|
82
|
+
if (entry.name.startsWith("."))
|
|
83
|
+
continue;
|
|
84
|
+
const entryPath = path_1.default.join(currentPath, entry.name);
|
|
85
|
+
let isReadable = false;
|
|
86
|
+
let isWritable = false;
|
|
87
|
+
let size;
|
|
88
|
+
let modified;
|
|
89
|
+
try {
|
|
90
|
+
await promises_1.default.access(entryPath, promises_1.default.constants.R_OK);
|
|
91
|
+
isReadable = true;
|
|
92
|
+
}
|
|
93
|
+
catch { }
|
|
94
|
+
try {
|
|
95
|
+
await promises_1.default.access(entryPath, promises_1.default.constants.W_OK);
|
|
96
|
+
isWritable = true;
|
|
97
|
+
}
|
|
98
|
+
catch { }
|
|
99
|
+
try {
|
|
100
|
+
const stats = await promises_1.default.stat(entryPath);
|
|
101
|
+
size = stats.size;
|
|
102
|
+
modified = stats.mtime.toISOString();
|
|
103
|
+
}
|
|
104
|
+
catch { }
|
|
105
|
+
entries.push({
|
|
106
|
+
name: entry.name,
|
|
107
|
+
path: entryPath,
|
|
108
|
+
isDirectory: entry.isDirectory(),
|
|
109
|
+
size,
|
|
110
|
+
modified,
|
|
111
|
+
isReadable,
|
|
112
|
+
isWritable,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
// Sort: directories first, then alphabetically
|
|
116
|
+
entries.sort((a, b) => {
|
|
117
|
+
if (a.isDirectory && !b.isDirectory)
|
|
118
|
+
return -1;
|
|
119
|
+
if (!a.isDirectory && b.isDirectory)
|
|
120
|
+
return 1;
|
|
121
|
+
return a.name.localeCompare(b.name);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
logger_1.default.error(`Failed to browse directory ${currentPath}:`, error);
|
|
126
|
+
throw new Error(`Cannot read directory: ${currentPath}`);
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
currentPath,
|
|
130
|
+
parentPath: hasParent ? parentPath : null,
|
|
131
|
+
entries,
|
|
132
|
+
roots,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Create a new directory
|
|
137
|
+
*/
|
|
138
|
+
static async createDirectory(parentPath, name) {
|
|
139
|
+
const absoluteParent = path_1.default.resolve(parentPath);
|
|
140
|
+
if (!this.isPathAllowed(absoluteParent)) {
|
|
141
|
+
throw new Error(`Access to ${absoluteParent} is not allowed`);
|
|
142
|
+
}
|
|
143
|
+
// Validate name
|
|
144
|
+
if (!name ||
|
|
145
|
+
name.includes("/") ||
|
|
146
|
+
name.includes("\\") ||
|
|
147
|
+
name.startsWith(".")) {
|
|
148
|
+
throw new Error("Invalid directory name");
|
|
149
|
+
}
|
|
150
|
+
const newDirPath = path_1.default.join(absoluteParent, name);
|
|
151
|
+
try {
|
|
152
|
+
await promises_1.default.mkdir(newDirPath, { recursive: true, mode: 0o755 });
|
|
153
|
+
logger_1.default.info(`Created directory: ${newDirPath}`);
|
|
154
|
+
return newDirPath;
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
158
|
+
throw new Error(`Failed to create directory: ${message}`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Validate and create working directory
|
|
163
|
+
*/
|
|
164
|
+
static async validateAndCreate(workingDir) {
|
|
165
|
+
// Resolve to absolute path
|
|
166
|
+
const absolutePath = path_1.default.resolve(workingDir);
|
|
167
|
+
// Security check: prevent access to sensitive directories
|
|
168
|
+
for (const forbidden of FORBIDDEN_DIRECTORIES) {
|
|
169
|
+
if (absolutePath.startsWith(forbidden)) {
|
|
170
|
+
throw new Error(`Access to ${forbidden} is forbidden`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// Create directory if it doesn't exist
|
|
174
|
+
try {
|
|
175
|
+
await promises_1.default.mkdir(absolutePath, { recursive: true, mode: 0o755 });
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
179
|
+
throw new Error(`Failed to create directory: ${message}`);
|
|
180
|
+
}
|
|
181
|
+
// Verify write permissions
|
|
182
|
+
const testFile = path_1.default.join(absolutePath, `.write-test-${Date.now()}`);
|
|
183
|
+
try {
|
|
184
|
+
await promises_1.default.writeFile(testFile, "test", "utf8");
|
|
185
|
+
await promises_1.default.unlink(testFile);
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
throw new Error(`Working directory ${absolutePath} is not writable`);
|
|
189
|
+
}
|
|
190
|
+
logger_1.default.info(`Validated working directory: ${absolutePath}`);
|
|
191
|
+
return absolutePath;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* List files in directory
|
|
195
|
+
*/
|
|
196
|
+
static async listFiles(workingDir, subPath, recursive = false) {
|
|
197
|
+
const targetDir = subPath ? path_1.default.join(workingDir, subPath) : workingDir;
|
|
198
|
+
// Security check
|
|
199
|
+
if (!targetDir.startsWith(workingDir)) {
|
|
200
|
+
throw new Error("Path traversal detected");
|
|
201
|
+
}
|
|
202
|
+
const entries = await promises_1.default.readdir(targetDir, { withFileTypes: true });
|
|
203
|
+
const files = [];
|
|
204
|
+
const directories = [];
|
|
205
|
+
for (const entry of entries) {
|
|
206
|
+
if (entry.isDirectory()) {
|
|
207
|
+
directories.push(entry.name);
|
|
208
|
+
if (recursive) {
|
|
209
|
+
const subFiles = await this.listFiles(workingDir, path_1.default.join(subPath || "", entry.name), true);
|
|
210
|
+
files.push(...subFiles.files);
|
|
211
|
+
directories.push(...subFiles.directories.map((d) => path_1.default.join(entry.name, d)));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
else if (entry.isFile()) {
|
|
215
|
+
const fullPath = path_1.default.join(targetDir, entry.name);
|
|
216
|
+
const stats = await promises_1.default.stat(fullPath);
|
|
217
|
+
files.push({
|
|
218
|
+
name: entry.name,
|
|
219
|
+
path: path_1.default.relative(workingDir, fullPath),
|
|
220
|
+
size: stats.size,
|
|
221
|
+
modified: stats.mtime,
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return { files, directories };
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Read file content
|
|
229
|
+
*/
|
|
230
|
+
static async readFile(workingDir, filePath) {
|
|
231
|
+
const absolutePath = path_1.default.join(workingDir, filePath);
|
|
232
|
+
// Security check
|
|
233
|
+
if (!absolutePath.startsWith(workingDir)) {
|
|
234
|
+
throw new Error("Path traversal detected");
|
|
235
|
+
}
|
|
236
|
+
try {
|
|
237
|
+
await promises_1.default.access(absolutePath, promises_1.default.constants.R_OK);
|
|
238
|
+
}
|
|
239
|
+
catch {
|
|
240
|
+
throw new Error("File not found");
|
|
241
|
+
}
|
|
242
|
+
const content = await promises_1.default.readFile(absolutePath, "utf8");
|
|
243
|
+
const mimeType = this.getMimeType(absolutePath);
|
|
244
|
+
return { content, mimeType };
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Write file
|
|
248
|
+
*/
|
|
249
|
+
static async writeFile(workingDir, filePath, content) {
|
|
250
|
+
const absolutePath = path_1.default.join(workingDir, filePath);
|
|
251
|
+
// Security check
|
|
252
|
+
if (!absolutePath.startsWith(workingDir)) {
|
|
253
|
+
throw new Error("Path traversal detected");
|
|
254
|
+
}
|
|
255
|
+
// Create parent directory
|
|
256
|
+
await promises_1.default.mkdir(path_1.default.dirname(absolutePath), {
|
|
257
|
+
recursive: true,
|
|
258
|
+
mode: 0o755,
|
|
259
|
+
});
|
|
260
|
+
// Write file
|
|
261
|
+
await promises_1.default.writeFile(absolutePath, content, { mode: 0o644 });
|
|
262
|
+
return path_1.default.relative(workingDir, absolutePath);
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Get MIME type from file path
|
|
266
|
+
*/
|
|
267
|
+
static getMimeType(filePath) {
|
|
268
|
+
const ext = path_1.default.extname(filePath).toLowerCase();
|
|
269
|
+
const mimeTypes = {
|
|
270
|
+
".txt": "text/plain",
|
|
271
|
+
".md": "text/markdown",
|
|
272
|
+
".json": "application/json",
|
|
273
|
+
".js": "text/javascript",
|
|
274
|
+
".ts": "text/typescript",
|
|
275
|
+
".tsx": "text/typescript",
|
|
276
|
+
".jsx": "text/javascript",
|
|
277
|
+
".py": "text/x-python",
|
|
278
|
+
".html": "text/html",
|
|
279
|
+
".css": "text/css",
|
|
280
|
+
".yaml": "text/yaml",
|
|
281
|
+
".yml": "text/yaml",
|
|
282
|
+
".xml": "text/xml",
|
|
283
|
+
};
|
|
284
|
+
return mimeTypes[ext] || "application/octet-stream";
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
exports.WorkingDirectoryService = WorkingDirectoryService;
|
|
288
|
+
exports.default = WorkingDirectoryService;
|
|
289
|
+
//# sourceMappingURL=WorkingDirectoryService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkingDirectoryService.js","sourceRoot":"","sources":["../../../src/services/job/WorkingDirectoryService.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAwB;AACxB,2DAA6B;AAC7B,4CAAoB;AACpB,gEAAwC;AACxC,2EAA8C;AAE9C,4CAA4C;AAC5C,MAAM,qBAAqB,GAAG;IAC5B,MAAM;IACN,MAAM;IACN,SAAS;IACT,MAAM;IACN,OAAO;IACP,MAAM;IACN,UAAU;CACX,CAAC;AAEF,8CAA8C;AAC9C,MAAM,oBAAoB,GAAG,CAAC,qBAAM,CAAC,gBAAgB,EAAE,YAAE,CAAC,OAAO,EAAE,EAAE,MAAM,CAAC,CAAC;AA0B7E,MAAa,uBAAuB;IAClC;;OAEG;IACH,MAAM,CAAC,QAAQ;QACb,OAAO;YACL,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,cAAI,CAAC,OAAO,CAAC,qBAAM,CAAC,gBAAgB,CAAC,EAAE;YACnE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAE,CAAC,OAAO,EAAE,EAAE;YACpC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE;SAC/B,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,UAAkB;QACrC,MAAM,YAAY,GAAG,cAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAE9C,sCAAsC;QACtC,KAAK,MAAM,SAAS,IAAI,qBAAqB,EAAE,CAAC;YAC9C,IAAI,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,YAAY,KAAK,YAAE,CAAC,OAAO,EAAE,EAAE,CAAC;gBACxE,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,UAAmB;QACrC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAE9B,kCAAkC;QAClC,IAAI,WAAW,GAAG,UAAU;YAC1B,CAAC,CAAC,cAAI,CAAC,OAAO,CAAC,UAAU,CAAC;YAC1B,CAAC,CAAC,cAAI,CAAC,OAAO,CAAC,qBAAM,CAAC,gBAAgB,CAAC,CAAC;QAE1C,iBAAiB;QACjB,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,aAAa,WAAW,iBAAiB,CAAC,CAAC;QAC7D,CAAC;QAED,4DAA4D;QAC5D,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,kBAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACzC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACzB,WAAW,GAAG,cAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,WAAW,GAAG,cAAI,CAAC,OAAO,CAAC,qBAAM,CAAC,gBAAgB,CAAC,CAAC;YACpD,0BAA0B;YAC1B,MAAM,kBAAE,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAChE,CAAC;QAED,kBAAkB;QAClB,MAAM,UAAU,GAAG,cAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC7C,MAAM,SAAS,GACb,UAAU,KAAK,WAAW,IAAI,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QAE/D,yBAAyB;QACzB,MAAM,OAAO,GAAqB,EAAE,CAAC;QAErC,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,MAAM,kBAAE,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;YAE1E,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;gBAC/B,kDAAkD;gBAClD,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;oBAAE,SAAS;gBAEzC,MAAM,SAAS,GAAG,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;gBACrD,IAAI,UAAU,GAAG,KAAK,CAAC;gBACvB,IAAI,UAAU,GAAG,KAAK,CAAC;gBACvB,IAAI,IAAwB,CAAC;gBAC7B,IAAI,QAA4B,CAAC;gBAEjC,IAAI,CAAC;oBACH,MAAM,kBAAE,CAAC,MAAM,CAAC,SAAS,EAAE,kBAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;oBAC9C,UAAU,GAAG,IAAI,CAAC;gBACpB,CAAC;gBAAC,MAAM,CAAC,CAAA,CAAC;gBAEV,IAAI,CAAC;oBACH,MAAM,kBAAE,CAAC,MAAM,CAAC,SAAS,EAAE,kBAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;oBAC9C,UAAU,GAAG,IAAI,CAAC;gBACpB,CAAC;gBAAC,MAAM,CAAC,CAAA,CAAC;gBAEV,IAAI,CAAC;oBACH,MAAM,KAAK,GAAG,MAAM,kBAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;oBACvC,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;oBAClB,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;gBACvC,CAAC;gBAAC,MAAM,CAAC,CAAA,CAAC;gBAEV,OAAO,CAAC,IAAI,CAAC;oBACX,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,IAAI,EAAE,SAAS;oBACf,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE;oBAChC,IAAI;oBACJ,QAAQ;oBACR,UAAU;oBACV,UAAU;iBACX,CAAC,CAAC;YACL,CAAC;YAED,+CAA+C;YAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;gBACpB,IAAI,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC,WAAW;oBAAE,OAAO,CAAC,CAAC,CAAC;gBAC/C,IAAI,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,WAAW;oBAAE,OAAO,CAAC,CAAC;gBAC9C,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACtC,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,gBAAM,CAAC,KAAK,CAAC,8BAA8B,WAAW,GAAG,EAAE,KAAK,CAAC,CAAC;YAClE,MAAM,IAAI,KAAK,CAAC,0BAA0B,WAAW,EAAE,CAAC,CAAC;QAC3D,CAAC;QAED,OAAO;YACL,WAAW;YACX,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI;YACzC,OAAO;YACP,KAAK;SACN,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,eAAe,CAC1B,UAAkB,EAClB,IAAY;QAEZ,MAAM,cAAc,GAAG,cAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAEhD,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,aAAa,cAAc,iBAAiB,CAAC,CAAC;QAChE,CAAC;QAED,gBAAgB;QAChB,IACE,CAAC,IAAI;YACL,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;YAClB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YACnB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EACpB,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAC5C,CAAC;QAED,MAAM,UAAU,GAAG,cAAI,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;QAEnD,IAAI,CAAC;YACH,MAAM,kBAAE,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YAC7D,gBAAM,CAAC,IAAI,CAAC,sBAAsB,UAAU,EAAE,CAAC,CAAC;YAChD,OAAO,UAAU,CAAC;QACpB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,MAAM,IAAI,KAAK,CAAC,+BAA+B,OAAO,EAAE,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,UAAkB;QAC/C,2BAA2B;QAC3B,MAAM,YAAY,GAAG,cAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAE9C,0DAA0D;QAC1D,KAAK,MAAM,SAAS,IAAI,qBAAqB,EAAE,CAAC;YAC9C,IAAI,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;gBACvC,MAAM,IAAI,KAAK,CAAC,aAAa,SAAS,eAAe,CAAC,CAAC;YACzD,CAAC;QACH,CAAC;QAED,uCAAuC;QACvC,IAAI,CAAC;YACH,MAAM,kBAAE,CAAC,KAAK,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACjE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,MAAM,IAAI,KAAK,CAAC,+BAA+B,OAAO,EAAE,CAAC,CAAC;QAC5D,CAAC;QAED,2BAA2B;QAC3B,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,YAAY,EAAE,eAAe,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACtE,IAAI,CAAC;YACH,MAAM,kBAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;YAC7C,MAAM,kBAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC5B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,qBAAqB,YAAY,kBAAkB,CAAC,CAAC;QACvE,CAAC;QAED,gBAAM,CAAC,IAAI,CAAC,gCAAgC,YAAY,EAAE,CAAC,CAAC;QAC5D,OAAO,YAAY,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,SAAS,CACpB,UAAkB,EAClB,OAAgB,EAChB,SAAS,GAAG,KAAK;QAEjB,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,cAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;QAExE,iBAAiB;QACjB,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QAC7C,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,kBAAE,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAErE,MAAM,KAAK,GAAe,EAAE,CAAC;QAC7B,MAAM,WAAW,GAAa,EAAE,CAAC;QAEjC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAE7B,IAAI,SAAS,EAAE,CAAC;oBACd,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CACnC,UAAU,EACV,cAAI,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,EACpC,IAAI,CACL,CAAC;oBACF,KAAK,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;oBAC9B,WAAW,CAAC,IAAI,CACd,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAC7D,CAAC;gBACJ,CAAC;YACH,CAAC;iBAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;gBAC1B,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;gBAClD,MAAM,KAAK,GAAG,MAAM,kBAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAEtC,KAAK,CAAC,IAAI,CAAC;oBACT,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,IAAI,EAAE,cAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC;oBACzC,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,QAAQ,EAAE,KAAK,CAAC,KAAK;iBACtB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;IAChC,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,QAAQ,CACnB,UAAkB,EAClB,QAAgB;QAEhB,MAAM,YAAY,GAAG,cAAI,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAErD,iBAAiB;QACjB,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YACzC,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QAC7C,CAAC;QAED,IAAI,CAAC;YACH,MAAM,kBAAE,CAAC,MAAM,CAAC,YAAY,EAAE,kBAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACnD,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;QACpC,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QACxD,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;QAEhD,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,SAAS,CACpB,UAAkB,EAClB,QAAgB,EAChB,OAAwB;QAExB,MAAM,YAAY,GAAG,cAAI,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAErD,iBAAiB;QACjB,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YACzC,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QAC7C,CAAC;QAED,0BAA0B;QAC1B,MAAM,kBAAE,CAAC,KAAK,CAAC,cAAI,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE;YACzC,SAAS,EAAE,IAAI;YACf,IAAI,EAAE,KAAK;SACZ,CAAC,CAAC;QAEH,aAAa;QACb,MAAM,kBAAE,CAAC,SAAS,CAAC,YAAY,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAE3D,OAAO,cAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IACjD,CAAC;IAED;;OAEG;IACK,MAAM,CAAC,WAAW,CAAC,QAAgB;QACzC,MAAM,GAAG,GAAG,cAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;QAEjD,MAAM,SAAS,GAA2B;YACxC,MAAM,EAAE,YAAY;YACpB,KAAK,EAAE,eAAe;YACtB,OAAO,EAAE,kBAAkB;YAC3B,KAAK,EAAE,iBAAiB;YACxB,KAAK,EAAE,iBAAiB;YACxB,MAAM,EAAE,iBAAiB;YACzB,MAAM,EAAE,iBAAiB;YACzB,KAAK,EAAE,eAAe;YACtB,OAAO,EAAE,WAAW;YACpB,MAAM,EAAE,UAAU;YAClB,OAAO,EAAE,WAAW;YACpB,MAAM,EAAE,WAAW;YACnB,MAAM,EAAE,UAAU;SACnB,CAAC;QAEF,OAAO,SAAS,CAAC,GAAG,CAAC,IAAI,0BAA0B,CAAC;IACtD,CAAC;CACF;AAjUD,0DAiUC;AAED,kBAAe,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { LLMProviderBase, LLMProviderConfig, SendMessageParams, SendMessageResult, ProviderStatus } from "./LLMProviderBase";
|
|
2
|
+
export declare class ClaudeProvider extends LLMProviderBase {
|
|
3
|
+
private currentSessionId?;
|
|
4
|
+
constructor(providerConfig: LLMProviderConfig);
|
|
5
|
+
initialize(): Promise<void>;
|
|
6
|
+
sendMessage(params: SendMessageParams): Promise<SendMessageResult>;
|
|
7
|
+
private handleJsonResponse;
|
|
8
|
+
private handleStreamingResponse;
|
|
9
|
+
resumeSession(sessionId: string): Promise<boolean>;
|
|
10
|
+
endSession(): Promise<void>;
|
|
11
|
+
getStatus(): Promise<ProviderStatus>;
|
|
12
|
+
cleanup(): Promise<void>;
|
|
13
|
+
private resolveClaudeCli;
|
|
14
|
+
}
|
|
15
|
+
export default ClaudeProvider;
|
|
16
|
+
//# sourceMappingURL=ClaudeProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ClaudeProvider.d.ts","sourceRoot":"","sources":["../../../src/services/llm/ClaudeProvider.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACf,MAAM,mBAAmB,CAAC;AAqB3B,qBAAa,cAAe,SAAQ,eAAe;IACjD,OAAO,CAAC,gBAAgB,CAAC,CAAS;gBAEtB,cAAc,EAAE,iBAAiB;IAIvC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAgC3B,WAAW,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;YAyD1D,kBAAkB;YAuFlB,uBAAuB;IAkD/B,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAMlD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAK3B,SAAS,IAAI,OAAO,CAAC,cAAc,CAAC;IAQpC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAK9B,OAAO,CAAC,gBAAgB;CAuBzB;AAED,eAAe,cAAc,CAAC"}
|