@galaxyproject/orbit 0.0.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (451) hide show
  1. package/CHANGELOG.md +123 -0
  2. package/LICENSE +21 -0
  3. package/README.md +760 -5
  4. package/bin/legacy-mcp-config.js +363 -0
  5. package/bin/orbit.js +810 -0
  6. package/bin/pi-extension-path.d.ts +4 -0
  7. package/bin/pi-extension-path.js +44 -0
  8. package/bin/provider-auth.d.ts +22 -0
  9. package/bin/provider-auth.js +77 -0
  10. package/bin/thinking-pref.js +38 -0
  11. package/bin/update-check.d.ts +15 -0
  12. package/bin/update-check.js +137 -0
  13. package/extensions/cli-update/index.ts +32 -0
  14. package/extensions/orbit/activity-hooks.ts +141 -0
  15. package/extensions/orbit/activity.ts +116 -0
  16. package/extensions/orbit/agent-dir.ts +11 -0
  17. package/extensions/orbit/auto-resume.ts +352 -0
  18. package/extensions/orbit/config.ts +3 -0
  19. package/extensions/orbit/confusables.ts +1 -0
  20. package/extensions/orbit/context.ts +957 -0
  21. package/extensions/orbit/dashboard-commands.ts +191 -0
  22. package/extensions/orbit/dashboard-store.ts +473 -0
  23. package/extensions/orbit/dashboard-tools.ts +1185 -0
  24. package/extensions/orbit/empty-completion.ts +99 -0
  25. package/extensions/orbit/evidence-gate.ts +1276 -0
  26. package/extensions/orbit/evidence-override-command.ts +294 -0
  27. package/extensions/orbit/exec-guard/bash-risk.ts +1408 -0
  28. package/extensions/orbit/exec-guard/gate.ts +181 -0
  29. package/extensions/orbit/exec-guard/guardian-config.ts +54 -0
  30. package/extensions/orbit/exec-guard/index.ts +1 -0
  31. package/extensions/orbit/exec-guard/model-tier.ts +36 -0
  32. package/extensions/orbit/exec-guard/path-jail.ts +54 -0
  33. package/extensions/orbit/exec-guard/policy.ts +342 -0
  34. package/extensions/orbit/exec-guard/runtime-state.ts +15 -0
  35. package/extensions/orbit/exec-guard/sensitive-read.ts +525 -0
  36. package/extensions/orbit/exec-guard/types.ts +42 -0
  37. package/extensions/orbit/execution-commands.ts +134 -0
  38. package/extensions/orbit/feedback-command.ts +81 -0
  39. package/extensions/orbit/feedback.ts +96 -0
  40. package/extensions/orbit/galaxy-api.test.ts +122 -0
  41. package/extensions/orbit/galaxy-api.ts +606 -0
  42. package/extensions/orbit/galaxy-artifact-link-guidance.ts +5 -0
  43. package/extensions/orbit/galaxy-destructive-gate.ts +113 -0
  44. package/extensions/orbit/galaxy-enrich.ts +1108 -0
  45. package/extensions/orbit/galaxy-failure.ts +101 -0
  46. package/extensions/orbit/galaxy-fixture.ts +126 -0
  47. package/extensions/orbit/galaxy-history-guard.ts +233 -0
  48. package/extensions/orbit/galaxy-job-block.ts +347 -0
  49. package/extensions/orbit/galaxy-job-ops.ts +288 -0
  50. package/extensions/orbit/galaxy-live-source.ts +929 -0
  51. package/extensions/orbit/galaxy-markdown-adapter.ts +248 -0
  52. package/extensions/orbit/galaxy-op-policy.ts +332 -0
  53. package/extensions/orbit/galaxy-ops-tools.ts +326 -0
  54. package/extensions/orbit/galaxy-output-store.ts +80 -0
  55. package/extensions/orbit/galaxy-output.ts +346 -0
  56. package/extensions/orbit/galaxy-page-binding.ts +222 -0
  57. package/extensions/orbit/galaxy-page-markdown-guidance.ts +15 -0
  58. package/extensions/orbit/galaxy-page-ops.ts +159 -0
  59. package/extensions/orbit/galaxy-page-sync.test.ts +417 -0
  60. package/extensions/orbit/galaxy-page-sync.ts +318 -0
  61. package/extensions/orbit/galaxy-pages-api.ts +203 -0
  62. package/extensions/orbit/galaxy-pages-sync.ts +409 -0
  63. package/extensions/orbit/galaxy-poll-guard.ts +189 -0
  64. package/extensions/orbit/galaxy-poller.ts +706 -0
  65. package/extensions/orbit/galaxy-provenance.ts +623 -0
  66. package/extensions/orbit/galaxy-reconcile.ts +956 -0
  67. package/extensions/orbit/galaxy-recovery.ts +176 -0
  68. package/extensions/orbit/galaxy-repeat-guard.ts +55 -0
  69. package/extensions/orbit/galaxy-submission-capture.ts +707 -0
  70. package/extensions/orbit/galaxy-submission.ts +502 -0
  71. package/extensions/orbit/galaxy-tool-source.ts +78 -0
  72. package/extensions/orbit/galaxy-tool-wrap.ts +234 -0
  73. package/extensions/orbit/galaxy-udt-block.ts +127 -0
  74. package/extensions/orbit/galaxy-upload-tus.ts +334 -0
  75. package/extensions/orbit/galaxy-upload.ts +300 -0
  76. package/extensions/orbit/galaxy-version-capture.ts +65 -0
  77. package/extensions/orbit/git.ts +173 -0
  78. package/extensions/orbit/harness-block-fields.ts +597 -0
  79. package/extensions/orbit/index.ts +593 -0
  80. package/extensions/orbit/init-gate.ts +284 -0
  81. package/extensions/orbit/instructions-command.ts +136 -0
  82. package/extensions/orbit/invocation-failure-hint.ts +57 -0
  83. package/extensions/orbit/iwc-plan-check.ts +94 -0
  84. package/extensions/orbit/lesson-command.ts +303 -0
  85. package/extensions/orbit/lesson-hint.ts +245 -0
  86. package/extensions/orbit/lesson-nudge.ts +106 -0
  87. package/extensions/orbit/lessons/compose.ts +177 -0
  88. package/extensions/orbit/lessons/counters.ts +120 -0
  89. package/extensions/orbit/lessons/enabled.ts +116 -0
  90. package/extensions/orbit/lessons/matcher.ts +346 -0
  91. package/extensions/orbit/lessons/paths.ts +286 -0
  92. package/extensions/orbit/lessons/pi-event-contract.ts +105 -0
  93. package/extensions/orbit/lessons/propose-replay.ts +103 -0
  94. package/extensions/orbit/lessons/propose-tool.ts +222 -0
  95. package/extensions/orbit/lessons/propose.ts +502 -0
  96. package/extensions/orbit/lessons/replay.ts +89 -0
  97. package/extensions/orbit/lessons/reproduction-index.ts +83 -0
  98. package/extensions/orbit/lessons/search-tool.ts +99 -0
  99. package/extensions/orbit/lessons/search.ts +136 -0
  100. package/extensions/orbit/lessons/store.ts +415 -0
  101. package/extensions/orbit/lessons/text.ts +36 -0
  102. package/extensions/orbit/lessons/types.ts +69 -0
  103. package/extensions/orbit/lessons/user-dir.ts +24 -0
  104. package/extensions/orbit/lessons/user-lesson.ts +88 -0
  105. package/extensions/orbit/lessons/wrapper.ts +61 -0
  106. package/extensions/orbit/lessons-command.ts +147 -0
  107. package/extensions/orbit/local-exec.ts +39 -0
  108. package/extensions/orbit/mcp-output.ts +179 -0
  109. package/extensions/orbit/mcp-servers.test.ts +24 -0
  110. package/extensions/orbit/mcp-servers.ts +25 -0
  111. package/extensions/orbit/model-script.ts +351 -0
  112. package/extensions/orbit/notebook-anchors.ts +342 -0
  113. package/extensions/orbit/notebook-writer.ts +863 -0
  114. package/extensions/orbit/observation-allowlists.ts +1109 -0
  115. package/extensions/orbit/observation-replay.ts +148 -0
  116. package/extensions/orbit/observation-triggers.ts +563 -0
  117. package/extensions/orbit/observation-ui.ts +175 -0
  118. package/extensions/orbit/observations-command.ts +421 -0
  119. package/extensions/orbit/observations-config.ts +200 -0
  120. package/extensions/orbit/observations.ts +1381 -0
  121. package/extensions/orbit/profiles.ts +270 -0
  122. package/extensions/orbit/progress-updates.ts +95 -0
  123. package/extensions/orbit/proposal-commands.ts +882 -0
  124. package/extensions/orbit/provenance-fs-file.ts +59 -0
  125. package/extensions/orbit/provenance-fs.ts +32 -0
  126. package/extensions/orbit/provenance-memory-fs.ts +59 -0
  127. package/extensions/orbit/record-store-file.ts +177 -0
  128. package/extensions/orbit/record-store-page.ts +77 -0
  129. package/extensions/orbit/record-store-seam.ts +47 -0
  130. package/extensions/orbit/record-store.ts +149 -0
  131. package/extensions/orbit/registry-carrier.ts +107 -0
  132. package/extensions/orbit/registry-eligibility.ts +95 -0
  133. package/extensions/orbit/registry-evaluation.ts +403 -0
  134. package/extensions/orbit/registry-evaluator.ts +519 -0
  135. package/extensions/orbit/registry-import.ts +91 -0
  136. package/extensions/orbit/registry-lock.ts +221 -0
  137. package/extensions/orbit/registry-memory-fs.ts +42 -0
  138. package/extensions/orbit/registry-page-carrier.ts +103 -0
  139. package/extensions/orbit/registry-proposal.ts +1348 -0
  140. package/extensions/orbit/registry-runtime.ts +234 -0
  141. package/extensions/orbit/registry-schema.ts +735 -0
  142. package/extensions/orbit/registry-submitter.ts +59 -0
  143. package/extensions/orbit/registry-templates.ts +346 -0
  144. package/extensions/orbit/registry.ts +476 -0
  145. package/extensions/orbit/sandbox/index.ts +120 -0
  146. package/extensions/orbit/sandbox/sandbox-bash.ts +93 -0
  147. package/extensions/orbit/sandbox/sandbox-config.ts +87 -0
  148. package/extensions/orbit/sandbox/sandbox-init-message.ts +28 -0
  149. package/extensions/orbit/secret-redaction.ts +247 -0
  150. package/extensions/orbit/session-index/cwd.ts +18 -0
  151. package/extensions/orbit/session-index/db.ts +56 -0
  152. package/extensions/orbit/session-index/indexer.ts +154 -0
  153. package/extensions/orbit/session-index/is-enabled.ts +17 -0
  154. package/extensions/orbit/session-index/parse.ts +254 -0
  155. package/extensions/orbit/session-index/query.ts +209 -0
  156. package/extensions/orbit/session-index/schema.ts +72 -0
  157. package/extensions/orbit/session-index/tools.ts +152 -0
  158. package/extensions/orbit/session-lifecycle.ts +321 -0
  159. package/extensions/orbit/skill-triggers.ts +159 -0
  160. package/extensions/orbit/skills-command.ts +48 -0
  161. package/extensions/orbit/skills-discovery.ts +435 -0
  162. package/extensions/orbit/skills.ts +84 -0
  163. package/extensions/orbit/sra-import-gate.ts +77 -0
  164. package/extensions/orbit/state.ts +265 -0
  165. package/extensions/orbit/submission-replay.ts +147 -0
  166. package/extensions/orbit/sync-command.ts +157 -0
  167. package/extensions/orbit/teams/critic-parser.ts +93 -0
  168. package/extensions/orbit/teams/dispatcher.ts +210 -0
  169. package/extensions/orbit/teams/is-enabled.ts +22 -0
  170. package/extensions/orbit/teams/tool.ts +187 -0
  171. package/extensions/orbit/teams/types.ts +57 -0
  172. package/extensions/orbit/teams/validate.ts +42 -0
  173. package/extensions/orbit/tester-id-command.ts +133 -0
  174. package/extensions/orbit/tools-sync.ts +279 -0
  175. package/extensions/orbit/tools.ts +1300 -0
  176. package/extensions/orbit/types.ts +41 -0
  177. package/extensions/orbit/ui-bridge.ts +55 -0
  178. package/extensions/orbit/ulid.ts +60 -0
  179. package/extensions/orbit/user-instructions.ts +388 -0
  180. package/extensions/orbit/vendor/skills/_catalog.json +68 -0
  181. package/extensions/orbit/vendor/skills/_manifest.json +1106 -0
  182. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/SKILL.md +112 -0
  183. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/_provenance.json +218 -0
  184. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/_required_tools.json +33 -0
  185. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/_verify.json +4 -0
  186. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/cli/add.json +50 -0
  187. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/cli/draft-extract.json +51 -0
  188. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/cli/draft-next-step.json +42 -0
  189. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/cli/draft-validate.json +140 -0
  190. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/cli/list.json +32 -0
  191. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/notes/galaxy-tool-job-failure-reference.md +137 -0
  192. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/notes/open-requirements-ledger.md +173 -0
  193. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/schemas/galaxy-tool-summary.schema.json +175 -0
  194. package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/schemas/galaxy-workflow-draft.schema.json +2727 -0
  195. package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/SKILL.md +82 -0
  196. package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/_provenance.json +133 -0
  197. package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/_required_tools.json +16 -0
  198. package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/_verify.json +4 -0
  199. package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/references/cli/draft-validate.json +140 -0
  200. package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/references/notes/galaxy-workflow-draft-format.md +135 -0
  201. package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/references/notes/open-requirements-ledger.md +173 -0
  202. package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/references/schemas/galaxy-workflow-draft.schema.json +2727 -0
  203. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/SKILL.md +84 -0
  204. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/_provenance.json +166 -0
  205. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/_verify.json +29 -0
  206. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/notes/galaxy-workflow-testability-design.md +136 -0
  207. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/notes/iwc-shortcuts-anti-patterns.md +357 -0
  208. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/notes/iwc-test-data-conventions.md +308 -0
  209. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/notes/planemo-asserts-idioms.md +246 -0
  210. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/notes/planemo-workflow-test-architecture.md +151 -0
  211. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/schemas/galaxy-workflow-test-plan.schema.json +552 -0
  212. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/schemas/summary-galaxy-workflow.schema.json +687 -0
  213. package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/schemas/tests-format.schema.json +7328 -0
  214. package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/SKILL.md +127 -0
  215. package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/_provenance.json +198 -0
  216. package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/_required_tools.json +16 -0
  217. package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/_verify.json +4 -0
  218. package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/references/cli/convert.json +123 -0
  219. package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/references/notes/galaxy-data-flow-draft-contract.md +129 -0
  220. package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/references/notes/iwc-shortcuts-anti-patterns.md +357 -0
  221. package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/references/notes/iwc-test-data-conventions.md +308 -0
  222. package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/references/notes/open-requirements-ledger.md +173 -0
  223. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/SKILL.md +73 -0
  224. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/_provenance.json +160 -0
  225. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/_verify.json +4 -0
  226. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/galaxy-collection-semantics.md +43 -0
  227. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/galaxy-collection-semantics.yml +1250 -0
  228. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/galaxy-tool-job-failure-reference.md +137 -0
  229. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/galaxy-workflow-invocation-failure-reference.md +138 -0
  230. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/iwc-shortcuts-anti-patterns.md +357 -0
  231. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/nextflow-operators-to-galaxy-collection-recipes.md +98 -0
  232. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/planemo-asserts-idioms.md +246 -0
  233. package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/planemo-workflow-test-architecture.md +151 -0
  234. package/extensions/orbit/vendor/skills/discover-shed-tool/SKILL.md +174 -0
  235. package/extensions/orbit/vendor/skills/discover-shed-tool/_provenance.json +130 -0
  236. package/extensions/orbit/vendor/skills/discover-shed-tool/_required_tools.json +18 -0
  237. package/extensions/orbit/vendor/skills/discover-shed-tool/_verify.json +17 -0
  238. package/extensions/orbit/vendor/skills/discover-shed-tool/references/cli/tool-revisions.json +48 -0
  239. package/extensions/orbit/vendor/skills/discover-shed-tool/references/cli/tool-search.json +95 -0
  240. package/extensions/orbit/vendor/skills/discover-shed-tool/references/cli/tool-versions.json +39 -0
  241. package/extensions/orbit/vendor/skills/discover-shed-tool/references/notes/component-tool-shed-search.md +230 -0
  242. package/extensions/orbit/vendor/skills/discover-shed-tool/references/schemas/galaxy-tool-discovery.schema.json +231 -0
  243. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/SKILL.md +93 -0
  244. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/_provenance.json +201 -0
  245. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/_required_tools.json +28 -0
  246. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/_verify.json +17 -0
  247. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/cli/planemo.md +44 -0
  248. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/cli/validate-tests.json +40 -0
  249. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/notes/galaxy-workflow-testability-design.md +136 -0
  250. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/notes/iwc-shortcuts-anti-patterns.md +357 -0
  251. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/notes/iwc-test-data-conventions.md +308 -0
  252. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/notes/planemo-asserts-idioms.md +246 -0
  253. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/notes/planemo-workflow-test-architecture.md +151 -0
  254. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/schemas/galaxy-workflow-test-plan.schema.json +552 -0
  255. package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/schemas/tests-format.schema.json +7328 -0
  256. package/extensions/orbit/vendor/skills/interview-to-galaxy-workflow-changeset/SKILL.md +81 -0
  257. package/extensions/orbit/vendor/skills/interview-to-galaxy-workflow-changeset/_provenance.json +93 -0
  258. package/extensions/orbit/vendor/skills/interview-to-galaxy-workflow-changeset/_verify.json +17 -0
  259. package/extensions/orbit/vendor/skills/interview-to-galaxy-workflow-changeset/references/notes/open-requirements-ledger.md +173 -0
  260. package/extensions/orbit/vendor/skills/interview-to-galaxy-workflow-changeset/references/schemas/summary-galaxy-workflow.schema.json +687 -0
  261. package/extensions/orbit/vendor/skills/pipeline-update-interview-to-galaxy/SKILL.md +81 -0
  262. package/extensions/orbit/vendor/skills/pipeline-update-interview-to-galaxy/_assembly.json +23 -0
  263. package/extensions/orbit/vendor/skills/run-workflow-test/SKILL.md +79 -0
  264. package/extensions/orbit/vendor/skills/run-workflow-test/_provenance.json +125 -0
  265. package/extensions/orbit/vendor/skills/run-workflow-test/_required_tools.json +28 -0
  266. package/extensions/orbit/vendor/skills/run-workflow-test/_verify.json +4 -0
  267. package/extensions/orbit/vendor/skills/run-workflow-test/references/cli/planemo.md +44 -0
  268. package/extensions/orbit/vendor/skills/run-workflow-test/references/cli/validate-tests.json +40 -0
  269. package/extensions/orbit/vendor/skills/run-workflow-test/references/notes/galaxy-workflow-invocation-failure-reference.md +138 -0
  270. package/extensions/orbit/vendor/skills/run-workflow-test/references/notes/planemo-asserts-idioms.md +246 -0
  271. package/extensions/orbit/vendor/skills/run-workflow-test/references/notes/planemo-workflow-test-architecture.md +151 -0
  272. package/extensions/orbit/vendor/skills/run-workflow-test/references/schemas/tests-format.schema.json +7328 -0
  273. package/extensions/orbit/vendor/skills/skills/LICENSE +21 -0
  274. package/extensions/orbit/vendor/skills/skills/collection-manipulation/README.md +39 -0
  275. package/extensions/orbit/vendor/skills/skills/collection-manipulation/SKILL.md +892 -0
  276. package/extensions/orbit/vendor/skills/skills/collection-manipulation/references/api-patterns.md +927 -0
  277. package/extensions/orbit/vendor/skills/skills/collection-manipulation/references/apply-rules.md +1482 -0
  278. package/extensions/orbit/vendor/skills/skills/collection-manipulation/references/test-patterns.md +996 -0
  279. package/extensions/orbit/vendor/skills/skills/collection-manipulation/references/tools.md +609 -0
  280. package/extensions/orbit/vendor/skills/skills/galaxy-data-libraries/SKILL.md +170 -0
  281. package/extensions/orbit/vendor/skills/skills/galaxy-integration/README.md +162 -0
  282. package/extensions/orbit/vendor/skills/skills/galaxy-integration/SKILL.md +99 -0
  283. package/extensions/orbit/vendor/skills/skills/galaxy-integration/examples/README.md +119 -0
  284. package/extensions/orbit/vendor/skills/skills/galaxy-integration/examples/tool-checking.md +419 -0
  285. package/extensions/orbit/vendor/skills/skills/galaxy-integration/examples/workflow-testing.md +617 -0
  286. package/extensions/orbit/vendor/skills/skills/galaxy-integration/galaxy-integration.md +614 -0
  287. package/extensions/orbit/vendor/skills/skills/galaxy-integration/jupyterlite/SKILL.md +144 -0
  288. package/extensions/orbit/vendor/skills/skills/galaxy-integration/jupyterlite/examples/average_col3.ipynb +68 -0
  289. package/extensions/orbit/vendor/skills/skills/galaxy-integration/jupyterlite/examples/extract_sample_metadata.ipynb +190 -0
  290. package/extensions/orbit/vendor/skills/skills/galaxy-integration/jupyterlite/examples/variant_annotation.ipynb +816 -0
  291. package/extensions/orbit/vendor/skills/skills/galaxy-integration/jupyterlite/examples/vcp_variant_map.ipynb +443 -0
  292. package/extensions/orbit/vendor/skills/skills/galaxy-integration/scripts/README.md +165 -0
  293. package/extensions/orbit/vendor/skills/skills/galaxy-integration/scripts/galaxy_tool_checker.py +521 -0
  294. package/extensions/orbit/vendor/skills/skills/galaxy-mcp-reference/SKILL.md +128 -0
  295. package/extensions/orbit/vendor/skills/skills/galaxy-mcp-reference/gotchas.md +135 -0
  296. package/extensions/orbit/vendor/skills/skills/galaxy-mcp-reference/history-access.md +132 -0
  297. package/extensions/orbit/vendor/skills/skills/reproduciblify/SKILL.md +146 -0
  298. package/extensions/orbit/vendor/skills/skills/reproduciblify/references/directives.yml +496 -0
  299. package/extensions/orbit/vendor/skills/skills/udt-authoring/SKILL.md +245 -0
  300. package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/01-minimal-echo.yml +27 -0
  301. package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/02-single-data-in-out.yml +27 -0
  302. package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/03-multiple-data-js.yml +28 -0
  303. package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/04-select-integer-boolean.yml +41 -0
  304. package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/05-resource-requirements.yml +25 -0
  305. package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/06-biocontainer-tool.yml +38 -0
  306. package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/07-inline-python-script.yml +56 -0
  307. package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/08-configfile-script.yml +74 -0
  308. package/extensions/orbit/vendor/skills/skills/udt-authoring/references/common-mistakes.md +76 -0
  309. package/extensions/orbit/vendor/skills/skills/udt-authoring/references/schema-reference.md +155 -0
  310. package/extensions/orbit/vendor/skills/skills/udt-authoring/references/templating.md +196 -0
  311. package/extensions/orbit/vendor/skills/skills/udt-authoring/scripts/validate.py +109 -0
  312. package/extensions/orbit/vendor/skills/skills/workflow-reports/README.md +71 -0
  313. package/extensions/orbit/vendor/skills/skills/workflow-reports/SKILL.md +190 -0
  314. package/extensions/orbit/vendor/skills/skills/workflow-reports/examples/histology-staining.md +145 -0
  315. package/extensions/orbit/vendor/skills/skills/workflow-reports/examples/tissue-microarray-analysis.md +176 -0
  316. package/extensions/orbit/vendor/skills/skills/workflow-reports/references/directives.md +415 -0
  317. package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/SKILL.md +98 -0
  318. package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/_provenance.json +93 -0
  319. package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/_required_tools.json +28 -0
  320. package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/_verify.json +17 -0
  321. package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/references/cli/convert.json +123 -0
  322. package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/references/cli/foundry.md +25 -0
  323. package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/references/cli/validate.json +142 -0
  324. package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/references/schemas/summary-galaxy-workflow.schema.json +687 -0
  325. package/extensions/orbit/vendor/skills/validate-galaxy-workflow/SKILL.md +74 -0
  326. package/extensions/orbit/vendor/skills/validate-galaxy-workflow/_provenance.json +71 -0
  327. package/extensions/orbit/vendor/skills/validate-galaxy-workflow/_required_tools.json +16 -0
  328. package/extensions/orbit/vendor/skills/validate-galaxy-workflow/_verify.json +4 -0
  329. package/extensions/orbit/vendor/skills/validate-galaxy-workflow/references/cli/validate.json +142 -0
  330. package/extensions/orbit/vendor/skills/validate-galaxy-workflow/references/notes/galaxy-workflow-invocation-failure-reference.md +138 -0
  331. package/extensions/orbit/vendor/skills/validate-galaxy-workflow/references/notes/galaxy-workflow-testability-design.md +136 -0
  332. package/extensions/orbit/vendor-skills.ts +283 -0
  333. package/extensions/orbit/workspace-state-dir.ts +46 -0
  334. package/extensions/orbit-handoff/index.ts +73 -0
  335. package/extensions/orbit-handoff/orbit-launcher.ts +142 -0
  336. package/extensions/whats-new/index.ts +98 -0
  337. package/lessons/LICENSE +17 -0
  338. package/lessons/README.md +117 -0
  339. package/lessons/SCHEMA.md +187 -0
  340. package/lessons/build-snapshot.mjs +311 -0
  341. package/lessons/data/downloaded-file-is-not-what-its-extension-says.md +61 -0
  342. package/lessons/galaxy-api/403-history-is-a-hard-stop.md +57 -0
  343. package/lessons/galaxy-api/collection-into-single-dataset-input.md +61 -0
  344. package/lessons/galaxy-api/connectedvalue-in-command-line.md +62 -0
  345. package/lessons/galaxy-api/hid-is-not-an-id.md +59 -0
  346. package/lessons/galaxy-api/invoke-workflow-inputs-not-params.md +60 -0
  347. package/lessons/galaxy-api/repeat-param-pipe-keys.md +63 -0
  348. package/lessons/galaxy-api/run-tool-returns-on-submit.md +61 -0
  349. package/lessons/galaxy-tools/reference-index-not-on-server.md +62 -0
  350. package/lessons/log.md +42 -0
  351. package/lessons/reproduction/input-population-mismatch.md +59 -0
  352. package/lessons/reproduction/methods-text-vs-executed-parameters.md +62 -0
  353. package/lessons/snapshot.json +1004 -0
  354. package/lessons/stats/de-contrast-direction-and-sample-labels.md +63 -0
  355. package/lessons/stats/na-coerced-to-zero-in-filters.md +59 -0
  356. package/lessons/validate.mjs +1219 -0
  357. package/package.json +103 -5
  358. package/shared/agent-prompt.d.ts +8 -0
  359. package/shared/agent-prompt.js +15 -0
  360. package/shared/approval-prompt.d.ts +4 -0
  361. package/shared/approval-prompt.js +61 -0
  362. package/shared/brain-env.d.ts +14 -0
  363. package/shared/brain-env.js +108 -0
  364. package/shared/brain-exit.d.ts +20 -0
  365. package/shared/brain-exit.js +149 -0
  366. package/shared/capability-profile.d.ts +16 -0
  367. package/shared/capability-profile.js +75 -0
  368. package/shared/config-source.d.ts +13 -0
  369. package/shared/config-source.js +17 -0
  370. package/shared/confusables.d.ts +3 -0
  371. package/shared/confusables.js +93 -0
  372. package/shared/custom-provider.d.ts +45 -0
  373. package/shared/custom-provider.js +169 -0
  374. package/shared/dashboard-contract.d.ts +123 -0
  375. package/shared/dashboard-contract.js +560 -0
  376. package/shared/dashboard-layout-store.d.ts +44 -0
  377. package/shared/dashboard-layout-store.js +281 -0
  378. package/shared/feedback-contract.d.ts +61 -0
  379. package/shared/feedback-contract.js +146 -0
  380. package/shared/galaxy-artifact-links.d.ts +30 -0
  381. package/shared/galaxy-artifact-links.js +166 -0
  382. package/shared/galaxy-credentials.d.ts +26 -0
  383. package/shared/galaxy-credentials.js +71 -0
  384. package/shared/galaxy-destructive.d.ts +21 -0
  385. package/shared/galaxy-destructive.js +269 -0
  386. package/shared/galaxy-guidance.d.ts +2 -0
  387. package/shared/galaxy-guidance.js +53 -0
  388. package/shared/galaxy-live-contract.d.ts +92 -0
  389. package/shared/galaxy-live-contract.js +180 -0
  390. package/shared/galaxy-page-cells.d.ts +2 -0
  391. package/shared/galaxy-page-cells.js +22 -0
  392. package/shared/galaxy-tool-family.d.ts +5 -0
  393. package/shared/galaxy-tool-family.js +27 -0
  394. package/shared/galaxy-url.d.ts +1 -0
  395. package/shared/galaxy-url.js +48 -0
  396. package/shared/gtn.d.ts +31 -0
  397. package/shared/gtn.js +253 -0
  398. package/shared/handled-prompt.d.ts +3 -0
  399. package/shared/handled-prompt.js +26 -0
  400. package/shared/known-provider.d.ts +11 -0
  401. package/shared/known-provider.js +89 -0
  402. package/shared/lesson-hint-marker.d.ts +7 -0
  403. package/shared/lesson-hint-marker.js +32 -0
  404. package/shared/lesson-rules.d.ts +150 -0
  405. package/shared/lesson-rules.js +203 -0
  406. package/shared/malformed-object-ids.d.ts +1 -0
  407. package/shared/malformed-object-ids.js +37 -0
  408. package/shared/markdown-sections.d.ts +10 -0
  409. package/shared/markdown-sections.js +118 -0
  410. package/shared/notebook-fences.d.ts +12 -0
  411. package/shared/notebook-fences.js +53 -0
  412. package/shared/observation-contract.d.ts +91 -0
  413. package/shared/observation-contract.js +544 -0
  414. package/shared/orbit-config.d.ts +226 -0
  415. package/shared/orbit-config.js +189 -0
  416. package/shared/orbit-env.d.ts +13 -0
  417. package/shared/orbit-env.js +124 -0
  418. package/shared/orbit-shell-contract.d.ts +74 -0
  419. package/shared/orbit-shell-contract.js +30 -0
  420. package/shared/page-content-hash.d.ts +1 -0
  421. package/shared/page-content-hash.js +13 -0
  422. package/shared/pi-default-model.d.ts +7 -0
  423. package/shared/pi-default-model.js +41 -0
  424. package/shared/prompt-blocks.d.ts +87 -0
  425. package/shared/prompt-blocks.js +898 -0
  426. package/shared/provider-auth-caps.d.ts +22 -0
  427. package/shared/provider-auth-caps.js +57 -0
  428. package/shared/random.d.ts +2 -0
  429. package/shared/random.js +15 -0
  430. package/shared/record-excerpt.d.ts +4 -0
  431. package/shared/record-excerpt.js +16 -0
  432. package/shared/redirect-guard.d.ts +36 -0
  433. package/shared/redirect-guard.js +235 -0
  434. package/shared/skills-pin.d.ts +8 -0
  435. package/shared/skills-pin.js +9 -0
  436. package/shared/skills-router.d.ts +17 -0
  437. package/shared/skills-router.js +63 -0
  438. package/shared/sra-import.d.ts +34 -0
  439. package/shared/sra-import.js +206 -0
  440. package/shared/state-dir.d.ts +21 -0
  441. package/shared/state-dir.js +240 -0
  442. package/shared/team-dispatch-contract.d.ts +28 -0
  443. package/shared/team-dispatch-contract.js +1 -0
  444. package/shared/truncate-middle.d.ts +11 -0
  445. package/shared/truncate-middle.js +68 -0
  446. package/shared/version-compare.d.ts +10 -0
  447. package/shared/version-compare.js +74 -0
  448. package/shared/whats-new.d.ts +31 -0
  449. package/shared/whats-new.js +83 -0
  450. package/shared/wsl.d.ts +10 -0
  451. package/shared/wsl.js +24 -0
@@ -0,0 +1,321 @@
1
+ import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
2
+ import {
3
+ resetState,
4
+ initSessionArtifacts,
5
+ getNotebookPath,
6
+ stopWatchingNotebook,
7
+ } from "./state.js";
8
+ import { startGalaxyPoller, stopGalaxyPoller } from "./galaxy-poller.js";
9
+ import { armGalaxyLivePanel, disarmGalaxyLivePanel } from "./galaxy-live-source.js";
10
+ import {
11
+ createFollowUpDelivery,
12
+ isAutoResumeEnabled,
13
+ setActiveFollowUpDelivery,
14
+ } from "./auto-resume.js";
15
+ import { initGalaxyPageSync, flushNotebookToGalaxy } from "./galaxy-page-sync.js";
16
+ import {
17
+ upsertSessionSummaryBlock,
18
+ readNotebook,
19
+ withNotebookLock,
20
+ writeNotebook,
21
+ type SessionSummaryYaml,
22
+ } from "./notebook-writer.js";
23
+ import { activeGalaxyStatus, type ActiveGalaxyStatus } from "./profiles.js";
24
+ import { recordStore } from "./record-store.js";
25
+ import * as fs from "fs";
26
+ import * as path from "path";
27
+ import { readEnv } from "../../shared/orbit-env.js";
28
+ import { capabilityProfile } from "../../shared/capability-profile.js";
29
+ import {
30
+ closeSessionRegistry,
31
+ openSessionRegistry,
32
+ recordActiveAtShutdown,
33
+ } from "./registry-runtime.js";
34
+ import { getGalaxyConfig } from "./galaxy-api.js";
35
+
36
+ // Tracked across the session so the shutdown handler can write a complete
37
+ // `loom-session` block. ctx is per-event; we can't read it on shutdown
38
+ // directly, so capture what we need on session_start.
39
+ let sessionStart: { id: string; startedAt: string } | null = null;
40
+
41
+ export function registerSessionLifecycle(pi: ExtensionAPI): void {
42
+ // Refreshed each session_start; a no-op until then.
43
+ let notifyUser: (text: string) => void = () => {};
44
+ let isIdle: () => boolean = () => true;
45
+ const followUps = createFollowUpDelivery(
46
+ // Pi swallows a rejected prompt; delivery watches for the turn to start.
47
+ (text) => pi.sendUserMessage(text, { deliverAs: "followUp" }),
48
+ { onPaused: (text) => notifyUser(text), isIdle: () => isIdle() },
49
+ );
50
+ setActiveFollowUpDelivery(followUps);
51
+ pi.on("agent_start", async () => followUps.agentStarted());
52
+ pi.on("message_end", async (event) => {
53
+ const msg = event.message;
54
+ if (msg.role !== "user") return;
55
+ const text =
56
+ typeof msg.content === "string"
57
+ ? msg.content
58
+ : msg.content
59
+ .filter((c) => c.type === "text")
60
+ .map((c) => c.text)
61
+ .join("\n");
62
+ followUps.userMessageRecorded(text);
63
+ });
64
+ pi.on("agent_settled", async () => followUps.agentSettled());
65
+ // Our own follow-ups (and other brain-sent prompts) arrive as "extension";
66
+ // only what a person typed counts as permission to keep going.
67
+ pi.on("input", async (event) => {
68
+ if (event.source !== "extension") followUps.userInput();
69
+ return { action: "continue" };
70
+ });
71
+ // Every shell's Stop ends in Pi's abort, which lands here as an aborted turn.
72
+ pi.on("agent_end", async (event) => {
73
+ const last = [...event.messages].reverse().find((m) => m.role === "assistant");
74
+ if (last && "stopReason" in last && last.stopReason === "aborted") followUps.aborted();
75
+ });
76
+
77
+ pi.on("session_start", async (_event, ctx) => {
78
+ ctx.ui.setToolsExpanded(false);
79
+
80
+ resetState();
81
+
82
+ syncSessionJsonlSymlink(ctx);
83
+
84
+ await initSessionArtifacts(process.cwd());
85
+
86
+ // Resume the per-history Galaxy page and arm debounce auto-push (no-op
87
+ // unless LOOM_GALAXY_PAGE_SYNC=auto and Galaxy creds are present).
88
+ await initGalaxyPageSync();
89
+
90
+ // Background poller for in-flight Galaxy invocations (#67 part 2).
91
+ // Idempotent — start() stops any prior timer first. Pass the shell
92
+ // notifier so a backgrounded invocation toasts the user on completion
93
+ // (async-by-default execution: submit, hand back, notify-on-finish).
94
+ // The poller fires this from a 15s timer, so the captured session_start
95
+ // ctx may be headless (rpc/--print/web) or stale after a session swap —
96
+ // ctx.ui/hasUI assert an active context and can throw. Guard like the
97
+ // compaction notifier (see registerCommand("compact") in index.ts).
98
+ // Auto-resume (on unless explicitly disabled) hands changed runs back as a
99
+ // queued follow-up, so it verifies outputs itself instead of the toast
100
+ // asking the user to relay. `followUp` is required, not
101
+ // cosmetic: a plain send to a brain that is mid-turn is rejected with
102
+ // "Agent is already processing".
103
+ const resumeFn = isAutoResumeEnabled() ? (text: string) => followUps.deliver(text) : undefined;
104
+
105
+ const toast = (text: string, level: "info" | "warning" | "error") => {
106
+ try {
107
+ if (ctx.hasUI) ctx.ui.notify(text, level);
108
+ } catch {
109
+ /* stale/headless context — a dropped completion toast is fine */
110
+ }
111
+ };
112
+ notifyUser = (text) => toast(text, "info");
113
+ isIdle = () => {
114
+ try {
115
+ return ctx.isIdle();
116
+ } catch {
117
+ return true; // stale context: let the ack timeout decide
118
+ }
119
+ };
120
+ startGalaxyPoller(toast, resumeFn);
121
+
122
+ // Live Galaxy history for the dashboard panel, pushed from the poller tick
123
+ // above rather than a timer of its own. A no-op outside a shell that draws
124
+ // a dashboard, so the terminal pays nothing for it -- and inside one it
125
+ // asks Galaxy nothing until some dashboard actually holds the panel.
126
+ armGalaxyLivePanel(ctx);
127
+
128
+ sessionStart = {
129
+ id: ctx.sessionManager?.getSessionId?.() ?? `session-${Date.now()}`,
130
+ startedAt: new Date().toISOString(),
131
+ };
132
+
133
+ // The approval registry. Opening it never blocks the session: a registry
134
+ // that can't be loaded or locked comes up read-only, with one notice.
135
+ // It hangs off the record the way the activity log does: a page record's
136
+ // key is per conversation, so two pages hosted by one worker never share
137
+ // approvals, while a file record's dirname is the cwd it always was.
138
+ const notebookPath = getNotebookPath();
139
+ const analysisDir =
140
+ capabilityProfile().notebook === "page" && notebookPath
141
+ ? path.dirname(notebookPath)
142
+ : process.cwd();
143
+ const registry = openSessionRegistry({
144
+ analysisDir,
145
+ sessionId: sessionStart.id,
146
+ serverUrl: getGalaxyConfig()?.url ?? "",
147
+ });
148
+ if (registry.notice) {
149
+ toast(registry.notice, registry.session.store.mode === "writer" ? "info" : "warning");
150
+ }
151
+
152
+ const freshSession = readEnv("FRESH_SESSION") === "1";
153
+ const isResume = process.argv.includes("--continue");
154
+
155
+ if (freshSession || isResume) {
156
+ return;
157
+ }
158
+
159
+ sendStartupGreeting(pi, ctx);
160
+ });
161
+
162
+ // Compaction recovery: snapshot the notebook so the post-compact agent can
163
+ // re-orient by re-reading. Notebook is the source of truth — no plan struct
164
+ // to persist.
165
+ pi.on("session_before_compact", async () => {
166
+ await snapshotNotebook(pi);
167
+ return {};
168
+ });
169
+
170
+ pi.on("session_shutdown", async () => {
171
+ // While the store still holds the lock: what this session last saw running.
172
+ const orphaned = recordActiveAtShutdown();
173
+ closeSessionRegistry();
174
+ stopGalaxyPoller();
175
+ disarmGalaxyLivePanel();
176
+ followUps.clear();
177
+ // Close the notebook FSWatcher before the summary write below. The watcher
178
+ // otherwise keeps the event loop alive (so --print never exits) and, since
179
+ // writeSessionSummary() writes to notebook.md, would fire its callback
180
+ // against a now-stale ctx. Closing first releases the loop and silences
181
+ // that fire. #271
182
+ stopWatchingNotebook();
183
+ await writeSessionSummary(orphaned);
184
+ await snapshotNotebook(pi);
185
+ // Best-effort final push (debounce already pushed recent changes).
186
+ await flushNotebookToGalaxy();
187
+ });
188
+ }
189
+
190
+ async function snapshotNotebook(pi: ExtensionAPI): Promise<void> {
191
+ const nbPath = getNotebookPath();
192
+ if (!nbPath) return;
193
+ try {
194
+ const { content } = await recordStore(nbPath).read();
195
+ pi.appendEntry("notebook_snapshot", { path: nbPath, content });
196
+ } catch (err) {
197
+ console.error("notebook snapshot failed:", err);
198
+ }
199
+ }
200
+
201
+ /**
202
+ * Write a `loom-session` block to the notebook on shutdown so a future
203
+ * session can see what was running. `orphaned_active_steps` counts the
204
+ * registry attempts whose runs were still going when the session ended
205
+ * (`supervision.active_at_shutdown`); it never says the remote run stopped.
206
+ *
207
+ * Upserts by session id (#260): Pi reuses the same session id when an idle
208
+ * session is resumed, so a second shutdown continues the existing block
209
+ * rather than appending a duplicate under the same id.
210
+ *
211
+ * Uses the same per-path mutex chain as the invocation poller so a
212
+ * concurrent `galaxy_invocation_check_*` write at shutdown doesn't lose
213
+ * the summary.
214
+ */
215
+ async function writeSessionSummary(orphanedActiveSteps: number): Promise<void> {
216
+ const nbPath = getNotebookPath();
217
+ if (!nbPath || !sessionStart) return;
218
+ const summary: SessionSummaryYaml = {
219
+ id: sessionStart.id,
220
+ startedAt: sessionStart.startedAt,
221
+ endedAt: new Date().toISOString(),
222
+ notebook: path.basename(nbPath),
223
+ orphanedActiveSteps,
224
+ };
225
+ try {
226
+ await withNotebookLock(nbPath, async () => {
227
+ const content = await readNotebook(nbPath);
228
+ const updated = upsertSessionSummaryBlock(content, summary);
229
+ await writeNotebook(nbPath, updated);
230
+ });
231
+ } catch (err) {
232
+ console.error("session summary write failed:", err);
233
+ }
234
+ }
235
+
236
+ /**
237
+ * Drop a `session.jsonl` symlink in the cwd pointing at pi's authoritative
238
+ * session file (~/.pi/agent/sessions/<encoded-cwd>/). Best-effort.
239
+ */
240
+ function syncSessionJsonlSymlink(ctx: ExtensionContext): void {
241
+ try {
242
+ const target = ctx.sessionManager?.getSessionFile?.();
243
+ if (!target) return;
244
+ const linkPath = path.join(process.cwd(), "session.jsonl");
245
+ try {
246
+ const existing = fs.lstatSync(linkPath);
247
+ if (!existing.isSymbolicLink()) {
248
+ console.warn("session.jsonl exists and is not an Orbit symlink; leaving it untouched");
249
+ return;
250
+ }
251
+ fs.unlinkSync(linkPath);
252
+ } catch {
253
+ // link didn't exist -- fall through to create
254
+ }
255
+ fs.symlinkSync(target, linkPath);
256
+ } catch (err) {
257
+ console.error("session.jsonl symlink failed:", err);
258
+ }
259
+ }
260
+
261
+ type NotifyAction = { kind: "notify"; text: string; level: "info" | "warning" };
262
+ type GreetingAction = { kind: "model"; message: string } | NotifyAction;
263
+
264
+ /**
265
+ * Decide the startup greeting from the active Galaxy credential status. Pure so
266
+ * it can be unit-tested without a live session.
267
+ *
268
+ * `usable` keeps a real model turn, which says the Galaxy tools are ready.
269
+ * The other two states are pure pleasantries, so they render as a static
270
+ * notify: no model round-trip, no leaked instruction, and the same call
271
+ * surfaces in both the terminal TUI and Orbit (which renders the notify RPC
272
+ * event).
273
+ */
274
+ export function planStartupGreeting(status: ActiveGalaxyStatus, isOrbit: boolean): GreetingAction {
275
+ if (status === "usable") {
276
+ const message =
277
+ `Session started in this project directory. Read \`notebook.md\` to see prior work. ` +
278
+ (isOrbit
279
+ ? `Reply with one short sentence: "What do you want to work on next?" ` +
280
+ `No greeting, no emojis, no product branding.`
281
+ : `Give a brief welcome, then ask what to work on next, referencing the notebook contents if there is prior work. ` +
282
+ `Keep it to 2-3 sentences.`) +
283
+ ` Galaxy credentials are configured and the Galaxy tools are ready to use.`;
284
+ return { kind: "model", message };
285
+ }
286
+
287
+ if (status === "configured-unusable") {
288
+ return {
289
+ kind: "notify",
290
+ level: "warning",
291
+ text:
292
+ `Welcome to Orbit. A Galaxy profile is configured, but its API key only decrypts inside the Orbit desktop app -- ` +
293
+ `Galaxy tools won't work in this terminal. Run from Orbit, export GALAXY_URL and GALAXY_API_KEY, or /connect a server. ` +
294
+ `What would you like to work on?`,
295
+ };
296
+ }
297
+
298
+ return {
299
+ kind: "notify",
300
+ level: "info",
301
+ text:
302
+ `Welcome to Orbit. No Galaxy server is configured, so work runs locally for now -- use /connect to set one up. ` +
303
+ `What would you like to work on?`,
304
+ };
305
+ }
306
+
307
+ export function sendStartupGreeting(pi: ExtensionAPI, ctx: ExtensionContext): void {
308
+ // Print and json modes prompt the session themselves right after
309
+ // session_start; a greeting turn there starts first, and their prompt is then
310
+ // rejected with "Agent is already processing" (#424). Nobody would read the
311
+ // greeting in those modes anyway. Gated on the mode rather than hasUI: a shell
312
+ // host without dialogs (the browser's, today) still wants its greeting.
313
+ if (ctx.mode === "print" || ctx.mode === "json") return;
314
+ const isOrbit = capabilityProfile().ui === "desktop";
315
+ const action = planStartupGreeting(activeGalaxyStatus(), isOrbit);
316
+ if (action.kind === "model") {
317
+ pi.sendUserMessage(action.message);
318
+ } else {
319
+ ctx.ui.notify(action.text, action.level);
320
+ }
321
+ }
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Tool-result hints, as one table.
3
+ *
4
+ * A hint appends a short note to a tool result when the result shows a
5
+ * situation the model should handle a particular way -- usually with a
6
+ * `skills_fetch` pointer to the bundled reference that covers it. This is how
7
+ * skills that stay out of the prompt router reach the model: they cost nothing
8
+ * until the situation comes up.
9
+ *
10
+ * Each trigger used to be its own module with its own `message_end` hook. New
11
+ * ones are a row here instead. Every hint that fires is logged as a
12
+ * `skill.hint` activity event, so evals can check it fired and whether the
13
+ * model followed up.
14
+ */
15
+
16
+ import path from "node:path";
17
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
18
+ import { appendActivityEvent } from "./activity";
19
+ import { findConfusablesMatch } from "./confusables";
20
+ import { hasFailedTransition, INVOCATION_FAILED_HINT } from "./invocation-failure-hint";
21
+ import { getNotebookPath } from "./state";
22
+ import type { GalaxyToolFamily } from "../../shared/galaxy-tool-family.js";
23
+
24
+ export interface HintContext {
25
+ toolName: string;
26
+ /** One text block of the result. A trigger sees each block in order. */
27
+ text: string;
28
+ activeTools: () => string[];
29
+ }
30
+
31
+ export interface SkillTrigger {
32
+ id: string;
33
+ /** Tool names this trigger watches; omit to watch every tool. */
34
+ tools?: ReadonlySet<string>;
35
+ /** Which results to look at. Most hints only make sense on a success. */
36
+ on: "success" | "error";
37
+ /**
38
+ * The hint to append after this text block, or null. The first block that
39
+ * yields a hint gets it; a result that already contains the hint is skipped,
40
+ * so re-delivery never stacks copies.
41
+ */
42
+ hint(ctx: HintContext): string | null;
43
+ }
44
+
45
+ // agent-loop.js wording when dispatch finds no tool by that exact name.
46
+ const NOT_FOUND_RE = /^Tool\s+(\S+)\s+not found\b/;
47
+
48
+ export const iwcCandidatesHint = (family: GalaxyToolFamily) =>
49
+ "[loom] These are ranked by word overlap, not relevance. Before offering one, call " +
50
+ `\`${family.tool("get_iwc_workflow_details")}\` on the plausible candidates and check their inputs ` +
51
+ "against the data the user actually has (reads vs count tables, paired vs single-end). " +
52
+ "A workflow that needs another's outputs first is half of a chain, not a match. If none " +
53
+ "fit, say so. If nothing came back, retry once with just the assay; if the query had no " +
54
+ "searchable terms, ask the user what they want to find out.";
55
+
56
+ export const skillTriggers = (family: GalaxyToolFamily): readonly SkillTrigger[] => [
57
+ {
58
+ // STOPGAP for #100: the model emitted a Cyrillic/Greek lookalike in a tool
59
+ // name. Only the first text block carries agent-loop's message.
60
+ id: "tool-name-confusables",
61
+ on: "error",
62
+ hint: ({ toolName, text, activeTools }) => {
63
+ if (!NOT_FOUND_RE.test(text)) return null;
64
+ const match = findConfusablesMatch(toolName, activeTools());
65
+ return match
66
+ ? `Did you mean \`${match}\`? The tool name you called contains Unicode confusables (visually similar non-Latin characters).`
67
+ : null;
68
+ },
69
+ },
70
+ {
71
+ // The background poller queues triage for a failed invocation, but a
72
+ // manual check can see the transition first. See invocation-failure-hint.ts.
73
+ id: "invocation-failed",
74
+ tools: new Set(["galaxy_invocation_check_all", "galaxy_invocation_check_one"]),
75
+ on: "success",
76
+ hint: ({ text }) => (hasFailedTransition(text) ? INVOCATION_FAILED_HINT : null),
77
+ },
78
+ {
79
+ // IWC ranking is BM25 with no relevance floor, so an off-topic question
80
+ // still gets confident-looking hits. Fires on the tool name alone: the
81
+ // adapter's output guard can truncate a big result into non-JSON, so the
82
+ // body can't be relied on.
83
+ id: "iwc-candidates",
84
+ tools: new Set([family.tool("recommend_iwc_workflows"), family.tool("search_iwc_workflows")]),
85
+ on: "success",
86
+ hint: () => iwcCandidatesHint(family),
87
+ },
88
+ ];
89
+
90
+ type ContentBlock = { type: string; text?: string };
91
+
92
+ export interface FiredHint {
93
+ id: string;
94
+ hint: string;
95
+ }
96
+
97
+ /**
98
+ * Apply every matching trigger to a tool result. Returns the new content and
99
+ * the hints that fired, or null when nothing changed. Never mutates `content`.
100
+ */
101
+ export function applySkillTriggers<T extends ContentBlock>(
102
+ msg: { toolName: string; isError: boolean; content: T[] },
103
+ activeTools: () => string[],
104
+ triggers: readonly SkillTrigger[],
105
+ ): { content: T[]; fired: FiredHint[] } | null {
106
+ let content = msg.content;
107
+ const fired: FiredHint[] = [];
108
+ const kind = msg.isError ? "error" : "success";
109
+
110
+ for (const trigger of triggers) {
111
+ if (trigger.on !== kind) continue;
112
+ if (trigger.tools && !trigger.tools.has(msg.toolName)) continue;
113
+
114
+ for (let i = 0; i < content.length; i++) {
115
+ const block = content[i];
116
+ if (block.type !== "text" || typeof block.text !== "string") continue;
117
+ const hint = trigger.hint({ toolName: msg.toolName, text: block.text, activeTools });
118
+ if (!hint) continue;
119
+ const already = content.some((c) => typeof c.text === "string" && c.text.includes(hint));
120
+ if (!already) {
121
+ content = content.slice();
122
+ content[i] = { ...block, text: `${block.text}\n\n${hint}` };
123
+ fired.push({ id: trigger.id, hint });
124
+ }
125
+ break;
126
+ }
127
+ }
128
+
129
+ return fired.length > 0 ? { content, fired } : null;
130
+ }
131
+
132
+ export function registerSkillTriggers(pi: ExtensionAPI, family: GalaxyToolFamily): void {
133
+ const triggers = skillTriggers(family);
134
+ pi.on("message_end", (event) => {
135
+ const msg = event.message;
136
+ if (msg.role !== "toolResult" || !msg.toolName) return;
137
+
138
+ const applied = applySkillTriggers(
139
+ { toolName: msg.toolName, isError: !!msg.isError, content: msg.content },
140
+ () => pi.getActiveTools(),
141
+ triggers,
142
+ );
143
+ if (!applied) return;
144
+
145
+ const notebook = getNotebookPath();
146
+ if (notebook) {
147
+ for (const { id } of applied.fired) {
148
+ appendActivityEvent(path.dirname(notebook), {
149
+ timestamp: new Date().toISOString(),
150
+ kind: "skill.hint",
151
+ source: "loom",
152
+ payload: { trigger: id, toolName: msg.toolName, toolCallId: msg.toolCallId },
153
+ });
154
+ }
155
+ }
156
+
157
+ return { message: { ...msg, content: applied.content } };
158
+ });
159
+ }
@@ -0,0 +1,48 @@
1
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
+ import { refreshAllCatalogs, catalogSummary } from "./skills-discovery";
3
+
4
+ export function registerSkillsCommand(pi: ExtensionAPI): void {
5
+ pi.registerCommand("skills", {
6
+ description: "Manage skill catalogs. Subcommands: status (default) | refresh",
7
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
8
+ handler: async (args: string, ctx: any) => {
9
+ const sub = (args ?? "").trim().split(/\s+/)[0] || "status";
10
+ try {
11
+ if (sub === "refresh") {
12
+ ctx.ui.notify("Refreshing skill catalogs…", "info");
13
+ const results = await refreshAllCatalogs();
14
+ const summary = results
15
+ .map((r) => {
16
+ if (r.staging)
17
+ return `${r.repo}: ${r.count} staging skill(s) in Orbit, nothing to fetch`;
18
+ if (r.bundled) return `${r.repo}: ${r.count} (bundled, nothing to fetch)`;
19
+ return r.ok ? `${r.repo}: ${r.count}` : `${r.repo}: failed (${r.error})`;
20
+ })
21
+ .join(", ");
22
+ ctx.ui.notify(`Skills refreshed (${summary}). Takes effect next session.`, "info");
23
+ return;
24
+ }
25
+ if (sub === "status") {
26
+ const summary = catalogSummary()
27
+ .map((r) => {
28
+ if (r.staging)
29
+ return `${r.repo}: ${r.count} staging skill(s) in Orbit, awaiting a permanent home`;
30
+ if (r.bundled) return `${r.repo}: ${r.count} skill(s) bundled with Orbit`;
31
+ return r.cached
32
+ ? `${r.repo}: ${r.count} skill(s) cached`
33
+ : `${r.repo}: not cached yet (run /skills refresh to fetch the latest)`;
34
+ })
35
+ .join("\n");
36
+ ctx.ui.notify(summary || "No skill repos enabled.", "info");
37
+ return;
38
+ }
39
+ ctx.ui.notify(`Unknown /skills subcommand: ${sub}. Use status or refresh.`, "warning");
40
+ } catch (err) {
41
+ ctx.ui.notify(
42
+ `/skills ${sub}: ${err instanceof Error ? err.message : String(err)}`,
43
+ "error",
44
+ );
45
+ }
46
+ },
47
+ });
48
+ }