@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,87 @@
1
+ import * as path from "path";
2
+ import type { SandboxRuntimeConfig } from "@anthropic-ai/sandbox-runtime";
3
+ import { normalizeGalaxyUrl } from "../profiles";
4
+ import { WORKSPACE_STATE_DIR_NAMES } from "../workspace-state-dir";
5
+
6
+ /**
7
+ * Inputs for deriving the OS-sandbox profile. Pure: no I/O, fully testable.
8
+ * Home-relative credential paths are passed to ASRT as `~/...` literals (it
9
+ * expands them); cwd/tmp are absolute.
10
+ */
11
+ export interface SandboxConfigInput {
12
+ /** Session working directory -- the workspace. */
13
+ cwd: string;
14
+ /** OS temp dir (os.tmpdir()). */
15
+ tmpDir: string;
16
+ /** Extra silent-write roots (guardian.extraWorkspaceRoots). */
17
+ extraWriteRoots?: string[];
18
+ /** Galaxy base URL, if known -- its host is allowlisted for bash network. */
19
+ galaxyUrl?: string;
20
+ /** Additional domains a deployment wants reachable from bash. */
21
+ extraAllowedDomains?: string[];
22
+ }
23
+
24
+ // Credential/secret locations under $HOME the sandbox blocks bash from reading,
25
+ // mirroring the exec-guard's sensitive-read set. ASRT expands the `~`.
26
+ const DENY_READ = [
27
+ "~/.ssh",
28
+ "~/.aws",
29
+ "~/.gnupg",
30
+ "~/.config/gcloud",
31
+ "~/.kube",
32
+ "~/.docker",
33
+ "~/Library/Keychains",
34
+ "~/.netrc",
35
+ "~/.pgpass",
36
+ "~/.npmrc",
37
+ "~/.loom/config.json",
38
+ "~/.orbit/config.json",
39
+ ];
40
+
41
+ // Sensitive files the sandbox blocks bash from writing even inside the
42
+ // workspace (a project `.env` or a stray key).
43
+ const DENY_WRITE = [".env", ".env.*", "*.pem", "*.key"];
44
+
45
+ export function hostFromUrl(url?: string): string | undefined {
46
+ if (!url) return undefined;
47
+ try {
48
+ // Normalize via the same helper /connect and the profile system use, so a
49
+ // scheme-less GALAXY_URL ("usegalaxy.org") still resolves to a host.
50
+ const parsed = new URL(normalizeGalaxyUrl(url));
51
+ // Galaxy speaks http(s) only (validateGalaxyUrl enforces this on connect),
52
+ // so keep the host only for those schemes -- an ftp:// or file:// GALAXY_URL
53
+ // must not seed the bash network allowlist.
54
+ if (parsed.protocol !== "https:" && parsed.protocol !== "http:") return undefined;
55
+ return parsed.hostname || undefined;
56
+ } catch {
57
+ return undefined;
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Build the ASRT profile: writable = workspace + tmp + both state-dir spellings
63
+ * (ASRT itself refuses an allow path that symlinks out of bounds); readable = everything except the credential set; network
64
+ * = deny-all for bash by default, allowlisting only the Galaxy host (Galaxy work
65
+ * itself flows over MCP, not bash, so a tight bash network default is safe).
66
+ */
67
+ export function buildSandboxConfig(input: SandboxConfigInput): SandboxRuntimeConfig {
68
+ const allowWrite = [
69
+ input.cwd,
70
+ input.tmpDir,
71
+ ...WORKSPACE_STATE_DIR_NAMES.map((name) => path.join(input.cwd, name)),
72
+ ...(input.extraWriteRoots ?? []),
73
+ ];
74
+ const galaxyHost = hostFromUrl(input.galaxyUrl);
75
+ const allowedDomains = [
76
+ ...(galaxyHost ? [galaxyHost] : []),
77
+ ...(input.extraAllowedDomains ?? []),
78
+ ];
79
+ return {
80
+ network: { allowedDomains, deniedDomains: [] },
81
+ filesystem: {
82
+ denyRead: [...DENY_READ],
83
+ allowWrite,
84
+ denyWrite: [...DENY_WRITE],
85
+ },
86
+ };
87
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * apt package names that provide the Linux sandbox runtime binaries ASRT shells
3
+ * out to: `ripgrep` -> rg, `socat` -> socat, `bubblewrap` -> bwrap. These ship as
4
+ * deb `recommends` (see app/forge.config.ts), so a `--no-install-recommends`
5
+ * install -- or a distro/derivative that strips Recommends -- can still be missing
6
+ * them and trip the init failure in issue #305. (#305 only named rg + socat, but
7
+ * ASRT requires bwrap on Linux too.)
8
+ */
9
+ export const LINUX_SANDBOX_APT_PACKAGES = ["ripgrep", "socat", "bubblewrap"];
10
+
11
+ /**
12
+ * User-facing message for a failed bash-sandbox init. On Linux, when ASRT reports
13
+ * its runtime prerequisites are missing, append the exact apt install line so the
14
+ * user can fix it in one step instead of decoding "ripgrep (rg) not found". Pure:
15
+ * takes the platform and the underlying error message, does no IO.
16
+ */
17
+ export function describeSandboxInitFailure(
18
+ platform: NodeJS.Platform,
19
+ errorMessage: string,
20
+ ): string {
21
+ const base = `Bash sandbox init failed (${errorMessage}); bash stays gated per action.`;
22
+ // ASRT's initialize() throws "Sandbox dependencies not available: ..." only when
23
+ // the Linux binary checks fail; anchor on that so unrelated failures stay terse.
24
+ if (platform === "linux" && /dependencies not available/i.test(errorMessage)) {
25
+ return `${base} On Debian/Ubuntu, install the prerequisites with: sudo apt install ${LINUX_SANDBOX_APT_PACKAGES.join(" ")}`;
26
+ }
27
+ return base;
28
+ }
@@ -0,0 +1,247 @@
1
+ /**
2
+ * Secret redaction for tool OUTPUT (#183).
3
+ *
4
+ * The exec-guard decides whether a path may be read; this is the data-shaped
5
+ * companion that ensures a known secret VALUE never rides a tool result back
6
+ * into the model's context (and from there into the provider's request logs).
7
+ * It is value-based by design: we redact the concrete keys Orbit holds -- the
8
+ * provider/Galaxy API keys in ~/.orbit/config.json and the secret-valued env
9
+ * vars the agent process carries -- so there are no false positives on ordinary
10
+ * output. It is a defense-in-depth backstop for the guard, and it also catches
11
+ * vectors the guard can't (an `env` dump, a key pasted into some other file).
12
+ */
13
+
14
+ import * as fs from "fs";
15
+ import * as path from "path";
16
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
17
+ import { loadConfig } from "../../shared/orbit-config.js";
18
+ import type { OrbitConfig } from "../../shared/orbit-config.js";
19
+ import { installedConfigSource } from "../../shared/config-source.js";
20
+ import { piAgentDir } from "./agent-dir";
21
+ import { galaxyCredentials } from "./galaxy-api";
22
+
23
+ export const REDACTED = "[redacted]";
24
+
25
+ // Below this length a "secret" is too short to redact safely -- scrubbing a
26
+ // 3-char value would mangle ordinary output. Real API keys are far longer.
27
+ const MIN_SECRET_LEN = 8;
28
+
29
+ // Env vars whose VALUE is a live secret. The agent process carries these at
30
+ // runtime (the CLI exports the active provider's key from config; Orbit injects
31
+ // the decrypted key when it spawns the brain), so an `env`/`printenv` dump would
32
+ // otherwise leak them even when the config file itself is locked down. Only
33
+ // secret-VALUED vars belong here -- not names like AWS_PROFILE. Every LOOM_ name
34
+ // is paired with its ORBIT_ twin (tests/orbit-env-security.test.ts enforces it):
35
+ // either spelling can carry the value, and brain-env forwards both prefixes.
36
+ export const SECRET_ENV_VARS = [
37
+ "ANTHROPIC_API_KEY",
38
+ "ANTHROPIC_OAUTH_TOKEN",
39
+ "OPENAI_API_KEY",
40
+ "GEMINI_API_KEY",
41
+ "GOOGLE_API_KEY",
42
+ "GROQ_API_KEY",
43
+ "MISTRAL_API_KEY",
44
+ "XAI_API_KEY",
45
+ "DEEPSEEK_API_KEY",
46
+ "OPENROUTER_API_KEY",
47
+ "CEREBRAS_API_KEY",
48
+ "AI_GATEWAY_API_KEY",
49
+ "AZURE_OPENAI_API_KEY",
50
+ "HF_TOKEN",
51
+ "GALAXY_API_KEY",
52
+ // Custom OpenAI-compatible endpoints carry their key here (pi --api-key). With
53
+ // the dev/CI env fallback this can be the only place the key lives, so its
54
+ // value would otherwise dodge redaction.
55
+ "LOOM_ACTIVE_LLM_API_KEY",
56
+ "ORBIT_ACTIVE_LLM_API_KEY",
57
+ // Shell-side secrets that still ride into the brain through the LOOM_/ORBIT_
58
+ // prefix forwarding, so an `env` dump would otherwise show them.
59
+ "LOOM_WEB_TOKEN",
60
+ "ORBIT_WEB_TOKEN",
61
+ "LOOM_FEEDBACK_KEY",
62
+ "ORBIT_FEEDBACK_KEY",
63
+ ];
64
+
65
+ // Keys in a stored pi credential that are metadata rather than secret. Every
66
+ // other long-enough string in the entry gets collected, deliberately: pi-ai's
67
+ // OAuthCredentials carries an open index signature (`[key: string]: unknown`),
68
+ // so a provider can add a token-shaped field whenever it likes. The two failure
69
+ // modes are not symmetric -- missing a field leaks a live token, over-matching
70
+ // costs a `[redacted]` where an account id used to print -- so this errs toward
71
+ // collecting.
72
+ const AUTH_METADATA_KEYS = new Set(["type", "expires"]);
73
+
74
+ /**
75
+ * Read pi's credential store (~/.pi/agent/auth.json, or wherever
76
+ * PI_CODING_AGENT_DIR points). Best-effort: absent, unreadable, or mid-write
77
+ * under pi's lock all yield null and simply contribute no secrets, exactly as
78
+ * an unconfigured provider does. Never throws -- a redaction pass that failed
79
+ * closed would drop every tool result.
80
+ */
81
+ export function loadPiAuth(agentDir: string = piAgentDir()): unknown {
82
+ try {
83
+ return JSON.parse(fs.readFileSync(path.join(agentDir, "auth.json"), "utf8"));
84
+ } catch {
85
+ return null;
86
+ }
87
+ }
88
+
89
+ /** Minimal structural shape for a pi tool-result content item. */
90
+ interface ContentItem {
91
+ type: string;
92
+ text?: string;
93
+ }
94
+
95
+ /**
96
+ * Gather the concrete secret strings to scrub: every API key in the config
97
+ * (plaintext apiKey AND the apiKeyEncrypted blob, for LLM providers and Galaxy
98
+ * profiles) plus the known secret-valued env vars. Pure -- env is passed in so
99
+ * it's testable. `testerId` is deliberately not a secret, so it survives (the
100
+ * #189 path can read it without leaking keys). `extra` is for values a caller
101
+ * already holds that live in none of those places.
102
+ */
103
+ export function collectSecretValues(
104
+ config: OrbitConfig,
105
+ env: Record<string, string | undefined>,
106
+ auth: unknown = null,
107
+ extra: readonly unknown[] = [],
108
+ ): string[] {
109
+ const out = new Set<string>();
110
+ const add = (v: unknown): void => {
111
+ if (typeof v === "string" && v.length >= MIN_SECRET_LEN) out.add(v);
112
+ };
113
+ for (const p of Object.values(config.llm?.providers ?? {})) {
114
+ add(p?.apiKey);
115
+ add(p?.apiKeyEncrypted);
116
+ }
117
+ for (const p of Object.values(config.galaxy?.profiles ?? {})) {
118
+ add(p?.apiKey);
119
+ add(p?.apiKeyEncrypted);
120
+ }
121
+ for (const name of SECRET_ENV_VARS) add(env[name]);
122
+ // pi's auth.json: the one credential class Orbit cannot encrypt at rest, so
123
+ // value-redaction is the only backstop its tokens get.
124
+ for (const cred of Object.values((auth ?? {}) as Record<string, unknown>)) {
125
+ if (!cred || typeof cred !== "object") continue;
126
+ for (const [key, value] of Object.entries(cred as Record<string, unknown>)) {
127
+ if (AUTH_METADATA_KEYS.has(key)) continue;
128
+ if (typeof value === "string") add(value);
129
+ // An api-key credential nests provider-scoped config under `env`
130
+ // (Cloudflare account/gateway ids and the like), which can itself be secret.
131
+ else if (value && typeof value === "object")
132
+ for (const nested of Object.values(value as Record<string, unknown>)) add(nested);
133
+ }
134
+ }
135
+ for (const v of extra) add(v);
136
+ return [...out];
137
+ }
138
+
139
+ /**
140
+ * Everything the redactor scrubs right now: the config's keys, the secret env
141
+ * vars, pi's auth.json where pi runs natively, the Galaxy key the transport
142
+ * holds, and whatever the shell's config source lists. `auth: false` leaves
143
+ * auth.json out: only the tool_result redactor has ever read it, and the
144
+ * activity log and lesson text keep the set they had.
145
+ */
146
+ export function currentSecretValues({ auth = true }: { auth?: boolean } = {}): string[] {
147
+ const source = installedConfigSource();
148
+ // A shell that hands over the config hands over its secrets too; auth.json is pi's own store.
149
+ const piAuth = auth && !source ? loadPiAuth() : null;
150
+ return collectSecretValues(loadConfig(), process.env, piAuth, [
151
+ galaxyCredentials().apiKey,
152
+ ...(source?.secrets?.() ?? []),
153
+ ]);
154
+ }
155
+
156
+ /**
157
+ * Replace every occurrence of each known secret with the placeholder. Literal
158
+ * (no regex, so key characters can't be misread as patterns); longest-first so a
159
+ * key that contains a shorter one is scrubbed whole. Short/empty values ignored.
160
+ */
161
+ export function redactSecrets(text: string, secrets: Iterable<string>): string {
162
+ let out = text;
163
+ const sorted = [...secrets]
164
+ .filter((s) => s.length >= MIN_SECRET_LEN)
165
+ .sort((a, b) => b.length - a.length);
166
+ for (const s of sorted) {
167
+ if (out.includes(s)) out = out.split(s).join(REDACTED);
168
+ }
169
+ return out;
170
+ }
171
+
172
+ /**
173
+ * Redact text items of a tool-result content array. Returns a changed copy, or
174
+ * `null` if nothing matched (so the caller can no-op). Non-text items (images)
175
+ * pass through untouched; the original array is never mutated.
176
+ */
177
+ export function redactContent<T extends ContentItem>(content: T[], secrets: string[]): T[] | null {
178
+ if (secrets.length === 0) return null;
179
+ let changed = false;
180
+ const next = content.map((c) => {
181
+ if (c && c.type === "text" && typeof c.text === "string") {
182
+ const red = redactSecrets(c.text, secrets);
183
+ if (red !== c.text) {
184
+ changed = true;
185
+ return { ...c, text: red };
186
+ }
187
+ }
188
+ return c;
189
+ });
190
+ return changed ? next : null;
191
+ }
192
+
193
+ /**
194
+ * Register the output-redaction hook. Runs after every tool and rewrites the
195
+ * result content the model receives, so a leaked key never reaches the provider.
196
+ * Reloads config each time so a key added mid-session is covered immediately;
197
+ * a clean result returns nothing (pi keeps the original).
198
+ */
199
+ export function registerSecretRedaction(pi: ExtensionAPI): void {
200
+ pi.on("tool_result", async (event) => {
201
+ const secrets = currentSecretValues();
202
+ const content = redactContent(event.content, secrets);
203
+ // An in-process Galaxy result keeps its whole envelope here, and codemode hands it to the
204
+ // model's script; a spilled one previews only part of it in `content`.
205
+ const structured = event.structuredContent;
206
+ const scrubbed = structured === undefined ? undefined : redactValue(structured, secrets);
207
+ if (!content && scrubbed === structured) return;
208
+ return {
209
+ ...(content ? { content } : {}),
210
+ ...(scrubbed === undefined ? {} : { structuredContent: scrubbed }),
211
+ };
212
+ });
213
+ }
214
+
215
+ /** `value` with every string redacted, or `value` itself when nothing matched. */
216
+ function redactValue<T>(value: T, secrets: string[]): T {
217
+ if (secrets.length === 0) return value;
218
+ if (typeof value === "string") return redactSecrets(value, secrets) as T;
219
+ if (Array.isArray(value)) {
220
+ const next = value.map((v) => redactValue(v, secrets));
221
+ return next.some((v, i) => v !== value[i]) ? (next as T) : value;
222
+ }
223
+ if (value && typeof value === "object") {
224
+ // What reaches the model is the serialized form, which an object's toJSON decides.
225
+ if (typeof (value as { toJSON?: unknown }).toJSON === "function") {
226
+ let plain: unknown;
227
+ try {
228
+ plain = JSON.parse(JSON.stringify(value));
229
+ } catch {
230
+ return value;
231
+ }
232
+ const r = redactValue(plain, secrets);
233
+ return r !== plain ? (r as T) : value;
234
+ }
235
+ let changed = false;
236
+ const next = Object.fromEntries(
237
+ Object.entries(value).map(([k, v]) => {
238
+ const key = redactSecrets(k, secrets);
239
+ const r = redactValue(v, secrets);
240
+ if (r !== v || key !== k) changed = true;
241
+ return [key, r];
242
+ }),
243
+ );
244
+ return changed ? (next as T) : value;
245
+ }
246
+ return value;
247
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Pi.dev encodes each working directory as "--<path-with-slashes-as-dashes>--"
3
+ * and uses that as the per-cwd session directory name under ~/.pi/agent/sessions/.
4
+ *
5
+ * Lossy by design -- a cwd with a literal hyphen collides with one where a
6
+ * slash sat in the same position. This matches Pi's own on-disk encoding
7
+ * (see Pi's SessionManager.getDefaultSessionDir). Do not add escaping; the
8
+ * indexer needs to reproduce the exact directory name Pi writes.
9
+ */
10
+ export function encodeCwd(cwd: string): string {
11
+ return `--${cwd.replace(/^[/\\]/, "").replace(/[/\\:]/g, "-")}--`;
12
+ }
13
+
14
+ export function decodeCwd(encoded: string): string | null {
15
+ if (!encoded.startsWith("--") || !encoded.endsWith("--")) return null;
16
+ const inner = encoded.slice(2, -2);
17
+ return "/" + inner.replace(/-/g, "/");
18
+ }
@@ -0,0 +1,56 @@
1
+ import Database, { type Database as Db } from "better-sqlite3";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { SCHEMA_SQL, SCHEMA_VERSION } from "./schema";
5
+ import { resolveStateDir } from "../../../shared/state-dir.js";
6
+
7
+ export { SCHEMA_VERSION };
8
+
9
+ /**
10
+ * Open (and if needed rebuild) the session-index database.
11
+ *
12
+ * The index is a derived cache -- Pi's JSONL files are the source of truth --
13
+ * so a schema-version mismatch triggers a clean rebuild rather than a
14
+ * migration. Cheap because the next scan will repopulate.
15
+ */
16
+ export function openIndexDb(filePath: string): Db {
17
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
18
+ let db = new Database(filePath);
19
+ db.pragma("journal_mode = WAL");
20
+ db.pragma("foreign_keys = ON");
21
+
22
+ const existing = isSchemaCurrent(db);
23
+ if (!existing) {
24
+ // Single-writer assumption: the session-index DB has one owner per user.
25
+ // If a second process opens between close() and the rmSync calls, its
26
+ // handle becomes invalid -- accepted tradeoff for a derived-cache layer.
27
+ db.close();
28
+ fs.rmSync(filePath, { force: true });
29
+ fs.rmSync(filePath + "-wal", { force: true });
30
+ fs.rmSync(filePath + "-shm", { force: true });
31
+ db = new Database(filePath);
32
+ db.pragma("journal_mode = WAL");
33
+ db.pragma("foreign_keys = ON");
34
+ db.exec(SCHEMA_SQL);
35
+ db.prepare("INSERT INTO meta(key, value) VALUES ('schema_version', ?)").run(
36
+ String(SCHEMA_VERSION),
37
+ );
38
+ }
39
+ return db;
40
+ }
41
+
42
+ function isSchemaCurrent(db: Db): boolean {
43
+ try {
44
+ const row = db.prepare("SELECT value FROM meta WHERE key='schema_version'").get() as
45
+ { value: string } | undefined;
46
+ return row?.value === String(SCHEMA_VERSION);
47
+ } catch {
48
+ // meta table doesn't exist yet
49
+ return false;
50
+ }
51
+ }
52
+
53
+ /** Default location: <state dir>/sessions-index.db. */
54
+ export function defaultDbPath(): string {
55
+ return path.join(resolveStateDir(), "sessions-index.db");
56
+ }
@@ -0,0 +1,154 @@
1
+ import type { Database as Db } from "better-sqlite3";
2
+ import fs from "node:fs";
3
+ import os from "node:os";
4
+ import path from "node:path";
5
+ import { parseSessionFile, type EntryRow, type ToolCallRow } from "./parse";
6
+ import { decodeCwd } from "./cwd";
7
+
8
+ export interface ScanReport {
9
+ sessionsSeen: number;
10
+ sessionsRemoved: number;
11
+ entriesInserted: number;
12
+ toolCallsInserted: number;
13
+ }
14
+
15
+ /**
16
+ * Default location of Pi's session corpus.
17
+ */
18
+ export function defaultSessionsDir(): string {
19
+ return path.join(os.homedir(), ".pi", "agent", "sessions");
20
+ }
21
+
22
+ /**
23
+ * Incrementally synchronize the index DB against a sessions directory.
24
+ *
25
+ * Safe to call repeatedly. On the first call, indexes every file in bulk.
26
+ * Subsequent calls resume per-file from the stored byte offset; files
27
+ * whose mtime hasn't advanced are skipped. Sessions whose file has been
28
+ * deleted are removed from the index.
29
+ */
30
+ export function scanSessions(db: Db, sessionsDir: string = defaultSessionsDir()): ScanReport {
31
+ const report: ScanReport = {
32
+ sessionsSeen: 0,
33
+ sessionsRemoved: 0,
34
+ entriesInserted: 0,
35
+ toolCallsInserted: 0,
36
+ };
37
+
38
+ if (!fs.existsSync(sessionsDir)) return report;
39
+
40
+ const knownFiles = listJsonlFiles(sessionsDir);
41
+ const seenPaths = new Set(knownFiles);
42
+
43
+ // Stale-session cleanup (ON DELETE CASCADE handles entries + tool_calls)
44
+ const existing = db.prepare("SELECT session_id, file_path FROM sessions").all() as Array<{
45
+ session_id: string;
46
+ file_path: string;
47
+ }>;
48
+ const del = db.prepare("DELETE FROM sessions WHERE session_id = ?");
49
+ for (const row of existing) {
50
+ if (!seenPaths.has(row.file_path)) {
51
+ del.run(row.session_id);
52
+ report.sessionsRemoved++;
53
+ }
54
+ }
55
+
56
+ const selState = db.prepare(
57
+ "SELECT session_id, last_indexed_offset FROM sessions WHERE file_path = ?",
58
+ );
59
+ const upsertSession = db.prepare(`
60
+ INSERT INTO sessions(
61
+ session_id, file_path, cwd, name, parent_session, notebook_path,
62
+ created_at, last_indexed_at, last_indexed_offset
63
+ )
64
+ VALUES (@session_id, @file_path, @cwd, @name, @parent_session, @notebook_path,
65
+ @created_at, @last_indexed_at, @last_indexed_offset)
66
+ ON CONFLICT(session_id) DO UPDATE SET
67
+ name = COALESCE(excluded.name, sessions.name),
68
+ notebook_path = COALESCE(excluded.notebook_path, sessions.notebook_path),
69
+ last_indexed_at = excluded.last_indexed_at,
70
+ last_indexed_offset = excluded.last_indexed_offset
71
+ `);
72
+ const insEntry = db.prepare(`
73
+ INSERT OR IGNORE INTO entries(
74
+ entry_id, session_id, parent_id, entry_type, timestamp, role, text_content, raw_json
75
+ ) VALUES (@entry_id, @session_id, @parent_id, @entry_type, @timestamp, @role, @text_content, @raw_json)
76
+ `);
77
+ const insTc = db.prepare(`
78
+ INSERT OR IGNORE INTO tool_calls(entry_id, session_id, tool_use_id, tool_name, arguments_json, result_text)
79
+ VALUES (@entry_id, @session_id, @tool_use_id, @tool_name, @arguments_json, @result_text)
80
+ `);
81
+
82
+ const indexOne = db.transaction((filePath: string) => {
83
+ const prior = selState.get(filePath) as
84
+ { session_id: string; last_indexed_offset: number } | undefined;
85
+ const startOffset = prior?.last_indexed_offset ?? 0;
86
+ const fileSize = fs.statSync(filePath).size;
87
+ if (prior && startOffset >= fileSize) return;
88
+
89
+ const parsed = parseSessionFile(filePath, {
90
+ startOffset,
91
+ skipHeader: startOffset > 0,
92
+ });
93
+
94
+ // Decode cwd from directory name (fallback to header.cwd when decode fails)
95
+ const enclosingDir = path.basename(path.dirname(filePath));
96
+ const cwd = decodeCwd(enclosingDir) ?? parsed.header.cwd ?? "";
97
+
98
+ const sessionId = prior?.session_id ?? parsed.header.id;
99
+ if (!sessionId) return;
100
+
101
+ upsertSession.run({
102
+ session_id: sessionId,
103
+ file_path: filePath,
104
+ cwd,
105
+ name: parsed.sessionName,
106
+ parent_session: parsed.header.parentSession,
107
+ notebook_path: parsed.notebookPath,
108
+ created_at: parsed.header.createdAt || new Date().toISOString(),
109
+ last_indexed_at: new Date().toISOString(),
110
+ last_indexed_offset: parsed.endOffset,
111
+ });
112
+
113
+ for (const entry of parsed.entries) {
114
+ const info = insEntry.run({
115
+ ...entry,
116
+ session_id: sessionId,
117
+ } as EntryRow & { session_id: string });
118
+ if (info.changes > 0) report.entriesInserted++;
119
+ }
120
+ for (const tc of parsed.tool_calls) {
121
+ const info = insTc.run({
122
+ ...tc,
123
+ session_id: sessionId,
124
+ } as ToolCallRow & { session_id: string });
125
+ if (info.changes > 0) report.toolCallsInserted++;
126
+ }
127
+
128
+ report.sessionsSeen++;
129
+ });
130
+
131
+ for (const fp of knownFiles) {
132
+ try {
133
+ indexOne(fp);
134
+ } catch {
135
+ // Broken file -- skip, don't halt the scan
136
+ }
137
+ }
138
+
139
+ return report;
140
+ }
141
+
142
+ function listJsonlFiles(root: string): string[] {
143
+ const out: string[] = [];
144
+ for (const entry of fs.readdirSync(root, { withFileTypes: true })) {
145
+ if (!entry.isDirectory()) continue;
146
+ const sub = path.join(root, entry.name);
147
+ for (const file of fs.readdirSync(sub, { withFileTypes: true })) {
148
+ if (!file.isFile()) continue;
149
+ if (!file.name.endsWith(".jsonl")) continue;
150
+ out.push(path.join(sub, file.name));
151
+ }
152
+ }
153
+ return out;
154
+ }
@@ -0,0 +1,17 @@
1
+ import { loadConfig } from "../config";
2
+ import { readEnv } from "../../../shared/orbit-env.js";
3
+
4
+ /**
5
+ * Whether the experimental session-index tools are opted in.
6
+ *
7
+ * Resolution order mirrors isTeamDispatchEnabled():
8
+ * 1. LOOM_SESSION_INDEX env var -- "1" -> on, "0" -> off, else defer.
9
+ * 2. config.experiments.sessionIndex -- boolean.
10
+ * 3. Default: off.
11
+ */
12
+ export function isSessionIndexEnabled(): boolean {
13
+ const env = readEnv("SESSION_INDEX");
14
+ if (env === "1") return true;
15
+ if (env === "0") return false;
16
+ return loadConfig().experiments?.sessionIndex === true;
17
+ }