coppermind-cmo 0.3.2__tar.gz → 0.3.4__tar.gz
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.
- {coppermind_cmo-0.3.2/src/coppermind_cmo.egg-info → coppermind_cmo-0.3.4}/PKG-INFO +1 -1
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/pyproject.toml +2 -2
- coppermind_cmo-0.3.4/src/coppermind_cmo/commands/cmo-actions.md +39 -0
- coppermind_cmo-0.3.4/src/coppermind_cmo/commands/cmo-batch.md +44 -0
- coppermind_cmo-0.3.4/src/coppermind_cmo/commands/cmo-connect.md +43 -0
- coppermind_cmo-0.3.4/src/coppermind_cmo/commands/cmo-followup.md +25 -0
- coppermind_cmo-0.3.4/src/coppermind_cmo/commands/cmo-handoff.md +57 -0
- coppermind_cmo-0.3.4/src/coppermind_cmo/commands/cmo-help.md +53 -0
- coppermind_cmo-0.3.4/src/coppermind_cmo/commands/cmo-morning.md +38 -0
- coppermind_cmo-0.3.4/src/coppermind_cmo/commands/cmo-review.md +60 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo/server.py +35 -1
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo/tools/minds.py +13 -2
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4/src/coppermind_cmo.egg-info}/PKG-INFO +1 -1
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo.egg-info/SOURCES.txt +8 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/LICENSE +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/README.md +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/setup.cfg +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo/__init__.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo/__main__.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo/active_client.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo/background.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo/config.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo/db.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo/embedding_client.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo/embedding_server.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo/errors.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo/ingest.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo/ingest_folder.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo/llm_client.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo/log.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo/skills/cmo-onboard-client.md +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo/statusline.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo/statusline.sh +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo/supabase-ca.pem +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo/tips.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo/tools/__init__.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo/tools/brand.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo/tools/intelligence.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo/tools/memories.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo/utils.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo/watch.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo.egg-info/dependency_links.txt +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo.egg-info/entry_points.txt +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo.egg-info/requires.txt +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo.egg-info/top_level.txt +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/tests/test_active_client.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/tests/test_api_contracts.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/tests/test_background_ingestion.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/tests/test_brand.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/tests/test_config.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/tests/test_customer_isolation.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/tests/test_db.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/tests/test_embedding_client.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/tests/test_embedding_server.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/tests/test_errors.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/tests/test_ingest.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/tests/test_ingest_folder.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/tests/test_integration.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/tests/test_integration_flows.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/tests/test_integration_smoke.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/tests/test_intelligence.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/tests/test_llm_client.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/tests/test_log.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/tests/test_memories.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/tests/test_minds.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/tests/test_performance.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/tests/test_pid_management.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/tests/test_raw_documents.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/tests/test_reconsolidation.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/tests/test_schema.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/tests/test_server.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/tests/test_session_tracking.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/tests/test_tips.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/tests/test_upgrade_resilience.py +0 -0
- {coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/tests/test_watch.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: coppermind-cmo
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.4
|
|
4
4
|
Summary: AI-powered memory for fractional CMOs — never forget a client detail, never leak data between clients
|
|
5
5
|
Author-email: Ben Finklea <ben@volacci.com>
|
|
6
6
|
License-Expression: LicenseRef-Proprietary
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "coppermind-cmo"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.4"
|
|
8
8
|
description = "AI-powered memory for fractional CMOs — never forget a client detail, never leak data between clients"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "LicenseRef-Proprietary"
|
|
@@ -71,4 +71,4 @@ exclude_lines = [
|
|
|
71
71
|
where = ["src"]
|
|
72
72
|
|
|
73
73
|
[tool.setuptools.package-data]
|
|
74
|
-
coppermind_cmo = ["supabase-ca.pem", "skills/*.md", "statusline.sh"]
|
|
74
|
+
coppermind_cmo = ["supabase-ca.pem", "skills/*.md", "statusline.sh", "commands/*.md"]
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# /cmo-actions — Cross-Client Action Items
|
|
2
|
+
|
|
3
|
+
Show overdue and open action items across all clients.
|
|
4
|
+
|
|
5
|
+
## Steps
|
|
6
|
+
|
|
7
|
+
1. Call `list_minds` to get all client minds.
|
|
8
|
+
2. For each client, switch and search for commitment-type memories.
|
|
9
|
+
3. Build a unified action item view grouped by urgency:
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
ACTION ITEMS — All Clients
|
|
13
|
+
|
|
14
|
+
OVERDUE
|
|
15
|
+
- [Acme] Send revised media plan to Sarah — due 3/8 (7 days overdue)
|
|
16
|
+
- [5 Star] Follow up with Stephanie on LSA lead marking — due 3/11 (4 days overdue)
|
|
17
|
+
|
|
18
|
+
DUE THIS WEEK
|
|
19
|
+
- [Acme] Approve Q3 creative concepts — due 3/18
|
|
20
|
+
- [XSCAPE] Verify satellite office signage — no date, committed 3/11
|
|
21
|
+
|
|
22
|
+
OPEN (no due date)
|
|
23
|
+
- [5 Star] Evaluate RP1 as Lead Truffle replacement
|
|
24
|
+
- [5 Star] Help with van wrap design
|
|
25
|
+
- [XSCAPE] Review direct mail demographics with Josh before printing
|
|
26
|
+
- [Bluebell] Finalize Q2 content calendar
|
|
27
|
+
|
|
28
|
+
TOTAL: 8 open items across 3 clients
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
4. Ask: "Want me to focus on any of these?"
|
|
32
|
+
|
|
33
|
+
## Rules
|
|
34
|
+
- Process all clients in parallel.
|
|
35
|
+
- Sort overdue items by how late they are (most overdue first).
|
|
36
|
+
- Only include commitments that haven't been resolved by a later memory.
|
|
37
|
+
- If a commitment was clearly completed based on subsequent memories, skip it.
|
|
38
|
+
- Keep descriptions to one line each.
|
|
39
|
+
- Show the client name in brackets on every line — this is a cross-client view.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# /cmo-batch — Batch Content Creation
|
|
2
|
+
|
|
3
|
+
Write content for multiple clients in one session.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
User says something like:
|
|
8
|
+
- "Write this week's social posts for all my clients"
|
|
9
|
+
- "Draft newsletters for Acme and 5 Star"
|
|
10
|
+
- "Write a blog post for each client about spring topics"
|
|
11
|
+
|
|
12
|
+
## Steps
|
|
13
|
+
|
|
14
|
+
1. Parse which clients and what content type.
|
|
15
|
+
- If "all clients": use `list_minds` to get the full list.
|
|
16
|
+
- If specific clients named: use those.
|
|
17
|
+
2. For each client:
|
|
18
|
+
a. Switch to the client
|
|
19
|
+
b. Pull brand voice, content themes, and recent memories
|
|
20
|
+
c. Write the requested content using the client's voice and themes
|
|
21
|
+
d. Label it clearly with the client name
|
|
22
|
+
3. Present all content together with clear separators:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
---
|
|
26
|
+
ACME CORP — Social Post (Instagram)
|
|
27
|
+
[content in Acme's brand voice]
|
|
28
|
+
---
|
|
29
|
+
5 STAR CHARLESTON — Social Post (Instagram)
|
|
30
|
+
[content in 5 Star's brand voice]
|
|
31
|
+
---
|
|
32
|
+
XSCAPE — Social Post (Instagram)
|
|
33
|
+
[content in XSCAPE's brand voice]
|
|
34
|
+
---
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
4. Ask: "Want me to adjust any of these, or copy them all to clipboard?"
|
|
38
|
+
|
|
39
|
+
## Rules
|
|
40
|
+
- Each piece of content MUST use that client's brand voice. This is the whole point — don't use a generic voice.
|
|
41
|
+
- Reference recent events/memories when relevant ("Just launched our rebrand!" for XSCAPE, "Spring tune-up season is here" for 5 Star).
|
|
42
|
+
- Match the content type to the platform (short for social, longer for blogs, professional for newsletters).
|
|
43
|
+
- If a client has no brand voice set, mention it: "[Client] doesn't have brand voice configured yet. Want me to set it up?"
|
|
44
|
+
- Don't show the switch_client responses. Just present the final content.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# /cmo-connect — Pull Data from Any MCP
|
|
2
|
+
|
|
3
|
+
Bridge data from any connected MCP into Coppermind. Claude acts as the extractor — fetches data, breaks it into memories, and stores them with the right types.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
- `/cmo-connect pull my last 3 Granola meetings into the right client minds`
|
|
8
|
+
- `/cmo-connect search Gmail for emails from sarah@acme.com about the rebrand`
|
|
9
|
+
- `/cmo-connect pull recent Slack messages from #acme-marketing`
|
|
10
|
+
|
|
11
|
+
## Steps
|
|
12
|
+
|
|
13
|
+
1. Parse what the user wants: which data source, what data, which client(s).
|
|
14
|
+
2. Check if the required MCP is connected (look for its tools in available tools).
|
|
15
|
+
- **If not connected:** Tell them exactly how to add it. Example: "Granola isn't connected. Run `claude mcp add granola -- uvx granola-mcp-server` and restart."
|
|
16
|
+
- **If connected:** Proceed.
|
|
17
|
+
3. Fetch the data using the source MCP's tools.
|
|
18
|
+
4. For each item (meeting, email, message):
|
|
19
|
+
a. Determine which client mind it belongs to (match by participant names, company names, or ask the user).
|
|
20
|
+
b. Switch to that client mind.
|
|
21
|
+
c. Extract and store memories using the same rules as transcript ingestion:
|
|
22
|
+
- Stakeholder profiles, decisions, commitments, key facts
|
|
23
|
+
- Tag with the source date and source type
|
|
24
|
+
d. Report progress every 10 memories.
|
|
25
|
+
5. Summarize: "Pulled [N] items from [source]. Stored [M] memories across [K] clients."
|
|
26
|
+
|
|
27
|
+
## Known MCP Setups
|
|
28
|
+
|
|
29
|
+
- **Granola:** `claude mcp add granola -- uvx granola-mcp-server` (no API key, reads local cache)
|
|
30
|
+
- **Slack:** Check for `slack_read_channel`, `slack_search_public` tools
|
|
31
|
+
- **Gmail:** Check for `gmail_search_messages`, `gmail_read_message` tools
|
|
32
|
+
- **Google Calendar:** Check for `gcal_list_events` tools
|
|
33
|
+
|
|
34
|
+
## Rate Limits
|
|
35
|
+
- Maximum 50 memories per invocation
|
|
36
|
+
- Maximum 20 source items per fetch (emails, meetings, messages)
|
|
37
|
+
- If the source has more, store the 50 most recent/important first and tell the user: "There's more — want me to continue?"
|
|
38
|
+
|
|
39
|
+
## Rules
|
|
40
|
+
- Always confirm which client mind to store into before storing. If ambiguous, ask.
|
|
41
|
+
- Don't store duplicate content — check if a similar memory already exists before storing.
|
|
42
|
+
- Meeting transcripts from Granola should be processed the same way as pasted transcripts (full extraction, not just a raw dump).
|
|
43
|
+
- Report what was stored at the end, not during. Keep the output clean.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# /cmo-followup — Post-Meeting Follow-Up Email
|
|
2
|
+
|
|
3
|
+
Draft a follow-up email after a client meeting.
|
|
4
|
+
|
|
5
|
+
## Steps
|
|
6
|
+
|
|
7
|
+
1. Confirm the active client. If none, ask which client the meeting was with.
|
|
8
|
+
2. Pull the most recent memories (last 24 hours) and the last meeting brief if saved.
|
|
9
|
+
3. Check if a CMO voice profile exists (search for an internal mind called "CMO Profile" or check for a `cmo_voice` memory). If found, use it for tone and style. If not, use a neutral professional tone — warm, concise, and direct.
|
|
10
|
+
4. Do NOT use the client's brand voice for emails. Brand voice is how the client talks to their customers. This email is from the CMO to the client.
|
|
11
|
+
5. Draft a follow-up email that includes:
|
|
12
|
+
- Brief thank-you / recap of what was discussed
|
|
13
|
+
- Key decisions made (bulleted)
|
|
14
|
+
- Action items with owners and deadlines (bulleted)
|
|
15
|
+
- Next steps or next meeting date if known
|
|
16
|
+
6. Match formality to the relationship — use stakeholder profile to gauge. If the stakeholder profile says "direct communicator" or the transcript shows casual language, be casual. Otherwise default to professional.
|
|
17
|
+
7. Present the draft and ask: "Want me to adjust anything, or copy this to your clipboard?"
|
|
18
|
+
|
|
19
|
+
## Rules
|
|
20
|
+
- Keep it short — 3-4 paragraphs max. CMOs send dozens of these.
|
|
21
|
+
- Never include internal notes or agency-specific details. This goes TO the client.
|
|
22
|
+
- Action items should clearly state who owns each one (including items the CMO owns).
|
|
23
|
+
- If the user just pasted a transcript, extract from that. Don't make them re-explain.
|
|
24
|
+
- Offer to copy to clipboard when done.
|
|
25
|
+
- If this is the first follow-up email and no CMO voice exists, mention it once: "Tip: paste 2-3 emails you've sent to clients and I'll learn your writing style for future emails."
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# /cmo-handoff — Client Handoff Document
|
|
2
|
+
|
|
3
|
+
Generate a comprehensive handoff document for a client engagement. This is the "deliverable mind" — when the engagement ends, the client gets this.
|
|
4
|
+
|
|
5
|
+
## Steps
|
|
6
|
+
|
|
7
|
+
1. Confirm the active client. If argument provided, switch to that client.
|
|
8
|
+
2. Gather everything:
|
|
9
|
+
- `get_brand_voice` — full brand DNA
|
|
10
|
+
- `search_memory` — broad search for decisions, commitments, stakeholders, facts, campaign outcomes
|
|
11
|
+
- `get_campaign_history` — all campaign results
|
|
12
|
+
- `get_last_brief` — most recent meeting brief
|
|
13
|
+
- Company info from the mind's configuration
|
|
14
|
+
3. Generate a structured handoff document:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
CLIENT HANDOFF: [Client Name]
|
|
18
|
+
Prepared by: [CMO name] | Date: [today]
|
|
19
|
+
Engagement period: [first memory date] — [today]
|
|
20
|
+
|
|
21
|
+
COMPANY OVERVIEW
|
|
22
|
+
[From company_info: industry, location, services, key details]
|
|
23
|
+
|
|
24
|
+
BRAND DNA
|
|
25
|
+
Voice & Tone: [summary]
|
|
26
|
+
Positioning: [tagline, positioning statement]
|
|
27
|
+
Key Differentiators: [bulleted]
|
|
28
|
+
Target Audience: [description]
|
|
29
|
+
Content Themes: [bulleted]
|
|
30
|
+
|
|
31
|
+
KEY STAKEHOLDERS
|
|
32
|
+
[Name, title, role, communication style — for each]
|
|
33
|
+
|
|
34
|
+
DECISION LOG
|
|
35
|
+
[Chronological list of major decisions with dates and rationale]
|
|
36
|
+
|
|
37
|
+
ACTIVE COMMITMENTS
|
|
38
|
+
[Open action items with owners]
|
|
39
|
+
|
|
40
|
+
CAMPAIGN HISTORY & RESULTS
|
|
41
|
+
[Campaign summaries with outcomes]
|
|
42
|
+
|
|
43
|
+
STRATEGIC CONTEXT
|
|
44
|
+
[Key concerns, priorities, and unresolved questions]
|
|
45
|
+
|
|
46
|
+
RECOMMENDATIONS FOR NEXT CMO
|
|
47
|
+
[Based on patterns in the data — what to focus on, what to avoid, relationship dynamics]
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
4. Ask: "Want me to copy this to clipboard, or save it as a file?"
|
|
51
|
+
|
|
52
|
+
## Rules
|
|
53
|
+
- This is the crown jewel feature. Make it comprehensive and polished.
|
|
54
|
+
- Write the "Recommendations" section as genuine strategic advice, not just a data dump.
|
|
55
|
+
- Include dates on everything — decisions, campaigns, stakeholder additions.
|
|
56
|
+
- The document should be useful to someone who has NEVER met this client.
|
|
57
|
+
- Use the brand voice description but write the document in a professional, neutral tone — it's a handoff, not marketing copy.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# /cmo-help — Coppermind Help
|
|
2
|
+
|
|
3
|
+
Provide help, troubleshooting, and how-to guidance for Coppermind CMO.
|
|
4
|
+
|
|
5
|
+
## Steps
|
|
6
|
+
|
|
7
|
+
1. Read `docs/product-knowledge.md` for the full knowledge base.
|
|
8
|
+
2. Read `docs/QUICKSTART.md` if the user needs setup help.
|
|
9
|
+
3. Answer the user's question conversationally from those sources.
|
|
10
|
+
|
|
11
|
+
## If no specific question
|
|
12
|
+
|
|
13
|
+
Show this quick reference:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
COPPERMIND CMO — Quick Reference
|
|
17
|
+
|
|
18
|
+
GETTING STARTED
|
|
19
|
+
"Set up [client name]" Create a new client
|
|
20
|
+
"Switch to [client]" Change active client
|
|
21
|
+
"List my clients" Show all client minds
|
|
22
|
+
|
|
23
|
+
MEETINGS
|
|
24
|
+
"Prep my meeting with [client]" Build a meeting brief
|
|
25
|
+
"Save the brief" Persist for later retrieval
|
|
26
|
+
"Show my last brief" Pull up saved brief
|
|
27
|
+
|
|
28
|
+
MEMORY
|
|
29
|
+
"Remember: [anything]" Store a structured memory
|
|
30
|
+
"Quick note: [anything]" Fast capture, no classification
|
|
31
|
+
"What did we decide about X?" Search decisions
|
|
32
|
+
"Who is [person]?" Search stakeholders
|
|
33
|
+
|
|
34
|
+
CONTENT
|
|
35
|
+
"Write a blog post for [client]" Uses client's brand voice
|
|
36
|
+
"Draft a social post about X" On-brand content
|
|
37
|
+
"Write a follow-up email" Post-meeting email draft
|
|
38
|
+
|
|
39
|
+
POWER FEATURES
|
|
40
|
+
/cmo-morning Daily briefing across all clients
|
|
41
|
+
/cmo-followup Draft post-meeting follow-up email
|
|
42
|
+
/cmo-handoff Generate client handoff document
|
|
43
|
+
/cmo-actions Overdue items across all clients
|
|
44
|
+
/cmo-batch Write content for multiple clients
|
|
45
|
+
/cmo-review Quarterly review for a client
|
|
46
|
+
/cmo-connect Pull data from Granola/Gmail/Slack
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Rules
|
|
50
|
+
- Always check the knowledge base and quickstart before saying "I don't know."
|
|
51
|
+
- For setup issues, walk them through step by step — don't just link to the doc.
|
|
52
|
+
- Only suggest emailing coppermind@volacci.com for issues you genuinely cannot resolve.
|
|
53
|
+
- Keep answers short and actionable. CMOs don't want tutorials.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# /cmo-morning — Daily Briefing
|
|
2
|
+
|
|
3
|
+
Build a morning briefing across all clients.
|
|
4
|
+
|
|
5
|
+
## Steps
|
|
6
|
+
|
|
7
|
+
1. Call `list_minds` to get all client minds.
|
|
8
|
+
2. For each client with memories, switch to it and gather:
|
|
9
|
+
- Open commitments (action items not marked complete)
|
|
10
|
+
- Any memories from the last 48 hours
|
|
11
|
+
- Current sprint status and what's due (if sprint plan exists)
|
|
12
|
+
3. If Google Calendar MCP is connected, check today's meetings and match attendees to client minds.
|
|
13
|
+
4. Present a unified briefing:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
GOOD MORNING — [Date]
|
|
17
|
+
|
|
18
|
+
TODAY'S MEETINGS
|
|
19
|
+
- 10:00 Acme Corp (Sarah Chen) — prep available, say "prep my meeting with Acme"
|
|
20
|
+
- 2:30 5 Star Charleston (Stephen Graham) — no recent notes, consider catching up
|
|
21
|
+
|
|
22
|
+
NEEDS ATTENTION
|
|
23
|
+
- [Acme] 2 action items overdue from Sprint 3
|
|
24
|
+
- [Bluebell] No interaction in 18 days — consider a check-in
|
|
25
|
+
- [5 Star] Stephen waiting on van wrap designs (committed 3/10)
|
|
26
|
+
|
|
27
|
+
THIS WEEK'S SPRINT DELIVERABLES
|
|
28
|
+
- [Acme] Publish 4 SEO pages, launch outbound calling
|
|
29
|
+
- [5 Star] Finalize hiring reqs, evaluate RP1 platform
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
5. End with: "Want me to prep any of these meetings?"
|
|
33
|
+
|
|
34
|
+
## Rules
|
|
35
|
+
- Process clients in parallel if possible.
|
|
36
|
+
- Only show clients that have something to report — skip clients with no open items and no recent activity.
|
|
37
|
+
- Keep it scannable. No paragraphs. Bullets and short lines only.
|
|
38
|
+
- Don't show the raw switch_client responses. Just present the final briefing.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# /cmo-review — Quarterly Review
|
|
2
|
+
|
|
3
|
+
Generate a quarterly review for a client.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
- `/cmo-review` — reviews current quarter for active client
|
|
8
|
+
- `/cmo-review Q4 2025` — reviews a specific quarter
|
|
9
|
+
- "How did Q1 go for Acme?" — triggers naturally
|
|
10
|
+
|
|
11
|
+
## Steps
|
|
12
|
+
|
|
13
|
+
1. Confirm the active client and quarter. Default to current quarter from cadence.
|
|
14
|
+
2. Gather all memories from that quarter:
|
|
15
|
+
- Decisions made (with dates)
|
|
16
|
+
- Commitments — which were completed, which are still open
|
|
17
|
+
- Campaign outcomes and metrics
|
|
18
|
+
- Key facts and status changes
|
|
19
|
+
- Stakeholder changes (new hires, departures, role changes)
|
|
20
|
+
3. If a sprint plan exists for that quarter, pull completion rates per initiative.
|
|
21
|
+
4. Generate the review:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
QUARTERLY REVIEW: [Client Name] — [Quarter Year]
|
|
25
|
+
|
|
26
|
+
SUMMARY
|
|
27
|
+
[2-3 sentence executive summary of the quarter]
|
|
28
|
+
|
|
29
|
+
WINS
|
|
30
|
+
- [Completed initiatives, successful campaigns, goals met]
|
|
31
|
+
|
|
32
|
+
DECISIONS MADE
|
|
33
|
+
- [Date] [Decision and rationale]
|
|
34
|
+
- [Date] [Decision and rationale]
|
|
35
|
+
|
|
36
|
+
CAMPAIGNS & RESULTS
|
|
37
|
+
- [Campaign name]: [outcome, metrics if available]
|
|
38
|
+
|
|
39
|
+
OPEN ITEMS CARRIED FORWARD
|
|
40
|
+
- [Items not completed this quarter that carry into next]
|
|
41
|
+
|
|
42
|
+
SPRINT PLAN SCORECARD (if applicable)
|
|
43
|
+
- Initiative 1: 5/6 sprints complete ████████░░ 83%
|
|
44
|
+
- Initiative 2: 3/6 sprints complete █████░░░░░ 50%
|
|
45
|
+
- Initiative 3: CUT in Sprint 4
|
|
46
|
+
|
|
47
|
+
TEAM CHANGES
|
|
48
|
+
- [New hires, departures, role changes during the quarter]
|
|
49
|
+
|
|
50
|
+
LOOKING AHEAD
|
|
51
|
+
[Recommendations for next quarter based on what happened this quarter]
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
5. Ask: "Want me to copy this, or use it as input for next quarter's planning?"
|
|
55
|
+
|
|
56
|
+
## Rules
|
|
57
|
+
- Be honest. If results were poor, say so constructively. CMOs need accurate assessments, not cheerleading.
|
|
58
|
+
- Include specific dates and numbers wherever available.
|
|
59
|
+
- The "Looking Ahead" section should be genuine strategic recommendations, not generic advice.
|
|
60
|
+
- If there's not enough data for a full review, say so: "I only have [N] memories from Q4. The review will be thin — want to feed me more context first?"
|
|
@@ -330,8 +330,9 @@ def _startup_checks():
|
|
|
330
330
|
# Install statusline script if it doesn't exist
|
|
331
331
|
_install_statusline()
|
|
332
332
|
|
|
333
|
-
# Install bundled skills
|
|
333
|
+
# Install bundled skills and commands
|
|
334
334
|
_install_skills()
|
|
335
|
+
_install_commands()
|
|
335
336
|
|
|
336
337
|
# Optional: auto-start session watcher
|
|
337
338
|
_start_watcher()
|
|
@@ -370,6 +371,39 @@ def _install_skills():
|
|
|
370
371
|
logger.warn(f"Failed to install skills: {e}")
|
|
371
372
|
|
|
372
373
|
|
|
374
|
+
def _install_commands():
|
|
375
|
+
"""Copy bundled /cmo command files to ~/.claude/commands/ if newer or missing."""
|
|
376
|
+
import hashlib
|
|
377
|
+
from pathlib import Path
|
|
378
|
+
from importlib import resources
|
|
379
|
+
|
|
380
|
+
commands_dir = Path.home() / ".claude" / "commands"
|
|
381
|
+
commands_dir.mkdir(parents=True, exist_ok=True)
|
|
382
|
+
|
|
383
|
+
try:
|
|
384
|
+
commands_package = resources.files("coppermind_cmo") / "commands"
|
|
385
|
+
if not commands_package.is_dir():
|
|
386
|
+
return
|
|
387
|
+
|
|
388
|
+
for cmd_file in commands_package.iterdir():
|
|
389
|
+
if not cmd_file.name.endswith(".md"):
|
|
390
|
+
continue
|
|
391
|
+
|
|
392
|
+
dest = commands_dir / cmd_file.name
|
|
393
|
+
source_content = cmd_file.read_text(encoding="utf-8")
|
|
394
|
+
source_hash = hashlib.md5(source_content.encode()).hexdigest()
|
|
395
|
+
|
|
396
|
+
if dest.exists():
|
|
397
|
+
dest_hash = hashlib.md5(dest.read_text(encoding="utf-8").encode()).hexdigest()
|
|
398
|
+
if source_hash == dest_hash:
|
|
399
|
+
continue
|
|
400
|
+
|
|
401
|
+
dest.write_text(source_content, encoding="utf-8")
|
|
402
|
+
logger.info(f"Installed command: {cmd_file.name}")
|
|
403
|
+
except Exception as e:
|
|
404
|
+
logger.warn(f"Failed to install commands: {e}")
|
|
405
|
+
|
|
406
|
+
|
|
373
407
|
def _install_statusline():
|
|
374
408
|
"""Copy statusline.sh to ~/.coppermind/ on first run (skipped on Windows)."""
|
|
375
409
|
if sys.platform == "win32":
|
|
@@ -141,6 +141,12 @@ def _switch_client(
|
|
|
141
141
|
has_customer = _has_customer_id_col(db)
|
|
142
142
|
|
|
143
143
|
# --- LOOKUP: filter by customer_id when available ---
|
|
144
|
+
# Default-deny: if isolation column exists but customer_id is missing, refuse lookup.
|
|
145
|
+
if has_customer and not customer_id:
|
|
146
|
+
return tool_error("PROVISIONING_ERROR",
|
|
147
|
+
"Your account could not be identified. "
|
|
148
|
+
"This usually means your API key is misconfigured. "
|
|
149
|
+
"Contact coppermind@volacci.com for help.")
|
|
144
150
|
has_access = _has_access_table(db)
|
|
145
151
|
if customer_id and has_customer:
|
|
146
152
|
# Only show minds this customer owns or has access to
|
|
@@ -322,8 +328,13 @@ def _list_minds(limit: int, offset: int, db: Database, include_internal: bool =
|
|
|
322
328
|
where_clauses = []
|
|
323
329
|
params: list = []
|
|
324
330
|
|
|
325
|
-
# Customer isolation: only show minds this customer owns or has access to
|
|
326
|
-
if customer_id
|
|
331
|
+
# Customer isolation: only show minds this customer owns or has access to.
|
|
332
|
+
# Default-deny: if the isolation column exists but customer_id is missing,
|
|
333
|
+
# return nothing rather than leaking all customers' data.
|
|
334
|
+
if _has_customer_id_col(db):
|
|
335
|
+
if not customer_id:
|
|
336
|
+
logger.warn("Isolation column present but no customer_id — returning empty list")
|
|
337
|
+
return []
|
|
327
338
|
if _has_access_table(db):
|
|
328
339
|
where_clauses.append(
|
|
329
340
|
"(cm.customer_id = %s OR EXISTS ("
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: coppermind-cmo
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.4
|
|
4
4
|
Summary: AI-powered memory for fractional CMOs — never forget a client detail, never leak data between clients
|
|
5
5
|
Author-email: Ben Finklea <ben@volacci.com>
|
|
6
6
|
License-Expression: LicenseRef-Proprietary
|
|
@@ -27,6 +27,14 @@ src/coppermind_cmo.egg-info/dependency_links.txt
|
|
|
27
27
|
src/coppermind_cmo.egg-info/entry_points.txt
|
|
28
28
|
src/coppermind_cmo.egg-info/requires.txt
|
|
29
29
|
src/coppermind_cmo.egg-info/top_level.txt
|
|
30
|
+
src/coppermind_cmo/commands/cmo-actions.md
|
|
31
|
+
src/coppermind_cmo/commands/cmo-batch.md
|
|
32
|
+
src/coppermind_cmo/commands/cmo-connect.md
|
|
33
|
+
src/coppermind_cmo/commands/cmo-followup.md
|
|
34
|
+
src/coppermind_cmo/commands/cmo-handoff.md
|
|
35
|
+
src/coppermind_cmo/commands/cmo-help.md
|
|
36
|
+
src/coppermind_cmo/commands/cmo-morning.md
|
|
37
|
+
src/coppermind_cmo/commands/cmo-review.md
|
|
30
38
|
src/coppermind_cmo/skills/cmo-onboard-client.md
|
|
31
39
|
src/coppermind_cmo/tools/__init__.py
|
|
32
40
|
src/coppermind_cmo/tools/brand.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo/skills/cmo-onboard-client.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{coppermind_cmo-0.3.2 → coppermind_cmo-0.3.4}/src/coppermind_cmo.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|