← Aircover.aiCONTENT HISTORY

Update to Aircover.ai

Snapshot Oct 24, 2026 · 13:48 UTC · version 1.0.0

Collection source: downloaded plugin package.

WHAT CHANGED

First saved snapshot

No earlier snapshot is available to establish a change.

Save Aircover.ai and check future changes in Following.

Up to 10 plugins free · no card required.

Compare saved observations

Download comparison JSON
Full technical diff · 0 changed fields
Full snapshot data
{
  "description": "Generate a Customer Product Sentiment report as an Excel workbook from Aircover agent results. Runs the Product VoC agent on every external meeting in a date range, writes each result to disk as it goes, aggregates signals by account, and outputs a professional .xlsx with Sentiment Highlights, Account Summary, Signal Detail, Sentiment Summary, Raw Data, and Agent Properties Guide sheets. Trigger when the user says \"product sentiment\", \"sentiment report\", \"VoC report\", \"product feedback report\", \"customer sentiment tracking\", or asks for a summary of product signals across accounts.",
  "included_files": [
    {
      "relative_path": "LICENSE",
      "size_in_bytes": 1071
    },
    {
      "relative_path": "README.md",
      "size_in_bytes": 3210
    },
    {
      "relative_path": "examples/Customer_Sentiment_Report_SAMPLE.xlsx",
      "size_in_bytes": 12519
    },
    {
      "relative_path": "examples/sentiment_results.example.jsonl",
      "size_in_bytes": 3917
    },
    {
      "relative_path": "scripts/generate_report.py",
      "size_in_bytes": 13648
    }
  ],
  "name": "product-sentiment-tracker",
  "skill_md_contents": "---\nname: product-sentiment-tracker\ndescription: Generate a Customer Product Sentiment report as an Excel workbook from Aircover agent results. Runs the Product VoC agent on every external meeting in a date range, writes each result to disk as it goes, aggregates signals by account, and outputs a professional .xlsx with Sentiment Highlights, Account Summary, Signal Detail, Sentiment Summary, Raw Data, and Agent Properties Guide sheets. Trigger when the user says \"product sentiment\", \"sentiment report\", \"VoC report\", \"product feedback report\", \"customer sentiment tracking\", or asks for a summary of product signals across accounts.\n---\n\n# Product Sentiment Tracker\n\nGenerate a consolidated Customer Product Sentiment report from Aircover meeting data. Runs the Product VoC agent on every processable meeting, writes each result to a JSONL file on disk as it goes, then aggregates product requests, product gaps, feature adoption signals, competitive intelligence, integration requests, and VoC summaries by account. Output is a professionally formatted Excel workbook (.xlsx) where Raw Data is the source of truth and all other sheets aggregate from it.\n\n## Bundled resources\n\n- `scripts/generate_report.py`: Reads the JSONL results file, aggregates, and generates the .xlsx with six sheets (requires `openpyxl`).\n- Follows the shared Aircover MCP rules (inlined below).\n\n## Requirements\n\n- The **Production** Aircover connector must be connected.\n- Code execution / file creation enabled.\n\n## Configuration\n\n- **Environment:** Production (api.aircover.ai)\n- **Agent:** Selected at run time, not hardcoded. The skill lists the available agents and asks the user which to run (see Run order step 2). It works best with a product-sentiment or product-VoC style agent whose properties cover requests, gaps, feature signals, competitive intelligence, integrations, and a summary.\n- **App host:** app.aircover.ai (for meeting URLs)\n- **Default date range:** Last 30 days from today\n- **Default owner:** Omit (pull org-wide). Pass an email if the user asks for \"my calls\" only.\n\n## Agent properties (expected shape)\n\nA product-VoC agent typically returns these 6 properties. The agent the user selects may use different titles; **join on `title`, never on `key`** (keys are positional and vary), and map the selected agent's properties to the closest report slots below. A property with no equivalent can fold into the VoC Summary or be omitted. If the selected agent looks nothing like a product-sentiment agent, say so and confirm before running.\n\n| # | Title | Scored | Max Score | What it captures |\n|---|-------|--------|-----------|-----------------|\n| 0 | Product Requests | Yes | 5 | Explicit feature requests from the customer |\n| 1 | Product Gaps | Yes | 5 | Existing features that fall short of needs |\n| 2 | Feature Adoption Signals | No | 0 | Customer reactions to specific features (Active Use, Interested, Not Adopted, Dropped) |\n| 3 | Competitive Intelligence | No | 0 | Competitor mentions, comparisons, sentiment |\n| 4 | Integration Requests | Yes | 5 | Integration needs for connecting to other systems |\n| 5 | VoC Summary | No | 0 | 2-4 sentence executive summary of all signals |\n\n**Important:** A single property result often contains multiple signals separated by double newlines (`\\n\\n`). Each block starting with a bold label (e.g., `**Request:**`, `**Gap:**`, `**Feature:**`, `**Competitor:**`, `**Integration:**`) is one individual signal. Parse these into separate rows on the Signal Detail sheet.\n\n## Run order\n\n### 1. Load tools and confirm environment\n\nUse the Aircover tools exposed by the host and follow the exact parameter names in their live schemas. Confirm the connected MCP server is **Aircover Production** at `api.aircover.ai`. If the tools are unavailable, ask the user to connect Aircover.ai before continuing.\n\n### 2. Interview (minimal)\n\nFirst, **select the agent**. Call `list_agents` and present the available agents to the user (name and category), then ask which one to run. Suggest agents whose title or category indicates product sentiment or VoC, but let the user pick any. If exactly one clearly matches, you may propose it and confirm rather than listing everything. Use the chosen agent's `id` as `template_id` for every `agent_results` call below. Do not hardcode an id.\n\nThen confirm the rest, asking only if ambiguous:\n- Date range? Default last 30 days. Accept overrides.\n- Owner scoped or org-wide? Default org-wide.\n- Subset of accounts? Default all.\n\n### 3. Pull meetings\n\nCall `list_meetings(start, end)` with optional `owner`. Save the full response.\n\n### 4. Filter to external prospect meetings\n\nRemove meetings where:\n- `prospect_org` is \"unknown\" (solo/test meetings)\n- `prospect_org` is \"aircover.ai\" AND `customer_org` is \"aircover.ai\" (internal)\n- Fewer than 2 attendees\n- Summary starts with \"Canceled\" or \"Declined\" (case-insensitive)\n\n### 5. Estimate and warn\n\nCount filtered meetings. Report the count to the user. If over 80, offer to narrow by account or date range. Each meeting is one `agent_results` call. Many meetings will have no transcript and will be skipped automatically.\n\nNote from experience: expect roughly 40-60% of meetings to have processable transcripts. Teams meetings, very short calls, and same-day meetings often lack transcripts. The skill handles these gracefully.\n\n### 6. Loop: run agent_results per meeting, write to disk as you go\n\nUse a temporary host-provided working directory as `WORK_DIR` and the host-provided deliverables directory as `OUTPUT_DIR`. Create a JSONL file at `$WORK_DIR/sentiment_results.jsonl`. For each meeting:\n\n```\nagent_results(meeting_id=<full 32-char id>, template_id=<the agent id selected in step 2>)\n```\n\n**On success:** Extract the entries by joining on `title`. Write one JSON line to the JSONL file:\n```json\n{\"mid\":\"<id>\",\"date\":\"<YYYY-MM-DD from start_time>\",\"acct\":\"<prospect_org>\",\"title\":\"<meeting summary>\",\"pr\":\"<Product Requests result>\",\"pr_c\":<score>,\"pg\":\"<Product Gaps result>\",\"pg_c\":<score>,\"fs\":\"<Feature Adoption Signals result>\",\"ci\":\"<Competitive Intelligence result>\",\"ir\":\"<Integration Requests result>\",\"ir_c\":<score>,\"voc\":\"<VoC Summary result>\",\"url\":\"https://app.aircover.ai/meetings/<full id>\"}\n```\n\n**On error:** Check the error message.\n- If it contains \"no transcript available\": skip silently, increment a `no_transcript` counter.\n- If it is a generic error: skip, increment a `errors` counter.\n- In both cases, do NOT write a row to the JSONL. Do NOT stop the loop.\n\n**After every 10-15 meetings**, briefly report progress to the user (e.g., \"Processed 15/49, 8 with data, 7 no transcript\").\n\n### 7. Report processing summary\n\nAfter the loop, tell the user:\n- Total meetings attempted\n- Meetings with data (rows in JSONL)\n- Meetings skipped: no transcript\n- Meetings skipped: error\n- This is the actual meeting count the report will reflect.\n\n### 8. Generate the .xlsx\n\nRun the bundled script:\n\n```bash\npython3 scripts/generate_report.py $WORK_DIR/sentiment_results.jsonl $OUTPUT_DIR/Customer_Sentiment_Report.xlsx \"<name of the agent selected in step 2>\"\n```\n\nThe host runtime must already provide `openpyxl`. If it is unavailable, explain the missing dependency and stop before generating the workbook; do not install packages silently.\n\nThe script:\n1. Reads the JSONL file (one JSON object per line)\n2. Aggregates by account (using `acct` field as the grouping key)\n3. Parses multi-signal entries into individual signal rows (splitting on `\\n\\n` blocks)\n4. Computes signal counts, distributions, and top signals per account\n5. Writes all six sheets with Raw Data as the source of truth\n\n### 9. Present the file\n\nProvide the generated file using the host’s normal file-delivery mechanism.\n\n## Output format\n\nThe .xlsx workbook contains six sheets:\n\n1. **Sentiment Highlights**: Title, subtitle with accurate meeting/account counts, and a summary table with one row per account sorted by signal count descending. Columns: Account, Meetings, Total Signals, Product Requests, Product Gaps, Feature Signals, Top Product Request, Top Product Gap. Frozen header, auto-filter.\n\n2. **Account Summary**: One row per account with detail. Columns: Account, Meetings, Signals, PR, PG, FS, Top Signal, First Date, Latest Date, Blockers?, Latest VoC Summary. Frozen header, auto-filter.\n\n3. **Signal Detail**: One row per individual signal (multi-signal entries parsed into separate rows). Columns: Account, Date, Signal Type, Signal, Confidence, Meeting URL. Frozen header, auto-filter.\n\n4. **Sentiment Summary**: Two tables. Signal Type Distribution (type, accounts, count, %). Top Signal Sources by Account (account, PR count, PG count, FS count).\n\n5. **Raw Data**: One row per meeting with the full agent output per property. This is the source of truth. All other sheets aggregate from this data. Columns: Meeting ID, Date, Account, Meeting Title, Product Requests, PR Conf, Product Gaps, PG Conf, Feature Sentiment, VoC Summary, Meeting URL. Frozen header, auto-filter.\n\n6. **Agent Properties Guide**: Reference sheet documenting the 6 agent properties, their types, scoring, and what they capture.\n\n## Rules\n\n- **Raw Data is the source of truth.** Every other sheet aggregates from it. The meeting count on Sentiment Highlights must equal the row count on Raw Data, not the total from list_meetings.\n- Join agent_results on title, not key. Discover field names at runtime. Never fabricate; use \"Not found\" or omit.\n- \"Not found\" matching is case-insensitive (\"Not found\", \"Not Found\", \"not found\" all mean empty).\n- Full 32-char meeting ids everywhere, especially in URLs.\n- Filter by prospect_org, never bare deal_id.\n- No em dashes anywhere. Use commas, periods, colons, or parentheses.\n- Lists for enumerations, short prose for narrative.\n- Times in PT, no UTC.\n- Write results to JSONL on disk after each call. Do not hold all results in conversation context.\n- If agent_results errors on a meeting, skip and continue. Track skipped counts separately for \"no transcript\" vs generic errors.\n- Multi-signal entries: split on double newlines and bold-label patterns to produce individual signal rows.\n- Expect 40-60% of meetings to lack transcripts (Teams without recording, same-day meetings, short calls). This is normal, not a failure.\n"
}

SHA-256 of public snapshot: 339db3eff12fd4d47e242dab4f0c29c465da1284ec7e98dcfea4410f37530323