@xylabs/aries 0.1.1 → 0.1.7

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 (421) hide show
  1. package/README.md +6 -688
  2. package/dist/aries.mjs +47 -8466
  3. package/package.json +14 -169
  4. package/dist/actions/audit/auditPaths.mjs +0 -22
  5. package/dist/actions/audit/auditPaths.mjs.map +0 -1
  6. package/dist/actions/audit/index.mjs +0 -739
  7. package/dist/actions/audit/index.mjs.map +0 -1
  8. package/dist/actions/audit/installPlugin.mjs +0 -298
  9. package/dist/actions/audit/installPlugin.mjs.map +0 -1
  10. package/dist/actions/audit/listSessions.mjs +0 -93
  11. package/dist/actions/audit/listSessions.mjs.map +0 -1
  12. package/dist/actions/audit/openAuditDir.mjs +0 -44
  13. package/dist/actions/audit/openAuditDir.mjs.map +0 -1
  14. package/dist/actions/audit/searchAudit.mjs +0 -77
  15. package/dist/actions/audit/searchAudit.mjs.map +0 -1
  16. package/dist/actions/audit/showAiMeta.mjs +0 -105
  17. package/dist/actions/audit/showAiMeta.mjs.map +0 -1
  18. package/dist/actions/audit/showSession.mjs +0 -105
  19. package/dist/actions/audit/showSession.mjs.map +0 -1
  20. package/dist/actions/audit/statusAudit.mjs +0 -98
  21. package/dist/actions/audit/statusAudit.mjs.map +0 -1
  22. package/dist/actions/clamp/clampAudit.mjs +0 -53
  23. package/dist/actions/clamp/clampAudit.mjs.map +0 -1
  24. package/dist/actions/clamp/index.mjs +0 -2258
  25. package/dist/actions/clamp/index.mjs.map +0 -1
  26. package/dist/actions/clamp/ipcServer.mjs +0 -55
  27. package/dist/actions/clamp/ipcServer.mjs.map +0 -1
  28. package/dist/actions/clamp/policyManagement.mjs +0 -144
  29. package/dist/actions/clamp/policyManagement.mjs.map +0 -1
  30. package/dist/actions/clamp/promptUser.mjs +0 -91
  31. package/dist/actions/clamp/promptUser.mjs.map +0 -1
  32. package/dist/actions/clamp/runClamped.mjs +0 -2107
  33. package/dist/actions/clamp/runClamped.mjs.map +0 -1
  34. package/dist/actions/clamp/sandboxExec.mjs +0 -1612
  35. package/dist/actions/clamp/sandboxExec.mjs.map +0 -1
  36. package/dist/actions/clamp/shellEnvSetup.mjs +0 -59
  37. package/dist/actions/clamp/shellEnvSetup.mjs.map +0 -1
  38. package/dist/actions/clamp/shimGenerator.mjs +0 -68
  39. package/dist/actions/clamp/shimGenerator.mjs.map +0 -1
  40. package/dist/actions/clamp/terminalRenderer.mjs +0 -145
  41. package/dist/actions/clamp/terminalRenderer.mjs.map +0 -1
  42. package/dist/actions/datalake/audit/auditLog.mjs +0 -191
  43. package/dist/actions/datalake/audit/auditLog.mjs.map +0 -1
  44. package/dist/actions/datalake/createDatalake.mjs +0 -127
  45. package/dist/actions/datalake/createDatalake.mjs.map +0 -1
  46. package/dist/actions/datalake/describeDatalake.mjs +0 -159
  47. package/dist/actions/datalake/describeDatalake.mjs.map +0 -1
  48. package/dist/actions/datalake/destroyDatalake.mjs +0 -34
  49. package/dist/actions/datalake/destroyDatalake.mjs.map +0 -1
  50. package/dist/actions/datalake/dev/downDevServer.mjs +0 -102
  51. package/dist/actions/datalake/dev/downDevServer.mjs.map +0 -1
  52. package/dist/actions/datalake/dev/index.mjs +0 -369
  53. package/dist/actions/datalake/dev/index.mjs.map +0 -1
  54. package/dist/actions/datalake/dev/logsDevServer.mjs +0 -44
  55. package/dist/actions/datalake/dev/logsDevServer.mjs.map +0 -1
  56. package/dist/actions/datalake/dev/paths.mjs +0 -25
  57. package/dist/actions/datalake/dev/paths.mjs.map +0 -1
  58. package/dist/actions/datalake/dev/resetDevServer.mjs +0 -118
  59. package/dist/actions/datalake/dev/resetDevServer.mjs.map +0 -1
  60. package/dist/actions/datalake/dev/resolveServerBin.mjs +0 -26
  61. package/dist/actions/datalake/dev/resolveServerBin.mjs.map +0 -1
  62. package/dist/actions/datalake/dev/state.mjs +0 -62
  63. package/dist/actions/datalake/dev/state.mjs.map +0 -1
  64. package/dist/actions/datalake/dev/statusDevServer.mjs +0 -101
  65. package/dist/actions/datalake/dev/statusDevServer.mjs.map +0 -1
  66. package/dist/actions/datalake/dev/upDevServer.mjs +0 -221
  67. package/dist/actions/datalake/dev/upDevServer.mjs.map +0 -1
  68. package/dist/actions/datalake/dev/waitForHealth.mjs +0 -22
  69. package/dist/actions/datalake/dev/waitForHealth.mjs.map +0 -1
  70. package/dist/actions/datalake/formatters.mjs +0 -90
  71. package/dist/actions/datalake/formatters.mjs.map +0 -1
  72. package/dist/actions/datalake/grantAccess.mjs +0 -116
  73. package/dist/actions/datalake/grantAccess.mjs.map +0 -1
  74. package/dist/actions/datalake/index.mjs +0 -361
  75. package/dist/actions/datalake/index.mjs.map +0 -1
  76. package/dist/actions/datalake/listDatalakes.mjs +0 -54
  77. package/dist/actions/datalake/listDatalakes.mjs.map +0 -1
  78. package/dist/actions/datalake/login.mjs +0 -20
  79. package/dist/actions/datalake/login.mjs.map +0 -1
  80. package/dist/actions/datalake/logout.mjs +0 -11
  81. package/dist/actions/datalake/logout.mjs.map +0 -1
  82. package/dist/actions/datalake/mintToken.mjs +0 -37
  83. package/dist/actions/datalake/mintToken.mjs.map +0 -1
  84. package/dist/actions/datalake/parseSize.mjs +0 -21
  85. package/dist/actions/datalake/parseSize.mjs.map +0 -1
  86. package/dist/actions/datalake/payloads/fetchPayload.mjs +0 -76
  87. package/dist/actions/datalake/payloads/fetchPayload.mjs.map +0 -1
  88. package/dist/actions/datalake/payloads/index.mjs +0 -271
  89. package/dist/actions/datalake/payloads/index.mjs.map +0 -1
  90. package/dist/actions/datalake/payloads/mintAndConnect.mjs +0 -46
  91. package/dist/actions/datalake/payloads/mintAndConnect.mjs.map +0 -1
  92. package/dist/actions/datalake/payloads/parsePayloadsFile.mjs +0 -71
  93. package/dist/actions/datalake/payloads/parsePayloadsFile.mjs.map +0 -1
  94. package/dist/actions/datalake/payloads/pushPayloads.mjs +0 -181
  95. package/dist/actions/datalake/payloads/pushPayloads.mjs.map +0 -1
  96. package/dist/actions/datalake/payloads/tailPayloads.mjs +0 -106
  97. package/dist/actions/datalake/payloads/tailPayloads.mjs.map +0 -1
  98. package/dist/actions/datalake/resolveTarget.mjs +0 -15
  99. package/dist/actions/datalake/resolveTarget.mjs.map +0 -1
  100. package/dist/actions/datalake/revokeAccess.mjs +0 -108
  101. package/dist/actions/datalake/revokeAccess.mjs.map +0 -1
  102. package/dist/actions/datalake/useDatalake.mjs +0 -22
  103. package/dist/actions/datalake/useDatalake.mjs.map +0 -1
  104. package/dist/actions/detect/detectAiClients.mjs +0 -405
  105. package/dist/actions/detect/detectAiClients.mjs.map +0 -1
  106. package/dist/actions/detect/index.mjs +0 -405
  107. package/dist/actions/detect/index.mjs.map +0 -1
  108. package/dist/actions/hash/algorithms/blockhash.mjs +0 -61
  109. package/dist/actions/hash/algorithms/blockhash.mjs.map +0 -1
  110. package/dist/actions/hash/algorithms/chromaprint.mjs +0 -205
  111. package/dist/actions/hash/algorithms/chromaprint.mjs.map +0 -1
  112. package/dist/actions/hash/algorithms/dhash.mjs +0 -75
  113. package/dist/actions/hash/algorithms/dhash.mjs.map +0 -1
  114. package/dist/actions/hash/algorithms/index.mjs +0 -818
  115. package/dist/actions/hash/algorithms/index.mjs.map +0 -1
  116. package/dist/actions/hash/algorithms/nilsimsa.mjs +0 -27
  117. package/dist/actions/hash/algorithms/nilsimsa.mjs.map +0 -1
  118. package/dist/actions/hash/algorithms/pdq.mjs +0 -83
  119. package/dist/actions/hash/algorithms/pdq.mjs.map +0 -1
  120. package/dist/actions/hash/algorithms/phash.mjs +0 -71
  121. package/dist/actions/hash/algorithms/phash.mjs.map +0 -1
  122. package/dist/actions/hash/algorithms/sha256.mjs +0 -24
  123. package/dist/actions/hash/algorithms/sha256.mjs.map +0 -1
  124. package/dist/actions/hash/algorithms/ssdeep.mjs +0 -203
  125. package/dist/actions/hash/algorithms/ssdeep.mjs.map +0 -1
  126. package/dist/actions/hash/algorithms/tlsh.mjs +0 -66
  127. package/dist/actions/hash/algorithms/tlsh.mjs.map +0 -1
  128. package/dist/actions/hash/algorithms/types.mjs +0 -1
  129. package/dist/actions/hash/algorithms/types.mjs.map +0 -1
  130. package/dist/actions/hash/algorithms/videoFrames.mjs +0 -404
  131. package/dist/actions/hash/algorithms/videoFrames.mjs.map +0 -1
  132. package/dist/actions/hash/algorithms/xyo.mjs +0 -30
  133. package/dist/actions/hash/algorithms/xyo.mjs.map +0 -1
  134. package/dist/actions/hash/compareHashes.mjs +0 -823
  135. package/dist/actions/hash/compareHashes.mjs.map +0 -1
  136. package/dist/actions/hash/hashInput.mjs +0 -868
  137. package/dist/actions/hash/hashInput.mjs.map +0 -1
  138. package/dist/actions/hash/index.mjs +0 -881
  139. package/dist/actions/hash/index.mjs.map +0 -1
  140. package/dist/actions/hash/lib/hamming.mjs +0 -44
  141. package/dist/actions/hash/lib/hamming.mjs.map +0 -1
  142. package/dist/actions/hash/lib/levenshtein.mjs +0 -36
  143. package/dist/actions/hash/lib/levenshtein.mjs.map +0 -1
  144. package/dist/actions/hash/lib/runBinary.mjs +0 -54
  145. package/dist/actions/hash/lib/runBinary.mjs.map +0 -1
  146. package/dist/actions/hash/lib/which.mjs +0 -36
  147. package/dist/actions/hash/lib/which.mjs.map +0 -1
  148. package/dist/actions/hash/lib/withTempfile.mjs +0 -19
  149. package/dist/actions/hash/lib/withTempfile.mjs.map +0 -1
  150. package/dist/actions/index.mjs +0 -4615
  151. package/dist/actions/index.mjs.map +0 -1
  152. package/dist/actions/printVersion.mjs +0 -12
  153. package/dist/actions/printVersion.mjs.map +0 -1
  154. package/dist/actions/sync/index.mjs +0 -51
  155. package/dist/actions/sync/index.mjs.map +0 -1
  156. package/dist/actions/sync/syncAiConfig.mjs +0 -51
  157. package/dist/actions/sync/syncAiConfig.mjs.map +0 -1
  158. package/dist/actions/wallet/account/deriveAndAdd.mjs +0 -394
  159. package/dist/actions/wallet/account/deriveAndAdd.mjs.map +0 -1
  160. package/dist/actions/wallet/account/getActiveWallet.mjs +0 -338
  161. package/dist/actions/wallet/account/getActiveWallet.mjs.map +0 -1
  162. package/dist/actions/wallet/account/labelAccount.mjs +0 -389
  163. package/dist/actions/wallet/account/labelAccount.mjs.map +0 -1
  164. package/dist/actions/wallet/account/listAccounts.mjs +0 -374
  165. package/dist/actions/wallet/account/listAccounts.mjs.map +0 -1
  166. package/dist/actions/wallet/account/removeAccount.mjs +0 -384
  167. package/dist/actions/wallet/account/removeAccount.mjs.map +0 -1
  168. package/dist/actions/wallet/account/showAccount.mjs +0 -368
  169. package/dist/actions/wallet/account/showAccount.mjs.map +0 -1
  170. package/dist/actions/wallet/addressBook/storage.mjs +0 -110
  171. package/dist/actions/wallet/addressBook/storage.mjs.map +0 -1
  172. package/dist/actions/wallet/backup/exportBackup.mjs +0 -93
  173. package/dist/actions/wallet/backup/exportBackup.mjs.map +0 -1
  174. package/dist/actions/wallet/backup/importBackup.mjs +0 -142
  175. package/dist/actions/wallet/backup/importBackup.mjs.map +0 -1
  176. package/dist/actions/wallet/balance/getBalance.mjs +0 -434
  177. package/dist/actions/wallet/balance/getBalance.mjs.map +0 -1
  178. package/dist/actions/wallet/client/walletClient.mjs +0 -64
  179. package/dist/actions/wallet/client/walletClient.mjs.map +0 -1
  180. package/dist/actions/wallet/contact/contactActions.mjs +0 -120
  181. package/dist/actions/wallet/contact/contactActions.mjs.map +0 -1
  182. package/dist/actions/wallet/contact/storage.mjs +0 -69
  183. package/dist/actions/wallet/contact/storage.mjs.map +0 -1
  184. package/dist/actions/wallet/index.mjs +0 -1439
  185. package/dist/actions/wallet/index.mjs.map +0 -1
  186. package/dist/actions/wallet/network/networkActions.mjs +0 -137
  187. package/dist/actions/wallet/network/networkActions.mjs.map +0 -1
  188. package/dist/actions/wallet/network/storage.mjs +0 -93
  189. package/dist/actions/wallet/network/storage.mjs.map +0 -1
  190. package/dist/actions/wallet/password/changePassword.mjs +0 -282
  191. package/dist/actions/wallet/password/changePassword.mjs.map +0 -1
  192. package/dist/actions/wallet/password/getActiveKey.mjs +0 -297
  193. package/dist/actions/wallet/password/getActiveKey.mjs.map +0 -1
  194. package/dist/actions/wallet/password/initOrUnlock.mjs +0 -337
  195. package/dist/actions/wallet/password/initOrUnlock.mjs.map +0 -1
  196. package/dist/actions/wallet/password/passwordStorage.mjs +0 -69
  197. package/dist/actions/wallet/password/passwordStorage.mjs.map +0 -1
  198. package/dist/actions/wallet/password/setPassword.mjs +0 -138
  199. package/dist/actions/wallet/password/setPassword.mjs.map +0 -1
  200. package/dist/actions/wallet/password/validatePassword.mjs +0 -123
  201. package/dist/actions/wallet/password/validatePassword.mjs.map +0 -1
  202. package/dist/actions/wallet/passwordKey.mjs +0 -87
  203. package/dist/actions/wallet/passwordKey.mjs.map +0 -1
  204. package/dist/actions/wallet/paths.mjs +0 -26
  205. package/dist/actions/wallet/paths.mjs.map +0 -1
  206. package/dist/actions/wallet/prompt.mjs +0 -93
  207. package/dist/actions/wallet/prompt.mjs.map +0 -1
  208. package/dist/actions/wallet/seedPhrase/createPhrase.mjs +0 -392
  209. package/dist/actions/wallet/seedPhrase/createPhrase.mjs.map +0 -1
  210. package/dist/actions/wallet/seedPhrase/exportPhrase.mjs +0 -334
  211. package/dist/actions/wallet/seedPhrase/exportPhrase.mjs.map +0 -1
  212. package/dist/actions/wallet/seedPhrase/idGen.mjs +0 -11
  213. package/dist/actions/wallet/seedPhrase/idGen.mjs.map +0 -1
  214. package/dist/actions/wallet/seedPhrase/importPhrase.mjs +0 -393
  215. package/dist/actions/wallet/seedPhrase/importPhrase.mjs.map +0 -1
  216. package/dist/actions/wallet/seedPhrase/listPhrases.mjs +0 -62
  217. package/dist/actions/wallet/seedPhrase/listPhrases.mjs.map +0 -1
  218. package/dist/actions/wallet/seedPhrase/phraseStorage.mjs +0 -89
  219. package/dist/actions/wallet/seedPhrase/phraseStorage.mjs.map +0 -1
  220. package/dist/actions/wallet/seedPhrase/removePhrase.mjs +0 -366
  221. package/dist/actions/wallet/seedPhrase/removePhrase.mjs.map +0 -1
  222. package/dist/actions/wallet/seedPhrase/renamePhrase.mjs +0 -78
  223. package/dist/actions/wallet/seedPhrase/renamePhrase.mjs.map +0 -1
  224. package/dist/actions/wallet/seedPhrase/types.mjs +0 -1
  225. package/dist/actions/wallet/seedPhrase/types.mjs.map +0 -1
  226. package/dist/actions/wallet/seedPhrase/usePhrase.mjs +0 -83
  227. package/dist/actions/wallet/seedPhrase/usePhrase.mjs.map +0 -1
  228. package/dist/actions/wallet/session/machineId.mjs +0 -145
  229. package/dist/actions/wallet/session/machineId.mjs.map +0 -1
  230. package/dist/actions/wallet/session/sessionCache.mjs +0 -221
  231. package/dist/actions/wallet/session/sessionCache.mjs.map +0 -1
  232. package/dist/actions/wallet/session/unlock.mjs +0 -307
  233. package/dist/actions/wallet/session/unlock.mjs.map +0 -1
  234. package/dist/actions/wallet/sign/signPayload.mjs +0 -637
  235. package/dist/actions/wallet/sign/signPayload.mjs.map +0 -1
  236. package/dist/actions/wallet/storage.mjs +0 -51
  237. package/dist/actions/wallet/storage.mjs.map +0 -1
  238. package/dist/actions/wallet/transaction/broadcastTransaction.mjs +0 -453
  239. package/dist/actions/wallet/transaction/broadcastTransaction.mjs.map +0 -1
  240. package/dist/actions/wallet/transaction/sendTransaction.mjs +0 -457
  241. package/dist/actions/wallet/transaction/sendTransaction.mjs.map +0 -1
  242. package/dist/actions/wallet/transaction/signTransactionFile.mjs +0 -378
  243. package/dist/actions/wallet/transaction/signTransactionFile.mjs.map +0 -1
  244. package/dist/actions/xyo/index.mjs +0 -138
  245. package/dist/actions/xyo/index.mjs.map +0 -1
  246. package/dist/actions/xyo/transaction/index.mjs +0 -138
  247. package/dist/actions/xyo/transaction/index.mjs.map +0 -1
  248. package/dist/actions/xyo/transaction/validateTransactions.mjs +0 -138
  249. package/dist/actions/xyo/transaction/validateTransactions.mjs.map +0 -1
  250. package/dist/aries.mjs.map +0 -1
  251. package/dist/bin/aries.mjs +0 -8472
  252. package/dist/bin/aries.mjs.map +0 -1
  253. package/dist/commands/aiCommand.mjs +0 -492
  254. package/dist/commands/aiCommand.mjs.map +0 -1
  255. package/dist/commands/auditAiCommand.mjs +0 -119
  256. package/dist/commands/auditAiCommand.mjs.map +0 -1
  257. package/dist/commands/auditCommand.mjs +0 -857
  258. package/dist/commands/auditCommand.mjs.map +0 -1
  259. package/dist/commands/auditInstallCommand.mjs +0 -324
  260. package/dist/commands/auditInstallCommand.mjs.map +0 -1
  261. package/dist/commands/auditListCommand.mjs +0 -107
  262. package/dist/commands/auditListCommand.mjs.map +0 -1
  263. package/dist/commands/auditOpenCommand.mjs +0 -51
  264. package/dist/commands/auditOpenCommand.mjs.map +0 -1
  265. package/dist/commands/auditSearchCommand.mjs +0 -98
  266. package/dist/commands/auditSearchCommand.mjs.map +0 -1
  267. package/dist/commands/auditShowCommand.mjs +0 -123
  268. package/dist/commands/auditShowCommand.mjs.map +0 -1
  269. package/dist/commands/auditStatusCommand.mjs +0 -105
  270. package/dist/commands/auditStatusCommand.mjs.map +0 -1
  271. package/dist/commands/clampCommand.mjs +0 -2328
  272. package/dist/commands/clampCommand.mjs.map +0 -1
  273. package/dist/commands/clampPolicyCommand.mjs +0 -184
  274. package/dist/commands/clampPolicyCommand.mjs.map +0 -1
  275. package/dist/commands/clampPolicyInitCommand.mjs +0 -63
  276. package/dist/commands/clampPolicyInitCommand.mjs.map +0 -1
  277. package/dist/commands/clampPolicyListCommand.mjs +0 -56
  278. package/dist/commands/clampPolicyListCommand.mjs.map +0 -1
  279. package/dist/commands/clampPolicyShowCommand.mjs +0 -83
  280. package/dist/commands/clampPolicyShowCommand.mjs.map +0 -1
  281. package/dist/commands/clampRunCommand.mjs +0 -2137
  282. package/dist/commands/clampRunCommand.mjs.map +0 -1
  283. package/dist/commands/datalakeAuditCommand.mjs +0 -273
  284. package/dist/commands/datalakeAuditCommand.mjs.map +0 -1
  285. package/dist/commands/datalakeCommand.mjs +0 -1637
  286. package/dist/commands/datalakeCommand.mjs.map +0 -1
  287. package/dist/commands/datalakeCreateCommand.mjs +0 -189
  288. package/dist/commands/datalakeCreateCommand.mjs.map +0 -1
  289. package/dist/commands/datalakeDescribeCommand.mjs +0 -172
  290. package/dist/commands/datalakeDescribeCommand.mjs.map +0 -1
  291. package/dist/commands/datalakeDestroyCommand.mjs +0 -53
  292. package/dist/commands/datalakeDestroyCommand.mjs.map +0 -1
  293. package/dist/commands/datalakeDevCommand.mjs +0 -470
  294. package/dist/commands/datalakeDevCommand.mjs.map +0 -1
  295. package/dist/commands/datalakeDevDownCommand.mjs +0 -111
  296. package/dist/commands/datalakeDevDownCommand.mjs.map +0 -1
  297. package/dist/commands/datalakeDevLogsCommand.mjs +0 -65
  298. package/dist/commands/datalakeDevLogsCommand.mjs.map +0 -1
  299. package/dist/commands/datalakeDevResetCommand.mjs +0 -125
  300. package/dist/commands/datalakeDevResetCommand.mjs.map +0 -1
  301. package/dist/commands/datalakeDevStatusCommand.mjs +0 -110
  302. package/dist/commands/datalakeDevStatusCommand.mjs.map +0 -1
  303. package/dist/commands/datalakeDevUpCommand.mjs +0 -268
  304. package/dist/commands/datalakeDevUpCommand.mjs.map +0 -1
  305. package/dist/commands/datalakeFetchCommand.mjs +0 -106
  306. package/dist/commands/datalakeFetchCommand.mjs.map +0 -1
  307. package/dist/commands/datalakeGrantCommand.mjs +0 -147
  308. package/dist/commands/datalakeGrantCommand.mjs.map +0 -1
  309. package/dist/commands/datalakeListCommand.mjs +0 -61
  310. package/dist/commands/datalakeListCommand.mjs.map +0 -1
  311. package/dist/commands/datalakeLoginCommand.mjs +0 -39
  312. package/dist/commands/datalakeLoginCommand.mjs.map +0 -1
  313. package/dist/commands/datalakeLogoutCommand.mjs +0 -20
  314. package/dist/commands/datalakeLogoutCommand.mjs.map +0 -1
  315. package/dist/commands/datalakePushCommand.mjs +0 -214
  316. package/dist/commands/datalakePushCommand.mjs.map +0 -1
  317. package/dist/commands/datalakeRevokeCommand.mjs +0 -127
  318. package/dist/commands/datalakeRevokeCommand.mjs.map +0 -1
  319. package/dist/commands/datalakeTailCommand.mjs +0 -144
  320. package/dist/commands/datalakeTailCommand.mjs.map +0 -1
  321. package/dist/commands/datalakeTokenCommand.mjs +0 -61
  322. package/dist/commands/datalakeTokenCommand.mjs.map +0 -1
  323. package/dist/commands/datalakeUseCommand.mjs +0 -35
  324. package/dist/commands/datalakeUseCommand.mjs.map +0 -1
  325. package/dist/commands/detectCommand.mjs +0 -419
  326. package/dist/commands/detectCommand.mjs.map +0 -1
  327. package/dist/commands/hashCommand.mjs +0 -976
  328. package/dist/commands/hashCommand.mjs.map +0 -1
  329. package/dist/commands/hashCompareCommand.mjs +0 -865
  330. package/dist/commands/hashCompareCommand.mjs.map +0 -1
  331. package/dist/commands/index.mjs +0 -8461
  332. package/dist/commands/index.mjs.map +0 -1
  333. package/dist/commands/syncCommand.mjs +0 -66
  334. package/dist/commands/syncCommand.mjs.map +0 -1
  335. package/dist/commands/versionCommand.mjs +0 -24
  336. package/dist/commands/versionCommand.mjs.map +0 -1
  337. package/dist/commands/walletAccountCommand.mjs +0 -536
  338. package/dist/commands/walletAccountCommand.mjs.map +0 -1
  339. package/dist/commands/walletAccountDeriveCommand.mjs +0 -415
  340. package/dist/commands/walletAccountDeriveCommand.mjs.map +0 -1
  341. package/dist/commands/walletAccountLabelCommand.mjs +0 -405
  342. package/dist/commands/walletAccountLabelCommand.mjs.map +0 -1
  343. package/dist/commands/walletAccountListCommand.mjs +0 -381
  344. package/dist/commands/walletAccountListCommand.mjs.map +0 -1
  345. package/dist/commands/walletAccountRemoveCommand.mjs +0 -396
  346. package/dist/commands/walletAccountRemoveCommand.mjs.map +0 -1
  347. package/dist/commands/walletAccountShowCommand.mjs +0 -380
  348. package/dist/commands/walletAccountShowCommand.mjs.map +0 -1
  349. package/dist/commands/walletBackupCommand.mjs +0 -222
  350. package/dist/commands/walletBackupCommand.mjs.map +0 -1
  351. package/dist/commands/walletBackupExportCommand.mjs +0 -107
  352. package/dist/commands/walletBackupExportCommand.mjs.map +0 -1
  353. package/dist/commands/walletBackupImportCommand.mjs +0 -154
  354. package/dist/commands/walletBackupImportCommand.mjs.map +0 -1
  355. package/dist/commands/walletBalanceCommand.mjs +0 -448
  356. package/dist/commands/walletBalanceCommand.mjs.map +0 -1
  357. package/dist/commands/walletCommand.mjs +0 -1968
  358. package/dist/commands/walletCommand.mjs.map +0 -1
  359. package/dist/commands/walletContactAddCommand.mjs +0 -111
  360. package/dist/commands/walletContactAddCommand.mjs.map +0 -1
  361. package/dist/commands/walletContactCommand.mjs +0 -184
  362. package/dist/commands/walletContactCommand.mjs.map +0 -1
  363. package/dist/commands/walletContactListCommand.mjs +0 -66
  364. package/dist/commands/walletContactListCommand.mjs.map +0 -1
  365. package/dist/commands/walletContactRemoveCommand.mjs +0 -97
  366. package/dist/commands/walletContactRemoveCommand.mjs.map +0 -1
  367. package/dist/commands/walletContactRenameCommand.mjs +0 -114
  368. package/dist/commands/walletContactRenameCommand.mjs.map +0 -1
  369. package/dist/commands/walletCreateCommand.mjs +0 -407
  370. package/dist/commands/walletCreateCommand.mjs.map +0 -1
  371. package/dist/commands/walletExportCommand.mjs +0 -345
  372. package/dist/commands/walletExportCommand.mjs.map +0 -1
  373. package/dist/commands/walletImportCommand.mjs +0 -413
  374. package/dist/commands/walletImportCommand.mjs.map +0 -1
  375. package/dist/commands/walletListCommand.mjs +0 -69
  376. package/dist/commands/walletListCommand.mjs.map +0 -1
  377. package/dist/commands/walletLockCommand.mjs +0 -56
  378. package/dist/commands/walletLockCommand.mjs.map +0 -1
  379. package/dist/commands/walletNetworkAddCommand.mjs +0 -131
  380. package/dist/commands/walletNetworkAddCommand.mjs.map +0 -1
  381. package/dist/commands/walletNetworkCommand.mjs +0 -206
  382. package/dist/commands/walletNetworkCommand.mjs.map +0 -1
  383. package/dist/commands/walletNetworkListCommand.mjs +0 -104
  384. package/dist/commands/walletNetworkListCommand.mjs.map +0 -1
  385. package/dist/commands/walletNetworkRemoveCommand.mjs +0 -112
  386. package/dist/commands/walletNetworkRemoveCommand.mjs.map +0 -1
  387. package/dist/commands/walletNetworkUseCommand.mjs +0 -110
  388. package/dist/commands/walletNetworkUseCommand.mjs.map +0 -1
  389. package/dist/commands/walletPasswordChangeCommand.mjs +0 -291
  390. package/dist/commands/walletPasswordChangeCommand.mjs.map +0 -1
  391. package/dist/commands/walletPasswordCommand.mjs +0 -301
  392. package/dist/commands/walletPasswordCommand.mjs.map +0 -1
  393. package/dist/commands/walletRemoveCommand.mjs +0 -378
  394. package/dist/commands/walletRemoveCommand.mjs.map +0 -1
  395. package/dist/commands/walletRenameCommand.mjs +0 -94
  396. package/dist/commands/walletRenameCommand.mjs.map +0 -1
  397. package/dist/commands/walletSignCommand.mjs +0 -662
  398. package/dist/commands/walletSignCommand.mjs.map +0 -1
  399. package/dist/commands/walletTxBroadcastCommand.mjs +0 -473
  400. package/dist/commands/walletTxBroadcastCommand.mjs.map +0 -1
  401. package/dist/commands/walletTxCommand.mjs +0 -612
  402. package/dist/commands/walletTxCommand.mjs.map +0 -1
  403. package/dist/commands/walletTxSendCommand.mjs +0 -492
  404. package/dist/commands/walletTxSendCommand.mjs.map +0 -1
  405. package/dist/commands/walletTxSignCommand.mjs +0 -403
  406. package/dist/commands/walletTxSignCommand.mjs.map +0 -1
  407. package/dist/commands/walletUnlockCommand.mjs +0 -308
  408. package/dist/commands/walletUnlockCommand.mjs.map +0 -1
  409. package/dist/commands/walletUseCommand.mjs +0 -95
  410. package/dist/commands/walletUseCommand.mjs.map +0 -1
  411. package/dist/commands/xyoCommand.mjs +0 -188
  412. package/dist/commands/xyoCommand.mjs.map +0 -1
  413. package/dist/commands/xyoTxCommand.mjs +0 -178
  414. package/dist/commands/xyoTxCommand.mjs.map +0 -1
  415. package/dist/commands/xyoTxValidateCommand.mjs +0 -168
  416. package/dist/commands/xyoTxValidateCommand.mjs.map +0 -1
  417. package/dist/index.d.ts +0 -3
  418. package/dist/index.mjs +0 -8466
  419. package/dist/index.mjs.map +0 -1
  420. package/dist/types/modules.d.mjs +0 -1
  421. package/dist/types/modules.d.mjs.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../../src/actions/hash/algorithms/blockhash.ts","../../../../src/actions/hash/lib/hamming.ts","../../../../src/actions/hash/lib/runBinary.ts","../../../../src/actions/hash/lib/which.ts","../../../../src/actions/hash/lib/withTempfile.ts","../../../../src/actions/hash/algorithms/chromaprint.ts","../../../../src/actions/hash/algorithms/dhash.ts","../../../../src/actions/hash/algorithms/nilsimsa.ts","../../../../src/actions/hash/algorithms/pdq.ts","../../../../src/actions/hash/algorithms/phash.ts","../../../../src/actions/hash/algorithms/sha256.ts","../../../../src/actions/hash/lib/levenshtein.ts","../../../../src/actions/hash/algorithms/ssdeep.ts","../../../../src/actions/hash/algorithms/tlsh.ts","../../../../src/actions/hash/algorithms/videoFrames.ts","../../../../src/actions/hash/algorithms/xyo.ts","../../../../src/actions/hash/algorithms/index.ts"],"sourcesContent":["import imghash from 'imghash'\n\nimport { hammingHex } from '../lib/hamming.ts'\nimport type { Algorithm } from './types.ts'\n\nconst { hash: imghashFn } = imghash\n\n/**\n * blockhash via the imghash package — defaults to 8×8 = 64-bit for cross-comparability\n * with phash/dhash. Imghash accepts both filepath and Buffer natively.\n */\nexport const blockhashAlgorithm: Algorithm = {\n name: 'blockhash',\n family: 'perceptual-image',\n inputType: 'image',\n async hash(input) {\n if (input.path !== undefined) {\n return await imghashFn(input.path, 8, 'hex')\n }\n if (input.bytes !== undefined) {\n return await imghashFn(input.bytes, 8, 'hex')\n }\n throw new Error('blockhash requires bytes or a path.')\n },\n async compare(a, b) {\n const dist = hammingHex(a, b)\n const bits = (a.length / 2) * 8\n return {\n distance: dist, similarity: 1 - dist / bits, metric: `hamming-${bits}`,\n }\n },\n}\n","/**\n * Population count for an 8-bit value (number of set bits).\n */\nfunction popcount8(byte: number): number {\n let count = 0\n let value = byte & 0xff\n while (value !== 0) {\n count += value & 1\n value >>>= 1\n }\n return count\n}\n\n/**\n * Hamming distance between two equal-length lowercase-hex strings.\n * Throws when the lengths differ.\n */\nexport function hammingHex(a: string, b: string): number {\n if (a.length !== b.length) {\n throw new Error(`Hash length mismatch: ${a.length} vs ${b.length}`)\n }\n if (a.length % 2 !== 0) {\n throw new Error(`Hash hex length must be even, got ${a.length}`)\n }\n let dist = 0\n for (let i = 0; i < a.length; i += 2) {\n const xa = Number.parseInt(a.slice(i, i + 2), 16)\n const xb = Number.parseInt(b.slice(i, i + 2), 16)\n if (Number.isNaN(xa) || Number.isNaN(xb)) {\n throw new TypeError(`Invalid hex at position ${i}: '${a.slice(i, i + 2)}' / '${b.slice(i, i + 2)}'`)\n }\n dist += popcount8(xa ^ xb)\n }\n return dist\n}\n\n/**\n * Bit-length of an even-length hex string.\n */\nexport function bitLengthHex(hex: string): number {\n return (hex.length / 2) * 8\n}\n\n/**\n * Population count for a 32-bit unsigned value (number of set bits).\n * Uses the parallel-prefix bit trick.\n */\nexport function popcount32(value: number): number {\n let v = Math.trunc(value)\n v = v - ((v >>> 1) & 0x55_55_55_55)\n v = (v & 0x33_33_33_33) + ((v >>> 2) & 0x33_33_33_33)\n v = (v + (v >>> 4)) & 0x0f_0f_0f_0f\n return ((v * 0x01_01_01_01) >>> 24) & 0xff\n}\n","import { spawn } from 'node:child_process'\n\nexport interface RunBinaryOptions {\n binary: string\n args?: readonly string[]\n /** When provided, written to the child's stdin and stdin is closed. */\n stdin?: Buffer\n /** When true, the child's stdout is captured as a Buffer. Otherwise as utf8. */\n binaryOutput?: boolean\n /** Cap stdout capture at this many bytes. Default 64 MiB. */\n maxBytes?: number\n}\n\nexport interface RunBinaryResult {\n stdout: Buffer\n stderr: string\n exitCode: number\n}\n\n/**\n * Spawn a binary, optionally write to its stdin, and capture stdout/stderr.\n * Throws if the child exits non-zero.\n */\nexport async function runBinary(options: RunBinaryOptions): Promise<RunBinaryResult> {\n const maxBytes = options.maxBytes ?? 64 * 1024 * 1024\n return await new Promise((resolve, reject) => {\n const child = spawn(options.binary, [...(options.args ?? [])], { stdio: ['pipe', 'pipe', 'pipe'] })\n\n const stdoutChunks: Buffer[] = []\n let stdoutBytes = 0\n let stderr = ''\n let killedForOverflow = false\n\n child.stdout.on('data', (chunk: Buffer) => {\n stdoutBytes += chunk.length\n if (stdoutBytes > maxBytes) {\n if (!killedForOverflow) {\n killedForOverflow = true\n child.kill('SIGKILL')\n }\n return\n }\n stdoutChunks.push(chunk)\n })\n child.stderr.on('data', (chunk: Buffer) => {\n stderr += chunk.toString('utf8')\n })\n\n child.on('error', err => reject(err))\n child.on('close', (code) => {\n if (killedForOverflow) {\n reject(new Error(`${options.binary} stdout exceeded ${maxBytes} bytes`))\n return\n }\n const exitCode = code ?? -1\n const stdout = Buffer.concat(stdoutChunks)\n if (exitCode !== 0) {\n const tail = stderr.trim().split(/\\r?\\n/).slice(-3).join('\\n')\n reject(new Error(`${options.binary} exited ${exitCode}${tail.length > 0 ? `: ${tail}` : ''}`))\n return\n }\n resolve({\n stdout, stderr, exitCode,\n })\n })\n\n if (options.stdin === undefined) {\n child.stdin.end()\n } else {\n child.stdin.end(options.stdin)\n }\n })\n}\n","import { spawn } from 'node:child_process'\n\nimport type { RequiredBinary } from '../algorithms/types.ts'\n\n/**\n * Resolve a binary name to its absolute path on the user's PATH.\n * Returns null if not found.\n */\nexport async function which(binary: string): Promise<string | null> {\n return await new Promise((resolve) => {\n const cmd = process.platform === 'win32' ? 'where' : 'command'\n const args = process.platform === 'win32' ? [binary] : ['-v', binary]\n const child = spawn(cmd, args, { shell: process.platform !== 'win32' })\n\n let stdout = ''\n child.stdout.on('data', (chunk: Buffer) => {\n stdout += chunk.toString('utf8')\n })\n child.on('error', () => resolve(null))\n child.on('close', (code) => {\n if (code === 0) {\n const path = stdout.split(/\\r?\\n/).find(line => line.trim().length > 0)?.trim() ?? null\n resolve(path)\n } else {\n resolve(null)\n }\n })\n })\n}\n\n/**\n * Throw a clearly-actionable error when a required binary is missing.\n */\nexport async function requireBinary(req: RequiredBinary): Promise<string> {\n const path = await which(req.binary)\n if (path !== null) return path\n const lines = [`${req.binary} binary not found on PATH. Install with:`]\n if (req.install.brew !== undefined) lines.push(` macOS: brew install ${req.install.brew}`)\n if (req.install.apt !== undefined) lines.push(` Debian: apt install ${req.install.apt}`)\n if (req.install.choco !== undefined) lines.push(` Windows: choco install ${req.install.choco}`)\n throw new Error(lines.join('\\n'))\n}\n","import { randomBytes } from 'node:crypto'\nimport { rm, writeFile } from 'node:fs/promises'\nimport OS from 'node:os'\nimport PATH from 'node:path'\n\n/**\n * Write a buffer to a tempfile, run `fn` with its path, and unlink afterwards.\n * `extension` is included in the filename when provided (no leading dot).\n */\nexport async function withTempfile<T>(\n bytes: Buffer,\n extension: string | undefined,\n fn: (path: string) => Promise<T>,\n): Promise<T> {\n const ext = extension !== undefined && extension.length > 0 ? `.${extension}` : ''\n const path = PATH.join(OS.tmpdir(), `aries-hash-${randomBytes(8).toString('hex')}${ext}`)\n await writeFile(path, bytes)\n try {\n return await fn(path)\n } finally {\n await rm(path, { force: true })\n }\n}\n","import { popcount32 } from '../lib/hamming.ts'\nimport { runBinary } from '../lib/runBinary.ts'\nimport { requireBinary } from '../lib/which.ts'\nimport { withTempfile } from '../lib/withTempfile.ts'\nimport type { Algorithm, RequiredBinary } from './types.ts'\n\nconst FPCALC_BIN: RequiredBinary = {\n binary: 'fpcalc',\n install: {\n brew: 'chromaprint',\n apt: 'libchromaprint-tools',\n choco: 'chromaprint',\n },\n}\n\ninterface ChromaprintFingerprint {\n algorithm: 'chromaprint'\n duration: number\n fingerprint: number[]\n}\n\ninterface FpcalcJsonRaw {\n duration: number\n fingerprint: number[]\n}\n\nasync function runFpcalc(path: string): Promise<ChromaprintFingerprint> {\n await requireBinary(FPCALC_BIN)\n // -raw: output the fingerprint as a comma-separated list of 32-bit integers.\n // -json: combine with -raw to get JSON whose `fingerprint` is an int[].\n const { stdout } = await runBinary({ binary: 'fpcalc', args: ['-raw', '-json', path] })\n const parsed = JSON.parse(stdout.toString('utf8')) as FpcalcJsonRaw\n if (typeof parsed.duration !== 'number' || !Array.isArray(parsed.fingerprint)) {\n throw new TypeError('fpcalc returned unexpected JSON shape.')\n }\n return {\n algorithm: 'chromaprint',\n duration: parsed.duration,\n fingerprint: parsed.fingerprint,\n }\n}\n\nfunction parseChromaprintHash(raw: string): ChromaprintFingerprint {\n let parsed: unknown\n try {\n parsed = JSON.parse(raw)\n } catch {\n throw new Error('chromaprint hash must be a JSON document produced by `aries hash --algorithm chromaprint`.')\n }\n const obj = parsed as Partial<ChromaprintFingerprint>\n if (obj.algorithm !== 'chromaprint' || typeof obj.duration !== 'number' || !Array.isArray(obj.fingerprint)) {\n throw new Error('chromaprint hash JSON missing required fields (algorithm, duration, fingerprint).')\n }\n return obj as ChromaprintFingerprint\n}\n\n/**\n * Compare two chromaprint fingerprints by windowed Hamming distance over their 32-bit\n * frame integers. We slide one fingerprint over the other to find the best alignment\n * offset; bits matching across the overlap → similarity, lower is better.\n */\nfunction compareFingerprints(a: number[], b: number[]): { similarity: number; distance: number; offset: number } {\n if (a.length === 0 || b.length === 0) {\n return {\n similarity: 0, distance: Number.NaN, offset: 0,\n }\n }\n\n const span = Math.min(a.length, b.length)\n const maxOffset = Math.max(a.length, b.length) - span\n let best = {\n similarity: 0,\n distance: 32 * span,\n offset: 0,\n }\n\n for (let offset = -maxOffset; offset <= maxOffset; offset++) {\n const aStart = Math.max(0, -offset)\n const bStart = Math.max(0, offset)\n const overlap = Math.min(a.length - aStart, b.length - bStart)\n if (overlap < Math.max(8, span / 4)) continue\n let bits = 0\n for (let i = 0; i < overlap; i++) {\n bits += popcount32(a[aStart + i] ^ b[bStart + i])\n }\n const similarity = 1 - bits / (32 * overlap)\n if (similarity > best.similarity) {\n best = {\n similarity, distance: bits, offset,\n }\n }\n }\n return best\n}\n\nexport const chromaprintAlgorithm: Algorithm = {\n name: 'chromaprint',\n family: 'audio',\n inputType: 'audio',\n requires: [FPCALC_BIN],\n async hash(input) {\n const fp = input.path === undefined\n ? input.bytes === undefined\n ? null\n : await withTempfile(input.bytes, 'audio.bin', async path => await runFpcalc(path))\n : await runFpcalc(input.path)\n if (fp === null) {\n throw new Error('chromaprint requires bytes or a path.')\n }\n return JSON.stringify(fp)\n },\n async compare(a, b) {\n const fpA = parseChromaprintHash(a)\n const fpB = parseChromaprintHash(b)\n const result = compareFingerprints(fpA.fingerprint, fpB.fingerprint)\n return {\n similarity: result.similarity,\n distance: Number.isFinite(result.distance) ? result.distance : undefined,\n metric: 'chromaprint-windowed-hamming',\n }\n },\n}\n","import { readFile } from 'node:fs/promises'\n\nimport sharp from 'sharp'\n\nimport { hammingHex } from '../lib/hamming.ts'\nimport type { Algorithm } from './types.ts'\n\n/**\n * dHash (difference hash): resize to 9×8 grayscale, then for each row produce 8 bits\n * representing whether pixel[i] > pixel[i+1]. 8 rows × 8 bits = 64 bits → 16 hex chars.\n */\nexport const dhashAlgorithm: Algorithm = {\n name: 'dhash',\n family: 'perceptual-image',\n inputType: 'image',\n async hash(input) {\n const source = input.bytes ?? (input.path === undefined ? undefined : await readFile(input.path))\n if (source === undefined) {\n throw new Error('dhash requires bytes or a path.')\n }\n const raw = await sharp(source)\n .resize(9, 8, { fit: 'fill' })\n .grayscale()\n .raw()\n .toBuffer()\n if (raw.length !== 9 * 8) {\n throw new Error(`dhash unexpected raw buffer length ${raw.length}`)\n }\n let bits = ''\n for (let row = 0; row < 8; row++) {\n for (let col = 0; col < 8; col++) {\n const left = raw[row * 9 + col]\n const right = raw[row * 9 + col + 1]\n bits += left > right ? '1' : '0'\n }\n }\n let hex = ''\n for (let i = 0; i < bits.length; i += 4) {\n hex += Number.parseInt(bits.slice(i, i + 4), 2).toString(16)\n }\n return hex\n },\n async compare(a, b) {\n const dist = hammingHex(a, b)\n const bits = (a.length / 2) * 8\n return {\n distance: dist, similarity: 1 - dist / bits, metric: `hamming-${bits}`,\n }\n },\n}\n","import { Nilsimsa } from 'nilsimsa'\n\nimport type { Algorithm } from './types.ts'\n\nexport const nilsimsaAlgorithm: Algorithm = {\n name: 'nilsimsa',\n family: 'fuzzy-byte',\n inputType: 'bytes',\n async hash(input) {\n if (input.bytes === undefined) {\n throw new Error('nilsimsa requires loaded bytes.')\n }\n const n = new Nilsimsa(input.bytes)\n return n.digest('hex')\n },\n async compare(a, b) {\n // Nilsimsa.compare returns a similarity score in [-128, 128].\n // 128 = identical; 0 ≈ unrelated; -128 = perfectly anti-correlated.\n const raw = Nilsimsa.compare(a, b, 'hex')\n const similarity = Math.max(0, Math.min(1, (raw + 128) / 256))\n return {\n distance: 128 - raw, similarity, metric: 'nilsimsa-score',\n }\n },\n}\n","import { createRequire } from 'node:module'\n\nimport sharp from 'sharp'\n\nimport { hammingHex } from '../lib/hamming.ts'\nimport type { Algorithm } from './types.ts'\n\n/**\n * pdq-wasm ships a CommonJS entry that uses `require` to load its bundled WASM file.\n * Aries is ESM, so we use `createRequire` to bridge — this picks the CJS dist via the\n * package's `exports.require` condition, which can resolve the relative WASM path.\n */\nconst require = createRequire(import.meta.url)\ninterface PDQHashResult { hash: Uint8Array; quality: number }\ninterface PDQModule {\n init(): Promise<void>\n hash(input: { data: Uint8Array; width: number; height: number; channels: 1 | 3 }): PDQHashResult\n toHex(hash: Uint8Array): string\n}\nconst { PDQ } = require('pdq-wasm') as { PDQ: PDQModule }\n\nlet initialized = false\nasync function ensureInit(): Promise<void> {\n if (initialized) return\n await PDQ.init()\n initialized = true\n}\n\n/**\n * Decode the input image to RGB raw bytes that pdq-wasm can consume directly.\n * sharp handles JPEG/PNG/WebP/AVIF/etc. transparently.\n */\nasync function toRgbRaw(source: Buffer | string): Promise<{ data: Uint8Array; width: number; height: number }> {\n const { data, info } = await sharp(source).removeAlpha().raw().toBuffer({ resolveWithObject: true })\n return {\n data: new Uint8Array(data.buffer, data.byteOffset, data.byteLength),\n width: info.width,\n height: info.height,\n }\n}\n\nexport const pdqAlgorithm: Algorithm = {\n name: 'pdq',\n family: 'perceptual-image',\n inputType: 'image',\n async hash(input) {\n const source = input.path ?? input.bytes\n if (source === undefined) {\n throw new Error('pdq requires bytes or a path.')\n }\n await ensureInit()\n const rgb = await toRgbRaw(source)\n const result = PDQ.hash({\n data: rgb.data, width: rgb.width, height: rgb.height, channels: 3,\n })\n return PDQ.toHex(result.hash)\n },\n async compare(a, b) {\n const dist = hammingHex(a, b)\n const bits = (a.length / 2) * 8\n return {\n distance: dist, similarity: 1 - dist / bits, metric: `hamming-${bits}`,\n }\n },\n}\n","import phashLib from 'sharp-phash'\n\nimport { hammingHex } from '../lib/hamming.ts'\nimport type { Algorithm } from './types.ts'\n\nconst phash = phashLib as unknown as (image: Buffer | string) => Promise<string>\n\n/**\n * sharp-phash returns a 64-character '01' binary string. We pack it into 16-char hex\n * for parity with the other perceptual image algorithms.\n */\nfunction binaryToHex(bin: string): string {\n if (!/^[01]+$/.test(bin)) {\n throw new TypeError(`phash returned unexpected output: ${bin.slice(0, 20)}…`)\n }\n const padded = bin.padStart(Math.ceil(bin.length / 4) * 4, '0')\n let hex = ''\n for (let i = 0; i < padded.length; i += 4) {\n hex += Number.parseInt(padded.slice(i, i + 4), 2).toString(16)\n }\n return hex\n}\n\nexport const phashAlgorithm: Algorithm = {\n name: 'phash',\n family: 'perceptual-image',\n inputType: 'image',\n async hash(input) {\n const source = input.path ?? input.bytes\n if (source === undefined) {\n throw new Error('phash requires bytes or a path.')\n }\n const bin = await phash(source)\n return binaryToHex(bin)\n },\n async compare(a, b) {\n const dist = hammingHex(a, b)\n const bits = (a.length / 2) * 8\n return {\n distance: dist, similarity: 1 - dist / bits, metric: `hamming-${bits}`,\n }\n },\n}\n","import { createHash } from 'node:crypto'\n\nimport type { Algorithm } from './types.ts'\n\nexport const sha256Algorithm: Algorithm = {\n name: 'sha256',\n family: 'strict',\n inputType: 'bytes',\n async hash(input) {\n if (input.bytes === undefined) {\n throw new Error('sha256 requires loaded bytes.')\n }\n return createHash('sha256').update(input.bytes).digest('hex')\n },\n async compare(a, b) {\n return {\n similarity: a === b ? 1 : 0,\n distance: a === b ? 0 : 1,\n metric: 'exact-match',\n }\n },\n}\n","/**\n * Standard Levenshtein edit distance between two strings.\n * O(m·n) time, O(min(m,n)) space.\n */\nexport function levenshtein(a: string, b: string): number {\n if (a === b) return 0\n if (a.length === 0) return b.length\n if (b.length === 0) return a.length\n\n // Make `s1` the longer string so the row width is min(m,n)+1.\n let s1 = a\n let s2 = b\n if (s1.length < s2.length) {\n const tmp = s1\n s1 = s2\n s2 = tmp\n }\n\n const m = s1.length\n const n = s2.length\n let prev: number[] = Array.from({ length: n + 1 }, (_, j) => j)\n let curr: number[] = Array.from({ length: n + 1 }, () => 0)\n\n for (let i = 1; i <= m; i++) {\n curr[0] = i\n const cp1 = s1.codePointAt(i - 1)\n for (let j = 1; j <= n; j++) {\n const cost = cp1 === s2.codePointAt(j - 1) ? 0 : 1\n const del = prev[j] + 1\n const ins = curr[j - 1] + 1\n const sub = prev[j - 1] + cost\n curr[j] = Math.min(del, ins, sub)\n }\n const tmp = prev\n prev = curr\n curr = tmp\n }\n return prev[n]\n}\n","import { levenshtein } from '../lib/levenshtein.ts'\nimport { runBinary } from '../lib/runBinary.ts'\nimport { requireBinary } from '../lib/which.ts'\nimport type { Algorithm, RequiredBinary } from './types.ts'\n\nconst SSDEEP_BIN: RequiredBinary = {\n binary: 'ssdeep',\n install: {\n brew: 'ssdeep',\n apt: 'ssdeep',\n choco: 'ssdeep',\n },\n}\n\n/**\n * Parse an ssdeep hash of the form `<block_size>:<h1>:<h2>` (filename suffix is dropped).\n */\nfunction parseSsdeepHash(raw: string): { blockSize: number; h1: string; h2: string } {\n const cleaned = raw.replace(/,.*$/u, '').trim()\n const parts = cleaned.split(':')\n if (parts.length < 3) {\n throw new Error(`Invalid ssdeep hash: ${raw}`)\n }\n const blockSize = Number.parseInt(parts[0], 10)\n if (!Number.isFinite(blockSize) || blockSize <= 0) {\n throw new Error(`Invalid ssdeep block size: ${parts[0]}`)\n }\n return {\n blockSize, h1: parts[1], h2: parts[2],\n }\n}\n\nfunction levenshteinSimilarity(a: string, b: string): number {\n if (a.length === 0 && b.length === 0) return 1\n const dist = levenshtein(a, b)\n const maxLen = Math.max(a.length, b.length, 1)\n return Math.max(0, 1 - dist / maxLen)\n}\n\n/**\n * Approximate ssdeep similarity using Levenshtein on whichever sub-hash pair shares a\n * compatible block size (1×, 2×, or 0.5×). Returns 0 if block sizes are incompatible.\n *\n * This is NOT the canonical ssdeep score — that algorithm applies a block-size\n * attenuation curve we don't replicate here. The metric label `ssdeep-levenshtein`\n * makes that explicit.\n */\nfunction ssdeepSimilarity(rawA: string, rawB: string): { similarity: number; distance: number } {\n const a = parseSsdeepHash(rawA)\n const b = parseSsdeepHash(rawB)\n if (a.blockSize === b.blockSize) {\n const s1 = levenshteinSimilarity(a.h1, b.h1)\n const s2 = levenshteinSimilarity(a.h2, b.h2)\n const similarity = Math.max(s1, s2)\n const distance = Math.round((1 - similarity) * Math.max(a.h1.length, b.h1.length, a.h2.length, b.h2.length))\n return { similarity, distance }\n }\n if (a.blockSize === b.blockSize * 2) {\n const similarity = levenshteinSimilarity(a.h2, b.h1)\n return { similarity, distance: Math.round((1 - similarity) * Math.max(a.h2.length, b.h1.length)) }\n }\n if (b.blockSize === a.blockSize * 2) {\n const similarity = levenshteinSimilarity(a.h1, b.h2)\n return { similarity, distance: Math.round((1 - similarity) * Math.max(a.h1.length, b.h2.length)) }\n }\n return { similarity: 0, distance: Number.NaN }\n}\n\nexport const ssdeepAlgorithm: Algorithm = {\n name: 'ssdeep',\n family: 'fuzzy-byte',\n inputType: 'bytes',\n requires: [SSDEEP_BIN],\n async hash(input) {\n if (input.bytes === undefined) {\n throw new Error('ssdeep requires loaded bytes.')\n }\n await requireBinary(SSDEEP_BIN)\n // -b: bare output (no header line, no filename column)\n // -s: silent — suppress warnings/banner\n // We still get a header, so parse defensively.\n const { stdout } = await runBinary({\n binary: 'ssdeep', args: ['-b', '-s'], stdin: input.bytes,\n })\n const text = stdout.toString('utf8')\n const lines = text.split(/\\r?\\n/).map(l => l.trim()).filter(l => l.length > 0)\n // Skip the \"ssdeep,1.1--blocksize:hash:hash,filename\" header if present.\n const hashLine = lines.find(l => !l.startsWith('ssdeep,')) ?? lines.at(-1)\n if (hashLine === undefined) {\n throw new Error('ssdeep produced no output.')\n }\n return hashLine.replace(/,.*$/u, '')\n },\n async compare(a, b) {\n const { similarity, distance } = ssdeepSimilarity(a, b)\n return {\n similarity, distance: Number.isFinite(distance) ? distance : undefined, metric: 'ssdeep-levenshtein',\n }\n },\n}\n","import tlsh from 'tlsh'\n\nimport { hammingHex } from '../lib/hamming.ts'\nimport type { Algorithm } from './types.ts'\n\n/**\n * The `tlsh` npm package exports a single function: `tlsh(data: string): string`.\n * It does NOT expose the canonical diff algorithm publicly. We use a Hamming-distance\n * proxy over the hash bytes for `compare`. This is a reasonable approximation, not the\n * canonical TLSH-diff score — the metric label `tlsh-bit-hamming` makes that explicit.\n */\n\nexport const tlshAlgorithm: Algorithm = {\n name: 'tlsh',\n family: 'fuzzy-byte',\n inputType: 'bytes',\n async hash(input) {\n if (input.bytes === undefined) {\n throw new Error('tlsh requires loaded bytes.')\n }\n if (input.bytes.length < 50) {\n throw new Error(`tlsh requires at least 50 bytes of input (got ${input.bytes.length}).`)\n }\n return tlsh(input.bytes.toString('binary'))\n },\n async compare(a, b) {\n if (a.length !== b.length) {\n throw new Error(`tlsh hash length mismatch: ${a.length} vs ${b.length}`)\n }\n // TLSH hashes carry a leading version/type byte that's identical for hashes\n // produced by the same library — skip 4 hex chars (version+checksum bytes)\n // before measuring distance for slightly more meaningful comparison.\n const skip = a.length >= 8 ? 4 : 0\n const aBody = a.slice(skip)\n const bBody = b.slice(skip)\n const distance = hammingHex(aBody, bBody)\n const bits = (aBody.length / 2) * 8\n return {\n distance,\n similarity: 1 - distance / bits,\n metric: 'tlsh-bit-hamming',\n }\n },\n}\n","import { randomBytes } from 'node:crypto'\nimport {\n mkdtemp, readdir, readFile, rm,\n} from 'node:fs/promises'\nimport OS from 'node:os'\nimport PATH from 'node:path'\n\nimport { hammingHex } from '../lib/hamming.ts'\nimport { runBinary } from '../lib/runBinary.ts'\nimport { requireBinary } from '../lib/which.ts'\nimport { withTempfile } from '../lib/withTempfile.ts'\nimport { pdqAlgorithm } from './pdq.ts'\nimport { phashAlgorithm } from './phash.ts'\nimport type { Algorithm, RequiredBinary } from './types.ts'\n\nconst FFMPEG_BIN: RequiredBinary = {\n binary: 'ffmpeg',\n install: {\n brew: 'ffmpeg',\n apt: 'ffmpeg',\n choco: 'ffmpeg',\n },\n}\n\nexport type FrameAlgorithmName = 'phash' | 'pdq'\nexport const SUPPORTED_FRAME_ALGORITHMS = ['phash', 'pdq'] as const\n\ninterface VideoFramesFingerprint {\n algorithm: 'video-frames'\n fps: number\n frameAlgorithm: FrameAlgorithmName\n duration: number\n frames: { t: number; hash: string }[]\n}\n\nexport const DEFAULT_FPS = 1\nexport const DEFAULT_FRAME_ALGORITHM: FrameAlgorithmName = 'phash'\n\nasync function extractFrames(videoPath: string, fps: number): Promise<{ frames: Buffer[] }> {\n await requireBinary(FFMPEG_BIN)\n const dir = await mkdtemp(PATH.join(OS.tmpdir(), `aries-vframes-${randomBytes(6).toString('hex')}-`))\n try {\n await runBinary({\n binary: 'ffmpeg',\n args: [\n '-hide_banner',\n '-loglevel',\n 'error',\n '-i',\n videoPath,\n '-vf',\n `fps=${fps},scale=128:128:force_original_aspect_ratio=disable`,\n '-q:v',\n '5',\n PATH.join(dir, 'frame-%05d.jpg'),\n ],\n })\n const entries = (await readdir(dir)).filter(name => name.endsWith('.jpg')).toSorted()\n const frames = await Promise.all(entries.map(async name => await readFile(PATH.join(dir, name))))\n return { frames }\n } finally {\n await rm(dir, { recursive: true, force: true })\n }\n}\n\nfunction frameHasher(name: FrameAlgorithmName): (bytes: Buffer) => Promise<string> {\n switch (name) {\n case 'phash': { return async bytes => await phashAlgorithm.hash({ bytes })\n }\n case 'pdq': { return async bytes => await pdqAlgorithm.hash({ bytes })\n }\n }\n}\n\nasync function fingerprintVideo(\n videoPath: string,\n fps: number,\n frameAlgorithm: FrameAlgorithmName,\n): Promise<VideoFramesFingerprint> {\n const { frames } = await extractFrames(videoPath, fps)\n const hashFrame = frameHasher(frameAlgorithm)\n const hashes = await Promise.all(frames.map(async (frame, idx) => ({\n t: idx / fps,\n hash: await hashFrame(frame),\n })))\n return {\n algorithm: 'video-frames',\n fps,\n frameAlgorithm,\n duration: frames.length / fps,\n frames: hashes,\n }\n}\n\nfunction parseVideoFramesHash(raw: string): VideoFramesFingerprint {\n let parsed: unknown\n try {\n parsed = JSON.parse(raw)\n } catch {\n throw new Error('video-frames hash must be JSON produced by `aries hash --algorithm video-frames`.')\n }\n const obj = parsed as Partial<VideoFramesFingerprint>\n if (\n obj.algorithm !== 'video-frames'\n || typeof obj.fps !== 'number'\n || typeof obj.duration !== 'number'\n || !Array.isArray(obj.frames)\n ) {\n throw new Error('video-frames hash JSON missing required fields.')\n }\n // frameAlgorithm was added in a later revision; default to phash when older hashes lack it.\n if (obj.frameAlgorithm === undefined) {\n return { ...obj, frameAlgorithm: 'phash' } as VideoFramesFingerprint\n }\n return obj as VideoFramesFingerprint\n}\n\ninterface VideoFramesCompareDetails {\n similarity: number\n distance: number\n bestOffsetSeconds: number\n overlapSeconds: number\n}\n\n/** Sliding-window Hamming distance over the two frame sequences. */\nfunction compareFrameSequences(\n a: VideoFramesFingerprint,\n b: VideoFramesFingerprint,\n): VideoFramesCompareDetails {\n const fps = Math.min(a.fps, b.fps)\n if (a.frames.length === 0 || b.frames.length === 0) {\n return {\n similarity: 0, distance: Number.NaN, bestOffsetSeconds: 0, overlapSeconds: 0,\n }\n }\n const minLen = Math.min(a.frames.length, b.frames.length)\n const maxOffset = Math.max(a.frames.length, b.frames.length) - 1\n let best: VideoFramesCompareDetails = {\n similarity: 0,\n distance: Number.NaN,\n bestOffsetSeconds: 0,\n overlapSeconds: 0,\n }\n const minOverlap = Math.max(2, Math.floor(minLen / 4))\n for (let offset = -maxOffset; offset <= maxOffset; offset++) {\n const aStart = Math.max(0, -offset)\n const bStart = Math.max(0, offset)\n const overlap = Math.min(a.frames.length - aStart, b.frames.length - bStart)\n if (overlap < minOverlap) continue\n let totalBits = 0\n let bitWidth = 0\n for (let i = 0; i < overlap; i++) {\n const ah = a.frames[aStart + i].hash\n const bh = b.frames[bStart + i].hash\n if (ah.length !== bh.length) continue\n totalBits += hammingHex(ah, bh)\n bitWidth += (ah.length / 2) * 8\n }\n if (bitWidth === 0) continue\n const similarity = 1 - totalBits / bitWidth\n if (similarity > best.similarity) {\n best = {\n similarity,\n distance: totalBits,\n bestOffsetSeconds: offset / fps,\n overlapSeconds: overlap / fps,\n }\n }\n }\n return best\n}\n\nfunction parseFps(options: Record<string, unknown> | undefined): number {\n const raw = options?.fps\n if (raw === undefined) return DEFAULT_FPS\n const value = typeof raw === 'string' ? Number.parseFloat(raw) : Number(raw)\n if (!Number.isFinite(value) || value <= 0 || value > 60) {\n const display = typeof raw === 'string' || typeof raw === 'number' ? String(raw) : '<non-scalar>'\n throw new RangeError(`Invalid --fps ${display}: expected a number in (0, 60].`)\n }\n return value\n}\n\nfunction parseFrameAlgorithm(options: Record<string, unknown> | undefined): FrameAlgorithmName {\n const raw = options?.frameAlgorithm\n if (raw === undefined) return DEFAULT_FRAME_ALGORITHM\n if (typeof raw !== 'string' || !(SUPPORTED_FRAME_ALGORITHMS as readonly string[]).includes(raw)) {\n const display = typeof raw === 'string' ? raw : `<${typeof raw}>`\n throw new RangeError(`Invalid --frame-algorithm ${display}: expected one of ${SUPPORTED_FRAME_ALGORITHMS.join(', ')}.`)\n }\n return raw as FrameAlgorithmName\n}\n\nexport const videoFramesAlgorithm: Algorithm = {\n name: 'video-frames',\n family: 'video',\n inputType: 'video',\n requires: [FFMPEG_BIN],\n async hash(input) {\n const fps = parseFps(input.options)\n const frameAlgorithm = parseFrameAlgorithm(input.options)\n const fp = input.path === undefined\n ? input.bytes === undefined\n ? null\n : await withTempfile(input.bytes, 'video.bin', async path => await fingerprintVideo(path, fps, frameAlgorithm))\n : await fingerprintVideo(input.path, fps, frameAlgorithm)\n if (fp === null) {\n throw new Error('video-frames requires bytes or a path.')\n }\n return JSON.stringify(fp)\n },\n async compare(a, b) {\n const fpA = parseVideoFramesHash(a)\n const fpB = parseVideoFramesHash(b)\n if (fpA.frameAlgorithm !== fpB.frameAlgorithm) {\n throw new Error(`Cannot compare video-frames hashes with different frame algorithms (${fpA.frameAlgorithm} vs ${fpB.frameAlgorithm}).`)\n }\n const result = compareFrameSequences(fpA, fpB)\n return {\n similarity: result.similarity,\n distance: Number.isFinite(result.distance) ? result.distance : undefined,\n metric: `frame-sequence-${fpA.frameAlgorithm}@${fpA.fps}fps`,\n }\n },\n}\n","import { ObjectHasher } from '@xyo-network/hash'\n\nimport type { Algorithm } from './types.ts'\n\nexport const xyoAlgorithm: Algorithm = {\n name: 'xyo',\n family: 'strict',\n inputType: 'bytes',\n async hash(input) {\n if (input.bytes === undefined) {\n throw new Error('xyo requires loaded bytes.')\n }\n let parsed: unknown\n try {\n parsed = JSON.parse(input.bytes.toString('utf8'))\n } catch {\n throw new Error('xyo requires valid JSON input.')\n }\n return await ObjectHasher.hash(parsed as Record<string, unknown>)\n },\n async compare(a, b) {\n return {\n similarity: a === b ? 1 : 0,\n distance: a === b ? 0 : 1,\n metric: 'exact-match',\n }\n },\n}\n","import { blockhashAlgorithm } from './blockhash.ts'\nimport { chromaprintAlgorithm } from './chromaprint.ts'\nimport { dhashAlgorithm } from './dhash.ts'\nimport { nilsimsaAlgorithm } from './nilsimsa.ts'\nimport { pdqAlgorithm } from './pdq.ts'\nimport { phashAlgorithm } from './phash.ts'\nimport { sha256Algorithm } from './sha256.ts'\nimport { ssdeepAlgorithm } from './ssdeep.ts'\nimport { tlshAlgorithm } from './tlsh.ts'\nimport type { Algorithm } from './types.ts'\nimport { videoFramesAlgorithm } from './videoFrames.ts'\nimport { xyoAlgorithm } from './xyo.ts'\n\nconst REGISTRY: ReadonlyMap<string, Algorithm> = new Map([\n sha256Algorithm,\n xyoAlgorithm,\n tlshAlgorithm,\n nilsimsaAlgorithm,\n ssdeepAlgorithm,\n phashAlgorithm,\n dhashAlgorithm,\n blockhashAlgorithm,\n pdqAlgorithm,\n chromaprintAlgorithm,\n videoFramesAlgorithm,\n].map(algo => [algo.name, algo]))\n\nexport function getAlgorithm(name: string): Algorithm {\n const algo = REGISTRY.get(name)\n if (algo === undefined) {\n const known = [...REGISTRY.keys()].join(', ')\n throw new Error(`Unknown algorithm '${name}'. Known: ${known}`)\n }\n return algo\n}\n\nexport function listAlgorithms(): readonly string[] {\n return [...REGISTRY.keys()]\n}\n\nexport type {\n Algorithm, AlgorithmFamily, AlgorithmInputType, CompareResult, HashInput,\n} from './types.ts'\n"],"mappings":"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","names":["spawn","sharp","require","sharp","randomBytes","readFile","rm","OS","PATH","PATH","OS","randomBytes","readFile","rm"]}
@@ -1,27 +0,0 @@
1
- // src/actions/hash/algorithms/nilsimsa.ts
2
- import { Nilsimsa } from "nilsimsa";
3
- var nilsimsaAlgorithm = {
4
- name: "nilsimsa",
5
- family: "fuzzy-byte",
6
- inputType: "bytes",
7
- async hash(input) {
8
- if (input.bytes === void 0) {
9
- throw new Error("nilsimsa requires loaded bytes.");
10
- }
11
- const n = new Nilsimsa(input.bytes);
12
- return n.digest("hex");
13
- },
14
- async compare(a, b) {
15
- const raw = Nilsimsa.compare(a, b, "hex");
16
- const similarity = Math.max(0, Math.min(1, (raw + 128) / 256));
17
- return {
18
- distance: 128 - raw,
19
- similarity,
20
- metric: "nilsimsa-score"
21
- };
22
- }
23
- };
24
- export {
25
- nilsimsaAlgorithm
26
- };
27
- //# sourceMappingURL=nilsimsa.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../../src/actions/hash/algorithms/nilsimsa.ts"],"sourcesContent":["import { Nilsimsa } from 'nilsimsa'\n\nimport type { Algorithm } from './types.ts'\n\nexport const nilsimsaAlgorithm: Algorithm = {\n name: 'nilsimsa',\n family: 'fuzzy-byte',\n inputType: 'bytes',\n async hash(input) {\n if (input.bytes === undefined) {\n throw new Error('nilsimsa requires loaded bytes.')\n }\n const n = new Nilsimsa(input.bytes)\n return n.digest('hex')\n },\n async compare(a, b) {\n // Nilsimsa.compare returns a similarity score in [-128, 128].\n // 128 = identical; 0 ≈ unrelated; -128 = perfectly anti-correlated.\n const raw = Nilsimsa.compare(a, b, 'hex')\n const similarity = Math.max(0, Math.min(1, (raw + 128) / 256))\n return {\n distance: 128 - raw, similarity, metric: 'nilsimsa-score',\n }\n },\n}\n"],"mappings":";AAAA,SAAS,gBAAgB;AAIlB,IAAM,oBAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,MAAM,KAAK,OAAO;AAChB,QAAI,MAAM,UAAU,QAAW;AAC7B,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACnD;AACA,UAAM,IAAI,IAAI,SAAS,MAAM,KAAK;AAClC,WAAO,EAAE,OAAO,KAAK;AAAA,EACvB;AAAA,EACA,MAAM,QAAQ,GAAG,GAAG;AAGlB,UAAM,MAAM,SAAS,QAAQ,GAAG,GAAG,KAAK;AACxC,UAAM,aAAa,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,MAAM,OAAO,GAAG,CAAC;AAC7D,WAAO;AAAA,MACL,UAAU,MAAM;AAAA,MAAK;AAAA,MAAY,QAAQ;AAAA,IAC3C;AAAA,EACF;AACF;","names":[]}
@@ -1,83 +0,0 @@
1
- // src/actions/hash/algorithms/pdq.ts
2
- import { createRequire } from "module";
3
- import sharp from "sharp";
4
-
5
- // src/actions/hash/lib/hamming.ts
6
- function popcount8(byte) {
7
- let count = 0;
8
- let value = byte & 255;
9
- while (value !== 0) {
10
- count += value & 1;
11
- value >>>= 1;
12
- }
13
- return count;
14
- }
15
- function hammingHex(a, b) {
16
- if (a.length !== b.length) {
17
- throw new Error(`Hash length mismatch: ${a.length} vs ${b.length}`);
18
- }
19
- if (a.length % 2 !== 0) {
20
- throw new Error(`Hash hex length must be even, got ${a.length}`);
21
- }
22
- let dist = 0;
23
- for (let i = 0; i < a.length; i += 2) {
24
- const xa = Number.parseInt(a.slice(i, i + 2), 16);
25
- const xb = Number.parseInt(b.slice(i, i + 2), 16);
26
- if (Number.isNaN(xa) || Number.isNaN(xb)) {
27
- throw new TypeError(`Invalid hex at position ${i}: '${a.slice(i, i + 2)}' / '${b.slice(i, i + 2)}'`);
28
- }
29
- dist += popcount8(xa ^ xb);
30
- }
31
- return dist;
32
- }
33
-
34
- // src/actions/hash/algorithms/pdq.ts
35
- var require2 = createRequire(import.meta.url);
36
- var { PDQ } = require2("pdq-wasm");
37
- var initialized = false;
38
- async function ensureInit() {
39
- if (initialized) return;
40
- await PDQ.init();
41
- initialized = true;
42
- }
43
- async function toRgbRaw(source) {
44
- const { data, info } = await sharp(source).removeAlpha().raw().toBuffer({ resolveWithObject: true });
45
- return {
46
- data: new Uint8Array(data.buffer, data.byteOffset, data.byteLength),
47
- width: info.width,
48
- height: info.height
49
- };
50
- }
51
- var pdqAlgorithm = {
52
- name: "pdq",
53
- family: "perceptual-image",
54
- inputType: "image",
55
- async hash(input) {
56
- const source = input.path ?? input.bytes;
57
- if (source === void 0) {
58
- throw new Error("pdq requires bytes or a path.");
59
- }
60
- await ensureInit();
61
- const rgb = await toRgbRaw(source);
62
- const result = PDQ.hash({
63
- data: rgb.data,
64
- width: rgb.width,
65
- height: rgb.height,
66
- channels: 3
67
- });
68
- return PDQ.toHex(result.hash);
69
- },
70
- async compare(a, b) {
71
- const dist = hammingHex(a, b);
72
- const bits = a.length / 2 * 8;
73
- return {
74
- distance: dist,
75
- similarity: 1 - dist / bits,
76
- metric: `hamming-${bits}`
77
- };
78
- }
79
- };
80
- export {
81
- pdqAlgorithm
82
- };
83
- //# sourceMappingURL=pdq.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../../src/actions/hash/algorithms/pdq.ts","../../../../src/actions/hash/lib/hamming.ts"],"sourcesContent":["import { createRequire } from 'node:module'\n\nimport sharp from 'sharp'\n\nimport { hammingHex } from '../lib/hamming.ts'\nimport type { Algorithm } from './types.ts'\n\n/**\n * pdq-wasm ships a CommonJS entry that uses `require` to load its bundled WASM file.\n * Aries is ESM, so we use `createRequire` to bridge — this picks the CJS dist via the\n * package's `exports.require` condition, which can resolve the relative WASM path.\n */\nconst require = createRequire(import.meta.url)\ninterface PDQHashResult { hash: Uint8Array; quality: number }\ninterface PDQModule {\n init(): Promise<void>\n hash(input: { data: Uint8Array; width: number; height: number; channels: 1 | 3 }): PDQHashResult\n toHex(hash: Uint8Array): string\n}\nconst { PDQ } = require('pdq-wasm') as { PDQ: PDQModule }\n\nlet initialized = false\nasync function ensureInit(): Promise<void> {\n if (initialized) return\n await PDQ.init()\n initialized = true\n}\n\n/**\n * Decode the input image to RGB raw bytes that pdq-wasm can consume directly.\n * sharp handles JPEG/PNG/WebP/AVIF/etc. transparently.\n */\nasync function toRgbRaw(source: Buffer | string): Promise<{ data: Uint8Array; width: number; height: number }> {\n const { data, info } = await sharp(source).removeAlpha().raw().toBuffer({ resolveWithObject: true })\n return {\n data: new Uint8Array(data.buffer, data.byteOffset, data.byteLength),\n width: info.width,\n height: info.height,\n }\n}\n\nexport const pdqAlgorithm: Algorithm = {\n name: 'pdq',\n family: 'perceptual-image',\n inputType: 'image',\n async hash(input) {\n const source = input.path ?? input.bytes\n if (source === undefined) {\n throw new Error('pdq requires bytes or a path.')\n }\n await ensureInit()\n const rgb = await toRgbRaw(source)\n const result = PDQ.hash({\n data: rgb.data, width: rgb.width, height: rgb.height, channels: 3,\n })\n return PDQ.toHex(result.hash)\n },\n async compare(a, b) {\n const dist = hammingHex(a, b)\n const bits = (a.length / 2) * 8\n return {\n distance: dist, similarity: 1 - dist / bits, metric: `hamming-${bits}`,\n }\n },\n}\n","/**\n * Population count for an 8-bit value (number of set bits).\n */\nfunction popcount8(byte: number): number {\n let count = 0\n let value = byte & 0xff\n while (value !== 0) {\n count += value & 1\n value >>>= 1\n }\n return count\n}\n\n/**\n * Hamming distance between two equal-length lowercase-hex strings.\n * Throws when the lengths differ.\n */\nexport function hammingHex(a: string, b: string): number {\n if (a.length !== b.length) {\n throw new Error(`Hash length mismatch: ${a.length} vs ${b.length}`)\n }\n if (a.length % 2 !== 0) {\n throw new Error(`Hash hex length must be even, got ${a.length}`)\n }\n let dist = 0\n for (let i = 0; i < a.length; i += 2) {\n const xa = Number.parseInt(a.slice(i, i + 2), 16)\n const xb = Number.parseInt(b.slice(i, i + 2), 16)\n if (Number.isNaN(xa) || Number.isNaN(xb)) {\n throw new TypeError(`Invalid hex at position ${i}: '${a.slice(i, i + 2)}' / '${b.slice(i, i + 2)}'`)\n }\n dist += popcount8(xa ^ xb)\n }\n return dist\n}\n\n/**\n * Bit-length of an even-length hex string.\n */\nexport function bitLengthHex(hex: string): number {\n return (hex.length / 2) * 8\n}\n\n/**\n * Population count for a 32-bit unsigned value (number of set bits).\n * Uses the parallel-prefix bit trick.\n */\nexport function popcount32(value: number): number {\n let v = Math.trunc(value)\n v = v - ((v >>> 1) & 0x55_55_55_55)\n v = (v & 0x33_33_33_33) + ((v >>> 2) & 0x33_33_33_33)\n v = (v + (v >>> 4)) & 0x0f_0f_0f_0f\n return ((v * 0x01_01_01_01) >>> 24) & 0xff\n}\n"],"mappings":";AAAA,SAAS,qBAAqB;AAE9B,OAAO,WAAW;;;ACClB,SAAS,UAAU,MAAsB;AACvC,MAAI,QAAQ;AACZ,MAAI,QAAQ,OAAO;AACnB,SAAO,UAAU,GAAG;AAClB,aAAS,QAAQ;AACjB,eAAW;AAAA,EACb;AACA,SAAO;AACT;AAMO,SAAS,WAAW,GAAW,GAAmB;AACvD,MAAI,EAAE,WAAW,EAAE,QAAQ;AACzB,UAAM,IAAI,MAAM,yBAAyB,EAAE,MAAM,OAAO,EAAE,MAAM,EAAE;AAAA,EACpE;AACA,MAAI,EAAE,SAAS,MAAM,GAAG;AACtB,UAAM,IAAI,MAAM,qCAAqC,EAAE,MAAM,EAAE;AAAA,EACjE;AACA,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK,GAAG;AACpC,UAAM,KAAK,OAAO,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE;AAChD,UAAM,KAAK,OAAO,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE;AAChD,QAAI,OAAO,MAAM,EAAE,KAAK,OAAO,MAAM,EAAE,GAAG;AACxC,YAAM,IAAI,UAAU,2BAA2B,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,GAAG;AAAA,IACrG;AACA,YAAQ,UAAU,KAAK,EAAE;AAAA,EAC3B;AACA,SAAO;AACT;;;ADtBA,IAAMA,WAAU,cAAc,YAAY,GAAG;AAO7C,IAAM,EAAE,IAAI,IAAIA,SAAQ,UAAU;AAElC,IAAI,cAAc;AAClB,eAAe,aAA4B;AACzC,MAAI,YAAa;AACjB,QAAM,IAAI,KAAK;AACf,gBAAc;AAChB;AAMA,eAAe,SAAS,QAAuF;AAC7G,QAAM,EAAE,MAAM,KAAK,IAAI,MAAM,MAAM,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,mBAAmB,KAAK,CAAC;AACnG,SAAO;AAAA,IACL,MAAM,IAAI,WAAW,KAAK,QAAQ,KAAK,YAAY,KAAK,UAAU;AAAA,IAClE,OAAO,KAAK;AAAA,IACZ,QAAQ,KAAK;AAAA,EACf;AACF;AAEO,IAAM,eAA0B;AAAA,EACrC,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,MAAM,KAAK,OAAO;AAChB,UAAM,SAAS,MAAM,QAAQ,MAAM;AACnC,QAAI,WAAW,QAAW;AACxB,YAAM,IAAI,MAAM,+BAA+B;AAAA,IACjD;AACA,UAAM,WAAW;AACjB,UAAM,MAAM,MAAM,SAAS,MAAM;AACjC,UAAM,SAAS,IAAI,KAAK;AAAA,MACtB,MAAM,IAAI;AAAA,MAAM,OAAO,IAAI;AAAA,MAAO,QAAQ,IAAI;AAAA,MAAQ,UAAU;AAAA,IAClE,CAAC;AACD,WAAO,IAAI,MAAM,OAAO,IAAI;AAAA,EAC9B;AAAA,EACA,MAAM,QAAQ,GAAG,GAAG;AAClB,UAAM,OAAO,WAAW,GAAG,CAAC;AAC5B,UAAM,OAAQ,EAAE,SAAS,IAAK;AAC9B,WAAO;AAAA,MACL,UAAU;AAAA,MAAM,YAAY,IAAI,OAAO;AAAA,MAAM,QAAQ,WAAW,IAAI;AAAA,IACtE;AAAA,EACF;AACF;","names":["require"]}
@@ -1,71 +0,0 @@
1
- // src/actions/hash/algorithms/phash.ts
2
- import phashLib from "sharp-phash";
3
-
4
- // src/actions/hash/lib/hamming.ts
5
- function popcount8(byte) {
6
- let count = 0;
7
- let value = byte & 255;
8
- while (value !== 0) {
9
- count += value & 1;
10
- value >>>= 1;
11
- }
12
- return count;
13
- }
14
- function hammingHex(a, b) {
15
- if (a.length !== b.length) {
16
- throw new Error(`Hash length mismatch: ${a.length} vs ${b.length}`);
17
- }
18
- if (a.length % 2 !== 0) {
19
- throw new Error(`Hash hex length must be even, got ${a.length}`);
20
- }
21
- let dist = 0;
22
- for (let i = 0; i < a.length; i += 2) {
23
- const xa = Number.parseInt(a.slice(i, i + 2), 16);
24
- const xb = Number.parseInt(b.slice(i, i + 2), 16);
25
- if (Number.isNaN(xa) || Number.isNaN(xb)) {
26
- throw new TypeError(`Invalid hex at position ${i}: '${a.slice(i, i + 2)}' / '${b.slice(i, i + 2)}'`);
27
- }
28
- dist += popcount8(xa ^ xb);
29
- }
30
- return dist;
31
- }
32
-
33
- // src/actions/hash/algorithms/phash.ts
34
- var phash = phashLib;
35
- function binaryToHex(bin) {
36
- if (!/^[01]+$/.test(bin)) {
37
- throw new TypeError(`phash returned unexpected output: ${bin.slice(0, 20)}\u2026`);
38
- }
39
- const padded = bin.padStart(Math.ceil(bin.length / 4) * 4, "0");
40
- let hex = "";
41
- for (let i = 0; i < padded.length; i += 4) {
42
- hex += Number.parseInt(padded.slice(i, i + 4), 2).toString(16);
43
- }
44
- return hex;
45
- }
46
- var phashAlgorithm = {
47
- name: "phash",
48
- family: "perceptual-image",
49
- inputType: "image",
50
- async hash(input) {
51
- const source = input.path ?? input.bytes;
52
- if (source === void 0) {
53
- throw new Error("phash requires bytes or a path.");
54
- }
55
- const bin = await phash(source);
56
- return binaryToHex(bin);
57
- },
58
- async compare(a, b) {
59
- const dist = hammingHex(a, b);
60
- const bits = a.length / 2 * 8;
61
- return {
62
- distance: dist,
63
- similarity: 1 - dist / bits,
64
- metric: `hamming-${bits}`
65
- };
66
- }
67
- };
68
- export {
69
- phashAlgorithm
70
- };
71
- //# sourceMappingURL=phash.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../../src/actions/hash/algorithms/phash.ts","../../../../src/actions/hash/lib/hamming.ts"],"sourcesContent":["import phashLib from 'sharp-phash'\n\nimport { hammingHex } from '../lib/hamming.ts'\nimport type { Algorithm } from './types.ts'\n\nconst phash = phashLib as unknown as (image: Buffer | string) => Promise<string>\n\n/**\n * sharp-phash returns a 64-character '01' binary string. We pack it into 16-char hex\n * for parity with the other perceptual image algorithms.\n */\nfunction binaryToHex(bin: string): string {\n if (!/^[01]+$/.test(bin)) {\n throw new TypeError(`phash returned unexpected output: ${bin.slice(0, 20)}…`)\n }\n const padded = bin.padStart(Math.ceil(bin.length / 4) * 4, '0')\n let hex = ''\n for (let i = 0; i < padded.length; i += 4) {\n hex += Number.parseInt(padded.slice(i, i + 4), 2).toString(16)\n }\n return hex\n}\n\nexport const phashAlgorithm: Algorithm = {\n name: 'phash',\n family: 'perceptual-image',\n inputType: 'image',\n async hash(input) {\n const source = input.path ?? input.bytes\n if (source === undefined) {\n throw new Error('phash requires bytes or a path.')\n }\n const bin = await phash(source)\n return binaryToHex(bin)\n },\n async compare(a, b) {\n const dist = hammingHex(a, b)\n const bits = (a.length / 2) * 8\n return {\n distance: dist, similarity: 1 - dist / bits, metric: `hamming-${bits}`,\n }\n },\n}\n","/**\n * Population count for an 8-bit value (number of set bits).\n */\nfunction popcount8(byte: number): number {\n let count = 0\n let value = byte & 0xff\n while (value !== 0) {\n count += value & 1\n value >>>= 1\n }\n return count\n}\n\n/**\n * Hamming distance between two equal-length lowercase-hex strings.\n * Throws when the lengths differ.\n */\nexport function hammingHex(a: string, b: string): number {\n if (a.length !== b.length) {\n throw new Error(`Hash length mismatch: ${a.length} vs ${b.length}`)\n }\n if (a.length % 2 !== 0) {\n throw new Error(`Hash hex length must be even, got ${a.length}`)\n }\n let dist = 0\n for (let i = 0; i < a.length; i += 2) {\n const xa = Number.parseInt(a.slice(i, i + 2), 16)\n const xb = Number.parseInt(b.slice(i, i + 2), 16)\n if (Number.isNaN(xa) || Number.isNaN(xb)) {\n throw new TypeError(`Invalid hex at position ${i}: '${a.slice(i, i + 2)}' / '${b.slice(i, i + 2)}'`)\n }\n dist += popcount8(xa ^ xb)\n }\n return dist\n}\n\n/**\n * Bit-length of an even-length hex string.\n */\nexport function bitLengthHex(hex: string): number {\n return (hex.length / 2) * 8\n}\n\n/**\n * Population count for a 32-bit unsigned value (number of set bits).\n * Uses the parallel-prefix bit trick.\n */\nexport function popcount32(value: number): number {\n let v = Math.trunc(value)\n v = v - ((v >>> 1) & 0x55_55_55_55)\n v = (v & 0x33_33_33_33) + ((v >>> 2) & 0x33_33_33_33)\n v = (v + (v >>> 4)) & 0x0f_0f_0f_0f\n return ((v * 0x01_01_01_01) >>> 24) & 0xff\n}\n"],"mappings":";AAAA,OAAO,cAAc;;;ACGrB,SAAS,UAAU,MAAsB;AACvC,MAAI,QAAQ;AACZ,MAAI,QAAQ,OAAO;AACnB,SAAO,UAAU,GAAG;AAClB,aAAS,QAAQ;AACjB,eAAW;AAAA,EACb;AACA,SAAO;AACT;AAMO,SAAS,WAAW,GAAW,GAAmB;AACvD,MAAI,EAAE,WAAW,EAAE,QAAQ;AACzB,UAAM,IAAI,MAAM,yBAAyB,EAAE,MAAM,OAAO,EAAE,MAAM,EAAE;AAAA,EACpE;AACA,MAAI,EAAE,SAAS,MAAM,GAAG;AACtB,UAAM,IAAI,MAAM,qCAAqC,EAAE,MAAM,EAAE;AAAA,EACjE;AACA,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK,GAAG;AACpC,UAAM,KAAK,OAAO,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE;AAChD,UAAM,KAAK,OAAO,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE;AAChD,QAAI,OAAO,MAAM,EAAE,KAAK,OAAO,MAAM,EAAE,GAAG;AACxC,YAAM,IAAI,UAAU,2BAA2B,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,GAAG;AAAA,IACrG;AACA,YAAQ,UAAU,KAAK,EAAE;AAAA,EAC3B;AACA,SAAO;AACT;;;AD7BA,IAAM,QAAQ;AAMd,SAAS,YAAY,KAAqB;AACxC,MAAI,CAAC,UAAU,KAAK,GAAG,GAAG;AACxB,UAAM,IAAI,UAAU,qCAAqC,IAAI,MAAM,GAAG,EAAE,CAAC,QAAG;AAAA,EAC9E;AACA,QAAM,SAAS,IAAI,SAAS,KAAK,KAAK,IAAI,SAAS,CAAC,IAAI,GAAG,GAAG;AAC9D,MAAI,MAAM;AACV,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK,GAAG;AACzC,WAAO,OAAO,SAAS,OAAO,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE;AAAA,EAC/D;AACA,SAAO;AACT;AAEO,IAAM,iBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,MAAM,KAAK,OAAO;AAChB,UAAM,SAAS,MAAM,QAAQ,MAAM;AACnC,QAAI,WAAW,QAAW;AACxB,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACnD;AACA,UAAM,MAAM,MAAM,MAAM,MAAM;AAC9B,WAAO,YAAY,GAAG;AAAA,EACxB;AAAA,EACA,MAAM,QAAQ,GAAG,GAAG;AAClB,UAAM,OAAO,WAAW,GAAG,CAAC;AAC5B,UAAM,OAAQ,EAAE,SAAS,IAAK;AAC9B,WAAO;AAAA,MACL,UAAU;AAAA,MAAM,YAAY,IAAI,OAAO;AAAA,MAAM,QAAQ,WAAW,IAAI;AAAA,IACtE;AAAA,EACF;AACF;","names":[]}
@@ -1,24 +0,0 @@
1
- // src/actions/hash/algorithms/sha256.ts
2
- import { createHash } from "crypto";
3
- var sha256Algorithm = {
4
- name: "sha256",
5
- family: "strict",
6
- inputType: "bytes",
7
- async hash(input) {
8
- if (input.bytes === void 0) {
9
- throw new Error("sha256 requires loaded bytes.");
10
- }
11
- return createHash("sha256").update(input.bytes).digest("hex");
12
- },
13
- async compare(a, b) {
14
- return {
15
- similarity: a === b ? 1 : 0,
16
- distance: a === b ? 0 : 1,
17
- metric: "exact-match"
18
- };
19
- }
20
- };
21
- export {
22
- sha256Algorithm
23
- };
24
- //# sourceMappingURL=sha256.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../../src/actions/hash/algorithms/sha256.ts"],"sourcesContent":["import { createHash } from 'node:crypto'\n\nimport type { Algorithm } from './types.ts'\n\nexport const sha256Algorithm: Algorithm = {\n name: 'sha256',\n family: 'strict',\n inputType: 'bytes',\n async hash(input) {\n if (input.bytes === undefined) {\n throw new Error('sha256 requires loaded bytes.')\n }\n return createHash('sha256').update(input.bytes).digest('hex')\n },\n async compare(a, b) {\n return {\n similarity: a === b ? 1 : 0,\n distance: a === b ? 0 : 1,\n metric: 'exact-match',\n }\n },\n}\n"],"mappings":";AAAA,SAAS,kBAAkB;AAIpB,IAAM,kBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,MAAM,KAAK,OAAO;AAChB,QAAI,MAAM,UAAU,QAAW;AAC7B,YAAM,IAAI,MAAM,+BAA+B;AAAA,IACjD;AACA,WAAO,WAAW,QAAQ,EAAE,OAAO,MAAM,KAAK,EAAE,OAAO,KAAK;AAAA,EAC9D;AAAA,EACA,MAAM,QAAQ,GAAG,GAAG;AAClB,WAAO;AAAA,MACL,YAAY,MAAM,IAAI,IAAI;AAAA,MAC1B,UAAU,MAAM,IAAI,IAAI;AAAA,MACxB,QAAQ;AAAA,IACV;AAAA,EACF;AACF;","names":[]}
@@ -1,203 +0,0 @@
1
- // src/actions/hash/lib/levenshtein.ts
2
- function levenshtein(a, b) {
3
- if (a === b) return 0;
4
- if (a.length === 0) return b.length;
5
- if (b.length === 0) return a.length;
6
- let s1 = a;
7
- let s2 = b;
8
- if (s1.length < s2.length) {
9
- const tmp = s1;
10
- s1 = s2;
11
- s2 = tmp;
12
- }
13
- const m = s1.length;
14
- const n = s2.length;
15
- let prev = Array.from({ length: n + 1 }, (_, j) => j);
16
- let curr = Array.from({ length: n + 1 }, () => 0);
17
- for (let i = 1; i <= m; i++) {
18
- curr[0] = i;
19
- const cp1 = s1.codePointAt(i - 1);
20
- for (let j = 1; j <= n; j++) {
21
- const cost = cp1 === s2.codePointAt(j - 1) ? 0 : 1;
22
- const del = prev[j] + 1;
23
- const ins = curr[j - 1] + 1;
24
- const sub = prev[j - 1] + cost;
25
- curr[j] = Math.min(del, ins, sub);
26
- }
27
- const tmp = prev;
28
- prev = curr;
29
- curr = tmp;
30
- }
31
- return prev[n];
32
- }
33
-
34
- // src/actions/hash/lib/runBinary.ts
35
- import { spawn } from "child_process";
36
- async function runBinary(options) {
37
- const maxBytes = options.maxBytes ?? 64 * 1024 * 1024;
38
- return await new Promise((resolve, reject) => {
39
- const child = spawn(options.binary, [...options.args ?? []], { stdio: ["pipe", "pipe", "pipe"] });
40
- const stdoutChunks = [];
41
- let stdoutBytes = 0;
42
- let stderr = "";
43
- let killedForOverflow = false;
44
- child.stdout.on("data", (chunk) => {
45
- stdoutBytes += chunk.length;
46
- if (stdoutBytes > maxBytes) {
47
- if (!killedForOverflow) {
48
- killedForOverflow = true;
49
- child.kill("SIGKILL");
50
- }
51
- return;
52
- }
53
- stdoutChunks.push(chunk);
54
- });
55
- child.stderr.on("data", (chunk) => {
56
- stderr += chunk.toString("utf8");
57
- });
58
- child.on("error", (err) => reject(err));
59
- child.on("close", (code) => {
60
- if (killedForOverflow) {
61
- reject(new Error(`${options.binary} stdout exceeded ${maxBytes} bytes`));
62
- return;
63
- }
64
- const exitCode = code ?? -1;
65
- const stdout = Buffer.concat(stdoutChunks);
66
- if (exitCode !== 0) {
67
- const tail = stderr.trim().split(/\r?\n/).slice(-3).join("\n");
68
- reject(new Error(`${options.binary} exited ${exitCode}${tail.length > 0 ? `: ${tail}` : ""}`));
69
- return;
70
- }
71
- resolve({
72
- stdout,
73
- stderr,
74
- exitCode
75
- });
76
- });
77
- if (options.stdin === void 0) {
78
- child.stdin.end();
79
- } else {
80
- child.stdin.end(options.stdin);
81
- }
82
- });
83
- }
84
-
85
- // src/actions/hash/lib/which.ts
86
- import { spawn as spawn2 } from "child_process";
87
- async function which(binary) {
88
- return await new Promise((resolve) => {
89
- const cmd = process.platform === "win32" ? "where" : "command";
90
- const args = process.platform === "win32" ? [binary] : ["-v", binary];
91
- const child = spawn2(cmd, args, { shell: process.platform !== "win32" });
92
- let stdout = "";
93
- child.stdout.on("data", (chunk) => {
94
- stdout += chunk.toString("utf8");
95
- });
96
- child.on("error", () => resolve(null));
97
- child.on("close", (code) => {
98
- if (code === 0) {
99
- const path = stdout.split(/\r?\n/).find((line) => line.trim().length > 0)?.trim() ?? null;
100
- resolve(path);
101
- } else {
102
- resolve(null);
103
- }
104
- });
105
- });
106
- }
107
- async function requireBinary(req) {
108
- const path = await which(req.binary);
109
- if (path !== null) return path;
110
- const lines = [`${req.binary} binary not found on PATH. Install with:`];
111
- if (req.install.brew !== void 0) lines.push(` macOS: brew install ${req.install.brew}`);
112
- if (req.install.apt !== void 0) lines.push(` Debian: apt install ${req.install.apt}`);
113
- if (req.install.choco !== void 0) lines.push(` Windows: choco install ${req.install.choco}`);
114
- throw new Error(lines.join("\n"));
115
- }
116
-
117
- // src/actions/hash/algorithms/ssdeep.ts
118
- var SSDEEP_BIN = {
119
- binary: "ssdeep",
120
- install: {
121
- brew: "ssdeep",
122
- apt: "ssdeep",
123
- choco: "ssdeep"
124
- }
125
- };
126
- function parseSsdeepHash(raw) {
127
- const cleaned = raw.replace(/,.*$/u, "").trim();
128
- const parts = cleaned.split(":");
129
- if (parts.length < 3) {
130
- throw new Error(`Invalid ssdeep hash: ${raw}`);
131
- }
132
- const blockSize = Number.parseInt(parts[0], 10);
133
- if (!Number.isFinite(blockSize) || blockSize <= 0) {
134
- throw new Error(`Invalid ssdeep block size: ${parts[0]}`);
135
- }
136
- return {
137
- blockSize,
138
- h1: parts[1],
139
- h2: parts[2]
140
- };
141
- }
142
- function levenshteinSimilarity(a, b) {
143
- if (a.length === 0 && b.length === 0) return 1;
144
- const dist = levenshtein(a, b);
145
- const maxLen = Math.max(a.length, b.length, 1);
146
- return Math.max(0, 1 - dist / maxLen);
147
- }
148
- function ssdeepSimilarity(rawA, rawB) {
149
- const a = parseSsdeepHash(rawA);
150
- const b = parseSsdeepHash(rawB);
151
- if (a.blockSize === b.blockSize) {
152
- const s1 = levenshteinSimilarity(a.h1, b.h1);
153
- const s2 = levenshteinSimilarity(a.h2, b.h2);
154
- const similarity = Math.max(s1, s2);
155
- const distance = Math.round((1 - similarity) * Math.max(a.h1.length, b.h1.length, a.h2.length, b.h2.length));
156
- return { similarity, distance };
157
- }
158
- if (a.blockSize === b.blockSize * 2) {
159
- const similarity = levenshteinSimilarity(a.h2, b.h1);
160
- return { similarity, distance: Math.round((1 - similarity) * Math.max(a.h2.length, b.h1.length)) };
161
- }
162
- if (b.blockSize === a.blockSize * 2) {
163
- const similarity = levenshteinSimilarity(a.h1, b.h2);
164
- return { similarity, distance: Math.round((1 - similarity) * Math.max(a.h1.length, b.h2.length)) };
165
- }
166
- return { similarity: 0, distance: Number.NaN };
167
- }
168
- var ssdeepAlgorithm = {
169
- name: "ssdeep",
170
- family: "fuzzy-byte",
171
- inputType: "bytes",
172
- requires: [SSDEEP_BIN],
173
- async hash(input) {
174
- if (input.bytes === void 0) {
175
- throw new Error("ssdeep requires loaded bytes.");
176
- }
177
- await requireBinary(SSDEEP_BIN);
178
- const { stdout } = await runBinary({
179
- binary: "ssdeep",
180
- args: ["-b", "-s"],
181
- stdin: input.bytes
182
- });
183
- const text = stdout.toString("utf8");
184
- const lines = text.split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0);
185
- const hashLine = lines.find((l) => !l.startsWith("ssdeep,")) ?? lines.at(-1);
186
- if (hashLine === void 0) {
187
- throw new Error("ssdeep produced no output.");
188
- }
189
- return hashLine.replace(/,.*$/u, "");
190
- },
191
- async compare(a, b) {
192
- const { similarity, distance } = ssdeepSimilarity(a, b);
193
- return {
194
- similarity,
195
- distance: Number.isFinite(distance) ? distance : void 0,
196
- metric: "ssdeep-levenshtein"
197
- };
198
- }
199
- };
200
- export {
201
- ssdeepAlgorithm
202
- };
203
- //# sourceMappingURL=ssdeep.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../../src/actions/hash/lib/levenshtein.ts","../../../../src/actions/hash/lib/runBinary.ts","../../../../src/actions/hash/lib/which.ts","../../../../src/actions/hash/algorithms/ssdeep.ts"],"sourcesContent":["/**\n * Standard Levenshtein edit distance between two strings.\n * O(m·n) time, O(min(m,n)) space.\n */\nexport function levenshtein(a: string, b: string): number {\n if (a === b) return 0\n if (a.length === 0) return b.length\n if (b.length === 0) return a.length\n\n // Make `s1` the longer string so the row width is min(m,n)+1.\n let s1 = a\n let s2 = b\n if (s1.length < s2.length) {\n const tmp = s1\n s1 = s2\n s2 = tmp\n }\n\n const m = s1.length\n const n = s2.length\n let prev: number[] = Array.from({ length: n + 1 }, (_, j) => j)\n let curr: number[] = Array.from({ length: n + 1 }, () => 0)\n\n for (let i = 1; i <= m; i++) {\n curr[0] = i\n const cp1 = s1.codePointAt(i - 1)\n for (let j = 1; j <= n; j++) {\n const cost = cp1 === s2.codePointAt(j - 1) ? 0 : 1\n const del = prev[j] + 1\n const ins = curr[j - 1] + 1\n const sub = prev[j - 1] + cost\n curr[j] = Math.min(del, ins, sub)\n }\n const tmp = prev\n prev = curr\n curr = tmp\n }\n return prev[n]\n}\n","import { spawn } from 'node:child_process'\n\nexport interface RunBinaryOptions {\n binary: string\n args?: readonly string[]\n /** When provided, written to the child's stdin and stdin is closed. */\n stdin?: Buffer\n /** When true, the child's stdout is captured as a Buffer. Otherwise as utf8. */\n binaryOutput?: boolean\n /** Cap stdout capture at this many bytes. Default 64 MiB. */\n maxBytes?: number\n}\n\nexport interface RunBinaryResult {\n stdout: Buffer\n stderr: string\n exitCode: number\n}\n\n/**\n * Spawn a binary, optionally write to its stdin, and capture stdout/stderr.\n * Throws if the child exits non-zero.\n */\nexport async function runBinary(options: RunBinaryOptions): Promise<RunBinaryResult> {\n const maxBytes = options.maxBytes ?? 64 * 1024 * 1024\n return await new Promise((resolve, reject) => {\n const child = spawn(options.binary, [...(options.args ?? [])], { stdio: ['pipe', 'pipe', 'pipe'] })\n\n const stdoutChunks: Buffer[] = []\n let stdoutBytes = 0\n let stderr = ''\n let killedForOverflow = false\n\n child.stdout.on('data', (chunk: Buffer) => {\n stdoutBytes += chunk.length\n if (stdoutBytes > maxBytes) {\n if (!killedForOverflow) {\n killedForOverflow = true\n child.kill('SIGKILL')\n }\n return\n }\n stdoutChunks.push(chunk)\n })\n child.stderr.on('data', (chunk: Buffer) => {\n stderr += chunk.toString('utf8')\n })\n\n child.on('error', err => reject(err))\n child.on('close', (code) => {\n if (killedForOverflow) {\n reject(new Error(`${options.binary} stdout exceeded ${maxBytes} bytes`))\n return\n }\n const exitCode = code ?? -1\n const stdout = Buffer.concat(stdoutChunks)\n if (exitCode !== 0) {\n const tail = stderr.trim().split(/\\r?\\n/).slice(-3).join('\\n')\n reject(new Error(`${options.binary} exited ${exitCode}${tail.length > 0 ? `: ${tail}` : ''}`))\n return\n }\n resolve({\n stdout, stderr, exitCode,\n })\n })\n\n if (options.stdin === undefined) {\n child.stdin.end()\n } else {\n child.stdin.end(options.stdin)\n }\n })\n}\n","import { spawn } from 'node:child_process'\n\nimport type { RequiredBinary } from '../algorithms/types.ts'\n\n/**\n * Resolve a binary name to its absolute path on the user's PATH.\n * Returns null if not found.\n */\nexport async function which(binary: string): Promise<string | null> {\n return await new Promise((resolve) => {\n const cmd = process.platform === 'win32' ? 'where' : 'command'\n const args = process.platform === 'win32' ? [binary] : ['-v', binary]\n const child = spawn(cmd, args, { shell: process.platform !== 'win32' })\n\n let stdout = ''\n child.stdout.on('data', (chunk: Buffer) => {\n stdout += chunk.toString('utf8')\n })\n child.on('error', () => resolve(null))\n child.on('close', (code) => {\n if (code === 0) {\n const path = stdout.split(/\\r?\\n/).find(line => line.trim().length > 0)?.trim() ?? null\n resolve(path)\n } else {\n resolve(null)\n }\n })\n })\n}\n\n/**\n * Throw a clearly-actionable error when a required binary is missing.\n */\nexport async function requireBinary(req: RequiredBinary): Promise<string> {\n const path = await which(req.binary)\n if (path !== null) return path\n const lines = [`${req.binary} binary not found on PATH. Install with:`]\n if (req.install.brew !== undefined) lines.push(` macOS: brew install ${req.install.brew}`)\n if (req.install.apt !== undefined) lines.push(` Debian: apt install ${req.install.apt}`)\n if (req.install.choco !== undefined) lines.push(` Windows: choco install ${req.install.choco}`)\n throw new Error(lines.join('\\n'))\n}\n","import { levenshtein } from '../lib/levenshtein.ts'\nimport { runBinary } from '../lib/runBinary.ts'\nimport { requireBinary } from '../lib/which.ts'\nimport type { Algorithm, RequiredBinary } from './types.ts'\n\nconst SSDEEP_BIN: RequiredBinary = {\n binary: 'ssdeep',\n install: {\n brew: 'ssdeep',\n apt: 'ssdeep',\n choco: 'ssdeep',\n },\n}\n\n/**\n * Parse an ssdeep hash of the form `<block_size>:<h1>:<h2>` (filename suffix is dropped).\n */\nfunction parseSsdeepHash(raw: string): { blockSize: number; h1: string; h2: string } {\n const cleaned = raw.replace(/,.*$/u, '').trim()\n const parts = cleaned.split(':')\n if (parts.length < 3) {\n throw new Error(`Invalid ssdeep hash: ${raw}`)\n }\n const blockSize = Number.parseInt(parts[0], 10)\n if (!Number.isFinite(blockSize) || blockSize <= 0) {\n throw new Error(`Invalid ssdeep block size: ${parts[0]}`)\n }\n return {\n blockSize, h1: parts[1], h2: parts[2],\n }\n}\n\nfunction levenshteinSimilarity(a: string, b: string): number {\n if (a.length === 0 && b.length === 0) return 1\n const dist = levenshtein(a, b)\n const maxLen = Math.max(a.length, b.length, 1)\n return Math.max(0, 1 - dist / maxLen)\n}\n\n/**\n * Approximate ssdeep similarity using Levenshtein on whichever sub-hash pair shares a\n * compatible block size (1×, 2×, or 0.5×). Returns 0 if block sizes are incompatible.\n *\n * This is NOT the canonical ssdeep score — that algorithm applies a block-size\n * attenuation curve we don't replicate here. The metric label `ssdeep-levenshtein`\n * makes that explicit.\n */\nfunction ssdeepSimilarity(rawA: string, rawB: string): { similarity: number; distance: number } {\n const a = parseSsdeepHash(rawA)\n const b = parseSsdeepHash(rawB)\n if (a.blockSize === b.blockSize) {\n const s1 = levenshteinSimilarity(a.h1, b.h1)\n const s2 = levenshteinSimilarity(a.h2, b.h2)\n const similarity = Math.max(s1, s2)\n const distance = Math.round((1 - similarity) * Math.max(a.h1.length, b.h1.length, a.h2.length, b.h2.length))\n return { similarity, distance }\n }\n if (a.blockSize === b.blockSize * 2) {\n const similarity = levenshteinSimilarity(a.h2, b.h1)\n return { similarity, distance: Math.round((1 - similarity) * Math.max(a.h2.length, b.h1.length)) }\n }\n if (b.blockSize === a.blockSize * 2) {\n const similarity = levenshteinSimilarity(a.h1, b.h2)\n return { similarity, distance: Math.round((1 - similarity) * Math.max(a.h1.length, b.h2.length)) }\n }\n return { similarity: 0, distance: Number.NaN }\n}\n\nexport const ssdeepAlgorithm: Algorithm = {\n name: 'ssdeep',\n family: 'fuzzy-byte',\n inputType: 'bytes',\n requires: [SSDEEP_BIN],\n async hash(input) {\n if (input.bytes === undefined) {\n throw new Error('ssdeep requires loaded bytes.')\n }\n await requireBinary(SSDEEP_BIN)\n // -b: bare output (no header line, no filename column)\n // -s: silent — suppress warnings/banner\n // We still get a header, so parse defensively.\n const { stdout } = await runBinary({\n binary: 'ssdeep', args: ['-b', '-s'], stdin: input.bytes,\n })\n const text = stdout.toString('utf8')\n const lines = text.split(/\\r?\\n/).map(l => l.trim()).filter(l => l.length > 0)\n // Skip the \"ssdeep,1.1--blocksize:hash:hash,filename\" header if present.\n const hashLine = lines.find(l => !l.startsWith('ssdeep,')) ?? lines.at(-1)\n if (hashLine === undefined) {\n throw new Error('ssdeep produced no output.')\n }\n return hashLine.replace(/,.*$/u, '')\n },\n async compare(a, b) {\n const { similarity, distance } = ssdeepSimilarity(a, b)\n return {\n similarity, distance: Number.isFinite(distance) ? distance : undefined, metric: 'ssdeep-levenshtein',\n }\n },\n}\n"],"mappings":"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","names":["spawn"]}