napoln 0.2.2__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.
Files changed (75) hide show
  1. napoln-0.2.2/.github/workflows/ci.yml +37 -0
  2. napoln-0.2.2/.github/workflows/pr-title.yml +15 -0
  3. napoln-0.2.2/.github/workflows/release-please.yml +27 -0
  4. napoln-0.2.2/.github/workflows/release.yml +54 -0
  5. napoln-0.2.2/.gitignore +26 -0
  6. napoln-0.2.2/.release-please-manifest.json +3 -0
  7. napoln-0.2.2/AGENTS.md +107 -0
  8. napoln-0.2.2/ARCHITECTURE.md +440 -0
  9. napoln-0.2.2/CHANGELOG.md +66 -0
  10. napoln-0.2.2/CLI-REDESIGN.md +895 -0
  11. napoln-0.2.2/CONTRIBUTING.md +165 -0
  12. napoln-0.2.2/LICENSE +21 -0
  13. napoln-0.2.2/PKG-INFO +141 -0
  14. napoln-0.2.2/PROMPT.md +67 -0
  15. napoln-0.2.2/README.md +121 -0
  16. napoln-0.2.2/SPEC.md +1933 -0
  17. napoln-0.2.2/STORIES.md +701 -0
  18. napoln-0.2.2/justfile +40 -0
  19. napoln-0.2.2/pyproject.toml +41 -0
  20. napoln-0.2.2/release-please-config.json +12 -0
  21. napoln-0.2.2/skills-lock.json +10 -0
  22. napoln-0.2.2/src/napoln/__init__.py +3 -0
  23. napoln-0.2.2/src/napoln/cli.py +300 -0
  24. napoln-0.2.2/src/napoln/commands/__init__.py +0 -0
  25. napoln-0.2.2/src/napoln/commands/add.py +392 -0
  26. napoln-0.2.2/src/napoln/commands/config.py +310 -0
  27. napoln-0.2.2/src/napoln/commands/init.py +54 -0
  28. napoln-0.2.2/src/napoln/commands/install.py +140 -0
  29. napoln-0.2.2/src/napoln/commands/list_cmd.py +246 -0
  30. napoln-0.2.2/src/napoln/commands/remove.py +72 -0
  31. napoln-0.2.2/src/napoln/commands/upgrade.py +217 -0
  32. napoln-0.2.2/src/napoln/core/__init__.py +0 -0
  33. napoln-0.2.2/src/napoln/core/agents.py +190 -0
  34. napoln-0.2.2/src/napoln/core/hasher.py +64 -0
  35. napoln-0.2.2/src/napoln/core/linker.py +95 -0
  36. napoln-0.2.2/src/napoln/core/manifest.py +230 -0
  37. napoln-0.2.2/src/napoln/core/merger.py +231 -0
  38. napoln-0.2.2/src/napoln/core/resolver.py +545 -0
  39. napoln-0.2.2/src/napoln/core/store.py +127 -0
  40. napoln-0.2.2/src/napoln/core/validator.py +168 -0
  41. napoln-0.2.2/src/napoln/errors.py +64 -0
  42. napoln-0.2.2/src/napoln/output.py +89 -0
  43. napoln-0.2.2/src/napoln/prompts.py +96 -0
  44. napoln-0.2.2/src/napoln/skills/napoln-manage/SKILL.md +78 -0
  45. napoln-0.2.2/tests/__init__.py +0 -0
  46. napoln-0.2.2/tests/conftest.py +72 -0
  47. napoln-0.2.2/tests/features/config.feature +32 -0
  48. napoln-0.2.2/tests/features/first_run.feature +20 -0
  49. napoln-0.2.2/tests/features/init.feature +16 -0
  50. napoln-0.2.2/tests/features/install.feature +22 -0
  51. napoln-0.2.2/tests/features/list.feature +24 -0
  52. napoln-0.2.2/tests/features/upgrade.feature +59 -0
  53. napoln-0.2.2/tests/fixtures/invalid-skill/SKILL.md +7 -0
  54. napoln-0.2.2/tests/fixtures/multi-skill-repo/README.md +3 -0
  55. napoln-0.2.2/tests/fixtures/multi-skill-repo/skills/skill-a/SKILL.md +10 -0
  56. napoln-0.2.2/tests/fixtures/multi-skill-repo/skills/skill-b/SKILL.md +10 -0
  57. napoln-0.2.2/tests/fixtures/valid-skill/SKILL.md +16 -0
  58. napoln-0.2.2/tests/integration/test_cli.py +306 -0
  59. napoln-0.2.2/tests/steps/__init__.py +0 -0
  60. napoln-0.2.2/tests/steps/conftest.py +83 -0
  61. napoln-0.2.2/tests/steps/test_config.py +96 -0
  62. napoln-0.2.2/tests/steps/test_first_run.py +93 -0
  63. napoln-0.2.2/tests/steps/test_init.py +78 -0
  64. napoln-0.2.2/tests/steps/test_install.py +103 -0
  65. napoln-0.2.2/tests/steps/test_list.py +90 -0
  66. napoln-0.2.2/tests/steps/test_upgrade.py +239 -0
  67. napoln-0.2.2/tests/unit/test_agents.py +130 -0
  68. napoln-0.2.2/tests/unit/test_hasher.py +108 -0
  69. napoln-0.2.2/tests/unit/test_linker.py +100 -0
  70. napoln-0.2.2/tests/unit/test_manifest.py +159 -0
  71. napoln-0.2.2/tests/unit/test_merger.py +160 -0
  72. napoln-0.2.2/tests/unit/test_resolver.py +131 -0
  73. napoln-0.2.2/tests/unit/test_store.py +112 -0
  74. napoln-0.2.2/tests/unit/test_validator.py +132 -0
  75. napoln-0.2.2/uv.lock +782 -0
@@ -0,0 +1,37 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ paths:
7
+ - "src/**"
8
+ - "tests/**"
9
+ - "pyproject.toml"
10
+ - "justfile"
11
+ - ".github/workflows/ci.yml"
12
+ pull_request:
13
+ branches: [main]
14
+ paths:
15
+ - "src/**"
16
+ - "tests/**"
17
+ - "pyproject.toml"
18
+ - "justfile"
19
+ - ".github/workflows/ci.yml"
20
+
21
+ jobs:
22
+ check:
23
+ name: Check, Lint & Test
24
+ runs-on: ubuntu-latest
25
+ strategy:
26
+ matrix:
27
+ python-version: ["3.11", "3.12", "3.13"]
28
+ steps:
29
+ - uses: actions/checkout@v4
30
+ - uses: astral-sh/setup-uv@v6
31
+ - uses: extractions/setup-just@v2
32
+ - name: Set up Python ${{ matrix.python-version }}
33
+ run: uv python install ${{ matrix.python-version }}
34
+ - name: Install dependencies
35
+ run: uv sync --extra dev
36
+ - name: Run checks
37
+ run: just check
@@ -0,0 +1,15 @@
1
+ name: PR Title
2
+
3
+ on:
4
+ pull_request:
5
+ types: [opened, edited, synchronize, reopened]
6
+
7
+ jobs:
8
+ validate:
9
+ permissions:
10
+ pull-requests: read
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: amannn/action-semantic-pull-request@e32d7e603df1aa1ba07e981f2a23455dee596825 # v5
14
+ env:
15
+ GITHUB_TOKEN: ${{ github.token }}
@@ -0,0 +1,27 @@
1
+ name: Release Please
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+
8
+ permissions:
9
+ actions: write
10
+ contents: write
11
+ pull-requests: write
12
+
13
+ jobs:
14
+ release-please:
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - uses: googleapis/release-please-action@v4
18
+ id: release-please
19
+ with:
20
+ config-file: release-please-config.json
21
+ manifest-file: .release-please-manifest.json
22
+
23
+ - name: Dispatch release build
24
+ if: ${{ steps.release-please.outputs.releases_created == 'true' }}
25
+ env:
26
+ GH_TOKEN: ${{ github.token }}
27
+ run: gh workflow run release.yml --repo ${{ github.repository }} -f tag=${{ steps.release-please.outputs.tag_name }}
@@ -0,0 +1,54 @@
1
+ name: Release
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ inputs:
6
+ tag:
7
+ description: "Git tag to build and release (e.g. v0.1.0)"
8
+ required: true
9
+ type: string
10
+
11
+ permissions:
12
+ contents: write
13
+ id-token: write
14
+
15
+ jobs:
16
+ build:
17
+ name: Build & Publish
18
+ runs-on: ubuntu-latest
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+ with:
22
+ ref: ${{ inputs.tag }}
23
+ - uses: astral-sh/setup-uv@v6
24
+ - uses: extractions/setup-just@v2
25
+
26
+ - name: Build
27
+ run: just build
28
+
29
+ - name: Upload artifacts
30
+ uses: actions/upload-artifact@v4
31
+ with:
32
+ name: dist
33
+ path: dist/
34
+
35
+ - name: Publish to PyPI
36
+ run: uv publish
37
+ env:
38
+ UV_PUBLISH_TOKEN: ${{ secrets.PYPI_TOKEN }}
39
+
40
+ release:
41
+ name: GitHub Release
42
+ needs: build
43
+ runs-on: ubuntu-latest
44
+ steps:
45
+ - uses: actions/download-artifact@v4
46
+ with:
47
+ name: dist
48
+ path: dist/
49
+
50
+ - name: Upload to GitHub Release
51
+ uses: softprops/action-gh-release@v2
52
+ with:
53
+ tag_name: ${{ inputs.tag }}
54
+ files: dist/*
@@ -0,0 +1,26 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ .venv/
8
+
9
+ # IDE
10
+ .idea/
11
+ .vscode/
12
+ *.swp
13
+ *.swo
14
+
15
+ # OS
16
+ .DS_Store
17
+ Thumbs.db
18
+
19
+ # napoln placements (commit manifest, not placements)
20
+ .claude/skills/
21
+ .gemini/skills/
22
+ .agents/skills/
23
+ .pi/skills/
24
+ .coverage
25
+ .pytest_cache/
26
+ .napoln/
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.2.2"
3
+ }
napoln-0.2.2/AGENTS.md ADDED
@@ -0,0 +1,107 @@
1
+ # Development Rules
2
+
3
+ ## First Message
4
+
5
+ If no concrete task is given, read README.md and ARCHITECTURE.md, then ask what to work on.
6
+
7
+ ## Project Overview
8
+
9
+ napoln is a package manager for agent skills. Python 3.11+, built with uv and hatchling. CLI uses typer. Tests use pytest + pytest-bdd.
10
+
11
+ Key directories:
12
+ - `src/napoln/core/` — Core logic (no CLI dependency)
13
+ - `src/napoln/commands/` — One module per CLI command
14
+ - `src/napoln/cli.py` — Typer entry point (7 commands)
15
+ - `tests/unit/` — Parametrized unit tests per core module
16
+ - `tests/integration/` — CLI tests via typer.testing.CliRunner
17
+ - `tests/steps/` — BDD step definitions
18
+ - `tests/features/` — BDD .feature files
19
+
20
+ Read [CONTRIBUTING.md](CONTRIBUTING.md) for full project layout, test organization, and how to add commands or agents.
21
+
22
+ ## Commands
23
+
24
+ - After code changes: `just check` (runs format check + lint + tests). Fix all errors before committing.
25
+ - `just check` is the single source of truth. CI runs the same command.
26
+ - `just fmt` to auto-fix formatting and lint issues.
27
+ - `just test` to run tests only. Supports args: `just test -k "test_merge" -x -v`
28
+ - `just coverage` for coverage report.
29
+ - Run the CLI locally: `uv run napoln <command>`
30
+ - NEVER run `uv run napoln add` or `uv run napoln remove` against the real `~/.napoln/` during development without explicit user instruction. Tests use isolated `$HOME` and `$NAPOLN_HOME`.
31
+
32
+ ## Code Quality
33
+
34
+ - Keep `core/` independent. Commands import from core, never the reverse.
35
+ - One command per file in `commands/`. Each exports a `run_<command>()` function.
36
+ - Use `from __future__ import annotations` in every module.
37
+ - Line length: 100 (configured in pyproject.toml).
38
+ - Linter/formatter: ruff.
39
+ - Type hints on all function signatures.
40
+ - No unused imports or variables (ruff enforces this).
41
+
42
+ ## Architecture
43
+
44
+ Read [ARCHITECTURE.md](ARCHITECTURE.md) for design decisions. Key points:
45
+
46
+ - **7 CLI commands**: `add`, `remove`, `upgrade`, `list`, `install`, `init`, `config`
47
+ - **Reflink-first placement.** Copy-on-write where supported, full copy fallback. No hardlinks (skills are mutable).
48
+ - **Content-addressed store** at `~/.napoln/store/{name}/{version}-{hash}/`. Immutable after write.
49
+ - **Three-way merge on upgrade** using `git merge-file` with `difflib` fallback.
50
+ - **Agent path deduplication.** Gemini CLI, pi, and Codex share `~/.agents/skills/` — one placement serves all three.
51
+ - **Dual-scope manifests.** Global (`~/.napoln/manifest.toml`) and project (`.napoln/manifest.toml`). `napoln install` syncs both.
52
+ - **No registry in v0.x.** Git-only sources. Registry identifiers are parsed but return "not yet available".
53
+ - **No telemetry.** Cut until there's a real backend.
54
+
55
+ ## Testing
56
+
57
+ - Write tests first when adding behavior.
58
+ - Unit tests for core logic, BDD for user-facing workflows.
59
+ - Tests run in isolated environments with `$HOME` and `$NAPOLN_HOME` set to tmp dirs.
60
+ - The `NapolnTestEnv` class in `tests/steps/conftest.py` manages isolated BDD environments.
61
+ - The `skill_builder` factory in `tests/conftest.py` creates test skills for unit tests.
62
+ - Use `--agents claude-code` in tests that use `--project` to avoid relying on agent detection.
63
+ - BDD tests that check `napoln list` must `chdir` to the isolated home to avoid picking up the real project manifest.
64
+ - Reflink may not be available (Linux ext4, CI). The linker falls back to copy. Tests pass on both.
65
+
66
+ ## CLI Design
67
+
68
+ The CLI has 7 top-level commands. No completion flags in help output. Common short flags:
69
+
70
+ | Flag | Meaning | Available on |
71
+ |------|---------|-------------|
72
+ | `-p` | Project scope | add, remove, upgrade, list, install, config doctor |
73
+ | `-g` | Global only | list, install |
74
+ | `-a` | Install all skills | add |
75
+ | `-s` | Select specific skill | add |
76
+ | `-v` | Verbose (show paths) | list |
77
+
78
+ `config` has subcommands: `set`, `doctor`, `gc`.
79
+
80
+ All mutating commands support `--dry-run`.
81
+
82
+ ## Commit Messages
83
+
84
+ Use [Conventional Commits](https://www.conventionalcommits.org/):
85
+
86
+ ```
87
+ feat: add napoln init command
88
+ fix: catch ReflinkImpossibleError on Linux
89
+ test: BDD coverage for three-way merge cases
90
+ refactor: reduce CLI from 13 commands to 7
91
+ docs: update ARCHITECTURE.md for new command set
92
+ chore: trigger release-please
93
+ ```
94
+
95
+ Breaking changes bump minor while pre-v1 (configured via release-please `bump-minor-pre-major`).
96
+
97
+ ## Style
98
+
99
+ - Concise answers, no filler.
100
+ - Neutral technical voice in documentation (no "This is exactly what we want", no first-person plural editorializing).
101
+ - No emojis in commits, docs, or code. Terminal output uses unicode symbols (✓, ✗, ⚠, ℹ).
102
+
103
+ ## File Reading
104
+
105
+ - Use the read tool to examine files, not cat or sed.
106
+ - Read files fully before editing.
107
+ - When editing, keep `oldText` as small as possible while being unique.