gitgrip 1.5.0__py3-none-any.whl

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. gitgrip-1.5.0.dist-info/METADATA +13 -0
  2. gitgrip-1.5.0.dist-info/RECORD +80 -0
  3. gitgrip-1.5.0.dist-info/WHEEL +5 -0
  4. gitgrip-1.5.0.dist-info/entry_points.txt +2 -0
  5. gitgrip-1.5.0.dist-info/top_level.txt +2 -0
  6. gr2/__init__.py +0 -0
  7. gr2/overlay/__init__.py +6 -0
  8. gr2/overlay/activate.py +196 -0
  9. gr2/overlay/agent_manifest.py +138 -0
  10. gr2/overlay/cli.py +181 -0
  11. gr2/overlay/cross_repo.py +124 -0
  12. gr2/overlay/drivers.py +113 -0
  13. gr2/overlay/introspection.py +155 -0
  14. gr2/overlay/language_drivers.py +115 -0
  15. gr2/overlay/objects.py +412 -0
  16. gr2/overlay/perf.py +251 -0
  17. gr2/overlay/refs.py +36 -0
  18. gr2/overlay/trust.py +150 -0
  19. gr2/overlay/types.py +69 -0
  20. gr2/overlay/units.py +313 -0
  21. gr2/overlay/workspace_spec.py +59 -0
  22. gr2/prototypes/__init__.py +0 -0
  23. gr2/prototypes/cache_materialization_probe.py +190 -0
  24. gr2/prototypes/concurrent_event_stress.py +199 -0
  25. gr2/prototypes/concurrent_lease_stress.py +240 -0
  26. gr2/prototypes/concurrent_workspace_cap_stress.py +231 -0
  27. gr2/prototypes/contribution_protocol.py +665 -0
  28. gr2/prototypes/cross_mode_lane_stress.py +986 -0
  29. gr2/prototypes/jsonl_store.py +158 -0
  30. gr2/prototypes/lane_workspace_prototype.py +2088 -0
  31. gr2/prototypes/layout_model_probe.py +139 -0
  32. gr2/prototypes/propagation_daemon.py +546 -0
  33. gr2/prototypes/propagation_state_machine.py +1478 -0
  34. gr2/prototypes/python_exec_playground.py +194 -0
  35. gr2/prototypes/python_hook_runtime_playground.py +240 -0
  36. gr2/prototypes/python_migration_playground.py +144 -0
  37. gr2/prototypes/python_review_checkout_playground.py +242 -0
  38. gr2/prototypes/python_spec_apply_playground.py +282 -0
  39. gr2/prototypes/real_git_lane_materialization.py +248 -0
  40. gr2/prototypes/real_git_playground.py +334 -0
  41. gr2/prototypes/recall_lane_history.py +274 -0
  42. gr2/prototypes/repo_maintenance_prototype.py +659 -0
  43. gr2/prototypes/repo_transport_probe.py +147 -0
  44. gr2/python_cli/__init__.py +2 -0
  45. gr2/python_cli/__main__.py +6 -0
  46. gr2/python_cli/add.py +51 -0
  47. gr2/python_cli/app.py +2516 -0
  48. gr2/python_cli/branch.py +67 -0
  49. gr2/python_cli/channel_bridge.py +131 -0
  50. gr2/python_cli/clone_exec.py +1019 -0
  51. gr2/python_cli/commit.py +199 -0
  52. gr2/python_cli/config.py +291 -0
  53. gr2/python_cli/env_exec.py +419 -0
  54. gr2/python_cli/events.py +529 -0
  55. gr2/python_cli/execops.py +372 -0
  56. gr2/python_cli/failures.py +98 -0
  57. gr2/python_cli/file_exec.py +256 -0
  58. gr2/python_cli/gitops.py +226 -0
  59. gr2/python_cli/grip.py +1337 -0
  60. gr2/python_cli/grip_cli.py +493 -0
  61. gr2/python_cli/hooks.py +450 -0
  62. gr2/python_cli/launch_exec.py +786 -0
  63. gr2/python_cli/merge_verification.py +274 -0
  64. gr2/python_cli/migration.py +985 -0
  65. gr2/python_cli/open_gr_review.py +699 -0
  66. gr2/python_cli/platform.py +441 -0
  67. gr2/python_cli/pr.py +487 -0
  68. gr2/python_cli/project_review.py +314 -0
  69. gr2/python_cli/prune.py +365 -0
  70. gr2/python_cli/push.py +172 -0
  71. gr2/python_cli/review.py +462 -0
  72. gr2/python_cli/review_ephemeral.py +143 -0
  73. gr2/python_cli/review_run.py +621 -0
  74. gr2/python_cli/spec_apply.py +1285 -0
  75. gr2/python_cli/staging_cleanup.py +205 -0
  76. gr2/python_cli/syncops.py +920 -0
  77. gr2/python_cli/target.py +100 -0
  78. gr2/python_cli/workspace_snapshot.py +105 -0
  79. gr2/schemas/gr2-materialization-plan-v1.schema.json +191 -0
  80. gr2_overlay/__init__.py +37 -0
@@ -0,0 +1,274 @@
1
+ #!/usr/bin/env python3
2
+ """Prototype recall-friendly indexing over gr2 lane event history."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import argparse
7
+ import json
8
+ from collections import defaultdict
9
+ from datetime import UTC, datetime, timedelta
10
+ from pathlib import Path
11
+ from typing import Any
12
+
13
+ from gr2.prototypes.jsonl_store import (
14
+ JsonlRead,
15
+ append_jsonl,
16
+ read_jsonl,
17
+ warn_unreadable,
18
+ )
19
+
20
+
21
+ def parse_args() -> argparse.Namespace:
22
+ parser = argparse.ArgumentParser(description="Prototype recall lane history surface")
23
+ sub = parser.add_subparsers(dest="command", required=True)
24
+
25
+ demo = sub.add_parser("demo-data")
26
+ demo.add_argument("workspace_root", type=Path)
27
+
28
+ query = sub.add_parser("query")
29
+ query.add_argument("workspace_root", type=Path)
30
+ query.add_argument("--lane")
31
+ query.add_argument("--actor")
32
+ query.add_argument("--repo")
33
+ query.add_argument("--start")
34
+ query.add_argument("--end")
35
+ query.add_argument("--json", action="store_true")
36
+
37
+ return parser.parse_args()
38
+
39
+
40
+ def events_dir(workspace_root: Path) -> Path:
41
+ return workspace_root / ".grip" / "events"
42
+
43
+
44
+ def lane_events_file(workspace_root: Path) -> Path:
45
+ return events_dir(workspace_root) / "lane_events.jsonl"
46
+
47
+
48
+ def load_jsonl(path: Path) -> JsonlRead:
49
+ """Rows AND the lines that could not be read. See ``jsonl_store.JsonlRead``."""
50
+
51
+ return read_jsonl(path)
52
+
53
+
54
+ def parse_ts(raw: str) -> datetime:
55
+ return datetime.fromisoformat(raw)
56
+
57
+
58
+ def now_utc() -> datetime:
59
+ return datetime.now(UTC).replace(microsecond=0)
60
+
61
+
62
+ def event_key(event: dict) -> tuple:
63
+ return (
64
+ event.get("timestamp", ""),
65
+ event.get("lane", ""),
66
+ event.get("type", ""),
67
+ event.get("agent", ""),
68
+ )
69
+
70
+
71
+ def build_index(events: list[dict]) -> dict[str, Any]:
72
+ by_lane: dict[str, list[dict]] = defaultdict(list)
73
+ by_actor: dict[str, list[dict]] = defaultdict(list)
74
+ by_repo: dict[str, list[dict]] = defaultdict(list)
75
+
76
+ for event in sorted(events, key=event_key):
77
+ lane = event.get("lane")
78
+ actor = event.get("agent")
79
+ repos = event.get("repos", [])
80
+ if lane:
81
+ by_lane[lane].append(event)
82
+ if actor:
83
+ by_actor[actor].append(event)
84
+ for repo in repos:
85
+ by_repo[repo].append(event)
86
+
87
+ return {
88
+ "by_lane": dict(by_lane),
89
+ "by_actor": dict(by_actor),
90
+ "by_repo": dict(by_repo),
91
+ "all": sorted(events, key=event_key),
92
+ }
93
+
94
+
95
+ def lane_history(index: dict[str, Any], lane_name: str) -> dict[str, Any]:
96
+ rows = index["by_lane"].get(lane_name, [])
97
+ return {
98
+ "query": {"lane": lane_name},
99
+ "count": len(rows),
100
+ "timeline": rows,
101
+ }
102
+
103
+
104
+ def actor_history(index: dict[str, Any], actor: str) -> dict[str, Any]:
105
+ rows = index["by_actor"].get(actor, [])
106
+ touched_lanes = sorted({row.get("lane") for row in rows if row.get("lane")})
107
+ return {
108
+ "query": {"actor": actor},
109
+ "count": len(rows),
110
+ "lanes": touched_lanes,
111
+ "timeline": rows,
112
+ }
113
+
114
+
115
+ def repo_activity(index: dict[str, Any], repo: str) -> dict[str, Any]:
116
+ rows = index["by_repo"].get(repo, [])
117
+ actors = sorted({row.get("agent") for row in rows if row.get("agent")})
118
+ return {
119
+ "query": {"repo": repo},
120
+ "count": len(rows),
121
+ "actors": actors,
122
+ "timeline": rows,
123
+ }
124
+
125
+
126
+ def time_range(index: dict[str, Any], start: str, end: str) -> dict[str, Any]:
127
+ start_dt = parse_ts(start)
128
+ end_dt = parse_ts(end)
129
+ rows = [event for event in index["all"] if start_dt <= parse_ts(event["timestamp"]) <= end_dt]
130
+ return {
131
+ "query": {"start": start, "end": end},
132
+ "count": len(rows),
133
+ "timeline": rows,
134
+ }
135
+
136
+
137
+ def demo_events() -> list[dict]:
138
+ base = now_utc() - timedelta(days=7)
139
+
140
+ def at(minutes: int) -> str:
141
+ return (base + timedelta(minutes=minutes)).isoformat()
142
+
143
+ return [
144
+ {
145
+ "type": "lane_enter",
146
+ "agent": "agent:alpha",
147
+ "agent_id": "agent_a1b2c3",
148
+ "owner_unit": "design-research",
149
+ "lane": "auth-refactor",
150
+ "lane_type": "feature",
151
+ "repos": ["grip", "billing"],
152
+ "timestamp": at(0),
153
+ },
154
+ {
155
+ "type": "lease_acquire",
156
+ "agent": "agent:alpha",
157
+ "agent_id": "agent_a1b2c3",
158
+ "owner_unit": "design-research",
159
+ "lane": "auth-refactor",
160
+ "lane_type": "feature",
161
+ "lease_mode": "edit",
162
+ "repos": ["grip", "billing"],
163
+ "timestamp": at(2),
164
+ },
165
+ {
166
+ "type": "lane_enter",
167
+ "agent": "agent:beta",
168
+ "agent_id": "agent_d4e5f6",
169
+ "owner_unit": "qa-beta",
170
+ "lane": "backend-review",
171
+ "lane_type": "review",
172
+ "repos": ["tests", "grip"],
173
+ "timestamp": at(5),
174
+ },
175
+ {
176
+ "type": "lease_acquire",
177
+ "agent": "agent:beta",
178
+ "agent_id": "agent_d4e5f6",
179
+ "owner_unit": "qa-beta",
180
+ "lane": "backend-review",
181
+ "lane_type": "review",
182
+ "lease_mode": "review",
183
+ "repos": ["tests", "grip"],
184
+ "timestamp": at(7),
185
+ },
186
+ {
187
+ "type": "lease_release",
188
+ "agent": "agent:alpha",
189
+ "agent_id": "agent_a1b2c3",
190
+ "owner_unit": "design-research",
191
+ "lane": "auth-refactor",
192
+ "lane_type": "feature",
193
+ "repos": ["grip", "billing"],
194
+ "timestamp": at(45),
195
+ },
196
+ {
197
+ "type": "lane_exit",
198
+ "agent": "agent:alpha",
199
+ "agent_id": "agent_a1b2c3",
200
+ "owner_unit": "design-research",
201
+ "lane": "auth-refactor",
202
+ "lane_type": "feature",
203
+ "repos": ["grip", "billing"],
204
+ "timestamp": at(47),
205
+ },
206
+ {
207
+ "type": "lane_enter",
208
+ "agent": "agent:delta",
209
+ "agent_id": "agent_9f8e7d",
210
+ "owner_unit": "release-control",
211
+ "lane": "auth-refactor",
212
+ "lane_type": "review",
213
+ "repos": ["grip", "billing"],
214
+ "timestamp": at(60),
215
+ },
216
+ {
217
+ "type": "lease_acquire",
218
+ "agent": "agent:delta",
219
+ "agent_id": "agent_9f8e7d",
220
+ "owner_unit": "release-control",
221
+ "lane": "auth-refactor",
222
+ "lane_type": "review",
223
+ "lease_mode": "review",
224
+ "repos": ["grip", "billing"],
225
+ "timestamp": at(62),
226
+ },
227
+ ]
228
+
229
+
230
+ def write_demo_data(workspace_root: Path) -> dict[str, Any]:
231
+ path = lane_events_file(workspace_root)
232
+ rows = demo_events()
233
+ path.parent.mkdir(parents=True, exist_ok=True)
234
+ path.write_text("")
235
+ for row in rows:
236
+ append_jsonl(path, row)
237
+ return {"path": str(path), "count": len(rows)}
238
+
239
+
240
+ def render_result(result: dict[str, Any], as_json: bool) -> int:
241
+ if as_json:
242
+ print(json.dumps(result, indent=2))
243
+ return 0
244
+ print(json.dumps(result, indent=2))
245
+ return 0
246
+
247
+
248
+ def main() -> int:
249
+ args = parse_args()
250
+ if args.command == "demo-data":
251
+ result = write_demo_data(args.workspace_root.resolve())
252
+ print(json.dumps(result, indent=2))
253
+ return 0
254
+
255
+ read = load_jsonl(lane_events_file(args.workspace_root.resolve()))
256
+ warn_unreadable(read, "the lane event log")
257
+ index = build_index(read.rows)
258
+
259
+ if args.command == "query":
260
+ if args.lane:
261
+ return render_result(lane_history(index, args.lane), args.json)
262
+ if args.actor:
263
+ return render_result(actor_history(index, args.actor), args.json)
264
+ if args.repo:
265
+ return render_result(repo_activity(index, args.repo), args.json)
266
+ if args.start and args.end:
267
+ return render_result(time_range(index, args.start, args.end), args.json)
268
+ raise SystemExit("query requires one of --lane, --actor, --repo, or --start/--end")
269
+
270
+ raise SystemExit(f"unknown command: {args.command}")
271
+
272
+
273
+ if __name__ == "__main__":
274
+ raise SystemExit(main())