Mapick
Priority: recommendation = privacy > persona > safety score > cleanup > everything else.
Global rules
- Output reference below is English — render in the user's conversation language.
- Match every intent trigger in ANY language. Trigger lists are illustrative, not allow-lists.
- Every
node scripts/shell.js <subcommand>runs the Mapick Node entrypoint. Node.js (>=22.14) required. - Shell responses are single-line JSON. Parse it; never dump raw JSON to the user. Paraphrase errors.
- For slash commands, never narrate internal preparation. Do not tell the user you are reading SKILL.md, loading reference files, checking handlers, or deciding which tool to call. Run the command and render only the final user-facing result.
- Use the literal command names registered in
scripts/shell.jsHANDLERS — 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 tosummarybecausestatus"looked wrong").
Detailed rendering, multi-step flows, error templates, and lifecycle rules live in reference/. Load on demand.
1. Recommend / Search
Intent: recommend
Triggers: recommend, suggest, find skill, what should I install, what am I missing.
Command: node scripts/shell.js recommend [limit] · cached 24h, force refresh with explicit limit.
Intent: search
Triggers: search, find, look for, anything for X.
Command: node scripts/shell.js search <keyword> [limit]
Intent: intent (P1 — local gap detection)
Triggers: 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.
Command: node scripts/shell.js intent <natural language description>
How it works (privacy-first):
- You detect the gap from the user's natural language.
- Call
intent "他们的原话"— Mapick extracts keywords locally. - Only the extracted keywords are sent to the backend for search.
- The user's full message never leaves the machine.
Rendering:
- When
itemsnon-empty: render likesearchresults (same gap→fix two-sentence style, same badge rules). - Lead with: "基于你说的「{original}」,我提取了关键词「{keywords}」帮你搜了一下" (translate to user's language).
- When
itemsempty ornoticepresent: surface the extracted keywords to the user so they can refine. Suggest trying/mapick recommendor broadening their description. - NEVER show or transmit the raw
originaltext — theoriginalfield in the response is for the AI's rendering context only.
On 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).
On 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).
Install command rule (STRICT)
Always render: openclaw skills install <slug>. Slug resolution uses resolveCanonicalSlug:
resolveCanonicalSlug(input) → slug:
- If input has
slugfield → use it directly. - If input has
skillIdwith no path separators → use it (e.g.code-review). - If input has
skillssh:org/repo/skillformat → extract last segment (e.g.skillssh:soultrace-ai/soultrace-skill/soultrace→soultrace). - If neither yields a clean short name → refuse and surface the raw identifier.
Applies to:
/mapick recommend→ on user pick, resolve fromitems[].skillIdoritems[].slug./mapick bundle:install <id>→ resolve each entry ininstallCommands[]before running.
NEVER show or run: raw installCommands[].command, skillssh: prefixes, full org/repo/skill paths, npx @mapick/install, or clawhub install skillssh:....
Rendering: recommend / search
Filter score < 0.4. Show 3 items max. For each item render exactly two sentences — no tables, no bulleted field lists:
- 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.")
- 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.")
Append 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'."
NEVER 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".
For 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).
2. Privacy
Intent: privacy
Triggers: privacy, redact, who can see my data, delete my data, forget me, anonymous mode.
Privacy model: function-level consent (P3)
Mapick 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:
- 允许并记住 (
always) — allow all future network operations without prompting. - 仅这一次 (
once) — allow this one command; prompt again next time. - 本地模式 (
declined) — all remote commands disabled. Use local-only features.
Once a choice is made, it's stored in CONFIG.md. You can change it at any time:
node scripts/shell.js network-consent alwaysnode scripts/shell.js network-consent declined
Consent dialog (P3 — render exactly)
When shell returns { intent: "network_consent_required", ... }, render this dialog in the user's language:
🔒 首次联网确认
Mapick 需要联网来推荐 skill。**不会发送**聊天内容、API key、文件内容。
仅发送:
• 匿名设备 ID
• 已安装 skill 名称列表
• 搜索关键词
选择:
1. 允许并记住 — 以后不再询问
2. 仅这一次 — 下次再问
3. 本地模式 — 只使用本地功能
回复 1、2 或 3。
On user pick:
- 1 → "允许并记住": run
node scripts/shell.js network-consent always, then re-run the original command. - 2 → "仅这一次": run
node scripts/shell.js network-consent once, then re-run the original command. Consent expires after this command. - 3 → "本地模式": run
node scripts/shell.js network-consent declined. Do NOT re-run the original command. Show local alternatives instead.
Subcommands
node scripts/shell.js privacy status— current mode (default vs declined) + trusted skills listnode scripts/shell.js privacy trust <skillId>— allow unredacted accessnode scripts/shell.js privacy untrust <skillId>— revokenode scripts/shell.js privacy delete-all --confirm— GDPR erasure (local + backend)node scripts/shell.js privacy consent-decline— opt out: refuse remote commands client-sidenode scripts/shell.js privacy consent-agree— undo a previous decline (only needed if you ranconsent-decline)node scripts/shell.js network-consent <always|once|declined>— set function-level network consentnode scripts/shell.js privacy log [limit]— show last N ou