Bundle
dsh-loop
DeepSeek Harness plugin: a /loop slash command for timed recurring agent loops
- Source
- XiaoWind
- stars
- 1 stars
- License
- MIT
- Updated
- Updated 23 hours ago
Readme
# dsh-loop
English | [中文](README.zh.md)
A [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (DSH)
plugin that adds a human-facing `/loop` slash command for **timed, recurring
agent loops**.
`/loop 30m` fires one immediate tick, then re-prompts the agent once per
30-minute interval (measured from the moment the agent returns to idle after
the previous tick) until you stop it with `/loop stop`.
## Install
```sh
# from GitHub (works immediately — no npm publish required)
dsh plugin --profile web add git+https://github.com/XiaoWind/dsh-loop.git
# or from npm, once published
dsh plugin --profile web add dsh-loop
```
The `dsh plugin` command forwards to `pnpm` inside the `web` profile directory,
then reconciles the profile's `dsh.profile.bundles` layer list. Because this
package declares `dsh.bundle.patch`, it joins the layer stack automatically.
Restart the Web app after installing.
> The plugin injects the `commands` service, so it activates only in profiles
> that compose a command adapter — the shipped `web` profile does.
## Update
Pull the latest version of the plugin into an installed profile:
```sh
dsh plugin --profile web update dsh-loop
```
`dsh plugin` forwards to `pnpm update dsh-loop` inside the profile directory,
which re-resolves the `github:XiaoWind/dsh-loop` dependency to the latest commit
on the default branch. The lockfile pins a git dependency by commit hash, so a
`version` bump is not required for the update to land. If pnpm has cached an old
git resolution, re-pin it explicitly:
```sh
dsh plugin --profile web add github:XiaoWind/dsh-loop
```
Restart the Web app after updating — the bundle layer is composed at boot, so a
running Web process does not hot-reload an installed plugin.
## Usage
| Command | Result |
|---|---|
| `/loop 30m` | Start a loop: tick now, then once every 30 minutes. Keeps any current objective. |
| `/loop 30m fix the tests` | Start a 30-minute loop toward an objective. |
| `/loop fix the tests` | Start a loop toward an objective at the default interval. |
| `/loop 1h30m` | Combined durations are supported. |
| `/loop resume` | Resume the loop saved before a restart. |
| `/loop` or `/loop status` | Show the running loop. |
| `/loop stop` | Stop the loop. |
| `/loop help` | Show help. |
Intervals are a whitespace-free sequence of `<number><unit>` tokens where
`unit` is one of `ms`, `s`, `m`, `h`, `d` — for example `90s`, `30m`, `1h30m`,
`2h`.
A leading duration token is the interval and the remainder is the objective;
with no leading duration, the whole input is the objective and the default
interval applies.
### Semantics
- **First tick is immediate.** Each later tick fires `interval` after the agent
returns to idle, so a running turn is never interrupted.
- **Saved across restarts.** The loop config is persisted to
`$DSH_HOME/dsh-loop/<sessionId>.json`. When you reopen the session after a
restart, the plugin asks whether to continue the saved loop (`Continue` /
`Stop`); `/loop resume` restarts it manually when no prompt is available.
`/loop stop` discards the saved loop.
- **Manual stop.** The loop runs until you run `/loop stop`, the agent is
disposed, or the plugin is unloaded. There is no automatic completion
detection.
## Configuration
Set `config.defaultIntervalMs` (milliseconds) to change the interval used by a
bare `/loop <objective>` with no leading duration token. The default is
`600000` (10 minutes).
```yaml
# your profile's cordis.patch.yml
- id: loop
config:
defaultIntervalMs: 900000
```
## Development
```sh
# syntax check
node --check lib/index.js
```
The plugin is a single-file ESM Cordis function plugin (`lib/index.js`) with no
build step. It exports `apply`, `inject`, and `name`, and the bundle layer
`cordis.patch.yml` inserts it into the profile composition.
## License
MIT
Install
dsh plugin --profile web add github:XiaoWind/dsh-loop
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-loop from the hub
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.