@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,597 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Harness-only fields shared by the `loom-invocation` and `loom-job` blocks.
|
|
3
|
+
*
|
|
4
|
+
* Everything here is written by the harness from what Galaxy returned, never
|
|
5
|
+
* by the agent. That distinction is the point: a block that says
|
|
6
|
+
* `submitted_by: harness` is a claim that the harness watched the submission
|
|
7
|
+
* happen and read the id out of Galaxy's own response. If the agent could set
|
|
8
|
+
* that, the claim would be worth nothing -- so `stripHarnessFields` runs on
|
|
9
|
+
* every agent-facing write and the values are carried over from the block
|
|
10
|
+
* already on disk instead.
|
|
11
|
+
*
|
|
12
|
+
* `server_verified` is deliberately *not* here. It is the record tools' own
|
|
13
|
+
* tri-state field (galaxy-job-block.ts and notebook-writer.ts own it): a
|
|
14
|
+
* record call writes `false` when it asked Galaxy and got no answer, and the
|
|
15
|
+
* poller upgrades it on the first round trip that does. Stripping it would
|
|
16
|
+
* make both of those writes no-ops. The capture hook simply sets it `true` on
|
|
17
|
+
* the block it writes, which it has earned the same way -- by reading the id
|
|
18
|
+
* out of Galaxy's response.
|
|
19
|
+
*
|
|
20
|
+
* On-disk shape stays line-oriented and grep-friendly like the rest of the
|
|
21
|
+
* block, one `key: value` per line. The two collection fields (`jobs`,
|
|
22
|
+
* `drift`) are single-line compact JSON rather than nested YAML: every block
|
|
23
|
+
* parser in the codebase reads a block line-by-line and splits on the first
|
|
24
|
+
* colon, so a nested list would parse as garbage in some readers and be
|
|
25
|
+
* silently dropped in others. JSON on one line round-trips exactly and still
|
|
26
|
+
* greps.
|
|
27
|
+
*
|
|
28
|
+
* Every field here but one is a bare token or a JSON array, so they need
|
|
29
|
+
* neither of the two block parsers' differing quote handling (`notebook-writer`
|
|
30
|
+
* strips paired quotes, `galaxy-job-block` runs `JSON.parse`). The exception is
|
|
31
|
+
* `enrichment_error`, which carries text a Galaxy server wrote. It sidesteps the
|
|
32
|
+
* difference rather than reconciling it: it is always written JSON-quoted and
|
|
33
|
+
* read back here from the raw line, which both parsers hand over untouched.
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
import { isNotebookFenceOpen, type NotebookFenceKind } from "../../shared/notebook-fences.js";
|
|
37
|
+
|
|
38
|
+
export type SubmittedBy = "harness" | "agent" | "unknown";
|
|
39
|
+
export type EnrichmentState = "pending" | "complete" | "unavailable";
|
|
40
|
+
|
|
41
|
+
const SUBMITTED_BY: readonly SubmittedBy[] = ["harness", "agent", "unknown"];
|
|
42
|
+
const ENRICHMENT_STATES: readonly EnrichmentState[] = ["pending", "complete", "unavailable"];
|
|
43
|
+
|
|
44
|
+
/** One output dataset on an enriched job summary. */
|
|
45
|
+
export interface BlockJobOutput {
|
|
46
|
+
id: string;
|
|
47
|
+
ext?: string;
|
|
48
|
+
dbkey?: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Compact per-job summary. The full per-attempt record lives in
|
|
53
|
+
* `.loom/provenance/<attempt_id>.json`; this is what the notebook carries so
|
|
54
|
+
* a reader can see the versions without opening another file.
|
|
55
|
+
*/
|
|
56
|
+
export interface BlockJobSummary {
|
|
57
|
+
jobId: string;
|
|
58
|
+
toolId?: string;
|
|
59
|
+
toolVersion?: string;
|
|
60
|
+
state?: string;
|
|
61
|
+
outputs?: BlockJobOutput[];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** A tool version that moved between two attempts bound to the same step. */
|
|
65
|
+
export interface BlockDriftNote {
|
|
66
|
+
toolId: string;
|
|
67
|
+
from: string;
|
|
68
|
+
to: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The registry's evaluation of the run, as rendered onto its block. A
|
|
73
|
+
* projection only: the gate reads the registry, never this, so a hand edit
|
|
74
|
+
* here changes nothing but what a reader sees until the next pass re-renders
|
|
75
|
+
* it.
|
|
76
|
+
*/
|
|
77
|
+
export interface BlockEvaluation {
|
|
78
|
+
execution: string;
|
|
79
|
+
conformity: string;
|
|
80
|
+
check: string;
|
|
81
|
+
predicate: string;
|
|
82
|
+
integrity: string;
|
|
83
|
+
authority: string;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export interface HarnessBlockFields {
|
|
87
|
+
/** ULID minted at submission dispatch; the join key for the provenance file. */
|
|
88
|
+
attemptId?: string;
|
|
89
|
+
historyId?: string;
|
|
90
|
+
submittedBy?: SubmittedBy;
|
|
91
|
+
enrichment?: EnrichmentState;
|
|
92
|
+
enrichmentAttempts?: number;
|
|
93
|
+
/**
|
|
94
|
+
* Why the last enrichment attempt did not complete. Free text from a Galaxy
|
|
95
|
+
* error, so it is flattened and capped before it is written. An empty string
|
|
96
|
+
* clears it: `undefined` means "leave it alone" to the merge.
|
|
97
|
+
*/
|
|
98
|
+
enrichmentError?: string;
|
|
99
|
+
jobs?: BlockJobSummary[];
|
|
100
|
+
drift?: BlockDriftNote[];
|
|
101
|
+
/** The registry's verdict for this run's attempt, and the revision it was read at. */
|
|
102
|
+
evaluation?: BlockEvaluation;
|
|
103
|
+
handoffEligible?: boolean;
|
|
104
|
+
registryRevision?: number;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Every harness-owned property name, as it appears on the TS object. Used by
|
|
109
|
+
* `stripHarnessFields`; keep in sync with `HarnessBlockFields`.
|
|
110
|
+
*/
|
|
111
|
+
export const HARNESS_FIELD_KEYS = [
|
|
112
|
+
"attemptId",
|
|
113
|
+
"historyId",
|
|
114
|
+
"submittedBy",
|
|
115
|
+
"enrichment",
|
|
116
|
+
"enrichmentAttempts",
|
|
117
|
+
"enrichmentError",
|
|
118
|
+
"jobs",
|
|
119
|
+
"drift",
|
|
120
|
+
"evaluation",
|
|
121
|
+
"handoffEligible",
|
|
122
|
+
"registryRevision",
|
|
123
|
+
] as const;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Drop every harness-owned field from a caller-supplied record.
|
|
127
|
+
*
|
|
128
|
+
* Applied at the agent-facing block writers (`upsertInvocationBlock`,
|
|
129
|
+
* `upsertJobBlock`) so a record-tool call can never assert provenance it
|
|
130
|
+
* didn't earn -- including via a spread of raw tool arguments, which is the
|
|
131
|
+
* shape this is actually defending against. Returns a shallow copy; the input
|
|
132
|
+
* is untouched.
|
|
133
|
+
*/
|
|
134
|
+
export function stripHarnessFields<T extends object>(input: T): T {
|
|
135
|
+
const out = { ...input } as Record<string, unknown>;
|
|
136
|
+
for (const key of HARNESS_FIELD_KEYS) delete out[key];
|
|
137
|
+
return out as T;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** Keep only the harness-owned fields. The complement of `stripHarnessFields`. */
|
|
141
|
+
export function pickHarnessFields(input: HarnessBlockFields): HarnessBlockFields {
|
|
142
|
+
const out: Record<string, unknown> = {};
|
|
143
|
+
for (const key of HARNESS_FIELD_KEYS) {
|
|
144
|
+
const value = (input as Record<string, unknown>)[key];
|
|
145
|
+
if (value !== undefined) out[key] = value;
|
|
146
|
+
}
|
|
147
|
+
return out as HarnessBlockFields;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Merge harness fields for an upsert: `incoming` wins per field, `existing`
|
|
152
|
+
* fills the gaps. `undefined` on the incoming side means "don't change",
|
|
153
|
+
* which is what lets a later enrichment pass set `jobs` without having to
|
|
154
|
+
* restate the attempt id.
|
|
155
|
+
*/
|
|
156
|
+
export function mergeHarnessFields(
|
|
157
|
+
existing: HarnessBlockFields,
|
|
158
|
+
incoming: HarnessBlockFields,
|
|
159
|
+
): HarnessBlockFields {
|
|
160
|
+
return pickHarnessFields({ ...existing, ...pickHarnessFields(incoming) });
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* True when a scalar can be written as a bare `key: value` line and read back
|
|
165
|
+
* unchanged.
|
|
166
|
+
*
|
|
167
|
+
* The bare scalars here (`attempt_id`, `history_id`) are written unescaped, so
|
|
168
|
+
* a value carrying a newline would render as a second block line and be read
|
|
169
|
+
* back as a different field entirely -- or, worse, shadow a real one. Callers
|
|
170
|
+
* are expected to have validated already (see `idToken` in
|
|
171
|
+
* galaxy-submission.ts); this is the last line of defence before the bytes
|
|
172
|
+
* land, because these fields will also be written by the reconcile and
|
|
173
|
+
* enrichment passes that don't exist yet.
|
|
174
|
+
*/
|
|
175
|
+
function isBareScalar(value: string): boolean {
|
|
176
|
+
return value.length > 0 && !/[\s\u0000-\u001f\u007f-\u009f]/.test(value);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Thrown when a block field's value cannot be written as one `key: value`
|
|
181
|
+
* line. Carries the field name so the caller can say which argument to fix.
|
|
182
|
+
*/
|
|
183
|
+
export class UnrenderableBlockValue extends Error {
|
|
184
|
+
constructor(readonly field: string) {
|
|
185
|
+
super(
|
|
186
|
+
`${field} cannot contain a line break or a control character -- ` +
|
|
187
|
+
`a block field is one line, and a value that spans two writes a second field.`,
|
|
188
|
+
);
|
|
189
|
+
this.name = "UnrenderableBlockValue";
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* One line, no control characters. Deliberately looser than `isBareScalar`:
|
|
195
|
+
* an interior space is fine here, because `notebook_anchor` is matched against
|
|
196
|
+
* the notebook's own spelling and headings have spaces in them. What is not
|
|
197
|
+
* fine is anything that ends the line.
|
|
198
|
+
*/
|
|
199
|
+
function isOneLine(value: string): boolean {
|
|
200
|
+
return !/[\u0000-\u001f\u007f-\u009f]/.test(value);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Render one unquoted `key: value` block line, refusing a value that would
|
|
205
|
+
* not survive the round trip.
|
|
206
|
+
*
|
|
207
|
+
* Both block parsers read a block line by line and take the last value for a
|
|
208
|
+
* key, so a value carrying a newline does not come back mangled -- it comes
|
|
209
|
+
* back as *additional fields*. That is a forgery primitive wherever the value
|
|
210
|
+
* is agent-supplied: `tool_id` on `galaxy_job_record` is a plain tool
|
|
211
|
+
* argument, and rendering it raw let a call write `submitted_by: harness` and
|
|
212
|
+
* an `attempt_id` of its choosing into a block it was only meant to label.
|
|
213
|
+
*
|
|
214
|
+
* Refusing beats escaping for these fields: every value that legitimately
|
|
215
|
+
* reaches here is machine-generated or already token-checked upstream (see
|
|
216
|
+
* `idToken` in galaxy-submission.ts), so an unrepresentable one is a bug or
|
|
217
|
+
* an attempt, and either way half a block is worse than none. The free-text
|
|
218
|
+
* fields -- `label`, `summary` -- go through the block's own quoting instead,
|
|
219
|
+
* because a colon in a human label is ordinary.
|
|
220
|
+
*/
|
|
221
|
+
/**
|
|
222
|
+
* Every fenced block type Orbit writes. The append locator needs the whole set:
|
|
223
|
+
* an unterminated `loom-job` opener swallows an appended `loom-invocation`
|
|
224
|
+
* just as well as another job block would.
|
|
225
|
+
*/
|
|
226
|
+
const ORBIT_FENCE_KINDS: readonly NotebookFenceKind[] = [
|
|
227
|
+
"invocation",
|
|
228
|
+
"job",
|
|
229
|
+
"udt",
|
|
230
|
+
"session",
|
|
231
|
+
"galaxy-page",
|
|
232
|
+
"proposal",
|
|
233
|
+
];
|
|
234
|
+
|
|
235
|
+
const FENCE_CLOSE = "```";
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* A line that can sit in a block body: blank, or a field.
|
|
239
|
+
*
|
|
240
|
+
* "Field" is the block parsers' own key grammar -- snake_case at the start of
|
|
241
|
+
* the line -- rather than anything with a colon in it. `Note: see below` is
|
|
242
|
+
* prose that would pass a looser check and is not a field to any reader here,
|
|
243
|
+
* and an indented key is not one either: `parseInvocationBlock` anchors its
|
|
244
|
+
* match at the line start, so a reader would skip it while a looser body rule
|
|
245
|
+
* counted it.
|
|
246
|
+
*
|
|
247
|
+
* Every line these blocks carry comes from `renderHarnessFieldLines`,
|
|
248
|
+
* `renderInvocationYaml`, `renderJobYaml` or `renderUdtYaml`, all of which
|
|
249
|
+
* emit exactly this shape.
|
|
250
|
+
*/
|
|
251
|
+
function isBlockBodyLine(line: string): boolean {
|
|
252
|
+
return line.trim() === "" || /^[a-z0-9_]+:/.test(line);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/** One block's line span: the opener, its body, and the closing fence. */
|
|
256
|
+
export interface FenceRange {
|
|
257
|
+
/** Index of the opening fence line. */
|
|
258
|
+
start: number;
|
|
259
|
+
/** Index of the closing fence line. */
|
|
260
|
+
end: number;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Find every properly closed block opened by `opener`.
|
|
265
|
+
*
|
|
266
|
+
* One grammar, used by every scanner and by the append locator, because the
|
|
267
|
+
* two going their own way is how a notebook loses content: whoever decides
|
|
268
|
+
* where a block *ends* has to be the same thing that decides where it is safe
|
|
269
|
+
* to write, or one of them hands the other a range that spans somebody else's
|
|
270
|
+
* prose.
|
|
271
|
+
*
|
|
272
|
+
* The rule: a block opens on an exact opener line, its body is `key: value`
|
|
273
|
+
* lines and nothing else, and it closes on an exact ```. Anything else -- a
|
|
274
|
+
* run of four backticks where the close should be, another opener, a line of
|
|
275
|
+
* prose, end of file -- means this is not a block. Running to EOF instead
|
|
276
|
+
* would make every writer treat the rest of the notebook as this block's body
|
|
277
|
+
* and rewrite it away; stopping at the next fence line is what keeps an orphan
|
|
278
|
+
* from swallowing the real block that follows it.
|
|
279
|
+
*
|
|
280
|
+
* The body rule is what settles ownership when fences of two different types
|
|
281
|
+
* overlap. An unclosed `loom-job` followed by a `loom-invocation` opener and
|
|
282
|
+
* then a bare ``` is ambiguous -- the close could belong to either -- and
|
|
283
|
+
* reading it as the invocation's meant its "body" swallowed whatever the user
|
|
284
|
+
* had written in between, which the next write then replaced. A real block's
|
|
285
|
+
* body never contains prose, so requiring that is both true to what these
|
|
286
|
+
* blocks are and exactly the check that refuses the ambiguous case. The block
|
|
287
|
+
* is then invisible rather than rewritable: a fresh one is appended ahead of
|
|
288
|
+
* the orphan and the user's lines stay put.
|
|
289
|
+
*/
|
|
290
|
+
export function scanFencedBlocks(lines: readonly string[], kind: NotebookFenceKind): FenceRange[] {
|
|
291
|
+
const ranges: FenceRange[] = [];
|
|
292
|
+
let i = 0;
|
|
293
|
+
while (i < lines.length) {
|
|
294
|
+
// Either fence prefix opens one: notebooks outlive the Loom -> Orbit rename.
|
|
295
|
+
if (!isNotebookFenceOpen(lines[i], kind)) {
|
|
296
|
+
i++;
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
const start = i;
|
|
300
|
+
let end = start + 1;
|
|
301
|
+
while (end < lines.length && isBlockBodyLine(lines[end])) end++;
|
|
302
|
+
if (end < lines.length && lines[end].trim() === FENCE_CLOSE) {
|
|
303
|
+
ranges.push({ start, end });
|
|
304
|
+
i = end + 1;
|
|
305
|
+
} else {
|
|
306
|
+
// Not a block: skip only the opener, so the line that ended this one
|
|
307
|
+
// still gets its own chance to open one.
|
|
308
|
+
i = start + 1;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return ranges;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Whether a second block with the same id can be folded into the one being
|
|
316
|
+
* rewritten. Same-id duplicates are normally one record written twice (an
|
|
317
|
+
* older build that didn't know the other fence prefix), and collapsing them
|
|
318
|
+
* is what keeps the id unique. A duplicate carrying its own attempt id is a
|
|
319
|
+
* separate harness record, though, and dropping it would delete provenance.
|
|
320
|
+
*/
|
|
321
|
+
export function isFoldableDuplicate(
|
|
322
|
+
keptAttemptId: string | undefined,
|
|
323
|
+
otherAttemptId: string | undefined,
|
|
324
|
+
): boolean {
|
|
325
|
+
return !otherAttemptId || otherAttemptId === keptAttemptId;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Where a new block can be appended without landing after an Orbit fence that
|
|
330
|
+
* never closed.
|
|
331
|
+
*
|
|
332
|
+
* Skipping an unterminated block is not enough on its own. Append after one
|
|
333
|
+
* and the new block's own closing fence becomes the orphan's closing fence, so
|
|
334
|
+
* the orphan, whatever prose sits between them, and the new block all read as
|
|
335
|
+
* a single block -- and the *next* write replaces that whole range and takes
|
|
336
|
+
* the prose with it. Deletion deferred by one update is still deletion.
|
|
337
|
+
*
|
|
338
|
+
* So a block goes in before the orphan instead. The orphan stays orphaned and
|
|
339
|
+
* stays the user's problem to fix, the prose after it stays where they put it,
|
|
340
|
+
* and the run still gets recorded, which matters more than tidy placement:
|
|
341
|
+
* refusing the write over a stray backtick would lose the record of something
|
|
342
|
+
* that is actually running.
|
|
343
|
+
*
|
|
344
|
+
* Reads the notebook with `scanFencedBlocks`' grammar, not a second one of its
|
|
345
|
+
* own -- see that function.
|
|
346
|
+
*/
|
|
347
|
+
export function appendIndexOutsideOpenFence(lines: readonly string[]): number {
|
|
348
|
+
const closed = new Set<number>();
|
|
349
|
+
for (const kind of ORBIT_FENCE_KINDS) {
|
|
350
|
+
for (const range of scanFencedBlocks(lines, kind)) closed.add(range.start);
|
|
351
|
+
}
|
|
352
|
+
for (let i = 0; i < lines.length; i++) {
|
|
353
|
+
const opensBlock = ORBIT_FENCE_KINDS.some((kind) => isNotebookFenceOpen(lines[i], kind));
|
|
354
|
+
if (opensBlock && !closed.has(i)) return i;
|
|
355
|
+
}
|
|
356
|
+
return lines.length;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
export function blockLine(key: string, value: string, field = key): string {
|
|
360
|
+
if (!isOneLine(value)) throw new UnrenderableBlockValue(field);
|
|
361
|
+
return `${key}: ${value}`;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Render the harness fields as block lines. Only defined fields are emitted,
|
|
366
|
+
* so a block written before these existed round-trips byte-identical. A scalar
|
|
367
|
+
* that cannot be represented on one line is dropped rather than written: a
|
|
368
|
+
* missing field reads as unknown provenance, while a broken one corrupts the
|
|
369
|
+
* block around it.
|
|
370
|
+
*/
|
|
371
|
+
export function renderHarnessFieldLines(fields: HarnessBlockFields): string[] {
|
|
372
|
+
const lines: string[] = [];
|
|
373
|
+
if (fields.attemptId && isBareScalar(fields.attemptId)) {
|
|
374
|
+
lines.push(`attempt_id: ${fields.attemptId}`);
|
|
375
|
+
}
|
|
376
|
+
if (fields.historyId && isBareScalar(fields.historyId)) {
|
|
377
|
+
lines.push(`history_id: ${fields.historyId}`);
|
|
378
|
+
}
|
|
379
|
+
if (fields.submittedBy) lines.push(`submitted_by: ${fields.submittedBy}`);
|
|
380
|
+
if (fields.enrichment) lines.push(`enrichment: ${fields.enrichment}`);
|
|
381
|
+
if (fields.enrichmentAttempts !== undefined) {
|
|
382
|
+
lines.push(`enrichment_attempts: ${fields.enrichmentAttempts}`);
|
|
383
|
+
}
|
|
384
|
+
if (fields.enrichmentError) {
|
|
385
|
+
const flat = flattenErrorText(fields.enrichmentError);
|
|
386
|
+
if (flat) lines.push(`enrichment_error: ${JSON.stringify(flat)}`);
|
|
387
|
+
}
|
|
388
|
+
if (fields.jobs && fields.jobs.length > 0) {
|
|
389
|
+
lines.push(`jobs: ${JSON.stringify(fields.jobs.map(jobSummaryToWire))}`);
|
|
390
|
+
}
|
|
391
|
+
if (fields.drift && fields.drift.length > 0) {
|
|
392
|
+
lines.push(`drift: ${JSON.stringify(fields.drift.map(driftToWire))}`);
|
|
393
|
+
}
|
|
394
|
+
if (fields.evaluation) lines.push(`evaluation: ${JSON.stringify(fields.evaluation)}`);
|
|
395
|
+
if (fields.handoffEligible !== undefined) {
|
|
396
|
+
lines.push(`handoff_eligible: ${fields.handoffEligible ? "true" : "false"}`);
|
|
397
|
+
}
|
|
398
|
+
if (fields.registryRevision !== undefined && Number.isSafeInteger(fields.registryRevision)) {
|
|
399
|
+
lines.push(`registry_revision: ${fields.registryRevision}`);
|
|
400
|
+
}
|
|
401
|
+
return lines;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* Read harness fields back out of a parsed block. `get` is the block parser's
|
|
406
|
+
* own field lookup, so this works for both block types without caring how
|
|
407
|
+
* they split lines.
|
|
408
|
+
*
|
|
409
|
+
* Unrecognised values are dropped rather than coerced: a hand-edited
|
|
410
|
+
* `submitted_by: definitely-the-harness` reads back as absent, which the
|
|
411
|
+
* consumers already treat as "unknown provenance". Coercing it to a legal
|
|
412
|
+
* value would invent a claim.
|
|
413
|
+
*/
|
|
414
|
+
export function parseHarnessFields(get: (key: string) => string | undefined): HarnessBlockFields {
|
|
415
|
+
const fields: HarnessBlockFields = {};
|
|
416
|
+
|
|
417
|
+
const attemptId = get("attempt_id");
|
|
418
|
+
if (attemptId) fields.attemptId = attemptId;
|
|
419
|
+
|
|
420
|
+
const historyId = get("history_id");
|
|
421
|
+
if (historyId) fields.historyId = historyId;
|
|
422
|
+
|
|
423
|
+
const submittedBy = get("submitted_by");
|
|
424
|
+
if (submittedBy && (SUBMITTED_BY as readonly string[]).includes(submittedBy)) {
|
|
425
|
+
fields.submittedBy = submittedBy as SubmittedBy;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
const enrichment = get("enrichment");
|
|
429
|
+
if (enrichment && (ENRICHMENT_STATES as readonly string[]).includes(enrichment)) {
|
|
430
|
+
fields.enrichment = enrichment as EnrichmentState;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
const attempts = Number(get("enrichment_attempts"));
|
|
434
|
+
if (get("enrichment_attempts") && Number.isFinite(attempts)) fields.enrichmentAttempts = attempts;
|
|
435
|
+
|
|
436
|
+
const enrichmentError = parseQuotedText(get("enrichment_error"));
|
|
437
|
+
if (enrichmentError) fields.enrichmentError = enrichmentError;
|
|
438
|
+
|
|
439
|
+
const jobs = parseJsonArray(get("jobs"), jobSummaryFromWire);
|
|
440
|
+
if (jobs) fields.jobs = jobs;
|
|
441
|
+
|
|
442
|
+
const drift = parseJsonArray(get("drift"), driftFromWire);
|
|
443
|
+
if (drift) fields.drift = drift;
|
|
444
|
+
|
|
445
|
+
const evaluation = parseEvaluation(get("evaluation"));
|
|
446
|
+
if (evaluation) fields.evaluation = evaluation;
|
|
447
|
+
|
|
448
|
+
const eligible = get("handoff_eligible");
|
|
449
|
+
if (eligible === "true" || eligible === "false") fields.handoffEligible = eligible === "true";
|
|
450
|
+
|
|
451
|
+
const revision = Number(get("registry_revision"));
|
|
452
|
+
if (get("registry_revision") && Number.isSafeInteger(revision))
|
|
453
|
+
fields.registryRevision = revision;
|
|
454
|
+
|
|
455
|
+
return fields;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
const EVALUATION_KEYS = [
|
|
459
|
+
"execution",
|
|
460
|
+
"conformity",
|
|
461
|
+
"check",
|
|
462
|
+
"predicate",
|
|
463
|
+
"integrity",
|
|
464
|
+
"authority",
|
|
465
|
+
] as const;
|
|
466
|
+
|
|
467
|
+
function parseEvaluation(raw: string | undefined): BlockEvaluation | undefined {
|
|
468
|
+
if (!raw) return undefined;
|
|
469
|
+
let parsed: unknown;
|
|
470
|
+
try {
|
|
471
|
+
parsed = JSON.parse(raw);
|
|
472
|
+
} catch {
|
|
473
|
+
return undefined;
|
|
474
|
+
}
|
|
475
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return undefined;
|
|
476
|
+
const o = parsed as Record<string, unknown>;
|
|
477
|
+
if (!EVALUATION_KEYS.every((k) => typeof o[k] === "string")) return undefined;
|
|
478
|
+
return Object.fromEntries(
|
|
479
|
+
EVALUATION_KEYS.map((k) => [k, o[k] as string]),
|
|
480
|
+
) as unknown as BlockEvaluation;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/** Longest `enrichment_error` the block carries; the full text is in the activity row. */
|
|
484
|
+
const MAX_ERROR_TEXT = 200;
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* One line, no control characters, capped. The text comes out of a Galaxy
|
|
488
|
+
* error body, which is neither ours nor short, and a block line has to stay
|
|
489
|
+
* one line whatever it says.
|
|
490
|
+
*/
|
|
491
|
+
export function flattenErrorText(text: string): string {
|
|
492
|
+
const flat = text
|
|
493
|
+
.replace(/[\u0000-\u001f\u007f-\u009f]+/g, " ")
|
|
494
|
+
.replace(/\s+/g, " ")
|
|
495
|
+
.trim();
|
|
496
|
+
return flat.length <= MAX_ERROR_TEXT ? flat : flat.slice(0, MAX_ERROR_TEXT - 1) + "…";
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
/** A JSON-quoted one-line string, or the raw text when a hand edit dropped the quotes. */
|
|
500
|
+
function parseQuotedText(raw: string | undefined): string | undefined {
|
|
501
|
+
if (!raw) return undefined;
|
|
502
|
+
if (raw.startsWith('"')) {
|
|
503
|
+
try {
|
|
504
|
+
const parsed: unknown = JSON.parse(raw);
|
|
505
|
+
return typeof parsed === "string" && parsed.length > 0 ? parsed : undefined;
|
|
506
|
+
} catch {
|
|
507
|
+
return undefined;
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
return raw;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* Parse a single-line JSON array field. A malformed value yields `undefined`
|
|
515
|
+
* (field absent) rather than throwing -- one bad hand edit must not make the
|
|
516
|
+
* whole block unreadable and take its ids with it.
|
|
517
|
+
*/
|
|
518
|
+
function parseJsonArray<T>(raw: string | undefined, map: (entry: unknown) => T | null): T[] | null {
|
|
519
|
+
if (!raw) return null;
|
|
520
|
+
let parsed: unknown;
|
|
521
|
+
try {
|
|
522
|
+
parsed = JSON.parse(raw);
|
|
523
|
+
} catch {
|
|
524
|
+
return null;
|
|
525
|
+
}
|
|
526
|
+
if (!Array.isArray(parsed)) return null;
|
|
527
|
+
const out: T[] = [];
|
|
528
|
+
for (const entry of parsed) {
|
|
529
|
+
const mapped = map(entry);
|
|
530
|
+
if (mapped) out.push(mapped);
|
|
531
|
+
}
|
|
532
|
+
return out;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
function str(value: unknown): string | undefined {
|
|
536
|
+
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
function jobSummaryToWire(job: BlockJobSummary): Record<string, unknown> {
|
|
540
|
+
return {
|
|
541
|
+
job_id: job.jobId,
|
|
542
|
+
...(job.toolId ? { tool_id: job.toolId } : {}),
|
|
543
|
+
...(job.toolVersion ? { tool_version: job.toolVersion } : {}),
|
|
544
|
+
...(job.state ? { state: job.state } : {}),
|
|
545
|
+
...(job.outputs && job.outputs.length > 0
|
|
546
|
+
? {
|
|
547
|
+
outputs: job.outputs.map((o) => ({
|
|
548
|
+
id: o.id,
|
|
549
|
+
...(o.ext ? { ext: o.ext } : {}),
|
|
550
|
+
...(o.dbkey ? { dbkey: o.dbkey } : {}),
|
|
551
|
+
})),
|
|
552
|
+
}
|
|
553
|
+
: {}),
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
function jobSummaryFromWire(entry: unknown): BlockJobSummary | null {
|
|
558
|
+
if (!entry || typeof entry !== "object") return null;
|
|
559
|
+
const e = entry as Record<string, unknown>;
|
|
560
|
+
const jobId = str(e.job_id);
|
|
561
|
+
if (!jobId) return null;
|
|
562
|
+
const outputs = Array.isArray(e.outputs)
|
|
563
|
+
? e.outputs
|
|
564
|
+
.map((o): BlockJobOutput | null => {
|
|
565
|
+
if (!o || typeof o !== "object") return null;
|
|
566
|
+
const id = str((o as Record<string, unknown>).id);
|
|
567
|
+
if (!id) return null;
|
|
568
|
+
return {
|
|
569
|
+
id,
|
|
570
|
+
ext: str((o as Record<string, unknown>).ext),
|
|
571
|
+
dbkey: str((o as Record<string, unknown>).dbkey),
|
|
572
|
+
};
|
|
573
|
+
})
|
|
574
|
+
.filter((o): o is BlockJobOutput => o !== null)
|
|
575
|
+
: undefined;
|
|
576
|
+
return {
|
|
577
|
+
jobId,
|
|
578
|
+
toolId: str(e.tool_id),
|
|
579
|
+
toolVersion: str(e.tool_version),
|
|
580
|
+
state: str(e.state),
|
|
581
|
+
...(outputs && outputs.length > 0 ? { outputs } : {}),
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
function driftToWire(note: BlockDriftNote): Record<string, unknown> {
|
|
586
|
+
return { tool_id: note.toolId, from: note.from, to: note.to };
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
function driftFromWire(entry: unknown): BlockDriftNote | null {
|
|
590
|
+
if (!entry || typeof entry !== "object") return null;
|
|
591
|
+
const e = entry as Record<string, unknown>;
|
|
592
|
+
const toolId = str(e.tool_id);
|
|
593
|
+
const from = str(e.from);
|
|
594
|
+
const to = str(e.to);
|
|
595
|
+
if (!toolId || !from || !to) return null;
|
|
596
|
+
return { toolId, from, to };
|
|
597
|
+
}
|