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.
- package/cordis.patch.yml +1 -1
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- package/docs/50_test-reports/upstream-dsh-0.1.3-alpha.2-local-test-report.md +44 -0
- package/docs/50_test-reports/upstream-dsh-0.1.3-alpha.2-report.md +110 -0
- package/docs/50_test-reports/upstream-dsh-0.1.5-rc.2-local-test-report.md +79 -0
- 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
- 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
- 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
- package/docs/specs/agent/spec.md +54 -0
- package/docs/specs/ast/spec.md +34 -0
- package/docs/specs/compaction-recall/spec.md +46 -0
- package/docs/specs/ctx/spec.md +107 -0
- package/docs/specs/dsh/spec.md +47 -0
- package/docs/specs/dvc/spec.md +87 -0
- package/docs/specs/escalation-guidance/spec.md +44 -0
- package/docs/specs/fs-scheme-resolution/spec.md +37 -0
- package/docs/specs/hash-edit/spec.md +41 -0
- package/docs/specs/http-read/spec.md +73 -0
- package/docs/specs/kernel-provisioning/spec.md +53 -0
- package/docs/specs/lsp/spec.md +121 -0
- package/docs/specs/mobile-layout/spec.md +108 -0
- package/docs/specs/model-failover/spec.md +20 -0
- package/docs/specs/preact-ui-shell/spec.md +22 -0
- package/docs/specs/repl-dispatch-resilience/spec.md +21 -0
- package/docs/specs/skill/spec.md +58 -0
- package/docs/specs/tool-surface/spec.md +222 -0
- package/docs/specs/url-schema/spec.md +148 -0
- package/docs/specs/web-trust-fence/spec.md +43 -0
- package/docs/upstream-dsh-0.1.5-rc.2-report.md +156 -0
- package/dsh-docs/AGENTS.md +75 -0
- package/dsh-docs/agent-lifecycle.md +84 -0
- package/dsh-docs/agent-lifecycle.zh.md +86 -0
- package/dsh-docs/api-gateway.md +164 -0
- package/dsh-docs/api-gateway.zh.md +164 -0
- package/dsh-docs/architecture.md +150 -0
- package/dsh-docs/architecture.zh.md +154 -0
- package/dsh-docs/capability-seams.md +543 -0
- package/dsh-docs/capability-seams.zh.md +545 -0
- package/dsh-docs/config-catalog.md +3473 -0
- package/dsh-docs/config-catalog.zh.md +3474 -0
- package/dsh-docs/cookbook/adding-a-package.md +117 -0
- package/dsh-docs/cookbook/adding-a-package.zh.md +119 -0
- package/dsh-docs/cookbook/adding-a-remote-api.md +197 -0
- package/dsh-docs/cookbook/adding-a-remote-api.zh.md +197 -0
- package/dsh-docs/cookbook/adding-a-session-format-version.md +109 -0
- package/dsh-docs/cookbook/adding-a-session-format-version.zh.md +109 -0
- package/dsh-docs/cookbook/adding-a-settings-card.md +102 -0
- package/dsh-docs/cookbook/adding-a-settings-card.zh.md +102 -0
- package/dsh-docs/cookbook/adding-a-tool.md +101 -0
- package/dsh-docs/cookbook/adding-a-tool.zh.md +103 -0
- package/dsh-docs/cookbook/adding-a-vendored-package.md +59 -0
- package/dsh-docs/cookbook/adding-a-vendored-package.zh.md +59 -0
- package/dsh-docs/cookbook/adding-an-llm-adapter.md +43 -0
- package/dsh-docs/cookbook/adding-an-llm-adapter.zh.md +43 -0
- package/dsh-docs/cookbook/extension-cookbook.md +132 -0
- package/dsh-docs/cookbook/extension-cookbook.zh.md +136 -0
- package/dsh-docs/cookbook/maintaining-dsh-code-review.md +64 -0
- package/dsh-docs/cookbook/maintaining-dsh-code-review.zh.md +64 -0
- package/dsh-docs/cookbook/responding-to-pr-review-on-a-stack.md +32 -0
- package/dsh-docs/cookbook/responding-to-pr-review-on-a-stack.zh.md +32 -0
- package/dsh-docs/cordis-api/context.md +364 -0
- package/dsh-docs/cordis-api/context.zh.md +366 -0
- package/dsh-docs/cordis-api/events.md +207 -0
- package/dsh-docs/cordis-api/events.zh.md +209 -0
- package/dsh-docs/cordis-api/fiber.md +375 -0
- package/dsh-docs/cordis-api/fiber.zh.md +377 -0
- package/dsh-docs/cordis-api/inherited.md +39 -0
- package/dsh-docs/cordis-api/registry.md +152 -0
- package/dsh-docs/cordis-api/registry.zh.md +154 -0
- package/dsh-docs/cordis-api/service.md +102 -0
- package/dsh-docs/cordis-api/service.zh.md +104 -0
- package/dsh-docs/cordis-primer.md +45 -0
- package/dsh-docs/cordis-primer.zh.md +51 -0
- package/dsh-docs/cordis-tutorial/01-first-plugin.md +95 -0
- package/dsh-docs/cordis-tutorial/01-first-plugin.zh.md +95 -0
- package/dsh-docs/cordis-tutorial/02-lifecycle-and-effects.md +98 -0
- package/dsh-docs/cordis-tutorial/02-lifecycle-and-effects.zh.md +98 -0
- package/dsh-docs/cordis-tutorial/03-services.md +98 -0
- package/dsh-docs/cordis-tutorial/03-services.zh.md +98 -0
- package/dsh-docs/cordis-tutorial/04-events.md +144 -0
- package/dsh-docs/cordis-tutorial/04-events.zh.md +144 -0
- package/dsh-docs/cordis-tutorial/05-config.md +84 -0
- package/dsh-docs/cordis-tutorial/05-config.zh.md +84 -0
- package/dsh-docs/cordis-tutorial/06-composition-and-hmr.md +113 -0
- package/dsh-docs/cordis-tutorial/06-composition-and-hmr.zh.md +113 -0
- package/dsh-docs/cordis-tutorial/07-into-the-harness.md +108 -0
- package/dsh-docs/cordis-tutorial/07-into-the-harness.zh.md +108 -0
- package/dsh-docs/cordis-tutorial/index.md +60 -0
- package/dsh-docs/cordis-tutorial/index.zh.md +62 -0
- package/dsh-docs/deepseek-llm-api-wire-extensions.md +163 -0
- package/dsh-docs/deepseek-llm-api-wire-extensions.zh.md +163 -0
- package/dsh-docs/defensive-patterns.md +33 -0
- package/dsh-docs/defensive-patterns.zh.md +35 -0
- package/dsh-docs/development.md +167 -0
- package/dsh-docs/development.zh.md +173 -0
- package/dsh-docs/event-producer-consumer.md +86 -0
- package/dsh-docs/event-producer-consumer.zh.md +88 -0
- package/dsh-docs/glossary.md +45 -0
- package/dsh-docs/glossary.zh.md +45 -0
- package/dsh-docs/graph-atlas.md +22 -0
- package/dsh-docs/graph-atlas.zh.md +24 -0
- package/dsh-docs/i18n/README.md +60 -0
- package/dsh-docs/i18n/README.zh.md +62 -0
- package/dsh-docs/i18n/style-samples.md +87 -0
- package/dsh-docs/i18n/terminology.md +214 -0
- package/dsh-docs/i18n/translation-prompt.md +263 -0
- package/dsh-docs/i18n/translation-rules.md +69 -0
- package/dsh-docs/i18n/translation-rules.zh.md +69 -0
- package/dsh-docs/module-graph.md +1411 -0
- package/dsh-docs/module-graph.zh.md +1413 -0
- package/dsh-docs/persistence-catalog.md +1075 -0
- package/dsh-docs/persistence-catalog.zh.md +1077 -0
- package/dsh-docs/postmortem/0001-acp-default-export-drops-inject.md +113 -0
- package/dsh-docs/postmortem/0001-acp-default-export-drops-inject.zh.md +113 -0
- package/dsh-docs/postmortem/0002-js-expression-disabled-filesystem-tools.md +47 -0
- package/dsh-docs/postmortem/0002-js-expression-disabled-filesystem-tools.zh.md +47 -0
- package/dsh-docs/postmortem/0003-web-agent-gui-feedback-loop.md +53 -0
- package/dsh-docs/postmortem/0003-web-agent-gui-feedback-loop.zh.md +53 -0
- package/dsh-docs/postmortem/0004-landlock-partial-notice-misclassified-child-failures.md +55 -0
- package/dsh-docs/postmortem/0004-landlock-partial-notice-misclassified-child-failures.zh.md +55 -0
- package/dsh-docs/postmortem/README.md +18 -0
- package/dsh-docs/postmortem/README.zh.md +18 -0
- package/dsh-docs/rescope.md +53 -0
- package/dsh-docs/rescope.zh.md +53 -0
- package/dsh-docs/session-format-status.md +47 -0
- package/dsh-docs/session-format-status.zh.md +47 -0
- package/dsh-docs/subsystems/README.md +61 -0
- package/dsh-docs/subsystems/README.zh.md +61 -0
- package/dsh-docs/subsystems/agent-team.md +207 -0
- package/dsh-docs/subsystems/agent-team.zh.md +207 -0
- package/dsh-docs/subsystems/approval.md +170 -0
- package/dsh-docs/subsystems/approval.zh.md +170 -0
- package/dsh-docs/subsystems/attachment.md +351 -0
- package/dsh-docs/subsystems/attachment.zh.md +351 -0
- package/dsh-docs/subsystems/client-modules.md +168 -0
- package/dsh-docs/subsystems/client-modules.zh.md +168 -0
- package/dsh-docs/subsystems/client-resources.md +91 -0
- package/dsh-docs/subsystems/client-resources.zh.md +91 -0
- package/dsh-docs/subsystems/code-runtime.md +195 -0
- package/dsh-docs/subsystems/code-runtime.zh.md +195 -0
- package/dsh-docs/subsystems/commands.md +219 -0
- package/dsh-docs/subsystems/commands.zh.md +219 -0
- package/dsh-docs/subsystems/compaction.md +238 -0
- package/dsh-docs/subsystems/compaction.zh.md +238 -0
- package/dsh-docs/subsystems/conversation.md +258 -0
- package/dsh-docs/subsystems/conversation.zh.md +258 -0
- package/dsh-docs/subsystems/core.md +1209 -0
- package/dsh-docs/subsystems/core.zh.md +1219 -0
- package/dsh-docs/subsystems/credentials.md +329 -0
- package/dsh-docs/subsystems/credentials.zh.md +329 -0
- package/dsh-docs/subsystems/extensions.md +382 -0
- package/dsh-docs/subsystems/extensions.zh.md +382 -0
- package/dsh-docs/subsystems/feedback.md +266 -0
- package/dsh-docs/subsystems/feedback.zh.md +266 -0
- package/dsh-docs/subsystems/filesystem.md +505 -0
- package/dsh-docs/subsystems/filesystem.zh.md +505 -0
- package/dsh-docs/subsystems/goal.md +277 -0
- package/dsh-docs/subsystems/goal.zh.md +277 -0
- package/dsh-docs/subsystems/invariants.md +88 -0
- package/dsh-docs/subsystems/invariants.zh.md +88 -0
- package/dsh-docs/subsystems/jobs.md +290 -0
- package/dsh-docs/subsystems/jobs.zh.md +290 -0
- package/dsh-docs/subsystems/llm-streaming.md +1080 -0
- package/dsh-docs/subsystems/llm-streaming.zh.md +1086 -0
- package/dsh-docs/subsystems/lsp.md +202 -0
- package/dsh-docs/subsystems/lsp.zh.md +202 -0
- package/dsh-docs/subsystems/permission-presets.md +131 -0
- package/dsh-docs/subsystems/permission-presets.zh.md +131 -0
- package/dsh-docs/subsystems/persistence.md +395 -0
- package/dsh-docs/subsystems/persistence.zh.md +395 -0
- package/dsh-docs/subsystems/plan.md +87 -0
- package/dsh-docs/subsystems/plan.zh.md +87 -0
- package/dsh-docs/subsystems/sandbox.md +220 -0
- package/dsh-docs/subsystems/sandbox.zh.md +220 -0
- package/dsh-docs/subsystems/schedule.md +192 -0
- package/dsh-docs/subsystems/schedule.zh.md +192 -0
- package/dsh-docs/subsystems/scope.md +59 -0
- package/dsh-docs/subsystems/scope.zh.md +59 -0
- package/dsh-docs/subsystems/session-projection.md +354 -0
- package/dsh-docs/subsystems/session-projection.zh.md +354 -0
- package/dsh-docs/subsystems/session-query.md +509 -0
- package/dsh-docs/subsystems/session-query.zh.md +509 -0
- package/dsh-docs/subsystems/session-reference.md +219 -0
- package/dsh-docs/subsystems/session-reference.zh.md +219 -0
- package/dsh-docs/subsystems/session-telemetry.md +194 -0
- package/dsh-docs/subsystems/session-telemetry.zh.md +194 -0
- package/dsh-docs/subsystems/session-title.md +204 -0
- package/dsh-docs/subsystems/session-title.zh.md +204 -0
- package/dsh-docs/subsystems/session.md +1155 -0
- package/dsh-docs/subsystems/session.zh.md +1159 -0
- package/dsh-docs/subsystems/settings.md +405 -0
- package/dsh-docs/subsystems/settings.zh.md +405 -0
- package/dsh-docs/subsystems/shell.md +303 -0
- package/dsh-docs/subsystems/shell.zh.md +303 -0
- package/dsh-docs/subsystems/sidebar-right.md +148 -0
- package/dsh-docs/subsystems/sidebar-right.zh.md +148 -0
- package/dsh-docs/subsystems/skills.md +354 -0
- package/dsh-docs/subsystems/skills.zh.md +354 -0
- package/dsh-docs/subsystems/slots.md +175 -0
- package/dsh-docs/subsystems/slots.zh.md +175 -0
- package/dsh-docs/subsystems/spill.md +117 -0
- package/dsh-docs/subsystems/spill.zh.md +117 -0
- package/dsh-docs/subsystems/storage.md +260 -0
- package/dsh-docs/subsystems/storage.zh.md +260 -0
- package/dsh-docs/subsystems/subagent.md +766 -0
- package/dsh-docs/subsystems/subagent.zh.md +770 -0
- package/dsh-docs/subsystems/subprocess.md +324 -0
- package/dsh-docs/subsystems/subprocess.zh.md +324 -0
- package/dsh-docs/subsystems/system-prompt.md +220 -0
- package/dsh-docs/subsystems/system-prompt.zh.md +220 -0
- package/dsh-docs/subsystems/terminal.md +184 -0
- package/dsh-docs/subsystems/terminal.zh.md +184 -0
- package/dsh-docs/subsystems/todo.md +32 -0
- package/dsh-docs/subsystems/todo.zh.md +32 -0
- package/dsh-docs/subsystems/token-meter.md +105 -0
- package/dsh-docs/subsystems/token-meter.zh.md +105 -0
- package/dsh-docs/subsystems/tools.md +720 -0
- package/dsh-docs/subsystems/tools.zh.md +720 -0
- package/dsh-docs/subsystems/typert.md +343 -0
- package/dsh-docs/subsystems/typert.zh.md +343 -0
- package/dsh-docs/subsystems/user-questions.md +178 -0
- package/dsh-docs/subsystems/user-questions.zh.md +178 -0
- package/dsh-docs/subsystems/web-client.md +95 -0
- package/dsh-docs/subsystems/web-client.zh.md +95 -0
- package/dsh-docs/subsystems/web-server.md +154 -0
- package/dsh-docs/subsystems/web-server.zh.md +154 -0
- package/dsh-docs/subsystems/web.md +206 -0
- package/dsh-docs/subsystems/web.zh.md +206 -0
- package/dsh-docs/subsystems/webhook.md +70 -0
- package/dsh-docs/subsystems/webhook.zh.md +70 -0
- package/dsh-docs/subsystems/workflow.md +278 -0
- package/dsh-docs/subsystems/workflow.zh.md +278 -0
- package/dsh-docs/subsystems/workspace.md +321 -0
- package/dsh-docs/subsystems/workspace.zh.md +321 -0
- package/dsh-docs/testing.md +54 -0
- package/dsh-docs/testing.zh.md +54 -0
- package/dsh-docs/tool-catalog.md +2225 -0
- package/dsh-docs/tool-catalog.zh.md +2233 -0
- package/dsh-docs/tool-execution-pipeline.md +62 -0
- package/dsh-docs/tool-execution-pipeline.zh.md +64 -0
- package/dsh-docs/user/develop/basic/config.md +106 -0
- package/dsh-docs/user/develop/basic/config.zh.md +106 -0
- package/dsh-docs/user/develop/basic/index.md +144 -0
- package/dsh-docs/user/develop/basic/index.zh.md +144 -0
- package/dsh-docs/user/develop/basic/publish.md +183 -0
- package/dsh-docs/user/develop/basic/publish.zh.md +183 -0
- package/dsh-docs/user/develop/basic/tool.md +52 -0
- package/dsh-docs/user/develop/basic/tool.zh.md +52 -0
- package/dsh-docs/user/develop/framework/events.md +143 -0
- package/dsh-docs/user/develop/framework/events.zh.md +143 -0
- package/dsh-docs/user/develop/framework/index.md +137 -0
- package/dsh-docs/user/develop/framework/index.zh.md +137 -0
- package/dsh-docs/user/develop/framework/service.md +148 -0
- package/dsh-docs/user/develop/framework/service.zh.md +150 -0
- package/dsh-docs/user/develop/practice/dynamic-cordis.md +15 -0
- package/dsh-docs/user/develop/practice/dynamic-cordis.zh.md +15 -0
- package/dsh-docs/user/develop/practice/index.md +155 -0
- package/dsh-docs/user/develop/practice/index.zh.md +155 -0
- package/dsh-docs/user/develop/practice/llm-adapter.md +189 -0
- package/dsh-docs/user/develop/practice/llm-adapter.zh.md +189 -0
- package/dsh-docs/user/guide/github-review.md +102 -0
- package/dsh-docs/user/guide/github-review.zh.md +102 -0
- package/dsh-docs/user/guide/index.md +30 -0
- package/dsh-docs/user/guide/index.zh.md +30 -0
- package/dsh-docs/user/guide/mcp-memory.md +101 -0
- package/dsh-docs/user/guide/mcp-memory.zh.md +101 -0
- package/dsh-docs/user/guide/network-proxy.md +85 -0
- package/dsh-docs/user/guide/network-proxy.zh.md +85 -0
- package/dsh-docs/user/guide/providers.md +190 -0
- package/dsh-docs/user/guide/providers.zh.md +190 -0
- package/dsh-docs/user/guide/python-sdk.md +150 -0
- package/dsh-docs/user/guide/python-sdk.zh.md +150 -0
- package/dsh-docs/user/guide/schedule.md +21 -0
- package/dsh-docs/user/guide/schedule.zh.md +21 -0
- package/dsh-docs/user/index.md +11 -0
- package/dsh-docs/user/index.zh.md +11 -0
- package/dsh-docs/web-styling.md +29 -0
- package/dsh-docs/web-styling.zh.md +29 -0
- package/eval-description.md +33 -0
- package/lib/client/index.js +327 -88
- package/lib/fs-aware/sandbox-plugin.d.ts +71 -0
- package/lib/fs-aware/sandbox-plugin.js +249 -0
- package/lib/index.d.ts +22 -22
- package/lib/index.js +3095 -3204
- package/lib/lsp-server-registry-DkaYmTwt.js +972 -0
- package/lib/lsp-server-registry-_hk-Wcia.js +3 -0
- package/lib/py-sdk-Chvy92MB.js +178 -0
- package/lib/py-sdk.d.ts +19 -2
- package/lib/py-sdk.js +2 -2
- package/lib/wrap-JFjcWwZf.js +747 -0
- package/package.json +9 -3
- package/url-schemes-instruction.md +22 -0
- package/control-prompt.md +0 -37
- package/docs/50_test-reports/v0.1.8d_artifacts/README.md +0 -138
- package/docs/50_test-reports/v0.1.8d_artifacts/code-mode-repl-only.observation.md +0 -74
- package/docs/50_test-reports/v0.1.8d_artifacts/dsh-session-session-4a293388-9ae1-474b-87a0-9e17bb556d94.jsonl +0 -3890
- package/docs/50_test-reports/v0.1.8d_artifacts/dsh-session-session-4a293388-9ae1-474b-87a0-9e17bb556d94.w-sample-0435.jsonl +0 -544
- package/docs/50_test-reports/v0.1.8d_artifacts/functions.json +0 -592
- package/docs/50_test-reports/v0.1.8d_artifacts/skills-catalog.snapshot.md +0 -30
- package/docs/50_test-reports/v0.1.8d_artifacts/tools-sdk.output-schemas.json +0 -1236
- package/docs/50_test-reports/v0.1.8d_artifacts/tools-sdk.python.txt +0 -592
- package/docs/50_test-reports/v0.1.8d_artifacts/tools-sdk.typescript.txt +0 -516
- package/docs/50_test-reports/v0.1.8d_artifacts/wire-vs-transcription.diff.md +0 -54
- package/docs/50_test-reports/v0.2.0b_artifacts/f2probe/Cargo.lock +0 -7
- package/docs/50_test-reports/v0.2.0b_artifacts/f2probe/Cargo.toml +0 -6
- package/docs/50_test-reports/v0.2.0b_artifacts/f2probe/src/bin/messy.rs +0 -8
- package/docs/50_test-reports/v0.2.0b_artifacts/f2probe/src/main.rs +0 -4
- package/docs/50_test-reports/v0.2.0b_artifacts/hashline-probe.md +0 -5
- package/docs/50_test-reports/v0.2.0b_artifacts/slowprobe/Cargo.lock +0 -7
- package/docs/50_test-reports/v0.2.0b_artifacts/slowprobe/Cargo.toml +0 -7
- package/docs/50_test-reports/v0.2.0b_artifacts/slowprobe/build.rs +0 -4
- package/docs/50_test-reports/v0.2.0b_artifacts/slowprobe/src/main.rs +0 -13
- package/docs/60_exploration-and-research/cordis-research.md +0 -350
- package/docs/60_exploration-and-research/dsh-web-profile-package-map.md +0 -186
- package/docs/60_exploration-and-research/dsh-web-ui-slot-system-research.md +0 -310
- package/docs/60_exploration-and-research/dsh-webui-strip-boundary-research.md +0 -300
- package/docs/60_exploration-and-research/ios-chat-app-bridge-research.md +0 -324
- package/docs/60_exploration-and-research/web-frontend-composability-research.md +0 -191
- 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
- package/docs/adr/0001-bridge-tool-layer-not-service-layer.md +0 -14
- package/docs/adr/0002-masking-is-presentation-only.md +0 -15
- package/docs/plans/A2A-messaging-channel-test-archive.md +0 -256
- package/docs/plans/code-mode-vs-rlm-ipython-comparison.md +0 -137
- package/docs/plans/dashr-blueprint-review.md +0 -201
- package/docs/plans/dashr-blueprint.md +0 -561
- package/docs/plans/dashr-compaction-window-and-archive.md +0 -307
- package/docs/plans/dashr-profile-layer-feasibility.md +0 -367
- package/docs/plans/dashr-sandbox-escalation-semantics-gap.md +0 -171
- package/docs/plans/dashr-security-sandbox-analysis.md +0 -187
- package/docs/plans/dashr-surface-invariant-and-omp-imports.md +0 -97
- package/docs/plans/ipython-kernel-interactive-interface-test-report.md +0 -152
- package/docs/plans/kernel-refactoring/Dash-IPython-Control-Prompt-draft.md +0 -146
- package/docs/plans/kernel-refactoring/Dash-IPython-Control-Prompt-draft_v3.md +0 -50
- package/docs/plans/kernel-refactoring/Dash-IPython-Control-Prompt-draft_v4.md +0 -79
- package/docs/plans/kernel-refactoring/Dash-vs-PrimeAgent-systemprompt-toolcatalog-comparison.md +0 -138
- package/docs/plans/kernel-refactoring/RLM-system-prompt-injection-gap-report.md +0 -161
- package/docs/plans/kernel-refactoring/V0.1.5-development-plan.md +0 -109
- package/docs/plans/kernel-refactoring/actinoable-surface-to-llm-in-agent-runtime_dsh.md +0 -50
- package/docs/plans/kernel-refactoring/actinoable-surface-to-llm-in-agent-runtime_prime.md +0 -113
- package/docs/plans/recallable-compaction.md +0 -147
- package/docs/plans/spike-tag-repro.mjs +0 -102
- package/docs/plans/upstream-analysis.md +0 -128
- package/docs/v0.1.8-improved-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -142
- package/docs/v0.1.8-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -193
- package/docs/v0.1.8b-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -96
- package/docs/v0.1.8c-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -127
- package/docs/v0.1.8d-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -150
- package/docs/v0.1.8d_artifacts/README.md +0 -138
- package/docs/v0.1.8d_artifacts/code-mode-repl-only.observation.md +0 -74
- package/docs/v0.1.8d_artifacts/dsh-session-session-4a293388-9ae1-474b-87a0-9e17bb556d94.jsonl +0 -3890
- package/docs/v0.1.8d_artifacts/dsh-session-session-4a293388-9ae1-474b-87a0-9e17bb556d94.w-sample-0435.jsonl +0 -544
- package/docs/v0.1.8d_artifacts/functions.json +0 -592
- package/docs/v0.1.8d_artifacts/skills-catalog.snapshot.md +0 -30
- package/docs/v0.1.8d_artifacts/tools-sdk.output-schemas.json +0 -1236
- package/docs/v0.1.8d_artifacts/tools-sdk.python.txt +0 -592
- package/docs/v0.1.8d_artifacts/tools-sdk.typescript.txt +0 -516
- package/docs/v0.1.8d_artifacts/wire-vs-transcription.diff.md +0 -54
- package/docs/v0.1.8e-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -224
- package/docs/v0.1.9a-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -168
- package/docs/v0.2.0b-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -123
- package/docs/v0.2.0b_artifacts/f2probe/Cargo.lock +0 -7
- package/docs/v0.2.0b_artifacts/f2probe/Cargo.toml +0 -6
- package/docs/v0.2.0b_artifacts/f2probe/src/bin/messy.rs +0 -8
- package/docs/v0.2.0b_artifacts/f2probe/src/main.rs +0 -4
- package/docs/v0.2.0b_artifacts/hashline-probe.md +0 -5
- package/docs/v0.2.0b_artifacts/slowprobe/Cargo.lock +0 -7
- package/docs/v0.2.0b_artifacts/slowprobe/Cargo.toml +0 -7
- package/docs/v0.2.0b_artifacts/slowprobe/build.rs +0 -4
- package/docs/v0.2.0b_artifacts/slowprobe/src/main.rs +0 -13
- package/docs/v0.2.1-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -110
- package/docs/v0.2.1b-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -86
- package/docs/v0.2.1c-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -66
- package/lib/py-sdk-BCaOGYz7.d.ts +0 -125
- package/lib/py-sdk-CbgYiX8O.js +0 -691
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# lsp Specification
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
`lsp` 是**双模**语言服务能力:passive push 模(插件订阅 dsh 文件事件流,替 agent 向 per-session LSP server 子进程做 `didOpen/didChange/didSave` 文本同步,缓存 server 推回的 `publishDiagnostics`)+ proactive tool 模(agent 经 `dvc://lsp` 主动要 `diagnostics`/`format`/`definition` 等)。工作单位 = agent session(cwd 即 workspace root 候选);**每 session 每语言一个 server 子进程**,不跨 session 共享。生命周期三级供给,类比 repl kernel:host start 零重物、session-start 登记零子进程、首用 lazy spawn。
|
|
5
|
+
|
|
6
|
+
## Requirements
|
|
7
|
+
|
|
8
|
+
### Requirement: Root-marker probing (lspMarker)
|
|
9
|
+
Server availability and project-root determination SHALL follow the per-language marker table(`pyrightconfig.json`/`pyproject.toml`、`tsconfig.json`/`jsconfig.json`、`Cargo.toml`、`go.mod` …配置驱动,不发明 `lsp.json`)——编辑器侧工程惯例,非 LSP 协议标准。Marker 缺席不阻断:server 仍可 spawn,root 退化为 mutation 文件所在目录。
|
|
10
|
+
|
|
11
|
+
#### Scenario: Marker present
|
|
12
|
+
- **WHEN** a session's cwd contains a language marker file and the language's server is locally available
|
|
13
|
+
- **THEN** the manager resolves project root to the marker's directory and reports availability for that language
|
|
14
|
+
|
|
15
|
+
#### Scenario: Marker absent
|
|
16
|
+
- **WHEN** no marker exists for the mutated file's language
|
|
17
|
+
- **THEN** availability is `unknown`, not `unavailable` — the gate below still offers opt-in
|
|
18
|
+
|
|
19
|
+
### Requirement: Gated notice with explicit per-session opt-in (on/off)
|
|
20
|
+
The manager at session start SHALL check local availability of each language server in its table(Python/TypeScript 为必备,缺失即安装;Rust/Go 保留 nag 检测,server 缺失时按需安装). When a session performs file mutations (edit/write 落盘) in a language with availability `available` or `unknown` and the session gate is `unasked`, the tool result MAY append the availability notice (lsp 可用,`dvc://lsp` 开/关) **at most 10 times per session**(防刷屏上限). Both `on` and `off` are PER-SESSION state — the manager handles everything, and SHALL write NO repo artifact or marker file in either direction(无 `.dashr/lsp.json`,无任何落盘偏好).
|
|
21
|
+
|
|
22
|
+
#### Scenario: Mutation nag capped
|
|
23
|
+
- **WHEN** the agent edits `.py` files repeatedly in a session with gate `unasked`
|
|
24
|
+
- **THEN** at most 10 tool results carry the notice; afterwards mutations stay silent until the gate is decided
|
|
25
|
+
|
|
26
|
+
#### Scenario: Explicit on (per session)
|
|
27
|
+
- **WHEN** the agent sets `dvc://lsp` on
|
|
28
|
+
- **THEN** the session gate becomes `on` and the manager warm-starts the language server; nothing is written to the repo
|
|
29
|
+
|
|
30
|
+
#### Scenario: Explicit off (per session)
|
|
31
|
+
- **WHEN** the agent sets `dvc://lsp` off
|
|
32
|
+
- **THEN** the gate becomes `off`, no server spawns, the notice is muted for the session, and no repo marker is written
|
|
33
|
+
|
|
34
|
+
### Requirement: Must-have servers installed, niche on demand
|
|
35
|
+
At session start the manager SHALL verify Python and TypeScript servers and INSTALL a missing one (pip/npm, pinned, fail-soft — 安装失败降级为该语言 `unavailable`);Rust/Go servers SHALL NOT be installed proactively — they stay in the nag-detection table and install only when the agent turns lsp on for that language.
|
|
36
|
+
|
|
37
|
+
#### Scenario: Missing pyright on a fresh host
|
|
38
|
+
- **WHEN** a session starts and no Python language server is installed
|
|
39
|
+
- **THEN** the manager installs it in the background and reports availability `available` once done(安装期间 `unknown`,nag 照常)
|
|
40
|
+
|
|
41
|
+
#### Scenario: Rust opted in on demand
|
|
42
|
+
- **WHEN** the agent sets lsp on in a session touching Rust files and rust-analyzer is absent
|
|
43
|
+
- **THEN** the manager installs rust-analyzer then spawns it — never before the opt-in
|
|
44
|
+
|
|
45
|
+
### Requirement: Lazy spawn, session lifetime
|
|
46
|
+
Server subprocesses SHALL spawn lazily on first post-on use, one subprocess per (session, language), registered under the agent's own tool effect so agent dispose unwinds them via `shutdown`+`exit`; an idle timeout reclaims servers of still-live sessions.
|
|
47
|
+
|
|
48
|
+
#### Scenario: Per-session isolation
|
|
49
|
+
- **WHEN** two sessions work in different cwd/repo simultaneously
|
|
50
|
+
- **THEN** each owns independent server subprocesses with its own workspace root and document mirrors
|
|
51
|
+
|
|
52
|
+
### Requirement: Text synchronization is post-hoc, never intercepting
|
|
53
|
+
The plugin SHALL feed document sync (`didOpen`/`didChange` full-text + `didSave`) from AFTER-THE-FACT dsh events only — `tools/post-execute` on successful read/edit/write, mirroring the exact landed content(EXACT content, didSave freshness, span guard)— and SHALL NOT intercept, wrap, or delay any dsh read/write/edit flow. The version ledger follows the host fs observation policy's read-before-edit accounts; no second version book is kept.
|
|
54
|
+
|
|
55
|
+
#### Scenario: Landed content is the mirror
|
|
56
|
+
- **WHEN** an edit lands and lsp is on for that language
|
|
57
|
+
- **THEN** the server receives a full-text `didChange` + `didSave` with the exact written content before diagnostics are requested, so line numbers match what the model just wrote
|
|
58
|
+
|
|
59
|
+
### Requirement: Dual-mode results
|
|
60
|
+
Proactive mode (`dvc://lsp` write: `diagnostics`/`format`/`definition`/…) and passive mode (cached `publishDiagnostics` attached to tool results, e.g. hashline edit 的 post-edit summary,经注入回调而非模块内依赖) SHALL both be served from the same session manager. Every failure — no server, gate off, cold-start noise — SHALL read as "no feedback": a serverless mutation is byte-identical to stock behavior.
|
|
61
|
+
|
|
62
|
+
#### Scenario: Diagnostics ride the edit result
|
|
63
|
+
- **WHEN** lsp is on, an edit lands, and the server answers diagnostics
|
|
64
|
+
- **THEN** the edit's tool result carries the diagnostics summary; when the server is absent or slow, the result is unchanged
|
|
65
|
+
|
|
66
|
+
### Requirement: Spin-up latency is absorbed, never blocking
|
|
67
|
+
Server cold-start(spawn + `initialize` + 首轮索引)SHALL be handled by three means: (1) **warm-start at opt-in** — gate on 即后台 spawn,不等首个请求; (2) **fire-and-attach** — diagnostics 请求带超时,超时/未就绪读作"no feedback",server 稍后推回的 `publishDiagnostics` 缓存并附到**下一个** mutation 的 tool result(延迟附挂,不丢不阻塞); (3) **read 预热** — session 内首个某语言文件 read 即提前 `didOpen`,使首个 edit 命中已初始化的 server. The mutation path SHALL NEVER wait on server readiness — worst case is a summary arriving one tool call late.
|
|
68
|
+
|
|
69
|
+
#### Scenario: First edit on a cold server
|
|
70
|
+
- **WHEN** the gate turns on and the very next mutation hits an uninitialized server
|
|
71
|
+
- **THEN** the edit result carries no diagnostics (no feedback), and when the server finishes indexing the diagnostics attach to the next mutation's result
|
|
72
|
+
|
|
73
|
+
#### Scenario: Read pre-warms
|
|
74
|
+
- **WHEN** the agent reads a `.ts` file before editing it and lsp gate is on for TypeScript
|
|
75
|
+
- **THEN** the read triggers `didOpen` and server initialization, so the subsequent edit usually gets same-call diagnostics
|
|
76
|
+
|
|
77
|
+
### Requirement: Orthogonality and injection boundaries
|
|
78
|
+
The lsp capability SHALL be a self-contained module: no url-schemes/hashline imports; per-feature attachments (edit-result diagnostics, availability notices) arrive as injected callbacks from composition roots. Host start SHALL NOT probe markers or spawn processes — all discovery is per-session, on demand.
|
|
79
|
+
|
|
80
|
+
#### Scenario: Host boot cost
|
|
81
|
+
- **WHEN** the host starts with the lsp capability mounted
|
|
82
|
+
- **THEN** no subprocess spawns, no marker probing runs, and nothing on the boot path can fail because of lsp
|
|
83
|
+
|
|
84
|
+
## Surface syntax (`dvc://lsp`)
|
|
85
|
+
|
|
86
|
+
The dvc contract is uniform: **bare read = roster, `<device>` read = doc/status, `<device>` write = action dispatch**. Gate state is per-session — the write dispatcher injects the calling agent's session id automatically; agents never type it.
|
|
87
|
+
|
|
88
|
+
Read-vs-write follows GET/PUT semantics — **reads never mutate, writes always do**:
|
|
89
|
+
|
|
90
|
+
- `read dvc://lsp` — the device doc: actions, args, current contract.
|
|
91
|
+
- `read dvc://lsp/status` — the calling session's gate (session injected from the read env; no session → an explicit pointer note).
|
|
92
|
+
- `read dvc://lsp/diagnostics?file=<path>&all=1` — fan-out query (read-only; spawning a lazily-managed server is the side effect of asking, not a mutation).
|
|
93
|
+
- `read dvc://lsp/definition?file=&line=&character=|&symbol=` (also `references`, `hover`) — position queries, 1-based.
|
|
94
|
+
- `write dvc://lsp` `{"action":"on"}` / `{"action":"off"}` — per-session gate decision; ack describes the effect. No repo artifact in either direction.
|
|
95
|
+
- `write dvc://lsp` `{"action":"reload"}` — restart the server (config re-read).
|
|
96
|
+
- `write dvc://lsp` `{"action":"rename",...}` / `{"action":"code_actions",...,"apply":N}` / `{"action":"format","file":...}` — workspace-mutating operations.
|
|
97
|
+
|
|
98
|
+
The write surface retains `status` for symmetry with the session-injected dispatcher, but the read form is canonical for all queries. Path-mutation forms (`dvc://lsp/on`) are NOT part of the contract: mutation never rides a read URL.
|
|
99
|
+
|
|
100
|
+
### Requirement: Session transport is out-of-band
|
|
101
|
+
The per-session gate addressing SHALL ride the dvc write dispatcher's `execute(args, { session })` context — NOT the args payload — so devices with strict argument validators (browser) are unaffected; the lsp device reads `ctx.session` with a legacy in-args fallback for direct callers. The read surface receives the calling session through the resolver env the same way (`dvc://lsp/status` returns the calling session's gate).
|
|
102
|
+
|
|
103
|
+
#### Scenario: Strict-validator device unaffected
|
|
104
|
+
- **WHEN** the model writes `dvc://browser` with `{"action":"open","url":…}` from a session
|
|
105
|
+
- **THEN** the browser device's validator sees only its declared fields and the action executes (the session rides the dispatcher's out-of-band ctx)
|
|
106
|
+
|
|
107
|
+
#### Scenario: Status read is session-aware
|
|
108
|
+
- **WHEN** the model turns lsp on and then reads `dvc://lsp/status` from the same session
|
|
109
|
+
- **THEN** the status reports that session's gate (`"gate":"on"`)
|
|
110
|
+
|
|
111
|
+
## OMP parity progress
|
|
112
|
+
|
|
113
|
+
The device vendored a trimmed upstream oh-my-pi (`packages/coding-agent/src/lsp`) surface; parity is being completed in stages, each keeping the module boundary (nothing imports hash-edit/ast/url-schemes internals):
|
|
114
|
+
|
|
115
|
+
1. ✅ `rename` / `code_actions` / `reload` actions (apply/preview WorkspaceEdit over `changes` + `documentChanges`; code action apply by index; reload = shutdown + evict).
|
|
116
|
+
2. ✅ Workspace-wide diagnostics (`{"action":"diagnostics","file":"*"}` — aggregate cached publishDiagnostics across all live servers, per-file E/W counts) + `documentDiagnostic` pull for servers advertising `diagnosticProvider` (pull wins over last push on the saved path).
|
|
117
|
+
3. ✅ Per-file fan-out: `{"action":"diagnostics","file":...,"all":true}` queries every registered server covering the file and merges results tagged per server (single-coverage falls through to the primary path).
|
|
118
|
+
4. ✅ `symbol` / `symbol#N` position resolution on definition/references/rename/hover (word-bounded exact first, case-insensitive fallback, structured `LSP_SYMBOL_NOT_FOUND`; explicit `character` wins).
|
|
119
|
+
5. ✅ Must-have installer: registry `installServer()` runs the package-manager command (npm/pip/go/rustup, 5 min timeout, fail-soft) for missing python/ts/js primaries once per session at first nag; niche languages stay install-on-opt-in.
|
|
120
|
+
|
|
121
|
+
All five stages are in-tree; residual deltas vs upstream (lspmux, deferred-diagnostics ledger, writethrough editor integration) are IDE-side facilities without a dsh counterpart and are tracked as out of scope by the lsp spec's post-hoc sync ruling.
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# mobile-layout Specification
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
better-dsh 的移动端布局与输入契约:窄视口侧栏轨 0(注入 CSS 覆盖,桌面档零影响)、三条件滑动手势(边缘带 × 距离 × 速率,纯函数可测)、iOS focus 自动放大抑制 zoomGuard(browser=viewport meta token 改写 / standalone=16px 字号地板双形态,`'off'` 逃生门),全部随插件发布、config 门控(`mobile.enabled` / `mobile.breakpoint` / `mobile.zoomGuard`)。
|
|
5
|
+
|
|
6
|
+
## Requirements
|
|
7
|
+
|
|
8
|
+
### Requirement: iOS focus auto-zoom suppression on narrow viewports
|
|
9
|
+
|
|
10
|
+
The plugin's host half SHALL suppress the iOS Safari focus-triggered auto-zoom with **display-mode-dependent behavior**:
|
|
11
|
+
|
|
12
|
+
- **Browser context** (not standalone): rewrite the page's viewport meta (appending `maximum-scale=1` and `user-scalable=no`) inside the injected head boot script — before any application bundle can focus an input — with the v0.2.4 machinery (double gate iOS-class UA AND narrow viewport, breakpoint re-evaluation, provisional/reconcile single-meta invariant, early-load re-evaluation ladder, idempotent merge, byte-level restore). Real-device datum (2026-09-03): in-browser iOS Safari ignores `user-scalable=no` for pinch, so pinch zoom remains available in this mode.
|
|
13
|
+
- **Standalone context** (`(display-mode: standalone)` media query matches OR `navigator.standalone === true`): the plugin SHALL NOT touch the viewport meta at all (no rewrite, no provisional, no listeners, no timers — real-device datum: standalone iOS honors `user-scalable=no` and pinch would break), and SHALL instead inject a static style element (`id="ios-zoom-font-floor"`, carrying the plugin's style-claim attributes) with `@media (max-width: {breakpoint-0.02}px){ input,textarea,select,[contenteditable="true"]{ font-size:16px !important } }`, which suppresses the focus auto-zoom by the font-size mechanism.
|
|
14
|
+
|
|
15
|
+
Both branches SHALL be config-gated via `mobile.zoomGuard` (`'meta'` default = auto dual-mode behavior; `'off'` emits neither branch on any platform). Non-iOS browsers and wide viewports SHALL observe stock behavior in both display modes.
|
|
16
|
+
|
|
17
|
+
#### Scenario: iOS narrow focus does not zoom
|
|
18
|
+
|
|
19
|
+
- **WHEN** an input, select, checkbox, or contenteditable receives focus on an iOS-class browser below the breakpoint with `zoomGuard: 'meta'`
|
|
20
|
+
- **THEN** no auto-zoom occurs in either display mode: browser mode suppresses it via the rewritten viewport meta, standalone mode via the 16px font-floor style
|
|
21
|
+
|
|
22
|
+
#### Scenario: Rewrite lands before first possible focus
|
|
23
|
+
|
|
24
|
+
- **WHEN** the head boot script executes during page load in browser (non-standalone) display mode
|
|
25
|
+
- **THEN** the viewport meta rewrite is applied synchronously before any application bundle materializes, so no zoom flash can occur on an early auto-focus
|
|
26
|
+
|
|
27
|
+
#### Scenario: Browser mode rewrites meta (unchanged from v0.2.4)
|
|
28
|
+
|
|
29
|
+
- **WHEN** an iOS-class browser below the breakpoint loads in a non-standalone display mode with `zoomGuard: 'meta'`
|
|
30
|
+
- **THEN** the viewport meta carries `maximum-scale=1, user-scalable=no` (single meta, idempotent, restorable) and no font-floor style is injected
|
|
31
|
+
|
|
32
|
+
#### Scenario: Standalone mode never touches the viewport meta
|
|
33
|
+
|
|
34
|
+
- **WHEN** an iOS-class browser below the breakpoint loads with display-mode standalone (matched via media query or `navigator.standalone`) and `zoomGuard: 'meta'`
|
|
35
|
+
- **THEN** the viewport meta is byte-identical to stock, no provisional meta is created, no resize/MQ listeners or re-evaluation timers are armed, and the `ios-zoom-font-floor` style element is present with the 16px floor rules scoped to the configured breakpoint
|
|
36
|
+
|
|
37
|
+
#### Scenario: Standalone pinch zoom is preserved
|
|
38
|
+
|
|
39
|
+
- **WHEN** the user pinch-zooms in standalone display mode with the guard active
|
|
40
|
+
- **THEN** the viewport meta contains no zoom-restricting tokens (pinch is engine-available; suppression relies solely on the font-size floor)
|
|
41
|
+
|
|
42
|
+
#### Scenario: Font floor suppresses the focus zoom in standalone
|
|
43
|
+
|
|
44
|
+
- **WHEN** an input, textarea, select, or `[contenteditable="true"]` element receives focus in standalone mode below the breakpoint
|
|
45
|
+
- **THEN** its computed font-size is at least 16px and no auto-zoom occurs
|
|
46
|
+
|
|
47
|
+
#### Scenario: Non-iOS touch browsers unaffected
|
|
48
|
+
|
|
49
|
+
- **WHEN** the page loads on a non-iOS touch browser (e.g. Android Chrome) below the breakpoint, in either display mode
|
|
50
|
+
- **THEN** the viewport meta is not rewritten and no font-floor style is injected (Android never focus-zooms; the iOS gate avoids `maximum-scale` side effects there)
|
|
51
|
+
|
|
52
|
+
#### Scenario: Breakpoint crossing re-evaluates
|
|
53
|
+
|
|
54
|
+
- **WHEN** the viewport crosses the breakpoint after load (rotation, split-screen) in browser display mode
|
|
55
|
+
- **THEN** the rewrite is applied on entering the narrow band and the stock meta content is restored on leaving it; in standalone mode the font-floor style's media query naturally stops matching above the breakpoint (no JS re-evaluation exists there)
|
|
56
|
+
|
|
57
|
+
#### Scenario: Desktop and wide viewports unaffected
|
|
58
|
+
|
|
59
|
+
- **WHEN** the page loads on a desktop browser, a non-iOS browser, or at/above the breakpoint (either display mode)
|
|
60
|
+
- **THEN** the viewport meta is stock and no font-floor style is injected (the floor's media query does not match above the breakpoint)
|
|
61
|
+
|
|
62
|
+
#### Scenario: Config off restores stock behavior
|
|
63
|
+
|
|
64
|
+
- **WHEN** `mobile.zoomGuard` is `'off'`
|
|
65
|
+
- **THEN** neither the meta machinery nor the font-floor style exists in any display mode
|
|
66
|
+
|
|
67
|
+
#### Scenario: Idempotent evaluation
|
|
68
|
+
|
|
69
|
+
- **WHEN** the browser-mode re-evaluation runs multiple times within one state (load, resize storms, repeated crossings)
|
|
70
|
+
- **THEN** the meta content does not accumulate duplicate tokens or regress (standalone mode arms no re-evaluation machinery at all)
|
|
71
|
+
|
|
72
|
+
### Requirement: Sidebar occupies zero width on narrow viewports
|
|
73
|
+
|
|
74
|
+
The plugin's client half SHALL hide the sidebar rail (zero-width column track) on narrow viewports via injected static CSS (media query + semantic attribute selectors, `!important` over the inline grid template), aligned with the upstream CSS-first layout paradigm and WITHOUT JavaScript geometry measurement; desktop-class rendering SHALL remain identical to the unpatched product, and the feature SHALL ship with the plugin, config-gated (`mobile.enabled`, default on).
|
|
75
|
+
|
|
76
|
+
#### Scenario: Mobile viewport hides the rail
|
|
77
|
+
|
|
78
|
+
- **WHEN** the page renders at a mobile-class viewport width below the configured breakpoint with the feature enabled
|
|
79
|
+
- **THEN** the sidebar column track is zero width and the conversation area spans the frame
|
|
80
|
+
|
|
81
|
+
#### Scenario: Desktop unaffected
|
|
82
|
+
|
|
83
|
+
- **WHEN** the page renders at or above the breakpoint
|
|
84
|
+
- **THEN** layout behavior is identical to the unpatched product
|
|
85
|
+
|
|
86
|
+
#### Scenario: Degradation is benign
|
|
87
|
+
|
|
88
|
+
- **WHEN** upstream DOM/attribute changes break the CSS override
|
|
89
|
+
- **THEN** the layout falls back to the native rail rendering without errors or blank areas
|
|
90
|
+
|
|
91
|
+
### Requirement: Three-condition swipe recognition
|
|
92
|
+
|
|
93
|
+
Swipe recognition SHALL require all three of: gesture origin within the edge band, displacement at or above the distance threshold, and average velocity at or above the velocity threshold; slow press-drag gestures (text selection and similar) SHALL NOT trigger a swipe, and a recognized swipe SHALL toggle the sidebar via the layout service (`ctx.layout.toggleSidebar()`, narrow-viewport semantics), with the velocity/distance predicates implemented as pure functions under unit test.
|
|
94
|
+
|
|
95
|
+
#### Scenario: Slow text-selection drag does not toggle
|
|
96
|
+
|
|
97
|
+
- **WHEN** a pointer press-drag covers the distance threshold at sub-threshold velocity (e.g. selecting text to copy)
|
|
98
|
+
- **THEN** no sidebar toggle occurs
|
|
99
|
+
|
|
100
|
+
#### Scenario: Fast swipe toggles
|
|
101
|
+
|
|
102
|
+
- **WHEN** a pointer gesture starts in the edge band, exceeds the distance threshold, and meets the velocity threshold
|
|
103
|
+
- **THEN** the sidebar overlay state toggles (narrowExpanded flips)
|
|
104
|
+
|
|
105
|
+
#### Scenario: Interactive-element origins are ignored
|
|
106
|
+
|
|
107
|
+
- **WHEN** a gesture begins on an interactive element (link, button, input)
|
|
108
|
+
- **THEN** no swipe recognition runs for that gesture
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# model-failover Specification
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
TBD - created by archiving change 2026-09-02-model-failover-settings-surface. Update Purpose after archive.
|
|
5
|
+
|
|
6
|
+
## Requirements
|
|
7
|
+
|
|
8
|
+
### Requirement: Model Failover surface in General settings
|
|
9
|
+
|
|
10
|
+
The plugin SHALL register a Model Failover row into the Settings > General page via the `settings.general.item` slot, exposing the failover pair (primary/secondary model selectors) with persisted configuration, wherever the plugin's client bundle is built and loaded — including the source-level test instance — and the row SHALL remain functional across upstream settings-slot contract evolutions covered by the alignment process.
|
|
11
|
+
|
|
12
|
+
#### Scenario: Row renders in the source-level test instance
|
|
13
|
+
|
|
14
|
+
- **WHEN** the Dev/Test 1 instance starts with the plugin's client bundle built and the user opens Settings > General
|
|
15
|
+
- **THEN** the Model Failover row with both model selectors is visible and its selections persist across instance restarts
|
|
16
|
+
|
|
17
|
+
#### Scenario: Failover engages on primary failure
|
|
18
|
+
|
|
19
|
+
- **WHEN** a turn's primary model request fails and a secondary model is configured in the row
|
|
20
|
+
- **THEN** the host-side per-turn waterfall retries via the configured secondary and the outcome is observable in the session
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# preact-ui-shell Specification
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
为测试线(test-line)的 `apps/web` shell 提供构建期 React 家族到 `preact/compat` 的 vite alias patch:上游 ui-* 插件 bundle 的 `require("react")` 零改动获得 Preact 实例,shell 体积随之显著缩减。该 patch 仅限测试线 checkout,随 tag 切换重放;是否随插件包发布 dist 由 ship 决策另行裁决、暂缓。
|
|
5
|
+
|
|
6
|
+
### Requirement: Preact-shell build for the web UI
|
|
7
|
+
The test-line harness build SHALL support building the web shell (`apps/web`) with the React family aliased to `preact/compat` (including `react/jsx-runtime`, `react/jsx-dev-runtime`, `react-dom`, `react-dom/client` subpaths) via a build-time vite alias, so the platform module seed materializes Preact instances and every upstream client plugin bundle's `require("react")` receives Preact with zero upstream component edits. The alias SHALL be a monorepo-local build patch (documented, re-applied on tag switches), never an upstream source fork.
|
|
8
|
+
|
|
9
|
+
#### Scenario: Shell serves the UI with Preact
|
|
10
|
+
- **WHEN** the test-line instance is rebuilt with the alias patch and a browser loads the served UI
|
|
11
|
+
- **THEN** the full upstream UI corpus mounts (sidebar/workspace/settings/chat), the session reports zero `pageerror` and zero `console.error`, and the shell bundle contains no `react-dom` production banner while carrying `preact` identity
|
|
12
|
+
|
|
13
|
+
#### Scenario: Size regression is measured, not assumed
|
|
14
|
+
- **WHEN** the alias build completes
|
|
15
|
+
- **THEN** the shell `index` chunk (where the React family rides) is measured against the stock build and the delta recorded in the change report
|
|
16
|
+
|
|
17
|
+
### Requirement: Test-line-only scope pending a ship decision
|
|
18
|
+
The alias patch lives in the harness checkout only. The published plugin package (`@pgmi-builds/better-dsh`) SHALL NOT silently fork the web-UI serve surface: shipping a Preact-built frontend dist through the plugin (web-runtime override rows) is a separate decision gated on the prod host version upgrade, because a shipped dist freezes the UI corpus at the fork point.
|
|
19
|
+
|
|
20
|
+
#### Scenario: Plugin publish content unchanged by this change
|
|
21
|
+
- **WHEN** the next plugin alpha is published after this change
|
|
22
|
+
- **THEN** the Preact enhancement is not part of the published artifact; the report records the ship-in-plugin option (dist + override rows) and its corpus-freeze trade-off as a pending decision tied to the prod host upgrade
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# repl-dispatch-resilience Specification
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
REPL(`eval` cell)子分派的韧性契约:分派层的任何错误——调度器缺失、工具体抛错、取消——都必须 settle 为 cell 可见的 `ToolCallError` 结果,绝不外泄为 unhandled rejection 或使宿主进程崩溃。生产组合必须把带 `TOOL_RUNTIME_SCHEDULER` symbol 的原生 `ToolRuntime` 实例解析给插件,测试组合与生产组合之间不得存在环境差异导致的静默行为分裂。
|
|
5
|
+
|
|
6
|
+
## Requirements
|
|
7
|
+
|
|
8
|
+
### Requirement: Dispatch errors settle as visible ToolCallError
|
|
9
|
+
The system SHALL resolve the plugin's tools service to the native `ToolRuntime` instance carrying the `TOOL_RUNTIME_SCHEDULER` symbol in the production composition, so REPL sub-dispatches execute through the same staged scheduler as the agent loop and return real tool results to the cell. The symbol this plugin imports SHALL be identical (`===`) to the one keying the mounted instance — a second dsh-tools module copy reachable from the deployed plugin (e.g. stray nested `@deepseek-ai` symlinks) breaks that identity and is a deployment defect (2026-09-02 corrected root cause; the plain `runtimeCtx.tools` read is the sanctioned resolution path). A mount whose tools service genuinely lacks the symbol SHALL be treated as a loud, diagnosable configuration failure — the error names the plugin's own `dsh-tools` resolution path — rather than a silent runtime crash, and that loud failure SHALL be the abnormal fallback, not the normal production state.
|
|
10
|
+
|
|
11
|
+
#### Scenario: Production mount carries the scheduler symbol
|
|
12
|
+
- **WHEN** the DASHR plugin mounts in the production composition and a cell dispatches a real tool call
|
|
13
|
+
- **THEN** the dispatch executes through `registry[TOOL_RUNTIME_SCHEDULER]` and returns the tool result to the cell without crashing the daemon
|
|
14
|
+
|
|
15
|
+
#### Scenario: Legitimate cell tool call returns its real result
|
|
16
|
+
- **WHEN** a cell dispatches a legitimate tool call (e.g. `tool.read({ path })`) in a live session after the fix
|
|
17
|
+
- **THEN** the cell receives the tool's actual result, not the `TOOL_RUNTIME_SCHEDULER` loud error
|
|
18
|
+
|
|
19
|
+
#### Scenario: Regression probes pass after the fix
|
|
20
|
+
- **WHEN** the four probe cells from the diagnosis matrix (`tool.subagent` background:false, `tool.subagent` background:true, `tool.bash` background:true, `tool.read`) run in a live session after the fix
|
|
21
|
+
- **THEN** all four return a real result (or a visible `ToolCallError` where the call is legitimately invalid) instead of truncating, and the journal contains no new daemon crash
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# skill Specification
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Let the model address skill bodies and internal skill resources via `skill://` URLs, with discovery tied to the same workspace source that advertises skills, and replace the skill tool's body-loading role on the REPL surface.
|
|
6
|
+
|
|
7
|
+
## Requirements
|
|
8
|
+
|
|
9
|
+
### Requirement: Skill body addressing
|
|
10
|
+
The system SHALL let read accept `skill://<name>` and return that skill's SKILL.md body in full text (no default truncation; only explicit selectors page).
|
|
11
|
+
|
|
12
|
+
#### Scenario: Reading an existing skill
|
|
13
|
+
- **WHEN** the model reads `skill://<registered skill name>`
|
|
14
|
+
- **THEN** the system returns the skill's body text in full
|
|
15
|
+
|
|
16
|
+
#### Scenario: Reading an unknown skill
|
|
17
|
+
- **WHEN** the model reads `skill://<unregistered name>`
|
|
18
|
+
- **THEN** the system returns the structured `URL_SKILL_NOT_FOUND` error ("unknown or no longer available")
|
|
19
|
+
|
|
20
|
+
### Requirement: Skill internal resource addressing
|
|
21
|
+
The system SHALL let read accept `skill://<name>/<path>` and return the named file inside the skill's resource directory, loaded through the sandboxed filesystem (same containment/audit rules as host reads). A skill without a filesystem resource directory returns `URL_SKILL_NO_RESOURCE_BASE`; a subpath escaping the directory returns `URL_SKILL_RESOURCE_ESCAPE`.
|
|
22
|
+
|
|
23
|
+
#### Scenario: Reading a referenced skill file
|
|
24
|
+
- **WHEN** the model reads `skill://foo/references/x.md`
|
|
25
|
+
- **THEN** the system returns the content of `references/x.md` inside foo's resource directory
|
|
26
|
+
|
|
27
|
+
#### Scenario: Resource path escapes the skill directory
|
|
28
|
+
- **WHEN** the model reads `skill://foo/../../etc/passwd`
|
|
29
|
+
- **THEN** the system returns the structured `URL_SKILL_RESOURCE_ESCAPE` error and reads nothing
|
|
30
|
+
|
|
31
|
+
### Requirement: Workspace-cwd-sensitive discovery
|
|
32
|
+
The system SHALL pass the calling agent's session cwd (`{cwd: agent.session.header.cwd}`) to every skill-registry lookup — the same source `dsh-tool-skill` uses to render `<available_skills>` — so `skill://` can address exactly the skills the catalog advertises for the current workspace.
|
|
33
|
+
|
|
34
|
+
#### Scenario: Skill visible in the current workspace
|
|
35
|
+
- **WHEN** the model reads `skill://foo` from a session whose cwd is inside a project root that provides foo
|
|
36
|
+
- **THEN** the lookup succeeds and the body resolves
|
|
37
|
+
|
|
38
|
+
#### Scenario: Skill outside the workspace is unknown
|
|
39
|
+
- **WHEN** a skill's project roots do not cover the session cwd
|
|
40
|
+
- **THEN** the lookup misses and the system returns `URL_SKILL_NOT_FOUND`, matching what `<available_skills>` advertised
|
|
41
|
+
|
|
42
|
+
### Requirement: Path-backed search view
|
|
43
|
+
The system SHALL expose the handler's `resolvePath`: `skill://<name>` maps to the skill's resource-directory root and `skill://<name>/<subpath>` to the joined file (same escape guard), letting grep/glob search the real files; unmappable URLs (unknown skill, non-directory resource base, escaping subpath) resolve to `undefined` so callers fall back to text resolution with its structured error.
|
|
44
|
+
|
|
45
|
+
#### Scenario: grep searches the skill's real directory
|
|
46
|
+
- **WHEN** the model greps a `skill://foo` URL
|
|
47
|
+
- **THEN** the search runs natively over foo's on-disk resource directory
|
|
48
|
+
|
|
49
|
+
### Requirement: Skill tool masked on the REPL surface only
|
|
50
|
+
The system SHALL mask the upstream `skill` tool presentation-only (ADR-0002): it disappears from the REPL `tool.*` binding names and the dashr tool-catalog section, while the host-layer native `skill` tool stays registered and executable and the `<available_skills>` discovery catalog is retained.
|
|
51
|
+
|
|
52
|
+
#### Scenario: Skill absent from the REPL surface
|
|
53
|
+
- **WHEN** the model inspects the kernel tool bindings or the tool-catalog text
|
|
54
|
+
- **THEN** neither contains `skill`, and `skill://` URLs remain the addressing path for skill content
|
|
55
|
+
|
|
56
|
+
#### Scenario: Host-native skill tool survives
|
|
57
|
+
- **WHEN** any host-plane consumer dispatches the native `skill` tool directly
|
|
58
|
+
- **THEN** the tool remains registered and executable — the mask touched only presentation surfaces
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
# tool-surface Specification
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
DASHR 的模型表面(model surface)契约:哪些工具出现在 registry 投影(LLM-client 协议 tools 数组、REPL 绑定)里。核心原则——掩码作用于 tool registry(被替代了呈现面的原生工具全部 visible=false);REPL 绑定对 registry 可见集做机械/透明的自动桥接(零名单维护);被掩工具的能力保留靠三桥 service 层直调(`agent` spawn/fork、`agent_message` 消息+中断、`agent_workflow` 编排),不靠 registry 豁免。全部 REPL 指引(cell 语义、调用形、非 flat 名例外、`subagent` 别名注记)只经由 `eval` 工具的 wire description 承载——system prompt 中不存在任何 DASHR 渲染的工具目录或 control-prompt section。
|
|
5
|
+
|
|
6
|
+
## Requirements
|
|
7
|
+
|
|
8
|
+
### Requirement: Registry masking of replaced-presentation native tools
|
|
9
|
+
|
|
10
|
+
The system SHALL remove the native tools whose presentation surface DASHR replaces(`skill`、上游 `send_message`、`report`、`list_agents`、delegation 家族 `subagent_fork`/`interrupt_agent`/`workflow`/`ralph`)from the agent's tool registry projection via an agent-scope registry restriction —— wire tools array 与 REPL bindings 同源于该 projection,移除因此均匀生效。`subagent` is deliberately NOT masked:它在每个表面保持可见,且 **`eval` 工具的 description** 注记它是 `agent` delegation tool(统一 agent-spawn 入口)的别名。The restriction MUST NOT touch the registered tool definitions themselves;DASHR preserves each masked tool's native capability at the tool-bridge level(not by registry exemption):`agent` spawns/forks subagents、`agent_message` 经 host-plane service 层传递 child-downlink/parent-uplink/interrupt、`agent_workflow` 把 script/rfc 透传给 CAPTURED native workflow/ralph definitions(workflowEngine service 是 preset delegation realm 的 entry-local 服务,任何外部 ctx 不可见——native execute closures 从内部解析);`agent://` 取代 `list_agents`、`read skill://` 取代 `skill`。
|
|
11
|
+
|
|
12
|
+
#### Scenario: Masked tool absent from every model-facing surface
|
|
13
|
+
|
|
14
|
+
- **WHEN** an agent session starts under DASHR
|
|
15
|
+
- **THEN** the wire tools array 与 the REPL bindings 均不含 masked 名,对 masked 名的调用返回 `UNKNOWN_TOOL`
|
|
16
|
+
|
|
17
|
+
#### Scenario: subagent stays visible as an annotated alias
|
|
18
|
+
|
|
19
|
+
- **WHEN** an agent session starts under DASHR
|
|
20
|
+
- **THEN** `subagent` remains present on the wire tools array 与 the REPL bindings,且 `eval` 工具 description 注明它是 `agent` delegation tool 的别名
|
|
21
|
+
|
|
22
|
+
#### Scenario: Masked capability preserved through the bridge
|
|
23
|
+
|
|
24
|
+
- **WHEN** the model sends a child-downlink, parent-uplink, or interrupt through the `agent_message` bridge
|
|
25
|
+
- **THEN** the service layer executes it with native delivery semantics (user-role next-turn delivery, `messageId` confirmation) and native authorization (direct-child-only lineage, ancestor authority for interrupt)
|
|
26
|
+
|
|
27
|
+
#### Scenario: DASHR's own wrappers unaffected
|
|
28
|
+
|
|
29
|
+
- **WHEN** the agent-scope restriction denies a native name that a DASHR wrapper shadows on the agent's own layer
|
|
30
|
+
- **THEN** the wrapper (`read`/`write`/`grep`/`glob`, `agent`/`agent_message`/`agent_workflow`) remains visible and callable on every surface
|
|
31
|
+
|
|
32
|
+
### Requirement: Delegation bridges are registry tools
|
|
33
|
+
|
|
34
|
+
The system SHALL register the delegation bridges(`agent`、`agent_message`、`agent_workflow`)as real tools in the tool registry(与 `eval` transport 同一 host registration 层),runtime argument validation inside their execute、structured `{ error }` return values(bad input 不抛异常)。Registry projection 是**两个**模型表面的 single source:wire tools array 与 REPL `tool.*` bindings(经 mechanical auto-bridge)。两个表面 SHALL 每个 session name-by-name 相等(以 mechanical binding rule 的 flat-name 限定为界);唯一允许的例外是 `eval` 本身排除在 binding set 之外(self-call prevention)。
|
|
35
|
+
|
|
36
|
+
#### Scenario: Bridge callable directly on the wire
|
|
37
|
+
|
|
38
|
+
- **WHEN** the model sends a direct tool call `agent` with `{ description, prompt }` (no cell)
|
|
39
|
+
- **THEN** the call dispatches through the normal kernel pipeline and returns the same result shape the REPL binding returns, with the same audit events as any registry tool
|
|
40
|
+
|
|
41
|
+
#### Scenario: Three-surface name equality
|
|
42
|
+
|
|
43
|
+
- **WHEN** a DASHR session starts
|
|
44
|
+
- **THEN** 目录表面已随「Catalog section presents REPL bridge instructions」的 REMOVED 撤销,原三表面等式收敛为两表面:the wire tools array 与 the REPL binding names 在 flat-name 规则内 equal as sets,excepting only `eval`
|
|
45
|
+
|
|
46
|
+
#### Scenario: No dual-source drift
|
|
47
|
+
|
|
48
|
+
- **WHEN** a bridge's parameter surface changes
|
|
49
|
+
- **THEN** the wire schema 与 REPL binding 一起变化,因为两者都派生自同一注册 schema
|
|
50
|
+
|
|
51
|
+
### Requirement: eval transport description matches runtime semantics
|
|
52
|
+
|
|
53
|
+
The system SHALL state the eval transport's top-level semantics truthfully in **the `eval` tool's model-facing description(唯一的 REPL 指引载体)**:top-level `await` works —— kernel 以 `PyCF_ALLOW_TOP_LEVEL_AWAIT` 编译 cell 并运行 module coroutine;top-level `return` is a SyntaxError(cell 运行于 module scope,globals = locals)。The description SHALL NOT claim top-level `return` is accepted.
|
|
54
|
+
|
|
55
|
+
#### Scenario: Description promises only what the kernel does
|
|
56
|
+
|
|
57
|
+
- **WHEN** the model reads the `eval` tool description
|
|
58
|
+
- **THEN** the text states that top-level `await` works,states that top-level `return` is a SyntaxError(module-scope cell),and contains no claim that top-level `return` is accepted
|
|
59
|
+
|
|
60
|
+
#### Scenario: Top-level return stays rejected
|
|
61
|
+
|
|
62
|
+
- **WHEN** a cell contains a top-level `return`
|
|
63
|
+
- **THEN** the kernel rejects it with a SyntaxError, matching the description
|
|
64
|
+
|
|
65
|
+
### Requirement: eval description is the single REPL guidance source
|
|
66
|
+
|
|
67
|
+
The system SHALL carry ALL REPL guidance in the `eval` tool's wire description —— cell 语义、直调 vs 进 cell 的判据、非 flat 名例外、`subagent` 别名注记、**置于 description 末尾**的 mechanical bridge 调用形 —— 内容从**插件源码中的 Markdown 文件**加载、注册工具时作为 `description` 生效;system prompt 中 SHALL NOT 存在任何 DASHR 渲染的工具目录或 control-prompt section。桥接指引 SHALL 只陈述**一个**统一调用形、一句话说清:`await tool.<name>(argsObject)`,argsObject = 该工具 wire JSON-Schema 参数对象写成的 Python dict 字面量(同字段名、单个位置参数、不用 kwargs),唯一系统性语法差异为 `true`/`false`/`null` → `True`/`False`/`None`;SHALL NOT 渲染 per-tool 签名表,且 SHALL NOT 对桥接调用的返回值形态作任何陈述(不写"不保证形状/需试错"类措辞)。描述中的桥接示例 SHALL 使用与被引工具 wire schema 一致的参数名。
|
|
68
|
+
|
|
69
|
+
#### Scenario: System prompt carries no DASHR catalog or control section
|
|
70
|
+
|
|
71
|
+
- **WHEN** an agent session renders its system prompt
|
|
72
|
+
- **THEN** 没有 DASHR 来源的 section 枚举 per-tool 签名,也没有独立的 control-prompt section 教 cell 范式;全部 REPL 指引只经由 `eval` description 到达模型
|
|
73
|
+
|
|
74
|
+
#### Scenario: Description loads from the source Markdown
|
|
75
|
+
|
|
76
|
+
- **WHEN** the plugin registers the `eval` tool
|
|
77
|
+
- **THEN** 其 wire description 等于包内 Markdown 指引文件的内容——编辑该文件即改变模型可见的 description
|
|
78
|
+
|
|
79
|
+
#### Scenario: One bridge call form, one syntax delta
|
|
80
|
+
|
|
81
|
+
- **WHEN** the model reads the bridge instructions in the `eval` description
|
|
82
|
+
- **THEN** it sees the single positional-args-object call form 与 `True`/`False`/`None` 大小写映射,and no per-tool signature table or output-shape caveat(无任何"不保证形态/试错"措辞)
|
|
83
|
+
|
|
84
|
+
#### Scenario: Examples match wire parameter names
|
|
85
|
+
|
|
86
|
+
- **WHEN** the description shows a bridge example for `read`
|
|
87
|
+
- **THEN** 参数键与 `read` 的 wire schema 一致(如 `path`),而非其它工具的键名
|
|
88
|
+
|
|
89
|
+
#### Scenario: Guidance lives and dies with the tool
|
|
90
|
+
|
|
91
|
+
- **WHEN** a session's scope excludes the `eval` tool
|
|
92
|
+
- **THEN** 任何地方都不渲染 REPL 指引(指引即工具自身的 description);`eval` 在场时指引必然在场
|
|
93
|
+
|
|
94
|
+
#### Scenario: Alias annotation present
|
|
95
|
+
|
|
96
|
+
- **WHEN** the model reads the `eval` description
|
|
97
|
+
- **THEN** it states that `subagent` is an alias of the `agent` delegation tool,两者经同一 runtime delegate
|
|
98
|
+
|
|
99
|
+
#### Scenario: Non-flat exception present
|
|
100
|
+
|
|
101
|
+
- **WHEN** the model reads the `eval` description
|
|
102
|
+
- **THEN** it states that 含非标识符字符(如连字符)的工具名没有 `tool.<name>` member,必须以 direct tool call 调用
|
|
103
|
+
|
|
104
|
+
### Requirement: Masking failures surface loudly
|
|
105
|
+
|
|
106
|
+
The system SHALL surface a structured error, not a silent skip, when restricting any masked tool name fails at session start;application 完成后 mask SHALL verify 每个 masked 名在 **the wire tools array 与 the REPL bindings** 中均不存在。
|
|
107
|
+
|
|
108
|
+
#### Scenario: A masked name's restriction errors and the session reports it
|
|
109
|
+
|
|
110
|
+
- **WHEN** applying the mask, a single masked name's registry restriction throws
|
|
111
|
+
- **THEN** the session surfaces the failure as a structured error naming the masked tool, and the name does not silently remain on any model-facing surface
|
|
112
|
+
|
|
113
|
+
#### Scenario: Masked names absent after successful application
|
|
114
|
+
|
|
115
|
+
- **WHEN** an agent session starts under DASHR with a healthy registry
|
|
116
|
+
- **THEN** the wire tools array 与 the REPL bindings contain none of the masked names(`skill`、`send_message`、`report`、`list_agents`、`subagent_fork`、`interrupt_agent`、`workflow`、`ralph`),and a call naming a masked tool returns `UNKNOWN_TOOL`
|
|
117
|
+
|
|
118
|
+
### Requirement: REPL bindings bridge the visible registry mechanically
|
|
119
|
+
The system SHALL install REPL bindings by automatic, transparent conversion of every flat-bindable name in the registry's visible set at session start — no manual allowlist or denylist; masked names are naturally absent because the binding source and the masking act on the same projection. Non-flat names SHALL be skipped — a name is non-flat when it contains characters outside `[A-Za-z0-9_]` (e.g. hyphens); a `__` infix alone is a legal identifier and does not by itself make a name non-flat — and the bridge instructions SHALL state the name-shape limitation without enumerating affected tools.
|
|
120
|
+
|
|
121
|
+
#### Scenario: A newly registered host tool appears in the REPL without list edits
|
|
122
|
+
- **WHEN** the host registers a new flat-named tool after a DASHR upgrade
|
|
123
|
+
- **THEN** the next agent session exposes it as `tool.<name>` with no DASHR source change
|
|
124
|
+
|
|
125
|
+
#### Scenario: Non-flat MCP names documented, not listed
|
|
126
|
+
- **WHEN** an MCP tool named `mcp__server__tool-name` is registered
|
|
127
|
+
- **THEN** no binding is created for it, and the bridge instructions explain the name-shape limitation
|
|
128
|
+
|
|
129
|
+
#### Scenario: Double-underscore infix alone stays bindable
|
|
130
|
+
- **WHEN** a tool named `mcp__server__tool` (identifier characters only, no hyphen) is registered
|
|
131
|
+
- **THEN** the name is flat-bindable (`'mcp__server__tool'.isidentifier()` is true) and appears as `tool.<name>` unless separately masked
|
|
132
|
+
|
|
133
|
+
### Requirement: llm_completion tool
|
|
134
|
+
The system SHALL provide an `llm_completion` tool: a one-shot, stateless LLM call — no tools, no conversation history, no agent creation. Inputs: `{ prompt, system?, maxTokens? }`; output: the model's text. The call SHALL be attributed to the calling agent's session through the normal tool-call audit (the host's auxiliary-purpose enum is closed and carries no completion class), SHALL honor the caller's abort signal, and SHALL resolve its model route from the calling agent's current model selection, and SHALL answer a structured error value — never a silent fallback route — when no selection is available. A finish other than a clean stop, or any tool-call block in the output, SHALL produce a structured error value, not a thrown exception.
|
|
135
|
+
|
|
136
|
+
#### Scenario: Zero-spawn judge step inside a cell
|
|
137
|
+
- **WHEN** a cell calls `await tool.llm_completion({ prompt: "<judge prompt>", system: "<rubric>" })`
|
|
138
|
+
- **THEN** the value returned is the model's text; no subagent is spawned, no session besides the caller's is created, and the call is auditable under its own purpose
|
|
139
|
+
|
|
140
|
+
#### Scenario: Model route follows the caller
|
|
141
|
+
- **WHEN** the calling agent's selected model differs from the host default
|
|
142
|
+
- **THEN** the completion runs on the caller's selection
|
|
143
|
+
|
|
144
|
+
#### Scenario: Degraded finish is a structured error
|
|
145
|
+
- **WHEN** the completion hits maxTokens or aborts
|
|
146
|
+
- **THEN** the tool returns `{ error: <description> }` rather than throwing
|
|
147
|
+
|
|
148
|
+
### Requirement: REPL tool namespace introspection
|
|
149
|
+
The system SHALL make the REPL `tool` namespace introspectable: `dir(tool)` returns the sorted list of bound tool names — exactly the names callable as `tool.<name>(argsObject)`. The underlying injected mapping (e.g. `__dashr_injected__`) remains unchanged for compatibility; `dir()` is the documented introspection surface.
|
|
150
|
+
|
|
151
|
+
#### Scenario: dir(tool) lists the binding set
|
|
152
|
+
- **WHEN** a cell runs `dir(tool)`
|
|
153
|
+
- **THEN** the returned list equals the sorted set of names bound in the `tool` namespace for that run (dunder members aside), including the delegation bridges and `llm_completion`
|
|
154
|
+
|
|
155
|
+
### Requirement: Hashline edit family registered on the agent's own layer
|
|
156
|
+
|
|
157
|
+
The system SHALL register the vendored hashline edit family on each agent's own scope layer at session start — `edit` (hash-anchored ordered edit tuples, shadowing the preset's built-in edit by nearest-layer resolution, no mask entry needed) and `undo_last_edit` (revert of the most recent hashline edit) — alongside the URL-aware read/write/grep/glob wrappers, unwinding with the agent. The write tool SHALL remain the upstream full-file write with its native confirmation envelope: no hook SHALL append a hashline preview to write results, and the hashline guidance SHALL NOT promise post-write anchors (the model MAY edit directly using anchors derived from the content it just wrote, or read first). The hashline guidance sections SHALL shadow the preset's built-in tool guidance on the same layer (compiled defaults when no agentPresets service or a failing override — never a failed install).
|
|
158
|
+
|
|
159
|
+
#### Scenario: A hash-anchored edit lands and is reversible
|
|
160
|
+
|
|
161
|
+
- **WHEN** the model calls `edit` with anchored edit tuples on a file whose current content matches the anchors
|
|
162
|
+
- **THEN** the edit applies atomically (drift-checked against current content), and a subsequent `undo_last_edit` reverts it
|
|
163
|
+
|
|
164
|
+
#### Scenario: A write result stays upstream-native
|
|
165
|
+
|
|
166
|
+
- **WHEN** the model calls `write` and it succeeds
|
|
167
|
+
- **THEN** the result content is the upstream confirmation envelope with no auto-read/anchor section appended, and no read is required before the next anchored `edit` on that file
|
|
168
|
+
|
|
169
|
+
#### Scenario: The shadow replaces the built-in edit without masking
|
|
170
|
+
|
|
171
|
+
- **WHEN** an agent session starts under DASHR
|
|
172
|
+
- **THEN** the `edit` the model sees is the hashline tool (own-layer shadow), the preset's built-in edit is unreachable for that agent, and no deny-list entry names `edit`
|
|
173
|
+
|
|
174
|
+
### Requirement: Lsp feedback rides edit results
|
|
175
|
+
The system SHALL attach the same write-feedback diagnostics contract to successful edits: after a landed `edit` with an explicit path, the result content carries the diagnostics summary computed from the exact landed content (didSave freshness, timeout degradation, span guard — the `dvc` write-feedback requirement's terms apply verbatim). Anchor-only edits (path inferred from anchors) and non-edit tools pass through untouched; the write tool's feedback stays with its wrapper (no double pull).
|
|
176
|
+
|
|
177
|
+
#### Scenario: An edit that introduces a type error reports it
|
|
178
|
+
- **WHEN** an edit lands content introducing a type error in a file with a language server and its check completes within the budget
|
|
179
|
+
- **THEN** the edit result text carries the diagnostics summary for the exact landed content
|
|
180
|
+
|
|
181
|
+
### Requirement: Hashline edit verification is content-anchored
|
|
182
|
+
|
|
183
|
+
The system SHALL verify each edit tuple's anchors against the CURRENT file content before consulting any ledger: an anchor SHALL be accepted when its hash locates a unique, consistently pairable position in the current canonical line hashes; the served ledger SHALL be advisory (echo/undo attribution) and keyed by canonical absolute path with no session identity, so anchors survive session-tree forks and continuation without a re-read. Genuine drift SHALL still fail closed with nothing written, batch atomicity SHALL be unchanged, and a multi-tuple batch failure SHALL instruct reading the file once and resubmitting the whole batch.
|
|
184
|
+
|
|
185
|
+
#### Scenario: An edit across a forked session lands without a re-read
|
|
186
|
+
|
|
187
|
+
- **WHEN** a file is written or read in one session node, the conversation continues in a forked node (new session identity), and the model submits anchored edit tuples derived from that earlier content
|
|
188
|
+
- **THEN** the edit applies without any intervening `read`, because verification matched current content
|
|
189
|
+
|
|
190
|
+
#### Scenario: A drifted line still fails closed
|
|
191
|
+
|
|
192
|
+
- **WHEN** an anchor's hash no longer exists in the current file (content changed or line removed externally)
|
|
193
|
+
- **THEN** the tuple is rejected with a drift error stating the content changed and a read is needed, and nothing is written
|
|
194
|
+
|
|
195
|
+
#### Scenario: An ambiguous anchor falls back before failing
|
|
196
|
+
|
|
197
|
+
- **WHEN** an anchor's hash occurs at multiple current positions and the served ledger cannot disambiguate the span
|
|
198
|
+
- **THEN** the tuple is rejected with nothing written, and the error names the ambiguity
|
|
199
|
+
|
|
200
|
+
#### Scenario: Multi-tuple failure copy is actionable
|
|
201
|
+
|
|
202
|
+
- **WHEN** any tuple in a multi-tuple batch fails verification
|
|
203
|
+
- **THEN** the batch aborts with zero writes and the error instructs reading the file once, then resubmitting the whole batch
|
|
204
|
+
|
|
205
|
+
### Requirement: Hashline store centralized under DSH_HOME
|
|
206
|
+
|
|
207
|
+
The hashline store SHALL live at a single location — `$DSH_HOME/storages/dsh-better-edit/hash-store.sqlite` — for tool calls, previews, and tests alike, resolved through the harness home resolver so `DSH_HOME` isolates deployments; no per-workspace dot-directory SHALL be created. The served table SHALL be keyed by canonical absolute path (no session column), the 7-day TTL prune SHALL be retained, and the store schema version SHALL bump with a rebuild-on-mismatch gate that drops and recreates legacy session-keyed served tables.
|
|
208
|
+
|
|
209
|
+
#### Scenario: No dot-directory is created
|
|
210
|
+
|
|
211
|
+
- **WHEN** hashline tools run inside any workspace
|
|
212
|
+
- **THEN** state lands in the centralized store and no `<workspace>/.dsh_better_edit/` directory is created
|
|
213
|
+
|
|
214
|
+
#### Scenario: DSH_HOME isolates deployments
|
|
215
|
+
|
|
216
|
+
- **WHEN** the harness runs with a test `DSH_HOME` (e.g. the 4999 line)
|
|
217
|
+
- **THEN** its hashline store is a separate file under that home and never touches the production store
|
|
218
|
+
|
|
219
|
+
#### Scenario: Legacy session-keyed served tables rebuild
|
|
220
|
+
|
|
221
|
+
- **WHEN** the store opens with a schema version below the current one, or a served table still carrying a `session_id` column
|
|
222
|
+
- **THEN** the served table is dropped and recreated with the path-keyed schema, and the version marker is updated
|