kanibako-cli 1.6.0.dev36__tar.gz → 1.7.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 (258) hide show
  1. {kanibako_cli-1.6.0.dev36/src/kanibako_cli.egg-info → kanibako_cli-1.7.0}/PKG-INFO +1 -1
  2. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/README.md +134 -50
  3. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/pyproject.toml +9 -1
  4. kanibako_cli-1.7.0/src/kanibako/__init__.py +25 -0
  5. kanibako_cli-1.7.0/src/kanibako/agent_config.py +146 -0
  6. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/agent_defaults.py +61 -4
  7. kanibako_cli-1.7.0/src/kanibako/agent_ref.py +185 -0
  8. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/agent_representation.py +86 -9
  9. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/box_identity.py +73 -49
  10. kanibako_cli-1.7.0/src/kanibako/box_lifecycle.py +285 -0
  11. kanibako_cli-1.7.0/src/kanibako/box_resolve.py +335 -0
  12. kanibako_cli-1.7.0/src/kanibako/box_supervisor.py +1172 -0
  13. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/channels.py +13 -13
  14. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/cli.py +81 -37
  15. kanibako_cli-1.7.0/src/kanibako/commands/agent_cmd.py +666 -0
  16. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/commands/archive.py +21 -10
  17. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/commands/box/__init__.py +7 -3
  18. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/commands/box/_duplicate.py +90 -29
  19. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/commands/box/_lifecycle.py +256 -99
  20. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/commands/box/_parser.py +532 -105
  21. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/commands/clean.py +30 -21
  22. kanibako_cli-1.7.0/src/kanibako/commands/code_cmd.py +725 -0
  23. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/commands/diagnose.py +258 -14
  24. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/commands/flags.py +4 -1
  25. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/commands/install.py +16 -15
  26. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/commands/setup_cmd.py +117 -2
  27. kanibako_cli-1.7.0/src/kanibako/commands/start.py +5292 -0
  28. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/commands/stop.py +31 -6
  29. kanibako_cli-1.7.0/src/kanibako/commands/system_cmd.py +428 -0
  30. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/commands/workset_cmd.py +235 -144
  31. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/config.py +289 -259
  32. kanibako_cli-1.7.0/src/kanibako/config_interface.py +2926 -0
  33. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/config_io.py +1 -1
  34. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/container.py +178 -15
  35. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/core_defaults.py +85 -4
  36. kanibako_cli-1.7.0/src/kanibako/creds_watcher.py +386 -0
  37. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/data/core-defaults.yaml +90 -3
  38. kanibako_cli-1.7.0/src/kanibako/data/global/rom/playbook/kanibako/directives/KANIBAKO.md +81 -0
  39. kanibako_cli-1.7.0/src/kanibako/data/global/rom/playbook/kanibako/scripts/clear.py +20 -0
  40. kanibako_cli-1.7.0/src/kanibako/data/global/rom/playbook/kanibako/scripts/import-directives.py +307 -0
  41. kanibako_cli-1.7.0/src/kanibako/data/global/rom/playbook/kanibako/scripts/start.py +50 -0
  42. kanibako_cli-1.7.0/src/kanibako/data/global/template/playbook/CONTENTS.md +11 -0
  43. kanibako_cli-1.7.0/src/kanibako/data/global/template/playbook/agents/directives/AGENTS.md +4 -0
  44. kanibako_cli-1.7.0/src/kanibako/data/global/template/playbook/box/directives/BOX.md +16 -0
  45. kanibako_cli-1.7.0/src/kanibako/data/global/template/playbook/general/directives/GENERAL.md +12 -0
  46. kanibako_cli-1.7.0/src/kanibako/data/global/template/playbook/general/directives/rules/INTERACTION.md +20 -0
  47. kanibako_cli-1.7.0/src/kanibako/data/global/template/playbook/general/directives/rules/WORKPOLICY.md +17 -0
  48. kanibako_cli-1.7.0/src/kanibako/data/global/template/playbook/workset/directives/WORKSET.md +4 -0
  49. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/helper_listener.py +36 -13
  50. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/helpers.py +2 -2
  51. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/hygiene.py +116 -0
  52. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/image_sharing.py +2 -1
  53. kanibako_cli-1.7.0/src/kanibako/import_reconcile.py +299 -0
  54. kanibako_cli-1.7.0/src/kanibako/journal.py +201 -0
  55. kanibako_cli-1.7.0/src/kanibako/kuid.py +118 -0
  56. kanibako_cli-1.7.0/src/kanibako/names.py +336 -0
  57. kanibako_cli-1.7.0/src/kanibako/paths.py +2676 -0
  58. kanibako_cli-1.7.0/src/kanibako/registry_store.py +194 -0
  59. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/rig_registry.py +9 -7
  60. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/scripts/kanibako-entry +4 -0
  61. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/settings_assemble.py +164 -31
  62. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/settings_categories.py +113 -257
  63. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/settings_configset.py +149 -125
  64. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/settings_expand.py +124 -10
  65. kanibako_cli-1.7.0/src/kanibako/settings_launch.py +1706 -0
  66. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/settings_merge.py +39 -105
  67. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/settings_resolve.py +28 -2
  68. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/settings_store.py +13 -0
  69. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/settings_views.py +106 -6
  70. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/shells.py +6 -4
  71. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/targets/__init__.py +4 -4
  72. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/targets/assembly.py +41 -11
  73. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/targets/base.py +54 -5
  74. kanibako_cli-1.7.0/src/kanibako/targets/credsync.py +452 -0
  75. kanibako_cli-1.7.0/src/kanibako/templates.py +443 -0
  76. kanibako_cli-1.7.0/src/kanibako/vscode_config.py +971 -0
  77. kanibako_cli-1.7.0/src/kanibako/vscode_remote.py +705 -0
  78. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/workset.py +263 -212
  79. kanibako_cli-1.7.0/src/kanibako/workset_registry.py +201 -0
  80. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0/src/kanibako_cli.egg-info}/PKG-INFO +1 -1
  81. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako_cli.egg-info/SOURCES.txt +42 -4
  82. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_agent_config.py +63 -0
  83. kanibako_cli-1.7.0/tests/test_agent_ref.py +242 -0
  84. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_agent_representation.py +172 -0
  85. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_agent_resolution.py +114 -17
  86. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_box_identity.py +87 -56
  87. kanibako_cli-1.7.0/tests/test_box_lifecycle.py +304 -0
  88. kanibako_cli-1.7.0/tests/test_box_resolve.py +344 -0
  89. kanibako_cli-1.7.0/tests/test_box_supervisor.py +1372 -0
  90. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_channels.py +44 -2
  91. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_cli.py +495 -49
  92. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_cli_exitcodes.py +37 -15
  93. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_comms.py +15 -17
  94. kanibako_cli-1.7.0/tests/test_config.py +906 -0
  95. kanibako_cli-1.7.0/tests/test_config_interface.py +3644 -0
  96. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_container.py +248 -0
  97. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_container_extended.py +7 -1
  98. kanibako_cli-1.7.0/tests/test_create_recovery.py +649 -0
  99. kanibako_cli-1.7.0/tests/test_creds_watcher.py +281 -0
  100. kanibako_cli-1.7.0/tests/test_delivery_manifest.py +327 -0
  101. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_env_cmd.py +6 -6
  102. kanibako_cli-1.7.0/tests/test_explicit_create.py +204 -0
  103. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_fork.py +14 -10
  104. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_helper_cmd.py +1 -1
  105. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_helper_listener.py +18 -8
  106. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_hygiene.py +152 -0
  107. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_image_sharing.py +3 -3
  108. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_import.py +91 -109
  109. kanibako_cli-1.7.0/tests/test_import_directives.py +205 -0
  110. kanibako_cli-1.7.0/tests/test_import_recovery.py +604 -0
  111. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_init_cmd.py +194 -57
  112. kanibako_cli-1.7.0/tests/test_instructions_bind.py +183 -0
  113. kanibako_cli-1.7.0/tests/test_journal.py +212 -0
  114. kanibako_cli-1.7.0/tests/test_kuid.py +208 -0
  115. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_lifecycle_integration.py +11 -3
  116. kanibako_cli-1.7.0/tests/test_meta_pin.py +84 -0
  117. kanibako_cli-1.7.0/tests/test_names.py +793 -0
  118. kanibako_cli-1.7.0/tests/test_paths.py +1881 -0
  119. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_paths_extended.py +8 -1
  120. kanibako_cli-1.7.0/tests/test_persona_config_set.py +400 -0
  121. kanibako_cli-1.7.0/tests/test_playbook_delivery.py +126 -0
  122. kanibako_cli-1.7.0/tests/test_registry_store.py +294 -0
  123. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_resolve_box_target.py +73 -19
  124. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_resource_scoping.py +173 -57
  125. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_rig_registry.py +1 -1
  126. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_safety_invariants.py +20 -14
  127. kanibako_cli-1.7.0/tests/test_settings_assemble.py +846 -0
  128. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_settings_categories.py +320 -52
  129. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_settings_configset.py +274 -58
  130. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_settings_expand.py +167 -0
  131. kanibako_cli-1.7.0/tests/test_settings_launch.py +1694 -0
  132. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_settings_launch_equivalence.py +142 -72
  133. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_settings_merge.py +50 -102
  134. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_settings_views.py +1 -4
  135. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_setup_cmd.py +127 -0
  136. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_shells.py +7 -1
  137. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_standalone_paths.py +201 -6
  138. kanibako_cli-1.7.0/tests/test_system_paths.py +689 -0
  139. kanibako_cli-1.7.0/tests/test_templates.py +612 -0
  140. kanibako_cli-1.7.0/tests/test_vscode_remote.py +440 -0
  141. kanibako_cli-1.7.0/tests/test_vscode_remote_dispatch.py +205 -0
  142. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_workset.py +224 -140
  143. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_workset_paths.py +0 -79
  144. kanibako_cli-1.7.0/tests/test_workset_registry.py +280 -0
  145. kanibako_cli-1.6.0.dev36/src/kanibako/__init__.py +0 -11
  146. kanibako_cli-1.6.0.dev36/src/kanibako/agent_config.py +0 -101
  147. kanibako_cli-1.6.0.dev36/src/kanibako/box_seed.py +0 -84
  148. kanibako_cli-1.6.0.dev36/src/kanibako/commands/agent_cmd.py +0 -481
  149. kanibako_cli-1.6.0.dev36/src/kanibako/commands/start.py +0 -2830
  150. kanibako_cli-1.6.0.dev36/src/kanibako/commands/system_cmd.py +0 -248
  151. kanibako_cli-1.6.0.dev36/src/kanibako/config_interface.py +0 -1033
  152. kanibako_cli-1.6.0.dev36/src/kanibako/data/templates/base/INSTRUCTIONS.md +0 -67
  153. kanibako_cli-1.6.0.dev36/src/kanibako/import_reconcile.py +0 -312
  154. kanibako_cli-1.6.0.dev36/src/kanibako/names.py +0 -250
  155. kanibako_cli-1.6.0.dev36/src/kanibako/paths.py +0 -1889
  156. kanibako_cli-1.6.0.dev36/src/kanibako/registry_store.py +0 -285
  157. kanibako_cli-1.6.0.dev36/src/kanibako/settings_launch.py +0 -734
  158. kanibako_cli-1.6.0.dev36/src/kanibako/targets/credsync.py +0 -208
  159. kanibako_cli-1.6.0.dev36/src/kanibako/templates.py +0 -222
  160. kanibako_cli-1.6.0.dev36/tests/test_box_seed.py +0 -137
  161. kanibako_cli-1.6.0.dev36/tests/test_config.py +0 -912
  162. kanibako_cli-1.6.0.dev36/tests/test_config_interface.py +0 -1009
  163. kanibako_cli-1.6.0.dev36/tests/test_names.py +0 -652
  164. kanibako_cli-1.6.0.dev36/tests/test_paths.py +0 -1084
  165. kanibako_cli-1.6.0.dev36/tests/test_registry_store.py +0 -238
  166. kanibako_cli-1.6.0.dev36/tests/test_settings_assemble.py +0 -511
  167. kanibako_cli-1.6.0.dev36/tests/test_settings_launch.py +0 -354
  168. kanibako_cli-1.6.0.dev36/tests/test_system_paths.py +0 -492
  169. kanibako_cli-1.6.0.dev36/tests/test_templates.py +0 -327
  170. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/LICENSE.md +0 -0
  171. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/setup.cfg +0 -0
  172. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/__main__.py +0 -0
  173. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/_atomic.py +0 -0
  174. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/auth_browser.py +0 -0
  175. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/auth_parser.py +0 -0
  176. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/baseline.py +0 -0
  177. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/browser_sidecar.py +0 -0
  178. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/browser_state.py +0 -0
  179. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/bun_sea.py +0 -0
  180. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/commands/__init__.py +0 -0
  181. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/commands/baseline_cmd.py +0 -0
  182. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/commands/fork_cmd.py +0 -0
  183. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/commands/helper_cmd.py +0 -0
  184. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/commands/image.py +0 -0
  185. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/commands/restore.py +0 -0
  186. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/commands/upgrade.py +0 -0
  187. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/commands/vault_cmd.py +0 -0
  188. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/containerfiles.py +0 -0
  189. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/containers/Containerfile.template-android +0 -0
  190. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/containers/Containerfile.template-dotnet +0 -0
  191. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/containers/Containerfile.template-js +0 -0
  192. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/containers/Containerfile.template-jvm +0 -0
  193. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/containers/Containerfile.template-systems +0 -0
  194. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/containers/__init__.py +0 -0
  195. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/containers/tmux.conf +0 -0
  196. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/data/__init__.py +0 -0
  197. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/data/image-baseline.yaml +0 -0
  198. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/deprecation.py +0 -0
  199. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/errors.py +0 -0
  200. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/freshness.py +0 -0
  201. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/git.py +0 -0
  202. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/helper_client.py +0 -0
  203. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/install_method.py +0 -0
  204. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/log.py +0 -0
  205. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/plugins/__init__.py +0 -0
  206. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/py.typed +0 -0
  207. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/registry.py +0 -0
  208. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/rig_bundle.py +0 -0
  209. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/rig_meta.py +0 -0
  210. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/rig_resolve.py +0 -0
  211. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/rig_source.py +0 -0
  212. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/scripts/__init__.py +0 -0
  213. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/scripts/helper-init.sh +0 -0
  214. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/shellenv.py +0 -0
  215. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/snapshots.py +0 -0
  216. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/targets/no_agent.py +0 -0
  217. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/templates_image.py +0 -0
  218. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/tweakcc.py +0 -0
  219. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/tweakcc_cache.py +0 -0
  220. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako/utils.py +0 -0
  221. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako_cli.egg-info/dependency_links.txt +0 -0
  222. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako_cli.egg-info/entry_points.txt +0 -0
  223. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako_cli.egg-info/requires.txt +0 -0
  224. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/src/kanibako_cli.egg-info/top_level.txt +0 -0
  225. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_archive_restore_integration.py +0 -0
  226. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_atomic.py +0 -0
  227. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_auth_browser.py +0 -0
  228. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_auth_parser.py +0 -0
  229. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_baseline.py +0 -0
  230. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_browser_sidecar.py +0 -0
  231. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_browser_state.py +0 -0
  232. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_bun_sea.py +0 -0
  233. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_container_integration.py +0 -0
  234. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_containerfiles.py +0 -0
  235. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_credentials.py +0 -0
  236. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_defaults_golden.py +0 -0
  237. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_deprecations.py +0 -0
  238. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_error_messages.py +0 -0
  239. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_freshness.py +0 -0
  240. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_git.py +0 -0
  241. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_helper_client.py +0 -0
  242. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_helpers.py +0 -0
  243. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_install_integration.py +0 -0
  244. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_log.py +0 -0
  245. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_registry.py +0 -0
  246. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_rig_bundle.py +0 -0
  247. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_rig_meta.py +0 -0
  248. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_rig_resolve.py +0 -0
  249. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_rig_source.py +0 -0
  250. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_settings_resolve.py +0 -0
  251. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_settings_store.py +0 -0
  252. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_shellenv.py +0 -0
  253. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_snapshots.py +0 -0
  254. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_start_integration.py +0 -0
  255. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_status.py +0 -0
  256. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_templates_image.py +0 -0
  257. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_tweakcc.py +0 -0
  258. {kanibako_cli-1.6.0.dev36 → kanibako_cli-1.7.0}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kanibako-cli
3
- Version: 1.6.0.dev36
3
+ Version: 1.7.0
4
4
  Summary: Run AI coding agents in rootless containers with per-project isolation
5
5
  Requires-Python: >=3.11
6
6
  License-File: LICENSE.md
@@ -13,6 +13,9 @@ agent sessions that survive reboots and SSH disconnects.
13
13
 
14
14
  CRAB: **C**ontained **R**untime **A**gent in a **B**ox.
15
15
 
16
+ New here? Start with [GETTING_STARTED.md](GETTING_STARTED.md) for a five-minute
17
+ walkthrough from install to your first agent session.
18
+
16
19
  No Docker or Podman experience required. Just `cd` into a project and run
17
20
  `kanibako`. Setup, rig pulls, credential syncing, and teardown are automatic.
18
21
  Claude Code, Codex, and Goose ship as first-class agent plugins (all installed
@@ -39,12 +42,12 @@ by the `kanibako` meta-package); other agents can be added as plugins.
39
42
  - **Vault snapshots** -- per-box read-only and read-write shared
40
43
  directories with smart snapshot strategy detection (reflink, hardlink,
41
44
  or tar.xz depending on filesystem)
42
- - **Shell customization** -- per-box environment variables (`box config
45
+ - **Shell customization** -- per-box environment variables (`box set
43
46
  env.*`), drop-in init scripts (`shell.d/`), and layered seed-once home
44
47
  templates
45
48
  - **Agent configuration** -- per-agent YAML config with default args, state
46
49
  knobs, env vars, and shared caches; per-box setting overrides via
47
- `box config`
50
+ `box set`
48
51
  - **Shared caches** -- global download caches (pip, cargo, npm, etc.)
49
52
  shared across boxes; agent-level caches via the agent config
50
53
  - **Plugin system** -- agent-agnostic core (`kanibako-cli`); Claude/Codex/Goose
@@ -60,21 +63,26 @@ by the `kanibako` meta-package); other agents can be added as plugins.
60
63
  ## Prerequisites
61
64
 
62
65
  - Python 3.11+
63
- - [Podman](https://podman.io/) (recommended) or Docker -- just needs to be
66
+ - [Podman](https://podman.io/) 4.3+ (recommended) or Docker -- just needs to be
64
67
  installed; Kanibako manages all container operations automatically
65
68
  - An AI coding agent installed on the host (e.g.
66
69
  [Claude Code](https://docs.anthropic.com/en/docs/claude-code))
67
70
 
68
71
  ## Installation
69
72
 
73
+ > **Pre-release:** the current line (`1.7.0`) is still in release candidates, so
74
+ > add `--pre` (pip/pipx) or `--prerelease allow` (uv) to get the newest rc. Plain
75
+ > `pip install kanibako` gets the last *stable* release (`1.6.0`). Once `1.7.0`
76
+ > ships, drop the flag.
77
+
70
78
  ```bash
71
- # Standard install (cli + Claude, Codex, and Goose plugins)
72
- uv tool install kanibako
79
+ # Standard install (cli + Claude, Codex, and Goose plugins) -- current rc
80
+ uv tool install --prerelease allow kanibako
73
81
  # -- or --
74
- pip install kanibako
82
+ pip install --pre kanibako
75
83
 
76
84
  # Base only (no agent plugins -- agent-agnostic shell mode)
77
- pip install kanibako-cli
85
+ pip install --pre kanibako-cli
78
86
 
79
87
  # Development install
80
88
  git clone https://github.com/doctorjei/kanibako.git
@@ -92,8 +100,11 @@ it is used automatically. See [Agent Selection](#agent-selection).
92
100
  ## Quick Start
93
101
 
94
102
  ```bash
95
- # Start an agent session in the current directory
103
+ # Create a box for the current directory (a deliberate, one-time step)
96
104
  cd ~/my-project
105
+ kanibako create
106
+
107
+ # Start an agent session (shortcut for `kanibako start`)
97
108
  kanibako
98
109
 
99
110
  # Start with a specific rig
@@ -109,10 +120,11 @@ kanibako shell -- echo hello
109
120
  kanibako -N
110
121
  ```
111
122
 
112
- That's it -- no `docker run`, no volume flags, no Containerfile. On first run,
113
- Kanibako automatically pulls the container rig, sets up the project
114
- environment, and syncs your credentials. Subsequent runs pick up where you
115
- left off.
123
+ That's it -- no `docker run`, no volume flags, no Containerfile. Creating a box
124
+ is an explicit step (`kanibako create`); a launch (`kanibako` / `start` / `code` /
125
+ `shell`) never invents a box, so a typo'd project or wrong directory can't
126
+ silently make one. On the first launch of a box, Kanibako pulls the container
127
+ rig and syncs your credentials; subsequent runs pick up where you left off.
116
128
 
117
129
  ## Example: Python Project
118
130
 
@@ -121,21 +133,24 @@ gh, nano, jq, ripgrep, tmux, Podman, and common dev tools. This is enough for
121
133
  most Python, JavaScript, and general scripting work.
122
134
 
123
135
  ```bash
124
- # 1. Install kanibako
125
- pip install kanibako
136
+ # 1. Install kanibako (--pre while 1.7.0 is in rc; see Installation)
137
+ pip install --pre kanibako
126
138
 
127
139
  # 2. Create or clone a project
128
140
  mkdir ~/my-flask-app && cd ~/my-flask-app
129
141
  git init
130
142
  # (or: git clone https://github.com/you/my-flask-app.git && cd my-flask-app)
131
143
 
132
- # 3. Launch -- that's it
144
+ # 3. Create the box for this project (explicit, one-time)
145
+ kanibako create
146
+
147
+ # 4. Launch -- that's it
133
148
  kanibako
134
149
  ```
135
150
 
136
- On the first launch, Kanibako will:
151
+ `kanibako create` sets up an isolated environment for this project. On the
152
+ first launch, Kanibako will:
137
153
  - Pull the base container rig (once, cached afterwards)
138
- - Create an isolated environment for this project
139
154
  - Copy your agent credentials into the sandbox
140
155
  - Drop you into an agent session inside the container
141
156
 
@@ -161,20 +176,23 @@ toolchains you need:
161
176
  kanibako rig prep systems
162
177
  # (or build one interactively with: kanibako rig extend my-systems --from kanibako-oci)
163
178
 
164
- # 2. Use it for your project
179
+ # 2. Create the box for your project, pinned to that rig (explicit, one-time)
165
180
  cd ~/my-rust-project
166
- kanibako --image kanibako-template-systems
181
+ kanibako create --image kanibako-template-systems
182
+
183
+ # 3. Launch
184
+ kanibako
167
185
  ```
168
186
 
169
- After the first run, Kanibako remembers the rig choice for this project,
170
- so you can just run `kanibako` next time.
187
+ `kanibako create` pins the rig choice for this project, so you can just run
188
+ `kanibako` next time.
171
189
 
172
190
  See [Container Rigs](#container-rigs) for the base rigs and custom rig
173
191
  creation.
174
192
 
175
193
  ## Commands
176
194
 
177
- Kanibako organizes commands into four management groups plus seven top-level
195
+ Kanibako organizes commands into four management groups plus eight top-level
178
196
  shortcuts for common operations:
179
197
 
180
198
  ### Top-Level Shortcuts
@@ -188,6 +206,7 @@ shortcuts for common operations:
188
206
  | `kanibako ps [-a] [-q]` | `box ps` | List active (running) boxes |
189
207
  | `kanibako create [path]` | `box create` | Create a new project |
190
208
  | `kanibako rm <project>` | `box rm` | Remove a project |
209
+ | `kanibako code [project]` | *(top-level only)* | Open VS Code attached to the box (see [VS Code Integration](#vs-code-integration)) |
191
210
 
192
211
  ### Management Commands
193
212
 
@@ -220,7 +239,7 @@ shortcuts for common operations:
220
239
  | `box list` / `box ls` | List projects (`--all`, `--orphan`, `-q`) |
221
240
  | `box info` / `box inspect` | Project details (mode, paths, lock, rig) |
222
241
  | `box rm` / `box delete` | Remove project (`--purge` deletes metadata, `--force` skips confirm) |
223
- | `box config` | View or modify project configuration |
242
+ | `box set` / `box get` / `box show` / `box reset` | View or modify project configuration |
224
243
  | `box diagnose [project]` | Check project box health |
225
244
 
226
245
  **Relocation & conversion:**
@@ -265,7 +284,7 @@ shortcuts for common operations:
265
284
  | `workset list` / `workset ls` | List working sets (`-q`) |
266
285
  | `workset info` / `workset inspect` | Working set details |
267
286
  | `workset rm` / `workset delete` | Remove working set (`--purge`, `--force`) |
268
- | `workset config` | View or modify workset configuration (use `workset config default <key>=<value>` for default-workset defaults) |
287
+ | `workset set` / `workset get` / `workset show` / `workset reset` | View or modify workset configuration (use `workset set default <key>=<value>` for default-workset defaults) |
269
288
  | `workset connect <workset> [source]` | Add project to working set (`--name`) |
270
289
  | `workset disconnect <workset> <project>` | Remove project from working set (`--force`) |
271
290
 
@@ -275,7 +294,7 @@ shortcuts for common operations:
275
294
  |------------|-------------|
276
295
  | `agent list` / `agent ls` | List configured agents (`-q`) |
277
296
  | `agent info` / `agent inspect` | Agent configuration details |
278
- | `agent config` | View or modify agent configuration |
297
+ | `agent set` / `agent get` / `agent show` / `agent reset` | View or modify agent configuration |
279
298
  | `agent reauth [project]` | Refresh credentials |
280
299
 
281
300
  ### `box helper` / `box fork` Subcommands
@@ -300,10 +319,74 @@ The runtime helper and fork verbs (formerly under `crab`) now live under `box`:
300
319
  | Subcommand | Description |
301
320
  |------------|-------------|
302
321
  | `system info` / `system inspect` | System details (version, runtime, paths) |
303
- | `system config` | View or modify global configuration |
322
+ | `system set` / `system get` / `system show` / `system reset` | View or modify global configuration |
304
323
  | `system upgrade` | Self-update (`--check` for dry run) |
305
324
  | `system diagnose` | Check system health (runtime, images, agents, storage) |
306
325
 
326
+ ## VS Code Integration
327
+
328
+ > **⚠ Experimental.** VS Code integration is **experimental** in this release.
329
+ > The commands below work, but multi-surface behavior is still hardening — in
330
+ > particular, kanibako does **not yet enforce a single active agent per box**.
331
+ > Running the agent **panel** and a **CLI agent** on the *same box at the same
332
+ > time* silently **forks the session**: both write the same agent history and
333
+ > one surface's turns can be lost with no warning. **Use one agent surface per
334
+ > box at a time** until single-writer enforcement lands.
335
+
336
+ `kanibako code [project]` opens your **host** VS Code attached to the box
337
+ (Dev Containers "Attach to Running Container"), at the box's `~/workspace`.
338
+ The box is auto-started detached if it isn't running, and it stays up when
339
+ you close the window. The box agent's editor extension is installed into the
340
+ attached window automatically.
341
+
342
+ Requirements: the `code` CLI on your PATH, the Dev Containers extension
343
+ (`ms-vscode-remote.remote-containers`), and
344
+ `"dev.containers.dockerPath": "podman"` in your VS Code user settings.
345
+ `kanibako system diagnose` checks all three.
346
+
347
+ ### Remote boxes
348
+
349
+ ```bash
350
+ kanibako code --remote <host> <project>
351
+ ```
352
+
353
+ attaches your **local** VS Code to a box on a **remote** kanibako host —
354
+ no relay service, no VS Code on the remote host. `<host>` is an opaque SSH
355
+ destination resolved by your own `~/.ssh/config`. kanibako runs the box
356
+ lifecycle on the remote host over plain SSH, and the container-engine leg
357
+ rides a kanibako-owned SSH tunnel: one OpenSSH `ControlPersist` master
358
+ forwards the remote rootless podman socket to a local unix socket, and local
359
+ podman dials that socket. podman's own golang `ssh:` transport is **not**
360
+ used, so no `ssh-agent` is required, your `~/.ssh/config` is fully honored
361
+ (aliases, ProxyJump, ports, `IdentityFile`), and per-call SSH handshake
362
+ overhead is gone once the first call warms the tunnel.
363
+
364
+ Requirements:
365
+
366
+ - the same kanibako **version** on both hosts, plus a local `code` CLI and
367
+ local `podman` (the `--remote` client);
368
+ - the rootless podman API socket on the remote host:
369
+
370
+ ```bash
371
+ systemctl --user enable --now podman.socket
372
+ loginctl enable-linger "$USER"
373
+ ```
374
+
375
+ On first `--remote` use, kanibako asks to point
376
+ `dev.containers.dockerPath` at its dispatch wrapper (local attaches are
377
+ unaffected — the wrapper is a pass-through to `podman` except for remote
378
+ attach windows).
379
+
380
+ If a remote attach fails, check the dispatch log at
381
+ `~/.local/state/kanibako/vscode-remote/dispatch.log` (or under
382
+ `$XDG_STATE_HOME`) — one line per engine call showing the resolved route and
383
+ context.
384
+
385
+ > **First attach:** the first time VS Code attaches to a given container it
386
+ > shows a workspace-trust dialog you must click through. In headless or
387
+ > automated setups this can look like a silent hang — bring the VS Code
388
+ > window forward and confirm the trust prompt to proceed.
389
+
307
390
  ## Common Flags
308
391
 
309
392
  ### Agent Flags (on `start`)
@@ -349,7 +432,7 @@ error, not a silent no-op).
349
432
  #### `--box`: operate on any box
350
433
 
351
434
  `--box` substitutes for being in the box's directory: `kanibako stop --box myproj`,
352
- `kanibako box config --box myproj model=opus`. The value is a **box name (resolved
435
+ `kanibako box set --box myproj model=opus`. The value is a **box name (resolved
353
436
  first) or a path**. It is the *subject* the command acts on, and stays orthogonal to
354
437
  the `move`/`convert` *destination* group, so they coexist:
355
438
 
@@ -408,7 +491,7 @@ confirm. Non-TTY runs (CI / headless) skip the prompt gracefully.
408
491
  nudge to run `setup` if it has never been run, then proceed.
409
492
 
410
493
  Because `system.*` keys are **file-only** (see [Configuration](#configuration)),
411
- the default agent is *not* settable via `kanibako system config` -- use `setup` or
494
+ the default agent is *not* settable via `kanibako system set` -- use `setup` or
412
495
  edit `global/settings.yaml` directly.
413
496
 
414
497
  ## Project Modes
@@ -431,11 +514,11 @@ and run `kanibako`, and the box joins the primary workset.
431
514
 
432
515
  The primary workset is addressable through the same `workset` commands as named
433
516
  worksets (workset name token `__PRIMARY__`), so primary-workset settings use the
434
- ordinary `workset config default` mechanism (see [Configuration](#configuration)):
517
+ ordinary `workset set default` mechanism (see [Configuration](#configuration)):
435
518
 
436
519
  ```bash
437
- kanibako workset config default model=opus # default for ALL primary-mode boxes
438
- kanibako workset config default group_auth=false # distinct credentials by default
520
+ kanibako workset set default model=opus # default for ALL primary-mode boxes
521
+ kanibako workset set default group_auth=false # distinct credentials by default
439
522
  ```
440
523
 
441
524
  The names `__PRIMARY__` / `__STANDALONE__` (and legacy `default`) are reserved
@@ -629,9 +712,9 @@ container:
629
712
 
630
713
  ```bash
631
714
  # Persistent (stored in project config)
632
- kanibako box config env.EDITOR=vim # project-level
633
- kanibako system config env.EDITOR=nano # global (all projects)
634
- kanibako box config env.EDITOR # show one value
715
+ kanibako box set env.EDITOR=vim # project-level
716
+ kanibako system set env.EDITOR=nano # global (all projects)
717
+ kanibako box get env.EDITOR # show one value
635
718
 
636
719
  # Per-run (not persisted)
637
720
  kanibako start -e EDITOR=vim -e DEBUG=1
@@ -644,7 +727,7 @@ Project env vars override global ones.
644
727
  The shell prompt is controlled by the `KANIBAKO_PS1` environment variable:
645
728
 
646
729
  ```bash
647
- kanibako box config env.KANIBAKO_PS1="(myproject) \u:\w\$ "
730
+ kanibako box set env.KANIBAKO_PS1="(myproject) \u:\w\$ "
648
731
  ```
649
732
 
650
733
  ### Init scripts
@@ -702,8 +785,8 @@ Manage agent settings via the CLI:
702
785
 
703
786
  ```bash
704
787
  kanibako agent list # list configured agents
705
- kanibako agent config model # show effective model
706
- kanibako agent config model=sonnet # set agent-level default
788
+ kanibako agent get claude model # show the agent's model
789
+ kanibako agent set claude model=sonnet # set agent-level default
707
790
  ```
708
791
 
709
792
  ## Home Templates
@@ -822,7 +905,7 @@ guide.
822
905
  pip install kanibako-target-myagent
823
906
 
824
907
  # Use a specific target
825
- kanibako box config box.agent=myagent
908
+ kanibako box set box.agent=myagent
826
909
  kanibako start
827
910
 
828
911
  # (`crab_name` is gone -- select the agent via box.agent)
@@ -846,29 +929,30 @@ CLI flag > settings_required > box > workset > agent.<agent> > system > settings
846
929
  **file-only** -- the CLI reads and shows them but refuses to set them (edit the
847
930
  file directly); `setup` and programmatic writers still write them.
848
931
 
849
- All settings levels share a unified interface:
932
+ All settings levels share the same four verbs -- `set` / `get` / `show` /
933
+ `reset`:
850
934
 
851
935
  ```bash
852
936
  # Box level
853
- kanibako box config # show box overrides
854
- kanibako box config --effective # show resolved values (inherited + overrides)
855
- kanibako box config model # get one key
856
- kanibako box config model=sonnet # set one key
857
- kanibako box config --reset model # remove override, back to default
937
+ kanibako box show # show box overrides
938
+ kanibako box show --effective # show resolved values (inherited + overrides)
939
+ kanibako box get model # get one key
940
+ kanibako box set model=sonnet # set one key
941
+ kanibako box reset model # remove override, back to default
858
942
 
859
943
  # Workset level (group defaults inherited by member boxes)
860
- kanibako workset config <workset> model=opus
861
- kanibako workset config default model=opus # primary-workset default
944
+ kanibako workset set <workset> model=opus
945
+ kanibako workset set default model=opus # primary-workset default
862
946
 
863
947
  # Agent level (defaults for all boxes using this agent)
864
- kanibako agent config model=opus
948
+ kanibako agent set claude model=opus
865
949
 
866
950
  # System level (global settings defaults)
867
- kanibako system config model=opus
868
- kanibako system config --reset --all # reset all global settings
951
+ kanibako system set model=opus
952
+ kanibako system reset --all # reset all global settings
869
953
  ```
870
954
 
871
- `kanibako system config` sets **non-`system.`** settings only. `system.*`-prefixed
955
+ `kanibako system set` sets **non-`system.`** settings only. `system.*`-prefixed
872
956
  keys (layout paths AND `system.default_agent`) are **file-only**: the CLI shows them
873
957
  but refuses to set/reset them, pointing you at the config file. Set the default agent
874
958
  with `kanibako setup`; edit structural paths in `~/.config/kanibako.yaml` directly.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "kanibako-cli"
7
- version = "1.6.0.dev36"
7
+ version = "1.7.0"
8
8
  description = "Run AI coding agents in rootless containers with per-project isolation"
9
9
  requires-python = ">=3.11"
10
10
  dependencies = ["argcomplete>=3.0", "PyYAML>=6.0", "packaging>=20.0"]
@@ -30,11 +30,16 @@ where = ["src"]
30
30
  "templates/**/*", "templates/**/.*",
31
31
  "templates/.*/**/*", "templates/.*/*",
32
32
  "templates/**/.*/**/*", "templates/**/.*/*",
33
+ "global/*", "global/**/*",
33
34
  ]
34
35
 
35
36
  [tool.ruff]
36
37
  target-version = "py311"
37
38
  line-length = 99
39
+ # ``salvage/`` holds frozen, non-shipping reference snapshots (retired code kept
40
+ # for a possible future ``system recover``); it is not live code and is not
41
+ # linted. It is also outside ``src/`` so the wheel build never includes it.
42
+ extend-exclude = ["salvage"]
38
43
 
39
44
  [tool.ruff.lint.per-file-ignores]
40
45
  "tests/conftest.py" = ["E402"]
@@ -48,6 +53,9 @@ line-length = 99
48
53
  # mypy at every src base and enable explicit package bases.
49
54
  namespace_packages = true
50
55
  explicit_package_bases = true
56
+ # ``salvage/`` is a frozen non-shipping reference snapshot (see [tool.ruff]); it
57
+ # is not type-checked and is not on any src base.
58
+ exclude = ['^salvage/']
51
59
  mypy_path = "$MYPY_CONFIG_FILE_DIR/src:$MYPY_CONFIG_FILE_DIR/packages/agent-claude/src:$MYPY_CONFIG_FILE_DIR/packages/agent-goose/src:$MYPY_CONFIG_FILE_DIR/packages/agent-codex/src"
52
60
 
53
61
  [[tool.mypy.overrides]]
@@ -0,0 +1,25 @@
1
+ """kanibako: Run AI coding agents in rootless containers with per-project isolation."""
2
+
3
+ __version__ = "1.7.0"
4
+
5
+ # Two-tier setup/config compatibility constants for the 5-band setup-completion
6
+ # gate (design: ``plans/2026-06-23-setup-version-tiers-NEXT.md``). Both are
7
+ # compared against the recorded ``system.setup_completed`` marker by BASE version
8
+ # (PEP 440 via ``packaging.version``), so a dev/rc build of the same base reads
9
+ # as the released base, not "from the future".
10
+ #
11
+ # * ``SETUP_BCV`` — backward-compatible version: the OLDEST setup/config version
12
+ # this build can function with AT ALL. Below it, the build can no longer
13
+ # auto-fill the gaps → the gate ERRORS (rc1) and the user must re-run setup.
14
+ # Bump only when a setup change can no longer be auto-filled.
15
+ # * ``SETUP_FCV`` — forward-compatible version: the oldest version whose setup is
16
+ # COMPLETELY compatible (nothing new since). At or above it (but below the
17
+ # running build) the gate SILENTLY bumps the marker forward. Between BCV and
18
+ # FCV the gate NUDGES (non-blocking) to re-run setup. Bump whenever setup adds
19
+ # a new feature/case.
20
+ #
21
+ # Invariant: ``SETUP_BCV <= SETUP_FCV <= __version__`` (base versions). Most
22
+ # releases change setup in no way → bump NEITHER → existing configs land
23
+ # ``>= FCV`` → silent.
24
+ SETUP_BCV = "1.6.0"
25
+ SETUP_FCV = "1.7.0"
@@ -0,0 +1,146 @@
1
+ """Agent YAML configuration: load, write, and resolve per-agent settings."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass, field
6
+ from pathlib import Path
7
+
8
+ from kanibako.config_io import dump_doc, load_doc
9
+
10
+ # Keys that live directly in the [agent] section as agent identity (not state).
11
+ IDENTITY_KEYS = frozenset({"name", "run_args"})
12
+
13
+
14
+ @dataclass
15
+ class AgentConfig:
16
+ """Per-agent configuration loaded from an agent YAML file.
17
+
18
+ Sections:
19
+ agent — identity (name, run_args) plus agent-state knobs
20
+ (model, auto_approve, allow_helpers, endpoint, …). The
21
+ per-node DISCRIMINATED sub-table ``agent.<node>.secret_path``
22
+ also lives here (see *secret_path* below).
23
+ env — raw env vars injected into container (VAR -> value)
24
+ secret_path — the SECRET category (spec §2a, 2026-07-06; RENAMED from the
25
+ rc0-rc2 ``env_file``): VAR -> host PATH pointer to secret
26
+ material (e.g. a 0600 bearer-token file). Stored DISCRIMINATED
27
+ under ``agent.<node>.secret_path.<VAR>`` (the SAME first-class
28
+ category shape ``config set agent.<node>.secret_path.<VAR>``
29
+ writes and ``_agent_partial`` reads into the launch cascade),
30
+ so it resolves through ``system → workset → box → agent``
31
+ precedence. The value is a PATH only — at launch it is ro-bind-
32
+ mounted arm's-length + exported IN-BOX; kanibako NEVER reads the
33
+ secret VALUE (never in the snapshot/keystore/logs/argv).
34
+ """
35
+
36
+ name: str = ""
37
+ run_args: list[str] = field(default_factory=list)
38
+ state: dict[str, str] = field(default_factory=dict)
39
+ env: dict[str, str] = field(default_factory=dict)
40
+ secret_path: dict[str, str] = field(default_factory=dict)
41
+ tweakcc: dict = field(default_factory=dict)
42
+
43
+
44
+ def agents_dir(data_path: Path, paths_agents: str = "agents") -> Path:
45
+ """Return the agents directory under *data_path*."""
46
+ return data_path / (paths_agents or "agents")
47
+
48
+
49
+ def agent_settings_path(agents_root: Path, agent_id: str) -> Path:
50
+ """Return ``@meta.agent.<agent>.settings`` for *agent_id*.
51
+
52
+ The per-agent SETTINGS cascade file lives INSIDE the per-agent store dir
53
+ (``@meta.agent.<agent>.path`` = ``agents/<agent>/``) as ``settings.yaml``
54
+ — NOT the old sibling ``agents/<agent>.yaml`` file (D-2026-06-22). This
55
+ parallels the per-agent template dir ``agents/<agent>/template`` and the
56
+ Part-3 ``agents/<agent>/{plugins,cache}`` stores.
57
+ """
58
+ return agents_root / agent_id / "settings.yaml"
59
+
60
+
61
+ def agent_config_path(
62
+ data_path: Path, agent_id: str, paths_agents: str = "agents",
63
+ ) -> Path:
64
+ """Return the path to an agent's config (settings) file.
65
+
66
+ Convenience wrapper for callers that hold a *data_path* rather than the
67
+ resolved agents root; delegates to :func:`agent_settings_path`.
68
+ """
69
+ return agent_settings_path(agents_dir(data_path, paths_agents), agent_id)
70
+
71
+
72
+ def load_agent_config(path: Path) -> AgentConfig:
73
+ """Read an agent config file and return an AgentConfig.
74
+
75
+ Returns defaults if the file does not exist.
76
+ """
77
+ cfg = AgentConfig()
78
+ if not path.exists():
79
+ return cfg
80
+
81
+ data = load_doc(path)
82
+
83
+ # The node is the per-agent store dir name (agents/<node>/settings.yaml), which
84
+ # IS the cascade discriminator ``_agent_partial`` reads (agent_name == node). The
85
+ # DISCRIMINATED ``agent.<node>.secret_path`` sub-table (first-class category)
86
+ # lives under the same ``agent:`` table as the flat state — read it by node.
87
+ node = path.parent.name
88
+
89
+ agent_sec = data.get("agent", {})
90
+ if not isinstance(agent_sec, dict):
91
+ agent_sec = {}
92
+ cfg.name = str(agent_sec.get("name", ""))
93
+ raw_args = agent_sec.get("run_args", [])
94
+ cfg.run_args = [str(a) for a in raw_args] if isinstance(raw_args, list) else []
95
+
96
+ # Flat state = the SCALAR agent-state knobs. Exclude identity keys AND any
97
+ # dict-valued entry: the discriminated ``<node>:`` sub-table (secret_path, node
98
+ # binds) is a dict and is NOT flat state — it rides ``_agent_partial``, not the
99
+ # ``_agent_state_partial`` state channel.
100
+ cfg.state = {
101
+ k: str(v)
102
+ for k, v in agent_sec.items()
103
+ if k not in IDENTITY_KEYS and not isinstance(v, dict)
104
+ }
105
+ cfg.env = {k: str(v) for k, v in data.get("env", {}).items()}
106
+ # secret_path: VAR -> host PATH pointer, read from the DISCRIMINATED
107
+ # ``agent.<node>.secret_path`` sub-table (spec §2a SECRET category). Stored as a
108
+ # plain string path; the file's CONTENTS (the secret) are never persisted here
109
+ # nor read — they are ro-mounted + exported IN-BOX only at launch.
110
+ node_sub = agent_sec.get(node, {})
111
+ secret_sub = node_sub.get("secret_path", {}) if isinstance(node_sub, dict) else {}
112
+ cfg.secret_path = {
113
+ k: str(v) for k, v in secret_sub.items()
114
+ } if isinstance(secret_sub, dict) else {}
115
+ cfg.tweakcc = dict(data.get("tweakcc", {}))
116
+
117
+ return cfg
118
+
119
+
120
+ def write_agent_config(path: Path, cfg: AgentConfig) -> None:
121
+ """Write an AgentConfig to a YAML file."""
122
+ node = path.parent.name
123
+ agent_sec: dict = {
124
+ "name": cfg.name,
125
+ "run_args": list(cfg.run_args),
126
+ }
127
+ for k, v in cfg.state.items():
128
+ agent_sec[k] = v
129
+ # secret_path (spec §2a SECRET category) is stored DISCRIMINATED under the
130
+ # ``agent.<node>.secret_path`` sub-table — the SAME first-class category location
131
+ # ``config set agent.<node>.secret_path.<VAR>`` writes and ``_agent_partial``
132
+ # reads into the launch cascade — so the persona-adopted token pointer resolves
133
+ # through the cascade like any other agent-tier category. Only materialized when
134
+ # non-empty (sparse). NO ``env_file`` section (RENAMED, clean break — rc0-rc2 only).
135
+ if cfg.secret_path:
136
+ agent_sec[node] = {"secret_path": dict(cfg.secret_path)}
137
+
138
+ data: dict = {
139
+ "agent": agent_sec,
140
+ "env": dict(cfg.env),
141
+ "tweakcc": dict(cfg.tweakcc),
142
+ }
143
+ # The settings file lives inside the per-agent store dir
144
+ # (agents/<agent>/settings.yaml); ensure that dir exists.
145
+ path.parent.mkdir(parents=True, exist_ok=True)
146
+ dump_doc(path, data)