tunestra 0.0.0 → 0.1.0
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.
- package/README.md +217 -11
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +1881 -0
- package/dist/index.d.mts +3 -0
- package/dist/index.mjs +1 -0
- package/dist/src-DSbrKtiC.mjs +5 -0
- package/package.json +40 -5
- package/bin/tunestra.js +0 -5
package/README.md
CHANGED
|
@@ -1,21 +1,227 @@
|
|
|
1
1
|
# tunestra
|
|
2
2
|
|
|
3
|
+
[](https://github.com/sensetive5/tunestra/actions/workflows/ci.yml)
|
|
4
|
+
[](https://codecov.io/gh/sensetive5/tunestra)
|
|
5
|
+
[](https://www.npmjs.com/package/tunestra)
|
|
6
|
+
[](package.json)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
|
|
3
9
|
> Tune your AI agents to play as one orchestra.
|
|
4
10
|
|
|
5
|
-
|
|
11
|
+
> [!WARNING]
|
|
12
|
+
> **Early version.** v0.1 supports Claude Code; Codex comes in v0.2. The formats may still
|
|
13
|
+
> change before v1.0.
|
|
14
|
+
|
|
15
|
+
tunestra gives Claude Code, Codex and other AI coding agents **one shared source** of rules,
|
|
16
|
+
skills, commands and MCP servers, and generates each agent's native configuration from it.
|
|
17
|
+
|
|
18
|
+
The source is a chain of **presets**, from general to specific:
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
base — your organization: security, general principles, shared tools
|
|
22
|
+
↓ extends
|
|
23
|
+
team — your team: conventions, stack, team skills
|
|
24
|
+
↓ extends
|
|
25
|
+
project — this repository: architecture, domain model, project skills
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
More specific levels **override** general ones by artifact key or **exclude** them.
|
|
29
|
+
Agents receive the result from specific to general: when two instructions conflict, the more
|
|
30
|
+
specific one wins.
|
|
31
|
+
|
|
32
|
+
## Quick start
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
npx tunestra init --extends github:<organisation_name>/<presets_repo>/team#v1
|
|
36
|
+
npx tunestra setup # generates AGENTS.md, CLAUDE.md, .claude/, .agents/, .mcp.json
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
`init` creates `tunestra.yaml`:
|
|
40
|
+
|
|
41
|
+
```yaml
|
|
42
|
+
extends:
|
|
43
|
+
- github:<organisation_name>/<presets_repo>/team#v1
|
|
44
|
+
agents: [claude]
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Commit `tunestra.yaml`, `.tunestra/`, `AGENTS.md` and `CLAUDE.md`. Everything else that
|
|
48
|
+
tunestra generates is listed in `.gitignore` automatically.
|
|
49
|
+
|
|
50
|
+
## Principles
|
|
51
|
+
|
|
52
|
+
1. **Sources are the only truth.** Presets and `.tunestra/` are edited by people.
|
|
53
|
+
Everything tunestra writes for agents is generated.
|
|
54
|
+
2. **Generated files are never edited by hand.** Every `tunestra setup` rebuilds them from
|
|
55
|
+
scratch. A manual edit is overwritten with a warning that tells you which source to change.
|
|
56
|
+
3. **Open standards first.** Rules follow [`AGENTS.md`](https://agents.md), skills follow
|
|
57
|
+
[Agent Skills](https://agentskills.io) (`SKILL.md`), MCP servers use the `.mcp.json` shape.
|
|
58
|
+
|
|
59
|
+
## Presets
|
|
60
|
+
|
|
61
|
+
A preset is a directory with a fixed layout. Artifacts are collected from the folders;
|
|
62
|
+
the manifest only holds metadata and overrides.
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
<preset>/
|
|
66
|
+
tunestra.preset.yaml # manifest
|
|
67
|
+
AGENTS.md # optional: main instructions of this level
|
|
68
|
+
rules/<key>.md # rules, one topic per file
|
|
69
|
+
skills/<key>/SKILL.md # skills (Agent Skills format)
|
|
70
|
+
commands/<key>.md # slash commands
|
|
71
|
+
mcp/<key>.yaml # MCP servers
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Manifest: `tunestra.preset.yaml`
|
|
75
|
+
|
|
76
|
+
```yaml
|
|
77
|
+
name: team # required, unique in the chain
|
|
78
|
+
level: team # required: base | domain | team
|
|
79
|
+
description: Frontend team conventions
|
|
80
|
+
extends: # optional, from general to specific
|
|
81
|
+
- ../base
|
|
82
|
+
exclude: # optional: drop inherited artifacts by key
|
|
83
|
+
skills: [code-review]
|
|
84
|
+
overrides: # optional: patch inherited MCP servers
|
|
85
|
+
mcp:
|
|
86
|
+
tracker:
|
|
87
|
+
env:
|
|
88
|
+
QUEUE: TEAM
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Project: `tunestra.yaml`
|
|
92
|
+
|
|
93
|
+
The project is the most specific level. Its artifacts live in `.tunestra/` with the same layout
|
|
94
|
+
as a preset.
|
|
95
|
+
|
|
96
|
+
```yaml
|
|
97
|
+
name: my-service # optional, defaults to the directory name
|
|
98
|
+
extends:
|
|
99
|
+
- ../presets/team
|
|
100
|
+
agents: [claude] # v0.1 supports claude
|
|
101
|
+
exclude: {}
|
|
102
|
+
overrides: {}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Sources
|
|
106
|
+
|
|
107
|
+
| Reference | Example |
|
|
108
|
+
|---|---|
|
|
109
|
+
| Relative path | `../presets/team` (relative to the file that references it) |
|
|
110
|
+
| GitHub | `github:<owner>/<repo>/<path>#<ref>` |
|
|
111
|
+
| GitLab | `gitlab:<owner>/<repo>/<path>#<ref>` |
|
|
112
|
+
|
|
113
|
+
Pin git sources to a tag or commit. tunestra downloads the whole repository at that ref
|
|
114
|
+
into `.tunestra/state/sources/` on every setup, so a preset can extend other presets of its
|
|
115
|
+
repository with a relative path, like `../base`. A relative path cannot leave the repository.
|
|
116
|
+
Git is not needed: repositories are downloaded as archives over HTTPS.
|
|
117
|
+
|
|
118
|
+
For a private repository, set the `TUNESTRA_GIT_TOKEN` environment variable to a token with
|
|
119
|
+
read access. Lockfiles and npm sources are planned for v0.3.
|
|
120
|
+
|
|
121
|
+
## Inheritance
|
|
122
|
+
|
|
123
|
+
The chain is linearized from general to specific: every preset comes after the presets it
|
|
124
|
+
extends. Each level is applied on top of the accumulated result.
|
|
125
|
+
|
|
126
|
+
A level can extend a more general level or a level of the same kind: a `team` preset can
|
|
127
|
+
build on another `team` preset. When two presets extend the same preset, it joins the
|
|
128
|
+
chain once, before both of them.
|
|
129
|
+
|
|
130
|
+
### Artifact keys
|
|
131
|
+
|
|
132
|
+
| Artifact | Key | Same key on a more specific level | Remove |
|
|
133
|
+
|---|---|---|---|
|
|
134
|
+
| Rule | file name without `.md` | replaces it | `exclude.rules` |
|
|
135
|
+
| Level instructions (`AGENTS.md`) | `instructions@<preset name>` | never collides: every level keeps its own | `exclude.rules` |
|
|
136
|
+
| Skill | `name` from `SKILL.md`, otherwise the folder name | replaces it | `exclude.skills` |
|
|
137
|
+
| Command | file name without `.md` | replaces it | `exclude.commands` |
|
|
138
|
+
| MCP server | file name without `.yaml` | replaces it | `exclude.mcp` |
|
|
139
|
+
|
|
140
|
+
`overrides.mcp.<key>` patches an inherited server instead of replacing it: `env` and `headers`
|
|
141
|
+
are merged by key (the specific value wins); `command`, `args` and `url` are replaced.
|
|
142
|
+
|
|
143
|
+
### Validation
|
|
144
|
+
|
|
145
|
+
`tunestra setup` stops with an error when:
|
|
146
|
+
|
|
147
|
+
- a preset extends a more specific level (for example, `base` extends `team`);
|
|
148
|
+
- `extends` contains a cycle;
|
|
149
|
+
- two levels have the same name;
|
|
150
|
+
- a manifest has an unknown field or a missing required field;
|
|
151
|
+
- `exclude` or `overrides` refers to a key that is not inherited;
|
|
152
|
+
- after a patch, an MCP server has both `command` and `url`, or neither.
|
|
153
|
+
|
|
154
|
+
All problems are reported at once, in the order of the files, so you can fix them in one pass.
|
|
155
|
+
|
|
156
|
+
## What gets generated (Claude Code)
|
|
157
|
+
|
|
158
|
+
| Path | Content | Committed |
|
|
159
|
+
|---|---|---|
|
|
160
|
+
| `AGENTS.md` | Index: hierarchy, rules, skills, commands, MCP servers | yes |
|
|
161
|
+
| `CLAUDE.md` | `@AGENTS.md` | yes |
|
|
162
|
+
| `.agents/rules/<NN>-<level>-<key>.md` | Rule texts, ordered from specific to general | no |
|
|
163
|
+
| `.agents/skills/<key>/` | Skills | no |
|
|
164
|
+
| `.claude/rules/tunestra/<NN>-<level>-<key>.md` | Copies of the rules; Claude Code loads them in every session | no |
|
|
165
|
+
| `.claude/skills/<key>` | Symlinks to `.agents/skills/<key>` | no |
|
|
166
|
+
| `.claude/commands/<key>.md` | Commands | no |
|
|
167
|
+
| `.mcp.json` | MCP servers | no |
|
|
168
|
+
| `.tunestra/state/` | What tunestra generated last time | no |
|
|
169
|
+
| `.gitignore` | A block between `# >>> tunestra` and `# <<< tunestra` | yes |
|
|
170
|
+
|
|
171
|
+
`<NN>` orders rules from specific to general: `10` project, `20` team, `30` domain, `40` base.
|
|
172
|
+
Level instructions get the key `instructions`, and the preset name when it differs from the
|
|
173
|
+
level: `20-team-instructions.md`, but `20-team-instructions-frontend.md` for a `team` preset
|
|
174
|
+
named `frontend`.
|
|
175
|
+
|
|
176
|
+
Every generated rule starts with its origin:
|
|
177
|
+
|
|
178
|
+
```md
|
|
179
|
+
<!-- Generated by tunestra from team:rules/code-style.md. Do not edit. -->
|
|
180
|
+
> Level: team, preset: team. Overrides: base.
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Skills and commands are copied as is: their frontmatter must stay on the first line.
|
|
184
|
+
|
|
185
|
+
## Running setup again
|
|
186
|
+
|
|
187
|
+
tunestra keeps a list of what it wrote in `.tunestra/state/outputs.json` and compares every
|
|
188
|
+
run with it:
|
|
189
|
+
|
|
190
|
+
| Situation | What setup does |
|
|
191
|
+
|---|---|
|
|
192
|
+
| A generated file is still needed | Writes it again |
|
|
193
|
+
| A generated file was edited by hand | Writes it again and warns which source file to edit instead |
|
|
194
|
+
| A file is no longer generated (for example, a rule was deleted from a preset) | Removes it and the folders it leaves empty; warns if the file was edited by hand |
|
|
195
|
+
| A file is in the way, and tunestra did not create it | Stops and asks you to move it away |
|
|
196
|
+
| `.tunestra/state/` was deleted | Accepts its own files by their header or content and goes on |
|
|
197
|
+
|
|
198
|
+
Generated files are never kept because of manual edits: change the sources instead.
|
|
199
|
+
|
|
200
|
+
## Commands
|
|
201
|
+
|
|
202
|
+
| Command | What it does |
|
|
203
|
+
|---|---|
|
|
204
|
+
| `tunestra init` | Creates `tunestra.yaml`; `--extends <presets...>` fills `extends`. Moves a hand-written `AGENTS.md` to `.tunestra/AGENTS.md` and a `CLAUDE.md` with its own text to `.tunestra/rules/claude-md.md`; a `CLAUDE.md` that only imports `AGENTS.md` is removed |
|
|
205
|
+
| `tunestra setup` | Resolves the chain and regenerates every output |
|
|
206
|
+
| `tunestra setup --dry-run` | Prints what would be written or removed, and the warnings |
|
|
207
|
+
| `tunestra setup --verbose` | Also prints where every artifact comes from and what it overrides |
|
|
208
|
+
| `tunestra uninstall` | Removes everything tunestra generated and its block in `.gitignore`; `tunestra.yaml` and `.tunestra/` stay. `--dry-run` shows the list first |
|
|
6
209
|
|
|
7
|
-
tunestra
|
|
8
|
-
|
|
9
|
-
configuration from it.
|
|
210
|
+
`tunestra setup` refuses to overwrite an `AGENTS.md` or `CLAUDE.md` that it did not generate
|
|
211
|
+
and tells you where to move their text.
|
|
10
212
|
|
|
11
|
-
|
|
213
|
+
## Roadmap
|
|
12
214
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
215
|
+
| Release | Scope |
|
|
216
|
+
|---|---|
|
|
217
|
+
| v0.1 | Inheritance for Claude Code (this document) |
|
|
218
|
+
| v0.2 | Codex |
|
|
219
|
+
| v0.3 | Spaces, npm sources, lockfile |
|
|
220
|
+
| v0.4 | `required` / `locked` policies, CI check |
|
|
221
|
+
| v0.5 | Hooks |
|
|
222
|
+
| v0.6 | LLM gateway, permissions |
|
|
223
|
+
| v0.7 | Local plugins |
|
|
224
|
+
| v0.8 | Isolated remote plugins |
|
|
19
225
|
|
|
20
226
|
## License
|
|
21
227
|
|
package/dist/cli.d.mts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|