49 lines
1.3 KiB
Python
Executable File
49 lines
1.3 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import json
|
|
from datetime import datetime, timezone
|
|
from pathlib import Path
|
|
|
|
STATE_PATH = Path('/home/node/.openclaw/workspace/state/projects.json')
|
|
|
|
|
|
def parse_ts(ts: str | None):
|
|
if not ts:
|
|
return None
|
|
if ts.endswith('Z'):
|
|
ts = ts[:-1] + '+00:00'
|
|
return datetime.fromisoformat(ts)
|
|
|
|
|
|
def main():
|
|
state = json.loads(STATE_PATH.read_text())
|
|
now = datetime.now(timezone.utc)
|
|
stale = []
|
|
missing_next_action = []
|
|
missing_tasks = []
|
|
|
|
for project in state.get('projects', []):
|
|
if project.get('status') != 'open':
|
|
continue
|
|
if not project.get('next_action'):
|
|
missing_next_action.append(project['title'])
|
|
if not project.get('task_ids'):
|
|
missing_tasks.append(project['title'])
|
|
last = parse_ts(project.get('last_activity_at'))
|
|
if last and (now - last).days >= 14:
|
|
stale.append({
|
|
'title': project['title'],
|
|
'days_since_update': (now - last).days,
|
|
'last_activity_at': project.get('last_activity_at')
|
|
})
|
|
|
|
print(json.dumps({
|
|
'generated_at': now.isoformat(),
|
|
'stale_projects': stale,
|
|
'missing_next_action': missing_next_action,
|
|
'missing_tasks': missing_tasks
|
|
}, indent=2))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|