{"id":52098,"plugin_id":"plugin_asdk_app_6ac900a965a08191961defc63200cf3f","kind":"skill","collection_source":"plugin_package","comparison_source":null,"observed_at":"2026-10-24T13:48:37.605Z","digest":"d97080916255ea347fac84477c088dddb1a6706bcbeeb9c31d03156fc38ea7ec","against":null,"payload":{"description":"Generate a completed Mutual Action Plan (MAP) spreadsheet for a deal, pulling the account, opportunity, sponsors, target go-live date, and deal progress from the Aircover Production account and filling the team's standard MAP template. Use this whenever someone says \"build a mutual action plan\", \"run the MAP\", \"make a MAP for [company]\", \"close plan\", or \"joint action plan\", or wants a deal turned into the shared roadmap spreadsheet, even if they do not name the template.","included_files":[{"relative_path":"LICENSE","size_in_bytes":1071},{"relative_path":"README.md","size_in_bytes":3950},{"relative_path":"assets/Mutual_Action_Plan_TEMPLATE.xlsx","size_in_bytes":11272},{"relative_path":"config.json","size_in_bytes":1613},{"relative_path":"references/example_values.json","size_in_bytes":1457},{"relative_path":"references/field_source_map.md","size_in_bytes":3659},{"relative_path":"scripts/fill_map.py","size_in_bytes":8376}],"name":"aircover-mutual-action-plan","skill_md_contents":"---\nname: aircover-mutual-action-plan\ndescription: Generate a completed Mutual Action Plan (MAP) spreadsheet for a deal, pulling the account, opportunity, sponsors, target go-live date, and deal progress from the Aircover Production account and filling the team's standard MAP template. Use this whenever someone says \"build a mutual action plan\", \"run the MAP\", \"make a MAP for [company]\", \"close plan\", or \"joint action plan\", or wants a deal turned into the shared roadmap spreadsheet, even if they do not name the template.\n---\n\n# Aircover Mutual Action Plan\n\nTurn a live Aircover deal into a completed Mutual Action Plan: the shared, dated\nroadmap from discovery to go-live. The skill keeps the team's standard 17-step\nplaybook as the backbone and grounds it in real deal data (account, opportunity,\nsponsors, close date, current progress, agreed next steps). Sourced values render in\nblack; anything the data cannot supply stays a grey placeholder so the rep sees\n\n> **This document is customer-facing.** The MAP is shared and reviewed with the\n> customer. Every cell must be value-add for both sides. Write the substance of\n> what was agreed (objectives, success criteria, decisions, mutual next steps),\n> never internal deal commentary. No MEDDPICC/qualification labels, no coaching or\n> gap language (for example \"captured across 2 calls\", \"still to be established\",\n> \"process mapped\", \"X is the economic buyer\", \"we still need to extract Y\"), and\n> nothing that reads as the seller's private plan. If you would not say it to the\n> customer's face, it does not go in a cell. See \"Writing customer-facing content\"\n> below.\nwhat to finish.\n\n## Bundled resources\n- `config.json` - everything org-specific: environment, how to find the agent, the template filename, the cell map, value colours, and status colours. Change this, not the code, to retarget the skill. The engine reads it automatically.\n- `assets/Mutual_Action_Plan_TEMPLATE.xlsx` - the team template. Holds all styling, the Status dropdown, and the `=$F$7-Fn` due-date formulas. Do not rebuild it; fill it.\n- `scripts/fill_map.py` - template-agnostic engine. Reads `config.json`, writes only the cells you supply, preserves everything else, recolours Status cells when status changes, and writes Go-Live as a real date so all due dates recalculate. Requires openpyxl.\n- `references/field_source_map.md` - which Aircover field feeds which cell, and how to infer status.\n- `references/example_values.json` - a worked values file.\n- `README.md` - install and the three things a new customer changes. Read it if you are forking this for another org.\n\nCopy the script, config, and template into your working directory first:\n```\ncp \"$SKILL_DIR/scripts/fill_map.py\" .\ncp \"$SKILL_DIR/config.json\" .\ncp \"$SKILL_DIR/assets/Mutual_Action_Plan_TEMPLATE.xlsx\" .\n```\n\n## Requirements\n- The **Aircover Production** connector (api.aircover.ai) must be connected. Confirm it before running: Production and Staging share tool names, and an \"agent not found\" error usually means you are pointed at the wrong environment.\n- Code execution / file creation on.\n- `openpyxl` available in the host runtime. If it is unavailable, explain the missing dependency and stop before writing an output file; do not install packages silently.\n\n## Configuration\nAll of this lives in `config.json`. Edit that file to retarget the skill; the engine and run order do not change.\n- **Environment:** Production, api.aircover.ai. App host: app.aircover.ai.\n- **Agent:** discovered at runtime. `config.agent.pinned_template_id` is null, so the skill calls `list_agents` and matches on `config.agent.category` (\"qualification\") and `config.agent.title_keywords`. To lock a specific agent, set `pinned_template_id` and discovery is skipped. Always join results on the entry `title`, never the positional key, so a rebuilt agent still works.\n- **Template + layout:** `config.template.file`, the sheet name, the overview cell map, the action-item columns and row range, and the status colours all come from config. A customer who wants their own MAP template swaps the file and updates the cell map once; no code change.\n- **White-label.** The skill assumes no specific selling company. The \"Our\" side (sponsor, team owners) is read from whatever Aircover account is connected, so the same skill works unchanged for any company whose team uses Aircover. The only platform constants are the Aircover API and app hosts in config; everything else is per-deal, per-account data pulled at run time.\n- Template offsets and the step list are the team standard (config, not deal data). Keep them unless the deal genuinely needs a custom step.\n\n## Run order\n1. **Confirm environment.** Make sure the connected MCP server is Aircover Production at `api.aircover.ai`. Use the Aircover tools exposed by the host and follow the exact parameter names in their live schemas. If the tools are unavailable, ask the user to connect Aircover.ai before continuing.\n\n2. **Identify the deal (deal-first).** `list_meetings` has no account filter, so start from the deal. `get_deals(search=\"<company>\")` to find it. Use the full `deal_key` (`prospect_org/deal_id`) or `prospect_org`, never the bare integer `deal_id` (it resets per org and collides). Echo back the matched deal (company + opportunity + close date) and confirm before building.\n\n3. **Deal + CRM in one call.** `get_deal(prospect_org, deal_id)` returns a `crm` block (both SFDC and HubSpot fields) and a `completed_meetings` array. Pull:\n   - `crm.sfdc_opportunity_name` (or HubSpot equivalent) -> **Project** (B6).\n   - the CRM close date -> **Target Go-Live** (F7). If absent, fall back to the agent Timeline in step 4.\n   - the CRM stage and `completed_meetings` -> evidence for inferring statuses (step 6).\n   - `prospect_org` / company name -> **Account** (B5).\n   Call `get_deal` once and reuse it. An empty `crm` block is a placeholder, not an error: Project and Go-Live then stay grey.\n\n4. **Qualification agent on the key meeting.** Pick the most recent substantive meeting from `completed_meetings`. If `config.agent.pinned_template_id` is set, use it. Otherwise discover the agent: call `list_agents` and match on `config.agent.category` and `config.agent.title_keywords`. Then `agent_results(meeting_id, template_id=<that id>)`. Join on title:\n   - **Discovery fallback:** if `list_agents` returns no match, or more than one plausible candidate, ask the user which agent to use rather than guessing or erroring. If they confirm there is no qualification agent, skip this step and leave Objective and Their Sponsor as grey placeholders for the rep.\n   - Pain / Metrics / Why Now -> synthesize one **Objective** line (B7), the customer's words where possible.\n   - The objectives and success criteria discussed -> the **Notes** on the \"Confirm business objectives and success criteria\" row. List the actual business objectives. For success criteria: if the two sides set specific metrics, state them as agreed. If they did not, write that they are still to be defined and add recommendations from the agent output, in this shape: \"Success criteria to be defined. Recommended based on the customer's needs: X, Y, Z.\" This is honest (nothing is presented as agreed when it is not) and still value-add. Never write a bare gap note like \"metrics still to be established\".\n   - Authority -> the buying committee. The economic buyer and champion -> **Their Sponsor** (F6) and the Owner (Them) on the approval rows. Use the person's name and real title; do not write internal labels like \"Champion\" or \"Economic Buyer\" in cells the customer reads.\n   - Timeline -> sanity-check or supply Go-Live if CRM had none.\n   - The agreed buying/decision process and mutual next steps -> Notes on the relevant rows, phrased as shared understanding (\"Agreed process: ...\", \"Next step: ...\"), not as a private map of their org.\n   - A genuine shared blocker (a security review, a legal document in flight, a procurement window) -> Notes on the affected row plus At Risk/Blocked status, stated neutrally as a joint item to clear, not as the seller's worry.\n   A property with `max_score: 0` is unscored rollup text, not a dimension. If a dimension is \"Not found\", that is accurate for an early call: leave it as a placeholder.\n\n5. **Meeting metadata and the seller side.** `get_meeting(meeting_id)` returns `deal_team`, `prospect_attendees`, and an AI `notes` summary. The \"Our\" side is always derived from the connected Aircover account, never assumed: take **Our Sponsor** (F5) and the Owner (Us) people from `deal_team` (the senior owner as sponsor; map AE/SC/CSM to real names where you can). If `deal_team` is thin, use `get_teams` or the connected user's own email to anchor the seller org. Do not hardcode or assume any specific selling company: whoever is connected is \"us\". Use the `notes` summary to find agreed decisions and mutual next steps for the Notes column, not internal observations about the deal.\n\n6. **Infer status conservatively (judgment, not keywords).** Read the CRM stage and meeting history and reason about which phases are genuinely done. Discovery captured -> rows 1-4 Complete/In Progress; POC underway -> rows 5-9 In Progress then Not Started; security pending -> that row In Progress with the blocker noted; a real blocker -> At Risk/Blocked with the reason. Only mark Complete/In Progress what the data supports. Default everything else to the template's Not Started. Never fabricate progress. See `references/field_source_map.md` for the full mapping.\n\n## Writing customer-facing content\nThe MAP is shared with the customer, so the Notes column and the Owner cells must\nread as a joint working document. Two tests for every note: (1) would you be glad\nthe customer read it, and (2) does it add value for both sides. Convert internal\nagent/coaching output into shared substance.\n\n| Row | Internal (do not write) | Customer-facing (write this) |\n|---|---|---|\n| Confirm business objectives and success criteria | \"Pain, decision criteria, and process captured across 2 calls. Quantified metrics still to be established.\" | \"Objectives: improve prospecting efficiency, raise hit rates, ensure privacy compliance through the role restructure. Success criteria to be defined. Recommended based on the customer's needs: target hit-rate lift, ramp-time reduction, compliance benchmark.\" |\n| Map decision process and stakeholders | \"Process mapped: committee demo, narrow to 2, vote, exec approval.\" | \"Agreed evaluation path: committee demo, shortlist to two, trials, committee vote, final approval.\" |\n| Present business case to Economic Buyer | \"Sam Patel is the economic buyer. Jordan to be briefed and aligned before exec presentation.\" | \"Executive review with Sam Patel (final approver). Pre-brief Jordan Lee beforehand.\" |\n\nRules for Notes:\n- State objectives, success criteria, decisions, and mutual next steps. Recommend\n  success criteria when none were set, framed as a joint proposal.\n- No qualification labels (Champion, Economic Buyer, MEDDPICC terms), no \"captured /\n  established / mapped / extracted\" coaching verbs, no \"across N calls\", no private\n  seller plans, no internal risk editorializing.\n- Name people by their real role/title, not their deal label. Keep notes short,\n  concrete, and neutral. If a row has nothing value-add to say, leave it blank.\n1. Write `values.json` (see `references/example_values.json`). Schema:\n```json\n{\n  \"overview\": {\n    \"account\":       {\"value\": \"...\", \"sourced\": true},\n    \"project\":       {\"value\": \"...\", \"sourced\": true},\n    \"objective\":     {\"value\": \"...\", \"sourced\": true},\n    \"our_sponsor\":   {\"value\": \"...\", \"sourced\": true},\n    \"their_sponsor\": {\"value\": \"...\", \"sourced\": false},\n    \"go_live\":       {\"value\": \"2026-10-01\", \"sourced\": true}\n  },\n  \"action_items\": [\n    {\"row\": 12, \"status\": \"Complete\", \"owner_them\": \"Name (Champion)\", \"notes\": \"...\"}\n  ]\n}\n```\n   - `sourced: true` renders black; `sourced: false` renders grey italic (placeholder still needs the rep). Action-item rows are 12-28; include only the fields you are changing.\n   - `go_live` is an ISO date (YYYY-MM-DD). It is written into F7 as a real date; the Due Date column is `=$F$7-Fn`, so every date recalculates from it.\n\n2. Run:\n```\npython fill_map.py --template Mutual_Action_Plan_TEMPLATE.xlsx --values values.json --out \"Mutual Action Plan - {Company} - {YYYY-MM-DD}.xlsx\"\n```\n\n3. **Recalculate** so the preview shows correct due dates. Use the host's spreadsheet recalculation and validation capability on `Mutual Action Plan - {Company} - {YYYY-MM-DD}.xlsx`. Expect a successful validation with no formula errors. Excel and Google Sheets also recalculate on open.\n\n4. **Present** the `.xlsx`. Note which overview fields are still grey placeholders (the rep's input), confirm the primary champion/EB if there were several attendees, and remind them that changing the Go-Live date in F7 re-dates the whole plan.\n\n## Rules (house style)\n- **No em dashes** anywhere. Use commas, periods, colons, or parentheses.\n- Discover field names at runtime; schemas vary per org and per agent. **Never fabricate**: if a tool returns nothing, leave the grey placeholder, do not invent a value, sponsor, date, or progress.\n- Join `agent_results` on `title`, not the positional key. Use the full 32-char meeting id. Filter by `prospect_org` / `deal_key`, never the bare `deal_id`.\n- Objective and Notes are short and concrete. Times and dates are local (PT), no UTC.\n- Keep the template's structure, banding, formulas, and the Status dropdown intact: the script does this as long as you only pass values.\n\n## Caveats to surface\n- Early deals with no CRM opportunity: Project and Go-Live come back grey; the rep sets them.\n- The 17 steps are the team's standard close plan. If a specific deal needs a different step or cadence, edit `action`/`days_before` for that row in `values.json`; the due date recalcs.\n- Status is an inference from CRM stage and call history, not ground truth. Frame it as a starting point for the rep to confirm.\n"},"changes":[],"summary":"First saved snapshot. No earlier version is available for comparison.","summary_kind":"deterministic","summary_metadata":{}}