Home

mweinbach / agent-coworker

publicmweinbach/agent-coworker
Overview Code History Branches Pull requestsIssuesInsights
main
HomeOverview Code PRsIssues

feat: Skill Improvement (Beta) with hardened runs, backups, and live settings (#200)

2 months ago

c989f4d
Authored
Max Weinbach7/6/2026, 8:52:04 AM
* feat: add skill improvement beta

Add headless skill improvement scheduling, backups, JSON-RPC controls, and desktop settings UI. Wire skill usage capture after completed turns and cover persistence/config defaults plus restore flows.

* fix(skill-improvement): harden runs, backups, scheduling, and live config

- Roll back failed runs from a per-run snapshot instead of the first-ever
  original, preserving prior improvements and manual edits
- Drive the changed signal from a write/edit dirty flag so reference-only
  edits refresh live skill catalogs and validate correctly
- Make the whole run path exception-safe: crashes roll back, record a failed
  history entry, release the lock, and never leave a stuck retry loop
- Detect and break stale locks from crashed processes (pid + age); keep
  scheduler reschedules silent so busy hours cannot flood run history
- Gate restore behind the run queue + lock, verify backups exist before
  deleting live skills, reuse delete-shadow backups when re-improving a
  shadowed built-in, and clean up backup artifacts after restore
- Preserve corrupt state.json as .corrupt and rebuild the backup registry
  from per-backup sidecar metadata; lock state writes across processes
- Key project-scope jobs per workspace, resolve targets against the workspace
  the usage came from (preferring the exact SKILL.md path used), and keep
  evidence recorded during in-flight runs queued for the next window
- Reload effective config from disk per operation so settings applied through
  workspace control sessions take effect without a server restart
- Drain all queued jobs on run-now, refuse evidence-free named runs, dedupe
  transcripts per turn with per-job caps, include plugin/marketplace skills
  in the all-skills scope, and push status to clients after background runs
- Harden the improver sandbox (symlink escape checks, write caps) and the
  prompt (untrusted transcripts, trigger-tuning guidance)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(desktop): reversible skill exclusions and honest improvement status UI

- Keep excluded skills listed (unchecked) in the improvement checklist so
  exclusion is reversible instead of a one-way door
- Show the restore-backups row whenever backups exist, even with the feature
  toggled off
- Report the actual run outcome (completed/skipped/failed) in the run
  notification instead of assuming success, and surface restore error details
- Render failed history entries with the destructive badge variant

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: detail skill improvement run/restore semantics and status push

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(desktop): keep pending action keys and out-of-scope exclusions stable

- Run/restore actions now own their pending keys end to end; status events
  (including background scheduler broadcasts) no longer wipe keys for
  requests still in flight
- The improvement checklist keeps excluded skills visible even when the
  current scope no longer covers them, so exclusions stay reversible

Addresses both Cursor Bugbot findings on the PR.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(skill-improvement): unique pending-job keys and accurate empty-run toast

- Expose the queue key on pending-job summaries (project-scope jobs from
  different workspaces can share a skillName) and key the desktop list by it
- Use a neutral toast title when a manual run had nothing due instead of
  claiming completion

Addresses the second Cursor Bugbot pass; the session_config model-field
finding is intentional behavior (absence propagates a cleared override,
matching memoryGenerationModel).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(desktop): attribute run toasts only to history the request produced

Snapshot known history entry ids before the run RPC and derive the toast
from entries added by the response, so a background run finishing just
before the click can no longer be mislabeled as the manual action. Without
a prior snapshot, fall back to entries finished after the request started.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

Parent64133a5

64 files changed
  • apps/desktop/electron/services/persistence.ts+12−0
  • apps/desktop/src/app/store.actions/bootstrap.ts+12−0
  • apps/desktop/src/app/store.actions/memory.ts+387−3
  • apps/desktop/src/app/store.actions/workspaceDefaultRecords.ts+6−0
  • apps/desktop/src/app/store.actions/workspaceDefaults.ts+62−0
  • apps/desktop/src/app/store.actions/workspaceMemoryDefaults.ts+84−3
  • apps/desktop/src/app/store.helpers.ts+31−0
  • apps/desktop/src/app/store.helpers/controlSocket.ts+81−6
  • apps/desktop/src/app/store.helpers/runtimeState.ts+3−0
  • apps/desktop/src/app/types.ts+10−0
  • apps/desktop/src/lib/desktopSchemas.ts+4−0
  • apps/desktop/src/ui/settings/pages/MemoryPage.tsx+378−0
  • apps/desktop/test/jsonrpc-single-connection.test.ts+4−0
  • apps/desktop/test/memory-actions.test.ts+210−0
  • apps/desktop/test/workspace-memory-defaults.test.ts+34−0
  • apps/desktop/test/workspace-settings-sync.sessionConfig.test.ts+20−0
  • config/defaults.json+3−0
  • docs/generated/websocket-jsonrpc.d.ts+14−8
  • docs/generated/websocket-jsonrpc.schema.json+1−1
  • docs/websocket-protocol.md+33−2
  • prompts/skill-improver.md+42−0
  • src/agent.ts+3−0
  • src/config.ts+49−0
  • src/server/jsonrpc/routes/index.ts+2−0
  • src/server/jsonrpc/routes/skillImprovement.ts+74−0
  • src/server/jsonrpc/routes/types.ts+2−0
  • src/server/jsonrpc/schema.misc.ts+2−0
  • src/server/jsonrpc/schema.sessionRuntime.ts+10−0
  • src/server/jsonrpc/schema.skillImprovement.ts+20−0
  • src/server/jsonrpc/schema.ts+6−0
  • src/server/protocol.ts+12−1
  • src/server/runtime/ConfigPatchStore.ts+35−0
  • src/server/runtime/ServerRuntime.ts+40−0
  • src/server/runtime/SessionRegistry.ts+3−0
  • src/server/runtime/WorkspaceControl.ts+25−1
  • src/server/session/AgentSession.ts+37−0
  • src/server/session/AgentSessionManagerRegistry.ts+2−0
  • src/server/session/SessionContext.ts+17−0
  • src/server/session/SessionMetadataManager.ts+60−0
  • src/server/session/TurnExecutionManager.ts+2−0
  • src/server/session/turnExecution/referenceInjection.ts+11−0
  • src/server/session/turnExecution/runTurnInvocation.ts+7−0
  • src/server/session/turnExecution/runUserMessageTurn.ts+5−0
  • src/shared/jsonrpcControlSchemas.ts+111−0
  • src/skillImprovement/JobStore.ts+515−0
  • src/skillImprovement/SkillImprovementService.ts+626−0
  • src/skillImprovement/SkillImprover.ts+320−0
  • src/skillImprovement/backups.ts+185−0
  • src/skillImprovement/index.ts+4−0
  • src/skillImprovement/types.ts+163−0
  • src/skills/catalog.ts+4−1
  • src/tools/context.ts+4−0
  • src/tools/skill.ts+7−0
  • src/types.ts+25−0
  • test/jsonrpc/control.skillImprovement.test.ts+129−0
  • test/mcp.test.ts+1−1
  • test/providers/connection-catalog.test.ts+6−0
  • test/server/runtime/configPatchStore.test.ts+36−0
  • test/session.syntheticSkillInjection.test.ts+63−0
  • test/skillImprovement.backups.test.ts+78−0
  • test/skillImprovement.improver.test.ts+166−0
  • test/skillImprovement.jobStore.test.ts+188−0
  • test/skillImprovement.service.test.ts+427−0
  • test/tools/tools.skill.test.ts+10−0