SuperAPI AI Directory

site-storage-heatmap

Agents & models

View repository

Updated 10-16 03:43

About this skill

Site Storage Heatmap

Generate an interactive HTML site map with storage sizes and hot/cold activity heatmaps for a SharePoint site, then navigate the user to the output.

Steps

1. Get the Current User's First Name

  • Call get_user_info(query="@currentUser") to resolve the current user.
  • Extract the first name from the resolved display name (e.g., "Adam Harmetz" → "Adam").
  • The output filename will be: {FirstName}-Site-Storage-Heatmap.html

2. Discover All Containers

  • Call discover_sharepoint_lists with filterType="all" and includeHidden=false to get every list, library, and page library on the site.
  • Categorize each container:
    • Document Libraries: templateType 101
    • Lists: templateType 100
    • Site Pages: templateType 119
    • Calendar: templateType 106
  • Record each container's id, title, itemCount, and serverRelativeUrl.

3. Collect File-Level Data from Each Non-Empty Library

  • For every document library (templateType 101) with itemCount > 0, call list_items with:
    • viewFields: ["FileLeafRef", "File_x0020_Size", "File_x0020_Type", "Modified"]
    • itemType: "files", recursive: true, rowLimit set to the library's itemCount
  • For Site Pages (templateType 119), also query with viewFields: ["FileLeafRef", "Modified"] to get page modification dates.
  • Parallelize all independent list_items calls.

Large sites (≥ 100 libraries or any library with ≥ 5,000 items)

Naïvely parallelising every list_items call against a large site will hit throttling (HTTP 429) and balloon memory because every file row sits in the model state.

  • Batch the parallel fan-out at no more than ~10 concurrent list_items calls. After each batch, aggregate the results into the running totals via execute_code with outputDataRef: true so the raw rows are released from model state. Never hold all libraries' file rows in memory at once.
  • Per-library paging. If a library reports itemCount > 5,000, fetch it in pages of 5,000 (the SharePoint list view threshold) rather than one giant rowLimit. Aggregate per-page into running totals — do not retain the per-page raw arrays after they are summed.
  • On 429 / throttling: back off, retry the affected library once with a smaller rowLimit, and continue. If retry fails, record the library as Partial data — throttled and surface it explicitly in the HTML output (a yellow badge on that library card) so the consumer knows the totals are an undercount, not zero.
  • Progress reporting. Every 10 libraries processed, post a short progress line (Processed 30 of 142 libraries…) so a multi-minute run doesn't look frozen.
  • Never silently drop a library. Every container from Step 2 must appear in the final HTML output, even if its row is annotated (no data) or (throttled).

4. Aggregate Per-Library Stats

For each library, compute:

  • Total size (sum of File_x0020_Size in bytes)
  • File count
  • File type breakdown: group by File_x0020_Type → { ext: { count, size } }
  • Recency buckets based on Modified date relative to today:
    • Hot: modified ≤ HOT_DAYS ago (default 7)
    • Warm: modified ≤ WARM_DAYS ago (default 30)
    • Cool: modified ≤ COOL_DAYS ago (default 90)
    • Cold: modified > COOL_DAYS ago
  • Track both file count AND storage per recency bucket.

Configurable bucket thresholds

The 7 / 30 / 90 day defaults are conventional but not always right — a fast-moving project site may want 1 / 7 / 30, a records archive may want 30 / 180 / 365.

  • Honour explicit overrides in the user's prompt. Examples that must work:
    • "heatmap with hot=1 day, warm=7, cool=30"
    • "use 30/90/365 buckets"
    • "only consider files older than a year as cold"
  • Validate: HOT_DAYS < WARM_DAYS < COOL_DAYS, all positive integers. If the user gives invalid values, ask once for correction; do not silently re-order.
  • Always render the thresholds used in the HTML output — a small legend line under the heatmap such as Hot ≤ 7d · Warm ≤ 30d · Cool ≤ 90d · Cold > 90d — so the consumer can tell at a glance what "hot" means in this report.

For lists (no file sizes), classify each list as hot/warm/cool/cold based on the list's lastModified date from the discovery response. Count list items per recency bucket.

5. Compute Site-Wide Rollup

Sum across ALL containers (libraries + lists + pages):

  • Grand total items (files + list items + pages)
  • Total storage (libraries only)
  • Aggregate recency: total hot / warm / cool / cold counts
  • Separate recency breakdowns for: Document Libraries, Lists, Site Pages

6. Generate the Interactive HTML

Build a self-contained HTML file with embedded CSS and JavaScript containing:

Root Banner

  • Site name, total item count, container count, page count
  • "Total Library Storage: X" badge

Site-Wide Heatmap Panel (below root, above branches)

  • 3-column grid: one for Document Libraries, one for Lists, one for Site Pages
  • Each column has a stacked horizontal bar (hot=red #E74856, warm=orange #FF8C00, cool=blue #50E6FF, cold=grey #A0AEC0) showing file/item counts per recency tier
  • Below each bar: storage per tier (for libraries) or counts (for lists/pages)
  • Bottom legend row: grand totals per tier across the entire site

3-Column Site Map (below heatmap)

  • Column 1 (wider): Document Libraries — all libraries merged together (including expense libraries), sorted by total size descending. Each leaf card shows: name, size badge, file count badge. Clickable.
  • Column 2: Lists — each list with item count badge. Not clickable.
  • Column 3: Site Pages — each page name. Not clickable.
  • Empty containers grayed out.

Click-Through Modal (JavaScript)

When a library leaf is clicked, show a modal overlay with:

  • Summary cards: File count, Total size, File type count
  • Activity Heatmap: 4 horizontal bars (hot/warm/cool/cold) showing file counts + storage per tier
  • Storage by File Type: horizontal bars per extension showing % of total, file count, and size
  • Close on Escape, click outside, or ✕ button

Styling

  • Use Segoe UI font, #f5f5f5 background
  • Branch headers: blue gradient for doc libs, green for lists, purple for pages
  • Responsive grid that stacks on mobile
  • Hover effects on clickable leaves (translateX + shadow)
  • Modal with backdrop blur

7. Save the HTML File

  • Save as {FirstName}-Site-Storage-Heatmap.html
  • Target location: the site's document library, inside a folder called "storage heatmap"
    • Use create_text_file with relativeFolderPath="storage heatmap"
    • If the folder doesn't exist, create it first with create_folder

8. Navigate the User

  • After saving, call navigate_to_url to take the user to the document library where the file was saved.
  • Provide the direct file URL so the user can open it.
  • Remind the user: "Download and open in your browser for full interactivity — SharePoint strips JavaScript from inline HTML previews."

Example

User: "Generate a storage heatmap for this site"

Result: File saved as Adam-Site-Storage-Heatmap.html in the "storage heatmap" folder, user navigated to the library, with a note to download for JS interactivity.

Constraints

  • Always get the current user's first name — never hardcode.
  • Always get the current date via get_datetime_info before computing recency buckets — never assume today's date.
  • Parallelize list_items calls for all non-empty libraries to minimize latency. For large sites, follow the batching/throttling rules in Step 3 → Large sites — never fan out unbounded.
  • Use execute_code with outputDataRef: true for all large intermediate data so raw rows are released from model state after aggregation.
  • Keep the HTML fully self-contained (no external dependencies).
  • File type colors: use a rotating palette of Fluent-style colors.
  • Recency colors are fixed: hot=#E74856, warm=#FF8C00, cool=#50E6FF, cold=#A0AEC0.
  • Recency thresholds are configurable per run (see Step 4 → Configurable bucket thresholds) but must be rendered in the HTML so the report is self-explanatory.
  • Every container discovered in Step 2 must appear in the final HTML, including throttled or empty ones — never silently drop.