dotai-cli 0.4.0__tar.gz → 0.5.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.
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/PKG-INFO +116 -22
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/README.md +115 -21
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/pyproject.toml +1 -1
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/__init__.py +1 -1
- dotai_cli-0.5.0/src/dotai/agents.py +156 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/cli/__init__.py +9 -4
- dotai_cli-0.5.0/src/dotai/cli/agents_cmd.py +108 -0
- dotai_cli-0.5.0/src/dotai/cli/sync_cmd.py +349 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/cli/watch_cmd.py +18 -4
- dotai_cli-0.5.0/src/dotai/context.py +359 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/sync.py +310 -40
- dotai_cli-0.5.0/tests/test_agents.py +110 -0
- dotai_cli-0.5.0/tests/test_context.py +181 -0
- dotai_cli-0.5.0/tests/test_sync.py +378 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/uv.lock +1 -1
- dotai_cli-0.4.0/src/dotai/cli/sync_cmd.py +0 -211
- dotai_cli-0.4.0/tests/test_sync.py +0 -154
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/.github/workflows/ci.yml +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/.github/workflows/publish.yml +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/.gitignore +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/LICENSE +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/rdc.yaml +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/__main__.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/cli/__main__.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/cli/prefs_cmd.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/cli/roles_cmd.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/cli/rules_cmd.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/cli/skills_cmd.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/converter.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/import_agent.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/indexer.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/maintenance.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/models.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/preferences.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/roles.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/rules.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/seed/roles/architect.md +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/seed/roles/debugger.md +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/seed/roles/founder.md +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/seed/roles/mentor.md +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/seed/roles/product-manager.md +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/seed/roles/qa.md +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/seed/roles/reviewer.md +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/seed/roles/security.md +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/seed/roles/ship.md +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/seed/roles/writer.md +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/seed/skills/careful.md +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/seed/skills/commit-helper.md +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/seed/skills/compress.md +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/seed/skills/context-dump.md +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/seed/skills/investigate.md +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/seed/skills/learn.md +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/seed/skills/parallel-work.md +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/seed/skills/plan.md +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/seed/skills/review.md +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/seed/skills/scaffold.md +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/seed/skills/ship.md +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/seed/skills/techdebt.md +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/seed/skills/verify.md +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/skills.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/store.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/tools/__init__.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/tools/base.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/tools/registry.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/utils.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/src/dotai/vet.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/tests/__init__.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/tests/conftest.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/tests/test_converter.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/tests/test_import_agent.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/tests/test_maintenance.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/tests/test_models.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/tests/test_preferences.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/tests/test_roles.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/tests/test_rules.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/tests/test_skills.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/tests/test_store.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/tests/test_utils.py +0 -0
- {dotai_cli-0.4.0 → dotai_cli-0.5.0}/tests/test_vet.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dotai-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Universal AI context for any coding agent. Roles, skills, and rules in ~/.ai/
|
|
5
5
|
Project-URL: Homepage, https://github.com/dawalama/dotai
|
|
6
6
|
Project-URL: Repository, https://github.com/dawalama/dotai
|
|
@@ -72,7 +72,7 @@ dotai learn "no-print-debugging" \
|
|
|
72
72
|
--correction "Use structured logging and remove temporary debug output" \
|
|
73
73
|
--globs "*.py"
|
|
74
74
|
|
|
75
|
-
#
|
|
75
|
+
# Prepare that knowledge for the current project
|
|
76
76
|
cd ~/my-project
|
|
77
77
|
dotai sync
|
|
78
78
|
```
|
|
@@ -121,32 +121,113 @@ dotai roles
|
|
|
121
121
|
dotai skills
|
|
122
122
|
dotai rules
|
|
123
123
|
|
|
124
|
-
#
|
|
124
|
+
# Prepare agent context for a project
|
|
125
125
|
cd ~/my-project
|
|
126
126
|
dotai sync
|
|
127
127
|
```
|
|
128
128
|
|
|
129
|
-
|
|
129
|
+
Inside a Git repository, `dotai sync` defaults to **local mode**. It writes personal context under `~/.config/dotai/contexts/` and leaves team-owned files such as `CLAUDE.md`, `AGENTS.md`, and `.claude/skills/` untouched. Existing repository instructions are copied into the local context as the authoritative layer; personal dotai rules and preferences are explicitly supplemental.
|
|
130
|
+
|
|
131
|
+
Local context storage does not, by itself, make an agent load the context. Until an agent adapter is configured, use `dotai primer --path .` to print context for pasting or piping into your agent. Use `dotai sync --shared` only when your team has intentionally chosen to maintain dotai sections in repository files.
|
|
132
|
+
|
|
133
|
+
dotai uses progressive disclosure to keep prompts small. Synced context contains rule summaries and role/skill catalogs. Expand only what a task needs:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
# Expand rules matching the affected files
|
|
137
|
+
dotai context --path . --files src/api.py,tests/test_api.py
|
|
138
|
+
|
|
139
|
+
# Expand security-tagged rules and an active CLI preference pack
|
|
140
|
+
dotai context --path . --context security --domain cli
|
|
141
|
+
|
|
142
|
+
# Load one complete skill and its declared role
|
|
143
|
+
dotai context --path . --skill run_review
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Selection is deterministic: file globs, explicit context tags, active preference domains, and named skills or roles. dotai does not guess from semantic similarity. Every expanded item includes the reason it was selected.
|
|
147
|
+
|
|
148
|
+
### Automatic delivery with Claude Code
|
|
149
|
+
|
|
150
|
+
The resolver is infrastructure; you should not have to type `dotai context`
|
|
151
|
+
during normal work. Install dotai's user-level Claude adapter once:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
# Preview the user-memory change
|
|
155
|
+
dotai agent setup claude
|
|
156
|
+
|
|
157
|
+
# Back up existing memory and install it
|
|
158
|
+
dotai agent setup claude --apply
|
|
159
|
+
|
|
160
|
+
# Confirm activation
|
|
161
|
+
dotai agent status claude
|
|
162
|
+
|
|
163
|
+
# See the most recent context Claude actually resolved
|
|
164
|
+
dotai agent last claude
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
The adapter adds a small marker-managed block to `~/.claude/CLAUDE.md`, which
|
|
168
|
+
Claude Code loads as user memory across projects. It tells Claude to resolve
|
|
169
|
+
dotai context for substantial development work, after affected files are known,
|
|
170
|
+
and to avoid repeated calls when the task has not changed. Repository and
|
|
171
|
+
organization instructions remain authoritative.
|
|
172
|
+
|
|
173
|
+
For file-sensitive workflows such as review, debugging, verification, scaffolding,
|
|
174
|
+
maintenance, and release work, a resolution without `--files` is explicitly
|
|
175
|
+
marked provisional. Claude must resolve again after discovering the affected
|
|
176
|
+
files. `dotai agent last claude` reports whether the latest resolution is
|
|
177
|
+
`provisional` or `complete`.
|
|
178
|
+
|
|
179
|
+
The adapter does not modify repositories, install a persistent process, or use
|
|
180
|
+
MCP. Existing personal Claude instructions are preserved. To remove only
|
|
181
|
+
dotai's block:
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
dotai agent remove claude
|
|
185
|
+
dotai agent remove claude --apply
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Setup and removal preview by default. Applied changes back up the prior Claude
|
|
189
|
+
memory under `~/.config/dotai/backups/agents/claude/`.
|
|
190
|
+
|
|
191
|
+
`dotai agent last claude` reads a local receipt written only when the Claude
|
|
192
|
+
adapter invokes the resolver. It reports selection metadata and reasons, but
|
|
193
|
+
never stores source contents, expanded prompts, credentials, or telemetry.
|
|
194
|
+
|
|
195
|
+
### Moving an existing repository to local mode
|
|
196
|
+
|
|
197
|
+
If an older dotai version wrote generated context into repository files, use the
|
|
198
|
+
one-off detach command. It previews by default:
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
dotai detach
|
|
202
|
+
dotai detach --apply
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Detach removes only complete `<!-- dotai:start -->` blocks and Claude skill
|
|
206
|
+
directories whose `SKILL.md` contains dotai's generated marker. Loader files
|
|
207
|
+
containing team content are preserved and updated in place; files containing
|
|
208
|
+
only generated dotai content are removed. Before applying changes, dotai copies
|
|
209
|
+
every affected artifact to `~/.config/dotai/backups/detach/`. Detach is not part
|
|
210
|
+
of routine sync and does not need to be run again after migration.
|
|
130
211
|
|
|
131
212
|
## Usage
|
|
132
213
|
|
|
133
214
|
### Daily workflow
|
|
134
215
|
|
|
135
216
|
```bash
|
|
136
|
-
# Start of day:
|
|
217
|
+
# Start of day: refresh local context for the project you're working on
|
|
137
218
|
cd ~/my-project
|
|
138
219
|
dotai sync
|
|
139
220
|
|
|
140
221
|
# Or leave it running — auto-resyncs when you edit ~/.ai/ files
|
|
141
222
|
dotai watch
|
|
142
223
|
|
|
143
|
-
#
|
|
144
|
-
|
|
224
|
+
# Print the context for an agent that does not yet have a dotai adapter
|
|
225
|
+
dotai primer --path .
|
|
145
226
|
```
|
|
146
227
|
|
|
147
228
|
### Using skills in Claude Code
|
|
148
229
|
|
|
149
|
-
After `dotai sync
|
|
230
|
+
After an explicit shared Claude sync (`dotai sync --shared --agents claude`), skills appear as native slash commands:
|
|
150
231
|
|
|
151
232
|
```
|
|
152
233
|
> /run_plan # Plan before coding
|
|
@@ -601,25 +682,31 @@ dotai toggle no-useeffect --off --project my-legacy-app
|
|
|
601
682
|
dotai toggle no-useeffect --on
|
|
602
683
|
```
|
|
603
684
|
|
|
604
|
-
|
|
685
|
+
Synced agent files contain a compact bootstrap by default: universal rule summaries plus preference, role, and skill catalogs. Use `dotai context` to expand relevant material on demand, or pass `dotai sync --full` for the legacy complete inline context.
|
|
605
686
|
|
|
606
687
|
## Agent Sync
|
|
607
688
|
|
|
608
|
-
`dotai sync`
|
|
689
|
+
`dotai sync` prepares tool-specific context with:
|
|
609
690
|
|
|
610
|
-
- **
|
|
611
|
-
- **
|
|
612
|
-
- **Role and skill catalogs** (names, triggers,
|
|
691
|
+
- **Universal structured rule summaries** (always visible)
|
|
692
|
+
- **Pointers to freeform `rules.md` conventions**
|
|
693
|
+
- **Role and skill catalogs** (names, triggers, categories — not full workflows)
|
|
613
694
|
- **Claude Code**: compact pointers + native `.claude/skills/` slash commands
|
|
614
695
|
|
|
615
696
|
Use `--full` only when you need every role persona and skill definition dumped inline (larger context).
|
|
616
697
|
|
|
617
|
-
|
|
698
|
+
In a Git repository, local mode is the default and writes outside the worktree. Team instructions take precedence over personal dotai rules and preferences. dotai does not attempt unreliable keyword-based conflict resolution; the generated context tells the agent to ignore conflicting personal guidance and ask when a disagreement is ambiguous.
|
|
618
699
|
|
|
619
700
|
```bash
|
|
620
|
-
#
|
|
701
|
+
# Safe default in Git: generate outside the repository
|
|
621
702
|
dotai sync
|
|
622
703
|
|
|
704
|
+
# Preview the resolved mode and target without writing
|
|
705
|
+
dotai sync --check
|
|
706
|
+
|
|
707
|
+
# Explicit team-owned mode: update marked sections in repository files
|
|
708
|
+
dotai sync --shared
|
|
709
|
+
|
|
623
710
|
# Generate for specific agents
|
|
624
711
|
dotai sync --agents claude,cursor
|
|
625
712
|
dotai sync --agents gemini
|
|
@@ -629,18 +716,22 @@ dotai sync --full
|
|
|
629
716
|
|
|
630
717
|
# Print primer to stdout (for piping)
|
|
631
718
|
dotai primer
|
|
632
|
-
dotai primer --
|
|
719
|
+
dotai primer --path .
|
|
633
720
|
dotai primer --full
|
|
721
|
+
|
|
722
|
+
# Resolve task-specific context on demand
|
|
723
|
+
dotai context --path . --files src/app.tsx --context security
|
|
724
|
+
dotai context --path . --skill run_review
|
|
634
725
|
```
|
|
635
726
|
|
|
636
727
|
### Supported Agents
|
|
637
728
|
|
|
638
729
|
| Agent | Output File | Sync Command | Notes |
|
|
639
730
|
|-------|-------------|--------------|-------|
|
|
640
|
-
| Claude Code | `CLAUDE.md` + `.claude/skills/` | `dotai sync --agents claude` |
|
|
641
|
-
| Cursor | `.cursorrules` | `dotai sync --agents cursor` |
|
|
642
|
-
| Gemini CLI | `GEMINI.md` | `dotai sync --agents gemini` |
|
|
643
|
-
| Generic | `AGENTS.md` | `dotai sync --agents generic` |
|
|
731
|
+
| Claude Code | Local cache; shared: `CLAUDE.md` + `.claude/skills/` | `dotai sync --agents claude` | Team file is authoritative; shared mode uses marker-based merging |
|
|
732
|
+
| Cursor | `.cursorrules` | `dotai sync --agents cursor` | Compact bootstrap by default; full context with `--full` |
|
|
733
|
+
| Gemini CLI | `GEMINI.md` | `dotai sync --agents gemini` | Compact bootstrap; shared files are auto-discovered by Gemini CLI |
|
|
734
|
+
| Generic | `AGENTS.md` | `dotai sync --agents generic` | Compact bootstrap for agents that read `AGENTS.md` |
|
|
644
735
|
|
|
645
736
|
For Claude Code, `dotai sync` also generates `.claude/skills/<trigger>/SKILL.md` files. These register as native slash commands — they appear in autocomplete and work as real `/run_*` commands with role composition support built in.
|
|
646
737
|
|
|
@@ -768,8 +859,11 @@ dotai roles # List available roles
|
|
|
768
859
|
dotai role <name> # Output a role's full prompt to stdout
|
|
769
860
|
dotai skills [-c category] # List skills (optionally filter by category)
|
|
770
861
|
dotai prompt <skill> [--role <role>] # Assemble skill + role prompt for any agent
|
|
771
|
-
dotai sync [path] [--agents ...] [--full]
|
|
772
|
-
dotai
|
|
862
|
+
dotai sync [path] [--local|--shared] [--check] [--agents ...] [--full]
|
|
863
|
+
dotai detach [path] [--apply] # One-off removal of old shared-sync artifacts
|
|
864
|
+
dotai agent setup|status|last|remove claude [--apply] # User-level Claude delivery
|
|
865
|
+
dotai primer [--project <name>|--path <path>] [--full]
|
|
866
|
+
dotai context --path <path> [--task ...] [--files ...] [--context ...] [--domain ...] [--skill ...]
|
|
773
867
|
dotai rules [-p project] [-a] [--check] # List rules (or audit quality)
|
|
774
868
|
dotai audit [-p project] [--json] [--fail-on severity] # Read-only rule audit
|
|
775
869
|
dotai compress [-p project] [--json] # Plan compression candidates
|
|
@@ -43,7 +43,7 @@ dotai learn "no-print-debugging" \
|
|
|
43
43
|
--correction "Use structured logging and remove temporary debug output" \
|
|
44
44
|
--globs "*.py"
|
|
45
45
|
|
|
46
|
-
#
|
|
46
|
+
# Prepare that knowledge for the current project
|
|
47
47
|
cd ~/my-project
|
|
48
48
|
dotai sync
|
|
49
49
|
```
|
|
@@ -92,32 +92,113 @@ dotai roles
|
|
|
92
92
|
dotai skills
|
|
93
93
|
dotai rules
|
|
94
94
|
|
|
95
|
-
#
|
|
95
|
+
# Prepare agent context for a project
|
|
96
96
|
cd ~/my-project
|
|
97
97
|
dotai sync
|
|
98
98
|
```
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
Inside a Git repository, `dotai sync` defaults to **local mode**. It writes personal context under `~/.config/dotai/contexts/` and leaves team-owned files such as `CLAUDE.md`, `AGENTS.md`, and `.claude/skills/` untouched. Existing repository instructions are copied into the local context as the authoritative layer; personal dotai rules and preferences are explicitly supplemental.
|
|
101
|
+
|
|
102
|
+
Local context storage does not, by itself, make an agent load the context. Until an agent adapter is configured, use `dotai primer --path .` to print context for pasting or piping into your agent. Use `dotai sync --shared` only when your team has intentionally chosen to maintain dotai sections in repository files.
|
|
103
|
+
|
|
104
|
+
dotai uses progressive disclosure to keep prompts small. Synced context contains rule summaries and role/skill catalogs. Expand only what a task needs:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# Expand rules matching the affected files
|
|
108
|
+
dotai context --path . --files src/api.py,tests/test_api.py
|
|
109
|
+
|
|
110
|
+
# Expand security-tagged rules and an active CLI preference pack
|
|
111
|
+
dotai context --path . --context security --domain cli
|
|
112
|
+
|
|
113
|
+
# Load one complete skill and its declared role
|
|
114
|
+
dotai context --path . --skill run_review
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Selection is deterministic: file globs, explicit context tags, active preference domains, and named skills or roles. dotai does not guess from semantic similarity. Every expanded item includes the reason it was selected.
|
|
118
|
+
|
|
119
|
+
### Automatic delivery with Claude Code
|
|
120
|
+
|
|
121
|
+
The resolver is infrastructure; you should not have to type `dotai context`
|
|
122
|
+
during normal work. Install dotai's user-level Claude adapter once:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
# Preview the user-memory change
|
|
126
|
+
dotai agent setup claude
|
|
127
|
+
|
|
128
|
+
# Back up existing memory and install it
|
|
129
|
+
dotai agent setup claude --apply
|
|
130
|
+
|
|
131
|
+
# Confirm activation
|
|
132
|
+
dotai agent status claude
|
|
133
|
+
|
|
134
|
+
# See the most recent context Claude actually resolved
|
|
135
|
+
dotai agent last claude
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
The adapter adds a small marker-managed block to `~/.claude/CLAUDE.md`, which
|
|
139
|
+
Claude Code loads as user memory across projects. It tells Claude to resolve
|
|
140
|
+
dotai context for substantial development work, after affected files are known,
|
|
141
|
+
and to avoid repeated calls when the task has not changed. Repository and
|
|
142
|
+
organization instructions remain authoritative.
|
|
143
|
+
|
|
144
|
+
For file-sensitive workflows such as review, debugging, verification, scaffolding,
|
|
145
|
+
maintenance, and release work, a resolution without `--files` is explicitly
|
|
146
|
+
marked provisional. Claude must resolve again after discovering the affected
|
|
147
|
+
files. `dotai agent last claude` reports whether the latest resolution is
|
|
148
|
+
`provisional` or `complete`.
|
|
149
|
+
|
|
150
|
+
The adapter does not modify repositories, install a persistent process, or use
|
|
151
|
+
MCP. Existing personal Claude instructions are preserved. To remove only
|
|
152
|
+
dotai's block:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
dotai agent remove claude
|
|
156
|
+
dotai agent remove claude --apply
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Setup and removal preview by default. Applied changes back up the prior Claude
|
|
160
|
+
memory under `~/.config/dotai/backups/agents/claude/`.
|
|
161
|
+
|
|
162
|
+
`dotai agent last claude` reads a local receipt written only when the Claude
|
|
163
|
+
adapter invokes the resolver. It reports selection metadata and reasons, but
|
|
164
|
+
never stores source contents, expanded prompts, credentials, or telemetry.
|
|
165
|
+
|
|
166
|
+
### Moving an existing repository to local mode
|
|
167
|
+
|
|
168
|
+
If an older dotai version wrote generated context into repository files, use the
|
|
169
|
+
one-off detach command. It previews by default:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
dotai detach
|
|
173
|
+
dotai detach --apply
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Detach removes only complete `<!-- dotai:start -->` blocks and Claude skill
|
|
177
|
+
directories whose `SKILL.md` contains dotai's generated marker. Loader files
|
|
178
|
+
containing team content are preserved and updated in place; files containing
|
|
179
|
+
only generated dotai content are removed. Before applying changes, dotai copies
|
|
180
|
+
every affected artifact to `~/.config/dotai/backups/detach/`. Detach is not part
|
|
181
|
+
of routine sync and does not need to be run again after migration.
|
|
101
182
|
|
|
102
183
|
## Usage
|
|
103
184
|
|
|
104
185
|
### Daily workflow
|
|
105
186
|
|
|
106
187
|
```bash
|
|
107
|
-
# Start of day:
|
|
188
|
+
# Start of day: refresh local context for the project you're working on
|
|
108
189
|
cd ~/my-project
|
|
109
190
|
dotai sync
|
|
110
191
|
|
|
111
192
|
# Or leave it running — auto-resyncs when you edit ~/.ai/ files
|
|
112
193
|
dotai watch
|
|
113
194
|
|
|
114
|
-
#
|
|
115
|
-
|
|
195
|
+
# Print the context for an agent that does not yet have a dotai adapter
|
|
196
|
+
dotai primer --path .
|
|
116
197
|
```
|
|
117
198
|
|
|
118
199
|
### Using skills in Claude Code
|
|
119
200
|
|
|
120
|
-
After `dotai sync
|
|
201
|
+
After an explicit shared Claude sync (`dotai sync --shared --agents claude`), skills appear as native slash commands:
|
|
121
202
|
|
|
122
203
|
```
|
|
123
204
|
> /run_plan # Plan before coding
|
|
@@ -572,25 +653,31 @@ dotai toggle no-useeffect --off --project my-legacy-app
|
|
|
572
653
|
dotai toggle no-useeffect --on
|
|
573
654
|
```
|
|
574
655
|
|
|
575
|
-
|
|
656
|
+
Synced agent files contain a compact bootstrap by default: universal rule summaries plus preference, role, and skill catalogs. Use `dotai context` to expand relevant material on demand, or pass `dotai sync --full` for the legacy complete inline context.
|
|
576
657
|
|
|
577
658
|
## Agent Sync
|
|
578
659
|
|
|
579
|
-
`dotai sync`
|
|
660
|
+
`dotai sync` prepares tool-specific context with:
|
|
580
661
|
|
|
581
|
-
- **
|
|
582
|
-
- **
|
|
583
|
-
- **Role and skill catalogs** (names, triggers,
|
|
662
|
+
- **Universal structured rule summaries** (always visible)
|
|
663
|
+
- **Pointers to freeform `rules.md` conventions**
|
|
664
|
+
- **Role and skill catalogs** (names, triggers, categories — not full workflows)
|
|
584
665
|
- **Claude Code**: compact pointers + native `.claude/skills/` slash commands
|
|
585
666
|
|
|
586
667
|
Use `--full` only when you need every role persona and skill definition dumped inline (larger context).
|
|
587
668
|
|
|
588
|
-
|
|
669
|
+
In a Git repository, local mode is the default and writes outside the worktree. Team instructions take precedence over personal dotai rules and preferences. dotai does not attempt unreliable keyword-based conflict resolution; the generated context tells the agent to ignore conflicting personal guidance and ask when a disagreement is ambiguous.
|
|
589
670
|
|
|
590
671
|
```bash
|
|
591
|
-
#
|
|
672
|
+
# Safe default in Git: generate outside the repository
|
|
592
673
|
dotai sync
|
|
593
674
|
|
|
675
|
+
# Preview the resolved mode and target without writing
|
|
676
|
+
dotai sync --check
|
|
677
|
+
|
|
678
|
+
# Explicit team-owned mode: update marked sections in repository files
|
|
679
|
+
dotai sync --shared
|
|
680
|
+
|
|
594
681
|
# Generate for specific agents
|
|
595
682
|
dotai sync --agents claude,cursor
|
|
596
683
|
dotai sync --agents gemini
|
|
@@ -600,18 +687,22 @@ dotai sync --full
|
|
|
600
687
|
|
|
601
688
|
# Print primer to stdout (for piping)
|
|
602
689
|
dotai primer
|
|
603
|
-
dotai primer --
|
|
690
|
+
dotai primer --path .
|
|
604
691
|
dotai primer --full
|
|
692
|
+
|
|
693
|
+
# Resolve task-specific context on demand
|
|
694
|
+
dotai context --path . --files src/app.tsx --context security
|
|
695
|
+
dotai context --path . --skill run_review
|
|
605
696
|
```
|
|
606
697
|
|
|
607
698
|
### Supported Agents
|
|
608
699
|
|
|
609
700
|
| Agent | Output File | Sync Command | Notes |
|
|
610
701
|
|-------|-------------|--------------|-------|
|
|
611
|
-
| Claude Code | `CLAUDE.md` + `.claude/skills/` | `dotai sync --agents claude` |
|
|
612
|
-
| Cursor | `.cursorrules` | `dotai sync --agents cursor` |
|
|
613
|
-
| Gemini CLI | `GEMINI.md` | `dotai sync --agents gemini` |
|
|
614
|
-
| Generic | `AGENTS.md` | `dotai sync --agents generic` |
|
|
702
|
+
| Claude Code | Local cache; shared: `CLAUDE.md` + `.claude/skills/` | `dotai sync --agents claude` | Team file is authoritative; shared mode uses marker-based merging |
|
|
703
|
+
| Cursor | `.cursorrules` | `dotai sync --agents cursor` | Compact bootstrap by default; full context with `--full` |
|
|
704
|
+
| Gemini CLI | `GEMINI.md` | `dotai sync --agents gemini` | Compact bootstrap; shared files are auto-discovered by Gemini CLI |
|
|
705
|
+
| Generic | `AGENTS.md` | `dotai sync --agents generic` | Compact bootstrap for agents that read `AGENTS.md` |
|
|
615
706
|
|
|
616
707
|
For Claude Code, `dotai sync` also generates `.claude/skills/<trigger>/SKILL.md` files. These register as native slash commands — they appear in autocomplete and work as real `/run_*` commands with role composition support built in.
|
|
617
708
|
|
|
@@ -739,8 +830,11 @@ dotai roles # List available roles
|
|
|
739
830
|
dotai role <name> # Output a role's full prompt to stdout
|
|
740
831
|
dotai skills [-c category] # List skills (optionally filter by category)
|
|
741
832
|
dotai prompt <skill> [--role <role>] # Assemble skill + role prompt for any agent
|
|
742
|
-
dotai sync [path] [--agents ...] [--full]
|
|
743
|
-
dotai
|
|
833
|
+
dotai sync [path] [--local|--shared] [--check] [--agents ...] [--full]
|
|
834
|
+
dotai detach [path] [--apply] # One-off removal of old shared-sync artifacts
|
|
835
|
+
dotai agent setup|status|last|remove claude [--apply] # User-level Claude delivery
|
|
836
|
+
dotai primer [--project <name>|--path <path>] [--full]
|
|
837
|
+
dotai context --path <path> [--task ...] [--files ...] [--context ...] [--domain ...] [--skill ...]
|
|
744
838
|
dotai rules [-p project] [-a] [--check] # List rules (or audit quality)
|
|
745
839
|
dotai audit [-p project] [--json] [--fail-on severity] # Read-only rule audit
|
|
746
840
|
dotai compress [-p project] [--json] # Plan compression candidates
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"""User-level agent adapters for automatic dotai context delivery."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import shutil
|
|
6
|
+
import shlex
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
from datetime import datetime, timezone
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Literal
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
ADAPTER_MARKER_START = "<!-- dotai:agent:claude:start -->"
|
|
14
|
+
ADAPTER_MARKER_END = "<!-- dotai:agent:claude:end -->"
|
|
15
|
+
|
|
16
|
+
CLAUDE_BOOTSTRAP = """# dotai Personal Context
|
|
17
|
+
|
|
18
|
+
Repository and organization instructions are authoritative. dotai is personal,
|
|
19
|
+
supplemental guidance and must never override team instructions.
|
|
20
|
+
|
|
21
|
+
For substantial coding, debugging, review, planning, verification, or release
|
|
22
|
+
work, run this before acting:
|
|
23
|
+
|
|
24
|
+
`{command} context --agent claude --path . --task "<concise task>" --files "<comma-separated affected files>"`
|
|
25
|
+
|
|
26
|
+
If affected files are not known yet, omit `--files` only for an initial,
|
|
27
|
+
provisional resolution. Discover the relevant files, then you MUST run dotai again
|
|
28
|
+
with `--files` before substantive review, editing, or implementation. The second
|
|
29
|
+
resolution replaces the provisional one and loads file-scoped rules. Do not call
|
|
30
|
+
dotai for casual conversation, simple factual questions, or repeatedly after a
|
|
31
|
+
complete file-aware resolution unless the task or affected files materially change.
|
|
32
|
+
|
|
33
|
+
When the user explicitly invokes a dotai workflow such as `/run_review`, load it
|
|
34
|
+
with `{command} context --agent claude --path . --skill run_review`. Treat dotai preferences as soft
|
|
35
|
+
taste only; team rules, security constraints, and user instructions take precedence.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@dataclass(frozen=True)
|
|
40
|
+
class AgentAdapterPlan:
|
|
41
|
+
"""A previewable user-memory change for one supported agent."""
|
|
42
|
+
|
|
43
|
+
agent: Literal["claude"]
|
|
44
|
+
path: Path
|
|
45
|
+
action: Literal["create", "update", "remove", "none"]
|
|
46
|
+
content: str | None
|
|
47
|
+
detail: str
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def claude_memory_path(home: Path | None = None) -> Path:
|
|
51
|
+
return (home or Path.home()) / ".claude" / "CLAUDE.md"
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _managed_block(command: str) -> str:
|
|
55
|
+
rendered = CLAUDE_BOOTSTRAP.format(command=shlex.quote(command))
|
|
56
|
+
return (
|
|
57
|
+
f"{ADAPTER_MARKER_START}\n"
|
|
58
|
+
f"{rendered.strip()}\n"
|
|
59
|
+
f"{ADAPTER_MARKER_END}"
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _remove_adapter_block(content: str) -> tuple[str, bool]:
|
|
64
|
+
if ADAPTER_MARKER_START not in content or ADAPTER_MARKER_END not in content:
|
|
65
|
+
return content, False
|
|
66
|
+
before, _, rest = content.partition(ADAPTER_MARKER_START)
|
|
67
|
+
_, _, after = rest.partition(ADAPTER_MARKER_END)
|
|
68
|
+
cleaned = "\n\n".join(
|
|
69
|
+
part for part in (before.rstrip(), after.lstrip().rstrip()) if part
|
|
70
|
+
)
|
|
71
|
+
return (cleaned + "\n" if cleaned else ""), True
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def plan_claude_setup(
|
|
75
|
+
path: Path | None = None, command: str = "dotai"
|
|
76
|
+
) -> AgentAdapterPlan:
|
|
77
|
+
"""Plan marker-managed installation without touching Claude user memory."""
|
|
78
|
+
path = path or claude_memory_path()
|
|
79
|
+
block = _managed_block(command)
|
|
80
|
+
if not path.exists():
|
|
81
|
+
return AgentAdapterPlan(
|
|
82
|
+
"claude", path, "create", block + "\n",
|
|
83
|
+
"create user-level Claude memory",
|
|
84
|
+
)
|
|
85
|
+
if path.is_symlink():
|
|
86
|
+
raise ValueError(f"Refusing to modify symlinked Claude memory: {path}")
|
|
87
|
+
|
|
88
|
+
existing = path.read_text()
|
|
89
|
+
if (ADAPTER_MARKER_START in existing) != (ADAPTER_MARKER_END in existing):
|
|
90
|
+
raise ValueError(f"Claude memory contains incomplete dotai markers: {path}")
|
|
91
|
+
cleaned, found = _remove_adapter_block(existing)
|
|
92
|
+
content = (
|
|
93
|
+
f"{cleaned.rstrip()}\n\n{block}\n" if cleaned.strip() else block + "\n"
|
|
94
|
+
)
|
|
95
|
+
if found and content == existing:
|
|
96
|
+
return AgentAdapterPlan("claude", path, "none", None, "already configured")
|
|
97
|
+
detail = "refresh dotai block" if found else "append dotai block; preserve existing memory"
|
|
98
|
+
return AgentAdapterPlan("claude", path, "update", content, detail)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def plan_claude_remove(path: Path | None = None) -> AgentAdapterPlan:
|
|
102
|
+
"""Plan removal of only dotai's Claude user-memory block."""
|
|
103
|
+
path = path or claude_memory_path()
|
|
104
|
+
if not path.exists():
|
|
105
|
+
return AgentAdapterPlan("claude", path, "none", None, "memory file does not exist")
|
|
106
|
+
if path.is_symlink():
|
|
107
|
+
raise ValueError(f"Refusing to modify symlinked Claude memory: {path}")
|
|
108
|
+
existing = path.read_text()
|
|
109
|
+
if (ADAPTER_MARKER_START in existing) != (ADAPTER_MARKER_END in existing):
|
|
110
|
+
raise ValueError(f"Claude memory contains incomplete dotai markers: {path}")
|
|
111
|
+
cleaned, found = _remove_adapter_block(existing)
|
|
112
|
+
if not found:
|
|
113
|
+
return AgentAdapterPlan("claude", path, "none", None, "dotai block not installed")
|
|
114
|
+
return AgentAdapterPlan(
|
|
115
|
+
"claude", path, "update" if cleaned else "remove",
|
|
116
|
+
cleaned or None, "remove only dotai's managed block",
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def claude_adapter_status(path: Path | None = None) -> tuple[str, str]:
|
|
121
|
+
"""Return a stable status code and human-readable detail."""
|
|
122
|
+
path = path or claude_memory_path()
|
|
123
|
+
if not path.exists():
|
|
124
|
+
return "not-configured", "Claude user memory does not exist"
|
|
125
|
+
if path.is_symlink():
|
|
126
|
+
return "unsafe", "Claude user memory is a symlink"
|
|
127
|
+
content = path.read_text()
|
|
128
|
+
has_start = ADAPTER_MARKER_START in content
|
|
129
|
+
has_end = ADAPTER_MARKER_END in content
|
|
130
|
+
if has_start and has_end:
|
|
131
|
+
return "configured", "dotai adapter block is installed"
|
|
132
|
+
if has_start or has_end:
|
|
133
|
+
return "invalid", "dotai adapter markers are incomplete"
|
|
134
|
+
return "not-configured", "Claude user memory exists without a dotai block"
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def apply_agent_plan(plan: AgentAdapterPlan, backup_root: Path) -> Path | None:
|
|
138
|
+
"""Back up existing memory, then apply a reviewed adapter plan."""
|
|
139
|
+
if plan.action == "none":
|
|
140
|
+
return None
|
|
141
|
+
if plan.path.is_symlink():
|
|
142
|
+
raise ValueError(f"Refusing to modify symlinked Claude memory: {plan.path}")
|
|
143
|
+
|
|
144
|
+
backup_path: Path | None = None
|
|
145
|
+
if plan.path.exists():
|
|
146
|
+
timestamp = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%S%fZ")
|
|
147
|
+
backup_root.mkdir(parents=True, exist_ok=True)
|
|
148
|
+
backup_path = backup_root / f"CLAUDE-{timestamp}.md"
|
|
149
|
+
shutil.copy2(plan.path, backup_path)
|
|
150
|
+
|
|
151
|
+
plan.path.parent.mkdir(parents=True, exist_ok=True)
|
|
152
|
+
if plan.action == "remove":
|
|
153
|
+
plan.path.unlink()
|
|
154
|
+
else:
|
|
155
|
+
plan.path.write_text(plan.content or "")
|
|
156
|
+
return backup_path
|
|
@@ -38,7 +38,7 @@ def init(
|
|
|
38
38
|
|
|
39
39
|
Use --force to re-seed after upgrading dotai (overwrites seed files, keeps your custom files).
|
|
40
40
|
"""
|
|
41
|
-
from ..store import load_config, save_config
|
|
41
|
+
from ..store import get_config_dir, load_config, save_config
|
|
42
42
|
from ..models import ProjectConfig
|
|
43
43
|
|
|
44
44
|
if project:
|
|
@@ -72,9 +72,13 @@ def init(
|
|
|
72
72
|
console.print(f"[green]Initialized .ai/ in {project_path}[/green]")
|
|
73
73
|
console.print(f" Created: rules.md, roles/, skills/, preferences/, tools/")
|
|
74
74
|
|
|
75
|
-
#
|
|
76
|
-
from ..sync import sync_project
|
|
77
|
-
|
|
75
|
+
# Prepare context without silently taking ownership of team agent files.
|
|
76
|
+
from ..sync import plan_sync, sync_local_context, sync_project
|
|
77
|
+
plan = plan_sync(project_path, get_config_dir())
|
|
78
|
+
if plan.mode == "local":
|
|
79
|
+
written = sync_local_context(plan, config, project_path.name)
|
|
80
|
+
else:
|
|
81
|
+
written = sync_project(project_path, config, project_path.name)
|
|
78
82
|
for f in written:
|
|
79
83
|
console.print(f" [green]Synced[/green] {f}")
|
|
80
84
|
else:
|
|
@@ -153,3 +157,4 @@ from . import rules_cmd # noqa: E402, F401
|
|
|
153
157
|
from . import prefs_cmd # noqa: E402, F401
|
|
154
158
|
from . import sync_cmd # noqa: E402, F401
|
|
155
159
|
from . import watch_cmd # noqa: E402, F401
|
|
160
|
+
from . import agents_cmd # noqa: E402, F401
|