kiwi-code 0.0.442__tar.gz → 0.0.444__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 (68) hide show
  1. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/PKG-INFO +1 -1
  2. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/pyproject.toml +1 -1
  3. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_cli/__init__.py +1 -1
  4. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_cli/cli.py +14 -38
  5. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_cli/commands.py +1 -160
  6. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_runtime/__init__.py +1 -1
  7. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_runtime/main.py +287 -33
  8. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_tui/__init__.py +1 -1
  9. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_tui/main.py +5 -0
  10. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_tui/screens/dashboard.py +4 -360
  11. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_tui/screens/term_dashboard.py +166 -14
  12. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_tui/slash_commands.py +1 -5
  13. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/tests/test_term_dashboard_ui.py +142 -0
  14. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/uv.lock +1 -1
  15. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/.github/workflows/publish.yml +0 -0
  16. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/.github/workflows/test.yml +0 -0
  17. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/.gitignore +0 -0
  18. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/.python-version +0 -0
  19. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/CLAUDE.md +0 -0
  20. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/Makefile +0 -0
  21. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/README.md +0 -0
  22. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_cli/auth.py +0 -0
  23. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_cli/checkpoints.py +0 -0
  24. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_cli/client.py +0 -0
  25. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_cli/logger.py +0 -0
  26. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_cli/models.py +0 -0
  27. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_cli/runtime_manager.py +0 -0
  28. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_cli/server.py +0 -0
  29. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_cli/terminal_mode.py +0 -0
  30. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_runtime/__main__.py +0 -0
  31. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_tui/inline_file_picker.py +0 -0
  32. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_tui/random_words.py +0 -0
  33. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_tui/runtime_agent.py +0 -0
  34. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_tui/screens/__init__.py +0 -0
  35. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_tui/screens/attach_content.py +0 -0
  36. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_tui/screens/command_result.py +0 -0
  37. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_tui/screens/detach_files.py +0 -0
  38. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_tui/screens/file_browser.py +0 -0
  39. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_tui/screens/help.py +0 -0
  40. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_tui/screens/id_picker.py +0 -0
  41. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_tui/screens/login.py +0 -0
  42. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_tui/screens/runtime_cleanup.py +0 -0
  43. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_tui/screens/runtime_logs.py +0 -0
  44. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_tui/screens/slash_picker.py +0 -0
  45. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_tui/status_words.py +0 -0
  46. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_tui/term_app.py +0 -0
  47. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_tui/widgets.py +0 -0
  48. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/src/kiwi_tui/worktrees.py +0 -0
  49. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/test_hello.py +0 -0
  50. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/tests/__init__.py +0 -0
  51. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/tests/conftest.py +0 -0
  52. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/tests/test_batch_fs_tool.py +0 -0
  53. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/tests/test_checkpoints.py +0 -0
  54. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/tests/test_cli_help.py +0 -0
  55. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/tests/test_copy_path_fs_tool.py +0 -0
  56. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/tests/test_imports.py +0 -0
  57. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/tests/test_read_file_streaming.py +0 -0
  58. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/tests/test_reexec_kiwi.py +0 -0
  59. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/tests/test_runtime_log_trimming.py +0 -0
  60. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/tests/test_search_in_files_fs_tool.py +0 -0
  61. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/tests/test_slash_commands.py +0 -0
  62. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/tests/test_terminal_mode.py +0 -0
  63. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/tests/test_tokens.py +0 -0
  64. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/tests/test_tui_headless.py +0 -0
  65. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/tests/test_tui_interactive_runtime.py +0 -0
  66. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/tests/test_tui_palette.py +0 -0
  67. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/tests/test_unified_diff.py +0 -0
  68. {kiwi_code-0.0.442 → kiwi_code-0.0.444}/tests/test_worktrees.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kiwi-code
3
- Version: 0.0.442
3
+ Version: 0.0.444
4
4
  Summary: A textual-based terminal user interface application
5
5
  Project-URL: Homepage, https://meetkiwi.ai
6
6
  Project-URL: Repository, https://github.com/jetoslabs/kiwi-code
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "kiwi-code"
3
- version = "0.0.442"
3
+ version = "0.0.444"
4
4
  description = "A textual-based terminal user interface application"
5
5
  readme = {file = "README.md", content-type = "text/markdown"}
6
6
  requires-python = ">=3.11,<4.0"
@@ -1,3 +1,3 @@
1
1
  """Kiwi CLI - command-line interface and shared infrastructure modules."""
2
2
 
3
- __version__ = "0.0.442"
3
+ __version__ = "0.0.444"
@@ -8,23 +8,26 @@ from .auth import TokenManager
8
8
  from .models import AppConfig
9
9
  from .server import http_url_from_server
10
10
  from . import commands
11
+ from . import __version__ as KIWI_CLI_VERSION
11
12
 
12
13
  app = typer.Typer(name="kiwi", help="Kiwi — interact with the Kiwi AI platform.")
13
14
 
14
15
  actions_app = typer.Typer(name="actions", help="Manage actions.")
15
16
  action_runs_app = typer.Typer(name="runs", help="Manage action runs (results).")
16
- graphs_app = typer.Typer(name="graphs", help="Manage action graphs.")
17
- graph_runs_app = typer.Typer(name="graph-runs", help="Manage action graph runs (results).")
18
17
 
19
18
  app.add_typer(actions_app)
20
19
  app.add_typer(action_runs_app)
21
- app.add_typer(graphs_app)
22
- app.add_typer(graph_runs_app)
23
20
 
24
21
  # NOTE: kiwi-runtime is a standalone executable; this CLI does not manage it.
25
22
 
26
23
  _SERVER: str | None = None
27
24
 
25
+ def _version_callback(value: bool) -> None:
26
+ if value:
27
+ typer.echo(f"kiwicli {KIWI_CLI_VERSION}")
28
+ raise typer.Exit()
29
+
30
+
28
31
  @app.callback()
29
32
  def _main(
30
33
  server: Optional[str] = typer.Option(
@@ -35,6 +38,13 @@ def _main(
35
38
  "or a full URL (e.g. https://custom.server.com)."
36
39
  ),
37
40
  ),
41
+ version: Optional[bool] = typer.Option(
42
+ None,
43
+ "--version",
44
+ callback=_version_callback,
45
+ is_eager=True,
46
+ help="Show version and exit.",
47
+ ),
38
48
  ):
39
49
  """Global options for `kiwicli`."""
40
50
  global _SERVER
@@ -181,40 +191,6 @@ def runs_get_cmd(id: str = typer.Argument(help="Action run ID")):
181
191
  _print(_run_with_refresh_retry(lambda c: commands.runs_get(c, id=id)))
182
192
 
183
193
 
184
- # -- graphs -----------------------------------------------------------------
185
-
186
- @graphs_app.command("list")
187
- def graphs_list_cmd(
188
- name: Optional[str] = typer.Option(None, help="Filter by name"),
189
- limit: int = typer.Option(20, help="Max results"),
190
- offset: int = typer.Option(0, help="Offset"),
191
- ):
192
- """List action graphs."""
193
- _print(_run_with_refresh_retry(lambda c: commands.graphs_list(c, name=name, limit=limit, offset=offset)))
194
-
195
- @graphs_app.command("get")
196
- def graphs_get_cmd(id: str = typer.Argument(help="Action graph ID")):
197
- """Get action graph details."""
198
- _print(_run_with_refresh_retry(lambda c: commands.graphs_get(c, id=id)))
199
-
200
-
201
- # -- graph-runs -------------------------------------------------------------
202
-
203
- @graph_runs_app.command("list")
204
- def graph_runs_list_cmd(
205
- graph_id: Optional[str] = typer.Option(None, "--graph-id", help="Filter by graph ID"),
206
- graph_name: Optional[str] = typer.Option(None, "--graph-name", help="Filter by graph name"),
207
- status: Optional[str] = typer.Option(None, help="Filter by status"),
208
- limit: int = typer.Option(20, help="Max results"),
209
- offset: int = typer.Option(0, help="Offset"),
210
- ):
211
- """List action graph runs (results)."""
212
- _print(_run_with_refresh_retry(lambda c: commands.graph_runs_list(c, action_graph_id=graph_id, action_graph_name=graph_name, status=status, limit=limit, offset=offset)))
213
-
214
- @graph_runs_app.command("get")
215
- def graph_runs_get_cmd(id: str = typer.Argument(help="Graph run ID")):
216
- """Get action graph run details."""
217
- _print(_run_with_refresh_retry(lambda c: commands.graph_runs_get(c, id=id)))
218
194
 
219
195
 
220
196
  # -- runtime ----------------------------------------------------------------
@@ -14,14 +14,7 @@ from autobots_client.api.action_results import (
14
14
  list_action_result_v1_action_results_get,
15
15
  get_action_result_v1_action_results_id_get,
16
16
  )
17
- from autobots_client.api.action_graphs import (
18
- list_action_graphs_v1_action_graphs_get,
19
- get_action_graph_v1_action_graphs_id_get,
20
- )
21
- from autobots_client.api.action_graphs_results import (
22
- list_action_graph_result_v1_action_graphs_results_get,
23
- get_action_graph_result_v1_action_graphs_results_id_get,
24
- )
17
+
25
18
  from autobots_client.types import UNSET
26
19
 
27
20
 
@@ -157,122 +150,7 @@ def runs_get(client: AuthenticatedClient, *, id: str) -> list[str]:
157
150
  return lines
158
151
 
159
152
 
160
- # graphs (action graphs)
161
-
162
- def graphs_list(client: AuthenticatedClient, *, name: Optional[str] = None, limit: int = 20, offset: int = 0) -> list[str]:
163
- """List action graphs. Returns output lines."""
164
- resp = list_action_graphs_v1_action_graphs_get.sync_detailed(
165
- client=client,
166
- name=name if name else UNSET,
167
- limit=limit,
168
- offset=offset,
169
- )
170
- if resp.status_code != 200:
171
- return [f"Error: HTTP {resp.status_code}"]
172
-
173
- result = resp.parsed
174
- lines = [
175
- f"Action Graphs ({result.total_count} total, showing {result.offset}-{result.offset + len(result.docs)}):",
176
- "",
177
- f"{'ID':<28} {'Name':<30} {'Ver':<6} {'Published':<10} {'Created'}",
178
- "-" * 105,
179
- ]
180
- for doc in result.docs:
181
- lines.append(
182
- f"{doc.field_id:<28} {_val(doc.name):<30} {_val(doc.version):<6} "
183
- f"{_val(doc.is_published):<10} {_fmt_date(doc.created_at)}"
184
- )
185
- return lines
186
-
187
-
188
- def graphs_get(client: AuthenticatedClient, *, id: str) -> list[str]:
189
- """Get action graph details. Returns output lines."""
190
- resp = get_action_graph_v1_action_graphs_id_get.sync_detailed(id=id, client=client)
191
- if resp.status_code != 200:
192
- return [f"Error: HTTP {resp.status_code}"]
193
-
194
- doc = resp.parsed
195
- if hasattr(doc, 'field_id'):
196
- return [
197
- f"ID: {doc.field_id}",
198
- f"Name: {_val(getattr(doc, 'name', ''))}",
199
- f"Version: {_val(getattr(doc, 'version', ''))}",
200
- f"Description: {_val(getattr(doc, 'description', ''))}",
201
- f"Published: {_val(getattr(doc, 'is_published', ''))}",
202
- f"Created: {_fmt_date(getattr(doc, 'created_at', None))}",
203
- f"Updated: {_fmt_date(getattr(doc, 'updated_at', None))}",
204
- ]
205
- import json
206
- if hasattr(doc, 'to_dict'):
207
- return [json.dumps(doc.to_dict(), indent=2, default=str)]
208
- return [str(doc)]
209
-
210
-
211
- # graph-runs (action graph results)
212
-
213
- def graph_runs_list(client: AuthenticatedClient, *, action_graph_id: Optional[str] = None,
214
- action_graph_name: Optional[str] = None, status: Optional[str] = None,
215
- limit: int = 20, offset: int = 0) -> list[str]:
216
- """List action graph runs. Returns output lines."""
217
- from autobots_client.models.event_result_status import EventResultStatus
218
-
219
- status_enum = UNSET
220
- if status:
221
- try:
222
- status_enum = EventResultStatus(status.lower())
223
- except ValueError:
224
- return [f"Invalid status: {status}. Valid: processing, success, error, stuck, waiting"]
225
-
226
- resp = list_action_graph_result_v1_action_graphs_results_get.sync_detailed(
227
- client=client,
228
- action_graph_id=action_graph_id if action_graph_id else UNSET,
229
- action_graph_name=action_graph_name if action_graph_name else UNSET,
230
- status=status_enum,
231
- limit=limit,
232
- offset=offset,
233
- )
234
- if resp.status_code != 200:
235
- return [f"Error: HTTP {resp.status_code}"]
236
-
237
- result = resp.parsed
238
- lines = [
239
- f"Action Graph Runs ({result.total_count} total, showing {result.offset}-{result.offset + len(result.docs)}):",
240
- "",
241
- f"{'ID':<28} {'Status':<12} {'Name':<30} {'Created':<18} {'Updated'}",
242
- "-" * 105,
243
- ]
244
- for doc in result.docs:
245
- lines.append(
246
- f"{doc.field_id:<28} {doc.status.value:<12} {_val(doc.name):<30} "
247
- f"{_fmt_date(doc.created_at):<18} {_fmt_date(doc.updated_at)}"
248
- )
249
- return lines
250
-
251
-
252
- def graph_runs_get(client: AuthenticatedClient, *, id: str) -> list[str]:
253
- """Get action graph run details. Returns output lines."""
254
- resp = get_action_graph_result_v1_action_graphs_results_id_get.sync_detailed(id=id, client=client)
255
- if resp.status_code != 200:
256
- return [f"Error: HTTP {resp.status_code}"]
257
153
 
258
- doc = resp.parsed
259
- lines = [
260
- f"ID: {doc.field_id}",
261
- f"Status: {doc.status.value}",
262
- f"Name: {_val(doc.name)}",
263
- f"Type: {doc.type_.value}",
264
- f"Saved: {_val(doc.is_saved)}",
265
- f"Created: {_fmt_date(doc.created_at)}",
266
- f"Updated: {_fmt_date(doc.updated_at)}",
267
- ]
268
- if doc.result and not isinstance(doc.result, type(UNSET)):
269
- lines += [
270
- "",
271
- "Action Graph:",
272
- f" Name: {doc.result.name}",
273
- f" ID: {doc.result.field_id}",
274
- ]
275
- return lines
276
154
 
277
155
 
278
156
  # Command dispatcher — parses "/command args" from TUI input
@@ -309,10 +187,6 @@ Query:
309
187
  /autocode-select Choose the version of AutoCode you wish to use
310
188
  /runs list [--action-id ID] [--status STATUS] [--limit N]
311
189
  /runs get <id>
312
- /graphs list [--name NAME] [--limit N]
313
- /graphs get <id>
314
- /graph-runs list [--graph-id ID] [--status STATUS] [--limit N]
315
- /graph-runs get <id>
316
190
 
317
191
  /help Show this help"""
318
192
 
@@ -400,39 +274,6 @@ def dispatch(command_str: str, client: AuthenticatedClient) -> list[str]:
400
274
  else:
401
275
  return ["Usage: /runs list | /runs get <id>"]
402
276
 
403
- elif group == "graphs":
404
- if sub == "list":
405
- return graphs_list(
406
- client,
407
- name=opts.get("name"),
408
- limit=_int(opts.get("limit", "20"), 20),
409
- offset=_int(opts.get("offset", "0"), 0),
410
- )
411
- elif sub == "get":
412
- pos = opts.get("_positional", [])
413
- if not pos:
414
- return ["Usage: /graphs get <id>"]
415
- return graphs_get(client, id=pos[0])
416
- else:
417
- return ["Usage: /graphs list | /graphs get <id>"]
418
-
419
- elif group in ("graph-runs", "graph_runs"):
420
- if sub == "list":
421
- return graph_runs_list(
422
- client,
423
- action_graph_id=opts.get("graph_id"),
424
- action_graph_name=opts.get("graph_name"),
425
- status=opts.get("status"),
426
- limit=_int(opts.get("limit", "20"), 20),
427
- offset=_int(opts.get("offset", "0"), 0),
428
- )
429
- elif sub == "get":
430
- pos = opts.get("_positional", [])
431
- if not pos:
432
- return ["Usage: /graph-runs get <id>"]
433
- return graph_runs_get(client, id=pos[0])
434
- else:
435
- return ["Usage: /graph-runs list | /graph-runs get <id>"]
436
277
 
437
278
  else:
438
279
  return [f"Unknown command: /{group}", "", HELP_TEXT]
@@ -1,3 +1,3 @@
1
1
  """Kiwi Runtime — terminal agent that connects to the server via WebSocket."""
2
2
 
3
- __version__ = "0.0.442"
3
+ __version__ = "0.0.444"