feat(linkedin-studio): RE-R2b — dated morning-brief artifact + session-start surfacing [skip-docs]
The visible layer of R2. Pure brief.ts: rankForBrief (pillar-overlap -> recency over the store; publishedAt ?? capturedAt freshness, 7d window; total-order sort), renderBrief (dated Markdown + hook-surfaceable summary frontmatter), briefSummary (one summary source), defaultBriefDir (derived from defaultStorePath). CLI `brief` writes <data>/trends/morning-brief/YYYY-MM-DD.md; session-start surfaces the latest zero-tsx (latestMorningBrief). Wired into trend-spotter Step 4.6 (scan->capture->brief->surfaced). No store-schema/scoring change; no scheduler (R3). 25 new trends tests (21 brief.test + 4 cli brief, RED-first) + 3 hook tests (morning-brief surfacing). trends 104/104 (floor 104), hook-suite 139/139, gate FAIL=0 (ASSERT floor 94, Section 16i: cli brief-handler + trend-spotter brief-pointer + session-start surfacing greps), tsc clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VmHCQjJHUyWwxGAVVjNLgp
This commit is contained in:
parent
88fbbadb1b
commit
fa7551070e
9 changed files with 712 additions and 10 deletions
|
|
@ -51,6 +51,31 @@ function trendsNewestCapture(storePath) {
|
|||
}
|
||||
}
|
||||
|
||||
// RE-R2b: the most recent morning brief (date + pre-rendered summary) for
|
||||
// session-start surfacing. Reads the dated Markdown directly — NO tsx (same
|
||||
// zero-dep discipline as trendsNewestCapture above): the brief's frontmatter
|
||||
// carries a single-line `summary` the hook surfaces verbatim (extractYaml's
|
||||
// [^"\n]* + .trim() guarantees date/summary are newline-free). Returns null when
|
||||
// the dir is absent / empty / unreadable — no brief yet => no block.
|
||||
function latestMorningBrief(briefDir) {
|
||||
if (!existsSync(briefDir)) return null;
|
||||
try {
|
||||
const files = readdirSync(briefDir)
|
||||
.filter((f) => /^\d{4}-\d{2}-\d{2}\.md$/.test(f))
|
||||
.sort();
|
||||
const name = files[files.length - 1];
|
||||
if (!name) return null;
|
||||
const content = readFileSync(join(briefDir, name), 'utf-8');
|
||||
return {
|
||||
date: extractYaml(content, 'date'),
|
||||
summary: extractYaml(content, 'summary'),
|
||||
file: join(briefDir, name),
|
||||
};
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// SB-S2: brain consolidation freshness. Both read zero-dep through getDataRoot —
|
||||
// the SAME data root the brain CLI's --apply writes to (sidecar reachable by both).
|
||||
// No tsx, no profile.md parse: a readdir count + a tiny JSON read, cost-bounded.
|
||||
|
|
@ -503,6 +528,14 @@ if (brainProfileMissing) {
|
|||
context += '\\n## Brain\\n- Brain not initialised. Run `brain init` to seed your evolving profile.\\n';
|
||||
}
|
||||
|
||||
// RE-R2b: surface the latest dated morning brief (zero-tsx; summary is a
|
||||
// pre-rendered single line from the brief's frontmatter). Unconditional on a brief
|
||||
// existing, like the brain nudge above (so the fresh-install branch surfaces it too).
|
||||
const latestBrief = latestMorningBrief(join(getDataRoot('trends'), 'morning-brief'));
|
||||
if (latestBrief && latestBrief.summary) {
|
||||
context += `\\n## Morning Brief (${latestBrief.date})\\n${latestBrief.summary}\\n→ Full brief: ${latestBrief.file}\\n`;
|
||||
}
|
||||
|
||||
// Read REMEMBER.md for user session context
|
||||
const rememberFile = join(getDataRoot(), 'REMEMBER.md');
|
||||
const rememberTemplate = join(PLUGIN_ROOT, 'config', 'REMEMBER.template.md');
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue