code-agnostic 0.3.11__tar.gz → 0.3.13__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.
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/PKG-INFO +31 -17
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/README.md +30 -16
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/__init__.py +1 -1
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/__main__.py +3 -1
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/agents/opencode.py +7 -2
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/codex/config_repository.py +17 -2
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/codex/schema.json +34 -24
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/opencode/config_repository.py +18 -5
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/opencode/schema.json +65 -38
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/cli/commands/agents.py +2 -1
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/cli/commands/apps.py +3 -1
- code_agnostic-0.3.13/code_agnostic/cli/commands/projects.py +78 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/cli/commands/rules.py +2 -1
- code_agnostic-0.3.13/code_agnostic/cli/commands/skills.py +192 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/cli/commands/status.py +20 -2
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/cli/helpers.py +13 -1
- code_agnostic-0.3.13/code_agnostic/core/project_repository.py +10 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/core/repository.py +90 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/executor.py +122 -41
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/imports/service.py +70 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/mcp_service.py +10 -3
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/models.py +15 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/planner.py +143 -1
- code_agnostic-0.3.13/code_agnostic/project_artifacts.py +39 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/skills/compilers.py +8 -1
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/status.py +98 -1
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/tui/renderers.py +105 -31
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/tui/tables.py +39 -3
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/workspace_artifacts.py +1 -1
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic.egg-info/PKG-INFO +31 -17
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic.egg-info/SOURCES.txt +5 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/pyproject.toml +1 -1
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_cli_agents.py +15 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_cli_apply_target.py +4 -4
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_cli_apps.py +2 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_cli_mcp.py +33 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_cli_module_organization.py +1 -1
- code_agnostic-0.3.13/tests/test_cli_projects.py +227 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_cli_rules.py +15 -0
- code_agnostic-0.3.13/tests/test_cli_skills.py +334 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_cli_status.py +13 -1
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_cli_workspaces.py +3 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_planner_executor.py +17 -9
- code_agnostic-0.3.13/tests/test_project_config_sync.py +242 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_workspace_config_sync.py +58 -4
- code_agnostic-0.3.11/code_agnostic/cli/commands/skills.py +0 -70
- code_agnostic-0.3.11/tests/test_cli_skills.py +0 -96
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/LICENSE +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/agents/__init__.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/agents/claude.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/agents/codex.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/agents/compilers.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/agents/models.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/agents/parser.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/__init__.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/app_id.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/apps_service.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/claude/__init__.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/claude/config_repository.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/claude/mapper.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/claude/service.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/codex/__init__.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/codex/mapper.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/codex/schema_repository.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/codex/service.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/common/__init__.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/common/compiled_planning.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/common/framework.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/common/interfaces/__init__.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/common/interfaces/mapper.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/common/interfaces/repositories.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/common/interfaces/service.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/common/loader.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/common/models.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/common/schema.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/common/symlink_planning.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/common/utils.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/cursor/__init__.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/cursor/config_repository.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/cursor/mapper.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/cursor/schema.json +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/cursor/schema_repository.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/cursor/service.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/opencode/__init__.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/opencode/mapper.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/opencode/schema_repository.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/opencode/service.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/cli/__init__.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/cli/aliases.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/cli/commands/__init__.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/cli/commands/apply.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/cli/commands/explain_lossiness.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/cli/commands/import_.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/cli/commands/mcp.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/cli/commands/plan.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/cli/commands/restore.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/cli/commands/validate.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/cli/commands/workspaces.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/cli/options.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/constants.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/core/__init__.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/core/workspace_repository.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/errors.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/generated_artifacts.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/git_exclude_service.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/imports/__init__.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/imports/adapters.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/imports/filesystem.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/imports/models.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/lossiness.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/rules/__init__.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/rules/compilers.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/rules/models.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/rules/parser.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/rules/repository.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/skills/__init__.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/skills/models.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/skills/parser.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/spec/__init__.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/spec/loaders.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/spec/schemas/agent.v1.schema.json +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/spec/schemas/mcp.base.schema.json +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/spec/schemas/mcp.v1.schema.json +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/spec/schemas/rule.v1.schema.json +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/spec/schemas/skill.v1.schema.json +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/tui/__init__.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/tui/enums.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/tui/import_selector.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/tui/sections.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/utils.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/validation.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/workspaces.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic.egg-info/dependency_links.txt +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic.egg-info/entry_points.txt +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic.egg-info/requires.txt +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic.egg-info/top_level.txt +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/setup.cfg +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_cli_aliases.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_cli_apply_apps.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_cli_apply_codex.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_cli_apply_cursor.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_cli_explain_lossiness.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_cli_flags.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_cli_git_exclude.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_cli_import.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_cli_import_interactive.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_cli_plan.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_cli_restore.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_cli_validate.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_cli_workspace_resolution.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_common_mcp_to_dto.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_common_repository.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_compiled_planning.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_dto_to_common_mcp.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_git_exclude_service.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_mcp_service.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_planner_rules.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_symlink_planning.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_sync_plan_model.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_transactional_executor.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_utils.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_version.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_workspace_repo_status.py +0 -0
- {code_agnostic-0.3.11 → code_agnostic-0.3.13}/tests/test_workspaces.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code-agnostic
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.13
|
|
4
4
|
Summary: Centralized hub for LLM coding config: MCP, skills, rules, and agents.
|
|
5
5
|
Requires-Python: >=3.10
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -54,7 +54,7 @@ AI coding tools each want config in a different place and format. When you use m
|
|
|
54
54
|
|
|
55
55
|
~/.config/opencode/ Compiled & synced for OpenCode
|
|
56
56
|
~/.cursor/ Compiled & synced for Cursor
|
|
57
|
-
~/.codex/ Compiled & synced for Codex
|
|
57
|
+
~/.codex/ Compiled & synced for Codex (or CODEX_HOME)
|
|
58
58
|
~/.claude.json and ~/.claude/ Compiled & synced for Claude Code
|
|
59
59
|
```
|
|
60
60
|
|
|
@@ -66,18 +66,19 @@ Today the implementation is still mixed: some assets are compiled and some are s
|
|
|
66
66
|
|
|
67
67
|
## Scope model
|
|
68
68
|
|
|
69
|
-
`code-agnostic` has
|
|
69
|
+
`code-agnostic` has three managed source scopes:
|
|
70
70
|
|
|
71
71
|
- global source config under `~/.config/code-agnostic/`, synced to enabled
|
|
72
72
|
user-level app config;
|
|
73
73
|
- workspace source config under `~/.config/code-agnostic/workspaces/<name>/`,
|
|
74
|
-
propagated into repos inside a registered workspace
|
|
74
|
+
propagated into repos inside a registered workspace;
|
|
75
|
+
- project source config under `~/.config/code-agnostic/projects/<name>/`,
|
|
76
|
+
synced to exactly one registered project directory.
|
|
75
77
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
without bypassing the hub.
|
|
78
|
+
Workspace sync may generate repo-local outputs, but those outputs are not
|
|
79
|
+
source. Project-local skill folders generated inside a repo, such as
|
|
80
|
+
`.agents/skills` or `.opencode/skills`, are also generated outputs; install
|
|
81
|
+
skills into managed project source first, then run `plan` / `apply`.
|
|
81
82
|
|
|
82
83
|
## Install
|
|
83
84
|
|
|
@@ -142,9 +143,9 @@ that are omitted or rejected for a selected target.
|
|
|
142
143
|
|
|
143
144
|
Cursor workspace propagation writes repo-local MCP, skills, and agents when those resources exist in the workspace source config.
|
|
144
145
|
|
|
145
|
-
OpenCode workspace configs include the shared workspace `AGENTS.md` natively via `instructions`, so repos under the workspace get both repo-local and shared workspace instructions. Codex repos receive workspace instructions through a generated `AGENTS.override.md`, which is added to each repo's `.git/info/exclude`. Claude Code receives workspace instructions through generated `CLAUDE.local.md` files, never by editing committed `CLAUDE.md`.
|
|
146
|
+
OpenCode workspace configs write project-root `opencode.json` files that include the shared workspace `AGENTS.md` natively via `instructions`, so repos under the workspace get both repo-local and shared workspace instructions. Codex repos receive workspace instructions through a generated `AGENTS.override.md`, which is added to each repo's `.git/info/exclude`. Claude Code receives workspace instructions through generated `CLAUDE.local.md` files, never by editing committed `CLAUDE.md`.
|
|
146
147
|
|
|
147
|
-
Cursor documents `AGENTS.md` support in project roots and subdirectories. `code-agnostic` does not copy or link the shared workspace `AGENTS.md` into child repos; Cursor will load
|
|
148
|
+
Cursor documents `AGENTS.md` support in project roots and subdirectories. `code-agnostic` does not copy or link the shared workspace `AGENTS.md` into child repos; Cursor will load `AGENTS.md` files that already exist in the opened project. Codex documents nested `AGENTS.md` discovery, but not a native config include for an extra workspace file.
|
|
148
149
|
|
|
149
150
|
## Features
|
|
150
151
|
|
|
@@ -229,16 +230,27 @@ code-agnostic skills list
|
|
|
229
230
|
code-agnostic agents list
|
|
230
231
|
```
|
|
231
232
|
|
|
232
|
-
|
|
233
|
+
Install a local skill directory into managed source:
|
|
233
234
|
|
|
234
235
|
```bash
|
|
235
|
-
|
|
236
|
-
|
|
236
|
+
code-agnostic skills install ./my-skill --global
|
|
237
|
+
code-agnostic skills install ./my-skill --workspace myworkspace
|
|
238
|
+
code-agnostic projects add --name myproject --path .
|
|
239
|
+
code-agnostic skills install ./my-skill --project myproject
|
|
237
240
|
code-agnostic plan
|
|
238
241
|
code-agnostic apply
|
|
239
242
|
```
|
|
240
243
|
|
|
241
|
-
Global skills live under `~/.config/code-agnostic/skills`. Workspace-local
|
|
244
|
+
Global skills live under `~/.config/code-agnostic/skills`. Workspace-local
|
|
245
|
+
skills live under `~/.config/code-agnostic/workspaces/<name>/skills` and can be
|
|
246
|
+
inspected with `code-agnostic skills list -w <name>`. Project-local skills live
|
|
247
|
+
under `~/.config/code-agnostic/projects/<name>/skills` and are generated into
|
|
248
|
+
the registered project directory by `plan` / `apply`. Codex generated skill
|
|
249
|
+
outputs are written to `~/.agents/skills`, while Codex agents and config remain
|
|
250
|
+
under `CODEX_HOME` when set, defaulting to `~/.codex`. Claude Code generated
|
|
251
|
+
skills and agents are written under `~/.claude/skills` and `~/.claude/agents`,
|
|
252
|
+
with workspace/project copies under repo-local `.claude/skills` and
|
|
253
|
+
`.claude/agents`.
|
|
242
254
|
|
|
243
255
|
Project-local skills are not first-class source inputs in `code-agnostic` yet. If a target app discovers repo-local skill folders such as `.agents/skills`, `.opencode/skills`, or user-created `.claude/skills`, treat those as unmanaged app inputs. Workspace sync writes only the exact generated paths recorded in `.sync-state.json`.
|
|
244
256
|
|
|
@@ -249,10 +261,12 @@ code-agnostic skills install ./my-skill --apply
|
|
|
249
261
|
```
|
|
250
262
|
|
|
251
263
|
That command should copy the skill into the source of truth and then run the normal compiler/apply flow.
|
|
264
|
+
See [docs/project-scoped-skills.md](docs/project-scoped-skills.md) for the
|
|
265
|
+
first implementation slice.
|
|
252
266
|
|
|
253
267
|
### Workspaces
|
|
254
268
|
|
|
255
|
-
Register workspace directories. Workspace rules are compiled into a canonical `AGENTS.md` at the workspace root. Repos keep their own repo-specific `AGENTS.md`; Codex receives the workspace rules through generated, git-excluded `AGENTS.override.md` files, while OpenCode workspace configs reference the shared workspace file through `instructions`. Claude receives generated `CLAUDE.local.md` files and project MCP entries in `~/.claude.json["projects"][absolute_repo_path]["mcpServers"]`. Workspace source config, skills, and agents are propagated into repo-local generated paths for OpenCode, Cursor, Codex, and Claude; user-created project-local skill folders remain unmanaged until project-scoped installs are supported.
|
|
269
|
+
Register workspace directories. Workspace rules are compiled into a canonical `AGENTS.md` at the workspace root. Repos keep their own repo-specific `AGENTS.md`; Codex receives the workspace rules through generated, git-excluded `AGENTS.override.md` files, while OpenCode workspace configs write project-root `opencode.json` files that reference the shared workspace file through `instructions`. Claude receives generated `CLAUDE.local.md` files and project MCP entries in `~/.claude.json["projects"][absolute_repo_path]["mcpServers"]`. Workspace source config, skills, and agents are propagated into repo-local generated paths for OpenCode, Cursor, Codex, and Claude; user-created project-local skill folders remain unmanaged until project-scoped installs are supported.
|
|
256
270
|
|
|
257
271
|
Cursor propagation intentionally stays to repo-local MCP, skills, and agents; it does not copy the shared workspace `AGENTS.md` into child repos.
|
|
258
272
|
|
|
@@ -316,12 +330,12 @@ The compiler migration is documented in:
|
|
|
316
330
|
- [x] MCP add/remove/list commands
|
|
317
331
|
- [x] Rules system with YAML frontmatter and per-editor compilation
|
|
318
332
|
- [x] Cross-compilation for skills and agents
|
|
333
|
+
- [x] Planner integration for cross-compiled skills and agents
|
|
319
334
|
- [x] Per-workspace git-exclude customization
|
|
320
335
|
- [x] Interactive TUI for import selection
|
|
321
336
|
- [x] Claude Code support
|
|
322
337
|
- [ ] Project-scoped skill installs and sync
|
|
323
338
|
- [ ] `rules add` / `skills add` / `agents add` commands (open `$EDITOR` with template)
|
|
324
|
-
- [ ] Planner integration for cross-compiled skills and agents
|
|
325
339
|
- [ ] Shell auto-complete
|
|
326
340
|
- [ ] Full TUI mode (command palette + menus)
|
|
327
341
|
|
|
@@ -29,7 +29,7 @@ AI coding tools each want config in a different place and format. When you use m
|
|
|
29
29
|
|
|
30
30
|
~/.config/opencode/ Compiled & synced for OpenCode
|
|
31
31
|
~/.cursor/ Compiled & synced for Cursor
|
|
32
|
-
~/.codex/ Compiled & synced for Codex
|
|
32
|
+
~/.codex/ Compiled & synced for Codex (or CODEX_HOME)
|
|
33
33
|
~/.claude.json and ~/.claude/ Compiled & synced for Claude Code
|
|
34
34
|
```
|
|
35
35
|
|
|
@@ -41,18 +41,19 @@ Today the implementation is still mixed: some assets are compiled and some are s
|
|
|
41
41
|
|
|
42
42
|
## Scope model
|
|
43
43
|
|
|
44
|
-
`code-agnostic` has
|
|
44
|
+
`code-agnostic` has three managed source scopes:
|
|
45
45
|
|
|
46
46
|
- global source config under `~/.config/code-agnostic/`, synced to enabled
|
|
47
47
|
user-level app config;
|
|
48
48
|
- workspace source config under `~/.config/code-agnostic/workspaces/<name>/`,
|
|
49
|
-
propagated into repos inside a registered workspace
|
|
49
|
+
propagated into repos inside a registered workspace;
|
|
50
|
+
- project source config under `~/.config/code-agnostic/projects/<name>/`,
|
|
51
|
+
synced to exactly one registered project directory.
|
|
50
52
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
without bypassing the hub.
|
|
53
|
+
Workspace sync may generate repo-local outputs, but those outputs are not
|
|
54
|
+
source. Project-local skill folders generated inside a repo, such as
|
|
55
|
+
`.agents/skills` or `.opencode/skills`, are also generated outputs; install
|
|
56
|
+
skills into managed project source first, then run `plan` / `apply`.
|
|
56
57
|
|
|
57
58
|
## Install
|
|
58
59
|
|
|
@@ -117,9 +118,9 @@ that are omitted or rejected for a selected target.
|
|
|
117
118
|
|
|
118
119
|
Cursor workspace propagation writes repo-local MCP, skills, and agents when those resources exist in the workspace source config.
|
|
119
120
|
|
|
120
|
-
OpenCode workspace configs include the shared workspace `AGENTS.md` natively via `instructions`, so repos under the workspace get both repo-local and shared workspace instructions. Codex repos receive workspace instructions through a generated `AGENTS.override.md`, which is added to each repo's `.git/info/exclude`. Claude Code receives workspace instructions through generated `CLAUDE.local.md` files, never by editing committed `CLAUDE.md`.
|
|
121
|
+
OpenCode workspace configs write project-root `opencode.json` files that include the shared workspace `AGENTS.md` natively via `instructions`, so repos under the workspace get both repo-local and shared workspace instructions. Codex repos receive workspace instructions through a generated `AGENTS.override.md`, which is added to each repo's `.git/info/exclude`. Claude Code receives workspace instructions through generated `CLAUDE.local.md` files, never by editing committed `CLAUDE.md`.
|
|
121
122
|
|
|
122
|
-
Cursor documents `AGENTS.md` support in project roots and subdirectories. `code-agnostic` does not copy or link the shared workspace `AGENTS.md` into child repos; Cursor will load
|
|
123
|
+
Cursor documents `AGENTS.md` support in project roots and subdirectories. `code-agnostic` does not copy or link the shared workspace `AGENTS.md` into child repos; Cursor will load `AGENTS.md` files that already exist in the opened project. Codex documents nested `AGENTS.md` discovery, but not a native config include for an extra workspace file.
|
|
123
124
|
|
|
124
125
|
## Features
|
|
125
126
|
|
|
@@ -204,16 +205,27 @@ code-agnostic skills list
|
|
|
204
205
|
code-agnostic agents list
|
|
205
206
|
```
|
|
206
207
|
|
|
207
|
-
|
|
208
|
+
Install a local skill directory into managed source:
|
|
208
209
|
|
|
209
210
|
```bash
|
|
210
|
-
|
|
211
|
-
|
|
211
|
+
code-agnostic skills install ./my-skill --global
|
|
212
|
+
code-agnostic skills install ./my-skill --workspace myworkspace
|
|
213
|
+
code-agnostic projects add --name myproject --path .
|
|
214
|
+
code-agnostic skills install ./my-skill --project myproject
|
|
212
215
|
code-agnostic plan
|
|
213
216
|
code-agnostic apply
|
|
214
217
|
```
|
|
215
218
|
|
|
216
|
-
Global skills live under `~/.config/code-agnostic/skills`. Workspace-local
|
|
219
|
+
Global skills live under `~/.config/code-agnostic/skills`. Workspace-local
|
|
220
|
+
skills live under `~/.config/code-agnostic/workspaces/<name>/skills` and can be
|
|
221
|
+
inspected with `code-agnostic skills list -w <name>`. Project-local skills live
|
|
222
|
+
under `~/.config/code-agnostic/projects/<name>/skills` and are generated into
|
|
223
|
+
the registered project directory by `plan` / `apply`. Codex generated skill
|
|
224
|
+
outputs are written to `~/.agents/skills`, while Codex agents and config remain
|
|
225
|
+
under `CODEX_HOME` when set, defaulting to `~/.codex`. Claude Code generated
|
|
226
|
+
skills and agents are written under `~/.claude/skills` and `~/.claude/agents`,
|
|
227
|
+
with workspace/project copies under repo-local `.claude/skills` and
|
|
228
|
+
`.claude/agents`.
|
|
217
229
|
|
|
218
230
|
Project-local skills are not first-class source inputs in `code-agnostic` yet. If a target app discovers repo-local skill folders such as `.agents/skills`, `.opencode/skills`, or user-created `.claude/skills`, treat those as unmanaged app inputs. Workspace sync writes only the exact generated paths recorded in `.sync-state.json`.
|
|
219
231
|
|
|
@@ -224,10 +236,12 @@ code-agnostic skills install ./my-skill --apply
|
|
|
224
236
|
```
|
|
225
237
|
|
|
226
238
|
That command should copy the skill into the source of truth and then run the normal compiler/apply flow.
|
|
239
|
+
See [docs/project-scoped-skills.md](docs/project-scoped-skills.md) for the
|
|
240
|
+
first implementation slice.
|
|
227
241
|
|
|
228
242
|
### Workspaces
|
|
229
243
|
|
|
230
|
-
Register workspace directories. Workspace rules are compiled into a canonical `AGENTS.md` at the workspace root. Repos keep their own repo-specific `AGENTS.md`; Codex receives the workspace rules through generated, git-excluded `AGENTS.override.md` files, while OpenCode workspace configs reference the shared workspace file through `instructions`. Claude receives generated `CLAUDE.local.md` files and project MCP entries in `~/.claude.json["projects"][absolute_repo_path]["mcpServers"]`. Workspace source config, skills, and agents are propagated into repo-local generated paths for OpenCode, Cursor, Codex, and Claude; user-created project-local skill folders remain unmanaged until project-scoped installs are supported.
|
|
244
|
+
Register workspace directories. Workspace rules are compiled into a canonical `AGENTS.md` at the workspace root. Repos keep their own repo-specific `AGENTS.md`; Codex receives the workspace rules through generated, git-excluded `AGENTS.override.md` files, while OpenCode workspace configs write project-root `opencode.json` files that reference the shared workspace file through `instructions`. Claude receives generated `CLAUDE.local.md` files and project MCP entries in `~/.claude.json["projects"][absolute_repo_path]["mcpServers"]`. Workspace source config, skills, and agents are propagated into repo-local generated paths for OpenCode, Cursor, Codex, and Claude; user-created project-local skill folders remain unmanaged until project-scoped installs are supported.
|
|
231
245
|
|
|
232
246
|
Cursor propagation intentionally stays to repo-local MCP, skills, and agents; it does not copy the shared workspace `AGENTS.md` into child repos.
|
|
233
247
|
|
|
@@ -291,12 +305,12 @@ The compiler migration is documented in:
|
|
|
291
305
|
- [x] MCP add/remove/list commands
|
|
292
306
|
- [x] Rules system with YAML frontmatter and per-editor compilation
|
|
293
307
|
- [x] Cross-compilation for skills and agents
|
|
308
|
+
- [x] Planner integration for cross-compiled skills and agents
|
|
294
309
|
- [x] Per-workspace git-exclude customization
|
|
295
310
|
- [x] Interactive TUI for import selection
|
|
296
311
|
- [x] Claude Code support
|
|
297
312
|
- [ ] Project-scoped skill installs and sync
|
|
298
313
|
- [ ] `rules add` / `skills add` / `agents add` commands (open `$EDITOR` with template)
|
|
299
|
-
- [ ] Planner integration for cross-compiled skills and agents
|
|
300
314
|
- [ ] Shell auto-complete
|
|
301
315
|
- [ ] Full TUI mode (command palette + menus)
|
|
302
316
|
|
|
@@ -10,6 +10,7 @@ from code_agnostic.cli.commands.explain_lossiness import explain_lossiness
|
|
|
10
10
|
from code_agnostic.cli.commands.import_ import import_group
|
|
11
11
|
from code_agnostic.cli.commands.mcp import mcp
|
|
12
12
|
from code_agnostic.cli.commands.plan import plan
|
|
13
|
+
from code_agnostic.cli.commands.projects import projects
|
|
13
14
|
from code_agnostic.cli.commands.restore import restore
|
|
14
15
|
from code_agnostic.cli.commands.rules import rules
|
|
15
16
|
from code_agnostic.cli.commands.skills import skills
|
|
@@ -25,7 +26,7 @@ from code_agnostic.errors import SyncAppError
|
|
|
25
26
|
)
|
|
26
27
|
@click.pass_context
|
|
27
28
|
def cli(ctx: click.Context) -> None:
|
|
28
|
-
"""
|
|
29
|
+
"""Manage one source of truth for AI coding-tool config."""
|
|
29
30
|
ctx.obj = {}
|
|
30
31
|
|
|
31
32
|
|
|
@@ -40,6 +41,7 @@ cli.add_command(explain_lossiness)
|
|
|
40
41
|
# Register command groups
|
|
41
42
|
cli.add_command(apps)
|
|
42
43
|
cli.add_command(workspaces)
|
|
44
|
+
cli.add_command(projects)
|
|
43
45
|
cli.add_command(rules)
|
|
44
46
|
cli.add_command(skills)
|
|
45
47
|
cli.add_command(agents_group)
|
|
@@ -7,14 +7,19 @@ from typing import Any
|
|
|
7
7
|
import yaml
|
|
8
8
|
|
|
9
9
|
from code_agnostic.agents.models import Agent
|
|
10
|
+
from code_agnostic.errors import InvalidConfigSchemaError
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
def serialize_opencode_agent(agent: Agent) -> str:
|
|
13
14
|
fm: dict[str, Any] = {}
|
|
14
15
|
if agent.metadata.name:
|
|
15
16
|
fm["name"] = agent.metadata.name
|
|
16
|
-
if agent.metadata.description:
|
|
17
|
-
|
|
17
|
+
if not agent.metadata.description:
|
|
18
|
+
raise InvalidConfigSchemaError(
|
|
19
|
+
agent.source_path,
|
|
20
|
+
"OpenCode agents require a description",
|
|
21
|
+
)
|
|
22
|
+
fm["description"] = agent.metadata.description
|
|
18
23
|
model = agent.metadata.effective_value("opencode", "model")
|
|
19
24
|
if model:
|
|
20
25
|
fm["model"] = model
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import os
|
|
1
2
|
from pathlib import Path
|
|
2
3
|
from typing import Any
|
|
3
4
|
|
|
@@ -21,7 +22,8 @@ from code_agnostic.errors import InvalidConfigSchemaError, InvalidJsonFormatErro
|
|
|
21
22
|
|
|
22
23
|
class CodexConfigRepository(IAppConfigRepository):
|
|
23
24
|
def __init__(self, root: Path | None = None) -> None:
|
|
24
|
-
self._root = root or (
|
|
25
|
+
self._root = root or _default_codex_root()
|
|
26
|
+
self._skills_dir = _default_codex_skills_dir(root)
|
|
25
27
|
|
|
26
28
|
@property
|
|
27
29
|
def root(self) -> Path:
|
|
@@ -33,7 +35,7 @@ class CodexConfigRepository(IAppConfigRepository):
|
|
|
33
35
|
|
|
34
36
|
@property
|
|
35
37
|
def skills_dir(self) -> Path:
|
|
36
|
-
return self.
|
|
38
|
+
return self._skills_dir
|
|
37
39
|
|
|
38
40
|
@property
|
|
39
41
|
def agents_dir(self) -> Path:
|
|
@@ -81,3 +83,16 @@ class CodexConfigRepository(IAppConfigRepository):
|
|
|
81
83
|
config = self.load_config()
|
|
82
84
|
config["agents"] = payload
|
|
83
85
|
self.save_config(config)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def _default_codex_root() -> Path:
|
|
89
|
+
codex_home = os.environ.get("CODEX_HOME")
|
|
90
|
+
if codex_home:
|
|
91
|
+
return Path(codex_home).expanduser()
|
|
92
|
+
return Path.home() / CODEX_PROJECT_DIRNAME
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def _default_codex_skills_dir(root: Path | None) -> Path:
|
|
96
|
+
if root is not None:
|
|
97
|
+
return root.parent / AGENTS_PROJECT_DIRNAME / SKILLS_DIRNAME
|
|
98
|
+
return Path.home() / AGENTS_PROJECT_DIRNAME / SKILLS_DIRNAME
|
|
@@ -226,18 +226,6 @@
|
|
|
226
226
|
},
|
|
227
227
|
"type": "object"
|
|
228
228
|
},
|
|
229
|
-
"AppsMcpPathOverrideConfigToml": {
|
|
230
|
-
"additionalProperties": false,
|
|
231
|
-
"properties": {
|
|
232
|
-
"enabled": {
|
|
233
|
-
"type": "boolean"
|
|
234
|
-
},
|
|
235
|
-
"path": {
|
|
236
|
-
"type": "string"
|
|
237
|
-
}
|
|
238
|
-
},
|
|
239
|
-
"type": "object"
|
|
240
|
-
},
|
|
241
229
|
"AskForApproval": {
|
|
242
230
|
"description": "Determines the conditions under which the user is consulted to approve running the command proposed by Codex.",
|
|
243
231
|
"oneOf": [
|
|
@@ -408,7 +396,23 @@
|
|
|
408
396
|
"type": "boolean"
|
|
409
397
|
},
|
|
410
398
|
"apps_mcp_path_override": {
|
|
411
|
-
"
|
|
399
|
+
"anyOf": [
|
|
400
|
+
{
|
|
401
|
+
"type": "boolean"
|
|
402
|
+
},
|
|
403
|
+
{
|
|
404
|
+
"additionalProperties": false,
|
|
405
|
+
"properties": {
|
|
406
|
+
"enabled": {
|
|
407
|
+
"type": "boolean"
|
|
408
|
+
},
|
|
409
|
+
"path": {
|
|
410
|
+
"type": "string"
|
|
411
|
+
}
|
|
412
|
+
},
|
|
413
|
+
"type": "object"
|
|
414
|
+
}
|
|
415
|
+
]
|
|
412
416
|
},
|
|
413
417
|
"auth_elicitation": {
|
|
414
418
|
"type": "boolean"
|
|
@@ -836,16 +840,6 @@
|
|
|
836
840
|
},
|
|
837
841
|
"type": "object"
|
|
838
842
|
},
|
|
839
|
-
"FeatureToml_for_AppsMcpPathOverrideConfigToml": {
|
|
840
|
-
"anyOf": [
|
|
841
|
-
{
|
|
842
|
-
"type": "boolean"
|
|
843
|
-
},
|
|
844
|
-
{
|
|
845
|
-
"$ref": "#/definitions/AppsMcpPathOverrideConfigToml"
|
|
846
|
-
}
|
|
847
|
-
]
|
|
848
|
-
},
|
|
849
843
|
"FeatureToml_for_CodeModeConfigToml": {
|
|
850
844
|
"anyOf": [
|
|
851
845
|
{
|
|
@@ -4534,7 +4528,23 @@
|
|
|
4534
4528
|
"type": "boolean"
|
|
4535
4529
|
},
|
|
4536
4530
|
"apps_mcp_path_override": {
|
|
4537
|
-
"
|
|
4531
|
+
"anyOf": [
|
|
4532
|
+
{
|
|
4533
|
+
"type": "boolean"
|
|
4534
|
+
},
|
|
4535
|
+
{
|
|
4536
|
+
"additionalProperties": false,
|
|
4537
|
+
"properties": {
|
|
4538
|
+
"enabled": {
|
|
4539
|
+
"type": "boolean"
|
|
4540
|
+
},
|
|
4541
|
+
"path": {
|
|
4542
|
+
"type": "string"
|
|
4543
|
+
}
|
|
4544
|
+
},
|
|
4545
|
+
"type": "object"
|
|
4546
|
+
}
|
|
4547
|
+
]
|
|
4538
4548
|
},
|
|
4539
4549
|
"auth_elicitation": {
|
|
4540
4550
|
"type": "boolean"
|
{code_agnostic-0.3.11 → code_agnostic-0.3.13}/code_agnostic/apps/opencode/config_repository.py
RENAMED
|
@@ -13,8 +13,15 @@ from code_agnostic.utils import merge_dict_overlay, read_json_safe, write_json
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
class OpenCodeConfigRepository(IAppConfigRepository):
|
|
16
|
-
def __init__(
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
root: Path | None = None,
|
|
19
|
+
config_path: Path | None = None,
|
|
20
|
+
legacy_config_path: Path | None = None,
|
|
21
|
+
) -> None:
|
|
17
22
|
self._root = root or (Path.home() / ".config" / "opencode")
|
|
23
|
+
self._config_path = config_path
|
|
24
|
+
self._legacy_config_path = legacy_config_path
|
|
18
25
|
|
|
19
26
|
@property
|
|
20
27
|
def root(self) -> Path:
|
|
@@ -22,7 +29,7 @@ class OpenCodeConfigRepository(IAppConfigRepository):
|
|
|
22
29
|
|
|
23
30
|
@property
|
|
24
31
|
def config_path(self) -> Path:
|
|
25
|
-
return self.root / OPENCODE_CONFIG_FILENAME
|
|
32
|
+
return self._config_path or self.root / OPENCODE_CONFIG_FILENAME
|
|
26
33
|
|
|
27
34
|
@property
|
|
28
35
|
def skills_dir(self) -> Path:
|
|
@@ -39,13 +46,14 @@ class OpenCodeConfigRepository(IAppConfigRepository):
|
|
|
39
46
|
return plural
|
|
40
47
|
|
|
41
48
|
def load_config(self) -> dict[str, Any]:
|
|
42
|
-
|
|
49
|
+
config_path = self._read_config_path()
|
|
50
|
+
payload, error = read_json_safe(config_path)
|
|
43
51
|
if error is not None:
|
|
44
|
-
raise InvalidJsonFormatError(
|
|
52
|
+
raise InvalidJsonFormatError(config_path, error)
|
|
45
53
|
if payload is None:
|
|
46
54
|
return {}
|
|
47
55
|
if not isinstance(payload, dict):
|
|
48
|
-
raise InvalidConfigSchemaError(
|
|
56
|
+
raise InvalidConfigSchemaError(config_path, "must be a JSON object")
|
|
49
57
|
return payload
|
|
50
58
|
|
|
51
59
|
def save_config(self, payload: dict[str, Any]) -> None:
|
|
@@ -105,3 +113,8 @@ class OpenCodeConfigRepository(IAppConfigRepository):
|
|
|
105
113
|
|
|
106
114
|
if tools:
|
|
107
115
|
merged["tools"] = tools
|
|
116
|
+
|
|
117
|
+
def _read_config_path(self) -> Path:
|
|
118
|
+
if self.config_path.exists() or self._legacy_config_path is None:
|
|
119
|
+
return self.config_path
|
|
120
|
+
return self._legacy_config_path
|
|
@@ -43,48 +43,44 @@
|
|
|
43
43
|
},
|
|
44
44
|
"additionalProperties": false
|
|
45
45
|
},
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
|
|
46
|
+
"ConfigV2.Reference.Git": {
|
|
47
|
+
"type": "object",
|
|
48
|
+
"properties": {
|
|
49
|
+
"repository": {
|
|
49
50
|
"type": "string"
|
|
50
51
|
},
|
|
51
|
-
{
|
|
52
|
-
"type": "
|
|
53
|
-
"properties": {
|
|
54
|
-
"repository": {
|
|
55
|
-
"type": "string",
|
|
56
|
-
"description": "Git repository URL, host/path reference, or GitHub owner/repo shorthand"
|
|
57
|
-
},
|
|
58
|
-
"branch": {
|
|
59
|
-
"type": "string",
|
|
60
|
-
"description": "Branch or ref to clone and inspect"
|
|
61
|
-
}
|
|
62
|
-
},
|
|
63
|
-
"required": [
|
|
64
|
-
"repository"
|
|
65
|
-
],
|
|
66
|
-
"additionalProperties": false
|
|
52
|
+
"branch": {
|
|
53
|
+
"type": "string"
|
|
67
54
|
},
|
|
68
|
-
{
|
|
69
|
-
"type": "
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
"description": "Absolute path, ~/ path, or workspace-relative path to a local reference directory"
|
|
74
|
-
}
|
|
75
|
-
},
|
|
76
|
-
"required": [
|
|
77
|
-
"path"
|
|
78
|
-
],
|
|
79
|
-
"additionalProperties": false
|
|
55
|
+
"description": {
|
|
56
|
+
"type": "string"
|
|
57
|
+
},
|
|
58
|
+
"hidden": {
|
|
59
|
+
"type": "boolean"
|
|
80
60
|
}
|
|
81
|
-
|
|
61
|
+
},
|
|
62
|
+
"required": [
|
|
63
|
+
"repository"
|
|
64
|
+
],
|
|
65
|
+
"additionalProperties": false
|
|
82
66
|
},
|
|
83
|
-
"
|
|
67
|
+
"ConfigV2.Reference.Local": {
|
|
84
68
|
"type": "object",
|
|
85
|
-
"
|
|
86
|
-
"
|
|
87
|
-
|
|
69
|
+
"properties": {
|
|
70
|
+
"path": {
|
|
71
|
+
"type": "string"
|
|
72
|
+
},
|
|
73
|
+
"description": {
|
|
74
|
+
"type": "string"
|
|
75
|
+
},
|
|
76
|
+
"hidden": {
|
|
77
|
+
"type": "boolean"
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
"required": [
|
|
81
|
+
"path"
|
|
82
|
+
],
|
|
83
|
+
"additionalProperties": false
|
|
88
84
|
},
|
|
89
85
|
"PermissionActionConfig": {
|
|
90
86
|
"type": "string",
|
|
@@ -390,6 +386,7 @@
|
|
|
390
386
|
"field": {
|
|
391
387
|
"type": "string",
|
|
392
388
|
"enum": [
|
|
389
|
+
"reasoning",
|
|
393
390
|
"reasoning_content",
|
|
394
391
|
"reasoning_details"
|
|
395
392
|
]
|
|
@@ -826,9 +823,39 @@
|
|
|
826
823
|
"additionalProperties": false,
|
|
827
824
|
"description": "Additional skill folder paths"
|
|
828
825
|
},
|
|
826
|
+
"references": {
|
|
827
|
+
"type": "object",
|
|
828
|
+
"additionalProperties": {
|
|
829
|
+
"anyOf": [
|
|
830
|
+
{
|
|
831
|
+
"type": "string"
|
|
832
|
+
},
|
|
833
|
+
{
|
|
834
|
+
"$ref": "#/$defs/ConfigV2.Reference.Git"
|
|
835
|
+
},
|
|
836
|
+
{
|
|
837
|
+
"$ref": "#/$defs/ConfigV2.Reference.Local"
|
|
838
|
+
}
|
|
839
|
+
]
|
|
840
|
+
},
|
|
841
|
+
"description": "Named git or local directory references"
|
|
842
|
+
},
|
|
829
843
|
"reference": {
|
|
830
|
-
"
|
|
831
|
-
"
|
|
844
|
+
"type": "object",
|
|
845
|
+
"additionalProperties": {
|
|
846
|
+
"anyOf": [
|
|
847
|
+
{
|
|
848
|
+
"type": "string"
|
|
849
|
+
},
|
|
850
|
+
{
|
|
851
|
+
"$ref": "#/$defs/ConfigV2.Reference.Git"
|
|
852
|
+
},
|
|
853
|
+
{
|
|
854
|
+
"$ref": "#/$defs/ConfigV2.Reference.Local"
|
|
855
|
+
}
|
|
856
|
+
]
|
|
857
|
+
},
|
|
858
|
+
"description": "@deprecated Use 'references' field instead. Named git or local directory references"
|
|
832
859
|
},
|
|
833
860
|
"watcher": {
|
|
834
861
|
"type": "object",
|
|
@@ -5,7 +5,7 @@ import shutil
|
|
|
5
5
|
import click
|
|
6
6
|
from rich.console import Console
|
|
7
7
|
|
|
8
|
-
from code_agnostic.cli.helpers import workspace_config_root
|
|
8
|
+
from code_agnostic.cli.helpers import validate_resource_name, workspace_config_root
|
|
9
9
|
from code_agnostic.cli.options import workspace_option
|
|
10
10
|
from code_agnostic.core.repository import CoreRepository
|
|
11
11
|
from code_agnostic.tui import SyncConsoleUI
|
|
@@ -33,6 +33,7 @@ def agents_list(obj: dict[str, str], workspace: str | None) -> None:
|
|
|
33
33
|
@workspace_option()
|
|
34
34
|
@click.pass_obj
|
|
35
35
|
def agents_remove(obj: dict[str, str], name: str, workspace: str | None) -> None:
|
|
36
|
+
validate_resource_name(name, "agent")
|
|
36
37
|
core = CoreRepository()
|
|
37
38
|
root = workspace_config_root(core, workspace)
|
|
38
39
|
agent_dir = root / "agents" / name
|
|
@@ -30,8 +30,10 @@ def apps_enable(obj: dict[str, str], app: str) -> None:
|
|
|
30
30
|
ui = SyncConsoleUI(Console())
|
|
31
31
|
core = CoreRepository()
|
|
32
32
|
service = AppsService(core)
|
|
33
|
-
|
|
33
|
+
app = app.lower()
|
|
34
|
+
service.enable(app)
|
|
34
35
|
ui.render_apps(service.list_status_rows())
|
|
36
|
+
ui.render_app_enabled_next_steps(app)
|
|
35
37
|
|
|
36
38
|
|
|
37
39
|
@apps.command("disable", help="Disable app sync target.")
|