matrix_time_analysis
Analyze time spent across Matrix entries by tracking totals grouped by topic, bug, or time period. Parses time markers from entries to provide insights into work distribution.
Instructions
Analyze time spent across Matrix entries. Tracks total time by topic, bug UID, or week. Parses time markers like [30m], [2h] from entries.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| endDate | No | End date YYYY-MM-DD (optional, defaults to today) | |
| groupBy | No | How to group the analysis | |
| startDate | No | Start date YYYY-MM-DD (optional, defaults to beginning) |
Implementation Reference
- index.js:723-725 (handler)Handler case for the 'matrix_time_analysis' tool call. Delegates execution to the external Google Apps Script API via the callAPI helper function, passing arguments.case "matrix_time_analysis": result = await callAPI("matrixTimeAnalysis", args); break;
- index.js:517-538 (schema)Tool schema definition and registration in the list of tools returned by ListToolsRequestSchema. Includes input schema with optional parameters for date range and grouping.{ name: "matrix_time_analysis", description: "Analyze time spent across Matrix entries. Tracks total time by topic, bug UID, or week. Parses time markers like [30m], [2h] from entries.", inputSchema: { type: "object", properties: { startDate: { type: "string", description: "Start date YYYY-MM-DD (optional, defaults to beginning)" }, endDate: { type: "string", description: "End date YYYY-MM-DD (optional, defaults to today)" }, groupBy: { type: "string", description: "How to group the analysis", enum: ["topic", "bug", "week", "day"] } } } },
- index.js:74-131 (helper)Shared helper function callAPI used by matrix_time_analysis (and other tools) to proxy requests to the Google Apps Script backend at the configured API_URL, handling form-encoded POST requests and logging.async function callAPI(action, data = {}) { debugLog('=== API CALL START ==='); debugLog(`Action: ${action}`); debugLog(`Data: ${JSON.stringify(data)}`); try { // Build form-encoded body for POST const formData = new URLSearchParams(); formData.append('action', action); // Add all data fields to form for (const [key, value] of Object.entries(data)) { if (value !== undefined && value !== null) { formData.append(key, value.toString()); } } const formString = formData.toString(); debugLog(`FormData: ${formString}`); debugLog(`API_URL: ${API_URL}`); // Use POST with proper content type const response = await fetch(API_URL, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: formString }); debugLog(`Response status: ${response.status}`); debugLog(`Response ok: ${response.ok}`); if (!response.ok) { debugLog(`Response not OK: ${response.status} ${response.statusText}`); throw new Error(`API request failed: ${response.status} ${response.statusText}`); } const text = await response.text(); debugLog(`Response text length: ${text.length}`); debugLog(`Response text: ${text}`); if (!text) { debugLog('ERROR: Empty response from API'); throw new Error('Empty response from API'); } const parsed = JSON.parse(text); debugLog(`Parsed successfully: ${JSON.stringify(parsed)}`); debugLog('=== API CALL END ==='); return parsed; } catch (error) { debugLog(`ERROR in callAPI: ${error.message}`); debugLog(`ERROR stack: ${error.stack}`); throw error; } }