Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ Package metadata lives in [prpm.json](prpm.json). The repo currently publishes `
| [using-agent-relay](skills/using-agent-relay/SKILL.md) | 1.2.0 | Coordinate agents in real time with Relaycast messaging, channels, threads, reactions, search, and webhooks. |
| [running-headless-orchestrator](skills/running-headless-orchestrator/SKILL.md) | 1.0.4 | Self-bootstrap Agent Relay infrastructure and manage worker agents without human intervention. |
| [relay-80-100-workflow](skills/relay-80-100-workflow/SKILL.md) | 1.0.4 | Author workflows that close the 80-to-100 validation gap with repair-aware test, verify, and commit gates. |
| [activity-summary](skills/activity-summary/SKILL.md) | 1.0.0 | Answer "what did I work on yesterday" questions by reading `digests/yesterday.md` first instead of crawling provider directories. |
| [daily-digest](skills/daily-digest/SKILL.md) | 1.0.0 | Authoring contract for `<mount>/digests/` files — windows, per-provider sections, adapter `digest()` exports, regeneration rules. |
| [writeback-as-files](skills/writeback-as-files/SKILL.md) | 1.0.0 | File-creation writeback contract — drop a JSON file at the canonical path and relayfile delivers the mutation, with dead-letter recovery. |
| [workspace-layout](skills/workspace-layout/SKILL.md) | 1.0.0 | Navigate a relayfile mount via `LAYOUT.md`, per-provider `.layout.md`, and `by-*` alias indexes instead of `find`/`grep -r`. |

## Slash Commands

Expand Down
68 changes: 68 additions & 0 deletions prpm.json
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,74 @@
"skills/relay-80-100-workflow/SKILL.md"
]
},
{
"name": "activity-summary",
"version": "1.0.0",
"description": "Use when an agent is asked \"what did I (or my team) work on yesterday / this week / today\" across provider data in a relayfile mount (Linear, GitHub, Notion, Slack, Confluence, Jira, etc.). Tells the agent to consult the pre-computed `digests/yesterday.md` (and sibling digest files) at the workspace root BEFORE doing manual exploration with `ls`/`grep`/`find`. The digest is deterministic, exhaustive over the window, and costs one file read instead of dozens of provider queries.",
"format": "claude",
"subtype": "skill",
"tags": [
"relayfile",
"activity-summary",
"digest",
"agent-context",
"cost-optimization"
],
"files": [
"skills/activity-summary/SKILL.md"
]
},
{
"name": "daily-digest",
"version": "1.0.0",
"description": "Use when authoring or extending the digest set in a relayfile workspace - covers the contract for files under `<mount>/digests/` (`yesterday.md`, `today.md`, `this-week.md`, date-stamped daily files), per-provider section format, link conventions back into the canonical mount tree, when digests are regenerated, and how adapter authors expose new provider data to the digest pipeline.",
"format": "claude",
"subtype": "skill",
"tags": [
"relayfile",
"digest",
"adapter",
"authoring",
"provider-integration"
],
"files": [
"skills/daily-digest/SKILL.md"
]
},
{
"name": "writeback-as-files",
"version": "1.0.0",
"description": "Use when an agent needs to write back to a provider (create a Linear comment, open a GitHub issue, post a Slack message, edit a Notion page, etc.) through a relayfile mount. Covers the file-creation writeback contract (drop a JSON file at the canonical path → provider mutation), discovering the right path and schema via `.schema.json` siblings, idempotency keys, watching writeback status with `relayfile writeback list` and `relayfile status`, and recovering from dead-lettered writes under `.relay/dead-letter/`.",
"format": "claude",
"subtype": "skill",
"tags": [
"relayfile",
"writeback",
"provider-mutation",
"agent-action",
"dead-letter"
],
"files": [
"skills/writeback-as-files/SKILL.md"
]
},
{
"name": "workspace-layout",
"version": "1.0.0",
"description": "Use when an agent is exploring a relayfile mount for the first time or trying to locate a specific resource (Notion page, Linear issue, Slack channel, GitHub PR). Tells the agent to start with `<mount>/LAYOUT.md` and `<provider>/.layout.md` rather than guessing paths from memory, and to use the `by-title/`, `by-id/`, `by-name/`, `by-edited/<date>/`, `by-state/` alias subtrees instead of recursively grepping. Filename convention is `<identifier>__<uuid>`.",
"format": "claude",
"subtype": "skill",
"tags": [
"relayfile",
"workspace",
"navigation",
"indexes",
"agent-context"
],
"files": [
"skills/workspace-layout/SKILL.md"
]
},
{
"name": "create-workflow",
"version": "1.0.0",
Expand Down
96 changes: 96 additions & 0 deletions skills/activity-summary/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
---
name: activity-summary
description: Use when an agent is asked "what did I (or my team) work on yesterday / this week / today" across provider data in a relayfile mount (Linear, GitHub, Notion, Slack, Confluence, Jira, etc.). Tells the agent to consult the pre-computed `digests/yesterday.md` (and sibling digest files) at the workspace root BEFORE doing manual exploration with `ls`/`grep`/`find`. The digest is deterministic, exhaustive over the window, and costs one file read instead of dozens of provider queries.
---

# Activity Summary — Read the Digest First

## Overview

A relayfile workspace pre-computes deterministic daily activity digests at `<mount>/digests/`. These are produced by relayfile itself from the raw provider data, so they are **complete over the time window** (no API pagination gaps) and **free for the agent to consume** (one file read, no LLM generation step).

If you've been asked an activity-summary question, **read the digest before doing anything else.** Reaching for `ls`, `grep`, or per-provider exploration first is the most common reason these answers cost 20+ tool calls when they could cost 1.

## When to use this skill

Trigger phrases from the user — read the digest first:

- "what did I work on yesterday / today / this week"
- "what changed across {GitHub, Linear, Notion, Slack, ...} {yesterday, since Friday, etc.}"
- "summarize my activity"
- "give me a standup update"
- "what did $team_member ship recently"

If the user's question is **not** windowed by time (e.g. "find the Notion page about onboarding"), the digest is not the right entry point — use `by-title/` or `by-id/` indexes instead. See the `workspace-layout` skill.

## What digests look like

```bash
$ ls $MOUNT/digests/
yesterday.md # rolling — generated at 00:00 local for the prior calendar day
today.md # rolling — updated continuously as the day progresses
2026-05-12.md # date-stamped, immutable once the day closes
2026-05-11.md
...
this-week.md # rolling — Mon→now of the current ISO week
last-week.md # immutable, prior ISO week
```

The body is plain Markdown with one section per provider:

```markdown
# Activity for 2026-05-12

## linear
- AGE-16 moved to Blocked (waiting on design) — [/linear/issues/AGE-16__87389837-...]
- AGE-9 closed — [/linear/issues/AGE-9__2bb2c00f-...]

## github
- relayfile-adapters#412 merged to main — [/github/repos/.../pulls/412.json]
- relayfile#287 opened — [/github/repos/.../pulls/287.json]

## notion
- "Khaliq's To Dos" edited — [/notion/pages/3566800c-.../content.md]

## slack
- 7 messages in #gtm-prospects mentioning "ACME"
```

Each bullet links to the canonical file in the mount, so a follow-up question ("what changed about AGE-16?") is one `cat` away.

## How to use it

```bash
# 1. Check the digest covers the date the user asked about.
ls $MOUNT/digests/
cat $MOUNT/digests/yesterday.md

# 2. If the user asked about a specific date, prefer the date-stamped file.
cat $MOUNT/digests/2026-05-12.md

# 3. Confirm coverage before answering. The digest header includes the window
# it spans; if the user's window is wider, read multiple digest files
# rather than re-deriving from raw provider data.
head -5 $MOUNT/digests/this-week.md
```

That is usually the entire workflow: read → quote → done. Four tool calls or fewer.

## When to fall back to exploration

The digest is the right answer when:

- The window matches a digest file (yesterday, today, a specific past date, this/last week).
- The user wants **everything** in the window, not a filtered slice.

Fall back to direct exploration via `by-edited/<date>/` index subtrees when:

- The window is unusual (e.g. "the last 36 hours"). Use `by-edited/` indexes; see `workspace-layout`.
- The user wants a filter the digest doesn't pre-compute (e.g. "only Linear issues assigned to me").
- The digest file is missing or its header indicates incomplete provider coverage.

## Why this matters

In our published benchmarks, the activity-summary question dropped from ~20 turns and $0.30+ to 4 turns and ~$0.07 once the digest existed and the agent read it first. The digest is one file read that replaces ~25 individual provider queries.

If you find yourself listing more than 2-3 directories to answer an activity question, stop and check `digests/` — you're almost certainly working harder than you need to.
104 changes: 104 additions & 0 deletions skills/daily-digest/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
---
name: daily-digest
description: Use when authoring or extending the digest set in a relayfile workspace - covers the contract for files under `<mount>/digests/` (`yesterday.md`, `today.md`, `this-week.md`, date-stamped daily files), the per-provider section format, link conventions back into the canonical mount tree, when digests are regenerated, and how adapter authors expose new provider data to the digest pipeline. NOT for agents answering activity questions — those should use the `activity-summary` skill to consume digests, not produce them.
---

# Daily Digest — Authoring Contract

## Overview

`<mount>/digests/` is a relayfile-managed directory containing deterministic, pre-computed Markdown summaries of provider activity over fixed time windows. Digests are the cheap entry point for activity-summary queries (see the `activity-summary` skill). This skill is for **producers** — adapter authors, provider integrators, and anyone extending what shows up in a digest.

## When to use this skill

- You are writing a new relayfile adapter (Notion, Linear, …) and need to wire it into the digest pipeline.
- You want a new digest window (e.g. `last-30-days.md`) and need to know the contract.
- A digest is missing a provider's content and you need to know why.
- You need to debug why `yesterday.md` was empty or stale this morning.

If you're an agent **reading** the digest to answer a user question, switch to the `activity-summary` skill instead.

## Digest file taxonomy

| File | Window | Mutability |
|---|---|---|
| `today.md` | 00:00 local → now | Updated on every change-event for the current day |
| `yesterday.md` | full prior calendar day | Generated at 00:00 local, immutable for the rest of the day |
| `YYYY-MM-DD.md` | that calendar day | Immutable once the day closes |
| `this-week.md` | Mon 00:00 → now (ISO week) | Updated on every change-event |
| `last-week.md` | full prior ISO week | Immutable |

A digest file is **always present** for each window even if the window contains no activity (the body says `_no activity_`). Agents can detect empty windows without retrying.

## File header

Every digest starts with a frontmatter-style header that callers can verify before trusting the body:

```markdown
# Activity for 2026-05-12

> window: 2026-05-12T00:00:00-07:00 → 2026-05-13T00:00:00-07:00
> generated: 2026-05-13T00:01:14Z
> providers: linear, github, notion, slack
> events: 47
```

- `window` is the half-open interval in the workspace's configured timezone.
- `providers` lists every adapter that contributed (or attempted to). A missing provider here means the adapter never ran, not that it had zero activity.
- `events` is the raw change-event count over the window — useful for sanity-checking against the body.

## Per-provider section format

Each provider gets exactly one `## <provider>` section, in alphabetical order. Bullets within a section are sorted by event time, ascending. Each bullet must:

1. Start with the canonical record identifier the provider uses (`AGE-16`, `#412`, page title, etc.).
2. Describe the change in past tense — "moved to Blocked", "merged to main", "edited".
3. End with a Markdown link to the canonical file path in the mount, in square brackets.

```markdown
## linear
- AGE-16 moved to Blocked (waiting on design) — [/linear/issues/AGE-16__87389837-62b1-4e1a-a237-59218bab2974.json]
- AGE-9 closed — [/linear/issues/AGE-9__2bb2c00f-ee93-4c73-a793-df5b725d9a1a.json]
```

The link target is what makes the digest interactive — a follow-up "tell me more about AGE-16" is one `cat` away from the digest line.

## Adapter contract

For an adapter to contribute to digests it must export a `digest()` function in addition to its sync/writeback handlers:

```typescript
import type { DigestContext, DigestSection } from '@relayfile/adapter-sdk';

export async function digest(ctx: DigestContext): Promise<DigestSection | null> {
const events = await ctx.changeEvents({
window: ctx.window, // { from: ISO8601, to: ISO8601 }
providers: [ctx.provider],
});

if (events.length === 0) return null;

return {
provider: ctx.provider,
bullets: events.map((e) => ({
text: renderBullet(e),
canonicalPath: e.resource.path,
})),
};
}
```

Returning `null` is correct for "ran successfully, no activity"; throwing is reserved for "could not produce a digest" and surfaces as a warning in the digest header.

## Regeneration

- **Rolling windows** (`today.md`, `this-week.md`) are regenerated on every change event for the current window, coalesced to a max of one rebuild per 30 seconds.
- **Closing windows** (`yesterday.md`, `YYYY-MM-DD.md`, `last-week.md`) are produced once at window close (00:00 local for daily, Monday 00:00 for weekly) and never modified afterward. This is what makes them safe to cache and quote verbatim.
- If you need to force a rebuild (e.g. after fixing an adapter bug), `relayfile digest rebuild --window yesterday` re-derives from the change log.

## Common mistakes when adding a new digest

- **Don't inline raw provider payloads.** Bullets are one line. Anything larger belongs in the canonical file the bullet links to.
- **Don't summarize across providers in one section.** Cross-provider correlation is the agent's job; the digest's job is exhaustive per-provider listing.
- **Don't omit the canonical link.** A digest line without a link is dead weight — the agent can't follow up without re-deriving the path.
- **Don't generate non-deterministic content.** Two runs over the same change-event window must produce byte-identical output. LLM-generated prose belongs in the agent, not the digest.
Loading