spooling 0.1.2__tar.gz → 0.1.3__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 (51) hide show
  1. {spooling-0.1.2/spooling.egg-info → spooling-0.1.3}/PKG-INFO +1 -1
  2. {spooling-0.1.2 → spooling-0.1.3}/pyproject.toml +1 -1
  3. {spooling-0.1.2 → spooling-0.1.3}/spooling/providers/opencode.py +18 -3
  4. {spooling-0.1.2 → spooling-0.1.3/spooling.egg-info}/PKG-INFO +1 -1
  5. {spooling-0.1.2 → spooling-0.1.3}/LICENSE +0 -0
  6. {spooling-0.1.2 → spooling-0.1.3}/README.md +0 -0
  7. {spooling-0.1.2 → spooling-0.1.3}/setup.cfg +0 -0
  8. {spooling-0.1.2 → spooling-0.1.3}/spooling/__init__.py +0 -0
  9. {spooling-0.1.2 → spooling-0.1.3}/spooling/agent.py +0 -0
  10. {spooling-0.1.2 → spooling-0.1.3}/spooling/classifiers.py +0 -0
  11. {spooling-0.1.2 → spooling-0.1.3}/spooling/cli.py +0 -0
  12. {spooling-0.1.2 → spooling-0.1.3}/spooling/cloud.py +0 -0
  13. {spooling-0.1.2 → spooling-0.1.3}/spooling/config.py +0 -0
  14. {spooling-0.1.2 → spooling-0.1.3}/spooling/db.py +0 -0
  15. {spooling-0.1.2 → spooling-0.1.3}/spooling/embeddings.py +0 -0
  16. {spooling-0.1.2 → spooling-0.1.3}/spooling/evals.py +0 -0
  17. {spooling-0.1.2 → spooling-0.1.3}/spooling/experiments.py +0 -0
  18. {spooling-0.1.2 → spooling-0.1.3}/spooling/ingest.py +0 -0
  19. {spooling-0.1.2 → spooling-0.1.3}/spooling/mcp_server.py +0 -0
  20. {spooling-0.1.2 → spooling-0.1.3}/spooling/parser.py +0 -0
  21. {spooling-0.1.2 → spooling-0.1.3}/spooling/pricing.py +0 -0
  22. {spooling-0.1.2 → spooling-0.1.3}/spooling/providers/__init__.py +0 -0
  23. {spooling-0.1.2 → spooling-0.1.3}/spooling/providers/antigravity.py +0 -0
  24. {spooling-0.1.2 → spooling-0.1.3}/spooling/providers/base.py +0 -0
  25. {spooling-0.1.2 → spooling-0.1.3}/spooling/providers/codex.py +0 -0
  26. {spooling-0.1.2 → spooling-0.1.3}/spooling/providers/copilot.py +0 -0
  27. {spooling-0.1.2 → spooling-0.1.3}/spooling/providers/cortex_code.py +0 -0
  28. {spooling-0.1.2 → spooling-0.1.3}/spooling/providers/cursor.py +0 -0
  29. {spooling-0.1.2 → spooling-0.1.3}/spooling/providers/gemini.py +0 -0
  30. {spooling-0.1.2 → spooling-0.1.3}/spooling/providers/github.py +0 -0
  31. {spooling-0.1.2 → spooling-0.1.3}/spooling/providers/gitlab.py +0 -0
  32. {spooling-0.1.2 → spooling-0.1.3}/spooling/providers/kiro.py +0 -0
  33. {spooling-0.1.2 → spooling-0.1.3}/spooling/providers/session_file.py +0 -0
  34. {spooling-0.1.2 → spooling-0.1.3}/spooling/providers/windsurf.py +0 -0
  35. {spooling-0.1.2 → spooling-0.1.3}/spooling/redact.py +0 -0
  36. {spooling-0.1.2 → spooling-0.1.3}/spooling/remote_otel.py +0 -0
  37. {spooling-0.1.2 → spooling-0.1.3}/spooling/sdk.py +0 -0
  38. {spooling-0.1.2 → spooling-0.1.3}/spooling/search.py +0 -0
  39. {spooling-0.1.2 → spooling-0.1.3}/spooling/server.py +0 -0
  40. {spooling-0.1.2 → spooling-0.1.3}/spooling/stats.py +0 -0
  41. {spooling-0.1.2 → spooling-0.1.3}/spooling/subscription_pricing.py +0 -0
  42. {spooling-0.1.2 → spooling-0.1.3}/spooling/tracing.py +0 -0
  43. {spooling-0.1.2 → spooling-0.1.3}/spooling/watcher.py +0 -0
  44. {spooling-0.1.2 → spooling-0.1.3}/spooling.egg-info/SOURCES.txt +0 -0
  45. {spooling-0.1.2 → spooling-0.1.3}/spooling.egg-info/dependency_links.txt +0 -0
  46. {spooling-0.1.2 → spooling-0.1.3}/spooling.egg-info/entry_points.txt +0 -0
  47. {spooling-0.1.2 → spooling-0.1.3}/spooling.egg-info/requires.txt +0 -0
  48. {spooling-0.1.2 → spooling-0.1.3}/spooling.egg-info/top_level.txt +0 -0
  49. {spooling-0.1.2 → spooling-0.1.3}/tests/test_parser.py +0 -0
  50. {spooling-0.1.2 → spooling-0.1.3}/tests/test_pricing.py +0 -0
  51. {spooling-0.1.2 → spooling-0.1.3}/tests/test_redact.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: spooling
3
- Version: 0.1.2
3
+ Version: 0.1.3
4
4
  Summary: Local session tracker and semantic search for AI coding assistants
5
5
  Author: Parsed Analytics, Inc.
6
6
  License-Expression: MIT
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "spooling"
3
- version = "0.1.2"
3
+ version = "0.1.3"
4
4
  description = "Local session tracker and semantic search for AI coding assistants"
5
5
  license = "MIT"
6
6
  license-files = ["LICENSE"]
@@ -88,6 +88,19 @@ def _tool_name_from_part(part_type: str, data: dict) -> str:
88
88
  return data.get("toolName") or data.get("name") or data.get("tool") or "tool"
89
89
 
90
90
 
91
+ _CAMEL_TO_SNAKE = {"filePath": "file_path", "oldString": "old_string", "newString": "new_string"}
92
+
93
+ def _normalize_tool_input(name: str, inp: dict) -> dict:
94
+ """Normalize opencode's camelCase input keys to snake_case for
95
+ the JSONL-parser utility functions (``_summarize_tool_input``,
96
+ ``_format_edit_diff``)."""
97
+ if not isinstance(inp, dict):
98
+ return inp
99
+ if name not in ("Edit", "Write"):
100
+ return inp
101
+ return {_CAMEL_TO_SNAKE.get(k, k): v for k, v in inp.items()}
102
+
103
+
91
104
  def _build_message(
92
105
  message_id: str,
93
106
  session_id: str,
@@ -128,7 +141,8 @@ def _build_message(
128
141
  continue
129
142
 
130
143
  if _part_is_tool(ptype):
131
- name = _tool_name_from_part(ptype, p)
144
+ raw_name = _tool_name_from_part(ptype, p)
145
+ name = raw_name[0].upper() + raw_name[1:] if raw_name else raw_name
132
146
  state = p.get("state") or {}
133
147
  inp = state.get("input") or p.get("input") or p.get("args") or {}
134
148
  call_id = p.get("toolCallId") or p.get("id") or p.get("tool_use_id") or p.get("callID") or ""
@@ -136,13 +150,14 @@ def _build_message(
136
150
 
137
151
  input_summary = ""
138
152
  tool_input_raw = None
153
+ norm_inp = _normalize_tool_input(name, inp) if isinstance(inp, dict) else inp
139
154
  if isinstance(inp, dict) and inp:
140
- input_summary = _summarize_tool_input(name, inp)
155
+ input_summary = _summarize_tool_input(name, norm_inp)
141
156
  tool_input_raw = inp
142
157
 
143
158
  result_preview = ""
144
159
  if name == "Edit" and isinstance(inp, dict):
145
- result_preview = _format_edit_diff(inp)
160
+ result_preview = _format_edit_diff(norm_inp)
146
161
  elif name == "Write" and isinstance(inp, dict):
147
162
  result_preview = (inp.get("content") or "")[:2000]
148
163
  elif output is not None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: spooling
3
- Version: 0.1.2
3
+ Version: 0.1.3
4
4
  Summary: Local session tracker and semantic search for AI coding assistants
5
5
  Author: Parsed Analytics, Inc.
6
6
  License-Expression: MIT
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
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
File without changes
File without changes
File without changes