From c242a0ca532f6bf0043dcf6dac288b423e9fb458 Mon Sep 17 00:00:00 2001 From: "Thomas G. Lopes" Date: Thu, 19 Feb 2026 22:18:38 +0000 Subject: [PATCH] yay --- matugen/files/config.toml | 5 + matugen/files/templates/zellij-colors.kdl | 128 ++++++++++++++++++++++ pi/files/agent/extensions/fetch-url.ts | 79 +++++++++++++ pi/files/agent/extensions/pi-web-access | 1 + pi/files/agent/extensions/tools-list.ts | 18 +++ pi/files/web-search.json | 4 + zellij/files/config.kdl | 4 + 7 files changed, 239 insertions(+) create mode 100644 matugen/files/templates/zellij-colors.kdl create mode 100644 pi/files/agent/extensions/fetch-url.ts create mode 160000 pi/files/agent/extensions/pi-web-access create mode 100644 pi/files/agent/extensions/tools-list.ts create mode 100644 pi/files/web-search.json diff --git a/matugen/files/config.toml b/matugen/files/config.toml index 27a829d..5f4f57a 100644 --- a/matugen/files/config.toml +++ b/matugen/files/config.toml @@ -33,6 +33,11 @@ output_path = '~/.config/rofi/colors/matugen.rasi' input_path = '~/.config/matugen/templates/niri-colors.kdl' output_path = '~/.config/niri/colors.kdl' +[templates.zellij] +input_path = '~/.config/matugen/templates/zellij-colors.kdl' +output_path = '~/.config/zellij/themes/matugen.kdl' +post_hook = 'touch ~/.config/zellij/config.kdl' + [templates.jjui] input_path = '~/.config/matugen/templates/jjui-theme.toml' output_path = '~/.config/jjui/themes/matugen.toml' diff --git a/matugen/files/templates/zellij-colors.kdl b/matugen/files/templates/zellij-colors.kdl new file mode 100644 index 0000000..b3520f6 --- /dev/null +++ b/matugen/files/templates/zellij-colors.kdl @@ -0,0 +1,128 @@ +themes { + matugen { + text_unselected { + base {{ colors.on_surface.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + background {{ colors.surface.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_0 {{ colors.primary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_1 {{ colors.secondary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_2 {{ colors.tertiary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_3 {{ colors.error.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + } + text_selected { + base {{ colors.on_surface.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + background {{ colors.surface_variant.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_0 {{ colors.primary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_1 {{ colors.secondary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_2 {{ colors.tertiary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_3 {{ colors.error.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + } + ribbon_selected { + base {{ colors.on_primary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + background {{ colors.primary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_0 {{ colors.error.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_1 {{ colors.tertiary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_2 {{ colors.secondary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_3 {{ colors.on_primary_container.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + } + ribbon_unselected { + base {{ colors.on_surface.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + background {{ colors.surface_variant.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_0 {{ colors.error.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_1 {{ colors.on_surface.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_2 {{ colors.outline.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_3 {{ colors.secondary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + } + table_title { + base {{ colors.primary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + background {{ colors.surface.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_0 {{ colors.tertiary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_1 {{ colors.secondary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_2 {{ colors.primary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_3 {{ colors.error.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + } + table_cell_selected { + base {{ colors.on_surface.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + background {{ colors.surface_variant.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_0 {{ colors.primary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_1 {{ colors.secondary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_2 {{ colors.tertiary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_3 {{ colors.error.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + } + table_cell_unselected { + base {{ colors.on_surface.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + background {{ colors.surface.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_0 {{ colors.primary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_1 {{ colors.secondary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_2 {{ colors.tertiary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_3 {{ colors.error.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + } + list_selected { + base {{ colors.on_surface.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + background {{ colors.surface_variant.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_0 {{ colors.primary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_1 {{ colors.secondary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_2 {{ colors.tertiary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_3 {{ colors.error.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + } + list_unselected { + base {{ colors.on_surface.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + background {{ colors.surface.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_0 {{ colors.primary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_1 {{ colors.secondary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_2 {{ colors.tertiary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_3 {{ colors.error.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + } + frame_unselected { + base {{ colors.outline.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + background {{ colors.surface.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_0 {{ colors.outline_variant.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_1 {{ colors.primary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_2 {{ colors.secondary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_3 {{ colors.tertiary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + } + frame_selected { + base {{ colors.primary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + background {{ colors.surface.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_0 {{ colors.tertiary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_1 {{ colors.secondary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_2 {{ colors.error.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_3 {{ colors.outline.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + } + frame_highlight { + base {{ colors.tertiary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + background {{ colors.surface.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_0 {{ colors.error.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_1 {{ colors.tertiary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_2 {{ colors.primary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_3 {{ colors.secondary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + } + exit_code_success { + base {{ colors.primary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + background {{ colors.surface.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_0 {{ colors.secondary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_1 {{ colors.on_surface.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_2 {{ colors.tertiary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_3 {{ colors.outline.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + } + exit_code_error { + base {{ colors.error.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + background {{ colors.surface.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_0 {{ colors.tertiary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_1 {{ colors.on_surface.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_2 {{ colors.outline.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + emphasis_3 {{ colors.outline_variant.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + } + multiplayer_user_colors { + player_1 {{ colors.primary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + player_2 {{ colors.secondary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + player_3 {{ colors.tertiary.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + player_4 {{ colors.error.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + player_5 {{ colors.primary_container.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + player_6 {{ colors.secondary_container.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + player_7 {{ colors.tertiary_container.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + player_8 {{ colors.on_primary_container.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + player_9 {{ colors.on_secondary_container.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + player_10 {{ colors.on_tertiary_container.default.rgb | replace: "rgb(", "" | replace: ")", "" | replace: ",", "" }} + } + } +} diff --git a/pi/files/agent/extensions/fetch-url.ts b/pi/files/agent/extensions/fetch-url.ts new file mode 100644 index 0000000..5f226dc --- /dev/null +++ b/pi/files/agent/extensions/fetch-url.ts @@ -0,0 +1,79 @@ +import type { ExtensionAPI } from "@mariozechner/pi-coding-agent"; +import { + DEFAULT_MAX_BYTES, + DEFAULT_MAX_LINES, + formatSize, + truncateHead, +} from "@mariozechner/pi-coding-agent"; +import { Type } from "@sinclair/typebox"; +import fs from "node:fs/promises"; +import os from "node:os"; +import path from "node:path"; + +async function writeTempFile(content: string): Promise { + const dir = await fs.mkdtemp(path.join(os.tmpdir(), "pi-fetch-")); + const filePath = path.join(dir, "response.txt"); + await fs.writeFile(filePath, content, "utf8"); + return filePath; +} + +export default function (pi: ExtensionAPI) { + pi.registerTool({ + name: "fetch_url", + label: "Fetch URL", + description: + "Fetch a URL over HTTP(S) and return the response body as text (truncated to 50KB/2000 lines).", + parameters: Type.Object({ + url: Type.String({ description: "URL to fetch" }), + timeoutMs: Type.Optional( + Type.Number({ description: "Timeout in milliseconds (default: 10000)" }) + ), + headers: Type.Optional( + Type.Record(Type.String(), Type.String(), { + description: "Optional request headers", + }) + ), + }), + async execute(_toolCallId, params, signal) { + const controller = new AbortController(); + const timeout = setTimeout( + () => controller.abort(), + params.timeoutMs ?? 10000 + ); + + const combinedSignal = signal + ? AbortSignal.any([signal, controller.signal]) + : controller.signal; + + try { + const response = await fetch(params.url, { + headers: params.headers, + signal: combinedSignal, + }); + const body = await response.text(); + const truncation = truncateHead(body, { + maxLines: DEFAULT_MAX_LINES, + maxBytes: DEFAULT_MAX_BYTES, + }); + + let content = truncation.content; + if (truncation.truncated) { + const tempFile = await writeTempFile(body); + content += `\n\n[Output truncated: ${truncation.outputLines} of ${truncation.totalLines} lines (${formatSize(truncation.outputBytes)} of ${formatSize(truncation.totalBytes)}). Full output saved to: ${tempFile}]`; + } + + return { + content: [{ type: "text", text: content }], + details: { + status: response.status, + statusText: response.statusText, + contentType: response.headers.get("content-type"), + url: response.url, + }, + }; + } finally { + clearTimeout(timeout); + } + }, + }); +} diff --git a/pi/files/agent/extensions/pi-web-access b/pi/files/agent/extensions/pi-web-access new file mode 160000 index 0000000..4461c2b --- /dev/null +++ b/pi/files/agent/extensions/pi-web-access @@ -0,0 +1 @@ +Subproject commit 4461c2bcb2d871bd8b7b54ee5ecadee20bf3a1f8 diff --git a/pi/files/agent/extensions/tools-list.ts b/pi/files/agent/extensions/tools-list.ts new file mode 100644 index 0000000..4024a5b --- /dev/null +++ b/pi/files/agent/extensions/tools-list.ts @@ -0,0 +1,18 @@ +import type { ExtensionAPI } from "@mariozechner/pi-coding-agent"; + +export default function (pi: ExtensionAPI) { + pi.registerCommand("tools", { + description: "List available and active tools", + handler: async (_args, ctx) => { + const allTools = pi.getAllTools(); + const activeTools = new Set(pi.getActiveTools()); + const lines = allTools + .map((tool) => { + const status = activeTools.has(tool.name) ? "active" : "inactive"; + return `- ${tool.name} (${status})${tool.description ? `: ${tool.description}` : ""}`; + }) + .join("\n"); + ctx.ui.notify(lines || "No tools registered.", "info"); + }, + }); +} diff --git a/pi/files/web-search.json b/pi/files/web-search.json new file mode 100644 index 0000000..b432129 --- /dev/null +++ b/pi/files/web-search.json @@ -0,0 +1,4 @@ +{ + "provider": "duckduckgo", + "searchProvider": "duckduckgo" +} diff --git a/zellij/files/config.kdl b/zellij/files/config.kdl index 7c8baf8..41e5d36 100644 --- a/zellij/files/config.kdl +++ b/zellij/files/config.kdl @@ -283,6 +283,10 @@ web_client { // Default: default // // theme "dracula" + +// Load the matugen-generated theme. +source_file "~/.config/zellij/themes/matugen.kdl" +theme "matugen" // Choose the base input mode of zellij. // Default: normal