247-cli 2.21.0 → 2.23.2
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/agent/dist/config.d.ts +4 -7
- package/agent/dist/config.d.ts.map +1 -1
- package/agent/dist/config.js +1 -2
- package/agent/dist/config.js.map +1 -1
- package/agent/dist/db/index.d.ts +0 -6
- package/agent/dist/db/index.d.ts.map +1 -1
- package/agent/dist/db/index.js +142 -88
- package/agent/dist/db/index.js.map +1 -1
- package/agent/dist/db/schema.d.ts +3 -32
- package/agent/dist/db/schema.d.ts.map +1 -1
- package/agent/dist/db/schema.js +1 -38
- package/agent/dist/db/schema.js.map +1 -1
- package/agent/dist/db/sessions.d.ts +0 -20
- package/agent/dist/db/sessions.d.ts.map +1 -1
- package/agent/dist/db/sessions.js +0 -86
- package/agent/dist/db/sessions.js.map +1 -1
- package/agent/dist/index.js +1 -0
- package/agent/dist/index.js.map +1 -1
- package/agent/dist/logger.d.ts +0 -2
- package/agent/dist/logger.d.ts.map +1 -1
- package/agent/dist/logger.js +0 -4
- package/agent/dist/logger.js.map +1 -1
- package/agent/dist/routes/attention.d.ts +10 -0
- package/agent/dist/routes/attention.d.ts.map +1 -0
- package/agent/dist/routes/attention.js +123 -0
- package/agent/dist/routes/attention.js.map +1 -0
- package/agent/dist/routes/index.d.ts +3 -7
- package/agent/dist/routes/index.d.ts.map +1 -1
- package/agent/dist/routes/index.js +3 -7
- package/agent/dist/routes/index.js.map +1 -1
- package/agent/dist/routes/pair.d.ts +26 -0
- package/agent/dist/routes/pair.d.ts.map +1 -0
- package/agent/dist/routes/pair.js +381 -0
- package/agent/dist/routes/pair.js.map +1 -0
- package/agent/dist/routes/projects.d.ts +2 -1
- package/agent/dist/routes/projects.d.ts.map +1 -1
- package/agent/dist/routes/projects.js +7 -39
- package/agent/dist/routes/projects.js.map +1 -1
- package/agent/dist/routes/sessions.d.ts.map +1 -1
- package/agent/dist/routes/sessions.js +38 -97
- package/agent/dist/routes/sessions.js.map +1 -1
- package/agent/dist/server.d.ts.map +1 -1
- package/agent/dist/server.js +11 -81
- package/agent/dist/server.js.map +1 -1
- package/agent/dist/setup-hooks.d.ts +10 -0
- package/agent/dist/setup-hooks.d.ts.map +1 -0
- package/agent/dist/setup-hooks.js +157 -0
- package/agent/dist/setup-hooks.js.map +1 -0
- package/agent/dist/status.d.ts.map +1 -1
- package/agent/dist/status.js +0 -8
- package/agent/dist/status.js.map +1 -1
- package/agent/dist/websocket-handlers.d.ts.map +1 -1
- package/agent/dist/websocket-handlers.js +2 -139
- package/agent/dist/websocket-handlers.js.map +1 -1
- package/agent/node_modules/247-shared/dist/types/index.d.ts +0 -54
- package/agent/node_modules/247-shared/dist/types/index.d.ts.map +1 -1
- package/agent/node_modules/247-shared/dist/types/index.js +0 -16
- package/agent/node_modules/247-shared/dist/types/index.js.map +1 -1
- package/agent/node_modules/247-shared/package.json +1 -1
- package/dist/index.js +1 -1
- package/package.json +3 -3
- package/agent/dist/db/environments.d.ts +0 -60
- package/agent/dist/db/environments.d.ts.map +0 -1
- package/agent/dist/db/environments.js +0 -235
- package/agent/dist/db/environments.js.map +0 -1
- package/agent/dist/db/push-subscriptions.d.ts +0 -44
- package/agent/dist/db/push-subscriptions.d.ts.map +0 -1
- package/agent/dist/db/push-subscriptions.js +0 -98
- package/agent/dist/db/push-subscriptions.js.map +0 -1
- package/agent/dist/editor.d.ts +0 -18
- package/agent/dist/editor.d.ts.map +0 -1
- package/agent/dist/editor.js +0 -222
- package/agent/dist/editor.js.map +0 -1
- package/agent/dist/environments.d.ts +0 -59
- package/agent/dist/environments.d.ts.map +0 -1
- package/agent/dist/environments.js +0 -229
- package/agent/dist/environments.js.map +0 -1
- package/agent/dist/git.d.ts +0 -39
- package/agent/dist/git.d.ts.map +0 -1
- package/agent/dist/git.js +0 -436
- package/agent/dist/git.js.map +0 -1
- package/agent/dist/heartbeat-monitor.d.ts +0 -24
- package/agent/dist/heartbeat-monitor.d.ts.map +0 -1
- package/agent/dist/heartbeat-monitor.js +0 -105
- package/agent/dist/heartbeat-monitor.js.map +0 -1
- package/agent/dist/push/sender.d.ts +0 -26
- package/agent/dist/push/sender.d.ts.map +0 -1
- package/agent/dist/push/sender.js +0 -122
- package/agent/dist/push/sender.js.map +0 -1
- package/agent/dist/push/vapid.d.ts +0 -25
- package/agent/dist/push/vapid.d.ts.map +0 -1
- package/agent/dist/push/vapid.js +0 -81
- package/agent/dist/push/vapid.js.map +0 -1
- package/agent/dist/routes/editor.d.ts +0 -9
- package/agent/dist/routes/editor.d.ts.map +0 -1
- package/agent/dist/routes/editor.js +0 -63
- package/agent/dist/routes/editor.js.map +0 -1
- package/agent/dist/routes/environments.d.ts +0 -6
- package/agent/dist/routes/environments.d.ts.map +0 -1
- package/agent/dist/routes/environments.js +0 -94
- package/agent/dist/routes/environments.js.map +0 -1
- package/agent/dist/routes/files.d.ts +0 -6
- package/agent/dist/routes/files.d.ts.map +0 -1
- package/agent/dist/routes/files.js +0 -84
- package/agent/dist/routes/files.js.map +0 -1
- package/agent/dist/routes/heartbeat.d.ts +0 -10
- package/agent/dist/routes/heartbeat.d.ts.map +0 -1
- package/agent/dist/routes/heartbeat.js +0 -124
- package/agent/dist/routes/heartbeat.js.map +0 -1
- package/agent/dist/routes/notification.d.ts +0 -9
- package/agent/dist/routes/notification.d.ts.map +0 -1
- package/agent/dist/routes/notification.js +0 -172
- package/agent/dist/routes/notification.js.map +0 -1
- package/agent/dist/routes/push.d.ts +0 -7
- package/agent/dist/routes/push.d.ts.map +0 -1
- package/agent/dist/routes/push.js +0 -98
- package/agent/dist/routes/push.js.map +0 -1
- package/agent/dist/routes/stop.d.ts +0 -9
- package/agent/dist/routes/stop.d.ts.map +0 -1
- package/agent/dist/routes/stop.js +0 -121
- package/agent/dist/routes/stop.js.map +0 -1
- package/agent/dist/setup-statusline.d.ts +0 -10
- package/agent/dist/setup-statusline.d.ts.map +0 -1
- package/agent/dist/setup-statusline.js +0 -234
- package/agent/dist/setup-statusline.js.map +0 -1
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Push notification sender.
|
|
3
|
-
* Sends Web Push notifications to all subscribed clients.
|
|
4
|
-
*/
|
|
5
|
-
import webpush from 'web-push';
|
|
6
|
-
import * as pushDb from '../db/push-subscriptions.js';
|
|
7
|
-
/**
|
|
8
|
-
* Get notification message based on attention reason.
|
|
9
|
-
*/
|
|
10
|
-
function getNotificationMessage(reason) {
|
|
11
|
-
switch (reason) {
|
|
12
|
-
case 'permission':
|
|
13
|
-
return {
|
|
14
|
-
title: 'Action requise',
|
|
15
|
-
body: 'Claude a besoin de votre autorisation pour continuer.',
|
|
16
|
-
};
|
|
17
|
-
case 'input':
|
|
18
|
-
return {
|
|
19
|
-
title: 'Réponse attendue',
|
|
20
|
-
body: 'Claude attend votre réponse pour continuer.',
|
|
21
|
-
};
|
|
22
|
-
case 'plan_approval':
|
|
23
|
-
return {
|
|
24
|
-
title: 'Plan à valider',
|
|
25
|
-
body: 'Claude a terminé son plan et attend votre validation.',
|
|
26
|
-
};
|
|
27
|
-
case 'task_complete':
|
|
28
|
-
return {
|
|
29
|
-
title: 'Tâche terminée',
|
|
30
|
-
body: 'Claude a terminé sa tâche.',
|
|
31
|
-
};
|
|
32
|
-
default:
|
|
33
|
-
return {
|
|
34
|
-
title: 'Attention requise',
|
|
35
|
-
body: 'Une session nécessite votre attention.',
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Send push notification for a session status update.
|
|
41
|
-
* Only sends if status is 'needs_attention'.
|
|
42
|
-
*/
|
|
43
|
-
export async function sendPushNotification(session) {
|
|
44
|
-
// Only send for needs_attention status
|
|
45
|
-
if (session.status !== 'needs_attention') {
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
const subscriptions = pushDb.getAllSubscriptions();
|
|
49
|
-
if (subscriptions.length === 0) {
|
|
50
|
-
console.log('[Push] No subscriptions, skipping push notification');
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
const { title, body } = getNotificationMessage(session.attentionReason || 'input');
|
|
54
|
-
const payload = {
|
|
55
|
-
title: `${title} - ${session.name}`,
|
|
56
|
-
body,
|
|
57
|
-
tag: `session-${session.name}`,
|
|
58
|
-
url: `/?session=${encodeURIComponent(session.name)}`,
|
|
59
|
-
timestamp: Date.now(),
|
|
60
|
-
};
|
|
61
|
-
const payloadStr = JSON.stringify(payload);
|
|
62
|
-
const invalidEndpoints = [];
|
|
63
|
-
console.log(`[Push] Sending notification to ${subscriptions.length} subscriber(s)`);
|
|
64
|
-
// Send to all subscriptions in parallel
|
|
65
|
-
const results = await Promise.allSettled(subscriptions.map(async (dbSub) => {
|
|
66
|
-
const subscription = pushDb.toWebPushSubscription(dbSub);
|
|
67
|
-
try {
|
|
68
|
-
await webpush.sendNotification(subscription, payloadStr);
|
|
69
|
-
return { success: true, endpoint: dbSub.endpoint };
|
|
70
|
-
}
|
|
71
|
-
catch (err) {
|
|
72
|
-
const error = err;
|
|
73
|
-
// 404 or 410 means subscription is no longer valid
|
|
74
|
-
if (error.statusCode === 404 || error.statusCode === 410) {
|
|
75
|
-
invalidEndpoints.push(dbSub.endpoint);
|
|
76
|
-
console.log(`[Push] Subscription expired: ${dbSub.endpoint.substring(0, 50)}...`);
|
|
77
|
-
}
|
|
78
|
-
else {
|
|
79
|
-
console.error(`[Push] Failed to send:`, error);
|
|
80
|
-
}
|
|
81
|
-
return { success: false, endpoint: dbSub.endpoint };
|
|
82
|
-
}
|
|
83
|
-
}));
|
|
84
|
-
// Clean up invalid subscriptions
|
|
85
|
-
if (invalidEndpoints.length > 0) {
|
|
86
|
-
const deleted = pushDb.deleteInvalidSubscriptions(invalidEndpoints);
|
|
87
|
-
console.log(`[Push] Cleaned up ${deleted} invalid subscription(s)`);
|
|
88
|
-
}
|
|
89
|
-
const successful = results.filter((r) => r.status === 'fulfilled' && r.value.success).length;
|
|
90
|
-
console.log(`[Push] Sent ${successful}/${subscriptions.length} notification(s)`);
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Send a test push notification.
|
|
94
|
-
* Useful for verifying setup.
|
|
95
|
-
*/
|
|
96
|
-
export async function sendTestNotification() {
|
|
97
|
-
const subscriptions = pushDb.getAllSubscriptions();
|
|
98
|
-
if (subscriptions.length === 0) {
|
|
99
|
-
return { sent: 0, failed: 0 };
|
|
100
|
-
}
|
|
101
|
-
const payload = {
|
|
102
|
-
title: 'Test Notification',
|
|
103
|
-
body: 'Les notifications push fonctionnent !',
|
|
104
|
-
tag: 'test',
|
|
105
|
-
url: '/',
|
|
106
|
-
timestamp: Date.now(),
|
|
107
|
-
};
|
|
108
|
-
const payloadStr = JSON.stringify(payload);
|
|
109
|
-
let sent = 0;
|
|
110
|
-
let failed = 0;
|
|
111
|
-
for (const dbSub of subscriptions) {
|
|
112
|
-
try {
|
|
113
|
-
await webpush.sendNotification(pushDb.toWebPushSubscription(dbSub), payloadStr);
|
|
114
|
-
sent++;
|
|
115
|
-
}
|
|
116
|
-
catch {
|
|
117
|
-
failed++;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
return { sent, failed };
|
|
121
|
-
}
|
|
122
|
-
//# sourceMappingURL=sender.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sender.js","sourceRoot":"","sources":["../../src/push/sender.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* VAPID key management for Web Push notifications.
|
|
3
|
-
* Keys are generated once and stored in ~/.247/vapid.json
|
|
4
|
-
*/
|
|
5
|
-
interface VapidKeys {
|
|
6
|
-
publicKey: string;
|
|
7
|
-
privateKey: string;
|
|
8
|
-
subject: string;
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Get or generate VAPID keys.
|
|
12
|
-
* Keys are cached in memory and persisted to disk.
|
|
13
|
-
*/
|
|
14
|
-
export declare function getVapidKeys(): VapidKeys;
|
|
15
|
-
/**
|
|
16
|
-
* Get the public VAPID key (for client subscription).
|
|
17
|
-
*/
|
|
18
|
-
export declare function getPublicVapidKey(): string;
|
|
19
|
-
/**
|
|
20
|
-
* Initialize web-push with VAPID keys.
|
|
21
|
-
* Call this at server startup.
|
|
22
|
-
*/
|
|
23
|
-
export declare function initWebPush(): void;
|
|
24
|
-
export {};
|
|
25
|
-
//# sourceMappingURL=vapid.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"vapid.d.ts","sourceRoot":"","sources":["../../src/push/vapid.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,UAAU,SAAS;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAOD;;;GAGG;AACH,wBAAgB,YAAY,IAAI,SAAS,CAgDxC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED;;;GAGG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAUlC"}
|
package/agent/dist/push/vapid.js
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* VAPID key management for Web Push notifications.
|
|
3
|
-
* Keys are generated once and stored in ~/.247/vapid.json
|
|
4
|
-
*/
|
|
5
|
-
import webpush from 'web-push';
|
|
6
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
7
|
-
import { resolve, dirname } from 'path';
|
|
8
|
-
const CONFIG_DIR = resolve(process.env.HOME || '~', '.247');
|
|
9
|
-
const VAPID_FILE = resolve(CONFIG_DIR, 'vapid.json');
|
|
10
|
-
let cachedKeys = null;
|
|
11
|
-
/**
|
|
12
|
-
* Get or generate VAPID keys.
|
|
13
|
-
* Keys are cached in memory and persisted to disk.
|
|
14
|
-
*/
|
|
15
|
-
export function getVapidKeys() {
|
|
16
|
-
if (cachedKeys) {
|
|
17
|
-
return cachedKeys;
|
|
18
|
-
}
|
|
19
|
-
// Try to load from file
|
|
20
|
-
if (existsSync(VAPID_FILE)) {
|
|
21
|
-
try {
|
|
22
|
-
const content = readFileSync(VAPID_FILE, 'utf-8');
|
|
23
|
-
const loaded = JSON.parse(content);
|
|
24
|
-
// Validate that all required fields exist
|
|
25
|
-
if (loaded.publicKey && loaded.privateKey && loaded.subject) {
|
|
26
|
-
cachedKeys = loaded;
|
|
27
|
-
console.log('[VAPID] Loaded keys from file');
|
|
28
|
-
return cachedKeys;
|
|
29
|
-
}
|
|
30
|
-
// Keys incomplete, will regenerate
|
|
31
|
-
console.log('[VAPID] Loaded keys are incomplete, regenerating...');
|
|
32
|
-
}
|
|
33
|
-
catch (err) {
|
|
34
|
-
console.error('[VAPID] Failed to load keys, regenerating:', err);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
// Generate new keys
|
|
38
|
-
console.log('[VAPID] Generating new keys...');
|
|
39
|
-
const keys = webpush.generateVAPIDKeys();
|
|
40
|
-
cachedKeys = {
|
|
41
|
-
publicKey: keys.publicKey,
|
|
42
|
-
privateKey: keys.privateKey,
|
|
43
|
-
subject: 'mailto:247@quivr.com', // Required for VAPID
|
|
44
|
-
};
|
|
45
|
-
// Persist to file
|
|
46
|
-
try {
|
|
47
|
-
const dir = dirname(VAPID_FILE);
|
|
48
|
-
if (!existsSync(dir)) {
|
|
49
|
-
mkdirSync(dir, { recursive: true });
|
|
50
|
-
}
|
|
51
|
-
writeFileSync(VAPID_FILE, JSON.stringify(cachedKeys, null, 2));
|
|
52
|
-
console.log('[VAPID] Keys saved to:', VAPID_FILE);
|
|
53
|
-
}
|
|
54
|
-
catch (err) {
|
|
55
|
-
console.error('[VAPID] Failed to save keys:', err);
|
|
56
|
-
}
|
|
57
|
-
return cachedKeys;
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Get the public VAPID key (for client subscription).
|
|
61
|
-
*/
|
|
62
|
-
export function getPublicVapidKey() {
|
|
63
|
-
return getVapidKeys().publicKey;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Initialize web-push with VAPID keys.
|
|
67
|
-
* Call this at server startup.
|
|
68
|
-
*/
|
|
69
|
-
export function initWebPush() {
|
|
70
|
-
try {
|
|
71
|
-
const keys = getVapidKeys();
|
|
72
|
-
webpush.setVapidDetails(keys.subject, keys.publicKey, keys.privateKey);
|
|
73
|
-
console.log('[VAPID] web-push initialized');
|
|
74
|
-
}
|
|
75
|
-
catch (err) {
|
|
76
|
-
// In test environments, we may not have proper config directory access
|
|
77
|
-
console.warn('[VAPID] Failed to initialize web-push:', err.message);
|
|
78
|
-
console.warn('[VAPID] Push notifications will be disabled');
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
//# sourceMappingURL=vapid.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"vapid.js","sourceRoot":"","sources":["../../src/push/vapid.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Editor API routes: start/stop code-server, status checks.
|
|
3
|
-
*/
|
|
4
|
-
import { Router } from 'express';
|
|
5
|
-
import { getOrStartEditor, updateEditorActivity } from '../editor.js';
|
|
6
|
-
export declare function isProjectAllowed(project: string): boolean;
|
|
7
|
-
export declare function createEditorRoutes(): Router;
|
|
8
|
-
export { updateEditorActivity, getOrStartEditor };
|
|
9
|
-
//# sourceMappingURL=editor.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../src/routes/editor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAGjC,OAAO,EACL,gBAAgB,EAIhB,oBAAoB,EACrB,MAAM,cAAc,CAAC;AAGtB,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAIzD;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CA0D3C;AAGD,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,CAAC"}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Editor API routes: start/stop code-server, status checks.
|
|
3
|
-
*/
|
|
4
|
-
import { Router } from 'express';
|
|
5
|
-
import { config } from '../config.js';
|
|
6
|
-
import { getOrStartEditor, stopEditor, getEditorStatus, getAllEditors, updateEditorActivity, } from '../editor.js';
|
|
7
|
-
// Helper to check if project is allowed (whitelist empty = allow any)
|
|
8
|
-
export function isProjectAllowed(project) {
|
|
9
|
-
const whitelist = config.projects.whitelist;
|
|
10
|
-
const hasWhitelist = whitelist && whitelist.length > 0;
|
|
11
|
-
return hasWhitelist ? whitelist.includes(project) : true;
|
|
12
|
-
}
|
|
13
|
-
export function createEditorRoutes() {
|
|
14
|
-
const router = Router();
|
|
15
|
-
const typedConfig = config;
|
|
16
|
-
// Get editor status for a project
|
|
17
|
-
router.get('/:project/status', (req, res) => {
|
|
18
|
-
const { project } = req.params;
|
|
19
|
-
if (!isProjectAllowed(project)) {
|
|
20
|
-
return res.status(403).json({ error: 'Project not allowed' });
|
|
21
|
-
}
|
|
22
|
-
res.json(getEditorStatus(project));
|
|
23
|
-
});
|
|
24
|
-
// Start editor for a project
|
|
25
|
-
router.post('/:project/start', async (req, res) => {
|
|
26
|
-
const { project } = req.params;
|
|
27
|
-
if (!isProjectAllowed(project)) {
|
|
28
|
-
return res.status(403).json({ error: 'Project not allowed' });
|
|
29
|
-
}
|
|
30
|
-
if (!typedConfig.editor?.enabled) {
|
|
31
|
-
return res.status(400).json({ error: 'Editor is disabled in config' });
|
|
32
|
-
}
|
|
33
|
-
try {
|
|
34
|
-
const editor = await getOrStartEditor(project);
|
|
35
|
-
res.json({
|
|
36
|
-
success: true,
|
|
37
|
-
port: editor.port,
|
|
38
|
-
startedAt: editor.startedAt,
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
catch (err) {
|
|
42
|
-
console.error('[Editor] Failed to start:', err);
|
|
43
|
-
res.status(500).json({ error: 'Failed to start editor', message: err.message });
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
|
-
// Stop editor for a project
|
|
47
|
-
router.post('/:project/stop', (req, res) => {
|
|
48
|
-
const { project } = req.params;
|
|
49
|
-
if (!isProjectAllowed(project)) {
|
|
50
|
-
return res.status(403).json({ error: 'Project not allowed' });
|
|
51
|
-
}
|
|
52
|
-
const stopped = stopEditor(project);
|
|
53
|
-
res.json({ success: stopped });
|
|
54
|
-
});
|
|
55
|
-
// List all running editors
|
|
56
|
-
router.get('/', (_req, res) => {
|
|
57
|
-
res.json(getAllEditors());
|
|
58
|
-
});
|
|
59
|
-
return router;
|
|
60
|
-
}
|
|
61
|
-
// Export helper for proxy middleware
|
|
62
|
-
export { updateEditorActivity, getOrStartEditor };
|
|
63
|
-
//# sourceMappingURL=editor.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"editor.js","sourceRoot":"","sources":["../../src/routes/editor.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"environments.d.ts","sourceRoot":"","sources":["../../src/routes/environments.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAUjC,wBAAgB,uBAAuB,IAAI,MAAM,CAiGhD"}
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Environment API routes: CRUD operations for environment configurations.
|
|
3
|
-
*/
|
|
4
|
-
import { Router } from 'express';
|
|
5
|
-
import { getEnvironmentsMetadata, getEnvironmentMetadata, getEnvironment, createEnvironment, updateEnvironment, deleteEnvironment, } from '../db/environments.js';
|
|
6
|
-
export function createEnvironmentRoutes() {
|
|
7
|
-
const router = Router();
|
|
8
|
-
// List all environments (metadata only - no secret values)
|
|
9
|
-
router.get('/', (_req, res) => {
|
|
10
|
-
res.json(getEnvironmentsMetadata());
|
|
11
|
-
});
|
|
12
|
-
// Get single environment metadata
|
|
13
|
-
router.get('/:id', (req, res) => {
|
|
14
|
-
const metadata = getEnvironmentMetadata(req.params.id);
|
|
15
|
-
if (!metadata) {
|
|
16
|
-
return res.status(404).json({ error: 'Environment not found' });
|
|
17
|
-
}
|
|
18
|
-
res.json(metadata);
|
|
19
|
-
});
|
|
20
|
-
// Get full environment data (including secret values) - for local editing only
|
|
21
|
-
router.get('/:id/full', (req, res) => {
|
|
22
|
-
const env = getEnvironment(req.params.id);
|
|
23
|
-
if (!env) {
|
|
24
|
-
return res.status(404).json({ error: 'Environment not found' });
|
|
25
|
-
}
|
|
26
|
-
res.json(env);
|
|
27
|
-
});
|
|
28
|
-
// Create environment
|
|
29
|
-
router.post('/', (req, res) => {
|
|
30
|
-
const { name, provider, icon, isDefault, variables } = req.body;
|
|
31
|
-
if (!name || !provider) {
|
|
32
|
-
return res.status(400).json({ error: 'Missing required fields: name, provider' });
|
|
33
|
-
}
|
|
34
|
-
try {
|
|
35
|
-
const env = createEnvironment({
|
|
36
|
-
name,
|
|
37
|
-
provider,
|
|
38
|
-
icon,
|
|
39
|
-
isDefault,
|
|
40
|
-
variables: variables ?? {},
|
|
41
|
-
});
|
|
42
|
-
// Return metadata only (not the actual secrets)
|
|
43
|
-
res.status(201).json({
|
|
44
|
-
id: env.id,
|
|
45
|
-
name: env.name,
|
|
46
|
-
provider: env.provider,
|
|
47
|
-
icon: env.icon,
|
|
48
|
-
isDefault: env.isDefault,
|
|
49
|
-
variableKeys: Object.keys(env.variables),
|
|
50
|
-
createdAt: env.createdAt,
|
|
51
|
-
updatedAt: env.updatedAt,
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
catch (err) {
|
|
55
|
-
console.error('[Environments] Create error:', err);
|
|
56
|
-
res.status(500).json({ error: 'Failed to create environment' });
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
// Update environment
|
|
60
|
-
router.put('/:id', (req, res) => {
|
|
61
|
-
const { name, provider, icon, isDefault, variables } = req.body;
|
|
62
|
-
const updated = updateEnvironment(req.params.id, {
|
|
63
|
-
name,
|
|
64
|
-
provider,
|
|
65
|
-
icon,
|
|
66
|
-
isDefault,
|
|
67
|
-
variables,
|
|
68
|
-
});
|
|
69
|
-
if (!updated) {
|
|
70
|
-
return res.status(404).json({ error: 'Environment not found' });
|
|
71
|
-
}
|
|
72
|
-
// Return metadata only
|
|
73
|
-
res.json({
|
|
74
|
-
id: updated.id,
|
|
75
|
-
name: updated.name,
|
|
76
|
-
provider: updated.provider,
|
|
77
|
-
icon: updated.icon,
|
|
78
|
-
isDefault: updated.isDefault,
|
|
79
|
-
variableKeys: Object.keys(updated.variables),
|
|
80
|
-
createdAt: updated.createdAt,
|
|
81
|
-
updatedAt: updated.updatedAt,
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
// Delete environment
|
|
85
|
-
router.delete('/:id', (req, res) => {
|
|
86
|
-
const deleted = deleteEnvironment(req.params.id);
|
|
87
|
-
if (!deleted) {
|
|
88
|
-
return res.status(404).json({ error: 'Environment not found' });
|
|
89
|
-
}
|
|
90
|
-
res.json({ success: true });
|
|
91
|
-
});
|
|
92
|
-
return router;
|
|
93
|
-
}
|
|
94
|
-
//# sourceMappingURL=environments.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"environments.js","sourceRoot":"","sources":["../../src/routes/environments.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../src/routes/files.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAKjC,wBAAgB,iBAAiB,IAAI,MAAM,CA0F1C"}
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* File explorer API routes: list files, get content, open in editor.
|
|
3
|
-
*/
|
|
4
|
-
import { Router } from 'express';
|
|
5
|
-
import { listFiles, getFileContent, openFileInEditor, getChangesSummary } from '../git.js';
|
|
6
|
-
import { config } from '../config.js';
|
|
7
|
-
import { isProjectAllowed } from './editor.js';
|
|
8
|
-
export function createFilesRoutes() {
|
|
9
|
-
const router = Router();
|
|
10
|
-
// Get files tree with git status for a project
|
|
11
|
-
router.get('/:project', async (req, res) => {
|
|
12
|
-
const { project } = req.params;
|
|
13
|
-
if (!isProjectAllowed(project)) {
|
|
14
|
-
return res.status(403).json({ error: 'Project not allowed' });
|
|
15
|
-
}
|
|
16
|
-
try {
|
|
17
|
-
const projectPath = `${config.projects.basePath}/${project}`.replace('~', process.env.HOME);
|
|
18
|
-
const fs = await import('fs');
|
|
19
|
-
if (!fs.existsSync(projectPath)) {
|
|
20
|
-
return res.status(404).json({ error: 'Project not found' });
|
|
21
|
-
}
|
|
22
|
-
const files = await listFiles(projectPath);
|
|
23
|
-
const summary = await getChangesSummary(projectPath);
|
|
24
|
-
res.json({ files, summary });
|
|
25
|
-
}
|
|
26
|
-
catch (err) {
|
|
27
|
-
console.error('[Files] Failed to list files:', err);
|
|
28
|
-
res.status(500).json({ error: 'Failed to list files', message: err.message });
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
// Get content of a specific file
|
|
32
|
-
router.get('/:project/content', async (req, res) => {
|
|
33
|
-
const { project } = req.params;
|
|
34
|
-
const { path: filePath } = req.query;
|
|
35
|
-
if (!isProjectAllowed(project)) {
|
|
36
|
-
return res.status(403).json({ error: 'Project not allowed' });
|
|
37
|
-
}
|
|
38
|
-
if (!filePath || typeof filePath !== 'string') {
|
|
39
|
-
return res.status(400).json({ error: 'Missing path parameter' });
|
|
40
|
-
}
|
|
41
|
-
if (filePath.includes('..') || filePath.startsWith('/')) {
|
|
42
|
-
return res.status(400).json({ error: 'Invalid path' });
|
|
43
|
-
}
|
|
44
|
-
try {
|
|
45
|
-
const projectPath = `${config.projects.basePath}/${project}`.replace('~', process.env.HOME);
|
|
46
|
-
const content = await getFileContent(projectPath, filePath);
|
|
47
|
-
res.json(content);
|
|
48
|
-
}
|
|
49
|
-
catch (err) {
|
|
50
|
-
console.error('[Files] Failed to get file content:', err);
|
|
51
|
-
res.status(500).json({ error: 'Failed to read file', message: err.message });
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
// Open a file in the local editor
|
|
55
|
-
router.post('/:project/open', async (req, res) => {
|
|
56
|
-
const { project } = req.params;
|
|
57
|
-
const { path: filePath } = req.body;
|
|
58
|
-
if (!isProjectAllowed(project)) {
|
|
59
|
-
return res.status(403).json({ error: 'Project not allowed' });
|
|
60
|
-
}
|
|
61
|
-
if (!filePath || typeof filePath !== 'string') {
|
|
62
|
-
return res.status(400).json({ error: 'Missing path in body' });
|
|
63
|
-
}
|
|
64
|
-
if (filePath.includes('..') || filePath.startsWith('/')) {
|
|
65
|
-
return res.status(400).json({ error: 'Invalid path' });
|
|
66
|
-
}
|
|
67
|
-
try {
|
|
68
|
-
const projectPath = `${config.projects.basePath}/${project}`.replace('~', process.env.HOME);
|
|
69
|
-
const result = await openFileInEditor(projectPath, filePath);
|
|
70
|
-
if (result.success) {
|
|
71
|
-
res.json({ success: true, command: result.command });
|
|
72
|
-
}
|
|
73
|
-
else {
|
|
74
|
-
res.status(400).json(result);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
catch (err) {
|
|
78
|
-
console.error('[Files] Failed to open file:', err);
|
|
79
|
-
res.status(500).json({ error: 'Failed to open file', message: err.message });
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
return router;
|
|
83
|
-
}
|
|
84
|
-
//# sourceMappingURL=files.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/routes/files.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Heartbeat API route: receives statusLine updates from Claude Code.
|
|
3
|
-
* Replaces the old hooks system with a simpler heartbeat-based approach.
|
|
4
|
-
*/
|
|
5
|
-
import { Router, type Router as RouterType } from 'express';
|
|
6
|
-
declare const router: RouterType;
|
|
7
|
-
export declare const lastHeartbeat: Map<string, number>;
|
|
8
|
-
export declare function createHeartbeatRoutes(): Router;
|
|
9
|
-
export default router;
|
|
10
|
-
//# sourceMappingURL=heartbeat.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"heartbeat.d.ts","sourceRoot":"","sources":["../../src/routes/heartbeat.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,KAAK,MAAM,IAAI,UAAU,EAAE,MAAM,SAAS,CAAC;AAO5D,QAAA,MAAM,MAAM,EAAE,UAAqB,CAAC;AAGpC,eAAO,MAAM,aAAa,qBAA4B,CAAC;AAuJvD,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED,eAAe,MAAM,CAAC"}
|