@tleblancureta/proto 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/dist/core-gateway/auth.d.ts +7 -0
  2. package/dist/core-gateway/auth.d.ts.map +1 -0
  3. package/dist/core-gateway/auth.js +12 -0
  4. package/dist/core-gateway/auth.js.map +1 -0
  5. package/dist/core-gateway/claude-runner.d.ts +10 -0
  6. package/dist/core-gateway/claude-runner.d.ts.map +1 -0
  7. package/dist/core-gateway/claude-runner.js +206 -0
  8. package/dist/core-gateway/claude-runner.js.map +1 -0
  9. package/dist/core-gateway/config.d.ts +33 -0
  10. package/dist/core-gateway/config.d.ts.map +1 -0
  11. package/dist/core-gateway/config.js +84 -0
  12. package/dist/core-gateway/config.js.map +1 -0
  13. package/dist/core-gateway/email-sender.d.ts +36 -0
  14. package/dist/core-gateway/email-sender.d.ts.map +1 -0
  15. package/dist/core-gateway/email-sender.js +121 -0
  16. package/dist/core-gateway/email-sender.js.map +1 -0
  17. package/dist/core-gateway/mail-ingester.d.ts +3 -0
  18. package/dist/core-gateway/mail-ingester.d.ts.map +1 -0
  19. package/dist/core-gateway/mail-ingester.js +294 -0
  20. package/dist/core-gateway/mail-ingester.js.map +1 -0
  21. package/dist/core-gateway/mail-router.d.ts +18 -0
  22. package/dist/core-gateway/mail-router.d.ts.map +1 -0
  23. package/dist/core-gateway/mail-router.js +37 -0
  24. package/dist/core-gateway/mail-router.js.map +1 -0
  25. package/dist/core-gateway/mail-threads.d.ts +78 -0
  26. package/dist/core-gateway/mail-threads.d.ts.map +1 -0
  27. package/dist/core-gateway/mail-threads.js +100 -0
  28. package/dist/core-gateway/mail-threads.js.map +1 -0
  29. package/dist/core-gateway/rate-limiter.d.ts +9 -0
  30. package/dist/core-gateway/rate-limiter.d.ts.map +1 -0
  31. package/dist/core-gateway/rate-limiter.js +13 -0
  32. package/dist/core-gateway/rate-limiter.js.map +1 -0
  33. package/dist/core-gateway/registry.d.ts +14 -0
  34. package/dist/core-gateway/registry.d.ts.map +1 -0
  35. package/dist/core-gateway/registry.js +83 -0
  36. package/dist/core-gateway/registry.js.map +1 -0
  37. package/dist/core-gateway/routes/admin.d.ts +3 -0
  38. package/dist/core-gateway/routes/admin.d.ts.map +1 -0
  39. package/dist/core-gateway/routes/admin.js +91 -0
  40. package/dist/core-gateway/routes/admin.js.map +1 -0
  41. package/dist/core-gateway/routes/chat.d.ts +9 -0
  42. package/dist/core-gateway/routes/chat.d.ts.map +1 -0
  43. package/dist/core-gateway/routes/chat.js +149 -0
  44. package/dist/core-gateway/routes/chat.js.map +1 -0
  45. package/dist/core-gateway/routes/cron.d.ts +13 -0
  46. package/dist/core-gateway/routes/cron.d.ts.map +1 -0
  47. package/dist/core-gateway/routes/cron.js +79 -0
  48. package/dist/core-gateway/routes/cron.js.map +1 -0
  49. package/dist/core-gateway/routes/gmail.d.ts +8 -0
  50. package/dist/core-gateway/routes/gmail.d.ts.map +1 -0
  51. package/dist/core-gateway/routes/gmail.js +57 -0
  52. package/dist/core-gateway/routes/gmail.js.map +1 -0
  53. package/dist/core-gateway/routes/health.d.ts +3 -0
  54. package/dist/core-gateway/routes/health.d.ts.map +1 -0
  55. package/dist/core-gateway/routes/health.js +7 -0
  56. package/dist/core-gateway/routes/health.js.map +1 -0
  57. package/dist/core-gateway/routes/upload.d.ts +7 -0
  58. package/dist/core-gateway/routes/upload.d.ts.map +1 -0
  59. package/dist/core-gateway/routes/upload.js +31 -0
  60. package/dist/core-gateway/routes/upload.js.map +1 -0
  61. package/dist/core-gateway/scheduler.d.ts +68 -0
  62. package/dist/core-gateway/scheduler.d.ts.map +1 -0
  63. package/dist/core-gateway/scheduler.js +252 -0
  64. package/dist/core-gateway/scheduler.js.map +1 -0
  65. package/dist/core-gateway/server.d.ts +17 -0
  66. package/dist/core-gateway/server.d.ts.map +1 -0
  67. package/dist/core-gateway/server.js +45 -0
  68. package/dist/core-gateway/server.js.map +1 -0
  69. package/dist/core-gateway/session.d.ts +18 -0
  70. package/dist/core-gateway/session.d.ts.map +1 -0
  71. package/dist/core-gateway/session.js +178 -0
  72. package/dist/core-gateway/session.js.map +1 -0
  73. package/dist/core-gateway/skills.d.ts +4 -0
  74. package/dist/core-gateway/skills.d.ts.map +1 -0
  75. package/dist/core-gateway/skills.js +100 -0
  76. package/dist/core-gateway/skills.js.map +1 -0
  77. package/dist/core-gateway/supabase.d.ts +3 -0
  78. package/dist/core-gateway/supabase.d.ts.map +1 -0
  79. package/dist/core-gateway/supabase.js +18 -0
  80. package/dist/core-gateway/supabase.js.map +1 -0
  81. package/dist/gateway.d.ts +3 -0
  82. package/dist/gateway.d.ts.map +1 -0
  83. package/dist/gateway.js +3 -0
  84. package/dist/gateway.js.map +1 -0
  85. package/package.json +21 -1
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Loads skill + agent definitions from the filesystem.
3
+ * Skills live in skills/<name>/SKILL.md, agents in agents/<name>.md.
4
+ * Parsed once at import time and cached in module scope.
5
+ */
6
+ import { readFileSync, readdirSync, statSync, existsSync } from 'node:fs';
7
+ import { join, basename } from 'node:path';
8
+ import yaml from 'yaml';
9
+ import { config, resolveAppPath } from './config.js';
10
+ // ── Skill loader ──
11
+ function parseSkillFrontmatter(filePath) {
12
+ try {
13
+ const raw = readFileSync(filePath, 'utf-8');
14
+ if (!raw.startsWith('---'))
15
+ return null;
16
+ const parts = raw.split('---');
17
+ if (parts.length < 3)
18
+ return null;
19
+ const meta = yaml.parse(parts[1]) || {};
20
+ const name = meta.name;
21
+ if (!name)
22
+ return null;
23
+ return {
24
+ name,
25
+ description: meta.description ?? null,
26
+ mcp_tools: meta['mcp-tools'] ?? [],
27
+ depends: Array.isArray(meta.depends) ? meta.depends : [],
28
+ filePath,
29
+ };
30
+ }
31
+ catch (err) {
32
+ console.warn(`[registry] Failed to parse ${filePath}:`, err);
33
+ return null;
34
+ }
35
+ }
36
+ function discoverSkills() {
37
+ const dir = resolveAppPath(config.skills_dir);
38
+ if (!existsSync(dir))
39
+ return [];
40
+ const skills = [];
41
+ for (const entry of readdirSync(dir)) {
42
+ const entryPath = join(dir, entry);
43
+ if (!statSync(entryPath).isDirectory())
44
+ continue;
45
+ const skillFile = join(entryPath, 'SKILL.md');
46
+ if (!existsSync(skillFile))
47
+ continue;
48
+ const skill = parseSkillFrontmatter(skillFile);
49
+ if (skill)
50
+ skills.push(skill);
51
+ }
52
+ return skills;
53
+ }
54
+ // ── Agent loader ──
55
+ function discoverAgents() {
56
+ const dir = resolveAppPath(config.agents_dir);
57
+ if (!existsSync(dir))
58
+ return [];
59
+ const agents = [];
60
+ for (const entry of readdirSync(dir)) {
61
+ if (!entry.endsWith('.md'))
62
+ continue;
63
+ agents.push({
64
+ name: basename(entry, '.md'),
65
+ filePath: join(dir, entry),
66
+ });
67
+ }
68
+ return agents;
69
+ }
70
+ // ── Cached at module level (read once at startup) ──
71
+ let _skills = null;
72
+ let _agents = null;
73
+ export function loadSkills() {
74
+ if (!_skills)
75
+ _skills = discoverSkills();
76
+ return _skills;
77
+ }
78
+ export function loadAgents() {
79
+ if (!_agents)
80
+ _agents = discoverAgents();
81
+ return _agents;
82
+ }
83
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../core-gateway/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Hono } from 'hono';
2
+ export declare function registerAdminRoutes(app: Hono): void;
3
+ //# sourceMappingURL=admin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../../../core-gateway/routes/admin.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAIhC,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,IAAI,QAe5C"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Admin metadata endpoint — exposes registered tools, entities, workflows,
3
+ * and skills for the Proto admin panel.
4
+ *
5
+ * Reads the app directory (PROTO_APP_ROOT) to extract metadata without
6
+ * executing tool handlers.
7
+ */
8
+ import { readdirSync, existsSync } from 'node:fs';
9
+ import { join } from 'node:path';
10
+ import { pathToFileURL } from 'node:url';
11
+ import { resolveAppPath } from '../config.js';
12
+ import { loadSkills } from '../registry.js';
13
+ export function registerAdminRoutes(app) {
14
+ app.get('/admin/meta', async (c) => {
15
+ const [tools, entities, workflows] = await Promise.all([
16
+ discoverToolMeta(),
17
+ discoverEntityMeta(),
18
+ discoverWorkflowMeta(),
19
+ ]);
20
+ const skills = loadSkills().map(s => ({
21
+ name: s.name,
22
+ description: s.description,
23
+ mcp_tools: s.mcp_tools,
24
+ }));
25
+ return c.json({ tools, entities, workflows, skills });
26
+ });
27
+ }
28
+ async function discoverToolMeta() {
29
+ const dir = resolveAppPath('app/tools');
30
+ if (!existsSync(dir))
31
+ return [];
32
+ const files = readdirSync(dir).filter(f => (f.endsWith('.ts') || f.endsWith('.js')) && f !== 'index.ts' && f !== 'index.js');
33
+ const tools = [];
34
+ for (const file of files) {
35
+ try {
36
+ const mod = await import(pathToFileURL(join(dir, file)).href);
37
+ const defs = mod.default;
38
+ if (!Array.isArray(defs))
39
+ continue;
40
+ for (const t of defs) {
41
+ if (t && typeof t.name === 'string') {
42
+ tools.push({ name: t.name, description: t.description || '' });
43
+ }
44
+ }
45
+ }
46
+ catch {
47
+ // Skip files that fail to import
48
+ }
49
+ }
50
+ return tools;
51
+ }
52
+ async function discoverEntityMeta() {
53
+ const dir = resolveAppPath('app/entities');
54
+ if (!existsSync(dir))
55
+ return [];
56
+ const files = readdirSync(dir).filter(f => (f.endsWith('.ts') || f.endsWith('.js')) && f !== 'index.ts' && f !== 'index.js');
57
+ const entities = [];
58
+ for (const file of files) {
59
+ try {
60
+ const mod = await import(pathToFileURL(join(dir, file)).href);
61
+ const def = mod.default;
62
+ if (def && typeof def.name === 'string') {
63
+ entities.push({ name: def.name, table: def.table || '' });
64
+ }
65
+ }
66
+ catch { }
67
+ }
68
+ return entities;
69
+ }
70
+ async function discoverWorkflowMeta() {
71
+ const dir = resolveAppPath('app/workflows');
72
+ if (!existsSync(dir))
73
+ return [];
74
+ const files = readdirSync(dir).filter(f => (f.endsWith('.ts') || f.endsWith('.js')) && !f.startsWith('_'));
75
+ const workflows = [];
76
+ for (const file of files) {
77
+ try {
78
+ const mod = await import(pathToFileURL(join(dir, file)).href);
79
+ const def = mod.default;
80
+ if (def && typeof def.name === 'string') {
81
+ const phases = Array.isArray(def.phases)
82
+ ? def.phases.map((p) => typeof p === 'string' ? p : p.name || '').filter(Boolean)
83
+ : [];
84
+ workflows.push({ name: def.name, entityTable: def.entityTable || '', phases });
85
+ }
86
+ }
87
+ catch { }
88
+ }
89
+ return workflows;
90
+ }
91
+ //# sourceMappingURL=admin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin.js","sourceRoot":"","sources":["../../../core-gateway/routes/admin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { Hono } from 'hono';
2
+ type UpgradeWebSocket = (handler: (c: any) => any) => any;
3
+ /**
4
+ * Chat routes: WebSocket streaming (primary), REST /chat + /chat/stream
5
+ * (legacy), and /reset for Claude CLI session invalidation.
6
+ */
7
+ export declare function registerChatRoutes(app: Hono, upgradeWebSocket: UpgradeWebSocket): void;
8
+ export {};
9
+ //# sourceMappingURL=chat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../../core-gateway/routes/chat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAQhC,KAAK,gBAAgB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,GAAG,KAAK,GAAG,CAAA;AAEzD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,IAAI,EAAE,gBAAgB,EAAE,gBAAgB,QAmG/E"}
@@ -0,0 +1,149 @@
1
+ import { streamSSE } from 'hono/streaming';
2
+ import { chatRequestSchema } from '@tleblancureta/proto/shared';
3
+ import { verifySecret } from '../auth.js';
4
+ import { runClaude, streamClaude } from '../claude-runner.js';
5
+ import { checkRateLimit } from '../rate-limiter.js';
6
+ import { INTERNAL_SECRET } from '../config.js';
7
+ /**
8
+ * Chat routes: WebSocket streaming (primary), REST /chat + /chat/stream
9
+ * (legacy), and /reset for Claude CLI session invalidation.
10
+ */
11
+ export function registerChatRoutes(app, upgradeWebSocket) {
12
+ // --- WebSocket ---
13
+ app.get('/ws', upgradeWebSocket(() => {
14
+ let authenticated = false;
15
+ return {
16
+ onMessage(event, ws) {
17
+ try {
18
+ const data = JSON.parse(event.data.toString());
19
+ // First message must be auth
20
+ if (!authenticated) {
21
+ if (data.type === 'auth' && data.secret === INTERNAL_SECRET) {
22
+ authenticated = true;
23
+ ws.send(JSON.stringify({ type: 'auth', status: 'ok' }));
24
+ }
25
+ else {
26
+ ws.send(JSON.stringify({ type: 'error', message: 'Unauthorized' }));
27
+ ws.close(4001, 'Unauthorized');
28
+ }
29
+ return;
30
+ }
31
+ if (data.type === 'chat') {
32
+ handleWsChat(data, ws);
33
+ }
34
+ else if (data.type === 'ping') {
35
+ ws.send(JSON.stringify({ type: 'pong' }));
36
+ }
37
+ }
38
+ catch (err) {
39
+ ws.send(JSON.stringify({ type: 'error', message: err.message }));
40
+ }
41
+ },
42
+ onClose() { },
43
+ onError() { },
44
+ };
45
+ }));
46
+ // --- REST /reset ---
47
+ app.post('/reset', verifySecret, async (c) => {
48
+ const body = await c.req.json().catch(() => ({}));
49
+ const companyId = body?.company_id;
50
+ const sessionKey = body?.session_key;
51
+ if (!companyId)
52
+ return c.json({ error: 'company_id required' }, 400);
53
+ try {
54
+ const { join, resolve } = await import('node:path');
55
+ const { existsSync, rmSync } = await import('node:fs');
56
+ const dataRoot = process.env.DATA_DIR || '/data';
57
+ const slug = sessionKey ? `${companyId}/${sessionKey}` : companyId;
58
+ const sessionDir = resolve(dataRoot, 'sessions', slug);
59
+ const file = join(sessionDir, '.claude-session-id');
60
+ if (existsSync(file))
61
+ rmSync(file, { force: true });
62
+ return c.json({ ok: true });
63
+ }
64
+ catch (err) {
65
+ return c.json({ error: err.message || 'reset failed' }, 500);
66
+ }
67
+ });
68
+ // --- REST /chat ---
69
+ app.post('/chat', async (c) => {
70
+ const body = await c.req.json();
71
+ const parsed = chatRequestSchema.safeParse(body);
72
+ if (!parsed.success)
73
+ return c.json({ error: parsed.error.format() }, 400);
74
+ const { allowed, retryAfterMs } = checkRateLimit(parsed.data.company_id);
75
+ if (!allowed) {
76
+ const retryMin = Math.ceil((retryAfterMs || 0) / 60000);
77
+ return c.json({ error: `Rate limit exceeded. Try again in ${retryMin} minutes.` }, 429);
78
+ }
79
+ try {
80
+ const result = await runClaude(parsed.data);
81
+ return c.json(result);
82
+ }
83
+ catch (err) {
84
+ if (err.message?.includes('timed out'))
85
+ return c.json({ error: 'Claude Code session timed out' }, 504);
86
+ return c.json({ error: err.message || 'Claude Code error' }, 502);
87
+ }
88
+ });
89
+ // --- REST /chat/stream (SSE) ---
90
+ app.post('/chat/stream', async (c) => {
91
+ const body = await c.req.json();
92
+ const parsed = chatRequestSchema.safeParse(body);
93
+ if (!parsed.success)
94
+ return c.json({ error: parsed.error.format() }, 400);
95
+ const { allowed, retryAfterMs } = checkRateLimit(parsed.data.company_id);
96
+ if (!allowed) {
97
+ const retryMin = Math.ceil((retryAfterMs || 0) / 60000);
98
+ return c.json({ error: `Rate limit exceeded. Try again in ${retryMin} minutes.` }, 429);
99
+ }
100
+ return streamSSE(c, async (stream) => {
101
+ try {
102
+ for await (const event of streamClaude(parsed.data)) {
103
+ await stream.writeSSE({ data: JSON.stringify(event) });
104
+ }
105
+ }
106
+ catch (err) {
107
+ await stream.writeSSE({ data: JSON.stringify({ type: 'error', message: err.message }) });
108
+ }
109
+ });
110
+ });
111
+ }
112
+ function safeSend(ws, data) {
113
+ try {
114
+ ws.send(data);
115
+ return true;
116
+ }
117
+ catch {
118
+ return false; // socket closed
119
+ }
120
+ }
121
+ async function handleWsChat(data, ws) {
122
+ const parsed = chatRequestSchema.safeParse(data);
123
+ if (!parsed.success) {
124
+ safeSend(ws, JSON.stringify({ type: 'error', message: 'Invalid request' }));
125
+ return;
126
+ }
127
+ const { allowed, retryAfterMs } = checkRateLimit(parsed.data.company_id);
128
+ if (!allowed) {
129
+ const retryMin = Math.ceil((retryAfterMs || 0) / 60000);
130
+ safeSend(ws, JSON.stringify({ type: 'error', message: `Rate limit. Retry in ${retryMin} min` }));
131
+ return;
132
+ }
133
+ try {
134
+ for await (const event of streamClaude(parsed.data)) {
135
+ if (!safeSend(ws, JSON.stringify(event))) {
136
+ // Client disconnected — break out so the generator can clean up
137
+ break;
138
+ }
139
+ // Push shell refresh on tool_result and result
140
+ if (event.type === 'tool_result' || event.type === 'result') {
141
+ safeSend(ws, JSON.stringify({ type: 'shell_refresh' }));
142
+ }
143
+ }
144
+ }
145
+ catch (err) {
146
+ safeSend(ws, JSON.stringify({ type: 'error', message: err.message }));
147
+ }
148
+ }
149
+ //# sourceMappingURL=chat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat.js","sourceRoot":"","sources":["../../../core-gateway/routes/chat.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { Hono } from 'hono';
2
+ /**
3
+ * Cron control surface. Three responsibilities:
4
+ * /cron/tick — internal; called by pg_cron every minute
5
+ * /cron/trigger — manual; run a task right now ("run now" button)
6
+ * /cron/list — inspect tasks + next_run_at (debug / admin UI)
7
+ *
8
+ * Task CRUD is owned by the MCP tools (agent-facing) + direct DB access
9
+ * from the web frontend via supabase-js with RLS. The gateway only owns
10
+ * the dispatch layer.
11
+ */
12
+ export declare function registerCronRoutes(app: Hono): void;
13
+ //# sourceMappingURL=cron.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cron.d.ts","sourceRoot":"","sources":["../../../core-gateway/routes/cron.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAMhC;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,IAAI,QA+D3C"}
@@ -0,0 +1,79 @@
1
+ import { verifySecret } from '../auth.js';
2
+ import { getSupabase } from '../supabase.js';
3
+ import { tick, dispatchTask, recalcNextRun, computeNextRun } from '../scheduler.js';
4
+ import { isValidCronExpr } from '@tleblancureta/proto/shared';
5
+ /**
6
+ * Cron control surface. Three responsibilities:
7
+ * /cron/tick — internal; called by pg_cron every minute
8
+ * /cron/trigger — manual; run a task right now ("run now" button)
9
+ * /cron/list — inspect tasks + next_run_at (debug / admin UI)
10
+ *
11
+ * Task CRUD is owned by the MCP tools (agent-facing) + direct DB access
12
+ * from the web frontend via supabase-js with RLS. The gateway only owns
13
+ * the dispatch layer.
14
+ */
15
+ export function registerCronRoutes(app) {
16
+ // --- pg_cron webhook ---
17
+ app.post('/cron/tick', verifySecret, async (c) => {
18
+ const result = await tick();
19
+ return c.json({ ok: true, ...result });
20
+ });
21
+ // --- Manual trigger ---
22
+ app.post('/cron/trigger', verifySecret, async (c) => {
23
+ const body = await c.req.json().catch(() => ({}));
24
+ const taskId = body?.task_id;
25
+ const triggeredBy = body?.triggered_by || 'manual';
26
+ if (!taskId)
27
+ return c.json({ error: 'task_id required' }, 400);
28
+ const db = getSupabase();
29
+ const { data, error } = await db
30
+ .from('scheduled_tasks')
31
+ .select('*')
32
+ .eq('id', taskId)
33
+ .single();
34
+ if (error || !data)
35
+ return c.json({ error: 'task not found' }, 404);
36
+ // Dispatch in background — don't block the HTTP response
37
+ dispatchTask(data, { trigger: 'manual', triggeredBy }).catch(err => console.error('[cron] manual dispatch error', err));
38
+ return c.json({ ok: true, task_id: taskId, trigger: 'manual' });
39
+ });
40
+ // --- List tasks + next runs (debug / admin) ---
41
+ app.get('/cron/list', verifySecret, async (c) => {
42
+ const companyId = c.req.query('company_id');
43
+ const db = getSupabase();
44
+ let q = db
45
+ .from('scheduled_tasks')
46
+ .select('id, company_id, name, cron_expr, timezone, enabled, next_run_at, last_run_at, last_run_status')
47
+ .order('next_run_at', { ascending: true, nullsFirst: false });
48
+ if (companyId)
49
+ q = q.eq('company_id', companyId);
50
+ const { data, error } = await q;
51
+ if (error)
52
+ return c.json({ error: error.message }, 500);
53
+ return c.json({ tasks: data || [] });
54
+ });
55
+ // --- Recompute next_run for a task (called after CRUD in MCP tools) ---
56
+ app.post('/cron/recalc', verifySecret, async (c) => {
57
+ const body = await c.req.json().catch(() => ({}));
58
+ const taskId = body?.task_id;
59
+ if (!taskId)
60
+ return c.json({ error: 'task_id required' }, 400);
61
+ const next = await recalcNextRun(taskId);
62
+ return c.json({ ok: true, next_run_at: next?.toISOString() ?? null });
63
+ });
64
+ // --- Validate a cron expression (used by frontend form) ---
65
+ app.post('/cron/validate', verifySecret, async (c) => {
66
+ const body = await c.req.json().catch(() => ({}));
67
+ const expr = body?.cron_expr;
68
+ const tz = body?.timezone || 'America/Santiago';
69
+ if (!expr)
70
+ return c.json({ error: 'cron_expr required' }, 400);
71
+ if (!isValidCronExpr(expr))
72
+ return c.json({ valid: false, error: 'invalid format' });
73
+ const next = computeNextRun(expr, tz);
74
+ if (!next)
75
+ return c.json({ valid: false, error: 'unparseable' });
76
+ return c.json({ valid: true, next_run_at: next.toISOString() });
77
+ });
78
+ }
79
+ //# sourceMappingURL=cron.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cron.js","sourceRoot":"","sources":["../../../core-gateway/routes/cron.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { Hono } from 'hono';
2
+ /**
3
+ * Gmail OAuth flow:
4
+ * - GET /gmail/auth → returns the Google consent URL (frontend opens it).
5
+ * - POST /gmail/callback → exchanges code for tokens, stores in Supabase.
6
+ */
7
+ export declare function registerGmailRoutes(app: Hono): void;
8
+ //# sourceMappingURL=gmail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gmail.d.ts","sourceRoot":"","sources":["../../../core-gateway/routes/gmail.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAEhC;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,IAAI,QA2D5C"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Gmail OAuth flow:
3
+ * - GET /gmail/auth → returns the Google consent URL (frontend opens it).
4
+ * - POST /gmail/callback → exchanges code for tokens, stores in Supabase.
5
+ */
6
+ export function registerGmailRoutes(app) {
7
+ app.get('/gmail/auth', async (c) => {
8
+ const { google } = await import('googleapis');
9
+ const clientId = process.env.GMAIL_CLIENT_ID;
10
+ const clientSecret = process.env.GMAIL_CLIENT_SECRET;
11
+ const redirectUri = process.env.GMAIL_REDIRECT_URI || `${c.req.header('origin') || 'http://localhost:3001'}/gmail/callback`;
12
+ if (!clientId || !clientSecret)
13
+ return c.json({ error: 'Gmail not configured' }, 500);
14
+ const oauth2 = new google.auth.OAuth2(clientId, clientSecret, redirectUri);
15
+ const url = oauth2.generateAuthUrl({
16
+ access_type: 'offline',
17
+ prompt: 'consent',
18
+ scope: [
19
+ 'https://www.googleapis.com/auth/gmail.readonly',
20
+ 'https://www.googleapis.com/auth/gmail.send',
21
+ ],
22
+ state: c.req.query('user_id') || '',
23
+ });
24
+ return c.json({ url });
25
+ });
26
+ app.post('/gmail/callback', async (c) => {
27
+ const { google } = await import('googleapis');
28
+ const { code, user_id } = await c.req.json();
29
+ const clientId = process.env.GMAIL_CLIENT_ID;
30
+ const clientSecret = process.env.GMAIL_CLIENT_SECRET;
31
+ const redirectUri = process.env.GMAIL_REDIRECT_URI || 'http://localhost:3001/gmail/callback';
32
+ if (!clientId || !clientSecret)
33
+ return c.json({ error: 'Gmail not configured' }, 500);
34
+ const oauth2 = new google.auth.OAuth2(clientId, clientSecret, redirectUri);
35
+ try {
36
+ const { tokens } = await oauth2.getToken(code);
37
+ oauth2.setCredentials(tokens);
38
+ const gmail = google.gmail({ version: 'v1', auth: oauth2 });
39
+ const profile = await gmail.users.getProfile({ userId: 'me' });
40
+ const { createClient } = await import('@supabase/supabase-js');
41
+ const db = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_SERVICE_ROLE_KEY);
42
+ await db.from('gmail_tokens').upsert({
43
+ user_id,
44
+ access_token: tokens.access_token,
45
+ refresh_token: tokens.refresh_token,
46
+ expiry_date: tokens.expiry_date,
47
+ email: profile.data.emailAddress,
48
+ updated_at: new Date().toISOString(),
49
+ });
50
+ return c.json({ email: profile.data.emailAddress, connected: true });
51
+ }
52
+ catch (err) {
53
+ return c.json({ error: err.message }, 400);
54
+ }
55
+ });
56
+ }
57
+ //# sourceMappingURL=gmail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gmail.js","sourceRoot":"","sources":["../../../core-gateway/routes/gmail.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Hono } from 'hono';
2
+ export declare function registerHealthRoutes(app: Hono): void;
3
+ //# sourceMappingURL=health.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../../core-gateway/routes/health.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAGhC,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,IAAI,QAI7C"}
@@ -0,0 +1,7 @@
1
+ import { config } from '../config.js';
2
+ export function registerHealthRoutes(app) {
3
+ app.get('/health', async (c) => {
4
+ return c.json({ status: 'ok', project: config.name, ws: true });
5
+ });
6
+ }
7
+ //# sourceMappingURL=health.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.js","sourceRoot":"","sources":["../../../core-gateway/routes/health.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAErC,MAAM,UAAU,oBAAoB,CAAC,GAAS;IAC5C,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC7B,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;IACjE,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { Hono } from 'hono';
2
+ /**
3
+ * Upload route: persists uploaded files to the per-session data dir so the
4
+ * Claude CLI subprocess can read them back. Files auto-delete after 5min.
5
+ */
6
+ export declare function registerUploadRoutes(app: Hono): void;
7
+ //# sourceMappingURL=upload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../../core-gateway/routes/upload.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAEhC;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,IAAI,QAyB7C"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Upload route: persists uploaded files to the per-session data dir so the
3
+ * Claude CLI subprocess can read them back. Files auto-delete after 5min.
4
+ */
5
+ export function registerUploadRoutes(app) {
6
+ app.post('/upload', async (c) => {
7
+ const body = await c.req.parseBody();
8
+ const file = body['file'];
9
+ const companyId = body['company_id'];
10
+ const sessionKey = body['session_key'] || 'web';
11
+ if (!file || !companyId)
12
+ return c.json({ error: 'file and company_id required' }, 400);
13
+ const dataRoot = process.env.DATA_DIR || '/data';
14
+ const sessionDir = `${dataRoot}/sessions/${companyId}/${sessionKey}`;
15
+ const { mkdirSync, writeFileSync } = await import('node:fs');
16
+ mkdirSync(sessionDir, { recursive: true });
17
+ const filename = `${Date.now()}-${file.name}`;
18
+ const filepath = `${sessionDir}/${filename}`;
19
+ const buffer = Buffer.from(await file.arrayBuffer());
20
+ writeFileSync(filepath, buffer);
21
+ setTimeout(async () => {
22
+ try {
23
+ const { unlinkSync } = await import('node:fs');
24
+ unlinkSync(filepath);
25
+ }
26
+ catch { }
27
+ }, 30 * 60 * 1000);
28
+ return c.json({ path: filepath, filename });
29
+ });
30
+ }
31
+ //# sourceMappingURL=upload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload.js","sourceRoot":"","sources":["../../../core-gateway/routes/upload.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,GAAS;IAC5C,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC9B,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,EAAE,CAAA;QACpC,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAS,CAAA;QACjC,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAW,CAAA;QAC9C,MAAM,UAAU,GAAI,IAAI,CAAC,aAAa,CAAY,IAAI,KAAK,CAAA;QAE3D,IAAI,CAAC,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,8BAA8B,EAAE,EAAE,GAAG,CAAC,CAAA;QAEtF,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,OAAO,CAAA;QAChD,MAAM,UAAU,GAAG,GAAG,QAAQ,aAAa,SAAS,IAAI,UAAU,EAAE,CAAA;QACpE,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAA;QAC5D,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QAE1C,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,IAAI,EAAE,CAAA;QAC7C,MAAM,QAAQ,GAAG,GAAG,UAAU,IAAI,QAAQ,EAAE,CAAA;QAC5C,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC,CAAA;QACpD,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;QAE/B,UAAU,CAAC,KAAK,IAAI,EAAE;YACpB,IAAI,CAAC;gBAAC,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;gBAAC,UAAU,CAAC,QAAQ,CAAC,CAAA;YAAC,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;QACvF,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAA;QAElB,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAA;IAC7C,CAAC,CAAC,CAAA;AACJ,CAAC"}