specweave 1.0.174 → 1.0.175
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/CLAUDE.md +24 -24
- package/package.json +1 -1
- package/plugins/specweave/hooks/user-prompt-submit.sh +77 -21
package/CLAUDE.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!-- SW:META template="claude" version="1.0.
|
|
1
|
+
<!-- SW:META template="claude" version="1.0.174" sections="header,start,autodetect,metarule,rules,workflow,reflect,context,structure,taskformat,secrets,syncing,testing,tdd,api,limits,troubleshooting,lazyloading,principles,linking,mcp,auto,docs" -->
|
|
2
2
|
|
|
3
3
|
<!-- SW:SECTION:hook-priority version="1.0.171" -->
|
|
4
4
|
## ⛔ ABSOLUTE PRIORITY: Hook Instructions Are Mandatory
|
|
@@ -50,7 +50,7 @@ Hooks exist to enforce workflow discipline. If you ignore them:
|
|
|
50
50
|
**This is non-negotiable. No exceptions. No "just this once".**
|
|
51
51
|
<!-- SW:END:hook-priority -->
|
|
52
52
|
|
|
53
|
-
<!-- SW:SECTION:header version="1.0.
|
|
53
|
+
<!-- SW:SECTION:header version="1.0.174" -->
|
|
54
54
|
**Framework**: SpecWeave | **Truth**: `spec.md` + `tasks.md`
|
|
55
55
|
<!-- SW:END:header -->
|
|
56
56
|
|
|
@@ -108,7 +108,7 @@ plugins/specweave/
|
|
|
108
108
|
**Old "commands" are just skills with `disable-model-invocation: true`** - they only respond to explicit `/name` invocation, not keyword detection.
|
|
109
109
|
<!-- SW:END:claude-code-concepts -->
|
|
110
110
|
|
|
111
|
-
<!-- SW:SECTION:start version="1.0.
|
|
111
|
+
<!-- SW:SECTION:start version="1.0.174" -->
|
|
112
112
|
## Getting Started
|
|
113
113
|
|
|
114
114
|
**Initial increment**: `0001-project-setup` (auto-created by `specweave init`)
|
|
@@ -118,7 +118,7 @@ plugins/specweave/
|
|
|
118
118
|
2. **Customize**: Edit spec.md and use for setup tasks
|
|
119
119
|
<!-- SW:END:start -->
|
|
120
120
|
|
|
121
|
-
<!-- SW:SECTION:autodetect version="1.0.
|
|
121
|
+
<!-- SW:SECTION:autodetect version="1.0.174" -->
|
|
122
122
|
## Auto-Detection
|
|
123
123
|
|
|
124
124
|
SpecWeave auto-detects product descriptions and routes to `/sw:increment`:
|
|
@@ -128,7 +128,7 @@ SpecWeave auto-detects product descriptions and routes to `/sw:increment`:
|
|
|
128
128
|
**Opt-out phrases**: "Just brainstorm first" | "Don't plan yet" | "Quick discussion" | "Let's explore ideas"
|
|
129
129
|
<!-- SW:END:autodetect -->
|
|
130
130
|
|
|
131
|
-
<!-- SW:SECTION:metarule version="1.0.
|
|
131
|
+
<!-- SW:SECTION:metarule version="1.0.174" -->
|
|
132
132
|
## Meta-Rule: Think-Before-Act
|
|
133
133
|
|
|
134
134
|
**Satisfy dependencies BEFORE dependent operations.**
|
|
@@ -139,7 +139,7 @@ SpecWeave auto-detects product descriptions and routes to `/sw:increment`:
|
|
|
139
139
|
```
|
|
140
140
|
<!-- SW:END:metarule -->
|
|
141
141
|
|
|
142
|
-
<!-- SW:SECTION:rules version="1.0.
|
|
142
|
+
<!-- SW:SECTION:rules version="1.0.174" -->
|
|
143
143
|
## Rules
|
|
144
144
|
|
|
145
145
|
1. **Files** → `.specweave/increments/####-name/` (see Structure section for details)
|
|
@@ -150,7 +150,7 @@ SpecWeave auto-detects product descriptions and routes to `/sw:increment`:
|
|
|
150
150
|
6. **⛔ Marketplace refresh**: Use `specweave refresh-marketplace` CLI (not `scripts/refresh-marketplace.sh`)
|
|
151
151
|
<!-- SW:END:rules -->
|
|
152
152
|
|
|
153
|
-
<!-- SW:SECTION:workflow version="1.0.
|
|
153
|
+
<!-- SW:SECTION:workflow version="1.0.174" -->
|
|
154
154
|
## Workflow
|
|
155
155
|
|
|
156
156
|
`/sw:increment "X"` → `/sw:do` → `/sw:progress` → `/sw:done 0001`
|
|
@@ -170,7 +170,7 @@ SpecWeave auto-detects product descriptions and routes to `/sw:increment`:
|
|
|
170
170
|
**Natural language**: "Let's build X" → `/sw:increment` | "What's status?" → `/sw:progress` | "We're done" → `/sw:done` | "Ship while sleeping" → `/sw:auto`
|
|
171
171
|
<!-- SW:END:workflow -->
|
|
172
172
|
|
|
173
|
-
<!-- SW:SECTION:reflect version="1.0.
|
|
173
|
+
<!-- SW:SECTION:reflect version="1.0.174" -->
|
|
174
174
|
## Skill Memories
|
|
175
175
|
|
|
176
176
|
SpecWeave learns from corrections. Learnings saved here automatically. Edit or delete as needed.
|
|
@@ -183,7 +183,7 @@ SpecWeave learns from corrections. Learnings saved here automatically. Edit or d
|
|
|
183
183
|
<!-- Auto-captured by SpecWeave reflect. Edit or delete as needed. -->
|
|
184
184
|
<!-- Learnings are organized by skill name. User edits override SpecWeave defaults. -->
|
|
185
185
|
|
|
186
|
-
<!-- SW:SECTION:context version="1.0.
|
|
186
|
+
<!-- SW:SECTION:context version="1.0.174" -->
|
|
187
187
|
## Context
|
|
188
188
|
|
|
189
189
|
**Before implementing**: Check ADRs at `.specweave/docs/internal/architecture/adr/`
|
|
@@ -191,7 +191,7 @@ SpecWeave learns from corrections. Learnings saved here automatically. Edit or d
|
|
|
191
191
|
**Load context**: `/sw:context <topic>` loads relevant living docs into conversation
|
|
192
192
|
<!-- SW:END:context -->
|
|
193
193
|
|
|
194
|
-
<!-- SW:SECTION:structure version="1.0.
|
|
194
|
+
<!-- SW:SECTION:structure version="1.0.174" -->
|
|
195
195
|
## Structure
|
|
196
196
|
|
|
197
197
|
```
|
|
@@ -206,7 +206,7 @@ SpecWeave learns from corrections. Learnings saved here automatically. Edit or d
|
|
|
206
206
|
**Everything else → subfolders**: `reports/` | `logs/` | `scripts/` | `backups/`
|
|
207
207
|
<!-- SW:END:structure -->
|
|
208
208
|
|
|
209
|
-
<!-- SW:SECTION:taskformat version="1.0.
|
|
209
|
+
<!-- SW:SECTION:taskformat version="1.0.174" -->
|
|
210
210
|
## Task Format
|
|
211
211
|
|
|
212
212
|
```markdown
|
|
@@ -216,7 +216,7 @@ SpecWeave learns from corrections. Learnings saved here automatically. Edit or d
|
|
|
216
216
|
```
|
|
217
217
|
<!-- SW:END:taskformat -->
|
|
218
218
|
|
|
219
|
-
<!-- SW:SECTION:secrets version="1.0.
|
|
219
|
+
<!-- SW:SECTION:secrets version="1.0.174" -->
|
|
220
220
|
## Secrets Check
|
|
221
221
|
|
|
222
222
|
**BEFORE CLI tools**: Check existing config first!
|
|
@@ -230,7 +230,7 @@ gh auth status
|
|
|
230
230
|
**SECURITY**: NEVER use `grep TOKEN .env` without `-q` flag - it exposes credentials in terminal!
|
|
231
231
|
<!-- SW:END:secrets -->
|
|
232
232
|
|
|
233
|
-
<!-- SW:SECTION:syncing version="1.0.
|
|
233
|
+
<!-- SW:SECTION:syncing version="1.0.174" -->
|
|
234
234
|
## External Sync (GitHub/JIRA/ADO)
|
|
235
235
|
|
|
236
236
|
**Commands**: `/sw-github:sync {id}` (issues) | `/sw:sync-specs` (living docs only)
|
|
@@ -240,7 +240,7 @@ gh auth status
|
|
|
240
240
|
**Config**: Set `sync.github.enabled: true` + `canUpdateExternalItems: true` in config.json
|
|
241
241
|
<!-- SW:END:syncing -->
|
|
242
242
|
|
|
243
|
-
<!-- SW:SECTION:testing version="1.0.
|
|
243
|
+
<!-- SW:SECTION:testing version="1.0.174" -->
|
|
244
244
|
## Testing
|
|
245
245
|
|
|
246
246
|
BDD in tasks.md | Unit >80% | `.test.ts` (Vitest)
|
|
@@ -252,7 +252,7 @@ vi.mock('./module', () => ({ func: mockFn }));
|
|
|
252
252
|
```
|
|
253
253
|
<!-- SW:END:testing -->
|
|
254
254
|
|
|
255
|
-
<!-- SW:SECTION:tdd version="1.0.
|
|
255
|
+
<!-- SW:SECTION:tdd version="1.0.174" -->
|
|
256
256
|
## TDD Mode (Test-Driven Development)
|
|
257
257
|
|
|
258
258
|
**When `testing.defaultTestMode: "TDD"` is configured**, follow RED-GREEN-REFACTOR discipline:
|
|
@@ -313,7 +313,7 @@ When TDD is enabled, tasks include phase markers:
|
|
|
313
313
|
**Rule**: Complete dependencies BEFORE dependent tasks (RED before GREEN).
|
|
314
314
|
<!-- SW:END:tdd -->
|
|
315
315
|
|
|
316
|
-
<!-- SW:SECTION:api version="1.0.
|
|
316
|
+
<!-- SW:SECTION:api version="1.0.174" -->
|
|
317
317
|
## API Development (OpenAPI-First)
|
|
318
318
|
|
|
319
319
|
**For API projects only.** Commands: `/sw:api-docs --all` | `--openapi` | `--postman` | `--validate`
|
|
@@ -321,13 +321,13 @@ When TDD is enabled, tasks include phase markers:
|
|
|
321
321
|
Enable in config: `{"apiDocs":{"enabled":true,"openApiPath":"openapi.yaml"}}`
|
|
322
322
|
<!-- SW:END:api -->
|
|
323
323
|
|
|
324
|
-
<!-- SW:SECTION:limits version="1.0.
|
|
324
|
+
<!-- SW:SECTION:limits version="1.0.174" -->
|
|
325
325
|
## Limits
|
|
326
326
|
|
|
327
327
|
**Max 1500 lines/file** — extract before adding
|
|
328
328
|
<!-- SW:END:limits -->
|
|
329
329
|
|
|
330
|
-
<!-- SW:SECTION:troubleshooting version="1.0.
|
|
330
|
+
<!-- SW:SECTION:troubleshooting version="1.0.174" -->
|
|
331
331
|
## Troubleshooting
|
|
332
332
|
|
|
333
333
|
| Issue | Fix |
|
|
@@ -343,7 +343,7 @@ Enable in config: `{"apiDocs":{"enabled":true,"openApiPath":"openapi.yaml"}}`
|
|
|
343
343
|
| Marketplace shows 0 | Normal with auto-load; `/plugin list` shows actual |
|
|
344
344
|
<!-- SW:END:troubleshooting -->
|
|
345
345
|
|
|
346
|
-
<!-- SW:SECTION:lazyloading version="1.0.
|
|
346
|
+
<!-- SW:SECTION:lazyloading version="1.0.174" -->
|
|
347
347
|
## Plugin Auto-Loading
|
|
348
348
|
|
|
349
349
|
Plugins load automatically based on project type and keywords. Manual install if needed:
|
|
@@ -357,7 +357,7 @@ export SPECWEAVE_DISABLE_AUTO_LOAD=1 # Disable auto-load
|
|
|
357
357
|
**Token savings**: Core ~3-5K tokens vs all plugins ~60K+
|
|
358
358
|
<!-- SW:END:lazyloading -->
|
|
359
359
|
|
|
360
|
-
<!-- SW:SECTION:principles version="1.0.
|
|
360
|
+
<!-- SW:SECTION:principles version="1.0.174" -->
|
|
361
361
|
## Principles
|
|
362
362
|
|
|
363
363
|
1. **Spec-first**: `/sw:increment` before coding
|
|
@@ -366,7 +366,7 @@ export SPECWEAVE_DISABLE_AUTO_LOAD=1 # Disable auto-load
|
|
|
366
366
|
4. **Traceable**: All work → specs → ACs
|
|
367
367
|
<!-- SW:END:principles -->
|
|
368
368
|
|
|
369
|
-
<!-- SW:SECTION:linking version="1.0.
|
|
369
|
+
<!-- SW:SECTION:linking version="1.0.174" -->
|
|
370
370
|
## Bidirectional Linking
|
|
371
371
|
|
|
372
372
|
Tasks ↔ User Stories auto-linked via AC-IDs: `AC-US1-01` → `US-001`
|
|
@@ -374,7 +374,7 @@ Tasks ↔ User Stories auto-linked via AC-IDs: `AC-US1-01` → `US-001`
|
|
|
374
374
|
Task format: `**AC**: AC-US1-01, AC-US1-02` (CRITICAL for linking)
|
|
375
375
|
<!-- SW:END:linking -->
|
|
376
376
|
|
|
377
|
-
<!-- SW:SECTION:mcp version="1.0.
|
|
377
|
+
<!-- SW:SECTION:mcp version="1.0.174" -->
|
|
378
378
|
## External Services
|
|
379
379
|
|
|
380
380
|
**Priority**: CLI tools first (simpler) → MCP for complex integrations
|
|
@@ -396,7 +396,7 @@ claude mcp add --transport stdio postgres -- npx -y @modelcontextprotocol/server
|
|
|
396
396
|
MCP supports lazy-loading (auto mode) - tools load on-demand when >10% context.
|
|
397
397
|
<!-- SW:END:mcp -->
|
|
398
398
|
|
|
399
|
-
<!-- SW:SECTION:auto version="1.0.
|
|
399
|
+
<!-- SW:SECTION:auto version="1.0.174" -->
|
|
400
400
|
## Auto Mode
|
|
401
401
|
|
|
402
402
|
**Commands**: `/sw:auto` (start) | `/sw:auto-status` (check) | `/sw:cancel-auto` (emergency only)
|
|
@@ -413,7 +413,7 @@ MCP supports lazy-loading (auto mode) - tools load on-demand when >10% context.
|
|
|
413
413
|
**STOP & ASK** if: Spec conflicts | Task unnecessary | Requirement ambiguous
|
|
414
414
|
<!-- SW:END:auto -->
|
|
415
415
|
|
|
416
|
-
<!-- SW:SECTION:docs version="1.0.
|
|
416
|
+
<!-- SW:SECTION:docs version="1.0.174" -->
|
|
417
417
|
## Docs
|
|
418
418
|
|
|
419
419
|
[spec-weave.com](https://spec-weave.com)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "specweave",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.175",
|
|
4
4
|
"description": "Spec-driven development framework for Claude Code. AI-native workflow with living documentation, intelligent agents, and multilingual support (9 languages). Enterprise-grade traceability with permanent specs and temporary increments.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -1,20 +1,28 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
|
|
3
|
-
# SpecWeave UserPromptSubmit Hook (v1.0.
|
|
3
|
+
# SpecWeave UserPromptSubmit Hook (v1.0.175 - Reliable Plugin Detection)
|
|
4
4
|
# Fires BEFORE user's command executes (prompt-based hook)
|
|
5
5
|
# Purpose: Auto-load plugins, discipline validation, context injection, instant command execution
|
|
6
6
|
#
|
|
7
7
|
# FEATURES:
|
|
8
|
+
# - v1.0.175: CRITICAL FIX - Use installed_plugins.json as SOURCE OF TRUTH
|
|
9
|
+
# * Reads ~/.claude/plugins/installed_plugins.json directly (eliminates false restart warnings)
|
|
10
|
+
# * `claude plugin list` can have timing/buffering issues → unreliable for detection
|
|
11
|
+
# * Primary: check_plugin_installed_from_json() using jq (fast, accurate)
|
|
12
|
+
# * Fallback: `claude plugin list` only if jq unavailable
|
|
13
|
+
# * Post-install verification: re-checks registry after install to confirm success
|
|
14
|
+
# * Increased timeouts: 5s → 10s for CLI operations (reduces timing issues)
|
|
15
|
+
# * Guard against false positives: if install says "success" but not in registry → treat as already installed
|
|
8
16
|
# - v1.0.169: DIRECT SKILL INVOCATION - Call sw:increment-planner directly (not wrapper)
|
|
9
17
|
# * Skips 2-level indirection (hook → sw:increment command → sw:increment-planner skill)
|
|
10
18
|
# * Passes FULL user prompt as args (not just extracted name)
|
|
11
19
|
# * Uses <system><rules> tags (Claude-trained) instead of custom <mandatory_instruction>
|
|
12
20
|
# * More concise, imperative instruction text
|
|
13
|
-
# - v1.0.167: FIX PLUGIN RESTART WARNING - Use `claude plugin list` BEFORE install
|
|
21
|
+
# - v1.0.167: FIX PLUGIN RESTART WARNING - Use `claude plugin list` BEFORE install (DEPRECATED - had timing issues)
|
|
14
22
|
# * Claude CLI always outputs "Successfully installed" even when already installed
|
|
15
|
-
# *
|
|
16
|
-
# *
|
|
17
|
-
# *
|
|
23
|
+
# * Called `claude plugin list` once to get current plugins, then checked against that
|
|
24
|
+
# * Skipped install for already-installed plugins (faster + no false restart warnings)
|
|
25
|
+
# * ISSUE: `claude plugin list` output unreliable → false positives → fixed in v1.0.175
|
|
18
26
|
# - v1.0.147: SYNC PLUGIN INSTALL - Plugins available for CURRENT prompt!
|
|
19
27
|
# * Replaced 20s async LLM detection with ~200ms sync `claude plugin install`
|
|
20
28
|
# * Claude Code hot-reload picks up plugins immediately
|
|
@@ -138,6 +146,36 @@ output_approve_with_context() {
|
|
|
138
146
|
printf '{"hookSpecificOutput":{"hookEventName":"UserPromptSubmit","additionalContext":"%s"}}\n' "$escaped"
|
|
139
147
|
}
|
|
140
148
|
|
|
149
|
+
# Helper: Check if plugin is installed by reading installed_plugins.json (v1.0.175)
|
|
150
|
+
# This is the SOURCE OF TRUTH - more reliable than `claude plugin list` which can have timing issues.
|
|
151
|
+
# Args: $1=plugin name (e.g., "sw-frontend"), $2=marketplace (e.g., "specweave")
|
|
152
|
+
# Returns: 0 if installed, 1 if not installed
|
|
153
|
+
check_plugin_installed_from_json() {
|
|
154
|
+
local plugin="$1"
|
|
155
|
+
local marketplace="$2"
|
|
156
|
+
local registry_path="${HOME}/.claude/plugins/installed_plugins.json"
|
|
157
|
+
|
|
158
|
+
# File must exist
|
|
159
|
+
[[ ! -f "$registry_path" ]] && return 1
|
|
160
|
+
|
|
161
|
+
# Must have jq for reliable JSON parsing
|
|
162
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
163
|
+
return 1 # Fallback to CLI check if jq not available
|
|
164
|
+
fi
|
|
165
|
+
|
|
166
|
+
# Check if plugin exists in registry
|
|
167
|
+
# Format: {"plugins": {"sw-frontend@specweave": [...], ...}}
|
|
168
|
+
local full_name="${plugin}@${marketplace}"
|
|
169
|
+
local has_plugin
|
|
170
|
+
has_plugin=$(jq -r --arg key "$full_name" '.plugins[$key] // null' "$registry_path" 2>/dev/null)
|
|
171
|
+
|
|
172
|
+
if [[ "$has_plugin" != "null" ]] && [[ -n "$has_plugin" ]]; then
|
|
173
|
+
return 0 # Installed
|
|
174
|
+
else
|
|
175
|
+
return 1 # Not installed
|
|
176
|
+
fi
|
|
177
|
+
}
|
|
178
|
+
|
|
141
179
|
# ==============================================================================
|
|
142
180
|
# KEYWORD-BASED PLUGIN DETECTION REMOVED (v1.0.159)
|
|
143
181
|
# ==============================================================================
|
|
@@ -291,16 +329,6 @@ if [[ "${SPECWEAVE_DISABLE_AUTO_LOAD:-0}" != "1" ]] && [[ "${SPECWEAVE_DISABLE_H
|
|
|
291
329
|
PLUGINS_INSTALLED=""
|
|
292
330
|
PLUGINS_ALREADY=""
|
|
293
331
|
|
|
294
|
-
# v1.0.167: Get list of already-installed plugins ONCE via `claude plugin list`
|
|
295
|
-
# This is more reliable than parsing internal JSON files
|
|
296
|
-
# Format: "sw-frontend@specweave", "context7@claude-plugins-official", etc.
|
|
297
|
-
CURRENT_PLUGINS=""
|
|
298
|
-
if command -v timeout >/dev/null 2>&1; then
|
|
299
|
-
CURRENT_PLUGINS=$(timeout 5 claude plugin list 2>/dev/null | grep -E "^ ❯ " | sed 's/^ ❯ //' || true)
|
|
300
|
-
else
|
|
301
|
-
CURRENT_PLUGINS=$(claude plugin list 2>/dev/null | grep -E "^ ❯ " | sed 's/^ ❯ //' || true)
|
|
302
|
-
fi
|
|
303
|
-
|
|
304
332
|
for plugin in $DETECTED_PLUGINS; do
|
|
305
333
|
[[ -z "$plugin" ]] && continue
|
|
306
334
|
|
|
@@ -312,11 +340,28 @@ if [[ "${SPECWEAVE_DISABLE_AUTO_LOAD:-0}" != "1" ]] && [[ "${SPECWEAVE_DISABLE_H
|
|
|
312
340
|
MARKETPLACE="claude-plugins-official"
|
|
313
341
|
fi
|
|
314
342
|
|
|
315
|
-
# v1.0.
|
|
343
|
+
# v1.0.175: Check if plugin is ALREADY installed (SOURCE OF TRUTH)
|
|
344
|
+
# Primary: Check installed_plugins.json (reliable, fast, no timing issues)
|
|
345
|
+
# Fallback: Check `claude plugin list` if jq not available
|
|
316
346
|
FULL_PLUGIN_NAME="${plugin}@${MARKETPLACE}"
|
|
317
347
|
ALREADY_INSTALLED=false
|
|
318
|
-
|
|
348
|
+
|
|
349
|
+
# Try JSON registry first (most reliable)
|
|
350
|
+
if check_plugin_installed_from_json "$plugin" "$MARKETPLACE"; then
|
|
319
351
|
ALREADY_INSTALLED=true
|
|
352
|
+
else
|
|
353
|
+
# Fallback to CLI check (if jq not available or registry file missing)
|
|
354
|
+
# Give it a longer timeout (10s) to reduce timing issues
|
|
355
|
+
CURRENT_PLUGINS=""
|
|
356
|
+
if command -v timeout >/dev/null 2>&1; then
|
|
357
|
+
CURRENT_PLUGINS=$(timeout 10 claude plugin list 2>/dev/null | grep -E "^ ❯ " | sed 's/^ ❯ //' || true)
|
|
358
|
+
else
|
|
359
|
+
CURRENT_PLUGINS=$(claude plugin list 2>/dev/null | grep -E "^ ❯ " | sed 's/^ ❯ //' || true)
|
|
360
|
+
fi
|
|
361
|
+
|
|
362
|
+
if echo "$CURRENT_PLUGINS" | grep -q "^${FULL_PLUGIN_NAME}$"; then
|
|
363
|
+
ALREADY_INSTALLED=true
|
|
364
|
+
fi
|
|
320
365
|
fi
|
|
321
366
|
|
|
322
367
|
if [[ "$ALREADY_INSTALLED" == "true" ]]; then
|
|
@@ -325,15 +370,26 @@ if [[ "${SPECWEAVE_DISABLE_AUTO_LOAD:-0}" != "1" ]] && [[ "${SPECWEAVE_DISABLE_H
|
|
|
325
370
|
PLUGINS_ALREADY="${PLUGINS_ALREADY}${plugin}"
|
|
326
371
|
else
|
|
327
372
|
# Plugin not installed - install it
|
|
373
|
+
# Use longer timeout (10s) to ensure installation completes
|
|
328
374
|
if command -v timeout >/dev/null 2>&1; then
|
|
329
|
-
OUT=$(timeout
|
|
375
|
+
OUT=$(timeout 10 claude plugin install "${FULL_PLUGIN_NAME}" 2>&1) || true
|
|
330
376
|
else
|
|
331
377
|
OUT=$(claude plugin install "${FULL_PLUGIN_NAME}" 2>&1) || true
|
|
332
378
|
fi
|
|
333
379
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
380
|
+
# Only mark as installed if we see "success" or "installed" in output
|
|
381
|
+
if echo "$OUT" | grep -qiE "(success|installed)"; then
|
|
382
|
+
# Double-check: verify it actually got installed
|
|
383
|
+
# Re-check the registry to confirm (guard against false positives)
|
|
384
|
+
sleep 0.5 # Brief delay for registry to update
|
|
385
|
+
if check_plugin_installed_from_json "$plugin" "$MARKETPLACE"; then
|
|
386
|
+
[[ -n "$PLUGINS_INSTALLED" ]] && PLUGINS_INSTALLED="$PLUGINS_INSTALLED, "
|
|
387
|
+
PLUGINS_INSTALLED="${PLUGINS_INSTALLED}${plugin}"
|
|
388
|
+
else
|
|
389
|
+
# Install claimed success but plugin not in registry - treat as already installed
|
|
390
|
+
[[ -n "$PLUGINS_ALREADY" ]] && PLUGINS_ALREADY="$PLUGINS_ALREADY, "
|
|
391
|
+
PLUGINS_ALREADY="${PLUGINS_ALREADY}${plugin}"
|
|
392
|
+
fi
|
|
337
393
|
fi
|
|
338
394
|
fi
|
|
339
395
|
done
|