skillsinc 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.
- skillsinc-0.1.0/LICENSE +21 -0
- skillsinc-0.1.0/PKG-INFO +150 -0
- skillsinc-0.1.0/README.md +124 -0
- skillsinc-0.1.0/pyproject.toml +232 -0
- skillsinc-0.1.0/pyproject.toml.orig +140 -0
- skillsinc-0.1.0/src/skillsinc/__init__.py +3 -0
- skillsinc-0.1.0/src/skillsinc/__main__.py +80 -0
- skillsinc-0.1.0/src/skillsinc/applier.py +207 -0
- skillsinc-0.1.0/src/skillsinc/blocks.py +87 -0
- skillsinc-0.1.0/src/skillsinc/cli.py +118 -0
- skillsinc-0.1.0/src/skillsinc/commands.py +90 -0
- skillsinc-0.1.0/src/skillsinc/config.py +342 -0
- skillsinc-0.1.0/src/skillsinc/diff.py +359 -0
- skillsinc-0.1.0/src/skillsinc/entries.py +490 -0
- skillsinc-0.1.0/src/skillsinc/exceptions.py +27 -0
- skillsinc-0.1.0/src/skillsinc/frontmatter.py +87 -0
- skillsinc-0.1.0/src/skillsinc/jsonc.py +313 -0
- skillsinc-0.1.0/src/skillsinc/lock.py +60 -0
- skillsinc-0.1.0/src/skillsinc/manifest.py +135 -0
- skillsinc-0.1.0/src/skillsinc/models.py +172 -0
- skillsinc-0.1.0/src/skillsinc/paths.py +84 -0
- skillsinc-0.1.0/src/skillsinc/plan.py +116 -0
- skillsinc-0.1.0/src/skillsinc/planner.py +492 -0
- skillsinc-0.1.0/src/skillsinc/profiles/__init__.py +3 -0
- skillsinc-0.1.0/src/skillsinc/profiles/base.py +249 -0
- skillsinc-0.1.0/src/skillsinc/profiles/claude.py +166 -0
- skillsinc-0.1.0/src/skillsinc/profiles/codex.py +263 -0
- skillsinc-0.1.0/src/skillsinc/profiles/copilot.py +146 -0
- skillsinc-0.1.0/src/skillsinc/profiles/hooks.py +155 -0
- skillsinc-0.1.0/src/skillsinc/profiles/registry.py +43 -0
- skillsinc-0.1.0/src/skillsinc/profiles/shared.py +59 -0
- skillsinc-0.1.0/src/skillsinc/py.typed +0 -0
- skillsinc-0.1.0/src/skillsinc/report.py +245 -0
- skillsinc-0.1.0/src/skillsinc/settings.py +39 -0
- skillsinc-0.1.0/src/skillsinc/sources.py +481 -0
- skillsinc-0.1.0/src/skillsinc/starter.py +107 -0
skillsinc-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Mike Hill
|
|
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.
|
skillsinc-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: skillsinc
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Sync one library of agent skills, instructions, agents, and prompts into every AI coding harness you use.
|
|
5
|
+
Keywords: agents,skills,claude-code,codex,copilot,sync
|
|
6
|
+
Author: Mike Hill
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Environment :: Console
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
17
|
+
Classifier: Topic :: Software Development
|
|
18
|
+
Classifier: Typing :: Typed
|
|
19
|
+
Requires-Dist: pyyaml>=6.0.3
|
|
20
|
+
Requires-Dist: tomlkit>=0.13.3
|
|
21
|
+
Requires-Python: >=3.12
|
|
22
|
+
Project-URL: Homepage, https://github.com/mikejhill/skillsinc
|
|
23
|
+
Project-URL: Issues, https://github.com/mikejhill/skillsinc/issues
|
|
24
|
+
Project-URL: Changelog, https://github.com/mikejhill/skillsinc/blob/main/CHANGELOG.md
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
|
|
27
|
+
# SkillSinc
|
|
28
|
+
|
|
29
|
+
[](https://github.com/mikejhill/skillsinc/actions/workflows/ci.yml)
|
|
30
|
+
[](https://github.com/mikejhill/skillsinc/actions/workflows/release.yml)
|
|
31
|
+
[](LICENSE)
|
|
32
|
+
|
|
33
|
+
Write your agent skills, instructions, agents, prompts, MCP servers, reference files, and hooks once. SkillSinc copies them into Claude Code, GitHub Copilot, VS Code, Codex, and the shared `~/.agents` folder, converting formats where it must and saying so when a conversion loses something.
|
|
34
|
+
|
|
35
|
+
It replaces hand-copying, symlinks, and per-tool sync scripts with one command that shows you every change before it makes it.
|
|
36
|
+
|
|
37
|
+
## How it works
|
|
38
|
+
|
|
39
|
+
```mermaid
|
|
40
|
+
graph LR
|
|
41
|
+
Library[Your library<br/>skills/ instructions/ agents/ prompts/] --> Plan[skillsinc plan]
|
|
42
|
+
Plan --> Claude[~/.claude]
|
|
43
|
+
Plan --> Copilot[~/.copilot]
|
|
44
|
+
Plan --> VSCode[VS Code prompts]
|
|
45
|
+
Plan --> Codex[~/.codex/AGENTS.md]
|
|
46
|
+
Plan --> Agents[~/.agents/skills]
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
- **Your library is the source of truth.** A sync makes each destination match it: new items are added, changed items updated, removed items deleted.
|
|
50
|
+
- **SkillSinc only touches what it wrote.** It records every file it owns. An existing file it did not write blocks that destination until you review it and pass `--adopt`.
|
|
51
|
+
- **Nothing is written without a plan.** `skillsinc plan` lists every change; `skillsinc sync` applies the same plan.
|
|
52
|
+
- **Lossy conversions are opt-in.** If a harness cannot represent a field (for example, Claude ignores Copilot `tools` lists), the item is skipped until the route sets `allow_lossy = true`.
|
|
53
|
+
- **A broken source never deletes anything.** If a library cannot be read completely, its destinations are left untouched.
|
|
54
|
+
|
|
55
|
+
## Install
|
|
56
|
+
|
|
57
|
+
Requires Python 3.12+ and [uv](https://docs.astral.sh/uv/).
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
uv tool install git+https://github.com/mikejhill/skillsinc.git
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Quick start
|
|
64
|
+
|
|
65
|
+
1. Write a configuration. It enables a destination for every harness folder found on this machine and creates an empty library at `~/.config/skillsinc/library` (`$XDG_CONFIG_HOME/skillsinc/library`). Pass `--source DIR` to use an existing library instead:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
skillsinc init
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
2. Preview the changes:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
skillsinc plan
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
3. Apply them:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
skillsinc sync
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Run `skillsinc sync` again whenever the library changes, or schedule it with Task Scheduler, launchd, or a systemd timer using the [scheduling examples](docs/guides/scheduling.md). An overlapping run exits without writing.
|
|
84
|
+
|
|
85
|
+
## Library layout
|
|
86
|
+
|
|
87
|
+
The layout matches GitHub Copilot's file conventions, so an existing Copilot library works unchanged:
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
my-agent-library/
|
|
91
|
+
├── skills/<name>/SKILL.md # plus any supporting files
|
|
92
|
+
├── instructions/<name>.instructions.md
|
|
93
|
+
├── agents/<name>.agent.md
|
|
94
|
+
├── prompts/<name>.prompt.md
|
|
95
|
+
├── mcp/<name>.json # one MCP server definition per file
|
|
96
|
+
├── resources/<name>.md # reference files, copied as written
|
|
97
|
+
├── hooks/<name>.json # one Copilot CLI hook file per file
|
|
98
|
+
└── plugins/<plugin>/ # Claude Code plugin layout, expanded into the kinds above
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
`INTENT.md`, `*.intent.md`, and hidden files are never distributed. A plugin's `skills/`, `agents/`, `commands/`, and `.mcp.json` are synced as skills, agents, prompts, and MCP servers; everything else in it (hooks, scripts, LSP servers) is reported as a loss. See [decision 0005](docs/decisions/0005-plugins-expand-into-kinds.md).
|
|
102
|
+
|
|
103
|
+
## What each harness receives
|
|
104
|
+
|
|
105
|
+
| Profile | Skills | Instructions | Agents | Prompts | MCP servers | Resources | Hooks |
|
|
106
|
+
| --------- | --------- | ---------------------------- | -------------------- | -------------------- | ------------------------------ | ------------------------------------- | ----------------------- |
|
|
107
|
+
| `claude` | `skills/` | `rules/<name>.md` (`paths`) | `agents/<name>.md` | `commands/<name>.md` | `~/.claude.json` `mcpServers` | `resources/` + `CLAUDE.md` `@` import | `settings.json` `hooks` |
|
|
108
|
+
| `copilot` | `skills/` | `instructions/` | `agents/` | — | `mcp-config.json` `mcpServers` | `resources/` | `hooks/` |
|
|
109
|
+
| `vscode` | — | `<name>.instructions.md` | `<name>.agent.md` | `<name>.prompt.md` | `User/mcp.json` `servers` | — | — |
|
|
110
|
+
| `codex` | — | managed block in `AGENTS.md` | `agents/<name>.toml` | — | — | — | — |
|
|
111
|
+
| `agents` | `skills/` | — | — | — | — | — | — |
|
|
112
|
+
| `generic` | verbatim | verbatim | verbatim | verbatim | verbatim | verbatim | verbatim |
|
|
113
|
+
|
|
114
|
+
Run `skillsinc profiles` for the same table. See [harness profiles](docs/guides/harness-profiles.md) for exact conversions.
|
|
115
|
+
|
|
116
|
+
## Commands
|
|
117
|
+
|
|
118
|
+
| Command | Purpose |
|
|
119
|
+
| -------------------- | -------------------------------------------------- |
|
|
120
|
+
| `skillsinc init` | Write a starter configuration |
|
|
121
|
+
| `skillsinc plan` | Show every change a sync would make; write nothing |
|
|
122
|
+
| `skillsinc sync` | Apply the plan |
|
|
123
|
+
| `skillsinc profiles` | List harness profiles and what each kind becomes |
|
|
124
|
+
|
|
125
|
+
`plan` and `sync` accept `--destination NAME` (repeatable), `--adopt`, `--json`, `--verbose`, and `--config PATH`. Exit codes: `0` success, `1` a destination was blocked or failed, `2` configuration or usage error, `130` interrupted.
|
|
126
|
+
|
|
127
|
+
## Documentation
|
|
128
|
+
|
|
129
|
+
- [Configuration reference](docs/guides/configuration.md)
|
|
130
|
+
- [Command-line reference](docs/guides/command-line.md)
|
|
131
|
+
- [Scheduling](docs/guides/scheduling.md)
|
|
132
|
+
- [Development guide](docs/guides/development.md)
|
|
133
|
+
- [Roadmap](docs/planning/roadmap.md)
|
|
134
|
+
- [Harness profiles](docs/guides/harness-profiles.md)
|
|
135
|
+
- [Philosophy and goals](docs/architecture/philosophy.md)
|
|
136
|
+
- [Architecture](docs/architecture/overview.md)
|
|
137
|
+
- [Decision: rebuild scope](docs/decisions/0001-rebuild-scope.md)
|
|
138
|
+
- [Decision: MCP server entries](docs/decisions/0002-mcp-server-entries.md)
|
|
139
|
+
- [Decision: resources and Claude imports](docs/decisions/0003-resources-and-claude-imports.md)
|
|
140
|
+
- [Decision: TOML entries with tomlkit](docs/decisions/0004-toml-entries-with-tomlkit.md)
|
|
141
|
+
- [Decision: plugins expand into kinds](docs/decisions/0005-plugins-expand-into-kinds.md)
|
|
142
|
+
- [Decision: entry files beside a destination root](docs/decisions/0007-files-beside-the-root.md)
|
|
143
|
+
- [Decision: edit VS Code's JSONC mcp.json in place](docs/decisions/0008-jsonc-edits-in-place.md)
|
|
144
|
+
- [Decision: one copy of each item per harness](docs/decisions/0009-one-copy-per-harness.md)
|
|
145
|
+
- [Decision: MCP server options and per-profile overrides](docs/decisions/0010-mcp-server-options.md)
|
|
146
|
+
- [Contributing](CONTRIBUTING.md) · [Security](SECURITY.md) · [Changelog](CHANGELOG.md)
|
|
147
|
+
|
|
148
|
+
## License
|
|
149
|
+
|
|
150
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# SkillSinc
|
|
2
|
+
|
|
3
|
+
[](https://github.com/mikejhill/skillsinc/actions/workflows/ci.yml)
|
|
4
|
+
[](https://github.com/mikejhill/skillsinc/actions/workflows/release.yml)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
|
|
7
|
+
Write your agent skills, instructions, agents, prompts, MCP servers, reference files, and hooks once. SkillSinc copies them into Claude Code, GitHub Copilot, VS Code, Codex, and the shared `~/.agents` folder, converting formats where it must and saying so when a conversion loses something.
|
|
8
|
+
|
|
9
|
+
It replaces hand-copying, symlinks, and per-tool sync scripts with one command that shows you every change before it makes it.
|
|
10
|
+
|
|
11
|
+
## How it works
|
|
12
|
+
|
|
13
|
+
```mermaid
|
|
14
|
+
graph LR
|
|
15
|
+
Library[Your library<br/>skills/ instructions/ agents/ prompts/] --> Plan[skillsinc plan]
|
|
16
|
+
Plan --> Claude[~/.claude]
|
|
17
|
+
Plan --> Copilot[~/.copilot]
|
|
18
|
+
Plan --> VSCode[VS Code prompts]
|
|
19
|
+
Plan --> Codex[~/.codex/AGENTS.md]
|
|
20
|
+
Plan --> Agents[~/.agents/skills]
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
- **Your library is the source of truth.** A sync makes each destination match it: new items are added, changed items updated, removed items deleted.
|
|
24
|
+
- **SkillSinc only touches what it wrote.** It records every file it owns. An existing file it did not write blocks that destination until you review it and pass `--adopt`.
|
|
25
|
+
- **Nothing is written without a plan.** `skillsinc plan` lists every change; `skillsinc sync` applies the same plan.
|
|
26
|
+
- **Lossy conversions are opt-in.** If a harness cannot represent a field (for example, Claude ignores Copilot `tools` lists), the item is skipped until the route sets `allow_lossy = true`.
|
|
27
|
+
- **A broken source never deletes anything.** If a library cannot be read completely, its destinations are left untouched.
|
|
28
|
+
|
|
29
|
+
## Install
|
|
30
|
+
|
|
31
|
+
Requires Python 3.12+ and [uv](https://docs.astral.sh/uv/).
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
uv tool install git+https://github.com/mikejhill/skillsinc.git
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Quick start
|
|
38
|
+
|
|
39
|
+
1. Write a configuration. It enables a destination for every harness folder found on this machine and creates an empty library at `~/.config/skillsinc/library` (`$XDG_CONFIG_HOME/skillsinc/library`). Pass `--source DIR` to use an existing library instead:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
skillsinc init
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
2. Preview the changes:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
skillsinc plan
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
3. Apply them:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
skillsinc sync
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Run `skillsinc sync` again whenever the library changes, or schedule it with Task Scheduler, launchd, or a systemd timer using the [scheduling examples](docs/guides/scheduling.md). An overlapping run exits without writing.
|
|
58
|
+
|
|
59
|
+
## Library layout
|
|
60
|
+
|
|
61
|
+
The layout matches GitHub Copilot's file conventions, so an existing Copilot library works unchanged:
|
|
62
|
+
|
|
63
|
+
```text
|
|
64
|
+
my-agent-library/
|
|
65
|
+
├── skills/<name>/SKILL.md # plus any supporting files
|
|
66
|
+
├── instructions/<name>.instructions.md
|
|
67
|
+
├── agents/<name>.agent.md
|
|
68
|
+
├── prompts/<name>.prompt.md
|
|
69
|
+
├── mcp/<name>.json # one MCP server definition per file
|
|
70
|
+
├── resources/<name>.md # reference files, copied as written
|
|
71
|
+
├── hooks/<name>.json # one Copilot CLI hook file per file
|
|
72
|
+
└── plugins/<plugin>/ # Claude Code plugin layout, expanded into the kinds above
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
`INTENT.md`, `*.intent.md`, and hidden files are never distributed. A plugin's `skills/`, `agents/`, `commands/`, and `.mcp.json` are synced as skills, agents, prompts, and MCP servers; everything else in it (hooks, scripts, LSP servers) is reported as a loss. See [decision 0005](docs/decisions/0005-plugins-expand-into-kinds.md).
|
|
76
|
+
|
|
77
|
+
## What each harness receives
|
|
78
|
+
|
|
79
|
+
| Profile | Skills | Instructions | Agents | Prompts | MCP servers | Resources | Hooks |
|
|
80
|
+
| --------- | --------- | ---------------------------- | -------------------- | -------------------- | ------------------------------ | ------------------------------------- | ----------------------- |
|
|
81
|
+
| `claude` | `skills/` | `rules/<name>.md` (`paths`) | `agents/<name>.md` | `commands/<name>.md` | `~/.claude.json` `mcpServers` | `resources/` + `CLAUDE.md` `@` import | `settings.json` `hooks` |
|
|
82
|
+
| `copilot` | `skills/` | `instructions/` | `agents/` | — | `mcp-config.json` `mcpServers` | `resources/` | `hooks/` |
|
|
83
|
+
| `vscode` | — | `<name>.instructions.md` | `<name>.agent.md` | `<name>.prompt.md` | `User/mcp.json` `servers` | — | — |
|
|
84
|
+
| `codex` | — | managed block in `AGENTS.md` | `agents/<name>.toml` | — | — | — | — |
|
|
85
|
+
| `agents` | `skills/` | — | — | — | — | — | — |
|
|
86
|
+
| `generic` | verbatim | verbatim | verbatim | verbatim | verbatim | verbatim | verbatim |
|
|
87
|
+
|
|
88
|
+
Run `skillsinc profiles` for the same table. See [harness profiles](docs/guides/harness-profiles.md) for exact conversions.
|
|
89
|
+
|
|
90
|
+
## Commands
|
|
91
|
+
|
|
92
|
+
| Command | Purpose |
|
|
93
|
+
| -------------------- | -------------------------------------------------- |
|
|
94
|
+
| `skillsinc init` | Write a starter configuration |
|
|
95
|
+
| `skillsinc plan` | Show every change a sync would make; write nothing |
|
|
96
|
+
| `skillsinc sync` | Apply the plan |
|
|
97
|
+
| `skillsinc profiles` | List harness profiles and what each kind becomes |
|
|
98
|
+
|
|
99
|
+
`plan` and `sync` accept `--destination NAME` (repeatable), `--adopt`, `--json`, `--verbose`, and `--config PATH`. Exit codes: `0` success, `1` a destination was blocked or failed, `2` configuration or usage error, `130` interrupted.
|
|
100
|
+
|
|
101
|
+
## Documentation
|
|
102
|
+
|
|
103
|
+
- [Configuration reference](docs/guides/configuration.md)
|
|
104
|
+
- [Command-line reference](docs/guides/command-line.md)
|
|
105
|
+
- [Scheduling](docs/guides/scheduling.md)
|
|
106
|
+
- [Development guide](docs/guides/development.md)
|
|
107
|
+
- [Roadmap](docs/planning/roadmap.md)
|
|
108
|
+
- [Harness profiles](docs/guides/harness-profiles.md)
|
|
109
|
+
- [Philosophy and goals](docs/architecture/philosophy.md)
|
|
110
|
+
- [Architecture](docs/architecture/overview.md)
|
|
111
|
+
- [Decision: rebuild scope](docs/decisions/0001-rebuild-scope.md)
|
|
112
|
+
- [Decision: MCP server entries](docs/decisions/0002-mcp-server-entries.md)
|
|
113
|
+
- [Decision: resources and Claude imports](docs/decisions/0003-resources-and-claude-imports.md)
|
|
114
|
+
- [Decision: TOML entries with tomlkit](docs/decisions/0004-toml-entries-with-tomlkit.md)
|
|
115
|
+
- [Decision: plugins expand into kinds](docs/decisions/0005-plugins-expand-into-kinds.md)
|
|
116
|
+
- [Decision: entry files beside a destination root](docs/decisions/0007-files-beside-the-root.md)
|
|
117
|
+
- [Decision: edit VS Code's JSONC mcp.json in place](docs/decisions/0008-jsonc-edits-in-place.md)
|
|
118
|
+
- [Decision: one copy of each item per harness](docs/decisions/0009-one-copy-per-harness.md)
|
|
119
|
+
- [Decision: MCP server options and per-profile overrides](docs/decisions/0010-mcp-server-options.md)
|
|
120
|
+
- [Contributing](CONTRIBUTING.md) · [Security](SECURITY.md) · [Changelog](CHANGELOG.md)
|
|
121
|
+
|
|
122
|
+
## License
|
|
123
|
+
|
|
124
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "skillsinc"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Sync one library of agent skills, instructions, agents, and prompts into every AI coding harness you use."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
license-files = ["LICENSE"]
|
|
8
|
+
requires-python = ">=3.12"
|
|
9
|
+
keywords = [
|
|
10
|
+
"agents",
|
|
11
|
+
"skills",
|
|
12
|
+
"claude-code",
|
|
13
|
+
"codex",
|
|
14
|
+
"copilot",
|
|
15
|
+
"sync",
|
|
16
|
+
]
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Development Status :: 3 - Alpha",
|
|
19
|
+
"Environment :: Console",
|
|
20
|
+
"Intended Audience :: Developers",
|
|
21
|
+
"Operating System :: OS Independent",
|
|
22
|
+
"Programming Language :: Python :: 3",
|
|
23
|
+
"Programming Language :: Python :: 3.12",
|
|
24
|
+
"Programming Language :: Python :: 3.13",
|
|
25
|
+
"Programming Language :: Python :: 3.14",
|
|
26
|
+
"Topic :: Software Development",
|
|
27
|
+
"Typing :: Typed",
|
|
28
|
+
]
|
|
29
|
+
dependencies = [
|
|
30
|
+
"pyyaml>=6.0.3",
|
|
31
|
+
"tomlkit>=0.13.3",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
[[project.authors]]
|
|
35
|
+
name = "Mike Hill"
|
|
36
|
+
|
|
37
|
+
[project.urls]
|
|
38
|
+
Homepage = "https://github.com/mikejhill/skillsinc"
|
|
39
|
+
Issues = "https://github.com/mikejhill/skillsinc/issues"
|
|
40
|
+
Changelog = "https://github.com/mikejhill/skillsinc/blob/main/CHANGELOG.md"
|
|
41
|
+
|
|
42
|
+
[project.scripts]
|
|
43
|
+
skillsinc = "skillsinc.__main__:Application.main"
|
|
44
|
+
|
|
45
|
+
[build-system]
|
|
46
|
+
requires = ["uv_build>=0.11.32,<0.12.0"]
|
|
47
|
+
build-backend = "uv_build"
|
|
48
|
+
|
|
49
|
+
[dependency-groups]
|
|
50
|
+
dev = [
|
|
51
|
+
"hypothesis>=6.169.2",
|
|
52
|
+
"poethepoet>=0.48.0",
|
|
53
|
+
"pytest>=9.1.1",
|
|
54
|
+
"pytest-cov>=7.1.0",
|
|
55
|
+
"pytest-randomly>=5.0.0",
|
|
56
|
+
"ruff>=0.17.0",
|
|
57
|
+
"ty>=0.0.86",
|
|
58
|
+
"types-pyyaml>=6.0.12.20260906",
|
|
59
|
+
]
|
|
60
|
+
mutation = ["mutmut>=3.8.0"]
|
|
61
|
+
|
|
62
|
+
[tool.ruff]
|
|
63
|
+
target-version = "py312"
|
|
64
|
+
line-length = 88
|
|
65
|
+
src = [
|
|
66
|
+
"src",
|
|
67
|
+
"tests",
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
[tool.ruff.lint]
|
|
71
|
+
select = [
|
|
72
|
+
"A",
|
|
73
|
+
"ANN",
|
|
74
|
+
"ARG",
|
|
75
|
+
"B",
|
|
76
|
+
"BLE",
|
|
77
|
+
"C4",
|
|
78
|
+
"C90",
|
|
79
|
+
"D",
|
|
80
|
+
"DTZ",
|
|
81
|
+
"E",
|
|
82
|
+
"ERA",
|
|
83
|
+
"F",
|
|
84
|
+
"FA",
|
|
85
|
+
"FBT",
|
|
86
|
+
"G",
|
|
87
|
+
"I",
|
|
88
|
+
"LOG",
|
|
89
|
+
"N",
|
|
90
|
+
"PERF",
|
|
91
|
+
"PGH",
|
|
92
|
+
"PIE",
|
|
93
|
+
"PL",
|
|
94
|
+
"PT",
|
|
95
|
+
"PTH",
|
|
96
|
+
"RET",
|
|
97
|
+
"RSE",
|
|
98
|
+
"RUF",
|
|
99
|
+
"S",
|
|
100
|
+
"SIM",
|
|
101
|
+
"T20",
|
|
102
|
+
"TID",
|
|
103
|
+
"TRY",
|
|
104
|
+
"UP",
|
|
105
|
+
"W",
|
|
106
|
+
]
|
|
107
|
+
ignore = [
|
|
108
|
+
"D107",
|
|
109
|
+
"TRY003",
|
|
110
|
+
]
|
|
111
|
+
|
|
112
|
+
[tool.ruff.lint.per-file-ignores]
|
|
113
|
+
"tests/**" = [
|
|
114
|
+
"S101",
|
|
115
|
+
"PLR2004",
|
|
116
|
+
]
|
|
117
|
+
|
|
118
|
+
[tool.ruff.lint.pydocstyle]
|
|
119
|
+
convention = "google"
|
|
120
|
+
|
|
121
|
+
[tool.ruff.lint.flake8-tidy-imports]
|
|
122
|
+
ban-relative-imports = "all"
|
|
123
|
+
|
|
124
|
+
[tool.ruff.lint.mccabe]
|
|
125
|
+
max-complexity = 10
|
|
126
|
+
|
|
127
|
+
[tool.ruff.format]
|
|
128
|
+
docstring-code-format = true
|
|
129
|
+
|
|
130
|
+
[tool.ty.rules]
|
|
131
|
+
all = "error"
|
|
132
|
+
|
|
133
|
+
[tool.pytest.ini_options]
|
|
134
|
+
testpaths = ["tests"]
|
|
135
|
+
addopts = [
|
|
136
|
+
"--strict-markers",
|
|
137
|
+
"--strict-config",
|
|
138
|
+
"-ra",
|
|
139
|
+
"--import-mode=importlib",
|
|
140
|
+
"-m",
|
|
141
|
+
"not perf",
|
|
142
|
+
]
|
|
143
|
+
xfail_strict = true
|
|
144
|
+
markers = [
|
|
145
|
+
"unit: one module through its public API (the default layer)",
|
|
146
|
+
"integration: user journeys through Application.run in one process",
|
|
147
|
+
"e2e: the skillsinc process run against a throwaway home directory",
|
|
148
|
+
"perf: time budgets for planning and syncing large libraries",
|
|
149
|
+
]
|
|
150
|
+
|
|
151
|
+
[tool.coverage.run]
|
|
152
|
+
source = ["skillsinc"]
|
|
153
|
+
branch = true
|
|
154
|
+
|
|
155
|
+
[tool.coverage.report]
|
|
156
|
+
fail_under = 98
|
|
157
|
+
show_missing = true
|
|
158
|
+
skip_covered = true
|
|
159
|
+
exclude_also = [
|
|
160
|
+
"if __name__ == .__main__.:",
|
|
161
|
+
'assert_never\(',
|
|
162
|
+
]
|
|
163
|
+
|
|
164
|
+
[tool.poe.tasks.format]
|
|
165
|
+
cmd = "ruff format ."
|
|
166
|
+
help = "Format code"
|
|
167
|
+
|
|
168
|
+
[tool.poe.tasks.format-check]
|
|
169
|
+
cmd = "ruff format --check ."
|
|
170
|
+
help = "Check formatting"
|
|
171
|
+
|
|
172
|
+
[tool.poe.tasks.lint]
|
|
173
|
+
cmd = "ruff check ."
|
|
174
|
+
help = "Lint code"
|
|
175
|
+
|
|
176
|
+
[tool.poe.tasks.lint-fix]
|
|
177
|
+
cmd = "ruff check . --fix"
|
|
178
|
+
help = "Lint and auto-fix"
|
|
179
|
+
|
|
180
|
+
[tool.poe.tasks.typecheck]
|
|
181
|
+
cmd = "ty check"
|
|
182
|
+
help = "Type check (strict)"
|
|
183
|
+
|
|
184
|
+
[tool.poe.tasks.test]
|
|
185
|
+
cmd = "pytest --cov"
|
|
186
|
+
help = "Run unit, property, integration, and e2e tests with coverage"
|
|
187
|
+
|
|
188
|
+
[tool.poe.tasks.e2e]
|
|
189
|
+
cmd = "pytest -m e2e"
|
|
190
|
+
help = "Run the skillsinc process against a throwaway home"
|
|
191
|
+
|
|
192
|
+
[tool.poe.tasks.perf]
|
|
193
|
+
cmd = "pytest -m perf --durations=0 -p no:randomly"
|
|
194
|
+
help = "Run the performance budgets"
|
|
195
|
+
|
|
196
|
+
[tool.poe.tasks.mutate]
|
|
197
|
+
shell = "uv run --group mutation mutmut run && uv run --group mutation mutmut results --all true > mutation-results.txt && uv run python scripts/mutation_report.py mutation-results.txt"
|
|
198
|
+
help = "Mutation testing (POSIX only; slow)"
|
|
199
|
+
|
|
200
|
+
[tool.poe.tasks.docs-lint]
|
|
201
|
+
cmd = "npx --yes markdownlint-cli2"
|
|
202
|
+
help = "Lint Markdown documentation"
|
|
203
|
+
|
|
204
|
+
[tool.poe.tasks.fix]
|
|
205
|
+
sequence = [
|
|
206
|
+
"format",
|
|
207
|
+
"lint-fix",
|
|
208
|
+
]
|
|
209
|
+
help = "Auto-fix formatting and lint"
|
|
210
|
+
|
|
211
|
+
[tool.poe.tasks.check]
|
|
212
|
+
sequence = [
|
|
213
|
+
"format-check",
|
|
214
|
+
"lint",
|
|
215
|
+
"typecheck",
|
|
216
|
+
"test",
|
|
217
|
+
]
|
|
218
|
+
help = "Run every Python quality gate"
|
|
219
|
+
|
|
220
|
+
[tool.mutmut]
|
|
221
|
+
source_paths = ["src/skillsinc/"]
|
|
222
|
+
pytest_add_cli_args_test_selection = ["tests/"]
|
|
223
|
+
pytest_add_cli_args = [
|
|
224
|
+
"-p",
|
|
225
|
+
"no:randomly",
|
|
226
|
+
"-p",
|
|
227
|
+
"no:cacheprovider",
|
|
228
|
+
"-m",
|
|
229
|
+
"not e2e and not perf",
|
|
230
|
+
]
|
|
231
|
+
mutate_only_covered_lines = true
|
|
232
|
+
also_copy = ["examples/"]
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "skillsinc"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Sync one library of agent skills, instructions, agents, and prompts into every AI coding harness you use."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "MIT"
|
|
7
|
+
license-files = ["LICENSE"]
|
|
8
|
+
authors = [{ name = "Mike Hill" }]
|
|
9
|
+
requires-python = ">=3.12"
|
|
10
|
+
keywords = ["agents", "skills", "claude-code", "codex", "copilot", "sync"]
|
|
11
|
+
classifiers = [
|
|
12
|
+
"Development Status :: 3 - Alpha",
|
|
13
|
+
"Environment :: Console",
|
|
14
|
+
"Intended Audience :: Developers",
|
|
15
|
+
"Operating System :: OS Independent",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Python :: 3.12",
|
|
18
|
+
"Programming Language :: Python :: 3.13",
|
|
19
|
+
"Programming Language :: Python :: 3.14",
|
|
20
|
+
"Topic :: Software Development",
|
|
21
|
+
"Typing :: Typed",
|
|
22
|
+
]
|
|
23
|
+
dependencies = [
|
|
24
|
+
"pyyaml>=6.0.3",
|
|
25
|
+
"tomlkit>=0.13.3",
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
[project.urls]
|
|
29
|
+
Homepage = "https://github.com/mikejhill/skillsinc"
|
|
30
|
+
Issues = "https://github.com/mikejhill/skillsinc/issues"
|
|
31
|
+
Changelog = "https://github.com/mikejhill/skillsinc/blob/main/CHANGELOG.md"
|
|
32
|
+
|
|
33
|
+
[project.scripts]
|
|
34
|
+
skillsinc = "skillsinc.__main__:Application.main"
|
|
35
|
+
|
|
36
|
+
[build-system]
|
|
37
|
+
requires = ["uv_build>=0.11.32,<0.12.0"]
|
|
38
|
+
build-backend = "uv_build"
|
|
39
|
+
|
|
40
|
+
[dependency-groups]
|
|
41
|
+
dev = [
|
|
42
|
+
"hypothesis>=6.169.2",
|
|
43
|
+
"poethepoet>=0.48.0",
|
|
44
|
+
"pytest>=9.1.1",
|
|
45
|
+
"pytest-cov>=7.1.0",
|
|
46
|
+
"pytest-randomly>=5.0.0",
|
|
47
|
+
"ruff>=0.17.0",
|
|
48
|
+
"ty>=0.0.86",
|
|
49
|
+
"types-pyyaml>=6.0.12.20260906",
|
|
50
|
+
]
|
|
51
|
+
mutation = [
|
|
52
|
+
"mutmut>=3.8.0",
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
[tool.ruff]
|
|
56
|
+
target-version = "py312"
|
|
57
|
+
line-length = 88
|
|
58
|
+
src = ["src", "tests"]
|
|
59
|
+
|
|
60
|
+
[tool.ruff.lint]
|
|
61
|
+
select = [
|
|
62
|
+
"A", "ANN", "ARG", "B", "BLE", "C4", "C90", "D", "DTZ", "E", "ERA", "F",
|
|
63
|
+
"FA", "FBT", "G", "I", "LOG", "N", "PERF", "PGH", "PIE", "PL", "PT", "PTH",
|
|
64
|
+
"RET", "RSE", "RUF", "S", "SIM", "T20", "TID", "TRY", "UP", "W",
|
|
65
|
+
]
|
|
66
|
+
ignore = [
|
|
67
|
+
"D107", # __init__ docstring: the class docstring covers it
|
|
68
|
+
"TRY003", # long messages in raise: context-rich messages are required here
|
|
69
|
+
]
|
|
70
|
+
|
|
71
|
+
[tool.ruff.lint.per-file-ignores]
|
|
72
|
+
"tests/**" = [
|
|
73
|
+
"S101", # assert is how pytest works
|
|
74
|
+
"PLR2004", # literal expected values are clearer in tests
|
|
75
|
+
]
|
|
76
|
+
|
|
77
|
+
[tool.ruff.lint.pydocstyle]
|
|
78
|
+
convention = "google"
|
|
79
|
+
|
|
80
|
+
[tool.ruff.lint.flake8-tidy-imports]
|
|
81
|
+
ban-relative-imports = "all"
|
|
82
|
+
|
|
83
|
+
[tool.ruff.lint.mccabe]
|
|
84
|
+
max-complexity = 10
|
|
85
|
+
|
|
86
|
+
[tool.ruff.format]
|
|
87
|
+
docstring-code-format = true
|
|
88
|
+
|
|
89
|
+
[tool.ty.rules]
|
|
90
|
+
all = "error"
|
|
91
|
+
|
|
92
|
+
[tool.pytest.ini_options]
|
|
93
|
+
testpaths = ["tests"]
|
|
94
|
+
addopts = [
|
|
95
|
+
"--strict-markers", "--strict-config", "-ra", "--import-mode=importlib",
|
|
96
|
+
# Performance budgets run in their own job: `poe perf`
|
|
97
|
+
"-m", "not perf",
|
|
98
|
+
]
|
|
99
|
+
xfail_strict = true
|
|
100
|
+
markers = [
|
|
101
|
+
"unit: one module through its public API (the default layer)",
|
|
102
|
+
"integration: user journeys through Application.run in one process",
|
|
103
|
+
"e2e: the skillsinc process run against a throwaway home directory",
|
|
104
|
+
"perf: time budgets for planning and syncing large libraries",
|
|
105
|
+
]
|
|
106
|
+
|
|
107
|
+
[tool.coverage.run]
|
|
108
|
+
source = ["skillsinc"]
|
|
109
|
+
branch = true
|
|
110
|
+
|
|
111
|
+
[tool.coverage.report]
|
|
112
|
+
fail_under = 98
|
|
113
|
+
show_missing = true
|
|
114
|
+
skip_covered = true
|
|
115
|
+
exclude_also = ['if __name__ == .__main__.:', 'assert_never\(']
|
|
116
|
+
|
|
117
|
+
[tool.poe.tasks]
|
|
118
|
+
format = { cmd = "ruff format .", help = "Format code" }
|
|
119
|
+
format-check = { cmd = "ruff format --check .", help = "Check formatting" }
|
|
120
|
+
lint = { cmd = "ruff check .", help = "Lint code" }
|
|
121
|
+
lint-fix = { cmd = "ruff check . --fix", help = "Lint and auto-fix" }
|
|
122
|
+
typecheck = { cmd = "ty check", help = "Type check (strict)" }
|
|
123
|
+
test = { cmd = "pytest --cov", help = "Run unit, property, integration, and e2e tests with coverage" }
|
|
124
|
+
e2e = { cmd = "pytest -m e2e", help = "Run the skillsinc process against a throwaway home" }
|
|
125
|
+
perf = { cmd = "pytest -m perf --durations=0 -p no:randomly", help = "Run the performance budgets" }
|
|
126
|
+
mutate = { shell = "uv run --group mutation mutmut run && uv run --group mutation mutmut results --all true > mutation-results.txt && uv run python scripts/mutation_report.py mutation-results.txt", help = "Mutation testing (POSIX only; slow)" }
|
|
127
|
+
docs-lint = { cmd = "npx --yes markdownlint-cli2", help = "Lint Markdown documentation" }
|
|
128
|
+
fix = { sequence = ["format", "lint-fix"], help = "Auto-fix formatting and lint" }
|
|
129
|
+
check = { sequence = ["format-check", "lint", "typecheck", "test"], help = "Run every Python quality gate" }
|
|
130
|
+
|
|
131
|
+
[tool.mutmut]
|
|
132
|
+
# Mutation testing: change the code in small ways and check a test fails.
|
|
133
|
+
# POSIX only (it forks); run it on Linux, macOS, or WSL with `uv run poe mutate`.
|
|
134
|
+
source_paths = ["src/skillsinc/"]
|
|
135
|
+
pytest_add_cli_args_test_selection = ["tests/"]
|
|
136
|
+
# Process tests and timing budgets run the installed code, not the mutant
|
|
137
|
+
pytest_add_cli_args = ["-p", "no:randomly", "-p", "no:cacheprovider", "-m", "not e2e and not perf"]
|
|
138
|
+
mutate_only_covered_lines = true
|
|
139
|
+
# Files tests read beside the code
|
|
140
|
+
also_copy = ["examples/"]
|