human-mode 0.1.0__tar.gz
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.
- human_mode-0.1.0/PKG-INFO +7 -0
- human_mode-0.1.0/README.md +133 -0
- human_mode-0.1.0/human_mode/__init__.py +0 -0
- human_mode-0.1.0/human_mode/cli.py +36 -0
- human_mode-0.1.0/human_mode/reminder.py +113 -0
- human_mode-0.1.0/human_mode/utils.py +36 -0
- human_mode-0.1.0/human_mode.egg-info/PKG-INFO +7 -0
- human_mode-0.1.0/human_mode.egg-info/SOURCES.txt +11 -0
- human_mode-0.1.0/human_mode.egg-info/dependency_links.txt +1 -0
- human_mode-0.1.0/human_mode.egg-info/entry_points.txt +2 -0
- human_mode-0.1.0/human_mode.egg-info/top_level.txt +1 -0
- human_mode-0.1.0/setup.cfg +4 -0
- human_mode-0.1.0/setup.py +15 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# π§ human-mode
|
|
2
|
+
|
|
3
|
+
A smart CLI tool that reminds you to *actually be human*.
|
|
4
|
+
|
|
5
|
+
Most reminder apps just spam notifications.
|
|
6
|
+
This one adapts to your behavior.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## π Features
|
|
11
|
+
|
|
12
|
+
* β±οΈ Smart reminders (`10s`, `5m`, `1h`)
|
|
13
|
+
* π§ Activity-aware (wonβt interrupt when idle)
|
|
14
|
+
* β‘ Lightweight & fast (minimal dependencies)
|
|
15
|
+
* π Usage analytics (`human report`)
|
|
16
|
+
* β οΈ Burnout detection (long work session alerts)
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## π¦ Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install human-mode
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## π οΈ Usage
|
|
29
|
+
|
|
30
|
+
### β€ Add a reminder
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
human add "drink water" 30m
|
|
34
|
+
human add "stretch" 1h
|
|
35
|
+
human add "blink" 10s
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
### β€ Run reminders
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
human run
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
### β€ View report
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
human report
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Example output:
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
π Human Mode Report
|
|
58
|
+
Total reminders: 5
|
|
59
|
+
Active time: 12.5 minutes
|
|
60
|
+
Burnout risk: Low π
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## π‘ Why this exists
|
|
66
|
+
|
|
67
|
+
I tried multiple reminder apps.
|
|
68
|
+
|
|
69
|
+
Most of them:
|
|
70
|
+
|
|
71
|
+
* Required accounts
|
|
72
|
+
* Ran heavy background services
|
|
73
|
+
* Sent annoying notifications
|
|
74
|
+
|
|
75
|
+
So I built something simple:
|
|
76
|
+
|
|
77
|
+
* No cloud
|
|
78
|
+
* No accounts
|
|
79
|
+
* Just a CLI tool that adapts to how you work
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## π§ How it works
|
|
84
|
+
|
|
85
|
+
* Tracks system activity (CPU usage as a proxy)
|
|
86
|
+
* Delays reminders when you're focused
|
|
87
|
+
* Skips reminders when you're idle
|
|
88
|
+
* Tracks usage to generate insights
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## π Project Structure
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
human-mode/
|
|
96
|
+
β
|
|
97
|
+
βββ human_mode/
|
|
98
|
+
β βββ cli.py
|
|
99
|
+
β βββ reminder.py
|
|
100
|
+
β βββ utils.py
|
|
101
|
+
β
|
|
102
|
+
βββ setup.py
|
|
103
|
+
βββ README.md
|
|
104
|
+
βββ requirements.txt
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## βοΈ Tech Stack
|
|
110
|
+
|
|
111
|
+
* Python (stdlib + minimal dependencies)
|
|
112
|
+
* `psutil` (for activity detection)
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## π§ Future Improvements
|
|
117
|
+
|
|
118
|
+
* Desktop notifications
|
|
119
|
+
* Daily/weekly reports
|
|
120
|
+
* ML-based focus detection
|
|
121
|
+
* Plugin system (Slack, etc.)
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## π€ Contributing
|
|
126
|
+
|
|
127
|
+
PRs and suggestions are welcome!
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## β If you found this useful
|
|
132
|
+
|
|
133
|
+
Give it a star on GitHub β it helps a lot π
|
|
File without changes
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from human_mode.reminder import add_reminder, run_reminders, show_report
|
|
3
|
+
from human_mode.utils import parse_time
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def handle_command():
|
|
7
|
+
args = sys.argv
|
|
8
|
+
|
|
9
|
+
if len(args) < 2:
|
|
10
|
+
print("Usage:")
|
|
11
|
+
print(" human add <message> <interval>")
|
|
12
|
+
print(" human run")
|
|
13
|
+
print(" human report")
|
|
14
|
+
return
|
|
15
|
+
|
|
16
|
+
command = args[1]
|
|
17
|
+
|
|
18
|
+
if command == "add":
|
|
19
|
+
if len(args) < 4:
|
|
20
|
+
print("Usage: human add <message> <interval>")
|
|
21
|
+
return
|
|
22
|
+
|
|
23
|
+
message = " ".join(args[2:-1]) # β
FIXED
|
|
24
|
+
interval_input = args[-1]
|
|
25
|
+
interval = parse_time(interval_input)
|
|
26
|
+
|
|
27
|
+
add_reminder(message, interval)
|
|
28
|
+
|
|
29
|
+
elif command == "run":
|
|
30
|
+
run_reminders()
|
|
31
|
+
|
|
32
|
+
elif command == "report":
|
|
33
|
+
show_report()
|
|
34
|
+
|
|
35
|
+
else:
|
|
36
|
+
print("Unknown command")
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import time
|
|
2
|
+
import json
|
|
3
|
+
import os
|
|
4
|
+
from human_mode.utils import is_user_active
|
|
5
|
+
|
|
6
|
+
FILE = "reminders.json"
|
|
7
|
+
STATS_FILE = "stats.json"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# ---------------- REMINDERS ----------------
|
|
11
|
+
def load_reminders():
|
|
12
|
+
if not os.path.exists(FILE):
|
|
13
|
+
return []
|
|
14
|
+
with open(FILE, "r") as f:
|
|
15
|
+
return json.load(f)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def save_reminders(data):
|
|
19
|
+
with open(FILE, "w") as f:
|
|
20
|
+
json.dump(data, f)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def add_reminder(message, interval):
|
|
24
|
+
data = load_reminders()
|
|
25
|
+
data.append({"message": message, "interval": interval})
|
|
26
|
+
save_reminders(data)
|
|
27
|
+
# print(f"Added reminder: {message} every {interval} min")
|
|
28
|
+
if interval < 1:
|
|
29
|
+
print(f"Added reminder: {message} every {int(interval*60)} sec")
|
|
30
|
+
else:
|
|
31
|
+
print(f"Added reminder: {message} every {interval} min")
|
|
32
|
+
|
|
33
|
+
# ---------------- STATS ----------------
|
|
34
|
+
def load_stats():
|
|
35
|
+
if not os.path.exists(STATS_FILE):
|
|
36
|
+
return {"total_reminders": 0, "active_time": 0}
|
|
37
|
+
with open(STATS_FILE, "r") as f:
|
|
38
|
+
return json.load(f)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def save_stats(stats):
|
|
42
|
+
with open(STATS_FILE, "w") as f:
|
|
43
|
+
json.dump(stats, f)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
# ---------------- RUN ----------------
|
|
47
|
+
def run_reminders():
|
|
48
|
+
reminders = load_reminders()
|
|
49
|
+
|
|
50
|
+
if not reminders:
|
|
51
|
+
print("No reminders found")
|
|
52
|
+
return
|
|
53
|
+
|
|
54
|
+
print("Running smart reminders... (Ctrl+C to stop)")
|
|
55
|
+
|
|
56
|
+
current_time = time.time()
|
|
57
|
+
last_trigger = [current_time] * len(reminders)
|
|
58
|
+
focus_start = current_time
|
|
59
|
+
|
|
60
|
+
stats = load_stats()
|
|
61
|
+
|
|
62
|
+
while True:
|
|
63
|
+
current_time = time.time()
|
|
64
|
+
active = is_user_active()
|
|
65
|
+
|
|
66
|
+
for i, r in enumerate(reminders):
|
|
67
|
+
|
|
68
|
+
next_time = last_trigger[i] + (r["interval"] * 60)
|
|
69
|
+
|
|
70
|
+
if current_time >= next_time:
|
|
71
|
+
|
|
72
|
+
if active:
|
|
73
|
+
print(f"\nπ‘ You've been working continuously. {r['message']}?")
|
|
74
|
+
stats["total_reminders"] += 1
|
|
75
|
+
else:
|
|
76
|
+
# print(f"\nπ΄ Skipping (idle): {r['message']}")
|
|
77
|
+
last_trigger[i] = current_time
|
|
78
|
+
continue
|
|
79
|
+
|
|
80
|
+
last_trigger[i] = current_time
|
|
81
|
+
|
|
82
|
+
# track active time
|
|
83
|
+
if active:
|
|
84
|
+
stats["active_time"] += 5 # loop runs every 5 sec
|
|
85
|
+
|
|
86
|
+
save_stats(stats)
|
|
87
|
+
|
|
88
|
+
# burnout detection
|
|
89
|
+
if active and (current_time - focus_start > 7200):
|
|
90
|
+
print("\nβ οΈ You've been working for 2+ hours. Take a break!")
|
|
91
|
+
focus_start = current_time
|
|
92
|
+
|
|
93
|
+
time.sleep(5)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
# ---------------- REPORT ----------------
|
|
97
|
+
def show_report():
|
|
98
|
+
stats = load_stats()
|
|
99
|
+
|
|
100
|
+
total = stats["total_reminders"]
|
|
101
|
+
active_time = stats["active_time"] / 60 # seconds β minutes
|
|
102
|
+
|
|
103
|
+
if active_time > 120:
|
|
104
|
+
burnout = "High β οΈ"
|
|
105
|
+
elif active_time > 60:
|
|
106
|
+
burnout = "Moderate π"
|
|
107
|
+
else:
|
|
108
|
+
burnout = "Low π"
|
|
109
|
+
|
|
110
|
+
print("\nπ Human Mode Report")
|
|
111
|
+
print(f"Total reminders: {total}")
|
|
112
|
+
print(f"Active time: {round(active_time, 2)} minutes")
|
|
113
|
+
print(f"Burnout risk: {burnout}")
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import psutil
|
|
2
|
+
import time
|
|
3
|
+
|
|
4
|
+
# πΉ Time parsing (for CLI)
|
|
5
|
+
def parse_time(interval_str):
|
|
6
|
+
"""
|
|
7
|
+
Converts time like:
|
|
8
|
+
30m -> minutes
|
|
9
|
+
1h -> minutes
|
|
10
|
+
45s -> minutes
|
|
11
|
+
"""
|
|
12
|
+
unit = interval_str[-1]
|
|
13
|
+
value = int(interval_str[:-1])
|
|
14
|
+
|
|
15
|
+
if unit == "s":
|
|
16
|
+
return value / 60
|
|
17
|
+
elif unit == "m":
|
|
18
|
+
return value
|
|
19
|
+
elif unit == "h":
|
|
20
|
+
return value * 60
|
|
21
|
+
else:
|
|
22
|
+
raise ValueError("Invalid time format. Use s, m, or h.")
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# πΉ Activity detection
|
|
26
|
+
def is_user_active(threshold=60):
|
|
27
|
+
"""
|
|
28
|
+
Checks CPU usage β basic proxy for activity
|
|
29
|
+
"""
|
|
30
|
+
cpu = psutil.cpu_percent(interval=1)
|
|
31
|
+
return cpu > 5 # tweak later
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
# (Optional for future use)
|
|
35
|
+
def is_user_idle(last_activity_time, idle_limit=300):
|
|
36
|
+
return (time.time() - last_activity_time) > idle_limit
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
setup.py
|
|
3
|
+
human_mode/__init__.py
|
|
4
|
+
human_mode/cli.py
|
|
5
|
+
human_mode/reminder.py
|
|
6
|
+
human_mode/utils.py
|
|
7
|
+
human_mode.egg-info/PKG-INFO
|
|
8
|
+
human_mode.egg-info/SOURCES.txt
|
|
9
|
+
human_mode.egg-info/dependency_links.txt
|
|
10
|
+
human_mode.egg-info/entry_points.txt
|
|
11
|
+
human_mode.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
human_mode
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
setup(
|
|
4
|
+
name="human-mode",
|
|
5
|
+
version="0.1.0",
|
|
6
|
+
packages=find_packages(),
|
|
7
|
+
install_requires=[],
|
|
8
|
+
entry_points={
|
|
9
|
+
"console_scripts": [
|
|
10
|
+
"human=human_mode.cli:handle_command"
|
|
11
|
+
]
|
|
12
|
+
},
|
|
13
|
+
author="Sakshi Selmokar",
|
|
14
|
+
description="A smart CLI tool to remind you to be human",
|
|
15
|
+
)
|