{"owner":"Drakkar-Software","repo":"OctoBot","hasSkills":true,"totalSkillsCount":5,"totalTokensCount":3801,"categories":["claude-rule","root-instruction","mcp-config","marketplace","plugin-manifest"],"hasMcp":true,"mcpConfig":{"mcpServers":{"OctoBot":{"command":"npx","args":["-y","@modelcontextprotocol/server-OctoBot"]}}},"found":["CLAUDE.md","AGENTS.md",".cursor/mcp.json",".claude-plugin/marketplace.json",".claude-plugin/plugin.json"],"skills":{"CLAUDE.md":"# OctoBot\n\n## Environment\n\n### Installing pants\n\nPants is not bundled. Install the `scie-pants` launcher once (bootstraps pants 2.30.0 from `pants.toml` on first run):\n\n```bash\ncurl -fsSL https://github.com/pantsbuild/scie-pants/releases/latest/download/scie-pants-linux-x86_64 \\\n  -o /usr/local/bin/pants\nchmod +x /usr/local/bin/pants\npants --version   # triggers bootstrap; prints 2.30.0 when done\n```\n\nIf the GitHub releases URL is reachable but the internal pex download is not, point pants at a locally cached pex binary by adding to `pants.toml` temporarily (do not commit):\n\n```toml\n[pex-cli]\nurl_template = \"file:///path/to/pex\"\n```\n\n### Python virtualenv\n\nResolves are disabled (`enable_resolves = false` in `pants.toml`) — no lockfile is committed. Pants resolves requirements directly from `python_requirement` targets each run.\n\nCreate a local virtualenv from the project requirements for IDE / debugging:\n\n```bash\npython3.13 -m venv .venv\n.venv/bin/pip install -r requirements.txt -r full_requirements.txt\n```\n\nUse `.venv/bin/python` as the interpreter for running and debugging.\n\n> **Interpreter constraint**: `pants.toml` pins `interpreter_constraints = [\"==3.13.*\"]` (wildcard required — `==3.13` matches only 3.13.0 exactly and rejects 3.13.1+).\n\n### PYTHONPATH\n\n```bash\nROOT=$PWD\n# Without tentacles (bare start.py, no tentacle features):\nexport PYTHONPATH=\"$ROOT:$ROOT/packages/agents:$ROOT/packages/async_channel:$ROOT/packages/backtesting:$ROOT/packages/binary:$ROOT/packages/commons:$ROOT/packages/copy:$ROOT/packages/evaluators:$ROOT/packages/flow:$ROOT/packages/node:$ROOT/packages/protocol:$ROOT/packages/services:$ROOT/packages/sync:$ROOT/packages/tentacles_manager:$ROOT/packages/trading\"\n\n# With tentacles (after python start.py tentacles install):\nexport PYTHONPATH=\"$ROOT:$ROOT/packages/agents:$ROOT/packages/async_channel:$ROOT/packages/backtesting:$ROOT/packages/binary:$ROOT/packages/commons:$ROOT/packages/copy:$ROOT/packages/evaluators:$ROOT/packages/flow:$ROOT/packages/node:$ROOT/packages/protocol:$ROOT/packages/services:$ROOT/packages/sync:$ROOT/packages/tentacles:$ROOT/packages/tentacles_manager:$ROOT/packages/trading\"\n```\n\nPYTHONPATH must use absolute paths (`$PWD`-based) — build subprocesses run from tentacle subdirectories and need to resolve all packages.\n\n## Tentacles\n\n- **Source of truth**: `packages/tentacles/` — all tentacle changes go here.\n- **Never edit `tentacles/` directly** — it is generated from `packages/tentacles/` via export+install and will be overwritten.\n- After any change to `packages/tentacles/`, run the **tentacle-manager** agent to export and install.\n\n## Agents\n\nCustom agents live in `.claude/agents/`. They are **not** dispatchable via `subagent_type` — trigger them with `@agent-<name>` in your prompt (e.g. `@agent-test-runner run node tests`), or use `claude --agent <name>` to make one the session agent.\n\n### tentacle-manager\n\nManages the OctoBot tentacles lifecycle: export from source, install from zip, and generate CCXT exchange tentacles. Mirrors the VSCode \"Install tentacles zip\" launch configuration.\n\nUse when: installing tentacles after code changes, generating exchange tentacles from CCXT, or running any `python start.py tentacles` command.\n\nTrigger: `@agent-tentacle-manager` · Definition: `.claude/agents/tentacle-manager.md`\n\n### test-runner\n\nRuns and debugs OctoBot Python tests. Handles root-level tests (`tests/`) and per-package tests (`packages/<name>/tests/`). On failure, reads the test and source code, diagnoses the issue, fixes it, and re-runs.\n\nUse when: running tests, debugging test failures, or verifying changes after code modifications.\n\nTrigger: `@agent-test-runner` · Definition: `.claude/agents/test-runner.md`\n\n## Code Conventions\n\n### Enums\nPlace enums in `<package_root>/enums.py` (e.g. `octobot/enums.py`, `packages/node/octobot_node/enums.py`). Never define enums inline in module files.\n\n### Constants\nPlace module-wide constants in `<package_root>/constants.py`. Private module constants (used only within one file) may stay in that file, prefixed with `_`.\n\n### Typed errors\nDefine a typed error hierarchy rather than raising bare `ValueError`/`KeyError`. Pattern:\n```python\n# errors.py (sibling to the feature module)\nclass FeatureError(Exception): pass\nclass SpecificError(FeatureError): pass\n```\nRe-export from the package `__init__.py`. Use typed catches everywhere — never inspect `str(err).lower()`, and never catch bare `ValueError`/`KeyError` for domain errors.\n\n### TypedDicts for structured dicts\nWhen a dict has a fixed schema (e.g. wallet info returned to callers), define a `typing.TypedDict`. Place it in the module that owns the data, before the class that produces it.\n\n### Import priority in tentacle files\nPrefer the installed `tentacles.Services.Interfaces.*` path first; fall back to bare direct imports (build-time fallback). Pattern:\n```python\ntry:\n    from tentacles.Services.Interfaces.node_api_interface.api.deps import X\nexcept ImportError:\n    from api.deps import X  # type: ignore[no-redef]\n```\nAll files within a tentacle package should use the same priority order.\n\n### Log levels\n- `debug`: verbose diagnostics, expected no-ops.\n- `info`: normal operational events (startup, shutdown, config loaded).\n- `warning`: unexpected but recoverable (auto-unlock skipped, optional feature unavailable).\n- `error`: configuration/state errors that affect functionality (wallet missing, key wrong).\n- `exception`: unexpected exceptions — always re-raise after logging unless the function is a top-level \"best-effort\" path that must not crash the caller.\n\n### Shared filter helpers\nFiltering logic used in multiple places belongs in a shared utility module (e.g. `workflows_util.py`), not duplicated inline. Name with a verb: `filter_by_wallet`, not `_filter`.\n\n## Documentation\n\nDocumentation lives in `docs/content/` and is built with Docusaurus 3. Package docs go under `docs/content/developers/packages/<pkg-name>/`.\n\n### Tone\n\nWrite descriptive prose that explains what things do and why, not how they're implemented line by line. Favor plain-language explanations over technical detail. Reference class or function names when they help anchor the explanation, but don't build the doc around them — the reader should understand the concepts even if names change. The style should be descriptive yet grounded in code, explains design decisions and non-obvious behavior, mentions concrete names only when they clarify the concept.\n\n### What to include\n\n- Architecture and design decisions\n- How components interact and why\n- Important concepts and patterns\n- Code snippets that illustrate non-obvious behavior\n- Configuration that users/developers need to know about\n\n### What NOT to include\n\nThe code is the source of truth. Don't duplicate anything that can be read from source or will break on the next refactor:\n\n- **API surfaces**: function signatures, parameter lists, return types, class hierarchies, enum/constant values, error classes\n- **Project structure**: directory trees, package layouts, dependency lists, requirements, version numbers\n- **Categorized lists**: sections that just group and list code elements (helpers, classes, endpoints) without explaining why they exist\n- **Implementation details**: build config specifics, hidden imports, lifecycle step-by-step sequences\n\n### File format\n\nEach `.md` file must have Docusaurus frontmatter:\n\n```yaml\n---\ntitle: <Title>\ndescription: <One-line description>\nsidebar_position: <number>\n---\n```\n\nThe sidebar uses `autogenerated` for `developers/packages`, so new files appear automatically.\n","AGENTS.md":"# Agent quick pointer (OctoBot repo)\n\nThis repository is the **OctoBot** application and its `packages/*` monorepo. Default integration branch: **`dev`** (open PRs to `dev` unless told otherwise).\n\n## Cursor Cloud\n\n- Environment: [`.cursor/README.md`](.cursor/README.md), `environment.json`, `source .cursor/env.sh`\n- Skill (procedures): `.cursor/skills/octobot-cloud/SKILL.md`\n- Roadmap plans: before `CreatePlan`, if the plan title or description contains `roadmap`, follow `.cursor/skills/cloud-roadmap/SKILL.md`\n- Always-on rules: `.cursor/rules/octobot-cloud.mdc`\n\n## Before you finish\n\n```bash\nsource .cursor/env.sh\npython -m tools.extended_linter --base origin/dev\n```\n\nUse `origin/<base>` matching your PR target. Policy: `tools/extended_linter/config/policy.yaml` — see `tools/extended_linter/ARCHITECTURE.md`. No agent plan files or Node UI Playwright e2e in the diff (`path.deny_agent_plans`, `path.deny_node_web_playwright_e2e`). No accidental agent-doc regressions (`agent_docs.no_regression_vs_merge_base`; see `octobot-cloud.mdc`).\n\n## Architecture for agents\n\nColocated **`AGENTS.md`** files describe package boundaries (owns, deps, tests). They are for automation; human docs live under `docs/content/` (Docusaurus).\n\n### When to read\n\n| Situation | Read |\n|-----------|------|\n| Single package task | `packages/<name>/AGENTS.md` |\n| Core app / CLI / config | [`octobot/AGENTS.md`](octobot/AGENTS.md) |\n| Tentacles sources vs install | [`packages/tentacles/AGENTS.md`](packages/tentacles/AGENTS.md) |\n| Node UI or classic web UI (copy, layout, errors) | [`packages/tentacles/Services/Interfaces/node_web_interface/AGENTS.md`](packages/tentacles/Services/Interfaces/node_web_interface/AGENTS.md), [`packages/tentacles/Services/Interfaces/web_interface/AGENTS.md`](packages/tentacles/Services/Interfaces/web_interface/AGENTS.md), skill **end-user-ui** (`.cursor/skills/end-user-ui/SKILL.md`) |\n| Node journal (record / export) | [`octobot/community/node_journal/AGENTS.md`](octobot/community/node_journal/AGENTS.md), skill **node-journal** (`.cursor/skills/node-journal/SKILL.md`) |\n| Python style (imports, literals, `__init__.py` API) | [CONTRIBUTING-agent.md](CONTRIBUTING-agent.md) — **Python conventions (agents)** |\n| Cross-package or tentacles | This file + every involved colocated `AGENTS.md` |\n| Node UI demo / agent-seed QA | [`tools/agent_seed/README.md`](tools/agent_seed/README.md) + skill **agent-seed** (`.cursor/skills/agent-seed/SKILL.md`) |\n\n### Dependency sketch\n\n```mermaid\nflowchart TB\n  octobot[octobot app]\n  commons[commons]\n  trading[trading]\n  evaluators[evaluators]\n  services[services]\n  tentacles_pkg[packages/tentacles sources]\n  octobot --> commons\n  octobot --> trading\n  octobot --> evaluators\n  octobot --> services\n  trading --> commons\n  evaluators --> commons\n  tentacles_pkg --> services\n```\n\n### CI matrix packages (colocated `AGENTS.md`)\n\n| Package | Path |\n|---------|------|\n| Core application | [`octobot/AGENTS.md`](octobot/AGENTS.md) |\n| Tentacles sources | [`packages/tentacles/AGENTS.md`](packages/tentacles/AGENTS.md) |\n| agents | [`packages/agents/AGENTS.md`](packages/agents/AGENTS.md) |\n| async_channel | [`packages/async_channel/AGENTS.md`](packages/async_channel/AGENTS.md) |\n| backtesting | [`packages/backtesting/AGENTS.md`](packages/backtesting/AGENTS.md) |\n| commons | [`packages/commons/AGENTS.md`](packages/commons/AGENTS.md) |\n| copy | [`packages/copy/AGENTS.md`](packages/copy/AGENTS.md) |\n| evaluators | [`packages/evaluators/AGENTS.md`](packages/evaluators/AGENTS.md) |\n| flow | [`packages/flow/AGENTS.md`](packages/flow/AGENTS.md) |\n| node | [`packages/node/AGENTS.md`](packages/node/AGENTS.md) |\n| protocol | [`packages/protocol/AGENTS.md`](packages/protocol/AGENTS.md) |\n| services | [`packages/services/AGENTS.md`](packages/services/AGENTS.md) |\n| sync | [`packages/sync/AGENTS.md`](packages/sync/AGENTS.md) |\n| tentacles_manager | [`packages/tentacles_manager/AGENTS.md`](packages/tentacles_manager/AGENTS.md) |\n| trading | [`packages/trading/AGENTS.md`](packages/trading/AGENTS.md) |\n\nNew packages: follow **AGENTS.md sections** in [CONTRIBUTING-agent.md](CONTRIBUTING-agent.md).\n\n## Humans\n\n- [CONTRIBUTING-agent.md](CONTRIBUTING-agent.md) — agents, policy, boundaries\n",".cursor/mcp.json":"# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/Drakkar-Software/OctoBot/HEAD/.cursor/mcp.json)",".claude-plugin/marketplace.json":"# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/Drakkar-Software/OctoBot/HEAD/.claude-plugin/marketplace.json)",".claude-plugin/plugin.json":"# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/Drakkar-Software/OctoBot/HEAD/.claude-plugin/plugin.json)"},"files":{"CLAUDE.md":"# OctoBot\n\n## Environment\n\n### Installing pants\n\nPants is not bundled. Install the `scie-pants` launcher once (bootstraps pants 2.30.0 from `pants.toml` on first run):\n\n```bash\ncurl -fsSL https://github.com/pantsbuild/scie-pants/releases/latest/download/scie-pants-linux-x86_64 \\\n  -o /usr/local/bin/pants\nchmod +x /usr/local/bin/pants\npants --version   # triggers bootstrap; prints 2.30.0 when done\n```\n\nIf the GitHub releases URL is reachable but the internal pex download is not, point pants at a locally cached pex binary by adding to `pants.toml` temporarily (do not commit):\n\n```toml\n[pex-cli]\nurl_template = \"file:///path/to/pex\"\n```\n\n### Python virtualenv\n\nResolves are disabled (`enable_resolves = false` in `pants.toml`) — no lockfile is committed. Pants resolves requirements directly from `python_requirement` targets each run.\n\nCreate a local virtualenv from the project requirements for IDE / debugging:\n\n```bash\npython3.13 -m venv .venv\n.venv/bin/pip install -r requirements.txt -r full_requirements.txt\n```\n\nUse `.venv/bin/python` as the interpreter for running and debugging.\n\n> **Interpreter constraint**: `pants.toml` pins `interpreter_constraints = [\"==3.13.*\"]` (wildcard required — `==3.13` matches only 3.13.0 exactly and rejects 3.13.1+).\n\n### PYTHONPATH\n\n```bash\nROOT=$PWD\n# Without tentacles (bare start.py, no tentacle features):\nexport PYTHONPATH=\"$ROOT:$ROOT/packages/agents:$ROOT/packages/async_channel:$ROOT/packages/backtesting:$ROOT/packages/binary:$ROOT/packages/commons:$ROOT/packages/copy:$ROOT/packages/evaluators:$ROOT/packages/flow:$ROOT/packages/node:$ROOT/packages/protocol:$ROOT/packages/services:$ROOT/packages/sync:$ROOT/packages/tentacles_manager:$ROOT/packages/trading\"\n\n# With tentacles (after python start.py tentacles install):\nexport PYTHONPATH=\"$ROOT:$ROOT/packages/agents:$ROOT/packages/async_channel:$ROOT/packages/backtesting:$ROOT/packages/binary:$ROOT/packages/commons:$ROOT/packages/copy:$ROOT/packages/evaluators:$ROOT/packages/flow:$ROOT/packages/node:$ROOT/packages/protocol:$ROOT/packages/services:$ROOT/packages/sync:$ROOT/packages/tentacles:$ROOT/packages/tentacles_manager:$ROOT/packages/trading\"\n```\n\nPYTHONPATH must use absolute paths (`$PWD`-based) — build subprocesses run from tentacle subdirectories and need to resolve all packages.\n\n## Tentacles\n\n- **Source of truth**: `packages/tentacles/` — all tentacle changes go here.\n- **Never edit `tentacles/` directly** — it is generated from `packages/tentacles/` via export+install and will be overwritten.\n- After any change to `packages/tentacles/`, run the **tentacle-manager** agent to export and install.\n\n## Agents\n\nCustom agents live in `.claude/agents/`. They are **not** dispatchable via `subagent_type` — trigger them with `@agent-<name>` in your prompt (e.g. `@agent-test-runner run node tests`), or use `claude --agent <name>` to make one the session agent.\n\n### tentacle-manager\n\nManages the OctoBot tentacles lifecycle: export from source, install from zip, and generate CCXT exchange tentacles. Mirrors the VSCode \"Install tentacles zip\" launch configuration.\n\nUse when: installing tentacles after code changes, generating exchange tentacles from CCXT, or running any `python start.py tentacles` command.\n\nTrigger: `@agent-tentacle-manager` · Definition: `.claude/agents/tentacle-manager.md`\n\n### test-runner\n\nRuns and debugs OctoBot Python tests. Handles root-level tests (`tests/`) and per-package tests (`packages/<name>/tests/`). On failure, reads the test and source code, diagnoses the issue, fixes it, and re-runs.\n\nUse when: running tests, debugging test failures, or verifying changes after code modifications.\n\nTrigger: `@agent-test-runner` · Definition: `.claude/agents/test-runner.md`\n\n## Code Conventions\n\n### Enums\nPlace enums in `<package_root>/enums.py` (e.g. `octobot/enums.py`, `packages/node/octobot_node/enums.py`). Never define enums inline in module files.\n\n### Constants\nPlace module-wide constants in `<package_root>/constants.py`. Private module constants (used only within one file) may stay in that file, prefixed with `_`.\n\n### Typed errors\nDefine a typed error hierarchy rather than raising bare `ValueError`/`KeyError`. Pattern:\n```python\n# errors.py (sibling to the feature module)\nclass FeatureError(Exception): pass\nclass SpecificError(FeatureError): pass\n```\nRe-export from the package `__init__.py`. Use typed catches everywhere — never inspect `str(err).lower()`, and never catch bare `ValueError`/`KeyError` for domain errors.\n\n### TypedDicts for structured dicts\nWhen a dict has a fixed schema (e.g. wallet info returned to callers), define a `typing.TypedDict`. Place it in the module that owns the data, before the class that produces it.\n\n### Import priority in tentacle files\nPrefer the installed `tentacles.Services.Interfaces.*` path first; fall back to bare direct imports (build-time fallback). Pattern:\n```python\ntry:\n    from tentacles.Services.Interfaces.node_api_interface.api.deps import X\nexcept ImportError:\n    from api.deps import X  # type: ignore[no-redef]\n```\nAll files within a tentacle package should use the same priority order.\n\n### Log levels\n- `debug`: verbose diagnostics, expected no-ops.\n- `info`: normal operational events (startup, shutdown, config loaded).\n- `warning`: unexpected but recoverable (auto-unlock skipped, optional feature unavailable).\n- `error`: configuration/state errors that affect functionality (wallet missing, key wrong).\n- `exception`: unexpected exceptions — always re-raise after logging unless the function is a top-level \"best-effort\" path that must not crash the caller.\n\n### Shared filter helpers\nFiltering logic used in multiple places belongs in a shared utility module (e.g. `workflows_util.py`), not duplicated inline. Name with a verb: `filter_by_wallet`, not `_filter`.\n\n## Documentation\n\nDocumentation lives in `docs/content/` and is built with Docusaurus 3. Package docs go under `docs/content/developers/packages/<pkg-name>/`.\n\n### Tone\n\nWrite descriptive prose that explains what things do and why, not how they're implemented line by line. Favor plain-language explanations over technical detail. Reference class or function names when they help anchor the explanation, but don't build the doc around them — the reader should understand the concepts even if names change. The style should be descriptive yet grounded in code, explains design decisions and non-obvious behavior, mentions concrete names only when they clarify the concept.\n\n### What to include\n\n- Architecture and design decisions\n- How components interact and why\n- Important concepts and patterns\n- Code snippets that illustrate non-obvious behavior\n- Configuration that users/developers need to know about\n\n### What NOT to include\n\nThe code is the source of truth. Don't duplicate anything that can be read from source or will break on the next refactor:\n\n- **API surfaces**: function signatures, parameter lists, return types, class hierarchies, enum/constant values, error classes\n- **Project structure**: directory trees, package layouts, dependency lists, requirements, version numbers\n- **Categorized lists**: sections that just group and list code elements (helpers, classes, endpoints) without explaining why they exist\n- **Implementation details**: build config specifics, hidden imports, lifecycle step-by-step sequences\n\n### File format\n\nEach `.md` file must have Docusaurus frontmatter:\n\n```yaml\n---\ntitle: <Title>\ndescription: <One-line description>\nsidebar_position: <number>\n---\n```\n\nThe sidebar uses `autogenerated` for `developers/packages`, so new files appear automatically.\n","AGENTS.md":"# Agent quick pointer (OctoBot repo)\n\nThis repository is the **OctoBot** application and its `packages/*` monorepo. Default integration branch: **`dev`** (open PRs to `dev` unless told otherwise).\n\n## Cursor Cloud\n\n- Environment: [`.cursor/README.md`](.cursor/README.md), `environment.json`, `source .cursor/env.sh`\n- Skill (procedures): `.cursor/skills/octobot-cloud/SKILL.md`\n- Roadmap plans: before `CreatePlan`, if the plan title or description contains `roadmap`, follow `.cursor/skills/cloud-roadmap/SKILL.md`\n- Always-on rules: `.cursor/rules/octobot-cloud.mdc`\n\n## Before you finish\n\n```bash\nsource .cursor/env.sh\npython -m tools.extended_linter --base origin/dev\n```\n\nUse `origin/<base>` matching your PR target. Policy: `tools/extended_linter/config/policy.yaml` — see `tools/extended_linter/ARCHITECTURE.md`. No agent plan files or Node UI Playwright e2e in the diff (`path.deny_agent_plans`, `path.deny_node_web_playwright_e2e`). No accidental agent-doc regressions (`agent_docs.no_regression_vs_merge_base`; see `octobot-cloud.mdc`).\n\n## Architecture for agents\n\nColocated **`AGENTS.md`** files describe package boundaries (owns, deps, tests). They are for automation; human docs live under `docs/content/` (Docusaurus).\n\n### When to read\n\n| Situation | Read |\n|-----------|------|\n| Single package task | `packages/<name>/AGENTS.md` |\n| Core app / CLI / config | [`octobot/AGENTS.md`](octobot/AGENTS.md) |\n| Tentacles sources vs install | [`packages/tentacles/AGENTS.md`](packages/tentacles/AGENTS.md) |\n| Node UI or classic web UI (copy, layout, errors) | [`packages/tentacles/Services/Interfaces/node_web_interface/AGENTS.md`](packages/tentacles/Services/Interfaces/node_web_interface/AGENTS.md), [`packages/tentacles/Services/Interfaces/web_interface/AGENTS.md`](packages/tentacles/Services/Interfaces/web_interface/AGENTS.md), skill **end-user-ui** (`.cursor/skills/end-user-ui/SKILL.md`) |\n| Node journal (record / export) | [`octobot/community/node_journal/AGENTS.md`](octobot/community/node_journal/AGENTS.md), skill **node-journal** (`.cursor/skills/node-journal/SKILL.md`) |\n| Python style (imports, literals, `__init__.py` API) | [CONTRIBUTING-agent.md](CONTRIBUTING-agent.md) — **Python conventions (agents)** |\n| Cross-package or tentacles | This file + every involved colocated `AGENTS.md` |\n| Node UI demo / agent-seed QA | [`tools/agent_seed/README.md`](tools/agent_seed/README.md) + skill **agent-seed** (`.cursor/skills/agent-seed/SKILL.md`) |\n\n### Dependency sketch\n\n```mermaid\nflowchart TB\n  octobot[octobot app]\n  commons[commons]\n  trading[trading]\n  evaluators[evaluators]\n  services[services]\n  tentacles_pkg[packages/tentacles sources]\n  octobot --> commons\n  octobot --> trading\n  octobot --> evaluators\n  octobot --> services\n  trading --> commons\n  evaluators --> commons\n  tentacles_pkg --> services\n```\n\n### CI matrix packages (colocated `AGENTS.md`)\n\n| Package | Path |\n|---------|------|\n| Core application | [`octobot/AGENTS.md`](octobot/AGENTS.md) |\n| Tentacles sources | [`packages/tentacles/AGENTS.md`](packages/tentacles/AGENTS.md) |\n| agents | [`packages/agents/AGENTS.md`](packages/agents/AGENTS.md) |\n| async_channel | [`packages/async_channel/AGENTS.md`](packages/async_channel/AGENTS.md) |\n| backtesting | [`packages/backtesting/AGENTS.md`](packages/backtesting/AGENTS.md) |\n| commons | [`packages/commons/AGENTS.md`](packages/commons/AGENTS.md) |\n| copy | [`packages/copy/AGENTS.md`](packages/copy/AGENTS.md) |\n| evaluators | [`packages/evaluators/AGENTS.md`](packages/evaluators/AGENTS.md) |\n| flow | [`packages/flow/AGENTS.md`](packages/flow/AGENTS.md) |\n| node | [`packages/node/AGENTS.md`](packages/node/AGENTS.md) |\n| protocol | [`packages/protocol/AGENTS.md`](packages/protocol/AGENTS.md) |\n| services | [`packages/services/AGENTS.md`](packages/services/AGENTS.md) |\n| sync | [`packages/sync/AGENTS.md`](packages/sync/AGENTS.md) |\n| tentacles_manager | [`packages/tentacles_manager/AGENTS.md`](packages/tentacles_manager/AGENTS.md) |\n| trading | [`packages/trading/AGENTS.md`](packages/trading/AGENTS.md) |\n\nNew packages: follow **AGENTS.md sections** in [CONTRIBUTING-agent.md](CONTRIBUTING-agent.md).\n\n## Humans\n\n- [CONTRIBUTING-agent.md](CONTRIBUTING-agent.md) — agents, policy, boundaries\n",".cursor/mcp.json":"# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/Drakkar-Software/OctoBot/HEAD/.cursor/mcp.json)",".claude-plugin/marketplace.json":"# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/Drakkar-Software/OctoBot/HEAD/.claude-plugin/marketplace.json)",".claude-plugin/plugin.json":"# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/Drakkar-Software/OctoBot/HEAD/.claude-plugin/plugin.json)"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","rawUrl":"https://raw.githubusercontent.com/Drakkar-Software/OctoBot/HEAD/AGENTS.md","title":"AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"# Agent quick pointer (OctoBot repo)\n\nThis repository is the **OctoBot** application and its `packages/*` monorepo. Default integration branch: **`dev`** (open PRs to `dev` unless told otherwise).\n\n## Cursor Cloud\n\n- Environment: [`.cursor/README.md`](.cursor/README.md), `environment.json`, `source .cursor/env.sh`\n- Skill (procedures): `.cursor/skills/octobot-cloud/SKILL.md`\n- Roadmap plans: before `CreatePlan`, if the plan title or description contains `roadmap`, follow `.cursor/skills/cloud-roadmap/SKILL.md`\n- Always-on rules: `.cursor/rules/octobot-cloud.mdc`\n\n## Before you finish\n\n```bash\nsource .cursor/env.sh\npython -m tools.extended_linter --base origin/dev\n```\n\nUse `origin/<base>` matching your PR target. Policy: `tools/extended_linter/config/policy.yaml` — see `tools/extended_linter/ARCHITECTURE.md`. No agent plan files or Node UI Playwright e2e in the diff (`path.deny_agent_plans`, `path.deny_node_web_playwright_e2e`). No accidental agent-doc regressions (`agent_docs.no_regression_vs_merge_base`; see `octobot-cloud.mdc`).\n\n## Architecture for agents\n\nColocated **`AGENTS.md`** files describe package boundaries (owns, deps, tests). They are for automation; human docs live under `docs/content/` (Docusaurus).\n\n### When to read\n\n| Situation | Read |\n|-----------|------|\n| Single package task | `packages/<name>/AGENTS.md` |\n| Core app / CLI / config | [`octobot/AGENTS.md`](octobot/AGENTS.md) |\n| Tentacles sources vs install | [`packages/tentacles/AGENTS.md`](packages/tentacles/AGENTS.md) |\n| Node UI or classic web UI (copy, layout, errors) | [`packages/tentacles/Services/Interfaces/node_web_interface/AGENTS.md`](packages/tentacles/Services/Interfaces/node_web_interface/AGENTS.md), [`packages/tentacles/Services/Interfaces/web_interface/AGENTS.md`](packages/tentacles/Services/Interfaces/web_interface/AGENTS.md), skill **end-user-ui** (`.cursor/skills/end-user-ui/SKILL.md`) |\n| Node journal (record / export) | [`octobot/community/node_journal/AGENTS.md`](octobot/community/node_journal/AGENTS.md), skill **node-journal** (`.cursor/skills/node-journal/SKILL.md`) |\n| Python style (imports, literals, `__init__.py` API) | [CONTRIBUTING-agent.md](CONTRIBUTING-agent.md) — **Python conventions (agents)** |\n| Cross-package or tentacles | This file + every involved colocated `AGENTS.md` |\n| Node UI demo / agent-seed QA | [`tools/agent_seed/README.md`](tools/agent_seed/README.md) + skill **agent-seed** (`.cursor/skills/agent-seed/SKILL.md`) |\n\n### Dependency sketch\n\n```mermaid\nflowchart TB\n  octobot[octobot app]\n  commons[commons]\n  trading[trading]\n  evaluators[evaluators]\n  services[services]\n  tentacles_pkg[packages/tentacles sources]\n  octobot --> commons\n  octobot --> trading\n  octobot --> evaluators\n  octobot --> services\n  trading --> commons\n  evaluators --> commons\n  tentacles_pkg --> services\n```\n\n### CI matrix packages (colocated `AGENTS.md`)\n\n| Package | Path |\n|---------|------|\n| Core application | [`octobot/AGENTS.md`](octobot/AGENTS.md) |\n| Tentacles sources | [`packages/tentacles/AGENTS.md`](packages/tentacles/AGENTS.md) |\n| agents | [`packages/agents/AGENTS.md`](packages/agents/AGENTS.md) |\n| async_channel | [`packages/async_channel/AGENTS.md`](packages/async_channel/AGENTS.md) |\n| backtesting | [`packages/backtesting/AGENTS.md`](packages/backtesting/AGENTS.md) |\n| commons | [`packages/commons/AGENTS.md`](packages/commons/AGENTS.md) |\n| copy | [`packages/copy/AGENTS.md`](packages/copy/AGENTS.md) |\n| evaluators | [`packages/evaluators/AGENTS.md`](packages/evaluators/AGENTS.md) |\n| flow | [`packages/flow/AGENTS.md`](packages/flow/AGENTS.md) |\n| node | [`packages/node/AGENTS.md`](packages/node/AGENTS.md) |\n| protocol | [`packages/protocol/AGENTS.md`](packages/protocol/AGENTS.md) |\n| services | [`packages/services/AGENTS.md`](packages/services/AGENTS.md) |\n| sync | [`packages/sync/AGENTS.md`](packages/sync/AGENTS.md) |\n| tentacles_manager | [`packages/tentacles_manager/AGENTS.md`](packages/tentacles_manager/AGENTS.md) |\n| trading | [`packages/trading/AGENTS.md`](packages/trading/AGENTS.md) |\n\nNew packages: follow **AGENTS.md sections** in [CONTRIBUTING-agent.md](CONTRIBUTING-agent.md).\n\n## Humans\n\n- [CONTRIBUTING-agent.md](CONTRIBUTING-agent.md) — agents, policy, boundaries\n","isInternal":false,"tokens":1162,"sizeBytes":4261},{"name":"CLAUDE.md","path":"CLAUDE.md","rawUrl":"https://raw.githubusercontent.com/Drakkar-Software/OctoBot/HEAD/CLAUDE.md","title":"Claude Agent Guidelines & System Prompt","category":"claude-rule","format":"markdown","content":"# OctoBot\n\n## Environment\n\n### Installing pants\n\nPants is not bundled. Install the `scie-pants` launcher once (bootstraps pants 2.30.0 from `pants.toml` on first run):\n\n```bash\ncurl -fsSL https://github.com/pantsbuild/scie-pants/releases/latest/download/scie-pants-linux-x86_64 \\\n  -o /usr/local/bin/pants\nchmod +x /usr/local/bin/pants\npants --version   # triggers bootstrap; prints 2.30.0 when done\n```\n\nIf the GitHub releases URL is reachable but the internal pex download is not, point pants at a locally cached pex binary by adding to `pants.toml` temporarily (do not commit):\n\n```toml\n[pex-cli]\nurl_template = \"file:///path/to/pex\"\n```\n\n### Python virtualenv\n\nResolves are disabled (`enable_resolves = false` in `pants.toml`) — no lockfile is committed. Pants resolves requirements directly from `python_requirement` targets each run.\n\nCreate a local virtualenv from the project requirements for IDE / debugging:\n\n```bash\npython3.13 -m venv .venv\n.venv/bin/pip install -r requirements.txt -r full_requirements.txt\n```\n\nUse `.venv/bin/python` as the interpreter for running and debugging.\n\n> **Interpreter constraint**: `pants.toml` pins `interpreter_constraints = [\"==3.13.*\"]` (wildcard required — `==3.13` matches only 3.13.0 exactly and rejects 3.13.1+).\n\n### PYTHONPATH\n\n```bash\nROOT=$PWD\n# Without tentacles (bare start.py, no tentacle features):\nexport PYTHONPATH=\"$ROOT:$ROOT/packages/agents:$ROOT/packages/async_channel:$ROOT/packages/backtesting:$ROOT/packages/binary:$ROOT/packages/commons:$ROOT/packages/copy:$ROOT/packages/evaluators:$ROOT/packages/flow:$ROOT/packages/node:$ROOT/packages/protocol:$ROOT/packages/services:$ROOT/packages/sync:$ROOT/packages/tentacles_manager:$ROOT/packages/trading\"\n\n# With tentacles (after python start.py tentacles install):\nexport PYTHONPATH=\"$ROOT:$ROOT/packages/agents:$ROOT/packages/async_channel:$ROOT/packages/backtesting:$ROOT/packages/binary:$ROOT/packages/commons:$ROOT/packages/copy:$ROOT/packages/evaluators:$ROOT/packages/flow:$ROOT/packages/node:$ROOT/packages/protocol:$ROOT/packages/services:$ROOT/packages/sync:$ROOT/packages/tentacles:$ROOT/packages/tentacles_manager:$ROOT/packages/trading\"\n```\n\nPYTHONPATH must use absolute paths (`$PWD`-based) — build subprocesses run from tentacle subdirectories and need to resolve all packages.\n\n## Tentacles\n\n- **Source of truth**: `packages/tentacles/` — all tentacle changes go here.\n- **Never edit `tentacles/` directly** — it is generated from `packages/tentacles/` via export+install and will be overwritten.\n- After any change to `packages/tentacles/`, run the **tentacle-manager** agent to export and install.\n\n## Agents\n\nCustom agents live in `.claude/agents/`. They are **not** dispatchable via `subagent_type` — trigger them with `@agent-<name>` in your prompt (e.g. `@agent-test-runner run node tests`), or use `claude --agent <name>` to make one the session agent.\n\n### tentacle-manager\n\nManages the OctoBot tentacles lifecycle: export from source, install from zip, and generate CCXT exchange tentacles. Mirrors the VSCode \"Install tentacles zip\" launch configuration.\n\nUse when: installing tentacles after code changes, generating exchange tentacles from CCXT, or running any `python start.py tentacles` command.\n\nTrigger: `@agent-tentacle-manager` · Definition: `.claude/agents/tentacle-manager.md`\n\n### test-runner\n\nRuns and debugs OctoBot Python tests. Handles root-level tests (`tests/`) and per-package tests (`packages/<name>/tests/`). On failure, reads the test and source code, diagnoses the issue, fixes it, and re-runs.\n\nUse when: running tests, debugging test failures, or verifying changes after code modifications.\n\nTrigger: `@agent-test-runner` · Definition: `.claude/agents/test-runner.md`\n\n## Code Conventions\n\n### Enums\nPlace enums in `<package_root>/enums.py` (e.g. `octobot/enums.py`, `packages/node/octobot_node/enums.py`). Never define enums inline in module files.\n\n### Constants\nPlace module-wide constants in `<package_root>/constants.py`. Private module constants (used only within one file) may stay in that file, prefixed with `_`.\n\n### Typed errors\nDefine a typed error hierarchy rather than raising bare `ValueError`/`KeyError`. Pattern:\n```python\n# errors.py (sibling to the feature module)\nclass FeatureError(Exception): pass\nclass SpecificError(FeatureError): pass\n```\nRe-export from the package `__init__.py`. Use typed catches everywhere — never inspect `str(err).lower()`, and never catch bare `ValueError`/`KeyError` for domain errors.\n\n### TypedDicts for structured dicts\nWhen a dict has a fixed schema (e.g. wallet info returned to callers), define a `typing.TypedDict`. Place it in the module that owns the data, before the class that produces it.\n\n### Import priority in tentacle files\nPrefer the installed `tentacles.Services.Interfaces.*` path first; fall back to bare direct imports (build-time fallback). Pattern:\n```python\ntry:\n    from tentacles.Services.Interfaces.node_api_interface.api.deps import X\nexcept ImportError:\n    from api.deps import X  # type: ignore[no-redef]\n```\nAll files within a tentacle package should use the same priority order.\n\n### Log levels\n- `debug`: verbose diagnostics, expected no-ops.\n- `info`: normal operational events (startup, shutdown, config loaded).\n- `warning`: unexpected but recoverable (auto-unlock skipped, optional feature unavailable).\n- `error`: configuration/state errors that affect functionality (wallet missing, key wrong).\n- `exception`: unexpected exceptions — always re-raise after logging unless the function is a top-level \"best-effort\" path that must not crash the caller.\n\n### Shared filter helpers\nFiltering logic used in multiple places belongs in a shared utility module (e.g. `workflows_util.py`), not duplicated inline. Name with a verb: `filter_by_wallet`, not `_filter`.\n\n## Documentation\n\nDocumentation lives in `docs/content/` and is built with Docusaurus 3. Package docs go under `docs/content/developers/packages/<pkg-name>/`.\n\n### Tone\n\nWrite descriptive prose that explains what things do and why, not how they're implemented line by line. Favor plain-language explanations over technical detail. Reference class or function names when they help anchor the explanation, but don't build the doc around them — the reader should understand the concepts even if names change. The style should be descriptive yet grounded in code, explains design decisions and non-obvious behavior, mentions concrete names only when they clarify the concept.\n\n### What to include\n\n- Architecture and design decisions\n- How components interact and why\n- Important concepts and patterns\n- Code snippets that illustrate non-obvious behavior\n- Configuration that users/developers need to know about\n\n### What NOT to include\n\nThe code is the source of truth. Don't duplicate anything that can be read from source or will break on the next refactor:\n\n- **API surfaces**: function signatures, parameter lists, return types, class hierarchies, enum/constant values, error classes\n- **Project structure**: directory trees, package layouts, dependency lists, requirements, version numbers\n- **Categorized lists**: sections that just group and list code elements (helpers, classes, endpoints) without explaining why they exist\n- **Implementation details**: build config specifics, hidden imports, lifecycle step-by-step sequences\n\n### File format\n\nEach `.md` file must have Docusaurus frontmatter:\n\n```yaml\n---\ntitle: <Title>\ndescription: <One-line description>\nsidebar_position: <number>\n---\n```\n\nThe sidebar uses `autogenerated` for `developers/packages`, so new files appear automatically.\n","isInternal":false,"tokens":1739,"sizeBytes":7622},{"name":"marketplace.json","path":".claude-plugin/marketplace.json","rawUrl":"https://raw.githubusercontent.com/Drakkar-Software/OctoBot/HEAD/.claude-plugin/marketplace.json","title":"Claude Plugin Marketplace Catalog","category":"marketplace","format":"json","content":"# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/Drakkar-Software/OctoBot/HEAD/.claude-plugin/marketplace.json)","tokens":300,"sizeBytes":203},{"name":"plugin.json","path":".claude-plugin/plugin.json","rawUrl":"https://raw.githubusercontent.com/Drakkar-Software/OctoBot/HEAD/.claude-plugin/plugin.json","title":"claude-plugin Plugin Manifest","category":"plugin-manifest","format":"json","content":"# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/Drakkar-Software/OctoBot/HEAD/.claude-plugin/plugin.json)","tokens":300,"sizeBytes":189},{"name":"mcp.json","path":".cursor/mcp.json","rawUrl":"https://raw.githubusercontent.com/Drakkar-Software/OctoBot/HEAD/.cursor/mcp.json","title":"Model Context Protocol (MCP) Configuration","category":"mcp-config","format":"json","content":"# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/Drakkar-Software/OctoBot/HEAD/.cursor/mcp.json)","tokens":300,"sizeBytes":182}],"systemPromptSnippet":"<yakaai_skills repo=\"Drakkar-Software/OctoBot\">\n<!-- File: AGENTS.md (Tokens: ~1162 | Category: root-instruction) -->\n# Agent quick pointer (OctoBot repo)\n\nThis repository is the **OctoBot** application and its `packages/*` monorepo. Default integration branch: **`dev`** (open PRs to `dev` unless told otherwise).\n\n## Cursor Cloud\n\n- Environment: [`.cursor/README.md`](.cursor/README.md), `environment.json`, `source .cursor/env.sh`\n- Skill (procedures): `.cursor/skills/octobot-cloud/SKILL.md`\n- Roadmap plans: before `CreatePlan`, if the plan title or description contains `roadmap`, follow `.cursor/skills/cloud-roadmap/SKILL.md`\n- Always-on rules: `.cursor/rules/octobot-cloud.mdc`\n\n## Before you finish\n\n```bash\nsource .cursor/env.sh\npython -m tools.extended_linter --base origin/dev\n```\n\nUse `origin/<base>` matching your PR target. Policy: `tools/extended_linter/config/policy.yaml` — see `tools/extended_linter/ARCHITECTURE.md`. No agent plan files or Node UI Playwright e2e in the diff (`path.deny_agent_plans`, `path.deny_node_web_playwright_e2e`). No accidental agent-doc regressions (`agent_docs.no_regression_vs_merge_base`; see `octobot-cloud.mdc`).\n\n## Architecture for agents\n\nColocated **`AGENTS.md`** files describe package boundaries (owns, deps, tests). They are for automation; human docs live under `docs/content/` (Docusaurus).\n\n### When to read\n\n| Situation | Read |\n|-----------|------|\n| Single package task | `packages/<name>/AGENTS.md` |\n| Core app / CLI / config | [`octobot/AGENTS.md`](octobot/AGENTS.md) |\n| Tentacles sources vs install | [`packages/tentacles/AGENTS.md`](packages/tentacles/AGENTS.md) |\n| Node UI or classic web UI (copy, layout, errors) | [`packages/tentacles/Services/Interfaces/node_web_interface/AGENTS.md`](packages/tentacles/Services/Interfaces/node_web_interface/AGENTS.md), [`packages/tentacles/Services/Interfaces/web_interface/AGENTS.md`](packages/tentacles/Services/Interfaces/web_interface/AGENTS.md), skill **end-user-ui** (`.cursor/skills/end-user-ui/SKILL.md`) |\n| Node journal (record / export) | [`octobot/community/node_journal/AGENTS.md`](octobot/community/node_journal/AGENTS.md), skill **node-journal** (`.cursor/skills/node-journal/SKILL.md`) |\n| Python style (imports, literals, `__init__.py` API) | [CONTRIBUTING-agent.md](CONTRIBUTING-agent.md) — **Python conventions (agents)** |\n| Cross-package or tentacles | This file + every involved colocated `AGENTS.md` |\n| Node UI demo / agent-seed QA | [`tools/agent_seed/README.md`](tools/agent_seed/README.md) + skill **agent-seed** (`.cursor/skills/agent-seed/SKILL.md`) |\n\n### Dependency sketch\n\n```mermaid\nflowchart TB\n  octobot[octobot app]\n  commons[commons]\n  trading[trading]\n  evaluators[evaluators]\n  services[services]\n  tentacles_pkg[packages/tentacles sources]\n  octobot --> commons\n  octobot --> trading\n  octobot --> evaluators\n  octobot --> services\n  trading --> commons\n  evaluators --> commons\n  tentacles_pkg --> services\n```\n\n### CI matrix packages (colocated `AGENTS.md`)\n\n| Package | Path |\n|---------|------|\n| Core application | [`octobot/AGENTS.md`](octobot/AGENTS.md) |\n| Tentacles sources | [`packages/tentacles/AGENTS.md`](packages/tentacles/AGENTS.md) |\n| agents | [`packages/agents/AGENTS.md`](packages/agents/AGENTS.md) |\n| async_channel | [`packages/async_channel/AGENTS.md`](packages/async_channel/AGENTS.md) |\n| backtesting | [`packages/backtesting/AGENTS.md`](packages/backtesting/AGENTS.md) |\n| commons | [`packages/commons/AGENTS.md`](packages/commons/AGENTS.md) |\n| copy | [`packages/copy/AGENTS.md`](packages/copy/AGENTS.md) |\n| evaluators | [`packages/evaluators/AGENTS.md`](packages/evaluators/AGENTS.md) |\n| flow | [`packages/flow/AGENTS.md`](packages/flow/AGENTS.md) |\n| node | [`packages/node/AGENTS.md`](packages/node/AGENTS.md) |\n| protocol | [`packages/protocol/AGENTS.md`](packages/protocol/AGENTS.md) |\n| services | [`packages/services/AGENTS.md`](packages/services/AGENTS.md) |\n| sync | [`packages/sync/AGENTS.md`](packages/sync/AGENTS.md) |\n| tentacles_manager | [`packages/tentacles_manager/AGENTS.md`](packages/tentacles_manager/AGENTS.md) |\n| trading | [`packages/trading/AGENTS.md`](packages/trading/AGENTS.md) |\n\nNew packages: follow **AGENTS.md sections** in [CONTRIBUTING-agent.md](CONTRIBUTING-agent.md).\n\n## Humans\n\n- [CONTRIBUTING-agent.md](CONTRIBUTING-agent.md) — agents, policy, boundaries\n\n<!-- File: CLAUDE.md (Tokens: ~1739 | Category: claude-rule) -->\n# OctoBot\n\n## Environment\n\n### Installing pants\n\nPants is not bundled. Install the `scie-pants` launcher once (bootstraps pants 2.30.0 from `pants.toml` on first run):\n\n```bash\ncurl -fsSL https://github.com/pantsbuild/scie-pants/releases/latest/download/scie-pants-linux-x86_64 \\\n  -o /usr/local/bin/pants\nchmod +x /usr/local/bin/pants\npants --version   # triggers bootstrap; prints 2.30.0 when done\n```\n\nIf the GitHub releases URL is reachable but the internal pex download is not, point pants at a locally cached pex binary by adding to `pants.toml` temporarily (do not commit):\n\n```toml\n[pex-cli]\nurl_template = \"file:///path/to/pex\"\n```\n\n### Python virtualenv\n\nResolves are disabled (`enable_resolves = false` in `pants.toml`) — no lockfile is committed. Pants resolves requirements directly from `python_requirement` targets each run.\n\nCreate a local virtualenv from the project requirements for IDE / debugging:\n\n```bash\npython3.13 -m venv .venv\n.venv/bin/pip install -r requirements.txt -r full_requirements.txt\n```\n\nUse `.venv/bin/python` as the interpreter for running and debugging.\n\n> **Interpreter constraint**: `pants.toml` pins `interpreter_constraints = [\"==3.13.*\"]` (wildcard required — `==3.13` matches only 3.13.0 exactly and rejects 3.13.1+).\n\n### PYTHONPATH\n\n```bash\nROOT=$PWD\n# Without tentacles (bare start.py, no tentacle features):\nexport PYTHONPATH=\"$ROOT:$ROOT/packages/agents:$ROOT/packages/async_channel:$ROOT/packages/backtesting:$ROOT/packages/binary:$ROOT/packages/commons:$ROOT/packages/copy:$ROOT/packages/evaluators:$ROOT/packages/flow:$ROOT/packages/node:$ROOT/packages/protocol:$ROOT/packages/services:$ROOT/packages/sync:$ROOT/packages/tentacles_manager:$ROOT/packages/trading\"\n\n# With tentacles (after python start.py tentacles install):\nexport PYTHONPATH=\"$ROOT:$ROOT/packages/agents:$ROOT/packages/async_channel:$ROOT/packages/backtesting:$ROOT/packages/binary:$ROOT/packages/commons:$ROOT/packages/copy:$ROOT/packages/evaluators:$ROOT/packages/flow:$ROOT/packages/node:$ROOT/packages/protocol:$ROOT/packages/services:$ROOT/packages/sync:$ROOT/packages/tentacles:$ROOT/packages/tentacles_manager:$ROOT/packages/trading\"\n```\n\nPYTHONPATH must use absolute paths (`$PWD`-based) — build subprocesses run from tentacle subdirectories and need to resolve all packages.\n\n## Tentacles\n\n- **Source of truth**: `packages/tentacles/` — all tentacle changes go here.\n- **Never edit `tentacles/` directly** — it is generated from `packages/tentacles/` via export+install and will be overwritten.\n- After any change to `packages/tentacles/`, run the **tentacle-manager** agent to export and install.\n\n## Agents\n\nCustom agents live in `.claude/agents/`. They are **not** dispatchable via `subagent_type` — trigger them with `@agent-<name>` in your prompt (e.g. `@agent-test-runner run node tests`), or use `claude --agent <name>` to make one the session agent.\n\n### tentacle-manager\n\nManages the OctoBot tentacles lifecycle: export from source, install from zip, and generate CCXT exchange tentacles. Mirrors the VSCode \"Install tentacles zip\" launch configuration.\n\nUse when: installing tentacles after code changes, generating exchange tentacles from CCXT, or running any `python start.py tentacles` command.\n\nTrigger: `@agent-tentacle-manager` · Definition: `.claude/agents/tentacle-manager.md`\n\n### test-runner\n\nRuns and debugs OctoBot Python tests. Handles root-level tests (`tests/`) and per-package tests (`packages/<name>/tests/`). On failure, reads the test and source code, diagnoses the issue, fixes it, and re-runs.\n\nUse when: running tests, debugging test failures, or verifying changes after code modifications.\n\nTrigger: `@agent-test-runner` · Definition: `.claude/agents/test-runner.md`\n\n## Code Conventions\n\n### Enums\nPlace enums in `<package_root>/enums.py` (e.g. `octobot/enums.py`, `packages/node/octobot_node/enums.py`). Never define enums inline in module files.\n\n### Constants\nPlace module-wide constants in `<package_root>/constants.py`. Private module constants (used only within one file) may stay in that file, prefixed with `_`.\n\n### Typed errors\nDefine a typed error hierarchy rather than raising bare `ValueError`/`KeyError`. Pattern:\n```python\n# errors.py (sibling to the feature module)\nclass FeatureError(Exception): pass\nclass SpecificError(FeatureError): pass\n```\nRe-export from the package `__init__.py`. Use typed catches everywhere — never inspect `str(err).lower()`, and never catch bare `ValueError`/`KeyError` for domain errors.\n\n### TypedDicts for structured dicts\nWhen a dict has a fixed schema (e.g. wallet info returned to callers), define a `typing.TypedDict`. Place it in the module that owns the data, before the class that produces it.\n\n### Import priority in tentacle files\nPrefer the installed `tentacles.Services.Interfaces.*` path first; fall back to bare direct imports (build-time fallback). Pattern:\n```python\ntry:\n    from tentacles.Services.Interfaces.node_api_interface.api.deps import X\nexcept ImportError:\n    from api.deps import X  # type: ignore[no-redef]\n```\nAll files within a tentacle package should use the same priority order.\n\n### Log levels\n- `debug`: verbose diagnostics, expected no-ops.\n- `info`: normal operational events (startup, shutdown, config loaded).\n- `warning`: unexpected but recoverable (auto-unlock skipped, optional feature unavailable).\n- `error`: configuration/state errors that affect functionality (wallet missing, key wrong).\n- `exception`: unexpected exceptions — always re-raise after logging unless the function is a top-level \"best-effort\" path that must not crash the caller.\n\n### Shared filter helpers\nFiltering logic used in multiple places belongs in a shared utility module (e.g. `workflows_util.py`), not duplicated inline. Name with a verb: `filter_by_wallet`, not `_filter`.\n\n## Documentation\n\nDocumentation lives in `docs/content/` and is built with Docusaurus 3. Package docs go under `docs/content/developers/packages/<pkg-name>/`.\n\n### Tone\n\nWrite descriptive prose that explains what things do and why, not how they're implemented line by line. Favor plain-language explanations over technical detail. Reference class or function names when they help anchor the explanation, but don't build the doc around them — the reader should understand the concepts even if names change. The style should be descriptive yet grounded in code, explains design decisions and non-obvious behavior, mentions concrete names only when they clarify the concept.\n\n### What to include\n\n- Architecture and design decisions\n- How components interact and why\n- Important concepts and patterns\n- Code snippets that illustrate non-obvious behavior\n- Configuration that users/developers need to know about\n\n### What NOT to include\n\nThe code is the source of truth. Don't duplicate anything that can be read from source or will break on the next refactor:\n\n- **API surfaces**: function signatures, parameter lists, return types, class hierarchies, enum/constant values, error classes\n- **Project structure**: directory trees, package layouts, dependency lists, requirements, version numbers\n- **Categorized lists**: sections that just group and list code elements (helpers, classes, endpoints) without explaining why they exist\n- **Implementation details**: build config specifics, hidden imports, lifecycle step-by-step sequences\n\n### File format\n\nEach `.md` file must have Docusaurus frontmatter:\n\n```yaml\n---\ntitle: <Title>\ndescription: <One-line description>\nsidebar_position: <number>\n---\n```\n\nThe sidebar uses `autogenerated` for `developers/packages`, so new files appear automatically.\n\n<!-- File: .claude-plugin/marketplace.json (Tokens: ~300 | Category: marketplace) -->\n# Claude Plugin Marketplace Catalog\n\nPath: `.claude-plugin/marketplace.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/Drakkar-Software/OctoBot/HEAD/.claude-plugin/marketplace.json)\n\n<!-- File: .claude-plugin/plugin.json (Tokens: ~300 | Category: plugin-manifest) -->\n# claude-plugin Plugin Manifest\n\nPath: `.claude-plugin/plugin.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/Drakkar-Software/OctoBot/HEAD/.claude-plugin/plugin.json)\n\n<!-- File: .cursor/mcp.json (Tokens: ~300 | Category: mcp-config) -->\n# Model Context Protocol (MCP) Configuration\n\nPath: `.cursor/mcp.json`\n\n[View Raw Content on GitHub](https://raw.githubusercontent.com/Drakkar-Software/OctoBot/HEAD/.cursor/mcp.json)\n</yakaai_skills>"}