@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,206 @@
|
|
|
1
|
+
// Shared, shell-neutral core of the SRA fan-out gate. Orbit's brain and the browser agent both
|
|
2
|
+
// refuse one fastq_dump/fasterq_dump job per accession; the parsing and the turn-local batch
|
|
3
|
+
// bookkeeping live here, while each shell keeps its own tool-name family and refusal wording.
|
|
4
|
+
|
|
5
|
+
const SRA_TOOL = /^(?:(?:[^/]+\/repos\/iuc\/sra_tools\/)?(?:fastq_dump|fasterq_dump))(?:\/[^/]+)?$/;
|
|
6
|
+
const ACCESSION = /^(?:SRR|ERR|DRR)\d+$/;
|
|
7
|
+
|
|
8
|
+
/** @typedef {Record<string, unknown>} Obj */
|
|
9
|
+
|
|
10
|
+
/** @param {unknown} value @returns {Obj | null} */
|
|
11
|
+
function object(value) {
|
|
12
|
+
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
13
|
+
? /** @type {Obj} */ (value)
|
|
14
|
+
: null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** A JSON object, given as one or as its JSON text.
|
|
18
|
+
* @param {unknown} value @returns {Obj | null} */
|
|
19
|
+
export function parseObject(value) {
|
|
20
|
+
if (typeof value !== "string") return object(value);
|
|
21
|
+
try {
|
|
22
|
+
return object(JSON.parse(value));
|
|
23
|
+
} catch {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** A canonical rendering, so two spellings of the same settings share a key.
|
|
29
|
+
* @param {unknown} value @returns {string} */
|
|
30
|
+
export function stable(value) {
|
|
31
|
+
if (Array.isArray(value)) return `[${value.map(stable).join(",")}]`;
|
|
32
|
+
const obj = object(value);
|
|
33
|
+
if (obj)
|
|
34
|
+
return `{${Object.keys(obj)
|
|
35
|
+
.sort()
|
|
36
|
+
.map((k) => `${JSON.stringify(k)}:${stable(obj[k])}`)
|
|
37
|
+
.join(",")}}`;
|
|
38
|
+
return JSON.stringify(value) ?? "null";
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** @param {Obj} inputs @returns {Obj} */
|
|
42
|
+
export function flatten(inputs) {
|
|
43
|
+
/** @type {Obj} */
|
|
44
|
+
const result = {};
|
|
45
|
+
for (const [key, value] of Object.entries(inputs)) {
|
|
46
|
+
const group = key === "input" || key === "adv" ? object(value) : null;
|
|
47
|
+
if (!group) {
|
|
48
|
+
result[key] = value;
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
for (const [child, v] of Object.entries(group)) {
|
|
52
|
+
if (child !== "__current_case__") result[`${key}|${child}`] = v;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** @param {unknown} value @returns {string[] | undefined} */
|
|
59
|
+
export function accessions(value) {
|
|
60
|
+
if (typeof value !== "string") return undefined;
|
|
61
|
+
const runs = value
|
|
62
|
+
.trim()
|
|
63
|
+
.split(/[\s,;]+/)
|
|
64
|
+
.filter(Boolean);
|
|
65
|
+
return runs.length > 0 && runs.every((r) => ACCESSION.test(r)) ? runs : undefined;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** @type {import("./sra-import.js").NormalizeName} */
|
|
69
|
+
const identity = (name, args) => ({ name, args });
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Exact structured surfaces only; never interpret arbitrary Python as JSON.
|
|
73
|
+
* @param {unknown} name
|
|
74
|
+
* @param {unknown} input
|
|
75
|
+
* @param {{ normalizeName?: import("./sra-import.js").NormalizeName }} [options]
|
|
76
|
+
* @returns {import("./sra-import.js").SraCall | null}
|
|
77
|
+
*/
|
|
78
|
+
export function sraCall(name, input, { normalizeName = identity } = {}) {
|
|
79
|
+
const parsed = parseObject(input);
|
|
80
|
+
if (!parsed) return null;
|
|
81
|
+
const normalized = normalizeName(String(name ?? ""), parsed);
|
|
82
|
+
if (!normalized || normalized.name !== "run_tool") return null;
|
|
83
|
+
const args = normalized.args;
|
|
84
|
+
const toolId = args.tool_id;
|
|
85
|
+
const historyId = args.history_id;
|
|
86
|
+
if (typeof toolId !== "string" || typeof historyId !== "string" || !historyId) return null;
|
|
87
|
+
if (!SRA_TOOL.test(toolId)) return null;
|
|
88
|
+
const inputs = parseObject(args.inputs);
|
|
89
|
+
if (!inputs) return null;
|
|
90
|
+
const flat = flatten(inputs);
|
|
91
|
+
const mode = flat["input|input_select"] ?? "accession_number";
|
|
92
|
+
if (mode !== "accession_number" && mode !== "file_list") return null;
|
|
93
|
+
const value = flat[mode === "file_list" ? "input|file_list" : "input|accession"];
|
|
94
|
+
const ref = object(value);
|
|
95
|
+
const settings = { ...flat };
|
|
96
|
+
delete settings["input|input_select"];
|
|
97
|
+
delete settings["input|accession"];
|
|
98
|
+
delete settings["input|file_list"];
|
|
99
|
+
return {
|
|
100
|
+
key: stable({ ...args, inputs: settings }),
|
|
101
|
+
historyId,
|
|
102
|
+
toolId,
|
|
103
|
+
runs: mode === "accession_number" ? accessions(value) : undefined,
|
|
104
|
+
mapped: ref?.__class__ === "Batch" || ref?.batch === true || ref?.src === "hdca",
|
|
105
|
+
fileList: mode === "file_list" && ref?.src === "hda" && typeof ref.id === "string",
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** Turn-local import intent: what was fanned out, what was let through, what landed. */
|
|
110
|
+
export class SraImportGate {
|
|
111
|
+
/** @param {{ remediation: (runs: string[]) => string, normalizeName?: import("./sra-import.js").NormalizeName }} options */
|
|
112
|
+
constructor({ remediation, normalizeName }) {
|
|
113
|
+
this.remediation = remediation;
|
|
114
|
+
this.options = { normalizeName };
|
|
115
|
+
// Not a second durable import registry. A rejected batch is kept across tool-error
|
|
116
|
+
// recovery so serializing the same calls won't pass.
|
|
117
|
+
/** @type {Map<string, Set<string>>} */
|
|
118
|
+
this.batches = new Map();
|
|
119
|
+
/** @type {Set<string>} */
|
|
120
|
+
this.blocked = new Set();
|
|
121
|
+
// A history preflight can leave exactly one missing accession, and a literal singleton is
|
|
122
|
+
// the right call for it. Let one singleton out of a rejected batch per key; a second one is
|
|
123
|
+
// serialization.
|
|
124
|
+
/** @type {Set<string>} */
|
|
125
|
+
this.releasedSingleton = new Set();
|
|
126
|
+
// Accessions already sent to Galaxy in one combined call this turn. Splitting them
|
|
127
|
+
// afterwards is failure recovery (bad accession, resource limit), not fan-out.
|
|
128
|
+
/** @type {Map<string, Set<string>>} */
|
|
129
|
+
this.submitted = new Map();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
clear() {
|
|
133
|
+
this.batches.clear();
|
|
134
|
+
this.blocked.clear();
|
|
135
|
+
this.releasedSingleton.clear();
|
|
136
|
+
this.submitted.clear();
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/** One completed answer's calls, read together before any of them runs.
|
|
140
|
+
* @param {Iterable<{ id: string, name: string, arguments: unknown }>} calls */
|
|
141
|
+
observe(calls) {
|
|
142
|
+
/** @type {Map<string, Array<{ id: string, run: string }>>} */
|
|
143
|
+
const groups = new Map();
|
|
144
|
+
for (const part of calls) {
|
|
145
|
+
const call = sraCall(part.name, part.arguments, this.options);
|
|
146
|
+
if (!call || call.runs?.length !== 1 || call.mapped) continue;
|
|
147
|
+
if (this.submitted.get(call.key)?.has(call.runs[0])) continue;
|
|
148
|
+
const group = groups.get(call.key) ?? [];
|
|
149
|
+
group.push({ id: part.id, run: call.runs[0] });
|
|
150
|
+
groups.set(call.key, group);
|
|
151
|
+
}
|
|
152
|
+
for (const [key, group] of groups) {
|
|
153
|
+
if (group.length < 2) continue;
|
|
154
|
+
const batch = this.batches.get(key) ?? new Set();
|
|
155
|
+
for (const { id, run } of group) {
|
|
156
|
+
batch.add(run);
|
|
157
|
+
this.blocked.add(id);
|
|
158
|
+
}
|
|
159
|
+
this.batches.set(key, batch);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* @param {string} id @param {string} name @param {unknown} args
|
|
165
|
+
* @returns {import("./sra-import.js").SraBlock | undefined}
|
|
166
|
+
*/
|
|
167
|
+
block(id, name, args) {
|
|
168
|
+
const call = sraCall(name, args, this.options);
|
|
169
|
+
if (!call) return undefined;
|
|
170
|
+
const batch = this.batches.get(call.key);
|
|
171
|
+
const runs = call.runs ?? [];
|
|
172
|
+
const duplicate = new Set(runs).size < runs.length;
|
|
173
|
+
const single = runs.length === 1 ? runs[0] : undefined;
|
|
174
|
+
let serialized = !!(batch && single && batch.size > 1 && batch.has(single));
|
|
175
|
+
const blocked = this.blocked.has(id) || call.mapped || duplicate;
|
|
176
|
+
if (serialized && !blocked && !this.releasedSingleton.has(call.key)) {
|
|
177
|
+
this.releasedSingleton.add(call.key);
|
|
178
|
+
serialized = false;
|
|
179
|
+
}
|
|
180
|
+
if (!blocked && !serialized) {
|
|
181
|
+
// A history preflight may reduce the candidate set. Do not force the original candidates
|
|
182
|
+
// back into a corrected batch and re-download them.
|
|
183
|
+
if (batch && single) batch.delete(single);
|
|
184
|
+
if (batch && (call.fileList || runs.length > 1)) this.batches.delete(call.key);
|
|
185
|
+
if (runs.length > 1) {
|
|
186
|
+
const sent = this.submitted.get(call.key) ?? new Set();
|
|
187
|
+
for (const run of runs) sent.add(run);
|
|
188
|
+
this.submitted.set(call.key, sent);
|
|
189
|
+
}
|
|
190
|
+
return undefined;
|
|
191
|
+
}
|
|
192
|
+
const candidates = [...new Set([...(batch ?? []), ...runs])];
|
|
193
|
+
return {
|
|
194
|
+
reason: this.remediation(candidates),
|
|
195
|
+
call,
|
|
196
|
+
runs: candidates,
|
|
197
|
+
cause: call.mapped ? "mapped-import" : duplicate ? "duplicate-accession" : "split-batch",
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/** The refusal for a call about to run, or undefined to let it through.
|
|
202
|
+
* @param {string} id @param {string} name @param {unknown} args @returns {string | undefined} */
|
|
203
|
+
check(id, name, args) {
|
|
204
|
+
return this.block(id, name, args)?.reason;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface StateDirOptions {
|
|
2
|
+
home?: string;
|
|
3
|
+
migrate?: boolean;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export type StateDirMigrationStatus =
|
|
7
|
+
"disabled" | "nothing-to-migrate" | "already-migrated" | "migrated" | "failed";
|
|
8
|
+
|
|
9
|
+
export const MIGRATE_TO_ORBIT_STATE_DIR: boolean;
|
|
10
|
+
export const MOVED_MARKER_FILE: string;
|
|
11
|
+
|
|
12
|
+
export function legacyStateDir(home?: string): string;
|
|
13
|
+
export function orbitStateDir(home?: string): string;
|
|
14
|
+
export function resolveStateDir(opts?: StateDirOptions): string;
|
|
15
|
+
export function resolveConfigPath(opts?: StateDirOptions): string;
|
|
16
|
+
export function resolveCliVersionCheckPath(opts?: StateDirOptions): string;
|
|
17
|
+
export function resolveDefaultAnalysesDir(opts?: StateDirOptions): string;
|
|
18
|
+
export function migrateStateDir(opts?: StateDirOptions & { enabled?: boolean; now?: Date }): {
|
|
19
|
+
status: StateDirMigrationStatus;
|
|
20
|
+
error?: unknown;
|
|
21
|
+
};
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where the brain keeps its global state (config.json, caches, the session
|
|
3
|
+
* index, the what's-new stamp). Historically ~/.loom; moving to ~/.orbit.
|
|
4
|
+
*
|
|
5
|
+
* Every caller that needs a path under that dir resolves it here rather than
|
|
6
|
+
* joining homedir() with ".loom" itself, so the move is one switch and a
|
|
7
|
+
* ~/.orbit/config.json written by a newer release is honored by this one.
|
|
8
|
+
*
|
|
9
|
+
* ~/.orbit also holds desktop-only shell state (window-state.json and the
|
|
10
|
+
* desktop's own version-check.json); nothing here touches those.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import fs from "node:fs";
|
|
14
|
+
import os from "node:os";
|
|
15
|
+
import path from "node:path";
|
|
16
|
+
|
|
17
|
+
// Off for the compatibility release: ~/.orbit is used only if a newer release
|
|
18
|
+
// already put a config there, and nothing is copied. On since the rename
|
|
19
|
+
// release: the first run copies config.json (encrypted fields intact, mode
|
|
20
|
+
// 0600) and the user's other durable state into ~/.orbit, leaves a
|
|
21
|
+
// MOVED-TO-ORBIT.txt marker behind, and ~/.orbit is the default for new installs. ~/.loom/analyses stays where it is (see
|
|
22
|
+
// resolveDefaultAnalysesDir).
|
|
23
|
+
export const MIGRATE_TO_ORBIT_STATE_DIR = true;
|
|
24
|
+
|
|
25
|
+
export const MOVED_MARKER_FILE = "MOVED-TO-ORBIT.txt";
|
|
26
|
+
const CONFIG_FILE = "config.json";
|
|
27
|
+
// Carried across on migration besides config.json: what the user accumulated
|
|
28
|
+
// and could not get back. Caches, the session index and the version-check
|
|
29
|
+
// cache rebuild themselves and stay behind, as does analyses/ (see
|
|
30
|
+
// resolveDefaultAnalysesDir).
|
|
31
|
+
const MIGRATED_FILES = [
|
|
32
|
+
"whats-new-seen.json",
|
|
33
|
+
"upload-resume.json",
|
|
34
|
+
"feedback-outbox.jsonl",
|
|
35
|
+
"observations-outbox.jsonl",
|
|
36
|
+
"observations-sent.jsonl",
|
|
37
|
+
"observations-tokens.json",
|
|
38
|
+
];
|
|
39
|
+
const MIGRATED_DIRS = ["lessons", "lesson-drafts"];
|
|
40
|
+
// Holds a credential or a secret token: copied at 0600 whatever the source had.
|
|
41
|
+
const PRIVATE_FILES = new Set([CONFIG_FILE, "observations-tokens.json"]);
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @typedef {{ home?: string, migrate?: boolean }} StateDirOptions
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
function homeOf(opts) {
|
|
48
|
+
return opts?.home ?? os.homedir();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** @param {string} [home] */
|
|
52
|
+
export function legacyStateDir(home = os.homedir()) {
|
|
53
|
+
return path.join(home, ".loom");
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** @param {string} [home] */
|
|
57
|
+
export function orbitStateDir(home = os.homedir()) {
|
|
58
|
+
return path.join(home, ".orbit");
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* ~/.orbit once it holds a config.json, else ~/.loom -- until migration is on,
|
|
63
|
+
* after which only an unmigrated ~/.loom/config.json keeps a user on the old
|
|
64
|
+
* dir.
|
|
65
|
+
*
|
|
66
|
+
* @param {StateDirOptions} [opts]
|
|
67
|
+
*/
|
|
68
|
+
export function resolveStateDir(opts = {}) {
|
|
69
|
+
const home = homeOf(opts);
|
|
70
|
+
const orbit = orbitStateDir(home);
|
|
71
|
+
if (fs.existsSync(path.join(orbit, CONFIG_FILE))) return orbit;
|
|
72
|
+
const legacy = legacyStateDir(home);
|
|
73
|
+
if (!(opts.migrate ?? MIGRATE_TO_ORBIT_STATE_DIR)) return legacy;
|
|
74
|
+
return fs.existsSync(path.join(legacy, CONFIG_FILE)) ? legacy : orbit;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** @param {StateDirOptions} [opts] */
|
|
78
|
+
export function resolveConfigPath(opts = {}) {
|
|
79
|
+
return path.join(resolveStateDir(opts), CONFIG_FILE);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* The CLI's npm version-check cache. ~/.orbit/version-check.json already
|
|
84
|
+
* belongs to the desktop's GitHub release check, so anywhere but the legacy
|
|
85
|
+
* dir the CLI uses its own name.
|
|
86
|
+
*
|
|
87
|
+
* @param {StateDirOptions} [opts]
|
|
88
|
+
*/
|
|
89
|
+
export function resolveCliVersionCheckPath(opts = {}) {
|
|
90
|
+
const dir = resolveStateDir(opts);
|
|
91
|
+
const name =
|
|
92
|
+
dir === legacyStateDir(homeOf(opts)) ? "version-check.json" : "cli-version-check.json";
|
|
93
|
+
return path.join(dir, name);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Where a new analysis goes when nothing is configured. ~/.loom/analyses is
|
|
98
|
+
* real user data that is never moved, and pi keys session history by absolute
|
|
99
|
+
* cwd, so an existing one keeps winning until ~/.orbit/analyses appears.
|
|
100
|
+
*
|
|
101
|
+
* @param {StateDirOptions} [opts]
|
|
102
|
+
*/
|
|
103
|
+
export function resolveDefaultAnalysesDir(opts = {}) {
|
|
104
|
+
const home = homeOf(opts);
|
|
105
|
+
const legacy = path.join(legacyStateDir(home), "analyses");
|
|
106
|
+
const orbit = path.join(orbitStateDir(home), "analyses");
|
|
107
|
+
if (fs.existsSync(legacy) && !fs.existsSync(orbit)) return legacy;
|
|
108
|
+
return path.join(resolveStateDir(opts), "analyses");
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function movedNotice(legacyDir, orbitDir, when) {
|
|
112
|
+
return `Loom is now Orbit, and its settings live in ${orbitDir} now.
|
|
113
|
+
|
|
114
|
+
On ${when} Orbit copied config.json, saved lessons and drafts, the observation
|
|
115
|
+
and feedback outboxes and the what's-new stamp from this directory to
|
|
116
|
+
${orbitDir}. From now on it reads ${path.join(orbitDir, CONFIG_FILE)}
|
|
117
|
+
and ignores ${path.join(legacyDir, CONFIG_FILE)}, so changes made to the copy here
|
|
118
|
+
have no effect. Saved API keys were copied as-is and keep working. Caches and
|
|
119
|
+
the session index were not copied; they rebuild on their own.
|
|
120
|
+
|
|
121
|
+
Nothing here was deleted. Analyses under ${path.join(legacyDir, "analyses")} stay
|
|
122
|
+
where they are, and Orbit keeps opening them. Loom releases older than 0.9
|
|
123
|
+
still read the old config.json here. Once you no longer run one, the rest of
|
|
124
|
+
this directory apart from analyses/ is safe to remove.
|
|
125
|
+
`;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Stage the bytes beside the destination, then hard-link into place: link()
|
|
129
|
+
// refuses to replace an existing file, so a second process migrating at the
|
|
130
|
+
// same moment can't overwrite a config the first one already copied and the
|
|
131
|
+
// user has since changed.
|
|
132
|
+
function copyNoClobber(src, dest, mode) {
|
|
133
|
+
const bytes = fs.readFileSync(src);
|
|
134
|
+
const tmp = `${dest}.migrating-${process.pid}`;
|
|
135
|
+
fs.rmSync(tmp, { force: true });
|
|
136
|
+
const fd = fs.openSync(tmp, "wx", mode);
|
|
137
|
+
try {
|
|
138
|
+
// writeFileSync on a descriptor loops until every byte is down; a short
|
|
139
|
+
// writeSync would otherwise be fsynced and linked into place as the config.
|
|
140
|
+
fs.writeFileSync(fd, bytes);
|
|
141
|
+
fs.fsyncSync(fd);
|
|
142
|
+
} finally {
|
|
143
|
+
fs.closeSync(fd);
|
|
144
|
+
}
|
|
145
|
+
try {
|
|
146
|
+
if (fs.statSync(tmp).size !== bytes.length) throw new Error(`short write staging ${dest}`);
|
|
147
|
+
fs.chmodSync(tmp, mode);
|
|
148
|
+
try {
|
|
149
|
+
fs.linkSync(tmp, dest);
|
|
150
|
+
return true;
|
|
151
|
+
} catch (err) {
|
|
152
|
+
if (err?.code === "EEXIST") return false;
|
|
153
|
+
// Filesystems without hard links: an exclusive copy keeps the no-clobber
|
|
154
|
+
// guarantee (a rename after an existence check would not).
|
|
155
|
+
try {
|
|
156
|
+
fs.copyFileSync(tmp, dest, fs.constants.COPYFILE_EXCL);
|
|
157
|
+
return true;
|
|
158
|
+
} catch (copyErr) {
|
|
159
|
+
if (copyErr?.code === "EEXIST") return false;
|
|
160
|
+
throw copyErr;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
} finally {
|
|
164
|
+
fs.rmSync(tmp, { force: true });
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function modeFor(name, src) {
|
|
169
|
+
return PRIVATE_FILES.has(name) ? 0o600 : fs.statSync(src).mode & 0o777;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Copies files that are missing on the destination side, so an interrupted
|
|
173
|
+
// migration picks up where it stopped. Symlinks are left alone: the lessons
|
|
174
|
+
// store refuses linked directories, and following one could copy anything.
|
|
175
|
+
function copyTreeNoClobber(srcDir, destDir) {
|
|
176
|
+
fs.mkdirSync(destDir, { recursive: true, mode: 0o700 });
|
|
177
|
+
for (const entry of fs.readdirSync(srcDir, { withFileTypes: true })) {
|
|
178
|
+
const src = path.join(srcDir, entry.name);
|
|
179
|
+
const dest = path.join(destDir, entry.name);
|
|
180
|
+
if (entry.isSymbolicLink()) continue;
|
|
181
|
+
if (entry.isDirectory()) copyTreeNoClobber(src, dest);
|
|
182
|
+
else if (entry.isFile() && !fs.existsSync(dest))
|
|
183
|
+
copyNoClobber(src, dest, modeFor(entry.name, src));
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* One-time copy of ~/.loom's settings and durable state into ~/.orbit. Copies, never moves:
|
|
189
|
+
* ~/.loom is left intact apart from a MOVED-TO-ORBIT.txt explaining where
|
|
190
|
+
* things went. Safe to call on every startup.
|
|
191
|
+
*
|
|
192
|
+
* @param {StateDirOptions & { enabled?: boolean, now?: Date }} [opts]
|
|
193
|
+
* @returns {{ status: "disabled" | "nothing-to-migrate" | "already-migrated" | "migrated" | "failed", error?: unknown }}
|
|
194
|
+
*/
|
|
195
|
+
export function migrateStateDir(opts = {}) {
|
|
196
|
+
if (!(opts.enabled ?? MIGRATE_TO_ORBIT_STATE_DIR)) return { status: "disabled" };
|
|
197
|
+
const home = homeOf(opts);
|
|
198
|
+
const legacy = legacyStateDir(home);
|
|
199
|
+
const orbit = orbitStateDir(home);
|
|
200
|
+
const legacyConfig = path.join(legacy, CONFIG_FILE);
|
|
201
|
+
const orbitConfig = path.join(orbit, CONFIG_FILE);
|
|
202
|
+
const marker = path.join(legacy, MOVED_MARKER_FILE);
|
|
203
|
+
const writeMarker = () => {
|
|
204
|
+
try {
|
|
205
|
+
fs.writeFileSync(marker, movedNotice(legacy, orbit, (opts.now ?? new Date()).toISOString()), {
|
|
206
|
+
flag: "wx",
|
|
207
|
+
});
|
|
208
|
+
} catch {
|
|
209
|
+
/* already there, or ~/.loom is read-only -- the copy still stands */
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
if (!fs.existsSync(legacyConfig)) return { status: "nothing-to-migrate" };
|
|
214
|
+
if (fs.existsSync(orbitConfig)) {
|
|
215
|
+
writeMarker();
|
|
216
|
+
return { status: "already-migrated" };
|
|
217
|
+
}
|
|
218
|
+
try {
|
|
219
|
+
fs.mkdirSync(orbit, { recursive: true, mode: 0o700 });
|
|
220
|
+
// Any failure here aborts before config.json is copied, so the user stays
|
|
221
|
+
// on ~/.loom with everything intact and the next start tries again.
|
|
222
|
+
for (const name of MIGRATED_FILES) {
|
|
223
|
+
const src = path.join(legacy, name);
|
|
224
|
+
if (!fs.existsSync(src) || fs.existsSync(path.join(orbit, name))) continue;
|
|
225
|
+
copyNoClobber(src, path.join(orbit, name), modeFor(name, src));
|
|
226
|
+
}
|
|
227
|
+
for (const name of MIGRATED_DIRS) {
|
|
228
|
+
const src = path.join(legacy, name);
|
|
229
|
+
if (fs.existsSync(src) && fs.statSync(src).isDirectory()) {
|
|
230
|
+
copyTreeNoClobber(src, path.join(orbit, name));
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
// Last, because its presence is what switches resolveStateDir over.
|
|
234
|
+
const copied = copyNoClobber(legacyConfig, orbitConfig, 0o600);
|
|
235
|
+
writeMarker();
|
|
236
|
+
return { status: copied ? "migrated" : "already-migrated" };
|
|
237
|
+
} catch (error) {
|
|
238
|
+
return { status: "failed", error };
|
|
239
|
+
}
|
|
240
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-boundary contract for team_dispatch tool-card payloads.
|
|
3
|
+
* The brain (extensions/orbit/teams) emits these as the `details` field on
|
|
4
|
+
* tool execution updates; the shell renderer (app/src/renderer/chat) consumes
|
|
5
|
+
* them. Keeping the shape here prevents the two sides from drifting.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export const TEAM_DISPATCH_KIND: "team_dispatch";
|
|
9
|
+
|
|
10
|
+
export interface TeamDispatchSpecSummary {
|
|
11
|
+
description?: string;
|
|
12
|
+
roles?: Array<{ name: string; model?: string }>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface TeamDispatchTurn {
|
|
16
|
+
round: number;
|
|
17
|
+
role: string;
|
|
18
|
+
content?: string;
|
|
19
|
+
approved?: boolean;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface TeamDispatchDetails {
|
|
23
|
+
kind: typeof TEAM_DISPATCH_KIND;
|
|
24
|
+
spec?: TeamDispatchSpecSummary;
|
|
25
|
+
turns?: TeamDispatchTurn[];
|
|
26
|
+
summary?: string;
|
|
27
|
+
error?: string;
|
|
28
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const TEAM_DISPATCH_KIND = "team_dispatch";
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// Byte-bounded head + tail cut of tool output, the same cut pi 1.1.0 makes for its own tool results
|
|
2
|
+
// (`dist/core/tools/truncate.js` truncateMiddle). Ported over TextEncoder rather than imported: that
|
|
3
|
+
// file is a deep dist import, and it uses Node's byte buffers, which the browser worker lacks.
|
|
4
|
+
|
|
5
|
+
const encoder = new TextEncoder();
|
|
6
|
+
// ignoreBOM keeps a leading U+FEFF in the head or tail, as pi's Node decode does.
|
|
7
|
+
const decoder = new TextDecoder("utf-8", { ignoreBOM: true });
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* UTF-8 length of `s` without encoding it. A lone surrogate counts as 3 bytes, the U+FFFD that
|
|
11
|
+
* TextEncoder (and Node's byteLength) write in its place.
|
|
12
|
+
* @param {string} s @returns {number}
|
|
13
|
+
*/
|
|
14
|
+
export function utf8ByteLength(s) {
|
|
15
|
+
let bytes = 0;
|
|
16
|
+
for (let i = 0; i < s.length; i++) {
|
|
17
|
+
const c = s.charCodeAt(i);
|
|
18
|
+
if (c < 0x80) bytes += 1;
|
|
19
|
+
else if (c < 0x800) bytes += 2;
|
|
20
|
+
else if (c >= 0xd800 && c <= 0xdbff && i + 1 < s.length) {
|
|
21
|
+
const next = s.charCodeAt(i + 1);
|
|
22
|
+
if (next >= 0xdc00 && next <= 0xdfff) {
|
|
23
|
+
bytes += 4;
|
|
24
|
+
i++;
|
|
25
|
+
} else bytes += 3;
|
|
26
|
+
} else bytes += 3;
|
|
27
|
+
}
|
|
28
|
+
return bytes;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** @param {string} content @returns {number} */
|
|
32
|
+
function lineCount(content) {
|
|
33
|
+
if (content.length === 0) return 0;
|
|
34
|
+
const lines = content.split("\n");
|
|
35
|
+
if (content.endsWith("\n")) lines.pop();
|
|
36
|
+
return lines.length;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Keep the first and last halves of `maxBytes` and replace the middle with a
|
|
41
|
+
* `…N chars truncated…` marker. Cuts only at character boundaries.
|
|
42
|
+
* @param {string} content @param {number} maxBytes
|
|
43
|
+
* @returns {{ content: string, truncated: boolean, removedChars: number, totalBytes: number, totalLines: number }}
|
|
44
|
+
*/
|
|
45
|
+
export function truncateMiddle(content, maxBytes) {
|
|
46
|
+
const buf = encoder.encode(content);
|
|
47
|
+
const totalLines = lineCount(content);
|
|
48
|
+
if (buf.length <= maxBytes) {
|
|
49
|
+
return { content, truncated: false, removedChars: 0, totalBytes: buf.length, totalLines };
|
|
50
|
+
}
|
|
51
|
+
// Continuation bytes (10xxxxxx) never start a character.
|
|
52
|
+
const isBoundary = (/** @type {number} */ index) =>
|
|
53
|
+
index >= buf.length || (buf[index] & 0xc0) !== 0x80;
|
|
54
|
+
let headEnd = Math.floor(maxBytes / 2);
|
|
55
|
+
while (headEnd > 0 && !isBoundary(headEnd)) headEnd--;
|
|
56
|
+
let tailStart = buf.length - (maxBytes - Math.floor(maxBytes / 2));
|
|
57
|
+
while (tailStart < buf.length && !isBoundary(tailStart)) tailStart++;
|
|
58
|
+
const head = decoder.decode(buf.subarray(0, headEnd));
|
|
59
|
+
const tail = decoder.decode(buf.subarray(tailStart));
|
|
60
|
+
const removedChars = Array.from(decoder.decode(buf.subarray(headEnd, tailStart))).length;
|
|
61
|
+
return {
|
|
62
|
+
content: `${head}…${removedChars} chars truncated…${tail}`,
|
|
63
|
+
truncated: true,
|
|
64
|
+
removedChars,
|
|
65
|
+
totalBytes: buf.length,
|
|
66
|
+
totalLines,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface SemverParts {
|
|
2
|
+
major: number;
|
|
3
|
+
minor: number;
|
|
4
|
+
patch: number;
|
|
5
|
+
pre: string;
|
|
6
|
+
}
|
|
7
|
+
export function parseSemver(v: string): SemverParts | null;
|
|
8
|
+
export function comparePre(a: string, b: string): number;
|
|
9
|
+
export function isNewer(current: string, candidate: string): boolean;
|
|
10
|
+
export function pickChannel(version: string): string;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// Shared, shell-neutral semver helpers. Used by the Orbit version-check banner
|
|
2
|
+
// and the CLI update notice so there's one implementation of precedence rules.
|
|
3
|
+
// Deliberately dependency-free (no `semver` package) for one small feature.
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {{ major: number, minor: number, patch: number, pre: string }} SemverParts
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/** @param {string} v @returns {SemverParts | null} */
|
|
10
|
+
export function parseSemver(v) {
|
|
11
|
+
const m = String(v)
|
|
12
|
+
.replace(/^v/, "")
|
|
13
|
+
.match(/^(\d+)\.(\d+)\.(\d+)(?:-(.+))?$/);
|
|
14
|
+
if (!m) return null;
|
|
15
|
+
return {
|
|
16
|
+
major: parseInt(m[1], 10),
|
|
17
|
+
minor: parseInt(m[2], 10),
|
|
18
|
+
patch: parseInt(m[3], 10),
|
|
19
|
+
pre: m[4] ?? "",
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Compares two prerelease tags per semver precedence. Numeric segments compare
|
|
24
|
+
// numerically (alpha.10 > alpha.9, which a string compare gets wrong). Returns
|
|
25
|
+
// negative when a < b, positive when a > b, zero when equal.
|
|
26
|
+
/** @param {string} a @param {string} b @returns {number} */
|
|
27
|
+
export function comparePre(a, b) {
|
|
28
|
+
if (a === b) return 0;
|
|
29
|
+
// No prerelease tag outranks the same version with one (1.0.0 > 1.0.0-alpha).
|
|
30
|
+
if (!a) return 1;
|
|
31
|
+
if (!b) return -1;
|
|
32
|
+
const ap = a.split(".");
|
|
33
|
+
const bp = b.split(".");
|
|
34
|
+
const len = Math.min(ap.length, bp.length);
|
|
35
|
+
for (let i = 0; i < len; i++) {
|
|
36
|
+
const x = ap[i];
|
|
37
|
+
const y = bp[i];
|
|
38
|
+
const xn = /^\d+$/.test(x);
|
|
39
|
+
const yn = /^\d+$/.test(y);
|
|
40
|
+
if (xn && yn) {
|
|
41
|
+
const dx = parseInt(x, 10);
|
|
42
|
+
const dy = parseInt(y, 10);
|
|
43
|
+
if (dx !== dy) return dx < dy ? -1 : 1;
|
|
44
|
+
} else if (xn !== yn) {
|
|
45
|
+
// Numeric identifiers have lower precedence than alphanumeric ones.
|
|
46
|
+
return xn ? -1 : 1;
|
|
47
|
+
} else if (x !== y) {
|
|
48
|
+
return x < y ? -1 : 1;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return ap.length === bp.length ? 0 : ap.length < bp.length ? -1 : 1;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** True when `candidate` is a strictly newer version than `current`.
|
|
55
|
+
* @param {string} current @param {string} candidate @returns {boolean} */
|
|
56
|
+
export function isNewer(current, candidate) {
|
|
57
|
+
const a = parseSemver(current);
|
|
58
|
+
const b = parseSemver(candidate);
|
|
59
|
+
if (!a || !b) return false;
|
|
60
|
+
if (b.major !== a.major) return b.major > a.major;
|
|
61
|
+
if (b.minor !== a.minor) return b.minor > a.minor;
|
|
62
|
+
if (b.patch !== a.patch) return b.patch > a.patch;
|
|
63
|
+
return comparePre(a.pre, b.pre) < 0;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Maps an installed version to the npm dist-tag / release channel it tracks.
|
|
67
|
+
// Mirrors release.yml: prerelease -> first prerelease identifier (alpha/beta/
|
|
68
|
+
// rc), plain semver -> latest. So an alpha user hears about alphas, not stable.
|
|
69
|
+
/** @param {string} version @returns {string} */
|
|
70
|
+
export function pickChannel(version) {
|
|
71
|
+
const parsed = parseSemver(version);
|
|
72
|
+
if (!parsed || !parsed.pre) return "latest";
|
|
73
|
+
return parsed.pre.split(".")[0] || "latest";
|
|
74
|
+
}
|