pidriver 0.2.0__tar.gz → 0.3.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 (71) hide show
  1. {pidriver-0.2.0 → pidriver-0.3.0}/PKG-INFO +1 -1
  2. {pidriver-0.2.0 → pidriver-0.3.0}/pyproject.toml +1 -1
  3. {pidriver-0.2.0 → pidriver-0.3.0}/src/pidriver/__init__.py +18 -1
  4. {pidriver-0.2.0 → pidriver-0.3.0}/src/pidriver/errors.py +39 -0
  5. pidriver-0.3.0/src/pidriver/staging.py +634 -0
  6. pidriver-0.3.0/tests/test_staging.py +356 -0
  7. pidriver-0.2.0/.sc/last-chat-settings.json +0 -4
  8. {pidriver-0.2.0 → pidriver-0.3.0}/.gitignore +0 -0
  9. {pidriver-0.2.0 → pidriver-0.3.0}/LICENSE +0 -0
  10. {pidriver-0.2.0 → pidriver-0.3.0}/README.md +0 -0
  11. {pidriver-0.2.0 → pidriver-0.3.0}/examples/basic_prompt.py +0 -0
  12. {pidriver-0.2.0 → pidriver-0.3.0}/src/pidriver/_install.py +0 -0
  13. {pidriver-0.2.0 → pidriver-0.3.0}/src/pidriver/_transport.py +0 -0
  14. {pidriver-0.2.0 → pidriver-0.3.0}/src/pidriver/assets/pi_login.mjs +0 -0
  15. {pidriver-0.2.0 → pidriver-0.3.0}/src/pidriver/auth.py +0 -0
  16. {pidriver-0.2.0 → pidriver-0.3.0}/src/pidriver/client.py +0 -0
  17. {pidriver-0.2.0 → pidriver-0.3.0}/src/pidriver/config.py +0 -0
  18. {pidriver-0.2.0 → pidriver-0.3.0}/src/pidriver/events.py +0 -0
  19. {pidriver-0.2.0 → pidriver-0.3.0}/src/pidriver/interaction.py +0 -0
  20. {pidriver-0.2.0 → pidriver-0.3.0}/src/pidriver/manager.py +0 -0
  21. {pidriver-0.2.0 → pidriver-0.3.0}/src/pidriver/models.py +0 -0
  22. {pidriver-0.2.0 → pidriver-0.3.0}/src/pidriver/py.typed +0 -0
  23. {pidriver-0.2.0 → pidriver-0.3.0}/src/pidriver/session.py +0 -0
  24. {pidriver-0.2.0 → pidriver-0.3.0}/src/pidriver/usage.py +0 -0
  25. {pidriver-0.2.0 → pidriver-0.3.0}/src/pidriver/workspace.py +0 -0
  26. {pidriver-0.2.0 → pidriver-0.3.0}/tests/conftest.py +0 -0
  27. {pidriver-0.2.0 → pidriver-0.3.0}/tests/fixtures/README.md +0 -0
  28. {pidriver-0.2.0 → pidriver-0.3.0}/tests/fixtures/_capture_driver.py +0 -0
  29. {pidriver-0.2.0 → pidriver-0.3.0}/tests/fixtures/frames/agent_end.json +0 -0
  30. {pidriver-0.2.0 → pidriver-0.3.0}/tests/fixtures/frames/agent_start.json +0 -0
  31. {pidriver-0.2.0 → pidriver-0.3.0}/tests/fixtures/frames/extension_ui_request.confirm.json +0 -0
  32. {pidriver-0.2.0 → pidriver-0.3.0}/tests/fixtures/frames/extension_ui_request.editor.json +0 -0
  33. {pidriver-0.2.0 → pidriver-0.3.0}/tests/fixtures/frames/extension_ui_request.input.json +0 -0
  34. {pidriver-0.2.0 → pidriver-0.3.0}/tests/fixtures/frames/extension_ui_request.select.approval.json +0 -0
  35. {pidriver-0.2.0 → pidriver-0.3.0}/tests/fixtures/frames/extension_ui_request.select.ask.json +0 -0
  36. {pidriver-0.2.0 → pidriver-0.3.0}/tests/fixtures/frames/extension_ui_request.setWidget.json +0 -0
  37. {pidriver-0.2.0 → pidriver-0.3.0}/tests/fixtures/frames/extension_ui_response.approve.json +0 -0
  38. {pidriver-0.2.0 → pidriver-0.3.0}/tests/fixtures/frames/extension_ui_response.confirm.json +0 -0
  39. {pidriver-0.2.0 → pidriver-0.3.0}/tests/fixtures/frames/extension_ui_response.editor.json +0 -0
  40. {pidriver-0.2.0 → pidriver-0.3.0}/tests/fixtures/frames/extension_ui_response.input.json +0 -0
  41. {pidriver-0.2.0 → pidriver-0.3.0}/tests/fixtures/frames/extension_ui_response.value.json +0 -0
  42. {pidriver-0.2.0 → pidriver-0.3.0}/tests/fixtures/frames/message_start_assistant.json +0 -0
  43. {pidriver-0.2.0 → pidriver-0.3.0}/tests/fixtures/frames/message_start_user.json +0 -0
  44. {pidriver-0.2.0 → pidriver-0.3.0}/tests/fixtures/frames/message_update.text_delta.json +0 -0
  45. {pidriver-0.2.0 → pidriver-0.3.0}/tests/fixtures/frames/message_update.thinking_delta.json +0 -0
  46. {pidriver-0.2.0 → pidriver-0.3.0}/tests/fixtures/frames/message_update.toolcall_end.json +0 -0
  47. {pidriver-0.2.0 → pidriver-0.3.0}/tests/fixtures/frames/message_update.toolcall_start.json +0 -0
  48. {pidriver-0.2.0 → pidriver-0.3.0}/tests/fixtures/frames/ready.json +0 -0
  49. {pidriver-0.2.0 → pidriver-0.3.0}/tests/fixtures/frames/response_prompt_ack.json +0 -0
  50. {pidriver-0.2.0 → pidriver-0.3.0}/tests/fixtures/frames/tool_execution_end.json +0 -0
  51. {pidriver-0.2.0 → pidriver-0.3.0}/tests/fixtures/frames/tool_execution_start.json +0 -0
  52. {pidriver-0.2.0 → pidriver-0.3.0}/tests/fixtures/frames/tool_execution_update.json +0 -0
  53. {pidriver-0.2.0 → pidriver-0.3.0}/tests/fixtures/frames/turn_end.json +0 -0
  54. {pidriver-0.2.0 → pidriver-0.3.0}/tests/fixtures/frames/turn_start.json +0 -0
  55. {pidriver-0.2.0 → pidriver-0.3.0}/tests/fixtures/payloads/get_session_stats.response.json +0 -0
  56. {pidriver-0.2.0 → pidriver-0.3.0}/tests/fixtures/payloads/get_state.response.json +0 -0
  57. {pidriver-0.2.0 → pidriver-0.3.0}/tests/test_auth.py +0 -0
  58. {pidriver-0.2.0 → pidriver-0.3.0}/tests/test_config.py +0 -0
  59. {pidriver-0.2.0 → pidriver-0.3.0}/tests/test_event_summary.py +0 -0
  60. {pidriver-0.2.0 → pidriver-0.3.0}/tests/test_events.py +0 -0
  61. {pidriver-0.2.0 → pidriver-0.3.0}/tests/test_fixtures_replay.py +0 -0
  62. {pidriver-0.2.0 → pidriver-0.3.0}/tests/test_install.py +0 -0
  63. {pidriver-0.2.0 → pidriver-0.3.0}/tests/test_install_resolve.py +0 -0
  64. {pidriver-0.2.0 → pidriver-0.3.0}/tests/test_manager.py +0 -0
  65. {pidriver-0.2.0 → pidriver-0.3.0}/tests/test_models.py +0 -0
  66. {pidriver-0.2.0 → pidriver-0.3.0}/tests/test_replay_session.py +0 -0
  67. {pidriver-0.2.0 → pidriver-0.3.0}/tests/test_session.py +0 -0
  68. {pidriver-0.2.0 → pidriver-0.3.0}/tests/test_transport.py +0 -0
  69. {pidriver-0.2.0 → pidriver-0.3.0}/tests/test_ui_methods.py +0 -0
  70. {pidriver-0.2.0 → pidriver-0.3.0}/tests/test_usage.py +0 -0
  71. {pidriver-0.2.0 → pidriver-0.3.0}/tests/test_workspace.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pidriver
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: Async Python driver for the pi coding agent (pi --mode rpc), built for isolated, headless project work.
5
5
  Project-URL: Homepage, https://github.com/bobuk/pidriver
6
6
  Project-URL: Repository, https://github.com/bobuk/pidriver
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pidriver"
3
- version = "0.2.0"
3
+ version = "0.3.0"
4
4
  description = "Async Python driver for the pi coding agent (pi --mode rpc), built for isolated, headless project work."
5
5
  readme = "README.md"
6
6
  license = { text = "MIT" }
@@ -56,6 +56,7 @@ from .config import (
56
56
  PiConfig,
57
57
  )
58
58
  from .errors import (
59
+ MergeConflict,
59
60
  PiCommandError,
60
61
  PiDriverError,
61
62
  PiInstallError,
@@ -65,6 +66,7 @@ from .errors import (
65
66
  PiTimeoutError,
66
67
  ProjectError,
67
68
  SessionNotFoundError,
69
+ StagingError,
68
70
  TransportClosedError,
69
71
  )
70
72
  from .events import (
@@ -99,10 +101,17 @@ from .interaction import (
99
101
  from .manager import ManagedSession, PiSessionManager
100
102
  from .models import ModelInfo, list_models, parse_models
101
103
  from .session import PiSession
104
+ from .staging import (
105
+ DEFAULT_COPY_EXCLUDES,
106
+ DEFAULT_MAX_COPY_BYTES,
107
+ MergeResult,
108
+ StagedWorkspace,
109
+ stage_workspace,
110
+ )
102
111
  from .usage import UsageTotals
103
112
  from .workspace import ProjectDir, list_candidate_projects, list_projects, resolve_project
104
113
 
105
- __version__ = "0.2.0"
114
+ __version__ = "0.3.0"
106
115
 
107
116
  __all__ = [
108
117
  "__version__",
@@ -161,6 +170,12 @@ __all__ = [
161
170
  "list_projects",
162
171
  "list_candidate_projects",
163
172
  "ProjectDir",
173
+ # staging
174
+ "stage_workspace",
175
+ "StagedWorkspace",
176
+ "MergeResult",
177
+ "DEFAULT_COPY_EXCLUDES",
178
+ "DEFAULT_MAX_COPY_BYTES",
164
179
  # models
165
180
  "ModelInfo",
166
181
  "parse_models",
@@ -180,4 +195,6 @@ __all__ = [
180
195
  "TransportClosedError",
181
196
  "SessionNotFoundError",
182
197
  "ProjectError",
198
+ "StagingError",
199
+ "MergeConflict",
183
200
  ]
@@ -19,6 +19,8 @@ __all__ = [
19
19
  "TransportClosedError",
20
20
  "SessionNotFoundError",
21
21
  "ProjectError",
22
+ "StagingError",
23
+ "MergeConflict",
22
24
  ]
23
25
 
24
26
 
@@ -35,6 +37,43 @@ class ProjectError(PiDriverError, ValueError):
35
37
  """
36
38
 
37
39
 
40
+ class StagingError(PiDriverError):
41
+ """A staging operation (stage/diff/merge/discard/cleanup) failed structurally.
42
+
43
+ Raised by :mod:`pidriver.staging` when a ``git`` command exits non-zero, the
44
+ staging root is unusable, the source/stage path is invalid, the source repo is
45
+ in a state that cannot be merged into (dirty working tree, detached HEAD), or a
46
+ non-git copy exceeds the size cap. Carries the failing git ``argv`` + ``stderr``
47
+ when the cause was a git invocation.
48
+ """
49
+
50
+ def __init__(
51
+ self,
52
+ message: str,
53
+ *,
54
+ argv: tuple[str, ...] | None = None,
55
+ stderr: str | None = None,
56
+ ) -> None:
57
+ self.argv = argv
58
+ self.stderr = stderr
59
+ super().__init__(message)
60
+
61
+
62
+ class MergeConflict(StagingError):
63
+ """A staged change could not be landed into the source cleanly.
64
+
65
+ The ``pi/<job>`` branch (git) or the staged tree (non-git) is preserved
66
+ untouched and the source is left pristine, so the user can resolve by hand.
67
+ ``conflicts`` lists the conflicting paths; ``diff`` is the unified diff to
68
+ reconcile.
69
+ """
70
+
71
+ def __init__(self, message: str, *, conflicts: tuple[str, ...], diff: str) -> None:
72
+ self.conflicts = conflicts
73
+ self.diff = diff
74
+ super().__init__(message)
75
+
76
+
38
77
  class PiNotFoundError(PiDriverError):
39
78
  """The pi/omp executable could not be located or is not runnable."""
40
79