@vhyxvoid/agent 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.
Files changed (37) hide show
  1. package/dist/AgentClient.d.ts +70 -0
  2. package/dist/AgentClient.d.ts.map +1 -0
  3. package/dist/AgentClient.js +261 -0
  4. package/dist/AgentClient.js.map +1 -0
  5. package/dist/batcher/MessageBatcher.d.ts +40 -0
  6. package/dist/batcher/MessageBatcher.d.ts.map +1 -0
  7. package/dist/batcher/MessageBatcher.js +86 -0
  8. package/dist/batcher/MessageBatcher.js.map +1 -0
  9. package/dist/cache/ResponseCache.d.ts +50 -0
  10. package/dist/cache/ResponseCache.d.ts.map +1 -0
  11. package/dist/cache/ResponseCache.js +127 -0
  12. package/dist/cache/ResponseCache.js.map +1 -0
  13. package/dist/cli.d.ts +3 -0
  14. package/dist/cli.d.ts.map +1 -0
  15. package/dist/cli.js +106 -0
  16. package/dist/cli.js.map +1 -0
  17. package/dist/discovery/LocalDiscoveryServer.d.ts +24 -0
  18. package/dist/discovery/LocalDiscoveryServer.d.ts.map +1 -0
  19. package/dist/discovery/LocalDiscoveryServer.js +58 -0
  20. package/dist/discovery/LocalDiscoveryServer.js.map +1 -0
  21. package/dist/index.d.ts +13 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +21 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/proxy/BackendProxy.d.ts +19 -0
  26. package/dist/proxy/BackendProxy.d.ts.map +1 -0
  27. package/dist/proxy/BackendProxy.js +122 -0
  28. package/dist/proxy/BackendProxy.js.map +1 -0
  29. package/dist/queue/DurableQueue.d.ts +37 -0
  30. package/dist/queue/DurableQueue.d.ts.map +1 -0
  31. package/dist/queue/DurableQueue.js +142 -0
  32. package/dist/queue/DurableQueue.js.map +1 -0
  33. package/dist/replay/replayQueue.d.ts +11 -0
  34. package/dist/replay/replayQueue.d.ts.map +1 -0
  35. package/dist/replay/replayQueue.js +58 -0
  36. package/dist/replay/replayQueue.js.map +1 -0
  37. package/package.json +39 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResponseCache.js","sourceRoot":"","sources":["../../src/cache/ResponseCache.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,106 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ // packages/agent/src/cli.ts
4
+ // CLI entry point: npx @vhyxvoid/agent
5
+ var __importDefault = (this && this.__importDefault) || function (mod) {
6
+ return (mod && mod.__esModule) ? mod : { "default": mod };
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ const commander_1 = require("commander");
10
+ const AgentClient_1 = require("./AgentClient");
11
+ const crypto_1 = __importDefault(require("crypto"));
12
+ const package_json_1 = require("../package.json");
13
+ const program = new commander_1.Command();
14
+ program
15
+ .name("vhyxvoid")
16
+ .description("Platform tunnel agent.\n" +
17
+ "Connects your local server to the platform so the frontend SDK can reach it.")
18
+ .version(package_json_1.version)
19
+ .option("-k, --key <keyId>", "API key ID (e.g. vhyxvoid_dev_abc123). Env: VHYXVOID_API_KEY", process.env.VHYXVOID_API_KEY)
20
+ .option("-s, --secret <secret>", "API key secret (shown once at creation). Env: VHYXVOID_SECRET", process.env.VHYXVOID_SECRET)
21
+ .option("-p, --port <port>", "Local backend port to tunnel (e.g. 3000). Env: VHYXVOID_PORT", process.env.VHYXVOID_PORT ?? "3000")
22
+ .option("-l, --label <label>", "Tunnel label — identifies this agent if you run multiple. Env: VHYXVOID_LABEL", process.env.VHYXVOID_LABEL ?? "default")
23
+ .option("--hub <url>", "Hub WebSocket URL. Env: VHYXVOID_HUB_URL", process.env.VHYXVOID_HUB_URL ?? "wss://hub.yourplatform.com/agent")
24
+ .option("--pepper <pepper>", "Server HMAC pepper (from platform settings). Env: SERVER_HMAC_PEPPER", process.env.SERVER_HMAC_PEPPER ?? "")
25
+ .option("--queue-path <path>", "SQLite queue file path. Default: ~/.vhyxvoid/queue.db", process.env.VHYXVOID_QUEUE_PATH)
26
+ .option("--no-local-discovery", "Disable local discovery server on port 4242")
27
+ .parse(process.argv);
28
+ const opts = program.opts();
29
+ // ── Validate required options ─────────────────────────────────────────────────
30
+ if (!opts.key) {
31
+ console.error("❌ --key is required. Get your API key from the platform dashboard.");
32
+ console.error(" Usage: vhyxvoid --key vhyxvoid_dev_xxx --secret xxx --port 3000");
33
+ process.exit(1);
34
+ }
35
+ if (!opts.secret) {
36
+ console.error("❌ --secret is required. It was shown once when you created the API key.");
37
+ console.error(" If you lost it, rotate the key from the dashboard to get a new secret.");
38
+ process.exit(1);
39
+ }
40
+ // ── Hash the secret ───────────────────────────────────────────────────────────
41
+ // The agent hashes the raw secret on startup using the server pepper.
42
+ // After this point, the raw secret is never kept in memory.
43
+ // secretHash = HMAC-SHA256(rawSecret, pepper)
44
+ // This matches how the Hub and API key module hash secrets in the database.
45
+ const pepper = opts.pepper;
46
+ const secretHash = pepper
47
+ ? crypto_1.default.createHmac("sha256", pepper).update(opts.secret).digest("hex")
48
+ : crypto_1.default.createHmac("sha256", "dev-pepper").update(opts.secret).digest("hex");
49
+ if (!pepper) {
50
+ console.warn("⚠ --pepper not set. Using dev-pepper — this will not work in production.\n" +
51
+ " Set SERVER_HMAC_PEPPER to match the value in your hub environment.");
52
+ }
53
+ // ── Start agent ───────────────────────────────────────────────────────────────
54
+ const port = parseInt(opts.port, 10);
55
+ if (isNaN(port) || port < 1 || port > 65535) {
56
+ console.error(`❌ Invalid port: "${opts.port}"`);
57
+ process.exit(1);
58
+ }
59
+ console.log(`\nvhyxvoid-agent v${package_json_1.version}`);
60
+ console.log(` Key: ${opts.key}`);
61
+ console.log(` Label: ${opts.label}`);
62
+ console.log(` Port: ${port}`);
63
+ console.log(` Hub: ${opts.hub}`);
64
+ console.log(` Queue: ${opts.queuePath ?? "~/.vhyxvoid/queue.db"}`);
65
+ console.log(` Local discovery: ${opts.localDiscovery ? "enabled" : "disabled"}`);
66
+ console.log("");
67
+ const agent = new AgentClient_1.AgentClient({
68
+ hubUrl: opts.hub,
69
+ keyId: opts.key,
70
+ secretHash,
71
+ label: opts.label,
72
+ port,
73
+ agentVersion: package_json_1.version,
74
+ queuePath: opts.queuePath,
75
+ localDiscovery: opts.localDiscovery,
76
+ onStateChange: (state) => {
77
+ if (state === "CONNECTED") {
78
+ console.log(`✅ Tunnel active — label "${opts.label}" → localhost:${port}`);
79
+ console.log(` SDK requests with label "${opts.label}" will reach your backend.\n`);
80
+ }
81
+ if (state === "RECONNECTING") {
82
+ console.log("⚠ Disconnected from hub — reconnecting automatically...");
83
+ }
84
+ if (state === "STOPPED") {
85
+ console.log("🛑 Agent stopped.");
86
+ }
87
+ },
88
+ });
89
+ agent.start();
90
+ // ── Graceful shutdown ─────────────────────────────────────────────────────────
91
+ process.on("SIGTERM", () => {
92
+ console.log("\nReceived SIGTERM — shutting down gracefully...");
93
+ agent.stop();
94
+ process.exit(0);
95
+ });
96
+ process.on("SIGINT", () => {
97
+ console.log("\nReceived SIGINT — shutting down gracefully...");
98
+ agent.stop();
99
+ process.exit(0);
100
+ });
101
+ process.on("uncaughtException", (err) => {
102
+ console.error("Uncaught exception:", err);
103
+ agent.stop();
104
+ process.exit(1);
105
+ });
106
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ export interface DiscoveryPayload {
2
+ /** npm package version */
3
+ agentVersion: string;
4
+ /** Tunnel label */
5
+ label: string;
6
+ /** Local backend port the agent is proxying to */
7
+ port: number;
8
+ /**
9
+ * SHA-256 of accountId — lets SDK verify it's talking to an agent for the same account
10
+ * without exposing the actual accountId over the local network.
11
+ * Populated after hub:registered is received.
12
+ */
13
+ accountIdHash: string;
14
+ }
15
+ export declare class LocalDiscoveryServer {
16
+ private server;
17
+ private payload;
18
+ constructor(payload: DiscoveryPayload);
19
+ /** Update the accountIdHash after hub registration completes */
20
+ setAccountIdHash(hash: string): void;
21
+ start(): void;
22
+ stop(): void;
23
+ }
24
+ //# sourceMappingURL=LocalDiscoveryServer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalDiscoveryServer.d.ts","sourceRoot":"","sources":["../../src/discovery/LocalDiscoveryServer.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,gBAAgB;IAC/B,0BAA0B;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,OAAO,CAAmB;gBAEtB,OAAO,EAAE,gBAAgB;IAIrC,gEAAgE;IAChE,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIpC,KAAK,IAAI,IAAI;IAqCb,IAAI,IAAI,IAAI;CAIb"}
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ // packages/agent/src/discovery/LocalDiscoveryServer.ts
3
+ // Broadcasts agent presence on localhost:4242.
4
+ // SDK discovers this and bypasses Hub for local-to-local calls (<1ms overhead).
5
+ var __importDefault = (this && this.__importDefault) || function (mod) {
6
+ return (mod && mod.__esModule) ? mod : { "default": mod };
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.LocalDiscoveryServer = void 0;
10
+ const http_1 = __importDefault(require("http"));
11
+ const protocol_1 = require("@vhyxvoid/protocol");
12
+ class LocalDiscoveryServer {
13
+ server = null;
14
+ payload;
15
+ constructor(payload) {
16
+ this.payload = payload;
17
+ }
18
+ /** Update the accountIdHash after hub registration completes */
19
+ setAccountIdHash(hash) {
20
+ this.payload = { ...this.payload, accountIdHash: hash };
21
+ }
22
+ start() {
23
+ this.server = http_1.default.createServer((req, res) => {
24
+ // Only respond to the discovery endpoint
25
+ if (req.url !== "/vhyxvoid" || req.method !== "GET") {
26
+ res.writeHead(404).end();
27
+ return;
28
+ }
29
+ const body = JSON.stringify(this.payload);
30
+ res.writeHead(200, {
31
+ "Content-Type": "application/json",
32
+ "Content-Length": Buffer.byteLength(body).toString(),
33
+ "Cache-Control": "no-cache",
34
+ });
35
+ res.end(body);
36
+ });
37
+ this.server.listen(protocol_1.LIMITS.LOCAL_AGENT_DISCOVERY_PORT, "127.0.0.1", () => {
38
+ console.info(`[discovery] local discovery server ready on port ${protocol_1.LIMITS.LOCAL_AGENT_DISCOVERY_PORT}`);
39
+ });
40
+ this.server.on("error", (err) => {
41
+ if (err.code === "EADDRINUSE") {
42
+ // Non-fatal — another agent instance may be running
43
+ console.warn(`[discovery] port ${protocol_1.LIMITS.LOCAL_AGENT_DISCOVERY_PORT} in use — ` +
44
+ `local discovery disabled. Another agent may already be running.`);
45
+ }
46
+ else {
47
+ console.warn(`[discovery] server error: ${err.message}`);
48
+ }
49
+ // Local discovery is an optimization, not required — never crash here
50
+ });
51
+ }
52
+ stop() {
53
+ this.server?.close();
54
+ this.server = null;
55
+ }
56
+ }
57
+ exports.LocalDiscoveryServer = LocalDiscoveryServer;
58
+ //# sourceMappingURL=LocalDiscoveryServer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalDiscoveryServer.js","sourceRoot":"","sources":["../../src/discovery/LocalDiscoveryServer.ts"],"names":[],"mappings":";AAAA,uDAAuD;AACvD,+CAA+C;AAC/C,gFAAgF;;;;;;AAEhF,gDAAwB;AACxB,iDAA4C;AAiB5C,MAAa,oBAAoB;IACvB,MAAM,GAAuB,IAAI,CAAC;IAClC,OAAO,CAAmB;IAElC,YAAY,OAAyB;QACnC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,gEAAgE;IAChE,gBAAgB,CAAC,IAAY;QAC3B,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;IAC1D,CAAC;IAED,KAAK;QACH,IAAI,CAAC,MAAM,GAAG,cAAI,CAAC,YAAY,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YAC3C,yCAAyC;YACzC,IAAI,GAAG,CAAC,GAAG,KAAK,WAAW,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;gBACpD,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;gBACzB,OAAO;YACT,CAAC;YAED,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC1C,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;gBACjB,cAAc,EAAE,kBAAkB;gBAClC,gBAAgB,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE;gBACpD,eAAe,EAAE,UAAU;aAC5B,CAAC,CAAC;YACH,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,iBAAM,CAAC,0BAA0B,EAAE,WAAW,EAAE,GAAG,EAAE;YACtE,OAAO,CAAC,IAAI,CACV,oDAAoD,iBAAM,CAAC,0BAA0B,EAAE,CACxF,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAA0B,EAAE,EAAE;YACrD,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBAC9B,oDAAoD;gBACpD,OAAO,CAAC,IAAI,CACV,oBAAoB,iBAAM,CAAC,0BAA0B,YAAY;oBAC/D,iEAAiE,CACpE,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,6BAA6B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YAC3D,CAAC;YACD,sEAAsE;QACxE,CAAC,CAAC,CAAC;IACL,CAAC;IAED,IAAI;QACF,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACrB,CAAC;CACF;AAtDD,oDAsDC"}
@@ -0,0 +1,13 @@
1
+ export { AgentClient } from "./AgentClient";
2
+ export type { AgentConfig, AgentState } from "./AgentClient";
3
+ export { DurableQueue } from "./queue/DurableQueue";
4
+ export type { QueueItem, QueueDirection } from "./queue/DurableQueue";
5
+ export { BackendProxy } from "./proxy/BackendProxy";
6
+ export { ResponseCache } from "./cache/ResponseCache";
7
+ export type { CachedResponse } from "./cache/ResponseCache";
8
+ export { MessageBatcher } from "./batcher/MessageBatcher";
9
+ export { replayQueue } from "./replay/replayQueue";
10
+ export type { ReplayResult } from "./replay/replayQueue";
11
+ export { LocalDiscoveryServer } from "./discovery/LocalDiscoveryServer";
12
+ export type { DiscoveryPayload } from "./discovery/LocalDiscoveryServer";
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,YAAY,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AACxE,YAAY,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ // packages/agent/src/index.ts
3
+ // Public API of the agent package when imported as a library (not CLI).
4
+ // Consumers who want to embed the agent in their own process import from here.
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.LocalDiscoveryServer = exports.replayQueue = exports.MessageBatcher = exports.ResponseCache = exports.BackendProxy = exports.DurableQueue = exports.AgentClient = void 0;
7
+ var AgentClient_1 = require("./AgentClient");
8
+ Object.defineProperty(exports, "AgentClient", { enumerable: true, get: function () { return AgentClient_1.AgentClient; } });
9
+ var DurableQueue_1 = require("./queue/DurableQueue");
10
+ Object.defineProperty(exports, "DurableQueue", { enumerable: true, get: function () { return DurableQueue_1.DurableQueue; } });
11
+ var BackendProxy_1 = require("./proxy/BackendProxy");
12
+ Object.defineProperty(exports, "BackendProxy", { enumerable: true, get: function () { return BackendProxy_1.BackendProxy; } });
13
+ var ResponseCache_1 = require("./cache/ResponseCache");
14
+ Object.defineProperty(exports, "ResponseCache", { enumerable: true, get: function () { return ResponseCache_1.ResponseCache; } });
15
+ var MessageBatcher_1 = require("./batcher/MessageBatcher");
16
+ Object.defineProperty(exports, "MessageBatcher", { enumerable: true, get: function () { return MessageBatcher_1.MessageBatcher; } });
17
+ var replayQueue_1 = require("./replay/replayQueue");
18
+ Object.defineProperty(exports, "replayQueue", { enumerable: true, get: function () { return replayQueue_1.replayQueue; } });
19
+ var LocalDiscoveryServer_1 = require("./discovery/LocalDiscoveryServer");
20
+ Object.defineProperty(exports, "LocalDiscoveryServer", { enumerable: true, get: function () { return LocalDiscoveryServer_1.LocalDiscoveryServer; } });
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,8BAA8B;AAC9B,wEAAwE;AACxE,+EAA+E;;;AAE/E,6CAA4C;AAAnC,0GAAA,WAAW,OAAA;AAEpB,qDAAoD;AAA3C,4GAAA,YAAY,OAAA;AAErB,qDAAoD;AAA3C,4GAAA,YAAY,OAAA;AACrB,uDAAsD;AAA7C,8GAAA,aAAa,OAAA;AAEtB,2DAA0D;AAAjD,gHAAA,cAAc,OAAA;AACvB,oDAAmD;AAA1C,0GAAA,WAAW,OAAA;AAEpB,yEAAwE;AAA/D,4HAAA,oBAAoB,OAAA"}
@@ -0,0 +1,19 @@
1
+ import { TunnelForwardMsg, TunnelResponseMsg } from "@vhyxvoid/protocol";
2
+ export declare class BackendProxy {
3
+ private readonly port;
4
+ private readonly client;
5
+ private readonly cache;
6
+ private evictTimer;
7
+ constructor(port: number);
8
+ forward(msg: TunnelForwardMsg): Promise<Omit<TunnelResponseMsg, "v" | "type" | "requestId">>;
9
+ /** Invalidate cached GETs related to a mutating request path */
10
+ invalidateCacheFor(method: string, path: string): void;
11
+ getCacheStats(): {
12
+ size: number;
13
+ totalHits: number;
14
+ };
15
+ stop(): void;
16
+ private sanitizeInboundHeaders;
17
+ private sanitizeOutboundHeaders;
18
+ }
19
+ //# sourceMappingURL=BackendProxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BackendProxy.d.ts","sourceRoot":"","sources":["../../src/proxy/BackendProxy.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EAElB,MAAM,oBAAoB,CAAC;AAiB5B,qBAAa,YAAY;IAKX,OAAO,CAAC,QAAQ,CAAC,IAAI;IAJjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAuB;IAC7C,OAAO,CAAC,UAAU,CAA+B;gBAEpB,IAAI,EAAE,MAAM;IAoBnC,OAAO,CACX,GAAG,EAAE,gBAAgB,GACpB,OAAO,CAAC,IAAI,CAAC,iBAAiB,EAAE,GAAG,GAAG,MAAM,GAAG,WAAW,CAAC,CAAC;IA8C/D,gEAAgE;IAChE,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAQtD,aAAa;;;;IAIb,IAAI,IAAI,IAAI;IAQZ,OAAO,CAAC,sBAAsB;IAY9B,OAAO,CAAC,uBAAuB;CAUhC"}
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ // packages/agent/src/proxy/BackendProxy.ts
3
+ // HTTP client to localhost. Never throws — always returns a response.
4
+ // Uses axios with validateStatus: () => true so 4xx/5xx pass through.
5
+ var __importDefault = (this && this.__importDefault) || function (mod) {
6
+ return (mod && mod.__esModule) ? mod : { "default": mod };
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.BackendProxy = void 0;
10
+ const axios_1 = __importDefault(require("axios"));
11
+ const protocol_1 = require("@vhyxvoid/protocol");
12
+ const ResponseCache_1 = require("../cache/ResponseCache");
13
+ const HOP_BY_HOP = new Set([
14
+ "connection",
15
+ "keep-alive",
16
+ "proxy-authenticate",
17
+ "proxy-authorization",
18
+ "te",
19
+ "trailers",
20
+ "transfer-encoding",
21
+ "upgrade",
22
+ ]);
23
+ // Evict expired cache entries every 60 seconds
24
+ const CACHE_EVICT_INTERVAL_MS = 60_000;
25
+ class BackendProxy {
26
+ port;
27
+ client;
28
+ cache = new ResponseCache_1.ResponseCache();
29
+ evictTimer = null;
30
+ constructor(port) {
31
+ this.port = port;
32
+ this.client = axios_1.default.create({
33
+ baseURL: `http://127.0.0.1:${port}`,
34
+ timeout: 28_000,
35
+ maxContentLength: protocol_1.LIMITS.MAX_PAYLOAD_BYTES,
36
+ maxBodyLength: protocol_1.LIMITS.MAX_PAYLOAD_BYTES,
37
+ validateStatus: () => true,
38
+ decompress: true,
39
+ responseType: "arraybuffer",
40
+ });
41
+ // Periodic cache eviction
42
+ this.evictTimer = setInterval(() => this.cache.evictExpired(), CACHE_EVICT_INTERVAL_MS);
43
+ // Don't prevent process exit
44
+ this.evictTimer.unref?.();
45
+ }
46
+ async forward(msg) {
47
+ // ── Cache check (GET only) ────────────────────────────────────────────────
48
+ const cached = this.cache.get(msg.method, msg.path, msg.query);
49
+ if (cached) {
50
+ return {
51
+ status: cached.status,
52
+ headers: { ...cached.headers, "x-vhyxvoid-cache": "HIT" },
53
+ body: cached.body,
54
+ durationMs: 0, // served from memory
55
+ };
56
+ }
57
+ // ── Real HTTP request ─────────────────────────────────────────────────────
58
+ const start = Date.now();
59
+ const url = msg.path + (msg.query ? `?${msg.query}` : "");
60
+ const response = await this.client.request({
61
+ method: msg.method,
62
+ url,
63
+ headers: this.sanitizeInboundHeaders(msg.headers),
64
+ data: msg.body ?? undefined,
65
+ });
66
+ const bodyBuffer = response.data;
67
+ const bodyStr = bodyBuffer.length > 0 ? bodyBuffer.toString("utf8") : null;
68
+ const headers = this.sanitizeOutboundHeaders(response.headers);
69
+ const durationMs = Date.now() - start;
70
+ // ── Store in cache if cacheable ───────────────────────────────────────────
71
+ this.cache.set(msg.method, msg.path, msg.query, {
72
+ status: response.status,
73
+ headers,
74
+ body: bodyStr,
75
+ durationMs,
76
+ });
77
+ return {
78
+ status: response.status,
79
+ headers: { ...headers, "x-vhyxvoid-cache": "MISS" },
80
+ body: bodyStr,
81
+ durationMs,
82
+ };
83
+ }
84
+ /** Invalidate cached GETs related to a mutating request path */
85
+ invalidateCacheFor(method, path) {
86
+ if (["POST", "PUT", "PATCH", "DELETE"].includes(method.toUpperCase())) {
87
+ // Invalidate the base path and common related paths
88
+ const basePath = path.split("/").slice(0, -1).join("/");
89
+ this.cache.invalidatePrefix(basePath || path);
90
+ }
91
+ }
92
+ getCacheStats() {
93
+ return this.cache.stats();
94
+ }
95
+ stop() {
96
+ if (this.evictTimer) {
97
+ clearInterval(this.evictTimer);
98
+ this.evictTimer = null;
99
+ }
100
+ this.cache.clear();
101
+ }
102
+ sanitizeInboundHeaders(headers) {
103
+ const clean = {};
104
+ for (const [k, v] of Object.entries(headers)) {
105
+ if (!HOP_BY_HOP.has(k.toLowerCase()))
106
+ clean[k] = v;
107
+ }
108
+ clean["x-forwarded-by"] = "vhyxvoid";
109
+ clean["x-forwarded-host"] = `127.0.0.1:${this.port}`;
110
+ return clean;
111
+ }
112
+ sanitizeOutboundHeaders(headers) {
113
+ const clean = {};
114
+ for (const [k, v] of Object.entries(headers)) {
115
+ if (!HOP_BY_HOP.has(k.toLowerCase()) && typeof v === "string")
116
+ clean[k] = v;
117
+ }
118
+ return clean;
119
+ }
120
+ }
121
+ exports.BackendProxy = BackendProxy;
122
+ //# sourceMappingURL=BackendProxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BackendProxy.js","sourceRoot":"","sources":["../../src/proxy/BackendProxy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import { TunnelForwardMsg, TunnelResponseMsg, TunnelAgentErrorMsg } from "@vhyxvoid/protocol";
2
+ export type QueueDirection = "inbound" | "outbound";
3
+ export interface QueueItem {
4
+ id: string;
5
+ direction: QueueDirection;
6
+ payload: string;
7
+ ts: number;
8
+ attempts: number;
9
+ maxAttempts: number;
10
+ nextRetryAt: number;
11
+ }
12
+ export type InboundPayload = TunnelForwardMsg;
13
+ export type OutboundPayload = TunnelResponseMsg | TunnelAgentErrorMsg;
14
+ export declare class DurableQueue {
15
+ private readonly db;
16
+ constructor(dbPath: string);
17
+ private migrate;
18
+ enqueueInbound(payload: InboundPayload): void;
19
+ enqueueOutbound(payload: OutboundPayload): void;
20
+ /**
21
+ * Returns all items ready for replay, ordered:
22
+ * 1. OUTBOUND first (send cached responses before processing new requests)
23
+ * 2. Within same direction: oldest first (preserve request ordering)
24
+ */
25
+ drainForReplay(): QueueItem[];
26
+ markSuccess(id: string): void;
27
+ markFailed(id: string): void;
28
+ count(): {
29
+ ready: number;
30
+ pending: number;
31
+ deadLetter: number;
32
+ };
33
+ /** Drain dead letter for inspection. Returns last N items. */
34
+ deadLetterItems(limit?: number): QueueItem[];
35
+ close(): void;
36
+ }
37
+ //# sourceMappingURL=DurableQueue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DurableQueue.d.ts","sourceRoot":"","sources":["../../src/queue/DurableQueue.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACpB,MAAM,oBAAoB,CAAC;AAG5B,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,UAAU,CAAC;AAEpD,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,cAAc,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,cAAc,GAAG,gBAAgB,CAAC;AAC9C,MAAM,MAAM,eAAe,GAAG,iBAAiB,GAAG,mBAAmB,CAAC;AAEtE,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAoB;gBAE3B,MAAM,EAAE,MAAM;IAS1B,OAAO,CAAC,OAAO;IA8Bf,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAgB7C,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI;IAgB/C;;;;OAIG;IACH,cAAc,IAAI,SAAS,EAAE;IAe7B,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAI7B,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IA0C5B,KAAK,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE;IAkB/D,8DAA8D;IAC9D,eAAe,CAAC,KAAK,SAAK,GAAG,SAAS,EAAE;IAWxC,KAAK,IAAI,IAAI;CAGd"}
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ // packages/agent/src/queue/DurableQueue.ts
3
+ // SQLite-backed durable queue. Single source of truth for all pending messages.
4
+ // WAL mode: survives process crashes without corruption.
5
+ // Never shares storage with batching — batcher is in-memory only.
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.DurableQueue = void 0;
11
+ const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
12
+ const crypto_1 = require("crypto");
13
+ const protocol_1 = require("@vhyxvoid/protocol");
14
+ class DurableQueue {
15
+ db;
16
+ constructor(dbPath) {
17
+ this.db = new better_sqlite3_1.default(dbPath);
18
+ this.db.pragma("journal_mode = WAL"); // crash-safe: writes go to WAL file first
19
+ this.db.pragma("synchronous = NORMAL"); // balanced: fsync on WAL checkpoint only
20
+ this.db.pragma("foreign_keys = ON");
21
+ this.db.pragma("busy_timeout = 5000"); // wait up to 5s on lock contention
22
+ this.migrate();
23
+ }
24
+ migrate() {
25
+ this.db.exec(`
26
+ CREATE TABLE IF NOT EXISTS queue (
27
+ id TEXT PRIMARY KEY,
28
+ direction TEXT NOT NULL CHECK(direction IN ('inbound', 'outbound')),
29
+ payload TEXT NOT NULL,
30
+ ts INTEGER NOT NULL,
31
+ attempts INTEGER NOT NULL DEFAULT 0,
32
+ max_attempts INTEGER NOT NULL DEFAULT 5,
33
+ next_retry_at INTEGER NOT NULL DEFAULT 0
34
+ );
35
+
36
+ CREATE INDEX IF NOT EXISTS idx_queue_direction_retry
37
+ ON queue(direction, next_retry_at);
38
+
39
+ CREATE INDEX IF NOT EXISTS idx_queue_ts
40
+ ON queue(ts);
41
+
42
+ -- Dead letter: items that exceeded max_attempts
43
+ CREATE TABLE IF NOT EXISTS dead_letter (
44
+ id TEXT PRIMARY KEY,
45
+ direction TEXT NOT NULL,
46
+ payload TEXT NOT NULL,
47
+ ts INTEGER NOT NULL,
48
+ attempts INTEGER NOT NULL,
49
+ failed_at INTEGER NOT NULL
50
+ );
51
+ `);
52
+ }
53
+ enqueueInbound(payload) {
54
+ this.db
55
+ .prepare(`
56
+ INSERT INTO queue (id, direction, payload, ts, attempts, max_attempts, next_retry_at)
57
+ VALUES (?, 'inbound', ?, ?, 0, ?, 0)
58
+ `)
59
+ .run((0, crypto_1.randomUUID)(), JSON.stringify(payload), Date.now(), protocol_1.LIMITS.QUEUE_MAX_ATTEMPTS_INBOUND);
60
+ }
61
+ enqueueOutbound(payload) {
62
+ this.db
63
+ .prepare(`
64
+ INSERT INTO queue (id, direction, payload, ts, attempts, max_attempts, next_retry_at)
65
+ VALUES (?, 'outbound', ?, ?, 0, ?, 0)
66
+ `)
67
+ .run((0, crypto_1.randomUUID)(), JSON.stringify(payload), Date.now(), protocol_1.LIMITS.QUEUE_MAX_ATTEMPTS_OUTBOUND);
68
+ }
69
+ /**
70
+ * Returns all items ready for replay, ordered:
71
+ * 1. OUTBOUND first (send cached responses before processing new requests)
72
+ * 2. Within same direction: oldest first (preserve request ordering)
73
+ */
74
+ drainForReplay() {
75
+ return this.db
76
+ .prepare(`
77
+ SELECT id, direction, payload, ts, attempts, max_attempts, next_retry_at
78
+ FROM queue
79
+ WHERE next_retry_at <= ?
80
+ ORDER BY
81
+ CASE direction WHEN 'outbound' THEN 0 ELSE 1 END ASC,
82
+ ts ASC
83
+ `)
84
+ .all(Date.now());
85
+ }
86
+ markSuccess(id) {
87
+ this.db.prepare("DELETE FROM queue WHERE id = ?").run(id);
88
+ }
89
+ markFailed(id) {
90
+ const item = this.db
91
+ .prepare("SELECT * FROM queue WHERE id = ?")
92
+ .get(id);
93
+ if (!item)
94
+ return;
95
+ const newAttempts = item.attempts + 1;
96
+ if (newAttempts >= item.maxAttempts) {
97
+ // Move to dead letter table
98
+ this.db.transaction(() => {
99
+ this.db
100
+ .prepare(`
101
+ INSERT INTO dead_letter (id, direction, payload, ts, attempts, failed_at)
102
+ VALUES (?, ?, ?, ?, ?, ?)
103
+ `)
104
+ .run(item.id, item.direction, item.payload, item.ts, newAttempts, Date.now());
105
+ this.db.prepare("DELETE FROM queue WHERE id = ?").run(id);
106
+ })();
107
+ return;
108
+ }
109
+ // Exponential backoff: 1s, 2s, 4s, 8s, 16s … capped at 5 min
110
+ const backoffMs = Math.min(1000 * Math.pow(2, newAttempts - 1), 300_000);
111
+ this.db
112
+ .prepare(`
113
+ UPDATE queue SET attempts = ?, next_retry_at = ? WHERE id = ?
114
+ `)
115
+ .run(newAttempts, Date.now() + backoffMs, id);
116
+ }
117
+ count() {
118
+ const now = Date.now();
119
+ const ready = this.db
120
+ .prepare("SELECT COUNT(*) as n FROM queue WHERE next_retry_at <= ?")
121
+ .get(now).n;
122
+ const pending = this.db
123
+ .prepare("SELECT COUNT(*) as n FROM queue WHERE next_retry_at > ?")
124
+ .get(now).n;
125
+ const deadLetter = this.db.prepare("SELECT COUNT(*) as n FROM dead_letter").get().n;
126
+ return { ready, pending, deadLetter };
127
+ }
128
+ /** Drain dead letter for inspection. Returns last N items. */
129
+ deadLetterItems(limit = 50) {
130
+ return this.db
131
+ .prepare(`
132
+ SELECT id, direction, payload, ts, attempts, 0 as max_attempts, failed_at as next_retry_at
133
+ FROM dead_letter ORDER BY failed_at DESC LIMIT ?
134
+ `)
135
+ .all(limit);
136
+ }
137
+ close() {
138
+ this.db.close();
139
+ }
140
+ }
141
+ exports.DurableQueue = DurableQueue;
142
+ //# sourceMappingURL=DurableQueue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DurableQueue.js","sourceRoot":"","sources":["../../src/queue/DurableQueue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { DurableQueue } from "../queue/DurableQueue";
2
+ import { BackendProxy } from "../proxy/BackendProxy";
3
+ type SendFn = (data: string) => void;
4
+ export interface ReplayResult {
5
+ succeeded: number;
6
+ failed: number;
7
+ skipped: number;
8
+ }
9
+ export declare function replayQueue(queue: DurableQueue, send: SendFn, proxy: BackendProxy): Promise<ReplayResult>;
10
+ export {};
11
+ //# sourceMappingURL=replayQueue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replayQueue.d.ts","sourceRoot":"","sources":["../../src/replay/replayQueue.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAa,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAQrD,KAAK,MAAM,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;AAErC,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,WAAW,CAC/B,KAAK,EAAE,YAAY,EACnB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,YAAY,CAAC,CAsCvB"}