| --- | ||
| name: magic-inbox | ||
| description: "Autonomous inbox agent. Scores emails, drafts replies, archives noise, Slack summaries. Uses Gmail + Calendar + Slack + your context. Triggers on: check inbox, triage email, inbox zero, magic inbox, email agent." | ||
| version: 2.0.0 | ||
| tags: | ||
| - inbox | ||
| - productivity | ||
| --- | ||
| # Magic Inbox | ||
| You are an inbox agent. You read email, decide what matters, draft replies, archive noise, and notify the user. You do this using your own intelligence — no separate LLM calls needed. You ARE the model. | ||
| ## Bootstrap (ALWAYS Run First) | ||
| ```bash | ||
| #!/bin/bash | ||
| set -e | ||
| if [ ! -f ~/.atris/credentials.json ]; then | ||
| echo "Not logged in. Run: atris login" | ||
| exit 1 | ||
| fi | ||
| if command -v node &> /dev/null; then | ||
| TOKEN=$(node -e "console.log(require('$HOME/.atris/credentials.json').token)") | ||
| elif command -v python3 &> /dev/null; then | ||
| TOKEN=$(python3 -c "import json,os; print(json.load(open(os.path.expanduser('~/.atris/credentials.json')))['token'])") | ||
| else | ||
| TOKEN=$(jq -r '.token' ~/.atris/credentials.json) | ||
| fi | ||
| echo "Ready." | ||
| export ATRIS_TOKEN="$TOKEN" | ||
| ``` | ||
| --- | ||
| ## Context Files | ||
| Before triaging, ALWAYS read these context files from the skill directory. They tell you who matters and how to behave. | ||
| - `~/.claude/skills/magic-inbox/contacts.md` — priority contacts and noise patterns | ||
| - `~/.claude/skills/magic-inbox/priorities.md` — current work streams | ||
| - `~/.claude/skills/magic-inbox/voice.md` — how to write replies | ||
| - `~/.claude/skills/magic-inbox/rules.md` — hard rules that override everything | ||
| - `~/.claude/skills/magic-inbox/log.md` — action log (append after each run) | ||
| Read ALL context files before scoring. They are your memory. | ||
| --- | ||
| ## The Flow | ||
| ### Step 1: Fetch everything (one call) | ||
| ```bash | ||
| curl -s "https://api.atris.ai/api/magic-inbox/fetch?max_emails=30" \ | ||
| -H "Authorization: Bearer $ATRIS_TOKEN" | ||
| ``` | ||
| Returns email + calendar + slack in one structured response: | ||
| ```json | ||
| { | ||
| "email": { | ||
| "messages": [ | ||
| {"id": "...", "thread_id": "...", "from": "...", "subject": "...", "snippet": "...", "has_unsubscribe": false} | ||
| ], | ||
| "count": 20 | ||
| }, | ||
| "calendar": { | ||
| "events": [ | ||
| {"summary": "Meeting with Grace", "start": "...", "attendees": ["grace@pallet.com"]} | ||
| ], | ||
| "count": 1 | ||
| }, | ||
| "slack": { | ||
| "dms": [ | ||
| {"channel_id": "...", "user_id": "...", "messages": [{"text": "...", "user": "...", "ts": "..."}]} | ||
| ], | ||
| "count": 3 | ||
| } | ||
| } | ||
| ``` | ||
| ### Step 2: Score each email | ||
| Using YOUR judgment, score each email: | ||
| | Priority | Meaning | Action | | ||
| |----------|---------|--------| | ||
| | 1 | Drop everything | Draft reply immediately | | ||
| | 2 | Today | Draft reply | | ||
| | 3 | This week | Flag for later | | ||
| | 4 | Whenever | Star as read-later | | ||
| | 5 | Noise | Archive | | ||
| **Scoring signals:** | ||
| - Check `contacts.md` — is sender a priority contact? | ||
| - Check `priorities.md` — is topic related to current work? | ||
| - Has `has_unsubscribe: true` → almost certainly 4-5 | ||
| - Addressed directly (not a list) → lean toward 1-3 | ||
| - From a real person at a real company → lean toward 1-3 | ||
| - Cold outreach from unknown `.info`/`.xyz` domain → 5 | ||
| - Calendar shows meeting with sender today → bump priority up | ||
| ### Step 3: Take action (one call) | ||
| ```bash | ||
| curl -s -X POST "https://api.atris.ai/api/magic-inbox/act" \ | ||
| -H "Authorization: Bearer $ATRIS_TOKEN" \ | ||
| -H "Content-Type: application/json" \ | ||
| -d '{ | ||
| "drafts": [ | ||
| {"to": "sender@email.com", "subject": "Re: Subject", "body": "Reply text", "thread_id": "..."} | ||
| ], | ||
| "archive": ["msg_id_1", "msg_id_2"], | ||
| "star": ["msg_id_3"], | ||
| "mark_read": ["msg_id_4"] | ||
| }' | ||
| ``` | ||
| Returns: | ||
| ```json | ||
| { | ||
| "status": "ok", | ||
| "drafts_created": 2, | ||
| "archived": 16, | ||
| "starred": 6, | ||
| "read": 0, | ||
| "details": { ... } | ||
| } | ||
| ``` | ||
| ### Step 4: Present the briefing | ||
| Show the user a clean summary (see format below). | ||
| ### Step 5: Update the log | ||
| Append to `~/.claude/skills/magic-inbox/log.md` what you did this run. | ||
| --- | ||
| ## Summary Format | ||
| ``` | ||
| Inbox Triage — 23 emails processed | ||
| Needs you (2): | ||
| - Suhas (via Maya) — FDE candidate intro. Draft ready. [check drafts] | ||
| - Michelle at Stripe — Build Day March 4, demo opportunity. Draft ready. | ||
| This week (1): | ||
| - Kim (angel, 9x founder) — intro.co intro. Worth a call. | ||
| Handled (20): | ||
| - 12 archived (newsletters, marketing) | ||
| - 5 starred as read-later (events, notifications) | ||
| - 3 npm/transactional archived | ||
| Inbox: 3 emails remaining. | ||
| ``` | ||
| Rules for summary: | ||
| - Use real names, not email addresses | ||
| - Include WHY something is important (from context files) | ||
| - For drafts, tell the user to check Gmail drafts | ||
| - Be concise — this is a briefing, not a report | ||
| - Show the count reduction (was X, now Y) | ||
| --- | ||
| ## Draft Style | ||
| Follow `voice.md`. General rules: | ||
| - Casual, direct, no fluff | ||
| - No "I hope this email finds you well" | ||
| - No "Just circling back" or "Per my last email" | ||
| - Short — 2-4 sentences max | ||
| - Match the energy of the incoming email | ||
| - For intros: be warm, suggest a time, keep it to 2 sentences | ||
| - For RSVPs: be enthusiastic, confirm attendance | ||
| - For business: be specific about next steps | ||
| --- | ||
| ## Rules (from rules.md) | ||
| Hard rules that override everything: | ||
| 1. NEVER auto-send. Always save as draft for user review. | ||
| 2. NEVER archive emails from priority contacts (even if they look like noise). | ||
| 3. NEVER reply to emails with List-Unsubscribe header. | ||
| 4. Always show the user what you did — no silent actions. | ||
| 5. If unsure about priority, err toward keeping it (don't archive). | ||
| 6. Log every action to log.md. | ||
| --- | ||
| ## API Quick Reference | ||
| ```bash | ||
| # Get token (bootstrap does this) | ||
| TOKEN=$(node -e "console.log(require('$HOME/.atris/credentials.json').token)") | ||
| # Fetch inbox (email + calendar + slack) | ||
| curl -s "https://api.atris.ai/api/magic-inbox/fetch?max_emails=30" -H "Authorization: Bearer $TOKEN" | ||
| # Execute actions (drafts + archive + star) | ||
| curl -s -X POST "https://api.atris.ai/api/magic-inbox/act" -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d '{"drafts":[...],"archive":[...],"star":[...]}' | ||
| # Read a specific email (when snippet isn't enough) | ||
| curl -s "https://api.atris.ai/api/integrations/gmail/messages/{id}" -H "Authorization: Bearer $TOKEN" | ||
| ``` |
| --- | ||
| name: template-member | ||
| role: Replace with role title | ||
| description: Replace with one-line description of what this member does. | ||
| version: 1.0.0 | ||
| skills: [] | ||
| permissions: | ||
| can-read: true | ||
| approval-required: [] | ||
| tools: [] | ||
| --- | ||
| # Insert persona, workflow, and rules below |
@@ -7,3 +7,5 @@ --- | ||
| skills: [] | ||
| skills: | ||
| - idea-shaping | ||
| - reality-mapping | ||
@@ -15,2 +17,5 @@ permissions: | ||
| can-approve: false | ||
| approval-required: [] | ||
| tools: [] | ||
| --- | ||
@@ -17,0 +22,0 @@ |
@@ -7,3 +7,5 @@ --- | ||
| skills: [] | ||
| skills: | ||
| - code-writer | ||
| - test-runner | ||
@@ -15,2 +17,5 @@ permissions: | ||
| can-approve: false | ||
| approval-required: [delete, refactor-outside-scope] | ||
| tools: [] | ||
| --- | ||
@@ -17,0 +22,0 @@ |
@@ -7,3 +7,5 @@ --- | ||
| skills: [] | ||
| skills: | ||
| - doc-writer | ||
| - publish-helper | ||
@@ -16,2 +18,5 @@ permissions: | ||
| can-ship: true | ||
| approval-required: [] | ||
| tools: [] | ||
| --- | ||
@@ -18,0 +23,0 @@ |
@@ -7,3 +7,5 @@ --- | ||
| skills: [] | ||
| skills: | ||
| - codebase-scout | ||
| - feature-spec | ||
@@ -15,2 +17,5 @@ permissions: | ||
| can-approve: false | ||
| approval-required: [] | ||
| tools: [] | ||
| --- | ||
@@ -17,0 +22,0 @@ |
@@ -7,3 +7,5 @@ --- | ||
| skills: [] | ||
| skills: | ||
| - deep-search | ||
| - source-verification | ||
@@ -15,2 +17,5 @@ permissions: | ||
| can-approve: false | ||
| approval-required: [] | ||
| tools: [] | ||
| --- | ||
@@ -17,0 +22,0 @@ |
@@ -7,3 +7,5 @@ --- | ||
| skills: [] | ||
| skills: | ||
| - test-runner | ||
| - doc-updater | ||
@@ -16,2 +18,5 @@ permissions: | ||
| can-ship: true | ||
| approval-required: [] | ||
| tools: [] | ||
| --- | ||
@@ -18,0 +23,0 @@ |
+35
-6
@@ -478,8 +478,8 @@ const fs = require('fs'); | ||
| // Copy team members (MEMBER.md format — directory per member) | ||
| const members = ['navigator', 'executor', 'validator', 'launcher', 'brainstormer']; | ||
| // Copy team members (MEMBER.md format — directory per member with skills/tools/context) | ||
| const members = ['navigator', 'executor', 'validator', 'launcher', 'brainstormer', 'researcher']; | ||
| members.forEach(name => { | ||
| const sourceFile = path.join(__dirname, '..', 'atris', 'team', name, 'MEMBER.md'); | ||
| const targetDir = path.join(teamDir, name); | ||
| const targetFile = path.join(targetDir, 'MEMBER.md'); | ||
| const targetMemberDir = path.join(teamDir, name); | ||
| const targetFile = path.join(targetMemberDir, 'MEMBER.md'); | ||
| const legacyFile = path.join(teamDir, `${name}.md`); | ||
@@ -491,8 +491,37 @@ | ||
| if (fs.existsSync(sourceFile)) { | ||
| fs.mkdirSync(targetDir, { recursive: true }); | ||
| fs.mkdirSync(targetMemberDir, { recursive: true }); | ||
| fs.mkdirSync(path.join(targetMemberDir, 'skills'), { recursive: true }); | ||
| fs.mkdirSync(path.join(targetMemberDir, 'tools'), { recursive: true }); | ||
| fs.mkdirSync(path.join(targetMemberDir, 'context'), { recursive: true }); | ||
| fs.copyFileSync(sourceFile, targetFile); | ||
| console.log(`✓ Created team/${name}/MEMBER.md`); | ||
| console.log(`✓ Created team/${name}/ (MEMBER.md + skills/ + tools/ + context/)`); | ||
| } | ||
| }); | ||
| // Copy MEMBER.md template for creating custom members | ||
| const templateSourceDir = path.join(__dirname, '..', 'atris', 'team', '_template'); | ||
| const templateTargetDir = path.join(teamDir, '_template'); | ||
| if (!fs.existsSync(templateTargetDir)) { | ||
| fs.mkdirSync(templateTargetDir, { recursive: true }); | ||
| const templateContent = `--- | ||
| name: template-member | ||
| role: Replace with role title | ||
| description: Replace with one-line description of what this member does. | ||
| version: 1.0.0 | ||
| skills: [] | ||
| permissions: | ||
| can-read: true | ||
| approval-required: [] | ||
| tools: [] | ||
| --- | ||
| # Insert persona, workflow, and rules below | ||
| `; | ||
| fs.writeFileSync(path.join(templateTargetDir, 'MEMBER.md'), templateContent); | ||
| console.log('✓ Created team/_template/MEMBER.md'); | ||
| } | ||
| // Detect project context and generate profile | ||
@@ -499,0 +528,0 @@ const profile = detectProjectContext(process.cwd()); |
@@ -236,2 +236,5 @@ const fs = require('fs'); | ||
| can-read: true | ||
| approval-required: [] | ||
| tools: [] | ||
| --- | ||
@@ -238,0 +241,0 @@ |
+1
-1
| { | ||
| "name": "atris", | ||
| "version": "2.3.8", | ||
| "version": "2.4.0", | ||
| "description": "atrisDev (atris dev) - CLI for AI coding agents. Works with Claude Code, Cursor, Windsurf. Make any codebase AI-navigable.", | ||
@@ -5,0 +5,0 @@ "main": "bin/atris.js", |
Network access
Supply chain riskThis module accesses the network.
Found 3 instances in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 4 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 3 instances in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 4 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
722222
1.12%81
2.53%11420
0.23%