brainiac-cli 0.20.45__tar.gz → 0.20.46__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.
- {brainiac_cli-0.20.45/src/brainiac_cli.egg-info → brainiac_cli-0.20.46}/PKG-INFO +7 -5
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/pyproject.toml +24 -4
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/_version.py +1 -1
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/audit_drift.py +2 -1
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/core/_maintenance_state.py +2 -1
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/exceptions_page.py +3 -2
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/exceptions_verify.py +3 -2
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/folds/intake.py +5 -5
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/graph_ops.py +3 -2
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/ingest/deliverables.py +2 -1
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/ingest/handlers/concealment_pdf.py +4 -1
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/ingest/pipeline_files.py +8 -3
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/interview.py +2 -1
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/invariant_coverage.py +2 -1
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/maintenance_notify.py +2 -1
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/overlay_generated.py +2 -1
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/provision.py +2 -2
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/remediation_exceptions_store.py +2 -1
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/remediation_state.py +2 -1
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/session_hook_settings.py +2 -1
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/update_channels.py +7 -7
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/vmstaging.py +22 -6
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/workspaces.py +2 -1
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46/src/brainiac_cli.egg-info}/PKG-INFO +7 -5
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brainiac_cli.egg-info/requires.txt +12 -2
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/LICENSE +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/MANIFEST.in +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/README.md +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/setup.cfg +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/__init__.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/__main__.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/_assets/AGENTS.md +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/_assets/assets/graph-explorer-template.html +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/_assets/overlay/template/brand/brand-guide.md +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/_assets/overlay/template/keywords/glossary.md +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/_assets/overlay/template/people/roster.md +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/_assets/overlay/template/voice/voice-profile.md +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/_assets/routines/manifest.json +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/_assets/scripts/brain-brief-mac.plist +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/_assets/scripts/brain-brief.sh +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/_assets/scripts/brain-synthesis-mac.plist +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/_assets/scripts/brain-synthesis.sh +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/_assets/scripts/brain_synthesis_codex.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/_assets/scripts/brainiac-alerts.sh +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/_assets/scripts/brainiac-egress-guard.sh +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/_assets/scripts/install-brief-mac.sh +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/_assets/scripts/install-brief-windows.ps1 +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/_assets/scripts/register_tasks.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/_assets/scripts/vm-boundary-probe.sh +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/_assets/scripts/vm-selftest.sh +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/_assets/templates/company.md +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/_assets/templates/concept.md +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/_assets/templates/daily.md +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/_assets/templates/decision.md +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/_assets/templates/deliverable.md +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/_assets/templates/meeting.md +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/_assets/templates/person.md +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/_assets/templates/project.md +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/_assets/templates/state-moc.md +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/_optional.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/alerts.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/alerts_render.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/alerts_staging.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/anchor.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/atomic_temp.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/attestation.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/audit.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/audit_chain.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/autolink.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/backup.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/brief.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/brief_render.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/capture.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/chunk.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/classification.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cli.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cli_cmds/__init__.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cli_cmds/common_parser.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cli_cmds/connect.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cli_cmds/connect_parser.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cli_cmds/eval.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cli_cmds/eval_parser.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cli_cmds/index_storage.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cli_cmds/index_storage_parser.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cli_cmds/ingest_storage.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cli_cmds/ingest_storage_parser.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cli_cmds/lifecycle.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cli_cmds/lifecycle_parser.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cli_cmds/maintenance.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cli_cmds/maintenance_parser.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cli_cmds/navigation.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cli_cmds/navigation_parser.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cli_cmds/owner_workflow.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cli_cmds/owner_workflow_parser.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cli_cmds/presentation.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cli_cmds/presentation_parser.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cli_cmds/retrieval.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cli_cmds/retrieval_parser.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cli_cmds/update.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cli_cmds/update_parser.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cli_cmds/versioning.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cli_cmds/versioning_parser.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cli_help.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cli_read_record.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cli_render.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/config.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/config_hostpaths.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/connect.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/context.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/conventions.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/conventions_scan.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/core/__init__.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/core/_audit.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/core/_briefing.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/core/_capture.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/core/_capture_staging.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/core/_durability.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/core/_health.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/core/_maintenance.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/core/_retrieval.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/core/_shared.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/core/_supersede_batch.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/core/_supersession.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/core/_supersession_journal.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cowork_leak_artifact.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cowork_leak_databases.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cowork_leak_notes.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cowork_leak_scan.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cowork_snapshot_guard.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/cowork_staging.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/dbretry.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/deliverables_absorb.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/deliverables_apply.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/deliverables_ledger.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/deliverables_materialize.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/deliverables_previous.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/deliverables_readme.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/deliverables_shelf.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/deliverables_sync.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/doctor.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/doctor_checks.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/doctor_context.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/doctor_desktop.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/doctor_health.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/doctor_mount_leak.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/doctor_plugins.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/doctor_staging.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/doctor_vendor.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/doctor_vm.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/doctor_wiring.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/draft_drain.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/draft_update.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/egress.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/egress_terms.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/embed.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/embed_backends.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/embed_catalog.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/embed_onnx.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/embed_qwen.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/encryption.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/exceptions_cli.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/exceptions_render.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/exceptions_tray.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/folds/__init__.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/folds/context.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/folds/daily.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/folds/deliverables.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/folds/golden.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/folds/graph.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/folds/invariants.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/folds/orchestrator.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/folds/organization.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/folds/preflight.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/folds/publish.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/folds/remediation.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/folds/remediation_bookkeeping.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/folds/reporting.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/folds/retention.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/folds/watchdogs.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/folds/weekly.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/frontmatter.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/golden_ops.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/golden_probe.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/golden_probe_cases.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/graph.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/graph_hygiene.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/graphify.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/graphify_edges.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/graphreport.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/graphreport_sections.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/graphreport_sections_2.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/guard_settings.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/healthreport.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/healthreport_sections.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/healthreport_unsigned.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/inbox.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/index/__init__.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/index/_connection.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/index/_families.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/index/_graph.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/index/_identity.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/index/_lifecycle.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/index/_models.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/index/_planning.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/index/_records.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/index/_retirement.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/index/_schema.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/index/_search.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/index/_settings.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/index/_shared.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/index/_tools.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/index/_zones.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/index_stages/__init__.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/index_stages/connection.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/index_stages/diagnostics.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/index_stages/duplicate_families.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/index_stages/near_duplicates.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/index_stages/rebuild.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/index_stages/reranking.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/index_stages/search.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/index_stages/search_finalization.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/index_stages/search_identity.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/index_stages/search_ranking.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/index_stages/sync.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/ingest/__init__.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/ingest/handlers/__init__.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/ingest/handlers/base.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/ingest/handlers/concealment.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/ingest/handlers/concealment_gate.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/ingest/handlers/concealment_html.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/ingest/handlers/concealment_ledger.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/ingest/handlers/concealment_office.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/ingest/handlers/docx.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/ingest/handlers/email.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/ingest/handlers/html.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/ingest/handlers/image.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/ingest/handlers/ole.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/ingest/handlers/pdf.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/ingest/handlers/pptx.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/ingest/handlers/tables.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/ingest/handlers/text.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/ingest/handlers/xlsx.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/ingest/handlers/zip.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/ingest/pipeline.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/ingest/pipeline_duplicates.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/ingest/pipeline_injection.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/ingest/pipeline_nested.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/ingest/pipeline_run.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/ingest/pipeline_stages.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/ingest/tierguard.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/ingest/tierguard_verdict.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/ingest/transcript.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/init.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/init_import.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/init_samples.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/init_seed.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/init_steps.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/injection_fold.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/injection_scan.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/interview_apply.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/interview_detect.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/invariant_crosstier.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/invariant_deliverables.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/invariant_floors.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/invariant_ingest_guard.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/invariant_lane_health.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/invariant_reachability.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/invariant_shared.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/invariant_unsigned_notes.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/invariants.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/invariants_metrics.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/language.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/link_targets.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/lock.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/maintenance.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/maintenance_escalation.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/maintenance_folds.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/maintenance_folds_2.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/maintenance_folds_3.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/maintenance_folds_4.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/maintenance_golden.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/maintenance_graphfolds.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/maintenance_healthlog.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/maintenance_hotmd.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/maintenance_invariant_fields.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/maintenance_outcomes.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/maintenance_para.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/maintenance_recommendations.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/maintenance_retention.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/maintenance_sweep.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/maintenance_watchdog.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/mcp_adapter.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/mcp_capture_verbs.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/mcp_housekeeping_verbs.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/mcp_mediation.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/mcp_supersede_verbs.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/mcp_tools/__init__.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/mcp_tools/capture.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/mcp_tools/core_read.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/mcp_tools/housekeeping.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/mcp_tools/retrieval.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/mcp_tools/supersession.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/mcp_verbs.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/model_slot.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/multihop.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/notes.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/originals_resolve.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/overlay.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/overlay_core.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/overlay_keywords.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/overlay_rules.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/pathkey.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/progress.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/projection.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/provenance.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/provision_mcp.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/provision_stage.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/provision_wire.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/querylog.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/querylog_digest.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/querylog_replay.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/querylog_status.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/read_log.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/reexec.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/remediation.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/remediation_answers.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/remediation_branches.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/remediation_converged.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/remediation_exceptions.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/remediation_extract_retry.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/remediation_folds.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/remediation_questions.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/remediation_routing.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/remediation_schema.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/rerank.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/rerank_onnx.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/retrieval_ops.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/retro.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/session_hook.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/session_hook_spec.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/snapshot.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/status_ops.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/supersede_declared.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/sweepdirs.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/update.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/update_channels_2.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/update_cos_guard.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/update_model.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/update_ops.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/update_plugins.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/update_state.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/update_venv.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/vectors.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/versionlink.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/versionlink_stages.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brain/vm_ceiling.py +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brainiac_cli.egg-info/SOURCES.txt +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brainiac_cli.egg-info/dependency_links.txt +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brainiac_cli.egg-info/entry_points.txt +0 -0
- {brainiac_cli-0.20.45 → brainiac_cli-0.20.46}/src/brainiac_cli.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: brainiac-cli
|
|
3
|
-
Version: 0.20.
|
|
3
|
+
Version: 0.20.46
|
|
4
4
|
Summary: Brainiac — local any-LLM second-brain core engine + brain CLI (Markdown truth, derived SQLite index).
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Project-URL: Homepage, https://github.com/Autopsias/brainiac
|
|
@@ -19,11 +19,12 @@ Requires-Dist: cryptography>=49
|
|
|
19
19
|
Requires-Dist: PyYAML>=6
|
|
20
20
|
Requires-Dist: regex>=2023.0.0
|
|
21
21
|
Requires-Dist: keyring>=24; sys_platform == "win32"
|
|
22
|
-
Requires-Dist: pypdf>=6.
|
|
22
|
+
Requires-Dist: pypdf>=6.21.2
|
|
23
23
|
Requires-Dist: python-docx>=1.1
|
|
24
24
|
Requires-Dist: python-pptx>=0.6.23
|
|
25
25
|
Requires-Dist: openpyxl>=3.1
|
|
26
|
-
Requires-Dist: Pillow>=
|
|
26
|
+
Requires-Dist: Pillow>=13.0.0; python_version >= "3.11"
|
|
27
|
+
Requires-Dist: Pillow>=12.3.0; python_version < "3.11"
|
|
27
28
|
Provides-Extra: vec
|
|
28
29
|
Requires-Dist: sqlite-vec>=0.1.6; extra == "vec"
|
|
29
30
|
Provides-Extra: audit
|
|
@@ -43,11 +44,12 @@ Requires-Dist: PyYAML>=6; extra == "corporate"
|
|
|
43
44
|
Provides-Extra: yaml
|
|
44
45
|
Requires-Dist: PyYAML>=6; extra == "yaml"
|
|
45
46
|
Provides-Extra: ingest
|
|
46
|
-
Requires-Dist: pypdf>=6.
|
|
47
|
+
Requires-Dist: pypdf>=6.21.2; extra == "ingest"
|
|
47
48
|
Requires-Dist: python-docx>=1.1; extra == "ingest"
|
|
48
49
|
Requires-Dist: python-pptx>=0.6.23; extra == "ingest"
|
|
49
50
|
Requires-Dist: openpyxl>=3.1; extra == "ingest"
|
|
50
|
-
Requires-Dist: Pillow>=
|
|
51
|
+
Requires-Dist: Pillow>=13.0.0; python_version >= "3.11" and extra == "ingest"
|
|
52
|
+
Requires-Dist: Pillow>=12.3.0; python_version < "3.11" and extra == "ingest"
|
|
51
53
|
Provides-Extra: dev
|
|
52
54
|
Requires-Dist: pytest>=7; extra == "dev"
|
|
53
55
|
Requires-Dist: build>=1; extra == "dev"
|
|
@@ -8,7 +8,7 @@ build-backend = "setuptools.build_meta"
|
|
|
8
8
|
# check. The IMPORT package stays `brain` and the console script stays
|
|
9
9
|
# `brain` — only the distribution/project name changes.
|
|
10
10
|
name = "brainiac-cli"
|
|
11
|
-
version = "0.20.
|
|
11
|
+
version = "0.20.46"
|
|
12
12
|
description = "Brainiac — local any-LLM second-brain core engine + brain CLI (Markdown truth, derived SQLite index)."
|
|
13
13
|
readme = "README.md"
|
|
14
14
|
license = "Apache-2.0"
|
|
@@ -42,7 +42,7 @@ dependencies = [
|
|
|
42
42
|
# because requirements.lock is CI/audit-only -- a plain
|
|
43
43
|
# `pip install brainiac-cli` reads THIS constraint, and >=4.0 let the
|
|
44
44
|
# vulnerable 6.14.2 survive an upgrade to 0.20.5 on a real host.
|
|
45
|
-
"pypdf>=6.
|
|
45
|
+
"pypdf>=6.21.2",
|
|
46
46
|
"python-docx>=1.1",
|
|
47
47
|
"python-pptx>=0.6.23",
|
|
48
48
|
"openpyxl>=3.1",
|
|
@@ -50,7 +50,10 @@ dependencies = [
|
|
|
50
50
|
# binary is present — the pytesseract binding itself stays a fully
|
|
51
51
|
# OPTIONAL, NOT-a-pip-dependency probe: OCR degrades gracefully absent
|
|
52
52
|
# it, matching the ADR's "system binaries are never pip deps" rule).
|
|
53
|
-
|
|
53
|
+
# >=13.0.0 fixes 37 advisories (one a FlashPix heap overflow); 13 needs
|
|
54
|
+
# Python 3.11+, and no fixed 12.x exists, so 3.10 keeps the old floor.
|
|
55
|
+
"Pillow>=13.0.0; python_version >= '3.11'",
|
|
56
|
+
"Pillow>=12.3.0; python_version < '3.11'",
|
|
54
57
|
]
|
|
55
58
|
|
|
56
59
|
[project.optional-dependencies]
|
|
@@ -94,7 +97,7 @@ yaml = ["PyYAML>=6"]
|
|
|
94
97
|
# message hints valid even though a default install already has these. Absent,
|
|
95
98
|
# `brain ingest` degrades per-handler (reports which extensions are
|
|
96
99
|
# unavailable) rather than crashing.
|
|
97
|
-
ingest = ["pypdf>=6.
|
|
100
|
+
ingest = ["pypdf>=6.21.2", "python-docx>=1.1", "python-pptx>=0.6.23", "openpyxl>=3.1", "Pillow>=13.0.0; python_version >= '3.11'", "Pillow>=12.3.0; python_version < '3.11'"]
|
|
98
101
|
# pytest-xdist/-timeout back the documented parallel suite run (AGENTS.md §8,
|
|
99
102
|
# "Running the test suite"): ~15 min sequential -> ~6 min at `-n 8`. Both are
|
|
100
103
|
# pytest-dev org, actively maintained. Declared here so a fresh checkout can
|
|
@@ -296,3 +299,20 @@ python-platform = "linux"
|
|
|
296
299
|
# `_assets` is the generated mirror of tools/ + scripts/ inside src/brain/.
|
|
297
300
|
include = ["src", "tools", "eval", "scripts", "packaging"]
|
|
298
301
|
exclude = ["**/_plans", "**/_archive", "**/_evidence", "**/_assets"]
|
|
302
|
+
|
|
303
|
+
[tool.uv]
|
|
304
|
+
# Wait 7 days before resolving a newly published version (a new release can be
|
|
305
|
+
# malicious or broken). shortcut: pypdf 6.21.2, filelock 4.2.4 and certifi
|
|
306
|
+
# 2026.10.23 are security fixes under 7 days old on 2026-10-24, so they are
|
|
307
|
+
# exempt; remove the exemptions after 2026-10-31.
|
|
308
|
+
exclude-newer = "7 days"
|
|
309
|
+
exclude-newer-package = { pypdf = false, filelock = false, certifi = false }
|
|
310
|
+
# fastembed (the optional `embed` extra, not installed by default) caps
|
|
311
|
+
# pillow<13 in every release up to 0.9.0, but pillow 13.0.0 is the first
|
|
312
|
+
# release fixing 37 advisories (one a FlashPix heap overflow). fastembed uses
|
|
313
|
+
# pillow only for IMAGE embeddings; this repo embeds text only.
|
|
314
|
+
# shortcut: drop this once a fastembed release allows pillow>=13.
|
|
315
|
+
override-dependencies = [
|
|
316
|
+
"pillow>=13.0.0; python_version >= '3.11'",
|
|
317
|
+
"pillow>=12.3.0; python_version < '3.11'",
|
|
318
|
+
]
|
|
@@ -6,6 +6,7 @@ import os
|
|
|
6
6
|
from datetime import date
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
from typing import TYPE_CHECKING
|
|
9
|
+
from .atomic_temp import atomic_temp_path
|
|
9
10
|
|
|
10
11
|
if TYPE_CHECKING: # annotation-only; a runtime import here would be a cycle
|
|
11
12
|
from .audit_chain import AuditChain
|
|
@@ -32,7 +33,7 @@ def _write_dispositions(path: Path, payload: dict) -> None:
|
|
|
32
33
|
turn every explained finding back into an unexplained one. `os.replace` is
|
|
33
34
|
atomic within a filesystem, so a reader sees the old file or the new one.
|
|
34
35
|
"""
|
|
35
|
-
tmp =
|
|
36
|
+
tmp = atomic_temp_path(path)
|
|
36
37
|
tmp.write_text(json.dumps(payload, indent=2), encoding="utf-8")
|
|
37
38
|
os.replace(tmp, path)
|
|
38
39
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""Maintenance state methods for BrainCore."""
|
|
2
2
|
from __future__ import annotations
|
|
3
|
+
from ..atomic_temp import atomic_temp_path
|
|
3
4
|
|
|
4
5
|
from ._shared import (
|
|
5
6
|
Any,
|
|
@@ -130,7 +131,7 @@ class _MaintenanceStateMixin:
|
|
|
130
131
|
|
|
131
132
|
path = config.maintain_state_path(self.vault)
|
|
132
133
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
133
|
-
tmp =
|
|
134
|
+
tmp = atomic_temp_path(path)
|
|
134
135
|
tmp.write_text(_json.dumps(state, indent=2, sort_keys=True), encoding="utf-8")
|
|
135
136
|
_os.replace(tmp, path)
|
|
136
137
|
def _note_graphify_build_outcome(
|
|
@@ -60,6 +60,7 @@ from . import maintenance as _maintenance
|
|
|
60
60
|
from . import maintenance_notify as _notify
|
|
61
61
|
from . import remediation as _rem
|
|
62
62
|
from . import remediation_exceptions as _rex
|
|
63
|
+
from .atomic_temp import atomic_temp_path
|
|
63
64
|
from .exceptions_render import render_page # re-exported: the page's one
|
|
64
65
|
# renderer, split out on 2026-08-22 when this file hit the 500-line bound.
|
|
65
66
|
|
|
@@ -287,7 +288,7 @@ def maybe_ping(vault: Path, keys: list[str], full_path: Path) -> str | None:
|
|
|
287
288
|
if not str(out or "").startswith("skipped"): # a SKIP defers, never spends
|
|
288
289
|
try:
|
|
289
290
|
state_path.parent.mkdir(parents=True, exist_ok=True)
|
|
290
|
-
tmp =
|
|
291
|
+
tmp = atomic_temp_path(state_path)
|
|
291
292
|
tmp.write_text(json.dumps({"hash": current_hash}), encoding="utf-8")
|
|
292
293
|
os.replace(tmp, state_path)
|
|
293
294
|
except OSError:
|
|
@@ -364,6 +365,6 @@ def generate(core: Any, today: datetime.date | None = None) -> dict[str, Any]:
|
|
|
364
365
|
|
|
365
366
|
|
|
366
367
|
def _atomic_write(path: Path, text: str) -> None:
|
|
367
|
-
tmp =
|
|
368
|
+
tmp = atomic_temp_path(path)
|
|
368
369
|
tmp.write_text(text, encoding="utf-8")
|
|
369
370
|
os.replace(tmp, path)
|
|
@@ -78,6 +78,7 @@ from pathlib import Path
|
|
|
78
78
|
from typing import Any
|
|
79
79
|
|
|
80
80
|
from . import config as _config
|
|
81
|
+
from .atomic_temp import atomic_temp_path
|
|
81
82
|
|
|
82
83
|
PINNED_FILENAME = "pinned-verify.json"
|
|
83
84
|
MOUNT_HTML_FILENAME = "exceptions.html"
|
|
@@ -372,7 +373,7 @@ def stage_pin(vault: Path, workspace: Path | None = None) -> dict[str, Any]:
|
|
|
372
373
|
data = {"vault_id": vid, "public_key_pem": pem}
|
|
373
374
|
path = staging_root(vault, workspace) / PINNED_FILENAME
|
|
374
375
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
375
|
-
tmp =
|
|
376
|
+
tmp = atomic_temp_path(path)
|
|
376
377
|
tmp.write_text(json.dumps(data, indent=1, sort_keys=True), encoding="utf-8")
|
|
377
378
|
os.replace(tmp, path)
|
|
378
379
|
return data
|
|
@@ -413,6 +414,6 @@ def publish_summary(vault: Path, workspace: Path | None = None) -> None:
|
|
|
413
414
|
if not src.exists():
|
|
414
415
|
continue
|
|
415
416
|
dest = dest_dir / filename
|
|
416
|
-
tmp =
|
|
417
|
+
tmp = atomic_temp_path(dest)
|
|
417
418
|
tmp.write_bytes(src.read_bytes())
|
|
418
419
|
os.replace(tmp, dest)
|
|
@@ -240,12 +240,12 @@ class IntakeFoldsMixin:
|
|
|
240
240
|
from .. import cos # noqa: PLC0415
|
|
241
241
|
|
|
242
242
|
ops = cos.run_ops_dir(self.vault)
|
|
243
|
-
ledgers = sorted(ops.glob(
|
|
243
|
+
ledgers = sorted(ops.glob(cos.LEDGER_GLOB),
|
|
244
244
|
key=self._ledger_order)
|
|
245
245
|
if not ledgers:
|
|
246
246
|
return
|
|
247
247
|
latest = ledgers[-1]
|
|
248
|
-
run_id =
|
|
248
|
+
run_id = cos.ledger_run_id(latest)
|
|
249
249
|
rows, seen = [], set()
|
|
250
250
|
for line in latest.read_text(encoding="utf-8").splitlines():
|
|
251
251
|
if not line.strip():
|
|
@@ -268,7 +268,7 @@ class IntakeFoldsMixin:
|
|
|
268
268
|
"""Sort key for `_cos_ingestion_ledger_<date>-run<N>.jsonl`: the date
|
|
269
269
|
as text, then the run number as an INT. A missing or unparseable run
|
|
270
270
|
number sorts first, which keeps a malformed name from winning."""
|
|
271
|
-
stem = path.stem[len("_cos_ingestion_ledger_"):]
|
|
271
|
+
stem = path.stem[len("_cos_ingestion_ledger_"):] # no COS import: this runs unguarded
|
|
272
272
|
date, _, tail = stem.partition("-run")
|
|
273
273
|
return (date, int(tail) if tail.isdigit() else -1)
|
|
274
274
|
|
|
@@ -355,12 +355,12 @@ class IntakeFoldsMixin:
|
|
|
355
355
|
from .. import cos # noqa: PLC0415
|
|
356
356
|
|
|
357
357
|
ops = cos.run_ops_dir(self.vault)
|
|
358
|
-
ledgers = sorted(ops.glob(
|
|
358
|
+
ledgers = sorted(ops.glob(cos.LEDGER_GLOB),
|
|
359
359
|
key=self._ledger_order)
|
|
360
360
|
if not ledgers:
|
|
361
361
|
return
|
|
362
362
|
latest = ledgers[-1]
|
|
363
|
-
run_id =
|
|
363
|
+
run_id = cos.ledger_run_id(latest)
|
|
364
364
|
stuck, seen = {}, set()
|
|
365
365
|
for line in latest.read_text(encoding="utf-8").splitlines():
|
|
366
366
|
if not line.strip():
|
|
@@ -14,6 +14,7 @@ from . import classification, config, egress
|
|
|
14
14
|
from . import graphify as graphify_model
|
|
15
15
|
from .graph import build_graph
|
|
16
16
|
from .progress import progress_note
|
|
17
|
+
from .atomic_temp import atomic_temp_path
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
@dataclass(frozen=True)
|
|
@@ -186,7 +187,7 @@ def _publish_graph_artifact(
|
|
|
186
187
|
day: dt.date,
|
|
187
188
|
) -> None:
|
|
188
189
|
"""Atomically publish validated graph and manifest files."""
|
|
189
|
-
temporary_graph =
|
|
190
|
+
temporary_graph = atomic_temp_path(paths.graph)
|
|
190
191
|
temporary_graph.write_text(
|
|
191
192
|
json.dumps(artifact, indent=2, sort_keys=True), encoding="utf-8"
|
|
192
193
|
)
|
|
@@ -197,7 +198,7 @@ def _publish_graph_artifact(
|
|
|
197
198
|
"built_at": day.isoformat(),
|
|
198
199
|
"notes": manifest,
|
|
199
200
|
}
|
|
200
|
-
temporary_manifest =
|
|
201
|
+
temporary_manifest = atomic_temp_path(paths.manifest)
|
|
201
202
|
temporary_manifest.write_text(
|
|
202
203
|
json.dumps(new_state, indent=2, sort_keys=True), encoding="utf-8"
|
|
203
204
|
)
|
|
@@ -49,6 +49,7 @@ from typing import TYPE_CHECKING, Any
|
|
|
49
49
|
|
|
50
50
|
from .. import classification as CLS
|
|
51
51
|
from .. import supersede_declared as SUP
|
|
52
|
+
from ..atomic_temp import atomic_temp_path
|
|
52
53
|
|
|
53
54
|
if TYPE_CHECKING: # the stage record; a runtime import here would be a cycle
|
|
54
55
|
from .pipeline_stages import ClaimRecord
|
|
@@ -423,7 +424,7 @@ def _store(vault: Any, pending: dict[str, dict[str, Any]]) -> None:
|
|
|
423
424
|
path = journal_path(vault)
|
|
424
425
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
425
426
|
config.secure_file_permissions(path.parent, 0o700)
|
|
426
|
-
tmp =
|
|
427
|
+
tmp = atomic_temp_path(path)
|
|
427
428
|
tmp.write_text(json.dumps(pending, indent=2, sort_keys=True), encoding="utf-8")
|
|
428
429
|
config.secure_file_permissions(tmp, 0o600)
|
|
429
430
|
tmp.replace(path)
|
|
@@ -62,7 +62,10 @@ def page_fonts(page: Any) -> dict[str, Any]:
|
|
|
62
62
|
"""
|
|
63
63
|
fonts: dict[str, Any] = {}
|
|
64
64
|
try:
|
|
65
|
-
|
|
65
|
+
try:
|
|
66
|
+
from pypdf.generic._font import Font # pypdf >= 6.21
|
|
67
|
+
except ImportError: # coverage-audit: older pypdf keeps Font here
|
|
68
|
+
from pypdf._font import Font
|
|
66
69
|
|
|
67
70
|
resources = page.get_inherited("/Resources", None)
|
|
68
71
|
table = resources.get("/Font") if resources else None
|
|
@@ -10,6 +10,7 @@ import shutil
|
|
|
10
10
|
import tempfile
|
|
11
11
|
from pathlib import Path
|
|
12
12
|
from typing import Any
|
|
13
|
+
from ..atomic_temp import atomic_temp_path
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
def manifest_path(vault: Path) -> Path:
|
|
@@ -32,7 +33,7 @@ def load_manifest(vault: Path) -> dict[str, str]:
|
|
|
32
33
|
def save_manifest(vault: Path, manifest: dict[str, str]) -> None:
|
|
33
34
|
path = manifest_path(vault)
|
|
34
35
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
35
|
-
tmp = path
|
|
36
|
+
tmp = atomic_temp_path(path)
|
|
36
37
|
tmp.write_text(json.dumps(manifest, indent=2, sort_keys=True), encoding="utf-8")
|
|
37
38
|
os.replace(tmp, path)
|
|
38
39
|
|
|
@@ -57,7 +58,7 @@ def load_failures(vault: Path) -> dict[str, int]:
|
|
|
57
58
|
def save_failures(vault: Path, failures: dict[str, int]) -> None:
|
|
58
59
|
path = failures_path(vault)
|
|
59
60
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
60
|
-
tmp = path
|
|
61
|
+
tmp = atomic_temp_path(path)
|
|
61
62
|
tmp.write_text(json.dumps(failures, indent=2, sort_keys=True), encoding="utf-8")
|
|
62
63
|
os.replace(tmp, path)
|
|
63
64
|
|
|
@@ -88,7 +89,11 @@ def read_nofollow(path: Path, *, max_bytes: int | None = None) -> bytes:
|
|
|
88
89
|
|
|
89
90
|
if path.is_symlink():
|
|
90
91
|
raise ReadRefused(f"{path.name} is a symlink — refused")
|
|
91
|
-
|
|
92
|
+
# O_NONBLOCK: a FIFO planted at the name would otherwise block the open
|
|
93
|
+
# until a writer arrives, before the S_ISREG check below can refuse it
|
|
94
|
+
# (same guard as ``cos._io``). It changes nothing for a regular file.
|
|
95
|
+
flags = (os.O_RDONLY | getattr(os, "O_NOFOLLOW", 0) | getattr(os, "O_BINARY", 0)
|
|
96
|
+
| getattr(os, "O_NONBLOCK", 0))
|
|
92
97
|
try:
|
|
93
98
|
fd = os.open(path, flags)
|
|
94
99
|
except OSError as exc:
|
|
@@ -27,6 +27,7 @@ import os
|
|
|
27
27
|
import re
|
|
28
28
|
from pathlib import Path
|
|
29
29
|
from typing import Any
|
|
30
|
+
from .atomic_temp import atomic_temp_path
|
|
30
31
|
|
|
31
32
|
SCHEMA = "brain-interview/1"
|
|
32
33
|
STATE_RELPATH = ".brain/interview/state.json"
|
|
@@ -103,7 +104,7 @@ def read_state(vault: Any) -> dict[str, Any]:
|
|
|
103
104
|
def write_state(vault: Any, state: dict[str, Any]) -> Path:
|
|
104
105
|
p = state_path(vault)
|
|
105
106
|
p.parent.mkdir(parents=True, exist_ok=True)
|
|
106
|
-
tmp = p
|
|
107
|
+
tmp = atomic_temp_path(p)
|
|
107
108
|
tmp.write_text(json.dumps(state, ensure_ascii=False, sort_keys=True,
|
|
108
109
|
indent=1) + "\n", encoding="utf-8")
|
|
109
110
|
os.chmod(tmp, 0o600)
|
|
@@ -9,6 +9,7 @@ from pathlib import Path
|
|
|
9
9
|
from typing import Any
|
|
10
10
|
|
|
11
11
|
from .invariant_shared import SAMPLE_CAP
|
|
12
|
+
from .atomic_temp import atomic_temp_path
|
|
12
13
|
|
|
13
14
|
# ---------------------------------------------------------------------------
|
|
14
15
|
# G12 — the exclusion set, defined ONCE here and imported by every consumer
|
|
@@ -437,7 +438,7 @@ def write_link_lane(conn: Any, vault: Path, *, limit: int | None = None) -> dict
|
|
|
437
438
|
except (OSError, ValueError):
|
|
438
439
|
previous = None
|
|
439
440
|
payload.update(lane_consumption(previous, all_ids, payload["generated"]))
|
|
440
|
-
tmp = out
|
|
441
|
+
tmp = atomic_temp_path(out)
|
|
441
442
|
tmp.write_text(json.dumps(payload, indent=1), encoding="utf-8")
|
|
442
443
|
tmp.replace(out)
|
|
443
444
|
return {"path": str(out), "written": len(payload["candidates"]),
|
|
@@ -13,6 +13,7 @@ import os
|
|
|
13
13
|
import platform
|
|
14
14
|
import subprocess
|
|
15
15
|
import hashlib
|
|
16
|
+
from .atomic_temp import atomic_temp_path
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
# ---------------------------------------------------------------------------
|
|
@@ -138,7 +139,7 @@ def record_current_findings(
|
|
|
138
139
|
}
|
|
139
140
|
try:
|
|
140
141
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
141
|
-
tmp =
|
|
142
|
+
tmp = atomic_temp_path(path)
|
|
142
143
|
tmp.write_text(json.dumps(payload, indent=1), encoding="utf-8")
|
|
143
144
|
os.replace(tmp, path)
|
|
144
145
|
except OSError:
|
|
@@ -64,6 +64,7 @@ from typing import Any, NamedTuple
|
|
|
64
64
|
|
|
65
65
|
from . import frontmatter
|
|
66
66
|
from . import overlay as ov
|
|
67
|
+
from .atomic_temp import atomic_temp_path
|
|
67
68
|
|
|
68
69
|
#: Sibling of ``keywords/`` — deliberately NOT inside it. See the module
|
|
69
70
|
#: docstring: ``keywords/`` drives ingest classification and this does not.
|
|
@@ -223,7 +224,7 @@ def _publish(path: Path, text: str) -> None:
|
|
|
223
224
|
``*.md`` glob in :func:`brain.overlay._ring_files` cannot pick a half-written
|
|
224
225
|
temp file up as a ring file of its own.
|
|
225
226
|
"""
|
|
226
|
-
tmp =
|
|
227
|
+
tmp = atomic_temp_path(path)
|
|
227
228
|
try:
|
|
228
229
|
tmp.write_text(text, encoding="utf-8")
|
|
229
230
|
os.replace(tmp, path)
|
|
@@ -47,7 +47,7 @@ from datetime import datetime, timezone
|
|
|
47
47
|
from pathlib import Path
|
|
48
48
|
from typing import Any, Callable, Optional
|
|
49
49
|
|
|
50
|
-
from . import workspaces
|
|
50
|
+
from . import atomic_temp, workspaces
|
|
51
51
|
# Wire 5 moved to `provision_mcp` (its own module: the Desktop config is a
|
|
52
52
|
# third-party file with a third party still writing to it). Re-exported here
|
|
53
53
|
# because this module is the one every caller already imports.
|
|
@@ -94,7 +94,7 @@ def write_request(vault: str | os.PathLike[str], *, role: str) -> dict[str, Any]
|
|
|
94
94
|
for zone in ("brain", "raw", "inbox"):
|
|
95
95
|
(vault_p / zone).mkdir(exist_ok=True)
|
|
96
96
|
payload = {"version": 1, "requested_at": _now_iso(), "role": role}
|
|
97
|
-
tmp =
|
|
97
|
+
tmp = atomic_temp.atomic_temp_path(marker)
|
|
98
98
|
tmp.write_text(json.dumps(payload, indent=2) + "\n", encoding="utf-8")
|
|
99
99
|
os.replace(tmp, marker)
|
|
100
100
|
return {"action": "provision-request", "status": "staged",
|
|
@@ -21,6 +21,7 @@ from typing import Any, Mapping
|
|
|
21
21
|
|
|
22
22
|
from . import remediation_state as _rs
|
|
23
23
|
from .remediation_answers import unlabelled_ids
|
|
24
|
+
from .atomic_temp import atomic_temp_path
|
|
24
25
|
|
|
25
26
|
#: BUMPED (llm-review, s06 HIGH finding). Behaviour changed under this same
|
|
26
27
|
#: string once already: an earlier build of THIS feature normalized a pair's
|
|
@@ -127,7 +128,7 @@ def _write_proposal(vault: str | os.PathLike[str], meta: Mapping[str, Any]) -> N
|
|
|
127
128
|
d = exceptions_dir(vault) / PENDING_DIRNAME
|
|
128
129
|
d.mkdir(parents=True, exist_ok=True)
|
|
129
130
|
path = d / f"{meta['id']}.json"
|
|
130
|
-
tmp =
|
|
131
|
+
tmp = atomic_temp_path(path)
|
|
131
132
|
tmp.write_text(json.dumps(dict(meta), indent=1, sort_keys=True), encoding="utf-8")
|
|
132
133
|
os.replace(tmp, path)
|
|
133
134
|
|
|
@@ -52,6 +52,7 @@ from pathlib import Path
|
|
|
52
52
|
from typing import Any, Mapping, MutableMapping
|
|
53
53
|
|
|
54
54
|
from . import maintenance_escalation as _escalation
|
|
55
|
+
from .atomic_temp import atomic_temp_path
|
|
55
56
|
|
|
56
57
|
#: The host-private root, under ``config.index_dir(vault)``.
|
|
57
58
|
DIRNAME = "remediation"
|
|
@@ -128,7 +129,7 @@ def write_state(vault: str | os.PathLike[str], state: Mapping[str, Any]) -> bool
|
|
|
128
129
|
d = remediation_dir(vault)
|
|
129
130
|
d.mkdir(parents=True, exist_ok=True)
|
|
130
131
|
path = d / STATE_FILENAME
|
|
131
|
-
tmp =
|
|
132
|
+
tmp = atomic_temp_path(path)
|
|
132
133
|
tmp.write_text(json.dumps(payload, indent=1, sort_keys=True), encoding="utf-8")
|
|
133
134
|
os.replace(tmp, path)
|
|
134
135
|
return True
|
|
@@ -19,10 +19,11 @@ from pathlib import Path
|
|
|
19
19
|
from typing import Any
|
|
20
20
|
|
|
21
21
|
from .session_hook_spec import HOOK_EVENT, HOOKS, HookSpec
|
|
22
|
+
from .atomic_temp import atomic_temp_path
|
|
22
23
|
|
|
23
24
|
|
|
24
25
|
def _write_json_atomic(path: Path, payload: Any) -> None:
|
|
25
|
-
tmp =
|
|
26
|
+
tmp = atomic_temp_path(path)
|
|
26
27
|
tmp.write_text(json.dumps(payload, indent=2) + "\n", encoding="utf-8")
|
|
27
28
|
os.replace(tmp, path)
|
|
28
29
|
|
|
@@ -4,11 +4,11 @@ from __future__ import annotations
|
|
|
4
4
|
import os
|
|
5
5
|
import shutil
|
|
6
6
|
import subprocess
|
|
7
|
-
import sys
|
|
8
7
|
from dataclasses import dataclass
|
|
9
8
|
from pathlib import Path
|
|
10
9
|
from typing import Any, Callable, Optional
|
|
11
10
|
from .cowork_snapshot_guard import snapshot_lands_on_the_mount
|
|
11
|
+
from .vmstaging import tools_on_path
|
|
12
12
|
from .doctor import (
|
|
13
13
|
CHANNEL_EDITABLE,
|
|
14
14
|
CHANNEL_PIP_USER,
|
|
@@ -233,11 +233,11 @@ def stage_engine_and_skills(
|
|
|
233
233
|
|
|
234
234
|
vendor_status: dict[str, str] = {}
|
|
235
235
|
try:
|
|
236
|
-
|
|
237
|
-
|
|
236
|
+
with tools_on_path(engine_src):
|
|
237
|
+
import vendor_semantic_deps as vendor_deps # type: ignore
|
|
238
238
|
|
|
239
|
-
|
|
240
|
-
|
|
239
|
+
vendor_deps.write_shim(brain_dir)
|
|
240
|
+
vendor_status = vendor_deps.stage_vendor(brain_dir)
|
|
241
241
|
except Exception as exc:
|
|
242
242
|
vendor_status = {"error": f"{type(exc).__name__}: {exc}"}
|
|
243
243
|
|
|
@@ -421,8 +421,8 @@ def restage_workspaces(
|
|
|
421
421
|
resolve_model_source: Callable[[], tuple[Path, str]],
|
|
422
422
|
) -> list[dict]:
|
|
423
423
|
"""Restage every registered Cowork workspace."""
|
|
424
|
-
|
|
425
|
-
|
|
424
|
+
with tools_on_path(engine_src):
|
|
425
|
+
import workspace_registry as workspace_registry_module # type: ignore
|
|
426
426
|
|
|
427
427
|
results: list[dict] = []
|
|
428
428
|
model_source: tuple[Path, str] | None = None
|
|
@@ -29,15 +29,32 @@ marker the host can read WITHOUT executing it, or it cannot be checked at all.
|
|
|
29
29
|
"""
|
|
30
30
|
from __future__ import annotations
|
|
31
31
|
|
|
32
|
+
import contextlib
|
|
32
33
|
import hashlib
|
|
33
34
|
import re
|
|
34
35
|
import shutil
|
|
36
|
+
import sys
|
|
35
37
|
from pathlib import Path
|
|
36
|
-
from typing import Any
|
|
38
|
+
from typing import Any, Iterator
|
|
37
39
|
|
|
38
40
|
ARCHES = ("x86_64", "aarch64")
|
|
39
41
|
|
|
40
42
|
|
|
43
|
+
@contextlib.contextmanager
|
|
44
|
+
def tools_on_path(engine_src: Path) -> Iterator[None]:
|
|
45
|
+
"""Put ``<engine_src>/tools`` on ``sys.path`` for the block, and ALWAYS take
|
|
46
|
+
it off again, so importing a tools module never leaves the path changed."""
|
|
47
|
+
entry = str(engine_src / "tools")
|
|
48
|
+
sys.path.insert(0, entry)
|
|
49
|
+
try:
|
|
50
|
+
yield
|
|
51
|
+
finally:
|
|
52
|
+
try:
|
|
53
|
+
sys.path.remove(entry)
|
|
54
|
+
except ValueError:
|
|
55
|
+
pass
|
|
56
|
+
|
|
57
|
+
|
|
41
58
|
def stage_vm_binaries(brain_dir: Path, dist: Path) -> dict:
|
|
42
59
|
"""Copy each frozen ELF, its ``.version`` marker, and rewrite SHA256SUMS.
|
|
43
60
|
|
|
@@ -94,12 +111,11 @@ def stage_vm_support_files(brain_dir: Path, engine_src: Path, packaged_script) -
|
|
|
94
111
|
"""
|
|
95
112
|
vendor_status: dict[str, str] = {}
|
|
96
113
|
try:
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
import vendor_semantic_deps as _vsd # type: ignore
|
|
114
|
+
with tools_on_path(engine_src):
|
|
115
|
+
import vendor_semantic_deps as _vsd # type: ignore
|
|
100
116
|
|
|
101
|
-
|
|
102
|
-
|
|
117
|
+
_vsd.write_shim(brain_dir) # vendored-deps-aware shim
|
|
118
|
+
vendor_status = _vsd.stage_vendor(brain_dir) # tokenizers + sqlite-vec per arch
|
|
103
119
|
except Exception as exc: # advisory — a networkless host degrades to lexical
|
|
104
120
|
vendor_status = {"error": f"{type(exc).__name__}: {exc}"}
|
|
105
121
|
|
|
@@ -49,6 +49,7 @@ from pathlib import Path
|
|
|
49
49
|
from typing import Iterator, Optional
|
|
50
50
|
|
|
51
51
|
from .pathkey import real_key
|
|
52
|
+
from .atomic_temp import atomic_temp_path
|
|
52
53
|
|
|
53
54
|
REGISTRY_VERSION = 1
|
|
54
55
|
|
|
@@ -126,7 +127,7 @@ def _load(path: Path) -> dict:
|
|
|
126
127
|
|
|
127
128
|
def _write_atomic(path: Path, data: dict) -> None:
|
|
128
129
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
129
|
-
tmp =
|
|
130
|
+
tmp = atomic_temp_path(path)
|
|
130
131
|
tmp.write_text(json.dumps(data, indent=2, sort_keys=False) + "\n", encoding="utf-8")
|
|
131
132
|
os.replace(tmp, path)
|
|
132
133
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: brainiac-cli
|
|
3
|
-
Version: 0.20.
|
|
3
|
+
Version: 0.20.46
|
|
4
4
|
Summary: Brainiac — local any-LLM second-brain core engine + brain CLI (Markdown truth, derived SQLite index).
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Project-URL: Homepage, https://github.com/Autopsias/brainiac
|
|
@@ -19,11 +19,12 @@ Requires-Dist: cryptography>=49
|
|
|
19
19
|
Requires-Dist: PyYAML>=6
|
|
20
20
|
Requires-Dist: regex>=2023.0.0
|
|
21
21
|
Requires-Dist: keyring>=24; sys_platform == "win32"
|
|
22
|
-
Requires-Dist: pypdf>=6.
|
|
22
|
+
Requires-Dist: pypdf>=6.21.2
|
|
23
23
|
Requires-Dist: python-docx>=1.1
|
|
24
24
|
Requires-Dist: python-pptx>=0.6.23
|
|
25
25
|
Requires-Dist: openpyxl>=3.1
|
|
26
|
-
Requires-Dist: Pillow>=
|
|
26
|
+
Requires-Dist: Pillow>=13.0.0; python_version >= "3.11"
|
|
27
|
+
Requires-Dist: Pillow>=12.3.0; python_version < "3.11"
|
|
27
28
|
Provides-Extra: vec
|
|
28
29
|
Requires-Dist: sqlite-vec>=0.1.6; extra == "vec"
|
|
29
30
|
Provides-Extra: audit
|
|
@@ -43,11 +44,12 @@ Requires-Dist: PyYAML>=6; extra == "corporate"
|
|
|
43
44
|
Provides-Extra: yaml
|
|
44
45
|
Requires-Dist: PyYAML>=6; extra == "yaml"
|
|
45
46
|
Provides-Extra: ingest
|
|
46
|
-
Requires-Dist: pypdf>=6.
|
|
47
|
+
Requires-Dist: pypdf>=6.21.2; extra == "ingest"
|
|
47
48
|
Requires-Dist: python-docx>=1.1; extra == "ingest"
|
|
48
49
|
Requires-Dist: python-pptx>=0.6.23; extra == "ingest"
|
|
49
50
|
Requires-Dist: openpyxl>=3.1; extra == "ingest"
|
|
50
|
-
Requires-Dist: Pillow>=
|
|
51
|
+
Requires-Dist: Pillow>=13.0.0; python_version >= "3.11" and extra == "ingest"
|
|
52
|
+
Requires-Dist: Pillow>=12.3.0; python_version < "3.11" and extra == "ingest"
|
|
51
53
|
Provides-Extra: dev
|
|
52
54
|
Requires-Dist: pytest>=7; extra == "dev"
|
|
53
55
|
Requires-Dist: build>=1; extra == "dev"
|
|
@@ -6,12 +6,17 @@ huggingface-hub>=0.20
|
|
|
6
6
|
cryptography>=49
|
|
7
7
|
PyYAML>=6
|
|
8
8
|
regex>=2023.0.0
|
|
9
|
-
pypdf>=6.
|
|
9
|
+
pypdf>=6.21.2
|
|
10
10
|
python-docx>=1.1
|
|
11
11
|
python-pptx>=0.6.23
|
|
12
12
|
openpyxl>=3.1
|
|
13
|
+
|
|
14
|
+
[:python_version < "3.11"]
|
|
13
15
|
Pillow>=12.3.0
|
|
14
16
|
|
|
17
|
+
[:python_version >= "3.11"]
|
|
18
|
+
Pillow>=13.0.0
|
|
19
|
+
|
|
15
20
|
[:sys_platform == "win32"]
|
|
16
21
|
keyring>=24
|
|
17
22
|
|
|
@@ -45,12 +50,17 @@ numpy>=1.24
|
|
|
45
50
|
regex>=2023.0.0
|
|
46
51
|
|
|
47
52
|
[ingest]
|
|
48
|
-
pypdf>=6.
|
|
53
|
+
pypdf>=6.21.2
|
|
49
54
|
python-docx>=1.1
|
|
50
55
|
python-pptx>=0.6.23
|
|
51
56
|
openpyxl>=3.1
|
|
57
|
+
|
|
58
|
+
[ingest:python_version < "3.11"]
|
|
52
59
|
Pillow>=12.3.0
|
|
53
60
|
|
|
61
|
+
[ingest:python_version >= "3.11"]
|
|
62
|
+
Pillow>=13.0.0
|
|
63
|
+
|
|
54
64
|
[mcp]
|
|
55
65
|
mcp<2,>=1.30.0
|
|
56
66
|
|
|
File without changes
|