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.
Files changed (46) hide show
  1. up/__init__.py +1 -1
  2. up/ai_cli.py +229 -0
  3. up/cli.py +54 -9
  4. up/commands/agent.py +521 -0
  5. up/commands/bisect.py +343 -0
  6. up/commands/branch.py +350 -0
  7. up/commands/init.py +195 -6
  8. up/commands/learn.py +1392 -32
  9. up/commands/memory.py +545 -0
  10. up/commands/provenance.py +267 -0
  11. up/commands/review.py +239 -0
  12. up/commands/start.py +752 -42
  13. up/commands/status.py +173 -18
  14. up/commands/sync.py +317 -0
  15. up/commands/vibe.py +304 -0
  16. up/context.py +64 -10
  17. up/core/__init__.py +69 -0
  18. up/core/checkpoint.py +479 -0
  19. up/core/provenance.py +364 -0
  20. up/core/state.py +678 -0
  21. up/events.py +512 -0
  22. up/git/__init__.py +37 -0
  23. up/git/utils.py +270 -0
  24. up/git/worktree.py +331 -0
  25. up/learn/__init__.py +155 -0
  26. up/learn/analyzer.py +227 -0
  27. up/learn/plan.py +374 -0
  28. up/learn/research.py +511 -0
  29. up/learn/utils.py +117 -0
  30. up/memory.py +1096 -0
  31. up/parallel.py +551 -0
  32. up/templates/config/__init__.py +1 -1
  33. up/templates/docs/SKILL.md +28 -0
  34. up/templates/docs/__init__.py +341 -0
  35. up/templates/docs/standards/HEADERS.md +24 -0
  36. up/templates/docs/standards/STRUCTURE.md +18 -0
  37. up/templates/docs/standards/TEMPLATES.md +19 -0
  38. up/templates/loop/__init__.py +92 -32
  39. up/ui/__init__.py +14 -0
  40. up/ui/loop_display.py +650 -0
  41. up/ui/theme.py +137 -0
  42. {up_cli-0.2.0.dist-info → up_cli-0.5.0.dist-info}/METADATA +160 -15
  43. up_cli-0.5.0.dist-info/RECORD +55 -0
  44. up_cli-0.2.0.dist-info/RECORD +0 -23
  45. {up_cli-0.2.0.dist-info → up_cli-0.5.0.dist-info}/WHEEL +0 -0
  46. {up_cli-0.2.0.dist-info → up_cli-0.5.0.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,341 @@
1
+ """Docs system templates."""
2
+
3
+ from pathlib import Path
4
+
5
+ def create_docs_system(target_dir: Path, force: bool = False) -> None:
6
+ """Create the documentation system structure."""
7
+ docs = target_dir / "docs"
8
+
9
+ # Create directory structure
10
+ dirs = [
11
+ "roadmap/vision",
12
+ "roadmap/phases",
13
+ "roadmap/sales",
14
+ "roadmap/implementation",
15
+ "changelog",
16
+ "architecture",
17
+ "features",
18
+ "guides",
19
+ "operations",
20
+ "development",
21
+ "research",
22
+ "todo",
23
+ # New SDLC folders
24
+ "decisions",
25
+ "handoff",
26
+ "learnings",
27
+ "tests",
28
+ "reviews",
29
+ "releases",
30
+ ]
31
+ for d in dirs:
32
+ (docs / d).mkdir(parents=True, exist_ok=True)
33
+
34
+ # Create template files
35
+ _create_main_readme(docs, force)
36
+ _create_context_file(docs, force)
37
+ _create_index_file(docs, force)
38
+ _create_roadmap_readme(docs, force)
39
+ _create_vision_template(docs, force)
40
+ _create_phase_templates(docs, force)
41
+ _create_changelog_readme(docs, force)
42
+ _create_folder_readmes(docs, force)
43
+ _create_sdlc_readmes(docs, force)
44
+
45
+
46
+ def _create_main_readme(docs: Path, force: bool) -> None:
47
+ """Create main docs README."""
48
+ from datetime import date
49
+ content = f"""# Documentation
50
+
51
+ **Updated**: {date.today().isoformat()}
52
+
53
+ ## Structure
54
+
55
+ | Folder | Purpose |
56
+ |--------|---------|
57
+ | roadmap/ | Strategic planning |
58
+ | architecture/ | System design |
59
+ | features/ | Feature specs |
60
+ | changelog/ | Progress tracking |
61
+ | guides/ | User how-to |
62
+ | todo/ | Future work |
63
+ | decisions/ | ADRs |
64
+ | handoff/ | Session continuity |
65
+ | learnings/ | Patterns discovered |
66
+ | tests/ | Test documentation |
67
+ | reviews/ | Code reviews |
68
+ | releases/ | Release notes |
69
+
70
+ ## Key Files
71
+
72
+ - `CONTEXT.md` - AI reads first (current state)
73
+ - `INDEX.md` - Quick reference to find docs
74
+ - `handoff/LATEST.md` - Most recent session handoff
75
+ """
76
+ _write_file(docs / "README.md", content, force)
77
+
78
+
79
+ def _write_file(path: Path, content: str, force: bool) -> None:
80
+ """Write file if it doesn't exist or force is True."""
81
+ if path.exists() and not force:
82
+ return
83
+ path.write_text(content)
84
+
85
+
86
+ def _create_roadmap_readme(docs: Path, force: bool) -> None:
87
+ """Create roadmap README."""
88
+ content = """# Project Roadmap
89
+
90
+ **Created**: {date}
91
+ **Status**: 🔄 Active
92
+
93
+ ---
94
+
95
+ ## Overview
96
+
97
+ This roadmap defines the evolution of the project.
98
+
99
+ ## Current Status
100
+
101
+ | Phase | Status | Progress |
102
+ |-------|--------|----------|
103
+ | Phase 1: Foundation | 📋 Planned | 0% |
104
+ | Phase 2: Intelligence | 📋 Planned | 0% |
105
+ | Phase 3: Scale | 📋 Planned | 0% |
106
+
107
+ ## Folder Structure
108
+
109
+ ```
110
+ docs/roadmap/
111
+ ├── README.md (this file)
112
+ ├── vision/ (Product Vision)
113
+ ├── phases/ (Phase Roadmaps)
114
+ ├── sales/ (Sales Materials)
115
+ └── implementation/ (Implementation Plans)
116
+ ```
117
+
118
+ ## Quick Links
119
+
120
+ - [Product Vision](./vision/PRODUCT_VISION.md)
121
+ - [Phase 1](./phases/PHASE_1_FOUNDATION.md)
122
+ - [Implementation Status](./implementation/STATUS.md)
123
+ """
124
+ from datetime import date
125
+ content = content.replace("{date}", date.today().isoformat())
126
+ _write_file(docs / "roadmap/README.md", content, force)
127
+
128
+
129
+ def _create_vision_template(docs: Path, force: bool) -> None:
130
+ """Create product vision template."""
131
+ content = """# Product Vision
132
+
133
+ **Created**: {date}
134
+ **Status**: 📋 Draft
135
+
136
+ ---
137
+
138
+ ## The Vision
139
+
140
+ > **One-line vision statement here**
141
+
142
+ ## Problem Statement
143
+
144
+ | Pain Point | Impact |
145
+ |------------|--------|
146
+ | Problem 1 | Description |
147
+ | Problem 2 | Description |
148
+
149
+ ## Solution
150
+
151
+ Brief description of the solution.
152
+
153
+ ## Success Metrics
154
+
155
+ | Metric | Target |
156
+ |--------|--------|
157
+ | Metric 1 | Value |
158
+ | Metric 2 | Value |
159
+ """
160
+ from datetime import date
161
+ content = content.replace("{date}", date.today().isoformat())
162
+ _write_file(docs / "roadmap/vision/PRODUCT_VISION.md", content, force)
163
+
164
+
165
+ def _create_phase_templates(docs: Path, force: bool) -> None:
166
+ """Create phase template files."""
167
+ from datetime import date
168
+ today = date.today().isoformat()
169
+
170
+ phase1 = f"""# Phase 1: Foundation
171
+
172
+ **Timeline**: Q1
173
+ **Status**: 📋 Planned
174
+
175
+ ---
176
+
177
+ ## Objectives
178
+
179
+ 1. Objective 1
180
+ 2. Objective 2
181
+
182
+ ## Deliverables
183
+
184
+ | Task | Priority | Status |
185
+ |------|----------|--------|
186
+ | Task 1 | 🔴 Critical | 📋 Planned |
187
+ | Task 2 | 🟠 High | 📋 Planned |
188
+
189
+ ## Success Criteria
190
+
191
+ - [ ] Criterion 1
192
+ - [ ] Criterion 2
193
+ """
194
+ _write_file(docs / "roadmap/phases/PHASE_1_FOUNDATION.md", phase1, force)
195
+
196
+
197
+ def _create_changelog_readme(docs: Path, force: bool) -> None:
198
+ """Create changelog README."""
199
+ content = """# Changelog
200
+
201
+ **Purpose**: Track progress and changes.
202
+
203
+ ## Format
204
+
205
+ Each entry: `YYYY-MM-DD-topic.md`
206
+
207
+ ## Template
208
+
209
+ ```markdown
210
+ # Change Title
211
+
212
+ **Date**: YYYY-MM-DD
213
+ **Status**: ✅ Completed
214
+
215
+ ## Summary
216
+ Brief overview
217
+
218
+ ## Changes
219
+ - Change 1
220
+ - Change 2
221
+ ```
222
+ """
223
+ _write_file(docs / "changelog/README.md", content, force)
224
+
225
+
226
+ def _create_folder_readmes(docs: Path, force: bool) -> None:
227
+ """Create README for each folder."""
228
+ folders = {
229
+ "architecture": "System design docs",
230
+ "features": "Feature specifications",
231
+ "operations": "Deployment guides",
232
+ "development": "Developer guides",
233
+ "guides": "User how-to guides",
234
+ "research": "Research notes",
235
+ "todo": "Future work tracking",
236
+ }
237
+ for folder, purpose in folders.items():
238
+ content = f"# {folder.title()}\n\n**Purpose**: {purpose}\n"
239
+ _write_file(docs / folder / "README.md", content, force)
240
+
241
+
242
+ def _create_context_file(docs: Path, force: bool) -> None:
243
+ """Create CONTEXT.md - AI reads this first."""
244
+ from datetime import date
245
+ content = f"""# Project Context
246
+
247
+ **Updated**: {date.today().isoformat()}
248
+ **Status**: 🔄 Active
249
+
250
+ ---
251
+
252
+ ## Current State
253
+
254
+ | Aspect | Status |
255
+ |--------|--------|
256
+ | Phase | Planning |
257
+ | Focus | Initial setup |
258
+ | Blockers | None |
259
+
260
+ ## Recent Changes
261
+
262
+ - Project initialized
263
+
264
+ ## Next Steps
265
+
266
+ 1. Define project vision
267
+ 2. Set up development environment
268
+ 3. Begin implementation
269
+
270
+ ## Key Files
271
+
272
+ | File | Purpose |
273
+ |------|---------|
274
+ | CLAUDE.md | AI instructions |
275
+ | docs/handoff/LATEST.md | Session continuity |
276
+ """
277
+ _write_file(docs / "CONTEXT.md", content, force)
278
+
279
+
280
+ def _create_sdlc_readmes(docs: Path, force: bool) -> None:
281
+ """Create README files for SDLC folders."""
282
+ sdlc_folders = {
283
+ "decisions": ("Architecture Decision Records", "ADR-NNN-title.md"),
284
+ "handoff": ("Session continuity for AI agents", "LATEST.md"),
285
+ "learnings": ("Patterns and anti-patterns discovered", "YYYY-MM-DD-topic.md"),
286
+ "tests": ("Test documentation and coverage", "component-tests.md"),
287
+ "reviews": ("Code and design reviews", "YYYY-MM-DD-review.md"),
288
+ "releases": ("Release notes and versioning", "vX.Y.Z-YYYY-MM-DD.md"),
289
+ }
290
+ for folder, (purpose, fmt) in sdlc_folders.items():
291
+ content = f"# {folder.title()}\n\n**Purpose**: {purpose}\n\n**Format**: `{fmt}`\n"
292
+ _write_file(docs / folder / "README.md", content, force)
293
+
294
+
295
+ def _create_index_file(docs: Path, force: bool) -> None:
296
+ """Create INDEX.md - Quick reference for AI to find docs."""
297
+ from datetime import date
298
+ content = f"""# Documentation Index
299
+
300
+ **Updated**: {date.today().isoformat()}
301
+
302
+ > AI: Use this index to quickly find relevant documentation.
303
+
304
+ ---
305
+
306
+ ## Quick Reference
307
+
308
+ | Topic | File | Description |
309
+ |-------|------|-------------|
310
+ | Project State | CONTEXT.md | Current status, blockers, next steps |
311
+ | Recent Work | handoff/LATEST.md | Last session summary |
312
+ | Vision | roadmap/vision/PRODUCT_VISION.md | Product goals |
313
+ | Phase 1 | roadmap/phases/PHASE_1_FOUNDATION.md | Current phase |
314
+
315
+ ## By Category
316
+
317
+ ### Architecture
318
+ | Topic | File |
319
+ |-------|------|
320
+ | *Add architecture docs here* | architecture/*.md |
321
+
322
+ ### Features
323
+ | Topic | File |
324
+ |-------|------|
325
+ | *Add feature specs here* | features/*.md |
326
+
327
+ ### Decisions
328
+ | Topic | File |
329
+ |-------|------|
330
+ | *Add ADRs here* | decisions/ADR-*.md |
331
+
332
+ ---
333
+
334
+ ## How to Update
335
+
336
+ When adding new docs, update this index:
337
+ 1. Add entry to relevant category table
338
+ 2. Keep descriptions brief (5-10 words)
339
+ 3. Use relative paths
340
+ """
341
+ _write_file(docs / "INDEX.md", content, force)
@@ -0,0 +1,24 @@
1
+ # Header Standards
2
+
3
+ ## Required Header
4
+
5
+ ```markdown
6
+ # Document Title
7
+
8
+ **Created**: YYYY-MM-DD
9
+ **Updated**: YYYY-MM-DD
10
+ **Status**: [emoji] [description]
11
+ **Priority**: High/Medium/Low
12
+
13
+ ---
14
+ ```
15
+
16
+ ## Status Values
17
+
18
+ | Status | Emoji | Use When |
19
+ |--------|-------|----------|
20
+ | Complete | ✅ | 100% done |
21
+ | In Progress | 🚧 | Active work |
22
+ | Planned | 📋 | Future work |
23
+ | Draft | 📝 | Early stage |
24
+ | Blocked | 🔴 | Blocked |
@@ -0,0 +1,18 @@
1
+ # Folder Structure
2
+
3
+ ```
4
+ docs/
5
+ ├── README.md
6
+ ├── roadmap/
7
+ │ ├── vision/
8
+ │ ├── phases/
9
+ │ └── sales/
10
+ ├── architecture/
11
+ ├── features/
12
+ ├── changelog/
13
+ ├── guides/
14
+ ├── operations/
15
+ ├── development/
16
+ ├── research/
17
+ └── todo/
18
+ ```
@@ -0,0 +1,19 @@
1
+ # Document Templates
2
+
3
+ ## Feature Template
4
+
5
+ ```markdown
6
+ # Feature: [Name]
7
+
8
+ **Created**: YYYY-MM-DD
9
+ **Status**: 📋 Planned
10
+
11
+ ---
12
+
13
+ ## Overview
14
+ Brief description.
15
+
16
+ ## Requirements
17
+ - Requirement 1
18
+ - Requirement 2
19
+ ```
@@ -62,12 +62,22 @@ OBSERVE → CHECKPOINT → EXECUTE → VERIFY → COMMIT
62
62
 
63
63
  ## Commands
64
64
 
65
+ ### Skill Commands (for AI)
65
66
  | Command | Description |
66
67
  |---------|-------------|
67
68
  | `/product-loop` | Start the development loop |
68
69
  | `/product-loop resume` | Resume from last checkpoint |
69
70
  | `/product-loop status` | Show current state |
70
- | `/product-loop rollback` | Rollback last change |
71
+
72
+ ### CLI Commands (for users)
73
+ | Command | Description |
74
+ |---------|-------------|
75
+ | `up start` | Start the product loop |
76
+ | `up start --resume` | Resume from checkpoint |
77
+ | `up start --parallel` | Run tasks in parallel |
78
+ | `up save` | Create checkpoint |
79
+ | `up reset` | Rollback to checkpoint |
80
+ | `up status` | Show current state |
71
81
 
72
82
  ---
73
83
 
@@ -93,16 +103,16 @@ Prevents infinite loops on persistent failures.
93
103
  ### Phase 1: OBSERVE
94
104
 
95
105
  Read task sources in priority order:
96
- 1. `.loop_state.json` - Resume interrupted task
106
+ 1. `.up/state.json` - Resume interrupted task (unified state)
97
107
  2. `prd.json` - Structured user stories
98
108
  3. `TODO.md` - Feature backlog
99
109
 
100
110
  ### Phase 2: CHECKPOINT
101
111
 
102
112
  Before risky operations:
103
- - Create git stash checkpoint
113
+ - Create git checkpoint via `up save`
104
114
  - Record modified files
105
- - Save state to `.loop_state.json`
115
+ - Save state to `.up/state.json`
106
116
 
107
117
  ### Phase 3: EXECUTE
108
118
 
@@ -129,22 +139,26 @@ On success:
129
139
 
130
140
  ---
131
141
 
132
- ## State File: `.loop_state.json`
142
+ ## State File: `.up/state.json`
143
+
144
+ The unified state file stores loop state, context budget, agent state, and metrics:
133
145
 
134
146
  ```json
135
147
  {
136
- "version": "1.0",
137
- "iteration": 5,
138
- "phase": "VERIFY",
139
- "current_task": "US-003",
140
- "tasks_completed": ["US-001", "US-002"],
141
- "circuit_breaker": {
142
- "test": {"failures": 0, "state": "CLOSED"},
143
- "build": {"failures": 0, "state": "CLOSED"}
148
+ "version": "2.0",
149
+ "loop": {
150
+ "iteration": 5,
151
+ "phase": "VERIFY",
152
+ "current_task": "US-003",
153
+ "tasks_completed": ["US-001", "US-002"],
154
+ "tasks_failed": [],
155
+ "last_checkpoint": "cp-20260204-123456"
156
+ },
157
+ "circuit_breakers": {
158
+ "task": {"failures": 0, "state": "CLOSED"}
144
159
  },
145
- "checkpoints": [],
146
160
  "metrics": {
147
- "total_edits": 15,
161
+ "total_tasks": 15,
148
162
  "total_rollbacks": 1,
149
163
  "success_rate": 0.93
150
164
  }
@@ -178,7 +192,7 @@ timeout_per_operation: 120s
178
192
  ## Quick Start
179
193
 
180
194
  1. Ensure `prd.json` or `TODO.md` exists with tasks
181
- 2. Run `/product-loop`
195
+ 2. Run `/product-loop` or `up start`
182
196
  3. Loop will:
183
197
  - Pick highest priority task
184
198
  - Create checkpoint
@@ -197,6 +211,17 @@ This skill respects context budget:
197
211
 
198
212
  ---
199
213
 
214
+ ## Implementation Note
215
+
216
+ The actual implementation is in `src/up/core/`:
217
+ - `state.py` - Unified state management with circuit breaker
218
+ - `checkpoint.py` - Git checkpoint operations
219
+ - `provenance.py` - AI operation tracking
220
+
221
+ The Python files in this skill folder (`circuit_breaker.py`, `state_manager.py`) are **reference implementations** for understanding the patterns. The CLI uses the implementations in `src/up/core/`.
222
+
223
+ ---
224
+
200
225
  ## Status Output Format
201
226
 
202
227
  ```
@@ -204,7 +229,7 @@ This skill respects context budget:
204
229
  PRODUCT LOOP - Iteration #5
205
230
  ═══════════════════════════════════════════
206
231
  Health: ✅ HEALTHY
207
- Circuit: test=CLOSED build=CLOSED
232
+ Circuit: task=CLOSED
208
233
  Task: US-003 Add authentication
209
234
  Status: ✅ COMPLETE
210
235
  ───────────────────────────────────────────
@@ -523,28 +548,63 @@ if __name__ == "__main__":
523
548
 
524
549
 
525
550
  def _create_loop_state(target_dir: Path, force: bool) -> None:
526
- """Create initial loop state file."""
551
+ """Create initial unified state file in .up/ directory."""
527
552
  today = date.today().isoformat()
553
+
554
+ # Create .up directory
555
+ up_dir = target_dir / ".up"
556
+ up_dir.mkdir(parents=True, exist_ok=True)
557
+
558
+ # Unified state file
528
559
  content = f"""{{
529
- "version": "1.0",
530
- "iteration": 0,
531
- "phase": "INIT",
532
- "current_task": null,
533
- "tasks_completed": [],
534
- "tasks_remaining": [],
535
- "circuit_breaker": {{
536
- "test": {{"failures": 0, "state": "CLOSED"}},
537
- "build": {{"failures": 0, "state": "CLOSED"}},
538
- "lint": {{"failures": 0, "state": "CLOSED"}}
560
+ "version": "2.0",
561
+ "loop": {{
562
+ "iteration": 0,
563
+ "phase": "INIT",
564
+ "current_task": null,
565
+ "tasks_completed": [],
566
+ "tasks_failed": [],
567
+ "last_checkpoint": null,
568
+ "doom_loop_threshold": 3
569
+ }},
570
+ "context": {{
571
+ "budget": 100000,
572
+ "used": 0,
573
+ "warning_threshold": 0.8,
574
+ "critical_threshold": 0.9
575
+ }},
576
+ "parallel": {{
577
+ "active": false,
578
+ "max_workers": 3,
579
+ "active_worktrees": []
539
580
  }},
540
581
  "checkpoints": [],
582
+ "circuit_breakers": {{
583
+ "task": {{"failures": 0, "state": "CLOSED", "last_failure": null}}
584
+ }},
541
585
  "metrics": {{
542
- "total_edits": 0,
586
+ "total_tasks": 0,
543
587
  "total_rollbacks": 0,
544
- "success_rate": 1.0
588
+ "success_rate": 1.0,
589
+ "session_start": "{today}"
545
590
  }},
546
591
  "created_at": "{today}",
547
- "last_updated": "{today}"
592
+ "updated_at": "{today}"
548
593
  }}
549
594
  """
550
- _write_file(target_dir / ".loop_state.json", content, force)
595
+ _write_file(up_dir / "state.json", content, force)
596
+
597
+ # Also create config.json with defaults
598
+ config_content = """{
599
+ "doom_loop_threshold": 3,
600
+ "circuit_breaker_cooldown_minutes": 5,
601
+ "circuit_breaker_failure_threshold": 3,
602
+ "checkpoint_retention_count": 50,
603
+ "context_budget": 100000,
604
+ "context_warning_threshold": 0.8,
605
+ "context_critical_threshold": 0.9,
606
+ "ai_timeout_seconds": 600,
607
+ "parallel_max_workers": 3
608
+ }
609
+ """
610
+ _write_file(up_dir / "config.json", config_content, force)
up/ui/__init__.py ADDED
@@ -0,0 +1,14 @@
1
+ """UP-CLI UI Components.
2
+
3
+ Cybersecurity/AI themed terminal UI for the product loop.
4
+ """
5
+
6
+ from up.ui.theme import CyberTheme, THEME
7
+ from up.ui.loop_display import ProductLoopDisplay, TaskStatus
8
+
9
+ __all__ = [
10
+ "CyberTheme",
11
+ "THEME",
12
+ "ProductLoopDisplay",
13
+ "TaskStatus",
14
+ ]