[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M69BVXYA2DJCCDS1ASQKT8AS":3,"skill-same:01M69BVXYA2DJCCDS1ASQKT8AS":140},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":34,"publishedAt":47,"linkOnly":48,"markdownContent":49,"markdownBody":50,"frontMatter":51,"refName":56,"commitSha":57,"skillDirectory":58,"forksCount":59,"repositoryHtmlUrl":60,"repositoryHomepageUrl":61,"ownerHtmlUrl":62,"ownerBlogUrl":63,"ownerDescription":64,"updatedAt":65,"install":66,"resources":79},"01M69BVXYA2DJCCDS1ASQKT8AS","cowork-dashboard-team-dashboard",null,"Manager-side team rollup for Copilot Cowork ROI. Aggregates the de-identified stats teammates post (via the Cowork Dashboard Member skill) to a shared Teams channel into ONE anonymized HTML dashboard (five tabs), then emails the channel members a summary with the dashboard and a one-page PDF guide attached. First run asks for the Teams channel link and remembers it; each run reads the latest 15 days and keeps the latest post per person. Numbers only — no names or files; a Role breaks out only when 3+ share it. Small homogeneous teams; not org-wide.\nUse when the user asks to \"build the team Cowork Dashboard\", \"aggregate my team's Cowork stats\", \"roll up the channel posts\", \"manager Cowork Dashboard report\", \"email the team dashboard\", or set up \u002F refresh the rollup.\nDo NOT use for: the personal report (cowork-roi-report), a member's own post (cowork-dashboard-member), the member-side aggregated post (cowork-roi-report-aggregated), org-wide\u002Flarge-team aggregation, GitHub Copilot reports, or single-meeting summaries.","microsoft\u002FCoworkDashboard","microsoft","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F6154722?v=4","01M698VYDXZ6JW5WH3CRV650R8","Microsoft","01M69BVJN563EZMNC1Z6K1CBJ9",14,"MIT","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FCoworkDashboard\u002Fblob\u002Fmain\u002Farchived\u002Fcowork-dashboard-team-dashboard-v1.3.0\u002FSKILL.md",[18,23,26,29],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000002","文档处理","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000013","分析与可视化",{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":30,"categoryName":31,"taxonomyType":32,"taxonomyTypeDesc":33},"01JBSEEDCAT000000000000033","数据分析师","PROFESSION","适用职业",[35,36,37,38,39,40,41,42,43,44,45,46],"dashboard","cowork dashboard team dashboard","PDF","personal","github","roi","github copilot","copilot","teams","run","report","cowork dashboard member","2026-11-10 10:12:30",false,"---\nname: cowork-dashboard-team-dashboard\ndescription: |\n  Manager-side team rollup for Copilot Cowork ROI. Aggregates the de-identified stats teammates post (via the Cowork Dashboard Member skill) to a shared Teams channel into ONE anonymized HTML dashboard (five tabs), then emails the channel members a summary with the dashboard and a one-page PDF guide attached. First run asks for the Teams channel link and remembers it; each run reads the latest 15 days and keeps the latest post per person. Numbers only — no names or files; a Role breaks out only when 3+ share it. Small homogeneous teams; not org-wide.\n  Use when the user asks to \"build the team Cowork Dashboard\", \"aggregate my team's Cowork stats\", \"roll up the channel posts\", \"manager Cowork Dashboard report\", \"email the team dashboard\", or set up \u002F refresh the rollup.\n  Do NOT use for: the personal report (cowork-roi-report), a member's own post (cowork-dashboard-member), the member-side aggregated post (cowork-roi-report-aggregated), org-wide\u002Flarge-team aggregation, GitHub Copilot reports, or single-meeting summaries.\ncowork:\n  category: analysis\n  icon: BarChart4\n---\n\n# Cowork Dashboard — Team Dashboard (manager rollup)\n\nAggregates the **de-identified Cowork Dashboard posts** teammates publish (via the **Copilot ROI\nMember** skill, `cowork-dashboard-member`) to a shared Teams channel, renders a single self-contained,\n**anonymized** HTML dashboard, and **emails the channel members** a high-level summary with the\ndashboard and a one-page interpretation guide (PDF) attached.\n\n**This skill only reads what the Member skill posts.** It never harvests anyone's OneDrive and\nnever sees names, files, or prompts. If a label (business process, skill, Role) doesn't match the\nMember bundle's copy, aggregation drifts — the taxonomy files here are **byte-for-byte mirrors** of\nthe Member skill's (see *Cross-skill contract*).\n\n## Scope (v1)\n- **Small, homogeneous teams** (people doing similar work), **team level**. A handful of\n  contributors sharing one channel.\n- **Not** org-wide \u002F large-team \u002F multi-channel aggregation, and **not** cross-team benchmarking.\n\n## When NOT to Use\n- **A single person's full impact report** → `cowork-roi-report` (rich personal web app).\n- **Posting your own de-identified stats** to the channel → `cowork-dashboard-member`.\n- **The member-side anonymized table post** → `cowork-roi-report-aggregated`.\n- **Org-wide \u002F multi-team \u002F cross-channel aggregation** — out of scope for v1; don't force it.\n- **GitHub Copilot \u002F IDE usage reports**, **daily briefings**, or **single-meeting summaries** —\n  different skills entirely.\n- If the shared channel has **no Cowork Dashboard posts in the last 15 days**, don't fabricate a dashboard —\n  say the window was empty and offer to widen it.\n\n## First run — point the skill at the channel (once)\n\nThe rollup reads ONE shared Teams channel that teammates post to. The channel is **not hard-coded**.\n\n1. **Load `config\u002Fteam_config.json`.** If `team_id` **or** `channel_id` is blank, this is a first run.\n2. **Ask for the channel link.** Use `AskUserQuestion` to ask the user to paste the **link of the\n   Teams channel** where the team posts its Cowork Dashboard stats (in Teams: channel ⋯ → *Get link to\n   channel*). This must be the same channel `cowork-dashboard-member` posts to.\n3. **Resolve + persist the IDs** from that link — no Graph call needed:\n   ```\n   python scripts\u002Fresolve_channel.py --link \"\u003Cpasted url>\" --config config\u002Fteam_config.json\n   ```\n   It extracts `channel_id` (the `19:…@thread.…` segment) and `team_id` (the `groupId`), writes them\n   plus `channel_link` back to the config, and every later run reads the same place. Optionally call\n   `GetTeam(team_id)` and save its `displayName` as `team_name` so the dashboard header is named.\n4. **The Team must already exist** and the runner must be a **member** of it\n   (`ChannelMessage.Read.All`). This skill does not create Teams or channels. If a read fails with an\n   authorization error, the runner isn't a member — add them in Teams; the skill can't grant access.\n\nOn later runs `team_id` + `channel_id` are already set, so skip straight to the workflow. Re-ask for a\nlink only if the user wants to point at a **different** channel.\n\n## Workflow\n\n### 1. Load config (+ first-run channel link)\nRead `config\u002Fteam_config.json`. If `team_id`\u002F`channel_id` are blank, run **First run** above.\n\n### 2. Read the channel posts (latest 15 days)\n`ListChannelMessages(team_id, channel_id, top=50)` (paginate with `next_link` if the team is chatty).\nSave the returned `value` array verbatim to `working\u002Fraw_messages.json` (the parser accepts the Graph\nmessage shape directly). The **latest-15-days window** and **latest-post-per-person** dedupe are\napplied in step 3 — don't hand-filter here.\n\n### 3. Parse + aggregate (window, anonymize, group, canonicalize)\n```\npython scripts\u002Fparse_posts.py --in working\u002Fraw_messages.json --config config\u002Fteam_config.json \\\n       --out working\u002Fteam_data.json --window-days 15 [--now YYYY-MM-DD] [--generated YYYY-MM-DD]\n```\n`parse_posts.py`:\n- keeps only posts from the **last 15 days** (`--window-days`, anchored to `--now`\u002Ftoday), then keeps\n  the **latest post per sender** (id hashed away, never stored\u002Fshown), numbering contributors 1..N;\n- reads each post's parser-stable tables by header signature (tolerant of metric wording drift);\n- pulls the **Role** line if present (the only attribute — no names, no country, no files);\n- **groups business processes** (`process_groups.json`) and **canonicalizes skills**\n  (`skills_vocabulary.json` + `skill_aliases.json`);\n- writes `working\u002Fteam_data.json` (meta + one snapshot + members[] with role|null + metrics).\n\n### 4. Build both outputs — dashboard + one-page guide (a single approval)\n```\npython scripts\u002Fbuild_outputs.py --in working\u002Fteam_data.json --config config\u002Fteam_config.json\n```\nOne invocation renders BOTH deliverables, so the manager approves the build **once, not twice**:\n- **`output\u002Fcowork-team-roi-dashboard.html`** — self-contained HTML (no external assets). Five small\n  tabs: **Overview** (auto-insights + KPI band) · **Impact & Value** (pillars, categories with $,\n  roles, deliverables by format) · **How Cowork is used** (business-process accordion — each process\n  expands to its **distinct deliverables** with the file format inline + the skills behind them —\n  category mix, analyzed → produced) · **Trends** (minimal fortnight-over-fortnight line) ·\n  **Glossary & method**. Value = hours × rate, recomputed live by a rate control.\n- **`output\u002Fhow-to-read-team-roi-dashboard.pdf`** — a single **landscape** interpretation guide\n  explaining every KPI, the five tabs, the two controls, the privacy model, and the methodology, so\n  recipients can read the dashboard unaided (uses `reportlab`, bundled in the Cowork container).\n\n`build_outputs.py` just drives the two builders in sequence; `build_dashboard.py` and\n`build_guide_pdf.py` still run individually if you ever need only one.\n\n### 5. Email the channel members (summary + both attachments) — a separate, expected approval\nThe email send is deliberately **not** bundled into step 4: building the files is one approval, and\nsending them to people is a second, distinct approval. If `email_on_run` is true (default) and the\nuser hasn't said \"don't send\":\n- **Recipients = the channel members.** `ListChannelMembers(team_id, channel_id)` → resolve each to an\n  email\u002FUPN; de-duplicate; include the runner. (A standard channel returns the team members — that's\n  the intended audience.) Never add anyone outside the channel.\n- **Body = a high-level HTML summary** (aggregate only, same privacy rules as the dashboard). Pull the\n  figures from `working\u002Fteam_data.json` — sum the members' headline metrics (time saved, value =\n  hours × rate, sessions, run tasks, deliverables) and name the top 1–2 business processes. Do **not**\n  hand-invent numbers; if a figure isn't in the data, omit it.\n- **Send** with both attachments:\n  ```\n  SendEmailWithAttachments(\n    to=\u003Cresolved channel-member emails>,\n    subject=\"Team Cowork Dashboard — latest rollup (\u003Cperiod>)\",\n    content_type=\"HTML\", body=\u003Csummary html>,\n    direct_attachment_file_paths=[\"output\u002Fcowork-team-roi-dashboard.html\",\n                                  \"output\u002Fhow-to-read-team-roi-dashboard.pdf\"])\n  ```\n  In interactive runs the platform's approval dialog is the confirmation; scheduled runs send\n  automatically. The \"Powered by Copilot Cowork\" footer is appended by the host — don't add your own.\n\n### 6. Verify + deliver\n`Glob output\u002Fcowork-team-roi-dashboard.html` and `Glob output\u002Fhow-to-read-team-roi-dashboard.pdf` to\nconfirm both exist, then tell the user they're saved and the email went to the channel members.\nOptionally show a 3-line highlight (time saved, value, top process) — aggregate only.\n\n### 7. (Optional) automate — run 1–2 days after the member fortnight\nIf the user asks, `SetupScheduledPrompt` with a self-contained description: *\"Read the last 15 days of\nCowork Dashboard posts in the team channel, aggregate them into the anonymized team dashboard and one-page\nPDF guide, save them to my files, and email them to the channel members.\"*\n\n**Timing:** the Member skill posts on a **biweekly Monday** cycle, so schedule the manager rollup to\nrun **1–2 days later — on Wednesday** — which gives teammates Monday and Tuesday to post before the\nrollup reads the channel. Use frequency **Week**, `interval = cadence_days \u002F 7` (= **2** → every other\nWednesday), `weekDays=[\"Wednesday\"]`, `hours=[\"9\"]`, name \"Cowork Dashboard team dashboard\". Scheduled runs\nbuild both outputs and email the channel members automatically (no interactive approval).\n\n## Privacy (hard rules)\n- **Never show anything at an individual level.** Members are counts + a number only.\n- **k-anonymity:** a per-attribute (Role) breakdown renders only when **≥ `privacy_k_threshold`**\n  (default **3**) contributors share that Role; otherwise those contributors collapse into a single\n  combined bar. Small homogeneous teams usually render one combined bar — that's correct.\n- **Attributes:** only the directory **Role** a post carries. **Never** names, country, file names,\n  prompts, or JTBD prose. The parser doesn't read them and the dashboard can't show them.\n- **The email body is aggregate-only too** — same rules; no member is ever named or singled out.\n- The whole artifact is **team-safe \u002F shareable** — it exposes totals and the generic shape of work,\n  never who did what.\n\n## Cross-skill contract (keep in sync)\nThis skill can only aggregate what **`cowork-dashboard-member`** posts. These must match its copies or\naggregation breaks — **change them in both bundles together**:\n\n| Item | This skill | Must match |\n|---|---|---|\n| Business-process **grouping** | `scripts\u002Fprocess_groups.json` | `cowork-dashboard-member\u002Fscripts\u002Fprocess_groups.json` (and `cowork-roi-report`'s copy) — **byte-for-byte** |\n| **Skills** vocabulary | `scripts\u002Fskills_vocabulary.json` | `cowork-dashboard-member\u002Fscripts\u002Fskills_vocabulary.json` (and `cowork-roi-report`'s) — **byte-for-byte** |\n| **Roles** taxonomy | `scripts\u002Froles_taxonomy.json` | `cowork-dashboard-member\u002Fscripts\u002Froles_taxonomy.json` — **byte-for-byte** |\n| **Value pillars** | `references\u002Fvalue-pillars.md` | `cowork-dashboard-member\u002Freferences\u002Fvalue-pillars.md` — **byte-for-byte** |\n| **Role** attribute + no country\u002Fnames | reads the post header `Role:` line | `cowork-dashboard-member\u002Fscripts\u002Fformat_member_message.py` (emits `Role:`; excludes country\u002Fnames) |\n| Deliverable → process link + **by-type** rollup | parser reads the \"By type\" deliverables table | `format_member_message.py` (that rollup \"is also what the aggregated Dashboard reads\") |\n| The **shared channel** | `channel_id` resolved from the link the user pastes | the channel `cowork-dashboard-member` posts to (its SKILL.md → *Target channel*) — must be the same channel |\n\n- `scripts\u002Fskill_aliases.json` is a **reader-only** compatibility shim (maps older non-canonical skill\n  labels → the vocabulary). It is **not** part of the shared contract and lives only here.\n- **Deliverable NAMES:** the Member skill **strips file names by design** (emits\n  Type\u002FDate\u002FProcess\u002FSkills\u002FHours\u002FValue — no names). To show doc names, the Member skill must first add\n  an opt-in name manifest; only then can this reader surface a manager-only named list. That is a\n  **Member-skill change** — flag it before promising named deliverables.\n\n## Guardrails\n- **No fabricated data.** Every number traces to a post via the pipeline. Empty sections are omitted;\n  an empty 15-day window yields no dashboard, not a made-up one.\n- **No hand math.** `parse_posts.py` totals; `build_dashboard.py` prices at the live rate; the email\n  figures are read from `team_data.json`.\n- **Self-contained output.** The HTML embeds all CSS\u002FJS\u002Fdata — no external assets.\n- **Latest post wins, within the window.** The reader keeps only the last 15 days, then the most\n  recent post per sender; re-running a member's post replaces their earlier contribution.\n- **Channel is user-owned.** Read the channel resolved from the user's link; re-ask only if they name\n  a different one. Never guess or construct a `channel_id`.\n- **Email stays inside the channel.** Recipients are the channel members only; the body is\n  aggregate-only. Interactive sends go through the approval dialog; honor \"don't email\" \u002F `email_on_run:false`.\n\n## Bundled files\n- `SKILL.md`, `README.md`, `CHANGELOG.md`\n- `config\u002Fteam_config.json` — rate + k-threshold + cadence + 15-day lookback + email toggle; the\n  channel IDs are filled in on first run (not shipped hard-coded).\n- `scripts\u002Fresolve_channel.py` — parse a pasted Teams channel\u002Fmessage link → `team_id` + `channel_id`; persist to config (stdlib only).\n- `scripts\u002Fparse_posts.py` — channel posts → anonymized `team_data.json` (stdlib only; 15-day window, latest-per-sender, groups processes, canonicalizes skills, k-anon-ready).\n- `scripts\u002Fbuild_dashboard.py` — `team_data.json` → self-contained HTML dashboard (stdlib only).\n- `scripts\u002Fbuild_guide_pdf.py` — one-page landscape interpretation PDF (uses `reportlab`, bundled in Cowork).\n- `scripts\u002Fbuild_outputs.py` — one step that builds BOTH the dashboard and the PDF guide (single approval; drives the two builders above).\n- `scripts\u002Fprocess_groups.json`, `scripts\u002Fskills_vocabulary.json`, `scripts\u002Froles_taxonomy.json` — **mirrors** of the Member bundle (shared contract).\n- `scripts\u002Fskill_aliases.json` — reader-only skill-label compatibility shim.\n- `references\u002Fvalue-pillars.md` — **mirror** of the four-pillar crosswalk.\n- `examples\u002Fsample_raw_messages.json` — two real, de-identified posts for an offline end-to-end test.\n","# Cowork Dashboard — Team Dashboard (manager rollup)\n\nAggregates the **de-identified Cowork Dashboard posts** teammates publish (via the **Copilot ROI\nMember** skill, `cowork-dashboard-member`) to a shared Teams channel, renders a single self-contained,\n**anonymized** HTML dashboard, and **emails the channel members** a high-level summary with the\ndashboard and a one-page interpretation guide (PDF) attached.\n\n**This skill only reads what the Member skill posts.** It never harvests anyone's OneDrive and\nnever sees names, files, or prompts. If a label (business process, skill, Role) doesn't match the\nMember bundle's copy, aggregation drifts — the taxonomy files here are **byte-for-byte mirrors** of\nthe Member skill's (see *Cross-skill contract*).\n\n## Scope (v1)\n- **Small, homogeneous teams** (people doing similar work), **team level**. A handful of\n  contributors sharing one channel.\n- **Not** org-wide \u002F large-team \u002F multi-channel aggregation, and **not** cross-team benchmarking.\n\n## When NOT to Use\n- **A single person's full impact report** → `cowork-roi-report` (rich personal web app).\n- **Posting your own de-identified stats** to the channel → `cowork-dashboard-member`.\n- **The member-side anonymized table post** → `cowork-roi-report-aggregated`.\n- **Org-wide \u002F multi-team \u002F cross-channel aggregation** — out of scope for v1; don't force it.\n- **GitHub Copilot \u002F IDE usage reports**, **daily briefings**, or **single-meeting summaries** —\n  different skills entirely.\n- If the shared channel has **no Cowork Dashboard posts in the last 15 days**, don't fabricate a dashboard —\n  say the window was empty and offer to widen it.\n\n## First run — point the skill at the channel (once)\n\nThe rollup reads ONE shared Teams channel that teammates post to. The channel is **not hard-coded**.\n\n1. **Load `config\u002Fteam_config.json`.** If `team_id` **or** `channel_id` is blank, this is a first run.\n2. **Ask for the channel link.** Use `AskUserQuestion` to ask the user to paste the **link of the\n   Teams channel** where the team posts its Cowork Dashboard stats (in Teams: channel ⋯ → *Get link to\n   channel*). This must be the same channel `cowork-dashboard-member` posts to.\n3. **Resolve + persist the IDs** from that link — no Graph call needed:\n   ```\n   python scripts\u002Fresolve_channel.py --link \"\u003Cpasted url>\" --config config\u002Fteam_config.json\n   ```\n   It extracts `channel_id` (the `19:…@thread.…` segment) and `team_id` (the `groupId`), writes them\n   plus `channel_link` back to the config, and every later run reads the same place. Optionally call\n   `GetTeam(team_id)` and save its `displayName` as `team_name` so the dashboard header is named.\n4. **The Team must already exist** and the runner must be a **member** of it\n   (`ChannelMessage.Read.All`). This skill does not create Teams or channels. If a read fails with an\n   authorization error, the runner isn't a member — add them in Teams; the skill can't grant access.\n\nOn later runs `team_id` + `channel_id` are already set, so skip straight to the workflow. Re-ask for a\nlink only if the user wants to point at a **different** channel.\n\n## Workflow\n\n### 1. Load config (+ first-run channel link)\nRead `config\u002Fteam_config.json`. If `team_id`\u002F`channel_id` are blank, run **First run** above.\n\n### 2. Read the channel posts (latest 15 days)\n`ListChannelMessages(team_id, channel_id, top=50)` (paginate with `next_link` if the team is chatty).\nSave the returned `value` array verbatim to `working\u002Fraw_messages.json` (the parser accepts the Graph\nmessage shape directly). The **latest-15-days window** and **latest-post-per-person** dedupe are\napplied in step 3 — don't hand-filter here.\n\n### 3. Parse + aggregate (window, anonymize, group, canonicalize)\n```\npython scripts\u002Fparse_posts.py --in working\u002Fraw_messages.json --config config\u002Fteam_config.json \\\n       --out working\u002Fteam_data.json --window-days 15 [--now YYYY-MM-DD] [--generated YYYY-MM-DD]\n```\n`parse_posts.py`:\n- keeps only posts from the **last 15 days** (`--window-days`, anchored to `--now`\u002Ftoday), then keeps\n  the **latest post per sender** (id hashed away, never stored\u002Fshown), numbering contributors 1..N;\n- reads each post's parser-stable tables by header signature (tolerant of metric wording drift);\n- pulls the **Role** line if present (the only attribute — no names, no country, no files);\n- **groups business processes** (`process_groups.json`) and **canonicalizes skills**\n  (`skills_vocabulary.json` + `skill_aliases.json`);\n- writes `working\u002Fteam_data.json` (meta + one snapshot + members[] with role|null + metrics).\n\n### 4. Build both outputs — dashboard + one-page guide (a single approval)\n```\npython scripts\u002Fbuild_outputs.py --in working\u002Fteam_data.json --config config\u002Fteam_config.json\n```\nOne invocation renders BOTH deliverables, so the manager approves the build **once, not twice**:\n- **`output\u002Fcowork-team-roi-dashboard.html`** — self-contained HTML (no external assets). Five small\n  tabs: **Overview** (auto-insights + KPI band) · **Impact & Value** (pillars, categories with $,\n  roles, deliverables by format) · **How Cowork is used** (business-process accordion — each process\n  expands to its **distinct deliverables** with the file format inline + the skills behind them —\n  category mix, analyzed → produced) · **Trends** (minimal fortnight-over-fortnight line) ·\n  **Glossary & method**. Value = hours × rate, recomputed live by a rate control.\n- **`output\u002Fhow-to-read-team-roi-dashboard.pdf`** — a single **landscape** interpretation guide\n  explaining every KPI, the five tabs, the two controls, the privacy model, and the methodology, so\n  recipients can read the dashboard unaided (uses `reportlab`, bundled in the Cowork container).\n\n`build_outputs.py` just drives the two builders in sequence; `build_dashboard.py` and\n`build_guide_pdf.py` still run individually if you ever need only one.\n\n### 5. Email the channel members (summary + both attachments) — a separate, expected approval\nThe email send is deliberately **not** bundled into step 4: building the files is one approval, and\nsending them to people is a second, distinct approval. If `email_on_run` is true (default) and the\nuser hasn't said \"don't send\":\n- **Recipients = the channel members.** `ListChannelMembers(team_id, channel_id)` → resolve each to an\n  email\u002FUPN; de-duplicate; include the runner. (A standard channel returns the team members — that's\n  the intended audience.) Never add anyone outside the channel.\n- **Body = a high-level HTML summary** (aggregate only, same privacy rules as the dashboard). Pull the\n  figures from `working\u002Fteam_data.json` — sum the members' headline metrics (time saved, value =\n  hours × rate, sessions, run tasks, deliverables) and name the top 1–2 business processes. Do **not**\n  hand-invent numbers; if a figure isn't in the data, omit it.\n- **Send** with both attachments:\n  ```\n  SendEmailWithAttachments(\n    to=\u003Cresolved channel-member emails>,\n    subject=\"Team Cowork Dashboard — latest rollup (\u003Cperiod>)\",\n    content_type=\"HTML\", body=\u003Csummary html>,\n    direct_attachment_file_paths=[\"output\u002Fcowork-team-roi-dashboard.html\",\n                                  \"output\u002Fhow-to-read-team-roi-dashboard.pdf\"])\n  ```\n  In interactive runs the platform's approval dialog is the confirmation; scheduled runs send\n  automatically. The \"Powered by Copilot Cowork\" footer is appended by the host — don't add your own.\n\n### 6. Verify + deliver\n`Glob output\u002Fcowork-team-roi-dashboard.html` and `Glob output\u002Fhow-to-read-team-roi-dashboard.pdf` to\nconfirm both exist, then tell the user they're saved and the email went to the channel members.\nOptionally show a 3-line highlight (time saved, value, top process) — aggregate only.\n\n### 7. (Optional) automate — run 1–2 days after the member fortnight\nIf the user asks, `SetupScheduledPrompt` with a self-contained description: *\"Read the last 15 days of\nCowork Dashboard posts in the team channel, aggregate them into the anonymized team dashboard and one-page\nPDF guide, save them to my files, and email them to the channel members.\"*\n\n**Timing:** the Member skill posts on a **biweekly Monday** cycle, so schedule the manager rollup to\nrun **1–2 days later — on Wednesday** — which gives teammates Monday and Tuesday to post before the\nrollup reads the channel. Use frequency **Week**, `interval = cadence_days \u002F 7` (= **2** → every other\nWednesday), `weekDays=[\"Wednesday\"]`, `hours=[\"9\"]`, name \"Cowork Dashboard team dashboard\". Scheduled runs\nbuild both outputs and email the channel members automatically (no interactive approval).\n\n## Privacy (hard rules)\n- **Never show anything at an individual level.** Members are counts + a number only.\n- **k-anonymity:** a per-attribute (Role) breakdown renders only when **≥ `privacy_k_threshold`**\n  (default **3**) contributors share that Role; otherwise those contributors collapse into a single\n  combined bar. Small homogeneous teams usually render one combined bar — that's correct.\n- **Attributes:** only the directory **Role** a post carries. **Never** names, country, file names,\n  prompts, or JTBD prose. The parser doesn't read them and the dashboard can't show them.\n- **The email body is aggregate-only too** — same rules; no member is ever named or singled out.\n- The whole artifact is **team-safe \u002F shareable** — it exposes totals and the generic shape of work,\n  never who did what.\n\n## Cross-skill contract (keep in sync)\nThis skill can only aggregate what **`cowork-dashboard-member`** posts. These must match its copies or\naggregation breaks — **change them in both bundles together**:\n\n| Item | This skill | Must match |\n|---|---|---|\n| Business-process **grouping** | `scripts\u002Fprocess_groups.json` | `cowork-dashboard-member\u002Fscripts\u002Fprocess_groups.json` (and `cowork-roi-report`'s copy) — **byte-for-byte** |\n| **Skills** vocabulary | `scripts\u002Fskills_vocabulary.json` | `cowork-dashboard-member\u002Fscripts\u002Fskills_vocabulary.json` (and `cowork-roi-report`'s) — **byte-for-byte** |\n| **Roles** taxonomy | `scripts\u002Froles_taxonomy.json` | `cowork-dashboard-member\u002Fscripts\u002Froles_taxonomy.json` — **byte-for-byte** |\n| **Value pillars** | `references\u002Fvalue-pillars.md` | `cowork-dashboard-member\u002Freferences\u002Fvalue-pillars.md` — **byte-for-byte** |\n| **Role** attribute + no country\u002Fnames | reads the post header `Role:` line | `cowork-dashboard-member\u002Fscripts\u002Fformat_member_message.py` (emits `Role:`; excludes country\u002Fnames) |\n| Deliverable → process link + **by-type** rollup | parser reads the \"By type\" deliverables table | `format_member_message.py` (that rollup \"is also what the aggregated Dashboard reads\") |\n| The **shared channel** | `channel_id` resolved from the link the user pastes | the channel `cowork-dashboard-member` posts to (its SKILL.md → *Target channel*) — must be the same channel |\n\n- `scripts\u002Fskill_aliases.json` is a **reader-only** compatibility shim (maps older non-canonical skill\n  labels → the vocabulary). It is **not** part of the shared contract and lives only here.\n- **Deliverable NAMES:** the Member skill **strips file names by design** (emits\n  Type\u002FDate\u002FProcess\u002FSkills\u002FHours\u002FValue — no names). To show doc names, the Member skill must first add\n  an opt-in name manifest; only then can this reader surface a manager-only named list. That is a\n  **Member-skill change** — flag it before promising named deliverables.\n\n## Guardrails\n- **No fabricated data.** Every number traces to a post via the pipeline. Empty sections are omitted;\n  an empty 15-day window yields no dashboard, not a made-up one.\n- **No hand math.** `parse_posts.py` totals; `build_dashboard.py` prices at the live rate; the email\n  figures are read from `team_data.json`.\n- **Self-contained output.** The HTML embeds all CSS\u002FJS\u002Fdata — no external assets.\n- **Latest post wins, within the window.** The reader keeps only the last 15 days, then the most\n  recent post per sender; re-running a member's post replaces their earlier contribution.\n- **Channel is user-owned.** Read the channel resolved from the user's link; re-ask only if they name\n  a different one. Never guess or construct a `channel_id`.\n- **Email stays inside the channel.** Recipients are the channel members only; the body is\n  aggregate-only. Interactive sends go through the approval dialog; honor \"don't email\" \u002F `email_on_run:false`.\n\n## Bundled files\n- `SKILL.md`, `README.md`, `CHANGELOG.md`\n- `config\u002Fteam_config.json` — rate + k-threshold + cadence + 15-day lookback + email toggle; the\n  channel IDs are filled in on first run (not shipped hard-coded).\n- `scripts\u002Fresolve_channel.py` — parse a pasted Teams channel\u002Fmessage link → `team_id` + `channel_id`; persist to config (stdlib only).\n- `scripts\u002Fparse_posts.py` — channel posts → anonymized `team_data.json` (stdlib only; 15-day window, latest-per-sender, groups processes, canonicalizes skills, k-anon-ready).\n- `scripts\u002Fbuild_dashboard.py` — `team_data.json` → self-contained HTML dashboard (stdlib only).\n- `scripts\u002Fbuild_guide_pdf.py` — one-page landscape interpretation PDF (uses `reportlab`, bundled in Cowork).\n- `scripts\u002Fbuild_outputs.py` — one step that builds BOTH the dashboard and the PDF guide (single approval; drives the two builders above).\n- `scripts\u002Fprocess_groups.json`, `scripts\u002Fskills_vocabulary.json`, `scripts\u002Froles_taxonomy.json` — **mirrors** of the Member bundle (shared contract).\n- `scripts\u002Fskill_aliases.json` — reader-only skill-label compatibility shim.\n- `references\u002Fvalue-pillars.md` — **mirror** of the four-pillar crosswalk.\n- `examples\u002Fsample_raw_messages.json` — two real, de-identified posts for an offline end-to-end test.\n",{"name":5,"cowork":52,"description":55},{"icon":53,"category":54},"BarChart4","analysis","Manager-side team rollup for Copilot Cowork ROI. Aggregates the de-identified stats teammates post (via the Cowork Dashboard Member skill) to a shared Teams channel into ONE anonymized HTML dashboard (five tabs), then emails the channel members a summary with the dashboard and a one-page PDF guide attached. First run asks for the Teams channel link and remembers it; each run reads the latest 15 days and keeps the latest post per person. Numbers only — no names or files; a Role breaks out only when 3+ share it. Small homogeneous teams; not org-wide.\nUse when the user asks to \"build the team Cowork Dashboard\", \"aggregate my team's Cowork stats\", \"roll up the channel posts\", \"manager Cowork Dashboard report\", \"email the team dashboard\", or set up \u002F refresh the rollup.\nDo NOT use for: the personal report (cowork-roi-report), a member's own post (cowork-dashboard-member), the member-side aggregated post (cowork-roi-report-aggregated), org-wide\u002Flarge-team aggregation, GitHub Copilot reports, or single-meeting summaries.\n","main","70f8cc6bed1f0710886586713c41b7154295c68c","archived\u002Fcowork-dashboard-team-dashboard-v1.3.0",6,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FCoworkDashboard","https:\u002F\u002Faka.ms\u002FCoworkDashboard","https:\u002F\u002Fgithub.com\u002Fmicrosoft","https:\u002F\u002Fopensource.microsoft.com","Open source projects and samples from Microsoft","2026-11-06 06:38:19",{"source":8,"skillName":5,"commands":67,"prompt":77,"zipAvailable":78},[68,71,74],{"tool":69,"command":70},"npx","npx skills add microsoft\u002FCoworkDashboard --skill cowork-dashboard-team-dashboard",{"tool":72,"command":73},"bunx","bunx skills add microsoft\u002FCoworkDashboard --skill cowork-dashboard-team-dashboard",{"tool":75,"command":76},"pnpm","pnpm dlx skills add microsoft\u002FCoworkDashboard --skill cowork-dashboard-team-dashboard","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FCoworkDashboard\u002Fblob\u002Fmain\u002Farchived\u002Fcowork-dashboard-team-dashboard-v1.3.0\u002FSKILL.md",true,[80,86,90,94,98,102,108,112,116,120,124,128,132,136],{"path":81,"resourceType":82,"resourceTypeDesc":83,"sizeBytes":84,"sourceHtmlUrl":85},"CHANGELOG.md","REFERENCE","参考文档",10810,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FCoworkDashboard\u002Fblob\u002Fmain\u002Farchived\u002Fcowork-dashboard-team-dashboard-v1.3.0\u002FCHANGELOG.md",{"path":87,"resourceType":82,"resourceTypeDesc":83,"sizeBytes":88,"sourceHtmlUrl":89},"config\u002Fteam_config.json",1988,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FCoworkDashboard\u002Fblob\u002Fmain\u002Farchived\u002Fcowork-dashboard-team-dashboard-v1.3.0\u002Fconfig\u002Fteam_config.json",{"path":91,"resourceType":82,"resourceTypeDesc":83,"sizeBytes":92,"sourceHtmlUrl":93},"examples\u002Fsample_raw_messages.json",20015,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FCoworkDashboard\u002Fblob\u002Fmain\u002Farchived\u002Fcowork-dashboard-team-dashboard-v1.3.0\u002Fexamples\u002Fsample_raw_messages.json",{"path":95,"resourceType":82,"resourceTypeDesc":83,"sizeBytes":96,"sourceHtmlUrl":97},"README.md",7589,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FCoworkDashboard\u002Fblob\u002Fmain\u002Farchived\u002Fcowork-dashboard-team-dashboard-v1.3.0\u002FREADME.md",{"path":99,"resourceType":82,"resourceTypeDesc":83,"sizeBytes":100,"sourceHtmlUrl":101},"references\u002Fvalue-pillars.md",3487,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FCoworkDashboard\u002Fblob\u002Fmain\u002Farchived\u002Fcowork-dashboard-team-dashboard-v1.3.0\u002Freferences\u002Fvalue-pillars.md",{"path":103,"resourceType":104,"resourceTypeDesc":105,"sizeBytes":106,"sourceHtmlUrl":107},"scripts\u002Fbuild_dashboard.py","SCRIPT","脚本",39722,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FCoworkDashboard\u002Fblob\u002Fmain\u002Farchived\u002Fcowork-dashboard-team-dashboard-v1.3.0\u002Fscripts\u002Fbuild_dashboard.py",{"path":109,"resourceType":104,"resourceTypeDesc":105,"sizeBytes":110,"sourceHtmlUrl":111},"scripts\u002Fbuild_guide_pdf.py",9179,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FCoworkDashboard\u002Fblob\u002Fmain\u002Farchived\u002Fcowork-dashboard-team-dashboard-v1.3.0\u002Fscripts\u002Fbuild_guide_pdf.py",{"path":113,"resourceType":104,"resourceTypeDesc":105,"sizeBytes":114,"sourceHtmlUrl":115},"scripts\u002Fbuild_outputs.py",2139,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FCoworkDashboard\u002Fblob\u002Fmain\u002Farchived\u002Fcowork-dashboard-team-dashboard-v1.3.0\u002Fscripts\u002Fbuild_outputs.py",{"path":117,"resourceType":104,"resourceTypeDesc":105,"sizeBytes":118,"sourceHtmlUrl":119},"scripts\u002Fparse_posts.py",21104,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FCoworkDashboard\u002Fblob\u002Fmain\u002Farchived\u002Fcowork-dashboard-team-dashboard-v1.3.0\u002Fscripts\u002Fparse_posts.py",{"path":121,"resourceType":104,"resourceTypeDesc":105,"sizeBytes":122,"sourceHtmlUrl":123},"scripts\u002Fprocess_groups.json",4392,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FCoworkDashboard\u002Fblob\u002Fmain\u002Farchived\u002Fcowork-dashboard-team-dashboard-v1.3.0\u002Fscripts\u002Fprocess_groups.json",{"path":125,"resourceType":104,"resourceTypeDesc":105,"sizeBytes":126,"sourceHtmlUrl":127},"scripts\u002Fresolve_channel.py",4155,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FCoworkDashboard\u002Fblob\u002Fmain\u002Farchived\u002Fcowork-dashboard-team-dashboard-v1.3.0\u002Fscripts\u002Fresolve_channel.py",{"path":129,"resourceType":104,"resourceTypeDesc":105,"sizeBytes":130,"sourceHtmlUrl":131},"scripts\u002Froles_taxonomy.json",2354,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FCoworkDashboard\u002Fblob\u002Fmain\u002Farchived\u002Fcowork-dashboard-team-dashboard-v1.3.0\u002Fscripts\u002Froles_taxonomy.json",{"path":133,"resourceType":104,"resourceTypeDesc":105,"sizeBytes":134,"sourceHtmlUrl":135},"scripts\u002Fskill_aliases.json",2254,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FCoworkDashboard\u002Fblob\u002Fmain\u002Farchived\u002Fcowork-dashboard-team-dashboard-v1.3.0\u002Fscripts\u002Fskill_aliases.json",{"path":137,"resourceType":104,"resourceTypeDesc":105,"sizeBytes":138,"sourceHtmlUrl":139},"scripts\u002Fskills_vocabulary.json",1502,"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FCoworkDashboard\u002Fblob\u002Fmain\u002Farchived\u002Fcowork-dashboard-team-dashboard-v1.3.0\u002Fscripts\u002Fskills_vocabulary.json",[141,170,190,199],{"skillNo":142,"name":5,"nameZh":6,"description":143,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":144,"categories":145,"keywords":155,"publishedAt":47},"01M69BW6B57C12TNWS39WAPQC1","Interactive HTML team rollup report for Cowork ROI. Download the attachment and open it in a browser; no server needed. Each run reads the latest 15 days and keeps the latest report per person. The public report contains no member records. For small teams, not org-wide.\n\nUse when the user asks to \"build the team Cowork Team Report\", \"aggregate my team's Cowork stats\", \"roll up the channel posts\", \"email the team dashboard\", \"set up the skill\" after installing it, or \"invite my team\" \u002F \"send the member skill to my team\".\n\nDo NOT use for: the personal report (cowork-roi-report), a member's own post (cowork-dashboard-member), the member-side aggregated post (cowork-roi-report-aggregated), org-wide\u002Flarge-team aggregation, GitHub Copilot reports, or single-meeting summaries.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FCoworkDashboard\u002Fblob\u002Fmain\u002Fdocs\u002Fskill-template\u002Fcowork-dashboard-team-dashboard\u002FSKILL.md",[146,149,150,151,152],{"categoryNo":147,"categoryName":148,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000005","邮件与沟通",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":30,"categoryName":31,"taxonomyType":32,"taxonomyTypeDesc":33},{"categoryNo":153,"categoryName":154,"taxonomyType":32,"taxonomyTypeDesc":33},"01JBSEEDCAT000000000000034","行政与办公人员",[156,157,36,35,44,158,159,160,161,162,163,54,164,165,41,166,167,168,169,42],"cowork","team","up","org","my","server","browser","reports","when","open","send","invite","posts","SET",{"skillNo":171,"name":172,"nameZh":6,"description":173,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":174,"categories":175,"keywords":180,"publishedAt":47},"01M69BW1ZMGW3S71AAYD3565NT","cowork-dashboard-member","Member step of the Cowork Team Report: gathers the user's own Cowork sessions, supports exclusions, computes impact metrics, and emails aggregate tables to a configured Teams channel email address. Excludes person names and prompts and replaces raw file names with de-identified descriptive labels; retains customer\u002Faccount names. Supports one-time or biweekly runs with review before sending.\nUse for \"send my Cowork Team Report stats\", \"email my Cowork stats to the team channel\", \"run the Cowork Team Report member step\", or \"share my Cowork impact with the team\".\nDo NOT use for the full personal HTML report (use cowork-roi-report), the manager-side team dashboard, GitHub Copilot reports, or single-meeting summaries.","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FCoworkDashboard\u002Fblob\u002Fmain\u002Fdocs\u002Fskill-template\u002Fcowork-dashboard-member\u002FSKILL.md",[176,177,178,179],{"categoryNo":147,"categoryName":148,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":30,"categoryName":31,"taxonomyType":32,"taxonomyTypeDesc":33},{"categoryNo":153,"categoryName":154,"taxonomyType":32,"taxonomyTypeDesc":33},[156,46,35,181,182,160,183,163,157,184,185,166,186,187,38,44,188,189,41,42],"impact","manager","de","labels","html report","time","review","customer","cowork impact",{"skillNo":191,"name":172,"nameZh":6,"description":173,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":192,"categories":193,"keywords":198,"publishedAt":47},"01M69BVSHK9N8J4DBT35DZNX9H","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FCoworkDashboard\u002Fblob\u002Fmain\u002FCowork Dashboard - Team Member Cowork Skill\u002Fcowork-dashboard-member\u002FSKILL.md",[194,195,196,197],{"categoryNo":147,"categoryName":148,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":30,"categoryName":31,"taxonomyType":32,"taxonomyTypeDesc":33},{"categoryNo":153,"categoryName":154,"taxonomyType":32,"taxonomyTypeDesc":33},[156,46,35,38,42,44,188,189,41,187,163,182,160,183,157,181,184,185,166,186],{"skillNo":200,"name":5,"nameZh":6,"description":143,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":201,"categories":202,"keywords":208,"publishedAt":47},"01M69BVNKT3S7TV88YGJ3AKPS2","https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FCoworkDashboard\u002Fblob\u002Fmain\u002FCowork Dashboard - Team Dashboard Cowork Skill\u002Fcowork-dashboard-team-dashboard\u002FSKILL.md",[203,204,205,206,207],{"categoryNo":147,"categoryName":148,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":30,"categoryName":31,"taxonomyType":32,"taxonomyTypeDesc":33},{"categoryNo":153,"categoryName":154,"taxonomyType":32,"taxonomyTypeDesc":33},[35,157,156,36,44,42,41,159,167,166,160,161,162,163,54,164,165,158,169,168]]