Introducing standalone session scheduled tasks for DeepSeek Harness: execute self-contained tasks on schedule within the new Agent + Session, with dual access via Web console and Agent tools.
- Language
- TypeScript
- License
- MIT
- Branch
- main
Install
$ dsh plugin --profile web add github:titanwings/dsh-automationRun the command above in your terminal to install this plugin via the dsh CLI. You can switch Profile in the top-right corner. New to dsh? Read the beginner tutorial
Install via your agent
Install the DeepSeek Harness plugin titanwings/dsh-automation for me: review the repository at https://github.com/titanwings/dsh-automation first, then run the install command and verify the plugin loads successfully.
Paste this instruction to the DSH Web GUI assistant — it will install and verify for you.
One-Line Positioning
dsh-automation adds "standalone scheduled task" capability to DeepSeek Harness. Whenever it's time, it executes a self-contained prompt in a brand new root Agent + new Session, and leaves each execution result as an auditable record. Unlike DSH Core Schedule which is "come back to this session in ten minutes", each execution here is an independent new session.
Core Capabilities
- Supports four scheduling types: one-time, fixed interval (≥5 minutes), daily, weekly (by IANA timezone), daily/weekly schedules are normalized to RFC 5545 RRULE for persistence
- Each trigger executes in a brand new root Agent + new Session, with prompts explicitly marked source.kind = "automation" for auditability
- Provides a Web "Automation" tab for creating, pausing/resuming, running immediately, deleting, and viewing history directly in the browser
- Provides 6 Agent tools (automation_create / list / update / run_now / runs / delete), tool scope bound to the current workspace, cannot cross workspaces
- Each execution leaves a complete record (definition version, prompt snapshot, target snapshot, scheduled time, result Session ID, summary, structured errors), status includes queued / running / succeeded / failed / skipped / cancelled
- Security guardrails: only accepts read-only / workspace-write permissions; approval policy fixed to never; background processes rejected; tool whitelist strictly validated at the executor layer
Technical Implementation
- Language: TypeScript (ESM, main entry compiled to lib/)
- Key Dependencies: luxon (timezone and DST calculations), zod (domain schema and schedule validation), @deepseek-ai/cordis (host plugin runtime)
- Architecture Pattern: Single Cordis plugin split into two lines—Host side (src/index.ts / service.ts) holds the single authoritative service, Client side (src/client/index.ts) injects Web tabs via conversation.view slot; Agent tools are dynamically attached to each root Agent through agent/created events
- Entry Files: src/index.ts (Host entry), src/client/index.ts (Web client entry, exposed via package.json#dsh.client)
Use Cases
Suitable for people who need DSH to "independently" complete coding/inspection/regression tasks at specified times or intervals, such as automatically running regression triage at 9:30 AM on workdays, generating weekly repository health reports, or delayed retesting for an unstable failure. Tasks must be written as self-contained and independently verifiable, not suitable for "continue from last chat" or "fix everything" that relies on conversation context.
Prerequisites and Compatibility
| Dependency | Minimum Version | Notes |
|---|---|---|
| Node.js | ^22.19.0 || >=24.0.0 | Enforced by package.json#engines; won't run below this version |
| React (optional) | ^18.2.0 | peerDependencies, optional; only needed for Web client |
| Platform | Cross-platform | No os/cpu restrictions declared; pure TypeScript/Node implementation |
| Native modules | None | No dependencies on node-pty, node:sqlite, or similar native modules |
Installation
dsh plugin --profile web add github:titanwings/dsh-automation
Configuration Options
| Configuration | Type | Description | Default Value |
|---|---|---|---|
| maxConcurrentRuns | Integer 1-32 | Maximum concurrent runs allowed at any time; each automation remains internally exclusive | 2 |
| runTimeoutMinutes | Integer 1-1440 | Maximum duration in minutes before a run is cancelled and marked failed | 60 |
| misfireGraceMinutes | Integer 0-10080 | Maximum delay in minutes for catching up on recent due items after Host recovery; exceeded items are marked as misfire skipped | 15 |
| historyLimit | Integer 1-5000 | Maximum finished run records retained per automation; in-progress or queued runs are never trimmed | 200 |
| archiveRunSessions | Boolean | Whether to archive finished run Sessions from the regular session list; current DSH host has no unarchive API, archived sessions cannot be reopened | false |
FAQ
Q: Does this plugin add a cron to DSH?
A: It's more restrictive and secure than cron. Each trigger executes a self-contained prompt in a brand new root Agent + new Session, with permissions limited to read-only or workspace-write only; danger-full-access is not accepted, and arbitrary shell execution is prevented.
Q: Can automation tasks inherit the current session's context, inbox, or historical approvals?
A: No. Each run cannot access the source session's history, inbox, or historical authorizations; tasks are explicitly delivered with source.kind = "automation" for traceable behavior.
Q: If the host crashes and misses an execution time, will it rerun?
A: No. Within the default 15-minute tolerance window, only the most recent due item is backfilled; earlier ones are marked as misfire skipped; runs with potential side effects are not silently re-executed.
Q: What happens if execution times out or crashes mid-run?
A: A single run is cancelled and marked failed after the default 60-minute timeout; when the Host restarts, any lingering queued/running records are uniformly marked as failed(host_interrupted), with no silent retry.
Q: Can I manage automations from both Web and Agent?
A: Yes. The Web has an "Automation" tab (create, pause/resume, run immediately, delete, view history), and any root Agent can invoke 6 tools: automation_create / list / update / run_now / runs / delete. Tool scope is bound to the caller's current workspace and cannot target other workspaces.
Q: Does deleting a task also delete its history?
A: No. Deletion only removes the definition; finished run records are retained for auditing; only the oldest finished records are trimmed by historyLimit (default 200 per task); in-progress or queued runs are never trimmed.
Learning Curve
Advanced — Requires understanding DSH's workspace, Agent presets, permission presets, and session model, plus writing "self-contained, independently verifiable" prompts; scheduling syntax and timezone/DST rules also require some learning time.
Known Issues and Limitations
- No same-session heartbeat reminders; use DSH Core Schedule if needed
- No raw cron expressions or arbitrary shell commands
- Does not accept danger-full-access in unattended mode
- No automatic retry for runs with potential side effects
- No Git worktree creation or cleanup
- No multi-workspace targeting, DAG dependencies, or cross-run hidden memory
- No email, SMS, push, or other external notification channels
- No "exactly once" guarantee for external side effects, only "at most once" dispatch
- Local execution only; multiple Hosts cannot share the same storage directory (README.md:230)
- Version 0.1 does not implement OS-level daemon
- Tool whitelist rejects bash/pwsh with run_in_background=true (src/executor.ts:33-42)
- After enabling archiveRunSessions, archived Sessions cannot be reopened in the current Harness version
⏱️ dsh-automation
Run coding tasks on schedule. Manage them from Web or Agent.
|
🕒 Need recurring or one-shot coding work to run later without relying on an old chat? |
✨ dsh-automation turns all three requirements into one workflow.
Create and manage schedules from DSH Web or any eligible root Agent. Every dispatched occurrence starts in a fresh root Agent and Session, then leaves an auditable record.
Self-contained task + schedule + permission boundary → fresh root Agent + fresh Session + durable run history
Why automation · Features · Install · Quick start · Safety · Technical details
English · 简体中文


🎯 Why automation
DSH Core Schedule is the right tool for reminders in the current conversation: “come back to this Session in ten minutes.” dsh-automation handles a different job: “run this complete task independently every weekday and leave me a result I can inspect.”
| DSH Core Schedule | dsh-automation | |
|---|---|---|
| Execution context | Returns to the same live Agent | Starts a fresh root Agent and Session |
| Input | A follow-up inside existing context | A saved, self-contained task |
| Scope | Current Session Log | One canonical DSH workspace |
| History | Conversation events | Definition revisions and durable run records |
| Best for | Reminders and same-chat follow-ups | Repeated or one-shot standalone coding work |
If a task depends on unstated chat history, needs an interactive approval halfway through, or should react to a file, HTTP, or process condition rather than time, it is not a good automation yet.
✨ Features
🕹️ One control plane, two ways in
- DSH Web: use the Automations conversation tab to create a rule, pause or resume it, run it now, delete it, and inspect recent runs.
- Any eligible root Agent: ask in natural language. Six scoped tools let the Agent manage automations only for its exact workspace.
There is no separate bot, daemon UI, or third-party scheduler to operate.
📅 Schedules people can read
Create a one-shot, fixed-interval, daily, or weekly rule. Daily and weekly schedules use an IANA time zone; the friendly form is normalized into a validated RFC 5545 RRULE for persistence and inspection.

🧼 A clean execution boundary every time
Each dispatched occurrence receives:
- a new Session ID and fresh root Agent;
- the saved prompt, not the source conversation history;
- the captured workspace, cwd, Agent preset, model target, and permission preset;
- an explicit
automationmessage source containing the automation ID, run ID, and scheduled time; - a terminal result derived from the actual DSH turn end, not merely “message delivered.”
🧾 History that explains failure as well as success
Runs progress through queued, running, and a terminal state such as succeeded, failed, skipped, or cancelled. Each record keeps its definition revision, prompt and target snapshot, scheduled time, result Session ID, bounded summary, and structured error.

Updating a definition increments its revision, so each retained run still identifies what it executed. Deleting the definition does not immediately erase those run records. Retention removes only the oldest terminal records; queued and running records are never pruned.
Set archiveRunSessions: true in the Cordis plugin config to archive completed, failed, cancelled, and other terminal run Sessions from the ordinary DSH conversation list. Their logs are not deleted: the Automations run history keeps the Session ID, summary, and error as an auditable inbox. Current Harness releases do not expose an unarchive API, so an archived result is labeled instead of offering a broken Session-open action. The default is false and preserves ordinary Session navigation.
⚡ Install
Install the GitHub bundle into the DSH Web profile, then restart dsh web:
dsh plugin --profile web add github:titanwings/dsh-automation#v0.1.6
The version tag keeps the install reproducible; a reviewed commit SHA is equally valid. If you run DSH from its source checkout, use pnpm dsh in place of dsh.
Install from a local checkout
Node.js 22.19 or newer is required.
git clone https://github.com/titanwings/dsh-automation.git
cd dsh-automation
pnpm install
pnpm check
cd /path/to/deepseek-harness
pnpm dsh plugin --profile web add /absolute/path/to/dsh-automation
The repository ships its built Host and Web bundles. Git installation runs no
package build script and needs no allowBuilds entry.
🚀 Quick start
🖥️ From DSH Web
- Open a Session attached to the workspace you want to automate.
- Select Automations next to Chat and Trajectory.
- Enter a self-contained task, schedule, IANA time zone, and permission boundary.
- Use Run now once before relying on the schedule; inspect the resulting Session and run record.
💬 Ask an Agent
Once installed, eligible root Agents receive the management tools. For example:
Create a read-only automation called "Weekday regression triage" for this workspace.
Run it Monday through Friday at 09:30 in Asia/Shanghai. Inspect the latest local test
evidence, identify regressions, and return a short report. Do not modify files.
| Tool | Purpose |
|---|---|
automation_create | Create a workspace-bound standalone rule. |
automation_list | Read rules, next occurrences, and recent history. |
automation_update | Change name, prompt, cadence, permission, or active/paused state. |
automation_run_now | Queue one manual occurrence with the same boundary. |
automation_runs | Read bounded run history, errors, summaries, and Session IDs. |
automation_delete | Delete the definition while retaining durable run records. |
Plugin-level approval asks for human confirmation when an Agent creates or expands unattended future work. Read operations and a pause-only update do not add that extra approval step.
🧰 Good automation candidates
The best automations are repeatable, bounded, and easy to verify.
| Automation | Suggested boundary | Why it is useful |
|---|---|---|
| Weekday regression triage | read-only | Inspect local test evidence, group failures, and leave a concise diagnosis in a new Session. |
| Weekly repository health report | read-only | Review stale TODOs, dependency manifests, ignored failures, and test gaps without changing the tree. |
| One-shot verification | read-only | Recheck a flaky failure later and preserve evidence outside the current chat. |
| Generated-code refresh | workspace-write | Rebuild a known generated artifact, run focused checks, and report the exact diff. |
| Maintenance fix window | workspace-write | Reproduce one bounded issue, make the smallest verified fix, and stop when acceptance checks pass. |
A strong task states the goal, evidence to inspect, allowed changes, verification, and stopping condition. Avoid prompts such as “continue what we discussed” or “fix everything”: scheduled runs do not inherit the conversation that created them.
🛡️ A schedule is not permission
Unattended coding needs a smaller trust boundary than an interactive chat. dsh-automation makes these constraints explicit:
- No inherited authority. A run receives no source-chat history, inbox, grant, or past approval.
- Two permission modes only. Rules may use
read-onlyorworkspace-write; unattendeddanger-full-accessis not accepted. - Fail closed. Each fresh Session uses approval policy
never. A tool that still requires interactive approval fails instead of waiting forever or silently escalating. - Exact workspace scope. Agent tools bind to the caller's canonical registered workspace; callers cannot supply an arbitrary target path.
- Explicit capability allowlist. The fresh Agent admits a small coding-tool set. Interactive questions, plans, goals, nested Agents, runtime plugin mounting, terminal/background jobs, recursive automation management, and unknown third-party tools are denied by an Agent-scoped final guard.
- Loopback Web control. The management RPC channel accepts loopback authority only.
- Traceable origin. The task enters the Session with
source.kind = automation, plus the automation/run identity and scheduled time. It never impersonates a human message. - No blind retries. Once an Agent may have produced side effects, the plugin does not automatically retry it.
These boundaries do not turn every third-party DSH tool into a sandbox. Foreground shell and network behavior still depends on the selected Agent preset, tool set, and DSH guards. Review a task with Run now before enabling unattended writes.
🔧 Technical details
⏱️ Scheduling and recovery semantics
| Situation | Behavior |
|---|---|
| Interval | Minimum five minutes; the first run occurs after one full interval, not immediately. |
| Daily / weekly | Evaluated at local HH:mm in an explicit IANA zone; nonexistent DST wall times are skipped rather than shifted. |
| Overlap | One active run per automation. A due occurrence is recorded as skipped(overlap) if its previous run is queued or running. |
| Host restarts late | Within the grace window (15 minutes by default), only the latest due occurrence can catch up. Older work is not replayed as a write backlog. |
| Run timeout | The Agent is cancelled after 60 minutes by default and the run is recorded as failed. |
| Host crash | Persisted queued or running records become failed(host_interrupted) on recovery; they are not secretly re-executed. |
| Session list | With archiveRunSessions enabled, terminal run Sessions are durably archived after their run record is saved. Startup retries archival for an interrupted terminal record, and an archive failure never changes the run outcome. |
| Retry | Manual Run now only. There is no automatic side-effect retry. |
A deterministic occurrence key prevents the scheduler from dispatching the same recorded occurrence twice. This is an at-most-once dispatch policy, not a claim that external side effects are exactly once.
The DSH Host must be running for a task to start. Version 0.1 is not an operating-system daemon and does not coordinate multiple Hosts over one storage directory.
🏗️ Architecture
The product model is inspired by Codex Scheduled tasks, especially the distinction between returning to a chat and starting a standalone run. The implementation is native to DSH and Cordis; it does not copy Codex internals or patch DSH Core.
flowchart LR
UI["Web control center"] --> Service["Automation service"]
Tools["Agent-scoped tools"] --> Service
Service --> Definitions["Durable definitions"]
Clock["Cordis-owned clock"] --> Claim["Durable occurrence claim"]
Definitions --> Clock
Claim --> Executor["Run executor"]
Executor --> Agent["Fresh root Agent + Session"]
Agent --> Runs["Durable run history"]
Runs --> Service
| Layer | Owns | Does not own |
|---|---|---|
| Definition/run store | Durable facts and revision snapshots | Timers or Agents |
| Clock | Finding the next due occurrence | Prompts, permissions, or execution |
| Executor | One already-claimed fresh Agent run | Schedule mutation |
| Agent tools / Web RPC | Validated service calls | Tables, timers, or direct Agent construction |
| Web client | Native conversation.view presentation | Authoritative due state |
Cordis disposal stops the clock, cancels plugin-owned live handles, removes tools/RPC/UI, and closes storage without inventing a successful run. The full rationale and data model are in the design document.
⚙️ Configuration
The included cordis.patch.yml uses conservative defaults:
| Option | Default | Meaning |
|---|---|---|
maxConcurrentRuns | 2 | Global execution capacity for this Host. Per-automation overlap is still disabled. |
runTimeoutMinutes | 60 | Maximum wall-clock time for one fresh Agent run. |
misfireGraceMinutes | 15 | How late the latest due occurrence may catch up after downtime. |
historyLimit | 200 | Durable terminal-run retention per automation; active records are always kept. |
archiveRunSessions | false | Opt in to archiving terminal run Sessions from the ordinary conversation list while preserving their logs and durable Automation result metadata. Current Harness releases cannot directly reopen an archived Session. |
Edit the plugin row in the deployment profile if you need different values. Increasing concurrency or timeout expands the amount of unattended work; treat those changes as policy decisions.
🚧 Current limits
Version 0.1 deliberately does not provide:
- same-chat heartbeats — use DSH Core Schedule;
- raw cron or arbitrary shell actions;
- unattended full access;
- automatic retry of a run that may have side effects;
- Git worktree creation or cleanup;
- multi-workspace targets, DAGs, or hidden cross-run memory;
- external email, SMS, or push delivery;
- a guarantee of exactly-once external side effects.
Only local execution is implemented. A stable DSH worktree lifecycle service should exist before a UI toggle claims worktree isolation.
🧪 Development
pnpm typecheck
pnpm test
pnpm build
# or all three
pnpm check
The package builds a Host ESM bundle and a Web client bundle for DSH's window.__ModuleLoader__ contract. Tests cover recurrence and DST behavior, durable-domain invariants, Agent capability guards, scheduler overlap/recovery/retention, and client schedule/localization helpers.
📄 License
MIT. This is an independent community plugin for DeepSeek Harness. “Codex” is referenced only to describe the product pattern that informed the design.
Read the usage guide →
Install steps, key points, FAQ and compatibility for this plugin — auto-derived from indexed fields.
Listing badge
[](https://deepseek-plugin.org/plugins/titanwings/dsh-automation)Paste this markdown into your GitHub README to link back to this listing. The badge only states the listing — not a security endorsement.