@cortask/gateway 0.2.36 → 0.2.38
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/index.d.ts +3 -1
- package/dist/index.js +341 -13
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as http from 'http';
|
|
2
2
|
import { WebSocketServer } from 'ws';
|
|
3
|
-
import { PermissionRequest, QuestionnaireRequest, QuestionnaireResponse, CortaskConfig, WorkspaceManager, EncryptedCredentialStore, UsageStore, ModelStore, SessionStore, AgentRunner } from '@cortask/core';
|
|
3
|
+
import { PermissionRequest, QuestionnaireRequest, QuestionnaireResponse, CortaskConfig, WorkspaceManager, EncryptedCredentialStore, UsageStore, ModelStore, SessionStore, MemoryManager, AgentRunner } from '@cortask/core';
|
|
4
4
|
|
|
5
5
|
interface AgentRunnerOptions {
|
|
6
6
|
onPermissionRequest?: (req: PermissionRequest) => Promise<boolean>;
|
|
@@ -16,6 +16,8 @@ interface GatewayContext {
|
|
|
16
16
|
usageStore: UsageStore;
|
|
17
17
|
modelStore: ModelStore;
|
|
18
18
|
getSessionStore: (workspacePath: string) => SessionStore;
|
|
19
|
+
getMemoryManager: (workspacePath: string) => Promise<MemoryManager>;
|
|
20
|
+
invalidateMemoryManagers: () => void;
|
|
19
21
|
createAgentRunner: (workspacePath: string, options?: AgentRunnerOptions) => Promise<AgentRunner>;
|
|
20
22
|
}
|
|
21
23
|
declare function startServer(port?: number, host?: string): Promise<{
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { createServer } from "http";
|
|
|
4
4
|
import { WebSocketServer } from "ws";
|
|
5
5
|
import cors from "cors";
|
|
6
6
|
import path3 from "path";
|
|
7
|
-
import
|
|
7
|
+
import fs2 from "fs";
|
|
8
8
|
import { fileURLToPath } from "url";
|
|
9
9
|
import { createRequire } from "module";
|
|
10
10
|
import {
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
migrateAllWorkspaces,
|
|
16
16
|
EncryptedCredentialStore,
|
|
17
17
|
getOrCreateSecret,
|
|
18
|
-
createProvider as
|
|
18
|
+
createProvider as createProvider5,
|
|
19
19
|
AgentRunner,
|
|
20
20
|
builtinTools,
|
|
21
21
|
createCronTool,
|
|
@@ -35,6 +35,8 @@ import {
|
|
|
35
35
|
UsageStore,
|
|
36
36
|
ModelStore,
|
|
37
37
|
TemplateStore,
|
|
38
|
+
MemoryManager,
|
|
39
|
+
createLocalEmbeddingProvider,
|
|
38
40
|
logger as logger2
|
|
39
41
|
} from "@cortask/core";
|
|
40
42
|
import { TelegramAdapter, DiscordAdapter, WhatsAppAdapter as WhatsAppAdapter2 } from "@cortask/channels";
|
|
@@ -42,6 +44,7 @@ import { TelegramAdapter, DiscordAdapter, WhatsAppAdapter as WhatsAppAdapter2 }
|
|
|
42
44
|
// src/routes/workspaces.ts
|
|
43
45
|
import { Router } from "express";
|
|
44
46
|
import path from "path";
|
|
47
|
+
import fs from "fs/promises";
|
|
45
48
|
function createWorkspaceRoutes(ctx) {
|
|
46
49
|
const router = Router();
|
|
47
50
|
router.get("/", async (_req, res) => {
|
|
@@ -119,6 +122,192 @@ function createWorkspaceRoutes(ctx) {
|
|
|
119
122
|
res.status(500).json({ error: String(err) });
|
|
120
123
|
}
|
|
121
124
|
});
|
|
125
|
+
router.get("/:id/list-files", async (req, res) => {
|
|
126
|
+
try {
|
|
127
|
+
const workspace = await ctx.workspaceManager.get(req.params.id);
|
|
128
|
+
if (!workspace) {
|
|
129
|
+
res.status(404).json({ error: "Workspace not found" });
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
let entries = [];
|
|
133
|
+
try {
|
|
134
|
+
const dirents = await fs.readdir(workspace.rootPath, { withFileTypes: true });
|
|
135
|
+
const fileEntries = dirents.filter(
|
|
136
|
+
(d) => d.isFile() && d.name !== ".cortask"
|
|
137
|
+
);
|
|
138
|
+
const withStats = await Promise.all(
|
|
139
|
+
fileEntries.map(async (d) => {
|
|
140
|
+
const stat = await fs.stat(path.join(workspace.rootPath, d.name));
|
|
141
|
+
return { name: d.name, mtime: stat.mtimeMs };
|
|
142
|
+
})
|
|
143
|
+
);
|
|
144
|
+
entries = withStats.sort((a, b) => b.mtime - a.mtime).slice(0, 10);
|
|
145
|
+
} catch {
|
|
146
|
+
}
|
|
147
|
+
res.json({ files: entries });
|
|
148
|
+
} catch (err) {
|
|
149
|
+
res.status(500).json({ error: String(err) });
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
router.get("/:id/memory", async (req, res) => {
|
|
153
|
+
try {
|
|
154
|
+
const workspace = await ctx.workspaceManager.get(req.params.id);
|
|
155
|
+
if (!workspace) {
|
|
156
|
+
res.status(404).json({ error: "Workspace not found" });
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const content = await ctx.workspaceManager.readMemory(workspace.rootPath);
|
|
160
|
+
res.json({ content: content ?? null });
|
|
161
|
+
} catch (err) {
|
|
162
|
+
res.status(500).json({ error: String(err) });
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
router.put("/:id/memory", async (req, res) => {
|
|
166
|
+
try {
|
|
167
|
+
const workspace = await ctx.workspaceManager.get(req.params.id);
|
|
168
|
+
if (!workspace) {
|
|
169
|
+
res.status(404).json({ error: "Workspace not found" });
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
const { content } = req.body;
|
|
173
|
+
if (typeof content !== "string") {
|
|
174
|
+
res.status(400).json({ error: "content string required" });
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
await ctx.workspaceManager.writeMemory(workspace.rootPath, content);
|
|
178
|
+
res.json({ ok: true });
|
|
179
|
+
} catch (err) {
|
|
180
|
+
res.status(500).json({ error: String(err) });
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
router.get("/:id/memory/search", async (req, res) => {
|
|
184
|
+
try {
|
|
185
|
+
const workspace = await ctx.workspaceManager.get(req.params.id);
|
|
186
|
+
if (!workspace) {
|
|
187
|
+
res.status(404).json({ error: "Workspace not found" });
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const query = req.query.q;
|
|
191
|
+
if (!query) {
|
|
192
|
+
res.status(400).json({ error: "q query parameter required" });
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
const limit = Math.min(Math.max(parseInt(req.query.limit) || 5, 1), 50);
|
|
196
|
+
const manager = await ctx.getMemoryManager(workspace.rootPath);
|
|
197
|
+
const results = await manager.search(query, limit);
|
|
198
|
+
res.json(results);
|
|
199
|
+
} catch (err) {
|
|
200
|
+
res.status(500).json({ error: String(err) });
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
router.get("/:id/memory/entries", async (req, res) => {
|
|
204
|
+
try {
|
|
205
|
+
const workspace = await ctx.workspaceManager.get(req.params.id);
|
|
206
|
+
if (!workspace) {
|
|
207
|
+
res.status(404).json({ error: "Workspace not found" });
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
const limit = Math.min(Math.max(parseInt(req.query.limit) || 20, 1), 100);
|
|
211
|
+
const manager = await ctx.getMemoryManager(workspace.rootPath);
|
|
212
|
+
const entries = await manager.list(limit);
|
|
213
|
+
res.json(entries);
|
|
214
|
+
} catch (err) {
|
|
215
|
+
res.status(500).json({ error: String(err) });
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
router.get("/:id/tree", async (req, res) => {
|
|
219
|
+
try {
|
|
220
|
+
const workspace = await ctx.workspaceManager.get(req.params.id);
|
|
221
|
+
if (!workspace) {
|
|
222
|
+
res.status(404).json({ error: "Workspace not found" });
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
const maxDepth = Math.min(Math.max(parseInt(req.query.depth) || 3, 1), 5);
|
|
226
|
+
const skip = /* @__PURE__ */ new Set([".cortask", ".git", "node_modules", "dist", "__pycache__", ".venv", ".env"]);
|
|
227
|
+
const entries = [];
|
|
228
|
+
async function walk(dir, relPrefix, depth) {
|
|
229
|
+
if (depth > maxDepth) return;
|
|
230
|
+
let dirents;
|
|
231
|
+
try {
|
|
232
|
+
dirents = await fs.readdir(dir, { withFileTypes: true });
|
|
233
|
+
} catch {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
dirents.sort((a, b) => {
|
|
237
|
+
if (a.isDirectory() && !b.isDirectory()) return -1;
|
|
238
|
+
if (!a.isDirectory() && b.isDirectory()) return 1;
|
|
239
|
+
return a.name.localeCompare(b.name);
|
|
240
|
+
});
|
|
241
|
+
for (const d of dirents) {
|
|
242
|
+
if (skip.has(d.name) || d.name.startsWith(".")) continue;
|
|
243
|
+
const rel = relPrefix ? `${relPrefix}/${d.name}` : d.name;
|
|
244
|
+
if (d.isDirectory()) {
|
|
245
|
+
entries.push({ path: rel, name: d.name, type: "dir" });
|
|
246
|
+
await walk(path.join(dir, d.name), rel, depth + 1);
|
|
247
|
+
} else {
|
|
248
|
+
entries.push({ path: rel, name: d.name, type: "file" });
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
await walk(workspace.rootPath, "", 1);
|
|
253
|
+
res.json({ tree: entries });
|
|
254
|
+
} catch (err) {
|
|
255
|
+
res.status(500).json({ error: String(err) });
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
router.put("/:id/files/rename", async (req, res) => {
|
|
259
|
+
try {
|
|
260
|
+
const workspace = await ctx.workspaceManager.get(req.params.id);
|
|
261
|
+
if (!workspace) {
|
|
262
|
+
res.status(404).json({ error: "Workspace not found" });
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
const { oldPath, newPath } = req.body;
|
|
266
|
+
if (!oldPath || !newPath) {
|
|
267
|
+
res.status(400).json({ error: "oldPath and newPath are required" });
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
const fullOld = path.resolve(workspace.rootPath, oldPath);
|
|
271
|
+
const fullNew = path.resolve(workspace.rootPath, newPath);
|
|
272
|
+
if (!fullOld.startsWith(path.resolve(workspace.rootPath)) || !fullNew.startsWith(path.resolve(workspace.rootPath))) {
|
|
273
|
+
res.status(403).json({ error: "Path outside workspace" });
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
await fs.mkdir(path.dirname(fullNew), { recursive: true });
|
|
277
|
+
await fs.rename(fullOld, fullNew);
|
|
278
|
+
res.json({ ok: true });
|
|
279
|
+
} catch (err) {
|
|
280
|
+
res.status(500).json({ error: String(err) });
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
router.delete("/:id/files/*", async (req, res) => {
|
|
284
|
+
try {
|
|
285
|
+
const workspace = await ctx.workspaceManager.get(req.params.id);
|
|
286
|
+
if (!workspace) {
|
|
287
|
+
res.status(404).json({ error: "Workspace not found" });
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
const relPath = req.params["0"];
|
|
291
|
+
if (!relPath) {
|
|
292
|
+
res.status(400).json({ error: "File path required" });
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
const fullPath = path.resolve(workspace.rootPath, relPath);
|
|
296
|
+
if (!fullPath.startsWith(path.resolve(workspace.rootPath))) {
|
|
297
|
+
res.status(403).json({ error: "Path outside workspace" });
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
const stat = await fs.stat(fullPath);
|
|
301
|
+
if (stat.isDirectory()) {
|
|
302
|
+
await fs.rm(fullPath, { recursive: true });
|
|
303
|
+
} else {
|
|
304
|
+
await fs.unlink(fullPath);
|
|
305
|
+
}
|
|
306
|
+
res.json({ ok: true });
|
|
307
|
+
} catch (err) {
|
|
308
|
+
res.status(500).json({ error: String(err) });
|
|
309
|
+
}
|
|
310
|
+
});
|
|
122
311
|
router.get("/:id/files/*", async (req, res) => {
|
|
123
312
|
try {
|
|
124
313
|
const workspace = await ctx.workspaceManager.get(req.params.id);
|
|
@@ -673,9 +862,10 @@ function createSkillRoutes(ctx) {
|
|
|
673
862
|
import { Router as Router6 } from "express";
|
|
674
863
|
function createCronRoutes(cronService) {
|
|
675
864
|
const router = Router6();
|
|
676
|
-
router.get("/", (
|
|
865
|
+
router.get("/", (req, res) => {
|
|
677
866
|
try {
|
|
678
|
-
const
|
|
867
|
+
const workspaceId = typeof req.query.workspaceId === "string" ? req.query.workspaceId : void 0;
|
|
868
|
+
const jobs = cronService.list(workspaceId);
|
|
679
869
|
const result = jobs.map((job) => {
|
|
680
870
|
const state = cronService.getState(job.id);
|
|
681
871
|
return { ...job, state };
|
|
@@ -886,6 +1076,7 @@ async function handleChat(ws, msg, ctx) {
|
|
|
886
1076
|
for await (const event of runner.runStream({
|
|
887
1077
|
prompt: msg.message,
|
|
888
1078
|
attachments: msg.attachments,
|
|
1079
|
+
fileReferences: msg.fileReferences,
|
|
889
1080
|
sessionId: msg.sessionKey,
|
|
890
1081
|
workspaceId: msg.workspaceId,
|
|
891
1082
|
signal: abortController.signal
|
|
@@ -1234,20 +1425,20 @@ function createOnboardingRoutes(ctx) {
|
|
|
1234
1425
|
|
|
1235
1426
|
// src/routes/config.ts
|
|
1236
1427
|
import { Router as Router10 } from "express";
|
|
1237
|
-
import { saveConfig as saveConfig3 } from "@cortask/core";
|
|
1428
|
+
import { saveConfig as saveConfig3, createProvider as createProvider2 } from "@cortask/core";
|
|
1238
1429
|
function createConfigRoutes(ctx) {
|
|
1239
1430
|
const router = Router10();
|
|
1240
1431
|
router.get("/", (_req, res) => {
|
|
1241
1432
|
try {
|
|
1242
|
-
const { agent, server, spending } = ctx.config;
|
|
1243
|
-
res.json({ agent, server, spending });
|
|
1433
|
+
const { agent, server, spending, memory } = ctx.config;
|
|
1434
|
+
res.json({ agent, server, spending, memory, dataDir: ctx.dataDir });
|
|
1244
1435
|
} catch (err) {
|
|
1245
1436
|
res.status(500).json({ error: String(err) });
|
|
1246
1437
|
}
|
|
1247
1438
|
});
|
|
1248
1439
|
router.put("/", async (req, res) => {
|
|
1249
1440
|
try {
|
|
1250
|
-
const { agent, server, spending } = req.body;
|
|
1441
|
+
const { agent, server, spending, memory } = req.body;
|
|
1251
1442
|
if (agent) {
|
|
1252
1443
|
if (agent.maxTurns !== void 0) {
|
|
1253
1444
|
const v = Math.max(1, Math.min(200, Math.round(agent.maxTurns)));
|
|
@@ -1283,16 +1474,70 @@ function createConfigRoutes(ctx) {
|
|
|
1283
1474
|
ctx.config.spending.period = spending.period;
|
|
1284
1475
|
}
|
|
1285
1476
|
}
|
|
1477
|
+
if (memory) {
|
|
1478
|
+
const providerChanged = memory.embeddingProvider !== void 0 && memory.embeddingProvider !== ctx.config.memory?.embeddingProvider;
|
|
1479
|
+
const modelChanged = memory.embeddingModel !== void 0 && memory.embeddingModel !== ctx.config.memory?.embeddingModel;
|
|
1480
|
+
if (memory.embeddingProvider !== void 0) {
|
|
1481
|
+
ctx.config.memory.embeddingProvider = memory.embeddingProvider;
|
|
1482
|
+
}
|
|
1483
|
+
if (memory.embeddingModel !== void 0) {
|
|
1484
|
+
ctx.config.memory.embeddingModel = memory.embeddingModel;
|
|
1485
|
+
}
|
|
1486
|
+
if (providerChanged || modelChanged) {
|
|
1487
|
+
ctx.invalidateMemoryManagers();
|
|
1488
|
+
}
|
|
1489
|
+
}
|
|
1286
1490
|
await saveConfig3(ctx.configPath, ctx.config);
|
|
1287
1491
|
res.json({
|
|
1288
1492
|
agent: ctx.config.agent,
|
|
1289
1493
|
server: ctx.config.server,
|
|
1290
|
-
spending: ctx.config.spending
|
|
1494
|
+
spending: ctx.config.spending,
|
|
1495
|
+
memory: ctx.config.memory
|
|
1291
1496
|
});
|
|
1292
1497
|
} catch (err) {
|
|
1293
1498
|
res.status(500).json({ error: String(err) });
|
|
1294
1499
|
}
|
|
1295
1500
|
});
|
|
1501
|
+
router.post("/memory/test-embedding", async (req, res) => {
|
|
1502
|
+
try {
|
|
1503
|
+
const { provider, apiKey, model } = req.body;
|
|
1504
|
+
if (provider === "local") {
|
|
1505
|
+
res.json({ success: true, message: "Local embeddings use on-device model. No API connection needed.", dimensions: null });
|
|
1506
|
+
return;
|
|
1507
|
+
}
|
|
1508
|
+
const providerMap = {
|
|
1509
|
+
openai: { id: "openai", credKey: "provider.openai.apiKey", defaultModel: "text-embedding-3-small" },
|
|
1510
|
+
google: { id: "google", credKey: "provider.google.apiKey", defaultModel: "text-embedding-004" },
|
|
1511
|
+
ollama: { id: "ollama", credKey: "provider.ollama.host", defaultModel: "nomic-embed-text" }
|
|
1512
|
+
};
|
|
1513
|
+
const providerInfo = providerMap[provider];
|
|
1514
|
+
if (!providerInfo) {
|
|
1515
|
+
res.status(400).json({ success: false, error: `Unknown embedding provider: ${provider}` });
|
|
1516
|
+
return;
|
|
1517
|
+
}
|
|
1518
|
+
const key = apiKey || await ctx.credentialStore.get(providerInfo.credKey);
|
|
1519
|
+
if (!key) {
|
|
1520
|
+
res.status(400).json({ success: false, error: "No API key configured. Add one in the AI Providers tab or enter it above." });
|
|
1521
|
+
return;
|
|
1522
|
+
}
|
|
1523
|
+
const llmProvider = createProvider2(providerInfo.id, key);
|
|
1524
|
+
const embeddingModel = model || providerInfo.defaultModel;
|
|
1525
|
+
const result = await llmProvider.embed({
|
|
1526
|
+
model: embeddingModel,
|
|
1527
|
+
inputs: ["test"]
|
|
1528
|
+
});
|
|
1529
|
+
res.json({
|
|
1530
|
+
success: true,
|
|
1531
|
+
message: `Connected successfully. Model: ${embeddingModel}`,
|
|
1532
|
+
dimensions: result.embeddings[0]?.length ?? null
|
|
1533
|
+
});
|
|
1534
|
+
} catch (err) {
|
|
1535
|
+
res.status(500).json({
|
|
1536
|
+
success: false,
|
|
1537
|
+
error: err instanceof Error ? err.message : String(err)
|
|
1538
|
+
});
|
|
1539
|
+
}
|
|
1540
|
+
});
|
|
1296
1541
|
return router;
|
|
1297
1542
|
}
|
|
1298
1543
|
|
|
@@ -1327,7 +1572,7 @@ function createUsageRoutes(usageStore) {
|
|
|
1327
1572
|
|
|
1328
1573
|
// src/routes/models.ts
|
|
1329
1574
|
import { Router as Router12 } from "express";
|
|
1330
|
-
import { createProvider as
|
|
1575
|
+
import { createProvider as createProvider3, getModelDefinitions } from "@cortask/core";
|
|
1331
1576
|
function createModelRoutes(ctx) {
|
|
1332
1577
|
const router = Router12();
|
|
1333
1578
|
router.get("/:providerId/available", async (req, res) => {
|
|
@@ -1340,7 +1585,7 @@ function createModelRoutes(ctx) {
|
|
|
1340
1585
|
res.status(400).json({ error: `No credentials configured for ${providerId}` });
|
|
1341
1586
|
return;
|
|
1342
1587
|
}
|
|
1343
|
-
const provider =
|
|
1588
|
+
const provider = createProvider3(providerId, credential);
|
|
1344
1589
|
const models2 = await provider.listModels();
|
|
1345
1590
|
res.json(models2);
|
|
1346
1591
|
return;
|
|
@@ -1443,12 +1688,49 @@ function createTemplateRoutes(templateStore) {
|
|
|
1443
1688
|
return router;
|
|
1444
1689
|
}
|
|
1445
1690
|
|
|
1691
|
+
// src/routes/llm.ts
|
|
1692
|
+
import { Router as Router14 } from "express";
|
|
1693
|
+
import { createProvider as createProvider4 } from "@cortask/core";
|
|
1694
|
+
function createLlmRoutes(ctx) {
|
|
1695
|
+
const router = Router14();
|
|
1696
|
+
router.post("/complete", async (req, res) => {
|
|
1697
|
+
try {
|
|
1698
|
+
const { prompt } = req.body;
|
|
1699
|
+
if (!prompt) {
|
|
1700
|
+
res.status(400).json({ error: "prompt is required" });
|
|
1701
|
+
return;
|
|
1702
|
+
}
|
|
1703
|
+
const providerId = ctx.config.providers.default || "anthropic";
|
|
1704
|
+
const credKey = providerId === "ollama" ? "provider.ollama.host" : `provider.${providerId}.apiKey`;
|
|
1705
|
+
const apiKey = await ctx.credentialStore.get(credKey);
|
|
1706
|
+
if (!apiKey) {
|
|
1707
|
+
res.status(400).json({ error: "No API key configured" });
|
|
1708
|
+
return;
|
|
1709
|
+
}
|
|
1710
|
+
const provider = createProvider4(providerId, apiKey);
|
|
1711
|
+
const model = ctx.config.providers[providerId]?.model || getDefaultModel(providerId);
|
|
1712
|
+
const result = await provider.generateText({
|
|
1713
|
+
model,
|
|
1714
|
+
messages: [{ role: "user", content: prompt }],
|
|
1715
|
+
maxTokens: 200
|
|
1716
|
+
});
|
|
1717
|
+
res.json({ response: result.content });
|
|
1718
|
+
} catch (err) {
|
|
1719
|
+
res.status(500).json({
|
|
1720
|
+
error: err instanceof Error ? err.message : String(err)
|
|
1721
|
+
});
|
|
1722
|
+
}
|
|
1723
|
+
});
|
|
1724
|
+
return router;
|
|
1725
|
+
}
|
|
1726
|
+
|
|
1446
1727
|
// src/server.ts
|
|
1447
1728
|
var __filename = fileURLToPath(import.meta.url);
|
|
1448
1729
|
var __dirname = path3.dirname(__filename);
|
|
1449
1730
|
var _require = createRequire(import.meta.url);
|
|
1450
1731
|
var PKG_VERSION = _require("../package.json").version;
|
|
1451
1732
|
var sessionStoreCache = /* @__PURE__ */ new Map();
|
|
1733
|
+
var memoryManagerCache = /* @__PURE__ */ new Map();
|
|
1452
1734
|
function getSessionStore(workspacePath) {
|
|
1453
1735
|
const dbPath = path3.join(workspacePath, ".cortask", "sessions.db");
|
|
1454
1736
|
let store = sessionStoreCache.get(dbPath);
|
|
@@ -1480,6 +1762,41 @@ async function startServer(port, host) {
|
|
|
1480
1762
|
path3.join(dataDir, "credentials.enc.json"),
|
|
1481
1763
|
secret
|
|
1482
1764
|
);
|
|
1765
|
+
let localEmbedProvider = null;
|
|
1766
|
+
let localEmbedFailed = false;
|
|
1767
|
+
async function getMemoryManager(workspacePath) {
|
|
1768
|
+
const mmDbPath = path3.join(workspacePath, ".cortask", "memory.db");
|
|
1769
|
+
let manager = memoryManagerCache.get(mmDbPath);
|
|
1770
|
+
if (manager) return manager;
|
|
1771
|
+
const embeddingProvider = config.memory?.embeddingProvider ?? "local";
|
|
1772
|
+
const embeddingModel = config.memory?.embeddingModel;
|
|
1773
|
+
let apiProvider;
|
|
1774
|
+
if (embeddingProvider === "local") {
|
|
1775
|
+
if (!localEmbedProvider && !localEmbedFailed) {
|
|
1776
|
+
try {
|
|
1777
|
+
localEmbedProvider = await createLocalEmbeddingProvider();
|
|
1778
|
+
logger2.info("Local embedding provider initialized", "memory");
|
|
1779
|
+
} catch (err) {
|
|
1780
|
+
localEmbedFailed = true;
|
|
1781
|
+
logger2.debug(`Local embeddings unavailable: ${err instanceof Error ? err.message : err}`, "memory");
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
} else if (["openai", "google", "ollama"].includes(embeddingProvider)) {
|
|
1785
|
+
const credKey = embeddingProvider === "ollama" ? "provider.ollama.host" : `provider.${embeddingProvider}.apiKey`;
|
|
1786
|
+
const key = await credentialStore.get(credKey);
|
|
1787
|
+
if (key) {
|
|
1788
|
+
apiProvider = createProvider5(embeddingProvider, key);
|
|
1789
|
+
}
|
|
1790
|
+
}
|
|
1791
|
+
manager = new MemoryManager({
|
|
1792
|
+
dbPath: mmDbPath,
|
|
1793
|
+
localProvider: embeddingProvider === "local" ? localEmbedProvider ?? void 0 : void 0,
|
|
1794
|
+
apiProvider: apiProvider ?? void 0,
|
|
1795
|
+
embeddingModel
|
|
1796
|
+
});
|
|
1797
|
+
memoryManagerCache.set(mmDbPath, manager);
|
|
1798
|
+
return manager;
|
|
1799
|
+
}
|
|
1483
1800
|
const cronService = new CronService(dbPath);
|
|
1484
1801
|
const modelStore = new ModelStore(dbPath);
|
|
1485
1802
|
const templateStore = new TemplateStore(dbPath);
|
|
@@ -1535,7 +1852,7 @@ async function startServer(port, host) {
|
|
|
1535
1852
|
`No credentials found for provider "${providerId}". Set it in Settings.`
|
|
1536
1853
|
);
|
|
1537
1854
|
}
|
|
1538
|
-
const provider =
|
|
1855
|
+
const provider = createProvider5(providerId, apiKey);
|
|
1539
1856
|
const sessionStore = getSessionStore(workspacePath);
|
|
1540
1857
|
const allSkills = await loadSkills2(
|
|
1541
1858
|
bundledSkillsDir,
|
|
@@ -1557,6 +1874,7 @@ async function startServer(port, host) {
|
|
|
1557
1874
|
}));
|
|
1558
1875
|
const skillPrompts = eligible.map((s) => `- **${s.manifest.name}**: ${s.manifest.description}`);
|
|
1559
1876
|
const channelTools = channelCtx ? [createSwitchWorkspaceTool(workspaceManager, channelCtx.chatKey)] : [];
|
|
1877
|
+
const memoryManager = await getMemoryManager(workspacePath);
|
|
1560
1878
|
const runner = new AgentRunner({
|
|
1561
1879
|
config: {
|
|
1562
1880
|
provider,
|
|
@@ -1565,6 +1883,7 @@ async function startServer(port, host) {
|
|
|
1565
1883
|
temperature: config.agent.temperature,
|
|
1566
1884
|
maxTokens: config.agent.maxTokens
|
|
1567
1885
|
},
|
|
1886
|
+
memoryManager,
|
|
1568
1887
|
tools: [
|
|
1569
1888
|
...channelCtx ? builtinTools.filter((t) => !uiOnlyTools.has(t.definition.name)) : builtinTools,
|
|
1570
1889
|
createCronTool(cronService),
|
|
@@ -1616,6 +1935,14 @@ async function startServer(port, host) {
|
|
|
1616
1935
|
usageStore,
|
|
1617
1936
|
modelStore,
|
|
1618
1937
|
getSessionStore,
|
|
1938
|
+
getMemoryManager,
|
|
1939
|
+
invalidateMemoryManagers: () => {
|
|
1940
|
+
for (const mgr of memoryManagerCache.values()) mgr.close();
|
|
1941
|
+
memoryManagerCache.clear();
|
|
1942
|
+
localEmbedProvider?.dispose();
|
|
1943
|
+
localEmbedProvider = null;
|
|
1944
|
+
localEmbedFailed = false;
|
|
1945
|
+
},
|
|
1619
1946
|
createAgentRunner
|
|
1620
1947
|
};
|
|
1621
1948
|
const app = express();
|
|
@@ -1671,6 +1998,7 @@ async function startServer(port, host) {
|
|
|
1671
1998
|
app.use("/api/usage", createUsageRoutes(usageStore));
|
|
1672
1999
|
app.use("/api/models", createModelRoutes(ctx));
|
|
1673
2000
|
app.use("/api/templates", createTemplateRoutes(templateStore));
|
|
2001
|
+
app.use("/api/llm", createLlmRoutes(ctx));
|
|
1674
2002
|
async function createChannelAdapter(id) {
|
|
1675
2003
|
if (id === "telegram") {
|
|
1676
2004
|
const botToken = await credentialStore.get("channel.telegram.botToken");
|
|
@@ -1726,7 +2054,7 @@ async function startServer(port, host) {
|
|
|
1726
2054
|
// electron packaged
|
|
1727
2055
|
];
|
|
1728
2056
|
for (const uiDir of uiDistCandidates) {
|
|
1729
|
-
if (
|
|
2057
|
+
if (fs2.existsSync(path3.join(uiDir, "index.html"))) {
|
|
1730
2058
|
app.use(express.static(uiDir));
|
|
1731
2059
|
app.get("*", (_req, res, next) => {
|
|
1732
2060
|
if (_req.path.startsWith("/api/") || _req.path.startsWith("/ws")) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server.ts","../src/routes/workspaces.ts","../src/routes/sessions.ts","../src/routes/credentials.ts","../src/routes/providers.ts","../src/routes/skills.ts","../src/routes/cron.ts","../src/routes/channels.ts","../src/ws.ts","../src/routes/artifacts.ts","../src/routes/onboarding.ts","../src/routes/config.ts","../src/routes/usage.ts","../src/routes/models.ts","../src/routes/templates.ts","../src/index.ts"],"sourcesContent":["import express from \"express\";\nimport { createServer } from \"node:http\";\nimport { WebSocketServer, type WebSocket } from \"ws\";\nimport cors from \"cors\";\nimport path from \"node:path\";\nimport fs from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { createRequire } from \"node:module\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\nconst _require = createRequire(import.meta.url);\nconst PKG_VERSION: string = _require(\"../package.json\").version;\nimport {\n loadConfig,\n getDataDir,\n WorkspaceManager,\n SessionStore,\n migrateAllWorkspaces,\n EncryptedCredentialStore,\n getOrCreateSecret,\n createProvider,\n AgentRunner,\n builtinTools,\n createCronTool,\n createArtifactTool,\n createBrowserTool,\n ensureBrowserInstalled,\n createSubagentTool,\n createSwitchWorkspaceTool,\n createSkillTool,\n setSubagentRunner,\n cleanupSubagentRecords,\n loadSkills,\n getEligibleSkills,\n buildSkillTools,\n CronService,\n ArtifactStore,\n UsageStore,\n ModelStore,\n TemplateStore,\n logger,\n type CortaskConfig,\n type ProviderId,\n type ToolHandler,\n type PermissionRequest,\n type QuestionnaireRequest,\n type QuestionnaireResponse,\n type ChannelType,\n} from \"@cortask/core\";\nimport { TelegramAdapter, DiscordAdapter, WhatsAppAdapter, type ChannelPlugin } from \"@cortask/channels\";\nimport { createWorkspaceRoutes } from \"./routes/workspaces.js\";\nimport { createSessionRoutes } from \"./routes/sessions.js\";\nimport { createCredentialRoutes } from \"./routes/credentials.js\";\nimport { createProviderRoutes } from \"./routes/providers.js\";\nimport { createSkillRoutes } from \"./routes/skills.js\";\nimport { createCronRoutes } from \"./routes/cron.js\";\nimport { createChannelRoutes } from \"./routes/channels.js\";\nimport { createArtifactRoutes } from \"./routes/artifacts.js\";\nimport { createOnboardingRoutes } from \"./routes/onboarding.js\";\nimport { createConfigRoutes } from \"./routes/config.js\";\nimport { createUsageRoutes } from \"./routes/usage.js\";\nimport { createModelRoutes } from \"./routes/models.js\";\nimport { createTemplateRoutes } from \"./routes/templates.js\";\nimport { handleWebSocket, broadcastSessionRefresh } from \"./ws.js\";\n\nexport interface AgentRunnerOptions {\n onPermissionRequest?: (req: PermissionRequest) => Promise<boolean>;\n onQuestionnaireRequest?: (\n req: QuestionnaireRequest,\n ) => Promise<QuestionnaireResponse>;\n}\n\nexport interface GatewayContext {\n config: CortaskConfig;\n configPath: string;\n dataDir: string;\n bundledSkillsDir: string;\n workspaceManager: WorkspaceManager;\n credentialStore: EncryptedCredentialStore;\n usageStore: UsageStore;\n modelStore: ModelStore;\n getSessionStore: (workspacePath: string) => SessionStore;\n createAgentRunner: (workspacePath: string, options?: AgentRunnerOptions) => Promise<AgentRunner>;\n}\n\nconst sessionStoreCache = new Map<string, SessionStore>();\n\nfunction getSessionStore(workspacePath: string): SessionStore {\n const dbPath = path.join(workspacePath, \".cortask\", \"sessions.db\");\n let store = sessionStoreCache.get(dbPath);\n if (!store) {\n store = new SessionStore(dbPath);\n sessionStoreCache.set(dbPath, store);\n }\n return store;\n}\n\nexport async function startServer(port?: number, host?: string) {\n const dataDir = getDataDir();\n const configPath = path.join(dataDir, \"config.yaml\");\n const config = await loadConfig(configPath);\n\n // Initialize logging\n logger.init(path.join(dataDir, \"logs\"));\n logger.info(\"Starting Cortask gateway\", \"gateway\");\n\n // Initialize workspace manager\n const dbPath = path.join(dataDir, \"cortask.db\");\n const workspaceManager = new WorkspaceManager(dbPath);\n\n // Run database migrations for all workspaces\n try {\n const workspaces = await workspaceManager.list();\n migrateAllWorkspaces(workspaces);\n } catch (err) {\n logger.error(\n `Database migration failed: ${err instanceof Error ? err.message : String(err)}`,\n \"gateway\",\n );\n // Continue startup even if migration fails - SessionStore will handle missing columns\n }\n\n // Initialize credential store\n const secret = await getOrCreateSecret(dataDir);\n const credentialStore = new EncryptedCredentialStore(\n path.join(dataDir, \"credentials.enc.json\"),\n secret,\n );\n\n // Initialize cron service (uses central DB)\n const cronService = new CronService(dbPath);\n\n // Initialize model store (enabled models with pricing)\n const modelStore = new ModelStore(dbPath);\n\n // Initialize template store\n const templateStore = new TemplateStore(dbPath);\n\n // Initialize usage store (tracks token consumption, uses model store for pricing)\n const usageStore = new UsageStore(dbPath, modelStore);\n\n // Initialize artifact store (in-memory with TTL)\n const artifactStore = new ArtifactStore();\n\n // Initialize channel adapters\n const channels = new Map<string, ChannelPlugin>();\n let wss: WebSocketServer;\n\n // Channel message handler helper\n function wireMessageHandler(channel: ChannelPlugin) {\n const channelType = channel.id as ChannelType;\n\n channel.onMessage(async (msg) => {\n try {\n // Check spending limits before running\n if (config.spending.enabled) {\n const summary = usageStore.getSummary(config.spending.period);\n if (config.spending.maxTokens && summary.totalTokens >= config.spending.maxTokens) {\n return \"Spending limit reached. Please increase or disable the limit.\";\n }\n if (config.spending.maxCostUsd && summary.totalCostUsd >= config.spending.maxCostUsd) {\n return \"Spending limit reached. Please increase or disable the limit.\";\n }\n }\n\n const chatKey = `${channel.id}-${msg.chatId}`;\n const workspaces = await workspaceManager.list();\n if (workspaces.length === 0) return \"No workspace configured.\";\n\n // Resolve workspace: use saved mapping or fall back to first workspace\n const mappedWorkspaceId = workspaceManager.getChannelWorkspace(chatKey);\n const workspace = mappedWorkspaceId\n ? (await workspaceManager.get(mappedWorkspaceId)) ?? workspaces[0]\n : workspaces[0];\n\n const runner = await createAgentRunner(workspace.rootPath, undefined, {\n channelType,\n chatKey,\n chatId: msg.chatId,\n });\n const result = await runner.run({\n prompt: msg.text,\n sessionId: chatKey,\n });\n\n // Notify UI clients to refresh session list\n if (wss) broadcastSessionRefresh(wss, workspace.id);\n\n return result.response;\n } catch (err) {\n return `Error: ${err instanceof Error ? err.message : String(err)}`;\n }\n });\n }\n\n // Resolve skill directories\n const bundledSkillsDir = process.env.CORTASK_SKILLS_DIR\n ?? path.join(path.resolve(__dirname, \"..\", \"..\", \"..\"), \"skills\");\n const userSkillsDir = path.join(dataDir, \"skills\");\n\n interface ChannelContext {\n channelType: ChannelType;\n chatKey: string;\n chatId: string;\n }\n\n // Tools that only work in the web UI (not in channels)\n const uiOnlyTools = new Set([\"questionnaire\", \"artifact\", \"show_file\"]);\n\n // Create agent runner factory\n async function createAgentRunner(workspacePath: string, options?: AgentRunnerOptions, channelCtx?: ChannelContext): Promise<AgentRunner> {\n const providerId = (config.providers.default || \"anthropic\") as ProviderId;\n const providerConfig = config.providers[providerId];\n const model = providerConfig?.model || getDefaultModel(providerId);\n\n // Get credential from credential store (Ollama uses host, others use apiKey)\n const credKey = providerId === \"ollama\"\n ? \"provider.ollama.host\"\n : `provider.${providerId}.apiKey`;\n const apiKey = await credentialStore.get(credKey);\n if (!apiKey) {\n throw new Error(\n `No credentials found for provider \"${providerId}\". Set it in Settings.`,\n );\n }\n\n const provider = createProvider(providerId, apiKey);\n const sessionStore = getSessionStore(workspacePath);\n\n // Load skills and build skill tools\n const allSkills = await loadSkills(\n bundledSkillsDir,\n userSkillsDir,\n config.skills.dirs,\n credentialStore,\n );\n const eligible = getEligibleSkills(allSkills);\n const skillRegistry = await buildSkillTools(eligible, credentialStore);\n\n // Convert skill handlers to ToolHandler format\n const skillToolHandlers: ToolHandler[] = skillRegistry.toolDefs.map((def) => ({\n definition: def,\n execute: async (args, context) => {\n const handler = skillRegistry.handlers.get(def.name);\n if (!handler) {\n return { toolCallId: \"\", content: `No handler for skill tool: ${def.name}`, isError: true };\n }\n return handler(args, context.workspacePath);\n },\n }));\n\n // Build skill prompts from eligible skills (lightweight: just name + description)\n const skillPrompts = eligible\n .map((s) => `- **${s.manifest.name}**: ${s.manifest.description}`);\n\n // Include switch_workspace tool only for channel-based runners\n const channelTools: ToolHandler[] = channelCtx\n ? [createSwitchWorkspaceTool(workspaceManager, channelCtx.chatKey)]\n : [];\n\n const runner = new AgentRunner({\n config: {\n provider,\n model,\n maxTurns: config.agent.maxTurns,\n temperature: config.agent.temperature,\n maxTokens: config.agent.maxTokens,\n },\n tools: [\n ...(channelCtx\n ? builtinTools.filter((t) => !uiOnlyTools.has(t.definition.name))\n : builtinTools),\n createCronTool(cronService),\n createSkillTool(userSkillsDir, allSkills.filter(s => s.source === \"bundled\").map(s => s.manifest.name)),\n ...(channelCtx ? [] : [createArtifactTool(artifactStore)]),\n createBrowserTool(artifactStore),\n createSubagentTool(),\n ...channelTools,\n ...skillToolHandlers,\n ],\n channel: channelCtx\n ? { type: channelCtx.channelType, chatId: channelCtx.chatId }\n : undefined,\n getWorkspacePath: () => workspacePath,\n getDataDir: () => dataDir,\n getMemoryContent: () => workspaceManager.readMemory(workspacePath),\n getGlobalMemoryContent: () => workspaceManager.readGlobalMemory(dataDir),\n getSkillPrompts: () => skillPrompts,\n getSessionMessages: async (sessionId) => {\n return sessionStore.getMessages(sessionId);\n },\n saveSessionMessages: async (sessionId, messages) => {\n sessionStore.saveMessages(sessionId, messages, channelCtx?.channelType);\n\n // Auto-set title from first user message if still default\n const session = sessionStore.getSession(sessionId);\n if (session && session.title === \"New Chat\") {\n const firstUserMsg = messages.find((m) => m.role === \"user\");\n if (firstUserMsg) {\n const text =\n typeof firstUserMsg.content === \"string\"\n ? firstUserMsg.content\n : firstUserMsg.content\n .filter((p) => p.type === \"text\" && p.text)\n .map((p) => p.text)\n .join(\" \");\n if (text) {\n sessionStore.updateTitle(\n sessionId,\n text.length > 80 ? text.slice(0, 80) + \"…\" : text,\n );\n }\n }\n }\n },\n onPermissionRequest: options?.onPermissionRequest,\n onQuestionnaireRequest: options?.onQuestionnaireRequest,\n });\n\n // Inject runner reference for subagent tool\n setSubagentRunner(runner);\n\n return runner;\n }\n\n const ctx: GatewayContext = {\n config,\n configPath,\n dataDir,\n bundledSkillsDir,\n workspaceManager,\n credentialStore,\n usageStore,\n modelStore,\n getSessionStore,\n createAgentRunner,\n };\n\n // Express app\n const app = express();\n\n // CORS: only allow local origins (localhost/127.0.0.1) to protect against\n // cross-origin attacks from external sites. Additional origins can be allowed\n // via CORTASK_CORS_ORIGIN env var.\n const corsOrigin = process.env.CORTASK_CORS_ORIGIN;\n app.use(cors({\n origin: (origin, callback) => {\n // Allow requests with no Origin (same-origin, curl, etc.)\n if (!origin) return callback(null, true);\n try {\n const url = new URL(origin);\n if (url.hostname === \"localhost\" || url.hostname === \"127.0.0.1\" || url.hostname === finalHost) {\n return callback(null, true);\n }\n } catch { /* invalid origin */ }\n if (corsOrigin && origin === corsOrigin) return callback(null, true);\n callback(new Error(\"CORS not allowed\"));\n },\n }));\n\n // Security headers\n app.use((_req, res, next) => {\n res.setHeader(\"X-Content-Type-Options\", \"nosniff\");\n res.setHeader(\"X-Frame-Options\", \"DENY\");\n next();\n });\n\n app.use(express.json({ limit: \"10mb\" }));\n\n // HTTP + WebSocket server (created early so wss is available to routes)\n const server = createServer(app);\n wss = new WebSocketServer({\n server,\n path: \"/ws\",\n verifyClient: ({ origin }: { origin?: string }) => {\n // Allow connections with no Origin (e.g. non-browser clients)\n if (!origin) return true;\n // Allow any local origin (localhost/127.0.0.1) regardless of port —\n // the threat is external sites, not local processes\n try {\n const url = new URL(origin);\n if (url.hostname === \"localhost\" || url.hostname === \"127.0.0.1\" || url.hostname === finalHost) {\n return true;\n }\n } catch { /* invalid origin → reject */ }\n if (corsOrigin && origin === corsOrigin) return true;\n return false;\n },\n });\n wss.on(\"connection\", (ws: WebSocket) => {\n handleWebSocket(ws, ctx);\n });\n\n // API routes\n app.use(\"/api/onboarding\", createOnboardingRoutes(ctx));\n app.use(\"/api/workspaces\", createWorkspaceRoutes(ctx));\n app.use(\"/api/sessions\", createSessionRoutes(ctx));\n app.use(\"/api/credentials\", createCredentialRoutes(ctx));\n app.use(\"/api/providers\", createProviderRoutes(ctx));\n app.use(\"/api/config\", createConfigRoutes(ctx));\n app.use(\"/api/skills\", createSkillRoutes(ctx));\n app.use(\"/api/cron\", createCronRoutes(cronService));\n app.use(\"/api/usage\", createUsageRoutes(usageStore));\n app.use(\"/api/models\", createModelRoutes(ctx));\n app.use(\"/api/templates\", createTemplateRoutes(templateStore));\n async function createChannelAdapter(id: string): Promise<ChannelPlugin | null> {\n if (id === \"telegram\") {\n const botToken = await credentialStore.get(\"channel.telegram.botToken\");\n if (!botToken) return null;\n const adapter = new TelegramAdapter({\n botToken,\n allowedUsers: config.channels?.telegram?.allowedUsers ?? [],\n });\n wireMessageHandler(adapter);\n return adapter;\n }\n if (id === \"discord\") {\n const botToken = await credentialStore.get(\"channel.discord.botToken\");\n if (!botToken) return null;\n const adapter = new DiscordAdapter({ botToken });\n wireMessageHandler(adapter);\n return adapter;\n }\n if (id === \"whatsapp\") {\n const contactsJson = await credentialStore.get(\"channel.whatsapp.trustedContacts\");\n const trustedContacts = contactsJson ? JSON.parse(contactsJson) : [];\n const adapter = new WhatsAppAdapter({ trustedContacts });\n wireMessageHandler(adapter);\n return adapter;\n }\n return null;\n }\n\n app.use(\"/api/channels\", createChannelRoutes(channels, ctx, createChannelAdapter, wss));\n app.use(\"/api/artifacts\", createArtifactRoutes(artifactStore));\n\n // Health check\n let gatewayReady = false;\n app.get(\"/api/health\", (_req, res) => {\n res.json({ status: \"ok\", version: PKG_VERSION, ready: gatewayReady });\n });\n\n // Update check\n app.get(\"/api/updates/check\", async (_req, res) => {\n try {\n const response = await fetch(\"https://registry.npmjs.org/cortask/latest\");\n if (!response.ok) throw new Error(\"Failed to fetch from npm\");\n const data = await response.json() as { version: string };\n const latest = data.version;\n const hasUpdate = latest !== PKG_VERSION;\n res.json({ currentVersion: PKG_VERSION, latestVersion: latest, hasUpdate });\n } catch (err) {\n res.json({ currentVersion: PKG_VERSION, latestVersion: null, hasUpdate: false, error: (err as Error).message });\n }\n });\n\n // Serve built UI static files (for standalone & desktop mode)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const resourcesPath = (process as any).resourcesPath as string | undefined;\n const uiDistCandidates = [\n path.resolve(\"../ui/dist\"), // monorepo dev\n path.resolve(__dirname, \"../../ui/dist\"), // relative to gateway dist\n ...(resourcesPath ? [path.resolve(resourcesPath, \"ui\")] : []), // electron packaged\n ];\n for (const uiDir of uiDistCandidates) {\n if (fs.existsSync(path.join(uiDir, \"index.html\"))) {\n app.use(express.static(uiDir));\n // SPA fallback: serve index.html for non-API routes\n app.get(\"*\", (_req, res, next) => {\n if (_req.path.startsWith(\"/api/\") || _req.path.startsWith(\"/ws\")) {\n return next();\n }\n res.sendFile(path.join(uiDir, \"index.html\"));\n });\n logger.info(`Serving UI from ${uiDir}`, \"gateway\");\n break;\n }\n }\n\n const envPort = process.env.CORTASK_PORT ? parseInt(process.env.CORTASK_PORT, 10) : undefined;\n const envHost = process.env.CORTASK_HOST;\n const finalPort = port ?? envPort ?? config.server.port;\n const finalHost = host ?? envHost ?? config.server.host;\n\n // Wire cron executor to agent runner\n cronService.setExecutor(async (job) => {\n // Check spending limits before running cron jobs\n if (config.spending.enabled) {\n const summary = usageStore.getSummary(config.spending.period);\n if (config.spending.maxTokens && summary.totalTokens >= config.spending.maxTokens) {\n throw new Error(`Spending limit reached: ${summary.totalTokens.toLocaleString()} / ${config.spending.maxTokens.toLocaleString()} tokens`);\n }\n if (config.spending.maxCostUsd && summary.totalCostUsd >= config.spending.maxCostUsd) {\n throw new Error(`Spending limit reached: $${summary.totalCostUsd.toFixed(2)} / $${config.spending.maxCostUsd.toFixed(2)}`);\n }\n }\n\n const workspaces = await workspaceManager.list();\n let workspacePath: string;\n\n if (job.workspaceId) {\n const ws = await workspaceManager.get(job.workspaceId);\n workspacePath = ws?.rootPath ?? workspaces[0]?.rootPath ?? dataDir;\n } else {\n workspacePath = workspaces[0]?.rootPath ?? dataDir;\n }\n\n const runner = await createAgentRunner(workspacePath);\n const result = await runner.run({ prompt: job.prompt });\n\n // Deliver to channel if specified\n if (job.delivery.channel && job.delivery.target) {\n const channel = channels.get(job.delivery.channel);\n if (!channel) {\n logger.warn(`Cron job \"${job.name}\" delivery failed: channel \"${job.delivery.channel}\" not found`, \"cron\");\n } else if (!channel.isRunning()) {\n logger.warn(`Cron job \"${job.name}\" delivery failed: channel \"${job.delivery.channel}\" is not running`, \"cron\");\n } else {\n await channel.sendMessage(job.delivery.target, result.response);\n }\n } else if (!job.delivery.channel && !job.delivery.target) {\n logger.debug(`Cron job \"${job.name}\" has no delivery channel configured`, \"cron\");\n }\n\n return result.response;\n });\n\n // Start cron service\n cronService.start();\n\n // Find an available port (try up to 10 starting from finalPort)\n let actualPort = finalPort;\n for (let attempt = 0; attempt < 10; attempt++) {\n const inUse = await new Promise<boolean>((resolve) => {\n const tester = createServer();\n tester.once(\"error\", () => resolve(true));\n tester.listen(actualPort, finalHost, () => {\n tester.close(() => resolve(false));\n });\n });\n if (!inUse) break;\n logger.info(`Port ${actualPort} in use, trying ${actualPort + 1}`, \"gateway\");\n actualPort++;\n if (attempt === 9) throw new Error(`No available port found (tried ${finalPort}-${actualPort})`);\n }\n\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(actualPort, finalHost, () => {\n server.removeAllListeners(\"error\");\n resolve();\n });\n });\n\n logger.info(\n `Gateway running on http://${finalHost}:${actualPort}`,\n \"gateway\",\n );\n console.log(`Cortask gateway running on http://${finalHost}:${actualPort}`);\n\n // Prepare gateway: install browser, start channels, then mark ready\n (async () => {\n try {\n await ensureBrowserInstalled();\n } catch (err) {\n logger.debug(`Browser pre-install skipped: ${err instanceof Error ? err.message : err}`, \"gateway\");\n }\n gatewayReady = true;\n logger.info(\"Gateway ready\", \"gateway\");\n })();\n\n // Auto-start channels that were previously enabled\n const knownChannelIds = [\"telegram\", \"discord\", \"whatsapp\"];\n for (const id of knownChannelIds) {\n credentialStore.get(`channel.${id}.enabled`).then(async (enabled) => {\n if (enabled !== \"true\") return;\n try {\n let channel = channels.get(id);\n if (!channel) {\n const created = await createChannelAdapter(id);\n if (!created) return;\n channel = created;\n channels.set(id, channel);\n }\n await channel.start();\n logger.info(`Channel \"${id}\" auto-started`, \"gateway\");\n } catch (err) {\n logger.error(`Failed to auto-start channel \"${id}\": ${err}`, \"gateway\");\n }\n });\n }\n\n // Cleanup completed subagent records every 10 minutes\n setInterval(() => {\n cleanupSubagentRecords(30 * 60 * 1000); // 30 min TTL\n }, 10 * 60 * 1000);\n\n return { server, wss, ctx };\n}\n\nexport function getDefaultModel(providerId: string): string {\n switch (providerId) {\n case \"anthropic\":\n return \"claude-sonnet-4-5-20250929\";\n case \"openai\":\n return \"gpt-4o\";\n case \"google\":\n return \"gemini-2.0-flash\";\n case \"moonshot\":\n return \"moonshot-v1-8k\";\n case \"grok\":\n return \"grok-3-latest\";\n case \"openrouter\":\n return \"openai/gpt-4o\";\n case \"minimax\":\n return \"MiniMax-Text-01\";\n default:\n return \"claude-sonnet-4-5-20250929\";\n }\n}\n","import { Router } from \"express\";\nimport path from \"node:path\";\nimport type { GatewayContext } from \"../server.js\";\n\nexport function createWorkspaceRoutes(ctx: GatewayContext): Router {\n const router = Router();\n\n router.get(\"/\", async (_req, res) => {\n try {\n const workspaces = await ctx.workspaceManager.list();\n res.json(workspaces);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.get(\"/:id\", async (req, res) => {\n try {\n const workspace = await ctx.workspaceManager.get(req.params.id);\n if (!workspace) {\n res.status(404).json({ error: \"Workspace not found\" });\n return;\n }\n res.json(workspace);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.post(\"/\", async (req, res) => {\n try {\n const { name, rootPath } = req.body;\n if (!name) {\n res.status(400).json({ error: \"name is required\" });\n return;\n }\n const workspace = await ctx.workspaceManager.create(name, rootPath || undefined);\n res.status(201).json(workspace);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.put(\"/reorder\", async (req, res) => {\n try {\n const { ids } = req.body;\n if (!Array.isArray(ids)) {\n res.status(400).json({ error: \"ids array required\" });\n return;\n }\n await ctx.workspaceManager.reorder(ids);\n res.json({ ok: true });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.put(\"/:id\", async (req, res) => {\n try {\n await ctx.workspaceManager.update(req.params.id, req.body);\n const updated = await ctx.workspaceManager.get(req.params.id);\n res.json(updated);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.delete(\"/:id\", async (req, res) => {\n try {\n await ctx.workspaceManager.delete(req.params.id);\n res.status(204).send();\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.post(\"/:id/open\", async (req, res) => {\n try {\n const workspace = await ctx.workspaceManager.open(req.params.id);\n if (!workspace) {\n res.status(404).json({ error: \"Workspace not found\" });\n return;\n }\n res.json(workspace);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n // Serve workspace files for download\n router.get(\"/:id/files/*\", async (req, res) => {\n try {\n const workspace = await ctx.workspaceManager.get(req.params.id);\n if (!workspace) {\n res.status(404).json({ error: \"Workspace not found\" });\n return;\n }\n\n const relPath = (req.params as unknown as Record<string, string>)[\"0\"];\n if (!relPath) {\n res.status(400).json({ error: \"File path required\" });\n return;\n }\n\n const fullPath = path.resolve(workspace.rootPath, relPath);\n\n // Prevent directory traversal\n if (!fullPath.startsWith(path.resolve(workspace.rootPath))) {\n res.status(403).json({ error: \"Path outside workspace\" });\n return;\n }\n\n res.sendFile(fullPath, (err) => {\n if (err) {\n res.status(404).json({ error: \"File not found\" });\n }\n });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n return router;\n}\n","import { Router } from \"express\";\nimport type { GatewayContext } from \"../server.js\";\n\nexport function createSessionRoutes(ctx: GatewayContext): Router {\n const router = Router();\n\n router.get(\"/\", async (req, res) => {\n try {\n const workspaceId = req.query.workspaceId as string;\n if (!workspaceId) {\n res.status(400).json({ error: \"workspaceId query param required\" });\n return;\n }\n const workspace = await ctx.workspaceManager.get(workspaceId);\n if (!workspace) {\n res.status(404).json({ error: \"Workspace not found\" });\n return;\n }\n const store = ctx.getSessionStore(workspace.rootPath);\n const sessions = store.listSessions();\n res.json(sessions);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.get(\"/:id\", async (req, res) => {\n try {\n const workspaceId = req.query.workspaceId as string;\n if (!workspaceId) {\n res.status(400).json({ error: \"workspaceId query param required\" });\n return;\n }\n const workspace = await ctx.workspaceManager.get(workspaceId);\n if (!workspace) {\n res.status(404).json({ error: \"Workspace not found\" });\n return;\n }\n const store = ctx.getSessionStore(workspace.rootPath);\n const session = store.getSession(req.params.id);\n if (!session) {\n res.status(404).json({ error: \"Session not found\" });\n return;\n }\n res.json(session);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.delete(\"/:id\", async (req, res) => {\n try {\n const workspaceId = req.query.workspaceId as string;\n if (!workspaceId) {\n res.status(400).json({ error: \"workspaceId query param required\" });\n return;\n }\n const workspace = await ctx.workspaceManager.get(workspaceId);\n if (!workspace) {\n res.status(404).json({ error: \"Workspace not found\" });\n return;\n }\n const store = ctx.getSessionStore(workspace.rootPath);\n store.deleteSession(req.params.id);\n res.status(204).send();\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n return router;\n}\n","import { Router } from \"express\";\nimport { clearSkillCache } from \"@cortask/core\";\nimport type { GatewayContext } from \"../server.js\";\n\nexport function createCredentialRoutes(ctx: GatewayContext): Router {\n const router = Router();\n\n router.get(\"/\", async (_req, res) => {\n try {\n const keys = await ctx.credentialStore.list();\n res.json(keys);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.post(\"/\", async (req, res) => {\n try {\n const { key, value } = req.body;\n if (!key || !value) {\n res.status(400).json({ error: \"key and value are required\" });\n return;\n }\n await ctx.credentialStore.set(key, value);\n clearSkillCache(); // Invalidate skill cache when credentials change\n res.status(201).json({ key });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.get(\"/:key\", async (req, res) => {\n try {\n const value = await ctx.credentialStore.get(req.params.key);\n if (value === null) {\n res.status(404).json({ error: \"Key not found\" });\n return;\n }\n res.json({ key: req.params.key, value });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.delete(\"/:key\", async (req, res) => {\n try {\n await ctx.credentialStore.delete(req.params.key);\n clearSkillCache(); // Invalidate skill cache when credentials change\n res.status(204).send();\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n return router;\n}\n","import { Router } from \"express\";\nimport type { GatewayContext } from \"../server.js\";\nimport { createProvider, saveConfig, type ProviderId } from \"@cortask/core\";\n\nconst PROVIDERS = [\n { id: \"anthropic\", name: \"Anthropic\", defaultModel: \"claude-sonnet-4-5-20250929\", credKey: \"provider.anthropic.apiKey\" },\n { id: \"openai\", name: \"OpenAI\", defaultModel: \"gpt-4o\", credKey: \"provider.openai.apiKey\" },\n { id: \"google\", name: \"Google\", defaultModel: \"gemini-2.0-flash\", credKey: \"provider.google.apiKey\" },\n { id: \"moonshot\", name: \"Moonshot\", defaultModel: \"moonshot-v1-8k\", credKey: \"provider.moonshot.apiKey\" },\n { id: \"grok\", name: \"Grok\", defaultModel: \"grok-3-latest\", credKey: \"provider.grok.apiKey\" },\n { id: \"openrouter\", name: \"OpenRouter\", defaultModel: \"openai/gpt-4o\", credKey: \"provider.openrouter.apiKey\" },\n { id: \"minimax\", name: \"MiniMax\", defaultModel: \"MiniMax-Text-01\", credKey: \"provider.minimax.apiKey\" },\n { id: \"ollama\", name: \"Ollama\", defaultModel: \"llama3\", credKey: \"provider.ollama.host\" },\n] as const;\n\nexport function createProviderRoutes(ctx: GatewayContext): Router {\n const router = Router();\n\n router.get(\"/\", async (_req, res) => {\n try {\n const providers = await Promise.all(\n PROVIDERS.map(async (p) => {\n const providerConfig = ctx.config.providers[p.id as ProviderId];\n const configModel = providerConfig?.model;\n return {\n id: p.id,\n name: p.name,\n defaultModel: configModel || p.defaultModel,\n configured: await ctx.credentialStore.has(p.credKey),\n isDefault: ctx.config.providers.default === p.id,\n };\n }),\n );\n res.json(providers);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.put(\"/default\", async (req, res) => {\n try {\n const { providerId, model } = req.body as { providerId: string; model: string };\n if (!providerId || !model) {\n res.status(400).json({ error: \"providerId and model are required\" });\n return;\n }\n\n // Update in-memory config\n ctx.config.providers.default = providerId;\n const key = providerId as ProviderId;\n if (key in ctx.config.providers) {\n ctx.config.providers[key] = { model };\n }\n\n // Persist to config file\n await saveConfig(ctx.configPath, ctx.config);\n\n res.json({ providerId, model });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.post(\"/:id/test\", async (req, res) => {\n try {\n const providerId = req.params.id as ProviderId;\n const provMeta = PROVIDERS.find((p) => p.id === providerId);\n const apiKey = await ctx.credentialStore.get(\n provMeta?.credKey ?? `provider.${providerId}.apiKey`,\n );\n if (!apiKey) {\n res.status(400).json({ error: \"No API key configured\" });\n return;\n }\n\n const provider = createProvider(providerId, apiKey);\n const result = await provider.generateText({\n model:\n PROVIDERS.find((p) => p.id === providerId)?.defaultModel ??\n \"claude-sonnet-4-5-20250929\",\n messages: [{ role: \"user\", content: \"Say hi in 3 words\" }],\n maxTokens: 20,\n });\n\n res.json({\n success: true,\n response: result.content,\n usage: result.usage,\n });\n } catch (err) {\n res.status(500).json({\n success: false,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n\n return router;\n}\n","import crypto from \"node:crypto\";\nimport { Router } from \"express\";\nimport path from \"node:path\";\nimport {\n loadSkills,\n clearSkillCache,\n installSkillFromGit,\n removeSkill,\n createSkill,\n updateSkill,\n readSkillFile,\n validateSkillName,\n getCredentialStorageKey,\n getOAuth2StorageKeys,\n buildSkillOAuth2AuthUrl,\n exchangeSkillOAuth2Code,\n revokeSkillOAuth2,\n} from \"@cortask/core\";\nimport type { GatewayContext } from \"../server.js\";\n\n// In-memory CSRF state store for OAuth2 flows\nconst oauthStates = new Map<string, { skillName: string; credentialId: string; createdAt: number }>();\nconst STATE_TTL_MS = 10 * 60 * 1000; // 10 minutes\n\n// Clean up expired states every minute\nsetInterval(() => {\n const now = Date.now();\n for (const [key, val] of oauthStates) {\n if (now - val.createdAt > STATE_TTL_MS) {\n oauthStates.delete(key);\n }\n }\n}, 60_000).unref();\n\nfunction oauthHtml(title: string, message: string, script?: string): string {\n return `<html><body><h2>${title}</h2><p>${message}</p>${script ? `<script>${script}</script>` : \"<p>You can close this tab.</p>\"}</body></html>`;\n}\n\nexport function createSkillRoutes(ctx: GatewayContext): Router {\n const router = Router();\n\n const bundledDir = ctx.bundledSkillsDir;\n const userSkillsDir = path.join(ctx.dataDir, \"skills\");\n\n async function findSkillAndOAuth(name: string) {\n const skills = await loadSkills(\n bundledDir,\n userSkillsDir,\n ctx.config.skills.dirs,\n ctx.credentialStore,\n );\n const skill = skills.find((s) => s.manifest.name === name);\n if (!skill) return null;\n const oauth2Cred = skill.credentialSchema?.credentials.find((c) => c.type === \"oauth2\");\n return { skill, oauth2Cred };\n }\n\n router.get(\"/\", async (_req, res) => {\n try {\n const skills = await loadSkills(\n bundledDir,\n userSkillsDir,\n ctx.config.skills.dirs,\n ctx.credentialStore,\n );\n\n const result = skills.map((s) => ({\n name: s.manifest.name,\n description: s.manifest.description,\n eligible: s.eligible,\n ineligibleReason: s.ineligibleReason,\n source: s.source,\n editable: s.editable,\n hasCodeTools: s.hasCodeTools,\n toolCount: (s.manifest.tools?.length ?? 0) + (s.hasCodeTools ? 1 : 0),\n tags: s.manifest.metadata?.tags ?? [],\n homepage: (s.manifest.metadata?.homepage as string) ?? null,\n content: s.content,\n installOptions: s.installOptions,\n credentialSchema: s.credentialSchema,\n credentialStatus: s.credentialStatus,\n }));\n\n res.json(result);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.post(\"/install\", async (req, res) => {\n try {\n const { gitUrl } = req.body;\n if (!gitUrl) {\n res.status(400).json({ error: \"gitUrl is required\" });\n return;\n }\n\n const result = await installSkillFromGit(gitUrl, userSkillsDir);\n clearSkillCache();\n res.status(201).json(result);\n } catch (err) {\n res.status(500).json({\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n\n router.delete(\"/:name\", async (req, res) => {\n try {\n await removeSkill(req.params.name, userSkillsDir);\n clearSkillCache();\n res.status(204).send();\n } catch (err) {\n res.status(500).json({\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n\n // ───── Create custom skill ─────\n router.post(\"/\", async (req, res) => {\n try {\n const { name, content } = req.body;\n if (!name || !content) {\n res.status(400).json({ error: \"name and content are required\" });\n return;\n }\n\n const nameErr = validateSkillName(name);\n if (nameErr) {\n res.status(400).json({ error: nameErr });\n return;\n }\n\n // Check for conflict with bundled skills\n const allSkills = await loadSkills(\n bundledDir,\n userSkillsDir,\n ctx.config.skills.dirs,\n ctx.credentialStore,\n );\n const isBundled = allSkills.some(\n (s) => s.source === \"bundled\" && s.manifest.name === name,\n );\n if (isBundled) {\n res.status(409).json({\n error: `A built-in skill named \"${name}\" already exists. Choose a different name.`,\n });\n return;\n }\n\n const result = await createSkill(userSkillsDir, name, content);\n res.status(201).json(result);\n } catch (err) {\n res.status(500).json({\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n\n // ───── Update custom skill ─────\n router.put(\"/:name\", async (req, res) => {\n try {\n const { content } = req.body;\n if (!content) {\n res.status(400).json({ error: \"content is required\" });\n return;\n }\n\n // Reject editing bundled skills\n const allSkills = await loadSkills(\n bundledDir,\n userSkillsDir,\n ctx.config.skills.dirs,\n ctx.credentialStore,\n );\n const skill = allSkills.find((s) => s.manifest.name === req.params.name);\n if (skill && !skill.editable) {\n res.status(403).json({ error: \"Built-in skills cannot be edited\" });\n return;\n }\n\n await updateSkill(userSkillsDir, req.params.name, content);\n res.json({ name: req.params.name });\n } catch (err) {\n res.status(500).json({\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n\n // ───── Get raw SKILL.md content for editing ─────\n router.get(\"/:name/content\", async (req, res) => {\n try {\n const content = await readSkillFile(userSkillsDir, req.params.name);\n res.json({ name: req.params.name, content });\n } catch (err) {\n res.status(404).json({\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n\n // ───── OAuth2: Start authorization flow ─────\n router.get(\"/:name/oauth2/authorize\", async (req, res) => {\n try {\n const name = req.params.name;\n const result = await findSkillAndOAuth(name);\n\n if (!result || !result.oauth2Cred?.oauth) {\n res.status(400).json({ error: \"Skill not found or has no OAuth2 config\" });\n return;\n }\n\n const credentialId = result.oauth2Cred.id;\n const clientIdKey = getCredentialStorageKey(name, credentialId, \"clientId\", result.oauth2Cred.storeAs);\n const clientId = await ctx.credentialStore.get(clientIdKey);\n\n if (!clientId) {\n res.status(400).json({ error: \"Client ID not configured. Save it before authorizing.\" });\n return;\n }\n\n const state = crypto.randomBytes(16).toString(\"hex\");\n oauthStates.set(state, { skillName: name, credentialId, createdAt: Date.now() });\n\n // Determine gateway base URL from the request\n const proto = req.headers[\"x-forwarded-proto\"] || req.protocol || \"http\";\n const host = req.headers[\"x-forwarded-host\"] || req.headers.host || \"localhost:3777\";\n const gatewayBaseUrl = `${proto}://${host}`;\n\n const redirectUri = `${gatewayBaseUrl}/api/skills/${encodeURIComponent(name)}/oauth2/callback`;\n const authorizationUrl = buildSkillOAuth2AuthUrl(\n name,\n result.oauth2Cred.oauth,\n clientId,\n redirectUri,\n state,\n );\n\n res.json({ authorizationUrl, redirectUri });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n // ───── OAuth2: Get redirect URI (for display before credentials are saved) ─────\n router.get(\"/:name/oauth2/redirect-uri\", (req, res) => {\n const name = req.params.name;\n const proto = req.headers[\"x-forwarded-proto\"] || req.protocol || \"http\";\n const host = req.headers[\"x-forwarded-host\"] || req.headers.host || \"localhost:3777\";\n const gatewayBaseUrl = `${proto}://${host}`;\n const redirectUri = `${gatewayBaseUrl}/api/skills/${encodeURIComponent(name)}/oauth2/callback`;\n res.json({ redirectUri });\n });\n\n // ───── OAuth2: Callback from provider ─────\n router.get(\"/:name/oauth2/callback\", async (req, res) => {\n const { code, state, error: oauthError } = req.query as Record<string, string>;\n const name = req.params.name;\n\n if (oauthError) {\n res.status(400).send(oauthHtml(\"OAuth Error\", oauthError));\n return;\n }\n\n if (!code || !state) {\n res.status(400).send(oauthHtml(\"Error\", \"Missing code or state parameter.\"));\n return;\n }\n\n // Validate CSRF state\n const stateEntry = oauthStates.get(state);\n if (!stateEntry || stateEntry.skillName !== name) {\n res.status(400).send(oauthHtml(\"Error\", \"Invalid or expired OAuth state. Please try again.\"));\n return;\n }\n oauthStates.delete(state);\n\n if (Date.now() - stateEntry.createdAt > STATE_TTL_MS) {\n res.status(400).send(oauthHtml(\"Error\", \"OAuth state expired. Please try again.\"));\n return;\n }\n\n try {\n const result = await findSkillAndOAuth(name);\n if (!result || !result.oauth2Cred?.oauth) {\n res.status(400).send(oauthHtml(\"Error\", \"Skill not found or has no OAuth2 config.\"));\n return;\n }\n\n const credentialId = result.oauth2Cred.id;\n const clientIdKey = getCredentialStorageKey(name, credentialId, \"clientId\", result.oauth2Cred.storeAs);\n const clientSecretKey = getCredentialStorageKey(name, credentialId, \"clientSecret\", result.oauth2Cred.storeAs);\n const clientId = await ctx.credentialStore.get(clientIdKey);\n const clientSecret = await ctx.credentialStore.get(clientSecretKey);\n\n if (!clientId || !clientSecret) {\n res.status(400).send(oauthHtml(\"Error\", \"OAuth client credentials not configured.\"));\n return;\n }\n\n const proto = req.headers[\"x-forwarded-proto\"] || req.protocol || \"http\";\n const host = req.headers[\"x-forwarded-host\"] || req.headers.host || \"localhost:3777\";\n const gatewayBaseUrl = `${proto}://${host}`;\n const redirectUri = `${gatewayBaseUrl}/api/skills/${encodeURIComponent(name)}/oauth2/callback`;\n\n await exchangeSkillOAuth2Code(\n name,\n credentialId,\n result.oauth2Cred.oauth,\n clientId,\n clientSecret,\n code,\n redirectUri,\n ctx.credentialStore,\n );\n\n clearSkillCache();\n\n res.send(oauthHtml(\n \"Authorization Successful\",\n `Skill \"${name}\" has been authorized.`,\n `if (window.opener) { window.opener.postMessage({ type: \"oauth-success\", skill: \"${name}\" }, \"*\"); }`,\n ));\n } catch (err) {\n res.status(500).send(oauthHtml(\"Error\", `Token exchange failed: ${err instanceof Error ? err.message : String(err)}`));\n }\n });\n\n // ───── OAuth2: Token status ─────\n router.get(\"/:name/oauth2/status\", async (req, res) => {\n try {\n const name = req.params.name;\n const result = await findSkillAndOAuth(name);\n\n if (!result || !result.oauth2Cred) {\n res.status(400).json({ error: \"Skill not found or has no OAuth2 config\" });\n return;\n }\n\n const keys = getOAuth2StorageKeys(name, result.oauth2Cred.id);\n const hasToken = await ctx.credentialStore.has(keys.accessToken);\n const expiresAtStr = await ctx.credentialStore.get(keys.expiresAt);\n const hasRefresh = await ctx.credentialStore.has(keys.refreshToken);\n\n let expiresAt: number | null = null;\n let expired = false;\n if (expiresAtStr) {\n expiresAt = parseInt(expiresAtStr, 10);\n expired = !isNaN(expiresAt) && Date.now() >= expiresAt;\n }\n\n res.json({ connected: hasToken, expired, expiresAt, hasRefreshToken: hasRefresh });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n // ───── OAuth2: Revoke tokens ─────\n router.post(\"/:name/oauth2/revoke\", async (req, res) => {\n try {\n const name = req.params.name;\n const result = await findSkillAndOAuth(name);\n\n if (!result || !result.oauth2Cred) {\n res.status(400).json({ error: \"Skill not found or has no OAuth2 config\" });\n return;\n }\n\n await revokeSkillOAuth2(name, result.oauth2Cred.id, ctx.credentialStore);\n clearSkillCache();\n res.json({ ok: true });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n return router;\n}\n","import { Router } from \"express\";\nimport type { CronService } from \"@cortask/core\";\nimport type { CronJobCreate } from \"@cortask/core\";\n\nexport function createCronRoutes(cronService: CronService): Router {\n const router = Router();\n\n // List all cron jobs\n router.get(\"/\", (_req, res) => {\n try {\n const jobs = cronService.list();\n const result = jobs.map((job) => {\n const state = cronService.getState(job.id);\n return { ...job, state };\n });\n res.json(result);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n // Get single job\n router.get(\"/:id\", (req, res) => {\n try {\n const job = cronService.getJob(req.params.id);\n if (!job) {\n res.status(404).json({ error: \"Job not found\" });\n return;\n }\n const state = cronService.getState(job.id);\n res.json({ ...job, state });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n // Create a cron job\n router.post(\"/\", (req, res) => {\n try {\n const input: CronJobCreate = req.body;\n if (!input.name || !input.schedule || !input.prompt) {\n res\n .status(400)\n .json({ error: \"name, schedule, and prompt are required\" });\n return;\n }\n const job = cronService.add(input);\n res.status(201).json(job);\n } catch (err) {\n res.status(500).json({\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n\n // Update a cron job\n router.put(\"/:id\", (req, res) => {\n try {\n const updated = cronService.update(req.params.id, req.body);\n if (!updated) {\n res.status(404).json({ error: \"Job not found\" });\n return;\n }\n res.json(updated);\n } catch (err) {\n res.status(500).json({\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n\n // Delete a cron job\n router.delete(\"/:id\", (req, res) => {\n try {\n const removed = cronService.remove(req.params.id);\n if (!removed) {\n res.status(404).json({ error: \"Job not found\" });\n return;\n }\n res.status(204).send();\n } catch (err) {\n res.status(500).json({\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n\n // Run a job immediately\n router.post(\"/:id/run\", async (req, res) => {\n try {\n await cronService.runNow(req.params.id);\n res.json({ status: \"executed\" });\n } catch (err) {\n res.status(500).json({\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n\n return router;\n}\n","import { Router } from \"express\";\nimport type { WebSocketServer } from \"ws\";\nimport type { ChannelPlugin } from \"@cortask/channels\";\nimport { WhatsAppAdapter } from \"@cortask/channels\";\nimport type { TrustedContact } from \"@cortask/channels\";\nimport type { GatewayContext } from \"../server.js\";\nimport { broadcastChannelStatus } from \"../ws.js\";\n\nexport function createChannelRoutes(\n channels: Map<string, ChannelPlugin>,\n ctx: GatewayContext,\n createChannel: (id: string) => Promise<ChannelPlugin | null>,\n wss: WebSocketServer,\n): Router {\n const router = Router();\n\n const KNOWN_CHANNELS = [\n { id: \"telegram\", name: \"Telegram\" },\n { id: \"whatsapp\", name: \"WhatsApp\" },\n { id: \"discord\", name: \"Discord\" },\n ];\n\n // List channel statuses\n router.get(\"/\", (_req, res) => {\n const result = KNOWN_CHANNELS.map((def) => {\n const ch = channels.get(def.id);\n const base = { id: def.id, name: ch?.name ?? def.name, running: ch?.isRunning() ?? false };\n // Add WhatsApp auth status\n if (def.id === \"whatsapp\") {\n const wa = ch as WhatsAppAdapter | undefined;\n return { ...base, authenticated: wa?.isAuthenticated() ?? new WhatsAppAdapter().isAuthenticated() };\n }\n return base;\n });\n res.json(result);\n });\n\n // Start a channel (create on-demand if needed)\n router.post(\"/:id/start\", async (req, res) => {\n const { id } = req.params;\n let channel = channels.get(id);\n\n if (!channel) {\n try {\n const created = await createChannel(id);\n if (!created) {\n res.status(400).json({ error: `No credentials configured for ${id}` });\n return;\n }\n channel = created;\n } catch (err) {\n res.status(400).json({\n error: err instanceof Error ? err.message : String(err),\n });\n return;\n }\n channels.set(id, channel);\n }\n\n try {\n await channel.start();\n await ctx.credentialStore.set(`channel.${id}.enabled`, \"true\");\n broadcastChannelStatus(wss, { channelId: id, running: true, authenticated: true });\n res.json({ id, name: channel.name, running: true });\n } catch (err) {\n res.status(500).json({\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n\n // Stop a channel\n router.post(\"/:id/stop\", async (req, res) => {\n const channel = channels.get(req.params.id);\n if (!channel) {\n res.status(404).json({ error: \"Channel not found\" });\n return;\n }\n try {\n await channel.stop();\n await ctx.credentialStore.delete(`channel.${req.params.id}.enabled`);\n broadcastChannelStatus(wss, { channelId: req.params.id, running: false, authenticated: false });\n res.json({ id: req.params.id, name: channel.name, running: false });\n } catch (err) {\n res.status(500).json({\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n\n // WhatsApp: generate QR code for authentication + auto-start after scan\n router.post(\"/whatsapp/qr\", async (_req, res) => {\n try {\n // Ensure adapter exists\n let wa = channels.get(\"whatsapp\") as WhatsAppAdapter | undefined;\n if (!wa) {\n const created = await createChannel(\"whatsapp\");\n if (!created) {\n res.status(500).json({ error: \"Failed to create WhatsApp adapter\" });\n return;\n }\n wa = created as WhatsAppAdapter;\n channels.set(\"whatsapp\", wa);\n }\n\n const result = await wa.generateQR();\n res.json(result);\n\n // After returning QR, poll for authentication and auto-start\n if (result.success) {\n const pollInterval = 2000;\n const maxPolls = 30; // 60 seconds\n let polls = 0;\n\n const poller = setInterval(async () => {\n polls++;\n try {\n if (wa!.isAuthenticated() && !wa!.isRunning()) {\n clearInterval(poller);\n await wa!.start();\n await ctx.credentialStore.set(\"channel.whatsapp.enabled\", \"true\");\n broadcastChannelStatus(wss, { channelId: \"whatsapp\", running: true, authenticated: true });\n } else if (polls >= maxPolls) {\n clearInterval(poller);\n // Still broadcast auth status even if we don't auto-start\n if (wa!.isAuthenticated()) {\n broadcastChannelStatus(wss, { channelId: \"whatsapp\", running: false, authenticated: true });\n }\n }\n } catch (err) {\n clearInterval(poller);\n console.error(\"[whatsapp] Auto-start failed:\", err);\n }\n }, pollInterval);\n }\n } catch (err) {\n res.status(500).json({\n success: false,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n\n // WhatsApp: logout and clear auth\n router.post(\"/whatsapp/logout\", async (_req, res) => {\n const wa = channels.get(\"whatsapp\") as WhatsAppAdapter | undefined;\n if (!wa) {\n // Clear auth even without an adapter instance\n new WhatsAppAdapter().logout();\n res.json({ success: true });\n return;\n }\n try {\n await wa.logout();\n await ctx.credentialStore.delete(\"channel.whatsapp.enabled\");\n broadcastChannelStatus(wss, { channelId: \"whatsapp\", running: false, authenticated: false });\n res.json({ success: true });\n } catch (err) {\n res.status(500).json({\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n\n // WhatsApp: get trusted contacts\n router.get(\"/whatsapp/contacts\", async (_req, res) => {\n try {\n const json = await ctx.credentialStore.get(\"channel.whatsapp.trustedContacts\");\n const contacts: TrustedContact[] = json ? JSON.parse(json) : [];\n res.json(contacts);\n } catch (err) {\n res.status(500).json({ error: err instanceof Error ? err.message : String(err) });\n }\n });\n\n // WhatsApp: save trusted contacts\n router.put(\"/whatsapp/contacts\", async (req, res) => {\n try {\n const contacts: TrustedContact[] = req.body;\n await ctx.credentialStore.set(\"channel.whatsapp.trustedContacts\", JSON.stringify(contacts));\n\n // Update running adapter if present\n const wa = channels.get(\"whatsapp\") as WhatsAppAdapter | undefined;\n if (wa) {\n wa.setTrustedContacts(contacts);\n }\n\n res.json(contacts);\n } catch (err) {\n res.status(500).json({ error: err instanceof Error ? err.message : String(err) });\n }\n });\n\n return router;\n}\n","import type { WebSocket } from \"ws\";\nimport type { WebSocketServer } from \"ws\";\nimport { getDefaultModel, type GatewayContext } from \"./server.js\";\nimport { logger, type QuestionnaireResponse } from \"@cortask/core\";\n\nexport interface ChannelStatusEvent {\n channelId: string;\n running: boolean;\n authenticated?: boolean;\n}\n\nexport function broadcastChannelStatus(wss: WebSocketServer, status: ChannelStatusEvent) {\n const data = JSON.stringify({ type: \"channel:status\", ...status });\n for (const client of wss.clients) {\n if (client.readyState === (client as WebSocket).OPEN) {\n client.send(data);\n }\n }\n}\n\nexport function broadcastSessionRefresh(wss: WebSocketServer, workspaceId: string) {\n const data = JSON.stringify({ type: \"session:refresh\", workspaceId });\n for (const client of wss.clients) {\n if (client.readyState === (client as WebSocket).OPEN) {\n client.send(data);\n }\n }\n}\n\ninterface ChatAttachment {\n mimeType: string;\n base64: string;\n name?: string;\n}\n\ninterface ChatMessage {\n type: \"chat\";\n sessionKey: string;\n message: string;\n workspaceId: string;\n attachments?: ChatAttachment[];\n}\n\ninterface CancelMessage {\n type: \"cancel\";\n sessionKey: string;\n}\n\ninterface PermissionResponse {\n type: \"permission_response\";\n requestId: string;\n approved: boolean;\n}\n\ninterface QuestionnaireResponseMessage {\n type: \"questionnaire_response\";\n requestId: string;\n responses: QuestionnaireResponse;\n}\n\ntype IncomingMessage =\n | ChatMessage\n | CancelMessage\n | PermissionResponse\n | QuestionnaireResponseMessage;\n\n// Pending permission requests: requestId → resolve callback\nconst pendingPermissions = new Map<string, (approved: boolean) => void>();\n\n// Pending questionnaire requests: requestId → resolve callback\nconst pendingQuestionnaires = new Map<\n string,\n (responses: QuestionnaireResponse) => void\n>();\n\n// Active runs: sessionKey → AbortController\nconst activeRuns = new Map<string, AbortController>();\n\nexport function handleWebSocket(ws: WebSocket, ctx: GatewayContext) {\n logger.info(\"WebSocket client connected\", \"gateway\");\n\n ws.on(\"message\", async (raw) => {\n let msg: IncomingMessage;\n try {\n msg = JSON.parse(raw.toString()) as IncomingMessage;\n } catch {\n sendError(ws, \"\", \"Invalid JSON\");\n return;\n }\n\n if (msg.type === \"chat\") {\n await handleChat(ws, msg, ctx);\n } else if (msg.type === \"cancel\") {\n logger.info(`Cancel requested for session ${msg.sessionKey}`, \"gateway\");\n const controller = activeRuns.get(msg.sessionKey);\n if (controller) {\n controller.abort();\n activeRuns.delete(msg.sessionKey);\n }\n } else if (msg.type === \"permission_response\") {\n const resolver = pendingPermissions.get(msg.requestId);\n if (resolver) {\n resolver(msg.approved);\n pendingPermissions.delete(msg.requestId);\n }\n } else if (msg.type === \"questionnaire_response\") {\n const resolver = pendingQuestionnaires.get(msg.requestId);\n if (resolver) {\n resolver(msg.responses);\n pendingQuestionnaires.delete(msg.requestId);\n }\n }\n });\n\n ws.on(\"close\", () => {\n logger.info(\"WebSocket client disconnected\", \"gateway\");\n // Abort all active runs when client disconnects\n for (const [id, controller] of activeRuns) {\n controller.abort();\n activeRuns.delete(id);\n }\n // Deny all pending permissions when client disconnects\n for (const [id, resolver] of pendingPermissions) {\n resolver(false);\n pendingPermissions.delete(id);\n }\n // Don't resolve pending questionnaires on disconnect — the user may\n // reconnect and submit. They will time out on their own if abandoned.\n });\n}\n\nfunction checkSpendingLimit(ctx: GatewayContext): string | null {\n const { spending } = ctx.config;\n if (!spending.enabled) return null;\n\n const summary = ctx.usageStore.getSummary(spending.period);\n\n if (spending.maxTokens && summary.totalTokens >= spending.maxTokens) {\n return `Spending limit reached: ${summary.totalTokens.toLocaleString()} / ${spending.maxTokens.toLocaleString()} tokens (${spending.period})`;\n }\n if (spending.maxCostUsd && summary.totalCostUsd >= spending.maxCostUsd) {\n return `Spending limit reached: $${summary.totalCostUsd.toFixed(2)} / $${spending.maxCostUsd.toFixed(2)} (${spending.period})`;\n }\n return null;\n}\n\nasync function handleChat(\n ws: WebSocket,\n msg: ChatMessage,\n ctx: GatewayContext,\n) {\n // Create abort controller for this run\n const abortController = new AbortController();\n activeRuns.set(msg.sessionKey, abortController);\n\n try {\n // Check spending limits before running\n const limitError = checkSpendingLimit(ctx);\n if (limitError) {\n sendError(ws, msg.sessionKey, limitError);\n return;\n }\n\n const workspace = await ctx.workspaceManager.get(msg.workspaceId);\n if (!workspace) {\n sendError(ws, msg.sessionKey, \"Workspace not found\");\n return;\n }\n\n const runner = await ctx.createAgentRunner(workspace.rootPath, {\n onPermissionRequest: async (req) => {\n return new Promise<boolean>((resolve) => {\n pendingPermissions.set(req.id, resolve);\n send(ws, {\n type: \"permission_request\",\n requestId: req.id,\n description: req.description,\n details: req.details,\n });\n\n // Auto-deny after 60 seconds\n setTimeout(() => {\n if (pendingPermissions.has(req.id)) {\n pendingPermissions.delete(req.id);\n resolve(false);\n }\n }, 60000);\n });\n },\n onQuestionnaireRequest: async (req) => {\n return new Promise<QuestionnaireResponse>((resolve) => {\n pendingQuestionnaires.set(req.id, resolve);\n send(ws, {\n type: \"questionnaire_request\",\n requestId: req.id,\n data: {\n title: req.title,\n description: req.description,\n questions: req.questions,\n },\n });\n\n });\n },\n });\n\n for await (const event of runner.runStream({\n prompt: msg.message,\n attachments: msg.attachments,\n sessionId: msg.sessionKey,\n workspaceId: msg.workspaceId,\n signal: abortController.signal,\n })) {\n if (ws.readyState !== ws.OPEN || abortController.signal.aborted) break;\n\n switch (event.type) {\n case \"thinking_delta\":\n send(ws, {\n type: \"thinking_delta\",\n sessionKey: msg.sessionKey,\n text: event.text,\n });\n break;\n case \"text_delta\":\n send(ws, {\n type: \"text_delta\",\n sessionKey: msg.sessionKey,\n text: event.text,\n });\n break;\n case \"tool_call_start\":\n send(ws, {\n type: \"tool_call_start\",\n sessionKey: msg.sessionKey,\n toolName: event.toolName,\n toolCallId: event.toolCallId,\n });\n break;\n case \"tool_result\":\n send(ws, {\n type: \"tool_result\",\n sessionKey: msg.sessionKey,\n toolCallId: event.toolCallId,\n toolName: event.toolName,\n toolArgs: event.toolArgs,\n content: event.toolResult?.content,\n isError: event.toolResult?.isError,\n });\n break;\n case \"done\":\n // Record usage for spending tracking\n if (event.usage) {\n try {\n const providerId = ctx.config.providers.default || \"anthropic\";\n const providerConfig = ctx.config.providers[providerId as keyof typeof ctx.config.providers];\n const model = (typeof providerConfig === \"object\" && providerConfig && \"model\" in providerConfig ? providerConfig.model : undefined) || getDefaultModel(providerId);\n ctx.usageStore.record(\n providerId,\n model,\n event.usage.inputTokens,\n event.usage.outputTokens,\n );\n } catch (err) {\n logger.error(`Failed to record usage: ${err}`, \"gateway\");\n }\n }\n send(ws, {\n type: \"done\",\n sessionKey: msg.sessionKey,\n usage: event.usage,\n });\n break;\n case \"error\":\n sendError(ws, msg.sessionKey, event.error ?? \"Unknown error\");\n break;\n }\n }\n } catch (err) {\n // Don't report abort errors as failures\n if (!abortController.signal.aborted) {\n sendError(\n ws,\n msg.sessionKey,\n err instanceof Error ? err.message : String(err),\n );\n }\n } finally {\n activeRuns.delete(msg.sessionKey);\n }\n}\n\nfunction send(ws: WebSocket, data: Record<string, unknown>) {\n if (ws.readyState === ws.OPEN) {\n ws.send(JSON.stringify(data));\n }\n}\n\nfunction sendError(ws: WebSocket, sessionKey: string, error: string) {\n send(ws, { type: \"error\", sessionKey, error });\n}\n","import { Router } from \"express\";\nimport type { ArtifactStore } from \"@cortask/core\";\n\nexport function createArtifactRoutes(artifactStore: ArtifactStore): Router {\n const router = Router();\n\n // Get artifact by ID\n router.get(\"/:id\", (req, res) => {\n const artifact = artifactStore.get(req.params.id);\n if (!artifact) {\n res.status(404).json({ error: \"Artifact not found or expired\" });\n return;\n }\n\n // If ?raw query param, serve the content directly with correct mime type\n if (req.query.raw !== undefined) {\n res.setHeader(\"Content-Type\", artifact.mimeType);\n // Image artifacts are stored as base64 — decode to binary\n if (artifact.type === \"image\") {\n res.send(Buffer.from(artifact.content, \"base64\"));\n } else {\n res.send(artifact.content);\n }\n return;\n }\n\n res.json({\n id: artifact.id,\n type: artifact.type,\n title: artifact.title,\n content: artifact.content,\n mimeType: artifact.mimeType,\n createdAt: artifact.createdAt,\n });\n });\n\n // List all artifacts\n router.get(\"/\", (_req, res) => {\n const artifacts = artifactStore.list();\n res.json(\n artifacts.map((a) => ({\n id: a.id,\n type: a.type,\n title: a.title,\n mimeType: a.mimeType,\n createdAt: a.createdAt,\n })),\n );\n });\n\n return router;\n}\n","import { Router } from \"express\";\nimport type { GatewayContext } from \"../server.js\";\nimport { saveConfig, AVAILABLE_PROVIDERS } from \"@cortask/core\";\n\nexport function createOnboardingRoutes(ctx: GatewayContext): Router {\n const router = Router();\n\n // GET /api/onboarding/status\n router.get(\"/status\", async (_req, res) => {\n try {\n const hasProvider = await Promise.any(\n AVAILABLE_PROVIDERS.flatMap((p) => [\n ctx.credentialStore.has(`provider.${p.id}.apiKey`),\n ctx.credentialStore.has(`provider.${p.id}.host`),\n ])\n ).catch(() => false);\n\n const workspaces = await ctx.workspaceManager.list();\n const hasWorkspace = workspaces.length > 0;\n\n res.json({\n completed: ctx.config.onboarded === true,\n hasProvider,\n hasWorkspace,\n });\n } catch (error) {\n res.status(500).json({\n error: error instanceof Error ? error.message : \"Unknown error\",\n });\n }\n });\n\n // POST /api/onboarding/complete\n router.post(\"/complete\", async (req, res) => {\n try {\n const { provider } = req.body;\n\n const isOllama = provider?.type === \"ollama\";\n if (!provider?.type || (!provider?.apiKey && !provider?.host)) {\n res.status(400).json({ error: \"Provider configuration required\" });\n return;\n }\n\n // Save credential to store\n const credKey = isOllama\n ? `provider.${provider.type}.host`\n : `provider.${provider.type}.apiKey`;\n const credValue = isOllama ? provider.host : provider.apiKey;\n await ctx.credentialStore.set(credKey, credValue);\n\n // Update config\n const newConfig = {\n ...ctx.config,\n onboarded: true,\n providers: {\n ...ctx.config.providers,\n default: provider.type,\n },\n };\n\n await saveConfig(ctx.configPath, newConfig);\n\n // Reload config in context\n Object.assign(ctx.config, newConfig);\n\n // Auto-create a default project if none exist\n const workspaces = await ctx.workspaceManager.list();\n if (workspaces.length === 0) {\n await ctx.workspaceManager.create(\"Default\");\n }\n\n res.json({ success: true });\n } catch (error) {\n res.status(500).json({\n error: error instanceof Error ? error.message : \"Unknown error\",\n });\n }\n });\n\n return router;\n}\n","import { Router } from \"express\";\nimport type { GatewayContext } from \"../server.js\";\nimport { saveConfig } from \"@cortask/core\";\n\nexport function createConfigRoutes(ctx: GatewayContext): Router {\n const router = Router();\n\n // GET /api/config — return current config (excluding sensitive fields)\n router.get(\"/\", (_req, res) => {\n try {\n const { agent, server, spending } = ctx.config;\n res.json({ agent, server, spending });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n // PUT /api/config — update config fields\n router.put(\"/\", async (req, res) => {\n try {\n const { agent, server, spending } = req.body as {\n agent?: { maxTurns?: number; temperature?: number; maxTokens?: number | null };\n server?: { port?: number; host?: string };\n spending?: {\n enabled?: boolean;\n maxTokens?: number | null;\n maxCostUsd?: number | null;\n period?: \"daily\" | \"weekly\" | \"monthly\";\n };\n };\n\n if (agent) {\n if (agent.maxTurns !== undefined) {\n const v = Math.max(1, Math.min(200, Math.round(agent.maxTurns)));\n ctx.config.agent.maxTurns = v;\n }\n if (agent.temperature !== undefined) {\n const v = Math.max(0, Math.min(2, agent.temperature));\n ctx.config.agent.temperature = Math.round(v * 100) / 100;\n }\n if (agent.maxTokens !== undefined) {\n ctx.config.agent.maxTokens = agent.maxTokens === null ? undefined : Math.max(1, Math.round(agent.maxTokens));\n }\n }\n\n if (server) {\n if (server.port !== undefined) {\n ctx.config.server.port = Math.max(1, Math.min(65535, Math.round(server.port)));\n }\n if (server.host !== undefined) {\n ctx.config.server.host = server.host;\n }\n }\n\n if (spending) {\n if (spending.enabled !== undefined) {\n ctx.config.spending.enabled = spending.enabled;\n }\n if (spending.maxTokens !== undefined) {\n ctx.config.spending.maxTokens = spending.maxTokens === null ? undefined : Math.max(0, Math.round(spending.maxTokens));\n }\n if (spending.maxCostUsd !== undefined) {\n ctx.config.spending.maxCostUsd = spending.maxCostUsd === null ? undefined : Math.max(0, spending.maxCostUsd);\n }\n if (spending.period !== undefined) {\n ctx.config.spending.period = spending.period;\n }\n }\n\n await saveConfig(ctx.configPath, ctx.config);\n\n res.json({\n agent: ctx.config.agent,\n server: ctx.config.server,\n spending: ctx.config.spending,\n });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n return router;\n}\n","import { Router } from \"express\";\nimport type { UsageStore } from \"@cortask/core\";\n\nexport function createUsageRoutes(usageStore: UsageStore): Router {\n const router = Router();\n\n // GET /api/usage?period=daily|weekly|monthly\n router.get(\"/\", (req, res) => {\n try {\n const period = (req.query.period as string) || \"monthly\";\n if (![\"daily\", \"weekly\", \"monthly\"].includes(period)) {\n res.status(400).json({ error: \"Invalid period. Use daily, weekly, or monthly.\" });\n return;\n }\n const summary = usageStore.getSummary(period as \"daily\" | \"weekly\" | \"monthly\");\n res.json(summary);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n // GET /api/usage/history?days=30\n router.get(\"/history\", (req, res) => {\n try {\n const days = Math.min(365, Math.max(1, parseInt(req.query.days as string) || 30));\n const history = usageStore.getHistory(days);\n res.json(history);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n return router;\n}\n","import { Router } from \"express\";\nimport type { GatewayContext } from \"../server.js\";\nimport { createProvider, getModelDefinitions, type ProviderId } from \"@cortask/core\";\n\nexport function createModelRoutes(ctx: GatewayContext): Router {\n const router = Router();\n\n // GET /api/models/:providerId/available — list available models for a provider\n router.get(\"/:providerId/available\", async (req, res) => {\n try {\n const providerId = req.params.providerId as ProviderId;\n\n // Providers that fetch models from their API\n if (providerId === \"openrouter\" || providerId === \"ollama\") {\n const credKey = providerId === \"ollama\"\n ? \"provider.ollama.host\"\n : `provider.${providerId}.apiKey`;\n const credential = await ctx.credentialStore.get(credKey);\n if (!credential) {\n res.status(400).json({ error: `No credentials configured for ${providerId}` });\n return;\n }\n const provider = createProvider(providerId, credential);\n const models = await provider.listModels();\n res.json(models);\n return;\n }\n\n // For all other providers, return hardcoded definitions\n const models = getModelDefinitions(providerId);\n res.json(models);\n } catch (err) {\n res.status(500).json({ error: err instanceof Error ? err.message : String(err) });\n }\n });\n\n // GET /api/models/enabled — list all enabled models (optionally filter by provider)\n router.get(\"/enabled\", async (_req, res) => {\n try {\n const provider = _req.query.provider as string | undefined;\n const models = ctx.modelStore.list(provider);\n res.json(models);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n // POST /api/models/enable — enable a model\n router.post(\"/enable\", async (req, res) => {\n try {\n const { provider, modelId, label, inputPricePer1m, outputPricePer1m } = req.body as {\n provider: string;\n modelId: string;\n label: string;\n inputPricePer1m: number;\n outputPricePer1m: number;\n };\n if (!provider || !modelId || !label) {\n res.status(400).json({ error: \"provider, modelId, and label are required\" });\n return;\n }\n const model = ctx.modelStore.enable(\n provider,\n modelId,\n label,\n inputPricePer1m ?? 0,\n outputPricePer1m ?? 0,\n );\n res.json(model);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n // DELETE /api/models/disable — disable a model\n router.delete(\"/disable\", async (req, res) => {\n try {\n const { provider, modelId } = req.body as { provider: string; modelId: string };\n if (!provider || !modelId) {\n res.status(400).json({ error: \"provider and modelId are required\" });\n return;\n }\n ctx.modelStore.disable(provider, modelId);\n res.json({ success: true });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n return router;\n}\n","import { Router } from \"express\";\nimport type { TemplateStore } from \"@cortask/core\";\n\nexport function createTemplateRoutes(templateStore: TemplateStore): Router {\n const router = Router();\n\n router.get(\"/\", (_req, res) => {\n try {\n const templates = templateStore.list();\n res.json(templates);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.post(\"/\", (req, res) => {\n try {\n const { name, content, category } = req.body;\n if (!name || !content) {\n res.status(400).json({ error: \"name and content are required\" });\n return;\n }\n const template = templateStore.create(name, content, category);\n res.status(201).json(template);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.put(\"/:id\", (req, res) => {\n try {\n const updated = templateStore.update(req.params.id, req.body);\n if (!updated) {\n res.status(404).json({ error: \"Template not found\" });\n return;\n }\n res.json(updated);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.delete(\"/:id\", (req, res) => {\n try {\n templateStore.delete(req.params.id);\n res.status(204).send();\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n return router;\n}\n","import { startServer as _startServer } from \"./server.js\";\n\nexport { startServer } from \"./server.js\";\nexport type { GatewayContext, AgentRunnerOptions } from \"./server.js\";\n\n// When run directly (not imported by CLI), start the server\nconst entryScript = process.argv[1] ?? \"\";\nconst isMainModule =\n typeof process !== \"undefined\" &&\n (entryScript.includes(\"gateway\") && entryScript.endsWith(\"index.js\"));\n\nif (isMainModule) {\n _startServer().catch((err: unknown) => {\n console.error(\"Failed to start gateway:\", err);\n process.exit(1);\n });\n}\n"],"mappings":"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","names":["path","createProvider","loadSkills","logger","WhatsAppAdapter","Router","Router","Router","Router","path","clearSkillCache","Router","Router","Router","Router","Router","saveConfig","Router","saveConfig","Router","Router","createProvider","models","Router","path","logger","createProvider","loadSkills","WhatsAppAdapter"]}
|
|
1
|
+
{"version":3,"sources":["../src/server.ts","../src/routes/workspaces.ts","../src/routes/sessions.ts","../src/routes/credentials.ts","../src/routes/providers.ts","../src/routes/skills.ts","../src/routes/cron.ts","../src/routes/channels.ts","../src/ws.ts","../src/routes/artifacts.ts","../src/routes/onboarding.ts","../src/routes/config.ts","../src/routes/usage.ts","../src/routes/models.ts","../src/routes/templates.ts","../src/routes/llm.ts","../src/index.ts"],"sourcesContent":["import express from \"express\";\nimport { createServer } from \"node:http\";\nimport { WebSocketServer, type WebSocket } from \"ws\";\nimport cors from \"cors\";\nimport path from \"node:path\";\nimport fs from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { createRequire } from \"node:module\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\nconst _require = createRequire(import.meta.url);\nconst PKG_VERSION: string = _require(\"../package.json\").version;\nimport {\n loadConfig,\n getDataDir,\n WorkspaceManager,\n SessionStore,\n migrateAllWorkspaces,\n EncryptedCredentialStore,\n getOrCreateSecret,\n createProvider,\n AgentRunner,\n builtinTools,\n createCronTool,\n createArtifactTool,\n createBrowserTool,\n ensureBrowserInstalled,\n createSubagentTool,\n createSwitchWorkspaceTool,\n createSkillTool,\n setSubagentRunner,\n cleanupSubagentRecords,\n loadSkills,\n getEligibleSkills,\n buildSkillTools,\n CronService,\n ArtifactStore,\n UsageStore,\n ModelStore,\n TemplateStore,\n MemoryManager,\n createLocalEmbeddingProvider,\n type LocalEmbeddingProvider,\n logger,\n type CortaskConfig,\n type ProviderId,\n type ToolHandler,\n type PermissionRequest,\n type QuestionnaireRequest,\n type QuestionnaireResponse,\n type ChannelType,\n} from \"@cortask/core\";\nimport { TelegramAdapter, DiscordAdapter, WhatsAppAdapter, type ChannelPlugin } from \"@cortask/channels\";\nimport { createWorkspaceRoutes } from \"./routes/workspaces.js\";\nimport { createSessionRoutes } from \"./routes/sessions.js\";\nimport { createCredentialRoutes } from \"./routes/credentials.js\";\nimport { createProviderRoutes } from \"./routes/providers.js\";\nimport { createSkillRoutes } from \"./routes/skills.js\";\nimport { createCronRoutes } from \"./routes/cron.js\";\nimport { createChannelRoutes } from \"./routes/channels.js\";\nimport { createArtifactRoutes } from \"./routes/artifacts.js\";\nimport { createOnboardingRoutes } from \"./routes/onboarding.js\";\nimport { createConfigRoutes } from \"./routes/config.js\";\nimport { createUsageRoutes } from \"./routes/usage.js\";\nimport { createModelRoutes } from \"./routes/models.js\";\nimport { createTemplateRoutes } from \"./routes/templates.js\";\nimport { createLlmRoutes } from \"./routes/llm.js\";\nimport { handleWebSocket, broadcastSessionRefresh } from \"./ws.js\";\n\nexport interface AgentRunnerOptions {\n onPermissionRequest?: (req: PermissionRequest) => Promise<boolean>;\n onQuestionnaireRequest?: (\n req: QuestionnaireRequest,\n ) => Promise<QuestionnaireResponse>;\n}\n\nexport interface GatewayContext {\n config: CortaskConfig;\n configPath: string;\n dataDir: string;\n bundledSkillsDir: string;\n workspaceManager: WorkspaceManager;\n credentialStore: EncryptedCredentialStore;\n usageStore: UsageStore;\n modelStore: ModelStore;\n getSessionStore: (workspacePath: string) => SessionStore;\n getMemoryManager: (workspacePath: string) => Promise<MemoryManager>;\n invalidateMemoryManagers: () => void;\n createAgentRunner: (workspacePath: string, options?: AgentRunnerOptions) => Promise<AgentRunner>;\n}\n\nconst sessionStoreCache = new Map<string, SessionStore>();\nconst memoryManagerCache = new Map<string, MemoryManager>();\n\nfunction getSessionStore(workspacePath: string): SessionStore {\n const dbPath = path.join(workspacePath, \".cortask\", \"sessions.db\");\n let store = sessionStoreCache.get(dbPath);\n if (!store) {\n store = new SessionStore(dbPath);\n sessionStoreCache.set(dbPath, store);\n }\n return store;\n}\n\nexport async function startServer(port?: number, host?: string) {\n const dataDir = getDataDir();\n const configPath = path.join(dataDir, \"config.yaml\");\n const config = await loadConfig(configPath);\n\n // Initialize logging\n logger.init(path.join(dataDir, \"logs\"));\n logger.info(\"Starting Cortask gateway\", \"gateway\");\n\n // Initialize workspace manager\n const dbPath = path.join(dataDir, \"cortask.db\");\n const workspaceManager = new WorkspaceManager(dbPath);\n\n // Run database migrations for all workspaces\n try {\n const workspaces = await workspaceManager.list();\n migrateAllWorkspaces(workspaces);\n } catch (err) {\n logger.error(\n `Database migration failed: ${err instanceof Error ? err.message : String(err)}`,\n \"gateway\",\n );\n // Continue startup even if migration fails - SessionStore will handle missing columns\n }\n\n // Initialize credential store\n const secret = await getOrCreateSecret(dataDir);\n const credentialStore = new EncryptedCredentialStore(\n path.join(dataDir, \"credentials.enc.json\"),\n secret,\n );\n\n // Memory manager factory with embedding provider wiring\n let localEmbedProvider: LocalEmbeddingProvider | null = null;\n let localEmbedFailed = false;\n\n async function getMemoryManager(workspacePath: string): Promise<MemoryManager> {\n const mmDbPath = path.join(workspacePath, \".cortask\", \"memory.db\");\n let manager = memoryManagerCache.get(mmDbPath);\n if (manager) return manager;\n\n const embeddingProvider = config.memory?.embeddingProvider ?? \"local\";\n const embeddingModel = config.memory?.embeddingModel;\n let apiProvider: ReturnType<typeof createProvider> | undefined;\n\n if (embeddingProvider === \"local\") {\n if (!localEmbedProvider && !localEmbedFailed) {\n try {\n localEmbedProvider = await createLocalEmbeddingProvider();\n logger.info(\"Local embedding provider initialized\", \"memory\");\n } catch (err) {\n localEmbedFailed = true;\n logger.debug(`Local embeddings unavailable: ${err instanceof Error ? err.message : err}`, \"memory\");\n }\n }\n } else if ([\"openai\", \"google\", \"ollama\"].includes(embeddingProvider)) {\n const credKey = embeddingProvider === \"ollama\"\n ? \"provider.ollama.host\"\n : `provider.${embeddingProvider}.apiKey`;\n const key = await credentialStore.get(credKey);\n if (key) {\n apiProvider = createProvider(embeddingProvider as ProviderId, key);\n }\n }\n\n manager = new MemoryManager({\n dbPath: mmDbPath,\n localProvider: embeddingProvider === \"local\" ? localEmbedProvider ?? undefined : undefined,\n apiProvider: apiProvider ?? undefined,\n embeddingModel,\n });\n memoryManagerCache.set(mmDbPath, manager);\n return manager;\n }\n\n // Initialize cron service (uses central DB)\n const cronService = new CronService(dbPath);\n\n // Initialize model store (enabled models with pricing)\n const modelStore = new ModelStore(dbPath);\n\n // Initialize template store\n const templateStore = new TemplateStore(dbPath);\n\n // Initialize usage store (tracks token consumption, uses model store for pricing)\n const usageStore = new UsageStore(dbPath, modelStore);\n\n // Initialize artifact store (in-memory with TTL)\n const artifactStore = new ArtifactStore();\n\n // Initialize channel adapters\n const channels = new Map<string, ChannelPlugin>();\n let wss: WebSocketServer;\n\n // Channel message handler helper\n function wireMessageHandler(channel: ChannelPlugin) {\n const channelType = channel.id as ChannelType;\n\n channel.onMessage(async (msg) => {\n try {\n // Check spending limits before running\n if (config.spending.enabled) {\n const summary = usageStore.getSummary(config.spending.period);\n if (config.spending.maxTokens && summary.totalTokens >= config.spending.maxTokens) {\n return \"Spending limit reached. Please increase or disable the limit.\";\n }\n if (config.spending.maxCostUsd && summary.totalCostUsd >= config.spending.maxCostUsd) {\n return \"Spending limit reached. Please increase or disable the limit.\";\n }\n }\n\n const chatKey = `${channel.id}-${msg.chatId}`;\n const workspaces = await workspaceManager.list();\n if (workspaces.length === 0) return \"No workspace configured.\";\n\n // Resolve workspace: use saved mapping or fall back to first workspace\n const mappedWorkspaceId = workspaceManager.getChannelWorkspace(chatKey);\n const workspace = mappedWorkspaceId\n ? (await workspaceManager.get(mappedWorkspaceId)) ?? workspaces[0]\n : workspaces[0];\n\n const runner = await createAgentRunner(workspace.rootPath, undefined, {\n channelType,\n chatKey,\n chatId: msg.chatId,\n });\n const result = await runner.run({\n prompt: msg.text,\n sessionId: chatKey,\n });\n\n // Notify UI clients to refresh session list\n if (wss) broadcastSessionRefresh(wss, workspace.id);\n\n return result.response;\n } catch (err) {\n return `Error: ${err instanceof Error ? err.message : String(err)}`;\n }\n });\n }\n\n // Resolve skill directories\n const bundledSkillsDir = process.env.CORTASK_SKILLS_DIR\n ?? path.join(path.resolve(__dirname, \"..\", \"..\", \"..\"), \"skills\");\n const userSkillsDir = path.join(dataDir, \"skills\");\n\n interface ChannelContext {\n channelType: ChannelType;\n chatKey: string;\n chatId: string;\n }\n\n // Tools that only work in the web UI (not in channels)\n const uiOnlyTools = new Set([\"questionnaire\", \"artifact\", \"show_file\"]);\n\n // Create agent runner factory\n async function createAgentRunner(workspacePath: string, options?: AgentRunnerOptions, channelCtx?: ChannelContext): Promise<AgentRunner> {\n const providerId = (config.providers.default || \"anthropic\") as ProviderId;\n const providerConfig = config.providers[providerId];\n const model = providerConfig?.model || getDefaultModel(providerId);\n\n // Get credential from credential store (Ollama uses host, others use apiKey)\n const credKey = providerId === \"ollama\"\n ? \"provider.ollama.host\"\n : `provider.${providerId}.apiKey`;\n const apiKey = await credentialStore.get(credKey);\n if (!apiKey) {\n throw new Error(\n `No credentials found for provider \"${providerId}\". Set it in Settings.`,\n );\n }\n\n const provider = createProvider(providerId, apiKey);\n const sessionStore = getSessionStore(workspacePath);\n\n // Load skills and build skill tools\n const allSkills = await loadSkills(\n bundledSkillsDir,\n userSkillsDir,\n config.skills.dirs,\n credentialStore,\n );\n const eligible = getEligibleSkills(allSkills);\n const skillRegistry = await buildSkillTools(eligible, credentialStore);\n\n // Convert skill handlers to ToolHandler format\n const skillToolHandlers: ToolHandler[] = skillRegistry.toolDefs.map((def) => ({\n definition: def,\n execute: async (args, context) => {\n const handler = skillRegistry.handlers.get(def.name);\n if (!handler) {\n return { toolCallId: \"\", content: `No handler for skill tool: ${def.name}`, isError: true };\n }\n return handler(args, context.workspacePath);\n },\n }));\n\n // Build skill prompts from eligible skills (lightweight: just name + description)\n const skillPrompts = eligible\n .map((s) => `- **${s.manifest.name}**: ${s.manifest.description}`);\n\n // Include switch_workspace tool only for channel-based runners\n const channelTools: ToolHandler[] = channelCtx\n ? [createSwitchWorkspaceTool(workspaceManager, channelCtx.chatKey)]\n : [];\n\n const memoryManager = await getMemoryManager(workspacePath);\n\n const runner = new AgentRunner({\n config: {\n provider,\n model,\n maxTurns: config.agent.maxTurns,\n temperature: config.agent.temperature,\n maxTokens: config.agent.maxTokens,\n },\n memoryManager,\n tools: [\n ...(channelCtx\n ? builtinTools.filter((t) => !uiOnlyTools.has(t.definition.name))\n : builtinTools),\n createCronTool(cronService),\n createSkillTool(userSkillsDir, allSkills.filter(s => s.source === \"bundled\").map(s => s.manifest.name)),\n ...(channelCtx ? [] : [createArtifactTool(artifactStore)]),\n createBrowserTool(artifactStore),\n createSubagentTool(),\n ...channelTools,\n ...skillToolHandlers,\n ],\n channel: channelCtx\n ? { type: channelCtx.channelType, chatId: channelCtx.chatId }\n : undefined,\n getWorkspacePath: () => workspacePath,\n getDataDir: () => dataDir,\n getMemoryContent: () => workspaceManager.readMemory(workspacePath),\n getGlobalMemoryContent: () => workspaceManager.readGlobalMemory(dataDir),\n getSkillPrompts: () => skillPrompts,\n getSessionMessages: async (sessionId) => {\n return sessionStore.getMessages(sessionId);\n },\n saveSessionMessages: async (sessionId, messages) => {\n sessionStore.saveMessages(sessionId, messages, channelCtx?.channelType);\n\n // Auto-set title from first user message if still default\n const session = sessionStore.getSession(sessionId);\n if (session && session.title === \"New Chat\") {\n const firstUserMsg = messages.find((m) => m.role === \"user\");\n if (firstUserMsg) {\n const text =\n typeof firstUserMsg.content === \"string\"\n ? firstUserMsg.content\n : firstUserMsg.content\n .filter((p) => p.type === \"text\" && p.text)\n .map((p) => p.text)\n .join(\" \");\n if (text) {\n sessionStore.updateTitle(\n sessionId,\n text.length > 80 ? text.slice(0, 80) + \"…\" : text,\n );\n }\n }\n }\n },\n onPermissionRequest: options?.onPermissionRequest,\n onQuestionnaireRequest: options?.onQuestionnaireRequest,\n });\n\n // Inject runner reference for subagent tool\n setSubagentRunner(runner);\n\n return runner;\n }\n\n const ctx: GatewayContext = {\n config,\n configPath,\n dataDir,\n bundledSkillsDir,\n workspaceManager,\n credentialStore,\n usageStore,\n modelStore,\n getSessionStore,\n getMemoryManager,\n invalidateMemoryManagers: () => {\n for (const mgr of memoryManagerCache.values()) mgr.close();\n memoryManagerCache.clear();\n localEmbedProvider?.dispose();\n localEmbedProvider = null;\n localEmbedFailed = false;\n },\n createAgentRunner,\n };\n\n // Express app\n const app = express();\n\n // CORS: only allow local origins (localhost/127.0.0.1) to protect against\n // cross-origin attacks from external sites. Additional origins can be allowed\n // via CORTASK_CORS_ORIGIN env var.\n const corsOrigin = process.env.CORTASK_CORS_ORIGIN;\n app.use(cors({\n origin: (origin, callback) => {\n // Allow requests with no Origin (same-origin, curl, etc.)\n if (!origin) return callback(null, true);\n try {\n const url = new URL(origin);\n if (url.hostname === \"localhost\" || url.hostname === \"127.0.0.1\" || url.hostname === finalHost) {\n return callback(null, true);\n }\n } catch { /* invalid origin */ }\n if (corsOrigin && origin === corsOrigin) return callback(null, true);\n callback(new Error(\"CORS not allowed\"));\n },\n }));\n\n // Security headers\n app.use((_req, res, next) => {\n res.setHeader(\"X-Content-Type-Options\", \"nosniff\");\n res.setHeader(\"X-Frame-Options\", \"DENY\");\n next();\n });\n\n app.use(express.json({ limit: \"10mb\" }));\n\n // HTTP + WebSocket server (created early so wss is available to routes)\n const server = createServer(app);\n wss = new WebSocketServer({\n server,\n path: \"/ws\",\n verifyClient: ({ origin }: { origin?: string }) => {\n // Allow connections with no Origin (e.g. non-browser clients)\n if (!origin) return true;\n // Allow any local origin (localhost/127.0.0.1) regardless of port —\n // the threat is external sites, not local processes\n try {\n const url = new URL(origin);\n if (url.hostname === \"localhost\" || url.hostname === \"127.0.0.1\" || url.hostname === finalHost) {\n return true;\n }\n } catch { /* invalid origin → reject */ }\n if (corsOrigin && origin === corsOrigin) return true;\n return false;\n },\n });\n wss.on(\"connection\", (ws: WebSocket) => {\n handleWebSocket(ws, ctx);\n });\n\n // API routes\n app.use(\"/api/onboarding\", createOnboardingRoutes(ctx));\n app.use(\"/api/workspaces\", createWorkspaceRoutes(ctx));\n app.use(\"/api/sessions\", createSessionRoutes(ctx));\n app.use(\"/api/credentials\", createCredentialRoutes(ctx));\n app.use(\"/api/providers\", createProviderRoutes(ctx));\n app.use(\"/api/config\", createConfigRoutes(ctx));\n app.use(\"/api/skills\", createSkillRoutes(ctx));\n app.use(\"/api/cron\", createCronRoutes(cronService));\n app.use(\"/api/usage\", createUsageRoutes(usageStore));\n app.use(\"/api/models\", createModelRoutes(ctx));\n app.use(\"/api/templates\", createTemplateRoutes(templateStore));\n app.use(\"/api/llm\", createLlmRoutes(ctx));\n async function createChannelAdapter(id: string): Promise<ChannelPlugin | null> {\n if (id === \"telegram\") {\n const botToken = await credentialStore.get(\"channel.telegram.botToken\");\n if (!botToken) return null;\n const adapter = new TelegramAdapter({\n botToken,\n allowedUsers: config.channels?.telegram?.allowedUsers ?? [],\n });\n wireMessageHandler(adapter);\n return adapter;\n }\n if (id === \"discord\") {\n const botToken = await credentialStore.get(\"channel.discord.botToken\");\n if (!botToken) return null;\n const adapter = new DiscordAdapter({ botToken });\n wireMessageHandler(adapter);\n return adapter;\n }\n if (id === \"whatsapp\") {\n const contactsJson = await credentialStore.get(\"channel.whatsapp.trustedContacts\");\n const trustedContacts = contactsJson ? JSON.parse(contactsJson) : [];\n const adapter = new WhatsAppAdapter({ trustedContacts });\n wireMessageHandler(adapter);\n return adapter;\n }\n return null;\n }\n\n app.use(\"/api/channels\", createChannelRoutes(channels, ctx, createChannelAdapter, wss));\n app.use(\"/api/artifacts\", createArtifactRoutes(artifactStore));\n\n // Health check\n let gatewayReady = false;\n app.get(\"/api/health\", (_req, res) => {\n res.json({ status: \"ok\", version: PKG_VERSION, ready: gatewayReady });\n });\n\n // Update check\n app.get(\"/api/updates/check\", async (_req, res) => {\n try {\n const response = await fetch(\"https://registry.npmjs.org/cortask/latest\");\n if (!response.ok) throw new Error(\"Failed to fetch from npm\");\n const data = await response.json() as { version: string };\n const latest = data.version;\n const hasUpdate = latest !== PKG_VERSION;\n res.json({ currentVersion: PKG_VERSION, latestVersion: latest, hasUpdate });\n } catch (err) {\n res.json({ currentVersion: PKG_VERSION, latestVersion: null, hasUpdate: false, error: (err as Error).message });\n }\n });\n\n // Serve built UI static files (for standalone & desktop mode)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const resourcesPath = (process as any).resourcesPath as string | undefined;\n const uiDistCandidates = [\n path.resolve(\"../ui/dist\"), // monorepo dev\n path.resolve(__dirname, \"../../ui/dist\"), // relative to gateway dist\n ...(resourcesPath ? [path.resolve(resourcesPath, \"ui\")] : []), // electron packaged\n ];\n for (const uiDir of uiDistCandidates) {\n if (fs.existsSync(path.join(uiDir, \"index.html\"))) {\n app.use(express.static(uiDir));\n // SPA fallback: serve index.html for non-API routes\n app.get(\"*\", (_req, res, next) => {\n if (_req.path.startsWith(\"/api/\") || _req.path.startsWith(\"/ws\")) {\n return next();\n }\n res.sendFile(path.join(uiDir, \"index.html\"));\n });\n logger.info(`Serving UI from ${uiDir}`, \"gateway\");\n break;\n }\n }\n\n const envPort = process.env.CORTASK_PORT ? parseInt(process.env.CORTASK_PORT, 10) : undefined;\n const envHost = process.env.CORTASK_HOST;\n const finalPort = port ?? envPort ?? config.server.port;\n const finalHost = host ?? envHost ?? config.server.host;\n\n // Wire cron executor to agent runner\n cronService.setExecutor(async (job) => {\n // Check spending limits before running cron jobs\n if (config.spending.enabled) {\n const summary = usageStore.getSummary(config.spending.period);\n if (config.spending.maxTokens && summary.totalTokens >= config.spending.maxTokens) {\n throw new Error(`Spending limit reached: ${summary.totalTokens.toLocaleString()} / ${config.spending.maxTokens.toLocaleString()} tokens`);\n }\n if (config.spending.maxCostUsd && summary.totalCostUsd >= config.spending.maxCostUsd) {\n throw new Error(`Spending limit reached: $${summary.totalCostUsd.toFixed(2)} / $${config.spending.maxCostUsd.toFixed(2)}`);\n }\n }\n\n const workspaces = await workspaceManager.list();\n let workspacePath: string;\n\n if (job.workspaceId) {\n const ws = await workspaceManager.get(job.workspaceId);\n workspacePath = ws?.rootPath ?? workspaces[0]?.rootPath ?? dataDir;\n } else {\n workspacePath = workspaces[0]?.rootPath ?? dataDir;\n }\n\n const runner = await createAgentRunner(workspacePath);\n const result = await runner.run({ prompt: job.prompt });\n\n // Deliver to channel if specified\n if (job.delivery.channel && job.delivery.target) {\n const channel = channels.get(job.delivery.channel);\n if (!channel) {\n logger.warn(`Cron job \"${job.name}\" delivery failed: channel \"${job.delivery.channel}\" not found`, \"cron\");\n } else if (!channel.isRunning()) {\n logger.warn(`Cron job \"${job.name}\" delivery failed: channel \"${job.delivery.channel}\" is not running`, \"cron\");\n } else {\n await channel.sendMessage(job.delivery.target, result.response);\n }\n } else if (!job.delivery.channel && !job.delivery.target) {\n logger.debug(`Cron job \"${job.name}\" has no delivery channel configured`, \"cron\");\n }\n\n return result.response;\n });\n\n // Start cron service\n cronService.start();\n\n // Find an available port (try up to 10 starting from finalPort)\n let actualPort = finalPort;\n for (let attempt = 0; attempt < 10; attempt++) {\n const inUse = await new Promise<boolean>((resolve) => {\n const tester = createServer();\n tester.once(\"error\", () => resolve(true));\n tester.listen(actualPort, finalHost, () => {\n tester.close(() => resolve(false));\n });\n });\n if (!inUse) break;\n logger.info(`Port ${actualPort} in use, trying ${actualPort + 1}`, \"gateway\");\n actualPort++;\n if (attempt === 9) throw new Error(`No available port found (tried ${finalPort}-${actualPort})`);\n }\n\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(actualPort, finalHost, () => {\n server.removeAllListeners(\"error\");\n resolve();\n });\n });\n\n logger.info(\n `Gateway running on http://${finalHost}:${actualPort}`,\n \"gateway\",\n );\n console.log(`Cortask gateway running on http://${finalHost}:${actualPort}`);\n\n // Prepare gateway: install browser, start channels, then mark ready\n (async () => {\n try {\n await ensureBrowserInstalled();\n } catch (err) {\n logger.debug(`Browser pre-install skipped: ${err instanceof Error ? err.message : err}`, \"gateway\");\n }\n gatewayReady = true;\n logger.info(\"Gateway ready\", \"gateway\");\n })();\n\n // Auto-start channels that were previously enabled\n const knownChannelIds = [\"telegram\", \"discord\", \"whatsapp\"];\n for (const id of knownChannelIds) {\n credentialStore.get(`channel.${id}.enabled`).then(async (enabled) => {\n if (enabled !== \"true\") return;\n try {\n let channel = channels.get(id);\n if (!channel) {\n const created = await createChannelAdapter(id);\n if (!created) return;\n channel = created;\n channels.set(id, channel);\n }\n await channel.start();\n logger.info(`Channel \"${id}\" auto-started`, \"gateway\");\n } catch (err) {\n logger.error(`Failed to auto-start channel \"${id}\": ${err}`, \"gateway\");\n }\n });\n }\n\n // Cleanup completed subagent records every 10 minutes\n setInterval(() => {\n cleanupSubagentRecords(30 * 60 * 1000); // 30 min TTL\n }, 10 * 60 * 1000);\n\n return { server, wss, ctx };\n}\n\nexport function getDefaultModel(providerId: string): string {\n switch (providerId) {\n case \"anthropic\":\n return \"claude-sonnet-4-5-20250929\";\n case \"openai\":\n return \"gpt-4o\";\n case \"google\":\n return \"gemini-2.0-flash\";\n case \"moonshot\":\n return \"moonshot-v1-8k\";\n case \"grok\":\n return \"grok-3-latest\";\n case \"openrouter\":\n return \"openai/gpt-4o\";\n case \"minimax\":\n return \"MiniMax-Text-01\";\n default:\n return \"claude-sonnet-4-5-20250929\";\n }\n}\n","import { Router } from \"express\";\nimport path from \"node:path\";\nimport fs from \"node:fs/promises\";\nimport type { GatewayContext } from \"../server.js\";\n\nexport function createWorkspaceRoutes(ctx: GatewayContext): Router {\n const router = Router();\n\n router.get(\"/\", async (_req, res) => {\n try {\n const workspaces = await ctx.workspaceManager.list();\n res.json(workspaces);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.get(\"/:id\", async (req, res) => {\n try {\n const workspace = await ctx.workspaceManager.get(req.params.id);\n if (!workspace) {\n res.status(404).json({ error: \"Workspace not found\" });\n return;\n }\n res.json(workspace);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.post(\"/\", async (req, res) => {\n try {\n const { name, rootPath } = req.body;\n if (!name) {\n res.status(400).json({ error: \"name is required\" });\n return;\n }\n const workspace = await ctx.workspaceManager.create(name, rootPath || undefined);\n res.status(201).json(workspace);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.put(\"/reorder\", async (req, res) => {\n try {\n const { ids } = req.body;\n if (!Array.isArray(ids)) {\n res.status(400).json({ error: \"ids array required\" });\n return;\n }\n await ctx.workspaceManager.reorder(ids);\n res.json({ ok: true });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.put(\"/:id\", async (req, res) => {\n try {\n await ctx.workspaceManager.update(req.params.id, req.body);\n const updated = await ctx.workspaceManager.get(req.params.id);\n res.json(updated);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.delete(\"/:id\", async (req, res) => {\n try {\n await ctx.workspaceManager.delete(req.params.id);\n res.status(204).send();\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.post(\"/:id/open\", async (req, res) => {\n try {\n const workspace = await ctx.workspaceManager.open(req.params.id);\n if (!workspace) {\n res.status(404).json({ error: \"Workspace not found\" });\n return;\n }\n res.json(workspace);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n // List recent files in workspace\n router.get(\"/:id/list-files\", async (req, res) => {\n try {\n const workspace = await ctx.workspaceManager.get(req.params.id);\n if (!workspace) {\n res.status(404).json({ error: \"Workspace not found\" });\n return;\n }\n let entries: Array<{ name: string; mtime: number }> = [];\n try {\n const dirents = await fs.readdir(workspace.rootPath, { withFileTypes: true });\n const fileEntries = dirents.filter(\n (d) => d.isFile() && d.name !== \".cortask\",\n );\n const withStats = await Promise.all(\n fileEntries.map(async (d) => {\n const stat = await fs.stat(path.join(workspace.rootPath, d.name));\n return { name: d.name, mtime: stat.mtimeMs };\n }),\n );\n entries = withStats.sort((a, b) => b.mtime - a.mtime).slice(0, 10);\n } catch {\n // Directory may not exist yet\n }\n res.json({ files: entries });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n // Read workspace memory\n router.get(\"/:id/memory\", async (req, res) => {\n try {\n const workspace = await ctx.workspaceManager.get(req.params.id);\n if (!workspace) {\n res.status(404).json({ error: \"Workspace not found\" });\n return;\n }\n const content = await ctx.workspaceManager.readMemory(workspace.rootPath);\n res.json({ content: content ?? null });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n // Write workspace memory\n router.put(\"/:id/memory\", async (req, res) => {\n try {\n const workspace = await ctx.workspaceManager.get(req.params.id);\n if (!workspace) {\n res.status(404).json({ error: \"Workspace not found\" });\n return;\n }\n const { content } = req.body;\n if (typeof content !== \"string\") {\n res.status(400).json({ error: \"content string required\" });\n return;\n }\n await ctx.workspaceManager.writeMemory(workspace.rootPath, content);\n res.json({ ok: true });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n // Search structured memory (SQLite)\n router.get(\"/:id/memory/search\", async (req, res) => {\n try {\n const workspace = await ctx.workspaceManager.get(req.params.id);\n if (!workspace) {\n res.status(404).json({ error: \"Workspace not found\" });\n return;\n }\n const query = req.query.q as string;\n if (!query) {\n res.status(400).json({ error: \"q query parameter required\" });\n return;\n }\n const limit = Math.min(Math.max(parseInt(req.query.limit as string) || 5, 1), 50);\n const manager = await ctx.getMemoryManager(workspace.rootPath);\n const results = await manager.search(query, limit);\n res.json(results);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n // List recent memory entries (SQLite)\n router.get(\"/:id/memory/entries\", async (req, res) => {\n try {\n const workspace = await ctx.workspaceManager.get(req.params.id);\n if (!workspace) {\n res.status(404).json({ error: \"Workspace not found\" });\n return;\n }\n const limit = Math.min(Math.max(parseInt(req.query.limit as string) || 20, 1), 100);\n const manager = await ctx.getMemoryManager(workspace.rootPath);\n const entries = await manager.list(limit);\n res.json(entries);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n // Recursive directory tree\n router.get(\"/:id/tree\", async (req, res) => {\n try {\n const workspace = await ctx.workspaceManager.get(req.params.id);\n if (!workspace) {\n res.status(404).json({ error: \"Workspace not found\" });\n return;\n }\n const maxDepth = Math.min(Math.max(parseInt(req.query.depth as string) || 3, 1), 5);\n const skip = new Set([\".cortask\", \".git\", \"node_modules\", \"dist\", \"__pycache__\", \".venv\", \".env\"]);\n\n interface TreeEntry { path: string; name: string; type: \"file\" | \"dir\" }\n const entries: TreeEntry[] = [];\n\n async function walk(dir: string, relPrefix: string, depth: number) {\n if (depth > maxDepth) return;\n let dirents;\n try {\n dirents = await fs.readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n dirents.sort((a, b) => {\n if (a.isDirectory() && !b.isDirectory()) return -1;\n if (!a.isDirectory() && b.isDirectory()) return 1;\n return a.name.localeCompare(b.name);\n });\n for (const d of dirents) {\n if (skip.has(d.name) || d.name.startsWith(\".\")) continue;\n const rel = relPrefix ? `${relPrefix}/${d.name}` : d.name;\n if (d.isDirectory()) {\n entries.push({ path: rel, name: d.name, type: \"dir\" });\n await walk(path.join(dir, d.name), rel, depth + 1);\n } else {\n entries.push({ path: rel, name: d.name, type: \"file\" });\n }\n }\n }\n\n await walk(workspace.rootPath, \"\", 1);\n res.json({ tree: entries });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n // Rename a file in the workspace\n router.put(\"/:id/files/rename\", async (req, res) => {\n try {\n const workspace = await ctx.workspaceManager.get(req.params.id);\n if (!workspace) {\n res.status(404).json({ error: \"Workspace not found\" });\n return;\n }\n\n const { oldPath, newPath } = req.body as { oldPath?: string; newPath?: string };\n if (!oldPath || !newPath) {\n res.status(400).json({ error: \"oldPath and newPath are required\" });\n return;\n }\n\n const fullOld = path.resolve(workspace.rootPath, oldPath);\n const fullNew = path.resolve(workspace.rootPath, newPath);\n\n // Prevent directory traversal\n if (!fullOld.startsWith(path.resolve(workspace.rootPath)) || !fullNew.startsWith(path.resolve(workspace.rootPath))) {\n res.status(403).json({ error: \"Path outside workspace\" });\n return;\n }\n\n // Ensure target directory exists\n await fs.mkdir(path.dirname(fullNew), { recursive: true });\n await fs.rename(fullOld, fullNew);\n res.json({ ok: true });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n // Delete a file or directory in the workspace\n router.delete(\"/:id/files/*\", async (req, res) => {\n try {\n const workspace = await ctx.workspaceManager.get(req.params.id);\n if (!workspace) {\n res.status(404).json({ error: \"Workspace not found\" });\n return;\n }\n\n const relPath = (req.params as unknown as Record<string, string>)[\"0\"];\n if (!relPath) {\n res.status(400).json({ error: \"File path required\" });\n return;\n }\n\n const fullPath = path.resolve(workspace.rootPath, relPath);\n\n // Prevent directory traversal\n if (!fullPath.startsWith(path.resolve(workspace.rootPath))) {\n res.status(403).json({ error: \"Path outside workspace\" });\n return;\n }\n\n const stat = await fs.stat(fullPath);\n if (stat.isDirectory()) {\n await fs.rm(fullPath, { recursive: true });\n } else {\n await fs.unlink(fullPath);\n }\n res.json({ ok: true });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n // Serve workspace files for download\n router.get(\"/:id/files/*\", async (req, res) => {\n try {\n const workspace = await ctx.workspaceManager.get(req.params.id);\n if (!workspace) {\n res.status(404).json({ error: \"Workspace not found\" });\n return;\n }\n\n const relPath = (req.params as unknown as Record<string, string>)[\"0\"];\n if (!relPath) {\n res.status(400).json({ error: \"File path required\" });\n return;\n }\n\n const fullPath = path.resolve(workspace.rootPath, relPath);\n\n // Prevent directory traversal\n if (!fullPath.startsWith(path.resolve(workspace.rootPath))) {\n res.status(403).json({ error: \"Path outside workspace\" });\n return;\n }\n\n res.sendFile(fullPath, (err) => {\n if (err) {\n res.status(404).json({ error: \"File not found\" });\n }\n });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n return router;\n}\n","import { Router } from \"express\";\nimport type { GatewayContext } from \"../server.js\";\n\nexport function createSessionRoutes(ctx: GatewayContext): Router {\n const router = Router();\n\n router.get(\"/\", async (req, res) => {\n try {\n const workspaceId = req.query.workspaceId as string;\n if (!workspaceId) {\n res.status(400).json({ error: \"workspaceId query param required\" });\n return;\n }\n const workspace = await ctx.workspaceManager.get(workspaceId);\n if (!workspace) {\n res.status(404).json({ error: \"Workspace not found\" });\n return;\n }\n const store = ctx.getSessionStore(workspace.rootPath);\n const sessions = store.listSessions();\n res.json(sessions);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.get(\"/:id\", async (req, res) => {\n try {\n const workspaceId = req.query.workspaceId as string;\n if (!workspaceId) {\n res.status(400).json({ error: \"workspaceId query param required\" });\n return;\n }\n const workspace = await ctx.workspaceManager.get(workspaceId);\n if (!workspace) {\n res.status(404).json({ error: \"Workspace not found\" });\n return;\n }\n const store = ctx.getSessionStore(workspace.rootPath);\n const session = store.getSession(req.params.id);\n if (!session) {\n res.status(404).json({ error: \"Session not found\" });\n return;\n }\n res.json(session);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.delete(\"/:id\", async (req, res) => {\n try {\n const workspaceId = req.query.workspaceId as string;\n if (!workspaceId) {\n res.status(400).json({ error: \"workspaceId query param required\" });\n return;\n }\n const workspace = await ctx.workspaceManager.get(workspaceId);\n if (!workspace) {\n res.status(404).json({ error: \"Workspace not found\" });\n return;\n }\n const store = ctx.getSessionStore(workspace.rootPath);\n store.deleteSession(req.params.id);\n res.status(204).send();\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n return router;\n}\n","import { Router } from \"express\";\nimport { clearSkillCache } from \"@cortask/core\";\nimport type { GatewayContext } from \"../server.js\";\n\nexport function createCredentialRoutes(ctx: GatewayContext): Router {\n const router = Router();\n\n router.get(\"/\", async (_req, res) => {\n try {\n const keys = await ctx.credentialStore.list();\n res.json(keys);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.post(\"/\", async (req, res) => {\n try {\n const { key, value } = req.body;\n if (!key || !value) {\n res.status(400).json({ error: \"key and value are required\" });\n return;\n }\n await ctx.credentialStore.set(key, value);\n clearSkillCache(); // Invalidate skill cache when credentials change\n res.status(201).json({ key });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.get(\"/:key\", async (req, res) => {\n try {\n const value = await ctx.credentialStore.get(req.params.key);\n if (value === null) {\n res.status(404).json({ error: \"Key not found\" });\n return;\n }\n res.json({ key: req.params.key, value });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.delete(\"/:key\", async (req, res) => {\n try {\n await ctx.credentialStore.delete(req.params.key);\n clearSkillCache(); // Invalidate skill cache when credentials change\n res.status(204).send();\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n return router;\n}\n","import { Router } from \"express\";\nimport type { GatewayContext } from \"../server.js\";\nimport { createProvider, saveConfig, type ProviderId } from \"@cortask/core\";\n\nconst PROVIDERS = [\n { id: \"anthropic\", name: \"Anthropic\", defaultModel: \"claude-sonnet-4-5-20250929\", credKey: \"provider.anthropic.apiKey\" },\n { id: \"openai\", name: \"OpenAI\", defaultModel: \"gpt-4o\", credKey: \"provider.openai.apiKey\" },\n { id: \"google\", name: \"Google\", defaultModel: \"gemini-2.0-flash\", credKey: \"provider.google.apiKey\" },\n { id: \"moonshot\", name: \"Moonshot\", defaultModel: \"moonshot-v1-8k\", credKey: \"provider.moonshot.apiKey\" },\n { id: \"grok\", name: \"Grok\", defaultModel: \"grok-3-latest\", credKey: \"provider.grok.apiKey\" },\n { id: \"openrouter\", name: \"OpenRouter\", defaultModel: \"openai/gpt-4o\", credKey: \"provider.openrouter.apiKey\" },\n { id: \"minimax\", name: \"MiniMax\", defaultModel: \"MiniMax-Text-01\", credKey: \"provider.minimax.apiKey\" },\n { id: \"ollama\", name: \"Ollama\", defaultModel: \"llama3\", credKey: \"provider.ollama.host\" },\n] as const;\n\nexport function createProviderRoutes(ctx: GatewayContext): Router {\n const router = Router();\n\n router.get(\"/\", async (_req, res) => {\n try {\n const providers = await Promise.all(\n PROVIDERS.map(async (p) => {\n const providerConfig = ctx.config.providers[p.id as ProviderId];\n const configModel = providerConfig?.model;\n return {\n id: p.id,\n name: p.name,\n defaultModel: configModel || p.defaultModel,\n configured: await ctx.credentialStore.has(p.credKey),\n isDefault: ctx.config.providers.default === p.id,\n };\n }),\n );\n res.json(providers);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.put(\"/default\", async (req, res) => {\n try {\n const { providerId, model } = req.body as { providerId: string; model: string };\n if (!providerId || !model) {\n res.status(400).json({ error: \"providerId and model are required\" });\n return;\n }\n\n // Update in-memory config\n ctx.config.providers.default = providerId;\n const key = providerId as ProviderId;\n if (key in ctx.config.providers) {\n ctx.config.providers[key] = { model };\n }\n\n // Persist to config file\n await saveConfig(ctx.configPath, ctx.config);\n\n res.json({ providerId, model });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.post(\"/:id/test\", async (req, res) => {\n try {\n const providerId = req.params.id as ProviderId;\n const provMeta = PROVIDERS.find((p) => p.id === providerId);\n const apiKey = await ctx.credentialStore.get(\n provMeta?.credKey ?? `provider.${providerId}.apiKey`,\n );\n if (!apiKey) {\n res.status(400).json({ error: \"No API key configured\" });\n return;\n }\n\n const provider = createProvider(providerId, apiKey);\n const result = await provider.generateText({\n model:\n PROVIDERS.find((p) => p.id === providerId)?.defaultModel ??\n \"claude-sonnet-4-5-20250929\",\n messages: [{ role: \"user\", content: \"Say hi in 3 words\" }],\n maxTokens: 20,\n });\n\n res.json({\n success: true,\n response: result.content,\n usage: result.usage,\n });\n } catch (err) {\n res.status(500).json({\n success: false,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n\n return router;\n}\n","import crypto from \"node:crypto\";\nimport { Router } from \"express\";\nimport path from \"node:path\";\nimport {\n loadSkills,\n clearSkillCache,\n installSkillFromGit,\n removeSkill,\n createSkill,\n updateSkill,\n readSkillFile,\n validateSkillName,\n getCredentialStorageKey,\n getOAuth2StorageKeys,\n buildSkillOAuth2AuthUrl,\n exchangeSkillOAuth2Code,\n revokeSkillOAuth2,\n} from \"@cortask/core\";\nimport type { GatewayContext } from \"../server.js\";\n\n// In-memory CSRF state store for OAuth2 flows\nconst oauthStates = new Map<string, { skillName: string; credentialId: string; createdAt: number }>();\nconst STATE_TTL_MS = 10 * 60 * 1000; // 10 minutes\n\n// Clean up expired states every minute\nsetInterval(() => {\n const now = Date.now();\n for (const [key, val] of oauthStates) {\n if (now - val.createdAt > STATE_TTL_MS) {\n oauthStates.delete(key);\n }\n }\n}, 60_000).unref();\n\nfunction oauthHtml(title: string, message: string, script?: string): string {\n return `<html><body><h2>${title}</h2><p>${message}</p>${script ? `<script>${script}</script>` : \"<p>You can close this tab.</p>\"}</body></html>`;\n}\n\nexport function createSkillRoutes(ctx: GatewayContext): Router {\n const router = Router();\n\n const bundledDir = ctx.bundledSkillsDir;\n const userSkillsDir = path.join(ctx.dataDir, \"skills\");\n\n async function findSkillAndOAuth(name: string) {\n const skills = await loadSkills(\n bundledDir,\n userSkillsDir,\n ctx.config.skills.dirs,\n ctx.credentialStore,\n );\n const skill = skills.find((s) => s.manifest.name === name);\n if (!skill) return null;\n const oauth2Cred = skill.credentialSchema?.credentials.find((c) => c.type === \"oauth2\");\n return { skill, oauth2Cred };\n }\n\n router.get(\"/\", async (_req, res) => {\n try {\n const skills = await loadSkills(\n bundledDir,\n userSkillsDir,\n ctx.config.skills.dirs,\n ctx.credentialStore,\n );\n\n const result = skills.map((s) => ({\n name: s.manifest.name,\n description: s.manifest.description,\n eligible: s.eligible,\n ineligibleReason: s.ineligibleReason,\n source: s.source,\n editable: s.editable,\n hasCodeTools: s.hasCodeTools,\n toolCount: (s.manifest.tools?.length ?? 0) + (s.hasCodeTools ? 1 : 0),\n tags: s.manifest.metadata?.tags ?? [],\n homepage: (s.manifest.metadata?.homepage as string) ?? null,\n content: s.content,\n installOptions: s.installOptions,\n credentialSchema: s.credentialSchema,\n credentialStatus: s.credentialStatus,\n }));\n\n res.json(result);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.post(\"/install\", async (req, res) => {\n try {\n const { gitUrl } = req.body;\n if (!gitUrl) {\n res.status(400).json({ error: \"gitUrl is required\" });\n return;\n }\n\n const result = await installSkillFromGit(gitUrl, userSkillsDir);\n clearSkillCache();\n res.status(201).json(result);\n } catch (err) {\n res.status(500).json({\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n\n router.delete(\"/:name\", async (req, res) => {\n try {\n await removeSkill(req.params.name, userSkillsDir);\n clearSkillCache();\n res.status(204).send();\n } catch (err) {\n res.status(500).json({\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n\n // ───── Create custom skill ─────\n router.post(\"/\", async (req, res) => {\n try {\n const { name, content } = req.body;\n if (!name || !content) {\n res.status(400).json({ error: \"name and content are required\" });\n return;\n }\n\n const nameErr = validateSkillName(name);\n if (nameErr) {\n res.status(400).json({ error: nameErr });\n return;\n }\n\n // Check for conflict with bundled skills\n const allSkills = await loadSkills(\n bundledDir,\n userSkillsDir,\n ctx.config.skills.dirs,\n ctx.credentialStore,\n );\n const isBundled = allSkills.some(\n (s) => s.source === \"bundled\" && s.manifest.name === name,\n );\n if (isBundled) {\n res.status(409).json({\n error: `A built-in skill named \"${name}\" already exists. Choose a different name.`,\n });\n return;\n }\n\n const result = await createSkill(userSkillsDir, name, content);\n res.status(201).json(result);\n } catch (err) {\n res.status(500).json({\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n\n // ───── Update custom skill ─────\n router.put(\"/:name\", async (req, res) => {\n try {\n const { content } = req.body;\n if (!content) {\n res.status(400).json({ error: \"content is required\" });\n return;\n }\n\n // Reject editing bundled skills\n const allSkills = await loadSkills(\n bundledDir,\n userSkillsDir,\n ctx.config.skills.dirs,\n ctx.credentialStore,\n );\n const skill = allSkills.find((s) => s.manifest.name === req.params.name);\n if (skill && !skill.editable) {\n res.status(403).json({ error: \"Built-in skills cannot be edited\" });\n return;\n }\n\n await updateSkill(userSkillsDir, req.params.name, content);\n res.json({ name: req.params.name });\n } catch (err) {\n res.status(500).json({\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n\n // ───── Get raw SKILL.md content for editing ─────\n router.get(\"/:name/content\", async (req, res) => {\n try {\n const content = await readSkillFile(userSkillsDir, req.params.name);\n res.json({ name: req.params.name, content });\n } catch (err) {\n res.status(404).json({\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n\n // ───── OAuth2: Start authorization flow ─────\n router.get(\"/:name/oauth2/authorize\", async (req, res) => {\n try {\n const name = req.params.name;\n const result = await findSkillAndOAuth(name);\n\n if (!result || !result.oauth2Cred?.oauth) {\n res.status(400).json({ error: \"Skill not found or has no OAuth2 config\" });\n return;\n }\n\n const credentialId = result.oauth2Cred.id;\n const clientIdKey = getCredentialStorageKey(name, credentialId, \"clientId\", result.oauth2Cred.storeAs);\n const clientId = await ctx.credentialStore.get(clientIdKey);\n\n if (!clientId) {\n res.status(400).json({ error: \"Client ID not configured. Save it before authorizing.\" });\n return;\n }\n\n const state = crypto.randomBytes(16).toString(\"hex\");\n oauthStates.set(state, { skillName: name, credentialId, createdAt: Date.now() });\n\n // Determine gateway base URL from the request\n const proto = req.headers[\"x-forwarded-proto\"] || req.protocol || \"http\";\n const host = req.headers[\"x-forwarded-host\"] || req.headers.host || \"localhost:3777\";\n const gatewayBaseUrl = `${proto}://${host}`;\n\n const redirectUri = `${gatewayBaseUrl}/api/skills/${encodeURIComponent(name)}/oauth2/callback`;\n const authorizationUrl = buildSkillOAuth2AuthUrl(\n name,\n result.oauth2Cred.oauth,\n clientId,\n redirectUri,\n state,\n );\n\n res.json({ authorizationUrl, redirectUri });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n // ───── OAuth2: Get redirect URI (for display before credentials are saved) ─────\n router.get(\"/:name/oauth2/redirect-uri\", (req, res) => {\n const name = req.params.name;\n const proto = req.headers[\"x-forwarded-proto\"] || req.protocol || \"http\";\n const host = req.headers[\"x-forwarded-host\"] || req.headers.host || \"localhost:3777\";\n const gatewayBaseUrl = `${proto}://${host}`;\n const redirectUri = `${gatewayBaseUrl}/api/skills/${encodeURIComponent(name)}/oauth2/callback`;\n res.json({ redirectUri });\n });\n\n // ───── OAuth2: Callback from provider ─────\n router.get(\"/:name/oauth2/callback\", async (req, res) => {\n const { code, state, error: oauthError } = req.query as Record<string, string>;\n const name = req.params.name;\n\n if (oauthError) {\n res.status(400).send(oauthHtml(\"OAuth Error\", oauthError));\n return;\n }\n\n if (!code || !state) {\n res.status(400).send(oauthHtml(\"Error\", \"Missing code or state parameter.\"));\n return;\n }\n\n // Validate CSRF state\n const stateEntry = oauthStates.get(state);\n if (!stateEntry || stateEntry.skillName !== name) {\n res.status(400).send(oauthHtml(\"Error\", \"Invalid or expired OAuth state. Please try again.\"));\n return;\n }\n oauthStates.delete(state);\n\n if (Date.now() - stateEntry.createdAt > STATE_TTL_MS) {\n res.status(400).send(oauthHtml(\"Error\", \"OAuth state expired. Please try again.\"));\n return;\n }\n\n try {\n const result = await findSkillAndOAuth(name);\n if (!result || !result.oauth2Cred?.oauth) {\n res.status(400).send(oauthHtml(\"Error\", \"Skill not found or has no OAuth2 config.\"));\n return;\n }\n\n const credentialId = result.oauth2Cred.id;\n const clientIdKey = getCredentialStorageKey(name, credentialId, \"clientId\", result.oauth2Cred.storeAs);\n const clientSecretKey = getCredentialStorageKey(name, credentialId, \"clientSecret\", result.oauth2Cred.storeAs);\n const clientId = await ctx.credentialStore.get(clientIdKey);\n const clientSecret = await ctx.credentialStore.get(clientSecretKey);\n\n if (!clientId || !clientSecret) {\n res.status(400).send(oauthHtml(\"Error\", \"OAuth client credentials not configured.\"));\n return;\n }\n\n const proto = req.headers[\"x-forwarded-proto\"] || req.protocol || \"http\";\n const host = req.headers[\"x-forwarded-host\"] || req.headers.host || \"localhost:3777\";\n const gatewayBaseUrl = `${proto}://${host}`;\n const redirectUri = `${gatewayBaseUrl}/api/skills/${encodeURIComponent(name)}/oauth2/callback`;\n\n await exchangeSkillOAuth2Code(\n name,\n credentialId,\n result.oauth2Cred.oauth,\n clientId,\n clientSecret,\n code,\n redirectUri,\n ctx.credentialStore,\n );\n\n clearSkillCache();\n\n res.send(oauthHtml(\n \"Authorization Successful\",\n `Skill \"${name}\" has been authorized.`,\n `if (window.opener) { window.opener.postMessage({ type: \"oauth-success\", skill: \"${name}\" }, \"*\"); }`,\n ));\n } catch (err) {\n res.status(500).send(oauthHtml(\"Error\", `Token exchange failed: ${err instanceof Error ? err.message : String(err)}`));\n }\n });\n\n // ───── OAuth2: Token status ─────\n router.get(\"/:name/oauth2/status\", async (req, res) => {\n try {\n const name = req.params.name;\n const result = await findSkillAndOAuth(name);\n\n if (!result || !result.oauth2Cred) {\n res.status(400).json({ error: \"Skill not found or has no OAuth2 config\" });\n return;\n }\n\n const keys = getOAuth2StorageKeys(name, result.oauth2Cred.id);\n const hasToken = await ctx.credentialStore.has(keys.accessToken);\n const expiresAtStr = await ctx.credentialStore.get(keys.expiresAt);\n const hasRefresh = await ctx.credentialStore.has(keys.refreshToken);\n\n let expiresAt: number | null = null;\n let expired = false;\n if (expiresAtStr) {\n expiresAt = parseInt(expiresAtStr, 10);\n expired = !isNaN(expiresAt) && Date.now() >= expiresAt;\n }\n\n res.json({ connected: hasToken, expired, expiresAt, hasRefreshToken: hasRefresh });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n // ───── OAuth2: Revoke tokens ─────\n router.post(\"/:name/oauth2/revoke\", async (req, res) => {\n try {\n const name = req.params.name;\n const result = await findSkillAndOAuth(name);\n\n if (!result || !result.oauth2Cred) {\n res.status(400).json({ error: \"Skill not found or has no OAuth2 config\" });\n return;\n }\n\n await revokeSkillOAuth2(name, result.oauth2Cred.id, ctx.credentialStore);\n clearSkillCache();\n res.json({ ok: true });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n return router;\n}\n","import { Router } from \"express\";\nimport type { CronService } from \"@cortask/core\";\nimport type { CronJobCreate } from \"@cortask/core\";\n\nexport function createCronRoutes(cronService: CronService): Router {\n const router = Router();\n\n // List cron jobs (optionally filtered by workspaceId)\n router.get(\"/\", (req, res) => {\n try {\n const workspaceId = typeof req.query.workspaceId === \"string\" ? req.query.workspaceId : undefined;\n const jobs = cronService.list(workspaceId);\n const result = jobs.map((job) => {\n const state = cronService.getState(job.id);\n return { ...job, state };\n });\n res.json(result);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n // Get single job\n router.get(\"/:id\", (req, res) => {\n try {\n const job = cronService.getJob(req.params.id);\n if (!job) {\n res.status(404).json({ error: \"Job not found\" });\n return;\n }\n const state = cronService.getState(job.id);\n res.json({ ...job, state });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n // Create a cron job\n router.post(\"/\", (req, res) => {\n try {\n const input: CronJobCreate = req.body;\n if (!input.name || !input.schedule || !input.prompt) {\n res\n .status(400)\n .json({ error: \"name, schedule, and prompt are required\" });\n return;\n }\n const job = cronService.add(input);\n res.status(201).json(job);\n } catch (err) {\n res.status(500).json({\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n\n // Update a cron job\n router.put(\"/:id\", (req, res) => {\n try {\n const updated = cronService.update(req.params.id, req.body);\n if (!updated) {\n res.status(404).json({ error: \"Job not found\" });\n return;\n }\n res.json(updated);\n } catch (err) {\n res.status(500).json({\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n\n // Delete a cron job\n router.delete(\"/:id\", (req, res) => {\n try {\n const removed = cronService.remove(req.params.id);\n if (!removed) {\n res.status(404).json({ error: \"Job not found\" });\n return;\n }\n res.status(204).send();\n } catch (err) {\n res.status(500).json({\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n\n // Run a job immediately\n router.post(\"/:id/run\", async (req, res) => {\n try {\n await cronService.runNow(req.params.id);\n res.json({ status: \"executed\" });\n } catch (err) {\n res.status(500).json({\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n\n return router;\n}\n","import { Router } from \"express\";\nimport type { WebSocketServer } from \"ws\";\nimport type { ChannelPlugin } from \"@cortask/channels\";\nimport { WhatsAppAdapter } from \"@cortask/channels\";\nimport type { TrustedContact } from \"@cortask/channels\";\nimport type { GatewayContext } from \"../server.js\";\nimport { broadcastChannelStatus } from \"../ws.js\";\n\nexport function createChannelRoutes(\n channels: Map<string, ChannelPlugin>,\n ctx: GatewayContext,\n createChannel: (id: string) => Promise<ChannelPlugin | null>,\n wss: WebSocketServer,\n): Router {\n const router = Router();\n\n const KNOWN_CHANNELS = [\n { id: \"telegram\", name: \"Telegram\" },\n { id: \"whatsapp\", name: \"WhatsApp\" },\n { id: \"discord\", name: \"Discord\" },\n ];\n\n // List channel statuses\n router.get(\"/\", (_req, res) => {\n const result = KNOWN_CHANNELS.map((def) => {\n const ch = channels.get(def.id);\n const base = { id: def.id, name: ch?.name ?? def.name, running: ch?.isRunning() ?? false };\n // Add WhatsApp auth status\n if (def.id === \"whatsapp\") {\n const wa = ch as WhatsAppAdapter | undefined;\n return { ...base, authenticated: wa?.isAuthenticated() ?? new WhatsAppAdapter().isAuthenticated() };\n }\n return base;\n });\n res.json(result);\n });\n\n // Start a channel (create on-demand if needed)\n router.post(\"/:id/start\", async (req, res) => {\n const { id } = req.params;\n let channel = channels.get(id);\n\n if (!channel) {\n try {\n const created = await createChannel(id);\n if (!created) {\n res.status(400).json({ error: `No credentials configured for ${id}` });\n return;\n }\n channel = created;\n } catch (err) {\n res.status(400).json({\n error: err instanceof Error ? err.message : String(err),\n });\n return;\n }\n channels.set(id, channel);\n }\n\n try {\n await channel.start();\n await ctx.credentialStore.set(`channel.${id}.enabled`, \"true\");\n broadcastChannelStatus(wss, { channelId: id, running: true, authenticated: true });\n res.json({ id, name: channel.name, running: true });\n } catch (err) {\n res.status(500).json({\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n\n // Stop a channel\n router.post(\"/:id/stop\", async (req, res) => {\n const channel = channels.get(req.params.id);\n if (!channel) {\n res.status(404).json({ error: \"Channel not found\" });\n return;\n }\n try {\n await channel.stop();\n await ctx.credentialStore.delete(`channel.${req.params.id}.enabled`);\n broadcastChannelStatus(wss, { channelId: req.params.id, running: false, authenticated: false });\n res.json({ id: req.params.id, name: channel.name, running: false });\n } catch (err) {\n res.status(500).json({\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n\n // WhatsApp: generate QR code for authentication + auto-start after scan\n router.post(\"/whatsapp/qr\", async (_req, res) => {\n try {\n // Ensure adapter exists\n let wa = channels.get(\"whatsapp\") as WhatsAppAdapter | undefined;\n if (!wa) {\n const created = await createChannel(\"whatsapp\");\n if (!created) {\n res.status(500).json({ error: \"Failed to create WhatsApp adapter\" });\n return;\n }\n wa = created as WhatsAppAdapter;\n channels.set(\"whatsapp\", wa);\n }\n\n const result = await wa.generateQR();\n res.json(result);\n\n // After returning QR, poll for authentication and auto-start\n if (result.success) {\n const pollInterval = 2000;\n const maxPolls = 30; // 60 seconds\n let polls = 0;\n\n const poller = setInterval(async () => {\n polls++;\n try {\n if (wa!.isAuthenticated() && !wa!.isRunning()) {\n clearInterval(poller);\n await wa!.start();\n await ctx.credentialStore.set(\"channel.whatsapp.enabled\", \"true\");\n broadcastChannelStatus(wss, { channelId: \"whatsapp\", running: true, authenticated: true });\n } else if (polls >= maxPolls) {\n clearInterval(poller);\n // Still broadcast auth status even if we don't auto-start\n if (wa!.isAuthenticated()) {\n broadcastChannelStatus(wss, { channelId: \"whatsapp\", running: false, authenticated: true });\n }\n }\n } catch (err) {\n clearInterval(poller);\n console.error(\"[whatsapp] Auto-start failed:\", err);\n }\n }, pollInterval);\n }\n } catch (err) {\n res.status(500).json({\n success: false,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n\n // WhatsApp: logout and clear auth\n router.post(\"/whatsapp/logout\", async (_req, res) => {\n const wa = channels.get(\"whatsapp\") as WhatsAppAdapter | undefined;\n if (!wa) {\n // Clear auth even without an adapter instance\n new WhatsAppAdapter().logout();\n res.json({ success: true });\n return;\n }\n try {\n await wa.logout();\n await ctx.credentialStore.delete(\"channel.whatsapp.enabled\");\n broadcastChannelStatus(wss, { channelId: \"whatsapp\", running: false, authenticated: false });\n res.json({ success: true });\n } catch (err) {\n res.status(500).json({\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n\n // WhatsApp: get trusted contacts\n router.get(\"/whatsapp/contacts\", async (_req, res) => {\n try {\n const json = await ctx.credentialStore.get(\"channel.whatsapp.trustedContacts\");\n const contacts: TrustedContact[] = json ? JSON.parse(json) : [];\n res.json(contacts);\n } catch (err) {\n res.status(500).json({ error: err instanceof Error ? err.message : String(err) });\n }\n });\n\n // WhatsApp: save trusted contacts\n router.put(\"/whatsapp/contacts\", async (req, res) => {\n try {\n const contacts: TrustedContact[] = req.body;\n await ctx.credentialStore.set(\"channel.whatsapp.trustedContacts\", JSON.stringify(contacts));\n\n // Update running adapter if present\n const wa = channels.get(\"whatsapp\") as WhatsAppAdapter | undefined;\n if (wa) {\n wa.setTrustedContacts(contacts);\n }\n\n res.json(contacts);\n } catch (err) {\n res.status(500).json({ error: err instanceof Error ? err.message : String(err) });\n }\n });\n\n return router;\n}\n","import type { WebSocket } from \"ws\";\nimport type { WebSocketServer } from \"ws\";\nimport { getDefaultModel, type GatewayContext } from \"./server.js\";\nimport { logger, type QuestionnaireResponse } from \"@cortask/core\";\n\nexport interface ChannelStatusEvent {\n channelId: string;\n running: boolean;\n authenticated?: boolean;\n}\n\nexport function broadcastChannelStatus(wss: WebSocketServer, status: ChannelStatusEvent) {\n const data = JSON.stringify({ type: \"channel:status\", ...status });\n for (const client of wss.clients) {\n if (client.readyState === (client as WebSocket).OPEN) {\n client.send(data);\n }\n }\n}\n\nexport function broadcastSessionRefresh(wss: WebSocketServer, workspaceId: string) {\n const data = JSON.stringify({ type: \"session:refresh\", workspaceId });\n for (const client of wss.clients) {\n if (client.readyState === (client as WebSocket).OPEN) {\n client.send(data);\n }\n }\n}\n\ninterface ChatAttachment {\n mimeType: string;\n base64: string;\n name?: string;\n}\n\ninterface ChatMessage {\n type: \"chat\";\n sessionKey: string;\n message: string;\n workspaceId: string;\n attachments?: ChatAttachment[];\n fileReferences?: string[];\n}\n\ninterface CancelMessage {\n type: \"cancel\";\n sessionKey: string;\n}\n\ninterface PermissionResponse {\n type: \"permission_response\";\n requestId: string;\n approved: boolean;\n}\n\ninterface QuestionnaireResponseMessage {\n type: \"questionnaire_response\";\n requestId: string;\n responses: QuestionnaireResponse;\n}\n\ntype IncomingMessage =\n | ChatMessage\n | CancelMessage\n | PermissionResponse\n | QuestionnaireResponseMessage;\n\n// Pending permission requests: requestId → resolve callback\nconst pendingPermissions = new Map<string, (approved: boolean) => void>();\n\n// Pending questionnaire requests: requestId → resolve callback\nconst pendingQuestionnaires = new Map<\n string,\n (responses: QuestionnaireResponse) => void\n>();\n\n// Active runs: sessionKey → AbortController\nconst activeRuns = new Map<string, AbortController>();\n\nexport function handleWebSocket(ws: WebSocket, ctx: GatewayContext) {\n logger.info(\"WebSocket client connected\", \"gateway\");\n\n ws.on(\"message\", async (raw) => {\n let msg: IncomingMessage;\n try {\n msg = JSON.parse(raw.toString()) as IncomingMessage;\n } catch {\n sendError(ws, \"\", \"Invalid JSON\");\n return;\n }\n\n if (msg.type === \"chat\") {\n await handleChat(ws, msg, ctx);\n } else if (msg.type === \"cancel\") {\n logger.info(`Cancel requested for session ${msg.sessionKey}`, \"gateway\");\n const controller = activeRuns.get(msg.sessionKey);\n if (controller) {\n controller.abort();\n activeRuns.delete(msg.sessionKey);\n }\n } else if (msg.type === \"permission_response\") {\n const resolver = pendingPermissions.get(msg.requestId);\n if (resolver) {\n resolver(msg.approved);\n pendingPermissions.delete(msg.requestId);\n }\n } else if (msg.type === \"questionnaire_response\") {\n const resolver = pendingQuestionnaires.get(msg.requestId);\n if (resolver) {\n resolver(msg.responses);\n pendingQuestionnaires.delete(msg.requestId);\n }\n }\n });\n\n ws.on(\"close\", () => {\n logger.info(\"WebSocket client disconnected\", \"gateway\");\n // Abort all active runs when client disconnects\n for (const [id, controller] of activeRuns) {\n controller.abort();\n activeRuns.delete(id);\n }\n // Deny all pending permissions when client disconnects\n for (const [id, resolver] of pendingPermissions) {\n resolver(false);\n pendingPermissions.delete(id);\n }\n // Don't resolve pending questionnaires on disconnect — the user may\n // reconnect and submit. They will time out on their own if abandoned.\n });\n}\n\nfunction checkSpendingLimit(ctx: GatewayContext): string | null {\n const { spending } = ctx.config;\n if (!spending.enabled) return null;\n\n const summary = ctx.usageStore.getSummary(spending.period);\n\n if (spending.maxTokens && summary.totalTokens >= spending.maxTokens) {\n return `Spending limit reached: ${summary.totalTokens.toLocaleString()} / ${spending.maxTokens.toLocaleString()} tokens (${spending.period})`;\n }\n if (spending.maxCostUsd && summary.totalCostUsd >= spending.maxCostUsd) {\n return `Spending limit reached: $${summary.totalCostUsd.toFixed(2)} / $${spending.maxCostUsd.toFixed(2)} (${spending.period})`;\n }\n return null;\n}\n\nasync function handleChat(\n ws: WebSocket,\n msg: ChatMessage,\n ctx: GatewayContext,\n) {\n // Create abort controller for this run\n const abortController = new AbortController();\n activeRuns.set(msg.sessionKey, abortController);\n\n try {\n // Check spending limits before running\n const limitError = checkSpendingLimit(ctx);\n if (limitError) {\n sendError(ws, msg.sessionKey, limitError);\n return;\n }\n\n const workspace = await ctx.workspaceManager.get(msg.workspaceId);\n if (!workspace) {\n sendError(ws, msg.sessionKey, \"Workspace not found\");\n return;\n }\n\n const runner = await ctx.createAgentRunner(workspace.rootPath, {\n onPermissionRequest: async (req) => {\n return new Promise<boolean>((resolve) => {\n pendingPermissions.set(req.id, resolve);\n send(ws, {\n type: \"permission_request\",\n requestId: req.id,\n description: req.description,\n details: req.details,\n });\n\n // Auto-deny after 60 seconds\n setTimeout(() => {\n if (pendingPermissions.has(req.id)) {\n pendingPermissions.delete(req.id);\n resolve(false);\n }\n }, 60000);\n });\n },\n onQuestionnaireRequest: async (req) => {\n return new Promise<QuestionnaireResponse>((resolve) => {\n pendingQuestionnaires.set(req.id, resolve);\n send(ws, {\n type: \"questionnaire_request\",\n requestId: req.id,\n data: {\n title: req.title,\n description: req.description,\n questions: req.questions,\n },\n });\n\n });\n },\n });\n\n for await (const event of runner.runStream({\n prompt: msg.message,\n attachments: msg.attachments,\n fileReferences: msg.fileReferences,\n sessionId: msg.sessionKey,\n workspaceId: msg.workspaceId,\n signal: abortController.signal,\n })) {\n if (ws.readyState !== ws.OPEN || abortController.signal.aborted) break;\n\n switch (event.type) {\n case \"thinking_delta\":\n send(ws, {\n type: \"thinking_delta\",\n sessionKey: msg.sessionKey,\n text: event.text,\n });\n break;\n case \"text_delta\":\n send(ws, {\n type: \"text_delta\",\n sessionKey: msg.sessionKey,\n text: event.text,\n });\n break;\n case \"tool_call_start\":\n send(ws, {\n type: \"tool_call_start\",\n sessionKey: msg.sessionKey,\n toolName: event.toolName,\n toolCallId: event.toolCallId,\n });\n break;\n case \"tool_result\":\n send(ws, {\n type: \"tool_result\",\n sessionKey: msg.sessionKey,\n toolCallId: event.toolCallId,\n toolName: event.toolName,\n toolArgs: event.toolArgs,\n content: event.toolResult?.content,\n isError: event.toolResult?.isError,\n });\n break;\n case \"done\":\n // Record usage for spending tracking\n if (event.usage) {\n try {\n const providerId = ctx.config.providers.default || \"anthropic\";\n const providerConfig = ctx.config.providers[providerId as keyof typeof ctx.config.providers];\n const model = (typeof providerConfig === \"object\" && providerConfig && \"model\" in providerConfig ? providerConfig.model : undefined) || getDefaultModel(providerId);\n ctx.usageStore.record(\n providerId,\n model,\n event.usage.inputTokens,\n event.usage.outputTokens,\n );\n } catch (err) {\n logger.error(`Failed to record usage: ${err}`, \"gateway\");\n }\n }\n send(ws, {\n type: \"done\",\n sessionKey: msg.sessionKey,\n usage: event.usage,\n });\n break;\n case \"error\":\n sendError(ws, msg.sessionKey, event.error ?? \"Unknown error\");\n break;\n }\n }\n } catch (err) {\n // Don't report abort errors as failures\n if (!abortController.signal.aborted) {\n sendError(\n ws,\n msg.sessionKey,\n err instanceof Error ? err.message : String(err),\n );\n }\n } finally {\n activeRuns.delete(msg.sessionKey);\n }\n}\n\nfunction send(ws: WebSocket, data: Record<string, unknown>) {\n if (ws.readyState === ws.OPEN) {\n ws.send(JSON.stringify(data));\n }\n}\n\nfunction sendError(ws: WebSocket, sessionKey: string, error: string) {\n send(ws, { type: \"error\", sessionKey, error });\n}\n","import { Router } from \"express\";\nimport type { ArtifactStore } from \"@cortask/core\";\n\nexport function createArtifactRoutes(artifactStore: ArtifactStore): Router {\n const router = Router();\n\n // Get artifact by ID\n router.get(\"/:id\", (req, res) => {\n const artifact = artifactStore.get(req.params.id);\n if (!artifact) {\n res.status(404).json({ error: \"Artifact not found or expired\" });\n return;\n }\n\n // If ?raw query param, serve the content directly with correct mime type\n if (req.query.raw !== undefined) {\n res.setHeader(\"Content-Type\", artifact.mimeType);\n // Image artifacts are stored as base64 — decode to binary\n if (artifact.type === \"image\") {\n res.send(Buffer.from(artifact.content, \"base64\"));\n } else {\n res.send(artifact.content);\n }\n return;\n }\n\n res.json({\n id: artifact.id,\n type: artifact.type,\n title: artifact.title,\n content: artifact.content,\n mimeType: artifact.mimeType,\n createdAt: artifact.createdAt,\n });\n });\n\n // List all artifacts\n router.get(\"/\", (_req, res) => {\n const artifacts = artifactStore.list();\n res.json(\n artifacts.map((a) => ({\n id: a.id,\n type: a.type,\n title: a.title,\n mimeType: a.mimeType,\n createdAt: a.createdAt,\n })),\n );\n });\n\n return router;\n}\n","import { Router } from \"express\";\nimport type { GatewayContext } from \"../server.js\";\nimport { saveConfig, AVAILABLE_PROVIDERS } from \"@cortask/core\";\n\nexport function createOnboardingRoutes(ctx: GatewayContext): Router {\n const router = Router();\n\n // GET /api/onboarding/status\n router.get(\"/status\", async (_req, res) => {\n try {\n const hasProvider = await Promise.any(\n AVAILABLE_PROVIDERS.flatMap((p) => [\n ctx.credentialStore.has(`provider.${p.id}.apiKey`),\n ctx.credentialStore.has(`provider.${p.id}.host`),\n ])\n ).catch(() => false);\n\n const workspaces = await ctx.workspaceManager.list();\n const hasWorkspace = workspaces.length > 0;\n\n res.json({\n completed: ctx.config.onboarded === true,\n hasProvider,\n hasWorkspace,\n });\n } catch (error) {\n res.status(500).json({\n error: error instanceof Error ? error.message : \"Unknown error\",\n });\n }\n });\n\n // POST /api/onboarding/complete\n router.post(\"/complete\", async (req, res) => {\n try {\n const { provider } = req.body;\n\n const isOllama = provider?.type === \"ollama\";\n if (!provider?.type || (!provider?.apiKey && !provider?.host)) {\n res.status(400).json({ error: \"Provider configuration required\" });\n return;\n }\n\n // Save credential to store\n const credKey = isOllama\n ? `provider.${provider.type}.host`\n : `provider.${provider.type}.apiKey`;\n const credValue = isOllama ? provider.host : provider.apiKey;\n await ctx.credentialStore.set(credKey, credValue);\n\n // Update config\n const newConfig = {\n ...ctx.config,\n onboarded: true,\n providers: {\n ...ctx.config.providers,\n default: provider.type,\n },\n };\n\n await saveConfig(ctx.configPath, newConfig);\n\n // Reload config in context\n Object.assign(ctx.config, newConfig);\n\n // Auto-create a default project if none exist\n const workspaces = await ctx.workspaceManager.list();\n if (workspaces.length === 0) {\n await ctx.workspaceManager.create(\"Default\");\n }\n\n res.json({ success: true });\n } catch (error) {\n res.status(500).json({\n error: error instanceof Error ? error.message : \"Unknown error\",\n });\n }\n });\n\n return router;\n}\n","import { Router } from \"express\";\nimport type { GatewayContext } from \"../server.js\";\nimport { saveConfig, createProvider, type ProviderId } from \"@cortask/core\";\n\nexport function createConfigRoutes(ctx: GatewayContext): Router {\n const router = Router();\n\n // GET /api/config — return current config (excluding sensitive fields)\n router.get(\"/\", (_req, res) => {\n try {\n const { agent, server, spending, memory } = ctx.config;\n res.json({ agent, server, spending, memory, dataDir: ctx.dataDir });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n // PUT /api/config — update config fields\n router.put(\"/\", async (req, res) => {\n try {\n const { agent, server, spending, memory } = req.body as {\n agent?: { maxTurns?: number; temperature?: number; maxTokens?: number | null };\n server?: { port?: number; host?: string };\n spending?: {\n enabled?: boolean;\n maxTokens?: number | null;\n maxCostUsd?: number | null;\n period?: \"daily\" | \"weekly\" | \"monthly\";\n };\n memory?: {\n embeddingProvider?: \"local\" | \"openai\" | \"google\" | \"ollama\";\n embeddingModel?: string;\n };\n };\n\n if (agent) {\n if (agent.maxTurns !== undefined) {\n const v = Math.max(1, Math.min(200, Math.round(agent.maxTurns)));\n ctx.config.agent.maxTurns = v;\n }\n if (agent.temperature !== undefined) {\n const v = Math.max(0, Math.min(2, agent.temperature));\n ctx.config.agent.temperature = Math.round(v * 100) / 100;\n }\n if (agent.maxTokens !== undefined) {\n ctx.config.agent.maxTokens = agent.maxTokens === null ? undefined : Math.max(1, Math.round(agent.maxTokens));\n }\n }\n\n if (server) {\n if (server.port !== undefined) {\n ctx.config.server.port = Math.max(1, Math.min(65535, Math.round(server.port)));\n }\n if (server.host !== undefined) {\n ctx.config.server.host = server.host;\n }\n }\n\n if (spending) {\n if (spending.enabled !== undefined) {\n ctx.config.spending.enabled = spending.enabled;\n }\n if (spending.maxTokens !== undefined) {\n ctx.config.spending.maxTokens = spending.maxTokens === null ? undefined : Math.max(0, Math.round(spending.maxTokens));\n }\n if (spending.maxCostUsd !== undefined) {\n ctx.config.spending.maxCostUsd = spending.maxCostUsd === null ? undefined : Math.max(0, spending.maxCostUsd);\n }\n if (spending.period !== undefined) {\n ctx.config.spending.period = spending.period;\n }\n }\n\n if (memory) {\n const providerChanged = memory.embeddingProvider !== undefined\n && memory.embeddingProvider !== (ctx.config as any).memory?.embeddingProvider;\n const modelChanged = memory.embeddingModel !== undefined\n && memory.embeddingModel !== (ctx.config as any).memory?.embeddingModel;\n\n if (memory.embeddingProvider !== undefined) {\n (ctx.config as any).memory.embeddingProvider = memory.embeddingProvider;\n }\n if (memory.embeddingModel !== undefined) {\n (ctx.config as any).memory.embeddingModel = memory.embeddingModel;\n }\n\n if (providerChanged || modelChanged) {\n ctx.invalidateMemoryManagers();\n }\n }\n\n await saveConfig(ctx.configPath, ctx.config);\n\n res.json({\n agent: ctx.config.agent,\n server: ctx.config.server,\n spending: ctx.config.spending,\n memory: (ctx.config as any).memory,\n });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n // POST /api/config/memory/test-embedding — test embedding provider connection\n router.post(\"/memory/test-embedding\", async (req, res) => {\n try {\n const { provider, apiKey, model } = req.body as {\n provider: string;\n apiKey?: string;\n model?: string;\n };\n\n if (provider === \"local\") {\n // Local embedding doesn't need a connection test — just confirm it's selected\n res.json({ success: true, message: \"Local embeddings use on-device model. No API connection needed.\", dimensions: null });\n return;\n }\n\n const providerMap: Record<string, { id: ProviderId; credKey: string; defaultModel: string }> = {\n openai: { id: \"openai\" as ProviderId, credKey: \"provider.openai.apiKey\", defaultModel: \"text-embedding-3-small\" },\n google: { id: \"google\" as ProviderId, credKey: \"provider.google.apiKey\", defaultModel: \"text-embedding-004\" },\n ollama: { id: \"ollama\" as ProviderId, credKey: \"provider.ollama.host\", defaultModel: \"nomic-embed-text\" },\n };\n\n const providerInfo = providerMap[provider];\n if (!providerInfo) {\n res.status(400).json({ success: false, error: `Unknown embedding provider: ${provider}` });\n return;\n }\n\n // Use provided API key or fall back to stored credential\n const key = apiKey || await ctx.credentialStore.get(providerInfo.credKey);\n if (!key) {\n res.status(400).json({ success: false, error: \"No API key configured. Add one in the AI Providers tab or enter it above.\" });\n return;\n }\n\n const llmProvider = createProvider(providerInfo.id, key);\n const embeddingModel = model || providerInfo.defaultModel;\n const result = await llmProvider.embed({\n model: embeddingModel,\n inputs: [\"test\"],\n });\n\n res.json({\n success: true,\n message: `Connected successfully. Model: ${embeddingModel}`,\n dimensions: result.embeddings[0]?.length ?? null,\n });\n } catch (err) {\n res.status(500).json({\n success: false,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n\n return router;\n}\n","import { Router } from \"express\";\nimport type { UsageStore } from \"@cortask/core\";\n\nexport function createUsageRoutes(usageStore: UsageStore): Router {\n const router = Router();\n\n // GET /api/usage?period=daily|weekly|monthly\n router.get(\"/\", (req, res) => {\n try {\n const period = (req.query.period as string) || \"monthly\";\n if (![\"daily\", \"weekly\", \"monthly\"].includes(period)) {\n res.status(400).json({ error: \"Invalid period. Use daily, weekly, or monthly.\" });\n return;\n }\n const summary = usageStore.getSummary(period as \"daily\" | \"weekly\" | \"monthly\");\n res.json(summary);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n // GET /api/usage/history?days=30\n router.get(\"/history\", (req, res) => {\n try {\n const days = Math.min(365, Math.max(1, parseInt(req.query.days as string) || 30));\n const history = usageStore.getHistory(days);\n res.json(history);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n return router;\n}\n","import { Router } from \"express\";\nimport type { GatewayContext } from \"../server.js\";\nimport { createProvider, getModelDefinitions, type ProviderId } from \"@cortask/core\";\n\nexport function createModelRoutes(ctx: GatewayContext): Router {\n const router = Router();\n\n // GET /api/models/:providerId/available — list available models for a provider\n router.get(\"/:providerId/available\", async (req, res) => {\n try {\n const providerId = req.params.providerId as ProviderId;\n\n // Providers that fetch models from their API\n if (providerId === \"openrouter\" || providerId === \"ollama\") {\n const credKey = providerId === \"ollama\"\n ? \"provider.ollama.host\"\n : `provider.${providerId}.apiKey`;\n const credential = await ctx.credentialStore.get(credKey);\n if (!credential) {\n res.status(400).json({ error: `No credentials configured for ${providerId}` });\n return;\n }\n const provider = createProvider(providerId, credential);\n const models = await provider.listModels();\n res.json(models);\n return;\n }\n\n // For all other providers, return hardcoded definitions\n const models = getModelDefinitions(providerId);\n res.json(models);\n } catch (err) {\n res.status(500).json({ error: err instanceof Error ? err.message : String(err) });\n }\n });\n\n // GET /api/models/enabled — list all enabled models (optionally filter by provider)\n router.get(\"/enabled\", async (_req, res) => {\n try {\n const provider = _req.query.provider as string | undefined;\n const models = ctx.modelStore.list(provider);\n res.json(models);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n // POST /api/models/enable — enable a model\n router.post(\"/enable\", async (req, res) => {\n try {\n const { provider, modelId, label, inputPricePer1m, outputPricePer1m } = req.body as {\n provider: string;\n modelId: string;\n label: string;\n inputPricePer1m: number;\n outputPricePer1m: number;\n };\n if (!provider || !modelId || !label) {\n res.status(400).json({ error: \"provider, modelId, and label are required\" });\n return;\n }\n const model = ctx.modelStore.enable(\n provider,\n modelId,\n label,\n inputPricePer1m ?? 0,\n outputPricePer1m ?? 0,\n );\n res.json(model);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n // DELETE /api/models/disable — disable a model\n router.delete(\"/disable\", async (req, res) => {\n try {\n const { provider, modelId } = req.body as { provider: string; modelId: string };\n if (!provider || !modelId) {\n res.status(400).json({ error: \"provider and modelId are required\" });\n return;\n }\n ctx.modelStore.disable(provider, modelId);\n res.json({ success: true });\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n return router;\n}\n","import { Router } from \"express\";\nimport type { TemplateStore } from \"@cortask/core\";\n\nexport function createTemplateRoutes(templateStore: TemplateStore): Router {\n const router = Router();\n\n router.get(\"/\", (_req, res) => {\n try {\n const templates = templateStore.list();\n res.json(templates);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.post(\"/\", (req, res) => {\n try {\n const { name, content, category } = req.body;\n if (!name || !content) {\n res.status(400).json({ error: \"name and content are required\" });\n return;\n }\n const template = templateStore.create(name, content, category);\n res.status(201).json(template);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.put(\"/:id\", (req, res) => {\n try {\n const updated = templateStore.update(req.params.id, req.body);\n if (!updated) {\n res.status(404).json({ error: \"Template not found\" });\n return;\n }\n res.json(updated);\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n router.delete(\"/:id\", (req, res) => {\n try {\n templateStore.delete(req.params.id);\n res.status(204).send();\n } catch (err) {\n res.status(500).json({ error: String(err) });\n }\n });\n\n return router;\n}\n","import { Router } from \"express\";\nimport type { GatewayContext } from \"../server.js\";\nimport { createProvider, type ProviderId } from \"@cortask/core\";\nimport { getDefaultModel } from \"../server.js\";\n\nexport function createLlmRoutes(ctx: GatewayContext): Router {\n const router = Router();\n\n // Simple one-shot completion (used for cron expression conversion, etc.)\n router.post(\"/complete\", async (req, res) => {\n try {\n const { prompt } = req.body as { prompt?: string };\n if (!prompt) {\n res.status(400).json({ error: \"prompt is required\" });\n return;\n }\n\n const providerId = (ctx.config.providers.default || \"anthropic\") as ProviderId;\n const credKey = providerId === \"ollama\"\n ? \"provider.ollama.host\"\n : `provider.${providerId}.apiKey`;\n const apiKey = await ctx.credentialStore.get(credKey);\n if (!apiKey) {\n res.status(400).json({ error: \"No API key configured\" });\n return;\n }\n\n const provider = createProvider(providerId, apiKey);\n const model = ctx.config.providers[providerId]?.model || getDefaultModel(providerId);\n\n const result = await provider.generateText({\n model,\n messages: [{ role: \"user\", content: prompt }],\n maxTokens: 200,\n });\n\n res.json({ response: result.content });\n } catch (err) {\n res.status(500).json({\n error: err instanceof Error ? err.message : String(err),\n });\n }\n });\n\n return router;\n}\n","import { startServer as _startServer } from \"./server.js\";\n\nexport { startServer } from \"./server.js\";\nexport type { GatewayContext, AgentRunnerOptions } from \"./server.js\";\n\n// When run directly (not imported by CLI), start the server\nconst entryScript = process.argv[1] ?? \"\";\nconst isMainModule =\n typeof process !== \"undefined\" &&\n (entryScript.includes(\"gateway\") && entryScript.endsWith(\"index.js\"));\n\nif (isMainModule) {\n _startServer().catch((err: unknown) => {\n console.error(\"Failed to start gateway:\", err);\n process.exit(1);\n });\n}\n"],"mappings":"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","names":["path","fs","createProvider","loadSkills","logger","WhatsAppAdapter","Router","Router","Router","Router","path","clearSkillCache","Router","Router","Router","Router","Router","saveConfig","Router","saveConfig","createProvider","Router","Router","createProvider","models","Router","Router","createProvider","Router","createProvider","path","logger","createProvider","loadSkills","WhatsAppAdapter","fs"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cortask/gateway",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.38",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
"express": "^4.21.0",
|
|
18
18
|
"ws": "^8.18.0",
|
|
19
19
|
"cors": "^2.8.5",
|
|
20
|
-
"@cortask/core": "0.2.
|
|
21
|
-
"@cortask/channels": "0.2.
|
|
20
|
+
"@cortask/core": "0.2.38",
|
|
21
|
+
"@cortask/channels": "0.2.38"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@types/express": "^5.0.0",
|