songjongdevsecops/dsh-agenda

dsh-agenda

DeepSeek Harness plugin: a personal agenda of Markdown cards (tasks, ideas, notes, projects) with seven agent tools, a sidebar tab and a daily digest. The data never lives in the plugin.

Uncategorizeddeepseek-harness

dsh-agenda

A personal agenda of Markdown cards, inside DeepSeek Harness.

Tasks, ideas, notes and projects live as plain Markdown files with YAML frontmatter in a directory you own. The agent captures what you say, answers what is due, and changes a card only with the etag it just read. You get a sidebar tab, a chat command and a short digest at the start of every turn. The data never lives inside the plugin: uninstalling it leaves every card intact and readable.

WhoHowWhat you get
the agentseven agenda_* toolscapture, search, read, update, close, the day's digest, reminders
you, in the chat/agenda [hoje | capturar <texto> | buscar <termo>]the digest or a capture without leaving the conversation
you, in the sidebarAcervo tab and the anotar shortcutfilters, the card detail and the day-to-day actions
you, in SettingsAcervo sectionthe agenda.yml parameters, the tag vocabulary and the model reference

Install

# 1. pnpm (needed by `dsh plugin`)
npm install -g pnpm

# 2. add the plugin to your `web` profile
npx @deepseek-ai/dsh plugin --profile web add github:songjongdevsecops/dsh-agenda

# 3. restart the harness: the bundle layer is read at boot
npx @deepseek-ai/dsh web

If dsh is already installed globally, step 2 is dsh plugin --profile web add github:songjongdevsecops/dsh-agenda.

The package declares dsh.bundle.patch, so dsh plugin add appends dsh-agenda to dsh.profile.bundles in the profile manifest. That line is the only activation, and it is applied at every boot.

Check the loaded line:

npx @deepseek-ai/dsh --profile web --dump-config | grep -A3 agenda

Expected shape:

- id: agenda
  name: dsh-agenda
  config: {}

Update and uninstall

# update: re-run the add command, then restart the harness
npx @deepseek-ai/dsh plugin --profile web add github:songjongdevsecops/dsh-agenda

# uninstall, then restart
npx @deepseek-ai/dsh plugin --profile web remove dsh-agenda

Requirements

  • Node.js ^22.19.0 || >=24.0.0 (the range DeepSeek Harness supports). No runtime dependencies: the core uses the Node standard library only.
  • pnpm on PATH; the harness manages profile plugins with it.
  • DeepSeek Harness itself, e.g. npx @deepseek-ai/dsh web.
  • A writable directory for the cards. It defaults to ~/.dsh/agenda and is created on the first capture; see Configuration.
  • Optional: the native Schedule plugin (@deepseek-ai/dsh-schedule) if you want reminders to come back as a turn. Without it, agenda_lembrar still records the instant on the card and returns the arguments for schedule_create.

Configuration

The acervo root is resolved in this order:

  1. config.acervo on the agenda line of your profile patch;
  2. the AGENDA_DIR environment variable;
  3. ~/.dsh/agenda.

The default is deliberately neutral: installed from npm, the package lives under node_modules/, and the folder above it is not an agenda. Point the plugin at your own directory with one of the first two.

Profile patch example (~/.dsh/profiles/<profile>/cordis.patch.yml):

- id: agenda
  config:
    acervo: '/path/to/agenda'

The same directory can hold an optional agenda.yml. The Settings section edits this file; nothing about your agenda is stored in a harness settings namespace, so the configuration is versionable, legible and the same file the agent reads.

KeyDefaultMeaning
dia_comeca_as4hour the working day starts; work after midnight counts as the previous day
revisar_em_padrao_dias7default revisit distance, in days, for an open card with no date
algum_dia_padrao_dias30default revisit distance for algum-dia
arquivar_apos_dias90days after closing before a card is archived
tags[]the closed tag vocabulary

A new tag is refused until it is added to agenda.yml (or approved through the nova_tag flag of agenda_capturar). A tag in use is refused for removal: merge it first.

The acervo on disk

acervo/
├── agenda.yml          # optional parameters and tag vocabulary
├── cartoes/            # one Markdown file per open card
├── projetos/           # cards of type `projeto`
├── arquivo/            # closed and old cards
└── .agents/skills/agenda/SKILL.md   # optional: the procedure the agent follows

A card is a file named AAAA-MM-DD-HHMM-<slug>.md. The title is the first # line of the body, not a field; the id is the start of the file name and never changes.

---
id: 2026-10-09-1432-pagar-luz
tipo: tarefa              # tarefa | ideia | nota | projeto
estagio: backlog
prioridade: media         # none | baixa | media | alta
urgente: false
tags: [casa, financas]
proxima_acao: "Pegar a 2ª via no site da concessionária"
pronto_quando: "Boleto pago e comprovante salvo"
prazo: 2026-10-12
agendar: 2026-10-10
revisar_em: 2026-10-16
criado: 2026-10-09T14:32:00-03:00
atualizado: 2026-10-09T15:02:00-03:00
origem: conversa
---
# Pagar a conta de luz

Chegou a fatura de outubro, R$ 187,40, vence dia 12.

Stages. Tasks and projects: refinar, backlog, fazendo, revisao, concluido, cancelado, algum-dia. Notes and ideas: aberta, arquivada.

Conditions are orthogonal to the stage: urgente: true and impedido: { motivo, desde, espera_por }. Priority is a four-step scale where none is a first-class state, and the numeric ordem field beats the label when the day's list is sorted.

Transitions that require a field. The core refuses them, not the prompt:

TransitionRequires
refinar → backlogproxima_acao (a phrase starting with a verb) and pronto_quando
fazendo → revisaopronto_quando
any → concluidoevidence from you; the core records concluido_em
any → canceladomotivo_cancelamento
any → algum-diarevisar_em

Every write carries an if_match. A stale etag is an explicit conflict, never a silent "updated".

Usage

Talk to the agent:

  • "anota: comprar filtro de água" → agenda_capturar writes one card and returns its id. Capturing the same text again on the same working day returns the existing card instead of creating a second one.
  • "o que tenho hoje?" → agenda_hoje returns overdue, due today, scheduled, blocked, stalled refinar and overdue revisit, with counts.
  • "procura o que falei do filtro" → agenda_buscar searches in steps: exact filters first, local BM25 scoring when there is text. It never dumps the whole agenda.
  • "passa o cartão X para fazendo" → agenda_ler first (to get the etag), then agenda_atualizar with if_match.
  • "fecha o cartão X: paguei" → agenda_concluir, which demands evidence.
  • "me lembra dia 12 às 9h" → agenda_lembrar records the instant and returns the arguments for the native schedule_create.

In the chat:

/agenda                          # the day's digest
/agenda capturar comprar pilha   # capture without leaving the conversation
/agenda buscar pilha             # search

In the sidebar, the Acervo tab lists today, refinar, fazendo, blocked and all open cards; selecting a card shows its fields and the everyday actions (start, backlog, priority, urgent, block, unblock, schedule, close). The anotar shortcut in the conversation header captures from the current conversation. The browser half talks to the host through /agenda/api, a loopback-only POST route, and has no privileged path: it is the same core the agent uses.

At the first step of a turn the plugin injects a short digest, and only when there is something to say: what is overdue, what is due today and what waits on someone else. An empty agenda injects nothing.

Verification

After installing and restarting, confirm the plugin is loaded:

npx @deepseek-ai/dsh --profile web --dump-config | grep -A3 agenda

Then ask the agent "anota: testar o acervo". A card should appear under <acervo>/cartoes/, and agenda_hoje should list it. Ask the same thing again: the answer is the same card, with criado: false, and no second file.

Troubleshooting

  • Plugin installed but nothing appears: restart the harness. The bundle layer is read at boot, not at install time.
  • pnpm not found on PATH: npm install -g pnpm, then re-run the add.
  • bin/agenda.mjs não encontrado: the package is incomplete; reinstall it.
  • Cards land in the wrong directory: set acervo in the profile patch or AGENDA_DIR in the environment, then restart.
  • A reminder never fires: the native Schedule plugin is not enabled in this profile. agenda_lembrar returns the schedule_create arguments so the agent can create the trigger explicitly.

License

MIT