Update antfarm, dashboard, memory +1 more (+20 ~12 -6)
This commit is contained in:
@@ -1759,20 +1759,33 @@ class TaskBoardHandler(SimpleHTTPRequestHandler):
|
||||
all_checks = all(c.get('type') == 'check' for c in recent_completions)
|
||||
if all_checks:
|
||||
habit['lives'] = min(habit['lives'] + 1, 3)
|
||||
|
||||
|
||||
# Update timestamp
|
||||
habit['updatedAt'] = datetime.now().isoformat()
|
||||
habits_data['lastUpdated'] = habit['updatedAt']
|
||||
|
||||
|
||||
# Save to file
|
||||
with open(HABITS_FILE, 'w', encoding='utf-8') as f:
|
||||
json.dump(habits_data, f, indent=2)
|
||||
|
||||
# Return updated habit
|
||||
self.send_json(habit, 200)
|
||||
|
||||
# Enrich habit with calculated stats before returning
|
||||
current_streak = habits_helpers.calculate_streak(habit)
|
||||
best_streak = habit.get('streak', {}).get('best', 0)
|
||||
completion_rate = habits_helpers.get_completion_rate(habit, days=30)
|
||||
weekly_summary = habits_helpers.get_weekly_summary(habit)
|
||||
|
||||
enriched_habit = habit.copy()
|
||||
enriched_habit['current_streak'] = current_streak
|
||||
enriched_habit['best_streak'] = best_streak
|
||||
enriched_habit['completion_rate_30d'] = completion_rate
|
||||
enriched_habit['weekly_summary'] = weekly_summary
|
||||
enriched_habit['should_check_today'] = habits_helpers.should_check_today(habit)
|
||||
|
||||
# Return enriched habit
|
||||
self.send_json(enriched_habit, 200)
|
||||
except Exception as e:
|
||||
self.send_json({'error': str(e)}, 500)
|
||||
|
||||
|
||||
def handle_habits_uncheck(self):
|
||||
"""Uncheck a habit (remove completion for a specific date)."""
|
||||
try:
|
||||
@@ -1841,20 +1854,32 @@ class TaskBoardHandler(SimpleHTTPRequestHandler):
|
||||
# Update best streak if needed (best never decreases, but we keep it for consistency)
|
||||
if current_streak > habit['streak']['best']:
|
||||
habit['streak']['best'] = current_streak
|
||||
|
||||
|
||||
# Update timestamp
|
||||
habit['updatedAt'] = datetime.now().isoformat()
|
||||
habits_data['lastUpdated'] = habit['updatedAt']
|
||||
|
||||
|
||||
# Save to file
|
||||
with open(HABITS_FILE, 'w', encoding='utf-8') as f:
|
||||
json.dump(habits_data, f, indent=2)
|
||||
|
||||
# Return updated habit
|
||||
self.send_json(habit, 200)
|
||||
|
||||
# Enrich habit with calculated stats before returning
|
||||
best_streak = habit.get('streak', {}).get('best', 0)
|
||||
completion_rate = habits_helpers.get_completion_rate(habit, days=30)
|
||||
weekly_summary = habits_helpers.get_weekly_summary(habit)
|
||||
|
||||
enriched_habit = habit.copy()
|
||||
enriched_habit['current_streak'] = current_streak
|
||||
enriched_habit['best_streak'] = best_streak
|
||||
enriched_habit['completion_rate_30d'] = completion_rate
|
||||
enriched_habit['weekly_summary'] = weekly_summary
|
||||
enriched_habit['should_check_today'] = habits_helpers.should_check_today(habit)
|
||||
|
||||
# Return enriched habit
|
||||
self.send_json(enriched_habit, 200)
|
||||
except Exception as e:
|
||||
self.send_json({'error': str(e)}, 500)
|
||||
|
||||
|
||||
def handle_habits_skip(self):
|
||||
"""Skip a day using a life to preserve streak."""
|
||||
try:
|
||||
@@ -1901,17 +1926,30 @@ class TaskBoardHandler(SimpleHTTPRequestHandler):
|
||||
'type': 'skip'
|
||||
}
|
||||
habit['completions'].append(completion_entry)
|
||||
|
||||
|
||||
# Update timestamp
|
||||
habit['updatedAt'] = datetime.now().isoformat()
|
||||
habits_data['lastUpdated'] = habit['updatedAt']
|
||||
|
||||
|
||||
# Save to file
|
||||
with open(HABITS_FILE, 'w', encoding='utf-8') as f:
|
||||
json.dump(habits_data, f, indent=2)
|
||||
|
||||
# Return updated habit
|
||||
self.send_json(habit, 200)
|
||||
|
||||
# Enrich habit with calculated stats before returning
|
||||
current_streak = habits_helpers.calculate_streak(habit)
|
||||
best_streak = habit.get('streak', {}).get('best', 0)
|
||||
completion_rate = habits_helpers.get_completion_rate(habit, days=30)
|
||||
weekly_summary = habits_helpers.get_weekly_summary(habit)
|
||||
|
||||
enriched_habit = habit.copy()
|
||||
enriched_habit['current_streak'] = current_streak
|
||||
enriched_habit['best_streak'] = best_streak
|
||||
enriched_habit['completion_rate_30d'] = completion_rate
|
||||
enriched_habit['weekly_summary'] = weekly_summary
|
||||
enriched_habit['should_check_today'] = habits_helpers.should_check_today(habit)
|
||||
|
||||
# Return enriched habit
|
||||
self.send_json(enriched_habit, 200)
|
||||
except Exception as e:
|
||||
self.send_json({'error': str(e)}, 500)
|
||||
|
||||
|
||||
57
dashboard/archive/tasks-2026-02.json
Normal file
57
dashboard/archive/tasks-2026-02.json
Normal file
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"month": "2026-02",
|
||||
"tasks": [
|
||||
{
|
||||
"id": "task-034",
|
||||
"title": "Actualizare documentație canale agenți",
|
||||
"description": "",
|
||||
"created": "2026-02-01T12:15:41Z",
|
||||
"priority": "medium",
|
||||
"completed": "2026-02-01T12:15:44Z"
|
||||
},
|
||||
{
|
||||
"id": "task-035",
|
||||
"title": "Restructurare echipă: șterg work, unific health+growth→self",
|
||||
"description": "",
|
||||
"created": "2026-02-01T12:20:59Z",
|
||||
"priority": "medium",
|
||||
"completed": "2026-02-01T12:23:32Z"
|
||||
},
|
||||
{
|
||||
"id": "task-036",
|
||||
"title": "Unificare în 1 agent cu tehnici diminuare dezavantaje",
|
||||
"description": "",
|
||||
"created": "2026-02-01T13:27:51Z",
|
||||
"priority": "medium",
|
||||
"completed": "2026-02-01T13:30:01Z"
|
||||
},
|
||||
{
|
||||
"id": "task-037",
|
||||
"title": "Coaching dimineață - Asumarea eforturilor (Zoltan Vereș)",
|
||||
"description": "",
|
||||
"created": "2026-02-02T07:01:14Z",
|
||||
"priority": "medium"
|
||||
},
|
||||
{
|
||||
"id": "task-038",
|
||||
"title": "Raport dimineata trimis pe email",
|
||||
"description": "",
|
||||
"created": "2026-02-03T06:31:08Z",
|
||||
"priority": "medium"
|
||||
},
|
||||
{
|
||||
"id": "task-039",
|
||||
"title": "Raport seară 3 feb trimis pe email",
|
||||
"description": "",
|
||||
"created": "2026-02-03T18:01:12Z",
|
||||
"priority": "medium"
|
||||
},
|
||||
{
|
||||
"id": "task-040",
|
||||
"title": "Job night-execute: 2 video-uri YouTube procesate",
|
||||
"description": "",
|
||||
"created": "2026-02-03T21:02:31Z",
|
||||
"priority": "medium"
|
||||
}
|
||||
]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,60 @@
|
||||
{
|
||||
"lastUpdated": "",
|
||||
"habits": []
|
||||
}
|
||||
"lastUpdated": "2026-02-11T07:35:47.146507",
|
||||
"habits": [
|
||||
{
|
||||
"id": "95c15eef-3a14-4985-a61e-0b64b72851b0",
|
||||
"name": "Bazin",
|
||||
"category": "health",
|
||||
"color": "#EF4444",
|
||||
"icon": "target",
|
||||
"priority": 50,
|
||||
"notes": "",
|
||||
"reminderTime": "19:00",
|
||||
"frequency": {
|
||||
"type": "x_per_week",
|
||||
"count": 5
|
||||
},
|
||||
"streak": {
|
||||
"current": 1,
|
||||
"best": 1,
|
||||
"lastCheckIn": "2026-02-11"
|
||||
},
|
||||
"lives": 0,
|
||||
"completions": [
|
||||
{
|
||||
"date": "2026-02-11",
|
||||
"type": "check"
|
||||
}
|
||||
],
|
||||
"createdAt": "2026-02-11T00:54:03.447063",
|
||||
"updatedAt": "2026-02-11T07:30:17.715769"
|
||||
},
|
||||
{
|
||||
"id": "ceddaa7e-caf9-4038-94bb-da486c586bf8",
|
||||
"name": "Test Daily",
|
||||
"category": "health",
|
||||
"color": "#10B981",
|
||||
"icon": "check-circle",
|
||||
"priority": 10,
|
||||
"notes": "",
|
||||
"reminderTime": "",
|
||||
"frequency": {
|
||||
"type": "daily"
|
||||
},
|
||||
"streak": {
|
||||
"current": 1,
|
||||
"best": 1,
|
||||
"lastCheckIn": "2026-02-11"
|
||||
},
|
||||
"lives": 2,
|
||||
"completions": [
|
||||
{
|
||||
"date": "2026-02-11",
|
||||
"type": "check"
|
||||
}
|
||||
],
|
||||
"createdAt": "2026-02-11T01:58:44.779904",
|
||||
"updatedAt": "2026-02-11T07:35:47.146507"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -117,92 +117,34 @@ def _calculate_specific_days_streak(habit: Dict[str, Any], completions: List[Dic
|
||||
|
||||
|
||||
def _calculate_x_per_week_streak(habit: Dict[str, Any], completions: List[Dict[str, Any]]) -> int:
|
||||
"""Calculate streak for x_per_week habits (consecutive weeks meeting target)."""
|
||||
target_count = habit.get("frequency", {}).get("count", 1)
|
||||
|
||||
streak = 0
|
||||
today = datetime.now().date()
|
||||
|
||||
# Group completions by week
|
||||
week_counts = {}
|
||||
for completion in completions:
|
||||
completion_date = datetime.fromisoformat(completion["date"]).date()
|
||||
# Get ISO week (year, week_number)
|
||||
week_key = completion_date.isocalendar()[:2]
|
||||
week_counts[week_key] = week_counts.get(week_key, 0) + 1
|
||||
|
||||
# Start from current week and count backwards
|
||||
current_week = today.isocalendar()[:2]
|
||||
|
||||
while current_week in week_counts:
|
||||
if week_counts[current_week] >= target_count:
|
||||
streak += 1
|
||||
# Move to previous week
|
||||
year, week = current_week
|
||||
if week == 1:
|
||||
year -= 1
|
||||
week = 52
|
||||
else:
|
||||
week -= 1
|
||||
current_week = (year, week)
|
||||
else:
|
||||
break
|
||||
|
||||
return streak
|
||||
"""Calculate streak for x_per_week habits (consecutive days with check-ins).
|
||||
|
||||
For x_per_week habits, streak counts consecutive DAYS with check-ins,
|
||||
not consecutive weeks meeting the target. The weekly target (e.g., 4/week)
|
||||
is a goal, but streak measures the chain of check-in days.
|
||||
"""
|
||||
# Use the same logic as daily habits - count consecutive check-in days
|
||||
return _calculate_daily_streak(completions)
|
||||
|
||||
|
||||
def _calculate_weekly_streak(completions: List[Dict[str, Any]]) -> int:
|
||||
"""Calculate streak for weekly habits (consecutive weeks with at least one check)."""
|
||||
today = datetime.now().date()
|
||||
|
||||
# Group completions by week
|
||||
weeks_with_checks = set()
|
||||
for completion in completions:
|
||||
completion_date = datetime.fromisoformat(completion["date"]).date()
|
||||
week_key = completion_date.isocalendar()[:2]
|
||||
weeks_with_checks.add(week_key)
|
||||
|
||||
streak = 0
|
||||
current_week = today.isocalendar()[:2]
|
||||
|
||||
while current_week in weeks_with_checks:
|
||||
streak += 1
|
||||
year, week = current_week
|
||||
if week == 1:
|
||||
year -= 1
|
||||
week = 52
|
||||
else:
|
||||
week -= 1
|
||||
current_week = (year, week)
|
||||
|
||||
return streak
|
||||
"""Calculate streak for weekly habits (consecutive days with check-ins).
|
||||
|
||||
For weekly habits, streak counts consecutive DAYS with check-ins,
|
||||
just like daily habits. The weekly frequency just means you should
|
||||
check in at least once per week.
|
||||
"""
|
||||
return _calculate_daily_streak(completions)
|
||||
|
||||
|
||||
def _calculate_monthly_streak(completions: List[Dict[str, Any]]) -> int:
|
||||
"""Calculate streak for monthly habits (consecutive months with at least one check)."""
|
||||
today = datetime.now().date()
|
||||
|
||||
# Group completions by month
|
||||
months_with_checks = set()
|
||||
for completion in completions:
|
||||
completion_date = datetime.fromisoformat(completion["date"]).date()
|
||||
month_key = (completion_date.year, completion_date.month)
|
||||
months_with_checks.add(month_key)
|
||||
|
||||
streak = 0
|
||||
current_month = (today.year, today.month)
|
||||
|
||||
while current_month in months_with_checks:
|
||||
streak += 1
|
||||
year, month = current_month
|
||||
if month == 1:
|
||||
year -= 1
|
||||
month = 12
|
||||
else:
|
||||
month -= 1
|
||||
current_month = (year, month)
|
||||
|
||||
return streak
|
||||
"""Calculate streak for monthly habits (consecutive days with check-ins).
|
||||
|
||||
For monthly habits, streak counts consecutive DAYS with check-ins,
|
||||
just like daily habits. The monthly frequency just means you should
|
||||
check in at least once per month.
|
||||
"""
|
||||
return _calculate_daily_streak(completions)
|
||||
|
||||
|
||||
def _calculate_custom_streak(habit: Dict[str, Any], completions: List[Dict[str, Any]]) -> int:
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
function handleSwipe() {
|
||||
const deltaX = touchEndX - touchStartX;
|
||||
const deltaY = Math.abs(touchEndY - touchStartY);
|
||||
|
||||
|
||||
// Ignore if vertical swipe or too short
|
||||
if (deltaY > maxVerticalDistance) return;
|
||||
if (Math.abs(deltaX) < minSwipeDistance) return;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"lastUpdated": "2026-02-07T03:00:05.489098",
|
||||
"lastUpdated": "2026-02-11T03:00:04.800665",
|
||||
"columns": [
|
||||
{
|
||||
"id": "backlog",
|
||||
@@ -30,58 +30,6 @@
|
||||
"id": "done",
|
||||
"name": "Done",
|
||||
"tasks": [
|
||||
{
|
||||
"id": "task-034",
|
||||
"title": "Actualizare documentație canale agenți",
|
||||
"description": "",
|
||||
"created": "2026-02-01T12:15:41Z",
|
||||
"priority": "medium",
|
||||
"completed": "2026-02-01T12:15:44Z"
|
||||
},
|
||||
{
|
||||
"id": "task-035",
|
||||
"title": "Restructurare echipă: șterg work, unific health+growth→self",
|
||||
"description": "",
|
||||
"created": "2026-02-01T12:20:59Z",
|
||||
"priority": "medium",
|
||||
"completed": "2026-02-01T12:23:32Z"
|
||||
},
|
||||
{
|
||||
"id": "task-036",
|
||||
"title": "Unificare în 1 agent cu tehnici diminuare dezavantaje",
|
||||
"description": "",
|
||||
"created": "2026-02-01T13:27:51Z",
|
||||
"priority": "medium",
|
||||
"completed": "2026-02-01T13:30:01Z"
|
||||
},
|
||||
{
|
||||
"id": "task-037",
|
||||
"title": "Coaching dimineață - Asumarea eforturilor (Zoltan Vereș)",
|
||||
"description": "",
|
||||
"created": "2026-02-02T07:01:14Z",
|
||||
"priority": "medium"
|
||||
},
|
||||
{
|
||||
"id": "task-038",
|
||||
"title": "Raport dimineata trimis pe email",
|
||||
"description": "",
|
||||
"created": "2026-02-03T06:31:08Z",
|
||||
"priority": "medium"
|
||||
},
|
||||
{
|
||||
"id": "task-039",
|
||||
"title": "Raport seară 3 feb trimis pe email",
|
||||
"description": "",
|
||||
"created": "2026-02-03T18:01:12Z",
|
||||
"priority": "medium"
|
||||
},
|
||||
{
|
||||
"id": "task-040",
|
||||
"title": "Job night-execute: 2 video-uri YouTube procesate",
|
||||
"description": "",
|
||||
"created": "2026-02-03T21:02:31Z",
|
||||
"priority": "medium"
|
||||
},
|
||||
{
|
||||
"id": "task-041",
|
||||
"title": "Raport dimineață trimis pe email",
|
||||
|
||||
@@ -1,6 +1,19 @@
|
||||
{
|
||||
"lastUpdated": "2026-02-09T19:00:00.000Z",
|
||||
"lastUpdated": "2026-02-11T07:00:00.000Z",
|
||||
"items": [
|
||||
{
|
||||
"id": "prov-2026-02-11",
|
||||
"text": "Provocare: Identifică un task pe care îl execuți singur și ar putea fi orchestrat",
|
||||
"context": "Alege UNA din variantele: (1) Delegat la angajat - task repetitiv pe care îl faci de 10 ori și ar putea învăța? (2) Automatizat cu Echo - verificare/raport/backup care rulează manual? (3) Modelat de la colegă - proces pe care ea îl face excelent și tu îl faci mai greu? (4) Documentat pentru viitor - explicație pe care o repeți la fiecare client nou? La 17:00 notează: Ce task? Cum ar arăta orchestrat? Primul pas minim pentru orchestrare? Nu implementa imediat - doar identifică și scrie. Conștientizarea e primul pas.",
|
||||
"example": "Exemple reale: (1) Explicația cum să adauge client nou în ROA - ai făcut-o de 10 ori la angajat, ar putea fi screencast + checklist. (2) Verificarea zilnică backups - rulează manual, ar putea fi script Echo automat cu alertă doar dacă fail. (3) Suportul tehnic calm - colega face excelent, tu mai nervos, ar putea cere să te învețe procesul TOTE intern. (4) Setup ANAF pentru client nou - repeți aceiași pași, ar putea fi documentație step-by-step pe care Echo o trimite automat.",
|
||||
"domain": "work",
|
||||
"dueDate": "2026-02-11",
|
||||
"done": false,
|
||||
"doneAt": null,
|
||||
"source": "Claude Code Multi-Agent Orchestration + TDi Mindset Entrepreneurship",
|
||||
"sourceUrl": "https://moltbot.tailf7372d.ts.net/echo/files.html#memory/kb/coaching/2026-02-11-dimineata.md",
|
||||
"createdAt": "2026-02-11T07:00:00.000Z"
|
||||
},
|
||||
{
|
||||
"id": "prov-2026-02-10",
|
||||
"text": "Provocare: Body Loose, Head Clear - verifică corpul înainte de situație tensionată",
|
||||
|
||||
Reference in New Issue
Block a user