tunestra 0.0.0-stage → 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Aleksandr Sokolov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,228 @@
1
- # Temporary Holding Version
1
+ # tunestra
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ [![CI](https://github.com/sensetive5/tunestra/actions/workflows/ci.yml/badge.svg)](https://github.com/sensetive5/tunestra/actions/workflows/ci.yml)
4
+ [![Coverage](https://codecov.io/gh/sensetive5/tunestra/graph/badge.svg)](https://codecov.io/gh/sensetive5/tunestra)
5
+ [![npm](https://img.shields.io/npm/v/tunestra)](https://www.npmjs.com/package/tunestra)
6
+ [![Node](https://img.shields.io/node/v/tunestra)](package.json)
7
+ [![License: MIT](https://img.shields.io/github/license/sensetive5/tunestra)](LICENSE)
8
+
9
+ > Tune your AI agents to play as one orchestra.
10
+
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 |
209
+
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.
212
+
213
+ ## Roadmap
214
+
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 |
225
+
226
+ ## License
227
+
228
+ [MIT](LICENSE)
package/dist/cli.d.mts ADDED
@@ -0,0 +1 @@
1
+ export {}