skillcost 0.0.3__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.
@@ -0,0 +1,64 @@
1
+ # Editor configuration, see http://editorconfig.org
2
+ root = true
3
+
4
+ [*]
5
+ charset = utf-8
6
+ end_of_line = lf
7
+ indent_style = tab
8
+ indent_size = 4
9
+ insert_final_newline = true
10
+ trim_trailing_whitespace = true
11
+ max_line_length = 99
12
+
13
+ # Web
14
+ [*.{html,htm}]
15
+ indent_style = space
16
+ indent_size = 2
17
+
18
+ [*.{css,scss,sass}]
19
+ indent_style = space
20
+ indent_size = 2
21
+
22
+ [*.{ts,tsx,js,jsx}]
23
+ indent_style = space
24
+ indent_size = 2
25
+
26
+ # Data/config
27
+ [*.json]
28
+ indent_style = space
29
+ indent_size = 2
30
+
31
+ [*.{yaml,yml}]
32
+ indent_style = space
33
+ indent_size = 2
34
+
35
+ [*.toml]
36
+ indent_style = space
37
+ indent_size = 2
38
+
39
+ [*.{xml,svg}]
40
+ indent_style = space
41
+ indent_size = 2
42
+
43
+ # Docs/text
44
+ [*.md]
45
+ indent_style = space
46
+ indent_size = 2
47
+
48
+ [*.txt]
49
+ indent_style = space
50
+ indent_size = 2
51
+
52
+ # Scripts/build
53
+ [Makefile]
54
+ indent_style = tab
55
+
56
+ [*.sh]
57
+ indent_style = tab
58
+ max_line_length = 88
59
+
60
+ # Languages
61
+ [*.py]
62
+ # Python convention is 4 spaces per PEP 8
63
+ indent_style = space
64
+ max_line_length = 88
@@ -0,0 +1,10 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # Virtual environments
10
+ .venv
@@ -0,0 +1,6 @@
1
+ # Python files are formatted by ruff, not prettier
2
+ *.py
3
+ *.pyi
4
+
5
+ # Example markdown files
6
+ examples/*.md
@@ -0,0 +1,3 @@
1
+ {
2
+ "proseWrap": "always"
3
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "[json]": {
3
+ "editor.defaultFormatter": "esbenp.prettier-vscode",
4
+ "editor.formatOnSave": true,
5
+ "editor.formatOnSaveMode": "file"
6
+ },
7
+ "[markdown]": {
8
+ "editor.defaultFormatter": "esbenp.prettier-vscode",
9
+ "editor.formatOnSave": true,
10
+ "editor.formatOnSaveMode": "file"
11
+ },
12
+ "[yaml]": {
13
+ "editor.defaultFormatter": "esbenp.prettier-vscode",
14
+ "editor.formatOnSave": true,
15
+ "editor.formatOnSaveMode": "file"
16
+ },
17
+ "[python]": {
18
+ "editor.defaultFormatter": "charliermarsh.ruff",
19
+ "editor.formatOnSave": true,
20
+ "editor.formatOnSaveMode": "file"
21
+ }
22
+ }
@@ -0,0 +1 @@
1
+ This project uses `uv` for `venv` and package management.
@@ -0,0 +1,49 @@
1
+ # Contributing
2
+
3
+ ## Install Dependencies
4
+
5
+ Requires Python 3.12+ and uses `task`:
6
+
7
+ ```sh
8
+ # https://taskfile.dev/docs/installation
9
+ brew install go-task
10
+ task check:dependencies
11
+ ```
12
+
13
+ The project uses `uv` for dependency management:
14
+
15
+ ```sh
16
+ uv sync
17
+ ```
18
+
19
+ ## Run Tests
20
+
21
+ ```sh
22
+ task test
23
+ ```
24
+
25
+ ## Format
26
+
27
+ ```sh
28
+ task format
29
+ ```
30
+
31
+ ## Release gate
32
+
33
+ ```sh
34
+ task gate
35
+ ```
36
+
37
+ ---
38
+
39
+ ## Submitting Changes
40
+
41
+ Bug fixes and new features are welcome via pull request.
42
+
43
+ 1. Fork the repository and create a branch from `main`.
44
+ 2. Make your changes — include tests for any new behavior.
45
+ 3. Run `task gate` to confirm all checks pass.
46
+ 4. Open a pull request with a clear description of what changed and why.
47
+
48
+ For significant changes, open an issue first to discuss the approach before investing time in an
49
+ implementation.
@@ -0,0 +1,80 @@
1
+ Metadata-Version: 2.4
2
+ Name: skillcost
3
+ Version: 0.0.3
4
+ Summary: Estimates the token cost of agent skills and their linked resources
5
+ Requires-Python: >=3.12
6
+ Requires-Dist: pyyaml>=6.0.3
7
+ Requires-Dist: tiktoken>=0.12.0
8
+ Description-Content-Type: text/markdown
9
+
10
+ # skillcost
11
+
12
+ Estimates the token cost of agent skills and their linked resources.
13
+
14
+ Given a target file (typically a `SKILL.md`), `skillcost` counts tokens and crawls all linked files
15
+ and URLs to produce three cost figures:
16
+
17
+ | Metric | Description |
18
+ | ------------ | ------------------------------------------------------------------------------- |
19
+ | **Resident** | Tokens loaded on every prompt, just because the skill is installed. |
20
+ | **Baseline** | Tokens loaded when the skill is invoked — the skill file plus any `@`-includes. |
21
+ | **Maximum** | Tokens loaded if the agent follows every link in the skill file. |
22
+
23
+ This also works on `CLAUDE.md` or any other plain-text UTF-8 file.
24
+
25
+ ## Installation
26
+
27
+ Requires Python 3.12+ and [uv](https://github.com/astral-sh/uv).
28
+
29
+ ```sh
30
+ uv sync
31
+ ```
32
+
33
+ ## Usage
34
+
35
+ ```sh
36
+ uv run python -m main <path/to/file>
37
+ ```
38
+
39
+ Output defaults to human-readable text. Pass `--json` or `--yaml` for machine-readable output.
40
+
41
+ ```sh
42
+ uv run python -m main SKILL.md
43
+ uv run python -m main SKILL.md --json
44
+ uv run python -m main SKILL.md --yaml
45
+ ```
46
+
47
+ ### Example output
48
+
49
+ ```
50
+ Token Cost Report
51
+ =================
52
+ Resident : 97
53
+ Baseline : 1,940
54
+ Maximum : 18,390
55
+
56
+ Files (24)
57
+ /path/to/reference/conventions.md 926
58
+ /path/to/reference/utilities.md 1,751
59
+ ...
60
+
61
+ Links
62
+ @-directives : 0
63
+ Local links : 17
64
+ HTTP links : 0
65
+ ```
66
+
67
+ ## How links are counted
68
+
69
+ `skillcost` recognizes two link syntaxes in Markdown files:
70
+
71
+ - **`@{relative/path}`** — an include directive; the file is always fetched when the skill is
72
+ invoked, so it counts toward the **baseline** cost.
73
+ - **`[text](relative/path)`** — a standard Markdown link; followed recursively and counted toward
74
+ the **maximum** cost only.
75
+
76
+ HTTP links (`https://...`) are fetched and counted toward the maximum cost only.
77
+
78
+ ## Contributing
79
+
80
+ See [CONTRIBUTING.md](CONTRIBUTING.md).
@@ -0,0 +1,71 @@
1
+ # skillcost
2
+
3
+ Estimates the token cost of agent skills and their linked resources.
4
+
5
+ Given a target file (typically a `SKILL.md`), `skillcost` counts tokens and crawls all linked files
6
+ and URLs to produce three cost figures:
7
+
8
+ | Metric | Description |
9
+ | ------------ | ------------------------------------------------------------------------------- |
10
+ | **Resident** | Tokens loaded on every prompt, just because the skill is installed. |
11
+ | **Baseline** | Tokens loaded when the skill is invoked — the skill file plus any `@`-includes. |
12
+ | **Maximum** | Tokens loaded if the agent follows every link in the skill file. |
13
+
14
+ This also works on `CLAUDE.md` or any other plain-text UTF-8 file.
15
+
16
+ ## Installation
17
+
18
+ Requires Python 3.12+ and [uv](https://github.com/astral-sh/uv).
19
+
20
+ ```sh
21
+ uv sync
22
+ ```
23
+
24
+ ## Usage
25
+
26
+ ```sh
27
+ uv run python -m main <path/to/file>
28
+ ```
29
+
30
+ Output defaults to human-readable text. Pass `--json` or `--yaml` for machine-readable output.
31
+
32
+ ```sh
33
+ uv run python -m main SKILL.md
34
+ uv run python -m main SKILL.md --json
35
+ uv run python -m main SKILL.md --yaml
36
+ ```
37
+
38
+ ### Example output
39
+
40
+ ```
41
+ Token Cost Report
42
+ =================
43
+ Resident : 97
44
+ Baseline : 1,940
45
+ Maximum : 18,390
46
+
47
+ Files (24)
48
+ /path/to/reference/conventions.md 926
49
+ /path/to/reference/utilities.md 1,751
50
+ ...
51
+
52
+ Links
53
+ @-directives : 0
54
+ Local links : 17
55
+ HTTP links : 0
56
+ ```
57
+
58
+ ## How links are counted
59
+
60
+ `skillcost` recognizes two link syntaxes in Markdown files:
61
+
62
+ - **`@{relative/path}`** — an include directive; the file is always fetched when the skill is
63
+ invoked, so it counts toward the **baseline** cost.
64
+ - **`[text](relative/path)`** — a standard Markdown link; followed recursively and counted toward
65
+ the **maximum** cost only.
66
+
67
+ HTTP links (`https://...`) are fetched and counted toward the maximum cost only.
68
+
69
+ ## Contributing
70
+
71
+ See [CONTRIBUTING.md](CONTRIBUTING.md).
@@ -0,0 +1,183 @@
1
+ version: "3"
2
+
3
+ tasks:
4
+ default:
5
+ desc: List all available tasks
6
+ silent: true
7
+ cmds:
8
+ - task --list
9
+
10
+ # ---------------------------------------------------------------------------
11
+ # Dependencies
12
+ # ---------------------------------------------------------------------------
13
+
14
+ dependencies:
15
+ internal: true
16
+ desc: Check all required dependencies are installed
17
+ deps:
18
+ - dependencies:git
19
+ - dependencies:uv
20
+ - dependencies:ruff
21
+ - dependencies:prettier
22
+
23
+ dependencies:git:
24
+ internal: true
25
+ preconditions:
26
+ - sh: command -v git
27
+ msg: |
28
+ 'git' is not installed. Install it via:
29
+ brew install git
30
+ -or-
31
+ https://git-scm.com/downloads
32
+
33
+ dependencies:uv:
34
+ internal: true
35
+ preconditions:
36
+ - sh: command -v uv
37
+ msg: |
38
+ 'uv' is not installed. Install it via:
39
+ curl -LsSf https://astral.sh/uv/install.sh | sh
40
+
41
+ dependencies:ruff:
42
+ internal: true
43
+ preconditions:
44
+ - sh: command -v ruff
45
+ msg: |
46
+ 'ruff' is not installed. Install it via:
47
+ uv tool install ruff
48
+
49
+ dependencies:prettier:
50
+ internal: true
51
+ preconditions:
52
+ - sh: command -v prettier
53
+ msg: |
54
+ 'prettier' is not installed. Install it via:
55
+ npm install -g prettier
56
+ -or-
57
+ deno install -g -f --allow-env --allow-sys --allow-read --allow-write npm:prettier
58
+
59
+ # ---------------------------------------------------------------------------
60
+ # Checks
61
+ # ---------------------------------------------------------------------------
62
+
63
+ check:dependencies:
64
+ desc: Check all required dependencies are installed
65
+ silent: true
66
+ deps: [dependencies]
67
+ cmds:
68
+ - printf '✅ All dependencies satisfied\n'
69
+
70
+ check:git:
71
+ desc: Check git repo is clean and in sync
72
+ deps: [dependencies:git]
73
+ cmds:
74
+ - vendor/git-clean-check
75
+
76
+ check:test:
77
+ desc: Run tests with a simple non-redrawing reporter
78
+ deps: [dependencies:uv]
79
+ cmds:
80
+ - uv run python -m pytest tests/ -qq --tb=line
81
+
82
+ check:lint:
83
+ desc: Fail if any lint errors are found
84
+ deps: [dependencies:ruff]
85
+ cmds:
86
+ - ruff check .
87
+
88
+ check:format:
89
+ desc: Fail if any files have unformatted code
90
+ deps: [dependencies:ruff, dependencies:prettier]
91
+ cmds:
92
+ - ruff format --check .
93
+ - prettier --check .
94
+
95
+ # ---------------------------------------------------------------------------
96
+ # Testing
97
+ # ---------------------------------------------------------------------------
98
+
99
+ test:
100
+ desc: Run all tests
101
+ deps: [dependencies:uv]
102
+ cmds:
103
+ - uv run python -m pytest tests/
104
+
105
+ test:watch:
106
+ desc: Run tests in watch mode
107
+ deps: [dependencies:uv]
108
+ cmds:
109
+ - uv run pytest-watch tests/
110
+
111
+ # ---------------------------------------------------------------------------
112
+ # Formatting
113
+ # ---------------------------------------------------------------------------
114
+
115
+ format:
116
+ desc: Format all source files
117
+ deps: [dependencies:ruff, dependencies:prettier]
118
+ cmds:
119
+ - ruff format .
120
+ - prettier --write .
121
+
122
+ # ---------------------------------------------------------------------------
123
+ # Release
124
+ # ---------------------------------------------------------------------------
125
+
126
+ gate:
127
+ desc: Run all release gate checks
128
+ deps:
129
+ - check:lint
130
+ - check:format
131
+ - check:git
132
+ - check:test
133
+
134
+ release-patch:
135
+ desc: Release a patch version
136
+ silent: true
137
+ vars:
138
+ VERSION:
139
+ sh: tr -d '[:space:]' < VERSION
140
+ VERSION_TMP:
141
+ sh: mktemp
142
+ cmds:
143
+ - vendor/semver bump patch "{{.VERSION}}" > "{{.VERSION_TMP}}"
144
+ - mv "{{.VERSION_TMP}}" VERSION
145
+ - printf '🚀 bumped to v%s\n' "$(tr -d '[:space:]' < VERSION)"
146
+ - vendor/pyproject-version-sync VERSION
147
+ - vendor/pyproject-version-commit
148
+ - git push origin main
149
+ - vendor/version-tag VERSION
150
+
151
+ release-minor:
152
+ desc: Release a minor version
153
+ silent: true
154
+ vars:
155
+ VERSION:
156
+ sh: tr -d '[:space:]' < VERSION
157
+ VERSION_TMP:
158
+ sh: mktemp
159
+ cmds:
160
+ - vendor/semver bump minor "{{.VERSION}}" > "{{.VERSION_TMP}}"
161
+ - mv "{{.VERSION_TMP}}" VERSION
162
+ - printf '🚀 bumped to v%s\n' "$(tr -d '[:space:]' < VERSION)"
163
+ - vendor/pyproject-version-sync VERSION
164
+ - vendor/pyproject-version-commit
165
+ - git push origin main
166
+ - vendor/version-tag VERSION
167
+
168
+ release-major:
169
+ desc: Release a major version
170
+ silent: true
171
+ vars:
172
+ VERSION:
173
+ sh: tr -d '[:space:]' < VERSION
174
+ VERSION_TMP:
175
+ sh: mktemp
176
+ cmds:
177
+ - vendor/semver bump major "{{.VERSION}}" > "{{.VERSION_TMP}}"
178
+ - mv "{{.VERSION_TMP}}" VERSION
179
+ - printf '🚀 bumped to v%s\n' "$(tr -d '[:space:]' < VERSION)"
180
+ - vendor/pyproject-version-sync VERSION
181
+ - vendor/pyproject-version-commit
182
+ - git push origin main
183
+ - vendor/version-tag VERSION
@@ -0,0 +1 @@
1
+ 0.0.3
@@ -0,0 +1,21 @@
1
+ ---
2
+ name: data-transformer
3
+ description:
4
+ Transforms raw JSON payloads into a normalized schema, applies field mappings, and validates
5
+ against a JSON Schema definition before emitting the result.
6
+ ---
7
+
8
+ # Data Transformer Skill
9
+
10
+ This skill normalises incoming JSON data and validates it against a schema.
11
+
12
+ ## Usage
13
+
14
+ Pass a JSON payload and a schema file path. The skill returns the transformed, validated output or
15
+ raises a structured error.
16
+
17
+ ## Implementation notes
18
+
19
+ See [helpers](sub/helpers.md) for shared utility functions used by this skill.
20
+
21
+ Also references the shared [config](sub/config.md) module.
@@ -0,0 +1,16 @@
1
+ # Simple Example
2
+
3
+ A standalone markdown file with no links or directives.
4
+
5
+ This file is used as a baseline to verify that the token counter works correctly on a plain
6
+ document with no external references.
7
+
8
+ ## Section A
9
+
10
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore
11
+ et dolore magna aliqua.
12
+
13
+ ## Section B
14
+
15
+ Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
16
+ consequat.
@@ -0,0 +1,15 @@
1
+ # Configuration
2
+
3
+ Environment and runtime configuration for skills.
4
+
5
+ ## Variables
6
+
7
+ | Variable | Default | Description |
8
+ | -------------- | ------- | ---------------------- |
9
+ | `LOG_LEVEL` | `INFO` | Logging verbosity |
10
+ | `TIMEOUT_SECS` | `30` | HTTP request timeout |
11
+ | `MAX_RETRIES` | `3` | Maximum retry attempts |
12
+
13
+ ## Loading
14
+
15
+ Configuration is loaded from environment variables at startup.
@@ -0,0 +1,13 @@
1
+ # Helper Utilities
2
+
3
+ Shared utility functions referenced by skills and other markdown files.
4
+
5
+ ## parse_json
6
+
7
+ Parses a UTF-8 encoded JSON string and returns a Python dict. Raises `ValueError` on malformed
8
+ input.
9
+
10
+ ## validate_schema
11
+
12
+ Validates a dict against a JSON Schema definition. Returns `True` on success, raises `SchemaError`
13
+ on failure.
@@ -0,0 +1,18 @@
1
+ # With References
2
+
3
+ This file demonstrates all three link types supported by skillcost.
4
+
5
+ ## @-directives (always-included references)
6
+
7
+ @{simple.md}
8
+
9
+ The file above is always included in the baseline token count.
10
+
11
+ ## Local links (included in maximum only)
12
+
13
+ See [helper utilities](sub/helpers.md) for shared functions. See [configuration](sub/config.md) for
14
+ environment settings.
15
+
16
+ ## Remote links (included in maximum only)
17
+
18
+ Documentation: [Python pathlib](https://docs.python.org/3/library/pathlib.html)
@@ -0,0 +1,28 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "skillcost"
7
+ version = "0.0.3"
8
+ description = "Estimates the token cost of agent skills and their linked resources"
9
+ readme = "README.md"
10
+ requires-python = ">=3.12"
11
+ dependencies = [
12
+ "pyyaml>=6.0.3",
13
+ "tiktoken>=0.12.0",
14
+ ]
15
+
16
+ [dependency-groups]
17
+ dev = [
18
+ "pytest>=9.0.2",
19
+ ]
20
+
21
+ [project.scripts]
22
+ skillcost = "skillcost:main"
23
+
24
+ [tool.hatch.build.targets.wheel]
25
+ packages = ["src/skillcost"]
26
+
27
+ [tool.pytest.ini_options]
28
+ pythonpath = ["src"]