@psychout98/tadaima 1.0.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/dist/config.d.ts +23 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +25 -0
- package/dist/config.js.map +1 -0
- package/dist/daemon.d.ts +8 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +91 -0
- package/dist/daemon.js.map +1 -0
- package/dist/download-handler.d.ts +15 -0
- package/dist/download-handler.d.ts.map +1 -0
- package/dist/download-handler.js +203 -0
- package/dist/download-handler.js.map +1 -0
- package/dist/downloader.d.ts +11 -0
- package/dist/downloader.d.ts.map +1 -0
- package/dist/downloader.js +65 -0
- package/dist/downloader.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +271 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +2 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +74 -0
- package/dist/logger.js.map +1 -0
- package/dist/organizer.d.ts +12 -0
- package/dist/organizer.d.ts.map +1 -0
- package/dist/organizer.js +42 -0
- package/dist/organizer.js.map +1 -0
- package/dist/rd-client.d.ts +25 -0
- package/dist/rd-client.d.ts.map +1 -0
- package/dist/rd-client.js +129 -0
- package/dist/rd-client.js.map +1 -0
- package/dist/service.d.ts +3 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +186 -0
- package/dist/service.js.map +1 -0
- package/dist/setup.d.ts +2 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/setup.js +92 -0
- package/dist/setup.js.map +1 -0
- package/dist/status-writer.d.ts +20 -0
- package/dist/status-writer.d.ts.map +1 -0
- package/dist/status-writer.js +34 -0
- package/dist/status-writer.js.map +1 -0
- package/dist/tui.d.ts +14 -0
- package/dist/tui.d.ts.map +1 -0
- package/dist/tui.js +73 -0
- package/dist/tui.js.map +1 -0
- package/dist/updater.d.ts +27 -0
- package/dist/updater.d.ts.map +1 -0
- package/dist/updater.js +191 -0
- package/dist/updater.js.map +1 -0
- package/dist/ws-client.d.ts +26 -0
- package/dist/ws-client.d.ts.map +1 -0
- package/dist/ws-client.js +155 -0
- package/dist/ws-client.js.map +1 -0
- package/package.json +62 -0
package/dist/updater.js
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { createWriteStream, readFileSync, copyFileSync, chmodSync, renameSync } from "node:fs";
|
|
3
|
+
import { pipeline } from "node:stream/promises";
|
|
4
|
+
import { Readable } from "node:stream";
|
|
5
|
+
import { dirname, join, extname } from "node:path";
|
|
6
|
+
import { config } from "./config.js";
|
|
7
|
+
import { GITHUB_RELEASES_API, getAssetNameForPlatform, } from "@tadaima/shared";
|
|
8
|
+
let cachedETag = "";
|
|
9
|
+
/**
|
|
10
|
+
* Try the relay's /api/version endpoint first for a quick version check.
|
|
11
|
+
* Falls back to the full GitHub API if the relay is unreachable.
|
|
12
|
+
*/
|
|
13
|
+
async function checkViaRelay(currentVersion) {
|
|
14
|
+
const relayUrl = config.get("relay");
|
|
15
|
+
if (!relayUrl)
|
|
16
|
+
return null;
|
|
17
|
+
try {
|
|
18
|
+
const res = await fetch(`${relayUrl}/api/version`, {
|
|
19
|
+
signal: AbortSignal.timeout(5000),
|
|
20
|
+
});
|
|
21
|
+
if (!res.ok)
|
|
22
|
+
return null;
|
|
23
|
+
const data = (await res.json());
|
|
24
|
+
if (data.latest && isNewer(data.latest, currentVersion)) {
|
|
25
|
+
return data.latest;
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Check the GitHub Releases API for a newer version.
|
|
35
|
+
* Returns null if already up-to-date or unsupported platform.
|
|
36
|
+
*/
|
|
37
|
+
export async function checkForUpdate(currentVersion) {
|
|
38
|
+
const assetName = getAssetNameForPlatform();
|
|
39
|
+
if (!assetName)
|
|
40
|
+
return null;
|
|
41
|
+
// Quick check via relay first
|
|
42
|
+
const relayLatest = await checkViaRelay(currentVersion);
|
|
43
|
+
// If relay says we're up-to-date, skip the full GitHub API call
|
|
44
|
+
if (relayLatest === null) {
|
|
45
|
+
// Relay either unreachable or says up-to-date; still try GitHub for authoritative answer
|
|
46
|
+
}
|
|
47
|
+
const headers = {
|
|
48
|
+
Accept: "application/vnd.github+json",
|
|
49
|
+
"User-Agent": `tadaima-agent/${currentVersion}`,
|
|
50
|
+
};
|
|
51
|
+
if (cachedETag) {
|
|
52
|
+
headers["If-None-Match"] = cachedETag;
|
|
53
|
+
}
|
|
54
|
+
const res = await fetch(GITHUB_RELEASES_API, { headers });
|
|
55
|
+
if (res.status === 304)
|
|
56
|
+
return null; // not modified
|
|
57
|
+
if (!res.ok) {
|
|
58
|
+
throw new Error(`GitHub API returned ${res.status}: ${res.statusText}`);
|
|
59
|
+
}
|
|
60
|
+
const etag = res.headers.get("etag");
|
|
61
|
+
if (etag)
|
|
62
|
+
cachedETag = etag;
|
|
63
|
+
const data = (await res.json());
|
|
64
|
+
const latestVersion = data.tag_name.replace(/^v/, "");
|
|
65
|
+
if (!isNewer(latestVersion, currentVersion))
|
|
66
|
+
return null;
|
|
67
|
+
const binaryAsset = data.assets.find((a) => a.name === assetName);
|
|
68
|
+
const checksumAsset = data.assets.find((a) => a.name === "checksums.sha256");
|
|
69
|
+
if (!binaryAsset || !checksumAsset)
|
|
70
|
+
return null;
|
|
71
|
+
config.set("lastUpdateCheck", new Date().toISOString());
|
|
72
|
+
return {
|
|
73
|
+
version: latestVersion,
|
|
74
|
+
downloadUrl: binaryAsset.browser_download_url,
|
|
75
|
+
checksumUrl: checksumAsset.browser_download_url,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Download, verify, and replace the current binary with the update.
|
|
80
|
+
*/
|
|
81
|
+
export async function applyUpdate(update) {
|
|
82
|
+
const configDir = dirname(config.path);
|
|
83
|
+
const ext = extname(process.execPath);
|
|
84
|
+
const tmpPath = join(configDir, `tadaima-agent-update-${update.version}${ext}`);
|
|
85
|
+
const backupPath = join(configDir, `tadaima-agent-previous${ext}`);
|
|
86
|
+
// Download binary
|
|
87
|
+
const binRes = await fetch(update.downloadUrl);
|
|
88
|
+
if (!binRes.ok || !binRes.body) {
|
|
89
|
+
throw new Error(`Failed to download binary: ${binRes.status}`);
|
|
90
|
+
}
|
|
91
|
+
const ws = createWriteStream(tmpPath);
|
|
92
|
+
await pipeline(Readable.fromWeb(binRes.body), ws);
|
|
93
|
+
// Download and verify checksum
|
|
94
|
+
const csRes = await fetch(update.checksumUrl);
|
|
95
|
+
if (!csRes.ok) {
|
|
96
|
+
throw new Error(`Failed to download checksums: ${csRes.status}`);
|
|
97
|
+
}
|
|
98
|
+
const checksumText = await csRes.text();
|
|
99
|
+
const assetName = getAssetNameForPlatform();
|
|
100
|
+
const expectedLine = checksumText.split("\n").find((l) => l.includes(assetName));
|
|
101
|
+
if (!expectedLine) {
|
|
102
|
+
throw new Error(`No checksum found for ${assetName}`);
|
|
103
|
+
}
|
|
104
|
+
const expectedHash = expectedLine.trim().split(/\s+/)[0].toLowerCase();
|
|
105
|
+
const actualHash = createHash("sha256")
|
|
106
|
+
.update(readFileSync(tmpPath))
|
|
107
|
+
.digest("hex");
|
|
108
|
+
if (actualHash !== expectedHash) {
|
|
109
|
+
throw new Error(`Checksum mismatch: expected ${expectedHash}, got ${actualHash}`);
|
|
110
|
+
}
|
|
111
|
+
// Make executable
|
|
112
|
+
if (process.platform !== "win32") {
|
|
113
|
+
chmodSync(tmpPath, 0o755);
|
|
114
|
+
}
|
|
115
|
+
// Backup current binary
|
|
116
|
+
try {
|
|
117
|
+
copyFileSync(process.execPath, backupPath);
|
|
118
|
+
config.set("previousBinaryPath", backupPath);
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
// Backup may fail if execPath is read-only (npm global); non-fatal
|
|
122
|
+
}
|
|
123
|
+
// Atomic rename
|
|
124
|
+
renameSync(tmpPath, process.execPath);
|
|
125
|
+
// If running as a service, exit so the service manager restarts with the new binary
|
|
126
|
+
if (process.env.TADAIMA_DAEMON || isRunningAsService()) {
|
|
127
|
+
console.log(`Updated to v${update.version}. Exiting for service restart.`);
|
|
128
|
+
process.exit(0);
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
console.log(`Update to v${update.version} downloaded. Restart to apply.`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Check if enough time has passed since the last update check.
|
|
136
|
+
*/
|
|
137
|
+
export function shouldCheckNow(trigger) {
|
|
138
|
+
const last = config.get("lastUpdateCheck");
|
|
139
|
+
if (!last)
|
|
140
|
+
return true;
|
|
141
|
+
const elapsed = Date.now() - new Date(last).getTime();
|
|
142
|
+
const ONE_HOUR = 60 * 60 * 1000;
|
|
143
|
+
const TWENTY_FOUR_HOURS = 24 * ONE_HOUR;
|
|
144
|
+
if (trigger === "startup")
|
|
145
|
+
return elapsed > ONE_HOUR;
|
|
146
|
+
return elapsed > TWENTY_FOUR_HOURS;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Restore the previous binary from backup.
|
|
150
|
+
*/
|
|
151
|
+
export function rollback() {
|
|
152
|
+
const prev = config.get("previousBinaryPath");
|
|
153
|
+
if (!prev) {
|
|
154
|
+
console.log("No previous binary to roll back to.");
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
try {
|
|
158
|
+
copyFileSync(prev, process.execPath);
|
|
159
|
+
console.log(`Rolled back to previous binary from ${prev}.`);
|
|
160
|
+
console.log("Restart the agent to use the restored version.");
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
console.error("Rollback failed:", err instanceof Error ? err.message : err);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Log an update advisory for npm/Docker users who can't self-update.
|
|
168
|
+
*/
|
|
169
|
+
export function logUpdateAdvisory(currentVersion, latestVersion) {
|
|
170
|
+
console.log(`\nTadaima v${latestVersion} is available (you have v${currentVersion}).`);
|
|
171
|
+
console.log(" npm: npm update -g @tadaima/agent");
|
|
172
|
+
console.log(" Docker: docker compose pull && docker compose up -d\n");
|
|
173
|
+
}
|
|
174
|
+
// ── Helpers ──────────────────────────────────────────────────────
|
|
175
|
+
function isNewer(latest, current) {
|
|
176
|
+
const [lMaj, lMin, lPatch] = latest.split(".").map(Number);
|
|
177
|
+
const [cMaj, cMin, cPatch] = current.split(".").map(Number);
|
|
178
|
+
if (lMaj !== cMaj)
|
|
179
|
+
return lMaj > cMaj;
|
|
180
|
+
if (lMin !== cMin)
|
|
181
|
+
return lMin > cMin;
|
|
182
|
+
return lPatch > cPatch;
|
|
183
|
+
}
|
|
184
|
+
function isRunningAsService() {
|
|
185
|
+
// launchd/systemd/Windows Service detection heuristics
|
|
186
|
+
return (!!process.env.INVOCATION_ID || // systemd
|
|
187
|
+
process.ppid === 1 || // launchd (parent is launchd PID 1)
|
|
188
|
+
!!process.env.TADAIMA_SERVICE // explicit flag
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=updater.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"updater.js","sourceRoot":"","sources":["../src/updater.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
type MessageHandler = (message: Record<string, unknown>) => void;
|
|
2
|
+
export declare class AgentWebSocket {
|
|
3
|
+
private ws;
|
|
4
|
+
private backoff;
|
|
5
|
+
private heartbeatTimer;
|
|
6
|
+
private reconnectTimer;
|
|
7
|
+
private messageQueue;
|
|
8
|
+
private onMessage;
|
|
9
|
+
private stopped;
|
|
10
|
+
private startTime;
|
|
11
|
+
private activeJobs;
|
|
12
|
+
connect(): void;
|
|
13
|
+
stop(): void;
|
|
14
|
+
setMessageHandler(handler: MessageHandler): void;
|
|
15
|
+
send(message: Record<string, unknown>): void;
|
|
16
|
+
setActiveJobs(count: number): void;
|
|
17
|
+
private sendHello;
|
|
18
|
+
private sendHeartbeat;
|
|
19
|
+
private startHeartbeat;
|
|
20
|
+
private stopHeartbeat;
|
|
21
|
+
private drainQueue;
|
|
22
|
+
private cleanup;
|
|
23
|
+
private scheduleReconnect;
|
|
24
|
+
}
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=ws-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ws-client.d.ts","sourceRoot":"","sources":["../src/ws-client.ts"],"names":[],"mappings":"AAQA,KAAK,cAAc,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;AAEjE,qBAAa,cAAc;IACzB,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,cAAc,CAA+C;IACrE,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,YAAY,CAAgB;IACpC,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,UAAU,CAAK;IAEvB,OAAO,IAAI,IAAI;IAkDf,IAAI,IAAI,IAAI;IASZ,iBAAiB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAIhD,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAgB5C,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAIlC,OAAO,CAAC,SAAS;IAcjB,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,OAAO;IAQf,OAAO,CAAC,iBAAiB;CAM1B"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import WebSocket from "ws";
|
|
2
|
+
import { platform, freemem } from "node:os";
|
|
3
|
+
import { createMessageId, createTimestamp } from "@tadaima/shared";
|
|
4
|
+
import { config } from "./config.js";
|
|
5
|
+
const HEARTBEAT_INTERVAL = 30_000;
|
|
6
|
+
const MAX_BACKOFF = 30_000;
|
|
7
|
+
export class AgentWebSocket {
|
|
8
|
+
ws = null;
|
|
9
|
+
backoff = 1000;
|
|
10
|
+
heartbeatTimer = null;
|
|
11
|
+
reconnectTimer = null;
|
|
12
|
+
messageQueue = [];
|
|
13
|
+
onMessage = null;
|
|
14
|
+
stopped = false;
|
|
15
|
+
startTime = Date.now();
|
|
16
|
+
activeJobs = 0;
|
|
17
|
+
connect() {
|
|
18
|
+
this.stopped = false;
|
|
19
|
+
const relayUrl = config.get("relay");
|
|
20
|
+
const deviceToken = config.get("deviceToken");
|
|
21
|
+
if (!relayUrl || !deviceToken) {
|
|
22
|
+
console.error("Not configured. Run `tadaima-agent setup` first.");
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const wsUrl = relayUrl
|
|
26
|
+
.replace(/^http/, "ws")
|
|
27
|
+
.replace(/\/$/, "");
|
|
28
|
+
const url = `${wsUrl}/ws/agent?token=${deviceToken}`;
|
|
29
|
+
this.ws = new WebSocket(url);
|
|
30
|
+
this.ws.on("open", () => {
|
|
31
|
+
console.log("Connected to relay");
|
|
32
|
+
this.backoff = 1000;
|
|
33
|
+
this.sendHello();
|
|
34
|
+
this.startHeartbeat();
|
|
35
|
+
this.drainQueue();
|
|
36
|
+
});
|
|
37
|
+
this.ws.on("message", (data) => {
|
|
38
|
+
try {
|
|
39
|
+
const msg = JSON.parse(data.toString());
|
|
40
|
+
if (this.onMessage) {
|
|
41
|
+
this.onMessage(msg);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
const raw = data.toString().slice(0, 200);
|
|
46
|
+
console.error("Failed to parse WebSocket message:", err, "raw:", raw);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
this.ws.on("close", () => {
|
|
50
|
+
console.log("Disconnected from relay");
|
|
51
|
+
this.cleanup();
|
|
52
|
+
this.scheduleReconnect();
|
|
53
|
+
});
|
|
54
|
+
this.ws.on("error", (err) => {
|
|
55
|
+
console.error("WebSocket error:", err.message);
|
|
56
|
+
this.cleanup();
|
|
57
|
+
this.scheduleReconnect();
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
stop() {
|
|
61
|
+
this.stopped = true;
|
|
62
|
+
this.cleanup();
|
|
63
|
+
if (this.ws) {
|
|
64
|
+
this.ws.close(1000, "Agent stopped");
|
|
65
|
+
this.ws = null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
setMessageHandler(handler) {
|
|
69
|
+
this.onMessage = handler;
|
|
70
|
+
}
|
|
71
|
+
send(message) {
|
|
72
|
+
const data = JSON.stringify(message);
|
|
73
|
+
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
|
74
|
+
try {
|
|
75
|
+
this.ws.send(data);
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
console.error("Send failed, re-queuing message:", err);
|
|
79
|
+
this.messageQueue.push(data);
|
|
80
|
+
this.cleanup();
|
|
81
|
+
this.scheduleReconnect();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
this.messageQueue.push(data);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
setActiveJobs(count) {
|
|
89
|
+
this.activeJobs = count;
|
|
90
|
+
}
|
|
91
|
+
sendHello() {
|
|
92
|
+
this.send({
|
|
93
|
+
id: createMessageId(),
|
|
94
|
+
type: "agent:hello",
|
|
95
|
+
timestamp: createTimestamp(),
|
|
96
|
+
payload: {
|
|
97
|
+
version: "0.0.0",
|
|
98
|
+
platform: platform(),
|
|
99
|
+
activeJobs: this.activeJobs,
|
|
100
|
+
diskFreeBytes: freemem(),
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
sendHeartbeat() {
|
|
105
|
+
this.send({
|
|
106
|
+
id: createMessageId(),
|
|
107
|
+
type: "agent:heartbeat",
|
|
108
|
+
timestamp: createTimestamp(),
|
|
109
|
+
payload: {
|
|
110
|
+
activeJobs: this.activeJobs,
|
|
111
|
+
diskFreeBytes: freemem(),
|
|
112
|
+
uptimeSeconds: Math.floor((Date.now() - this.startTime) / 1000),
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
startHeartbeat() {
|
|
117
|
+
this.stopHeartbeat();
|
|
118
|
+
this.heartbeatTimer = setInterval(() => this.sendHeartbeat(), HEARTBEAT_INTERVAL);
|
|
119
|
+
}
|
|
120
|
+
stopHeartbeat() {
|
|
121
|
+
if (this.heartbeatTimer) {
|
|
122
|
+
clearInterval(this.heartbeatTimer);
|
|
123
|
+
this.heartbeatTimer = null;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
drainQueue() {
|
|
127
|
+
while (this.messageQueue.length > 0 && this.ws?.readyState === WebSocket.OPEN) {
|
|
128
|
+
try {
|
|
129
|
+
this.ws.send(this.messageQueue[0]);
|
|
130
|
+
this.messageQueue.shift();
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
console.error("Drain failed, will retry on reconnect:", err);
|
|
134
|
+
this.cleanup();
|
|
135
|
+
this.scheduleReconnect();
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
cleanup() {
|
|
141
|
+
this.stopHeartbeat();
|
|
142
|
+
if (this.reconnectTimer) {
|
|
143
|
+
clearTimeout(this.reconnectTimer);
|
|
144
|
+
this.reconnectTimer = null;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
scheduleReconnect() {
|
|
148
|
+
if (this.stopped)
|
|
149
|
+
return;
|
|
150
|
+
this.backoff = Math.min(this.backoff * 2, MAX_BACKOFF);
|
|
151
|
+
console.log(`Reconnecting in ${this.backoff / 1000}s...`);
|
|
152
|
+
this.reconnectTimer = setTimeout(() => this.connect(), this.backoff);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=ws-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ws-client.js","sourceRoot":"","sources":["../src/ws-client.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@psychout98/tadaima",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CLI download agent for Tadaima — a self-hosted media download orchestrator",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/psychout98/tadaima.git",
|
|
10
|
+
"directory": "packages/agent"
|
|
11
|
+
},
|
|
12
|
+
"keywords": ["tadaima", "media", "download", "plex", "real-debrid", "agent"],
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=18"
|
|
15
|
+
},
|
|
16
|
+
"bin": {
|
|
17
|
+
"tadaima": "dist/index.js"
|
|
18
|
+
},
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"import": "./dist/index.js",
|
|
23
|
+
"default": "./dist/index.js"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist",
|
|
28
|
+
"README.md"
|
|
29
|
+
],
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public"
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "tsc",
|
|
35
|
+
"dev": "tsx watch src/index.ts",
|
|
36
|
+
"lint": "eslint src/ --ignore-pattern src/__tests__/",
|
|
37
|
+
"test": "vitest run",
|
|
38
|
+
"typecheck": "tsc --noEmit",
|
|
39
|
+
"start": "node dist/index.js",
|
|
40
|
+
"compile": "pnpm run compile:all",
|
|
41
|
+
"compile:darwin-arm64": "bun build src/index.ts --compile --target=bun-darwin-arm64 --outfile=dist/tadaima-agent-darwin-arm64",
|
|
42
|
+
"compile:darwin-x64": "bun build src/index.ts --compile --target=bun-darwin-x64 --outfile=dist/tadaima-agent-darwin-x64",
|
|
43
|
+
"compile:win-x64": "bun build src/index.ts --compile --target=bun-windows-x64 --outfile=dist/tadaima-agent-win-x64.exe",
|
|
44
|
+
"compile:linux-x64": "bun build src/index.ts --compile --target=bun-linux-x64 --outfile=dist/tadaima-agent-linux-x64",
|
|
45
|
+
"compile:all": "pnpm run compile:darwin-arm64 && pnpm run compile:darwin-x64 && pnpm run compile:win-x64 && pnpm run compile:linux-x64",
|
|
46
|
+
"compile:checksums": "cd dist && shasum -a 256 tadaima-agent-* > checksums.sha256"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"@tadaima/shared": "workspace:*",
|
|
50
|
+
"conf": "^15.1.0",
|
|
51
|
+
"prompts": "^2.4.2",
|
|
52
|
+
"ws": "^8.20.0"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@types/node": "^25.5.2",
|
|
56
|
+
"@types/prompts": "^2.4.9",
|
|
57
|
+
"@types/ws": "^8.18.1",
|
|
58
|
+
"tsx": "^4.19.0",
|
|
59
|
+
"typescript": "^5.7.0",
|
|
60
|
+
"vitest": "^4.1.2"
|
|
61
|
+
}
|
|
62
|
+
}
|