better configs

This commit is contained in:
Thomas G. Lopes
2026-03-04 19:43:09 +00:00
parent 9a68fb34bf
commit 94b95291ed
26 changed files with 2842 additions and 105 deletions
+6
View File
@@ -0,0 +1,6 @@
---@meta
---Configuration type for Sigil dotfile manager
---@class SigilConfig
---@field target table<string, string|boolean> Platform-specific target paths (linux, macos, windows, default). Use `false` to disable on a platform.
---@field ignore? string[] Array of glob patterns to ignore when applying symlinks
+11
View File
@@ -0,0 +1,11 @@
{
"$schema": "https://raw.githubusercontent.com/LuaLS/LLS-Addons/main/schemas/luarc.json",
"runtime.version": "Lua 5.4",
"diagnostics": {
"enable": true,
"globals": []
},
"completion": {
"enable": true
}
}
+1
View File
@@ -1,3 +1,4 @@
---@type SigilConfig
return { return {
target = { target = {
linux = "~", linux = "~",
+1
View File
@@ -1,3 +1,4 @@
---@type SigilConfig
return { return {
target = { target = {
linux = "~/.config/alacritty", linux = "~/.config/alacritty",
+1
View File
@@ -1,3 +1,4 @@
---@type SigilConfig
return { return {
target = { target = {
linux = "~/.config/fish", linux = "~/.config/fish",
+1
View File
@@ -1,3 +1,4 @@
---@type SigilConfig
return { return {
target = { target = {
linux = "~/.config/foot", linux = "~/.config/foot",
+1
View File
@@ -1,3 +1,4 @@
---@type SigilConfig
return { return {
target = { target = {
linux = "~/.config/jj", linux = "~/.config/jj",
+1
View File
@@ -1,3 +1,4 @@
---@type SigilConfig
return { return {
target = { target = {
linux = "~/.config/jjui", linux = "~/.config/jjui",
+1
View File
@@ -1,3 +1,4 @@
---@type SigilConfig
return { return {
target = { target = {
linux = "~/.config/kitty", linux = "~/.config/kitty",
+1
View File
@@ -1,3 +1,4 @@
---@type SigilConfig
return { return {
target = { target = {
linux = "~/.config/matugen", linux = "~/.config/matugen",
+1
View File
@@ -1,3 +1,4 @@
---@type SigilConfig
return { return {
target = { target = {
linux = "~/.config/niri", linux = "~/.config/niri",
+1
View File
@@ -1,3 +1,4 @@
---@type SigilConfig
return { return {
target = { target = {
linux = "~/.config/nvim", linux = "~/.config/nvim",
+6
View File
@@ -7,6 +7,12 @@ return {
completion = { completion = {
callSnippet = "Replace", callSnippet = "Replace",
}, },
workspace = {
library = {
vim.env.VIMRUNTIME,
},
checkThirdParty = false,
},
}, },
}, },
} }
+1
View File
@@ -1,3 +1,4 @@
---@type SigilConfig
return { return {
target = { target = {
linux = "~/.config/opencode", linux = "~/.config/opencode",
+1
View File
@@ -1,3 +1,4 @@
---@type SigilConfig
return { return {
target = { target = {
linux = "~/.config/paru", linux = "~/.config/paru",
+5
View File
@@ -1,6 +1,11 @@
---@type SigilConfig
return { return {
target = { target = {
linux = "~/.pi", linux = "~/.pi",
default = "~/.pi", default = "~/.pi",
}, },
ignore = {
"**/node_modules",
"pnpm_lock.yaml",
},
} }
+12
View File
@@ -0,0 +1,12 @@
{
"name": "pi-extensions",
"private": true,
"type": "module",
"devDependencies": {
"typescript": "^5.7.0",
"@mariozechner/pi-coding-agent": "^0.55.3",
"@mariozechner/pi-tui": "^0.55.3",
"@mariozechner/pi-ai": "^0.55.3",
"@sinclair/typebox": "^0.34.0"
}
}
File diff suppressed because it is too large Load Diff
+118 -103
View File
@@ -16,131 +16,146 @@ let turnStartTime: number | null = null;
let lastTurnDuration: number | null = null; let lastTurnDuration: number | null = null;
function formatTime(date: Date): string { function formatTime(date: Date): string {
return date.toLocaleTimeString("en-US", { return date.toLocaleTimeString("en-US", {
hour: "2-digit", hour: "2-digit",
minute: "2-digit", minute: "2-digit",
second: "2-digit", second: "2-digit",
hour12: false, hour12: false,
}); });
} }
function formatElapsed(ms: number): string { function formatElapsed(ms: number): string {
const seconds = Math.floor(ms / 1000); const seconds = Math.floor(ms / 1000);
const minutes = Math.floor(seconds / 60); const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60); const hours = Math.floor(minutes / 60);
if (hours > 0) return `${hours}h ${minutes % 60}m`; if (hours > 0) return `${hours}h ${minutes % 60}m`;
if (minutes > 0) return `${minutes}m ${seconds % 60}s`; if (minutes > 0) return `${minutes}m ${seconds % 60}s`;
return `${seconds}s`; return `${seconds}s`;
} }
function formatDuration(ms: number): string { function formatDuration(ms: number): string {
if (ms < 1000) return `${ms}ms`; if (ms < 1000) return `${ms}ms`;
if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`; if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;
return `${(ms / 60000).toFixed(1)}m`; return `${(ms / 60000).toFixed(1)}m`;
} }
export default function (pi: ExtensionAPI) { export default function (pi: ExtensionAPI) {
const updateStatus = (ctx: { ui: { setStatus: (id: string, text: string | undefined) => void; theme: { fg: (color: string, text: string) => string } } }) => { const updateStatus = (ctx: {
const elapsed = Date.now() - sessionStart; ui: {
let status = ctx.ui.theme.fg("dim", `${formatElapsed(elapsed)}`); setStatus: (id: string, text: string | undefined) => void;
if (lastTurnDuration !== null) { theme: { fg: (color: string, text: string) => string };
status += ctx.ui.theme.fg("muted", ` | took ${formatDuration(lastTurnDuration)}`); };
} }) => {
ctx.ui.setStatus("timestamps", status); const elapsed = Date.now() - sessionStart;
}; let status = ctx.ui.theme.fg("dim", `${formatElapsed(elapsed)}`);
if (lastTurnDuration !== null) {
status += ctx.ui.theme.fg(
"muted",
` | took ${formatDuration(lastTurnDuration)}`,
);
}
ctx.ui.setStatus("timestamps", status);
};
// Renderer for user timestamp // Renderer for user timestamp
pi.registerMessageRenderer("timestamp-prefix", (message, _options, theme) => { pi.registerMessageRenderer("timestamp-prefix", (message, _options, theme) => {
const details = message.details as { timestamp: number; elapsed: string } | undefined; const details = message.details as
if (!details) return new Text(""); | { timestamp: number; elapsed: string }
| undefined;
if (!details) return new Text("");
const timeStr = formatTime(new Date(details.timestamp)); const timeStr = formatTime(new Date(details.timestamp));
const line = theme.fg("dim", `${timeStr} (+${details.elapsed})`); const line = theme.fg("dim", ` ${timeStr} (+${details.elapsed})`);
const box = new Box(0, 0, undefined); const box = new Box(0, 0, undefined);
box.addChild(new Text(line, 0, 0)); box.addChild(new Text(line, 0, 0));
return box; return box;
}); });
// Renderer for legacy timestamp-suffix messages (from old sessions) // Renderer for legacy timestamp-suffix messages (from old sessions)
pi.registerMessageRenderer("timestamp-suffix", (message, _options, theme) => { pi.registerMessageRenderer("timestamp-suffix", (message, _options, theme) => {
const details = message.details as { timestamp: number; elapsed: string; duration?: number } | undefined; const details = message.details as
if (!details) return new Text(""); | { timestamp: number; elapsed: string; duration?: number }
| undefined;
if (!details) return new Text("");
const timeStr = formatTime(new Date(details.timestamp)); const timeStr = formatTime(new Date(details.timestamp));
let line = `${timeStr} (+${details.elapsed})`; let line = `${timeStr} (+${details.elapsed})`;
if (details.duration && details.duration > 1000) { if (details.duration && details.duration > 1000) {
line += ` • took ${formatDuration(details.duration)}`; line += ` • took ${formatDuration(details.duration)}`;
} }
const box = new Box(0, 0, undefined); const box = new Box(0, 0, undefined);
box.addChild(new Text(theme.fg("dim", line), 0, 0)); box.addChild(new Text(theme.fg("dim", line), 0, 0));
return box; return box;
}); });
// Start timer on session start // Start timer on session start
pi.on("session_start", async (_event, ctx) => { pi.on("session_start", async (_event, ctx) => {
sessionStart = Date.now(); sessionStart = Date.now();
turnStartTime = null; turnStartTime = null;
lastTurnDuration = null; lastTurnDuration = null;
if (timerHandle) clearInterval(timerHandle); if (timerHandle) clearInterval(timerHandle);
timerHandle = setInterval(() => updateStatus(ctx), 1000); timerHandle = setInterval(() => updateStatus(ctx), 1000);
updateStatus(ctx); updateStatus(ctx);
}); });
// Track turn timing // Track turn timing
pi.on("turn_start", async () => { pi.on("turn_start", async () => {
turnStartTime = Date.now(); turnStartTime = Date.now();
}); });
pi.on("turn_end", async (_event, ctx) => { pi.on("turn_end", async (_event, ctx) => {
if (turnStartTime !== null) { if (turnStartTime !== null) {
lastTurnDuration = Date.now() - turnStartTime; lastTurnDuration = Date.now() - turnStartTime;
turnStartTime = null; turnStartTime = null;
updateStatus(ctx); updateStatus(ctx);
} }
if (lastTurnDuration !== null) { if (lastTurnDuration !== null) {
const now = Date.now(); const now = Date.now();
const elapsed = formatElapsed(now - sessionStart); const elapsed = formatElapsed(now - sessionStart);
const timeStr = formatTime(new Date(now)); const timeStr = formatTime(new Date(now));
let line = `${timeStr} (+${elapsed})`; let line = `${timeStr} (+${elapsed})`;
if (lastTurnDuration > 1000) { if (lastTurnDuration > 1000) {
line += ` • took ${formatDuration(lastTurnDuration)}`; line += ` • took ${formatDuration(lastTurnDuration)}`;
} }
ctx.ui.notify(line, "info"); ctx.ui.notify(line, "info");
} }
}); });
// Strip old timestamp-suffix messages from LLM context // Strip old timestamp-suffix messages from LLM context
pi.on("context", async (event) => { pi.on("context", async (event) => {
const messages = event.messages.filter( const messages = event.messages.filter(
(m: any) => m.role !== "custom" || (m.customType !== "timestamp-prefix" && m.customType !== "timestamp-suffix") (m: any) =>
); m.role !== "custom" ||
return { messages }; (m.customType !== "timestamp-prefix" &&
}); m.customType !== "timestamp-suffix"),
);
return { messages };
});
// Inject timestamp marker right before agent starts (inline, persistent) // Inject timestamp marker right before agent starts (inline, persistent)
pi.on("before_agent_start", async () => { pi.on("before_agent_start", async () => {
const now = Date.now(); const now = Date.now();
const elapsed = formatElapsed(now - sessionStart); const elapsed = formatElapsed(now - sessionStart);
return { return {
message: { message: {
customType: "timestamp-prefix", customType: "timestamp-prefix",
content: ".", content: ".",
display: true, display: true,
details: { timestamp: now, elapsed }, details: { timestamp: now, elapsed },
}, },
}; };
}); });
// Clean up on shutdown // Clean up on shutdown
pi.on("session_shutdown", async () => { pi.on("session_shutdown", async () => {
if (timerHandle) { if (timerHandle) {
clearInterval(timerHandle); clearInterval(timerHandle);
timerHandle = null; timerHandle = null;
} }
}); });
} }
+12
View File
@@ -0,0 +1,12 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "Bundler",
"strict": true,
"noEmit": true,
"skipLibCheck": true,
"types": ["node"]
},
"include": ["**/*.ts"]
}
+2 -2
View File
@@ -1,8 +1,8 @@
{ {
"lastChangelogVersion": "0.55.4", "lastChangelogVersion": "0.55.4",
"defaultProvider": "openrouter", "defaultProvider": "openrouter",
"defaultModel": "openai/gpt-5.3-codex", "defaultModel": "z-ai/glm-5",
"defaultThinkingLevel": "minimal", "defaultThinkingLevel": "off",
"theme": "matugen", "theme": "matugen",
"lsp": { "lsp": {
"hookMode": "edit_write" "hookMode": "edit_write"
+1
View File
@@ -1,3 +1,4 @@
---@type SigilConfig
return { return {
target = { target = {
linux = "~/scripts", linux = "~/scripts",
+1
View File
@@ -1,3 +1,4 @@
---@type SigilConfig
return { return {
target = { target = {
linux = "~/.ssh", linux = "~/.ssh",
+1
View File
@@ -1,3 +1,4 @@
---@type SigilConfig
return { return {
target = { target = {
linux = "~/.config/wezterm", linux = "~/.config/wezterm",
+1
View File
@@ -1,3 +1,4 @@
---@type SigilConfig
return { return {
target = { target = {
linux = "~/.config/yazi", linux = "~/.config/yazi",
+1
View File
@@ -1,3 +1,4 @@
---@type SigilConfig
return { return {
target = { target = {
linux = "~/.config/zellij", linux = "~/.config/zellij",