healthy-developer 0.1.0
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.
- package/dist/chunk-KFGEBBKV.js +87 -0
- package/dist/cli.js +162 -0
- package/dist/mcp-server.js +13859 -0
- package/package.json +31 -0
- package/scripts/session-start.sh +27 -0
- package/scripts/user-prompt-submit.sh +54 -0
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "healthy-developer",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Wellness reminders integrated into your AI agent workflow — water and walk breaks, natively in Claude Code and any MCP-compatible IDE",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"keywords": ["developer", "wellness", "health", "mcp", "claude", "ai", "reminders"],
|
|
8
|
+
"bin": {
|
|
9
|
+
"healthy-developer": "./dist/cli.js"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsup",
|
|
13
|
+
"dev": "tsx src/cli.ts",
|
|
14
|
+
"prepublishOnly": "npm run build"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@clack/prompts": "^0.9.1",
|
|
18
|
+
"@modelcontextprotocol/sdk": "^1.10.2",
|
|
19
|
+
"chalk": "^5.4.1"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@types/node": "^22.15.2",
|
|
23
|
+
"tsup": "^8.4.0",
|
|
24
|
+
"tsx": "^4.19.3",
|
|
25
|
+
"typescript": "^5.8.3"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist",
|
|
29
|
+
"scripts"
|
|
30
|
+
]
|
|
31
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# healthy-developer — SessionStart hook
|
|
3
|
+
# Initializes state file if missing
|
|
4
|
+
|
|
5
|
+
CONFIG_FILE="$HOME/.healthy-developer/config.json"
|
|
6
|
+
STATE_FILE="$HOME/.healthy-developer/state.json"
|
|
7
|
+
CONFIG_DIR="$HOME/.healthy-developer"
|
|
8
|
+
|
|
9
|
+
mkdir -p "$CONFIG_DIR"
|
|
10
|
+
|
|
11
|
+
# Create default state if missing
|
|
12
|
+
if [ ! -f "$STATE_FILE" ]; then
|
|
13
|
+
TODAY=$(date +%Y-%m-%d)
|
|
14
|
+
echo "{\"lastWaterReminder\":0,\"lastWalkReminder\":0,\"waterCountToday\":0,\"lastResetDate\":\"$TODAY\"}" > "$STATE_FILE"
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
# Reset daily counter if new day
|
|
18
|
+
if [ -f "$STATE_FILE" ]; then
|
|
19
|
+
TODAY=$(date +%Y-%m-%d)
|
|
20
|
+
LAST_DATE=$(jq -r '.lastResetDate // ""' "$STATE_FILE" 2>/dev/null)
|
|
21
|
+
if [ "$LAST_DATE" != "$TODAY" ]; then
|
|
22
|
+
TMP=$(mktemp)
|
|
23
|
+
jq ".waterCountToday = 0 | .lastResetDate = \"$TODAY\"" "$STATE_FILE" > "$TMP" 2>/dev/null && mv "$TMP" "$STATE_FILE"
|
|
24
|
+
fi
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
exit 0
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# healthy-developer — UserPromptSubmit hook
|
|
3
|
+
# Checks wellness intervals and injects reminders into Claude's context
|
|
4
|
+
|
|
5
|
+
CONFIG_FILE="$HOME/.healthy-developer/config.json"
|
|
6
|
+
STATE_FILE="$HOME/.healthy-developer/state.json"
|
|
7
|
+
|
|
8
|
+
# Exit silently if not configured or disabled
|
|
9
|
+
[ -f "$CONFIG_FILE" ] || exit 0
|
|
10
|
+
ENABLED=$(jq -r '.enabled // true' "$CONFIG_FILE" 2>/dev/null)
|
|
11
|
+
[ "$ENABLED" = "false" ] && exit 0
|
|
12
|
+
|
|
13
|
+
# Read config
|
|
14
|
+
WATER_INTERVAL=$(jq -r '.waterIntervalMinutes // 30' "$CONFIG_FILE" 2>/dev/null)
|
|
15
|
+
WALK_INTERVAL=$(jq -r '.walkIntervalMinutes // 60' "$CONFIG_FILE" 2>/dev/null)
|
|
16
|
+
LANGUAGE=$(jq -r '.language // "es"' "$CONFIG_FILE" 2>/dev/null)
|
|
17
|
+
|
|
18
|
+
# Read state
|
|
19
|
+
LAST_WATER=$(jq -r '.lastWaterReminder // 0' "$STATE_FILE" 2>/dev/null)
|
|
20
|
+
LAST_WALK=$(jq -r '.lastWalkReminder // 0' "$STATE_FILE" 2>/dev/null)
|
|
21
|
+
|
|
22
|
+
NOW=$(date +%s)
|
|
23
|
+
WATER_ELAPSED=$(( (NOW - LAST_WATER) / 60 ))
|
|
24
|
+
WALK_ELAPSED=$(( (NOW - LAST_WALK) / 60 ))
|
|
25
|
+
|
|
26
|
+
REMINDER=""
|
|
27
|
+
|
|
28
|
+
if [ "$WATER_ELAPSED" -ge "$WATER_INTERVAL" ]; then
|
|
29
|
+
if [ "$LANGUAGE" = "es" ]; then
|
|
30
|
+
REMINDER="${REMINDER}💧 El usuario lleva ${WATER_ELAPSED} minutos sin tomar agua. Antes de responder su consulta, recordarle brevemente y con naturalidad que tome agua. Solo una línea, sin exagerar.\n"
|
|
31
|
+
else
|
|
32
|
+
REMINDER="${REMINDER}💧 The user hasn't had water in ${WATER_ELAPSED} minutes. Before answering their question, briefly and naturally remind them to drink water. One line, keep it casual.\n"
|
|
33
|
+
fi
|
|
34
|
+
# Update state
|
|
35
|
+
TMP=$(mktemp)
|
|
36
|
+
jq ".lastWaterReminder = $NOW | .waterCountToday = ((.waterCountToday // 0) + 1)" "$STATE_FILE" > "$TMP" 2>/dev/null && mv "$TMP" "$STATE_FILE"
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
if [ "$WALK_ELAPSED" -ge "$WALK_INTERVAL" ]; then
|
|
40
|
+
if [ "$LANGUAGE" = "es" ]; then
|
|
41
|
+
REMINDER="${REMINDER}🚶 El usuario lleva ${WALK_ELAPSED} minutos sentado. Antes de responder su consulta, recordarle brevemente que se levante y estire las piernas. Solo una línea, con naturalidad.\n"
|
|
42
|
+
else
|
|
43
|
+
REMINDER="${REMINDER}🚶 The user has been sitting for ${WALK_ELAPSED} minutes. Before answering their question, briefly remind them to stand up and stretch. One line, keep it natural.\n"
|
|
44
|
+
fi
|
|
45
|
+
TMP=$(mktemp)
|
|
46
|
+
jq ".lastWalkReminder = $NOW" "$STATE_FILE" > "$TMP" 2>/dev/null && mv "$TMP" "$STATE_FILE"
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
# Only output if there's a reminder — stdout becomes additionalContext for Claude
|
|
50
|
+
if [ -n "$REMINDER" ]; then
|
|
51
|
+
printf "## healthy-developer — wellness reminder\n%b" "$REMINDER"
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
exit 0
|