up-cli 0.2.0__py3-none-any.whl → 0.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.
- up/__init__.py +1 -1
- up/ai_cli.py +229 -0
- up/cli.py +54 -9
- up/commands/agent.py +521 -0
- up/commands/bisect.py +343 -0
- up/commands/branch.py +350 -0
- up/commands/init.py +195 -6
- up/commands/learn.py +1392 -32
- up/commands/memory.py +545 -0
- up/commands/provenance.py +267 -0
- up/commands/review.py +239 -0
- up/commands/start.py +752 -42
- up/commands/status.py +173 -18
- up/commands/sync.py +317 -0
- up/commands/vibe.py +304 -0
- up/context.py +64 -10
- up/core/__init__.py +69 -0
- up/core/checkpoint.py +479 -0
- up/core/provenance.py +364 -0
- up/core/state.py +678 -0
- up/events.py +512 -0
- up/git/__init__.py +37 -0
- up/git/utils.py +270 -0
- up/git/worktree.py +331 -0
- up/learn/__init__.py +155 -0
- up/learn/analyzer.py +227 -0
- up/learn/plan.py +374 -0
- up/learn/research.py +511 -0
- up/learn/utils.py +117 -0
- up/memory.py +1096 -0
- up/parallel.py +551 -0
- up/templates/config/__init__.py +1 -1
- up/templates/docs/SKILL.md +28 -0
- up/templates/docs/__init__.py +341 -0
- up/templates/docs/standards/HEADERS.md +24 -0
- up/templates/docs/standards/STRUCTURE.md +18 -0
- up/templates/docs/standards/TEMPLATES.md +19 -0
- up/templates/loop/__init__.py +92 -32
- up/ui/__init__.py +14 -0
- up/ui/loop_display.py +650 -0
- up/ui/theme.py +137 -0
- {up_cli-0.2.0.dist-info → up_cli-0.5.0.dist-info}/METADATA +160 -15
- up_cli-0.5.0.dist-info/RECORD +55 -0
- up_cli-0.2.0.dist-info/RECORD +0 -23
- {up_cli-0.2.0.dist-info → up_cli-0.5.0.dist-info}/WHEEL +0 -0
- {up_cli-0.2.0.dist-info → up_cli-0.5.0.dist-info}/entry_points.txt +0 -0
up/commands/vibe.py
ADDED
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
"""up save/reset/diff - Vibe coding safety commands.
|
|
2
|
+
|
|
3
|
+
These commands provide the core safety rails for AI-assisted development:
|
|
4
|
+
- up save: Create checkpoint before AI work
|
|
5
|
+
- up reset: Restore to checkpoint when AI fails
|
|
6
|
+
- up diff: Review AI changes before accepting
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import subprocess
|
|
10
|
+
import sys
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
import click
|
|
14
|
+
from rich.console import Console
|
|
15
|
+
from rich.panel import Panel
|
|
16
|
+
from rich.syntax import Syntax
|
|
17
|
+
from rich.table import Table
|
|
18
|
+
|
|
19
|
+
from up.core.checkpoint import (
|
|
20
|
+
get_checkpoint_manager,
|
|
21
|
+
CheckpointManager,
|
|
22
|
+
CheckpointNotFoundError,
|
|
23
|
+
NotAGitRepoError,
|
|
24
|
+
)
|
|
25
|
+
from up.core.state import get_state_manager
|
|
26
|
+
|
|
27
|
+
console = Console()
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# =============================================================================
|
|
31
|
+
# up save - Create checkpoint
|
|
32
|
+
# =============================================================================
|
|
33
|
+
|
|
34
|
+
@click.command("save")
|
|
35
|
+
@click.argument("message", required=False)
|
|
36
|
+
@click.option("--task", "-t", help="Associated task ID")
|
|
37
|
+
@click.option("--quiet", "-q", is_flag=True, help="Minimal output")
|
|
38
|
+
def save_cmd(message: str, task: str, quiet: bool):
|
|
39
|
+
"""Create a checkpoint before AI work.
|
|
40
|
+
|
|
41
|
+
Automatically commits any dirty files and creates a tag for easy recovery.
|
|
42
|
+
Use 'up reset' to restore if AI generation goes wrong.
|
|
43
|
+
|
|
44
|
+
\b
|
|
45
|
+
Examples:
|
|
46
|
+
up save # Auto-named checkpoint
|
|
47
|
+
up save "before auth" # Named checkpoint
|
|
48
|
+
up save -t US-004 # Link to task
|
|
49
|
+
"""
|
|
50
|
+
cwd = Path.cwd()
|
|
51
|
+
|
|
52
|
+
try:
|
|
53
|
+
manager = get_checkpoint_manager(cwd)
|
|
54
|
+
|
|
55
|
+
# Check for changes
|
|
56
|
+
has_changes = manager._has_changes()
|
|
57
|
+
|
|
58
|
+
if not has_changes and not quiet:
|
|
59
|
+
console.print("[dim]No changes to checkpoint (working tree clean)[/]")
|
|
60
|
+
|
|
61
|
+
# Create checkpoint
|
|
62
|
+
metadata = manager.save(
|
|
63
|
+
message=message,
|
|
64
|
+
task_id=task,
|
|
65
|
+
auto_commit=True
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
if quiet:
|
|
69
|
+
console.print(metadata.id)
|
|
70
|
+
else:
|
|
71
|
+
console.print(f"[green]✓[/] Checkpoint created: [cyan]{metadata.id}[/]")
|
|
72
|
+
if metadata.files_changed > 0:
|
|
73
|
+
console.print(f" Committed {metadata.files_changed} file(s)")
|
|
74
|
+
console.print(f" Commit: {metadata.commit_sha[:8]}")
|
|
75
|
+
console.print(f" Tag: {metadata.tag_name}")
|
|
76
|
+
console.print(f"\nTo restore: [cyan]up reset {metadata.id}[/]")
|
|
77
|
+
|
|
78
|
+
except NotAGitRepoError:
|
|
79
|
+
console.print("[red]Error:[/] Not a git repository")
|
|
80
|
+
console.print("Initialize with: [cyan]git init[/]")
|
|
81
|
+
sys.exit(1)
|
|
82
|
+
except Exception as e:
|
|
83
|
+
console.print(f"[red]Error:[/] {e}")
|
|
84
|
+
sys.exit(1)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
# =============================================================================
|
|
88
|
+
# up reset - Restore checkpoint
|
|
89
|
+
# =============================================================================
|
|
90
|
+
|
|
91
|
+
@click.command("reset")
|
|
92
|
+
@click.argument("checkpoint_id", required=False)
|
|
93
|
+
@click.option("--hard", is_flag=True, default=True, help="Hard reset (discard changes)")
|
|
94
|
+
@click.option("--soft", is_flag=True, help="Soft reset (keep changes staged)")
|
|
95
|
+
@click.option("--list", "list_checkpoints", is_flag=True, help="List available checkpoints")
|
|
96
|
+
@click.option("--yes", "-y", is_flag=True, help="Skip confirmation")
|
|
97
|
+
def reset_cmd(checkpoint_id: str, hard: bool, soft: bool, list_checkpoints: bool, yes: bool):
|
|
98
|
+
"""Reset to a checkpoint.
|
|
99
|
+
|
|
100
|
+
Instantly restores your code to a previous checkpoint state.
|
|
101
|
+
Use when AI generation produces bad results.
|
|
102
|
+
|
|
103
|
+
\b
|
|
104
|
+
Examples:
|
|
105
|
+
up reset # Reset to last checkpoint
|
|
106
|
+
up reset cp-20260204-1234 # Reset to specific checkpoint
|
|
107
|
+
up reset --list # Show available checkpoints
|
|
108
|
+
"""
|
|
109
|
+
cwd = Path.cwd()
|
|
110
|
+
|
|
111
|
+
try:
|
|
112
|
+
manager = get_checkpoint_manager(cwd)
|
|
113
|
+
|
|
114
|
+
# List mode
|
|
115
|
+
if list_checkpoints:
|
|
116
|
+
checkpoints = manager.list_checkpoints(limit=20)
|
|
117
|
+
|
|
118
|
+
if not checkpoints:
|
|
119
|
+
console.print("[dim]No checkpoints available[/]")
|
|
120
|
+
return
|
|
121
|
+
|
|
122
|
+
table = Table(title="Available Checkpoints")
|
|
123
|
+
table.add_column("ID", style="cyan")
|
|
124
|
+
table.add_column("Message")
|
|
125
|
+
table.add_column("Branch")
|
|
126
|
+
table.add_column("Time")
|
|
127
|
+
|
|
128
|
+
for cp in checkpoints:
|
|
129
|
+
table.add_row(
|
|
130
|
+
cp.id,
|
|
131
|
+
cp.message[:40] + "..." if len(cp.message) > 40 else cp.message,
|
|
132
|
+
cp.branch,
|
|
133
|
+
cp.created_at[:19]
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
console.print(table)
|
|
137
|
+
return
|
|
138
|
+
|
|
139
|
+
# Get checkpoint info for confirmation
|
|
140
|
+
if checkpoint_id:
|
|
141
|
+
target = checkpoint_id
|
|
142
|
+
else:
|
|
143
|
+
last = manager.get_last_checkpoint()
|
|
144
|
+
if not last:
|
|
145
|
+
console.print("[yellow]No checkpoints available[/]")
|
|
146
|
+
console.print("Create one with: [cyan]up save[/]")
|
|
147
|
+
return
|
|
148
|
+
target = last.id
|
|
149
|
+
|
|
150
|
+
# Show what will be reset
|
|
151
|
+
stats = manager.diff_stats(target)
|
|
152
|
+
|
|
153
|
+
console.print(f"[bold]Reset to checkpoint:[/] {target}")
|
|
154
|
+
if stats["files"] > 0:
|
|
155
|
+
console.print(f" Changes to discard: {stats['files']} files, "
|
|
156
|
+
f"+{stats['insertions']} -{stats['deletions']}")
|
|
157
|
+
|
|
158
|
+
# Confirm
|
|
159
|
+
if not yes:
|
|
160
|
+
if not click.confirm("Proceed with reset?"):
|
|
161
|
+
console.print("[dim]Cancelled[/]")
|
|
162
|
+
return
|
|
163
|
+
|
|
164
|
+
# Perform reset
|
|
165
|
+
use_hard = not soft
|
|
166
|
+
metadata = manager.restore(checkpoint_id=target, hard=use_hard)
|
|
167
|
+
|
|
168
|
+
console.print(f"\n[green]✓[/] Reset to [cyan]{metadata.id}[/]")
|
|
169
|
+
console.print(f" Commit: {metadata.commit_sha[:8]}")
|
|
170
|
+
|
|
171
|
+
# Update state
|
|
172
|
+
state_manager = get_state_manager(cwd)
|
|
173
|
+
state_manager.state.loop.consecutive_failures = 0 # Reset doom loop counter
|
|
174
|
+
state_manager.save()
|
|
175
|
+
|
|
176
|
+
except NotAGitRepoError:
|
|
177
|
+
console.print("[red]Error:[/] Not a git repository")
|
|
178
|
+
sys.exit(1)
|
|
179
|
+
except CheckpointNotFoundError as e:
|
|
180
|
+
console.print(f"[red]Error:[/] {e}")
|
|
181
|
+
console.print("List available: [cyan]up reset --list[/]")
|
|
182
|
+
sys.exit(1)
|
|
183
|
+
except Exception as e:
|
|
184
|
+
console.print(f"[red]Error:[/] {e}")
|
|
185
|
+
sys.exit(1)
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
# =============================================================================
|
|
189
|
+
# up diff - Review AI changes
|
|
190
|
+
# =============================================================================
|
|
191
|
+
|
|
192
|
+
@click.command("diff")
|
|
193
|
+
@click.argument("checkpoint_id", required=False)
|
|
194
|
+
@click.option("--stat", is_flag=True, help="Show only stats")
|
|
195
|
+
@click.option("--accept", "-a", is_flag=True, help="Accept changes and commit")
|
|
196
|
+
@click.option("--reject", "-r", is_flag=True, help="Reject changes and reset")
|
|
197
|
+
@click.option("--message", "-m", help="Commit message (with --accept)")
|
|
198
|
+
def diff_cmd(checkpoint_id: str, stat: bool, accept: bool, reject: bool, message: str):
|
|
199
|
+
"""Review AI changes before accepting.
|
|
200
|
+
|
|
201
|
+
Shows a syntax-highlighted diff of changes since the last checkpoint.
|
|
202
|
+
Can accept (commit) or reject (reset) the changes.
|
|
203
|
+
|
|
204
|
+
\b
|
|
205
|
+
Examples:
|
|
206
|
+
up diff # Show diff from last checkpoint
|
|
207
|
+
up diff --stat # Show stats only
|
|
208
|
+
up diff --accept # Accept and commit changes
|
|
209
|
+
up diff --reject # Reject and reset to checkpoint
|
|
210
|
+
"""
|
|
211
|
+
cwd = Path.cwd()
|
|
212
|
+
|
|
213
|
+
try:
|
|
214
|
+
manager = get_checkpoint_manager(cwd)
|
|
215
|
+
|
|
216
|
+
# Get diff
|
|
217
|
+
diff_output = manager.diff_from_checkpoint(checkpoint_id)
|
|
218
|
+
stats = manager.diff_stats(checkpoint_id)
|
|
219
|
+
|
|
220
|
+
if not diff_output and stats["files"] == 0:
|
|
221
|
+
console.print("[dim]No changes since checkpoint[/]")
|
|
222
|
+
return
|
|
223
|
+
|
|
224
|
+
# Stats mode
|
|
225
|
+
if stat:
|
|
226
|
+
console.print(Panel.fit(
|
|
227
|
+
f"[bold]Changes since checkpoint[/]\n\n"
|
|
228
|
+
f"Files: {stats['files']}\n"
|
|
229
|
+
f"Insertions: [green]+{stats['insertions']}[/]\n"
|
|
230
|
+
f"Deletions: [red]-{stats['deletions']}[/]",
|
|
231
|
+
border_style="blue"
|
|
232
|
+
))
|
|
233
|
+
return
|
|
234
|
+
|
|
235
|
+
# Reject mode
|
|
236
|
+
if reject:
|
|
237
|
+
console.print("[yellow]Rejecting changes...[/]")
|
|
238
|
+
manager.restore(checkpoint_id=checkpoint_id)
|
|
239
|
+
console.print("[green]✓[/] Changes rejected, reset to checkpoint")
|
|
240
|
+
return
|
|
241
|
+
|
|
242
|
+
# Accept mode
|
|
243
|
+
if accept:
|
|
244
|
+
# Commit the changes
|
|
245
|
+
result = subprocess.run(
|
|
246
|
+
["git", "add", "-A"],
|
|
247
|
+
cwd=cwd,
|
|
248
|
+
capture_output=True
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
commit_msg = message or "Accept AI changes"
|
|
252
|
+
result = subprocess.run(
|
|
253
|
+
["git", "commit", "-m", commit_msg],
|
|
254
|
+
cwd=cwd,
|
|
255
|
+
capture_output=True,
|
|
256
|
+
text=True
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
if result.returncode == 0:
|
|
260
|
+
console.print(f"[green]✓[/] Changes accepted and committed")
|
|
261
|
+
console.print(f" Message: {commit_msg}")
|
|
262
|
+
else:
|
|
263
|
+
console.print("[yellow]No changes to commit[/]")
|
|
264
|
+
return
|
|
265
|
+
|
|
266
|
+
# Show diff
|
|
267
|
+
console.print(Panel.fit(
|
|
268
|
+
f"[bold]Changes since checkpoint[/] "
|
|
269
|
+
f"({stats['files']} files, +{stats['insertions']} -{stats['deletions']})",
|
|
270
|
+
border_style="blue"
|
|
271
|
+
))
|
|
272
|
+
console.print()
|
|
273
|
+
|
|
274
|
+
# Syntax-highlighted diff
|
|
275
|
+
syntax = Syntax(diff_output, "diff", theme="monokai", line_numbers=False)
|
|
276
|
+
console.print(syntax)
|
|
277
|
+
|
|
278
|
+
# Interactive prompt
|
|
279
|
+
console.print()
|
|
280
|
+
console.print("[bold]Actions:[/]")
|
|
281
|
+
console.print(" [cyan]up diff --accept[/] Accept changes")
|
|
282
|
+
console.print(" [cyan]up diff --reject[/] Reject and reset")
|
|
283
|
+
|
|
284
|
+
except NotAGitRepoError:
|
|
285
|
+
console.print("[red]Error:[/] Not a git repository")
|
|
286
|
+
sys.exit(1)
|
|
287
|
+
except Exception as e:
|
|
288
|
+
console.print(f"[red]Error:[/] {e}")
|
|
289
|
+
sys.exit(1)
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
# =============================================================================
|
|
293
|
+
# Command Group (for future expansion)
|
|
294
|
+
# =============================================================================
|
|
295
|
+
|
|
296
|
+
@click.group()
|
|
297
|
+
def vibe():
|
|
298
|
+
"""Vibe coding safety commands."""
|
|
299
|
+
pass
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
vibe.add_command(save_cmd, name="save")
|
|
303
|
+
vibe.add_command(reset_cmd, name="reset")
|
|
304
|
+
vibe.add_command(diff_cmd, name="diff")
|
up/context.py
CHANGED
|
@@ -127,7 +127,11 @@ def estimate_file_tokens(path: Path) -> int:
|
|
|
127
127
|
|
|
128
128
|
|
|
129
129
|
class ContextManager:
|
|
130
|
-
"""Manages context window budget for AI sessions.
|
|
130
|
+
"""Manages context window budget for AI sessions.
|
|
131
|
+
|
|
132
|
+
Now uses the unified StateManager for storage while maintaining
|
|
133
|
+
backwards compatibility with the existing API.
|
|
134
|
+
"""
|
|
131
135
|
|
|
132
136
|
def __init__(
|
|
133
137
|
self,
|
|
@@ -135,19 +139,46 @@ class ContextManager:
|
|
|
135
139
|
budget: int = DEFAULT_BUDGET
|
|
136
140
|
):
|
|
137
141
|
self.workspace = workspace or Path.cwd()
|
|
138
|
-
|
|
142
|
+
# Old location for migration
|
|
143
|
+
self._old_state_file = self.workspace / ".claude" / "context_budget.json"
|
|
144
|
+
# New unified state
|
|
145
|
+
self._use_unified_state = True
|
|
139
146
|
self.budget = ContextBudget(budget=budget)
|
|
140
147
|
self._load_state()
|
|
141
148
|
|
|
142
149
|
def _load_state(self) -> None:
|
|
143
|
-
"""Load state from file."""
|
|
144
|
-
|
|
150
|
+
"""Load state from unified state manager or migrate from old file."""
|
|
151
|
+
try:
|
|
152
|
+
from up.core.state import get_state_manager
|
|
153
|
+
manager = get_state_manager(self.workspace)
|
|
154
|
+
ctx = manager.state.context
|
|
155
|
+
|
|
156
|
+
# Sync from unified state
|
|
157
|
+
self.budget.budget = ctx.budget
|
|
158
|
+
self.budget.total_tokens = ctx.total_tokens
|
|
159
|
+
self.budget.warning_threshold = ctx.warning_threshold
|
|
160
|
+
self.budget.critical_threshold = ctx.critical_threshold
|
|
161
|
+
self.budget.session_start = ctx.session_start
|
|
162
|
+
|
|
163
|
+
# Convert entries
|
|
164
|
+
self.budget.entries = [
|
|
165
|
+
ContextEntry(**e) if isinstance(e, dict) else e
|
|
166
|
+
for e in ctx.entries
|
|
167
|
+
]
|
|
168
|
+
|
|
169
|
+
except ImportError:
|
|
170
|
+
# Fallback to old file-based storage
|
|
171
|
+
self._use_unified_state = False
|
|
172
|
+
self._load_state_legacy()
|
|
173
|
+
|
|
174
|
+
def _load_state_legacy(self) -> None:
|
|
175
|
+
"""Load state from old file location (for backwards compatibility)."""
|
|
176
|
+
if self._old_state_file.exists():
|
|
145
177
|
try:
|
|
146
|
-
data = json.loads(self.
|
|
178
|
+
data = json.loads(self._old_state_file.read_text())
|
|
147
179
|
self.budget.budget = data.get("budget", DEFAULT_BUDGET)
|
|
148
180
|
self.budget.total_tokens = data.get("total_tokens", 0)
|
|
149
181
|
self.budget.session_start = data.get("session_start", datetime.now().isoformat())
|
|
150
|
-
# Reconstruct entries
|
|
151
182
|
entries_data = data.get("entries", [])
|
|
152
183
|
self.budget.entries = [
|
|
153
184
|
ContextEntry(**e) for e in entries_data
|
|
@@ -156,9 +187,31 @@ class ContextManager:
|
|
|
156
187
|
pass
|
|
157
188
|
|
|
158
189
|
def _save_state(self) -> None:
|
|
159
|
-
"""Save state to
|
|
160
|
-
self.
|
|
161
|
-
|
|
190
|
+
"""Save state to unified state manager."""
|
|
191
|
+
if self._use_unified_state:
|
|
192
|
+
try:
|
|
193
|
+
from up.core.state import get_state_manager
|
|
194
|
+
manager = get_state_manager(self.workspace)
|
|
195
|
+
|
|
196
|
+
# Sync to unified state
|
|
197
|
+
manager.state.context.budget = self.budget.budget
|
|
198
|
+
manager.state.context.total_tokens = self.budget.total_tokens
|
|
199
|
+
manager.state.context.warning_threshold = self.budget.warning_threshold
|
|
200
|
+
manager.state.context.critical_threshold = self.budget.critical_threshold
|
|
201
|
+
manager.state.context.session_start = self.budget.session_start
|
|
202
|
+
manager.state.context.entries = [
|
|
203
|
+
e.to_dict() if hasattr(e, 'to_dict') else e
|
|
204
|
+
for e in self.budget.entries[-50:] # Keep last 50
|
|
205
|
+
]
|
|
206
|
+
|
|
207
|
+
manager.save()
|
|
208
|
+
return
|
|
209
|
+
except ImportError:
|
|
210
|
+
pass
|
|
211
|
+
|
|
212
|
+
# Fallback to old file-based storage
|
|
213
|
+
self._old_state_file.parent.mkdir(parents=True, exist_ok=True)
|
|
214
|
+
self._old_state_file.write_text(json.dumps(self.budget.to_dict(), indent=2))
|
|
162
215
|
|
|
163
216
|
def record_file_read(self, path: Path) -> ContextEntry:
|
|
164
217
|
"""Record a file being read into context.
|
|
@@ -327,7 +380,8 @@ def create_context_budget_file(target_dir: Path, budget: int = DEFAULT_BUDGET) -
|
|
|
327
380
|
"""
|
|
328
381
|
manager = ContextManager(workspace=target_dir, budget=budget)
|
|
329
382
|
manager.reset()
|
|
330
|
-
|
|
383
|
+
# Return the unified state file path
|
|
384
|
+
return target_dir / ".up" / "state.json"
|
|
331
385
|
|
|
332
386
|
|
|
333
387
|
# CLI integration
|
up/core/__init__.py
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"""Core modules for up-cli.
|
|
2
|
+
|
|
3
|
+
This package contains the foundational modules used across all commands:
|
|
4
|
+
- state: Unified state management
|
|
5
|
+
- checkpoint: Git checkpoint operations
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from up.core.state import (
|
|
9
|
+
UnifiedState,
|
|
10
|
+
LoopState,
|
|
11
|
+
ContextState,
|
|
12
|
+
AgentState,
|
|
13
|
+
CircuitBreakerState,
|
|
14
|
+
StateManager,
|
|
15
|
+
get_state_manager,
|
|
16
|
+
get_state,
|
|
17
|
+
save_state,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
from up.core.checkpoint import (
|
|
21
|
+
CheckpointManager,
|
|
22
|
+
CheckpointMetadata,
|
|
23
|
+
CheckpointError,
|
|
24
|
+
GitError,
|
|
25
|
+
NotAGitRepoError,
|
|
26
|
+
CheckpointNotFoundError,
|
|
27
|
+
get_checkpoint_manager,
|
|
28
|
+
save_checkpoint,
|
|
29
|
+
restore_checkpoint,
|
|
30
|
+
get_diff,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
from up.core.provenance import (
|
|
34
|
+
ProvenanceEntry,
|
|
35
|
+
ProvenanceManager,
|
|
36
|
+
get_provenance_manager,
|
|
37
|
+
track_ai_operation,
|
|
38
|
+
complete_ai_operation,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
__all__ = [
|
|
42
|
+
# State
|
|
43
|
+
"UnifiedState",
|
|
44
|
+
"LoopState",
|
|
45
|
+
"ContextState",
|
|
46
|
+
"AgentState",
|
|
47
|
+
"CircuitBreakerState",
|
|
48
|
+
"StateManager",
|
|
49
|
+
"get_state_manager",
|
|
50
|
+
"get_state",
|
|
51
|
+
"save_state",
|
|
52
|
+
# Checkpoint
|
|
53
|
+
"CheckpointManager",
|
|
54
|
+
"CheckpointMetadata",
|
|
55
|
+
"CheckpointError",
|
|
56
|
+
"GitError",
|
|
57
|
+
"NotAGitRepoError",
|
|
58
|
+
"CheckpointNotFoundError",
|
|
59
|
+
"get_checkpoint_manager",
|
|
60
|
+
"save_checkpoint",
|
|
61
|
+
"restore_checkpoint",
|
|
62
|
+
"get_diff",
|
|
63
|
+
# Provenance
|
|
64
|
+
"ProvenanceEntry",
|
|
65
|
+
"ProvenanceManager",
|
|
66
|
+
"get_provenance_manager",
|
|
67
|
+
"track_ai_operation",
|
|
68
|
+
"complete_ai_operation",
|
|
69
|
+
]
|