diff --git a/Agents.md b/Agents.md index 1c9489f..5ec6b9c 100644 --- a/Agents.md +++ b/Agents.md @@ -865,4 +865,4 @@ path table and the [official sbx mixin reference](https://docs.docker.com/ai/san installs/domains they bring. Not a bug, just visibility. - **The `sql` agent's `usql` install is in the base kit, not a per-agent mixin.** Same for `pandoc` (used by `fetch_url_via_curl`). Both ship with every Coyote sandbox automatically. See `assets/sbx-kit/spec.yaml` for the - full base prereq list. + full base prereq list. \ No newline at end of file diff --git a/Home.md b/Home.md index 6925b6d..7f204a0 100644 --- a/Home.md +++ b/Home.md @@ -40,6 +40,7 @@ Coming from [AIChat](https://github.com/sigoden/aichat)? Follow the [migration g * [RAG](RAG): Retrieval-Augmented Generation for enhanced information retrieval and generation. * [Sessions](Sessions): Manage and persist conversational contexts and settings across multiple interactions. * [Memory](Memory): Persistent file-based memory that survives across sessions. Bootstrap with `coyote --init-memory [global|workspace]`. +* [Workspace Instructions](Workspace-Instructions): Human-curated project instructions (`COYOTE.md`) injected into every prompt, with `AGENTS.md`/`CLAUDE.md`/`GEMINI.md` fallbacks for cross-tool compatibility. Scaffold with `coyote --init-instructions`. * [Roles](Roles): Customize model behavior for specific tasks or domains. * [Skills](Skills): Modular knowledge or capability packs the LLM can load and unload mid-conversation. Multiple skills compose; instructions stack, tools and MCPs union. * [Agents](Agents): Leverage AI agents to perform complex tasks and workflows, including sub-agent spawning, teammate messaging, and user interaction tools. diff --git a/MCP-Servers.md b/MCP-Servers.md index d160d51..5fc0915 100644 --- a/MCP-Servers.md +++ b/MCP-Servers.md @@ -42,16 +42,27 @@ Every server entry **must** include a `"type"` field set to one of: `"stdio"`, ` ## Workspace-Local MCP Servers -In addition to the global `functions/mcp.json`, Coyote automatically loads a workspace-local MCP config from `.coyote/mcp.json` -in the current directory at startup. This lets you ship project-specific MCP servers alongside your code without -touching your global configuration. +In addition to the global `functions/mcp.json`, Coyote automatically loads a workspace-local MCP config at startup. +This lets you ship project-specific MCP servers alongside your code without touching your global configuration. + +Coyote checks the following locations in order and loads the **first** file it finds: + +1. `.coyote/mcp.json` — the native location +2. `.coyote/.mcp.json` — Claude-style file name (leading dot) inside the workspace config directory +3. `.mcp.json` — project root; [Claude Code's project-scope convention](https://code.claude.com/docs/en/mcp) ``` / -└── .coyote/ - └── mcp.json # same format as functions/mcp.json +├── .coyote/ +│ └── mcp.json # same format as functions/mcp.json (preferred) +└── .mcp.json # Claude Code-compatible fallback ``` +This means a repository that only ships a Claude Code `.mcp.json` works with Coyote out of the box. The `.coyote/` +directory name is also customizable via the `COYOTE_WORKSPACE_CONFIG_DIR` +[environment variable](Environment-Variables), so you can point Coyote at another tool's config directory +(e.g. `.cursor/`, which holds an `mcp.json`) entirely. + The workspace file uses the exact same format as the global `functions/mcp.json`, including [Vault](Vault) secret interpolation via `{{SECRET_NAME}}` syntax. Workspace server names shadow global ones on collision. This means that if both files define a server named `my-db`, the workspace version takes precedence. diff --git a/Memory.md b/Memory.md index c055893..740520c 100644 --- a/Memory.md +++ b/Memory.md @@ -10,25 +10,24 @@ The fastest path is the bootstrap command: # Workspace memory (per-project) cd /path/to/your/project coyote --init-memory workspace -# → creates ./COYOTE.md with a skeleton +# → creates /.coyote/memory/MEMORY.md with a skeleton (falls back to the +# current directory outside a git repo) and appends .coyote/memory/ to .gitignore # Global memory (per-user, applies everywhere) coyote --init-memory global # → creates /memory/MEMORY.md ``` -Then edit the file with anything you want the LLM to remember: +Then edit the index with anything you want the LLM to remember: ```markdown -# Project Memory +# Workspace Memory Index This project is a Rust CLI tool. I prefer terse responses and concrete code examples. ``` Run coyote in that directory and the memory content is injected into every system prompt automatically. The LLM will see and use the `memory__*` tools to update it over time (when function calling is on). -That's it for "lite mode." For structured memory, see below. - > Memory is **opt-in by file presence** for the read path. If no marker exists on disk, no workspace memory is injected and global memory is loaded only if the global marker exists. `--init-memory` is the explicit consent signal. > **Write-side exception (git repos only):** if the LLM calls `memory__write(scope=workspace)` and no marker exists, coyote auto-bootstraps a structured layout at the git root and adds `.coyote/memory/` to `.gitignore`. See [Git-Repo Auto-Bootstrap](#git-repo-auto-bootstrap) below. Outside a git repo this fails with a hint to run `coyote --init-memory workspace`. @@ -40,12 +39,11 @@ That's it for "lite mode." For structured memory, see below. Memory has two scopes: - **Global** (user-level): `~/.config/coyote/memory/` - facts about you that apply everywhere -- **Workspace** (project-level): `/COYOTE.md` (lite) or `/.coyote/memory/` (structured) +- **Workspace** (project-level): `/.coyote/memory/` -Memory is **opt-in by workspace**: coyote walks up from your current directory looking for a memory marker. If none is -found, no workspace memory is loaded. Global memory is loaded if it exists. - -When both a `.coyote/memory/MEMORY.md` and a `COYOTE.md` exist at the same level, the structured layout wins. +Memory is **opt-in by workspace**: coyote walks up from your current directory looking for a +`.coyote/memory/MEMORY.md` marker. If none is found, no workspace memory is loaded. Global memory is loaded if it +exists. A root-level `COYOTE.md` is **not** a memory marker; it is [workspace instructions](Workspace-Instructions). ### Git-Repo Auto-Bootstrap @@ -78,7 +76,7 @@ without needing tools. ## Structured Mode -For non-trivial memory, use the structured layout: +Workspace memory always uses the structured layout: ``` /.coyote/memory/ @@ -146,11 +144,9 @@ When function calling is enabled, coyote exposes: - `memory__lint()`: health-check (orphans, broken `[[wikilinks]]`, oversized files >2K chars, stale files that are superseded or expired, and index descriptions that drifted from the file's own `description:`) -The LLM is instructed to update `MEMORY.md` whenever it writes a new file. Two silent promotions can happen on a +The LLM is instructed to update `MEMORY.md` whenever it writes a new file. One silent promotion can happen on a `memory__write(scope=workspace)`: -- **Lite -> structured**: if the workspace is in lite mode (`COYOTE.md` only), the new file goes into - `/.coyote/memory/` and `COYOTE.md` is left untouched. - **None -> structured (git only)**: if no marker exists anywhere, coyote auto-bootstraps at the git root. See [Git-Repo Auto-Bootstrap](#git-repo-auto-bootstrap). @@ -164,7 +160,7 @@ Memory can be disabled at multiple levels (most specific wins): 4. **Session**: `memory: false` in the saved session frontmatter (also settable via the session's `set_memory` API) 5. **Role config**: `memory: false` in role frontmatter 6. **AppConfig**: `memory: false` in global config -7. **Workspace presence** (read side): absence of `COYOTE.md` and `.coyote/memory/`. On the write side, +7. **Workspace presence** (read side): absence of `.coyote/memory/`. On the write side, `memory__write(scope=workspace)` inside a git repo can auto-create `.coyote/memory/` (see [Git-Repo Auto-Bootstrap](#git-repo-auto-bootstrap) for more information). @@ -215,6 +211,7 @@ explicitly tell the LLM not to write secrets, but treat that as a defense-in-dep ## See Also +- [Workspace Instructions](Workspace-Instructions): human-curated project instructions (`COYOTE.md`/`AGENTS.md`/`CLAUDE.md`/`GEMINI.md`/etc.) - [Sessions](Sessions): per-conversation state - [Skills](Skills): modular knowledge packs - [Roles](Roles): model behavior customization (supports `memory: false`) diff --git a/Workspace-Instructions.md b/Workspace-Instructions.md new file mode 100644 index 0000000..25b4be2 --- /dev/null +++ b/Workspace-Instructions.md @@ -0,0 +1,121 @@ +Coyote can inject **human-curated project instructions** into every system prompt. This is its equivalent of Claude Code's +`CLAUDE.md` or the cross-tool `AGENTS.md` standard. Instructions are the "hard rules and orientation" for a repository: +coding conventions, build commands, architectural constraints, and anything else the LLM should *always* see. + +Instructions complement [Memory](Memory): instructions are **human-curated and read-only to the LLM**, while memory +(`.coyote/memory/`) is **agent-curated** via the `memory__*` tools. + +| | Workspace Instructions | [Memory](Memory) | +|-------------|-------------------------------------|-------------------------------------------| +| Curated by | You (committed to git) | The LLM (gitignored by default) | +| Injection | Always, in full | Index eagerly; drill files on demand | +| LLM writes? | Never | Yes (with function calling) | +| File(s) | `COYOTE.md` at the repo root | `.coyote/memory/` directory | + +## Quick Start + +```bash +cd /path/to/your/project +coyote --init-instructions +# → creates ./COYOTE.md with a skeleton +``` + +Edit `COYOTE.md` with your project's instructions, commit it, and every Coyote invocation in that repository (or any +subdirectory of it) will include the file in the system prompt. + +Re-running `--init-instructions` is safe: it refuses to overwrite an existing file. + +## File Discovery + +Coyote walks up from the current directory. In each directory it checks the file chain **in order** and injects the +first non-empty match: + +1. `COYOTE.md` — Coyote-native +2. `AGENTS.md` — the [cross-tool agent instructions standard](https://agents.md) (Codex, opencode, Cline, and others) +3. `CLAUDE.md` — [Claude Code's](https://code.claude.com/docs/en/memory) instructions file +4. `GEMINI.md` — [Gemini CLI's](https://github.com/google-gemini/gemini-cli) context file + +This means a repository that only ships an `AGENTS.md` or `CLAUDE.md` gives Coyote full project context with zero +configuration. A file closer to your working directory wins over a higher-priority file name further up the tree, so +a package-level `CLAUDE.md` beats a repo-root `COYOTE.md` when you launch Coyote inside that package. + +Empty files are skipped, so an empty `COYOTE.md` will not shadow a real `AGENTS.md` next to it. + +## What Gets Injected + +The file content is injected **read-only and in full** as its own system prompt section: + +```xml + +# Project Instructions +... + +``` + +There is no truncation cap. If the file exceeds ~24,000 characters Coyote logs a warning suggesting you move detail +into [Memory](Memory) drill files, but still injects everything. Keep instructions lean: hard rules and orientation +belong here; voluminous reference material belongs in the memory wiki where the LLM fetches it on demand (see the +`iwe-knowledge-base` skill for structural navigation of large corpora). + +The LLM is never given tools to edit instructions files. They are yours. + +## Configuration + +In the global `config.yaml`: + +```yaml +workspace_instructions: null # null/true = inject when a file exists; false = never inject +workspace_instructions_files: null # Custom file chain, in priority order. + # Default: [COYOTE.md, AGENTS.md, CLAUDE.md, GEMINI.md] +``` + +Reorder or drop fallbacks by setting a custom chain: + +```yaml +# Only ever read the Coyote-native file +workspace_instructions_files: [COYOTE.md] + +# Prefer AGENTS.md over COYOTE.md +workspace_instructions_files: [AGENTS.md, COYOTE.md] +``` + +## CLI Flags + +| Flag | Effect | +|---------------------------------------|------------------------------------------------------------------------| +| `--init-instructions` | Scaffold a `COYOTE.md` in the current directory | +| `--no-workspace-instructions` | Skip instructions injection for this invocation | +| `--workspace-instructions-file NAME` | Override the file chain for this invocation (repeatable, priority order) | + +The override flag is handy for previewing what other tools see: + +```bash +# What would Claude Code's context look like here? +coyote --workspace-instructions-file CLAUDE.md --dry-run 'hello' +``` + +Verify what is being picked up with `coyote --info`, which reports the resolved `workspace_instructions_file`. + +## Relationship to Other Tools' Conventions + +| Tool | Instructions file | Coyote reads it? | +|-------------|--------------------------|------------------------------| +| Coyote | `COYOTE.md` | ✅ (first priority) | +| Codex CLI | `AGENTS.md` | ✅ (second priority) | +| opencode | `AGENTS.md` | ✅ (second priority) | +| Claude Code | `CLAUDE.md` | ✅ (third priority) | +| Gemini CLI | `GEMINI.md` | ✅ (fourth priority) | +| Cursor | `.cursor/rules/*.mdc` | ❌ | + +Unlike Claude Code, Coyote does not concatenate instruction files from every ancestor directory, support `@path` +imports, or load nested files on demand. The first match wins. The [Memory](Memory) system's eagerly-injected index +plus on-demand drill files (navigable with IWE graph tools) covers those use cases with better token economics: put a +pointer in the index ("working in `packages/frontend/`? read `[[frontend-conventions]]`") instead of scattering +instruction files. + +## See Also + +- [Memory](Memory): agent-curated persistent memory +- [Skills](Skills): modular knowledge and capability packs +- [Roles](Roles): model behavior customization +- [Environment Variables](Environment-Variables): includes `COYOTE_WORKSPACE_CONFIG_DIR` for cross-tool config dirs diff --git a/_Sidebar.md b/_Sidebar.md index e8a1c1d..5d10053 100644 --- a/_Sidebar.md +++ b/_Sidebar.md @@ -50,6 +50,9 @@ - [Structured Mode](Memory#structured-mode) - [Tools](Memory#tools) - [Toggles](Memory#toggles) +- [Workspace Instructions](Workspace-Instructions) + - [File Discovery](Workspace-Instructions#file-discovery) + - [Configuration](Workspace-Instructions#configuration) - [RAG](RAG) - [Macros](Macros) - [Roles](Roles)