Files
microsoft-SkillOpt/plugins/devin/README.md
Ismar 6e10394e86 feat(devin): add SessionEnd hook for activity tracking (#5)
The Claude Code plugin ships a SessionEnd hook that logs a cheap timestamp
+ PWD marker to ~/.skillopt-sleep/session-end.log so the next nightly cycle
knows there is fresh activity to harvest. The Devin plugin had no
equivalent — nightly runs relied on cron alone with no activity signal.

Devin CLI supports SessionEnd hooks via .devin/hooks.v1.json (same JSON
format as Claude Code), firing with {"reason": "..."} on stdin and setting
DEVIN_PROJECT_DIR to the project root.

Add hooks/hooks.v1.json (SessionEnd hook config) and
hooks/on-session-end.sh (mirrors the Claude Code on-session-end.sh: append
timestamp + project dir, non-blocking, no API spend). Update README install
instructions with the optional copy step.
2026-07-16 15:20:52 +02:00

4.3 KiB

SkillOpt-Sleep — Devin integration

Give Devin (Cognition) a nightly sleep cycle via a tiny MCP server that exposes the skillopt_sleep engine as tools. MCP is Devin's supported way to add custom tooling, so this works in Devin's CLI and IDE.

Devin doesn't write transcripts in the format the engine consumes, so this plugin adds a Devin-specific harvester that converts every locally available source into the Claude Code-compatible JSONL the engine reads.

What's here

File Purpose
mcp_server.py stdlib-only MCP (stdio) server exposing sleep_* tools
harvest_devin.py converts Devin ATIF-v1.7 transcripts + agentmemory + .devin/skills into JSONL, with taskKey + outcome envelopes
judge.py reference judge for the deferred/judge branch of the validation gate
mcp-config.example.json drop-in MCP server config
install.sh copies hooks + rules into a project's .devin/ and prints the MCP registration command
devin-rules.snippet.md copied to .devin/rules/skillopt-sleep.md by install.sh
hooks/hooks.v1.json SessionEnd hook config — copied to .devin/hooks.v1.json by install.sh
hooks/on-session-end.sh best-effort activity marker script (called by the hook)

What it harvests

Source Where
Devin transcripts (ATIF-v1.7) ~/.local/share/devin/cli/transcripts/*.json
agentmemory ~/.agentmemory/standalone.json
Skill files .devin/skills/*/SKILL.md

Workspaces are auto-detected from ~/.config/Devin/User/workspaceStorage/*/workspace.json. After sleep_adopt, the evolved skill is synced to .devin/skills/skillopt-sleep-learned/SKILL.md.

Install

Requires Python ≥ 3.10. No third-party packages — the server is pure stdlib.

  1. Install hooks + rules into your project. From the repo root:

    bash plugins/devin/install.sh /path/to/your/project
    

    This copies the SessionEnd hook and rules snippet into the project's .devin/ directory and prints the MCP registration command. The hook is on by default — it logs a cheap activity marker when each session ends so the next nightly cycle knows there is fresh data to harvest. It is non-blocking and spends no API budget. Re-run the script to update.

  2. Register the MCP server. Use mcp-config.example.json as a template, or run the command printed by install.sh:

    devin mcp add skillopt-sleep \
      --env "SKILLOPT_DEVIN_CLAUDE_HOME=$HOME/.skillopt-sleep-devin" \
      -- python3 /abs/path/to/SkillOpt/plugins/devin/mcp_server.py
    
  3. Ask Devin: "run the sleep cycle", "what did the last sleep propose?", "adopt it".

Tools

Tool What it does
sleep_status nights run so far + latest staged proposal
sleep_dry_run preview cycle — no staging; a real backend still makes provider calls
sleep_run full cycle; stages a proposal for review
sleep_adopt apply the staged proposal; syncs skill to the workspace
sleep_harvest debug: list the recurring tasks mined
sleep_schedule install a nightly cron entry (--hour / --minute)
sleep_unschedule remove the nightly cron entry

Default backend is mock (no API spend); the claude, codex, and copilot backends use the corresponding authenticated CLI and budget. The handoff backend runs the cycle with no model subprocess or API key — the engine writes pending model calls to .skillopt-sleep-handoff/PROMPTS.md + pending.json (exit code 3) and resumes after answers are placed in answers/<id>.md; re-run sleep_run with the same arguments to resume. The seven tools call the same python -m skillopt_sleep actions as the other shared-engine integrations.

Data boundary

The Devin harvester reads local ATIF transcripts, agentmemory, and skill files and converts them into the engine's session format. The mock backend keeps that workflow local. A real backend sends truncated excerpts and derived tasks to the selected provider for mining, replay, judging, and reflection. The conversion step is not a guarantee that outbound prompts contain no secrets; review sensitive sources and provider policy before enabling a real backend. See the shared data-boundary guidance and implemented CLI reference.