250 lines
9.5 KiB
Nix
250 lines
9.5 KiB
Nix
{
|
|
den,
|
|
modules,
|
|
inputs,
|
|
...
|
|
}:
|
|
{
|
|
modules.pi-coding = {
|
|
homeManager =
|
|
{ pkgs, config, ... }:
|
|
{
|
|
programs.pi-coding-agent = {
|
|
enable = true;
|
|
extraPackages = [
|
|
pkgs.nodejs
|
|
# pkgs.lean-lsp-mcp
|
|
];
|
|
settings = {
|
|
"litellm" = {
|
|
"providers" = {
|
|
"litellm" = {
|
|
"displayName" = "scuggo";
|
|
"baseUrl" = "https://ai-proxy.fwds.scug.io";
|
|
"apiKey" = "$SCUG_IO_API_KEY";
|
|
"compat" = {
|
|
"sendSessionAffinityHeaders" = true;
|
|
};
|
|
};
|
|
};
|
|
"skills" = {
|
|
"enabled" = true;
|
|
};
|
|
"compat" = {
|
|
"sendSessionAffinityHeaders" = true;
|
|
};
|
|
};
|
|
"mcp" = {
|
|
"enabled" = true;
|
|
};
|
|
"uiMode" = "fullscreen";
|
|
"showCacheMissNotices" = true;
|
|
"vstack" = {
|
|
"extensionManager" = {
|
|
"config" = { };
|
|
};
|
|
};
|
|
packages = [
|
|
# "npm:@odinlayer/pi-provider-litellm"
|
|
"npm:pi-provider-litellm"
|
|
# Web search / content extraction (opencode-crawlberg + opencode-html-to-markdown equivalent)
|
|
"npm:pi-web-access"
|
|
# Local document parsing / OCR (opencode-xberg equivalent)
|
|
"npm:pi-docparser"
|
|
# "npm:@gotgenes/pi-permission-system"
|
|
"npm:@vanillagreen/pi-extension-manager"
|
|
# "npm:@vanillagreen/pi-qol"
|
|
"npm:pi-vitals"
|
|
"npm:pi-spark"
|
|
# "npm:pi-caveman"
|
|
"npm:@tmustier/pi-usage-extension"
|
|
"npm:@heyhuynhgiabuu/pi-pretty"
|
|
"npm:pi-lens"
|
|
# "npm:pi-lean-ctx"
|
|
# "npm:@rohaquinlop/pi-deepseek-cache"
|
|
"npm:pi-cache-optimizer"
|
|
"npm:pi-opencode-go-cache"
|
|
"npm:@pi-vault/pi-dcp"
|
|
"git:github.com/DietrichGebert/ponytail"
|
|
];
|
|
};
|
|
context = ''
|
|
Core Directive: precise execution, strict safety, long-term solutions.
|
|
1. Standards: hard fail unless overridden; files <=300 lines (refactor if exceeded); no hardcoding — config/env/consts only; no defaults — fail on missing config; no legacy/shims/auto-migrations, assume clean state; root fixes only, no cosmetic patches (report unrelated bugs).
|
|
2. Safety: never run destructive ops (rm, reset --hard, deletions) without explicit prior approval; respect sandbox mode (ro/write), request approval if blocked; new code = creative, existing code = minimal deltas (no style/rename drift).
|
|
3. Tools: todowrite for multi-step — exactly one in_progress, update on completion; rg for search; outputs truncated (~256 lines/10KB), read large files in chunks (<250 lines); edit = trust tool, no re-read, no added headers/comments; build/test/lint before yielding, yield only after todowrite done.
|
|
4. Communication: AGENTS.md governs — deepest file wins, user prompt overrides; 1-sentence next-action preamble before any tool call; final output GFM with clickable file refs (src/main.ts:50), no file://, technical/dense/impersonal.
|
|
|
|
[CORE TOOLING DOCTRINE]
|
|
- Files: read truncates at 2000 lines/50KB (use offset/limit); write creates/overwrites/auto-parents; edit = smallest unique oldText, merge nearby, never include huge unchanged regions. Never cat/echo/tee/sed -i/head/tail for file content.
|
|
- Search: rg -n for text; grep tool (glob filter) for content; find tool for glob discovery only.
|
|
- Navigation: symbol_search → module_report → read_symbol/read_enclosing; never find + manual parsing.
|
|
- Diagnostics: lens_diagnostics (delta=this turn, all=session, full=project-wide before done); lsp_diagnostics before builds.
|
|
- Context: recall_context(id) to recover compressed/expired/truncated content.
|
|
- bash: only for git/nix/builds/scripts/network/system mgmt; set timeout for long ops.
|
|
- CRITICAL: never find on /nix/store — unpruned walk locks up execution; ls known paths, ask user for unknown paths. ABSOLUTE.
|
|
- You have a web-search tool. Use it sparingly but reach for it in situations where info isnt directly known. (i.e, "common problem" -> get from memory, think hard if needed, "hard problem that isnt in your training data or request for you to read docs for a lib or program" -> search online)
|
|
- Searching for anything (including with wildcards ("/nix/store/*/**" or others)) isnt permitted at all. You must find paths inside the project, such a result/
|
|
'';
|
|
};
|
|
|
|
# pi-vitals config
|
|
home.file.".pi/agent/powerline.json" = {
|
|
text = builtins.toJSON {
|
|
leftSegments = [
|
|
"pi"
|
|
"separator"
|
|
"model"
|
|
"thinking"
|
|
"ext_status"
|
|
"separator"
|
|
"path"
|
|
"git"
|
|
"separator"
|
|
"token_total"
|
|
"token_in"
|
|
"token_out"
|
|
"cache_read"
|
|
"cache_write"
|
|
];
|
|
rightSegments = [
|
|
"separator"
|
|
"cost"
|
|
"model_cost"
|
|
"context_pct"
|
|
];
|
|
icons = {
|
|
pi = "π";
|
|
model = "◈";
|
|
thinking = "🧠";
|
|
folder = "📁";
|
|
repo = "📦";
|
|
git = "⎇";
|
|
tokens = "⊛";
|
|
input = "↑";
|
|
output = "↓";
|
|
cacheRead = "↙";
|
|
cacheWrite = "↗";
|
|
contextPct = "◫";
|
|
cost = "$";
|
|
modelCost = "(in/out)";
|
|
separator = "│";
|
|
};
|
|
colors = {
|
|
pi = "accent";
|
|
model = "#d787af";
|
|
path = "#00afaf";
|
|
git = "success";
|
|
gitDirty = "warning";
|
|
gitClean = "success";
|
|
thinking = "muted";
|
|
context = "dim";
|
|
contextWarn = "warning";
|
|
contextError = "error";
|
|
cost = "text";
|
|
modelCost = "text";
|
|
tokens = "muted";
|
|
separator = "dim";
|
|
};
|
|
segmentOptions = {
|
|
path = {
|
|
mode = "basename";
|
|
};
|
|
git = {
|
|
showBranch = true;
|
|
showStaged = true;
|
|
showUnstaged = true;
|
|
showUntracked = true;
|
|
};
|
|
context_pct = {
|
|
showAutoIcon = false;
|
|
};
|
|
};
|
|
};
|
|
};
|
|
home.file.".pi/agent/auth.json" = {
|
|
text = builtins.toJSON {
|
|
"opencode-go" = {
|
|
"type" = "api_key";
|
|
"key" = "$OPENCODE_GO_API_KEY";
|
|
};
|
|
"opencode" = {
|
|
"type" = "api_key";
|
|
"key" = "$OPENCODE_GO_API_KEY";
|
|
};
|
|
};
|
|
};
|
|
|
|
# Cache/routing compat overrides (provider-level minimal)
|
|
home.file.".pi/agent/models.json" = {
|
|
text = builtins.toJSON {
|
|
providers = {
|
|
"opencode-go" = {
|
|
compat = {
|
|
supportsLongCacheRetention = true;
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
# Restrict providers to a subset of their built-in models.
|
|
# Filter config: ~/.pi/agent/model-filters.json (see below).
|
|
home.file.".pi/agent/extensions/model-filter.ts" = {
|
|
source = ./model-filter.ts;
|
|
};
|
|
|
|
# Show model cost in status bar
|
|
home.file.".pi/agent/extensions/model-cost.ts" = {
|
|
source = ./model-cost.ts;
|
|
};
|
|
|
|
# Model filter config: per-provider filters applied by model-filter.ts
|
|
home.file.".pi/agent/model-filters.json" = {
|
|
text = builtins.toJSON {
|
|
providers = {
|
|
# opencode: only free models (all cost zero)
|
|
opencode = {
|
|
freeOnly = true;
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
# pi-web-access config: raw results, no curator / no AI summarising
|
|
home.file.".pi/web-search.json" = {
|
|
text = builtins.toJSON {
|
|
workflow = "none";
|
|
};
|
|
};
|
|
|
|
# pi-spark config
|
|
home.file.".pi/agent/spark.json" = {
|
|
text = builtins.toJSON {
|
|
editor = {
|
|
spinner = "tildes";
|
|
};
|
|
footer = false;
|
|
presets = {
|
|
"scuggo" = {
|
|
provider = "litellm";
|
|
model = "Ornith-1.0-9B";
|
|
thinkingLevel = "medium";
|
|
};
|
|
"claude" = {
|
|
provider = "anthropic";
|
|
model = "claude-opus-4-8";
|
|
thinkingLevel = "high";
|
|
};
|
|
"gpt" = {
|
|
provider = "openai-codex";
|
|
model = "gpt-5.5";
|
|
thinkingLevel = "medium";
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
}
|