Install
$ agentstack add skill-astralune-ai-dunbar-contacts-add ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ● Filesystem access Used
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
contacts-add — add a new person to your dunbar workspace
User input: /contacts-add $ARGUMENTS where $ARGUMENTS is a natural-language description of one person.
Where's my dunbar root?
Find it in this order, same as the contacts-sync skill:
$DUNBAR_ROOTenvironment variable- Current working directory if it has
contacts.csvand at least one0N_*circle folder - Ask the user
1. Dedupe first
NAME=""
grep -ih "^${NAME}," "$DUNBAR_ROOT/contacts.csv"
If a row is found → tell the user "X already exists in your contacts — update instead of add?" and wait for their call before proceeding.
2. Parse the input (only what's stated, never inferred)
Extract from $ARGUMENTS (leave blank if not stated):
| Field | Rule | |-------|------| | 昵称 | Required. Identify from the input (the noun phrase after "add", "new", etc.) | | 真实姓名 | Only if the user said the full name. If only a nickname is given, leave blank | | 公司 / 职位 / 行业 | Only if explicitly stated | | 身份 | Whatever role the user described ("agent", "friend", "classmate") | | 介绍人 | Only if the user said "introduced by X" | | 电话 / 微信 / Email / Discord | Extract verbatim | | LinkedIn | Full URL (linkedin.com/in//) | | 社交媒体 | Handle or link for Twitter / IG / TikTok / 小红书 / etc. | | 家庭地址 | Only if user said "lives in X" / "home is in X" | | 办公地址 | Only if user said "works in X" / "office is in X" | | 圈层 | Only if user named one; otherwise see §3 | | 标签 | Keywords the user mentioned, semicolon-separated |
Never fabricate any field. If the user didn't say it, it stays blank. (This is the single most-violated rule when LLMs try to be "helpful" — resist.)
3. Pick a circle
- User named one → use it
- Default to 熟人 (
04_熟人_casual) when in doubt — the safe fallback - If context strongly hints (e.g. "my partner" → 核心; "we'll be working together regularly" → 常联系), suggest one and confirm
- When unsure, ask one short question rather than guess
4. Create the folder + stub MD
mkdir -p "$DUNBAR_ROOT///"
Write .md, following the template (do NOT include `` block — sync.py adds it):
#
## Basics
- Public name:
- (other fields: only what the user provided; leave omitted ones out — don't list "TBD" placeholders)
## How we know each other
_(empty if the user didn't say)_
## Interactions
_(empty — fill in over time)_
## Shared items / follow-ups
_(empty — fill in over time)_
If the person is a creator / public figure / has notable online presence, you may add ## Content notes and ## Public metrics sections.
5. Append a CSV row
Use Python (not awk — quoted fields with commas will break):
import csv, os
p = os.path.join(os.environ["DUNBAR_ROOT"], "contacts.csv")
with open(p, encoding="utf-8") as f:
rows = list(csv.reader(f))
header = rows[0]
new_row = [""] * len(header)
new_row[header.index("昵称")] = ""
# ... fill only the columns the user provided ...
rows.append(new_row)
with open(p, "w", encoding="utf-8", newline="") as f:
csv.writer(f).writerows(rows)
Leave 圈层 and 详档 blank in this step — sync.py owns those (filesystem is the source of truth).
6. Run sync
python3 "$DUNBAR_ROOT/sync.py" --root "$DUNBAR_ROOT"
This will:
- Detect the new folder → fill in 圈层 + 详档
- Write the `` summary block at the top of the .md
7. Report
✅ Added to contacts.csv
Circle: · Profile: //.md
Filled:
Empty (fill in later if you want):
-
8. Don't ❌
- Don't invent any field value (introducer, circle, industry, birthday, etc.)
- Don't write "TBD", "to be confirmed", "🔴 risk", "verify this" sections in the MD body
- Don't write audit-style follow-ups about the person (e.g. "[ ] check whether their credentials are real")
- Don't bypass sync.py to hand-edit 圈层 / 详档 in the CSV
- Don't add the same person twice (step 1 dedupe is mandatory)
- When 真实姓名 == 昵称, leave 真实姓名 blank (don't copy)
9. ⛔ Hard rule: "Organization / partnership = only if it's actually happening"
Any description of an organization, company, partnership, project, role, or title can ONLY be written into the contacts profile when that organization is actually operating and that partnership is actually under way.
| State | Can it go in the contact's profile (公司 / 职位 / 身份 / 标签 / 备注)? | |---|---| | Registered company / signed contract / work in progress | ✅ yes | | Salary paid / project delivered / money received | ✅ yes | | "We're planning to set up" / MOU draft / "we intend to" | ❌ no | | Prep meetings / framework conversations / on-hold / pending Asher's confirmation | ❌ no | | Other-party self-claim with no actual output | ❌ no |
Violating this is the single biggest failure mode of contact-management LLMs. Even if the person introduces themselves as "CEO of X" — if X is a paper company and they've shipped nothing, in the contact record they are just the person, not "CEO of X".
✅ Always safe to record:
- The person themselves (education, languages, address, visa, personality, what they self-describe as their background)
- Things that have actually happened between you (meeting dates, conversations)
- The person's standalone identity ("UNSW MEd student" is a fact about them regardless of any business deal)
❌ Don't record:
- "CEO of X Co" — unless X is a registered entity and they are a legal officer
- "Co-founder of Y project" — unless Y has actually started shipping
- " partner / collaborator" — unless the partnership is concrete (signed / paid / actively executing)
- Speculative comp splits, unsigned terms, hypothetical roles
Project-prep artifacts (MOUs, org charts, external PDFs, draft frameworks) belong in a project workspace, not a contacts profile. Once the project actually exists, come back and fill in the 身份 / 公司 / 职位 columns.
10. Example
User input:
/contacts-add add Alice, my partner, lives in Sydney, alice@example.com
The skill does:
- grep
contacts.csvfor^Alice,→ not found → continue - Parse: 昵称=Alice, 身份=partner, 家庭地址=Sydney, Email=alice@example.com
- Circle → "partner" strongly hints 核心 → confirm with user, then proceed
mkdir -p $DUNBAR_ROOT/01_核心_core/Alice/- Write
Alice.mdwith Basics + How-we-know-each-other (empty, since user didn't elaborate) + empty Interactions + empty Shared - Append CSV row (21 cols, fill 昵称 / 身份 / 家庭地址 / Email, rest blank)
- Run sync.py → fills in 圈层=核心, 详档=01核心core/Alice/Alice.md, prepends summary block
- Report
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Astralune-ai
- Source: Astralune-ai/dunbar
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.