一键导入
morning-brief
Daily financial summary — net worth, recent activity, payment due dates, alerts
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Daily financial summary — net worth, recent activity, payment due dates, alerts
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Manage recurring scheduled tasks — add, list, pause, resume, remove
Build a custom dashboard view from a natural language request — query, API, React component, build, deploy
On-demand financial briefing — spending, balances, portfolio, transactions, reports, CSV export
Override transaction categories via natural language — update rules, reclassify
Guided first-bank setup — credentials, exploration, sync, extraction, import
Discover and build a complete bank integration by answering 9 required questions
| name | morning-brief |
| description | Daily financial summary — net worth, recent activity, payment due dates, alerts |
| trigger | manual |
When the user says "good morning", "daily summary", "morning brief", or "how are my finances" — generate a personalized financial brief.
The brief serves two purposes:
data/brief/latest.json, rendered by the React dashboarddata/foliome.db must exist. If not: "No financial data found. Run /sync first."data/brief/ directory is created automatically if missing.The brief draws from three sources:
Read the agent's financial memory wiki at data/wiki/:
data/wiki/index.md to discover all active pagesdata/wiki/goals/) for savings targets, progress, deadlinesdata/wiki/preferences/) for spending intentionsdata/wiki/concerns/) for balance worries, spending alertsdata/wiki/context/) for life events, pay scheduleIf the wiki is empty (no pages in index), generate a data-only brief — no warning banner needed. An empty wiki just means the agent hasn't captured any context yet.
Use dashboard-queries.js functions via Node.js:
const { getOverview, getTransactions, getSpending, getBudgets } = require('./scripts/dashboard-queries.js');
const overview = getOverview();
const txns = getTransactions(undefined, { from: sevenDaysAgo, limit: 20 });
const spending = getSpending(undefined, { from: monthStart });
const budgets = getBudgets();
Key data points:
overview.netWorth, trend from overview.netWorthTrendoverview.balancesbudgets.categories (spent vs budget per category)overview.alerts (credit cards due soon)overview.syncStatusconfig/budgets.json — monthly budget limits per category (already included in getBudgets())config/payment-schedule.json — credit card due dates (already included in getOverview())Do not guess the day of the week. Compute it programmatically:
const now = new Date();
const greeting = now.toLocaleDateString('en-US', { weekday: 'long', month: 'long', day: 'numeric' });
// e.g. "Saturday, April 11"
Use this computed value for the greeting field. LLMs are unreliable at day-of-week calculations.
{
"netWorth": 142350.00,
"delta": 1230.00,
"deltaPeriod": "since last week",
"sparkline": [138200, 139100, 140500, 141120, 142350],
"summary": "3 transactions yesterday, $47 spent."
}
netWorth: from overview.netWorthdelta: compare to previous brief's headline.netWorth (read data/brief/latest.json before overwriting). If no previous brief, use month-over-month from netWorthTrend.sparkline: last 5 values from netWorthTrendsummary: count recent transactions, total spending. One sentence.Include sections based on available data and memories. Order by relevance:
spent, budget, progress (0-1), pace ("on_track", "above", "over").overview.alerts. Include payments array.Write to data/brief/latest.json atomically:
const fs = require('fs');
const path = require('path');
const briefDir = path.join(__dirname, 'data', 'brief');
fs.mkdirSync(briefDir, { recursive: true });
const brief = { generatedAt, greeting, headline, sections };
// Atomic write: temp file → rename
const tmpPath = path.join(briefDir, '.latest.tmp');
fs.writeFileSync(tmpPath, JSON.stringify(brief, null, 2));
fs.renameSync(tmpPath, path.join(briefDir, 'latest.json'));
Also save a dated copy: data/brief/YYYY-MM-DD.json.
Send a conversational summary to the user (Telegram or CLI). This is shorter than the JSON — just the highlights.
If running as a Telegram agent, also present the dashboard as a Mini App button so the user can tap to see the full Brief tab:
node scripts/telegram-notify.js --dashboard "<chatId>" "Your brief is ready. Tap to see the full view." "<tunnel-url>"
Use the chatId from the inbound Telegram message and the active cloudflared tunnel URL. Do NOT send the dashboard URL as a plain text link — it won't work without Mini App initData.
Conversational summary example:
Good morning. Here's your snapshot for April 7.
Net worth: $142,350 (+$1,230 since last week)
Restaurants at $620, 78% of your $800 budget with 8 days left.
Chase Sapphire due in 4 days — balance: $672.
3 transactions yesterday totaling $47. Nothing unusual.
After querying, check staleness for each institution:
48h old: prominent warning in both the JSON and the message
When the wiki has no pages, the brief is data-only:
{
"generatedAt": "2026-04-07T08:00:00Z",
"greeting": "Monday, April 7",
"headline": {
"netWorth": 142350.00,
"delta": 1230.00,
"deltaPeriod": "since last week",
"sparkline": [138200, 139100, 140500, 141120, 142350],
"summary": "3 transactions yesterday, $47 spent."
},
"sections": [
{
"type": "budget_pulse",
"title": "Restaurants",
"body": "Restaurants at $620, 78% of your $800 budget with 8 days left. Tracking above pace.",
"category": "Restaurants",
"spent": 620,
"budget": 800,
"progress": 0.78,
"pace": "above"
},
{
"type": "recent_activity",
"title": "Since Yesterday",
"body": "3 transactions totaling $47.57. Whole Foods $28.50, Spotify $10.99, parking $8.08."
},
{
"type": "upcoming",
"title": "Coming Up",
"body": "Chase Sapphire due in 4 days. Current balance: $671.99.",
"payments": [
{ "account_id": "chase-sapphire", "account_name": "Chase Sapphire", "balance": -671.99, "days_until": 4 }
]
},
{
"type": "account_health",
"title": "Accounts",
"body": "All 9 institutions synced within the last 24 hours."
}
]
}
When the wiki has goals and preferences:
{
"generatedAt": "2026-04-07T08:00:00Z",
"greeting": "Monday, April 7",
"headline": {
"netWorth": 142350.00,
"delta": 1230.00,
"deltaPeriod": "since last week",
"sparkline": [138200, 139100, 140500, 141120, 142350],
"summary": "Your third week of growth. 3 transactions yesterday."
},
"sections": [
{
"type": "goal_progress",
"title": "House Fund",
"body": "Your Chase savings is at $42,300 — 53% to your $80k target. At this pace, you'll hit it by November 2027.",
"progress": 0.53,
"account": "chase-savings"
},
{
"type": "budget_pulse",
"title": "Restaurants",
"body": "Restaurants at $620, 78% of your $800 budget with 8 days left. You mentioned wanting to cut back — this month is tracking above your usual pace.",
"category": "Restaurants",
"spent": 620,
"budget": 800,
"progress": 0.78,
"pace": "above"
},
{
"type": "recent_activity",
"title": "Since Yesterday",
"body": "3 transactions totaling $47.57. Nothing unusual."
},
{
"type": "upcoming",
"title": "Coming Up",
"body": "Chase Sapphire due in 4 days. Current balance: $671.99.",
"payments": [
{ "account_id": "chase-sapphire", "account_name": "Chase Sapphire", "balance": -671.99, "days_until": 4 }
]
},
{
"type": "concern",
"title": "Credit Card Balance",
"body": "Your Sapphire balance is $1,247 — above the $1,000 comfort level you mentioned."
},
{
"type": "account_health",
"title": "Accounts",
"body": "All institutions synced. Capital One was 26 hours ago — still fresh."
}
]
}
| Type | Required Fields | Optional Fields |
|---|---|---|
goal_progress | title, body | progress (0-1), account |
budget_pulse | title, body | category, spent, budget, progress (0-1), pace |
recent_activity | title, body | transactions[] |
upcoming | title, body | payments[] |
concern | title, body | account |
portfolio | title, body | — |
account_health | title, body | — |
insight | title, body | — |