spooling 0.2.13__tar.gz → 0.2.14__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 (77) hide show
  1. {spooling-0.2.13/spooling.egg-info → spooling-0.2.14}/PKG-INFO +41 -1
  2. {spooling-0.2.13 → spooling-0.2.14}/README.md +40 -0
  3. {spooling-0.2.13 → spooling-0.2.14}/pyproject.toml +1 -1
  4. {spooling-0.2.13 → spooling-0.2.14}/spooling/cloud.py +1 -1
  5. {spooling-0.2.13 → spooling-0.2.14/spooling.egg-info}/PKG-INFO +41 -1
  6. {spooling-0.2.13 → spooling-0.2.14}/spooling.egg-info/SOURCES.txt +1 -0
  7. spooling-0.2.14/tests/test_docs.py +31 -0
  8. {spooling-0.2.13 → spooling-0.2.14}/LICENSE +0 -0
  9. {spooling-0.2.13 → spooling-0.2.14}/setup.cfg +0 -0
  10. {spooling-0.2.13 → spooling-0.2.14}/spooling/__init__.py +0 -0
  11. {spooling-0.2.13 → spooling-0.2.14}/spooling/agent.py +0 -0
  12. {spooling-0.2.13 → spooling-0.2.14}/spooling/classifiers.py +0 -0
  13. {spooling-0.2.13 → spooling-0.2.14}/spooling/cli.py +0 -0
  14. {spooling-0.2.13 → spooling-0.2.14}/spooling/config.py +0 -0
  15. {spooling-0.2.13 → spooling-0.2.14}/spooling/connectors/__init__.py +0 -0
  16. {spooling-0.2.13 → spooling-0.2.14}/spooling/connectors/base.py +0 -0
  17. {spooling-0.2.13 → spooling-0.2.14}/spooling/connectors/bigquery.py +0 -0
  18. {spooling-0.2.13 → spooling-0.2.14}/spooling/connectors/clickhouse.py +0 -0
  19. {spooling-0.2.13 → spooling-0.2.14}/spooling/connectors/factory.py +0 -0
  20. {spooling-0.2.13 → spooling-0.2.14}/spooling/connectors/mongodb.py +0 -0
  21. {spooling-0.2.13 → spooling-0.2.14}/spooling/connectors/mysql.py +0 -0
  22. {spooling-0.2.13 → spooling-0.2.14}/spooling/connectors/postgresql.py +0 -0
  23. {spooling-0.2.13 → spooling-0.2.14}/spooling/connectors/rest/__init__.py +0 -0
  24. {spooling-0.2.13 → spooling-0.2.14}/spooling/connectors/rest/base.py +0 -0
  25. {spooling-0.2.13 → spooling-0.2.14}/spooling/connectors/rest/shopify_connectors.py +0 -0
  26. {spooling-0.2.13 → spooling-0.2.14}/spooling/connectors/snowflake.py +0 -0
  27. {spooling-0.2.13 → spooling-0.2.14}/spooling/connectors/types.py +0 -0
  28. {spooling-0.2.13 → spooling-0.2.14}/spooling/db.py +0 -0
  29. {spooling-0.2.13 → spooling-0.2.14}/spooling/embeddings.py +0 -0
  30. {spooling-0.2.13 → spooling-0.2.14}/spooling/evals.py +0 -0
  31. {spooling-0.2.13 → spooling-0.2.14}/spooling/experiments.py +0 -0
  32. {spooling-0.2.13 → spooling-0.2.14}/spooling/ingest.py +0 -0
  33. {spooling-0.2.13 → spooling-0.2.14}/spooling/insights.py +0 -0
  34. {spooling-0.2.13 → spooling-0.2.14}/spooling/mcp_server.py +0 -0
  35. {spooling-0.2.13 → spooling-0.2.14}/spooling/optimize.py +0 -0
  36. {spooling-0.2.13 → spooling-0.2.14}/spooling/parser.py +0 -0
  37. {spooling-0.2.13 → spooling-0.2.14}/spooling/pricing.py +0 -0
  38. {spooling-0.2.13 → spooling-0.2.14}/spooling/providers/__init__.py +0 -0
  39. {spooling-0.2.13 → spooling-0.2.14}/spooling/providers/antigravity.py +0 -0
  40. {spooling-0.2.13 → spooling-0.2.14}/spooling/providers/base.py +0 -0
  41. {spooling-0.2.13 → spooling-0.2.14}/spooling/providers/claude_code.py +0 -0
  42. {spooling-0.2.13 → spooling-0.2.14}/spooling/providers/codex.py +0 -0
  43. {spooling-0.2.13 → spooling-0.2.14}/spooling/providers/copilot.py +0 -0
  44. {spooling-0.2.13 → spooling-0.2.14}/spooling/providers/cortex_code.py +0 -0
  45. {spooling-0.2.13 → spooling-0.2.14}/spooling/providers/cursor.py +0 -0
  46. {spooling-0.2.13 → spooling-0.2.14}/spooling/providers/gemini.py +0 -0
  47. {spooling-0.2.13 → spooling-0.2.14}/spooling/providers/github.py +0 -0
  48. {spooling-0.2.13 → spooling-0.2.14}/spooling/providers/gitlab.py +0 -0
  49. {spooling-0.2.13 → spooling-0.2.14}/spooling/providers/kiro.py +0 -0
  50. {spooling-0.2.13 → spooling-0.2.14}/spooling/providers/opencode.py +0 -0
  51. {spooling-0.2.13 → spooling-0.2.14}/spooling/providers/session_file.py +0 -0
  52. {spooling-0.2.13 → spooling-0.2.14}/spooling/providers/windsurf.py +0 -0
  53. {spooling-0.2.13 → spooling-0.2.14}/spooling/redact.py +0 -0
  54. {spooling-0.2.13 → spooling-0.2.14}/spooling/remote_otel.py +0 -0
  55. {spooling-0.2.13 → spooling-0.2.14}/spooling/schema.py +0 -0
  56. {spooling-0.2.13 → spooling-0.2.14}/spooling/sdk.py +0 -0
  57. {spooling-0.2.13 → spooling-0.2.14}/spooling/search.py +0 -0
  58. {spooling-0.2.13 → spooling-0.2.14}/spooling/server.py +0 -0
  59. {spooling-0.2.13 → spooling-0.2.14}/spooling/sessions.py +0 -0
  60. {spooling-0.2.13 → spooling-0.2.14}/spooling/stats.py +0 -0
  61. {spooling-0.2.13 → spooling-0.2.14}/spooling/subscription_pricing.py +0 -0
  62. {spooling-0.2.13 → spooling-0.2.14}/spooling/tracing.py +0 -0
  63. {spooling-0.2.13 → spooling-0.2.14}/spooling/tunnel.py +0 -0
  64. {spooling-0.2.13 → spooling-0.2.14}/spooling/tunnel_auth.py +0 -0
  65. {spooling-0.2.13 → spooling-0.2.14}/spooling/watcher.py +0 -0
  66. {spooling-0.2.13 → spooling-0.2.14}/spooling.egg-info/dependency_links.txt +0 -0
  67. {spooling-0.2.13 → spooling-0.2.14}/spooling.egg-info/entry_points.txt +0 -0
  68. {spooling-0.2.13 → spooling-0.2.14}/spooling.egg-info/requires.txt +0 -0
  69. {spooling-0.2.13 → spooling-0.2.14}/spooling.egg-info/top_level.txt +0 -0
  70. {spooling-0.2.13 → spooling-0.2.14}/tests/test_agent_spans.py +0 -0
  71. {spooling-0.2.13 → spooling-0.2.14}/tests/test_claude_code_provider.py +0 -0
  72. {spooling-0.2.13 → spooling-0.2.14}/tests/test_cloud_errors.py +0 -0
  73. {spooling-0.2.13 → spooling-0.2.14}/tests/test_insights.py +0 -0
  74. {spooling-0.2.13 → spooling-0.2.14}/tests/test_mcp_auth_middleware.py +0 -0
  75. {spooling-0.2.13 → spooling-0.2.14}/tests/test_session_ids.py +0 -0
  76. {spooling-0.2.13 → spooling-0.2.14}/tests/test_storage_optimizations.py +0 -0
  77. {spooling-0.2.13 → spooling-0.2.14}/tests/test_tunnel_auth.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: spooling
3
- Version: 0.2.13
3
+ Version: 0.2.14
4
4
  Summary: Local session tracker and semantic search for AI coding assistants
5
5
  Author: Parsed Analytics, Inc.
6
6
  License: MIT
@@ -415,6 +415,46 @@ spooling push --dry-run # show what would be pushed
415
415
 
416
416
  `push` ingests new provider sessions into the local database before uploading, so you don't need to run `spooling sync` first. The server upserts by session id, so re-running is safe.
417
417
 
418
+ ### Push only some sessions, or to a specific team
419
+
420
+ **Which team gets the sessions** is decided by the API key you are logged in with. Each key belongs to one workspace (personal or a team), and `spooling push` sends to that workspace. Mint a key for the team in the app, then log in with it:
421
+
422
+ ```bash
423
+ spooling cloud login --key sk_<team-key> # replaces the stored key; later pushes go to this team
424
+ spooling cloud status # session/cost totals of the workspace this key belongs to
425
+ ```
426
+
427
+ To push to a different team, log in with that team's key. Only one key is stored at a time. `cloud status` doesn't print the workspace name, so compare its totals with what the team shows in the app.
428
+
429
+ **Which sessions go up.** With no filters, `spooling push` sends the most recent `--limit` sessions from every project on the machine. Use these to send only some of them. Filters combine with AND:
430
+
431
+ | Option | Matches |
432
+ |---|---|
433
+ | `--project NAME` | Sessions whose project name is exactly `NAME` (find names with `spooling cost breakdown --by project`) |
434
+ | `--cwd TEXT` | Sessions whose working directory contains `TEXT` (case-insensitive) |
435
+ | `--title TEXT` | Sessions whose title contains `TEXT` (case-insensitive). Useful when an agent was launched from your home directory, so every session shares a generic working directory, but the project name is in the title |
436
+
437
+ ```bash
438
+ spooling cloud login --key sk_<team-key>
439
+ spooling push --cwd toebox --dry-run # preview what would be sent; nothing is uploaded
440
+ spooling push --cwd toebox # send only sessions from the toebox directory
441
+ spooling push --project my-app --limit 200
442
+ spooling push --title islet # sessions with "islet" in the title
443
+ ```
444
+
445
+ **Share the same sessions with more than one team.** Add `--copy` to write the sessions into the workspace you are logged into as fresh rows, even if they were already pushed to another workspace. Re-running is safe:
446
+
447
+ ```bash
448
+ spooling cloud login --key sk_<other-team-key>
449
+ spooling push --cwd toebox --copy
450
+ ```
451
+
452
+ **Include trace data.** Add `--with-spans` to also push each session's trace and spans (per-LLM-call usage, cost, tool calls, MCP calls and agent runs). The Traces page in the app, its agent, tool and MCP filters, and `spooling agents --cloud` / `spooling mcps --cloud` all rely on it. `--with-spans` can't be combined with `--copy` yet.
453
+
454
+ **Secrets** (cloud and AWS keys, GitHub, OpenAI, Anthropic and Stripe tokens, PEM private keys, and `KEY=VALUE` lines whose key looks sensitive) are redacted on your machine before anything is uploaded. Pass `--no-redact` only if you are sure the content is clean.
455
+
456
+ `spooling cloud watch` has no filters: it keeps pushing every new or updated session to the workspace you are logged into. Use filtered `spooling push` runs when you need to keep some sessions out.
457
+
418
458
  To bring sessions from the cloud back down, use `spooling cloud pull`, or `spooling cloud sync` for both directions.
419
459
 
420
460
  ### Watch (continuous push)
@@ -379,6 +379,46 @@ spooling push --dry-run # show what would be pushed
379
379
 
380
380
  `push` ingests new provider sessions into the local database before uploading, so you don't need to run `spooling sync` first. The server upserts by session id, so re-running is safe.
381
381
 
382
+ ### Push only some sessions, or to a specific team
383
+
384
+ **Which team gets the sessions** is decided by the API key you are logged in with. Each key belongs to one workspace (personal or a team), and `spooling push` sends to that workspace. Mint a key for the team in the app, then log in with it:
385
+
386
+ ```bash
387
+ spooling cloud login --key sk_<team-key> # replaces the stored key; later pushes go to this team
388
+ spooling cloud status # session/cost totals of the workspace this key belongs to
389
+ ```
390
+
391
+ To push to a different team, log in with that team's key. Only one key is stored at a time. `cloud status` doesn't print the workspace name, so compare its totals with what the team shows in the app.
392
+
393
+ **Which sessions go up.** With no filters, `spooling push` sends the most recent `--limit` sessions from every project on the machine. Use these to send only some of them. Filters combine with AND:
394
+
395
+ | Option | Matches |
396
+ |---|---|
397
+ | `--project NAME` | Sessions whose project name is exactly `NAME` (find names with `spooling cost breakdown --by project`) |
398
+ | `--cwd TEXT` | Sessions whose working directory contains `TEXT` (case-insensitive) |
399
+ | `--title TEXT` | Sessions whose title contains `TEXT` (case-insensitive). Useful when an agent was launched from your home directory, so every session shares a generic working directory, but the project name is in the title |
400
+
401
+ ```bash
402
+ spooling cloud login --key sk_<team-key>
403
+ spooling push --cwd toebox --dry-run # preview what would be sent; nothing is uploaded
404
+ spooling push --cwd toebox # send only sessions from the toebox directory
405
+ spooling push --project my-app --limit 200
406
+ spooling push --title islet # sessions with "islet" in the title
407
+ ```
408
+
409
+ **Share the same sessions with more than one team.** Add `--copy` to write the sessions into the workspace you are logged into as fresh rows, even if they were already pushed to another workspace. Re-running is safe:
410
+
411
+ ```bash
412
+ spooling cloud login --key sk_<other-team-key>
413
+ spooling push --cwd toebox --copy
414
+ ```
415
+
416
+ **Include trace data.** Add `--with-spans` to also push each session's trace and spans (per-LLM-call usage, cost, tool calls, MCP calls and agent runs). The Traces page in the app, its agent, tool and MCP filters, and `spooling agents --cloud` / `spooling mcps --cloud` all rely on it. `--with-spans` can't be combined with `--copy` yet.
417
+
418
+ **Secrets** (cloud and AWS keys, GitHub, OpenAI, Anthropic and Stripe tokens, PEM private keys, and `KEY=VALUE` lines whose key looks sensitive) are redacted on your machine before anything is uploaded. Pass `--no-redact` only if you are sure the content is clean.
419
+
420
+ `spooling cloud watch` has no filters: it keeps pushing every new or updated session to the workspace you are logged into. Use filtered `spooling push` runs when you need to keep some sessions out.
421
+
382
422
  To bring sessions from the cloud back down, use `spooling cloud pull`, or `spooling cloud sync` for both directions.
383
423
 
384
424
  ### Watch (continuous push)
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "spooling"
3
- version = "0.2.13"
3
+ version = "0.2.14"
4
4
  description = "Local session tracker and semantic search for AI coding assistants"
5
5
  readme = "README.md"
6
6
  authors = [{ name = "Parsed Analytics, Inc." }]
@@ -627,7 +627,7 @@ _SYNC_OPTION = click.option(
627
627
  @click.option(
628
628
  "--project",
629
629
  default=None,
630
- help="Only push sessions whose project name matches exactly. Pair with `spooling stats --by project` to discover names.",
630
+ help="Only push sessions whose project name matches exactly. Pair with `spooling cost breakdown --by project` to discover names.",
631
631
  )
632
632
  @click.option(
633
633
  "--cwd",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: spooling
3
- Version: 0.2.13
3
+ Version: 0.2.14
4
4
  Summary: Local session tracker and semantic search for AI coding assistants
5
5
  Author: Parsed Analytics, Inc.
6
6
  License: MIT
@@ -415,6 +415,46 @@ spooling push --dry-run # show what would be pushed
415
415
 
416
416
  `push` ingests new provider sessions into the local database before uploading, so you don't need to run `spooling sync` first. The server upserts by session id, so re-running is safe.
417
417
 
418
+ ### Push only some sessions, or to a specific team
419
+
420
+ **Which team gets the sessions** is decided by the API key you are logged in with. Each key belongs to one workspace (personal or a team), and `spooling push` sends to that workspace. Mint a key for the team in the app, then log in with it:
421
+
422
+ ```bash
423
+ spooling cloud login --key sk_<team-key> # replaces the stored key; later pushes go to this team
424
+ spooling cloud status # session/cost totals of the workspace this key belongs to
425
+ ```
426
+
427
+ To push to a different team, log in with that team's key. Only one key is stored at a time. `cloud status` doesn't print the workspace name, so compare its totals with what the team shows in the app.
428
+
429
+ **Which sessions go up.** With no filters, `spooling push` sends the most recent `--limit` sessions from every project on the machine. Use these to send only some of them. Filters combine with AND:
430
+
431
+ | Option | Matches |
432
+ |---|---|
433
+ | `--project NAME` | Sessions whose project name is exactly `NAME` (find names with `spooling cost breakdown --by project`) |
434
+ | `--cwd TEXT` | Sessions whose working directory contains `TEXT` (case-insensitive) |
435
+ | `--title TEXT` | Sessions whose title contains `TEXT` (case-insensitive). Useful when an agent was launched from your home directory, so every session shares a generic working directory, but the project name is in the title |
436
+
437
+ ```bash
438
+ spooling cloud login --key sk_<team-key>
439
+ spooling push --cwd toebox --dry-run # preview what would be sent; nothing is uploaded
440
+ spooling push --cwd toebox # send only sessions from the toebox directory
441
+ spooling push --project my-app --limit 200
442
+ spooling push --title islet # sessions with "islet" in the title
443
+ ```
444
+
445
+ **Share the same sessions with more than one team.** Add `--copy` to write the sessions into the workspace you are logged into as fresh rows, even if they were already pushed to another workspace. Re-running is safe:
446
+
447
+ ```bash
448
+ spooling cloud login --key sk_<other-team-key>
449
+ spooling push --cwd toebox --copy
450
+ ```
451
+
452
+ **Include trace data.** Add `--with-spans` to also push each session's trace and spans (per-LLM-call usage, cost, tool calls, MCP calls and agent runs). The Traces page in the app, its agent, tool and MCP filters, and `spooling agents --cloud` / `spooling mcps --cloud` all rely on it. `--with-spans` can't be combined with `--copy` yet.
453
+
454
+ **Secrets** (cloud and AWS keys, GitHub, OpenAI, Anthropic and Stripe tokens, PEM private keys, and `KEY=VALUE` lines whose key looks sensitive) are redacted on your machine before anything is uploaded. Pass `--no-redact` only if you are sure the content is clean.
455
+
456
+ `spooling cloud watch` has no filters: it keeps pushing every new or updated session to the workspace you are logged into. Use filtered `spooling push` runs when you need to keep some sessions out.
457
+
418
458
  To bring sessions from the cloud back down, use `spooling cloud pull`, or `spooling cloud sync` for both directions.
419
459
 
420
460
  ### Watch (continuous push)
@@ -67,6 +67,7 @@ spooling/providers/windsurf.py
67
67
  tests/test_agent_spans.py
68
68
  tests/test_claude_code_provider.py
69
69
  tests/test_cloud_errors.py
70
+ tests/test_docs.py
70
71
  tests/test_insights.py
71
72
  tests/test_mcp_auth_middleware.py
72
73
  tests/test_session_ids.py
@@ -0,0 +1,31 @@
1
+ """Docs/help text must only point at options that exist."""
2
+
3
+ from click.testing import CliRunner
4
+
5
+ from spooling.cli import cli
6
+
7
+
8
+ def _help(*args):
9
+ return CliRunner().invoke(cli, [*args, "--help"]).output
10
+
11
+
12
+ def test_push_help_points_at_a_real_command_for_project_names():
13
+ out = _help("push")
14
+ assert "stats --by" not in out
15
+ assert "cost breakdown --by project" in out
16
+ # and that command really has the option the help names
17
+ assert "--by" in _help("cost", "breakdown")
18
+
19
+
20
+ def test_push_documents_scoping_and_team_options():
21
+ out = _help("push")
22
+ for opt in ("--project", "--cwd", "--title", "--copy", "--with-spans", "--dry-run", "--no-redact"):
23
+ assert opt in out
24
+
25
+
26
+ def test_readme_documents_every_push_scoping_option():
27
+ from pathlib import Path
28
+ readme = (Path(__file__).resolve().parent.parent / "README.md").read_text()
29
+ for opt in ("--project", "--cwd", "--title", "--copy", "--with-spans", "--dry-run", "--no-redact", "cloud login --key sk_<team-key>"):
30
+ assert opt in readme, f"README does not mention {opt}"
31
+ assert "stats --by" not in readme
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