oasr 0.5.1__py3-none-any.whl → 0.6.0__py3-none-any.whl

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.
completions/zsh.sh ADDED
@@ -0,0 +1,285 @@
1
+ #compdef oasr
2
+ # oasr completion for zsh
3
+ # This file provides tab completion for the oasr command in zsh.
4
+ #
5
+ # Installation:
6
+ # Run: oasr completion install
7
+ # Or manually: Add this file to your fpath and run compinit
8
+
9
+ _oasr_skills() {
10
+ local skills
11
+ skills=(${(f)"$(oasr registry list --quiet 2>/dev/null | grep '^ -' | sed 's/^ - //' | awk '{print $1}')"})
12
+ _describe 'skill' skills
13
+ }
14
+
15
+ _oasr_agents() {
16
+ local agents
17
+ agents=(
18
+ 'codex:OpenAI Codex agent'
19
+ 'copilot:GitHub Copilot agent'
20
+ 'claude:Anthropic Claude agent'
21
+ 'opencode:OpenCode agent'
22
+ )
23
+ _describe 'agent' agents
24
+ }
25
+
26
+ _oasr_profiles() {
27
+ local profiles
28
+ profiles=(${(f)"$(oasr config profiles --names 2>/dev/null)"})
29
+ _describe 'profile' profiles
30
+ }
31
+
32
+ _oasr_config_keys() {
33
+ local keys
34
+ keys=(
35
+ 'agent:Default agent'
36
+ 'profile:Default policy profile'
37
+ 'adapter.default_targets:Default adapter targets'
38
+ 'validation.strict:Strict validation'
39
+ 'validation.reference_max_lines:Reference max lines'
40
+ 'oasr.completions:Enable completions'
41
+ )
42
+ _describe 'config key' keys
43
+ }
44
+
45
+ _oasr_exec() {
46
+ _arguments \
47
+ '--agent[Agent to use]:agent:_oasr_agents' \
48
+ '--profile[Policy profile]:profile:_oasr_profiles' \
49
+ '--agent-flags[Additional agent flags]:flags:' \
50
+ '(-y --yes)'{-y,--yes}'[Skip confirmation]' \
51
+ '--confirm[Force confirmation] \
52
+ --unsafe[Pass unsafe agent flags]' \
53
+ '(-p --prompt)'{-p,--prompt}'[Prompt from file]:file:_files' \
54
+ '1:skill:_oasr_skills'
55
+ }
56
+
57
+ _oasr_clone() {
58
+ _arguments \
59
+ '(-t --target)'{-t,--target}'[Target directory]:directory:_directories' \
60
+ '*:skill:_oasr_skills'
61
+ }
62
+
63
+ _oasr_info() {
64
+ _arguments \
65
+ '--files[Show file list]' \
66
+ '1:skill:_oasr_skills'
67
+ }
68
+
69
+ _oasr_validate() {
70
+ _arguments \
71
+ '*:skill:_oasr_skills'
72
+ }
73
+
74
+ _oasr_config() {
75
+ local -a subcommands
76
+ subcommands=(
77
+ 'set:Set a configuration value'
78
+ 'get:Get a configuration value'
79
+ 'list:List all configuration'
80
+ 'agent:Show agent configuration'
81
+ 'validation:Show validation settings'
82
+ 'adapter:Show adapter settings'
83
+ 'oasr:Show core settings'
84
+ 'profiles:Show profiles'
85
+ 'man:Show config reference'
86
+ 'validate:Validate config file'
87
+ 'path:Show config file path'
88
+ )
89
+
90
+ _arguments -C \
91
+ '1:subcommand:->subcommand' \
92
+ '*::arg:->args'
93
+
94
+ case $state in
95
+ subcommand)
96
+ _describe 'config subcommand' subcommands
97
+ ;;
98
+ args)
99
+ case ${words[1]} in
100
+ set)
101
+ if [ ${#words[@]} -eq 2 ]; then
102
+ _oasr_config_keys
103
+ elif [ ${#words[@]} -eq 3 ]; then
104
+ case ${words[2]} in
105
+ agent)
106
+ _oasr_agents
107
+ ;;
108
+ profile|oasr.default_profile)
109
+ _oasr_profiles
110
+ ;;
111
+ validation.strict|oasr.completions)
112
+ _values 'boolean' true false
113
+ ;;
114
+ validation.reference_max_lines)
115
+ _message 'integer'
116
+ ;;
117
+ adapter.default_targets)
118
+ _message 'comma-separated list'
119
+ ;;
120
+ esac
121
+ fi
122
+ ;;
123
+ get)
124
+ _oasr_config_keys
125
+ ;;
126
+ esac
127
+ ;;
128
+ esac
129
+ }
130
+
131
+ _oasr_profile() {
132
+ _arguments \
133
+ '1:profile:_oasr_profiles'
134
+ }
135
+
136
+ _oasr_registry() {
137
+ local -a subcommands
138
+ subcommands=(
139
+ 'add:Add skill to registry'
140
+ 'rm:Remove skill from registry'
141
+ 'sync:Sync remote skills'
142
+ 'list:List registry skills'
143
+ 'validate:Validate registry'
144
+ 'prune:Clean up registry'
145
+ )
146
+
147
+ _arguments -C \
148
+ '1:subcommand:->subcommand' \
149
+ '*::arg:->args'
150
+
151
+ case $state in
152
+ subcommand)
153
+ _describe 'registry subcommand' subcommands
154
+ ;;
155
+ args)
156
+ case ${words[1]} in
157
+ add)
158
+ _alternative \
159
+ 'directories:directory:_directories' \
160
+ 'urls:url:(http:// https:// git@)'
161
+ ;;
162
+ rm)
163
+ _oasr_skills
164
+ ;;
165
+ prune)
166
+ _arguments '--dry-run[Show what would be removed]'
167
+ ;;
168
+ esac
169
+ ;;
170
+ esac
171
+ }
172
+
173
+ _oasr_completion() {
174
+ local -a shells
175
+ shells=(
176
+ 'bash:Bash completion'
177
+ 'zsh:Zsh completion'
178
+ 'fish:Fish completion'
179
+ 'powershell:PowerShell completion'
180
+ 'install:Auto-detect and install'
181
+ 'uninstall:Remove completions'
182
+ )
183
+
184
+ _arguments \
185
+ '--force[Force reinstall]' \
186
+ '--dry-run[Preview without installing]' \
187
+ '1:shell:->shell'
188
+
189
+ case $state in
190
+ shell)
191
+ _describe 'shell' shells
192
+ ;;
193
+ esac
194
+ }
195
+
196
+ _oasr_adapter() {
197
+ local -a subcommands
198
+ subcommands=(
199
+ 'list:List adapters'
200
+ 'generate:Generate adapter files'
201
+ )
202
+
203
+ _arguments -C \
204
+ '1:subcommand:->subcommand' \
205
+ '*::arg:->args'
206
+
207
+ case $state in
208
+ subcommand)
209
+ _describe 'adapter subcommand' subcommands
210
+ ;;
211
+ esac
212
+ }
213
+
214
+ _oasr() {
215
+ local -a commands
216
+ commands=(
217
+ 'registry:Manage skill registry'
218
+ 'diff:Show tracked skill status'
219
+ 'sync:Refresh tracked skills'
220
+ 'config:Manage configuration'
221
+ 'profile:Select execution profile'
222
+ 'clone:Clone skills to directory'
223
+ 'exec:Execute a skill'
224
+ 'use:DEPRECATED - use clone instead'
225
+ 'find:Find skills recursively'
226
+ 'validate:Validate skills'
227
+ 'clean:Clean up corrupted skills'
228
+ 'adapter:Generate IDE-specific files'
229
+ 'update:Update OASR tool'
230
+ 'info:Show skill information'
231
+ 'help:Show help'
232
+ 'completion:Manage shell completions'
233
+ )
234
+
235
+ _arguments -C \
236
+ '(--help -h)'{--help,-h}'[Show help]' \
237
+ '--version[Show version]' \
238
+ '--config[Config file path]:file:_files' \
239
+ '--json[JSON output]' \
240
+ '--quiet[Suppress warnings]' \
241
+ '1:command:->command' \
242
+ '*::arg:->args'
243
+
244
+ case $state in
245
+ command)
246
+ _describe 'oasr command' commands
247
+ ;;
248
+ args)
249
+ case ${words[1]} in
250
+ exec)
251
+ _oasr_exec
252
+ ;;
253
+ profile)
254
+ _oasr_profile
255
+ ;;
256
+ clone)
257
+ _oasr_clone
258
+ ;;
259
+ info)
260
+ _oasr_info
261
+ ;;
262
+ validate)
263
+ _oasr_validate
264
+ ;;
265
+ config)
266
+ _oasr_config
267
+ ;;
268
+ profile)
269
+ _oasr_profile
270
+ ;;
271
+ registry)
272
+ _oasr_registry
273
+ ;;
274
+ completion)
275
+ _oasr_completion
276
+ ;;
277
+ adapter)
278
+ _oasr_adapter
279
+ ;;
280
+ esac
281
+ ;;
282
+ esac
283
+ }
284
+
285
+ _oasr "$@"
config/__init__.py CHANGED
@@ -14,6 +14,7 @@ import tomli_w
14
14
  from config.defaults import DEFAULT_CONFIG
15
15
  from config.env import load_env_config, merge_configs
16
16
  from config.schema import validate_config
17
+ from profiles.loader import load_profiles
17
18
 
18
19
  OASR_DIR = Path.home() / ".oasr"
19
20
  CONFIG_FILE = OASR_DIR / "config.toml"
@@ -75,6 +76,16 @@ def load_config(config_path: Path | None = None, cli_overrides: dict[str, Any] |
75
76
  with open(path, "rb") as f:
76
77
  file_config = tomllib.load(f)
77
78
 
79
+ if not isinstance(file_config, dict):
80
+ file_config = {}
81
+
82
+ # Merge profile files with inline profiles (inline wins)
83
+ inline_profiles = file_config.get("profiles", {})
84
+ if not isinstance(inline_profiles, dict):
85
+ inline_profiles = {}
86
+ merged_profiles = load_profiles(inline_profiles=inline_profiles)
87
+ file_config["profiles"] = merged_profiles
88
+
78
89
  # Load environment variables
79
90
  env_config = load_env_config()
80
91
 
config/defaults.py CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  from typing import Any
4
4
 
5
+ from profiles.builtins import BUILTIN_PROFILES
6
+
5
7
  DEFAULT_CONFIG: dict[str, Any] = {
6
8
  "validation": {
7
9
  "reference_max_lines": 500,
@@ -15,26 +17,7 @@ DEFAULT_CONFIG: dict[str, Any] = {
15
17
  },
16
18
  "oasr": {
17
19
  "default_profile": "safe",
20
+ "completions": True,
18
21
  },
19
- "profiles": {
20
- # Built-in safe profile (always available as fallback)
21
- "safe": {
22
- "fs_read_roots": ["./"],
23
- "fs_write_roots": ["./out", "./.oasr"],
24
- "deny_paths": [
25
- "~/.ssh",
26
- "~/.aws",
27
- "~/.gnupg",
28
- "~/.config",
29
- ".env",
30
- "~/.bashrc",
31
- "~/.zshrc",
32
- "~/.profile",
33
- ],
34
- "allowed_commands": ["rg", "fd", "jq", "cat"],
35
- "deny_shell": True,
36
- "network": False,
37
- "allow_env": False,
38
- },
39
- },
22
+ "profiles": {name: values.copy() for name, values in BUILTIN_PROFILES.items()},
40
23
  }
config/schema.py CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  from typing import Any
4
4
 
5
+ from profiles.validation import validate_profiles
6
+
5
7
  VALID_AGENTS = {"codex", "copilot", "claude", "opencode"}
6
8
 
7
9
 
@@ -80,32 +82,4 @@ def validate_config(config: dict[str, Any]) -> None:
80
82
  raise ValueError("oasr.default_profile must be a string")
81
83
 
82
84
  if "profiles" in config:
83
- if not isinstance(config["profiles"], dict):
84
- raise ValueError("profiles must be a table (dictionary)")
85
-
86
- # Validate each profile structure
87
- for profile_name, profile_data in config["profiles"].items():
88
- if not isinstance(profile_data, dict):
89
- raise ValueError(f"Profile '{profile_name}' must be a table (dictionary)")
90
-
91
- # Validate profile fields if present
92
- if "fs_read_roots" in profile_data and not isinstance(profile_data["fs_read_roots"], list):
93
- raise ValueError(f"Profile '{profile_name}': fs_read_roots must be a list")
94
-
95
- if "fs_write_roots" in profile_data and not isinstance(profile_data["fs_write_roots"], list):
96
- raise ValueError(f"Profile '{profile_name}': fs_write_roots must be a list")
97
-
98
- if "deny_paths" in profile_data and not isinstance(profile_data["deny_paths"], list):
99
- raise ValueError(f"Profile '{profile_name}': deny_paths must be a list")
100
-
101
- if "allowed_commands" in profile_data and not isinstance(profile_data["allowed_commands"], list):
102
- raise ValueError(f"Profile '{profile_name}': allowed_commands must be a list")
103
-
104
- if "deny_shell" in profile_data and not isinstance(profile_data["deny_shell"], bool):
105
- raise ValueError(f"Profile '{profile_name}': deny_shell must be a boolean")
106
-
107
- if "network" in profile_data and not isinstance(profile_data["network"], bool):
108
- raise ValueError(f"Profile '{profile_name}': network must be a boolean")
109
-
110
- if "allow_env" in profile_data and not isinstance(profile_data["allow_env"], bool):
111
- raise ValueError(f"Profile '{profile_name}': allow_env must be a boolean")
85
+ validate_profiles(config["profiles"])
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oasr
3
- Version: 0.5.1
3
+ Version: 0.6.0
4
4
  Summary: CLI for managing agent skills across IDE integrations
5
5
  Project-URL: Homepage, https://github.com/jgodau/asr
6
6
  Project-URL: Repository, https://github.com/jgodau/asr
@@ -210,6 +210,7 @@ Classifier: Topic :: Software Development :: Build Tools
210
210
  Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
211
211
  Requires-Python: >=3.10
212
212
  Requires-Dist: pyyaml>=6.0
213
+ Requires-Dist: questionary>=2.0.1
213
214
  Requires-Dist: tomli-w>=1.0.0
214
215
  Requires-Dist: tomli>=2.0.0; python_version < '3.11'
215
216
  Provides-Extra: dev
@@ -219,7 +220,7 @@ Description-Content-Type: text/markdown
219
220
 
220
221
  # OASR
221
222
 
222
- **Open Agent Skill Registry** — Manage reusable AI agent skills across IDEs without drift.
223
+ **Open Agent Skill Registry** — Register, sync, and reuse AI agent skills across IDEs with a single source of truth.
223
224
 
224
225
  ---
225
226
 
@@ -229,16 +230,22 @@ You've built useful skills for your AI coding assistant. They work great in Curs
229
230
 
230
231
  Each tool expects skills in different locations with different formats:
231
232
 
232
- - Cursor: `.cursor/skills/`
233
- - Windsurf: `.windsurf/skills/`
233
+ - Cursor: `.cursor/commands/`
234
+ - Windsurf: `.windsurf/workflows/`
234
235
  - Claude: `.claude/commands/`
235
- - Copilot: `.github/.md`
236
+ - Copilot: `.github/prompts/`
236
237
 
237
238
  So you copy your skills everywhere. Then you improve one. Now the copies are stale. You forget which version is current. Some break silently. This is **skill drift**.
238
239
 
239
240
  ## The Solution
240
241
 
241
- ASR keeps your skills in one place and generates thin adapters for each IDE.
242
+ ASR keeps your skills in a registry, syncs local and remote sources, and generates thin adapters for each IDE.
243
+ It also lets you execute skills safely with policy profiles.
244
+
245
+ Key capabilities:
246
+ - Register skills once (local folders or GitHub/GitLab URLs)
247
+ - Sync and track drift across sources
248
+ - Generate IDE adapters and run skills via `oasr exec`
242
249
 
243
250
  ```text
244
251
  ┌─────────────────────────────────────────────────────────┐
@@ -267,12 +274,15 @@ No copying. No drift. One source of truth.
267
274
 
268
275
  ```bash
269
276
  # Register local skills
270
- oasr add ~/skills/git-commit
271
- oasr add ~/skills/code-review
277
+ oasr registry add ~/skills/git-commit
278
+ oasr registry add ~/skills/code-review
279
+
280
+ # List registered skills
281
+ oasr registry list
272
282
 
273
283
  # Register remote skills from GitHub/GitLab
274
- oasr add https://github.com/user/skills-repo/tree/main/my-skill
275
- oasr add https://gitlab.com/org/project/tree/main/cool-skill
284
+ oasr registry add https://github.com/user/skills-repo/tree/main/my-skill
285
+ oasr registry add https://gitlab.com/org/project/tree/main/cool-skill
276
286
 
277
287
  # Generate adapters for a project
278
288
  oasr adapter --output-dir ~/projects/my-app
@@ -294,16 +304,16 @@ ASR supports registering skills directly from GitHub and GitLab repositories:
294
304
 
295
305
  ```bash
296
306
  # Add a skill from GitHub
297
- oasr add https://github.com/user/repo/tree/main/skills/my-skill
307
+ oasr registry add https://github.com/user/repo/tree/main/skills/my-skill
298
308
 
299
309
  # Add a skill from GitLab
300
- oasr add https://gitlab.com/org/project/tree/dev/cool-skill
310
+ oasr registry add https://gitlab.com/org/project/tree/dev/cool-skill
301
311
 
302
312
  # Sync remote skills (check for updates)
303
- oasr sync
313
+ oasr registry sync
304
314
 
305
315
  # Use remote skills
306
- oasr use my-skill -d ./output
316
+ oasr clone my-skill -d ./output
307
317
  ```
308
318
 
309
319
  **Authentication** (optional, for private repos and higher rate limits):
@@ -313,7 +323,27 @@ export GITHUB_TOKEN=ghp_your_token_here
313
323
  export GITLAB_TOKEN=glpat_your_token_here
314
324
  ```
315
325
 
316
- Remote skills are fetched on-demand during `adapter` and `use` operations. The registry stores the URL, and `sync` checks if the remote source has changed.
326
+ Remote skills are fetched on-demand during `adapter` and `clone` operations. The registry stores the URL, and `oasr registry sync` checks if the remote source has changed.
327
+
328
+ ---
329
+
330
+ ## Shell Completions
331
+
332
+ OASR supports intelligent tab completion for Bash, Zsh, Fish, and PowerShell:
333
+
334
+ ```bash
335
+ # Install for your current shell
336
+ oasr completion install
337
+
338
+ # Now try it:
339
+ oasr <TAB> # Complete commands
340
+ oasr info <TAB> # Complete skill names
341
+ oasr exec --<TAB> # Complete flags
342
+ ```
343
+
344
+ Completions are **dynamic** — skill names, agents, and profiles are fetched live from your registry.
345
+
346
+ See [`oasr completion --help`](docs/commands/COMPLETION.md) for details.
317
347
 
318
348
  ---
319
349
 
@@ -325,7 +355,7 @@ Remote skills are fetched on-demand during `adapter` and `use` operations. The r
325
355
 
326
356
  ---
327
357
 
328
- ## Supported `asr adapter` IDEs
358
+ ## Supported `oasr adapter` IDEs
329
359
 
330
360
  | IDE | Adapter | Output |
331
361
  |----------------|------------|-------------------------------|
@@ -347,11 +377,11 @@ See [LICENSE](LICENSE).
347
377
 
348
378
  | Command | Screenshot |
349
379
  |---------|-----------|
350
- | **oasr list** | ![list](docs/.images/list.png) |
351
- | **oasr add** (local) | ![add](docs/.images/add.png) |
352
- | **oasr add** (remote) | ![add-remote](docs/.images/add-remote.png) |
353
- | **oasr sync** | ![sync](docs/.images/sync.png) |
354
- | **oasr status** | ![status](docs/.images/status.png) |
380
+ | **oasr registry list** | ![list](docs/.images/list.png) |
381
+ | **oasr registry add** (local) | ![add](docs/.images/add.png) |
382
+ | **oasr registry add** (remote) | ![add-remote](docs/.images/add-remote.png) |
383
+ | **oasr registry sync** | ![sync](docs/.images/sync.png) |
384
+ | **oasr registry -v** | ![status](docs/.images/status.png) |
355
385
  | **oasr find** | ![find](docs/.images/find.png) |
356
386
  | **oasr adapter** | ![adapter](docs/.images/adapter.png) |
357
387
 
@@ -1,7 +1,7 @@
1
1
  __init__.py,sha256=cYuwXNht5J2GDPEbHz57rmXRyWzaUgAaCXz8okR0rKE,84
2
2
  __main__.py,sha256=Due_Us-4KNlLZhf8MkmoP1hWS5qMWmpZvz2ZaCqPHT4,120
3
3
  adapter.py,sha256=WEpYkKDTb7We0zU9i6Z-r5ydtUdghNhxTZ5Eq58h4fU,10027
4
- cli.py,sha256=xghN20mgfEeh3vR_Vaiv0i2f1MBN6gk8J0uU3kXRK8g,2672
4
+ cli.py,sha256=gJLlOplekDkoFKceG3D5tXZ8m0Jm8tnOu0x9n1y2MW0,2883
5
5
  discovery.py,sha256=WWF8SN2LH88mOUBJLavM7rvXcxi6uDQGpqRK20GysxA,3298
6
6
  manifest.py,sha256=feNCjkFWfhoVubevKjLtKoIEuzT1YGQn6wWgs9XM8_o,12229
7
7
  registry.py,sha256=zGutwVP39xaYqc3KDEXMWCV1tORYpqc5JISO8OaWP1Q,4470
@@ -16,45 +16,59 @@ adapters/copilot.py,sha256=090aS0N7SApSK5kcmm2xErjyUmEsOMrj0n36B0M3fAM,7274
16
16
  adapters/cursor.py,sha256=BoS3Xo_hZyV4zrZKpNjDAaeGmJPTn_j_GI5QXuW5AOo,2244
17
17
  adapters/windsurf.py,sha256=VZidyuFxiHQWl64w0-OgUsfdWeGXV7bf7_XYkiGchyw,2369
18
18
  agents/__init__.py,sha256=Dwdwzb01DM2ZJ5pZBsbLPUYRM4Emai7p3oeayiYcj1w,546
19
- agents/base.py,sha256=ALFkXkKs0IBoZKrEjFoNL_GRa7Wt_DC783UMo-6NOFA,2872
20
- agents/claude.py,sha256=csZ1efZ6GFyaLNHDszKF6hCzJQBiebnx1gmGktpw7DI,676
21
- agents/codex.py,sha256=t7VVVyln_OjbLP1RQzL-x7PJ1C6grVbDCKddI84kre4,674
22
- agents/copilot.py,sha256=kfBk59WXOGd2ZIBBI74kT1WCNH3jFyrOg_HhIkAGG64,697
23
- agents/opencode.py,sha256=fbBAqJhUg0uk6wrhC3SwaE5X27Qej96p9QgVAPpty8w,702
19
+ agents/base.py,sha256=NBBhpJ4KMBLpi8UjGWaKNx9RNJkSxpobDq2LzIa0EYw,3213
20
+ agents/claude.py,sha256=J3LIha5npufT0dD5ZK2eWvM7BZjb615QYHGu-C-pFXI,857
21
+ agents/codex.py,sha256=tYZQEJCLPTxm8zlpwxADyZEbz9EAWmZPrJM3CPRX6lI,853
22
+ agents/copilot.py,sha256=5gieLBlXcpHu6Ci5JZo2QwJoSKeD-Xprb7nCtU3ODXU,878
23
+ agents/opencode.py,sha256=wTUF2_1jaitQkxjs7oRgvpRmdtyOlLBdvLdJRAMdjAw,881
24
24
  agents/registry.py,sha256=i6YUAdNUXq1LNqLDNqSg2RlHxqF5Ig5Z40ryteXoLu4,1434
25
25
  commands/__init__.py,sha256=g_ZxSKLVZwCVAPpn-Ga_gj53BS2473SOg72ivGph--U,147
26
26
  commands/adapter.py,sha256=_68v3t-dRU0mszzL4udKs1bKennyg7RfBTaK2fDGTsE,3215
27
27
  commands/add.py,sha256=NJLQ-8-3zy7o6S9VLfL_wauP-Vz0oNGwN3nvtiwxNYM,15255
28
28
  commands/clean.py,sha256=RQBAfe6iCLsjMqUyVR55JdYX9MBqgrUuIrA8rFKs1J0,1102
29
29
  commands/clone.py,sha256=4APH34-yHjiXQIQwBnKOSEQ_sxV24_GKypcOJMfncvs,5912
30
- commands/config.py,sha256=4kzDEjVpwrmMPK_DPYePdQe2lGh_b8waYORZDHCDYZw,6976
30
+ commands/completion.py,sha256=Y2KshaJ64vI1fcTR5z2KTJT7u9PPK_w8qMf5HK_q9ns,8570
31
+ commands/config.py,sha256=zUh65j4N1R5ikRst18eKCvGFQWnhm7fphu314J9lLpo,15211
31
32
  commands/diff.py,sha256=37JMjvfAEfvK7-4X5iFbD-IGkS8ae4YSY7ZDIZF5B9E,5766
32
- commands/exec.py,sha256=zFmxxclpHQF39sqDpR5436XQiEYo334BGcQ5a8gbR9I,8711
33
+ commands/exec.py,sha256=rO18v7HOcJ9FQ71OHcR4Pplj_YTDD9Z6GxfoWGpK0f0,9518
33
34
  commands/find.py,sha256=zgqwUnaG5aLX6gJIU2ZeQzxsFh2s7oDNNtmV-e-62Jg,1663
34
35
  commands/help.py,sha256=5yhIpgGs1xPs2f39lg-ELE7D0tV_uUTjxQsgkWusIwo,1449
35
36
  commands/info.py,sha256=zywaUQsrvcPXcX8W49P7Jqnr90pX8nBPqnH1XcIs0Uk,4396
36
37
  commands/list.py,sha256=P3E_PItNoqAStNTcLCY7dV-Db2_Yb7TRCYXgP4G19rQ,3185
38
+ commands/profile.py,sha256=bjfdXJ6HeM8NRSsEn4t4kbHxSK0o6M3fHc7Cr9RH90U,2732
37
39
  commands/registry.py,sha256=nerDoR0Uvd_2WlDMQZshJunMW31HsENklAy19A00x4U,16065
38
40
  commands/rm.py,sha256=bOPXgifAbgx7kp4ZuNanJbv4wP1l1sIsI8vD6Rlgi8g,4160
39
41
  commands/status.py,sha256=8si3iEVu0AUE2qojSCVoU0BLwpLm4UiFyY-Ln7Uo36k,3944
40
42
  commands/sync.py,sha256=ZQoB5hBqrzvM6LUQVlKqHQVJib4dB5qe5M-pVG2vtGM,4946
41
- commands/update.py,sha256=bOWjdTNyeYg-hvXv5GfUzEtsTA7gU9JLM592GI9Oq68,11939
43
+ commands/update.py,sha256=gWBBETMxi1ZQ3BV049eAkA_AuCEvvjA9FRzIOBpwdb4,15062
42
44
  commands/use.py,sha256=ggB28g2BDg3Lv3nF40wnDAJ7p0mo6C1pc1KgahvQYXM,1452
43
45
  commands/validate.py,sha256=Y8TLHxW4Z98onmzu-h-kDIET-48lVaIdQXOvuyBemLw,2361
44
- config/__init__.py,sha256=glSjT1_y4aOfhZ8odrUWCGF1hBbY_huTjVp6suepHDY,3647
45
- config/defaults.py,sha256=JfCltQYoE7EqBYlxsNrSITLmwifTvRrJe5lqL0Ys7Cs,986
46
+ completions/__init__.py,sha256=cLGMHifEf91ElOIMSVffVWcifjGZ7oStb0Ot4ivLmmE,41
47
+ completions/bash.sh,sha256=2gk60fm17lPfBddpOvO0c8o0anGmqzbVrtic9pabjnQ,6647
48
+ completions/fish.fish,sha256=N2xXseX2djUNRGDs9TaUNU6YltmNT0PSEK0rYJJSuXc,10160
49
+ completions/powershell.ps1,sha256=m-EsgUpyvg1-wO6Afo2QnmHkzdmBfetDUMgaHn4vlO4,7614
50
+ completions/zsh.sh,sha256=XZRLOEi2_grWACeGiDeucsnyFlKwx_SuU7RMBOPe7Ng,7624
51
+ config/__init__.py,sha256=KcrfpKlWkDqVYooupSqMcfYstUDMpVgdSeOJv38nGS0,4063
52
+ config/defaults.py,sha256=1M5rxaOV-51vKAX_CaUZ8-AFL0vnklqYQeo7BpbOsJ8,525
46
53
  config/env.py,sha256=WgnQXjhfvV7m1oxZCK9WdIX_rqLy_-BOSuPjbpjdI1c,7163
47
- config/schema.py,sha256=VlvmiYWjU2hExBJfME90Oyqp-H4OHcUs_hvvp54K9jA,4498
54
+ config/schema.py,sha256=kQ1EeepRHjjf4dy9y_qRw7DKEEjeTtyvzd2MZLSIAYY,2816
48
55
  policy/__init__.py,sha256=0sPJaruOyc9ioNyIcrTW72RgpaE64FgibS0h5mQELb8,1353
49
- policy/defaults.py,sha256=9GMQM2l2OKTmhXlKwyTfcICR5vD9qEvyvqaR5KrN7ZI,620
56
+ policy/defaults.py,sha256=7DHRzeW79pEPx7x0_8dTmaFz9cpCosmto_yzb-cpMDs,233
50
57
  policy/enforcement.py,sha256=djsosjjfdyr0SjnHF2kz4u3glvMNgd1CJztN6yZE-fM,2749
51
- policy/profile.py,sha256=WDKaUagsWnBPGz5a_OOcxTsdZ66WjaIaR0R7ITVqy8g,6790
58
+ policy/profile.py,sha256=j9C4Ut5Hwa6DotbbFR1ggmDPVmEC4dNMW7D4oxz2kxM,6839
59
+ profiles/__init__.py,sha256=IqlTPlQdKibdLFMbYIk_tpn_B7dmMSnPhN_OJwPzgAo,760
60
+ profiles/builtins.py,sha256=cu3lvUIUZw-OxEYJgGQeDJvQMPuwTnJqxYTOvnf5oiM,1430
61
+ profiles/loader.py,sha256=n6FJm1r_PhAtuCVlIom2I3yqxnTQUryU8b7ggYyUJjI,2487
62
+ profiles/paths.py,sha256=l0TbuVOOLrJBXOR-BAnxxA__2wZ9rHDTNHANTK1xafo,536
63
+ profiles/registry.py,sha256=hkLUXaN-57iAxQtTwnDkHzLrzl3HTJPF44JcBfg_rjg,659
64
+ profiles/summary.py,sha256=jLbmROC4TqyUJgswsn73rJqPkYq0YmAoKKoWxx5XBRg,853
65
+ profiles/validation.py,sha256=J9pZBs9l-PpNmYoRdn43UhA07FSDM8EdGpZMpsTikvY,1920
52
66
  skillcopy/__init__.py,sha256=YUglUkDzKfnCt4ar_DU33ksI9fGyn2UYbV7qn2c_BcU,2322
53
67
  skillcopy/local.py,sha256=QH6484dCenjg8pfNOyTRbQQBklEWhkkTnfQok5ssf_4,1049
54
68
  skillcopy/remote.py,sha256=83jRA2VfjtSDGO-YM1x3WGJjKvWzK1RmSTL7SdUOz8s,3155
55
- oasr-0.5.1.dist-info/METADATA,sha256=fAfdWjbFnZGfRpQ7gJx1IgpKLbaXgpFZz6ddjdzumxc,17924
56
- oasr-0.5.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
57
- oasr-0.5.1.dist-info/entry_points.txt,sha256=VnMuOi6XYMbzAD2bP0X5uV1sQXjOqoDWJ33Lsxwq8u8,52
58
- oasr-0.5.1.dist-info/licenses/LICENSE,sha256=nQ1j9Ldb8FlJ-z7y2WuXPIlyfnYC7YPasjGdOBgcfP4,10561
59
- oasr-0.5.1.dist-info/licenses/NOTICE,sha256=EsfkCN0ZRDS0oj3ADvMKeKrAXaPlC8YfpSjvjGVv9jE,207
60
- oasr-0.5.1.dist-info/RECORD,,
69
+ oasr-0.6.0.dist-info/METADATA,sha256=ueWMiIfDSfj_PC73af_g5NRMgGcVaxiEYU_YM9k-3Fo,18919
70
+ oasr-0.6.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
71
+ oasr-0.6.0.dist-info/entry_points.txt,sha256=VnMuOi6XYMbzAD2bP0X5uV1sQXjOqoDWJ33Lsxwq8u8,52
72
+ oasr-0.6.0.dist-info/licenses/LICENSE,sha256=nQ1j9Ldb8FlJ-z7y2WuXPIlyfnYC7YPasjGdOBgcfP4,10561
73
+ oasr-0.6.0.dist-info/licenses/NOTICE,sha256=EsfkCN0ZRDS0oj3ADvMKeKrAXaPlC8YfpSjvjGVv9jE,207
74
+ oasr-0.6.0.dist-info/RECORD,,
policy/defaults.py CHANGED
@@ -6,22 +6,6 @@ Conservative defaults that fail closed. Used when:
6
6
  - Config parsing errors occur
7
7
  """
8
8
 
9
- # Safe default profile - conservative and restrictive
10
- SAFE = {
11
- "fs_read_roots": ["./"],
12
- "fs_write_roots": ["./out", "./.oasr"],
13
- "deny_paths": [
14
- "~/.ssh",
15
- "~/.aws",
16
- "~/.gnupg",
17
- "~/.config",
18
- ".env",
19
- "~/.bashrc",
20
- "~/.zshrc",
21
- "~/.profile",
22
- ],
23
- "allowed_commands": ["rg", "fd", "jq", "cat"],
24
- "deny_shell": True,
25
- "network": False,
26
- "allow_env": False,
27
- }
9
+ from profiles.builtins import SAFE
10
+
11
+ __all__ = ["SAFE"]