@wenathlan/saddle 1.8.17 → 2.0.2

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 (1005) hide show
  1. package/Dockerfile +1339 -0
  2. package/README.md +68 -22
  3. package/alternatives.ts +1218 -0
  4. package/biome.json +153 -0
  5. package/boards.json +1517 -0
  6. package/compute.ts +3144 -0
  7. package/cores.json +1801 -0
  8. package/dist/acquisition.d.ts +359 -0
  9. package/dist/acquisition.d.ts.map +1 -0
  10. package/dist/acquisition.js +629 -0
  11. package/dist/acquisition.js.map +1 -0
  12. package/dist/alternatives.d.ts +509 -0
  13. package/dist/alternatives.d.ts.map +1 -0
  14. package/dist/alternatives.js +951 -0
  15. package/dist/alternatives.js.map +1 -0
  16. package/dist/automation.d.ts +426 -0
  17. package/dist/automation.d.ts.map +1 -0
  18. package/dist/automation.js +561 -0
  19. package/dist/automation.js.map +1 -0
  20. package/dist/browser.d.ts +562 -0
  21. package/dist/browser.d.ts.map +1 -0
  22. package/dist/browser.js +1057 -0
  23. package/dist/browser.js.map +1 -0
  24. package/dist/capacitor.config.d.ts +13 -0
  25. package/dist/capacitor.config.d.ts.map +1 -0
  26. package/dist/capacitor.config.js +26 -0
  27. package/dist/capacitor.config.js.map +1 -0
  28. package/dist/cli.d.ts +17 -0
  29. package/dist/cli.d.ts.map +1 -0
  30. package/dist/cli.js +111 -0
  31. package/dist/cli.js.map +1 -0
  32. package/dist/communication.d.ts +192 -0
  33. package/dist/communication.d.ts.map +1 -0
  34. package/dist/communication.js +418 -0
  35. package/dist/communication.js.map +1 -0
  36. package/dist/compute.d.ts +1161 -0
  37. package/dist/compute.d.ts.map +1 -0
  38. package/dist/compute.js +2273 -0
  39. package/dist/compute.js.map +1 -0
  40. package/dist/distribution.d.ts +529 -0
  41. package/dist/distribution.d.ts.map +1 -0
  42. package/dist/distribution.js +811 -0
  43. package/dist/distribution.js.map +1 -0
  44. package/dist/execution.d.ts +530 -0
  45. package/dist/execution.d.ts.map +1 -0
  46. package/dist/execution.js +761 -0
  47. package/dist/execution.js.map +1 -0
  48. package/dist/format.d.ts +19 -0
  49. package/dist/format.d.ts.map +1 -0
  50. package/dist/format.js +60 -0
  51. package/dist/format.js.map +1 -0
  52. package/dist/foundation.d.ts +176 -0
  53. package/dist/foundation.d.ts.map +1 -0
  54. package/dist/foundation.js +309 -0
  55. package/dist/foundation.js.map +1 -0
  56. package/dist/index.d.ts +733 -122
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +1018 -122
  59. package/dist/index.js.map +1 -1
  60. package/dist/integration.d.ts +236 -0
  61. package/dist/integration.d.ts.map +1 -0
  62. package/dist/integration.js +236 -0
  63. package/dist/integration.js.map +1 -0
  64. package/dist/intelligence.d.ts +94 -0
  65. package/dist/intelligence.d.ts.map +1 -0
  66. package/dist/intelligence.js +145 -0
  67. package/dist/intelligence.js.map +1 -0
  68. package/dist/isolation.d.ts +129 -0
  69. package/dist/isolation.d.ts.map +1 -0
  70. package/dist/isolation.js +96 -0
  71. package/dist/isolation.js.map +1 -0
  72. package/dist/media.d.ts +344 -0
  73. package/dist/media.d.ts.map +1 -0
  74. package/dist/media.js +986 -0
  75. package/dist/media.js.map +1 -0
  76. package/dist/modes.d.ts +359 -0
  77. package/dist/modes.d.ts.map +1 -0
  78. package/dist/modes.js +134 -0
  79. package/dist/modes.js.map +1 -0
  80. package/dist/{library/public.d.ts → operations.d.ts} +15 -1
  81. package/dist/operations.d.ts.map +1 -0
  82. package/dist/{library/public.js → operations.js} +18 -7
  83. package/dist/operations.js.map +1 -0
  84. package/dist/orchestrator.d.ts +1339 -0
  85. package/dist/orchestrator.d.ts.map +1 -0
  86. package/dist/orchestrator.js +4308 -0
  87. package/dist/orchestrator.js.map +1 -0
  88. package/dist/performance.d.ts +416 -0
  89. package/dist/performance.d.ts.map +1 -0
  90. package/dist/performance.js +827 -0
  91. package/dist/performance.js.map +1 -0
  92. package/dist/quantum.d.ts +810 -0
  93. package/dist/quantum.d.ts.map +1 -0
  94. package/dist/quantum.js +2073 -0
  95. package/dist/quantum.js.map +1 -0
  96. package/dist/render.d.ts +381 -0
  97. package/dist/render.d.ts.map +1 -0
  98. package/dist/render.js +1073 -0
  99. package/dist/render.js.map +1 -0
  100. package/dist/scheduler.d.ts +596 -0
  101. package/dist/scheduler.d.ts.map +1 -0
  102. package/dist/scheduler.js +1259 -0
  103. package/dist/scheduler.js.map +1 -0
  104. package/dist/security.d.ts +501 -0
  105. package/dist/security.d.ts.map +1 -0
  106. package/dist/security.js +1170 -0
  107. package/dist/security.js.map +1 -0
  108. package/dist/server.d.ts +21 -0
  109. package/dist/server.d.ts.map +1 -0
  110. package/dist/{server/node.js → server.js} +16 -2
  111. package/dist/server.js.map +1 -0
  112. package/dist/tiers.d.ts +1002 -0
  113. package/dist/tiers.d.ts.map +1 -0
  114. package/dist/tiers.js +2165 -0
  115. package/dist/tiers.js.map +1 -0
  116. package/dist/virtual.d.ts +641 -0
  117. package/dist/virtual.d.ts.map +1 -0
  118. package/dist/virtual.js +1285 -0
  119. package/dist/virtual.js.map +1 -0
  120. package/dist/virtualcpu.d.ts +316 -0
  121. package/dist/virtualcpu.d.ts.map +1 -0
  122. package/dist/virtualcpu.js +1180 -0
  123. package/dist/virtualcpu.js.map +1 -0
  124. package/dist/virtualgpu.d.ts +345 -0
  125. package/dist/virtualgpu.d.ts.map +1 -0
  126. package/dist/virtualgpu.js +1000 -0
  127. package/dist/virtualgpu.js.map +1 -0
  128. package/dist/virtualization.d.ts +607 -0
  129. package/dist/virtualization.d.ts.map +1 -0
  130. package/dist/virtualization.js +1187 -0
  131. package/dist/virtualization.js.map +1 -0
  132. package/dist/virtualmemory.d.ts +818 -0
  133. package/dist/virtualmemory.d.ts.map +1 -0
  134. package/dist/virtualmemory.js +1796 -0
  135. package/dist/virtualmemory.js.map +1 -0
  136. package/dist/webscrape.d.ts +720 -0
  137. package/dist/webscrape.d.ts.map +1 -0
  138. package/dist/webscrape.js +2697 -0
  139. package/dist/webscrape.js.map +1 -0
  140. package/docker.config +769 -0
  141. package/docs/CONVERSA.txt +1523 -0
  142. package/docs/alternatives.md +499 -0
  143. package/docs/architecture-1.8.19.md +76 -0
  144. package/docs/architecture-1.8.19.mmd +33 -0
  145. package/docs/architecture-1.8.19.png +0 -0
  146. package/docs/architecture.md +355 -0
  147. package/docs/artifactavailability.md +6 -0
  148. package/docs/brancharchive-2026-08-18.md +18 -0
  149. package/docs/browser.md +7 -0
  150. package/docs/consolidation.md +70 -0
  151. package/docs/e2ugh-engine.md +528 -0
  152. package/{dist/examples/localjob.js → docs/example-localjob.ts} +3 -3
  153. package/{dist/examples/publicapi.js → docs/example-publicapi.ts} +2 -2
  154. package/docs/hardware.md +342 -0
  155. package/docs/optimization.md +126 -0
  156. package/docs/performance.md +499 -0
  157. package/docs/planning.1.8.18.md +94 -0
  158. package/docs/planning.1.8.19.md +49 -0
  159. package/docs/releasenotes-1.8.17.md +6 -0
  160. package/docs/releasenotes-1.8.18.md +32 -0
  161. package/docs/releasenotes-1.8.19.md +35 -0
  162. package/docs/research-1.8.18-isolation.md +43 -0
  163. package/docs/research-1.8.19-virtual-browser.md +27 -0
  164. package/docs/saddle.archive.1.8.17.tar.gz.gpg +0 -0
  165. package/docs/security.md +454 -0
  166. package/docs/todo-1.8.16.md +56 -1
  167. package/docs/todo-1.8.18.md +164 -0
  168. package/docs/todo-1.8.19.md +241 -0
  169. package/docs/viability.md +777 -0
  170. package/docs/virtualization.md +335 -0
  171. package/docs/web-duplicatecleanup.md +9 -0
  172. package/docs/web-ideas.md +106 -0
  173. package/docs/workflowimprovements-2026-08-19.md +70 -0
  174. package/gpumonitor.cpp +1543 -0
  175. package/gpus.json +2408 -0
  176. package/index.ts +1478 -0
  177. package/media.ts +1337 -0
  178. package/mttg.config +1549 -0
  179. package/orchestrator.ts +5462 -0
  180. package/package.json +304 -55
  181. package/passage.config +1331 -0
  182. package/performance.ts +1049 -0
  183. package/processors.json +2217 -0
  184. package/qemu.config +1062 -0
  185. package/qemubridge.py +1340 -0
  186. package/quantum.ts +2393 -0
  187. package/render.ts +1325 -0
  188. package/scheduler.ts +1600 -0
  189. package/security.ts +1449 -0
  190. package/tiers.ts +2871 -0
  191. package/tsconfig.json +29 -0
  192. package/virtualcpu.ts +1273 -0
  193. package/virtualgpu.ts +1181 -0
  194. package/virtualhardware.c +1011 -0
  195. package/virtualhardware.json +739 -0
  196. package/virtualization.ts +1628 -0
  197. package/virtualizationcore.cpp +4635 -0
  198. package/virtualmemory.ts +2303 -0
  199. package/vm.config.json +1910 -0
  200. package/{extension → web/extension}/manifest.json +1 -1
  201. package/web/readme.md +382 -0
  202. package/web/tsconfig.json +25 -0
  203. package/dist/adapters/forge.d.ts +0 -17
  204. package/dist/adapters/forge.d.ts.map +0 -1
  205. package/dist/adapters/forge.js +0 -19
  206. package/dist/adapters/forge.js.map +0 -1
  207. package/dist/adapters/forgejo.d.ts +0 -49
  208. package/dist/adapters/forgejo.d.ts.map +0 -1
  209. package/dist/adapters/forgejo.js +0 -8
  210. package/dist/adapters/forgejo.js.map +0 -1
  211. package/dist/adapters/github.d.ts +0 -12
  212. package/dist/adapters/github.d.ts.map +0 -1
  213. package/dist/adapters/github.js +0 -20
  214. package/dist/adapters/github.js.map +0 -1
  215. package/dist/adapters/gitlab.d.ts +0 -17
  216. package/dist/adapters/gitlab.d.ts.map +0 -1
  217. package/dist/adapters/gitlab.js +0 -10
  218. package/dist/adapters/gitlab.js.map +0 -1
  219. package/dist/adapters/huggingface.d.ts +0 -17
  220. package/dist/adapters/huggingface.d.ts.map +0 -1
  221. package/dist/adapters/huggingface.js +0 -6
  222. package/dist/adapters/huggingface.js.map +0 -1
  223. package/dist/adapters/socket.d.ts +0 -11
  224. package/dist/adapters/socket.d.ts.map +0 -1
  225. package/dist/adapters/socket.js +0 -17
  226. package/dist/adapters/socket.js.map +0 -1
  227. package/dist/adapters/transport.d.ts +0 -7
  228. package/dist/adapters/transport.d.ts.map +0 -1
  229. package/dist/adapters/transport.js +0 -36
  230. package/dist/adapters/transport.js.map +0 -1
  231. package/dist/ai/chunk.d.ts +0 -2
  232. package/dist/ai/chunk.d.ts.map +0 -1
  233. package/dist/ai/chunk.js +0 -36
  234. package/dist/ai/chunk.js.map +0 -1
  235. package/dist/ai/llmstxt.d.ts +0 -6
  236. package/dist/ai/llmstxt.d.ts.map +0 -1
  237. package/dist/ai/llmstxt.js +0 -12
  238. package/dist/ai/llmstxt.js.map +0 -1
  239. package/dist/ai/provenance.d.ts +0 -22
  240. package/dist/ai/provenance.d.ts.map +0 -1
  241. package/dist/ai/provenance.js +0 -25
  242. package/dist/ai/provenance.js.map +0 -1
  243. package/dist/ai/rag.d.ts +0 -26
  244. package/dist/ai/rag.d.ts.map +0 -1
  245. package/dist/ai/rag.js +0 -22
  246. package/dist/ai/rag.js.map +0 -1
  247. package/dist/ai/tokens.d.ts +0 -15
  248. package/dist/ai/tokens.d.ts.map +0 -1
  249. package/dist/ai/tokens.js +0 -9
  250. package/dist/ai/tokens.js.map +0 -1
  251. package/dist/api/auth.d.ts +0 -16
  252. package/dist/api/auth.d.ts.map +0 -1
  253. package/dist/api/auth.js +0 -19
  254. package/dist/api/auth.js.map +0 -1
  255. package/dist/api/contracts.d.ts +0 -28
  256. package/dist/api/contracts.d.ts.map +0 -1
  257. package/dist/api/contracts.js +0 -14
  258. package/dist/api/contracts.js.map +0 -1
  259. package/dist/api/control.d.ts +0 -10
  260. package/dist/api/control.d.ts.map +0 -1
  261. package/dist/api/control.js +0 -35
  262. package/dist/api/control.js.map +0 -1
  263. package/dist/api/http.d.ts +0 -7
  264. package/dist/api/http.d.ts.map +0 -1
  265. package/dist/api/http.js +0 -12
  266. package/dist/api/http.js.map +0 -1
  267. package/dist/api/rate.d.ts +0 -28
  268. package/dist/api/rate.d.ts.map +0 -1
  269. package/dist/api/rate.js +0 -36
  270. package/dist/api/rate.js.map +0 -1
  271. package/dist/api/security.d.ts +0 -12
  272. package/dist/api/security.d.ts.map +0 -1
  273. package/dist/api/security.js +0 -56
  274. package/dist/api/security.js.map +0 -1
  275. package/dist/api/service.d.ts +0 -5
  276. package/dist/api/service.d.ts.map +0 -1
  277. package/dist/api/service.js +0 -70
  278. package/dist/api/service.js.map +0 -1
  279. package/dist/apps/registry.d.ts +0 -33
  280. package/dist/apps/registry.d.ts.map +0 -1
  281. package/dist/apps/registry.js +0 -24
  282. package/dist/apps/registry.js.map +0 -1
  283. package/dist/binary/archive.d.ts +0 -27
  284. package/dist/binary/archive.d.ts.map +0 -1
  285. package/dist/binary/archive.js +0 -46
  286. package/dist/binary/archive.js.map +0 -1
  287. package/dist/binary/build.d.ts +0 -29
  288. package/dist/binary/build.d.ts.map +0 -1
  289. package/dist/binary/build.js +0 -17
  290. package/dist/binary/build.js.map +0 -1
  291. package/dist/binary/transform.d.ts +0 -70
  292. package/dist/binary/transform.d.ts.map +0 -1
  293. package/dist/binary/transform.js +0 -105
  294. package/dist/binary/transform.js.map +0 -1
  295. package/dist/bot/adapter.d.ts +0 -5
  296. package/dist/bot/adapter.d.ts.map +0 -1
  297. package/dist/bot/adapter.js +0 -11
  298. package/dist/bot/adapter.js.map +0 -1
  299. package/dist/bot/bot.d.ts +0 -28
  300. package/dist/bot/bot.d.ts.map +0 -1
  301. package/dist/bot/bot.js +0 -52
  302. package/dist/bot/bot.js.map +0 -1
  303. package/dist/bot/commands.d.ts +0 -8
  304. package/dist/bot/commands.d.ts.map +0 -1
  305. package/dist/bot/commands.js +0 -19
  306. package/dist/bot/commands.js.map +0 -1
  307. package/dist/bot/permissions.d.ts +0 -13
  308. package/dist/bot/permissions.d.ts.map +0 -1
  309. package/dist/bot/permissions.js +0 -16
  310. package/dist/bot/permissions.js.map +0 -1
  311. package/dist/browser/actions.d.ts +0 -33
  312. package/dist/browser/actions.d.ts.map +0 -1
  313. package/dist/browser/actions.js +0 -44
  314. package/dist/browser/actions.js.map +0 -1
  315. package/dist/browser/agent.d.ts +0 -21
  316. package/dist/browser/agent.d.ts.map +0 -1
  317. package/dist/browser/agent.js +0 -13
  318. package/dist/browser/agent.js.map +0 -1
  319. package/dist/browser/context.d.ts +0 -43
  320. package/dist/browser/context.d.ts.map +0 -1
  321. package/dist/browser/context.js +0 -54
  322. package/dist/browser/context.js.map +0 -1
  323. package/dist/browser/fingerprint.d.ts +0 -4
  324. package/dist/browser/fingerprint.d.ts.map +0 -1
  325. package/dist/browser/fingerprint.js +0 -12
  326. package/dist/browser/fingerprint.js.map +0 -1
  327. package/dist/browser/index.d.ts +0 -11
  328. package/dist/browser/index.d.ts.map +0 -1
  329. package/dist/browser/index.js +0 -11
  330. package/dist/browser/index.js.map +0 -1
  331. package/dist/browser/playwright.d.ts +0 -11
  332. package/dist/browser/playwright.d.ts.map +0 -1
  333. package/dist/browser/playwright.js +0 -24
  334. package/dist/browser/playwright.js.map +0 -1
  335. package/dist/browser/recorder.d.ts +0 -21
  336. package/dist/browser/recorder.d.ts.map +0 -1
  337. package/dist/browser/recorder.js +0 -58
  338. package/dist/browser/recorder.js.map +0 -1
  339. package/dist/browser/session.d.ts +0 -14
  340. package/dist/browser/session.d.ts.map +0 -1
  341. package/dist/browser/session.js +0 -21
  342. package/dist/browser/session.js.map +0 -1
  343. package/dist/browser/snapshot.d.ts +0 -69
  344. package/dist/browser/snapshot.d.ts.map +0 -1
  345. package/dist/browser/snapshot.js +0 -133
  346. package/dist/browser/snapshot.js.map +0 -1
  347. package/dist/captcha/contract.d.ts +0 -35
  348. package/dist/captcha/contract.d.ts.map +0 -1
  349. package/dist/captcha/contract.js +0 -17
  350. package/dist/captcha/contract.js.map +0 -1
  351. package/dist/captcha/evidence.d.ts +0 -10
  352. package/dist/captcha/evidence.d.ts.map +0 -1
  353. package/dist/captcha/evidence.js +0 -9
  354. package/dist/captcha/evidence.js.map +0 -1
  355. package/dist/captcha/guard.d.ts +0 -23
  356. package/dist/captcha/guard.d.ts.map +0 -1
  357. package/dist/captcha/guard.js +0 -12
  358. package/dist/captcha/guard.js.map +0 -1
  359. package/dist/cli/main.d.ts +0 -4
  360. package/dist/cli/main.d.ts.map +0 -1
  361. package/dist/cli/main.js +0 -46
  362. package/dist/cli/main.js.map +0 -1
  363. package/dist/core/errors.d.ts +0 -84
  364. package/dist/core/errors.d.ts.map +0 -1
  365. package/dist/core/errors.js +0 -54
  366. package/dist/core/errors.js.map +0 -1
  367. package/dist/core/events.d.ts +0 -9
  368. package/dist/core/events.d.ts.map +0 -1
  369. package/dist/core/events.js +0 -21
  370. package/dist/core/events.js.map +0 -1
  371. package/dist/core/hash.d.ts +0 -10
  372. package/dist/core/hash.d.ts.map +0 -1
  373. package/dist/core/hash.js +0 -82
  374. package/dist/core/hash.js.map +0 -1
  375. package/dist/core/ids.d.ts +0 -10
  376. package/dist/core/ids.d.ts.map +0 -1
  377. package/dist/core/ids.js +0 -15
  378. package/dist/core/ids.js.map +0 -1
  379. package/dist/delivery/manifest.d.ts +0 -35
  380. package/dist/delivery/manifest.d.ts.map +0 -1
  381. package/dist/delivery/manifest.js +0 -68
  382. package/dist/delivery/manifest.js.map +0 -1
  383. package/dist/deploy/index.d.ts +0 -6
  384. package/dist/deploy/index.d.ts.map +0 -1
  385. package/dist/deploy/index.js +0 -6
  386. package/dist/deploy/index.js.map +0 -1
  387. package/dist/dispatch/resumable.d.ts +0 -102
  388. package/dist/dispatch/resumable.d.ts.map +0 -1
  389. package/dist/dispatch/resumable.js +0 -64
  390. package/dist/dispatch/resumable.js.map +0 -1
  391. package/dist/dispatch/workflow.d.ts +0 -6
  392. package/dist/dispatch/workflow.d.ts.map +0 -1
  393. package/dist/dispatch/workflow.js +0 -37
  394. package/dist/dispatch/workflow.js.map +0 -1
  395. package/dist/domain/artifacts.d.ts +0 -12
  396. package/dist/domain/artifacts.d.ts.map +0 -1
  397. package/dist/domain/artifacts.js +0 -14
  398. package/dist/domain/artifacts.js.map +0 -1
  399. package/dist/domain/jobs.d.ts +0 -12
  400. package/dist/domain/jobs.d.ts.map +0 -1
  401. package/dist/domain/jobs.js +0 -20
  402. package/dist/domain/jobs.js.map +0 -1
  403. package/dist/domain/providers.d.ts +0 -10
  404. package/dist/domain/providers.d.ts.map +0 -1
  405. package/dist/domain/providers.js +0 -8
  406. package/dist/domain/providers.js.map +0 -1
  407. package/dist/domain/runtime.d.ts +0 -14
  408. package/dist/domain/runtime.d.ts.map +0 -1
  409. package/dist/domain/runtime.js +0 -10
  410. package/dist/domain/runtime.js.map +0 -1
  411. package/dist/domain/sessions.d.ts +0 -12
  412. package/dist/domain/sessions.d.ts.map +0 -1
  413. package/dist/domain/sessions.js +0 -57
  414. package/dist/domain/sessions.js.map +0 -1
  415. package/dist/examples/localjob.d.ts +0 -2
  416. package/dist/examples/localjob.d.ts.map +0 -1
  417. package/dist/examples/localjob.js.map +0 -1
  418. package/dist/examples/publicapi.d.ts +0 -2
  419. package/dist/examples/publicapi.d.ts.map +0 -1
  420. package/dist/examples/publicapi.js.map +0 -1
  421. package/dist/extension/build.d.ts +0 -9
  422. package/dist/extension/build.d.ts.map +0 -1
  423. package/dist/extension/build.js +0 -85
  424. package/dist/extension/build.js.map +0 -1
  425. package/dist/extension/content.d.ts +0 -6
  426. package/dist/extension/content.d.ts.map +0 -1
  427. package/dist/extension/content.js +0 -135
  428. package/dist/extension/content.js.map +0 -1
  429. package/dist/extension/index.d.ts +0 -7
  430. package/dist/extension/index.d.ts.map +0 -1
  431. package/dist/extension/index.js +0 -7
  432. package/dist/extension/index.js.map +0 -1
  433. package/dist/extension/pagebridge.d.ts +0 -6
  434. package/dist/extension/pagebridge.d.ts.map +0 -1
  435. package/dist/extension/pagebridge.js +0 -42
  436. package/dist/extension/pagebridge.js.map +0 -1
  437. package/dist/extension/permissions.d.ts +0 -26
  438. package/dist/extension/permissions.d.ts.map +0 -1
  439. package/dist/extension/permissions.js +0 -28
  440. package/dist/extension/permissions.js.map +0 -1
  441. package/dist/extension/popup.d.ts +0 -5
  442. package/dist/extension/popup.d.ts.map +0 -1
  443. package/dist/extension/popup.js +0 -26
  444. package/dist/extension/popup.js.map +0 -1
  445. package/dist/extension/protocol.d.ts +0 -58
  446. package/dist/extension/protocol.d.ts.map +0 -1
  447. package/dist/extension/protocol.js +0 -101
  448. package/dist/extension/protocol.js.map +0 -1
  449. package/dist/extension/serviceworker.d.ts +0 -25
  450. package/dist/extension/serviceworker.d.ts.map +0 -1
  451. package/dist/extension/serviceworker.js +0 -102
  452. package/dist/extension/serviceworker.js.map +0 -1
  453. package/dist/extension/worker.d.ts +0 -28
  454. package/dist/extension/worker.d.ts.map +0 -1
  455. package/dist/extension/worker.js +0 -22
  456. package/dist/extension/worker.js.map +0 -1
  457. package/dist/format/check.d.ts +0 -8
  458. package/dist/format/check.d.ts.map +0 -1
  459. package/dist/format/check.js +0 -38
  460. package/dist/format/check.js.map +0 -1
  461. package/dist/library/public.d.ts.map +0 -1
  462. package/dist/library/public.js.map +0 -1
  463. package/dist/mcp/browser.d.ts +0 -9
  464. package/dist/mcp/browser.d.ts.map +0 -1
  465. package/dist/mcp/browser.js +0 -13
  466. package/dist/mcp/browser.js.map +0 -1
  467. package/dist/mcp/server.d.ts +0 -35
  468. package/dist/mcp/server.d.ts.map +0 -1
  469. package/dist/mcp/server.js +0 -40
  470. package/dist/mcp/server.js.map +0 -1
  471. package/dist/mcp/transport.d.ts +0 -7
  472. package/dist/mcp/transport.d.ts.map +0 -1
  473. package/dist/mcp/transport.js +0 -17
  474. package/dist/mcp/transport.js.map +0 -1
  475. package/dist/memory/bridge.d.ts +0 -14
  476. package/dist/memory/bridge.d.ts.map +0 -1
  477. package/dist/memory/bridge.js +0 -16
  478. package/dist/memory/bridge.js.map +0 -1
  479. package/dist/memory/engine.d.ts +0 -38
  480. package/dist/memory/engine.d.ts.map +0 -1
  481. package/dist/memory/engine.js +0 -109
  482. package/dist/memory/engine.js.map +0 -1
  483. package/dist/memory/modes.d.ts +0 -43
  484. package/dist/memory/modes.d.ts.map +0 -1
  485. package/dist/memory/modes.js +0 -66
  486. package/dist/memory/modes.js.map +0 -1
  487. package/dist/memory/objects.d.ts +0 -21
  488. package/dist/memory/objects.d.ts.map +0 -1
  489. package/dist/memory/objects.js +0 -20
  490. package/dist/memory/objects.js.map +0 -1
  491. package/dist/memory/planner.d.ts +0 -66
  492. package/dist/memory/planner.d.ts.map +0 -1
  493. package/dist/memory/planner.js +0 -108
  494. package/dist/memory/planner.js.map +0 -1
  495. package/dist/memory/targets.d.ts +0 -78
  496. package/dist/memory/targets.d.ts.map +0 -1
  497. package/dist/memory/targets.js +0 -29
  498. package/dist/memory/targets.js.map +0 -1
  499. package/dist/memory/transforms.d.ts +0 -19
  500. package/dist/memory/transforms.d.ts.map +0 -1
  501. package/dist/memory/transforms.js +0 -14
  502. package/dist/memory/transforms.js.map +0 -1
  503. package/dist/modes/matrix.d.ts +0 -23
  504. package/dist/modes/matrix.d.ts.map +0 -1
  505. package/dist/modes/matrix.js +0 -18
  506. package/dist/modes/matrix.js.map +0 -1
  507. package/dist/modes/modes.d.ts +0 -33
  508. package/dist/modes/modes.d.ts.map +0 -1
  509. package/dist/modes/modes.js +0 -15
  510. package/dist/modes/modes.js.map +0 -1
  511. package/dist/modes/resolve.d.ts +0 -96
  512. package/dist/modes/resolve.d.ts.map +0 -1
  513. package/dist/modes/resolve.js +0 -48
  514. package/dist/modes/resolve.js.map +0 -1
  515. package/dist/observability/metrics.d.ts +0 -14
  516. package/dist/observability/metrics.d.ts.map +0 -1
  517. package/dist/observability/metrics.js +0 -18
  518. package/dist/observability/metrics.js.map +0 -1
  519. package/dist/packager/manifest.d.ts +0 -66
  520. package/dist/packager/manifest.d.ts.map +0 -1
  521. package/dist/packager/manifest.js +0 -94
  522. package/dist/packager/manifest.js.map +0 -1
  523. package/dist/packager/publish.d.ts +0 -51
  524. package/dist/packager/publish.d.ts.map +0 -1
  525. package/dist/packager/publish.js +0 -18
  526. package/dist/packager/publish.js.map +0 -1
  527. package/dist/packager/targetcli.d.ts +0 -7
  528. package/dist/packager/targetcli.d.ts.map +0 -1
  529. package/dist/packager/targetcli.js +0 -22
  530. package/dist/packager/targetcli.js.map +0 -1
  531. package/dist/persistence/adapter.d.ts +0 -5
  532. package/dist/persistence/adapter.d.ts.map +0 -1
  533. package/dist/persistence/adapter.js +0 -11
  534. package/dist/persistence/adapter.js.map +0 -1
  535. package/dist/persistence/drizzle.d.ts +0 -2
  536. package/dist/persistence/drizzle.d.ts.map +0 -1
  537. package/dist/persistence/drizzle.js +0 -12
  538. package/dist/persistence/drizzle.js.map +0 -1
  539. package/dist/persistence/memory.d.ts +0 -2
  540. package/dist/persistence/memory.d.ts.map +0 -1
  541. package/dist/persistence/memory.js +0 -27
  542. package/dist/persistence/memory.js.map +0 -1
  543. package/dist/persistence/migrations.d.ts +0 -19
  544. package/dist/persistence/migrations.d.ts.map +0 -1
  545. package/dist/persistence/migrations.js +0 -13
  546. package/dist/persistence/migrations.js.map +0 -1
  547. package/dist/persistence/prisma.d.ts +0 -2
  548. package/dist/persistence/prisma.d.ts.map +0 -1
  549. package/dist/persistence/prisma.js +0 -25
  550. package/dist/persistence/prisma.js.map +0 -1
  551. package/dist/persistence/schema.d.ts +0 -63
  552. package/dist/persistence/schema.d.ts.map +0 -1
  553. package/dist/persistence/schema.js +0 -28
  554. package/dist/persistence/schema.js.map +0 -1
  555. package/dist/persistence/sql.d.ts +0 -3
  556. package/dist/persistence/sql.d.ts.map +0 -1
  557. package/dist/persistence/sql.js +0 -37
  558. package/dist/persistence/sql.js.map +0 -1
  559. package/dist/protocol/blocks.d.ts +0 -10
  560. package/dist/protocol/blocks.d.ts.map +0 -1
  561. package/dist/protocol/blocks.js +0 -26
  562. package/dist/protocol/blocks.js.map +0 -1
  563. package/dist/protocol/json.d.ts +0 -6
  564. package/dist/protocol/json.d.ts.map +0 -1
  565. package/dist/protocol/json.js +0 -6
  566. package/dist/protocol/json.js.map +0 -1
  567. package/dist/protocol/ndjson.d.ts +0 -3
  568. package/dist/protocol/ndjson.d.ts.map +0 -1
  569. package/dist/protocol/ndjson.js +0 -20
  570. package/dist/protocol/ndjson.js.map +0 -1
  571. package/dist/protocol/sse.d.ts +0 -7
  572. package/dist/protocol/sse.d.ts.map +0 -1
  573. package/dist/protocol/sse.js +0 -25
  574. package/dist/protocol/sse.js.map +0 -1
  575. package/dist/proxy/pool.d.ts +0 -9
  576. package/dist/proxy/pool.d.ts.map +0 -1
  577. package/dist/proxy/pool.js +0 -27
  578. package/dist/proxy/pool.js.map +0 -1
  579. package/dist/queue/idempotency.d.ts +0 -10
  580. package/dist/queue/idempotency.d.ts.map +0 -1
  581. package/dist/queue/idempotency.js +0 -13
  582. package/dist/queue/idempotency.js.map +0 -1
  583. package/dist/queue/persistent.d.ts +0 -14
  584. package/dist/queue/persistent.d.ts.map +0 -1
  585. package/dist/queue/persistent.js +0 -66
  586. package/dist/queue/persistent.js.map +0 -1
  587. package/dist/queue/queue.d.ts +0 -7
  588. package/dist/queue/queue.d.ts.map +0 -1
  589. package/dist/queue/queue.js +0 -55
  590. package/dist/queue/queue.js.map +0 -1
  591. package/dist/queue/saga.d.ts +0 -5
  592. package/dist/queue/saga.d.ts.map +0 -1
  593. package/dist/queue/saga.js +0 -20
  594. package/dist/queue/saga.js.map +0 -1
  595. package/dist/release/assets.d.ts +0 -144
  596. package/dist/release/assets.d.ts.map +0 -1
  597. package/dist/release/assets.js +0 -157
  598. package/dist/release/assets.js.map +0 -1
  599. package/dist/release/evidence.d.ts +0 -92
  600. package/dist/release/evidence.d.ts.map +0 -1
  601. package/dist/release/evidence.js +0 -148
  602. package/dist/release/evidence.js.map +0 -1
  603. package/dist/release/verify.d.ts +0 -12
  604. package/dist/release/verify.d.ts.map +0 -1
  605. package/dist/release/verify.js +0 -112
  606. package/dist/release/verify.js.map +0 -1
  607. package/dist/runners/chain.d.ts +0 -125
  608. package/dist/runners/chain.d.ts.map +0 -1
  609. package/dist/runners/chain.js +0 -95
  610. package/dist/runners/chain.js.map +0 -1
  611. package/dist/runners/health.d.ts +0 -36
  612. package/dist/runners/health.d.ts.map +0 -1
  613. package/dist/runners/health.js +0 -26
  614. package/dist/runners/health.js.map +0 -1
  615. package/dist/runners/heartbeat.d.ts +0 -23
  616. package/dist/runners/heartbeat.d.ts.map +0 -1
  617. package/dist/runners/heartbeat.js +0 -29
  618. package/dist/runners/heartbeat.js.map +0 -1
  619. package/dist/runners/inprocess.d.ts +0 -17
  620. package/dist/runners/inprocess.d.ts.map +0 -1
  621. package/dist/runners/inprocess.js +0 -20
  622. package/dist/runners/inprocess.js.map +0 -1
  623. package/dist/runners/scheduler.d.ts +0 -5
  624. package/dist/runners/scheduler.d.ts.map +0 -1
  625. package/dist/runners/scheduler.js +0 -19
  626. package/dist/runners/scheduler.js.map +0 -1
  627. package/dist/runtime/abort.d.ts +0 -8
  628. package/dist/runtime/abort.d.ts.map +0 -1
  629. package/dist/runtime/abort.js +0 -13
  630. package/dist/runtime/abort.js.map +0 -1
  631. package/dist/runtime/compatibility.d.ts +0 -37
  632. package/dist/runtime/compatibility.d.ts.map +0 -1
  633. package/dist/runtime/compatibility.js +0 -10
  634. package/dist/runtime/compatibility.js.map +0 -1
  635. package/dist/runtime/detect.d.ts +0 -13
  636. package/dist/runtime/detect.d.ts.map +0 -1
  637. package/dist/runtime/detect.js +0 -18
  638. package/dist/runtime/detect.js.map +0 -1
  639. package/dist/runtime/engine.d.ts +0 -20
  640. package/dist/runtime/engine.d.ts.map +0 -1
  641. package/dist/runtime/engine.js +0 -61
  642. package/dist/runtime/engine.js.map +0 -1
  643. package/dist/runtime/retry.d.ts +0 -19
  644. package/dist/runtime/retry.d.ts.map +0 -1
  645. package/dist/runtime/retry.js +0 -54
  646. package/dist/runtime/retry.js.map +0 -1
  647. package/dist/runtime/worker.d.ts +0 -10
  648. package/dist/runtime/worker.d.ts.map +0 -1
  649. package/dist/runtime/worker.js +0 -25
  650. package/dist/runtime/worker.js.map +0 -1
  651. package/dist/scrape/cache.d.ts +0 -45
  652. package/dist/scrape/cache.d.ts.map +0 -1
  653. package/dist/scrape/cache.js +0 -45
  654. package/dist/scrape/cache.js.map +0 -1
  655. package/dist/scrape/crawl.d.ts +0 -47
  656. package/dist/scrape/crawl.d.ts.map +0 -1
  657. package/dist/scrape/crawl.js +0 -114
  658. package/dist/scrape/crawl.js.map +0 -1
  659. package/dist/scrape/extract.d.ts +0 -63
  660. package/dist/scrape/extract.d.ts.map +0 -1
  661. package/dist/scrape/extract.js +0 -47
  662. package/dist/scrape/extract.js.map +0 -1
  663. package/dist/scrape/normalize.d.ts +0 -52
  664. package/dist/scrape/normalize.d.ts.map +0 -1
  665. package/dist/scrape/normalize.js +0 -102
  666. package/dist/scrape/normalize.js.map +0 -1
  667. package/dist/scrape/robots.d.ts +0 -37
  668. package/dist/scrape/robots.d.ts.map +0 -1
  669. package/dist/scrape/robots.js +0 -71
  670. package/dist/scrape/robots.js.map +0 -1
  671. package/dist/scrape/schema.d.ts +0 -23
  672. package/dist/scrape/schema.d.ts.map +0 -1
  673. package/dist/scrape/schema.js +0 -92
  674. package/dist/scrape/schema.js.map +0 -1
  675. package/dist/scrape/scraper.d.ts +0 -6
  676. package/dist/scrape/scraper.d.ts.map +0 -1
  677. package/dist/scrape/scraper.js +0 -46
  678. package/dist/scrape/scraper.js.map +0 -1
  679. package/dist/scrape/semantic.d.ts +0 -25
  680. package/dist/scrape/semantic.d.ts.map +0 -1
  681. package/dist/scrape/semantic.js +0 -27
  682. package/dist/scrape/semantic.js.map +0 -1
  683. package/dist/server/node.d.ts +0 -7
  684. package/dist/server/node.d.ts.map +0 -1
  685. package/dist/server/node.js.map +0 -1
  686. package/dist/sessions/file.d.ts +0 -25
  687. package/dist/sessions/file.d.ts.map +0 -1
  688. package/dist/sessions/file.js +0 -13
  689. package/dist/sessions/file.js.map +0 -1
  690. package/dist/sessions/replay.d.ts +0 -9
  691. package/dist/sessions/replay.d.ts.map +0 -1
  692. package/dist/sessions/replay.js +0 -70
  693. package/dist/sessions/replay.js.map +0 -1
  694. package/dist/sessions/store.d.ts +0 -25
  695. package/dist/sessions/store.d.ts.map +0 -1
  696. package/dist/sessions/store.js +0 -13
  697. package/dist/sessions/store.js.map +0 -1
  698. package/dist/storage/adapter.d.ts +0 -5
  699. package/dist/storage/adapter.d.ts.map +0 -1
  700. package/dist/storage/adapter.js +0 -11
  701. package/dist/storage/adapter.js.map +0 -1
  702. package/dist/storage/cache.d.ts +0 -23
  703. package/dist/storage/cache.d.ts.map +0 -1
  704. package/dist/storage/cache.js +0 -79
  705. package/dist/storage/cache.js.map +0 -1
  706. package/dist/storage/checksum.d.ts +0 -3
  707. package/dist/storage/checksum.d.ts.map +0 -1
  708. package/dist/storage/checksum.js +0 -19
  709. package/dist/storage/checksum.js.map +0 -1
  710. package/dist/storage/chunked.d.ts +0 -21
  711. package/dist/storage/chunked.d.ts.map +0 -1
  712. package/dist/storage/chunked.js +0 -67
  713. package/dist/storage/chunked.js.map +0 -1
  714. package/dist/storage/content.d.ts +0 -24
  715. package/dist/storage/content.d.ts.map +0 -1
  716. package/dist/storage/content.js +0 -44
  717. package/dist/storage/content.js.map +0 -1
  718. package/dist/storage/filehosting.d.ts +0 -2
  719. package/dist/storage/filehosting.d.ts.map +0 -1
  720. package/dist/storage/filehosting.js +0 -24
  721. package/dist/storage/filehosting.js.map +0 -1
  722. package/dist/storage/githubcontents.d.ts +0 -2
  723. package/dist/storage/githubcontents.d.ts.map +0 -1
  724. package/dist/storage/githubcontents.js +0 -29
  725. package/dist/storage/githubcontents.js.map +0 -1
  726. package/dist/storage/index.d.ts +0 -12
  727. package/dist/storage/index.d.ts.map +0 -1
  728. package/dist/storage/index.js +0 -12
  729. package/dist/storage/index.js.map +0 -1
  730. package/dist/storage/local.d.ts +0 -2
  731. package/dist/storage/local.d.ts.map +0 -1
  732. package/dist/storage/local.js +0 -72
  733. package/dist/storage/local.js.map +0 -1
  734. package/dist/storage/memory.d.ts +0 -6
  735. package/dist/storage/memory.d.ts.map +0 -1
  736. package/dist/storage/memory.js +0 -36
  737. package/dist/storage/memory.js.map +0 -1
  738. package/dist/storage/pool.d.ts +0 -95
  739. package/dist/storage/pool.d.ts.map +0 -1
  740. package/dist/storage/pool.js +0 -202
  741. package/dist/storage/pool.js.map +0 -1
  742. package/dist/storage/s3compatible.d.ts +0 -3
  743. package/dist/storage/s3compatible.d.ts.map +0 -1
  744. package/dist/storage/s3compatible.js +0 -70
  745. package/dist/storage/s3compatible.js.map +0 -1
  746. package/dist/storage/sync.d.ts +0 -47
  747. package/dist/storage/sync.d.ts.map +0 -1
  748. package/dist/storage/sync.js +0 -75
  749. package/dist/storage/sync.js.map +0 -1
  750. package/dist/surfaces/adapters.d.ts +0 -97
  751. package/dist/surfaces/adapters.d.ts.map +0 -1
  752. package/dist/surfaces/adapters.js +0 -50
  753. package/dist/surfaces/adapters.js.map +0 -1
  754. package/dist/surfaces/controls.d.ts +0 -18
  755. package/dist/surfaces/controls.d.ts.map +0 -1
  756. package/dist/surfaces/controls.js +0 -45
  757. package/dist/surfaces/controls.js.map +0 -1
  758. package/dist/surfaces/manifest.d.ts +0 -68
  759. package/dist/surfaces/manifest.d.ts.map +0 -1
  760. package/dist/surfaces/manifest.js +0 -42
  761. package/dist/surfaces/manifest.js.map +0 -1
  762. package/dist/surfaces/n8n.d.ts +0 -25
  763. package/dist/surfaces/n8n.d.ts.map +0 -1
  764. package/dist/surfaces/n8n.js +0 -31
  765. package/dist/surfaces/n8n.js.map +0 -1
  766. package/dist/surfaces/operations.d.ts +0 -32
  767. package/dist/surfaces/operations.d.ts.map +0 -1
  768. package/dist/surfaces/operations.js +0 -53
  769. package/dist/surfaces/operations.js.map +0 -1
  770. package/dist/surfaces/requirements.d.ts +0 -29
  771. package/dist/surfaces/requirements.d.ts.map +0 -1
  772. package/dist/surfaces/requirements.js +0 -50
  773. package/dist/surfaces/requirements.js.map +0 -1
  774. package/dist/surfaces/targets.d.ts +0 -196
  775. package/dist/surfaces/targets.d.ts.map +0 -1
  776. package/dist/surfaces/targets.js +0 -27
  777. package/dist/surfaces/targets.js.map +0 -1
  778. package/dist/webhook/delivery.d.ts +0 -18
  779. package/dist/webhook/delivery.d.ts.map +0 -1
  780. package/dist/webhook/delivery.js +0 -36
  781. package/dist/webhook/delivery.js.map +0 -1
  782. package/dist/webhook/receiver.d.ts +0 -26
  783. package/dist/webhook/receiver.d.ts.map +0 -1
  784. package/dist/webhook/receiver.js +0 -24
  785. package/dist/webhook/receiver.js.map +0 -1
  786. package/dist/webhook/signature.d.ts +0 -3
  787. package/dist/webhook/signature.d.ts.map +0 -1
  788. package/dist/webhook/signature.js +0 -7
  789. package/dist/webhook/signature.js.map +0 -1
  790. package/dist/workflow/manifest.d.ts +0 -22
  791. package/dist/workflow/manifest.d.ts.map +0 -1
  792. package/dist/workflow/manifest.js +0 -21
  793. package/dist/workflow/manifest.js.map +0 -1
  794. package/dist/workflow/registry.d.ts +0 -7
  795. package/dist/workflow/registry.d.ts.map +0 -1
  796. package/dist/workflow/registry.js +0 -18
  797. package/dist/workflow/registry.js.map +0 -1
  798. package/dist/workflow/templates.d.ts +0 -6
  799. package/dist/workflow/templates.d.ts.map +0 -1
  800. package/dist/workflow/templates.js +0 -18
  801. package/dist/workflow/templates.js.map +0 -1
  802. package/dist/workflow/triggers.d.ts +0 -64
  803. package/dist/workflow/triggers.d.ts.map +0 -1
  804. package/dist/workflow/triggers.js +0 -99
  805. package/dist/workflow/triggers.js.map +0 -1
  806. package/docs/logs/.gitkeep +0 -0
  807. package/docs/plans/00.index.md +0 -50
  808. package/docs/plans/01.architecture.md +0 -86
  809. package/docs/plans/02.research.computer.use.md +0 -58
  810. package/docs/plans/03.research.captcha.bypass.md +0 -68
  811. package/docs/plans/04.research.sandbox.ai.md +0 -52
  812. package/docs/plans/05.capture.platform.md +0 -57
  813. package/docs/plans/06.dependencies.md +0 -97
  814. package/docs/plans/07.captcha.test.page.md +0 -41
  815. package/docs/plans/08.production.infra.md +0 -70
  816. package/docs/plans/09.database.schema.md +0 -121
  817. package/docs/plans/10.cloudinary.storage.md +0 -57
  818. package/docs/plans/11.movement.logs.json.md +0 -72
  819. package/docs/plans/12.research.atlas.agent.browser.md +0 -79
  820. package/docs/plans/13.research.anti.detection.md +0 -898
  821. package/docs/plans/14.research.proxy.md +0 -1495
  822. package/docs/plans/15.research.retry.rate.limit.md +0 -1958
  823. package/docs/plans/16.research.crawling.md +0 -1417
  824. package/docs/plans/17.research.caching.md +0 -1610
  825. package/docs/plans/18.research.content.extraction.md +0 -1952
  826. package/docs/plans/19.research.errors.events.md +0 -1523
  827. package/docs/plans/20.research.zod.validation.md +0 -1350
  828. package/docs/plans/21.research.batch.concurrency.md +0 -1888
  829. package/docs/plans/22.research.universal.runtime.md +0 -944
  830. package/docs/plans/23.research.ai.integration.md +0 -1465
  831. package/docs/plans/24.research.memory.persistence.md +0 -1979
  832. package/docs/plans/25.research.server.api.md +0 -342
  833. package/docs/plans/26.research.compilation.md +0 -249
  834. package/docs/plans/27.research.html.parsing.md +0 -251
  835. package/docs/plans/28.action.plan.md +0 -50
  836. package/docs/plans/29.api.reference.md +0 -174
  837. package/docs/plans/30.architecture.plan.md +0 -94
  838. package/docs/plans/31.auditoria.dados.md +0 -163
  839. package/docs/plans/32.bots.automacao.computacional.md +0 -214
  840. package/docs/plans/33.bots.codigo.revisao.md +0 -220
  841. package/docs/plans/34.bots.seguranca.cicd.md +0 -366
  842. package/docs/plans/35.comparativo.concorrencia.md +0 -464
  843. package/docs/plans/36.computational.memory.md +0 -340
  844. package/docs/plans/37.deploystrategy.md +0 -394
  845. package/docs/plans/38.flow.md +0 -155
  846. package/docs/plans/39.multi.platform.bot.md +0 -252
  847. package/docs/plans/40.npm.publish.md +0 -250
  848. package/docs/plans/41.o.que.falta.md +0 -407
  849. package/docs/plans/42.pesquisa.concorrencia.md +0 -721
  850. package/docs/plans/43.plan.universal.architecture.md +0 -496
  851. package/docs/plans/44.reference.md +0 -100
  852. package/docs/plans/45.robotarchitecture.md +0 -237
  853. package/docs/plans/46.scdnintegration.md +0 -284
  854. package/docs/plans/47.multiforge.readme.md +0 -129
  855. package/docs/plans/48.theory.v4.repo.os.md +0 -152
  856. package/docs/plans/49.third.party.infra.md +0 -12
  857. package/docs/plans/50.file.as.compute.md +0 -39
  858. package/docs/plans/51.architecture.virtual.processor.md +0 -80
  859. package/docs/plans/52.manifesto.v8.md +0 -11
  860. package/docs/plans/58.cdn.list.md +0 -23
  861. package/docs/plans/59.sql.frameworks.md +0 -33
  862. package/docs/plans/60.sql.thirdparty.md +0 -26
  863. package/docs/plans/61.objective.multiforge.md +0 -63
  864. package/docs/plans/62.huggingface.upload.md +0 -26
  865. package/docs/plans/63.kaggle.upload.md +0 -24
  866. package/docs/plans/64.npm.storage.md +0 -30
  867. package/docs/plans/65.rclone.terabox.md +0 -32
  868. package/docs/plans/66.buckets.and.models.todo.md +0 -14
  869. package/docs/plans/67.database.todo.md +0 -13
  870. package/docs/plans/68.deploy.packages.todo.md +0 -12
  871. package/docs/plans/69.report.human.operator.md +0 -133
  872. package/docs/plans/70.report.brain2qwerty.ems.md +0 -135
  873. package/docs/plans/71.report.hd.infinito.vram.md +0 -155
  874. package/docs/plans/72.plan.hd.infinito.node.md +0 -146
  875. package/docs/plans/73.plan.scifi.repos.md +0 -125
  876. package/docs/plans/74.000.manifesto.v8.flat.2..md +0 -11
  877. package/docs/plans/README.md +0 -489
  878. package/docs/plans/aggregate_platforms.mjs +0 -146
  879. package/docs/plans/examplesession.json +0 -36
  880. package/docs/plans/missing-facts.md +0 -192
  881. package/docs/plans/models.md +0 -64
  882. package/docs/plans/organize.cjs +0 -270
  883. package/docs/plans/platforms.md +0 -2887
  884. package/docs/plans/sites.md +0 -31322
  885. package/docs/sources/farm.py +0 -117
  886. package/docs/sources/html/saddle1.html +0 -132
  887. package/docs/sources/html/saddle2.html +0 -157
  888. package/docs/sources/html/saddle3.html +0 -119
  889. package/docs/sources/html/saddle4.html +0 -144
  890. package/docs/sources/html/saddle5.html +0 -72
  891. package/docs/sources/html/saddle6.html +0 -171
  892. package/docs/sources/html/saddle7.html +0 -236
  893. package/docs/sources/saddle.ts +0 -74
  894. package/docs/sources/schema.prisma +0 -88
  895. package/docs/sources/script.sh +0 -64
  896. package/docs/sources/workflows.yml +0 -458
  897. package/docs/talks1/_body.txt +0 -14
  898. package/docs/talks1/_index.md +0 -15
  899. package/docs/talks1/_screenshot.png +0 -0
  900. package/docs/talks1/assistant-01.md +0 -5
  901. package/docs/talks1/assistant-02.md +0 -5
  902. package/docs/talks1/assistant-03.md +0 -531
  903. package/docs/talks1/assistant-04.md +0 -26
  904. package/docs/talks1/assistant-05.md +0 -774
  905. package/docs/talks1/assistant-06.md +0 -1718
  906. package/docs/talks1/scrape-share.cjs +0 -185
  907. package/docs/talks1/scrape-share.ts +0 -183
  908. package/docs/talks1/user-01.md +0 -3
  909. package/docs/talks1/user-02.md +0 -3
  910. package/docs/talks1/user-03.md +0 -88
  911. package/docs/talks1/user-04.md +0 -3
  912. package/docs/talks1/user-05.md +0 -3
  913. package/docs/talks1/user-06.md +0 -88
  914. package/docs/talks1/user-07.md +0 -88
  915. package/docs/talks2/_body.txt +0 -14
  916. package/docs/talks2/_index.md +0 -16
  917. package/docs/talks2/_screenshot.png +0 -0
  918. package/docs/talks2/assistant-01.md +0 -5
  919. package/docs/talks2/assistant-02.md +0 -5
  920. package/docs/talks2/assistant-03.md +0 -424
  921. package/docs/talks2/assistant-04.md +0 -598
  922. package/docs/talks2/assistant-05.md +0 -1280
  923. package/docs/talks2/assistant-06.md +0 -1227
  924. package/docs/talks2/assistant-07.md +0 -1252
  925. package/docs/talks2/user-01.md +0 -3
  926. package/docs/talks2/user-02.md +0 -3
  927. package/docs/talks2/user-03.md +0 -88
  928. package/docs/talks2/user-04.md +0 -88
  929. package/docs/talks2/user-05.md +0 -88
  930. package/docs/talks2/user-06.md +0 -88
  931. package/docs/talks2/user-07.md +0 -3
  932. package/docs/talks3/_body.txt +0 -467
  933. package/docs/talks3/_index.md +0 -10
  934. package/docs/talks3/_screenshot.png +0 -0
  935. package/docs/talks3/assistant-01.md +0 -417
  936. package/docs/talks3/assistant-02.md +0 -417
  937. package/docs/talks3/assistant-03.md +0 -29
  938. package/docs/talks3/assistant-04.md +0 -727
  939. package/docs/talks3/user-01.md +0 -88
  940. package/docs/talks3/user-02.md +0 -88
  941. package/docs/talks3/user-03.md +0 -3
  942. package/docs/talks3/user-04.md +0 -3
  943. package/docs/talks4/_body.txt +0 -14
  944. package/docs/talks4/_index.md +0 -12
  945. package/docs/talks4/_screenshot.png +0 -0
  946. package/docs/talks4/assistant-01.md +0 -5
  947. package/docs/talks4/assistant-02.md +0 -5
  948. package/docs/talks4/assistant-03.md +0 -35
  949. package/docs/talks4/assistant-04.md +0 -512
  950. package/docs/talks4/assistant-05.md +0 -599
  951. package/docs/talks4/user-01.md +0 -3
  952. package/docs/talks4/user-02.md +0 -3
  953. package/docs/talks4/user-03.md +0 -88
  954. package/docs/talks4/user-04.md +0 -88
  955. package/docs/talks4/user-05.md +0 -7
  956. package/docs/talks5/_body.txt +0 -14
  957. package/docs/talks5/_index.md +0 -13
  958. package/docs/talks5/_screenshot.png +0 -0
  959. package/docs/talks5/assistant-01.md +0 -5
  960. package/docs/talks5/assistant-02.md +0 -5
  961. package/docs/talks5/assistant-03.md +0 -690
  962. package/docs/talks5/assistant-04.md +0 -758
  963. package/docs/talks5/assistant-05.md +0 -974
  964. package/docs/talks5/user-01.md +0 -3
  965. package/docs/talks5/user-02.md +0 -3
  966. package/docs/talks5/user-03.md +0 -105
  967. package/docs/talks5/user-04.md +0 -105
  968. package/docs/talks5/user-05.md +0 -63
  969. package/docs/talks5/user-06.md +0 -105
  970. package/docs/talks6/_body.txt +0 -14
  971. package/docs/talks6/_index.md +0 -9
  972. package/docs/talks6/_screenshot.png +0 -0
  973. package/docs/talks6/assistant-01.md +0 -5
  974. package/docs/talks6/assistant-02.md +0 -5
  975. package/docs/talks6/assistant-03.md +0 -1499
  976. package/docs/talks6/user-01.md +0 -3
  977. package/docs/talks6/user-02.md +0 -3
  978. package/docs/talks6/user-03.md +0 -88
  979. package/docs/talks6/user-04.md +0 -88
  980. package/docs/talks7/_body.txt +0 -14
  981. package/docs/talks7/_index.md +0 -10
  982. package/docs/talks7/_screenshot.png +0 -0
  983. package/docs/talks7/assistant-01.md +0 -5
  984. package/docs/talks7/assistant-02.md +0 -5
  985. package/docs/talks7/assistant-03.md +0 -523
  986. package/docs/talks7/assistant-04.md +0 -617
  987. package/docs/talks7/user-01.md +0 -3
  988. package/docs/talks7/user-02.md +0 -3
  989. package/docs/talks7/user-03.md +0 -105
  990. package/docs/talks7/user-04.md +0 -67
  991. package/docs/talks8/conversa1.txt +0 -1322
  992. package/docs/talks8/conversa2.txt +0 -237
  993. package/docs/talks9/Beyond the Obvious_ 50 Plataformas Auto-Hospedadas de Forja de C/303/263digo para Al/303/251m de Gitea e GitLab.md" +0 -174
  994. package/docs/talks9/De NPM a Multi-Linguagem_ Uma Arquitetura T/303/251cnica para a Execu/303/247/303/243o Integrada de C/303/263digo no Ecossistema Node.js.md" +0 -59
  995. package/docs/talks9/De NPM a VMs Virtuais_ Uma An/303/241lise Arquitet/303/264nica para a Realiza/303/247/303/243o do Ciclo de Vida do Projeto SADDLE.md" +0 -91
  996. package/docs/talks9/Mapeamento da Engrenagem Computacional_ Uma Arquitetura para Execu/303/247/303/243o Isolada e Persist/303/252ncia em Ambientes Distribu/303/255dos.md" +0 -116
  997. package/docs/talks9/O Cen/303/241rio Pr/303/241tico do SADDLE_ Uma An/303/241lise de Viabilidade e Modelo de Ciclo de Vida Integrado.md" +0 -128
  998. package/docs/talks9/README (2).md +0 -489
  999. package/docs/talks9/README.md +0 -198
  1000. package/docs/talks9/Viabilidade do Saddle_ Uma An/303/241lise T/303/251cnica da Transforma/303/247/303/243o de Armazenamento Remoto em Mem/303/263ria Computacional.md" +0 -80
  1001. package/docs/talks9/conversa.txt +0 -544
  1002. package/docs/talks9/other (2).md +0 -39
  1003. package/docs/talks9/other.md +0 -57
  1004. package/docs/talks9/outro.txt +0 -24
  1005. /package/{extension/README.md → docs/extension.md} +0 -0
@@ -1,489 +0,0 @@
1
- # Saddle
2
-
3
- Binary computing agent, agent browser, computer-use, scraper and packager.
4
-
5
- > **Storage turned into memory.** Saddle runs on other people's computers (GitHub Actions, Forgejo, Gitea, GitLab, Codeberg, free Docker containers) and turns unlimited third-party storage buckets into virtual RAM/GPU/CPU. **Nothing runs on the operator's local machine.** Ships as a library, CLI, binary, n8n node, CRX extension, Android/iOS and Tauri desktop app. Package `@wenathlan/saddle` — published to npm, GitHub Packages, Maven, NuGet, RubyGems and GitHub Containers (auto-mirrored to jsDelivr). It is simultaneously **sandbox + virtual machine + webhook server + workflow orchestrator (n8n-style) + packager + deployment system + integration platform** — sometimes each *is* the other three; the virtual VMs expose vCPU/VRAM/vGPU/virtual processing to the user, 100% on the internet, 100% virtual.
6
-
7
- This document is the single source of truth, arranged as a progressive arc: **Foundation (1–6)**, **Engine (7–17)**, **Productization (18–31)**. Nothing here is attributed to external tooling; it is the project's own architecture.
8
-
9
- ## Foundation
10
-
11
- ### 1. What Saddle Is
12
-
13
- A **virtual machine you publish as a package**. Core thesis: **storage bytes and compute-memory bytes are the same bytes** — the only difference is a *usage flag* (process vs keep). A Node.js framework runs on other people's runners, loading storage buckets as virtual RAM/GPU via a storage→RAM bridge. The operator only owns: accounts, the published repo/package, and the automation breadboard.
14
-
15
- - **Agent Browser** — Brave capture, movement replay, session recording, binary computing.
16
- - **Computational Memory** — repos / Hugging Face / Kaggle / S3 → virtual RAM/GPU; published as a package.
17
- - **Captcha Bypass** — hCaptcha, Cloudflare Turnstile, reCAPTCHA (VLM ONNX + token APIs).
18
- - **Multi-Platform Bot** — GitHub, GitLab, Forgejo, Gitea, Discord, Telegram, Reddit, HF via a unified adapter.
19
- - **Compute Backends** — GitHub (4 vCPU / 16 GB, unlimited OSS minutes), Forgejo/Gitea self-hosted (unlimited), GitLab Free (400–800 min/mo, 10 GB), Codeberg + Woodpecker (750 MB FLOSS), HF Spaces (16 GB RAM, suspends after 48 h idle — keep-alive cron), HF ZeroGPU (~96 GB VRAM, a few min/day free), Kaggle (30 h/wk GPU T4/P100), ModelScope (2,000 calls/day + 2 notebook-VM accounts that run the engine directly on their compute), Oracle Cloud Always Free (2 OCPU / 12 GB ARM), free Docker containers. Provider chain: **oracle-cloud → github-actions → huggingface → gitlab-ci → kaggle** — the first free runner wins (`github-actions {cpu:4, ramGb:16, maxDuration:6h}`). GitHub Actions runners are owned by Microsoft — the *whole* chain runs on third-party hosts.
20
- - **Storage Backends (virtual memory)** — HF (500 GB/file), Kaggle (200 GB/dataset), Terabox (1 TB, ×3 = 3 TB), R2, Telegram (2 GB/file Bot API), Discord (∞ via 8 MB chunks) — aggregated via rclone (70+ backends) into effectively unlimited disk that behaves as RAM/GPU.
21
- - **Package Surfaces** — n8n node, CRX extension, Android/iOS (native or Ionic/Capacitor), Tauri desktop + Electron/Unity converts.
22
-
23
- **Agent Browser (capture & replay):** the same engine records and replays human movement deterministically. Virtual mouse = CDP `Input.dispatchMouseEvent` + SVG cursor sprite with trail and click ripple; trajectory follows a Bézier curve with realistic speed phases (0–5% ramp 0.3×→2.5×; 5–75% cruise 2.3–2.5× with sinusoidal jitter; 75–100% ease-out 2.5×→0.3×; sub-pixel final drift σ 0.3–1.5 px), duration from Fitts's law `0.05 + 0.07·log2(1 + d/20)` s, ~15% overshoot on long moves. Typing = lognormal inter-key delay (μ=4.17, σ=0.3 → ~65 ms) with bigram speedup and ~2% typos; scroll = wheel with accel/decel + settle delay. Stealth patches `navigator.webdriver`→`undefined`, plugins/WebGL/canvas/audio, per-session coherent fingerprints.
24
-
25
- **Session JSON (`docs/logs/<session>.json`)** — one reproducible artifact per session:
26
-
27
- ```json
28
- { "version": 1, "session": { "id": "sess_...", "agentName": "UKA-capture", "browser": "brave",
29
- "originUrl": "https://accounts.hcaptcha.com/demo", "seed": "session-42", "personality": "careful",
30
- "viewport": "1280x800", "startedAt": "…", "finishedAt": "…", "status": "passed" },
31
- "events": [ { "t": 12.4, "type": "move", "x": 312, "y": 480, "tx": 320, "ty": 500 },
32
- { "t": 220.1, "type": "click", "x": 320, "y": 500, "button": "left", "target": "#checkbox" },
33
- { "t": 540.0, "type": "scroll", "dx": 0, "dy": -120, "angle": 0 } ],
34
- "captcha": { "kind": "hcaptcha", "sitekey": "a9b5fb07-…", "passed": true, "solver": "vlm",
35
- "evidenceUrl": "https://res.cloudinary.com/uka/sess_…/hcaptcha.png" },
36
- "metrics": { "eventCount": 1284, "durationMs": 201000, "avgMouseSpeed": 2.3, "clickCount": 7 } }
37
- ```
38
-
39
- Event types: `move | click | drag | scroll | key`; `drag` is typed `(t, x0, y0, x1, y1)`, `key` `(t, key="Enter", target)`, click carries `button:"left"|"right"`; coordinates in CSS px, `t` in ms relative; long move runs may be compacted; every log is reproducible from `seed` + `events`. `viewport` is an object `{width, height}`; ids look like `sess_01J9XEXAMPLE0001`. `replay.js` re-dispatches events in Brave at configurable speed; `d3` plots the mouse trail; evidence (screenshot/token/video via `ffmpeg-static`) goes to Cloudinary. Baselines: hybrid DOM+vision wins — OpenAI CUA 87% complex-JS (58% WebArena), Google Mariner 83.5% WebVoyager (84% ScreenSpot), browser-use 89.1%, OSWorld human 72.4% vs SOTA ~12–20%; WebArena top systems ~71%, production range 50–60%; Microsoft UFO² = Windows UI Automation + OmniParser (vision).
40
-
41
- **Build gates:** planning + research complete; platform implementation begins only on explicit user go-ahead.
42
-
43
- ### 2. Core Principle: Storage == Compute
44
-
45
- One rule underlies everything: **RAM and disk are the same construct** — `inode + dentry + file_operations` in VFS. Storage and RAM differ only by *backing*; a static repo file is `/usr /bin /lib`, a static site is the BIOS, a workflow trigger is the bootloader.
46
-
47
- | Aspect | Storage | Compute memory | Same? |
48
- |--------|---------|----------------|-------|
49
- | Bytes | yes | yes | ✅ |
50
- | Abstraction | VFS inode | VFS inode | ✅ |
51
- | Difference | usage flag = keep | usage flag = process | only flag |
52
-
53
- **Hard physical limit:** storage ≠ VRAM. VRAM is soldered (≈900 GB/s bus); remote storage has ~50–300 ms latency. Bucket-as-VRAM is impossible; bucket-as-VHD via FUSE is valid.
54
-
55
- ### 3. Repo-as-CPU & Repo OS
56
-
57
- A git repo + CI runner is a **serverless function / virtual processor**.
58
-
59
- | Piece | Role in the "computer" |
60
- |-------|------------------------|
61
- | Repo | Disk (persistent state in `docs/results/`) |
62
- | CI | CPU (`workflow_dispatch` = function call) |
63
- | Pages | Bus + CDN (static JSON as shared memory) |
64
- | Static site | BIOS (~50 KB, triggers and polls) |
65
- | `repository_dispatch` | IPC between repositories |
66
- | `workflow_dispatch` | cross-repo API call — returns `run_id` since Feb 2026 |
67
- | `workflow_call` / `workflow_run` | reusable / intra-repo chaining |
68
-
69
- **VFS theory — "everything is a file":** process, memory, device and socket are all `inode + dentry + file_operations`. Docker OverlayFS (`lowerdir` read-only → `upperdir` writable → `merged`) and K8s `emptyDir`/tmpfs turn static filesystem into a running system. A VM is a static `qcow2`/`vmdk` + an emulator.
70
-
71
- - **Magic bytes are the true type** (extension is UX): ELF `7F 45 4C 46`, PE `4D 5A`+`50 45 00 00`, PNG `89 50 4E 47 0D 0A 1A 0A`, ZIP `50 4B 03 04`. The loader **reads magic bytes → picks parser → maps to RAM → executes**; "10 GB RAM and 600 GB storage" are the same gigabytes, with 1-bit/4-bit quantization as the fallback to squeeze models into that budget.
72
- - **VM-as-file:** v86 boots Linux from a static ISO on Pages (`seabios.bin` + cdrom `linux.iso`); WebContainers run Node-in-WASM with a SharedArrayBuffer FS (needs COOP/COEP — `coi-serviceworker` shim + `.nojekyll`).
73
- - **RAM-ified git:** `git clone --separate-git-dir=/dev/shm/repo.git` + `mount -o bind /dev/shm/repo /mnt/repo` runs a working copy fully in RAM; browsers only ever read a **256-byte preview** via `File API slice` (never the full binary). OverlayFS `copy_up` copies a whole file lower→upper on first write.
74
- - Each static file is a handler: `api/queue.json` as message queue, `dumps/incoming/` as binary inbox.
75
-
76
- **Storage → RAM (inside a runner):**
77
-
78
- ```bash
79
- fallocate -l 16G /mnt/swapfile && mkswap /mnt/swapfile && swapon /mnt/swapfile # disk → RAM
80
- mount -t tmpfs -o size=8G tmpfs /mnt/ramdisk # RAM → fast disk
81
- modprobe zram && echo 8G > /sys/block/zram0/disksize && mkswap /dev/zram0 && swapon /dev/zram0 # 2–3× compression
82
- ```
83
-
84
- Heavy work runs in `/mnt/ramdisk`; results commit to `docs/results/` and are served via Pages/CDN. The client only does `File` API slice + base64 + `fetch`.
85
-
86
- **mmap — one buffer, two roles:** `mmap(MAP_SHARED)` maps a storage file directly into the process address space — the *same* bytes are simultaneously storage and RAM; `mmap.sync()` flushes RAM→storage; file grows via `ftruncate`. Libraries: `@riaskov/mmap-io`, `@cloudpss/mmap` (`/dev/shm`), memfs/unionfs, `@platformatic/vfs` (SQLite-backed VFS), paged-buffer (64 KB pages, ~50 pages ≈ 3 MB resident).
87
-
88
- **Persistent liquid sandbox (`storage.bin`):** CI downloads the previous `storage.bin` artifact → mmaps it → CDN packages (`https://esm.sh/…`) fetched and written into the buffer → container runs (8 GB RAM + 8 GB storage) → `bridge.sync()` flushes RAM→storage → artifact re-uploaded (7-day retention) → next session resumes exactly where it left off.
89
-
90
- ### 4. Multiforge & Distributed Compute
91
-
92
- Mirroring the engine across forges multiplies free quota.
93
-
94
- | Forge | Minutes | Storage | Role |
95
- |-------|---------|---------|------|
96
- | GitHub Public | unlimited (OSS), 6 h/job, 20 concurrent jobs | 500 MB artifacts, 10 GB cache, 1 GB Pages | primary |
97
- | Forgejo self-hosted | unlimited (your HW) | unlimited | mirror |
98
- | Gitea self-hosted | unlimited | unlimited | mirror |
99
- | Codeberg + Woodpecker | unlimited FLOSS | 750 MB soft | OSS backup |
100
- | GitLab Free | 400 min/mo | 10 GB/project | Pages fallback |
101
- | HF Buckets | — | 500 GB/file, 100 GB private | AI storage |
102
- | Kaggle | — | 200 GB/dataset (10 = 2 TB) | datasets |
103
-
104
- **Farm:** `n` worker repos × 500 MB = distributed storage (`100 opencode-worker-N` repos × 500 MB = **50 GB**); a controller (`scripts/farm.py`) dispatches `workflow_dispatch` (`{job_id, filename, action: run}`, and `binary_url` in the V3 draft) and breaks at the **first free runner (`204 Accepted`)** — not blind round-robin. Parallel repo-related push ≈ 4× compute. Real workflow file set: GitHub `.github/workflows/{process-binary,opencode-runner,dump-processor,pages,cleanup,thirdparty-only}.yml`; Forgejo `.forgejo/workflows/{forgejo-heavy,thirdparty-only}.yml`; Gitea `.gitea/workflows/saddle.yml`; Codeberg `.woodpecker/deploy.yml`; GitLab root `.gitlab-ci.yml` (hard-coded `heavy_processor` + `pages` jobs). `opencode-runner.yml` listens on `repository_dispatch` type `opencode-run` + `workflow_dispatch` (inputs `session_id`, `prompt`, model default `opencode/gpt-5`) → installs opencode via `curl -fsSL https://opencode.ai/install | bash` → `opencode run --format json` → `.opencode/results/{session_id}.json`. `cleanup.yml` (cron `0 0 * * 0`) deletes artifacts older than 7 d via `actions/github-script@v7` (`listArtifactsForRepo` + `deleteArtifact`). `thirdparty-only.yml` forces `ubuntu-latest` public, never self-hosted. Multi-forge paths: GitHub `.github/workflows/`, Forgejo/Gitea `.forgejo/`/`.gitea/workflows/`, Codeberg `.woodpecker/`, GitLab `.gitlab-ci.yml` (`saas-linux-small-amd64` default tag, `medium` when RAM>8 GB). Forgejo Actions ≈95% GitHub-Actions compatible (Gitea ≈90%, both self-hostable ≥512 MB).
105
-
106
- **Runner facts:** GitHub `ubuntu-latest` 4 vCPU/16 GB/14 GB SSD, public = unlimited minutes, max 6 h/job, 20 concurrent, artifacts ≤500 MB cleaned after 7 days (cleanup.yml), 2026 small runner = 1 vCPU/5 GB/15 min; Codeberg labels `codeberg-small` 2 CPU/4 GB/5 min (−medium 4/8/10 min); GitLab size classes small 2vCPU/8GB → 2xlarge 32/128 GB. Codeberg: 750 MB git + 1.5 GB LFS/packages; GitLab Pages 100 MB limit (separate Registry); GitLab cache 5 GB/14 d, artifacts unlimited/30 d default; GitHub LFS free 1 GB storage + 1 GB bandwidth/mo; GitHub cache 10 GB retained 7–90 d.
107
-
108
- **Env vars:** `SBOT_TOKEN`, `SBOT_PLATFORM`, `SBOT_MEMORY_BUCKET`, `SBOT_WEBHOOK_SECRET`, `SBOT_CDN_URL`, `SBOT_SCDN_*`, `VERCEL_REGION`, `SBOT_MEMORY_ENGINE` (ram/storage/bucket), `HF_TOKEN`, `KAGGLE_USERNAME/KEY`, 3 × Terabox remotes, plus `TURSO_DATABASE_URL`, `TURSO_AUTH_TOKEN`, `INIT_SECRET`, `SELF_URL`, `GITHUB_TOKEN`, `GITLAB_TOKEN`, `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `OPENCODE_SERVER_PASSWORD`; secret-size limit 48 KB → base64 via `AnimMouse/setup-rclone`. Gitea runner: `GITEA_INSTANCE_URL` + `GITEA_RUNNER_REGISTRATION_TOKEN` with `gitea/act_runner:latest`.
109
-
110
- ### 5. Storage Backends & Sync
111
-
112
- | Backend | Limit / pattern | CLI |
113
- |---------|-----------------|-----|
114
- | rclone | 70+ backends (S3, R2, WebDAV…); install `curl https://rclone.org/install.sh \| sudo bash`; `rclone copy … --progress --transfers 8` | `rclone copy/sync`, `rclone serve http` (local CDN, `--addr :8080`) |
115
- | S3 / R2 | object store, key `s3://bucket/uuid`; R2 free 10 GB + 10 M ops, 5 GB file | `rclone` |
116
- | Hugging Face | free unlimited best-effort; 10 TB public + 1 TB private PRO **$9/mo**; 500 GB/file via Xet | `HfApi.upload_folder`; browser-raw `https://huggingface.co/datasets/{id}/resolve/main/<file>` (dataset viewer = better for binaries) |
117
- | Kaggle | **private total 200 GB, public unlimited**; 50 top-level files; egress free via CDN; metadata `dataset-metadata.json` (title/id/licenses:[mit]/resources) | `kaggle datasets create -p … --dir-mode tar`, `kaggle datasets version -p … -m "<msg>"` |
118
- | Terabox | 1 TB/account, 4 GB/file free (20 GB premium, **300 files/transfer**); multi-cloud sync `rclone sync terabox1:… huggingface:/kaggle:` | `split -b 200M` named `.bin.js` packaging |
119
- | npm | 250 MB tarball/version (`npm pack --dry-run` preview); jsDelivr/UNPKG/esm.sh unlimited CDN; chunks renamed `.bin.js` **to escape the npm binary-content scan** | `npm publish --access public` |
120
- | Cloudinary | heavy media (video/screenshots/large JSON; mp4/webm replays, before/after challenge shots, click masks); DB stores only `url` + `cloudinaryId` | `cloudinary.uploader.upload` `{resource_type:"auto", folder:"uka/<folder>"}` |
121
- | Telegram / Discord | Telegram 2 GB/file Bot API (4 GB premium) via telethon/pyrogram (TeleSync, teledrive); Discord ∞ via 8 MB chunks (25 MB base / 500 MB Nitro), discord-fs FTP-over-Discord | chunker + mesh |
122
-
123
- **Free pool (no own machine):** GitHub 500 MB + HF ~10 TB + Kaggle 20 TB + Terabox 3 TB + npm ~unlimited + Turso 9 GB ≈ **>33 TB**. SQL sharding: `shards=[drizzle(URL_1),drizzle(URL_2)]; getShard(k)=shards[Bun.hash(k)%n]` (40 shards × 3 GB = 120 GB, or **400 shards = 1.2 TB** via HTTPS-only, no git push). Multi-cloud sync: Terabox → HF → Kaggle. **rclone hidden-RAM risk:** mounting large trees can grow driver RAM from ~1.8 GB to >7 GB (OOM) — prefer `--vfs-cache-mode full` + `--memory` limits.
124
-
125
- **npm chunk-as-package CDN farm:** `split -b 200M binary.wasm chunk-` → rename to `chunk-NNN.bin.js` → `npm publish @seuuser/assets-001…` → `https://cdn.jsdelivr.net/npm/@seuuser/assets-001@1.0.0/dist/chunk-NNN.bin.js` → fetch, rebuild in tmpfs, execute. 1 GB = 4 packages; 10 packages = 2.5 GB on a global CDN.
126
-
127
- **10 CDNs with free egress:** jsDelivr (NPM+GitHub, 50 MB GH / 100 MB npm, unlimited bw, purge API `https://purge.jsdelivr.net/gh/user/repo@tag/file` — "the free S3") · UNPKG (npm, ~100 MB, unlisted-package use for private config/JSON) · esm.sh (NPM+JSR+GitHub, TSX→JS on edge, `?bundle&min&target`, **no hard file-size limit**) · cdnjs (curated, 50 MB/file) · Statically (GH+GL+BB, image CDN `?w=` `?f=webp`) · GCore (1 TB/mo free) · Cloudflare R2 (10 GB free, 10 M ops, free egress) · Backblaze B2 (10 GB, 1 GB/day) · Supabase Storage (1 GB) · HF Hub CDN (free unlimited egress). Skypack is deprecated — use esm.sh; `esm.unpkg.com` adds ESM+bundling to UNPKG.
128
-
129
- ### 6. Memory Engine
130
-
131
- The bridge that loads storage objects into compute memory (RAM/GPU), transforms, processes and persists results back.
132
-
133
- | Method | Behavior |
134
- |--------|----------|
135
- | `load(key)` | iterates backends, returns first hit as compute buffer; throws on error |
136
- | `persist(key, data)` | writes to **all** configured backends |
137
- | `release(key)` | deletes from in-memory `Map` |
138
- | `safeLoad(key)` | wrapped `load` → `{ success, data?, error? }` |
139
-
140
- Object shapes: `MemoryObject{id, buffer, size, type, createdAt, metadata}`; `ComputeResult{id, payload, mimeType?, metadata?, processingTimeMs, memoryUsedBytes}`. Backend targets are declared per type: `RepoStorageTarget{platform,owner,repo,branch,path,token}`, `HFStorageTarget{space,revision}`, `KaggleStorageTarget{dataset,ssl_verification}`, `ModelScopeStorageTarget{namespace,repo}`, `FileHostingStorageTarget{host,path,method: upload|s3compatible|webdav}`; factory throws on unknown type. Error contract: `MemoryEngine.load failed for key "{key}": {error}`; `transformToStorage` defaults MIME to `application/octet-stream`. Use-case URIs: `repo://my-repo/large-file.bin`, `repo://models/my-model/weights.bin`, `repo://saddle/sessions/session-001.json`.
141
-
142
- Transforms: `transformToCompute` (~2× overhead) and `transformToStorage`. Backends (factory): `github`, `gitlab`, `forgejo`, `gitea`, `huggingface`, `kaggle`, `modelscope`, `filehosting` (s3compatible / webdav). Repository is primary; HF/Kaggle/ModelScope/terabox(s) secondary.
143
-
144
- **Memory capacity model (8 GB box):**
145
-
146
- | Layer | Size |
147
- |-------|------|
148
- | kernel/OS | ~500 MB |
149
- | Docker runtime | ~200 MB |
150
- | WASM runtime | ~100 MB |
151
- | Firecracker overlay | ~50 MB |
152
- | app | ~2 GB |
153
- | sandboxes | ~4 GB |
154
- | cache | ~1.15 GB |
155
-
156
- **Memory tiers (by preference):** ram (~100 ns) · zram (~500 ns) · tmpfs (~1 µs) · mmap (~5 µs) · sqlite (~10 µs) · r2 (~50 µs), auto-scaled by size (<64 MB → memfs; <1 GB → mmap; larger → SQLite/R2).
157
-
158
- **Tuning:** `sysctl vm.swappiness=180 vm.page-cluster=0` → zram 3:1 (8 → 24 GB effective); tmpfs sizes must be explicit (default ½ RAM); `--tmpfs /tmp:size=2G` as RAM-storage in containers; `/dev/shm` is already tmpfs in runners.
159
-
160
- ---
161
-
162
- ## Engine
163
-
164
- ### 7. Memory Modes & Tiers
165
-
166
- | Tier | Type | Source | Capacity |
167
- |------|------|--------|----------|
168
- | L1 | RAM | System | Limited, ephemeral |
169
- | L2 | VRAM | GPU | Limited, compute-bound |
170
- | L3 | Storage RAM | Repositories | Practically unlimited |
171
- | L4 | External buckets | HF / Kaggle / Terabox / R2 | Unlimited |
172
-
173
- Memory forms (annotated): internal — always supported, the baseline · external — repos, HF, Kaggle, S3, R2, Terabox · physical — runner RAM via swap/tmpfs/zram · vectorized — embeddings, supports **averaging / ensemble across shards** · library — shared via npm/Maven/NuGet/RubyGems/GHCR.
174
-
175
- Every operational mode works **without and with** its pair — the engine is never locked to one form: computer · library · application · browser · desktop · mobile · extension · cli · binary · headless · physical file · vector file · internal/external file · internal/external dependency. Same for memory: internal, external, physical, vectorized, library — all work with or without.
176
-
177
- ### 8. Database & SQL
178
-
179
- Drizzle ORM + `mysql2` (Turso/libSQL and Prisma/Neon as alternates). DB is **created at deploy**, never local sqlite — though `drizzle-kit generate`/`migrate` run in the build script (`"build": "drizzle-kit push && next build"`) for edge-safe migration. Columns: `BIGINT` (pointer, >2 GB), `INT` (chunk_index), `TEXT` (`s3://bucket/uuid`), `JSON` manifest, `BYTEA`/`LONGBLOB` (1 MB chunk). **Guardrail:** never put TB in one row — always chunk; base64 in DB is an anti-pattern (+33%). Postgres limits: `varlena` TOAST 1 GB, table 32 TB, `pg_largeobject` 4 TB/OID; MySQL `LONGBLOB` = 4 GB, row < 65 KB.
180
-
181
- ```sql
182
- CREATE TABLE files (id BIGSERIAL PRIMARY KEY, size_bytes BIGINT, storage_key TEXT, hash TEXT, metadata JSONB);
183
- CREATE TABLE file_chunks (file_id BIGINT REFERENCES files(id), chunk_index INT, data BYTEA, PRIMARY KEY(file_id, chunk_index)) PARTITION BY HASH(file_id);
184
- ```
185
-
186
- **Operational tables (drizzle/mysql-core):** `sessions` (id text PK, agent_name, browser default `"brave"`, origin_url, status default `"running"`, seed, timestamps; idx on status) · `events` (session_id FK cascade, t float, type, x/y float, data text; idx on session_id) · `captcha_results` (session_id FK cascade, kind, sitekey, token, passed bool, solver, evidence_url) · `assets` (session_id FK cascade, kind, cloudinary_id, url, bytes). Prisma mirrors the same four models with cascade `onDelete`.
187
-
188
- **V6 Prisma models (file-as-compute):** `Site` (id, domain unique, plan default hobby, storagePointer BigInt) → `File` (name, mime, size BigInt, sizeInt UI cache, chunkCount, sha256, metadata Json `{originalRepos[1..10], cdnUrls[]}`) → `FileChunk` (index 0..599, byteOffset BigInt = index × 1,048,576, size 1_048_576, data Bytes optional + `dataBase64 Text` fallback for D1/Turso, repoId 1..10, repoUrl raw.githubusercontent, cdnUrl cdn.jsdelivr.net, nextChunkId linked-list, checksum; `@@unique([fileId,index])`) → `ComputeJob` (type REBUILD|EXEC|TRANSPILE, status queued/running/done, priority, ramdiskPath `/mnt/ramdisk/job…/rebuilt.bin`, resultJson `{stdout,timeMs,ramUsed}`, resultUrl).
189
-
190
- **SQL frameworks (chunk-as-blob per provider):** Prisma (`bytes`→bytea/longblob) · Drizzle (`customType` bytea, light, type-safe) · TypeORM (`bytea`/`longblob`) · Sequelize (`BLOB('long')`) · Knex (`binary('data')`) · better-sqlite3 (sync) · mysql2 (LONGBLOB) · pg (bytea + large objects) · MikroORM (+DataLoader) · TypeDORM (DynamoDB-style). Prisma `driverAdapters` preview + `previewFeatures` for Postgres.
191
-
192
- **Free third-party SQL tiers:** Turso (9 GB / 500 DBs / **500 M rows read**; CLI `turso db create <name> --group default` + `turso db shell … "CREATE TABLE dumps (id TEXT, data BLOB)"`), Neon (0.5 GB → **1 project / 100 h compute**, scale-to-zero, billed only on use), Supabase (500 MB DB + 1 GB storage + 2 GB bandwidth), PlanetScale, Cloudflare D1, Deta, Fly.io SQLite. Paired with `mysql2`, `better-sqlite3`, `@libsql/client` (local file + `syncUrl: libsql://`), `pglite` for in-memory PostgreSQL, and **`node:sqlite` `DatabaseSync`** (Node 22+, `PRAGMA journal_mode=WAL / synchronous=NORMAL / cache_size=10000 / temp_store=MEMORY`) as a zero-dependency RAM/storage bridge. Drizzle generated columns (`VIRTUAL vs STORED`) support in-memory computed fields.
193
-
194
- ### 9. File-as-Compute
195
-
196
- Published site + Prisma schema stores everything as tables. `Site` (JSON data) → `File` (storage pointer, `BIGINT` size) → `FileChunk` (1 MB/row) → `ComputeJob` (queued/running/done; `runner: github|forgejo|codeberg`).
197
-
198
- **Flow:** browser drags a 600 MB `binary.wasm` → sliced into 600 × 1 MB chunks across 10 worker repos (60 chunks/worker) → `ComputeJob` queued (`runner: github|forgejo|codeberg|gitlab|huggingface`) → worker `SELECT`s chunks, rebuilds in tmpfs 8 GB, runs via WASI/Node → result back to the FileChunk table or an R2/CDN `storageKey` (jsDelivr) → browser polls `GET /api/jobs/:id`.
199
-
200
- **Pointers (TB scale):** `BigInt` id = 9×10¹⁸ files; `BigInt` size >2 GB; `BYTEA` ≤10 MB inline (else chunked); `storageKey` = `s3://bucket/uuid`. `nextChunkId` linked list keeps order; `repoId` 1..10 distributes under provider caps.
201
-
202
- ### 10. Content Types & API Communication
203
-
204
- The API accepts **any content type** — nothing is locked to one format. Sites, protocols and techniques talk to each other over HTTPS the way an LLM API does: **request in → response streamed → done**. Every exchange is a request/response pair that can arrive as JSON, an event stream, a stream of blocks/numbers/payloads, or raw bytes.
205
-
206
- | Media type | Role | Where |
207
- |-----------|------|-------|
208
- | `application/json` | primary requests/responses, dispatches, webhooks, job payloads | `POST /v1/scrape`, `workflow_dispatch`, `site`↔`site` |
209
- | `text/event-stream` (SSE) | progress streaming, LLM-style responses | `/v1/event`, `/session/message`, TUI, frontend |
210
- | `application/x-ndjson` (JSONL) | append-only event log, traces, sessions | `~/.local/share/opencode`, `docs/logs/*.jsonl`, audit |
211
- | `application/ld+json` (JSON-LD) | structured data embedded in HTML | extraction, Schema.org |
212
- | `multipart/form-data` | file & evidence upload | HF Spaces, asset evidence |
213
- | `application/octet-stream` | binary chunks (1 MB); base64 0x8000 during upload | FileChunk, SCDN, binary run |
214
- | `application/javascript` | ESM modules served from CDN | zero-install execution |
215
- | `image/png` / `video/mp4` / `markdown` | evidence, replays, serialized output | Cloudinary, serialization |
216
-
217
- **Request → stream → response (LLM-style):**
218
- ```
219
- client ──POST /v1/scrape──► API ──(validate, open stream)──► worker
220
- ◄────────── 200 text/event-stream ──────────
221
- event: message data: {"block":1,"kind":"status","value":"running"}
222
- event: message data: {"block":2,"kind":"content","value":"..."}
223
- event: done data: {"job":"sess_123","status":"completed","resultUrl":"https://cdn..."}
224
- ```
225
- - Each **block** carries a payload (string | number | JSON | Buffer); every event may be a number, a byte-chunk, or a JSON object.
226
- - Retries are at-least-once, idempotent via `request_id`.
227
- - Streams: SSE `text/event-stream` (30 s keepalive, reconnect — `proxy_buffering off` required) · WebSocket (30 s heartbeat, `socket.io` in `web/server.js`) · NDJSON lines.
228
-
229
- **Reference protocol (server, port 4096):** `GET /doc` (OpenAPI 3.1) · `GET /global/health` → `{healthy}` · `GET /global/event` (SSE `ReadableStream`, `Cache-Control: no-cache`) · `POST /session/create` → then `session.prompt` SSE · `/tui/*` (`append-prompt`, `submit-prompt`, `execute-command`, `show-toast`). Sessions are append-only JSONL under `~/.local/share/opencode`; CLI flags `--format json`, `--variant high|xhigh|max`. Auth `Basic opencode:<password>`; SSE needs `proxy_buffering off` (Nginx `X-Accel-Buffering: no`), Cloudflare free idle ~100 s → keep-alive 30 s, browsers cap ~6 SSE connections per origin.
230
-
231
- **Interop across sites and protocols:** `web` ↔ runner ↔ worker ↔ vault (Netlify/Vercel/HF) cross every hop with the **same JSON payload**. Protocols: HTTP (REST, webhooks) ↔ HTTPS (dispatches) ↔ git (3-step write: `blob → tree → commit`) ↔ WS/SSE (realtime) ↔ WebDAV/S3 (storage) ↔ CDN (esm.sh/jsDelivr). The same content-type contract passes through capture → serialize → compute → store → serve.
232
-
233
- ### 11. Request Strategies & Resilience
234
-
235
- | Method | Use in Saddle | When |
236
- |--------|---------------|------|
237
- | `GET` | fetch/crawl, `/health` | read pages |
238
- | `POST` | `/v1/scrape`, `/v1/batch`, login, webhooks, dispatches | create / send data |
239
- | `PUT` | upload/replace (SCDN) | full replace |
240
- | `PATCH` | update job/session fields | partial modify |
241
- | `DELETE` | revoke session, delete CDN asset | remove |
242
- | `HEAD` | existence / `Content-Length` before download | probe |
243
- | `OPTIONS` | CORS preflight | cross-origin check |
244
- | `CONNECT` | HTTPS proxy tunnel | proxy |
245
- | `PROPFIND`/`MKCOL`/`COPY`/`MOVE`/`LOCK` | WebDAV | remote storage |
246
- | `SUBSCRIBE`/`NOTIFY` | pub/sub | progress streaming (pre-WS/SSE) |
247
- | `TRACE` / `PRI` | diagnostics / HTTP/2 stream priority | debug, QoS |
248
-
249
- **fetch:** universal `fetch` across Node/Bun/Deno/Workers/browser — no local cross-protocol shim. Timeout via `AbortController`.
250
-
251
- **Retry & backoff** (transient only: `429 500 502 503 504 408 409`, plus Cloudflare `520–530`): exponential + jitter (with `linear`/`constant` variants), honor `Retry-After > X-Retry-After > X-Rate-Limit-Reset` (+10% margin); never retry `400 401 403 404 410 422 451` — stop/fix. Network codes that force a retry: `ECONNRESET`, `ECONNREFUSED`, `ETIMEDOUT`, `ENOTFOUND`. Combine with circuit breaker `CLOSED → OPEN → HALF_OPEN` (`failureThreshold: 5`, `resetTimeout: 60000`) and **Saga** compensations for multi-step ops. Hooks lifecycle (ky/ofetch): `beforeRequest` / `afterResponse` / `beforeRetry` / `beforeError` (`retry:3 retryDelay:1000 backoff:2^n·1000`).
252
-
253
- **Webhook idempotency (at-least-once):** key = `X-GitHub-Delivery` / `eventId` stored before processing; duplicates dropped. Validate signatures with HMAC before trust; inspect `X-RateLimit-Limit/Remaining` and batch calls.
254
-
255
- **Git writes = 3 atomic steps** via REST: push `blobs` → reference in `trees` → point `commits` to the tree. OCI registries (GitHub/GitLab Packages) double as **universal content-addressed storage** (`oras push`; Chainloop proofs).
256
-
257
- ### 12. Anti-Detection & Stealth
258
-
259
- | Category | Signal | Risk |
260
- |----------|--------|------|
261
- | Browser | `navigator.webdriver`, Canvas/WebGL/Audio, `languages`, `hardwareConcurrency` | High |
262
- | Browser (extended) | `window.chrome`, `navigator.connection`, `navigator.credentials`, WebGPU (2024+) | High |
263
- | Network | TLS JA3/JA4, HTTP/2, IP reputation | High |
264
- | Hardware | `deviceMemory`, `maxTouchPoints` | Med |
265
-
266
- **Fingerprint coherence:** 1 stable fingerprint per session, rotate only between sessions; OS↔UA↔engine mapping (Windows↔`Win32`↔Edge/Chrome, macOS↔`MacIntel`↔Safari, mobile↔touch, locale↔`Accept-Language`, timezone↔locale). **JA4** (FoxIO 2024, SHA-256, `t{TLSVer}{SNI}{CipherCount}{ExtCount}_{HashCiphers}_{HashExtensions}_{SigAlgs}_{ALPN}`, e.g. `t13d1516h2_8daaf6152771_e5627efa2ab5_c5e56a2154c7_0`) preferred over **JA3** (Salesforce 2017, MD5 of ClientHello, spoofable). HTTP/2 fingerprint = SETTINGS + WINDOW_UPDATE + PRIORITY frames (Chrome 125: `0|1|0|0|0|0|1|0|0|0|0`, WINDOW_UPDATE 15663105; Firefox 125 SETTINGS `0|0|0|0|0|1|0|0|0|0|0`, WINDOW_UPDATE 12517377). `patchright` (modified Chromium, TLS/HTTP2/CDP) >> JS-only stealth. Per-target breakdown (pass/fail): userAgent ✓ all; webdriver ✓ stealth/patchright/cloak; plugins ✓; WebGL ✓ patchright/cloak; TLS ✓ only patchright; HTTP2 ⚠ patchright/Cloak; CDP ⚠ patchright; `window.chrome` ⚠ patchright/Cloak.
267
-
268
- **Stack:** `patchright` (recommended) + `crawlee` (`useFingerprints`, `SessionPool` maxSize 100 / usage 50 / age 3600, `fingerprintOptions` browsers chrome≥120/firefox≥120/safari≥17, devices desktop/mobile, locales en-US/en-GB/pt-BR/es-ES, screen 1366–1920) + residential proxies. 2026 benchmark (block 0–30, lower better): CloakBrowser 26/2 · patchright 24/4 · puppeteer-extra-stealth 18/10 · vanilla Playwright 26/2. Realistic distribution: Chrome 65% / Safari 18% / Firefox 12% / Edge 5%; OS Windows 55% / macOS 25% / Linux 15% / Mobile 5%; resolutions 1920×1080 31% (30%), 1366×768 20%, plus 1536×864 15% / 1440×900 10%. Versions: patchright 1.x, playwright 1.45+, puppeteer 22.x+ / extra 3.3.x / stealth 2.11.x, crawlee 3.x, tls-fingerprint 1.x. **`rebrowser-playwright` is unmaintained since 2024** — use patchright. CloakBrowser (~13.5k★, 2026): `createProfile({os, browser, screen, proxy})`, integrates Puppeteer/Playwright.
269
-
270
- ### 13. Proxy
271
-
272
- | Protocol | Security | Note |
273
- |----------|----------|------|
274
- | HTTP / HTTPS | Low / Med | fast, DNS at client |
275
- | SOCKS4 / 4a | Low | no auth / DNS at proxy |
276
- | SOCKS5 / 5h | Med | auth; `socks5h` resolves DNS at proxy (no leak) — preferred |
277
-
278
- Tiers: residential (low block, ~$15/1000) > **mobile 4G/5G** (social) > datacenter (high block, ~$0.50). **Rotation:** intelligent per-session/domain, least-used, tiered — never blind `proxies[i % n]`. **1 fingerprint = 1 proxy = 1 session.** Pool health: active (`httpbin.org/ip`), passive (error score; `failureThreshold: 3`, `recoveryTime: 300000`), graveyard+revive (maxFailures 3, revive timer 300000). Packages: `crawlee`, `proxy-rotator-js` 1.3.2 (round-robin/random/least-used, healthCheck), `rezo` 1.x (2026, active health 30s/5s on `httpbin.org/ip`), `https-proxy-agent` 7.x / `socks-proxy-agent` 8.x (fetch dispatcher, Node 18+), **`proxy-chain` 2.4.0** (`ProxyChain.createServer` local chain), **`socks` 2.8.9** (`SocksClient.createConnection`).
279
-
280
- ### 14. Captcha
281
-
282
- | Priority | Layer | Coverage |
283
- |----------|-------|----------|
284
- | P1 | Stealth (fingerprint + TLS) | avoids the trace |
285
- | P2 | Human behavior (Bézier mouse, lognormal typing) | passes checkbox/score |
286
- | P3 | Solver (VLM / token API) | ~1–5% of sessions |
287
-
288
- **Solvers:** `hcaptcha-challenger` (LLM + ONNX: ResNet `image_label_binary`, YOLOv8 `area_select` point/bbox, Spatial Chain-of-Thought `drag_drop`, ViT zero-shot `multiple_choice`; pipeline `install() → AgentT.from_page() → handle_checkbox() → execute()`; deps playwright/httpx/opencv-python/pillow/loguru/pydantic-settings), NopeCHA/auto-captcha (hCaptcha ✅, reCAPTCHA v2/v3 ✅, Turnstile slow), ClickSolver / 2Captcha / CapSolver (30+ types: reCAPTCHA v2/v3/Enterprise, Turnstile, hCaptcha, FunCaptcha/Arkose, GeeTest, DataDome, Amazon WAF, Akamai, Imperva, Friendly, MTCaptcha, KeyCaptcha, Tencent, Yandex, ALTCHA, **Lemin, Cutcaptcha, Prosopo**). Turnstile resolves in ~5 s via ClickSolver (free) with paid fallback. Pipeline: `launchBrave()` → `navigate` → `detectCaptcha` → `solve(page)` → `record` → `assert`. Test fixtures: local (`tests/examples/hcaptchatest.html`) + `accounts.hcaptcha.com/demo`, `challenges.cloudflare.com/turnstile`, `google.com/recaptcha/api2/demo`; evidence (token, screenshot, trace.json, mp4 via `ffmpeg-static`) to `tests/output/`. Success: detects type; solves hCaptcha checkbox via VLM; passes Turnstile ≥1 of 3 (sticky proxy); reproducible JSON (seed).
289
-
290
- **Sandbox:** HF Spaces default 16 GB RAM; Vercel Sandbox (Firecracker microVM — per-session/agent isolated, runtimes `node26/24/22` + `python3.13` (default node24), user `vercel-sandbox` + sudo, working dir `/vercel/sandbox`, boots in ms, supports Docker **and FUSE** inside the microVM, domain-allowlist network policy updateable at runtime, **one Linux user per agent** with groups to share; secrets brokered — injected into outbound requests, never visible inside the VM); gVisor (syscall-level). Reference AI-stack: Next.js + AI SDK + Claude Sonnet 4.5 (env `ANTHROPIC_API_KEY`, `SANDBOX_SNAPSHOT_ID`, `VERCEL_OIDC_TOKEN`/`VERCEL_TOKEN`), snapshot stack Xvnc + openbox + noVNC/websockify + Chrome + tools `computer`/`bash`. MicroVM catalog beyond Firecracker/gVisor/Kata: kern (rootless, ~1.5 MB bin, ~1.9 ms cold) · exec-sandbox (QEMU, L1 ~100 ms / L2 ~400 ms, 192 MB) · mitos (Firecracker+K8s, ~27 ms) · rust-nano-vm (<1 MiB) · CubeSandbox (Rust+KVM, <60 ms boot, E2B-compatible) · Edge.js (whole Node app in WASI, ~40 ms boot). **Atlas Browser:** real multi-mode browser layer (computer / browser / cli / binary / headless) with layered stealth + its own backend DB (Drizzle+mysql2+Prisma+Cloudinary), 30 modes — differentiator vs `vercel-labs/agent-browser`, `browser-use`, `clark-browser`.
291
-
292
- ### 15. Crawling, Cache & Extraction
293
-
294
- - **Crawling:** BFS (`enqueueLinks()`) vs DFS (`forefront:true`); `robots.txt` + `Crawl-delay` honored (`robots-parser` 3.0.1 RFC 9309: `isAllowed`/`getCrawlDelay`/`getSitemaps`; Crawlee `RobotsTxtFile.parse` + `parseUrlsFromSitemaps()`; fetched via `got-scraping`); sitemap discovery (`sitemapper` 4.1.6 — streaming, sitemap-index, TTL 15000–60000 ms); URL normalization strips `utm_*`, `fbclid`, `msclkid`, `ref`, `source`, `medium`, plus `gclid, gclsrc, dclid, gbraid, wbraid, fb_action_*, fb_ref, fb_source, mc_cid, mc_eid, twclid, hsa_* (13 HubSpot), campaign, content, term, spm, from, share_id` (`normalize-url` 9.0.0: `sortQueryParams, removeTrailingSlash, stripWWW, stripHash, removeExplicitPort`; alt `ufo`, `url-normalize`); `EnqueueStrategy` (SameHostname/SameDomain/SameOrigin/All) + globs/regex/exclude; `maxCrawlDepth` via `request.userData`; canonical `link[rel=canonical]` precedence + redirect chain 301/302/307/308; persistent frontiers `microfrontier` + `p-queue` (priority 1–10). Domain concurrency 2–3.
295
- - **Cache:** L1 RAM (<1 ms) · L2 disk · HTTP (`ETag`/`If-None-Match`, 304, s-maxage) · CDN. TTL by content: static 24–72 h (24 h / 48 h stale), semi-static 4–24 h (4 h), dynamic 30 min–4 h (30 min), realtime 30 s–5 min, transactional **0** — auto-detect via headers (`no-store`→0, `max-age ≤60` realtime, `≤3600` dynamic, `≤86400` semi-static, else static; json→dynamic, html→semi-static, asset→static). Invalidation: TTL, versioned keys `url#v{n}` (keep 3), pattern/domain/path regex, event-driven tags. Multi-layer: LRU (max 500, TTL 5 min) → cacache/Keyv (promote to L1 on hit); SWR `ttl 300_000, swr 600_000`. Libs: `lru-cache`, `node-cache`, `quick-lru`, `cache-manager` (multi-store L1+L2), `keyv`, `cacache` (content-addressable SHA-512), `flat-cache` — with stale-while-revalidate. Crawlee request dedup persists to disk (SQLite), survives crashes, resumes.
296
- - **Extraction (structured-first):** JSON-LD `@graph` → Microdata (`microdata-minimal`) → OpenGraph/Twitter (`open-graph-scraper` 6.11.0, `ogie`) → RSS/Atom (`feedsmith` 2.x fastest RSS/Atom/JSON-Feed, `rss-parser` 3.13.0 customFields, `rss-finder` 2.1.5 auto-discovery) → Readability (`@mozilla/readability` 0.6.0: `charThreshold 100, keepClasses false, nbTopCandidates 5`; alt `defuddle`) → CSS. Parser by load: Cheerio (~1 MB, no JS) / jsdom (~50 MB, DOM) / node-html-parser (throughput) / parse5 (spec). Entities: `entities` (~235 M dl) / `html-entities` / `he`. HTML malformed: `htmlparser2` (forgiving) / `tag-soup`. HTML→MD perf (166 KB Wikipedia): mdream (Rust) 0.34 ms · mdream (JS) 3.26 ms · node-html-markdown 14.31 ms; (1 MB): turndown ~500 ms · node-html-markdown ~320 ms · `mdream` (Rust) ~15 ms. Conversion: `turndown` + `turndown-plugin-gfm`, `html-to-text` v10 (`wordWrap:80, tables:true`), sanitize server-side (`sanitize-html`) / browser (`DOMPurify`). Table parsing: `cheerio-tableparser`. Content-type heuristics: `__NEXT_DATA__`, `_next/data`, `__NUXT__`, `window.__INITIAL_STATE__`, `data-reactroot`, `ng-app`, `id="app"`+vue, `___gatsby`, `__remixContext`, `astro-island`; API interception via `page.on('response')` (XHR/fetch JSON, lazy-load scroll).
297
-
298
- ### 16. Modes & Runtime
299
-
300
- | Mode | Needs browser | Notes |
301
- |------|--------------|-------|
302
- | Fetch | no | Cheerio; static pages / APIs |
303
- | Browser | yes | Playwright AgentBrowser (chromium/firefox/webkit); SPAs, interactive |
304
- | Auto (default) | auto | tries fetch, detects render (framework heuristics), falls back |
305
- | Headless | no UI | CI/CD, servers |
306
- | CLI / Binary | no runtime dep | standalone tool / compiled binary |
307
- | Computer | — | binary data streams, storage→compute core |
308
-
309
- **Robot modes (SaddleBot taxonomy):** Binary-runner bot · Automation/API bot · Scraper bot · Bypass bot (captcha/anti-detect) · Headless agent · Internal page/RedLens bot — each persists its output to repos/buckets/DB and triggers from webhooks/cron/commands. Isolation per robot: `runner: github|forgejo|codeberg|gitlab|huggingface`.
310
-
311
- **Operation modes work without AND with their pair** — nothing is gated: computer · library · application · browser · desktop · mobile · extension · cli · binary · headless · physical file · vector file · internal/external file · internal/external dependency · internet/dev-dependencies · visible mode. Same for memory: internal/external/physical/vectorized/library — all work with or without.
312
-
313
- ### 17. Validation, Concurrency & Universal Runtime
314
-
315
- - **Zod v4** (~14× faster, ~26 KB; v3 was 60 KB): `z.strictObject`, `.prefault()`, `z.toJSONSchema()` (→ OpenAPI 3.1 via `zod-openapi.createDocument()`), branded/discriminated unions, `z.interface()`, `z.coerce` for CLI, `.brand<'T'>()`, separation of `z.input`/`z.output`, cross-field refines. Core: `ScrapeOptions` (viewport 320–7680 × 240–4320, `maxRetries` 0–10, timeout 1000–300000 ms, format html|text|json|screenshot, `SafeUrl` http/https), `ScrapedItem`, `ScrapeJob` (UUID), `BatchConfig` (`concurrency` 1–100, `jobs` 1–10_000). Middleware per framework (`zValidator` Hono, `ZodTypeProvider` Fastify).
316
- - **Batch/concurrency:** `p-map` 7.0.4, `p-queue` 9.1.2 (priority, `intervalCap`, per-item `timeout`, `onIdle()`/`pause()`/`resume()`), `p-limit` 7.3.0; `BrowserPool` (`minBrowsers:1`, `maxBrowsers:5`, `maxPagesPerBrowser:10`, `launchTimeout:30000`, `idleTimeout:60000`, `acquire()→release()`); Crawlee `AutoscaledPool` (scale up if CPU<50% & mem<70%, down if >80%/85%; min 1 / max 20, scaleUpInterval 1000, scaleDownInterval 5000); `cockatiel` retry/timeout/circuit-breaker (`byPercentage({threshold:50, duration:30000, halfOpenAfter:10000})`) + bulkhead (`maxPerBulkhead 5, maxTotal 50`) + FallbackChain (primary → cache → archive.org). Adaptive: targetErrorRate 0.1 (reduce ×0.3 / increase ×0.2, window 100, 10 s), latency-target p50/p95/p99 ±30%. Defaults: concurrency **10**, `maxAttempts` **3**, exponential backoff.
317
- - **Universal runtime (WinterTC / ECMA-429):** `fetch`, `Request/Response`, `URL`, `URLPattern`, `Headers`, `crypto`, `ReadableStream`, `WritableStream`, `TransformStream`, `TextEncoder/Decoder`, `structuredClone`, `AbortController`, `WebSocket`, `setTimeout/setInterval`, `queueMicrotask`, `atob/btoa`, `performance.now()`. Avoid `fs/process/Buffer/path/child_process/require/__dirname` in the core (use `import.meta.url`, `node:`-prefixed imports); isolate in `src/adapters/{node,browser,deno,cloudflare}.ts`. Runtime detection order: `globalThis.Deno → globalThis.Bun → process.versions.node → window/document`. Build: `tsdown` (`platform:'neutral', format:['esm']`, `exe:true` SEA, auto-exports) / `tsup` (external `/^node:/`) / `unbuild`; polyfills via `unenv`; validate with `npx publint`, `npx @arethetypeswrong/cli`, `madge --circular`. 2026 "do not polyfill" list: node-fetch, cross-fetch, isomorphic-fetch, undici, buffer, path-browserify, process, stream-browserify. Distribution: `bun build --compile` (8 targets, `--bytecode`, embed `with {type:'file'}`/`sqlite`), Node SEA (`postject`), `@vercel/ncc`, `deno compile`.
318
- - **Error taxonomy (typed hierarchy with HTTP statuses):** `WebScrapeError` base → `ValidationError` 400, `TimeoutError` 504, `BlockedError` 403, `RateLimitError` 429, `ProxyError` 502, `ParseError` 422, `AuthError` 401, `NetworkError` 503; each carries `code/statusCode/isRetryable/details`; plus `RetryRequestError` (rate-limit delay), `SessionError` (rotate proxy/UA), `CriticalError`. Recovery: `WAIT_AND_RETRY`, `ROTATE_PROXY`, `REDUCE_CONCURRENCY`, `REVIEW_ROBOTS_TXT`, `ROTATE_USER_AGENT`, `ADD_HUMAN_DELAY`, `STOP_CRAWLING`. Events via `TypedEmitter` (`emittery` 2.0.0: AbortSignal, async-iteration, `Symbol.dispose`; eventemitter3 2–5× faster; mitt ~200 B): `request:start|retry|error|response`, `cache:hit|miss`, `session:rotate`, `proxy:rotate|error`, `browser:crash`, `crawl:discover|complete`. Error metadata: `severity` low/medium/high/critical + `Error.captureStackTrace` + `cause` chaining.
319
- - **Error codes (tree-shakable const enum):** Network 1xxx (E1001 timeout, E1002 conn-refused, E1003 DNS, E1004 TLS) · HTTP 2xxx (E2001 rate-limited, E2002 403, E2003 404, E2004 500, E2005 503) · Browser 3xxx (launch/crash/timeout/navigation) · Scraping 4xxx (E4001 selector, E4002 parse, E4003 captcha, E4004 bot) · Session 5xxx (expired/blocked/cookies) · Config 6xxx (invalid/missing). `ScraperError` base with `{code, cause?, retryable?, metadata?}`; `extends Error` needs `Object.setPrototypeOf(this, Class.prototype)` for `instanceof`. Default policy: maxRetries 3, base 1000, factor 2, cap 30 s; unknown errors retry once; non-retryable: 404, BOT, CAPTCHA, CONFIG.
320
-
321
- ---
322
-
323
- ## Productization
324
-
325
- 18. **Distribution Surfaces** — One package, repackaged per target; nothing runs locally.
326
-
327
- | Target | Form |
328
- |--------|------|
329
- | n8n | first-class node / its own (automation engine) |
330
- | Browser | CRX extension for any Chromium/Gecko browser — capture runs in-page; movement capture, session replay and captcha bypass work from the extension UI |
331
- | Mobile | Android / iOS native apps |
332
- | Desktop | Tauri (one codebase, three native builds — Windows/macOS/Linux) |
333
-
334
- 19. **Third-Party Application & Robot Identity** — registered on each platform as a developer-owned third-party app (user owns client ID/secret), never a hosted service.
335
-
336
- | Platform | Registration | Robot identity | Runs on |
337
- |----------|--------------|----------------|---------|
338
- | GitHub | GitHub App / OAuth App (`contents/pull-requests/issues/actions` R-W, metadata R, webhooks manage) | bot via `workflow_dispatch` | Actions / Codespaces |
339
- | GitLab | OAuth App + bot user | project bot via CI | GitLab CI |
340
- | Forgejo | OAuth2 (3rd-party) | bot via Actions | Forgejo Actions |
341
- | Gitea | OAuth2 (3rd-party) | bot via Actions | Gitea Actions |
342
- | Hugging Face | OAuth + Spaces | agent in a Space | HF |
343
- | Bitbucket | OAuth Consumer (3rd-party app) | pipeline bot | Bitbucket Pipelines |
344
- | SourceHut | OAuth Application | build bot | builds.sr.ht |
345
- | Discord / Telegram / Reddit / Slack / Mastodon / Matrix / Bluesky | Bot App / Bot API / 3rd-party app | interactive bot; app-only robot | gateway / webhooks / API |
346
-
347
- Where a platform has no formal app portal (Telegram, Matrix), the robot is still a developer-owned credentialed account seeded by the user. Registration notes: Reddit app portal `reddit.com/prefs/apps` (web/installed/script + app-only OAuth); Telegram via BotFather; Mastodon/Matrix/Bluesky = per-instance client apps.
348
-
349
- 20. **Multi-Platform Bots & Automation** — `SaddleBot` unified: `start()`, `stop()`, `executeCommand(cmd)`, `handleWebhook(event)`, `scheduleTask(task)`, `getStatus()`. Adapters `PlatformAdapter`: `authenticate`, `listRepos`, `createWebhook`, `executeBot` — Forgejo/Gitea reuse the GitHub adapter with a custom `baseUrl`. Commands: `capture`, `scrape`, `review`, `deploy`, `memory`, `test`, `release`, `webhook`, `schedule`, `publish`, `artifact`, `status`, `npm publish` (GitHub-only). Adapter specifics: GitHub `createIssue`, `createPR(repo,title,body,branch)`, `addComment`, `executeWorkflow(repo,workflow)`, `uploadReleaseAsset` (token scopes `repo`+`workflow`+`read:org`); GitLab `listProjects`, `createMergeRequest(sourceBranch,targetBranch)`, `triggerPipeline(projectId,ref,variables)`, `uploadFile` (scope `api`); Discord `sendMessage`, `createWebhook`, `executeWebhook(webhookId,webhookToken)`, `addReaction`, `createThread`; Forgejo paths `write:repository`+`write:issue`+`write:webhook`. Webhook events: GitHub `push, pull_request, issues, issue_comment, release, deployment` with `"secret":"${WEBHOOK_SECRET}"`; GitLab trigger/push/merge_request/issue/tag_push. **Flow:** command on Discord → parse → adapter → run on forge → store in memory → report back.
350
-
351
- 21. **AI Integration & Models**
352
-
353
- - Convert HTML → **Markdown before the LLM** (60–80% token reduction). Token/1 KB: HTML ~300–400, Markdown ~80–120, text ~60–80 (cleaned HTML ~200–250, JSON ~150–200). `estimateTokens ≈ chars/4` (~70% accurate) — model-aware helper `estimateTokens(text, model)` / `fitsInContext(text, ctx, model)` / `tokenCost(text, model, price)` with char/token ratios (gpt-4o 3.5, claude 3.2, gemini 3.5). Tokenizers: `js-tiktoken` (~5 MB, o200k_base), `gpt-tokenizer` (~1 MB), `bpe-lite` (~2 MB, multi-model, Gemini 100% accurate, Claude p50k_base ±10–30%).
354
- - **RAG pipeline:** Fetch → Extract → Markdown → Chunk (400–512 tokens, overlap 10–20%, SHA-256 dedupe, hierarchical `chunk-{i}-{j}` with heading path + parentChunkId; separators `['\n\n','\n','. ','! ','? ',', ',' ']`, ~1.3 words/token; metadata frontmatter `source/title/description/scraped_at/content_hash/language`; API `chunkMarkdown({maxTokens:512, overlapTokens:50, preserveCodeBlocks, includeHeadingPath})`, `splitByHeaders()`, `formatChunksForRAG()`) → Embed → Store (Pinecone `{id,values,metadata}` / Weaviate `{class:'DocumentChunk',id,vector,properties}` / Qdrant `{id,vector,payload}`; metadata `headingPath, contentHash, parentChunkId, sourceUrl, tokenCount, expiresAt, sourceDomain, contentType text|code|table|list, language, embeddingModel, embeddingDimensions`). Chunk id = `sha256(hex).slice(0,8)-{position}` (`documentId = contentHash.slice(0,16)`); near-duplicate threshold 0.95; self-healing selectors (strip class, `[id*=x]`, `[class$="x-*"]`, `:nth-child`, `[aria-label]`) with Cheerio fallback.
355
- - Structured extraction: `response_format: json_object`, `temperature: 0`, confidence = used / total. Embeddings: `POST https://api.openai.com/v1/embeddings` `text-embedding-3-small`; Anthropic count via `POST https://api.anthropic.com/v1/messages` (`anthropic-version: 2023-06-01`, `usage.input_tokens`). External context windows: GPT-4o 128K (sweet 8–32K), Claude 3.5 Sonnet 200K (~180K), Gemini 1.5 Pro 2M (~1.8M), Llama 3.1 405B 128K, Mistral Large 128K.
356
- - **llms.txt:** `# Title`, `> desc`, `## sections` (≤2 levels, desc ≤100 chars, absolute HTTPS URLs) ≤100 atomic links — consumed by AI agents directly; `llms-full.txt` = concatenated content variant; adopters: Vercel, Anthropic, OpenAI, Stripe, Supabase, 840+ sites.
357
- - **Free inference:** `@huggingface/inference` `InferenceClient` (textGeneration, featureExtraction) free for models <10 B params; ModelScope OpenAI-compatible at `https://api-inference.modelscope.cn/v1` (e.g. `Qwen/Qwen3.5-27B`).
358
-
359
- | Model (free catalog, 26 available) | Source | Context | Modality |
360
- |-------|--------|---------|----------|
361
- | deepseek-v4-flash-free | Zen | 1,048,576 | text |
362
- | longcat-2.0-free | Zen | 1,048,756 | text |
363
- | nemotron-3-ultra-free | Zen | 1,000,000 | text |
364
- | mimo-v2.5-free | Zen | 1,050,000 | text+audio+image+video |
365
- | tencent/hy3:free | OpenRouter | 262,144 | text |
366
- | stepfun/step-3.7-flash:free | OpenRouter | 262,144 | text+image |
367
- | openai/gpt-oss-20b:free | OpenRouter | 131,072 | text |
368
-
369
- Sources: `api.kilo.ai`, `opencode.ai/zen`, `openrouter.ai`. Count with `js-tiktoken` / `gpt-tokenizer`.
370
-
371
- 22. **Packaging & Publishing** — `@wenathlan/saddle` as **lib + CLI** (`saddle`); install `npm install @wenathlan/saddle` (global for CLI). Package layout: `lib/index.js` + `bin/saddle.js` (`node:util parseArgs{command, platform, token, verbose}`, default `help`), exports map subpaths `./browser, ./bot, ./captcha, ./memory-engine, ./deploy` (import/require dual) + `./index.cjs`. Scripts: `"build":"tsc"`, `"test":"vitest run"`, `"lint":"biome check ."`, `"typecheck":"tsc --noEmit"`, `"prepublishOnly":"npm run build && npm test"`, `"prepare":"husky"`. Version: semver `npm version patch|minor|major` + `git push --follow-tags`. Library API: `import { SaddleRobot } from '@wenathlan/saddle'; await robot.start(); await robot.executeCommand(cmd)`. `npm publish --access public` → auto-mirror jsDelivr/UNPKG/esm.sh.
372
-
373
- | Registry | What |
374
- |----------|------|
375
- | Node registry | lib + CLI |
376
- | GitHub | repo + Packages + container image |
377
- | Maven | `.jar` via GitHub Packages |
378
- | NuGet | `.nupkg` via GitHub Packages |
379
- | RubyGems | gem push |
380
- | PyPI | wheel via trusted publishing |
381
- | GHCR | docker push |
382
- | HF / Kaggle | bucket/dataset |
383
-
384
- Every package is auto-mirrored to jsDelivr/UNPKG/esm.sh (CDN executable from anywhere). OCI registries (GitHub/GitLab Packages, ACR, Docker Hub) double as **universal content-addressed storage** via `oras push` (Chainloop proofs). Trusted publishing: npm/NuGet via OIDC token exchange; Azure via `@azure/storage-blob` + Entra ID/OIDC federated identity.
385
-
386
- 23. **Deploy & Secure Execution** — All cross-site comms over HTTPS with cert validation.
387
-
388
- - **Multiple sites** (Netlify/Vercel); each site opens containers; each container writes back through its **own internal API** (Hono) to its **own DB** (Drizzle/Prisma), then mirrored → repo/Terabox/temp container (backup, no loss). Edge inference runs **not only on the site but via npm, GitHub and Maven packages** — the same bytes run wherever pulled. Free tiers: Vercel ≈1 M invocations/mo; Netlify ≈125 K function calls/mo; Cloudflare Workers 100 K req/day; AWS Lambda ≤15 min timeout (postgres 16 + redis 7 via `docker-compose`, `node:22-alpine` multi-stage + HEALTHCHECK).
389
- - **Deploy-at-boot DB (idempotent):** `GET /api/init` (`runtime="nodejs"`, `dynamic="force-dynamic"`) runs `CREATE TABLE IF NOT EXISTS` (or `drizzle-kit push`) with `middleware.ts`/`instrumentation.ts` (Next ≥14.2) firing it at boot via `fetch(process.env.SELF_URL + "/api/init")` + `x-init-secret`; runtime `nodejs` (edge has no `pg`/`fs`). Build variants: `"build": "prisma generate && prisma migrate deploy && next build"` + `"db:push": "drizzle-kit push"`.
390
- - **Secure ladder (by risk):** V8 Isolates (`@edge-runtime/vm`, `isolated-vm`, <5 ms) → WASM (Rust/Go/C++/Pyodide — PyPI native C/C++ extensions excluded) → MicroVMs (Firecracker/Kata/gVisor, ~300 ms boot) → **`vm2` banned** (deprecated, RCE CVEs). Node is the orchestration "brain"; single-threaded → heavy compute offloaded. Python-in-Node also via bridges: `pythonia`, `pymport`, `node-calls-python`, `nodepyx` (embed CPython). Docker hardening: `--network=none`, `--cap-drop=ALL`, `--security-opt=no-new-privileges`, `--read-only`, `--pids-limit=512`, `--runtime=runsc`.
391
- - **Auth:** GitHub Apps > PATs (granular `read:packages`/`write:packages`); **OIDC Federated Identity** for Azure/Blob; **Trusted Publishing** for npm/NuGet (short-lived tokens; NuGet limits on self-hosted runners). **Skew protection**: `drizzle-kit push` in the build step.
392
- - **Serverless constraints:** Vercel Node max 300 s / Edge 50 ms; Netlify Functions 10 s sync / 15 min async; Edge 1–5 ms cold (Wasm); memory caps are small on edge → heavy work stays in runners, not functions. `child_process` is **blocked on Netlify** — route subprocess workloads to WASM/Pyodide/isolates or a separate executor (`microservice split`: Python as its own function + HTTP call). Netlify limits: 1,024 MB fn memory / 512 MB edge. Vercel runs Node/Python/Go/Ruby; cron triggers are **not real-time** (50–60 min delay) — use `node-cron`/`node-schedule`/Scheduled Functions (Netlify `@hourly`) or Supercronic where timeliness matters. Runtime create-at-deploy: Vercel Blob / Netlify `@netlify/blobs` / `prisma migrate deploy` / `drizzle-kit push`; `vercel env pull && vercel build` / `netlify build --context production` keeps local == prod.
393
- - **Isolation ladder (by risk):** `node:vm` / V8 Isolates (`isolated-vm`, `@edge-runtime/vm`, <5 ms, <5 MB) → Docker containers (full apps) → MicroVMs (Firecracker/Kata/gVisor, ~300 ms boot) → WebAssembly (Pyodide = CPython→WASM, WasmEdge CNCF, Runno, Edge.js ~40 ms, BoxLang). **Pyright is NOT an executor** — it is a static type-checker; Python-in-Node = Pyodide/subprocess/MicroVM. `vm2` **banned** (deprecated, RCE CVEs incl. CVE-2025-68613/CVE-2026-1470).
394
-
395
- 24. **CDN / SCDN & Zero-Install** — Saddle never runs `npm install`. Every package is pulled by URL at execution time: `esm.sh`, `jsDelivr` (`+esm`), `UNPKG`, `esm.run`, `jspm`, `cdnjs`, npm registry. Serve modules via CDN and import inline with **SRI** (`integrity="sha384-…"`).
396
-
397
- ```
398
- POST /v1/scrape GET /v1/scrape/:taskId
399
- POST /v1/scrape/async POST /v1/batch
400
- POST /v1/crawl GET /v1/crawl/:crawlId
401
- GET /health (SSE via text/event-stream, 30 s keepalive)
402
- ```
403
-
404
- SCDN pipeline: capture → `PUT` upload (Bearer token, `Cache-Control`) → edge cache → workers fetch nearest edge → store URLs in repo. Providers: Cloudflare Workers (300+ cities), Cloudflare R2 (free egress), CloudFront (400+ cities, pay-per-use), Bun CDN, Deno Deploy, Vercel Edge Config, Netlify Edge. Config: endpoint/token/bucketId/region?/ttlSeconds; perf: upload 50–200 ms vs direct 200–2000 ms, download 10–50 ms, cache hit 5–20 ms; safeUpload maxRetries 3, backoff `1000 * attempt` ms; TTL example: session JSON 3600, screenshot PNG 86400.
405
-
406
- **Zero-install execution — three production patterns:** ESM `import 'https://esm.sh/<pkg>@<ver>'` in `<script type="module">`; dynamic `import('https://esm.sh/<pkg>')`; `<script type="importmap">`; plus the Node one-liner `node --input-type=module -e "import x from 'https://esm.sh/<pkg>'"`. SRI hashes (`integrity="sha384-…"`) pin supply-chain for every module. `esm.run`, `jspm` (`ga.jspm.io`), `cdnjs`, `esm.unpkg.com` (ESM+bundling) complete the catalog (see §58 CDN list doc). Live pins: `https://esm.sh/@opencode-ai/sdk@1.18.4`, `https://esm.sh/@octokit/rest@20.0.2`, COOP/COEP via `coi-serviceworker@0.1.7` (GitHub Pages cannot send those headers → breaks SharedArrayBuffer). Thin-client protocol: 256-byte hex preview + **SHA-256 in a Web Worker** before upload → streaming `CHUNK=0x8000` base64 via GitHub Contents API (`createOrUpdateFileContents`) with a fine-grained PAT (`Contents:write` + `Actions:write`) kept only in `sessionStorage` → poll `GET /actions/runs?event=workflow_dispatch&per_page=20` every 3 s → artifact unzipped in-browser via `DecompressionStream('gzip')` (browser stays <5 MB RAM). Five browser-embedding strategies: SDK Remote · WebContainers · ServiceWorker+Hono+OPFS mock · WASM Go (`GOOS=js`) · GitHub-as-storage+Actions.
407
-
408
- 25. **Architecture & Conventions**
409
-
410
- ```
411
- saddle/
412
- ├── docs/ # planning + documentation
413
- │ ├── plans/ # numbered goals (001..0NN, flat; index: 00.index ↔ 46.scdnintegration…)
414
- │ ├── talks/ # decision transcripts
415
- │ └── logs/ # JSON movement logs
416
- ├── tests/ # {examples/: fixtures (hcaptchatest.html), output/, scripts/}
417
- ├── web/ # production site (Vercel/Netlify open server)
418
- │ ├── index.js # capture UI / server
419
- │ ├── server.js # API routes (Hono + SSE, socket.io)
420
- │ ├── db.js # drizzle + mysql2 + prisma loader
421
- │ ├── storage.js # cloudinary upload
422
- │ ├── capture.js # browser movement capture (virtual mouse, arrow)
423
- │ └── *.html # capture UI + test pages (saddle1–7)
424
- ├── saddle-robot/ # engine: browser.js, bot.js, captcha.js, memory-engine.js, deploy.js, adapters/{github,gitlab,forgejo,gitea,discord}.js
425
- ├── 3d/ # standalone nodes and CLI
426
- ├── bin/ # CLI entry points (bin/saddle.js)
427
- └── (root files) # library entry, configs
428
- ```
429
-
430
- **Library modules:** saddleUrl · fetch · browser · extract · serialize · errors · retry · proxy · cache · rate-limiter · crawler · batch · pool · agent · tokens · chunking · llms-txt · server · cli · memory-engine · captcha · bot · deploy · storage · adapters.
431
-
432
- **Hard conventions:** no `src/` (root-based; **`crc: clean root code`**; the `web/` folder *is* production) · no Vercel/Netlify **Functions** (open Node server; `prisma`/`drizzle`/`mysql2`/`socket`) · no localhost (host parametrized, **ports randomized then locked**) · lowercase files, no underscore, no hyphenals · English docs, JSDoc · error catcher embedded in every script · ≤20 related logics per file · V8 flat manifest: Numeric file names (Title Case with spaces, no nesting; ~50 flat files of 100 total, e.g. `026 API Init Database Trigger.ts`) — `ls` is the documentation, alphabetical order is the diagram.
433
-
434
- 26. **API Reference** — server framework: Hono (edge, 14 KB) for Workers · Fastify/Elysia → Bun/Node · Express legacy. Always HTTPS + auth (API key/JWT), per-user rate limit, input validation, **SSRF protection** (block internal networks), CORS, `request_id` audit. Respect `robots.txt`. Streaming: SSE / WebSocket / NDJSON. Benchmarks (req/s): Elysia ~184K (Bun) · Fastify 42–114K · Hono 45–78K · Express 8–21K.
435
-
436
- **Public library API:** `saddleUrl(url, {mode, timeout, scroll, format: 'markdown'|'json'|'xml'|'text'|'redis', retries, proxy, cache, extractLinks/Images/Tables, antiDetection, tokenCount})` → `{content, metadata}` · `scrapeUrl/scrapeHtml/scrapeWithBrowser` · `extractContent(html, options?)` · `serializeResult(result, {format})` / `serializeHtml(html)` · `formatForAgent(result, {model, maxChunkSize 4000, includeSummary/KeyPoints/RelevantUrls/Metadata})` → `{summary, keyPoints, relevantUrls, chunks[], tokenCount}` · `batchScrape({urls, concurrency, onProgress})` → `(completed, total)` · `crawl(url, {maxDepth, maxPages, sameDomain})` → `{results, stats}` · `chunkMarkdown(content, {maxTokens})` → `{content, headingPath, tokenCount}` · `createServer({port})`. AgentBrowser methods: `navigate({waitUntil:'networkidle'})`, `click`, `type`, `screenshot({fullPage})`, `html()/text()/title()/evaluate()`, `scrollToBottom({step:500, delay:100})`, `executeCommands([{action:'goto', args:{url}},…])`.
437
-
438
- ```
439
- POST /v1/scrape # sync, fields: useBrowser, format, waitFor, timeout, proxy; → timing.duration_ms
440
- POST /v1/scrape/async # returns task id
441
- GET /v1/scrape/:taskId # poll result
442
- POST /v1/batch # up to 10k jobs, concurrency 10
443
- POST /v1/crawl # GET /v1/crawl/:crawlId
444
- GET /health # SSE, 30s keepalive; Nginx proxy_buffering off
445
- ```
446
-
447
- Rate limiting: global 1000/min · per-endpoint `/v1/scrape` 10/min · per-user key · **per-domain token bucket** (rate-limiter module); algorithms Token Bucket / Sliding Window Log / Sliding Window Counter / Fixed Window / Leaky Bucket; engines: `express-rate-limit` 8.5.x, `@fastify/rate-limit`, `hono-rate-limiter` (+`@hono-rate-limiter/redis`, `standardHeaders:'draft-7'`), universal-rate-limit (`draft-7` headers), `bottleneck` 2.19.5 (Redis Cluster, minTime/maxConcurrent), `rate-limiter-flexible` (Memory/Redis, `blockDuration`, `execEvenlyMinDelayMs`), `limiter` (Redis), Upstash REST sliding-window via zset (`zremrangebyscore/zadd/zcard/expire`, env `UPSTASH_REDIS_REST_URL/TOKEN`). Error shape `{error: {code, message, retry_after, request_id}}`. SSE 30 s keepalive (Cloudflare free idle ~100 s), browsers cap ~6 SSE/origin; skip streaming under 50 KB.
448
-
449
- 27. **Examples / Cases**
450
-
451
- 1. **Human Operator (voice+vision → EMS):** VLM (Claude API) → egocentric camera + open-ended voice trigger → Flask gateway (`utils/receiver.py`) → Arduino relays → EMS (D2→wrist_left, D4→wrist_right, D3→thumb, D5→index, D6→middle, D7→ring, D8→pinky). MIT Hard Mode 2026 winner (Learn Track, 6–8 Mar 2026, 48 h, 6 students: He, Neall, Danry, Kaijzer, Wu, Lewis). Repo `danielkaijzer/Human-Operator`; lineage: PossessedHand (CHI 2011) → Affordance++ (CHI 2015) → openEMSstim (2016) → DextrEMS (2021) → SplitBody (CHI 2024, +35% multitask) → Generative Muscle Stimulation (CHI 2026 Best Paper) → Hand by Hand/FlightAxis (IJCAI 2025); ~150 HCI publications in the field.
452
- 2. **Infinite HD / VRAM (FUSE):** bucket → VHD via FUSE; `hf-mount start bucket <user>/<bucket> /mnt/...` / `huggingface/hf-csi-driver` (K8s CSI) / `nisten/huggingface-filesystem` (stream-sync, no local disk); `rclone mount --vfs-cache-mode full`; `cf-vfs` (R2 + Durable Objects), `tigrisfs` (mount R2 as `/mnt/r2`), `@cyclic.sh/s3fs` (drop-in `fs`); mounts → tmpfs 2 G. Mount S3 as FS in Node (`fuse-native` + `@aws-sdk/client-s3`, Range reads). ORM sharding `Bun.hash(k)%n` (40×3 GB = 120 GB; 400 = 1.2 TB). Free: Terabox 1 TB, R2 10 GB (5 GB file), HF, Telegram (2 GB/4 GB premium), Discord (8 MB chunks/∞). Portable runtime: Node 20 portable + Electron, `pkg` single .exe presented as drive Z:. VRAM→swap is legitimate (nbd-vram), bucket→VRAM is not (256-bit bus, hundreds GB/s, no S3→VRAM protocol; S3-as-swap → BSOD/kernel panic).
453
- 3. **Repo as processor + WASM in browser:** `@octokit/rest` + `isomorphic-git` in-memory clone → process → push; `WebAssembly.instantiateStreaming` + `go.run`. Cross-repo trigger `repository_dispatch {event_type:"bridge_event"}`; Site A → dispatch → Action commits `docs/queue.json` → Pages rebuild → Site B GETs it.
454
- 4. **Sci-Fi (body↔mind):** output EMS/e-Taste (taste via glucose/citric/NaCl/Mg → Wi-Fi actuator, Ohio State) / OVR ION (9-smell cartridge, Unity API) / GVS (0–2 mA; hand redirection +45–55%) / ThermoReal/Peltier (20°→40°C in 1 s); input OpenBCI/brain2qwerty (v2 MEG→text 61% avg / 78% best word accuracy, ~22,000 sentences / 9 volunteers / 10 h MEG each, repo `facebookresearch/brain2qwerty`, dataset `bcbl190626/SpanishBCBL`, CC BY-NC 4.0) / emg2qwerty (sEMG) / Neural Band (meta, sEMG wristband); Tiny AI: llama.cpp (70B Q4_K_M on CPU), BitNet (1-bit, {-1,0,1} weights; 2B trained on 4T tokens runs 100B-class on CPU 5–7 tok/s, 82% less energy), web-llm (WebGPU, no server), llamafile (Mozilla-Ocho single executable); storage: Project Silica (quartz, 10,000-yr life, CD-size = 4 TB), DNA (`microsoft/TrellisBMA`, 200 MB, 1 EB/mm³ theoretical), 5D memory (360 TB/disc, 13.8 B-yr stability), Cerabyte ceramic (1000+ yr, no power), IPFS/Filecoin.
455
- 5. **Minimal recipe:** `[Bucket FUSE] → [unionfs] → [llama.cpp/BitNet]` — each piece independent.
456
-
457
- 28. **Competition & Differentiators** — 7 competitors (Crawlee, Playwright, Puppeteer, Cheerio, Scrapy, Firecrawl, Browserless). **Saddle leads on all-in-one** toolchain (scrape + crawl + batch + serialize → markdown/llms.txt + server + RAG chunking), cross-runtime Node **and** Bun (Node ≥26.2.0 / Bun ≥1.4.0), token estimation, heading-aware chunking, `llms-txt`, Redis `JSON.SET`, AI SDK with 20+ providers, no cloud dependency. Competitor metrics: Crawlee 23.7k★/134 releases · Playwright 90.5k★/~471k dependents · Puppeteer 94.5k★/~575k · Cheerio 30.4k★/~1.8 M dependents · Scrapy 62.1k★/300+ releases/15+ yrs · Firecrawl 130k★ (highest, AGPL-3.0) · Browserless 13.3k★/655 releases (SSPL-1.0). Notes: Crawlee ships multi-package + `npx crawlee create`; Scrapy ecosystem = scrapyrt (REST) + scrapyd (deployment) + scrapy-playwright; all four (Playwright, Firecrawl, Browserless, Puppeteer) ship MCP servers (`@playwright/mcp`, `firecrawl-mcp`, `chrome-devtools-mcp`). **Gaps (P0→P3, see §29):** anti-detection not integrated, no persistent queue, no Dockerfile yet, no MCP server.
458
-
459
- 29. **Status, Roadmap & What's Missing**
460
-
461
- - **Status:** planning + research complete; implementation gated on user go-ahead. Compute backends next: computational-memory engine, storage backends, VM packaging (GitHub + npm → jsDelivr).
462
- - **P0 (blocks prod):** anti-detection (integrate stealth plugin — `playwright-extra` is already an optional dep, never imported), persistent queue (`SqliteQueue` over `better-sqlite3`, schema `CREATE TABLE requests (url TEXT PRIMARY KEY, depth INT, status TEXT, created_at INT, processed_at INT)`, option `CrawlOptions.persist`, in-memory kept as fallback), Docker (`Dockerfile.saddle` + `docker-compose.yml`) — 1–5 d each.
463
- - **P1:** MCP server (`@modelcontextprotocol/sdk`, tools `scrape/crawl/batch/extract/serialize`, CLI subcommand `mcp`) · session persistence (`CookieJar`/`ScrapingSession` → `save(path)/load(path)`) · schema extraction (`extractWithSchema(url, zodSchema)`, endpoint `/scrape/schema`, file `schema-extract.ts`).
464
- - **P2:** PDF (`page.pdf()`) · token prices configurable (`setModelPrices(prices)`; 2024 hardcoded: gpt-4o 0.0025/0.01, gpt-4o-mini 0.00015/0.0006, gpt-4-turbo 0.01/0.03, claude-3-5-sonnet 0.003/0.015, claude-3-haiku 0.00025/0.00125, gemini-1.5-pro 0.00125/0.005, gemini-1.5-flash 0.000075/0.0003) · webhooks (`webhook?: {url, events[]}`; POST on crawl-started/batch-completed/error) · video extraction (metadata + transcript only, never download).
465
- - **P3:** mobile emulation (`device?: string` → `playwright.devices[device]`) · tracing (`context.tracing.start()/stop()`) · adaptive rendering cache (framework detection + API calls, per-domain).
466
- - **Technical debt:** 30+ hardcoded config defaults (timeout 30000, scroll delay 300, max scrolls 50, viewport 1280×720, retries 3/1000 ms, cache TTL 300000, branch…), 7 hardcoded 2024 model prices (above), hardcoded paths (pythonPath/windowSize/doomFramesDir), static User-Agent, `host: 0.0.0.0` (default to `127.0.0.1`) + `--disable-web-security` (security risk), `CORS '*'` in dev-server, version in 4 files, empty Dependabot config, dead optional deps (`playwright-extra`, `puppeteer-extra-plugin-stealth`), unused stealth flag, ~25 packages to remove (react, sharp, hls.js, ink, blessed, ora, figlet, marked…), no try-catch around storage ops.
467
-
468
- **Legal/ToS cliff:** global file cap (<5 GB/repo, GitHub 50 MiB warning / 100 MB CLI, 5 GB/repo cap — "not allowed as pure serverless, but valid for processing the repo's own binaries"; farm sharding with throwaway accounts = ToS violation → legit: Turso or R2 @ $0.015/GB, self-hosted Forgejo + MinIO), HuggingFace for AI only (free storage = public/community repos only; private billed); bucket-as-VRAM impossible (legit infinite-HD stack = FUSE + rclone + R2/Storj/Kaggle/self-hosted Forgejo+MinIO). Keep VRAM models in buckets, run locally quantized — never dump movies in repos.
469
-
470
- 30. **Scripts & CLI**
471
-
472
- ``` bash
473
- npm run test # vitest
474
- npm run lint # biome check
475
- npm run typecheck # tsc --noEmit
476
- npm run build # tsdown / compile
477
- ```
478
-
479
- ``` bash
480
- saddle --help # usage
481
- saddle <url> -f json --pretty # scrape URL, CLI flags -f/--format, --pretty, --mode browser --scroll, --agent --output result.json
482
- saddle capture --url <url> # Agent Browser capture/replay → docs/logs/<session>.json
483
- saddle bot --platform github --token $SBOT_TOKEN # run SaddleBot on a forge
484
- saddle memory --load repo://owner/repo/path/file.json # load storage → RAM buffer
485
- saddle deploy --target netlify # CLI generates platform artifacts + CI/CD for multi-registry publish
486
- saddle mcp # MCP server (SaddleBot tools)
487
- ```
488
-
489
- 31. **License** — MIT