better-dsh 0.3.1 → 0.3.2
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/README.md +6 -5
- package/cordis.patch.yml +14 -9
- package/docs/20_specs/kernel-provisioning/spec.md +2 -0
- package/docs/remote-tools.md +15 -9
- package/docs/specs/kernel-provisioning/spec.md +12 -40
- package/docs/specs/omp-python-repl-port/runtime-guide.md +3 -1
- package/docs/specs/omp-python-repl-port/spec.md +7 -0
- package/docs/specs/remote-pty-label/spec.md +2 -0
- package/docs/specs/remote-tool-enhancement/spec.md +1 -0
- package/lib/BrowserWebSocketTransport.js +4 -0
- package/lib/{BrowserWebSocketTransport-wm99h94r.js → BrowserWebSocketTransport2.js} +1 -1
- package/lib/LaunchOptions.js +4 -0
- package/lib/{LaunchOptions-5eg7E0ye.js → LaunchOptions2.js} +1 -1
- package/lib/{NodeWebSocketTransport-D9ysYGLM.js → NodeWebSocketTransport.js} +2 -2
- package/lib/NodeWebSocketTransport2.js +4 -0
- package/lib/{bidi-CwabFH07.js → bidi.js} +4 -4
- package/lib/client/index.js +59 -6
- package/lib/compaction/index.d.ts +1 -1
- package/lib/compaction/index.js +1 -1
- package/lib/failover/index.d.ts +1 -1
- package/lib/failover/index.js +1 -1
- package/lib/fs-aware/sandbox-plugin.js +1 -1
- package/lib/{index-browser-B-9jm12n.js → index-browser.js} +6 -6
- package/lib/index.d.ts +2 -12
- package/lib/index.js +58 -62
- package/lib/kernel-env.d.ts +5 -15
- package/lib/kernel-env.js +2 -2
- package/lib/kernel-env2.js +76 -0
- package/lib/{lsp-server-registry-BcdkHROD.js → lsp-server-registry2.js} +1 -1
- package/lib/{main-BeCgUd20.js → main.js} +1 -1
- package/lib/{main-Dv_UQqG2.js → main2.js} +1 -1
- package/lib/mobile/plugin.d.ts +2 -2
- package/lib/mobile/plugin.js +2 -2
- package/lib/{puppeteer-core-Dnd7eqel.js → puppeteer-core.js} +9 -9
- package/lib/py-sdk.js +1 -1
- package/lib/remote/helper-bin/MANIFEST.json +35 -0
- package/lib/remote/helper-bin/aarch64-apple-darwin/BUILT-VER +1 -0
- package/lib/remote/helper-bin/aarch64-apple-darwin/superd-run +0 -0
- package/lib/remote/helper-bin/aarch64-unknown-linux-musl/BUILT-VER +1 -0
- package/lib/remote/helper-bin/aarch64-unknown-linux-musl/superd-run +0 -0
- package/lib/remote/helper-bin/x86_64-pc-windows-gnu/BUILT-VER +1 -0
- package/lib/remote/helper-bin/x86_64-pc-windows-gnu/superd-run.exe +0 -0
- package/lib/remote/helper-bin/x86_64-unknown-linux-musl/BUILT-VER +1 -0
- package/lib/remote/helper-bin/x86_64-unknown-linux-musl/superd-run +0 -0
- package/lib/remote/plugin.d.ts +172 -51
- package/lib/remote/plugin.js +2168 -718
- package/lib/url-schemes/index.d.ts +11 -11
- package/lib/url-schemes/index.js +12 -12
- package/lib/{wasm_bg-CNXhHjVg.js → wasm_bg.js} +1 -1
- package/lib/web-password.d.ts +7 -7
- package/lib/web-password.js +1 -1
- package/lib/web-trust.d.ts +1 -1
- package/lib/web-trust.js +2 -2
- package/lib/{web-trust-D6gJpUMf.js → web-trust2.js} +20 -8
- package/lib/welcome-notice.js +1 -1
- package/package.json +4 -4
- package/scripts/kernel-check.mjs +5 -0
- package/lib/BrowserWebSocketTransport-D1aFReu_.js +0 -4
- package/lib/LaunchOptions-DxQQ0s-A.js +0 -4
- package/lib/NodeWebSocketTransport-BRLjmu2R.js +0 -4
- package/lib/kernel-env-BOF0fNHn.js +0 -91
- package/scripts/kernel-provision.mjs +0 -5
- /package/lib/{chunk-DQxbwPpZ.js → chunk.js} +0 -0
- /package/lib/{index-DTDXUe6m.d.ts → index2.d.ts} +0 -0
- /package/lib/{lib-C8_jXvwA.js → lib.js} +0 -0
- /package/lib/{lsp-server-registry-D4VLs1Sm.js → lsp-server-registry.js} +0 -0
- /package/lib/{native-capture-BEByDXYM.js → native-capture.js} +0 -0
- /package/lib/{py-sdk-D7klhpWb.js → py-sdk2.js} +0 -0
- /package/lib/{util-BHL_dfV_.js → util.js} +0 -0
- /package/lib/{web-tree-sitter-CPrPD4J2.js → web-tree-sitter.js} +0 -0
- /package/lib/{web-trust-CwZrTBcl.d.ts → web-trust2.d.ts} +0 -0
- /package/lib/{wrap-0VA0uFx8.js → wrap.js} +0 -0
package/README.md
CHANGED
|
@@ -18,7 +18,11 @@ Super Dash installs Better as a separate native bundle. `../dev-webmcp` is a dev
|
|
|
18
18
|
npm install better-dsh
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
Better uses an existing Python interpreter. An explicit `python` setting (or `DASHR_KERNEL_PYTHON`) takes precedence; otherwise discovery checks the active virtual/Conda environment, an existing workspace `.venv` or `venv`, then PATH `python3` and `python`. Candidates are actually probed, and a broken automatically discovered candidate does not hide a working fallback. Relative explicit paths resolve against the session workspace. No CPython implementation or Python3.11 version is selected. The packaged dill0.4.1 checkpoint helper requires Python >=3.9.
|
|
22
|
+
|
|
23
|
+
Better does not install Python, invoke uv/pip, or create a virtual environment. When none of the existing candidates works, the error lists the attempts and asks for an existing interpreter or a Python installation. `npm run kernel:check` checks availability without changing the environment. The runner and dill sources ship in the package; runtime checkpoints belong under the native profile home, and package upgrades do not require rebuilding a package-local Python environment.
|
|
24
|
+
|
|
25
|
+
The old `kernelEnvDir`, `kernelPythonVersion` and `kernelAutoInstall` provisioning fields and `kernel:venv` command are removed. Existing package-local `.venv-kernel` / `.uv-cache` directories are no longer selected automatically or modified; an existing interpreter can still be selected explicitly. A checkpoint made with another interpreter/environment may be incompatible and produces the usual explicit recovery notice; it is never replayed into a new environment.
|
|
22
26
|
|
|
23
27
|
The original OMP runner's source commit/hash and MIT license, and dill's source hashes/version and BSD-3-Clause license, accompany the packaged resources. Better's integration code is separate from these original files. OMP-specific Agent helpers are not exposed as DSH features.
|
|
24
28
|
|
|
@@ -28,7 +32,7 @@ Runtime fields remain configurable through the ordinary Cordis row. The implemen
|
|
|
28
32
|
|
|
29
33
|
| Field | Default | Meaning |
|
|
30
34
|
| --- | --- | --- |
|
|
31
|
-
| `python` |
|
|
35
|
+
| `python` | automatic discovery | Existing executable name/path; explicit selection bypasses discovery. |
|
|
32
36
|
| `startupTimeoutMs` | `30000` | Budget for child startup and initialization. |
|
|
33
37
|
| `runTimeoutMs` | `120000` | Wall budget per user cell. |
|
|
34
38
|
| `interruptGraceMs` | `2000` | Grace after an interrupt before terminating an unresponsive child. |
|
|
@@ -38,9 +42,6 @@ Runtime fields remain configurable through the ordinary Cordis row. The implemen
|
|
|
38
42
|
| `maxOutputBytes` | `67108864` | Cap for serialized logs, completion and error output; overflow is reported. |
|
|
39
43
|
| `snapshotDir` | native profile checkpoint directory | Explicit directory overrides the native profile default; `""` disables persistence and retains only live process state. Standalone runtimes must explicitly configure persistence. |
|
|
40
44
|
| `snapshotSizeCapBytes` | `268435456` | Checkpoint payload cap; failed or over-cap saves preserve the previous committed generation. |
|
|
41
|
-
| `kernelEnvDir` | `<package>/.venv-kernel` | Managed environment location used by the `python3` compatibility selection. |
|
|
42
|
-
| `kernelPythonVersion` | `3.11` | Interpreter version requested from uv for a new managed environment. |
|
|
43
|
-
| `kernelAutoInstall` | `true` | Allow creation of the managed environment on first use. |
|
|
44
45
|
| `username` | `dashr` | Retained compatibility field. |
|
|
45
46
|
|
|
46
47
|
## Cells and recovery
|
package/cordis.patch.yml
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
- id: dashr-repl
|
|
22
22
|
name: 'better-dsh'
|
|
23
23
|
config:
|
|
24
|
-
python: !!js process.env.DASHR_KERNEL_PYTHON
|
|
24
|
+
python: !!js process.env.DASHR_KERNEL_PYTHON
|
|
25
25
|
|
|
26
26
|
# URL-aware I/O + hashline + devices. Gates ride THIS row's config
|
|
27
27
|
# (schema defaults: both ON — opt-out), no longer the core row's.
|
|
@@ -90,17 +90,22 @@
|
|
|
90
90
|
# dsh-web-app bundle declares (same id), restating its full shape per the
|
|
91
91
|
# patch-layer contract, with `trustedHosts` merging the DSH_TRUSTED_HOSTS
|
|
92
92
|
# environment (whitespace-separated, operator-declared serving authorities)
|
|
93
|
-
# ahead of the upstream
|
|
94
|
-
#
|
|
95
|
-
#
|
|
96
|
-
# (
|
|
97
|
-
#
|
|
98
|
-
#
|
|
93
|
+
# ahead of the upstream invocation authorities. Since DSH 0.1.7 the parsed
|
|
94
|
+
# Web flags live on the `webStartup` service and every host in the declared
|
|
95
|
+
# peer range provides it, so the row injects webStartup and reads
|
|
96
|
+
# `ctx.webStartup.trustedHosts` (the --trusted-host values) — the 0.2.1+
|
|
97
|
+
# upstream row's own source; on pre-0.2.1 hosts this drops only the LAN
|
|
98
|
+
# literals an all-interface bind used to derive (wildcard binds are rejected
|
|
99
|
+
# there too, and this repo's lines always declare authorities explicitly).
|
|
100
|
+
# Unset/empty env ⇒ identical behavior to the unpatched row. Malformed entries
|
|
101
|
+
# fail plugin load loudly (upstream assertTrustedAuthority). The browser-side
|
|
102
|
+
# twin (page-authority loopback verdict) is the plugin's
|
|
103
|
+
# webserver/index-inject boot script — see src/web-trust.ts.
|
|
99
104
|
- id: connection
|
|
100
105
|
name: '@deepseek-ai/dsh-client-connection'
|
|
101
|
-
inject: [
|
|
106
|
+
inject: [webStartup]
|
|
102
107
|
config:
|
|
103
|
-
trustedHosts: !!js (process.env.DSH_TRUSTED_HOSTS ?? '').split(/\s+/).filter(Boolean).concat(ctx.
|
|
108
|
+
trustedHosts: !!js (process.env.DSH_TRUSTED_HOSTS ?? '').split(/\s+/).filter(Boolean).concat(ctx.webStartup.trustedHosts)
|
|
104
109
|
|
|
105
110
|
- id: ui-settings-models
|
|
106
111
|
name: '@deepseek-ai/dsh-client-ui-settings-models'
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# kernel-provisioning Specification
|
|
2
2
|
|
|
3
|
+
> Historical iKernel contract, superseded on2026-10-12. Do not apply the provisioning requirements below to current Better. The active [existing-interpreter discovery contract](../../specs/kernel-provisioning/spec.md) removes uv/pip provisioning,3.11 selection and package-local venv creation.
|
|
4
|
+
|
|
3
5
|
## Purpose
|
|
4
6
|
better-dsh 的 REPL kernel(IPython)供给契约:独占 managed venv(插件包目录内,`kernelEnvDir` 可显式覆盖)、版本锁定(ipykernel 7.3.0 / dill 0.4.1,uv 与 pip 双路径)、三级触发供给(postinstall 加速器 / daemon spin-up 主路径 / 首用 lazy 兜底)全 fail-open 且幂等、供给状态可观测;npm 包不内嵌预建 venv(供给能力随包,供给结果不随包)。
|
|
5
7
|
|
package/docs/remote-tools.md
CHANGED
|
@@ -8,21 +8,27 @@ Better Dash and Super Dash each provide the native `remote` tool and REPL route.
|
|
|
8
8
|
| --- | --- |
|
|
9
9
|
| List locally known targets without dialing | `{}` |
|
|
10
10
|
| Probe one target | `{target:"ssh:alias"}` |
|
|
11
|
-
| Register an Agent-local SSH identity | `{target:"
|
|
12
|
-
| Stateless command and stdin | `{target:"
|
|
13
|
-
| Stream a local script to fixed `bash -s` | `{target:"ssh:alias",
|
|
14
|
-
|
|
|
15
|
-
|
|
|
11
|
+
| Register an Agent-local SSH identity (no dialing) | `{target:"ssh:build",ssh:{host:"host",user:"user",key:"/origin/key"}}`; omit `target` for an auto id (`ssh-xxxx`) |
|
|
12
|
+
| Stateless command and stdin over an identity | `{target:"ssh:build",cmd:"cat",stdin:"hello"}` |
|
|
13
|
+
| Stream a local script to fixed `bash -s` | `{target:"ssh:alias",scriptPath:"/absolute/script.sh"}` |
|
|
14
|
+
| Create a persistent shell (tab semantics) | `{target:"ssh:alias:pty",cmd:"cd /tmp; export CHECK=ready"}`; append `:label` (`ssh:alias:pty:build`) to name it |
|
|
15
|
+
| Reuse a persistent shell | `{target:"pty:<id\|label>",cmd:"…"}` |
|
|
16
|
+
| Session card (state + ledger, no command) | `{target:"pty:<id\|label>"}` |
|
|
17
|
+
| Create a BYO PTY from a spawn command | `{spawn:"docker exec -it img bash",target:"pty:build",cmd:"…"}`; later `{target:"pty:build",cmd:"…"}` |
|
|
18
|
+
| Background job (oneshot or PTY) | `{target:"ssh:alias",cmd:"long-command",run_in_background:true}` |
|
|
19
|
+
| Close a PTY session | `{action:"close",target:"pty:<id\|label>",force:true}` |
|
|
16
20
|
| Native CLI copy | `{action:"copy",src:"/absolute/source",dst:"ssh:alias:/absolute/destination",argv:["-p"]}` |
|
|
17
21
|
| Native rsync | `{action:"rsync",src:"/absolute/source/",dst:"ssh:alias:/existing/destination/",argv:["-a","--partial","--dry-run"]}` |
|
|
18
22
|
|
|
19
|
-
`
|
|
23
|
+
`mode` no longer exists: append `:pty` to a transport target to create, address a live shell as `pty:<id|label>`. `scriptPath` cannot combine with cmd/stdin/spawn/PTY. Direct local command execution is not provided; use native local shell tools. Background jobs require the official jobs service/controller and are read/killed with `job_output`/`job_kill`; on PTY lanes a background job's jobId is the commandId (a timeout handoff keeps them as separate ledger fields). SSH keys/config stay on the origin; BYO identities are not persisted across new/cold Agents. PTY backlog recovery and live probes are not part of this release.
|
|
24
|
+
|
|
25
|
+
PTY state is durable and readable: every dispatch returns exit, cwd and `envDelta` (variable names and change markers only — values never leave the endpoint; fetch them yourself if needed). `close` is idempotent (`closed:false, reason:"not-found"|"already-closed-or-reaped"`); a session with a running job refuses close unless `force:true`, which kills the group and reports `killed`. A busy session rejects new commands instead of queueing; open another PTY or use a oneshot. Idle PTYs are reaped after 15 minutes; an Agent holds at most 10 live sessions across connections, and dead sessions do not count. `hub:<m4>:pty` selects the Hub lane's PTY but exposes no session id, label, parallelism or background works there.
|
|
20
26
|
|
|
21
27
|
Native/PTY output retains at most 4,000,000 UTF-16 units per stream; Hub oneshot retains 4 MiB bytes. Normal returned tails are smaller. Read `outputStats` units and dropped/returned counters rather than treating character counts as bytes. Discarded output is not recoverable after restart.
|
|
22
28
|
|
|
23
29
|
## File operations: native CLI semantics
|
|
24
30
|
|
|
25
|
-
`remote` addresses targets once (`ssh:<name>`, `
|
|
31
|
+
`remote` addresses targets once (`ssh:<name>`, `ssh:<label>` for a BYO identity, `docker:<name>`, `incus:<name>`, `hub:<machine>`, local paths) and hands the actual transfer to the native CLI. `argv` is an ordered array of native option tokens — one element = one argv token, appended verbatim before the parsed `src`/`dst`. There is no option whitelist, no shell parsing, and no forced defaults: no hidden `--dry-run`, no forced archive/timeout, no automatic verification. A dry run means passing `--dry-run` yourself; unknown or incompatible options fail in the native CLI and its exit code and stderr come back as-is. Success of a native command is never reported as independently verified — `verified:false` on native copy receipts means exactly that.
|
|
26
32
|
|
|
27
33
|
### copy routes
|
|
28
34
|
|
|
@@ -39,7 +45,7 @@ The native CLIs do not create destination parents or verify results on their own
|
|
|
39
45
|
|
|
40
46
|
### rsync routes
|
|
41
47
|
|
|
42
|
-
rsync supports SSH
|
|
48
|
+
rsync supports SSH endpoints (native aliases and BYO identities) with at most one local endpoint. Local↔SSH runs `rsync` on the origin with the endpoint's SSH identity wired through `RSYNC_RSH`; an explicit `-e`/`--rsh` in `argv` replaces that wiring per rsync's own rules (the command must then carry its own port/key/config). Nothing else is injected — no archive, no timeout, no dry-run, no remote owner, no `--rsync-path`.
|
|
43
49
|
|
|
44
50
|
SSH↔SSH prefers the native forwarding route: the destination runs a temporary loopback-only rsync daemon, `ssh -L` brings it to an origin port, `ssh -R` carries it onto the source's loopback, and the source's own native rsync client performs one protocol conversation through the chain. The origin only forwards rsync protocol bytes; the destination's existing file data feeds real delta matching (`--stats` shows Matched data dominating for a small change on a large file). If an endpoint refuses TCP forwarding (`AllowTcpForwarding no`), a standard-stream route would be attempted; on the current OpenSSH/rsync combination (10.2 / 3.4.1) that route reports itself unavailable — the error says so and nothing is copied. rsync never falls back to a full copy or to Python.
|
|
45
51
|
|
|
@@ -51,6 +57,6 @@ File operations require the corresponding CLI on the origin (`scp`, `rsync`, `do
|
|
|
51
57
|
|
|
52
58
|
## One-shot command requirements
|
|
53
59
|
|
|
54
|
-
One-shot SSH
|
|
60
|
+
One-shot SSH commands (native alias or BYO identity; foreground, background, scriptPath and literal stdin) run through ONE native SSH exec: the command executes under bash with a small POSIX wrapper whose TERM/HUP trap kills the command's whole process group, so backgrounded children do not outlive the session teardown. Remote prerequisites: bash (POSIX) — **no Python, no owner/lease protocol, no flock/monotonic clock, no extra sessions**. On normal completion the wrapper's EXIT trap reaps the command's whole process group (backgrounded children included — they neither outlive the call nor hold the channel open), and the exit code passes through verbatim. On timeout/cancellation the local transport dies at once and a dedicated cleanup session reads the pidfile the wrapper left and kills the group (TERM→KILL); sshd delivers no signal to a no-PTY session, so this explicit cleanup is the remote kill path.
|
|
55
61
|
|
|
56
62
|
Docker/Incus one-shots use the same pure-CLI lane (`docker exec` / `incus exec` with the same wrapper); container prerequisites are the container's own bash. PTY paths are unchanged (`ssh -tt bash`, docker via script(1), incus interactive) and never required Python.
|
|
@@ -1,53 +1,25 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Existing Python interpreter discovery
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
better-dsh 的 REPL kernel(IPython)供给契约:独占 managed venv(插件包目录内,`kernelEnvDir` 可显式覆盖)、版本锁定(ipykernel 7.3.0 / dill 0.4.1,uv 与 pip 双路径)、三级触发供给(postinstall 加速器 / daemon spin-up 主路径 / 首用 lazy 兜底)全 fail-open 且幂等、供给状态可观测;npm 包不内嵌预建 venv(供给能力随包,供给结果不随包)。
|
|
3
|
+
Updated 2026-10-12 by explicit user correction. This replaces the former iKernel managed-provisioning contract. Execution and recovery are specified in [OMP Python REPL](../omp-python-repl-port/spec.md); consumer behavior is in its [runtime guide](../omp-python-repl-port/runtime-guide.md).
|
|
5
4
|
|
|
6
5
|
## Requirements
|
|
7
6
|
|
|
8
|
-
###
|
|
7
|
+
### Existing interpreters only
|
|
9
8
|
|
|
10
|
-
|
|
9
|
+
Better SHALL run an existing Python interpreter. It SHALL NOT invoke uv/pip, download Python, create or repair a virtual environment, or place Python environment/cache state in the installed npm package. No CPython implementation or Python3.11 preference is applied. The packaged dill0.4.1 checkpoint helper requires Python >=3.9.
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
### Explicit selection
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
- **THEN** the venv root is inside the plugin's package directory (or the explicitly configured `kernelEnvDir`), and no file outside that territory is required for kernel operation
|
|
13
|
+
An explicit `python` executable name/path SHALL bypass automatic discovery. Bare `python3` is an explicit executable name, not a provisioning sentinel. Relative paths SHALL resolve against the session workspace and `~/` against the user's home. An unusable explicit selection SHALL report the actual failure without silently substituting another interpreter. Existing explicit virtual environments SHALL receive their activation environment.
|
|
16
14
|
|
|
17
|
-
|
|
15
|
+
### Automatic discovery
|
|
18
16
|
|
|
19
|
-
|
|
20
|
-
- **THEN** no package is installed into, and no configuration of, the user's global environment is modified
|
|
17
|
+
Without explicit selection, Better SHALL probe an existing active virtual/Conda environment or workspace `.venv`/`venv`, then PATH `python3` and `python`. A broken automatically discovered candidate SHALL permit a working fallback without repair. Resolved executable identity and activation environment SHALL reach the spawned child. One session's project interpreter SHALL NOT be cached as the choice for another workspace.
|
|
21
18
|
|
|
22
|
-
###
|
|
19
|
+
### Readiness and failure
|
|
23
20
|
|
|
24
|
-
|
|
21
|
+
Availability is checked when the session needs its Python child. Plugin mounting SHALL NOT provision an environment. With no working candidate, the error SHALL identify attempted interpreters and explain how to install Python or configure an existing executable. `npm run kernel:check` SHALL perform discovery only, with no installation side effects.
|
|
25
22
|
|
|
26
|
-
|
|
23
|
+
### Runtime state and migration
|
|
27
24
|
|
|
28
|
-
|
|
29
|
-
- **THEN** provisioning succeeds using the redirected cache location
|
|
30
|
-
|
|
31
|
-
#### Scenario: Pinned versions installed
|
|
32
|
-
|
|
33
|
-
- **WHEN** provisioning creates or repairs the venv
|
|
34
|
-
- **THEN** the installed `ipykernel` and `dill` match the pinned tested versions, verifiable by the kernel probe
|
|
35
|
-
|
|
36
|
-
### Requirement: Provisioning ladder — install-time, daemon spin-up, first-use
|
|
37
|
-
|
|
38
|
-
The plugin SHALL provision the kernel through a three-trigger ladder converging on the same managed venv, every trigger fail-open (a failure or suppression at any level degrades to a logged status message and NEVER blocks package installation, daemon startup, or plugin mounting, and never asks the user for approval): (1) an install-time postinstall best-effort step that runs only when the package manager executes build scripts; (2) a daemon spin-up check as the PRIMARY path — when the plugin is brought up on the host plane by the host daemon, it asynchronously verifies the kernel environment and provisions it immediately when absent (uv → `python3 -m venv` → explicit configuration), so an agent session never discovers a missing kernel at first use; (3) first-use lazy provisioning as the final fallback. Provisioning status (provisioning/ready/degraded/failed) SHALL be logged, and failure messages MUST name the available remedies (`npm run kernel:venv`, `kernelAutoInstall`, explicit `python`).
|
|
39
|
-
|
|
40
|
-
#### Scenario: Daemon spin-up provisions before any agent session
|
|
41
|
-
|
|
42
|
-
- **WHEN** the host daemon starts and brings the plugin up on the host plane, and the managed venv is absent
|
|
43
|
-
- **THEN** the plugin asynchronously provisions the kernel within the spin-up window without blocking daemon startup or plugin mounting, and a new agent session's first REPL cell finds the kernel already in place
|
|
44
|
-
|
|
45
|
-
#### Scenario: Suppressed postinstall still reaches a working kernel
|
|
46
|
-
|
|
47
|
-
- **WHEN** the package manager skips the plugin's postinstall script and the daemon later starts
|
|
48
|
-
- **THEN** the spin-up check provisions the kernel and REPL cells execute, with the install itself never having failed and no approval ever having been requested
|
|
49
|
-
|
|
50
|
-
#### Scenario: Failure is non-blocking and visible
|
|
51
|
-
|
|
52
|
-
- **WHEN** provisioning fails on a constrained host at any trigger
|
|
53
|
-
- **THEN** the installation, daemon startup, and plugin mounting all succeed; the surfaced error names the concrete remedy commands/configuration paths
|
|
25
|
+
Checkpoints SHALL remain under the native profile home (or explicitly configured snapshot directory), isolated by profile/session. Old `kernelEnvDir`, `kernelPythonVersion`, `kernelAutoInstall` fields and `kernel:venv` command are removed. Existing package-local `.venv-kernel`/`.uv-cache` files SHALL be left untouched and SHALL NOT be selected automatically. An interpreter/environment change SHALL pass the existing checkpoint compatibility checks and report incompatible recovery explicitly; no user cell is replayed.
|
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
Implementation and acceptance are tracked in the [plan](../../superpowers/plans/2026-10-12-omp-python-repl-port.md). The [spec](spec.md) defines the recovery boundary; this guide explains the consumer contract being implemented.
|
|
4
4
|
|
|
5
|
-
Better runs a persistent Python child for each DSH session. Node communicates with an unchanged, pinned OMP runner over JSON lines. Better owns tool bindings, cancellation, output mapping and checkpoint management.
|
|
5
|
+
Better runs a persistent Python child for each DSH session. Node communicates with an unchanged, pinned OMP runner over JSON lines. Better owns tool bindings, cancellation, output mapping and checkpoint management. Interpreter discovery reuses an explicitly configured interpreter, otherwise an active/project environment then PATH `python3` or `python`. It probes candidates and falls back from broken automatically discovered environments; it never invokes uv/pip, installs Python or creates a venv. Explicit relative paths and project environments resolve against the session workspace. Python >=3.9 is required by the packaged dill0.4.1 checkpoint helper; no3.11 or CPython implementation is selected. Better ships the Python runner and dill 0.4.1 source. It does not install Jupyter, IPython, ZeroMQ or dill into the consumer's interpreter. OMP's Agent-specific prelude is not exposed as a DSH feature.
|
|
6
6
|
|
|
7
7
|
Variables, functions, classes and imports remain available across cells while the child lives. Top-level await works; a top-level return is invalid. The final expression supplies the completion value and print supplies logs. Host tools remain callable with `await tool.<name>({...})`. Internal initialization and checkpoint cells do not appear as user results or user scratchpad variables.
|
|
8
8
|
|
|
9
9
|
`tool.read` forwards to the current DSH native read tool with its usual permissions, scheduling and results. Better supplies the call-site helper required by OMP's compiler without enabling OMP speculative reads. Interactive `input()` is unsupported and returns an actionable error. Output uses the existing text/log/result contract; a nontext-only display produces an explicit MIME notice.
|
|
10
10
|
|
|
11
|
+
`npm run kernel:check` checks existing interpreter availability without provisioning. Legacy provisioning fields `kernelEnvDir`, `kernelPythonVersion`, `kernelAutoInstall` and the `kernel:venv` command are removed. Old package-local environments/caches are left untouched and are not auto-selected. An interpreter change may make existing checkpoints incompatible; recovery reports that condition explicitly.
|
|
12
|
+
|
|
11
13
|
## Checkpoint boundary
|
|
12
14
|
|
|
13
15
|
In a native DSH profile, checkpoints belong under that profile's resolved DSH home and are isolated by profile and session. An explicitly configured checkpoint directory takes precedence; `snapshotDir: ""` disables persistence and leaves process-local state only. A standalone runtime without a native profile must explicitly choose a checkpoint directory.
|
|
@@ -59,3 +59,10 @@ Best effort 不应退回普通标准库 `pickle`,否则对 REPL 函数、闭
|
|
|
59
59
|
5. 资源句柄、网络连接和其他进程副作用始终超出承诺;用户代码应能检测和重建这些资源。
|
|
60
60
|
|
|
61
61
|
因此,第二阶段的目标是“尽可能恢复模型的 Python scratchpad 变量,并准确报告缺口”,不是恢复整个 Python 进程。是否加这一阶段,不影响先完成 OMP 执行链移植与去除 Jupyter/ZMQ 依赖。
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
## 2026-10-12 interpreter discovery correction
|
|
65
|
+
|
|
66
|
+
After the0.3.1 release, user rejected retaining the old iKernel-era uv/3.11 provisioning path and package-local venv. The correction reuses an explicitly configured interpreter; otherwise it probes an existing active/project environment and PATH `python3` then `python`. A broken automatic candidate may fall back; a broken explicit selection is reported. Relative paths/project environments belong to the session workspace. No interpreter is downloaded, no uv/pip process is launched, and no venv or cache is created in the installed package. Original OMP/dill resources and checkpoint ownership remain unchanged. Packaged dill0.4.1 has a Python >=3.9 support floor; there is no3.11 or CPython implementation preference.
|
|
67
|
+
|
|
68
|
+
Legacy provisioning fields and command are removed, replaced by a read-only `kernel:check`. Existing old environment files are left untouched. Interpreter/environment changes may invalidate old checkpoints and must produce an explicit recovery notice. Delivery and target acceptance are recorded in [environment correction report](../../test-reports/2026-10-12-python-environment-discovery.md). This correction has separate test artifacts and does not authorize an npm release.
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# remote-pty-label Specification
|
|
2
2
|
|
|
3
|
+
> **Superseded(2026-10-19)**:本 spec 的 `byop:<label>` 入口、`mode` 锁定、`p:<label>` 池键与「同 label 复用」语义已被 [PTY Workbench v2 计划](../../superpowers/plans/2026-10-19-pty-workbench.md) 取代:BYO-PTY 并入 `pty:` selector(`spawn` 在场 = BYO)、`byossh:`/`byop:` 前缀移除、`mode` 字段移除且未知参数不强制拒绝、label 与机器名统一池、id 为 `pty-xxxx` / `ssh-xxxx`。下文保留为历史契约参照。
|
|
4
|
+
|
|
3
5
|
## Purpose
|
|
4
6
|
|
|
5
7
|
`remote` 工具的持久化 BYO-PTY 通道从「`spawn` 命令原文即会话键」改为「`target` 选择器寻址的具名会话」。旧实现的池键就是整条 spawn 文本,于是「同一条命令」与「同一个会话」被绑死:改一个 token 就**静默**新开一个 shell(cwd/env 全丢、零提示),roster 又拿整整一条 shell 命令当会话名。本规格固定新契约——`byop:<label>` 是唯一入口、label 由调用方(模型)自选并因此成为复用入口、`spawn` 降格为该 label 首次创建时的伴生参数——并据此定义创建/复用/冲突三分支、失败面,以及裸名候选表的末位新增项。
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
- 日期:2026-10-10(Asia/Hong_Kong)
|
|
4
4
|
- 状态:2026-10-10 user 已审阅并明确授权执行;Task0–7 已独立审阅通过;Task8 完整双包消费者验收进行中,L 实装暴露的 worker/SSH cleanup 缺陷已进入修复验证。用户亲验与发布尚未放行。
|
|
5
|
+
- 0.3.2-b 对齐(2026-10-19):`script` 已定名 `scriptPath`;`mode` 字段已移除(用 `<transport>:pty[:label]` 创建、`pty:<id|label>` 复用);`byossh:`/`byop:` 前缀已移除(`ssh`/`spawn` 参数在场即 BYO)。下文旧调用形仅作历史。
|
|
5
6
|
- 输入:[2026-10-09 方向稿](../../10_plans/2026-10-09-remote-tool-optimization-directions.md)及 2026-10-10 会话裁决。
|
|
6
7
|
- 执行计划:[2026-10-10-remote-tool-enhancement.md](../../superpowers/plans/2026-10-10-remote-tool-enhancement.md)。本规格优先于方向稿的冲突条款。
|
|
7
8
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as __require, r as __toESM, t as __commonJS } from "./chunk
|
|
2
|
-
import { D as packageVersion, o as debugCatchError } from "./util
|
|
1
|
+
import { n as __require, r as __toESM, t as __commonJS } from "./chunk.js";
|
|
2
|
+
import { D as packageVersion, o as debugCatchError } from "./util.js";
|
|
3
3
|
|
|
4
4
|
//#region node_modules/ws/lib/constants.js
|
|
5
5
|
var require_constants = /* @__PURE__ */ __commonJS({ "node_modules/ws/lib/constants.js": ((exports, module) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { n as __require } from "./chunk
|
|
2
|
-
import { A as stringToTypedArray, G as first, H as delayWhen, K as firstValueFrom, L as combineLatest, M as assert, Q as map, S as timeout, St as debug, Tt as environment, V as defer, W as filter, at as race, b as isString, bt as TouchError, c as evaluationString, d as fromEmitterEvent, g as isDate, gt as ProtocolError, h as getSourceUrlComment, ht as ConnectionClosedError, i as SOURCE_URL_REGEX, k as stringToBase64, lt as switchMap, m as getSourcePuppeteerURLIfAvailable, o as debugCatchError, ot as raceWith, q as from, r as PuppeteerURL, rt as of, s as debugError, u as fromAbortSignal, v as isPlainObject, vt as TargetCloseError, x as parsePDFOptions, xt as UnsupportedOperation, y as isRegExp, yt as TimeoutError } from "./util
|
|
3
|
-
import { $n as Deferred, $t as scriptInjector, Bt as throwIfDetached, Ct as WebWorkerEvent, Dn as DeviceRequestPrompt, Dt as normalizeHeaderValue, Fn as Browser, Hn as DisposableStack, Ht as bindIsolatedHandle, In as WEB_PERMISSION_TO_PROTOCOL_PERMISSION, It as Dialog, Jn as CallbackRegistry, Kn as disposeSymbol, Ln as CDPSession, Lt as Accessibility, Mn as invokeAtMostOnceForArguments, Mt as InterceptResolutionAction, Nn as throwIfDisposed, Nt as STATUS_TEXTS, On as BrowserContext, Ot as SecurityDetails, Pt as handleError, Rt as Frame, St as WebWorker, Ut as JSHandle, Vt as ElementHandle, Zn as isErrorLike, _t as Mouse, an as stringifyFunction, cn as Tracing, dt as ConsoleMessage, en as ARIAQueryHandler, fn as Coverage, gt as Keyboard, ht as TargetType, in as interpolateFunction, jn as inertIfDisposed, jt as HTTPRequest, kn as bubble, kt as HTTPResponse, mn as Page, mt as Target, nn as LazyArg, on as AsyncIterableUtil, sn as FileChooser, un as EmulationManager, vt as MouseButton, wt as Realm, yt as Touchscreen, zn as EventEmitter } from "./index-browser
|
|
4
|
-
import "./
|
|
1
|
+
import { n as __require } from "./chunk.js";
|
|
2
|
+
import { A as stringToTypedArray, G as first, H as delayWhen, K as firstValueFrom, L as combineLatest, M as assert, Q as map, S as timeout, St as debug, Tt as environment, V as defer, W as filter, at as race, b as isString, bt as TouchError, c as evaluationString, d as fromEmitterEvent, g as isDate, gt as ProtocolError, h as getSourceUrlComment, ht as ConnectionClosedError, i as SOURCE_URL_REGEX, k as stringToBase64, lt as switchMap, m as getSourcePuppeteerURLIfAvailable, o as debugCatchError, ot as raceWith, q as from, r as PuppeteerURL, rt as of, s as debugError, u as fromAbortSignal, v as isPlainObject, vt as TargetCloseError, x as parsePDFOptions, xt as UnsupportedOperation, y as isRegExp, yt as TimeoutError } from "./util.js";
|
|
3
|
+
import { $n as Deferred, $t as scriptInjector, Bt as throwIfDetached, Ct as WebWorkerEvent, Dn as DeviceRequestPrompt, Dt as normalizeHeaderValue, Fn as Browser, Hn as DisposableStack, Ht as bindIsolatedHandle, In as WEB_PERMISSION_TO_PROTOCOL_PERMISSION, It as Dialog, Jn as CallbackRegistry, Kn as disposeSymbol, Ln as CDPSession, Lt as Accessibility, Mn as invokeAtMostOnceForArguments, Mt as InterceptResolutionAction, Nn as throwIfDisposed, Nt as STATUS_TEXTS, On as BrowserContext, Ot as SecurityDetails, Pt as handleError, Rt as Frame, St as WebWorker, Ut as JSHandle, Vt as ElementHandle, Zn as isErrorLike, _t as Mouse, an as stringifyFunction, cn as Tracing, dt as ConsoleMessage, en as ARIAQueryHandler, fn as Coverage, gt as Keyboard, ht as TargetType, in as interpolateFunction, jn as inertIfDisposed, jt as HTTPRequest, kn as bubble, kt as HTTPResponse, mn as Page, mt as Target, nn as LazyArg, on as AsyncIterableUtil, sn as FileChooser, un as EmulationManager, vt as MouseButton, wt as Realm, yt as Touchscreen, zn as EventEmitter } from "./index-browser.js";
|
|
4
|
+
import "./BrowserWebSocketTransport2.js";
|
|
5
5
|
|
|
6
6
|
//#region node_modules/mitt/dist/mitt.mjs
|
|
7
7
|
function mitt_default(n) {
|
package/lib/client/index.js
CHANGED
|
@@ -172,6 +172,20 @@ function FailoverRow({ catalog, loadConfig, save, t }) {
|
|
|
172
172
|
|
|
173
173
|
//#endregion
|
|
174
174
|
//#region src/mobile/gesture.ts
|
|
175
|
+
/**
|
|
176
|
+
* Whether the mobile adaptation mounts at all (2026-10-18 user ruling):
|
|
177
|
+
* touch-first means the device's PRIMARY input is a finger. A query
|
|
178
|
+
* answering FALSE — a hover-capable or fine primary pointer — decides
|
|
179
|
+
* desktop on its own (a touchscreen laptop keeps desktop behavior); the
|
|
180
|
+
* pair answering true is the standard idiom; and only when the queries
|
|
181
|
+
* are entirely unavailable does `maxTouchPoints` become the honest
|
|
182
|
+
* degrade (every such legacy device is a phone or tablet anyway).
|
|
183
|
+
*/
|
|
184
|
+
function isTouchFirstDevice(input) {
|
|
185
|
+
if (input.hoverNone === false || input.pointerCoarse === false) return false;
|
|
186
|
+
if (input.hoverNone === true && input.pointerCoarse === true) return true;
|
|
187
|
+
return (input.maxTouchPoints ?? 0) > 0;
|
|
188
|
+
}
|
|
175
189
|
/** Resolved defaults — the `1706b81` constants (120 / viewport÷4 / 40 / 1.3)
|
|
176
190
|
* plus the one addition, the velocity gate. A slow text-selection drag runs
|
|
177
191
|
* ~0.13 px/ms; 0.15 px/ms filters those while any comfortable sweep (0.4
|
|
@@ -260,6 +274,18 @@ function resolveMobileConfig(pageConfig) {
|
|
|
260
274
|
|
|
261
275
|
//#endregion
|
|
262
276
|
//#region src/mobile/client/index.ts
|
|
277
|
+
/**
|
|
278
|
+
* One media query, or `undefined` when the environment has none (old
|
|
279
|
+
* webviews throw or omit `matchMedia`) — the probe then rides the
|
|
280
|
+
* touch-points fallback in {@link isTouchFirstDevice}.
|
|
281
|
+
*/
|
|
282
|
+
function safeMatchMedia(query) {
|
|
283
|
+
try {
|
|
284
|
+
return globalThis.matchMedia?.(query) ?? void 0;
|
|
285
|
+
} catch {
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
263
289
|
/** Left sidebar state, live off AppFrame's semantic attribute. */
|
|
264
290
|
function readLeftCollapsed() {
|
|
265
291
|
return document.querySelector("[data-sidebar-collapsed]") !== null;
|
|
@@ -340,17 +366,46 @@ function mobileCss() {
|
|
|
340
366
|
}
|
|
341
367
|
/**
|
|
342
368
|
* Mount the mobile feature: style injection plus the swipe listeners.
|
|
343
|
-
* Inert unless the host's boot script opted the page in
|
|
369
|
+
* Inert unless the host's boot script opted the page in AND the device is
|
|
370
|
+
* touch-first (2026-10-18 user ruling). Capability flips (a tablet's
|
|
371
|
+
* primary pointer hardware changing) re-evaluate and mount/unmount the
|
|
372
|
+
* surface live; the media queries answer on every browser since ~2015 and
|
|
373
|
+
* a webview without `matchMedia` degrades to the touch-points probe.
|
|
344
374
|
*
|
|
345
375
|
* @param ctx - client root context.
|
|
346
|
-
* @returns the effect disposer (style tag + listeners removed on unload).
|
|
347
376
|
*/
|
|
348
377
|
function setupMobileLayout(ctx) {
|
|
349
378
|
const pageConfig = globalThis.__DASHR_MOBILE__;
|
|
350
379
|
const config = resolveMobileConfig(pageConfig);
|
|
351
380
|
if (!config.enabled) return;
|
|
352
|
-
const
|
|
381
|
+
const coarseQuery = safeMatchMedia("(pointer: coarse)");
|
|
382
|
+
const hoverQuery = safeMatchMedia("(hover: none)");
|
|
353
383
|
ctx.effect(() => {
|
|
384
|
+
let disposeSurface;
|
|
385
|
+
const apply$1 = () => {
|
|
386
|
+
const touchFirst = isTouchFirstDevice({
|
|
387
|
+
hoverNone: hoverQuery?.matches,
|
|
388
|
+
pointerCoarse: coarseQuery?.matches,
|
|
389
|
+
maxTouchPoints: navigator.maxTouchPoints
|
|
390
|
+
});
|
|
391
|
+
if (touchFirst && disposeSurface === void 0) disposeSurface = mountTouchSurface();
|
|
392
|
+
else if (!touchFirst && disposeSurface !== void 0) {
|
|
393
|
+
disposeSurface();
|
|
394
|
+
disposeSurface = void 0;
|
|
395
|
+
}
|
|
396
|
+
};
|
|
397
|
+
coarseQuery?.addEventListener("change", apply$1);
|
|
398
|
+
hoverQuery?.addEventListener("change", apply$1);
|
|
399
|
+
apply$1();
|
|
400
|
+
return () => {
|
|
401
|
+
coarseQuery?.removeEventListener("change", apply$1);
|
|
402
|
+
hoverQuery?.removeEventListener("change", apply$1);
|
|
403
|
+
disposeSurface?.();
|
|
404
|
+
};
|
|
405
|
+
}, "dashr: mobile layout");
|
|
406
|
+
/** The style tag + gesture listeners, mounted and disposed as one surface. */
|
|
407
|
+
function mountTouchSurface() {
|
|
408
|
+
const styleTagId = "better-dsh/mobile";
|
|
354
409
|
const tag = document.createElement("style");
|
|
355
410
|
tag.dataset.plugin = "better-dsh";
|
|
356
411
|
tag.dataset.pluginCss = styleTagId;
|
|
@@ -363,9 +418,7 @@ function setupMobileLayout(ctx) {
|
|
|
363
418
|
const onPointerDown = (event) => {
|
|
364
419
|
start = void 0;
|
|
365
420
|
const viewport = window.innerWidth;
|
|
366
|
-
const coarsePointer = window.matchMedia?.("(pointer: coarse)").matches === true;
|
|
367
421
|
const panels = readPanelState();
|
|
368
|
-
if (!coarsePointer && !panels.leftCollapsed && !panels.rightOpen) return;
|
|
369
422
|
if (!admitsSwipeStart(event.clientX, viewport, panels, config)) return;
|
|
370
423
|
start = {
|
|
371
424
|
x: event.clientX,
|
|
@@ -405,7 +458,7 @@ function setupMobileLayout(ctx) {
|
|
|
405
458
|
tag.remove();
|
|
406
459
|
Promise.resolve(offLayout.dispose());
|
|
407
460
|
};
|
|
408
|
-
}
|
|
461
|
+
}
|
|
409
462
|
}
|
|
410
463
|
|
|
411
464
|
//#endregion
|
package/lib/compaction/index.js
CHANGED
package/lib/failover/index.d.ts
CHANGED
package/lib/failover/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { f as UrlSchemesError, t as buildFsLayerResolver } from "../wrap
|
|
1
|
+
import { f as UrlSchemesError, t as buildFsLayerResolver } from "../wrap.js";
|
|
2
2
|
import { Context } from "@deepseek-ai/cordis";
|
|
3
3
|
import { dirname, sep } from "node:path";
|
|
4
4
|
import { stat } from "node:fs/promises";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as merge, A as stringToTypedArray, B as defaultIfEmpty, Et as isNode, G as first, I as catchError, K as firstValueFrom, M as assert, N as EMPTY, O as mergeUint8Arrays, P as ReplaySubject, Q as map, R as concat, S as timeout, St as debug, T as withSourcePuppeteerURLIfNone, Tt as environment, U as distinctUntilChanged, V as defer, W as filter, X as ignoreElements, Y as identity, a as UTILITY_WORLD_NAME, at as race, b as isString, bt as TouchError, c as evaluationString, ct as startWith, d as fromEmitterEvent, dt as takeUntil, et as mergeMap, f as getReadableAsTypedArray, ft as tap, gt as ProtocolError, h as getSourceUrlComment, ht as ConnectionClosedError, i as SOURCE_URL_REGEX, it as pipe, j as typedArrayToBase64, k as stringToBase64, l as filterAsync, lt as switchMap, m as getSourcePuppeteerURLIfAvailable, mt as timer, n as NETWORK_IDLE_TIME, nt as noop, o as debugCatchError, ot as raceWith, p as getReadableFromProtocolStream, pt as throwIfEmpty, q as from, r as PuppeteerURL, rt as of, s as debugError, st as retry, t as DEFAULT_VIEWPORT, tt as mergeScan, u as fromAbortSignal, ut as take, vt as TargetCloseError, w as validateDialogType, x as parsePDFOptions, xt as UnsupportedOperation, yt as TimeoutError } from "./util
|
|
1
|
+
import { $ as merge, A as stringToTypedArray, B as defaultIfEmpty, Et as isNode, G as first, I as catchError, K as firstValueFrom, M as assert, N as EMPTY, O as mergeUint8Arrays, P as ReplaySubject, Q as map, R as concat, S as timeout, St as debug, T as withSourcePuppeteerURLIfNone, Tt as environment, U as distinctUntilChanged, V as defer, W as filter, X as ignoreElements, Y as identity, a as UTILITY_WORLD_NAME, at as race, b as isString, bt as TouchError, c as evaluationString, ct as startWith, d as fromEmitterEvent, dt as takeUntil, et as mergeMap, f as getReadableAsTypedArray, ft as tap, gt as ProtocolError, h as getSourceUrlComment, ht as ConnectionClosedError, i as SOURCE_URL_REGEX, it as pipe, j as typedArrayToBase64, k as stringToBase64, l as filterAsync, lt as switchMap, m as getSourcePuppeteerURLIfAvailable, mt as timer, n as NETWORK_IDLE_TIME, nt as noop, o as debugCatchError, ot as raceWith, p as getReadableFromProtocolStream, pt as throwIfEmpty, q as from, r as PuppeteerURL, rt as of, s as debugError, st as retry, t as DEFAULT_VIEWPORT, tt as mergeScan, u as fromAbortSignal, ut as take, vt as TargetCloseError, w as validateDialogType, x as parsePDFOptions, xt as UnsupportedOperation, yt as TimeoutError } from "./util.js";
|
|
2
2
|
|
|
3
3
|
//#region node_modules/puppeteer-core/lib/puppeteer/util/Deferred.js
|
|
4
4
|
/**
|
|
@@ -20792,7 +20792,7 @@ async function _connectToBiDiBrowser(connectionTransport, url, options) {
|
|
|
20792
20792
|
const { bidiConnection, cdpConnection, closeCallback } = await getBiDiConnection(connectionTransport, url, options);
|
|
20793
20793
|
return await (await import(
|
|
20794
20794
|
/* webpackIgnore: true */
|
|
20795
|
-
"./bidi
|
|
20795
|
+
"./bidi.js"
|
|
20796
20796
|
)).BidiBrowser.create({
|
|
20797
20797
|
connection: bidiConnection,
|
|
20798
20798
|
cdpConnection,
|
|
@@ -20815,7 +20815,7 @@ async function _connectToBiDiBrowser(connectionTransport, url, options) {
|
|
|
20815
20815
|
async function getBiDiConnection(connectionTransport, url, options) {
|
|
20816
20816
|
const BiDi = await import(
|
|
20817
20817
|
/* webpackIgnore: true */
|
|
20818
|
-
"./bidi
|
|
20818
|
+
"./bidi.js"
|
|
20819
20819
|
);
|
|
20820
20820
|
const { slowMo = 0, protocolTimeout, idGenerator = createIncrementalIdGenerator() } = options;
|
|
20821
20821
|
const pureBidiConnection = new BiDi.BidiConnection(url, connectionTransport, idGenerator, slowMo, protocolTimeout);
|
|
@@ -20845,7 +20845,7 @@ async function getBiDiConnection(connectionTransport, url, options) {
|
|
|
20845
20845
|
//#endregion
|
|
20846
20846
|
//#region node_modules/puppeteer-core/lib/puppeteer/common/BrowserConnector.js
|
|
20847
20847
|
const getWebSocketTransportClass = async () => {
|
|
20848
|
-
return isNode ? (await import("./
|
|
20848
|
+
return isNode ? (await import("./NodeWebSocketTransport2.js")).NodeWebSocketTransport : (await import("./BrowserWebSocketTransport.js")).BrowserWebSocketTransport;
|
|
20849
20849
|
};
|
|
20850
20850
|
/**
|
|
20851
20851
|
* Users should never call this directly; it's called when calling
|
|
@@ -20887,10 +20887,10 @@ async function getConnectionTransport(options) {
|
|
|
20887
20887
|
endpointUrl: connectionURL
|
|
20888
20888
|
};
|
|
20889
20889
|
} else if (options.channel && isNode) {
|
|
20890
|
-
const { detectBrowserPlatform, resolveDefaultUserDataDir, Browser: Browser$1 } = await import("./
|
|
20890
|
+
const { detectBrowserPlatform, resolveDefaultUserDataDir, Browser: Browser$1 } = await import("./main2.js");
|
|
20891
20891
|
const platform = detectBrowserPlatform();
|
|
20892
20892
|
if (!platform) throw new Error("Could not detect required browser platform");
|
|
20893
|
-
const { convertPuppeteerChannelToBrowsersChannel } = await import("./LaunchOptions
|
|
20893
|
+
const { convertPuppeteerChannelToBrowsersChannel } = await import("./LaunchOptions.js");
|
|
20894
20894
|
const { join } = await import("node:path");
|
|
20895
20895
|
const portPath = join(resolveDefaultUserDataDir(Browser$1.CHROME, platform, convertPuppeteerChannelToBrowsersChannel(options.channel)), "DevToolsActivePort");
|
|
20896
20896
|
try {
|
package/lib/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as Schema } from "./
|
|
1
|
+
import { t as Schema } from "./index2.js";
|
|
2
2
|
import { Context, Service } from "@deepseek-ai/cordis";
|
|
3
3
|
import { ToolDefinition, ToolExecutionInput, ToolRunContext, ToolRuntime } from "@deepseek-ai/dsh-tools";
|
|
4
4
|
import { ContentBlock, HarnessError } from "@deepseek-ai/dsh-llm";
|
|
@@ -379,7 +379,7 @@ interface ReplRuntimeSurface {
|
|
|
379
379
|
//#region src/runtime.d.ts
|
|
380
380
|
/** Plugin config: every tunable, changeable from `cordis.yml` (no hardcoded tunables). */
|
|
381
381
|
interface Config$1 {
|
|
382
|
-
/**
|
|
382
|
+
/** Existing interpreter path/name; absent discovers active/project environments then PATH. */
|
|
383
383
|
python?: string;
|
|
384
384
|
/** Budget for kernel spawn → ready, in milliseconds. */
|
|
385
385
|
startupTimeoutMs?: number;
|
|
@@ -402,12 +402,6 @@ interface Config$1 {
|
|
|
402
402
|
snapshotDir?: string;
|
|
403
403
|
/** Serialized graph cap in bytes; each over-cap attempt reports the last successful checkpoint. */
|
|
404
404
|
snapshotSizeCapBytes?: number;
|
|
405
|
-
/** Managed venv directory (used when `python` is absent/`python3`); defaults to `<package>/.venv-kernel`. */
|
|
406
|
-
kernelEnvDir?: string;
|
|
407
|
-
/** Preferred CPython version for a managed venv. */
|
|
408
|
-
kernelPythonVersion?: string;
|
|
409
|
-
/** Provision a stdlib-only managed venv on first use; default true. */
|
|
410
|
-
kernelAutoInstall?: boolean;
|
|
411
405
|
username?: string;
|
|
412
406
|
}
|
|
413
407
|
/**
|
|
@@ -428,8 +422,6 @@ declare class DashrRuntime extends ReplRuntime {
|
|
|
428
422
|
private readonly kernels;
|
|
429
423
|
private disposed;
|
|
430
424
|
private readonly transactions;
|
|
431
|
-
/** Lazily-resolved (and, when managed, provisioned) kernel interpreter. */
|
|
432
|
-
private kernelEnvPromise;
|
|
433
425
|
constructor(ctx: Context, config: Config$1);
|
|
434
426
|
/**
|
|
435
427
|
* The agentless-default kernel's pid, for lifecycle diagnostics; absent
|
|
@@ -480,8 +472,6 @@ declare class DashrRuntime extends ReplRuntime {
|
|
|
480
472
|
private validateBindings;
|
|
481
473
|
/** Dispatch one kernel-side host request; unknown types and bad payloads become error replies. */
|
|
482
474
|
private dispatchHostRequest;
|
|
483
|
-
/** Resolve (and provision, when managed) the kernel interpreter once per runtime. */
|
|
484
|
-
private resolveKernelPython;
|
|
485
475
|
/**
|
|
486
476
|
* Spawn-or-reuse the kernel for one key. The lazy map guarantees one
|
|
487
477
|
* entry is created here and nowhere else, so a key that never runs never
|