hotmilk

extensionmaintained

hotmilk - Pi package bundling gentle-pi, context-mode, graphify, subagents, and bundled extension toggles via hotmilk.json

by · v0.1.20 · published 2d ago

$ pi install npm:hotmilk
downloads/mo
0
stars
4
last push
2d ago
open issues
1

Signals

license: MITtestspi manifest: missinginstall size: —deps: 0peer deps: 0

Download trend

2.7K downloads · last 12 weeks (weekly)

README

hotmilk

hotmilk is a Pi meta-package: one install wires gentle-pi, context-mode, graphify, subagents, and related extensions, plus user toggles in ~/.pi/agent/hotmilk.json.

Use it when you want a practical engineering workstation without hand-picking a dozen pi-* packages and wiring settings.json yourself.

Contents

What you get

LayerPackages / assets
Orchestrationgentle-pi ^2.1.x (el Gentleman, SDD/OpenSpec sync, skill registry, /gentle-ai:doctor)
Contextcontext-mode, pi-simplify, pi-rtk-optimizer (default off), pi-observational-memory (default off)
Codebase graphgraphify-pi (default on); optional @isac322/pi-codegraph / pi-shazam (default off)
Subagentspi-subagents, pi-ask-user, pi-herdr-squad (Herdr panes only, off by default)
Goals & docspi-goal, pi-docparser
File-based planning@tomxprime/planning-with-files, @plannotator/pi-extension (browser plan approval)
Integrationspi-mcp-adapter, pi-btw (side channel — see below), @haispeed/pi-obsidian
Web toolspi-web-access
Experiment loopspi-autoresearch
Local assets./prompts, ./skills, ./themes, mcp.json template

Bundled extension on/off is controlled in hotmilk.json (via /mode), then /reload. Only src/index.ts is listed in package.jsonpi.extensions; every other bundled package is loaded dynamically when its toggle is true. Package-level pi.skills / pi.prompts / pi.themes paths are always indexed by Pi (they are not gated by /mode toggles).

Quick start

Install

pi install npm:hotmilk

Or add to Pi settings (~/.pi/agent/settings.json or project .pi/settings.json):

{
  "packages": ["npm:hotmilk"]
}

Local checkout:

pi install -l npm:hotmilk

First run

  1. Open a project directory in Pi.
  2. On first session, hotmilk creates ~/.pi/agent/hotmilk.json if missing (defaults match the bundled template).
  3. After config changes, run /reload.

Pi 0.84 and npm peers

hotmilk targets Pi 0.84 (@earendil-works/pi-coding-agent and peers). Some bundled dependencies still declare narrow peer ranges that exclude 0.84 (pi-kanagawa peers on the @mariozechner/* namespace). npm may report ERESOLVE until those packages publish wider peers.

This repo ships .npmrc with legacy-peer-deps=true so npm install and npm ci succeed. Copy from .npmrc.example if you clone without .npmrc. Treat upstream extensions as best-effort on 0.84 until their maintainers widen peer ranges.

Project trust (Pi 0.79+)

Pi gates project-local .pi/ resources and .agents/skills behind project trust (Pi docs). hotmilk registers a project_trust handler and, by default, defers to Pi's built-in prompt (projectTrust.mode: "delegate").

Configure in ~/.pi/agent/hotmilk.json:

{
  "projectTrust": {
    "mode": "delegate",
    "remember": false
  }
}
modeBehavior
delegateLet Pi resolve trust (trust.json, defaultProjectTrust, or built-in prompt)
prompthotmilk confirm explaining what project trust enables
alwaysTrust project-local resources (optionally remember: true)
neverDecline project-local resources for this handler

On startup, hotmilk scans only global Pi settings for bundled-extension dedupe. After trust, project .pi/settings.json duplicates are reported; run /reload to dedupe.

Commands (hotmilk)

CommandPurpose
/modeToggle bundled extensions; writes ~/.pi/agent/hotmilk.json
/stopStop current running work
/interrupt <message>Steer in-flight work with an interrupt prompt

Upstream packages add their own commands (gentle-pi /gentle-ai:status, /gentle-ai:doctor, SDD chains, graphify, context-mode, planning-with-files /plan-status, plannotator /plannotator, and so on).

For which plan, memory, or optimize path to use, see Workflow routing (canonical matrix) and the bundled pioneer skill.

Configuration

~/.pi/agent/hotmilk.json

{
  "extensions": {
    "skill-registry": true,
    "sdd-init": false,
    "gentle-ai": true,
    "context-mode": true,
    "ask-user": true,
    "graphify": true,
    "codegraph": false,
    "shazam": false,
    "subagents": true,
    "herdr-squad": false,
    "goal": true,
    "docparser": true,
    "obsidian": true,
    "btw": true,
    "simplify": true,
    "rtk-optimizer": false,
    "observational-memory": false,
    "supi-context": false,
    "mcp-adapter": false,
    "planning-with-files": false,
    "plannotator": false,
    "caveman": false,
    "red-green": false,
    "autoresearch": false,
    "web-access": false,
    "kanagawa": false,
    "prompt-template-model": false
  },
  "graph": {
    "warnOnStale": true,
    "autoSuggestUpdate": true
  },
  "defaults": {
    "persona": "gentleman"
  },
  "mcp": {
    "seedOnStart": false
  },
  "projectTrust": {
    "mode": "delegate",
    "remember": false
  }
}
Key / areaBehavior
extensions.*Set to false to skip registering that bundled extension
extensions.gentle-aiDefault true. gentle-pi 2.1.x (bundled ^2.1.2): orchestration, lazy SDD preflight, OpenSpec sync/archive agents, /gentle-ai:doctor / :status. hotmilk keeps startup-banner off (figlet header instead)
extensions.subagentsDefault true. Imports pi-subagents 0.38+ (bundled ^0.38.0): acceptance gates, timeoutMs, resource limits. Use with gentle-ai for delegation; set false for faster startup without Task tools
extensions.btwDefault true. Side conversation via /btw while main runs. Delegate implementation to subagents; use BTW for quick human questions. See pi-btw coexistence
extensions.context-modeDefault true. Prefer ctx_* for large outputs (see project context-window rules)
extensions.observational-memoryDefault false. Compaction continuity; pairs with context-mode. See Workflow routing
extensions.codegraphDefault false. CodeGraph tools (explore / search / impact / …) via @isac322/pi-codegraph; worktree-aware index; overlaps graphify — enable in /mode when wanted
extensions.shazamDefault false. Tree-sitter + LSP execute guards (shazam_impact, shazam_verify); complements graphify — see Workflow routing
extensions.herdr-squadDefault false. Visible read-only Herdr investigation squads (/herdr-squad). Requires Pi inside a Herdr-managed pane (HERDR_ENV=1)
extensions.rtk-optimizerDefault false. Bash/read/grep output compaction; enable with context-mode for leftover shell output. Install rtk CLI for command rewrite (/rtk verify)
extensions.planning-with-filesDefault false. On-disk planning — see Workflow routing
extensions.plannotatorDefault false. Browser plan approval — see Workflow routing
extensions.autoresearchDefault false. Optimize loop — see Workflow routing
extensions.goalmcp-adapterIntegration / perf extensions (formerly always loaded via pi.extensions; now toggled like other bundled deps)
Enabled extensionsLoaded in parallel on session start (faster than sequential import when many toggles are on)
graph.warnOnStaleNotify when graphify-out/needs_update exists
graph.autoSuggestUpdateAppend graphify update . to that notification
defaults.personaSeeds .pi/gentle-ai/persona.json when missing (gentleman | neutral)
defaults.languageAppends a project language hint to the system prompt each turn
mcp.seedOnStartCopy mcp.json template into ~/.pi/agent/mcp.json when missing (empty template; for pi-mcp-adapter)
projectTrust.modePi project trust: delegate (default), prompt, always, or never
projectTrust.rememberWhen mode is always or never, persist the decision in Pi trust.json
extensions.mcp-adapterDefault false. Enable only when you want MCP servers from ~/.pi/agent/mcp.json (do not duplicate context-mode)

MCP (default): context-mode extension registers ctx_* via its built-in bridge (same module as upstream .pi/extensions/context-mode, loaded from build/adapters/pi/extension.js). Hotmilk removes any context-mode server from ~/.pi/agent/mcp.json when the extension is on. Enable mcp-adapter only for other MCP servers—not a second context-mode entry.

/mode groups

/mode sections follow BUNDLED_EXTENSION_GROUP_ORDER in src/config/bundled-extensions.ts:

GroupExtensions (toggle ids)
Harnessskill-registry, sdd-init, gentle-ai
Agent toolsask-user, graphify, codegraph, shazam, prompt-template-model, subagents, herdr-squad, web-access
Context & performancecontext-mode, simplify, rtk-optimizer, observational-memory, supi-context
Integrationsgoal, docparser, obsidian, btw, mcp-adapter
Workflowplanning-with-files, plannotator, red-green
Outputcaveman, kanagawa
Experimentsautoresearch

Workflow routing

Pick one plan authority per task. Memory and optimize loops are not plan paths — they layer beside execution. Full tie-breakers and anti-patterns: bundled pioneer skill.

Plan paths (enable toggle → /reload when default off):

WhenToggle / commandArtifactPioneer reference
Small, bounded fix(none) — chat Plan:chat onlychat-plan.md
Medium scope + browser approvalplannotator/plannotator plans/<name>.mdplans/*.mdplannotator-routing.md
Heavy research, /clear recoveryplanning-with-files/skill:planning-with-filestask_plan.md, findings.md, progress.mdupstream PWF skill
Cross-cutting, spec, >400L reviewgentle-ai → OpenSpec SDDopenspec/changes/<change>/openspec-routing.md

Memory layers (supplementary — never replace plan/spec authority):

NeedPrefer
Large logs, docs, test outputcontext-modectx_*
Rationale across compactionsobservational-memory (extra model cost; V3 needs clean session after upgrade)
User-readable plan filesplanning-with-files
Execute-time impact / LSPshazam (after graphify recon; not a graph replacement)
Codebase graph, worktree-awarecodegraph (alternative index to graphify; prefer one, not both)

Details: observational-memory-routing.md, shazam-routing.md.

Optimize loops (mutually exclusive with SDD/Plannotator on the same task):

NeedPrefer
Metric optimize (bench, bundle size, loss)autoresearch/skill:autoresearch-create
Feature delivery, spec, approval gatesgentle-ai SDD or plannotator — keep autoresearch off
Correctness-first TDDred-green (/tdd)

Stop active loops (/autoresearch off) before switching plan paths. Details: autoresearch-routing.md. Default shortcut Ctrl+Shift+F — override in ~/.pi/agent/extensions/pi-autoresearch.json.

Agents, skills, and scope

Pi resolves bundled assets at user (global), project, and package layers. hotmilk ships package defaults; you override per machine or per repo.

LayerConfigAgents (pi-subagents)Skills / prompts
User (global)~/.pi/agent/hotmilk.json, ~/.pi/agent/settings.json~/.pi/agent/agents/ or ~/.agents/User skill dirs indexed by gentle-pi skill-registry
Project.pi/settings.json.pi/agents/ (canonical); legacy .agents/ still read.pi/skills/; legacy .agents/skills/
Packagepi install npm:hotmilkagents/ in the npm tarball — source of truth in git, not auto-discovered at runtimepackage.jsonpi.skills, pi.prompts, pi.themes (always indexed; extension toggles do not gate these)

Precedence (same runtime name): project → user → builtin (pi-subagents built-ins). /run, chains, and the subagent tool default to agentScope: "both" (user + project + builtin).

hotmilk subagents

  • Edit in git / npm: agents/*.md — package canonical prompts (package: hotmilk in frontmatter → runtime name hotmilk.coach, hotmilk.planner, …).
  • Pi discovery: copy or symlink into .pi/agents/ for the project you are working in. pi-subagents reads project and user dirs only; it does not scan the installed package’s agents/ folder.
  • Parent vs child: the main session runs gentle-ai orchestration (delegation, SDD, skill injection). Subagents get isolated prompts; the parent stays responsible for /run, acceptance blocks, and routing.

After changing prompts in this repo, sync the local project overlay (often untracked):

cp agents/*.md .pi/agents/

Verify with /subagents-doctor — expect hotmilk.* under project agents when .pi/agents/ is populated.

See agents/README.md for the role map (coach, planner, coder, reviewer, …).

Environment variables

Pi and bundled extensions read the process environment. hotmilk itself only defines HOTMILK_CONFIG_ROOT; everything else comes from Pi core or toggled bundled packages.

Pi core (always relevant; full list in Pi usage — environment variables):

VariablePurpose
PI_CODING_AGENT_DIROverride agent config dir (default ~/.pi/agent). Affects hotmilk.json, auth, global agents, MCP path
PI_CODING_AGENT_SESSION_DIROverride session storage (also --session-dir)
PI_PACKAGE_DIROverride package dir (Nix/Guix store paths)
PI_OFFLINEDisable startup network (update checks, package checks, install telemetry)
PI_SKIP_VERSION_CHECKSkip pi.dev latest-version check only
PI_TELEMETRYOpt in/out of install/update telemetry and provider attribution headers (1/0)
PI_CACHE_RETENTIONlong for extended prompt cache where supported
PI_TIMING1 — emit timing diagnostics
PI_HARDWARE_CURSOR1 — show hardware cursor (IME / some terminals)
PI_TUI_WRITE_LOGPath — log raw TUI ANSI to a file (debug)
VISUAL, EDITORExternal editor for Ctrl+G

LLM providers (Pi auth.json → env fallback; not hotmilk-specific): common keys include ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, GOOGLE_API_KEY, OPENROUTER_API_KEY, Azure (AZURE_OPENAI_*), Vertex (GOOGLE_CLOUD_*). See @earendil-works/pi-ai for the full provider table.

hotmilk-owned:

VariablePurpose
HOTMILK_CONFIG_ROOTOverride directory that contains hotmilk.json (default ~/.pi/agent). Tests and sandboxes only; normal installs leave unset

Bundled extensions (only when the matching /mode toggle is on):

VariableToggle / packagePurpose
PI_SUBAGENT_MAX_DEPTHsubagentsMax nested subagent depth (default 2). Do not set PI_SUBAGENT_DEPTH manually
PI_SUBAGENT_INHERIT_PROJECT_CONTEXTsubagents0/false — child skips project context inheritance
PI_SUBAGENT_INHERIT_SKILLSsubagents0/false — child skips skill inheritance
GEMINI_API_KEY, GOOGLE_API_KEYgraphify (CLI)Semantic extraction backend for graphify extract
GRAPHIFY_GEMINI_MODEL, GRAPHIFY_WHISPER_MODELgraphify (CLI)Override graphify LLM / Whisper model
EXA_API_KEY, PERPLEXITY_API_KEY, GEMINI_API_KEYweb-accessSearch / fetch keys (~/.pi/web-search.json also)
PI_ALLOW_BROWSER_COOKIESweb-access1 — allow Chromium cookie extraction for Gemini Web
CTX_FETCH_STRICTcontext-mode1 — stricter fetch routing in context-mode

Internal PI_SUBAGENT_* spawn markers (PI_SUBAGENT_CHILD, PI_SUBAGENT_RUN_ID, …) are set by pi-subagents between parent and child processes — not user configuration.

CI / publish (this repo only): GitHub Actions uses secret NPM_TOKEN; setup-node maps it to NODE_AUTH_TOKEN for npm publish. Local bun publish uses ~/.npmrc, not NPM_TOKEN.

pi-btw with subagents (default on)

Both subagents and btw default to on. They do not share commands or extension IDs; hotmilk loads them in parallel.

Do thisTool
Exploration, implementation, review, SDD phasessubagents (Task, /run, /chain; use worktree: true when running parallel writers)
Ask a quick question while main is working/btw or /btw:tangent (Alt+/ toggles BTW ↔ main)
Bring BTW results back to the main thread/btw:inject

BTW runs a separate Pi session. hotmilk wraps upstream pi-btw (src/extensions/btw.ts):

  • subagents: true (default): read-biased tools only (read, grep, find, ls, bash) — no main-cwd edit/write.
  • graphify: true + graphify-out/graph.json: adds graphify_query (CLI-backed) for architecture questions.
  • context-mode: true: adds ctx_search proxy to the main session knowledge base (read-only).
  • Inherited prompts drop main-session harness noise (gentle-ai orchestrator, graphify rules, caveman); project AGENTS.md stays.
  • Still no ctx_execute, Task, or MCP inside BTW — use main/subagents for heavy ctx work.

Global npm:pi-btw in Pi settings skips the hotmilk shim (standard dedupe). Prefer bundled hotmilk so BTW gets prompt/tool patches via createAgentSession hook.

During subagent chains, avoid BTW file edits on the main cwd; use read-only or :tangent until workers finish.

Set "btw": false in /mode if you want delegation only with no side channel.

Optional extensions (off by default)

Enable in /mode or set the key to true in hotmilk.json, then /reload. Workflow-oriented toggles are summarized in Workflow routing.

TogglePackageNotes
planning-with-files@tomxprime/planning-with-filesOn-disk planning; /skill:planning-with-files
plannotator@plannotator/pi-extension/plannotator, pi --plan; ~37MB UI; plannotator.json
observational-memorypi-observational-memoryCompaction continuity; V3 = clean session after upgrade
supi-context@mrclrchtr/supi-contextContext analysis & formatting; default off
codegraph@isac322/pi-codegraphCodeGraph CLI/MCP wrapper; /codegraph; overlaps graphify — default off
shazampi-shazamshazam_* tools; LSP-backed verify; complements graphify
autoresearchpi-autoresearch/autoresearch, .auto/; shortcut override in pi-autoresearch.json
cavemanpi-cavemanTerse English; conflicts with defaults.language: ja
red-greenpi-red-green/tdd, /tdd-status; ~/.pi/red-green/config.json
web-accesspi-web-accessweb_search, fetch; ~/.pi/web-search.json
herdr-squadpi-herdr-squadVisible read-only Herdr squads; requires HERDR_ENV=1
prompt-template-modelpi-prompt-template-modelPrompt template model selector; default off
kanagawapi-kanagawaTheme; replaces hotmilk footer when on

Alternative skill stacks (not bundled)

hotmilk does not bundle bigpowers — a separate spec-driven skill stack (70+ skills, prompts, MCP). It has no pi.extensions entry, runs postinstall global symlinks, and conflicts with gentle-pi / pioneer plan routing. Install separately if you want that workflow instead of hotmilk's defaults:

pi install npm:bigpowers

Do not enable bigpowers alongside pioneer OpenSpec/Plannotator on the same task. See .agents/plans/EXTENSIONS.md §L8.

latchkey (API credential injection via /skill:latchkey) is also not bundled — install with pi install npm:latchkey if needed.

Cursor models (optional, not bundled)

hotmilk does not ship @netandreus/pi-cursor-provider. Install when you route Pi through the Cursor Agent CLI:

pi install npm:@netandreus/pi-cursor-provider
agent login
# then in Pi: /model cursor/auto

Development

Requires Node.js 22+ (or Bun 1.3+), Bun for installs in this repo, and Pi 0.84 peers in the environment.

bun install       # commit bun.lock; peers resolved by Bun
bun test          # vitest via vite-plus
bun run lint
bun run check     # lint + format + test

npm install still works with this repo’s .npmrc (legacy-peer-deps=true). This repo commits bun.lock only (no package-lock.json); CI uses Bun (bun install --frozen-lockfile).

CI and release

On push to main, GitHub Actions runs lint + test, then a publish job (needs: test) when hotmilk@<package.json version> is not already on npm. No separate workflow or tag push is required to start publish.

push main → test → publish (npm publish --provenance) → git tag v<version>

Bump version in package.json before pushing to main.

GitHub secret NPM_TOKEN (required for CI publish):

  1. npm Access TokensGranular Access Token or Classic Automation token
  2. Scope: publish to hotmilk (or classic publish on the account)
  3. Repository → Settings → Secrets → Actions → name NPM_TOKEN

CI uses npm’s CI/CD workflow: actions/setup-node with registry-url, then npm publish --provenance --access public with NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}. The secret is named NPM_TOKEN; setup-node reads NODE_AUTH_TOKEN for auth. Dependencies are not bundled into the tarball (bundleDependencies removed — npm rejected the 162 MB hard-linked bundle with E415).

Trusted Publisher on npm can stay configured or be removed; CI uses the token path above.

GitHub Release is optional — npm publish does not require it.

Local publish: npm login once, then npm publish --access public. Or add the token to ~/.npmrc (not the repo .npmrc):

echo "//registry.npmjs.org/:_authToken=YOUR_NPM_TOKEN" >> ~/.npmrc
npm publish --access public

bun publish also works locally if ~/.npmrc has a token; it does not read the NPM_TOKEN environment variable by itself.

Layout

PathRole
src/index.tsExtension entry: config, bundled extensions, session UI, input routing
src/config/hotmilk.tshotmilk.json load / seed / save
agents/Package-canonical subagent prompts (package: hotmilk); install into .pi/agents/ for discovery
prompts/, skills/, themes/Shipped with the package (pi.prompts, pi.skills, pi.themes); workflow routing in skills/pioneer/
mcp.jsonMCP server template for local projects
hotmilk.jsonDefault toggle template (published in the npm package)

License

MIT — Copyright (c) 2026 dayjobdoor. Bundled dependencies keep their own licenses (for example gentle-pi is MIT).

Contributing

Issues and PRs are welcome. When you add an extension, skill, or workflow, document how to enable it (toggle key, settings path, or command) in this README.