distilly
Set up the owner profile so a personal agent knows who it works for (first-run setup, "get to know me"), or distill colleague, relationship, or celebrity source material into reusable Person Profiles for agents.
含まれるファイル(129)
- SKILL.md39.2 KB
- .github/ISSUE_TEMPLATE/bug_report.md753 B
- .github/ISSUE_TEMPLATE/config.yml310 B
- .github/ISSUE_TEMPLATE/feature_request.md503 B
- .github/ISSUE_TEMPLATE/question.md418 B
- .github/PULL_REQUEST_TEMPLATE.md947 B
- .github/workflows/ci.yml1.3 KB
- .github/workflows/publish-package.yml551 B
- .gitignore395 B
- .npmrc48 B
- bin/distilly.mjs5.6 KB
- CITATION.cff1.1 KB
- CONTRIBUTING.md4.2 KB
- docs/assets/hosts/claude-code-wordmark-dark.svg8.1 KB
- docs/assets/hosts/claude-code-wordmark-light.svg6.8 KB
- docs/assets/hosts/codex-mark-dark.png42.9 KB
- docs/assets/hosts/codex-mark-light.png40.7 KB
- docs/assets/hosts/deepseek-wordmark-dark.svg9.8 KB
- docs/assets/hosts/deepseek-wordmark-light.svg9.8 KB
- docs/assets/hosts/grok-build-mark-dark.png11.1 KB
- docs/assets/hosts/grok-build-mark-light.png11.4 KB
- docs/assets/hosts/hermes-agent-wordmark.png12.0 KB
- docs/assets/hosts/meta-mark.svg1.3 KB
- docs/assets/hosts/openai-mark-dark.svg1.5 KB
- docs/assets/hosts/openai-mark-light.svg1.5 KB
- docs/assets/hosts/openclaw-wordmark-dark.svg63.6 KB
- docs/assets/hosts/openclaw-wordmark-light.svg63.6 KB
- docs/assets/hosts/opencode-wordmark-dark.svg1.1 KB
- docs/assets/hosts/opencode-wordmark-light.svg1.1 KB
- docs/assets/hosts/pi-mark.svg618 B
- docs/assets/hosts/README.md1.6 KB
- docs/assets/sources/dingtalk-mark.jpg1.5 KB
- docs/assets/sources/lark-mark.png3.8 KB
- docs/assets/sources/README.md602 B
- docs/assets/sources/slack-mark.png2.8 KB
- docs/assets/sources/wechat-mark.jpg4.1 KB
- docs/assets/sources/x-mark-dark.svg292 B
- docs/assets/sources/x-mark-light.svg292 B
- docs/lang/README_DE.md17.4 KB
- docs/lang/README_ES.md17.4 KB
- docs/lang/README_JA.md19.1 KB
- docs/lang/README_KO.md17.6 KB
- docs/lang/README_PT.md17.2 KB
- docs/lang/README_RU.md23.4 KB
- docs/lang/README_ZH.md16.1 KB
- docs/lang/ROADMAP_DE.md6.0 KB
- docs/lang/ROADMAP_ES.md6.1 KB
- docs/lang/ROADMAP_JA.md6.9 KB
- docs/lang/ROADMAP_KO.md6.4 KB
- docs/lang/ROADMAP_PT.md5.8 KB
- docs/lang/ROADMAP_RU.md9.2 KB
- docs/lang/ROADMAP_ZH.md5.4 KB
- docs/social-preview-distilly-v10.png839.8 KB
- INSTALL_EN.md6.4 KB
- INSTALL.md20.5 KB
- LICENSE1.0 KB
- package.json1015 B
- prompts/celebrity/budget_unfriendly/audit.md3.9 KB
- prompts/celebrity/budget_unfriendly/persona_analyzer.md3.3 KB
- prompts/celebrity/budget_unfriendly/persona_builder.md3.3 KB
- prompts/celebrity/budget_unfriendly/research.md15.8 KB
- prompts/celebrity/budget_unfriendly/synthesis.md1.2 KB
- prompts/celebrity/budget_unfriendly/validation.md1.3 KB
- prompts/celebrity/intake.md5.2 KB
- prompts/celebrity/merger.md6.8 KB
- prompts/celebrity/persona_analyzer.md5.5 KB
- prompts/celebrity/persona_builder.md6.1 KB
- prompts/celebrity/research.md12.3 KB
- prompts/correction_handler.md3.3 KB
- prompts/intake.md5.3 KB
- prompts/merger.md2.4 KB
- prompts/owner/intake.md5.4 KB
- prompts/owner/profile_builder.md2.5 KB
- prompts/persona_analyzer.md8.7 KB
- prompts/persona_builder.md5.1 KB
- prompts/relationship/intake.md2.2 KB
- prompts/relationship/merger.md1.1 KB
- prompts/relationship/persona_analyzer.md1.9 KB
- prompts/relationship/persona_builder.md1.7 KB
- prompts/work_analyzer.md5.3 KB
- prompts/work_builder.md2.6 KB
- README.md19.2 KB
- references/celebrity_budget_unfriendly_framework.md7.4 KB
- references/celebrity_budget_unfriendly_template.md3.7 KB
- requirements.txt459 B
- ROADMAP.md5.3 KB
- tests/e2e/owner_discovery/.gitignore54 B
- tests/e2e/owner_discovery/mock_mcp.py4.9 KB
- tests/e2e/owner_discovery/README.md1.2 KB
- tests/e2e/owner_discovery/setup.sh545 B
- tests/e2e/owner_discovery/turn.sh1.0 KB
- tests/test_cli_lifecycle.py22.4 KB
- tests/test_config_migration.py1.7 KB
- tests/test_credentials.py5.1 KB
- tests/test_install_claude_generated_skill.py3.3 KB
- tests/test_install_distilly.py4.0 KB
- tests/test_install_generated_skill.py4.4 KB
- tests/test_install_openclaw_and_codex.py5.3 KB
- tests/test_owner_profile.py9.7 KB
- tests/test_owner_sources.py5.5 KB
- tests/test_research_tools.py8.7 KB
- tests/test_skill_entrypoint_docs.py15.7 KB
- tests/test_skill_writer.py31.1 KB
- tests/test_xquik_public_posts.py8.7 KB
- tools/credentials.py7.3 KB
- tools/dingtalk_auto_collector.py28.1 KB
- tools/email_parser.py9.8 KB
- tools/feishu_auto_collector.py39.1 KB
- tools/feishu_browser.py12.5 KB
- tools/feishu_mcp_client.py11.5 KB
- tools/feishu_parser.py7.4 KB
- tools/install_claude_generated_skill.py3.6 KB
- tools/install_distilly.py2.7 KB
- tools/install_generated_skill_common.py3.9 KB
- tools/install_generated_skill.py2.4 KB
- tools/owner_profile.py11.3 KB
- tools/owner_sources.py12.8 KB
- tools/research/__init__.py72 B
- tools/research/download_subtitles.sh887 B
- tools/research/merge_research.py10.0 KB
- tools/research/quality_check.py10.2 KB
- tools/research/srt_to_transcript.py2.7 KB
- tools/research/transcribe_audio.py10.0 KB
- tools/research/xquik_public_posts.py14.3 KB
- tools/skill_presets.py11.8 KB
- tools/skill_schema.py15.7 KB
- tools/skill_writer.py25.0 KB
- tools/slack_auto_collector.py25.6 KB
- tools/version_manager.py7.8 KB
SKILL.md(原文)
インストールする前に、エージェントに与えられる指示の中身を確認できます。
Language: These instructions are written in English. Detect the user's language from their first message and reply to the user in that language throughout.
Skill Root: Before reading a bundled prompt or running a bundled script, resolve the absolute directory of the
SKILL.mdthat the host actually loaded. In the instructions below,{distilly_skill_root}means that exact directory. Claude Code exposes it as${CLAUDE_SKILL_DIR}; on every other host, use the loaded-skill path supplied by that host's discovery context. Do not assume the shell's current working directory is the Skill root, and do not guess or hard-code an install path. If the host does not expose the loaded path or more than one Distilly installation is ambiguous, ask the user to identify the active installation before running code.Keep the shell in the user's current workspace so relative output paths such as
./skills/...remain project-local. Resolve everytools/...andprompts/...resource against{distilly_skill_root}. For example, execute the bundledtools/example.pyaspython3 "{distilly_skill_root}/tools/example.py"; replace the placeholder with the resolved absolute path in the actual tool call.
Distilly Creator
Distilly was formerly Colleague Skill / colleague-skill. The current Skill frontmatter name and creator entrypoint are both
distilly.
Trigger Conditions
Activate when the user says any of the following:
/distilly- "Help me create a skill"
- "I want to distill someone"
- "Create a new skill"
- "Make a skill for XX"
- "Set up my profile" / "Get to know me" / "Who am I to you", or a host's first run with no owner profile yet → go straight to the "Owner Profile" flow below
Compatible hosts:
- Claude Code
- OpenClaw
- Hermes
- Codex
- DeepSeek Harness
- Pi coding agent
- Grok Build
- OpenCode
Explicit invocation differs among hosts that expose it: use /distilly in Claude Code, Hermes, DeepSeek Harness, and Grok Build; use /distilly in OpenClaw, or /skill distilly when its native slash is not registered; use $distilly or choose it through /skills in Codex; use /skill:distilly in Pi. OpenCode uses native Skill discovery and loading; do not invent a dedicated command.
Grok Bot can save a workflow as a private Skill, but its official documentation does not describe direct local SKILL.md directory imports. Do not present this repository as a direct Grok Bot install; migrate the workflow manually into a saved Skill or wait for a dedicated adapter.
Enter evolution mode when the user says:
- "I have new files" / "append"
- "That's wrong" / "He wouldn't do that" / "He should be"
/update-skill {character} {slug}
Compatibility update alias:
/update-colleague {slug}
When the user asks to see generated skills, use the list commands in "Management Operations" below.
Tool Usage Rules
This Skill runs in any compatible host that can read local files and execute Bash / Python commands. Use the following tool conventions:
| Task | Tool |
|---|---|
| Read PDF documents | Read tool (native PDF support) |
| Read image screenshots | Read tool (native image support) |
| Read MD/TXT files | Read tool |
| Parse Lark message JSON export | Bash → python3 "{distilly_skill_root}/tools/feishu_parser.py" |
| Lark auto-collect (recommended) | Bash → python3 "{distilly_skill_root}/tools/feishu_auto_collector.py" |
| Lark docs (browser session) | Bash → python3 "{distilly_skill_root}/tools/feishu_browser.py" |
| Lark docs (MCP App Token) | Bash → python3 "{distilly_skill_root}/tools/feishu_mcp_client.py" |
| DingTalk auto-collect | Bash → python3 "{distilly_skill_root}/tools/dingtalk_auto_collector.py" |
| Collect public X post candidates | Bash → python3 "{distilly_skill_root}/tools/research/xquik_public_posts.py" |
| Parse email .eml/.mbox | Bash → python3 "{distilly_skill_root}/tools/email_parser.py" |
| Write/update Skill files | Write / Edit tool |
| Version management | Bash → python3 "{distilly_skill_root}/tools/version_manager.py" |
| List existing Skills | Bash → python3 "{distilly_skill_root}/tools/skill_writer.py" --action list |
Base directories:
colleague→./skills/colleague/{slug}/relationship→./skills/relationship/{slug}/celebrity→./skills/celebrity/{slug}/
For a global path, use --base-dir with the storage root for that character family.
Credential rules (Lark / DingTalk / Slack): App Secrets, user_access_token, refresh_token, Bot Tokens and OAuth codes must never enter the conversation context.
- Never ask the user to send you these values, and never put them in command arguments, script source, output files or replies.
- For setup, ask the user to run the script's
--setupin their own terminal (plus--loginfor Lark private chats). Secrets are typed with hidden input and stored in the OS keychain (whenkeyringis installed) or in~/.distilly/*_config.json(mode 0600). The user may instead export environment variables (FEISHU_APP_ID/FEISHU_APP_SECRET/FEISHU_USER_ACCESS_TOKEN/DINGTALK_APP_KEY/DINGTALK_APP_SECRET/SLACK_BOT_TOKEN).--setup/--loginrefuse to run without an interactive terminal, so you cannot run them on the user's behalf. - Use
--checkto see whether credentials are ready; it shows only the source (env / keychain / config file), never the values. - If you write your own script against the APIs, load credentials from environment variables or
credentials.resolve(...)intools/credentials.py, and never print them. - If the user pastes a secret into the chat anyway: do not repeat or use it, tell them to rotate it on the open platform, then reconfigure as above.
The Lark-labelled compatibility collectors currently connect to the China-region open.feishu.cn / feishu.cn endpoints. International larksuite.com tenant routing is not implemented yet.
Main Flow: Create a New Skill
Step 0: Confirm the character family
If the user entered /distilly, first confirm which family should be distilled:
owner: the user themself (the default on a personal agent's first run)colleaguerelationshipcelebrity
For owner (including "distill myself"), do not continue with Steps 1-5 below; use the "Owner Profile" flow instead.
If the host already passed an explicit family, lock the character family immediately.
If the current family is celebrity, also confirm the research profile:
budget-friendlybudget-unfriendly
Default to budget-friendly. Only switch to budget-unfriendly when the user explicitly wants deeper research, higher confidence, or accepts a slower and more expensive distillation pass.
Step 1: Basic Info Collection
Choose the intake prompt by character family:
colleague→prompts/intake.mdrelationship→prompts/relationship/intake.mdcelebrity→prompts/celebrity/intake.md
For colleague and relationship, ask only 3 questions.
For celebrity, use the 4-question intake in prompts/celebrity/intake.md; the fourth question must confirm research_profile.
The default 3 base questions are:
- Alias / Codename (required)
- Basic info (one sentence: company, level, role, gender — say whatever comes to mind)
- Example:
ByteDance L2-1 backend engineer male
- Example:
- Personality profile (one sentence: MBTI, zodiac, traits, corporate culture, impressions)
- Example:
INTJ Capricorn blame-shifter ByteDance-style strict in CR but never explains why
- Example:
Everything except the alias can be skipped. Summarize and confirm before moving to the next step.
Step 2: Source Material Import
Ask the user how they'd like to provide materials:
How would you like to provide source materials?
[A] Lark Auto-Collect (recommended)
Enter name, auto-pull messages + docs + spreadsheets
[B] DingTalk Auto-Collect
Enter name, auto-pull docs + spreadsheets
Messages collected via browser (DingTalk API doesn't support message history)
[C] Lark Link
Provide doc/Wiki link (browser session or MCP)
[D] Upload Files
PDF / images / exported JSON / email .eml
[E] Paste Text
Copy-paste text directly
Can mix and match, or skip entirely (generate from manual info only).
Option A: Lark Auto-Collect (Recommended)
First-time setup. Check whether credentials are ready:
python3 "{distilly_skill_root}/tools/feishu_auto_collector.py" --check
If not, ask the user to run this in their own terminal (do not run it yourself, and do not ask for the App Secret in chat):
python3 "{distilly_skill_root}/tools/feishu_auto_collector.py" --setup
Group chat collection (uses tenant_access_token, bot must be in the group):
python3 "{distilly_skill_root}/tools/feishu_auto_collector.py" \
--name "{name}" \
--output-dir ./knowledge/{slug} \
--msg-limit 1000 \
--doc-limit 20
Private chat (P2P) collection (requires user_access_token + p2p chat_id):
Private messages can only be accessed via user identity (user_access_token). App identity cannot access private chats.
Prerequisites (the user completes these on the Open Platform and in their own terminal; you only guide):
- Lark app credentials:
app_id/app_secretconfigured via--setupor environment variables (confirm with--check) - User scopes: The app must have these user scopes enabled:
im:message— read/send messages as userim:chat— read chat list as user
- Redirect URL: add
http://www.example.comunder the app's "Security Settings → Redirect URLs"
If the user is missing any of these, guide them through setup. Don't assume anything is pre-configured.
Getting user_access_token: ask the user to run this in their own terminal:
python3 "{distilly_skill_root}/tools/feishu_auto_collector.py" --login
The script prints the authorization URL; after authorizing in the browser, the user pastes the callback URL into the terminal (hidden input) and the token goes straight into the keychain or config file. Never ask the user to send the code or token in chat.
When the token expires (about 2 hours), you can refresh it yourself with no secret input:
python3 "{distilly_skill_root}/tools/feishu_auto_collector.py" --refresh
Getting the p2p chat_id:
Users typically don't know their chat_id. The user can open the private chat in Lark and find the oc_ chat_id in the chat link or developer tools. If you write a script to obtain it, the script must read the token from credentials.resolve("feishu", ...) or environment variables and must not print it:
- Method: Send a message to the other user's open_id — the response includes the chat_id (this really sends a message, so ask the user first)
POST https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=open_id Header: Authorization: Bearer <read via credentials.resolve, never hard-coded> Body: {"receive_id": "{target_open_id}", "msg_type": "text", "content": "{\"text\":\"hello\"}"} # The chat_id in the response is the p2p chat ID - Important:
GET /im/v1/chatsdoes NOT return p2p chats — this is an API limitation, not a permission issue. Do not try to use it for finding private chats. - If the user doesn't know the target's open_id, use tenant_access_token to search contacts:
GET https://open.feishu.cn/open-apis/contact/v3/scopes # Returns open_ids of all users visible to the app
Running collection:
Once credentials are ready and you have the chat_id (the script loads the token itself; it never appears on the command line):
python3 "{distilly_skill_root}/tools/feishu_auto_collector.py" \
--open-id {target_open_id} \
--p2p-chat-id {chat_id} \
--name "{name}" \
--output-dir ./knowledge/{slug} \
--msg-limit 1000
Flexibility principle: The above API calls don't have to go through the collector script. If the script doesn't work or doesn't fit the scenario, write Python scripts directly against the same endpoints, but load credentials through credentials.resolve("feishu", feishu_auto_collector.load_config()) or environment variables; they must never appear in script source, command arguments or output. Key API reference:
- Get token:
POST /auth/v3/tenant_access_token/internal(wrapped byget_tenant_tokenin the collector) - Send message (get chat_id):
POST /im/v1/messages?receive_id_type=open_id - Fetch messages:
GET /im/v1/messages?container_id_type=chat&container_id={chat_id} - Search contacts:
GET /contact/v3/scopes,GET /contact/v3/users/{user_id}
Auto-collected content:
- Group chats: messages sent by them (system messages and stickers filtered)
- Private chats: full conversation with both parties (for context understanding)
- Lark docs and Wikis they created/edited
- Related spreadsheets (if accessible)
After collection, Read the output files:
knowledge/{slug}/messages.txt→ messages (group + private)knowledge/{slug}/docs.txt→ document contentknowledge/{slug}/collection_summary.json→ collection summary
If collection fails, diagnose the error and attempt to fix it. Common issues:
- Group chat: bot not added to the group
- Private chat: user_access_token expired (2-hour TTL; run
--refresh, or ask the user to re-run--loginin their own terminal if there is no refresh_token) - Insufficient permissions: guide user to enable scopes and re-authorize
- Or switch to Option B/C
Option B: DingTalk Auto-Collect
First-time setup. Run --check first; if not configured, ask the user to run --setup in their own terminal (hidden AppSecret input), or to export DINGTALK_APP_KEY / DINGTALK_APP_SECRET. Never ask for the AppSecret in chat:
python3 "{distilly_skill_root}/tools/dingtalk_auto_collector.py" --check
python3 "{distilly_skill_root}/tools/dingtalk_auto_collector.py" --setup # run by the user
Then enter the name:
python3 "{distilly_skill_root}/tools/dingtalk_auto_collector.py" \
--name "{name}" \
--output-dir ./knowledge/{slug} \
--msg-limit 500 \
--doc-limit 20 \
--show-browser # add this flag on first use to complete DingTalk login
Collected content:
- DingTalk docs and knowledge bases they created/edited
- Spreadsheets
- Messages (⚠️ DingTalk API doesn't support message history — auto-switches to browser scraping)
After collection, Read:
knowledge/{slug}/docs.txtknowledge/{slug}/bitables.txtknowledge/{slug}/messages.txt
If message collection fails, prompt user to upload chat screenshots.
Option D: Upload Files
- PDF / Images:
Readtool directly - Lark message JSON export:
Thenpython3 "{distilly_skill_root}/tools/feishu_parser.py" --file {path} --target "{name}" --output /tmp/feishu_out.txtRead /tmp/feishu_out.txt - Email files .eml / .mbox:
Thenpython3 "{distilly_skill_root}/tools/email_parser.py" --file {path} --target "{name}" --output /tmp/email_out.txtRead /tmp/email_out.txt - Markdown / TXT:
Readtool directly
Option C: Lark Link
When the user provides a Lark doc/Wiki link, ask which method to use:
Lark link detected. Choose read method:
[1] Browser Method (recommended)
Reuses your local Chrome login session
✅ Works with internal docs requiring permissions
✅ No token configuration needed
⚠️ Requires Chrome + playwright installed locally
[2] MCP Method
Uses a Lark App Token via the official API
✅ Stable, no browser dependency
✅ Can read messages (needs chat ID)
⚠️ Requires App ID / App Secret setup
⚠️ Internal docs need admin authorization for the app
Choose [1/2]:
Option 1 (Browser):
python3 "{distilly_skill_root}/tools/feishu_browser.py" \
--url "{feishu_url}" \
--target "{name}" \
--output /tmp/feishu_doc_out.txt
First use will open a browser window for login (one-time).
Option 2 (MCP):
First-time setup (shares Lark credentials with Option A). Run --check first; if not configured, ask the user to run --setup in their own terminal:
python3 "{distilly_skill_root}/tools/feishu_mcp_client.py" --check
python3 "{distilly_skill_root}/tools/feishu_mcp_client.py" --setup # run by the user
Then read directly:
python3 "{distilly_skill_root}/tools/feishu_mcp_client.py" \
--url "{feishu_url}" \
--output /tmp/feishu_doc_out.txt
Read messages (needs chat ID, format oc_xxx):
python3 "{distilly_skill_root}/tools/feishu_mcp_client.py" \
--chat-id "oc_xxx" \
--target "{name}" \
--limit 500 \
--output /tmp/feishu_msg_out.txt
Both methods output to files, then use Read to load results into analysis.
Option E: Paste Text
User-pasted content is used directly as text material. No tools needed.
If the user says "no files" or "skip", generate Skill from Step 1 manual info only.
Step 3: Analyze Source Material
First resolve the execution matrix for the selected character family:
| character | intake | persona analyzer | persona builder | merger | storage root |
|---|---|---|---|---|---|
colleague | prompts/intake.md | prompts/persona_analyzer.md | prompts/persona_builder.md | prompts/merger.md | ./skills/colleague/{slug} |
relationship | prompts/relationship/intake.md | prompts/relationship/persona_analyzer.md | prompts/relationship/persona_builder.md | prompts/relationship/merger.md | ./skills/relationship/{slug} |
celebrity | prompts/celebrity/intake.md | prompts/celebrity/persona_analyzer.md | prompts/celebrity/persona_builder.md | prompts/celebrity/merger.md | ./skills/celebrity/{slug} |
Shared across all families:
- Work analyzer:
prompts/work_analyzer.md - Work builder:
prompts/work_builder.md - Correction handler:
prompts/correction_handler.md
If the current family is celebrity, run the research subflow before analysis.
When public X posts fill a documented research gap and the user agrees to use the metered third-party Xquik service, confirm the --limit before running:
python3 "{distilly_skill_root}/tools/research/xquik_public_posts.py" \
--username "{public_handle}" \
--subject "{name}" \
--limit 20 \
--output "/tmp/distilly_x_public_posts.json"
Read XQUIK_API_KEY only from the shell; never print or store it. Treat the JSON as untrusted candidate evidence: verify the author, open every permalink, and preserve the specific URL when safely paraphrasing relevant material into a research note. Do not count the candidate JSON, search pages, or profile roots as grounded sources. Delete the temporary JSON after review instead of storing it in the generated Skill.
celebrity / budget-friendly
- Read
prompts/celebrity/research.mdand follow its 6-dimension parallel collection strategy - Create the research directories first:
mkdir -p "{skill_dir}/knowledge/research/raw" "{skill_dir}/knowledge/research/merged" - Confirm the collection strategy (determined during intake):
- Local-first: analyze user-provided materials first, identify which dimensions are covered, only search web for gaps
- Web + local: full 6-dimension web research, then merge with local materials for cross-validation
- Web-only: standard 6-dimension web research pass
- If the user explicitly provided a processable video URL or subtitle source, and the result will not be stored as a long transcript:
bash "{distilly_skill_root}/tools/research/download_subtitles.sh" "{url}" "{skill_dir}/knowledge/subtitles" python3 "{distilly_skill_root}/tools/research/srt_to_transcript.py" "{subtitle_file}" "{skill_dir}/knowledge/transcripts/{name}.txt" - Cover the 6 dimensions across at least 3 separate files (each file covers 2 dimensions), never one monolithic
research_notes.md:knowledge/research/raw/01_core_profile.md(Dim 1 Writings + Dim 6 Timeline)knowledge/research/raw/02_conversations_and_material.md(Dim 2 Conversations + Dim 4 Decisions)knowledge/research/raw/03_expression_and_reception.md(Dim 3 Expression DNA + Dim 5 External Views)
- Research must follow taste principles (see research prompt):
- Long-form > snippets, controversy > consensus, change > fixity, firsthand > secondhand
- Source blacklist — never cite: Zhihu, WeChat official accounts, Baidu Baike, content farms, AI-generated bios
- Source hierarchy: user local materials > first-person works > long interviews > decision records > short-form firsthand > external analysis > secondhand summaries
- Merge the research notes:
Output:python3 "{distilly_skill_root}/tools/research/merge_research.py" "{skill_dir}"knowledge/research/merged/summary.md - Read
knowledge/research/merged/summary.mdand confirm:Files scanned >= 3Unique URLs >= 2Potential long quote lines = 0- URLs in notes are actual inspected pages, not platform roots, search/topic pages, or placeholder paths If these do not hold, extend the research notes before continuing or explicitly record the collection limits.
- Quality checkpoint (Phase 1.5): before entering analysis, show the user a structured collection summary:
Wait for user confirmation before continuing. If the user flags issues or wants more depth, extend research first.┌──────────────────────────────┬──────────┬─────────────────────────────┐ │ Dimension │ Sources │ Key Finding │ ├──────────────────────────────┼──────────┼─────────────────────────────┤ │ 1 Writings │ N │ [core thesis / gap] │ │ 2 Conversations │ N │ [key pattern / gap] │ │ 3 Expression DNA │ N │ [style marker / gap] │ │ 4 Decisions │ N │ [decision pattern / gap] │ │ 5 External Views │ N │ [outside view / gap] │ │ 6 Timeline │ N │ [trajectory / gap] │ ├──────────────────────────────┼──────────┼─────────────────────────────┤ │ Contradictions │ N │ [summary] │ │ Thin dimensions │ [list] │ Backfill plan: [plan] │ │ Cold figure? │ yes/no │ │ └──────────────────────────────┴──────────┴─────────────────────────────┘ - Cold figure detection: if total sources < 10, apply the cold figure protocol:
- Limit mental models to 2–3
- Mark thin models as "based on limited information"
- Expand the honest boundaries section
- Tell the user what additional material would improve quality
- Celebrity analysis must prioritize:
- primary materials (source weight 1-3)
- merged research summary
- explicit user notes
celebrity / budget-unfriendly
- First read:
prompts/celebrity/budget_unfriendly/research.mdreferences/celebrity_budget_unfriendly_framework.md
- Create the research directories first:
mkdir -p "{skill_dir}/knowledge/research/raw" "{skill_dir}/knowledge/research/merged" "{skill_dir}/knowledge/research/reviews" - Confirm the collection strategy (determined during intake): local-first / web+local / web-only
- Build the six-track research set as independent files (never merged, never clone observations):
knowledge/research/raw/01_writings.md(Dim 1: Writings / systematic thought)knowledge/research/raw/02_conversations.md(Dim 2: Conversations under pressure)knowledge/research/raw/03_expression_dna.md(Dim 3: Linguistic fingerprint)knowledge/research/raw/04_decisions.md(Dim 4: Behavior and choices)knowledge/research/raw/05_external_views.md(Dim 5: External views and criticism)knowledge/research/raw/06_timeline.md(Dim 6: Cognitive trajectory)
- Research must follow taste principles + source blacklist + source hierarchy (see research prompt). Every evidence item must carry a source weight (1-7) annotation.
- Merge the research notes:
python3 "{distilly_skill_root}/tools/research/merge_research.py" "{skill_dir}" - Read
knowledge/research/merged/summary.mdand confirm the minimum floor:Files scanned >= 6Unique URLs >= 8Primary-source markers >= 3Source metadata blocks >= 6Contradiction bullets >= 6Inference bullets >= 6Potential long quote lines = 0Track coverage count = 6- URLs in notes are actual inspected pages, not platform roots, search/topic pages, or placeholder paths If these do not hold, keep filling the weak tracks before continuing to any review stage.
- Quality checkpoint (Phase 1.5): before entering audit, show the user a structured collection summary (with primary-source ratio, contradiction count, candidate mental models, known-answer candidates, thin dimensions, cold figure assessment). Wait for user confirmation before continuing.
- Then read:
prompts/celebrity/budget_unfriendly/audit.mdprompts/celebrity/budget_unfriendly/synthesis.mdreferences/celebrity_budget_unfriendly_template.md
- First write
knowledge/research/reviews/research_audit.md- The audit must produce an explicit
PASS / FAIL - The audit must verify: source hierarchy compliance (no blacklisted sources), primary-source ratio > 50%, taste principle compliance, cold figure assessment
- If the audit says
FAIL, follow the Backfill Tasks before synthesis
- The audit must produce an explicit
- Extraction checkpoint (Phase 2.5): after audit PASS, show the user a summary of candidate mental models (with triple-gate verdict, evidence anchors, failure modes). Confirm reasonableness before synthesis.
- Then write
knowledge/research/reviews/synthesis.md- Apply the triple gate to candidate mental models:
- cross-context recurrence
- generative power
- exclusivity
- Also extract intellectual genealogy seeds (influenced by / diverged from) and Agentic Protocol seeds (the dimensions this person would investigate when facing a novel question)
- Apply the triple gate to candidate mental models:
- Then use
prompts/celebrity/budget_unfriendly/validation.mdto write:knowledge/research/reviews/validation.md- Validation must produce an explicit
PASS / FAIL - Validation must perform: known-answer check (≥2 questions) + edge-case check (1 question) + voice check (100-word blind test) + copyright check + Agentic Protocol check
- If validation says
FAIL, revise the draft before continuing
- Budget-unfriendly celebrity analysis must prioritize:
- six-track raw notes
- merged research summary
- research audit
- synthesis review (with genealogy + Agentic Protocol seeds)
- validation review
- explicit user notes
Shared rules for both celebrity profiles:
- If external collection fails or a platform blocks access:
- tell the user exactly what was blocked
- preserve the raw research notes and merged summary
- continue generation with the available materials
- treat
source_groundingas incomplete - never invent URLs, quotes, titles, or generic homepage links just to satisfy the checker
- Do not store full transcripts, full subtitles, or long verbatim source passages in the repository
- Keep the stored notes paraphrased, structured, and copyright-safe
Once the family is resolved, analyze along two tracks:
Track A (Work Skill):
- Refer to
prompts/work_analyzer.md - Extract: responsible systems, technical standards, workflow, output preferences, experience
- For
celebrity, interpretworkas methods, judgment frameworks, and decision patterns rather than literal job scope
Track B (Persona):
- Use the family-specific persona analyzer
- If
celebritywithresearch_profile=budget-unfriendly, use:prompts/celebrity/budget_unfriendly/persona_analyzer.md
- Translate user-provided tags into concrete behavior rules
- Extract from materials: communication style, decision patterns, interpersonal behavior
- For
celebrity, retain:- mental models
- decision heuristics
- expression DNA
- contradictions
- honest boundaries
Step 4: Generate and Preview
Use prompts/work_builder.md to generate Work content.
Use the family-specific persona builder to generate Persona content.
Mapping:
colleague→prompts/persona_builder.mdrelationship→prompts/relationship/persona_builder.mdcelebrity→prompts/celebrity/persona_builder.mdcelebrity+budget-unfriendly→prompts/celebrity/budget_unfriendly/persona_builder.md
Show the user a summary (5-8 lines each), ask:
Work Skill Summary:
- Responsible for: {xxx}
- Tech stack: {xxx}
- CR focus: {xxx}
...
Persona Summary:
- Core personality: {xxx}
- Communication style: {xxx}
- Decision pattern: {xxx}
...
Confirm generation? Or need adjustments?
Step 5: Write Files
After user confirmation, do not hand-build a skills/colleague/{slug}-style tree. Always go through the writer:
- Resolve the current storage root:
colleague→./skills/colleaguerelationship→./skills/relationshipcelebrity→./skills/celebrity
- Use the
Writetool to create three temporary files:/tmp/distilly_{slug}_meta.json/tmp/distilly_{slug}_work.md/tmp/distilly_{slug}_persona.md
- The temporary meta file must include at least:
namedisplay_namecharacterresearch_profile(required whencharacter=celebrity)classification.language(must match the user's language, for examplezh-CNoren)profiletagsknowledge_sources
- Then call:
python3 "{distilly_skill_root}/tools/skill_writer.py" \ --action create \ --character {character} \ --research-profile {research_profile} \ --slug {slug} \ --name "{name}" \ --meta /tmp/distilly_{slug}_meta.json \ --work /tmp/distilly_{slug}_work.md \ --persona /tmp/distilly_{slug}_persona.md \ --base-dir {resolved_base_dir} - This command will generate:
SKILL.mdwork.mdpersona.mdwork_skill.mdpersona_skill.mdmanifest.jsonmeta.json- To install the generated role skill into a host, append the relevant flag:
- Claude Code:
--install-claude-skill - OpenClaw:
--install-openclaw-skill - Codex:
--install-codex-skill - Hermes: run
python3 "{distilly_skill_root}/tools/install_generated_skill.py" --skill-dir "{resolved_base_dir}/{slug}" --host hermes --force; for a trusted project, append--skills-dir .hermes/skills, runhermes skills trust, then start a new session or run/reload-skills. Use~/.agents/skillsonly when it is explicitly configured in Hermesskills.external_dirs - DeepSeek Harness: run
python3 "{distilly_skill_root}/tools/install_generated_skill.py" --skill-dir "{resolved_base_dir}/{slug}" --host deepseek-harness --force; append--skills-dir .dsh/skillsfor a project install - Pi: run
python3 "{distilly_skill_root}/tools/install_generated_skill.py" --skill-dir "{resolved_base_dir}/{slug}" --host pi --force; append--skills-dir .pi/skillsfor a project install, then invoke it with/skill:{character}-{slug} - Grok Build: run
python3 "{distilly_skill_root}/tools/install_generated_skill.py" --skill-dir "{resolved_base_dir}/{slug}" --host grok-build --force; append--skills-dir .grok/skillsfor a project install - OpenCode: run
python3 "{distilly_skill_root}/tools/install_generated_skill.py" --skill-dir "{resolved_base_dir}/{slug}" --host opencode --force; append--skills-dir .opencode/skillsfor a project install - The shared installer writes only the self-contained
SKILL.mdand install metadata and normalizes legacy frontmatter in the installed copy. Do not manually copy the whole generated directory; it may contain private source material - Claude Code on Windows: optionally add
--install-claude-command-shim
- Claude Code:
- If the current family is
celebrity, run a quality check after creation:python3 "{distilly_skill_root}/tools/research/quality_check.py" "{resolved_base_dir}/{slug}/SKILL.md" --profile {research_profile} - If
source_groundingstill fails for acelebrityskill:- you may add honest limitation notes and a grounded source summary
- only add URLs when they are real, specific, and traceable sources
- never use site roots, topic pages, search pages, or other generic links as fake grounding
- if no verified external sources exist, keep the FAIL state and explain what source material is still missing
When reporting success, return the correct family-specific location instead of assuming colleague storage.
Owner Profile
Build a profile of the agent's owner so the agent knows who it works for from the first session. It is context the agent reads every session, not a role-play Skill: do not generate a {character}-{slug} Skill and never write "you are <user>".
- Gather information with
{distilly_skill_root}/prompts/owner/intake.md: first discover the sources this agent already has (the tools, connectors and memory in this session, the platform the agent runs on such as Grok's X account, and the user files, connector configs and exports thattools/owner_sources.py discoverfinds on this machine) instead of walking a fixed list; propose which to read, ask the user which to use and whether to add anything else; read only what they pick, read-only; then ask only the questions the sources did not answer. Use only the host's own tools; never ask for API keys or OAuth setup on this path, and do not use the Lark, DingTalk or Slack collectors here. - Build the profile with
{distilly_skill_root}/prompts/owner/profile_builder.md, write it to/tmp/distilly_owner_profile.md, show the full text to the user and apply their corrections. - After the user approves, save it:
python3 "{distilly_skill_root}/tools/owner_profile.py" save --profile /tmp/distilly_owner_profile.md - Link it into the current host's always-on user file. Show the
--dry-runresult first and write only after the user agrees:
Claude Code usespython3 "{distilly_skill_root}/tools/owner_profile.py" link --host claude-code --dry-run python3 "{distilly_skill_root}/tools/owner_profile.py" link --host claude-code~/.claude/CLAUDE.md; OpenClaw (--host openclaw) uses the workspaceUSER.md. Other hosts are not supported yet; tell the user the full profile is at~/.distilly/owner/profile.md. - Only the text between the Distilly markers changes; everything else in the file is left alone and the previous file is backed up. Delete
/tmp/distilly_owner_profile.mdafterwards.
Updates: when the user corrects something or adds information, edit the full profile, then run save and link again. To undo: owner_profile.py unlink --host <host>.
Evolution Mode: Append Files
When user provides new files or text:
- Read new content using Step 2 methods
- Resolve the base dir for the current family
Readexisting{resolved_base_dir}/{slug}/work.mdandpersona.md- Use the family-specific merger prompt for incremental analysis
- Archive current version (Bash):
python3 "{distilly_skill_root}/tools/version_manager.py" \ --action backup \ --character {character} \ --slug {slug} \ --base-dir {resolved_base_dir} - Write work/persona delta into temporary patch files
- Call:
python3 "{distilly_skill_root}/tools/skill_writer.py" \ --action update \ --character {character} \ --slug {slug} \ --work-patch /tmp/distilly_{slug}_work_patch.md \ --persona-patch /tmp/distilly_{slug}_persona_patch.md \ --base-dir {resolved_base_dir} - If the current family is
celebrity, run the quality check again after the update
Evolution Mode: Conversation Correction
When user expresses "that's wrong" / "he should be":
- Refer to
prompts/correction_handler.mdto identify correction content - Determine if it belongs to Work (technical/workflow) or Persona (personality/communication)
- If it belongs to Work:
- Generate
/tmp/distilly_{slug}_work_patch.md - The patch must be one or more replaceable
##sections - Call:
python3 "{distilly_skill_root}/tools/skill_writer.py" \ --action update \ --character {character} \ --slug {slug} \ --work-patch /tmp/distilly_{slug}_work_patch.md \ --base-dir {resolved_base_dir}
- Generate
- If it belongs to Persona:
- Write the correction record to
/tmp/distilly_{slug}_correction.json - For a single correction, write
{scene, wrong, correct} - For multiple persona corrections, write
{"persona_corrections": [{...}, {...}]} - Call:
python3 "{distilly_skill_root}/tools/skill_writer.py" \ --action update \ --character {character} \ --slug {slug} \ --correction-json /tmp/distilly_{slug}_correction.json \ --base-dir {resolved_base_dir}
- Write the correction record to
- If the current family is
celebrity, run the quality check again after the update - Do not hand-edit
work.md,persona.md,SKILL.md, ormeta.json; always update throughskill_writer.py
Management Operations
List skills across the three families:
python3 "{distilly_skill_root}/tools/skill_writer.py" --action list --character colleague --base-dir ./skills/colleague
python3 "{distilly_skill_root}/tools/skill_writer.py" --action list --character relationship --base-dir ./skills/relationship
python3 "{distilly_skill_root}/tools/skill_writer.py" --action list --character celebrity --base-dir ./skills/celebrity
Roll back a specific skill version:
# colleague
python3 "{distilly_skill_root}/tools/version_manager.py" --action rollback --character colleague --slug {slug} --version {version} --base-dir ./skills/colleague
# relationship
python3 "{distilly_skill_root}/tools/version_manager.py" --action rollback --character relationship --slug {slug} --version {version} --base-dir ./skills/relationship
# celebrity
python3 "{distilly_skill_root}/tools/version_manager.py" --action rollback --character celebrity --slug {slug} --version {version} --base-dir ./skills/celebrity
Delete a specific skill: After confirming the character family:
# colleague
rm -rf skills/colleague/{slug}
# relationship
rm -rf skills/relationship/{slug}
# celebrity
rm -rf skills/celebrity/{slug}
レビュー
まだレビューはありません。使ってみた感想をお寄せください。