blq-cli 0.11.2__tar.gz → 0.12.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.
Files changed (191) hide show
  1. {blq_cli-0.11.2 → blq_cli-0.12.0}/.gitignore +2 -1
  2. {blq_cli-0.11.2 → blq_cli-0.12.0}/CLAUDE.md +9 -9
  3. {blq_cli-0.11.2 → blq_cli-0.12.0}/PKG-INFO +1 -1
  4. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/plans/roadmap-to-1.0.md +2 -2
  5. {blq_cli-0.11.2 → blq_cli-0.12.0}/pyproject.toml +1 -1
  6. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/bird.py +7 -7
  7. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/bird_schema.sql +2 -2
  8. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/cli.py +6 -6
  9. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/commands/ci_cmd.py +3 -3
  10. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/commands/clean_cmd.py +4 -4
  11. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/commands/config_cmd.py +1 -1
  12. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/commands/core.py +66 -37
  13. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/commands/execution.py +4 -4
  14. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/commands/hooks_cmd.py +17 -17
  15. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/commands/hooks_gen.py +2 -2
  16. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/commands/init_cmd.py +28 -24
  17. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/commands/management.py +6 -6
  18. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/commands/migrate.py +2 -2
  19. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/commands/query_cmd.py +1 -1
  20. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/commands/registry.py +1 -1
  21. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/commands/serve_cmd.py +1 -1
  22. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/commands/sync_cmd.py +4 -4
  23. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/locks.py +1 -1
  24. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/query.py +14 -14
  25. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/schema.sql +3 -3
  26. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/serve.py +15 -10
  27. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/storage.py +22 -14
  28. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/templates/drone.yml.j2 +1 -1
  29. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/templates/git_hook.sh.j2 +1 -1
  30. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/templates/github_workflow.yml.j2 +1 -1
  31. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/templates/gitlab_ci.yml.j2 +1 -1
  32. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/templates/hook_script.sh.j2 +1 -1
  33. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/user_config.py +2 -2
  34. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/conftest.py +2 -2
  35. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_attempts_outcomes.py +31 -31
  36. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_auto_init.py +3 -3
  37. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_autoprune.py +10 -10
  38. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_bird.py +19 -19
  39. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_ci_generators.py +5 -5
  40. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_core.py +20 -20
  41. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_ext_integration.py +1 -1
  42. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_ext_types.py +3 -3
  43. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_hooks.py +4 -4
  44. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_hooks_gen.py +5 -5
  45. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_inspect.py +4 -4
  46. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_phase2_command_registry.py +4 -4
  47. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_query_api.py +2 -2
  48. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_query_filter.py +3 -3
  49. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_record_invocation.py +7 -7
  50. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_sandbox_ext.py +1 -1
  51. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_storage.py +2 -2
  52. {blq_cli-0.11.2 → blq_cli-0.12.0}/.claude/hooks/blq-suggest.sh +0 -0
  53. {blq_cli-0.11.2 → blq_cli-0.12.0}/.github/workflows/ci.yml +0 -0
  54. {blq_cli-0.11.2 → blq_cli-0.12.0}/.github/workflows/docs.yml +0 -0
  55. {blq_cli-0.11.2 → blq_cli-0.12.0}/.github/workflows/publish.yml +0 -0
  56. {blq_cli-0.11.2 → blq_cli-0.12.0}/.mcp.json +0 -0
  57. {blq_cli-0.11.2 → blq_cli-0.12.0}/.readthedocs.yml +0 -0
  58. {blq_cli-0.11.2 → blq_cli-0.12.0}/AGENT.md +0 -0
  59. {blq_cli-0.11.2 → blq_cli-0.12.0}/AGENTS.md +0 -0
  60. {blq_cli-0.11.2 → blq_cli-0.12.0}/CONTRIBUTING.md +0 -0
  61. {blq_cli-0.11.2 → blq_cli-0.12.0}/README.md +0 -0
  62. {blq_cli-0.11.2 → blq_cli-0.12.0}/SKILL.md +0 -0
  63. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/commands/capture.md +0 -0
  64. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/commands/ci.md +0 -0
  65. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/commands/completions.md +0 -0
  66. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/commands/errors.md +0 -0
  67. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/commands/exec.md +0 -0
  68. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/commands/filter.md +0 -0
  69. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/commands/index.md +0 -0
  70. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/commands/init.md +0 -0
  71. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/commands/maintenance.md +0 -0
  72. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/commands/query.md +0 -0
  73. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/commands/registry.md +0 -0
  74. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/commands/report.md +0 -0
  75. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/commands/run.md +0 -0
  76. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/commands/sql.md +0 -0
  77. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/commands/status.md +0 -0
  78. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/commands/sync.md +0 -0
  79. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/commands/watch.md +0 -0
  80. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/design/design-bird-migration.md +0 -0
  81. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/design/design-commands.md +0 -0
  82. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/design/design-config-command.md +0 -0
  83. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/design/design-extensions.md +0 -0
  84. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/design/design-git-integration.md +0 -0
  85. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/design/design-hooks-v2.md +0 -0
  86. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/design/design-live-inspection.md +0 -0
  87. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/design/design-parameterized-commands.md +0 -0
  88. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/design/design-run-args.md +0 -0
  89. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/design/design-sandbox-specs.md +0 -0
  90. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/design/design-sync.md +0 -0
  91. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/design/design-track-save.md +0 -0
  92. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/design/duck-hunt-v2-migration.md +0 -0
  93. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/design/duck-hunt-v3-migration.md +0 -0
  94. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/design/proposal-bird-v5.md +0 -0
  95. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/design/skill-inspect-enrichment.md +0 -0
  96. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/getting-started.md +0 -0
  97. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/index.md +0 -0
  98. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/integration.md +0 -0
  99. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/mcp.md +0 -0
  100. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/plans/explore-nsjail-python-wrapper.md +0 -0
  101. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/plans/explore-nsjail-spack-package.md +0 -0
  102. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/plans/patterns-integration-prompt.md +0 -0
  103. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/python-api.md +0 -0
  104. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/query-guide.md +0 -0
  105. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/requirements.txt +0 -0
  106. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/sandbox.md +0 -0
  107. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/schema.md +0 -0
  108. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/superpowers/plans/2026-03-22-extension-system.md +0 -0
  109. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/superpowers/plans/2026-03-28-bwrap-engine.md +0 -0
  110. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/superpowers/plans/2026-03-28-command-locks.md +0 -0
  111. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/superpowers/plans/2026-03-29-annotators-and-tighten.md +0 -0
  112. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/superpowers/plans/2026-03-29-service-layer-phase1.md +0 -0
  113. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/superpowers/plans/2026-03-29-strace-profiling.md +0 -0
  114. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/superpowers/specs/2026-03-22-extension-system-design.md +0 -0
  115. {blq_cli-0.11.2 → blq_cli-0.12.0}/docs/superpowers/specs/2026-03-29-unified-service-layer-design.md +0 -0
  116. {blq_cli-0.11.2 → blq_cli-0.12.0}/experiments/agent-build-test.md +0 -0
  117. {blq_cli-0.11.2 → blq_cli-0.12.0}/mkdocs.yml +0 -0
  118. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/__init__.py +0 -0
  119. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/__main__.py +0 -0
  120. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/commands/README.md +0 -0
  121. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/commands/__init__.py +0 -0
  122. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/commands/events.py +0 -0
  123. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/commands/management_cmd.py +0 -0
  124. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/commands/mcp_cmd.py +0 -0
  125. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/commands/record_cmd.py +0 -0
  126. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/commands/report_cmd.py +0 -0
  127. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/commands/sandbox_cmd.py +0 -0
  128. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/commands/watch_cmd.py +0 -0
  129. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/config_format.py +0 -0
  130. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/ext/__init__.py +0 -0
  131. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/ext/annotator.py +0 -0
  132. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/ext/discovery.py +0 -0
  133. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/ext/local_executor.py +0 -0
  134. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/ext/pipeline.py +0 -0
  135. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/git.py +0 -0
  136. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/github.py +0 -0
  137. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/output.py +0 -0
  138. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/services/__init__.py +0 -0
  139. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/services/execution.py +0 -0
  140. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/services/inspect.py +0 -0
  141. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/services/query.py +0 -0
  142. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq/services/refs.py +0 -0
  143. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq_sandbox/__init__.py +0 -0
  144. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq_sandbox/engines.py +0 -0
  145. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq_sandbox/profile.py +0 -0
  146. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq_sandbox/source_annotator.py +0 -0
  147. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq_sandbox/spec.py +0 -0
  148. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq_sandbox/strace_parser.py +0 -0
  149. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq_sandbox/tighten.py +0 -0
  150. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq_sandbox/violations.py +0 -0
  151. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq_sandbox_bwrap/__init__.py +0 -0
  152. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq_sandbox_bwrap/args.py +0 -0
  153. {blq_cli-0.11.2 → blq_cli-0.12.0}/src/blq_sandbox_systemd/__init__.py +0 -0
  154. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/__init__.py +0 -0
  155. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/sql/test_duck_hunt_v2_migration.sql +0 -0
  156. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_annotator.py +0 -0
  157. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_bwrap_args.py +0 -0
  158. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_bwrap_engine.py +0 -0
  159. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_ci.py +0 -0
  160. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_command_args.py +0 -0
  161. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_command_lock_field.py +0 -0
  162. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_execution_locks.py +0 -0
  163. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_exit_code_reason.py +0 -0
  164. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_ext_discovery.py +0 -0
  165. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_ext_local_executor.py +0 -0
  166. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_ext_pipeline.py +0 -0
  167. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_git.py +0 -0
  168. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_json_null_filter.py +0 -0
  169. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_locks.py +0 -0
  170. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_mcp_ci_tools.py +0 -0
  171. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_mcp_merge.py +0 -0
  172. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_mcp_server.py +0 -0
  173. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_phase1_structured_output.py +0 -0
  174. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_report.py +0 -0
  175. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_sandbox.py +0 -0
  176. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_sandbox_cmd.py +0 -0
  177. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_sandbox_events.py +0 -0
  178. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_sandbox_profile.py +0 -0
  179. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_sandbox_register.py +0 -0
  180. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_sandbox_systemd.py +0 -0
  181. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_sandbox_tighten.py +0 -0
  182. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_sandbox_violations.py +0 -0
  183. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_services_execution.py +0 -0
  184. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_services_inspect.py +0 -0
  185. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_services_query.py +0 -0
  186. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_services_refs.py +0 -0
  187. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_source_annotator.py +0 -0
  188. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_storage_prune.py +0 -0
  189. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_strace_parser.py +0 -0
  190. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_user_config.py +0 -0
  191. {blq_cli-0.11.2 → blq_cli-0.12.0}/tests/test_watch.py +0 -0
@@ -41,7 +41,8 @@ htmlcov/
41
41
  # mypy
42
42
  .mypy_cache/
43
43
 
44
- # lq data (local to each project)
44
+ # BIRD data (local to each project)
45
+ .bird/
45
46
  .lq/
46
47
 
47
48
  # Documentation
@@ -98,7 +98,7 @@ This is the initial scaffolding for `blq` (Build Log Query) - a CLI tool for cap
98
98
  - [ ] Consider integration with duckdb_mcp for ATTACH/DETACH workflow
99
99
 
100
100
  **BIRD Spec:**
101
- - [ ] Migrate from `.lq/` to `.bird/` directory (pending spec finalization)
101
+ - [x] Migrated from `.lq/` to `.bird/` directory (auto-migration from legacy)
102
102
  - [ ] Running process tracking (pending BIRD spec)
103
103
  - [ ] Migrate to updated BIRD spec (when ready)
104
104
 
@@ -111,13 +111,13 @@ This is the initial scaffolding for `blq` (Build Log Query) - a CLI tool for cap
111
111
  ```
112
112
  blq (Python CLI)
113
113
 
114
- ├── .lq/blq.duckdb - BIRD database with tables and macros
114
+ ├── .bird/blq.duckdb - BIRD database with tables and macros
115
115
  │ ├── sessions - Invoker sessions (shell, CLI, MCP)
116
116
  │ ├── invocations - Command executions with metadata
117
117
  │ ├── outputs - Captured stdout/stderr (content-addressed)
118
118
  │ └── events - Parsed diagnostics (errors, warnings)
119
119
 
120
- ├── .lq/blobs/ - Content-addressed blob storage
120
+ ├── .bird/blobs/ - Content-addressed blob storage
121
121
  │ └── content/ab/{hash}.bin
122
122
 
123
123
  ├── Uses duckdb Python API directly
@@ -171,7 +171,7 @@ All SQL macros use the `blq_` prefix:
171
171
 
172
172
  Direct DuckDB access:
173
173
  ```bash
174
- duckdb .lq/blq.duckdb "SELECT * FROM blq_status()"
174
+ duckdb .bird/blq.duckdb "SELECT * FROM blq_status()"
175
175
  ```
176
176
 
177
177
  ## Run Metadata
@@ -193,7 +193,7 @@ Each `blq run` captures comprehensive execution context:
193
193
 
194
194
  ### Environment Capture
195
195
 
196
- Configurable in `.lq/config.toml`:
196
+ Configurable in `.bird/config.toml`:
197
197
  ```toml
198
198
  capture_env = [
199
199
  "PATH",
@@ -221,7 +221,7 @@ SELECT ci['provider'], ci['run_id'] FROM blq_load_events() WHERE ci IS NOT NULL
221
221
 
222
222
  ## Project Identification
223
223
 
224
- Detected at `blq init` and stored in `.lq/config.toml`:
224
+ Detected at `blq init` and stored in `.bird/config.toml`:
225
225
 
226
226
  ```toml
227
227
  [project]
@@ -265,7 +265,7 @@ Runtime override: `blq run --no-capture <cmd>` or `blq run --capture <cmd>`
265
265
 
266
266
  1. **BIRD as default storage**: DuckDB tables for simpler queries, content-addressed blobs for outputs
267
267
  2. **Parquet mode available**: For multi-writer scenarios (legacy, use `--parquet` flag)
268
- 3. **Project-local storage**: `.lq/` directory in project root
268
+ 3. **Project-local storage**: `.bird/` directory in project root
269
269
  4. **blq.duckdb for everything**: Tables, views, and macros in single database file
270
270
  5. **Table-returning macros**: `blq_load_events()` evaluated at query time, not view creation
271
271
  6. **Backward-compatible views**: `blq_events_flat` provides v1-compatible schema
@@ -334,7 +334,7 @@ blq mcp serve -D exec,clean # Disable specific tools
334
334
  blq mcp serve -S -D custom_tool # Combine safe mode with additional tools
335
335
  ```
336
336
 
337
- Or via `.lq/config.toml`:
337
+ Or via `.bird/config.toml`:
338
338
  ```toml
339
339
  [mcp]
340
340
  disabled_tools = ["clean", "register_command", "unregister_command"]
@@ -441,7 +441,7 @@ ruff format src/blq/
441
441
 
442
442
  ### Config Options
443
443
 
444
- Key `.lq/config.toml` options:
444
+ Key `.bird/config.toml` options:
445
445
  ```toml
446
446
  [storage]
447
447
  keep_raw = true # Always keep raw output
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: blq-cli
3
- Version: 0.11.2
3
+ Version: 0.12.0
4
4
  Summary: Buidl Log Query - capture and query build/test logs with DuckDB
5
5
  Project-URL: Homepage, https://blq-cli.readthedocs.com/
6
6
  Project-URL: Repository, https://github.com/teaguesterling/blq-cli
@@ -52,11 +52,11 @@ Fetch and query logs from CI systems. This is the last major feature gap.
52
52
 
53
53
  **Why before 1.0:** Users expect to query CI logs the same way they query local logs. Without sync, blq is local-only, which limits its value for teams.
54
54
 
55
- ### 0.13.x — BIRD Spec Finalization
55
+ ### 0.12.x — BIRD Spec Finalization
56
56
 
57
57
  Settle the storage format before committing to API stability.
58
58
 
59
- - [ ] `.lq/` vs `.bird/` directory decision and migration (#35)
59
+ - [x] `.lq/` `.bird/` directory migration (#35) — auto-migration on first access
60
60
  - [ ] Finalize schema version, document storage guarantees (#36)
61
61
 
62
62
  **Why before 1.0:** Changing the storage directory or schema after 1.0 would be a breaking change. Lock it down now.
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "blq-cli"
7
- version = "0.11.2"
7
+ version = "0.12.0"
8
8
  description = "Buidl Log Query - capture and query build/test logs with DuckDB"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -314,7 +314,7 @@ class BirdStore:
314
314
  It handles sessions, invocations, outputs, and events tables.
315
315
 
316
316
  Example:
317
- store = BirdStore.open(".lq/")
317
+ store = BirdStore.open(".bird/")
318
318
 
319
319
  # Register session (once per CLI invocation)
320
320
  store.ensure_session("test", "blq-shell", "blq", "cli")
@@ -330,7 +330,7 @@ class BirdStore:
330
330
  """Initialize BirdStore.
331
331
 
332
332
  Args:
333
- lq_dir: Path to .lq directory
333
+ lq_dir: Path to .bird directory
334
334
  conn: Open DuckDB connection
335
335
  """
336
336
  self._lq_dir = lq_dir
@@ -355,7 +355,7 @@ class BirdStore:
355
355
  """Open or create a BirdStore.
356
356
 
357
357
  Args:
358
- lq_dir: Path to .lq directory
358
+ lq_dir: Path to .bird directory
359
359
 
360
360
  Returns:
361
361
  BirdStore instance
@@ -384,7 +384,7 @@ class BirdStore:
384
384
  writers (e.g., parallel command execution, hooks).
385
385
 
386
386
  Args:
387
- lq_dir: Path to .lq directory
387
+ lq_dir: Path to .bird directory
388
388
  max_retries: Maximum number of retry attempts
389
389
  initial_delay: Initial delay between retries in seconds
390
390
 
@@ -408,7 +408,7 @@ class BirdStore:
408
408
 
409
409
  Args:
410
410
  conn: DuckDB connection
411
- lq_dir: Path to .lq directory
411
+ lq_dir: Path to .bird directory
412
412
  force: If True, reload schema even if it exists (for reinit)
413
413
  """
414
414
  # Check if schema is already initialized (skip on force)
@@ -936,7 +936,7 @@ class BirdStore:
936
936
  attempt_id: The attempt UUID
937
937
 
938
938
  Returns:
939
- Path to live output directory (.lq/live/{attempt_id}/)
939
+ Path to live output directory (.bird/live/{attempt_id}/)
940
940
  """
941
941
  return self._lq_dir / "live" / attempt_id
942
942
 
@@ -1617,7 +1617,7 @@ def write_bird_invocation(
1617
1617
  Args:
1618
1618
  events: Parsed events from the command output
1619
1619
  run_meta: Run metadata dict (same format as write_run_parquet)
1620
- lq_dir: Path to .lq directory
1620
+ lq_dir: Path to .bird directory
1621
1621
  output: Optional raw output bytes to store
1622
1622
 
1623
1623
  Returns:
@@ -4,7 +4,7 @@
4
4
  -- All reads go through views, writes go directly to tables.
5
5
  --
6
6
  -- Directory structure:
7
- -- .lq/
7
+ -- .bird/
8
8
  -- ├── blq.duckdb # Database with tables and views
9
9
  -- ├── blobs/ # Content-addressed output storage
10
10
  -- │ └── content/
@@ -30,7 +30,7 @@ INSERT OR IGNORE INTO blq_metadata VALUES ('schema_version', '2.4.0');
30
30
  INSERT OR IGNORE INTO blq_metadata VALUES ('storage_mode', 'duckdb');
31
31
 
32
32
  -- Base path for blob storage (set at runtime)
33
- CREATE OR REPLACE MACRO blq_blob_root() AS '.lq/blobs/content';
33
+ CREATE OR REPLACE MACRO blq_blob_root() AS '.bird/blobs/content';
34
34
 
35
35
  -- ============================================================================
36
36
  -- CORE TABLES (BIRD Schema)
@@ -2,7 +2,7 @@
2
2
  blq CLI - Build Log Query command-line interface.
3
3
 
4
4
  Usage:
5
- blq init [--mcp] Initialize .lq directory
5
+ blq init [--mcp] Initialize .bird directory
6
6
  blq run <command> Run registered command (alias: r)
7
7
  blq exec <command> Execute ad-hoc command (alias: e)
8
8
  blq import <file> [--name NAME] Import existing log file
@@ -201,7 +201,7 @@ def main() -> None:
201
201
  "--lq-dir",
202
202
  metavar="PATH",
203
203
  dest="lq_dir",
204
- help="Use specific .lq directory (overrides discovery)",
204
+ help="Use specific .bird directory (overrides discovery)",
205
205
  )
206
206
  parser.add_argument(
207
207
  "-F",
@@ -214,7 +214,7 @@ def main() -> None:
214
214
  "--global",
215
215
  action="store_true",
216
216
  dest="global_",
217
- help="Query global store (~/.lq/projects/) instead of local .lq",
217
+ help="Query global store (~/.bird/projects/) instead of local .bird",
218
218
  )
219
219
  parser.add_argument(
220
220
  "-d",
@@ -226,7 +226,7 @@ def main() -> None:
226
226
  subparsers = parser.add_subparsers(dest="command", help="Command")
227
227
 
228
228
  # init
229
- p_init = subparsers.add_parser("init", help="Initialize .lq directory")
229
+ p_init = subparsers.add_parser("init", help="Initialize .bird directory")
230
230
  mcp_group = p_init.add_mutually_exclusive_group()
231
231
  mcp_group.add_argument(
232
232
  "--mcp", "-m", action="store_true", help="Create .mcp.json for MCP server discovery"
@@ -272,7 +272,7 @@ def main() -> None:
272
272
  action="store_true",
273
273
  dest="gitignore",
274
274
  default=True,
275
- help="Add .lq/ to .gitignore (default)",
275
+ help="Add .bird/ to .gitignore (default)",
276
276
  )
277
277
  gitignore_group.add_argument(
278
278
  "--no-gitignore",
@@ -919,7 +919,7 @@ def main() -> None:
919
919
  )
920
920
 
921
921
  # clean full - full reset
922
- p_clean_full = clean_subparsers.add_parser("full", help="Delete and recreate .lq directory")
922
+ p_clean_full = clean_subparsers.add_parser("full", help="Delete and recreate .bird directory")
923
923
  p_clean_full.add_argument(
924
924
  "--confirm", "-y", action="store_true", help="Confirm destructive operation"
925
925
  )
@@ -498,7 +498,7 @@ def _generate_simple_script(cmd: RegisteredCommand, shell: str = "bash") -> str:
498
498
  set -euo pipefail
499
499
 
500
500
  # Check if blq is available for log capture
501
- if command -v blq &> /dev/null && [ -d ".lq" ]; then
501
+ if command -v blq &> /dev/null && [ -d ".bird" ]; then
502
502
  # Use blq to capture and parse output
503
503
  if [ $# -gt 0 ]; then
504
504
  blq run {name} -- "$@"
@@ -645,7 +645,7 @@ done
645
645
  {required_block}
646
646
 
647
647
  # Check if blq is available for log capture
648
- if command -v blq &> /dev/null && [ -d ".lq" ]; then
648
+ if command -v blq &> /dev/null && [ -d ".bird" ]; then
649
649
  # Build blq run command with parameters
650
650
  BLQ_ARGS="{cmd.name}"
651
651
  """
@@ -709,7 +709,7 @@ def cmd_ci_generate(args: argparse.Namespace) -> None:
709
709
  """
710
710
  config = BlqConfig.find()
711
711
  if config is None:
712
- print("Error: .lq not initialized. Run 'blq init' first.", file=sys.stderr)
712
+ print("Error: .bird not initialized. Run 'blq init' first.", file=sys.stderr)
713
713
  sys.exit(1)
714
714
 
715
715
  commands = config.commands
@@ -28,7 +28,7 @@ def cmd_clean(args: argparse.Namespace) -> None:
28
28
  print(" prune Remove data older than N days", file=sys.stderr)
29
29
  print(" orphans Mark stale pending runs as orphaned", file=sys.stderr)
30
30
  print(" schema Recreate database schema", file=sys.stderr)
31
- print(" full Delete and recreate .lq directory", file=sys.stderr)
31
+ print(" full Delete and recreate .bird directory", file=sys.stderr)
32
32
  sys.exit(1)
33
33
 
34
34
  config = BlqConfig.ensure()
@@ -240,9 +240,9 @@ def _clean_schema(lq_dir: Path, confirm: bool) -> None:
240
240
 
241
241
 
242
242
  def _clean_full(lq_dir: Path, confirm: bool) -> None:
243
- """Delete and recreate .lq directory."""
243
+ """Delete and recreate .bird directory."""
244
244
  if not confirm:
245
- print("This will delete the entire .lq directory and reinitialize.", file=sys.stderr)
245
+ print("This will delete the entire .bird directory and reinitialize.", file=sys.stderr)
246
246
  print("ALL data including config and commands will be lost.", file=sys.stderr)
247
247
  print("", file=sys.stderr)
248
248
  print("Run with --confirm to proceed.", file=sys.stderr)
@@ -259,7 +259,7 @@ def _clean_full(lq_dir: Path, confirm: bool) -> None:
259
259
  )
260
260
 
261
261
  if result.returncode == 0:
262
- print("Fully reinitialized .lq directory.")
262
+ print("Fully reinitialized .bird directory.")
263
263
  else:
264
264
  print(f"Init failed: {result.stderr}", file=sys.stderr)
265
265
  sys.exit(1)
@@ -39,7 +39,7 @@ CONFIG_SCHEMA: dict[str, dict[str, Any]] = {
39
39
  "attr": "auto_gitignore",
40
40
  "section": "init",
41
41
  "key": "auto_gitignore",
42
- "description": "Add .lq/ to .gitignore",
42
+ "description": "Add .bird/ to .gitignore",
43
43
  },
44
44
  "init.default_storage": {
45
45
  "type": "str",
@@ -8,6 +8,7 @@ that are shared across multiple commands.
8
8
  from __future__ import annotations
9
9
 
10
10
  import json
11
+ import logging
11
12
  import os
12
13
  import re
13
14
  import shutil
@@ -33,11 +34,15 @@ from blq.git import GitInfo, capture_git_info # noqa: F401
33
34
  if TYPE_CHECKING:
34
35
  pass
35
36
 
37
+ logger = logging.getLogger("blq")
38
+
36
39
  # ============================================================================
37
40
  # Configuration
38
41
  # ============================================================================
39
42
 
40
- LQ_DIR = ".lq"
43
+ BIRD_DIR = ".bird"
44
+ LQ_DIR = BIRD_DIR # Backward-compatible alias
45
+ LEGACY_DIR = ".lq" # Old directory name for auto-migration
41
46
  LOGS_DIR = "logs"
42
47
  RAW_DIR = "raw"
43
48
  SCHEMA_FILE = "schema.sql"
@@ -45,9 +50,10 @@ DB_FILE = "blq.duckdb"
45
50
  # Re-export from config_format for compatibility
46
51
  # COMMANDS_FILE = "commands.toml"
47
52
  # CONFIG_FILE = "config.toml"
48
- GLOBAL_LQ_DIR = Path.home() / ".lq"
53
+ GLOBAL_BIRD_DIR = Path.home() / BIRD_DIR
54
+ GLOBAL_LQ_DIR = GLOBAL_BIRD_DIR # Backward-compatible alias
49
55
  PROJECTS_DIR = "projects"
50
- GLOBAL_PROJECTS_PATH = GLOBAL_LQ_DIR / PROJECTS_DIR
56
+ GLOBAL_PROJECTS_PATH = GLOBAL_BIRD_DIR / PROJECTS_DIR
51
57
 
52
58
  # ============================================================================
53
59
  # Result Types
@@ -548,7 +554,7 @@ class WatchConfig:
548
554
  "**/__pycache__/**",
549
555
  "**/*.pyc",
550
556
  "**/.git/**",
551
- ".lq/**",
557
+ ".bird/**",
552
558
  "**/*.egg-info/**",
553
559
  "**/node_modules/**",
554
560
  "**/.venv/**",
@@ -620,32 +626,32 @@ class BlqConfig:
620
626
  # Computed paths
621
627
  @property
622
628
  def logs_dir(self) -> Path:
623
- """Path to logs directory (.lq/logs)."""
629
+ """Path to logs directory (.bird/logs)."""
624
630
  return self.lq_dir / LOGS_DIR
625
631
 
626
632
  @property
627
633
  def raw_dir(self) -> Path:
628
- """Path to raw logs directory (.lq/raw)."""
634
+ """Path to raw logs directory (.bird/raw)."""
629
635
  return self.lq_dir / RAW_DIR
630
636
 
631
637
  @property
632
638
  def schema_path(self) -> Path:
633
- """Path to schema file (.lq/schema.sql)."""
639
+ """Path to schema file (.bird/schema.sql)."""
634
640
  return self.lq_dir / SCHEMA_FILE
635
641
 
636
642
  @property
637
643
  def db_path(self) -> Path:
638
- """Path to database file (.lq/blq.duckdb)."""
644
+ """Path to database file (.bird/blq.duckdb)."""
639
645
  return self.lq_dir / DB_FILE
640
646
 
641
647
  @property
642
648
  def config_path(self) -> Path:
643
- """Path to config file (.lq/config.toml)."""
649
+ """Path to config file (.bird/config.toml)."""
644
650
  return self.lq_dir / CONFIG_FILE
645
651
 
646
652
  @property
647
653
  def commands_path(self) -> Path:
648
- """Path to commands file (.lq/commands.toml)."""
654
+ """Path to commands file (.bird/commands.toml)."""
649
655
  return self.lq_dir / COMMANDS_FILE
650
656
 
651
657
  @property
@@ -705,7 +711,7 @@ class BlqConfig:
705
711
  "**/__pycache__/**",
706
712
  "**/*.pyc",
707
713
  "**/.git/**",
708
- ".lq/**",
714
+ ".bird/**",
709
715
  "**/*.egg-info/**",
710
716
  "**/node_modules/**",
711
717
  "**/.venv/**",
@@ -769,7 +775,7 @@ class BlqConfig:
769
775
  def storage_config(self) -> dict[str, Any]:
770
776
  """Get project-level [storage] config as a raw dict.
771
777
 
772
- This exposes .lq/config.toml's [storage] section for merging
778
+ This exposes .bird/config.toml's [storage] section for merging
773
779
  with user config during autoprune.
774
780
 
775
781
  Returns:
@@ -802,7 +808,10 @@ class BlqConfig:
802
808
 
803
809
  @classmethod
804
810
  def find(cls, start_dir: Path | None = None) -> BlqConfig | None:
805
- """Find .lq directory in start_dir or parents and load config.
811
+ """Find .bird directory in start_dir or parents and load config.
812
+
813
+ Searches for .bird/ first. If not found but .lq/ exists,
814
+ auto-migrates by renaming .lq/ to .bird/.
806
815
 
807
816
  Args:
808
817
  start_dir: Directory to start searching from (default: cwd)
@@ -815,21 +824,38 @@ class BlqConfig:
815
824
 
816
825
  # Search current directory and parents
817
826
  for p in [start_dir, *list(start_dir.parents)]:
818
- lq_path = p / LQ_DIR
819
- if lq_path.exists() and lq_path.is_dir():
820
- return cls.load(lq_path)
827
+ bird_path = p / BIRD_DIR
828
+ if bird_path.exists() and bird_path.is_dir():
829
+ return cls.load(bird_path)
830
+
831
+ # Auto-migrate from legacy .lq/ to .bird/
832
+ legacy_path = p / LEGACY_DIR
833
+ if legacy_path.exists() and legacy_path.is_dir():
834
+ try:
835
+ legacy_path.rename(bird_path)
836
+ logger.info(f"Migrated {legacy_path} → {bird_path}")
837
+ print(
838
+ f" Migrated {LEGACY_DIR}/ → {BIRD_DIR}/ "
839
+ f"(legacy directory renamed)",
840
+ file=sys.stderr,
841
+ )
842
+ return cls.load(bird_path)
843
+ except OSError as e:
844
+ logger.warning(f"Failed to migrate {legacy_path}: {e}")
845
+ # Fall back to loading from legacy path
846
+ return cls.load(legacy_path)
821
847
 
822
848
  return None
823
849
 
824
850
  @classmethod
825
851
  def load(cls, lq_dir: Path) -> BlqConfig:
826
- """Load configuration from an existing .lq directory.
852
+ """Load configuration from an existing .bird directory.
827
853
 
828
854
  Merges user-level defaults (from ~/.config/blq/config.toml) with
829
- project-level config (from .lq/config.toml).
855
+ project-level config (from .bird/config.toml).
830
856
 
831
857
  Args:
832
- lq_dir: Path to the .lq directory
858
+ lq_dir: Path to the .bird directory
833
859
 
834
860
  Returns:
835
861
  BlqConfig loaded from config.toml (or defaults)
@@ -891,25 +917,25 @@ class BlqConfig:
891
917
 
892
918
  Args:
893
919
  start_dir: Directory to start searching from (default: cwd)
894
- lq_dir: Explicit .lq directory to use (overrides discovery)
920
+ lq_dir: Explicit .bird directory to use (overrides discovery)
895
921
 
896
922
  Returns:
897
923
  BlqConfig if found
898
924
 
899
925
  Raises:
900
- SystemExit: If .lq directory not found
926
+ SystemExit: If .bird directory not found
901
927
  """
902
928
  # If explicit lq_dir is provided, use it directly
903
929
  if lq_dir is not None:
904
930
  lq_path = Path(lq_dir).expanduser()
905
931
  if not lq_path.exists():
906
- print(f"Error: .lq directory does not exist: {lq_path}", file=sys.stderr)
932
+ print(f"Error: .bird directory does not exist: {lq_path}", file=sys.stderr)
907
933
  sys.exit(1)
908
934
  return cls.load(lq_path)
909
935
 
910
936
  config = cls.find(start_dir)
911
937
  if config is None:
912
- print("Error: .lq not initialized. Run 'blq init' first.", file=sys.stderr)
938
+ print("Error: .bird not initialized. Run 'blq init' first.", file=sys.stderr)
913
939
  sys.exit(1)
914
940
  return config
915
941
 
@@ -1474,15 +1500,18 @@ def get_all_suppressed_fingerprints(config: BlqConfig) -> list[str]:
1474
1500
 
1475
1501
 
1476
1502
  def get_lq_dir() -> Path | None:
1477
- """Find .lq directory in current or parent directories.
1503
+ """Find .bird (or legacy .lq) directory in current or parent directories.
1478
1504
 
1479
- Returns None if no .lq directory is found.
1505
+ Returns None if no directory is found.
1480
1506
  """
1481
1507
  cwd = Path.cwd()
1482
1508
  for p in [cwd, *list(cwd.parents)]:
1483
- lq_path = p / LQ_DIR
1484
- if lq_path.exists():
1485
- return lq_path
1509
+ bird_path = p / BIRD_DIR
1510
+ if bird_path.exists():
1511
+ return bird_path
1512
+ legacy_path = p / LEGACY_DIR
1513
+ if legacy_path.exists():
1514
+ return legacy_path
1486
1515
  return None
1487
1516
 
1488
1517
 
@@ -1597,7 +1626,7 @@ class ConnectionFactory:
1597
1626
  """Create a properly initialized DuckDB connection.
1598
1627
 
1599
1628
  Args:
1600
- lq_dir: Path to .lq directory (for schema loading)
1629
+ lq_dir: Path to .bird directory (for schema loading)
1601
1630
  load_schema: Whether to load the schema (for stored data queries)
1602
1631
  require_duck_hunt: If True, raise error if duck_hunt unavailable
1603
1632
  install_duck_hunt: If True, attempt to install duck_hunt if missing
@@ -1705,7 +1734,7 @@ def get_connection(lq_dir: Path | None = None) -> duckdb.DuckDBPyConnection:
1705
1734
 
1706
1735
 
1707
1736
  def get_lq_dir_from_args(args) -> Path | None:
1708
- """Get the .lq directory path from parsed arguments.
1737
+ """Get the .bird directory path from parsed arguments.
1709
1738
 
1710
1739
  Handles the --lq-dir flag.
1711
1740
 
@@ -1713,7 +1742,7 @@ def get_lq_dir_from_args(args) -> Path | None:
1713
1742
  args: Parsed arguments with optional 'lq_dir' attribute
1714
1743
 
1715
1744
  Returns:
1716
- Path to .lq directory if --lq-dir was specified, None otherwise
1745
+ Path to .bird directory if --lq-dir was specified, None otherwise
1717
1746
  """
1718
1747
  lq_dir = getattr(args, "lq_dir", None)
1719
1748
  if lq_dir:
@@ -1729,14 +1758,14 @@ def get_data_root(args) -> tuple[Path | None, bool]:
1729
1758
 
1730
1759
  Returns:
1731
1760
  Tuple of (path, is_raw_parquet):
1732
- - path: Path to data root, or None for local .lq
1761
+ - path: Path to data root, or None for local .bird
1733
1762
  - is_raw_parquet: True if path is a raw parquet directory (no schema.sql)
1734
1763
  """
1735
1764
  # Check for --database flag first (explicit path)
1736
1765
  database = getattr(args, "database", None)
1737
1766
  if database:
1738
1767
  db_path = Path(database).expanduser()
1739
- # Raw parquet directory (no .lq structure)
1768
+ # Raw parquet directory (no .bird structure)
1740
1769
  return db_path, True
1741
1770
 
1742
1771
  # Check for --global flag
@@ -1744,7 +1773,7 @@ def get_data_root(args) -> tuple[Path | None, bool]:
1744
1773
  if use_global:
1745
1774
  return GLOBAL_PROJECTS_PATH, True
1746
1775
 
1747
- # Default: local .lq directory
1776
+ # Default: local .bird directory
1748
1777
  return None, False
1749
1778
 
1750
1779
 
@@ -1761,12 +1790,12 @@ def get_store_for_args(args):
1761
1790
  """
1762
1791
  from blq.storage import BlqStorage
1763
1792
 
1764
- # Check for --lq-dir flag first (explicit .lq directory)
1793
+ # Check for --lq-dir flag first (explicit .bird directory)
1765
1794
  lq_dir = getattr(args, "lq_dir", None)
1766
1795
  if lq_dir:
1767
1796
  lq_path = Path(lq_dir).expanduser()
1768
1797
  if not lq_path.exists():
1769
- print(f"Error: .lq directory does not exist: {lq_path}", file=sys.stderr)
1798
+ print(f"Error: .bird directory does not exist: {lq_path}", file=sys.stderr)
1770
1799
  sys.exit(1)
1771
1800
  return BlqStorage.open(lq_path)
1772
1801
 
@@ -1785,7 +1814,7 @@ def get_store_for_args(args):
1785
1814
  )
1786
1815
  return LogStore.from_parquet_root(data_root)
1787
1816
  else:
1788
- # Standard .lq directory - use BlqStorage
1817
+ # Standard .bird directory - use BlqStorage
1789
1818
  # Check for --lq-dir override
1790
1819
  lq_dir_override = getattr(args, "lq_dir", None)
1791
1820
  if lq_dir_override:
@@ -569,7 +569,7 @@ def _execute_with_live_output(
569
569
  store.cleanup_live_dir(attempt_id)
570
570
  # Connection closed
571
571
 
572
- # Save raw output to .lq/raw/ if requested (filesystem only, no DB)
572
+ # Save raw output to .bird/raw/ if requested (filesystem only, no DB)
573
573
  if keep_raw:
574
574
  raw_file = lq_dir / RAW_DIR / f"{run_id:03d}.log"
575
575
  raw_file.parent.mkdir(parents=True, exist_ok=True)
@@ -1350,7 +1350,7 @@ def cmd_run(args: argparse.Namespace) -> None:
1350
1350
  def _resolve_prune_config(config: BlqConfig, user_config) -> dict:
1351
1351
  """Merge user config with project-level storage overrides.
1352
1352
 
1353
- Project-level .lq/config.toml [storage] keys override user defaults.
1353
+ Project-level .bird/config.toml [storage] keys override user defaults.
1354
1354
 
1355
1355
  Returns:
1356
1356
  Dict with auto_prune, prune_days, max_runs, max_size_mb, prune_interval_minutes
@@ -1383,7 +1383,7 @@ def _should_prune(lq_dir: Path, interval_minutes: int) -> bool:
1383
1383
  """Check if enough time has passed since last auto-prune.
1384
1384
 
1385
1385
  Args:
1386
- lq_dir: Path to .lq directory
1386
+ lq_dir: Path to .bird directory
1387
1387
  interval_minutes: Minimum minutes between prunes
1388
1388
 
1389
1389
  Returns:
@@ -1403,7 +1403,7 @@ def _should_prune(lq_dir: Path, interval_minutes: int) -> bool:
1403
1403
 
1404
1404
 
1405
1405
  def _mark_pruned(lq_dir: Path) -> None:
1406
- """Write current timestamp to .lq/.last_prune."""
1406
+ """Write current timestamp to .bird/.last_prune."""
1407
1407
  stamp_file = lq_dir / ".last_prune"
1408
1408
  try:
1409
1409
  stamp_file.write_text(datetime.now().isoformat())