campfire-cli 0.1.16__tar.gz → 0.1.18__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.16 → campfire_cli-0.1.18}/.github/workflows/release.yml +2 -5
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/PKG-INFO +7 -5
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/README.md +6 -4
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/SPEC.md +2 -1
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/pyproject.toml +1 -1
- campfire_cli-0.1.18/scripts/pypi_verify.py +67 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/scripts/quality_check.py +1 -1
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/__init__.py +1 -1
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/base/schema/operation_schema.py +6 -2
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/SPEC.md +4 -1
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/cli/document_cli.py +68 -34
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/schema/document_schema.py +1 -1
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/service/document_apply_service.py +45 -36
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/service/document_move_service.py +81 -14
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/service/document_service.py +15 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/common/agent_hints.py +13 -7
- campfire_cli-0.1.18/src/campfire_cli/resources/skills/SPEC.md +48 -0
- campfire_cli-0.1.18/src/campfire_cli/resources/skills/TEMPLATE.md +88 -0
- campfire_cli-0.1.18/src/campfire_cli/resources/skills/campfire-context-bootstrap/SKILL.md +58 -0
- campfire_cli-0.1.18/src/campfire_cli/resources/skills/campfire-conversation-router/SKILL.md +49 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/resources/skills/campfire-conversation-router/references/inbox-handoff.md +2 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/resources/skills/campfire-conversation-router/references/learning-intake.md +2 -2
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/resources/skills/campfire-conversation-router/references/task-intake.md +3 -4
- campfire_cli-0.1.18/src/campfire_cli/resources/skills/campfire-document-capture/SKILL.md +96 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/resources/skills/campfire-document-capture/references//345/267/262/346/234/211/346/226/207/346/241/243/346/233/264/346/226/260.md +1 -1
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/resources/skills/campfire-document-capture/references//351/200/232/347/224/250/347/237/245/350/257/206/346/262/211/346/267/200.md +2 -2
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/resources/skills/campfire-document-capture/references//351/241/271/347/233/256/345/206/205/345/256/271/346/262/211/346/267/200.md +2 -2
- campfire_cli-0.1.18/src/campfire_cli/resources/skills/campfire-inbox-triage/SKILL.md +55 -0
- campfire_cli-0.1.18/src/campfire_cli/resources/skills/campfire-kanban-board/SKILL.md +59 -0
- campfire_cli-0.1.18/src/campfire_cli/resources/skills/campfire-task-management/SKILL.md +73 -0
- campfire_cli-0.1.18/src/campfire_cli/resources/skills/campfire-weekly-report-writing/SKILL.md +56 -0
- campfire_cli-0.1.18/src/campfire_cli/resources/skills/campfire-workspace-adoption/SKILL.md +59 -0
- campfire_cli-0.1.18/src/campfire_cli/resources/skills/campfire-workspace-maintenance/SKILL.md +73 -0
- campfire_cli-0.1.18/src/campfire_cli/resources/skills/campfire-workspace-onboarding/SKILL.md +67 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/resources/skills/campfire-workspace-onboarding/references//346/240/207/345/207/206/345/267/245/344/275/234/345/214/272/347/273/223/346/236/204.md +2 -3
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/resources/skills/campfire-workspace-restructure/SKILL.md +38 -7
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/resources/skills/campfire-workspace-restructure/references/restructure-spec.md +1 -1
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/tests/integration/test_cli.py +87 -6
- campfire_cli-0.1.18/tests/integration/test_skill_examples.py +96 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/tests/unit/test_document_apply.py +108 -0
- campfire_cli-0.1.18/tests/unit/test_operation_schema.py +14 -0
- campfire_cli-0.1.18/tests/unit/test_pypi_verify.py +94 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/uv.lock +1 -1
- campfire_cli-0.1.16/src/campfire_cli/resources/skills/SPEC.md +0 -33
- campfire_cli-0.1.16/src/campfire_cli/resources/skills/campfire-context-bootstrap/SKILL.md +0 -70
- campfire_cli-0.1.16/src/campfire_cli/resources/skills/campfire-conversation-router/SKILL.md +0 -53
- campfire_cli-0.1.16/src/campfire_cli/resources/skills/campfire-document-capture/SKILL.md +0 -120
- campfire_cli-0.1.16/src/campfire_cli/resources/skills/campfire-inbox-triage/SKILL.md +0 -23
- campfire_cli-0.1.16/src/campfire_cli/resources/skills/campfire-kanban-board/SKILL.md +0 -69
- campfire_cli-0.1.16/src/campfire_cli/resources/skills/campfire-task-management/SKILL.md +0 -81
- campfire_cli-0.1.16/src/campfire_cli/resources/skills/campfire-weekly-report-writing/SKILL.md +0 -21
- campfire_cli-0.1.16/src/campfire_cli/resources/skills/campfire-workspace-adoption/SKILL.md +0 -32
- campfire_cli-0.1.16/src/campfire_cli/resources/skills/campfire-workspace-maintenance/SKILL.md +0 -94
- campfire_cli-0.1.16/src/campfire_cli/resources/skills/campfire-workspace-onboarding/SKILL.md +0 -57
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/.github/workflows/ci.yml +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/.gitignore +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/.python-version +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/AGENTS.md +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/ARCHITECTURE.md +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/COMMAND.md +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/DECISIONS.md +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/LICENSE +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/alembic/SPEC.md +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/alembic/env.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/alembic/script.py.mako +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/alembic/versions/001_initial_schema.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/alembic.ini +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/scripts/SPEC.md +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/alembic/__init__.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/alembic/env.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/alembic/script.py.mako +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/alembic/versions/001_initial_schema.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/alembic/versions/002_workspace_project_registry.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/alembic/versions/003_unified_workspace_state.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/alembic/versions/004_restructure_workspace_domain.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/alembic/versions/005_decision_channel.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/alembic/versions/006_workspace_topology_index.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/alembic/versions/007_workspace_adoption.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/alembic/versions/008_remove_adoption_batches.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/alembic/versions/009_document_query_index.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/alembic/versions/010_project_domain_identity.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/alembic/versions/011_document_state_model.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/alembic/versions/012_remove_decision_channel.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/alembic/versions/__init__.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/SPEC.md +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/__init__.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/base/SPEC.md +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/base/__init__.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/base/cli/base_cli.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/base/repository/base_repository.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/base/schema/base_schema.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/base/service/base_service.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/__init__.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/cli/__init__.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/cli/profile_cli.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/cli/type_cli.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/repository/__init__.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/repository/document_index_repository.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/repository/document_profile_repository.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/repository/document_type_repository.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/schema/__init__.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/service/__init__.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/service/document_index_builder.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/service/document_index_protocol.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/service/document_index_service.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/service/document_patch_values.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/service/document_profile_service.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/service/document_relocation.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/service/document_rule_service.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/service/document_scanner.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/service/document_type_service.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/service/frontmatter_apply.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/service/frontmatter_formatter.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/service/frontmatter_plan.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/service/kanban_service.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/service/profile_candidates.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/service/profile_registry.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/service/type_apply.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/service/type_plan.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/maintenance/SPEC.md +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/maintenance/__init__.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/maintenance/cli/maintenance_cli.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/maintenance/repository/maintenance_repository.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/maintenance/schema/maintenance_schema.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/maintenance/service/link_service.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/maintenance/service/maintenance_protocol.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/maintenance/service/maintenance_service.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/maintenance/service/moc_service.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/skill/SPEC.md +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/skill/__init__.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/skill/cli/skill_cli.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/skill/repository/skill_repository.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/skill/schema/skill_schema.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/skill/service/skill_service.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/workspace/SPEC.md +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/workspace/__init__.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/workspace/cli/__init__.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/workspace/cli/config_cli.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/workspace/cli/domain_cli.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/workspace/cli/project_cli.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/workspace/cli/restructure_cli.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/workspace/cli/space_cli.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/workspace/cli/workspace_cli.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/workspace/repository/__init__.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/workspace/repository/manifest_repository.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/workspace/repository/restructure_repository.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/workspace/repository/workspace_repository.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/workspace/schema/__init__.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/workspace/schema/adoption_schema.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/workspace/schema/restructure_schema.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/workspace/schema/workspace_schema.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/workspace/service/__init__.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/workspace/service/adoption_service.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/workspace/service/config_service.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/workspace/service/domain_restructure_service.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/workspace/service/project_service.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/workspace/service/restructure_protocol.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/workspace/service/restructure_service.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/workspace/service/restructure_verifier.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/workspace/service/structure_service.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/workspace/service/workspace_protocol.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/workspace/service/workspace_service.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/common/SPEC.md +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/common/__init__.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/common/cli_output.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/common/database/__init__.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/common/database/migrations.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/common/database/models.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/common/database/session.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/common/documents/__init__.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/common/documents/document_types.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/common/documents/domain_context.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/common/documents/frontmatter_format.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/common/documents/frontmatter_schema.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/common/documents/links.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/common/documents/markdown.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/common/exceptions/__init__.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/common/exceptions/base.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/common/filesystem/__init__.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/common/filesystem/atomic.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/common/filesystem/change_set.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/common/filesystem/cwd.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/common/filesystem/locking.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/common/governance/__init__.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/common/governance/issues.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/common/governance/locking.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/common/governance/snapshots.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/common/hashing.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/common/package_version.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/common/reports/__init__.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/common/reports/json_report.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/common/reports/markdown_report.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/config/SPEC.md +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/config/defaults.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/config/settings.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/container.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/main.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/resources/__init__.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/resources/bases/SPEC.md +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/resources/bases//344/273/273/345/212/241/345/267/245/344/275/234/345/217/260-/344/270/252/344/272/272.base" +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/resources/bases//344/273/273/345/212/241/345/267/245/344/275/234/345/217/260-/351/241/271/347/233/256.base" +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/resources/bases//345/275/222/346/241/243/346/226/207/346/241/243/345/267/245/344/275/234/345/217/260.base" +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/resources/bases//345/276/205/344/272/272/345/206/263/347/255/226/345/267/245/344/275/234/345/217/260.base" +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/resources/bases//346/226/207/346/241/243/345/267/245/344/275/234/345/217/260.base" +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/resources/defaults/__init__.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/resources/defaults/config.yml +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/resources/skills/campfire-context-bootstrap/agents/openai.yaml +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/resources/skills/campfire-conversation-router/agents/openai.yaml +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/resources/skills/campfire-document-capture/references//344/273/273/345/212/241/344/270/216/350/256/241/345/210/222/346/262/211/346/267/200.md" +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/resources/skills/campfire-document-capture/references//351/227/256/351/242/230/344/270/216/345/206/263/347/255/226/346/262/211/346/267/200.md" +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/resources/skills/campfire-weekly-report-writing/agents/openai.yaml +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/tests/SPEC.md +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/tests/conftest.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/tests/perf/test_read_counts.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/tests/perf/test_resolve_subprocess_count.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/tests/unit/test_agent_hints.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/tests/unit/test_atomic_write.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/tests/unit/test_base_service.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/tests/unit/test_config.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/tests/unit/test_document_index.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/tests/unit/test_domain_context.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/tests/unit/test_file_change_executor.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/tests/unit/test_frontmatter.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/tests/unit/test_generated_regions.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/tests/unit/test_kanban_service.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/tests/unit/test_migrations.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/tests/unit/test_package_version.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/tests/unit/test_repository_boundaries.py +0 -0
- {campfire_cli-0.1.16 → campfire_cli-0.1.18}/tests/unit/test_workspace_manifest.py +0 -0
|
@@ -55,12 +55,9 @@ jobs:
|
|
|
55
55
|
needs: publish
|
|
56
56
|
runs-on: ubuntu-latest
|
|
57
57
|
steps:
|
|
58
|
+
- uses: actions/checkout@v5
|
|
58
59
|
- uses: astral-sh/setup-uv@v10.1.0
|
|
59
60
|
- name: Install published package from PyPI
|
|
60
61
|
shell: bash
|
|
61
62
|
run: |
|
|
62
|
-
|
|
63
|
-
verify_dir="$RUNNER_TEMP/campfire-pypi-verify"
|
|
64
|
-
uv venv "$verify_dir"
|
|
65
|
-
uv pip install --python "$verify_dir/bin/python" --index-url https://pypi.org/simple "campfire-cli==$version"
|
|
66
|
-
test "$("$verify_dir/bin/campfire" version)" = "$version"
|
|
63
|
+
python scripts/pypi_verify.py "${GITHUB_REF_NAME#v}"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: campfire-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.18
|
|
4
4
|
Summary: Local-first shared context and governance CLI for humans and agents
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -61,7 +61,7 @@ campfire maintenance sync --dry-run
|
|
|
61
61
|
|
|
62
62
|
不指定 `--path` 运行 `campfire setup` 是降级执行而不是报错:仍会同步全局 Skill 与提示词路标,输出接入引导,并显式列出被跳过的 Manifest 相关步骤。
|
|
63
63
|
|
|
64
|
-
`setup`
|
|
64
|
+
`setup` 会向 `~/.claude/CLAUDE.md`、`~/.agents/AGENTS.md` 注入幂等的 campfire 路标块,保留标记外内容;`CAMPFIRE_AGENT_HINT_PATH` 可覆盖目标。`setup` 与 `skill sync` 会把托管 Skill 同步到 `~/.claude/skills`、`~/.agents/skills`,可通过 `CAMPFIRE_SKILL_TARGETS` 覆盖。单独执行 `skill sync` 不更新提示词路标。
|
|
65
65
|
|
|
66
66
|
## 核心概念
|
|
67
67
|
|
|
@@ -85,7 +85,7 @@ Workspace ── Space ── Domain 树 ── 文档
|
|
|
85
85
|
|
|
86
86
|
```bash
|
|
87
87
|
campfire tree # 完整命令树
|
|
88
|
-
campfire workspace resolve #
|
|
88
|
+
campfire workspace resolve # Workspace 不明确时解析
|
|
89
89
|
campfire workspace list / show / export / import # 注册库管理与备份
|
|
90
90
|
campfire workspace project resolve # 当前目录属于哪个已注册项目
|
|
91
91
|
|
|
@@ -94,7 +94,7 @@ campfire maintenance sync [--dry-run] [--scope] # 刷新 MOC 与相关文档页
|
|
|
94
94
|
|
|
95
95
|
campfire document inspect / check / format # 单篇文档查看、校验、格式化
|
|
96
96
|
campfire document list # 精确枚举和筛选受管文档
|
|
97
|
-
campfire document apply / move
|
|
97
|
+
campfire document apply / move / rename # 结构写入、跨 Domain 移动、原地改名
|
|
98
98
|
campfire document profile list / show / resolve # Frontmatter Profile 规则
|
|
99
99
|
campfire document type list # 文档类型与前缀
|
|
100
100
|
campfire base list / show / check / sync # Obsidian Base 治理视图
|
|
@@ -146,7 +146,9 @@ campfire workspace restructure verify --batch move-001
|
|
|
146
146
|
|
|
147
147
|
## Agent 协作
|
|
148
148
|
|
|
149
|
-
全局 Skill
|
|
149
|
+
全局 Skill 定义 Agent 的文档工作流:已知路径的人工正文直接 Edit;新建文档先 apply 创建结构,再按返回的 `target` 补正文。只在治理上下文缺失时加载 bootstrap;字段契约未知时,新建查一次目标 Profile,更新查一次 inspect。已明确的信息不重复查询,用户已有授权不重复询问。文档相对路径以 Workspace 根目录为基准,不随 cwd 改变;创建时可省略类型前缀与 `.md`。改标题用 rename,跨 Domain 移动用 move,完成后仅执行实际 follow_up。归档仍需用户对具体文档明确同意,关键歧义不得自行猜测。
|
|
150
|
+
|
|
151
|
+
仓库 Skill 编写规范见 `src/campfire_cli/resources/skills/SPEC.md`。本地与 CI 共用 `uv run python scripts/quality_check.py`;发布前使用 `--release` 增加构建、wheel 隔离安装与冒烟验证。测试日志包含最慢 10 项耗时。Release 的公共 PyPI 安装验证最多等待 3 分钟、间隔 15 秒重试,不重试上传;安装后版本不符直接失败。
|
|
150
152
|
|
|
151
153
|
## 许可
|
|
152
154
|
|
|
@@ -45,7 +45,7 @@ campfire maintenance sync --dry-run
|
|
|
45
45
|
|
|
46
46
|
不指定 `--path` 运行 `campfire setup` 是降级执行而不是报错:仍会同步全局 Skill 与提示词路标,输出接入引导,并显式列出被跳过的 Manifest 相关步骤。
|
|
47
47
|
|
|
48
|
-
`setup`
|
|
48
|
+
`setup` 会向 `~/.claude/CLAUDE.md`、`~/.agents/AGENTS.md` 注入幂等的 campfire 路标块,保留标记外内容;`CAMPFIRE_AGENT_HINT_PATH` 可覆盖目标。`setup` 与 `skill sync` 会把托管 Skill 同步到 `~/.claude/skills`、`~/.agents/skills`,可通过 `CAMPFIRE_SKILL_TARGETS` 覆盖。单独执行 `skill sync` 不更新提示词路标。
|
|
49
49
|
|
|
50
50
|
## 核心概念
|
|
51
51
|
|
|
@@ -69,7 +69,7 @@ Workspace ── Space ── Domain 树 ── 文档
|
|
|
69
69
|
|
|
70
70
|
```bash
|
|
71
71
|
campfire tree # 完整命令树
|
|
72
|
-
campfire workspace resolve #
|
|
72
|
+
campfire workspace resolve # Workspace 不明确时解析
|
|
73
73
|
campfire workspace list / show / export / import # 注册库管理与备份
|
|
74
74
|
campfire workspace project resolve # 当前目录属于哪个已注册项目
|
|
75
75
|
|
|
@@ -78,7 +78,7 @@ campfire maintenance sync [--dry-run] [--scope] # 刷新 MOC 与相关文档页
|
|
|
78
78
|
|
|
79
79
|
campfire document inspect / check / format # 单篇文档查看、校验、格式化
|
|
80
80
|
campfire document list # 精确枚举和筛选受管文档
|
|
81
|
-
campfire document apply / move
|
|
81
|
+
campfire document apply / move / rename # 结构写入、跨 Domain 移动、原地改名
|
|
82
82
|
campfire document profile list / show / resolve # Frontmatter Profile 规则
|
|
83
83
|
campfire document type list # 文档类型与前缀
|
|
84
84
|
campfire base list / show / check / sync # Obsidian Base 治理视图
|
|
@@ -130,7 +130,9 @@ campfire workspace restructure verify --batch move-001
|
|
|
130
130
|
|
|
131
131
|
## Agent 协作
|
|
132
132
|
|
|
133
|
-
全局 Skill
|
|
133
|
+
全局 Skill 定义 Agent 的文档工作流:已知路径的人工正文直接 Edit;新建文档先 apply 创建结构,再按返回的 `target` 补正文。只在治理上下文缺失时加载 bootstrap;字段契约未知时,新建查一次目标 Profile,更新查一次 inspect。已明确的信息不重复查询,用户已有授权不重复询问。文档相对路径以 Workspace 根目录为基准,不随 cwd 改变;创建时可省略类型前缀与 `.md`。改标题用 rename,跨 Domain 移动用 move,完成后仅执行实际 follow_up。归档仍需用户对具体文档明确同意,关键歧义不得自行猜测。
|
|
134
|
+
|
|
135
|
+
仓库 Skill 编写规范见 `src/campfire_cli/resources/skills/SPEC.md`。本地与 CI 共用 `uv run python scripts/quality_check.py`;发布前使用 `--release` 增加构建、wheel 隔离安装与冒烟验证。测试日志包含最慢 10 项耗时。Release 的公共 PyPI 安装验证最多等待 3 分钟、间隔 15 秒重试,不重试上传;安装后版本不符直接失败。
|
|
134
136
|
|
|
135
137
|
## 许可
|
|
136
138
|
|
|
@@ -31,6 +31,7 @@ SQLite / Filesystem Implementation
|
|
|
31
31
|
- Frontmatter Profile 只允许一层 `base` 配置继承;Profile Loader 编译完整规则,Validator 与 Formatter 共用同一个 EffectiveProfile。
|
|
32
32
|
- 公共接口不得依赖调用方猜测未声明契约。参数类型与复杂输入格式必须能从当前命令帮助获得;错误必须同时提供稳定机器字段和可操作的修复信息,但不得为此复制 Profile 枚举或新增平行命令。
|
|
33
33
|
- `tree` 只用于未知能力发现,不是 Agent 执行已知文档操作的固定前置步骤;Skill 必须把已知正文编辑、契约已知的 Frontmatter 写入和契约未知的 `inspect → apply` 分流清楚。
|
|
34
|
+
- Skill 的最短路径不得省略写入门禁;门禁表达必要前提,不强制重复查询或审批。编写与验收要求统一维护在 `src/campfire_cli/resources/skills/SPEC.md`,运行步骤放对应 Skill。
|
|
34
35
|
- 命令不得读取“最近一次操作”等隐式 Session 状态推导对象或作用域;跨命令后续动作只使用当前结果显式返回的结构化 `follow_up`。
|
|
35
36
|
- 所有写入默认预检,语义计划默认未审批。
|
|
36
37
|
- 写入用例必须在治理锁内复核生成计划时的内容哈希,发现外部变化时拒绝覆盖。
|
|
@@ -41,7 +42,7 @@ SQLite / Filesystem Implementation
|
|
|
41
42
|
## CLI 输出契约
|
|
42
43
|
|
|
43
44
|
- 正常输出 indent JSON;错误输出单行 JSON 并写 stderr,退出码非 0。
|
|
44
|
-
- `status` 字段是 Agent 依赖的公共契约,只允许复用既有词汇,不得发明近义词。命令级词汇:ok、error、blocked、needs-input、needs-review、dry-run、synced、planned、ready、applied、issues-found、formatted、archived、up-to-date。文档、领域与 Decision 各有自己的字段词汇表。需要新状态先在本节登记。
|
|
45
|
+
- `status` 字段是 Agent 依赖的公共契约,只允许复用既有词汇,不得发明近义词。命令级词汇:ok、error、blocked、needs-input、needs-review、dry-run、synced、planned、ready、applied、moved、renamed、issues-found、formatted、archived、up-to-date。文档、领域与 Decision 各有自己的字段词汇表。需要新状态先在本节登记。
|
|
45
46
|
- 可恢复的输入错误必须包含稳定 `code`、对应字段和机器可读的期望类型;当正确序列化方式不直观时,同时返回示例值或修复提示。自然语言 message 与示例可以演进,不作为调用方分支判断依据。
|
|
46
47
|
- 前置条件缺失时优先降级执行:能完成的部分照常完成,输出 `needs-input` 并以 `skipped` 字段显式列出被跳过的步骤,而非整体报错退出。
|
|
47
48
|
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"""SPEC:
|
|
2
|
+
name: pypi_verify
|
|
3
|
+
purpose: 有限等待公共 PyPI 安装可用,并验证已发布版本
|
|
4
|
+
idempotent: true
|
|
5
|
+
side_effects:
|
|
6
|
+
- 在临时虚拟环境安装已发布的包,不构建或上传产物
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import argparse
|
|
12
|
+
import os
|
|
13
|
+
import subprocess
|
|
14
|
+
import tempfile
|
|
15
|
+
import time
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def verify(version: str, environment: Path) -> None:
|
|
20
|
+
"""Retry installation for at most three minutes; never retry a version mismatch."""
|
|
21
|
+
subprocess.run(["uv", "venv", str(environment)], check=True)
|
|
22
|
+
bin_dir = environment / ("Scripts" if os.name == "nt" else "bin")
|
|
23
|
+
python = bin_dir / ("python.exe" if os.name == "nt" else "python")
|
|
24
|
+
campfire = bin_dir / ("campfire.exe" if os.name == "nt" else "campfire")
|
|
25
|
+
command = [
|
|
26
|
+
"uv",
|
|
27
|
+
"pip",
|
|
28
|
+
"install",
|
|
29
|
+
"--python",
|
|
30
|
+
str(python),
|
|
31
|
+
"--refresh",
|
|
32
|
+
"--index-url",
|
|
33
|
+
"https://pypi.org/simple",
|
|
34
|
+
f"campfire-cli=={version}",
|
|
35
|
+
]
|
|
36
|
+
deadline = time.monotonic() + 180
|
|
37
|
+
while True:
|
|
38
|
+
try:
|
|
39
|
+
subprocess.run(command, check=True, timeout=max(0.001, deadline - time.monotonic()))
|
|
40
|
+
break
|
|
41
|
+
except (subprocess.CalledProcessError, subprocess.TimeoutExpired):
|
|
42
|
+
remaining = deadline - time.monotonic()
|
|
43
|
+
if remaining <= 15:
|
|
44
|
+
raise
|
|
45
|
+
print("PyPI installation unavailable; retrying in 15 seconds", flush=True)
|
|
46
|
+
time.sleep(15)
|
|
47
|
+
installed = subprocess.run(
|
|
48
|
+
[str(campfire), "version"],
|
|
49
|
+
check=True,
|
|
50
|
+
capture_output=True,
|
|
51
|
+
text=True,
|
|
52
|
+
timeout=30,
|
|
53
|
+
).stdout.strip()
|
|
54
|
+
if installed != version:
|
|
55
|
+
raise SystemExit(f"installed version {installed} does not match {version}")
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def main() -> None:
|
|
59
|
+
parser = argparse.ArgumentParser()
|
|
60
|
+
parser.add_argument("version")
|
|
61
|
+
args = parser.parse_args()
|
|
62
|
+
with tempfile.TemporaryDirectory(prefix="campfire-pypi-") as directory:
|
|
63
|
+
verify(args.version, Path(directory) / "venv")
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
if __name__ == "__main__":
|
|
67
|
+
main()
|
|
@@ -103,7 +103,7 @@ def main() -> None:
|
|
|
103
103
|
if arguments.artifact_dir is not None and not arguments.release:
|
|
104
104
|
parser.error("--artifact-dir 只能与 --release 一起使用")
|
|
105
105
|
run("uv", "run", "ruff", "check", "src", "tests", "scripts")
|
|
106
|
-
run("uv", "run", "pytest", "-q")
|
|
106
|
+
run("uv", "run", "pytest", "-q", "--durations=10")
|
|
107
107
|
if arguments.release:
|
|
108
108
|
version = project_version()
|
|
109
109
|
check_tag(version)
|
{campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/base/schema/operation_schema.py
RENAMED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from collections.abc import Iterable
|
|
2
|
+
from os import PathLike
|
|
2
3
|
from pathlib import PurePosixPath
|
|
3
4
|
from typing import Literal
|
|
4
5
|
|
|
@@ -13,10 +14,13 @@ class CommandFollowUp(BaseModel):
|
|
|
13
14
|
scope: str
|
|
14
15
|
|
|
15
16
|
|
|
16
|
-
def maintenance_sync_follow_up(
|
|
17
|
+
def maintenance_sync_follow_up(
|
|
18
|
+
workspace: str, scopes: Iterable[str | PathLike[str]]
|
|
19
|
+
) -> list[CommandFollowUp]:
|
|
17
20
|
"""Build one sync follow-up at the smallest scope containing all changes."""
|
|
18
21
|
|
|
19
|
-
|
|
22
|
+
normalized = (str(scope).replace("\\", "/").strip("/") for scope in scopes if scope)
|
|
23
|
+
paths = [PurePosixPath(scope) for scope in dict.fromkeys(normalized)]
|
|
20
24
|
if not paths:
|
|
21
25
|
return []
|
|
22
26
|
common = list(paths[0].parts)
|
|
@@ -46,7 +46,8 @@ document/
|
|
|
46
46
|
- `inspect`:向 Agent 返回单篇文档的 Domain、类型、有效 Profile、具体问题,以及 declared、outgoing、incoming、unresolved 四类确定关系。
|
|
47
47
|
- `apply`:根据目标路径和类型解析 Profile,不存在时生成文档,已有 Frontmatter 时只应用显式补丁,无 Frontmatter 时保留正文并补齐完整契约;先完整渲染并校验,追加 `--confirm` 后原子写入。
|
|
48
48
|
- `template`:只继承 base Profile,必须位于所属 Domain 的 `_模板/`;Domain 归属由物理路径解析,不在 Frontmatter 复制模板作用域或继承关系。
|
|
49
|
-
- `move`:在任意已声明 Domain
|
|
49
|
+
- `move`:在任意已声明 Domain 之间移动一篇文档,按目标 Profile 对齐可确定的 `domain`/`project` 归属,并更新可确定解析的 Wiki、Markdown 和路径引用。目标 Profile 缺少业务字段时返回 `needs-input`,不猜测。
|
|
50
|
+
- `rename`:保持一篇文档的物理目录与 Domain 归属不变,根据逻辑标题重算类型前缀文件名,并在同一变更集中更新 `name` 与可确定引用。目标存在时阻止,不覆盖或自动编号。
|
|
50
51
|
- `scanner`:统一解释受管根、忽略目录和豁免文件;Document 与 Maintenance 共用。
|
|
51
52
|
|
|
52
53
|
Document Service 可以被 Workspace Restructure 编排,但不得反向依赖 Maintenance。批量计划文件、运行记录、MOC、Base、归档和重构批次不属于 Document App。
|
|
@@ -67,6 +68,8 @@ Document 写入接口不得要求 Agent 猜测 Frontmatter 输入契约:
|
|
|
67
68
|
- Document App 解析一次目标 EffectiveProfile,并由 apply 与 move 共用的值解码器转换补丁:enum、string 和 date 保留原始字符串,boolean 只接受明确的 `true` 或 `false`,list 只接受严格 JSON 数组。
|
|
68
69
|
- Profile 与 Rule Service 继续拥有字段类型、合法值和业务校验,不保存命令行字符串。命令帮助负责 Shell 展示方式,并为列表值给出 `--set 'tags=["tag1","tag2"]'` 形式的最小例子。
|
|
69
70
|
- 输入错误统一返回稳定错误码、字段、实际值、期望类型和可直接照抄的参数示例;apply 与 move 不得分别构造两套解码或诊断。
|
|
71
|
+
- apply 在 Profile 已明确时并列收集可确定的禁用字段、缺失字段与类型错误;无效赋值不再重复报同字段缺失。有错误不写入且 follow-up 为空;只有缺失输入时返回 needs-input,含其他问题时返回 blocked 并保留 missing_fields。
|
|
72
|
+
- 文档相对路径始终以 Workspace 根解析,不受 cwd 影响;apply 的 domain-missing 返回实际解析路径和带 Workspace 的领域发现入口,不默认枚举全量候选。
|
|
70
73
|
- 不因输入格式不直观而增加 `--tags`、`--sources` 等字段专用参数,也不把逗号字符串静默猜成列表。
|
|
71
74
|
- 现有文档的有效 Profile 已由 `document inspect` 返回。Skill 只在字段契约未知时安排一次 `inspect → apply`;契约已知的补丁直接 apply,正文小改不进入本接口。
|
|
72
75
|
|
{campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/cli/document_cli.py
RENAMED
|
@@ -21,6 +21,7 @@ SET_OPTION_HELP = (
|
|
|
21
21
|
"值类型由有效 Profile 决定;列表使用严格 JSON,例如 "
|
|
22
22
|
'--set \'tags=["tag1","tag2"]\'。'
|
|
23
23
|
)
|
|
24
|
+
PATH_OPTION_HELP = "Workspace 根目录相对路径(不是 cwd 相对路径),或 Workspace 内绝对路径"
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
def service(ctx: typer.Context) -> DocumentService:
|
|
@@ -31,19 +32,25 @@ def service(ctx: typer.Context) -> DocumentService:
|
|
|
31
32
|
|
|
32
33
|
|
|
33
34
|
@document_cli.command("check")
|
|
34
|
-
def check(
|
|
35
|
+
def check(
|
|
36
|
+
ctx: typer.Context, path: str = typer.Option(..., "--path", help=PATH_OPTION_HELP)
|
|
37
|
+
) -> None:
|
|
35
38
|
"""检查一篇 Markdown 文档是否符合当前类型与 Profile 契约。"""
|
|
36
39
|
emit(invoke(lambda: service(ctx).check(path)))
|
|
37
40
|
|
|
38
41
|
|
|
39
42
|
@document_cli.command("kanban-check")
|
|
40
|
-
def kanban_check(
|
|
43
|
+
def kanban_check(
|
|
44
|
+
ctx: typer.Context, path: str = typer.Option(..., "--path", help=PATH_OPTION_HELP)
|
|
45
|
+
) -> None:
|
|
41
46
|
"""检查文档是否满足 Obsidian Kanban 插件的渲染契约。"""
|
|
42
47
|
emit(invoke(lambda: service(ctx).kanban_check(path)))
|
|
43
48
|
|
|
44
49
|
|
|
45
50
|
@document_cli.command("inspect")
|
|
46
|
-
def inspect(
|
|
51
|
+
def inspect(
|
|
52
|
+
ctx: typer.Context, path: str = typer.Option(..., "--path", help=PATH_OPTION_HELP)
|
|
53
|
+
) -> None:
|
|
47
54
|
"""返回单篇文档的 Profile、领域、确定关系和问题上下文。
|
|
48
55
|
|
|
49
56
|
示例:campfire document inspect --path "mywork/项目/记录-进展.md"
|
|
@@ -62,22 +69,24 @@ def list_documents(
|
|
|
62
69
|
limit: int | None = typer.Option(None, "--limit", min=1),
|
|
63
70
|
) -> None:
|
|
64
71
|
"""按 Project、Domain、类型与状态列出受管内容文档。"""
|
|
65
|
-
emit(
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
emit(
|
|
73
|
+
invoke(
|
|
74
|
+
lambda: service(ctx).list(
|
|
75
|
+
project=project,
|
|
76
|
+
domain=domain,
|
|
77
|
+
document_type=document_type,
|
|
78
|
+
document_status=document_status,
|
|
79
|
+
task_status=task_status,
|
|
80
|
+
limit=limit,
|
|
81
|
+
)
|
|
73
82
|
)
|
|
74
|
-
)
|
|
83
|
+
)
|
|
75
84
|
|
|
76
85
|
|
|
77
86
|
@document_cli.command("format")
|
|
78
87
|
def format_document(
|
|
79
88
|
ctx: typer.Context,
|
|
80
|
-
path: str = typer.Option(..., "--path", help=
|
|
89
|
+
path: str = typer.Option(..., "--path", help=PATH_OPTION_HELP),
|
|
81
90
|
confirm: bool = typer.Option(False, "--confirm"),
|
|
82
91
|
) -> None:
|
|
83
92
|
"""预览或执行一篇文档的 Frontmatter 字段排序。"""
|
|
@@ -112,7 +121,7 @@ def apply_document(
|
|
|
112
121
|
path: str = typer.Option(
|
|
113
122
|
...,
|
|
114
123
|
"--path",
|
|
115
|
-
help=
|
|
124
|
+
help=PATH_OPTION_HELP + ";创建或唯一更新时可省略 .md,创建时可省略类型前缀",
|
|
116
125
|
),
|
|
117
126
|
document_type: str | None = typer.Option(None, "--type"),
|
|
118
127
|
set_values: list[str] | None = typer.Option(None, "--set", help=SET_OPTION_HELP),
|
|
@@ -128,23 +137,25 @@ def apply_document(
|
|
|
128
137
|
已有文档的 --type 发生变化时,同一原子操作同步文件名和引用。
|
|
129
138
|
"""
|
|
130
139
|
values = invoke(lambda: parse_values(set_values or []))
|
|
131
|
-
emit(
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
140
|
+
emit(
|
|
141
|
+
invoke(
|
|
142
|
+
lambda: service(ctx).apply(
|
|
143
|
+
DocumentApplyRequest(
|
|
144
|
+
path=path,
|
|
145
|
+
document_type=document_type,
|
|
146
|
+
values=values,
|
|
147
|
+
expected_hash=expected_hash,
|
|
148
|
+
confirm=confirm,
|
|
149
|
+
)
|
|
139
150
|
)
|
|
140
151
|
)
|
|
141
|
-
)
|
|
152
|
+
)
|
|
142
153
|
|
|
143
154
|
|
|
144
155
|
@document_cli.command("move")
|
|
145
156
|
def move_document(
|
|
146
157
|
ctx: typer.Context,
|
|
147
|
-
source: str = typer.Option(..., "--path", help=
|
|
158
|
+
source: str = typer.Option(..., "--path", help=PATH_OPTION_HELP),
|
|
148
159
|
target_domain: str = typer.Option(..., "--domain", help="目标 Domain 的稳定 id"),
|
|
149
160
|
name: str | None = typer.Option(None, "--name", help="可选的新文件名;省略时保持原文件名"),
|
|
150
161
|
set_values: list[str] | None = typer.Option(None, "--set", help=SET_OPTION_HELP),
|
|
@@ -154,14 +165,37 @@ def move_document(
|
|
|
154
165
|
) -> None:
|
|
155
166
|
"""预览或移动一篇文档,并按目标 Domain 契约更新归属与引用。"""
|
|
156
167
|
values = invoke(lambda: parse_values(set_values or []))
|
|
157
|
-
emit(
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
168
|
+
emit(
|
|
169
|
+
invoke(
|
|
170
|
+
lambda: service(ctx).move(
|
|
171
|
+
source,
|
|
172
|
+
target_domain,
|
|
173
|
+
name=name,
|
|
174
|
+
values=values,
|
|
175
|
+
unset_fields=tuple(unset_fields or []),
|
|
176
|
+
expected_hash=expected_hash,
|
|
177
|
+
confirm=confirm,
|
|
178
|
+
)
|
|
179
|
+
)
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
@document_cli.command("rename")
|
|
184
|
+
def rename_document(
|
|
185
|
+
ctx: typer.Context,
|
|
186
|
+
source: str = typer.Option(..., "--path", help=PATH_OPTION_HELP),
|
|
187
|
+
name: str = typer.Option(..., "--name", help="新标题;不含类型前缀和 .md 后缀"),
|
|
188
|
+
expected_hash: str | None = typer.Option(None, "--expected-hash"),
|
|
189
|
+
confirm: bool = typer.Option(False, "--confirm"),
|
|
190
|
+
) -> None:
|
|
191
|
+
"""预览或原地改名一篇文档,并同步标题、文件名与受管引用。"""
|
|
192
|
+
emit(
|
|
193
|
+
invoke(
|
|
194
|
+
lambda: service(ctx).rename(
|
|
195
|
+
source,
|
|
196
|
+
name,
|
|
197
|
+
expected_hash=expected_hash,
|
|
198
|
+
confirm=confirm,
|
|
199
|
+
)
|
|
166
200
|
)
|
|
167
|
-
)
|
|
201
|
+
)
|
{campfire_cli-0.1.16 → campfire_cli-0.1.18}/src/campfire_cli/app/document/schema/document_schema.py
RENAMED
|
@@ -34,7 +34,7 @@ class DocumentApplyResult(BaseModel):
|
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
class DocumentMoveResult(BaseModel):
|
|
37
|
-
status: Literal["ready", "needs-input", "blocked", "moved"]
|
|
37
|
+
status: Literal["ready", "needs-input", "blocked", "moved", "renamed", "up-to-date"]
|
|
38
38
|
workspace_id: str
|
|
39
39
|
source: str
|
|
40
40
|
target: str
|
|
@@ -97,9 +97,13 @@ class DocumentApplyService:
|
|
|
97
97
|
else source
|
|
98
98
|
)
|
|
99
99
|
target_name = target.relative_to(self._settings.vault_root).as_posix()
|
|
100
|
-
context =
|
|
101
|
-
|
|
102
|
-
|
|
100
|
+
context = (
|
|
101
|
+
None
|
|
102
|
+
if is_system_scope_path(
|
|
103
|
+
self._settings.vault_root, target, self._settings.document_types
|
|
104
|
+
)
|
|
105
|
+
else self._domain_context(target)
|
|
106
|
+
)
|
|
103
107
|
relative_target = target.relative_to(self._settings.vault_root).as_posix()
|
|
104
108
|
if document_type == "human-request" and not relative_target.startswith(
|
|
105
109
|
f"{self._settings.governance['human_request_root']}/"
|
|
@@ -131,40 +135,22 @@ class DocumentApplyService:
|
|
|
131
135
|
frontmatter.pop(field, None)
|
|
132
136
|
actual_hash = file_sha256(source) if exists else "missing"
|
|
133
137
|
unknown = sorted(set(request.values) - set(profile.allowed))
|
|
134
|
-
|
|
135
|
-
return self._result(
|
|
136
|
-
request,
|
|
137
|
-
target_name,
|
|
138
|
-
action,
|
|
139
|
-
profile.name,
|
|
140
|
-
actual_hash,
|
|
141
|
-
"blocked",
|
|
142
|
-
[
|
|
143
|
-
{
|
|
144
|
-
"code": "frontmatter-field-not-allowed",
|
|
145
|
-
"path": request.path,
|
|
146
|
-
"field": key,
|
|
147
|
-
}
|
|
148
|
-
for key in unknown
|
|
149
|
-
],
|
|
150
|
-
)
|
|
151
|
-
|
|
138
|
+
candidates = workspace_candidate_sets(self._settings.vault_root)
|
|
152
139
|
values, input_issues = decode_patch_values(
|
|
153
140
|
profile,
|
|
154
|
-
request.values,
|
|
141
|
+
{key: value for key, value in request.values.items() if key in profile.allowed},
|
|
155
142
|
request.path,
|
|
156
|
-
|
|
143
|
+
candidates,
|
|
157
144
|
)
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
profile.
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
)
|
|
145
|
+
input_issues[:0] = [
|
|
146
|
+
{
|
|
147
|
+
"code": "frontmatter-field-not-allowed",
|
|
148
|
+
"path": request.path,
|
|
149
|
+
"field": key,
|
|
150
|
+
"allowed": list(profile.allowed),
|
|
151
|
+
}
|
|
152
|
+
for key in unknown
|
|
153
|
+
]
|
|
168
154
|
# Field semantics are fully declared by the selected Profile; no type-specific injection.
|
|
169
155
|
frontmatter.update(values)
|
|
170
156
|
frontmatter["type"] = document_type
|
|
@@ -195,12 +181,22 @@ class DocumentApplyService:
|
|
|
195
181
|
else:
|
|
196
182
|
rendered = render_document(frontmatter, next_body, list(profile.field_order))
|
|
197
183
|
issues = self._rules.check_content(self._settings.vault_root, target, rendered, profile)
|
|
184
|
+
# Rejected assignments already have a precise diagnostic; their fallback values
|
|
185
|
+
# must not produce contradictory missing-field or value errors.
|
|
186
|
+
invalid_fields = {item["field"] for item in input_issues}
|
|
187
|
+
issues = input_issues + [item for item in issues if item.get("field") not in invalid_fields]
|
|
198
188
|
if target != source and target.exists():
|
|
199
189
|
issues.insert(0, {"code": "target-exists", "path": target_name})
|
|
200
|
-
enrich_profile_issues(issues, profile,
|
|
190
|
+
enrich_profile_issues(issues, profile, candidates)
|
|
201
191
|
missing_codes = {"frontmatter-field-missing", "frontmatter-field-empty"}
|
|
202
192
|
missing = [item for item in issues if item["code"] in missing_codes]
|
|
203
|
-
status =
|
|
193
|
+
status = (
|
|
194
|
+
"blocked"
|
|
195
|
+
if any(item["code"] not in missing_codes for item in issues)
|
|
196
|
+
else "needs-input"
|
|
197
|
+
if missing
|
|
198
|
+
else "planned"
|
|
199
|
+
)
|
|
204
200
|
result = self._result(
|
|
205
201
|
request,
|
|
206
202
|
target_name,
|
|
@@ -354,4 +350,17 @@ class DocumentApplyService:
|
|
|
354
350
|
self._settings.governance.get("domain_marker", "_领域.md"),
|
|
355
351
|
)
|
|
356
352
|
except DomainContextError as exc:
|
|
357
|
-
|
|
353
|
+
if exc.code == "domain-missing":
|
|
354
|
+
exc.details.update(
|
|
355
|
+
resolved_path=str(path),
|
|
356
|
+
path_base="workspace",
|
|
357
|
+
workspace_root=str(self._settings.vault_root),
|
|
358
|
+
hint=(
|
|
359
|
+
"相对路径以 Workspace 根目录为基准,而不是 cwd;请先选择已声明的 Domain。"
|
|
360
|
+
),
|
|
361
|
+
next_action={
|
|
362
|
+
"command": "workspace domain list",
|
|
363
|
+
"arguments": {"workspace": self._settings.workspace_id},
|
|
364
|
+
},
|
|
365
|
+
)
|
|
366
|
+
raise
|