dadaia-workspace 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dadaia_workspace-0.1.0/PKG-INFO +27 -0
- dadaia_workspace-0.1.0/README.md +11 -0
- dadaia_workspace-0.1.0/dadaia_workspace/__init__.py +0 -0
- dadaia_workspace-0.1.0/dadaia_workspace/cli/__init__.py +0 -0
- dadaia_workspace-0.1.0/dadaia_workspace/cli/commands/__init__.py +0 -0
- dadaia_workspace-0.1.0/dadaia_workspace/cli/commands/academy.py +113 -0
- dadaia_workspace-0.1.0/dadaia_workspace/cli/commands/context.py +222 -0
- dadaia_workspace-0.1.0/dadaia_workspace/cli/commands/doctor.py +53 -0
- dadaia_workspace-0.1.0/dadaia_workspace/cli/commands/export.py +67 -0
- dadaia_workspace-0.1.0/dadaia_workspace/cli/commands/import_.py +89 -0
- dadaia_workspace-0.1.0/dadaia_workspace/cli/commands/init.py +51 -0
- dadaia_workspace-0.1.0/dadaia_workspace/cli/commands/orchestrate.py +311 -0
- dadaia_workspace-0.1.0/dadaia_workspace/cli/commands/public.py +77 -0
- dadaia_workspace-0.1.0/dadaia_workspace/cli/commands/repos.py +40 -0
- dadaia_workspace-0.1.0/dadaia_workspace/cli/main.py +38 -0
- dadaia_workspace-0.1.0/dadaia_workspace/container.py +133 -0
- dadaia_workspace-0.1.0/dadaia_workspace/core/__init__.py +0 -0
- dadaia_workspace-0.1.0/dadaia_workspace/core/exceptions.py +57 -0
- dadaia_workspace-0.1.0/dadaia_workspace/core/models/__init__.py +0 -0
- dadaia_workspace-0.1.0/dadaia_workspace/core/models/course.py +13 -0
- dadaia_workspace-0.1.0/dadaia_workspace/core/models/export.py +32 -0
- dadaia_workspace-0.1.0/dadaia_workspace/core/models/import_.py +32 -0
- dadaia_workspace-0.1.0/dadaia_workspace/core/models/run_state.py +104 -0
- dadaia_workspace-0.1.0/dadaia_workspace/core/models/spec_context.py +21 -0
- dadaia_workspace-0.1.0/dadaia_workspace/core/models/workflow.py +60 -0
- dadaia_workspace-0.1.0/dadaia_workspace/core/models/workspace.py +51 -0
- dadaia_workspace-0.1.0/dadaia_workspace/core/protocols/__init__.py +0 -0
- dadaia_workspace-0.1.0/dadaia_workspace/core/protocols/agent_dispatcher.py +17 -0
- dadaia_workspace-0.1.0/dadaia_workspace/core/protocols/context_store.py +13 -0
- dadaia_workspace-0.1.0/dadaia_workspace/core/protocols/course_store.py +13 -0
- dadaia_workspace-0.1.0/dadaia_workspace/core/protocols/git_client.py +15 -0
- dadaia_workspace-0.1.0/dadaia_workspace/core/protocols/primary_context_store.py +16 -0
- dadaia_workspace-0.1.0/dadaia_workspace/core/protocols/run_state_store.py +15 -0
- dadaia_workspace-0.1.0/dadaia_workspace/core/protocols/runtime_env.py +17 -0
- dadaia_workspace-0.1.0/dadaia_workspace/core/protocols/storage.py +24 -0
- dadaia_workspace-0.1.0/dadaia_workspace/core/protocols/workflow_store.py +11 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/__init__.py +0 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/__init__.py +0 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/00_dadaia_workspace/01_visao_geral_do_workspace.md +80 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/00_dadaia_workspace/02_arquitetura_do_runtime.md +86 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/00_dadaia_workspace/03_fluxo_de_trabalho_orientado_a_sdd.md +84 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/00_dadaia_workspace/06_specify_e_implementacao_por_spec/01_o_fluxo_sdd_completo.md +119 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/00_dadaia_workspace/06_specify_e_implementacao_por_spec/02_escrevendo_specs_executaveis.md +154 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/00_dadaia_workspace/06_specify_e_implementacao_por_spec/03_implementacao_guiada_por_spec_no_dadaia_workspace.md +153 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/00_dadaia_workspace/06_specify_e_implementacao_por_spec/EXAMPLE.md +166 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/00_dadaia_workspace/06_specify_e_implementacao_por_spec/EXERCISES.md +133 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/00_dadaia_workspace/06_specify_e_implementacao_por_spec/README.md +32 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/00_dadaia_workspace/06_specify_e_implementacao_por_spec/REFERENCES.md +44 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/00_dadaia_workspace/EXAMPLE.md +84 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/00_dadaia_workspace/EXERCISES.md +113 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/00_dadaia_workspace/README.md +29 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/00_dadaia_workspace/REFERENCES.md +22 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/01_spec_driven_development/01_por_que_sdd_existe.md +45 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/01_spec_driven_development/02_artefatos_e_escrita_executavel.md +59 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/01_spec_driven_development/03_sdd_na_pratica_no_dadaia_workspace.md +63 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/01_spec_driven_development/EXAMPLE.md +81 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/01_spec_driven_development/EXERCISES.md +115 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/01_spec_driven_development/README.md +25 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/01_spec_driven_development/REFERENCES.md +29 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/03_multi_agents/01_o_que_e_um_agent.md +81 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/03_multi_agents/02_quando_orquestrar_e_qual_padrao_usar.md +92 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/03_multi_agents/03_guardrails_memoria_e_governanca.md +69 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/03_multi_agents/EXAMPLE.md +75 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/03_multi_agents/EXERCISES.md +114 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/03_multi_agents/README.md +24 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/03_multi_agents/REFERENCES.md +25 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/05_opencode/01_modelo_mental_e_cli.md +44 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/05_opencode/02_commands_rules_e_skills.md +68 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/05_opencode/03_tools_permissoes_e_automacao.md +65 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/05_opencode/EXAMPLE.md +69 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/05_opencode/EXERCISES.md +123 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/05_opencode/README.md +25 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/05_opencode/REFERENCES.md +24 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/06_claude_code/01_modelo_mental_do_claude_code.md +72 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/06_claude_code/02_commands_skills_e_memoria.md +80 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/06_claude_code/03_operacao_segura_e_produtiva.md +62 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/06_claude_code/EXAMPLE.md +71 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/06_claude_code/EXERCISES.md +132 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/06_claude_code/README.md +25 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/06_claude_code/REFERENCES.md +22 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/07_codex/01_codex_hello_word.md +173 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/07_codex/02_codex_models.md +248 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/07_codex/03_codex_pricing.md +188 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/07_codex/04_codex_advanced.md +245 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/08_pi_agent/01_modelo_mental_e_setup.md +83 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/08_pi_agent/02_operacao_cli_sessoes_e_contexto.md +87 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/08_pi_agent/03_customizacao_extensions_skills_packages.md +85 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/08_pi_agent/EXERCISES.md +72 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/08_pi_agent/README.md +30 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/08_pi_agent/REFERENCES.md +26 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/09_openclaw/01_onboarding_e_setup_local.md +72 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/09_openclaw/02_cli_agents_models_sessions.md +77 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/09_openclaw/03_hooks_memoria_message_e_operacao_segura.md +72 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/09_openclaw/EXERCISES.md +86 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/09_openclaw/README.md +29 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/09_openclaw/REFERENCES.md +33 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/10_hermes_agent/01_quickstart_modelos_e_config.md +64 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/10_hermes_agent/02_gateway_automacao_e_operacao.md +58 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/10_hermes_agent/03_learning_path_e_playbooks.md +80 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/10_hermes_agent/EXERCISES.md +75 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/10_hermes_agent/README.md +29 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/knowledge_basis/10_hermes_agent/REFERENCES.md +23 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/academy/service.py +116 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/export/__init__.py +0 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/export/service.py +187 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/import_/__init__.py +0 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/import_/service.py +258 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/orchestration/__init__.py +1 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/orchestration/resolver.py +51 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/orchestration/runner.py +203 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/orchestration/service.py +282 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/public/__init__.py +0 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/public/service.py +19 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/repos/__init__.py +0 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/repos/service.py +14 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/spec_context/__init__.py +0 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/spec_context/doctor.py +182 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/spec_context/service.py +259 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/workspace/__init__.py +0 -0
- dadaia_workspace-0.1.0/dadaia_workspace/features/workspace/service.py +123 -0
- dadaia_workspace-0.1.0/dadaia_workspace/infrastructure/__init__.py +0 -0
- dadaia_workspace-0.1.0/dadaia_workspace/infrastructure/claude_agent_dispatcher.py +77 -0
- dadaia_workspace-0.1.0/dadaia_workspace/infrastructure/cli_agent_dispatcher.py +129 -0
- dadaia_workspace-0.1.0/dadaia_workspace/infrastructure/excel_reader.py +29 -0
- dadaia_workspace-0.1.0/dadaia_workspace/infrastructure/git_subprocess.py +56 -0
- dadaia_workspace-0.1.0/dadaia_workspace/infrastructure/json_context_store.py +79 -0
- dadaia_workspace-0.1.0/dadaia_workspace/infrastructure/json_course_store.py +77 -0
- dadaia_workspace-0.1.0/dadaia_workspace/infrastructure/json_primary_context_store.py +30 -0
- dadaia_workspace-0.1.0/dadaia_workspace/infrastructure/json_run_state_store.py +170 -0
- dadaia_workspace-0.1.0/dadaia_workspace/infrastructure/markdown_workflow_store.py +250 -0
- dadaia_workspace-0.1.0/dadaia_workspace/infrastructure/public_assets.py +562 -0
- dadaia_workspace-0.1.0/dadaia_workspace/infrastructure/python_env.py +21 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/agents/devops-engineer.md +647 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/agents/game-developer.md +233 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/agents/product-engineer.md +242 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/agents/qa-engineer.md +279 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/agents/software-architect.md +451 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/agents/software-engineer.md +218 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/commands/dadaia-academy.md +58 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/commands/dadaia-workspace-doctor.md +36 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/commands/dadaia-workspace-refine-specs.md +30 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/commands/spec-context.md +33 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/data/AGENTS.md +365 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/data/repos.xlsx +0 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/plugins/ctx-inject.ts +36 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/rules/dadaia-workspace-dev-guardrail.md +18 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/rules/game-developer-scope.md +35 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/scaffold/SPEC.md +46 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/scaffold/constitution.md +62 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/scaffold/foundation/SPEC.md +71 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/scaffold/memory/architecture.md +28 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/scaffold/memory/product.md +33 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/scaffold/memory/tech-stack.md +34 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/scripts/ctx-inject.sh +32 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/scripts/sdd-spec-gate.sh +125 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/skills/architect-code-audit/SKILL.md +322 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/skills/architect-design-patterns/SKILL.md +213 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/skills/dadaia-grill-me/SKILL.md +234 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/skills/dadaia-task-manager/SKILL.md +128 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/skills/dadaia-workspace-doctor/SKILL.md +94 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/skills/dadaia-workspace-manager/SKILL.md +156 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/skills/dadaia-workspace-spec-navigator/SKILL.md +51 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/skills/dadaia-workspace-spec-reviewer/SKILL.md +43 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/skills/devops-deploy-strategies/SKILL.md +420 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/skills/devops-gitflow-governance/SKILL.md +274 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/skills/game-map-architect/SKILL.md +364 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/skills/game-packaging-distribution/SKILL.md +320 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/skills/game-physics-engine/SKILL.md +394 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/skills/game-platform-browser/SKILL.md +357 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/skills/game-platform-godot/SKILL.md +279 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/skills/game-platform-unity/SKILL.md +323 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/skills/game-platform-unreal/SKILL.md +244 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/skills/github-actions-pipelines/SKILL.md +359 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/templates/repo-AGENTS.md +50 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/workflows/spec-refinement.workflow.md +98 -0
- dadaia_workspace-0.1.0/dadaia_workspace/public/workflows/tdd-cycle.workflow.md +74 -0
- dadaia_workspace-0.1.0/pyproject.toml +59 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: dadaia-workspace
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: AI-native workspace management CLI with Spec Context Projects
|
|
5
|
+
Author: Marco Menezes
|
|
6
|
+
Author-email: marcoaurelioreislima@gmail.com
|
|
7
|
+
Requires-Python: >=3.12,<4.0
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
10
|
+
Requires-Dist: openpyxl (>=3.1,<4.0)
|
|
11
|
+
Requires-Dist: pyyaml (>=6.0,<7.0)
|
|
12
|
+
Requires-Dist: rich (>=13,<14)
|
|
13
|
+
Requires-Dist: typer[all] (>=0.25)
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
|
|
16
|
+
# dadaia-workspace
|
|
17
|
+
|
|
18
|
+
## Guardrails do Repositorio
|
|
19
|
+
|
|
20
|
+
- `bash scripts/check_no_repo_local_claude.sh`: falha se a pasta proibida `dadaia-workspace/.claude/` reaparecer no subprojeto.
|
|
21
|
+
- A unica fonte versionada de rules, skills e commands do produto e `dadaia_workspace/public/`.
|
|
22
|
+
- O destino de instalacao continua sendo a `.claude/` na raiz do workspace do usuario.
|
|
23
|
+
|
|
24
|
+
## VPS
|
|
25
|
+
|
|
26
|
+
Gerenciado a partir de `srv1608865.hstgr.cloud` — setup 2026-05-08.
|
|
27
|
+
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# dadaia-workspace
|
|
2
|
+
|
|
3
|
+
## Guardrails do Repositorio
|
|
4
|
+
|
|
5
|
+
- `bash scripts/check_no_repo_local_claude.sh`: falha se a pasta proibida `dadaia-workspace/.claude/` reaparecer no subprojeto.
|
|
6
|
+
- A unica fonte versionada de rules, skills e commands do produto e `dadaia_workspace/public/`.
|
|
7
|
+
- O destino de instalacao continua sendo a `.claude/` na raiz do workspace do usuario.
|
|
8
|
+
|
|
9
|
+
## VPS
|
|
10
|
+
|
|
11
|
+
Gerenciado a partir de `srv1608865.hstgr.cloud` — setup 2026-05-08.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"""dadaia academy subcommands."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
import typer
|
|
6
|
+
from rich.console import Console
|
|
7
|
+
from rich.table import Table
|
|
8
|
+
|
|
9
|
+
from dadaia_workspace import container
|
|
10
|
+
from dadaia_workspace.core.exceptions import ContextAlreadyExistsError, ContextNotFoundError
|
|
11
|
+
from dadaia_workspace.features.academy.service import AcademyService
|
|
12
|
+
|
|
13
|
+
app = typer.Typer(help="Manage Academy courses.")
|
|
14
|
+
console = Console()
|
|
15
|
+
err_console = Console(stderr=True)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _resolve_workspace() -> Path:
|
|
19
|
+
cwd = Path.cwd()
|
|
20
|
+
for parent in [cwd, *cwd.parents]:
|
|
21
|
+
if (parent / ".dadaia").exists():
|
|
22
|
+
return parent
|
|
23
|
+
return cwd
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _academy_service() -> AcademyService:
|
|
27
|
+
workspace_root = _resolve_workspace()
|
|
28
|
+
return container.build_academy_service(workspace_root)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@app.command()
|
|
32
|
+
def modules() -> None:
|
|
33
|
+
"""List available Academy modules from the built-in knowledge base."""
|
|
34
|
+
svc = _academy_service()
|
|
35
|
+
mods = svc.list_modules()
|
|
36
|
+
if not mods:
|
|
37
|
+
console.print("[dim]No modules found.[/dim]")
|
|
38
|
+
return
|
|
39
|
+
for number, name in mods:
|
|
40
|
+
console.print(f" {number:2d} {name}")
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@app.command(name="list")
|
|
44
|
+
def list_all() -> None:
|
|
45
|
+
"""List all courses in this workspace."""
|
|
46
|
+
svc = _academy_service()
|
|
47
|
+
courses = svc.list_all()
|
|
48
|
+
if not courses:
|
|
49
|
+
console.print("[dim]No courses found. Use 'dadaia academy create' to start one.[/dim]")
|
|
50
|
+
return
|
|
51
|
+
|
|
52
|
+
table = Table(title="Academy Courses")
|
|
53
|
+
table.add_column("Slug", style="bold")
|
|
54
|
+
table.add_column("Name")
|
|
55
|
+
table.add_column("Module")
|
|
56
|
+
table.add_column("Created")
|
|
57
|
+
|
|
58
|
+
for course in courses:
|
|
59
|
+
table.add_row(
|
|
60
|
+
course.slug,
|
|
61
|
+
course.name,
|
|
62
|
+
f"{course.module_number} — {course.module_name}",
|
|
63
|
+
course.created_at[:10],
|
|
64
|
+
)
|
|
65
|
+
console.print(table)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
@app.command()
|
|
69
|
+
def create(
|
|
70
|
+
name: str = typer.Argument(..., help="Course name"),
|
|
71
|
+
module: int = typer.Option(..., "--module", "-m", help="Module number"),
|
|
72
|
+
) -> None:
|
|
73
|
+
"""Create a new course from a knowledge base module."""
|
|
74
|
+
try:
|
|
75
|
+
course = _academy_service().create(name, module)
|
|
76
|
+
console.print(
|
|
77
|
+
f"[green]✓[/green] Course '[bold]{course.slug}[/bold]' created "
|
|
78
|
+
f"from module {course.module_number} ({course.module_name})"
|
|
79
|
+
)
|
|
80
|
+
console.print(f" Course dir: {course.course_dir}")
|
|
81
|
+
except (ContextAlreadyExistsError, ContextNotFoundError) as e:
|
|
82
|
+
err_console.print(f"[red]Error:[/red] {e}")
|
|
83
|
+
raise typer.Exit(1) from None
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
@app.command()
|
|
87
|
+
def update(
|
|
88
|
+
slug: str = typer.Argument(..., help="Course slug"),
|
|
89
|
+
module: int = typer.Option(..., "--module", "-m", help="New module number"),
|
|
90
|
+
) -> None:
|
|
91
|
+
"""Update an existing course to use a different module."""
|
|
92
|
+
try:
|
|
93
|
+
course = _academy_service().update(slug, module)
|
|
94
|
+
console.print(
|
|
95
|
+
f"[green]✓[/green] Course '[bold]{course.slug}[/bold]' updated "
|
|
96
|
+
f"to module {course.module_number} ({course.module_name})"
|
|
97
|
+
)
|
|
98
|
+
except ContextNotFoundError as e:
|
|
99
|
+
err_console.print(f"[red]Error:[/red] {e}")
|
|
100
|
+
raise typer.Exit(1) from None
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
@app.command()
|
|
104
|
+
def delete(
|
|
105
|
+
slug: str = typer.Argument(..., help="Course slug to delete"),
|
|
106
|
+
) -> None:
|
|
107
|
+
"""Delete a course and its working directory."""
|
|
108
|
+
try:
|
|
109
|
+
_academy_service().delete(slug)
|
|
110
|
+
console.print(f"[green]✓[/green] Course '[bold]{slug}[/bold]' deleted")
|
|
111
|
+
except ContextNotFoundError as e:
|
|
112
|
+
err_console.print(f"[red]Error:[/red] {e}")
|
|
113
|
+
raise typer.Exit(1) from None
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
"""dadaia context subcommands."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
import typer
|
|
7
|
+
from rich.console import Console
|
|
8
|
+
from rich.table import Table
|
|
9
|
+
|
|
10
|
+
from dadaia_workspace import container
|
|
11
|
+
from dadaia_workspace.core.exceptions import (
|
|
12
|
+
ContextAlreadyExistsError,
|
|
13
|
+
ContextNotFoundError,
|
|
14
|
+
ContextStateError,
|
|
15
|
+
RepoCatalogError,
|
|
16
|
+
WorkspaceNotInitializedError,
|
|
17
|
+
)
|
|
18
|
+
from dadaia_workspace.core.models.spec_context import ContextState, SpecContextProject
|
|
19
|
+
from dadaia_workspace.features.spec_context.service import SpecContextService
|
|
20
|
+
|
|
21
|
+
app = typer.Typer(help="Manage Spec Context Projects.")
|
|
22
|
+
console = Console()
|
|
23
|
+
err_console = Console(stderr=True)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _resolve_workspace() -> Path:
|
|
27
|
+
cwd = Path.cwd()
|
|
28
|
+
for parent in [cwd, *cwd.parents]:
|
|
29
|
+
if (parent / ".dadaia").exists():
|
|
30
|
+
return parent
|
|
31
|
+
return cwd
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _ctx_service() -> SpecContextService:
|
|
35
|
+
try:
|
|
36
|
+
return container.build_spec_context_service(_resolve_workspace())
|
|
37
|
+
except WorkspaceNotInitializedError:
|
|
38
|
+
err_console.print(
|
|
39
|
+
"[red]Error:[/red] Workspace not initialized. Run [bold]dadaia init[/bold] first."
|
|
40
|
+
)
|
|
41
|
+
raise typer.Exit(1) from None
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _ctx_to_dict(ctx: SpecContextProject) -> dict: # type: ignore[type-arg]
|
|
45
|
+
return {
|
|
46
|
+
"name": ctx.name,
|
|
47
|
+
"state": ctx.state.value,
|
|
48
|
+
"repo_slug": ctx.repo_slug,
|
|
49
|
+
"repo_url": ctx.repo_url,
|
|
50
|
+
"is_primary": ctx.is_primary,
|
|
51
|
+
"created_at": ctx.created_at,
|
|
52
|
+
"activated_at": ctx.activated_at,
|
|
53
|
+
"current_branch": ctx.current_branch,
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@app.command()
|
|
58
|
+
def create(
|
|
59
|
+
name: str = typer.Argument(..., help="Context name"),
|
|
60
|
+
repo: str = typer.Option(..., "--repo", help="Repo slug (directory name under repos/)"),
|
|
61
|
+
) -> None:
|
|
62
|
+
"""Create a new Spec Context Project in state 'inativo'."""
|
|
63
|
+
workspace_root = _resolve_workspace()
|
|
64
|
+
# Look up repo_url from whitelist; fall back gracefully if catalog unavailable
|
|
65
|
+
repo_url = ""
|
|
66
|
+
try:
|
|
67
|
+
repos_svc = container.build_repos_service()
|
|
68
|
+
rows = repos_svc.list_known(workspace_root)
|
|
69
|
+
for row in rows:
|
|
70
|
+
if row.get("Repo Name") == repo:
|
|
71
|
+
repo_url = row.get("Repo URL", "")
|
|
72
|
+
break
|
|
73
|
+
except (RepoCatalogError, Exception):
|
|
74
|
+
pass
|
|
75
|
+
|
|
76
|
+
try:
|
|
77
|
+
ctx = _ctx_service().create(name, repo, repo_url)
|
|
78
|
+
console.print(
|
|
79
|
+
f"[green]✓[/green] Context '[bold]{ctx.name}[/bold]' created "
|
|
80
|
+
f"(repo: {ctx.repo_slug}, state: {ctx.state})"
|
|
81
|
+
)
|
|
82
|
+
except (ContextAlreadyExistsError, ContextNotFoundError) as e:
|
|
83
|
+
err_console.print(f"[red]Error:[/red] {e}")
|
|
84
|
+
raise typer.Exit(1) from None
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@app.command(name="list")
|
|
88
|
+
def list_all() -> None:
|
|
89
|
+
"""List all Spec Context Projects."""
|
|
90
|
+
contexts = _ctx_service().list_all()
|
|
91
|
+
if not contexts:
|
|
92
|
+
console.print("[dim]No contexts found. Use 'dadaia context create' to create one.[/dim]")
|
|
93
|
+
return
|
|
94
|
+
|
|
95
|
+
table = Table(title="Spec Context Projects")
|
|
96
|
+
table.add_column("Name", style="bold")
|
|
97
|
+
table.add_column("State")
|
|
98
|
+
table.add_column("Primary")
|
|
99
|
+
table.add_column("Repo")
|
|
100
|
+
|
|
101
|
+
state_style = {
|
|
102
|
+
ContextState.ATIVO: "[green]ativo[/green]",
|
|
103
|
+
ContextState.INATIVO: "[dim]inativo[/dim]",
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
for ctx in contexts:
|
|
107
|
+
table.add_row(
|
|
108
|
+
ctx.name,
|
|
109
|
+
state_style.get(ctx.state, ctx.state.value),
|
|
110
|
+
"[bold yellow]✓[/bold yellow]" if ctx.is_primary else "",
|
|
111
|
+
ctx.repo_slug,
|
|
112
|
+
)
|
|
113
|
+
console.print(table)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
@app.command()
|
|
117
|
+
def show(
|
|
118
|
+
name: str | None = typer.Argument(None, help="Context name"),
|
|
119
|
+
json_output: bool = typer.Option(False, "--json", help="Output stable JSON contract"),
|
|
120
|
+
) -> None:
|
|
121
|
+
"""Show details of a context."""
|
|
122
|
+
svc = _ctx_service()
|
|
123
|
+
if name is None:
|
|
124
|
+
# Show primary context
|
|
125
|
+
all_ctxs = svc.list_all()
|
|
126
|
+
ctx = next((c for c in all_ctxs if c.is_primary), None)
|
|
127
|
+
else:
|
|
128
|
+
try:
|
|
129
|
+
ctx = svc.show(name)
|
|
130
|
+
except ContextNotFoundError as e:
|
|
131
|
+
err_console.print(f"[red]Error:[/red] {e}")
|
|
132
|
+
raise typer.Exit(1) from None
|
|
133
|
+
|
|
134
|
+
if json_output:
|
|
135
|
+
if ctx is None:
|
|
136
|
+
print(json.dumps({"context": None}, indent=2))
|
|
137
|
+
else:
|
|
138
|
+
print(json.dumps(_ctx_to_dict(ctx), indent=2))
|
|
139
|
+
return
|
|
140
|
+
|
|
141
|
+
if ctx is None:
|
|
142
|
+
msg = f"Context '{name}' not found." if name else "No primary context."
|
|
143
|
+
console.print(f"[dim]{msg}[/dim]")
|
|
144
|
+
return
|
|
145
|
+
|
|
146
|
+
console.print(f"[bold]Name:[/bold] {ctx.name}")
|
|
147
|
+
console.print(f"[bold]State:[/bold] {ctx.state.value}")
|
|
148
|
+
console.print(f"[bold]Primary:[/bold] {ctx.is_primary}")
|
|
149
|
+
console.print(f"[bold]Repo:[/bold] {ctx.repo_slug}")
|
|
150
|
+
console.print(f"[bold]Repo URL:[/bold] {ctx.repo_url or '—'}")
|
|
151
|
+
console.print(f"[bold]Created:[/bold] {ctx.created_at}")
|
|
152
|
+
console.print(f"[bold]Activated:[/bold] {ctx.activated_at or '—'}")
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
@app.command()
|
|
156
|
+
def activate(name: str = typer.Argument(..., help="Context name to activate")) -> None:
|
|
157
|
+
"""Activate a context (clone repo if absent; auto-promote if no primary)."""
|
|
158
|
+
try:
|
|
159
|
+
ws = _resolve_workspace()
|
|
160
|
+
ctx = container.build_spec_context_service(ws).activate(name)
|
|
161
|
+
primary_note = " [bold yellow](primary)[/bold yellow]" if ctx.is_primary else ""
|
|
162
|
+
console.print(
|
|
163
|
+
f"[green]✓[/green] Context '[bold]{ctx.name}[/bold]' is now active{primary_note}"
|
|
164
|
+
)
|
|
165
|
+
if ctx.is_primary:
|
|
166
|
+
container.build_public_service().install(ws, target="opencode", force=True)
|
|
167
|
+
except (ContextNotFoundError, ContextStateError) as e:
|
|
168
|
+
err_console.print(f"[red]Error:[/red] {e}")
|
|
169
|
+
raise typer.Exit(1) from None
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
@app.command()
|
|
173
|
+
def deactivate(name: str = typer.Argument(..., help="Context name to deactivate")) -> None:
|
|
174
|
+
"""Deactivate a context (git sync + remove repo from disk)."""
|
|
175
|
+
try:
|
|
176
|
+
ctx = _ctx_service().deactivate(name)
|
|
177
|
+
console.print(f"[green]✓[/green] Context '[bold]{ctx.name}[/bold]' deactivated")
|
|
178
|
+
except (ContextNotFoundError, ContextStateError) as e:
|
|
179
|
+
err_console.print(f"[red]Error:[/red] {e}")
|
|
180
|
+
raise typer.Exit(1) from None
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
@app.command()
|
|
184
|
+
def promote(name: str = typer.Argument(..., help="Context name to promote as primary")) -> None:
|
|
185
|
+
"""Promote an active context as the workspace primary."""
|
|
186
|
+
try:
|
|
187
|
+
ws = _resolve_workspace()
|
|
188
|
+
ctx = container.build_spec_context_service(ws).promote(name)
|
|
189
|
+
console.print(f"[green]✓[/green] Context '[bold]{ctx.name}[/bold]' is now primary")
|
|
190
|
+
container.build_public_service().install(ws, target="opencode", force=True)
|
|
191
|
+
except (ContextNotFoundError, ContextStateError) as e:
|
|
192
|
+
err_console.print(f"[red]Error:[/red] {e}")
|
|
193
|
+
raise typer.Exit(1) from None
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
@app.command()
|
|
197
|
+
def delete(name: str = typer.Argument(..., help="Context name to delete")) -> None:
|
|
198
|
+
"""Delete a context. Context must be inactive."""
|
|
199
|
+
try:
|
|
200
|
+
_ctx_service().delete(name)
|
|
201
|
+
console.print(f"[green]✓[/green] Context '[bold]{name}[/bold]' deleted")
|
|
202
|
+
except (ContextNotFoundError, ContextStateError) as e:
|
|
203
|
+
err_console.print(f"[red]Error:[/red] {e}")
|
|
204
|
+
raise typer.Exit(1) from None
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
@app.command()
|
|
208
|
+
def use(name: str = typer.Argument(..., help="Context name to isolate this session to")) -> None:
|
|
209
|
+
"""Isolate this shell session to a specific context without changing global state.
|
|
210
|
+
|
|
211
|
+
Run: eval $(dadaia context use <name>)
|
|
212
|
+
|
|
213
|
+
Sets DADAIA_CONTEXT for the current shell only. Does NOT modify spec_contexts.json
|
|
214
|
+
or primary_context.json.
|
|
215
|
+
"""
|
|
216
|
+
all_ctxs = _ctx_service().list_all()
|
|
217
|
+
ctx = next((c for c in all_ctxs if c.name == name), None)
|
|
218
|
+
if ctx is None:
|
|
219
|
+
available = ", ".join(c.name for c in all_ctxs) or "none"
|
|
220
|
+
err_console.print(f"[red]Error:[/red] Context '{name}' not found. Available: {available}")
|
|
221
|
+
raise typer.Exit(1) from None
|
|
222
|
+
print(f"export DADAIA_CONTEXT={name}")
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""CLI command: dadaia doctor [--fix]."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
import typer
|
|
6
|
+
|
|
7
|
+
from dadaia_workspace import container
|
|
8
|
+
from dadaia_workspace.core.exceptions import WorkspaceNotInitializedError
|
|
9
|
+
|
|
10
|
+
app = typer.Typer(help="Diagnose and repair workspace state.")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _resolve_workspace() -> Path:
|
|
14
|
+
cwd = Path.cwd()
|
|
15
|
+
for parent in [cwd, *cwd.parents]:
|
|
16
|
+
if (parent / ".dadaia").exists():
|
|
17
|
+
return parent
|
|
18
|
+
return cwd
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
err_console = typer.echo
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@app.callback(invoke_without_command=True)
|
|
25
|
+
def doctor(
|
|
26
|
+
fix: bool = typer.Option(False, "--fix", help="Apply automatic repairs."),
|
|
27
|
+
) -> None:
|
|
28
|
+
"""Diagnose workspace state invariants and optionally repair them."""
|
|
29
|
+
workspace_root = _resolve_workspace()
|
|
30
|
+
try:
|
|
31
|
+
dr = container.build_doctor_service(workspace_root)
|
|
32
|
+
except WorkspaceNotInitializedError:
|
|
33
|
+
typer.echo("Error: Workspace not initialized. Run 'dadaia init' first.", err=True)
|
|
34
|
+
raise typer.Exit(1) from None
|
|
35
|
+
|
|
36
|
+
issues = dr.check()
|
|
37
|
+
|
|
38
|
+
if not issues:
|
|
39
|
+
typer.echo("All invariants OK — workspace is healthy.")
|
|
40
|
+
return
|
|
41
|
+
|
|
42
|
+
typer.echo(f"Found {len(issues)} issue(s):")
|
|
43
|
+
for issue in issues:
|
|
44
|
+
fixable = "[fixable]" if issue.fixable else "[manual]"
|
|
45
|
+
typer.echo(f" {issue.code} {fixable} — {issue.description}")
|
|
46
|
+
|
|
47
|
+
if fix:
|
|
48
|
+
actions = dr.fix()
|
|
49
|
+
typer.echo(f"\nApplied {len(actions)} repair(s):")
|
|
50
|
+
for action in actions:
|
|
51
|
+
typer.echo(f" - {action}")
|
|
52
|
+
else:
|
|
53
|
+
typer.echo("\nRun 'dadaia doctor --fix' to apply automatic repairs.")
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"""dadaia export command."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Annotated
|
|
5
|
+
|
|
6
|
+
import typer
|
|
7
|
+
from rich.console import Console
|
|
8
|
+
|
|
9
|
+
from dadaia_workspace import container
|
|
10
|
+
from dadaia_workspace.core.exceptions import DadaiaError
|
|
11
|
+
from dadaia_workspace.core.models.export import ExportOptions
|
|
12
|
+
|
|
13
|
+
console = Console()
|
|
14
|
+
err_console = Console(stderr=True)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _resolve_workspace() -> Path:
|
|
18
|
+
cwd = Path.cwd()
|
|
19
|
+
for parent in [cwd, *cwd.parents]:
|
|
20
|
+
if (parent / ".dadaia").exists():
|
|
21
|
+
return parent
|
|
22
|
+
return cwd
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def export(
|
|
26
|
+
output: Annotated[
|
|
27
|
+
Path | None,
|
|
28
|
+
typer.Option("--output", "-o", help="Output directory (default: .dadaia/dist/)."),
|
|
29
|
+
] = None,
|
|
30
|
+
include_reports: Annotated[
|
|
31
|
+
bool,
|
|
32
|
+
typer.Option("--include-reports", help="Include .dadaia/reports/ in the archive."),
|
|
33
|
+
] = False,
|
|
34
|
+
exclude_mnt: Annotated[
|
|
35
|
+
bool,
|
|
36
|
+
typer.Option("--exclude-mnt", help="Exclude mnt/ container volumes from the archive."),
|
|
37
|
+
] = False,
|
|
38
|
+
list_only: Annotated[
|
|
39
|
+
bool,
|
|
40
|
+
typer.Option("--list", help="Dry-run: print manifest JSON without creating the archive."),
|
|
41
|
+
] = False,
|
|
42
|
+
) -> None:
|
|
43
|
+
"""Export workspace state to a portable .tar.gz archive.
|
|
44
|
+
|
|
45
|
+
The archive includes all durable state (.dadaia/states, academy, scripts,
|
|
46
|
+
configs, .claude rules) needed to restore the workspace on a new VPS.
|
|
47
|
+
Secrets (*.env), caches (.venv, .npm, linuxbrew) and repos/ are excluded.
|
|
48
|
+
"""
|
|
49
|
+
workspace_root = _resolve_workspace()
|
|
50
|
+
try:
|
|
51
|
+
svc = container.build_export_service(workspace_root)
|
|
52
|
+
options = ExportOptions(
|
|
53
|
+
output=output,
|
|
54
|
+
include_reports=include_reports,
|
|
55
|
+
exclude_mnt=exclude_mnt,
|
|
56
|
+
list_only=list_only,
|
|
57
|
+
)
|
|
58
|
+
result = svc.run(options)
|
|
59
|
+
except DadaiaError as e:
|
|
60
|
+
err_console.print(f"[red]Error:[/red] {e}")
|
|
61
|
+
raise typer.Exit(1) from None
|
|
62
|
+
|
|
63
|
+
if list_only:
|
|
64
|
+
return
|
|
65
|
+
|
|
66
|
+
size_kb = result.size // 1024
|
|
67
|
+
console.print(f"[green]✓[/green] {result.path} ({size_kb} KB)")
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""dadaia import command."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Annotated
|
|
5
|
+
|
|
6
|
+
import typer
|
|
7
|
+
from rich.console import Console
|
|
8
|
+
|
|
9
|
+
from dadaia_workspace.core.models.import_ import ImportOptions
|
|
10
|
+
from dadaia_workspace.features.import_.service import ImportService
|
|
11
|
+
|
|
12
|
+
console = Console()
|
|
13
|
+
err_console = Console(stderr=True)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def import_workspace(
|
|
17
|
+
archive: Annotated[
|
|
18
|
+
Path,
|
|
19
|
+
typer.Argument(help="Path to the .tar.gz archive generated by 'dadaia export'."),
|
|
20
|
+
],
|
|
21
|
+
workspace: Annotated[
|
|
22
|
+
Path | None,
|
|
23
|
+
typer.Option("--workspace", "-w", help="Destination workspace root (default: cwd)."),
|
|
24
|
+
] = None,
|
|
25
|
+
skip_mnt: Annotated[
|
|
26
|
+
bool,
|
|
27
|
+
typer.Option("--skip-mnt", help="Do not extract mnt/ container volumes."),
|
|
28
|
+
] = False,
|
|
29
|
+
skip_activate: Annotated[
|
|
30
|
+
bool,
|
|
31
|
+
typer.Option(
|
|
32
|
+
"--skip-activate",
|
|
33
|
+
help="Skip context activation; leave all contexts as inativo.",
|
|
34
|
+
),
|
|
35
|
+
] = False,
|
|
36
|
+
dry_run: Annotated[
|
|
37
|
+
bool,
|
|
38
|
+
typer.Option("--dry-run", help="Preview what would happen without changing anything."),
|
|
39
|
+
] = False,
|
|
40
|
+
) -> None:
|
|
41
|
+
"""Import a workspace from a dadaia export archive.
|
|
42
|
+
|
|
43
|
+
Extracts the archive, patches absolute paths for the new workspace root,
|
|
44
|
+
runs 'dadaia init', and re-activates all contexts that were active at
|
|
45
|
+
export time.
|
|
46
|
+
|
|
47
|
+
Typical usage on a new machine after cloning dadaia-workspace and running
|
|
48
|
+
'pip install -e .':
|
|
49
|
+
|
|
50
|
+
\b
|
|
51
|
+
cd ~/workspace
|
|
52
|
+
dadaia import /path/to/workspace-2026-05-12-100000.tar.gz
|
|
53
|
+
dadaia import /path/to/workspace-2026-05-12-100000.tar.gz --skip-mnt
|
|
54
|
+
"""
|
|
55
|
+
resolved_workspace = (workspace or Path.cwd()).resolve()
|
|
56
|
+
options = ImportOptions(
|
|
57
|
+
archive=archive.resolve(),
|
|
58
|
+
workspace=resolved_workspace,
|
|
59
|
+
skip_mnt=skip_mnt,
|
|
60
|
+
skip_activate=skip_activate,
|
|
61
|
+
dry_run=dry_run,
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
try:
|
|
65
|
+
svc = ImportService(workspace_root=resolved_workspace)
|
|
66
|
+
result = svc.run(options)
|
|
67
|
+
except ValueError as exc:
|
|
68
|
+
err_console.print(f"[red]Error:[/red] {exc}")
|
|
69
|
+
raise typer.Exit(1) from None
|
|
70
|
+
|
|
71
|
+
if dry_run:
|
|
72
|
+
return
|
|
73
|
+
|
|
74
|
+
console.print(f"\n[green]✓[/green] Workspace imported at [bold]{result.workspace_root}[/bold]")
|
|
75
|
+
console.print(f" Source: {options.archive.name}")
|
|
76
|
+
|
|
77
|
+
if result.contexts_restored:
|
|
78
|
+
console.print(f"\nContexts restored ({len(result.contexts_restored)}):")
|
|
79
|
+
for name in result.contexts_restored:
|
|
80
|
+
console.print(f" [green]✓[/green] {name}")
|
|
81
|
+
|
|
82
|
+
if result.errors:
|
|
83
|
+
console.print("\n[yellow]Activation errors (check network/git access):[/yellow]")
|
|
84
|
+
for err in result.errors:
|
|
85
|
+
console.print(f" [red]✗[/red] {err}")
|
|
86
|
+
|
|
87
|
+
console.print("\n[dim]Next steps:[/dim]")
|
|
88
|
+
console.print(" [dim]• Add secrets to services/conf/*.env (not included in export)[/dim]")
|
|
89
|
+
console.print(" [dim]• Run 'dadaia doctor' to verify workspace consistency[/dim]")
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""dadaia init command."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
import typer
|
|
6
|
+
from rich.console import Console
|
|
7
|
+
|
|
8
|
+
from dadaia_workspace import container
|
|
9
|
+
|
|
10
|
+
console = Console()
|
|
11
|
+
app = typer.Typer()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _resolve_workspace(workspace: Path | None) -> Path:
|
|
15
|
+
if workspace:
|
|
16
|
+
return workspace.resolve()
|
|
17
|
+
# Walk up from CWD looking for .claude/ or .dadaia/
|
|
18
|
+
cwd = Path.cwd()
|
|
19
|
+
for parent in [cwd, *cwd.parents]:
|
|
20
|
+
if (parent / ".claude").exists() or (parent / ".dadaia").exists():
|
|
21
|
+
return parent
|
|
22
|
+
return cwd
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@app.command()
|
|
26
|
+
def init(
|
|
27
|
+
workspace: Path | None = typer.Option(None, "--workspace", "-w", help="Workspace root path"),
|
|
28
|
+
skip_assets: bool = typer.Option(
|
|
29
|
+
False, "--skip-assets", help="Skip installing public agent assets"
|
|
30
|
+
),
|
|
31
|
+
) -> None:
|
|
32
|
+
"""Bootstrap a dadaia workspace: creates .dadaia/ and installs agent assets into .claude/."""
|
|
33
|
+
root = _resolve_workspace(workspace)
|
|
34
|
+
console.print(f"[bold]Initializing workspace:[/bold] {root}")
|
|
35
|
+
|
|
36
|
+
svc = container.build_workspace_service(root)
|
|
37
|
+
_, installed = svc.init(root, skip_assets=skip_assets)
|
|
38
|
+
|
|
39
|
+
console.print(f"[green]✓[/green] .dadaia/ bootstrapped at {root / '.dadaia'}")
|
|
40
|
+
|
|
41
|
+
if skip_assets:
|
|
42
|
+
console.print("[dim]Skipped public asset installation (--skip-assets)[/dim]")
|
|
43
|
+
else:
|
|
44
|
+
if installed:
|
|
45
|
+
console.print(
|
|
46
|
+
f"[green]✓[/green] Installed {len(installed)} asset(s) into {root / '.claude'}"
|
|
47
|
+
)
|
|
48
|
+
for item in installed:
|
|
49
|
+
console.print(f" {item}")
|
|
50
|
+
else:
|
|
51
|
+
console.print("[dim]No new assets to install (all up to date)[/dim]")
|