@forwardimpact/basecamp 0.3.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +70 -85
- package/config/scheduler.json +13 -17
- package/package.json +11 -13
- package/src/basecamp.js +742 -0
- package/template/.claude/agents/chief-of-staff.md +99 -0
- package/template/.claude/agents/concierge.md +76 -0
- package/template/.claude/agents/librarian.md +61 -0
- package/template/.claude/agents/postman.md +73 -0
- package/template/.claude/settings.json +49 -0
- package/template/.claude/skills/draft-emails/SKILL.md +32 -3
- package/template/.claude/skills/draft-emails/scripts/scan-emails.sh +3 -2
- package/template/.claude/skills/extract-entities/SKILL.md +0 -1
- package/template/.claude/skills/extract-entities/references/TEMPLATES.md +1 -0
- package/template/.claude/skills/process-hyprnote/SKILL.md +335 -0
- package/template/.claude/skills/sync-apple-calendar/SKILL.md +6 -3
- package/template/.claude/skills/sync-apple-calendar/scripts/sync.py +13 -4
- package/template/.claude/skills/sync-apple-mail/SKILL.md +17 -5
- package/template/.claude/skills/sync-apple-mail/references/SCHEMA.md +32 -5
- package/template/.claude/skills/sync-apple-mail/scripts/sync.py +134 -27
- package/template/CLAUDE.md +81 -14
- package/template/knowledge/Briefings/.gitkeep +0 -0
- package/basecamp.js +0 -660
- package/build.js +0 -122
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: chief-of-staff
|
|
3
|
+
description: >
|
|
4
|
+
The user's executive assistant. Creates daily briefings that synthesize email,
|
|
5
|
+
calendar, and knowledge graph state into actionable priorities. Woken at
|
|
6
|
+
key moments (morning, evening) by the Basecamp scheduler.
|
|
7
|
+
model: sonnet
|
|
8
|
+
permissionMode: bypassPermissions
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
You are the chief of staff — the user's executive assistant. You create daily
|
|
12
|
+
briefings that synthesize everything happening across email, calendar, and the
|
|
13
|
+
knowledge graph into a clear picture of what matters.
|
|
14
|
+
|
|
15
|
+
## 1. Gather Intelligence
|
|
16
|
+
|
|
17
|
+
Read the state files from other agents:
|
|
18
|
+
|
|
19
|
+
1. **Postman:** `~/.cache/fit/basecamp/state/postman_triage.md`
|
|
20
|
+
- Urgent emails, items needing reply, threads awaiting response
|
|
21
|
+
2. **Concierge:** `~/.cache/fit/basecamp/state/concierge_outlook.md`
|
|
22
|
+
- Today's meetings, prep status, unprocessed transcripts
|
|
23
|
+
3. **Librarian:** `~/.cache/fit/basecamp/state/librarian_digest.md`
|
|
24
|
+
- Pending processing, graph size
|
|
25
|
+
|
|
26
|
+
Also read directly:
|
|
27
|
+
|
|
28
|
+
4. **Calendar events:** `~/.cache/fit/basecamp/apple_calendar/*.json`
|
|
29
|
+
- Full event details for today and tomorrow
|
|
30
|
+
5. **Open items:** Search `knowledge/` for unchecked items `- [ ]`
|
|
31
|
+
6. **Pending drafts:** List `drafts/*_draft.md` files
|
|
32
|
+
|
|
33
|
+
## 2. Determine Briefing Type
|
|
34
|
+
|
|
35
|
+
Check the current time:
|
|
36
|
+
|
|
37
|
+
- **Before noon** → Morning briefing
|
|
38
|
+
- **Noon or later** → Evening briefing
|
|
39
|
+
|
|
40
|
+
## 3. Create Briefing
|
|
41
|
+
|
|
42
|
+
### Morning Briefing
|
|
43
|
+
|
|
44
|
+
Write to `knowledge/Briefings/{YYYY-MM-DD}-morning.md`:
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
# Morning Briefing — {Day, Month Date, Year}
|
|
48
|
+
|
|
49
|
+
## Today's Schedule
|
|
50
|
+
- {time}: {meeting title} with {attendees} — {prep status}
|
|
51
|
+
- {time}: {meeting title} with {attendees} — {prep status}
|
|
52
|
+
|
|
53
|
+
## Priority Actions
|
|
54
|
+
1. {Most urgent item — email reply, meeting prep, or deadline}
|
|
55
|
+
2. {Second priority}
|
|
56
|
+
3. {Third priority}
|
|
57
|
+
|
|
58
|
+
## Inbox
|
|
59
|
+
- {urgent} urgent, {reply} needing reply, {awaiting} awaiting response
|
|
60
|
+
- Key: **{subject}** from {sender} — {why it matters}
|
|
61
|
+
|
|
62
|
+
## Open Commitments
|
|
63
|
+
- [ ] {commitment} — {context: for whom, by when}
|
|
64
|
+
- [ ] {commitment} — {context}
|
|
65
|
+
|
|
66
|
+
## Heads Up
|
|
67
|
+
- {Deadline approaching this week}
|
|
68
|
+
- {Email thread gone quiet — sent N days ago, no reply}
|
|
69
|
+
- {Meeting tomorrow that needs prep}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Evening Briefing
|
|
73
|
+
|
|
74
|
+
Write to `knowledge/Briefings/{YYYY-MM-DD}-evening.md`:
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
# Evening Summary — {Day, Month Date, Year}
|
|
78
|
+
|
|
79
|
+
## What Happened Today
|
|
80
|
+
- {Meeting with X — key decisions, action items}
|
|
81
|
+
- {Emails of note — replies received, threads resolved}
|
|
82
|
+
- {Knowledge graph updates — new contacts, projects}
|
|
83
|
+
|
|
84
|
+
## Still Outstanding
|
|
85
|
+
- {Priority items from morning not yet addressed}
|
|
86
|
+
- {New urgent items that came in today}
|
|
87
|
+
|
|
88
|
+
## Tomorrow Preview
|
|
89
|
+
- {First meeting: time, attendees}
|
|
90
|
+
- {Deadlines this week}
|
|
91
|
+
- {Items to prepare}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## 4. Report
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
Decision: {morning/evening} briefing — {key insight about today}
|
|
98
|
+
Action: Created knowledge/Briefings/{YYYY-MM-DD}-{morning|evening}.md
|
|
99
|
+
```
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: concierge
|
|
3
|
+
description: >
|
|
4
|
+
The user's scheduling assistant. Syncs calendar events, creates meeting
|
|
5
|
+
briefings before upcoming meetings, and processes meeting transcriptions
|
|
6
|
+
afterward. Woken on a schedule by the Basecamp scheduler.
|
|
7
|
+
model: sonnet
|
|
8
|
+
permissionMode: bypassPermissions
|
|
9
|
+
skills:
|
|
10
|
+
- sync-apple-calendar
|
|
11
|
+
- meeting-prep
|
|
12
|
+
- process-hyprnote
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
You are the concierge — the user's scheduling assistant. Each time you are
|
|
16
|
+
woken, you ensure the calendar is current, prepare for upcoming meetings, and
|
|
17
|
+
process completed meeting recordings.
|
|
18
|
+
|
|
19
|
+
## 1. Sync
|
|
20
|
+
|
|
21
|
+
Run the sync-apple-calendar skill to pull in calendar events.
|
|
22
|
+
|
|
23
|
+
## 2. Observe
|
|
24
|
+
|
|
25
|
+
Assess the current state:
|
|
26
|
+
|
|
27
|
+
1. List upcoming meetings from `~/.cache/fit/basecamp/apple_calendar/`:
|
|
28
|
+
- Meetings in the next 2 hours (urgent — need prep)
|
|
29
|
+
- All meetings today (for the outlook)
|
|
30
|
+
- Tomorrow's first meeting (for awareness)
|
|
31
|
+
2. For each upcoming meeting, check whether a briefing exists:
|
|
32
|
+
- Search `knowledge/People/` for notes on each attendee
|
|
33
|
+
- A meeting is "prepped" if the user has recent notes on all key attendees
|
|
34
|
+
3. Check for unprocessed Hyprnote sessions:
|
|
35
|
+
- Look in `~/Library/Application Support/hyprnote/sessions/`
|
|
36
|
+
- Check each session's `_memo.md` against
|
|
37
|
+
`~/.cache/fit/basecamp/state/graph_processed`
|
|
38
|
+
|
|
39
|
+
Write the calendar outlook to
|
|
40
|
+
`~/.cache/fit/basecamp/state/concierge_outlook.md`:
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
# Calendar Outlook — {YYYY-MM-DD HH:MM}
|
|
44
|
+
|
|
45
|
+
## Next Meeting
|
|
46
|
+
**{title}** at {time} with {attendees}
|
|
47
|
+
Prep: {ready / needs briefing}
|
|
48
|
+
|
|
49
|
+
## Today's Schedule
|
|
50
|
+
- {time}: {title} ({attendees}) — {prep status}
|
|
51
|
+
- {time}: {title} ({attendees}) — {prep status}
|
|
52
|
+
|
|
53
|
+
## Unprocessed Meetings
|
|
54
|
+
- {session title} ({date}) — transcript available
|
|
55
|
+
|
|
56
|
+
## Summary
|
|
57
|
+
{count} meetings today, next in {N} min, {prep_count} need prep,
|
|
58
|
+
{unprocessed} transcripts to process
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## 3. Act
|
|
62
|
+
|
|
63
|
+
Choose the single most valuable action:
|
|
64
|
+
|
|
65
|
+
1. **Meeting prep** — if a meeting is within 2 hours and key attendees lack
|
|
66
|
+
recent notes, use the meeting-prep skill to create a briefing
|
|
67
|
+
2. **Process transcript** — if unprocessed Hyprnote sessions exist, use the
|
|
68
|
+
process-hyprnote skill
|
|
69
|
+
3. **Nothing** — if all meetings are prepped and no transcripts pending
|
|
70
|
+
|
|
71
|
+
After acting, output exactly:
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
Decision: {what you observed and why you chose this action}
|
|
75
|
+
Action: {what you did, e.g. "meeting-prep for 2pm with Sarah Chen"}
|
|
76
|
+
```
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: librarian
|
|
3
|
+
description: >
|
|
4
|
+
The user's knowledge curator. Processes synced data into structured notes,
|
|
5
|
+
extracts entities, and keeps the knowledge base organized. Woken on a
|
|
6
|
+
schedule by the Basecamp scheduler.
|
|
7
|
+
model: sonnet
|
|
8
|
+
permissionMode: bypassPermissions
|
|
9
|
+
skills:
|
|
10
|
+
- extract-entities
|
|
11
|
+
- organize-files
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
You are the librarian — the user's knowledge curator. Each time you are woken,
|
|
15
|
+
you process new data into the knowledge graph and keep everything organized.
|
|
16
|
+
|
|
17
|
+
## 1. Observe
|
|
18
|
+
|
|
19
|
+
Assess what needs processing:
|
|
20
|
+
|
|
21
|
+
1. Check for unprocessed synced files (mail and calendar data):
|
|
22
|
+
|
|
23
|
+
python3 scripts/state.py check
|
|
24
|
+
|
|
25
|
+
(Run from the extract-entities skill directory:
|
|
26
|
+
`.claude/skills/extract-entities/`)
|
|
27
|
+
|
|
28
|
+
2. Count existing knowledge graph entities:
|
|
29
|
+
|
|
30
|
+
ls knowledge/People/ knowledge/Organizations/ knowledge/Projects/
|
|
31
|
+
knowledge/Topics/ 2>/dev/null | wc -l
|
|
32
|
+
|
|
33
|
+
Write your digest to `~/.cache/fit/basecamp/state/librarian_digest.md`:
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
# Knowledge Digest — {YYYY-MM-DD HH:MM}
|
|
37
|
+
|
|
38
|
+
## Pending Processing
|
|
39
|
+
- {count} unprocessed synced files
|
|
40
|
+
|
|
41
|
+
## Knowledge Graph
|
|
42
|
+
- {count} People / {count} Organizations / {count} Projects / {count} Topics
|
|
43
|
+
|
|
44
|
+
## Summary
|
|
45
|
+
{unprocessed} files to process, graph has {total} entities
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## 2. Act
|
|
49
|
+
|
|
50
|
+
Choose the most valuable action:
|
|
51
|
+
|
|
52
|
+
1. **Entity extraction** — if unprocessed synced files exist, use the
|
|
53
|
+
extract-entities skill (process up to 10 files)
|
|
54
|
+
2. **Nothing** — if the graph is current
|
|
55
|
+
|
|
56
|
+
After acting, output exactly:
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
Decision: {what you observed and why you chose this action}
|
|
60
|
+
Action: {what you did, e.g. "extract-entities on 7 files"}
|
|
61
|
+
```
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: postman
|
|
3
|
+
description: >
|
|
4
|
+
The user's email gatekeeper. Syncs mail, triages new messages, drafts replies,
|
|
5
|
+
and tracks threads awaiting response. Woken on a schedule by the Basecamp
|
|
6
|
+
scheduler.
|
|
7
|
+
model: sonnet
|
|
8
|
+
permissionMode: bypassPermissions
|
|
9
|
+
skills:
|
|
10
|
+
- sync-apple-mail
|
|
11
|
+
- draft-emails
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
You are the postman — the user's email gatekeeper. Each time you are woken by
|
|
15
|
+
the scheduler, you sync mail, triage what's new, and take the most valuable
|
|
16
|
+
action.
|
|
17
|
+
|
|
18
|
+
## 1. Sync
|
|
19
|
+
|
|
20
|
+
Check `~/.cache/fit/basecamp/state/apple_mail_last_sync`. If mail was synced
|
|
21
|
+
less than 3 minutes ago, skip to step 2.
|
|
22
|
+
|
|
23
|
+
Otherwise, run the sync-apple-mail skill to pull in new email threads.
|
|
24
|
+
|
|
25
|
+
## 2. Triage
|
|
26
|
+
|
|
27
|
+
Scan email threads in `~/.cache/fit/basecamp/apple_mail/`. Compare against
|
|
28
|
+
`drafts/drafted` and `drafts/ignored` to identify unprocessed threads.
|
|
29
|
+
|
|
30
|
+
For each unprocessed thread, classify:
|
|
31
|
+
|
|
32
|
+
- **Urgent** — deadline mentioned, time-sensitive request, escalation, VIP
|
|
33
|
+
sender (someone with a note in `knowledge/People/` who the user interacts with
|
|
34
|
+
frequently)
|
|
35
|
+
- **Needs reply** — question asked, action requested, follow-up needed
|
|
36
|
+
- **FYI** — informational, no action needed
|
|
37
|
+
- **Ignore** — newsletter, marketing, automated notification
|
|
38
|
+
|
|
39
|
+
Also scan `drafts/drafted` for emails the user sent more than 3 days ago where
|
|
40
|
+
no reply has appeared in the thread — these are **awaiting response**.
|
|
41
|
+
|
|
42
|
+
Write triage results to `~/.cache/fit/basecamp/state/postman_triage.md`:
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
# Inbox Triage — {YYYY-MM-DD HH:MM}
|
|
46
|
+
|
|
47
|
+
## Urgent
|
|
48
|
+
- **{subject}** from {sender} — {reason}
|
|
49
|
+
|
|
50
|
+
## Needs Reply
|
|
51
|
+
- **{subject}** from {sender} — {what's needed}
|
|
52
|
+
|
|
53
|
+
## Awaiting Response
|
|
54
|
+
- **{subject}** to {recipient} — sent {N} days ago
|
|
55
|
+
|
|
56
|
+
## Summary
|
|
57
|
+
{total} unread, {urgent} urgent, {reply} need reply, {awaiting} awaiting response
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## 3. Act
|
|
61
|
+
|
|
62
|
+
Choose the single most valuable action:
|
|
63
|
+
|
|
64
|
+
1. **Draft replies** — if there are urgent or actionable emails without drafts,
|
|
65
|
+
use the draft-emails skill for the highest-priority thread
|
|
66
|
+
2. **Nothing** — if no emails need attention, report "all current"
|
|
67
|
+
|
|
68
|
+
After acting, output exactly:
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
Decision: {what you observed and why you chose this action}
|
|
72
|
+
Action: {what you did, e.g. "draft-emails for thread 123"}
|
|
73
|
+
```
|
|
@@ -1,10 +1,47 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/claude-code-settings.json",
|
|
3
3
|
"permissions": {
|
|
4
|
+
"defaultMode": "acceptEdits",
|
|
4
5
|
"allow": [
|
|
6
|
+
"Bash(python3 *)",
|
|
7
|
+
"Bash(sqlite3 *)",
|
|
8
|
+
"Bash(bash scripts/*)",
|
|
9
|
+
"Bash(sh scripts/*)",
|
|
10
|
+
"Bash(node *)",
|
|
11
|
+
"Bash(npm install *)",
|
|
12
|
+
"Bash(npx *)",
|
|
13
|
+
"Bash(rg *)",
|
|
14
|
+
"Bash(find *)",
|
|
15
|
+
"Bash(cat *)",
|
|
16
|
+
"Bash(head *)",
|
|
17
|
+
"Bash(tail *)",
|
|
18
|
+
"Bash(ls *)",
|
|
19
|
+
"Bash(ls)",
|
|
20
|
+
"Bash(grep *)",
|
|
21
|
+
"Bash(echo *)",
|
|
22
|
+
"Bash(date *)",
|
|
23
|
+
"Bash(mkdir *)",
|
|
24
|
+
"Bash(mv *)",
|
|
25
|
+
"Bash(cp *)",
|
|
26
|
+
"Bash(touch *)",
|
|
27
|
+
"Bash(sort *)",
|
|
28
|
+
"Bash(wc *)",
|
|
29
|
+
"Bash(cut *)",
|
|
30
|
+
"Bash(tr *)",
|
|
31
|
+
"Bash(uniq *)",
|
|
32
|
+
"Bash(awk *)",
|
|
33
|
+
"Bash(sed *)",
|
|
34
|
+
"Bash(basename *)",
|
|
35
|
+
"Bash(dirname *)",
|
|
36
|
+
"Bash(realpath *)",
|
|
37
|
+
"Bash(pwd)",
|
|
38
|
+
"Bash(which *)",
|
|
39
|
+
"Bash(textutil *)",
|
|
40
|
+
"Bash(pdftotext *)",
|
|
5
41
|
"Read(~/Library/Mail/**)",
|
|
6
42
|
"Read(~/Library/Group Containers/group.com.apple.calendar/**)",
|
|
7
43
|
"Read(~/Library/Calendars/**)",
|
|
44
|
+
"Read(~/Library/Application Support/hyprnote/**)",
|
|
8
45
|
"Read(~/Desktop/**)",
|
|
9
46
|
"Read(~/Documents/**)",
|
|
10
47
|
"Read(~/Downloads/**)",
|
|
@@ -15,6 +52,17 @@
|
|
|
15
52
|
"Edit(~/.cache/fit/basecamp/**)"
|
|
16
53
|
],
|
|
17
54
|
"deny": [
|
|
55
|
+
"Bash(curl *)",
|
|
56
|
+
"Bash(wget *)",
|
|
57
|
+
"Bash(open *)",
|
|
58
|
+
"Bash(osascript *)",
|
|
59
|
+
"Bash(sudo *)",
|
|
60
|
+
"Bash(rm -rf *)",
|
|
61
|
+
"Bash(chmod *)",
|
|
62
|
+
"Bash(chown *)",
|
|
63
|
+
"Bash(killall *)",
|
|
64
|
+
"Bash(launchctl *)",
|
|
65
|
+
"Bash(brew *)",
|
|
18
66
|
"Edit(~/Library/**)",
|
|
19
67
|
"Read(~/Pictures/**)",
|
|
20
68
|
"Read(~/Music/**)",
|
|
@@ -31,6 +79,7 @@
|
|
|
31
79
|
"~/Library/Mail",
|
|
32
80
|
"~/Library/Group Containers/group.com.apple.calendar",
|
|
33
81
|
"~/Library/Calendars",
|
|
82
|
+
"~/Library/Application Support/hyprnote",
|
|
34
83
|
"~/Desktop",
|
|
35
84
|
"~/Documents",
|
|
36
85
|
"~/Downloads",
|
|
@@ -16,13 +16,15 @@ Run when the user asks to draft, reply to, or respond to an email.
|
|
|
16
16
|
## Prerequisites
|
|
17
17
|
|
|
18
18
|
- Knowledge base populated (from `extract-entities` skill)
|
|
19
|
-
- Synced email data in `~/.cache/fit/basecamp/apple_mail/`
|
|
19
|
+
- Synced email data in `~/.cache/fit/basecamp/apple_mail/` or
|
|
20
|
+
`~/.cache/fit/basecamp/gmail/`
|
|
20
21
|
|
|
21
22
|
## Inputs
|
|
22
23
|
|
|
23
24
|
- `knowledge/People/*.md` — person context
|
|
24
25
|
- `knowledge/Organizations/*.md` — organization context
|
|
25
|
-
- `~/.cache/fit/basecamp/apple_mail/*.md`
|
|
26
|
+
- `~/.cache/fit/basecamp/apple_mail/*.md` or `~/.cache/fit/basecamp/gmail/*.md`
|
|
27
|
+
— email threads
|
|
26
28
|
- `~/.cache/fit/basecamp/apple_calendar/*.json` — calendar events (for
|
|
27
29
|
scheduling)
|
|
28
30
|
- `drafts/last_processed` — timestamp of last processing run
|
|
@@ -116,7 +118,7 @@ cat "knowledge/Organizations/Company Name.md"
|
|
|
116
118
|
**Calendar (for scheduling emails):**
|
|
117
119
|
|
|
118
120
|
```bash
|
|
119
|
-
ls ~/.cache/fit/basecamp/apple_calendar/ 2>/dev/null
|
|
121
|
+
ls ~/.cache/fit/basecamp/apple_calendar/ ~/.cache/fit/basecamp/google_calendar/ 2>/dev/null
|
|
120
122
|
cat "$HOME/.cache/fit/basecamp/apple_calendar/event123.json"
|
|
121
123
|
```
|
|
122
124
|
|
|
@@ -184,6 +186,33 @@ date -u '+%Y-%m-%dT%H:%M:%SZ' > drafts/last_processed
|
|
|
184
186
|
- {id}: {subject} — {reason}
|
|
185
187
|
```
|
|
186
188
|
|
|
189
|
+
## Recruitment & Staffing Emails
|
|
190
|
+
|
|
191
|
+
**CRITICAL: Candidates must NEVER be copied on internal emails about them.**
|
|
192
|
+
|
|
193
|
+
When an email involves recruitment, staffing, or hiring:
|
|
194
|
+
|
|
195
|
+
1. **Identify the candidate** — Determine who the candidate is from the email
|
|
196
|
+
thread and knowledge base (`knowledge/Candidates/`, `knowledge/People/`)
|
|
197
|
+
2. **Strip the candidate from recipients** — The draft must ONLY be addressed to
|
|
198
|
+
internal stakeholders (hiring managers, recruiters, interview panel, etc.).
|
|
199
|
+
The candidate’s email address must NOT appear in To, CC, or BCC
|
|
200
|
+
3. **Only recruiters email candidates directly** — If the email is a direct
|
|
201
|
+
reply TO a candidate (e.g., scheduling an interview, extending an offer),
|
|
202
|
+
flag it clearly so only the recruiter sends it. Add a note:
|
|
203
|
+
`⚠️ RECRUITER ONLY — This email goes directly to the candidate.`
|
|
204
|
+
|
|
205
|
+
**Examples of internal recruitment emails (candidate must NOT be copied):**
|
|
206
|
+
|
|
207
|
+
- Interview feedback or debrief
|
|
208
|
+
- Candidate evaluation or comparison
|
|
209
|
+
- Hiring decision discussions
|
|
210
|
+
- Compensation/offer discussions
|
|
211
|
+
- Reference check follow-ups between colleagues
|
|
212
|
+
|
|
213
|
+
**When in doubt:** If an email thread mentions a candidate by name and involves
|
|
214
|
+
multiple internal recipients, treat it as internal and exclude the candidate.
|
|
215
|
+
|
|
187
216
|
## Constraints
|
|
188
217
|
|
|
189
218
|
- Never actually send emails — only create drafts
|
|
@@ -3,14 +3,15 @@
|
|
|
3
3
|
#
|
|
4
4
|
# Usage: bash scripts/scan-emails.sh
|
|
5
5
|
#
|
|
6
|
-
# Checks ~/.cache/fit/basecamp/apple_mail/ for email files
|
|
7
|
-
#
|
|
6
|
+
# Checks ~/.cache/fit/basecamp/apple_mail/ for email files not yet
|
|
7
|
+
# listed in drafts/drafted or drafts/ignored.
|
|
8
8
|
# Outputs tab-separated: email_id<TAB>subject
|
|
9
9
|
|
|
10
10
|
set -euo pipefail
|
|
11
11
|
|
|
12
12
|
MAIL_DIRS=(
|
|
13
13
|
"$HOME/.cache/fit/basecamp/apple_mail"
|
|
14
|
+
"$HOME/.cache/fit/basecamp/gmail"
|
|
14
15
|
)
|
|
15
16
|
|
|
16
17
|
for dir in "${MAIL_DIRS[@]}"; do
|
|
@@ -264,7 +264,6 @@ person?"** test:
|
|
|
264
264
|
- Transactional service providers (bank employees, support reps)
|
|
265
265
|
- One-time administrative contacts
|
|
266
266
|
- Large group meeting attendees you didn't interact with
|
|
267
|
-
- Internal colleagues (@user.domain)
|
|
268
267
|
- Assistants handling only logistics
|
|
269
268
|
|
|
270
269
|
For people who don't get their own note, add to the Organization note's
|
|
@@ -10,6 +10,7 @@ Templates for creating new knowledge base notes.
|
|
|
10
10
|
## Info
|
|
11
11
|
**Role:** {role or inferred role with qualifier}
|
|
12
12
|
**Organization:** [[Organizations/{organization}]]
|
|
13
|
+
**Reports to:** [[People/{{Person}}]]
|
|
13
14
|
**Email:** {email}
|
|
14
15
|
**Aliases:** {comma-separated variants}
|
|
15
16
|
**First met:** {YYYY-MM-DD}
|