@pushrec/skills 0.3.2 → 0.3.4
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 +21 -10
- package/bundled-skills/pushrec-skills/SKILL.md +23 -2
- package/bundled-skills/pushrec-skills/hooks/session_start.py +105 -0
- package/bundled-skills/pushrec-skills/references/prerequisites.yaml +43 -6
- package/bundled-skills/pushrec-skills/scripts/diagnostic.py +31 -2
- package/dist/index.js +2265 -254
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
CLI for the pushREC Agent Skills Marketplace. Install, manage, and update Claude Code skills.
|
|
4
4
|
|
|
5
|
-
**
|
|
5
|
+
**Local repo version target:** `0.3.4`
|
|
6
|
+
|
|
7
|
+
**Do not assume npm latest from this file.** Verify before customer-facing instructions:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm view @pushrec/skills version
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
As of 2026-02-27: npm `latest` = `0.2.0`, `next` = `0.3.2`. Local tree at `0.3.4` (Windows readiness). 19 test files, 139 tests passing.
|
|
6
14
|
|
|
7
15
|
## Quick Start
|
|
8
16
|
|
|
@@ -30,19 +38,22 @@ pushrec-skills auth login
|
|
|
30
38
|
|
|
31
39
|
| Command | Description |
|
|
32
40
|
|---------|-------------|
|
|
33
|
-
| `pushrec-skills
|
|
34
|
-
| `pushrec-skills
|
|
35
|
-
| `pushrec-skills
|
|
36
|
-
| `pushrec-skills
|
|
37
|
-
| `pushrec-skills search <query>` | Search
|
|
38
|
-
| `pushrec-skills info <name>` |
|
|
39
|
-
| `pushrec-skills uninstall <name>` |
|
|
41
|
+
| `pushrec-skills install [name]` | Install a skill (or `--all` for all available) |
|
|
42
|
+
| `pushrec-skills update [name]` | Update installed skills to latest versions |
|
|
43
|
+
| `pushrec-skills sync [name]` | Synchronize local skills with the registry (install missing + update installed) |
|
|
44
|
+
| `pushrec-skills list` | List available or installed skills |
|
|
45
|
+
| `pushrec-skills search <query>` | Search skills by keyword |
|
|
46
|
+
| `pushrec-skills info <name>` | Show detailed information about a skill |
|
|
47
|
+
| `pushrec-skills uninstall <name>` | Uninstall a skill from the active skills root |
|
|
48
|
+
| `pushrec-skills rollback <name>` | Rollback an installed skill to a backup snapshot |
|
|
40
49
|
|
|
41
|
-
### Utility
|
|
50
|
+
### Setup & Utility
|
|
42
51
|
|
|
43
52
|
| Command | Description |
|
|
44
53
|
|---------|-------------|
|
|
45
|
-
| `pushrec-skills
|
|
54
|
+
| `pushrec-skills setup` | One-command onboarding: verify license, activate device, install all skills |
|
|
55
|
+
| `pushrec-skills health` | Check registry server health (use `--full` for full diagnostic) |
|
|
56
|
+
| `pushrec-skills dashboard` | Launch the Generative UI dashboard |
|
|
46
57
|
|
|
47
58
|
## Registry
|
|
48
59
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: pushrec-skills
|
|
3
|
-
version: 1.
|
|
3
|
+
version: 1.1.0
|
|
4
4
|
description: "Universal entry point for all pushREC skill operations. Onboarding, skill discovery, troubleshooting, API key setup, and update guidance. Use when: first time using pushREC skills, need help finding the right skill, skill isn't working, setting up API keys, updating skills, or asking how skills work. Aliases: /onboarding, /start, /get-started, /help, /skills, /pushrec."
|
|
5
5
|
category: meta-tools
|
|
6
6
|
aliases: [onboarding, start, get-started, help, skills, pushrec]
|
|
@@ -143,7 +143,7 @@ Write `progress.json` with `first_win: {status: "completed", skill_recommended:
|
|
|
143
143
|
Present a personalized overview of available skills organized by level. Show only levels relevant to their profile.
|
|
144
144
|
|
|
145
145
|
**Structure:**
|
|
146
|
-
- **Level 0 -- Foundation (available now):** Group by category relevant to their profile. Highlight 5-8 most relevant skills with one-line descriptions. Mention total count (
|
|
146
|
+
- **Level 0 -- Foundation (available now):** Group by category relevant to their profile. Highlight 5-8 most relevant skills with one-line descriptions. Mention total count (check `~/.claude/skills/registry.json` for current `skill_count` — never hardcode).
|
|
147
147
|
- **Level 1 -- Google Workspace:** List capabilities unlocked (Gmail, Sheets, Docs, Calendar, Drive, Contacts, Slides). Note: "~15 minutes one-time setup."
|
|
148
148
|
- **Level 2 -- Creative and Data:** List key capabilities (AI image generation, voice synthesis, vision analysis, CRM). Note per-service setup time.
|
|
149
149
|
- **Level 3 -- Communication:** List capabilities (SMS, AI phone agents, web scraping). Note KYC requirements.
|
|
@@ -232,6 +232,10 @@ Check for missing prerequisites, missing API keys, or license issues.
|
|
|
232
232
|
| Skill produces no output | Skill invocation issue | Verify skill name, try `/skill-name` syntax |
|
|
233
233
|
| Import errors in scripts | Missing Python dependencies | Check skill's requirements, run `pip install` or `uv run --with` |
|
|
234
234
|
| License validation fails | License issue | Run `npx @pushrec/skills auth login` to re-authenticate |
|
|
235
|
+
| Hook errors in session output | Broken or incompatible hook | Check `~/.claude/settings.json` hooks array, remove or fix the offending hook |
|
|
236
|
+
| Rate limit / throttle errors | API quota exceeded | Wait and retry, or check service dashboard for quota limits |
|
|
237
|
+
| "No space left on device" | Disk full | Free disk space, check `df -h` output |
|
|
238
|
+
| Version mismatch warnings | Claude Code outdated | Run `claude update` to update to latest version |
|
|
235
239
|
|
|
236
240
|
### Step 4: Escalation
|
|
237
241
|
|
|
@@ -316,6 +320,7 @@ Note: `install --all` skips already-installed skills (no duplicates). Running it
|
|
|
316
320
|
| Skipping the diagnostic on first run | Always run diagnostic.py in Phase 0 |
|
|
317
321
|
| Proceeding after critical failures | STOP and help fix prerequisites before continuing |
|
|
318
322
|
| Recommending L1+ skills without mentioning API key requirements | Always state the setup requirement alongside the recommendation |
|
|
323
|
+
| Hardcoding skill counts | Always query dynamically or use safe-floor estimates |
|
|
319
324
|
|
|
320
325
|
### Verification Checklist
|
|
321
326
|
|
|
@@ -338,6 +343,7 @@ Before finishing any response, verify:
|
|
|
338
343
|
| Update skills | `npx @pushrec/skills update` |
|
|
339
344
|
| Install new skills | `npx @pushrec/skills install --all` |
|
|
340
345
|
| List all skills | `npx @pushrec/skills list` |
|
|
346
|
+
| Check CLI version | `npx @pushrec/skills --version` |
|
|
341
347
|
| Get help | Post in skool.com/pushrec-2909 |
|
|
342
348
|
| Reset onboarding | Type `/pushrec-skills` and say "reset" |
|
|
343
349
|
|
|
@@ -349,12 +355,27 @@ Before finishing any response, verify:
|
|
|
349
355
|
|
|
350
356
|
### State Files
|
|
351
357
|
|
|
358
|
+
The `state/` directory is created automatically on first write. No manual setup needed.
|
|
359
|
+
|
|
352
360
|
| File | Purpose |
|
|
353
361
|
|------|---------|
|
|
354
362
|
| `state/profile.json` | Business profile from adaptive profiling |
|
|
355
363
|
| `state/progress.json` | Completed phases, unlocked levels, skills invoked |
|
|
356
364
|
|
|
365
|
+
**Error recovery:** If `profile.json` or `progress.json` fails to parse (corrupt JSON), offer the user a reset: `rm ~/.claude/skills/pushrec-skills/state/*.json` and restart onboarding.
|
|
366
|
+
|
|
357
367
|
### Community
|
|
358
368
|
|
|
359
369
|
- **Skool:** skool.com/pushrec-2909
|
|
360
370
|
- **Live Q&A:** check Skool for scheduled sessions
|
|
371
|
+
|
|
372
|
+
---
|
|
373
|
+
|
|
374
|
+
## See Also
|
|
375
|
+
|
|
376
|
+
| Resource | Path | Purpose |
|
|
377
|
+
|----------|------|---------|
|
|
378
|
+
| Agent Skills Marketplace | `~/pushrec-vault/1-Projects/agent-skills-marketplace/` | License-gated skill distribution (ThriveCart + Convex + Vercel) |
|
|
379
|
+
| GTM Sprint | `~/pushrec-vault/1-Projects/gtm-sprint-claude-skills/` | Launch strategy, offer tiers, voice bible |
|
|
380
|
+
| Generative UI Dashboard | `~/.claude/skills/generative-ui/` | Visual dashboard with SkillBrowser (verify count via registry.json), SetupChecklist |
|
|
381
|
+
| Registry Runbook | `~/pushrec-vault/1-Projects/agent-skills-marketplace/registry/CLAUDE.md` | Zero-assumptions technical reference (687 lines) |
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""SessionStart hook for pushREC Skills onboarding nudge.
|
|
3
|
+
|
|
4
|
+
Reads progress.json and outputs a brief reminder if onboarding is incomplete.
|
|
5
|
+
Exit code 0 always — hooks must never fail the session.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import json
|
|
9
|
+
import os
|
|
10
|
+
import sys
|
|
11
|
+
from datetime import datetime, timezone
|
|
12
|
+
|
|
13
|
+
PROGRESS_FILE = os.path.expanduser(
|
|
14
|
+
"~/.claude/skills/pushrec-skills/state/progress.json"
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
# Canonical phase order for determining which phase comes next
|
|
18
|
+
PHASE_ORDER = [
|
|
19
|
+
("diagnostic", "System Diagnostic"),
|
|
20
|
+
("profiling", "Adaptive Profiling"),
|
|
21
|
+
("cc101", "Claude Code 101"),
|
|
22
|
+
("first_win", "First Win"),
|
|
23
|
+
("skill_map", "Skill Map"),
|
|
24
|
+
("unlock_guide", "Progressive Unlock"),
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def main():
|
|
29
|
+
# Prevent hook loops
|
|
30
|
+
if os.environ.get("stop_hook_active"):
|
|
31
|
+
return
|
|
32
|
+
|
|
33
|
+
# No progress file -> first-time user
|
|
34
|
+
if not os.path.exists(PROGRESS_FILE):
|
|
35
|
+
print(
|
|
36
|
+
"pushREC Skills: Welcome! Type /pushrec-skills to start your "
|
|
37
|
+
"personalized onboarding (takes ~30 min)."
|
|
38
|
+
)
|
|
39
|
+
return
|
|
40
|
+
|
|
41
|
+
# Read and parse progress
|
|
42
|
+
try:
|
|
43
|
+
with open(PROGRESS_FILE, "r") as f:
|
|
44
|
+
progress = json.load(f)
|
|
45
|
+
except json.JSONDecodeError as exc:
|
|
46
|
+
sys.stderr.write(f"pushrec-skills: progress.json parse error: {exc}\n")
|
|
47
|
+
return
|
|
48
|
+
except OSError as exc:
|
|
49
|
+
sys.stderr.write(f"pushrec-skills: progress.json read error: {exc}\n")
|
|
50
|
+
return
|
|
51
|
+
|
|
52
|
+
phases = progress.get("phases", {})
|
|
53
|
+
total_phases = len(PHASE_ORDER)
|
|
54
|
+
completed_count = sum(
|
|
55
|
+
1
|
|
56
|
+
for p in phases.values()
|
|
57
|
+
if isinstance(p, dict) and p.get("status") in ("completed", "skipped")
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
# All phases done -- nothing to show
|
|
61
|
+
if completed_count >= total_phases:
|
|
62
|
+
return
|
|
63
|
+
|
|
64
|
+
# Determine the next incomplete phase
|
|
65
|
+
next_phase_name = None
|
|
66
|
+
for phase_key, phase_label in PHASE_ORDER:
|
|
67
|
+
phase_data = phases.get(phase_key, {})
|
|
68
|
+
if not isinstance(phase_data, dict) or phase_data.get("status") not in (
|
|
69
|
+
"completed",
|
|
70
|
+
"skipped",
|
|
71
|
+
):
|
|
72
|
+
next_phase_name = phase_label
|
|
73
|
+
break
|
|
74
|
+
|
|
75
|
+
# Build the nudge message
|
|
76
|
+
prefix = ""
|
|
77
|
+
last_session_at = progress.get("last_session_at")
|
|
78
|
+
if last_session_at:
|
|
79
|
+
try:
|
|
80
|
+
last_dt = datetime.fromisoformat(last_session_at.replace("Z", "+00:00"))
|
|
81
|
+
now = datetime.now(timezone.utc)
|
|
82
|
+
days_since = (now - last_dt).days
|
|
83
|
+
if days_since > 7:
|
|
84
|
+
prefix = "Welcome back! It's been a while. "
|
|
85
|
+
except (ValueError, TypeError):
|
|
86
|
+
pass
|
|
87
|
+
|
|
88
|
+
if next_phase_name:
|
|
89
|
+
print(
|
|
90
|
+
f"{prefix}pushREC Skills: {completed_count}/{total_phases} phases complete. "
|
|
91
|
+
f"Next up: {next_phase_name}. Type /pushrec-skills to continue."
|
|
92
|
+
)
|
|
93
|
+
else:
|
|
94
|
+
print(
|
|
95
|
+
f"{prefix}pushREC Skills: {completed_count}/{total_phases} phases complete. "
|
|
96
|
+
"Type /pushrec-skills to continue where you left off."
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
if __name__ == "__main__":
|
|
101
|
+
try:
|
|
102
|
+
main()
|
|
103
|
+
except Exception:
|
|
104
|
+
pass # Never crash the session
|
|
105
|
+
sys.exit(0)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# pushREC Skills Prerequisites
|
|
2
|
-
# version: 1.
|
|
2
|
+
# version: 1.1.0
|
|
3
3
|
#
|
|
4
4
|
# Skills NOT listed here require NO API keys or credentials (Level 0).
|
|
5
5
|
# 80+ skills work immediately after install with zero configuration.
|
|
@@ -24,7 +24,7 @@ gmail:
|
|
|
24
24
|
service: Google Cloud Console
|
|
25
25
|
setup_url: https://console.cloud.google.com/apis/credentials
|
|
26
26
|
setup_time: "15 minutes (one-time for all Google services)"
|
|
27
|
-
credentials_path: "~/.gmail-
|
|
27
|
+
credentials_path: "~/.claude/.credentials/gmail-oauth.keys.json"
|
|
28
28
|
notes: "OAuth2 browser consent flow. Tokens stored at ~/.gmail-mcp/credentials.json"
|
|
29
29
|
|
|
30
30
|
google-sheets:
|
|
@@ -57,7 +57,7 @@ google-calendar:
|
|
|
57
57
|
service: Google Cloud Console
|
|
58
58
|
setup_url: https://console.cloud.google.com/apis/credentials
|
|
59
59
|
setup_time: "15 minutes (shared with other Google services)"
|
|
60
|
-
credentials_path: "~/.calendar-
|
|
60
|
+
credentials_path: "~/.claude/.credentials/calendar-oauth.keys.json"
|
|
61
61
|
notes: "OAuth2 browser consent flow."
|
|
62
62
|
|
|
63
63
|
google-drive:
|
|
@@ -68,7 +68,7 @@ google-drive:
|
|
|
68
68
|
service: Google Cloud Console
|
|
69
69
|
setup_url: https://console.cloud.google.com/apis/credentials
|
|
70
70
|
setup_time: "15 minutes (shared with other Google services)"
|
|
71
|
-
credentials_path: "~/.drive-
|
|
71
|
+
credentials_path: "~/.claude/.credentials/drive-oauth.keys.json"
|
|
72
72
|
notes: "OAuth2 browser consent flow."
|
|
73
73
|
|
|
74
74
|
google-contacts:
|
|
@@ -79,7 +79,7 @@ google-contacts:
|
|
|
79
79
|
service: Google Cloud Console
|
|
80
80
|
setup_url: https://console.cloud.google.com/apis/credentials
|
|
81
81
|
setup_time: "15 minutes (shared with other Google services)"
|
|
82
|
-
credentials_path: "~/.contacts-
|
|
82
|
+
credentials_path: "~/.claude/.credentials/contacts-oauth.keys.json"
|
|
83
83
|
notes: "Read-only. Shares GCP project with Gmail."
|
|
84
84
|
|
|
85
85
|
google-slides:
|
|
@@ -156,7 +156,13 @@ ocr-processor:
|
|
|
156
156
|
service: Google AI Studio
|
|
157
157
|
setup_url: https://aistudio.google.com/apikey
|
|
158
158
|
setup_time: "2 minutes (shared with gemini-vision)"
|
|
159
|
-
notes: "Primary provider: Gemini.
|
|
159
|
+
notes: "Primary provider: Gemini."
|
|
160
|
+
- env: MISTRAL_API_KEY
|
|
161
|
+
type: api_key
|
|
162
|
+
service: Mistral AI
|
|
163
|
+
setup_url: https://console.mistral.ai/api-keys
|
|
164
|
+
setup_time: "2 minutes"
|
|
165
|
+
notes: "Alternative provider for OCR. Set in ~/.claude/.env as MISTRAL_API_KEY=xxx"
|
|
160
166
|
|
|
161
167
|
airtable:
|
|
162
168
|
level: 2
|
|
@@ -248,6 +254,37 @@ skool-api:
|
|
|
248
254
|
setup_time: "5 minutes (browser login)"
|
|
249
255
|
notes: "Cookie-based auth persisted at ~/.skool/cookies.json. No API key - uses browser login."
|
|
250
256
|
|
|
257
|
+
# ============================================================================
|
|
258
|
+
# LEVEL 2 (continued): General-purpose API keys
|
|
259
|
+
# Used by multiple skills or for advanced integrations.
|
|
260
|
+
# ============================================================================
|
|
261
|
+
|
|
262
|
+
deep-research:
|
|
263
|
+
level: 2
|
|
264
|
+
requires:
|
|
265
|
+
- env: OPENAI_API_KEY
|
|
266
|
+
type: api_key
|
|
267
|
+
service: OpenAI
|
|
268
|
+
setup_url: https://platform.openai.com/api-keys
|
|
269
|
+
setup_time: "2 minutes"
|
|
270
|
+
notes: "Used by deep-research and other skills that support OpenAI models."
|
|
271
|
+
- env: ANTHROPIC_API_KEY
|
|
272
|
+
type: api_key
|
|
273
|
+
service: Anthropic
|
|
274
|
+
setup_url: https://console.anthropic.com/settings/keys
|
|
275
|
+
setup_time: "2 minutes"
|
|
276
|
+
notes: "Used for API-routed sub-agents and headless operations."
|
|
277
|
+
|
|
278
|
+
browser-automation:
|
|
279
|
+
level: 2
|
|
280
|
+
requires:
|
|
281
|
+
- env: RAPIDAPI_KEY
|
|
282
|
+
type: api_key
|
|
283
|
+
service: RapidAPI
|
|
284
|
+
setup_url: https://rapidapi.com/developer/dashboard
|
|
285
|
+
setup_time: "3 minutes"
|
|
286
|
+
notes: "Used by browser-automation and data enrichment integrations."
|
|
287
|
+
|
|
251
288
|
# ============================================================================
|
|
252
289
|
# LEVEL 3: Service Accounts
|
|
253
290
|
# Require KYC verification, usage-based billing, or special configuration.
|
|
@@ -14,12 +14,14 @@ import sys
|
|
|
14
14
|
from datetime import datetime, timezone
|
|
15
15
|
from pathlib import Path
|
|
16
16
|
|
|
17
|
-
VERSION = "1.
|
|
17
|
+
VERSION = "1.1.0"
|
|
18
18
|
SKILLS_DIR = Path.home() / ".claude" / "skills"
|
|
19
19
|
CONFIG_PATH = Path.home() / ".pushrec" / "config.json"
|
|
20
20
|
ENV_PATH = Path.home() / ".claude" / ".env"
|
|
21
|
+
PREREQUISITES_PATH = Path(__file__).resolve().parent.parent / "references" / "prerequisites.yaml"
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
# Fallback list used when prerequisites.yaml cannot be read
|
|
24
|
+
_FALLBACK_KEY_PREFIXES = [
|
|
23
25
|
"ELEVENLABS_API_KEY",
|
|
24
26
|
"OPENAI_API_KEY",
|
|
25
27
|
"ANTHROPIC_API_KEY",
|
|
@@ -41,6 +43,29 @@ KNOWN_KEY_PREFIXES = [
|
|
|
41
43
|
]
|
|
42
44
|
|
|
43
45
|
|
|
46
|
+
def load_key_prefixes():
|
|
47
|
+
"""Load API key env var names from prerequisites.yaml, falling back to hardcoded list."""
|
|
48
|
+
try:
|
|
49
|
+
with open(PREREQUISITES_PATH, "r") as f:
|
|
50
|
+
content = f.read()
|
|
51
|
+
# Simple YAML parsing: extract all `env: VALUE` lines (no PyYAML dependency)
|
|
52
|
+
prefixes = set()
|
|
53
|
+
for line in content.splitlines():
|
|
54
|
+
stripped = line.strip()
|
|
55
|
+
if stripped.startswith("- env:") or stripped.startswith("env:"):
|
|
56
|
+
value = stripped.split(":", 1)[1].strip()
|
|
57
|
+
if value:
|
|
58
|
+
prefixes.add(value)
|
|
59
|
+
if prefixes:
|
|
60
|
+
return sorted(prefixes)
|
|
61
|
+
except (OSError, ValueError):
|
|
62
|
+
pass
|
|
63
|
+
return _FALLBACK_KEY_PREFIXES
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
KNOWN_KEY_PREFIXES = load_key_prefixes()
|
|
67
|
+
|
|
68
|
+
|
|
44
69
|
def run_command(args):
|
|
45
70
|
"""Run a shell command and return (success, stdout_stripped)."""
|
|
46
71
|
try:
|
|
@@ -176,6 +201,8 @@ def check_obsidian():
|
|
|
176
201
|
|
|
177
202
|
|
|
178
203
|
def main():
|
|
204
|
+
# Exit silently in headless mode — hooks must never block headless sessions
|
|
205
|
+
# (e.g. CI pipelines, sub-agents) with interactive diagnostics or stdout noise.
|
|
179
206
|
if os.environ.get("CLAUDE_HEADLESS"):
|
|
180
207
|
sys.exit(0)
|
|
181
208
|
|
|
@@ -219,6 +246,8 @@ def main():
|
|
|
219
246
|
"version": VERSION,
|
|
220
247
|
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
221
248
|
"platform": platform.system().lower(),
|
|
249
|
+
"npm_version": checks["npm"].get("version"),
|
|
250
|
+
"skills_count": checks["skills_installed"].get("count", 0),
|
|
222
251
|
"checks": checks,
|
|
223
252
|
"exit_code": exit_code,
|
|
224
253
|
"summary": summary,
|