@aitne-sh/aitne 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +464 -0
- package/agent-assets/agent-profiles/_safety.md +26 -0
- package/agent-assets/agent-profiles/conversational.md +33 -0
- package/agent-assets/agent-profiles/docs-qa.md +24 -0
- package/agent-assets/agent-profiles/observer.md +28 -0
- package/agent-assets/agent-profiles/profile-importer.md +63 -0
- package/agent-assets/agent-profiles/proxy.md +28 -0
- package/agent-assets/agent-profiles/routine.md +16 -0
- package/agent-assets/agent-profiles/task.md +18 -0
- package/agent-assets/docs/concepts/agent-day.md +88 -0
- package/agent-assets/docs/concepts/auth-health.md +75 -0
- package/agent-assets/docs/concepts/backends-and-tiers.md +126 -0
- package/agent-assets/docs/concepts/costs-and-quotas.md +103 -0
- package/agent-assets/docs/concepts/delegated-mode.md +223 -0
- package/agent-assets/docs/concepts/memory-model.md +118 -0
- package/agent-assets/docs/concepts/observations.md +80 -0
- package/agent-assets/docs/concepts/process-keys.md +89 -0
- package/agent-assets/docs/concepts/routines.md +108 -0
- package/agent-assets/docs/concepts/safety-and-execution.md +109 -0
- package/agent-assets/docs/concepts/safety-model.md +279 -0
- package/agent-assets/docs/concepts/skills.md +100 -0
- package/agent-assets/docs/features/integrations/calendar.md +92 -0
- package/agent-assets/docs/features/integrations/git.md +95 -0
- package/agent-assets/docs/features/integrations/github.md +170 -0
- package/agent-assets/docs/features/integrations/mail.md +106 -0
- package/agent-assets/docs/features/integrations/notion.md +69 -0
- package/agent-assets/docs/features/integrations/obsidian.md +71 -0
- package/agent-assets/docs/features/lifestyle/git.md +178 -0
- package/agent-assets/docs/features/lifestyle/reading.md +93 -0
- package/agent-assets/docs/features/lifestyle/receipts.md +71 -0
- package/agent-assets/docs/features/lifestyle/travel-bookings.md +44 -0
- package/agent-assets/docs/features/lifestyle/travel-time.md +52 -0
- package/agent-assets/docs/features/memory-files/agent-journal.md +105 -0
- package/agent-assets/docs/features/memory-files/projects.md +56 -0
- package/agent-assets/docs/features/memory-files/roadmap.md +61 -0
- package/agent-assets/docs/features/memory-files/schedule.md +112 -0
- package/agent-assets/docs/features/memory-files/today.md +73 -0
- package/agent-assets/docs/features/memory-files/user-profile.md +81 -0
- package/agent-assets/docs/features/messaging/dashboard-chat.md +93 -0
- package/agent-assets/docs/features/messaging/discord.md +50 -0
- package/agent-assets/docs/features/messaging/overview.md +111 -0
- package/agent-assets/docs/features/messaging/pairing-and-magic-phrase.md +69 -0
- package/agent-assets/docs/features/messaging/slack.md +51 -0
- package/agent-assets/docs/features/messaging/telegram.md +63 -0
- package/agent-assets/docs/features/messaging/whatsapp.md +48 -0
- package/agent-assets/docs/features/operations/activity-and-conversations.md +105 -0
- package/agent-assets/docs/features/operations/approvals.md +58 -0
- package/agent-assets/docs/features/operations/backend-routing.md +62 -0
- package/agent-assets/docs/features/operations/cost-tracking.md +59 -0
- package/agent-assets/docs/features/operations/notifications.md +69 -0
- package/agent-assets/docs/features/operations/quiet-hours.md +106 -0
- package/agent-assets/docs/features/operations/schedule-approaching.md +60 -0
- package/agent-assets/docs/features/routines/custom-routines.md +101 -0
- package/agent-assets/docs/features/routines/evening-review.md +81 -0
- package/agent-assets/docs/features/routines/hourly-check.md +85 -0
- package/agent-assets/docs/features/routines/monthly-review.md +65 -0
- package/agent-assets/docs/features/routines/morning-routine.md +123 -0
- package/agent-assets/docs/features/routines/weekly-review.md +70 -0
- package/agent-assets/docs/getting-started/01-what-is-this.md +192 -0
- package/agent-assets/docs/getting-started/02-first-steps.md +80 -0
- package/agent-assets/docs/getting-started/03-what-can-this-do.md +110 -0
- package/agent-assets/docs/getting-started/04-first-day.md +287 -0
- package/agent-assets/docs/glossary.md +116 -0
- package/agent-assets/docs/guides/add-a-custom-routine.md +71 -0
- package/agent-assets/docs/guides/backup-and-restore.md +54 -0
- package/agent-assets/docs/guides/change-which-model-handles-x.md +47 -0
- package/agent-assets/docs/guides/connect-a-new-mail-account.md +59 -0
- package/agent-assets/docs/guides/import-knowledge-file.md +275 -0
- package/agent-assets/docs/guides/install-and-run.md +72 -0
- package/agent-assets/docs/guides/migrate-machines.md +52 -0
- package/agent-assets/docs/guides/pause-the-agent.md +65 -0
- package/agent-assets/docs/guides/reinstall-cleanly.md +52 -0
- package/agent-assets/docs/guides/setup-wizard.md +107 -0
- package/agent-assets/docs/guides/switch-default-backend.md +60 -0
- package/agent-assets/docs/reference/api.md +51 -0
- package/agent-assets/docs/reference/cli-commands.md +121 -0
- package/agent-assets/docs/reference/config.md +74 -0
- package/agent-assets/docs/reference/disallowed-tools.md +76 -0
- package/agent-assets/docs/reference/keyboard-shortcuts.md +39 -0
- package/agent-assets/docs/reference/process-keys.md +59 -0
- package/agent-assets/docs/reference/skills.md +50 -0
- package/agent-assets/docs/troubleshooting/auth-failed.md +57 -0
- package/agent-assets/docs/troubleshooting/dashboard-shows-degraded.md +55 -0
- package/agent-assets/docs/troubleshooting/fallback-keeps-firing.md +54 -0
- package/agent-assets/docs/troubleshooting/messaging-not-pairing.md +53 -0
- package/agent-assets/docs/troubleshooting/morning-routine-didnt-run.md +75 -0
- package/agent-assets/docs/troubleshooting/observation-not-detected.md +57 -0
- package/agent-assets/docs/troubleshooting/quota-exhausted.md +57 -0
- package/agent-assets/optimizer-skills/drift-analysis/SKILL.md +75 -0
- package/agent-assets/optimizer-skills/knowledge-map/SKILL.md +71 -0
- package/agent-assets/optimizer-skills/skill-curation/SKILL.md +108 -0
- package/agent-assets/project-doc-templates/git-repo.md +21 -0
- package/agent-assets/project-doc-templates/project.md +38 -0
- package/agent-assets/skills/attach/SKILL.md +104 -0
- package/agent-assets/skills/context/SKILL.md +257 -0
- package/agent-assets/skills/context/curation.json +37 -0
- package/agent-assets/skills/context/seeds/file-responsibilities.seed.json +13 -0
- package/agent-assets/skills/context/seeds/frontmatter-requirements.seed.json +40 -0
- package/agent-assets/skills/docs-search/SKILL.md +176 -0
- package/agent-assets/skills/external-services/SKILL.delegated.claude.md +369 -0
- package/agent-assets/skills/external-services/SKILL.delegated.codex.md +349 -0
- package/agent-assets/skills/external-services/SKILL.delegated.gemini.md +347 -0
- package/agent-assets/skills/external-services/SKILL.md +371 -0
- package/agent-assets/skills/mail/SKILL.delegated.claude.md +284 -0
- package/agent-assets/skills/mail/SKILL.delegated.codex.md +261 -0
- package/agent-assets/skills/mail/SKILL.delegated.gemini.md +255 -0
- package/agent-assets/skills/mail/SKILL.md +313 -0
- package/agent-assets/skills/mail/references/errors.md +17 -0
- package/agent-assets/skills/mail/references/providers.md +40 -0
- package/agent-assets/skills/mail/references/query-grammar.md +24 -0
- package/agent-assets/skills/management-policy/SKILL.md +307 -0
- package/agent-assets/skills/management-policy/curation.json +13 -0
- package/agent-assets/skills/management-policy/seeds/policy-file-shape.seed.json +16 -0
- package/agent-assets/skills/management-task-modify/SKILL.md +202 -0
- package/agent-assets/skills/management-task-register/SKILL.md +330 -0
- package/agent-assets/skills/management-task-stop/SKILL.md +166 -0
- package/agent-assets/skills/notify/SKILL.md +196 -0
- package/agent-assets/skills/notion/SKILL.delegated.claude.md +254 -0
- package/agent-assets/skills/notion/SKILL.delegated.codex.md +195 -0
- package/agent-assets/skills/notion/SKILL.delegated.gemini.md +194 -0
- package/agent-assets/skills/notion/SKILL.md +86 -0
- package/agent-assets/skills/observations/SKILL.md +234 -0
- package/agent-assets/skills/observations/curation.json +13 -0
- package/agent-assets/skills/observations/seeds/source-namespacing.seed.json +20 -0
- package/agent-assets/skills/project-doc/SKILL.md +86 -0
- package/agent-assets/skills/project-doc/curation.json +21 -0
- package/agent-assets/skills/project-doc/seeds/project-shape.seed.json +25 -0
- package/agent-assets/skills/project-doc/seeds/slug-grammar.seed.json +20 -0
- package/agent-assets/skills/reading/SKILL.md +198 -0
- package/agent-assets/skills/reading/references/reading-taste.md +197 -0
- package/agent-assets/skills/receipts/SKILL.md +134 -0
- package/agent-assets/skills/roadmap/SKILL.md +276 -0
- package/agent-assets/skills/roadmap/curation.json +13 -0
- package/agent-assets/skills/roadmap/references/horizon-tags.md +40 -0
- package/agent-assets/skills/roadmap/references/preparation-timeline.md +47 -0
- package/agent-assets/skills/roadmap/seeds/entry-types.seed.json +16 -0
- package/agent-assets/skills/schedule/SKILL.md +228 -0
- package/agent-assets/skills/scheduled-managed-task/SKILL.md +392 -0
- package/agent-assets/skills/today/SKILL.md +198 -0
- package/agent-assets/skills/today/curation.json +21 -0
- package/agent-assets/skills/today/seeds/agent-notes-flavors.seed.json +17 -0
- package/agent-assets/skills/today/seeds/section-shape.seed.json +17 -0
- package/agent-assets/skills/travel/SKILL.md +132 -0
- package/agent-assets/skills/travel-time/SKILL.md +149 -0
- package/agent-assets/skills/user-interview/SKILL.md +323 -0
- package/agent-assets/skills/user-interview/references/sweep-and-fallback.md +94 -0
- package/agent-assets/skills/user-profile/SKILL.md +210 -0
- package/agent-assets/skills/user-profile/curation.json +29 -0
- package/agent-assets/skills/user-profile/seeds/learned-context-format.seed.json +14 -0
- package/agent-assets/skills/user-profile/seeds/routing-table.seed.json +53 -0
- package/agent-assets/skills/user-profile/seeds/topic-files.seed.json +27 -0
- package/agent-assets/task-flows/dashboard.docs_qa.md +43 -0
- package/agent-assets/task-flows/default.md +11 -0
- package/agent-assets/task-flows/git.branch.created.md +25 -0
- package/agent-assets/task-flows/git.lifecycle.poll.md +52 -0
- package/agent-assets/task-flows/git.local_ahead.stale.md +34 -0
- package/agent-assets/task-flows/git.merge_to_default.md +30 -0
- package/agent-assets/task-flows/git.project.refresh_architecture.md +100 -0
- package/agent-assets/task-flows/git.project.retemplate.md +73 -0
- package/agent-assets/task-flows/git.push.detected.md +32 -0
- package/agent-assets/task-flows/git.push.force_pushed.md +36 -0
- package/agent-assets/task-flows/git.tag.created.md +24 -0
- package/agent-assets/task-flows/github.assigned.md +43 -0
- package/agent-assets/task-flows/github.pull_request.review_requested.md +57 -0
- package/agent-assets/task-flows/github.security_alert.md +45 -0
- package/agent-assets/task-flows/github.workflow_run.failed.md +57 -0
- package/agent-assets/task-flows/knowledge.import.md +161 -0
- package/agent-assets/task-flows/message.received.dm.md +142 -0
- package/agent-assets/task-flows/message.received.dm_first.md +117 -0
- package/agent-assets/task-flows/message.received.md +14 -0
- package/agent-assets/task-flows/routine.custom.md +38 -0
- package/agent-assets/task-flows/routine.evening_review.md +323 -0
- package/agent-assets/task-flows/routine.hourly_check.delegated.claude.md +405 -0
- package/agent-assets/task-flows/routine.hourly_check.delegated.codex.md +400 -0
- package/agent-assets/task-flows/routine.hourly_check.delegated.gemini.md +404 -0
- package/agent-assets/task-flows/routine.hourly_check.md +184 -0
- package/agent-assets/task-flows/routine.hourly_check.triage.md +93 -0
- package/agent-assets/task-flows/routine.monthly_review.md +250 -0
- package/agent-assets/task-flows/routine.morning_routine.md +300 -0
- package/agent-assets/task-flows/routine.morning_routine_initial.md +184 -0
- package/agent-assets/task-flows/routine.roadmap_refresh.md +275 -0
- package/agent-assets/task-flows/routine.today_refresh.md +172 -0
- package/agent-assets/task-flows/routine.user_profile_sweep.md +242 -0
- package/agent-assets/task-flows/routine.weekly_review.md +247 -0
- package/agent-assets/task-flows/schedule.approaching.md +124 -0
- package/agent-assets/task-flows/scheduled.dm.md +391 -0
- package/agent-assets/task-flows/scheduled.task.md +141 -0
- package/agent-assets/task-flows/setup.initial.md +277 -0
- package/agent-assets/task-flows/setup.update.md +53 -0
- package/agent-assets/templates/README.md +85 -0
- package/agent-assets/templates/_index.md +39 -0
- package/agent-assets/templates/_manifest.json +103 -0
- package/agent-assets/templates/agent/journal.md +10 -0
- package/agent-assets/templates/agent/profile-questions.md +74 -0
- package/agent-assets/templates/context-index.md +42 -0
- package/agent-assets/templates/dossiers/_index.md +22 -0
- package/agent-assets/templates/dossiers/evening.md +23 -0
- package/agent-assets/templates/dossiers/hourly.md +23 -0
- package/agent-assets/templates/dossiers/monthly.md +23 -0
- package/agent-assets/templates/dossiers/morning.md +23 -0
- package/agent-assets/templates/dossiers/roadmap.md +23 -0
- package/agent-assets/templates/dossiers/weekly.md +23 -0
- package/agent-assets/templates/projects/_active.base +14 -0
- package/agent-assets/templates/projects/_index.md +29 -0
- package/agent-assets/templates/roadmap.md +15 -0
- package/agent-assets/templates/routines/_index.md +20 -0
- package/agent-assets/templates/routines/evening.md +22 -0
- package/agent-assets/templates/routines/hourly.md +30 -0
- package/agent-assets/templates/routines/monthly.md +25 -0
- package/agent-assets/templates/routines/morning.md +26 -0
- package/agent-assets/templates/routines/weekly.md +23 -0
- package/agent-assets/templates/rules/_index.md +19 -0
- package/agent-assets/templates/rules/journal-export.md +41 -0
- package/agent-assets/templates/rules/journal-format.md +61 -0
- package/agent-assets/templates/rules/management.md +48 -0
- package/agent-assets/templates/rules/mcp.md +40 -0
- package/agent-assets/templates/rules/policies/_index.md +22 -0
- package/agent-assets/templates/rules/redaction.md +30 -0
- package/agent-assets/templates/today.md +13 -0
- package/agent-assets/templates/user/_index.md +16 -0
- package/agent-assets/templates/user/expertise.md +7 -0
- package/agent-assets/templates/user/goals.md +7 -0
- package/agent-assets/templates/user/people.md +7 -0
- package/agent-assets/templates/user/personal.md +7 -0
- package/agent-assets/templates/user/profile.md +28 -0
- package/agent-assets/templates/user/work.md +7 -0
- package/bin/aitne.mjs +1096 -0
- package/package.json +78 -0
- package/personal-agent.mjs +39 -0
- package/scripts/browser.mjs +99 -0
- package/scripts/check-redaction-coverage.mjs +109 -0
- package/scripts/commands/audit.mjs +309 -0
- package/scripts/commands/doctor.mjs +437 -0
- package/scripts/commands/open.mjs +40 -0
- package/scripts/commands/setup.mjs +21 -0
- package/scripts/commands/uninstall.mjs +114 -0
- package/scripts/commands/update.mjs +96 -0
- package/scripts/commands/version.mjs +62 -0
- package/scripts/commands.md +0 -0
- package/scripts/lib/sqlite-loader.mjs +49 -0
- package/scripts/message-discipline-digest.mjs +535 -0
- package/scripts/poc/google-connector-inheritance/REPORT.md +197 -0
- package/scripts/poc/google-connector-inheritance/claude-sdk-probe.mjs +79 -0
- package/scripts/remint-roadmap-ids.mjs +257 -0
- package/scripts/rm-paths.mjs +22 -0
- package/scripts/run-node.mjs +223 -0
- package/scripts/smoke-obsidian-api.mjs +166 -0
- package/scripts/start.mjs +160 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"kind": "knowledge_layout",
|
|
3
|
+
"files": [
|
|
4
|
+
{
|
|
5
|
+
"path": "projects/*.md",
|
|
6
|
+
"purpose": "Per-project context document for Git-backed projects",
|
|
7
|
+
"sections": [
|
|
8
|
+
{ "heading": "## Overview", "contains": "one-paragraph description of the project and its current state" },
|
|
9
|
+
{ "heading": "## Git Activity", "contains": "recent commits, branches, contributors summarised by the daemon" },
|
|
10
|
+
{ "heading": "## Lifecycle Phases", "contains": "phase markers (planning, build, ship, maintenance)" },
|
|
11
|
+
{ "heading": "## Notable Changes", "contains": "human-readable notes on important commits or decisions" },
|
|
12
|
+
{ "heading": "## Open Threads", "contains": "follow-ups and pending questions tracked across sessions" },
|
|
13
|
+
{ "heading": "## History (compressed)", "contains": "older content rolled up to keep the active body concise" }
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"path": "git-repos/*.md",
|
|
18
|
+
"purpose": "Per-repository context for non-project watched repositories",
|
|
19
|
+
"sections": [
|
|
20
|
+
{ "heading": "## Activity", "contains": "summarised recent activity for the watched repo" },
|
|
21
|
+
{ "heading": "## Recent Pushes", "contains": "list of push events with dates and short summaries" }
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"kind": "convention_notes",
|
|
3
|
+
"notes": [
|
|
4
|
+
{
|
|
5
|
+
"topic": "Slug format",
|
|
6
|
+
"rule": "Project and repo slugs are kebab-case, lowercase letters with hyphens between words.",
|
|
7
|
+
"example": "projects/cost-explorer.md, git-repos/personal-agent.md"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"topic": "Slug length",
|
|
11
|
+
"rule": "Slugs are 32 characters or fewer, including the hyphens but excluding the .md suffix.",
|
|
12
|
+
"example": "projects/personal-agent-skills.md is at the upper bound"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"topic": "Reserved stems",
|
|
16
|
+
"rule": "Stems _index and _archive are reserved for daemon-maintained files and not in use as project slugs.",
|
|
17
|
+
"example": "projects/_index.md is a directory listing, not a project file"
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: reading
|
|
3
|
+
description: Load when the user mentions a book or highlight, weekly/monthly reviews need reading progress, or routines need to refresh the reading-taste profile (`user/reading-taste.md`) and propose new book candidates. Owns the taste-profile schema and recommendation rules.
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Bash(curl *)
|
|
6
|
+
- Read
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Reading & Highlights Tracker
|
|
10
|
+
|
|
11
|
+
The daemon stores books and reading highlights imported from Kindle
|
|
12
|
+
(My Clippings.txt and the "Export Notebook" email pipeline) and manual
|
|
13
|
+
entries. Data lives in `books` and `reading_highlights` tables. All
|
|
14
|
+
display text in `reading-taste.md` must be English (project convention).
|
|
15
|
+
|
|
16
|
+
## When to Use
|
|
17
|
+
|
|
18
|
+
- **Monthly review**: generate reading report with books completed,
|
|
19
|
+
highlight counts, and reading pace.
|
|
20
|
+
- **Weekly review** (Phase 5, routine.weekly_review.md): refresh the
|
|
21
|
+
reading-taste profile and propose book recommendations.
|
|
22
|
+
- **User asks about a book**: query highlights and notes.
|
|
23
|
+
- **User asks about reading history**: list books by status.
|
|
24
|
+
- **Morning routine**: mention currently reading books (if user has active books).
|
|
25
|
+
|
|
26
|
+
## Workflow
|
|
27
|
+
|
|
28
|
+
1. Fetch books list with status and highlight counts.
|
|
29
|
+
2. For specific book queries, fetch highlights.
|
|
30
|
+
3. For reports, use the summary endpoint.
|
|
31
|
+
|
|
32
|
+
## Roadmap candidate signal
|
|
33
|
+
|
|
34
|
+
When a book / article request is **goal-shaped**, queue a
|
|
35
|
+
`roadmap_candidate:reading` observation so the next roadmap refresh can
|
|
36
|
+
land it in `## Long-term Plans` or `## Agent Action Plan`.
|
|
37
|
+
|
|
38
|
+
Goal-shaped means the user expresses both a reading/learning objective
|
|
39
|
+
and a future horizon or commitment. Examples:
|
|
40
|
+
- "I want to read Designing Data-Intensive Applications before Q3."
|
|
41
|
+
- "Learn Rust from this list this summer."
|
|
42
|
+
- "Finish the ML papers before the September course starts."
|
|
43
|
+
|
|
44
|
+
Do **not** queue a roadmap candidate for taste, preference, or finished
|
|
45
|
+
reading notes without a future objective:
|
|
46
|
+
- "I enjoyed Deep Work."
|
|
47
|
+
- "Recommend me books like this."
|
|
48
|
+
- "Add this article to my reading list" with no deadline or horizon.
|
|
49
|
+
|
|
50
|
+
Record the signal with a stable reading-list/book/article ref:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
curl -s -X POST http://localhost:8321/api/observations \
|
|
54
|
+
-H 'Content-Type: application/json' \
|
|
55
|
+
-d '{"source":"roadmap_candidate:reading","ref":"reading-goal-ddia-2026-q3","changeType":"created","actor":"agent","payload":{"kind":"reading_goal","horizon_tag":"2026-Q3","intent":"Finish Designing Data-Intensive Applications"}}'
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Payload contract:
|
|
59
|
+
- `kind`: `"reading_goal"`
|
|
60
|
+
- `horizon_tag`: roadmap horizon tag (`YYYY-MM`, `YYYY-Qn`,
|
|
61
|
+
`YYYY spring|summer|autumn|winter`, or `undated` when the user gave
|
|
62
|
+
no date but clearly stated a future learning goal)
|
|
63
|
+
- `intent`: concise human-readable goal, suitable for a Long-term Plan
|
|
64
|
+
line with `Source: reading`
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## API Reference
|
|
69
|
+
|
|
70
|
+
Base URL: `http://localhost:8321`
|
|
71
|
+
|
|
72
|
+
### GET /api/books
|
|
73
|
+
|
|
74
|
+
List books with optional filters.
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# Currently reading
|
|
78
|
+
curl -s "http://localhost:8321/api/books?status=reading"
|
|
79
|
+
|
|
80
|
+
# All completed books (first page)
|
|
81
|
+
curl -s "http://localhost:8321/api/books?status=completed&limit=50"
|
|
82
|
+
|
|
83
|
+
# Walk past the 200-row cap via offset
|
|
84
|
+
curl -s "http://localhost:8321/api/books?limit=200&offset=200"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
| Param | Type | Default | Description |
|
|
88
|
+
|-------|------|---------|-------------|
|
|
89
|
+
| `status` | string | all | reading, completed, abandoned, all |
|
|
90
|
+
| `source` | string | all | kindle, audible, manual, all |
|
|
91
|
+
| `limit` | number | 50 | Page size (1–200) |
|
|
92
|
+
| `offset` | number | 0 | Rows to skip. Use with `limit` to paginate beyond the 200 cap |
|
|
93
|
+
|
|
94
|
+
Response:
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"books": [
|
|
98
|
+
{
|
|
99
|
+
"id": 1,
|
|
100
|
+
"title": "Thinking, Fast and Slow",
|
|
101
|
+
"author": "Daniel Kahneman",
|
|
102
|
+
"source": "kindle",
|
|
103
|
+
"status": "reading",
|
|
104
|
+
"startedAt": null,
|
|
105
|
+
"completedAt": null,
|
|
106
|
+
"rating": null,
|
|
107
|
+
"notes": null,
|
|
108
|
+
"highlightCount": 47,
|
|
109
|
+
"createdAt": "2026-04-01T10:00:00Z"
|
|
110
|
+
}
|
|
111
|
+
],
|
|
112
|
+
"total": 1,
|
|
113
|
+
"limit": 50,
|
|
114
|
+
"offset": 0,
|
|
115
|
+
"hasMore": false
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
When iterating the entire library, keep calling with `offset += limit`
|
|
120
|
+
until `hasMore === false`.
|
|
121
|
+
|
|
122
|
+
### GET /api/books/:id/highlights
|
|
123
|
+
|
|
124
|
+
Get highlights for a specific book.
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
curl -s "http://localhost:8321/api/books/1/highlights?limit=50"
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### GET /api/books/summary
|
|
131
|
+
|
|
132
|
+
Reading statistics.
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
curl -s "http://localhost:8321/api/books/summary?months=12"
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Response:
|
|
139
|
+
```json
|
|
140
|
+
{
|
|
141
|
+
"byStatus": [
|
|
142
|
+
{ "status": "reading", "count": 3 },
|
|
143
|
+
{ "status": "completed", "count": 12 }
|
|
144
|
+
],
|
|
145
|
+
"monthlyCompleted": [
|
|
146
|
+
{ "month": "2026-04", "count": 1 },
|
|
147
|
+
{ "month": "2026-03", "count": 2 }
|
|
148
|
+
],
|
|
149
|
+
"totalHighlights": 234
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### PATCH /api/books/:id
|
|
154
|
+
|
|
155
|
+
Update book status, rating, or notes.
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
curl -s -X PATCH "http://localhost:8321/api/books/1" \
|
|
159
|
+
-H "Content-Type: application/json" \
|
|
160
|
+
-d '{"status": "completed", "rating": 4}'
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### POST /api/books/import-clippings
|
|
164
|
+
|
|
165
|
+
Import Kindle My Clippings.txt.
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
curl -s -X POST "http://localhost:8321/api/books/import-clippings" \
|
|
169
|
+
-H "Content-Type: application/json" \
|
|
170
|
+
-d "{\"data\": \"$(cat 'My Clippings.txt')\"}"
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## Formatting Guide
|
|
176
|
+
|
|
177
|
+
### Monthly review
|
|
178
|
+
|
|
179
|
+
```
|
|
180
|
+
## Reading Report (April 2026)
|
|
181
|
+
Books completed: 2
|
|
182
|
+
Currently reading: 3
|
|
183
|
+
New highlights: 34
|
|
184
|
+
|
|
185
|
+
### Completed This Month
|
|
186
|
+
1. "Deep Work" by Cal Newport — ★★★★★
|
|
187
|
+
2. "Atomic Habits" by James Clear — ★★★★
|
|
188
|
+
|
|
189
|
+
### Currently Reading
|
|
190
|
+
- "Thinking, Fast and Slow" by Daniel Kahneman (47 highlights)
|
|
191
|
+
- "The Design of Everyday Things" by Don Norman (12 highlights)
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## Reading Taste Profile (`user/reading-taste.md`)
|
|
197
|
+
|
|
198
|
+
{{> ref:reading-taste }}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
---
|
|
2
|
+
kind: reference
|
|
3
|
+
parent_skill: reading
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
This file captures what the user reads and *why* — topics they return to,
|
|
7
|
+
how they think, values that keep surfacing in their highlights, and a
|
|
8
|
+
rolling list of candidate books. It is dictionary-like (same layer as
|
|
9
|
+
other `user/*.md` files) and is consumed on-demand — never injected
|
|
10
|
+
into every session. Do not notify the user about taste updates.
|
|
11
|
+
|
|
12
|
+
### When to refresh
|
|
13
|
+
|
|
14
|
+
- **Weekly review, Phase 5**: required sweep (see task flow).
|
|
15
|
+
- **On-demand**: if the user asks "what do my highlights say about me?"
|
|
16
|
+
or "recommend a book based on what I've read".
|
|
17
|
+
- **After a book is marked `completed`** with rating ≥ 4: one-shot refresh
|
|
18
|
+
biased to that book's highlights.
|
|
19
|
+
|
|
20
|
+
**Do not refresh** if fewer than 10 new highlights have accrued since the
|
|
21
|
+
last sweep. A low-signal pass produces noise — prefer silence.
|
|
22
|
+
|
|
23
|
+
### Refresh-trigger check (how to compute the delta reliably)
|
|
24
|
+
|
|
25
|
+
The file carries a dedicated frontmatter line `Highlights at last sweep: N`
|
|
26
|
+
holding the `totalHighlights` value from `GET /api/books/summary` at the
|
|
27
|
+
time of the last successful write. To decide whether to refresh:
|
|
28
|
+
|
|
29
|
+
1. `GET /api/context/user/reading-taste` — if 404, treat as
|
|
30
|
+
`N = 0` and proceed (first sweep).
|
|
31
|
+
2. `GET /api/books/summary` — read `totalHighlights` as `M`.
|
|
32
|
+
3. If `M - N < 10`, skip the sweep (log one bullet under agent-journal
|
|
33
|
+
"What worked": `reading sweep skipped — only (M-N) new highlights`).
|
|
34
|
+
4. Otherwise, run the workflow. The new `M` becomes the `Highlights at
|
|
35
|
+
last sweep` value written on this sweep.
|
|
36
|
+
|
|
37
|
+
Do **not** compare the `Sampled: X highlights` line — `X` is the
|
|
38
|
+
sample size the agent read, not a count of highlights in the DB.
|
|
39
|
+
|
|
40
|
+
### Sampling strategy
|
|
41
|
+
|
|
42
|
+
You are working with potentially hundreds of highlights. Do not read them
|
|
43
|
+
all. Use this sampling recipe:
|
|
44
|
+
|
|
45
|
+
1. `GET /api/books?status=reading&limit=20` and
|
|
46
|
+
`GET /api/books?status=completed&limit=20` (most recently touched first).
|
|
47
|
+
2. Pick up to 8 books: all currently-reading, plus the most recent
|
|
48
|
+
completed books to fill the slot.
|
|
49
|
+
3. For each book: `GET /api/books/:id/highlights?limit=12`. The endpoint
|
|
50
|
+
sorts by `highlighted_at DESC` — for Kindle imports this is **when the
|
|
51
|
+
user highlighted on device**, not when the daemon ingested the email.
|
|
52
|
+
That means the 12-entry sample is representative of what the user
|
|
53
|
+
latched onto in a book, NOT a freshness-ordered activity feed. Treat
|
|
54
|
+
it as a broad taste sample, not a "last week" view.
|
|
55
|
+
4. When sampling a book with >50 highlights total, you are viewing a
|
|
56
|
+
dozen out of many. Note this in the "Sampled" line of the file —
|
|
57
|
+
don't claim exhaustive coverage of a 200-highlight book.
|
|
58
|
+
|
|
59
|
+
The refresh-trigger check (previous section) uses `totalHighlights` from
|
|
60
|
+
`/api/books/summary` and is insensitive to `highlighted_at`; it detects
|
|
61
|
+
"new highlights exist in the DB" regardless of their on-device date.
|
|
62
|
+
|
|
63
|
+
### Required file schema
|
|
64
|
+
|
|
65
|
+
First refresh writes the whole file via `PUT /api/context/user/reading-taste`.
|
|
66
|
+
Subsequent refreshes use `PATCH` per section (but the metadata lines must
|
|
67
|
+
be updated via a full-file `PUT`). Required structure:
|
|
68
|
+
|
|
69
|
+
```markdown
|
|
70
|
+
---
|
|
71
|
+
type: user
|
|
72
|
+
owner: shared
|
|
73
|
+
updated: YYYY-MM-DD
|
|
74
|
+
---
|
|
75
|
+
# Reading Taste
|
|
76
|
+
> Last updated: YYYY-MM-DD HH:MM
|
|
77
|
+
> Sampled: N highlights across M books (window: last K weeks)
|
|
78
|
+
> Highlights at last sweep: T <!-- total in DB from /books/summary, used for delta check -->
|
|
79
|
+
|
|
80
|
+
## Topics of Interest
|
|
81
|
+
- 3–6 bullets. Concrete topics, not categories: "cognitive biases in
|
|
82
|
+
decision-making" not "psychology". Each bullet: one line.
|
|
83
|
+
|
|
84
|
+
## Thinking Patterns
|
|
85
|
+
- 3–5 bullets. How the user processes ideas, inferred from what they
|
|
86
|
+
highlight — e.g. "highlights counter-intuitive claims with supporting
|
|
87
|
+
evidence", "prefers concrete cases over abstractions", "marks passages
|
|
88
|
+
that challenge common wisdom".
|
|
89
|
+
|
|
90
|
+
## Values & Recurring Questions
|
|
91
|
+
- 3–5 bullets. Values or open questions the highlights keep returning
|
|
92
|
+
to — e.g. "tension between productivity and depth", "skepticism of
|
|
93
|
+
institutional incentives", "what makes work meaningful".
|
|
94
|
+
|
|
95
|
+
## Preferred Formats
|
|
96
|
+
- 1–3 bullets. Observed preferences: narrative nonfiction, research-heavy,
|
|
97
|
+
essay collections, short-form, etc. State only what the sample supports.
|
|
98
|
+
|
|
99
|
+
## Book Candidates
|
|
100
|
+
- 5–10 bullets. Rolling list of books the user might enjoy, written by
|
|
101
|
+
you based on the sampled highlights. Format each as:
|
|
102
|
+
`- <Title> — <Author>. Why: <1 sentence tying it to a specific pattern
|
|
103
|
+
above>.`
|
|
104
|
+
Do not repeat books already in `books` (any status). Prefer ≤2 per author.
|
|
105
|
+
Replace the full list each weekly sweep (append-style drift produces
|
|
106
|
+
stale duplicates).
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Rules for the taste profile
|
|
110
|
+
|
|
111
|
+
- **Stay grounded in sampled highlights.** Every claim in Topics / Thinking
|
|
112
|
+
Patterns / Values should be traceable to specific passages you read.
|
|
113
|
+
When writing, mentally annotate each bullet with the highlight(s) that
|
|
114
|
+
justify it — if you cannot, drop the bullet.
|
|
115
|
+
- **No moralizing or judgement.** Record what the user is drawn to, not
|
|
116
|
+
whether those interests are "good". Avoid adjectives that evaluate the
|
|
117
|
+
user ("enlightened", "shallow").
|
|
118
|
+
- **Avoid one-shot artifacts.** A single standout highlight isn't a
|
|
119
|
+
pattern. Look for themes across ≥2 books before recording.
|
|
120
|
+
- **Language: English only.** Per project convention — even if the source
|
|
121
|
+
highlights are in another language, summarize in English.
|
|
122
|
+
- **Silent update.** Never notify the user about taste-profile changes.
|
|
123
|
+
|
|
124
|
+
### PATCH patterns
|
|
125
|
+
|
|
126
|
+
Replace a single section (snake_case the heading):
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
curl -s -X PATCH http://localhost:8321/api/context/user/reading-taste \
|
|
130
|
+
-H 'Content-Type: application/json' \
|
|
131
|
+
-d '{"section": "topics_of_interest", "mode": "replace", "content": "- cognitive biases\n- systems design"}'
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Replace the full file (first time, or after a major reset):
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
curl -s -X PUT http://localhost:8321/api/context/user/reading-taste \
|
|
138
|
+
-H 'Content-Type: application/json' \
|
|
139
|
+
-d '{"content": "---\ntype: user\nowner: shared\nupdated: 2026-04-21\n---\n# Reading Taste\n> Last updated: 2026-04-16 09:00\n> Sampled: 87 highlights across 8 books (window: last 12 weeks)\n> Highlights at last sweep: 245\n\n## Topics of Interest\n- ...\n..."}'
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Update both the `Last updated` line and the `Highlights at last sweep`
|
|
143
|
+
line on every refresh. Section-level `PATCH` does not touch the top
|
|
144
|
+
metadata — if only sections changed, still issue one `PUT` at the end of
|
|
145
|
+
the sweep to write the refreshed metadata and YAML `updated` date.
|
|
146
|
+
|
|
147
|
+
### First-write registration (_index.md)
|
|
148
|
+
|
|
149
|
+
The `user/_index.md` file indexes available topic files. When
|
|
150
|
+
creating `reading-taste.md` for the first time (GET returned 404),
|
|
151
|
+
append a one-line entry to the index so other flows can discover it:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
curl -s -X PATCH http://localhost:8321/api/context/user/_index \
|
|
155
|
+
-H 'Content-Type: application/json' \
|
|
156
|
+
-d '{"section": "topics", "mode": "append", "content": "- reading-taste — derived taste profile + rolling book candidates (updated weekly)"}'
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
The section name (`topics` above) depends on the existing `_index.md`
|
|
160
|
+
shape; fetch it first and append under the most natural heading. Do
|
|
161
|
+
NOT overwrite existing index content.
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Book Recommendations
|
|
166
|
+
|
|
167
|
+
The weekly sweep writes recommendations into the `Book Candidates`
|
|
168
|
+
section of `reading-taste.md` (see above). Do **not** create a separate
|
|
169
|
+
`recommendations.md` — the candidate list belongs with the taste it was
|
|
170
|
+
derived from.
|
|
171
|
+
|
|
172
|
+
### How to propose candidates
|
|
173
|
+
|
|
174
|
+
- Use your own book knowledge keyed by the sampled highlights. This is
|
|
175
|
+
reasoning from the user's demonstrated taste, not a lookup — no
|
|
176
|
+
external API.
|
|
177
|
+
- Avoid recommending books already in the `books` table (any status).
|
|
178
|
+
Fetch the existing library once before writing the final list. For
|
|
179
|
+
libraries larger than 200 books, paginate with
|
|
180
|
+
`?limit=200&offset=0`, `&offset=200`, … until `hasMore === false`,
|
|
181
|
+
and merge the titles into a single exclusion set.
|
|
182
|
+
- Tie each recommendation to a specific pattern from Topics / Thinking /
|
|
183
|
+
Values. A recommendation with no pattern-justification is a generic
|
|
184
|
+
suggestion and should be dropped.
|
|
185
|
+
- Prefer books the user is likely unaware of — not the usual-suspects
|
|
186
|
+
that trend on social media.
|
|
187
|
+
|
|
188
|
+
### Weekly user-facing hint (optional)
|
|
189
|
+
|
|
190
|
+
If the silent gate in Phase 4 of the weekly review does **not** trigger
|
|
191
|
+
and the taste file gained ≥1 genuinely new candidate this sweep, you
|
|
192
|
+
MAY add a single optional line to the weekly notification in the form:
|
|
193
|
+
`Reading pick: <Title> — <1-clause why>.`
|
|
194
|
+
|
|
195
|
+
Do not force a line just because recommendations were updated. The
|
|
196
|
+
silent-default principle applies: omit if the pick would feel like
|
|
197
|
+
filler.
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: receipts
|
|
3
|
+
description: Load when the user asks about receipts/invoices, tax-prep needs an annual list, or an unsaved receipt should be filed.
|
|
4
|
+
when_to_use: Downloads Gmail-observer-flagged attachments to the user's external Obsidian vault, separate from the agent's primary management store.
|
|
5
|
+
allowed-tools:
|
|
6
|
+
- Bash(curl *)
|
|
7
|
+
- Read
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Receipt & Document Manager
|
|
11
|
+
|
|
12
|
+
The daemon's Gmail observer scans travel-booking emails for PDF/image
|
|
13
|
+
attachments and can retain previously detected generic documents.
|
|
14
|
+
Attachment metadata is stored in the `receipts` SQLite table. Actual files
|
|
15
|
+
are downloaded on demand and can be saved to the user's **external**
|
|
16
|
+
Obsidian vault (separate from the agent's primary management store).
|
|
17
|
+
|
|
18
|
+
## When to Use
|
|
19
|
+
|
|
20
|
+
- **User asks about receipts**: list detected receipts, check save status.
|
|
21
|
+
- **Tax preparation season**: generate annual receipt list, save unsaved receipts.
|
|
22
|
+
- **Monthly/yearly review**: report on receipt collection completeness.
|
|
23
|
+
|
|
24
|
+
## Workflow
|
|
25
|
+
|
|
26
|
+
1. Fetch receipt list from `/api/receipts`.
|
|
27
|
+
2. To save a receipt to the external Obsidian vault, download via
|
|
28
|
+
`/api/receipts/:id/download` then save to the vault via
|
|
29
|
+
`POST /api/obsidian/notes` and update the receipt record with the
|
|
30
|
+
vault-relative path via `PATCH /api/receipts/:id`. (`obsidianPath` is
|
|
31
|
+
a path inside the external vault, not the primary management store.)
|
|
32
|
+
3. For tax preparation, filter by date range and category.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## API Reference
|
|
37
|
+
|
|
38
|
+
Base URL: `http://localhost:8321`
|
|
39
|
+
|
|
40
|
+
### GET /api/receipts
|
|
41
|
+
|
|
42
|
+
List detected receipt attachments.
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# All receipts
|
|
46
|
+
curl -s "http://localhost:8321/api/receipts?limit=50"
|
|
47
|
+
|
|
48
|
+
# Unsaved receipts only
|
|
49
|
+
curl -s "http://localhost:8321/api/receipts?saved=false"
|
|
50
|
+
|
|
51
|
+
# Filter by category
|
|
52
|
+
curl -s "http://localhost:8321/api/receipts?category=document"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
| Param | Type | Default | Description |
|
|
56
|
+
|-------|------|---------|-------------|
|
|
57
|
+
| `category` | string | — | document, travel |
|
|
58
|
+
| `saved` | boolean | — | true = saved to Obsidian, false = not yet saved |
|
|
59
|
+
| `limit` | number | 50 | Max results (1–200) |
|
|
60
|
+
|
|
61
|
+
Response:
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"receipts": [
|
|
65
|
+
{
|
|
66
|
+
"id": 1,
|
|
67
|
+
"gmailMessageId": "18f...",
|
|
68
|
+
"attachmentId": "ANGj...",
|
|
69
|
+
"filename": "receipt.pdf",
|
|
70
|
+
"mimeType": "application/pdf",
|
|
71
|
+
"sizeBytes": 45000,
|
|
72
|
+
"category": "document",
|
|
73
|
+
"obsidianPath": null,
|
|
74
|
+
"savedAt": null,
|
|
75
|
+
"createdAt": "2026-04-12T10:00:00Z"
|
|
76
|
+
}
|
|
77
|
+
],
|
|
78
|
+
"total": 1
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### GET /api/receipts/summary
|
|
83
|
+
|
|
84
|
+
Receipt statistics.
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
curl -s "http://localhost:8321/api/receipts/summary"
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Response:
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"total": 25,
|
|
94
|
+
"saved": 10,
|
|
95
|
+
"unsaved": 15,
|
|
96
|
+
"byCategory": [
|
|
97
|
+
{ "category": "document", "count": 23 },
|
|
98
|
+
{ "category": "travel", "count": 2 }
|
|
99
|
+
]
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### POST /api/receipts/:id/download
|
|
104
|
+
|
|
105
|
+
Download the actual attachment file from Gmail.
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
curl -s -X POST "http://localhost:8321/api/receipts/1/download" -o receipt.pdf
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### PATCH /api/receipts/:id
|
|
112
|
+
|
|
113
|
+
Update receipt metadata (change category or mark as saved).
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
# Mark as saved to Obsidian
|
|
117
|
+
curl -s -X PATCH "http://localhost:8321/api/receipts/1" \
|
|
118
|
+
-H "Content-Type: application/json" \
|
|
119
|
+
-d '{"obsidianPath": "receipts/2026/04/amazon-receipt.pdf"}'
|
|
120
|
+
|
|
121
|
+
# Reclassify a receipt
|
|
122
|
+
curl -s -X PATCH "http://localhost:8321/api/receipts/1" \
|
|
123
|
+
-H "Content-Type: application/json" \
|
|
124
|
+
-d '{"category": "travel"}'
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## External Obsidian Vault Save Convention
|
|
130
|
+
|
|
131
|
+
Save receipts to: `receipts/YYYY/MM/<merchant>-<date>.<ext>` inside the
|
|
132
|
+
external Obsidian vault.
|
|
133
|
+
|
|
134
|
+
Example: `receipts/2026/04/amazon-2026-04-12.pdf`
|