feat: v9.0.0 — three new agent templates (Discovery, Stakeholder Comms, Launch)
This release adds three new agent templates to the library, bringing the total to four. New templates: - PM Discovery Agent: synthesises customer interviews from Notion or Google Drive, identifies cross-interview themes, scores assumption confidence, generates follow-up questions - PM Stakeholder Comms Agent: detects audience type (executive/investor/stakeholder/board), pulls activity from Linear/Jira/Drive, drafts in audience-appropriate format - PM Launch Agent: end-to-end launch coordination with channel-specific content, calendar, success metrics, and launch checklist Each template follows the established pattern: README, AGENT.md, orchestrate.sh, 2 subagents, connectors with example configs, examples, smoke test. Total file count: 37 new files across 3 templates. Updated README to position library as 4-template collection. Bumped marketplace.json from v8.0.0 to v9.0.0.
This commit is contained in:
@@ -0,0 +1,169 @@
|
||||
# Connectors — PM Discovery Agent
|
||||
|
||||
This folder contains the connector configurations for the PM Discovery Agent. You only need to set up the connector for whichever tool your team uses for interview notes — Notion or Google Drive.
|
||||
|
||||
## Which connector should I use?
|
||||
|
||||
| If your interview notes live in... | Use this connector |
|
||||
|---|---|
|
||||
| A Notion database | `notion.json` |
|
||||
| A Google Drive folder of Google Docs | `google-drive.json` |
|
||||
| Both | Pick the one with more interviews — agents work better with more data |
|
||||
| Somewhere else (Dovetail, Granola, Otter, etc.) | See "Building a connector for another system" below |
|
||||
|
||||
## Notion setup (5 minutes)
|
||||
|
||||
This is the fastest path if you keep interviews in Notion.
|
||||
|
||||
### 1. Create a Notion integration
|
||||
|
||||
- Go to https://www.notion.so/my-integrations
|
||||
- Click "+ New integration"
|
||||
- Name it "PM Discovery Agent"
|
||||
- Leave defaults
|
||||
- Click Submit
|
||||
- Copy the "Internal Integration Token" (starts with `secret_`)
|
||||
|
||||
### 2. Set the environment variable
|
||||
|
||||
```bash
|
||||
export NOTION_INTEGRATION_TOKEN='secret_xxxxxxxxxxxxxxxxxxxxxxxx'
|
||||
```
|
||||
|
||||
To make permanent, add to `~/.zshrc` or `~/.bashrc`.
|
||||
|
||||
### 3. Share your interview database with the integration
|
||||
|
||||
- Open your interview notes database in Notion
|
||||
- Click the `...` menu in the top right
|
||||
- Select "Add connections"
|
||||
- Choose "PM Discovery Agent"
|
||||
|
||||
The integration now has access to that database.
|
||||
|
||||
### 4. Find your database ID
|
||||
|
||||
The database ID is in the URL when viewing the database. Format: `notion.so/your-workspace/DATABASE_ID?v=...`
|
||||
|
||||
The ID is the long string between `/` and `?`. Copy it.
|
||||
|
||||
### 5. Configure the connector
|
||||
|
||||
```bash
|
||||
cp notion.example.json notion.json
|
||||
```
|
||||
|
||||
Open `notion.json` and update:
|
||||
- `database_id` — paste the ID from step 4
|
||||
- `expected_properties` — adjust to match your actual property names (the defaults assume Name, Interview Date, Interviewee, Segment, Status, Tags)
|
||||
|
||||
### 6. Test
|
||||
|
||||
```bash
|
||||
cd ../ # back to pm-discovery-agent root
|
||||
bash orchestrate.sh --research-question "Test" --interview-source notion --dry-run
|
||||
```
|
||||
|
||||
If you see "✓ Dry-run complete", you're set up.
|
||||
|
||||
## Google Drive setup (10 minutes)
|
||||
|
||||
A bit more setup than Notion, but works well if your team uses Google Docs for interviews.
|
||||
|
||||
### 1. Create a Google Cloud project
|
||||
|
||||
- Go to https://console.cloud.google.com/
|
||||
- Click "Select a project" > "New Project"
|
||||
- Name it "PM Discovery Agent"
|
||||
- Click Create
|
||||
|
||||
### 2. Enable the APIs
|
||||
|
||||
- In the project, search for "Google Drive API" in the API library
|
||||
- Click Enable
|
||||
- Search for "Google Docs API"
|
||||
- Click Enable
|
||||
|
||||
### 3. Create a service account
|
||||
|
||||
- Go to IAM & Admin > Service Accounts
|
||||
- Click "+ Create Service Account"
|
||||
- Name: "pm-discovery-reader"
|
||||
- Description: "Read-only access for PM Discovery Agent"
|
||||
- Click Create
|
||||
- Skip the optional permissions step
|
||||
- Click Done
|
||||
|
||||
### 4. Download the service account key
|
||||
|
||||
- Click on the service account you just created
|
||||
- Go to the "Keys" tab
|
||||
- Click "Add Key" > "Create new key"
|
||||
- Choose JSON
|
||||
- Save the file somewhere secure (e.g., `~/.config/pm-discovery-agent/service-account.json`)
|
||||
|
||||
### 5. Set the environment variable
|
||||
|
||||
```bash
|
||||
export GOOGLE_APPLICATION_CREDENTIALS='/Users/yourname/.config/pm-discovery-agent/service-account.json'
|
||||
```
|
||||
|
||||
To make permanent, add to `~/.zshrc` or `~/.bashrc`.
|
||||
|
||||
### 6. Share your interview folder with the service account
|
||||
|
||||
- Find the service account email (it looks like `pm-discovery-reader@your-project.iam.gserviceaccount.com`)
|
||||
- Open your interview notes folder in Google Drive
|
||||
- Click Share
|
||||
- Paste the service account email
|
||||
- Set permission to Viewer
|
||||
- Click Send
|
||||
|
||||
### 7. Find your folder ID
|
||||
|
||||
Open the folder in Google Drive. The URL looks like: `drive.google.com/drive/folders/FOLDER_ID_HERE`
|
||||
|
||||
Copy the ID after `/folders/`.
|
||||
|
||||
### 8. Configure the connector
|
||||
|
||||
```bash
|
||||
cp google-drive.example.json google-drive.json
|
||||
```
|
||||
|
||||
Open `google-drive.json` and update:
|
||||
- `folder_id` — paste the ID from step 7
|
||||
|
||||
### 9. Test
|
||||
|
||||
```bash
|
||||
cd ../ # back to pm-discovery-agent root
|
||||
bash orchestrate.sh --research-question "Test" --interview-source google-drive --dry-run
|
||||
```
|
||||
|
||||
## Building a connector for another system
|
||||
|
||||
If your interview notes live somewhere other than Notion or Google Drive, you can build a connector following the same pattern. Common alternatives PMs use:
|
||||
|
||||
- **Dovetail** — has a research API; build a connector for the analysis endpoint
|
||||
- **Granola / Otter / Fathom** — meeting recorders; build a connector that pulls transcripts
|
||||
- **Reflect / Roam / Logseq** — personal note-taking apps; build a connector for the markdown files
|
||||
- **Coda / Airtable** — alternative databases; build a connector for the rows API
|
||||
- **Local files** — markdown files in a folder; build a simple file-reading connector
|
||||
|
||||
A connector needs three things:
|
||||
1. A configuration file defining the data source URL, credentials, and available operations
|
||||
2. An API client the orchestration script can call
|
||||
3. A mapping from the source's data model to what the agent expects (interview ID, date, interviewee, content, tags)
|
||||
|
||||
Copy `notion.example.json` or `google-drive.example.json` as a starting point.
|
||||
|
||||
If you build a connector for a new system, consider raising a PR back to the main pm-claude-skills repo.
|
||||
|
||||
## Security notes
|
||||
|
||||
**Credentials live in environment variables, not in the JSON files.** This means you can commit your `notion.json` or `google-drive.json` to source control without leaking credentials.
|
||||
|
||||
**Use read-only access where possible.** The agent only needs to read interview notes — never to modify them. Both Notion integrations and Google Drive service accounts can be set up with read-only permissions. Use them.
|
||||
|
||||
**Rotate credentials periodically.** Both Notion integration tokens and Google service account keys can be regenerated. Do this every 90 days as a security practice.
|
||||
@@ -0,0 +1,86 @@
|
||||
{
|
||||
"connector_name": "google-drive",
|
||||
"version": "1.0.0",
|
||||
"description": "Google Drive connector for the PM Discovery Agent. Reads interview notes from a Google Drive folder where each interview is a Google Doc.",
|
||||
|
||||
"configuration": {
|
||||
"folder_id": "FOLDER_ID_HERE",
|
||||
"file_type": "application/vnd.google-apps.document",
|
||||
"include_subfolders": false,
|
||||
"expected_naming_convention": "YYYY-MM-DD - Interviewee Name.gdoc",
|
||||
"default_sort": {
|
||||
"field": "modifiedTime",
|
||||
"direction": "desc"
|
||||
},
|
||||
"default_filters": {
|
||||
"exclude_trashed": true,
|
||||
"min_word_count": 100
|
||||
},
|
||||
"rate_limit_requests_per_minute": 60
|
||||
},
|
||||
|
||||
"credentials": {
|
||||
"_comment": "Google Drive uses OAuth 2.0. You'll need to create a Google Cloud project and enable the Drive API. Easiest path: use a service account with access to your folder.",
|
||||
"auth_method": "service_account",
|
||||
"service_account_key_path_env_var": "GOOGLE_APPLICATION_CREDENTIALS",
|
||||
"service_account_key_placeholder": "/path/to/service-account-key.json"
|
||||
},
|
||||
|
||||
"available_operations": [
|
||||
{
|
||||
"name": "list_recent_documents",
|
||||
"description": "Get the N most recent Google Docs in the configured folder",
|
||||
"filters": ["modifiedAfter", "name_contains", "starred"],
|
||||
"max_results": 50
|
||||
},
|
||||
{
|
||||
"name": "get_document_content",
|
||||
"description": "Fetch the full text content of a specific Google Doc",
|
||||
"required_input": "file_id"
|
||||
},
|
||||
{
|
||||
"name": "search_documents",
|
||||
"description": "Search document content by keyword across the folder",
|
||||
"required_input": "search_query"
|
||||
}
|
||||
],
|
||||
|
||||
"permissions_required": [
|
||||
"https://www.googleapis.com/auth/drive.readonly",
|
||||
"https://www.googleapis.com/auth/documents.readonly"
|
||||
],
|
||||
|
||||
"_setup_instructions": [
|
||||
"1. Go to Google Cloud Console: https://console.cloud.google.com/",
|
||||
"2. Create a new project (or use existing) — name it something like 'PM Discovery Agent'",
|
||||
"3. Enable the Google Drive API and Google Docs API for the project",
|
||||
"4. Create a service account: IAM & Admin > Service Accounts > Create Service Account",
|
||||
"5. Download the service account key as JSON",
|
||||
"6. Save the JSON file to a secure location (e.g., ~/.config/pm-discovery-agent/service-account.json)",
|
||||
"7. Set the environment variable: export GOOGLE_APPLICATION_CREDENTIALS='/path/to/service-account.json'",
|
||||
"8. Find the folder ID where your interview notes live: open the folder in Google Drive, the ID is in the URL (drive.google.com/drive/folders/FOLDER_ID_HERE)",
|
||||
"9. Share that folder with the service account email (it looks like xxx@your-project.iam.gserviceaccount.com) — give it Viewer access",
|
||||
"10. Update folder_id in this file",
|
||||
"11. Save this file as 'google-drive.json' (without the .example)",
|
||||
"12. Test the connection: bash orchestrate.sh --research-question 'Test' --interview-source google-drive --dry-run"
|
||||
],
|
||||
|
||||
"_alternative_simpler_setup": [
|
||||
"If creating a service account feels heavy, you can use OAuth user credentials instead:",
|
||||
"1. Go to APIs & Services > Credentials in Google Cloud Console",
|
||||
"2. Create OAuth client ID > Desktop application",
|
||||
"3. Download the credentials JSON",
|
||||
"4. The first time the agent runs, it'll open a browser for you to authorise",
|
||||
"This is simpler but requires re-authorisation if the token expires."
|
||||
],
|
||||
|
||||
"_folder_organisation_recommendation": [
|
||||
"If you're starting fresh, organise your interview notes folder like this:",
|
||||
"- One folder for the discovery project",
|
||||
"- One Google Doc per interview, named '2026-05-10 - Sarah Chen.gdoc' (date + interviewee)",
|
||||
"- Inside each doc: structured headers for Background, Notes, Key Quotes, Observations, Follow-ups",
|
||||
"Consistent structure makes the synthesis dramatically better."
|
||||
],
|
||||
|
||||
"_rate_limit_notes": "Google Drive's API rate limits are generous (1000 requests per 100 seconds). The agent uses approximately 12-15 API calls per discovery synthesis."
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
{
|
||||
"connector_name": "notion",
|
||||
"version": "1.0.0",
|
||||
"description": "Notion connector for the PM Discovery Agent. Reads interview notes from a Notion database where each interview is a database row.",
|
||||
|
||||
"configuration": {
|
||||
"database_id": "DATABASE_ID_HERE",
|
||||
"workspace_url": "https://www.notion.so/your-workspace",
|
||||
"expected_properties": {
|
||||
"title_property": "Name",
|
||||
"date_property": "Interview Date",
|
||||
"interviewee_property": "Interviewee",
|
||||
"segment_property": "Segment",
|
||||
"status_property": "Status",
|
||||
"tags_property": "Tags"
|
||||
},
|
||||
"default_filters": {
|
||||
"status_is": "Completed",
|
||||
"exclude_archived": true
|
||||
},
|
||||
"default_sort": {
|
||||
"property": "Interview Date",
|
||||
"direction": "descending"
|
||||
},
|
||||
"rate_limit_requests_per_second": 3
|
||||
},
|
||||
|
||||
"credentials": {
|
||||
"_comment": "Notion uses an integration token. Create one at https://www.notion.so/my-integrations and share your database with it.",
|
||||
"integration_token_env_var": "NOTION_INTEGRATION_TOKEN",
|
||||
"integration_token_placeholder": "secret_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||
},
|
||||
|
||||
"available_operations": [
|
||||
{
|
||||
"name": "list_recent_interviews",
|
||||
"description": "Get the N most recent interviews from the configured database",
|
||||
"filters": ["segment", "tags", "date_range", "status"],
|
||||
"max_results": 50
|
||||
},
|
||||
{
|
||||
"name": "get_interview_content",
|
||||
"description": "Fetch the full page content of a specific interview (notes, transcript, observations)",
|
||||
"required_input": "page_id"
|
||||
},
|
||||
{
|
||||
"name": "search_interviews",
|
||||
"description": "Search interview content by keyword",
|
||||
"required_input": "search_query"
|
||||
}
|
||||
],
|
||||
|
||||
"permissions_required": [
|
||||
"Read content",
|
||||
"Read user information without email"
|
||||
],
|
||||
|
||||
"_setup_instructions": [
|
||||
"1. Create a Notion integration at https://www.notion.so/my-integrations",
|
||||
"2. Click '+ New integration', name it 'PM Discovery Agent', leave defaults",
|
||||
"3. After creation, copy the Internal Integration Token (starts with 'secret_')",
|
||||
"4. Set the environment variable: export NOTION_INTEGRATION_TOKEN='secret_xxxxx...'",
|
||||
"5. Open your interview notes database in Notion",
|
||||
"6. Click '...' menu in top right > 'Add connections' > select your new integration",
|
||||
"7. Find your database ID: it's the long string in the URL when viewing the database (after the workspace name and before the '?'). Example: notion.so/workspace/abc123def456 — abc123def456 is the ID",
|
||||
"8. Update database_id in this file",
|
||||
"9. Update expected_properties to match your actual property names (the agent expects fields named Name, Interview Date, Interviewee, Segment, Status, Tags — adjust if yours are different)",
|
||||
"10. Save this file as 'notion.json' (without the .example)",
|
||||
"11. Test the connection: bash orchestrate.sh --research-question 'Test' --interview-source notion --dry-run"
|
||||
],
|
||||
|
||||
"_notion_database_setup_recommendation": [
|
||||
"If you don't have a Notion database for interviews yet, create one with these properties:",
|
||||
"- Name (title) — interview identifier or interviewee name",
|
||||
"- Interview Date (date) — when the interview happened",
|
||||
"- Interviewee (text) — who was interviewed",
|
||||
"- Segment (select) — which user segment they belong to",
|
||||
"- Status (select) — Scheduled / Completed / Cancelled",
|
||||
"- Tags (multi-select) — research project, persona, or feature area",
|
||||
"Then write your interview notes in the page body."
|
||||
],
|
||||
|
||||
"_rate_limit_notes": "Notion's API is rate limited to 3 requests per second per integration. The agent typically uses 10-25 API calls per discovery synthesis (depending on interview count), well within rate limits."
|
||||
}
|
||||
Reference in New Issue
Block a user