@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.
- package/CHANGELOG.md +123 -0
- package/LICENSE +21 -0
- package/README.md +760 -5
- package/bin/legacy-mcp-config.js +363 -0
- package/bin/orbit.js +810 -0
- package/bin/pi-extension-path.d.ts +4 -0
- package/bin/pi-extension-path.js +44 -0
- package/bin/provider-auth.d.ts +22 -0
- package/bin/provider-auth.js +77 -0
- package/bin/thinking-pref.js +38 -0
- package/bin/update-check.d.ts +15 -0
- package/bin/update-check.js +137 -0
- package/extensions/cli-update/index.ts +32 -0
- package/extensions/orbit/activity-hooks.ts +141 -0
- package/extensions/orbit/activity.ts +116 -0
- package/extensions/orbit/agent-dir.ts +11 -0
- package/extensions/orbit/auto-resume.ts +352 -0
- package/extensions/orbit/config.ts +3 -0
- package/extensions/orbit/confusables.ts +1 -0
- package/extensions/orbit/context.ts +957 -0
- package/extensions/orbit/dashboard-commands.ts +191 -0
- package/extensions/orbit/dashboard-store.ts +473 -0
- package/extensions/orbit/dashboard-tools.ts +1185 -0
- package/extensions/orbit/empty-completion.ts +99 -0
- package/extensions/orbit/evidence-gate.ts +1276 -0
- package/extensions/orbit/evidence-override-command.ts +294 -0
- package/extensions/orbit/exec-guard/bash-risk.ts +1408 -0
- package/extensions/orbit/exec-guard/gate.ts +181 -0
- package/extensions/orbit/exec-guard/guardian-config.ts +54 -0
- package/extensions/orbit/exec-guard/index.ts +1 -0
- package/extensions/orbit/exec-guard/model-tier.ts +36 -0
- package/extensions/orbit/exec-guard/path-jail.ts +54 -0
- package/extensions/orbit/exec-guard/policy.ts +342 -0
- package/extensions/orbit/exec-guard/runtime-state.ts +15 -0
- package/extensions/orbit/exec-guard/sensitive-read.ts +525 -0
- package/extensions/orbit/exec-guard/types.ts +42 -0
- package/extensions/orbit/execution-commands.ts +134 -0
- package/extensions/orbit/feedback-command.ts +81 -0
- package/extensions/orbit/feedback.ts +96 -0
- package/extensions/orbit/galaxy-api.test.ts +122 -0
- package/extensions/orbit/galaxy-api.ts +606 -0
- package/extensions/orbit/galaxy-artifact-link-guidance.ts +5 -0
- package/extensions/orbit/galaxy-destructive-gate.ts +113 -0
- package/extensions/orbit/galaxy-enrich.ts +1108 -0
- package/extensions/orbit/galaxy-failure.ts +101 -0
- package/extensions/orbit/galaxy-fixture.ts +126 -0
- package/extensions/orbit/galaxy-history-guard.ts +233 -0
- package/extensions/orbit/galaxy-job-block.ts +347 -0
- package/extensions/orbit/galaxy-job-ops.ts +288 -0
- package/extensions/orbit/galaxy-live-source.ts +929 -0
- package/extensions/orbit/galaxy-markdown-adapter.ts +248 -0
- package/extensions/orbit/galaxy-op-policy.ts +332 -0
- package/extensions/orbit/galaxy-ops-tools.ts +326 -0
- package/extensions/orbit/galaxy-output-store.ts +80 -0
- package/extensions/orbit/galaxy-output.ts +346 -0
- package/extensions/orbit/galaxy-page-binding.ts +222 -0
- package/extensions/orbit/galaxy-page-markdown-guidance.ts +15 -0
- package/extensions/orbit/galaxy-page-ops.ts +159 -0
- package/extensions/orbit/galaxy-page-sync.test.ts +417 -0
- package/extensions/orbit/galaxy-page-sync.ts +318 -0
- package/extensions/orbit/galaxy-pages-api.ts +203 -0
- package/extensions/orbit/galaxy-pages-sync.ts +409 -0
- package/extensions/orbit/galaxy-poll-guard.ts +189 -0
- package/extensions/orbit/galaxy-poller.ts +706 -0
- package/extensions/orbit/galaxy-provenance.ts +623 -0
- package/extensions/orbit/galaxy-reconcile.ts +956 -0
- package/extensions/orbit/galaxy-recovery.ts +176 -0
- package/extensions/orbit/galaxy-repeat-guard.ts +55 -0
- package/extensions/orbit/galaxy-submission-capture.ts +707 -0
- package/extensions/orbit/galaxy-submission.ts +502 -0
- package/extensions/orbit/galaxy-tool-source.ts +78 -0
- package/extensions/orbit/galaxy-tool-wrap.ts +234 -0
- package/extensions/orbit/galaxy-udt-block.ts +127 -0
- package/extensions/orbit/galaxy-upload-tus.ts +334 -0
- package/extensions/orbit/galaxy-upload.ts +300 -0
- package/extensions/orbit/galaxy-version-capture.ts +65 -0
- package/extensions/orbit/git.ts +173 -0
- package/extensions/orbit/harness-block-fields.ts +597 -0
- package/extensions/orbit/index.ts +593 -0
- package/extensions/orbit/init-gate.ts +284 -0
- package/extensions/orbit/instructions-command.ts +136 -0
- package/extensions/orbit/invocation-failure-hint.ts +57 -0
- package/extensions/orbit/iwc-plan-check.ts +94 -0
- package/extensions/orbit/lesson-command.ts +303 -0
- package/extensions/orbit/lesson-hint.ts +245 -0
- package/extensions/orbit/lesson-nudge.ts +106 -0
- package/extensions/orbit/lessons/compose.ts +177 -0
- package/extensions/orbit/lessons/counters.ts +120 -0
- package/extensions/orbit/lessons/enabled.ts +116 -0
- package/extensions/orbit/lessons/matcher.ts +346 -0
- package/extensions/orbit/lessons/paths.ts +286 -0
- package/extensions/orbit/lessons/pi-event-contract.ts +105 -0
- package/extensions/orbit/lessons/propose-replay.ts +103 -0
- package/extensions/orbit/lessons/propose-tool.ts +222 -0
- package/extensions/orbit/lessons/propose.ts +502 -0
- package/extensions/orbit/lessons/replay.ts +89 -0
- package/extensions/orbit/lessons/reproduction-index.ts +83 -0
- package/extensions/orbit/lessons/search-tool.ts +99 -0
- package/extensions/orbit/lessons/search.ts +136 -0
- package/extensions/orbit/lessons/store.ts +415 -0
- package/extensions/orbit/lessons/text.ts +36 -0
- package/extensions/orbit/lessons/types.ts +69 -0
- package/extensions/orbit/lessons/user-dir.ts +24 -0
- package/extensions/orbit/lessons/user-lesson.ts +88 -0
- package/extensions/orbit/lessons/wrapper.ts +61 -0
- package/extensions/orbit/lessons-command.ts +147 -0
- package/extensions/orbit/local-exec.ts +39 -0
- package/extensions/orbit/mcp-output.ts +179 -0
- package/extensions/orbit/mcp-servers.test.ts +24 -0
- package/extensions/orbit/mcp-servers.ts +25 -0
- package/extensions/orbit/model-script.ts +351 -0
- package/extensions/orbit/notebook-anchors.ts +342 -0
- package/extensions/orbit/notebook-writer.ts +863 -0
- package/extensions/orbit/observation-allowlists.ts +1109 -0
- package/extensions/orbit/observation-replay.ts +148 -0
- package/extensions/orbit/observation-triggers.ts +563 -0
- package/extensions/orbit/observation-ui.ts +175 -0
- package/extensions/orbit/observations-command.ts +421 -0
- package/extensions/orbit/observations-config.ts +200 -0
- package/extensions/orbit/observations.ts +1381 -0
- package/extensions/orbit/profiles.ts +270 -0
- package/extensions/orbit/progress-updates.ts +95 -0
- package/extensions/orbit/proposal-commands.ts +882 -0
- package/extensions/orbit/provenance-fs-file.ts +59 -0
- package/extensions/orbit/provenance-fs.ts +32 -0
- package/extensions/orbit/provenance-memory-fs.ts +59 -0
- package/extensions/orbit/record-store-file.ts +177 -0
- package/extensions/orbit/record-store-page.ts +77 -0
- package/extensions/orbit/record-store-seam.ts +47 -0
- package/extensions/orbit/record-store.ts +149 -0
- package/extensions/orbit/registry-carrier.ts +107 -0
- package/extensions/orbit/registry-eligibility.ts +95 -0
- package/extensions/orbit/registry-evaluation.ts +403 -0
- package/extensions/orbit/registry-evaluator.ts +519 -0
- package/extensions/orbit/registry-import.ts +91 -0
- package/extensions/orbit/registry-lock.ts +221 -0
- package/extensions/orbit/registry-memory-fs.ts +42 -0
- package/extensions/orbit/registry-page-carrier.ts +103 -0
- package/extensions/orbit/registry-proposal.ts +1348 -0
- package/extensions/orbit/registry-runtime.ts +234 -0
- package/extensions/orbit/registry-schema.ts +735 -0
- package/extensions/orbit/registry-submitter.ts +59 -0
- package/extensions/orbit/registry-templates.ts +346 -0
- package/extensions/orbit/registry.ts +476 -0
- package/extensions/orbit/sandbox/index.ts +120 -0
- package/extensions/orbit/sandbox/sandbox-bash.ts +93 -0
- package/extensions/orbit/sandbox/sandbox-config.ts +87 -0
- package/extensions/orbit/sandbox/sandbox-init-message.ts +28 -0
- package/extensions/orbit/secret-redaction.ts +247 -0
- package/extensions/orbit/session-index/cwd.ts +18 -0
- package/extensions/orbit/session-index/db.ts +56 -0
- package/extensions/orbit/session-index/indexer.ts +154 -0
- package/extensions/orbit/session-index/is-enabled.ts +17 -0
- package/extensions/orbit/session-index/parse.ts +254 -0
- package/extensions/orbit/session-index/query.ts +209 -0
- package/extensions/orbit/session-index/schema.ts +72 -0
- package/extensions/orbit/session-index/tools.ts +152 -0
- package/extensions/orbit/session-lifecycle.ts +321 -0
- package/extensions/orbit/skill-triggers.ts +159 -0
- package/extensions/orbit/skills-command.ts +48 -0
- package/extensions/orbit/skills-discovery.ts +435 -0
- package/extensions/orbit/skills.ts +84 -0
- package/extensions/orbit/sra-import-gate.ts +77 -0
- package/extensions/orbit/state.ts +265 -0
- package/extensions/orbit/submission-replay.ts +147 -0
- package/extensions/orbit/sync-command.ts +157 -0
- package/extensions/orbit/teams/critic-parser.ts +93 -0
- package/extensions/orbit/teams/dispatcher.ts +210 -0
- package/extensions/orbit/teams/is-enabled.ts +22 -0
- package/extensions/orbit/teams/tool.ts +187 -0
- package/extensions/orbit/teams/types.ts +57 -0
- package/extensions/orbit/teams/validate.ts +42 -0
- package/extensions/orbit/tester-id-command.ts +133 -0
- package/extensions/orbit/tools-sync.ts +279 -0
- package/extensions/orbit/tools.ts +1300 -0
- package/extensions/orbit/types.ts +41 -0
- package/extensions/orbit/ui-bridge.ts +55 -0
- package/extensions/orbit/ulid.ts +60 -0
- package/extensions/orbit/user-instructions.ts +388 -0
- package/extensions/orbit/vendor/skills/_catalog.json +68 -0
- package/extensions/orbit/vendor/skills/_manifest.json +1106 -0
- package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/SKILL.md +112 -0
- package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/_provenance.json +218 -0
- package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/_required_tools.json +33 -0
- package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/_verify.json +4 -0
- package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/cli/add.json +50 -0
- package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/cli/draft-extract.json +51 -0
- package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/cli/draft-next-step.json +42 -0
- package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/cli/draft-validate.json +140 -0
- package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/cli/list.json +32 -0
- package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/notes/galaxy-tool-job-failure-reference.md +137 -0
- package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/notes/open-requirements-ledger.md +173 -0
- package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/schemas/galaxy-tool-summary.schema.json +175 -0
- package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/schemas/galaxy-workflow-draft.schema.json +2727 -0
- package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/SKILL.md +82 -0
- package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/_provenance.json +133 -0
- package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/_required_tools.json +16 -0
- package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/_verify.json +4 -0
- package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/references/cli/draft-validate.json +140 -0
- package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/references/notes/galaxy-workflow-draft-format.md +135 -0
- package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/references/notes/open-requirements-ledger.md +173 -0
- package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/references/schemas/galaxy-workflow-draft.schema.json +2727 -0
- package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/SKILL.md +84 -0
- package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/_provenance.json +166 -0
- package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/_verify.json +29 -0
- package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/notes/galaxy-workflow-testability-design.md +136 -0
- package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/notes/iwc-shortcuts-anti-patterns.md +357 -0
- package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/notes/iwc-test-data-conventions.md +308 -0
- package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/notes/planemo-asserts-idioms.md +246 -0
- package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/notes/planemo-workflow-test-architecture.md +151 -0
- package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/schemas/galaxy-workflow-test-plan.schema.json +552 -0
- package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/schemas/summary-galaxy-workflow.schema.json +687 -0
- package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/schemas/tests-format.schema.json +7328 -0
- package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/SKILL.md +127 -0
- package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/_provenance.json +198 -0
- package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/_required_tools.json +16 -0
- package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/_verify.json +4 -0
- package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/references/cli/convert.json +123 -0
- package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/references/notes/galaxy-data-flow-draft-contract.md +129 -0
- package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/references/notes/iwc-shortcuts-anti-patterns.md +357 -0
- package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/references/notes/iwc-test-data-conventions.md +308 -0
- package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/references/notes/open-requirements-ledger.md +173 -0
- package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/SKILL.md +73 -0
- package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/_provenance.json +160 -0
- package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/_verify.json +4 -0
- package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/galaxy-collection-semantics.md +43 -0
- package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/galaxy-collection-semantics.yml +1250 -0
- package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/galaxy-tool-job-failure-reference.md +137 -0
- package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/galaxy-workflow-invocation-failure-reference.md +138 -0
- package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/iwc-shortcuts-anti-patterns.md +357 -0
- package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/nextflow-operators-to-galaxy-collection-recipes.md +98 -0
- package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/planemo-asserts-idioms.md +246 -0
- package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/planemo-workflow-test-architecture.md +151 -0
- package/extensions/orbit/vendor/skills/discover-shed-tool/SKILL.md +174 -0
- package/extensions/orbit/vendor/skills/discover-shed-tool/_provenance.json +130 -0
- package/extensions/orbit/vendor/skills/discover-shed-tool/_required_tools.json +18 -0
- package/extensions/orbit/vendor/skills/discover-shed-tool/_verify.json +17 -0
- package/extensions/orbit/vendor/skills/discover-shed-tool/references/cli/tool-revisions.json +48 -0
- package/extensions/orbit/vendor/skills/discover-shed-tool/references/cli/tool-search.json +95 -0
- package/extensions/orbit/vendor/skills/discover-shed-tool/references/cli/tool-versions.json +39 -0
- package/extensions/orbit/vendor/skills/discover-shed-tool/references/notes/component-tool-shed-search.md +230 -0
- package/extensions/orbit/vendor/skills/discover-shed-tool/references/schemas/galaxy-tool-discovery.schema.json +231 -0
- package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/SKILL.md +93 -0
- package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/_provenance.json +201 -0
- package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/_required_tools.json +28 -0
- package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/_verify.json +17 -0
- package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/cli/planemo.md +44 -0
- package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/cli/validate-tests.json +40 -0
- package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/notes/galaxy-workflow-testability-design.md +136 -0
- package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/notes/iwc-shortcuts-anti-patterns.md +357 -0
- package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/notes/iwc-test-data-conventions.md +308 -0
- package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/notes/planemo-asserts-idioms.md +246 -0
- package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/notes/planemo-workflow-test-architecture.md +151 -0
- package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/schemas/galaxy-workflow-test-plan.schema.json +552 -0
- package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/schemas/tests-format.schema.json +7328 -0
- package/extensions/orbit/vendor/skills/interview-to-galaxy-workflow-changeset/SKILL.md +81 -0
- package/extensions/orbit/vendor/skills/interview-to-galaxy-workflow-changeset/_provenance.json +93 -0
- package/extensions/orbit/vendor/skills/interview-to-galaxy-workflow-changeset/_verify.json +17 -0
- package/extensions/orbit/vendor/skills/interview-to-galaxy-workflow-changeset/references/notes/open-requirements-ledger.md +173 -0
- package/extensions/orbit/vendor/skills/interview-to-galaxy-workflow-changeset/references/schemas/summary-galaxy-workflow.schema.json +687 -0
- package/extensions/orbit/vendor/skills/pipeline-update-interview-to-galaxy/SKILL.md +81 -0
- package/extensions/orbit/vendor/skills/pipeline-update-interview-to-galaxy/_assembly.json +23 -0
- package/extensions/orbit/vendor/skills/run-workflow-test/SKILL.md +79 -0
- package/extensions/orbit/vendor/skills/run-workflow-test/_provenance.json +125 -0
- package/extensions/orbit/vendor/skills/run-workflow-test/_required_tools.json +28 -0
- package/extensions/orbit/vendor/skills/run-workflow-test/_verify.json +4 -0
- package/extensions/orbit/vendor/skills/run-workflow-test/references/cli/planemo.md +44 -0
- package/extensions/orbit/vendor/skills/run-workflow-test/references/cli/validate-tests.json +40 -0
- package/extensions/orbit/vendor/skills/run-workflow-test/references/notes/galaxy-workflow-invocation-failure-reference.md +138 -0
- package/extensions/orbit/vendor/skills/run-workflow-test/references/notes/planemo-asserts-idioms.md +246 -0
- package/extensions/orbit/vendor/skills/run-workflow-test/references/notes/planemo-workflow-test-architecture.md +151 -0
- package/extensions/orbit/vendor/skills/run-workflow-test/references/schemas/tests-format.schema.json +7328 -0
- package/extensions/orbit/vendor/skills/skills/LICENSE +21 -0
- package/extensions/orbit/vendor/skills/skills/collection-manipulation/README.md +39 -0
- package/extensions/orbit/vendor/skills/skills/collection-manipulation/SKILL.md +892 -0
- package/extensions/orbit/vendor/skills/skills/collection-manipulation/references/api-patterns.md +927 -0
- package/extensions/orbit/vendor/skills/skills/collection-manipulation/references/apply-rules.md +1482 -0
- package/extensions/orbit/vendor/skills/skills/collection-manipulation/references/test-patterns.md +996 -0
- package/extensions/orbit/vendor/skills/skills/collection-manipulation/references/tools.md +609 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-data-libraries/SKILL.md +170 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-integration/README.md +162 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-integration/SKILL.md +99 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-integration/examples/README.md +119 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-integration/examples/tool-checking.md +419 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-integration/examples/workflow-testing.md +617 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-integration/galaxy-integration.md +614 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-integration/jupyterlite/SKILL.md +144 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-integration/jupyterlite/examples/average_col3.ipynb +68 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-integration/jupyterlite/examples/extract_sample_metadata.ipynb +190 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-integration/jupyterlite/examples/variant_annotation.ipynb +816 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-integration/jupyterlite/examples/vcp_variant_map.ipynb +443 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-integration/scripts/README.md +165 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-integration/scripts/galaxy_tool_checker.py +521 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-mcp-reference/SKILL.md +128 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-mcp-reference/gotchas.md +135 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-mcp-reference/history-access.md +132 -0
- package/extensions/orbit/vendor/skills/skills/reproduciblify/SKILL.md +146 -0
- package/extensions/orbit/vendor/skills/skills/reproduciblify/references/directives.yml +496 -0
- package/extensions/orbit/vendor/skills/skills/udt-authoring/SKILL.md +245 -0
- package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/01-minimal-echo.yml +27 -0
- package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/02-single-data-in-out.yml +27 -0
- package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/03-multiple-data-js.yml +28 -0
- package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/04-select-integer-boolean.yml +41 -0
- package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/05-resource-requirements.yml +25 -0
- package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/06-biocontainer-tool.yml +38 -0
- package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/07-inline-python-script.yml +56 -0
- package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/08-configfile-script.yml +74 -0
- package/extensions/orbit/vendor/skills/skills/udt-authoring/references/common-mistakes.md +76 -0
- package/extensions/orbit/vendor/skills/skills/udt-authoring/references/schema-reference.md +155 -0
- package/extensions/orbit/vendor/skills/skills/udt-authoring/references/templating.md +196 -0
- package/extensions/orbit/vendor/skills/skills/udt-authoring/scripts/validate.py +109 -0
- package/extensions/orbit/vendor/skills/skills/workflow-reports/README.md +71 -0
- package/extensions/orbit/vendor/skills/skills/workflow-reports/SKILL.md +190 -0
- package/extensions/orbit/vendor/skills/skills/workflow-reports/examples/histology-staining.md +145 -0
- package/extensions/orbit/vendor/skills/skills/workflow-reports/examples/tissue-microarray-analysis.md +176 -0
- package/extensions/orbit/vendor/skills/skills/workflow-reports/references/directives.md +415 -0
- package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/SKILL.md +98 -0
- package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/_provenance.json +93 -0
- package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/_required_tools.json +28 -0
- package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/_verify.json +17 -0
- package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/references/cli/convert.json +123 -0
- package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/references/cli/foundry.md +25 -0
- package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/references/cli/validate.json +142 -0
- package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/references/schemas/summary-galaxy-workflow.schema.json +687 -0
- package/extensions/orbit/vendor/skills/validate-galaxy-workflow/SKILL.md +74 -0
- package/extensions/orbit/vendor/skills/validate-galaxy-workflow/_provenance.json +71 -0
- package/extensions/orbit/vendor/skills/validate-galaxy-workflow/_required_tools.json +16 -0
- package/extensions/orbit/vendor/skills/validate-galaxy-workflow/_verify.json +4 -0
- package/extensions/orbit/vendor/skills/validate-galaxy-workflow/references/cli/validate.json +142 -0
- package/extensions/orbit/vendor/skills/validate-galaxy-workflow/references/notes/galaxy-workflow-invocation-failure-reference.md +138 -0
- package/extensions/orbit/vendor/skills/validate-galaxy-workflow/references/notes/galaxy-workflow-testability-design.md +136 -0
- package/extensions/orbit/vendor-skills.ts +283 -0
- package/extensions/orbit/workspace-state-dir.ts +46 -0
- package/extensions/orbit-handoff/index.ts +73 -0
- package/extensions/orbit-handoff/orbit-launcher.ts +142 -0
- package/extensions/whats-new/index.ts +98 -0
- package/lessons/LICENSE +17 -0
- package/lessons/README.md +117 -0
- package/lessons/SCHEMA.md +187 -0
- package/lessons/build-snapshot.mjs +311 -0
- package/lessons/data/downloaded-file-is-not-what-its-extension-says.md +61 -0
- package/lessons/galaxy-api/403-history-is-a-hard-stop.md +57 -0
- package/lessons/galaxy-api/collection-into-single-dataset-input.md +61 -0
- package/lessons/galaxy-api/connectedvalue-in-command-line.md +62 -0
- package/lessons/galaxy-api/hid-is-not-an-id.md +59 -0
- package/lessons/galaxy-api/invoke-workflow-inputs-not-params.md +60 -0
- package/lessons/galaxy-api/repeat-param-pipe-keys.md +63 -0
- package/lessons/galaxy-api/run-tool-returns-on-submit.md +61 -0
- package/lessons/galaxy-tools/reference-index-not-on-server.md +62 -0
- package/lessons/log.md +42 -0
- package/lessons/reproduction/input-population-mismatch.md +59 -0
- package/lessons/reproduction/methods-text-vs-executed-parameters.md +62 -0
- package/lessons/snapshot.json +1004 -0
- package/lessons/stats/de-contrast-direction-and-sample-labels.md +63 -0
- package/lessons/stats/na-coerced-to-zero-in-filters.md +59 -0
- package/lessons/validate.mjs +1219 -0
- package/package.json +103 -5
- package/shared/agent-prompt.d.ts +8 -0
- package/shared/agent-prompt.js +15 -0
- package/shared/approval-prompt.d.ts +4 -0
- package/shared/approval-prompt.js +61 -0
- package/shared/brain-env.d.ts +14 -0
- package/shared/brain-env.js +108 -0
- package/shared/brain-exit.d.ts +20 -0
- package/shared/brain-exit.js +149 -0
- package/shared/capability-profile.d.ts +16 -0
- package/shared/capability-profile.js +75 -0
- package/shared/config-source.d.ts +13 -0
- package/shared/config-source.js +17 -0
- package/shared/confusables.d.ts +3 -0
- package/shared/confusables.js +93 -0
- package/shared/custom-provider.d.ts +45 -0
- package/shared/custom-provider.js +169 -0
- package/shared/dashboard-contract.d.ts +123 -0
- package/shared/dashboard-contract.js +560 -0
- package/shared/dashboard-layout-store.d.ts +44 -0
- package/shared/dashboard-layout-store.js +281 -0
- package/shared/feedback-contract.d.ts +61 -0
- package/shared/feedback-contract.js +146 -0
- package/shared/galaxy-artifact-links.d.ts +30 -0
- package/shared/galaxy-artifact-links.js +166 -0
- package/shared/galaxy-credentials.d.ts +26 -0
- package/shared/galaxy-credentials.js +71 -0
- package/shared/galaxy-destructive.d.ts +21 -0
- package/shared/galaxy-destructive.js +269 -0
- package/shared/galaxy-guidance.d.ts +2 -0
- package/shared/galaxy-guidance.js +53 -0
- package/shared/galaxy-live-contract.d.ts +92 -0
- package/shared/galaxy-live-contract.js +180 -0
- package/shared/galaxy-page-cells.d.ts +2 -0
- package/shared/galaxy-page-cells.js +22 -0
- package/shared/galaxy-tool-family.d.ts +5 -0
- package/shared/galaxy-tool-family.js +27 -0
- package/shared/galaxy-url.d.ts +1 -0
- package/shared/galaxy-url.js +48 -0
- package/shared/gtn.d.ts +31 -0
- package/shared/gtn.js +253 -0
- package/shared/handled-prompt.d.ts +3 -0
- package/shared/handled-prompt.js +26 -0
- package/shared/known-provider.d.ts +11 -0
- package/shared/known-provider.js +89 -0
- package/shared/lesson-hint-marker.d.ts +7 -0
- package/shared/lesson-hint-marker.js +32 -0
- package/shared/lesson-rules.d.ts +150 -0
- package/shared/lesson-rules.js +203 -0
- package/shared/malformed-object-ids.d.ts +1 -0
- package/shared/malformed-object-ids.js +37 -0
- package/shared/markdown-sections.d.ts +10 -0
- package/shared/markdown-sections.js +118 -0
- package/shared/notebook-fences.d.ts +12 -0
- package/shared/notebook-fences.js +53 -0
- package/shared/observation-contract.d.ts +91 -0
- package/shared/observation-contract.js +544 -0
- package/shared/orbit-config.d.ts +226 -0
- package/shared/orbit-config.js +189 -0
- package/shared/orbit-env.d.ts +13 -0
- package/shared/orbit-env.js +124 -0
- package/shared/orbit-shell-contract.d.ts +74 -0
- package/shared/orbit-shell-contract.js +30 -0
- package/shared/page-content-hash.d.ts +1 -0
- package/shared/page-content-hash.js +13 -0
- package/shared/pi-default-model.d.ts +7 -0
- package/shared/pi-default-model.js +41 -0
- package/shared/prompt-blocks.d.ts +87 -0
- package/shared/prompt-blocks.js +898 -0
- package/shared/provider-auth-caps.d.ts +22 -0
- package/shared/provider-auth-caps.js +57 -0
- package/shared/random.d.ts +2 -0
- package/shared/random.js +15 -0
- package/shared/record-excerpt.d.ts +4 -0
- package/shared/record-excerpt.js +16 -0
- package/shared/redirect-guard.d.ts +36 -0
- package/shared/redirect-guard.js +235 -0
- package/shared/skills-pin.d.ts +8 -0
- package/shared/skills-pin.js +9 -0
- package/shared/skills-router.d.ts +17 -0
- package/shared/skills-router.js +63 -0
- package/shared/sra-import.d.ts +34 -0
- package/shared/sra-import.js +206 -0
- package/shared/state-dir.d.ts +21 -0
- package/shared/state-dir.js +240 -0
- package/shared/team-dispatch-contract.d.ts +28 -0
- package/shared/team-dispatch-contract.js +1 -0
- package/shared/truncate-middle.d.ts +11 -0
- package/shared/truncate-middle.js +68 -0
- package/shared/version-compare.d.ts +10 -0
- package/shared/version-compare.js +74 -0
- package/shared/whats-new.d.ts +31 -0
- package/shared/whats-new.js +83 -0
- package/shared/wsl.d.ts +10 -0
- 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
|
+
}
|