@alisio/plugin-thesis 0.1.0

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 (547) hide show
  1. package/.agents/agents/thesis-architect.md +38 -0
  2. package/.agents/agents/thesis-coordinator.md +39 -0
  3. package/.agents/agents/thesis-editor.md +35 -0
  4. package/.agents/agents/thesis-evidence-auditor.md +37 -0
  5. package/.agents/agents/thesis-librarian.md +38 -0
  6. package/.agents/agents/thesis-methodologist.md +39 -0
  7. package/.agents/agents/thesis-reviewer.md +36 -0
  8. package/.agents/agents/thesis-writer.md +38 -0
  9. package/.agents/skills/thesis-build/SKILL.md +48 -0
  10. package/.agents/skills/thesis-citations/SKILL.md +49 -0
  11. package/.agents/skills/thesis-csl-authoring/SKILL.md +48 -0
  12. package/.agents/skills/thesis-editing/SKILL.md +49 -0
  13. package/.agents/skills/thesis-evidence/SKILL.md +48 -0
  14. package/.agents/skills/thesis-figures/SKILL.md +50 -0
  15. package/.agents/skills/thesis-institution-norms/SKILL.md +50 -0
  16. package/.agents/skills/thesis-intake/SKILL.md +48 -0
  17. package/.agents/skills/thesis-math/SKILL.md +48 -0
  18. package/.agents/skills/thesis-methodology/SKILL.md +49 -0
  19. package/.agents/skills/thesis-outline/SKILL.md +48 -0
  20. package/.agents/skills/thesis-policy/SKILL.md +48 -0
  21. package/.agents/skills/thesis-review/SKILL.md +49 -0
  22. package/.agents/skills/thesis-search/SKILL.md +47 -0
  23. package/.agents/skills/thesis-writing/SKILL.md +52 -0
  24. package/LICENSE +21 -0
  25. package/README.es.md +242 -0
  26. package/README.md +235 -0
  27. package/THIRD_PARTY_NOTICES.md +94 -0
  28. package/assets/architecture.svg +1 -0
  29. package/assets/evidence-pipeline.svg +1 -0
  30. package/assets/lifecycle.svg +1 -0
  31. package/assets/policy-resolution.svg +1 -0
  32. package/cover.webp +0 -0
  33. package/dist/authoring.d.ts +30 -0
  34. package/dist/authoring.d.ts.map +1 -0
  35. package/dist/authoring.js +681 -0
  36. package/dist/authoring.js.map +1 -0
  37. package/dist/brief.d.ts +40 -0
  38. package/dist/brief.d.ts.map +1 -0
  39. package/dist/brief.js +566 -0
  40. package/dist/brief.js.map +1 -0
  41. package/dist/cache.d.ts +8 -0
  42. package/dist/cache.d.ts.map +1 -0
  43. package/dist/cache.js +20 -0
  44. package/dist/cache.js.map +1 -0
  45. package/dist/checks/brief.d.ts +5 -0
  46. package/dist/checks/brief.d.ts.map +1 -0
  47. package/dist/checks/brief.js +38 -0
  48. package/dist/checks/brief.js.map +1 -0
  49. package/dist/checks/citations.d.ts +14 -0
  50. package/dist/checks/citations.d.ts.map +1 -0
  51. package/dist/checks/citations.js +87 -0
  52. package/dist/checks/citations.js.map +1 -0
  53. package/dist/checks/claims.d.ts +16 -0
  54. package/dist/checks/claims.d.ts.map +1 -0
  55. package/dist/checks/claims.js +147 -0
  56. package/dist/checks/claims.js.map +1 -0
  57. package/dist/checks/closing.d.ts +20 -0
  58. package/dist/checks/closing.d.ts.map +1 -0
  59. package/dist/checks/closing.js +168 -0
  60. package/dist/checks/closing.js.map +1 -0
  61. package/dist/checks/design.d.ts +5 -0
  62. package/dist/checks/design.d.ts.map +1 -0
  63. package/dist/checks/design.js +107 -0
  64. package/dist/checks/design.js.map +1 -0
  65. package/dist/checks/document.d.ts +17 -0
  66. package/dist/checks/document.d.ts.map +1 -0
  67. package/dist/checks/document.js +213 -0
  68. package/dist/checks/document.js.map +1 -0
  69. package/dist/checks/evidence.d.ts +7 -0
  70. package/dist/checks/evidence.d.ts.map +1 -0
  71. package/dist/checks/evidence.js +133 -0
  72. package/dist/checks/evidence.js.map +1 -0
  73. package/dist/checks/hygiene.d.ts +5 -0
  74. package/dist/checks/hygiene.d.ts.map +1 -0
  75. package/dist/checks/hygiene.js +37 -0
  76. package/dist/checks/hygiene.js.map +1 -0
  77. package/dist/checks/index.d.ts +21 -0
  78. package/dist/checks/index.d.ts.map +1 -0
  79. package/dist/checks/index.js +98 -0
  80. package/dist/checks/index.js.map +1 -0
  81. package/dist/checks/language.d.ts +14 -0
  82. package/dist/checks/language.d.ts.map +1 -0
  83. package/dist/checks/language.js +73 -0
  84. package/dist/checks/language.js.map +1 -0
  85. package/dist/checks/outline.d.ts +25 -0
  86. package/dist/checks/outline.d.ts.map +1 -0
  87. package/dist/checks/outline.js +214 -0
  88. package/dist/checks/outline.js.map +1 -0
  89. package/dist/checks/policy.d.ts +5 -0
  90. package/dist/checks/policy.d.ts.map +1 -0
  91. package/dist/checks/policy.js +129 -0
  92. package/dist/checks/policy.js.map +1 -0
  93. package/dist/checks/project.d.ts +65 -0
  94. package/dist/checks/project.d.ts.map +1 -0
  95. package/dist/checks/project.js +203 -0
  96. package/dist/checks/project.js.map +1 -0
  97. package/dist/checks/styles.d.ts +12 -0
  98. package/dist/checks/styles.d.ts.map +1 -0
  99. package/dist/checks/styles.js +67 -0
  100. package/dist/checks/styles.js.map +1 -0
  101. package/dist/checks/writing.d.ts +6 -0
  102. package/dist/checks/writing.d.ts.map +1 -0
  103. package/dist/checks/writing.js +115 -0
  104. package/dist/checks/writing.js.map +1 -0
  105. package/dist/chrome/detect.d.ts +19 -0
  106. package/dist/chrome/detect.d.ts.map +1 -0
  107. package/dist/chrome/detect.js +116 -0
  108. package/dist/chrome/detect.js.map +1 -0
  109. package/dist/claims.d.ts +19 -0
  110. package/dist/claims.d.ts.map +1 -0
  111. package/dist/claims.js +99 -0
  112. package/dist/claims.js.map +1 -0
  113. package/dist/cli.d.ts +11 -0
  114. package/dist/cli.d.ts.map +1 -0
  115. package/dist/cli.js +262 -0
  116. package/dist/cli.js.map +1 -0
  117. package/dist/context.d.ts +55 -0
  118. package/dist/context.d.ts.map +1 -0
  119. package/dist/context.js +62 -0
  120. package/dist/context.js.map +1 -0
  121. package/dist/coordinator.d.ts +139 -0
  122. package/dist/coordinator.d.ts.map +1 -0
  123. package/dist/coordinator.js +710 -0
  124. package/dist/coordinator.js.map +1 -0
  125. package/dist/delegate.d.ts +34 -0
  126. package/dist/delegate.d.ts.map +1 -0
  127. package/dist/delegate.js +105 -0
  128. package/dist/delegate.js.map +1 -0
  129. package/dist/diffguard.d.ts +24 -0
  130. package/dist/diffguard.d.ts.map +1 -0
  131. package/dist/diffguard.js +92 -0
  132. package/dist/diffguard.js.map +1 -0
  133. package/dist/doctor.d.ts +34 -0
  134. package/dist/doctor.d.ts.map +1 -0
  135. package/dist/doctor.js +155 -0
  136. package/dist/doctor.js.map +1 -0
  137. package/dist/draft.d.ts +64 -0
  138. package/dist/draft.d.ts.map +1 -0
  139. package/dist/draft.js +801 -0
  140. package/dist/draft.js.map +1 -0
  141. package/dist/figure.d.ts +13 -0
  142. package/dist/figure.d.ts.map +1 -0
  143. package/dist/figure.js +143 -0
  144. package/dist/figure.js.map +1 -0
  145. package/dist/finalize.d.ts +29 -0
  146. package/dist/finalize.d.ts.map +1 -0
  147. package/dist/finalize.js +230 -0
  148. package/dist/finalize.js.map +1 -0
  149. package/dist/index.d.ts +33 -0
  150. package/dist/index.d.ts.map +1 -0
  151. package/dist/index.js +206 -0
  152. package/dist/index.js.map +1 -0
  153. package/dist/intake.d.ts +57 -0
  154. package/dist/intake.d.ts.map +1 -0
  155. package/dist/intake.js +772 -0
  156. package/dist/intake.js.map +1 -0
  157. package/dist/labels.d.ts +50 -0
  158. package/dist/labels.d.ts.map +1 -0
  159. package/dist/labels.js +98 -0
  160. package/dist/labels.js.map +1 -0
  161. package/dist/outline.d.ts +45 -0
  162. package/dist/outline.d.ts.map +1 -0
  163. package/dist/outline.js +148 -0
  164. package/dist/outline.js.map +1 -0
  165. package/dist/pack-commands.d.ts +18 -0
  166. package/dist/pack-commands.d.ts.map +1 -0
  167. package/dist/pack-commands.js +397 -0
  168. package/dist/pack-commands.js.map +1 -0
  169. package/dist/package-paths.d.ts +8 -0
  170. package/dist/package-paths.d.ts.map +1 -0
  171. package/dist/package-paths.js +13 -0
  172. package/dist/package-paths.js.map +1 -0
  173. package/dist/policy/context.d.ts +19 -0
  174. package/dist/policy/context.d.ts.map +1 -0
  175. package/dist/policy/context.js +62 -0
  176. package/dist/policy/context.js.map +1 -0
  177. package/dist/policy/ethics.d.ts +59 -0
  178. package/dist/policy/ethics.d.ts.map +1 -0
  179. package/dist/policy/ethics.js +106 -0
  180. package/dist/policy/ethics.js.map +1 -0
  181. package/dist/policy/kinds.d.ts +9 -0
  182. package/dist/policy/kinds.d.ts.map +1 -0
  183. package/dist/policy/kinds.js +68 -0
  184. package/dist/policy/kinds.js.map +1 -0
  185. package/dist/policy/packs.d.ts +53 -0
  186. package/dist/policy/packs.d.ts.map +1 -0
  187. package/dist/policy/packs.js +336 -0
  188. package/dist/policy/packs.js.map +1 -0
  189. package/dist/policy/resolver.d.ts +87 -0
  190. package/dist/policy/resolver.d.ts.map +1 -0
  191. package/dist/policy/resolver.js +337 -0
  192. package/dist/policy/resolver.js.map +1 -0
  193. package/dist/policy/rules.d.ts +65 -0
  194. package/dist/policy/rules.d.ts.map +1 -0
  195. package/dist/policy/rules.js +194 -0
  196. package/dist/policy/rules.js.map +1 -0
  197. package/dist/protocol.d.ts +46 -0
  198. package/dist/protocol.d.ts.map +1 -0
  199. package/dist/protocol.js +86 -0
  200. package/dist/protocol.js.map +1 -0
  201. package/dist/render/adapters/chrome-pdf/cdp.d.ts +36 -0
  202. package/dist/render/adapters/chrome-pdf/cdp.d.ts.map +1 -0
  203. package/dist/render/adapters/chrome-pdf/cdp.js +291 -0
  204. package/dist/render/adapters/chrome-pdf/cdp.js.map +1 -0
  205. package/dist/render/adapters/chrome-pdf/index.d.ts +10 -0
  206. package/dist/render/adapters/chrome-pdf/index.d.ts.map +1 -0
  207. package/dist/render/adapters/chrome-pdf/index.js +139 -0
  208. package/dist/render/adapters/chrome-pdf/index.js.map +1 -0
  209. package/dist/render/adapters/chrome-pdf/network.d.ts +7 -0
  210. package/dist/render/adapters/chrome-pdf/network.d.ts.map +1 -0
  211. package/dist/render/adapters/chrome-pdf/network.js +33 -0
  212. package/dist/render/adapters/chrome-pdf/network.js.map +1 -0
  213. package/dist/render/adapters/html-preview/index.d.ts +8 -0
  214. package/dist/render/adapters/html-preview/index.d.ts.map +1 -0
  215. package/dist/render/adapters/html-preview/index.js +62 -0
  216. package/dist/render/adapters/html-preview/index.js.map +1 -0
  217. package/dist/render/adapters/test-json/index.d.ts +8 -0
  218. package/dist/render/adapters/test-json/index.d.ts.map +1 -0
  219. package/dist/render/adapters/test-json/index.js +62 -0
  220. package/dist/render/adapters/test-json/index.js.map +1 -0
  221. package/dist/render/adapters/typst-pdf/emitter.d.ts +21 -0
  222. package/dist/render/adapters/typst-pdf/emitter.d.ts.map +1 -0
  223. package/dist/render/adapters/typst-pdf/emitter.js +259 -0
  224. package/dist/render/adapters/typst-pdf/emitter.js.map +1 -0
  225. package/dist/render/adapters/typst-pdf/escape.d.ts +14 -0
  226. package/dist/render/adapters/typst-pdf/escape.d.ts.map +1 -0
  227. package/dist/render/adapters/typst-pdf/escape.js +56 -0
  228. package/dist/render/adapters/typst-pdf/escape.js.map +1 -0
  229. package/dist/render/adapters/typst-pdf/index.d.ts +9 -0
  230. package/dist/render/adapters/typst-pdf/index.d.ts.map +1 -0
  231. package/dist/render/adapters/typst-pdf/index.js +154 -0
  232. package/dist/render/adapters/typst-pdf/index.js.map +1 -0
  233. package/dist/render/adapters/typst-pdf/profile.d.ts +3 -0
  234. package/dist/render/adapters/typst-pdf/profile.d.ts.map +1 -0
  235. package/dist/render/adapters/typst-pdf/profile.js +55 -0
  236. package/dist/render/adapters/typst-pdf/profile.js.map +1 -0
  237. package/dist/render/adapters/typst-pdf/runner.d.ts +52 -0
  238. package/dist/render/adapters/typst-pdf/runner.d.ts.map +1 -0
  239. package/dist/render/adapters/typst-pdf/runner.js +209 -0
  240. package/dist/render/adapters/typst-pdf/runner.js.map +1 -0
  241. package/dist/render/adapters/typst-pdf/setup.d.ts +30 -0
  242. package/dist/render/adapters/typst-pdf/setup.d.ts.map +1 -0
  243. package/dist/render/adapters/typst-pdf/setup.js +183 -0
  244. package/dist/render/adapters/typst-pdf/setup.js.map +1 -0
  245. package/dist/render/adapters/typst-pdf/version.d.ts +8 -0
  246. package/dist/render/adapters/typst-pdf/version.d.ts.map +1 -0
  247. package/dist/render/adapters/typst-pdf/version.js +14 -0
  248. package/dist/render/adapters/typst-pdf/version.js.map +1 -0
  249. package/dist/render/assemble.d.ts +28 -0
  250. package/dist/render/assemble.d.ts.map +1 -0
  251. package/dist/render/assemble.js +309 -0
  252. package/dist/render/assemble.js.map +1 -0
  253. package/dist/render/assets.d.ts +27 -0
  254. package/dist/render/assets.d.ts.map +1 -0
  255. package/dist/render/assets.js +232 -0
  256. package/dist/render/assets.js.map +1 -0
  257. package/dist/render/build.d.ts +43 -0
  258. package/dist/render/build.d.ts.map +1 -0
  259. package/dist/render/build.js +187 -0
  260. package/dist/render/build.js.map +1 -0
  261. package/dist/render/charts.d.ts +83 -0
  262. package/dist/render/charts.d.ts.map +1 -0
  263. package/dist/render/charts.js +633 -0
  264. package/dist/render/charts.js.map +1 -0
  265. package/dist/render/default-registry.d.ts +7 -0
  266. package/dist/render/default-registry.d.ts.map +1 -0
  267. package/dist/render/default-registry.js +15 -0
  268. package/dist/render/default-registry.js.map +1 -0
  269. package/dist/render/diagram-theme.d.ts +7 -0
  270. package/dist/render/diagram-theme.d.ts.map +1 -0
  271. package/dist/render/diagram-theme.js +50 -0
  272. package/dist/render/diagram-theme.js.map +1 -0
  273. package/dist/render/dialect.d.ts +23 -0
  274. package/dist/render/dialect.d.ts.map +1 -0
  275. package/dist/render/dialect.js +188 -0
  276. package/dist/render/dialect.js.map +1 -0
  277. package/dist/render/html/citations.d.ts +70 -0
  278. package/dist/render/html/citations.d.ts.map +1 -0
  279. package/dist/render/html/citations.js +371 -0
  280. package/dist/render/html/citations.js.map +1 -0
  281. package/dist/render/html/css.d.ts +14 -0
  282. package/dist/render/html/css.d.ts.map +1 -0
  283. package/dist/render/html/css.js +113 -0
  284. package/dist/render/html/css.js.map +1 -0
  285. package/dist/render/html/emitter.d.ts +20 -0
  286. package/dist/render/html/emitter.d.ts.map +1 -0
  287. package/dist/render/html/emitter.js +652 -0
  288. package/dist/render/html/emitter.js.map +1 -0
  289. package/dist/render/html/escape.d.ts +11 -0
  290. package/dist/render/html/escape.d.ts.map +1 -0
  291. package/dist/render/html/escape.js +32 -0
  292. package/dist/render/html/escape.js.map +1 -0
  293. package/dist/render/html/katex.d.ts +9 -0
  294. package/dist/render/html/katex.d.ts.map +1 -0
  295. package/dist/render/html/katex.js +39 -0
  296. package/dist/render/html/katex.js.map +1 -0
  297. package/dist/render/html/stage.d.ts +12 -0
  298. package/dist/render/html/stage.d.ts.map +1 -0
  299. package/dist/render/html/stage.js +30 -0
  300. package/dist/render/html/stage.js.map +1 -0
  301. package/dist/render/index.d.ts +5 -0
  302. package/dist/render/index.d.ts.map +1 -0
  303. package/dist/render/index.js +5 -0
  304. package/dist/render/index.js.map +1 -0
  305. package/dist/render/math.d.ts +9 -0
  306. package/dist/render/math.d.ts.map +1 -0
  307. package/dist/render/math.js +60 -0
  308. package/dist/render/math.js.map +1 -0
  309. package/dist/render/model.d.ts +233 -0
  310. package/dist/render/model.d.ts.map +1 -0
  311. package/dist/render/model.js +2 -0
  312. package/dist/render/model.js.map +1 -0
  313. package/dist/render/numbering.d.ts +51 -0
  314. package/dist/render/numbering.d.ts.map +1 -0
  315. package/dist/render/numbering.js +155 -0
  316. package/dist/render/numbering.js.map +1 -0
  317. package/dist/render/output-name.d.ts +4 -0
  318. package/dist/render/output-name.d.ts.map +1 -0
  319. package/dist/render/output-name.js +11 -0
  320. package/dist/render/output-name.js.map +1 -0
  321. package/dist/render/palettes.d.ts +22 -0
  322. package/dist/render/palettes.d.ts.map +1 -0
  323. package/dist/render/palettes.js +46 -0
  324. package/dist/render/palettes.js.map +1 -0
  325. package/dist/render/parse.d.ts +15 -0
  326. package/dist/render/parse.d.ts.map +1 -0
  327. package/dist/render/parse.js +637 -0
  328. package/dist/render/parse.js.map +1 -0
  329. package/dist/render/port.d.ts +79 -0
  330. package/dist/render/port.d.ts.map +1 -0
  331. package/dist/render/port.js +2 -0
  332. package/dist/render/port.js.map +1 -0
  333. package/dist/render/registry.d.ts +11 -0
  334. package/dist/render/registry.d.ts.map +1 -0
  335. package/dist/render/registry.js +21 -0
  336. package/dist/render/registry.js.map +1 -0
  337. package/dist/render/text.d.ts +13 -0
  338. package/dist/render/text.d.ts.map +1 -0
  339. package/dist/render/text.js +65 -0
  340. package/dist/render/text.js.map +1 -0
  341. package/dist/render/walk.d.ts +13 -0
  342. package/dist/render/walk.d.ts.map +1 -0
  343. package/dist/render/walk.js +69 -0
  344. package/dist/render/walk.js.map +1 -0
  345. package/dist/research/bibtex.d.ts +12 -0
  346. package/dist/research/bibtex.d.ts.map +1 -0
  347. package/dist/research/bibtex.js +99 -0
  348. package/dist/research/bibtex.js.map +1 -0
  349. package/dist/research/client.d.ts +112 -0
  350. package/dist/research/client.d.ts.map +1 -0
  351. package/dist/research/client.js +661 -0
  352. package/dist/research/client.js.map +1 -0
  353. package/dist/research/dossier.d.ts +31 -0
  354. package/dist/research/dossier.d.ts.map +1 -0
  355. package/dist/research/dossier.js +54 -0
  356. package/dist/research/dossier.js.map +1 -0
  357. package/dist/research/flow.d.ts +31 -0
  358. package/dist/research/flow.d.ts.map +1 -0
  359. package/dist/research/flow.js +635 -0
  360. package/dist/research/flow.js.map +1 -0
  361. package/dist/research/library.d.ts +79 -0
  362. package/dist/research/library.d.ts.map +1 -0
  363. package/dist/research/library.js +319 -0
  364. package/dist/research/library.js.map +1 -0
  365. package/dist/research/verify.d.ts +80 -0
  366. package/dist/research/verify.d.ts.map +1 -0
  367. package/dist/research/verify.js +307 -0
  368. package/dist/research/verify.js.map +1 -0
  369. package/dist/resources.d.ts +15 -0
  370. package/dist/resources.d.ts.map +1 -0
  371. package/dist/resources.js +148 -0
  372. package/dist/resources.js.map +1 -0
  373. package/dist/review.d.ts +22 -0
  374. package/dist/review.d.ts.map +1 -0
  375. package/dist/review.js +355 -0
  376. package/dist/review.js.map +1 -0
  377. package/dist/schemas.d.ts +252 -0
  378. package/dist/schemas.d.ts.map +1 -0
  379. package/dist/schemas.js +1020 -0
  380. package/dist/schemas.js.map +1 -0
  381. package/dist/sections.d.ts +30 -0
  382. package/dist/sections.d.ts.map +1 -0
  383. package/dist/sections.js +62 -0
  384. package/dist/sections.js.map +1 -0
  385. package/dist/storage.d.ts +21 -0
  386. package/dist/storage.d.ts.map +1 -0
  387. package/dist/storage.js +296 -0
  388. package/dist/storage.js.map +1 -0
  389. package/dist/style-commands.d.ts +15 -0
  390. package/dist/style-commands.d.ts.map +1 -0
  391. package/dist/style-commands.js +54 -0
  392. package/dist/style-commands.js.map +1 -0
  393. package/dist/styles/csl.d.ts +58 -0
  394. package/dist/styles/csl.d.ts.map +1 -0
  395. package/dist/styles/csl.js +112 -0
  396. package/dist/styles/csl.js.map +1 -0
  397. package/dist/styles/discovery.d.ts +45 -0
  398. package/dist/styles/discovery.d.ts.map +1 -0
  399. package/dist/styles/discovery.js +99 -0
  400. package/dist/styles/discovery.js.map +1 -0
  401. package/dist/styles/golden.d.ts +52 -0
  402. package/dist/styles/golden.d.ts.map +1 -0
  403. package/dist/styles/golden.js +216 -0
  404. package/dist/styles/golden.js.map +1 -0
  405. package/dist/styles/profile.d.ts +126 -0
  406. package/dist/styles/profile.d.ts.map +1 -0
  407. package/dist/styles/profile.js +582 -0
  408. package/dist/styles/profile.js.map +1 -0
  409. package/dist/styles/xml.d.ts +22 -0
  410. package/dist/styles/xml.d.ts.map +1 -0
  411. package/dist/styles/xml.js +179 -0
  412. package/dist/styles/xml.js.map +1 -0
  413. package/dist/types.d.ts +285 -0
  414. package/dist/types.d.ts.map +1 -0
  415. package/dist/types.js +155 -0
  416. package/dist/types.js.map +1 -0
  417. package/dist/typst-pins.d.ts +16 -0
  418. package/dist/typst-pins.d.ts.map +1 -0
  419. package/dist/typst-pins.js +39 -0
  420. package/dist/typst-pins.js.map +1 -0
  421. package/dist/version.d.ts +2 -0
  422. package/dist/version.d.ts.map +1 -0
  423. package/dist/version.js +3 -0
  424. package/dist/version.js.map +1 -0
  425. package/dist/workflow.d.ts +49 -0
  426. package/dist/workflow.d.ts.map +1 -0
  427. package/dist/workflow.js +722 -0
  428. package/dist/workflow.js.map +1 -0
  429. package/dist/workspace.d.ts +12 -0
  430. package/dist/workspace.d.ts.map +1 -0
  431. package/dist/workspace.js +71 -0
  432. package/dist/workspace.js.map +1 -0
  433. package/package.json +70 -0
  434. package/policy-packs/countries/CO/academic-standards/ntc-1486-2022.yaml +188 -0
  435. package/policy-packs/countries/CO/copyright/decision-andina-351.yaml +61 -0
  436. package/policy-packs/countries/CO/copyright/ley-1915-2018.yaml +25 -0
  437. package/policy-packs/countries/CO/copyright/ley-23-1982.yaml +64 -0
  438. package/policy-packs/countries/CO/domains/health/resolucion-8430-1993.yaml +219 -0
  439. package/policy-packs/countries/CO/higher-education/ley-30-1992.yaml +61 -0
  440. package/policy-packs/countries/CO/manifest.yaml +42 -0
  441. package/policy-packs/countries/CO/official-domains.yaml +90 -0
  442. package/policy-packs/countries/CO/privacy/ley-1581-2012.yaml +197 -0
  443. package/policy-packs/countries/CO/research-integrity/minciencias-res-0314-2018.yaml +64 -0
  444. package/policy-packs/global/academic-integrity.yaml +45 -0
  445. package/policy-packs/global/academic-writing.yaml +70 -0
  446. package/policy-packs/global/evidence-quality.yaml +81 -0
  447. package/policy-packs/global/manifest.yaml +54 -0
  448. package/policy-packs/global/objective-verbs.yaml +245 -0
  449. package/policy-packs/global/reporting-guidelines.yaml +392 -0
  450. package/policy-packs/global/work-types.yaml +195 -0
  451. package/styles/LICENSE-CSL +375 -0
  452. package/styles/apa.csl +2283 -0
  453. package/styles/catalog.json +43 -0
  454. package/styles/fixtures/apa-7.expected.json +25 -0
  455. package/styles/fixtures/icontec-ntc1486-2022.expected.json +25 -0
  456. package/styles/fixtures/ieee.expected.json +25 -0
  457. package/styles/fixtures/references.jsonl +8 -0
  458. package/styles/icontec-ntc1486-2022.csl +388 -0
  459. package/styles/ieee.csl +519 -0
  460. package/templates/html/runtime.js +159 -0
  461. package/templates/html/thesis.css +98 -0
  462. package/templates/html/vendor/katex/LICENSE +21 -0
  463. package/templates/html/vendor/katex/fonts/KaTeX_AMS-Regular.woff2 +0 -0
  464. package/templates/html/vendor/katex/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
  465. package/templates/html/vendor/katex/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
  466. package/templates/html/vendor/katex/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
  467. package/templates/html/vendor/katex/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
  468. package/templates/html/vendor/katex/fonts/KaTeX_Main-Bold.woff2 +0 -0
  469. package/templates/html/vendor/katex/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
  470. package/templates/html/vendor/katex/fonts/KaTeX_Main-Italic.woff2 +0 -0
  471. package/templates/html/vendor/katex/fonts/KaTeX_Main-Regular.woff2 +0 -0
  472. package/templates/html/vendor/katex/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
  473. package/templates/html/vendor/katex/fonts/KaTeX_Math-Italic.woff2 +0 -0
  474. package/templates/html/vendor/katex/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
  475. package/templates/html/vendor/katex/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
  476. package/templates/html/vendor/katex/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
  477. package/templates/html/vendor/katex/fonts/KaTeX_Script-Regular.woff2 +0 -0
  478. package/templates/html/vendor/katex/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  479. package/templates/html/vendor/katex/fonts/KaTeX_Size2-Regular.woff2 +0 -0
  480. package/templates/html/vendor/katex/fonts/KaTeX_Size3-Regular.woff2 +0 -0
  481. package/templates/html/vendor/katex/fonts/KaTeX_Size4-Regular.woff2 +0 -0
  482. package/templates/html/vendor/katex/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
  483. package/templates/html/vendor/katex/katex.min.css +1 -0
  484. package/templates/html/vendor/katex/katex.min.js +1 -0
  485. package/templates/html/vendor/mermaid/LICENSE +21 -0
  486. package/templates/html/vendor/mermaid/mermaid.min.js +3587 -0
  487. package/templates/html/vendor/pagedjs/LICENSE +21 -0
  488. package/templates/html/vendor/pagedjs/paged.polyfill.min.js +4 -0
  489. package/templates/palettes.json +57 -0
  490. package/templates/profiles/apa-7.profile.yaml +15 -0
  491. package/templates/profiles/generic.profile.yaml +20 -0
  492. package/templates/profiles/icontec-ntc1486-2022.profile.yaml +36 -0
  493. package/templates/profiles/ieee.profile.yaml +14 -0
  494. package/templates/typst/i18n/en.yaml +31 -0
  495. package/templates/typst/i18n/es.yaml +31 -0
  496. package/templates/typst/i18n/pt.yaml +31 -0
  497. package/templates/typst/thesis.typ +276 -0
  498. package/typst-packages/preview/merman/0.3.0/LICENSE +231 -0
  499. package/typst-packages/preview/merman/0.3.0/README.md +388 -0
  500. package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/cose-base-v1/LICENSE +21 -0
  501. package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/cose-base-v2/LICENSE +21 -0
  502. package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/cytoscape/LICENSE +19 -0
  503. package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/cytoscape-cose-bilkent/LICENSE +21 -0
  504. package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/cytoscape-fcose/LICENSE +19 -0
  505. package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/d3-shape/LICENSE +13 -0
  506. package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/dagre/LICENSE +19 -0
  507. package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/dompurify/LICENSE +202 -0
  508. package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/eclipse-elk/LICENSE.md +264 -0
  509. package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/elkjs/LICENSE.md +264 -0
  510. package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/fmin/LICENSE +27 -0
  511. package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/graphlib/LICENSE +19 -0
  512. package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/layout-base-v1/LICENSE +21 -0
  513. package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/layout-base-v2/LICENSE +21 -0
  514. package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/mermaid/LICENSE +21 -0
  515. package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/rough-rs/LICENSE +21 -0
  516. package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/roughjs/LICENSE +21 -0
  517. package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/sanitize-url/LICENSE +21 -0
  518. package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/venn-js/LICENSE +22 -0
  519. package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/wasm-minimal-protocol/LICENSE +24 -0
  520. package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_LICENSES/zenuml-core/LICENSE +21 -0
  521. package/typst-packages/preview/merman/0.3.0/THIRD_PARTY_NOTICES.md +265 -0
  522. package/typst-packages/preview/merman/0.3.0/lib.typ +1 -0
  523. package/typst-packages/preview/merman/0.3.0/merman_typst_plugin.wasm +0 -0
  524. package/typst-packages/preview/merman/0.3.0/src/capabilities.typ +5 -0
  525. package/typst-packages/preview/merman/0.3.0/src/context.typ +1 -0
  526. package/typst-packages/preview/merman/0.3.0/src/errors.typ +33 -0
  527. package/typst-packages/preview/merman/0.3.0/src/exports.typ +5 -0
  528. package/typst-packages/preview/merman/0.3.0/src/figure.typ +143 -0
  529. package/typst-packages/preview/merman/0.3.0/src/image.typ +50 -0
  530. package/typst-packages/preview/merman/0.3.0/src/options.typ +566 -0
  531. package/typst-packages/preview/merman/0.3.0/src/plugin.typ +1 -0
  532. package/typst-packages/preview/merman/0.3.0/src/raw.typ +22 -0
  533. package/typst-packages/preview/merman/0.3.0/src/render.typ +137 -0
  534. package/typst-packages/preview/merman/0.3.0/src/source.typ +7 -0
  535. package/typst-packages/preview/merman/0.3.0/src/units.typ +51 -0
  536. package/typst-packages/preview/merman/0.3.0/typst.toml +12 -0
  537. package/typst-packages/preview/mitex/0.2.7/CHANGELOG.md +69 -0
  538. package/typst-packages/preview/mitex/0.2.7/LICENSE +176 -0
  539. package/typst-packages/preview/mitex/0.2.7/README.md +154 -0
  540. package/typst-packages/preview/mitex/0.2.7/lib.typ +1 -0
  541. package/typst-packages/preview/mitex/0.2.7/mitex.typ +45 -0
  542. package/typst-packages/preview/mitex/0.2.7/mitex.wasm +0 -0
  543. package/typst-packages/preview/mitex/0.2.7/specs/README.md +250 -0
  544. package/typst-packages/preview/mitex/0.2.7/specs/latex/standard.typ +1187 -0
  545. package/typst-packages/preview/mitex/0.2.7/specs/mod.typ +12 -0
  546. package/typst-packages/preview/mitex/0.2.7/specs/prelude.typ +230 -0
  547. package/typst-packages/preview/mitex/0.2.7/typst.toml +12 -0
@@ -0,0 +1,710 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { join, relative } from "node:path";
3
+ import { isValidLanguageTag, loadBrief } from "./brief.js";
4
+ import { cacheRoot } from "./cache.js";
5
+ import { formatReport, loadProject, parseGates, runChecks, } from "./checks/index.js";
6
+ import { Blocked } from "./context.js";
7
+ import { Delegator } from "./delegate.js";
8
+ import { formatDoctor, runDoctor } from "./doctor.js";
9
+ import { acceptAnswers, buildBriefText, buildRound, defaultRounds, flattenAnswers, hintFromEnvironment, icontecRound, intakeIntent, parseAnswerText, presentationRound, renderPending, seedAnswersFromRaw, } from "./intake.js";
10
+ import { checkPacks, explain, listPacks, newPack } from "./pack-commands.js";
11
+ import { setupTypst } from "./render/adapters/typst-pdf/setup.js";
12
+ import { buildThesis } from "./render/build.js";
13
+ import { createDefaultRegistry } from "./render/default-registry.js";
14
+ import { parseIdentifier, parseSearchInput, ScholarClient, } from "./research/client.js";
15
+ import { parseAddedSource } from "./research/flow.js";
16
+ import { classifyHost, officialDomainsFromProfile, resolveChecked, suggestStatus, } from "./research/verify.js";
17
+ import { atomicWrite, canonicalJson, defaultState, readState, validateRootName, writeState, } from "./storage.js";
18
+ import { checkStyleFiles, listStyles } from "./style-commands.js";
19
+ import { idPatterns } from "./types.js";
20
+ import { Workflow } from "./workflow.js";
21
+ import { createWorkspaceTree, refreshProject, thesisRootPath, writeCheckReport, } from "./workspace.js";
22
+ /** Plain-text build summary shared by the command and the CLI. */
23
+ export function formatBuild(outcome) {
24
+ const errors = outcome.findings.filter((finding) => finding.severity === "error");
25
+ const lines = [
26
+ outcome.ok
27
+ ? `Build OK (${outcome.scope}): ${outcome.path ?? "no file"}`
28
+ : `Build failed (${outcome.scope}): ${errors.length} error(s)`,
29
+ `Engine: ${outcome.engine}${outcome.pages === undefined ? "" : `; ${outcome.pages} page(s)`}; ${outcome.ms} ms`,
30
+ ];
31
+ for (const finding of errors.slice(0, 10)) {
32
+ lines.push(`ERROR ${finding.code}${finding.file ? ` ${finding.file}${finding.line ? `:${finding.line}` : ""}` : ""} ${finding.message}${finding.hint ? ` (${finding.hint})` : ""}`);
33
+ }
34
+ if (errors.length > 10)
35
+ lines.push(`... and ${errors.length - 10} more error(s)`);
36
+ for (const warning of outcome.warnings.slice(0, 5))
37
+ lines.push(`warning ${warning}`);
38
+ if (outcome.warnings.length > 5)
39
+ lines.push(`... and ${outcome.warnings.length - 5} more warning(s)`);
40
+ return lines.join("\n");
41
+ }
42
+ /** A phase command that cannot run yet answers with its reason instead of failing. */
43
+ async function blockable(run) {
44
+ try {
45
+ return await run();
46
+ }
47
+ catch (error) {
48
+ if (error instanceof Blocked)
49
+ return `Blocked: ${error.message}`;
50
+ throw error;
51
+ }
52
+ }
53
+ /** Split `<target> -- <text>` into its two parts; the text is empty when there is no delimiter. */
54
+ function splitDelimited(args) {
55
+ const delimiter = args.search(/(^|\s)--(\s|$)/);
56
+ if (delimiter < 0)
57
+ return { head: args.trim(), text: "" };
58
+ const marker = args.indexOf("--", delimiter);
59
+ return { head: args.slice(0, marker).trim(), text: args.slice(marker + 2).trim() };
60
+ }
61
+ function tokens(args) {
62
+ return args.trim().split(/\s+/).filter(Boolean);
63
+ }
64
+ export class ThesisCoordinator {
65
+ api;
66
+ now;
67
+ env;
68
+ projectOptions;
69
+ scholar;
70
+ workflow;
71
+ registry;
72
+ setupDeps;
73
+ constructor(api, options = {}) {
74
+ this.api = api;
75
+ this.registry = options.registry ?? createDefaultRegistry();
76
+ this.setupDeps = options.setupDeps;
77
+ this.now = options.now ?? (() => new Date());
78
+ this.env = options.env ?? process.env;
79
+ this.projectOptions = options.packsRoot ? { packsRoot: options.packsRoot } : {};
80
+ this.scholar = options.scholar ?? new ScholarClient({ env: this.env });
81
+ this.workflow = new Workflow({
82
+ api,
83
+ now: this.now,
84
+ projectOptions: this.projectOptions,
85
+ scholar: this.scholar,
86
+ delegator: new Delegator(api),
87
+ env: this.env,
88
+ cacheRoot: () => this.cacheRoot(),
89
+ build: (workspace, input) => this.buildRun(workspace, input),
90
+ });
91
+ }
92
+ workspace(sessionId) {
93
+ if (!sessionId)
94
+ throw new Error("Thesis commands require an active Alisio session");
95
+ return this.api.sessions.workspace(sessionId);
96
+ }
97
+ async requireState(workspace) {
98
+ const state = await readState(workspace);
99
+ if (!state)
100
+ throw new Error("No thesis workspace here. Run /thesis:init first.");
101
+ return state;
102
+ }
103
+ // ------------------------------------------------------------------------------------------
104
+ // /thesis:init
105
+ // ------------------------------------------------------------------------------------------
106
+ async init(args, sessionId) {
107
+ const workspace = this.workspace(sessionId);
108
+ let directory;
109
+ let hintArgument;
110
+ let presentation = false;
111
+ const parts = tokens(args);
112
+ for (let index = 0; index < parts.length; index += 1) {
113
+ const part = parts[index];
114
+ if (part === "--presentation")
115
+ presentation = true;
116
+ else if (part === "--lang") {
117
+ index += 1;
118
+ hintArgument = parts[index];
119
+ if (!hintArgument)
120
+ throw new Error("--lang needs a BCP-47 tag");
121
+ }
122
+ else if (part.startsWith("--"))
123
+ throw new Error(`Unknown option ${part}`);
124
+ else if (directory === undefined)
125
+ directory = part;
126
+ else
127
+ throw new Error("Usage: /thesis:init [dir] [--lang <bcp47>] [--presentation]");
128
+ }
129
+ if (directory !== undefined)
130
+ validateRootName(directory);
131
+ if (hintArgument !== undefined && !isValidLanguageTag(hintArgument)) {
132
+ throw new Error("--lang must be a well-formed BCP-47 tag such as es-CO");
133
+ }
134
+ let state = await readState(workspace);
135
+ if (state && directory !== undefined && directory !== state.root) {
136
+ throw new Error(`A thesis workspace already exists at "${state.root}"; it cannot be moved with init`);
137
+ }
138
+ const fresh = !state;
139
+ state ??= defaultState(directory ?? "thesis");
140
+ const base = await createWorkspaceTree(workspace, state.root);
141
+ if (fresh) {
142
+ try {
143
+ const existing = loadBrief(await readFile(join(base, "thesis.yaml"), "utf8"));
144
+ if (existing.raw)
145
+ state.intake.answers = seedAnswersFromRaw(existing.raw);
146
+ }
147
+ catch (error) {
148
+ if (error.code !== "ENOENT")
149
+ throw error;
150
+ }
151
+ }
152
+ if (hintArgument) {
153
+ state.intake.languageHint = hintArgument;
154
+ }
155
+ else {
156
+ state.intake.languageHint ??= hintFromEnvironment(this.env);
157
+ }
158
+ if (presentation) {
159
+ if (![1, 2].every((round) => state.intake.completedRounds.includes(round))) {
160
+ throw new Error("Finish interview rounds 1 and 2 before the presentation settings (/thesis:init)");
161
+ }
162
+ }
163
+ await writeState(workspace, state);
164
+ const message = await this.advance(workspace, state, presentation ? await this.presentationRounds(workspace, state) : defaultRounds);
165
+ return fresh ? `Created the thesis workspace at ${state.root}/.\n\n${message}` : message;
166
+ }
167
+ /** Round 4, plus the ICONTEC questions (round 5) when that profile is selected. */
168
+ async presentationRounds(workspace, state) {
169
+ let icontec = state.intake.answers.citationStyle === "icontec-ntc1486-2022";
170
+ if (!icontec) {
171
+ try {
172
+ const base = await thesisRootPath(workspace, state.root);
173
+ const profile = JSON.parse(await readFile(join(base, "compliance-profile.json"), "utf8"));
174
+ icontec = profile?.presentationStandard?.value === "icontec-ntc1486-2022";
175
+ }
176
+ catch {
177
+ icontec = false;
178
+ }
179
+ }
180
+ return icontec ? [presentationRound, icontecRound] : [presentationRound];
181
+ }
182
+ /** Drive the interview: ask interactively, or park the round as pending questions. */
183
+ async advance(workspace, state, rounds) {
184
+ const hint = state.intake.languageHint ?? "en";
185
+ for (const round of rounds) {
186
+ if (state.intake.completedRounds.includes(round))
187
+ continue;
188
+ let questions = buildRound(round, state.intake.answers, hint);
189
+ while (questions.length > 0) {
190
+ if (!this.api.ui.interactive())
191
+ return this.park(workspace, state, round, questions);
192
+ const asked = await this.api.ui.askQuestions({ questions, label: "Thesis interview" });
193
+ const { accepted, errors } = acceptAnswers(questions, flattenAnswers(asked), hint);
194
+ Object.assign(state.intake.answers, accepted);
195
+ const remaining = buildRound(round, state.intake.answers, hint);
196
+ if (errors.length > 0 || remaining.length === questions.length) {
197
+ return this.park(workspace, state, round, remaining, errors);
198
+ }
199
+ questions = remaining;
200
+ }
201
+ await this.completeRound(workspace, state, round);
202
+ }
203
+ delete state.pendingQuestions;
204
+ await writeState(workspace, state);
205
+ return this.summary(workspace, state);
206
+ }
207
+ async park(workspace, state, round, questions, errors = []) {
208
+ state.pendingQuestions = { round, createdAt: this.now().toISOString(), questions };
209
+ await writeState(workspace, state);
210
+ const prefix = errors.length
211
+ ? `Some answers were not accepted:\n- ${errors.join("\n- ")}\n\n`
212
+ : "";
213
+ return `${prefix}${renderPending(state.pendingQuestions)}`;
214
+ }
215
+ /** Persist everything a finished round produces: brief, profile, G0, intent, state. */
216
+ async completeRound(workspace, state, round) {
217
+ const base = await thesisRootPath(workspace, state.root);
218
+ let existing;
219
+ try {
220
+ const parsed = loadBrief(await readFile(join(base, "thesis.yaml"), "utf8"));
221
+ if (!parsed.raw)
222
+ throw new Error("thesis.yaml is not valid YAML; fix it and run /thesis:init again");
223
+ existing = parsed.raw;
224
+ }
225
+ catch (error) {
226
+ if (error.code !== "ENOENT")
227
+ throw error;
228
+ }
229
+ const built = buildBriefText(state.intake.answers, existing, {
230
+ hint: state.intake.languageHint ?? "en",
231
+ year: this.now().getFullYear(),
232
+ });
233
+ if (!built.text) {
234
+ throw new Error(`thesis.yaml cannot be updated from the answers:\n- ${built.errors.join("\n- ")}`);
235
+ }
236
+ await atomicWrite(join(base, "thesis.yaml"), built.text);
237
+ if (round === 3)
238
+ await atomicWrite(join(base, "research", "intake.json"), canonicalJson(intakeIntent(state.intake.answers)));
239
+ if (!state.intake.completedRounds.includes(round))
240
+ state.intake.completedRounds.push(round);
241
+ state.intake.completedRounds.sort();
242
+ delete state.pendingQuestions;
243
+ const report = await this.runG0(base);
244
+ state.lastCheck = {
245
+ at: report.at,
246
+ errors: report.counts.error,
247
+ warnings: report.counts.warning,
248
+ };
249
+ if (state.phase === "intake" &&
250
+ [1, 2].every((needed) => state.intake.completedRounds.includes(needed)) &&
251
+ report.ok) {
252
+ state.phase = "design";
253
+ }
254
+ await writeState(workspace, state);
255
+ }
256
+ async runG0(base) {
257
+ const project = await refreshProject(base, this.projectOptions);
258
+ const report = runChecks(project, { gates: ["G0"], now: this.now });
259
+ await writeCheckReport(base, report);
260
+ return report;
261
+ }
262
+ async summary(workspace, state) {
263
+ const base = await thesisRootPath(workspace, state.root);
264
+ const lines = [`Interview complete for ${state.root}/.`];
265
+ const brief = loadBrief(await readFile(join(base, "thesis.yaml"), "utf8")).brief;
266
+ const project = await loadProject(base, this.projectOptions);
267
+ if (brief && project.profile) {
268
+ lines.push(`Language ${brief.language}, ${brief.workType}, country ${brief.institution.country}.`, `Citation style: ${project.profile.citationStyle.value}${project.profile.citationStyle.defaulted ? " (default; confirm with your program)" : ""}.`, "Wrote thesis.yaml and compliance-profile.json.");
269
+ }
270
+ if (state.lastCheck) {
271
+ lines.push(`G0: ${state.lastCheck.errors} error(s), ${state.lastCheck.warnings} warning(s). Run /thesis:check for details.`);
272
+ }
273
+ lines.push(this.nextStep(state));
274
+ return lines.join("\n");
275
+ }
276
+ // ------------------------------------------------------------------------------------------
277
+ // /thesis:answer
278
+ // ------------------------------------------------------------------------------------------
279
+ async answer(args, sessionId) {
280
+ const workspace = this.workspace(sessionId);
281
+ const state = await this.requireState(workspace);
282
+ const pending = state.pendingQuestions;
283
+ if (!pending)
284
+ throw new Error("There are no pending interview questions. Run /thesis:init to continue.");
285
+ const hint = state.intake.languageHint ?? "en";
286
+ let flat;
287
+ try {
288
+ flat = parseAnswerText(args, pending.questions.map((question) => question.id));
289
+ }
290
+ catch (error) {
291
+ return `${error.message}\n\n${renderPending(pending)}`;
292
+ }
293
+ const { accepted, errors } = acceptAnswers(pending.questions, flat, hint);
294
+ if (errors.length > 0) {
295
+ return `No answers were recorded:\n- ${errors.join("\n- ")}\n\n${renderPending(pending)}`;
296
+ }
297
+ Object.assign(state.intake.answers, accepted);
298
+ const remaining = buildRound(pending.round, state.intake.answers, hint);
299
+ if (remaining.length > 0) {
300
+ return this.park(workspace, state, pending.round, remaining);
301
+ }
302
+ await this.completeRound(workspace, state, pending.round);
303
+ return this.advance(workspace, state, pending.round === presentationRound
304
+ ? await this.presentationRounds(workspace, state)
305
+ : pending.round === icontecRound
306
+ ? []
307
+ : defaultRounds);
308
+ }
309
+ // ------------------------------------------------------------------------------------------
310
+ // /thesis:status and thesis_status
311
+ // ------------------------------------------------------------------------------------------
312
+ nextStep(state) {
313
+ if (state.pendingQuestions)
314
+ return `Next: answer the pending round ${state.pendingQuestions.round} questions with /thesis:answer.`;
315
+ if (!defaultRounds.every((round) => state.intake.completedRounds.includes(round))) {
316
+ return "Next: finish the interview with /thesis:init.";
317
+ }
318
+ if (state.phase === "intake")
319
+ return "Next: fix the G0 errors (see /thesis:check), then run /thesis:check again.";
320
+ const command = this.workflow.nextCommand({ state });
321
+ const extra = state.phase === "design" && !state.intake.completedRounds.includes(presentationRound)
322
+ ? " Optional: /thesis:init --presentation sets paper, palette, typeface and AI declaration."
323
+ : "";
324
+ return `Next: ${command}.${extra}`;
325
+ }
326
+ async statusSummary(workspace) {
327
+ const state = await readState(workspace);
328
+ if (!state) {
329
+ return { initialized: false, next: "Run /thesis:init to create the thesis workspace." };
330
+ }
331
+ return {
332
+ initialized: true,
333
+ root: state.root,
334
+ phase: state.phase,
335
+ humanGates: Object.fromEntries(Object.entries(state.humanGates).map(([name, gate]) => [name, gate.status])),
336
+ sections: Object.entries(state.sections)
337
+ .sort(([a], [b]) => (a < b ? -1 : 1))
338
+ .map(([id, section]) => ({
339
+ id,
340
+ title: section.title ?? null,
341
+ status: section.status,
342
+ next: this.workflow.sectionNext(state, id) || null,
343
+ })),
344
+ lastReview: state.lastReview ?? null,
345
+ intake: {
346
+ completedRounds: state.intake.completedRounds,
347
+ pendingRound: state.pendingQuestions?.round ?? null,
348
+ pendingQuestionIds: state.pendingQuestions?.questions.map((question) => question.id) ?? [],
349
+ },
350
+ lastCheck: state.lastCheck ?? null,
351
+ lastBuild: state.lastBuild ?? null,
352
+ next: this.nextStep(state),
353
+ };
354
+ }
355
+ async status(_args, sessionId) {
356
+ const workspace = this.workspace(sessionId);
357
+ const summary = await this.statusSummary(workspace);
358
+ if (!summary.initialized)
359
+ return `Thesis Studio: not initialized.\n${summary.next}`;
360
+ const state = (await readState(workspace));
361
+ const gates = Object.entries(state.humanGates)
362
+ .map(([name, gate]) => `${name} ${gate.status}`)
363
+ .join(", ");
364
+ const sectionLines = Object.keys(state.sections)
365
+ .sort()
366
+ .map((id) => {
367
+ const section = state.sections[id];
368
+ const next = this.workflow.sectionNext(state, id);
369
+ return ` ${id} ${section.title ?? ""} [${section.status}]${next ? ` -> ${next}` : ""}`;
370
+ });
371
+ return [
372
+ "Thesis Studio",
373
+ `Root: ${state.root}/`,
374
+ `Phase: ${state.phase}`,
375
+ `Interview: rounds ${state.intake.completedRounds.join(", ") || "none"} complete${state.pendingQuestions ? `; round ${state.pendingQuestions.round} awaits answers` : ""}`,
376
+ `Human gates: ${gates}`,
377
+ sectionLines.length ? `Sections:\n${sectionLines.join("\n")}` : "Sections: none yet",
378
+ ...(state.lastReview
379
+ ? [
380
+ `Last review: ${state.lastReview.scope}, ${state.lastReview.findings} finding(s), ${state.lastReview.blocking ?? 0} blocking, at ${state.lastReview.at}`,
381
+ ]
382
+ : []),
383
+ state.lastCheck
384
+ ? `Last check: ${state.lastCheck.errors} error(s), ${state.lastCheck.warnings} warning(s) at ${state.lastCheck.at}`
385
+ : "Last check: never",
386
+ this.nextStep(state),
387
+ ].join("\n");
388
+ }
389
+ // ------------------------------------------------------------------------------------------
390
+ // /thesis:check and thesis_check
391
+ // ------------------------------------------------------------------------------------------
392
+ async check(args, sessionId) {
393
+ const workspace = this.workspace(sessionId);
394
+ const state = await this.requireState(workspace);
395
+ const selected = parseGates(tokens(args.replace(/^--\s*/, "")).flatMap((token) => token.split(",").filter(Boolean)));
396
+ const base = await thesisRootPath(workspace, state.root);
397
+ const project = await refreshProject(base, {
398
+ ...this.projectOptions,
399
+ state,
400
+ });
401
+ const report = runChecks(project, { gates: selected, now: this.now });
402
+ await writeCheckReport(base, report);
403
+ state.lastCheck = {
404
+ at: report.at,
405
+ errors: report.counts.error,
406
+ warnings: report.counts.warning,
407
+ };
408
+ await writeState(workspace, state);
409
+ return formatReport(report);
410
+ }
411
+ /** Read-only variant used by the thesis_check tool: it never writes files. */
412
+ async checkReadOnly(workspace, input) {
413
+ const state = await this.requireState(workspace);
414
+ if (input.section !== undefined && !idPatterns.section.test(input.section)) {
415
+ throw new Error("section must look like SEC-03 or SEC-03.02");
416
+ }
417
+ const selected = parseGates(input.gates ?? []);
418
+ const project = await loadProject(await thesisRootPath(workspace, state.root), {
419
+ ...this.projectOptions,
420
+ state,
421
+ });
422
+ return runChecks(project, {
423
+ gates: selected,
424
+ now: this.now,
425
+ ...(input.section ? { section: input.section } : {}),
426
+ });
427
+ }
428
+ // ------------------------------------------------------------------------------------------
429
+ // /thesis:pack
430
+ // ------------------------------------------------------------------------------------------
431
+ async pack(args, sessionId) {
432
+ const workspace = this.workspace(sessionId);
433
+ const state = await this.requireState(workspace);
434
+ const [sub, ...rest] = tokens(args.replace(/^--\s*/, ""));
435
+ const base = await thesisRootPath(workspace, state.root);
436
+ const project = await loadProject(base, this.projectOptions);
437
+ switch (sub) {
438
+ case "list":
439
+ return listPacks(project);
440
+ case "check":
441
+ return checkPacks(project, this.now);
442
+ case "explain":
443
+ if (rest.length === 0)
444
+ throw new Error("Usage: /thesis:pack explain <ruleId|value>");
445
+ return explain(project, rest.join(" "));
446
+ case "new":
447
+ return newPack(this.api, project, base, rest, this.now);
448
+ default:
449
+ throw new Error("Usage: /thesis:pack new <scope> <id> | list | check | explain <ruleId|value>");
450
+ }
451
+ }
452
+ // ------------------------------------------------------------------------------------------
453
+ // /thesis:style
454
+ // ------------------------------------------------------------------------------------------
455
+ async style(args, sessionId) {
456
+ const workspace = this.workspace(sessionId);
457
+ const usage = "Usage: /thesis:style new <id> -- <guide text|URL|path> | list | check";
458
+ const { head, text } = splitDelimited(args.replace(/^--\s*/, ""));
459
+ const [sub, ...rest] = tokens(head);
460
+ if (sub === "new") {
461
+ if (rest.length !== 1 || !text)
462
+ throw new Error(usage);
463
+ return blockable(() => this.workflow.authoring.styleNew(workspace, sessionId, rest[0], text));
464
+ }
465
+ const state = await this.requireState(workspace);
466
+ const base = await thesisRootPath(workspace, state.root);
467
+ if ((sub !== "list" && sub !== "check") || rest.length > 0 || text)
468
+ throw new Error(usage);
469
+ const project = await loadProject(base, this.projectOptions);
470
+ if (sub === "list")
471
+ return listStyles(project);
472
+ return (await checkStyleFiles(project, { env: this.env, cacheRoot: this.cacheRoot(), now: this.now })).text;
473
+ }
474
+ // ------------------------------------------------------------------------------------------
475
+ // /thesis:norms
476
+ // ------------------------------------------------------------------------------------------
477
+ async norms(args, sessionId) {
478
+ const { head, text } = splitDelimited(args.replace(/^--\s*/, ""));
479
+ if (head !== "import" || !text)
480
+ throw new Error("Usage: /thesis:norms import -- <guide text|URL|path>");
481
+ return blockable(() => this.workflow.authoring.normsImport(this.workspace(sessionId), sessionId, text));
482
+ }
483
+ // ------------------------------------------------------------------------------------------
484
+ // /thesis:design, outline, approve, revise, research, next
485
+ // ------------------------------------------------------------------------------------------
486
+ async design(args, sessionId) {
487
+ if (args.trim())
488
+ throw new Error("Usage: /thesis:design (use /thesis:revise A|B -- <feedback> to change a draft)");
489
+ return blockable(() => this.workflow.design(this.workspace(sessionId), sessionId));
490
+ }
491
+ async outline(args, sessionId) {
492
+ if (args.trim())
493
+ throw new Error("Usage: /thesis:outline (use /thesis:revise OUTLINE -- <feedback> to change a draft)");
494
+ return blockable(() => this.workflow.outline(this.workspace(sessionId), sessionId));
495
+ }
496
+ async approve(args, sessionId) {
497
+ const { head, text } = splitDelimited(args);
498
+ if (!head || head.includes(" ")) {
499
+ throw new Error("Usage: /thesis:approve <A|B|OUTLINE|C|SEC-id|FND-id|ETH-id|norms|style:id> [-- notes]");
500
+ }
501
+ return blockable(() => this.workflow.approve(this.workspace(sessionId), sessionId, head, text || undefined));
502
+ }
503
+ async revise(args, sessionId) {
504
+ const { head, text } = splitDelimited(args);
505
+ if (!head || head.includes(" ") || (!text && !/^FND-\d{4}$/.test(head))) {
506
+ throw new Error("Usage: /thesis:revise <A|B|OUTLINE|SEC-id|FND-id|norms|style:id> -- <feedback>");
507
+ }
508
+ return blockable(() => this.workflow.revise(this.workspace(sessionId), sessionId, head, text));
509
+ }
510
+ async research(args, sessionId) {
511
+ const { head, text } = splitDelimited(args);
512
+ const usage = "Usage: /thesis:research <SEC-id|next> [-- <search more on ...> | -- add <DOI or URL; title; year; type>]";
513
+ if (!head || head.includes(" ") || (head !== "next" && !idPatterns.section.test(head))) {
514
+ throw new Error(usage);
515
+ }
516
+ const added = /^add\s+(.+)$/i.exec(text);
517
+ if (added) {
518
+ const parsed = parseAddedSource(added[1]);
519
+ if (parsed.error)
520
+ throw new Error(parsed.error);
521
+ }
522
+ return blockable(() => this.workflow.research.run(this.workspace(sessionId), sessionId, head, {
523
+ ...(added ? { add: added[1] } : text ? { focus: text } : {}),
524
+ }));
525
+ }
526
+ async draft(args, sessionId) {
527
+ const { head, text } = splitDelimited(args);
528
+ if (!head || head.includes(" ") || (head !== "next" && !idPatterns.section.test(head))) {
529
+ throw new Error("Usage: /thesis:draft <SEC-id|next> [-- <feedback>]");
530
+ }
531
+ return blockable(() => this.workflow.drafts.run(this.workspace(sessionId), sessionId, head, {
532
+ ...(text ? { feedback: text } : {}),
533
+ }));
534
+ }
535
+ async figure(args, sessionId) {
536
+ const { head, text } = splitDelimited(args);
537
+ if (!idPatterns.section.test(head) || !text)
538
+ throw new Error("Usage: /thesis:figure <SEC-id> -- <what the figure should show>");
539
+ return blockable(() => this.workflow.figures.run(this.workspace(sessionId), sessionId, head, text));
540
+ }
541
+ async review(args, sessionId) {
542
+ const target = args.trim() || "all";
543
+ if (target !== "all" && !idPatterns.section.test(target))
544
+ throw new Error("Usage: /thesis:review [SEC-id|all]");
545
+ return blockable(() => this.workflow.reviews.run(this.workspace(sessionId), sessionId, target));
546
+ }
547
+ async finalize(args, sessionId) {
548
+ if (args.trim())
549
+ throw new Error("Usage: /thesis:finalize");
550
+ return blockable(() => this.workflow.finalize.run(this.workspace(sessionId), sessionId));
551
+ }
552
+ async next(_args, sessionId) {
553
+ return blockable(() => this.workflow.next(this.workspace(sessionId), sessionId));
554
+ }
555
+ // ------------------------------------------------------------------------------------------
556
+ // scholarly tools
557
+ // ------------------------------------------------------------------------------------------
558
+ /** thesis_scholar_search: structured, sanitized and capped ScholarRecords. */
559
+ async scholarSearch(input, signal) {
560
+ const parsed = parseSearchInput(input);
561
+ return { results: await this.scholar.search(parsed, signal) };
562
+ }
563
+ /** thesis_scholar_resolve: one record with its retraction flag and what verification would say. */
564
+ async scholarResolve(workspace, input, signal) {
565
+ if (typeof input !== "object" || input === null || Array.isArray(input))
566
+ throw new Error("invalid input");
567
+ const keys = Object.keys(input);
568
+ if (keys.some((key) => key !== "identifier"))
569
+ throw new Error("invalid input");
570
+ const identifier = parseIdentifier(input.identifier);
571
+ let profile;
572
+ if (workspace) {
573
+ const state = await readState(workspace).catch(() => undefined);
574
+ if (state) {
575
+ profile = (await loadProject(await thesisRootPath(workspace, state.root), this.projectOptions)).profile;
576
+ }
577
+ }
578
+ const domains = officialDomainsFromProfile(profile);
579
+ if (identifier.kind === "url") {
580
+ // Official pages are matched by host only; reachability is never tested.
581
+ const tier = classifyHost(identifier.value, "law", domains).tier;
582
+ return {
583
+ identifier,
584
+ record: null,
585
+ retraction: { retracted: false },
586
+ verification: {
587
+ method: "official_domain",
588
+ officialDomain: tier === "primary" || tier === "type_not_allowed"
589
+ ? "official"
590
+ : tier === "indexing"
591
+ ? "indexing"
592
+ : "none",
593
+ suggestedStatus: tier === "primary" || tier === "type_not_allowed"
594
+ ? "VERIFIED_PRIMARY (when the type is law, standard, report or dataset)"
595
+ : "UNVERIFIED",
596
+ },
597
+ };
598
+ }
599
+ const resolved = await resolveChecked(this.scholar, identifier, signal);
600
+ if (!resolved)
601
+ return {
602
+ identifier,
603
+ record: null,
604
+ retraction: { retracted: false },
605
+ verification: {
606
+ method: identifier.kind === "doi" ? "crossref" : identifier.kind,
607
+ officialDomain: "none",
608
+ suggestedStatus: "UNVERIFIED",
609
+ },
610
+ };
611
+ return {
612
+ identifier,
613
+ record: resolved.record,
614
+ retraction: { retracted: resolved.retracted },
615
+ verification: {
616
+ method: resolved.record.source,
617
+ officialDomain: "none",
618
+ suggestedStatus: resolved.retracted ? "REJECTED" : suggestStatus(resolved.record, domains),
619
+ },
620
+ };
621
+ }
622
+ // ------------------------------------------------------------------------------------------
623
+ // /thesis:doctor
624
+ // ------------------------------------------------------------------------------------------
625
+ async doctor() {
626
+ return formatDoctor(await runDoctor({ env: this.env, cacheRoot: this.cacheRoot() }));
627
+ }
628
+ // ------------------------------------------------------------------------------------------
629
+ // /thesis:build, /thesis:setup and thesis_build
630
+ // ------------------------------------------------------------------------------------------
631
+ cacheRoot() {
632
+ const host = this.api.paths?.cache;
633
+ return cacheRoot(host, this.env);
634
+ }
635
+ /** Build the thesis and record the result in the state; shared by the command and the tool. */
636
+ async buildRun(workspace, input, signal) {
637
+ const state = await this.requireState(workspace);
638
+ if (state.phase === "intake") {
639
+ throw new Blocked("finish the intake interview first (/thesis:init, /thesis:answer).");
640
+ }
641
+ const root = await thesisRootPath(workspace, state.root);
642
+ const outcome = await buildThesis({
643
+ root,
644
+ scope: input.scope,
645
+ ...(input.section ? { section: input.section } : {}),
646
+ ...(input.pdfa ? { pdfa: true } : {}),
647
+ ...(input.format ? { format: input.format } : {}),
648
+ sections: state.sections,
649
+ env: this.env,
650
+ cacheRoot: this.cacheRoot(),
651
+ registry: this.registry,
652
+ ...(this.projectOptions.packsRoot ? { packsRoot: this.projectOptions.packsRoot } : {}),
653
+ now: this.now,
654
+ ...(signal ? { signal } : {}),
655
+ progress: (note) => this.api.ui.status("build", note),
656
+ });
657
+ this.api.ui.status("build", undefined);
658
+ if (outcome.ok && outcome.path?.endsWith(".pdf")) {
659
+ state.lastBuild = {
660
+ at: this.now().toISOString(),
661
+ engine: outcome.engine.startsWith("chrome-pdf") ? "chrome" : "typst-cli",
662
+ pdf: relative(workspace, outcome.path).split("\\").join("/"),
663
+ ms: outcome.ms,
664
+ };
665
+ await writeState(workspace, state);
666
+ }
667
+ return outcome;
668
+ }
669
+ async build(args, sessionId) {
670
+ const workspace = this.workspace(sessionId);
671
+ let scope = "full";
672
+ let section;
673
+ let pdfa = false;
674
+ let format = "pdf";
675
+ const parts = tokens(args);
676
+ for (const part of parts) {
677
+ if (part === "--pdfa")
678
+ pdfa = true;
679
+ else if (part === "--html")
680
+ format = "html";
681
+ else if (part === "full")
682
+ scope = "full";
683
+ else if (part === "approved")
684
+ scope = "approved";
685
+ else if (idPatterns.section.test(part)) {
686
+ scope = "section";
687
+ section = part;
688
+ }
689
+ else
690
+ throw new Error("Usage: /thesis:build [full|approved|SEC-id] [--pdfa] [--html]");
691
+ }
692
+ return blockable(async () => formatBuild(await this.buildRun(workspace, { scope, ...(section ? { section } : {}), pdfa, format })));
693
+ }
694
+ async setup(args) {
695
+ if (args.trim())
696
+ throw new Error("Usage: /thesis:setup");
697
+ this.api.ui.status("setup", "installing the pinned Typst");
698
+ try {
699
+ const result = await setupTypst({
700
+ cacheRoot: this.cacheRoot(),
701
+ ...(this.setupDeps ? { deps: this.setupDeps } : {}),
702
+ });
703
+ return result.ok ? result.message : `Setup failed: ${result.message}`;
704
+ }
705
+ finally {
706
+ this.api.ui.status("setup", undefined);
707
+ }
708
+ }
709
+ }
710
+ //# sourceMappingURL=coordinator.js.map