session-planner 1.0.1 → 1.0.3
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/README.md +12 -33
- package/hello-list.md +10 -0
- package/hello-remove.md +15 -0
- package/hello-scheduler.sh +270 -0
- package/hello.md +55 -0
- package/package.json +13 -7
package/README.md
CHANGED
|
@@ -3,39 +3,21 @@
|
|
|
3
3
|
[](https://github.com/MahmoudMabrok/SessionPlanner/actions)
|
|
4
4
|
[](https://www.npmjs.com/package/session-planner)
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
>
|
|
8
|
-
> 📦 **Available on npm:** [session-planner](https://www.npmjs.com/package/session-planner)
|
|
6
|
+
This tool helps maximize your Claude Code session duration by opening sessions ahead of time. Starting a session earlier ensures that if you hit a usage limit, the next reset time is already much closer (or has already passed), effectively eliminating idle waiting time.
|
|
9
7
|
|
|
10
|
-
---
|
|
11
8
|
|
|
12
|
-
|
|
9
|
+
# How it works
|
|
13
10
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
> Schedule "Hello!" Claude Code sessions at times you choose — opening Claude **N hours before** each target time. Works as a terminal CLI, an `npx` one-liner, or a Claude Code plugin.
|
|
12
|
+
>
|
|
13
|
+
> 📦 **Available on npm:** [session-planner](https://www.npmjs.com/package/session-planner)
|
|
17
14
|
|
|
18
|
-

|
|
19
15
|
|
|
20
|
-
```mermaid
|
|
21
|
-
graph TD
|
|
22
|
-
subgraph Standard_Way [Standard Way]
|
|
23
|
-
A1[Start Work at 1 PM] --> B1{Hit Limit?}
|
|
24
|
-
B1 -- Yes --> C1["'Limit will reset at 9:00 PM'"]
|
|
25
|
-
C1 --> D1[Wait 5 Hours 😫]
|
|
26
|
-
end
|
|
27
16
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
C2 -- Yes --> D2["'Limit will reset... in 5 mins'"]
|
|
32
|
-
D2 --> E2[NO MORE WAITING 😎]
|
|
33
|
-
end
|
|
17
|
+
## The "Session Hack" Explained
|
|
18
|
+

|
|
19
|
+

|
|
34
20
|
|
|
35
|
-
style A2 fill:#4CAF50,stroke:#2E7D32,color:#fff
|
|
36
|
-
style E2 fill:#2196F3,stroke:#1565C0,color:#fff
|
|
37
|
-
style D1 fill:#f44336,stroke:#c62828,color:#fff
|
|
38
|
-
```
|
|
39
21
|
|
|
40
22
|
---
|
|
41
23
|
|
|
@@ -143,14 +125,11 @@ Logs: `~/.claude/session-planner.log`
|
|
|
143
125
|
|
|
144
126
|
```
|
|
145
127
|
SessionPlanner/
|
|
146
|
-
├──
|
|
147
|
-
├──
|
|
148
|
-
├──
|
|
149
|
-
├── skills/hello-scheduler/SKILL.md
|
|
150
|
-
├── scripts/hello-scheduler.sh ← core scheduling logic
|
|
151
|
-
├── tests/test-parse.sh ← 18 unit tests
|
|
128
|
+
├── hello-scheduler.sh ← core scheduling logic
|
|
129
|
+
├── session-planner.js ← npx / global CLI entry
|
|
130
|
+
├── {hello,hello-list,hello-remove}.md ← command definitions
|
|
152
131
|
├── package.json
|
|
153
|
-
└── .
|
|
132
|
+
└── README.md
|
|
154
133
|
```
|
|
155
134
|
|
|
156
135
|
---
|
package/hello-list.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: List all scheduled Hello! sessions. Shows target times, session-open times, and cron expressions.
|
|
3
|
+
allowed-tools: Bash
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
List all scheduled hello sessions:
|
|
7
|
+
|
|
8
|
+
!`bash ~/.claude/scripts/hello-scheduler.sh --list`
|
|
9
|
+
|
|
10
|
+
Present the output as a clean table to the user. If no jobs are found, let them know and suggest running `/hello <time>` to schedule one.
|
package/hello-remove.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Remove a scheduled Hello! session. Usage: /hello-remove 2pm OR /hello-remove --all
|
|
3
|
+
argument-hint: [time] e.g. 2pm OR --all
|
|
4
|
+
allowed-tools: Bash
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
The user wants to remove a scheduled hello session. Their argument is: $ARGUMENTS
|
|
8
|
+
|
|
9
|
+
If the argument is "--all" or "all":
|
|
10
|
+
!`bash ~/.claude/scripts/hello-scheduler.sh --remove-all`
|
|
11
|
+
|
|
12
|
+
Otherwise treat $ARGUMENTS as a time and run:
|
|
13
|
+
!`bash ~/.claude/scripts/hello-scheduler.sh --remove $ARGUMENTS`
|
|
14
|
+
|
|
15
|
+
Confirm to the user what was removed.
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# scripts/hello-scheduler.sh
|
|
3
|
+
# Schedule "Hello!" Claude Code sessions at specific times.
|
|
4
|
+
# Each session opens N hours before the chosen time (default: 4h).
|
|
5
|
+
#
|
|
6
|
+
# When installed as a plugin, this script lives at:
|
|
7
|
+
# ~/.claude/plugins/session-planner/scripts/hello-scheduler.sh
|
|
8
|
+
#
|
|
9
|
+
# Usage:
|
|
10
|
+
# hello-scheduler.sh 1am
|
|
11
|
+
# hello-scheduler.sh 9am 2pm 6pm
|
|
12
|
+
# hello-scheduler.sh 14:00 --offset 2h
|
|
13
|
+
# hello-scheduler.sh --list
|
|
14
|
+
# hello-scheduler.sh --remove 2pm
|
|
15
|
+
# hello-scheduler.sh --remove-all
|
|
16
|
+
# hello-scheduler.sh --help
|
|
17
|
+
|
|
18
|
+
set -euo pipefail
|
|
19
|
+
|
|
20
|
+
# ── defaults ──────────────────────────────────────────────────────────────────
|
|
21
|
+
OFFSET_HOURS=4
|
|
22
|
+
TIMES=()
|
|
23
|
+
LIST_MODE=false
|
|
24
|
+
REMOVE_ALL=false
|
|
25
|
+
REMOVE_TIME=""
|
|
26
|
+
|
|
27
|
+
# ── colours (disabled when not a tty, e.g. inside cron) ──────────────────────
|
|
28
|
+
if [[ -t 1 ]]; then
|
|
29
|
+
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
|
|
30
|
+
BOLD='\033[1m'; RESET='\033[0m'
|
|
31
|
+
else
|
|
32
|
+
RED=''; GREEN=''; YELLOW=''; BOLD=''; RESET=''
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
# ── helpers ───────────────────────────────────────────────────────────────────
|
|
36
|
+
|
|
37
|
+
usage() {
|
|
38
|
+
cat <<EOF
|
|
39
|
+
${BOLD}hello-scheduler${RESET} — Schedule "Hello!" Claude Code sessions
|
|
40
|
+
|
|
41
|
+
${BOLD}USAGE${RESET}
|
|
42
|
+
hello-scheduler.sh <time> [time2 ...] [--offset Nh]
|
|
43
|
+
hello-scheduler.sh --list
|
|
44
|
+
hello-scheduler.sh --remove <time>
|
|
45
|
+
hello-scheduler.sh --remove-all
|
|
46
|
+
|
|
47
|
+
${BOLD}TIME FORMATS${RESET}
|
|
48
|
+
1am 2pm 12:00 9:30am 14:30
|
|
49
|
+
|
|
50
|
+
${BOLD}OPTIONS${RESET}
|
|
51
|
+
--offset Nh Open session N hours before target time (default: 4)
|
|
52
|
+
--list Show all scheduled hello jobs
|
|
53
|
+
--remove <time> Remove the job for a specific target time
|
|
54
|
+
--remove-all Cancel all scheduled hello jobs
|
|
55
|
+
--help Show this help
|
|
56
|
+
|
|
57
|
+
${BOLD}EXAMPLES${RESET}
|
|
58
|
+
hello-scheduler.sh 1am
|
|
59
|
+
hello-scheduler.sh 9am 2pm 6pm
|
|
60
|
+
hello-scheduler.sh 14:00 --offset 2h
|
|
61
|
+
hello-scheduler.sh --remove 2pm
|
|
62
|
+
hello-scheduler.sh --list
|
|
63
|
+
EOF
|
|
64
|
+
exit 0
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
error() { echo -e "${RED}ERROR:${RESET} $1" >&2; exit 1; }
|
|
68
|
+
|
|
69
|
+
# Cross-platform date → epoch (GNU date -d OR BSD/macOS date -j)
|
|
70
|
+
timestamp_for() {
|
|
71
|
+
local s="$1"
|
|
72
|
+
date -d "$s" +%s 2>/dev/null \
|
|
73
|
+
|| date -j -f "%Y-%m-%d %H:%M:%S" "$s" +%s 2>/dev/null \
|
|
74
|
+
|| error "Cannot parse date '$s'. Is 'date' available?"
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
# Parse any supported time format → sets PARSED_HOUR, PARSED_MIN
|
|
78
|
+
parse_time() {
|
|
79
|
+
local raw="${1,,}"
|
|
80
|
+
PARSED_HOUR=""; PARSED_MIN=0
|
|
81
|
+
|
|
82
|
+
# 24-hour H:MM or HH:MM
|
|
83
|
+
if [[ "$raw" =~ ^([0-9]{1,2}):([0-9]{2})$ ]]; then
|
|
84
|
+
PARSED_HOUR=$((10#${BASH_REMATCH[1]}))
|
|
85
|
+
PARSED_MIN=$((10#${BASH_REMATCH[2]}))
|
|
86
|
+
|
|
87
|
+
# 12-hour with minutes H:MMam / H:MMpm
|
|
88
|
+
elif [[ "$raw" =~ ^([0-9]{1,2}):([0-9]{2})(am|pm)$ ]]; then
|
|
89
|
+
local h=$((10#${BASH_REMATCH[1]})) m=$((10#${BASH_REMATCH[2]})) ap=${BASH_REMATCH[3]}
|
|
90
|
+
[[ $h -lt 1 || $h -gt 12 ]] && error "Hour must be 1-12 for am/pm (got: $1)"
|
|
91
|
+
[[ $m -gt 59 ]] && error "Minutes must be 00-59 (got: $1)"
|
|
92
|
+
[[ "$ap" == "am" ]] && PARSED_HOUR=$(( h==12 ? 0 : h )) || PARSED_HOUR=$(( h==12 ? 12 : h+12 ))
|
|
93
|
+
PARSED_MIN=$m
|
|
94
|
+
|
|
95
|
+
# 12-hour no minutes Ham / Hpm
|
|
96
|
+
elif [[ "$raw" =~ ^([0-9]{1,2})(am|pm)$ ]]; then
|
|
97
|
+
local h=$((10#${BASH_REMATCH[1]})) ap=${BASH_REMATCH[2]}
|
|
98
|
+
[[ $h -lt 1 || $h -gt 12 ]] && error "Hour must be 1-12 for am/pm (got: $1)"
|
|
99
|
+
[[ "$ap" == "am" ]] && PARSED_HOUR=$(( h==12 ? 0 : h )) || PARSED_HOUR=$(( h==12 ? 12 : h+12 ))
|
|
100
|
+
PARSED_MIN=0
|
|
101
|
+
|
|
102
|
+
else
|
|
103
|
+
error "Unrecognised time format: '$1'. Try: 1am 2:30pm 14:00"
|
|
104
|
+
fi
|
|
105
|
+
|
|
106
|
+
[[ $PARSED_HOUR -gt 23 ]] && error "Hour out of range 0-23 (got: $1)"
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
# 24h hour+min → pretty 12h string
|
|
110
|
+
pretty_time() {
|
|
111
|
+
local h=$1 m=$2 suffix ph
|
|
112
|
+
if [[ $h -eq 0 ]]; then ph=12; suffix="am"
|
|
113
|
+
elif [[ $h -lt 12 ]]; then ph=$h; suffix="am"
|
|
114
|
+
elif [[ $h -eq 12 ]]; then ph=12; suffix="pm"
|
|
115
|
+
else ph=$(( h-12 )); suffix="pm"
|
|
116
|
+
fi
|
|
117
|
+
printf "%d:%02d %s" $ph $m $suffix
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
# Seconds until next occurrence of HH:MM (today or tomorrow)
|
|
121
|
+
seconds_until() {
|
|
122
|
+
local th=$1 tm=$2
|
|
123
|
+
local now today target_ts
|
|
124
|
+
now=$(date +%s)
|
|
125
|
+
today=$(date +%Y-%m-%d)
|
|
126
|
+
target_ts=$(timestamp_for "$today $(printf '%02d:%02d' "$th" "$tm"):00")
|
|
127
|
+
[[ $target_ts -le $now ]] && target_ts=$(( target_ts + 86400 ))
|
|
128
|
+
echo $(( target_ts - now ))
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
# ── argument parsing ──────────────────────────────────────────────────────────
|
|
132
|
+
|
|
133
|
+
[[ $# -eq 0 ]] && usage
|
|
134
|
+
|
|
135
|
+
while [[ $# -gt 0 ]]; do
|
|
136
|
+
case "$1" in
|
|
137
|
+
--help|-h) usage ;;
|
|
138
|
+
--list|-l) LIST_MODE=true; shift ;;
|
|
139
|
+
--remove-all) REMOVE_ALL=true; shift ;;
|
|
140
|
+
--remove)
|
|
141
|
+
[[ -z "${2:-}" ]] && error "--remove requires a time (e.g. --remove 2pm)"
|
|
142
|
+
REMOVE_TIME="$2"; shift 2 ;;
|
|
143
|
+
--offset)
|
|
144
|
+
[[ -z "${2:-}" ]] && error "--offset requires a value (e.g. 2h or 2)"
|
|
145
|
+
val="${2//h/}"
|
|
146
|
+
[[ "$val" =~ ^[0-9]+$ ]] || error "--offset must be a number (e.g. 2h or 2)"
|
|
147
|
+
OFFSET_HOURS=$val; shift 2 ;;
|
|
148
|
+
--offset=*)
|
|
149
|
+
val="${1#*=}"; val="${val//h/}"
|
|
150
|
+
[[ "$val" =~ ^[0-9]+$ ]] || error "--offset must be a number (e.g. --offset=2h)"
|
|
151
|
+
OFFSET_HOURS=$val; shift ;;
|
|
152
|
+
-*) error "Unknown option: $1" ;;
|
|
153
|
+
*) TIMES+=("$1"); shift ;;
|
|
154
|
+
esac
|
|
155
|
+
done
|
|
156
|
+
|
|
157
|
+
# ── --list ────────────────────────────────────────────────────────────────────
|
|
158
|
+
|
|
159
|
+
if $LIST_MODE; then
|
|
160
|
+
echo -e "${BOLD}Scheduled Hello jobs:${RESET}"
|
|
161
|
+
if crontab -l 2>/dev/null | grep -q "# session-planner"; then
|
|
162
|
+
crontab -l 2>/dev/null | grep "# session-planner"
|
|
163
|
+
else
|
|
164
|
+
echo -e " ${YELLOW}No session-planner jobs found.${RESET}"
|
|
165
|
+
fi
|
|
166
|
+
exit 0
|
|
167
|
+
fi
|
|
168
|
+
|
|
169
|
+
# ── --remove-all ──────────────────────────────────────────────────────────────
|
|
170
|
+
|
|
171
|
+
if $REMOVE_ALL; then
|
|
172
|
+
tmp=$(mktemp)
|
|
173
|
+
crontab -l 2>/dev/null \
|
|
174
|
+
| grep -v "# session-planner" \
|
|
175
|
+
| grep -v "session-planner" \
|
|
176
|
+
> "$tmp" || true
|
|
177
|
+
crontab "$tmp"; rm -f "$tmp"
|
|
178
|
+
echo -e "${GREEN}✓${RESET} All session-planner jobs removed."
|
|
179
|
+
exit 0
|
|
180
|
+
fi
|
|
181
|
+
|
|
182
|
+
# ── --remove <time> ───────────────────────────────────────────────────────────
|
|
183
|
+
|
|
184
|
+
if [[ -n "$REMOVE_TIME" ]]; then
|
|
185
|
+
parse_time "$REMOVE_TIME"
|
|
186
|
+
TARGET_PRETTY=$(pretty_time "$PARSED_HOUR" "$PARSED_MIN")
|
|
187
|
+
tmp=$(mktemp)
|
|
188
|
+
crontab -l 2>/dev/null \
|
|
189
|
+
| grep -v "# session-planner.*${TARGET_PRETTY}" \
|
|
190
|
+
| grep -v "Hello! It is now ${TARGET_PRETTY}" \
|
|
191
|
+
> "$tmp" || true
|
|
192
|
+
crontab "$tmp"; rm -f "$tmp"
|
|
193
|
+
echo -e "${GREEN}✓${RESET} Removed session-planner job for ${BOLD}${TARGET_PRETTY}${RESET}."
|
|
194
|
+
exit 0
|
|
195
|
+
fi
|
|
196
|
+
|
|
197
|
+
# ── validate at least one time was given ─────────────────────────────────────
|
|
198
|
+
|
|
199
|
+
[[ ${#TIMES[@]} -eq 0 ]] && error "Please provide at least one time. E.g: hello-scheduler.sh 1am"
|
|
200
|
+
|
|
201
|
+
# ── ensure log dir ────────────────────────────────────────────────────────────
|
|
202
|
+
|
|
203
|
+
mkdir -p "$HOME/.claude"
|
|
204
|
+
LOG="$HOME/.claude/session-planner.log"
|
|
205
|
+
|
|
206
|
+
# ── load crontab, strip existing session-planner entries ─────────────────────
|
|
207
|
+
|
|
208
|
+
tmp=$(mktemp)
|
|
209
|
+
crontab -l 2>/dev/null \
|
|
210
|
+
| grep -v "# session-planner" \
|
|
211
|
+
| grep -v "session-planner" \
|
|
212
|
+
> "$tmp" || true
|
|
213
|
+
|
|
214
|
+
# ── process each time ─────────────────────────────────────────────────────────
|
|
215
|
+
|
|
216
|
+
JOBS_JSON="["
|
|
217
|
+
FIRST=true
|
|
218
|
+
SOONEST_SECS=999999999
|
|
219
|
+
SOONEST_TARGET=""
|
|
220
|
+
SOONEST_SESSION=""
|
|
221
|
+
|
|
222
|
+
for T in "${TIMES[@]}"; do
|
|
223
|
+
parse_time "$T"
|
|
224
|
+
TARGET_H=$PARSED_HOUR
|
|
225
|
+
TARGET_M=$PARSED_MIN
|
|
226
|
+
|
|
227
|
+
# Calculate session-open time = target − offset
|
|
228
|
+
TOTAL=$(( TARGET_H*60 + TARGET_M ))
|
|
229
|
+
SCHED=$(( (TOTAL - OFFSET_HOURS*60 + 1440) % 1440 ))
|
|
230
|
+
SCHED_H=$(( SCHED/60 ))
|
|
231
|
+
SCHED_M=$(( SCHED%60 ))
|
|
232
|
+
|
|
233
|
+
TARGET_PRETTY=$(pretty_time "$TARGET_H" "$TARGET_M")
|
|
234
|
+
SCHED_PRETTY=$(pretty_time "$SCHED_H" "$SCHED_M")
|
|
235
|
+
|
|
236
|
+
# cron job: claude --print fires at session-open time
|
|
237
|
+
MSG="Hello! It is now ${TARGET_PRETTY}. This is your scheduled greeting."
|
|
238
|
+
CRON_EXPR="${SCHED_M} ${SCHED_H} * * *"
|
|
239
|
+
CRON_LINE="${CRON_EXPR} claude --print \"${MSG}\" >> ${LOG} 2>&1"
|
|
240
|
+
|
|
241
|
+
{
|
|
242
|
+
echo "# session-planner: session at ${SCHED_PRETTY} → greeting at ${TARGET_PRETTY} (offset: ${OFFSET_HOURS}h)"
|
|
243
|
+
echo "$CRON_LINE"
|
|
244
|
+
} >> "$tmp"
|
|
245
|
+
|
|
246
|
+
# Seconds until session-open for /loop handoff
|
|
247
|
+
LOOP_SECS=$(seconds_until "$SCHED_H" "$SCHED_M")
|
|
248
|
+
|
|
249
|
+
if [[ $LOOP_SECS -lt $SOONEST_SECS ]]; then
|
|
250
|
+
SOONEST_SECS=$LOOP_SECS
|
|
251
|
+
SOONEST_TARGET="$TARGET_PRETTY"
|
|
252
|
+
SOONEST_SESSION="$SCHED_PRETTY"
|
|
253
|
+
fi
|
|
254
|
+
|
|
255
|
+
# Structured output for Claude to parse
|
|
256
|
+
echo "SCHEDULED: {\"target\":\"${TARGET_PRETTY}\",\"session_at\":\"${SCHED_PRETTY}\",\"cron\":\"${CRON_EXPR}\",\"loop_in_seconds\":${LOOP_SECS},\"offset_hours\":${OFFSET_HOURS}}"
|
|
257
|
+
|
|
258
|
+
$FIRST || JOBS_JSON+=","
|
|
259
|
+
JOBS_JSON+="{\"target\":\"${TARGET_PRETTY}\",\"session_at\":\"${SCHED_PRETTY}\",\"loop_in_seconds\":${LOOP_SECS}}"
|
|
260
|
+
FIRST=false
|
|
261
|
+
done
|
|
262
|
+
|
|
263
|
+
JOBS_JSON+="]"
|
|
264
|
+
|
|
265
|
+
# Commit updated crontab
|
|
266
|
+
crontab "$tmp"
|
|
267
|
+
rm -f "$tmp"
|
|
268
|
+
|
|
269
|
+
# Summary for Claude's confirmation message
|
|
270
|
+
echo "SUMMARY: {\"count\":${#TIMES[@]},\"offset_hours\":${OFFSET_HOURS},\"soonest_session_in_seconds\":${SOONEST_SECS},\"soonest_target\":\"${SOONEST_TARGET}\",\"soonest_session\":\"${SOONEST_SESSION}\",\"log\":\"${LOG}\",\"jobs\":${JOBS_JSON}}"
|
package/hello.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Schedule one or more "Hello!" greetings at specific times. Sessions open N hours before each time (default 4h). Usage: /hello <time> [time2 ...] [--offset Nh]
|
|
3
|
+
argument-hint: [time ...] [--offset Nh] e.g. 1am / 9am 2pm / 14:00 --offset 2h
|
|
4
|
+
allowed-tools: Bash
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
The user wants to schedule hello sessions. Their arguments are: $ARGUMENTS
|
|
8
|
+
|
|
9
|
+
## Step 1 — Run the scheduler
|
|
10
|
+
|
|
11
|
+
Execute the scheduler script:
|
|
12
|
+
|
|
13
|
+
!`bash ~/.claude/scripts/hello-scheduler.sh $ARGUMENTS`
|
|
14
|
+
|
|
15
|
+
## Step 2 — Parse the output and report
|
|
16
|
+
|
|
17
|
+
Read the output from the script carefully. It will print one JSON block per scheduled time in the form:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
SCHEDULED: {"target":"<pretty time>","session_at":"<pretty time>","cron":"<cron expression>","loop_in_seconds":<number>}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
And a final summary line:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
SUMMARY: {"count":<n>,"offset_hours":<h>,"jobs":[...]}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
For each SCHEDULED entry, tell the user clearly:
|
|
30
|
+
- The **target time** they chose
|
|
31
|
+
- The **session opens at** time (offset hours before)
|
|
32
|
+
- The cron expression registered
|
|
33
|
+
|
|
34
|
+
## Step 3 — Use /loop for in-session countdown
|
|
35
|
+
|
|
36
|
+
After reporting all scheduled jobs, use the built-in `/loop` command to set a **single-fire reminder** for the soonest upcoming session time.
|
|
37
|
+
|
|
38
|
+
Calculate which session_at time is soonest (it will be in the output). Then issue:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
/loop <interval> Say: "⏰ Reminder: your Hello session is starting now! Originally scheduled for <target time>."
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Where `<interval>` is the number of seconds until the soonest session (use the `loop_in_seconds` value from SCHEDULED output).
|
|
45
|
+
|
|
46
|
+
This uses Claude Code's built-in `/loop` to give the user an in-session ping without needing an extra tool.
|
|
47
|
+
|
|
48
|
+
## Step 4 — Final message
|
|
49
|
+
|
|
50
|
+
Tell the user:
|
|
51
|
+
1. How many jobs were scheduled
|
|
52
|
+
2. The offset used (e.g. "4 hours before each target time")
|
|
53
|
+
3. That persistent cron jobs have been registered (survive terminal close)
|
|
54
|
+
4. That the `/loop` in-session reminder was set for the soonest session
|
|
55
|
+
5. How to list or remove jobs: `crontab -l` / `~/.claude/scripts/hello-scheduler.sh --list` / `--remove-all`
|
package/package.json
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "session-planner",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "Schedule Hello! Claude Code sessions at specific times. Opens a session N hours before your chosen time.",
|
|
5
|
-
"keywords": [
|
|
5
|
+
"keywords": [
|
|
6
|
+
"claude",
|
|
7
|
+
"claude-code",
|
|
8
|
+
"scheduler",
|
|
9
|
+
"cli",
|
|
10
|
+
"cron"
|
|
11
|
+
],
|
|
6
12
|
"author": "MahmoudMabrok",
|
|
7
13
|
"license": "MIT",
|
|
8
14
|
"homepage": "https://github.com/MahmoudMabrok/SessionPlanner",
|
|
@@ -23,11 +29,11 @@
|
|
|
23
29
|
"test": "bash tests/test-parse.sh"
|
|
24
30
|
},
|
|
25
31
|
"files": [
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
".
|
|
32
|
+
"hello-scheduler.sh",
|
|
33
|
+
"session-planner.js",
|
|
34
|
+
"hello.md",
|
|
35
|
+
"hello-list.md",
|
|
36
|
+
"hello-remove.md",
|
|
31
37
|
"README.md",
|
|
32
38
|
"LICENSE"
|
|
33
39
|
]
|