brigade-cli 0.8.2__tar.gz → 0.9.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- brigade_cli-0.9.0/PKG-INFO +194 -0
- brigade_cli-0.9.0/README.md +165 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/pyproject.toml +1 -1
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/__init__.py +1 -1
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/cli.py +54 -3
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/handoff_cmd.py +2 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/install.py +5 -1
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/operator_cmd.py +2 -1
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/hermes/memory-handoff.harness.json +1 -1
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/hermes/model-lanes.harness.json +1 -1
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/hermes/workspace.harness.json +1 -1
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/memory/chat-memory-sweep.example.json +1 -1
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/memory/memory-care.example.json +1 -1
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/policies/personal.json +1 -1
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/policies/public-content.json +1 -1
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/policies/public-repo.json +1 -1
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/tools_cmd.py +18 -3
- brigade_cli-0.9.0/src/brigade_cli.egg-info/PKG-INFO +194 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade_cli.egg-info/SOURCES.txt +1 -0
- brigade_cli-0.9.0/tests/test_cli_help.py +55 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_operator_cmd.py +8 -0
- brigade_cli-0.8.2/PKG-INFO +0 -778
- brigade_cli-0.8.2/README.md +0 -749
- brigade_cli-0.8.2/src/brigade_cli.egg-info/PKG-INFO +0 -778
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/LICENSE +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/MANIFEST.in +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/QUICKSTART.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/setup.cfg +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/__main__.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/aboyeur.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/add.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/agents.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/budgets.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/budgets_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/center_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/chat_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/config.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/context_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/daily_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/doctor.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/dogfood_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/fragments.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/handoff.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/hermes_adapter.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/ingest.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/learn_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/managed.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/memory_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/notifications_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/pantry_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/phases_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/proc.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/projects_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/prompt.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/py.typed +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/reconfigure.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/registry.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/release_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/repos_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/research/__init__.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/research/config.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/research/engine.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/research/extract.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/research/handoff.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/research/llm.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/research/registry.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/research/report.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/research/sources/__init__.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/research/sources/cli.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/research/sources/local.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/research/sources/web.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/research/types.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/research_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/roadmap_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/roster.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/roster_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/runbook_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/runs_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/scrub.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/security_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/selection.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/skills_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/station.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/status.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/adal/memory-handoffs/TEMPLATE.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/aider/memory-handoffs/TEMPLATE.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/antigravity/memory-handoffs/TEMPLATE.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/claude/memory-handoffs/TEMPLATE.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/codex/memory-handoffs/TEMPLATE.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/continue/memory-handoffs/TEMPLATE.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/copilot/memory-handoffs/TEMPLATE.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/cursor/memory-handoffs/TEMPLATE.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/depth/repo.json +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/depth/workspace.json +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/generic/harness-adapter-checklist.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/generic/memory-contract.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/goose/memory-handoffs/TEMPLATE.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/handoff/handoff-sources.example.json +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/handoff/openclaw-ingest-receipt.example.json +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/harnesses/adal.json +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/harnesses/aider.json +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/harnesses/antigravity.json +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/harnesses/claude.json +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/harnesses/codex.json +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/harnesses/continue.json +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/harnesses/copilot.json +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/harnesses/cursor.json +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/harnesses/goose.json +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/harnesses/hermes.json +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/harnesses/kimi.json +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/harnesses/openclaw.json +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/harnesses/opencode.json +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/harnesses/openhands.json +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/harnesses/pi.json +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/harnesses/qwen.json +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/hermes/README.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/hermes/memory-handoffs/TEMPLATE.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/hooks/pre-push +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/includes/publisher.json +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/kimi/memory-handoffs/TEMPLATE.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/memory/cards/backup-restic.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/memory/cards/chat-surface-crawlers.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/memory/cards/content-safety.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/memory/cards/handoff-flow.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/memory/cards/memory-architecture.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/memory/cards/memory-care-staleness.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/memory/cards/memory-scanner.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/memory/cards/multi-workspace-handoff-admin.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/memory/cards/obsidian-notes.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/memory/cards/pipeline-standups.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/memory/cards/tokenjuice-output-compaction.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/openclaw/README.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/openclaw/acp-escalation.openclaw.json +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/openclaw/memory-sweep-cron.openclaw.json +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/openclaw/model-aliases.openclaw.json +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/openclaw/ollama-memory-search.openclaw.json +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/opencode/memory-handoffs/TEMPLATE.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/openhands/memory-handoffs/TEMPLATE.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/pi/memory-handoffs/TEMPLATE.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/qwen/memory-handoffs/TEMPLATE.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/scripts/backup-restic.sh +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/skills/note/SKILL.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/workspace/AGENTS.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/workspace/CLAUDE.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/workspace/HEARTBEAT.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/workspace/IDENTITY.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/workspace/INSTALL_FOR_AGENTS.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/workspace/MEMORY.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/workspace/SAFETY_RULES.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/workspace/SOUL.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/workspace/TOOLS.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/workspace/USER.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/workspace/rules/acceptance-driven-work.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/workspace/rules/issue-tdd-loop.md +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/toml_compat.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/untrusted.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/untrusted_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/work_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade_cli.egg-info/dependency_links.txt +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade_cli.egg-info/entry_points.txt +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade_cli.egg-info/requires.txt +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade_cli.egg-info/top_level.txt +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_aboyeur.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_add.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_agents.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_budgets.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_cli_alias.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_config.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_doctor.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_dogfood_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_fragments.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_gitignore.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_handoff.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_handoff_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_ingest.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_init.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_install.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_managed.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_memory_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_neutrality.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_notifications_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_pantry_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_phase100_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_phase101_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_phase165_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_phase36_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_phase37_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_phase38_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_phase39_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_phase40_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_phase41_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_phase42_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_phase43_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_phase44_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_phase45_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_phase46_50_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_phase51_55_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_phase56_60_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_phase96_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_phase97_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_phase98_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_phase99_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_privacy_regression.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_proc.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_prompt.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_reconfigure.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_registry.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_release_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_repos_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_research_cli_sources.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_research_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_research_config.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_research_engine.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_research_extract.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_research_handoff.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_research_llm.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_research_local_sources.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_research_registry.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_research_report.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_research_types.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_research_web.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_roadmap_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_roster.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_roster_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_run_cli.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_runbook_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_runs_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_scrub.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_security_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_selection.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_skills_cmd.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_station.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_status.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_toml_compat.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_untrusted.py +0 -0
- {brigade_cli-0.8.2 → brigade_cli-0.9.0}/tests/test_work_cmd.py +0 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: brigade-cli
|
|
3
|
+
Version: 0.9.0
|
|
4
|
+
Summary: AI agent memory, handoffs, and local guardrails for Codex, Claude Code, OpenCode, Hermes, and OpenClaw.
|
|
5
|
+
Author-email: Solomon Neas <srneas@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://brigade.tools
|
|
8
|
+
Project-URL: Repository, https://github.com/escoffier-labs/brigade
|
|
9
|
+
Project-URL: Cookbook, https://github.com/solomonneas/solos-cookbook
|
|
10
|
+
Project-URL: OpenClaw, https://github.com/solomonneas/openclaw
|
|
11
|
+
Project-URL: ContentGuard, https://github.com/solomonneas/content-guard
|
|
12
|
+
Project-URL: AgentPantry, https://github.com/escoffier-labs/agentpantry
|
|
13
|
+
Project-URL: Issues, https://github.com/escoffier-labs/brigade/issues
|
|
14
|
+
Keywords: agents,ai-agents,agent-memory,agent-handoffs,ai-memory,openclaw,claude-code,codex,opencode,memory,bootstrap,brigade,brigade-cli,operator,local-first,guardrails,agents-md
|
|
15
|
+
Classifier: Development Status :: 3 - Alpha
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: pytest>=7; extra == "dev"
|
|
26
|
+
Provides-Extra: research
|
|
27
|
+
Requires-Dist: playwright>=1.40; extra == "research"
|
|
28
|
+
Dynamic: license-file
|
|
29
|
+
|
|
30
|
+
<p align="center">
|
|
31
|
+
<img src="docs/assets/brigade-social-preview.jpg" alt="Brigade" width="900">
|
|
32
|
+
</p>
|
|
33
|
+
|
|
34
|
+
<h1 align="center">Brigade CLI</h1>
|
|
35
|
+
|
|
36
|
+
<p align="center">
|
|
37
|
+
<strong>AI agent memory, handoffs, and local guardrails for Codex, Claude Code, OpenCode, and a dozen other harnesses.</strong>
|
|
38
|
+
</p>
|
|
39
|
+
|
|
40
|
+
<p align="center">
|
|
41
|
+
<img src="https://img.shields.io/github/actions/workflow/status/escoffier-labs/brigade/ci.yml?branch=main&style=for-the-badge&label=ci" alt="CI status">
|
|
42
|
+
<img src="https://img.shields.io/pypi/v/brigade-cli?style=for-the-badge&label=pypi" alt="PyPI version">
|
|
43
|
+
<img src="https://img.shields.io/badge/python-3.10%2B-blue?style=for-the-badge&logo=python&logoColor=white" alt="Python 3.10+">
|
|
44
|
+
<img src="https://img.shields.io/badge/license-MIT-green?style=for-the-badge" alt="MIT license">
|
|
45
|
+
</p>
|
|
46
|
+
|
|
47
|
+
Your agents run loops. Brigade keeps the receipts.
|
|
48
|
+
|
|
49
|
+
## Why I built this
|
|
50
|
+
|
|
51
|
+
I run an always-on OpenClaw agent next to daily Codex and Claude Code sessions, and I have since January. Every one of those tools wakes up empty. Whatever a session learned about my machine, my rules, or yesterday's dead ends scattered across tool-specific folders and died there.
|
|
52
|
+
|
|
53
|
+
So I hand-rolled the fixes, one incident at a time: a slim `MEMORY.md` index pointing at small memory cards instead of one giant file, a handoff note format every harness could write, an ingest cron that filed the good notes into durable memory every 30 minutes, staleness checks so old cards stopped being trusted forever.
|
|
54
|
+
|
|
55
|
+
Two incidents shaped the design more than anything I planned. First, a nightly "dreaming" job that auto-promoted session fragments quietly bloated `MEMORY.md` to 41KB, way past the 12KB bootstrap budget, so every session started with truncated memory and nobody noticed for weeks. Auto-promotion died that day. Everything goes through review now. Second, I found 195 handoff notes sitting unread across 35 repos because the ingester had a hardcoded three-repo allowlist and nothing warned about the coverage gap. Silence is the failure mode. Every part of Brigade that lints, warns, or writes a receipt exists because something once failed quietly.
|
|
56
|
+
|
|
57
|
+
That system now runs 482 memory cards and survives daily multi-agent work. But explaining it to anyone meant: clone six repos, write these crons, keep your index slim, watch for staleness, and whatever you do, turn auto-promotion off. Brigade is that setup packaged as one installable CLI. The full production stack is documented in the [solos-cookbook](https://github.com/solomonneas/solos-cookbook) if you want to see where it came from.
|
|
58
|
+
|
|
59
|
+
## The loop
|
|
60
|
+
|
|
61
|
+
Writer harnesses leave handoff notes as they work. A memory owner (OpenClaw, Hermes, or just you) ingests the ones worth keeping. Brigade lints, guards, and routes everything in between, and every consequential action lands a receipt in a plain file you can grep, diff, and prune.
|
|
62
|
+
|
|
63
|
+
1. agents write handoff notes into their own local inboxes
|
|
64
|
+
2. Brigade lints and scans them before they can become memory
|
|
65
|
+
3. safe targeted notes get filed into durable memory by the owner
|
|
66
|
+
4. ambiguous or risky notes wait for your review
|
|
67
|
+
5. future sessions start with better context, and receipts show what happened
|
|
68
|
+
|
|
69
|
+
```mermaid
|
|
70
|
+
flowchart LR
|
|
71
|
+
WRITERS["writer harnesses<br/>Codex · Claude Code · OpenCode · ..."]
|
|
72
|
+
BRIGADE["Brigade<br/>lint · guard · route · receipts"]
|
|
73
|
+
REVIEW["operator review<br/>safe · ambiguous · risky"]
|
|
74
|
+
OWNER["memory owner<br/>OpenClaw / Hermes / you"]
|
|
75
|
+
MEM["durable memory<br/>MEMORY.md index · memory cards"]
|
|
76
|
+
|
|
77
|
+
WRITERS -- handoff notes --> BRIGADE --> REVIEW
|
|
78
|
+
REVIEW -- safe targeted notes --> OWNER --> MEM
|
|
79
|
+
MEM -. context .-> WRITERS
|
|
80
|
+
|
|
81
|
+
classDef brigade fill:#2563eb,stroke:#1d4ed8,color:#fff;
|
|
82
|
+
classDef memory fill:#ecfdf5,stroke:#059669,color:#064e3b;
|
|
83
|
+
classDef gate fill:#fff7ed,stroke:#ea580c,color:#7c2d12;
|
|
84
|
+
class BRIGADE brigade;
|
|
85
|
+
class OWNER,MEM memory;
|
|
86
|
+
class REVIEW gate;
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Memory has two layers: knowledge cards under `memory/cards/` hold the detail, and `MEMORY.md` stays a slim one-line-per-card index that loads every session. `brigade memory care scan` flags stale, contradictory, or undersourced cards for review instead of letting them rot. Brigade never edits canonical memory itself; the owner does the writing.
|
|
90
|
+
|
|
91
|
+
It all runs on the machine you control: laptop, workstation, or VPS. Local by default, loud about the exceptions.
|
|
92
|
+
|
|
93
|
+
## Install
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
pipx install brigade-cli
|
|
97
|
+
brigade operator quickstart --target ./my-repo --harnesses codex
|
|
98
|
+
brigade operator doctor --target ./my-repo --profile local-operator
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
For an OpenClaw or Hermes workspace instead of a code repo:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
brigade operator quickstart --target ~/agent-workspace --depth workspace --harnesses openclaw,hermes --owner openclaw
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Use `--dry-run` first to preview the planned steps without writing anything; `brigade init --target ./my-repo --harnesses codex --dry-run` shows the full file-by-file list. Pass more harnesses as a comma-separated list. Quickstart only wires the harnesses you select and leaves the rest alone.
|
|
108
|
+
|
|
109
|
+
Write a handoff and check the wiring:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
brigade handoff draft --target ./my-repo --inbox codex \
|
|
113
|
+
--title "What changed" \
|
|
114
|
+
--summary "Short note future agents should know." \
|
|
115
|
+
--content "The durable note itself goes here."
|
|
116
|
+
brigade handoff lint --target ./my-repo
|
|
117
|
+
brigade handoff doctor --target ./my-repo
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
New here? Start with [docs/first-10-minutes.md](docs/first-10-minutes.md). Already have a homegrown setup with scripts, crons, and handoff folders? Brigade has an adoption path that inventories what you have before changing anything: start with `brigade operator adopt plan` and see the [technical guide](docs/technical-guide.md). Want an agent to set this up for you? Point it at this repo; [AGENTS.md](AGENTS.md) tells it exactly what to do and where to stop.
|
|
121
|
+
|
|
122
|
+
## Harness support
|
|
123
|
+
|
|
124
|
+
Each writer gets its own local inbox; one canonical owner ingests. Brigade keeps the note format consistent so different tools can contribute without inventing their own styles.
|
|
125
|
+
|
|
126
|
+
| Writer | Harness id | Inbox |
|
|
127
|
+
|---|---|---|
|
|
128
|
+
| Codex CLI | `codex` | `.codex/memory-handoffs/` |
|
|
129
|
+
| Claude Code | `claude` | `.claude/memory-handoffs/` |
|
|
130
|
+
| OpenCode | `opencode` | `.opencode/memory-handoffs/` |
|
|
131
|
+
| Antigravity | `antigravity` | `.antigravity/memory-handoffs/` |
|
|
132
|
+
| Pi | `pi` | `.pi/memory-handoffs/` |
|
|
133
|
+
| Cursor | `cursor` | `.cursor/memory-handoffs/` |
|
|
134
|
+
| Aider | `aider` | `.aider/memory-handoffs/` |
|
|
135
|
+
| Goose | `goose` | `.goose/memory-handoffs/` |
|
|
136
|
+
| Continue | `continue` | `.continue/memory-handoffs/` |
|
|
137
|
+
| GitHub Copilot CLI | `copilot` | `.copilot/memory-handoffs/` |
|
|
138
|
+
| Qwen Code | `qwen` | `.qwen/memory-handoffs/` |
|
|
139
|
+
| Kimi Code | `kimi` | `.kimi/memory-handoffs/` |
|
|
140
|
+
| AdaL | `adal` | `.adal/memory-handoffs/` |
|
|
141
|
+
| OpenHands | `openhands` | `.openhands/memory-handoffs/` |
|
|
142
|
+
| Hermes | `hermes` | `.hermes/memory-handoffs/` |
|
|
143
|
+
| OpenClaw | `openclaw` | usually the memory owner, not a writer |
|
|
144
|
+
|
|
145
|
+
All of them get handoff templates, ingest source coverage, and projected tools/skills. Per-harness details are in the [technical guide](docs/technical-guide.md).
|
|
146
|
+
|
|
147
|
+
## Beyond memory
|
|
148
|
+
|
|
149
|
+
The memory loop is the core. Around it, the same review-and-receipt pattern covers the rest of an operator's day, and you can ignore all of it until you need it:
|
|
150
|
+
|
|
151
|
+
- **Daily loop**: `brigade work brief` shows pending work, imports, and warnings; `brigade daily status` keeps it bounded and cheap.
|
|
152
|
+
- **Security**: `brigade security scan` is a local read-only scanner for agent workspaces (secrets, risky hooks, MCP configs, prompt-injection patterns); `brigade scrub` gates content before it leaves the machine.
|
|
153
|
+
- **Tools and skills**: one reviewed catalog projected into every harness's native format, with approval gates for anything that executes.
|
|
154
|
+
- **Research**: `brigade research run` turns a question into a cited local report and a reviewable memory handoff.
|
|
155
|
+
- **Fleet and release**: health evidence across your local repos and release-readiness receipts, with no publish step.
|
|
156
|
+
|
|
157
|
+
The full tour of every station lives in [docs/overview.md](docs/overview.md).
|
|
158
|
+
|
|
159
|
+
## Why not something else?
|
|
160
|
+
|
|
161
|
+
- **mem0, Letta, and friends** are memory layers for apps you are building, usually behind an API or a server. Brigade is for the agent CLIs you already run, and it is file-first: your memory is markdown in your repo, reviewable in git, readable without Brigade.
|
|
162
|
+
- **Native harness memory** (each tool's own auto-memory) is a per-tool silo. It does not cross harnesses, and it writes without review. Brigade gives every tool one shared format and one canonical owner, with a review gate in between.
|
|
163
|
+
- **A plain CLAUDE.md / AGENTS.md** works great until it bloats past the context budget and goes stale. Brigade exists because mine hit 41KB. It keeps bootstrap files slim, moves detail into indexed cards, and flags staleness instead of trusting last month's facts forever.
|
|
164
|
+
- **A daemon or hosted service** would be simpler to demo and worse to trust. Brigade writes local files when you run a command, and that is all it does.
|
|
165
|
+
|
|
166
|
+
## What Brigade is not
|
|
167
|
+
|
|
168
|
+
Brigade is not a hosted memory service, a daemon, or an automatic release bot.
|
|
169
|
+
|
|
170
|
+
It does not:
|
|
171
|
+
|
|
172
|
+
- run in the background or install schedulers
|
|
173
|
+
- push to GitHub or publish packages
|
|
174
|
+
- send notifications by default
|
|
175
|
+
- save every note automatically
|
|
176
|
+
- turn memory ingest into a silent background process
|
|
177
|
+
- skip review for ambiguous, risky, or failed notes
|
|
178
|
+
|
|
179
|
+
That pause is the point. Agent memory should be useful, not noisy.
|
|
180
|
+
|
|
181
|
+
## Docs
|
|
182
|
+
|
|
183
|
+
- [First 10 minutes](docs/first-10-minutes.md): shortest path from install to healthy setup.
|
|
184
|
+
- [Overview](docs/overview.md): the full tour of every station and diagram.
|
|
185
|
+
- [Technical guide](docs/technical-guide.md): the detailed command walkthrough.
|
|
186
|
+
- [Security and Content Guard](docs/security.md): scanner policies, handoff guards, import flow.
|
|
187
|
+
- [Handoff promotion](docs/handoff-promotion.md): how notes move toward memory.
|
|
188
|
+
- [Repo fleet](docs/repo-fleet.md) and [Tool catalog](docs/tool-catalog.md).
|
|
189
|
+
- [Command inventory](docs/command-inventory.md): every public CLI command.
|
|
190
|
+
- [Roadmap](ROADMAP.md) and [roadmap archive](docs/roadmap-archive.md).
|
|
191
|
+
|
|
192
|
+
Project identity: GitHub [`escoffier-labs/brigade`](https://github.com/escoffier-labs/brigade), website [brigade.tools](https://brigade.tools), PyPI [`brigade-cli`](https://pypi.org/project/brigade-cli/), command `brigade`. The name comes from the kitchen: a *brigade de cuisine* runs the line, and *mise en place* means the station is prepped before service. Set up the rules, memory, tools, and receipts before the session gets expensive.
|
|
193
|
+
|
|
194
|
+
It is early-stage and moving fast. If you hit a broken workflow, a confusing command, or a setup issue, [open an issue](https://github.com/escoffier-labs/brigade/issues) and I will get it fixed.
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="docs/assets/brigade-social-preview.jpg" alt="Brigade" width="900">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">Brigade CLI</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>AI agent memory, handoffs, and local guardrails for Codex, Claude Code, OpenCode, and a dozen other harnesses.</strong>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<img src="https://img.shields.io/github/actions/workflow/status/escoffier-labs/brigade/ci.yml?branch=main&style=for-the-badge&label=ci" alt="CI status">
|
|
13
|
+
<img src="https://img.shields.io/pypi/v/brigade-cli?style=for-the-badge&label=pypi" alt="PyPI version">
|
|
14
|
+
<img src="https://img.shields.io/badge/python-3.10%2B-blue?style=for-the-badge&logo=python&logoColor=white" alt="Python 3.10+">
|
|
15
|
+
<img src="https://img.shields.io/badge/license-MIT-green?style=for-the-badge" alt="MIT license">
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
Your agents run loops. Brigade keeps the receipts.
|
|
19
|
+
|
|
20
|
+
## Why I built this
|
|
21
|
+
|
|
22
|
+
I run an always-on OpenClaw agent next to daily Codex and Claude Code sessions, and I have since January. Every one of those tools wakes up empty. Whatever a session learned about my machine, my rules, or yesterday's dead ends scattered across tool-specific folders and died there.
|
|
23
|
+
|
|
24
|
+
So I hand-rolled the fixes, one incident at a time: a slim `MEMORY.md` index pointing at small memory cards instead of one giant file, a handoff note format every harness could write, an ingest cron that filed the good notes into durable memory every 30 minutes, staleness checks so old cards stopped being trusted forever.
|
|
25
|
+
|
|
26
|
+
Two incidents shaped the design more than anything I planned. First, a nightly "dreaming" job that auto-promoted session fragments quietly bloated `MEMORY.md` to 41KB, way past the 12KB bootstrap budget, so every session started with truncated memory and nobody noticed for weeks. Auto-promotion died that day. Everything goes through review now. Second, I found 195 handoff notes sitting unread across 35 repos because the ingester had a hardcoded three-repo allowlist and nothing warned about the coverage gap. Silence is the failure mode. Every part of Brigade that lints, warns, or writes a receipt exists because something once failed quietly.
|
|
27
|
+
|
|
28
|
+
That system now runs 482 memory cards and survives daily multi-agent work. But explaining it to anyone meant: clone six repos, write these crons, keep your index slim, watch for staleness, and whatever you do, turn auto-promotion off. Brigade is that setup packaged as one installable CLI. The full production stack is documented in the [solos-cookbook](https://github.com/solomonneas/solos-cookbook) if you want to see where it came from.
|
|
29
|
+
|
|
30
|
+
## The loop
|
|
31
|
+
|
|
32
|
+
Writer harnesses leave handoff notes as they work. A memory owner (OpenClaw, Hermes, or just you) ingests the ones worth keeping. Brigade lints, guards, and routes everything in between, and every consequential action lands a receipt in a plain file you can grep, diff, and prune.
|
|
33
|
+
|
|
34
|
+
1. agents write handoff notes into their own local inboxes
|
|
35
|
+
2. Brigade lints and scans them before they can become memory
|
|
36
|
+
3. safe targeted notes get filed into durable memory by the owner
|
|
37
|
+
4. ambiguous or risky notes wait for your review
|
|
38
|
+
5. future sessions start with better context, and receipts show what happened
|
|
39
|
+
|
|
40
|
+
```mermaid
|
|
41
|
+
flowchart LR
|
|
42
|
+
WRITERS["writer harnesses<br/>Codex · Claude Code · OpenCode · ..."]
|
|
43
|
+
BRIGADE["Brigade<br/>lint · guard · route · receipts"]
|
|
44
|
+
REVIEW["operator review<br/>safe · ambiguous · risky"]
|
|
45
|
+
OWNER["memory owner<br/>OpenClaw / Hermes / you"]
|
|
46
|
+
MEM["durable memory<br/>MEMORY.md index · memory cards"]
|
|
47
|
+
|
|
48
|
+
WRITERS -- handoff notes --> BRIGADE --> REVIEW
|
|
49
|
+
REVIEW -- safe targeted notes --> OWNER --> MEM
|
|
50
|
+
MEM -. context .-> WRITERS
|
|
51
|
+
|
|
52
|
+
classDef brigade fill:#2563eb,stroke:#1d4ed8,color:#fff;
|
|
53
|
+
classDef memory fill:#ecfdf5,stroke:#059669,color:#064e3b;
|
|
54
|
+
classDef gate fill:#fff7ed,stroke:#ea580c,color:#7c2d12;
|
|
55
|
+
class BRIGADE brigade;
|
|
56
|
+
class OWNER,MEM memory;
|
|
57
|
+
class REVIEW gate;
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Memory has two layers: knowledge cards under `memory/cards/` hold the detail, and `MEMORY.md` stays a slim one-line-per-card index that loads every session. `brigade memory care scan` flags stale, contradictory, or undersourced cards for review instead of letting them rot. Brigade never edits canonical memory itself; the owner does the writing.
|
|
61
|
+
|
|
62
|
+
It all runs on the machine you control: laptop, workstation, or VPS. Local by default, loud about the exceptions.
|
|
63
|
+
|
|
64
|
+
## Install
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
pipx install brigade-cli
|
|
68
|
+
brigade operator quickstart --target ./my-repo --harnesses codex
|
|
69
|
+
brigade operator doctor --target ./my-repo --profile local-operator
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
For an OpenClaw or Hermes workspace instead of a code repo:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
brigade operator quickstart --target ~/agent-workspace --depth workspace --harnesses openclaw,hermes --owner openclaw
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Use `--dry-run` first to preview the planned steps without writing anything; `brigade init --target ./my-repo --harnesses codex --dry-run` shows the full file-by-file list. Pass more harnesses as a comma-separated list. Quickstart only wires the harnesses you select and leaves the rest alone.
|
|
79
|
+
|
|
80
|
+
Write a handoff and check the wiring:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
brigade handoff draft --target ./my-repo --inbox codex \
|
|
84
|
+
--title "What changed" \
|
|
85
|
+
--summary "Short note future agents should know." \
|
|
86
|
+
--content "The durable note itself goes here."
|
|
87
|
+
brigade handoff lint --target ./my-repo
|
|
88
|
+
brigade handoff doctor --target ./my-repo
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
New here? Start with [docs/first-10-minutes.md](docs/first-10-minutes.md). Already have a homegrown setup with scripts, crons, and handoff folders? Brigade has an adoption path that inventories what you have before changing anything: start with `brigade operator adopt plan` and see the [technical guide](docs/technical-guide.md). Want an agent to set this up for you? Point it at this repo; [AGENTS.md](AGENTS.md) tells it exactly what to do and where to stop.
|
|
92
|
+
|
|
93
|
+
## Harness support
|
|
94
|
+
|
|
95
|
+
Each writer gets its own local inbox; one canonical owner ingests. Brigade keeps the note format consistent so different tools can contribute without inventing their own styles.
|
|
96
|
+
|
|
97
|
+
| Writer | Harness id | Inbox |
|
|
98
|
+
|---|---|---|
|
|
99
|
+
| Codex CLI | `codex` | `.codex/memory-handoffs/` |
|
|
100
|
+
| Claude Code | `claude` | `.claude/memory-handoffs/` |
|
|
101
|
+
| OpenCode | `opencode` | `.opencode/memory-handoffs/` |
|
|
102
|
+
| Antigravity | `antigravity` | `.antigravity/memory-handoffs/` |
|
|
103
|
+
| Pi | `pi` | `.pi/memory-handoffs/` |
|
|
104
|
+
| Cursor | `cursor` | `.cursor/memory-handoffs/` |
|
|
105
|
+
| Aider | `aider` | `.aider/memory-handoffs/` |
|
|
106
|
+
| Goose | `goose` | `.goose/memory-handoffs/` |
|
|
107
|
+
| Continue | `continue` | `.continue/memory-handoffs/` |
|
|
108
|
+
| GitHub Copilot CLI | `copilot` | `.copilot/memory-handoffs/` |
|
|
109
|
+
| Qwen Code | `qwen` | `.qwen/memory-handoffs/` |
|
|
110
|
+
| Kimi Code | `kimi` | `.kimi/memory-handoffs/` |
|
|
111
|
+
| AdaL | `adal` | `.adal/memory-handoffs/` |
|
|
112
|
+
| OpenHands | `openhands` | `.openhands/memory-handoffs/` |
|
|
113
|
+
| Hermes | `hermes` | `.hermes/memory-handoffs/` |
|
|
114
|
+
| OpenClaw | `openclaw` | usually the memory owner, not a writer |
|
|
115
|
+
|
|
116
|
+
All of them get handoff templates, ingest source coverage, and projected tools/skills. Per-harness details are in the [technical guide](docs/technical-guide.md).
|
|
117
|
+
|
|
118
|
+
## Beyond memory
|
|
119
|
+
|
|
120
|
+
The memory loop is the core. Around it, the same review-and-receipt pattern covers the rest of an operator's day, and you can ignore all of it until you need it:
|
|
121
|
+
|
|
122
|
+
- **Daily loop**: `brigade work brief` shows pending work, imports, and warnings; `brigade daily status` keeps it bounded and cheap.
|
|
123
|
+
- **Security**: `brigade security scan` is a local read-only scanner for agent workspaces (secrets, risky hooks, MCP configs, prompt-injection patterns); `brigade scrub` gates content before it leaves the machine.
|
|
124
|
+
- **Tools and skills**: one reviewed catalog projected into every harness's native format, with approval gates for anything that executes.
|
|
125
|
+
- **Research**: `brigade research run` turns a question into a cited local report and a reviewable memory handoff.
|
|
126
|
+
- **Fleet and release**: health evidence across your local repos and release-readiness receipts, with no publish step.
|
|
127
|
+
|
|
128
|
+
The full tour of every station lives in [docs/overview.md](docs/overview.md).
|
|
129
|
+
|
|
130
|
+
## Why not something else?
|
|
131
|
+
|
|
132
|
+
- **mem0, Letta, and friends** are memory layers for apps you are building, usually behind an API or a server. Brigade is for the agent CLIs you already run, and it is file-first: your memory is markdown in your repo, reviewable in git, readable without Brigade.
|
|
133
|
+
- **Native harness memory** (each tool's own auto-memory) is a per-tool silo. It does not cross harnesses, and it writes without review. Brigade gives every tool one shared format and one canonical owner, with a review gate in between.
|
|
134
|
+
- **A plain CLAUDE.md / AGENTS.md** works great until it bloats past the context budget and goes stale. Brigade exists because mine hit 41KB. It keeps bootstrap files slim, moves detail into indexed cards, and flags staleness instead of trusting last month's facts forever.
|
|
135
|
+
- **A daemon or hosted service** would be simpler to demo and worse to trust. Brigade writes local files when you run a command, and that is all it does.
|
|
136
|
+
|
|
137
|
+
## What Brigade is not
|
|
138
|
+
|
|
139
|
+
Brigade is not a hosted memory service, a daemon, or an automatic release bot.
|
|
140
|
+
|
|
141
|
+
It does not:
|
|
142
|
+
|
|
143
|
+
- run in the background or install schedulers
|
|
144
|
+
- push to GitHub or publish packages
|
|
145
|
+
- send notifications by default
|
|
146
|
+
- save every note automatically
|
|
147
|
+
- turn memory ingest into a silent background process
|
|
148
|
+
- skip review for ambiguous, risky, or failed notes
|
|
149
|
+
|
|
150
|
+
That pause is the point. Agent memory should be useful, not noisy.
|
|
151
|
+
|
|
152
|
+
## Docs
|
|
153
|
+
|
|
154
|
+
- [First 10 minutes](docs/first-10-minutes.md): shortest path from install to healthy setup.
|
|
155
|
+
- [Overview](docs/overview.md): the full tour of every station and diagram.
|
|
156
|
+
- [Technical guide](docs/technical-guide.md): the detailed command walkthrough.
|
|
157
|
+
- [Security and Content Guard](docs/security.md): scanner policies, handoff guards, import flow.
|
|
158
|
+
- [Handoff promotion](docs/handoff-promotion.md): how notes move toward memory.
|
|
159
|
+
- [Repo fleet](docs/repo-fleet.md) and [Tool catalog](docs/tool-catalog.md).
|
|
160
|
+
- [Command inventory](docs/command-inventory.md): every public CLI command.
|
|
161
|
+
- [Roadmap](ROADMAP.md) and [roadmap archive](docs/roadmap-archive.md).
|
|
162
|
+
|
|
163
|
+
Project identity: GitHub [`escoffier-labs/brigade`](https://github.com/escoffier-labs/brigade), website [brigade.tools](https://brigade.tools), PyPI [`brigade-cli`](https://pypi.org/project/brigade-cli/), command `brigade`. The name comes from the kitchen: a *brigade de cuisine* runs the line, and *mise en place* means the station is prepped before service. Set up the rules, memory, tools, and receipts before the session gets expensive.
|
|
164
|
+
|
|
165
|
+
It is early-stage and moving fast. If you hit a broken workflow, a confusing command, or a setup issue, [open an issue](https://github.com/escoffier-labs/brigade/issues) and I will get it fixed.
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "brigade-cli"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.9.0"
|
|
8
8
|
description = "AI agent memory, handoffs, and local guardrails for Codex, Claude Code, OpenCode, Hermes, and OpenClaw."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -11,12 +11,62 @@ from .work_cmd import TASK_PRIORITIES, TASK_TYPES
|
|
|
11
11
|
from .prompt import prompt_for_selection # imported here so tests can monkeypatch cli.prompt_for_selection
|
|
12
12
|
|
|
13
13
|
|
|
14
|
+
# Top-level help groups. Every sub.add_parser command must appear in exactly
|
|
15
|
+
# one group; tests/test_cli_help.py enforces full coverage.
|
|
16
|
+
COMMAND_GROUPS: list[tuple[str, list[str]]] = [
|
|
17
|
+
("Core memory loop",
|
|
18
|
+
["init", "handoff", "handoff-template", "ingest", "memory", "doctor", "status"]),
|
|
19
|
+
("Daily operator loop",
|
|
20
|
+
["operator", "daily", "work", "center", "runbook", "budgets", "notifications"]),
|
|
21
|
+
("Stations and tools",
|
|
22
|
+
["add", "skills", "tools", "pantry", "roster", "run", "runs", "dogfood"]),
|
|
23
|
+
("Review, security, and research",
|
|
24
|
+
["security", "scrub", "untrusted", "research", "learn", "chat", "context", "projects"]),
|
|
25
|
+
("Wiring and advanced",
|
|
26
|
+
["release", "roadmap", "repos", "reconfigure", "openclaw-fragments", "hermes-fragments"]),
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
_START_HERE = """Brigade: run your agent brigade. Operator-system CLI for agent workspaces.
|
|
30
|
+
|
|
31
|
+
Start here:
|
|
32
|
+
brigade operator quickstart --target <repo> --harnesses codex set up a repo or workspace
|
|
33
|
+
brigade operator doctor --target <repo> check the wiring
|
|
34
|
+
brigade handoff draft --target <repo> ... record a durable note
|
|
35
|
+
brigade ingest --target <workspace> route handoffs into memory"""
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class _TopLevelHelpFormatter(argparse.RawDescriptionHelpFormatter):
|
|
39
|
+
"""Suppress argparse's flat subcommand dump on the top-level parser.
|
|
40
|
+
|
|
41
|
+
The grouped epilog lists every command instead. Subparsers do not inherit
|
|
42
|
+
this formatter, so `brigade <command> --help` keeps the normal listing.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
def _iter_indented_subactions(self, action):
|
|
46
|
+
if isinstance(action, argparse._SubParsersAction):
|
|
47
|
+
return iter(())
|
|
48
|
+
return super()._iter_indented_subactions(action)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _grouped_epilog(sub: argparse._SubParsersAction) -> str:
|
|
52
|
+
helps = {action.dest: (action.help or "") for action in sub._choices_actions}
|
|
53
|
+
lines = ["commands:"]
|
|
54
|
+
for title, names in COMMAND_GROUPS:
|
|
55
|
+
lines.append("")
|
|
56
|
+
lines.append(f"{title}:")
|
|
57
|
+
lines.extend(f" {name:<22}{helps.get(name, '')}" for name in names)
|
|
58
|
+
lines.append("")
|
|
59
|
+
lines.append("Run 'brigade <command> --help' for details on any command.")
|
|
60
|
+
return "\n".join(lines)
|
|
61
|
+
|
|
62
|
+
|
|
14
63
|
def _build_parser() -> argparse.ArgumentParser:
|
|
15
64
|
from . import learn_cmd, projects_cmd, release_cmd, repos_cmd
|
|
16
65
|
|
|
17
66
|
parser = argparse.ArgumentParser(
|
|
18
67
|
prog="brigade",
|
|
19
|
-
description=
|
|
68
|
+
description=_START_HERE,
|
|
69
|
+
formatter_class=_TopLevelHelpFormatter,
|
|
20
70
|
)
|
|
21
71
|
parser.add_argument(
|
|
22
72
|
"--version", action="version", version=f"brigade {__version__}"
|
|
@@ -1046,8 +1096,8 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
1046
1096
|
p_handoff_draft.add_argument("--action", choices=["create-card", "update-card", "no-card"], default="no-card", help="Recommended memory action.")
|
|
1047
1097
|
p_handoff_draft.add_argument("--target-card", default=None, help="Target card filename for card handoffs.")
|
|
1048
1098
|
p_handoff_draft.add_argument("--target-document", default=".learnings/LEARNINGS.md", help="Target document for no-card handoffs.")
|
|
1049
|
-
p_handoff_draft.add_argument("--content", default=None, help="Suggested card or document content.")
|
|
1050
|
-
p_handoff_draft.add_argument("--content-file", type=Path, default=None, help="Read suggested content from a file.")
|
|
1099
|
+
p_handoff_draft.add_argument("--content", default=None, help="Suggested card or document content. One of --content/--content-file is required.")
|
|
1100
|
+
p_handoff_draft.add_argument("--content-file", type=Path, default=None, help="Read suggested content from a file. One of --content/--content-file is required.")
|
|
1051
1101
|
p_handoff_draft.add_argument("--id", dest="draft_id", default=None, help="Stable id slug to use in the filename.")
|
|
1052
1102
|
p_handoff_draft.add_argument("--force", action="store_true", help="Overwrite an existing generated draft path.")
|
|
1053
1103
|
p_handoff_draft.add_argument("--guard", action="store_true", help="Scan the generated draft with content-guard before returning success.")
|
|
@@ -2817,6 +2867,7 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
2817
2867
|
p_recon.add_argument("--prune", action="store_true",
|
|
2818
2868
|
help="Remove files for harnesses no longer selected.")
|
|
2819
2869
|
|
|
2870
|
+
parser.epilog = _grouped_epilog(sub)
|
|
2820
2871
|
return parser
|
|
2821
2872
|
|
|
2822
2873
|
|
|
@@ -1437,6 +1437,8 @@ def draft(
|
|
|
1437
1437
|
print(f"content_guard_detail: {guard_result.get('detail')}")
|
|
1438
1438
|
for error in lint_result.errors:
|
|
1439
1439
|
print(f"error: {error}")
|
|
1440
|
+
if not lint_result.valid:
|
|
1441
|
+
print(f"note: invalid draft kept at {path}; repair or delete it, then rerun `brigade handoff lint`.")
|
|
1440
1442
|
return 0 if payload["valid"] else 1
|
|
1441
1443
|
|
|
1442
1444
|
|
|
@@ -247,7 +247,11 @@ def install_selection(
|
|
|
247
247
|
for d in dirs:
|
|
248
248
|
print(f" dir {target / d}")
|
|
249
249
|
for entry in files:
|
|
250
|
-
|
|
250
|
+
dst = target / entry["dst"]
|
|
251
|
+
if dst.exists():
|
|
252
|
+
print(f" file {dst} (exists; refused without --force)")
|
|
253
|
+
else:
|
|
254
|
+
print(f" file {dst}")
|
|
251
255
|
return 0
|
|
252
256
|
|
|
253
257
|
target.mkdir(parents=True, exist_ok=True)
|
|
@@ -2787,7 +2787,8 @@ def quickstart(
|
|
|
2787
2787
|
dry_run=dry_run,
|
|
2788
2788
|
allow_home=False,
|
|
2789
2789
|
)
|
|
2790
|
-
|
|
2790
|
+
install_status = "planned" if dry_run and install_rc == 0 else "ok" if install_rc == 0 else "error"
|
|
2791
|
+
steps.append({"id": "brigade-init", "status": install_status, "return_code": install_rc, "output": install_output})
|
|
2791
2792
|
if install_rc != 0:
|
|
2792
2793
|
payload = {
|
|
2793
2794
|
"target": str(target),
|
{brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/hermes/memory-handoff.harness.json
RENAMED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"Describes the handoff inbox + routing targets that Hermes should treat",
|
|
6
6
|
"as the canonical memory contract."
|
|
7
7
|
],
|
|
8
|
-
"_brigade_version": "0.
|
|
8
|
+
"_brigade_version": "0.9.0",
|
|
9
9
|
"_brigade_status": "experimental",
|
|
10
10
|
"memory_handoff": {
|
|
11
11
|
"inbox_dir": ".hermes/memory-handoffs",
|
{brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/hermes/model-lanes.harness.json
RENAMED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"Suggested model lane names. Same shape as the OpenClaw alias map so",
|
|
6
6
|
"knowledge cards and runbooks can talk about lanes without naming providers."
|
|
7
7
|
],
|
|
8
|
-
"_brigade_version": "0.
|
|
8
|
+
"_brigade_version": "0.9.0",
|
|
9
9
|
"_brigade_status": "experimental",
|
|
10
10
|
"model_lanes": {
|
|
11
11
|
"main": "<provider/main-model-id>",
|
{brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/memory/chat-memory-sweep.example.json
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"_brigade_version": "0.
|
|
2
|
+
"_brigade_version": "0.9.0",
|
|
3
3
|
"_description": "Example output contract for a nightly chat/session memory sweep. Keep raw chat transcripts in crawler archives; this file contains summaries and local source locators only.",
|
|
4
4
|
"generated_at": "2026-05-26T22:09:00-04:00",
|
|
5
5
|
"window": {
|
{brigade_cli-0.8.2 → brigade_cli-0.9.0}/src/brigade/templates/memory/memory-care.example.json
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"_brigade_version": "0.
|
|
2
|
+
"_brigade_version": "0.9.0",
|
|
3
3
|
"_description": "Example config for a local memory-care scanner. Brigade does not run this scanner for you; it validates the output with `brigade doctor`.",
|
|
4
4
|
"cards_glob": "memory/cards/*.md",
|
|
5
5
|
"decay_dir": "memory/cards/decay",
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"It blocks secrets and attribution trailers, while warning on personal or infrastructure-like context.",
|
|
5
5
|
"Use via: brigade handoff lint --content-guard --guard-policy personal"
|
|
6
6
|
],
|
|
7
|
-
"_brigade_version": "0.
|
|
7
|
+
"_brigade_version": "0.9.0",
|
|
8
8
|
"categories": {
|
|
9
9
|
"secret": "block",
|
|
10
10
|
"private-network": "warn",
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"Used by brigade pre-push hook and `brigade scrub`.",
|
|
5
5
|
"Override by pointing CONTENT_GUARD_POLICY at your own copy of this file."
|
|
6
6
|
],
|
|
7
|
-
"_brigade_version": "0.
|
|
7
|
+
"_brigade_version": "0.9.0",
|
|
8
8
|
"categories": {
|
|
9
9
|
"secret": "block",
|
|
10
10
|
"private-network": "block",
|
|
@@ -4094,7 +4094,7 @@ def init(*, target: Path, force: bool = False, update_gitignore: bool = True) ->
|
|
|
4094
4094
|
print(f"tools: {len(DEFAULT_TOOLS)}")
|
|
4095
4095
|
print(f"sources: {sum(1 for item in source_results if item['action'] == 'create')}")
|
|
4096
4096
|
if update_gitignore:
|
|
4097
|
-
result = apply_gitignore(target,
|
|
4097
|
+
result = apply_gitignore(target, _gitignore_selection(target))
|
|
4098
4098
|
print(f"gitignore: {result}")
|
|
4099
4099
|
else:
|
|
4100
4100
|
print("gitignore: skipped")
|
|
@@ -4143,6 +4143,21 @@ def _projection_scope(target: Path) -> set[str] | None:
|
|
|
4143
4143
|
return scope
|
|
4144
4144
|
|
|
4145
4145
|
|
|
4146
|
+
def _gitignore_selection(target: Path) -> Selection:
|
|
4147
|
+
"""Use the workspace's configured selection for gitignore rewrites.
|
|
4148
|
+
|
|
4149
|
+
Re-applying the managed gitignore block with a narrower selection than the
|
|
4150
|
+
install drops inbox entries for the other selected harnesses.
|
|
4151
|
+
"""
|
|
4152
|
+
try:
|
|
4153
|
+
config = load_brigade_config(target)
|
|
4154
|
+
except Exception:
|
|
4155
|
+
config = None
|
|
4156
|
+
if config is not None and config.selection.harnesses:
|
|
4157
|
+
return config.selection
|
|
4158
|
+
return Selection("repo", ["codex"], "codex")
|
|
4159
|
+
|
|
4160
|
+
|
|
4146
4161
|
def _scoped_default_tool(tool: dict[str, Any], scope: set[str] | None) -> dict[str, Any]:
|
|
4147
4162
|
entry = dict(tool)
|
|
4148
4163
|
if scope is None:
|
|
@@ -4222,7 +4237,7 @@ def defaults(*, target: Path, dry_run: bool = False, force: bool = False, update
|
|
|
4222
4237
|
source_results = _ensure_default_tool_sources(target, dry_run=dry_run or bool(conflicts))
|
|
4223
4238
|
gitignore_result = "skipped"
|
|
4224
4239
|
if update_gitignore and not dry_run and not conflicts:
|
|
4225
|
-
gitignore_result = apply_gitignore(target,
|
|
4240
|
+
gitignore_result = apply_gitignore(target, _gitignore_selection(target))
|
|
4226
4241
|
payload = {
|
|
4227
4242
|
"target": str(target),
|
|
4228
4243
|
"config_path": str(path),
|
|
@@ -5548,7 +5563,7 @@ def pack_import(*, target: Path, pack: Path, force: bool = False, json_output: b
|
|
|
5548
5563
|
imported.append({"tool_id": tool_id, "source_path": entry.get("source_path")})
|
|
5549
5564
|
config_path(target).parent.mkdir(parents=True, exist_ok=True)
|
|
5550
5565
|
config_path(target).write_text(_format_tool_entries(list(merged_by_id.values())))
|
|
5551
|
-
result = apply_gitignore(target,
|
|
5566
|
+
result = apply_gitignore(target, _gitignore_selection(target))
|
|
5552
5567
|
payload = {
|
|
5553
5568
|
"target": str(target),
|
|
5554
5569
|
"pack": str(pack),
|