god-code 0.1.4__tar.gz → 0.1.6__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 (82) hide show
  1. {god_code-0.1.4 → god_code-0.1.6}/PKG-INFO +1 -1
  2. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/cli.py +104 -13
  3. {god_code-0.1.4 → god_code-0.1.6}/pyproject.toml +1 -1
  4. {god_code-0.1.4 → god_code-0.1.6}/.github/workflows/publish.yml +0 -0
  5. {god_code-0.1.4 → god_code-0.1.6}/.gitignore +0 -0
  6. {god_code-0.1.4 → god_code-0.1.6}/CHANGELOG.md +0 -0
  7. {god_code-0.1.4 → god_code-0.1.6}/CLAUDE.md +0 -0
  8. {god_code-0.1.4 → god_code-0.1.6}/CONTRIBUTING.md +0 -0
  9. {god_code-0.1.4 → god_code-0.1.6}/LICENSE +0 -0
  10. {god_code-0.1.4 → god_code-0.1.6}/README.md +0 -0
  11. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/__init__.py +0 -0
  12. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/godot/__init__.py +0 -0
  13. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/godot/collision_planner.py +0 -0
  14. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/godot/consistency_checker.py +0 -0
  15. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/godot/dependency_graph.py +0 -0
  16. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/godot/gdscript_linter.py +0 -0
  17. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/godot/pattern_advisor.py +0 -0
  18. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/godot/project.py +0 -0
  19. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/godot/resource_validator.py +0 -0
  20. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/godot/scene_parser.py +0 -0
  21. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/godot/scene_writer.py +0 -0
  22. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/godot/tscn_validator.py +0 -0
  23. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/llm/__init__.py +0 -0
  24. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/llm/client.py +0 -0
  25. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/llm/streaming.py +0 -0
  26. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/llm/vision.py +0 -0
  27. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/prompts/__init__.py +0 -0
  28. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/prompts/build_discipline.py +0 -0
  29. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/prompts/godot_playbook.py +0 -0
  30. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/prompts/knowledge_selector.py +0 -0
  31. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/prompts/system.py +0 -0
  32. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/py.typed +0 -0
  33. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/runtime/__init__.py +0 -0
  34. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/runtime/auth.py +0 -0
  35. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/runtime/config.py +0 -0
  36. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/runtime/context_manager.py +0 -0
  37. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/runtime/engine.py +0 -0
  38. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/runtime/error_loop.py +0 -0
  39. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/runtime/oauth.py +0 -0
  40. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/runtime/session.py +0 -0
  41. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/tools/__init__.py +0 -0
  42. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/tools/base.py +0 -0
  43. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/tools/file_ops.py +0 -0
  44. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/tools/git.py +0 -0
  45. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/tools/godot_cli.py +0 -0
  46. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/tools/list_dir.py +0 -0
  47. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/tools/registry.py +0 -0
  48. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/tools/screenshot.py +0 -0
  49. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/tools/search.py +0 -0
  50. {god_code-0.1.4 → god_code-0.1.6}/godot_agent/tools/shell.py +0 -0
  51. {god_code-0.1.4 → god_code-0.1.6}/tests/__init__.py +0 -0
  52. {god_code-0.1.4 → god_code-0.1.6}/tests/godot/__init__.py +0 -0
  53. {god_code-0.1.4 → god_code-0.1.6}/tests/godot/test_collision_planner.py +0 -0
  54. {god_code-0.1.4 → god_code-0.1.6}/tests/godot/test_consistency.py +0 -0
  55. {god_code-0.1.4 → god_code-0.1.6}/tests/godot/test_dependency_graph.py +0 -0
  56. {god_code-0.1.4 → god_code-0.1.6}/tests/godot/test_linter.py +0 -0
  57. {god_code-0.1.4 → god_code-0.1.6}/tests/godot/test_pattern_advisor.py +0 -0
  58. {god_code-0.1.4 → god_code-0.1.6}/tests/godot/test_project.py +0 -0
  59. {god_code-0.1.4 → god_code-0.1.6}/tests/godot/test_resource_validator.py +0 -0
  60. {god_code-0.1.4 → god_code-0.1.6}/tests/godot/test_scene_parser.py +0 -0
  61. {god_code-0.1.4 → god_code-0.1.6}/tests/godot/test_scene_writer.py +0 -0
  62. {god_code-0.1.4 → god_code-0.1.6}/tests/godot/test_tscn_validator.py +0 -0
  63. {god_code-0.1.4 → god_code-0.1.6}/tests/llm/__init__.py +0 -0
  64. {god_code-0.1.4 → god_code-0.1.6}/tests/llm/test_client.py +0 -0
  65. {god_code-0.1.4 → god_code-0.1.6}/tests/llm/test_vision.py +0 -0
  66. {god_code-0.1.4 → god_code-0.1.6}/tests/prompts/__init__.py +0 -0
  67. {god_code-0.1.4 → god_code-0.1.6}/tests/prompts/test_knowledge_selector.py +0 -0
  68. {god_code-0.1.4 → god_code-0.1.6}/tests/prompts/test_system_prompt.py +0 -0
  69. {god_code-0.1.4 → god_code-0.1.6}/tests/runtime/__init__.py +0 -0
  70. {god_code-0.1.4 → god_code-0.1.6}/tests/runtime/test_config.py +0 -0
  71. {god_code-0.1.4 → god_code-0.1.6}/tests/runtime/test_context_manager.py +0 -0
  72. {god_code-0.1.4 → god_code-0.1.6}/tests/runtime/test_engine.py +0 -0
  73. {god_code-0.1.4 → god_code-0.1.6}/tests/runtime/test_error_loop.py +0 -0
  74. {god_code-0.1.4 → god_code-0.1.6}/tests/test_e2e.py +0 -0
  75. {god_code-0.1.4 → god_code-0.1.6}/tests/tools/__init__.py +0 -0
  76. {god_code-0.1.4 → god_code-0.1.6}/tests/tools/test_file_ops.py +0 -0
  77. {god_code-0.1.4 → god_code-0.1.6}/tests/tools/test_git.py +0 -0
  78. {god_code-0.1.4 → god_code-0.1.6}/tests/tools/test_godot_cli.py +0 -0
  79. {god_code-0.1.4 → god_code-0.1.6}/tests/tools/test_list_dir.py +0 -0
  80. {god_code-0.1.4 → god_code-0.1.6}/tests/tools/test_registry.py +0 -0
  81. {god_code-0.1.4 → god_code-0.1.6}/tests/tools/test_search.py +0 -0
  82. {god_code-0.1.4 → god_code-0.1.6}/tests/tools/test_shell.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: god-code
3
- Version: 0.1.4
3
+ Version: 0.1.6
4
4
  Summary: AI coding agent specialized for Godot game development
5
5
  Project-URL: Homepage, https://github.com/chuisiufai/god-code
6
6
  Project-URL: Repository, https://github.com/chuisiufai/god-code
@@ -195,18 +195,36 @@ def _run_setup_wizard() -> None:
195
195
  click.echo()
196
196
 
197
197
 
198
+ _VERSION = "0.1.5"
199
+
200
+
201
+ def _check_update() -> None:
202
+ """Check PyPI for a newer version. Non-blocking, fails silently."""
203
+ try:
204
+ import httpx as _httpx
205
+ resp = _httpx.get("https://pypi.org/pypi/god-code/json", timeout=3)
206
+ if resp.status_code == 200:
207
+ latest = resp.json()["info"]["version"]
208
+ if latest != _VERSION:
209
+ click.secho(f" Update available: {_VERSION} → {latest}", fg="yellow")
210
+ click.echo(f" Run: pip install --upgrade god-code")
211
+ click.echo()
212
+ except Exception:
213
+ pass
214
+
215
+
198
216
  @click.group(invoke_without_command=True)
199
- @click.version_option(version="0.1.0")
217
+ @click.version_option(version=_VERSION)
200
218
  @click.pass_context
201
219
  def main(ctx):
202
220
  """God Code -- AI coding assistant for Godot game development."""
203
221
  logging.basicConfig(level=logging.WARNING, format="%(message)s")
222
+ _check_update()
204
223
  if ctx.invoked_subcommand is None:
205
224
  if not _is_configured():
206
225
  _run_setup_wizard()
207
226
  else:
208
- # No subcommand but already configured — show help
209
- click.echo(ctx.get_help())
227
+ ctx.invoke(chat)
210
228
 
211
229
 
212
230
  @main.command()
@@ -285,38 +303,111 @@ def ask(prompt: str, project: str, config: str | None, image: tuple[str, ...]):
285
303
  @main.command()
286
304
  @click.option("--project", "-p", default=".", help="Path to Godot project root")
287
305
  @click.option("--config", "-c", default=None, help="Path to config file")
288
- def chat(project: str, config: str | None):
306
+ def chat(project: str = ".", config: str | None = None):
289
307
  """Start an interactive chat session."""
290
308
  cfg = load_config(Path(config) if config else default_config_path())
291
309
  if not cfg.api_key and not cfg.oauth_token:
292
310
  click.secho("Not configured. Run 'god-code setup' first.", fg="yellow", err=True)
293
311
  raise SystemExit(1)
312
+
294
313
  project_root = Path(project).resolve()
295
- engine = build_engine(cfg, project_root)
296
314
  session_id = str(uuid.uuid4())[:8]
297
315
 
316
+ # Detect Godot project
317
+ has_project = (project_root / "project.godot").exists()
318
+
298
319
  click.echo()
299
- click.secho(f" God Code v0.1.0", fg="cyan", bold=True)
300
- click.echo(f" Session: {session_id}")
301
- click.echo(f" Project: {project_root}")
302
- click.echo(f" Model: {cfg.model}")
320
+ click.secho(" God Code", fg="cyan", bold=True)
321
+ click.echo(f" Session: {session_id} | Model: {cfg.model}")
322
+ if has_project:
323
+ from godot_agent.godot.project import parse_project_godot
324
+ proj = parse_project_godot(project_root / "project.godot")
325
+ click.echo(f" Project: {proj.name} ({project_root})")
326
+ else:
327
+ click.echo(f" Working dir: {project_root}")
328
+ click.secho(" No project.godot found. Use /cd to navigate to a Godot project.", fg="yellow")
303
329
  click.echo()
304
- click.echo(" Commands: 'quit' to exit, 'save' to save session")
330
+ click.echo(" /cd <path> — change project directory")
331
+ click.echo(" /info — show project info")
332
+ click.echo(" /help — show commands")
333
+ click.echo(" /save — save session")
334
+ click.echo(" /quit — exit")
305
335
  click.echo()
306
336
 
337
+ engine = build_engine(cfg, project_root)
338
+
339
+ def _rebuild_engine(new_root: Path) -> ConversationEngine:
340
+ nonlocal project_root, has_project
341
+ project_root = new_root.resolve()
342
+ has_project = (project_root / "project.godot").exists()
343
+ return build_engine(cfg, project_root)
344
+
307
345
  async def _loop() -> None:
346
+ nonlocal engine
308
347
  try:
309
348
  while True:
310
349
  try:
311
- user_input = click.prompt(click.style("you", fg="green"), prompt_suffix="> ")
350
+ user_input = click.prompt(
351
+ click.style("you", fg="green"), prompt_suffix="> "
352
+ )
312
353
  except (EOFError, KeyboardInterrupt):
313
354
  break
314
- if user_input.strip().lower() == "quit":
355
+
356
+ cmd = user_input.strip().lower()
357
+
358
+ if cmd in ("/quit", "quit", "/exit", "exit"):
315
359
  break
316
- if user_input.strip().lower() == "save":
360
+
361
+ if cmd in ("/save", "save"):
317
362
  path = save_session(cfg.session_dir, session_id, engine.messages)
318
363
  click.echo(f" Session saved to {path}")
319
364
  continue
365
+
366
+ if cmd == "/help":
367
+ click.echo(" /cd <path> — change project directory")
368
+ click.echo(" /info — show project info")
369
+ click.echo(" /save — save session")
370
+ click.echo(" /status — show auth & model info")
371
+ click.echo(" /quit — exit")
372
+ continue
373
+
374
+ if cmd == "/info":
375
+ if has_project:
376
+ from godot_agent.godot.project import parse_project_godot
377
+ proj = parse_project_godot(project_root / "project.godot")
378
+ click.echo(f" Project: {proj.name}")
379
+ click.echo(f" Version: {proj.version}")
380
+ click.echo(f" Main Scene: {proj.main_scene}")
381
+ click.echo(f" Resolution: {proj.viewport_width}x{proj.viewport_height}")
382
+ click.echo(f" Autoloads: {len(proj.autoloads)}")
383
+ else:
384
+ click.secho(f" No project.godot in {project_root}", fg="yellow")
385
+ continue
386
+
387
+ if cmd == "/status":
388
+ click.echo(f" Model: {cfg.model}")
389
+ click.echo(f" Project: {project_root}")
390
+ click.echo(f" Godot: {cfg.godot_path}")
391
+ continue
392
+
393
+ if user_input.strip().startswith("/cd "):
394
+ new_path = Path(user_input.strip()[4:]).expanduser().resolve()
395
+ if not new_path.exists():
396
+ click.secho(f" Path not found: {new_path}", fg="red")
397
+ continue
398
+ await engine.close()
399
+ engine = _rebuild_engine(new_path)
400
+ has_godot = (new_path / "project.godot").exists()
401
+ if has_godot:
402
+ from godot_agent.godot.project import parse_project_godot
403
+ proj = parse_project_godot(new_path / "project.godot")
404
+ click.secho(f" Switched to: {proj.name} ({new_path})", fg="green")
405
+ else:
406
+ click.echo(f" Working dir: {new_path}")
407
+ click.secho(" No project.godot found here.", fg="yellow")
408
+ continue
409
+
410
+ # Regular message → send to LLM
320
411
  response = await engine.submit(user_input)
321
412
  click.echo()
322
413
  click.echo(click.style("agent> ", fg="cyan") + response)
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "god-code"
3
- version = "0.1.4"
3
+ version = "0.1.6"
4
4
  description = "AI coding agent specialized for Godot game development"
5
5
  requires-python = ">=3.9"
6
6
  license = {text = "GPL-3.0-or-later"}
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes