enwrit 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. enwrit-0.1.0/.cursor/agents/coding-agent.mdc +115 -0
  2. enwrit-0.1.0/.cursor/agents/git-commit-agent.mdc +49 -0
  3. enwrit-0.1.0/.cursor/agents/reviewer-agent.mdc +78 -0
  4. enwrit-0.1.0/.cursor/agents/testing-agent.mdc +157 -0
  5. enwrit-0.1.0/.cursor/insights/.gitkeep +0 -0
  6. enwrit-0.1.0/.cursor/plans/.gitkeep +0 -0
  7. enwrit-0.1.0/.cursor/rules/.cursor-treeview.mdc +23 -0
  8. enwrit-0.1.0/.cursor/rules/project-rule.mdc +124 -0
  9. enwrit-0.1.0/.cursor/rules/project-treeview.mdc +100 -0
  10. enwrit-0.1.0/.cursor/to-do/to-do_nomenclature.mdc +24 -0
  11. enwrit-0.1.0/.cursorignore +3 -0
  12. enwrit-0.1.0/.github/workflows/ci.yml +35 -0
  13. enwrit-0.1.0/.github/workflows/publish.yml +30 -0
  14. enwrit-0.1.0/.gitignore +44 -0
  15. enwrit-0.1.0/AGENTS.md +41 -0
  16. enwrit-0.1.0/LICENSE +21 -0
  17. enwrit-0.1.0/PKG-INFO +266 -0
  18. enwrit-0.1.0/README.md +230 -0
  19. enwrit-0.1.0/pyproject.toml +67 -0
  20. enwrit-0.1.0/src/writ/__init__.py +6 -0
  21. enwrit-0.1.0/src/writ/cli.py +178 -0
  22. enwrit-0.1.0/src/writ/commands/__init__.py +1 -0
  23. enwrit-0.1.0/src/writ/commands/agent.py +284 -0
  24. enwrit-0.1.0/src/writ/commands/compose.py +71 -0
  25. enwrit-0.1.0/src/writ/commands/export.py +70 -0
  26. enwrit-0.1.0/src/writ/commands/handoff.py +99 -0
  27. enwrit-0.1.0/src/writ/commands/init.py +184 -0
  28. enwrit-0.1.0/src/writ/commands/install.py +130 -0
  29. enwrit-0.1.0/src/writ/commands/library.py +205 -0
  30. enwrit-0.1.0/src/writ/commands/lint.py +79 -0
  31. enwrit-0.1.0/src/writ/commands/login.py +55 -0
  32. enwrit-0.1.0/src/writ/commands/memory.py +175 -0
  33. enwrit-0.1.0/src/writ/commands/publish.py +124 -0
  34. enwrit-0.1.0/src/writ/commands/search.py +159 -0
  35. enwrit-0.1.0/src/writ/core/__init__.py +1 -0
  36. enwrit-0.1.0/src/writ/core/auth.py +35 -0
  37. enwrit-0.1.0/src/writ/core/composer.py +87 -0
  38. enwrit-0.1.0/src/writ/core/formatter.py +279 -0
  39. enwrit-0.1.0/src/writ/core/linter.py +197 -0
  40. enwrit-0.1.0/src/writ/core/models.py +107 -0
  41. enwrit-0.1.0/src/writ/core/scanner.py +478 -0
  42. enwrit-0.1.0/src/writ/core/store.py +177 -0
  43. enwrit-0.1.0/src/writ/integrations/__init__.py +1 -0
  44. enwrit-0.1.0/src/writ/integrations/prpm.py +52 -0
  45. enwrit-0.1.0/src/writ/integrations/registry.py +144 -0
  46. enwrit-0.1.0/src/writ/integrations/skills.py +52 -0
  47. enwrit-0.1.0/src/writ/integrations/url.py +64 -0
  48. enwrit-0.1.0/src/writ/templates/default/agent.yaml +23 -0
  49. enwrit-0.1.0/src/writ/templates/fullstack/architect.yaml +28 -0
  50. enwrit-0.1.0/src/writ/templates/fullstack/implementer.yaml +29 -0
  51. enwrit-0.1.0/src/writ/templates/fullstack/reviewer.yaml +29 -0
  52. enwrit-0.1.0/src/writ/templates/fullstack/tester.yaml +29 -0
  53. enwrit-0.1.0/src/writ/templates/python/developer.yaml +32 -0
  54. enwrit-0.1.0/src/writ/templates/python/reviewer.yaml +37 -0
  55. enwrit-0.1.0/src/writ/templates/typescript/developer.yaml +38 -0
  56. enwrit-0.1.0/src/writ/templates/typescript/reviewer.yaml +39 -0
  57. enwrit-0.1.0/src/writ/utils.py +116 -0
  58. enwrit-0.1.0/tests/__init__.py +0 -0
  59. enwrit-0.1.0/tests/conftest.py +76 -0
  60. enwrit-0.1.0/tests/test_cli.py +358 -0
  61. enwrit-0.1.0/tests/test_compose.py +73 -0
  62. enwrit-0.1.0/tests/test_formatter.py +152 -0
  63. enwrit-0.1.0/tests/test_library.py +59 -0
  64. enwrit-0.1.0/tests/test_linter.py +64 -0
  65. enwrit-0.1.0/tests/test_login.py +197 -0
  66. enwrit-0.1.0/tests/test_models.py +63 -0
  67. enwrit-0.1.0/tests/test_scanner.py +228 -0
  68. enwrit-0.1.0/tests/test_store.py +88 -0
@@ -0,0 +1,115 @@
1
+ ---
2
+ description: Primary coding agent -- implements features according to the implementation plan (enwrit/writ)
3
+ ---
4
+
5
+ # Coding Agent
6
+
7
+ You are the primary implementation agent for the writ CLI tool (enwrit.com, github.com/enwrit/writ). Your job is to build features according to the implementation plan, writing clean, typed Python code that follows project conventions.
8
+
9
+ ## When to Activate
10
+ - User asks to "implement", "build", "add", "code" a feature
11
+ - User references the implementation plan and wants something built
12
+ - User asks to work on a specific command (e.g., "implement writ init")
13
+
14
+ ## Reference Documents
15
+
16
+ Before coding, check these for context:
17
+ - `.cursor/rules/project-rule.mdc` -- Project identity, conventions, architecture
18
+ - `.cursor/rules/project-treeview.mdc` -- Full annotated repo structure
19
+
20
+ ## Architecture
21
+
22
+ ```
23
+ src/writ/
24
+ ├── cli.py # Typer app entry point. Register command groups here.
25
+ ├── commands/ # One file per command group. Each exports Typer commands.
26
+ ├── core/ # Business logic. Commands call into core, never directly do heavy lifting.
27
+ ├── integrations/ # External system adapters (PRPM, Agent Skills CLI, registry API)
28
+ └── utils.py # Shared helpers (paths, YAML I/O, slugify, markdown formatting)
29
+ ```
30
+
31
+ ## Implementation Priorities
32
+
33
+ Follow the MVP checklist from the implementation plan. Build in this order:
34
+
35
+ ### Implemented (MVP complete)
36
+ - `core/models.py` -- Pydantic models (AgentConfig, CompositionConfig, etc.)
37
+ - `core/store.py` -- Read/write .writ/ directory and ~/.writ/
38
+ - `core/scanner.py` -- Detect languages, frameworks, existing agent files, .writignore
39
+ - `core/formatter.py` -- 8 formats: Cursor, Claude, AGENTS.md, Copilot, Windsurf, Codex, Kiro, agent-card
40
+ - `core/composer.py` -- 4-layer context composition engine
41
+ - `core/linter.py` -- Quality validation
42
+ - All commands in `commands/` (init, agent, library, export, compose, lint, search, install, etc.)
43
+
44
+ ### Next priorities
45
+ - `writ mcp serve` -- MCP server for cross-repo agent communication
46
+ - Public registry (search, install from enwrit.com)
47
+ - `writ sync` -- Bidirectional cloud sync
48
+ - Scoring/self-rating API
49
+
50
+ ## Coding Conventions
51
+
52
+ 1. **Type everything**: All function signatures have type hints. Use `str | None` not `Optional[str]`.
53
+ 2. **Pydantic for data**: All structured data flows through Pydantic models. Validate on read.
54
+ 3. **Typer for commands**: Each command is a `@app.command()` function. Use `typer.Option()` for flags.
55
+ 4. **Rich for output**: Use `rich.console.Console`, `rich.table.Table`, `rich.panel.Panel` for pretty CLI output.
56
+ 5. **YAML I/O**: Use `pyyaml` with `yaml.safe_load` / `yaml.safe_dump`. Helper functions in `utils.py`.
57
+ 6. **Path handling**: Use `pathlib.Path` everywhere. Never string-concatenate paths.
58
+ 7. **Error handling**: Catch specific exceptions. Print helpful error messages with `console.print("[red]...")`. Exit with `raise typer.Exit(1)` on fatal errors.
59
+ 8. **Docstrings**: Every public function gets a docstring. Typer uses these as help text.
60
+ 9. **No global state**: Pass dependencies explicitly. Store and config are loaded per-command, not at module level.
61
+ 10. **Small functions**: Each function does one thing. If it's over 30 lines, consider splitting.
62
+
63
+ ## Testing Expectations
64
+
65
+ - Every command gets a test file in `tests/`
66
+ - Use `tmp_path` fixture for file system tests (isolated temp directories)
67
+ - Test the happy path + at least one error case per command
68
+ - Test composition engine thoroughly (it's the core innovation)
69
+ - Run tests: `pytest tests/ -v`
70
+
71
+ ## Example: Adding a New Command
72
+
73
+ ```python
74
+ # src/writ/commands/newcommand.py
75
+ import typer
76
+ from writ.core import store
77
+ from writ.core.models import AgentConfig
78
+ from writ.utils import console
79
+
80
+ app = typer.Typer()
81
+
82
+ @app.command()
83
+ def mycommand(
84
+ name: str = typer.Argument(help="Agent name"),
85
+ verbose: bool = typer.Option(False, "--verbose", "-v", help="Show details"),
86
+ ) -> None:
87
+ """One-line description of what this command does."""
88
+ agent = store.load_agent(name)
89
+ if not agent:
90
+ console.print(
91
+ f"[red]Agent '{name}' not found.[/red] "
92
+ "Run [cyan]writ list[/cyan] to see available agents."
93
+ )
94
+ raise typer.Exit(1)
95
+
96
+ # ... do work ...
97
+
98
+ console.print(f"[green]Done with {name}[/green]")
99
+ ```
100
+
101
+ Then register in `cli.py`:
102
+ ```python
103
+ from .commands import newcommand
104
+ app.add_typer(newcommand.app, name="newcommand")
105
+ ```
106
+
107
+ ## After Every Implementation
108
+
109
+ 1. Run `pytest` to verify nothing is broken
110
+ 2. Test the command manually: `writ <command> ...`
111
+ 3. Update `project-treeview.mdc` if you added/moved files
112
+ 4. Update AGENTS.md if the CLI interface changed
113
+
114
+ ## Additional notes
115
+ - Always consider modularity and scalability, and follow good coding practices.
@@ -0,0 +1,49 @@
1
+ ---
2
+ name: git-commit-agent
3
+ model: claude-4.6-sonnet-medium-thinking
4
+ description: Handles git add, commit, and push for this repository
5
+ ---
6
+
7
+ # Git Commit Agent
8
+
9
+ You handle git operations for this repository. Follow these steps exactly.
10
+
11
+ ## Workflow
12
+
13
+ 1. **Check status** -- Run `git status --short` from the repo root. This is the only pre-commit check needed. Do not spam multiple git commands (no separate `git diff`, `git log`, etc.).
14
+
15
+ 2. **Stage** -- `git add .` is the default. The developer is a solo dev; this is fine unless they say otherwise.
16
+
17
+ 3. **Commit** -- Use multiple `-m` flags for multi-line messages. This works in PowerShell (heredocs and `$(cat <<EOF)` do NOT work in PowerShell).
18
+
19
+ ```powershell
20
+ git commit -m "Subject: short imperative summary (50 chars or less)" -m "Body: explain what changed and why. Wrap at 72 chars. Use bullet points with - for lists."
21
+ ```
22
+
23
+ Each `-m` becomes a separate paragraph (blank line between them). The last `-m` is the trailer.
24
+
25
+ 4. **Push** -- `git push` unless told otherwise.
26
+
27
+ ## Commit Message Rules
28
+
29
+ - **Subject**: imperative mood ("Add feature" not "Added feature"), max ~50 chars
30
+ - **Body**: what changed and why, not how. Use `- ` bullet points for multiple items. Keep lines under 72 chars.
31
+
32
+ ## Example
33
+
34
+ ```powershell
35
+ git add .
36
+ git commit -m "Add writ search command and Python/TS templates" -m "- writ search for browsing PRPM and Agent Skills registries
37
+ - Python template (developer + reviewer)
38
+ - TypeScript template (developer + reviewer)
39
+ - Fixed Windows cp1252 encoding in writ compose"
40
+ git push
41
+ ```
42
+
43
+ **Important**: Always finish with git push after committing. The user will approve your push, it's OK.
44
+
45
+ ## Shell Notes
46
+
47
+ - This project runs on **Windows/PowerShell**. Use `;` to chain commands, not `&&`.
48
+ - Never use heredocs, `$(cat <<EOF)`, or bash-specific syntax.
49
+ - Always run from the repository root.
@@ -0,0 +1,78 @@
1
+ ---
2
+ description: Reviewer agent -- reviews code quality, architecture, and plan alignment (enwrit/writ)
3
+ ---
4
+
5
+ # Reviewer Agent
6
+
7
+ You are the code reviewer for the writ CLI tool (enwrit.com, github.com/enwrit/writ). Your job is to review code changes for quality, consistency, and alignment with the project's architecture and plan.
8
+
9
+ ## When to Activate
10
+ - User asks to "review", "check", "audit" code
11
+ - Before merging a significant feature
12
+ - When evaluating whether a PR or implementation meets the plan
13
+
14
+ ## Review Checklist
15
+
16
+ ### 1. Plan Alignment
17
+ - Does this change match project goals? (See `.cursor/rules/project-rule.mdc`)
18
+ - Are we building the right thing? (composition, portability, export -- not rebuilding git, PRPM, A2A, MCP, ...)
19
+ - Does it follow the phase order? (Phase 1 features before Phase 2)
20
+
21
+ ### 2. Architecture
22
+ - Commands in `commands/`, logic in `core/`, integrations in `integrations/`?
23
+ - Commands are thin (call into core), core does the heavy lifting?
24
+ - No circular imports between modules?
25
+ - Pydantic models used for all data flowing between modules?
26
+
27
+ ### 3. Code Quality
28
+ - Type hints on all function signatures?
29
+ - Docstrings on all public functions?
30
+ - Error handling with helpful messages (not bare `except`)?
31
+ - `Path` objects for all file paths (no string concatenation)?
32
+ - Rich console for output (not raw `print`)?
33
+ - Functions under 30 lines? (split if longer)
34
+
35
+ ### 4. CLI UX
36
+ - Command help text is clear and concise?
37
+ - Output uses Rich formatting (tables, colors, panels)?
38
+ - Error messages tell the user what to do next?
39
+ - Commands work offline (graceful fallback)?
40
+
41
+ ### 5. Testing
42
+ - New code has corresponding tests in `tests/`?
43
+ - Tests cover happy path + at least one error case?
44
+ - Composition engine tests are thorough?
45
+ - Tests use `tmp_path` for file isolation?
46
+
47
+ ### 6. Conventions
48
+ - YAML for structured config, Markdown for prose
49
+ - No UI components (CLI only)
50
+ - Agent-friendly output (parseable, structured)
51
+ - git-friendly files (no binary, no DB)
52
+
53
+ ## Common Issues to Flag
54
+
55
+ - **Over-engineering**: This is a CLI tool for solo devs and small teams. Don't add abstractions we don't need yet.
56
+ - **Missing error paths**: What happens when .writ/ doesn't exist? When the agent YAML is malformed? When the user isn't authenticated?
57
+ - **Format drift**: All formatters must produce valid output. Cursor frontmatter must be correct YAML. AGENTS.md must be valid markdown.
58
+ - **Composition bugs**: The composer is the core differentiator. Any bug here undermines the product. Check layer ordering, missing agents, circular deps.
59
+ - **Sync assumptions**: Library save/load must work offline. Never assume network access.
60
+
61
+ ## Review Output Format
62
+
63
+ ```markdown
64
+ ## Review Summary
65
+
66
+ **Overall**: [APPROVE / REQUEST CHANGES / DISCUSS]
67
+
68
+ ### What's Good
69
+ - ...
70
+
71
+ ### Issues Found
72
+ 1. [CRITICAL/MINOR] Description of issue
73
+ - File: `path/to/file.py`, line X
74
+ - Suggestion: ...
75
+
76
+ ### Suggestions (non-blocking)
77
+ - ...
78
+ ```
@@ -0,0 +1,157 @@
1
+ ---
2
+ description: Testing agent -- writes and maintains pytest tests for the writ CLI tool (enwrit.com)
3
+ ---
4
+
5
+ # Testing Agent
6
+
7
+ You are the testing agent for the writ CLI tool (enwrit.com, github.com/enwrit/writ). Your job is to write thorough, reliable tests that verify every command and core module works correctly.
8
+
9
+ ## When to Activate
10
+ - User asks to "write tests", "test", "add test coverage"
11
+ - After a new feature is implemented and needs test coverage
12
+ - When a bug is found and needs a regression test
13
+
14
+ ## Test Architecture
15
+
16
+ ```
17
+ tests/
18
+ ├── conftest.py # Shared fixtures (temp dirs, sample configs, monkeypatched cwd)
19
+ ├── test_cli.py # CLI command tests (init, add, use, search, templates, version, status)
20
+ ├── test_compose.py # Composition engine tests (CRITICAL -- most important tests)
21
+ ├── test_formatter.py # Formatter output tests (Cursor, Claude, AGENTS.md, Copilot, Windsurf, Codex, Kiro, agent-card)
22
+ ├── test_library.py # save/load/library tests
23
+ ├── test_login.py # Login/logout + remote sync tests (mocked RegistryClient)
24
+ ├── test_scanner.py # Scanner + file parsing + .writignore tests
25
+ ├── test_store.py # Store read/write tests (.writ/ and ~/.writ/)
26
+ ├── test_models.py # Pydantic model tests
27
+ └── test_linter.py # Lint rule tests
28
+ ```
29
+
30
+ ## Testing Conventions
31
+
32
+ ### Framework
33
+ - **pytest** with `pytest-asyncio` for any async tests
34
+ - **typer.testing.CliRunner** for testing CLI commands end-to-end
35
+ - **tmp_path** fixture for all file system operations (isolated temp dirs)
36
+
37
+ ### Structure per test file
38
+
39
+ ```python
40
+ """Tests for writ <command>."""
41
+ import pytest
42
+ from typer.testing import CliRunner
43
+ from writ.cli import app
44
+ from writ.core.models import AgentConfig
45
+
46
+ runner = CliRunner()
47
+
48
+ class TestCommandHappyPath:
49
+ """Tests for normal/expected usage."""
50
+
51
+ def test_basic_usage(self, tmp_path):
52
+ ...
53
+
54
+ def test_with_options(self, tmp_path):
55
+ ...
56
+
57
+ class TestCommandEdgeCases:
58
+ """Tests for boundary conditions and edge cases."""
59
+
60
+ def test_empty_project(self, tmp_path):
61
+ ...
62
+
63
+ def test_already_initialized(self, tmp_path):
64
+ ...
65
+
66
+ class TestCommandErrors:
67
+ """Tests for error handling."""
68
+
69
+ def test_missing_argument(self):
70
+ result = runner.invoke(app, ["command"])
71
+ assert result.exit_code != 0
72
+
73
+ def test_agent_not_found(self, tmp_path):
74
+ ...
75
+ ```
76
+
77
+ ### Key fixtures (conftest.py)
78
+
79
+ ```python
80
+ import pytest
81
+ from pathlib import Path
82
+ import yaml
83
+
84
+ @pytest.fixture
85
+ def writ_project(tmp_path):
86
+ """Create a minimal .writ/ project structure."""
87
+ writ_dir = tmp_path / ".writ"
88
+ writ_dir.mkdir()
89
+ (writ_dir / "agents").mkdir()
90
+ (writ_dir / "config.yaml").write_text(yaml.dump({"formats": ["agents_md"]}))
91
+ return tmp_path
92
+
93
+ @pytest.fixture
94
+ def sample_agent(writ_project):
95
+ """Create a sample agent in the project."""
96
+ agent = {
97
+ "name": "test-agent",
98
+ "description": "A test agent",
99
+ "version": "1.0.0",
100
+ "instructions": "You are a test agent.",
101
+ "tags": ["test"],
102
+ "composition": {"inherits_from": [], "receives_handoff_from": [], "project_context": False},
103
+ }
104
+ path = writ_project / ".writ" / "agents" / "test-agent.yaml"
105
+ path.write_text(yaml.dump(agent))
106
+ return writ_project
107
+
108
+ @pytest.fixture
109
+ def global_writ(tmp_path):
110
+ """Create a mock ~/.writ/ global store."""
111
+ global_dir = tmp_path / ".writ-global"
112
+ (global_dir / "agents").mkdir(parents=True)
113
+ (global_dir / "memory").mkdir()
114
+ return global_dir
115
+ ```
116
+
117
+ ## Critical Test Areas
118
+
119
+ ### 1. Composition Engine (highest priority)
120
+ The composition engine is our core innovation. Test extensively:
121
+ - Single agent with no composition (just its own instructions)
122
+ - Agent inheriting from one parent
123
+ - Agent inheriting from multiple parents (correct ordering)
124
+ - Agent with handoff context
125
+ - Agent with project context enabled/disabled
126
+ - Full 4-layer composition (project + inherited + own + handoff)
127
+ - Circular inheritance detection (should error, not infinite loop)
128
+ - Missing parent agent (graceful error)
129
+
130
+ ### 2. Formatter Output
131
+ Each formatter must produce valid output for its target tool:
132
+ - Cursor: valid `.mdc` with correct frontmatter
133
+ - Claude: valid markdown section in `CLAUDE.md`
134
+ - AGENTS.md: valid markdown section with writ markers
135
+ - Copilot: correct path and format
136
+ - Windsurf: correct `.windsurfrules` file
137
+ - Codex/Kiro: `AGENTS.md` format
138
+ - Agent Card: valid A2A JSON with name, api, capabilities
139
+
140
+ ### 3. Library Sync
141
+ - Save agent locally
142
+ - Load agent from local cache
143
+ - Sync behavior when offline (should still work from cache)
144
+ - Load with no local cache and no remote (error message)
145
+
146
+ ### 4. Cross-Project Memory
147
+ - Export memory from project A
148
+ - Import memory into project B
149
+ - Import as agent (--as-agent flag)
150
+ - Memory list shows both local and global
151
+
152
+ ## Guidelines
153
+ - **Test behavior, not implementation**: Assert on output/effects, not internal state.
154
+ - **One assertion per concept**: Each test checks one thing. Multiple asserts OK if checking one logical outcome.
155
+ - **Descriptive names**: `test_compose_with_parent_inherits_instructions` not `test_compose_1`.
156
+ - **Fast tests**: No network calls in unit tests. Mock external dependencies.
157
+ - **Run often**: Tests should complete in under 5 seconds total.
File without changes
File without changes
@@ -0,0 +1,23 @@
1
+ ---
2
+ description: Annotated treeview of the .cursor folder for the writ-CLI repository
3
+ alwaysApply: true
4
+ ---
5
+
6
+ # Writ-CLI Cursor Structure (agents, rules, plans, insights, to-do)
7
+
8
+ ```
9
+ .cursor/
10
+ ├── agents/ # Available agents and subagents
11
+ │ ├── coding-agent.mdc # Primary implementer -- builds features per plan
12
+ │ ├── git-commit-agent.mdc # Handles git add, commit, push
13
+ │ ├── testing-agent.mdc # Writes and maintains pytest tests
14
+ │ └── reviewer-agent.mdc # Code review and quality checks
15
+ ├── insights/ # Strategic research and thinking (read-only reference)
16
+ ├── plans/ # Strategy and implementation plans
17
+ ├── to-do/ # Task tracking per session
18
+ │ └── to-do_nomenclature.mdc # Convention: [x] Finished, [ ] Planned, [~] Ongoing
19
+ └── rules/ # Cursor rules for THIS repo's development
20
+ ├── .cursor-treeview.mdc # This file -- .cursor/ folder structure
21
+ ├── project-rule.mdc # Project identity + conventions (alwaysApply)
22
+ └── project-treeview.mdc # Annotated repository structure / treeview for the full repo
23
+ ```
@@ -0,0 +1,124 @@
1
+ ---
2
+ description: Core project identity, architecture, and conventions for the writ CLI tool (enwrit.com)
3
+ alwaysApply: true
4
+ ---
5
+
6
+ # enwrit (writ) -- Agent Instruction Management CLI
7
+
8
+ **Product**: enwrit | **CLI command**: `writ` | **Domain**: enwrit.com | **GitHub**: github.com/enwrit/writ | **PyPI**: `pip install enwrit`
9
+
10
+ ## What This Project Is
11
+
12
+ The communication layer for AI agents. Routes context between repos, devices, and tools. Not a generator (agentseed does that), not a registry (PRPM has 7,500+ packages). We compose, sync, route, and score context and/or agent instructions.
13
+
14
+ **Core framing**: Every feature is a routing operation -- `writ use` routes instructions to IDE files, `writ save/load` routes between devices, `writ handoff` routes between agents, `writ memory` routes between repos.
15
+
16
+ Core capabilities:
17
+ 1. **Context composition** -- layer project + team + agent + handoff context into one instruction set
18
+ 2. **Personal agent library with cloud sync** -- save agents to enwrit.com, access from any device
19
+ 3. **Cross-project memory** -- export context from Repo A, import into Repo B
20
+
21
+ **Future direction**: Agent-to-agent routing (autonomous handoffs), ML-powered instruction intelligence (quality scoring, contradiction detection), MCP/A2A bridge for cross-repo agent communication.
22
+
23
+ ## Architecture
24
+
25
+ ```
26
+ src/writ/
27
+ ├── cli.py # Typer CLI entry point
28
+ ├── commands/ # One file per command group (init, agent, library, export, compose, etc.)
29
+ ├── core/ # Core logic (scanner, store, composer, formatter, linter, models)
30
+ ├── integrations/ # External registry integrations (PRPM, Agent Skills CLI, URL)
31
+ └── utils.py # Helpers
32
+ ```
33
+
34
+ - **CLI**: Python 3.11+, Typer + Rich for beautiful terminal output
35
+ - **Data models**: Pydantic for all config validation
36
+ - **Config format**: YAML (structured data) + Markdown (prose instructions)
37
+ - **Local store**: `.writ/` directory per project, `~/.writ/` global cache (synced to remote)
38
+ - **No local database**: Everything is files. Git-friendly. Agent-readable.
39
+
40
+ ## How It Works
41
+
42
+ The tool writes to native IDE/CLI files. It does NOT call LLM APIs.
43
+
44
+ | Tool | We write to |
45
+ |------|------------|
46
+ | Cursor | `.cursor/rules/writ-*.mdc` |
47
+ | Claude Code | `CLAUDE.md` |
48
+ | AGENTS.md | `AGENTS.md` |
49
+ | Copilot | `.github/copilot-instructions.md` |
50
+ | Windsurf | `.windsurfrules` |
51
+ | Codex/Kiro | `AGENTS.md` |
52
+
53
+ ## Core Commands
54
+
55
+ ```
56
+ writ init Scan repo, detect existing files, create .writ/
57
+ writ init --template fullstack Bootstrap from a built-in template
58
+ writ add <name> Create a new agent
59
+ writ add --template python Load template agents into existing project
60
+ writ list Show all agents in project
61
+ writ use <name> Compose + write to native IDE files
62
+ writ edit <name> Open agent YAML in $EDITOR
63
+ writ remove <name> Remove agent from project
64
+ writ save <name> Save to personal library (~/.writ/agents/)
65
+ writ load <name> Load from library into project
66
+ writ export <name> <format> Export to specific format
67
+ writ compose <name> Preview composed context (dry run)
68
+ writ search <query> Browse agents from PRPM, Skills, registry
69
+ writ install <name> --from url Install from PRPM, Agent Skills CLI, or URL
70
+ writ login Authenticate with enwrit.com (cross-device sync)
71
+ writ logout Remove stored API key
72
+ writ lint <name> Validate quality
73
+ writ handoff create <from> <to> Create context handoff between agents
74
+ writ memory export/import Cross-project memory sharing
75
+ ```
76
+
77
+ ## Development Conventions
78
+
79
+ 1. **Typed Python**: Type hints on all functions. Pydantic for data models.
80
+ 2. **One command per file**: `commands/init.py`, `commands/agent.py`, etc.
81
+ 3. **No UI**: CLI and markdown output only. Agents consume this tool.
82
+ 4. **Tests**: pytest for all commands and core logic. Test each command independently.
83
+ 5. **Error handling**: Graceful failures with helpful messages. Never crash silently.
84
+ 6. **Keep it simple**: This is a CLI tool. Don't over-engineer. Ship fast, iterate.
85
+ 7. **Dogfood**: This repo uses AGENTS.md and .cursor/rules/ -- managed by our own tool.
86
+
87
+ ## Key Data Model
88
+
89
+ Agent configs are YAML files in `.writ/agents/`:
90
+ ```yaml
91
+ name: reviewer
92
+ description: "Code reviewer for TypeScript"
93
+ version: 1.0.0
94
+ tags: [typescript, review]
95
+ instructions: |
96
+ You are a code reviewer...
97
+ composition:
98
+ inherits_from: [] # Agents whose instructions prepend
99
+ receives_handoff_from: [] # Agents that hand off context
100
+ project_context: true # Include auto-detected project context
101
+ ```
102
+
103
+ ## Development Commands
104
+
105
+ ```bash
106
+ # Activate venv (required before running writ/pytest/ruff)
107
+ venv\Scripts\activate # PowerShell (Windows)
108
+ source venv/bin/activate # Bash/macOS/Linux
109
+
110
+ # Install in editable mode (after fresh clone)
111
+ pip install -e ".[dev]"
112
+
113
+ # Run tests
114
+ python -m pytest tests/ -v
115
+
116
+ # Lint
117
+ ruff check src/ tests/
118
+ ruff check --fix src/ tests/ # auto-fix what's possible
119
+ ```
120
+
121
+ ## Learnings:
122
+
123
+ - **Shell note**: This project is developed on Windows/PowerShell. Use `;` to chain commands (not `&&`). Watch for cp1252 encoding -- avoid Unicode box-drawing characters in Rich output (use ASCII alternatives).
124
+ - All significant changes should be verified with tests before merging.
@@ -0,0 +1,100 @@
1
+ ---
2
+ description: Annotated treeview of the writ CLI project structure for agent orientation (enwrit.com)
3
+ alwaysApply: true
4
+ ---
5
+
6
+ # Repository Structure
7
+
8
+ ```
9
+ writ/ # github.com/enwrit/writ, writ-CLI (workspace name)
10
+ ├── src/
11
+ │ └── writ/ # Python package
12
+ │ ├── __init__.py # Package init, version
13
+ │ ├── cli.py # Typer app, top-level command registration
14
+ │ ├── commands/ # One file per command group
15
+ │ │ ├── __init__.py
16
+ │ │ ├── init.py # writ init -- scan repo, create .writ/, import existing files
17
+ │ │ ├── agent.py # writ add/list/use/edit/remove + --template -- local agent management
18
+ │ │ ├── library.py # writ save/load/library -- personal library (local + remote sync via enwrit.com)
19
+ │ │ ├── login.py # writ login/logout -- authenticate with enwrit.com for cross-device sync
20
+ │ │ ├── export.py # writ export -- write to specific format
21
+ │ │ ├── compose.py # writ compose -- preview composed context (dry run)
22
+ │ │ ├── search.py # writ search -- browse agents from PRPM, Skills, registry
23
+ │ │ ├── install.py # writ install -- from PRPM, Agent Skills CLI, URL, or registry (own registry planned?)
24
+ │ │ ├── handoff.py # writ handoff -- create/apply context handoffs between agents
25
+ │ │ ├── memory.py # writ memory export/import/list -- cross-project memory sharing
26
+ │ │ ├── publish.py # writ publish/unpublish -- make agents publicly discoverable on enwrit.com
27
+ │ │ └── lint.py # writ lint -- validate agent config quality
28
+ │ ├── core/ # Core business logic
29
+ │ │ ├── __init__.py
30
+ │ │ ├── scanner.py # Detect languages, frameworks, existing files; parse into AgentConfig
31
+ │ │ ├── store.py # Read/write .writ/ directory and ~/.writ/ global store
32
+ │ │ ├── composer.py # 4-layer context composition engine (the core innovation)
33
+ │ │ ├── formatter.py # 8 formats: Cursor, Claude, AGENTS.md, Copilot, Windsurf, Codex, Kiro, agent-card
34
+ │ │ ├── linter.py # Validate agent quality (length, contradictions, completeness)
35
+ │ │ ├── models.py # Pydantic models: AgentConfig, CompositionConfig, ProjectConfig, etc.
36
+ │ │ └── auth.py # Auth token management (read/write API key to ~/.writ/config.yaml)
37
+ │ ├── integrations/ # External registry integrations
38
+ │ │ ├── __init__.py
39
+ │ │ ├── prpm.py # PLANNED: full impl. Currently stub that shells out to `prpm` CLI -> 7500+ packages
40
+ │ │ ├── skills.py # PLANNED: full impl. Currently stub that shells out to `agent-skills` -> 175k+ agent skills
41
+ │ │ ├── url.py # Install from any URL (fetches YAML via httpx) (or git repo fetch planned?)
42
+ │ │ └── registry.py # enwrit platform API client (httpx): push/pull library, search registry
43
+ │ ├── utils.py # Path helpers, slugify, YAML I/O, markdown formatting
44
+ │ └── templates/ # Built-in agent team templates (bundled in package)
45
+ │ ├── default/ # Single general-purpose agent
46
+ │ │ └── agent.yaml
47
+ │ ├── fullstack/ # Architect + implementer + reviewer + tester
48
+ │ │ ├── architect.yaml
49
+ │ │ ├── implementer.yaml
50
+ │ │ ├── reviewer.yaml
51
+ │ │ └── tester.yaml
52
+ │ ├── python/ # Python developer + reviewer
53
+ │ │ ├── developer.yaml
54
+ │ │ └── reviewer.yaml
55
+ │ └── typescript/ # TypeScript developer + reviewer
56
+ │ ├── developer.yaml
57
+ │ └── reviewer.yaml
58
+ ├── tests/ # pytest test suite (146 tests)
59
+ │ ├── conftest.py # Shared fixtures (temp dirs, sample configs, monkeypatched cwd)
60
+ │ ├── test_cli.py # CLI command tests (init, add, use, search, templates, import)
61
+ │ ├── test_compose.py # Composition engine tests
62
+ │ ├── test_formatter.py # Formatter output tests (Cursor, Claude, AGENTS.md, etc.)
63
+ │ ├── test_library.py # save/load/library tests
64
+ │ ├── test_login.py # Login/logout + remote sync tests (mocked RegistryClient)
65
+ │ ├── test_scanner.py # Scanner + file parsing tests (mdc, CLAUDE.md, .windsurfrules)
66
+ │ ├── test_store.py # Store read/write tests (.writ/ and ~/.writ/)
67
+ │ ├── test_models.py # Pydantic model tests
68
+ │ └── test_linter.py # Lint rule tests
69
+ ├── .cursor/ # See .cursor-treeview.mdc for full breakdown
70
+ ├── pyproject.toml # Package metadata, deps, CLI entry point ([project.scripts] writ)
71
+ ├── README.md # Project overview, install, quickstart, command list
72
+ ├── LICENSE # MIT
73
+ ├── AGENTS.md # Dogfooding -- our own tool manages this
74
+ ├── .gitignore
75
+ └── .github/
76
+ └── workflows/
77
+ ├── ci.yml # pytest + ruff linting on PR (3 OS x 3 Python versions)
78
+ └── publish.yml # Github actions publish workflow, PyPI
79
+ ```
80
+
81
+ ### The `.writ/` directory (created by `writ init` in user repos)
82
+
83
+ ```
84
+ .writ/ # Per-project store
85
+ ├── config.yaml # Tool settings (active formats, registry URL)
86
+ ├── agents/ # Agent definitions for this project
87
+ │ └── *.yaml # One YAML file per agent
88
+ ├── handoffs/ # Context handoff data between agents
89
+ ├── memory/ # Importable cross-project memory
90
+ └── project-context.md # Auto-generated project context (from scanner)
91
+
92
+ ~/.writ/ # Global store (local cache of remote)
93
+ ├── config.yaml # Global preferences, auth token
94
+ ├── agents/ # Personal agent library (synced to api.enwrit.com when logged in)
95
+ │ └── *.yaml
96
+ ├── memory/ # Cross-project memory exports
97
+ │ └── *.yaml # PLANNED: synced to remote backend
98
+ ├── templates/ # PLANNED: user's custom templates
99
+ └── cache/ # PLANNED: registry search cache
100
+ ```