kanibako-cli 1.5.0.dev14__py3-none-any.whl

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 (85) hide show
  1. kanibako/__init__.py +3 -0
  2. kanibako/__main__.py +6 -0
  3. kanibako/auth_browser.py +296 -0
  4. kanibako/auth_parser.py +51 -0
  5. kanibako/browser_sidecar.py +183 -0
  6. kanibako/browser_state.py +103 -0
  7. kanibako/bun_sea.py +144 -0
  8. kanibako/cli.py +344 -0
  9. kanibako/commands/__init__.py +0 -0
  10. kanibako/commands/archive.py +228 -0
  11. kanibako/commands/box/__init__.py +22 -0
  12. kanibako/commands/box/_duplicate.py +395 -0
  13. kanibako/commands/box/_migrate.py +574 -0
  14. kanibako/commands/box/_parser.py +1178 -0
  15. kanibako/commands/clean.py +166 -0
  16. kanibako/commands/crab_cmd.py +480 -0
  17. kanibako/commands/diagnose.py +239 -0
  18. kanibako/commands/fork_cmd.py +51 -0
  19. kanibako/commands/helper_cmd.py +669 -0
  20. kanibako/commands/image.py +1300 -0
  21. kanibako/commands/install.py +152 -0
  22. kanibako/commands/refresh_credentials.py +67 -0
  23. kanibako/commands/restore.py +298 -0
  24. kanibako/commands/setup_cmd.py +89 -0
  25. kanibako/commands/start.py +1600 -0
  26. kanibako/commands/stop.py +116 -0
  27. kanibako/commands/system_cmd.py +224 -0
  28. kanibako/commands/upgrade.py +161 -0
  29. kanibako/commands/vault_cmd.py +199 -0
  30. kanibako/commands/workset_cmd.py +552 -0
  31. kanibako/config.py +514 -0
  32. kanibako/config_interface.py +573 -0
  33. kanibako/config_io.py +36 -0
  34. kanibako/container.py +607 -0
  35. kanibako/containerfiles.py +58 -0
  36. kanibako/containers/Containerfile.kanibako +99 -0
  37. kanibako/containers/Containerfile.template-android +55 -0
  38. kanibako/containers/Containerfile.template-dotnet +29 -0
  39. kanibako/containers/Containerfile.template-js +43 -0
  40. kanibako/containers/Containerfile.template-jvm +27 -0
  41. kanibako/containers/Containerfile.template-systems +46 -0
  42. kanibako/containers/__init__.py +0 -0
  43. kanibako/crabs.py +89 -0
  44. kanibako/errors.py +33 -0
  45. kanibako/freshness.py +67 -0
  46. kanibako/git.py +114 -0
  47. kanibako/helper_client.py +132 -0
  48. kanibako/helper_listener.py +538 -0
  49. kanibako/helpers.py +339 -0
  50. kanibako/hygiene.py +296 -0
  51. kanibako/image_sharing.py +133 -0
  52. kanibako/instructions.py +160 -0
  53. kanibako/log.py +31 -0
  54. kanibako/names.py +248 -0
  55. kanibako/paths.py +1483 -0
  56. kanibako/plugins/__init__.py +10 -0
  57. kanibako/registry.py +71 -0
  58. kanibako/rig_bundle.py +121 -0
  59. kanibako/rig_meta.py +92 -0
  60. kanibako/rig_registry.py +132 -0
  61. kanibako/rig_resolve.py +182 -0
  62. kanibako/rig_source.py +245 -0
  63. kanibako/scripts/__init__.py +0 -0
  64. kanibako/scripts/helper-init.sh +45 -0
  65. kanibako/scripts/kanibako-entry +12 -0
  66. kanibako/settings_resolve.py +312 -0
  67. kanibako/settings_seeds.py +154 -0
  68. kanibako/settings_shares.py +154 -0
  69. kanibako/shellenv.py +75 -0
  70. kanibako/snapshots.py +281 -0
  71. kanibako/targets/__init__.py +173 -0
  72. kanibako/targets/base.py +243 -0
  73. kanibako/targets/no_agent.py +58 -0
  74. kanibako/templates.py +60 -0
  75. kanibako/templates_image.py +224 -0
  76. kanibako/tweakcc.py +140 -0
  77. kanibako/tweakcc_cache.py +171 -0
  78. kanibako/utils.py +136 -0
  79. kanibako/workset.py +347 -0
  80. kanibako_cli-1.5.0.dev14.dist-info/METADATA +15 -0
  81. kanibako_cli-1.5.0.dev14.dist-info/RECORD +85 -0
  82. kanibako_cli-1.5.0.dev14.dist-info/WHEEL +5 -0
  83. kanibako_cli-1.5.0.dev14.dist-info/entry_points.txt +5 -0
  84. kanibako_cli-1.5.0.dev14.dist-info/licenses/LICENSE.md +594 -0
  85. kanibako_cli-1.5.0.dev14.dist-info/top_level.txt +1 -0
kanibako/workset.py ADDED
@@ -0,0 +1,347 @@
1
+ """Working set data model and persistence.
2
+
3
+ A *workset* is a named group of projects whose persistent state lives under a
4
+ single root directory chosen by the user. The layout is:
5
+
6
+ {root}/
7
+ workset.yaml ← workset metadata + project list
8
+ projects/{name}/ ← per-project metadata + home
9
+ home/ ← agent home (mounted as /home/agent)
10
+ project.yaml ← per-project config
11
+ .kanibako.lock ← concurrency lock
12
+ workspaces/{name}/ ← per-project workspace (source tree)
13
+ vault/{name}/ro/ ← per-project read-only vault
14
+ vault/{name}/rw/ ← per-project read-write vault
15
+
16
+ A global registry at ``$XDG_DATA_HOME/kanibako/worksets.yaml`` maps workset
17
+ names to root paths so they can be discovered from anywhere.
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ from dataclasses import dataclass, field
23
+ from datetime import datetime, timezone
24
+ from pathlib import Path
25
+
26
+ from kanibako.config_io import dump_doc, load_doc
27
+ from kanibako.errors import WorksetError
28
+ from kanibako.names import read_names, register_name, unregister_name
29
+ from kanibako.paths import StandardPaths
30
+
31
+
32
+ # Identity of the synthesized "default" workset (the group of default-mode
33
+ # projects). This workset is virtual — it is never written to disk.
34
+ DEFAULT_WORKSET_ID = "__default__"
35
+ DEFAULT_WORKSET_ALIAS = "default"
36
+
37
+
38
+ # ---------------------------------------------------------------------------
39
+ # Data classes
40
+ # ---------------------------------------------------------------------------
41
+
42
+ @dataclass
43
+ class WorksetProject:
44
+ """A project registered inside a workset."""
45
+
46
+ name: str
47
+ source_path: Path # original project path (for reference / cloning)
48
+
49
+
50
+ @dataclass
51
+ class Workset:
52
+ """In-memory representation of a workset."""
53
+
54
+ name: str
55
+ root: Path
56
+ created: str # ISO 8601, UTC
57
+ projects: list[WorksetProject] = field(default_factory=list)
58
+ group_auth: bool = field(default=True) # True = shared creds, False = distinct
59
+ is_default: bool = False # True = synthesized default workset
60
+
61
+ # Convenience paths -------------------------------------------------------
62
+
63
+ @property
64
+ def projects_dir(self) -> Path:
65
+ return self.root / "boxes"
66
+
67
+ @property
68
+ def workspaces_dir(self) -> Path:
69
+ return self.root / "workspaces"
70
+
71
+ @property
72
+ def vault_dir(self) -> Path:
73
+ return self.root / "vault"
74
+
75
+ @property
76
+ def toml_path(self) -> Path:
77
+ return self.root / "workset.yaml"
78
+
79
+
80
+ # ---------------------------------------------------------------------------
81
+ # workset.yaml (at workset root)
82
+ # ---------------------------------------------------------------------------
83
+
84
+ def _write_workset_toml(ws: Workset) -> None:
85
+ """Serialize *ws* to ``workset.yaml`` at the workset root."""
86
+ data: dict = {
87
+ "name": ws.name,
88
+ "created": ws.created,
89
+ "group_auth": ws.group_auth,
90
+ "projects": [
91
+ {"name": proj.name, "source_path": str(proj.source_path)}
92
+ for proj in ws.projects
93
+ ],
94
+ }
95
+ dump_doc(ws.toml_path, data)
96
+
97
+
98
+ def _load_workset_toml(root: Path) -> Workset:
99
+ """Read ``workset.yaml`` from *root* and return a ``Workset``."""
100
+ toml_path = root / "workset.yaml"
101
+ if not toml_path.is_file():
102
+ raise WorksetError(f"No workset.yaml in {root}")
103
+ data = load_doc(toml_path)
104
+ name = data.get("name")
105
+ if not name:
106
+ raise WorksetError(f"workset.yaml in {root} has no 'name' key")
107
+ created = data.get("created", "")
108
+ group_auth = bool(data.get("group_auth", True))
109
+ projects = []
110
+ for entry in data.get("projects", []):
111
+ projects.append(
112
+ WorksetProject(
113
+ name=entry["name"],
114
+ source_path=Path(entry["source_path"]),
115
+ )
116
+ )
117
+ return Workset(name=name, root=root, created=created, projects=projects, group_auth=group_auth)
118
+
119
+
120
+ # ---------------------------------------------------------------------------
121
+ # Global registry: $XDG_DATA_HOME/kanibako/worksets.yaml
122
+ # ---------------------------------------------------------------------------
123
+
124
+ def _registry_path(std: StandardPaths) -> Path:
125
+ return std.ws_hints
126
+
127
+
128
+ def _load_registry(std: StandardPaths) -> dict[str, Path]:
129
+ """Return ``{name: root_path}`` from the global worksets registry."""
130
+ path = _registry_path(std)
131
+ if not path.is_file():
132
+ return {}
133
+ data = load_doc(path)
134
+ return {
135
+ name: Path(root)
136
+ for name, root in data.get("worksets", {}).items()
137
+ }
138
+
139
+
140
+ def _write_registry(std: StandardPaths, registry: dict[str, Path]) -> None:
141
+ """Overwrite the global worksets registry."""
142
+ path = _registry_path(std)
143
+ data: dict = {
144
+ "worksets": {name: str(registry[name]) for name in sorted(registry)},
145
+ }
146
+ dump_doc(path, data)
147
+
148
+
149
+ # ---------------------------------------------------------------------------
150
+ # Public API
151
+ # ---------------------------------------------------------------------------
152
+
153
+ def create_workset(name: str, root: Path, std: StandardPaths) -> Workset:
154
+ """Create a new workset directory structure and register it globally.
155
+
156
+ Raises ``WorksetError`` if *root* already exists or name is already
157
+ registered.
158
+ """
159
+ if not name:
160
+ raise WorksetError("Workset name must not be empty.")
161
+
162
+ if name in (DEFAULT_WORKSET_ID, DEFAULT_WORKSET_ALIAS):
163
+ raise WorksetError("'default' is reserved for the default workset.")
164
+
165
+ registry = _load_registry(std)
166
+ if name in registry:
167
+ raise WorksetError(
168
+ f"Workset '{name}' is already registered at {registry[name]}"
169
+ )
170
+
171
+ root = root.resolve()
172
+ if root.exists():
173
+ raise WorksetError(f"Workset root already exists: {root}")
174
+
175
+ # Create directory skeleton.
176
+ root.mkdir(parents=True)
177
+ for subdir in ("boxes", "workspaces", "vault"):
178
+ (root / subdir).mkdir()
179
+
180
+ ws = Workset(
181
+ name=name,
182
+ root=root,
183
+ created=datetime.now(timezone.utc).isoformat(),
184
+ )
185
+ _write_workset_toml(ws)
186
+
187
+ # Register globally.
188
+ registry[name] = root
189
+ _write_registry(std, registry)
190
+
191
+ # Register in the name index for name-based lookups.
192
+ register_name(std.data_path, name, str(root), section="worksets")
193
+
194
+ return ws
195
+
196
+
197
+ def load_workset(root: Path) -> Workset:
198
+ """Load a workset from its root directory.
199
+
200
+ Raises ``WorksetError`` if the directory or ``workset.yaml`` is missing.
201
+ """
202
+ root = root.resolve()
203
+ if not root.is_dir():
204
+ raise WorksetError(f"Workset root does not exist: {root}")
205
+ # Migrate old kanibako/ subdir to boxes/ if needed.
206
+ old_subdir = root / "kanibako"
207
+ new_subdir = root / "boxes"
208
+ if old_subdir.is_dir() and not new_subdir.exists():
209
+ old_subdir.rename(new_subdir)
210
+ import sys
211
+ print(f"Migrated workset: {old_subdir} → {new_subdir}", file=sys.stderr)
212
+ return _load_workset_toml(root)
213
+
214
+
215
+ def list_worksets(std: StandardPaths) -> dict[str, Path]:
216
+ """Return ``{name: root_path}`` for all registered worksets.
217
+
218
+ This returns ONLY the on-disk registry; the synthesized default workset is
219
+ never injected here.
220
+ """
221
+ return _load_registry(std)
222
+
223
+
224
+ def default_workset(std: StandardPaths) -> Workset:
225
+ """Synthesize the default workset (the group of default-mode projects).
226
+
227
+ The default workset is virtual: its members are the default-mode projects
228
+ in ``names.yaml [projects]`` and its ``group_auth`` lives as a normal key in
229
+ ``{data_path}/config.yaml``. This object is NEVER persisted to disk (no
230
+ workset.yaml / registry write).
231
+ """
232
+ projects_map = read_names(std.data_path).get("projects", {})
233
+ projects = [
234
+ WorksetProject(name=name, source_path=Path(path))
235
+ for name, path in projects_map.items()
236
+ ]
237
+
238
+ group_auth = True
239
+ config_path = std.data_path / "config.yaml"
240
+ if config_path.is_file():
241
+ data = load_doc(config_path)
242
+ # group_auth lives in the [project] section (see config.py loader);
243
+ # tolerate a top-level key too for robustness.
244
+ if "group_auth" in data.get("project", {}):
245
+ group_auth = bool(data["project"]["group_auth"])
246
+ elif "group_auth" in data:
247
+ group_auth = bool(data["group_auth"])
248
+
249
+ return Workset(
250
+ name=DEFAULT_WORKSET_ID,
251
+ root=std.data_path,
252
+ created="",
253
+ projects=projects,
254
+ group_auth=group_auth,
255
+ is_default=True,
256
+ )
257
+
258
+
259
+ def resolve_workset_name(name: str, std: StandardPaths) -> Workset:
260
+ """Resolve a workset *name* to a :class:`Workset`.
261
+
262
+ The names ``default`` / ``__default__`` resolve to the synthesized default
263
+ workset; any other name is looked up in the on-disk registry. Raises
264
+ ``WorksetError`` if the name is not registered.
265
+ """
266
+ if name in (DEFAULT_WORKSET_ID, DEFAULT_WORKSET_ALIAS):
267
+ return default_workset(std)
268
+ registry = _load_registry(std)
269
+ if name not in registry:
270
+ raise WorksetError(f"Working set '{name}' is not registered.")
271
+ return load_workset(registry[name])
272
+
273
+
274
+ def delete_workset(name: str, std: StandardPaths, *, remove_files: bool = False) -> Path:
275
+ """Unregister a workset and optionally remove its directory tree.
276
+
277
+ Returns the root path of the deleted workset.
278
+ Raises ``WorksetError`` if the name is not registered.
279
+ """
280
+ registry = _load_registry(std)
281
+ if name not in registry:
282
+ raise WorksetError(f"Workset '{name}' is not registered.")
283
+ root = registry.pop(name)
284
+ _write_registry(std, registry)
285
+
286
+ # Unregister from the name index.
287
+ unregister_name(std.data_path, name, section="worksets")
288
+
289
+ if remove_files and root.is_dir():
290
+ import shutil
291
+ shutil.rmtree(root)
292
+
293
+ return root
294
+
295
+
296
+ def add_project(ws: Workset, name: str, source_path: Path) -> WorksetProject:
297
+ """Add a project to a workset. Creates per-project subdirectories.
298
+
299
+ Raises ``WorksetError`` if a project with *name* already exists.
300
+ """
301
+ for p in ws.projects:
302
+ if p.name == name:
303
+ raise WorksetError(
304
+ f"Project '{name}' already exists in workset '{ws.name}'."
305
+ )
306
+
307
+ # Create per-project directories.
308
+ for parent in (ws.projects_dir, ws.workspaces_dir):
309
+ (parent / name).mkdir(parents=True, exist_ok=True)
310
+ vault_proj = ws.vault_dir / name
311
+ (vault_proj / "ro").mkdir(parents=True, exist_ok=True)
312
+ (vault_proj / "rw").mkdir(parents=True, exist_ok=True)
313
+
314
+ proj = WorksetProject(name=name, source_path=source_path.resolve())
315
+ ws.projects.append(proj)
316
+ _write_workset_toml(ws)
317
+ return proj
318
+
319
+
320
+ def remove_project(
321
+ ws: Workset, name: str, *, remove_files: bool = False,
322
+ ) -> WorksetProject:
323
+ """Remove a project from a workset.
324
+
325
+ Raises ``WorksetError`` if no project with *name* exists.
326
+ """
327
+ target = None
328
+ for p in ws.projects:
329
+ if p.name == name:
330
+ target = p
331
+ break
332
+ if target is None:
333
+ raise WorksetError(
334
+ f"Project '{name}' not found in workset '{ws.name}'."
335
+ )
336
+
337
+ ws.projects.remove(target)
338
+ _write_workset_toml(ws)
339
+
340
+ if remove_files:
341
+ import shutil
342
+ for parent in (ws.projects_dir, ws.workspaces_dir, ws.vault_dir):
343
+ proj_dir = parent / name
344
+ if proj_dir.is_dir():
345
+ shutil.rmtree(proj_dir)
346
+
347
+ return target
@@ -0,0 +1,15 @@
1
+ Metadata-Version: 2.4
2
+ Name: kanibako-cli
3
+ Version: 1.5.0.dev14
4
+ Summary: Run AI coding agents in rootless containers with per-project isolation
5
+ Requires-Python: >=3.11
6
+ License-File: LICENSE.md
7
+ Requires-Dist: argcomplete>=3.0
8
+ Requires-Dist: PyYAML>=6.0
9
+ Provides-Extra: dev
10
+ Requires-Dist: pytest>=7.0; extra == "dev"
11
+ Requires-Dist: pytest-cov; extra == "dev"
12
+ Requires-Dist: mypy; extra == "dev"
13
+ Requires-Dist: ruff; extra == "dev"
14
+ Requires-Dist: bump2version; extra == "dev"
15
+ Dynamic: license-file
@@ -0,0 +1,85 @@
1
+ kanibako/__init__.py,sha256=o5Ar_8UWXU2r-_miPQGhUTE2-fTjzD2A1EGvIDx6XPs,117
2
+ kanibako/__main__.py,sha256=84HrjUclvVwE-JnDEO8-hHLWlvP3C7Pk7gSNlVwKQwA,124
3
+ kanibako/auth_browser.py,sha256=glQ1kJ4MbyE8F7dpMYyxHeGXkfwxFRVMfnxLHkYq4cg,9374
4
+ kanibako/auth_parser.py,sha256=cGQx0j0hBdX6CqjAYtSKtvv61jyIOoimsBhJ2WtQBGQ,1429
5
+ kanibako/browser_sidecar.py,sha256=UxEom3i4kuwbtuAA3O9_aC5qit-wP6Rzind_xyK9Lq4,6103
6
+ kanibako/browser_state.py,sha256=moEzmoRmeMpchATGjLnDPxReBjJYiSZgV8suZetpcik,3136
7
+ kanibako/bun_sea.py,sha256=97_lzmsxVqY3IZ8Gjosaw_MbYxNJLyshBaHzJXzhAxM,4742
8
+ kanibako/cli.py,sha256=GdzE3C8kVeQVL3pbq-I5J-qnaDbpBNhWYkmP2B0HAfc,12445
9
+ kanibako/config.py,sha256=WJSOAFFYBWFtImWBy8xb_OmBKikPtn5wEzIzn3F9Kvc,17814
10
+ kanibako/config_interface.py,sha256=qM2I1tBaaJ9aAr18NyUEg7HnvzgDQPhzCkltxyZS7Jc,18027
11
+ kanibako/config_io.py,sha256=vn_XIgClJ0grRqoCIXiiP1g1K6XGzN1qs18KpXuKSK8,1301
12
+ kanibako/container.py,sha256=rw8m6FXQkdaOjm47ebNS5QkdS7Fa-hxQIFF7v4F_H7I,22209
13
+ kanibako/containerfiles.py,sha256=RD38L8AzkRnTATRKnElc7DcBAGQ7622dLDZwKuaqBwQ,1923
14
+ kanibako/crabs.py,sha256=ls0f7t6jgiUU9l3kXX6XirWlc-IhhmhRVJwqZb8ymcU,2723
15
+ kanibako/errors.py,sha256=ccuDYwHAXe8xa27qPBy7AgBY0KKBhncCmZAezhHDOts,785
16
+ kanibako/freshness.py,sha256=FygNZ7aw_h0nJKPmQLLjst4Y035rm6Iwa_p7Dcys9Q4,1937
17
+ kanibako/git.py,sha256=X_ZhgFodByT6tLaIktp5Ue-9JFygeWbie2igNakHijA,3191
18
+ kanibako/helper_client.py,sha256=KBf8Tvehosqe-k3idB2yxEXWSczMv8cfTDekbKK2Ycs,4612
19
+ kanibako/helper_listener.py,sha256=Nrr0LnyrSd9oxviHoVC0QEAcgUd2iohQr6M2r6qyuAk,19529
20
+ kanibako/helpers.py,sha256=3JgXvUxJ8oiaMGkhwh9Pn5aEfV10eF3otBMdO7RBuJM,11109
21
+ kanibako/hygiene.py,sha256=aR5ug7yC-nOL1X3dsG_efMQ4T8yxOEx_xHa5r1ip3NI,8373
22
+ kanibako/image_sharing.py,sha256=U0mJjG5p-OxOmwy1lwdqdRtQXjifpwvNgnxGg8U_qq4,4619
23
+ kanibako/instructions.py,sha256=emT_VIdZo8gj6cHoHbBIuRqt3_CHpDg-N87b9tiQg10,5927
24
+ kanibako/log.py,sha256=dQzpzymX2KdoyquENccH-2wnlEX7O857G95xK4_88NM,829
25
+ kanibako/names.py,sha256=7ckGFhjc7t1Tjj8lzwRL8ChpHIxyF4ySLF9Wopll5eg,7420
26
+ kanibako/paths.py,sha256=3AK9tg_Rpp4AANhmfjokV33VJGt9fRmgdVvou_semC8,54572
27
+ kanibako/registry.py,sha256=EE0IOY6skJt6cNvoQBcATjCdNic2XlYFnG4r43myfvc,2288
28
+ kanibako/rig_bundle.py,sha256=OsAQTd_Piub3-4RJrRgkghEjiLA-NfkoOTutxBV6v9c,4267
29
+ kanibako/rig_meta.py,sha256=meY-QXNhFNCBkI0FFXtSBv886Jn4ke1nbeZKgjI7tbM,3445
30
+ kanibako/rig_registry.py,sha256=EgMlQrx3g9ALrh3UeOUVvbNUjjpXK3o6KIg5c2-_fa4,4045
31
+ kanibako/rig_resolve.py,sha256=H6aEDlqdcxuVL-kEinOJ2BrRsLRJgM_QtdDg-J0hpX8,7398
32
+ kanibako/rig_source.py,sha256=W1bR3qewZroxC8_PP-ytcHlhBVkNZBjLhlsW-_Mpd3w,9312
33
+ kanibako/settings_resolve.py,sha256=sEma0HofaOIQVxMXGEARAyeNSQyuS2AyrfUB8jrxHPk,10492
34
+ kanibako/settings_seeds.py,sha256=__8y7S1AfL2SDu8HpJ5uwfCXW9gHXwLH0YeFfBekRcY,5849
35
+ kanibako/settings_shares.py,sha256=DD2wDV_x2SbyGSqehp4S-K9nw6xR4bbop6_pDMId26Q,6169
36
+ kanibako/shellenv.py,sha256=5fPJljXm3A6hRIgTq4IIWNfQH0Wc8uRl1lGDOldnhYw,2219
37
+ kanibako/snapshots.py,sha256=qqv856N2MAzCtd5nZhh8osVuYrFWTPGh5ikNzU7Uiek,9346
38
+ kanibako/templates.py,sha256=Ggnw4MBiXrLGjksmSFP2sXzrmNvBBOxW--8wGVOYrBA,1683
39
+ kanibako/templates_image.py,sha256=ZlfKTHRQr6SNZfiJkSXSrVitIZF05mpJPC-bTqIcV14,8426
40
+ kanibako/tweakcc.py,sha256=HCi1tEcQP1pZit5_Rvfa8JDBnkBtLOWIn62YDA9k5Qo,4363
41
+ kanibako/tweakcc_cache.py,sha256=idgaeeQ0pUxGiN8h7HdMGeMKNiqhxAuW414YxXWl2Vc,5673
42
+ kanibako/utils.py,sha256=PXr1-Qbl6ByJTwhP66hrarWgDs2wrsGdwUGmUAhfOfw,4106
43
+ kanibako/workset.py,sha256=2vPpX8sU_hdW2g5n-oyoyaoF8EpG_JtS5aJ437gu0c4,11454
44
+ kanibako/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
45
+ kanibako/commands/archive.py,sha256=ZphHMYBkO3RtAbM-iFdt7Bdbbeijg7D7-jNfDF5qn7Y,8080
46
+ kanibako/commands/clean.py,sha256=REkr-i0HFAJIVkrYmbNEwESTxrAKdwS-3nqtxnuSkEE,5483
47
+ kanibako/commands/crab_cmd.py,sha256=UHRDKn1Z5zf58sFmfdedMqUbqM6RadyrtE93iMRzGYY,14757
48
+ kanibako/commands/diagnose.py,sha256=4CpyteGfXNvR_CqhlTf-h41SdjqvJ2U-jvzBtyUjcEg,7706
49
+ kanibako/commands/fork_cmd.py,sha256=Yx2eiqsKJaYwWxTNdE4DgaFTQ5cAqWG9YIZS0NDCZv4,1578
50
+ kanibako/commands/helper_cmd.py,sha256=CLhiGmdGq9sjhV58lGi0X7bDBhinQntWjyzMWQlRnYM,21535
51
+ kanibako/commands/image.py,sha256=pY7Pc6Rpfxnuow2U_oVgS-W8sKFD5RLGs-cPkAZlcuQ,46398
52
+ kanibako/commands/install.py,sha256=cwruTSh0TSu9wNaXiOOBAm6-E-0uAXyipkGjGbwMplQ,5883
53
+ kanibako/commands/refresh_credentials.py,sha256=2W5vzDIWp55Dk0jvpI5YrWO6jTOmzAONyEQZ7HkCqsI,2313
54
+ kanibako/commands/restore.py,sha256=zMOxtxtX77ZImUaFYTqYsy2uPFMVyD5crFuQts1zU9E,9883
55
+ kanibako/commands/setup_cmd.py,sha256=K1Rx-kKHRh-qxqVZGNxtPVuVhSBg7KNHx8uEcrC99b8,2802
56
+ kanibako/commands/start.py,sha256=AZGDVTDeXLLKKtu0eO4mKJnuLLkzm-WyE6-zOS0LYLo,61373
57
+ kanibako/commands/stop.py,sha256=FFmpwvukuvhy2RuiJEZhi3EMYEdfkbNMIH5snHLbS0w,3877
58
+ kanibako/commands/system_cmd.py,sha256=oCg6upiT8KJ1NyDwUdQ2Q3mLV0rDirwgvomVA04V8ws,6443
59
+ kanibako/commands/upgrade.py,sha256=u7v_YB_vDfdLP1DZOe7rsj-UoYyCrLHbKcvUuQ1koIE,4921
60
+ kanibako/commands/vault_cmd.py,sha256=QS3uPm-vxdXWfBGOySIDrit__YGAsitBnG-a28v4zKs,6130
61
+ kanibako/commands/workset_cmd.py,sha256=uzY9ShrJkbZcCCAST7jwNhM2NPWfyv1clwpyeJp0RHU,18546
62
+ kanibako/commands/box/__init__.py,sha256=OU6-KyqgVRgCuIvm0PS-qLinDx_tgspuohnsykkdwj0,675
63
+ kanibako/commands/box/_duplicate.py,sha256=4HEqs44B3pIySmGxnHdHCWS-KzYYbS-DQ5ZjLD9wxvw,13982
64
+ kanibako/commands/box/_migrate.py,sha256=iVlBpQIM65he4cNLdicVBNhw9GyjCqyFWJzPEgfLRMQ,20547
65
+ kanibako/commands/box/_parser.py,sha256=aOG1OlRGhu556cqFk2jdy60sjHLhUXzsS8cupQK6dKw,42086
66
+ kanibako/containers/Containerfile.kanibako,sha256=TVlJrvaEmSFGUITcAi1-u8iaqGrzfNuYf0gVkBbJpIA,3962
67
+ kanibako/containers/Containerfile.template-android,sha256=e6gEdSel7lGU5Gwc3vGPsWGNe956Jaax0ARz4U-ZYbc,2243
68
+ kanibako/containers/Containerfile.template-dotnet,sha256=Gj9ttJYf6Eyo2KRnl1u-gKXYlLwLm1KIZ0phvfEXbog,1124
69
+ kanibako/containers/Containerfile.template-js,sha256=qZ7icOhDXaeJco40bGGwBCVrWkDUjt97W4t6LhbrOVw,1925
70
+ kanibako/containers/Containerfile.template-jvm,sha256=Bawt6H5J0GWjZ_KDQTENURz07Metu1Y6CZZsDm59LOI,894
71
+ kanibako/containers/Containerfile.template-systems,sha256=nXEl8-cDsHV7O7DjNwt7bC2jRiuQDKrdTzsmE5rrBME,1577
72
+ kanibako/containers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
73
+ kanibako/plugins/__init__.py,sha256=AneQXwqYi6x0RgeBIdB_lY18kOCeOWYDGfSCUbAVxx0,305
74
+ kanibako/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
75
+ kanibako/scripts/helper-init.sh,sha256=YyQiTyRfbcHMr0TpATshl7DB8mNIBDsiweFrcrAaawk,1452
76
+ kanibako/scripts/kanibako-entry,sha256=7jZwTCprGrzNLntZ9bUq63Z4JNFeFXksZV8gLb-Kt8M,331
77
+ kanibako/targets/__init__.py,sha256=DX9Y86HhF9pkoeMMiJRASUwuN2RYzPpx-x0YYBbn2W8,5969
78
+ kanibako/targets/base.py,sha256=655X464foHr57g-vlh9mYf58OhInLBoxv_PkxyEpCqQ,8527
79
+ kanibako/targets/no_agent.py,sha256=uCZyQr6JHI-3a9drrydkkOWwN7ZponGP_fqddYBqmbo,1367
80
+ kanibako_cli-1.5.0.dev14.dist-info/licenses/LICENSE.md,sha256=myGniuZJOzblT1ZUaSVj9hNBLxPw3J80w6xujEYC_4c,34904
81
+ kanibako_cli-1.5.0.dev14.dist-info/METADATA,sha256=DYDpYO3xn0IFZMszmFxqHlDjyT9FzABvmDzQte8DCO0,493
82
+ kanibako_cli-1.5.0.dev14.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
83
+ kanibako_cli-1.5.0.dev14.dist-info/entry_points.txt,sha256=aG14qO1FbqJ_f8KzitcMA88_sRhqDNkp0MYPr9YP__c,117
84
+ kanibako_cli-1.5.0.dev14.dist-info/top_level.txt,sha256=-PkDK596XDYjXbzCXsH42eRlwpGGJFN_mKFqpiklbCs,9
85
+ kanibako_cli-1.5.0.dev14.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,5 @@
1
+ [console_scripts]
2
+ kanibako = kanibako.cli:main
3
+
4
+ [kanibako.agents]
5
+ no_agent = kanibako.targets.no_agent:NoAgentTarget