@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,502 @@
1
+ /**
2
+ * Reading Galaxy ids out of a submission tool's result.
3
+ *
4
+ * Pure functions, no I/O and no notebook writes -- the capture hook in
5
+ * galaxy-submission-capture.ts does that part. The shapes were first read out
6
+ * of galaxy-mcp 1.9.0's source rather than its docstrings (spike:
7
+ * `2026-09-16-galaxy-mcp-result-shapes.md`); galaxy-ops ports those operations
8
+ * and returns the same envelope.
9
+ *
10
+ * The rule the whole module is built around: **never guess an id.** A parse
11
+ * that cannot find the field it is looking for, in the shape it expects,
12
+ * returns a reason instead of a value, and the caller logs
13
+ * `submission.unparsed`. A wrong id is worse than no id -- it binds a
14
+ * notebook block, and later a provenance record, to work nobody did.
15
+ *
16
+ * ## What the result actually looks like
17
+ *
18
+ * Every Galaxy tool returns the `GalaxyResult` envelope
19
+ * (`{data, success, message, count?, pagination?}`) as the result's
20
+ * `structuredContent`, with one text block holding the same object as JSON.
21
+ * So the payload is always JSON, never prose -- parse it, don't regex it.
22
+ *
23
+ * Two things can get in the way (galaxy-tool-wrap.ts):
24
+ *
25
+ * 1. pi drops `structuredContent` whenever a `tool_result` handler replaces
26
+ * the content -- secret redaction, for one -- and the big results are the
27
+ * ones that matter most.
28
+ * 2. Past the spill size the text is a bounded preview, not the JSON. The
29
+ * full text is in the Galaxy output store under `details.galaxy.outputId`
30
+ * (details survive those handlers), so `resolveResultPayload` reports it
31
+ * and the caller re-reads from it rather than losing the biggest
32
+ * submissions. Its `CallToolResult` and `details.fullOutputPath` branches
33
+ * are the shapes pi's MCP layer produced.
34
+ */
35
+
36
+ import * as path from "path";
37
+
38
+ /** What a submission tool produces, and therefore which block it writes. */
39
+ export type SubmissionKind = "invocation" | "jobs" | "udt";
40
+
41
+ /**
42
+ * Tools whose success means work was submitted to Galaxy.
43
+ *
44
+ * `upload_file` is here alongside the URL one: both go through
45
+ * `POST /api/tools` and return the same envelope, so recording one and not the
46
+ * other would leave a silent hole for a shell that offers it.
47
+ */
48
+ export const SUBMISSION_TOOLS: Readonly<Record<string, SubmissionKind>> = {
49
+ invoke_workflow: "invocation",
50
+ run_tool: "jobs",
51
+ run_user_tool: "jobs",
52
+ upload_file_from_url: "jobs",
53
+ upload_file: "jobs",
54
+ // Orbit-native (galaxy-upload.ts), not a galaxy-ops operation: its result shape
55
+ // is ours, so it is parsed from `details` rather than from the JSON text.
56
+ galaxy_upload_local_file: "jobs",
57
+ create_user_tool: "udt",
58
+ };
59
+
60
+ export function isSubmissionTool(toolName: string | undefined): boolean {
61
+ return !!toolName && toolName in SUBMISSION_TOOLS;
62
+ }
63
+
64
+ /** One Galaxy job as the submission response described it. */
65
+ export interface SubmittedJob {
66
+ jobId: string;
67
+ toolId?: string;
68
+ /**
69
+ * Captured here on purpose: `GET /api/jobs/{id}` drops `tool_version`
70
+ * (no model in the response chain declares it, so pydantic's default
71
+ * `extra="ignore"` discards it), and the submission response is the only
72
+ * place it reliably survives.
73
+ */
74
+ toolVersion?: string;
75
+ historyId?: string;
76
+ /**
77
+ * Galaxy's job state when the submission call returned. Only set when the
78
+ * caller already waited the work out -- Orbit's uploader blocks until ingest
79
+ * finishes, so an `ok` upload is done before its block is ever written.
80
+ */
81
+ state?: string;
82
+ }
83
+
84
+ export interface ParsedSubmission {
85
+ kind: SubmissionKind;
86
+ /** Set when `kind === "invocation"`. */
87
+ invocationId?: string;
88
+ /** Set when `kind === "jobs"`; always at least one entry. */
89
+ jobs?: SubmittedJob[];
90
+ /** Set when `kind === "udt"`. */
91
+ udt?: { toolId: string; uuid: string; representation: unknown };
92
+ historyId?: string;
93
+ label: string;
94
+ /**
95
+ * True when Galaxy reported that some jobs in the request did not start
96
+ * (`data.errors` on a `POST /api/tools` response). The jobs that did start
97
+ * are still real and still recorded; the caller notes the partial failure.
98
+ */
99
+ partial?: boolean;
100
+ }
101
+
102
+ export type ParseOutcome =
103
+ { ok: true; submission: ParsedSubmission } | { ok: false; reason: string };
104
+
105
+ function fail(reason: string): ParseOutcome {
106
+ return { ok: false, reason };
107
+ }
108
+
109
+ // ─────────────────────────────────────────────────────────────────────────────
110
+ // Getting at the payload
111
+ // ─────────────────────────────────────────────────────────────────────────────
112
+
113
+ export interface ResolvedResult {
114
+ /** A structured payload, when pi handed one over directly. */
115
+ value?: unknown;
116
+ /** The result text to JSON.parse. */
117
+ text?: string;
118
+ /** pi's full-output file for a truncated result; the caller may re-read it. */
119
+ truncatedPath?: string;
120
+ /**
121
+ * The in-memory saved copy of an in-process Galaxy result that was too big to
122
+ * show in full; the caller may re-read it.
123
+ */
124
+ outputId?: string;
125
+ /** Orbit-native tool details, when the tool is one of ours. */
126
+ details?: Record<string, unknown>;
127
+ }
128
+
129
+ function asRecord(value: unknown): Record<string, unknown> | null {
130
+ return value && typeof value === "object" && !Array.isArray(value)
131
+ ? (value as Record<string, unknown>)
132
+ : null;
133
+ }
134
+
135
+ function firstTextBlock(content: unknown): string | undefined {
136
+ if (!Array.isArray(content)) return undefined;
137
+ for (const block of content) {
138
+ const b = asRecord(block);
139
+ if (b && b.type === "text" && typeof b.text === "string") return b.text;
140
+ }
141
+ return undefined;
142
+ }
143
+
144
+ /**
145
+ * Pull the parseable payload out of a `tool_execution_end` result.
146
+ *
147
+ * The result is pi's `AgentToolResult` (`{content, details, structuredContent?}`).
148
+ * Preference order is least-mangled-first: the untruncated `CallToolResult`
149
+ * pi keeps in `structuredContent`, then the text block, with the full-output
150
+ * file reported for the caller to fall back on.
151
+ *
152
+ * An in-process Galaxy tool (marked by `details.galaxy`, which only its wrapper
153
+ * sets) keeps the envelope itself in `structuredContent` rather than a whole
154
+ * `CallToolResult`, and names its saved copy in `details.galaxy.outputId`. The
155
+ * flat envelope is taken only behind that marker, so an MCP result reads
156
+ * exactly as it always has. The text and saved-copy paths stay load-bearing:
157
+ * pi drops `structuredContent` whenever a `tool_result` handler rewrites the
158
+ * content, never persists it, and the browser shim never forwards it.
159
+ */
160
+ export function resolveResultPayload(result: unknown): ResolvedResult {
161
+ if (typeof result === "string") return { text: result };
162
+
163
+ const r = asRecord(result);
164
+ if (!r) return {};
165
+
166
+ const details = asRecord(r.details) ?? undefined;
167
+ const out: ResolvedResult = { details };
168
+
169
+ if (typeof details?.fullOutputPath === "string") {
170
+ out.truncatedPath = details.fullOutputPath;
171
+ }
172
+
173
+ const galaxy = asRecord(details?.galaxy);
174
+ if (galaxy) {
175
+ if (typeof galaxy.outputId === "string") out.outputId = galaxy.outputId;
176
+ const envelope = asRecord(r.structuredContent);
177
+ if (envelope && "data" in envelope) {
178
+ out.value = envelope;
179
+ return out;
180
+ }
181
+ }
182
+
183
+ const call = asRecord(r.structuredContent);
184
+ if (call) {
185
+ const structured = asRecord(call.structuredContent);
186
+ if (structured) {
187
+ out.value = structured;
188
+ return out;
189
+ }
190
+ const text = firstTextBlock(call.content);
191
+ if (text !== undefined) {
192
+ out.text = text;
193
+ return out;
194
+ }
195
+ }
196
+
197
+ const text = firstTextBlock(r.content);
198
+ if (text !== undefined) out.text = text;
199
+ return out;
200
+ }
201
+
202
+ /**
203
+ * Parse the `GalaxyResult` envelope. Returns null when the text is not the
204
+ * envelope we expect -- truncated, prose, or some other tool's shape.
205
+ */
206
+ export function parseGalaxyResultEnvelope(
207
+ resolved: ResolvedResult,
208
+ ): Record<string, unknown> | null {
209
+ let value: unknown = resolved.value;
210
+ if (value === undefined) {
211
+ if (resolved.text === undefined) return null;
212
+ try {
213
+ value = JSON.parse(resolved.text);
214
+ } catch {
215
+ return null;
216
+ }
217
+ }
218
+ const envelope = asRecord(value);
219
+ if (!envelope) return null;
220
+ // `success` defaults to true on the model and every submission tool raises
221
+ // rather than returning false, so the field is usually absent-or-true. Only
222
+ // those two are accepted: a `success` of `"false"`, `0` or `null` is not a
223
+ // GalaxyResult we recognise, and reading it as a success would register a
224
+ // run off a payload we do not understand.
225
+ if ("success" in envelope && envelope.success !== true) return null;
226
+ if (!("data" in envelope)) return null;
227
+ return envelope;
228
+ }
229
+
230
+ // ─────────────────────────────────────────────────────────────────────────────
231
+ // Per-tool parsers
232
+ // ─────────────────────────────────────────────────────────────────────────────
233
+
234
+ function str(value: unknown): string | undefined {
235
+ return typeof value === "string" && value.trim().length > 0 ? value : undefined;
236
+ }
237
+
238
+ /**
239
+ * Accept a value only if it is shaped like an id that can survive a block.
240
+ *
241
+ * The blocks are line-oriented `key: value`, and the id scalars are written
242
+ * unescaped, so an id containing a newline renders as a SECOND `job_id:` line
243
+ * and the parser -- last key wins -- reads back a different id than the one
244
+ * Galaxy returned. That is the precise failure this whole module exists to
245
+ * prevent, so it is rejected at the boundary rather than escaped downstream:
246
+ * a Galaxy id with a newline, a tab or a control character in it is not a
247
+ * Galaxy id, and refusing beats inventing an escaping scheme that the two
248
+ * block parsers would then have to agree on.
249
+ *
250
+ * Deliberately not `/^[0-9a-f]{16}$/`: ids are 16-char lowercase hex on the
251
+ * usual servers, but tool ids are toolshed paths, UDT ids are uuids, and a
252
+ * server with a different id encoding is still a server we should record.
253
+ */
254
+ const MAX_ID_LENGTH = 512;
255
+
256
+ export function idToken(value: unknown): string | undefined {
257
+ const raw = str(value);
258
+ if (!raw) return undefined;
259
+ const trimmed = raw.trim();
260
+ if (trimmed.length === 0 || trimmed.length > MAX_ID_LENGTH) return undefined;
261
+ // No whitespace at all (newline, tab, space) and no C0/C1 control chars.
262
+ if (/[\s\u0000-\u001f\u007f-\u009f]/.test(trimmed)) return undefined;
263
+ return trimmed;
264
+ }
265
+
266
+ /** Trim a label to something a notebook row can show without wrapping. */
267
+ function label(text: string, max = 80): string {
268
+ const flat = text.replace(/\s+/g, " ").trim();
269
+ return flat.length <= max ? flat : flat.slice(0, max - 1) + "…";
270
+ }
271
+
272
+ /**
273
+ * A workflow invocation. `POST /api/workflows/{id}/invocations` answers with
274
+ * the *collection* view (`WorkflowInvocationResponse` is a left-to-right
275
+ * union and `to_dict()` defaults to `view="collection"`), so there are no
276
+ * `steps` and no job ids here -- only the invocation itself. `model_class` is
277
+ * checked so a differently-shaped success can't be read as an invocation.
278
+ */
279
+ function parseInvokeWorkflow(data: unknown, args: Record<string, unknown>): ParseOutcome {
280
+ if (Array.isArray(data)) {
281
+ // Batch invocation answers with a list. galaxy-ops never sets `batch`, so
282
+ // reaching this means the contract moved; refuse rather than pick one.
283
+ return fail("invoke_workflow returned a list (batch invocation); not registering");
284
+ }
285
+ const d = asRecord(data);
286
+ if (!d) return fail("invoke_workflow result has no data object");
287
+
288
+ const modelClass = str(d.model_class);
289
+ if (modelClass !== "WorkflowInvocation") {
290
+ return fail(`invoke_workflow data.model_class is ${modelClass ?? "missing"}`);
291
+ }
292
+ const invocationId = idToken(d.id);
293
+ if (!invocationId) return fail("invoke_workflow data.id is missing or not an id-shaped string");
294
+
295
+ const workflowId = str(d.workflow_id) ?? str(args.workflow_id);
296
+ return {
297
+ ok: true,
298
+ submission: {
299
+ kind: "invocation",
300
+ invocationId,
301
+ historyId: idToken(d.history_id) ?? idToken(args.history_id),
302
+ label: label(workflowId ? `Workflow ${workflowId}` : "Galaxy workflow"),
303
+ },
304
+ };
305
+ }
306
+
307
+ /**
308
+ * Anything that goes through `POST /api/tools`: `run_tool`, `run_user_tool`,
309
+ * and both uploads. `data.jobs` is authoritative and is a list even for a
310
+ * single job -- a map-over submission puts one entry per job there while
311
+ * `data.outputs` can be empty (the outputs surface as
312
+ * `data.implicit_collections` instead).
313
+ */
314
+ function parseToolRun(
315
+ data: unknown,
316
+ args: Record<string, unknown>,
317
+ labelFor: (jobs: SubmittedJob[]) => string,
318
+ ): ParseOutcome {
319
+ const d = asRecord(data);
320
+ if (!d) return fail("tool run result has no data object");
321
+ if (!Array.isArray(d.jobs)) return fail("tool run data.jobs is missing or not a list");
322
+
323
+ const jobs: SubmittedJob[] = [];
324
+ for (const entry of d.jobs) {
325
+ const j = asRecord(entry);
326
+ const jobId = j ? idToken(j.id) : undefined;
327
+ // One malformed entry means we do not know how many jobs really started,
328
+ // so the whole submission is unparsed rather than partly recorded.
329
+ if (!j || !jobId) return fail("tool run data.jobs has an entry with no id-shaped id");
330
+ // Galaxy's job dicts carry `model_class: "Job"`. When the field is there
331
+ // it has to say Job: an invocation id written into a job block sends the
332
+ // pollers to /api/jobs/<invocation id>, which fails quietly forever.
333
+ // Checked only when present, so a server that omits it still records.
334
+ const modelClass = str(j.model_class);
335
+ if (modelClass && modelClass !== "Job") {
336
+ return fail(`tool run data.jobs entry has model_class ${modelClass}, expected Job`);
337
+ }
338
+ jobs.push({
339
+ jobId,
340
+ toolId: idToken(j.tool_id),
341
+ toolVersion: idToken(j.tool_version),
342
+ historyId: idToken(j.history_id),
343
+ });
344
+ }
345
+ if (jobs.length === 0) return fail("tool run data.jobs is empty");
346
+
347
+ // Present only on partial failure, when some jobs ran and some did not.
348
+ const errors = d.errors;
349
+ const partial = Array.isArray(errors)
350
+ ? errors.length > 0
351
+ : !!asRecord(errors) && Object.keys(asRecord(errors)!).length > 0;
352
+
353
+ return {
354
+ ok: true,
355
+ submission: {
356
+ kind: "jobs",
357
+ jobs,
358
+ // Where Galaxy says the jobs landed beats where they were requested to
359
+ // land: the block claims server_verified, so every field on it should be
360
+ // the server's answer wherever the server gave one.
361
+ historyId: jobs[0].historyId ?? idToken(args.history_id),
362
+ label: label(labelFor(jobs)),
363
+ ...(partial ? { partial: true } : {}),
364
+ },
365
+ };
366
+ }
367
+
368
+ /**
369
+ * A user-defined tool creation. `data` is Galaxy's `UnprivilegedToolResponse`;
370
+ * `representation` there is the stored (and lifted) definition, which is
371
+ * better provenance than the agent's input because it is what Galaxy will
372
+ * actually run. `tool_id` is nullable in the schema, so fall back to the
373
+ * definition's own id before giving up.
374
+ */
375
+ function parseCreateUserTool(data: unknown, _args: Record<string, unknown>): ParseOutcome {
376
+ const d = asRecord(data);
377
+ if (!d) return fail("create_user_tool result has no data object");
378
+
379
+ const uuid = idToken(d.uuid);
380
+ if (!uuid) return fail("create_user_tool data.uuid is missing or not an id-shaped string");
381
+
382
+ // Only what Galaxy stored. The agent's own `args.representation` is NOT a
383
+ // fallback: preserving it under a block that says the harness recorded this
384
+ // would file the agent's draft as the definition Galaxy will actually run,
385
+ // and those can differ (Galaxy lifts and validates the representation on the
386
+ // way in). With nothing server-side to preserve there is nothing to claim.
387
+ const representation = d.representation;
388
+ const repr = asRecord(representation);
389
+ if (representation === undefined || !repr) {
390
+ return fail("create_user_tool returned no stored representation to preserve");
391
+ }
392
+ const toolId = idToken(d.tool_id) ?? idToken(repr.id);
393
+ if (!toolId) return fail("create_user_tool has no id-shaped tool id");
394
+
395
+ return {
396
+ ok: true,
397
+ submission: {
398
+ kind: "udt",
399
+ udt: { toolId, uuid, representation },
400
+ label: label(`User tool ${str(repr.name) ?? toolId}`),
401
+ },
402
+ };
403
+ }
404
+
405
+ /**
406
+ * Orbit's own uploader. Not an MCP passthrough, so the ids come from the tool's
407
+ * `details` rather than from a `GalaxyResult`: `galaxy-upload.ts` reads
408
+ * `jobs[]` off the `/tools/fetch` response and carries the ids there.
409
+ */
410
+ function parseLocalUpload(
411
+ details: Record<string, unknown> | undefined,
412
+ args: Record<string, unknown>,
413
+ ): ParseOutcome {
414
+ if (!details) return fail("upload result carried no details");
415
+ if (details.error) return fail("upload reported a failure");
416
+ if (!Array.isArray(details.jobs)) return fail("upload details carry no job ids");
417
+
418
+ const jobs: SubmittedJob[] = [];
419
+ for (const entry of details.jobs) {
420
+ const jobId = idToken(entry);
421
+ if (!jobId) return fail("upload details.jobs has an entry that is not an id-shaped string");
422
+ jobs.push({ jobId, toolId: "__DATA_FETCH__" });
423
+ }
424
+ // The uploader waited ingest out, so a dataset in `ok` means its upload job
425
+ // already finished. Anything else (the wait timed out) stays for the poller.
426
+ if (details.state === "ok") for (const job of jobs) job.state = "ok";
427
+ if (jobs.length === 0) return fail("upload details.jobs is empty");
428
+
429
+ const fileName = str(args.file_name) ?? (str(args.path) ? path.basename(String(args.path)) : "");
430
+ return {
431
+ ok: true,
432
+ submission: {
433
+ kind: "jobs",
434
+ jobs,
435
+ historyId: idToken(details.historyId) ?? idToken(args.history_id),
436
+ label: label(fileName ? `Upload ${fileName}` : "Upload to Galaxy"),
437
+ },
438
+ };
439
+ }
440
+
441
+ // ─────────────────────────────────────────────────────────────────────────────
442
+ // Entry point
443
+ // ─────────────────────────────────────────────────────────────────────────────
444
+
445
+ /**
446
+ * Parse a successful submission tool result into the ids to record.
447
+ *
448
+ * `args` is the tool's own input, captured at dispatch: `run_user_tool` never
449
+ * echoes the uuid it was given, and the uploads' file names live only there.
450
+ */
451
+ export function parseSubmission(
452
+ toolName: string,
453
+ args: Record<string, unknown>,
454
+ resolved: ResolvedResult,
455
+ ): ParseOutcome {
456
+ const kind = SUBMISSION_TOOLS[toolName];
457
+ if (!kind) return fail(`${toolName} is not a submission tool`);
458
+
459
+ if (toolName === "galaxy_upload_local_file") {
460
+ return parseLocalUpload(resolved.details, args);
461
+ }
462
+
463
+ const envelope = parseGalaxyResultEnvelope(resolved);
464
+ if (!envelope) {
465
+ return fail(
466
+ resolved.outputId
467
+ ? "result was not parseable JSON even after re-reading the saved Galaxy output"
468
+ : resolved.truncatedPath
469
+ ? "result was not parseable JSON even after re-reading the full-output file"
470
+ : "result was not a parseable GalaxyResult envelope",
471
+ );
472
+ }
473
+ const data = envelope.data;
474
+
475
+ switch (toolName) {
476
+ case "invoke_workflow":
477
+ return parseInvokeWorkflow(data, args);
478
+ case "run_tool":
479
+ return parseToolRun(
480
+ data,
481
+ args,
482
+ (jobs) => str(args.tool_id) ?? jobs[0].toolId ?? "Galaxy tool run",
483
+ );
484
+ case "run_user_tool":
485
+ // The uuid is the hook's own input and never appears in `data`; the
486
+ // resolved tool id does, on each job.
487
+ return parseToolRun(data, args, (jobs) =>
488
+ `User tool ${jobs[0].toolId ?? str(args.tool_uuid) ?? ""}`.trim(),
489
+ );
490
+ case "upload_file_from_url":
491
+ return parseToolRun(data, args, () => `Upload ${str(args.url) ?? "from URL"}`);
492
+ case "upload_file":
493
+ return parseToolRun(data, args, () => {
494
+ const p = str(args.path);
495
+ return p ? `Upload ${path.basename(p)}` : "Upload to Galaxy";
496
+ });
497
+ case "create_user_tool":
498
+ return parseCreateUserTool(data, args);
499
+ default:
500
+ return fail(`${toolName} has no parser`);
501
+ }
502
+ }
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Where the in-process Galaxy tools come from. The brain registers pi tool definitions
3
+ * carrying galaxy-ops' bare operation names (`run_tool`, `get_dataset_details`, ...) and hands
4
+ * those names to every guard as the tool family.
5
+ */
6
+ import type { ExtensionAPI, ToolDefinition } from "@earendil-works/pi-coding-agent";
7
+ import { bareFamily, type GalaxyToolFamily } from "../../shared/galaxy-tool-family.js";
8
+ import { createGalaxyOpsToolSource } from "./galaxy-ops-tools";
9
+
10
+ /** pi's own tool shape; the shim registers exactly this. */
11
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
+ export type GalaxyTool = ToolDefinition<any, any, any>;
13
+
14
+ /**
15
+ * The Galaxy tools registered in-process under their bare names.
16
+ *
17
+ * Orbit builds the list from galaxy-ops itself (`createGalaxyOpsToolSource`, the
18
+ * default). A shell installs a source only to add tools its galaxy-ops entry
19
+ * lacks, through that function's `extras`.
20
+ */
21
+ export interface GalaxyToolSource {
22
+ /** Registered once at extension load, in this order; their names are the bare family. */
23
+ tools(): readonly GalaxyTool[];
24
+ /** Registered after `tools()` but kept out of the family: readers no guard keys on. */
25
+ companions?(): readonly GalaxyTool[];
26
+ }
27
+
28
+ let installed: GalaxyToolSource | null = null;
29
+ let registered: GalaxyToolFamily | null = null;
30
+ let registeredTools: readonly GalaxyTool[] = [];
31
+
32
+ /** null uninstalls and forgets the registered family. */
33
+ export function setGalaxyToolSource(source: GalaxyToolSource | null): void {
34
+ installed = source;
35
+ registered = null;
36
+ registeredTools = [];
37
+ }
38
+
39
+ export function installedGalaxyToolSource(): GalaxyToolSource | null {
40
+ return installed;
41
+ }
42
+
43
+ /**
44
+ * Register the installed source's tools, or the default source's, then its
45
+ * companions, and return the family over the tools' names. Called once, from
46
+ * index.ts.
47
+ */
48
+ export function registerGalaxyTools(pi: ExtensionAPI): GalaxyToolFamily {
49
+ const source = installed ?? createGalaxyOpsToolSource();
50
+ const tools = source.tools();
51
+ const companions = source.companions?.() ?? [];
52
+ // pi keeps the last definition under a name, so a second one would silently
53
+ // replace the first (an extra the entry already has, say) and pass as one tool.
54
+ const names = new Set<string>();
55
+ for (const { name } of [...tools, ...companions]) {
56
+ if (names.has(name)) throw new Error(`[galaxy-tools] two Galaxy tools are named ${name}`);
57
+ names.add(name);
58
+ }
59
+ for (const tool of tools) pi.registerTool(tool);
60
+ for (const tool of companions) pi.registerTool(tool);
61
+ registeredTools = [...tools, ...companions];
62
+ registered = bareFamily(tools.map((t) => t.name));
63
+ return registered;
64
+ }
65
+
66
+ /** The definitions registerGalaxyTools registered, for readers of their annotations. */
67
+ export function registeredGalaxyTools(): readonly GalaxyTool[] {
68
+ return registeredTools;
69
+ }
70
+
71
+ /**
72
+ * How the brain names Galaxy tools to the model right now: the registered
73
+ * source's names. For render-time readers (context.ts, the greeting);
74
+ * registrars take the family as a parameter.
75
+ */
76
+ export function galaxyToolFamily(): GalaxyToolFamily {
77
+ return registered ?? bareFamily([]);
78
+ }