clockwork-cli 0.1.1__tar.gz → 0.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: clockwork-cli
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: Mine your Claude Code and Codex session logs to estimate active time
5
5
  License-Expression: MIT
6
6
  Project-URL: Homepage, https://github.com/danielsich/clockwork
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "clockwork-cli"
7
- version = "0.1.1"
7
+ version = "0.1.2"
8
8
  description = "Mine your Claude Code and Codex session logs to estimate active time"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -55,7 +55,7 @@ import hashlib
55
55
  from datetime import datetime, timedelta, timezone
56
56
  from collections import defaultdict
57
57
 
58
- __version__ = "0.1.1"
58
+ __version__ = "0.1.2"
59
59
 
60
60
 
61
61
  def _resolve_claude_dir():
@@ -200,6 +200,34 @@ def _print_json(obj):
200
200
  print(json.dumps(obj, indent=2))
201
201
 
202
202
 
203
+ def _stdout_target():
204
+ """Best-effort name of where stdout is going, for status messages.
205
+
206
+ Returns the basename of the file when stdout is redirected to a regular
207
+ file (`> out.json`), or None for a terminal or a pipe. Purely cosmetic;
208
+ any failure degrades to None so it never affects the export itself.
209
+ """
210
+ try:
211
+ if os.isatty(1):
212
+ return None
213
+ except Exception:
214
+ return None
215
+ path = None
216
+ try: # macOS / BSD: ask the kernel for fd 1's path
217
+ import fcntl
218
+ f_getpath = getattr(fcntl, "F_GETPATH", 50)
219
+ raw = fcntl.fcntl(1, f_getpath, b"\0" * 1024)
220
+ path = raw.split(b"\0", 1)[0].decode() or None
221
+ except Exception:
222
+ try: # Linux: /proc symlink
223
+ path = os.readlink("/proc/self/fd/1")
224
+ except Exception:
225
+ path = None
226
+ if path and os.path.isfile(path):
227
+ return os.path.basename(path)
228
+ return None
229
+
230
+
203
231
  def _project_id(path):
204
232
  """Stable short id for a project path (survives anonymization)."""
205
233
  return hashlib.sha1(path.encode("utf-8")).hexdigest()[:8]
@@ -838,6 +866,18 @@ def export_data(provider, idle_threshold, since, until, detail, anonymize):
838
866
  },
839
867
  })
840
868
 
869
+ # A friendly receipt on stderr — keeps stdout pure JSON for redirection.
870
+ dest = _stdout_target()
871
+ where = dest if dest else "stdout"
872
+ tags = [provider, f"detail={detail}"]
873
+ if anonymize:
874
+ tags.append("anonymized")
875
+ print(f"\n ✓ export complete → {where}", file=sys.stderr)
876
+ print(f" {' · '.join(tags)}", file=sys.stderr)
877
+ print(f" {len(out_projects)} projects · {grand_prompts:,} prompts "
878
+ f"· {grand_sessions:,} sessions · {grand_minutes / 60:.1f}h active",
879
+ file=sys.stderr)
880
+
841
881
 
842
882
  def list_projects(provider, as_json):
843
883
  projects = PROVIDERS[provider]["list"]()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: clockwork-cli
3
- Version: 0.1.1
3
+ Version: 0.1.2
4
4
  Summary: Mine your Claude Code and Codex session logs to estimate active time
5
5
  License-Expression: MIT
6
6
  Project-URL: Homepage, https://github.com/danielsich/clockwork
File without changes
File without changes
File without changes