@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,560 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dashboard document contract -- shared by the renderer (which draws it), the
|
|
3
|
+
* shells (which persist it) and, later, the brain (which may write one).
|
|
4
|
+
*
|
|
5
|
+
* A dashboard is data: a versioned JSON document of named dashboards, each an
|
|
6
|
+
* ordered list of panels. Validation is total -- it never throws on untrusted
|
|
7
|
+
* input, because this document can come off disk, out of an agent turn, or from
|
|
8
|
+
* a build newer than the one reading it. Anything repairable is repaired and
|
|
9
|
+
* reported; only three things are fatal (not an object, no usable version, a
|
|
10
|
+
* version from the future).
|
|
11
|
+
*
|
|
12
|
+
* Unknown widget types are deliberately preserved. Dropping them would silently
|
|
13
|
+
* delete panels every time an older build opened a newer layout.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
export const DASHBOARD_SCHEMA_VERSION = 1;
|
|
17
|
+
|
|
18
|
+
/** Per-analysis layout file, beside notebook.md in the working directory. */
|
|
19
|
+
export const DASHBOARD_FILENAME = ".loom-dashboard.json";
|
|
20
|
+
|
|
21
|
+
/** Refuse to persist anything larger. Layout, not a blob store. */
|
|
22
|
+
export const DASHBOARD_MAX_BYTES = 256 * 1024;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Advisory list used to build presets and to give the brain a vocabulary. It is
|
|
26
|
+
* deliberately not the set of renderable widgets -- the renderer's registry is
|
|
27
|
+
* that, and it includes flag-gated widgets this list should not advertise.
|
|
28
|
+
* Validation never consults either.
|
|
29
|
+
*/
|
|
30
|
+
export const KNOWN_WIDGET_TYPES = [
|
|
31
|
+
"notebook",
|
|
32
|
+
"jobs",
|
|
33
|
+
"plan",
|
|
34
|
+
"activity",
|
|
35
|
+
"results",
|
|
36
|
+
"galaxy-history",
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
const DEFAULT_PRESET_ID = "current-analysis";
|
|
40
|
+
export const MIN_ROWS = 1;
|
|
41
|
+
export const MAX_ROWS = 6;
|
|
42
|
+
const DEFAULT_ROWS = 2;
|
|
43
|
+
/**
|
|
44
|
+
* Validation enforces these by truncating and reporting a repair, which is the
|
|
45
|
+
* right answer for a file off disk. A caller acting on someone's click wants to
|
|
46
|
+
* refuse and say so instead, so it needs the same numbers rather than its own
|
|
47
|
+
* copy of them.
|
|
48
|
+
*/
|
|
49
|
+
export const MAX_DASHBOARDS = 20;
|
|
50
|
+
export const MAX_PANELS = 40;
|
|
51
|
+
const MAX_REASON_CHARS = 280;
|
|
52
|
+
const MAX_NAME_CHARS = 200;
|
|
53
|
+
const MAX_WIDGET_TYPE_CHARS = 100;
|
|
54
|
+
// Config is the one place the document carries arbitrary shape, so it is the one
|
|
55
|
+
// place that needs walking rather than trusting. JSON.stringify recurses and
|
|
56
|
+
// JSON.parse does not, so a 16 KB file nested a few thousand deep blows the
|
|
57
|
+
// stack inside a structuredClone-by-JSON.
|
|
58
|
+
const MAX_CONFIG_DEPTH = 24;
|
|
59
|
+
const MAX_CONFIG_NODES = 5000;
|
|
60
|
+
const ADDED_BY = new Set(["user", "agent", "preset"]);
|
|
61
|
+
|
|
62
|
+
export const DASHBOARD_PRESETS = [
|
|
63
|
+
{
|
|
64
|
+
id: "current-analysis",
|
|
65
|
+
label: "Current analysis",
|
|
66
|
+
description: "Where the plan stands, what Galaxy is running, and the notebook.",
|
|
67
|
+
dashboard: {
|
|
68
|
+
id: "current-analysis",
|
|
69
|
+
title: "Current analysis",
|
|
70
|
+
panels: [
|
|
71
|
+
{
|
|
72
|
+
id: "p-plan",
|
|
73
|
+
widget: "plan",
|
|
74
|
+
config: {},
|
|
75
|
+
layout: { span: 1, rows: 4 },
|
|
76
|
+
addedBy: "preset",
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
id: "p-jobs",
|
|
80
|
+
widget: "jobs",
|
|
81
|
+
config: {},
|
|
82
|
+
layout: { span: 1, rows: 4 },
|
|
83
|
+
addedBy: "preset",
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
id: "p-notebook",
|
|
87
|
+
widget: "notebook",
|
|
88
|
+
config: { follow: true },
|
|
89
|
+
layout: { span: 2, rows: 3 },
|
|
90
|
+
addedBy: "preset",
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
id: "monitoring",
|
|
97
|
+
label: "Monitoring",
|
|
98
|
+
description: "For a long run: jobs, plan progress, and the analysis log.",
|
|
99
|
+
dashboard: {
|
|
100
|
+
id: "monitoring",
|
|
101
|
+
title: "Monitoring",
|
|
102
|
+
panels: [
|
|
103
|
+
{
|
|
104
|
+
id: "p-jobs",
|
|
105
|
+
widget: "jobs",
|
|
106
|
+
config: {},
|
|
107
|
+
layout: { span: 2, rows: 4 },
|
|
108
|
+
addedBy: "preset",
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
id: "p-plan",
|
|
112
|
+
widget: "plan",
|
|
113
|
+
config: {},
|
|
114
|
+
layout: { span: 1, rows: 4 },
|
|
115
|
+
addedBy: "preset",
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
id: "p-activity",
|
|
119
|
+
widget: "activity",
|
|
120
|
+
config: {},
|
|
121
|
+
layout: { span: 1, rows: 3 },
|
|
122
|
+
addedBy: "preset",
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
id: "results",
|
|
129
|
+
label: "Results",
|
|
130
|
+
description: "What the analysis produced, next to the notebook that explains it.",
|
|
131
|
+
dashboard: {
|
|
132
|
+
id: "results",
|
|
133
|
+
title: "Results",
|
|
134
|
+
panels: [
|
|
135
|
+
{
|
|
136
|
+
id: "p-results",
|
|
137
|
+
widget: "results",
|
|
138
|
+
config: {},
|
|
139
|
+
layout: { span: 2, rows: 3 },
|
|
140
|
+
addedBy: "preset",
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
id: "p-notebook",
|
|
144
|
+
widget: "notebook",
|
|
145
|
+
config: { follow: false },
|
|
146
|
+
layout: { span: 2, rows: 3 },
|
|
147
|
+
addedBy: "preset",
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
];
|
|
153
|
+
|
|
154
|
+
function clone(value) {
|
|
155
|
+
return JSON.parse(JSON.stringify(value));
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Copy a panel config defensively: bounded depth and node count, cycles cut,
|
|
160
|
+
* anything JSON cannot carry dropped, and a property whose getter throws
|
|
161
|
+
* skipped rather than propagated. Returns the copy, or null if it hit a limit.
|
|
162
|
+
*/
|
|
163
|
+
function copyConfig(raw) {
|
|
164
|
+
let budget = MAX_CONFIG_NODES;
|
|
165
|
+
const seen = new WeakSet();
|
|
166
|
+
|
|
167
|
+
const walk = (value, depth) => {
|
|
168
|
+
if (depth > MAX_CONFIG_DEPTH) return { over: true };
|
|
169
|
+
if (budget-- <= 0) return { over: true };
|
|
170
|
+
|
|
171
|
+
if (value === null) return { value: null };
|
|
172
|
+
const kind = typeof value;
|
|
173
|
+
if (kind === "string" || kind === "boolean") return { value };
|
|
174
|
+
if (kind === "number") return Number.isFinite(value) ? { value } : { skip: true };
|
|
175
|
+
if (kind !== "object") return { skip: true }; // function, symbol, bigint, undefined
|
|
176
|
+
|
|
177
|
+
if (seen.has(value)) return { skip: true };
|
|
178
|
+
seen.add(value);
|
|
179
|
+
|
|
180
|
+
if (Array.isArray(value)) {
|
|
181
|
+
const out = [];
|
|
182
|
+
for (const item of value) {
|
|
183
|
+
const result = walk(item, depth + 1);
|
|
184
|
+
if (result.over) return result;
|
|
185
|
+
out.push(result.skip ? null : result.value);
|
|
186
|
+
}
|
|
187
|
+
seen.delete(value);
|
|
188
|
+
return { value: out };
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const out = {};
|
|
192
|
+
for (const key of Object.keys(value)) {
|
|
193
|
+
// `out["__proto__"] = x` sets the object's prototype instead of adding a
|
|
194
|
+
// property, so a config carrying one came back with a poisoned prototype:
|
|
195
|
+
// a widget reading `ctx.config.anything` could get a value the layout
|
|
196
|
+
// file never declared. Not global pollution -- `Object.prototype` is
|
|
197
|
+
// untouched and the key does not survive serialization -- but the widget
|
|
198
|
+
// sees it for the life of the panel, and no config has a legitimate
|
|
199
|
+
// reason to carry these names.
|
|
200
|
+
if (key === "__proto__" || key === "constructor" || key === "prototype") continue;
|
|
201
|
+
let member;
|
|
202
|
+
try {
|
|
203
|
+
member = value[key];
|
|
204
|
+
} catch {
|
|
205
|
+
continue; // a throwing getter is not worth the whole document
|
|
206
|
+
}
|
|
207
|
+
const result = walk(member, depth + 1);
|
|
208
|
+
if (result.over) return result;
|
|
209
|
+
if (!result.skip) out[key] = result.value;
|
|
210
|
+
}
|
|
211
|
+
seen.delete(value);
|
|
212
|
+
return { value: out };
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
const result = walk(raw, 0);
|
|
216
|
+
return result.over || result.skip ? null : result.value;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function problem(path, message) {
|
|
220
|
+
return { path, message };
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function describe(value) {
|
|
224
|
+
if (value === null) return "null";
|
|
225
|
+
if (Array.isArray(value)) return "an array";
|
|
226
|
+
return typeof value;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function isPlainObject(value) {
|
|
230
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/** A fresh copy of a preset's dashboard, or null if there is no such preset. */
|
|
234
|
+
export function dashboardFromPreset(presetId) {
|
|
235
|
+
const preset = DASHBOARD_PRESETS.find((p) => p.id === presetId);
|
|
236
|
+
return preset ? clone(preset.dashboard) : null;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/** The document a workspace starts with: one dashboard, the current-analysis preset. */
|
|
240
|
+
export function createDefaultDashboardDocument() {
|
|
241
|
+
const dashboard = dashboardFromPreset(DEFAULT_PRESET_ID) ?? {
|
|
242
|
+
// Only reachable if DEFAULT_PRESET_ID stops naming a preset. Returning an
|
|
243
|
+
// empty dashboard beats turning the never-throws validator, which calls
|
|
244
|
+
// this, into a thrower.
|
|
245
|
+
id: DEFAULT_PRESET_ID,
|
|
246
|
+
title: "Dashboard",
|
|
247
|
+
panels: [],
|
|
248
|
+
};
|
|
249
|
+
return {
|
|
250
|
+
version: DASHBOARD_SCHEMA_VERSION,
|
|
251
|
+
activeId: dashboard.id,
|
|
252
|
+
dashboards: [dashboard],
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
export function serializeDashboardDocument(document) {
|
|
257
|
+
return JSON.stringify(document, null, 2) + "\n";
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* A short content fingerprint for the layout file, used as the compare-and-swap
|
|
262
|
+
* token between a load and the save based on it. Not a security hash: FNV-1a in
|
|
263
|
+
* plain JS because the renderer, the main process and the web server all have to
|
|
264
|
+
* agree on it, and only one of the three can import node:crypto.
|
|
265
|
+
*/
|
|
266
|
+
export function dashboardRevision(raw) {
|
|
267
|
+
if (typeof raw !== "string") return null;
|
|
268
|
+
let high = 0x811c9dc5;
|
|
269
|
+
let low = 0x01000193;
|
|
270
|
+
for (let i = 0; i < raw.length; i++) {
|
|
271
|
+
const code = raw.charCodeAt(i);
|
|
272
|
+
high = Math.imul(high ^ code, 0x01000193) >>> 0;
|
|
273
|
+
low = Math.imul(low ^ ((code << 5) | (code >>> 3)), 0x85ebca6b) >>> 0;
|
|
274
|
+
}
|
|
275
|
+
return (
|
|
276
|
+
high.toString(16).padStart(8, "0") + low.toString(16).padStart(8, "0") + raw.length.toString(16)
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
function normalizeLayout(raw, path, problems) {
|
|
281
|
+
const layout = { span: 1, rows: DEFAULT_ROWS };
|
|
282
|
+
if (raw === undefined) return layout;
|
|
283
|
+
if (!isPlainObject(raw)) {
|
|
284
|
+
problems.push(
|
|
285
|
+
problem(path, `expected an object, got ${describe(raw)}; using the default size`),
|
|
286
|
+
);
|
|
287
|
+
return layout;
|
|
288
|
+
}
|
|
289
|
+
if (raw.span === 1 || raw.span === 2) {
|
|
290
|
+
layout.span = raw.span;
|
|
291
|
+
} else if (raw.span !== undefined) {
|
|
292
|
+
problems.push(problem(`${path}.span`, "expected 1 or 2; using 1"));
|
|
293
|
+
}
|
|
294
|
+
if (typeof raw.rows === "number" && Number.isFinite(raw.rows)) {
|
|
295
|
+
const rows = Math.round(raw.rows);
|
|
296
|
+
layout.rows = Math.min(MAX_ROWS, Math.max(MIN_ROWS, rows));
|
|
297
|
+
if (layout.rows !== rows) {
|
|
298
|
+
problems.push(problem(`${path}.rows`, `clamped ${rows} to ${MIN_ROWS}..${MAX_ROWS}`));
|
|
299
|
+
}
|
|
300
|
+
} else if (raw.rows !== undefined) {
|
|
301
|
+
problems.push(problem(`${path}.rows`, `expected a number; using ${DEFAULT_ROWS}`));
|
|
302
|
+
}
|
|
303
|
+
return layout;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/** Trim, and cap the length of a name-shaped string that ends up in the DOM. */
|
|
307
|
+
function capName(value, limit, path, field, problems) {
|
|
308
|
+
const trimmed = value.trim();
|
|
309
|
+
if (trimmed.length <= limit) return trimmed;
|
|
310
|
+
problems.push(problem(`${path}.${field}`, `longer than ${limit} characters; truncated`));
|
|
311
|
+
return trimmed.slice(0, limit);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
function normalizePanel(raw, path, index, ids, problems) {
|
|
315
|
+
if (!isPlainObject(raw)) {
|
|
316
|
+
problems.push(problem(path, `expected an object, got ${describe(raw)}; dropped`));
|
|
317
|
+
return null;
|
|
318
|
+
}
|
|
319
|
+
if (typeof raw.widget !== "string" || raw.widget.trim() === "") {
|
|
320
|
+
problems.push(problem(`${path}.widget`, "missing a widget type; panel dropped"));
|
|
321
|
+
return null;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
let id = typeof raw.id === "string" && raw.id.trim() !== "" ? raw.id.trim() : "";
|
|
325
|
+
if (id) {
|
|
326
|
+
id = capName(id, MAX_NAME_CHARS, path, "id", problems);
|
|
327
|
+
if (ids.taken.has(id)) {
|
|
328
|
+
let suffix = 2;
|
|
329
|
+
while (ids.taken.has(`${id}-${suffix}`)) suffix++;
|
|
330
|
+
problems.push(problem(`${path}.id`, `"${id}" is already used; renamed to "${id}-${suffix}"`));
|
|
331
|
+
id = `${id}-${suffix}`;
|
|
332
|
+
}
|
|
333
|
+
} else {
|
|
334
|
+
// Skip anything another panel declared for itself: a generated id must
|
|
335
|
+
// never push an explicitly named panel off its own id, because that id is
|
|
336
|
+
// what a config change is written through.
|
|
337
|
+
let n = index + 1;
|
|
338
|
+
while (ids.taken.has(`panel-${n}`) || ids.declared.has(`panel-${n}`)) n++;
|
|
339
|
+
id = `panel-${n}`;
|
|
340
|
+
problems.push(problem(`${path}.id`, `missing; using "${id}"`));
|
|
341
|
+
}
|
|
342
|
+
ids.taken.add(id);
|
|
343
|
+
|
|
344
|
+
const panel = {
|
|
345
|
+
id,
|
|
346
|
+
widget: capName(raw.widget, MAX_WIDGET_TYPE_CHARS, path, "widget", problems),
|
|
347
|
+
config: {},
|
|
348
|
+
layout: normalizeLayout(raw.layout, `${path}.layout`, problems),
|
|
349
|
+
};
|
|
350
|
+
if (typeof raw.title === "string" && raw.title.trim() !== "") {
|
|
351
|
+
panel.title = capName(raw.title, MAX_NAME_CHARS, path, "title", problems);
|
|
352
|
+
} else if (raw.title !== undefined) {
|
|
353
|
+
problems.push(problem(`${path}.title`, "expected a non-empty string; using the widget label"));
|
|
354
|
+
}
|
|
355
|
+
if (isPlainObject(raw.config)) {
|
|
356
|
+
const config = copyConfig(raw.config);
|
|
357
|
+
if (config === null) {
|
|
358
|
+
problems.push(
|
|
359
|
+
problem(`${path}.config`, "too large or too deeply nested to keep; using an empty config"),
|
|
360
|
+
);
|
|
361
|
+
} else {
|
|
362
|
+
panel.config = config;
|
|
363
|
+
}
|
|
364
|
+
} else if (raw.config !== undefined) {
|
|
365
|
+
problems.push(problem(`${path}.config`, `expected an object, got ${describe(raw.config)}`));
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// Provenance. Nothing renders it yet -- it is here so that an agent which
|
|
369
|
+
// curates the dashboard later can say who added a panel and why, and why the
|
|
370
|
+
// user pinned it, without a schema migration.
|
|
371
|
+
if (typeof raw.addedBy === "string" && ADDED_BY.has(raw.addedBy)) {
|
|
372
|
+
panel.addedBy = raw.addedBy;
|
|
373
|
+
} else if (raw.addedBy !== undefined) {
|
|
374
|
+
problems.push(problem(`${path}.addedBy`, "expected user, agent or preset; dropped"));
|
|
375
|
+
}
|
|
376
|
+
if (typeof raw.reason === "string" && raw.reason.trim() !== "") {
|
|
377
|
+
panel.reason = raw.reason.trim().slice(0, MAX_REASON_CHARS);
|
|
378
|
+
} else if (raw.reason !== undefined) {
|
|
379
|
+
problems.push(problem(`${path}.reason`, "expected a non-empty string; dropped"));
|
|
380
|
+
}
|
|
381
|
+
if (typeof raw.pinned === "boolean") {
|
|
382
|
+
panel.pinned = raw.pinned;
|
|
383
|
+
} else if (raw.pinned !== undefined) {
|
|
384
|
+
problems.push(problem(`${path}.pinned`, "expected a boolean; dropped"));
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
return panel;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
function normalizeDashboard(raw, path, index, seenIds, problems) {
|
|
391
|
+
if (!isPlainObject(raw)) {
|
|
392
|
+
problems.push(problem(path, `expected an object, got ${describe(raw)}; dropped`));
|
|
393
|
+
return null;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
let id = typeof raw.id === "string" && raw.id.trim() !== "" ? raw.id.trim() : "";
|
|
397
|
+
if (!id) {
|
|
398
|
+
id = `dashboard-${index + 1}`;
|
|
399
|
+
problems.push(problem(`${path}.id`, `missing; using "${id}"`));
|
|
400
|
+
} else {
|
|
401
|
+
id = capName(id, MAX_NAME_CHARS, path, "id", problems);
|
|
402
|
+
}
|
|
403
|
+
if (seenIds.has(id)) {
|
|
404
|
+
let suffix = 2;
|
|
405
|
+
while (seenIds.has(`${id}-${suffix}`)) suffix++;
|
|
406
|
+
problems.push(problem(`${path}.id`, `"${id}" is already used; renamed to "${id}-${suffix}"`));
|
|
407
|
+
id = `${id}-${suffix}`;
|
|
408
|
+
}
|
|
409
|
+
seenIds.add(id);
|
|
410
|
+
|
|
411
|
+
let title = "Dashboard";
|
|
412
|
+
if (typeof raw.title === "string" && raw.title.trim() !== "") {
|
|
413
|
+
title = capName(raw.title, MAX_NAME_CHARS, path, "title", problems);
|
|
414
|
+
} else if (raw.title !== undefined) {
|
|
415
|
+
problems.push(problem(`${path}.title`, 'expected a non-empty string; using "Dashboard"'));
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
let rawPanels = Array.isArray(raw.panels) ? raw.panels : [];
|
|
419
|
+
if (!Array.isArray(raw.panels) && raw.panels !== undefined) {
|
|
420
|
+
problems.push(problem(`${path}.panels`, `expected an array, got ${describe(raw.panels)}`));
|
|
421
|
+
}
|
|
422
|
+
if (rawPanels.length > MAX_PANELS) {
|
|
423
|
+
problems.push(
|
|
424
|
+
problem(`${path}.panels`, `${rawPanels.length} panels; keeping the first ${MAX_PANELS}`),
|
|
425
|
+
);
|
|
426
|
+
rawPanels = rawPanels.slice(0, MAX_PANELS);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// Collect every id a panel declares for itself before assigning any, so a
|
|
430
|
+
// generated fallback cannot steal one that appears later in the list.
|
|
431
|
+
const declared = new Set();
|
|
432
|
+
for (const rawPanel of rawPanels) {
|
|
433
|
+
if (isPlainObject(rawPanel) && typeof rawPanel.id === "string" && rawPanel.id.trim() !== "") {
|
|
434
|
+
declared.add(rawPanel.id.trim().slice(0, MAX_NAME_CHARS));
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
const ids = { declared, taken: new Set() };
|
|
438
|
+
const panels = [];
|
|
439
|
+
rawPanels.forEach((rawPanel, i) => {
|
|
440
|
+
const panel = normalizePanel(rawPanel, `${path}.panels[${i}]`, i, ids, problems);
|
|
441
|
+
if (panel) panels.push(panel);
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
return { id, title, panels };
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Normalize an untrusted value into a dashboard document.
|
|
449
|
+
*
|
|
450
|
+
* `{ok: true}` carries the document plus every repair that was made.
|
|
451
|
+
* `{ok: false}` means the input could not be repaired into anything meaningful:
|
|
452
|
+
* it was not an object, it had no usable version, or its version is newer than
|
|
453
|
+
* this build. Callers fall back to the default document and, per the design,
|
|
454
|
+
* leave the file on disk alone.
|
|
455
|
+
*/
|
|
456
|
+
export function validateDashboardDocument(input) {
|
|
457
|
+
// "Never throws" is a promise the callers rely on -- `parseDashboardDocument`
|
|
458
|
+
// is awaited with no try/catch, so a throw here becomes an unhandled
|
|
459
|
+
// rejection and a silently empty dashboard. The bounded walks below should
|
|
460
|
+
// make this unreachable; this is the backstop that keeps the promise true
|
|
461
|
+
// whatever a future edit does.
|
|
462
|
+
try {
|
|
463
|
+
return normalizeDocument(input);
|
|
464
|
+
} catch (err) {
|
|
465
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
466
|
+
return { ok: false, problems: [problem("", `could not be read: ${message}`)] };
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
function normalizeDocument(input) {
|
|
471
|
+
if (!isPlainObject(input)) {
|
|
472
|
+
return {
|
|
473
|
+
ok: false,
|
|
474
|
+
problems: [problem("", `expected a dashboard document object, got ${describe(input)}`)],
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
const version = input.version;
|
|
479
|
+
if (typeof version !== "number" || !Number.isFinite(version) || version < 1) {
|
|
480
|
+
return {
|
|
481
|
+
ok: false,
|
|
482
|
+
problems: [problem("version", `expected a schema version, got ${describe(version)}`)],
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
if (version > DASHBOARD_SCHEMA_VERSION) {
|
|
486
|
+
return {
|
|
487
|
+
ok: false,
|
|
488
|
+
problems: [
|
|
489
|
+
problem(
|
|
490
|
+
"version",
|
|
491
|
+
`schema version ${version} is newer than this build understands (${DASHBOARD_SCHEMA_VERSION})`,
|
|
492
|
+
),
|
|
493
|
+
],
|
|
494
|
+
};
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
const problems = [];
|
|
498
|
+
let rawDashboards = Array.isArray(input.dashboards) ? input.dashboards : [];
|
|
499
|
+
if (!Array.isArray(input.dashboards)) {
|
|
500
|
+
problems.push(problem("dashboards", `expected an array, got ${describe(input.dashboards)}`));
|
|
501
|
+
}
|
|
502
|
+
if (rawDashboards.length > MAX_DASHBOARDS) {
|
|
503
|
+
problems.push(
|
|
504
|
+
problem(
|
|
505
|
+
"dashboards",
|
|
506
|
+
`${rawDashboards.length} dashboards; keeping the first ${MAX_DASHBOARDS}`,
|
|
507
|
+
),
|
|
508
|
+
);
|
|
509
|
+
rawDashboards = rawDashboards.slice(0, MAX_DASHBOARDS);
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
const seenIds = new Set();
|
|
513
|
+
const dashboards = [];
|
|
514
|
+
rawDashboards.forEach((raw, i) => {
|
|
515
|
+
const dashboard = normalizeDashboard(raw, `dashboards[${i}]`, i, seenIds, problems);
|
|
516
|
+
if (dashboard) dashboards.push(dashboard);
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
if (dashboards.length === 0) {
|
|
520
|
+
problems.push(problem("dashboards", "no usable dashboards; using the default"));
|
|
521
|
+
dashboards.push(dashboardFromPreset(DEFAULT_PRESET_ID));
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
let activeId = typeof input.activeId === "string" ? input.activeId.trim() : "";
|
|
525
|
+
if (!dashboards.some((d) => d.id === activeId)) {
|
|
526
|
+
if (input.activeId !== undefined) {
|
|
527
|
+
problems.push(
|
|
528
|
+
problem(
|
|
529
|
+
"activeId",
|
|
530
|
+
`${activeId ? `"${activeId}"` : describe(input.activeId)} is not a dashboard in this document; using "${dashboards[0].id}"`,
|
|
531
|
+
),
|
|
532
|
+
);
|
|
533
|
+
}
|
|
534
|
+
activeId = dashboards[0].id;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
return {
|
|
538
|
+
ok: true,
|
|
539
|
+
document: { version: DASHBOARD_SCHEMA_VERSION, activeId, dashboards },
|
|
540
|
+
problems,
|
|
541
|
+
};
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
/** JSON text -> validated document. Same total-function guarantee. */
|
|
545
|
+
export function parseDashboardDocument(raw) {
|
|
546
|
+
if (typeof raw !== "string") {
|
|
547
|
+
return { ok: false, problems: [problem("", `expected JSON text, got ${describe(raw)}`)] };
|
|
548
|
+
}
|
|
549
|
+
if (raw.trim() === "") {
|
|
550
|
+
return { ok: false, problems: [problem("", "empty")] };
|
|
551
|
+
}
|
|
552
|
+
let parsed;
|
|
553
|
+
try {
|
|
554
|
+
parsed = JSON.parse(raw);
|
|
555
|
+
} catch (err) {
|
|
556
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
557
|
+
return { ok: false, problems: [problem("", `not valid JSON: ${message}`)] };
|
|
558
|
+
}
|
|
559
|
+
return validateDashboardDocument(parsed);
|
|
560
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The layout file, read and written the same way by every process that touches
|
|
3
|
+
* it. Node-only -- the renderer must not import this; it talks to the shells.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export type LayoutReadResult =
|
|
7
|
+
{ ok: true; raw: string | null; revision: string | null } | { ok: false; error: string };
|
|
8
|
+
|
|
9
|
+
export type LayoutWriteResult =
|
|
10
|
+
| { ok: true; revision: string }
|
|
11
|
+
| {
|
|
12
|
+
ok: false;
|
|
13
|
+
error: string;
|
|
14
|
+
conflict?: boolean;
|
|
15
|
+
raw?: string | null;
|
|
16
|
+
revision?: string | null;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Run `fn` with nothing else on this path running at the same time, in this
|
|
21
|
+
* process or any other. Rejects if the lock file cannot be taken within a few
|
|
22
|
+
* seconds; `casWriteLayoutFile` turns that into a failed result.
|
|
23
|
+
*/
|
|
24
|
+
export function withLayoutLock<T>(absPath: string, fn: () => Promise<T>): Promise<T>;
|
|
25
|
+
|
|
26
|
+
/** For tests: is anything queued on any path? */
|
|
27
|
+
export function layoutLockIdle(): boolean;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Read the layout file. A missing file is `{ok: true, raw: null}`; a symlink,
|
|
31
|
+
* a non-file and anything over `maxBytes` are refusals.
|
|
32
|
+
*/
|
|
33
|
+
export function readLayoutFile(absPath: string, maxBytes: number): Promise<LayoutReadResult>;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Replace the layout file if it still carries `baseRevision`. Pass `undefined`
|
|
37
|
+
* for an unconditional write; `null` means "there should be no file yet".
|
|
38
|
+
*/
|
|
39
|
+
export function casWriteLayoutFile(
|
|
40
|
+
absPath: string,
|
|
41
|
+
raw: string,
|
|
42
|
+
baseRevision: string | null | undefined,
|
|
43
|
+
maxBytes: number,
|
|
44
|
+
): Promise<LayoutWriteResult>;
|