campfire-cli 0.1.4__tar.gz → 0.1.6__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.
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/ARCHITECTURE.md +1 -1
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/COMMAND.md +3 -0
- campfire_cli-0.1.6/PKG-INFO +151 -0
- campfire_cli-0.1.6/README.md +135 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/SPEC.md +32 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/pyproject.toml +4 -1
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/__init__.py +1 -1
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/document/cli/document_cli.py +8 -1
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/document/cli/profile_cli.py +2 -1
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/document/cli/type_cli.py +2 -1
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/document/service/document_rule_service.py +11 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/document/service/document_service.py +14 -0
- campfire_cli-0.1.6/src/campfire_cli/app/document/service/kanban_service.py +74 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/maintenance/schema/maintenance_schema.py +1 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/maintenance/service/archive_service.py +103 -22
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/maintenance/service/maintenance_service.py +2 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/maintenance/service/moc_service.py +1 -2
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/workspace/cli/config_cli.py +2 -1
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/workspace/cli/domain_cli.py +2 -1
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/workspace/cli/project_cli.py +2 -1
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/workspace/cli/space_cli.py +2 -1
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/workspace/cli/workspace_cli.py +2 -1
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/workspace/service/project_service.py +26 -6
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/workspace/service/restructure_service.py +3 -1
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/workspace/service/workspace_service.py +2 -1
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/common/agent_hints.py +11 -1
- campfire_cli-0.1.6/src/campfire_cli/common/filesystem/cwd.py +21 -0
- campfire_cli-0.1.6/src/campfire_cli/common/package_version.py +132 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/container.py +60 -3
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/main.py +7 -3
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/resources/defaults/config.yml +2 -0
- campfire_cli-0.1.6/src/campfire_cli/resources/skills/campfire-kanban-board/SKILL.md +69 -0
- campfire_cli-0.1.6/src/campfire_cli/resources/skills/campfire-task-management/SKILL.md +90 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/tests/SPEC.md +1 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/tests/integration/test_cli.py +136 -0
- campfire_cli-0.1.6/tests/perf/test_read_counts.py +139 -0
- campfire_cli-0.1.6/tests/perf/test_resolve_subprocess_count.py +71 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/tests/unit/test_common_governance.py +74 -3
- campfire_cli-0.1.6/tests/unit/test_kanban_service.py +57 -0
- campfire_cli-0.1.6/tests/unit/test_package_version.py +89 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/uv.lock +1 -1
- campfire_cli-0.1.4/PKG-INFO +0 -153
- campfire_cli-0.1.4/README.md +0 -137
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/.github/workflows/ci.yml +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/.github/workflows/release.yml +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/.gitignore +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/AGENTS.md +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/DECISIONS.md +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/LICENSE +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/alembic/SPEC.md +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/alembic/env.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/alembic/script.py.mako +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/alembic/versions/001_initial_schema.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/alembic.ini +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/scripts/SPEC.md +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/alembic/__init__.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/alembic/env.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/alembic/script.py.mako +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/alembic/versions/001_initial_schema.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/alembic/versions/002_workspace_project_registry.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/alembic/versions/003_unified_workspace_state.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/alembic/versions/004_restructure_workspace_domain.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/alembic/versions/005_decision_channel.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/alembic/versions/006_workspace_topology_index.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/alembic/versions/007_workspace_adoption.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/alembic/versions/__init__.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/SPEC.md +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/__init__.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/base/SPEC.md +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/base/__init__.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/base/cli/base_cli.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/base/repository/base_repository.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/base/schema/base_schema.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/base/service/base_service.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/decision/SPEC.md +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/decision/__init__.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/decision/cli/decision_cli.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/decision/repository/decision_repository.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/decision/schema/decision_schema.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/decision/service/decision_projection_service.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/decision/service/decision_service.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/document/SPEC.md +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/document/__init__.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/document/cli/__init__.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/document/repository/__init__.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/document/repository/document_profile_repository.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/document/repository/document_type_repository.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/document/service/__init__.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/document/service/document_profile_service.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/document/service/document_scanner.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/document/service/document_type_service.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/document/service/frontmatter_apply.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/document/service/frontmatter_formatter.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/document/service/frontmatter_plan.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/document/service/profile_registry.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/document/service/type_apply.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/document/service/type_plan.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/maintenance/SPEC.md +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/maintenance/__init__.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/maintenance/cli/maintenance_cli.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/maintenance/repository/maintenance_repository.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/maintenance/service/link_service.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/maintenance/service/maintenance_protocol.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/maintenance/service/plan_service.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/skill/SPEC.md +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/skill/__init__.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/skill/cli/skill_cli.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/skill/repository/skill_repository.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/skill/schema/skill_schema.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/skill/service/skill_service.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/workspace/SPEC.md +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/workspace/__init__.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/workspace/cli/__init__.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/workspace/cli/adoption_cli.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/workspace/cli/restructure_cli.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/workspace/repository/__init__.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/workspace/repository/adoption_repository.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/workspace/repository/manifest_repository.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/workspace/repository/restructure_repository.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/workspace/repository/workspace_repository.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/workspace/schema/__init__.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/workspace/schema/adoption_schema.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/workspace/schema/restructure_schema.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/workspace/schema/workspace_schema.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/workspace/service/__init__.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/workspace/service/adoption_protocol.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/workspace/service/adoption_service.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/workspace/service/config_service.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/workspace/service/domain_restructure_service.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/workspace/service/restructure_protocol.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/workspace/service/restructure_verifier.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/workspace/service/structure_service.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/workspace/service/workspace_protocol.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/common/SPEC.md +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/common/__init__.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/common/database/__init__.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/common/database/migrations.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/common/database/models.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/common/database/session.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/common/documents/__init__.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/common/documents/document_types.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/common/documents/frontmatter_schema.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/common/documents/markdown.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/common/exceptions/__init__.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/common/exceptions/base.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/common/filesystem/__init__.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/common/filesystem/atomic.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/common/filesystem/locking.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/common/governance/__init__.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/common/governance/issues.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/common/governance/locking.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/common/governance/snapshots.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/common/hashing.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/common/reports/__init__.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/common/reports/json_report.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/common/reports/markdown_report.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/config/SPEC.md +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/config/defaults.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/config/settings.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/resources/__init__.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/resources/bases/Agent/346/211/247/350/241/214/345/267/245/344/275/234/345/217/260.base" +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/resources/bases/SPEC.md +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/resources/bases//344/273/273/345/212/241/345/267/245/344/275/234/345/217/260.base" +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/resources/bases//345/206/263/347/255/226/345/267/245/344/275/234/345/217/260.base" +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/resources/bases//345/276/205/345/275/222/346/241/243/346/226/207/346/241/243.base" +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/resources/bases//351/241/271/347/233/256/346/226/207/346/241/243.base" +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/resources/defaults/__init__.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/resources/skills/SPEC.md +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/resources/skills/campfire-context-bootstrap/SKILL.md +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/resources/skills/campfire-context-bootstrap/agents/openai.yaml +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/resources/skills/campfire-conversation-router/SKILL.md +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/resources/skills/campfire-conversation-router/agents/openai.yaml +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/resources/skills/campfire-conversation-router/references/inbox-handoff.md +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/resources/skills/campfire-conversation-router/references/learning-intake.md +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/resources/skills/campfire-conversation-router/references/task-intake.md +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/resources/skills/campfire-document-capture/SKILL.md +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/resources/skills/campfire-inbox-triage/SKILL.md +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/resources/skills/campfire-weekly-report-writing/SKILL.md +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/resources/skills/campfire-weekly-report-writing/agents/openai.yaml +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/resources/skills/campfire-workspace-adoption/SKILL.md +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/resources/skills/campfire-workspace-maintenance/SKILL.md +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/resources/skills/campfire-workspace-maintenance/references//344/273/273/345/212/241/346/255/243/346/226/207/347/273/223/346/236/204.md" +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/resources/skills/campfire-workspace-restructure/SKILL.md +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/tests/conftest.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/tests/unit/test_agent_hints.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/tests/unit/test_atomic_write.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/tests/unit/test_config.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/tests/unit/test_frontmatter.py +0 -0
- {campfire_cli-0.1.4 → campfire_cli-0.1.6}/tests/unit/test_repository_boundaries.py +0 -0
|
@@ -72,7 +72,7 @@ Markdown Workspace Adapter 用户级状态
|
|
|
72
72
|
|
|
73
73
|
Decision 以 SQLite 当前快照和追加事件为 SSOT。全部状态在 `_协作/decisions/` 生成只读 Markdown 投影,并由统一的决策工作台按 pending、answered、closed、cancelled 展示。Notification 与未来 Task Channel 只通过稳定 Decision id 和事件联动,不反向拥有 Decision 状态。
|
|
74
74
|
|
|
75
|
-
`app/` 按可独立理解的业务能力组织,CLI 只做参数和输出适配,Service 承担业务流程,Repository
|
|
75
|
+
`app/` 按可独立理解的业务能力组织,CLI 只做参数和输出适配,Service 承担业务流程,Repository 负责外部读写。跨 App 的用例编排由组合根 `AppContainer` 承担,`setup` 与 `upgrade` 是当前实例。`common/` 只放跨业务复用、无独立业务流程的原子能力;不能为了“复用”把业务编排下沉到 common。
|
|
76
76
|
|
|
77
77
|
配置采用两层模型:包内 `resources/defaults/config.yml` 保存完整默认契约,用户级 `~/.campfire/config.yml` 只保存覆盖项。Mapping 递归合并,scalar 和 list 整体替换;配置不按 Workspace 复制,运行状态不写回 YAML。
|
|
78
78
|
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: campfire-cli
|
|
3
|
+
Version: 0.1.6
|
|
4
|
+
Summary: Local-first shared context and governance CLI for humans and agents
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Requires-Python: >=3.12
|
|
8
|
+
Requires-Dist: alembic>=1.13
|
|
9
|
+
Requires-Dist: psutil>=7.2.2
|
|
10
|
+
Requires-Dist: pydantic-settings>=2.2
|
|
11
|
+
Requires-Dist: pydantic>=2.7
|
|
12
|
+
Requires-Dist: pyyaml>=6.0
|
|
13
|
+
Requires-Dist: sqlalchemy>=2.0
|
|
14
|
+
Requires-Dist: typer>=0.12
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
# Campfire
|
|
18
|
+
|
|
19
|
+
`campfire` 是面向工作与学习场景的本地优先人机协作 CLI。它让人类和多个 Agent 围绕同一份持久共享上下文协作:把口头要求、临时笔记、任务进度、项目资料和长期知识沉淀进可检索、可交接、可审计的 Workspace。
|
|
20
|
+
|
|
21
|
+
- **人类和 Agent 同一条链路**:同一套 CLI 契约 + 全局 Agent Skill,没有两套规则。
|
|
22
|
+
- **Markdown 是事实源**:正文永远可脱离 campfire 阅读和迁移;SQLite 只是可重建的本机索引与运行状态。
|
|
23
|
+
- **写操作默认预览**:先计划、再确认、执行前在治理锁内复核内容哈希,多会话并发不会互相覆盖。
|
|
24
|
+
- **本地优先**:不绑定云服务、不内置账号;Obsidian Vault 是当前首个存储适配器,Workspace 才是顶层概念。
|
|
25
|
+
|
|
26
|
+
产品目标、业务对象、SSOT 与模块边界见 [ARCHITECTURE.md](ARCHITECTURE.md),命令全景用 `campfire tree` 渐进发现。
|
|
27
|
+
|
|
28
|
+
## 安装
|
|
29
|
+
|
|
30
|
+
标准安装(已发布至 PyPI,无需源码仓库):
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
uv tool install campfire-cli
|
|
34
|
+
campfire version
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
升级:`campfire upgrade` 是一条幂等命令——检测 PyPI 新版本并按安装方式(uv tool / pipx)更新包本身(更新器在独立进程中等待当前进程退出后执行,完成后自动用新版代码对齐治理资源),随后对齐 SQLite Schema、全局 Skill、Base 与提示词路标。离线、已是最新、editable 源码安装或无法识别安装方式时跳过包更新仅对齐资源。
|
|
38
|
+
|
|
39
|
+
开发机安装(跟随本地源码):
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
git clone https://github.com/Kepler452Byte/campfire-cli
|
|
43
|
+
uv tool install --editable /path/to/campfire-cli
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
源码开发使用 `uv sync` 后直接 `uv run campfire --help`。
|
|
47
|
+
|
|
48
|
+
## 快速上手
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# 1. 接入已有 Vault(目录已存在,含或不含 .campfire.yaml)
|
|
52
|
+
campfire setup --workspace /path/to/vault --default
|
|
53
|
+
|
|
54
|
+
# 2. 或者从零创建新 Workspace(初始化目录结构并注册)
|
|
55
|
+
campfire workspace create --id personal --path /path/to/vault --default
|
|
56
|
+
|
|
57
|
+
# 3. 日常:检查治理状态、刷新生成视图
|
|
58
|
+
campfire maintenance check --summary
|
|
59
|
+
campfire maintenance sync --dry-run
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
不指定 `--workspace` 运行 `campfire setup` 是降级执行而不是报错:仍会同步全局 Skill 与提示词路标,输出接入引导,并显式列出被跳过的 Manifest 相关步骤。
|
|
63
|
+
|
|
64
|
+
`setup` 与 `skill sync` 会向 `~/.claude/CLAUDE.md`、`~/.agents/AGENTS.md` 注入幂等的 campfire 路标块(带注释标记、不触碰块外内容;`CAMPFIRE_AGENT_HINT_PATH` 可覆盖目标),并把托管 Skill 同步到 `~/.claude/skills`、`~/.agents/skills`(`CAMPFIRE_SKILL_TARGETS` 可覆盖)。Agent 冷启动时由此知道本机装有 campfire。
|
|
65
|
+
|
|
66
|
+
## 核心概念
|
|
67
|
+
|
|
68
|
+
```text
|
|
69
|
+
Workspace ── Space ── Domain 树 ── 文档
|
|
70
|
+
│ (_空间.md)(_领域.md + 自动 MOC)
|
|
71
|
+
└── Project(关联代码仓库与项目根 Domain)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
| 对象 | 说明 | 事实源 |
|
|
75
|
+
|------|------|--------|
|
|
76
|
+
| Workspace | 人与 Agent 共享的上下文边界,可对应一个 Vault | `~/.campfire/campfire.db`(注册)+ `.campfire.yaml`(便携 Manifest) |
|
|
77
|
+
| Space / Domain | 顶级容器 / 可嵌套内容边界,声明式 + 自动 MOC | Vault 内 `_空间.md`、`_领域.md` |
|
|
78
|
+
| Document | 知识、计划、问题、决策、记录等持久内容 | Markdown 正文 + Frontmatter |
|
|
79
|
+
| Decision | 需要人类或高级 Agent 回答的持久判断 | 全局 SQLite,投影到 `_协作/decisions/` |
|
|
80
|
+
| Generated View | MOC、相关文档页、Base、报告 | 派生数据,能生成就不手工维护 |
|
|
81
|
+
|
|
82
|
+
设备边界:`.campfire.yaml` 只保存可跨设备同步的稳定身份与逻辑关联(Project id、Git remote、文档 Domain 等),禁止本机绝对路径;新设备执行 `campfire setup --workspace <vault>` 即可恢复。本机路径绑定、索引、Decision、锁与报告都在 `~/.campfire/`(可用 `CAMPFIRE_HOME` 覆盖),按 Workspace 隔离。
|
|
83
|
+
|
|
84
|
+
## 常用命令
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
campfire tree # 完整命令树
|
|
88
|
+
campfire workspace resolve # Agent 冷启动第一步:解析当前 Workspace
|
|
89
|
+
campfire workspace list / show / export / import # 注册库管理与备份
|
|
90
|
+
campfire workspace project resolve # 当前目录属于哪个已注册项目
|
|
91
|
+
|
|
92
|
+
campfire maintenance check [--summary] [--scope] # Schema/枚举校验 + 刷新索引
|
|
93
|
+
campfire maintenance sync [--dry-run] [--scope] # 刷新 MOC 与相关文档页
|
|
94
|
+
campfire maintenance archive check / apply # 归档候选检查与执行
|
|
95
|
+
|
|
96
|
+
campfire document inspect / check / format # 单篇文档查看、校验、格式化
|
|
97
|
+
campfire document profile list / show / resolve # Frontmatter Profile 规则
|
|
98
|
+
campfire document type list # 文档类型与前缀
|
|
99
|
+
|
|
100
|
+
campfire decision create / list / answer / close # 持久决策通道
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
结构治理命令默认只输出计划,追加 `--confirm` 才执行:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
campfire workspace space create --id research --name "研究" --path myresearch --type research
|
|
107
|
+
campfire workspace domain create --id wiki --name "Wiki" --path "mywork/项目/wiki" \
|
|
108
|
+
--space work --type knowledge-domain --governance project-docs --confirm
|
|
109
|
+
campfire workspace project add --id example --workspace personal \
|
|
110
|
+
--name "Example" --document-domain "work/example" --local-path /path/to/repo
|
|
111
|
+
campfire workspace rebuild --confirm # 索引损坏时从 SSOT 完整恢复
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## 存量接管与结构重构
|
|
115
|
+
|
|
116
|
+
`workspace adopt` 负责首次接管已有文件夹:Vault 外来源先按哈希复制到 `_收件箱/待接管/<batch>`(原目录始终保留),Vault 内来源原地盘点;一次建立一个粗粒度 Domain,语义细分交给后续 Maintenance/Restructure 计划。
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
campfire workspace adopt inventory --source /path/to/folder --batch notes-001
|
|
120
|
+
campfire workspace adopt plan --batch notes-001 --target-path "mynote/新领域" \
|
|
121
|
+
--domain-id knowledge-new --name "新领域" --space knowledge \
|
|
122
|
+
--type knowledge-domain --governance knowledge-docs
|
|
123
|
+
campfire workspace adopt apply --batch notes-001 --confirm
|
|
124
|
+
campfire workspace adopt verify --batch notes-001
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
跨目录重构先冻结范围,再传入 YAML/JSON 意图规格(含 Frontmatter 修改),逐项审查 `approved` 后执行:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
campfire workspace restructure inventory --scope work --batch move-001
|
|
131
|
+
campfire workspace restructure plan --batch move-001 --spec restructure.yaml
|
|
132
|
+
campfire workspace restructure apply --batch move-001 --confirm
|
|
133
|
+
campfire workspace restructure verify --batch move-001
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
领域三个维度独立演进:`domain rename`(显示名)、`domain move`(物理路径)、`domain rekey`(稳定身份,高风险)。领域级命令联动 `_领域.md`、子领域、Project、`.campfire.yaml` 与路径引用。
|
|
137
|
+
|
|
138
|
+
## 治理模型
|
|
139
|
+
|
|
140
|
+
- **校验分工**:`maintenance check` 统一负责正式文档的 Schema 与枚举校验,并刷新可重建索引;结构声明由 `workspace space/domain check` 校验;`maintenance sync` 只因结构、MOC、路径或并发安全问题阻塞,单篇文档问题不阻止其他领域刷新。
|
|
141
|
+
- **Frontmatter Profile**:声明式一层继承(`base` 或 `base → knowledge/project-doc/task`),`document profile show` 展示编译后的完整规则;Formatter 只按有效 Profile 排序并保留值,不允许字段由 Validator 报告、不自动删除。
|
|
142
|
+
- **并发安全**:写入前在治理锁内复核内容哈希,外部变化返回 `concurrent-change` / `source-hash-changed`,拒绝覆盖。
|
|
143
|
+
- **配置两层模型**:产品默认契约在包内 `resources/defaults/config.yml`(SSOT),用户只在 `~/.campfire/config.yml` 写覆盖项;Mapping 递归合并,`campfire workspace config check` 验证有效配置。
|
|
144
|
+
|
|
145
|
+
## Agent 协作
|
|
146
|
+
|
|
147
|
+
全局 Skill(`campfire skill list` 查看托管清单,`campfire skill sync` 手动同步)定义了 Agent 的标准工作流:先 `workspace resolve` 解析上下文,再读取目标 Workspace 的 `AGENTS.md`;只读检查可直接执行,`restructure apply`、`maintenance apply`、`archive apply` 必须先审查计划并用显式确认参数。有歧义的分类和重构进入 Decision 待确认,不由 Agent 擅自决定。
|
|
148
|
+
|
|
149
|
+
## 许可
|
|
150
|
+
|
|
151
|
+
MIT。
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Campfire
|
|
2
|
+
|
|
3
|
+
`campfire` 是面向工作与学习场景的本地优先人机协作 CLI。它让人类和多个 Agent 围绕同一份持久共享上下文协作:把口头要求、临时笔记、任务进度、项目资料和长期知识沉淀进可检索、可交接、可审计的 Workspace。
|
|
4
|
+
|
|
5
|
+
- **人类和 Agent 同一条链路**:同一套 CLI 契约 + 全局 Agent Skill,没有两套规则。
|
|
6
|
+
- **Markdown 是事实源**:正文永远可脱离 campfire 阅读和迁移;SQLite 只是可重建的本机索引与运行状态。
|
|
7
|
+
- **写操作默认预览**:先计划、再确认、执行前在治理锁内复核内容哈希,多会话并发不会互相覆盖。
|
|
8
|
+
- **本地优先**:不绑定云服务、不内置账号;Obsidian Vault 是当前首个存储适配器,Workspace 才是顶层概念。
|
|
9
|
+
|
|
10
|
+
产品目标、业务对象、SSOT 与模块边界见 [ARCHITECTURE.md](ARCHITECTURE.md),命令全景用 `campfire tree` 渐进发现。
|
|
11
|
+
|
|
12
|
+
## 安装
|
|
13
|
+
|
|
14
|
+
标准安装(已发布至 PyPI,无需源码仓库):
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
uv tool install campfire-cli
|
|
18
|
+
campfire version
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
升级:`campfire upgrade` 是一条幂等命令——检测 PyPI 新版本并按安装方式(uv tool / pipx)更新包本身(更新器在独立进程中等待当前进程退出后执行,完成后自动用新版代码对齐治理资源),随后对齐 SQLite Schema、全局 Skill、Base 与提示词路标。离线、已是最新、editable 源码安装或无法识别安装方式时跳过包更新仅对齐资源。
|
|
22
|
+
|
|
23
|
+
开发机安装(跟随本地源码):
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
git clone https://github.com/Kepler452Byte/campfire-cli
|
|
27
|
+
uv tool install --editable /path/to/campfire-cli
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
源码开发使用 `uv sync` 后直接 `uv run campfire --help`。
|
|
31
|
+
|
|
32
|
+
## 快速上手
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# 1. 接入已有 Vault(目录已存在,含或不含 .campfire.yaml)
|
|
36
|
+
campfire setup --workspace /path/to/vault --default
|
|
37
|
+
|
|
38
|
+
# 2. 或者从零创建新 Workspace(初始化目录结构并注册)
|
|
39
|
+
campfire workspace create --id personal --path /path/to/vault --default
|
|
40
|
+
|
|
41
|
+
# 3. 日常:检查治理状态、刷新生成视图
|
|
42
|
+
campfire maintenance check --summary
|
|
43
|
+
campfire maintenance sync --dry-run
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
不指定 `--workspace` 运行 `campfire setup` 是降级执行而不是报错:仍会同步全局 Skill 与提示词路标,输出接入引导,并显式列出被跳过的 Manifest 相关步骤。
|
|
47
|
+
|
|
48
|
+
`setup` 与 `skill sync` 会向 `~/.claude/CLAUDE.md`、`~/.agents/AGENTS.md` 注入幂等的 campfire 路标块(带注释标记、不触碰块外内容;`CAMPFIRE_AGENT_HINT_PATH` 可覆盖目标),并把托管 Skill 同步到 `~/.claude/skills`、`~/.agents/skills`(`CAMPFIRE_SKILL_TARGETS` 可覆盖)。Agent 冷启动时由此知道本机装有 campfire。
|
|
49
|
+
|
|
50
|
+
## 核心概念
|
|
51
|
+
|
|
52
|
+
```text
|
|
53
|
+
Workspace ── Space ── Domain 树 ── 文档
|
|
54
|
+
│ (_空间.md)(_领域.md + 自动 MOC)
|
|
55
|
+
└── Project(关联代码仓库与项目根 Domain)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
| 对象 | 说明 | 事实源 |
|
|
59
|
+
|------|------|--------|
|
|
60
|
+
| Workspace | 人与 Agent 共享的上下文边界,可对应一个 Vault | `~/.campfire/campfire.db`(注册)+ `.campfire.yaml`(便携 Manifest) |
|
|
61
|
+
| Space / Domain | 顶级容器 / 可嵌套内容边界,声明式 + 自动 MOC | Vault 内 `_空间.md`、`_领域.md` |
|
|
62
|
+
| Document | 知识、计划、问题、决策、记录等持久内容 | Markdown 正文 + Frontmatter |
|
|
63
|
+
| Decision | 需要人类或高级 Agent 回答的持久判断 | 全局 SQLite,投影到 `_协作/decisions/` |
|
|
64
|
+
| Generated View | MOC、相关文档页、Base、报告 | 派生数据,能生成就不手工维护 |
|
|
65
|
+
|
|
66
|
+
设备边界:`.campfire.yaml` 只保存可跨设备同步的稳定身份与逻辑关联(Project id、Git remote、文档 Domain 等),禁止本机绝对路径;新设备执行 `campfire setup --workspace <vault>` 即可恢复。本机路径绑定、索引、Decision、锁与报告都在 `~/.campfire/`(可用 `CAMPFIRE_HOME` 覆盖),按 Workspace 隔离。
|
|
67
|
+
|
|
68
|
+
## 常用命令
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
campfire tree # 完整命令树
|
|
72
|
+
campfire workspace resolve # Agent 冷启动第一步:解析当前 Workspace
|
|
73
|
+
campfire workspace list / show / export / import # 注册库管理与备份
|
|
74
|
+
campfire workspace project resolve # 当前目录属于哪个已注册项目
|
|
75
|
+
|
|
76
|
+
campfire maintenance check [--summary] [--scope] # Schema/枚举校验 + 刷新索引
|
|
77
|
+
campfire maintenance sync [--dry-run] [--scope] # 刷新 MOC 与相关文档页
|
|
78
|
+
campfire maintenance archive check / apply # 归档候选检查与执行
|
|
79
|
+
|
|
80
|
+
campfire document inspect / check / format # 单篇文档查看、校验、格式化
|
|
81
|
+
campfire document profile list / show / resolve # Frontmatter Profile 规则
|
|
82
|
+
campfire document type list # 文档类型与前缀
|
|
83
|
+
|
|
84
|
+
campfire decision create / list / answer / close # 持久决策通道
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
结构治理命令默认只输出计划,追加 `--confirm` 才执行:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
campfire workspace space create --id research --name "研究" --path myresearch --type research
|
|
91
|
+
campfire workspace domain create --id wiki --name "Wiki" --path "mywork/项目/wiki" \
|
|
92
|
+
--space work --type knowledge-domain --governance project-docs --confirm
|
|
93
|
+
campfire workspace project add --id example --workspace personal \
|
|
94
|
+
--name "Example" --document-domain "work/example" --local-path /path/to/repo
|
|
95
|
+
campfire workspace rebuild --confirm # 索引损坏时从 SSOT 完整恢复
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## 存量接管与结构重构
|
|
99
|
+
|
|
100
|
+
`workspace adopt` 负责首次接管已有文件夹:Vault 外来源先按哈希复制到 `_收件箱/待接管/<batch>`(原目录始终保留),Vault 内来源原地盘点;一次建立一个粗粒度 Domain,语义细分交给后续 Maintenance/Restructure 计划。
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
campfire workspace adopt inventory --source /path/to/folder --batch notes-001
|
|
104
|
+
campfire workspace adopt plan --batch notes-001 --target-path "mynote/新领域" \
|
|
105
|
+
--domain-id knowledge-new --name "新领域" --space knowledge \
|
|
106
|
+
--type knowledge-domain --governance knowledge-docs
|
|
107
|
+
campfire workspace adopt apply --batch notes-001 --confirm
|
|
108
|
+
campfire workspace adopt verify --batch notes-001
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
跨目录重构先冻结范围,再传入 YAML/JSON 意图规格(含 Frontmatter 修改),逐项审查 `approved` 后执行:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
campfire workspace restructure inventory --scope work --batch move-001
|
|
115
|
+
campfire workspace restructure plan --batch move-001 --spec restructure.yaml
|
|
116
|
+
campfire workspace restructure apply --batch move-001 --confirm
|
|
117
|
+
campfire workspace restructure verify --batch move-001
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
领域三个维度独立演进:`domain rename`(显示名)、`domain move`(物理路径)、`domain rekey`(稳定身份,高风险)。领域级命令联动 `_领域.md`、子领域、Project、`.campfire.yaml` 与路径引用。
|
|
121
|
+
|
|
122
|
+
## 治理模型
|
|
123
|
+
|
|
124
|
+
- **校验分工**:`maintenance check` 统一负责正式文档的 Schema 与枚举校验,并刷新可重建索引;结构声明由 `workspace space/domain check` 校验;`maintenance sync` 只因结构、MOC、路径或并发安全问题阻塞,单篇文档问题不阻止其他领域刷新。
|
|
125
|
+
- **Frontmatter Profile**:声明式一层继承(`base` 或 `base → knowledge/project-doc/task`),`document profile show` 展示编译后的完整规则;Formatter 只按有效 Profile 排序并保留值,不允许字段由 Validator 报告、不自动删除。
|
|
126
|
+
- **并发安全**:写入前在治理锁内复核内容哈希,外部变化返回 `concurrent-change` / `source-hash-changed`,拒绝覆盖。
|
|
127
|
+
- **配置两层模型**:产品默认契约在包内 `resources/defaults/config.yml`(SSOT),用户只在 `~/.campfire/config.yml` 写覆盖项;Mapping 递归合并,`campfire workspace config check` 验证有效配置。
|
|
128
|
+
|
|
129
|
+
## Agent 协作
|
|
130
|
+
|
|
131
|
+
全局 Skill(`campfire skill list` 查看托管清单,`campfire skill sync` 手动同步)定义了 Agent 的标准工作流:先 `workspace resolve` 解析上下文,再读取目标 Workspace 的 `AGENTS.md`;只读检查可直接执行,`restructure apply`、`maintenance apply`、`archive apply` 必须先审查计划并用显式确认参数。有歧义的分类和重构进入 Decision 待确认,不由 Agent 擅自决定。
|
|
132
|
+
|
|
133
|
+
## 许可
|
|
134
|
+
|
|
135
|
+
MIT。
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
```text
|
|
8
8
|
CLI delivery adapter
|
|
9
9
|
↓
|
|
10
|
+
AppContainer 组合根,承担跨 App 编排
|
|
11
|
+
↓
|
|
10
12
|
Workspace Restructure / Maintenance Service
|
|
11
13
|
↓
|
|
12
14
|
消费方 Protocol
|
|
@@ -17,6 +19,8 @@ SQLite / Filesystem Implementation
|
|
|
17
19
|
- `app/` 放业务模块与 CLI 适配器。
|
|
18
20
|
- `common/` 放两个 App 共同使用的文档治理原子能力和技术机制。
|
|
19
21
|
- `config/` 放随 Workspace 或运行环境变化的配置。
|
|
22
|
+
- 跨 App 的用例编排放 `AppContainer` 组合根,`setup` 与 `upgrade` 是当前实例;CLI 不编排跨服务流程,单个 App Service 不直接调用其他 App 的 Service。
|
|
23
|
+
- 纯技术机制放 `common/`,例如网络查询、版本比较与进程编排;不得包含治理业务语义,也不得反向依赖 `app/`。
|
|
20
24
|
- `resources/defaults/config.yml` 是产品默认规则的唯一 SSOT;Service 不得重复声明可演进的目录、类型、状态、归档或 Issue 规则。
|
|
21
25
|
- CLI 通过用户级 registry 管理多个 Workspace,不依赖任何 Workspace 内的工具目录。
|
|
22
26
|
- Markdown 是内容事实来源;包内 `config.yml` 与可选的 `~/.campfire/config.yml` 覆盖共同形成有效治理契约;`~/.campfire/campfire.db` 是唯一数据库,保存 Workspace/Project 注册数据、按 Workspace 隔离的可重建索引和工作流状态。
|
|
@@ -30,6 +34,34 @@ SQLite / Filesystem Implementation
|
|
|
30
34
|
|
|
31
35
|
代码风格参考 `templates/fastapi-template`,但不引入 HTTP、WebSocket、认证和异步数据库等无关能力。
|
|
32
36
|
|
|
37
|
+
## CLI 输出契约
|
|
38
|
+
|
|
39
|
+
- 正常输出 indent JSON;错误输出单行 JSON 并写 stderr,退出码非 0。
|
|
40
|
+
- `status` 字段是 Agent 依赖的公共契约,只允许复用既有词汇,不得发明近义词。命令级词汇:ok、error、blocked、needs-input、needs-review、dry-run、synced、planned、ready、applied、issues-found、formatted、archived、up-to-date。文档、领域与 Decision 各有自己的字段词汇表。需要新状态先在本节登记。
|
|
41
|
+
- 前置条件缺失时优先降级执行:能完成的部分照常完成,输出 `needs-input` 并以 `skipped` 字段显式列出被跳过的步骤,而非整体报错退出。
|
|
42
|
+
|
|
43
|
+
## 升级语义
|
|
44
|
+
|
|
45
|
+
- `campfire upgrade` 是唯一的幂等升级入口:先更新 Python 包本身,再对齐本机治理资源,覆盖 Schema 迁移、全局 Skill、Base 与提示词路标。
|
|
46
|
+
- 包自更新按检测到的安装方式在独立进程中执行,当前支持 uv tool 与 pipx。更新脚本必须等待当前进程退出后再运行,因为 Windows 会锁定运行中的解释器与可执行文件,包管理器无法原地替换;成功后由新版代码完成资源对齐。
|
|
47
|
+
- editable 源码安装、离线、无法识别安装方式时跳过包更新仅对齐资源,结果中以 `action` 与 `hint` 显式说明原因。
|
|
48
|
+
- 自更新链使用的内部参数必须 `hidden=True`,`--skip-package` 是当前实例,不进入公共 CLI 契约。
|
|
49
|
+
- 外部网络查询尽力而为,例如 PyPI 版本检测;失败或超时静默降级,不得让命令失败或明显变慢。
|
|
50
|
+
|
|
51
|
+
## 开发纪律
|
|
52
|
+
|
|
53
|
+
- 提交使用 conventional commits,类型限定为 feat、fix、perf、refactor、docs、chore,正文说明动机;纯重构独立成 commit,不与功能变更混排。
|
|
54
|
+
- 行为保持型重构的验收等于两条同时满足:既有测试不改断言仍通过,真实数据上新旧输出全等对比。只过测试不足以证明行为未变。
|
|
55
|
+
- Windows 不变量:进程探活用 `psutil.pid_exists`,不用 `os.kill(pid, 0)`,后者在 Windows 等价于发送 CTRL_C_EVENT;CLI 入口处对 stdout/stderr 执行 UTF-8 reconfigure。
|
|
56
|
+
|
|
57
|
+
## 注释与文档字符串
|
|
58
|
+
|
|
59
|
+
以 PEP 8 与 PEP 257 为基线,外加两条本项目的硬规则:
|
|
60
|
+
|
|
61
|
+
- 注释只写代码本身表达不了的约束:为什么这样做、什么条件下不能改。不写下一行做什么,不写给评审者看的改动说明,不重复代码;只对本次改动有意义的内容进提交说明,不进代码。
|
|
62
|
+
- Docstring 是 API 契约:摘要行一句话陈述行为,补充行写前置条件、返回语义与副作用,不描述实现步骤。
|
|
63
|
+
- 注释是完整句子,与代码同语言;行内注释只用于取值域等代码无法自明的信息。
|
|
64
|
+
|
|
33
65
|
## 版本规范
|
|
34
66
|
|
|
35
67
|
Campfire 使用语义化版本:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "campfire-cli"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.6"
|
|
4
4
|
description = "Local-first shared context and governance CLI for humans and agents"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "MIT"
|
|
@@ -35,6 +35,9 @@ dev = [
|
|
|
35
35
|
[tool.pytest.ini_options]
|
|
36
36
|
testpaths = ["tests"]
|
|
37
37
|
python_files = ["test_*.py"]
|
|
38
|
+
markers = [
|
|
39
|
+
"perf: 性能回归测试,只断言确定性计数,不断言墙钟时间",
|
|
40
|
+
]
|
|
38
41
|
|
|
39
42
|
[tool.ruff]
|
|
40
43
|
line-length = 100
|
|
@@ -13,6 +13,7 @@ from campfire_cli.app.document.service.document_service import DocumentService
|
|
|
13
13
|
from campfire_cli.app.workspace.repository.workspace_repository import SqliteWorkspaceRepository
|
|
14
14
|
from campfire_cli.app.workspace.service.workspace_service import WorkspaceService
|
|
15
15
|
from campfire_cli.common.exceptions import AppError
|
|
16
|
+
from campfire_cli.common.filesystem.cwd import safe_cwd
|
|
16
17
|
from campfire_cli.config.settings import WorkspaceSettings, campfire_home
|
|
17
18
|
|
|
18
19
|
document_cli = typer.Typer(
|
|
@@ -27,7 +28,7 @@ def service(ctx: typer.Context) -> DocumentService:
|
|
|
27
28
|
selector = ctx.find_root().params.get("workspace")
|
|
28
29
|
root = campfire_home()
|
|
29
30
|
resolution = WorkspaceService(root, SqliteWorkspaceRepository(root)).resolve(
|
|
30
|
-
selector,
|
|
31
|
+
selector, safe_cwd()
|
|
31
32
|
)
|
|
32
33
|
settings = WorkspaceSettings.load(resolution.workspace_id, Path(resolution.workspace))
|
|
33
34
|
return DocumentService(settings)
|
|
@@ -47,6 +48,12 @@ def check(ctx: typer.Context, path: str = typer.Option(..., "--path")) -> None:
|
|
|
47
48
|
invoke(lambda: service(ctx).check(path))
|
|
48
49
|
|
|
49
50
|
|
|
51
|
+
@document_cli.command("kanban-check")
|
|
52
|
+
def kanban_check(ctx: typer.Context, path: str = typer.Option(..., "--path")) -> None:
|
|
53
|
+
"""检查文档是否满足 Obsidian Kanban 插件的渲染契约。"""
|
|
54
|
+
invoke(lambda: service(ctx).kanban_check(path))
|
|
55
|
+
|
|
56
|
+
|
|
50
57
|
@document_cli.command("inspect")
|
|
51
58
|
def inspect(ctx: typer.Context, path: str = typer.Option(..., "--path")) -> None:
|
|
52
59
|
"""返回 Agent 治理单篇文档所需的类型、Profile、领域和问题上下文。"""
|
|
@@ -16,6 +16,7 @@ from campfire_cli.app.document.service.document_profile_service import (
|
|
|
16
16
|
from campfire_cli.app.workspace.repository.workspace_repository import SqliteWorkspaceRepository
|
|
17
17
|
from campfire_cli.app.workspace.service.workspace_service import WorkspaceService
|
|
18
18
|
from campfire_cli.common.exceptions import AppError
|
|
19
|
+
from campfire_cli.common.filesystem.cwd import safe_cwd
|
|
19
20
|
from campfire_cli.config.settings import WorkspaceSettings, campfire_home
|
|
20
21
|
|
|
21
22
|
profile_cli = typer.Typer(
|
|
@@ -28,7 +29,7 @@ def service(ctx: typer.Context) -> DocumentProfileService:
|
|
|
28
29
|
selector = ctx.find_root().params.get("workspace")
|
|
29
30
|
root = campfire_home()
|
|
30
31
|
resolution = WorkspaceService(root, SqliteWorkspaceRepository(root)).resolve(
|
|
31
|
-
selector,
|
|
32
|
+
selector, safe_cwd()
|
|
32
33
|
)
|
|
33
34
|
settings = WorkspaceSettings.load(resolution.workspace_id, Path(resolution.workspace))
|
|
34
35
|
return DocumentProfileService(
|
|
@@ -14,6 +14,7 @@ from campfire_cli.app.document.service.document_type_service import DocumentType
|
|
|
14
14
|
from campfire_cli.app.workspace.repository.workspace_repository import SqliteWorkspaceRepository
|
|
15
15
|
from campfire_cli.app.workspace.service.workspace_service import WorkspaceService
|
|
16
16
|
from campfire_cli.common.exceptions import AppError
|
|
17
|
+
from campfire_cli.common.filesystem.cwd import safe_cwd
|
|
17
18
|
from campfire_cli.config.settings import WorkspaceSettings, campfire_home
|
|
18
19
|
|
|
19
20
|
type_cli = typer.Typer(
|
|
@@ -26,7 +27,7 @@ def service(ctx: typer.Context) -> DocumentTypeService:
|
|
|
26
27
|
selector = ctx.find_root().params.get("workspace")
|
|
27
28
|
root = campfire_home()
|
|
28
29
|
resolution = WorkspaceService(root, SqliteWorkspaceRepository(root)).resolve(
|
|
29
|
-
selector,
|
|
30
|
+
selector, safe_cwd()
|
|
30
31
|
)
|
|
31
32
|
settings = WorkspaceSettings.load(resolution.workspace_id, Path(resolution.workspace))
|
|
32
33
|
return DocumentTypeService(
|
|
@@ -233,6 +233,17 @@ class DocumentRuleService:
|
|
|
233
233
|
def known_fields(self) -> set[str]:
|
|
234
234
|
return self._profiles.known_fields()
|
|
235
235
|
|
|
236
|
+
def field_order_for(
|
|
237
|
+
self, frontmatter: dict[str, Any], path: Path | None = None
|
|
238
|
+
) -> list[str]:
|
|
239
|
+
"""返回文档在当前治理契约下的有效 Profile 字段序。
|
|
240
|
+
|
|
241
|
+
写入口修改 frontmatter 后必须按此序插入新增字段,否则文档立即产生
|
|
242
|
+
frontmatter-field-order-invalid。
|
|
243
|
+
"""
|
|
244
|
+
profile = self._profiles.resolve(frontmatter.get("type"), frontmatter, path)
|
|
245
|
+
return list(profile.field_order)
|
|
246
|
+
|
|
236
247
|
def validate_patch(
|
|
237
248
|
self,
|
|
238
249
|
root: Path,
|
{campfire_cli-0.1.4 → campfire_cli-0.1.6}/src/campfire_cli/app/document/service/document_service.py
RENAMED
|
@@ -6,6 +6,10 @@ from typing import Any
|
|
|
6
6
|
from campfire_cli.app.document.service.document_rule_service import DocumentRuleService
|
|
7
7
|
from campfire_cli.app.document.service.document_scanner import exempt_document
|
|
8
8
|
from campfire_cli.app.document.service.frontmatter_formatter import format_text
|
|
9
|
+
from campfire_cli.app.document.service.kanban_service import (
|
|
10
|
+
check_kanban_renderability,
|
|
11
|
+
renderability_result,
|
|
12
|
+
)
|
|
9
13
|
from campfire_cli.app.document.service.profile_registry import ProfileRegistry
|
|
10
14
|
from campfire_cli.common.documents.markdown import parse_document
|
|
11
15
|
from campfire_cli.common.exceptions import ConfigurationError, GovernanceBlockedError
|
|
@@ -33,6 +37,16 @@ class DocumentService:
|
|
|
33
37
|
"issues": issues,
|
|
34
38
|
}
|
|
35
39
|
|
|
40
|
+
def kanban_check(self, relative_path: str) -> dict[str, Any]:
|
|
41
|
+
path = self._document_path(relative_path)
|
|
42
|
+
if self._is_exempt(path):
|
|
43
|
+
return self._not_applicable(relative_path, path)
|
|
44
|
+
issues = check_kanban_renderability(path.read_text(encoding="utf-8"))
|
|
45
|
+
return {
|
|
46
|
+
**renderability_result(relative_path, issues),
|
|
47
|
+
"workspace_id": self._settings.workspace_id,
|
|
48
|
+
}
|
|
49
|
+
|
|
36
50
|
def inspect(self, relative_path: str) -> dict[str, Any]:
|
|
37
51
|
path = self._document_path(relative_path)
|
|
38
52
|
if self._is_exempt(path):
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"""
|
|
2
|
+
SPEC:
|
|
3
|
+
name: kanban_service
|
|
4
|
+
purpose: 校验 Markdown 文档是否满足 Obsidian Kanban 插件的渲染契约
|
|
5
|
+
default_env_file: none
|
|
6
|
+
env_override: none
|
|
7
|
+
idempotent: true
|
|
8
|
+
behavior:
|
|
9
|
+
- 只读检查 frontmatter 与正文结构,输出确定性 issue 列表
|
|
10
|
+
- 不修改文档;改造由 Agent 按 skill 流程完成
|
|
11
|
+
safety:
|
|
12
|
+
- 不把渲染契约混入 Frontmatter Profile 契约,两者正交
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import re
|
|
18
|
+
from typing import Any
|
|
19
|
+
|
|
20
|
+
from campfire_cli.common.documents.markdown import parse_document
|
|
21
|
+
|
|
22
|
+
LANE_RE = re.compile(r"^##\s+\S")
|
|
23
|
+
COMMENT_START_RE = re.compile(r"^(<!--|%%)")
|
|
24
|
+
INDENTED_RE = re.compile(r"^\s+\S")
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def check_kanban_renderability(text: str) -> list[dict[str, str]]:
|
|
28
|
+
"""返回文档渲染为 Obsidian Kanban 看板的阻碍项;空列表即可渲染。
|
|
29
|
+
|
|
30
|
+
契约按真实看板校准:frontmatter 含 kanban-plugin 键;正文由 `## 泳道`
|
|
31
|
+
标题分区,卡片为列表项;泳道前的 H1 标题与引用块导言、`%%` 设置块、
|
|
32
|
+
卡片的缩进续行都被插件容忍,不视为阻碍。
|
|
33
|
+
"""
|
|
34
|
+
parsed = parse_document(text)
|
|
35
|
+
issues: list[dict[str, str]] = []
|
|
36
|
+
plugin = parsed.frontmatter.get("kanban-plugin") if parsed.has_frontmatter else None
|
|
37
|
+
if not isinstance(plugin, str) or not plugin.strip():
|
|
38
|
+
issues.append({"code": "kanban-plugin-missing"})
|
|
39
|
+
lane_seen = False
|
|
40
|
+
comment_block = False
|
|
41
|
+
for number, raw in enumerate(parsed.body.splitlines(), start=1):
|
|
42
|
+
stripped = raw.strip()
|
|
43
|
+
if comment_block:
|
|
44
|
+
if stripped == "%%" or stripped.endswith("%%"):
|
|
45
|
+
comment_block = False
|
|
46
|
+
continue
|
|
47
|
+
if not stripped:
|
|
48
|
+
continue
|
|
49
|
+
if stripped.startswith("%%") and not stripped.endswith("%%"):
|
|
50
|
+
comment_block = True
|
|
51
|
+
continue
|
|
52
|
+
if LANE_RE.match(raw):
|
|
53
|
+
lane_seen = True
|
|
54
|
+
continue
|
|
55
|
+
if COMMENT_START_RE.match(stripped) or raw.startswith("#") or stripped.startswith(">"):
|
|
56
|
+
continue
|
|
57
|
+
if INDENTED_RE.match(raw) or stripped.startswith("-"):
|
|
58
|
+
if not lane_seen:
|
|
59
|
+
issues.append({"code": "kanban-card-outside-lane", "detail": f"line {number}"})
|
|
60
|
+
continue
|
|
61
|
+
issues.append({"code": "kanban-line-not-card", "detail": f"line {number}"})
|
|
62
|
+
if not lane_seen:
|
|
63
|
+
issues.append({"code": "kanban-lane-missing"})
|
|
64
|
+
return issues
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def renderability_result(relative_path: str, issues: list[dict[str, str]]) -> dict[str, Any]:
|
|
68
|
+
return {
|
|
69
|
+
"status": "ok" if not issues else "needs-review",
|
|
70
|
+
"path": relative_path,
|
|
71
|
+
"renderable": not issues,
|
|
72
|
+
"issue_count": len(issues),
|
|
73
|
+
"issues": issues,
|
|
74
|
+
}
|
|
@@ -62,6 +62,7 @@ class MaintenanceResult(BaseModel):
|
|
|
62
62
|
blocked_scope: str | None = None
|
|
63
63
|
issue_counts: dict[str, int] = Field(default_factory=dict)
|
|
64
64
|
operations: list[dict[str, Any]] = Field(default_factory=list)
|
|
65
|
+
candidates: list[dict[str, Any]] = Field(default_factory=list)
|
|
65
66
|
scope: str | None = None
|
|
66
67
|
workspace_status: str | None = None
|
|
67
68
|
space_count: int = 0
|