oasr 0.4.0__tar.gz → 0.4.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.
- {oasr-0.4.0 → oasr-0.4.2}/CHANGELOG.md +15 -2
- {oasr-0.4.0 → oasr-0.4.2}/PKG-INFO +1 -1
- {oasr-0.4.0 → oasr-0.4.2}/docs/commands/.INDEX.md +4 -2
- oasr-0.4.2/docs/commands/CLEAN.md +13 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/commands/CLONE.md +0 -1
- {oasr-0.4.0 → oasr-0.4.2}/docs/commands/REGISTRY.md +36 -0
- {oasr-0.4.0 → oasr-0.4.2}/pyproject.toml +1 -1
- {oasr-0.4.0 → oasr-0.4.2}/src/cli.py +1 -1
- oasr-0.4.2/src/commands/clean.py +30 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/commands/exec.py +3 -8
- {oasr-0.4.0 → oasr-0.4.2}/src/commands/registry.py +144 -0
- {oasr-0.4.0 → oasr-0.4.2}/tests/test_exec.py +3 -9
- {oasr-0.4.0 → oasr-0.4.2}/uv.lock +1 -1
- oasr-0.4.0/docs/commands/CLEAN.md +0 -11
- oasr-0.4.0/doctor/SKILL.md +0 -35
- oasr-0.4.0/doctor/assets/schemas/session.schema.yaml +0 -87
- oasr-0.4.0/doctor/assets/schemas/treatment.schema.yaml +0 -70
- oasr-0.4.0/doctor/references/00_ROUTER.md +0 -104
- oasr-0.4.0/doctor/references/01_SUMMARY.md +0 -44
- oasr-0.4.0/doctor/references/02_TRIGGERS.md +0 -40
- oasr-0.4.0/doctor/references/03_ALWAYS.md +0 -43
- oasr-0.4.0/doctor/references/04_NEVER.md +0 -45
- oasr-0.4.0/doctor/references/05_PROCEDURE.md +0 -99
- oasr-0.4.0/doctor/references/06_FAILURES.md +0 -77
- oasr-0.4.0/doctor/scripts/include/.doctor/session.yaml +0 -11
- oasr-0.4.0/doctor/scripts/include/doctor_cli.py +0 -357
- oasr-0.4.0/doctor/scripts/include/doctor_parse.py +0 -348
- oasr-0.4.0/doctor/scripts/include/pyproject.toml +0 -12
- oasr-0.4.0/doctor/scripts/include/uv.lock +0 -78
- oasr-0.4.0/doctor/scripts/router_checks.sh +0 -87
- oasr-0.4.0/doctor/scripts/skill.ps1 +0 -65
- oasr-0.4.0/doctor/scripts/skill.sh +0 -57
- oasr-0.4.0/src/commands/clean.py +0 -155
- {oasr-0.4.0 → oasr-0.4.2}/.gitignore +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/CONTRIBUTING.md +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/LICENSE +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/NOTICE +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/README.md +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/.INDEX.md +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/.images/adapter.png +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/.images/add-glob.png +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/.images/add-remote.png +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/.images/add.png +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/.images/find-add.png +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/.images/find.png +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/.images/help.png +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/.images/info.png +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/.images/list.png +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/.images/rm-glob.png +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/.images/rm.png +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/.images/status.png +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/.images/sync-update.png +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/.images/sync.png +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/.images/use.png +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/QUICKSTART.md +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/commands/ADAPTER.md +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/commands/ADD.md +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/commands/CONFIG.md +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/commands/DIFF.md +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/commands/EXEC.md +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/commands/FIND.md +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/commands/HELP.md +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/commands/INFO.md +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/commands/LIST.md +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/commands/RM.md +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/commands/ROOT.md +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/commands/STATUS.md +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/commands/SYNC.md +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/commands/UPDATE.md +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/commands/USE.md +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/commands/VALIDATE.md +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/validation/.INDEX.md +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/validation/ERRORS.md +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/validation/INFO.md +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/validation/RULES.md +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/docs/validation/WARNINGS.md +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/install.ps1 +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/install.sh +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/llms.txt +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/scripts/README.md +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/scripts/fix.sh +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/scripts/lint.sh +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/scripts/test.sh +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/__init__.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/__main__.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/adapter.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/adapters/__init__.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/adapters/base.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/adapters/claude.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/adapters/codex.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/adapters/copilot.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/adapters/cursor.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/adapters/windsurf.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/agents/__init__.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/agents/base.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/agents/claude.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/agents/codex.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/agents/copilot.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/agents/opencode.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/agents/registry.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/commands/__init__.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/commands/adapter.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/commands/add.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/commands/clone.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/commands/config.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/commands/diff.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/commands/find.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/commands/help.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/commands/info.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/commands/list.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/commands/rm.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/commands/status.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/commands/sync.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/commands/update.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/commands/use.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/commands/validate.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/config/__init__.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/config/defaults.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/config/schema.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/discovery.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/manifest.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/registry.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/remote.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/skillcopy/__init__.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/skillcopy/local.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/skillcopy/remote.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/tracking.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/src/validate.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/tests/conftest.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/tests/test_adapters.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/tests/test_agents.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/tests/test_clone.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/tests/test_config.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/tests/test_config_command.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/tests/test_copy.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/tests/test_help.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/tests/test_list.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/tests/test_multi_skill.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/tests/test_remote.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/tests/test_tracking.py +0 -0
- {oasr-0.4.0 → oasr-0.4.2}/tests/test_use_glob.py +0 -0
|
@@ -4,9 +4,22 @@ 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
|
-
## [
|
|
7
|
+
## [0.4.2] - 2026-02-01
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
### Added
|
|
10
|
+
- **registry prune subcommand**: Added `oasr registry prune` to align with registry command taxonomy
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- **clean command**: Deprecated `oasr clean` in favor of `oasr registry prune` (will be removed in v0.6.0)
|
|
14
|
+
- **documentation**: Updated REGISTRY.md with prune subcommand documentation and usage examples
|
|
15
|
+
|
|
16
|
+
## [0.4.1] - 2026-02-01
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
- **exec command**: Fixed `CompletedProcess` attribute error where code incorrectly referenced `.success`, `.output`, and `.error` attributes that don't exist. Now correctly uses `.returncode`
|
|
20
|
+
- **clone documentation**: Removed non-existent `-r, --recursive` flag from CLONE.md documentation
|
|
21
|
+
|
|
22
|
+
## [0.4.0] - 2026-01-31
|
|
10
23
|
|
|
11
24
|
### Added
|
|
12
25
|
- **🚀 `oasr exec` command** — Execute skills as CLI tools from anywhere
|
|
@@ -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.
|
|
@@ -17,7 +17,6 @@ oasr clone skill-one skill-two # Multiple skills
|
|
|
17
17
|
## Options
|
|
18
18
|
|
|
19
19
|
- `-d, --dest DIR` — Destination directory (default: current directory)
|
|
20
|
-
- `-r, --recursive` — Create destination directory if it doesn't exist
|
|
21
20
|
- `--quiet` — Suppress informational output
|
|
22
21
|
- `--json` — Output results in JSON format
|
|
23
22
|
|
|
@@ -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`
|
|
@@ -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.4.
|
|
16
|
+
__version__ = "0.4.2"
|
|
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)
|
|
@@ -104,14 +104,9 @@ def run(args: argparse.Namespace) -> int:
|
|
|
104
104
|
|
|
105
105
|
try:
|
|
106
106
|
result = driver.execute(skill_content, user_prompt)
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
return 0
|
|
111
|
-
else:
|
|
112
|
-
print("\nError executing skill:", file=sys.stderr)
|
|
113
|
-
print(result.error, file=sys.stderr)
|
|
114
|
-
return 1
|
|
107
|
+
# CompletedProcess has returncode attribute (0 = success)
|
|
108
|
+
# Output was already streamed to stdout since capture_output=False
|
|
109
|
+
return result.returncode
|
|
115
110
|
except Exception as e:
|
|
116
111
|
print(f"\nUnexpected error: {e}", file=sys.stderr)
|
|
117
112
|
return 1
|
|
@@ -64,6 +64,13 @@ def register(subparsers) -> None:
|
|
|
64
64
|
sync_p.add_argument("--config", type=Path, help="Override config file path")
|
|
65
65
|
sync_p.set_defaults(func=run_sync)
|
|
66
66
|
|
|
67
|
+
# registry prune
|
|
68
|
+
prune_p = registry_subparsers.add_parser("prune", help="Clean up corrupted/missing skills and orphaned artifacts")
|
|
69
|
+
prune_p.add_argument("-y", "--yes", action="store_true", help="Skip confirmation prompt")
|
|
70
|
+
prune_p.add_argument("--json", action="store_true", help="Output in JSON format")
|
|
71
|
+
prune_p.add_argument("--dry-run", action="store_true", help="Show what would be cleaned without doing it")
|
|
72
|
+
prune_p.set_defaults(func=run_prune)
|
|
73
|
+
|
|
67
74
|
|
|
68
75
|
def run_validate(args: argparse.Namespace) -> int:
|
|
69
76
|
"""Validate registry manifests (default oasr registry behavior)."""
|
|
@@ -301,3 +308,140 @@ def run_sync(args: argparse.Namespace) -> int:
|
|
|
301
308
|
print(f"{len(pruned)} skill(s) pruned")
|
|
302
309
|
|
|
303
310
|
return 1 if missing_count > 0 else 0
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
def run_prune(args: argparse.Namespace) -> int:
|
|
314
|
+
"""Clean up corrupted/missing skills and orphaned artifacts (oasr registry prune)."""
|
|
315
|
+
from manifest import delete_manifest, list_manifests
|
|
316
|
+
|
|
317
|
+
entries = load_registry()
|
|
318
|
+
registered_names = {e.name for e in entries}
|
|
319
|
+
manifest_names = set(list_manifests())
|
|
320
|
+
|
|
321
|
+
to_remove_skills = []
|
|
322
|
+
to_remove_manifests = []
|
|
323
|
+
|
|
324
|
+
# Check for remote skills and show progress header
|
|
325
|
+
remote_count = 0
|
|
326
|
+
for entry in entries:
|
|
327
|
+
manifest = load_manifest(entry.name)
|
|
328
|
+
if manifest and is_remote_source(manifest.source_path):
|
|
329
|
+
remote_count += 1
|
|
330
|
+
|
|
331
|
+
if remote_count > 0 and not args.json:
|
|
332
|
+
print(f"Checking {remote_count} remote skill(s)...", file=sys.stderr)
|
|
333
|
+
|
|
334
|
+
for entry in entries:
|
|
335
|
+
manifest = load_manifest(entry.name)
|
|
336
|
+
if manifest:
|
|
337
|
+
# Show progress for remote skills
|
|
338
|
+
is_remote = is_remote_source(manifest.source_path)
|
|
339
|
+
if is_remote and not args.json:
|
|
340
|
+
platform = (
|
|
341
|
+
"GitHub"
|
|
342
|
+
if "github.com" in manifest.source_path
|
|
343
|
+
else "GitLab"
|
|
344
|
+
if "gitlab.com" in manifest.source_path
|
|
345
|
+
else "remote"
|
|
346
|
+
)
|
|
347
|
+
print(f" ↓ {entry.name} (checking {platform}...)", file=sys.stderr, flush=True)
|
|
348
|
+
|
|
349
|
+
status = check_manifest(manifest)
|
|
350
|
+
|
|
351
|
+
if is_remote and not args.json:
|
|
352
|
+
print(f" ✓ {entry.name} (checked)", file=sys.stderr)
|
|
353
|
+
|
|
354
|
+
if status.status == "missing":
|
|
355
|
+
to_remove_skills.append(
|
|
356
|
+
{
|
|
357
|
+
"name": entry.name,
|
|
358
|
+
"reason": "source missing",
|
|
359
|
+
"path": entry.path,
|
|
360
|
+
}
|
|
361
|
+
)
|
|
362
|
+
|
|
363
|
+
orphaned = manifest_names - registered_names
|
|
364
|
+
for name in orphaned:
|
|
365
|
+
to_remove_manifests.append(
|
|
366
|
+
{
|
|
367
|
+
"name": name,
|
|
368
|
+
"reason": "orphaned manifest (not in registry)",
|
|
369
|
+
}
|
|
370
|
+
)
|
|
371
|
+
|
|
372
|
+
if not to_remove_skills and not to_remove_manifests:
|
|
373
|
+
if args.json:
|
|
374
|
+
print(json.dumps({"cleaned": 0, "message": "nothing to clean"}))
|
|
375
|
+
else:
|
|
376
|
+
print("Nothing to clean.")
|
|
377
|
+
return 0
|
|
378
|
+
|
|
379
|
+
if args.json:
|
|
380
|
+
result = {
|
|
381
|
+
"skills_to_remove": to_remove_skills,
|
|
382
|
+
"manifests_to_remove": to_remove_manifests,
|
|
383
|
+
"dry_run": args.dry_run,
|
|
384
|
+
}
|
|
385
|
+
if not args.dry_run and not args.yes:
|
|
386
|
+
result["requires_confirmation"] = True
|
|
387
|
+
print(json.dumps(result, indent=2))
|
|
388
|
+
if args.dry_run:
|
|
389
|
+
return 0
|
|
390
|
+
else:
|
|
391
|
+
print("The following will be cleaned:\n")
|
|
392
|
+
|
|
393
|
+
if to_remove_skills:
|
|
394
|
+
print("Skills with missing sources:")
|
|
395
|
+
for s in to_remove_skills:
|
|
396
|
+
print(f" ✗ {s['name']} ({s['path']})")
|
|
397
|
+
|
|
398
|
+
if to_remove_manifests:
|
|
399
|
+
print("\nOrphaned manifests:")
|
|
400
|
+
for m in to_remove_manifests:
|
|
401
|
+
print(f" ✗ {m['name']}")
|
|
402
|
+
|
|
403
|
+
print()
|
|
404
|
+
|
|
405
|
+
if args.dry_run:
|
|
406
|
+
print("(dry run - no changes made)")
|
|
407
|
+
return 0
|
|
408
|
+
|
|
409
|
+
if not args.yes and not args.json:
|
|
410
|
+
try:
|
|
411
|
+
response = input("Proceed with cleanup? [y/N] ").strip().lower()
|
|
412
|
+
if response not in ("y", "yes"):
|
|
413
|
+
print("Aborted.")
|
|
414
|
+
return 1
|
|
415
|
+
except (EOFError, KeyboardInterrupt):
|
|
416
|
+
print("\nAborted.")
|
|
417
|
+
return 1
|
|
418
|
+
|
|
419
|
+
removed_skills = []
|
|
420
|
+
removed_manifests = []
|
|
421
|
+
|
|
422
|
+
for s in to_remove_skills:
|
|
423
|
+
remove_skill(s["name"])
|
|
424
|
+
removed_skills.append(s["name"])
|
|
425
|
+
|
|
426
|
+
for m in to_remove_manifests:
|
|
427
|
+
delete_manifest(m["name"])
|
|
428
|
+
removed_manifests.append(m["name"])
|
|
429
|
+
|
|
430
|
+
if args.json:
|
|
431
|
+
print(
|
|
432
|
+
json.dumps(
|
|
433
|
+
{
|
|
434
|
+
"removed_skills": removed_skills,
|
|
435
|
+
"removed_manifests": removed_manifests,
|
|
436
|
+
},
|
|
437
|
+
indent=2,
|
|
438
|
+
)
|
|
439
|
+
)
|
|
440
|
+
else:
|
|
441
|
+
for name in removed_skills:
|
|
442
|
+
print(f"Removed skill: {name}")
|
|
443
|
+
for name in removed_manifests:
|
|
444
|
+
print(f"Removed manifest: {name}")
|
|
445
|
+
print(f"\nCleaned {len(removed_skills)} skill(s), {len(removed_manifests)} manifest(s)")
|
|
446
|
+
|
|
447
|
+
return 0
|
|
@@ -107,8 +107,7 @@ class TestExecCommand:
|
|
|
107
107
|
)
|
|
108
108
|
|
|
109
109
|
mock_result = mock.Mock()
|
|
110
|
-
mock_result.
|
|
111
|
-
mock_result.output = "Agent output here"
|
|
110
|
+
mock_result.returncode = 0 # Success
|
|
112
111
|
|
|
113
112
|
mock_driver = mock.Mock()
|
|
114
113
|
mock_driver.execute.return_value = mock_result
|
|
@@ -122,7 +121,6 @@ class TestExecCommand:
|
|
|
122
121
|
|
|
123
122
|
assert result == 0
|
|
124
123
|
captured = capsys.readouterr()
|
|
125
|
-
assert "Agent output here" in captured.out
|
|
126
124
|
assert "Executing skill 'test-skill' with codex" in captured.err
|
|
127
125
|
|
|
128
126
|
# Verify driver was called with skill content and prompt
|
|
@@ -143,8 +141,7 @@ class TestExecCommand:
|
|
|
143
141
|
)
|
|
144
142
|
|
|
145
143
|
mock_result = mock.Mock()
|
|
146
|
-
mock_result.
|
|
147
|
-
mock_result.error = "Agent failed with error"
|
|
144
|
+
mock_result.returncode = 1 # Failure
|
|
148
145
|
|
|
149
146
|
mock_driver = mock.Mock()
|
|
150
147
|
mock_driver.execute.return_value = mock_result
|
|
@@ -157,8 +154,6 @@ class TestExecCommand:
|
|
|
157
154
|
result = exec_cmd.run(args)
|
|
158
155
|
|
|
159
156
|
assert result == 1
|
|
160
|
-
captured = capsys.readouterr()
|
|
161
|
-
assert "Agent failed with error" in captured.err
|
|
162
157
|
|
|
163
158
|
def test_exec_with_explicit_agent(self, capsys, mock_registry):
|
|
164
159
|
"""Test exec with explicit agent flag."""
|
|
@@ -172,8 +167,7 @@ class TestExecCommand:
|
|
|
172
167
|
)
|
|
173
168
|
|
|
174
169
|
mock_result = mock.Mock()
|
|
175
|
-
mock_result.
|
|
176
|
-
mock_result.output = "Success"
|
|
170
|
+
mock_result.returncode = 0 # Success
|
|
177
171
|
|
|
178
172
|
mock_driver = mock.Mock()
|
|
179
173
|
mock_driver.execute.return_value = mock_result
|
oasr-0.4.0/doctor/SKILL.md
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: doctor
|
|
3
|
-
license: MIT
|
|
4
|
-
description: 'Diagnoses software failures by combining deterministic evidence gathering
|
|
5
|
-
with agent judgment. Models failures as medical cases. Idempotent — run repeatedly
|
|
6
|
-
until confident diagnosis, then generate schema-based treatment.
|
|
7
|
-
|
|
8
|
-
'
|
|
9
|
-
metadata:
|
|
10
|
-
author: Jordan Godau
|
|
11
|
-
version: 0.2.0
|
|
12
|
-
references:
|
|
13
|
-
- 00_ROUTER.md
|
|
14
|
-
- 01_SUMMARY.md
|
|
15
|
-
- 02_TRIGGERS.md
|
|
16
|
-
- 03_ALWAYS.md
|
|
17
|
-
- 04_NEVER.md
|
|
18
|
-
- 05_PROCEDURE.md
|
|
19
|
-
- 06_FAILURES.md
|
|
20
|
-
keywords:
|
|
21
|
-
- diagnose
|
|
22
|
-
- debug
|
|
23
|
-
- investigate
|
|
24
|
-
- evidence
|
|
25
|
-
- hypothesis
|
|
26
|
-
- treatment
|
|
27
|
-
oasr:
|
|
28
|
-
hash: sha256:f9fda45b7797923e9379e36c1b519c40b09f05f78bfa172a9d006c14b7283535
|
|
29
|
-
source: /home/jgodau/work/personal/skills/doctor/doctor
|
|
30
|
-
synced: '2026-02-01T06:35:54.685306Z'
|
|
31
|
-
---
|
|
32
|
-
|
|
33
|
-
# INSTRUCTIONS
|
|
34
|
-
|
|
35
|
-
1. Refer to `metadata.references`.
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
# Doctor Session Schema
|
|
2
|
-
# Artifact: .doctor/session.yaml
|
|
3
|
-
|
|
4
|
-
type: object
|
|
5
|
-
required:
|
|
6
|
-
- status
|
|
7
|
-
- created_at
|
|
8
|
-
|
|
9
|
-
properties:
|
|
10
|
-
status:
|
|
11
|
-
type: string
|
|
12
|
-
enum: [investigating, diagnosed, treated, abandoned]
|
|
13
|
-
description: Current session status
|
|
14
|
-
|
|
15
|
-
created_at:
|
|
16
|
-
type: string
|
|
17
|
-
format: date-time
|
|
18
|
-
description: RFC3339 UTC timestamp
|
|
19
|
-
|
|
20
|
-
updated_at:
|
|
21
|
-
type: string
|
|
22
|
-
format: date-time
|
|
23
|
-
description: RFC3339 UTC timestamp of last update
|
|
24
|
-
|
|
25
|
-
patient:
|
|
26
|
-
type: string
|
|
27
|
-
description: Repository or system name
|
|
28
|
-
|
|
29
|
-
symptoms:
|
|
30
|
-
type: array
|
|
31
|
-
items:
|
|
32
|
-
type: object
|
|
33
|
-
properties:
|
|
34
|
-
description:
|
|
35
|
-
type: string
|
|
36
|
-
category:
|
|
37
|
-
type: string
|
|
38
|
-
enum: [error, timeout, crash, wrong_output, performance, unknown]
|
|
39
|
-
evidence:
|
|
40
|
-
type: string
|
|
41
|
-
description: Observed symptoms
|
|
42
|
-
|
|
43
|
-
hypotheses:
|
|
44
|
-
type: array
|
|
45
|
-
items:
|
|
46
|
-
type: object
|
|
47
|
-
properties:
|
|
48
|
-
description:
|
|
49
|
-
type: string
|
|
50
|
-
confidence:
|
|
51
|
-
type: integer
|
|
52
|
-
minimum: 0
|
|
53
|
-
maximum: 100
|
|
54
|
-
evidence_for:
|
|
55
|
-
type: array
|
|
56
|
-
items:
|
|
57
|
-
type: string
|
|
58
|
-
evidence_against:
|
|
59
|
-
type: array
|
|
60
|
-
items:
|
|
61
|
-
type: string
|
|
62
|
-
falsifiable_by:
|
|
63
|
-
type: string
|
|
64
|
-
description: Working hypotheses with confidence
|
|
65
|
-
|
|
66
|
-
diagnosis:
|
|
67
|
-
type: object
|
|
68
|
-
properties:
|
|
69
|
-
summary:
|
|
70
|
-
type: string
|
|
71
|
-
confidence:
|
|
72
|
-
type: integer
|
|
73
|
-
minimum: 0
|
|
74
|
-
maximum: 100
|
|
75
|
-
root_cause:
|
|
76
|
-
type: string
|
|
77
|
-
contributing_factors:
|
|
78
|
-
type: array
|
|
79
|
-
items:
|
|
80
|
-
type: string
|
|
81
|
-
description: Final diagnosis (when confident)
|
|
82
|
-
|
|
83
|
-
evidence_files:
|
|
84
|
-
type: array
|
|
85
|
-
items:
|
|
86
|
-
type: string
|
|
87
|
-
description: Paths to evidence snapshots in .doctor/evidence/
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
# Treatment Plan Schema
|
|
2
|
-
# Artifact: .doctor/treatment.md (generated from this schema)
|
|
3
|
-
|
|
4
|
-
type: object
|
|
5
|
-
required:
|
|
6
|
-
- diagnosis_summary
|
|
7
|
-
- confidence
|
|
8
|
-
- options
|
|
9
|
-
|
|
10
|
-
properties:
|
|
11
|
-
diagnosis_summary:
|
|
12
|
-
type: string
|
|
13
|
-
description: One-line diagnosis
|
|
14
|
-
|
|
15
|
-
confidence:
|
|
16
|
-
type: integer
|
|
17
|
-
minimum: 0
|
|
18
|
-
maximum: 100
|
|
19
|
-
description: Diagnosis confidence percentage
|
|
20
|
-
|
|
21
|
-
root_cause:
|
|
22
|
-
type: string
|
|
23
|
-
description: Identified root cause
|
|
24
|
-
|
|
25
|
-
options:
|
|
26
|
-
type: array
|
|
27
|
-
minItems: 1
|
|
28
|
-
items:
|
|
29
|
-
type: object
|
|
30
|
-
required:
|
|
31
|
-
- name
|
|
32
|
-
- description
|
|
33
|
-
- risk
|
|
34
|
-
properties:
|
|
35
|
-
name:
|
|
36
|
-
type: string
|
|
37
|
-
description: Short option name
|
|
38
|
-
description:
|
|
39
|
-
type: string
|
|
40
|
-
description: What this option does
|
|
41
|
-
risk:
|
|
42
|
-
type: string
|
|
43
|
-
enum: [low, medium, high]
|
|
44
|
-
effort:
|
|
45
|
-
type: string
|
|
46
|
-
enum: [trivial, small, medium, large]
|
|
47
|
-
reversible:
|
|
48
|
-
type: boolean
|
|
49
|
-
steps:
|
|
50
|
-
type: array
|
|
51
|
-
items:
|
|
52
|
-
type: string
|
|
53
|
-
description: Ordered implementation steps
|
|
54
|
-
description: Treatment options (at least one required)
|
|
55
|
-
|
|
56
|
-
recommended:
|
|
57
|
-
type: string
|
|
58
|
-
description: Name of recommended option
|
|
59
|
-
|
|
60
|
-
caveats:
|
|
61
|
-
type: array
|
|
62
|
-
items:
|
|
63
|
-
type: string
|
|
64
|
-
description: Warnings or considerations
|
|
65
|
-
|
|
66
|
-
follow_up:
|
|
67
|
-
type: array
|
|
68
|
-
items:
|
|
69
|
-
type: string
|
|
70
|
-
description: Suggested follow-up actions
|