Reading the repo
Reading the repo
How to install on macOS
A toolkit for low-level operations in DSH, designed to reduce token usage and task execution time / DSH 底层操作工具插件,旨在减少 Token 消耗与任务耗时
Saved setup from 3 h ago
Will it work on my device?
docs/CONTRIBUTING.mdWelcome to dsh-ops. This guide covers how work is claimed, how to build and verify locally, and the conventions a pull request is reviewed against. 中文版:贡献指南.md.
ops_bash. Changes to DSH's original behaviour are limited to optionally
hiding duplicated official tools, so the plugin stays compatible with other plugins.work/<topic> branch.| Component | Requirement |
| --- | --- |
| Node.js | ^22.19 or >=24 (package.json#engines; CI uses 24) |
| Rust | 1.97.1 (the toolchain CI pins); needed to build the native worker |
| Target host | DSH 0.2.2-rc.1 (0.5 series; older hosts are unsupported) |
| Linux only | the acl package for the POSIX ACL checks |
npm ci --ignore-scripts
npm run build # compile src/ to lib/ and copy component assets
npm run build:ptc # build and stage the native worker (see below)
npm run verify
Edit the plugin in src/ using strict TypeScript or TSX. npm run build emits JavaScript into
lib/ and copies component manifests, locale files, icons and the panel HTML. lib/ is ignored by
Git and must not be edited by hand. Package exports, component entries and tests load lib/;
runtime imports retain their .js paths.
Run npm run build after changing source or assets and before invoking a suite directly with
node test/run.mjs <filter>. npm test, npm run test:ptc and npm run verify build first;
npm run typecheck checks all plugin source without emitting files. JavaScript source under src/
is rejected by the build, including unimported files that the TypeScript compiler would otherwise
silently ignore. Repository scripts and tests may continue to use JavaScript.
For a local or Git-source installation, build and pack a checkout before installing it into DSH:
npm ci --ignore-scripts
npm run build
npm run build:ptc
npm pack
Before packing on any host, run npm run stage:niubash -- --archive <absolute-frozen-v1.5.0.tar.gz> --offline (or omit --archive/--offline to acquire the fixed official archive through the configured proxy). prepack verifies this complete tree and fails closed if missing. The release gate stages it before tests and pack; set DSH_OPS_NIUBASH_ARCHIVE and DSH_OPS_OFFLINE=1 for offline gate runs. On Windows, the gate sets DSH_OPS_TEST_NIUBASH to the verified staged executable and separately acquires the committed legacy MSYS pin for compatibility tests and build:bash-ipc. DSH_OPS_TEST_BASH is only an explicit verified legacy fixture override, not the default backend. Install the resulting
dsh-ops-<version>.tgz with the DSH CLI for your target profile (see the README). npm pack runs
the build through prepack, unless lifecycle scripts are disabled. An unbuilt Git checkout has
no lib/ and is not ready to load; there is no install-time lifecycle hook. Keep development
dependencies installed while building, since they include the compiler. The published tarball
contains compiled lib/ and its assets, excludes src/, and does not require consumers to
compile the plugin.
prepack compiles lib/ but does not stage the native worker, so a Git installation can
never ship runtime/ on its own — see installing from Git.
Adding a prepare hook would not repair that channel: it would compile lib/ on every Git
install and still leave the worker unstaged, because staging needs cargo. The manifest gate in
scripts/validate-manifest.mjs fails if any install-time lifecycle hook appears in
package.json — (pre|post)?(prepare|install), so prepare, preprepare,
postprepare, install, preinstall and postinstall. A hook unrelated to the build,
such as a preinstall for tooling, is refused too: the gate reads the package manifest, not
the author's intent.
Most suites drive the real native worker. Without one they cannot answer, and they skip:
cargo test --workspace --locked --manifest-path native/Cargo.toml # worker unit tests
npm run build:ptc # build + stage runtime/<platform>-<arch>/
npm run build:bash-ipc # Windows only: Bash IPC proxies
What a skip means locally:
test/run.mjs counts a skip apart from a pass. A machine with no worker reports
N suite(s) passed, M skipped — that is not a green gate.DSH_OPS_REQUIRE_RUNTIME=1 turns any runtime-absence skip into a failure. The gate sets it on
Linux and macOS, so if you have not built the worker, expect those suites to fail there.DSH_OPS_ALLOW_SKIPS=tui-host,tui-native keeps suites that need an optional external checkout
(DSH_OPS_TUI_ROOT, DSH_OPS_TUI_WORKER) as skips even under DSH_OPS_REQUIRE_RUNTIME=1.scripts/verify-gate.mjs (ALLOWED_SKIPS): on Windows
file-metadata, linux-attributes, linux-shell; on POSIX only mount, and only when no worker
can be resolved. Any other skip fails the gate.npm run verify — build src/ into lib/, run scripts/validate-manifest.mjs, then
test/run.mjs (every test/*.test.mjs
in its own process with its own temporary DSH_HOME).node scripts/verify-gate.mjs --skip-install — the release gate, exactly what
.github/workflows/ci.yml runs on Windows x64, Linux x64, macOS arm64 and macOS Intel x64: worker unit tests, build
and stage, manifest floor, every suite, the allowed-skip set, the suite inventory on disk, and the
packed artifact.node test/run.mjs <filter> runs only the suites whose file names contain <filter>, e.g.
node test/run.mjs mount file-operations.The four full-payload suites (niubash-payload-integration, niubash-preparation,
niubash-security-host, niubash-consumer) default to a 600-second suite watchdog; other suites
keep 120 seconds. A positive finite DSH_OPS_SUITE_TIMEOUT_MS overrides either default. The clean
consumer reserves 60 seconds of that budget for packing/installing, leaving 540 seconds by default
for its real host checks. Bash commands retain their production 120-second default, including
verified staging of the complete execution tree; the suite watchdog is a separate outer limit.
The descendant timeout test proves that a child starts before its deadline and cannot write afterward.
On a loaded Windows host, provide a larger explicit outer budget without changing command deadlines:
$env:DSH_OPS_SUITE_TIMEOUT_MS = '1800000'
node test/run.mjs niubash
How to read the gate and the expected numbers per host: verify-locally.md.
CI runs on every pull request and every push to main, 0.3.2 and release/0.4.0. The two blocking POSIX legs (validate-posix: Linux x64, macOS arm64) block a merge. The Windows x64 leg (validate-windows) and the macOS Intel leg (validate-macos-intel) still run on every event but are non-blocking — a red run there is a defect to fix, not a reason to hold the merge (#316; the Intel leg measured 318 s).
All target branches are covered, including stacked feature branches. Repository enforcement requires the separate administrator ruleset and acceptance steps; passing CI alone does not configure branch protection.
Every pull request must show one run of the Cross-platform validation
workflow that its own pull_request event triggered. The aggregate job CI required
summarises the two blocking POSIX legs (Linux x64, macOS arm64); the non-blocking Windows x64 and
macOS Intel legs run alongside it and are deliberately not waited on. That job's run URL is what the
pull request template asks for.
What triggers it. ci.yml runs on pull_request targeting main, 0.3.2 and
release/0.4.0 (and on push to the same branches, plus merge_group). GitHub reads the
workflow file from the pull request's own head, so a PR against any of those branches starts a
run when it is opened or updated.
How to confirm it. List the runs for the branch, check the event, then read the run URL:
gh run list --branch <branch> --workflow ci.yml --event pull_request --limit 1
gh run view <run-id> --json url,event,conclusion --jq '"\(.url) \(.event) \(.conclusion)"'
The pull request's Checks tab shows the same run; a green CI required there is the check
that has to pass.
Fork contributors (#150). Two verifiable paths: (a) open the pull request upstream so the
repository triggers the pull_request run — a first run from a first-time fork contributor can
stop at action_required until a maintainer approves it; or (b) open a pull request inside
your fork from the feature branch to the fork's default branch, which is also a pull_request
event — paste that URL and mark it as the fork run. Running the workflow by hand or relying on a
push run is still not a substitute.
A hand-dispatched run is not a substitute. 26 of the 27 pull requests merged into
release/0.4.0 had no pull_request run at all: the green check came from a manual
workflow_dispatch, which validates a branch but never the merge (#303).
Required check. Making CI required a required status check on main, 0.3.2 and
release/0.4.0 is a repository-settings change that needs admin rights; it is tracked in #303
and cannot be done from a code PR. Until it lands, the rule is enforced in review.
Dependabot pull requests. Once the check is required, a dependency bump whose PR is red is blocked like any other: rebase or re-run first, fix the version/build in the PR if the upgrade is wanted, and close it with a note if it is not. Do not bypass a required check with admin rights; an upgrade that cannot pass CI is not merged.
test/mount.test.mjs.AUTHORITY_CHANGED).test/*.test.mjs file = one process. The gate asserts that every suite on
disk was collected. Shared helpers live in test/lib/ and must not end in .test.mjs.skipSuite() in test/lib/harness.mjs
and must be on the allowed list. A single check whose fixture cannot be built on a host prints a
named ... fixture unavailable: <reason> line instead of passing quietly.Capability names, component ownership, presentation modes, mutation/concurrency flags and file/PTC
schemas live in src/capabilities/. Keep new capability metadata there; adapters own registration
and rendering. src/kernel/ defines the 0.4 Outcome<T>, coverage/search/reference types and
error-to-retry policies. Their later adapter migrations will change wire results; this foundation
preserves existing output. node test/run.mjs capabilities kernel-errors kernel-types checks the
catalogue, retry rules and positive/negative TypeScript contracts. Node declarations are pinned to
@types/node@22.20.5 (published 2026-10-01) to type the supported Node 22 API without runtime code.
docs/ exists in English and Chinese, e.g. docs/usage.md and
docs/使用指南.md. Update both in the same PR.src/components/* and
test/lib/ layout.publicToolName() in src/policy.ts; never hand-write the ops_
prefix.src/config.ts; an unknown key is an error that names the key.
Defaults in cordis.patch.yml must match the defaults in code.apply; required: true must refuse activation
at load time.fix: report undeclared background arguments as argument errors (#14)..github/PULL_REQUEST_TEMPLATE.md. The Validation section carries real command output
(pass/skip/fail counts), not ticked boxes.## [Unreleased] in CHANGELOG.md when behaviour or shipped
documentation changes, or state in Validation why it is not needed.optionalDependencies in package.json unless
the issue asks for it.@deepseek-ai/* values at load time; use ctx.inject([...])
/ ctx.get() for host services.ops_* tools only through this plugin's own
ctx.tools.register.ctx.get('tools'), not ctx.tools.Current releases are MIT-licensed. FastCtx was removed in 0.3.2; the releases that shipped it were
MIT AND Apache-2.0. FastCtx's Apache-2.0 text, upstream notice and the acknowledgement reproduced
in NOTICE remain for those releases and must stay verbatim — do not "polish" it.
Native build and acceptance details: native-ptc.md and manual-validation.md.
The credential fence, trusted path anchors and permission helpers are strict TypeScript modules (src/credential-policy.ts, src/authority-paths.ts, src/permissions.ts). Their emitted .js imports and wire failures stay stable. Authority policies use type-only host definitions; unknown worker failures must be narrowed before use. node test/run.mjs kernel-types authority credential-fence credential-denial safety-atomicity permissions covers the typed boundary and existing authority behavior.
src/profile-install.ts and src/session-temp.ts are strict TypeScript helpers with unchanged emitted paths. Profile mutations still delegate to the official CLI; manifest data is narrowed before reading it. Private temporary directories retain their session-derived names and refusal of link/file targets. node test/run.mjs profile-temp kernel-types checks delegation, dry-run, failures and typed outcomes.
src/index.ts types the component entry against the public Cordis Context and Agent contracts. Raw configuration remains unknown until validation; callbacks and tool-denial decisions retain their public host signatures. Runtime imports remain .js, and host dependencies remain type-only at module load. node test/run.mjs kernel-types mount bundle-startup progressive-loop checks the type boundary, scoped startup/disposal and next-step publication.
The settings integration tests use exact development-only host settings, profile boot and config
editor packages at 0.2.2-rc.1, with matching Cordis loader/group/include, CosmoKit and Schemastery
patch versions. They exercise the real profile writer and component reload instead of substituting
an in-memory save. These packages are not production dependencies or host runtime imports.
Browser settings are strict TSX. The build uses the existing TypeScript compiler to produce the
host's lazy ./client factory, with React supplied by the host. Exact development-only React 18.3.1,
React type packages, jsdom 26.1.0 and the pinned 0.2.2-rc.1 client contracts support compilation,
DOM interactions and the real host slot lifecycle tests. No browser bundler or production dependency
is added. settings-ui, settings-client, settings-host and settings-runtime suites cover the
form-to-profile and reviewed-action boundaries.
The browser-page regression also uses development-only @deepseek-ai/dsh-client-modules
0.2.2-rc.1 to assert actual client registry activation, teardown and
restart against temporary installed profiles. settings-client covers exact composition,
backups and atomic rollback; it never migrates a developer profile.
src/panel/collect.ts uses typed filesystem seams and validates persisted event fields before folding. Valid capture documents keep their text, counters and archive behavior. Invalid persisted text/usage/timestamp fields are counted as malformed and mark the result degraded, with incomplete usage totals; they cannot be silently coerced. Stopping still cancels queued work, waits for issued I/O and retains the append log; explicit sealing remains separate. Run node test/run.mjs ops-panel-collect panel-records panel-stop kernel-types for recovery, bounded data, physical-stop and type checks.
npm run build:bash-ipc supports non-ASCII checkout, Visual Studio and temporary
paths without changing the machine's console code page. Its generated batch file
contains only ASCII commands; absolute pa
Then run bash setup.sh. It stops at the first error and is safe to run again. Servers and tests aren't started; it lists them at the end. Read it first.
Needs Git: xcode-select --install
git clone https://github.com/T-Auto/dsh-ops.git cd dsh-ops
Node.js ^22.19 || >=24
# needs nvm: brew install nvm (or https://github.com/nvm-sh/nvm) nvm install 22
npm ci
npm test
No reports for macOS yet.
Opens a chat with this manual already filled in, for macOS. It uses your own account; gitmanual sends nothing.