Skip to main content

Hermes Journal Writer

@webframp/hermes-journal-writerv2026.07.20.1· 11d agoMODELS
01README

Journal Writer — reads research-collector data from the swamp catalog and writes org-mode journal entries to ~/org/journal/. Commits and pushes to the org repo so entries become part of your living knowledge store.

Methods

  • write_daily_entry — Writes a daily research summary to ~/org/journal/YYYY-MM-DD-dow.org with property drawer, source links, and summaries from HN, Lobste.rs, SRE Weekly, IFIN, and RedMonk.
02Release Notes

Render The AI Daily Brief editions in daily org entries: new aiDailyBrief source (on by default) adds an edition section with date, title, tags, thesis, URL, and written takeaways. Upgrade backfills aiDailyBrief onto existing instances' sources list.

03Models1
@webframp/hermes-journal-writerv2026.07.20.1hermes-journal-writer/hermes_jrnl_writer.ts

Global Arguments

ArgumentTypeDescription
orgDirstringRoot directory of the org repo (supports ~ expansion)
jrnlSubdirstringSubdirectory under orgDir for journal entries
swampBinstringPath to the swamp binary (must be on PATH or specify full path)
repoDirstringPath to the swamp repo directory
gitUserNamestringGit commit user name
gitUserEmailstringGit commit user email
sourcesarrayWhich sources to include in the journal entry. Omit a source name to disable it.
fn write_daily_entry()
Write a daily research journal entry to the org repo with commit/push.

Resources

journalEntry(infinite)— Record of a journal entry
04Previous Versions6
2026.07.18.1

2026.07.18.1

Added: An upgrades array entry (no-op) to hermes_jrnl_writer.ts for proper typeVersion tracking on existing instances. No schema or behavior changes.

2026.07.09.1

Fixed: write_daily_entry failed argument validation under swamp. Its method arguments schema was z.object({}).strict(), and .strict() rejects the extra keys swamp injects into a method call — so every invocation errored before the method body ran. The schema is now z.object({}) (no .strict()), accepting the call as swamp makes it.

No behavioral change to the journal output or git handling: every safeguard from 2026.07.08.1 (single-colon FILETAGS, skipped-no-data, honest git status codes, single-file commit, stat rethrow, timeout cleanup) is unchanged.

2026.07.08.1

Changed: One org file per day instead of a monthly rollup.

  • Journal entries are now written to YYYY-MM-DD-dow.org (e.g. 2026-07-08-wed.org), each a standalone org document with #+TITLE, #+DATE, and #+FILETAGS headers. Writing is idempotent — an existing file for the day is left untouched.
  • Section headings are now level-1 (* Hacker News) since the day's entry is the whole document, rather than the ***/**** levels that assumed nesting inside a monthly file.
  • #+FILETAGS are now joined with single colons (:a:b:); the previous join emitted a doubled colon (:a::b:) that org parses as an empty tag. Tags that sanitize to an empty string are dropped rather than emitted.
  • A run with no research data now writes and commits nothing (status skipped-no-data) instead of committing a "No research data" placeholder. The placeholder would trip the idempotency guard and permanently block a later run that day from writing the real entry once the collector had run.

Added:

  • sources global arg — an array drawn from ["hn", "lobsters", "sre", "ifin", "redmonk", "arxiv"]. Defaults to all sources; remove a name to disable that source. An unset/empty value is treated as "all sources".
  • arXiv entries are now rendered as an * arXiv section (previously collected but never written out).

Fixed:

  • Git failures are no longer reported as success. The recorded status now reflects what actually reached the remote: written (committed and pushed), committed-not-pushed (push failed), written-not-committed (commit failed), or written-nothing-to-commit (the file already matched the last commit, so no push was attempted). A failed git status (e.g. a held index.lock) is treated as an error rather than "nothing to commit".
  • The commit now stages and commits only the day's file (git add -- <file>) rather than the whole journal subdirectory, so an unrelated in-progress edit is never swept into the bot commit.
  • The idempotency guard now rethrows non-NotFound stat errors (permission denied, I/O) instead of swallowing them and failing later without context.
  • runCommand clears its timeout timer in a finally block, so the timer no longer leaks if the subprocess call rejects.
  • Reads the research data spec first (the current @webframp/research-collector output), falling back to the legacy brief spec for older instances.
2026.07.09.1
2026.07.08.1

2026.07.08.1

Changed: One org file per day instead of a monthly rollup.

  • Journal entries are now written to YYYY-MM-DD-dow.org (e.g. 2026-07-08-wed.org), each a standalone org document with #+TITLE, #+DATE, and #+FILETAGS headers. Writing is idempotent — an existing file for the day is left untouched.
  • Section headings are now level-1 (* Hacker News) since the day's entry is the whole document, rather than the ***/**** levels that assumed nesting inside a monthly file.
  • #+FILETAGS are now joined with single colons (:a:b:); the previous join emitted a doubled colon (:a::b:) that org parses as an empty tag. Tags that sanitize to an empty string are dropped rather than emitted.

Added:

  • sources global arg — an array drawn from ["hn", "lobsters", "sre", "ifin", "redmonk", "arxiv"]. Defaults to all sources; remove a name to disable that source. An unset/empty value is treated as "all sources".
  • arXiv entries are now rendered as an * arXiv section (previously collected but never written out).

Fixed:

  • Git failures are no longer reported as success. A failed git push now records the entry as committed-not-pushed (and a failed commit as written-not-committed) instead of logging "Pushed to remote" and recording written. The recorded status reflects what actually reached the remote.
  • The commit now stages and commits only the day's file (git add -- <file>) rather than the whole journal subdirectory, so an unrelated in-progress edit is never swept into the bot commit.
  • The idempotency guard now rethrows non-NotFound stat errors (permission denied, I/O) instead of swallowing them and failing later without context.
  • runCommand clears its timeout timer in a finally block, so the timer no longer leaks if the subprocess call rejects.
  • Reads the research data spec first (the current @webframp/research-collector output), falling back to the legacy brief spec for older instances.
2026.06.21.1
2026.06.15.1
2026.06.14.1
05Stats
A
100 / 100
Downloads
7
Archive size
12.3 KB
  • Has README or module doc2/2earned
  • README has a code example1/1earned
  • README is substantive1/1earned
  • Most symbols documented1/1earned
  • No slow types (deprecated)1/1earned
  • Dependencies pass trust audit2/2earned
  • Has description1/1earned
  • Platform support declared (or universal)2/2earned
  • License declared1/1earned
  • Verified public repository2/2earned
06Platforms
07Labels