bizy-ai 1.0.1__py3-none-any.whl → 1.1.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.
agent/cli.py CHANGED
@@ -2,6 +2,8 @@
2
2
  """Business Agent CLI Tool"""
3
3
 
4
4
  import click
5
+ import os
6
+ import sys
5
7
  from agent.tasks import TaskManager
6
8
  from agent.planner import BusinessPlanner
7
9
  from agent.research import ResearchAgent
@@ -9,6 +11,7 @@ from rich.console import Console
9
11
  from rich.table import Table
10
12
  from rich.panel import Panel
11
13
  from rich.markdown import Markdown
14
+ from rich.prompt import Prompt, Confirm
12
15
  from datetime import datetime, timedelta
13
16
  from dotenv import load_dotenv
14
17
 
@@ -32,42 +35,172 @@ def task():
32
35
  @click.option('--priority', '-p', type=int, default=3)
33
36
  @click.option('--category', '-c', help='Task category')
34
37
  @click.option('--hours', '-h', type=float, help='Estimated hours')
35
- def add(title, description, priority, category, hours):
38
+ @click.option('--goal', '-g', type=int, help='Goal ID to assign task to')
39
+ def add(title, description, priority, category, hours, goal):
36
40
  """Add a new task"""
37
41
  task_mgr = TaskManager()
42
+ planner = BusinessPlanner()
43
+
44
+ goal_id = goal
45
+
46
+ # If no goal specified, prompt user to select or create one
47
+ if goal_id is None:
48
+ goals = planner.get_active_goals()
49
+
50
+ if goals:
51
+ console.print("\n[bold]📋 Available Goals:[/bold]")
52
+ goals_table = Table(show_header=True, header_style="bold cyan")
53
+ goals_table.add_column("ID", style="dim", width=6)
54
+ goals_table.add_column("Goal")
55
+ goals_table.add_column("Progress", justify="right", width=15)
56
+
57
+ for g in goals[:10]: # Show max 10 goals
58
+ progress_bar = "█" * int(g.progress_percentage / 10) + "░" * (10 - int(g.progress_percentage / 10))
59
+ goals_table.add_row(
60
+ str(g.id),
61
+ g.title[:50],
62
+ f"{progress_bar} {g.progress_percentage:.0f}%"
63
+ )
64
+ console.print(goals_table)
65
+
66
+ # Prompt user
67
+ console.print("\n[bold]Options:[/bold]")
68
+ console.print(" • Enter [cyan]goal ID[/cyan] to assign task to that goal")
69
+ console.print(" • Press [dim]Enter[/dim] to skip (create task without goal)")
70
+ console.print(" • Type [yellow]'new'[/yellow] to create a new goal")
71
+
72
+ choice = Prompt.ask("\n[bold]Your choice[/bold]", default="")
73
+
74
+ if choice.lower() == 'new':
75
+ # Create new goal interactively
76
+ console.print("\n[bold cyan]Creating New Goal[/bold cyan]")
77
+ goal_title = Prompt.ask("Goal title")
78
+ goal_horizon = Prompt.ask(
79
+ "Horizon",
80
+ choices=["daily", "weekly", "monthly", "quarterly", "yearly"],
81
+ default="monthly"
82
+ )
83
+
84
+ try:
85
+ new_goal = planner.create_goal(
86
+ title=goal_title,
87
+ horizon=goal_horizon
88
+ )
89
+ goal_id = new_goal.id
90
+ console.print(f"[green]✓[/green] Created goal: {new_goal.title} (ID: {new_goal.id})\n")
91
+ except Exception as e:
92
+ console.print(f"[red]✗[/red] Error creating goal: {e}")
93
+ console.print("[yellow]Creating task without goal assignment[/yellow]\n")
94
+ goal_id = None
95
+ elif choice and choice.isdigit():
96
+ goal_id = int(choice)
97
+ # Validate goal exists
98
+ goal_obj = planner.get_goal(goal_id)
99
+ if not goal_obj:
100
+ console.print(f"[yellow]⚠[/yellow] Goal #{goal_id} not found. Creating task without goal.\n")
101
+ goal_id = None
102
+ else:
103
+ console.print("\n[yellow]No active goals found.[/yellow]")
104
+ if Confirm.ask("Would you like to create a new goal?", default=False):
105
+ console.print("\n[bold cyan]Creating New Goal[/bold cyan]")
106
+ goal_title = Prompt.ask("Goal title")
107
+ goal_horizon = Prompt.ask(
108
+ "Horizon",
109
+ choices=["daily", "weekly", "monthly", "quarterly", "yearly"],
110
+ default="monthly"
111
+ )
112
+
113
+ try:
114
+ new_goal = planner.create_goal(
115
+ title=goal_title,
116
+ horizon=goal_horizon
117
+ )
118
+ goal_id = new_goal.id
119
+ console.print(f"[green]✓[/green] Created goal: {new_goal.title} (ID: {new_goal.id})\n")
120
+ except Exception as e:
121
+ console.print(f"[red]✗[/red] Error creating goal: {e}\n")
122
+ goal_id = None
123
+
124
+ # Create task with goal assignment
38
125
  task = task_mgr.create_task(
39
126
  title=title,
40
127
  description=description,
41
128
  priority=priority,
42
129
  category=category,
43
- estimated_hours=hours
130
+ estimated_hours=hours,
131
+ parent_goal_id=goal_id
44
132
  )
133
+
45
134
  console.print(f"[green]✓[/green] Task created: {task.title} (ID: {task.id})")
135
+ if goal_id:
136
+ console.print(f"[dim] Assigned to goal #{goal_id}[/dim]")
137
+ # Recalculate goal progress
138
+ planner.calculate_goal_progress(goal_id)
139
+
46
140
  task_mgr.close()
141
+ planner.close()
47
142
 
48
143
  @task.command()
49
- def list():
50
- """List all pending tasks"""
144
+ @click.option('--filter', '-f', type=click.Choice(['all', 'pending', 'completed', 'today']), default='all', help='Filter tasks')
145
+ @click.option('--goal', '-g', type=int, help='Filter by goal ID')
146
+ def list(filter, goal):
147
+ """List tasks with optional filters"""
51
148
  task_mgr = TaskManager()
52
- tasks = task_mgr.get_tasks_for_today()
149
+
150
+ # Get tasks based on filter
151
+ if filter == 'all':
152
+ from agent.models import Task
153
+ if goal:
154
+ tasks = task_mgr.session.query(Task).filter_by(parent_goal_id=goal).all()
155
+ else:
156
+ tasks = task_mgr.session.query(Task).all()
157
+ elif filter == 'completed':
158
+ from agent.models import Task
159
+ query = task_mgr.session.query(Task).filter_by(status='completed')
160
+ if goal:
161
+ query = query.filter_by(parent_goal_id=goal)
162
+ tasks = query.all()
163
+ elif filter == 'pending':
164
+ from agent.models import Task
165
+ query = task_mgr.session.query(Task).filter(Task.status.in_(['pending', 'in_progress']))
166
+ if goal:
167
+ query = query.filter_by(parent_goal_id=goal)
168
+ tasks = query.all()
169
+ else: # today
170
+ tasks = task_mgr.get_tasks_for_today()
53
171
 
54
172
  if not tasks:
55
- console.print("[yellow]No pending tasks[/yellow]")
173
+ console.print(f"[yellow]No {filter} tasks found[/yellow]")
174
+ task_mgr.close()
56
175
  return
57
176
 
58
- table = Table(title="📋 Your Tasks", show_header=True, header_style="bold cyan")
177
+ # Build title
178
+ title_parts = ["📋 Your Tasks"]
179
+ if filter != 'all':
180
+ title_parts.append(f"({filter.title()})")
181
+ if goal:
182
+ title_parts.append(f"for Goal #{goal}")
183
+
184
+ table = Table(title=" ".join(title_parts), show_header=True, header_style="bold cyan")
59
185
  table.add_column("ID", style="dim")
186
+ table.add_column("Status", justify="center")
60
187
  table.add_column("Priority", justify="center")
61
188
  table.add_column("Title")
62
189
  table.add_column("Category", style="cyan")
190
+ table.add_column("Due Date", style="dim")
63
191
 
64
192
  for task in tasks:
65
- priority_str = "🔴" if task.priority == 1 else "🟡" if task.priority == 3 else "🟢"
193
+ status_icon = "" if task.status == 'completed' else ""
194
+ priority_str = "🔴" if task.priority == 1 else "🟡" if task.priority == 2 else "🟢"
195
+ due_date = task.due_date.strftime('%Y-%m-%d') if task.due_date else "-"
196
+
66
197
  table.add_row(
67
198
  str(task.id),
199
+ status_icon,
68
200
  priority_str,
69
201
  task.title[:50],
70
- task.category or "-"
202
+ task.category or "-",
203
+ due_date
71
204
  )
72
205
 
73
206
  console.print(table)
@@ -81,6 +214,14 @@ def complete(task_id):
81
214
  task = task_mgr.complete_task(task_id)
82
215
  if task:
83
216
  console.print(f"[green]✓[/green] Completed: {task.title}")
217
+
218
+ # Update goal progress if task is associated with a goal
219
+ if task.parent_goal_id:
220
+ from agent.planner import BusinessPlanner
221
+ planner = BusinessPlanner()
222
+ progress = planner.calculate_goal_progress(task.parent_goal_id)
223
+ console.print(f"[dim]Goal progress updated: {progress:.1f}%[/dim]")
224
+ planner.close()
84
225
  else:
85
226
  console.print(f"[red]✗[/red] Task {task_id} not found")
86
227
  task_mgr.close()
@@ -120,8 +261,16 @@ def list():
120
261
 
121
262
  if not goals:
122
263
  console.print("[yellow]No active goals[/yellow]")
264
+ planner.close()
123
265
  return
124
266
 
267
+ # Recalculate progress for all goals
268
+ for goal in goals:
269
+ planner.calculate_goal_progress(goal.id)
270
+
271
+ # Refresh goals after recalculation
272
+ goals = planner.get_active_goals()
273
+
125
274
  table = Table(title="🎯 Your Goals", show_header=True, header_style="bold cyan")
126
275
  table.add_column("ID", style="dim")
127
276
  table.add_column("Title")
@@ -212,16 +361,28 @@ def competitors(domain, offering):
212
361
  def stats():
213
362
  """Show statistics"""
214
363
  task_mgr = TaskManager()
215
- weekly_stats = task_mgr.get_weekly_stats()
364
+ weekly_stats = task_mgr.get_weekly_task_stats()
216
365
  velocity = task_mgr.get_task_velocity()
217
366
  today_tasks = task_mgr.get_tasks_for_today()
218
367
 
219
368
  console.print("\n[bold cyan]📊 Your Statistics[/bold cyan]\n")
220
369
  console.print("[bold]This Week:[/bold]")
221
- console.print(f" • Tasks Completed: {weekly_stats['total_tasks_completed']}")
222
- console.print(f" • Completion Rate: {weekly_stats['average_completion_rate']:.0%}")
370
+ console.print(f" • Tasks Completed: {weekly_stats['tasks_completed_this_week']}")
371
+ console.print(f" • Tasks Created: {weekly_stats['tasks_created_this_week']}")
372
+ console.print(f" • Completion Rate: {weekly_stats['completion_rate']:.1f}%")
373
+ console.print(f" • Total Hours (Estimated): {weekly_stats['total_estimated_hours']:.1f}h")
374
+ if weekly_stats['total_actual_hours'] > 0:
375
+ console.print(f" • Total Hours (Actual): {weekly_stats['total_actual_hours']:.1f}h")
223
376
  console.print(f"\n[bold]Velocity:[/bold] {velocity:.1f} tasks/day")
224
377
  console.print(f"\n[bold]Today:[/bold] {len(today_tasks)} tasks scheduled\n")
378
+
379
+ # Show breakdown by category if available
380
+ if weekly_stats['categories']:
381
+ console.print("[bold]By Category:[/bold]")
382
+ for category, count in sorted(weekly_stats['categories'].items(), key=lambda x: x[1], reverse=True):
383
+ console.print(f" • {category}: {count} task(s)")
384
+ console.print()
385
+
225
386
  task_mgr.close()
226
387
 
227
388
  # DAILY/WEEKLY REVIEWS
@@ -243,5 +404,40 @@ def weekly():
243
404
  from agent.weekly_review import run_weekly_review
244
405
  run_weekly_review()
245
406
 
407
+ # BUSINESS PLAN MANAGEMENT
408
+ @cli.group()
409
+ def plan():
410
+ """Manage business plan"""
411
+ pass
412
+
413
+ @plan.command()
414
+ def show():
415
+ """Review current business plan and goals"""
416
+ from agent.plan_manager import review_business_plan
417
+ review_business_plan()
418
+
419
+ @plan.command()
420
+ def create():
421
+ """Create new business plan"""
422
+ from agent.plan_manager import create_business_plan
423
+ create_business_plan()
424
+
425
+ @plan.command()
426
+ def update():
427
+ """Update existing business plan"""
428
+ from agent.plan_manager import update_business_plan
429
+ update_business_plan()
430
+
431
+ @plan.command()
432
+ @click.argument('file_path', required=False)
433
+ @click.option('--name', '-n', help='Business plan name')
434
+ def load(file_path, name):
435
+ """Load business plan from YAML file"""
436
+ # Import and run the standalone script
437
+ repo_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
438
+ sys.path.insert(0, repo_root)
439
+ from scripts.load_business_plan import load_business_plan
440
+ load_business_plan(file_path, name)
441
+
246
442
  if __name__ == "__main__":
247
443
  cli()
agent/models.py CHANGED
@@ -158,8 +158,9 @@ class BusinessMetric(Base):
158
158
 
159
159
  class BusinessPlan(Base):
160
160
  __tablename__ = 'business_plans'
161
-
161
+
162
162
  id = Column(Integer, primary_key=True)
163
+ name = Column(String(255))
163
164
  version = Column(String(50))
164
165
  vision = Column(Text)
165
166
  mission = Column(Text)
@@ -171,6 +172,7 @@ class BusinessPlan(Base):
171
172
  key_partnerships = Column(JSON)
172
173
  cost_structure = Column(JSON)
173
174
  created_at = Column(DateTime, default=datetime.utcnow)
175
+ updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
174
176
  is_active = Column(Boolean, default=True)
175
177
 
176
178
  def to_dict(self):
@@ -193,15 +195,28 @@ class BusinessPlan(Base):
193
195
  # Database setup
194
196
  def get_engine(db_path=None):
195
197
  if db_path is None:
196
- # Use environment variable or default to home directory
197
- db_path = os.getenv('BUSINESS_AGENT_DB', os.path.expanduser('~/.business-agent/tasks.db'))
198
+ # Determine database path based on environment
199
+ env = os.getenv('BIZY_ENV', 'production')
200
+
201
+ if env == 'test':
202
+ # Test environment uses in-memory database (overridden by conftest.py)
203
+ return create_engine('sqlite:///:memory:', echo=False)
204
+ elif env == 'development':
205
+ # Development environment uses separate database
206
+ db_path = os.getenv('BUSINESS_AGENT_DB', os.path.expanduser('~/.business-agent/dev_tasks.db'))
207
+ else: # production
208
+ # Production environment uses main database
209
+ db_path = os.getenv('BUSINESS_AGENT_DB', os.path.expanduser('~/.business-agent/tasks.db'))
198
210
 
199
- # Create directory if it doesn't exist
200
- db_dir = os.path.dirname(db_path)
201
- if db_dir:
202
- os.makedirs(db_dir, exist_ok=True)
211
+ # Create directory if it doesn't exist (not needed for in-memory)
212
+ if db_path and db_path != ':memory:':
213
+ db_dir = os.path.dirname(db_path)
214
+ if db_dir:
215
+ os.makedirs(db_dir, exist_ok=True)
216
+ return create_engine(f'sqlite:///{db_path}', echo=False)
203
217
 
204
- return create_engine(f'sqlite:///{db_path}', echo=False)
218
+ # In-memory database
219
+ return create_engine('sqlite:///:memory:', echo=False)
205
220
 
206
221
  def get_session(engine=None):
207
222
  if engine is None:
agent/plan_manager.py ADDED
@@ -0,0 +1,320 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Business Plan Management Script
4
+ Review and update business plans, goals, and tasks
5
+ """
6
+
7
+ import sys
8
+ import os
9
+ import yaml
10
+ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
11
+
12
+ from agent.core import BusinessAgent
13
+ from agent.planner import BusinessPlanner
14
+ from agent.tasks import TaskManager
15
+ from agent.models import get_session, BusinessPlan
16
+ from rich.console import Console
17
+ from rich.panel import Panel
18
+ from rich.table import Table
19
+ from rich.prompt import Prompt, Confirm
20
+ from rich.markdown import Markdown
21
+ from datetime import datetime, timedelta
22
+ from dotenv import load_dotenv
23
+
24
+ load_dotenv()
25
+ console = Console()
26
+
27
+ def review_business_plan():
28
+ """Display comprehensive business plan review"""
29
+ try:
30
+ console.print()
31
+ console.print(f"[bold blue]{'='*70}[/bold blue]")
32
+ console.print(f"[bold blue] 📋 BUSINESS PLAN REVIEW - {datetime.now().strftime('%B %d, %Y')}[/bold blue]")
33
+ console.print(f"[bold blue]{'='*70}[/bold blue]")
34
+ console.print()
35
+
36
+ planner = BusinessPlanner()
37
+ task_mgr = TaskManager()
38
+ agent = BusinessAgent()
39
+
40
+ # Get active business plan
41
+ plan = planner.get_active_business_plan()
42
+
43
+ if not plan:
44
+ console.print("[yellow]⚠️ No active business plan found.[/yellow]")
45
+ console.print("\nWould you like to create one? Use: [cyan]bizy plan create[/cyan]")
46
+ return
47
+
48
+ # Display business plan
49
+ console.print("[bold]📊 Current Business Plan[/bold]")
50
+ console.print(f"[dim]Version: {plan.version} | Created: {plan.created_at.strftime('%Y-%m-%d')}[/dim]\n")
51
+
52
+ plan_info = f"""
53
+ **Vision:** {plan.vision}
54
+
55
+ **Mission:** {plan.mission}
56
+
57
+ **Value Proposition:** {plan.value_proposition}
58
+
59
+ **Target Market:** {plan.target_market}
60
+
61
+ **Revenue Model:** {plan.revenue_model}
62
+ """
63
+ console.print(Panel(Markdown(plan_info), title="Business Plan", border_style="blue"))
64
+
65
+ # Get goals
66
+ console.print("\n[bold]🎯 Goals Overview[/bold]\n")
67
+ all_goals = planner.get_active_goals()
68
+
69
+ # Recalculate progress for all goals
70
+ for goal in all_goals:
71
+ planner.calculate_goal_progress(goal.id)
72
+
73
+ # Refresh goals after recalculation
74
+ all_goals = planner.get_active_goals()
75
+
76
+ if all_goals:
77
+ goals_table = Table(show_header=True, header_style="bold cyan")
78
+ goals_table.add_column("Horizon")
79
+ goals_table.add_column("Goal")
80
+ goals_table.add_column("Progress", justify="right")
81
+ goals_table.add_column("Target Date")
82
+
83
+ for goal in all_goals[:10]:
84
+ progress_bar = "█" * int(goal.progress_percentage / 10) + "░" * (10 - int(goal.progress_percentage / 10))
85
+ target = goal.target_date.strftime('%Y-%m-%d') if goal.target_date else "Not set"
86
+ goals_table.add_row(
87
+ goal.horizon.upper(),
88
+ goal.title[:40],
89
+ f"{progress_bar} {goal.progress_percentage:.0f}%",
90
+ target
91
+ )
92
+
93
+ console.print(goals_table)
94
+ else:
95
+ console.print("[yellow]No active goals found.[/yellow]")
96
+
97
+ # Get task summary
98
+ console.print("\n[bold]📋 Task Summary[/bold]\n")
99
+ weekly_stats = task_mgr.get_weekly_task_stats()
100
+ today_tasks = task_mgr.get_tasks_for_today()
101
+ overdue = task_mgr.get_overdue_tasks()
102
+
103
+ console.print(f" • This Week: {weekly_stats['tasks_completed_this_week']} completed ({weekly_stats['completion_rate']:.1f}% completion rate)")
104
+ console.print(f" • Today: {len(today_tasks)} tasks scheduled")
105
+ console.print(f" • Overdue: {len(overdue)} tasks")
106
+
107
+ # AI Analysis
108
+ console.print("\n[dim]Generating AI analysis...[/dim]")
109
+
110
+ goals_summary = "\n".join([
111
+ f"- [{g.horizon.upper()}] {g.title}: {g.progress_percentage:.0f}% complete"
112
+ for g in all_goals[:5]
113
+ ]) if all_goals else "No active goals"
114
+
115
+ analysis_prompt = f"""Analyze this business plan and provide strategic insights:
116
+
117
+ BUSINESS PLAN:
118
+ - Vision: {plan.vision}
119
+ - Mission: {plan.mission}
120
+ - Value Proposition: {plan.value_proposition}
121
+
122
+ GOALS PROGRESS:
123
+ {goals_summary}
124
+
125
+ EXECUTION METRICS:
126
+ - Tasks Completed This Week: {weekly_stats['tasks_completed_this_week']}
127
+ - Tasks Created This Week: {weekly_stats['tasks_created_this_week']}
128
+ - Completion Rate: {weekly_stats['completion_rate']:.1f}%
129
+ - Tasks Overdue: {len(overdue)}
130
+
131
+ Provide:
132
+ 1. **Plan-Goal Alignment** - Are the goals aligned with the business plan?
133
+ 2. **Execution Health** - Is the execution on track?
134
+ 3. **Recommended Adjustments** - What should be updated or changed?
135
+ 4. **Next Strategic Moves** - What are the top 3 priorities?
136
+
137
+ Be concise and actionable."""
138
+
139
+ analysis = agent.client.messages.create(
140
+ model=agent.model,
141
+ max_tokens=2000,
142
+ messages=[{"role": "user", "content": analysis_prompt}]
143
+ ).content[0].text
144
+
145
+ console.print(Panel(
146
+ Markdown(analysis),
147
+ title="🤖 AI Strategic Analysis",
148
+ border_style="blue",
149
+ padding=(1, 2)
150
+ ))
151
+
152
+ console.print()
153
+ planner.close()
154
+ task_mgr.close()
155
+
156
+ except Exception as e:
157
+ console.print(f"[bold red]❌ Error reviewing plan:[/bold red] {e}")
158
+ import traceback
159
+ console.print(traceback.format_exc())
160
+
161
+ def create_business_plan():
162
+ """Interactive business plan creation"""
163
+ try:
164
+ console.print()
165
+ console.print(f"[bold green]{'='*70}[/bold green]")
166
+ console.print(f"[bold green] 📝 CREATE BUSINESS PLAN[/bold green]")
167
+ console.print(f"[bold green]{'='*70}[/bold green]")
168
+ console.print()
169
+
170
+ console.print("[cyan]Let's create your business plan. This will guide all your goals and tasks.[/cyan]\n")
171
+
172
+ vision = Prompt.ask("🔭 [bold]What is your vision?[/bold] (Where are you going?)")
173
+ mission = Prompt.ask("🎯 [bold]What is your mission?[/bold] (How will you get there?)")
174
+ value_prop = Prompt.ask("💎 [bold]What is your value proposition?[/bold] (Why you over competitors?)")
175
+ target_market = Prompt.ask("👥 [bold]Who is your target market?[/bold]")
176
+ revenue_model = Prompt.ask("💰 [bold]What is your revenue model?[/bold] (How will you make money?)")
177
+
178
+ version = Prompt.ask("📌 [bold]Version number?[/bold]", default="1.0")
179
+
180
+ console.print("\n[dim]Creating business plan...[/dim]")
181
+
182
+ planner = BusinessPlanner()
183
+ plan = planner.create_business_plan(
184
+ vision=vision,
185
+ mission=mission,
186
+ value_proposition=value_prop,
187
+ target_market=target_market,
188
+ revenue_model=revenue_model,
189
+ version=version
190
+ )
191
+
192
+ console.print(Panel(
193
+ f"[green]✅ Business Plan v{plan.version} Created Successfully![/green]\n\n"
194
+ f"This plan will now guide your goal setting and task management.",
195
+ title="Success",
196
+ border_style="green"
197
+ ))
198
+
199
+ # Ask if they want to create goals
200
+ if Confirm.ask("\n💡 Would you like to create your first goal now?"):
201
+ console.print("\n[cyan]Tip: Start with a yearly goal, then break it down into smaller goals.[/cyan]\n")
202
+
203
+ goal_title = Prompt.ask("🎯 [bold]Goal title[/bold]")
204
+ goal_desc = Prompt.ask("📝 [bold]Goal description[/bold]")
205
+ horizon = Prompt.ask(
206
+ "⏰ [bold]Time horizon[/bold]",
207
+ choices=["weekly", "monthly", "quarterly", "yearly"],
208
+ default="yearly"
209
+ )
210
+
211
+ # Calculate target date
212
+ days_map = {"weekly": 7, "monthly": 30, "quarterly": 90, "yearly": 365}
213
+ target_date = datetime.now() + timedelta(days=days_map[horizon])
214
+
215
+ goal = planner.create_goal(
216
+ title=goal_title,
217
+ description=goal_desc,
218
+ horizon=horizon,
219
+ target_date=target_date
220
+ )
221
+
222
+ console.print(f"\n[green]✅ Goal created (ID: {goal.id})[/green]")
223
+
224
+ if Confirm.ask("\n🤖 Would you like AI to break this goal into tasks?"):
225
+ console.print("\n[dim]AI is breaking down your goal into actionable tasks...[/dim]")
226
+ tasks = planner.break_down_goal(goal.id)
227
+
228
+ if tasks:
229
+ console.print(f"\n[green]✅ Created {len(tasks)} tasks:[/green]")
230
+ for i, task in enumerate(tasks[:5], 1):
231
+ console.print(f" {i}. {task.title}")
232
+ if len(tasks) > 5:
233
+ console.print(f" ... and {len(tasks) - 5} more")
234
+
235
+ planner.close()
236
+ console.print()
237
+
238
+ except Exception as e:
239
+ console.print(f"[bold red]❌ Error creating plan:[/bold red] {e}")
240
+ import traceback
241
+ console.print(traceback.format_exc())
242
+
243
+ def update_business_plan():
244
+ """Update existing business plan"""
245
+ try:
246
+ console.print()
247
+ console.print(f"[bold yellow]{'='*70}[/bold yellow]")
248
+ console.print(f"[bold yellow] ✏️ UPDATE BUSINESS PLAN[/bold yellow]")
249
+ console.print(f"[bold yellow]{'='*70}[/bold yellow]")
250
+ console.print()
251
+
252
+ planner = BusinessPlanner()
253
+ plan = planner.get_active_business_plan()
254
+
255
+ if not plan:
256
+ console.print("[yellow]⚠️ No active business plan found.[/yellow]")
257
+ console.print("\nCreate one with: [cyan]bizy plan create[/cyan]")
258
+ return
259
+
260
+ console.print(f"[bold]Current Plan (v{plan.version})[/bold]\n")
261
+ console.print(f"Vision: {plan.vision}")
262
+ console.print(f"Mission: {plan.mission}")
263
+ console.print(f"Value Proposition: {plan.value_proposition}")
264
+ console.print(f"Target Market: {plan.target_market}")
265
+ console.print(f"Revenue Model: {plan.revenue_model}")
266
+ console.print()
267
+
268
+ console.print("[cyan]What would you like to update? (Press Enter to skip)[/cyan]\n")
269
+
270
+ vision = Prompt.ask("🔭 [bold]Vision[/bold]", default=plan.vision)
271
+ mission = Prompt.ask("🎯 [bold]Mission[/bold]", default=plan.mission)
272
+ value_prop = Prompt.ask("💎 [bold]Value Proposition[/bold]", default=plan.value_proposition)
273
+ target_market = Prompt.ask("👥 [bold]Target Market[/bold]", default=plan.target_market)
274
+ revenue_model = Prompt.ask("💰 [bold]Revenue Model[/bold]", default=plan.revenue_model)
275
+
276
+ # Create new version
277
+ version_parts = plan.version.split('.')
278
+ new_minor = int(version_parts[1]) + 1 if len(version_parts) > 1 else 1
279
+ new_version = f"{version_parts[0]}.{new_minor}"
280
+
281
+ new_version = Prompt.ask("📌 [bold]New version number[/bold]", default=new_version)
282
+
283
+ if Confirm.ask("\n💾 Save this as a new version of your business plan?"):
284
+ new_plan = planner.create_business_plan(
285
+ vision=vision,
286
+ mission=mission,
287
+ value_proposition=value_prop,
288
+ target_market=target_market,
289
+ revenue_model=revenue_model,
290
+ version=new_version
291
+ )
292
+
293
+ console.print(Panel(
294
+ f"[green]✅ Business Plan Updated to v{new_plan.version}[/green]\n\n"
295
+ f"The previous version (v{plan.version}) has been archived.",
296
+ title="Success",
297
+ border_style="green"
298
+ ))
299
+
300
+ planner.close()
301
+ console.print()
302
+
303
+ except Exception as e:
304
+ console.print(f"[bold red]❌ Error updating plan:[/bold red] {e}")
305
+ import traceback
306
+ console.print(traceback.format_exc())
307
+
308
+ if __name__ == "__main__":
309
+ if len(sys.argv) > 1:
310
+ command = sys.argv[1]
311
+ if command == "review":
312
+ review_business_plan()
313
+ elif command == "create":
314
+ create_business_plan()
315
+ elif command == "update":
316
+ update_business_plan()
317
+ else:
318
+ console.print(f"[red]Unknown command: {command}[/red]")
319
+ else:
320
+ review_business_plan()