share-skill
Export Skill to Notion
Push a local skill's metadata and file to the Beam Nexus Skills database in Notion.
Purpose
This skill takes a local skill from 03-skills/ and creates a new entry in the company's Notion skills database. It handles:
- Validating SKILL.md format before upload
- Reading SKILL.md to extract metadata (including version)
- Automatically uploading all skill files via JSON bundle
- Mapping fields to Notion properties
- MANDATORY user confirmation before pushing
- Setting Owner from user-config.yaml
- Inferring appropriate Team (or creating new one)
- Creating the database entry with file attachment
Typically used after create-skill to share new skills with the company.
CRITICAL RULES
- ALWAYS confirm with user before pushing - Never auto-push
- ALWAYS set Owner - Use notion_user_id from user-config.yaml
- ALWAYS upload the skill file - Use Notion File Upload API (see Step 5)
- INFER appropriate Team - Don't default to Solutions. Think about scope:
- "General" for company-wide utility skills
- "Solutions" for client-facing/implementation skills
- "Engineering" for dev tools
- Create new team if needed
- ALWAYS check for duplicates first - Cannot overwrite others' skills
- NEVER delete skills from Notion - Deletion must be done manually in Notion UI
- Use --as-new for improved versions - Don't overwrite, create new entries
Safeguards
Pre-Flight Check (ALWAYS Run First)
Before ANY export operation, verify Notion setup:
python ../../notion-master/scripts/check_notion_config.py
If configuration missing:
- Option A: Run setup wizard:
python ../../notion-master/scripts/setup_notion.py - Option B: See ../../notion-master/references/setup-guide.md
Expected output if configured:
✅ ALL CHECKS PASSED
You're ready to use Notion skills
SKILL.md Validation
The upload script automatically validates SKILL.md before uploading:
[INFO] Validating SKILL.md...
[OK] SKILL.md valid
Validation checks:
- YAML frontmatter exists (starts with
---) - Required fields present:
name,description - Description contains trigger phrases (contains "when")
- Version format is valid (semantic versioning: 1.0, 1.0.0)
If validation fails:
[ERROR] SKILL.md validation failed:
✗ Missing required field: description
✗ Description should include trigger phrases
Fix these issues or use --skip-validation to bypass.
Duplicate Detection
When skill name already exists in Notion:
[ERROR] Skill 'my-skill' already exists in Notion!
Owner: Jack Li
Version: 1.0
URL: https://notion.so/my-skill-abc123
Options:
1. Use --as-new "new-name" to upload as improved version
2. Delete existing skill in Notion first
No overwriting allowed - This prevents accidental data loss and maintains clear ownership.
Prohibited Operations
| Operation | Status | Notes |
|---|---|---|
| Create new skill | ✅ Allowed | With confirmation |
| Create improved version | ✅ Allowed | Use --as-new flag |
| Overwrite existing | ❌ Blocked | Must delete in Notion first |
| Delete any skill | ❌ Blocked | Must use Notion UI |
| Bulk push | ❌ Blocked | One at a time only |
Workflow
Step 1: Read Local Skill
# Get skill metadata from SKILL.md
cat 03-skills/{skill-name}/SKILL.md
Extract from YAML header:
name→ Skill Namedescription→ Descriptionversion→ Version (defaults to 1.0)
Extract from content:
- Purpose section → Purpose field
Step 2: Prepare Skill Bundle
The upload script automatically creates a JSON bundle containing all skill files:
- SKILL.md (required)
- scripts/ folder (optional)
- references/ folder (optional)
- assets/ folder (optional)
Bundle format: {skill-name}.skill.json
{
"skill_name": "my-skill",
"version": "1.0",
"bundle_format": "nexus-skill-bundle-v1",
"created": "2025-12-10",
"files": {
"SKILL.md": "<base64-encoded content>",
"scripts/script.py": "<base64-encoded content>",
"references/guide.md": "<base64-encoded content>"
}
}
Note: Notion File Upload API doesn't support .zip files, so we use JSON with base64-encoded file contents. This preserves the full skill structure including scripts and references.
Step 3: Infer Team and Gather Info
AI should infer the Team based on skill purpose:
- General: Utility skills usable by anyone (query tools, import/export, etc.)
- Solutions: Client implementation, onboarding, customer-facing
- Engineering: Developer tools, CI/CD, testing
- Sales: Sales-specific workflows
- Other: Ask user if unclear
Present inference to user for confirmation:
Based on the skill's purpose, I suggest Team: "General"
(This is a utility skill for querying Notion databases)
Is this correct, or would you prefer a different team?
Step 4: Preview Before Push (MANDATORY)
Use --dry-run to preview without uploading:
python ../../notion-master/scripts/upload_skill.py 03-skills/{skill-name} --team General --dry-run
Output:
==================================================
[PREVIEW] Upload Summary
==================================================
Skill Name: my-skill
Version: 1.0
Team: General
Owner: Fredrik Falk
Bundle: my-skill.skill.json
Size: 4,521 bytes
Files: 3
==================================================
[DRY-RUN] No changes made. Remove --dry-run to upload.
WAIT FOR USER CONFIRMATION BEFORE PROCEEDING
Step 5: Create Notion Entry with File
Use the upload script:
python ../../notion-master/scripts/upload_skill.py 03-skills/{skill-name} --team General
Optional parameters:
# With integrations
python ../../notion-master/scripts/upload_skill.py 03-skills/my-skill --team General --integration "Beam AI,Linear"
# Dry run (preview without uploading)
python ../../notion-master/scripts/upload_skill.py 03-skills/my-skill --team General --dry-run
# Upload as new skill with different name (for improved versions)
python ../../notion-master/scripts/upload_skill.py 03-skills/my-skill --team General --as-new "my-skill-enhanced"
# Skip validation (not recommended)
python ../../notion-master/scripts/upload_skill.py 03-skills/my-skill --team General --skip-validation
The script handles:
- Validating SKILL.md format
- Reading SKILL.md metadata (including version)
- Checking for duplicates
- Creating JSON bundle with all files
- Creating file upload object
- Uploading file content
- Creating database entry with attachment
Step 6: Confirm Success
✅ Skill pushed to Notion!
📄 Skill Name: {skill-name}
📊 Version: 1.0
🔗 Notion URL: {url}
👥 Owner: {owner-name}
📁 Team: {team}
📎 Files in bundle: 3
The skill is now discoverable by anyone at Beam AI.
Version Tracking
Add version to SKILL.md frontmatter:
---
name: my-skill
description: Load when user says "do the thing"...
version: 1.0
---
Version Format Standard
Format: MAJOR.MINOR or MAJOR.MINOR.PATCH
| Valid | Invalid |
|---|---|
1.0 |
v1.0 (no "v" prefix) |
1.1 |
1 (needs MAJOR.MINOR) |
2.0 |
latest (must be numeric) |
1.0.0 |
1.0.0.0 (too many segments) |
When to Increment
| Change Type | Version Bump | Example |
|---|---|---|
| Bug fixes, typos | Increment MINOR | 1.0 → 1.1 |
| Minor improvements | Increment MINOR | 1.1 → 1.2 |
| New features added | Increment MINOR | 1.2 → 1.3 |
| Breaking changes | Increment MAJOR | 1.x → 2.0 |
| Complete rewrite | Increment MAJOR | 2.x → 3.0 |
Version Tracking Locations
Version is tracked in 3 places:
- SKILL.md frontmatter - Source of truth (
version:field) - JSON bundle - Embedded in upload (
"version": "1.0") - Notion database - Displayed in
Versioncolumn
Uploading Improved Versions
For significant improvements, use --as-new:
python upload_skill.py 03-skills/my-skill --team General --as-new "my-skill-v2"
This creates a new database entry rather than overwriting (which is blocked).
Field Mapping
See complete database schema:
Quick reference:
| Local (SKILL.md) | Notion Property | Type | Required | Notes |
|---|---|---|---|---|
name: in YAML |
Skill Name | title | Yes | |
description: in YAML |
Description | rich_text | Yes | |
version: in YAML |
Version | rich_text | Yes | Defaults to 1.0 |
| Purpose section | Purpose | rich_text | No | Extract from ## Purpose |
| AI infers + user confirms | Team | select | Yes | Create if doesn't exist |
| AI infers from content | Integration | multi_select | No | Beam AI, Linear, Notion, etc. |
| user-config.yaml | Owner | people | Yes | notion_user_id |
| Today's date | Created | date | Yes | Auto-set |
| JSON bundle | Skill | files | Yes | Auto-uploaded via File Upload API |
Configuration
From .env:
NOTION_API_KEY- Your Notion integration tokenNOTION_SKILLS_DB_ID- Database ID:2bc2cadf-bbbc-80be-af8a-d45dfc8dfa2e
From user-config.yaml:
notion_user_id- Your Notion user ID for Owner fieldnotion_user_name- Display name
Available Teams (can create new):
- General (for utility/company-wide skills)
- Solutions (for client-facing skills)
- Engineering (for dev tools)
- Sales (for sales workflows)
Available Integrations:
- Beam AI
- Linear
- Notion
Team Inference Rules
| Skill Type | Suggested Team | Reasoning |
|---|---|---|
| Query/import/export tools | General | Used by everyone |
| Notion/Linear integrations | General | Cross-functional |
| Client onboarding | Solutions | Client-facing |
| Agent building/testing | Solutions | Implementation work |
| CI/CD, testing tools | Engineering | Dev-focused |
| Proposal generators | Sales | Sales-specific |
| Unknown | Ask user | When unclear |
Example Usage
Export a New Skill
User: "Push query-notion-db to Notion"
AI: [Validates SKILL.md - passes]
[Checks for duplicates - none found]
Based on the skill's purpose (querying Notion databases for any use),
I suggest Team: "General"
This is a utility skill that anyone at Beam AI could use.
Is this correct? (yes/no/specify different)
User: "yes"
AI: Running dry-run preview...
==================================================
[PREVIEW] Upload Summary
==================================================
Skill Name: query-notion-db
Version: 1.0
Team: General
Owner: Fredrik Falk
Bundle: query-notion-db.skill.json
Size: 4,521 bytes
Files: 2
==================================================
Do you want to push this to Notion? (yes/no)
User: "yes"
AI: ✅ Skill pushed to Notion!
📄 Skill Name: query-notion-db
📊 Version: 1.0
🔗 https://notion.so/query-notion-db-abc123
👥 Owner: Fredrik Falk
📁 Team: General
Export Improved Version of Existing Skill
User: "Push my improved version of setup-linear-onboarding-template"
AI: [Validates SKILL.md - passes]
[Checks for duplicates]
⚠️ Skill "setup-linear-onboarding-template" already exists in Notion!
Owner: Jack Li
Version: 1.0
Since you've made improvements, I recommend uploading as a new skill.
Suggested name: "setup-linear-onboarding-template-enhanced"
Would you like to:
1. Upload as "setup-linear-onboarding-template-enhanced"
2. Choose a different name
3. Cancel
User: "1"
AI: ✅ Skill pushed to Notion!
📄 Skill Name: setup-linear-onboarding-template-enhanced
📊 Version: 1.0
🔗 https://notion.so/setup-linear-onboarding-template-enhanced-def456
Error Handling
Common errors:
| Error | Cause | Solution |
|---|---|---|
| 401 Unauthorized | Invalid API key | Check NOTION_API_KEY in .env |
| 400 Bad Request | Invalid property format | Check field mapping |
| Skill already exists | Duplicate in Notion | Use --as-new or delete in Notion |
| Missing notion_user_id | Not in user-config.yaml | Prompt to add it |
| Missing SKILL.md | Invalid skill path | Verify path |
| Validation failed | Invalid SKILL.md format | Fix issues or use --skip-validation |
For detailed troubleshooting:
Notes
- File upload: Uses Notion's File Upload API (3-step process: create upload object → send file → attach to page). Skills are packaged as JSON bundles (
.skill.json) containing all files with base64-encoded contents. This preserves the complete skill structure including scripts/, references/, and assets/ folders. - Validation: SKILL.md is validated before upload. Use --skip-validation to bypass (not recommended).
- Dry-run: Use --dry-run to preview what would be uploaded without actually pushing.
- Improved versions: Use --as-new "new-name" to upload improved versions without overwriting.
- Version tracking: Add
version:to SKILL.md frontmatter. Tracked in bundle AND Notion. - New teams auto-create: If you specify a team that doesn't exist, Notion will create it automatically.
- Owner is mandatory: Always set from user-config.yaml to maintain audit trail.
- Always confirm: Never push without explicit user approval.
Additional References
For more details:
- ../../notion-master/references/setup-guide.md - Initial setup
- ../../notion-master/references/api-reference.md - File upload API
- ../../notion-master/references/database-schema.md - Complete schema
- ../../notion-master/references/error-handling.md - Troubleshooting
More from abdullahbeam/nexus-design-abdullah
mental-models
Load when user says "mental model", "think through this", "structured thinking", "help me decide", "analyze this problem", "first principles", "pre-mortem", "stakeholder mapping", "what framework should I use", or any specific model name. Provides 59 thinking frameworks for decision-making, problem decomposition, and strategic analysis.
64notion-connect
Connect to any Notion database by name. Load when user mentions 'notion', 'connect notion', 'setup notion', 'query [database-name]', 'add to [database]', 'notion databases', or any database name from persistent context. Meta-skill that discovers workspace, caches schemas, and routes to appropriate operations.
24google-tasks
Manage Google Tasks and task lists. Load when user mentions 'google tasks', 'tasks', 'todo list', 'create task', 'complete task', or references task/todo management.
21google-sheets
Read and write Google Sheets data. Load when user mentions 'google sheets', 'spreadsheet', 'update sheet', 'read sheet', 'append to sheet', or references extracting data to update a tracking sheet.
20airtable-master
Shared resource library for Airtable integration skills. DO NOT load directly - provides common references (setup, API docs, error handling, field types) and scripts used by airtable-connect, airtable-query, and airtable-sync.
19google-integration
Complete Google Workspace integration (Gmail, Docs, Sheets, Calendar, Drive, Tasks, Slides). Load when user mentions 'google', 'gmail', 'email', 'google docs', 'google sheets', 'spreadsheet', 'google calendar', 'schedule meeting', 'calendar', 'google drive', 'upload file', 'download file', 'google tasks', 'todo', 'google slides', 'presentation', or any Google service operation.
18