@cortask/gateway 0.2.37 → 0.2.39

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 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 fs from "fs";
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 createProvider3,
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,221 @@ 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
+ });
311
+ router.put("/:id/files/*", async (req, res) => {
312
+ try {
313
+ const workspace = await ctx.workspaceManager.get(req.params.id);
314
+ if (!workspace) {
315
+ res.status(404).json({ error: "Workspace not found" });
316
+ return;
317
+ }
318
+ const relPath = req.params["0"];
319
+ if (!relPath || relPath === "rename") {
320
+ res.status(400).json({ error: "File path required" });
321
+ return;
322
+ }
323
+ const fullPath = path.resolve(workspace.rootPath, relPath);
324
+ if (!fullPath.startsWith(path.resolve(workspace.rootPath))) {
325
+ res.status(403).json({ error: "Path outside workspace" });
326
+ return;
327
+ }
328
+ const { content } = req.body;
329
+ if (typeof content !== "string") {
330
+ res.status(400).json({ error: "content string required" });
331
+ return;
332
+ }
333
+ await fs.mkdir(path.dirname(fullPath), { recursive: true });
334
+ await fs.writeFile(fullPath, content, "utf-8");
335
+ res.json({ ok: true });
336
+ } catch (err) {
337
+ res.status(500).json({ error: String(err) });
338
+ }
339
+ });
122
340
  router.get("/:id/files/*", async (req, res) => {
123
341
  try {
124
342
  const workspace = await ctx.workspaceManager.get(req.params.id);
@@ -673,9 +891,10 @@ function createSkillRoutes(ctx) {
673
891
  import { Router as Router6 } from "express";
674
892
  function createCronRoutes(cronService) {
675
893
  const router = Router6();
676
- router.get("/", (_req, res) => {
894
+ router.get("/", (req, res) => {
677
895
  try {
678
- const jobs = cronService.list();
896
+ const workspaceId = typeof req.query.workspaceId === "string" ? req.query.workspaceId : void 0;
897
+ const jobs = cronService.list(workspaceId);
679
898
  const result = jobs.map((job) => {
680
899
  const state = cronService.getState(job.id);
681
900
  return { ...job, state };
@@ -886,6 +1105,7 @@ async function handleChat(ws, msg, ctx) {
886
1105
  for await (const event of runner.runStream({
887
1106
  prompt: msg.message,
888
1107
  attachments: msg.attachments,
1108
+ fileReferences: msg.fileReferences,
889
1109
  sessionId: msg.sessionKey,
890
1110
  workspaceId: msg.workspaceId,
891
1111
  signal: abortController.signal
@@ -1234,20 +1454,20 @@ function createOnboardingRoutes(ctx) {
1234
1454
 
1235
1455
  // src/routes/config.ts
1236
1456
  import { Router as Router10 } from "express";
1237
- import { saveConfig as saveConfig3 } from "@cortask/core";
1457
+ import { saveConfig as saveConfig3, createProvider as createProvider2 } from "@cortask/core";
1238
1458
  function createConfigRoutes(ctx) {
1239
1459
  const router = Router10();
1240
1460
  router.get("/", (_req, res) => {
1241
1461
  try {
1242
- const { agent, server, spending } = ctx.config;
1243
- res.json({ agent, server, spending });
1462
+ const { agent, server, spending, memory } = ctx.config;
1463
+ res.json({ agent, server, spending, memory, dataDir: ctx.dataDir });
1244
1464
  } catch (err) {
1245
1465
  res.status(500).json({ error: String(err) });
1246
1466
  }
1247
1467
  });
1248
1468
  router.put("/", async (req, res) => {
1249
1469
  try {
1250
- const { agent, server, spending } = req.body;
1470
+ const { agent, server, spending, memory } = req.body;
1251
1471
  if (agent) {
1252
1472
  if (agent.maxTurns !== void 0) {
1253
1473
  const v = Math.max(1, Math.min(200, Math.round(agent.maxTurns)));
@@ -1283,16 +1503,70 @@ function createConfigRoutes(ctx) {
1283
1503
  ctx.config.spending.period = spending.period;
1284
1504
  }
1285
1505
  }
1506
+ if (memory) {
1507
+ const providerChanged = memory.embeddingProvider !== void 0 && memory.embeddingProvider !== ctx.config.memory?.embeddingProvider;
1508
+ const modelChanged = memory.embeddingModel !== void 0 && memory.embeddingModel !== ctx.config.memory?.embeddingModel;
1509
+ if (memory.embeddingProvider !== void 0) {
1510
+ ctx.config.memory.embeddingProvider = memory.embeddingProvider;
1511
+ }
1512
+ if (memory.embeddingModel !== void 0) {
1513
+ ctx.config.memory.embeddingModel = memory.embeddingModel;
1514
+ }
1515
+ if (providerChanged || modelChanged) {
1516
+ ctx.invalidateMemoryManagers();
1517
+ }
1518
+ }
1286
1519
  await saveConfig3(ctx.configPath, ctx.config);
1287
1520
  res.json({
1288
1521
  agent: ctx.config.agent,
1289
1522
  server: ctx.config.server,
1290
- spending: ctx.config.spending
1523
+ spending: ctx.config.spending,
1524
+ memory: ctx.config.memory
1291
1525
  });
1292
1526
  } catch (err) {
1293
1527
  res.status(500).json({ error: String(err) });
1294
1528
  }
1295
1529
  });
1530
+ router.post("/memory/test-embedding", async (req, res) => {
1531
+ try {
1532
+ const { provider, apiKey, model } = req.body;
1533
+ if (provider === "local") {
1534
+ res.json({ success: true, message: "Local embeddings use on-device model. No API connection needed.", dimensions: null });
1535
+ return;
1536
+ }
1537
+ const providerMap = {
1538
+ openai: { id: "openai", credKey: "provider.openai.apiKey", defaultModel: "text-embedding-3-small" },
1539
+ google: { id: "google", credKey: "provider.google.apiKey", defaultModel: "text-embedding-004" },
1540
+ ollama: { id: "ollama", credKey: "provider.ollama.host", defaultModel: "nomic-embed-text" }
1541
+ };
1542
+ const providerInfo = providerMap[provider];
1543
+ if (!providerInfo) {
1544
+ res.status(400).json({ success: false, error: `Unknown embedding provider: ${provider}` });
1545
+ return;
1546
+ }
1547
+ const key = apiKey || await ctx.credentialStore.get(providerInfo.credKey);
1548
+ if (!key) {
1549
+ res.status(400).json({ success: false, error: "No API key configured. Add one in the AI Providers tab or enter it above." });
1550
+ return;
1551
+ }
1552
+ const llmProvider = createProvider2(providerInfo.id, key);
1553
+ const embeddingModel = model || providerInfo.defaultModel;
1554
+ const result = await llmProvider.embed({
1555
+ model: embeddingModel,
1556
+ inputs: ["test"]
1557
+ });
1558
+ res.json({
1559
+ success: true,
1560
+ message: `Connected successfully. Model: ${embeddingModel}`,
1561
+ dimensions: result.embeddings[0]?.length ?? null
1562
+ });
1563
+ } catch (err) {
1564
+ res.status(500).json({
1565
+ success: false,
1566
+ error: err instanceof Error ? err.message : String(err)
1567
+ });
1568
+ }
1569
+ });
1296
1570
  return router;
1297
1571
  }
1298
1572
 
@@ -1327,7 +1601,7 @@ function createUsageRoutes(usageStore) {
1327
1601
 
1328
1602
  // src/routes/models.ts
1329
1603
  import { Router as Router12 } from "express";
1330
- import { createProvider as createProvider2, getModelDefinitions } from "@cortask/core";
1604
+ import { createProvider as createProvider3, getModelDefinitions } from "@cortask/core";
1331
1605
  function createModelRoutes(ctx) {
1332
1606
  const router = Router12();
1333
1607
  router.get("/:providerId/available", async (req, res) => {
@@ -1340,7 +1614,7 @@ function createModelRoutes(ctx) {
1340
1614
  res.status(400).json({ error: `No credentials configured for ${providerId}` });
1341
1615
  return;
1342
1616
  }
1343
- const provider = createProvider2(providerId, credential);
1617
+ const provider = createProvider3(providerId, credential);
1344
1618
  const models2 = await provider.listModels();
1345
1619
  res.json(models2);
1346
1620
  return;
@@ -1443,12 +1717,49 @@ function createTemplateRoutes(templateStore) {
1443
1717
  return router;
1444
1718
  }
1445
1719
 
1720
+ // src/routes/llm.ts
1721
+ import { Router as Router14 } from "express";
1722
+ import { createProvider as createProvider4 } from "@cortask/core";
1723
+ function createLlmRoutes(ctx) {
1724
+ const router = Router14();
1725
+ router.post("/complete", async (req, res) => {
1726
+ try {
1727
+ const { prompt } = req.body;
1728
+ if (!prompt) {
1729
+ res.status(400).json({ error: "prompt is required" });
1730
+ return;
1731
+ }
1732
+ const providerId = ctx.config.providers.default || "anthropic";
1733
+ const credKey = providerId === "ollama" ? "provider.ollama.host" : `provider.${providerId}.apiKey`;
1734
+ const apiKey = await ctx.credentialStore.get(credKey);
1735
+ if (!apiKey) {
1736
+ res.status(400).json({ error: "No API key configured" });
1737
+ return;
1738
+ }
1739
+ const provider = createProvider4(providerId, apiKey);
1740
+ const model = ctx.config.providers[providerId]?.model || getDefaultModel(providerId);
1741
+ const result = await provider.generateText({
1742
+ model,
1743
+ messages: [{ role: "user", content: prompt }],
1744
+ maxTokens: 200
1745
+ });
1746
+ res.json({ response: result.content });
1747
+ } catch (err) {
1748
+ res.status(500).json({
1749
+ error: err instanceof Error ? err.message : String(err)
1750
+ });
1751
+ }
1752
+ });
1753
+ return router;
1754
+ }
1755
+
1446
1756
  // src/server.ts
1447
1757
  var __filename = fileURLToPath(import.meta.url);
1448
1758
  var __dirname = path3.dirname(__filename);
1449
1759
  var _require = createRequire(import.meta.url);
1450
1760
  var PKG_VERSION = _require("../package.json").version;
1451
1761
  var sessionStoreCache = /* @__PURE__ */ new Map();
1762
+ var memoryManagerCache = /* @__PURE__ */ new Map();
1452
1763
  function getSessionStore(workspacePath) {
1453
1764
  const dbPath = path3.join(workspacePath, ".cortask", "sessions.db");
1454
1765
  let store = sessionStoreCache.get(dbPath);
@@ -1480,6 +1791,41 @@ async function startServer(port, host) {
1480
1791
  path3.join(dataDir, "credentials.enc.json"),
1481
1792
  secret
1482
1793
  );
1794
+ let localEmbedProvider = null;
1795
+ let localEmbedFailed = false;
1796
+ async function getMemoryManager(workspacePath) {
1797
+ const mmDbPath = path3.join(workspacePath, ".cortask", "memory.db");
1798
+ let manager = memoryManagerCache.get(mmDbPath);
1799
+ if (manager) return manager;
1800
+ const embeddingProvider = config.memory?.embeddingProvider ?? "local";
1801
+ const embeddingModel = config.memory?.embeddingModel;
1802
+ let apiProvider;
1803
+ if (embeddingProvider === "local") {
1804
+ if (!localEmbedProvider && !localEmbedFailed) {
1805
+ try {
1806
+ localEmbedProvider = await createLocalEmbeddingProvider();
1807
+ logger2.info("Local embedding provider initialized", "memory");
1808
+ } catch (err) {
1809
+ localEmbedFailed = true;
1810
+ logger2.debug(`Local embeddings unavailable: ${err instanceof Error ? err.message : err}`, "memory");
1811
+ }
1812
+ }
1813
+ } else if (["openai", "google", "ollama"].includes(embeddingProvider)) {
1814
+ const credKey = embeddingProvider === "ollama" ? "provider.ollama.host" : `provider.${embeddingProvider}.apiKey`;
1815
+ const key = await credentialStore.get(credKey);
1816
+ if (key) {
1817
+ apiProvider = createProvider5(embeddingProvider, key);
1818
+ }
1819
+ }
1820
+ manager = new MemoryManager({
1821
+ dbPath: mmDbPath,
1822
+ localProvider: embeddingProvider === "local" ? localEmbedProvider ?? void 0 : void 0,
1823
+ apiProvider: apiProvider ?? void 0,
1824
+ embeddingModel
1825
+ });
1826
+ memoryManagerCache.set(mmDbPath, manager);
1827
+ return manager;
1828
+ }
1483
1829
  const cronService = new CronService(dbPath);
1484
1830
  const modelStore = new ModelStore(dbPath);
1485
1831
  const templateStore = new TemplateStore(dbPath);
@@ -1535,7 +1881,7 @@ async function startServer(port, host) {
1535
1881
  `No credentials found for provider "${providerId}". Set it in Settings.`
1536
1882
  );
1537
1883
  }
1538
- const provider = createProvider3(providerId, apiKey);
1884
+ const provider = createProvider5(providerId, apiKey);
1539
1885
  const sessionStore = getSessionStore(workspacePath);
1540
1886
  const allSkills = await loadSkills2(
1541
1887
  bundledSkillsDir,
@@ -1557,6 +1903,7 @@ async function startServer(port, host) {
1557
1903
  }));
1558
1904
  const skillPrompts = eligible.map((s) => `- **${s.manifest.name}**: ${s.manifest.description}`);
1559
1905
  const channelTools = channelCtx ? [createSwitchWorkspaceTool(workspaceManager, channelCtx.chatKey)] : [];
1906
+ const memoryManager = await getMemoryManager(workspacePath);
1560
1907
  const runner = new AgentRunner({
1561
1908
  config: {
1562
1909
  provider,
@@ -1565,6 +1912,7 @@ async function startServer(port, host) {
1565
1912
  temperature: config.agent.temperature,
1566
1913
  maxTokens: config.agent.maxTokens
1567
1914
  },
1915
+ memoryManager,
1568
1916
  tools: [
1569
1917
  ...channelCtx ? builtinTools.filter((t) => !uiOnlyTools.has(t.definition.name)) : builtinTools,
1570
1918
  createCronTool(cronService),
@@ -1616,6 +1964,14 @@ async function startServer(port, host) {
1616
1964
  usageStore,
1617
1965
  modelStore,
1618
1966
  getSessionStore,
1967
+ getMemoryManager,
1968
+ invalidateMemoryManagers: () => {
1969
+ for (const mgr of memoryManagerCache.values()) mgr.close();
1970
+ memoryManagerCache.clear();
1971
+ localEmbedProvider?.dispose();
1972
+ localEmbedProvider = null;
1973
+ localEmbedFailed = false;
1974
+ },
1619
1975
  createAgentRunner
1620
1976
  };
1621
1977
  const app = express();
@@ -1636,7 +1992,7 @@ async function startServer(port, host) {
1636
1992
  }));
1637
1993
  app.use((_req, res, next) => {
1638
1994
  res.setHeader("X-Content-Type-Options", "nosniff");
1639
- res.setHeader("X-Frame-Options", "DENY");
1995
+ res.setHeader("X-Frame-Options", "SAMEORIGIN");
1640
1996
  next();
1641
1997
  });
1642
1998
  app.use(express.json({ limit: "10mb" }));
@@ -1671,6 +2027,7 @@ async function startServer(port, host) {
1671
2027
  app.use("/api/usage", createUsageRoutes(usageStore));
1672
2028
  app.use("/api/models", createModelRoutes(ctx));
1673
2029
  app.use("/api/templates", createTemplateRoutes(templateStore));
2030
+ app.use("/api/llm", createLlmRoutes(ctx));
1674
2031
  async function createChannelAdapter(id) {
1675
2032
  if (id === "telegram") {
1676
2033
  const botToken = await credentialStore.get("channel.telegram.botToken");
@@ -1726,7 +2083,7 @@ async function startServer(port, host) {
1726
2083
  // electron packaged
1727
2084
  ];
1728
2085
  for (const uiDir of uiDistCandidates) {
1729
- if (fs.existsSync(path3.join(uiDir, "index.html"))) {
2086
+ if (fs2.existsSync(path3.join(uiDir, "index.html"))) {
1730
2087
  app.use(express.static(uiDir));
1731
2088
  app.get("*", (_req, res, next) => {
1732
2089
  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\", \"SAMEORIGIN\");\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 // Write file content\n router.put(\"/: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 || relPath === \"rename\") {\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 { content } = req.body as { content?: string };\n if (typeof content !== \"string\") {\n res.status(400).json({ error: \"content string required\" });\n return;\n }\n\n // Ensure parent directory exists\n await fs.mkdir(path.dirname(fullPath), { recursive: true });\n await fs.writeFile(fullPath, content, \"utf-8\");\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.37",
3
+ "version": "0.2.39",
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.37",
21
- "@cortask/channels": "0.2.37"
20
+ "@cortask/core": "0.2.39",
21
+ "@cortask/channels": "0.2.39"
22
22
  },
23
23
  "devDependencies": {
24
24
  "@types/express": "^5.0.0",