@wenathlan/saddle 1.8.2 → 1.8.5

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 (257) hide show
  1. package/README.md +9 -9
  2. package/browser/playwright.js +22 -0
  3. package/docs/.gitkeep +0 -0
  4. package/docs/gapmatrix.md +3 -3
  5. package/docs/libraryapi.md +1 -0
  6. package/docs/logs/.gitkeep +0 -0
  7. package/docs/packageaudit185.md +23 -0
  8. package/docs/plans/00.index.md +50 -0
  9. package/docs/plans/01.architecture.md +86 -0
  10. package/docs/plans/02.research.computer.use.md +58 -0
  11. package/docs/plans/03.research.captcha.bypass.md +68 -0
  12. package/docs/plans/04.research.sandbox.ai.md +52 -0
  13. package/docs/plans/05.capture.platform.md +57 -0
  14. package/docs/plans/06.dependencies.md +97 -0
  15. package/docs/plans/07.captcha.test.page.md +41 -0
  16. package/docs/plans/08.production.infra.md +70 -0
  17. package/docs/plans/09.database.schema.md +121 -0
  18. package/docs/plans/10.cloudinary.storage.md +57 -0
  19. package/docs/plans/11.movement.logs.json.md +72 -0
  20. package/docs/plans/12.research.atlas.agent.browser.md +79 -0
  21. package/docs/plans/13.research.anti.detection.md +898 -0
  22. package/docs/plans/14.research.proxy.md +1495 -0
  23. package/docs/plans/15.research.retry.rate.limit.md +1958 -0
  24. package/docs/plans/16.research.crawling.md +1417 -0
  25. package/docs/plans/17.research.caching.md +1610 -0
  26. package/docs/plans/18.research.content.extraction.md +1952 -0
  27. package/docs/plans/19.research.errors.events.md +1523 -0
  28. package/docs/plans/20.research.zod.validation.md +1350 -0
  29. package/docs/plans/21.research.batch.concurrency.md +1888 -0
  30. package/docs/plans/22.research.universal.runtime.md +944 -0
  31. package/docs/plans/23.research.ai.integration.md +1465 -0
  32. package/docs/plans/24.research.memory.persistence.md +1979 -0
  33. package/docs/plans/25.research.server.api.md +342 -0
  34. package/docs/plans/26.research.compilation.md +249 -0
  35. package/docs/plans/27.research.html.parsing.md +251 -0
  36. package/docs/plans/28.action.plan.md +50 -0
  37. package/docs/plans/29.api.reference.md +174 -0
  38. package/docs/plans/30.architecture.plan.md +94 -0
  39. package/docs/plans/31.auditoria.dados.md +163 -0
  40. package/docs/plans/32.bots.automacao.computacional.md +214 -0
  41. package/docs/plans/33.bots.codigo.revisao.md +220 -0
  42. package/docs/plans/34.bots.seguranca.cicd.md +366 -0
  43. package/docs/plans/35.comparativo.concorrencia.md +464 -0
  44. package/docs/plans/36.computational.memory.md +340 -0
  45. package/docs/plans/37.deploystrategy.md +394 -0
  46. package/docs/plans/38.flow.md +155 -0
  47. package/docs/plans/39.multi.platform.bot.md +252 -0
  48. package/docs/plans/40.npm.publish.md +250 -0
  49. package/docs/plans/41.o.que.falta.md +407 -0
  50. package/docs/plans/42.pesquisa.concorrencia.md +721 -0
  51. package/docs/plans/43.plan.universal.architecture.md +496 -0
  52. package/docs/plans/44.reference.md +100 -0
  53. package/docs/plans/45.robotarchitecture.md +237 -0
  54. package/docs/plans/46.scdnintegration.md +284 -0
  55. package/docs/plans/47.multiforge.readme.md +129 -0
  56. package/docs/plans/48.theory.v4.repo.os.md +152 -0
  57. package/docs/plans/49.third.party.infra.md +12 -0
  58. package/docs/plans/50.file.as.compute.md +39 -0
  59. package/docs/plans/51.architecture.virtual.processor.md +80 -0
  60. package/docs/plans/52.manifesto.v8.md +11 -0
  61. package/docs/plans/58.cdn.list.md +23 -0
  62. package/docs/plans/59.sql.frameworks.md +33 -0
  63. package/docs/plans/60.sql.thirdparty.md +26 -0
  64. package/docs/plans/61.objective.multiforge.md +63 -0
  65. package/docs/plans/62.huggingface.upload.md +26 -0
  66. package/docs/plans/63.kaggle.upload.md +24 -0
  67. package/docs/plans/64.npm.storage.md +30 -0
  68. package/docs/plans/65.rclone.terabox.md +32 -0
  69. package/docs/plans/66.buckets.and.models.todo.md +14 -0
  70. package/docs/plans/67.database.todo.md +13 -0
  71. package/docs/plans/68.deploy.packages.todo.md +12 -0
  72. package/docs/plans/69.report.human.operator.md +133 -0
  73. package/docs/plans/70.report.brain2qwerty.ems.md +135 -0
  74. package/docs/plans/71.report.hd.infinito.vram.md +155 -0
  75. package/docs/plans/72.plan.hd.infinito.node.md +146 -0
  76. package/docs/plans/73.plan.scifi.repos.md +125 -0
  77. package/docs/plans/74.000.manifesto.v8.flat.2..md +11 -0
  78. package/docs/plans/README.md +489 -0
  79. package/docs/plans/aggregate_platforms.mjs +146 -0
  80. package/docs/plans/examplesession.json +36 -0
  81. package/docs/plans/missing-facts.md +192 -0
  82. package/docs/plans/models.md +64 -0
  83. package/docs/plans/organize.cjs +270 -0
  84. package/docs/plans/platforms.md +2887 -0
  85. package/docs/plans/sites.md +31322 -0
  86. package/docs/platformpipelineaudit.md +18 -0
  87. package/docs/platformpipelines.md +13 -0
  88. package/docs/registryresearch.md +4 -0
  89. package/docs/release.md +4 -4
  90. package/docs/release182notes.md +2 -0
  91. package/docs/release184notes.md +7 -0
  92. package/docs/release185notes.md +7 -0
  93. package/docs/sources/farm.py +117 -0
  94. package/docs/sources/html/saddle1.html +132 -0
  95. package/docs/sources/html/saddle2.html +157 -0
  96. package/docs/sources/html/saddle3.html +119 -0
  97. package/docs/sources/html/saddle4.html +144 -0
  98. package/docs/sources/html/saddle5.html +72 -0
  99. package/docs/sources/html/saddle6.html +171 -0
  100. package/docs/sources/html/saddle7.html +236 -0
  101. package/docs/sources/saddle.ts +74 -0
  102. package/docs/sources/schema.prisma +88 -0
  103. package/docs/sources/script.sh +64 -0
  104. package/docs/sources/workflows.yml +458 -0
  105. package/docs/talks1/_body.txt +14 -0
  106. package/docs/talks1/_index.md +15 -0
  107. package/docs/talks1/_screenshot.png +0 -0
  108. package/docs/talks1/assistant-01.md +5 -0
  109. package/docs/talks1/assistant-02.md +5 -0
  110. package/docs/talks1/assistant-03.md +531 -0
  111. package/docs/talks1/assistant-04.md +26 -0
  112. package/docs/talks1/assistant-05.md +774 -0
  113. package/docs/talks1/assistant-06.md +1718 -0
  114. package/docs/talks1/scrape-share.cjs +185 -0
  115. package/docs/talks1/scrape-share.ts +183 -0
  116. package/docs/talks1/user-01.md +3 -0
  117. package/docs/talks1/user-02.md +3 -0
  118. package/docs/talks1/user-03.md +88 -0
  119. package/docs/talks1/user-04.md +3 -0
  120. package/docs/talks1/user-05.md +3 -0
  121. package/docs/talks1/user-06.md +88 -0
  122. package/docs/talks1/user-07.md +88 -0
  123. package/docs/talks2/_body.txt +14 -0
  124. package/docs/talks2/_index.md +16 -0
  125. package/docs/talks2/_screenshot.png +0 -0
  126. package/docs/talks2/assistant-01.md +5 -0
  127. package/docs/talks2/assistant-02.md +5 -0
  128. package/docs/talks2/assistant-03.md +424 -0
  129. package/docs/talks2/assistant-04.md +598 -0
  130. package/docs/talks2/assistant-05.md +1280 -0
  131. package/docs/talks2/assistant-06.md +1227 -0
  132. package/docs/talks2/assistant-07.md +1252 -0
  133. package/docs/talks2/user-01.md +3 -0
  134. package/docs/talks2/user-02.md +3 -0
  135. package/docs/talks2/user-03.md +88 -0
  136. package/docs/talks2/user-04.md +88 -0
  137. package/docs/talks2/user-05.md +88 -0
  138. package/docs/talks2/user-06.md +88 -0
  139. package/docs/talks2/user-07.md +3 -0
  140. package/docs/talks3/_body.txt +467 -0
  141. package/docs/talks3/_index.md +10 -0
  142. package/docs/talks3/_screenshot.png +0 -0
  143. package/docs/talks3/assistant-01.md +417 -0
  144. package/docs/talks3/assistant-02.md +417 -0
  145. package/docs/talks3/assistant-03.md +29 -0
  146. package/docs/talks3/assistant-04.md +727 -0
  147. package/docs/talks3/user-01.md +88 -0
  148. package/docs/talks3/user-02.md +88 -0
  149. package/docs/talks3/user-03.md +3 -0
  150. package/docs/talks3/user-04.md +3 -0
  151. package/docs/talks4/_body.txt +14 -0
  152. package/docs/talks4/_index.md +12 -0
  153. package/docs/talks4/_screenshot.png +0 -0
  154. package/docs/talks4/assistant-01.md +5 -0
  155. package/docs/talks4/assistant-02.md +5 -0
  156. package/docs/talks4/assistant-03.md +35 -0
  157. package/docs/talks4/assistant-04.md +512 -0
  158. package/docs/talks4/assistant-05.md +599 -0
  159. package/docs/talks4/user-01.md +3 -0
  160. package/docs/talks4/user-02.md +3 -0
  161. package/docs/talks4/user-03.md +88 -0
  162. package/docs/talks4/user-04.md +88 -0
  163. package/docs/talks4/user-05.md +7 -0
  164. package/docs/talks5/_body.txt +14 -0
  165. package/docs/talks5/_index.md +13 -0
  166. package/docs/talks5/_screenshot.png +0 -0
  167. package/docs/talks5/assistant-01.md +5 -0
  168. package/docs/talks5/assistant-02.md +5 -0
  169. package/docs/talks5/assistant-03.md +690 -0
  170. package/docs/talks5/assistant-04.md +758 -0
  171. package/docs/talks5/assistant-05.md +974 -0
  172. package/docs/talks5/user-01.md +3 -0
  173. package/docs/talks5/user-02.md +3 -0
  174. package/docs/talks5/user-03.md +105 -0
  175. package/docs/talks5/user-04.md +105 -0
  176. package/docs/talks5/user-05.md +63 -0
  177. package/docs/talks5/user-06.md +105 -0
  178. package/docs/talks6/_body.txt +14 -0
  179. package/docs/talks6/_index.md +9 -0
  180. package/docs/talks6/_screenshot.png +0 -0
  181. package/docs/talks6/assistant-01.md +5 -0
  182. package/docs/talks6/assistant-02.md +5 -0
  183. package/docs/talks6/assistant-03.md +1499 -0
  184. package/docs/talks6/user-01.md +3 -0
  185. package/docs/talks6/user-02.md +3 -0
  186. package/docs/talks6/user-03.md +88 -0
  187. package/docs/talks6/user-04.md +88 -0
  188. package/docs/talks7/_body.txt +14 -0
  189. package/docs/talks7/_index.md +10 -0
  190. package/docs/talks7/_screenshot.png +0 -0
  191. package/docs/talks7/assistant-01.md +5 -0
  192. package/docs/talks7/assistant-02.md +5 -0
  193. package/docs/talks7/assistant-03.md +523 -0
  194. package/docs/talks7/assistant-04.md +617 -0
  195. package/docs/talks7/user-01.md +3 -0
  196. package/docs/talks7/user-02.md +3 -0
  197. package/docs/talks7/user-03.md +105 -0
  198. package/docs/talks7/user-04.md +67 -0
  199. package/docs/talks8/conversa1.txt +1322 -0
  200. package/docs/talks8/conversa2.txt +237 -0
  201. 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" +174 -0
  202. 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" +59 -0
  203. 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" +91 -0
  204. 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" +116 -0
  205. 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" +128 -0
  206. package/docs/talks9/README (2).md +489 -0
  207. package/docs/talks9/README.md +198 -0
  208. 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" +80 -0
  209. package/docs/talks9/conversa.txt +544 -0
  210. package/docs/talks9/other (2).md +39 -0
  211. package/docs/talks9/other.md +57 -0
  212. package/docs/talks9/outro.txt +24 -0
  213. package/extension/README.md +3 -3
  214. package/extension/serviceworker.js +63 -4
  215. package/extension/worker.js +3 -1
  216. package/package.json +12 -2
  217. package/packager/manifest.js +1 -1
  218. package/scrape/agent.ts +122 -0
  219. package/scrape/batch.ts +79 -0
  220. package/scrape/biome.json +76 -0
  221. package/scrape/browser.ts +222 -0
  222. package/scrape/cache.ts +84 -0
  223. package/scrape/chunking.ts +193 -0
  224. package/scrape/cli.ts +105 -0
  225. package/scrape/crawler.ts +115 -0
  226. package/scrape/dev-server.ts +94 -0
  227. package/scrape/errors.ts +132 -0
  228. package/scrape/events.ts +26 -0
  229. package/scrape/extract.ts +165 -0
  230. package/scrape/fetch.ts +105 -0
  231. package/scrape/formats.ts +85 -0
  232. package/scrape/headers.ts +71 -0
  233. package/scrape/index.ts +92 -0
  234. package/scrape/jsdom.d.ts +6 -0
  235. package/scrape/llms-txt.ts +84 -0
  236. package/scrape/middleware.ts +90 -0
  237. package/scrape/package-lock.json +9397 -0
  238. package/scrape/package.json +1420 -0
  239. package/scrape/pool.ts +95 -0
  240. package/scrape/port.ts +18 -0
  241. package/scrape/proxy.ts +103 -0
  242. package/scrape/rate-limiter.ts +95 -0
  243. package/scrape/renderer.ts +194 -0
  244. package/scrape/retry.ts +64 -0
  245. package/scrape/robots.ts +137 -0
  246. package/scrape/scrape.ts +123 -0
  247. package/scrape/serialize.ts +310 -0
  248. package/scrape/server.ts +137 -0
  249. package/scrape/session.ts +109 -0
  250. package/scrape/sitemap.ts +131 -0
  251. package/scrape/tokens.ts +45 -0
  252. package/scrape/tsconfig.json +28 -0
  253. package/scrape/types.ts +214 -0
  254. package/scrape/utils.ts +77 -0
  255. package/scrape/vite.config.ts +55 -0
  256. package/scrape/vitest.config.ts +17 -0
  257. package/workflow/templates.js +4 -4
@@ -0,0 +1,155 @@
1
+ # Scraping Pipeline Flow
2
+
3
+ ## High-Level Pipeline
4
+
5
+ ```
6
+ User Input (URL or HTML)
7
+
8
+
9
+ ┌──────────────────────┐
10
+ │ scrapeUrl() │
11
+ │ ┌────────────────┐ │
12
+ │ │ AgentBrowser │ │
13
+ │ │ ┌──────────┐ │ │
14
+ │ │ │ Launch │ │ │
15
+ │ │ │ Browser │ │ │
16
+ │ │ └────┬─────┘ │ │
17
+ │ │ ▼ │ │
18
+ │ │ ┌──────────┐ │ │
19
+ │ │ │ Navigate │ │ │
20
+ │ │ │ to URL │ │ │
21
+ │ │ └────┬─────┘ │ │
22
+ │ │ ▼ │ │
23
+ │ │ ┌──────────┐ │ │
24
+ │ │ │ Scroll / │ │ │
25
+ │ │ │ Interact │ │ │
26
+ │ │ └────┬─────┘ │ │
27
+ │ │ ▼ │ │
28
+ │ │ ┌──────────┐ │ │
29
+ │ │ │ Extract │ │ │
30
+ │ │ │ HTML │ │ │
31
+ │ │ └──────────┘ │ │
32
+ │ └────────────────┘ │
33
+ │ │ │
34
+ │ ▼ │
35
+ │ ┌────────────────┐ │
36
+ │ │ extractContent │ │
37
+ │ │ (Cheerio parse) │ │
38
+ │ └────────────────┘ │
39
+ └──────────┬───────────┘
40
+ │ ScrapeResult
41
+
42
+ ┌──────────────────────┐
43
+ │ serializeResult() │
44
+ │ Format: markdown / │
45
+ │ json / xml / redis │
46
+ │ / text │
47
+ └──────────┬───────────┘
48
+ │ SerializedOutput
49
+
50
+ ┌──────────────────────┐
51
+ │ formatForAgent() │
52
+ │ (LLM-friendly) │
53
+ │ or render with │
54
+ │ PygameRenderer │
55
+ └──────────────────────┘
56
+ ```
57
+
58
+ ## Execution Paths
59
+
60
+ ### URL Scraping
61
+
62
+ ```
63
+ scrapeUrl(url, options)
64
+ ├── AgentBrowser.launch('chromium')
65
+ ├── AgentBrowser.navigate(url)
66
+ ├── [optional] AgentBrowser.scrollToBottom()
67
+ ├── AgentBrowser.html() → raw HTML
68
+ ├── AgentBrowser.screenshot() → Buffer
69
+ ├── extractContent(html) → ExtractedContent
70
+ ├── AgentBrowser.close()
71
+ └── returns ScrapeResult { url, title, html, text, links, images, tables, metadata, screenshot }
72
+ ```
73
+
74
+ ### HTML Scraping (offline)
75
+
76
+ ```
77
+ scrapeHtml(html, options)
78
+ ├── extractContent(html) → ExtractedContent
79
+ └── returns ScrapeResult { url: 'inline', html, ...extracted }
80
+ ```
81
+
82
+ ### Browser Reuse
83
+
84
+ ```
85
+ scrapeWithBrowser(browser, url, options)
86
+ ├── browser.navigate(url)
87
+ ├── browser.html()
88
+ ├── extractContent(html)
89
+ └── returns ScrapeResult
90
+ ```
91
+
92
+ ## Data Flow
93
+
94
+ ```
95
+ Raw HTML
96
+
97
+
98
+ Cheerio.parse(html)
99
+
100
+ ├── Title: $('title').text() / $('h1').first().text()
101
+ ├── Author: $('[rel=author]') / meta tags
102
+ ├── Text: $('p, li, blockquote').text() (joined)
103
+ ├── Links: $('a[href]') → { href, text }
104
+ ├── Images: $('img[src]') → { src, alt }
105
+ ├── Tables: $('table') → { headers, rows }
106
+ └── Metadata: meta tags → { description, keywords, og:* }
107
+
108
+
109
+ ExtractedContent
110
+
111
+
112
+ serializeResult(result, { format })
113
+
114
+ ├── markdown: TurndownService.turndown(html)
115
+ ├── json: JSON.stringify(content)
116
+ ├── xml: xml2js.Builder.buildObject(content)
117
+ ├── redis: JSON.SET key path value
118
+ └── text: strip tags + join
119
+ ```
120
+
121
+ ## Serialization Flow
122
+
123
+ ```
124
+ serializeResult(result, options)
125
+
126
+ ├── resolveFormat(options.format) → format name
127
+ ├── resolveExtension(formatName) → file extension
128
+
129
+ ├── format === 'markdown'
130
+ │ └── TurndownService.turndown(html)
131
+
132
+ ├── format === 'json'
133
+ │ └── JSON.stringify(content, null, pretty ? 2 : 0)
134
+
135
+ ├── format === 'xml'
136
+ │ └── xml2js.Builder.buildObject({ root: content })
137
+
138
+ ├── format === 'redis'
139
+ │ └── "JSON.SET key $ '...escaped json...'\n"
140
+
141
+ └── format === 'text'
142
+ └── strip all HTML tags, join text nodes
143
+ ```
144
+
145
+ ## Agent Output Flow
146
+
147
+ ```
148
+ formatForAgent(result)
149
+
150
+ ├── Build summary (first 200 chars of text)
151
+ ├── Extract key points (sentences with key phrases)
152
+ ├── Collect relevant URLs
153
+ ├── Chunk content for token limits
154
+ └── Returns { summary, keyPoints, content, relevantUrls, chunks, tokenCount }
155
+ ```
@@ -0,0 +1,252 @@
1
+ # Saddle Multi-Platform Bot
2
+
3
+ > Bot that operates across GitHub, GitLab, Forgejo, Gitea, and Discord.
4
+ > Unified interface for all platform integrations.
5
+
6
+ ## Overview
7
+
8
+ The saddle robot operates as a bot across multiple code
9
+ hosting platforms and messaging services through a unified
10
+ adapter interface. Each platform has a dedicated adapter
11
+ implementing the same interface contract.
12
+
13
+ ## Platform Adapters
14
+
15
+ ### GitHub Adapter
16
+
17
+ ```typescript
18
+ interface GitHubAdapter {
19
+ type: 'github'
20
+ authenticate(token: string): Promise<boolean>
21
+ listRepos(query?: string): Promise<Repo[]>
22
+ getRepo(owner: string, repo: string): Promise<Repo>
23
+ createIssue(repo: string, title: string, body: string): Promise<Issue>
24
+ createPR(repo: string, title: string, body: string, branch: string): Promise<PR>
25
+ addComment(repo: string, issueNumber: number, body: string): Promise<Comment>
26
+ createWebhook(repo: string, url: string, events: string[]): Promise<Webhook>
27
+ executeWorkflow(repo: string, workflow: string): Promise<WorkflowRun>
28
+ uploadReleaseAsset(repo: string, tag: string, name: string, path: string): Promise<Asset>
29
+ }
30
+ ```
31
+
32
+ Authentication uses a personal access token or GitHub App token.
33
+
34
+ Token scopes required:
35
+ - `repo` (full control)
36
+ - `workflow` (manage workflows)
37
+ - `read:org` (read organization data)
38
+
39
+ ### GitLab Adapter
40
+
41
+ ```typescript
42
+ interface GitLabAdapter {
43
+ type: 'gitlab'
44
+ authenticate(token: string): Promise<boolean>
45
+ listProjects(query?: string): Promise<Project[]>
46
+ getProject(id: number | string): Promise<Project>
47
+ createIssue(projectId: number, title: string, description: string): Promise<Issue>
48
+ createMergeRequest(projectId: number, title: string, description: string, sourceBranch: string, targetBranch: string): Promise<MR>
49
+ addComment(projectId: number, noteableType: string, noteableId: number, body: string): Promise<Note>
50
+ createWebhook(projectId: number, url: string, events: string[]): Promise<Webhook>
51
+ triggerPipeline(projectId: number, ref: string, variables: Record<string, string>): Promise<Pipeline>
52
+ uploadFile(projectId: number, filePath: string, content: Buffer): Promise<Attachment>
53
+ }
54
+ ```
55
+
56
+ Authentication uses a personal access token with `api` scope.
57
+
58
+ ### Forgejo Adapter
59
+
60
+ Forgejo is fully compatible with the GitHub API, making the
61
+ GitHub adapter usable with minimal configuration changes.
62
+
63
+ ```typescript
64
+ interface ForgejoAdapter {
65
+ extends: GitHubAdapter
66
+ customBaseUrl: string
67
+ }
68
+ ```
69
+
70
+ Configuration:
71
+ - Use GitHub adapter with custom `baseUrl` pointing to Forgejo instance
72
+ - Token type: access token with `write:repository`, `write:issue`, `write:webhook` scopes
73
+
74
+ ### Gitea Adapter
75
+
76
+ Gitea also provides GitHub-compatible API endpoints.
77
+
78
+ ```typescript
79
+ interface GiteaAdapter {
80
+ extends: GitHubAdapter
81
+ customBaseUrl: string
82
+ }
83
+ ```
84
+
85
+ Configuration:
86
+ - Use GitHub adapter with custom `baseUrl` pointing to Gitea instance
87
+ - Token type: API token with full repository scope
88
+
89
+ ### Discord Adapter
90
+
91
+ ```typescript
92
+ interface DiscordAdapter {
93
+ type: 'discord'
94
+ authenticate(token: string): Promise<boolean>
95
+ sendMessage(channelId: string, content: string): Promise<Message>
96
+ createWebhook(channelId: string, name: string): Promise<Webhook>
97
+ executeWebhook(webhookId: string, webhookToken: string, payload: WebhookPayload): Promise<Message>
98
+ addReaction(channelId: string, messageId: string, emoji: string): Promise<void>
99
+ createThread(channelId: string, name: string, messageId: string): Promise<Thread>
100
+ }
101
+ ```
102
+
103
+ ## Unified Bot Interface
104
+
105
+ ```typescript
106
+ interface SaddleBot {
107
+ platform: PlatformAdapter
108
+ config: BotConfig
109
+
110
+ start(): Promise<void>
111
+ stop(): Promise<void>
112
+ executeCommand(command: BotCommand): Promise<BotResult>
113
+ handleWebhook(event: WebhookEvent): Promise<void>
114
+ scheduleTask(task: ScheduledTask): Promise<ScheduledTaskHandle>
115
+ getStatus(): Promise<BotStatus>
116
+ }
117
+ ```
118
+
119
+ ### Bot Config
120
+
121
+ ```typescript
122
+ interface BotConfig {
123
+ platforms: PlatformConfig[]
124
+ memoryEngine: MemoryEngineConfig
125
+ deploy: DeployConfig
126
+ logging: LogConfig
127
+ }
128
+
129
+ interface PlatformConfig {
130
+ type: 'github' | 'gitlab' | 'forgejo' | 'gitea' | 'discord'
131
+ name: string
132
+ token: string
133
+ baseUrl?: string
134
+ webhookSecret?: string
135
+ repositories: string[]
136
+ channels: string[]
137
+ }
138
+ ```
139
+
140
+ ## Bot Commands
141
+
142
+ | Command | Description | Platforms |
143
+ |---------|-------------|-----------|
144
+ | `capture` | Start browser capture session | All |
145
+ | `scrape` | Scrape URLs and extract content | All |
146
+ | `review` | Review PRs/issues automatically | GitHub, GitLab, Forgejo, Gitea |
147
+ | `deploy` | Deploy to target platform | GitHub, GitLab, Forgejo |
148
+ | `memory` | Store/retrieve memory objects | All |
149
+ | `status` | Report bot status | All |
150
+ | `test` | Run test suite | GitHub, GitLab, Forgejo |
151
+ | `release` | Create release with assets | GitHub, GitLab, Forgejo |
152
+ | `webhook` | Manage webhooks | GitHub, GitLab, Forgejo, Gitea |
153
+ | `schedule` | Schedule recurring tasks | All |
154
+ | `npm publish` | Publish NPM package | GitHub |
155
+ | `artifact` | Upload artifacts to storage | All |
156
+
157
+ ## Multi-Platform Workflow
158
+
159
+ A typical workflow uses the saddle robot across platforms:
160
+
161
+ ```
162
+ 1. Discord webhook receives user command
163
+ 2. Saddle robot parses command
164
+ 3. Bot selects target platform adapter
165
+ 4. Executes command on target platform
166
+ 5. Stores result in memory backend
167
+ 6. Reports status back to Discord
168
+ 7. Optionally triggers CI/CD pipeline
169
+ ```
170
+
171
+ ## Webhook Integration
172
+
173
+ ### GitHub Webhooks
174
+
175
+ ```json
176
+ {
177
+ "webhooks": [
178
+ {
179
+ "url": "https://saddle.example.com/webhook/github",
180
+ "content_type": "json",
181
+ "secret": "${WEBHOOK_SECRET}",
182
+ "events": [
183
+ "push",
184
+ "pull_request",
185
+ "issues",
186
+ "issue_comment",
187
+ "release",
188
+ "deployment"
189
+ ]
190
+ }
191
+ ]
192
+ }
193
+ ```
194
+
195
+ ### GitLab Webhooks
196
+
197
+ ```json
198
+ {
199
+ "webhooks": [
200
+ {
201
+ "url": "https://saddle.example.com/webhook/gitlab",
202
+ "secret_token": "${WEBHOOK_SECRET}",
203
+ "trigger_events": true,
204
+ "push_events": true,
205
+ "merge_request_events": true,
206
+ "issue_events": true,
207
+ "tag_push_events": true
208
+ }
209
+ ]
210
+ }
211
+ ```
212
+
213
+ ## Deployment per Platform
214
+
215
+ | Platform | Deploy Method | Best For |
216
+ |----------|--------------|----------|
217
+ | GitHub | GitHub Actions + NPM package | Team collaboration |
218
+ | GitLab | GitLab CI + Docker | Self-hosted or cloud |
219
+ | Forgejo | Forgejo Actions + Docker | Lightweight self-hosted |
220
+ | Gitea | Gitea Actions + Docker | Minimal self-hosted |
221
+ | Discord | Discord bot token + HTTPS | Messaging integration |
222
+
223
+ ## Error Handling
224
+
225
+ Each adapter implements error handling with contextual error
226
+ messages for later tracing. Adapter failures are caught and
227
+ reported without crashing the bot.
228
+
229
+ ```typescript
230
+ class SafeAdapter {
231
+ private adapter: PlatformAdapter
232
+
233
+ async execute(
234
+ method: string,
235
+ ...args: unknown[]
236
+ ): Promise<{ success: boolean; result?: unknown; error?: string }> {
237
+ try {
238
+ const result = await (this.adapter as Record<string, unknown>)[method](...args)
239
+ return { success: true, result }
240
+ } catch (error) {
241
+ return {
242
+ success: false,
243
+ error: error instanceof Error ? error.message : String(error),
244
+ }
245
+ }
246
+ }
247
+ }
248
+ ```
249
+
250
+ ## License
251
+
252
+ MIT
@@ -0,0 +1,250 @@
1
+ # NPM Package Publishing for Saddle Robot
2
+
3
+ > Package `@devthink/saddle` published to NPM registry.
4
+ > Acts as both library and CLI binary.
5
+
6
+ ## Overview
7
+
8
+ Saddle robot is published as an NPM package for easy
9
+ distribution as a library and a CLI tool. The package
10
+ includes browser automation, bot functionality, captcha
11
+ bypass, and memory engine capabilities.
12
+
13
+ ## Package Configuration
14
+
15
+ ### package.json
16
+
17
+ ```json
18
+ {
19
+ "name": "@devthink/saddle",
20
+ "version": "1.0.0",
21
+ "description": "Super bot: agent browser, captcha bypass, multi-platform GitHub/GitLab/Forgejo/Gitea automation with computational memory",
22
+ "main": "lib/index.js",
23
+ "bin": {
24
+ "saddle": "bin/saddle.js"
25
+ },
26
+ "type": "module",
27
+ "exports": {
28
+ ".": {
29
+ "import": "./lib/index.js",
30
+ "require": "./lib/index.cjs"
31
+ },
32
+ "./browser": {
33
+ "import": "./lib/browser.js"
34
+ },
35
+ "./bot": {
36
+ "import": "./lib/bot.js"
37
+ },
38
+ "./ captcha": {
39
+ "import": "./lib/captcha.js"
40
+ },
41
+ "./memory-engine": {
42
+ "import": "./lib/memory-engine.js"
43
+ },
44
+ "./deploy": {
45
+ "import": "./lib/deploy.js"
46
+ }
47
+ },
48
+ "scripts": {
49
+ "build": "tsc",
50
+ "test": "vitest run",
51
+ "lint": "biome check .",
52
+ "typecheck": "tsc --noEmit",
53
+ "prepublishOnly": "npm run build && npm test",
54
+ "prepare": "husky"
55
+ },
56
+ "repository": {
57
+ "type": "git",
58
+ "url": "https://github.com/username/saddle.git"
59
+ },
60
+ "keywords": [
61
+ "agent",
62
+ "browser",
63
+ "automation",
64
+ "bot",
65
+ "captcha-bypass",
66
+ "github-bot",
67
+ "gitlab-bot",
68
+ "scraper",
69
+ "computer-use",
70
+ "ai-agent"
71
+ ],
72
+ "author": "iakadion",
73
+ "license": "MIT",
74
+ "bugs": {
75
+ "url": "https://github.com/username/saddle/issues"
76
+ },
77
+ "homepage": "https://github.com/username/saddle#readme"
78
+ }
79
+ ```
80
+
81
+ ## Publishing Steps
82
+
83
+ ### 1. Build and Test
84
+
85
+ ```bash
86
+ npm run build
87
+ npm test
88
+ npm run lint
89
+ npm run typecheck
90
+ ```
91
+
92
+ All checks must pass before publishing.
93
+
94
+ ### 2. Login to NPM
95
+
96
+ ```bash
97
+ npm login
98
+ # Enter NPM credentials (token recommended)
99
+ ```
100
+
101
+ ### 3. Publish
102
+
103
+ ```bash
104
+ # Publish as public package
105
+ npm publish --access public
106
+
107
+ # Publish as scoped package
108
+ npm publish --access public
109
+ ```
110
+
111
+ ### 4. Version Bumping
112
+
113
+ ```bash
114
+ # Patch version (1.0.0 → 1.0.1)
115
+ npm version patch
116
+
117
+ # Minor version (1.0.0 → 1.1.0)
118
+ npm version minor
119
+
120
+ # Major version (1.0.0 → 2.0.0)
121
+ npm version major
122
+
123
+ # Push tags after version bump
124
+ git push --follow-tags
125
+ ```
126
+
127
+ ## Installation
128
+
129
+ ### As Library
130
+
131
+ ```bash
132
+ npm install @devthink/saddle
133
+ ```
134
+
135
+ ```javascript
136
+ import { SaddleRobot } from '@devthink/saddle'
137
+
138
+ const robot = new SaddleRobot({
139
+ platform: 'github',
140
+ token: process.env.SBOT_TOKEN,
141
+ })
142
+
143
+ await robot.start()
144
+ ```
145
+
146
+ ### As CLI
147
+
148
+ ```bash
149
+ npm install -g @devthink/saddle
150
+
151
+ saddle --help
152
+ saddle capture --url https://example.com
153
+ saddle bot --platform github --token $SBOT_TOKEN
154
+ saddle memory --load repo://owner/repo/path/file.json
155
+ ```
156
+
157
+ ## Binary Entry Point
158
+
159
+ ```javascript
160
+ #!/usr/bin/env node
161
+
162
+ import { SaddleRobot } from '../lib/index.js'
163
+ import { parseArgs } from 'node:util'
164
+
165
+ const options = parseArgs({
166
+ options: {
167
+ command: { type: 'string' },
168
+ platform: { type: 'string' },
169
+ token: { type: 'string' },
170
+ verbose: { type: 'boolean' },
171
+ },
172
+ })
173
+
174
+ const { values } = options
175
+ const robot = new SaddleRobot({
176
+ platform: values.platform ?? 'auto',
177
+ token: values.token ?? '',
178
+ verbose: values.verbose ?? false,
179
+ })
180
+
181
+ async function main() {
182
+ try {
183
+ const command = values.command ?? 'help'
184
+ await robot.start()
185
+ const result = await robot.executeCommand(command)
186
+ if (values.verbose) {
187
+ console.log(JSON.stringify(result, null, 2))
188
+ }
189
+ } catch (error) {
190
+ console.error(
191
+ `saddle: ${error instanceof Error ? error.message : String(error)}`
192
+ )
193
+ process.exit(1)
194
+ }
195
+ }
196
+
197
+ main()
198
+ ```
199
+
200
+ ## Scoped Package Structure
201
+
202
+ ```
203
+ @devthink/saddle/
204
+ ├── lib/
205
+ │ ├── index.js main entry point
206
+ │ ├── index.cjs CommonJS entry point
207
+ │ ├── browser.js browser automation engine
208
+ │ ├── bot.js multi-platform bot engine
209
+ │ ├── captcha.js captcha bypass module
210
+ │ ├── memory-engine.js storage-to-compute memory
211
+ │ ├── deploy.js deploy strategy implementations
212
+ │ └── adapters/
213
+ │ ├── github.js GitHub platform adapter
214
+ │ ├── gitlab.js GitLab platform adapter
215
+ │ ├── forgejo.js Forgejo platform adapter
216
+ │ ├── gitea.js Gitea platform adapter
217
+ │ └── discord.js Discord messaging adapter
218
+ ├── bin/
219
+ │ └── saddle.js CLI entry point
220
+ ├── types/
221
+ │ └── index.d.ts TypeScript declarations
222
+ ├── docs/
223
+ │ └── index.md package documentation
224
+ ├── package.json
225
+ └── README.md
226
+ ```
227
+
228
+ ## Versioning Strategy
229
+
230
+ Follow semantic versioning (semver):
231
+
232
+ | Change Type | Version Bump |
233
+ |-------------|-------------|
234
+ | Bug fix | Patch (1.x.X) |
235
+ | New backward-compatible feature | Minor (1.X.0) |
236
+ | Breaking change | Major (X.0.0) |
237
+
238
+ ## Pre-publish Checklist
239
+
240
+ 1. All tests pass (`npm test`)
241
+ 2. Linting passes (`npm run lint`)
242
+ 3. TypeScript checks pass (`npm run typecheck`)
243
+ 4. Build succeeds (`npm run build`)
244
+ 5. README is updated
245
+ 6. Changelog is updated
246
+ 7. No breaking changes without major version bump
247
+
248
+ ## License
249
+
250
+ MIT