xdog-coding 2.1.0__tar.gz → 2.1.2__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 (80) hide show
  1. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/.gitignore +1 -2
  2. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/PKG-INFO +9 -9
  3. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/README.md +3 -3
  4. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/pyproject.toml +6 -6
  5. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/config.py +7 -7
  6. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/modes/interactive/components/custom_editor.py +7 -2
  7. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/tests/test_slash_skills.py +38 -0
  8. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/LICENSE +0 -0
  9. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/LICENSE-EXCEPTION.md +0 -0
  10. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/__init__.py +0 -0
  11. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/cli/__init__.py +0 -0
  12. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/cli/args.py +0 -0
  13. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/cli/config_selector.py +0 -0
  14. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/cli/file_processor.py +0 -0
  15. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/cli/initial_message.py +0 -0
  16. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/cli/list_models.py +0 -0
  17. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/cli/session_picker.py +0 -0
  18. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/core/__init__.py +0 -0
  19. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/core/agent_session.py +0 -0
  20. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/core/bash_executor.py +0 -0
  21. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/core/compaction/__init__.py +0 -0
  22. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/core/compaction/compaction.py +0 -0
  23. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/core/compaction/utils.py +0 -0
  24. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/core/defaults.py +0 -0
  25. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/core/event_bus.py +0 -0
  26. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/core/exec_utils.py +0 -0
  27. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/core/extensions/__init__.py +0 -0
  28. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/core/extensions/loader.py +0 -0
  29. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/core/extensions/runner.py +0 -0
  30. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/core/extensions/types.py +0 -0
  31. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/core/keybindings.py +0 -0
  32. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/core/messages.py +0 -0
  33. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/core/prompt_templates.py +0 -0
  34. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/core/resource_loader.py +0 -0
  35. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/core/sdk.py +0 -0
  36. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/core/session_manager.py +0 -0
  37. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/core/settings_manager.py +0 -0
  38. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/core/slash_commands.py +0 -0
  39. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/core/system_prompt.py +0 -0
  40. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/core/timings.py +0 -0
  41. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/core/tools/__init__.py +0 -0
  42. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/main.py +0 -0
  43. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/modes/__init__.py +0 -0
  44. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/modes/interactive/__init__.py +0 -0
  45. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/modes/interactive/components/__init__.py +0 -0
  46. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/modes/interactive/components/assistant_message.py +0 -0
  47. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/modes/interactive/components/chat_log.py +0 -0
  48. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/modes/interactive/components/footer.py +0 -0
  49. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/modes/interactive/components/tool_execution.py +0 -0
  50. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/modes/interactive/components/user_message.py +0 -0
  51. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/modes/interactive/interactive_mode.py +0 -0
  52. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/modes/interactive/theme.py +0 -0
  53. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/modes/print_mode.py +0 -0
  54. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/modes/rpc/__init__.py +0 -0
  55. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/modes/rpc/rpc_mode.py +0 -0
  56. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/py.typed +0 -0
  57. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/utils/__init__.py +0 -0
  58. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/utils/frontmatter.py +0 -0
  59. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/utils/git.py +0 -0
  60. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/utils/mime.py +0 -0
  61. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/utils/shell.py +0 -0
  62. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/src/xdog/coding/utils/sleep.py +0 -0
  63. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/tests/test_agent_session.py +0 -0
  64. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/tests/test_cli_args.py +0 -0
  65. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/tests/test_cli_config_selector.py +0 -0
  66. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/tests/test_cli_file_processor.py +0 -0
  67. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/tests/test_coding_config.py +0 -0
  68. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/tests/test_event_bus.py +0 -0
  69. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/tests/test_footer_context.py +0 -0
  70. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/tests/test_interactive_mode.py +0 -0
  71. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/tests/test_messages.py +0 -0
  72. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/tests/test_prompt_templates.py +0 -0
  73. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/tests/test_resource_loader.py +0 -0
  74. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/tests/test_rpc_mode.py +0 -0
  75. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/tests/test_session_manager.py +0 -0
  76. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/tests/test_session_smoke.py +0 -0
  77. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/tests/test_settings_manager.py +0 -0
  78. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/tests/test_slash_commands.py +0 -0
  79. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/tests/test_system_prompt.py +0 -0
  80. {xdog_coding-2.1.0 → xdog_coding-2.1.2}/tests/test_timings.py +0 -0
@@ -45,7 +45,7 @@ env/
45
45
  *credential*
46
46
  *secret*
47
47
  # --- OS / editor ---
48
- # --- x-dog ---
48
+ # --- xdog ---
49
49
  data/
50
50
  result.txt
51
51
  plan.txt
@@ -57,4 +57,3 @@ plan.txt
57
57
  /cli_agent_workflow.json
58
58
  /cli_agent_workflow.py
59
59
  /essay_writer.py
60
- runtime/
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: xdog-coding
3
- Version: 2.1.0
3
+ Version: 2.1.2
4
4
  Summary: Interactive coding agent CLI
5
5
  Project-URL: Homepage, https://xdog.942295.xyz
6
- Project-URL: Repository, https://github.com/litterzhang/x-dog
6
+ Project-URL: Repository, https://github.com/litterzhang/xdog
7
7
  Project-URL: Documentation, https://xdog.942295.xyz
8
- Project-URL: Issues, https://github.com/litterzhang/x-dog/issues
8
+ Project-URL: Issues, https://github.com/litterzhang/xdog/issues
9
9
  Author: HugeMan
10
10
  License-Expression: AGPL-3.0-or-later
11
11
  License-File: LICENSE
@@ -21,9 +21,9 @@ Requires-Python: >=3.12
21
21
  Requires-Dist: click>=8.1.0
22
22
  Requires-Dist: pydantic>=2.0
23
23
  Requires-Dist: pyyaml>=6.0
24
- Requires-Dist: xdog-agent>=2.1.0
25
- Requires-Dist: xdog-ai>=2.1.0
26
- Requires-Dist: xdog-tui>=2.1.0
24
+ Requires-Dist: xdog-agent>=2.1.2
25
+ Requires-Dist: xdog-ai>=2.1.2
26
+ Requires-Dist: xdog-tui>=2.1.2
27
27
  Description-Content-Type: text/markdown
28
28
 
29
29
  # xdog-coding
@@ -38,9 +38,9 @@ A terminal coding agent with session management, built on
38
38
  uv run xdog-coding
39
39
  ```
40
40
 
41
- ## Part of x-dog
41
+ ## Part of xdog
42
42
 
43
- This package is one piece of [x-dog](https://github.com/litterzhang/x-dog), a
43
+ This package is one piece of [xdog](https://github.com/litterzhang/xdog), a
44
44
  local-first toolkit for building, running and scheduling LLM workflows. The
45
45
  centrepiece is [`xdog-flow`](https://pypi.org/project/xdog-flow/) — a typed
46
46
  workflow format and compiler.
@@ -52,4 +52,4 @@ Documentation: **https://xdog.942295.xyz**
52
52
  Copyright (c) 2026 HugeMan <942295.xyz>
53
53
 
54
54
  GNU Affero General Public License v3.0 or later — see
55
- [LICENSE](https://github.com/litterzhang/x-dog/blob/main/LICENSE).
55
+ [LICENSE](https://github.com/litterzhang/xdog/blob/main/LICENSE).
@@ -10,9 +10,9 @@ A terminal coding agent with session management, built on
10
10
  uv run xdog-coding
11
11
  ```
12
12
 
13
- ## Part of x-dog
13
+ ## Part of xdog
14
14
 
15
- This package is one piece of [x-dog](https://github.com/litterzhang/x-dog), a
15
+ This package is one piece of [xdog](https://github.com/litterzhang/xdog), a
16
16
  local-first toolkit for building, running and scheduling LLM workflows. The
17
17
  centrepiece is [`xdog-flow`](https://pypi.org/project/xdog-flow/) — a typed
18
18
  workflow format and compiler.
@@ -24,4 +24,4 @@ Documentation: **https://xdog.942295.xyz**
24
24
  Copyright (c) 2026 HugeMan <942295.xyz>
25
25
 
26
26
  GNU Affero General Public License v3.0 or later — see
27
- [LICENSE](https://github.com/litterzhang/x-dog/blob/main/LICENSE).
27
+ [LICENSE](https://github.com/litterzhang/xdog/blob/main/LICENSE).
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "xdog-coding"
7
- version = "2.1.0"
7
+ version = "2.1.2"
8
8
  description = "Interactive coding agent CLI"
9
9
  requires-python = ">=3.12"
10
10
  classifiers = [
@@ -21,9 +21,9 @@ readme = "README.md"
21
21
  license = "AGPL-3.0-or-later"
22
22
  license-files = ["LICENSE", "LICENSE-EXCEPTION.md"]
23
23
  dependencies = [
24
- "xdog-ai>=2.1.0",
25
- "xdog-agent>=2.1.0",
26
- "xdog-tui>=2.1.0",
24
+ "xdog-ai>=2.1.2",
25
+ "xdog-agent>=2.1.2",
26
+ "xdog-tui>=2.1.2",
27
27
  "pyyaml>=6.0",
28
28
  "click>=8.1.0",
29
29
  "pydantic>=2.0",
@@ -31,9 +31,9 @@ dependencies = [
31
31
 
32
32
  [project.urls]
33
33
  Homepage = "https://xdog.942295.xyz"
34
- Repository = "https://github.com/litterzhang/x-dog"
34
+ Repository = "https://github.com/litterzhang/xdog"
35
35
  Documentation = "https://xdog.942295.xyz"
36
- Issues = "https://github.com/litterzhang/x-dog/issues"
36
+ Issues = "https://github.com/litterzhang/xdog/issues"
37
37
 
38
38
  [project.scripts]
39
39
  xdog-coding = "xdog.coding.main:main"
@@ -1,9 +1,9 @@
1
1
  """Global configuration and paths for the coding agent.
2
2
 
3
3
  Follows XDG Base Directory Specification:
4
- - Config: $XDG_CONFIG_HOME/x-dog/coding/ (settings, models, keybindings)
5
- - Data: $XDG_DATA_HOME/x-dog/coding/ (sessions, auth, extensions)
6
- - State: $XDG_STATE_HOME/x-dog/coding/ (logs, cache)
4
+ - Config: $XDG_CONFIG_HOME/xdog/coding/ (settings, models, keybindings)
5
+ - Data: $XDG_DATA_HOME/xdog/coding/ (sessions, auth, extensions)
6
+ - State: $XDG_STATE_HOME/xdog/coding/ (logs, cache)
7
7
  - Project: <cwd>/.coding/ (project-local config)
8
8
 
9
9
  Override all XDG paths with a single directory via CODING_DIR env var.
@@ -24,7 +24,7 @@ from pydantic import BaseModel, Field
24
24
  # Constants
25
25
  # ---------------------------------------------------------------------------
26
26
 
27
- MONOREPO_NAME = "x-dog"
27
+ MONOREPO_NAME = "xdog"
28
28
  APP_NAME = "coding"
29
29
  VERSION = "0.57.1"
30
30
  PROJECT_DIR_NAME = ".coding"
@@ -45,7 +45,7 @@ def _env_override_dir() -> Path | None:
45
45
 
46
46
 
47
47
  def get_config_dir() -> Path:
48
- """$XDG_CONFIG_HOME/x-dog/coding/"""
48
+ """$XDG_CONFIG_HOME/xdog/coding/"""
49
49
  override = _env_override_dir()
50
50
  if override is not None:
51
51
  return override
@@ -54,7 +54,7 @@ def get_config_dir() -> Path:
54
54
 
55
55
 
56
56
  def get_data_dir() -> Path:
57
- """$XDG_DATA_HOME/x-dog/coding/"""
57
+ """$XDG_DATA_HOME/xdog/coding/"""
58
58
  override = _env_override_dir()
59
59
  if override is not None:
60
60
  return override
@@ -63,7 +63,7 @@ def get_data_dir() -> Path:
63
63
 
64
64
 
65
65
  def get_state_dir() -> Path:
66
- """$XDG_STATE_HOME/x-dog/coding/"""
66
+ """$XDG_STATE_HOME/xdog/coding/"""
67
67
  override = _env_override_dir()
68
68
  if override is not None:
69
69
  return override
@@ -4,7 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  from typing import Callable
6
6
 
7
- from xdog.coding.core.slash_commands import BUILTIN_COMMANDS
7
+ from xdog.coding.core.slash_commands import list_commands
8
8
  from xdog.coding.modes.interactive.theme import Theme
9
9
  from xdog.tui.keys import KeyEvent
10
10
  from xdog.tui.tui import Component
@@ -88,9 +88,14 @@ class CustomEditorComponent(Component):
88
88
  """Update the select list based on current input."""
89
89
  if self._value.startswith("/"):
90
90
  prefix = self._value[1:]
91
+ # `list_commands()`, not BUILTIN_COMMANDS: a skill is a command too,
92
+ # and the dispatcher has always run one. Completing only the built-ins
93
+ # meant an installed skill worked but could not be found -- you had to
94
+ # know its name already, which is the state its own docstring says to
95
+ # avoid.
91
96
  matching = [
92
97
  (f"/{name}", desc)
93
- for name, desc in BUILTIN_COMMANDS.items()
98
+ for name, desc in sorted(list_commands().items())
94
99
  if name.startswith(prefix) and f"/{name}" != self._value
95
100
  ]
96
101
  if matching:
@@ -467,3 +467,41 @@ def test_an_unresolvable_model_still_gets_its_tools_described(
467
467
 
468
468
  assert model_supports_tool_calls("no-such-provider/no-such-model") is None
469
469
  assert AgentSession._native_tool_calls(_Unresolvable()) is False
470
+
471
+
472
+ def test_completion_offers_skills_not_only_builtins(
473
+ tmp_path: Path, monkeypatch: pytest.MonkeyPatch
474
+ ) -> None:
475
+ """A skill has always been runnable — the dispatcher falls through to
476
+ `_load_skill`. It just could not be *found*: completion read
477
+ BUILTIN_COMMANDS, so you had to already know the name. `list_commands()`
478
+ exists for exactly this and says so in its docstring.
479
+ """
480
+ from xdog.coding.core import slash_commands
481
+ from xdog.coding.core.slash_commands import list_commands
482
+
483
+ shared = tmp_path / "skills"
484
+ shared.mkdir(parents=True)
485
+ _write(shared, "flow", "body", description="write a workflow")
486
+ manager = SkillManager(shared_dir=shared, packaged={})
487
+ monkeypatch.setattr(slash_commands, "skill_manager", lambda: manager)
488
+
489
+ commands = list_commands()
490
+
491
+ assert "flow" in commands, "a skill is a command"
492
+ assert commands["flow"] == "write a workflow"
493
+ assert "quit" in commands, "and the built-ins are still there"
494
+
495
+
496
+ def test_a_builtin_wins_a_name_clash(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
497
+ """Otherwise a skill named `quit` could take over leaving the session."""
498
+ from xdog.coding.core import slash_commands
499
+ from xdog.coding.core.slash_commands import BUILTIN_COMMANDS, list_commands
500
+
501
+ shared = tmp_path / "skills"
502
+ shared.mkdir(parents=True)
503
+ _write(shared, "quit", "body", description="a skill pretending to be quit")
504
+ manager = SkillManager(shared_dir=shared, packaged={})
505
+ monkeypatch.setattr(slash_commands, "skill_manager", lambda: manager)
506
+
507
+ assert list_commands()["quit"] == BUILTIN_COMMANDS["quit"]
File without changes