Skip to content

AGENTS.md

100 lines · 3.2 KB · Markdown
Raw

@kody/morning-briefing — agent notes

Human setup and intent live in README.md. This file is for agents: imports, smoke/dryRun execute snippets, and edge cases. Never paste OAuth client secrets. Do not disable or enable live jobs unless the operator explicitly asks — the bundled daily-morning-briefing job stays enabled: false until they save config and approve a dry-run.

Auth

SourceCredential
calendarGoogle OAuth via @kody/google (account, default personal)
weather / healthnone (Open-Meteo public APIs)
inboxGoogle OAuth with gmail.readonly (BYO client)
homecaller-supplied home.items only
email / notify outputkody.emailSend to signed-in account (no API-key secret)

Hosts: www.googleapis.com, gmail.googleapis.com (inbox), Open-Meteo geocoding / forecast / air-quality hosts. No /account/secrets/new for this package.

Import paths

ExportImport
root (build + optional deliver)kody:@kody/morning-briefing
run-morning-briefingkody:@kody/morning-briefing/run-morning-briefing
build-reportkody:@kody/morning-briefing/build-report
get-reportkody:@kody/morning-briefing/get-report

Prefer static kody:@kody/morning-briefing/... imports from execute. Do not lead with packages.invoke.

Smoke test (read-only / no send)

Weather-only (no OAuth):

import buildReport from 'kody:@kody/morning-briefing/build-report'

export default async function main() {
	const report = await buildReport({
		location: 'Austin',
		sources: ['weather'],
	})
	return {
		date: report.date,
		sections: report.sections.map((s) => ({ id: s.id, status: s.status })),
	}
}

Delivery dry-run (does not send):

import runMorningBriefing from 'kody:@kody/morning-briefing/run-morning-briefing'

export default async function main() {
	return await runMorningBriefing({
		dryRun: true,
		location: 'Austin',
		sources: ['weather'],
		output: 'email',
	})
}

Compose preview with optional sources:

import runMorningBriefing from 'kody:@kody/morning-briefing'

export default async function main() {
	return await runMorningBriefing({
		dryRun: true,
		location: 'Denver, CO',
		timezone: 'America/Denver',
		sources: ['calendar', 'weather', 'inbox', 'health', 'home'],
		output: 'email',
		calendar: { accounts: ['personal'] },
		inbox: { account: 'personal', query: 'is:unread newer_than:1d' },
		home: { items: [{ title: 'Thermostat 70°', detail: 'Heat, occupied' }] },
	})
}

Edge cases

  • Missing Google auth becomes a warning/skipped section; do not abort the whole briefing for one bad source.
  • @kody/google listEventsAcrossCalendars stops at its wall-clock budget. A truncated scan becomes a calendar warning so a partial day is not reported as complete.
  • 403 / insufficient-scope must name the missing scope and the connect URL — never fail silently.
  • This official listing does not post to Discord and has no Kent-specific Kit/YouTube/GitHub/Tesla/apartment wiring.
  • Do not enable daily-morning-briefing on the official listing; after a fork, enable only when config is saved and a dry-run looks right.
  • output: 'notify' is short callout-only body; email is the full markdown.