@codyswann/lisa 2.8.1 → 2.8.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.
@@ -10,37 +10,61 @@
10
10
  "plugins": [
11
11
  {
12
12
  "name": "lisa",
13
- "source": "./plugins/lisa",
13
+ "source": {
14
+ "source": "git-subdir",
15
+ "url": "https://github.com/CodySwannGT/lisa.git",
16
+ "path": "plugins/lisa"
17
+ },
14
18
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
15
19
  "category": "productivity"
16
20
  },
17
21
  {
18
22
  "name": "lisa-typescript",
19
- "source": "./plugins/lisa-typescript",
23
+ "source": {
24
+ "source": "git-subdir",
25
+ "url": "https://github.com/CodySwannGT/lisa.git",
26
+ "path": "plugins/lisa-typescript"
27
+ },
20
28
  "description": "TypeScript hooks — formatting, linting, and ast-grep scanning on edit",
21
29
  "category": "productivity"
22
30
  },
23
31
  {
24
32
  "name": "lisa-expo",
25
- "source": "./plugins/lisa-expo",
33
+ "source": {
34
+ "source": "git-subdir",
35
+ "url": "https://github.com/CodySwannGT/lisa.git",
36
+ "path": "plugins/lisa-expo"
37
+ },
26
38
  "description": "Expo/React Native skills, agents, and rules",
27
39
  "category": "productivity"
28
40
  },
29
41
  {
30
42
  "name": "lisa-nestjs",
31
- "source": "./plugins/lisa-nestjs",
43
+ "source": {
44
+ "source": "git-subdir",
45
+ "url": "https://github.com/CodySwannGT/lisa.git",
46
+ "path": "plugins/lisa-nestjs"
47
+ },
32
48
  "description": "NestJS skills (GraphQL, TypeORM)",
33
49
  "category": "productivity"
34
50
  },
35
51
  {
36
52
  "name": "lisa-cdk",
37
- "source": "./plugins/lisa-cdk",
53
+ "source": {
54
+ "source": "git-subdir",
55
+ "url": "https://github.com/CodySwannGT/lisa.git",
56
+ "path": "plugins/lisa-cdk"
57
+ },
38
58
  "description": "AWS CDK plugin",
39
59
  "category": "productivity"
40
60
  },
41
61
  {
42
62
  "name": "lisa-rails",
43
- "source": "./plugins/lisa-rails",
63
+ "source": {
64
+ "source": "git-subdir",
65
+ "url": "https://github.com/CodySwannGT/lisa.git",
66
+ "path": "plugins/lisa-rails"
67
+ },
44
68
  "description": "Ruby on Rails skills, rules, and conventions",
45
69
  "category": "productivity"
46
70
  }
package/package.json CHANGED
@@ -79,7 +79,7 @@
79
79
  "lodash": ">=4.18.1"
80
80
  },
81
81
  "name": "@codyswann/lisa",
82
- "version": "2.8.1",
82
+ "version": "2.8.3",
83
83
  "description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
84
84
  "main": "dist/index.js",
85
85
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.8.1",
3
+ "version": "2.8.3",
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": "2.8.1",
3
+ "version": "2.8.3",
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": "2.8.1",
3
+ "version": "2.8.3",
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": "2.8.1",
3
+ "version": "2.8.3",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.8.1",
3
+ "version": "2.8.3",
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": "2.8.1",
3
+ "version": "2.8.3",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -103,14 +103,115 @@ if ! command -v claude &>/dev/null; then exit 0; fi
103
103
  # pointing to the GitHub repo (CodySwannGT/lisa). Built plugins are committed to the repo
104
104
  # so relative paths in marketplace.json resolve correctly.
105
105
 
106
+ # Heal stale local registrations of the "lisa" marketplace.
107
+ # Earlier Lisa versions (pre-2.0) registered node_modules/@codyswann/lisa as a
108
+ # *local* marketplace named "lisa" via `claude marketplace add "$LISA_DIR"`.
109
+ # That registration persists in the host project's claude state across upgrades
110
+ # and shadows the github source declared in extraKnownMarketplaces, which makes
111
+ # Claude Code's plugin UI mark the lisa plugin as a local plugin and refuse the
112
+ # "Update now" action with: "Local plugins cannot be updated remotely."
113
+ # If we detect a non-github marketplace named "lisa", uninstall the plugins
114
+ # sourced from it and remove the registration so the github source can take over.
115
+ if command -v jq >/dev/null 2>&1; then
116
+ STALE_LISA_SOURCE=$(claude plugin marketplace list --json 2>/dev/null \
117
+ | jq -r '.[] | select(.name == "lisa" and .source != "github") | .source' 2>/dev/null \
118
+ | head -n 1)
119
+ if [ -n "${STALE_LISA_SOURCE:-}" ]; then
120
+ for stale_plugin in "lisa@lisa" "lisa-typescript@lisa" "lisa-expo@lisa" "lisa-nestjs@lisa" "lisa-cdk@lisa" "lisa-rails@lisa"; do
121
+ claude plugin uninstall "$stale_plugin" --scope project </dev/null >/dev/null 2>&1 || true
122
+ done
123
+ claude plugin marketplace remove lisa </dev/null >/dev/null 2>&1 || true
124
+ fi
125
+ fi
126
+
127
+ # Heal stale "local plugin" classification (heal-v2).
128
+ #
129
+ # Lisa marketplace v2.9+ switched plugin source declarations from bare
130
+ # relative-path strings (e.g. "source": "./plugins/lisa-expo") to object-form
131
+ # `git-subdir` sources. The relative-path form caused Claude Code's /plugin UI
132
+ # to classify each plugin as local — the UI showed "Local plugins cannot be
133
+ # updated remotely. To update, modify the source at: ./plugins/lisa-expo" and
134
+ # disabled the "Update now" action even though the marketplace itself was
135
+ # github-sourced.
136
+ #
137
+ # Plugins installed against the old marketplace.json schema retain that local
138
+ # classification until they're reinstalled. This block refreshes the cached
139
+ # marketplace.json, detects the new schema, and force-reinstalls already-
140
+ # installed lisa-* plugins so they get re-resolved as remote. Worktrees under
141
+ # .claude/worktrees/ have their own per-cwd plugin install state and are
142
+ # healed in the same pass. A marker file gates one-time execution per cwd.
143
+ LISA_PLUGINS=("lisa@lisa" "lisa-typescript@lisa" "lisa-expo@lisa" "lisa-nestjs@lisa" "lisa-cdk@lisa" "lisa-rails@lisa")
144
+ HEAL_V2_MARKER_NAME=".lisa-marketplace-heal-v2"
145
+
146
+ heal_local_classification() {
147
+ local cwd="$1"
148
+ local installed_for_cwd="$2"
149
+ local marker="$cwd/.claude/$HEAL_V2_MARKER_NAME"
150
+ [ -f "$marker" ] && return 0
151
+
152
+ # Important: do ALL uninstalls before ANY reinstall.
153
+ # Interleaved uninstall/install across sibling lisa-* plugins wipes other
154
+ # plugins' cache directories under ~/.claude/plugins/cache/lisa/, leaving
155
+ # later reinstalls with phantom installPaths and the /plugin UI hiding the
156
+ # base lisa plugin entirely. Batched ordering keeps all caches intact.
157
+ local to_heal=()
158
+ local plugin
159
+ for plugin in "${LISA_PLUGINS[@]}"; do
160
+ if printf '%s\n' "$installed_for_cwd" | grep -qx "$plugin"; then
161
+ to_heal+=("$plugin")
162
+ fi
163
+ done
164
+
165
+ if [ "${#to_heal[@]}" -gt 0 ]; then
166
+ (
167
+ cd "$cwd" || exit 0
168
+ for plugin in "${to_heal[@]}"; do
169
+ claude plugin uninstall "$plugin" --scope project </dev/null >/dev/null 2>&1 || true
170
+ done
171
+ for plugin in "${to_heal[@]}"; do
172
+ claude plugin install "$plugin" --scope project </dev/null >/dev/null 2>&1 || true
173
+ done
174
+ )
175
+ fi
176
+ mkdir -p "$cwd/.claude"
177
+ touch "$marker"
178
+ }
179
+
180
+ if command -v jq >/dev/null 2>&1; then
181
+ # Refresh the cached marketplace.json so we're reading the latest schema.
182
+ claude plugin marketplace update lisa </dev/null >/dev/null 2>&1 || true
183
+
184
+ MARKETPLACE_JSON_PATH="$HOME/.claude/plugins/marketplaces/lisa/.claude-plugin/marketplace.json"
185
+ NEW_SCHEMA="false"
186
+ if [ -f "$MARKETPLACE_JSON_PATH" ]; then
187
+ NEW_SCHEMA=$(jq -r '[.plugins[]? | select((.source | type) == "object")] | length > 0' "$MARKETPLACE_JSON_PATH" 2>/dev/null || echo "false")
188
+ fi
189
+
190
+ if [ "$NEW_SCHEMA" = "true" ]; then
191
+ PLUGIN_LIST_JSON=$(claude plugin list --json 2>/dev/null || echo "[]")
192
+
193
+ INSTALLED_FOR_PROJECT=$(printf '%s' "$PLUGIN_LIST_JSON" | jq -r --arg cwd "$PROJECT_ROOT" '.[] | select(.projectPath == $cwd) | .id' 2>/dev/null || true)
194
+ heal_local_classification "$PROJECT_ROOT" "$INSTALLED_FOR_PROJECT"
195
+
196
+ if [ -d "$PROJECT_ROOT/.claude/worktrees" ]; then
197
+ for worktree_dir in "$PROJECT_ROOT/.claude/worktrees"/*/; do
198
+ worktree_dir="${worktree_dir%/}"
199
+ [ -d "$worktree_dir" ] || continue
200
+ INSTALLED_FOR_WORKTREE=$(printf '%s' "$PLUGIN_LIST_JSON" | jq -r --arg cwd "$worktree_dir" '.[] | select(.projectPath == $cwd) | .id' 2>/dev/null || true)
201
+ heal_local_classification "$worktree_dir" "$INSTALLED_FOR_WORKTREE"
202
+ done
203
+ fi
204
+ fi
205
+ fi
206
+
106
207
  # Always install the base plugin (universal governance for all projects)
107
208
  claude plugin install "lisa@lisa" --scope project </dev/null 2>&1 || true
108
209
 
109
210
  # Detect which stack plugin to install from .claude/settings.json
110
211
  LISA_STACK=""
111
- if [ -f "$SETTINGS_FILE" ]; then
212
+ if [ -f "$SETTINGS_FILE" ] && command -v jq >/dev/null 2>&1; then
112
213
  for stack in expo nestjs cdk rails; do
113
- if grep -q "\"lisa-${stack}@lisa\"" "$SETTINGS_FILE" 2>/dev/null; then
214
+ if jq -e "(.enabledPlugins // {}) | has(\"lisa-${stack}@lisa\")" "$SETTINGS_FILE" >/dev/null 2>&1; then
114
215
  LISA_STACK="$stack"
115
216
  break
116
217
  fi