@codyswann/lisa 1.76.5 → 1.76.6

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/package.json CHANGED
@@ -74,7 +74,7 @@
74
74
  "flatted": "^3.4.2"
75
75
  },
76
76
  "name": "@codyswann/lisa",
77
- "version": "1.76.5",
77
+ "version": "1.76.6",
78
78
  "description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
79
79
  "main": "dist/index.js",
80
80
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "1.76.5",
3
+ "version": "1.76.6",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "1.76.5",
3
+ "version": "1.76.6",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "1.76.5",
3
+ "version": "1.76.6",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "1.76.5",
3
+ "version": "1.76.6",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "1.76.5",
3
+ "version": "1.76.6",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "1.76.5",
3
+ "version": "1.76.6",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -55,10 +55,12 @@ fi
55
55
  # Run ESLint with --fix --quiet --cache on the specific file
56
56
  # --quiet: suppress warnings, only show errors
57
57
  # --cache: use ESLint cache for performance
58
+ # --rule: disable no-unused-vars auto-fix to prevent removing imports that Claude
59
+ # plans to use in a subsequent edit (pre-commit hook still catches them)
58
60
  echo "Running ESLint --fix on: $FILE_PATH"
59
61
 
60
62
  # First pass: attempt auto-fix
61
- OUTPUT=$($PKG_MANAGER eslint --fix --quiet --cache "$FILE_PATH" 2>&1)
63
+ OUTPUT=$($PKG_MANAGER eslint --fix --quiet --cache --rule '@typescript-eslint/no-unused-vars: off' "$FILE_PATH" 2>&1)
62
64
  FIX_EXIT=$?
63
65
 
64
66
  if [ $FIX_EXIT -eq 0 ]; then
@@ -55,10 +55,12 @@ fi
55
55
  # Run ESLint with --fix --quiet --cache on the specific file
56
56
  # --quiet: suppress warnings, only show errors
57
57
  # --cache: use ESLint cache for performance
58
+ # --rule: disable no-unused-vars auto-fix to prevent removing imports that Claude
59
+ # plans to use in a subsequent edit (pre-commit hook still catches them)
58
60
  echo "Running ESLint --fix on: $FILE_PATH"
59
61
 
60
62
  # First pass: attempt auto-fix
61
- OUTPUT=$($PKG_MANAGER eslint --fix --quiet --cache "$FILE_PATH" 2>&1)
63
+ OUTPUT=$($PKG_MANAGER eslint --fix --quiet --cache --rule '@typescript-eslint/no-unused-vars: off' "$FILE_PATH" 2>&1)
62
64
  FIX_EXIT=$?
63
65
 
64
66
  if [ $FIX_EXIT -eq 0 ]; then
@@ -1,15 +0,0 @@
1
- #!/bin/bash
2
- # Reinjects plan-mode rules on every prompt when Claude is in plan mode.
3
- # Wired as a UserPromptSubmit hook in .claude/settings.json.
4
-
5
- INPUT=$(cat)
6
- PERMISSION_MODE=$(echo "$INPUT" | jq -r '.permission_mode // "default"')
7
-
8
- if [ "$PERMISSION_MODE" = "plan" ]; then
9
- PLAN_RULES="$CLAUDE_PROJECT_DIR/.claude/rules/plan.md"
10
- if [ -f "$PLAN_RULES" ]; then
11
- echo "PLAN MODE RULES (reinforced):"
12
- cat "$PLAN_RULES"
13
- fi
14
- fi
15
- exit 0
@@ -1,107 +0,0 @@
1
- #!/usr/bin/env bash
2
- #
3
- # sync-tasks.sh - Syncs Claude Code tasks to project directories
4
- #
5
- # This hook is triggered on PostToolUse for TaskCreate and TaskUpdate.
6
- # It reads the task metadata to determine the project and syncs
7
- # task JSON files to ./projects/{project}/tasks/{session-id}/
8
- #
9
- # This session-based structure preserves task history across /clear commands,
10
- # preventing overwrites when new sessions create tasks with the same IDs.
11
- #
12
- # Input (via stdin): JSON with tool_name, tool_input, tool_response
13
- #
14
-
15
- # Temporarily disable this hook
16
- exit 0
17
-
18
- set -euo pipefail
19
-
20
- # Read JSON input from stdin
21
- INPUT=$(cat)
22
-
23
- # Extract tool name
24
- TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // empty')
25
-
26
- # Only process TaskCreate and TaskUpdate
27
- if [[ "$TOOL_NAME" != "TaskCreate" && "$TOOL_NAME" != "TaskUpdate" ]]; then
28
- exit 0
29
- fi
30
-
31
- # Try to get project from multiple sources:
32
- # 1. Task metadata (passed in tool_input)
33
- # 2. .claude-active-project marker file
34
-
35
- PROJECT=""
36
-
37
- # Check tool_input metadata for project
38
- PROJECT=$(echo "$INPUT" | jq -r '.tool_input.metadata.project // empty')
39
-
40
- # If no project in metadata, check marker file
41
- if [[ -z "$PROJECT" && -f ".claude-active-project" ]]; then
42
- PROJECT=$(cat .claude-active-project | tr -d '[:space:]')
43
- fi
44
-
45
- # If still no project, skip syncing
46
- if [[ -z "$PROJECT" ]]; then
47
- exit 0
48
- fi
49
-
50
- # Validate project name (kebab-case, no path traversal)
51
- if [[ ! "$PROJECT" =~ ^[a-z0-9-]+$ ]]; then
52
- echo "Warning: Invalid project name '$PROJECT', skipping sync" >&2
53
- exit 0
54
- fi
55
-
56
- # Get task ID
57
- TASK_ID=""
58
- if [[ "$TOOL_NAME" == "TaskCreate" ]]; then
59
- # For TaskCreate, ID is in tool_response.task.id
60
- TASK_ID=$(echo "$INPUT" | jq -r '.tool_response.task.id // empty')
61
- elif [[ "$TOOL_NAME" == "TaskUpdate" ]]; then
62
- # For TaskUpdate, ID is in tool_input
63
- TASK_ID=$(echo "$INPUT" | jq -r '.tool_input.taskId // empty')
64
- fi
65
-
66
- if [[ -z "$TASK_ID" ]]; then
67
- exit 0
68
- fi
69
-
70
- # Find the task file in ~/.claude/tasks/
71
- # Tasks are stored in ~/.claude/tasks/{session-uuid}/{id}.json
72
- CLAUDE_TASKS_DIR="${HOME}/.claude/tasks"
73
- TASK_FILE=""
74
-
75
- # Get session ID from hook input (preferred - 100% accurate)
76
- SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // empty')
77
-
78
- if [[ -n "$SESSION_ID" && -f "${CLAUDE_TASKS_DIR}/${SESSION_ID}/${TASK_ID}.json" ]]; then
79
- # Use session ID directly - guaranteed correct session
80
- TASK_FILE="${CLAUDE_TASKS_DIR}/${SESSION_ID}/${TASK_ID}.json"
81
- else
82
- # Fallback: find most recently modified task file with this ID
83
- # This handles edge cases where session_id isn't available
84
- TASK_FILE=$(find "$CLAUDE_TASKS_DIR" -name "${TASK_ID}.json" -exec stat -f '%m %N' {} \; 2>/dev/null | sort -rn | head -1 | cut -d' ' -f2-)
85
- fi
86
-
87
- if [[ -z "$TASK_FILE" || ! -f "$TASK_FILE" ]]; then
88
- exit 0
89
- fi
90
-
91
- # Require session ID for proper history tracking
92
- if [[ -z "$SESSION_ID" ]]; then
93
- echo "Warning: No session_id available, skipping sync" >&2
94
- exit 0
95
- fi
96
-
97
- # Ensure project tasks directory exists (includes session ID for history preservation)
98
- PROJECT_TASKS_DIR="./projects/${PROJECT}/tasks/${SESSION_ID}"
99
- mkdir -p "$PROJECT_TASKS_DIR"
100
-
101
- # Copy task file to project directory
102
- cp "$TASK_FILE" "${PROJECT_TASKS_DIR}/${TASK_ID}.json"
103
-
104
- # Optionally stage the file for git (non-blocking)
105
- git add "${PROJECT_TASKS_DIR}/${TASK_ID}.json" 2>/dev/null || true
106
-
107
- exit 0
@@ -1,15 +0,0 @@
1
- #!/bin/bash
2
- # Reinjects plan-mode rules on every prompt when Claude is in plan mode.
3
- # Wired as a UserPromptSubmit hook in .claude/settings.json.
4
-
5
- INPUT=$(cat)
6
- PERMISSION_MODE=$(echo "$INPUT" | jq -r '.permission_mode // "default"')
7
-
8
- if [ "$PERMISSION_MODE" = "plan" ]; then
9
- PLAN_RULES="$CLAUDE_PROJECT_DIR/.claude/rules/plan.md"
10
- if [ -f "$PLAN_RULES" ]; then
11
- echo "PLAN MODE RULES (reinforced):"
12
- cat "$PLAN_RULES"
13
- fi
14
- fi
15
- exit 0
@@ -1,107 +0,0 @@
1
- #!/usr/bin/env bash
2
- #
3
- # sync-tasks.sh - Syncs Claude Code tasks to project directories
4
- #
5
- # This hook is triggered on PostToolUse for TaskCreate and TaskUpdate.
6
- # It reads the task metadata to determine the project and syncs
7
- # task JSON files to ./projects/{project}/tasks/{session-id}/
8
- #
9
- # This session-based structure preserves task history across /clear commands,
10
- # preventing overwrites when new sessions create tasks with the same IDs.
11
- #
12
- # Input (via stdin): JSON with tool_name, tool_input, tool_response
13
- #
14
-
15
- # Temporarily disable this hook
16
- exit 0
17
-
18
- set -euo pipefail
19
-
20
- # Read JSON input from stdin
21
- INPUT=$(cat)
22
-
23
- # Extract tool name
24
- TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // empty')
25
-
26
- # Only process TaskCreate and TaskUpdate
27
- if [[ "$TOOL_NAME" != "TaskCreate" && "$TOOL_NAME" != "TaskUpdate" ]]; then
28
- exit 0
29
- fi
30
-
31
- # Try to get project from multiple sources:
32
- # 1. Task metadata (passed in tool_input)
33
- # 2. .claude-active-project marker file
34
-
35
- PROJECT=""
36
-
37
- # Check tool_input metadata for project
38
- PROJECT=$(echo "$INPUT" | jq -r '.tool_input.metadata.project // empty')
39
-
40
- # If no project in metadata, check marker file
41
- if [[ -z "$PROJECT" && -f ".claude-active-project" ]]; then
42
- PROJECT=$(cat .claude-active-project | tr -d '[:space:]')
43
- fi
44
-
45
- # If still no project, skip syncing
46
- if [[ -z "$PROJECT" ]]; then
47
- exit 0
48
- fi
49
-
50
- # Validate project name (kebab-case, no path traversal)
51
- if [[ ! "$PROJECT" =~ ^[a-z0-9-]+$ ]]; then
52
- echo "Warning: Invalid project name '$PROJECT', skipping sync" >&2
53
- exit 0
54
- fi
55
-
56
- # Get task ID
57
- TASK_ID=""
58
- if [[ "$TOOL_NAME" == "TaskCreate" ]]; then
59
- # For TaskCreate, ID is in tool_response.task.id
60
- TASK_ID=$(echo "$INPUT" | jq -r '.tool_response.task.id // empty')
61
- elif [[ "$TOOL_NAME" == "TaskUpdate" ]]; then
62
- # For TaskUpdate, ID is in tool_input
63
- TASK_ID=$(echo "$INPUT" | jq -r '.tool_input.taskId // empty')
64
- fi
65
-
66
- if [[ -z "$TASK_ID" ]]; then
67
- exit 0
68
- fi
69
-
70
- # Find the task file in ~/.claude/tasks/
71
- # Tasks are stored in ~/.claude/tasks/{session-uuid}/{id}.json
72
- CLAUDE_TASKS_DIR="${HOME}/.claude/tasks"
73
- TASK_FILE=""
74
-
75
- # Get session ID from hook input (preferred - 100% accurate)
76
- SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // empty')
77
-
78
- if [[ -n "$SESSION_ID" && -f "${CLAUDE_TASKS_DIR}/${SESSION_ID}/${TASK_ID}.json" ]]; then
79
- # Use session ID directly - guaranteed correct session
80
- TASK_FILE="${CLAUDE_TASKS_DIR}/${SESSION_ID}/${TASK_ID}.json"
81
- else
82
- # Fallback: find most recently modified task file with this ID
83
- # This handles edge cases where session_id isn't available
84
- TASK_FILE=$(find "$CLAUDE_TASKS_DIR" -name "${TASK_ID}.json" -exec stat -f '%m %N' {} \; 2>/dev/null | sort -rn | head -1 | cut -d' ' -f2-)
85
- fi
86
-
87
- if [[ -z "$TASK_FILE" || ! -f "$TASK_FILE" ]]; then
88
- exit 0
89
- fi
90
-
91
- # Require session ID for proper history tracking
92
- if [[ -z "$SESSION_ID" ]]; then
93
- echo "Warning: No session_id available, skipping sync" >&2
94
- exit 0
95
- fi
96
-
97
- # Ensure project tasks directory exists (includes session ID for history preservation)
98
- PROJECT_TASKS_DIR="./projects/${PROJECT}/tasks/${SESSION_ID}"
99
- mkdir -p "$PROJECT_TASKS_DIR"
100
-
101
- # Copy task file to project directory
102
- cp "$TASK_FILE" "${PROJECT_TASKS_DIR}/${TASK_ID}.json"
103
-
104
- # Optionally stage the file for git (non-blocking)
105
- git add "${PROJECT_TASKS_DIR}/${TASK_ID}.json" 2>/dev/null || true
106
-
107
- exit 0