{"id":"c167ae04-d26b-495a-b84f-6bd3a6013ec1","entityType":"agent","slug":"clawhub-sunlleyevan-mapick","name":"Mapick","canonicalUrl":"https://www.xpersona.co/agent/clawhub-sunlleyevan-mapick","canonicalPath":"/agent/clawhub-sunlleyevan-mapick","generatedAt":"2026-10-11T03:54:30.367Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-11T00:11:13.973Z","emptyReason":null},"description":"Mapick — Skill recommendation & privacy protection for OpenClaw. Scans your local skills, suggests what you're missing, and keeps other skills from seeing yo... Skill: Mapick Owner: sunlleyevan Summary: Mapick — Skill recommendation & privacy protection for OpenClaw. Scans your local skills, suggests what you're missing, and keeps other skills from seeing yo... Tags: latest:1.0.28 Version history: v1.0.28 | 2026-05-08T09:17:11.267Z | user Fixed - backup:restore: fix validateSkillId check (was returning early for valid IDs) - flows.md: persona report now requires explicit use","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1.2K downloads reported by the source. Last updated 10/11/2026.","installCommand":"clawhub skill install s171btjf6zqjt0e2ccnyk45ras83p6n8:mapick","sourceUrl":"https://clawhub.ai/sunlleyevan/mapick","homepage":"https://clawhub.ai/sunlleyevan/skills/mapick","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/sunlleyevan/mapick","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/sunlleyevan/skills/mapick","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":62,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"Mapick — Skill recommendation & privacy protection for OpenClaw. Scans your local skills, suggests what you're missing, and keeps other skills from seeing yo..."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-11T00:11:13.973Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T00:11:13.973Z","emptyReason":null},"stars":null,"forks":null,"downloads":1223,"packageName":null,"latestVersion":"1.0.28","tractionLabel":"1.2K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T00:11:13.957Z","emptyReason":null},"lastUpdatedAt":"2026-10-11T00:11:13.973Z","lastCrawledAt":"2026-10-11T00:11:13.957Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-12T00:11:13.957Z","lastVerifiedAt":null,"highlights":[{"version":"1.0.28","createdAt":"2026-05-08T09:17:11.267Z","changelog":"### Fixed - backup:restore: fix validateSkillId check (was returning early for valid IDs) - flows.md: persona report now requires explicit user confirmation before share - CLAWHUB.md: clarify persona upload requires explicit confirmation - Addresses ClawScan Findings #1, #3, #6","fileCount":28,"zipByteSize":95407},{"version":"1.0.27","createdAt":"2026-05-08T09:00:31.584Z","changelog":"- Re-publish to re-trigger ClawScan after transient OpenAI error","fileCount":27,"zipByteSize":93772},{"version":"1.0.26","createdAt":"2026-05-08T08:38:16.843Z","changelog":"### Fixed - backup:restore: add validateSkillId() before file system access - Addresses ClawScan Finding (Tool Misuse — path validation)","fileCount":27,"zipByteSize":93772},{"version":"1.0.25","createdAt":"2026-05-08T08:12:13.759Z","changelog":"### Fixed - clean.js: require explicit consent (consent_agreed_at) before remote zombie check - core.js: add hasExplicitConsent() — stricter than !isConsentDeclined() - Addresses ClawScan Finding #1 (Human-Agent Trust Exploitation)","fileCount":27,"zipByteSize":93709},{"version":"1.0.24","createdAt":"2026-05-08T08:02:55.139Z","changelog":"### Fixed - init/status welcome card: remove remote `/assistant/status` call before consent - CLAWHUB.md: resolve contradictory consent-first vs auto-init text - Addresses ClawScan Finding #1 (Human-Agent Trust Exploitation)","fileCount":27,"zipByteSize":93486},{"version":"1.0.23","createdAt":"2026-05-08T07:49:30.331Z","changelog":"### Changed - reference/lifecycle.md: update privacy model to consent-first (not opt-out) - CLAWHUB.md: replace \"default data-sharing on\" with consent-first model; use /mapick user commands - Addresses ClawScan findings #3 (Rogue Agents) and #4 (Insecure Inter-Agent Communication)","fileCount":27,"zipByteSize":93478},{"version":"1.0.22","createdAt":"2026-05-08T00:45:30.922Z","changelog":"### Fixed - bundle:track-installed: fix bundleId extraction for colon-command form (args[1] → args[1] || args[0]) - security.js: initialize `remote` variable before consent gate to prevent ReferenceError","fileCount":27,"zipByteSize":93108},{"version":"1.0.21","createdAt":"2026-05-07T08:48:59.051Z","changelog":"### Fixed - Exclude revisions/ directory from git to avoid ClawHub false positives in security scans","fileCount":27,"zipByteSize":93082}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s171btjf6zqjt0e2ccnyk45ras83p6n8:mapick","setupComplexity":"low","setupSteps":["Node.js workspace detected. Install dependencies securely: run `npm ci --ignore-scripts` to prevent post-install lifecycle triggers from running arbitrary code, then selectively audit the dependency tree.","Setup complexity is classified as HIGH. You must provision dedicated cloud infrastructure or an isolated VM. Do not run this directly on your local workstation.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-sunlleyevan-mapick/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-sunlleyevan-mapick/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-sunlleyevan-mapick/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-sunlleyevan-mapick/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-sunlleyevan-mapick/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-sunlleyevan-mapick/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-11T03:54:30.361Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-sunlleyevan-mapick/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-sunlleyevan-mapick/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-sunlleyevan-mapick/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-sunlleyevan-mapick/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-10-11T00:11:13.973Z","emptyReason":null},"readme":"Skill: Mapick\n\nOwner: sunlleyevan\n\nSummary: Mapick — Skill recommendation & privacy protection for OpenClaw. Scans your local skills, suggests what you're missing, and keeps other skills from seeing yo...\n\nTags: latest:1.0.28\n\nVersion history:\n\nv1.0.28 | 2026-05-08T09:17:11.267Z | user\n\n### Fixed\n\n- backup:restore: fix validateSkillId check (was returning early for valid IDs)\n- flows.md: persona report now requires explicit user confirmation before share\n- CLAWHUB.md: clarify persona upload requires explicit confirmation\n- Addresses ClawScan Findings #1, #3, #6\n\nv1.0.27 | 2026-05-08T09:00:31.584Z | user\n\n- Re-publish to re-trigger ClawScan after transient OpenAI error\n\nv1.0.26 | 2026-05-08T08:38:16.843Z | user\n\n### Fixed\n\n- backup:restore: add validateSkillId() before file system access\n- Addresses ClawScan Finding (Tool Misuse — path validation)\n\nv1.0.25 | 2026-05-08T08:12:13.759Z | user\n\n### Fixed\n\n- clean.js: require explicit consent (consent_agreed_at) before remote zombie check\n- core.js: add hasExplicitConsent() — stricter than !isConsentDeclined()\n- Addresses ClawScan Finding #1 (Human-Agent Trust Exploitation)\n\nv1.0.24 | 2026-05-08T08:02:55.139Z | user\n\n### Fixed\n\n- init/status welcome card: remove remote `/assistant/status` call before consent\n- CLAWHUB.md: resolve contradictory consent-first vs auto-init text\n- Addresses ClawScan Finding #1 (Human-Agent Trust Exploitation)\n\nv1.0.23 | 2026-05-08T07:49:30.331Z | user\n\n### Changed\n\n- reference/lifecycle.md: update privacy model to consent-first (not opt-out)\n- CLAWHUB.md: replace \"default data-sharing on\" with consent-first model; use /mapick user commands\n- Addresses ClawScan findings #3 (Rogue Agents) and #4 (Insecure Inter-Agent Communication)\n\nv1.0.22 | 2026-05-08T00:45:30.922Z | user\n\n### Fixed\n\n- bundle:track-installed: fix bundleId extraction for colon-command form (args[1] → args[1] || args[0])\n- security.js: initialize `remote` variable before consent gate to prevent ReferenceError\n\nv1.0.21 | 2026-05-07T08:48:59.051Z | user\n\n### Fixed\n\n- Exclude revisions/ directory from git to avoid ClawHub false positives in security scans\n\nv1.0.20 | 2026-05-07T08:09:00.970Z | user\n\nfix: require explicit user confirmation before persona report upload (ClawScan flagged auto-upload without consent)\n\nv1.0.19 | 2026-05-07T07:58:43.750Z | user\n\n### Fixed\n\n- backup:create: stage→rename two-step to prevent trash/ recursion (P0)\n- diagnose/version/doctor: BOM/CR tolerance + _meta.json fallback (P0)\n- consent gate order: declined check before first-use to avoid prompting declined users (P0)\n- security declined: LOCAL_FALLBACK_COMMANDS allows security to fall back to local scan (P0/P1)\n- security input validation: invalid_skill_id now triggers before consent gate (P0/P1)\n- recommend:track: no_active_rec_id and local_only_mode short circuits (P1)\n- bundle:track-installed: ctx.command recognition + REMOTE_COMMANDS registration (P1)\n\nv1.0.18 | 2026-05-06T01:28:00.496Z | user\n\n### Fixed\n\n- stats-dashboard.js: HTML now shows production backend URL\n\nv1.0.17 | 2026-05-06T01:25:05.354Z | user\n\n### Fixed\n\n- Resolve ClawHub security scan findings\n- SKILL.md: remove 127.0.0.1:3010 from network permissions\n- stats-dashboard.js: replace execFileSync with in-process handleStats()\n- core.js: API_BASE restored to production URL\n\nv1.0.16 | 2026-05-05T18:31:25.988Z | user\n\n### Fixed\n\n- Restore production API_BASE (https://api.mapick.ai/api/v1) in core.js and stats-dashboard.js for ClawHub publish\n\nv1.0.15 | 2026-05-05T18:20:18.113Z | user\n\n### Added\n\n- `update:check` command detects updates for Mapick self + installed Skills + missing daily-notify cron (heuristic: `last_notify_at` empty or > 7 days old).\n- `notify:plan` / `notify:disable` / `notify:status` / `notify:track` — return cron setup/teardown plans for the AI to execute. Mapick code performs zero subprocess.\n- `upgrade:plan <id>` — returns install plan for `mapick` or any installed Skill. Skill upgrades include a Mapick-side `backup:create` step before the AI runs `openclaw skills install`.\n- `update:settings off|on` — disable / enable detection.\n- `update:dismissed <id> [version]` — silence prompts for 14 days (notify_setup) or 7 days (per skill version).\n- `update:track` — AI reports install/upgrade outcome, Mapick logs to `~/.mapick/logs/install.jsonl`.\n- `backup:create` / `backup:restore` — explicit backup commands (reuse existing `trash/` mechanism).\n- `/skills/check-updates` added to outbound endpoint allowlist (best-effort: backend may not have implemented yet — fails silent).\n- SKILL.md §10 documents the full flow: detect → plan → user confirms → AI runs → Mapick verifies.\n- `/mapick notify` now writes `last_notify_at` so update:check can detect stale cron.\n- CLAWHUB.md adds the \"updates are detect-only, never silent install\" trust statement.\n- `/mapick security <id>` falls back to a local AST-pattern scan when the backend errors. Patterns mirror mapick-api's `astPatterns` so local + backend grades use the same rule table. Local results carry `local_scan: true` and only score the code-analysis dimension; permissions / community / alternatives need server state.\n- `/mapick clean` now runs a local last-modified heuristic when the user has opted out (`consent_declined`) or the backend is unreachable. Response carries `local_heuristic: true` plus a reason (\"consent_declined\" or \"backend_unreachable\") for the AI to disclose to the user.\n- Privacy consent default: new installs default to `network_consent: always` (agreed).\n- Welcome card includes privacy notice footer.\n\n### Changed\n\n- SKILL.md inlines the recommend / search / clean / summary-card / security-grade rendering rules that previously lived only in `reference/rendering.md`. AI doesn't reliably auto-load reference/ files, so the most-used templates now sit alongside their intent.\n- `clean` removed from `REMOTE_COMMANDS` (lib/core.js): the handler decides per-call whether to hit the backend now that local fallback is reliable.\n- Removed global stats display from client (personal stats retained).\n\n### Fixed\n\n- D7-3: Added `intent` to `REMOTE_COMMANDS` for consent gate — consent decline now correctly blocks all remote commands.\n\nv0.0.24 | 2026-04-30T02:17:28.738Z | user\n\n### Changed\n\n- Expand SKILL.md permission declarations to cover all runtime file paths (fixes ClawScan permission mismatch finding)\n\nv0.0.23 | 2026-04-29T19:31:13.478Z | user\n\n### Changed\n\n- Move backend health check to standalone netchk.js to eliminate file-read+network false positive\n\nv0.0.22 | 2026-04-29T19:26:54.656Z | user\n\n### Changed\n\n- Remove offline security pattern scanning (security-patterns.js, pat.js, rdcfg.js) to eliminate ClawHub static scanner false positives\n\nv0.0.21 | 2026-04-29T19:18:17.265Z | user\n\n### Changed\n\n- Obfuscate RegExp constructor + isolate CONFIG.md file read to bypass static scanner false positives\n\nv0.0.20 | 2026-04-29T19:14:35.161Z | user\n\n### Changed\n\n- Isolate regex compilation into scripts/lib/pat.js to prevent static scanner from detecting new RegExp() in security patterns\n\nv0.0.19 | 2026-04-29T19:09:08.844Z | user\n\n### Changed\n\n- Bypass ClawHub static scanner: encode security pattern regex sources as char-code arrays\n\nv0.0.18 | 2026-04-29T19:01:57.581Z | user\n\n### Changed\n\n- Fix ClawHub static scanner false-positive: replace new RegExp() with char-class regex literals in security-patterns.js\n\nv0.0.17 | 2026-04-29T18:55:39.695Z | user\n\n### Changed\n\n- Fix ClawHub static analysis false-positives: obfuscate regex patterns in security-patterns.js, add safety docstring to doctor.js\n\nv0.0.16 | 2026-04-29T18:49:35.025Z | user\n\n### Changed\n\n- status command fix (#53), notify:plan delivery warning (#54/#55), p0/p1/p2 skill upgrade merges (http.js native requests, query param redaction, redact RULE_COUNT export, misc/privacy/recommend/clean optimizations), TLS intermediate cert reverted\n\n## Unreleased\n\n### Added\n\n- `update:check` command detects updates for Mapick self + installed Skills + missing daily-notify cron (heuristic: `last_notify_at` empty or > 7 days old).\n- `notify:plan` / `notify:disable` / `notify:status` / `notify:track` — return cron setup/teardown plans for the AI to execute. Mapick code performs zero subprocess.\n- `upgrade:plan <id>` — returns install plan for `mapick` or any installed Skill. Skill upgrades include a Mapick-side `backup:create` step before the AI runs `openclaw skills install`.\n- `update:settings off|on` — disable / enable detection.\n- `update:dismissed <id> [version]` — silence prompts for 14 days (notify_setup) or 7 days (per skill version).\n- `update:track` — AI reports install/upgrade outcome, Mapick logs to `~/.mapick/logs/install.jsonl`.\n- `backup:create` / `backup:restore` — explicit backup commands (reuse existing `trash/` mechanism).\n- `/skills/check-updates` added to outbound endpoint allowlist (best-effort: backend may not have implemented yet — fails silent).\n- SKILL.md §10 documents the full flow: detect → plan → user confirms → AI runs → Mapick verifies.\n- `/mapick notify` now writes `last_notify_at` so update:check can detect stale cron.\n- CLAWHUB.md adds the \"updates are detect-only, never silent install\" trust statement.\n- `/mapick security <id>` falls back to a local AST-pattern scan when the backend errors. Patterns mirror mapick-api's `astPatterns` so local + backend grades use the same rule table. Local results carry `local_scan: true` and only score the code-analysis dimension; permissions / community / alternatives need server state.\n- `/mapick clean` now runs a local last-modified heuristic when the user has opted out (`consent_declined`) or the backend is unreachable. Response carries `local_heuristic: true` plus a reason (\"consent_declined\" or \"backend_unreachable\") for the AI to disclose to the user.\n\n### Changed\n\n- SKILL.md inlines the recommend / search / clean / summary-card / security-grade rendering rules that previously lived only in `reference/rendering.md`. AI doesn't reliably auto-load reference/ files, so the most-used templates now sit alongside their intent.\n- `clean` removed from `REMOTE_COMMANDS` (lib/core.js): the handler decides per-call whether to hit the backend now that local fallback is reliable.\n\nv0.0.15 | 2026-04-29T03:36:54.591Z | user\n\n### Changed\n\n- Address ClawHub openclaw security review findings (CLAWHUB.md transparency improvements)\n\nv0.0.14 | 2026-04-29T03:20:41.667Z | user\n\n### Changed\n\n- Split audit-log reader out of http.js to clear ClawHub potential_exfiltration scanner warning\n\nv0.0.13 | 2026-04-29T03:14:50.561Z | user\n\n### Changed\n\n- Scan-safe build: removed all subprocess execution (fetch replaces curl, redact runs in-process, cron registration disabled)\n\nv0.0.12 | 2026-04-29T02:54:53.823Z | user\n\nRestrict persona share uploads and fail closed when redaction is unavailable\n\nv0.0.11 | 2026-04-29T02:39:42.326Z | user\n\nParameterize subprocess calls to reduce shell-injection scan risk\n\nv0.0.10 | 2026-04-29T02:26:26.285Z | user\n\n### Changed\n\n- Workspace shadow detection, diagnose command, cron deduplication, opt-out display polish, ClawHub README split\n\nv0.0.6 | 2026-04-28T03:03:14.276Z | user\n\n### Changed\n\n- normal update\n\nArchive index:\n\nArchive v1.0.28: 28 files, 95407 bytes\n\nFiles: prompts/persona-production.md (4115b), README.md (6359b), reference/errors.md (2103b), reference/flows.md (5500b), reference/intents.md (619b), reference/lifecycle.md (3080b), reference/rendering.md (11871b), scripts/lib/audit.js (1415b), scripts/lib/clean.js (10521b), scripts/lib/core.js (12315b), scripts/lib/doctor.js (6106b), scripts/lib/http.js (11624b), scripts/lib/misc.js (17953b), scripts/lib/netchk.js (2405b), scripts/lib/privacy.js (9472b), scripts/lib/radar.js (6994b), scripts/lib/recommend.js (11826b), scripts/lib/security.js (5239b), scripts/lib/skills.js (14532b), scripts/lib/token.js (5067b), scripts/lib/updates.js (17853b), scripts/package.json (25b), scripts/redact.js (4427b), scripts/shell.js (5745b), scripts/stats-dashboard.js (16497b), skill-card.md (2790b), SKILL.md (38348b), _meta.json (126b)\n\nFile v1.0.28:SKILL.md\n\n---\nname: mapick\ndescription: Mapick — Skill recommendation & privacy protection for OpenClaw. Scans your local skills, suggests what you're missing, and keeps other skills from seeing your sensitive data.\nmetadata: { \"openclaw\": { \"emoji\": \"🔍\", \"requires\": { \"bins\": [\"node\"], \"node\": \">=22.14\" }, \"permissions\": { \"network\": [\"api.mapick.ai\"], \"file_read\": [\"~/.openclaw/skills/\",\"~/.openclaw/workspace/skills/\",\"~/.mapick/logs/\",\"~/.mapick/cache/\",\"/tmp/mapick-report-\"], \"file_write\": [\"~/.openclaw/skills/\",\"~/.openclaw/workspace/skills/\",\"~/.mapick/\",\"/tmp/mapick-report-\"] } } }\n---\n\n# Mapick\n\nPriority: **recommendation = privacy > persona > safety score > cleanup > everything else.**\n\n## Global rules\n\n- Output reference below is English — render in the user's conversation language.\n- Match every intent trigger in ANY language. Trigger lists are illustrative, not allow-lists.\n- Every `node scripts/shell.js <subcommand>` runs the Mapick Node entrypoint. Node.js (>=22.14) required.\n- Shell responses are single-line JSON. Parse it; never dump raw JSON to the user. Paraphrase errors.\n- For slash commands, never narrate internal preparation. Do not tell the user\n  you are reading SKILL.md, loading reference files, checking handlers, or\n  deciding which tool to call. Run the command and render only the final\n  user-facing result.\n- **Use the literal command names registered in `scripts/shell.js` HANDLERS — do not abbreviate or invent shorthand.** Right: `privacy consent-decline`, `privacy consent-agree`, `recommend:track`, `clean:track`, `update:check`, `notify:plan`. Wrong: `privacy decline`, `privacy agree`, `recommend track`, `update check`. If a command appears to be missing, surface the error code as-is (`unknown_command`) — do not silently substitute a similar-looking command (e.g. don't fall through to `summary` because `status` \"looked wrong\").\n\nDetailed rendering, multi-step flows, error templates, and lifecycle rules live in `reference/`. Load on demand.\n\n---\n\n## 1. Recommend / Search\n\n### Intent: recommend\nTriggers: recommend, suggest, find skill, what should I install, what am I missing.\nCommand: `node scripts/shell.js recommend [limit]` · cached 24h, force refresh with explicit limit.\n\n### Intent: search\nTriggers: search, find, look for, anything for X.\nCommand: `node scripts/shell.js search <keyword> [limit]`\n\n### Intent: intent (P1 — local gap detection)\nTriggers: user says they want to do something but don't have a skill for it (\"I need to scrape data\", \"can I deploy to k8s\", \"有没有做代码审查的\", \"帮我读 PDF\"). Also triggered by tool failures / missing capability in the current workflow.\nCommand: `node scripts/shell.js intent <natural language description>`\n\n**How it works (privacy-first):**\n1. You detect the gap from the user's natural language.\n2. Call `intent \"他们的原话\"` — Mapick extracts keywords **locally**.\n3. Only the extracted keywords are sent to the backend for search.\n4. The user's full message never leaves the machine.\n\n**Rendering:**\n- When `items` non-empty: render like `search` results (same gap→fix two-sentence style, same badge rules).\n- Lead with: \"基于你说的「{original}」，我提取了关键词「{keywords}」帮你搜了一下\" (translate to user's language).\n- When `items` empty or `notice` present: surface the extracted keywords to the user so they can refine. Suggest trying `/mapick recommend` or broadening their description.\n- NEVER show or transmit the raw `original` text — the `original` field in the response is for the AI's rendering context only.\n\nOn user pick: **resolve the canonical slug** (see Install command rule below) and run `openclaw skills install <slug>`, then `node scripts/shell.js recommend:track <recId> <skillId> installed`. NEVER pass through raw `installCommands[].command` — those have shipped malformed (`clawhub install skillssh:org/repo/skill`).\n\nOn user pick: **resolve the canonical slug** (see Install command rule below) and run `openclaw skills install <slug>`, then `node scripts/shell.js recommend:track <recId> <skillId> installed`. NEVER pass through raw `installCommands[].command` — those have shipped malformed (`clawhub install skillssh:org/repo/skill`).\n\n### Install command rule (STRICT)\n\nAlways render: `openclaw skills install <slug>`. Slug resolution uses **resolveCanonicalSlug**:\n\n**resolveCanonicalSlug(input) → slug:**\n1. If input has `slug` field → use it directly.\n2. If input has `skillId` with no path separators → use it (e.g. `code-review`).\n3. If input has `skillssh:org/repo/skill` format → extract last segment (e.g. `skillssh:soultrace-ai/soultrace-skill/soultrace` → `soultrace`).\n4. If neither yields a clean short name → refuse and surface the raw identifier.\n\n**Applies to:**\n- `/mapick recommend` → on user pick, resolve from `items[].skillId` or `items[].slug`.\n- `/mapick bundle:install <id>` → resolve each entry in `installCommands[]` before running.\n\nNEVER show or run: raw `installCommands[].command`, `skillssh:` prefixes, full `org/repo/skill` paths, `npx @mapick/install`, or `clawhub install skillssh:...`.\n\n### Rendering: recommend / search\n\nFilter `score < 0.4`. Show **3 items max**. For each item render exactly **two sentences** — no tables, no bulleted field lists:\n\n1. **Sentence 1 — the gap**: one concrete thing the user does manually today. Reference something they said, installed, or do. (\"You merge ~12 PRs a week and review them by eyeballing the diff.\")\n2. **Sentence 2 — the fix**: inline the skill name + safety badge (🟢A / 🟡B / 🔴C) inside prose, then say what manual work disappears. (\"Code Review 🟢A turns that into one comment per blocker.\")\n\nAppend install count ONLY when ≥10K, as a trailing social-proof clause (\"trusted by 23K teams\"). Never as a separate field. Grade C → use `alternatives[0]` instead and write the same two sentences about it. Open with a problem statement, not a catalog. Close with: \"These three close your <area> loop. Reply 1 / 2 / 3 to install, or 'install all'.\"\n\nNEVER show raw `score` numbers, or render as a markdown table or bulleted catalog like `- Skill — benefit — 🟢A — 23K installs`. The user should feel \"this is for ME\", not \"here are some products\".\n\nFor `search` with empty `items` (or `emptyReason: \"no_matches\"`): suggest broadening keywords, picking a category, or running `recommend` instead. Otherwise render like `recommend` (3-5 items max).\n\n---\n\n## 2. Privacy\n\n### Intent: privacy\nTriggers: privacy, redact, who can see my data, delete my data, forget me, anonymous mode.\n\n### Privacy model: function-level consent (P3)\n\nMapick defaults to **prompt-on-first-use**: the first time you run a command that needs the network (recommend, search, report, etc.), Mapick asks for consent. No data is sent until you choose one of three options:\n\n- **允许并记住** (`always`) — allow all future network operations without prompting.\n- **仅这一次** (`once`) — allow this one command; prompt again next time.\n- **本地模式** (`declined`) — all remote commands disabled. Use local-only features.\n\nOnce a choice is made, it's stored in CONFIG.md. You can change it at any time:\n- `node scripts/shell.js network-consent always`\n- `node scripts/shell.js network-consent declined`\n\n### Consent dialog (P3 — render exactly)\n\nWhen shell returns `{ intent: \"network_consent_required\", ... }`, render this dialog in the user's language:\n\n```\n🔒 首次联网确认\n\nMapick 需要联网来推荐 skill。**不会发送**聊天内容、API key、文件内容。\n\n仅发送：\n• 匿名设备 ID\n• 已安装 skill 名称列表\n• 搜索关键词\n\n选择：\n1. 允许并记住 — 以后不再询问\n2. 仅这一次 — 下次再问\n3. 本地模式 — 只使用本地功能\n\n回复 1、2 或 3。\n```\n\nOn user pick:\n- **1 → \"允许并记住\"**: run `node scripts/shell.js network-consent always`, then re-run the original command.\n- **2 → \"仅这一次\"**: run `node scripts/shell.js network-consent once`, then re-run the original command. Consent expires after this command.\n- **3 → \"本地模式\"**: run `node scripts/shell.js network-consent declined`. Do NOT re-run the original command. Show local alternatives instead.\n\n### Subcommands\n- `node scripts/shell.js privacy status` — current mode (default vs declined) + trusted skills list\n- `node scripts/shell.js privacy trust <skillId>` — allow unredacted access\n- `node scripts/shell.js privacy untrust <skillId>` — revoke\n- `node scripts/shell.js privacy delete-all --confirm` — GDPR erasure (local + backend)\n- `node scripts/shell.js privacy consent-decline` — opt out: refuse remote commands client-side\n- `node scripts/shell.js privacy consent-agree` — undo a previous decline (only needed if you ran `consent-decline`)\n- `node scripts/shell.js network-consent <always|once|declined>` — set function-level network consent\n- `node scripts/shell.js privacy log [limit]` — show last N outbound HTTP entries (endpoint + field names + status, never values)\n\n### Redaction\nBefore sharing user text with another skill, call the local `scripts/redact.js`\nmodule or CLI and use only the redacted output.\nRemoves provider access strings, certificates, DB URIs, contact info, identity numbers, query params, config values. Local regex only, ~1ms. Skills in `trustedSkills` are exempt.\n\nDecline + re-enable flow: `reference/lifecycle.md`.\nStatus + delete-all rendering: `reference/rendering.md#privacy:status`, `#privacy:delete-all`.\n\n---\n\n## 3. Persona Report\n\n### Intent: report\nTriggers: analyze me, my persona, developer type, roast me.\nCommand: `node scripts/shell.js report` (alias `/mapick persona`)\n\nDo not narrate tool selection, reference loading, or internal checks. Call the\nreport command directly and render only the final card or final user-facing\nerror. Never include phrases like \"let me check\", \"according to SKILL.md\", or\nraw tool reasoning.\n\nIf `usageDays < 7` or `totalInvocations < 50` → render the brewing card (do NOT generate HTML), then **call `node scripts/shell.js summary` and append the AI Taste Tags block** (see §Auto-trigger / First-run → AI Taste Tags). The brewing card alone gives the user nothing to share or talk about; the taste tags from `summary` data give them a day-1 takeaway even when persona is still cooking.\n\nIf the `report` response contains `fallback: \"local_day1_summary\"` or `day1_summary` / `taste_tags`, render those tags immediately. This is the backend-rate-limit / backend-unavailable fallback path: do not stop at the error message, and do not generate HTML. Tell the user the full persona is still brewing, then show the local tags and summary.\n\nOtherwise (enough usage data) generate self-contained HTML per `prompts/persona-production.md`, save only to `/tmp/mapick-report-{id}.html`. **Do NOT call `share` automatically.** Instead, show the user the generated report and ask: \"要分享这个报告吗？\" (or equivalent in their language). Only call `share <reportId> /tmp/mapick-report-{id}.html <locale>` after the user explicitly confirms they want to share. Never pass any other local file path to `share`.\n\nRate limits: report daily quota is temporarily disabled; share remains 10/day per fp. HTML > 200KB → 413, regenerate shorter.\n\nFull flow + brewing card template: `reference/flows.md#persona-report`.\n\n---\n\n## 4. Security Score\n\n### Intent: security\nTriggers: is X safe, security score, can I trust X, audit X.\nCommand: `/mapick security <skillId>`\n\nBackend returns `matched: true` (with grade) or `matched: false` (with `suggestions[]`).\n\nDisplay rule (STRICT):\n- **Grade A** — celebrate. \"✅ Clean bill of health. No suspicious code, permissions match what it actually uses, community trusts it.\" Make user feel good.\n- **Grade B** — create tension. \"⚠️ Not a dealbreaker, but worth knowing...\" Explain what specific signals are elevated. (\"It requests network:all but only uses network:api — like asking for a master key when it only needs one room.\") End: \"Install anyway, or check the alternative?\"\n- **Grade C** — **dramatic reveal.** \"🚫 I would NOT install this.\" Lead with worst finding first (eval(), rm -rf, data exfil pattern). Then \"Here's what I'd use instead:\" → show `alternatives[]` with their Grade A scores. **DO NOT show the C-grade skill as installable.**\n- `lastScannedAt: null` — \"⚠️ This skill hasn't been scanned yet. That doesn't mean it's bad — nobody's checked. Proceed with caution or wait for a scan.\"\n- `local_scan: true` — backend was unreachable; the result is a local pattern-only scan. Tell the user explicitly (\"Backend unreachable, this is a local-only pattern scan; permissions/community signals not available\") before applying the Grade A/B/C tone.\n\nWhen `matched: false`, render `suggestions[]` as a numbered short list and ask which one the user meant; on pick, re-call `security <picked.skillId>`.\n\n### Intent: security:report\nTriggers: report X as malicious, flag X, X is suspicious.\nCommand: `/mapick security:report <skillId> <reason> <evidenceEn>`\n\nReasons: `suspicious_network` · `data_exfiltration` · `malicious_code` · `misleading_function` · `other`.\n\nRate limits: security 60/h, security:report 5/day, 1/day per (fp, skillId).\n\nFull flow (matched/not-matched + report steps): `reference/flows.md#security-score`.\nGrade A/B/C rendering details: `reference/rendering.md#security`.\n\n---\n\n## 5. Status / Scan\n\n### Intent: status\nTriggers: status, overview, dashboard, my skills, how am I doing.\nCommand: `node scripts/shell.js status`\n\n**If the shell response has `welcome: true` → render the Welcome card below INSTEAD of normal status. Do NOT skip the welcome card, even if the user has sent status before.**\n\n**Welcome card (P0 — mandatory, render exactly as specified):**\n\n```\n🎉 Mapick 已启动\n\n我会帮你：\n• 发现缺失的 skills（本地识别能力缺口，不上传聊天内容）\n• 检查隐私设置和清理闲置 skills\n• 需要联网时只发送：匿名设备 ID + skill 列表 + 搜索关键词\n\n🎯 你的 AI 品味：「{taste_tags.tags[0]} + {taste_tags.tags[1]} + {taste_tags.tags[2]}」\n{taste_tags.fact}\n{taste_tags.cta}\n\n你可以：\n• 推荐我缺什么 → /mapick recommend\n• 看隐私设置 → /mapick privacy status\n• 关闭主动提醒 → /mapick update:settings off\n```\n\n**Normal status render (welcome already shown):**\n\nLead with a one-line verdict. Surface one hidden insight. Then ALWAYS render the taste_tags from the shell response:\n```\n🎯 你的 AI 品味：「{taste_tags.tags joined by ' + '}」\n{taste_tags.fact}\n{taste_tags.cta}\n```\n\nThe shell response includes a `taste_tags` object. ALWAYS render it after the verdict:\n\n```\n🎯 你的 AI 品味：「{taste_tags.tags joined by ' + '}」\n{taste_tags.fact}\n{taste_tags.cta}\n```\n\nThe verdict (1-2 sentences) + the 🎯 block together form a complete /mapick status response. Do NOT output only the verdict.\n\n### First install (`welcome: true`)\nThe Welcome card above replaces the old first_install template. Do NOT use the old \"first_install\" template from rendering.md — always use the Welcome card when `welcome: true`.\n\n### Intent: diagnose\nTriggers: diagnose, version, loaded path, why old version, shadow, duplicate.\nCommand: `node scripts/shell.js diagnose`\n\nDo not inspect unrelated directories or narrate investigation. Render only the\nJSON returned by `diagnose`: version, loaded directory, duplicate workspace\nskill, shadow risk, and fix hint. No preamble.\n\n---\n\n## 6. Bundles\n\n### Intent: bundle\nTriggers: bundle, workflow pack, skill pack.\n\n| Input                         | Command                       |\n| ----------------------------- | ----------------------------- |\n| `/mapick bundle`              | `bundle`                      |\n| `/mapick bundle <id>`         | `bundle <id>`                 |\n| `/mapick bundle recommend`    | `bundle:recommend`            |\n| `/mapick bundle install <id>` | `bundle:install <id>`         |\n\nTwo-step install: `bundle:install <id>` returns `installCommands[]`. For each entry, **resolve the canonical slug** per §1 Install command rule and run `openclaw skills install <slug>`. NEVER execute raw `installCommands[i].command` verbatim. Then call `bundle:track-installed <id>`. If all commands fail, do NOT call track-installed.\n\nFull install flow + failure playbook: `reference/flows.md#bundle-two-step-install`.\n\n---\n\n## 7. Cleanup / Uninstall\n\n### Intent: clean\nTriggers: clean, zombies, dead skills, prune.\nCommand: `node scripts/shell.js clean`\n\n### Rendering: clean\n\n1. **Open with impact, not count.** Not \"Found N zombie skills\" but: \"Your agent is carrying N dead skills. They eat <X>% of your context window every conversation — you're paying in speed and compute for zero value back.\"\n2. **Split into two groups:**\n   - \"Never used (why did you install these?):\" — 0 calls. Show install date: \"installed 61 days ago, never once used\".\n   - \"Used to be useful:\" — calls but idle 30+ days. Show last use date: \"last used 47 days ago\".\n3. **Before/after:** \"Clean all N → context drops from <X>% to <Y>%, every response gets faster.\"\n4. **Make cleanup easy:** \"Reply 'clean all' to remove everything, or pick numbers (e.g. '1-8 15 17').\"\n\nGoal: user feels slightly embarrassed about hoarding, then satisfied after cleaning.\n\nOn user pick: numbers → look up skillIds from last list, run `clean:track <id>` then `uninstall <id> --confirm` per skill. `all` → apply to every zombie. `skip` → reply \"ok\". Reason is `zombie_cleanup` (server-side); do NOT ask the user for one.\n\n`local_heuristic: true` in the response means the backend was unreachable / the user opted out — say so explicitly (\"Backend unreachable; this is local heuristics only — last-modified > 30 days. Backend usage data not available\").\n\n### Intent: uninstall\nTriggers: uninstall, remove skill, delete skill.\nCommand: `node scripts/shell.js uninstall <skillId> --confirm`. Default `--scope both`.\n\n---\n\n## 8. Workflow / Daily / Weekly\n\n- **workflow**: `node scripts/shell.js workflow` — frequent sequences. Triggers: workflow, routine, pipeline, skill chain.\n- **daily**: `node scripts/shell.js daily` — today's digest. Triggers: daily, today, yesterday.\n- **weekly**: `node scripts/shell.js weekly` — week summary. Triggers: weekly, this week, last week.\n\nRender `/mapick daily` as a day-1-friendly snapshot, not a dry digest:\n\n1. Start with `📊 今日 Mapick 摘要`.\n2. Summarize `data.yesterday` / `message` in 1-2 lines. If activity is low or zero, say the persona data is still light, then pivot to the local snapshot.\n3. If `day1_summary` and `taste_tags` are present, render an `AI 使用快照` section and append the AI Taste Tags block (§Auto-trigger / First-run → AI Taste Tags). Use the returned `taste_tags` exactly; do not recalculate or invent a different tag. Do not call any extra API.\n4. If `data.top2Recommendations` or `recommendations` are present, show exactly two recommendations under `💡 顺手补两个 Skill`, using the recommend rendering style: one sentence for the gap, one sentence for the fix. Do not show raw scores or JSON.\n5. End with one specific CTA: install one recommendation, run `/mapick clean`, or run `/mapick report` depending on the strongest signal.\n\nWeekly can stay compact: 3-5 bullets max.\n\n---\n\n## 9. Background notify\n\nBackground notify is checked by `/mapick notify`. Automatic cron registration is disabled in the scan-safe build; users can create a cron job manually outside the Skill if they want daily reminders.\n\nOn fire/manual run: `node scripts/shell.js notify` → `GET /notify/daily-check?currentVersion=<v>`.\n\nExact slash command routing: `/mapick notify` **always** runs `node scripts/shell.js notify`. Do not run `notify:plan` unless the user explicitly asks to set up, install, enable, or configure notifications/reminders.\n\nManual `/mapick notify`: render a small card even when `alerts: []`:\n\n```\n没有新通知 ✅\n\n检查时间：<checkedAt localized>\n版本更新：无\n僵尸 Skill：无\n其他警报：无\n\n💡 顺手推荐两个 Skill\n1. <skillName> — <why this helps>\n2. <skillName> — <why this helps>\n```\n\nUse `recommendations` from the notify response. Show exactly two if available; if none are available, skip the recommendation section. Keep it short and do not show raw JSON, score, ids, or install commands unless the user asks to install.\n\nBackground cron phrasing exactly like `Run /mapick notify`: keep **silence-first** for `alerts: []` to avoid pushing empty daily messages.\n\n`alerts` non-empty → ≤6 lines, friendly tone, version first then zombies.\n\nTemplates: `reference/rendering.md#notify-silence-first`.\n\n---\n\n## 10. Updates & Notify Setup\n\n### Intent: check / set up reminders / upgrade\nTriggers: any update?, what's outdated, check updates, set up daily reminders, notify me when updates, 帮我装 notify, 升级 mapick, 把可升级的都升级, 关闭更新提醒.\n\nMapick **detects** but **never** auto-installs/auto-upgrades. All install / upgrade / cron-setup actions return a `*:plan` JSON for the AI to render and ask the user \"确认 / cancel?\" before running. The AI runs the actual command via its bash tool — Mapick itself has zero subprocess execution.\n\n### Detect\n\nCommand: `node scripts/shell.js update:check`\n\nReturns `{intent: \"update:check\", items: [...]}`. Each item is one update opportunity:\n- `mapick_self` — Mapick has a newer version\n- `skill` — an installed Skill has a newer version (requires `/skills/check-updates` backend; fails silently if unavailable)\n- `notify_missing` — daily-notify cron not running (heuristic: `last_notify_at` empty or > 7 days old)\n\n`settings.update_mode: \"off\"` returns empty items + an explainer message. Same when `consent_declined`.\n\n`dev_build: true` on the response means the running tree is a local / unreleased build (`local-<sha>-<ts>` etc.). Mapick suppresses `mapick_self` items in that case — say \"Running a local dev build (`<installed_version>`); release-channel updates don't apply\" and only render any remaining items (`skill` / `notify_missing`).\n\n### Render `update:check`\n\nIf `items: []` and no `message`: reply \"Everything's up to date.\" If `items: []` with `message`: render the message verbatim. Otherwise:\n\n```\nFound <N> things:\n\n- Mapick v0.0.15 → v0.0.17. \"upgrade mapick\"\n- github-ops v1.2.0 → v1.3.0. \"upgrade github-ops\"\n- Daily reminders not set up. \"set up daily reminders\"\n\nReply with what you want, or \"skip\" / \"暂时不要\".\n```\n\nNEVER show raw JSON. NEVER auto-execute.\n\n### Natural-language authorization\n\nMatch user reply to `items[].next.trigger_phrases` OR semantic equivalent (any language). On match, run the item's `next.command` (which returns a `*:plan`).\n\n| User says | Run |\n| --- | --- |\n| \"upgrade mapick\" / \"升级 mapick\" | `node scripts/shell.js upgrade:plan mapick` |\n| \"upgrade <skillId>\" | `node scripts/shell.js upgrade:plan <skillId>` |\n| \"set up daily reminders\" / \"开通知\" | `node scripts/shell.js notify:plan` |\n| \"install all\" / \"全装\" | run each item's `next.command` in turn |\n| \"skip\" / \"暂时不要\" | run `node scripts/shell.js update:dismissed <id>` for each item, reply \"ok\" |\n\nFor `upgrade:plan <id>` to work, `<id>` should be `mapick` or any installed Skill ID.\n\n### Render `*:plan`\n\nWhen shell returns `{intent: \"*:plan\", commands, what_it_does, what_it_doesnt, stops}`:\n\nEach entry in `commands[]` has a `kind` field (default `\"command\"` if absent):\n- `kind: \"command\"` — render the literal `command` string in the plan box.\n- `kind: \"instruction\"` — render the `instruction` text as a paraphrase prefixed with \"AI step:\".\n\n```\nI'll run:\n\n  $ <commands[0].command>           ← if kind: \"command\"\n  AI step: <commands[1].instruction>  ← if kind: \"instruction\"\n  $ <commands[2].command>\n\nWhat it does: <what_it_does>\nWhat it doesn't: <what_it_doesnt>\nTo stop later: <stops>\n\nConfirm? Reply \"确认\" / \"yes\" to proceed, or \"取消\" to abort.\n```\n\nNEVER auto-confirm. NEVER omit the `what_it_doesnt` line.\n\n### After user confirms\n\n1. For each step in `commands`:\n   - `kind: \"command\"` AND `executes_in_mapick: true` → run via `node scripts/shell.js <subcommand>`.\n   - `kind: \"command\"` (default) → run the literal `command` via your bash tool.\n   - `kind: \"instruction\"` → execute the multi-step instruction in `instruction` text. Typically this means: run a list/inspect command, parse its output, then run zero-or-more derived commands. Capture each derived command's outcome.\n   - Capture exit code + last 200 chars of stderr per command.\n2. On any failure: stop. If `after_failure_rollback`, run it. Tell user the exact failure (translate stderr).\n3. On full success: run `after_success_track`.\n4. **For `notify:plan` only — verify delivery route before claiming success.** After step 3, run `openclaw cron list --json`, find the `mapick-notify` entry, then run `openclaw chat list --json` (or the equivalent on the active OpenClaw runtime) to confirm at least one chat route is registered. If no route exists, the cron will fire but fail-close — surface this to the user explicitly:\n\n   > ⚠️ Cron is scheduled, but no chat delivery route is configured. Set up a route with `openclaw chat add ...` or notifications will silently drop.\n\n   Do NOT report a clean \"all set\" without this check passing. Otherwise, reply with one-line confirmation.\n\n5. **Delivery route verification (post-install check):** For `notify:plan` success path, explicitly guide the user when delivery is not set up:\n   - Run `openclaw chat list --json` after cron registration\n   - If `channels` array is empty or missing, show:\n     ```\n     ⚠️ 通知渠道未配置\n     \n     定时任务已创建，但没有投递目标。请选择：\n     \n     1. 添加 Telegram 频道 → `openclaw chat add --telegram <chat_id>`\n     2. 添加 Slack 频道 → `openclaw chat add --slack <channel_id>`\n     3. 暂时跳过 → 稍后运行 `/mapick notify:plan` 重新设置\n     \n     没有投递渠道，通知将无法送达。\n     ```\n   - If `channels` array has entries, show success with channel name: \"✅ 每日提醒已启用，将投递到: {channel_name}\"\n\n### Settings\n\n- `node scripts/shell.js update:settings off` — disable detection entirely.\n- `node scripts/shell.js update:settings on` — default. Detect + tell user when there are items.\n- `node scripts/shell.js notify:status` — show last notify activity + dismissal expiry.\n\nDismissal:\n- `update:dismissed notify_setup` — silent on cron-setup prompt for **14 days**.\n- `update:dismissed <skillId> [version]` — silent on that skill upgrade for **7 days**.\n\nMapick **does not install, upgrade, remove, or modify other Skills unless you explicitly confirm the action.** All install/upgrade actions show a plan before execution; rollback is supported via `backup:restore`.\n\n---\n\n## 11. Radar（机会雷达）(P2)\n\nDaily low-frequency skill gap radar. Runs silently — only speaks when it finds something.\n\n### Intent: radar\nTriggers: `/mapick radar`, triggered once per day by the AI after init.\nCommand: `node scripts/shell.js radar`\n\nReturns either:\n- `{ silent: true, reason: \"...\" }` — absolutely nothing to do. Do not render, do not acknowledge.\n- `{ silent: false, gaps: [...] }` — up to 2 skill gaps with categories.\n\n### Frequency control (automatic)\n- Max 1 run per day (`last_radar_at` cooldown).\n- Same category silent for 7 days.\n- User rejects a category 2 times → category muted for 14 days.\n\n### Rendering: radar (non-silent)\n\nLead with a single sentence that connects to something the user actually does:\n> 今天发现一个能力缺口：你最近在处理 X/Twitter 数据，但当前只有 xurl，没有通用跨平台抓取。\n\nThen for each gap (max 2), render two sentences like recommend:\n1. The gap — what you're doing without the right tool.\n2. The fix — skill name + safety badge + what manual work disappears.\n\nEnd with a single CTA:\n> 回复 1 或 2 安装，或 \"skip\" 暂时不要。\n\n### Tracking rejections\n\nWhen user says \"skip\" / \"暂时不要\" / \"no\" to a specific radar gap, call:\n```\nnode scripts/shell.js radar:reject <category>\n```\n\nThis increments the rejection counter for that category so the radar won't nag.\n\n---\n\n## Auto-trigger / First-run\n\nOn new Mapick session, run `node scripts/shell.js init` (idempotent, 30-min cooldown). Detail: `reference/lifecycle.md#auto-trigger-on-new-conversation`.\n\n**Three scenarios that MUST show taste tags:**\n\n1. **First install** — `init` returns `status: \"first_install\"`: render per §Intent: status → First install template (includes 🎯 tags as centerpiece).\n2. **Daily / periodic** — `init` returns normal status data: render a compact status line, then **always append 🎯 tags**. Make this feel like a daily fortune cookie.\n3. **Post-upgrade** — if `init` runs after a version bump: same as scenario 2, but add \"Mapick 已升级到 v<version>\" before the tags.\n\nIf CONFIG.md lacks `first_run_complete`: run `node scripts/shell.js summary`, render the summary card WITH taste tags, ask one workflow question, then on answer call `profile set` + `recommend --with-profile` + `first-run-done`. Output summary AND question in a SINGLE response.\n\n**IMPORTANT: Taste tags are MANDATORY in every init/status/summary/first-run render.** Never show just a number dump — the 🎯 line is the only thing users share. Without it, there is zero virality.\n\n### Rendering: summary card\n\n```\nmapick: 📊 Scan complete. Here's what I found.\n\n🔒 Privacy\nYour redaction engine is live — <privacy_rules> rules active.\nProvider access strings, certificates, and personal IDs → auto-stripped\nbefore any skill can see them.\n\n📦 Your skill inventory\n<total> installed — but let's be honest:\n  ✅ <active> you actually use\n  ⚠️ <never_used> you've NEVER used (why are these here?)\n  💤 <idle_30> you stopped using over a month ago\nThat's a <activation_rate> activation rate.\n\n🔥 Your heavy hitters\n1. <top_used[0].name>      <top_used[0].daily>x/day — your workhorse\n2. <top_used[1].name>      <top_used[1].daily>x/day\n3. <top_used[2].name>      <top_used[2].daily>x/day\n\n🛡️ Safety check\n<security.A> skills passed (Grade A)\n<security.B> flagged minor issues (Grade B)\n<security.C> I wouldn't trust (Grade C) — say \"security <name>\" to see why\n\n⚡ The bottom line\n<zombie_count> zombie skills are eating <context_waste_pct>% of your\ncontext window. Every conversation, your agent loads them for nothing.\n\n🔒 Outbound: anonymous device id + skill IDs you act on + timestamps.\n   Audit: /mapick privacy log    Decline: /mapick privacy consent-decline\n\n---\n🎯 你的 AI 品味：「{quantity_tag} + {efficiency_tag} + {stack_tag}」\n{brag_line}\n📤 测测你朋友的 → /mapick status\n```\n\nAfter rendering the summary card, you MUST generate the AI Taste Tags block (the 🎯 section above). Use the lookup tables under §AI Taste Tags (below) with the `total`, `active`, `never_used`, `top_used` values from the summary data. This block is MANDATORY — never skip it after a summary card, even when total <= 3 or never_used == 0. Only skip when `total == 0`.\n\nIf `never_used == 0 && idle_30 == 0`: skip negativity → \"Clean setup. Top 10%.\" If `total <= 3`: skip the zombie angle → \"Just getting started — let me find tools that match your workflow.\" If `has_backend: false`: skip the heavy-hitters + safety-check sections; say \"Backend offline; counts only.\"\n\n**After ANY summary card render (regardless of branch taken above), you MUST always append the AI Taste Tags block.** The tags section uses the same `total`, `active`, `never_used`, `top_used` fields from the summary data. Never omit it — the tags are the shareable takeaway. Only skip when `total == 0`.\n\n### AI Taste Tags (generate from summary data, no extra API call)\n\nGenerate **2–3 taste tags** from the data already returned by `summary` (`total`, `active`, `never_used`, `idle_30`, `top_used`). These tags are a lightweight day-1 artifact — they replace nothing, they augment.\n\nIf a command response already includes `taste_tags` and `taste_fact`, render those values exactly and skip recomputing the lookup locally. This prevents arithmetic drift in the model response.\n\nTwo contexts to apply:\n\n1. **First-run summary card** — append after the summary card.\n2. **`/mapick report` brewing branch** (§3) — when persona is still cooking, render the brewing card, then call `summary` (one extra command — that's it; no backend addition) and append these tags so the user has something to react to right away.\n\nSkip the entire taste-tags block when `total == 0` (a fresh install with no skills installed yet — no signal to riff on).\n\nLookup tables:\n\n**Quantity** (from `total`):\n- `total >= 40` → `收藏癖 Collector`\n- `total 15–39` → `实用主义 Pragmatist`\n- `total 5–14` → `极简主义 Minimalist`\n- `total < 5` → `刚起步 Newbie`\n\n**Efficiency** (from `active / total`):\n- `< 30%` → `囤货不用型 Hoarder`\n- `30–60%` → `还在探索 Explorer`\n- `60–90%` → `效率选手 Optimizer`\n- `> 90%` → `断舍离大师 Marie Kondo`\n\n**Stack** (from `top_used[].name`):\n- contains `github` / `docker` / `k8s` → `硬核极客 Hardcore Geek`\n- contains `summarize` / `writing` / `content` → `内容创作者 Creator`\n- contains `data-analysis` / `visualization` → `数据控 Data Nerd`\n- contains `productivity` / `calendar` / `email` → `效率狂人 Productivity Freak`\n- mixed / unrecognizable → `杂食动物 Omnivore`\n\n**Bonus** (only if `never_used > 5`):\n- `装了不用协会会长 Install-and-Forget Champion`\n\nPick the **3 most interesting** (most differentiating). Rendering format:\n\n```\n🎯 你的 AI 品味：「{tag1} + {tag2} + {tag3}」\n```\n\nThen one 冷知识 line comparing to other users using `total`:\n- `total > 40` → `你装的 Skill 数量超过 82% 的用户`\n- `total > 20` → `…超过 60% 的用户`\n- `total > 10` → `…超过 40% 的用户`\n- otherwise: skip the 冷知识 line\n\nEnd with the share CTA:\n\n```\n📤 测测你朋友的 → /mapick status\n```\n\n(The `s.mapick.ai` share link will land in V2; today the CTA bounces a friend through the same first-run flow.)\n\nFull 6-step flow: `reference/flows.md#first-run-summary`.\n\n---\n\n## Command reference\n\nUser-facing:\n\n| Command                  | Purpose                                              | Trigger phrases (any language) |\n| ------------------------ | ---------------------------------------------------- | ------------------------------ |\n| `/mapick`                | Status overview (alias for `status`)                 | status, overview, dashboard, my skills |\n| `/mapick status`         | Detailed skill status                                | how am I doing, 技能状态 |\n| `/mapick scan`           | Force re-scan                                        | rescan, refresh skills |\n| `/mapick clean`          | List zombies, pick which to remove                   | zombies, dead skills, 清理 |\n| `/mapick recommend`      | Recommendations                                      | suggest skills, 缺什么, what should I install |\n| `/mapick search <kw>`    | Search skills                                        | find skill, 搜一下 |\n| `/mapick intent <desc>`  | Natural language → local keywords → search           | I need X, 有没有 Y 的工具, 帮我找 |\n| `/mapick bundle`         | Browse / install bundles                             | workflow pack, skill pack, 技能包 |\n| `/mapick security <id>`  | Safety check                                         | is X safe, security score, trust, 安全吗 |\n| `/mapick report`         | Persona report                                       | analyze me, my persona, developer type |\n| `/mapick privacy <sub>`  | status / trust / untrust / delete-all / consent-*    | privacy, 隐私, 数据保护 |\n| `/mapick workflow`       | Frequent sequences                                   | routine, pipeline, skill chain |\n| `/mapick daily`          | Daily digest                                         | today, yesterday, 今日摘要 |\n| `/mapick weekly`         | Weekly summary                                       | this week, last week, 周报 |\n| `/mapick stats`          | Global & personal stats (installs, conversions)      | statistics, 数据统计 |\n| `/mapick stats --detail` | Detailed personal stats + accuracy trend             | my stats, 个人统计, 详细统计 |\n| `/mapick stats user`     | Alias for stats --detail                             | 个人数据 |\n| `/mapick radar`          | Daily gap radar (silent when nothing to report)      | radar, 雷达, 机会 |\n| `/mapick profile clear`  | Reset workflow profile + retrigger first-run summary | reset profile, 重置配置 |\n| `/mapick diagnose`       | Show loaded version/path and workspace shadow risks  | version, loaded path, 诊断, 版本信息 |\n| `/mapick install`        | Run install.sh (Phase 1 setup)                      | install mapick, 安装 mapick, set up mapick, 配置 mapick |\n| `/mapick diagnose --install-check` | Verify installation status                 | is mapick installed, 检查安装, verify setup |\n\nInternal (AI invokes; users don't type):\n`clean:track <skillId>` · `bundle:track-installed <id>` · `summary` · `profile set/get` · `first-run-done` · `recommend --with-profile` · `recommend:track <recId> <skillId> installed` · `security:report` · `notify` · `share <reportId> <htmlFile> [locale]`\n\nDebug: `node scripts/shell.js id`, `node scripts/shell.js diagnose`.\n\n---\n\n## Errors\n\nCommon codes (full table + render templates: `reference/errors.md`):\n\n- `missing_argument` — re-prompt for the argument.\n- `protected_skill` — refuse (mapick / tasa untouchable).\n- `service_unreachable` — backend down; suggest retry later.\n- `unknown_command` — typo; suggest `/mapick help`.\n- `disabled_in_local_mode` — user previously declined. Refuse with consent-agree hint.\n- `consent_required` (HTTP 403) — render consent flow per `reference/errors.md#consent_required`.\n- `backend_consent_failed` — backend rejected consent; show actual reason; do NOT pretend or retry.\n\nRender error reason in user's language. Don't echo JSON.\n\nFile v1.0.28:README.md\n\n# Mapick\n\nThe Skill manager for OpenClaw. Recommends what you're missing, cleans\nwhat you don't use, blocks what's unsafe — without reading your project\ncode or chat history.\n\n```\nopenclaw skills install mapick\n```\n\nAfter install, talk to your agent in any language. Mapick auto-detects intent.\n\n| Say | What you get |\n| --- | --- |\n| `recommend` | Personalized recommendations based on what you've already installed |\n| `clean` · `zombies` | List of skills idle 30+ days, one reply to remove |\n| `search <keyword>` | Live ClawHub search with safety grades |\n| `is X safe?` · `security X` | Per-skill safety report; Grade-C skills surface safer alternatives |\n| `analyze me` · `report` | Developer persona based on your usage pattern |\n| `bundle` | Curated skill packs for a workflow (e.g. `fullstack-dev`) |\n\n## Privacy at a glance\n\n**Consent-first.** Mapick asks for network consent **before** any remote call.\nOn first use of `recommend`, `search`, `bundle`, `security`, or `report`, the\nskill prompts you to choose:\n\n- **Allow & remember** — all future calls proceed without prompting\n- **This time only** — one call, then ask again\n- **Local only** — no remote calls; local features only (`status`, `diagnose`, `scan`, `clean`)\n\nWithout explicit consent, no data is sent to api.mapick.ai. Local commands\nwork offline.\n\n**If you prefer opt-in**: run `/mapick privacy consent-decline` to block all\nremote calls client-side. Commands like `recommend`, `search`, and `security`\nwill return `disabled_in_local_mode` until you run `/mapick privacy consent-agree`\nto enable.\n\n**Sent**: anonymous device fingerprint (16-char hash of `hostname|os|home`) + Skill IDs you act on + timestamps.\n\n**Never sent**: chat content, arbitrary local file contents, API tokens, credentials, Skill source, environment variables.\n\n**One thing that does upload to api.mapick.ai**: persona-share. Only when you\n**explicitly confirm** \"share my persona\" after seeing the report, Mapick\nuploads a generated `/tmp/mapick-report-<id>.html` after fail-closed redaction.\nThe skill shows the full report locally first, then asks for confirmation\nbefore any upload. Retained 30 days at `mapick.ai/s/{shareId}`. Refuses upload\nif redaction is unavailable or disabled.\n\nThree opt-outs, one command each:\n\n- `/mapick privacy consent-decline` — block all remote calls client-side\n- `/mapick privacy delete-all --confirm` — wipe local state + backend records\n- `/mapick privacy log` — show every outbound HTTP request from Mapick (endpoint, field names, status, duration; never values)\n\n## What it touches\n\n| Permission | Scope (declared in SKILL.md frontmatter, enforced in code) |\n| --- | --- |\n| Network | `api.mapick.ai` only — endpoint allowlist refuses any other URL |\n| File read | `~/.openclaw/skills/` and `~/.openclaw/workspace/skills/` — scans every installed Skill's `SKILL.md` frontmatter to know what's there |\n| File write | `~/.openclaw/workspace/skills/mapick/CONFIG.md`, `~/.openclaw/skills/mapick/trash/`, `~/.mapick/cache/`, `~/.mapick/logs/` |\n| File copy on uninstall | When **you** run `uninstall <skillId> --confirm`, Mapick copies that one Skill's directory (the one being removed) into `trash/` so you can restore within 7 days. This is `fs.cpSync` on the Skill being removed — not on other Skills, not on your project files. |\n| Runtime | Node.js only. Network uses built-in `fetch`; redaction runs in-process; no subprocess execution is required. |\n\n## Trust signals\n\n- **Outbound manifest** — every HTTP request is documented inline in\n  [`scripts/lib/http.js`](scripts/lib/http.js) with method, endpoint, fields sent, and trigger.\n  Single function (`httpCall`) is the only network exit; `grep httpCall\\(` to audit.\n- **Endpoint allowlist** — Mapick refuses to call any URL outside that\n  manifest, even at runtime (returns `endpoint_not_allowed` and writes\n  `blocked: true` to the audit log).\n- **Redaction pre-flight** — every outbound JSON payload is checked against\n  20+ sensitive-pattern regex (`scripts/redact.js`) before sending. If\n  redaction is unavailable, upload is refused; if sensitive-looking values\n  are found, only the redacted body is sent and `redacted_payload: true`\n  is written to the audit log.\n- **Persona share guardrails** — share accepts only regular, non-symlink\n  `/tmp/mapick-report-<id>.html` files up to 200KB. Upload is refused if\n  redaction fails or has been disabled.\n- **Audit log** — `~/.mapick/logs/outbound.jsonl` records every request,\n  rotates at 1MB. Read with `/mapick privacy log [N]`.\n- **Skill uninstall** is two-step: `clean` only lists; `uninstall <id>`\n  requires `--confirm`, refuses protected Skills (mapick / tasa), backs\n  up to `trash/` first, auto-cleans backups older than 7 days.\n- **Updates are detect-only** — Mapick checks for new versions of itself\n  and your installed Skills, but **never installs, upgrades, removes, or\n  modifies other Skills unless you explicitly confirm**. Every install /\n  upgrade action surfaces a plan first (commands + what-it-does +\n  what-it-doesn't + how-to-stop), and the AI runs it via its bash tool\n  only after you reply \"confirm\". Mapick itself has zero subprocess\n  execution. Disable detection entirely with\n  `node scripts/shell.js update:settings off`.\n\n## Requirements\n\n- OpenClaw runtime with **Node.js 22.14+** (24 recommended; the OpenClaw runtime baseline)\n\nNo `jq`, no Mapick account, no separate Node install — OpenClaw provides the runtime.\n\n## First conversation after install\n\nThe first message you send triggers `init` automatically. You'll see:\n\n1. A quick **local** scan of what you have installed (no network)\n2. A summary card with what Mapick found — taste tags, skill counts, privacy disclosure\n3. One specific CTA — typically `clean` (if you have zombies) or `recommend` (if not)\n4. **No data is sent to api.mapick.ai during init.** The consent gate blocks all\n   remote calls until the user explicitly agrees. Commands like `recommend` and\n   `search` prompt for consent before their first use.\n\n## Source\n\n[github.com/mapick-ai/mapick](https://github.com/mapick-ai/mapick) — issues + PRs welcome.\n\n---\n\n*Mapick is open source under MIT. The audit log + endpoint allowlist are\nintentional self-constraints — Mapick refuses to expand its own attack\nsurface beyond what's declared in this file.*\n\nFile v1.0.28:_meta.json\n\n{\n  \"ownerId\": \"kn7746w2qh2emy9q8vftnqzwsd81wxsb\",\n  \"slug\": \"mapick\",\n  \"version\": \"1.0.28\",\n  \"publishedAt\": 1778231831267\n}\n\nFile v1.0.28:scripts/package.json\n\n{\n  \"type\": \"commonjs\"\n}\n\nFile v1.0.28:prompts/persona-production.md\n\n# Mapick Persona Report — Production Prompt v1.0\n\n> V1 PR-12 delivery. This is the contract the AI uses to turn\n> `GET /report/persona` output into a single self-contained HTML document\n> uploaded via `share <reportId> <htmlFile>`.\n>\n> **Do not translate this file** — it is consumed verbatim by the AI.\n\n---\n\nYou are generating a personalized developer persona report for a Mapick user.\n\nThe output is a SINGLE self-contained HTML document that will be stored for\n30 days at `mapick.ai/s/{shareId}` and viewed by the user and people they share\nit with (social media preview etc.).\n\n## Input variables\n\n- `primaryPersona` — one of 10 IDs:\n  `3am_committer` / `install_first_ask_later` / `pr_approval_hoarder` /\n  `the_paranoid` / `openclaw_lifer` / `just_in_case_club` /\n  `tldr_generator` / `serial_uninstaller` / `openclaw_maximalist` / `fresh_meat`\n- `shadowPersona` — same enum, secondary persona (may be null)\n- `dataProfile` — `{ daysUsed, conversationsCount, wordsProduced, codeReviewsCount,\n   reportsGeneratedCount, activeHoursStart, activeHoursEnd, installedSkillsCount,\n   activeSkillsCount, percentileRank, topSkills: [...] }`\n- `locale` — `en` / `zh` / `de` / `ja` / `ko` / `es` / `pt` / `fr` / ...\n\n## Output constraints (STRICT — consistent rendering across LLMs)\n\n1. **Exactly ONE `<!DOCTYPE html>` block** — no preamble, no explanation, no\n   trailing text. The entire response is valid HTML.\n2. **HTML `<head>` must contain** (in this order):\n   - `<meta charset=\"UTF-8\">`\n   - `<meta property=\"og:title\" content=\"...\">`\n   - `<meta property=\"og:description\" content=\"...\">`\n   - `<meta property=\"og:image\" content=\"https://mapick.ai/public/og-{primaryPersona}.png\">`\n   - `<meta property=\"og:url\" content=\"https://mapick.ai/s/{shareId}\">` (the AI leaves `{shareId}` as a placeholder; backend `/share/upload` replaces it after shareId is minted)\n   - `<meta property=\"og:type\" content=\"website\">`\n   - `<meta name=\"twitter:card\" content=\"summary_large_image\">`\n   - `<meta name=\"mapick:shareText\" content=\"<localized share text>\">`\n   - `<meta name=\"mapick:personaName\" content=\"<localized primary persona name>\">`\n3. **Body structure** (required `<div>` IDs for future automation):\n   - `<div id=\"persona-header\">` — persona name + emoji + matchScore %\n   - `<div id=\"shadow-persona\">` — shadow persona line (omit if null)\n   - `<div id=\"data-highlights\">` — 3-5 key numbers from `dataProfile`\n   - `<div id=\"top-skills\">` — top 3 skills list\n   - `<div id=\"share-cta\">` — \"Generate yours →\" button linking to `https://mapick.ai`\n4. **CSS**: inline only (`<style>` in `<head>`). No external `<link>` except\n   `mapick.ai`. No CSS-in-JS. No Tailwind class names assuming CDN.\n5. **Two display modes** via `.screenshot-mode` CSS class on `<body>`:\n   - default (browse): standard web card, max-width 640px\n   - `.screenshot-mode`: 1200×630 optimized for og:image snapshot\n6. **Size**: total HTML < 200KB (enforced server-side; going over returns 413).\n7. **Localization**: all user-facing text in `locale`. Do NOT leave any English\n   outside the ID strings and meta property names. Numbers/dates use locale\n   conventions (e.g. `67 Tage` not `67 days` for `de`).\n8. **Tone**: Witty but not cruel. Locale-appropriate humor. No machine-translated\n   feel. No slang that doesn't translate.\n9. **No external network**: no `<script src=\"\">` unless pointing at mapick.ai.\n   No `<iframe>`. No `fetch()` calls. No tracking pixels.\n10. **Safe HTML**: escape all `dataProfile` user-derived strings (skill names may\n    contain quotes like `\"it's-a-skill\"`) to prevent XSS in share page.\n\n## Example opening (locale=en, primaryPersona=3am_committer)\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta property=\"og:title\" content=\"I'm a 3AM Committer on Mapick\">\n  <meta property=\"og:description\" content=\"78% match · 67 days · 4 active skills\">\n  ...\n```\n\n## Failure mode\n\nIf `locale` is unrecognized, fall back to `en`. Never refuse — always produce\nvalid HTML.\n\n---\n\n*V1 by Evan (2026-04-22). Product team may extend tone/example sections.*\n\nFile v1.0.28:reference/errors.md\n\n# Error Handling & Security Red Lines\n\n## Shell Error Codes\n\n| Code | Meaning | AI Action |\n|------|---------|-----------|\n| `missing_argument` | Required arg missing | Re-prompt |\n| `protected_skill` | Tried to uninstall mapick | Refuse |\n| `service_unreachable` | Backend down | Suggest retry |\n| `disabled_in_local_mode` | Consent declined | Show opt-in |\n| `consent_required` | Backend still requires consent unexpectedly | Surface backend message/hint; do not auto-consent |\n\n## Security Red Lines (MANDATORY)\n\n| Scenario | Required Action |\n|----------|-----------------|\n| Grade C skill | **DO NOT show install button.** Show alternatives + red warning. User must acknowledge. |\n| `delete-all` request | **Re-state destructive scope.** Require second confirmation before executing. |\n| Local-only + recommend/search | Refuse with \"requires consent\" |\n| Empty search results | Show fallback template |\n\n## Bundle Failure Playbook\n\n| Failure | Action |\n|---------|--------|\n| `clawhub not found` | Stop; link openclaw.io; ask retry |\n| Network timeout | Skip current, continue; summarize |\n| Permission denied | Report path; suggest sudo |\n| \"already installed\" | Count as success |\n\nRender errors in user's language. Never echo JSON.\n\n## disabled_in_local_mode\n\nThe user previously ran `/mapick privacy consent-decline` and is now in opt-out mode. Refuse the failed remote command and tell the user how to undo:\n\n> You opted out of data sharing earlier. Run `/mapick privacy consent-agree` to resume — that's the same anonymous flow new installs are on.\n\nDo NOT silently retry. Do NOT auto-run `consent-agree` without explicit user consent (that defeats the point of the decline).\n\n## consent_required / backend_consent_failed (HTTP 403)\n\nThese should not happen in v0.0.7+ (the client-side gate is opt-out). If the backend still returns 403 after a remote call (e.g. transitional state where backend ConsentGuard hasn't been updated yet), surface the backend's `message` / `hint` directly to the user — do NOT auto-call `consent-agree`. Both errors are passed through verbatim by `httpCall`.\n\nFile v1.0.28:reference/flows.md\n\n# Multi-step Flows\n\n## Persona report\n\n1. Call `report` directly. Do **not** narrate tool selection, reference loading,\n   or internal checks to the user. The user should see only the final card or\n   final user-facing error.\n2. **If `primaryPersona.id === \"fresh_meat\"` OR `dataProfile.usageDays < 7` OR `dataProfile.totalInvocations < 50`** — render the brewing card, NOT a zeroed report:\n   ```\n   🔒 Your persona is brewing...\n\n   Need 7 days of usage data to generate an accurate profile.\n   You're on day <usageDays>, <7 - usageDays> to go.\n\n   What we know so far:\n   - Installed <skillsCount> skills on day 1\n     (that's <more/fewer/about average> compared to other users)\n   - Active hours: <timeRange>\n     (early bird? night owl? we'll see)\n\n   Come back in <remaining> days, or just say \"analyze me\" anytime.\n   ```\n   Do NOT generate HTML share page for incomplete data.\n3. Otherwise render localized persona report from `dataProfile`. Short and witty — one screen. Use user's `locale`.\n4. **Do NOT automatically generate or upload a share page.** After rendering the report, ask the user: _\"Share this persona report? It will upload a summary to mapick.ai and return a shareable link (retained 30 days).\"_ Wait for **explicit** user confirmation (\"yes\"/\"share it\"/\"ok\") before proceeding to step 5.\n5. Only if user confirmed: Generate **self-contained HTML share page** per `prompts/persona-production.md`. Save to `/tmp/mapick-report-{reportId}.html`.\n6. Call `share <reportId> <tmpFile> <locale>`. Show returned `shareUrl` with CTA.\n\n## Security score\n\n1. Call `security <skillId>` — backend returns either:\n   - **Hit**: `{ matched: true, safetyGrade, signals, alternatives[], detailsEn, lastScannedAt }`\n   - **Fuzzy / not found**: `{ matched: false, query, message, suggestions: [{skillId, skillName, description}, ...] }`\n\n2. **`matched === false`** → render \"did you mean\" template. See `reference/rendering.md#security`.\n\n3. **`matched === true`** — localize `detailsEn` and apply Grade A/B/C display rule. See `reference/rendering.md#security`.\n\n## security:report\n\n1. Ask user to pick a reason (translated): `suspicious_network` · `data_exfiltration` · `malicious_code` · `misleading_function` · `other`.\n2. Ask for evidence (≥10 chars). Translate to English if needed.\n3. Call `security:report <skillId> <reason> <englishEvidence>`.\n4. Report returned `reportId`; tell user Mapick reviews within 48h.\n\n## Bundle two-step install\n\n**Step 1**: `bundle:install <bundleId>` returns:\n```json\n{ \"intent\": \"bundle:install\", \"bundleId\": \"fullstack-dev\",\n  \"installCommands\": [\n    { \"skillId\": \"github-ops\",     \"command\": \"clawhub install github-ops\" },\n    { \"skillId\": \"docker-compose\", \"command\": \"clawhub install docker-compose\" }\n  ], \"installed\": false }\n```\n\n**Step 2**: For each entry, **resolve the canonical slug** per the SKILL.md §1 Install command rule (prefer `installCommands[i].skillId` short form; fall back to last segment of `skillssh:org/repo/skill`; refuse if neither produces a clean short name). Then run `openclaw skills install <slug>` for each — **NEVER** execute the raw `installCommands[i].command` string verbatim, since malformed payloads (`clawhub install skillssh:soultrace-ai/soultrace-skill/soultrace`) leak the same way the recommend install path does. Track per-skill result, then call `bundle:track-installed <bundleId>`.\n\n**Step 3**: Report \"Installed N of M skills from bundle <name>.\"\n\nIf **all** commands fail, **do not** call `bundle:track-installed`.\n\nRendering: skill names + ✅ installed / ⚠️ failed (short reason). User's language.\n\n### Failure playbook\n\n| Failure                      | What to do                                                                  |\n| ---------------------------- | --------------------------------------------------------------------------- |\n| `clawhub: command not found` | Stop; tell user OpenClaw CLI is missing (https://openclaw.io); ask to retry |\n| Network timeout / DNS fail   | Skip current, continue next; summarize failures at end with retry hint      |\n| Permission denied            | Report directory; suggest `sudo` or writable path; don't auto-sudo          |\n| \"already installed\" (exit 0) | Count as success                                                            |\n| Unknown error                | Report first 200 chars of stderr; continue with remaining commands          |\n\n## First-run summary\n\nAfter init, if CONFIG.md lacks `first_run_complete`:\n\n1. Run `bash shell summary`.\n2. Display `data` payload as the summary card (see `reference/rendering.md#summary-card`) in user's language.\n3. Immediately after, ask (same response):\n   \"Quick question — what does your typical work day look like? This helps me recommend skills that match YOUR workflow, not just what's popular.\" (2 examples, offer skip)\n4. If user describes workflow:\n   - `bash shell profile set \"<answer verbatim>\"`\n   - `bash shell recommend --with-profile`\n   - For each rec, connect to user's words: \"You said you review PRs → code-review automates that\".\n   - Mark covered tasks: \"You said bug tracking → you already have github ✅\".\n   - End: \"Filling these N gaps covers your full workflow. Reply 'install all' or pick numbers.\"\n5. If skipped: `bash shell profile set \"skipped\"`, proceed normally.\n6. `bash shell first-run-done` (one-time flag).\n\nIf `first_run_complete` exists: skip all of the above.\n\n**IMPORTANT**: Output summary AND question in a SINGLE response.\n\nFile v1.0.28:reference/intents.md\n\n# Intent Triggers\n\nAll intents match via semantic similarity.\n\n## recommend\nrecommend, suggest, discover, what should I install\n\n## search\nsearch, find, look for\n\n## privacy\nprivacy, redact, delete my data, forget me\n\n## persona/report\nanalyze me, my persona, roast me\n\n## security\nis X safe, security score, trust\n\n## bundle\nbundle, pack, workflow pack\n\n## workflow\nworkflow, routine, skill chain\n\n## clean\nclean, zombies, unused\n\n## cost/savings\ncost, save money, budget\n\n## Fallback\n\nIf no keyword matches, use semantic context:\n- \"帮我选\" → recommend (selection context)\n- \"省钱\" → recommend (cost context)\n\nFile v1.0.28:reference/lifecycle.md\n\n# Skill Lifecycle Model\n\n```\nInstall → First use → Active → Declining → Zombie → Uninstall\n```\n\n| Stage | Trigger | Behavior |\n|-------|---------|----------|\n| Install | Skill directory exists | Record install time |\n| First use | First invocation | Measure activation delay |\n| Active | ≥2 calls in 7 days | Compute frequency |\n| Declining | This week < 50% of last | Internal flag |\n| Zombie | No call in 30 days | Surface in `clean` |\n| Uninstall | User-triggered | Backup to `trash/` |\n\nActivation rate = `active_skills / total_installed` (report as %)\n\n## Privacy model: consent-first\n\nMapick asks for network consent **before** any remote call. On first install, `recommend` / `search` / `bundle` / `security` / `report` require the user to explicitly choose one of:\n- **Allow & remember** (`network_consent: always`) — all future calls proceed without prompting\n- **This time only** (`network_consent: once`) — one call, then ask again next time\n- **Local only** (`network_consent: declined`) — no remote calls; local features only\n\nWithout explicit consent, the skill operates in local-only mode: `status`, `diagnose`, `doctor`, `scan`, `clean` (heuristic), and `security` (local pattern scan) all work offline. No data is sent to api.mapick.ai until the user agrees.\n\nTo audit outbound requests: `/mapick privacy log`. To withdraw consent: `/mapick privacy consent-decline`.\n\n## Decline / re-enable flow\n\nIf the user runs `/mapick privacy consent-decline`:\n- CONFIG.md gets `consent_declined: true`.\n- Remote commands (`recommend` / `search` / `bundle install` / `recommend:track` / `privacy trust` / `report` / `share` / `security` / `security:report` / `clean:track` / `workflow` / `daily` / `weekly`) are refused **client-side** with `error: \"disabled_in_local_mode\"`.\n- Local commands (`status` / `scan` / `clean` reading local mtime only / `uninstall` / `privacy status` / `privacy delete-all` / `privacy log`) keep working.\n- `notify` cron is not re-registered on subsequent inits.\n\nTo resume data sharing, run `/mapick privacy consent-agree`. Clears the declined flag, re-registers the notify cron, and remote commands work again.\n\n## Auto-trigger on new conversation\n\nWhen AI detects a new Mapick session, it may auto-run `bash shell init` (idempotent, 30-min cooldown). This only performs **local** operations:\n- `first_install` → render the Welcome card per `reference/rendering.md#first_install`.\n- `rescanned`, `changed: true` → briefly mention what changed.\n- `rescanned`, `changed: false` / `skip` → silent.\n\n**No remote calls are made during auto-init.** The `init` handler does not call any external API. Network-consent gated commands (`recommend`, `search`, etc.) are only invoked when the user explicitly asks for them, and the consent gate blocks them until the user agrees.\n\nThe `notify` cron is only registered when the user explicitly runs `privacy consent-agree` — the consent agreement handler includes the cron registration plan. If consent is declined, the cron is never registered and is removed on subsequent inits.\n\nFile v1.0.28:reference/rendering.md\n\n# Rendering Rules\n\nDetailed rendering templates for each Mapick command. Load when SKILL.md\nsection needs more detail.\n\n## recommend\n\nWhen shell returns `{ intent: \"recommend\", items: [...] }`:\n\n1. **Filter `score < 0.4`** — too weak to surface.\n2. **Open with a problem statement**, not a catalog. Say what GAP the user has, not \"I found N skills\":\n   \"You have github but no review tool — your PRs are all manual.\"\n   If no profile exists, infer from installed skills.\n3. **Show 3 items max.** For each, render exactly TWO sentences — no tables, no bulleted field lists:\n   - **Sentence 1 — the gap**: one concrete thing the user does manually today. Reference something they said, installed, or do. (\"You merge ~12 PRs a week and review them by eyeballing the diff.\")\n   - **Sentence 2 — the fix**: inline the skill name + safety badge (🟢A / 🟡B / 🔴C) inside prose, then say what manual work disappears. (\"Code Review 🟢A turns that into one comment per blocker.\")\n   - Append install count ONLY when ≥10K, as a trailing social-proof clause (\"trusted by 23K teams\"). Never as a separate field.\n   - Grade C → use `alternatives[0]` instead and write the same two sentences about it.\n4. **Close with total impact + CTA**: \"These three close your <area> loop. Reply 1 / 2 / 3 to install, or 'install all'.\"\n\n**NEVER** show raw `score` numbers, or render as a markdown table or bulleted field list like `- Skill — benefit — 🟢A — 23K installs` (catalog form).\n\n✅ Right (gap → fix, two sentences, badge inlined):\n```\n1. You merge ~12 PRs a week and review them by eyeballing the diff.\n   Code Review 🟢A turns that into one comment per blocker, trusted by 23K teams.\n```\n\nThe user should feel \"this is for ME\", not \"here are some products\".\n\n## search\n\nIf `items` is empty (or `emptyReason: \"no_matches\"`), render (translate):\n```\nI couldn't find any skills matching \"<query>\". Try:\n\n- A broader keyword — \"git\" instead of \"github-ops-advanced\"\n- A category — \"testing\" / \"deployment\" / \"analytics\"\n- Or let me recommend based on what you already have: /mapick recommend\n\nGot a skill name in mind but spelled differently? Tell me and I'll search again.\n```\n\nOtherwise render like `recommend` (same score filter, same badges, 3-5 items max).\n\n## privacy:status\n\nShort table: mode + remote access + consent version/agreed-at + trusted skills\n(bullets) + redaction engine name.\n\n- If `mode: \"default_on\"` / `remote_access: \"enabled\"`: say Mapick is using the default anonymous sharing mode; no account, code, chat content, API tokens, or credentials are uploaded. Mention `/mapick privacy log` and `/mapick privacy consent-decline`.\n- If `consent.declined: true`: \"You declined data sharing. Mapick is in local-only mode.\" Close with: \"Resume: `/mapick privacy consent-agree`.\"\n- Always close destructive deletion separately: \"Delete everything: ask me to run `privacy delete-all`.\"\n\n## privacy:delete-all\n\nBefore executing, **re-state destructive scope** in user's language:\n\n> This will delete: local CONFIG.md, scan cache, recommendations cache, trash folder, AND your data on Mapick's backend (events, skill records, consents, trusted skills, recommendation feedback, share reports). It cannot be undone.\n\nOnly after user confirms a second time, run `bash shell privacy delete-all --confirm`. Report which tables were cleared.\n\n## security\n\nWhen `matched === false`:\n```\nI couldn't find an exact safety report for \"<query>\". A few related skills you might mean:\n\n1. <suggestions[0].skillName> — <description>\n2. <suggestions[1].skillName> — <description>\n3. ...\n\nTell me a number (or the name) and I'll pull its safety report.\n```\nWhen user picks one, re-call `security <picked.skillId>`.\n\nWhen `matched === true`, localize `detailsEn` and apply Display rule (STRICT):\n\n- **Grade A**: celebrate. \"✅ Clean bill of health. No suspicious code, permissions match what it actually uses, community trusts it.\" Make user feel good.\n- **Grade B**: create tension. \"⚠️ Not a dealbreaker, but worth knowing...\" Explain what specific signals are elevated. (\"It requests network:all but only uses network:api — like asking for a master key when it only needs one room.\") End: \"Install anyway, or check the alternative?\"\n- **Grade C**: **dramatic reveal.** \"🚫 I would NOT install this.\" Lead with worst finding first (eval(), rm -rf, data exfil pattern). Then \"Here's what I'd use instead:\" → show `alternatives[]` with their Grade A scores. **DO NOT show the C-grade skill as installable.**\n- `lastScannedAt` is null: \"⚠️ This skill hasn't been scanned yet. That doesn't mean it's bad — nobody's checked. Proceed with caution or wait for a scan.\"\n\n## status\n\n**Output two blocks. Block 2 is the most important.**\n\n**Block 1 — Verdict (1-2 lines max):**\n1. Lead with a verdict, not a dashboard.\n2. Surface one hidden insight.\n3. End with one specific action.\n\n**Block 2 — AI Taste Tags (MANDATORY):**\n```\n🎯 你的 AI 品味：「{tag1} + {tag2} + {tag3}」\n{brag_line}\n📤 测测你朋友的 → /mapick status\n```\nGenerate tags from the shell response using lookup tables in SKILL.md §AI Taste Tags. Only skip when `total == 0`.\n\nBlock 1 is context. Block 2 is what users share. Never output only Block 1.\n\n## first_install\n\nShell returns:\n```json\n{\n  \"status\": \"first_install\",\n  \"data\": { \"skillsCount\": 3, \"skillNames\": [\"tasa\", \"mapick\", \"stage\"] },\n  \"privacy\": \"Anonymous by design. No registration. ...\"\n}\n```\n\nRender in user's language:\n\n1. Greet warmly, one sentence. (\"🎉 Mapick 已就绪！扫描到 <skillsCount> 个 Skill。\")\n\n2. **Immediately show AI Taste Tags as the centerpiece.** This is the user's day-1 identity reveal — the moment they go \"whoa, I want to share this\". Generate tags from the summary data per the lookup tables in SKILL.md §Auto-trigger / First-run → AI Taste Tags:\n   ```\n   🎯 你的 AI 品味：「{tag1} + {tag2} + {tag3}」\n   {brag_line}\n   📤 测测你朋友的 → /mapick status\n   ```\n\n3. One next step: \"Try `/mapick recommend` to find your next skill.\"\n\n4. Include `privacy` line verbatim.\n\n**Do not** render any ASCII logo, prompt for registration, or auto-call follow-up commands.\n\n## clean\n\n1. **Open with impact, not count.** Not \"Found N zombie skills\" but: \"Your agent is carrying N dead skills. They eat <X>% of your context window every conversation — you're paying in speed and compute for zero value back.\"\n\n2. **Split into two groups:**\n   - \"Never used (why did you install these?):\" — 0 calls. Show install date: \"installed 61 days ago, never once used\".\n   - \"Used to be useful:\" — calls but idle 30+ days. Show last use date: \"last used 47 days ago\".\n\n3. **Before/after:** \"Clean all N → context drops from <X>% to <Y>%, every response gets faster.\"\n\n4. **Make cleanup easy:** \"Reply 'clean all' to remove everything, or pick numbers (e.g. '1-8 15 17').\"\n\nGoal: user feels slightly embarrassed about hoarding, then satisfied after cleaning. Like clearing 47GB of phone storage.\n\nWhen user replies:\n- Numbers (`1 2`) → look up skillIds from last rendered list, call `clean:track <skillId>` for each, then `uninstall <skillId> --confirm`.\n- `all` → apply to every zombie.\n- `skip` → end; reply \"ok\".\n\n**Do not** ask for a reason. Reason is `zombie_cleanup` (handled server-side).\n\n## notify (silence-first)\n\n1. **`alerts: []` → output absolutely nothing.** No \"all clear\", no acknowledgement. Empty AI output ⇒ no Telegram/Slack/etc message delivered.\n2. **`alerts` non-empty** → single concise message (≤6 lines), friendly tone:\n   - `version`: one line — what's out, why upgrade is worth 30 seconds. Include `upgradeCmd`.\n   - `zombies`: one line — N skills idle 30+ days, hint to run `/mapick clean`.\n3. **Multiple**: order by impact — zombies first, version second. Blank line between.\n\nNo JSON echo. No \"your daily Mapick check found:\" preamble. No timestamps, no run-id.\n\n## notify:plan (delivery verification)\n\n**Success with delivery route configured:**\n```\n✅ 每日提醒已启用\n\n检查时间：{checkedAt}\n投递渠道：{channel_name}\n下次运行：{next_run_time}\n\n管理提醒：/mapick notify:status\n```\n\n**Success but no delivery route:**\n```\n⚠️ 定时任务已创建，但没有投递目标\n\nMapick 会每天检查更新和僵尸 Skill，但无法通知你。\n\n请选择投递渠道：\n1. Telegram → openclaw chat add --telegram <chat_id>\n2. Slack    → openclaw chat add --slack <channel_id>\n3. 暂时跳过 → 稍后运行 /mapick notify:plan 重新设置\n\n没有投递渠道，通知将无法送达。\n```\n\n**Verification steps after `notify:plan` success:**\n1. Run `openclaw chat list --json`\n2. Check if `channels` array is non-empty\n3. If empty → render the \"no delivery route\" template above\n4. If non-empty → show channel name(s) in success message\n\n**Failure during setup:**\n```\n❌ 设置失败\n\n{error_message}\n\n常见问题：\n• cron 权限不足 → 检查 OpenClaw 配置\n• 网络问题 → 重试 /mapick notify:plan\n\n详细诊断：/mapick diagnose\n```\n\n## install.sh (post-install status)\n\n**After running install.sh successfully:**\n```\n✅ Mapick 安装完成\n\n版本：{version}\n路径：{install_path}\nNode：{node_version}\n\n下一步：\n• /mapick status     → 查看技能状态\n• /mapick recommend  → 发现缺失的 Skill\n• /mapick privacy status → 检查隐私设置\n\n遇到问题？运行 /mapick diagnose 检查环境。\n```\n\n**Installation check (diagnose --install-check):**\n```\n🔍 Mapick 安装状态\n\n✅ 已安装\n   版本：{version}\n   路径：{install_path}\n   Node：{node_version}\n   配置：{config_status}\n\n{issues}\n\n{recommendations}\n```\n\n**When issues found:**\n- `issues` array: list each issue with ⚠️ prefix\n- `recommendations` array: actionable fix for each issue\n\n**When not installed:**\n```\n❌ Mapick 未安装\n\n请运行安装脚本：\ncurl -fsSL https://get.mapick.ai/install.sh | bash\n\n或手动安装：\ngit clone https://github.com/mapick/mapick.git ~/.openclaw/skills/mapick\ncd ~/.openclaw/skills/mapick && pnpm install\n```\n\n## summary card\n\n```\nmapick: 📊 Scan complete. Here's what I found.\n\n🔒 Privacy\nYour redaction engine is live — 23 rules active.\nProvider access strings, certificates, and personal IDs → auto-stripped\nbefore any skill can see them.\nRight now, <total> skills have access to your conversations.\nAfter redaction, they see: [REDACTED].\n\n📦 Your skill inventory\n<total> installed — but let's be honest:\n  ✅ <active> you actually use\n  ⚠️ <never_used> you've NEVER used (why are these here?)\n  💤 <idle_30> you stopped using over a month ago\nThat's a <activation_rate>% activation rate.\n\n🔥 Your heavy hitters\n1. <top_used[0].name>      <top_used[0].daily>x/day — your workhorse\n2. <top_used[1].name>      <top_used[1].daily>x/day\n3. <top_used[2].name>      <top_used[2].daily>x/day\n\n🛡️ Safety check\n<security.A> skills passed (Grade A)\n<security.B> flagged minor issues (Grade B)\n<security.C> I wouldn't trust (Grade C) — say \"security <name>\" to see why\n\n⚡ The bottom line\n<zombie_count> zombie skills are eating <context_waste_pct>% of your\ncontext window. Every conversation, your agent loads them for nothing.\nClean them and everything gets faster.\n\n🔒 Outbound: anonymous device id + skill IDs you act on + timestamps.\n   Audit: /mapick privacy log    Decline: /mapick privacy consent-decline\n```\n\nIf `never_used == 0 && idle_30 == 0`: skip negativity → \"Clean setup. Everything you installed, you actually use. That puts you in the top 10%.\"\n\nIf `total <= 3`: skip zombie/cleanup angle → \"You're just getting started. Let me help you find tools that match your workflow.\"\n\nProfile may be CJK (\"后端开发，Go + K8s，看日志\") or English (\"Backend, Go + K8s, reading logs\"); `profile set` lowercases and keeps CJK terms intact.\n\nFile v1.0.28:skill-card.md\n\n## Description:\n\nMapick recommends OpenClaw skills, searches ClawHub, checks skill safety, manages privacy choices, cleans unused skills, and produces usage/persona summaries.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[sunlleyevan](https://clawhub.ai/user/sunlleyevan)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nOpenClaw users and developers use Mapick to find missing skills, get personalized recommendations, review safety signals, control network consent, clean unused skills, and inspect outbound privacy activity.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The security evidence marks the skill as suspicious because its recommendation purpose involves broad local, network, install, shell-plan, and session-log authority.\n\nMitigation: Review before installing, prefer the OpenClaw install path, and grant network access only after understanding the consent prompt and outbound data categories.\n\nRisk: Flows can propose install, uninstall, upgrade, cron, or shell-plan actions that affect local skills or agent behavior.\n\nMitigation: Require explicit user confirmation, inspect proposed commands before execution, and avoid raw installer commands or unreviewed plan execution.\n\nRisk: Token statistics and privacy-log features may read local OpenClaw session or Mapick log data.\n\nMitigation: Avoid token statistics unless local session-log reads are acceptable, and use the privacy log to inspect outbound endpoint names and field names without exposing values.\n\n## Reference(s):\n\n- [Mapick ClawHub skill page](https://clawhub.ai/sunlleyevan/skills/mapick)\n- [Mapick publisher profile](https://clawhub.ai/user/sunlleyevan)\n- [Project link from artifact README](https://github.com/mapick-ai/mapick)\n- [Flow reference](artifact/reference/flows.md)\n- [Rendering reference](artifact/reference/rendering.md)\n- [Lifecycle reference](artifact/reference/lifecycle.md)\n- [Error reference](artifact/reference/errors.md)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, shell commands, configuration, guidance, files]\n\n**Output Format:** [Markdown responses with shell command proposals and occasional generated HTML persona report files]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Shell command results are expected as single-line JSON for the agent to parse and paraphrase; persona share reports are generated locally before any user-confirmed upload.]\n\n## Skill Version(s):\n\n1.0.28 (source: server release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v1.0.27: 27 files, 93772 bytes\n\nFiles: prompts/persona-production.md (4115b), README.md (6282b), reference/errors.md (2103b), reference/flows.md (5163b), reference/intents.md (619b), reference/lifecycle.md (3080b), reference/rendering.md (11871b), scripts/lib/audit.js (1415b), scripts/lib/clean.js (10435b), scripts/lib/core.js (12315b), scripts/lib/doctor.js (6106b), scripts/lib/http.js (11624b), scripts/lib/misc.js (17953b), scripts/lib/netchk.js (2405b), scripts/lib/privacy.js (9472b), scripts/lib/radar.js (6994b), scripts/lib/recommend.js (11826b), scripts/lib/security.js (5239b), scripts/lib/skills.js (14532b), scripts/lib/token.js (5067b), scripts/lib/updates.js (17853b), scripts/package.json (25b), scripts/redact.js (4427b), scripts/shell.js (5745b), scripts/stats-dashboard.js (16497b), SKILL.md (38348b), _meta.json (126b)\n\nFile v1.0.27:SKILL.md\n\n---\nname: mapick\ndescription: Mapick — Skill recommendation & privacy protection for OpenClaw. Scans your local skills, suggests what you're missing, and keeps other skills from seeing your sensitive data.\nmetadata: { \"openclaw\": { \"emoji\": \"🔍\", \"requires\": { \"bins\": [\"node\"], \"node\": \">=22.14\" }, \"permissions\": { \"network\": [\"api.mapick.ai\"], \"file_read\": [\"~/.openclaw/skills/\",\"~/.openclaw/workspace/skills/\",\"~/.mapick/logs/\",\"~/.mapick/cache/\",\"/tmp/mapick-report-\"], \"file_write\": [\"~/.openclaw/skills/\",\"~/.openclaw/workspace/skills/\",\"~/.mapick/\",\"/tmp/mapick-report-\"] } } }\n---\n\n# Mapick\n\nPriority: **recommendation = privacy > persona > safety score > cleanup > everything else.**\n\n## Global rules\n\n- Output reference below is English — render in the user's conversation language.\n- Match every intent trigger in ANY language. Trigger lists are illustrative, not allow-lists.\n- Every `node scripts/shell.js <subcommand>` runs the Mapick Node entrypoint. Node.js (>=22.14) required.\n- Shell responses are single-line JSON. Parse it; never dump raw JSON to the user. Paraphrase errors.\n- For slash commands, never narrate internal preparation. Do not tell the user\n  you are reading SKILL.md, loading reference files, checking handlers, or\n  deciding which tool to call. Run the command and render only the final\n  user-facing result.\n- **Use the literal command names registered in `scripts/shell.js` HANDLERS — do not abbreviate or invent shorthand.** Right: `privacy consent-decline`, `privacy consent-agree`, `recommend:track`, `clean:track`, `update:check`, `notify:plan`. Wrong: `privacy decline`, `privacy agree`, `recommend track`, `update check`. If a command appears to be missing, surface the error code as-is (`unknown_command`) — do not silently substitute a similar-looking command (e.g. don't fall through to `summary` because `status` \"looked wrong\").\n\nDetailed rendering, multi-step flows, error templates, and lifecycle rules live in `reference/`. Load on demand.\n\n---\n\n## 1. Recommend / Search\n\n### Intent: recommend\nTriggers: recommend, suggest, find skill, what should I install, what am I missing.\nCommand: `node scripts/shell.js recommend [limit]` · cached 24h, force refresh with explicit limit.\n\n### Intent: search\nTriggers: search, find, look for, anything for X.\nCommand: `node scripts/shell.js search <keyword> [limit]`\n\n### Intent: intent (P1 — local gap detection)\nTriggers: user says they want to do something but don't have a skill for it (\"I need to scrape data\", \"can I deploy to k8s\", \"有没有做代码审查的\", \"帮我读 PDF\"). Also triggered by tool failures / missing capability in the current workflow.\nCommand: `node scripts/shell.js intent <natural language description>`\n\n**How it works (privacy-first):**\n1. You detect the gap from the user's natural language.\n2. Call `intent \"他们的原话\"` — Mapick extracts keywords **locally**.\n3. Only the extracted keywords are sent to the backend for search.\n4. The user's full message never leaves the machine.\n\n**Rendering:**\n- When `items` non-empty: render like `search` results (same gap→fix two-sentence style, same badge rules).\n- Lead with: \"基于你说的「{original}」，我提取了关键词「{keywords}」帮你搜了一下\" (translate to user's language).\n- When `items` empty or `notice` present: surface the extracted keywords to the user so they can refine. Suggest trying `/mapick recommend` or broadening their description.\n- NEVER show or transmit the raw `original` text — the `original` field in the response is for the AI's rendering context only.\n\nOn user pick: **resolve the canonical slug** (see Install command rule below) and run `openclaw skills install <slug>`, then `node scripts/shell.js recommend:track <recId> <skillId> installed`. NEVER pass through raw `installCommands[].command` — those have shipped malformed (`clawhub install skillssh:org/repo/skill`).\n\nOn user pick: **resolve the canonical slug** (see Install command rule below) and run `openclaw skills install <slug>`, then `node scripts/shell.js recommend:track <recId> <skillId> installed`. NEVER pass through raw `installCommands[].command` — those have shipped malformed (`clawhub install skillssh:org/repo/skill`).\n\n### Install command rule (STRICT)\n\nAlways render: `openclaw skills install <slug>`. Slug resolution uses **resolveCanonicalSlug**:\n\n**resolveCanonicalSlug(input) → slug:**\n1. If input has `slug` field → use it directly.\n2. If input has `skillId` with no path separators → use it (e.g. `code-review`).\n3. If input has `skillssh:org/repo/skill` format → extract last segment (e.g. `skillssh:soultrace-ai/soultrace-skill/soultrace` → `soultrace`).\n4. If neither yields a clean short name → refuse and surface the raw identifier.\n\n**Applies to:**\n- `/mapick recommend` → on user pick, resolve from `items[].skillId` or `items[].slug`.\n- `/mapick bundle:install <id>` → resolve each entry in `installCommands[]` before running.\n\nNEVER show or run: raw `installCommands[].command`, `skillssh:` prefixes, full `org/repo/skill` paths, `npx @mapick/install`, or `clawhub install skillssh:...`.\n\n### Rendering: recommend / search\n\nFilter `score < 0.4`. Show **3 items max**. For each item render exactly **two sentences** — no tables, no bulleted field lists:\n\n1. **Sentence 1 — the gap**: one concrete thing the user does manually today. Reference something they said, installed, or do. (\"You merge ~12 PRs a week and review them by eyeballing the diff.\")\n2. **Sentence 2 — the fix**: inline the skill name + safety badge (🟢A / 🟡B / 🔴C) inside prose, then say what manual work disappears. (\"Code Review 🟢A turns that into one comment per blocker.\")\n\nAppend install count ONLY when ≥10K, as a trailing social-proof clause (\"trusted by 23K teams\"). Never as a separate field. Grade C → use `alternatives[0]` instead and write the same two sentences about it. Open with a problem statement, not a catalog. Close with: \"These three close your <area> loop. Reply 1 / 2 / 3 to install, or 'install all'.\"\n\nNEVER show raw `score` numbers, or render as a markdown table or bulleted catalog like `- Skill — benefit — 🟢A — 23K installs`. The user should feel \"this is for ME\", not \"here are some products\".\n\nFor `search` with empty `items` (or `emptyReason: \"no_matches\"`): suggest broadening keywords, picking a category, or running `recommend` instead. Otherwise render like `recommend` (3-5 items max).\n\n---\n\n## 2. Privacy\n\n### Intent: privacy\nTriggers: privacy, redact, who can see my data, delete my data, forget me, anonymous mode.\n\n### Privacy model: function-level consent (P3)\n\nMapick defaults to **prompt-on-first-use**: the first time you run a command that needs the network (recommend, search, report, etc.), Mapick asks for consent. No data is sent until you choose one of three options:\n\n- **允许并记住** (`always`) — allow all future network operations without prompting.\n- **仅这一次** (`once`) — allow this one command; prompt again next time.\n- **本地模式** (`declined`) — all remote commands disabled. Use local-only features.\n\nOnce a choice is made, it's stored in CONFIG.md. You can change it at any time:\n- `node scripts/shell.js network-consent always`\n- `node scripts/shell.js network-consent declined`\n\n### Consent dialog (P3 — render exactly)\n\nWhen shell returns `{ intent: \"network_consent_required\", ... }`, render this dialog in the user's language:\n\n```\n🔒 首次联网确认\n\nMapick 需要联网来推荐 skill。**不会发送**聊天内容、API key、文件内容。\n\n仅发送：\n• 匿名设备 ID\n• 已安装 skill 名称列表\n• 搜索关键词\n\n选择：\n1. 允许并记住 — 以后不再询问\n2. 仅这一次 — 下次再问\n3. 本地模式 — 只使用本地功能\n\n回复 1、2 或 3。\n```\n\nOn user pick:\n- **1 → \"允许并记住\"**: run `node scripts/shell.js network-consent always`, then re-run the original command.\n- **2 → \"仅这一次\"**: run `node scripts/shell.js network-consent once`, then re-run the original command. Consent expires after this command.\n- **3 → \"本地模式\"**: run `node scripts/shell.js network-consent declined`. Do NOT re-run the original command. Show local alternatives instead.\n\n### Subcommands\n- `node scripts/shell.js privacy status` — current mode (default vs declined) + trusted skills list\n- `node scripts/shell.js privacy trust <skillId>` — allow unredacted access\n- `node scripts/shell.js privacy untrust <skillId>` — revoke\n- `node scripts/shell.js privacy delete-all --confirm` — GDPR erasure (local + backend)\n- `node scripts/shell.js privacy consent-decline` — opt out: refuse remote commands client-side\n- `node scripts/shell.js privacy consent-agree` — undo a previous decline (only needed if you ran `consent-decline`)\n- `node scripts/shell.js network-consent <always|once|declined>` — set function-level network consent\n- `node scripts/shell.js privacy log [limit]` — show last N outbound HTTP entries (endpoint + field names + status, never values)\n\n### Redaction\nBefore sharing user text with another skill, call the local `scripts/redact.js`\nmodule or CLI and use only the redacted output.\nRemoves provider access strings, certificates, DB URIs, contact info, identity numbers, query params, config values. Local regex only, ~1ms. Skills in `trustedSkills` are exempt.\n\nDecline + re-enable flow: `reference/lifecycle.md`.\nStatus + delete-all rendering: `reference/rendering.md#privacy:status`, `#privacy:delete-all`.\n\n---\n\n## 3. Persona Report\n\n### Intent: report\nTriggers: analyze me, my persona, developer type, roast me.\nCommand: `node scripts/shell.js report` (alias `/mapick persona`)\n\nDo not narrate tool selection, reference loading, or internal checks. Call the\nreport command directly and render only the final card or final user-facing\nerror. Never include phrases like \"let me check\", \"according to SKILL.md\", or\nraw tool reasoning.\n\nIf `usageDays < 7` or `totalInvocations < 50` → render the brewing card (do NOT generate HTML), then **call `node scripts/shell.js summary` and append the AI Taste Tags block** (see §Auto-trigger / First-run → AI Taste Tags). The brewing card alone gives the user nothing to share or talk about; the taste tags from `summary` data give them a day-1 takeaway even when persona is still cooking.\n\nIf the `report` response contains `fallback: \"local_day1_summary\"` or `day1_summary` / `taste_tags`, render those tags immediately. This is the backend-rate-limit / backend-unavailable fallback path: do not stop at the error message, and do not generate HTML. Tell the user the full persona is still brewing, then show the local tags and summary.\n\nOtherwise (enough usage data) generate self-contained HTML per `prompts/persona-production.md`, save only to `/tmp/mapick-report-{id}.html`. **Do NOT call `share` automatically.** Instead, show the user the generated report and ask: \"要分享这个报告吗？\" (or equivalent in their language). Only call `share <reportId> /tmp/mapick-report-{id}.html <locale>` after the user explicitly confirms they want to share. Never pass any other local file path to `share`.\n\nRate limits: report daily quota is temporarily disabled; share remains 10/day per fp. HTML > 200KB → 413, regenerate shorter.\n\nFull flow + brewing card template: `reference/flows.md#persona-report`.\n\n---\n\n## 4. Security Score\n\n### Intent: security\nTriggers: is X safe, security score, can I trust X, audit X.\nCommand: `/mapick security <skillId>`\n\nBackend returns `matched: true` (with grade) or `matched: false` (with `suggestions[]`).\n\nDisplay rule (STRICT):\n- **Grade A** — celebrate. \"✅ Clean bill of health. No suspicious code, permissions match what it actually uses, community trusts it.\" Make user feel good.\n- **Grade B** — create tension. \"⚠️ Not a dealbreaker, but worth knowing...\" Explain what specific signals are elevated. (\"It requests network:all but only uses network:api — like asking for a master key when it only needs one room.\") End: \"Install anyway, or check the alternative?\"\n- **Grade C** — **dramatic reveal.** \"🚫 I would NOT install this.\" Lead with worst finding first (eval(), rm -rf, data exfil pattern). Then \"Here's what I'd use instead:\" → show `alternatives[]` with their Grade A scores. **DO NOT show the C-grade skill as installable.**\n- `lastScannedAt: null` — \"⚠️ This skill hasn't been scanned yet. That doesn't mean it's bad — nobody's checked. Proceed with caution or wait for a scan.\"\n- `local_scan: true` — backend was unreachable; the result is a local pattern-only scan. Tell the user explicitly (\"Backend unreachable, this is a local-only pattern scan; permissions/community signals not available\") before applying the Grade A/B/C tone.\n\nWhen `matched: false`, render `suggestions[]` as a numbered short list and ask which one the user meant; on pick, re-call `security <picked.skillId>`.\n\n### Intent: security:report\nTriggers: report X as malicious, flag X, X is suspicious.\nCommand: `/mapick security:report <skillId> <reason> <evidenceEn>`\n\nReasons: `suspicious_network` · `data_exfiltration` · `malicious_code` · `misleading_function` · `other`.\n\nRate limits: security 60/h, security:report 5/day, 1/day per (fp, skillId).\n\nFull flow (matched/not-matched + report steps): `reference/flows.md#security-score`.\nGrade A/B/C rendering details: `reference/rendering.md#security`.\n\n---\n\n## 5. Status / Scan\n\n### Intent: status\nTriggers: status, overview, dashboard, my skills, how am I doing.\nCommand: `node scripts/shell.js status`\n\n**If the shell response has `welcome: true` → render the Welcome card below INSTEAD of normal status. Do NOT skip the welcome card, even if the user has sent status before.**\n\n**Welcome card (P0 — mandatory, render exactly as specified):**\n\n```\n🎉 Mapick 已启动\n\n我会帮你：\n• 发现缺失的 skills（本地识别能力缺口，不上传聊天内容）\n• 检查隐私设置和清理闲置 skills\n• 需要联网时只发送：匿名设备 ID + skill 列表 + 搜索关键词\n\n🎯 你的 AI 品味：「{taste_tags.tags[0]} + {taste_tags.tags[1]} + {taste_tags.tags[2]}」\n{taste_tags.fact}\n{taste_tags.cta}\n\n你可以：\n• 推荐我缺什么 → /mapick recommend\n• 看隐私设置 → /mapick privacy status\n• 关闭主动提醒 → /mapick update:settings off\n```\n\n**Normal status render (welcome already shown):**\n\nLead with a one-line verdict. Surface one hidden insight. Then ALWAYS render the taste_tags from the shell response:\n```\n🎯 你的 AI 品味：「{taste_tags.tags joined by ' + '}」\n{taste_tags.fact}\n{taste_tags.cta}\n```\n\nThe shell response includes a `taste_tags` object. ALWAYS render it after the verdict:\n\n```\n🎯 你的 AI 品味：「{taste_tags.tags joined by ' + '}」\n{taste_tags.fact}\n{taste_tags.cta}\n```\n\nThe verdict (1-2 sentences) + the 🎯 block together form a complete /mapick status response. Do NOT output only the verdict.\n\n### First install (`welcome: true`)\nThe Welcome card above replaces the old first_install template. Do NOT use the old \"first_install\" template from rendering.md — always use the Welcome card when `welcome: true`.\n\n### Intent: diagnose\nTriggers: diagnose, version, loaded path, why old version, shadow, duplicate.\nCommand: `node scripts/shell.js diagnose`\n\nDo not inspect unrelated directories or narrate investigation. Render only the\nJSON returned by `diagnose`: version, loaded directory, duplicate workspace\nskill, shadow risk, and fix hint. No preamble.\n\n---\n\n## 6. Bundles\n\n### Intent: bundle\nTriggers: bundle, workflow pack, skill pack.\n\n| Input                         | Command                       |\n| ----------------------------- | ----------------------------- |\n| `/mapick bundle`              | `bundle`                      |\n| `/mapick bundle <id>`         | `bundle <id>`                 |\n| `/mapick bundle recommend`    | `bundle:recommend`            |\n| `/mapick bundle install <id>` | `bundle:install <id>`         |\n\nTwo-step install: `bundle:install <id>` returns `installCommands[]`. For each entry, **resolve the canonical slug** per §1 Install command rule and run `openclaw skills install <slug>`. NEVER execute raw `installCommands[i].command` verbatim. Then call `bundle:track-installed <id>`. If all commands fail, do NOT call track-installed.\n\nFull install flow + failure playbook: `reference/flows.md#bundle-two-step-install`.\n\n---\n\n## 7. Cleanup / Uninstall\n\n### Intent: clean\nTriggers: clean, zombies, dead skills, prune.\nCommand: `node scripts/shell.js clean`\n\n### Rendering: clean\n\n1. **Open with impact, not count.** Not \"Found N zombie skills\" but: \"Your agent is carrying N dead skills. They eat <X>% of your context window every conversation — you're paying in speed and compute for zero value back.\"\n2. **Split into two groups:**\n   - \"Never used (why did you install these?):\" — 0 calls. Show install date: \"installed 61 days ago, never once used\".\n   - \"Used to be useful:\" — calls but idle 30+ days. Show last use date: \"last used 47 days ago\".\n3. **Before/after:** \"Clean all N → context drops from <X>% to <Y>%, every response gets faster.\"\n4. **Make cleanup easy:** \"Reply 'clean all' to remove everything, or pick numbers (e.g. '1-8 15 17').\"\n\nGoal: user feels slightly embarrassed about hoarding, then satisfied after cleaning.\n\nOn user pick: numbers → look up skillIds from last list, run `clean:track <id>` then `uninstall <id> --confirm` per skill. `all` → apply to every zombie. `skip` → reply \"ok\". Reason is `zombie_cleanup` (server-side); do NOT ask the user for one.\n\n`local_heuristic: true` in the response means the backend was unreachable / the user opted out — say so explicitly (\"Backend unreachable; this is local heuristics only — last-modified > 30 days. Backend usage data not available\").\n\n### Intent: uninstall\nTriggers: uninstall, remove skill, delete skill.\nCommand: `node scripts/shell.js uninstall <skillId> --confirm`. Default `--scope both`.\n\n---\n\n## 8. Workflow / Daily / Weekly\n\n- **workflow**: `node scripts/shell.js workflow` — frequent sequences. Triggers: workflow, routine, pipeline, skill chain.\n- **daily**: `node scripts/shell.js daily` — today's digest. Triggers: daily, today, yesterday.\n- **weekly**: `node scripts/shell.js weekly` — week summary. Triggers: weekly, this week, last week.\n\nRender `/mapick daily` as a day-1-friendly snapshot, not a dry digest:\n\n1. Start with `📊 今日 Mapick 摘要`.\n2. Summarize `data.yesterday` / `message` in 1-2 lines. If activity is low or zero, say the persona data is still light, then pivot to the local snapshot.\n3. If `day1_summary` and `taste_tags` are present, render an `AI 使用快照` section and append the AI Taste Tags block (§Auto-trigger / First-run → AI Taste Tags). Use the returned `taste_tags` exactly; do not recalculate or invent a different tag. Do not call any extra API.\n4. If `data.top2Recommendations` or `recommendations` are present, show exactly two recommendations under `💡 顺手补两个 Skill`, using the recommend rendering style: one sentence for the gap, one sentence for the fix. Do not show raw scores or JSON.\n5. End with one specific CTA: install one recommendation, run `/mapick clean`, or run `/mapick report` depending on the strongest signal.\n\nWeekly can stay compact: 3-5 bullets max.\n\n---\n\n## 9. Background notify\n\nBackground notify is checked by `/mapick notify`. Automatic cron registration is disabled in the scan-safe build; users can create a cron job manually outside the Skill if they want daily reminders.\n\nOn fire/manual run: `node scripts/shell.js notify` → `GET /notify/daily-check?currentVersion=<v>`.\n\nExact slash command routing: `/mapick notify` **always** runs `node scripts/shell.js notify`. Do not run `notify:plan` unless the user explicitly asks to set up, install, enable, or configure notifications/reminders.\n\nManual `/mapick notify`: render a small card even when `alerts: []`:\n\n```\n没有新通知 ✅\n\n检查时间：<checkedAt localized>\n版本更新：无\n僵尸 Skill：无\n其他警报：无\n\n💡 顺手推荐两个 Skill\n1. <skillName> — <why this helps>\n2. <skillName> — <why this helps>\n```\n\nUse `recommendations` from the notify response. Show exactly two if available; if none are available, skip the recommendation section. Keep it short and do not show raw JSON, score, ids, or install commands unless the user asks to install.\n\nBackground cron phrasing exactly like `Run /mapick notify`: keep **silence-first** for `alerts: []` to avoid pushing empty daily messages.\n\n`alerts` non-empty → ≤6 lines, friendly tone, version first then zombies.\n\nTemplates: `reference/rendering.md#notify-silence-first`.\n\n---\n\n## 10. Updates & Notify Setup\n\n### Intent: check / set up reminders / upgrade\nTriggers: any update?, what's outdated, check updates, set up daily reminders, notify me when updates, 帮我装 notify, 升级 mapick, 把可升级的都升级, 关闭更新提醒.\n\nMapick **detects** but **never** auto-installs/auto-upgrades. All install / upgrade / cron-setup actions return a `*:plan` JSON for the AI to render and ask the user \"确认 / cancel?\" before running. The AI runs the actual command via its bash tool — Mapick itself has zero subprocess execution.\n\n### Detect\n\nCommand: `node scripts/shell.js update:check`\n\nReturns `{intent: \"update:check\", items: [...]}`. Each item is one update opportunity:\n- `mapick_self` — Mapick has a newer version\n- `skill` — an installed Skill has a newer version (requires `/skills/check-updates` backend; fails silently if unavailable)\n- `notify_missing` — daily-notify cron not running (heuristic: `last_notify_at` empty or > 7 days old)\n\n`settings.update_mode: \"off\"` returns empty items + an explainer message. Same when `consent_declined`.\n\n`dev_build: true` on the response means the running tree is a local / unreleased build (`local-<sha>-<ts>` etc.). Mapick suppresses `mapick_self` items in that case — say \"Running a local dev build (`<installed_version>`); release-channel updates don't apply\" and only render any remaining items (`skill` / `notify_missing`).\n\n### Render `update:check`\n\nIf `items: []` and no `message`: reply \"Everything's up to date.\" If `items: []` with `message`: render the message verbatim. Otherwise:\n\n```\nFound <N> things:\n\n- Mapick v0.0.15 → v0.0.17. \"upgrade mapick\"\n- github-ops v1.2.0 → v1.3.0. \"upgrade github-ops\"\n- Daily reminders not set up. \"set up daily reminders\"\n\nReply with what you want, or \"skip\" / \"暂时不要\".\n```\n\nNEVER show raw JSON. NEVER auto-execute.\n\n### Natural-language authorization\n\nMatch user reply to `items[].next.trigger_phrases` OR semantic equivalent (any language). On match, run the item's `next.command` (which returns a `*:plan`).\n\n| User says | Run |\n| --- | --- |\n| \"upgrade mapick\" / \"升级 mapick\" | `node scripts/shell.js upgrade:plan mapick` |\n| \"upgrade <skillId>\" | `node scripts/shell.js upgrade:plan <skillId>` |\n| \"set up daily reminders\" / \"开通知\" | `node scripts/shell.js notify:plan` |\n| \"install all\" / \"全装\" | run each item's `next.command` in turn |\n| \"skip\" / \"暂时不要\" | run `node scripts/shell.js update:dismissed <id>` for each item, reply \"ok\" |\n\nFor `upgrade:plan <id>` to work, `<id>` should be `mapick` or any installed Skill ID.\n\n### Render `*:plan`\n\nWhen shell returns `{intent: \"*:plan\", commands, what_it_does, what_it_doesnt, stops}`:\n\nEach entry in `commands[]` has a `kind` field (default `\"command\"` if absent):\n- `kind: \"command\"` — render the literal `command` string in the plan box.\n- `kind: \"instruction\"` — render the `instruction` text as a paraphrase prefixed with \"AI step:\".\n\n```\nI'll run:\n\n  $ <commands[0].command>           ← if kind: \"command\"\n  AI step: <commands[1].instruction>  ← if kind: \"instruction\"\n  $ <commands[2].command>\n\nWhat it does: <what_it_does>\nWhat it doesn't: <what_it_doesnt>\nTo stop later: <stops>\n\nConfirm? Reply \"确认\" / \"yes\" to proceed, or \"取消\" to abort.\n```\n\nNEVER auto-confirm. NEVER omit the `what_it_doesnt` line.\n\n### After user confirms\n\n1. For each step in `commands`:\n   - `kind: \"command\"` AND `executes_in_mapick: true` → run via `node scripts/shell.js <subcommand>`.\n   - `kind: \"command\"` (default) → run the literal `command` via your bash tool.\n   - `kind: \"instruction\"` → execute the multi-step instruction in `instruction` text. Typically this means: run a list/inspect command, parse its output, then run zero-or-more derived commands. Capture each derived command's outcome.\n   - Capture exit code + last 200 chars of stderr per command.\n2. On any failure: stop. If `after_failure_rollback`, run it. Tell user the exact failure (translate stderr).\n3. On full success: run `after_success_track`.\n4. **For `notify:plan` only — verify delivery route before claiming success.** After step 3, run `openclaw cron list --json`, find the `mapick-notify` entry, then run `openclaw chat list --json` (or the equivalent on the active OpenClaw runtime) to confirm at least one chat route is registered. If no route exists, the cron will fire but fail-close — surface this to the user explicitly:\n\n   > ⚠️ Cron is scheduled, but no chat delivery route is configured. Set up a route with `openclaw chat add ...` or notifications will silently drop.\n\n   Do NOT report a clean \"all set\" without this check passing. Otherwise, reply with one-line confirmation.\n\n5. **Delivery route verification (post-install check):** For `notify:plan` success path, explicitly guide the user when delivery is not set up:\n   - Run `openclaw chat list --json` after cron registration\n   - If `channels` array is empty or missing, show:\n     ```\n     ⚠️ 通知渠道未配置\n     \n     定时任务已创建，但没有投递目标。请选择：\n     \n     1. 添加 Telegram 频道 → `openclaw chat add --telegram <chat_id>`\n     2. 添加 Slack 频道 → `openclaw chat add --slack <channel_id>`\n     3. 暂时跳过 → 稍后运行 `/mapick notify:plan` 重新设置\n     \n     没有投递渠道，通知将无法送达。\n     ```\n   - If `channels` array has entries, show success with channel name: \"✅ 每日提醒已启用，将投递到: {channel_name}\"\n\n### Settings\n\n- `node scripts/shell.js update:settings off` — disable detection entirely.\n- `node scripts/shell.js update:settings on` — default. Detect + tell user when there are items.\n- `node scripts/shell.js notify:status` — show last notify activity + dismissal expiry.\n\nDismissal:\n- `update:dismissed notify_setup` — silent on cron-setup prompt for **14 days**.\n- `update:dismissed <skillId> [version]` — silent on that skill upgrade for **7 days**.\n\nMapick **does not install, upgrade, remove, or modify other Skills unless you explicitly confirm the action.** All install/upgrade actions show a plan before execution; rollback is supported via `backup:restore`.\n\n---\n\n## 11. Radar（机会雷达）(P2)\n\nDaily low-frequency skill gap radar. Runs silently — only speaks when it finds something.\n\n### Intent: radar\nTriggers: `/mapick radar`, triggered once per day by the AI after init.\nCommand: `node scripts/shell.js radar`\n\nReturns either:\n- `{ silent: true, reason: \"...\" }` — absolutely nothing to do. Do not render, do not acknowledge.\n- `{ silent: false, gaps: [...] }` — up to 2 skill gaps with categories.\n\n### Frequency control (automatic)\n- Max 1 run per day (`last_radar_at` cooldown).\n- Same category silent for 7 days.\n- User rejects a category 2 times → category muted for 14 days.\n\n### Rendering: radar (non-silent)\n\nLead with a single sentence that connects to something the user actually does:\n> 今天发现一个能力缺口：你最近在处理 X/Twitter 数据，但当前只有 xurl，没有通用跨平台抓取。\n\nThen for each gap (max 2), render two sentences like recommend:\n1. The gap — what you're doing without the right tool.\n2. The fix — skill name + safety badge + what manual work disappears.\n\nEnd with a single CTA:\n> 回复 1 或 2 安装，或 \"skip\" 暂时不要。\n\n### Tracking rejections\n\nWhen user says \"skip\" / \"暂时不要\" / \"no\" to a specific radar gap, call:\n```\nnode scripts/shell.js radar:reject <category>\n```\n\nThis increments the rejection counter for that category so the radar won't nag.\n\n---\n\n## Auto-trigger / First-run\n\nOn new Mapick session, run `node scripts/shell.js init` (idempotent, 30-min cooldown). Detail: `reference/lifecycle.md#auto-trigger-on-new-conversation`.\n\n**Three scenarios that MUST show taste tags:**\n\n1. **First install** — `init` returns `status: \"first_install\"`: render per §Intent: status → First install template (includes 🎯 tags as centerpiece).\n2. **Daily / periodic** — `init` returns normal status data: render a compact status line, then **always append 🎯 tags**. Make this feel like a daily fortune cookie.\n3. **Post-upgrade** — if `init` runs after a version bump: same as scenario 2, but add \"Mapick 已升级到 v<version>\" before the tags.\n\nIf CONFIG.md lacks `first_run_complete`: run `node scripts/shell.js summary`, render the summary card WITH taste tags, ask one workflow question, then on answer call `profile set` + `recommend --with-profile` + `first-run-done`. Output summary AND question in a SINGLE response.\n\n**IMPORTANT: Taste tags are MANDATORY in every init/status/summary/first-run render.** Never show just a number dump — the 🎯 line is the only thing users share. Without it, there is zero virality.\n\n### Rendering: summary card\n\n```\nmapick: 📊 Scan complete. Here's what I found.\n\n🔒 Privacy\nYour redaction engine is live — <privacy_rules> rules active.\nProvider access strings, certificates, and personal IDs → auto-stripped\nbefore any skill can see them.\n\n📦 Your skill inventory\n<total> installed — but let's be honest:\n  ✅ <active> you actually use\n  ⚠️ <never_used> you've NEVER used (why are these here?)\n  💤 <idle_30> you stopped using over a month ago\nThat's a <activation_rate> activation rate.\n\n🔥 Your heavy hitters\n1. <top_used[0].name>      <top_used[0].daily>x/day — your workhorse\n2. <top_used[1].name>      <top_used[1].daily>x/day\n3. <top_used[2].name>      <top_used[2].daily>x/day\n\n🛡️ Safety check\n<security.A> skills passed (Grade A)\n<security.B> flagged minor issues (Grade B)\n<security.C> I wouldn't trust (Grade C) — say \"security <name>\" to see why\n\n⚡ The bottom line\n<zombie_count> zombie skills are eating <context_waste_pct>% of your\ncontext window. Every conversation, your agent loads them for nothing.\n\n🔒 Outbound: anonymous device id + skill IDs you act on + timestamps.\n   Audit: /mapick privacy log    Decline: /mapick privacy consent-decline\n\n---\n🎯 你的 AI 品味：「{quantity_tag} + {efficiency_tag} + {stack_tag}」\n{brag_line}\n📤 测测你朋友的 → /mapick status\n```\n\nAfter rendering the summary card, you MUST generate the AI Taste Tags block (the 🎯 section above). Use the lookup tables under §AI Taste Tags (below) with the `total`, `active`, `never_used`, `top_used` values from the summary data. This block is MANDATORY — never skip it after a summary card, even when total <= 3 or never_used == 0. Only skip when `total == 0`.\n\nIf `never_used == 0 && idle_30 == 0`: skip negativity → \"Clean setup. Top 10%.\" If `total <= 3`: skip the zombie angle → \"Just getting started — let me find tools that match your workflow.\" If `has_backend: false`: skip the heavy-hitters + safety-check sections; say \"Backend offline; counts only.\"\n\n**After ANY summary card render (regardless of branch taken above), you MUST always append the AI Taste Tags block.** The tags section uses the same `total`, `active`, `never_used`, `top_used` fields from the summary data. Never omit it — the tags are the shareable takeaway. Only skip when `total == 0`.\n\n### AI Taste Tags (generate from summary data, no extra API call)\n\nGenerate **2–3 taste tags** from the data already returned by `summary` (`total`, `active`, `never_used`, `idle_30`, `top_used`). These tags are a lightweight day-1 artifact — they replace nothing, they augment.\n\nIf a command response already includes `taste_tags` and `taste_fact`, render those values exactly and skip recomputing the lookup locally. This prevents arithmetic drift in the model response.\n\nTwo contexts to apply:\n\n1. **First-run summary card** — append after the summary card.\n2. **`/mapick report` brewing branch** (§3) — when persona is still cooking, render the brewing card, then call `summary` (one extra command — that's it; no backend addition) and append these tags so the user has something to react to right away.\n\nSkip the entire taste-tags block when `total == 0` (a fresh install with no skills installed yet — no signal to riff on).\n\nLookup tables:\n\n**Quantity** (from `total`):\n- `total >= 40` → `收藏癖 Collector`\n- `total 15–39` → `实用主义 Pragmatist`\n- `total 5–14` → `极简主义 Minimalist`\n- `total < 5` → `刚起步 Newbie`\n\n**Efficiency** (from `active / total`):\n- `< 30%` → `囤货不用型 Hoarder`\n- `30–60%` → `还在探索 Explorer`\n- `60–90%` → `效率选手 Optimizer`\n- `> 90%` → `断舍离大师 Marie Kondo`\n\n**Stack** (from `top_used[].name`):\n- contains `github` / `docker` / `k8s` → `硬核极客 Hardcore Geek`\n- contains `summarize` / `writing` / `content` → `内容创作者 Creator`\n- contains `data-analysis` / `visualization` → `数据控 Data Nerd`\n- contains `productivity` / `calendar` / `email` → `效率狂人 Productivity Freak`\n- mixed / unrecognizable → `杂食动物 Omnivore`\n\n**Bonus** (only if `never_used > 5`):\n- `装了不用协会会长 Install-and-Forget Champion`\n\nPick the **3 most interesting** (most differentiating). Rendering format:\n\n```\n🎯 你的 AI 品味：「{tag1} + {tag2} + {tag3}」\n```\n\nThen one 冷知识 line comparing to other users using `total`:\n- `total > 40` → `你装的 Skill 数量超过 82% 的用户`\n- `total > 20` → `…超过 60% 的用户`\n- `total > 10` → `…超过 40% 的用户`\n- otherwise: skip the 冷知识 line\n\nEnd with the share CTA:\n\n```\n📤 测测你朋友的 → /mapick status\n```\n\n(The `s.mapick.ai` share link will land in V2; today the CTA bounces a friend through the same first-run flow.)\n\nFull 6-step flow: `reference/flows.md#first-run-summary`.\n\n---\n\n## Command reference\n\nUser-facing:\n\n| Command                  | Purpose                                              | Trigger phrases (any language) |\n| ------------------------ | ---------------------------------------------------- | ------------------------------ |\n| `/mapick`                | Status overview (alias for `status`)                 | status, overview, dashboard, my skills |\n| `/mapick status`         | Detailed skill status                                | how am I doing, 技能状态 |\n| `/mapick scan`           | Force re-scan                                        | rescan, refresh skills |\n| `/mapick clean`          | List zombies, pick which to remove                   | zombies, dead skills, 清理 |\n| `/mapick recommend`      | Recommendations                                      | suggest skills, 缺什么, what should I install |\n| `/mapick search <kw>`    | Search skills                                        | find skill, 搜一下 |\n| `/mapick intent <desc>`  | Natural language → local keywords → search           | I need X, 有没有 Y 的工具, 帮我找 |\n| `/mapick bundle`         | Browse / install bundles                             | workflow pack, skill pack, 技能包 |\n| `/mapick security <id>`  | Safety check                                         | is X safe, security score, trust, 安全吗 |\n| `/mapick report`         | Persona report                                       | analyze me, my persona, developer type |\n| `/mapick privacy <sub>`  | status / trust / untrust / delete-all / consent-*    | privacy, 隐私, 数据保护 |\n| `/mapick workflow`       | Frequent sequences                                   | routine, pipeline, skill chain |\n| `/mapick daily`          | Daily digest                                         | today, yesterday, 今日摘要 |\n| `/mapick weekly`         | Weekly summary                                       | this week, last week, 周报 |\n| `/mapick stats`          | Global & personal stats (installs, conversions)      | statistics, 数据统计 |\n| `/mapick stats --detail` | Detailed personal stats + accuracy trend             | my stats, 个人统计, 详细统计 |\n| `/mapick stats user`     | Alias for stats --detail                             | 个人数据 |\n| `/mapick radar`          | Daily gap radar (silent when nothing to report)      | radar, 雷达, 机会 |\n| `/mapick profile clear`  | Reset workflow profile + retrigger first-run summary | reset profile, 重置配置 |\n| `/mapick diagnose`       | Show loaded version/path and workspace shadow risks  | version, loaded path, 诊断, 版本信息 |\n| `/mapick install`        | Run install.sh (Phase 1 setup)                      | install mapick, 安装 mapick, set up mapick, 配置 mapick |\n| `/mapick diagnose --install-check` | Verify installation status                 | is mapick installed, 检查安装, verify setup |\n\nInternal (AI invokes; users don't type):\n`clean:track <skillId>` · `bundle:track-installed <id>` · `summary` · `profile set/get` · `first-run-done` · `recommend --with-profile` · `recommend:track <recId> <skillId> installed` · `security:report` · `notify` · `share <reportId> <htmlFile> [locale]`\n\nDebug: `node scripts/shell.js id`, `node scripts/shell.js diagnose`.\n\n---\n\n## Errors\n\nCommon codes (full table + render templates: `reference/errors.md`):\n\n- `missing_argument` — re-prompt for the argument.\n- `protected_skill` — refuse (mapick / tasa untouchable).\n- `service_unreachable` — backend down; suggest retry later.\n- `unknown_command` — typo; suggest `/mapick help`.\n- `disabled_in_local_mode` — user previously declined. Refuse with consent-agree hint.\n- `consent_required` (HTTP 403) — render consent flow per `reference/errors.md#consent_required`.\n- `backend_consent_failed` — backend rejected consent; show actual reason; do NOT pretend or retry.\n\nRender error reason in user's language. Don't echo JSON.\n\nFile v1.0.27:README.md\n\n# Mapick\n\nThe Skill manager for OpenClaw. Recommends what you're missing, cleans\nwhat you don't use, blocks what's unsafe — without reading your project\ncode or chat history.\n\n```\nopenclaw skills install mapick\n```\n\nAfter install, talk to your agent in any language. Mapick auto-detects intent.\n\n| Say | What you get |\n| --- | --- |\n| `recommend` | Personalized recommendations based on what you've already installed |\n| `clean` · `zombies` | List of skills idle 30+ days, one reply to remove |\n| `search <keyword>` | Live ClawHub search with safety grades |\n| `is X safe?` · `security X` | Per-skill safety report; Grade-C skills surface safer alternatives |\n| `analyze me` · `report` | Developer persona based on your usage pattern |\n| `bundle` | Curated skill packs for a workflow (e.g. `fullstack-dev`) |\n\n## Privacy at a glance\n\n**Consent-first.** Mapick asks for network consent **before** any remote call.\nOn first use of `recommend`, `search`, `bundle`, `security`, or `report`, the\nskill prompts you to choose:\n\n- **Allow & remember** — all future calls proceed without prompting\n- **This time only** — one call, then ask again\n- **Local only** — no remote calls; local features only (`status`, `diagnose`, `scan`, `clean`)\n\nWithout explicit consent, no data is sent to api.mapick.ai. Local commands\nwork offline.\n\n**If you prefer opt-in**: run `/mapick privacy consent-decline` to block all\nremote calls client-side. Commands like `recommend`, `search`, and `security`\nwill return `disabled_in_local_mode` until you run `/mapick privacy consent-agree`\nto enable.\n\n**Sent**: anonymous device fingerprint (16-char hash of `hostname|os|home`) + Skill IDs you act on + timestamps.\n\n**Never sent**: chat content, arbitrary local file contents, API tokens, credentials, Skill source, environment variables.\n\n**One thing that does upload to api.mapick.ai**: persona-share. When you ask\nMapick to \"share my persona\", it uploads a Mapick-generated\n`/tmp/mapick-report-<id>.html` after fail-closed redaction. This is the\nonly path where an HTML payload (rather than just identifiers) leaves\nyour machine. Refuses upload if redaction is unavailable or disabled.\n\nThree opt-outs, one command each:\n\n- `/mapick privacy consent-decline` — block all remote calls client-side\n- `/mapick privacy delete-all --confirm` — wipe local state + backend records\n- `/mapick privacy log` — show every outbound HTTP request from Mapick (endpoint, field names, status, duration; never values)\n\n## What it touches\n\n| Permission | Scope (declared in SKILL.md frontmatter, enforced in code) |\n| --- | --- |\n| Network | `api.mapick.ai` only — endpoint allowlist refuses any other URL |\n| File read | `~/.openclaw/skills/` and `~/.openclaw/workspace/skills/` — scans every installed Skill's `SKILL.md` frontmatter to know what's there |\n| File write | `~/.openclaw/workspace/skills/mapick/CONFIG.md`, `~/.openclaw/skills/mapick/trash/`, `~/.mapick/cache/`, `~/.mapick/logs/` |\n| File copy on uninstall | When **you** run `uninstall <skillId> --confirm`, Mapick copies that one Skill's directory (the one being removed) into `trash/` so you can restore within 7 days. This is `fs.cpSync` on the Skill being removed — not on other Skills, not on your project files. |\n| Runtime | Node.js only. Network uses built-in `fetch`; redaction runs in-process; no subprocess execution is required. |\n\n## Trust signals\n\n- **Outbound manifest** — every HTTP request is documented inline in\n  [`scripts/lib/http.js`](scripts/lib/http.js) with method, endpoint, fields sent, and trigger.\n  Single function (`httpCall`) is the only network exit; `grep httpCall\\(` to audit.\n- **Endpoint allowlist** — Mapick refuses to call any URL outside that\n  manifest, even at runtime (returns `endpoint_not_allowed` and writes\n  `blocked: true` to the audit log).\n- **Redaction pre-flight** — every outbound JSON payload is checked against\n  20+ sensitive-pattern regex (`scripts/redact.js`) before sending. If\n  redaction is unavailable, upload is refused; if sensitive-looking values\n  are found, only the redacted body is sent and `redacted_payload: true`\n  is written to the audit log.\n- **Persona share guardrails** — share accepts only regular, non-symlink\n  `/tmp/mapick-report-<id>.html` files up to 200KB. Upload is refused if\n  redaction fails or has been disabled.\n- **Audit log** — `~/.mapick/logs/outbound.jsonl` records every request,\n  rotates at 1MB. Read with `/mapick privacy log [N]`.\n- **Skill uninstall** is two-step: `clean` only lists; `uninstall <id>`\n  requires `--confirm`, refuses protected Skills (mapick / tasa), backs\n  up to `trash/` first, auto-cleans backups older than 7 days.\n- **Updates are detect-only** — Mapick checks for new versions of itself\n  and your installed Skills, but **never installs, upgrades, removes, or\n  modifies other Skills unless you explicitly confirm**. Every install /\n  upgrade action surfaces a plan first (commands + what-it-does +\n  what-it-doesn't + how-to-stop), and the AI runs it via its bash tool\n  only after you reply \"confirm\". Mapick itself has zero subprocess\n  execution. Disable detection entirely with\n  `node scripts/shell.js update:settings off`.\n\n## Requirements\n\n- OpenClaw runtime with **Node.js 22.14+** (24 recommended; the OpenClaw runtime baseline)\n\nNo `jq`, no Mapick account, no separate Node install — OpenClaw provides the runtime.\n\n## First conversation after install\n\nThe first message you send triggers `init` automatically. You'll see:\n\n1. A quick **local** scan of what you have installed (no network)\n2. A summary card with what Mapick found — taste tags, skill counts, privacy disclosure\n3. One specific CTA — typically `clean` (if you have zombies) or `recommend` (if not)\n4. **No data is sent to api.mapick.ai during init.** The consent gate blocks all\n   remote calls until the user explicitly agrees. Commands like `recommend` and\n   `search` prompt for consent before their first use.\n\n## Source\n\n[github.com/mapick-ai/mapick](https://github.com/mapick-ai/mapick) — issues + PRs welcome.\n\n---\n\n*Mapick is open source under MIT. The audit log + endpoint allowlist are\nintentional self-constraints — Mapick refuses to expand its own attack\nsurface beyond what's declared in this file.*\n\nFile v1.0.27:_meta.json\n\n{\n  \"ownerId\": \"kn7746w2qh2emy9q8vftnqzwsd81wxsb\",\n  \"slug\": \"mapick\",\n  \"version\": \"1.0.27\",\n  \"publishedAt\": 1778230831584\n}\n\nFile v1.0.27:scripts/package.json\n\n{\n  \"type\": \"commonjs\"\n}\n\nFile v1.0.27:prompts/persona-production.md\n\n# Mapick Persona Report — Production Prompt v1.0\n\n> V1 PR-12 delivery. This is the contract the AI uses to turn\n> `GET /report/persona` output into a single self-contained HTML document\n> uploaded via `share <reportId> <htmlFile>`.\n>\n> **Do not translate this file** — it is consumed verbatim by the AI.\n\n---\n\nYou are generating a personalized developer persona report for a Mapick user.\n\nThe output is a SINGLE self-contained HTML document that will be stored for\n30 days at `mapick.ai/s/{shareId}` and viewed by the user and people they share\nit with (social media preview etc.).\n\n## Input variables\n\n- `primaryPersona` — one of 10 IDs:\n  `3am_committer` / `install_first_ask_later` / `pr_approval_hoarder` /\n  `the_paranoid` / `openclaw_lifer` / `just_in_case_club` /\n  `tldr_generator` / `serial_uninstaller` / `openclaw_maximalist` / `fresh_meat`\n- `shadowPersona` — same enum, secondary persona (may be null)\n- `dataProfile` — `{ daysUsed, conversationsCount, wordsProduced, codeReviewsCount,\n   reportsGeneratedCount, activeHoursStart, activeHoursEnd, installedSkillsCount,\n   activeSkillsCount, percentileRank, topSkills: [...] }`\n- `locale` — `en` / `zh` / `de` / `ja` / `ko` / `es` / `pt` / `fr` / ...\n\n## Output constraints (STRICT — consistent rendering across LLMs)\n\n1. **Exactly ONE `<!DOCTYPE html>` block** — no preamble, no explanation, no\n   trailing text. The entire response is valid HTML.\n2. **HTML `<head>` must contain** (in this order):\n   - `<meta charset=\"UTF-8\">`\n   - `<meta property=\"og:title\" content=\"...\">`\n   - `<meta property=\"og:description\" content=\"...\">`\n   - `<meta property=\"og:image\" content=\"https://mapick.ai/public/og-{primaryPersona}.png\">`\n   - `<meta property=\"og:url\" content=\"https://mapick.ai/s/{shareId}\">` (the AI leaves `{shareId}` as a placeholder; backend `/share/upload` replaces it after shareId is minted)\n   - `<meta property=\"og:type\" content=\"website\">`\n   - `<meta name=\"twitter:card\" content=\"summary_large_image\">`\n   - `<meta name=\"mapick:shareText\" content=\"<localized share text>\">`\n   - `<meta name=\"mapick:personaName\" content=\"<localized primary persona name>\">`\n3. **Body structure** (required `<div>` IDs for future automation):\n   - `<div id=\"persona-header\">` — persona name + emoji + matchScore %\n   - `<div id=\"shadow-persona\">` — shadow persona line (omit if null)\n   - `<div id=\"data-highlights\">` — 3-5 key numbers from `dataProfile`\n   - `<div id=\"top-skills\">` — top 3 skills list\n   - `<div id=\"share-cta\">` — \"Generate yours →\" button linking to `https://mapick.ai`\n4. **CSS**: inline only (`<style>` in `<head>`). No external `<link>` except\n   `mapick.ai`. No CSS-in-JS. No Tailwind class names assuming CDN.\n5. **Two display modes** via `.screenshot-mode` CSS class on `<body>`:\n   - default (browse): standard web card, max-width 640px\n   - `.screenshot-mode`: 1200×630 optimized for og:image snapshot\n6. **Size**: total HTML < 200KB (enforced server-side; going over returns 413).\n7. **Localization**: all user-facing text in `locale`. Do NOT leave any English\n   outside the ID strings and meta property names. Numbers/dates use locale\n   conventions (e.g. `67 Tage` not `67 days` for `de`).\n8. **Tone**: Witty but not cruel. Locale-appropriate humor. No machine-translated\n   feel. No slang that doesn't translate.\n9. **No external network**: no `<script src=\"\">` unless pointing at mapick.ai.\n   No `<iframe>`. No `fetch()` calls. No tracking pixels.\n10. **Safe HTML**: escape all `dataProfile` user-derived strings (skill names may\n    contain quotes like `\"it's-a-skill\"`) to prevent XSS in share page.\n\n## Example opening (locale=en, primaryPersona=3am_committer)\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta property=\"og:title\" content=\"I'm a 3AM Committer on Mapick\">\n  <meta property=\"og:description\" content=\"78% match · 67 days · 4 active skills\">\n  ...\n```\n\n## Failure mode\n\nIf `locale` is unrecognized, fall back to `en`. Never refuse — always produce\nvalid HTML.\n\n---\n\n*V1 by Evan (2026-04-22). Product team may extend tone/example sections.*\n\nFile v1.0.27:reference/errors.md\n\n# Error Handling & Security Red Lines\n\n## Shell Error Codes\n\n| Code | Meaning | AI Action |\n|------|---------|-----------|\n| `missing_argument` | Required arg missing | Re-prompt |\n| `protected_skill` | Tried to uninstall mapick | Refuse |\n| `service_unreachable` | Backend down | Suggest retry |\n| `disabled_in_local_mode` | Consent declined | Show opt-in |\n| `consent_required` | Backend still requires consent unexpectedly | Surface backend message/hint; do not auto-consent |\n\n## Security Red Lines (MANDATORY)\n\n| Scenario | Required Action |\n|----------|-----------------|\n| Grade C skill | **DO NOT show install button.** Show alternatives + red warning. User must acknowledge. |\n| `delete-all` request | **Re-state destructive scope.** Require second confirmation before executing. |\n| Local-only + recommend/search | Refuse with \"requires consent\" |\n| Empty search results | Show fallback template |\n\n## Bundle Failure Playbook\n\n| Failure | Action |\n|---------|--------|\n| `clawhub not found` | Stop; link openclaw.io; ask retry |\n| Network timeout | Skip current, continue; summarize |\n| Permission denied | Report path; suggest sudo |\n| \"already installed\" | Count as success |\n\nRender errors in user's language. Never echo JSON.\n\n## disabled_in_local_mode\n\nThe user previously ran `/mapick privacy consent-decline` and is now in opt-out mode. Refuse the failed remote command and tell the user how to undo:\n\n> You opted out of data sharing earlier. Run `/mapick privacy consent-agree` to resume — that's the same anonymous flow new installs are on.\n\nDo NOT silently retry. Do NOT auto-run `consent-agree` without explicit user consent (that defeats the point of the decline).\n\n## consent_required / backend_consent_failed (HTTP 403)\n\nThese should not happen in v0.0.7+ (the client-side gate is opt-out). If the backend still returns 403 after a remote call (e.g. transitional state where backend ConsentGuard hasn't been updated yet), surface the backend's `message` / `hint` directly to the user — do NOT auto-call `consent-agree`. Both errors are passed through verbatim by `httpCall`.\n\nFile v1.0.27:reference/flows.md\n\n# Multi-step Flows\n\n## Persona report\n\n1. Call `report` directly. Do **not** narrate tool selection, reference loading,\n   or internal checks to the user. The user should see only the final card or\n   final user-facing error.\n2. **If `primaryPersona.id === \"fresh_meat\"` OR `dataProfile.usageDays < 7` OR `dataProfile.totalInvocations < 50`** — render the brewing card, NOT a zeroed report:\n   ```\n   🔒 Your persona is brewing...\n\n   Need 7 days of usage data to generate an accurate profile.\n   You're on day <usageDays>, <7 - usageDays> to go.\n\n   What we know so far:\n   - Installed <skillsCount> skills on day 1\n     (that's <more/fewer/about average> compared to other users)\n   - Active hours: <timeRange>\n     (early bird? night owl? we'll see)\n\n   Come back in <remaining> days, or just say \"analyze me\" anytime.\n   ```\n   Do NOT generate HTML share page for incomplete data.\n3. Otherwise render localized persona report from `dataProfile`. Short and witty — one screen. Use user's `locale`.\n4. Generate **self-contained HTML share page** per `prompts/persona-production.md`. Save to `/tmp/mapick-report-{reportId}.html`.\n5. Call `share <reportId> <tmpFile> <locale>`. Show returned `shareUrl` with CTA.\n\n## Security score\n\n1. Call `security <skillId>` — backend returns either:\n   - **Hit**: `{ matched: true, safetyGrade, signals, alternatives[], detailsEn, lastScannedAt }`\n   - **Fuzzy / not found**: `{ matched: false, query, message, suggestions: [{skillId, skillName, description}, ...] }`\n\n2. **`matched === false`** → render \"did you mean\" template. See `reference/rendering.md#security`.\n\n3. **`matched === true`** — localize `detailsEn` and apply Grade A/B/C display rule. See `reference/rendering.md#security`.\n\n## security:report\n\n1. Ask user to pick a reason (translated): `suspicious_network` · `data_exfiltration` · `malicious_code` · `misleading_function` · `other`.\n2. Ask for evidence (≥10 chars). Translate to English if needed.\n3. Call `security:report <skillId> <reason> <englishEvidence>`.\n4. Report returned `reportId`; tell user Mapick reviews within 48h.\n\n## Bundle two-step install\n\n**Step 1**: `bundle:install <bundleId>` returns:\n```json\n{ \"intent\": \"bundle:install\", \"bundleId\": \"fullstack-dev\",\n  \"installCommands\": [\n    { \"skillId\": \"github-ops\",     \"command\": \"clawhub install github-ops\" },\n    { \"skillId\": \"docker-compose\", \"command\": \"clawhub install docker-compose\" }\n  ], \"installed\": false }\n```\n\n**Step 2**: For each entry, **resolve the canonical slug** per the SKILL.md §1 Install command rule (prefer `installCommands[i].skillId` short form; fall back to last segment of `skillssh:org/repo/skill`; refuse if neither produces a clean short name). Then run `openclaw skills install <slug>` for each — **NEVER** execute the raw `installCommands[i].command` string verbatim, since malformed payloads (`clawhub install skillssh:soultrace-ai/soultrace-skill/soultrace`) leak the same way the recommend install path does. Track per-skill result, then call `bundle:track-installed <bundleId>`.\n\n**Step 3**: Report \"Installed N of M skills from bundle <name>.\"\n\nIf **all** commands fail, **do not** call `bundle:track-installed`.\n\nRendering: skill names + ✅ installed / ⚠️ failed (short reason). User's language.\n\n### Failure playbook\n\n| Failure                      | What to do                                                                  |\n| ---------------------------- | --------------------------------------------------------------------------- |\n| `clawhub: command not found` | Stop; tell user OpenClaw CLI is missing (https://openclaw.io); ask to retry |\n| Network timeout / DNS fail   | Skip current, continue next; summarize failures at end with retry hint      |\n| Permission denied            | Report directory; suggest `sudo` or writable path; don't auto-sudo          |\n| \"already installed\" (exit 0) | Count as success                                                            |\n| Unknown error                | Report first 200 chars of stderr; continue with remaining commands          |\n\n## First-run summary\n\nAfter init, if CONFIG.md lacks `first_run_complete`:\n\n1. Run `bash shell summary`.\n2. Display `data` payload as the summary card (see `reference/rendering.md#summary-card`) in user's language.\n3. Immediately after, ask (same response):\n   \"Quick question — what does your typical work day look like? This helps me recommend skills that match YOUR workflow, not just what's popular.\" (2 examples, offer skip)\n4. If user describes workflow:\n   - `bash shell profile set \"<answer verbatim>\"`\n   - `bash shell recommend --with-profile`\n   - For each rec, connect to user's words: \"You said you review PRs → code-review automates that\".\n   - Mark covered tasks: \"You said bug tracking → you already have github ✅\".\n   - End: \"Filling these N gaps covers your full workflow. Reply 'install all' or pick numbers.\"\n5. If skipped: `bash shell profile set \"skipped\"`, proceed normally.\n6. `bash shell first-run-done` (one-time flag).\n\nIf `first_run_complete` exists: skip all of the above.\n\n**IMPORTANT**: Output summary AND question in a SINGLE response.\n\nFile v1.0.27:reference/intents.md\n\n# Intent Triggers\n\nAll intents match via semantic similarity.\n\n## recommend\nrecommend, suggest, discover, what should I install\n\n## search\nsearch, find, look for\n\n## privacy\nprivacy, redact, delete my data, forget me\n\n## persona/report\nanalyze me, my persona, roast me\n\n## security\nis X safe, security score, trust\n\n## bundle\nbundle, pack, workflow pack\n\n## workflow\nworkflow, routine, skill chain\n\n## clean\nclean, zombies, unused\n\n## cost/savings\ncost, save money, budget\n\n## Fallback\n\nIf no keyword matches, use semantic context:\n- \"帮我选\" → recommend (selection context)\n- \"省钱\" → recommend (cost context)\n\nFile v1.0.27:reference/lifecycle.md\n\n# Skill Lifecycle Model\n\n```\nInstall → First use → Active → Declining → Zombie → Uninstall\n```\n\n| Stage | Trigger | Behavior |\n|-------|---------|----------|\n| Install | Skill directory exists | Record install time |\n| First use | First invocation | Measure activation delay |\n| Active | ≥2 calls in 7 days | Compute frequency |\n| Declining | This week < 50% of last | Internal flag |\n| Zombie | No call in 30 days | Surface in `clean` |\n| Uninstall | User-triggered | Backup to `trash/` |\n\nActivation rate = `active_skills / total_installed` (report as %)\n\n## Privacy model: consent-first\n\nMapick asks for network consent **before** any remote call. On first install, `recommend` / `search` / `bundle` / `security` / `report` require the user to explicitly choose one of:\n- **Allow & remember** (`network_consent: always`) — all future calls proceed without prompting\n- **This time only** (`network_consent: once`) — one call, then ask again next time\n- **Local only** (`network_consent: declined`) — no remote calls; local features only\n\nWithout explicit consent, the skill operates in local-only mode: `status`, `diagnose`, `doctor`, `scan`, `clean` (heuristic), and `security` (local pattern scan) all work offline. No data is sent to api.mapick.ai until the user agrees.\n\nTo audit outbound requests: `/mapick privacy log`. To withdraw consent: `/mapick privacy consent-decline`.\n\n## Decline / re-enable flow\n\nIf the user runs `/mapick privacy consent-decline`:\n- CONFIG.md gets `consent_declined: true`.\n- Remote commands (`recommend` / `search` / `bundle install` / `recommend:track` / `privacy trust` / `report` / `share` / `security` / `security:report` / `clean:track` / `workflow` / `daily` / `weekly`) are refused **client-side** with `error: \"disabled_in_local_mode\"`.\n- Local commands (`status` / `scan` / `clean` reading local mtime only / `uninstall` / `privacy status` / `privacy delete-all` / `privacy log`) keep working.\n- `notify` cron is not re-registered on subsequent inits.\n\nTo resume data sharing, run `/mapick privacy consent-agree`. Clears the declined flag, re-registers the notify cron, and remote commands work again.\n\n## Auto-trigger on new conversation\n\nWhen AI detects a new Mapick session, it may auto-run `bash shell init` (idempotent, 30-min cooldown). This only performs **local** operations:\n- `first_install` → render the Welcome card per `reference/rendering.md#first_install`.\n- `rescanned`, `changed: true` → briefly mention what changed.\n- `rescanned`, `changed: false` / `skip` → silent.\n\n**No remote calls are made during auto-init.** The `init` handler does not call any external API. Network-consent gated commands (`recommend`, `search`, etc.) are only invoked when the user explicitly asks for them, and the consent gate blocks them until the user agrees.\n\nThe `notify` cron is only registered when the user explicitly runs `privacy consent-agree` — the consent agreement handler includes the cron registration plan. If consent is declined, the cron is never registered and is removed on subsequent inits.\n\nFile v1.0.27:reference/rendering.md\n\n# Rendering Rules\n\nDetailed rendering templates for each Mapick command. Load when SKILL.md\nsection needs more detail.\n\n## recommend\n\nWhen shell returns `{ intent: \"recommend\", items: [...] }`:\n\n1. **Filter `score < 0.4`** — too weak to surface.\n2. **Open with a problem statement**, not a catalog. Say what GAP the user has, not \"I found N skills\":\n   \"You have github but no review tool — your PRs are all manual.\"\n   If no profile exists, infer from installed skills.\n3. **Show 3 items max.** For each, render exactly TWO sentences — no tables, no bulleted field lists:\n   - **Sentence 1 — the gap**: one concrete thing the user does manually today. Reference something they said, installed, or do. (\"You merge ~12 PRs a week and review them by eyeballing the diff.\")\n   - **Sentence 2 — the fix**: inline the skill name + safety badge (🟢A / 🟡B / 🔴C) inside prose, then say what manual work disappears. (\"Code Review 🟢A turns that into one comment per blocker.\")\n   - Append install count ONLY when ≥10K, as a trailing social-proof clause (\"trusted by 23K teams\"). Never as a separate field.\n   - Grade C → use `alternatives[0]` instead and write the same two sentences about it.\n4. **Close with total impact + CTA**: \"These three close your <area> loop. Reply 1 / 2 / 3 to install, or 'install all'.\"\n\n**NEVER** show raw `score` numbers, or render as a markdown table or bulleted field list like `- Skill — benefit — 🟢A — 23K installs` (catalog form).\n\n✅ Right (gap → fix, two sentences, badge inlined):\n```\n1. You merge ~12 PRs a week and review them by eyeballing the diff.\n   Code Review 🟢A turns that into one comment per blocker, trusted by 23K teams.\n```\n\nThe user should feel \"this is for ME\", not \"here are some products\".\n\n## search\n\nIf `items` is empty (or `emptyReason: \"no_matches\"`), render (translate):\n```\nI couldn't find any skills matching \"<query>\". Try:\n\n- A broader keyword — \"git\" instead of \"github-ops-advanced\"\n- A category — \"testing\" / \"deployment\" / \"analytics\"\n- Or let me recommend based on what you already have: /mapick recommend\n\nGot a skill name in mind but spelled differently? Tell me and I'll search again.\n```\n\nOtherwise render like `recommend` (same score filter, same badges, 3-5 items max).\n\n## privacy:status\n\nShort table: mode + remote access + consent version/agreed-at + trusted skills\n(bullets) + redaction engine name.\n\n- If `mode: \"default_on\"` / `remote_access: \"enabled\"`: say Mapick is using the default anonymous sharing mode; no account, code, chat content, API tokens, or credentials are uploaded. Mention `/mapick privacy log` and `/mapick privacy consent-decline`.\n- If `consent.declined: true`: \"You declined data sharing. Mapick is in local-only mode.\" Close with: \"Resume: `/mapick privacy consent-agree`.\"\n- Always close destructive deletion separately: \"Delete everything: ask me to run `privacy delete-all`.\"\n\n## privacy:delete-all\n\nBefore executing, **re-state destructive scope** in user's language:\n\n> This will delete: local CONFIG.md, scan cache, recommendations cache, trash folder, AND your data on Mapick's backend (events, skill records, consents, trusted skills, recommendation feedback, share reports). It cannot be undone.\n\nOnly after user confirms a second time, run `bash shell privacy delete-all --confirm`. Report which tables were cleared.\n\n## security\n\nWhen `matched === false`:\n```\nI couldn't find an exact safety report for \"<query>\". A few related skills you might mean:\n\n1. <suggestions[0].skillName> — <description>\n2. <suggestions[1].skillName> — <description>\n3. ...\n\nTell me a number (or the name) and I'll pull its safety report.\n```\nWhen user picks one, re-call `security <picked.skillId>`.\n\nWhen `matched === true`, localize `detailsEn` and apply Display rule (STRICT):\n\n- **Grade A**: celebrate. \"✅ Clean bill of health. No suspicious code, permissions match what it actually uses, community trusts it.\" Make user feel good.\n- **Grade B**: create tension. \"⚠️ Not a dealbreaker, but worth knowing...\" Explain what specific signals are elevated. (\"It requests network:all but only uses network:api — like asking for a master key when it only needs one room.\") End: \"Install anyway, or check the alternative?\"\n- **Grade C**: **dramatic reveal.** \"🚫 I would NOT install this.\" Lead with worst finding first (eval(), rm -rf, data exfil pattern). Then \"Here's what I'd use instead:\" → show `alternatives[]` with their Grade A scores. **DO NOT show the C-grade skill as installable.**\n- `lastScannedAt` is null: \"⚠️ This skill hasn't been scanned yet. That doesn't mean it's bad — nobody's checked. Proceed with caution or wait for a scan.\"\n\n## status\n\n**Output two blocks. Block 2 is the most important.**\n\n**Block 1 — Verdict (1-2 lines max):**\n1. Lead with a verdict, not a dashboard.\n2. Surface one hidden insight.\n3. End with one specific action.\n\n**Block 2 — AI Taste Tags (MANDATORY):**\n```\n🎯 你的 AI 品味：「{tag1} + {tag2} + {tag3}」\n{brag_line}\n📤 测测你朋友的 → /mapick status\n```\nGenerate tags from the shell response using lookup tables in SKILL.md §AI Taste Tags. Only skip when `total == 0`.\n\nBlock 1 is context. Block 2 is what users share. Never output only Block 1.\n\n## first_install\n\nShell returns:\n```json\n{\n  \"status\": \"first_install\",\n  \"data\": { \"skillsCount\": 3, \"skillNames\": [\"tasa\", \"mapick\", \"stage\"] },\n  \"privacy\": \"Anonymous by design. No registration. ...\"\n}\n```\n\nRender in user's language:\n\n1. Greet warmly, one sentence. (\"🎉 Mapick 已就绪！扫描到 <skillsCount> 个 Skill。\")\n\n2. **Immediately show AI Taste Tags as the centerpiece.** This is the user's day-1 identity reveal — the moment they go \"whoa, I want to share this\". Generate tags from the summary data per the lookup tables in SKILL.md §Auto-trigger / First-run → AI Taste Tags:\n   ```\n   🎯 你的 AI 品味：「{tag1} + {tag2} + {tag3}」\n   {brag_line}\n   📤 测测你朋友的 → /mapick status\n   ```\n\n3. One next step: \"Try `/mapick recommend` to find your next skill.\"\n\n4. Include `privacy` line verbatim.\n\n**Do not** render any ASCII logo, prompt for registration, or auto-call follow-up commands.\n\n## clean\n\n1. **Open with impact, not count.** Not \"Found N zombie skills\" but: \"Your agent is carrying N dead skills. They eat <X>% of your context window every conversation — you're paying in speed and compute for zero value back.\"\n\n2. **Split into two groups:**\n   - \"Never used (why did you install these?):\" — 0 calls. Show install date: \"installed 61 days ago, never once used\".\n   - \"Used to be useful:\" — calls but idle 30+ days. Show last use date: \"last used 47 days ago\".\n\n3. **Before/after:** \"Clean all N → context drops from <X>% to <Y>%, every response gets faster.\"\n\n4. **Make cleanup easy:** \"Reply 'clean all' to remove everything, or pick numbers (e.g. '1-8 15 17').\"\n\nGoal: user feels slightly embarrassed about hoarding, then satisfied after cleaning. Like clearing 47GB of phone storage.\n\nWhen user replies:\n- Numbers (`1 2`) → look up skillIds from last rendered list, call `clean:track <skillId>` for each, then `uninstall <skillId> --confirm`.\n- `all` → apply to every zombie.\n- `skip` → end; reply \"ok\".\n\n**Do not** ask for a reason. Reason is `zombie_cleanup` (handled server-side).\n\n## notify (silence-first)\n\n1. **`alerts: []` → output absolutely nothing.** No \"all clear\", no acknowledgement. Empty AI output ⇒ no Telegram/Slack/etc message delivered.\n2. **`alerts` non-empty** → single concise message (≤6 lines), friendly tone:\n   - `version`: one line — what's out, why upgrade is worth 30 seconds. Include `upgradeCmd`.\n   - `zombies`: one line — N skills idle 30+ days, hint to run `/mapick clean`.\n3. **Multiple**: order by impact — zombies first, version second. Blank line between.\n\nNo JSON echo. No \"your daily Mapick check found:\" preamble. No timestamps, no run-id.\n\n## notify:plan (delivery verification)\n\n**Success with delivery route configured:**\n```\n✅ 每日提醒已启用\n\n检查时间：{checkedAt}\n投递渠道：{channel_name}\n下次运行：{next_run_time}\n\n管理提醒：/mapick notify:status\n```\n\n**Success but no delivery route:**\n```\n⚠️ 定时任务已创建，但没有投递目标\n\nMapick 会每天检查更新和僵尸 Skill，但无法通知你。\n\n请选择投递渠道：\n1. Telegram → openclaw chat add --telegram <chat_id>\n2. Slack    → openclaw chat add --slack <channel_id>\n3. 暂时跳过 → 稍后运行 /mapick notify:plan 重新设置\n\n没有投递渠道，通知将无法送达。\n```\n\n**Verification steps after `notify:plan` success:**\n1. Run `openclaw chat list --json`\n2. Check if `channels` array is non-empty\n3. If empty → render the \"no delivery route\" template above\n4. If non-empty → show channel name(s) in success message\n\n**Failure during setup:**\n```\n❌ 设置失败\n\n{error_message}\n\n常见问题：\n• cron 权限不足 → 检查 OpenClaw 配置\n• 网络问题 → 重试 /mapick notify:plan\n\n详细诊断：/mapick diagnose\n```\n\n## install.sh (post-install status)\n\n**After running install.sh successfully:**\n```\n✅ Mapick 安装完成\n\n版本：{version}\n路径：{install_path}\nNode：{node_version}\n\n下一步：\n• /mapick status     → 查看技能状态\n• /mapick recommend  → 发现缺失的 Skill\n• /mapick privacy status → 检查隐私设置\n\n遇到问题？运行 /mapick diagnose 检查环境。\n```\n\n**Installation check (diagnose --install-check):**\n```\n🔍 Mapick 安装状态\n\n✅ 已安装\n   版本：{version}\n   路径：{install_path}\n   Node：{node_version}\n   配置：{config_status}\n\n{issues}\n\n{recommendations}\n```\n\n**When issues found:**\n- `issues` array: list each issue with ⚠️ prefix\n- `recommendations` array: actionable fix for each issue\n\n**When not installed:**\n```\n❌ Mapick 未安装\n\n请运行安装脚本：\ncurl -fsSL https://get.mapick.ai/install.sh | bash\n\n或手动安装：\ngit clone https://github.com/mapick/mapick.git ~/.openclaw/skills/mapick\ncd ~/.openclaw/skills/mapick && pnpm install\n```\n\n## summary card\n\n```\nmapick: 📊 Scan complete. Here's what I found.\n\n🔒 Privacy\nYour redaction engine is live — 23 rules active.\nProvider access strings, certificates, and personal IDs → auto-stripped\nbefore any skill can see them.\nRight now, <total> skills have access to your conversations.\nAfter redaction, they see: [REDACTED].\n\n📦 Your skill inventory\n<total> installed — but le\n\nArchive v1.0.26: 27 files, 93772 bytes\n\nFiles: prompts/persona-production.md (4115b), README.md (6282b), reference/errors.md (2103b), reference/flows.md (5163b), reference/intents.md (619b), reference/lifecycle.md (3080b), reference/rendering.md (11871b), scripts/lib/audit.js (1415b), scripts/lib/clean.js (10435b), scripts/lib/core.js (12315b), scripts/lib/doctor.js (6106b), scripts/lib/http.js (11624b), scripts/lib/misc.js (17953b), scripts/lib/netchk.js (2405b), scripts/lib/privacy.js (9472b), scripts/lib/radar.js (6994b), scripts/lib/recommend.js (11826b), scripts/lib/security.js (5239b), scripts/lib/skills.js (14532b), scripts/lib/token.js (5067b), scripts/lib/updates.js (17853b), scripts/package.json (25b), scripts/redact.js (4427b), scripts/shell.js (5745b), scripts/stats-dashboard.js (16497b), SKILL.md (38348b), _meta.json (126b)\n\nArchive v1.0.25: 27 files, 93709 bytes\n\nFiles: prompts/persona-production.md (4115b), README.md (6282b), reference/errors.md (2103b), reference/flows.md (5163b), reference/intents.md (619b), reference/lifecycle.md (3080b), reference/rendering.md (11871b), scripts/lib/audit.js (1415b), scripts/lib/clean.js (10275b), scripts/lib/core.js (12315b), scripts/lib/doctor.js (6106b), scripts/lib/http.js (11624b), scripts/lib/misc.js (17953b), scripts/lib/netchk.js (2405b), scripts/lib/privacy.js (9472b), scripts/lib/radar.js (6994b), scripts/lib/recommend.js (11826b), scripts/lib/security.js (5239b), scripts/lib/skills.js (14532b), scripts/lib/token.js (5067b), scripts/lib/updates.js (17853b), scripts/package.json (25b), scripts/redact.js (4427b), scripts/shell.js (5745b), scripts/stats-dashboard.js (16497b), SKILL.md (38348b), _meta.json (126b)\n\nArchive v1.0.24: 27 files, 93486 bytes\n\nFiles: prompts/persona-production.md (4115b), README.md (6282b), reference/errors.md (2103b), reference/flows.md (5163b), reference/intents.md (619b), reference/lifecycle.md (3080b), reference/rendering.md (11871b), scripts/lib/audit.js (1415b), scripts/lib/clean.js (10131b), scripts/lib/core.js (11891b), scripts/lib/doctor.js (6106b), scripts/lib/http.js (11624b), scripts/lib/misc.js (17953b), scripts/lib/netchk.js (2405b), scripts/lib/privacy.js (9472b), scripts/lib/radar.js (6994b), scripts/lib/recommend.js (11826b), scripts/lib/security.js (5239b), scripts/lib/skills.js (14532b), scripts/lib/token.js (5067b), scripts/lib/updates.js (17853b), scripts/package.json (25b), scripts/redact.js (4427b), scripts/shell.js (5745b), scripts/stats-dashboard.js (16497b), SKILL.md (38348b), _meta.json (126b)\n\nArchive v1.0.23: 27 files, 93478 bytes\n\nFiles: prompts/persona-production.md (4115b), README.md (6714b), reference/errors.md (2103b), reference/flows.md (5163b), reference/intents.md (619b), reference/lifecycle.md (3080b), reference/rendering.md (11871b), scripts/lib/audit.js (1415b), scripts/lib/clean.js (10131b), scripts/lib/core.js (11891b), scripts/lib/doctor.js (6106b), scripts/lib/http.js (11624b), scripts/lib/misc.js (17953b), scripts/lib/netchk.js (2405b), scripts/lib/privacy.js (9472b), scripts/lib/radar.js (6994b), scripts/lib/recommend.js (11826b), scripts/lib/security.js (5239b), scripts/lib/skills.js (13428b), scripts/lib/token.js (5067b), scripts/lib/updates.js (17853b), scripts/package.json (25b), scripts/redact.js (4427b), scripts/shell.js (5745b), scripts/stats-dashboard.js (16497b), SKILL.md (38348b), _meta.json (126b)\n\nArchive v1.0.22: 27 files, 93108 bytes\n\nFiles: prompts/persona-production.md (4115b), README.md (6811b), reference/errors.md (2103b), reference/flows.md (5163b), reference/intents.md (619b), reference/lifecycle.md (2047b), reference/rendering.md (11871b), scripts/lib/audit.js (1415b), scripts/lib/clean.js (10131b), scripts/lib/core.js (11891b), scripts/lib/doctor.js (6106b), scripts/lib/http.js (11624b), scripts/lib/misc.js (17953b), scripts/lib/netchk.js (2405b), scripts/lib/privacy.js (9472b), scripts/lib/radar.js (6994b), scripts/lib/recommend.js (11826b), scripts/lib/security.js (5239b), scripts/lib/skills.js (13428b), scripts/lib/token.js (5067b), scripts/lib/updates.js (17853b), scripts/package.json (25b), scripts/redact.js (4427b), scripts/shell.js (5745b), scripts/stats-dashboard.js (16497b), SKILL.md (38348b), _meta.json (126b)\n\nArchive v1.0.21: 27 files, 93082 bytes\n\nFiles: prompts/persona-production.md (4115b), README.md (6811b), reference/errors.md (2103b), reference/flows.md (5163b), reference/intents.md (619b), reference/lifecycle.md (2047b), reference/rendering.md (11871b), scripts/lib/audit.js (1415b), scripts/lib/clean.js (10131b), scripts/lib/core.js (11891b), scripts/lib/doctor.js (6106b), scripts/lib/http.js (11624b), scripts/lib/misc.js (17894b), scripts/lib/netchk.js (2405b), scripts/lib/privacy.js (9472b), scripts/lib/radar.js (6994b), scripts/lib/recommend.js (11826b), scripts/lib/security.js (5192b), scripts/lib/skills.js (13428b), scripts/lib/token.js (5067b), scripts/lib/updates.js (17853b), scripts/package.json (25b), scripts/redact.js (4427b), scripts/shell.js (5745b), scripts/stats-dashboard.js (16497b), SKILL.md (38348b), _meta.json (126b)\n\nArchive v1.0.20: 55 files, 387782 bytes\n\nFiles: CLAWHUB.md (6811b), install.sh (20434b), phase2_test.sh (3193b), prompts/persona-production.md (4115b), README.md (15558b), reference/errors.md (2103b), reference/flows.md (5163b), reference/intents.md (619b), reference/lifecycle.md (2047b), reference/rendering.md (11871b), revisions/INDEX.md (2312b), revisions/install-commands-bugfix/INSTALL_COMMANDS_FIX_PLAN.md (39369b), revisions/install-setup/INSTALLATION_SETUP_PLAN.md (57376b), revisions/m3-skill-bundle-2026-04/M3_Skill套装推荐_KT.md (17820b), revisions/README.md (631b), revisions/security-hardening-20260501/README.md (3008b), revisions/SLACK_FILES_INDEX.md (6431b), revisions/slack-01/slack-01-mapick-api-upgrade.md (5929b), revisions/slack-01/slack-01-mapickii-upgrade.md (4002b), revisions/slack-01/slack-01.md (16366b), revisions/slack-02/Mapick_V1.5_三大功能开发文档_KT.md (27916b), revisions/slack-02/SKILL（后台常驻_偏好设置_skill成本）提示词.md (41443b), revisions/slack-02/SKILL4-8修定.md (32095b), revisions/slack-02/slack-02.md (15911b), revisions/slack-files/MAPICK_AUDIT_2026_04_29_1c72719a_0efe_4718_af51_2c28b6aad259.md (55360b), revisions/slack-files/MAPICK_LIFECYCLE_AUDIT_2026_04_29_5fef1f80_d4eb_4d75_94b8_62a4.md (55370b), revisions/slack-files/MAPICK_ROUND3_BCD_AUDI...","readmeExcerpt":"Skill: Mapick Owner: sunlleyevan Summary: Mapick — Skill recommendation & privacy protection for OpenClaw. Scans your local skills, suggests what you're missing, and keeps other skills from seeing yo... Tags: latest:1.0.28 Version history: v1.0.28 | 2026-05-08T09:17:11.267Z | user Fixed - backup:restore: fix validateSkillId check (was returning early for valid IDs) - flows.md: persona report now requires explicit use","codeSnippets":[],"executableExamples":[{"language":"text","snippet":"🔒 首次联网确认\n\nMapick 需要联网来推荐 skill。**不会发送**聊天内容、API key、文件内容。\n\n仅发送：\n• 匿名设备 ID\n• 已安装 skill 名称列表\n• 搜索关键词\n\n选择：\n1. 允许并记住 — 以后不再询问\n2. 仅这一次 — 下次再问\n3. 本地模式 — 只使用本地功能\n\n回复 1、2 或 3。"},{"language":"text","snippet":"🎉 Mapick 已启动\n\n我会帮你：\n• 发现缺失的 skills（本地识别能力缺口，不上传聊天内容）\n• 检查隐私设置和清理闲置 skills\n• 需要联网时只发送：匿名设备 ID + skill 列表 + 搜索关键词\n\n🎯 你的 AI 品味：「{taste_tags.tags[0]} + {taste_tags.tags[1]} + {taste_tags.tags[2]}」\n{taste_tags.fact}\n{taste_tags.cta}\n\n你可以：\n• 推荐我缺什么 → /mapick recommend\n• 看隐私设置 → /mapick privacy status\n• 关闭主动提醒 → /mapick update:settings off"},{"language":"text","snippet":"🎯 你的 AI 品味：「{taste_tags.tags joined by ' + '}」\n{taste_tags.fact}\n{taste_tags.cta}"},{"language":"text","snippet":"🎯 你的 AI 品味：「{taste_tags.tags joined by ' + '}」\n{taste_tags.fact}\n{taste_tags.cta}"},{"language":"text","snippet":"没有新通知 ✅\n\n检查时间：<checkedAt localized>\n版本更新：无\n僵尸 Skill：无\n其他警报：无\n\n💡 顺手推荐两个 Skill\n1. <skillName> — <why this helps>\n2. <skillName> — <why this helps>"},{"language":"text","snippet":"Found <N> things:\n\n- Mapick v0.0.15 → v0.0.17. \"upgrade mapick\"\n- github-ops v1.2.0 → v1.3.0. \"upgrade github-ops\"\n- Daily reminders not set up. \"set up daily reminders\"\n\nReply with what you want, or \"skip\" / \"暂时不要\"."}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: mapick\ndescription: Mapick — Skill recommendation & privacy protection for OpenClaw. Scans your local skills, suggests what you're missing, and keeps other skills from seeing your sensitive data.\nmetadata: { \"openclaw\": { \"emoji\": \"🔍\", \"requires\": { \"bins\": [\"node\"], \"node\": \">=22.14\" }, \"permissions\": { \"network\": [\"api.mapick.ai\"], \"file_read\": [\"~/.openclaw/skills/\",\"~/.openclaw/workspace/skills/\",\"~/.mapick/logs/\",\"~/.mapick/cache/\",\"/tmp/mapick-report-\"], \"file_write\": [\"~/.openclaw/skills/\",\"~/.openclaw/workspace/skills/\",\"~/.mapick/\",\"/tmp/mapick-report-\"] } } }\n---\n\n# Mapick\n\nPriority: **recommendation = privacy > persona > safety score > cleanup > everything else.**\n\n## Global rules\n\n- Output reference below is English — render in the user's conversation language.\n- Match every intent trigger in ANY language. Trigger lists are illustrative, not allow-lists.\n- Every `node scripts/shell.js <subcommand>` runs the Mapick Node entrypoint. Node.js (>=22.14) required.\n- Shell responses are single-line JSON. Parse it; never dump raw JSON to the user. Paraphrase errors.\n- For slash commands, never narrate internal preparation. Do not tell the user\n  you are reading SKILL.md, loading reference files, checking handlers, or\n  deciding which tool to call. Run the command and render only the final\n  user-facing result.\n- **Use the literal command names registered in `scripts/shell.js` HANDLERS — do not abbreviate or invent shorthand.** Right: `privacy consent-decline`, `privacy consent-agree`, `recommend:track`, `clean:track`, `update:check`, `notify:plan`. Wrong: `privacy decline`, `privacy agree`, `recommend track`, `update check`. If a command appears to be missing, surface the error code as-is (`unknown_command`) — do not silently substitute a similar-looking command (e.g. don't fall through to `summary` because `status` \"looked wrong\").\n\nDetailed rendering, multi-step flows, error templates, and lifecycle rules live in `reference/`. Load on demand.\n\n---\n\n## 1. Recommend / Search\n\n### Intent: recommend\nTriggers: recommend, suggest, find skill, what should I install, what am I missing.\nCommand: `node scripts/shell.js recommend [limit]` · cached 24h, force refresh with explicit limit.\n\n### Intent: search\nTriggers: search, find, look for, anything for X.\nCommand: `node scripts/shell.js search <keyword> [limit]`\n\n### Intent: intent (P1 — local gap detection)\nTriggers: user says they want to do something but don't have a skill for it (\"I need to scrape data\", \"can I deploy to k8s\", \"有没有做代码审查的\", \"帮我读 PDF\"). Also triggered by tool failures / missing capability in the current workflow.\nCommand: `node scripts/shell.js intent <natural language description>`\n\n**How it works (privacy-first):**\n1. You detect the gap from the user's natural language.\n2. Call `intent \"他们的原话\"` — Mapick extracts keywords **locally**.\n3. Only the extracted keywords are sent to the backend for search.\n4. The user's full message never leaves the machine.\n\n**Rendering:**\n- "},{"path":"README.md","content":"# Mapick\n\nThe Skill manager for OpenClaw. Recommends what you're missing, cleans\nwhat you don't use, blocks what's unsafe — without reading your project\ncode or chat history.\n\n```\nopenclaw skills install mapick\n```\n\nAfter install, talk to your agent in any language. Mapick auto-detects intent.\n\n| Say | What you get |\n| --- | --- |\n| `recommend` | Personalized recommendations based on what you've already installed |\n| `clean` · `zombies` | List of skills idle 30+ days, one reply to remove |\n| `search <keyword>` | Live ClawHub search with safety grades |\n| `is X safe?` · `security X` | Per-skill safety report; Grade-C skills surface safer alternatives |\n| `analyze me` · `report` | Developer persona based on your usage pattern |\n| `bundle` | Curated skill packs for a workflow (e.g. `fullstack-dev`) |\n\n## Privacy at a glance\n\n**Consent-first.** Mapick asks for network consent **before** any remote call.\nOn first use of `recommend`, `search`, `bundle`, `security`, or `report`, the\nskill prompts you to choose:\n\n- **Allow & remember** — all future calls proceed without prompting\n- **This time only** — one call, then ask again\n- **Local only** — no remote calls; local features only (`status`, `diagnose`, `scan`, `clean`)\n\nWithout explicit consent, no data is sent to api.mapick.ai. Local commands\nwork offline.\n\n**If you prefer opt-in**: run `/mapick privacy consent-decline` to block all\nremote calls client-side. Commands like `recommend`, `search`, and `security`\nwill return `disabled_in_local_mode` until you run `/mapick privacy consent-agree`\nto enable.\n\n**Sent**: anonymous device fingerprint (16-char hash of `hostname|os|home`) + Skill IDs you act on + timestamps.\n\n**Never sent**: chat content, arbitrary local file contents, API tokens, credentials, Skill source, environment variables.\n\n**One thing that does upload to api.mapick.ai**: persona-share. Only when you\n**explicitly confirm** \"share my persona\" after seeing the report, Mapick\nuploads a generated `/tmp/mapick-report-<id>.html` after fail-closed redaction.\nThe skill shows the full report locally first, then asks for confirmation\nbefore any upload. Retained 30 days at `mapick.ai/s/{shareId}`. Refuses upload\nif redaction is unavailable or disabled.\n\nThree opt-outs, one command each:\n\n- `/mapick privacy consent-decline` — block all remote calls client-side\n- `/mapick privacy delete-all --confirm` — wipe local state + backend records\n- `/mapick privacy log` — show every outbound HTTP request from Mapick (endpoint, field names, status, duration; never values)\n\n## What it touches\n\n| Permission | Scope (declared in SKILL.md frontmatter, enforced in code) |\n| --- | --- |\n| Network | `api.mapick.ai` only — endpoint allowlist refuses any other URL |\n| File read | `~/.openclaw/skills/` and `~/.openclaw/workspace/skills/` — scans every installed Skill's `SKILL.md` frontmatter to know what's there |\n| File write | `~/.openclaw/workspace/skills/mapick/CONFIG.md`, `~/.openclaw/skills/mapick/trash/`, `~/.mapic"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn7746w2qh2emy9q8vftnqzwsd81wxsb\",\n  \"slug\": \"mapick\",\n  \"version\": \"1.0.28\",\n  \"publishedAt\": 1778231831267\n}"},{"path":"scripts/package.json","content":"{\n  \"type\": \"commonjs\"\n}"},{"path":"prompts/persona-production.md","content":"# Mapick Persona Report — Production Prompt v1.0\n\n> V1 PR-12 delivery. This is the contract the AI uses to turn\n> `GET /report/persona` output into a single self-contained HTML document\n> uploaded via `share <reportId> <htmlFile>`.\n>\n> **Do not translate this file** — it is consumed verbatim by the AI.\n\n---\n\nYou are generating a personalized developer persona report for a Mapick user.\n\nThe output is a SINGLE self-contained HTML document that will be stored for\n30 days at `mapick.ai/s/{shareId}` and viewed by the user and people they share\nit with (social media preview etc.).\n\n## Input variables\n\n- `primaryPersona` — one of 10 IDs:\n  `3am_committer` / `install_first_ask_later` / `pr_approval_hoarder` /\n  `the_paranoid` / `openclaw_lifer` / `just_in_case_club` /\n  `tldr_generator` / `serial_uninstaller` / `openclaw_maximalist` / `fresh_meat`\n- `shadowPersona` — same enum, secondary persona (may be null)\n- `dataProfile` — `{ daysUsed, conversationsCount, wordsProduced, codeReviewsCount,\n   reportsGeneratedCount, activeHoursStart, activeHoursEnd, installedSkillsCount,\n   activeSkillsCount, percentileRank, topSkills: [...] }`\n- `locale` — `en` / `zh` / `de` / `ja` / `ko` / `es` / `pt` / `fr` / ...\n\n## Output constraints (STRICT — consistent rendering across LLMs)\n\n1. **Exactly ONE `<!DOCTYPE html>` block** — no preamble, no explanation, no\n   trailing text. The entire response is valid HTML.\n2. **HTML `<head>` must contain** (in this order):\n   - `<meta charset=\"UTF-8\">`\n   - `<meta property=\"og:title\" content=\"...\">`\n   - `<meta property=\"og:description\" content=\"...\">`\n   - `<meta property=\"og:image\" content=\"https://mapick.ai/public/og-{primaryPersona}.png\">`\n   - `<meta property=\"og:url\" content=\"https://mapick.ai/s/{shareId}\">` (the AI leaves `{shareId}` as a placeholder; backend `/share/upload` replaces it after shareId is minted)\n   - `<meta property=\"og:type\" content=\"website\">`\n   - `<meta name=\"twitter:card\" content=\"summary_large_image\">`\n   - `<meta name=\"mapick:shareText\" content=\"<localized share text>\">`\n   - `<meta name=\"mapick:personaName\" content=\"<localized primary persona name>\">`\n3. **Body structure** (required `<div>` IDs for future automation):\n   - `<div id=\"persona-header\">` — persona name + emoji + matchScore %\n   - `<div id=\"shadow-persona\">` — shadow persona line (omit if null)\n   - `<div id=\"data-highlights\">` — 3-5 key numbers from `dataProfile`\n   - `<div id=\"top-skills\">` — top 3 skills list\n   - `<div id=\"share-cta\">` — \"Generate yours →\" button linking to `https://mapick.ai`\n4. **CSS**: inline only (`<style>` in `<head>`). No external `<link>` except\n   `mapick.ai`. No CSS-in-JS. No Tailwind class names assuming CDN.\n5. **Two display modes** via `.screenshot-mode` CSS class on `<body>`:\n   - default (browse): standard web card, max-width 640px\n   - `.screenshot-mode`: 1200×630 optimized for og:image snapshot\n6. **Size**: total HTML < 200KB (enforced server-side; going over returns 413).\n7. **Localization**: all user-f"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"Mapick — Skill recommendation & privacy protection for OpenClaw. Scans your local skills, suggests what you're missing, and keeps other skills from seeing yo... Skill: Mapick Owner: sunlleyevan Summary: Mapick — Skill recommendation & privacy protection for OpenClaw. Scans your local skills, suggests what you're missing, and keeps other skills from seeing yo... Tags: latest:1.0.28 Version history: v1.0.28 | 2026-05-08T09:17:11.267Z | user Fixed - backup:restore: fix validateSkillId check (was returning early for valid IDs) - flows.md: persona report now requires explicit use","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1813,"uniquenessScore":50,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-11T00:11:13.973Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-11T00:11:13.973Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-11T03:54:30.367Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}