{"id":50945852,"url":"https://github.com/phiat/project-pat","last_synced_at":"2026-06-17T20:05:19.394Z","repository":{"id":359712291,"uuid":"1247198751","full_name":"phiat/project-pat","owner":"phiat","description":"Single-user workshop for ideation, periodic research, and design-doc drafting — htmx-over-go, sqlite, multi-provider LLM agents.","archived":false,"fork":false,"pushed_at":"2026-05-23T04:40:42.000Z","size":603,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-23T05:23:59.955Z","etag":null,"topics":["agents","go","htmx","project-template","sqlite"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/phiat.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-23T02:37:40.000Z","updated_at":"2026-05-23T04:42:24.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/phiat/project-pat","commit_stats":null,"previous_names":["phiat/project-pat"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/phiat/project-pat","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phiat%2Fproject-pat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phiat%2Fproject-pat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phiat%2Fproject-pat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phiat%2Fproject-pat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/phiat","download_url":"https://codeload.github.com/phiat/project-pat/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phiat%2Fproject-pat/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34463560,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-17T02:00:05.408Z","response_time":127,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agents","go","htmx","project-template","sqlite"],"created_at":"2026-06-17T20:05:18.339Z","updated_at":"2026-06-17T20:05:19.387Z","avatar_url":"https://github.com/phiat.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# project-pat\n\n![go](https://img.shields.io/badge/go-1.26-00ADD8?logo=go\u0026logoColor=white)\n![htmx](https://img.shields.io/badge/htmx-2-3D72D7?logo=htmx\u0026logoColor=white)\n![sqlite](https://img.shields.io/badge/sqlite-pure--go-003B57?logo=sqlite\u0026logoColor=white)\n![providers](https://img.shields.io/badge/llm-7%20providers-6f42c1)\n![status](https://img.shields.io/badge/status-scaffolding-orange)\n![license](https://img.shields.io/badge/license-MIT-blue)\n\n![overview](docs/overview.png)\n\n![ideas (light theme)](docs/ideas-light.webp)\n\na single-user workshop for ideation, periodic research, and design-doc drafting — htmx-over-go with multi-provider LLM agents and a cron scheduler.\n\n\u003e **status**: scaffolding, but the loop is closed: ideas → projects → drafted/critiqued/reconciled design docs → workspace artifacts on disk → optional runnable prototype skeleton. Cron-scheduled agents and a manual run-now path feed the inbox; the workshop floor surfaces what's asking for attention.\n\n## what's wired\n\n- **`/`** — overview: counts + recent runs + streaming quick-draft form (creates an idea and seeds it via flash).\n- **`/floor`** — *the workshop floor*. One tile per project, sorted by an attention score (empty doc, critique pending, unread inbox, staleness). Each tile shows the last paragraph of the doc, the last resolved decision, and a one-button next action.\n- **`/ideas`** — capture pad; promote an idea to a project.\n- **`/projects`** — project list; create from scratch or via promote. Archive/unarchive to keep the working set tight.\n- **`/projects/:id`** — the heart of the workshop. Streaming panels for:\n  - **design doc** — draft / refine via flash or pro\n  - **team draft** — sequential planner → critic → drafter pro chain; intermediate plan + critic notes are persisted as artifacts; SSE `phase` events anchor the UI between passes\n  - **scaffold prototype** — pro emits a JSON file manifest; the server sanitises paths and writes a runnable skeleton to `workspace/\u003cslug\u003e/proto/` (the workshop generates it; running it is up to you)\n  - **critique** — pro critic produces a scorecard + numbered weaknesses + concrete edits; \"apply critique\" runs a second pro pass that refines the doc against those notes\n  - **stack picker** — slot-by-slot tech-stack selector (runtime / framework / storage / deploy / …) with presets, version pins, and an incompat warning when runtime changes invalidate prior picks. Stack context is auto-injected into every project-scoped prompt\n  - **devil's office hours** — pro \"devil\" reads the doc + latest critique + the resolved decisions and asks one sharp committing question; you answer ≤280 chars and the answer becomes a load-bearing decision in the prompt context of every later pass\n  - **research brief** — pro brief with claims, counter-claims, open questions, and a parsed reading list. Items are an interactive checklist; per-item notes persist\n  - **reconcile against notes** — once you've actually read some items, pro re-reads the brief through the lens of your per-item notes and emits a Confirmed / Complicated / New questions / Next moves reconciliation\n  - **standing orders** — agents scoped to this project; their prompt is auto-templated with the live design doc on every run\n  - **timeline** — recent runs touching the project (any trigger)\n  - **materialize** — one click writes the current state (design doc, critique, brief + reading-list notes, reconcile, decisions, stack) to `workspace/\u003cslug\u003e/` as a set of Markdown files\n- **`/agents`** — define cron-scheduled missions globally (or scope them via standing orders on a project). \"run now\" fires off-thread. Agent CRUD pings the scheduler in-process; new schedules are live within milliseconds, not 30 seconds.\n- **`/board`** — your idea constellation. Click *cluster ideas* and a pro agent groups them into themes and emits weighted edges; the view renders as a 2D force-directed graph over the landscape. Click two nodes to select them and hit *synthesize* — pro writes a unified design doc for the combined project and you land on it.\n- **`/inbox`** — agent reports (cron + manual) land here with unread badges, star, and a token-refined line diff vs the previous successful run by the same agent. Opening an item marks it read.\n- **`/runs`** — full LLM run log with token usage, errors, and expandable rendered output.\n\nAll LLM endpoints stream over SSE; the UI shows tokens arriving in real-time, then swaps in rendered markdown when the stream ends. Reasoning-model chain-of-thought (DeepSeek `reasoning_content` / Anthropic `thinking_delta`) streams as a separate `reasoning` event and renders in muted italics above the content — so the thinking phase doesn't read as a frozen UI. A `meta` event with run id + provider/model/effort lands before the first token. If the client disconnects mid-stream, the partial output is preserved in the run row (`status='cancelled'`) instead of being thrown away; orphaned `running` rows from a crashed process are reaped on the next server start.\n\n## run it\n\n```bash\nmise install                # installs a Go toolchain per mise.toml (or use any Go ≥ 1.26 directly)\ngo mod tidy\ngo run ./cmd/pat server    # or: just run\n```\n\nThen open \u003chttp://localhost:8080\u003e. `just` (no args) lists the available recipes — `just repl`, `just build`, `just test`, `just check`, `just pat \u003csubcommand\u003e`.\n\nThere's also a CLI / REPL over the same DB — run `go run ./cmd/pat help` for the full list. Highlights:\n```\npat ideas add \"title\" [body]    pat projects list [--archived]    pat projects materialize \u003cid\u003e\npat agents run \u003cid\u003e             pat inbox list [--unread]         pat repl\n```\nSQLite WAL lets the CLI and the server share the same db file safely.\n\nRequired `.env`:\n```\n# Generic LLM config (any OpenAI-compatible provider, or Anthropic):\nLLM_PROVIDER=deepseek       # openai | deepseek | anthropic | openrouter | ollama | groq | together\nLLM_API_KEY=sk-...          # falls back to DEEPSEEK_API_KEY / OPENAI_API_KEY / ANTHROPIC_API_KEY\n# LLM_BASE_URL=...          # override base URL; each provider has a sensible default\n# LLM_MODEL_FLASH=...       # tier 1: fast/cheap (per-provider default)\n# LLM_MODEL_PRO=...         # tier 2: deeper/slower (per-provider default)\n# LLM_REASONING_FLASH=off   # off | minimal | low | medium | high  (default: off)\n# LLM_REASONING_PRO=medium  # off | minimal | low | medium | high  (default: medium)\n\n# HTTP:\n# HOST=0.0.0.0              # bind address; default 0.0.0.0 (LAN/Tailscale-reachable). Set to 127.0.0.1 to lock to localhost.\n# PORT=8080\n# DB_PATH=projectpat.db\n```\n\nThe server binds on `0.0.0.0` by default — reachable on `http://localhost:8080`, your LAN IP, and your Tailscale IP. There's no auth (single-user tool), so don't expose it to the public internet without putting it behind a reverse proxy / VPN / SSH tunnel.\n\n### Provider defaults\n\n| provider     | base URL (default)                       | flash default              | pro default                  |\n|--------------|------------------------------------------|----------------------------|------------------------------|\n| `deepseek`   | `https://api.deepseek.com/v1`            | `deepseek-v4-flash`        | `deepseek-v4-pro`            |\n| `openai`     | `https://api.openai.com/v1`              | `gpt-4o-mini`              | `gpt-4o`                     |\n| `anthropic`  | `https://api.anthropic.com/v1`           | `claude-haiku-4-5-20251001`| `claude-opus-4-7`            |\n| `openrouter` | `https://openrouter.ai/api/v1`           | _(set explicitly)_         | _(set explicitly)_           |\n| `ollama`     | `http://localhost:11434/v1`              | _(set explicitly)_         | _(set explicitly)_           |\n| `groq`       | `https://api.groq.com/openai/v1`         | `llama-3.1-8b-instant`     | `llama-3.3-70b-versatile`    |\n| `together`   | `https://api.together.xyz/v1`            | _(set explicitly)_         | _(set explicitly)_           |\n\nAll non-Anthropic providers go through one OpenAI-compatible driver. Anthropic gets its own `/v1/messages` driver (with SSE streaming). Legacy `DEEPSEEK_*` env names still work for back-compat.\n\n### Reasoning / thinking effort\n\nPer-tier knob: `off | minimal | low | medium | high`. Mapped to `reasoning_effort` on OpenAI-style providers and to `thinking.budget_tokens` on Anthropic. Silently ignored where the model doesn't accept it.\n\n## stack\n\n- **go 1.26** (HTTP server, `html/template`, stdlib mux)\n- **sqlite** (`modernc.org/sqlite` — pure-go, no cgo) with single-writer connection pool\n- **htmx 2** + a small dark css (palette: black forest / dry sage / beige / baltic blue / bright snow / platinum)\n- **three.js** background — tessellated cubic landscape, plane-window vantage, slow forward drift, periodic hue cycle, drifting accent lights\n- **multi-provider LLMs** — OpenAI / DeepSeek / Anthropic / OpenRouter / Ollama / Groq / Together; two tier keys (`flash` for quick drafts, `pro` for deeper passes), optional reasoning/thinking budget per tier\n- **robfig/cron** for the agent scheduler, with in-process notify so agent CRUD reschedules immediately\n\n## layout\n\n```\ncmd/pat/                             single binary — `server`, `repl`, plus subcommands\ninternal/\n  config/      .env loader + paths\n  db/          sqlite open + migrations\n  store/       data access (ideas, projects, agents, runs, artifacts,\n               brief items, idea clusters, idea links, stack picks)\n  llm/         provider-agnostic client + openai/anthropic drivers\n  stack/       runtime catalog (slots, options, presets, compat rules)\n  handlers/    HTTP handlers (htmx partials)\n  workspace/   materializer — writes design doc, decisions, brief,\n               critique, stack, etc. to workspace/\u003cslug\u003e/ as Markdown\n  scheduler/   cron loop that ticks scheduled agents\n  web/\n    templates.go        + templates/  (layout + page templates)\n    static/css/app.css\n    static/js/background.js\ndocs/             screenshots + reference material referenced by README\nworkspace/        per-project workdirs (gitignored) — materialized\n                  artifacts and scaffolded prototypes land under\n                  workspace/\u003cslug\u003e/\n```\n\n## license\n\nMIT — see [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphiat%2Fproject-pat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphiat%2Fproject-pat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphiat%2Fproject-pat/lists"}