apteva 0.4.57 → 0.7.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/README.md +216 -54
- package/cli.js +35 -0
- package/install.js +92 -0
- package/package.json +12 -79
- package/LICENSE +0 -63
- package/bin/apteva.js +0 -196
- package/dist/ActivityPage.kxzzb4yc.js +0 -3
- package/dist/ApiDocsPage.zq998hbm.js +0 -4
- package/dist/App.55rea8mn.js +0 -61
- package/dist/App.5ywb23z4.js +0 -53
- package/dist/App.6thds120.js +0 -4
- package/dist/App.9tctxzqm.js +0 -8
- package/dist/App.a8r8ttaz.js +0 -4
- package/dist/App.agsv5bje.js +0 -4
- package/dist/App.cepapqmx.js +0 -4
- package/dist/App.dp041gb3.js +0 -221
- package/dist/App.fds72zb5.js +0 -4
- package/dist/App.fg9qj2dq.js +0 -4
- package/dist/App.ndfejbm9.js +0 -4
- package/dist/App.nxmfmq1h.js +0 -13
- package/dist/App.qdfyt8ba.js +0 -4
- package/dist/App.x2d0ygt6.js +0 -4
- package/dist/App.yt9p4nr3.js +0 -20
- package/dist/App.zn4mw16t.js +0 -1
- package/dist/ConnectionsPage.8r96ryw7.js +0 -3
- package/dist/McpPage.3cwh0gnd.js +0 -3
- package/dist/SettingsPage.ykgdh5ev.js +0 -3
- package/dist/SkillsPage.4np1s65b.js +0 -3
- package/dist/TasksPage.4g08t7p6.js +0 -3
- package/dist/TelemetryPage.72w9pwcp.js +0 -3
- package/dist/TestsPage.z4fk3r7r.js +0 -3
- package/dist/ThreadsPage.63tcajeh.js +0 -3
- package/dist/apteva-kit.css +0 -1
- package/dist/icon.png +0 -0
- package/dist/index.html +0 -16
- package/dist/styles.css +0 -1
- package/scripts/postinstall.mjs +0 -102
- package/src/auth/index.ts +0 -394
- package/src/auth/middleware.ts +0 -213
- package/src/binary.ts +0 -536
- package/src/channels/index.ts +0 -40
- package/src/channels/telegram.ts +0 -311
- package/src/crypto.ts +0 -301
- package/src/db-tests.ts +0 -174
- package/src/db.ts +0 -3133
- package/src/integrations/agentdojo.ts +0 -559
- package/src/integrations/composio.ts +0 -437
- package/src/integrations/index.ts +0 -87
- package/src/integrations/skillsmp.ts +0 -318
- package/src/mcp-client.ts +0 -605
- package/src/mcp-handler.ts +0 -394
- package/src/mcp-platform.ts +0 -2403
- package/src/openapi.ts +0 -2410
- package/src/providers.ts +0 -597
- package/src/routes/api/agent-utils.ts +0 -890
- package/src/routes/api/agents.ts +0 -916
- package/src/routes/api/api-keys.ts +0 -95
- package/src/routes/api/channels.ts +0 -182
- package/src/routes/api/helpers.ts +0 -12
- package/src/routes/api/integrations.ts +0 -639
- package/src/routes/api/mcp.ts +0 -574
- package/src/routes/api/meta-agent.ts +0 -195
- package/src/routes/api/projects.ts +0 -112
- package/src/routes/api/providers.ts +0 -424
- package/src/routes/api/skills.ts +0 -537
- package/src/routes/api/system.ts +0 -333
- package/src/routes/api/telemetry.ts +0 -203
- package/src/routes/api/tests.ts +0 -148
- package/src/routes/api/triggers.ts +0 -518
- package/src/routes/api/users.ts +0 -148
- package/src/routes/api/webhooks.ts +0 -171
- package/src/routes/api.ts +0 -53
- package/src/routes/auth.ts +0 -251
- package/src/routes/share.ts +0 -86
- package/src/routes/static.ts +0 -131
- package/src/server.ts +0 -642
- package/src/test-runner.ts +0 -598
- package/src/triggers/agentdojo.ts +0 -253
- package/src/triggers/composio.ts +0 -264
- package/src/triggers/index.ts +0 -71
- package/src/tui/AgentList.tsx +0 -145
- package/src/tui/App.tsx +0 -102
- package/src/tui/Login.tsx +0 -104
- package/src/tui/api.ts +0 -72
- package/src/tui/index.tsx +0 -7
- package/src/web/App.tsx +0 -455
- package/src/web/components/activity/ActivityPage.tsx +0 -314
- package/src/web/components/activity/index.ts +0 -1
- package/src/web/components/agents/AgentCard.tsx +0 -189
- package/src/web/components/agents/AgentPanel.tsx +0 -2244
- package/src/web/components/agents/AgentsView.tsx +0 -180
- package/src/web/components/agents/CreateAgentModal.tsx +0 -475
- package/src/web/components/agents/index.ts +0 -4
- package/src/web/components/api/ApiDocsPage.tsx +0 -842
- package/src/web/components/auth/CreateAccountStep.tsx +0 -176
- package/src/web/components/auth/LoginPage.tsx +0 -91
- package/src/web/components/auth/index.ts +0 -2
- package/src/web/components/common/Icons.tsx +0 -250
- package/src/web/components/common/LoadingSpinner.tsx +0 -44
- package/src/web/components/common/Modal.tsx +0 -199
- package/src/web/components/common/Select.tsx +0 -97
- package/src/web/components/common/index.ts +0 -20
- package/src/web/components/connections/ConnectionsPage.tsx +0 -54
- package/src/web/components/connections/IntegrationsTab.tsx +0 -170
- package/src/web/components/connections/OverviewTab.tsx +0 -137
- package/src/web/components/connections/TriggersTab.tsx +0 -1346
- package/src/web/components/dashboard/Dashboard.tsx +0 -572
- package/src/web/components/dashboard/index.ts +0 -1
- package/src/web/components/index.ts +0 -21
- package/src/web/components/layout/ErrorBanner.tsx +0 -18
- package/src/web/components/layout/Header.tsx +0 -332
- package/src/web/components/layout/Sidebar.tsx +0 -231
- package/src/web/components/layout/index.ts +0 -3
- package/src/web/components/mcp/IntegrationsPanel.tsx +0 -857
- package/src/web/components/mcp/McpPage.tsx +0 -2515
- package/src/web/components/mcp/index.ts +0 -1
- package/src/web/components/meta-agent/MetaAgent.tsx +0 -245
- package/src/web/components/onboarding/OnboardingWizard.tsx +0 -404
- package/src/web/components/onboarding/index.ts +0 -1
- package/src/web/components/settings/SettingsPage.tsx +0 -2776
- package/src/web/components/settings/index.ts +0 -1
- package/src/web/components/skills/SkillsPage.tsx +0 -1200
- package/src/web/components/tasks/TasksPage.tsx +0 -1116
- package/src/web/components/tasks/index.ts +0 -1
- package/src/web/components/telemetry/TelemetryPage.tsx +0 -1129
- package/src/web/components/tests/TestsPage.tsx +0 -594
- package/src/web/components/threads/ThreadsPage.tsx +0 -315
- package/src/web/context/AuthContext.tsx +0 -242
- package/src/web/context/ProjectContext.tsx +0 -214
- package/src/web/context/TelemetryContext.tsx +0 -299
- package/src/web/context/ThemeContext.tsx +0 -90
- package/src/web/context/UIModeContext.tsx +0 -49
- package/src/web/context/index.ts +0 -12
- package/src/web/hooks/index.ts +0 -3
- package/src/web/hooks/useAgents.ts +0 -115
- package/src/web/hooks/useOnboarding.ts +0 -20
- package/src/web/hooks/useProviders.ts +0 -75
- package/src/web/icon.png +0 -0
- package/src/web/index.html +0 -16
- package/src/web/styles.css +0 -118
- package/src/web/themes.ts +0 -162
- package/src/web/types.ts +0 -298
package/src/binary.ts
DELETED
|
@@ -1,536 +0,0 @@
|
|
|
1
|
-
import { join } from "path";
|
|
2
|
-
import { existsSync, mkdirSync, chmodSync, readFileSync, writeFileSync } from "fs";
|
|
3
|
-
|
|
4
|
-
// Binary configuration
|
|
5
|
-
const BINARY_BASE_URL = "https://github.com/apteva/agent/releases/latest/download";
|
|
6
|
-
const NPM_REGISTRY = "https://registry.npmjs.org";
|
|
7
|
-
const CONNECT_TIMEOUT = 15000; // 15 seconds for initial connection
|
|
8
|
-
const DOWNLOAD_TIMEOUT = 120000; // 120 seconds for full download
|
|
9
|
-
const MAX_RETRIES = 3;
|
|
10
|
-
const RETRY_DELAY = 1000; // 1 second between retries
|
|
11
|
-
|
|
12
|
-
// Version info stored in data directory
|
|
13
|
-
let versionFilePath: string | null = null;
|
|
14
|
-
|
|
15
|
-
// ANSI colors for console output
|
|
16
|
-
const c = {
|
|
17
|
-
reset: "\x1b[0m",
|
|
18
|
-
orange: "\x1b[38;5;208m",
|
|
19
|
-
gray: "\x1b[38;5;245m",
|
|
20
|
-
green: "\x1b[38;5;82m",
|
|
21
|
-
red: "\x1b[38;5;196m",
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
// Map Node.js platform/arch to npm package names
|
|
25
|
-
function getNpmPackageName(): string {
|
|
26
|
-
const platform = process.platform; // darwin, linux, win32
|
|
27
|
-
const arch = process.arch; // x64, arm64
|
|
28
|
-
|
|
29
|
-
// Map to our package naming convention
|
|
30
|
-
const archMap: Record<string, string> = {
|
|
31
|
-
x64: "x64",
|
|
32
|
-
arm64: "arm64",
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
const mappedArch = archMap[arch] || arch;
|
|
36
|
-
return `@apteva/agent-${platform}-${mappedArch}`;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Try to find binary from installed npm package
|
|
40
|
-
function findNpmBinary(): string | null {
|
|
41
|
-
const packageName = getNpmPackageName();
|
|
42
|
-
|
|
43
|
-
try {
|
|
44
|
-
// Try to require the package - it exports the binary path
|
|
45
|
-
const binaryPath = require(packageName);
|
|
46
|
-
if (existsSync(binaryPath)) {
|
|
47
|
-
return binaryPath;
|
|
48
|
-
}
|
|
49
|
-
} catch {
|
|
50
|
-
// Package not installed, fall through
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// Also try direct path resolution in node_modules
|
|
54
|
-
const possiblePaths = [
|
|
55
|
-
join(import.meta.dir, "../../node_modules", packageName, process.platform === "win32" ? "agent.exe" : "agent"),
|
|
56
|
-
join(process.cwd(), "node_modules", packageName, process.platform === "win32" ? "agent.exe" : "agent"),
|
|
57
|
-
];
|
|
58
|
-
|
|
59
|
-
for (const p of possiblePaths) {
|
|
60
|
-
if (existsSync(p)) {
|
|
61
|
-
return p;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return null;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Determine platform and architecture for download fallback
|
|
69
|
-
function getPlatformInfo(): { platform: string; arch: string; ext: string } {
|
|
70
|
-
const platform = process.platform === "win32" ? "windows" : process.platform;
|
|
71
|
-
let arch = process.arch;
|
|
72
|
-
|
|
73
|
-
// Normalize architecture names for GitHub releases
|
|
74
|
-
if (arch === "x64") arch = "amd64";
|
|
75
|
-
if (arch === "arm64") arch = "arm64";
|
|
76
|
-
|
|
77
|
-
const ext = platform === "windows" ? ".exe" : "";
|
|
78
|
-
|
|
79
|
-
return { platform, arch, ext };
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Get binary filename for current platform (for download)
|
|
83
|
-
export function getBinaryFilename(): string {
|
|
84
|
-
const { platform, arch, ext } = getPlatformInfo();
|
|
85
|
-
return `agent-${platform}-${arch}${ext}`;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Get full binary path in bin directory
|
|
89
|
-
export function getBinaryPath(binDir: string): string {
|
|
90
|
-
return join(binDir, getBinaryFilename());
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// Get download URL for current platform
|
|
94
|
-
function getDownloadUrl(): string {
|
|
95
|
-
const filename = getBinaryFilename();
|
|
96
|
-
return `${BINARY_BASE_URL}/${filename}`;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// Check if binary exists (downloaded or npm)
|
|
100
|
-
export function binaryExists(binDir: string): boolean {
|
|
101
|
-
// Check downloaded binary first
|
|
102
|
-
if (existsSync(getBinaryPath(binDir))) return true;
|
|
103
|
-
|
|
104
|
-
// Then check npm package
|
|
105
|
-
const npmBinary = findNpmBinary();
|
|
106
|
-
return !!npmBinary;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Get the actual binary path (downloaded takes priority over npm)
|
|
110
|
-
export function getActualBinaryPath(binDir: string): string | null {
|
|
111
|
-
// First check downloaded binary (takes priority - allows updates)
|
|
112
|
-
const downloadedPath = getBinaryPath(binDir);
|
|
113
|
-
if (existsSync(downloadedPath)) return downloadedPath;
|
|
114
|
-
|
|
115
|
-
// Fall back to npm package (initial install)
|
|
116
|
-
const npmBinary = findNpmBinary();
|
|
117
|
-
if (npmBinary) return npmBinary;
|
|
118
|
-
|
|
119
|
-
return null;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// Helper to delay
|
|
123
|
-
const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
|
|
124
|
-
|
|
125
|
-
// Download file with timeout for both connection and body
|
|
126
|
-
async function downloadWithTimeout(url: string): Promise<ArrayBuffer> {
|
|
127
|
-
const controller = new AbortController();
|
|
128
|
-
|
|
129
|
-
// Timeout for connection
|
|
130
|
-
let timeoutId = setTimeout(() => controller.abort(), CONNECT_TIMEOUT);
|
|
131
|
-
|
|
132
|
-
const response = await fetch(url, { signal: controller.signal });
|
|
133
|
-
clearTimeout(timeoutId);
|
|
134
|
-
|
|
135
|
-
if (!response.ok) {
|
|
136
|
-
throw new Error(`HTTP ${response.status}`);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// Timeout for body download
|
|
140
|
-
timeoutId = setTimeout(() => controller.abort(), DOWNLOAD_TIMEOUT);
|
|
141
|
-
|
|
142
|
-
try {
|
|
143
|
-
const arrayBuffer = await response.arrayBuffer();
|
|
144
|
-
clearTimeout(timeoutId);
|
|
145
|
-
return arrayBuffer;
|
|
146
|
-
} catch (err) {
|
|
147
|
-
clearTimeout(timeoutId);
|
|
148
|
-
throw err;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// Ensure binary exists - check downloaded first (for updates), then npm
|
|
153
|
-
export async function ensureBinary(binDir: string, silent = false): Promise<{
|
|
154
|
-
success: boolean;
|
|
155
|
-
path: string;
|
|
156
|
-
error?: string;
|
|
157
|
-
downloaded?: boolean;
|
|
158
|
-
source?: "npm" | "download" | "cached";
|
|
159
|
-
}> {
|
|
160
|
-
const binaryPath = getBinaryPath(binDir);
|
|
161
|
-
|
|
162
|
-
// Ensure bin directory exists
|
|
163
|
-
if (!existsSync(binDir)) {
|
|
164
|
-
mkdirSync(binDir, { recursive: true });
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// First check downloaded binary (takes priority - allows updates)
|
|
168
|
-
if (existsSync(binaryPath)) {
|
|
169
|
-
return {
|
|
170
|
-
success: true,
|
|
171
|
-
path: binaryPath,
|
|
172
|
-
downloaded: false,
|
|
173
|
-
source: "cached"
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// Fall back to npm package (initial install)
|
|
178
|
-
const npmBinary = findNpmBinary();
|
|
179
|
-
if (npmBinary) {
|
|
180
|
-
return {
|
|
181
|
-
success: true,
|
|
182
|
-
path: npmBinary,
|
|
183
|
-
downloaded: false,
|
|
184
|
-
source: "npm"
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// No cached binary and no npm package - show error
|
|
189
|
-
if (!silent) {
|
|
190
|
-
console.log(`${c.red}not found${c.reset}`);
|
|
191
|
-
console.log(`\n Install the agent binary: npm install @apteva/agent-linux-x64`);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
return {
|
|
195
|
-
success: false,
|
|
196
|
-
path: binaryPath,
|
|
197
|
-
error: "Binary not found. Install via: npm install @apteva/agent-<platform>",
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
// Get binary status info
|
|
202
|
-
export function getBinaryStatus(binDir: string): {
|
|
203
|
-
exists: boolean;
|
|
204
|
-
path: string;
|
|
205
|
-
filename: string;
|
|
206
|
-
downloadUrl: string;
|
|
207
|
-
platform: string;
|
|
208
|
-
arch: string;
|
|
209
|
-
source?: "npm" | "download" | "none";
|
|
210
|
-
} {
|
|
211
|
-
const { platform, arch } = getPlatformInfo();
|
|
212
|
-
|
|
213
|
-
// Check downloaded first (takes priority - allows updates)
|
|
214
|
-
const downloadedPath = getBinaryPath(binDir);
|
|
215
|
-
if (existsSync(downloadedPath)) {
|
|
216
|
-
return {
|
|
217
|
-
exists: true,
|
|
218
|
-
path: downloadedPath,
|
|
219
|
-
filename: getBinaryFilename(),
|
|
220
|
-
downloadUrl: getDownloadUrl(),
|
|
221
|
-
platform,
|
|
222
|
-
arch,
|
|
223
|
-
source: "download",
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
// Fall back to npm package
|
|
228
|
-
const npmBinary = findNpmBinary();
|
|
229
|
-
if (npmBinary) {
|
|
230
|
-
return {
|
|
231
|
-
exists: true,
|
|
232
|
-
path: npmBinary,
|
|
233
|
-
filename: getBinaryFilename(),
|
|
234
|
-
downloadUrl: getDownloadUrl(),
|
|
235
|
-
platform,
|
|
236
|
-
arch,
|
|
237
|
-
source: "npm",
|
|
238
|
-
};
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
return {
|
|
242
|
-
exists: false,
|
|
243
|
-
path: downloadedPath,
|
|
244
|
-
filename: getBinaryFilename(),
|
|
245
|
-
downloadUrl: getDownloadUrl(),
|
|
246
|
-
platform,
|
|
247
|
-
arch,
|
|
248
|
-
source: "none",
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
// ============ Version Management ============
|
|
253
|
-
|
|
254
|
-
// Get apteva app version from package.json
|
|
255
|
-
export function getAptevaVersion(): string {
|
|
256
|
-
try {
|
|
257
|
-
const pkgPath = join(import.meta.dir, "../package.json");
|
|
258
|
-
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
259
|
-
return pkg.version || "unknown";
|
|
260
|
-
} catch {
|
|
261
|
-
return "unknown";
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
// Check latest apteva version from npm
|
|
266
|
-
export async function getLatestAptevaVersion(): Promise<string | null> {
|
|
267
|
-
try {
|
|
268
|
-
const response = await fetch(`${NPM_REGISTRY}/apteva/latest`, {
|
|
269
|
-
signal: AbortSignal.timeout(5000),
|
|
270
|
-
});
|
|
271
|
-
if (!response.ok) return null;
|
|
272
|
-
const data = await response.json() as { version?: string };
|
|
273
|
-
return data.version || null;
|
|
274
|
-
} catch {
|
|
275
|
-
return null;
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
export interface VersionInfo {
|
|
280
|
-
installed: string | null;
|
|
281
|
-
latest: string | null;
|
|
282
|
-
updateAvailable: boolean;
|
|
283
|
-
lastChecked: string | null;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
export interface AllVersionInfo {
|
|
287
|
-
apteva: VersionInfo;
|
|
288
|
-
agent: VersionInfo;
|
|
289
|
-
isDocker: boolean;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
// Detect if running in Docker
|
|
293
|
-
export function isRunningInDocker(): boolean {
|
|
294
|
-
// Check for /.dockerenv file (standard Docker indicator)
|
|
295
|
-
if (existsSync("/.dockerenv")) {
|
|
296
|
-
return true;
|
|
297
|
-
}
|
|
298
|
-
// Check for DATA_DIR=/data (our Docker convention)
|
|
299
|
-
if (process.env.DATA_DIR === "/data") {
|
|
300
|
-
return true;
|
|
301
|
-
}
|
|
302
|
-
// Check for DOCKER env var we could set
|
|
303
|
-
if (process.env.DOCKER === "true") {
|
|
304
|
-
return true;
|
|
305
|
-
}
|
|
306
|
-
return false;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
// Initialize version file path
|
|
310
|
-
export function initVersionTracking(dataDir: string): void {
|
|
311
|
-
versionFilePath = join(dataDir, "agent-version.json");
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
// Get stored version info
|
|
315
|
-
function getStoredVersion(): { version: string; lastChecked: string } | null {
|
|
316
|
-
if (!versionFilePath || !existsSync(versionFilePath)) {
|
|
317
|
-
return null;
|
|
318
|
-
}
|
|
319
|
-
try {
|
|
320
|
-
const data = JSON.parse(readFileSync(versionFilePath, "utf-8"));
|
|
321
|
-
return data;
|
|
322
|
-
} catch {
|
|
323
|
-
return null;
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
// Save version info
|
|
328
|
-
function saveVersion(version: string): void {
|
|
329
|
-
if (!versionFilePath) return;
|
|
330
|
-
const data = {
|
|
331
|
-
version,
|
|
332
|
-
lastChecked: new Date().toISOString(),
|
|
333
|
-
};
|
|
334
|
-
writeFileSync(versionFilePath, JSON.stringify(data, null, 2));
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
// Get latest version from npm registry
|
|
338
|
-
export async function getLatestNpmVersion(): Promise<string | null> {
|
|
339
|
-
const packageName = getNpmPackageName();
|
|
340
|
-
try {
|
|
341
|
-
const response = await fetch(`${NPM_REGISTRY}/${packageName}/latest`, {
|
|
342
|
-
signal: AbortSignal.timeout(5000),
|
|
343
|
-
});
|
|
344
|
-
if (!response.ok) return null;
|
|
345
|
-
const data = await response.json() as { version?: string };
|
|
346
|
-
return data.version || null;
|
|
347
|
-
} catch {
|
|
348
|
-
return null;
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
// Get installed version (from npm package or stored)
|
|
353
|
-
export function getInstalledVersion(): string | null {
|
|
354
|
-
// Check stored version first (from manual updates)
|
|
355
|
-
const stored = getStoredVersion();
|
|
356
|
-
if (stored?.version) {
|
|
357
|
-
return stored.version;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
// Fall back to npm package version
|
|
361
|
-
const packageName = getNpmPackageName();
|
|
362
|
-
try {
|
|
363
|
-
const pkgPath = require.resolve(`${packageName}/package.json`);
|
|
364
|
-
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
365
|
-
return pkg.version || null;
|
|
366
|
-
} catch {
|
|
367
|
-
// Not installed via npm
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
return null;
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
// Check for agent binary updates
|
|
374
|
-
export async function checkForAgentUpdates(): Promise<VersionInfo> {
|
|
375
|
-
const installed = getInstalledVersion();
|
|
376
|
-
const latest = await getLatestNpmVersion();
|
|
377
|
-
|
|
378
|
-
let updateAvailable = false;
|
|
379
|
-
if (installed && latest) {
|
|
380
|
-
updateAvailable = compareVersions(latest, installed) > 0;
|
|
381
|
-
} else if (!installed && latest) {
|
|
382
|
-
updateAvailable = true;
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
const stored = getStoredVersion();
|
|
386
|
-
|
|
387
|
-
return {
|
|
388
|
-
installed,
|
|
389
|
-
latest,
|
|
390
|
-
updateAvailable,
|
|
391
|
-
lastChecked: stored?.lastChecked || null,
|
|
392
|
-
};
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
// Check for apteva app updates
|
|
396
|
-
export async function checkForAptevaUpdates(): Promise<VersionInfo> {
|
|
397
|
-
const installed = getAptevaVersion();
|
|
398
|
-
const latest = await getLatestAptevaVersion();
|
|
399
|
-
|
|
400
|
-
let updateAvailable = false;
|
|
401
|
-
if (installed && latest && installed !== "unknown") {
|
|
402
|
-
updateAvailable = compareVersions(latest, installed) > 0;
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
return {
|
|
406
|
-
installed,
|
|
407
|
-
latest,
|
|
408
|
-
updateAvailable,
|
|
409
|
-
lastChecked: new Date().toISOString(),
|
|
410
|
-
};
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
// Check for all updates (apteva + agent)
|
|
414
|
-
export async function checkForUpdates(): Promise<AllVersionInfo> {
|
|
415
|
-
const [apteva, agent] = await Promise.all([
|
|
416
|
-
checkForAptevaUpdates(),
|
|
417
|
-
checkForAgentUpdates(),
|
|
418
|
-
]);
|
|
419
|
-
|
|
420
|
-
return { apteva, agent, isDocker: isRunningInDocker() };
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
// Compare semver versions: returns positive if a > b, negative if a < b, 0 if equal
|
|
424
|
-
function compareVersions(a: string, b: string): number {
|
|
425
|
-
const partsA = a.split(".").map(n => parseInt(n, 10) || 0);
|
|
426
|
-
const partsB = b.split(".").map(n => parseInt(n, 10) || 0);
|
|
427
|
-
|
|
428
|
-
for (let i = 0; i < Math.max(partsA.length, partsB.length); i++) {
|
|
429
|
-
const numA = partsA[i] || 0;
|
|
430
|
-
const numB = partsB[i] || 0;
|
|
431
|
-
if (numA > numB) return 1;
|
|
432
|
-
if (numA < numB) return -1;
|
|
433
|
-
}
|
|
434
|
-
return 0;
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
// Download and install latest binary
|
|
438
|
-
export async function downloadLatestBinary(binDir: string): Promise<{
|
|
439
|
-
success: boolean;
|
|
440
|
-
version?: string;
|
|
441
|
-
error?: string;
|
|
442
|
-
}> {
|
|
443
|
-
// Ensure bin directory exists
|
|
444
|
-
if (!existsSync(binDir)) {
|
|
445
|
-
mkdirSync(binDir, { recursive: true });
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
const binaryPath = getBinaryPath(binDir);
|
|
449
|
-
const url = getDownloadUrl();
|
|
450
|
-
|
|
451
|
-
console.log(`${c.gray}Downloading latest agent binary...${c.reset}`);
|
|
452
|
-
|
|
453
|
-
let lastErr: Error | null = null;
|
|
454
|
-
for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
|
|
455
|
-
try {
|
|
456
|
-
const data = await downloadWithTimeout(url);
|
|
457
|
-
|
|
458
|
-
// Write binary
|
|
459
|
-
await Bun.write(binaryPath, data);
|
|
460
|
-
|
|
461
|
-
// Make executable on Unix
|
|
462
|
-
if (process.platform !== "win32") {
|
|
463
|
-
chmodSync(binaryPath, 0o755);
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
// Get and save version
|
|
467
|
-
const version = await getLatestNpmVersion();
|
|
468
|
-
if (version) {
|
|
469
|
-
saveVersion(version);
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
console.log(`${c.green}Downloaded agent v${version || "unknown"}${c.reset}`);
|
|
473
|
-
|
|
474
|
-
return {
|
|
475
|
-
success: true,
|
|
476
|
-
version: version || undefined,
|
|
477
|
-
};
|
|
478
|
-
} catch (err) {
|
|
479
|
-
lastErr = err as Error;
|
|
480
|
-
if (attempt < MAX_RETRIES - 1) {
|
|
481
|
-
await sleep(RETRY_DELAY * (attempt + 1));
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
return {
|
|
487
|
-
success: false,
|
|
488
|
-
error: lastErr?.message || "Download failed",
|
|
489
|
-
};
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
// Install/update via npm (locally in project)
|
|
493
|
-
export async function installViaNpm(): Promise<{
|
|
494
|
-
success: boolean;
|
|
495
|
-
version?: string;
|
|
496
|
-
error?: string;
|
|
497
|
-
}> {
|
|
498
|
-
const packageName = getNpmPackageName();
|
|
499
|
-
|
|
500
|
-
console.log(`${c.gray}Updating ${packageName}...${c.reset}`);
|
|
501
|
-
|
|
502
|
-
try {
|
|
503
|
-
// Install locally (not globally) - updates the package in node_modules
|
|
504
|
-
const proc = Bun.spawn(["npm", "update", packageName], {
|
|
505
|
-
stdout: "pipe",
|
|
506
|
-
stderr: "pipe",
|
|
507
|
-
cwd: join(import.meta.dir, ".."), // Run in package root
|
|
508
|
-
});
|
|
509
|
-
|
|
510
|
-
const exitCode = await proc.exited;
|
|
511
|
-
|
|
512
|
-
if (exitCode !== 0) {
|
|
513
|
-
const stderr = await new Response(proc.stderr).text();
|
|
514
|
-
return {
|
|
515
|
-
success: false,
|
|
516
|
-
error: stderr || `npm update failed with code ${exitCode}`,
|
|
517
|
-
};
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
const version = await getLatestNpmVersion();
|
|
521
|
-
if (version) {
|
|
522
|
-
saveVersion(version);
|
|
523
|
-
}
|
|
524
|
-
console.log(`${c.green}Updated agent to v${version || "latest"}${c.reset}`);
|
|
525
|
-
|
|
526
|
-
return {
|
|
527
|
-
success: true,
|
|
528
|
-
version: version || undefined,
|
|
529
|
-
};
|
|
530
|
-
} catch (err) {
|
|
531
|
-
return {
|
|
532
|
-
success: false,
|
|
533
|
-
error: (err as Error).message,
|
|
534
|
-
};
|
|
535
|
-
}
|
|
536
|
-
}
|
package/src/channels/index.ts
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { ChannelDB } from "../db";
|
|
2
|
-
import {
|
|
3
|
-
startTelegramChannel,
|
|
4
|
-
stopTelegramChannel,
|
|
5
|
-
isChannelActive,
|
|
6
|
-
} from "./telegram";
|
|
7
|
-
|
|
8
|
-
export async function startChannel(channelId: string): Promise<{ success: boolean; error?: string }> {
|
|
9
|
-
const channel = ChannelDB.findById(channelId);
|
|
10
|
-
if (!channel) return { success: false, error: "Channel not found" };
|
|
11
|
-
|
|
12
|
-
switch (channel.type) {
|
|
13
|
-
case "telegram":
|
|
14
|
-
return startTelegramChannel(channelId);
|
|
15
|
-
default:
|
|
16
|
-
return { success: false, error: `Unsupported channel type: ${channel.type}` };
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export async function stopChannel(channelId: string): Promise<void> {
|
|
21
|
-
const channel = ChannelDB.findById(channelId);
|
|
22
|
-
if (!channel) return;
|
|
23
|
-
|
|
24
|
-
switch (channel.type) {
|
|
25
|
-
case "telegram":
|
|
26
|
-
await stopTelegramChannel(channelId);
|
|
27
|
-
break;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export async function stopAllChannels(): Promise<void> {
|
|
32
|
-
const running = ChannelDB.findRunning();
|
|
33
|
-
for (const channel of running) {
|
|
34
|
-
await stopChannel(channel.id);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export function isActive(channelId: string): boolean {
|
|
39
|
-
return isChannelActive(channelId);
|
|
40
|
-
}
|