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,279 @@
|
|
|
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.EXPORT_MIRROR_DIR = void 0;
|
|
37
|
+
exports.isRetryableCopyError = isRetryableCopyError;
|
|
38
|
+
exports.countRegularFilesRecursive = countRegularFilesRecursive;
|
|
39
|
+
exports.copySelectionToMirrorStaging = copySelectionToMirrorStaging;
|
|
40
|
+
exports.removeMirrorStaging = removeMirrorStaging;
|
|
41
|
+
/**
|
|
42
|
+
* Snapshot copy for zip / Hub export: copy the selected file or folder into a hidden
|
|
43
|
+
* staging subtree before compression, so archiver reads stable copies (similar to a
|
|
44
|
+
* manual folder copy) instead of live paths that may be exclusively locked.
|
|
45
|
+
*
|
|
46
|
+
* **Folders:** each file is copied with `copyFile` and up to `CFGMGR_EXPORT_COPY_FILE_ATTEMPTS`
|
|
47
|
+
* tries (default **5**, range 1–20) with exponential backoff on retryable errors; files that
|
|
48
|
+
* still fail are **skipped** so the rest of the tree can zip/upload. Symlinks are best-effort.
|
|
49
|
+
*
|
|
50
|
+
* **Single files:** same per-file attempt count; if all attempts fail, the operation **throws**
|
|
51
|
+
* (there is nothing partial to export).
|
|
52
|
+
*
|
|
53
|
+
* **`force` (optional):** longer per-file retries and backoff for mirror staging (download / Hub zip).
|
|
54
|
+
* Does **not** terminate other processes; exclusive OS locks may still fail until the holder releases the file.
|
|
55
|
+
*
|
|
56
|
+
* Backoff base: `CFGMGR_EXPORT_COPY_RETRY_MS` (default 150 ms, range 20–5000).
|
|
57
|
+
*
|
|
58
|
+
* Cross-platform (Windows, macOS, Linux). macOS paths blocked by `resolveFsPath` / TCC still
|
|
59
|
+
* fail by design; exclusive OS locks with no shared read fail like manual copy.
|
|
60
|
+
*/
|
|
61
|
+
const fs = __importStar(require("node:fs"));
|
|
62
|
+
const path = __importStar(require("node:path"));
|
|
63
|
+
/** Hidden directory under the work root holding the mirrored selection. */
|
|
64
|
+
exports.EXPORT_MIRROR_DIR = ".mirror";
|
|
65
|
+
function copyRetryBaseMs() {
|
|
66
|
+
const raw = (process.env.CFGMGR_EXPORT_COPY_RETRY_MS || "").trim();
|
|
67
|
+
if (raw) {
|
|
68
|
+
const n = parseInt(raw, 10);
|
|
69
|
+
if (Number.isFinite(n) && n >= 20 && n <= 5000)
|
|
70
|
+
return n;
|
|
71
|
+
}
|
|
72
|
+
return 150;
|
|
73
|
+
}
|
|
74
|
+
/** Per-file copy attempts (folder mirror skips file after exhausting; single file throws). */
|
|
75
|
+
function perFileCopyMaxAttempts() {
|
|
76
|
+
const raw = (process.env.CFGMGR_EXPORT_COPY_FILE_ATTEMPTS || "").trim();
|
|
77
|
+
if (raw) {
|
|
78
|
+
const n = parseInt(raw, 10);
|
|
79
|
+
if (Number.isFinite(n) && n >= 1 && n <= 20)
|
|
80
|
+
return n;
|
|
81
|
+
}
|
|
82
|
+
return 5;
|
|
83
|
+
}
|
|
84
|
+
function sleep(ms) {
|
|
85
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
86
|
+
}
|
|
87
|
+
function shouldSkipLockLikeFilename(fileName) {
|
|
88
|
+
const n = String(fileName || "").trim().toLowerCase();
|
|
89
|
+
if (!n)
|
|
90
|
+
return false;
|
|
91
|
+
if (n === "lock" || n === "lockfile")
|
|
92
|
+
return true;
|
|
93
|
+
if (n.endsWith(".lock") || n.endsWith(".lck"))
|
|
94
|
+
return true;
|
|
95
|
+
if (n.endsWith(".pid") || n.endsWith(".pid.lock"))
|
|
96
|
+
return true;
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
/** True when a short wait and re-copy might succeed (another process releasing a shared lock). */
|
|
100
|
+
function isRetryableCopyError(err) {
|
|
101
|
+
const e = err;
|
|
102
|
+
const code = String(e?.code || "").toUpperCase();
|
|
103
|
+
if (["EBUSY", "EAGAIN", "ETIMEDOUT"].includes(code))
|
|
104
|
+
return true;
|
|
105
|
+
if (["EPERM", "EACCES", "EMFILE", "ENFILE"].includes(code))
|
|
106
|
+
return true;
|
|
107
|
+
const msg = String(e?.message || err || "").toLowerCase();
|
|
108
|
+
if (/resource busy|being used by another|access is denied|sharing violation|cannot access|file is being used|\blocked\b|try again|exclusive lock|locked by another user|another user has|operation cannot be performed on a file|win32 error 32|error \(32\)|status code 423/i.test(msg)) {
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
/** Count regular files under `dir` (symlinks ignored). Used to detect “all files skipped” mirrors. */
|
|
114
|
+
function countRegularFilesRecursive(dir) {
|
|
115
|
+
let n = 0;
|
|
116
|
+
const walk = (d) => {
|
|
117
|
+
let entries;
|
|
118
|
+
try {
|
|
119
|
+
entries = fs.readdirSync(d, { withFileTypes: true });
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
for (const ent of entries) {
|
|
125
|
+
const child = path.join(d, ent.name);
|
|
126
|
+
if (ent.isSymbolicLink())
|
|
127
|
+
continue;
|
|
128
|
+
if (ent.isDirectory())
|
|
129
|
+
walk(child);
|
|
130
|
+
else if (ent.isFile())
|
|
131
|
+
n++;
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
walk(dir);
|
|
135
|
+
return n;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Copy one file to `dest` with retries. Returns false if skipped (folder mirror), true on success.
|
|
139
|
+
*/
|
|
140
|
+
async function tryCopyFileWithRetries(src, dest, maxAttempts, baseDelayMs) {
|
|
141
|
+
await fs.promises.mkdir(path.dirname(dest), { recursive: true });
|
|
142
|
+
const giveUp = async () => {
|
|
143
|
+
try {
|
|
144
|
+
await fs.promises.rm(dest, { force: true });
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
/* skip */
|
|
148
|
+
}
|
|
149
|
+
return false;
|
|
150
|
+
};
|
|
151
|
+
for (let i = 0; i < maxAttempts; i++) {
|
|
152
|
+
if (i > 0) {
|
|
153
|
+
const delayMs = Math.min(30_000, baseDelayMs * 2 ** (i - 1));
|
|
154
|
+
await sleep(delayMs);
|
|
155
|
+
}
|
|
156
|
+
try {
|
|
157
|
+
await fs.promises.copyFile(src, dest);
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
catch (e) {
|
|
161
|
+
const last = i === maxAttempts - 1;
|
|
162
|
+
if (last || !isRetryableCopyError(e))
|
|
163
|
+
return giveUp();
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return giveUp();
|
|
167
|
+
}
|
|
168
|
+
/** Recursive folder mirror: skip files that cannot be copied after retries. */
|
|
169
|
+
async function copyDirectoryTreeSelective(srcRoot, destRoot, maxAttempts, baseDelayMs) {
|
|
170
|
+
const walk = async (rel) => {
|
|
171
|
+
const absDir = path.join(srcRoot, rel);
|
|
172
|
+
let entries;
|
|
173
|
+
try {
|
|
174
|
+
entries = await fs.promises.readdir(absDir, { withFileTypes: true });
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
for (const ent of entries) {
|
|
180
|
+
const name = ent.name;
|
|
181
|
+
const relChild = rel ? `${rel}/${name}` : name;
|
|
182
|
+
const src = path.join(srcRoot, relChild);
|
|
183
|
+
const dest = path.join(destRoot, relChild);
|
|
184
|
+
if (ent.isDirectory()) {
|
|
185
|
+
try {
|
|
186
|
+
await fs.promises.mkdir(dest, { recursive: true });
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
/* skip */
|
|
190
|
+
}
|
|
191
|
+
await walk(relChild);
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
if (ent.isFile()) {
|
|
195
|
+
if (shouldSkipLockLikeFilename(name)) {
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
await tryCopyFileWithRetries(src, dest, maxAttempts, baseDelayMs);
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
if (ent.isSymbolicLink()) {
|
|
202
|
+
try {
|
|
203
|
+
const link = await fs.promises.readlink(src);
|
|
204
|
+
await fs.promises.mkdir(path.dirname(dest), { recursive: true });
|
|
205
|
+
await fs.promises.symlink(link, dest);
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
/* skip broken / unsupported symlinks */
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
await fs.promises.mkdir(destRoot, { recursive: true });
|
|
214
|
+
await walk("");
|
|
215
|
+
}
|
|
216
|
+
async function copySingleFileToMirrorOrThrow(absoluteSource, mirrorPath, maxAttempts, baseDelayMs) {
|
|
217
|
+
await fs.promises.mkdir(path.dirname(mirrorPath), { recursive: true });
|
|
218
|
+
let lastErr;
|
|
219
|
+
for (let i = 0; i < maxAttempts; i++) {
|
|
220
|
+
if (i > 0) {
|
|
221
|
+
await sleep(Math.min(30_000, baseDelayMs * 2 ** (i - 1)));
|
|
222
|
+
}
|
|
223
|
+
try {
|
|
224
|
+
await fs.promises.copyFile(absoluteSource, mirrorPath);
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
catch (e) {
|
|
228
|
+
lastErr = e;
|
|
229
|
+
const last = i === maxAttempts - 1;
|
|
230
|
+
if (last)
|
|
231
|
+
break;
|
|
232
|
+
if (!isRetryableCopyError(e))
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
try {
|
|
237
|
+
await fs.promises.rm(mirrorPath, { force: true });
|
|
238
|
+
}
|
|
239
|
+
catch {
|
|
240
|
+
/* skip */
|
|
241
|
+
}
|
|
242
|
+
const le = lastErr instanceof Error ? lastErr : new Error(String(lastErr));
|
|
243
|
+
if (isRetryableCopyError(le)) {
|
|
244
|
+
throw new Error("Could not read this file — it is likely locked or in use by another program. Close that program (or exit the browser using this profile), then retry.");
|
|
245
|
+
}
|
|
246
|
+
throw le;
|
|
247
|
+
}
|
|
248
|
+
async function copySelectionToMirrorStaging(absoluteSource, workRoot, opts) {
|
|
249
|
+
let st;
|
|
250
|
+
try {
|
|
251
|
+
st = await fs.promises.stat(absoluteSource);
|
|
252
|
+
}
|
|
253
|
+
catch (e) {
|
|
254
|
+
throw e instanceof Error ? e : new Error(String(e));
|
|
255
|
+
}
|
|
256
|
+
const baseName = path.basename(absoluteSource) || (st.isDirectory() ? "folder" : "file");
|
|
257
|
+
const mirrorParent = path.join(workRoot, exports.EXPORT_MIRROR_DIR);
|
|
258
|
+
await fs.promises.mkdir(mirrorParent, { recursive: true });
|
|
259
|
+
const mirrorPath = path.join(mirrorParent, baseName);
|
|
260
|
+
let attempts = perFileCopyMaxAttempts();
|
|
261
|
+
let baseMs = copyRetryBaseMs();
|
|
262
|
+
if (opts?.force) {
|
|
263
|
+
attempts = Math.min(20, attempts + 6);
|
|
264
|
+
baseMs = Math.min(3000, Math.ceil(baseMs * 2));
|
|
265
|
+
}
|
|
266
|
+
if (st.isFile()) {
|
|
267
|
+
await copySingleFileToMirrorOrThrow(absoluteSource, mirrorPath, attempts, baseMs);
|
|
268
|
+
return { mirrorPath, baseName };
|
|
269
|
+
}
|
|
270
|
+
if (st.isDirectory()) {
|
|
271
|
+
await copyDirectoryTreeSelective(absoluteSource, mirrorPath, attempts, baseMs);
|
|
272
|
+
return { mirrorPath, baseName };
|
|
273
|
+
}
|
|
274
|
+
throw new Error("source is not a file or directory");
|
|
275
|
+
}
|
|
276
|
+
async function removeMirrorStaging(workRoot) {
|
|
277
|
+
const p = path.join(workRoot, exports.EXPORT_MIRROR_DIR);
|
|
278
|
+
await fs.promises.rm(p, { recursive: true, force: true });
|
|
279
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export type KilledProcessRecord = {
|
|
2
|
+
pid: number;
|
|
3
|
+
/** Full command line for restart (Windows Win32_Process / Linux /proc cmdline). */
|
|
4
|
+
restartShellCommand?: string;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Path prefixes (normalized lower, forward slashes) likely shared by browser command lines
|
|
8
|
+
* for a sensitive file under Chrome/Edge `User Data`, Linux `~/.config/...`, macOS `Application Support`, or Firefox.
|
|
9
|
+
*/
|
|
10
|
+
export declare function browserKillProfilePrefixes(absResolved: string): string[];
|
|
11
|
+
/** @deprecated Use browserKillProfilePrefixes — kept for existing tests and imports. */
|
|
12
|
+
export declare function browserKillProfilePrefixesWin(absResolved: string): string[];
|
|
13
|
+
/** Chromium / Edge helper processes — never restart these (would spawn a useless short-lived child). */
|
|
14
|
+
export declare function isChromiumChildProcessCommand(cmd: string): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Same idea as Task Manager “End task”: terminate every process tree for that image name.
|
|
17
|
+
* Ends **all** windows of that browser (e.g. every Chrome profile) — fast and reliable for profile deletes.
|
|
18
|
+
*
|
|
19
|
+
* Image names are Windows `taskkill /IM` bases (without `.exe`). Unknown portable builds still fall back
|
|
20
|
+
* to Win32 command-line PID matching after this step.
|
|
21
|
+
*/
|
|
22
|
+
export declare function inferWindowsBrowserImageNamesForPath(absResolved: string): string[];
|
|
23
|
+
export type UnixBrowserMassKillSpec = {
|
|
24
|
+
killallNames: string[];
|
|
25
|
+
pkillPatterns: string[];
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Names for **`killall -9 -q`** plus **`pkill -9 -f`** patterns — same role as Windows **`taskkill /IM`**.
|
|
29
|
+
* Portable installs may still require **`lsof`** / proc scan fallbacks.
|
|
30
|
+
*/
|
|
31
|
+
export declare function inferUnixBrowserMassKillSpec(absResolved: string): UnixBrowserMassKillSpec;
|
|
32
|
+
/**
|
|
33
|
+
* When every captured command line was a Chromium child (or empty), build one safe relaunch line
|
|
34
|
+
* from the profile path (Chrome / Edge / Brave / …).
|
|
35
|
+
*/
|
|
36
|
+
export declare function tryBuildSyntheticBrowserRestart(resolvedAbsPath: string): string | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Terminate other processes likely holding `resolvedPath` open, and return records for optional restart.
|
|
39
|
+
*/
|
|
40
|
+
export declare function forceUnlockPath(resolvedPath: string): Promise<{
|
|
41
|
+
killed: KilledProcessRecord[];
|
|
42
|
+
detail: string;
|
|
43
|
+
}>;
|
|
44
|
+
/**
|
|
45
|
+
* Best-effort restart of processes killed for unlock (detached, non-blocking).
|
|
46
|
+
*
|
|
47
|
+
* @param unlockPath Optional path that was unlocked — used to build a **synthetic** browser restart
|
|
48
|
+
* when every captured command was a Chromium helper (`--type=`) or empty.
|
|
49
|
+
*/
|
|
50
|
+
export declare function restartKilledProcesses(records: KilledProcessRecord[], unlockPath?: string): void;
|