zipsa 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.
zipsa-0.1.0/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ .venv/
2
+ .coverage
3
+ .pytest_cache/
4
+ *.pyc
5
+ __pycache__/
6
+ *.egg-info/
7
+ dist/
8
+ build/
9
+ .zipsa/
zipsa-0.1.0/CLAUDE.md ADDED
@@ -0,0 +1,336 @@
1
+ # Launcher Development Guide
2
+
3
+ > **IMPORTANT:** Read [/CLAUDE.md](../CLAUDE.md) first for common development rules.
4
+
5
+ This guide covers Launcher-specific development practices.
6
+
7
+ ---
8
+
9
+ ## Project Purpose
10
+
11
+ Python CLI tool for orchestrating SKILL execution across multiple runtimes (Claude Code, Codex, Gemini).
12
+
13
+ **Goals:**
14
+ - Runtime-agnostic execution
15
+ - Manifest validation
16
+ - Environment variable management
17
+ - Execution logging and metrics
18
+
19
+ ## Technology Stack
20
+ - **Language:** Python 3.12+
21
+ - **Package Manager:** uv
22
+ - **Testing:** pytest with coverage
23
+ - **Validation:** Pydantic models
24
+ - **CLI:** Click framework
25
+
26
+ ---
27
+
28
+ ## TDD for Python
29
+
30
+ **Example TDD cycle with pytest:**
31
+
32
+ ```bash
33
+ # 1. Write test
34
+ # tests/test_new_feature.py
35
+
36
+ # 2. Run test (should fail)
37
+ uv run pytest tests/test_new_feature.py -v
38
+
39
+ # 3. Implement feature
40
+ # zipsa/core/new_feature.py
41
+
42
+ # 4. Run test (should pass)
43
+ uv run pytest tests/test_new_feature.py -v
44
+
45
+ # 5. Run all tests
46
+ uv run pytest --cov=zipsa
47
+ ```
48
+
49
+ **Coverage Requirements:**
50
+ - Minimum: 70% overall coverage
51
+ - New code: 80%+ coverage preferred
52
+ - Don't sacrifice test quality for coverage %
53
+
54
+ ---
55
+
56
+ ## Code Guidelines
57
+
58
+ ### Project Structure
59
+ ```
60
+ launcher/
61
+ ├── zipsa/ # Main package
62
+ │ ├── __init__.py
63
+ │ ├── cli.py # Click commands
64
+ │ ├── core/ # Core logic
65
+ │ │ ├── executor.py # Docker orchestration
66
+ │ │ ├── skill.py # Skill loading
67
+ │ │ └── models.py # Pydantic models
68
+ │ └── runtimes/ # Runtime plugins
69
+ │ ├── base.py
70
+ │ ├── claude.py
71
+ │ └── ...
72
+ ├── tests/ # Test files
73
+ │ ├── test_cli.py
74
+ │ ├── test_executor.py
75
+ │ └── fixtures/ # Test data
76
+ └── pyproject.toml
77
+ ```
78
+
79
+ ### Pydantic Models
80
+ Use Pydantic for all configuration and validation:
81
+
82
+ ```python
83
+ from pydantic import BaseModel, Field
84
+
85
+ class SkillMetadata(BaseModel):
86
+ """Skill metadata with validation."""
87
+ name: str
88
+ version: str
89
+ author: str | None = None
90
+ ```
91
+
92
+ ### Error Handling
93
+ ```python
94
+ # Good - specific exceptions
95
+ try:
96
+ skill = Skill.load(path)
97
+ except FileNotFoundError:
98
+ print(f"Error: Manifest not found: {path}")
99
+ sys.exit(1)
100
+
101
+ # Bad - generic exceptions
102
+ try:
103
+ skill = Skill.load(path)
104
+ except Exception as e:
105
+ print(f"Error: {e}")
106
+ ```
107
+
108
+ ---
109
+
110
+ ## Testing Strategy
111
+
112
+ ### Running Tests
113
+
114
+ ```bash
115
+ # Run all tests
116
+ uv run pytest
117
+
118
+ # Run specific test file
119
+ uv run pytest tests/test_executor.py -v
120
+
121
+ # Run with coverage
122
+ uv run pytest --cov=zipsa --cov-report=term-missing
123
+
124
+ # Run only failed tests
125
+ uv run pytest --lf
126
+ ```
127
+
128
+ ### Test Structure
129
+
130
+ ```python
131
+ class TestFeatureName:
132
+ """Test suite for feature."""
133
+
134
+ def test_basic_behavior(self):
135
+ """Test basic expected behavior."""
136
+ result = function(input)
137
+ assert result == expected
138
+
139
+ def test_edge_case(self):
140
+ """Test edge case handling."""
141
+ with pytest.raises(ValueError):
142
+ function(invalid_input)
143
+
144
+ def test_with_fixture(self, tmp_path):
145
+ """Test using pytest fixture."""
146
+ file_path = tmp_path / "test.yaml"
147
+ # ... test implementation
148
+ ```
149
+
150
+ ### Coverage Requirements
151
+ - Minimum: 70% overall coverage
152
+ - New code: 80%+ coverage preferred
153
+ - Don't sacrifice test quality for coverage %
154
+
155
+ ---
156
+
157
+ ## Quality Checklist
158
+
159
+ **Launcher-specific checks** (see [/CLAUDE.md](../CLAUDE.md) for common checks):
160
+
161
+ - [ ] All tests pass: `uv run pytest`
162
+ - [ ] Coverage ≥ 70%: `uv run pytest --cov=zipsa`
163
+ - [ ] No linting errors (if configured)
164
+ - [ ] Pydantic models validate correctly
165
+ - [ ] CLI commands work as expected
166
+
167
+ ---
168
+
169
+ ## Common Tasks
170
+
171
+ ### Adding a New Runtime
172
+
173
+ 1. Create runtime plugin:
174
+ ```python
175
+ # zipsa/runtimes/newruntime.py
176
+ from .base import RuntimeBase
177
+
178
+ class NewRuntime(RuntimeBase):
179
+ name = "newruntime"
180
+ # ... implement methods
181
+ ```
182
+
183
+ 2. Register in `runtimes/__init__.py`
184
+
185
+ 3. Write tests:
186
+ ```python
187
+ # tests/test_runtimes.py
188
+ class TestNewRuntime:
189
+ def test_runtime_name(self):
190
+ runtime = NewRuntime()
191
+ assert runtime.name == "newruntime"
192
+ ```
193
+
194
+ ### Adding a New CLI Command
195
+
196
+ 1. Add command in `cli.py`:
197
+ ```python
198
+ @click.command()
199
+ def mycommand():
200
+ """Description of command."""
201
+ # implementation
202
+ ```
203
+
204
+ 2. Add to CLI group
205
+
206
+ 3. Write tests:
207
+ ```python
208
+ # tests/test_cli.py
209
+ def test_mycommand():
210
+ result = runner.invoke(cli, ["mycommand"])
211
+ assert result.exit_code == 0
212
+ ```
213
+
214
+ ### Updating Pydantic Models
215
+
216
+ 1. Write test with new field:
217
+ ```python
218
+ def test_new_field():
219
+ data = {"name": "test", "new_field": "value"}
220
+ model = MyModel.model_validate(data)
221
+ assert model.new_field == "value"
222
+ ```
223
+
224
+ 2. Update model:
225
+ ```python
226
+ class MyModel(BaseModel):
227
+ name: str
228
+ new_field: str | None = None
229
+ ```
230
+
231
+ 3. Verify tests pass
232
+
233
+ ---
234
+
235
+ ## Development Commands
236
+
237
+ ```bash
238
+ # Install dependencies
239
+ uv pip install -e ".[dev]"
240
+
241
+ # Run tests
242
+ uv run pytest
243
+
244
+ # Run with coverage
245
+ uv run pytest --cov=zipsa --cov-report=html
246
+ open htmlcov/index.html
247
+
248
+ # Format code (if configured)
249
+ uv run black zipsa/ tests/
250
+
251
+ # Type checking (if configured)
252
+ uv run mypy zipsa/
253
+
254
+ # Interactive Python with package
255
+ uv run python
256
+ >>> from zipsa.core.skill import Skill
257
+ >>> skill = Skill.load("../skills/daily-progress")
258
+ ```
259
+
260
+ ---
261
+
262
+ ## Debugging Tips
263
+
264
+ ### Dry Run Mode
265
+ ```bash
266
+ # See what Docker command would be executed
267
+ zipsa run my-skill "query" --dry-run
268
+ ```
269
+
270
+ ### Interactive Shell in Container
271
+ ```bash
272
+ # Debug inside container
273
+ zipsa shell ../skills/daily-progress
274
+ ```
275
+
276
+ ### Test Specific Scenario
277
+ ```bash
278
+ # Run single test with verbose output
279
+ uv run pytest tests/test_executor.py::TestRuntimeConfig::test_auto_inject_env_from_config -vv
280
+ ```
281
+
282
+ ### Check Logs
283
+ ```bash
284
+ # Execution logs are saved in skill directory
285
+ cat ../skills/daily-progress/.zipsa/runs/*/output.jsonl
286
+ cat ../skills/daily-progress/.zipsa/runs/*/metadata.json
287
+ ```
288
+
289
+ ---
290
+
291
+ ## Troubleshooting
292
+
293
+ ### Issue: Tests failing with import errors
294
+
295
+ **Solution:**
296
+ ```bash
297
+ # Reinstall in development mode
298
+ uv pip install -e ".[dev]"
299
+ ```
300
+
301
+ ### Issue: Coverage too low
302
+
303
+ **Solution:**
304
+ - Focus on critical paths first
305
+ - Add tests for error cases
306
+ - Don't skip integration tests
307
+
308
+ ### Issue: Pydantic validation error
309
+
310
+ **Solution:**
311
+ ```bash
312
+ # Check model definition matches test data
313
+ # Use .model_validate() not direct instantiation
314
+ data = {"field": "value"}
315
+ model = MyModel.model_validate(data) # Good
316
+ model = MyModel(field="value") # Also works but less explicit
317
+ ```
318
+
319
+ ---
320
+
321
+ ## Resources
322
+
323
+ - **Python Docs:** https://docs.python.org/3.12/
324
+ - **Pydantic:** https://docs.pydantic.dev/
325
+ - **pytest:** https://docs.pytest.org/
326
+ - **Click:** https://click.palletsprojects.com/
327
+ - **uv:** https://github.com/astral-sh/uv
328
+
329
+ ---
330
+
331
+ ## Notes
332
+
333
+ - This is a **CLI orchestrator**, not a runtime environment
334
+ - Focus on clean interfaces and testability
335
+ - Keep Docker logic isolated in executor
336
+ - Runtime plugins should be minimal and focused
zipsa-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,81 @@
1
+ Metadata-Version: 2.4
2
+ Name: zipsa
3
+ Version: 0.1.0
4
+ Summary: Multi-runtime skill launcher for Claude Code, Codex, and Gemini CLI
5
+ Author-email: WestbrookAI <neochoon@gmail.com>
6
+ License-Expression: MIT
7
+ Keywords: agent,claude,codex,gemini,mcp,runtime
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Requires-Python: >=3.10
16
+ Requires-Dist: pydantic>=2.0
17
+ Requires-Dist: pyyaml>=6.0
18
+ Requires-Dist: typer>=0.9
19
+ Provides-Extra: dev
20
+ Requires-Dist: mypy>=1.0; extra == 'dev'
21
+ Requires-Dist: pytest-cov>=4.0; extra == 'dev'
22
+ Requires-Dist: pytest>=7.0; extra == 'dev'
23
+ Requires-Dist: ruff>=0.1; extra == 'dev'
24
+ Description-Content-Type: text/markdown
25
+
26
+ # Zipsa Launcher
27
+
28
+ Multi-runtime skill launcher for Claude Code, Codex, and Gemini CLI.
29
+
30
+ ## Installation
31
+
32
+ ```bash
33
+ pip install -e ".[dev]"
34
+ ```
35
+
36
+ ## Configuration
37
+
38
+ ### Runtime Configuration
39
+
40
+ Create `~/.zipsa/runtime-config.yaml` to configure runtime-specific settings:
41
+
42
+ ```yaml
43
+ runtimes:
44
+ claude:
45
+ auto_inject_env:
46
+ - CLAUDE_CODE_OAUTH_TOKEN
47
+ ```
48
+
49
+ **How it works:**
50
+ - Only environment variables listed in `auto_inject_env` are automatically passed to the container
51
+ - If the config file doesn't exist or a runtime is not configured, no auto-injection occurs
52
+ - User-provided environment variables (via CLI) always take precedence
53
+ - If a listed env var is not set in the host environment, a warning is shown
54
+
55
+ Example file is provided at `runtime-config.yaml.example`.
56
+
57
+ ## Usage
58
+
59
+ ```bash
60
+ # Run a skill
61
+ zipsa run weather "Seoul weather"
62
+
63
+ # With specific runtime
64
+ zipsa run weather "Seoul" --runtime claude
65
+
66
+ # With environment variables (overrides auto-inject)
67
+ zipsa run weather "Seoul" --env CLAUDE_CODE_OAUTH_TOKEN=custom-token
68
+
69
+ # Validate manifest
70
+ zipsa validate ../zipsa-skills/weather
71
+
72
+ # List skills
73
+ zipsa list ../zipsa-skills
74
+
75
+ # List runtimes
76
+ zipsa runtimes
77
+ ```
78
+
79
+ ## Development
80
+
81
+ See [Design Document](../docs/zipsa-python-design.md) for architecture details.
zipsa-0.1.0/README.md ADDED
@@ -0,0 +1,56 @@
1
+ # Zipsa Launcher
2
+
3
+ Multi-runtime skill launcher for Claude Code, Codex, and Gemini CLI.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install -e ".[dev]"
9
+ ```
10
+
11
+ ## Configuration
12
+
13
+ ### Runtime Configuration
14
+
15
+ Create `~/.zipsa/runtime-config.yaml` to configure runtime-specific settings:
16
+
17
+ ```yaml
18
+ runtimes:
19
+ claude:
20
+ auto_inject_env:
21
+ - CLAUDE_CODE_OAUTH_TOKEN
22
+ ```
23
+
24
+ **How it works:**
25
+ - Only environment variables listed in `auto_inject_env` are automatically passed to the container
26
+ - If the config file doesn't exist or a runtime is not configured, no auto-injection occurs
27
+ - User-provided environment variables (via CLI) always take precedence
28
+ - If a listed env var is not set in the host environment, a warning is shown
29
+
30
+ Example file is provided at `runtime-config.yaml.example`.
31
+
32
+ ## Usage
33
+
34
+ ```bash
35
+ # Run a skill
36
+ zipsa run weather "Seoul weather"
37
+
38
+ # With specific runtime
39
+ zipsa run weather "Seoul" --runtime claude
40
+
41
+ # With environment variables (overrides auto-inject)
42
+ zipsa run weather "Seoul" --env CLAUDE_CODE_OAUTH_TOKEN=custom-token
43
+
44
+ # Validate manifest
45
+ zipsa validate ../zipsa-skills/weather
46
+
47
+ # List skills
48
+ zipsa list ../zipsa-skills
49
+
50
+ # List runtimes
51
+ zipsa runtimes
52
+ ```
53
+
54
+ ## Development
55
+
56
+ See [Design Document](../docs/zipsa-python-design.md) for architecture details.