This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
DeepScientist is a local-first autonomous research studio that manages long-horizon research workflows. It's a Python-based system with a Node.js launcher, web UI, and TUI, designed to keep research projects moving through baselines, experiments, and paper outputs.
Core principle: One quest = one Git repository. All durable state lives in files and Git.
# Install from repository
bash install.sh
# Install with LaTeX runtime
bash install.sh --with-tinytex
# Start DeepScientist
ds
# Check system health
ds doctor
# Check specific runner
ds doctor --runner codex
ds doctor --runner claude
ds doctor --runner opencode# Run tests
pytest
# Build web UI
npm --prefix src/ui install
npm --prefix src/ui run build
# Build TUI
npm --prefix src/tui install
npm --prefix src/tui run build
# Validate Python syntax
python3 -m compileall src/deepscientist
# Validate packaging
npm pack --dry-run --ignore-scripts# Quest management
ds init # Create new quest
ds status # Show quest status
ds pause # Pause quest
ds resume # Resume quest
# LaTeX runtime
ds latex status
ds latex install-runtime
# Configuration
ds config # Manage configuration
# Memory and baselines
ds memory # Memory operations
ds baseline # Baseline registry operations- User runs
ds(npm global bin) bin/ds.jsensures uv-managed Python runtime exists at~/DeepScientist/runtime/python-env- Launcher starts Python daemon
- Daemon serves web workspace at
http://127.0.0.1:20999 - Web UI and TUI consume same daemon API
~/DeepScientist/
├── runtime/ # Launcher-managed runtime (uv Python env, tools)
├── config/ # YAML configuration and baseline registry
├── memory/ # Global memory cards
├── quests/ # One quest per Git repository
├── logs/ # Daemon and runtime logs
└── cache/ # Reusable caches (synced skills)
Each quest lives at ~/DeepScientist/quests/<quest_id>/ as a Git repository:
quest_id/
├── quest.yaml # Quest metadata
├── brief.md # Research brief
├── plan.md # Implementation plan
├── status.md # Current status
├── SUMMARY.md # Quest summary
└── .ds/
├── runtime_state.json # Runtime state
├── user_message_queue.json # User message queue
├── events.jsonl # Event log
└── interaction_journal.jsonl # Interaction history
Python Runtime (src/deepscientist/)
cli.py- CLI commandsdaemon/- Web server, API routes, quest execution coordinationquest/- Quest creation, snapshots, state persistenceartifact/- Git-backed structured artifactsmemory/- Global and quest-scoped memorybash_exec/- Managed shell sessionsmcp/- MCP server implementationrunners/- Runner implementations (Codex, Claude, OpenCode)bridges/- Connector transport adaptationchannels/- Connector delivery and runtimeskills/- Skill discovery and installationprompts/- Prompt builderruntime_tools/- Managed local tools (TinyTeX, etc.)
Prompts (src/prompts/)
system.md- Core system promptsystem_copilot.md- Copilot mode promptconnectors/- Connector-specific promptscontracts/- Contract definitionsbenchstore/- BenchStore promptsstart_setup/- Setup prompts
Skills (src/skills/)
Stage skills that define research workflow:
intake-audit/- Initial quest setupscout/- Literature reviewbaseline/- Baseline reproductionidea/- Idea generationexperiment/- Experiment executionanalysis-campaign/- Analysiswrite/- Paper writingfigure-polish/- Figure refinementreview/- Paper reviewrebuttal/- Rebuttal generationfinalize/- Final deliverables
Web UI (src/ui/) - React-based workspace
TUI (src/tui/) - Terminal interface
Only three public MCP namespaces exist:
memory- Memory operationsartifact- Git-backed artifacts and quest operationsbash_exec- Managed shell execution
Do not add new public namespaces like git, connector, or runtime_tool.
Critical: All terminal operations MUST use bash_exec(...). Native shell_command is forbidden.
This includes: ls, cat, git, python, npm, uv, file inspection, package management, etc.
Defined in src/deepscientist/quest/layout.py. Changes require updating:
- Quest services
- Daemon handlers
- UI/TUI consumers
- Tests
Skills are discovered from src/skills/<skill_id>/SKILL.md with frontmatter:
---
name: skill-name
description: One-line purpose
skill_role: stage|companion|custom
skill_order: 60
---Three built-in runners:
codex(primary, battle-tested)claude(experimental)opencode(experimental)
Runners are registered in src/deepscientist/runners/ and discovered via registry.
- Add handler in
src/deepscientist/mcp/server.pyunder appropriate namespace - Update
src/deepscientist/runners/codex.pyapproval policy if needed - Update docs:
docs/en/07_MEMORY_AND_MCP.md,docs/en/14_PROMPT_SKILLS_AND_MCP_GUIDE.md - Add tests in
tests/test_mcp_servers.py
- Create
src/skills/<skill_id>/SKILL.mdwith frontmatter - Update
src/deepscientist/skills/registry.pyif canonical stage/companion - Update
src/deepscientist/prompts/builder.pyif stage needs memory plan - Add tests in
tests/test_stage_skills.py,tests/test_skill_contracts.py
- Add config in
src/deepscientist/config/models.py - Add validation in
src/deepscientist/config/service.py - Add bridge in
src/deepscientist/bridges/connectors.py - Register in
src/deepscientist/bridges/builtins.py - Register channel in
src/deepscientist/channels/builtins.py - Wire daemon lifecycle in
src/deepscientist/daemon/app.pyif needed - Add prompt in
src/prompts/connectors/<connector>.mdif needed - Add tests for config, bridge, and API
- Create provider in
src/deepscientist/runtime_tools/<tool>.py - Implement:
tool_name,status(),install(),resolve_binary() - Register in
src/deepscientist/runtime_tools/builtins.py - Access via
RuntimeToolService, not direct imports - Install under
~/DeepScientist/runtime/tools/
# Run all tests
pytest
# Run specific test file
pytest tests/test_daemon_api.py
# Run with verbose output
pytest -v
# Run with coverage
pytest --cov=src/deepscientistKey test files:
tests/test_daemon_api.py- API contract teststests/test_mcp_servers.py- MCP tool teststests/test_stage_skills.py- Skill teststests/test_codex_runner.py- Runner teststests/test_connector_bridges.py- Connector teststests/test_benchstore.py- BenchStore tests
- Keep files simple with direct control flow
- Avoid unnecessary abstraction layers
- Use small, explicit registries
- Prefer file- and Git-based state over hidden runtime state
- One quest = one Git repository (never violate this)
- Python is authoritative runtime, npm is launcher
- Prompts and skills carry workflow behavior, not rigid schedulers
- User docs:
docs/en/anddocs/zh/ - Architecture:
docs/en/90_ARCHITECTURE.md - Development:
docs/en/91_DEVELOPMENT.md - Contributing:
CONTRIBUTING.md
Update docs when behavior or architecture changes.
- Do not use native
shell_command- always usebash_exec(...) - Do not add new public MCP namespaces beyond
memory,artifact,bash_exec - Do not bypass quest layout contracts - update all consumers together
- Do not commit
node_modules/,dist/,__pycache__/, or local secrets - Do not make quests anything other than Git repositories
- Do not add connector-specific logic to unrelated quest code
- Do not put workflow logic in daemon schedulers - use prompts and skills
Before publishing:
- Python tests pass (
pytest) - Web and TUI bundles build (
npm run ui:build,npm run tui:build) - Packaging validates (
npm pack --dry-run --ignore-scripts) - README and docs match current behavior
- New config/route/state fields have tests