oasr 0.4.1__tar.gz → 0.5.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.
- {oasr-0.4.1 → oasr-0.5.0}/CHANGELOG.md +50 -0
- {oasr-0.4.1 → oasr-0.5.0}/PKG-INFO +1 -1
- {oasr-0.4.1 → oasr-0.5.0}/docs/commands/.INDEX.md +4 -2
- oasr-0.5.0/docs/commands/CLEAN.md +13 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/commands/CONFIG.md +57 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/commands/EXEC.md +172 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/commands/REGISTRY.md +36 -0
- oasr-0.5.0/docs/config.example.toml +220 -0
- {oasr-0.4.1 → oasr-0.5.0}/pyproject.toml +1 -1
- {oasr-0.4.1 → oasr-0.5.0}/src/cli.py +1 -1
- oasr-0.5.0/src/commands/clean.py +30 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/commands/exec.py +46 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/commands/registry.py +144 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/config/__init__.py +10 -0
- oasr-0.5.0/src/config/defaults.py +40 -0
- oasr-0.5.0/src/config/schema.py +73 -0
- oasr-0.5.0/src/policy/__init__.py +50 -0
- oasr-0.5.0/src/policy/defaults.py +27 -0
- oasr-0.5.0/src/policy/enforcement.py +98 -0
- oasr-0.5.0/src/policy/profile.py +185 -0
- {oasr-0.4.1 → oasr-0.5.0}/tests/test_config.py +121 -0
- {oasr-0.4.1 → oasr-0.5.0}/tests/test_exec.py +44 -4
- oasr-0.5.0/tests/test_policy_enforcement.py +158 -0
- oasr-0.5.0/tests/test_policy_profile.py +184 -0
- {oasr-0.4.1 → oasr-0.5.0}/uv.lock +1 -1
- oasr-0.4.1/docs/commands/CLEAN.md +0 -11
- oasr-0.4.1/doctor/SKILL.md +0 -35
- oasr-0.4.1/doctor/assets/schemas/session.schema.yaml +0 -87
- oasr-0.4.1/doctor/assets/schemas/treatment.schema.yaml +0 -70
- oasr-0.4.1/doctor/references/00_ROUTER.md +0 -104
- oasr-0.4.1/doctor/references/01_SUMMARY.md +0 -44
- oasr-0.4.1/doctor/references/02_TRIGGERS.md +0 -40
- oasr-0.4.1/doctor/references/03_ALWAYS.md +0 -43
- oasr-0.4.1/doctor/references/04_NEVER.md +0 -45
- oasr-0.4.1/doctor/references/05_PROCEDURE.md +0 -99
- oasr-0.4.1/doctor/references/06_FAILURES.md +0 -77
- oasr-0.4.1/doctor/scripts/include/.doctor/session.yaml +0 -11
- oasr-0.4.1/doctor/scripts/include/doctor_cli.py +0 -357
- oasr-0.4.1/doctor/scripts/include/doctor_parse.py +0 -348
- oasr-0.4.1/doctor/scripts/include/pyproject.toml +0 -12
- oasr-0.4.1/doctor/scripts/include/uv.lock +0 -78
- oasr-0.4.1/doctor/scripts/router_checks.sh +0 -87
- oasr-0.4.1/doctor/scripts/skill.ps1 +0 -65
- oasr-0.4.1/doctor/scripts/skill.sh +0 -57
- oasr-0.4.1/src/commands/clean.py +0 -155
- oasr-0.4.1/src/config/defaults.py +0 -16
- oasr-0.4.1/src/config/schema.py +0 -36
- {oasr-0.4.1 → oasr-0.5.0}/.gitignore +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/CONTRIBUTING.md +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/LICENSE +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/NOTICE +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/README.md +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/.INDEX.md +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/.images/adapter.png +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/.images/add-glob.png +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/.images/add-remote.png +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/.images/add.png +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/.images/find-add.png +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/.images/find.png +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/.images/help.png +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/.images/info.png +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/.images/list.png +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/.images/rm-glob.png +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/.images/rm.png +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/.images/status.png +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/.images/sync-update.png +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/.images/sync.png +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/.images/use.png +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/QUICKSTART.md +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/commands/ADAPTER.md +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/commands/ADD.md +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/commands/CLONE.md +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/commands/DIFF.md +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/commands/FIND.md +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/commands/HELP.md +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/commands/INFO.md +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/commands/LIST.md +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/commands/RM.md +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/commands/ROOT.md +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/commands/STATUS.md +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/commands/SYNC.md +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/commands/UPDATE.md +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/commands/USE.md +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/commands/VALIDATE.md +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/validation/.INDEX.md +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/validation/ERRORS.md +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/validation/INFO.md +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/validation/RULES.md +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/docs/validation/WARNINGS.md +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/install.ps1 +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/install.sh +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/llms.txt +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/scripts/README.md +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/scripts/fix.sh +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/scripts/lint.sh +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/scripts/test.sh +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/__init__.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/__main__.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/adapter.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/adapters/__init__.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/adapters/base.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/adapters/claude.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/adapters/codex.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/adapters/copilot.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/adapters/cursor.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/adapters/windsurf.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/agents/__init__.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/agents/base.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/agents/claude.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/agents/codex.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/agents/copilot.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/agents/opencode.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/agents/registry.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/commands/__init__.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/commands/adapter.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/commands/add.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/commands/clone.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/commands/config.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/commands/diff.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/commands/find.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/commands/help.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/commands/info.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/commands/list.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/commands/rm.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/commands/status.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/commands/sync.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/commands/update.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/commands/use.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/commands/validate.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/discovery.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/manifest.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/registry.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/remote.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/skillcopy/__init__.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/skillcopy/local.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/skillcopy/remote.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/tracking.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/src/validate.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/tests/conftest.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/tests/test_adapters.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/tests/test_agents.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/tests/test_clone.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/tests/test_config_command.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/tests/test_copy.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/tests/test_help.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/tests/test_list.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/tests/test_multi_skill.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/tests/test_remote.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/tests/test_tracking.py +0 -0
- {oasr-0.4.1 → oasr-0.5.0}/tests/test_use_glob.py +0 -0
|
@@ -4,6 +4,56 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
5
5
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [0.5.0] - 2026-02-02
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
- **🔒 Execution Policy System** — Host-level security boundaries for `oasr exec`
|
|
11
|
+
- Policy profiles define what agents can and cannot do
|
|
12
|
+
- Conservative safe defaults (fail closed)
|
|
13
|
+
- User-defined custom profiles in `config.toml`
|
|
14
|
+
- Pre-execution confirmation for risky operations
|
|
15
|
+
- Risk triggers: stdin, file prompts, non-safe profiles, network/env/shell access
|
|
16
|
+
- **New CLI flags for `oasr exec`**:
|
|
17
|
+
- `--profile <name>` — Choose execution policy profile
|
|
18
|
+
- `-y/--yes` — Skip confirmation prompt
|
|
19
|
+
- `--confirm` — Force confirmation even for safe operations
|
|
20
|
+
- **Configuration support for policies**:
|
|
21
|
+
- `[oasr]` section with `default_profile` setting
|
|
22
|
+
- `[profiles.<name>]` tables for custom profiles
|
|
23
|
+
- Policy field validation in config schema
|
|
24
|
+
- Built-in "safe" profile with conservative defaults
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
- **Security model**: `oasr exec` now requires explicit confirmation for risky execution contexts
|
|
28
|
+
- **Config schema**: Extended to support execution policy profiles
|
|
29
|
+
|
|
30
|
+
### Security
|
|
31
|
+
- **Prompt injection mitigation**: Policy enforcement reduces impact of malicious skill instructions
|
|
32
|
+
- **Sensitive file protection**: Default deny list includes `~/.ssh`, `~/.aws`, `~/.gnupg`, `.env`, etc.
|
|
33
|
+
- **Execution boundaries**: Clear limits on filesystem access, network, environment variables, and shell commands
|
|
34
|
+
- **User awareness**: Policy summary shown before risky executions
|
|
35
|
+
- **Fail-closed design**: Missing/malformed config falls back to safe defaults
|
|
36
|
+
|
|
37
|
+
### Documentation
|
|
38
|
+
- **[EXEC.md](docs/commands/EXEC.md)**: Added comprehensive Security Model section
|
|
39
|
+
- **[CONFIG.md](docs/commands/CONFIG.md)**: Added Execution Policy Profiles documentation
|
|
40
|
+
- **Policy examples**: Multiple profile configurations for different use cases
|
|
41
|
+
|
|
42
|
+
### Technical
|
|
43
|
+
- **New module**: `src/policy/` subpackage with clean API (Profile, load, assess_risk, prompt_confirmation)
|
|
44
|
+
- **41 new tests**: 30 policy tests + 11 config profile tests
|
|
45
|
+
- **Test coverage**: 187 total tests passing (all existing tests still pass)
|
|
46
|
+
- **Backward compatible**: No breaking changes to existing commands
|
|
47
|
+
|
|
48
|
+
## [0.4.2] - 2026-02-01
|
|
49
|
+
|
|
50
|
+
### Added
|
|
51
|
+
- **registry prune subcommand**: Added `oasr registry prune` to align with registry command taxonomy
|
|
52
|
+
|
|
53
|
+
### Changed
|
|
54
|
+
- **clean command**: Deprecated `oasr clean` in favor of `oasr registry prune` (will be removed in v0.6.0)
|
|
55
|
+
- **documentation**: Updated REGISTRY.md with prune subcommand documentation and usage examples
|
|
56
|
+
|
|
7
57
|
## [0.4.1] - 2026-02-01
|
|
8
58
|
|
|
9
59
|
### Fixed
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
## Core Commands (v0.4.0)
|
|
4
4
|
|
|
5
5
|
- [oasr](ROOT.md) - Global flags and options
|
|
6
|
-
- [oasr registry](REGISTRY.md) - Manage skill registry (validate, add, remove, list, sync)
|
|
6
|
+
- [oasr registry](REGISTRY.md) - Manage skill registry (validate, add, remove, list, sync, prune)
|
|
7
7
|
- [oasr diff](DIFF.md) - Show status of tracked skills
|
|
8
8
|
- [oasr sync](SYNC.md) - Refresh outdated tracked skills
|
|
9
9
|
- [oasr config](CONFIG.md) - Manage configuration (NEW in v0.4.0)
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
- [oasr exec](EXEC.md) - Execute skills as CLI tools (NEW in v0.4.0)
|
|
12
12
|
- [oasr find](FIND.md) - Find/discover skills in your file system
|
|
13
13
|
- [oasr validate](VALIDATE.md) - Validate a skill
|
|
14
|
-
- [oasr clean](CLEAN.md) - Clean up the registry
|
|
15
14
|
- [oasr adapter](ADAPTER.md) - Generate IDE/Tooling adapters
|
|
16
15
|
- [oasr update](UPDATE.md) - Update the `oasr` CLI
|
|
17
16
|
- [oasr info](INFO.md) - Show detailed information about a skill
|
|
@@ -19,6 +18,9 @@
|
|
|
19
18
|
|
|
20
19
|
## Deprecated Commands
|
|
21
20
|
|
|
21
|
+
### v0.4.1 Deprecations
|
|
22
|
+
- [oasr clean](CLEAN.md) - **Deprecated**, use `oasr registry prune` instead (will be removed in v0.6.0)
|
|
23
|
+
|
|
22
24
|
### v0.4.0 Deprecations
|
|
23
25
|
- [oasr use](USE.md) - **Deprecated**, use `oasr clone` instead (will be removed in v0.5.0)
|
|
24
26
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# `oasr clean` (DEPRECATED)
|
|
2
|
+
|
|
3
|
+
> **⚠️ Warning: This command is deprecated and will be removed in v0.6.0.**
|
|
4
|
+
> Use `oasr registry prune` instead.
|
|
5
|
+
|
|
6
|
+
Remove orphaned manifests and entries for missing skills.
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
oasr clean # Shows deprecation warning
|
|
10
|
+
oasr registry prune # New command (recommended)
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
This command now delegates to `oasr registry prune`. See [REGISTRY.md](./REGISTRY.md#oasr-registry-prune) for full documentation.
|
|
@@ -241,6 +241,63 @@ Configure a different agent:
|
|
|
241
241
|
oasr config set agent copilot
|
|
242
242
|
```
|
|
243
243
|
|
|
244
|
+
## Execution Policy Profiles (v0.5.0+)
|
|
245
|
+
|
|
246
|
+
Policy profiles define security boundaries for `oasr exec`. They control what agents can do during skill execution.
|
|
247
|
+
|
|
248
|
+
### Default Profile
|
|
249
|
+
|
|
250
|
+
Set the default execution policy profile:
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
oasr config set oasr.default_profile safe
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
This determines which profile is used unless overridden with `--profile`.
|
|
257
|
+
|
|
258
|
+
### Defining Custom Profiles
|
|
259
|
+
|
|
260
|
+
Add custom profiles to `~/.oasr/config.toml`:
|
|
261
|
+
|
|
262
|
+
```toml
|
|
263
|
+
[oasr]
|
|
264
|
+
default_profile = "safe"
|
|
265
|
+
|
|
266
|
+
# Conservative default
|
|
267
|
+
[profiles.safe]
|
|
268
|
+
fs_read_roots = ["./"]
|
|
269
|
+
fs_write_roots = ["./out", "./.oasr"]
|
|
270
|
+
deny_paths = ["~/.ssh", "~/.aws", "~/.gnupg", ".env"]
|
|
271
|
+
allowed_commands = ["rg", "fd", "jq", "cat"]
|
|
272
|
+
deny_shell = true
|
|
273
|
+
network = false
|
|
274
|
+
allow_env = false
|
|
275
|
+
|
|
276
|
+
# Development profile (more permissive)
|
|
277
|
+
[profiles.dev]
|
|
278
|
+
fs_read_roots = ["./", "~/projects"]
|
|
279
|
+
fs_write_roots = ["./", "~/projects/output"]
|
|
280
|
+
deny_paths = ["~/.ssh", "~/.aws"]
|
|
281
|
+
allowed_commands = ["bash", "curl", "git", "python"]
|
|
282
|
+
deny_shell = false
|
|
283
|
+
network = true
|
|
284
|
+
allow_env = true
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Profile Settings Reference
|
|
288
|
+
|
|
289
|
+
| Setting | Type | Description |
|
|
290
|
+
|---------|------|-------------|
|
|
291
|
+
| `fs_read_roots` | list[string] | Allowed filesystem read locations |
|
|
292
|
+
| `fs_write_roots` | list[string] | Allowed filesystem write locations |
|
|
293
|
+
| `deny_paths` | list[string] | Explicitly denied paths |
|
|
294
|
+
| `allowed_commands` | list[string] | Permitted shell commands |
|
|
295
|
+
| `deny_shell` | bool | Deny all shell execution |
|
|
296
|
+
| `network` | bool | Allow network access |
|
|
297
|
+
| `allow_env` | bool | Allow environment variable access |
|
|
298
|
+
|
|
299
|
+
See [`oasr exec` documentation](EXEC.md#security-model) for detailed security model explanation.
|
|
300
|
+
|
|
244
301
|
## Advanced Usage
|
|
245
302
|
|
|
246
303
|
### Direct Config File Editing
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Execute skills as CLI tools from anywhere on your system. Run skills with agent-driven execution without needing to clone them first.
|
|
4
4
|
|
|
5
|
+
> **🔒 Security Note**: As of v0.5.0, `oasr exec` includes host-level execution policy enforcement to protect against prompt injection and unsafe agent behavior. See [Security Model](#security-model) below.
|
|
6
|
+
|
|
5
7
|
## Usage
|
|
6
8
|
|
|
7
9
|
```bash
|
|
@@ -13,6 +15,9 @@ oasr exec <skill-name> [options]
|
|
|
13
15
|
- `-p, --prompt TEXT` — Inline prompt/instructions for the agent
|
|
14
16
|
- `-i, --instructions FILE` — Read prompt from a file
|
|
15
17
|
- `-a, --agent AGENT` — Override the default agent (codex, copilot, claude, opencode)
|
|
18
|
+
- `--profile PROFILE` — Use a specific execution policy profile (default: from config)
|
|
19
|
+
- `-y, --yes` — Skip confirmation prompt for risky operations
|
|
20
|
+
- `--confirm` — Force confirmation even for safe operations
|
|
16
21
|
|
|
17
22
|
## Features
|
|
18
23
|
|
|
@@ -311,6 +316,173 @@ This allows skills to:
|
|
|
311
316
|
- Tracking skill versions
|
|
312
317
|
- Working offline
|
|
313
318
|
|
|
319
|
+
## Security Model
|
|
320
|
+
|
|
321
|
+
### Overview
|
|
322
|
+
|
|
323
|
+
OASR enforces **host-level execution policies** to reduce the impact of prompt injection and unsafe agent behavior. Policies define what agents can and cannot do, protecting sensitive files and preventing unauthorized actions.
|
|
324
|
+
|
|
325
|
+
**Key Principles:**
|
|
326
|
+
- OASR does not judge skills
|
|
327
|
+
- OASR enforces user-defined host policy (execution ceilings)
|
|
328
|
+
- Skills and agents cannot override policy
|
|
329
|
+
- Policies stored in `~/.oasr/config.toml`
|
|
330
|
+
- Conservative defaults (fail closed)
|
|
331
|
+
|
|
332
|
+
### Policy Profiles
|
|
333
|
+
|
|
334
|
+
Execution policies are organized into profiles. Each profile defines:
|
|
335
|
+
|
|
336
|
+
| Setting | Description | Safe Default |
|
|
337
|
+
|---------|-------------|--------------|
|
|
338
|
+
| `fs_read_roots` | Allowed read locations | `["./"]` |
|
|
339
|
+
| `fs_write_roots` | Allowed write locations | `["./out", "./.oasr"]` |
|
|
340
|
+
| `deny_paths` | Explicitly denied paths | `["~/.ssh", "~/.aws", "~/.gnupg", ".env"]` |
|
|
341
|
+
| `allowed_commands` | Permitted shell commands | `["rg", "fd", "jq", "cat"]` |
|
|
342
|
+
| `deny_shell` | Block shell execution | `true` |
|
|
343
|
+
| `network` | Allow network access | `false` |
|
|
344
|
+
| `allow_env` | Allow environment access | `false` |
|
|
345
|
+
|
|
346
|
+
### Risk Triggers
|
|
347
|
+
|
|
348
|
+
OASR requires explicit confirmation when:
|
|
349
|
+
|
|
350
|
+
1. **Input from stdin** (non-interactive/piped)
|
|
351
|
+
2. **Prompt from file** (`-i/--instructions`)
|
|
352
|
+
3. **Non-safe profile** in use
|
|
353
|
+
4. **Environment access** enabled
|
|
354
|
+
5. **Network access** enabled
|
|
355
|
+
6. **Shell execution** allowed
|
|
356
|
+
7. **Force confirmation** flag (`--confirm`)
|
|
357
|
+
|
|
358
|
+
### Confirmation Flow
|
|
359
|
+
|
|
360
|
+
When risk triggers are detected:
|
|
361
|
+
|
|
362
|
+
```
|
|
363
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
364
|
+
EXECUTION POLICY REVIEW
|
|
365
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
366
|
+
Skill: csv-analyzer
|
|
367
|
+
Agent: codex
|
|
368
|
+
Profile: safe
|
|
369
|
+
Network: denied
|
|
370
|
+
Environment: denied
|
|
371
|
+
Shell: denied
|
|
372
|
+
Allowed commands: rg, fd, jq, cat
|
|
373
|
+
Read roots: ./
|
|
374
|
+
Write roots: ./out, ./.oasr
|
|
375
|
+
Deny paths: ~/.ssh, ~/.aws, ~/.gnupg, ~/.config, .env
|
|
376
|
+
|
|
377
|
+
⚠ This execution requires confirmation due to:
|
|
378
|
+
- Input from stdin (non-interactive)
|
|
379
|
+
|
|
380
|
+
Proceed? [y/N]
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
**Default answer is No** (safe).
|
|
384
|
+
|
|
385
|
+
### Configuration
|
|
386
|
+
|
|
387
|
+
Define profiles in `~/.oasr/config.toml`:
|
|
388
|
+
|
|
389
|
+
```toml
|
|
390
|
+
[oasr]
|
|
391
|
+
default_profile = "safe"
|
|
392
|
+
|
|
393
|
+
[profiles.safe]
|
|
394
|
+
fs_read_roots = ["./"]
|
|
395
|
+
fs_write_roots = ["./out", "./.oasr"]
|
|
396
|
+
deny_paths = ["~/.ssh", "~/.aws", "~/.gnupg", "~/.config", ".env"]
|
|
397
|
+
allowed_commands = ["rg", "fd", "jq", "cat"]
|
|
398
|
+
deny_shell = true
|
|
399
|
+
network = false
|
|
400
|
+
allow_env = false
|
|
401
|
+
|
|
402
|
+
[profiles.dev]
|
|
403
|
+
# More permissive for development
|
|
404
|
+
network = true
|
|
405
|
+
allow_env = true
|
|
406
|
+
deny_shell = false
|
|
407
|
+
allowed_commands = ["bash", "curl", "git", "python", "node"]
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### Usage Examples
|
|
411
|
+
|
|
412
|
+
#### Safe Default (No Confirmation)
|
|
413
|
+
```bash
|
|
414
|
+
# Interactive prompt, safe profile
|
|
415
|
+
oasr exec csv-analyzer -p "Analyze data"
|
|
416
|
+
# No confirmation needed
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
#### Stdin Triggers Confirmation
|
|
420
|
+
```bash
|
|
421
|
+
# Non-interactive input
|
|
422
|
+
echo "data" | oasr exec csv-analyzer
|
|
423
|
+
# Requires confirmation (unless --yes)
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
#### Skip Confirmation
|
|
427
|
+
```bash
|
|
428
|
+
# Use --yes to bypass (use carefully!)
|
|
429
|
+
echo "data" | oasr exec csv-analyzer --yes
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
#### Use Different Profile
|
|
433
|
+
```bash
|
|
434
|
+
# Use 'dev' profile with more permissions
|
|
435
|
+
oasr exec api-tester -p "Run tests" --profile dev
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
#### Force Confirmation
|
|
439
|
+
```bash
|
|
440
|
+
# Force confirmation even if safe
|
|
441
|
+
oasr exec data-processor -p "Process" --confirm
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
### Best Practices
|
|
445
|
+
|
|
446
|
+
1. **Use safe defaults**: Start with the built-in safe profile
|
|
447
|
+
2. **Create custom profiles**: Define profiles for different trust levels
|
|
448
|
+
3. **Be explicit with --yes**: Only skip confirmation when you understand the risks
|
|
449
|
+
4. **Review policy before confirming**: Read the summary carefully
|
|
450
|
+
5. **Protect sensitive paths**: Always include `~/.ssh`, `~/.aws`, etc. in `deny_paths`
|
|
451
|
+
6. **Limit commands**: Only allow necessary commands in `allowed_commands`
|
|
452
|
+
7. **Use profiles per context**: Different profiles for dev/prod/testing
|
|
453
|
+
|
|
454
|
+
### What This Protects Against
|
|
455
|
+
|
|
456
|
+
✅ **Prompt injection attempts** that try to access sensitive files
|
|
457
|
+
✅ **Unsafe agent behavior** (network calls, shell execution)
|
|
458
|
+
✅ **Accidental exposure** of credentials or secrets
|
|
459
|
+
✅ **Unauthorized file access** outside allowed roots
|
|
460
|
+
✅ **Malicious skill instructions** that exceed policy
|
|
461
|
+
|
|
462
|
+
### What This Does NOT Do
|
|
463
|
+
|
|
464
|
+
❌ NLP-based prompt injection detection
|
|
465
|
+
❌ Prompt rewriting or sanitization
|
|
466
|
+
❌ Skill correctness validation
|
|
467
|
+
❌ Agent-specific permission models
|
|
468
|
+
❌ Plan-gated execution (staged for future)
|
|
469
|
+
|
|
470
|
+
### Limitations
|
|
471
|
+
|
|
472
|
+
- **Confirmation is on execution, not per-action**: Policy is checked before running, not during
|
|
473
|
+
- **Agent behavior is not monitored**: Once confirmed, agent runs with specified permissions
|
|
474
|
+
- **Trust required**: You must trust the agent CLI itself
|
|
475
|
+
- **File-level enforcement not yet implemented**: Path checks are advisory in v0.5.0
|
|
476
|
+
|
|
477
|
+
### Future Enhancements
|
|
478
|
+
|
|
479
|
+
Planned for future releases:
|
|
480
|
+
- Plan-gated execution (structured plan approval)
|
|
481
|
+
- Runtime file access enforcement
|
|
482
|
+
- Command allowlist enforcement via executor
|
|
483
|
+
- Network access controls
|
|
484
|
+
- Real-time policy violations monitoring
|
|
485
|
+
|
|
314
486
|
## Configuration
|
|
315
487
|
|
|
316
488
|
### Set Default Agent
|
|
@@ -105,6 +105,40 @@ Syncing remote skills...
|
|
|
105
105
|
Synced: 2 skills
|
|
106
106
|
```
|
|
107
107
|
|
|
108
|
+
### `oasr registry prune`
|
|
109
|
+
|
|
110
|
+
Clean up corrupted/missing skills and orphaned artifacts:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
oasr registry prune # Interactive cleanup
|
|
114
|
+
oasr registry prune -y # Skip confirmation
|
|
115
|
+
oasr registry prune --dry-run # Show what would be cleaned
|
|
116
|
+
oasr registry prune --json # JSON output
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
This command:
|
|
120
|
+
- Removes skills whose source files/URLs are no longer accessible
|
|
121
|
+
- Removes orphaned manifest files not in the registry
|
|
122
|
+
- Requires confirmation unless `-y` flag is used
|
|
123
|
+
|
|
124
|
+
**Example output:**
|
|
125
|
+
```bash
|
|
126
|
+
$ oasr registry prune
|
|
127
|
+
Checking 3 remote skill(s)...
|
|
128
|
+
↓ python-analyzer (checking GitHub...)
|
|
129
|
+
✓ python-analyzer (checked)
|
|
130
|
+
|
|
131
|
+
The following will be cleaned:
|
|
132
|
+
|
|
133
|
+
Skills with missing sources:
|
|
134
|
+
✗ old-skill (/path/to/missing)
|
|
135
|
+
|
|
136
|
+
Proceed with cleanup? [y/N] y
|
|
137
|
+
Removed skill: old-skill
|
|
138
|
+
|
|
139
|
+
Cleaned 1 skill(s), 0 manifest(s)
|
|
140
|
+
```
|
|
141
|
+
|
|
108
142
|
## Migration from v0.2.0
|
|
109
143
|
|
|
110
144
|
The v0.3.0 CLI taxonomy reorganizes commands under the `registry` subcommand:
|
|
@@ -117,3 +151,5 @@ The v0.3.0 CLI taxonomy reorganizes commands under the `registry` subcommand:
|
|
|
117
151
|
| `oasr status` | `oasr registry -v` |
|
|
118
152
|
| `oasr sync` (manifest validation) | `oasr registry` |
|
|
119
153
|
| `oasr sync --update` (remote sync) | `oasr registry sync` |
|
|
154
|
+
|
|
155
|
+
**v0.4.1 update:** `oasr clean` → `oasr registry prune`
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# OASR Configuration Example
|
|
2
|
+
# Location: ~/.oasr/config.toml
|
|
3
|
+
#
|
|
4
|
+
# This file demonstrates the configuration options for OASR v0.5.0+
|
|
5
|
+
# Copy relevant sections to your own config file.
|
|
6
|
+
|
|
7
|
+
# =============================================================================
|
|
8
|
+
# OASR Settings
|
|
9
|
+
# =============================================================================
|
|
10
|
+
[oasr]
|
|
11
|
+
# Default execution policy profile for 'oasr exec'
|
|
12
|
+
# Options: "safe" (default), or any custom profile name defined below
|
|
13
|
+
default_profile = "safe"
|
|
14
|
+
|
|
15
|
+
# =============================================================================
|
|
16
|
+
# Agent Configuration
|
|
17
|
+
# =============================================================================
|
|
18
|
+
[agent]
|
|
19
|
+
# Default agent for 'oasr exec' command
|
|
20
|
+
# Options: "codex", "copilot", "claude", "opencode", or null
|
|
21
|
+
default = "codex"
|
|
22
|
+
|
|
23
|
+
# =============================================================================
|
|
24
|
+
# Validation Settings
|
|
25
|
+
# =============================================================================
|
|
26
|
+
[validation]
|
|
27
|
+
# Maximum lines to show in skill reference output
|
|
28
|
+
reference_max_lines = 500
|
|
29
|
+
|
|
30
|
+
# Strict validation mode (fail on warnings)
|
|
31
|
+
strict = false
|
|
32
|
+
|
|
33
|
+
# =============================================================================
|
|
34
|
+
# Adapter Settings
|
|
35
|
+
# =============================================================================
|
|
36
|
+
[adapter]
|
|
37
|
+
# Default targets for 'oasr adapter' command
|
|
38
|
+
default_targets = ["cursor", "windsurf"]
|
|
39
|
+
|
|
40
|
+
# =============================================================================
|
|
41
|
+
# Execution Policy Profiles (v0.5.0+)
|
|
42
|
+
# =============================================================================
|
|
43
|
+
# Policy profiles define security boundaries for 'oasr exec'.
|
|
44
|
+
# They control what agents can do during skill execution.
|
|
45
|
+
|
|
46
|
+
# -----------------------------------------------------------------------------
|
|
47
|
+
# Safe Profile (Built-in Default)
|
|
48
|
+
# -----------------------------------------------------------------------------
|
|
49
|
+
# Conservative default with minimal permissions
|
|
50
|
+
[profiles.safe]
|
|
51
|
+
fs_read_roots = ["./"] # Only read from current directory
|
|
52
|
+
fs_write_roots = ["./out", "./.oasr"] # Limited write locations
|
|
53
|
+
deny_paths = [ # Always deny these paths
|
|
54
|
+
"~/.ssh",
|
|
55
|
+
"~/.aws",
|
|
56
|
+
"~/.gnupg",
|
|
57
|
+
"~/.config",
|
|
58
|
+
".env",
|
|
59
|
+
"~/.bashrc",
|
|
60
|
+
"~/.zshrc",
|
|
61
|
+
"~/.profile",
|
|
62
|
+
]
|
|
63
|
+
allowed_commands = ["rg", "fd", "jq", "cat"] # Read-only tools
|
|
64
|
+
deny_shell = true # No shell execution
|
|
65
|
+
network = false # No network access
|
|
66
|
+
allow_env = false # No environment variables
|
|
67
|
+
|
|
68
|
+
# -----------------------------------------------------------------------------
|
|
69
|
+
# Development Profile
|
|
70
|
+
# -----------------------------------------------------------------------------
|
|
71
|
+
# More permissive for development work
|
|
72
|
+
[profiles.dev]
|
|
73
|
+
fs_read_roots = ["./", "~/projects"]
|
|
74
|
+
fs_write_roots = ["./", "~/projects/output", "./build", "./dist"]
|
|
75
|
+
deny_paths = [
|
|
76
|
+
"~/.ssh", # Still protect SSH keys
|
|
77
|
+
"~/.aws", # Still protect AWS credentials
|
|
78
|
+
"~/.gnupg", # Still protect GPG keys
|
|
79
|
+
]
|
|
80
|
+
allowed_commands = [
|
|
81
|
+
"bash", "sh", # Shell access
|
|
82
|
+
"curl", "wget", # Network tools
|
|
83
|
+
"git", # Version control
|
|
84
|
+
"python", "node", "go", # Programming languages
|
|
85
|
+
"npm", "pip", "cargo", # Package managers
|
|
86
|
+
"rg", "fd", "jq", # Search/parse tools
|
|
87
|
+
]
|
|
88
|
+
deny_shell = false # Allow shell commands
|
|
89
|
+
network = true # Allow network access
|
|
90
|
+
allow_env = true # Allow environment variables
|
|
91
|
+
|
|
92
|
+
# -----------------------------------------------------------------------------
|
|
93
|
+
# Testing Profile
|
|
94
|
+
# -----------------------------------------------------------------------------
|
|
95
|
+
# Isolated profile for running tests
|
|
96
|
+
[profiles.test]
|
|
97
|
+
fs_read_roots = ["./tests", "./fixtures", "./test-data"]
|
|
98
|
+
fs_write_roots = ["./test-output", "./coverage", "./.pytest_cache"]
|
|
99
|
+
deny_paths = [
|
|
100
|
+
"~/.ssh",
|
|
101
|
+
"~/.aws",
|
|
102
|
+
"~/", # Deny entire home directory
|
|
103
|
+
]
|
|
104
|
+
allowed_commands = [
|
|
105
|
+
"pytest", "coverage", # Python testing
|
|
106
|
+
"jest", "vitest", # JavaScript testing
|
|
107
|
+
"cargo", "go", # Other language test runners
|
|
108
|
+
"rg", "fd", # Search tools
|
|
109
|
+
]
|
|
110
|
+
deny_shell = true
|
|
111
|
+
network = false # Tests should not need network
|
|
112
|
+
allow_env = false
|
|
113
|
+
|
|
114
|
+
# -----------------------------------------------------------------------------
|
|
115
|
+
# CI/CD Profile
|
|
116
|
+
# -----------------------------------------------------------------------------
|
|
117
|
+
# Profile for continuous integration environments
|
|
118
|
+
[profiles.ci]
|
|
119
|
+
fs_read_roots = ["./", "/tmp/ci"]
|
|
120
|
+
fs_write_roots = ["./build", "./dist", "./coverage", "/tmp/ci"]
|
|
121
|
+
deny_paths = [
|
|
122
|
+
"~/.ssh", # Protect credentials
|
|
123
|
+
"~/.aws", # (CI should use injected secrets)
|
|
124
|
+
]
|
|
125
|
+
allowed_commands = [
|
|
126
|
+
"npm", "yarn", "pnpm",
|
|
127
|
+
"python", "pip",
|
|
128
|
+
"cargo", "go",
|
|
129
|
+
"git",
|
|
130
|
+
"docker", # Container builds
|
|
131
|
+
"kubectl", # Kubernetes
|
|
132
|
+
]
|
|
133
|
+
deny_shell = false
|
|
134
|
+
network = true # May need to fetch dependencies
|
|
135
|
+
allow_env = true # CI environment variables needed
|
|
136
|
+
|
|
137
|
+
# -----------------------------------------------------------------------------
|
|
138
|
+
# Data Analysis Profile
|
|
139
|
+
# -----------------------------------------------------------------------------
|
|
140
|
+
# Profile for data science and analysis tasks
|
|
141
|
+
[profiles.analysis]
|
|
142
|
+
fs_read_roots = ["./data", "./datasets", "./notebooks"]
|
|
143
|
+
fs_write_roots = ["./output", "./reports", "./plots"]
|
|
144
|
+
deny_paths = [
|
|
145
|
+
"~/.ssh",
|
|
146
|
+
"~/.aws",
|
|
147
|
+
"~/.gnupg",
|
|
148
|
+
]
|
|
149
|
+
allowed_commands = [
|
|
150
|
+
"python",
|
|
151
|
+
"jupyter",
|
|
152
|
+
"pandas",
|
|
153
|
+
"rg", "fd",
|
|
154
|
+
]
|
|
155
|
+
deny_shell = false # May need Python subprocess
|
|
156
|
+
network = false # Analysis should be offline
|
|
157
|
+
allow_env = false
|
|
158
|
+
|
|
159
|
+
# -----------------------------------------------------------------------------
|
|
160
|
+
# Production Profile
|
|
161
|
+
# -----------------------------------------------------------------------------
|
|
162
|
+
# Extremely restrictive profile for production use
|
|
163
|
+
[profiles.production]
|
|
164
|
+
fs_read_roots = ["./"]
|
|
165
|
+
fs_write_roots = ["./logs"] # Only write logs
|
|
166
|
+
deny_paths = [
|
|
167
|
+
"~/.ssh",
|
|
168
|
+
"~/.aws",
|
|
169
|
+
"~/.gnupg",
|
|
170
|
+
"~/.config",
|
|
171
|
+
".env",
|
|
172
|
+
"~/",
|
|
173
|
+
]
|
|
174
|
+
allowed_commands = ["rg", "cat"] # Minimal read-only
|
|
175
|
+
deny_shell = true
|
|
176
|
+
network = false
|
|
177
|
+
allow_env = false
|
|
178
|
+
|
|
179
|
+
# =============================================================================
|
|
180
|
+
# Usage Examples
|
|
181
|
+
# =============================================================================
|
|
182
|
+
#
|
|
183
|
+
# Use default profile:
|
|
184
|
+
# oasr exec my-skill -p "prompt"
|
|
185
|
+
#
|
|
186
|
+
# Use specific profile:
|
|
187
|
+
# oasr exec my-skill -p "prompt" --profile dev
|
|
188
|
+
#
|
|
189
|
+
# Skip confirmation (use carefully!):
|
|
190
|
+
# echo "data" | oasr exec my-skill --yes
|
|
191
|
+
#
|
|
192
|
+
# Force confirmation:
|
|
193
|
+
# oasr exec my-skill -p "prompt" --confirm
|
|
194
|
+
#
|
|
195
|
+
# Set default profile:
|
|
196
|
+
# oasr config set oasr.default_profile dev
|
|
197
|
+
#
|
|
198
|
+
# =============================================================================
|
|
199
|
+
# Security Notes
|
|
200
|
+
# =============================================================================
|
|
201
|
+
#
|
|
202
|
+
# 1. Always protect sensitive directories in deny_paths:
|
|
203
|
+
# - ~/.ssh (SSH keys)
|
|
204
|
+
# - ~/.aws (AWS credentials)
|
|
205
|
+
# - ~/.gnupg (GPG keys)
|
|
206
|
+
# - .env (environment secrets)
|
|
207
|
+
#
|
|
208
|
+
# 2. Use the most restrictive profile that works for your use case
|
|
209
|
+
#
|
|
210
|
+
# 3. Create custom profiles for different trust levels:
|
|
211
|
+
# - "safe" for untrusted skills
|
|
212
|
+
# - "dev" for development
|
|
213
|
+
# - "ci" for automation
|
|
214
|
+
# - Custom profiles for specific projects
|
|
215
|
+
#
|
|
216
|
+
# 4. Review policy summary before confirming risky operations
|
|
217
|
+
#
|
|
218
|
+
# 5. Use --yes flag sparingly and only when you understand the risks
|
|
219
|
+
#
|
|
220
|
+
# =============================================================================
|
|
@@ -13,7 +13,7 @@ from pathlib import Path
|
|
|
13
13
|
from commands import adapter, clean, clone, config, diff, exec, find, registry, sync, update, use, validate
|
|
14
14
|
from commands import help as help_cmd
|
|
15
15
|
|
|
16
|
-
__version__ = "0.
|
|
16
|
+
__version__ = "0.5.0"
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
def main(argv: list[str] | None = None) -> int:
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""`asr clean` command - DEPRECATED, use `oasr registry prune` instead."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def register(subparsers) -> None:
|
|
10
|
+
p = subparsers.add_parser(
|
|
11
|
+
"clean",
|
|
12
|
+
help="(Deprecated) Clean up corrupted/missing skills - use 'oasr registry prune'",
|
|
13
|
+
)
|
|
14
|
+
p.add_argument("-y", "--yes", action="store_true", help="Skip confirmation prompt")
|
|
15
|
+
p.add_argument("--json", action="store_true", help="Output in JSON format")
|
|
16
|
+
p.add_argument("--dry-run", action="store_true", help="Show what would be cleaned without doing it")
|
|
17
|
+
p.set_defaults(func=run)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def run(args: argparse.Namespace) -> int:
|
|
21
|
+
"""Delegate to registry prune with deprecation warning."""
|
|
22
|
+
# Show deprecation warning unless --json or --quiet
|
|
23
|
+
if not args.json:
|
|
24
|
+
print("⚠ Warning: 'oasr clean' is deprecated. Use 'oasr registry prune' instead.", file=sys.stderr)
|
|
25
|
+
print(" This command will be removed in v0.6.0.\n", file=sys.stderr)
|
|
26
|
+
|
|
27
|
+
# Delegate to registry prune
|
|
28
|
+
from commands.registry import run_prune
|
|
29
|
+
|
|
30
|
+
return run_prune(args)
|