@scemoon/cdh 1.0.3 → 1.0.5
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.
- package/ai-dlc-skill/SKILL.md +4 -2
- package/ai-dlc-skill/agents/master.md +6 -0
- package/ai-dlc-skill/agents/plan-agent.md +2 -2
- package/ai-dlc-skill/agents/understand-agent.md +4 -4
- package/ai-dlc-skill/agents/verify-agent.md +1 -1
- package/ai-dlc-skill/architecture/project-structure.md +10 -10
- package/ai-dlc-skill/brownfield/README.md +2 -2
- package/ai-dlc-skill/brownfield/generate-context.sh +3 -3
- package/ai-dlc-skill/brownfield/scripts/extract-api.sh +5 -5
- package/ai-dlc-skill/components/backend.md +1 -1
- package/ai-dlc-skill/components/web.md +2 -2
- package/ai-dlc-skill/contracts/README.md +3 -3
- package/ai-dlc-skill/cross-tool/cline/export.sh +1 -1
- package/ai-dlc-skill/cross-tool/copilot/export.sh +1 -1
- package/ai-dlc-skill/cross-tool/onecode/export-skills.sh +7 -3
- package/ai-dlc-skill/cross-tool/onecode/export.sh +14 -8
- package/ai-dlc-skill/phases/deliver/lifecycle.md +6 -6
- package/ai-dlc-skill/phases/deliver/prompt.md +2 -2
- package/ai-dlc-skill/phases/deliver/rules.md +1 -1
- package/ai-dlc-skill/phases/plan/lifecycle.md +11 -11
- package/ai-dlc-skill/phases/plan/prompt.md +6 -6
- package/ai-dlc-skill/phases/plan/rules.md +1 -1
- package/ai-dlc-skill/phases/understand/entry.md +1 -1
- package/ai-dlc-skill/phases/understand/lifecycle.md +7 -7
- package/ai-dlc-skill/phases/understand/prompt.md +8 -8
- package/ai-dlc-skill/phases/understand/rules.md +5 -5
- package/ai-dlc-skill/phases/verify/lifecycle.md +24 -24
- package/ai-dlc-skill/phases/verify/prompt.md +8 -8
- package/ai-dlc-skill/phases/verify/rules.md +9 -9
- package/ai-dlc-skill/providers/README.md +2 -2
- package/ai-dlc-skill/providers/aliyun/preview.yaml +2 -2
- package/ai-dlc-skill/providers/tcb/preview.yaml +2 -2
- package/ai-dlc-skill/requirements.md +7 -7
- package/ai-dlc-skill/skill.yaml +4 -4
- package/ai-dlc-skill/templates/integration/CHANGELOG.md +2 -2
- package/ai-dlc-skill/templates/integration/contract-diff.md +7 -7
- package/ai-dlc-skill/templates/integration/contract-spec.md +7 -7
- package/ai-dlc-skill/templates/integration/runtime-contract.yaml +1 -1
- package/ai-dlc-skill/templates/project/README.md +18 -19
- package/ai-dlc-skill/templates/project/template.md +21 -21
- package/ai-dlc-skill/walkthrough/collect.sh +1 -1
- package/ai-dlc-skill/walkthrough/template.md +2 -2
- package/ai-dlc-skill/workflows/ai-dlc.yaml +12 -12
- package/ai-dlc-skill/workflows/deployment.yaml +4 -4
- package/cdh/__pycache__/cdh_mcp_injector.cpython-314.pyc +0 -0
- package/cdh/__pycache__/cdh_mcp_loader.cpython-314.pyc +0 -0
- package/cdh/__pycache__/cdh_mcp_manager.cpython-314.pyc +0 -0
- package/cdh/__pycache__/cdh_session_aggregator.cpython-314.pyc +0 -0
- package/cdh/__pycache__/cdh_skill_loader.cpython-314.pyc +0 -0
- package/cdh/__pycache__/cdh_skill_manager.cpython-314.pyc +0 -0
- package/cdh/__pycache__/cli.cpython-313.pyc +0 -0
- package/cdh/__pycache__/cli.cpython-314.pyc +0 -0
- package/cdh/__pycache__/scaffold.cpython-314.pyc +0 -0
- package/cdh/cdh_mcp_injector.py +115 -0
- package/cdh/cdh_mcp_loader.py +67 -0
- package/cdh/cdh_mcp_manager.py +73 -0
- package/cdh/cdh_session_aggregator.py +258 -0
- package/cdh/cdh_skill_manager.py +105 -0
- package/cdh/cli.py +14 -3
- package/cdh/scaffold.py +192 -41
- package/onecode/__init__.py +1 -1
- package/onecode/__pycache__/cli.cpython-314.pyc +0 -0
- package/onecode/__pycache__/commands.cpython-314.pyc +0 -0
- package/onecode/__pycache__/config.cpython-314.pyc +0 -0
- package/onecode/__pycache__/config_screen.cpython-314.pyc +0 -0
- package/onecode/__pycache__/migrate.cpython-314.pyc +0 -0
- package/onecode/agent/__pycache__/cdh_loader.cpython-314.pyc +0 -0
- package/onecode/agent/__pycache__/context.cpython-314.pyc +0 -0
- package/onecode/agent/__pycache__/engine.cpython-314.pyc +0 -0
- package/onecode/agent/__pycache__/hooks.cpython-314.pyc +0 -0
- package/onecode/agent/__pycache__/onecode_agent_acp.cpython-314.pyc +0 -0
- package/onecode/agent/__pycache__/permissions.cpython-314.pyc +0 -0
- package/onecode/agent/__pycache__/project_doc.cpython-314.pyc +0 -0
- package/onecode/agent/__pycache__/session.cpython-314.pyc +0 -0
- package/onecode/agent/agents/__pycache__/types.cpython-314.pyc +0 -0
- package/onecode/agent/agents/types.py +47 -164
- package/onecode/agent/attachments.py +0 -1
- package/onecode/agent/cdh_loader.py +17 -25
- package/onecode/agent/context.py +8 -3
- package/onecode/agent/engine.py +835 -220
- package/onecode/agent/hooks.py +1 -1
- package/onecode/agent/onecode_agent_acp.py +462 -49
- package/onecode/agent/onecode_agent_acp.py.bak +2447 -0
- package/onecode/agent/permissions.py +0 -1
- package/onecode/agent/project_doc.py +19 -0
- package/onecode/agent/session.py +17 -3
- package/onecode/agent/snapshot.py +3 -4
- package/onecode/agent/tools/__pycache__/agent_tools.cpython-314.pyc +0 -0
- package/onecode/agent/tools/__pycache__/apply_patch_tool.cpython-314.pyc +0 -0
- package/onecode/agent/tools/__pycache__/bash_tool.cpython-314.pyc +0 -0
- package/onecode/agent/tools/__pycache__/communication_tools.cpython-314.pyc +0 -0
- package/onecode/agent/tools/__pycache__/config_tool.cpython-314.pyc +0 -0
- package/onecode/agent/tools/__pycache__/cron_tools.cpython-314.pyc +0 -0
- package/onecode/agent/tools/__pycache__/file_ops.cpython-314.pyc +0 -0
- package/onecode/agent/tools/__pycache__/file_tools.cpython-314.pyc +0 -0
- package/onecode/agent/tools/__pycache__/git_tools.cpython-314.pyc +0 -0
- package/onecode/agent/tools/__pycache__/lsp_tools.cpython-314.pyc +0 -0
- package/onecode/agent/tools/__pycache__/mcp_tools.cpython-314.pyc +0 -0
- package/onecode/agent/tools/__pycache__/permission_handler.cpython-314.pyc +0 -0
- package/onecode/agent/tools/__pycache__/protocol.cpython-314.pyc +0 -0
- package/onecode/agent/tools/__pycache__/registry.cpython-314.pyc +0 -0
- package/onecode/agent/tools/__pycache__/sandbox.cpython-314.pyc +0 -0
- package/onecode/agent/tools/__pycache__/skill_tools.cpython-314.pyc +0 -0
- package/onecode/agent/tools/__pycache__/todo_tools.cpython-314.pyc +0 -0
- package/onecode/agent/tools/__pycache__/web_tools.cpython-314.pyc +0 -0
- package/onecode/agent/tools/agent_tools.py +4 -6
- package/onecode/agent/tools/apply_patch_tool.py +2 -8
- package/onecode/agent/tools/bash_tool.py +32 -12
- package/onecode/agent/tools/communication_tools.py +4 -5
- package/onecode/agent/tools/config_tool.py +3 -3
- package/onecode/agent/tools/cron_tools.py +4 -5
- package/onecode/agent/tools/file_ops.py +37 -3
- package/onecode/agent/tools/file_tools.py +10 -11
- package/onecode/agent/tools/git_tools.py +2 -2
- package/onecode/agent/tools/lsp_tools.py +2 -2
- package/onecode/agent/tools/mcp_tools.py +3 -5
- package/onecode/agent/tools/permission_handler.py +1 -1
- package/onecode/agent/tools/protocol.py +1 -1
- package/onecode/agent/tools/registry.py +69 -2
- package/onecode/agent/tools/sandbox.py +110 -16
- package/onecode/agent/tools/skill_tools.py +2 -2
- package/onecode/agent/tools/todo_tools.py +38 -19
- package/onecode/agent/tools/web_tools.py +6 -7
- package/onecode/builtin_skills/agent-browser/SKILL.md +212 -0
- package/onecode/builtin_skills/agent-browser/skill.yaml +8 -0
- package/onecode/builtin_skills/skill-creator/SKILL.md +106 -0
- package/onecode/builtin_skills/skill-creator/skill.yaml +8 -0
- package/onecode/cli.py +186 -6
- package/onecode/codebase/__pycache__/chunker.cpython-314.pyc +0 -0
- package/onecode/codebase/__pycache__/indexer.cpython-314.pyc +0 -0
- package/onecode/codebase/__pycache__/retriever.cpython-314.pyc +0 -0
- package/onecode/codebase/__pycache__/storage.cpython-314.pyc +0 -0
- package/onecode/codebase/chunker.py +0 -5
- package/onecode/codebase/indexer.py +14 -1
- package/onecode/codebase/retriever.py +13 -2
- package/onecode/codebase/storage.py +5 -4
- package/onecode/commands.py +81 -6
- package/onecode/config.py +41 -12
- package/onecode/config_screen.py +7 -3
- package/onecode/mcp/__pycache__/manager.cpython-314.pyc +0 -0
- package/onecode/mcp/manager.py +2 -3
- package/onecode/memory/__init__.py +7 -53
- package/onecode/memory/__pycache__/__init__.cpython-314.pyc +0 -0
- package/onecode/memory/__pycache__/backend.cpython-314.pyc +0 -0
- package/onecode/memory/__pycache__/offload.cpython-314.pyc +0 -0
- package/onecode/memory/__pycache__/pyramid.cpython-314.pyc +0 -0
- package/onecode/memory/__pycache__/recall.cpython-314.pyc +0 -0
- package/onecode/memory/backend.py +13 -39
- package/onecode/memory/pyramid.py +2 -71
- package/onecode/memory/recall.py +38 -3
- package/onecode/migrate.py +122 -0
- package/onecode/models/__pycache__/messages.cpython-314.pyc +0 -0
- package/onecode/models/__pycache__/provider.cpython-314.pyc +0 -0
- package/onecode/models/messages.py +58 -0
- package/onecode/models/provider.py +20 -2
- package/onecode/models/providers/__pycache__/anthropic_provider.cpython-314.pyc +0 -0
- package/onecode/models/providers/__pycache__/glm_provider.cpython-314.pyc +0 -0
- package/onecode/models/providers/__pycache__/minimax_provider.cpython-314.pyc +0 -0
- package/onecode/models/providers/__pycache__/minimaxi_provider.cpython-314.pyc +0 -0
- package/onecode/models/providers/__pycache__/ollama_provider.cpython-314.pyc +0 -0
- package/onecode/models/providers/anthropic_provider.py +59 -12
- package/onecode/models/providers/glm_provider.py +40 -0
- package/onecode/models/providers/minimax_provider.py +3 -0
- package/onecode/models/providers/minimaxi_provider.py +3 -0
- package/onecode/models/providers/ollama_provider.py +3 -0
- package/onecode/server/app.py +1 -1
- package/onecode/skills/__pycache__/argument_substitution.cpython-314.pyc +0 -0
- package/onecode/skills/__pycache__/bootstrap.cpython-314.pyc +0 -0
- package/onecode/skills/__pycache__/loader.cpython-314.pyc +0 -0
- package/onecode/skills/__pycache__/manager.cpython-314.pyc +0 -0
- package/onecode/skills/argument_substitution.py +0 -1
- package/onecode/skills/bootstrap.py +124 -0
- package/onecode/skills/loader.py +35 -53
- package/onecode/skills/manager.py +2 -2
- package/onecode/storage/activity.py +3 -4
- package/onecode/storage/session.py +3 -4
- package/onecode/tasks/manager.py +23 -10
- package/onecode/trace/tracer.py +2 -3
- package/package.json +1 -1
- package/pyproject.toml +5 -1
- package/tui/__pycache__/about.cpython-314.pyc +0 -0
- package/tui/__pycache__/agents.cpython-314.pyc +0 -0
- package/tui/__pycache__/app.cpython-313.pyc +0 -0
- package/tui/__pycache__/app.cpython-314.pyc +0 -0
- package/tui/__pycache__/danger.cpython-314.pyc +0 -0
- package/tui/__pycache__/messages.cpython-314.pyc +0 -0
- package/tui/__pycache__/path_complete.cpython-314.pyc +0 -0
- package/tui/__pycache__/paths.cpython-314.pyc +0 -0
- package/tui/__pycache__/session_tracker.cpython-314.pyc +0 -0
- package/tui/__pycache__/settings_schema.cpython-314.pyc +0 -0
- package/tui/acp/__pycache__/agent.cpython-314.pyc +0 -0
- package/tui/acp/__pycache__/api.cpython-314.pyc +0 -0
- package/tui/acp/__pycache__/messages.cpython-314.pyc +0 -0
- package/tui/acp/__pycache__/prompt.cpython-314.pyc +0 -0
- package/tui/acp/__pycache__/protocol.cpython-314.pyc +0 -0
- package/tui/acp/agent.py +125 -58
- package/tui/acp/api.py +12 -0
- package/tui/acp/messages.py +3 -1
- package/tui/acp/prompt.py +0 -57
- package/tui/acp/protocol.py +6 -0
- package/tui/agents.py +8 -7
- package/tui/app.py +11 -33
- package/tui/data/agents/ampcode.com.toml +1 -0
- package/tui/data/agents/augmentcode.com.toml +1 -0
- package/tui/data/agents/cdh.cloud-dev-harness.toml +3 -2
- package/tui/data/agents/crowai.dev.toml +1 -0
- package/tui/data/agents/deepagents.langchain.com +1 -0
- package/tui/data/agents/docker.com.toml +1 -0
- package/tui/data/agents/goose.ai.toml +1 -0
- package/tui/data/agents/inference.huggingface.co.toml +1 -1
- package/tui/data/agents/kiro.dev.toml +1 -0
- package/tui/data/agents/onecode.dev.toml +22 -0
- package/tui/data/agents/openclaw.ai.toml +1 -1
- package/tui/data/agents/openhands.dev.toml +1 -0
- package/tui/data/agents/stakpak.dev.toml +1 -0
- package/tui/data/agents/vibe.mistral.ai.toml +1 -0
- package/tui/data/agents/vtcode.dev.toml +1 -0
- package/tui/messages.py +2 -0
- package/tui/path_complete.py +1 -1
- package/tui/paths.py +16 -0
- package/tui/screens/__pycache__/component_picker.cpython-314.pyc +0 -0
- package/tui/screens/__pycache__/diff_screen.cpython-314.pyc +0 -0
- package/tui/screens/__pycache__/log.cpython-314.pyc +0 -0
- package/tui/screens/__pycache__/main.cpython-313.pyc +0 -0
- package/tui/screens/__pycache__/main.cpython-314.pyc +0 -0
- package/tui/screens/__pycache__/permissions.cpython-314.pyc +0 -0
- package/tui/screens/__pycache__/projects_app.cpython-314.pyc +0 -0
- package/tui/screens/__pycache__/projects_screen.cpython-314.pyc +0 -0
- package/tui/screens/__pycache__/sessions.cpython-314.pyc +0 -0
- package/tui/screens/__pycache__/store.cpython-314.pyc +0 -0
- package/tui/screens/__pycache__/tool_content_screen.cpython-314.pyc +0 -0
- package/tui/screens/component_picker.py +35 -15
- package/tui/screens/diff_screen.py +84 -0
- package/tui/screens/log.py +25 -25
- package/tui/screens/main.py +48 -26
- package/tui/screens/projects.tcss +5 -1
- package/tui/screens/projects_app.py +6 -6
- package/tui/screens/projects_screen.py +19 -39
- package/tui/screens/sessions.py +3 -5
- package/tui/screens/store.py +1 -1
- package/tui/session_tracker.py +3 -0
- package/tui/settings_schema.py +2 -2
- package/tui/visuals/__pycache__/columns.cpython-314.pyc +0 -0
- package/tui/visuals/columns.py +1 -2
- package/tui/widgets/__pycache__/agent_response.cpython-314.pyc +0 -0
- package/tui/widgets/__pycache__/agent_thought.cpython-314.pyc +0 -0
- package/tui/widgets/__pycache__/conversation.cpython-314.pyc +0 -0
- package/tui/widgets/__pycache__/diff_view.cpython-314.pyc +0 -0
- package/tui/widgets/__pycache__/load_more.cpython-314.pyc +0 -0
- package/tui/widgets/__pycache__/modified_files.cpython-314.pyc +0 -0
- package/tui/widgets/__pycache__/plan.cpython-314.pyc +0 -0
- package/tui/widgets/__pycache__/project_grid_select.cpython-314.pyc +0 -0
- package/tui/widgets/__pycache__/session_grid_select.cpython-314.pyc +0 -0
- package/tui/widgets/__pycache__/shell_result.cpython-314.pyc +0 -0
- package/tui/widgets/__pycache__/side_bar.cpython-314.pyc +0 -0
- package/tui/widgets/__pycache__/subagent.cpython-314.pyc +0 -0
- package/tui/widgets/__pycache__/subagent_screen.cpython-314.pyc +0 -0
- package/tui/widgets/__pycache__/terminal.cpython-314.pyc +0 -0
- package/tui/widgets/__pycache__/tool_call.cpython-314.pyc +0 -0
- package/tui/widgets/agent_response.py +0 -1
- package/tui/widgets/agent_thought.py +0 -1
- package/tui/widgets/conversation.py +157 -14
- package/tui/widgets/diff_view.py +10 -0
- package/tui/widgets/load_more.py +24 -0
- package/tui/widgets/modified_files.py +173 -105
- package/tui/widgets/plan.py +1 -1
- package/tui/widgets/project_grid_select.py +9 -2
- package/tui/widgets/session_grid_select.py +6 -0
- package/tui/widgets/side_bar.py +10 -0
- package/tui/widgets/subagent.py +92 -58
- package/tui/widgets/subagent_screen.py +638 -115
- package/tui/widgets/terminal.py +1 -2
- package/tui/widgets/terminal_tool.py +11 -2
- package/tui/widgets/tool_call.py +35 -2
- package/cdh/__pycache__/__init__.cpython-313.pyc +0 -0
- package/cdh/__pycache__/__main__.cpython-314.pyc +0 -0
- package/cdh/__pycache__/scaffold.cpython-313.pyc +0 -0
- package/onecode/__pycache__/mock_data.cpython-314.pyc +0 -0
- package/onecode/agent/__pycache__/cdh_agent_acp.cpython-313.pyc +0 -0
- package/onecode/agent/__pycache__/cdh_agent_acp.cpython-314.pyc +0 -0
- package/onecode/agent/__pycache__/harness_skill.cpython-314.pyc +0 -0
- package/onecode/agent/tools/__pycache__/task_tools.cpython-314.pyc +0 -0
- package/onecode/codebase/__pycache__/config.cpython-314.pyc +0 -0
- package/onecode/memory/offload.py +0 -114
- package/onecode/memory/symbolic.py +0 -164
- package/onecode/models/providers/__pycache__/mock_provider.cpython-314.pyc +0 -0
- package/onecode/tasks/__pycache__/__init__.cpython-314.pyc +0 -0
- package/onecode/tasks/__pycache__/manager.cpython-314.pyc +0 -0
- package/onecode/tasks/__pycache__/models.cpython-314.pyc +0 -0
- package/tui/__pycache__/cli.cpython-314.pyc +0 -0
- package/tui/screens/__pycache__/settings.cpython-314.pyc +0 -0
- package/tui/widgets/__pycache__/conversation.cpython-313.pyc +0 -0
- package/tui/widgets/__pycache__/terminal.cpython-313.pyc +0 -0
- package/tui/widgets/__pycache__/tool_call.cpython-313.pyc +0 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"""cdh platform skill manager — operates ~/.cdh/skills/<name>/.
|
|
2
|
+
|
|
3
|
+
This is the cdh platform equivalent of onecode.skills.manager.SkillManager,
|
|
4
|
+
but operates strictly on ~/.cdh/skills/ (cdh platform shared pool).
|
|
5
|
+
Engines (onecode/opencode/claude) do NOT read this directory directly;
|
|
6
|
+
cdh injects platform skills into engines at runtime via prompt or env var.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import shutil
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
from typing import Optional
|
|
14
|
+
|
|
15
|
+
import yaml
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
CDH_PLATFORM_SKILLS_DIR = Path.home() / ".cdh" / "skills"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class CdhSkillManager:
|
|
22
|
+
def __init__(self, skills_dir: Path | None = None):
|
|
23
|
+
self.skills_dir = skills_dir or CDH_PLATFORM_SKILLS_DIR
|
|
24
|
+
self.skills_dir.mkdir(parents=True, exist_ok=True)
|
|
25
|
+
self._skills: dict[str, dict] = {}
|
|
26
|
+
|
|
27
|
+
def install(self, path: Path) -> Optional[str]:
|
|
28
|
+
"""Install a skill from source path into the cdh platform skill pool.
|
|
29
|
+
|
|
30
|
+
Copies the entire skill directory to ~/.cdh/skills/<name>/,
|
|
31
|
+
and writes .installed_version with the source's metadata.version.
|
|
32
|
+
Returns error message or None on success.
|
|
33
|
+
"""
|
|
34
|
+
skill_yaml = path / "skill.yaml"
|
|
35
|
+
if not skill_yaml.exists():
|
|
36
|
+
return "skill.yaml not found in source"
|
|
37
|
+
|
|
38
|
+
data = yaml.safe_load(skill_yaml.read_text())
|
|
39
|
+
name = data.get("name", path.name)
|
|
40
|
+
target = self.skills_dir / name
|
|
41
|
+
target.mkdir(parents=True, exist_ok=True)
|
|
42
|
+
|
|
43
|
+
for src in path.iterdir():
|
|
44
|
+
if src.name.startswith("."):
|
|
45
|
+
continue
|
|
46
|
+
dst = target / src.name
|
|
47
|
+
if src.is_dir():
|
|
48
|
+
shutil.copytree(src, dst, dirs_exist_ok=True)
|
|
49
|
+
else:
|
|
50
|
+
shutil.copy2(src, dst)
|
|
51
|
+
|
|
52
|
+
# Write version marker
|
|
53
|
+
version = data.get("metadata", {}).get("version", "4.0.0")
|
|
54
|
+
version_file = target / ".installed_version"
|
|
55
|
+
version_file.write_text(version + "\n", encoding="utf-8")
|
|
56
|
+
|
|
57
|
+
self._skills[name] = data
|
|
58
|
+
return None
|
|
59
|
+
|
|
60
|
+
def list(self) -> list[dict]:
|
|
61
|
+
result = []
|
|
62
|
+
for d in self.skills_dir.iterdir():
|
|
63
|
+
if d.is_dir():
|
|
64
|
+
config_path = d / "skill.yaml"
|
|
65
|
+
if config_path.exists():
|
|
66
|
+
data = yaml.safe_load(config_path.read_text()) or {}
|
|
67
|
+
data["name"] = data.get("name", d.name)
|
|
68
|
+
data["enabled"] = data.get("enabled", True)
|
|
69
|
+
result.append(data)
|
|
70
|
+
return result
|
|
71
|
+
|
|
72
|
+
def enable(self, name: str, enabled: bool = True):
|
|
73
|
+
config_path = self.skills_dir / name / "skill.yaml"
|
|
74
|
+
if config_path.exists():
|
|
75
|
+
data = yaml.safe_load(config_path.read_text()) or {}
|
|
76
|
+
data["enabled"] = enabled
|
|
77
|
+
config_path.write_text(yaml.dump(data, default_flow_style=False))
|
|
78
|
+
|
|
79
|
+
def get_installed_version(self, name: str) -> Optional[str]:
|
|
80
|
+
version_file = self.skills_dir / name / ".installed_version"
|
|
81
|
+
if version_file.exists():
|
|
82
|
+
return version_file.read_text(encoding="utf-8").strip()
|
|
83
|
+
return None
|
|
84
|
+
|
|
85
|
+
def remove(self, name: str) -> Optional[str]:
|
|
86
|
+
skill_path = self.skills_dir / name
|
|
87
|
+
if not skill_path.exists():
|
|
88
|
+
return f"Skill '{name}' not found"
|
|
89
|
+
if not skill_path.is_dir():
|
|
90
|
+
return f"'{name}' is not a skill directory"
|
|
91
|
+
shutil.rmtree(skill_path)
|
|
92
|
+
self._skills.pop(name, None)
|
|
93
|
+
return None
|
|
94
|
+
|
|
95
|
+
def get(self, name: str) -> Optional[dict]:
|
|
96
|
+
if name in self._skills:
|
|
97
|
+
return self._skills[name]
|
|
98
|
+
skill_path = self.skills_dir / name / "skill.yaml"
|
|
99
|
+
if skill_path.exists():
|
|
100
|
+
data = yaml.safe_load(skill_path.read_text()) or {}
|
|
101
|
+
data["name"] = data.get("name", name)
|
|
102
|
+
data["enabled"] = data.get("enabled", True)
|
|
103
|
+
self._skills[name] = data
|
|
104
|
+
return data
|
|
105
|
+
return None
|
package/cdh/cli.py
CHANGED
|
@@ -5,9 +5,7 @@ import click
|
|
|
5
5
|
|
|
6
6
|
from cdh.scaffold import (
|
|
7
7
|
COMPONENTS,
|
|
8
|
-
COMPONENT_BY_ID,
|
|
9
8
|
CROSS_CUTTING,
|
|
10
|
-
CROSS_CUTTING_BY_ID,
|
|
11
9
|
add_component,
|
|
12
10
|
add_cross_cutting,
|
|
13
11
|
init_dlc_project,
|
|
@@ -146,8 +144,15 @@ _ONECODE_HELP_OVERRIDES: dict[str, tuple[str, str]] = {
|
|
|
146
144
|
"Manage the onecode codebase index",
|
|
147
145
|
"Build and query onecode's local codebase index. Used by the "
|
|
148
146
|
"agent to ground answers in the project's own source files. "
|
|
147
|
+
"Index stored at ~/.onecode/codebase/indexes/. "
|
|
149
148
|
"Sub-commands: index, reindex, status, search.",
|
|
150
149
|
),
|
|
150
|
+
"memory": (
|
|
151
|
+
"Manage onecode long-term memory",
|
|
152
|
+
"View and manage onecode's long-term conversation memory. "
|
|
153
|
+
"Memory stored at ~/.onecode/memory/ with BM25 recall. "
|
|
154
|
+
"Sub-commands: status, clear, count.",
|
|
155
|
+
),
|
|
151
156
|
"skill": (
|
|
152
157
|
"Manage onecode skills",
|
|
153
158
|
"Install, enable, disable, or remove onecode skills. Skills are "
|
|
@@ -665,7 +670,13 @@ def session(action, session_id):
|
|
|
665
670
|
if session_id is None:
|
|
666
671
|
click.echo("Usage: cdh session load <id>")
|
|
667
672
|
return
|
|
668
|
-
s =
|
|
673
|
+
s = None
|
|
674
|
+
try:
|
|
675
|
+
s = await db.session_get(int(session_id))
|
|
676
|
+
except (ValueError, TypeError):
|
|
677
|
+
pass
|
|
678
|
+
if s is None:
|
|
679
|
+
s = await db.session_get_by_agent_session_id(session_id)
|
|
669
680
|
if s is None:
|
|
670
681
|
click.echo(f"Session {session_id} not found.")
|
|
671
682
|
return
|
package/cdh/scaffold.py
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from dataclasses import dataclass
|
|
3
|
+
from dataclasses import dataclass
|
|
4
4
|
from pathlib import Path
|
|
5
|
-
from typing import Optional
|
|
6
5
|
|
|
7
6
|
import yaml
|
|
8
7
|
|
|
@@ -102,40 +101,40 @@ COMPONENT_BY_ID: dict[str, ComponentSpec] = {c.id: c for c in COMPONENTS}
|
|
|
102
101
|
CROSS_CUTTING: tuple[CrossCutSpec, ...] = (
|
|
103
102
|
CrossCutSpec(
|
|
104
103
|
id="contracts",
|
|
105
|
-
paths=("
|
|
104
|
+
paths=("aidlc/contracts/CHANGELOG.md",),
|
|
106
105
|
label="Interface Contracts",
|
|
107
106
|
description="API/event contracts and changelog",
|
|
108
107
|
),
|
|
109
108
|
CrossCutSpec(
|
|
110
109
|
id="shared",
|
|
111
|
-
paths=("packages/shared",),
|
|
110
|
+
paths=("aidlc/packages/shared",),
|
|
112
111
|
label="Shared Types",
|
|
113
112
|
description="Cross-component shared types package",
|
|
114
113
|
),
|
|
115
114
|
CrossCutSpec(
|
|
116
115
|
id="openspec",
|
|
117
|
-
paths=(
|
|
116
|
+
paths=(),
|
|
118
117
|
label="OpenSpec Changes",
|
|
119
118
|
description="OpenSpec change proposals",
|
|
120
119
|
),
|
|
121
120
|
CrossCutSpec(
|
|
122
121
|
id="cross_stack_features",
|
|
123
|
-
paths=(
|
|
122
|
+
paths=(),
|
|
124
123
|
label="Cross-Stack BDD",
|
|
125
124
|
description="End-to-end BDD features across components",
|
|
126
125
|
),
|
|
127
126
|
CrossCutSpec(
|
|
128
127
|
id="cross_stack_tests",
|
|
129
|
-
paths=("tests/contract", "tests/cross-stack"),
|
|
128
|
+
paths=("aidlc/tests/contract", "aidlc/tests/cross-stack"),
|
|
130
129
|
label="Cross-Stack Tests",
|
|
131
130
|
description="Contract tests and cross-stack integration tests",
|
|
132
131
|
),
|
|
133
132
|
CrossCutSpec(
|
|
134
133
|
id="provider",
|
|
135
134
|
paths=(
|
|
136
|
-
"providers/tcb/provider.yaml",
|
|
137
|
-
"providers/tcb/deployment.yaml",
|
|
138
|
-
"providers/tcb/preview.yaml",
|
|
135
|
+
"aidlc/providers/tcb/provider.yaml",
|
|
136
|
+
"aidlc/providers/tcb/deployment.yaml",
|
|
137
|
+
"aidlc/providers/tcb/preview.yaml",
|
|
139
138
|
),
|
|
140
139
|
label="Cloud Provider",
|
|
141
140
|
description="TCB (Tencent CloudBase) provider config",
|
|
@@ -143,9 +142,9 @@ CROSS_CUTTING: tuple[CrossCutSpec, ...] = (
|
|
|
143
142
|
CrossCutSpec(
|
|
144
143
|
id="tools",
|
|
145
144
|
paths=(
|
|
146
|
-
"tools/deploy_stack.py",
|
|
147
|
-
"tools/contract_diff.py",
|
|
148
|
-
"tools/generate_shared.py",
|
|
145
|
+
"aidlc/tools/deploy_stack.py",
|
|
146
|
+
"aidlc/tools/contract_diff.py",
|
|
147
|
+
"aidlc/tools/generate_shared.py",
|
|
149
148
|
),
|
|
150
149
|
label="Tooling Scripts",
|
|
151
150
|
description="deploy_stack / contract_diff / generate_shared stubs",
|
|
@@ -238,6 +237,95 @@ Thumbs.db
|
|
|
238
237
|
|
|
239
238
|
CHANGELOG_MD = "# Changelog\n\n## [0.1.0] - Initial scaffold\n\n- Project created via cdh scaffold\n"
|
|
240
239
|
|
|
240
|
+
AGENTS_MD_TEMPLATE = """# AGENTS.md — Project Constitution
|
|
241
|
+
|
|
242
|
+
Hard rules every AI agent must follow when working in this repo.
|
|
243
|
+
Read once per session; behavior is enforced by the agent runtime.
|
|
244
|
+
|
|
245
|
+
## Project Overview
|
|
246
|
+
|
|
247
|
+
- **Name**: {project_name}
|
|
248
|
+
- **Description**: {description}
|
|
249
|
+
- **Type**: monorepo — AI-DLC multi-component stack
|
|
250
|
+
{component_list}
|
|
251
|
+
|
|
252
|
+
## AI-DLC Core Cycle
|
|
253
|
+
|
|
254
|
+
```
|
|
255
|
+
① Understand (SDD+BDD) Intent → Spec Delta → BDD Feature Files
|
|
256
|
+
② Plan (SDD+TDD) Design Doc → Task DAG → Test Plan
|
|
257
|
+
③ Verify (BDD+TDD) Red → Green → Refactor per scenario
|
|
258
|
+
④ Deliver (SDD+Cloud) Stack Preview → e2e → Production + BVT
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
Reference skill: `~/.cdh/skills/ai-dlc-skill/SKILL.md` (full AI-DLC methodology; installed by cdh platform bootstrap).
|
|
262
|
+
|
|
263
|
+
## Component Mapping
|
|
264
|
+
|
|
265
|
+
Work is partitioned by component prefix. Place new code in the matching directory:
|
|
266
|
+
|
|
267
|
+
| Prefix | Component | Directory |
|
|
268
|
+
|--------|-----------|-----------|
|
|
269
|
+
{component_table}
|
|
270
|
+
|
|
271
|
+
> **Note**: FR namespaces are used in AI-DLC lifecycle only.
|
|
272
|
+
|
|
273
|
+
## Quality Gates
|
|
274
|
+
|
|
275
|
+
Hard thresholds every agent must respect:
|
|
276
|
+
|
|
277
|
+
| Gate | Threshold |
|
|
278
|
+
|------|-----------|
|
|
279
|
+
| Unit/integration coverage | >= 80% |
|
|
280
|
+
| BDD scenarios pass | 100% |
|
|
281
|
+
| Contract tests pass | 100% |
|
|
282
|
+
| Cross-stack e2e pass | 100% |
|
|
283
|
+
| Security vulns | 0 |
|
|
284
|
+
|
|
285
|
+
## File / Path Hygiene
|
|
286
|
+
|
|
287
|
+
**Never read, write, or modify** any of these (they're local-only / secrets / build artifacts):
|
|
288
|
+
|
|
289
|
+
- `.cdh/` — project-level runtime state (managed by CLI; never hand-edit)
|
|
290
|
+
- `.opencode/`, `.claude/`, `.agents/` — tool configs (owned by user)
|
|
291
|
+
- `.qwen/`, `.idea/` — IDE / tool caches
|
|
292
|
+
- `dist/`, `*.egg-info/`, `__pycache__/`, `build/`, `.venv/`
|
|
293
|
+
- `node_modules/`, `.next/`, `.nuxt/`
|
|
294
|
+
- `.python-version`, `uv.lock` — Python toolchain pinning (user-managed)
|
|
295
|
+
- `aidlc/contracts/CHANGELOG.md` — contract changelog (managed by CLI)
|
|
296
|
+
- `aidlc/providers/` — provider config (managed by CLI)
|
|
297
|
+
|
|
298
|
+
**Global state directories** (managed at runtime, do not hand-edit):
|
|
299
|
+
- `~/.cdh/` — cdh platform global state (projects/, skills/, mcps/, state/, logs/, sessions/)
|
|
300
|
+
- `~/.onecode/` — onecode engine private state (traces, memory, mcps, skills, config)
|
|
301
|
+
|
|
302
|
+
## Forbidden Actions
|
|
303
|
+
|
|
304
|
+
- Commit secrets (API keys, tokens, passwords) — use env vars or vault
|
|
305
|
+
- Force-push to `main` / `master`
|
|
306
|
+
- Modify files outside the project root
|
|
307
|
+
- Run `npm publish` / `pip upload` without explicit user approval
|
|
308
|
+
- Hand-edit `.cdh/state.json`, `.cdh/todos.json`, `.cdh/last_session.json` — use CLI / slash commands
|
|
309
|
+
- Delete tracked files outside `dist/`, `build/`, `__pycache__/` without confirmation
|
|
310
|
+
|
|
311
|
+
## Working Conventions
|
|
312
|
+
|
|
313
|
+
This project follows the **AI-DLC (AI-Driven Lifecycle)** methodology shown above.
|
|
314
|
+
|
|
315
|
+
- **Plan first**: Use task management (TodoCreate) for any non-trivial task (3+ steps)
|
|
316
|
+
- **Route execution**:
|
|
317
|
+
- Single-step (1 tool, 1 file) → direct tool call
|
|
318
|
+
- Multi-step / multi-file / research → delegate to sub-agent
|
|
319
|
+
- **Language**: Chinese for explanations to user, English for code / comments / commit messages
|
|
320
|
+
- **Verification**: After non-trivial edits, run applicable lint/typecheck/test commands before declaring done
|
|
321
|
+
|
|
322
|
+
## Where to Find More
|
|
323
|
+
|
|
324
|
+
- **AI-DLC methodology**: `~/.cdh/skills/ai-dlc-skill/SKILL.md` (load via Skill tool; installed by cdh bootstrap)
|
|
325
|
+
- **Human-readable README**: `README.md`
|
|
326
|
+
- **Architecture / practices**: `docs/` if present, or ask the user
|
|
327
|
+
"""
|
|
328
|
+
|
|
241
329
|
REQUIREMENTS_MD = """# {project_name}
|
|
242
330
|
|
|
243
331
|
## Intent
|
|
@@ -267,9 +355,8 @@ Default cloud provider: TCB (Tencent CloudBase).
|
|
|
267
355
|
|
|
268
356
|
|
|
269
357
|
def _detect_dlc_skill(workspace_root: Path) -> bool:
|
|
270
|
-
from
|
|
271
|
-
|
|
272
|
-
return loader.get(SKILL_NAME) is not None
|
|
358
|
+
from cdh.cdh_skill_manager import CDH_PLATFORM_SKILLS_DIR
|
|
359
|
+
return (CDH_PLATFORM_SKILLS_DIR / SKILL_NAME / "SKILL.md").exists()
|
|
273
360
|
|
|
274
361
|
|
|
275
362
|
def _mkdir(path: Path) -> None:
|
|
@@ -287,6 +374,37 @@ def _write(path: Path, content: str) -> None:
|
|
|
287
374
|
path.write_text(content.lstrip("\n"), encoding="utf-8")
|
|
288
375
|
|
|
289
376
|
|
|
377
|
+
def _build_agents_component_list(active: list[ComponentSpec]) -> str:
|
|
378
|
+
if not active:
|
|
379
|
+
return ""
|
|
380
|
+
items = (f" - **{c.label}** (`{c.owns}`)" for c in active)
|
|
381
|
+
return "- **Components**:\n" + "\n".join(items)
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
def _build_agents_component_table(active: list[ComponentSpec]) -> str:
|
|
385
|
+
rows = []
|
|
386
|
+
for c in active:
|
|
387
|
+
rows.append(f"| {c.fr_prefix:7s} | {c.label:14s} | {c.owns:20s} |")
|
|
388
|
+
rows.append("| INT | Contracts, Shared | aidlc/contracts/, aidlc/packages/shared/ |")
|
|
389
|
+
return "\n".join(rows)
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
def _write_agents_and_claude_md(
|
|
393
|
+
root: Path,
|
|
394
|
+
project_name: str,
|
|
395
|
+
description: str,
|
|
396
|
+
active: list[ComponentSpec],
|
|
397
|
+
) -> None:
|
|
398
|
+
content = AGENTS_MD_TEMPLATE.format(
|
|
399
|
+
project_name=project_name,
|
|
400
|
+
description=description or f"AI-DLC monorepo project: {project_name}",
|
|
401
|
+
component_list=_build_agents_component_list(active),
|
|
402
|
+
component_table=_build_agents_component_table(active),
|
|
403
|
+
)
|
|
404
|
+
_write(root / "AGENTS.md", content)
|
|
405
|
+
_write(root / "CLAUDE.md", content)
|
|
406
|
+
|
|
407
|
+
|
|
290
408
|
def _component_to_dict(c: ComponentSpec) -> dict:
|
|
291
409
|
out = {
|
|
292
410
|
"id": c.id,
|
|
@@ -298,19 +416,27 @@ def _component_to_dict(c: ComponentSpec) -> dict:
|
|
|
298
416
|
return out
|
|
299
417
|
|
|
300
418
|
|
|
301
|
-
def _build_project_yaml(
|
|
419
|
+
def _build_project_yaml(
|
|
420
|
+
active: list[ComponentSpec],
|
|
421
|
+
cross_cutting_ids: list[str],
|
|
422
|
+
name: str = "",
|
|
423
|
+
description: str = "",
|
|
424
|
+
) -> dict:
|
|
302
425
|
cross_cutting: dict = {"fr_prefix": "INT"}
|
|
303
426
|
if "contracts" in cross_cutting_ids:
|
|
304
|
-
cross_cutting["contracts"] = "contracts/"
|
|
427
|
+
cross_cutting["contracts"] = "aidlc/contracts/"
|
|
305
428
|
if "shared" in cross_cutting_ids:
|
|
306
|
-
cross_cutting["shared_types"] = "packages/shared/"
|
|
307
|
-
|
|
429
|
+
cross_cutting["shared_types"] = "aidlc/packages/shared/"
|
|
430
|
+
doc: dict = {
|
|
431
|
+
"name": name,
|
|
432
|
+
"description": description,
|
|
308
433
|
"stack": {
|
|
309
434
|
"topology": "monorepo",
|
|
310
435
|
"components": [_component_to_dict(c) for c in active],
|
|
311
436
|
"cross_cutting": cross_cutting,
|
|
312
|
-
}
|
|
437
|
+
},
|
|
313
438
|
}
|
|
439
|
+
return doc
|
|
314
440
|
|
|
315
441
|
|
|
316
442
|
def _build_component_table(active: list[ComponentSpec]) -> str:
|
|
@@ -343,15 +469,15 @@ def _scaffold_cross_cutting(cross_ids: list[str], root: Path) -> None:
|
|
|
343
469
|
for p in spec.paths:
|
|
344
470
|
target = root / p
|
|
345
471
|
if p.endswith((".yaml", ".py", ".md")):
|
|
346
|
-
if p == "contracts/CHANGELOG.md":
|
|
472
|
+
if p == "aidlc/contracts/CHANGELOG.md":
|
|
347
473
|
_write(target, CHANGELOG_MD)
|
|
348
|
-
elif p == "providers/tcb/provider.yaml":
|
|
474
|
+
elif p == "aidlc/providers/tcb/provider.yaml":
|
|
349
475
|
_write(target, TCB_PROVIDER_YAML)
|
|
350
|
-
elif p == "providers/tcb/deployment.yaml":
|
|
476
|
+
elif p == "aidlc/providers/tcb/deployment.yaml":
|
|
351
477
|
_write(target, TCB_DEPLOYMENT_YAML)
|
|
352
|
-
elif p == "providers/tcb/preview.yaml":
|
|
478
|
+
elif p == "aidlc/providers/tcb/preview.yaml":
|
|
353
479
|
_write(target, TCB_PREVIEW_YAML)
|
|
354
|
-
elif p.startswith("tools/") and p.endswith(".py"):
|
|
480
|
+
elif p.startswith("aidlc/tools/") and p.endswith(".py"):
|
|
355
481
|
_write(target, TOOL_STUB)
|
|
356
482
|
target.chmod(0o755)
|
|
357
483
|
else:
|
|
@@ -369,11 +495,14 @@ def _write_project_yaml(
|
|
|
369
495
|
description: str,
|
|
370
496
|
) -> None:
|
|
371
497
|
_write(
|
|
372
|
-
root / "project.yaml",
|
|
373
|
-
yaml.dump(
|
|
498
|
+
root / "aidlc" / "project.yaml",
|
|
499
|
+
yaml.dump(
|
|
500
|
+
_build_project_yaml(active, cross_cutting_ids, name=project_name, description=description),
|
|
501
|
+
default_flow_style=False,
|
|
502
|
+
),
|
|
374
503
|
)
|
|
375
504
|
_write(
|
|
376
|
-
root / "requirements.md",
|
|
505
|
+
root / "aidlc" / "requirements.md",
|
|
377
506
|
REQUIREMENTS_MD.format(
|
|
378
507
|
project_name=project_name,
|
|
379
508
|
description=description or f"AI-DLC monorepo project: {project_name}",
|
|
@@ -381,7 +510,7 @@ def _write_project_yaml(
|
|
|
381
510
|
),
|
|
382
511
|
)
|
|
383
512
|
_write(root / ".gitignore", GITIGNORE_CONTENT)
|
|
384
|
-
_write(root / "CHANGELOG.md", CHANGELOG_MD)
|
|
513
|
+
_write(root / "aidlc" / "CHANGELOG.md", CHANGELOG_MD)
|
|
385
514
|
|
|
386
515
|
|
|
387
516
|
def init_dlc_project(
|
|
@@ -391,15 +520,15 @@ def init_dlc_project(
|
|
|
391
520
|
) -> bool:
|
|
392
521
|
"""Scaffold project metadata only (no apps/*, no cross-cutting dirs).
|
|
393
522
|
|
|
394
|
-
Writes project.yaml (with empty components list), requirements.md,
|
|
395
|
-
.gitignore, and CHANGELOG.md. The user is expected to add components
|
|
523
|
+
Writes project.yaml (with empty components list), aidlc/requirements.md,
|
|
524
|
+
.gitignore, and aidlc/CHANGELOG.md. The user is expected to add components
|
|
396
525
|
and cross-cutting items later via add_component / add_cross_cutting.
|
|
397
526
|
|
|
398
527
|
Returns True if scaffolding was performed.
|
|
399
528
|
|
|
400
529
|
Raises RuntimeError if ai-dlc-skill is not available — the directory
|
|
401
530
|
is left untouched in that case so callers don't end up with a
|
|
402
|
-
half-initialized project (.cdh/ written but no project.yaml).
|
|
531
|
+
half-initialized project (.cdh/ written but no aidlc/project.yaml).
|
|
403
532
|
"""
|
|
404
533
|
if not _detect_dlc_skill(workspace_root):
|
|
405
534
|
raise RuntimeError(
|
|
@@ -415,6 +544,7 @@ def init_dlc_project(
|
|
|
415
544
|
cross_cutting_ids=[],
|
|
416
545
|
description=description,
|
|
417
546
|
)
|
|
547
|
+
_write_agents_and_claude_md(root, project_name, description, [])
|
|
418
548
|
return True
|
|
419
549
|
|
|
420
550
|
|
|
@@ -457,7 +587,9 @@ def scaffold_dlc_project(
|
|
|
457
587
|
|
|
458
588
|
root = workspace_root.resolve()
|
|
459
589
|
active = [COMPONENT_BY_ID[cid] for cid in components]
|
|
460
|
-
all_cross_ids = [
|
|
590
|
+
all_cross_ids = [
|
|
591
|
+
c.id for c in CROSS_CUTTING if c.id not in ("provider", "tools")
|
|
592
|
+
]
|
|
461
593
|
|
|
462
594
|
_write_project_yaml(
|
|
463
595
|
root=root,
|
|
@@ -471,10 +603,27 @@ def scaffold_dlc_project(
|
|
|
471
603
|
_scaffold_component(c, root)
|
|
472
604
|
|
|
473
605
|
_scaffold_cross_cutting(all_cross_ids, root)
|
|
606
|
+
_write_agents_and_claude_md(root, project_name, description, active)
|
|
474
607
|
|
|
475
608
|
return True
|
|
476
609
|
|
|
477
610
|
|
|
611
|
+
def _regenerate_agents_and_claude_md(root: Path) -> None:
|
|
612
|
+
project_yaml = root / "aidlc" / "project.yaml"
|
|
613
|
+
if not project_yaml.exists():
|
|
614
|
+
return
|
|
615
|
+
data = yaml.safe_load(project_yaml.read_text(encoding="utf-8")) or {}
|
|
616
|
+
name = data.get("name", root.name)
|
|
617
|
+
description = data.get("description", "")
|
|
618
|
+
components = data.get("stack", {}).get("components", []) or []
|
|
619
|
+
active = []
|
|
620
|
+
for c in components:
|
|
621
|
+
spec = COMPONENT_BY_ID.get(c.get("id", ""))
|
|
622
|
+
if spec:
|
|
623
|
+
active.append(spec)
|
|
624
|
+
_write_agents_and_claude_md(root, name, description, active)
|
|
625
|
+
|
|
626
|
+
|
|
478
627
|
def add_component(
|
|
479
628
|
workspace_root: Path,
|
|
480
629
|
component_id: str,
|
|
@@ -482,7 +631,7 @@ def add_component(
|
|
|
482
631
|
"""Add a single application component to an existing project.
|
|
483
632
|
|
|
484
633
|
Creates apps/<owns>/{src,tests/unit,tests/e2e,features} with
|
|
485
|
-
.gitkeep files and updates project.yaml's stack.components list.
|
|
634
|
+
.gitkeep files and updates aidlc/project.yaml's stack.components list.
|
|
486
635
|
|
|
487
636
|
Returns True if the component was added, False if it was already
|
|
488
637
|
present. Raises ValueError on unknown component id.
|
|
@@ -495,10 +644,10 @@ def add_component(
|
|
|
495
644
|
)
|
|
496
645
|
|
|
497
646
|
root = workspace_root.resolve()
|
|
498
|
-
project_yaml = root / "project.yaml"
|
|
647
|
+
project_yaml = root / "aidlc" / "project.yaml"
|
|
499
648
|
if not project_yaml.exists():
|
|
500
649
|
raise FileNotFoundError(
|
|
501
|
-
f"project.yaml not found at {root}. Run 'cdh project init' first."
|
|
650
|
+
f"aidlc/project.yaml not found at {root}. Run 'cdh project init' first."
|
|
502
651
|
)
|
|
503
652
|
|
|
504
653
|
data = yaml.safe_load(project_yaml.read_text(encoding="utf-8")) or {}
|
|
@@ -514,6 +663,7 @@ def add_component(
|
|
|
514
663
|
yaml.dump(data, default_flow_style=False),
|
|
515
664
|
encoding="utf-8",
|
|
516
665
|
)
|
|
666
|
+
_regenerate_agents_and_claude_md(root)
|
|
517
667
|
return True
|
|
518
668
|
|
|
519
669
|
|
|
@@ -523,7 +673,7 @@ def add_cross_cutting(
|
|
|
523
673
|
) -> bool:
|
|
524
674
|
"""Add a single cross-cutting item to an existing project.
|
|
525
675
|
|
|
526
|
-
Creates the relevant directories/files and updates project.yaml
|
|
676
|
+
Creates the relevant directories/files and updates aidlc/project.yaml
|
|
527
677
|
so that stack.cross_cutting references the new path.
|
|
528
678
|
|
|
529
679
|
Returns True if the item was added, False if it was already present.
|
|
@@ -537,10 +687,10 @@ def add_cross_cutting(
|
|
|
537
687
|
)
|
|
538
688
|
|
|
539
689
|
root = workspace_root.resolve()
|
|
540
|
-
project_yaml = root / "project.yaml"
|
|
690
|
+
project_yaml = root / "aidlc" / "project.yaml"
|
|
541
691
|
if not project_yaml.exists():
|
|
542
692
|
raise FileNotFoundError(
|
|
543
|
-
f"project.yaml not found at {root}. Run 'cdh project init' first."
|
|
693
|
+
f"aidlc/project.yaml not found at {root}. Run 'cdh project init' first."
|
|
544
694
|
)
|
|
545
695
|
|
|
546
696
|
cross_paths = [root / p for p in spec.paths]
|
|
@@ -552,7 +702,7 @@ def add_cross_cutting(
|
|
|
552
702
|
data = yaml.safe_load(project_yaml.read_text(encoding="utf-8")) or {}
|
|
553
703
|
cross_cutting = data.setdefault("stack", {}).setdefault("cross_cutting", {})
|
|
554
704
|
if cross_id == "contracts":
|
|
555
|
-
cross_cutting["contracts"] = "contracts/"
|
|
705
|
+
cross_cutting["contracts"] = "aidlc/contracts/"
|
|
556
706
|
elif cross_id == "shared":
|
|
557
707
|
cross_cutting["shared_types"] = "packages/shared/"
|
|
558
708
|
|
|
@@ -560,6 +710,7 @@ def add_cross_cutting(
|
|
|
560
710
|
yaml.dump(data, default_flow_style=False),
|
|
561
711
|
encoding="utf-8",
|
|
562
712
|
)
|
|
713
|
+
_regenerate_agents_and_claude_md(root)
|
|
563
714
|
return True
|
|
564
715
|
|
|
565
716
|
|
package/onecode/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "1.0.
|
|
1
|
+
__version__ = "1.0.5"
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|