Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .cursor-plugin/marketplace.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "skillopt",
"owner": {
"name": "Yifan Yang",
"email": "yifanyang@microsoft.com"
},
"metadata": {
"description": "Official SkillOpt plugins for usage-driven, validation-gated agent improvement."
},
"plugins": [
{
"name": "skillopt-sleep",
"source": "plugins/cursor",
"description": "Review recent Cursor sessions, replay recurring work, and stage validation-gated improvements to a Cursor skill for explicit adoption."
}
]
}
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ All notable changes to SkillOpt are documented here. This project adheres to
## [Unreleased]

### Added
- Native SkillOpt-Sleep support for Cursor, including a local plugin command
and skill, Cursor transcript harvesting, and an optional Cursor Agent CLI
backend. Cursor tool-aware replay remains disabled pending live permission-
boundary validation.
- **Cursor Agent research target harness** (`cursor_exec`) for running
supported benchmark rollouts through an installed, authenticated
`cursor-agent`, with sandboxed workspaces, structured trace capture, and
Expand Down
14 changes: 11 additions & 3 deletions docs/guide/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ checkout for those files.
!!! important "PyPI versus `main`"
These docs track the latest `main`. The current PyPI release is `0.2.0`.
The generic research `openai_compatible` backend, SkillOpt-Sleep handoff,
Sleep support for non-Azure OpenAI-compatible endpoints, and the Sleep
`--preferences` flag landed after that release and require a source install
from `main` until the next release.
Sleep support for non-Azure OpenAI-compatible endpoints, the Sleep
`--preferences` flag, and Cursor source/backend/plugin support landed after
that release and require a source install from `main` until the next
release.

### Source checkout

Expand Down Expand Up @@ -128,6 +129,13 @@ Anthropic API client. Install and authenticate `claude`, and set
`CLAUDE_CLI_BIN` only if the executable is not available as `claude` on
`PATH`. `ANTHROPIC_API_KEY` is one authentication option the CLI may consume.

The SkillOpt-Sleep `cursor` backend similarly requires a separately installed
and authenticated `cursor-agent`; harvesting with `--source cursor` alone does
not. Set `SKILLOPT_SLEEP_CURSOR_PATH` when the executable is not on `PATH`, and
`SKILLOPT_SLEEP_CURSOR_MODEL` to override its model. Cursor plugin installation
and the explicit project skill target are documented in the
[Cursor integration guide](https://github.com/microsoft/SkillOpt/blob/main/plugins/cursor/README.md).

OpenAI-compatible servers have three distinct entry points:

1. The research engine's generic `openai_compatible` backend uses
Expand Down
44 changes: 39 additions & 5 deletions docs/guideline.html
Original file line number Diff line number Diff line change
Expand Up @@ -295,9 +295,10 @@ <h2>Install</h2>
<strong>Release boundary</strong>
This guide tracks <code>main</code>. PyPI currently serves 0.2.0; the
generic research <code>openai_compatible</code> backend, Sleep handoff,
SkillOpt-Sleep support for non-Azure OpenAI-compatible endpoints, and the
Sleep <code>--preferences</code> flag require a source install from
<code>main</code> until the next release.
SkillOpt-Sleep support for non-Azure OpenAI-compatible endpoints, the
Sleep <code>--preferences</code> flag, and Cursor source/backend/plugin
support require a source install from <code>main</code> until the next
release.
</div>
<p>See the <a href="https://github.com/microsoft/SkillOpt/blob/main/docs/guide/installation.md">installation guide</a>
for platform notes and dependency boundaries.</p>
Expand Down Expand Up @@ -451,8 +452,25 @@ <h2>SkillOpt-Sleep: safe first run</h2>
<p><code>--project</code> scopes collection but does not automatically
choose a project's skill file. Use <code>--target-skill-path</code> when
you intend to evolve a particular <code>SKILL.md</code>. Transcript source
(<code>claude</code>, <code>codex</code>, or <code>auto</code>) and replay
backend are independent settings.</p>
(<code>claude</code>, <code>codex</code>, <code>cursor</code>, or
<code>auto</code>) and replay backend are independent settings. The existing
<code>auto</code> precedence remains Codex then Claude; select Cursor
explicitly with <code>--source cursor</code>.</p>
<p>Cursor transcripts default to
<code>~/.cursor/projects/&lt;workspace&gt;/agent-transcripts</code>; override
that home with <code>--cursor-home</code>. Model-driven replay requires an
installed, authenticated <code>cursor-agent</code> and
<code>--backend cursor</code>; use <code>--cursor-path</code> when the CLI is
not on <code>PATH</code>. Target
<code>.cursor/skills/skillopt-sleep-learned/SKILL.md</code> explicitly so
adoption updates a project skill rather than the plugin's workflow skill.</p>
<p>The Cursor backend inserts that skill text into prompts; it does not
invoke the file as a native skill. Ordinary calls run in read-only Ask mode
in an empty temporary workspace and cannot inspect files under
<code>--project</code>. Cursor tasks containing a <code>tool_called</code>
check fail before Agent mode starts; use another backend for those tasks.
This validates textual guidance, not end-to-end repository, browser,
service, or filesystem workflows.</p>
<p>For subscription-based workflows that should not launch an API or model
subprocess, use <code>--backend handoff</code> and follow the generated
prompt/answer loop. Read the
Expand All @@ -468,6 +486,7 @@ <h2>Agent integrations</h2>
<tbody>
<tr><td>Claude Code</td><td>Shared-engine plugin and handoff command</td><td><a href="https://github.com/microsoft/SkillOpt/blob/main/plugins/claude-code/README.md">README</a></td></tr>
<tr><td>Codex</td><td>Shared-engine skill shell</td><td><a href="https://github.com/microsoft/SkillOpt/blob/main/plugins/codex/README.md">README</a></td></tr>
<tr><td>Cursor</td><td>Native command and skill, local transcript source, and Cursor Agent backend</td><td><a href="https://github.com/microsoft/SkillOpt/blob/main/plugins/cursor/README.md">README</a></td></tr>
<tr><td>GitHub Copilot</td><td>Shared-engine Sleep MCP plus a separate research MCP</td><td><a href="https://github.com/microsoft/SkillOpt/blob/main/plugins/copilot/README.md">README</a></td></tr>
<tr><td>Devin</td><td>Shared-engine MCP with Devin transcript conversion</td><td><a href="https://github.com/microsoft/SkillOpt/blob/main/plugins/devin/README.md">README</a></td></tr>
<tr><td>OpenClaw</td><td>Independent community/reference adaptation; review locally before use</td><td><a href="https://github.com/microsoft/SkillOpt/blob/main/plugins/openclaw/README.md">README</a></td></tr>
Expand All @@ -491,6 +510,7 @@ <h2>Advanced Sleep controls</h2>
<tr><td><code>dream_rollouts</code></td><td>1</td><td>Single rollout by default; values above 1 enable experimental contrastive replay.</td></tr>
<tr><td><code>dream_factor</code></td><td>0</td><td>Synthetic task variants are off by default.</td></tr>
<tr><td><code>recall_k</code></td><td>0</td><td>Historical associative recall is off by default.</td></tr>
<tr><td><code>replay_mode</code></td><td>mock</td><td>Reporting label for prompt replay; fresh-worktree replay is not implemented.</td></tr>
</tbody>
</table>
</div>
Expand All @@ -499,6 +519,13 @@ <h2>Advanced Sleep controls</h2>
reward/budget controls as advanced features that require task-specific
validation. The reported experiments and their exact settings are in
<a href="https://github.com/microsoft/SkillOpt/blob/main/docs/sleep/RESULTS.md">RESULTS.md</a>.</p>
<p>The managed scheduler persists only project, backend, time, and optional
auto-adopt. For Cursor schedules, put <code>transcript_source</code>,
<code>cursor_home</code>, <code>cursor_path</code>, <code>model</code>, and
<code>target_skill_path</code> in
<code>~/.skillopt-sleep/config.json</code>. Use an absolute Cursor CLI path
and verify authentication for the scheduled account because schedulers may
run with a minimal environment.</p>
</section>

<section id="safety">
Expand All @@ -511,6 +538,13 @@ <h2>Data, privacy, and adoption safety</h2>
is not a guarantee that every outbound model prompt is free of sensitive
content. In particular, do not treat raw coding-agent transcripts as
pre-sanitized.</li>
<li>The Cursor source excludes tool arguments and outputs, retaining only
user/assistant text, explicit turn errors, and tool names. The Cursor
backend still sends transcript-derived prompts through
<code>cursor-agent</code> to Cursor's selected model provider.</li>
<li>A real-backend <code>dry-run</code> still performs provider calls; it
suppresses staging rather than spend. Session and task limits are not hard
provider-call, token, time, or monetary budgets.</li>
<li>Updates are staged for review by default. Use
<code>--auto-adopt</code> only when you have an independent rollback and
validation process.</li>
Expand Down
89 changes: 84 additions & 5 deletions docs/reference/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
> **Version note.** This reference tracks `main`. PyPI 0.2.0 does not yet
> include the generic research `openai_compatible` backend, Sleep handoff,
> Sleep support for non-Azure OpenAI-compatible endpoints, the Sleep
> `--preferences` flag, or the research `cursor_exec` target harness; use a
> source install from `main` for those features until the next release.
> `--preferences` flag, the research `cursor_exec` target harness, or Cursor
> source/backend/plugin support; use a source install from `main` for those
> features until the next release.

## Training

Expand Down Expand Up @@ -125,11 +126,13 @@ Actions are `run`, `dry-run`, `status`, `adopt`, `harvest`, `schedule`, and

| Argument | Description |
|---|---|
| `--project PATH` | Project to evolve (default: current directory) |
| `--project PATH` | Project used for transcript scope, targets, state, and staging (default: current directory) |
| `--scope invoked\|all` | Harvest this project or all projects |
| `--source claude\|codex\|auto` | Transcript source |
| `--backend mock\|claude\|codex\|copilot\|handoff\|azure_openai` | Replay/optimizer backend |
| `--source claude\|codex\|cursor\|auto` | Transcript source; `auto` keeps Codex-then-Claude precedence and does not select Cursor |
| `--backend mock\|claude\|codex\|copilot\|cursor\|handoff\|azure_openai` | Replay/optimizer backend |
| `--model NAME` | Backend-specific model override |
| `--cursor-home PATH` | Override `~/.cursor` for Cursor transcript harvesting |
| `--cursor-path PATH` | Path to the installed Cursor Agent CLI |
| `--preferences TEXT` | House rules supplied to reflection |
| `--lookback-hours N` | Initial transcript lookback; `0` scans all history |
| `--max-sessions N` / `--max-tasks N` | Bound the harvested workload |
Expand All @@ -139,6 +142,82 @@ Actions are `run`, `dry-run`, `status`, `adopt`, `harvest`, `schedule`, and
| `--progress` / `--json` | Progress or machine-readable output |
| `--auto-adopt` | Apply an accepted staged proposal automatically |

### Cursor source and backend

`--source cursor` reads local Cursor JSONL transcripts from
`~/.cursor/projects/<workspace>/agent-transcripts/*/*.jsonl`. Invoked scope uses
Cursor's recorded workspace path, including when `--project` is a nested
directory, and falls back to the sanitized storage name when metadata is not
available. `--scope all` scans every workspace below `cursor_home`. The
harvester retains user/assistant text, explicit turn errors, and tool names,
while excluding tool arguments, tool outputs, and non-message records. It
redacts known secret patterns and filters SkillOpt-generated replay sessions,
but redaction is not a guarantee that outbound prompts contain no sensitive
data.

`--backend cursor` launches an installed, authenticated `cursor-agent`, sends
prompts over stdin, and parses its JSON result. SkillOpt reads the target skill
and includes its text in replay prompts; it does not invoke that file as a native
Cursor skill. Ordinary mining, replay, judging, and reflection calls use
read-only Ask mode in a new empty temporary workspace. Project file reads, file
writes, and MCP tools are denied. `--project` does not change that execution
workspace.

Cursor tool-aware replay is temporarily disabled pending live Cursor
permission-boundary validation. A task with a `tool_called` check fails nonzero
before Agent mode starts and does not stage, adopt, cache, persist state, or
advance the harvest checkpoint. Use another backend for such tasks. The current
Cursor backend therefore does not provide end-to-end validation for skills that
need repository inspection, real CLIs, browsers, running services, or file
changes.

There is no implemented fresh-worktree Cursor replay. If a report says
`replay: mock`, that is the prompt-replay label and does not mean the mock model
backend was selected. Both `run` and `dry-run` perform real-backend provider
calls; `dry-run` suppresses staging, adoption, and persisted state changes, not
spend. Session and task limits do not impose hard provider-call, token, time, or
monetary budgets.
Cursor and its selected model provider can receive the prompt content.

Cursor-specific settings are available through the CLI, config, and environment:

| Purpose | CLI | `~/.skillopt-sleep/config.json` | Environment |
|---|---|---|---|
| Transcript home | `--cursor-home PATH` | `"cursor_home": "/path/to/.cursor"` | none |
| Agent executable | `--cursor-path PATH` | `"cursor_path": "/path/to/cursor-agent"` | `SKILLOPT_SLEEP_CURSOR_PATH` |
| Model | `--model NAME` | `"model": "NAME"` | `SKILLOPT_SLEEP_CURSOR_MODEL` |

Use `cursor-agent --list-models` to inspect model identifiers available to the
authenticated account. When cost depends on a model variant, confirm the billed
variant in Cursor's usage reporting rather than relying only on its display
name.

Target the learned project skill explicitly so accepted updates are visible to
Cursor without modifying the plugin's own `skillopt-sleep` workflow skill:

```bash
skillopt-sleep run --project "$(pwd)" \
--source cursor --backend cursor \
--target-skill-path .cursor/skills/skillopt-sleep-learned/SKILL.md \
--max-sessions 5 --max-tasks 3 --progress
```

The first harvest uses a 72-hour lookback unless `--lookback-hours` is set. A
value of `0` considers all available history while still respecting
`--max-sessions`. A stateful `run`, including a run that mines no tasks, records
a new harvest checkpoint; subsequent runs use that checkpoint rather than the
initial lookback. Use `harvest` or `dry-run` to verify counts before the first
stateful run.

The managed `schedule` command persists the project, backend, time, and optional
auto-adopt setting only. It does not copy source, Cursor paths, model, or target
skill flags into the scheduled command. Put `transcript_source`, `cursor_home`,
`cursor_path`, `model`, and `target_skill_path` in the user config before
scheduling Cursor. Keep `target_skill_path` project-relative as
`.cursor/skills/skillopt-sleep-learned/SKILL.md`, prefer an absolute
`cursor_path`, and verify authentication for the scheduled account because cron
and Task Scheduler may have a minimal environment.

Backend-specific setup for compatible endpoints is documented in
[OpenAI-compatible endpoints for SkillOpt-Sleep](../sleep/openai-compatible-endpoints.md).

Expand Down
Loading