Skip to content

Commit 84d64ab

Browse files
committed
feat(sleep): add DeepSeek Harness transcript source
1 parent db46cd9 commit 84d64ab

8 files changed

Lines changed: 946 additions & 4 deletions

File tree

‎docs/reference/cli.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ Common options for the nightly actions include:
134134
|---|---|
135135
| `--project PATH` | Project used for transcript scope, targets, state, and staging (default: current directory) |
136136
| `--scope invoked\|all` | Harvest this project or all projects |
137-
| `--source claude\|codex\|copilot\|cursor\|pi\|opencode\|auto` | Transcript source; `auto` keeps Codex-then-Claude precedence and does not select Copilot, Cursor, Pi, or OpenCode |
137+
| `--source claude\|codex\|copilot\|cursor\|pi\|opencode\|dsh\|auto` | Transcript source; `auto` keeps Codex-then-Claude precedence and does not select Copilot, Cursor, Pi, OpenCode, or DSH |
138138
| `--backend mock\|claude\|codex\|copilot\|cursor\|pi\|opencode\|handoff\|azure_openai` | Replay/optimizer backend |
139139
| `--model NAME` | Backend-specific model override |
140140
| `--cursor-home PATH` | Override `~/.cursor` for Cursor transcript harvesting |
@@ -144,6 +144,7 @@ Common options for the nightly actions include:
144144
| `--pi-path PATH` | Path to the installed Pi coding-agent CLI |
145145
| `--opencode-path PATH` | Path to the installed OpenCode CLI |
146146
| `--opencode-db PATH` | Path to the OpenCode SQLite history database |
147+
| `--dsh-session-root PATH` | Override the DSH JSONL session root for `--source dsh` (default: `$DSH_HOME/sessions`, or `~/.dsh/sessions`) |
147148
| `--opencode-tool-replay` | Enable OpenCode tool-aware replay for `tool_called` checks in rule judges |
148149
| `--preferences TEXT` | House rules supplied to reflection |
149150
| `--lookback-hours N` | Initial transcript lookback; `0` scans all history |

‎docs/sleep/README.md‎

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,48 @@ The managed scheduler records the backend but does not preserve `--source`,
190190
`~/.skillopt-sleep/config.json`. Use an absolute `pi_path` and verify the
191191
scheduled account's Pi authentication.
192192

193+
### DeepSeek Harness (DSH)
194+
195+
Use `--source dsh` to read local DSH JSONL sessions. By default, SkillOpt uses
196+
DSH's standard `$DSH_HOME/sessions` directory, or `~/.dsh/sessions` when
197+
`DSH_HOME` is unset. Install the optional Zstandard reader first:
198+
199+
```bash
200+
python -m pip install -e ".[dsh]"
201+
skillopt-sleep harvest --project "$(pwd)" --source dsh --progress
202+
```
203+
204+
`--dsh-session-root PATH` remains available only to override that default.
205+
206+
The source reads `session.jsonl` and the default compressed
207+
`session.jsonl.zstd` files below DSH's project/session directory layout. It
208+
does not start DSH, require DSH login, connect to a model provider, or modify
209+
the stored logs. `--source auto` retains Codex-then-Claude precedence and does
210+
not select DSH.
211+
212+
DSH harvesting keeps human user text, visible assistant text, short tool names,
213+
timestamps, and positive/negative feedback signals derived from the immutable
214+
`feedback/record` event. It excludes reasoning, tool arguments and results,
215+
request/provider metadata, attachments, feedback remarks themselves, and
216+
injected user-role context. Malformed sessions are silently skipped as a whole;
217+
other sessions continue. Ordinary fork sessions are retained, while sessions
218+
explicitly marked as subagents and SkillOpt replay sessions are excluded.
219+
220+
The source follows the current observed DSH session format rather than a fixed
221+
application-version matrix. A session whose format or event structure cannot be
222+
safely understood is skipped. Plugin integration and DSH execution are outside
223+
this source's scope.
224+
225+
The managed scheduler does not preserve `--source` or `--dsh-session-root`.
226+
Before scheduling, set the source in `~/.skillopt-sleep/config.json`; add
227+
`dsh_session_root` only when overriding DSH's normal session directory:
228+
229+
```json
230+
{
231+
"transcript_source": "dsh"
232+
}
233+
```
234+
193235
### OpenCode
194236

195237
Use `--source opencode` to read local OpenCode SQLite history without launching

‎pyproject.toml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ docs = ["mkdocs-material>=9.5.0", "mkdocstrings[python]>=0.24.0"]
5555
webui = ["gradio>=5.50.0,<7"]
5656
# Development tools
5757
dev = ["ruff>=0.4.0", "pytest>=8.0.0"]
58+
# DeepSeek Harness JSONL transcript source
59+
dsh = ["zstandard>=0.22.0"]
5860
# All optional dependencies (except docs/dev/webui)
5961
all = [
6062
"alfworld>=0.4.0",

‎skillopt_sleep/__main__.py‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@
1515
--target-skill-path PATH explicit live SKILL.md to stage/adopt
1616
--tasks-file PATH reviewed TaskRecord JSON file to replay instead of harvesting
1717
--backend mock|claude|codex|copilot|cursor|pi|opencode|handoff|azure_openai
18-
--source claude|codex|copilot|copilot_cli|cursor|pi|opencode|auto
18+
--source claude|codex|copilot|copilot_cli|cursor|pi|opencode|dsh|auto
1919
--vscode-workspace-storage PATH
2020
--copilot-cli-session-store PATH
2121
--opencode-db PATH
22+
--dsh-session-root PATH
2223
--model NAME
2324
--lookback-hours N
2425
--auto-adopt
@@ -115,14 +116,16 @@ def _add_common(p: argparse.ArgumentParser) -> None:
115116
p.add_argument("--cursor-home", default="", help="override ~/.cursor for Cursor session harvest")
116117
p.add_argument("--pi-home", default="", help="override ~/.pi for Pi session harvest")
117118
p.add_argument("--source", default="",
118-
choices=["", "claude", "codex", "copilot", "copilot_cli", "cursor", "pi", "opencode", "auto"],
119+
choices=["", "claude", "codex", "copilot", "copilot_cli", "cursor", "pi", "opencode", "dsh", "auto"],
119120
help="session transcript source")
120121
p.add_argument("--vscode-workspace-storage", default="",
121122
help="override VS Code User/workspaceStorage root for copilot source")
122123
p.add_argument("--copilot-cli-session-store", default="",
123124
help="override ~/.copilot/session-store.db for copilot_cli source")
124125
p.add_argument("--opencode-db", default="",
125126
help="override the local OpenCode transcript database")
127+
p.add_argument("--dsh-session-root", default="",
128+
help="override DSH session root (default: $DSH_HOME/sessions or ~/.dsh/sessions)")
126129
p.add_argument("--lookback-hours", type=int, default=None,
127130
help="harvest window in hours; 0 = scan full history")
128131
p.add_argument("--edit-budget", type=int, default=0)
@@ -194,6 +197,8 @@ def _cfg_from_args(args, task_meta: Dict[str, Any] | None = None) -> Any:
194197
if args.opencode_db == ":memory:"
195198
else os.path.abspath(os.path.expanduser(args.opencode_db))
196199
)
200+
if getattr(args, "dsh_session_root", ""):
201+
overrides["dsh_session_root"] = os.path.abspath(os.path.expanduser(args.dsh_session_root))
197202
lh = getattr(args, "lookback_hours", None)
198203
if lh is not None: # --lookback-hours was explicitly passed (0 = full history)
199204
overrides["lookback_hours"] = lh

‎skillopt_sleep/config.py‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232
"vscode_workspace_storage": "", # "" => auto-detect platform defaults
3333
"copilot_cli_session_store": "", # "" => ~/.copilot/session-store.db
3434
"opencode_db": "", # "" => OPENCODE_DB or the OpenCode XDG data path
35-
# Explicit sources also include copilot, copilot_cli, cursor, pi, and opencode.
35+
"dsh_session_root": "", # "" => $DSH_HOME/sessions, or ~/.dsh/sessions
36+
# Explicit sources also include copilot, copilot_cli, cursor, pi, opencode, and dsh.
3637
# ``auto`` keeps the established Codex-then-Claude precedence.
3738
"transcript_source": "claude",
3839
"projects": "invoked", # "invoked" | "all" | [list of abs paths]
@@ -164,6 +165,18 @@ def opencode_db_path(self) -> str:
164165
return ":memory:"
165166
return os.path.abspath(os.path.expanduser(str(value)))
166167

168+
@property
169+
def dsh_session_root(self) -> str:
170+
value = self.data.get("dsh_session_root", "") or ""
171+
if value:
172+
return os.path.abspath(os.path.expanduser(str(value)))
173+
# Match the DSH base bundle: its JSONL persistence root is
174+
# dshHomePath("sessions"), where DSH_HOME defaults to ~/.dsh.
175+
dsh_home = str(os.environ.get("DSH_HOME", ""))
176+
if not dsh_home.strip():
177+
dsh_home = os.path.join(os.path.expanduser("~"), ".dsh")
178+
return os.path.abspath(os.path.expanduser(os.path.join(dsh_home, "sessions")))
179+
167180
@property
168181
def vscode_workspace_storage(self) -> str:
169182
value = self.data.get("vscode_workspace_storage", "") or ""

0 commit comments

Comments
 (0)