tim-hooks 0.1.0-beta.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/README.md +31 -0
- package/dist/cadence-runner.d.ts +11 -0
- package/dist/cadence-runner.d.ts.map +1 -0
- package/dist/cadence-runner.js +30 -0
- package/dist/cadence-runner.js.map +1 -0
- package/dist/cadence.d.ts +10 -0
- package/dist/cadence.d.ts.map +1 -0
- package/dist/cadence.js +36 -0
- package/dist/cadence.js.map +1 -0
- package/dist/checkpoint.d.ts +56 -0
- package/dist/checkpoint.d.ts.map +1 -0
- package/dist/checkpoint.js +232 -0
- package/dist/checkpoint.js.map +1 -0
- package/dist/claude-stop.d.ts +32 -0
- package/dist/claude-stop.d.ts.map +1 -0
- package/dist/claude-stop.js +213 -0
- package/dist/claude-stop.js.map +1 -0
- package/dist/constants.d.ts +5 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +8 -0
- package/dist/constants.js.map +1 -0
- package/dist/delta.d.ts +7 -0
- package/dist/delta.d.ts.map +1 -0
- package/dist/delta.js +53 -0
- package/dist/delta.js.map +1 -0
- package/dist/hooks.d.ts +39 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +136 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +88 -0
- package/dist/index.js.map +1 -0
- package/dist/marker.d.ts +179 -0
- package/dist/marker.d.ts.map +1 -0
- package/dist/marker.js +590 -0
- package/dist/marker.js.map +1 -0
- package/dist/phantom-recovery.d.ts +13 -0
- package/dist/phantom-recovery.d.ts.map +1 -0
- package/dist/phantom-recovery.js +113 -0
- package/dist/phantom-recovery.js.map +1 -0
- package/dist/project-creation.d.ts +48 -0
- package/dist/project-creation.d.ts.map +1 -0
- package/dist/project-creation.js +265 -0
- package/dist/project-creation.js.map +1 -0
- package/dist/prompt-submit.d.ts +16 -0
- package/dist/prompt-submit.d.ts.map +1 -0
- package/dist/prompt-submit.js +69 -0
- package/dist/prompt-submit.js.map +1 -0
- package/dist/rebalance.d.ts +17 -0
- package/dist/rebalance.d.ts.map +1 -0
- package/dist/rebalance.js +91 -0
- package/dist/rebalance.js.map +1 -0
- package/dist/session-hooks.d.ts +53 -0
- package/dist/session-hooks.d.ts.map +1 -0
- package/dist/session-hooks.js +167 -0
- package/dist/session-hooks.js.map +1 -0
- package/dist/update-check.d.ts +5 -0
- package/dist/update-check.d.ts.map +1 -0
- package/dist/update-check.js +66 -0
- package/dist/update-check.js.map +1 -0
- package/package.json +24 -0
- package/scripts/README-hermes-statusline.md +47 -0
- package/scripts/hermes-cli-tim-statusline.patch +75 -0
- package/scripts/lib/resolve-tim-cli.sh +30 -0
- package/scripts/post-commit.sh +30 -0
- package/scripts/tim-claude-session-start.sh +26 -0
- package/scripts/tim-cursor-inject.sh +17 -0
- package/scripts/tim-hermes-session-cache.sh +32 -0
- package/scripts/tim-hermes-statusline.sh +28 -0
- package/scripts/tim-post-commit.sh +14 -0
- package/scripts/tim-session-start.sh +104 -0
- package/scripts/tim-statusline.sh +16 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# tim-claude-session-start.sh — Claude Code SessionStart hook (TIM project auto-load).
|
|
3
|
+
# Reads cwd from the SessionStart payload, resolves nearest .tim-project (walk-up),
|
|
4
|
+
# emits additionalContext directive. Requires: jq, node. Override path with TIM_CLI.
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
SCRIPT_PATH="${BASH_SOURCE[0]}"
|
|
8
|
+
while [[ -L "$SCRIPT_PATH" ]]; do
|
|
9
|
+
SCRIPT_LINK_DIR="$(cd -P "$(dirname "$SCRIPT_PATH")" && pwd)"
|
|
10
|
+
SCRIPT_PATH="$(readlink "$SCRIPT_PATH")"
|
|
11
|
+
[[ "$SCRIPT_PATH" == /* ]] || SCRIPT_PATH="$SCRIPT_LINK_DIR/$SCRIPT_PATH"
|
|
12
|
+
done
|
|
13
|
+
SCRIPT_DIR="$(cd -P "$(dirname "$SCRIPT_PATH")" && pwd)"
|
|
14
|
+
unset SCRIPT_PATH SCRIPT_LINK_DIR
|
|
15
|
+
# shellcheck source=lib/resolve-tim-cli.sh
|
|
16
|
+
source "$SCRIPT_DIR/lib/resolve-tim-cli.sh"
|
|
17
|
+
|
|
18
|
+
payload="$(cat -)"
|
|
19
|
+
cwd=$(printf '%s' "$payload" | jq -r '.cwd // empty')
|
|
20
|
+
[[ -z "$cwd" ]] && exit 0
|
|
21
|
+
|
|
22
|
+
directive=$(run_tim_cli resolve-project --cwd "$cwd" --format directive 2>/dev/null || true)
|
|
23
|
+
[[ -z "$directive" ]] && exit 0
|
|
24
|
+
|
|
25
|
+
jq -n --arg ctx "$directive" \
|
|
26
|
+
'{hookSpecificOutput: {hookEventName: "SessionStart", additionalContext: $ctx}}'
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# tim-cursor-inject.sh — print the TIM load directive for a workspace, for the
|
|
3
|
+
# orchestrator to prepend to Cursor's first prompt (Cursor has no SessionStart hook).
|
|
4
|
+
# Usage: tim-cursor-inject.sh <project-dir>
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
SCRIPT_PATH="${BASH_SOURCE[0]}"
|
|
7
|
+
while [[ -L "$SCRIPT_PATH" ]]; do
|
|
8
|
+
SCRIPT_LINK_DIR="$(cd -P "$(dirname "$SCRIPT_PATH")" && pwd)"
|
|
9
|
+
SCRIPT_PATH="$(readlink "$SCRIPT_PATH")"
|
|
10
|
+
[[ "$SCRIPT_PATH" == /* ]] || SCRIPT_PATH="$SCRIPT_LINK_DIR/$SCRIPT_PATH"
|
|
11
|
+
done
|
|
12
|
+
SCRIPT_DIR="$(cd -P "$(dirname "$SCRIPT_PATH")" && pwd)"
|
|
13
|
+
unset SCRIPT_PATH SCRIPT_LINK_DIR
|
|
14
|
+
# shellcheck source=lib/resolve-tim-cli.sh
|
|
15
|
+
source "$SCRIPT_DIR/lib/resolve-tim-cli.sh"
|
|
16
|
+
cwd="${1:-$PWD}"
|
|
17
|
+
run_tim_cli resolve-project --cwd "$cwd" --format directive 2>/dev/null || true
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# tim-hermes-session-cache.sh — Hermes pre_llm_call: cache session_id + cwd for status bar
|
|
3
|
+
# Output: {} (no prompt injection). Register before tim-hermes-statusline refresh.
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
SCRIPT_PATH="${BASH_SOURCE[0]}"
|
|
7
|
+
while [[ -L "$SCRIPT_PATH" ]]; do
|
|
8
|
+
SCRIPT_LINK_DIR="$(cd -P "$(dirname "$SCRIPT_PATH")" && pwd)"
|
|
9
|
+
SCRIPT_PATH="$(readlink "$SCRIPT_PATH")"
|
|
10
|
+
[[ "$SCRIPT_PATH" == /* ]] || SCRIPT_PATH="$SCRIPT_LINK_DIR/$SCRIPT_PATH"
|
|
11
|
+
done
|
|
12
|
+
SCRIPT_DIR="$(cd -P "$(dirname "$SCRIPT_PATH")" && pwd)"
|
|
13
|
+
unset SCRIPT_PATH SCRIPT_LINK_DIR
|
|
14
|
+
# shellcheck source=lib/resolve-tim-cli.sh
|
|
15
|
+
source "$SCRIPT_DIR/lib/resolve-tim-cli.sh"
|
|
16
|
+
|
|
17
|
+
payload="$(cat)"
|
|
18
|
+
session_id=$(printf '%s' "$payload" | jq -r '.session_id // empty')
|
|
19
|
+
cwd=$(printf '%s' "$payload" | jq -r '.cwd // empty')
|
|
20
|
+
|
|
21
|
+
[[ -z "$session_id" && -z "$cwd" ]] && { printf '{}\n'; exit 0; }
|
|
22
|
+
|
|
23
|
+
cache_dir="${TIM_CACHE_DIR:-$HOME/.tim}"
|
|
24
|
+
mkdir -p "$cache_dir"
|
|
25
|
+
jq -n \
|
|
26
|
+
--arg sid "$session_id" \
|
|
27
|
+
--arg cwd "${cwd:-$HOME}" \
|
|
28
|
+
'{session_id: $sid, cwd: $cwd, ts: (now | todate)}' \
|
|
29
|
+
> "${cache_dir}/.session-cache"
|
|
30
|
+
|
|
31
|
+
printf '{}\n'
|
|
32
|
+
exit 0
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# tim-hermes-statusline.sh — Hermes TUI status bar (JSON stdout for hermes-cli patch)
|
|
3
|
+
# Project from nearest .tim-project walk-up only (tim statusline / resolve-project). No session cache.
|
|
4
|
+
# Install: symlink to ~/.hermes/agent-hooks/ + apply hermes-cli-tim-statusline.patch
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
SCRIPT_PATH="${BASH_SOURCE[0]}"
|
|
8
|
+
while [[ -L "$SCRIPT_PATH" ]]; do
|
|
9
|
+
SCRIPT_LINK_DIR="$(cd -P "$(dirname "$SCRIPT_PATH")" && pwd)"
|
|
10
|
+
SCRIPT_PATH="$(readlink "$SCRIPT_PATH")"
|
|
11
|
+
[[ "$SCRIPT_PATH" == /* ]] || SCRIPT_PATH="$SCRIPT_LINK_DIR/$SCRIPT_PATH"
|
|
12
|
+
done
|
|
13
|
+
SCRIPT_DIR="$(cd -P "$(dirname "$SCRIPT_PATH")" && pwd)"
|
|
14
|
+
unset SCRIPT_PATH SCRIPT_LINK_DIR
|
|
15
|
+
# shellcheck source=lib/resolve-tim-cli.sh
|
|
16
|
+
source "$SCRIPT_DIR/lib/resolve-tim-cli.sh"
|
|
17
|
+
|
|
18
|
+
# CWD: explicit env, else PWD (Hermes hook cwd is not piped here)
|
|
19
|
+
CWD="${TIM_STATUSLINE_CWD:-${PWD:-$HOME}}"
|
|
20
|
+
[[ -z "$CWD" ]] && CWD="${HOME}"
|
|
21
|
+
|
|
22
|
+
out=$(run_tim_cli statusline --format hermes --cwd "$CWD" 2>/dev/null || true)
|
|
23
|
+
if [[ -z "$out" ]]; then
|
|
24
|
+
echo '{}'
|
|
25
|
+
else
|
|
26
|
+
echo "$out"
|
|
27
|
+
fi
|
|
28
|
+
exit 0
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Back-compat wrapper — delegates to post-commit.sh
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
SCRIPT_PATH="${BASH_SOURCE[0]}"
|
|
5
|
+
while [[ -L "$SCRIPT_PATH" ]]; do
|
|
6
|
+
SCRIPT_LINK_DIR="$(cd -P "$(dirname "$SCRIPT_PATH")" && pwd)"
|
|
7
|
+
SCRIPT_PATH="$(readlink "$SCRIPT_PATH")"
|
|
8
|
+
[[ "$SCRIPT_PATH" == /* ]] || SCRIPT_PATH="$SCRIPT_LINK_DIR/$SCRIPT_PATH"
|
|
9
|
+
done
|
|
10
|
+
SCRIPT_DIR="$(cd -P "$(dirname "$SCRIPT_PATH")" && pwd)"
|
|
11
|
+
unset SCRIPT_PATH SCRIPT_LINK_DIR
|
|
12
|
+
# shellcheck source=lib/resolve-tim-cli.sh
|
|
13
|
+
source "$SCRIPT_DIR/lib/resolve-tim-cli.sh"
|
|
14
|
+
exec "$TIM_HOOKS_SCRIPTS_DIR/post-commit.sh" "$@"
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# tim-session-start.sh — Generic TIM auto-load hook for CLI coding agents.
|
|
3
|
+
#
|
|
4
|
+
# Supports: Claude Code, Cursor CLI, Codex CLI, OpenCode (via plugin wrapper).
|
|
5
|
+
#
|
|
6
|
+
# Reads a harness-specific session-start payload from stdin, resolves the nearest
|
|
7
|
+
# .tim-project marker (walk-up from cwd), and emits the buildLoadDirective text
|
|
8
|
+
# wrapped in the JSON envelope expected by the calling harness.
|
|
9
|
+
#
|
|
10
|
+
# Requires: bash, jq, node (for tim CLI). Override TIM_CLI path via env var.
|
|
11
|
+
#
|
|
12
|
+
# Output formats (auto-detected from stdin payload shape):
|
|
13
|
+
# Claude Code → {hookSpecificOutput: {hookEventName: "SessionStart", additionalContext: "…"}}
|
|
14
|
+
# Cursor CLI → {additional_context: "…"}
|
|
15
|
+
# Hermes/Codex → {context: "…"} (JSON — plain text broke Hermes session binding, PITFALLS-45)
|
|
16
|
+
# Fallback → {additional_context: "…"} (Cursor-safe, also works as plain text)
|
|
17
|
+
|
|
18
|
+
set -euo pipefail
|
|
19
|
+
|
|
20
|
+
SCRIPT_PATH="${BASH_SOURCE[0]}"
|
|
21
|
+
while [[ -L "$SCRIPT_PATH" ]]; do
|
|
22
|
+
SCRIPT_LINK_DIR="$(cd -P "$(dirname "$SCRIPT_PATH")" && pwd)"
|
|
23
|
+
SCRIPT_PATH="$(readlink "$SCRIPT_PATH")"
|
|
24
|
+
[[ "$SCRIPT_PATH" == /* ]] || SCRIPT_PATH="$SCRIPT_LINK_DIR/$SCRIPT_PATH"
|
|
25
|
+
done
|
|
26
|
+
SCRIPT_DIR="$(cd -P "$(dirname "$SCRIPT_PATH")" && pwd)"
|
|
27
|
+
unset SCRIPT_PATH SCRIPT_LINK_DIR
|
|
28
|
+
# shellcheck source=lib/resolve-tim-cli.sh
|
|
29
|
+
source "$SCRIPT_DIR/lib/resolve-tim-cli.sh"
|
|
30
|
+
TIM_HOOKS_MARKER="${TIM_MARKER_MODULE:-${SCRIPT_DIR}/../dist/marker.js}"
|
|
31
|
+
|
|
32
|
+
# Read stdin once (some harnesses pass payload, some pass nothing)
|
|
33
|
+
payload="$(cat -)"
|
|
34
|
+
|
|
35
|
+
# --- Determine cwd ---
|
|
36
|
+
cwd=""
|
|
37
|
+
|
|
38
|
+
# Strategy 1: Extract from payload (Claude Code, Codex, Hermes send .cwd)
|
|
39
|
+
if [[ -n "$payload" ]]; then
|
|
40
|
+
cwd=$(printf '%s' "$payload" | jq -r '.cwd // empty' 2>/dev/null || true)
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
# Strategy 2: Extract workspace path (some Cursor versions)
|
|
44
|
+
if [[ -z "$cwd" && -n "$payload" ]]; then
|
|
45
|
+
cwd=$(printf '%s' "$payload" | jq -r '.workspace // empty' 2>/dev/null || true)
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
# Strategy 3: Fall back to current working directory
|
|
49
|
+
if [[ -z "$cwd" ]]; then
|
|
50
|
+
cwd=$(pwd)
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
# Extract session_id from payload (for marker rotation, Fix F)
|
|
54
|
+
hook_session=$(printf '%s' "$payload" | jq -r '.session_id // empty' 2>/dev/null || true)
|
|
55
|
+
|
|
56
|
+
# --- Resolve project marker ---
|
|
57
|
+
directive=$(run_tim_cli resolve-project --walk-up --cwd "$cwd" --format directive 2>/dev/null || true)
|
|
58
|
+
if [[ -z "$directive" ]]; then
|
|
59
|
+
# No .tim-project marker found — silent skip (exit 0)
|
|
60
|
+
exit 0
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
# ── Session rotation: update .tim-project with current session ──
|
|
64
|
+
# Prevents stale cron session IDs from persisting in the marker (PITFALLS-46).
|
|
65
|
+
# cwd/session are passed via env, never interpolated into the JS source —
|
|
66
|
+
# paths or session ids containing quotes/backslashes must not break rotation.
|
|
67
|
+
if [[ -n "$hook_session" && -f "$TIM_HOOKS_MARKER" ]]; then
|
|
68
|
+
TIM_HOOK_CWD="$cwd" TIM_HOOK_SESSION="$hook_session" TIM_MARKER_MODULE="$TIM_HOOKS_MARKER" \
|
|
69
|
+
node --input-type=module -e "
|
|
70
|
+
const { pathToFileURL } = await import('node:url');
|
|
71
|
+
const m = await import(pathToFileURL(process.env.TIM_MARKER_MODULE).href);
|
|
72
|
+
m.rotateMarkerSession(process.env.TIM_HOOK_CWD, process.env.TIM_HOOK_SESSION);
|
|
73
|
+
" 2>/dev/null || true
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
# --- Detect harness and format output ---
|
|
77
|
+
|
|
78
|
+
# Claude Code sends hook_event_name in hook input. Keep accepting the older
|
|
79
|
+
# hookSpecificOutput-shaped payload used by existing integrations/tests.
|
|
80
|
+
if printf '%s' "$payload" | jq -e \
|
|
81
|
+
'(.hook_event_name == "SessionStart") or (.hookSpecificOutput // false)' >/dev/null 2>&1; then
|
|
82
|
+
# Claude Code format
|
|
83
|
+
exec jq -n --arg ctx "$directive" \
|
|
84
|
+
'{hookSpecificOutput: {hookEventName: "SessionStart", additionalContext: $ctx}}'
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
# Cursor sends payload with .conversation_id or .additional_context
|
|
88
|
+
if printf '%s' "$payload" | jq -e '(.conversation_id // empty) or (.additional_context // empty)' >/dev/null 2>&1; then
|
|
89
|
+
# Cursor format
|
|
90
|
+
exec jq -n --arg ctx "$directive" \
|
|
91
|
+
'{additional_context: $ctx}'
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
# Hermes / Codex — payload has .session_id but NOT .hookSpecificOutput or .conversation_id
|
|
95
|
+
if printf '%s' "$payload" | jq -e '.session_id // empty' >/dev/null 2>&1; then
|
|
96
|
+
# Hermes expects JSON context (PITFALLS-45: plain-text broke session binding)
|
|
97
|
+
exec jq -n --arg ctx "$directive" \
|
|
98
|
+
'{context: $ctx}'
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
# Fallback: no recognizable payload (empty stdin) — emit Cursor-safe JSON
|
|
102
|
+
# This covers: Cursor without payload, manual testing, unknown harnesses
|
|
103
|
+
exec jq -n --arg ctx "$directive" \
|
|
104
|
+
'{additional_context: $ctx}'
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# tim-statusline.sh — debug helper: one-line TIM status (stdin JSON optional, like Claude Code)
|
|
3
|
+
# Hermes TUI bar: use tim-hermes-statusline.sh + hermes-cli-tim-statusline.patch instead.
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
SCRIPT_PATH="${BASH_SOURCE[0]}"
|
|
7
|
+
while [[ -L "$SCRIPT_PATH" ]]; do
|
|
8
|
+
SCRIPT_LINK_DIR="$(cd -P "$(dirname "$SCRIPT_PATH")" && pwd)"
|
|
9
|
+
SCRIPT_PATH="$(readlink "$SCRIPT_PATH")"
|
|
10
|
+
[[ "$SCRIPT_PATH" == /* ]] || SCRIPT_PATH="$SCRIPT_LINK_DIR/$SCRIPT_PATH"
|
|
11
|
+
done
|
|
12
|
+
SCRIPT_DIR="$(cd -P "$(dirname "$SCRIPT_PATH")" && pwd)"
|
|
13
|
+
unset SCRIPT_PATH SCRIPT_LINK_DIR
|
|
14
|
+
# shellcheck source=lib/resolve-tim-cli.sh
|
|
15
|
+
source "$SCRIPT_DIR/lib/resolve-tim-cli.sh"
|
|
16
|
+
run_tim_cli statusline 2>/dev/null || true
|