session-start-next.sh bash
102 lines 3.5 KB
Raw
sha256:c07f2f34a0db9f43fe866f157d1935322008545ff8940c06c7c921eb219c55ab NXP-b DONE: independent BV-r2 pass + ISR (SD-17) Human minor ⚠ breaking 22 hours ago
1 #!/bin/sh
2 # sessionStart / stop hook — print CURRENT NEXT from disk (§LT.4.5, fail-open).
3
4 find_ok() {
5 if [ -n "$OVERSEER_OK" ] && [ -x "$OVERSEER_OK" ]; then
6 printf '%s\n' "$OVERSEER_OK"
7 return 0
8 fi
9 if [ -x "./cli/ok" ]; then
10 printf '%s\n' "./cli/ok"
11 return 0
12 fi
13 if command -v ok >/dev/null 2>&1; then
14 printf '%s\n' "ok"
15 return 0
16 fi
17 return 1
18 }
19
20 OK=$(find_ok) || {
21 printf '%s\n' '{"additional_context":"ok CLI not found","followup_message":"ok CLI not found"}'
22 exit 0
23 }
24
25 CONFIG=".overseer/config.yaml"
26
27 # Enumerate docs.lanes keys. `ok next` resolves exactly one lane (docs.default_lane
28 # when --lane is omitted), so on a multi-lane repo a bare `ok next` presents one
29 # lane's NEXT as if it were the whole repo and silently misdirects every session
30 # whose work lives in another lane. Emit every lane instead and let the reader pick.
31 lane_names() {
32 [ -f "$CONFIG" ] || return 0
33 awk '
34 /^ lanes:[[:space:]]*$/ { in_lanes = 1; next }
35 in_lanes {
36 if ($0 ~ /^[[:space:]]*$/) { next }
37 indent = match($0, /[^ ]/) - 1
38 if (indent >= 4) {
39 if (indent == 4 && $0 ~ /:[[:space:]]*$/) {
40 name = substr($0, indent + 1)
41 sub(/:[[:space:]]*$/, "", name)
42 print name
43 }
44 next
45 }
46 in_lanes = 0
47 }
48 ' "$CONFIG" 2>/dev/null
49 }
50
51 LANES=$(lane_names)
52 # awk, not `grep -c`: grep prints 0 and exits 1 on no match, so a `|| echo 0`
53 # fallback would emit a second 0 and make the arithmetic test below fail.
54 LANE_COUNT=$(printf '%s\n' "$LANES" | awk 'NF { n++ } END { print n + 0 }')
55
56 if [ "$LANE_COUNT" -gt 1 ]; then
57 # Accumulate with the separator leading each block: command substitution strips
58 # trailing newlines, so a trailing separator would glue the fences together.
59 NEXT=""
60 for lane in $LANES; do
61 LANE_BODY=$("$OK" next --lane "$lane" 2>&1) || true
62 if [ -z "$NEXT" ]; then
63 NEXT=$(printf '**Lane: %s**\n\n%s' "$lane" "$LANE_BODY")
64 else
65 NEXT=$(printf '%s\n\n**Lane: %s**\n\n%s' "$NEXT" "$lane" "$LANE_BODY")
66 fi
67 done
68 LANE_LIST=$(printf '%s' "$LANES" | tr '\n' ' ' | sed 's/ $//')
69 NEXT=$(printf '%s\n\n**This repo has %s lanes (%s).** Every lane is shown because one lane is not the whole repo. Pick the lane your task belongs to — the default lane is not necessarily the active one.' "$NEXT" "$LANE_COUNT" "$LANE_LIST")
70 else
71 NEXT=$("$OK" next 2>&1) || true
72 fi
73
74 WORKSPACE='Open the repository root (the folder that contains `.overseer/`) as the IDE workspace. If you open a parent folder, project rules and skills under `.cursor/` often do not load. The CLI still works. The open editor tab is not the source of truth — run `ok next`.'
75
76 STALE='If an editor tab of the handover looks old, close it and reopen it. The kit cannot reload the tab. Trust `ok next`, not the tab. A NEXT block pasted from an earlier chat is not evidence — re-read it from disk before acting on it.'
77
78 export LT_HOOK_NEXT="$NEXT"
79 export LT_HOOK_WORKSPACE="$WORKSPACE"
80 export LT_HOOK_STALE="$STALE"
81
82 if command -v python3 >/dev/null 2>&1; then
83 python3 - <<'PY' || true
84 import json
85 import os
86
87 body = "\n\n".join(
88 part
89 for part in (
90 os.environ.get("LT_HOOK_NEXT", ""),
91 os.environ.get("LT_HOOK_WORKSPACE", ""),
92 os.environ.get("LT_HOOK_STALE", ""),
93 )
94 if part
95 )
96 print(json.dumps({"additional_context": body, "followup_message": body}))
97 PY
98 else
99 printf '%s\n' '{"additional_context":"ok next (python3 unavailable)","followup_message":"ok next (python3 unavailable)"}'
100 fi
101
102 exit 0
File History 1 commit
sha256:c07f2f34a0db9f43fe866f157d1935322008545ff8940c06c7c921eb219c55ab NXP-b DONE: independent BV-r2 pass + ISR (SD-17) Human minor 22 hours ago