Skip to main content

Overview

Utilities for parsing status information from the first 10 lines of a digest page. Used by check-upstream-status to extract the agent’s execution status and run time.

Types

ParsedStatus

interface ParsedStatus {
  status_type: StatusType;
  status_value: StatusValue;
  raw_line: string;
}
Result of parsing a status line from digest content.
status_type
StatusType
required
Type of status: "sync", "snapshot", "report", or "heartbeat"
status_value
StatusValue
required
Outcome: "complete", "partial", "failed", "full_report", or "stub"
raw_line
string
required
The original line that was parsed (e.g., “Sync Status: ✅ Complete”)

Constants

STATUS_PREFIXES

const STATUS_PREFIXES = ["Sync Status:", "Snapshot Status:", "Report Status:"] as const;
Recognized status line prefixes. The parser searches for lines starting with these strings.

EMOJI_MAP

const EMOJI_MAP: Record<string, StatusValue> = {
  "✅": "complete",
  "⚠️": "partial",
  "❌": "failed",
};
Maps status emojis to their corresponding StatusValue.

Functions

parseStatusLine

function parseStatusLine(lines: string[]): ParsedStatus | null
Scans the first 10 lines of digest content for a status line (Sync Status, Snapshot Status, or Report Status) and parses the status type and value from the emoji and text.
lines
string[]
required
Array of lines from digest page content (typically from Notion block plain text)
return
ParsedStatus | null
Parsed status object, or null if no status line was found
Parsing rules:
  • Searches first 10 lines only
  • Matches lines starting with “Sync Status:”, “Snapshot Status:”, or “Report Status:”
  • Status type derived from prefix (Sync → sync, Snapshot → snapshot, Report → report)
  • Status value derived from emoji:
    • ✅ → "complete"
    • ⚠️ → "partial"
    • ❌ → "failed"
    • Text containing “stub” → "stub"
    • Text containing “full” → "full_report"
Example:
import { parseStatusLine } from "./shared/status-parser.js";

const lines = [
  "Email Triage — 2026-03-04",
  "Run Time: 2026-03-04 08:30 (America/Chicago)",
  "Sync Status: ✅ Complete",
  "Scope: Processed 12 emails",
];

const parsed = parseStatusLine(lines);
// {
//   status_type: "sync",
//   status_value: "complete",
//   raw_line: "Sync Status: ✅ Complete"
// }

parseRunTime

function parseRunTime(lines: string[]): string | null
Searches the first 10 lines for a “Run Time:” line and extracts the timestamp string.
lines
string[]
required
Array of lines from digest page content
return
string | null
Run time string (e.g., “2026-03-04 08:30 (America/Chicago)”), or null if not found
Example:
import { parseRunTime } from "./shared/status-parser.js";

const lines = [
  "Email Triage — 2026-03-04",
  "Run Time: 2026-03-04 08:30 (America/Chicago)",
  "Sync Status: ✅ Complete",
];

const runTime = parseRunTime(lines);
// "2026-03-04 08:30 (America/Chicago)"

hasHeartbeatLine

function hasHeartbeatLine(lines: string[]): boolean
Checks if content contains the exact heartbeat string “Heartbeat: no actionable items”.
lines
string[]
required
Array of lines from digest page content
return
boolean
true if heartbeat line is found, false otherwise
Example:
import { hasHeartbeatLine } from "./shared/status-parser.js";

const heartbeatLines = [
  "Email Triage — 2026-03-04",
  "Heartbeat: no actionable items",
];

hasHeartbeatLine(heartbeatLines); // true

buildStatusLine

function buildStatusLine(statusType: StatusType, statusValue: StatusValue): string
Generates a formatted status line string for inclusion in digest page content. Used by write-agent-digest when creating digest pages.
statusType
StatusType
required
Type of status: "sync", "snapshot", "report", or "heartbeat"
statusValue
StatusValue
required
Outcome: "complete", "partial", "failed", "full_report", or "stub"
return
string
Formatted status line (e.g., “Sync Status: ✅ Complete”)
Formatting rules:
  • Heartbeat always returns “Sync Status: ✅ Complete”
  • Emoji selection:
    • ✅ for complete or full_report
    • ⚠️ for partial or stub
    • ❌ for failed
  • Label based on status type:
    • sync → “Sync Status”
    • snapshot → “Snapshot Status”
    • report → “Report Status”
  • Value text:
    • sync: “Complete”, “Partial”, or “Failed”
    • snapshot: “Complete” or “Partial”
    • report: “Full report”, “Stub”, or “Failed”
Example:
import { buildStatusLine } from "./shared/status-parser.js";

buildStatusLine("sync", "complete");
// "Sync Status: ✅ Complete"

buildStatusLine("sync", "partial");
// "Sync Status: ⚠️ Partial"

buildStatusLine("report", "full_report");
// "Report Status: ✅ Full report"

buildStatusLine("heartbeat", "complete");
// "Sync Status: ✅ Complete"

Usage Example

Complete example of parsing digest content:
import {
  parseStatusLine,
  parseRunTime,
  hasHeartbeatLine,
} from "./shared/status-parser.js";

// Get page content from Notion
const blocks = await notion.blocks.children.list({ block_id: pageId });
const lines = blocks.results
  .map((b) => {
    if ("paragraph" in b && b.paragraph.rich_text.length > 0) {
      return b.paragraph.rich_text[0]?.plain_text ?? "";
    }
    return "";
  })
  .filter((line) => line.trim());

// Parse status
const parsed = parseStatusLine(lines);
if (!parsed) {
  console.log("No status line found");
} else {
  console.log(`Status: ${parsed.status_type} - ${parsed.status_value}`);
}

// Parse run time
const runTime = parseRunTime(lines);
console.log(`Run time: ${runTime}`);

// Check for heartbeat
const isHeartbeat = hasHeartbeatLine(lines);
console.log(`Is heartbeat: ${isHeartbeat}`);

Build docs developers (and LLMs) love