@galaxyproject/orbit 0.0.0 → 0.9.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 (451) hide show
  1. package/CHANGELOG.md +123 -0
  2. package/LICENSE +21 -0
  3. package/README.md +760 -5
  4. package/bin/legacy-mcp-config.js +363 -0
  5. package/bin/orbit.js +810 -0
  6. package/bin/pi-extension-path.d.ts +4 -0
  7. package/bin/pi-extension-path.js +44 -0
  8. package/bin/provider-auth.d.ts +22 -0
  9. package/bin/provider-auth.js +77 -0
  10. package/bin/thinking-pref.js +38 -0
  11. package/bin/update-check.d.ts +15 -0
  12. package/bin/update-check.js +137 -0
  13. package/extensions/cli-update/index.ts +32 -0
  14. package/extensions/orbit/activity-hooks.ts +141 -0
  15. package/extensions/orbit/activity.ts +116 -0
  16. package/extensions/orbit/agent-dir.ts +11 -0
  17. package/extensions/orbit/auto-resume.ts +352 -0
  18. package/extensions/orbit/config.ts +3 -0
  19. package/extensions/orbit/confusables.ts +1 -0
  20. package/extensions/orbit/context.ts +957 -0
  21. package/extensions/orbit/dashboard-commands.ts +191 -0
  22. package/extensions/orbit/dashboard-store.ts +473 -0
  23. package/extensions/orbit/dashboard-tools.ts +1185 -0
  24. package/extensions/orbit/empty-completion.ts +99 -0
  25. package/extensions/orbit/evidence-gate.ts +1276 -0
  26. package/extensions/orbit/evidence-override-command.ts +294 -0
  27. package/extensions/orbit/exec-guard/bash-risk.ts +1408 -0
  28. package/extensions/orbit/exec-guard/gate.ts +181 -0
  29. package/extensions/orbit/exec-guard/guardian-config.ts +54 -0
  30. package/extensions/orbit/exec-guard/index.ts +1 -0
  31. package/extensions/orbit/exec-guard/model-tier.ts +36 -0
  32. package/extensions/orbit/exec-guard/path-jail.ts +54 -0
  33. package/extensions/orbit/exec-guard/policy.ts +342 -0
  34. package/extensions/orbit/exec-guard/runtime-state.ts +15 -0
  35. package/extensions/orbit/exec-guard/sensitive-read.ts +525 -0
  36. package/extensions/orbit/exec-guard/types.ts +42 -0
  37. package/extensions/orbit/execution-commands.ts +134 -0
  38. package/extensions/orbit/feedback-command.ts +81 -0
  39. package/extensions/orbit/feedback.ts +96 -0
  40. package/extensions/orbit/galaxy-api.test.ts +122 -0
  41. package/extensions/orbit/galaxy-api.ts +606 -0
  42. package/extensions/orbit/galaxy-artifact-link-guidance.ts +5 -0
  43. package/extensions/orbit/galaxy-destructive-gate.ts +113 -0
  44. package/extensions/orbit/galaxy-enrich.ts +1108 -0
  45. package/extensions/orbit/galaxy-failure.ts +101 -0
  46. package/extensions/orbit/galaxy-fixture.ts +126 -0
  47. package/extensions/orbit/galaxy-history-guard.ts +233 -0
  48. package/extensions/orbit/galaxy-job-block.ts +347 -0
  49. package/extensions/orbit/galaxy-job-ops.ts +288 -0
  50. package/extensions/orbit/galaxy-live-source.ts +929 -0
  51. package/extensions/orbit/galaxy-markdown-adapter.ts +248 -0
  52. package/extensions/orbit/galaxy-op-policy.ts +332 -0
  53. package/extensions/orbit/galaxy-ops-tools.ts +326 -0
  54. package/extensions/orbit/galaxy-output-store.ts +80 -0
  55. package/extensions/orbit/galaxy-output.ts +346 -0
  56. package/extensions/orbit/galaxy-page-binding.ts +222 -0
  57. package/extensions/orbit/galaxy-page-markdown-guidance.ts +15 -0
  58. package/extensions/orbit/galaxy-page-ops.ts +159 -0
  59. package/extensions/orbit/galaxy-page-sync.test.ts +417 -0
  60. package/extensions/orbit/galaxy-page-sync.ts +318 -0
  61. package/extensions/orbit/galaxy-pages-api.ts +203 -0
  62. package/extensions/orbit/galaxy-pages-sync.ts +409 -0
  63. package/extensions/orbit/galaxy-poll-guard.ts +189 -0
  64. package/extensions/orbit/galaxy-poller.ts +706 -0
  65. package/extensions/orbit/galaxy-provenance.ts +623 -0
  66. package/extensions/orbit/galaxy-reconcile.ts +956 -0
  67. package/extensions/orbit/galaxy-recovery.ts +176 -0
  68. package/extensions/orbit/galaxy-repeat-guard.ts +55 -0
  69. package/extensions/orbit/galaxy-submission-capture.ts +707 -0
  70. package/extensions/orbit/galaxy-submission.ts +502 -0
  71. package/extensions/orbit/galaxy-tool-source.ts +78 -0
  72. package/extensions/orbit/galaxy-tool-wrap.ts +234 -0
  73. package/extensions/orbit/galaxy-udt-block.ts +127 -0
  74. package/extensions/orbit/galaxy-upload-tus.ts +334 -0
  75. package/extensions/orbit/galaxy-upload.ts +300 -0
  76. package/extensions/orbit/galaxy-version-capture.ts +65 -0
  77. package/extensions/orbit/git.ts +173 -0
  78. package/extensions/orbit/harness-block-fields.ts +597 -0
  79. package/extensions/orbit/index.ts +593 -0
  80. package/extensions/orbit/init-gate.ts +284 -0
  81. package/extensions/orbit/instructions-command.ts +136 -0
  82. package/extensions/orbit/invocation-failure-hint.ts +57 -0
  83. package/extensions/orbit/iwc-plan-check.ts +94 -0
  84. package/extensions/orbit/lesson-command.ts +303 -0
  85. package/extensions/orbit/lesson-hint.ts +245 -0
  86. package/extensions/orbit/lesson-nudge.ts +106 -0
  87. package/extensions/orbit/lessons/compose.ts +177 -0
  88. package/extensions/orbit/lessons/counters.ts +120 -0
  89. package/extensions/orbit/lessons/enabled.ts +116 -0
  90. package/extensions/orbit/lessons/matcher.ts +346 -0
  91. package/extensions/orbit/lessons/paths.ts +286 -0
  92. package/extensions/orbit/lessons/pi-event-contract.ts +105 -0
  93. package/extensions/orbit/lessons/propose-replay.ts +103 -0
  94. package/extensions/orbit/lessons/propose-tool.ts +222 -0
  95. package/extensions/orbit/lessons/propose.ts +502 -0
  96. package/extensions/orbit/lessons/replay.ts +89 -0
  97. package/extensions/orbit/lessons/reproduction-index.ts +83 -0
  98. package/extensions/orbit/lessons/search-tool.ts +99 -0
  99. package/extensions/orbit/lessons/search.ts +136 -0
  100. package/extensions/orbit/lessons/store.ts +415 -0
  101. package/extensions/orbit/lessons/text.ts +36 -0
  102. package/extensions/orbit/lessons/types.ts +69 -0
  103. package/extensions/orbit/lessons/user-dir.ts +24 -0
  104. package/extensions/orbit/lessons/user-lesson.ts +88 -0
  105. package/extensions/orbit/lessons/wrapper.ts +61 -0
  106. package/extensions/orbit/lessons-command.ts +147 -0
  107. package/extensions/orbit/local-exec.ts +39 -0
  108. package/extensions/orbit/mcp-output.ts +179 -0
  109. package/extensions/orbit/mcp-servers.test.ts +24 -0
  110. package/extensions/orbit/mcp-servers.ts +25 -0
  111. package/extensions/orbit/model-script.ts +351 -0
  112. package/extensions/orbit/notebook-anchors.ts +342 -0
  113. package/extensions/orbit/notebook-writer.ts +863 -0
  114. package/extensions/orbit/observation-allowlists.ts +1109 -0
  115. package/extensions/orbit/observation-replay.ts +148 -0
  116. package/extensions/orbit/observation-triggers.ts +563 -0
  117. package/extensions/orbit/observation-ui.ts +175 -0
  118. package/extensions/orbit/observations-command.ts +421 -0
  119. package/extensions/orbit/observations-config.ts +200 -0
  120. package/extensions/orbit/observations.ts +1381 -0
  121. package/extensions/orbit/profiles.ts +270 -0
  122. package/extensions/orbit/progress-updates.ts +95 -0
  123. package/extensions/orbit/proposal-commands.ts +882 -0
  124. package/extensions/orbit/provenance-fs-file.ts +59 -0
  125. package/extensions/orbit/provenance-fs.ts +32 -0
  126. package/extensions/orbit/provenance-memory-fs.ts +59 -0
  127. package/extensions/orbit/record-store-file.ts +177 -0
  128. package/extensions/orbit/record-store-page.ts +77 -0
  129. package/extensions/orbit/record-store-seam.ts +47 -0
  130. package/extensions/orbit/record-store.ts +149 -0
  131. package/extensions/orbit/registry-carrier.ts +107 -0
  132. package/extensions/orbit/registry-eligibility.ts +95 -0
  133. package/extensions/orbit/registry-evaluation.ts +403 -0
  134. package/extensions/orbit/registry-evaluator.ts +519 -0
  135. package/extensions/orbit/registry-import.ts +91 -0
  136. package/extensions/orbit/registry-lock.ts +221 -0
  137. package/extensions/orbit/registry-memory-fs.ts +42 -0
  138. package/extensions/orbit/registry-page-carrier.ts +103 -0
  139. package/extensions/orbit/registry-proposal.ts +1348 -0
  140. package/extensions/orbit/registry-runtime.ts +234 -0
  141. package/extensions/orbit/registry-schema.ts +735 -0
  142. package/extensions/orbit/registry-submitter.ts +59 -0
  143. package/extensions/orbit/registry-templates.ts +346 -0
  144. package/extensions/orbit/registry.ts +476 -0
  145. package/extensions/orbit/sandbox/index.ts +120 -0
  146. package/extensions/orbit/sandbox/sandbox-bash.ts +93 -0
  147. package/extensions/orbit/sandbox/sandbox-config.ts +87 -0
  148. package/extensions/orbit/sandbox/sandbox-init-message.ts +28 -0
  149. package/extensions/orbit/secret-redaction.ts +247 -0
  150. package/extensions/orbit/session-index/cwd.ts +18 -0
  151. package/extensions/orbit/session-index/db.ts +56 -0
  152. package/extensions/orbit/session-index/indexer.ts +154 -0
  153. package/extensions/orbit/session-index/is-enabled.ts +17 -0
  154. package/extensions/orbit/session-index/parse.ts +254 -0
  155. package/extensions/orbit/session-index/query.ts +209 -0
  156. package/extensions/orbit/session-index/schema.ts +72 -0
  157. package/extensions/orbit/session-index/tools.ts +152 -0
  158. package/extensions/orbit/session-lifecycle.ts +321 -0
  159. package/extensions/orbit/skill-triggers.ts +159 -0
  160. package/extensions/orbit/skills-command.ts +48 -0
  161. package/extensions/orbit/skills-discovery.ts +435 -0
  162. package/extensions/orbit/skills.ts +84 -0
  163. package/extensions/orbit/sra-import-gate.ts +77 -0
  164. package/extensions/orbit/state.ts +265 -0
  165. package/extensions/orbit/submission-replay.ts +147 -0
  166. package/extensions/orbit/sync-command.ts +157 -0
  167. package/extensions/orbit/teams/critic-parser.ts +93 -0
  168. package/extensions/orbit/teams/dispatcher.ts +210 -0
  169. package/extensions/orbit/teams/is-enabled.ts +22 -0
  170. package/extensions/orbit/teams/tool.ts +187 -0
  171. package/extensions/orbit/teams/types.ts +57 -0
  172. package/extensions/orbit/teams/validate.ts +42 -0
  173. package/extensions/orbit/tester-id-command.ts +133 -0
  174. package/extensions/orbit/tools-sync.ts +279 -0
  175. package/extensions/orbit/tools.ts +1300 -0
  176. package/extensions/orbit/types.ts +41 -0
  177. package/extensions/orbit/ui-bridge.ts +55 -0
  178. package/extensions/orbit/ulid.ts +60 -0
  179. package/extensions/orbit/user-instructions.ts +388 -0
  180. package/extensions/orbit/vendor/skills/_catalog.json +68 -0
  181. package/extensions/orbit/vendor/skills/_manifest.json +1106 -0
  182. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/SKILL.md +112 -0
  183. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/_provenance.json +218 -0
  184. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/_required_tools.json +33 -0
  185. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/_verify.json +4 -0
  186. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/cli/add.json +50 -0
  187. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/cli/draft-extract.json +51 -0
  188. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/cli/draft-next-step.json +42 -0
  189. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/cli/draft-validate.json +140 -0
  190. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/cli/list.json +32 -0
  191. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/notes/galaxy-tool-job-failure-reference.md +137 -0
  192. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/notes/open-requirements-ledger.md +173 -0
  193. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/schemas/galaxy-tool-summary.schema.json +175 -0
  194. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/schemas/galaxy-workflow-draft.schema.json +2727 -0
  195. package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/SKILL.md +82 -0
  196. package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/_provenance.json +133 -0
  197. package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/_required_tools.json +16 -0
  198. package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/_verify.json +4 -0
  199. package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/references/cli/draft-validate.json +140 -0
  200. package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/references/notes/galaxy-workflow-draft-format.md +135 -0
  201. package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/references/notes/open-requirements-ledger.md +173 -0
  202. package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/references/schemas/galaxy-workflow-draft.schema.json +2727 -0
  203. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/SKILL.md +84 -0
  204. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/_provenance.json +166 -0
  205. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/_verify.json +29 -0
  206. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/notes/galaxy-workflow-testability-design.md +136 -0
  207. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/notes/iwc-shortcuts-anti-patterns.md +357 -0
  208. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/notes/iwc-test-data-conventions.md +308 -0
  209. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/notes/planemo-asserts-idioms.md +246 -0
  210. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/notes/planemo-workflow-test-architecture.md +151 -0
  211. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/schemas/galaxy-workflow-test-plan.schema.json +552 -0
  212. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/schemas/summary-galaxy-workflow.schema.json +687 -0
  213. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/schemas/tests-format.schema.json +7328 -0
  214. package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/SKILL.md +127 -0
  215. package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/_provenance.json +198 -0
  216. package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/_required_tools.json +16 -0
  217. package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/_verify.json +4 -0
  218. package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/references/cli/convert.json +123 -0
  219. package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/references/notes/galaxy-data-flow-draft-contract.md +129 -0
  220. package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/references/notes/iwc-shortcuts-anti-patterns.md +357 -0
  221. package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/references/notes/iwc-test-data-conventions.md +308 -0
  222. package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/references/notes/open-requirements-ledger.md +173 -0
  223. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/SKILL.md +73 -0
  224. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/_provenance.json +160 -0
  225. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/_verify.json +4 -0
  226. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/galaxy-collection-semantics.md +43 -0
  227. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/galaxy-collection-semantics.yml +1250 -0
  228. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/galaxy-tool-job-failure-reference.md +137 -0
  229. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/galaxy-workflow-invocation-failure-reference.md +138 -0
  230. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/iwc-shortcuts-anti-patterns.md +357 -0
  231. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/nextflow-operators-to-galaxy-collection-recipes.md +98 -0
  232. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/planemo-asserts-idioms.md +246 -0
  233. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/planemo-workflow-test-architecture.md +151 -0
  234. package/extensions/orbit/vendor/skills/discover-shed-tool/SKILL.md +174 -0
  235. package/extensions/orbit/vendor/skills/discover-shed-tool/_provenance.json +130 -0
  236. package/extensions/orbit/vendor/skills/discover-shed-tool/_required_tools.json +18 -0
  237. package/extensions/orbit/vendor/skills/discover-shed-tool/_verify.json +17 -0
  238. package/extensions/orbit/vendor/skills/discover-shed-tool/references/cli/tool-revisions.json +48 -0
  239. package/extensions/orbit/vendor/skills/discover-shed-tool/references/cli/tool-search.json +95 -0
  240. package/extensions/orbit/vendor/skills/discover-shed-tool/references/cli/tool-versions.json +39 -0
  241. package/extensions/orbit/vendor/skills/discover-shed-tool/references/notes/component-tool-shed-search.md +230 -0
  242. package/extensions/orbit/vendor/skills/discover-shed-tool/references/schemas/galaxy-tool-discovery.schema.json +231 -0
  243. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/SKILL.md +93 -0
  244. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/_provenance.json +201 -0
  245. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/_required_tools.json +28 -0
  246. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/_verify.json +17 -0
  247. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/cli/planemo.md +44 -0
  248. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/cli/validate-tests.json +40 -0
  249. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/notes/galaxy-workflow-testability-design.md +136 -0
  250. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/notes/iwc-shortcuts-anti-patterns.md +357 -0
  251. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/notes/iwc-test-data-conventions.md +308 -0
  252. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/notes/planemo-asserts-idioms.md +246 -0
  253. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/notes/planemo-workflow-test-architecture.md +151 -0
  254. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/schemas/galaxy-workflow-test-plan.schema.json +552 -0
  255. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/schemas/tests-format.schema.json +7328 -0
  256. package/extensions/orbit/vendor/skills/interview-to-galaxy-workflow-changeset/SKILL.md +81 -0
  257. package/extensions/orbit/vendor/skills/interview-to-galaxy-workflow-changeset/_provenance.json +93 -0
  258. package/extensions/orbit/vendor/skills/interview-to-galaxy-workflow-changeset/_verify.json +17 -0
  259. package/extensions/orbit/vendor/skills/interview-to-galaxy-workflow-changeset/references/notes/open-requirements-ledger.md +173 -0
  260. package/extensions/orbit/vendor/skills/interview-to-galaxy-workflow-changeset/references/schemas/summary-galaxy-workflow.schema.json +687 -0
  261. package/extensions/orbit/vendor/skills/pipeline-update-interview-to-galaxy/SKILL.md +81 -0
  262. package/extensions/orbit/vendor/skills/pipeline-update-interview-to-galaxy/_assembly.json +23 -0
  263. package/extensions/orbit/vendor/skills/run-workflow-test/SKILL.md +79 -0
  264. package/extensions/orbit/vendor/skills/run-workflow-test/_provenance.json +125 -0
  265. package/extensions/orbit/vendor/skills/run-workflow-test/_required_tools.json +28 -0
  266. package/extensions/orbit/vendor/skills/run-workflow-test/_verify.json +4 -0
  267. package/extensions/orbit/vendor/skills/run-workflow-test/references/cli/planemo.md +44 -0
  268. package/extensions/orbit/vendor/skills/run-workflow-test/references/cli/validate-tests.json +40 -0
  269. package/extensions/orbit/vendor/skills/run-workflow-test/references/notes/galaxy-workflow-invocation-failure-reference.md +138 -0
  270. package/extensions/orbit/vendor/skills/run-workflow-test/references/notes/planemo-asserts-idioms.md +246 -0
  271. package/extensions/orbit/vendor/skills/run-workflow-test/references/notes/planemo-workflow-test-architecture.md +151 -0
  272. package/extensions/orbit/vendor/skills/run-workflow-test/references/schemas/tests-format.schema.json +7328 -0
  273. package/extensions/orbit/vendor/skills/skills/LICENSE +21 -0
  274. package/extensions/orbit/vendor/skills/skills/collection-manipulation/README.md +39 -0
  275. package/extensions/orbit/vendor/skills/skills/collection-manipulation/SKILL.md +892 -0
  276. package/extensions/orbit/vendor/skills/skills/collection-manipulation/references/api-patterns.md +927 -0
  277. package/extensions/orbit/vendor/skills/skills/collection-manipulation/references/apply-rules.md +1482 -0
  278. package/extensions/orbit/vendor/skills/skills/collection-manipulation/references/test-patterns.md +996 -0
  279. package/extensions/orbit/vendor/skills/skills/collection-manipulation/references/tools.md +609 -0
  280. package/extensions/orbit/vendor/skills/skills/galaxy-data-libraries/SKILL.md +170 -0
  281. package/extensions/orbit/vendor/skills/skills/galaxy-integration/README.md +162 -0
  282. package/extensions/orbit/vendor/skills/skills/galaxy-integration/SKILL.md +99 -0
  283. package/extensions/orbit/vendor/skills/skills/galaxy-integration/examples/README.md +119 -0
  284. package/extensions/orbit/vendor/skills/skills/galaxy-integration/examples/tool-checking.md +419 -0
  285. package/extensions/orbit/vendor/skills/skills/galaxy-integration/examples/workflow-testing.md +617 -0
  286. package/extensions/orbit/vendor/skills/skills/galaxy-integration/galaxy-integration.md +614 -0
  287. package/extensions/orbit/vendor/skills/skills/galaxy-integration/jupyterlite/SKILL.md +144 -0
  288. package/extensions/orbit/vendor/skills/skills/galaxy-integration/jupyterlite/examples/average_col3.ipynb +68 -0
  289. package/extensions/orbit/vendor/skills/skills/galaxy-integration/jupyterlite/examples/extract_sample_metadata.ipynb +190 -0
  290. package/extensions/orbit/vendor/skills/skills/galaxy-integration/jupyterlite/examples/variant_annotation.ipynb +816 -0
  291. package/extensions/orbit/vendor/skills/skills/galaxy-integration/jupyterlite/examples/vcp_variant_map.ipynb +443 -0
  292. package/extensions/orbit/vendor/skills/skills/galaxy-integration/scripts/README.md +165 -0
  293. package/extensions/orbit/vendor/skills/skills/galaxy-integration/scripts/galaxy_tool_checker.py +521 -0
  294. package/extensions/orbit/vendor/skills/skills/galaxy-mcp-reference/SKILL.md +128 -0
  295. package/extensions/orbit/vendor/skills/skills/galaxy-mcp-reference/gotchas.md +135 -0
  296. package/extensions/orbit/vendor/skills/skills/galaxy-mcp-reference/history-access.md +132 -0
  297. package/extensions/orbit/vendor/skills/skills/reproduciblify/SKILL.md +146 -0
  298. package/extensions/orbit/vendor/skills/skills/reproduciblify/references/directives.yml +496 -0
  299. package/extensions/orbit/vendor/skills/skills/udt-authoring/SKILL.md +245 -0
  300. package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/01-minimal-echo.yml +27 -0
  301. package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/02-single-data-in-out.yml +27 -0
  302. package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/03-multiple-data-js.yml +28 -0
  303. package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/04-select-integer-boolean.yml +41 -0
  304. package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/05-resource-requirements.yml +25 -0
  305. package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/06-biocontainer-tool.yml +38 -0
  306. package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/07-inline-python-script.yml +56 -0
  307. package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/08-configfile-script.yml +74 -0
  308. package/extensions/orbit/vendor/skills/skills/udt-authoring/references/common-mistakes.md +76 -0
  309. package/extensions/orbit/vendor/skills/skills/udt-authoring/references/schema-reference.md +155 -0
  310. package/extensions/orbit/vendor/skills/skills/udt-authoring/references/templating.md +196 -0
  311. package/extensions/orbit/vendor/skills/skills/udt-authoring/scripts/validate.py +109 -0
  312. package/extensions/orbit/vendor/skills/skills/workflow-reports/README.md +71 -0
  313. package/extensions/orbit/vendor/skills/skills/workflow-reports/SKILL.md +190 -0
  314. package/extensions/orbit/vendor/skills/skills/workflow-reports/examples/histology-staining.md +145 -0
  315. package/extensions/orbit/vendor/skills/skills/workflow-reports/examples/tissue-microarray-analysis.md +176 -0
  316. package/extensions/orbit/vendor/skills/skills/workflow-reports/references/directives.md +415 -0
  317. package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/SKILL.md +98 -0
  318. package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/_provenance.json +93 -0
  319. package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/_required_tools.json +28 -0
  320. package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/_verify.json +17 -0
  321. package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/references/cli/convert.json +123 -0
  322. package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/references/cli/foundry.md +25 -0
  323. package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/references/cli/validate.json +142 -0
  324. package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/references/schemas/summary-galaxy-workflow.schema.json +687 -0
  325. package/extensions/orbit/vendor/skills/validate-galaxy-workflow/SKILL.md +74 -0
  326. package/extensions/orbit/vendor/skills/validate-galaxy-workflow/_provenance.json +71 -0
  327. package/extensions/orbit/vendor/skills/validate-galaxy-workflow/_required_tools.json +16 -0
  328. package/extensions/orbit/vendor/skills/validate-galaxy-workflow/_verify.json +4 -0
  329. package/extensions/orbit/vendor/skills/validate-galaxy-workflow/references/cli/validate.json +142 -0
  330. package/extensions/orbit/vendor/skills/validate-galaxy-workflow/references/notes/galaxy-workflow-invocation-failure-reference.md +138 -0
  331. package/extensions/orbit/vendor/skills/validate-galaxy-workflow/references/notes/galaxy-workflow-testability-design.md +136 -0
  332. package/extensions/orbit/vendor-skills.ts +283 -0
  333. package/extensions/orbit/workspace-state-dir.ts +46 -0
  334. package/extensions/orbit-handoff/index.ts +73 -0
  335. package/extensions/orbit-handoff/orbit-launcher.ts +142 -0
  336. package/extensions/whats-new/index.ts +98 -0
  337. package/lessons/LICENSE +17 -0
  338. package/lessons/README.md +117 -0
  339. package/lessons/SCHEMA.md +187 -0
  340. package/lessons/build-snapshot.mjs +311 -0
  341. package/lessons/data/downloaded-file-is-not-what-its-extension-says.md +61 -0
  342. package/lessons/galaxy-api/403-history-is-a-hard-stop.md +57 -0
  343. package/lessons/galaxy-api/collection-into-single-dataset-input.md +61 -0
  344. package/lessons/galaxy-api/connectedvalue-in-command-line.md +62 -0
  345. package/lessons/galaxy-api/hid-is-not-an-id.md +59 -0
  346. package/lessons/galaxy-api/invoke-workflow-inputs-not-params.md +60 -0
  347. package/lessons/galaxy-api/repeat-param-pipe-keys.md +63 -0
  348. package/lessons/galaxy-api/run-tool-returns-on-submit.md +61 -0
  349. package/lessons/galaxy-tools/reference-index-not-on-server.md +62 -0
  350. package/lessons/log.md +42 -0
  351. package/lessons/reproduction/input-population-mismatch.md +59 -0
  352. package/lessons/reproduction/methods-text-vs-executed-parameters.md +62 -0
  353. package/lessons/snapshot.json +1004 -0
  354. package/lessons/stats/de-contrast-direction-and-sample-labels.md +63 -0
  355. package/lessons/stats/na-coerced-to-zero-in-filters.md +59 -0
  356. package/lessons/validate.mjs +1219 -0
  357. package/package.json +103 -5
  358. package/shared/agent-prompt.d.ts +8 -0
  359. package/shared/agent-prompt.js +15 -0
  360. package/shared/approval-prompt.d.ts +4 -0
  361. package/shared/approval-prompt.js +61 -0
  362. package/shared/brain-env.d.ts +14 -0
  363. package/shared/brain-env.js +108 -0
  364. package/shared/brain-exit.d.ts +20 -0
  365. package/shared/brain-exit.js +149 -0
  366. package/shared/capability-profile.d.ts +16 -0
  367. package/shared/capability-profile.js +75 -0
  368. package/shared/config-source.d.ts +13 -0
  369. package/shared/config-source.js +17 -0
  370. package/shared/confusables.d.ts +3 -0
  371. package/shared/confusables.js +93 -0
  372. package/shared/custom-provider.d.ts +45 -0
  373. package/shared/custom-provider.js +169 -0
  374. package/shared/dashboard-contract.d.ts +123 -0
  375. package/shared/dashboard-contract.js +560 -0
  376. package/shared/dashboard-layout-store.d.ts +44 -0
  377. package/shared/dashboard-layout-store.js +281 -0
  378. package/shared/feedback-contract.d.ts +61 -0
  379. package/shared/feedback-contract.js +146 -0
  380. package/shared/galaxy-artifact-links.d.ts +30 -0
  381. package/shared/galaxy-artifact-links.js +166 -0
  382. package/shared/galaxy-credentials.d.ts +26 -0
  383. package/shared/galaxy-credentials.js +71 -0
  384. package/shared/galaxy-destructive.d.ts +21 -0
  385. package/shared/galaxy-destructive.js +269 -0
  386. package/shared/galaxy-guidance.d.ts +2 -0
  387. package/shared/galaxy-guidance.js +53 -0
  388. package/shared/galaxy-live-contract.d.ts +92 -0
  389. package/shared/galaxy-live-contract.js +180 -0
  390. package/shared/galaxy-page-cells.d.ts +2 -0
  391. package/shared/galaxy-page-cells.js +22 -0
  392. package/shared/galaxy-tool-family.d.ts +5 -0
  393. package/shared/galaxy-tool-family.js +27 -0
  394. package/shared/galaxy-url.d.ts +1 -0
  395. package/shared/galaxy-url.js +48 -0
  396. package/shared/gtn.d.ts +31 -0
  397. package/shared/gtn.js +253 -0
  398. package/shared/handled-prompt.d.ts +3 -0
  399. package/shared/handled-prompt.js +26 -0
  400. package/shared/known-provider.d.ts +11 -0
  401. package/shared/known-provider.js +89 -0
  402. package/shared/lesson-hint-marker.d.ts +7 -0
  403. package/shared/lesson-hint-marker.js +32 -0
  404. package/shared/lesson-rules.d.ts +150 -0
  405. package/shared/lesson-rules.js +203 -0
  406. package/shared/malformed-object-ids.d.ts +1 -0
  407. package/shared/malformed-object-ids.js +37 -0
  408. package/shared/markdown-sections.d.ts +10 -0
  409. package/shared/markdown-sections.js +118 -0
  410. package/shared/notebook-fences.d.ts +12 -0
  411. package/shared/notebook-fences.js +53 -0
  412. package/shared/observation-contract.d.ts +91 -0
  413. package/shared/observation-contract.js +544 -0
  414. package/shared/orbit-config.d.ts +226 -0
  415. package/shared/orbit-config.js +189 -0
  416. package/shared/orbit-env.d.ts +13 -0
  417. package/shared/orbit-env.js +124 -0
  418. package/shared/orbit-shell-contract.d.ts +74 -0
  419. package/shared/orbit-shell-contract.js +30 -0
  420. package/shared/page-content-hash.d.ts +1 -0
  421. package/shared/page-content-hash.js +13 -0
  422. package/shared/pi-default-model.d.ts +7 -0
  423. package/shared/pi-default-model.js +41 -0
  424. package/shared/prompt-blocks.d.ts +87 -0
  425. package/shared/prompt-blocks.js +898 -0
  426. package/shared/provider-auth-caps.d.ts +22 -0
  427. package/shared/provider-auth-caps.js +57 -0
  428. package/shared/random.d.ts +2 -0
  429. package/shared/random.js +15 -0
  430. package/shared/record-excerpt.d.ts +4 -0
  431. package/shared/record-excerpt.js +16 -0
  432. package/shared/redirect-guard.d.ts +36 -0
  433. package/shared/redirect-guard.js +235 -0
  434. package/shared/skills-pin.d.ts +8 -0
  435. package/shared/skills-pin.js +9 -0
  436. package/shared/skills-router.d.ts +17 -0
  437. package/shared/skills-router.js +63 -0
  438. package/shared/sra-import.d.ts +34 -0
  439. package/shared/sra-import.js +206 -0
  440. package/shared/state-dir.d.ts +21 -0
  441. package/shared/state-dir.js +240 -0
  442. package/shared/team-dispatch-contract.d.ts +28 -0
  443. package/shared/team-dispatch-contract.js +1 -0
  444. package/shared/truncate-middle.d.ts +11 -0
  445. package/shared/truncate-middle.js +68 -0
  446. package/shared/version-compare.d.ts +10 -0
  447. package/shared/version-compare.js +74 -0
  448. package/shared/whats-new.d.ts +31 -0
  449. package/shared/whats-new.js +83 -0
  450. package/shared/wsl.d.ts +10 -0
  451. package/shared/wsl.js +24 -0
@@ -0,0 +1,318 @@
1
+ import { stripUntrustedMarkers } from "./galaxy-pages-sync.js";
2
+ import { stripGalaxyPageBlocks } from "./galaxy-page-binding.js";
3
+ import { readEnv } from "../../shared/orbit-env.js";
4
+
5
+ export function parsePageSyncMode(env: NodeJS.ProcessEnv): "auto" | "off" {
6
+ return readEnv("GALAXY_PAGE_SYNC", env) === "auto" ? "auto" : "off";
7
+ }
8
+
9
+ /** Deterministic per-history page identity so a fresh container finds the prior page. */
10
+ export function pageSlugForHistory(historyId: string): string {
11
+ return `orbit-${historyId}`;
12
+ }
13
+
14
+ export function pageTitleForHistory(historyId: string): string {
15
+ return `Orbit notebook (${historyId.slice(0, 8)})`;
16
+ }
17
+
18
+ /**
19
+ * The canonical comparison body: notebook content with the binding block and
20
+ * untrusted markers removed, matching exactly what pushNotebookToGalaxy persists
21
+ * locally. Used to dedupe pushes and break the watcher self-trigger loop.
22
+ */
23
+ export function strippedNotebookBody(content: string): string {
24
+ return stripUntrustedMarkers(stripGalaxyPageBlocks(content)).trim();
25
+ }
26
+
27
+ export function hasBodyChanged(prev: string | null, next: string): boolean {
28
+ return prev !== next;
29
+ }
30
+
31
+ import { getNotebookPath, onNotebookChange } from "./state.js";
32
+ import { readNotebook } from "./notebook-writer.js";
33
+ import { getGalaxyConfig, galaxyGetMostRecentHistory } from "./galaxy-api.js";
34
+ import { pushNotebookToGalaxy, resumeGalaxyPage } from "./galaxy-pages-sync.js";
35
+ import { listHistoryPages } from "./galaxy-pages-api.js";
36
+
37
+ export interface PageSyncDeps {
38
+ mode: "auto" | "off";
39
+ hasGalaxy: () => boolean;
40
+ getHistoryId: () => Promise<string | null>;
41
+ readBody: () => Promise<string>;
42
+ findPageId: (historyId: string, slug: string) => Promise<string | null>;
43
+ resume: (pageId: string) => Promise<void>;
44
+ push: (o: { historyId: string; slug: string; title: string }) => Promise<void>;
45
+ subscribe: (cb: () => void) => () => void;
46
+ debounceMs: number;
47
+ /**
48
+ * Cap on each init-time Galaxy call. init() runs inside session_start, so an
49
+ * unbounded history request against a wedged Galaxy hangs the session's whole
50
+ * startup rather than just costing us page sync.
51
+ */
52
+ initTimeoutMs?: number;
53
+ /**
54
+ * Don't re-attempt arming more often than this. Rate, not a total: a count cap
55
+ * would burn its whole budget on a handful of debounced edits during one short
56
+ * outage and then never sync again, which is the failure this is here to
57
+ * prevent. flush() ignores the cooldown -- shutdown is the last chance to save.
58
+ */
59
+ retryCooldownMs?: number;
60
+ /** Injectable clock so the cooldown is testable without wall time. */
61
+ now?: () => number;
62
+ }
63
+
64
+ const DEFAULT_INIT_TIMEOUT_MS = 15000;
65
+ const DEFAULT_RETRY_COOLDOWN_MS = 30000;
66
+
67
+ class TimeoutError extends Error {}
68
+
69
+ function withTimeout<T>(p: Promise<T>, ms: number, label: string): Promise<T> {
70
+ return new Promise((resolve, reject) => {
71
+ const timer = setTimeout(
72
+ () => reject(new TimeoutError(`${label} timed out after ${ms}ms`)),
73
+ ms,
74
+ );
75
+ p.then(
76
+ (v) => {
77
+ clearTimeout(timer);
78
+ resolve(v);
79
+ },
80
+ (err) => {
81
+ clearTimeout(timer);
82
+ reject(err);
83
+ },
84
+ );
85
+ });
86
+ }
87
+
88
+ export function createPageSyncEngine(deps: PageSyncDeps) {
89
+ let historyId: string | null = null;
90
+ let slug = "";
91
+ let lastBody: string | null = null;
92
+ let timer: ReturnType<typeof setTimeout> | null = null;
93
+ let unsubscribe: (() => void) | null = null;
94
+ let active = false;
95
+ let disposed = false;
96
+ let lastAttemptAt: number | null = null;
97
+ const initTimeoutMs = deps.initTimeoutMs ?? DEFAULT_INIT_TIMEOUT_MS;
98
+ const retryCooldownMs = deps.retryCooldownMs ?? DEFAULT_RETRY_COOLDOWN_MS;
99
+ const now = deps.now ?? (() => Date.now());
100
+ // Serialize pushes: at most one in flight; a change arriving mid-push queues
101
+ // exactly one follow-up so the latest body still lands. flush() awaits this.
102
+ let inFlight: Promise<void> | null = null;
103
+ let pendingAgain = false;
104
+
105
+ async function doPush(force = false): Promise<void> {
106
+ // A launch-time blip leaves us unarmed; retry here so the first change after
107
+ // Galaxy comes back recovers sync instead of the session running to its end
108
+ // with a notebook that only exists under /tmp.
109
+ if (!historyId && !(await arm(force))) return;
110
+ if (disposed || !historyId) return;
111
+ const body = await deps.readBody();
112
+ if (!hasBodyChanged(lastBody, body)) return; // dedupe + self-trigger guard
113
+ // Don't CREATE a page out of an empty notebook -- an untouched session has
114
+ // nothing worth publishing, and the baseline is null until a resume gives us
115
+ // a real one. Clearing a notebook we do have a baseline for is a real edit,
116
+ // though, so let that through rather than stranding deleted content in Galaxy.
117
+ if (body.length === 0 && lastBody === null) return;
118
+ await deps.push({ historyId, slug, title: pageTitleForHistory(historyId) });
119
+ lastBody = body;
120
+ }
121
+
122
+ // Run pushes one at a time. A change that lands while a push is in flight sets
123
+ // pendingAgain, so the loop runs doPush once more afterward -- never two
124
+ // concurrent pushes (which raced on lastBody and could double-create the
125
+ // page), and the latest body always wins. Returns the in-flight promise so
126
+ // flush() can await whatever is already running plus the queued follow-up.
127
+ function requestPush(force = false): Promise<void> {
128
+ if (inFlight) {
129
+ pendingAgain = true;
130
+ return inFlight;
131
+ }
132
+ inFlight = (async () => {
133
+ try {
134
+ do {
135
+ pendingAgain = false;
136
+ await doPush(force);
137
+ } while (pendingAgain);
138
+ } finally {
139
+ inFlight = null;
140
+ }
141
+ })();
142
+ return inFlight;
143
+ }
144
+
145
+ /**
146
+ * Resolve the history and adopt any prior page for it. Returns true once the
147
+ * engine can push. Safe to call repeatedly: it no-ops once armed, and a failed
148
+ * attempt won't retry until the cooldown passes (force skips the wait).
149
+ *
150
+ * Nothing is committed until discovery has actually succeeded. Committing
151
+ * historyId first, as this used to, meant a single failed page listing left the
152
+ * engine armed but unaware of an existing page -- the next push would then take
153
+ * the create path and either duplicate the page or fight its slug forever, with
154
+ * no way to re-run discovery.
155
+ */
156
+ async function arm(force = false): Promise<boolean> {
157
+ if (historyId) return true;
158
+ if (!force && lastAttemptAt !== null && now() - lastAttemptAt < retryCooldownMs) return false;
159
+ lastAttemptAt = now();
160
+
161
+ let resolvedHistory: string | null;
162
+ try {
163
+ resolvedHistory = await withTimeout(deps.getHistoryId(), initTimeoutMs, "history lookup");
164
+ } catch (err) {
165
+ console.error("[page-sync] history lookup failed:", err);
166
+ return false;
167
+ }
168
+ if (disposed || !resolvedHistory) return false;
169
+
170
+ const resolvedSlug = pageSlugForHistory(resolvedHistory);
171
+ // Galaxy's GET /pages/{id} takes a page id, not a slug, so resolve the
172
+ // per-history page id by listing the history's pages and matching the
173
+ // derived slug, then resume by id. A fresh container has no local binding,
174
+ // so listing is the only way to rediscover the page.
175
+ let existingPageId: string | null;
176
+ try {
177
+ existingPageId = await withTimeout(
178
+ deps.findPageId(resolvedHistory, resolvedSlug),
179
+ initTimeoutMs,
180
+ "page listing",
181
+ );
182
+ } catch (err) {
183
+ // Can't tell "no prior page" from "couldn't ask". Assuming the former is
184
+ // how you end up with two pages for one history, so stay unarmed and retry.
185
+ console.error("[page-sync] page listing failed:", err);
186
+ return false;
187
+ }
188
+ if (disposed) return false;
189
+
190
+ let resumed = false;
191
+ if (existingPageId) {
192
+ try {
193
+ // Timed out like the others: init() runs inside session_start, and a page
194
+ // GET that accepts the connection then never answers would hang startup.
195
+ await withTimeout(deps.resume(existingPageId), initTimeoutMs, "page resume");
196
+ resumed = true;
197
+ } catch (err) {
198
+ // The page exists but we couldn't read it. Pushing now would overwrite it
199
+ // with a notebook that never saw its content, so leave the engine unarmed
200
+ // and try the whole adoption again later.
201
+ console.error("[page-sync] resume failed:", err);
202
+ return false;
203
+ }
204
+ }
205
+ if (disposed) return false;
206
+
207
+ historyId = resolvedHistory;
208
+ slug = resolvedSlug;
209
+ // Baseline only from a resume, where the notebook now mirrors the page and
210
+ // the write we just made would otherwise self-trigger a pointless push.
211
+ // Without a resume the local notebook is the authoritative copy, so leave
212
+ // the baseline empty and let the next push carry it to Galaxy -- seeding it
213
+ // from disk here is what made a recovered session flush nothing at all.
214
+ lastBody = resumed ? await deps.readBody() : null;
215
+ return true;
216
+ }
217
+
218
+ async function init(): Promise<void> {
219
+ if (deps.mode !== "auto" || !deps.hasGalaxy()) return;
220
+ await arm();
221
+ // Subscribe regardless: an unarmed engine retries on the next change (see
222
+ // doPush), so a Galaxy that's down at launch no longer disables sync for the
223
+ // whole session.
224
+ active = true;
225
+ unsubscribe = deps.subscribe(() => {
226
+ if (timer) clearTimeout(timer);
227
+ timer = setTimeout(() => {
228
+ timer = null;
229
+ void requestPush().catch((err) => console.error("[page-sync] push failed:", err));
230
+ }, deps.debounceMs);
231
+ });
232
+ }
233
+
234
+ async function flush(): Promise<void> {
235
+ if (!active || disposed) return;
236
+ if (timer) {
237
+ clearTimeout(timer);
238
+ timer = null;
239
+ }
240
+ try {
241
+ // force: shutdown is the last chance to get this into Galaxy, so don't sit
242
+ // out a retry cooldown that happens to still be running.
243
+ await requestPush(true);
244
+ } catch (err) {
245
+ console.error("[page-sync] flush push failed:", err);
246
+ }
247
+ }
248
+
249
+ function dispose(): void {
250
+ if (timer) clearTimeout(timer);
251
+ timer = null;
252
+ if (unsubscribe) unsubscribe();
253
+ unsubscribe = null;
254
+ active = false;
255
+ // An arm() started before dispose can still be waiting on Galaxy, and it
256
+ // resolves against whatever notebook is current by then -- a later session's.
257
+ // Its resume would overwrite that session's notebook with this one's page, so
258
+ // the checks after each await bail on a disposed engine.
259
+ disposed = true;
260
+ historyId = null;
261
+ lastBody = null;
262
+ pendingAgain = false;
263
+ lastAttemptAt = null;
264
+ }
265
+
266
+ return { init, flush, dispose };
267
+ }
268
+
269
+ // ── Module-level wiring with the real dependencies ────────────────────────────
270
+
271
+ let engine: ReturnType<typeof createPageSyncEngine> | null = null;
272
+
273
+ const DEBOUNCE_MS = parseInt(readEnv("GALAXY_PAGE_SYNC_DEBOUNCE_MS") ?? "1500", 10);
274
+
275
+ function realDeps(): PageSyncDeps {
276
+ return {
277
+ mode: parsePageSyncMode(process.env),
278
+ hasGalaxy: () => getGalaxyConfig() != null,
279
+ getHistoryId: async () => (await galaxyGetMostRecentHistory())?.id ?? null,
280
+ readBody: async () => {
281
+ const p = getNotebookPath();
282
+ if (!p) return "";
283
+ return strippedNotebookBody(await readNotebook(p));
284
+ },
285
+ findPageId: async (historyId, slug) => {
286
+ const pages = await listHistoryPages(historyId);
287
+ const match = pages.find((p) => p.slug === slug);
288
+ return match ? match.id : null;
289
+ },
290
+ resume: async (pageId) => {
291
+ await resumeGalaxyPage(pageId);
292
+ },
293
+ push: async ({ historyId, slug, title }) => {
294
+ await pushNotebookToGalaxy({ historyId, slug, title });
295
+ },
296
+ subscribe: (cb) => onNotebookChange(() => cb()),
297
+ debounceMs: Number.isFinite(DEBOUNCE_MS) ? DEBOUNCE_MS : 1500,
298
+ };
299
+ }
300
+
301
+ export async function initGalaxyPageSync(): Promise<void> {
302
+ resetGalaxyPageSync();
303
+ engine = createPageSyncEngine(realDeps());
304
+ try {
305
+ await engine.init();
306
+ } catch (err) {
307
+ console.error("[page-sync] init failed:", err);
308
+ }
309
+ }
310
+
311
+ export async function flushNotebookToGalaxy(): Promise<void> {
312
+ if (engine) await engine.flush();
313
+ }
314
+
315
+ export function resetGalaxyPageSync(): void {
316
+ if (engine) engine.dispose();
317
+ engine = null;
318
+ }
@@ -0,0 +1,203 @@
1
+ /**
2
+ * Galaxy Pages API client — typed wrappers for the /api/pages endpoints
3
+ * introduced in galaxyproject/galaxy#22361 (Galaxy Notebooks).
4
+ *
5
+ * Contract matches Galaxy PR #22361 @ 8c702ecd. The PR is still open and the
6
+ * shape may move; tests use hand-rolled fixtures pinned to that SHA. When the
7
+ * PR merges, re-verify against the released contract.
8
+ *
9
+ * Notes on the contract corrections this client makes vs. an earlier draft:
10
+ *
11
+ * - `GET /api/pages/{id}/revisions` returns `PageRevisionSummary[]` —
12
+ * `{id, page_id, edit_source, create_time, update_time}` only, no
13
+ * content or title. Full body is at
14
+ * `GET /api/pages/{id}/revisions/{revision_id}` which returns
15
+ * `PageRevisionDetails`. Two calls, not one.
16
+ *
17
+ * - `edit_source` is only meaningful on the update payload. The create
18
+ * payload silently drops it (`extra="allow"` on the pydantic model),
19
+ * so don't send it on create.
20
+ *
21
+ * - `content_format` defaults to `"html"` server-side; always pass
22
+ * `"markdown"` explicitly for notebook content.
23
+ *
24
+ * The model's page tools do not go through this client. get_page and update_page
25
+ * are galaxy-ops operations, widened in galaxy-page-ops.ts until galaxy-ops ships
26
+ * #155's S6, and `updatePage` here always sends `content_format`, which would
27
+ * relabel a page authored as HTML.
28
+ */
29
+
30
+ import { galaxyGet, galaxyPost, galaxyPut } from "./galaxy-api";
31
+
32
+ // ─────────────────────────────────────────────────────────────────────────────
33
+ // Types
34
+ // ─────────────────────────────────────────────────────────────────────────────
35
+
36
+ /**
37
+ * Typed subset of upstream `PageSummary` (galaxyproject/galaxy schema.py).
38
+ * Includes only the fields the sync layer consumes; other required fields
39
+ * (username, email_hash, published, deleted, etc.) are returned by the API
40
+ * but unused here. `latest_revision_id` is the field push/pull stores into
41
+ * the binding's `last_synced_revision` after every successful sync.
42
+ */
43
+ export interface GalaxyPageSummary {
44
+ id: string;
45
+ title: string;
46
+ slug: string | null;
47
+ history_id?: string | null;
48
+ latest_revision_id: string;
49
+ revision_ids?: string[];
50
+ create_time: string;
51
+ update_time: string;
52
+ }
53
+
54
+ export interface GalaxyPage extends GalaxyPageSummary {
55
+ /** The embed-expanded render; `content_editor` is the source the agent edits. */
56
+ content?: string;
57
+ content_editor?: string;
58
+ content_format?: "markdown" | "html";
59
+ edit_source?: "user" | "agent" | "restore";
60
+ }
61
+
62
+ /** What `GET /api/pages/{id}/revisions` actually returns — no content. */
63
+ export interface GalaxyPageRevisionSummary {
64
+ id: string;
65
+ page_id: string;
66
+ edit_source?: "user" | "agent" | "restore";
67
+ create_time: string;
68
+ update_time: string;
69
+ }
70
+
71
+ /** What `GET /api/pages/{id}/revisions/{revision_id}` returns — full body. */
72
+ export interface GalaxyPageRevisionDetails extends GalaxyPageRevisionSummary {
73
+ title?: string;
74
+ content?: string;
75
+ content_format?: "markdown" | "html";
76
+ }
77
+
78
+ export interface CreatePageParams {
79
+ title: string;
80
+ content: string;
81
+ history_id: string;
82
+ slug?: string;
83
+ content_format?: "markdown" | "html";
84
+ annotation?: string;
85
+ }
86
+
87
+ export interface UpdatePageParams {
88
+ content: string;
89
+ title?: string;
90
+ content_format?: "markdown" | "html";
91
+ annotation?: string;
92
+ /** Agent-authored edits should set this to "agent" for provenance. */
93
+ edit_source?: "user" | "agent";
94
+ }
95
+
96
+ // ─────────────────────────────────────────────────────────────────────────────
97
+ // Pages API
98
+ // ─────────────────────────────────────────────────────────────────────────────
99
+
100
+ export async function listHistoryPages(
101
+ historyId: string,
102
+ signal?: AbortSignal,
103
+ ): Promise<GalaxyPageSummary[]> {
104
+ return galaxyGet<GalaxyPageSummary[]>(
105
+ `/pages?history_id=${encodeURIComponent(historyId)}`,
106
+ signal,
107
+ );
108
+ }
109
+
110
+ /** A page entry trimmed to what the discovery tool surfaces. `history_id` is
111
+ * the load-bearing field: a real history notebook has one, a workflow
112
+ * *invocation report* has `null` -- only the former can be resumed and read
113
+ * back as a bound history. */
114
+ export interface RecentPage {
115
+ page_id: string;
116
+ title: string;
117
+ slug: string | null;
118
+ history_id: string | null;
119
+ update_time: string;
120
+ }
121
+
122
+ /**
123
+ * List the user's own pages, most-recently-updated first. Wraps the unscoped
124
+ * `GET /api/pages` (which Galaxy returns in ascending update order, so we sort
125
+ * client-side) and projects each entry down to the fields a cold-start resume
126
+ * needs to pick a page. `limit` caps the returned list; pass 0 / omit for all.
127
+ */
128
+ export async function listRecentPages(
129
+ opts: { limit?: number } = {},
130
+ signal?: AbortSignal,
131
+ ): Promise<RecentPage[]> {
132
+ const pages = await galaxyGet<GalaxyPageSummary[]>("/pages", signal);
133
+ const sorted = [...pages].sort((a, b) =>
134
+ (b.update_time ?? "").localeCompare(a.update_time ?? ""),
135
+ );
136
+ const limited = opts.limit && opts.limit > 0 ? sorted.slice(0, opts.limit) : sorted;
137
+ return limited.map((p) => ({
138
+ page_id: p.id,
139
+ title: p.title,
140
+ slug: p.slug ?? null,
141
+ history_id: p.history_id ?? null,
142
+ update_time: p.update_time,
143
+ }));
144
+ }
145
+
146
+ export async function getPage(pageId: string, signal?: AbortSignal): Promise<GalaxyPage> {
147
+ return galaxyGet<GalaxyPage>(`/pages/${encodeURIComponent(pageId)}`, signal);
148
+ }
149
+
150
+ export async function createPage(
151
+ params: CreatePageParams,
152
+ signal?: AbortSignal,
153
+ ): Promise<GalaxyPageSummary> {
154
+ const body: Record<string, unknown> = {
155
+ title: params.title,
156
+ content: params.content,
157
+ content_format: params.content_format ?? "markdown",
158
+ history_id: params.history_id,
159
+ };
160
+ if (params.slug !== undefined) body.slug = params.slug;
161
+ if (params.annotation !== undefined) body.annotation = params.annotation;
162
+ return galaxyPost<GalaxyPageSummary>("/pages", body, signal);
163
+ }
164
+
165
+ export async function updatePage(
166
+ pageId: string,
167
+ params: UpdatePageParams,
168
+ signal?: AbortSignal,
169
+ ): Promise<GalaxyPageSummary> {
170
+ // Every update flowing through this client is Orbit-authored sync, so
171
+ // default `edit_source` to "agent" rather than making each call site
172
+ // remember to set it. Callers can still pass an explicit value to
173
+ // override (e.g. a future "manual revert" path setting "user").
174
+ const body: Record<string, unknown> = {
175
+ content: params.content,
176
+ content_format: params.content_format ?? "markdown",
177
+ edit_source: params.edit_source ?? "agent",
178
+ };
179
+ if (params.title !== undefined) body.title = params.title;
180
+ if (params.annotation !== undefined) body.annotation = params.annotation;
181
+ return galaxyPut<GalaxyPageSummary>(`/pages/${encodeURIComponent(pageId)}`, body, signal);
182
+ }
183
+
184
+ export async function getPageRevisions(
185
+ pageId: string,
186
+ signal?: AbortSignal,
187
+ ): Promise<GalaxyPageRevisionSummary[]> {
188
+ return galaxyGet<GalaxyPageRevisionSummary[]>(
189
+ `/pages/${encodeURIComponent(pageId)}/revisions`,
190
+ signal,
191
+ );
192
+ }
193
+
194
+ export async function getPageRevisionDetails(
195
+ pageId: string,
196
+ revisionId: string,
197
+ signal?: AbortSignal,
198
+ ): Promise<GalaxyPageRevisionDetails> {
199
+ return galaxyGet<GalaxyPageRevisionDetails>(
200
+ `/pages/${encodeURIComponent(pageId)}/revisions/${encodeURIComponent(revisionId)}`,
201
+ signal,
202
+ );
203
+ }