@tleblancureta/proto 0.1.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core-web/src/ProtoApp.tsx +30 -20
- package/core-web/src/components/admin/AdminPanel.tsx +285 -0
- package/core-web/src/components/admin/SystemTab.tsx +167 -0
- package/core-web/src/components/shell/Toolbar.tsx +11 -1
- package/core-web/src/index.ts +1 -0
- package/dist/core-gateway/auth.d.ts +7 -0
- package/dist/core-gateway/auth.d.ts.map +1 -0
- package/dist/core-gateway/auth.js +12 -0
- package/dist/core-gateway/auth.js.map +1 -0
- package/dist/core-gateway/claude-runner.d.ts +10 -0
- package/dist/core-gateway/claude-runner.d.ts.map +1 -0
- package/dist/core-gateway/claude-runner.js +206 -0
- package/dist/core-gateway/claude-runner.js.map +1 -0
- package/dist/core-gateway/config.d.ts +33 -0
- package/dist/core-gateway/config.d.ts.map +1 -0
- package/dist/core-gateway/config.js +84 -0
- package/dist/core-gateway/config.js.map +1 -0
- package/dist/core-gateway/email-sender.d.ts +36 -0
- package/dist/core-gateway/email-sender.d.ts.map +1 -0
- package/dist/core-gateway/email-sender.js +121 -0
- package/dist/core-gateway/email-sender.js.map +1 -0
- package/dist/core-gateway/mail-ingester.d.ts +3 -0
- package/dist/core-gateway/mail-ingester.d.ts.map +1 -0
- package/dist/core-gateway/mail-ingester.js +294 -0
- package/dist/core-gateway/mail-ingester.js.map +1 -0
- package/dist/core-gateway/mail-router.d.ts +18 -0
- package/dist/core-gateway/mail-router.d.ts.map +1 -0
- package/dist/core-gateway/mail-router.js +37 -0
- package/dist/core-gateway/mail-router.js.map +1 -0
- package/dist/core-gateway/mail-threads.d.ts +78 -0
- package/dist/core-gateway/mail-threads.d.ts.map +1 -0
- package/dist/core-gateway/mail-threads.js +100 -0
- package/dist/core-gateway/mail-threads.js.map +1 -0
- package/dist/core-gateway/rate-limiter.d.ts +9 -0
- package/dist/core-gateway/rate-limiter.d.ts.map +1 -0
- package/dist/core-gateway/rate-limiter.js +13 -0
- package/dist/core-gateway/rate-limiter.js.map +1 -0
- package/dist/core-gateway/registry.d.ts +14 -0
- package/dist/core-gateway/registry.d.ts.map +1 -0
- package/dist/core-gateway/registry.js +83 -0
- package/dist/core-gateway/registry.js.map +1 -0
- package/dist/core-gateway/routes/admin.d.ts +3 -0
- package/dist/core-gateway/routes/admin.d.ts.map +1 -0
- package/dist/core-gateway/routes/admin.js +91 -0
- package/dist/core-gateway/routes/admin.js.map +1 -0
- package/dist/core-gateway/routes/chat.d.ts +9 -0
- package/dist/core-gateway/routes/chat.d.ts.map +1 -0
- package/dist/core-gateway/routes/chat.js +149 -0
- package/dist/core-gateway/routes/chat.js.map +1 -0
- package/dist/core-gateway/routes/cron.d.ts +13 -0
- package/dist/core-gateway/routes/cron.d.ts.map +1 -0
- package/dist/core-gateway/routes/cron.js +79 -0
- package/dist/core-gateway/routes/cron.js.map +1 -0
- package/dist/core-gateway/routes/gmail.d.ts +8 -0
- package/dist/core-gateway/routes/gmail.d.ts.map +1 -0
- package/dist/core-gateway/routes/gmail.js +57 -0
- package/dist/core-gateway/routes/gmail.js.map +1 -0
- package/dist/core-gateway/routes/health.d.ts +3 -0
- package/dist/core-gateway/routes/health.d.ts.map +1 -0
- package/dist/core-gateway/routes/health.js +7 -0
- package/dist/core-gateway/routes/health.js.map +1 -0
- package/dist/core-gateway/routes/upload.d.ts +7 -0
- package/dist/core-gateway/routes/upload.d.ts.map +1 -0
- package/dist/core-gateway/routes/upload.js +31 -0
- package/dist/core-gateway/routes/upload.js.map +1 -0
- package/dist/core-gateway/scheduler.d.ts +68 -0
- package/dist/core-gateway/scheduler.d.ts.map +1 -0
- package/dist/core-gateway/scheduler.js +252 -0
- package/dist/core-gateway/scheduler.js.map +1 -0
- package/dist/core-gateway/server.d.ts +17 -0
- package/dist/core-gateway/server.d.ts.map +1 -0
- package/dist/core-gateway/server.js +45 -0
- package/dist/core-gateway/server.js.map +1 -0
- package/dist/core-gateway/session.d.ts +18 -0
- package/dist/core-gateway/session.d.ts.map +1 -0
- package/dist/core-gateway/session.js +178 -0
- package/dist/core-gateway/session.js.map +1 -0
- package/dist/core-gateway/skills.d.ts +4 -0
- package/dist/core-gateway/skills.d.ts.map +1 -0
- package/dist/core-gateway/skills.js +100 -0
- package/dist/core-gateway/skills.js.map +1 -0
- package/dist/core-gateway/supabase.d.ts +3 -0
- package/dist/core-gateway/supabase.d.ts.map +1 -0
- package/dist/core-gateway/supabase.js +18 -0
- package/dist/core-gateway/supabase.js.map +1 -0
- package/dist/core-web/src/ProtoApp.d.ts.map +1 -1
- package/dist/core-web/src/ProtoApp.js +5 -3
- package/dist/core-web/src/ProtoApp.js.map +1 -1
- package/dist/core-web/src/components/admin/AdminPanel.d.ts +7 -0
- package/dist/core-web/src/components/admin/AdminPanel.d.ts.map +1 -0
- package/dist/core-web/src/components/admin/AdminPanel.js +112 -0
- package/dist/core-web/src/components/admin/AdminPanel.js.map +1 -0
- package/dist/core-web/src/components/admin/SystemTab.d.ts +2 -0
- package/dist/core-web/src/components/admin/SystemTab.d.ts.map +1 -0
- package/dist/core-web/src/components/admin/SystemTab.js +25 -0
- package/dist/core-web/src/components/admin/SystemTab.js.map +1 -0
- package/dist/core-web/src/components/shell/Toolbar.d.ts.map +1 -1
- package/dist/core-web/src/components/shell/Toolbar.js +4 -2
- package/dist/core-web/src/components/shell/Toolbar.js.map +1 -1
- package/dist/core-web/src/index.d.ts +1 -0
- package/dist/core-web/src/index.d.ts.map +1 -1
- package/dist/core-web/src/index.js +1 -0
- package/dist/core-web/src/index.js.map +1 -1
- package/dist/gateway.d.ts +3 -0
- package/dist/gateway.d.ts.map +1 -0
- package/dist/gateway.js +3 -0
- package/dist/gateway.js.map +1 -0
- package/package.json +22 -1
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { TaskNotifyTrigger, TaskOutputChannel } from '@tleblancureta/proto/shared';
|
|
2
|
+
/**
|
|
3
|
+
* Scheduler core: next-run calculation, due-task scan, dispatch.
|
|
4
|
+
*
|
|
5
|
+
* The scheduling model is "next_run_at is canonical". On any schedule change
|
|
6
|
+
* (insert, update, or after a run finishes) we compute the next_run_at from
|
|
7
|
+
* the cron expression + timezone and store it. `scanDueTasks` just queries
|
|
8
|
+
* for rows where next_run_at <= now() AND enabled = true. This is cheap and
|
|
9
|
+
* race-free.
|
|
10
|
+
*/
|
|
11
|
+
export interface ScheduledTaskRow {
|
|
12
|
+
id: string;
|
|
13
|
+
company_id: string;
|
|
14
|
+
name: string;
|
|
15
|
+
description: string | null;
|
|
16
|
+
cron_expr: string;
|
|
17
|
+
timezone: string;
|
|
18
|
+
prompt: string;
|
|
19
|
+
enabled_skills: string[];
|
|
20
|
+
session_key: string | null;
|
|
21
|
+
user_id: string;
|
|
22
|
+
enabled: boolean;
|
|
23
|
+
max_runtime_seconds: number;
|
|
24
|
+
next_run_at: string | null;
|
|
25
|
+
last_run_at: string | null;
|
|
26
|
+
last_run_status: string | null;
|
|
27
|
+
output_channel: TaskOutputChannel;
|
|
28
|
+
output_recipient: string | null;
|
|
29
|
+
notify_on: TaskNotifyTrigger;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Compute the next firing instant of `expr` strictly after `from`.
|
|
33
|
+
* Returns null if the expression is invalid.
|
|
34
|
+
*/
|
|
35
|
+
export declare function computeNextRun(expr: string, timezone: string, from?: Date): Date | null;
|
|
36
|
+
/**
|
|
37
|
+
* Recompute and persist next_run_at for a task. Call this after INSERT/UPDATE
|
|
38
|
+
* and after a run finishes.
|
|
39
|
+
*/
|
|
40
|
+
export declare function recalcNextRun(taskId: string): Promise<Date | null>;
|
|
41
|
+
/**
|
|
42
|
+
* Find tasks whose next_run_at has passed. Returns at most `limit` rows.
|
|
43
|
+
*/
|
|
44
|
+
export declare function scanDueTasks(limit?: number): Promise<ScheduledTaskRow[]>;
|
|
45
|
+
interface DispatchOptions {
|
|
46
|
+
trigger: 'scheduled' | 'manual' | 'retry';
|
|
47
|
+
triggeredBy?: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Execute a task: creates a task_runs row, invokes runClaude with the task's
|
|
51
|
+
* prompt/skills, then writes back the result and recomputes next_run_at.
|
|
52
|
+
*
|
|
53
|
+
* Runs are non-blocking from the caller's perspective — the tick endpoint
|
|
54
|
+
* fires these and returns immediately while dispatch continues in the
|
|
55
|
+
* background. We guard against double-dispatch by claiming the row first
|
|
56
|
+
* (set last_run_at + clear next_run_at).
|
|
57
|
+
*/
|
|
58
|
+
export declare function dispatchTask(task: ScheduledTaskRow, opts: DispatchOptions): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* Scan + dispatch in background. Called by the pg_cron webhook.
|
|
61
|
+
* Returns immediately with the number of tasks claimed; actual execution
|
|
62
|
+
* runs async.
|
|
63
|
+
*/
|
|
64
|
+
export declare function tick(): Promise<{
|
|
65
|
+
dispatched: number;
|
|
66
|
+
}>;
|
|
67
|
+
export {};
|
|
68
|
+
//# sourceMappingURL=scheduler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../core-gateway/scheduler.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAA;AAEvF;;;;;;;;GAQG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,OAAO,CAAA;IAChB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,cAAc,EAAE,iBAAiB,CAAA;IACjC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,SAAS,EAAE,iBAAiB,CAAA;CAC7B;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,IAAiB,GAAG,IAAI,GAAG,IAAI,CAQnG;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAexE;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,KAAK,SAAK,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAe1E;AAED,UAAU,eAAe;IACvB,OAAO,EAAE,WAAW,GAAG,QAAQ,GAAG,OAAO,CAAA;IACzC,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAiH/F;AA8ED;;;;GAIG;AACH,wBAAsB,IAAI,IAAI,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAS5D"}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import { Cron } from 'croner';
|
|
2
|
+
import { getSupabase } from './supabase.js';
|
|
3
|
+
import { runClaude } from './claude-runner.js';
|
|
4
|
+
import { sendSystemMail } from './email-sender.js';
|
|
5
|
+
import { config } from './config.js';
|
|
6
|
+
/**
|
|
7
|
+
* Compute the next firing instant of `expr` strictly after `from`.
|
|
8
|
+
* Returns null if the expression is invalid.
|
|
9
|
+
*/
|
|
10
|
+
export function computeNextRun(expr, timezone, from = new Date()) {
|
|
11
|
+
try {
|
|
12
|
+
const c = new Cron(expr, { timezone });
|
|
13
|
+
const next = c.nextRun(from);
|
|
14
|
+
return next ?? null;
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Recompute and persist next_run_at for a task. Call this after INSERT/UPDATE
|
|
22
|
+
* and after a run finishes.
|
|
23
|
+
*/
|
|
24
|
+
export async function recalcNextRun(taskId) {
|
|
25
|
+
const db = getSupabase();
|
|
26
|
+
const { data: t, error } = await db
|
|
27
|
+
.from('scheduled_tasks')
|
|
28
|
+
.select('id, cron_expr, timezone, enabled')
|
|
29
|
+
.eq('id', taskId)
|
|
30
|
+
.single();
|
|
31
|
+
if (error || !t)
|
|
32
|
+
return null;
|
|
33
|
+
if (!t.enabled) {
|
|
34
|
+
await db.from('scheduled_tasks').update({ next_run_at: null }).eq('id', taskId);
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
const next = computeNextRun(t.cron_expr, t.timezone);
|
|
38
|
+
await db.from('scheduled_tasks').update({ next_run_at: next?.toISOString() ?? null }).eq('id', taskId);
|
|
39
|
+
return next;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Find tasks whose next_run_at has passed. Returns at most `limit` rows.
|
|
43
|
+
*/
|
|
44
|
+
export async function scanDueTasks(limit = 20) {
|
|
45
|
+
const db = getSupabase();
|
|
46
|
+
const nowIso = new Date().toISOString();
|
|
47
|
+
const { data, error } = await db
|
|
48
|
+
.from('scheduled_tasks')
|
|
49
|
+
.select('*')
|
|
50
|
+
.eq('enabled', true)
|
|
51
|
+
.lte('next_run_at', nowIso)
|
|
52
|
+
.order('next_run_at', { ascending: true })
|
|
53
|
+
.limit(limit);
|
|
54
|
+
if (error) {
|
|
55
|
+
console.error('[scheduler] scan error', error);
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
return (data || []);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Execute a task: creates a task_runs row, invokes runClaude with the task's
|
|
62
|
+
* prompt/skills, then writes back the result and recomputes next_run_at.
|
|
63
|
+
*
|
|
64
|
+
* Runs are non-blocking from the caller's perspective — the tick endpoint
|
|
65
|
+
* fires these and returns immediately while dispatch continues in the
|
|
66
|
+
* background. We guard against double-dispatch by claiming the row first
|
|
67
|
+
* (set last_run_at + clear next_run_at).
|
|
68
|
+
*/
|
|
69
|
+
export async function dispatchTask(task, opts) {
|
|
70
|
+
const db = getSupabase();
|
|
71
|
+
const startedAt = new Date();
|
|
72
|
+
// 1. Claim the row. For scheduled runs, use an optimistic lock on
|
|
73
|
+
// next_run_at to prevent races between overlapping ticks. For manual
|
|
74
|
+
// triggers the user explicitly wants it to run now, so we skip the
|
|
75
|
+
// lock — otherwise we'd also fail when next_run_at is null (e.g.,
|
|
76
|
+
// task created via direct DB insert without recalc).
|
|
77
|
+
let claimQuery = db
|
|
78
|
+
.from('scheduled_tasks')
|
|
79
|
+
.update({
|
|
80
|
+
next_run_at: null, // cleared; recomputed after run
|
|
81
|
+
last_run_at: startedAt.toISOString(),
|
|
82
|
+
last_run_status: 'running',
|
|
83
|
+
})
|
|
84
|
+
.eq('id', task.id);
|
|
85
|
+
if (opts.trigger === 'scheduled' && task.next_run_at) {
|
|
86
|
+
claimQuery = claimQuery.eq('next_run_at', task.next_run_at);
|
|
87
|
+
}
|
|
88
|
+
const { data: claimed, error: claimErr } = await claimQuery.select('id').single();
|
|
89
|
+
if (claimErr || !claimed) {
|
|
90
|
+
// Someone else claimed it (scheduled race), or it was edited mid-flight.
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
// 2. Insert run row
|
|
94
|
+
const { data: run, error: runErr } = await db
|
|
95
|
+
.from('task_runs')
|
|
96
|
+
.insert({
|
|
97
|
+
task_id: task.id,
|
|
98
|
+
company_id: task.company_id,
|
|
99
|
+
status: 'running',
|
|
100
|
+
trigger: opts.trigger,
|
|
101
|
+
triggered_by: opts.triggeredBy ?? 'cron',
|
|
102
|
+
started_at: startedAt.toISOString(),
|
|
103
|
+
})
|
|
104
|
+
.select('id')
|
|
105
|
+
.single();
|
|
106
|
+
if (runErr || !run) {
|
|
107
|
+
console.error('[scheduler] failed to insert task_run', runErr);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
// 3. Link run id to task
|
|
111
|
+
await db.from('scheduled_tasks').update({ last_run_id: run.id }).eq('id', task.id);
|
|
112
|
+
// 4. Invoke the agent
|
|
113
|
+
let status = 'success';
|
|
114
|
+
let response = null;
|
|
115
|
+
let errorText = null;
|
|
116
|
+
let costUsd;
|
|
117
|
+
let sessionId;
|
|
118
|
+
try {
|
|
119
|
+
const sessionKey = task.session_key || `cron-${task.name}-${Date.now()}`;
|
|
120
|
+
const result = await runClaude({
|
|
121
|
+
company_id: task.company_id,
|
|
122
|
+
user_id: task.user_id,
|
|
123
|
+
message: task.prompt,
|
|
124
|
+
channel: 'cron',
|
|
125
|
+
session_key: sessionKey,
|
|
126
|
+
enabled_skills: task.enabled_skills,
|
|
127
|
+
company_context: `[Cron task "${task.name}" firing via ${opts.trigger}]`,
|
|
128
|
+
selected_files: [],
|
|
129
|
+
});
|
|
130
|
+
response = result.response;
|
|
131
|
+
costUsd = result.cost_usd;
|
|
132
|
+
sessionId = result.session_id;
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
status = 'error';
|
|
136
|
+
errorText = err?.message || String(err);
|
|
137
|
+
console.error(`[scheduler] task ${task.name} failed:`, err);
|
|
138
|
+
}
|
|
139
|
+
const finishedAt = new Date();
|
|
140
|
+
const durationMs = finishedAt.getTime() - startedAt.getTime();
|
|
141
|
+
// 5. Write run result
|
|
142
|
+
await db
|
|
143
|
+
.from('task_runs')
|
|
144
|
+
.update({
|
|
145
|
+
status,
|
|
146
|
+
finished_at: finishedAt.toISOString(),
|
|
147
|
+
duration_ms: durationMs,
|
|
148
|
+
response,
|
|
149
|
+
error: errorText,
|
|
150
|
+
metadata: { cost_usd: costUsd, session_id: sessionId },
|
|
151
|
+
})
|
|
152
|
+
.eq('id', run.id);
|
|
153
|
+
// 6. Recompute next_run_at + update last_run_status on task
|
|
154
|
+
const next = computeNextRun(task.cron_expr, task.timezone);
|
|
155
|
+
await db
|
|
156
|
+
.from('scheduled_tasks')
|
|
157
|
+
.update({
|
|
158
|
+
next_run_at: next?.toISOString() ?? null,
|
|
159
|
+
last_run_status: status,
|
|
160
|
+
})
|
|
161
|
+
.eq('id', task.id);
|
|
162
|
+
// 7. Deliver via output channel (email) if configured
|
|
163
|
+
await maybeNotify(task, {
|
|
164
|
+
runId: run.id,
|
|
165
|
+
status,
|
|
166
|
+
response,
|
|
167
|
+
errorText,
|
|
168
|
+
previousStatus: task.last_run_status,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Decide whether + how to notify for a finished run and perform delivery.
|
|
173
|
+
* Writes back `notified_at` / `notify_error` on the task_runs row.
|
|
174
|
+
*/
|
|
175
|
+
async function maybeNotify(task, ctx) {
|
|
176
|
+
if (task.output_channel === 'silent')
|
|
177
|
+
return;
|
|
178
|
+
if (!task.output_recipient)
|
|
179
|
+
return;
|
|
180
|
+
// Apply notify_on filter
|
|
181
|
+
const shouldNotify = (() => {
|
|
182
|
+
switch (task.notify_on) {
|
|
183
|
+
case 'never': return false;
|
|
184
|
+
case 'always': return true;
|
|
185
|
+
case 'on_error': return ctx.status === 'error';
|
|
186
|
+
case 'on_change': return ctx.status !== ctx.previousStatus;
|
|
187
|
+
}
|
|
188
|
+
})();
|
|
189
|
+
if (!shouldNotify)
|
|
190
|
+
return;
|
|
191
|
+
// Build the message
|
|
192
|
+
const subject = ctx.status === 'error'
|
|
193
|
+
? `[${config.display_name}] Tarea "${task.name}" fallo`
|
|
194
|
+
: `[${config.display_name}] ${task.name}`;
|
|
195
|
+
const bodyLines = [];
|
|
196
|
+
bodyLines.push(`Tarea: ${task.name}`);
|
|
197
|
+
if (task.description)
|
|
198
|
+
bodyLines.push(`Descripcion: ${task.description}`);
|
|
199
|
+
bodyLines.push(`Estado: ${ctx.status}`);
|
|
200
|
+
bodyLines.push(`Cron: ${task.cron_expr}`);
|
|
201
|
+
bodyLines.push('');
|
|
202
|
+
if (ctx.status === 'error') {
|
|
203
|
+
bodyLines.push('Error:');
|
|
204
|
+
bodyLines.push(ctx.errorText ?? '(sin detalle)');
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
bodyLines.push('Resultado:');
|
|
208
|
+
bodyLines.push(ctx.response ?? '(sin respuesta)');
|
|
209
|
+
}
|
|
210
|
+
bodyLines.push('');
|
|
211
|
+
bodyLines.push('---');
|
|
212
|
+
bodyLines.push(`${config.display_name} · tarea programada`);
|
|
213
|
+
const body = bodyLines.join('\n');
|
|
214
|
+
if (task.output_channel === 'email') {
|
|
215
|
+
const result = await sendSystemMail({
|
|
216
|
+
companyId: task.company_id,
|
|
217
|
+
to: task.output_recipient,
|
|
218
|
+
subject,
|
|
219
|
+
body,
|
|
220
|
+
sourceTaskId: task.id,
|
|
221
|
+
sessionKey: task.session_key || undefined,
|
|
222
|
+
});
|
|
223
|
+
const db = getSupabase();
|
|
224
|
+
if (result.ok) {
|
|
225
|
+
await db
|
|
226
|
+
.from('task_runs')
|
|
227
|
+
.update({ notified_at: new Date().toISOString() })
|
|
228
|
+
.eq('id', ctx.runId);
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
await markNotifyError(ctx.runId, result.error || 'unknown send error');
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
async function markNotifyError(runId, msg) {
|
|
236
|
+
const db = getSupabase();
|
|
237
|
+
await db.from('task_runs').update({ notify_error: msg }).eq('id', runId);
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Scan + dispatch in background. Called by the pg_cron webhook.
|
|
241
|
+
* Returns immediately with the number of tasks claimed; actual execution
|
|
242
|
+
* runs async.
|
|
243
|
+
*/
|
|
244
|
+
export async function tick() {
|
|
245
|
+
const due = await scanDueTasks();
|
|
246
|
+
for (const task of due) {
|
|
247
|
+
// Fire and forget — each dispatch logs its own errors
|
|
248
|
+
dispatchTask(task, { trigger: 'scheduled', triggeredBy: 'cron' }).catch(err => console.error(`[scheduler] dispatch error for ${task.name}:`, err));
|
|
249
|
+
}
|
|
250
|
+
return { dispatched: due.length };
|
|
251
|
+
}
|
|
252
|
+
//# sourceMappingURL=scheduler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../core-gateway/scheduler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
export interface GatewayOptions {
|
|
3
|
+
/** Override the port (default: PORT env or 8090). */
|
|
4
|
+
port?: number;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Create and start the Proto gateway server.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* import { createProtoGateway } from '@tleblancureta/proto/gateway'
|
|
11
|
+
* await createProtoGateway()
|
|
12
|
+
*/
|
|
13
|
+
export declare function createProtoGateway(opts?: GatewayOptions): Promise<{
|
|
14
|
+
app: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
|
|
15
|
+
server: import("@hono/node-server").ServerType;
|
|
16
|
+
}>;
|
|
17
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../core-gateway/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAc3B,MAAM,WAAW,cAAc;IAC7B,qDAAqD;IACrD,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,CAAC,EAAE,cAAc;;;GA8B7D"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import { cors } from 'hono/cors';
|
|
3
|
+
import { createNodeWebSocket } from '@hono/node-ws';
|
|
4
|
+
import { serve } from '@hono/node-server';
|
|
5
|
+
import { verifySecret } from './auth.js';
|
|
6
|
+
import { config, PORT } from './config.js';
|
|
7
|
+
import { registerChatRoutes } from './routes/chat.js';
|
|
8
|
+
import { registerUploadRoutes } from './routes/upload.js';
|
|
9
|
+
import { registerGmailRoutes } from './routes/gmail.js';
|
|
10
|
+
import { registerHealthRoutes } from './routes/health.js';
|
|
11
|
+
import { registerCronRoutes } from './routes/cron.js';
|
|
12
|
+
import { registerAdminRoutes } from './routes/admin.js';
|
|
13
|
+
import { startMailIngester } from './mail-ingester.js';
|
|
14
|
+
/**
|
|
15
|
+
* Create and start the Proto gateway server.
|
|
16
|
+
*
|
|
17
|
+
* Usage:
|
|
18
|
+
* import { createProtoGateway } from '@tleblancureta/proto/gateway'
|
|
19
|
+
* await createProtoGateway()
|
|
20
|
+
*/
|
|
21
|
+
export async function createProtoGateway(opts) {
|
|
22
|
+
const port = opts?.port ?? PORT;
|
|
23
|
+
const app = new Hono();
|
|
24
|
+
const { injectWebSocket, upgradeWebSocket } = createNodeWebSocket({ app });
|
|
25
|
+
app.use('*', cors());
|
|
26
|
+
// Auth middleware for REST endpoints (WS uses its own auth handshake)
|
|
27
|
+
app.use('/chat', verifySecret);
|
|
28
|
+
app.use('/chat/*', verifySecret);
|
|
29
|
+
app.use('/upload/*', verifySecret);
|
|
30
|
+
// Mount routes
|
|
31
|
+
registerChatRoutes(app, upgradeWebSocket);
|
|
32
|
+
registerUploadRoutes(app);
|
|
33
|
+
registerGmailRoutes(app);
|
|
34
|
+
registerHealthRoutes(app);
|
|
35
|
+
registerCronRoutes(app);
|
|
36
|
+
registerAdminRoutes(app);
|
|
37
|
+
// Start
|
|
38
|
+
console.log(`${config.display_name} Gateway starting on port ${port}`);
|
|
39
|
+
const server = serve({ fetch: app.fetch, port });
|
|
40
|
+
injectWebSocket(server);
|
|
41
|
+
// Start the IMAP ingester (no-op if MAIL_IMAP_HOST not configured)
|
|
42
|
+
startMailIngester();
|
|
43
|
+
return { app, server };
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../core-gateway/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC3B,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AACnD,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACxC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AAOtD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAAqB;IAC5D,MAAM,IAAI,GAAG,IAAI,EAAE,IAAI,IAAI,IAAI,CAAA;IAE/B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAA;IACtB,MAAM,EAAE,eAAe,EAAE,gBAAgB,EAAE,GAAG,mBAAmB,CAAC,EAAE,GAAG,EAAE,CAAC,CAAA;IAE1E,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAA;IAEpB,sEAAsE;IACtE,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,YAAY,CAAC,CAAA;IAC9B,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,YAAY,CAAC,CAAA;IAChC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,YAAY,CAAC,CAAA;IAElC,eAAe;IACf,kBAAkB,CAAC,GAAG,EAAE,gBAAuB,CAAC,CAAA;IAChD,oBAAoB,CAAC,GAAG,CAAC,CAAA;IACzB,mBAAmB,CAAC,GAAG,CAAC,CAAA;IACxB,oBAAoB,CAAC,GAAG,CAAC,CAAA;IACzB,kBAAkB,CAAC,GAAG,CAAC,CAAA;IACvB,mBAAmB,CAAC,GAAG,CAAC,CAAA;IAExB,QAAQ;IACR,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,YAAY,6BAA6B,IAAI,EAAE,CAAC,CAAA;IACtE,MAAM,MAAM,GAAG,KAAK,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;IAChD,eAAe,CAAC,MAAM,CAAC,CAAA;IAEvB,mEAAmE;IACnE,iBAAiB,EAAE,CAAA;IAEnB,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,CAAA;AACxB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ChatRequest } from '@tleblancureta/proto/shared';
|
|
2
|
+
interface SessionResult {
|
|
3
|
+
sessionId: string;
|
|
4
|
+
sessionDir: string;
|
|
5
|
+
env: Record<string, string>;
|
|
6
|
+
promptFile: string;
|
|
7
|
+
mcpConfigFile: string;
|
|
8
|
+
claudeConfigDir: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function prepareSession(request: ChatRequest): Promise<SessionResult>;
|
|
11
|
+
/**
|
|
12
|
+
* Copy refreshed credentials from session config back to global config.
|
|
13
|
+
* Claude Code may refresh the OAuth token during a session — sync it back
|
|
14
|
+
* so future sessions use the fresh token.
|
|
15
|
+
*/
|
|
16
|
+
export declare function syncCredentialsBack(claudeConfigDir: string): void;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../core-gateway/session.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAA;AAc9D,UAAU,aAAa;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC3B,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,MAAM,CAAA;CACxB;AAED,wBAAsB,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CAmDjF;AAgHD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAajE"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { mkdirSync, writeFileSync, existsSync, readdirSync, copyFileSync, statSync, rmSync } from 'node:fs';
|
|
2
|
+
import { resolve, join } from 'node:path';
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
4
|
+
import { config } from './config.js';
|
|
5
|
+
import { buildSystemPrompt } from './skills.js';
|
|
6
|
+
import { loadSkills, loadAgents } from './registry.js';
|
|
7
|
+
/**
|
|
8
|
+
* Deterministic session ID from project name + company_id + optional session_key.
|
|
9
|
+
* Uses a simple hash to create a stable identifier (UUID v5 equivalent).
|
|
10
|
+
*/
|
|
11
|
+
function getSessionId(companyId, sessionKey) {
|
|
12
|
+
const seed = `${config.name}-${companyId}${sessionKey ? `-${sessionKey}` : ''}`;
|
|
13
|
+
return createHash('sha256').update(seed).digest('hex').slice(0, 32);
|
|
14
|
+
}
|
|
15
|
+
export async function prepareSession(request) {
|
|
16
|
+
const sessionId = getSessionId(request.company_id, request.session_key);
|
|
17
|
+
const dataRoot = process.env.DATA_DIR || '/data';
|
|
18
|
+
const sessionSlug = request.session_key
|
|
19
|
+
? `${request.company_id}/${request.session_key}`
|
|
20
|
+
: request.company_id;
|
|
21
|
+
const sessionDir = resolve(dataRoot, 'sessions', sessionSlug);
|
|
22
|
+
mkdirSync(sessionDir, { recursive: true });
|
|
23
|
+
// Claude config dir: use per-session dir in Docker, default (~/.claude) in local dev
|
|
24
|
+
const claudeConfigDir = process.env.CLAUDE_CONFIG_DIR
|
|
25
|
+
? resolve(dataRoot, 'claude-config', sessionSlug)
|
|
26
|
+
: join(process.env.HOME || '', '.claude');
|
|
27
|
+
if (process.env.CLAUDE_CONFIG_DIR) {
|
|
28
|
+
mkdirSync(claudeConfigDir, { recursive: true });
|
|
29
|
+
copyCredentials(claudeConfigDir);
|
|
30
|
+
}
|
|
31
|
+
// Load skills + agents from filesystem
|
|
32
|
+
const skills = loadSkills();
|
|
33
|
+
const agents = loadAgents();
|
|
34
|
+
// Write system prompt (uses skill metadata for tool restrictions)
|
|
35
|
+
const systemPrompt = buildSystemPrompt(request, skills);
|
|
36
|
+
const promptFile = join(sessionDir, 'system-prompt.md');
|
|
37
|
+
writeFileSync(promptFile, systemPrompt);
|
|
38
|
+
// Copy enabled skills + all agents into session dir
|
|
39
|
+
writeSkills(sessionDir, request, skills);
|
|
40
|
+
writeAgents(sessionDir, agents);
|
|
41
|
+
// Write MCP config (without secrets — secrets passed via env inheritance)
|
|
42
|
+
const mcpConfigFile = writeMcpConfig(sessionDir, request);
|
|
43
|
+
// Build environment for claude subprocess
|
|
44
|
+
const env = {
|
|
45
|
+
...process.env,
|
|
46
|
+
COMPANY_ID: request.company_id,
|
|
47
|
+
USER_ID: request.user_id,
|
|
48
|
+
CHANNEL: request.channel,
|
|
49
|
+
};
|
|
50
|
+
// Only override CLAUDE_CONFIG_DIR in Docker (where we isolate per session)
|
|
51
|
+
if (process.env.CLAUDE_CONFIG_DIR) {
|
|
52
|
+
env.CLAUDE_CONFIG_DIR = claudeConfigDir;
|
|
53
|
+
}
|
|
54
|
+
return { sessionId, sessionDir, env, promptFile, mcpConfigFile, claudeConfigDir };
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Copy enabled skills from repo into session dir.
|
|
58
|
+
* Channel exclusions and per-request enabled_skills are applied here.
|
|
59
|
+
*/
|
|
60
|
+
function writeSkills(sessionDir, request, skills) {
|
|
61
|
+
const enabledSet = new Set(request.enabled_skills);
|
|
62
|
+
const channelExcluded = config.channel_excluded_skills[request.channel] || new Set();
|
|
63
|
+
for (const s of channelExcluded)
|
|
64
|
+
enabledSet.delete(s);
|
|
65
|
+
const skillsDir = join(sessionDir, '.claude', 'skills');
|
|
66
|
+
mkdirSync(skillsDir, { recursive: true });
|
|
67
|
+
for (const entry of readdirSync(skillsDir)) {
|
|
68
|
+
try {
|
|
69
|
+
rmSync(join(skillsDir, entry), { recursive: true, force: true });
|
|
70
|
+
}
|
|
71
|
+
catch { }
|
|
72
|
+
}
|
|
73
|
+
for (const skill of skills) {
|
|
74
|
+
if (!enabledSet.has(skill.name))
|
|
75
|
+
continue;
|
|
76
|
+
const dir = join(skillsDir, skill.name);
|
|
77
|
+
mkdirSync(dir, { recursive: true });
|
|
78
|
+
copyFileSync(skill.filePath, join(dir, 'SKILL.md'));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Copy all agents from repo into session dir.
|
|
83
|
+
*/
|
|
84
|
+
function writeAgents(sessionDir, agents) {
|
|
85
|
+
const agentsDir = join(sessionDir, '.claude', 'agents');
|
|
86
|
+
mkdirSync(agentsDir, { recursive: true });
|
|
87
|
+
for (const entry of readdirSync(agentsDir)) {
|
|
88
|
+
try {
|
|
89
|
+
rmSync(join(agentsDir, entry), { force: true });
|
|
90
|
+
}
|
|
91
|
+
catch { }
|
|
92
|
+
}
|
|
93
|
+
for (const agent of agents) {
|
|
94
|
+
copyFileSync(agent.filePath, join(agentsDir, `${agent.name}.md`));
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
function writeMcpConfig(sessionDir, request) {
|
|
98
|
+
const mcpServers = {};
|
|
99
|
+
for (const [name, serverConfig] of Object.entries(config.mcp_servers)) {
|
|
100
|
+
if (serverConfig.type === 'http') {
|
|
101
|
+
// HTTP MCP server — just pass the URL
|
|
102
|
+
mcpServers[name] = { type: 'http', url: serverConfig.url };
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
// Stdio MCP server — resolve args and env
|
|
106
|
+
const resolvedArgs = serverConfig.args.map(arg => arg.startsWith('$') ? (process.env[arg.slice(1)] || '') : arg);
|
|
107
|
+
const resolvedEnv = {};
|
|
108
|
+
for (const [mcpVar, source] of Object.entries(serverConfig.env)) {
|
|
109
|
+
if (source === '__COMPANY_ID__') {
|
|
110
|
+
resolvedEnv[mcpVar] = request.company_id;
|
|
111
|
+
}
|
|
112
|
+
else if (source === '__ALLOWED_TOOLS__') {
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
resolvedEnv[mcpVar] = process.env[source] || '';
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
resolvedEnv.USER_ID = request.user_id;
|
|
120
|
+
resolvedEnv.COMPANY_ID = request.company_id;
|
|
121
|
+
if (request.session_key?.startsWith('order-')) {
|
|
122
|
+
resolvedEnv.ACTIVE_ORDER_ID = request.session_key.slice('order-'.length);
|
|
123
|
+
}
|
|
124
|
+
if (process.env.SUPABASE_URL)
|
|
125
|
+
resolvedEnv.SUPABASE_URL = process.env.SUPABASE_URL;
|
|
126
|
+
if (process.env.SUPABASE_SERVICE_ROLE_KEY)
|
|
127
|
+
resolvedEnv.SUPABASE_SERVICE_ROLE_KEY = process.env.SUPABASE_SERVICE_ROLE_KEY;
|
|
128
|
+
mcpServers[name] = {
|
|
129
|
+
command: serverConfig.command,
|
|
130
|
+
...(resolvedArgs.length > 0 && { args: resolvedArgs }),
|
|
131
|
+
env: resolvedEnv,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
const mcpConfig = { mcpServers };
|
|
135
|
+
const configFile = join(sessionDir, 'mcp-config.json');
|
|
136
|
+
writeFileSync(configFile, JSON.stringify(mcpConfig));
|
|
137
|
+
return configFile;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Copy Claude OAuth credentials from the global config to a session-specific config dir.
|
|
141
|
+
* This allows each session to have its own CLAUDE_CONFIG_DIR while sharing the same auth.
|
|
142
|
+
*/
|
|
143
|
+
function copyCredentials(claudeConfigDir) {
|
|
144
|
+
const credsFile = join(claudeConfigDir, '.credentials.json');
|
|
145
|
+
const candidates = [
|
|
146
|
+
join(process.env.HOME || '', '.claude', '.credentials.json'),
|
|
147
|
+
join(process.env.CLAUDE_CONFIG_DIR || '/data/claude', '.credentials.json'),
|
|
148
|
+
'/data/claude-host/.credentials.json',
|
|
149
|
+
];
|
|
150
|
+
for (const candidate of candidates) {
|
|
151
|
+
if (existsSync(candidate)) {
|
|
152
|
+
copyFileSync(candidate, credsFile);
|
|
153
|
+
console.log(`[credentials] Copied from ${candidate}`);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
console.warn('[credentials] No credentials found. Run: claude login');
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Copy refreshed credentials from session config back to global config.
|
|
161
|
+
* Claude Code may refresh the OAuth token during a session — sync it back
|
|
162
|
+
* so future sessions use the fresh token.
|
|
163
|
+
*/
|
|
164
|
+
export function syncCredentialsBack(claudeConfigDir) {
|
|
165
|
+
const sessionCreds = join(claudeConfigDir, '.credentials.json');
|
|
166
|
+
if (!existsSync(sessionCreds))
|
|
167
|
+
return;
|
|
168
|
+
const globalDir = process.env.CLAUDE_CONFIG_DIR || '/data/claude';
|
|
169
|
+
const globalCreds = join(globalDir, '.credentials.json');
|
|
170
|
+
try {
|
|
171
|
+
if (!existsSync(globalCreds) || statSync(sessionCreds).mtimeMs > statSync(globalCreds).mtimeMs) {
|
|
172
|
+
mkdirSync(globalDir, { recursive: true });
|
|
173
|
+
copyFileSync(sessionCreds, globalCreds);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
catch { }
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../core-gateway/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../core-gateway/skills.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAA;AAE9D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AA0B1C,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,WAAW,EAAE,SAAS,GAAE,KAAK,EAAO,GAAG,MAAM,CAsFvF"}
|