@alexismunozdev/claude-session-topics 2.1.1 → 2.2.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/hooks/hooks.json CHANGED
@@ -9,7 +9,7 @@
9
9
  },
10
10
  {
11
11
  "type": "command",
12
- "command": "S=$(ls \"$HOME/.claude/plugins/cache/claude-session-topics/claude-session-topics\"/*/scripts/auto-setup.sh 2>/dev/null | tail -1); [ -n \"$S\" ] && bash \"$S\" || true"
12
+ "command": "bash \"${CLAUDE_PLUGIN_ROOT}/scripts/auto-setup.sh\" || true"
13
13
  }
14
14
  ]
15
15
  }
@@ -20,7 +20,7 @@
20
20
  "hooks": [
21
21
  {
22
22
  "type": "command",
23
- "command": "S=$(ls \"$HOME/.claude/plugins/cache/claude-session-topics/claude-session-topics\"/*/scripts/auto-allow.sh 2>/dev/null | tail -1); [ -n \"$S\" ] && bash \"$S\" || true"
23
+ "command": "bash \"${CLAUDE_PLUGIN_ROOT}/scripts/auto-allow.sh\" || true"
24
24
  }
25
25
  ]
26
26
  }
@@ -30,7 +30,7 @@
30
30
  "hooks": [
31
31
  {
32
32
  "type": "command",
33
- "command": "S=$(ls \"$HOME/.claude/plugins/cache/claude-session-topics/claude-session-topics\"/*/scripts/auto-topic-hook.sh 2>/dev/null | tail -1); [ -n \"$S\" ] && bash \"$S\" || true"
33
+ "command": "bash \"${CLAUDE_PLUGIN_ROOT}/scripts/auto-topic-hook.sh\" || true"
34
34
  }
35
35
  ]
36
36
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alexismunozdev/claude-session-topics",
3
- "version": "2.1.1",
3
+ "version": "2.2.0",
4
4
  "description": "Session topics for Claude Code — auto-set and display a topic in the statusline, change anytime with /set-topic",
5
5
  "bin": {
6
6
  "claude-session-topics": "bin/install.js"
@@ -0,0 +1,25 @@
1
+ #!/bin/bash
2
+ # Auto-approve Bash commands containing "session-topics" (PermissionRequest hook)
3
+ # Writes the allow rule to userSettings so future requests skip the prompt
4
+
5
+ input=$(cat)
6
+ CMD=$(echo "$input" | jq -r '.tool_input.command // ""')
7
+
8
+ if echo "$CMD" | grep -q 'session-topics'; then
9
+ cat <<'EOF'
10
+ {
11
+ "hookSpecificOutput": {
12
+ "hookEventName": "PermissionRequest",
13
+ "permissionDecision": "allow",
14
+ "updatedPermissions": [
15
+ {
16
+ "type": "addRules",
17
+ "rules": [{"toolName": "Bash", "ruleContent": "*session-topics*"}],
18
+ "behavior": "allow",
19
+ "destination": "userSettings"
20
+ }
21
+ ]
22
+ }
23
+ }
24
+ EOF
25
+ fi
@@ -0,0 +1,68 @@
1
+ #!/bin/bash
2
+ # Auto-configure statusline on first run (SessionStart hook)
3
+ # Handles two cases:
4
+ # 1. No statusline configured -> set plugin's statusline.sh directly
5
+ # 2. Existing custom statusline -> generate a wrapper that prepends topic to original output
6
+
7
+ SETTINGS="$HOME/.claude/settings.json"
8
+ TOPIC_DIR="$HOME/.claude/session-topics"
9
+ WRAPPER="$TOPIC_DIR/wrapper-statusline.sh"
10
+ STABLE_SL="$TOPIC_DIR/plugin-statusline.sh"
11
+ ORIG_CMD_FILE="$TOPIC_DIR/.original-statusline-cmd"
12
+
13
+ [ ! -f "$SETTINGS" ] && exit 0
14
+
15
+ # Find the plugin's statusline script via CLAUDE_PLUGIN_ROOT (set by hooks system)
16
+ PLUGIN_SL="${CLAUDE_PLUGIN_ROOT}/scripts/statusline.sh"
17
+ [ ! -f "$PLUGIN_SL" ] && exit 0
18
+
19
+ mkdir -p "$TOPIC_DIR"
20
+
21
+ # Always refresh the stable copy (keeps it up-to-date across plugin updates)
22
+ cp "$PLUGIN_SL" "$STABLE_SL"
23
+ chmod +x "$STABLE_SL"
24
+
25
+ CURRENT_CMD=$(jq -r '.statusLine.command // ""' "$SETTINGS" 2>/dev/null)
26
+
27
+ # Already integrated — skip (but the copy above still refreshes)
28
+ echo "$CURRENT_CMD" | grep -q 'session-topics' && exit 0
29
+
30
+ HAS_STATUSLINE=$(jq 'has("statusLine")' "$SETTINGS" 2>/dev/null)
31
+
32
+ if [ "$HAS_STATUSLINE" = "true" ] && [ -n "$CURRENT_CMD" ]; then
33
+ # Case 2: User has a custom statusline — generate wrapper
34
+ echo "$CURRENT_CMD" > "$ORIG_CMD_FILE"
35
+
36
+ cat > "$WRAPPER" << 'WRAPPER_EOF'
37
+ #!/bin/bash
38
+ input=$(cat)
39
+
40
+ # Run the plugin's topic statusline (stable copy refreshed each session)
41
+ TOPIC_OUTPUT=""
42
+ if [ -f "$HOME/.claude/session-topics/plugin-statusline.sh" ]; then
43
+ TOPIC_OUTPUT=$(echo "$input" | bash "$HOME/.claude/session-topics/plugin-statusline.sh" 2>/dev/null || echo "")
44
+ fi
45
+
46
+ # Run the user's original statusline command
47
+ ORIG_CMD=$(cat "$HOME/.claude/session-topics/.original-statusline-cmd" 2>/dev/null || echo "")
48
+ ORIG_OUTPUT=""
49
+ if [ -n "$ORIG_CMD" ]; then
50
+ ORIG_OUTPUT=$(echo "$input" | bash -c "$ORIG_CMD" 2>/dev/null || echo "")
51
+ fi
52
+
53
+ # Combine: topic | original
54
+ if [ -n "$TOPIC_OUTPUT" ] && [ -n "$ORIG_OUTPUT" ]; then
55
+ echo -e "${TOPIC_OUTPUT} | ${ORIG_OUTPUT}"
56
+ elif [ -n "$TOPIC_OUTPUT" ]; then
57
+ echo -e "${TOPIC_OUTPUT}"
58
+ elif [ -n "$ORIG_OUTPUT" ]; then
59
+ echo -e "${ORIG_OUTPUT}"
60
+ fi
61
+ WRAPPER_EOF
62
+ chmod +x "$WRAPPER"
63
+
64
+ jq --arg cmd "bash \"$WRAPPER\"" '.statusLine.command = $cmd' "$SETTINGS" > "${SETTINGS}.tmp" && mv "${SETTINGS}.tmp" "$SETTINGS"
65
+ else
66
+ # Case 1: No statusline at all — use stable copy directly
67
+ jq --arg cmd "bash \"$STABLE_SL\"" '.statusLine = {"type": "command", "command": $cmd}' "$SETTINGS" > "${SETTINGS}.tmp" && mv "${SETTINGS}.tmp" "$SETTINGS"
68
+ fi
@@ -28,7 +28,7 @@ if [ -z "$SESSION_ID" ]; then
28
28
  echo "Error: No active session found. The statusline must run at least once before setting a topic."
29
29
  exit 1
30
30
  fi
31
- TOPIC=$(printf '%s' "$ARGUMENTS" | tr -cd 'a-zA-Z0-9 .,:!?'"'"'-' | cut -c1-100)
31
+ TOPIC=$(printf '%s' "$ARGUMENTS" | sed "s/[^a-zA-Z0-9àáâãäåèéêëìíîïòóôõöùúûüýÿñçÀÁÂÃÄÅÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝÑÇ .,:!?'-]//g" | cut -c1-100)
32
32
  if [ -z "$TOPIC" ]; then
33
33
  echo "Error: Topic text is empty after sanitization."
34
34
  exit 1