mirror of
https://github.com/ryan4yin/nix-config.git
synced 2026-11-13 12:13:46 +01:00
chore(agents): drop the dsh-nu plugin
dsh-nu replaced every shell command with Nushell and refused bash/pwsh syntax before it spawned; in practice the refusals were too noisy. Drop the flake input, install plain dsh, and remove the docs describing the Nushell-only shell. Assisted-by: DeepSeek Harness (deepseek-flash)
This commit is contained in:
1 parent
dfa53c71d7
commit
d7c493f5cd
6 files changed
+15
-115
No files matched your search
@@ -119,9 +119,9 @@ For an impactful change, follow these steps in order, scaled to its risk:
|
|||||||
Agents MUST NOT delete config the task did not ask about; when config merely appears unused,
|
Agents MUST NOT delete config the task did not ask about; when config merely appears unused,
|
||||||
report it instead. Ask before a breaking change.
|
report it instead. Ask before a breaking change.
|
||||||
- Minimality is not a reason to encode a local workaround for an upstream defect. Fix the owning
|
- Minimality is not a reason to encode a local workaround for an upstream defect. Fix the owning
|
||||||
upstream project first and consume the fixed revision; if a local stopgap is genuinely unavoidable,
|
upstream project first and consume the fixed revision; if a local stopgap is genuinely
|
||||||
stop and ask the user before adding it. "Minimal" means the smallest change that follows existing
|
unavoidable, stop and ask the user before adding it. "Minimal" means the smallest change that
|
||||||
best practice, not the smallest diff at any cost.
|
follows existing best practice, not the smallest diff at any cost.
|
||||||
- Documentation should describe current behavior for readers without the conversation history; give
|
- Documentation should describe current behavior for readers without the conversation history; give
|
||||||
each fact one home per audience and link instead of repeating. Comments explain contracts or
|
each fact one home per audience and link instead of repeating. Comments explain contracts or
|
||||||
non-obvious constraints, not obvious code, and preserve safety, license, and workaround
|
non-obvious constraints, not obvious code, and preserve safety, license, and workaround
|
||||||
@@ -182,7 +182,7 @@ For an impactful change, follow these steps in order, scaled to its risk:
|
|||||||
- Prefer native tool options to reduce output at the source, and the native read, grep, glob, write,
|
- Prefer native tool options to reduce output at the source, and the native read, grep, glob, write,
|
||||||
and edit tools over their shell equivalents. A single shell dispatch is for genuinely shell work
|
and edit tools over their shell equivalents. A single shell dispatch is for genuinely shell work
|
||||||
(git, ssh, nix, remote commands).
|
(git, ssh, nix, remote commands).
|
||||||
- Use the shell the runtime provides; dsh-nu fails closed rather than substituting another shell.
|
- Use the shell the runtime provides; never hand work to another shell (`bash -c`, `sh -c`, `pwsh`).
|
||||||
For genuinely shell work use the available runtime, `python -c '<code>'` for complex local
|
For genuinely shell work use the available runtime, `python -c '<code>'` for complex local
|
||||||
processing, or a script written with the write tool. A remote command usually runs under a POSIX
|
processing, or a script written with the write tool. A remote command usually runs under a POSIX
|
||||||
shell: keep it to one invocation or a copied script.
|
shell: keep it to one invocation or a copied script.
|
||||||
|
|||||||
Generated
+1
-44
@@ -145,27 +145,6 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dsh-nu": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": [
|
|
||||||
"nixpkgs"
|
|
||||||
],
|
|
||||||
"nur-ryan4yin": "nur-ryan4yin"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1793290908,
|
|
||||||
"narHash": "sha256-EXQpNeSoiLhk3NsfETZxuWbMwZT/01l/uP5maVziiCI=",
|
|
||||||
"owner": "ryan4yin",
|
|
||||||
"repo": "dsh-nu",
|
|
||||||
"rev": "b3a7c6eb7383aea56fe1ebbfbf06e5592952713a",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "ryan4yin",
|
|
||||||
"repo": "dsh-nu",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fcitx5-vinput": {
|
"fcitx5-vinput": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
@@ -778,27 +757,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nur-ryan4yin": {
|
"nur-ryan4yin": {
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": [
|
|
||||||
"dsh-nu",
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1793285532,
|
|
||||||
"narHash": "sha256-srlNGg3/PBb3DfaC9ROlYl68VjxJfKPJoddFSU89oOQ=",
|
|
||||||
"owner": "ryan4yin",
|
|
||||||
"repo": "nur-packages",
|
|
||||||
"rev": "4687255272d66973ee4a8c1b025ca9f84371b9a6",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "ryan4yin",
|
|
||||||
"repo": "nur-packages",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nur-ryan4yin_2": {
|
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
@@ -899,7 +857,6 @@
|
|||||||
"catppuccin": "catppuccin",
|
"catppuccin": "catppuccin",
|
||||||
"colmena": "colmena",
|
"colmena": "colmena",
|
||||||
"disko": "disko",
|
"disko": "disko",
|
||||||
"dsh-nu": "dsh-nu",
|
|
||||||
"fcitx5-vinput": "fcitx5-vinput",
|
"fcitx5-vinput": "fcitx5-vinput",
|
||||||
"haumea": "haumea",
|
"haumea": "haumea",
|
||||||
"home-manager": "home-manager",
|
"home-manager": "home-manager",
|
||||||
@@ -923,7 +880,7 @@
|
|||||||
"nixpkgs-patched": "nixpkgs-patched",
|
"nixpkgs-patched": "nixpkgs-patched",
|
||||||
"nixpkgs-stable": "nixpkgs-stable",
|
"nixpkgs-stable": "nixpkgs-stable",
|
||||||
"nu_scripts": "nu_scripts",
|
"nu_scripts": "nu_scripts",
|
||||||
"nur-ryan4yin": "nur-ryan4yin_2",
|
"nur-ryan4yin": "nur-ryan4yin",
|
||||||
"ponytail": "ponytail",
|
"ponytail": "ponytail",
|
||||||
"pre-commit-hooks": "pre-commit-hooks",
|
"pre-commit-hooks": "pre-commit-hooks",
|
||||||
"preservation": "preservation",
|
"preservation": "preservation",
|
||||||
|
|||||||
@@ -203,12 +203,5 @@
|
|||||||
url = "github:ryan4yin/nur-packages";
|
url = "github:ryan4yin/nur-packages";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
|
||||||
# The Nushell-only shell bundle. Its flake builds the plugin from the
|
|
||||||
# repository, so a release needs only `nix flake update dsh-nu`.
|
|
||||||
dsh-nu = {
|
|
||||||
url = "github:ryan4yin/dsh-nu";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -15,9 +15,7 @@ Markdown with no Nix dependency; this module only wires it into place.
|
|||||||
[agents/skills/README.md](../../../../agents/skills/README.md).
|
[agents/skills/README.md](../../../../agents/skills/README.md).
|
||||||
- `packages.nix`: agent CLIs (`codex`, `opencode`, `qwen-code`, `pi`) from the `llm-agents` flake
|
- `packages.nix`: agent CLIs (`codex`, `opencode`, `qwen-code`, `pi`) from the `llm-agents` flake
|
||||||
input, dsh from `nur-ryan4yin`, `pkgs.ctx7` for the `find-docs` skill, and `pkgs.mcp-grafana` for
|
input, dsh from `nur-ryan4yin`, `pkgs.ctx7` for the `find-docs` skill, and `pkgs.mcp-grafana` for
|
||||||
the Grafana MCP server. dsh's Nushell-only shell is selected when the package is built, via
|
the Grafana MCP server. Profile patches live in `~/.dsh/profiles/<name>/cordis.patch.yml`. See
|
||||||
`dsh.withPlugins` with the plugin from the `dsh-nu` flake input, so it is a derivation choice
|
|
||||||
rather than runtime state; profile patches live in `~/.dsh/profiles/<name>/cordis.patch.yml`. See
|
|
||||||
[dsh.md](./dsh.md) for the layer order and the settings that bite.
|
[dsh.md](./dsh.md) for the layer order and the settings that bite.
|
||||||
- `env.nix`: telemetry and auto-update opt-outs for the agents.
|
- `env.nix`: telemetry and auto-update opt-outs for the agents.
|
||||||
|
|
||||||
|
|||||||
@@ -3,19 +3,18 @@
|
|||||||
dsh is installed by this module (`packages.nix`) and configured at runtime, not by Nix. It boots a
|
dsh is installed by this module (`packages.nix`) and configured at runtime, not by Nix. It boots a
|
||||||
profile: an ordered stack of patch layers over an empty root entry list, where later layers win.
|
profile: an ordered stack of patch layers over an empty root entry list, where later layers win.
|
||||||
|
|
||||||
| # | Layer | Path | Writer |
|
| # | Layer | Path | Writer |
|
||||||
| --- | --------- | -------------------------------------------- | --------------- |
|
| --- | ------- | -------------------------------------------- | --------------- |
|
||||||
| 1 | bundles | shipped with the profile | upstream |
|
| 1 | bundles | shipped with the profile | upstream |
|
||||||
| 2 | profile | `$DSH_HOME/profiles/<name>/cordis.patch.yml` | dsh, at runtime |
|
| 2 | profile | `$DSH_HOME/profiles/<name>/cordis.patch.yml` | dsh, at runtime |
|
||||||
| 3 | home | `$DSH_HOME/cordis.patch.yml` | you |
|
| 3 | home | `$DSH_HOME/cordis.patch.yml` | you |
|
||||||
| 4 | `--patch` | whatever the launcher passes | package wrapper |
|
|
||||||
|
|
||||||
`$DSH_HOME` defaults to `~/.dsh`. Settings UI changes are written to the profile patch; a home-layer
|
`$DSH_HOME` defaults to `~/.dsh`. Settings UI changes are written to the profile patch; a home-layer
|
||||||
row outranks it, so the UI rejects that setting with
|
row outranks it, so the UI rejects that setting with
|
||||||
`Configuration for "..." is overridden by a home patch`. This repository ships no home layer:
|
`Configuration for "..." is overridden by a home patch`. This repository ships no home layer:
|
||||||
profile patches remain machine-local runtime state, the place for private endpoints (LAN servers,
|
profile patches remain machine-local runtime state, the place for private endpoints (LAN servers,
|
||||||
staging gateways) too. The shell swap is a package concern instead: Nix installs `dsh` from
|
staging gateways) too. Nix installs plain `dsh` from `nur-ryan4yin`, with no package wrapper and no
|
||||||
`nur-ryan4yin` with `dsh.withPlugins`, which adds a `--patch` overlay after the profile layer.
|
`--patch` overlay.
|
||||||
|
|
||||||
Three behaviours that are easy to get wrong:
|
Three behaviours that are easy to get wrong:
|
||||||
|
|
||||||
@@ -50,42 +49,3 @@ on, `$DSH_AGENTS_HOME/AGENTS.md` — so no patch row is needed; identical conten
|
|||||||
- The scopes come from the environment: `0.2.1-alpha.2` removed the row's `dshHome` / `agentsHome`.
|
- The scopes come from the environment: `0.2.1-alpha.2` removed the row's `dshHome` / `agentsHome`.
|
||||||
- Nested `AGENTS.md` files are discovered by `read` / `write` / `edit`, not by `cd` inside `bash`,
|
- Nested `AGENTS.md` files are discovered by `read` / `write` / `edit`, not by `cd` inside `bash`,
|
||||||
and nothing is watched: an external edit lands on the next such call, or on resume.
|
and nothing is watched: an external edit lands on the next such call, or on resume.
|
||||||
|
|
||||||
## Nushell-only shell
|
|
||||||
|
|
||||||
`dsh-nu`'s flake builds the bundle and `nur-ryan4yin`'s `dsh.withPlugins` applies it: every
|
|
||||||
`ctx.shell` consumer (model shell tools, background jobs, hook bridges, in-process callers) runs
|
|
||||||
`nu --no-config-file -c`, and a command that hands execution to another shell is refused before it
|
|
||||||
spawns. The plugin adds Nushell rules and a syntax guide, and rewrites the shell-tool descriptions,
|
|
||||||
so the model is told what actually runs. `nu` is the Nushell `dsh-nu`'s flake resolves — Nixpkgs',
|
|
||||||
through `inputs.nixpkgs.follows` — substituted into the rendered patch at build time, so it does not
|
|
||||||
depend on `PATH`. The bundle still records Nushell 0.115.1 as its tested release; nix-config follows
|
|
||||||
the main nixpkgs and rewrites that manifest field to the resolved Nushell in `outputs/default.nix`
|
|
||||||
until dsh-nu retests, rather than pinning an older nixpkgs for the whole plugin. A command that
|
|
||||||
hands a script file to a shell (`bash scripts/build.sh`) is refused, and the refusal names the
|
|
||||||
direct `./scripts/build.sh` spelling; the guard itself is unchanged.
|
|
||||||
|
|
||||||
`home/base/tui/agents/packages.nix` calls `dsh-nu.lib.mkDshNuPackage { inherit pkgs dsh; }` and
|
|
||||||
passes the result to `withPlugins`; `flake.lock` pins both inputs. `dsh.withPlugins` wraps the
|
|
||||||
binary: each invocation gets a generated `--patch <file>` overlay after the profile layer, while
|
|
||||||
`dsh plugin` stays untouched. No `$DSH_HOME/cordis.patch.yml` is written, so there is no home-layer
|
|
||||||
state to resolve or roll back. Boundaries: preset rows that spawn a shell themselves
|
|
||||||
(`custom-bash.mjs`, `persistent-shell`) bypass `ctx.shell`. So does
|
|
||||||
`@deepseek-ai/dsh-experimental-terminal-bundle`: its `terminal_*` tools use a separate
|
|
||||||
`ctx.terminals` seam and run the platform shell (bash on the POSIX hosts this repository manages),
|
|
||||||
so they coexist with this plugin but stay outside the Nushell-only guarantee — keep the bundle off
|
|
||||||
for a strict Nu-only machine. Bash hooks now run under Nushell and need rewriting; remote hosts
|
|
||||||
still run their own POSIX shell. Rollback: install plain `dsh` or pass an empty plugin list; there
|
|
||||||
is no home file to delete. Tested on Linux; the same package also builds for Darwin, where it has
|
|
||||||
not been boot-tested.
|
|
||||||
|
|
||||||
Verify after a switch:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
dsh --profile web --dump-config | grep -nE 'nu-executor|nu-teaching'
|
|
||||||
# expect the first-party shell rows disabled, nu-executor and nu-teaching inserted
|
|
||||||
```
|
|
||||||
|
|
||||||
A dsh bump can disable a row whose manifest no longer matches. That compatibility check runs only
|
|
||||||
when a profile boots, not under the boot-free `--dump-config`, so read the stderr of the next boot
|
|
||||||
(for example `just dsh-web`) for `disabling profile plugin`; nothing prints when healthy.
|
|
||||||
@@ -1,17 +1,10 @@
|
|||||||
{
|
{
|
||||||
pkgs,
|
pkgs,
|
||||||
llm-agents,
|
llm-agents,
|
||||||
dsh-nu,
|
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
agentPackages = llm-agents.packages.${pkgs.stdenv.hostPlatform.system};
|
agentPackages = llm-agents.packages.${pkgs.stdenv.hostPlatform.system};
|
||||||
# dsh-nu's flake builds the plugin from its own checkout; this repository
|
|
||||||
# supplies the dsh installation it plugs into.
|
|
||||||
dshNu = dsh-nu.lib.mkDshNuPackage {
|
|
||||||
inherit pkgs;
|
|
||||||
inherit (pkgs) dsh;
|
|
||||||
};
|
|
||||||
# llm-agents.nix still exposes OpenCode V2 as `opencode2` so it can coexist
|
# llm-agents.nix still exposes OpenCode V2 as `opencode2` so it can coexist
|
||||||
# with the v1 package. Re-expose its binary under the normal command name.
|
# with the v1 package. Re-expose its binary under the normal command name.
|
||||||
opencode = pkgs.linkFarm "opencode" [
|
opencode = pkgs.linkFarm "opencode" [
|
||||||
@@ -29,9 +22,8 @@ in
|
|||||||
agentPackages.qwen-code
|
agentPackages.qwen-code
|
||||||
agentPackages.pi
|
agentPackages.pi
|
||||||
# dsh from nur-packages: llm-agents.nix's dsh cannot boot on nixpkgs node
|
# dsh from nur-packages: llm-agents.nix's dsh cannot boot on nixpkgs node
|
||||||
# (node-addon-require-builtin probe), this one shims it. The Nushell-only
|
# (node-addon-require-builtin probe), this one shims it.
|
||||||
# plugin rides in through the package's withPlugins wrapper.
|
pkgs.dsh
|
||||||
(pkgs.dsh.withPlugins [ dshNu ])
|
|
||||||
|
|
||||||
# Docs lookup CLI behind the find-docs skill (agents/skills/find-docs). The skill's flags are
|
# Docs lookup CLI behind the find-docs skill (agents/skills/find-docs). The skill's flags are
|
||||||
# written against this package, not against upstream's npx instructions.
|
# written against this package, not against upstream's npx instructions.
|
||||||
|
|||||||
Reference in new issue
Block a user