@nac3/forge-cli 0.2.0-alpha.1

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 (561) hide show
  1. package/LICENSE +45 -0
  2. package/README.md +371 -0
  3. package/dist/bin/yf.d.ts +5 -0
  4. package/dist/bin/yf.d.ts.map +1 -0
  5. package/dist/bin/yf.js +86 -0
  6. package/dist/bin/yf.js.map +1 -0
  7. package/dist/chat/claude.d.ts +100 -0
  8. package/dist/chat/claude.d.ts.map +1 -0
  9. package/dist/chat/claude.js +228 -0
  10. package/dist/chat/claude.js.map +1 -0
  11. package/dist/chat/ingest_session.d.ts +97 -0
  12. package/dist/chat/ingest_session.d.ts.map +1 -0
  13. package/dist/chat/ingest_session.js +99 -0
  14. package/dist/chat/ingest_session.js.map +1 -0
  15. package/dist/chat/panel.d.ts +15 -0
  16. package/dist/chat/panel.d.ts.map +1 -0
  17. package/dist/chat/panel.js +1526 -0
  18. package/dist/chat/panel.js.map +1 -0
  19. package/dist/chat/persistence.d.ts +37 -0
  20. package/dist/chat/persistence.d.ts.map +1 -0
  21. package/dist/chat/persistence.js +91 -0
  22. package/dist/chat/persistence.js.map +1 -0
  23. package/dist/chat/server.d.ts +34 -0
  24. package/dist/chat/server.d.ts.map +1 -0
  25. package/dist/chat/server.js +1540 -0
  26. package/dist/chat/server.js.map +1 -0
  27. package/dist/chat/spec_extract.d.ts +35 -0
  28. package/dist/chat/spec_extract.d.ts.map +1 -0
  29. package/dist/chat/spec_extract.js +152 -0
  30. package/dist/chat/spec_extract.js.map +1 -0
  31. package/dist/chat/spec_plan.d.ts +65 -0
  32. package/dist/chat/spec_plan.d.ts.map +1 -0
  33. package/dist/chat/spec_plan.js +160 -0
  34. package/dist/chat/spec_plan.js.map +1 -0
  35. package/dist/chat/spec_scaffold.d.ts +95 -0
  36. package/dist/chat/spec_scaffold.d.ts.map +1 -0
  37. package/dist/chat/spec_scaffold.js +220 -0
  38. package/dist/chat/spec_scaffold.js.map +1 -0
  39. package/dist/chat/tools/git.d.ts +59 -0
  40. package/dist/chat/tools/git.d.ts.map +1 -0
  41. package/dist/chat/tools/git.js +313 -0
  42. package/dist/chat/tools/git.js.map +1 -0
  43. package/dist/chat/tools/github.d.ts +59 -0
  44. package/dist/chat/tools/github.d.ts.map +1 -0
  45. package/dist/chat/tools/github.js +310 -0
  46. package/dist/chat/tools/github.js.map +1 -0
  47. package/dist/chat/tools/lifecycle.d.ts +82 -0
  48. package/dist/chat/tools/lifecycle.d.ts.map +1 -0
  49. package/dist/chat/tools/lifecycle.js +295 -0
  50. package/dist/chat/tools/lifecycle.js.map +1 -0
  51. package/dist/chat/tools/manual.d.ts +26 -0
  52. package/dist/chat/tools/manual.d.ts.map +1 -0
  53. package/dist/chat/tools/manual.js +164 -0
  54. package/dist/chat/tools/manual.js.map +1 -0
  55. package/dist/chat/tools/reader.d.ts +80 -0
  56. package/dist/chat/tools/reader.d.ts.map +1 -0
  57. package/dist/chat/tools/reader.js +471 -0
  58. package/dist/chat/tools/reader.js.map +1 -0
  59. package/dist/chat/tools.d.ts +106 -0
  60. package/dist/chat/tools.d.ts.map +1 -0
  61. package/dist/chat/tools.js +587 -0
  62. package/dist/chat/tools.js.map +1 -0
  63. package/dist/codegen/e2e.d.ts +106 -0
  64. package/dist/codegen/e2e.d.ts.map +1 -0
  65. package/dist/codegen/e2e.js +931 -0
  66. package/dist/codegen/e2e.js.map +1 -0
  67. package/dist/codegen/v3_flow_emit.d.ts +70 -0
  68. package/dist/codegen/v3_flow_emit.d.ts.map +1 -0
  69. package/dist/codegen/v3_flow_emit.js +225 -0
  70. package/dist/codegen/v3_flow_emit.js.map +1 -0
  71. package/dist/commands/_stub.d.ts +2 -0
  72. package/dist/commands/_stub.d.ts.map +1 -0
  73. package/dist/commands/_stub.js +21 -0
  74. package/dist/commands/_stub.js.map +1 -0
  75. package/dist/commands/app.d.ts +31 -0
  76. package/dist/commands/app.d.ts.map +1 -0
  77. package/dist/commands/app.js +331 -0
  78. package/dist/commands/app.js.map +1 -0
  79. package/dist/commands/chat.d.ts +18 -0
  80. package/dist/commands/chat.d.ts.map +1 -0
  81. package/dist/commands/chat.js +76 -0
  82. package/dist/commands/chat.js.map +1 -0
  83. package/dist/commands/deploy.d.ts +21 -0
  84. package/dist/commands/deploy.d.ts.map +1 -0
  85. package/dist/commands/deploy.js +121 -0
  86. package/dist/commands/deploy.js.map +1 -0
  87. package/dist/commands/doctor.d.ts +14 -0
  88. package/dist/commands/doctor.d.ts.map +1 -0
  89. package/dist/commands/doctor.js +280 -0
  90. package/dist/commands/doctor.js.map +1 -0
  91. package/dist/commands/figma.d.ts +32 -0
  92. package/dist/commands/figma.d.ts.map +1 -0
  93. package/dist/commands/figma.js +141 -0
  94. package/dist/commands/figma.js.map +1 -0
  95. package/dist/commands/gen-flow-tests.d.ts +8 -0
  96. package/dist/commands/gen-flow-tests.d.ts.map +1 -0
  97. package/dist/commands/gen-flow-tests.js +78 -0
  98. package/dist/commands/gen-flow-tests.js.map +1 -0
  99. package/dist/commands/gen-tests.d.ts +9 -0
  100. package/dist/commands/gen-tests.d.ts.map +1 -0
  101. package/dist/commands/gen-tests.js +118 -0
  102. package/dist/commands/gen-tests.js.map +1 -0
  103. package/dist/commands/license.d.ts +14 -0
  104. package/dist/commands/license.d.ts.map +1 -0
  105. package/dist/commands/license.js +182 -0
  106. package/dist/commands/license.js.map +1 -0
  107. package/dist/commands/log.d.ts +19 -0
  108. package/dist/commands/log.d.ts.map +1 -0
  109. package/dist/commands/log.js +101 -0
  110. package/dist/commands/log.js.map +1 -0
  111. package/dist/commands/migrate.d.ts +118 -0
  112. package/dist/commands/migrate.d.ts.map +1 -0
  113. package/dist/commands/migrate.js +1410 -0
  114. package/dist/commands/migrate.js.map +1 -0
  115. package/dist/commands/mobile.d.ts +27 -0
  116. package/dist/commands/mobile.d.ts.map +1 -0
  117. package/dist/commands/mobile.js +90 -0
  118. package/dist/commands/mobile.js.map +1 -0
  119. package/dist/commands/new.d.ts +32 -0
  120. package/dist/commands/new.d.ts.map +1 -0
  121. package/dist/commands/new.js +107 -0
  122. package/dist/commands/new.js.map +1 -0
  123. package/dist/commands/pilot.d.ts +8 -0
  124. package/dist/commands/pilot.d.ts.map +1 -0
  125. package/dist/commands/pilot.js +104 -0
  126. package/dist/commands/pilot.js.map +1 -0
  127. package/dist/commands/projects.d.ts +21 -0
  128. package/dist/commands/projects.d.ts.map +1 -0
  129. package/dist/commands/projects.js +238 -0
  130. package/dist/commands/projects.js.map +1 -0
  131. package/dist/commands/publish.d.ts +35 -0
  132. package/dist/commands/publish.d.ts.map +1 -0
  133. package/dist/commands/publish.js +194 -0
  134. package/dist/commands/publish.js.map +1 -0
  135. package/dist/commands/repo.d.ts +59 -0
  136. package/dist/commands/repo.d.ts.map +1 -0
  137. package/dist/commands/repo.js +178 -0
  138. package/dist/commands/repo.js.map +1 -0
  139. package/dist/commands/review-screens.d.ts +28 -0
  140. package/dist/commands/review-screens.d.ts.map +1 -0
  141. package/dist/commands/review-screens.js +345 -0
  142. package/dist/commands/review-screens.js.map +1 -0
  143. package/dist/commands/scenarios.d.ts +23 -0
  144. package/dist/commands/scenarios.d.ts.map +1 -0
  145. package/dist/commands/scenarios.js +304 -0
  146. package/dist/commands/scenarios.js.map +1 -0
  147. package/dist/commands/ship.d.ts +18 -0
  148. package/dist/commands/ship.d.ts.map +1 -0
  149. package/dist/commands/ship.js +41 -0
  150. package/dist/commands/ship.js.map +1 -0
  151. package/dist/commands/test.d.ts +29 -0
  152. package/dist/commands/test.d.ts.map +1 -0
  153. package/dist/commands/test.js +62 -0
  154. package/dist/commands/test.js.map +1 -0
  155. package/dist/commands/tunnel.d.ts +22 -0
  156. package/dist/commands/tunnel.d.ts.map +1 -0
  157. package/dist/commands/tunnel.js +77 -0
  158. package/dist/commands/tunnel.js.map +1 -0
  159. package/dist/commands/validate.d.ts +14 -0
  160. package/dist/commands/validate.d.ts.map +1 -0
  161. package/dist/commands/validate.js +51 -0
  162. package/dist/commands/validate.js.map +1 -0
  163. package/dist/commands/vault.d.ts +32 -0
  164. package/dist/commands/vault.d.ts.map +1 -0
  165. package/dist/commands/vault.js +489 -0
  166. package/dist/commands/vault.js.map +1 -0
  167. package/dist/commands/voice.d.ts +16 -0
  168. package/dist/commands/voice.d.ts.map +1 -0
  169. package/dist/commands/voice.js +69 -0
  170. package/dist/commands/voice.js.map +1 -0
  171. package/dist/core/cascade_router.d.ts +90 -0
  172. package/dist/core/cascade_router.d.ts.map +1 -0
  173. package/dist/core/cascade_router.js +131 -0
  174. package/dist/core/cascade_router.js.map +1 -0
  175. package/dist/core/cf_tunnel.d.ts +52 -0
  176. package/dist/core/cf_tunnel.d.ts.map +1 -0
  177. package/dist/core/cf_tunnel.js +134 -0
  178. package/dist/core/cf_tunnel.js.map +1 -0
  179. package/dist/core/gha_dispatcher.d.ts +48 -0
  180. package/dist/core/gha_dispatcher.d.ts.map +1 -0
  181. package/dist/core/gha_dispatcher.js +198 -0
  182. package/dist/core/gha_dispatcher.js.map +1 -0
  183. package/dist/core/logger.d.ts +89 -0
  184. package/dist/core/logger.d.ts.map +1 -0
  185. package/dist/core/logger.js +245 -0
  186. package/dist/core/logger.js.map +1 -0
  187. package/dist/core/mode.d.ts +26 -0
  188. package/dist/core/mode.d.ts.map +1 -0
  189. package/dist/core/mode.js +122 -0
  190. package/dist/core/mode.js.map +1 -0
  191. package/dist/core/pairing.d.ts +40 -0
  192. package/dist/core/pairing.d.ts.map +1 -0
  193. package/dist/core/pairing.js +145 -0
  194. package/dist/core/pairing.js.map +1 -0
  195. package/dist/core/pilot_setup.d.ts +29 -0
  196. package/dist/core/pilot_setup.d.ts.map +1 -0
  197. package/dist/core/pilot_setup.js +119 -0
  198. package/dist/core/pilot_setup.js.map +1 -0
  199. package/dist/core/polar.d.ts +81 -0
  200. package/dist/core/polar.d.ts.map +1 -0
  201. package/dist/core/polar.js +175 -0
  202. package/dist/core/polar.js.map +1 -0
  203. package/dist/core/project_picker.d.ts +56 -0
  204. package/dist/core/project_picker.d.ts.map +1 -0
  205. package/dist/core/project_picker.js +86 -0
  206. package/dist/core/project_picker.js.map +1 -0
  207. package/dist/core/projects.d.ts +58 -0
  208. package/dist/core/projects.d.ts.map +1 -0
  209. package/dist/core/projects.js +146 -0
  210. package/dist/core/projects.js.map +1 -0
  211. package/dist/core/projects_sync.d.ts +80 -0
  212. package/dist/core/projects_sync.d.ts.map +1 -0
  213. package/dist/core/projects_sync.js +278 -0
  214. package/dist/core/projects_sync.js.map +1 -0
  215. package/dist/core/remote_runner.d.ts +70 -0
  216. package/dist/core/remote_runner.d.ts.map +1 -0
  217. package/dist/core/remote_runner.js +133 -0
  218. package/dist/core/remote_runner.js.map +1 -0
  219. package/dist/core/repo_state.d.ts +24 -0
  220. package/dist/core/repo_state.d.ts.map +1 -0
  221. package/dist/core/repo_state.js +109 -0
  222. package/dist/core/repo_state.js.map +1 -0
  223. package/dist/core/target.d.ts +31 -0
  224. package/dist/core/target.d.ts.map +1 -0
  225. package/dist/core/target.js +121 -0
  226. package/dist/core/target.js.map +1 -0
  227. package/dist/deploy/aws.d.ts +43 -0
  228. package/dist/deploy/aws.d.ts.map +1 -0
  229. package/dist/deploy/aws.js +173 -0
  230. package/dist/deploy/aws.js.map +1 -0
  231. package/dist/figma/api.d.ts +35 -0
  232. package/dist/figma/api.d.ts.map +1 -0
  233. package/dist/figma/api.js +40 -0
  234. package/dist/figma/api.js.map +1 -0
  235. package/dist/figma/decorator.d.ts +74 -0
  236. package/dist/figma/decorator.d.ts.map +1 -0
  237. package/dist/figma/decorator.js +210 -0
  238. package/dist/figma/decorator.js.map +1 -0
  239. package/dist/figma/heuristics.d.ts +29 -0
  240. package/dist/figma/heuristics.d.ts.map +1 -0
  241. package/dist/figma/heuristics.js +110 -0
  242. package/dist/figma/heuristics.js.map +1 -0
  243. package/dist/figma/normalize.d.ts +33 -0
  244. package/dist/figma/normalize.d.ts.map +1 -0
  245. package/dist/figma/normalize.js +101 -0
  246. package/dist/figma/normalize.js.map +1 -0
  247. package/dist/figma/tokens.d.ts +23 -0
  248. package/dist/figma/tokens.d.ts.map +1 -0
  249. package/dist/figma/tokens.js +111 -0
  250. package/dist/figma/tokens.js.map +1 -0
  251. package/dist/figma/types.d.ts +118 -0
  252. package/dist/figma/types.d.ts.map +1 -0
  253. package/dist/figma/types.js +12 -0
  254. package/dist/figma/types.js.map +1 -0
  255. package/dist/i18n/index.d.ts +48 -0
  256. package/dist/i18n/index.d.ts.map +1 -0
  257. package/dist/i18n/index.js +135 -0
  258. package/dist/i18n/index.js.map +1 -0
  259. package/dist/i18n/types.d.ts +52 -0
  260. package/dist/i18n/types.d.ts.map +1 -0
  261. package/dist/i18n/types.js +85 -0
  262. package/dist/i18n/types.js.map +1 -0
  263. package/dist/index.d.ts +12 -0
  264. package/dist/index.d.ts.map +1 -0
  265. package/dist/index.js +11 -0
  266. package/dist/index.js.map +1 -0
  267. package/dist/lan/mdns_packet.d.ts +74 -0
  268. package/dist/lan/mdns_packet.d.ts.map +1 -0
  269. package/dist/lan/mdns_packet.js +247 -0
  270. package/dist/lan/mdns_packet.js.map +1 -0
  271. package/dist/lan/mdns_service.d.ts +102 -0
  272. package/dist/lan/mdns_service.d.ts.map +1 -0
  273. package/dist/lan/mdns_service.js +206 -0
  274. package/dist/lan/mdns_service.js.map +1 -0
  275. package/dist/license/activate.d.ts +33 -0
  276. package/dist/license/activate.d.ts.map +1 -0
  277. package/dist/license/activate.js +135 -0
  278. package/dist/license/activate.js.map +1 -0
  279. package/dist/license/fingerprint.d.ts +2 -0
  280. package/dist/license/fingerprint.d.ts.map +1 -0
  281. package/dist/license/fingerprint.js +29 -0
  282. package/dist/license/fingerprint.js.map +1 -0
  283. package/dist/license/hito4_client.d.ts +24 -0
  284. package/dist/license/hito4_client.d.ts.map +1 -0
  285. package/dist/license/hito4_client.js +103 -0
  286. package/dist/license/hito4_client.js.map +1 -0
  287. package/dist/license/index.d.ts +22 -0
  288. package/dist/license/index.d.ts.map +1 -0
  289. package/dist/license/index.js +125 -0
  290. package/dist/license/index.js.map +1 -0
  291. package/dist/license/types.d.ts +38 -0
  292. package/dist/license/types.d.ts.map +1 -0
  293. package/dist/license/types.js +9 -0
  294. package/dist/license/types.js.map +1 -0
  295. package/dist/migrate/ai-apply.d.ts +198 -0
  296. package/dist/migrate/ai-apply.d.ts.map +1 -0
  297. package/dist/migrate/ai-apply.js +833 -0
  298. package/dist/migrate/ai-apply.js.map +1 -0
  299. package/dist/migrate/ai-decorator.d.ts +87 -0
  300. package/dist/migrate/ai-decorator.d.ts.map +1 -0
  301. package/dist/migrate/ai-decorator.js +203 -0
  302. package/dist/migrate/ai-decorator.js.map +1 -0
  303. package/dist/migrate/apply.d.ts +28 -0
  304. package/dist/migrate/apply.d.ts.map +1 -0
  305. package/dist/migrate/apply.js +119 -0
  306. package/dist/migrate/apply.js.map +1 -0
  307. package/dist/migrate/audit.d.ts +9 -0
  308. package/dist/migrate/audit.d.ts.map +1 -0
  309. package/dist/migrate/audit.js +197 -0
  310. package/dist/migrate/audit.js.map +1 -0
  311. package/dist/migrate/diff.d.ts +28 -0
  312. package/dist/migrate/diff.d.ts.map +1 -0
  313. package/dist/migrate/diff.js +154 -0
  314. package/dist/migrate/diff.js.map +1 -0
  315. package/dist/migrate/html-orchestrator.d.ts +81 -0
  316. package/dist/migrate/html-orchestrator.d.ts.map +1 -0
  317. package/dist/migrate/html-orchestrator.js +233 -0
  318. package/dist/migrate/html-orchestrator.js.map +1 -0
  319. package/dist/migrate/html-walker.d.ts +93 -0
  320. package/dist/migrate/html-walker.d.ts.map +1 -0
  321. package/dist/migrate/html-walker.js +288 -0
  322. package/dist/migrate/html-walker.js.map +1 -0
  323. package/dist/migrate/js-template-walker.d.ts +118 -0
  324. package/dist/migrate/js-template-walker.d.ts.map +1 -0
  325. package/dist/migrate/js-template-walker.js +644 -0
  326. package/dist/migrate/js-template-walker.js.map +1 -0
  327. package/dist/migrate/manifest-validator.d.ts +30 -0
  328. package/dist/migrate/manifest-validator.d.ts.map +1 -0
  329. package/dist/migrate/manifest-validator.js +261 -0
  330. package/dist/migrate/manifest-validator.js.map +1 -0
  331. package/dist/migrate/overrides.d.ts +58 -0
  332. package/dist/migrate/overrides.d.ts.map +1 -0
  333. package/dist/migrate/overrides.js +193 -0
  334. package/dist/migrate/overrides.js.map +1 -0
  335. package/dist/migrate/plugin-scope.d.ts +42 -0
  336. package/dist/migrate/plugin-scope.d.ts.map +1 -0
  337. package/dist/migrate/plugin-scope.js +94 -0
  338. package/dist/migrate/plugin-scope.js.map +1 -0
  339. package/dist/migrate/types.d.ts +45 -0
  340. package/dist/migrate/types.d.ts.map +1 -0
  341. package/dist/migrate/types.js +9 -0
  342. package/dist/migrate/types.js.map +1 -0
  343. package/dist/migrate/verb-inference.d.ts +37 -0
  344. package/dist/migrate/verb-inference.d.ts.map +1 -0
  345. package/dist/migrate/verb-inference.js +274 -0
  346. package/dist/migrate/verb-inference.js.map +1 -0
  347. package/dist/nac3/attrs.d.ts +87 -0
  348. package/dist/nac3/attrs.d.ts.map +1 -0
  349. package/dist/nac3/attrs.js +134 -0
  350. package/dist/nac3/attrs.js.map +1 -0
  351. package/dist/nac3/scenario_dsl.d.ts +71 -0
  352. package/dist/nac3/scenario_dsl.d.ts.map +1 -0
  353. package/dist/nac3/scenario_dsl.js +191 -0
  354. package/dist/nac3/scenario_dsl.js.map +1 -0
  355. package/dist/nac3/tokens.d.ts +126 -0
  356. package/dist/nac3/tokens.d.ts.map +1 -0
  357. package/dist/nac3/tokens.js +138 -0
  358. package/dist/nac3/tokens.js.map +1 -0
  359. package/dist/reader/parsers/csv.d.ts +42 -0
  360. package/dist/reader/parsers/csv.d.ts.map +1 -0
  361. package/dist/reader/parsers/csv.js +221 -0
  362. package/dist/reader/parsers/csv.js.map +1 -0
  363. package/dist/reader/parsers/docx.d.ts +31 -0
  364. package/dist/reader/parsers/docx.d.ts.map +1 -0
  365. package/dist/reader/parsers/docx.js +51 -0
  366. package/dist/reader/parsers/docx.js.map +1 -0
  367. package/dist/reader/parsers/epub.d.ts +39 -0
  368. package/dist/reader/parsers/epub.d.ts.map +1 -0
  369. package/dist/reader/parsers/epub.js +265 -0
  370. package/dist/reader/parsers/epub.js.map +1 -0
  371. package/dist/reader/parsers/html.d.ts +40 -0
  372. package/dist/reader/parsers/html.d.ts.map +1 -0
  373. package/dist/reader/parsers/html.js +386 -0
  374. package/dist/reader/parsers/html.js.map +1 -0
  375. package/dist/reader/parsers/md.d.ts +30 -0
  376. package/dist/reader/parsers/md.d.ts.map +1 -0
  377. package/dist/reader/parsers/md.js +199 -0
  378. package/dist/reader/parsers/md.js.map +1 -0
  379. package/dist/reader/parsers/pdf.d.ts +39 -0
  380. package/dist/reader/parsers/pdf.d.ts.map +1 -0
  381. package/dist/reader/parsers/pdf.js +220 -0
  382. package/dist/reader/parsers/pdf.js.map +1 -0
  383. package/dist/reader/parsers/rtf.d.ts +37 -0
  384. package/dist/reader/parsers/rtf.d.ts.map +1 -0
  385. package/dist/reader/parsers/rtf.js +347 -0
  386. package/dist/reader/parsers/rtf.js.map +1 -0
  387. package/dist/reader/parsers/source.d.ts +32 -0
  388. package/dist/reader/parsers/source.d.ts.map +1 -0
  389. package/dist/reader/parsers/source.js +122 -0
  390. package/dist/reader/parsers/source.js.map +1 -0
  391. package/dist/reader/parsers/txt.d.ts +25 -0
  392. package/dist/reader/parsers/txt.d.ts.map +1 -0
  393. package/dist/reader/parsers/txt.js +56 -0
  394. package/dist/reader/parsers/txt.js.map +1 -0
  395. package/dist/reader/parsers/xlsx.d.ts +33 -0
  396. package/dist/reader/parsers/xlsx.d.ts.map +1 -0
  397. package/dist/reader/parsers/xlsx.js +143 -0
  398. package/dist/reader/parsers/xlsx.js.map +1 -0
  399. package/dist/reader/registry.d.ts +39 -0
  400. package/dist/reader/registry.d.ts.map +1 -0
  401. package/dist/reader/registry.js +172 -0
  402. package/dist/reader/registry.js.map +1 -0
  403. package/dist/reader/search.d.ts +27 -0
  404. package/dist/reader/search.d.ts.map +1 -0
  405. package/dist/reader/search.js +77 -0
  406. package/dist/reader/search.js.map +1 -0
  407. package/dist/reader/state.d.ts +56 -0
  408. package/dist/reader/state.d.ts.map +1 -0
  409. package/dist/reader/state.js +179 -0
  410. package/dist/reader/state.js.map +1 -0
  411. package/dist/reader/types.d.ts +119 -0
  412. package/dist/reader/types.d.ts.map +1 -0
  413. package/dist/reader/types.js +23 -0
  414. package/dist/reader/types.js.map +1 -0
  415. package/dist/ship/run.d.ts +26 -0
  416. package/dist/ship/run.d.ts.map +1 -0
  417. package/dist/ship/run.js +123 -0
  418. package/dist/ship/run.js.map +1 -0
  419. package/dist/template/index.d.ts +50 -0
  420. package/dist/template/index.d.ts.map +1 -0
  421. package/dist/template/index.js +140 -0
  422. package/dist/template/index.js.map +1 -0
  423. package/dist/ui/colors.d.ts +13 -0
  424. package/dist/ui/colors.d.ts.map +1 -0
  425. package/dist/ui/colors.js +26 -0
  426. package/dist/ui/colors.js.map +1 -0
  427. package/dist/validate/index.d.ts +19 -0
  428. package/dist/validate/index.d.ts.map +1 -0
  429. package/dist/validate/index.js +181 -0
  430. package/dist/validate/index.js.map +1 -0
  431. package/dist/vault/catalog.d.ts +55 -0
  432. package/dist/vault/catalog.d.ts.map +1 -0
  433. package/dist/vault/catalog.js +424 -0
  434. package/dist/vault/catalog.js.map +1 -0
  435. package/dist/vault/crypto.d.ts +82 -0
  436. package/dist/vault/crypto.d.ts.map +1 -0
  437. package/dist/vault/crypto.js +173 -0
  438. package/dist/vault/crypto.js.map +1 -0
  439. package/dist/vault/git_askpass.d.ts +26 -0
  440. package/dist/vault/git_askpass.d.ts.map +1 -0
  441. package/dist/vault/git_askpass.js +104 -0
  442. package/dist/vault/git_askpass.js.map +1 -0
  443. package/dist/vault/migrator.d.ts +57 -0
  444. package/dist/vault/migrator.d.ts.map +1 -0
  445. package/dist/vault/migrator.js +204 -0
  446. package/dist/vault/migrator.js.map +1 -0
  447. package/dist/vault/redactor.d.ts +73 -0
  448. package/dist/vault/redactor.d.ts.map +1 -0
  449. package/dist/vault/redactor.js +182 -0
  450. package/dist/vault/redactor.js.map +1 -0
  451. package/dist/vault/store.d.ts +132 -0
  452. package/dist/vault/store.d.ts.map +1 -0
  453. package/dist/vault/store.js +335 -0
  454. package/dist/vault/store.js.map +1 -0
  455. package/dist/version.d.ts +8 -0
  456. package/dist/version.d.ts.map +1 -0
  457. package/dist/version.js +8 -0
  458. package/dist/version.js.map +1 -0
  459. package/dist/voice/chunker.d.ts +43 -0
  460. package/dist/voice/chunker.d.ts.map +1 -0
  461. package/dist/voice/chunker.js +133 -0
  462. package/dist/voice/chunker.js.map +1 -0
  463. package/dist/voice/config.d.ts +14 -0
  464. package/dist/voice/config.d.ts.map +1 -0
  465. package/dist/voice/config.js +51 -0
  466. package/dist/voice/config.js.map +1 -0
  467. package/dist/voice/intents.d.ts +71 -0
  468. package/dist/voice/intents.d.ts.map +1 -0
  469. package/dist/voice/intents.js +0 -0
  470. package/dist/voice/intents.js.map +1 -0
  471. package/dist/voice/providers/elevenlabs.d.ts +53 -0
  472. package/dist/voice/providers/elevenlabs.d.ts.map +1 -0
  473. package/dist/voice/providers/elevenlabs.js +159 -0
  474. package/dist/voice/providers/elevenlabs.js.map +1 -0
  475. package/dist/voice/providers/google.d.ts +56 -0
  476. package/dist/voice/providers/google.d.ts.map +1 -0
  477. package/dist/voice/providers/google.js +253 -0
  478. package/dist/voice/providers/google.js.map +1 -0
  479. package/dist/voice/providers/whisper.d.ts +44 -0
  480. package/dist/voice/providers/whisper.d.ts.map +1 -0
  481. package/dist/voice/providers/whisper.js +179 -0
  482. package/dist/voice/providers/whisper.js.map +1 -0
  483. package/dist/voice/registry.d.ts +35 -0
  484. package/dist/voice/registry.d.ts.map +1 -0
  485. package/dist/voice/registry.js +48 -0
  486. package/dist/voice/registry.js.map +1 -0
  487. package/dist/voice/router.d.ts +62 -0
  488. package/dist/voice/router.d.ts.map +1 -0
  489. package/dist/voice/router.js +175 -0
  490. package/dist/voice/router.js.map +1 -0
  491. package/dist/voice/types.d.ts +116 -0
  492. package/dist/voice/types.d.ts.map +1 -0
  493. package/dist/voice/types.js +22 -0
  494. package/dist/voice/types.js.map +1 -0
  495. package/dist/voice/voiceprint/enrollment.d.ts +36 -0
  496. package/dist/voice/voiceprint/enrollment.d.ts.map +1 -0
  497. package/dist/voice/voiceprint/enrollment.js +71 -0
  498. package/dist/voice/voiceprint/enrollment.js.map +1 -0
  499. package/dist/voice/voiceprint/identify.d.ts +16 -0
  500. package/dist/voice/voiceprint/identify.d.ts.map +1 -0
  501. package/dist/voice/voiceprint/identify.js +20 -0
  502. package/dist/voice/voiceprint/identify.js.map +1 -0
  503. package/dist/voice/voiceprint/liveness.d.ts +90 -0
  504. package/dist/voice/voiceprint/liveness.d.ts.map +1 -0
  505. package/dist/voice/voiceprint/liveness.js +251 -0
  506. package/dist/voice/voiceprint/liveness.js.map +1 -0
  507. package/dist/voice/voiceprint/match.d.ts +54 -0
  508. package/dist/voice/voiceprint/match.d.ts.map +1 -0
  509. package/dist/voice/voiceprint/match.js +88 -0
  510. package/dist/voice/voiceprint/match.js.map +1 -0
  511. package/dist/voice/voiceprint/providers/local-mfcc-stub.d.ts +44 -0
  512. package/dist/voice/voiceprint/providers/local-mfcc-stub.d.ts.map +1 -0
  513. package/dist/voice/voiceprint/providers/local-mfcc-stub.js +92 -0
  514. package/dist/voice/voiceprint/providers/local-mfcc-stub.js.map +1 -0
  515. package/dist/voice/voiceprint/store.d.ts +60 -0
  516. package/dist/voice/voiceprint/store.d.ts.map +1 -0
  517. package/dist/voice/voiceprint/store.js +155 -0
  518. package/dist/voice/voiceprint/store.js.map +1 -0
  519. package/dist/voice/voiceprint/trust.d.ts +90 -0
  520. package/dist/voice/voiceprint/trust.d.ts.map +1 -0
  521. package/dist/voice/voiceprint/trust.js +150 -0
  522. package/dist/voice/voiceprint/trust.js.map +1 -0
  523. package/dist/voice/voiceprint/types.d.ts +100 -0
  524. package/dist/voice/voiceprint/types.d.ts.map +1 -0
  525. package/dist/voice/voiceprint/types.js +23 -0
  526. package/dist/voice/voiceprint/types.js.map +1 -0
  527. package/dist/voice/wake.d.ts +64 -0
  528. package/dist/voice/wake.d.ts.map +1 -0
  529. package/dist/voice/wake.js +143 -0
  530. package/dist/voice/wake.js.map +1 -0
  531. package/docs/manuals/manual.ar.html +91 -0
  532. package/docs/manuals/manual.de.html +100 -0
  533. package/docs/manuals/manual.en.html +118 -0
  534. package/docs/manuals/manual.es.html +120 -0
  535. package/docs/manuals/manual.fr.html +102 -0
  536. package/docs/manuals/manual.hi.html +93 -0
  537. package/docs/manuals/manual.it.html +93 -0
  538. package/docs/manuals/manual.ja.html +97 -0
  539. package/docs/manuals/manual.pt.html +103 -0
  540. package/docs/manuals/manual.zh.html +89 -0
  541. package/package.json +94 -0
  542. package/src/i18n/catalogs/ar.json +86 -0
  543. package/src/i18n/catalogs/de.json +86 -0
  544. package/src/i18n/catalogs/en.json +86 -0
  545. package/src/i18n/catalogs/es.json +86 -0
  546. package/src/i18n/catalogs/fr.json +86 -0
  547. package/src/i18n/catalogs/hi.json +86 -0
  548. package/src/i18n/catalogs/it.json +86 -0
  549. package/src/i18n/catalogs/ja.json +86 -0
  550. package/src/i18n/catalogs/pt.json +86 -0
  551. package/src/i18n/catalogs/zh.json +86 -0
  552. package/templates/react-app/README.md +43 -0
  553. package/templates/react-app/index.html +12 -0
  554. package/templates/react-app/package.json +35 -0
  555. package/templates/react-app/src/App.tsx +106 -0
  556. package/templates/react-app/src/main.tsx +21 -0
  557. package/templates/react-app/src/nac/manifest.ts +46 -0
  558. package/templates/react-app/src/styles.css +68 -0
  559. package/templates/react-app/tsconfig.json +19 -0
  560. package/templates/react-app/vite.config.ts +12 -0
  561. package/templates/react-app/yujin.forge.json +15 -0
@@ -0,0 +1,39 @@
1
+ /**
2
+ * PDF parser for the document reader (V1.16 of HITO 1).
3
+ *
4
+ * Uses pdfjs-dist (Mozilla's pdf.js). PDF is dense + complex
5
+ * to hand-roll, and ADIP specs really need it -- accepting
6
+ * the ~3MB dependency was Pablo-approved.
7
+ *
8
+ * Pipeline:
9
+ * 1. pdfjs.getDocument(buffer).promise -> PDFDocumentProxy
10
+ * 2. for each page in document order:
11
+ * page.getTextContent() -> text items grouped by y
12
+ * coordinate -> reconstruct lines -> reconstruct
13
+ * paragraphs by blank-line breaks.
14
+ * 3. paragraph blocks; one section per page (with heading
15
+ * "Pagina N"). The first non-empty line of page 1 becomes
16
+ * the document title.
17
+ *
18
+ * Voice-readback choices:
19
+ * - One section per page so users can navigate "leeme la
20
+ * pagina 3".
21
+ * - "Pagina N" heading is concise enough not to clutter TTS.
22
+ * - Text items with very small font sizes (e.g. footnotes)
23
+ * fold into the surrounding paragraph -- the voice reader
24
+ * does not need typographic structure.
25
+ *
26
+ * Pathological inputs (encrypted PDFs, malformed XObjects)
27
+ * surface the pdfjs error message in a wrapper -- the voice
28
+ * reader stays alive.
29
+ *
30
+ * ASCII-only.
31
+ */
32
+ import type { NormalisedDocument } from '../types.js';
33
+ export interface ParsePdfOptions {
34
+ buffer: Buffer;
35
+ filename: string;
36
+ language?: string;
37
+ }
38
+ export declare function parsePdf(opts: ParsePdfOptions): Promise<NormalisedDocument>;
39
+ //# sourceMappingURL=pdf.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdf.d.ts","sourceRoot":"","sources":["../../../src/reader/parsers/pdf.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAkB,MAAM,aAAa,CAAC;AAEtE,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AA+HD,wBAAsB,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAmFjF"}
@@ -0,0 +1,220 @@
1
+ /**
2
+ * PDF parser for the document reader (V1.16 of HITO 1).
3
+ *
4
+ * Uses pdfjs-dist (Mozilla's pdf.js). PDF is dense + complex
5
+ * to hand-roll, and ADIP specs really need it -- accepting
6
+ * the ~3MB dependency was Pablo-approved.
7
+ *
8
+ * Pipeline:
9
+ * 1. pdfjs.getDocument(buffer).promise -> PDFDocumentProxy
10
+ * 2. for each page in document order:
11
+ * page.getTextContent() -> text items grouped by y
12
+ * coordinate -> reconstruct lines -> reconstruct
13
+ * paragraphs by blank-line breaks.
14
+ * 3. paragraph blocks; one section per page (with heading
15
+ * "Pagina N"). The first non-empty line of page 1 becomes
16
+ * the document title.
17
+ *
18
+ * Voice-readback choices:
19
+ * - One section per page so users can navigate "leeme la
20
+ * pagina 3".
21
+ * - "Pagina N" heading is concise enough not to clutter TTS.
22
+ * - Text items with very small font sizes (e.g. footnotes)
23
+ * fold into the surrounding paragraph -- the voice reader
24
+ * does not need typographic structure.
25
+ *
26
+ * Pathological inputs (encrypted PDFs, malformed XObjects)
27
+ * surface the pdfjs error message in a wrapper -- the voice
28
+ * reader stays alive.
29
+ *
30
+ * ASCII-only.
31
+ */
32
+ /** Reconstruct lines + paragraphs from a page's text items.
33
+ *
34
+ * pdf.js gives items in approximate reading order but with no
35
+ * paragraph structure. We:
36
+ * 1. Group items by y-coordinate (within 2 PDF units).
37
+ * 2. Sort each group by x-coordinate so left-to-right order
38
+ * is preserved.
39
+ * 3. Sort groups top-to-bottom (y descending; PDF coords
40
+ * grow upward).
41
+ * 4. Detect paragraph breaks when consecutive lines have
42
+ * large y-gaps (>= 1.5 * median line height) OR when a
43
+ * line ends with sentence punctuation followed by an
44
+ * indented next line.
45
+ */
46
+ function reconstructParagraphs(items) {
47
+ if (items.length === 0)
48
+ return [];
49
+ /* Group by quantised y (round to 2 PDF units). */
50
+ const buckets = new Map();
51
+ for (const it of items) {
52
+ if (!it.str || !it.transform || it.transform.length < 6)
53
+ continue;
54
+ const y = Math.round((it.transform[5] ?? 0) / 2) * 2;
55
+ if (!buckets.has(y))
56
+ buckets.set(y, []);
57
+ buckets.get(y).push(it);
58
+ }
59
+ /* Build lines top to bottom (y descending). */
60
+ const ys = Array.from(buckets.keys()).sort((a, b) => b - a);
61
+ const lines = [];
62
+ for (const y of ys) {
63
+ const bucket = buckets.get(y);
64
+ bucket.sort((a, b) => (a.transform[4] ?? 0) - (b.transform[4] ?? 0));
65
+ const text = bucket.map((it) => it.str).join('').replace(/\s+/g, ' ').trim();
66
+ if (text)
67
+ lines.push({ y, text });
68
+ }
69
+ if (lines.length === 0)
70
+ return [];
71
+ /* Median gap between consecutive lines. */
72
+ const gaps = [];
73
+ for (let i = 1; i < lines.length; i += 1) {
74
+ gaps.push((lines[i - 1].y) - (lines[i].y));
75
+ }
76
+ gaps.sort((a, b) => a - b);
77
+ const median = gaps[Math.floor(gaps.length / 2)] ?? 12;
78
+ const paragraphBreakAt = median * 1.6;
79
+ /* Build paragraphs. */
80
+ const paras = [];
81
+ let buf = lines[0].text;
82
+ for (let i = 1; i < lines.length; i += 1) {
83
+ const gap = (lines[i - 1].y) - (lines[i].y);
84
+ if (gap >= paragraphBreakAt) {
85
+ if (buf.trim())
86
+ paras.push(buf.trim());
87
+ buf = lines[i].text;
88
+ }
89
+ else {
90
+ /* Same paragraph -- hyphenated line break joins without
91
+ a space. */
92
+ if (buf.endsWith('-') && /^[a-zA-Z]/.test(lines[i].text)) {
93
+ buf = buf.slice(0, -1) + lines[i].text;
94
+ }
95
+ else {
96
+ buf += ' ' + lines[i].text;
97
+ }
98
+ }
99
+ }
100
+ if (buf.trim())
101
+ paras.push(buf.trim());
102
+ return paras;
103
+ }
104
+ /* Dynamic import wrapper -- pdfjs-dist is ESM only. */
105
+ async function loadPdfjs() {
106
+ /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
107
+ return await import('pdfjs-dist/legacy/build/pdf.mjs');
108
+ }
109
+ /** Resolve the path to pdf.worker.mjs inside the installed
110
+ * pdfjs-dist. pdfjs v4 requires workerSrc to be set even
111
+ * when disableWorker is true (the "fake worker" still loads
112
+ * the module). */
113
+ async function resolveWorkerSrc() {
114
+ /* createRequire is the most reliable cross-platform way to
115
+ find an installed module's actual file path under both
116
+ ESM and CJS. The ESM import shape varies across TS lib
117
+ versions; cast through unknown to get a stable handle. */
118
+ const mod = await import('node:module');
119
+ const createRequire = mod.createRequire
120
+ ?? mod.default.createRequire;
121
+ const require = createRequire(import.meta.url);
122
+ return require.resolve('pdfjs-dist/legacy/build/pdf.worker.mjs');
123
+ }
124
+ async function getDocument(buffer) {
125
+ const pdfjs = await loadPdfjs();
126
+ if (pdfjs.GlobalWorkerOptions && !pdfjs.GlobalWorkerOptions.workerSrc) {
127
+ pdfjs.GlobalWorkerOptions.workerSrc = await resolveWorkerSrc();
128
+ }
129
+ const loadingTask = pdfjs.getDocument({
130
+ data: new Uint8Array(buffer),
131
+ isEvalSupported: false,
132
+ useSystemFonts: true,
133
+ });
134
+ return await loadingTask.promise;
135
+ }
136
+ /* ----- document assembly ----- */
137
+ export async function parsePdf(opts) {
138
+ let doc;
139
+ try {
140
+ doc = await getDocument(opts.buffer);
141
+ }
142
+ catch (err) {
143
+ const msg = err instanceof Error ? err.message : String(err);
144
+ throw new Error('pdf: pdfjs could not open the document: ' + msg);
145
+ }
146
+ const sections = [];
147
+ let blockCounter = 0;
148
+ function nextId(prefix) {
149
+ blockCounter += 1;
150
+ return 's-' + prefix + '-' + blockCounter;
151
+ }
152
+ let title = '';
153
+ for (let pageNum = 1; pageNum <= doc.numPages; pageNum += 1) {
154
+ let page;
155
+ let content;
156
+ try {
157
+ page = await doc.getPage(pageNum);
158
+ content = await page.getTextContent();
159
+ }
160
+ catch (err) {
161
+ /* Skip the page rather than aborting -- voice reader
162
+ degrades to "pagina N: contenido ilegible". */
163
+ sections.push({
164
+ id: 's-' + pageNum,
165
+ heading: 'Pagina ' + pageNum,
166
+ level: 1,
167
+ blocks: [
168
+ { kind: 'heading', level: 1, text: 'Pagina ' + pageNum, id: nextId('h') },
169
+ { kind: 'paragraph', level: 0, text: 'Contenido ilegible.', id: nextId('p') },
170
+ ],
171
+ });
172
+ continue;
173
+ }
174
+ const paras = reconstructParagraphs(content.items);
175
+ if (pageNum === 1 && paras.length > 0 && !title) {
176
+ /* First non-empty line of page 1 becomes the title. */
177
+ const firstLine = paras[0].split(/[\n.;]/)[0].trim();
178
+ if (firstLine && firstLine.length < 120)
179
+ title = firstLine;
180
+ }
181
+ const heading = 'Pagina ' + pageNum;
182
+ const blocks = [
183
+ { kind: 'heading', level: 1, text: heading, id: nextId('h') },
184
+ ];
185
+ for (const p of paras) {
186
+ blocks.push({
187
+ kind: 'paragraph',
188
+ level: 0,
189
+ text: p,
190
+ id: nextId('p'),
191
+ });
192
+ }
193
+ sections.push({
194
+ id: 's-' + pageNum,
195
+ heading,
196
+ level: 1,
197
+ blocks,
198
+ });
199
+ }
200
+ if (sections.length === 0) {
201
+ sections.push({ id: 's-0', heading: '', level: 0, blocks: [] });
202
+ }
203
+ const docId = (opts.filename.split(/[\\/]/).pop() || 'doc')
204
+ .replace(/\.[^.]+$/, '')
205
+ .toLowerCase()
206
+ .replace(/[^a-z0-9]+/g, '-')
207
+ .replace(/^-+|-+$/g, '') || 'doc';
208
+ const out = {
209
+ id: docId,
210
+ filename: opts.filename,
211
+ format: 'pdf',
212
+ bytes: opts.buffer.length,
213
+ title: title || ('PDF (' + doc.numPages + ' pages)'),
214
+ sections,
215
+ };
216
+ if (opts.language !== undefined)
217
+ out.language = opts.language;
218
+ return out;
219
+ }
220
+ //# sourceMappingURL=pdf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdf.js","sourceRoot":"","sources":["../../../src/reader/parsers/pdf.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * RTF parser for the document reader (V1.20 of HITO 1).
3
+ *
4
+ * Tiny hand-rolled parser. No npm dep. RTF (Rich Text Format)
5
+ * is plain text with control words ({\rtf1 ... \par ... }),
6
+ * groups in {curly braces}, hex escapes (\'XX), and unicode
7
+ * escapes (\uNNNN). The parser walks the byte stream as a
8
+ * tiny state machine, dropping anything inside groups whose
9
+ * destination is metadata (fonttbl, colortbl, stylesheet,
10
+ * info, header, footer, pict, object, ...), and keeps the
11
+ * plain-text contents of the body.
12
+ *
13
+ * Paragraph breaks come from \par. Headings are detected
14
+ * heuristically (a line whose paragraph is fully bold and
15
+ * short, or a line tagged with \outlinelevelN, opens a new
16
+ * section). Plain paragraphs read as paragraph blocks.
17
+ *
18
+ * Bold/italic spans inside a paragraph are NOT preserved as
19
+ * structure -- they just contribute their text content. The
20
+ * reader spec doesn't need inline emphasis for voice readback;
21
+ * TTS prosody is handled elsewhere.
22
+ *
23
+ * Pathological inputs (mismatched braces, half-finished
24
+ * control words) degrade to "stop emitting and keep what we
25
+ * have so far" so the reader never crashes on a malformed
26
+ * file.
27
+ *
28
+ * ASCII-only.
29
+ */
30
+ import type { NormalisedDocument } from '../types.js';
31
+ export interface ParseRtfOptions {
32
+ buffer: Buffer;
33
+ filename: string;
34
+ language?: string;
35
+ }
36
+ export declare function parseRtf(opts: ParseRtfOptions): NormalisedDocument;
37
+ //# sourceMappingURL=rtf.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rtf.d.ts","sourceRoot":"","sources":["../../../src/reader/parsers/rtf.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAkB,MAAM,aAAa,CAAC;AAEtE,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAkSD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,kBAAkB,CA4ElE"}
@@ -0,0 +1,347 @@
1
+ /**
2
+ * RTF parser for the document reader (V1.20 of HITO 1).
3
+ *
4
+ * Tiny hand-rolled parser. No npm dep. RTF (Rich Text Format)
5
+ * is plain text with control words ({\rtf1 ... \par ... }),
6
+ * groups in {curly braces}, hex escapes (\'XX), and unicode
7
+ * escapes (\uNNNN). The parser walks the byte stream as a
8
+ * tiny state machine, dropping anything inside groups whose
9
+ * destination is metadata (fonttbl, colortbl, stylesheet,
10
+ * info, header, footer, pict, object, ...), and keeps the
11
+ * plain-text contents of the body.
12
+ *
13
+ * Paragraph breaks come from \par. Headings are detected
14
+ * heuristically (a line whose paragraph is fully bold and
15
+ * short, or a line tagged with \outlinelevelN, opens a new
16
+ * section). Plain paragraphs read as paragraph blocks.
17
+ *
18
+ * Bold/italic spans inside a paragraph are NOT preserved as
19
+ * structure -- they just contribute their text content. The
20
+ * reader spec doesn't need inline emphasis for voice readback;
21
+ * TTS prosody is handled elsewhere.
22
+ *
23
+ * Pathological inputs (mismatched braces, half-finished
24
+ * control words) degrade to "stop emitting and keep what we
25
+ * have so far" so the reader never crashes on a malformed
26
+ * file.
27
+ *
28
+ * ASCII-only.
29
+ */
30
+ /** Destinations whose content is metadata and should NOT
31
+ * appear in spoken text. When we enter a group whose first
32
+ * control word is one of these, we drop everything until the
33
+ * group closes. */
34
+ const DROP_DESTINATIONS = new Set([
35
+ 'fonttbl', 'colortbl', 'stylesheet', 'info', 'header',
36
+ 'footer', 'pict', 'object', 'shp', 'shppict', 'nonshppict',
37
+ 'datafield', 'panose', 'listtable', 'listoverridetable',
38
+ 'rsidtbl', 'mmathPr', 'themedata', 'colorschememapping',
39
+ 'latentstyles', 'datastore', 'wgrffmtfilter', 'xmlnstbl',
40
+ 'fldinst',
41
+ /* Document protection / revision tracking -- not useful
42
+ for voice readback. */
43
+ 'protect',
44
+ ]);
45
+ function emptyPara() {
46
+ return { spans: [], outline: -1, hadPlain: false, hadBold: false };
47
+ }
48
+ function paraText(p) {
49
+ return p.spans.map((s) => s.text).join('').replace(/\s+/g, ' ').trim();
50
+ }
51
+ function emit(state) {
52
+ const text = paraText(state.para);
53
+ if (text) {
54
+ state.out.push({
55
+ text,
56
+ outline: state.para.outline,
57
+ bold: state.para.hadBold && !state.para.hadPlain,
58
+ });
59
+ }
60
+ state.para = emptyPara();
61
+ }
62
+ function appendText(state, text) {
63
+ if (state.dropDepth >= 0)
64
+ return;
65
+ if (!text)
66
+ return;
67
+ /* Decide whether this run is bold for the "fully bold para
68
+ = heading" heuristic. */
69
+ state.para.spans.push({ text, bold: state.bold, outline: state.outline });
70
+ if (state.bold)
71
+ state.para.hadBold = true;
72
+ else
73
+ state.para.hadPlain = true;
74
+ }
75
+ /** Handle one control word (and its optional numeric arg). */
76
+ function handleControlWord(state, word, arg) {
77
+ /* Destination-introducing keywords. The RTF spec marks
78
+ destinations with a leading '*\\' but in practice we
79
+ can recognise them by name. */
80
+ if (DROP_DESTINATIONS.has(word)) {
81
+ state.dropDepth = state.depth;
82
+ return;
83
+ }
84
+ /* Skip the destination switch if we're already dropping. */
85
+ if (state.dropDepth >= 0)
86
+ return;
87
+ switch (word) {
88
+ case 'par':
89
+ case 'sect':
90
+ case 'page':
91
+ case 'line':
92
+ emit(state);
93
+ return;
94
+ case 'tab':
95
+ appendText(state, '\t');
96
+ return;
97
+ case 'b':
98
+ state.bold = arg === 0 ? false : true;
99
+ return;
100
+ case 'plain':
101
+ state.bold = false;
102
+ return;
103
+ case 'outlinelevel':
104
+ if (arg !== null && arg >= 0 && arg <= 5) {
105
+ state.outline = arg;
106
+ if (state.para.outline < 0 || arg < state.para.outline) {
107
+ state.para.outline = arg;
108
+ }
109
+ }
110
+ return;
111
+ default:
112
+ /* Unknown control word -> ignore. */
113
+ return;
114
+ }
115
+ }
116
+ /** Handle \'XX hex escape. Interprets as a single byte in
117
+ * CP1252 (the most common default RTF code page). For
118
+ * bytes < 0x80, this matches ASCII. */
119
+ function handleHexEscape(state, hex) {
120
+ const code = parseInt(hex, 16);
121
+ if (!isFinite(code))
122
+ return;
123
+ let ch;
124
+ if (code < 0x80) {
125
+ ch = String.fromCharCode(code);
126
+ }
127
+ else {
128
+ /* Map a few common CP1252 codepoints. Most RTF docs in
129
+ the wild use ASCII + utf-8 escapes; this fallback is
130
+ sufficient for voice readback. */
131
+ const CP1252 = {
132
+ 0x91: "'", 0x92: "'", 0x93: '"', 0x94: '"',
133
+ 0x95: '*', 0x96: '-', 0x97: '--', 0x85: '...',
134
+ 0x99: '(tm)', 0xa9: '(c)', 0xae: '(R)',
135
+ 0xa0: ' ',
136
+ };
137
+ ch = CP1252[code] || '?';
138
+ }
139
+ appendText(state, ch);
140
+ }
141
+ /** Handle \uNNNN unicode escape. RTF emits the code point as
142
+ * a signed 16-bit integer, optionally followed by a fallback
143
+ * ASCII character we must skip. */
144
+ function handleUnicodeEscape(state, value) {
145
+ /* Cast signed 16-bit to actual code point. */
146
+ let code = value;
147
+ if (code < 0)
148
+ code = code + 0x10000;
149
+ if (code >= 0 && code <= 0x10ffff) {
150
+ try {
151
+ appendText(state, String.fromCodePoint(code));
152
+ }
153
+ catch {
154
+ appendText(state, '?');
155
+ }
156
+ }
157
+ /* The fallback char count is \ucN; we don't track that
158
+ dynamically here -- assume default uc=1. */
159
+ return { skipChars: 1 };
160
+ }
161
+ function parseRtfBody(src) {
162
+ const state = {
163
+ src,
164
+ i: 0,
165
+ depth: 0,
166
+ dropDepth: -1,
167
+ bold: false,
168
+ outline: -1,
169
+ para: emptyPara(),
170
+ out: [],
171
+ };
172
+ while (state.i < state.src.length) {
173
+ const ch = state.src.charAt(state.i);
174
+ if (ch === '{') {
175
+ state.depth += 1;
176
+ state.i += 1;
177
+ continue;
178
+ }
179
+ if (ch === '}') {
180
+ state.depth -= 1;
181
+ /* Closing the group that started a drop ends the drop. */
182
+ if (state.dropDepth >= 0 && state.depth < state.dropDepth) {
183
+ state.dropDepth = -1;
184
+ }
185
+ state.i += 1;
186
+ continue;
187
+ }
188
+ if (ch === '\\') {
189
+ const next = state.src.charAt(state.i + 1);
190
+ /* Special single-char escapes. */
191
+ if (next === '\\' || next === '{' || next === '}') {
192
+ appendText(state, next);
193
+ state.i += 2;
194
+ continue;
195
+ }
196
+ if (next === '\n' || next === '\r') {
197
+ /* Backslash followed by newline = literal newline
198
+ paragraph break in some flavours. Treat as space. */
199
+ state.i += 2;
200
+ continue;
201
+ }
202
+ if (next === '*') {
203
+ /* Optional-destination prefix. The next control word
204
+ (if a destination) MUST be dropped; we just skip the
205
+ '*' and let the next token classify itself. */
206
+ state.i += 2;
207
+ continue;
208
+ }
209
+ if (next === "'") {
210
+ /* \'XX hex escape. */
211
+ const hex = state.src.substr(state.i + 2, 2);
212
+ handleHexEscape(state, hex);
213
+ state.i += 4;
214
+ continue;
215
+ }
216
+ if (next === 'u' && /[0-9-]/.test(state.src.charAt(state.i + 2) || '')) {
217
+ /* \uNNNN unicode escape. */
218
+ const m = state.src.slice(state.i + 1).match(/^u(-?\d+)/);
219
+ if (m) {
220
+ const result = handleUnicodeEscape(state, parseInt(m[1], 10));
221
+ state.i += 1 + m[0].length;
222
+ /* Skip the configured number of fallback chars. */
223
+ let skip = result.skipChars;
224
+ while (skip > 0 && state.i < state.src.length) {
225
+ const fc = state.src.charAt(state.i);
226
+ if (fc === ' ') {
227
+ state.i += 1;
228
+ skip -= 1;
229
+ continue;
230
+ }
231
+ if (fc === '\\') {
232
+ /* A fallback that itself is an escape -- bail. */
233
+ break;
234
+ }
235
+ state.i += 1;
236
+ skip -= 1;
237
+ }
238
+ continue;
239
+ }
240
+ }
241
+ /* Generic control word: \wordN where N is optional
242
+ signed numeric argument, optionally terminated by a
243
+ space. */
244
+ const m = state.src.slice(state.i + 1).match(/^([a-zA-Z]+)(-?\d+)?/);
245
+ if (!m) {
246
+ /* Stray backslash -- skip. */
247
+ state.i += 1;
248
+ continue;
249
+ }
250
+ const word = m[1].toLowerCase();
251
+ const arg = m[2] !== undefined ? parseInt(m[2], 10) : null;
252
+ state.i += 1 + m[0].length;
253
+ /* The control word may be terminated by a single space
254
+ that does NOT contribute to output. */
255
+ if (state.src.charAt(state.i) === ' ')
256
+ state.i += 1;
257
+ handleControlWord(state, word, arg);
258
+ continue;
259
+ }
260
+ /* Plain character. Drop CR/LF (RTF uses them as readability
261
+ breaks, not content). */
262
+ if (ch === '\r' || ch === '\n') {
263
+ state.i += 1;
264
+ continue;
265
+ }
266
+ appendText(state, ch);
267
+ state.i += 1;
268
+ }
269
+ /* Flush the final paragraph. */
270
+ emit(state);
271
+ return state.out;
272
+ }
273
+ /* ----- document assembly ----- */
274
+ export function parseRtf(opts) {
275
+ const text = opts.buffer.toString('utf-8');
276
+ const paras = parseRtfBody(text);
277
+ const sections = [];
278
+ let current = { id: 's-0', heading: '', level: 0, blocks: [] };
279
+ let sectionCounter = 0;
280
+ let blockCounter = 0;
281
+ let firstHeading = '';
282
+ function flush() {
283
+ if (current.blocks.length > 0 || current.heading)
284
+ sections.push(current);
285
+ }
286
+ function nextId(prefix) {
287
+ blockCounter += 1;
288
+ return 's-' + prefix + '-' + blockCounter;
289
+ }
290
+ function openSection(heading, level) {
291
+ flush();
292
+ sectionCounter += 1;
293
+ current = {
294
+ id: 's-' + sectionCounter,
295
+ heading,
296
+ level,
297
+ blocks: [{ kind: 'heading', level, text: heading, id: nextId('h') }],
298
+ };
299
+ }
300
+ for (const p of paras) {
301
+ /* Heading heuristics:
302
+ 1. explicit \outlinelevelN -> level = N+1.
303
+ 2. fully-bold short paragraph with no sentence punctuation
304
+ and <= 8 words -> heading at level 1. */
305
+ let level = 0;
306
+ if (p.outline >= 0) {
307
+ level = p.outline + 1;
308
+ }
309
+ else if (p.bold) {
310
+ const words = p.text.split(/\s+/).length;
311
+ if (words <= 8 && !/[.;:?!]$/.test(p.text)) {
312
+ level = 1;
313
+ }
314
+ }
315
+ const block = level > 0
316
+ ? { kind: 'heading', level, text: p.text, id: nextId('h') }
317
+ : { kind: 'paragraph', level: 0, text: p.text, id: nextId('p') };
318
+ if (level > 0) {
319
+ if (!firstHeading)
320
+ firstHeading = p.text;
321
+ openSection(p.text, level);
322
+ continue;
323
+ }
324
+ current.blocks.push(block);
325
+ }
326
+ flush();
327
+ if (sections.length === 0) {
328
+ sections.push({ id: 's-0', heading: '', level: 0, blocks: [] });
329
+ }
330
+ const docId = (opts.filename.split(/[\\/]/).pop() || 'doc')
331
+ .replace(/\.[^.]+$/, '')
332
+ .toLowerCase()
333
+ .replace(/[^a-z0-9]+/g, '-')
334
+ .replace(/^-+|-+$/g, '') || 'doc';
335
+ const doc = {
336
+ id: docId,
337
+ filename: opts.filename,
338
+ format: 'rtf',
339
+ bytes: opts.buffer.length,
340
+ title: firstHeading,
341
+ sections,
342
+ };
343
+ if (opts.language !== undefined)
344
+ doc.language = opts.language;
345
+ return doc;
346
+ }
347
+ //# sourceMappingURL=rtf.js.map