better-dsh 0.2.3 → 0.2.4

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 (385) hide show
  1. package/cordis.patch.yml +1 -1
  2. package/docs/50_test-reports/2026-09-06-write/345/267/245/345/205/267sandbox/345/215/207/347/272/247/351/200/217/344/274/240bug/345/244/215/345/217/221/345/217/212/346/214/202/350/265/267-/344/272/213/344/273/266/346/212/245/345/221/212.md +176 -0
  3. package/docs/50_test-reports/2026-09-08-hashline-edit-E_RANGE_UNVERIFIED/350/267/250/350/275/256/344/274/232/350/257/235/351/224/256/345/244/261/346/225/210-/350/257/212/346/226/255/346/212/245/345/221/212.md +226 -0
  4. package/docs/50_test-reports/2026-09-11-control-prompt-into-eval-description/345/256/236/346/265/213/346/212/245/345/221/212.md +222 -0
  5. package/docs/50_test-reports/2026-09-12-fs-scheme-resolution-/345/256/236/346/265/213/346/212/245/345/221/212.md +81 -0
  6. package/docs/50_test-reports/2026-09-12-url-schemes-grammar-matrix/344/270/216catalog-centralize-/345/256/236/346/265/213/346/212/245/345/221/212.md +234 -0
  7. package/docs/50_test-reports/2026-09-12-url-schemes-recallable-context-design/351/252/214/350/257/201/346/212/245/345/221/212.md +160 -0
  8. package/docs/50_test-reports/2026-09-12-url-schemes-recallable-context-/345/256/236/346/265/213/345/211/247/346/234/254.md +44 -0
  9. package/docs/50_test-reports/2026-09-12-url-schemes-recallable-context-/345/256/236/346/265/213/346/212/245/345/221/212.md +89 -0
  10. package/docs/50_test-reports/2026-09-12-url-schemes-/345/205/255scheme/345/206/222/347/203/237/344/270/216/350/276/271/347/225/214/345/256/236/346/265/213/346/212/245/345/221/212.md +198 -0
  11. package/docs/50_test-reports/2026-09-13-hashline-off/344/270/213scheme/345/217/257/350/276/276/346/200/247/345/267/245/345/205/267/351/235/242/344/270/215/345/257/271/347/247/260-/345/256/236/346/265/213/346/212/245/345/221/212.md +246 -0
  12. package/docs/50_test-reports/2026-09-13-preact-ui-shell/345/256/236/346/265/213/346/212/245/345/221/212.md +50 -0
  13. package/docs/50_test-reports/2026-09-14-4999-skill/346/270/205/345/215/225/344/270/216lsp-gate/345/256/236/346/265/213/346/212/245/345/221/212.md +63 -0
  14. package/docs/50_test-reports/upstream-dsh-0.1.3-alpha.2-local-test-report.md +44 -0
  15. package/docs/50_test-reports/upstream-dsh-0.1.3-alpha.2-report.md +110 -0
  16. package/docs/50_test-reports/upstream-dsh-0.1.5-rc.2-local-test-report.md +79 -0
  17. package/docs/50_test-reports/v0.2.3b-hashline-content-locator/345/256/236/346/265/213/346/212/245/345/221/212.md +73 -0
  18. package/docs/50_test-reports/v0.2.3c-mobile-wave/345/256/236/346/265/213/346/212/245/345/221/212.md +47 -0
  19. package/docs/50_test-reports/v0.2.4-ios-focus-zoom-suppression/345/256/236/346/265/213/346/212/245/345/221/212.md +158 -0
  20. package/docs/specs/agent/spec.md +54 -0
  21. package/docs/specs/ast/spec.md +34 -0
  22. package/docs/specs/compaction-recall/spec.md +46 -0
  23. package/docs/specs/ctx/spec.md +107 -0
  24. package/docs/specs/dsh/spec.md +47 -0
  25. package/docs/specs/dvc/spec.md +87 -0
  26. package/docs/specs/escalation-guidance/spec.md +44 -0
  27. package/docs/specs/fs-scheme-resolution/spec.md +37 -0
  28. package/docs/specs/hash-edit/spec.md +41 -0
  29. package/docs/specs/http-read/spec.md +73 -0
  30. package/docs/specs/kernel-provisioning/spec.md +53 -0
  31. package/docs/specs/lsp/spec.md +121 -0
  32. package/docs/specs/mobile-layout/spec.md +108 -0
  33. package/docs/specs/model-failover/spec.md +20 -0
  34. package/docs/specs/preact-ui-shell/spec.md +22 -0
  35. package/docs/specs/repl-dispatch-resilience/spec.md +21 -0
  36. package/docs/specs/skill/spec.md +58 -0
  37. package/docs/specs/tool-surface/spec.md +222 -0
  38. package/docs/specs/url-schema/spec.md +148 -0
  39. package/docs/specs/web-trust-fence/spec.md +43 -0
  40. package/docs/upstream-dsh-0.1.5-rc.2-report.md +156 -0
  41. package/dsh-docs/AGENTS.md +75 -0
  42. package/dsh-docs/agent-lifecycle.md +84 -0
  43. package/dsh-docs/agent-lifecycle.zh.md +86 -0
  44. package/dsh-docs/api-gateway.md +164 -0
  45. package/dsh-docs/api-gateway.zh.md +164 -0
  46. package/dsh-docs/architecture.md +150 -0
  47. package/dsh-docs/architecture.zh.md +154 -0
  48. package/dsh-docs/capability-seams.md +543 -0
  49. package/dsh-docs/capability-seams.zh.md +545 -0
  50. package/dsh-docs/config-catalog.md +3473 -0
  51. package/dsh-docs/config-catalog.zh.md +3474 -0
  52. package/dsh-docs/cookbook/adding-a-package.md +117 -0
  53. package/dsh-docs/cookbook/adding-a-package.zh.md +119 -0
  54. package/dsh-docs/cookbook/adding-a-remote-api.md +197 -0
  55. package/dsh-docs/cookbook/adding-a-remote-api.zh.md +197 -0
  56. package/dsh-docs/cookbook/adding-a-session-format-version.md +109 -0
  57. package/dsh-docs/cookbook/adding-a-session-format-version.zh.md +109 -0
  58. package/dsh-docs/cookbook/adding-a-settings-card.md +102 -0
  59. package/dsh-docs/cookbook/adding-a-settings-card.zh.md +102 -0
  60. package/dsh-docs/cookbook/adding-a-tool.md +101 -0
  61. package/dsh-docs/cookbook/adding-a-tool.zh.md +103 -0
  62. package/dsh-docs/cookbook/adding-a-vendored-package.md +59 -0
  63. package/dsh-docs/cookbook/adding-a-vendored-package.zh.md +59 -0
  64. package/dsh-docs/cookbook/adding-an-llm-adapter.md +43 -0
  65. package/dsh-docs/cookbook/adding-an-llm-adapter.zh.md +43 -0
  66. package/dsh-docs/cookbook/extension-cookbook.md +132 -0
  67. package/dsh-docs/cookbook/extension-cookbook.zh.md +136 -0
  68. package/dsh-docs/cookbook/maintaining-dsh-code-review.md +64 -0
  69. package/dsh-docs/cookbook/maintaining-dsh-code-review.zh.md +64 -0
  70. package/dsh-docs/cookbook/responding-to-pr-review-on-a-stack.md +32 -0
  71. package/dsh-docs/cookbook/responding-to-pr-review-on-a-stack.zh.md +32 -0
  72. package/dsh-docs/cordis-api/context.md +364 -0
  73. package/dsh-docs/cordis-api/context.zh.md +366 -0
  74. package/dsh-docs/cordis-api/events.md +207 -0
  75. package/dsh-docs/cordis-api/events.zh.md +209 -0
  76. package/dsh-docs/cordis-api/fiber.md +375 -0
  77. package/dsh-docs/cordis-api/fiber.zh.md +377 -0
  78. package/dsh-docs/cordis-api/inherited.md +39 -0
  79. package/dsh-docs/cordis-api/registry.md +152 -0
  80. package/dsh-docs/cordis-api/registry.zh.md +154 -0
  81. package/dsh-docs/cordis-api/service.md +102 -0
  82. package/dsh-docs/cordis-api/service.zh.md +104 -0
  83. package/dsh-docs/cordis-primer.md +45 -0
  84. package/dsh-docs/cordis-primer.zh.md +51 -0
  85. package/dsh-docs/cordis-tutorial/01-first-plugin.md +95 -0
  86. package/dsh-docs/cordis-tutorial/01-first-plugin.zh.md +95 -0
  87. package/dsh-docs/cordis-tutorial/02-lifecycle-and-effects.md +98 -0
  88. package/dsh-docs/cordis-tutorial/02-lifecycle-and-effects.zh.md +98 -0
  89. package/dsh-docs/cordis-tutorial/03-services.md +98 -0
  90. package/dsh-docs/cordis-tutorial/03-services.zh.md +98 -0
  91. package/dsh-docs/cordis-tutorial/04-events.md +144 -0
  92. package/dsh-docs/cordis-tutorial/04-events.zh.md +144 -0
  93. package/dsh-docs/cordis-tutorial/05-config.md +84 -0
  94. package/dsh-docs/cordis-tutorial/05-config.zh.md +84 -0
  95. package/dsh-docs/cordis-tutorial/06-composition-and-hmr.md +113 -0
  96. package/dsh-docs/cordis-tutorial/06-composition-and-hmr.zh.md +113 -0
  97. package/dsh-docs/cordis-tutorial/07-into-the-harness.md +108 -0
  98. package/dsh-docs/cordis-tutorial/07-into-the-harness.zh.md +108 -0
  99. package/dsh-docs/cordis-tutorial/index.md +60 -0
  100. package/dsh-docs/cordis-tutorial/index.zh.md +62 -0
  101. package/dsh-docs/deepseek-llm-api-wire-extensions.md +163 -0
  102. package/dsh-docs/deepseek-llm-api-wire-extensions.zh.md +163 -0
  103. package/dsh-docs/defensive-patterns.md +33 -0
  104. package/dsh-docs/defensive-patterns.zh.md +35 -0
  105. package/dsh-docs/development.md +167 -0
  106. package/dsh-docs/development.zh.md +173 -0
  107. package/dsh-docs/event-producer-consumer.md +86 -0
  108. package/dsh-docs/event-producer-consumer.zh.md +88 -0
  109. package/dsh-docs/glossary.md +45 -0
  110. package/dsh-docs/glossary.zh.md +45 -0
  111. package/dsh-docs/graph-atlas.md +22 -0
  112. package/dsh-docs/graph-atlas.zh.md +24 -0
  113. package/dsh-docs/i18n/README.md +60 -0
  114. package/dsh-docs/i18n/README.zh.md +62 -0
  115. package/dsh-docs/i18n/style-samples.md +87 -0
  116. package/dsh-docs/i18n/terminology.md +214 -0
  117. package/dsh-docs/i18n/translation-prompt.md +263 -0
  118. package/dsh-docs/i18n/translation-rules.md +69 -0
  119. package/dsh-docs/i18n/translation-rules.zh.md +69 -0
  120. package/dsh-docs/module-graph.md +1411 -0
  121. package/dsh-docs/module-graph.zh.md +1413 -0
  122. package/dsh-docs/persistence-catalog.md +1075 -0
  123. package/dsh-docs/persistence-catalog.zh.md +1077 -0
  124. package/dsh-docs/postmortem/0001-acp-default-export-drops-inject.md +113 -0
  125. package/dsh-docs/postmortem/0001-acp-default-export-drops-inject.zh.md +113 -0
  126. package/dsh-docs/postmortem/0002-js-expression-disabled-filesystem-tools.md +47 -0
  127. package/dsh-docs/postmortem/0002-js-expression-disabled-filesystem-tools.zh.md +47 -0
  128. package/dsh-docs/postmortem/0003-web-agent-gui-feedback-loop.md +53 -0
  129. package/dsh-docs/postmortem/0003-web-agent-gui-feedback-loop.zh.md +53 -0
  130. package/dsh-docs/postmortem/0004-landlock-partial-notice-misclassified-child-failures.md +55 -0
  131. package/dsh-docs/postmortem/0004-landlock-partial-notice-misclassified-child-failures.zh.md +55 -0
  132. package/dsh-docs/postmortem/README.md +18 -0
  133. package/dsh-docs/postmortem/README.zh.md +18 -0
  134. package/dsh-docs/rescope.md +53 -0
  135. package/dsh-docs/rescope.zh.md +53 -0
  136. package/dsh-docs/session-format-status.md +47 -0
  137. package/dsh-docs/session-format-status.zh.md +47 -0
  138. package/dsh-docs/subsystems/README.md +61 -0
  139. package/dsh-docs/subsystems/README.zh.md +61 -0
  140. package/dsh-docs/subsystems/agent-team.md +207 -0
  141. package/dsh-docs/subsystems/agent-team.zh.md +207 -0
  142. package/dsh-docs/subsystems/approval.md +170 -0
  143. package/dsh-docs/subsystems/approval.zh.md +170 -0
  144. package/dsh-docs/subsystems/attachment.md +351 -0
  145. package/dsh-docs/subsystems/attachment.zh.md +351 -0
  146. package/dsh-docs/subsystems/client-modules.md +168 -0
  147. package/dsh-docs/subsystems/client-modules.zh.md +168 -0
  148. package/dsh-docs/subsystems/client-resources.md +91 -0
  149. package/dsh-docs/subsystems/client-resources.zh.md +91 -0
  150. package/dsh-docs/subsystems/code-runtime.md +195 -0
  151. package/dsh-docs/subsystems/code-runtime.zh.md +195 -0
  152. package/dsh-docs/subsystems/commands.md +219 -0
  153. package/dsh-docs/subsystems/commands.zh.md +219 -0
  154. package/dsh-docs/subsystems/compaction.md +238 -0
  155. package/dsh-docs/subsystems/compaction.zh.md +238 -0
  156. package/dsh-docs/subsystems/conversation.md +258 -0
  157. package/dsh-docs/subsystems/conversation.zh.md +258 -0
  158. package/dsh-docs/subsystems/core.md +1209 -0
  159. package/dsh-docs/subsystems/core.zh.md +1219 -0
  160. package/dsh-docs/subsystems/credentials.md +329 -0
  161. package/dsh-docs/subsystems/credentials.zh.md +329 -0
  162. package/dsh-docs/subsystems/extensions.md +382 -0
  163. package/dsh-docs/subsystems/extensions.zh.md +382 -0
  164. package/dsh-docs/subsystems/feedback.md +266 -0
  165. package/dsh-docs/subsystems/feedback.zh.md +266 -0
  166. package/dsh-docs/subsystems/filesystem.md +505 -0
  167. package/dsh-docs/subsystems/filesystem.zh.md +505 -0
  168. package/dsh-docs/subsystems/goal.md +277 -0
  169. package/dsh-docs/subsystems/goal.zh.md +277 -0
  170. package/dsh-docs/subsystems/invariants.md +88 -0
  171. package/dsh-docs/subsystems/invariants.zh.md +88 -0
  172. package/dsh-docs/subsystems/jobs.md +290 -0
  173. package/dsh-docs/subsystems/jobs.zh.md +290 -0
  174. package/dsh-docs/subsystems/llm-streaming.md +1080 -0
  175. package/dsh-docs/subsystems/llm-streaming.zh.md +1086 -0
  176. package/dsh-docs/subsystems/lsp.md +202 -0
  177. package/dsh-docs/subsystems/lsp.zh.md +202 -0
  178. package/dsh-docs/subsystems/permission-presets.md +131 -0
  179. package/dsh-docs/subsystems/permission-presets.zh.md +131 -0
  180. package/dsh-docs/subsystems/persistence.md +395 -0
  181. package/dsh-docs/subsystems/persistence.zh.md +395 -0
  182. package/dsh-docs/subsystems/plan.md +87 -0
  183. package/dsh-docs/subsystems/plan.zh.md +87 -0
  184. package/dsh-docs/subsystems/sandbox.md +220 -0
  185. package/dsh-docs/subsystems/sandbox.zh.md +220 -0
  186. package/dsh-docs/subsystems/schedule.md +192 -0
  187. package/dsh-docs/subsystems/schedule.zh.md +192 -0
  188. package/dsh-docs/subsystems/scope.md +59 -0
  189. package/dsh-docs/subsystems/scope.zh.md +59 -0
  190. package/dsh-docs/subsystems/session-projection.md +354 -0
  191. package/dsh-docs/subsystems/session-projection.zh.md +354 -0
  192. package/dsh-docs/subsystems/session-query.md +509 -0
  193. package/dsh-docs/subsystems/session-query.zh.md +509 -0
  194. package/dsh-docs/subsystems/session-reference.md +219 -0
  195. package/dsh-docs/subsystems/session-reference.zh.md +219 -0
  196. package/dsh-docs/subsystems/session-telemetry.md +194 -0
  197. package/dsh-docs/subsystems/session-telemetry.zh.md +194 -0
  198. package/dsh-docs/subsystems/session-title.md +204 -0
  199. package/dsh-docs/subsystems/session-title.zh.md +204 -0
  200. package/dsh-docs/subsystems/session.md +1155 -0
  201. package/dsh-docs/subsystems/session.zh.md +1159 -0
  202. package/dsh-docs/subsystems/settings.md +405 -0
  203. package/dsh-docs/subsystems/settings.zh.md +405 -0
  204. package/dsh-docs/subsystems/shell.md +303 -0
  205. package/dsh-docs/subsystems/shell.zh.md +303 -0
  206. package/dsh-docs/subsystems/sidebar-right.md +148 -0
  207. package/dsh-docs/subsystems/sidebar-right.zh.md +148 -0
  208. package/dsh-docs/subsystems/skills.md +354 -0
  209. package/dsh-docs/subsystems/skills.zh.md +354 -0
  210. package/dsh-docs/subsystems/slots.md +175 -0
  211. package/dsh-docs/subsystems/slots.zh.md +175 -0
  212. package/dsh-docs/subsystems/spill.md +117 -0
  213. package/dsh-docs/subsystems/spill.zh.md +117 -0
  214. package/dsh-docs/subsystems/storage.md +260 -0
  215. package/dsh-docs/subsystems/storage.zh.md +260 -0
  216. package/dsh-docs/subsystems/subagent.md +766 -0
  217. package/dsh-docs/subsystems/subagent.zh.md +770 -0
  218. package/dsh-docs/subsystems/subprocess.md +324 -0
  219. package/dsh-docs/subsystems/subprocess.zh.md +324 -0
  220. package/dsh-docs/subsystems/system-prompt.md +220 -0
  221. package/dsh-docs/subsystems/system-prompt.zh.md +220 -0
  222. package/dsh-docs/subsystems/terminal.md +184 -0
  223. package/dsh-docs/subsystems/terminal.zh.md +184 -0
  224. package/dsh-docs/subsystems/todo.md +32 -0
  225. package/dsh-docs/subsystems/todo.zh.md +32 -0
  226. package/dsh-docs/subsystems/token-meter.md +105 -0
  227. package/dsh-docs/subsystems/token-meter.zh.md +105 -0
  228. package/dsh-docs/subsystems/tools.md +720 -0
  229. package/dsh-docs/subsystems/tools.zh.md +720 -0
  230. package/dsh-docs/subsystems/typert.md +343 -0
  231. package/dsh-docs/subsystems/typert.zh.md +343 -0
  232. package/dsh-docs/subsystems/user-questions.md +178 -0
  233. package/dsh-docs/subsystems/user-questions.zh.md +178 -0
  234. package/dsh-docs/subsystems/web-client.md +95 -0
  235. package/dsh-docs/subsystems/web-client.zh.md +95 -0
  236. package/dsh-docs/subsystems/web-server.md +154 -0
  237. package/dsh-docs/subsystems/web-server.zh.md +154 -0
  238. package/dsh-docs/subsystems/web.md +206 -0
  239. package/dsh-docs/subsystems/web.zh.md +206 -0
  240. package/dsh-docs/subsystems/webhook.md +70 -0
  241. package/dsh-docs/subsystems/webhook.zh.md +70 -0
  242. package/dsh-docs/subsystems/workflow.md +278 -0
  243. package/dsh-docs/subsystems/workflow.zh.md +278 -0
  244. package/dsh-docs/subsystems/workspace.md +321 -0
  245. package/dsh-docs/subsystems/workspace.zh.md +321 -0
  246. package/dsh-docs/testing.md +54 -0
  247. package/dsh-docs/testing.zh.md +54 -0
  248. package/dsh-docs/tool-catalog.md +2225 -0
  249. package/dsh-docs/tool-catalog.zh.md +2233 -0
  250. package/dsh-docs/tool-execution-pipeline.md +62 -0
  251. package/dsh-docs/tool-execution-pipeline.zh.md +64 -0
  252. package/dsh-docs/user/develop/basic/config.md +106 -0
  253. package/dsh-docs/user/develop/basic/config.zh.md +106 -0
  254. package/dsh-docs/user/develop/basic/index.md +144 -0
  255. package/dsh-docs/user/develop/basic/index.zh.md +144 -0
  256. package/dsh-docs/user/develop/basic/publish.md +183 -0
  257. package/dsh-docs/user/develop/basic/publish.zh.md +183 -0
  258. package/dsh-docs/user/develop/basic/tool.md +52 -0
  259. package/dsh-docs/user/develop/basic/tool.zh.md +52 -0
  260. package/dsh-docs/user/develop/framework/events.md +143 -0
  261. package/dsh-docs/user/develop/framework/events.zh.md +143 -0
  262. package/dsh-docs/user/develop/framework/index.md +137 -0
  263. package/dsh-docs/user/develop/framework/index.zh.md +137 -0
  264. package/dsh-docs/user/develop/framework/service.md +148 -0
  265. package/dsh-docs/user/develop/framework/service.zh.md +150 -0
  266. package/dsh-docs/user/develop/practice/dynamic-cordis.md +15 -0
  267. package/dsh-docs/user/develop/practice/dynamic-cordis.zh.md +15 -0
  268. package/dsh-docs/user/develop/practice/index.md +155 -0
  269. package/dsh-docs/user/develop/practice/index.zh.md +155 -0
  270. package/dsh-docs/user/develop/practice/llm-adapter.md +189 -0
  271. package/dsh-docs/user/develop/practice/llm-adapter.zh.md +189 -0
  272. package/dsh-docs/user/guide/github-review.md +102 -0
  273. package/dsh-docs/user/guide/github-review.zh.md +102 -0
  274. package/dsh-docs/user/guide/index.md +30 -0
  275. package/dsh-docs/user/guide/index.zh.md +30 -0
  276. package/dsh-docs/user/guide/mcp-memory.md +101 -0
  277. package/dsh-docs/user/guide/mcp-memory.zh.md +101 -0
  278. package/dsh-docs/user/guide/network-proxy.md +85 -0
  279. package/dsh-docs/user/guide/network-proxy.zh.md +85 -0
  280. package/dsh-docs/user/guide/providers.md +190 -0
  281. package/dsh-docs/user/guide/providers.zh.md +190 -0
  282. package/dsh-docs/user/guide/python-sdk.md +150 -0
  283. package/dsh-docs/user/guide/python-sdk.zh.md +150 -0
  284. package/dsh-docs/user/guide/schedule.md +21 -0
  285. package/dsh-docs/user/guide/schedule.zh.md +21 -0
  286. package/dsh-docs/user/index.md +11 -0
  287. package/dsh-docs/user/index.zh.md +11 -0
  288. package/dsh-docs/web-styling.md +29 -0
  289. package/dsh-docs/web-styling.zh.md +29 -0
  290. package/eval-description.md +33 -0
  291. package/lib/client/index.js +327 -88
  292. package/lib/fs-aware/sandbox-plugin.d.ts +71 -0
  293. package/lib/fs-aware/sandbox-plugin.js +249 -0
  294. package/lib/index.d.ts +22 -22
  295. package/lib/index.js +3095 -3204
  296. package/lib/lsp-server-registry-DkaYmTwt.js +972 -0
  297. package/lib/lsp-server-registry-_hk-Wcia.js +3 -0
  298. package/lib/py-sdk-Chvy92MB.js +178 -0
  299. package/lib/py-sdk.d.ts +19 -2
  300. package/lib/py-sdk.js +2 -2
  301. package/lib/wrap-JFjcWwZf.js +747 -0
  302. package/package.json +9 -3
  303. package/url-schemes-instruction.md +22 -0
  304. package/control-prompt.md +0 -37
  305. package/docs/50_test-reports/v0.1.8d_artifacts/README.md +0 -138
  306. package/docs/50_test-reports/v0.1.8d_artifacts/code-mode-repl-only.observation.md +0 -74
  307. package/docs/50_test-reports/v0.1.8d_artifacts/dsh-session-session-4a293388-9ae1-474b-87a0-9e17bb556d94.jsonl +0 -3890
  308. package/docs/50_test-reports/v0.1.8d_artifacts/dsh-session-session-4a293388-9ae1-474b-87a0-9e17bb556d94.w-sample-0435.jsonl +0 -544
  309. package/docs/50_test-reports/v0.1.8d_artifacts/functions.json +0 -592
  310. package/docs/50_test-reports/v0.1.8d_artifacts/skills-catalog.snapshot.md +0 -30
  311. package/docs/50_test-reports/v0.1.8d_artifacts/tools-sdk.output-schemas.json +0 -1236
  312. package/docs/50_test-reports/v0.1.8d_artifacts/tools-sdk.python.txt +0 -592
  313. package/docs/50_test-reports/v0.1.8d_artifacts/tools-sdk.typescript.txt +0 -516
  314. package/docs/50_test-reports/v0.1.8d_artifacts/wire-vs-transcription.diff.md +0 -54
  315. package/docs/50_test-reports/v0.2.0b_artifacts/f2probe/Cargo.lock +0 -7
  316. package/docs/50_test-reports/v0.2.0b_artifacts/f2probe/Cargo.toml +0 -6
  317. package/docs/50_test-reports/v0.2.0b_artifacts/f2probe/src/bin/messy.rs +0 -8
  318. package/docs/50_test-reports/v0.2.0b_artifacts/f2probe/src/main.rs +0 -4
  319. package/docs/50_test-reports/v0.2.0b_artifacts/hashline-probe.md +0 -5
  320. package/docs/50_test-reports/v0.2.0b_artifacts/slowprobe/Cargo.lock +0 -7
  321. package/docs/50_test-reports/v0.2.0b_artifacts/slowprobe/Cargo.toml +0 -7
  322. package/docs/50_test-reports/v0.2.0b_artifacts/slowprobe/build.rs +0 -4
  323. package/docs/50_test-reports/v0.2.0b_artifacts/slowprobe/src/main.rs +0 -13
  324. package/docs/60_exploration-and-research/cordis-research.md +0 -350
  325. package/docs/60_exploration-and-research/dsh-web-profile-package-map.md +0 -186
  326. package/docs/60_exploration-and-research/dsh-web-ui-slot-system-research.md +0 -310
  327. package/docs/60_exploration-and-research/dsh-webui-strip-boundary-research.md +0 -300
  328. package/docs/60_exploration-and-research/ios-chat-app-bridge-research.md +0 -324
  329. package/docs/60_exploration-and-research/web-frontend-composability-research.md +0 -191
  330. package/docs/REPL-/345/267/245/345/205/267/350/260/203/347/224/250-/346/210/252/346/226/255/350/257/212/346/226/255.md +0 -110
  331. package/docs/adr/0001-bridge-tool-layer-not-service-layer.md +0 -14
  332. package/docs/adr/0002-masking-is-presentation-only.md +0 -15
  333. package/docs/plans/A2A-messaging-channel-test-archive.md +0 -256
  334. package/docs/plans/code-mode-vs-rlm-ipython-comparison.md +0 -137
  335. package/docs/plans/dashr-blueprint-review.md +0 -201
  336. package/docs/plans/dashr-blueprint.md +0 -561
  337. package/docs/plans/dashr-compaction-window-and-archive.md +0 -307
  338. package/docs/plans/dashr-profile-layer-feasibility.md +0 -367
  339. package/docs/plans/dashr-sandbox-escalation-semantics-gap.md +0 -171
  340. package/docs/plans/dashr-security-sandbox-analysis.md +0 -187
  341. package/docs/plans/dashr-surface-invariant-and-omp-imports.md +0 -97
  342. package/docs/plans/ipython-kernel-interactive-interface-test-report.md +0 -152
  343. package/docs/plans/kernel-refactoring/Dash-IPython-Control-Prompt-draft.md +0 -146
  344. package/docs/plans/kernel-refactoring/Dash-IPython-Control-Prompt-draft_v3.md +0 -50
  345. package/docs/plans/kernel-refactoring/Dash-IPython-Control-Prompt-draft_v4.md +0 -79
  346. package/docs/plans/kernel-refactoring/Dash-vs-PrimeAgent-systemprompt-toolcatalog-comparison.md +0 -138
  347. package/docs/plans/kernel-refactoring/RLM-system-prompt-injection-gap-report.md +0 -161
  348. package/docs/plans/kernel-refactoring/V0.1.5-development-plan.md +0 -109
  349. package/docs/plans/kernel-refactoring/actinoable-surface-to-llm-in-agent-runtime_dsh.md +0 -50
  350. package/docs/plans/kernel-refactoring/actinoable-surface-to-llm-in-agent-runtime_prime.md +0 -113
  351. package/docs/plans/recallable-compaction.md +0 -147
  352. package/docs/plans/spike-tag-repro.mjs +0 -102
  353. package/docs/plans/upstream-analysis.md +0 -128
  354. package/docs/v0.1.8-improved-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -142
  355. package/docs/v0.1.8-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -193
  356. package/docs/v0.1.8b-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -96
  357. package/docs/v0.1.8c-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -127
  358. package/docs/v0.1.8d-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -150
  359. package/docs/v0.1.8d_artifacts/README.md +0 -138
  360. package/docs/v0.1.8d_artifacts/code-mode-repl-only.observation.md +0 -74
  361. package/docs/v0.1.8d_artifacts/dsh-session-session-4a293388-9ae1-474b-87a0-9e17bb556d94.jsonl +0 -3890
  362. package/docs/v0.1.8d_artifacts/dsh-session-session-4a293388-9ae1-474b-87a0-9e17bb556d94.w-sample-0435.jsonl +0 -544
  363. package/docs/v0.1.8d_artifacts/functions.json +0 -592
  364. package/docs/v0.1.8d_artifacts/skills-catalog.snapshot.md +0 -30
  365. package/docs/v0.1.8d_artifacts/tools-sdk.output-schemas.json +0 -1236
  366. package/docs/v0.1.8d_artifacts/tools-sdk.python.txt +0 -592
  367. package/docs/v0.1.8d_artifacts/tools-sdk.typescript.txt +0 -516
  368. package/docs/v0.1.8d_artifacts/wire-vs-transcription.diff.md +0 -54
  369. package/docs/v0.1.8e-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -224
  370. package/docs/v0.1.9a-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -168
  371. package/docs/v0.2.0b-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -123
  372. package/docs/v0.2.0b_artifacts/f2probe/Cargo.lock +0 -7
  373. package/docs/v0.2.0b_artifacts/f2probe/Cargo.toml +0 -6
  374. package/docs/v0.2.0b_artifacts/f2probe/src/bin/messy.rs +0 -8
  375. package/docs/v0.2.0b_artifacts/f2probe/src/main.rs +0 -4
  376. package/docs/v0.2.0b_artifacts/hashline-probe.md +0 -5
  377. package/docs/v0.2.0b_artifacts/slowprobe/Cargo.lock +0 -7
  378. package/docs/v0.2.0b_artifacts/slowprobe/Cargo.toml +0 -7
  379. package/docs/v0.2.0b_artifacts/slowprobe/build.rs +0 -4
  380. package/docs/v0.2.0b_artifacts/slowprobe/src/main.rs +0 -13
  381. package/docs/v0.2.1-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -110
  382. package/docs/v0.2.1b-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -86
  383. package/docs/v0.2.1c-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -66
  384. package/lib/py-sdk-BCaOGYz7.d.ts +0 -125
  385. package/lib/py-sdk-CbgYiX8O.js +0 -691
@@ -0,0 +1,747 @@
1
+ import { promises, statSync } from "node:fs";
2
+ import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+
5
+ //#region src/url-schemes/catalog.ts
6
+ /**
7
+ * The scheme set, in declaration order.
8
+ *
9
+ * `paths` mirrors each handler's own path parsing, not an idealised grammar:
10
+ * `dvc://` addresses a device by its FIRST segment only (a trailing `/sub` is
11
+ * parsed and then dropped), and `ctx://` addresses collection elements with a
12
+ * `[n]` bracket that lives in the *path*, not in the selector.
13
+ */
14
+ const SCHEME_CATALOGUE = [
15
+ {
16
+ names: ["skill"],
17
+ display: "skill://",
18
+ paths: "skill://<name>[/<file>]",
19
+ purpose: "a registered skill's files",
20
+ example: "skill://<name>/SKILL.md",
21
+ write: "read-only"
22
+ },
23
+ {
24
+ names: ["agent"],
25
+ display: "agent://",
26
+ paths: "agent://[<id>[/transcript]]",
27
+ purpose: "agent roster / a LIVE agent transcript",
28
+ example: "agent://<id>/transcript:1-40",
29
+ write: "read-only"
30
+ },
31
+ {
32
+ names: ["dsh"],
33
+ display: "dsh://",
34
+ paths: "dsh://docs[/<doc>] · dsh://config",
35
+ purpose: "harness docs / live resolved config",
36
+ example: "dsh://config:path/agent-loop.maxParallelToolCalls",
37
+ write: "read-only"
38
+ },
39
+ {
40
+ names: ["ctx"],
41
+ display: "ctx://",
42
+ paths: "ctx://session/<face>",
43
+ purpose: "THIS session's own log; face ∈ transcript, compactions, thinking, system, user_prompts[n], tool_calls[n], agent_responses[n]",
44
+ example: "ctx://session/tool_calls[0]",
45
+ write: "read-only",
46
+ selector: "`:raw` | `:N-M[,N2-M2]` | `:raw:N-M` (composite ≡ `:N-M`); `[n]` is path syntax (0-based ordinal or event seq)"
47
+ },
48
+ {
49
+ names: ["dvc"],
50
+ display: "dvc://",
51
+ paths: "dvc://[<device>]",
52
+ purpose: "device registry; `write dvc://<device>` with JSON args RUNS it",
53
+ example: "dvc://ast_grep",
54
+ write: "json-args"
55
+ },
56
+ {
57
+ names: ["http", "https"],
58
+ display: "http(s)://",
59
+ paths: "http(s)://<host>/<path>",
60
+ purpose: "plain fetch",
61
+ example: "https://example.com",
62
+ write: "read-only",
63
+ selector: "exempt — the whole remainder is the path (`:8443` port, `?x=1` query)"
64
+ }
65
+ ];
66
+ /** Every registered scheme token, sorted — the list error messages report. */
67
+ const SCHEME_NAMES = SCHEME_CATALOGUE.flatMap((doc) => doc.names).sort();
68
+ /** The schemes as display tokens (`skill://`, `http(s)://`, …) — prose + error messages. */
69
+ const SCHEME_DISPLAYS = SCHEME_CATALOGUE.map((doc) => doc.display);
70
+ /** Number of schemes with no write channel (every entry except `dvc://`). */
71
+ const READ_ONLY_SCHEME_COUNT = SCHEME_CATALOGUE.filter((doc) => doc.write === "read-only").length;
72
+
73
+ //#endregion
74
+ //#region src/url-schemes/selector.ts
75
+ /** Structured error thrown by the URL-schema layer. */
76
+ var UrlSchemesError = class extends Error {
77
+ code;
78
+ constructor(code, message) {
79
+ super(message);
80
+ this.name = "UrlSchemesError";
81
+ this.code = code;
82
+ }
83
+ };
84
+ /** Matches `scheme://rest` with a lowercase alphanumeric scheme. */
85
+ const SCHEME_RE = /^([a-z][a-z0-9]*):\/\/(.*)$/;
86
+ /** One line range token: `N`, `N-M`, or open `N-`. */
87
+ const RANGE_RE = /^(\d+)(?:-(\d*))?$/;
88
+ /**
89
+ * Schemes whose URL syntax reserves `:` and `?` (ports, query strings): the
90
+ * whole remainder is the path and NO selector is parsed. The http(s) handler
91
+ * is documented as selector-free for exactly this reason — `:8443` is a port
92
+ * and `?q=` a server query, never a line range or content filter.
93
+ */
94
+ const SELECTOR_EXEMPT = {
95
+ http: true,
96
+ https: true
97
+ };
98
+ /**
99
+ * Parse a `scheme://` URL into `{ scheme, path, selector }`.
100
+ *
101
+ * Throws a structured {@link UrlSchemesError} (code `URL_NO_SCHEME`) when the
102
+ * URL has no `scheme://` prefix. Any lowercase scheme is accepted here; the
103
+ * resolver rejects schemes with no registered handler. Selector-exempt
104
+ * schemes ({@link SELECTOR_EXEMPT}) return the whole remainder as the path.
105
+ */
106
+ function parseUrl(raw) {
107
+ const m = SCHEME_RE.exec(raw);
108
+ if (m === null) throw new UrlSchemesError("URL_NO_SCHEME", `URL "${raw}" has no scheme — expected "scheme://" (${SCHEME_DISPLAYS.join(", ")})`);
109
+ const scheme = m[1];
110
+ const rest = m[2];
111
+ if (SELECTOR_EXEMPT[scheme] === true) return {
112
+ scheme,
113
+ path: rest,
114
+ selector: null
115
+ };
116
+ const colon = rest.indexOf(":");
117
+ const question = rest.indexOf("?");
118
+ const hasColon = colon !== -1;
119
+ const hasQuestion = question !== -1;
120
+ if (!hasColon && !hasQuestion) return {
121
+ scheme,
122
+ path: rest,
123
+ selector: null
124
+ };
125
+ const isQuery = hasQuestion && (!hasColon || question < colon);
126
+ const marker = isQuery ? question : colon;
127
+ const path = rest.slice(0, marker);
128
+ const selPart = rest.slice(marker + 1);
129
+ return {
130
+ scheme,
131
+ path,
132
+ selector: isQuery ? {
133
+ kind: "query",
134
+ q: selPart.startsWith("q=") ? selPart.slice(2) : selPart
135
+ } : parseColonSelector(selPart)
136
+ };
137
+ }
138
+ /** `:raw`, composite `:raw:N-M`, `:path/<subpath>`, or a `:N-M` line range list. */
139
+ function parseColonSelector(selPart) {
140
+ if (selPart === "raw") return { kind: "raw" };
141
+ if (selPart.startsWith("raw:")) return {
142
+ kind: "lines",
143
+ ranges: parseRanges(selPart.slice(4))
144
+ };
145
+ if (selPart.startsWith("path/")) return {
146
+ kind: "path",
147
+ value: selPart.slice(5)
148
+ };
149
+ return {
150
+ kind: "lines",
151
+ ranges: parseRanges(selPart)
152
+ };
153
+ }
154
+ /** `N`, `N-M`, `N-`, comma-separated → `[[start, end], ...]` (1-based). */
155
+ function parseRanges(spec) {
156
+ return spec.split(",").map((part) => {
157
+ const token = part.trim();
158
+ const m = RANGE_RE.exec(token);
159
+ if (m === null) throw new UrlSchemesError("URL_BAD_SELECTOR", `invalid line selector ":${spec}" — expected N, N-M, or N-M,N2-M2`);
160
+ const start = Number(m[1]);
161
+ if (start < 1) throw new UrlSchemesError("URL_BAD_SELECTOR", `line numbers are 1-based — got ${start} in ":${spec}"`);
162
+ const end = m[2] === void 0 ? start : m[2] === "" ? Infinity : Number(m[2]);
163
+ if (end !== Infinity && end < start) throw new UrlSchemesError("URL_BAD_SELECTOR", `line range ${start}-${end} is empty — end must be >= start`);
164
+ return [start, end];
165
+ });
166
+ }
167
+ /**
168
+ * Apply a selector to already-resolved text.
169
+ *
170
+ * `null` and `{ kind: 'raw' }` return the text unchanged. `lines` performs a
171
+ * 1-based inclusive slice (open tail via `Infinity`). `path` navigates a JSON
172
+ * sub-resource by dot-path. `query` navigates JSON by dot-path when the text
173
+ * parses as JSON, and otherwise keeps the lines containing the query string.
174
+ */
175
+ function applySelector(text, sel) {
176
+ if (sel === null) return text;
177
+ switch (sel.kind) {
178
+ case "raw": return text;
179
+ case "lines": return applyLines(text, sel.ranges);
180
+ case "path": return applyPath(text, sel.value);
181
+ case "query": return applyQuery(text, sel.q);
182
+ }
183
+ }
184
+ /** 1-based inclusive line slicing; `Infinity` end = open tail. */
185
+ function applyLines(text, ranges) {
186
+ if (ranges.length === 0) return "";
187
+ const lines = text.split("\n");
188
+ const out = [];
189
+ for (const [startRaw, endRaw] of ranges) {
190
+ const start = Math.max(1, startRaw);
191
+ const end = endRaw === Infinity ? lines.length : Math.min(lines.length, endRaw);
192
+ if (start <= end) out.push(...lines.slice(start - 1, end));
193
+ }
194
+ return out.join("\n");
195
+ }
196
+ /** Navigate a JSON sub-resource by dot-path; non-JSON text passes through. */
197
+ function applyPath(text, value) {
198
+ if (value === "") return text;
199
+ const parsed = tryParseJson(text);
200
+ if (parsed === void 0) return text;
201
+ const node = navigate(parsed, value);
202
+ return node === void 0 ? text : stringifyNode(node);
203
+ }
204
+ /** JSON dot-path query when the text is JSON, else a substring line filter. */
205
+ function applyQuery(text, q) {
206
+ if (q === "") return text;
207
+ const parsed = tryParseJson(text);
208
+ if (parsed !== void 0) {
209
+ const node = navigate(parsed, q);
210
+ return node === void 0 ? text.split("\n").filter((line) => line.includes(q)).join("\n") : stringifyNode(node);
211
+ }
212
+ return text.split("\n").filter((line) => line.includes(q)).join("\n");
213
+ }
214
+ function tryParseJson(text) {
215
+ try {
216
+ return JSON.parse(text);
217
+ } catch {
218
+ return;
219
+ }
220
+ }
221
+ /** Walk a dot-path through a parsed JSON value (numeric segments index arrays). */
222
+ function navigate(node, path) {
223
+ let current = node;
224
+ for (const segment of path.split(".")) {
225
+ if (segment === "") return void 0;
226
+ if (Array.isArray(current)) {
227
+ const idx = Number(segment);
228
+ if (!Number.isInteger(idx) || idx < 0) return void 0;
229
+ current = current[idx];
230
+ } else if (current !== null && typeof current === "object") current = current[segment];
231
+ else return;
232
+ }
233
+ return current;
234
+ }
235
+ /** Render a navigated leaf as text. */
236
+ function stringifyNode(node) {
237
+ if (typeof node === "string") return node;
238
+ try {
239
+ return JSON.stringify(node) ?? "";
240
+ } catch {
241
+ return String(node);
242
+ }
243
+ }
244
+
245
+ //#endregion
246
+ //#region src/url-schemes/handlers/dvc.ts
247
+ /** Module-level device registry: insertion-ordered, shared by every handler instance. */
248
+ const devices = /* @__PURE__ */ new Map();
249
+ /** Register (or replace) the device mounted under `name`. */
250
+ function registerDvcDevice(name, device) {
251
+ devices.set(name, device);
252
+ }
253
+ /** Read-only view of the registered devices, in registration order. */
254
+ function listDvcDevices() {
255
+ return devices;
256
+ }
257
+ /**
258
+ * The first path segment is the device name (`dvc://name`, `dvc://name/sub`).
259
+ * A leading `dvc://` is tolerated so callers may pass either the parsed path
260
+ * (the write tool's contract) or the full URL.
261
+ */
262
+ /** Subpath after the device name (`status`, `diagnostics?file=…`), or undefined. */
263
+ function subpathOf(path) {
264
+ const trimmed = (path.startsWith("dvc://") ? path.slice(6) : path).replace(/^\/+/, "");
265
+ const slash = trimmed.indexOf("/");
266
+ if (slash === -1) return void 0;
267
+ const sub = trimmed.slice(slash + 1);
268
+ return sub === "" ? void 0 : sub;
269
+ }
270
+ function deviceNameFromPath(path) {
271
+ const trimmed = (path.startsWith("dvc://") ? path.slice(6) : path).replace(/^\/+/, "");
272
+ const slash = trimmed.indexOf("/");
273
+ return slash === -1 ? trimmed : trimmed.slice(0, slash);
274
+ }
275
+ /** Uniform `unknown`-error rendering for structured error messages. */
276
+ function messageOf(error) {
277
+ return error instanceof Error ? error.message : String(error);
278
+ }
279
+ /**
280
+ * Build the `dvc://` scheme handler over the module-level device registry.
281
+ * Bare `dvc://` yields the roster (`no devices mounted` while empty); a
282
+ * registered `<device>` yields its summary plus a usage hint; an unregistered
283
+ * name keeps the `unknown device` placeholder text.
284
+ */
285
+ function createDvcHandler(_deps = {}) {
286
+ return {
287
+ selectorAware: true,
288
+ async resolve(_env, path, selector) {
289
+ const name = deviceNameFromPath(path);
290
+ if (name === "") {
291
+ if (devices.size === 0) return "no devices mounted";
292
+ return applySelector([...devices].map(([n, device$1]) => `${n}\t${device$1.summary}`).join("\n"), selector ?? null);
293
+ }
294
+ const device = devices.get(name);
295
+ if (device === void 0) return `unknown device: ${name}`;
296
+ const subpath = subpathOf(path);
297
+ if (subpath !== void 0 && device.read !== void 0) {
298
+ const query = selector?.kind === "query" ? `?${selector.q}` : "";
299
+ let text;
300
+ try {
301
+ text = await device.read(`${subpath}${query}`, _env.agent?.id);
302
+ } catch (error) {
303
+ return `Error: ${error instanceof Error ? error.message : String(error)}`;
304
+ }
305
+ return selector !== void 0 && selector !== null && selector.kind !== "query" ? applySelector(text, selector) : text;
306
+ }
307
+ if (subpath !== void 0) return `unknown read path dvc://${name}/${subpath} (device serves doc only)`;
308
+ return applySelector(`${device.summary}\nusage: write dvc://${name} with a JSON args object to execute this device`, selector ?? null);
309
+ }
310
+ };
311
+ }
312
+ /**
313
+ * Write dispatch for `dvc://` URLs — called by the write tool's URL branch.
314
+ * `path` addresses the device (parsed path or full `dvc://` URL); `content`
315
+ * must be the JSON args payload.
316
+ *
317
+ * Routing and args failures (`DVC_NO_DEVICE`, `DVC_UNKNOWN_DEVICE`,
318
+ * `DVC_BAD_ARGS`) throw synchronously — the placeholder wave's observable
319
+ * contract — while a device-reported failure rejects the returned promise as
320
+ * `DVC_DEVICE_ERROR` carrying the device name.
321
+ */
322
+ function dispatchDvcWrite(path, content, session) {
323
+ if (devices.size === 0) throw new UrlSchemesError("DVC_NO_DEVICE", "dvc:// write dispatch: no devices mounted to route the write to");
324
+ const name = deviceNameFromPath(path);
325
+ const device = devices.get(name);
326
+ if (device === void 0) throw new UrlSchemesError("DVC_UNKNOWN_DEVICE", `dvc:// write dispatch: no device named "${name}" (registered: ${[...devices.keys()].sort().join(", ")})`);
327
+ let args;
328
+ try {
329
+ args = JSON.parse(content);
330
+ } catch (error) {
331
+ throw new UrlSchemesError("DVC_BAD_ARGS", `dvc:// write dispatch: device "${name}" requires a JSON args payload (${messageOf(error)})`);
332
+ }
333
+ if (session !== void 0 && args !== null && typeof args === "object" && !Array.isArray(args)) args = { ...args };
334
+ return Promise.resolve().then(() => device.execute(args, { session })).catch((error) => {
335
+ throw new UrlSchemesError("DVC_DEVICE_ERROR", `dvc:// device "${name}" execute failed: ${messageOf(error)}`);
336
+ });
337
+ }
338
+
339
+ //#endregion
340
+ //#region src/url-schemes/docs-dir.ts
341
+ function resolveDocsDir() {
342
+ let dir = dirname(fileURLToPath(import.meta.url));
343
+ for (;;) {
344
+ for (const name of ["dsh-docs", "docs"]) {
345
+ const candidate = join(dir, name);
346
+ try {
347
+ if (statSync(candidate).isDirectory()) return candidate;
348
+ } catch {}
349
+ }
350
+ const parent = dirname(dir);
351
+ if (parent === dir) return void 0;
352
+ dir = parent;
353
+ }
354
+ }
355
+
356
+ //#endregion
357
+ //#region src/url-schemes/resolver.ts
358
+ /** Scheme→handler registry that resolves `scheme://` URLs end-to-end. */
359
+ var UrlResolver = class {
360
+ handlers = /* @__PURE__ */ new Map();
361
+ /** Register (or replace) the handler for `scheme`. */
362
+ register(scheme, handler) {
363
+ this.handlers.set(scheme, handler);
364
+ }
365
+ /**
366
+ * Resolve a `scheme://` URL to its selected text: parse the URL, dispatch
367
+ * to the registered handler for the scheme, then apply the selector.
368
+ *
369
+ * Throws a structured {@link UrlSchemesError} for a scheme-less URL
370
+ * (`URL_NO_SCHEME`, from {@link parseUrl}) or an unregistered scheme
371
+ * (`URL_UNREGISTERED_SCHEME`).
372
+ */
373
+ async resolve(env, url) {
374
+ const parsed = parseUrl(url);
375
+ const handler = this.handlers.get(parsed.scheme);
376
+ if (handler === void 0) {
377
+ const registered = [...this.handlers.keys()].sort().join(", ");
378
+ throw new UrlSchemesError("URL_UNREGISTERED_SCHEME", `no handler registered for scheme "${parsed.scheme}" (registered: ${registered || "none"})`);
379
+ }
380
+ if (handler.selectorAware === true) return handler.resolve(env, parsed.path, parsed.selector);
381
+ return applySelector(await handler.resolve(env, parsed.path), parsed.selector);
382
+ }
383
+ /**
384
+ * Resolve a `scheme://` URL to its on-disk path when its handler is
385
+ * path-backed: parse the URL, dispatch to the handler's optional
386
+ * `resolvePath`, and return the real disk location. Returns `undefined`
387
+ * for an unregistered scheme, a handler without `resolvePath`, or a path
388
+ * the handler cannot map — callers then fall back to text resolution
389
+ * (whose unregistered-scheme error is the structured generic one).
390
+ * Selectors are NOT applied: they operate on resolved text, not paths.
391
+ */
392
+ async resolvePath(env, url) {
393
+ const parsed = parseUrl(url);
394
+ const handler = this.handlers.get(parsed.scheme);
395
+ if (handler?.resolvePath === void 0) return void 0;
396
+ return await handler.resolvePath(env, parsed.path);
397
+ }
398
+ };
399
+
400
+ //#endregion
401
+ //#region src/url-schemes/handlers/dsh.ts
402
+ /** File extensions considered readable harness documentation. */
403
+ const DOC_EXTENSIONS = {
404
+ ".md": true,
405
+ ".markdown": true,
406
+ ".txt": true
407
+ };
408
+ /**
409
+ * Key-name patterns for the defensive secret denylist, matched against a
410
+ * normalized key (lowercased, separators removed). Complements schema-declared
411
+ * `role('secret')` redaction for fields a schema did not mark secret.
412
+ */
413
+ const SECRET_KEY_PATTERNS = [
414
+ /secret/,
415
+ /password/,
416
+ /passwd/,
417
+ /credential/,
418
+ /token/,
419
+ /apikey/,
420
+ /authorization/,
421
+ /privatekey/,
422
+ /accesskey/
423
+ ];
424
+ /** True when a settings field name names credentials/env/API-key material. */
425
+ function isSecretKey(key) {
426
+ const normalized = key.toLowerCase().replace(/[^a-z0-9]/g, "");
427
+ if (normalized === "env" || normalized === "environment") return true;
428
+ return SECRET_KEY_PATTERNS.some((re) => re.test(normalized));
429
+ }
430
+ /** Deep-copy a settings value, dropping every key the denylist names. */
431
+ function stripSecrets(value) {
432
+ if (Array.isArray(value)) return value.map(stripSecrets);
433
+ if (value !== null && typeof value === "object") {
434
+ const out = {};
435
+ for (const [key, item] of Object.entries(value)) {
436
+ if (isSecretKey(key)) continue;
437
+ out[key] = stripSecrets(item);
438
+ }
439
+ return out;
440
+ }
441
+ return value;
442
+ }
443
+ /** True when `name` has a doc extension (case-insensitive). */
444
+ function isDocFile(name) {
445
+ const dot = name.lastIndexOf(".");
446
+ if (dot === -1) return false;
447
+ return DOC_EXTENSIONS[name.slice(dot).toLowerCase()] === true;
448
+ }
449
+ /** Recursive, sorted list of readable doc paths relative to `dir`. */
450
+ async function listDocs(dir) {
451
+ const out = [];
452
+ const entries = await promises.readdir(dir, { withFileTypes: true });
453
+ entries.sort((a, b) => a.name.localeCompare(b.name));
454
+ for (const entry of entries) {
455
+ if (entry.name.startsWith(".")) continue;
456
+ const abs = join(dir, entry.name);
457
+ if (entry.isDirectory()) for (const child of await listDocs(abs)) out.push(join(entry.name, child));
458
+ else if (isDocFile(entry.name)) out.push(entry.name);
459
+ }
460
+ return out;
461
+ }
462
+ /** Read one `<doc>` path inside `dir`, guarding against path traversal. */
463
+ async function readDoc(dir, docPath) {
464
+ const abs = resolve(dir, docPath);
465
+ const rel = relative(dir, abs);
466
+ if (rel === "" || rel === ".." || rel.startsWith(".." + sep) || isAbsolute(rel)) throw new UrlSchemesError("URL_DOC_NOT_FOUND", `dsh://docs/${docPath}: path escapes the docs directory`);
467
+ let stat;
468
+ try {
469
+ stat = await promises.stat(abs);
470
+ } catch {
471
+ throw new UrlSchemesError("URL_DOC_NOT_FOUND", `dsh://docs/${docPath}: document not found`);
472
+ }
473
+ if (stat.isDirectory()) return JSON.stringify(await listDocs(abs), null, 2);
474
+ if (stat.isFile()) return await promises.readFile(abs, "utf8");
475
+ throw new UrlSchemesError("URL_DOC_NOT_FOUND", `dsh://docs/${docPath}: not a regular file`);
476
+ }
477
+ /** Create the `dsh://` scheme handler, capturing `deps` by closure. */
478
+ function createDshHandler(deps) {
479
+ const { settings, docsDir } = deps;
480
+ let docsDirPromise;
481
+ function findDocsDir() {
482
+ if (docsDirPromise === void 0) docsDirPromise = (async () => {
483
+ const candidates = [];
484
+ if (docsDir !== void 0) candidates.push(docsDir);
485
+ const pkgRoot = dirname(dirname(dirname(dirname(fileURLToPath(import.meta.url)))));
486
+ candidates.push(join(pkgRoot, "dsh-docs"), join(pkgRoot, "docs"), join(pkgRoot, "..", "docs"));
487
+ for (const dir of candidates) try {
488
+ if ((await promises.stat(dir)).isDirectory()) return dir;
489
+ } catch {}
490
+ })();
491
+ return docsDirPromise;
492
+ }
493
+ /**
494
+ * Path-backed view: `docs` and `docs/<sub>` map into the real docs tree, so
495
+ * the URL-aware `grep`/`glob` can hand the native tools a disk path instead
496
+ * of materializing the listing text. `config` is content-backed (resolved
497
+ * settings JSON) — never path-backed.
498
+ */
499
+ async function resolvePathDisk(path) {
500
+ if (path !== "docs" && !path.startsWith("docs/")) return void 0;
501
+ const dir = await findDocsDir();
502
+ if (dir === void 0) return void 0;
503
+ const abs = path === "docs" ? dir : join(dir, path.slice(5));
504
+ try {
505
+ await promises.stat(abs);
506
+ return abs;
507
+ } catch {
508
+ return;
509
+ }
510
+ }
511
+ return {
512
+ async resolvePath(_env, path) {
513
+ return resolvePathDisk(path);
514
+ },
515
+ async resolve(_env, path) {
516
+ const [root, ...rest] = path.split("/");
517
+ const restPath = rest.join("/");
518
+ if (root === "docs") {
519
+ const dir = await findDocsDir();
520
+ if (dir === void 0) throw new UrlSchemesError("URL_DOCS_UNAVAILABLE", "dsh://docs: no docs directory found (provide `docsDir` to createDshHandler)");
521
+ if (restPath === "") return JSON.stringify(await listDocs(dir), null, 2);
522
+ return await readDoc(dir, restPath);
523
+ }
524
+ if (root === "config") {
525
+ if (settings === void 0) throw new UrlSchemesError("URL_SETTINGS_UNAVAILABLE", "dsh://config: no ctx.settings service is mounted");
526
+ const descriptors = settings.describe({ redactSecrets: true });
527
+ if (restPath === "") {
528
+ const out = {};
529
+ for (const descriptor of descriptors) out[String(descriptor.ns)] = stripSecrets(descriptor.value);
530
+ return JSON.stringify(out, null, 2);
531
+ }
532
+ const found = descriptors.find((descriptor) => String(descriptor.ns) === restPath);
533
+ if (found === void 0) throw new UrlSchemesError("URL_UNKNOWN_SETTINGS_NAMESPACE", `dsh://config/${restPath}: unknown settings namespace`);
534
+ return JSON.stringify(stripSecrets(found.value), null, 2);
535
+ }
536
+ throw new UrlSchemesError("URL_UNKNOWN_RESOURCE", `dsh://: unknown resource "${root || "(empty)"}" — expected "docs" or "config"`);
537
+ }
538
+ };
539
+ }
540
+
541
+ //#endregion
542
+ //#region src/url-schemes/handlers/http.ts
543
+ /** The schemes one handler instance serves; register it under each of these. */
544
+ const HTTP_SCHEMES = ["http", "https"];
545
+ /** Hard cap on a fetched body: 2 MiB. */
546
+ const MAX_BODY_BYTES = 2 * 1024 * 1024;
547
+ /** Abort the GET after this many milliseconds. */
548
+ const TIMEOUT_MS = 2e4;
549
+ /** First line of every resolved http(s) URL: flags plain-fetch semantics. */
550
+ const DISCLAIMER = "[url-fetch] plain-text result of a direct HTTP GET (curl-equivalent). No JS execution or interaction — use browser tools, if any, for that.";
551
+ /** `application/` MIME types treated as text (any `text/*` also is). */
552
+ const APPLICATION_TEXT_TYPES = {
553
+ "application/json": true,
554
+ "application/xml": true,
555
+ "application/yaml": true,
556
+ "application/toml": true,
557
+ "application/xhtml+xml": true,
558
+ "application/javascript": true,
559
+ "application/plain": true
560
+ };
561
+ /** Strict whitelist: `text/*` or a known textual `application/*` MIME. A
562
+ * missing header fails the check — binary decoding is never guessed. */
563
+ function isTextContentType(headerValue) {
564
+ if (headerValue === null) return false;
565
+ const mime = headerValue.split(";", 1)[0].trim().toLowerCase();
566
+ return mime.startsWith("text/") || mime in APPLICATION_TEXT_TYPES;
567
+ }
568
+ /** Best-effort `err.cause` message — undici nests DNS/socket failures there. */
569
+ function causeMessageOf(err) {
570
+ const cause = err?.cause;
571
+ if (cause instanceof Error) return cause.message;
572
+ if (typeof cause === "string" && cause !== "") return cause;
573
+ return null;
574
+ }
575
+ /** Stream the body as UTF-8 text, throwing past the 2 MiB byte cap. */
576
+ async function readBodyCapped(body, href) {
577
+ const reader = body.getReader();
578
+ const decoder = new TextDecoder();
579
+ let received = 0;
580
+ let text = "";
581
+ try {
582
+ for (;;) {
583
+ const { done, value } = await reader.read().catch((err) => {
584
+ if (err instanceof Error && err.name === "AbortError") throw new UrlSchemesError("URL_HTTP_TIMEOUT", `HTTP GET ${href} aborted after the ${TIMEOUT_MS / 1e3} s deadline`);
585
+ throw err;
586
+ });
587
+ if (done) break;
588
+ received += value.byteLength;
589
+ if (received > MAX_BODY_BYTES) throw new UrlSchemesError("URL_HTTP_TOO_LARGE", `body of ${href} exceeded the ${MAX_BODY_BYTES}-byte (2 MiB) text limit after ${received} bytes`);
590
+ text += decoder.decode(value, { stream: true });
591
+ }
592
+ return text + decoder.decode();
593
+ } finally {
594
+ await reader.cancel().catch(() => {});
595
+ }
596
+ }
597
+ /** One capped, whitelisted GET of `url`; returns the decoded body text. */
598
+ async function getUrl(url) {
599
+ const controller = new AbortController();
600
+ let timedOut = false;
601
+ const timer = setTimeout(() => {
602
+ timedOut = true;
603
+ controller.abort();
604
+ }, TIMEOUT_MS);
605
+ try {
606
+ let response;
607
+ try {
608
+ response = await fetch(url, {
609
+ method: "GET",
610
+ redirect: "follow",
611
+ signal: controller.signal
612
+ });
613
+ } catch (err) {
614
+ if (timedOut || err instanceof Error && err.name === "AbortError") throw new UrlSchemesError("URL_HTTP_TIMEOUT", `HTTP GET ${url.href} aborted after the ${TIMEOUT_MS / 1e3} s deadline`);
615
+ const cause = causeMessageOf(err);
616
+ const message = err instanceof Error ? err.message : String(err);
617
+ throw new UrlSchemesError("URL_HTTP_FETCH_FAILED", `HTTP GET ${url.href} failed: ${message}${cause === null ? "" : ` (${cause})`}`);
618
+ }
619
+ if (!response.ok) {
620
+ const statusText = response.statusText === "" ? "" : ` ${response.statusText}`;
621
+ throw new UrlSchemesError("URL_HTTP_STATUS", `HTTP GET ${url.href} returned ${response.status}${statusText}`);
622
+ }
623
+ const declared = response.headers.get("content-length");
624
+ if (declared !== null) {
625
+ const bytes = Number(declared);
626
+ if (Number.isFinite(bytes) && bytes > MAX_BODY_BYTES) throw new UrlSchemesError("URL_HTTP_TOO_LARGE", `body of ${url.href} is ${bytes} bytes, over the ${MAX_BODY_BYTES}-byte (2 MiB) text limit`);
627
+ }
628
+ const contentType = response.headers.get("content-type");
629
+ if (!isTextContentType(contentType)) throw new UrlSchemesError("URL_HTTP_UNSUPPORTED_MEDIA", `content-type of ${url.href} is "${contentType ?? "(none)"}", outside the text whitelist (text/* or application/{json,xml,yaml,toml,xhtml+xml,javascript,plain}) — binary decoding is deliberately not guessed`);
630
+ if (response.body === null) {
631
+ const text = await response.text();
632
+ const bytes = Buffer.byteLength(text, "utf8");
633
+ if (bytes > MAX_BODY_BYTES) throw new UrlSchemesError("URL_HTTP_TOO_LARGE", `body of ${url.href} is ${bytes} bytes, over the ${MAX_BODY_BYTES}-byte (2 MiB) text limit`);
634
+ return text;
635
+ }
636
+ return await readBodyCapped(response.body, url.href);
637
+ } finally {
638
+ clearTimeout(timer);
639
+ }
640
+ }
641
+ /**
642
+ * Build the `http://`/`https://` handler. Register the returned instance
643
+ * under BOTH schemes ({@link HTTP_SCHEMES}); it is stateless and safe to
644
+ * share.
645
+ */
646
+ function createHttpHandler() {
647
+ return { async resolve(env, path) {
648
+ const raw = env.rawUrl ?? `https://${path}`;
649
+ let url;
650
+ try {
651
+ url = new URL(raw);
652
+ } catch (err) {
653
+ throw new UrlSchemesError("URL_INVALID", `invalid http(s) URL "${raw}": ${err instanceof Error ? err.message : String(err)}`);
654
+ }
655
+ if (url.protocol !== "http:" && url.protocol !== "https:") throw new UrlSchemesError("URL_INVALID", `not an http(s) URL: "${raw}"`);
656
+ return `${DISCLAIMER}\n\n${await getUrl(url)}`;
657
+ } };
658
+ }
659
+
660
+ //#endregion
661
+ //#region src/fs-aware/wrap.ts
662
+ const WRAPPED = Symbol("dsh-url-schemes.fs-wrap");
663
+ function isSchemePath(path) {
664
+ return typeof path === "string" && /^[a-z][a-z0-9]*:\/\//.test(path);
665
+ }
666
+ function isSessionLayerScheme(path) {
667
+ return path.startsWith("ctx://") || path.startsWith("agent://") || path.startsWith("skill://");
668
+ }
669
+ function sessionLayerError(url) {
670
+ if (url.startsWith("skill://")) return new UrlSchemesError("CTX_SESSION_LAYER", `${url}: session-layer scheme — skill discovery (which roots load, scan depth, layered scope merge) is the host skill provider's business logic and resolves only against a calling agent, which the filesystem layer does not have. Load skills with the native \`skill\` tool; grep/glob with path=skill://… keep working through the tool layer`);
671
+ return new UrlSchemesError("CTX_SESSION_LAYER", `${url}: session-layer scheme — read it through the read tool (the session-layer resolver environment carries the live agent this filesystem layer does not have)`);
672
+ }
673
+ /** Build the FS-layer resolver: file-type schemes only (design D2). */
674
+ function buildFsLayerResolver(services, fsSelf) {
675
+ const resolver = new UrlResolver();
676
+ resolver.register("dsh", createDshHandler({
677
+ settings: services.settings,
678
+ docsDir: resolveDocsDir()
679
+ }));
680
+ resolver.register("dvc", createDvcHandler());
681
+ for (const scheme of HTTP_SCHEMES) resolver.register(scheme, createHttpHandler());
682
+ resolver.register("ctx", { async resolve(_env, path) {
683
+ throw sessionLayerError(`ctx://${path}`);
684
+ } });
685
+ resolver.register("agent", { async resolve(_env, path) {
686
+ throw sessionLayerError(`agent://${path}`);
687
+ } });
688
+ return resolver;
689
+ }
690
+ /**
691
+ * Wrap the mounted `ctx.fs` instance in place. Idempotent via a symbol flag.
692
+ * Returns the resolver used for scheme dereferencing (for diagnostics).
693
+ */
694
+ function wrapFsWithSchemes(fs, services) {
695
+ const holder = fs;
696
+ if (holder[WRAPPED] !== void 0) return holder[WRAPPED];
697
+ const resolver = buildFsLayerResolver(services, fs);
698
+ const envFor = (url) => ({
699
+ fs,
700
+ rawUrl: url
701
+ });
702
+ const bind = (fn) => typeof fn === "function" ? fn.bind(fs) : void 0;
703
+ const origResolve = bind(fs.resolve);
704
+ const origStat = bind(fs.stat);
705
+ const origReadText = bind(fs.readText);
706
+ const origWriteText = bind(fs.writeText);
707
+ const origEditText = bind(fs.editText);
708
+ const requireOrig = (orig, method) => {
709
+ if (orig === void 0) throw new UrlSchemesError("FS_BASE_UNSUPPORTED", `the mounted filesystem service exposes no "${method}" — scheme wrap is active but the base backend cannot serve real paths`);
710
+ return orig;
711
+ };
712
+ fs.resolve = async (path, opts) => {
713
+ if (!isSchemePath(path)) return requireOrig(origResolve, "resolve")(path, opts);
714
+ if (isSessionLayerScheme(path)) throw sessionLayerError(path);
715
+ await resolver.resolve(envFor(path), path);
716
+ return {
717
+ targetKey: path,
718
+ displayPath: path
719
+ };
720
+ };
721
+ fs.stat = async (target, signal) => {
722
+ if (!isSchemePath(target.targetKey)) return requireOrig(origStat, "stat")(target, signal);
723
+ if (isSessionLayerScheme(target.targetKey)) throw sessionLayerError(target.targetKey);
724
+ return {
725
+ type: "file",
726
+ size: (await resolver.resolve(envFor(target.targetKey), target.targetKey)).length
727
+ };
728
+ };
729
+ fs.readText = async (target, signal) => {
730
+ if (!isSchemePath(target.targetKey)) return requireOrig(origReadText, "readText")(target, signal);
731
+ if (isSessionLayerScheme(target.targetKey)) throw sessionLayerError(target.targetKey);
732
+ return resolver.resolve(envFor(target.targetKey), target.targetKey);
733
+ };
734
+ fs.writeText = async (target, ...rest) => {
735
+ if (isSchemePath(target.targetKey)) throw new UrlSchemesError("FS_VIRTUAL_READONLY", `cannot write "${target.targetKey}": scheme resources are read-only at the filesystem layer`);
736
+ return requireOrig(origWriteText, "writeText")(target, ...rest);
737
+ };
738
+ fs.editText = async (target, ...rest) => {
739
+ if (isSchemePath(target.targetKey)) throw new UrlSchemesError("FS_VIRTUAL_READONLY", `cannot edit "${target.targetKey}": scheme resources are read-only at the filesystem layer`);
740
+ return requireOrig(origEditText, "editText")(target, ...rest);
741
+ };
742
+ holder[WRAPPED] = resolver;
743
+ return resolver;
744
+ }
745
+
746
+ //#endregion
747
+ export { createDshHandler as a, createDvcHandler as c, registerDvcDevice as d, UrlSchemesError as f, createHttpHandler as i, dispatchDvcWrite as l, SCHEME_NAMES as m, wrapFsWithSchemes as n, UrlResolver as o, parseUrl as p, HTTP_SCHEMES as r, resolveDocsDir as s, buildFsLayerResolver as t, listDvcDevices as u };