Sync Harmonica deliberation sessions to markdown files. Run locally or in CI to keep a structured archive of your sessions in a git repo, Quartz wiki, or static site.
# 1. Scaffold config and template
npx harmonica-sync --init
# 2. Edit harmonica.config.json with your search queries
# 3. Set your API key (from Harmonica dashboard → Settings → API Keys)
export HARMONICA_API_KEY=hm_live_...
# 4. Sync
npx harmonica-sync- Searches the Harmonica API with your configured queries
- Filters by keywords, participant count, and summary availability
- Skips sessions already in the output directory (idempotent)
- Renders each session through a Mustache template
- Writes markdown files to the output directory
harmonica.config.json:
{
"sync": {
"search": ["community feedback", "retrospective"],
"keywords": ["our-org", "team"],
"minParticipants": 1,
"requireSummary": true
},
"output": {
"dir": "sessions",
"filename": "{{date}}-{{id}}.md",
"template": "./session-template.md"
}
}| Field | Description | Default |
|---|---|---|
sync.search |
API search queries (required) | — |
sync.keywords |
Filter on topic/goal/context text | all results accepted |
sync.minParticipants |
Skip sessions below this count | 1 |
sync.requireSummary |
Only sync sessions with a summary | true |
output.dir |
Output directory | sessions |
output.filename |
Filename template ({{date}}, {{id}}, {{slug}}) |
{{date}}-{{id}}.md |
output.template |
Path to Mustache template | built-in Quartz-compatible |
The default template produces Quartz/Hugo/Jekyll-compatible markdown with YAML frontmatter. Customize it by editing the session-template.md generated by --init.
Available template variables:
| Variable | Type | Description |
|---|---|---|
topic |
string | Session topic |
date |
string | ISO date (YYYY-MM-DD) |
id |
string | Session ID |
participant_count |
number | Number of participants |
status |
string | Session status |
goal |
string | Session goal |
critical |
string/null | Critical question |
context |
string/null | Session context |
summary |
string/null | AI-generated summary |
tags |
string[] | Matched search queries |
responses |
boolean | Whether responses exist |
participants |
array | Participant responses |
participants[].number |
number | Participant number (1-indexed) |
participants[].messages |
array | User messages |
name: Sync Harmonica Sessions
on:
schedule:
- cron: '0 */6 * * *'
workflow_dispatch:
permissions:
contents: write
jobs:
sync:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Sync sessions
env:
HARMONICA_API_KEY: ${{ secrets.HARMONICA_API_KEY }}
run: npx harmonica-sync
- name: Commit new sessions
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add sessions/
git diff --cached --quiet || git commit -m "Sync Harmonica sessions" && git pushnpx harmonica-sync # sync using ./harmonica.config.json
npx harmonica-sync --config path/to # custom config path
npx harmonica-sync --init # generate starter config + template
npx harmonica-sync --help # show help
| Variable | Required | Description |
|---|---|---|
HARMONICA_API_KEY |
Yes | API key from Harmonica dashboard |
HARMONICA_API_URL |
No | API base URL (default: https://app.harmonica.chat) |
- Research sync pipeline — A
--mode researchfor complex research projects where one session produces many output files. Extracts participant data, maps messages to problems/solutions (LLM-assisted or rule-based), computes metrics (breadth, depth, urgency scores), and renders 50+ files across wiki pages and dashboards — all from a single canonical data file. Includes a human-in-the-loop reconciliation step before any writes. (Design doc) - Git repo as session context — Feed repo content (previous sessions, workshop notes, artifacts, consensus) back into new Harmonica sessions as facilitator context. Closes the loop: sessions produce markdown → markdown informs future sessions. Config-driven context assembly in
harmonica.config.jsondefines rules for what to send (e.g., "include all artifacts, last 3 workshops, latest consensus") and a--contextflag assembles and pushes to the Session Context Sources API (HAR-94). Without this, communities must manually pick documents per session or write custom CI scripts. - Incremental updates — Re-sync sessions that changed since last run (based on
updated_ator response count) instead of skipping already-synced sessions entirely. Active sessions get new responses over time — the archive should reflect that. (HAR-339) - Webhook trigger — React to Harmonica webhooks when a session completes or gets new responses, instead of polling every 6 hours. Faster updates, fewer wasted CI runs. (HAR-340)
- Auto-generate emerging consensus — Post-sync synthesis step that reads all content in the output directory (sessions, workshops, artifacts) and writes a consensus summary to a data file (e.g.,
_data/consensus.yml) for static site generators. Supports BYOM (Bring Your Own Model): use Harmonica's API by default, or configure your own LLM provider inharmonica.config.json. (HAR-338)
MIT