Compare commits
3 Commits
97316a8f7b
...
5b29f22fb4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5b29f22fb4 | ||
|
|
4666776bda | ||
|
|
7106db51b5 |
@@ -1,26 +1,25 @@
|
|||||||
{
|
{
|
||||||
"atone.nvim": { "branch": "main", "commit": "7a0a9a4b185a72f99e47e7ac8bf0a311760e0940" },
|
|
||||||
"auto-session": { "branch": "main", "commit": "62437532b38495551410b3f377bcf4aaac574ebe" },
|
"auto-session": { "branch": "main", "commit": "62437532b38495551410b3f377bcf4aaac574ebe" },
|
||||||
"barbar.nvim": { "branch": "master", "commit": "539d73def39c9172b4d4d769f14090e08f37b29d" },
|
"barbar.nvim": { "branch": "master", "commit": "539d73def39c9172b4d4d769f14090e08f37b29d" },
|
||||||
"blink.cmp": { "branch": "main", "commit": "451168851e8e2466bc97ee3e026c3dcb9141ce07" },
|
"blink.cmp": { "branch": "main", "commit": "78336bc89ee5365633bcf754d93df01678b5c08f" },
|
||||||
"claudecode.nvim": { "branch": "main", "commit": "432121f0f5b9bda041030d1e9e83b7ba3a93dd8f" },
|
"claudecode.nvim": { "branch": "main", "commit": "432121f0f5b9bda041030d1e9e83b7ba3a93dd8f" },
|
||||||
"conform.nvim": { "branch": "master", "commit": "086a40dc7ed8242c03be9f47fbcee68699cc2395" },
|
"conform.nvim": { "branch": "master", "commit": "086a40dc7ed8242c03be9f47fbcee68699cc2395" },
|
||||||
"fzf-lua": { "branch": "main", "commit": "c9e7b7bfbd01f949164988ee1684035468e1995c" },
|
"fzf-lua": { "branch": "main", "commit": "9f0432fdd7825ab163520045831a40b6df82ea28" },
|
||||||
"gitsigns.nvim": { "branch": "main", "commit": "e1fb5425c8812214209b3f24eaa582c6c552cf98" },
|
"gitsigns.nvim": { "branch": "main", "commit": "0d797daee85366bc242580e352a4f62d67557b84" },
|
||||||
"lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" },
|
"lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" },
|
||||||
"lazygit.nvim": { "branch": "main", "commit": "a04ad0dbc725134edbee3a5eea29290976695357" },
|
"lazygit.nvim": { "branch": "main", "commit": "a04ad0dbc725134edbee3a5eea29290976695357" },
|
||||||
"leap.nvim": { "branch": "main", "commit": "b960d5038c5c505c52e56a54490f9bbb1f0e6ef6" },
|
"leap.nvim": { "branch": "main", "commit": "b960d5038c5c505c52e56a54490f9bbb1f0e6ef6" },
|
||||||
"lualine.nvim": { "branch": "master", "commit": "47f91c416daef12db467145e16bed5bbfe00add8" },
|
"lualine.nvim": { "branch": "master", "commit": "8811f3f3f4dc09d740c67e9ce399e7a541e2e5b2" },
|
||||||
"mason-lspconfig.nvim": { "branch": "main", "commit": "25f609e7fca78af7cede4f9fa3af8a94b1c4950b" },
|
"mason-lspconfig.nvim": { "branch": "main", "commit": "25f609e7fca78af7cede4f9fa3af8a94b1c4950b" },
|
||||||
"mason.nvim": { "branch": "main", "commit": "44d1e90e1f66e077268191e3ee9d2ac97cc18e65" },
|
"mason.nvim": { "branch": "main", "commit": "b03fb0f20bc1d43daf558cda981a2be22e73ac42" },
|
||||||
"nvim-cmp": { "branch": "main", "commit": "85bbfad83f804f11688d1ab9486b459e699292d6" },
|
"nvim-cmp": { "branch": "main", "commit": "85bbfad83f804f11688d1ab9486b459e699292d6" },
|
||||||
"nvim-lspconfig": { "branch": "master", "commit": "8e2084bf5e40c79c1f42210a6ef96a0a4793a763" },
|
"nvim-lspconfig": { "branch": "master", "commit": "bedca8b426b2fee0ccac596d167d71bbe971253f" },
|
||||||
"nvim-navic": { "branch": "master", "commit": "f5eba192f39b453675d115351808bd51276d9de5" },
|
"nvim-navic": { "branch": "master", "commit": "f5eba192f39b453675d115351808bd51276d9de5" },
|
||||||
"nvim-treesitter": { "branch": "master", "commit": "cf12346a3414fa1b06af75c79faebe7f76df080a" },
|
"nvim-treesitter": { "branch": "main", "commit": "4916d6592ede8c07973490d9322f187e07dfefac" },
|
||||||
"nvim-web-devicons": { "branch": "master", "commit": "d7462543c9e366c0d196c7f67a945eaaf5d99414" },
|
"nvim-web-devicons": { "branch": "master", "commit": "95b7a002d5dba1a42eb58f5fac5c565a485eefd0" },
|
||||||
"plenary.nvim": { "branch": "master", "commit": "b9fd5226c2f76c951fc8ed5923d85e4de065e509" },
|
"plenary.nvim": { "branch": "master", "commit": "b9fd5226c2f76c951fc8ed5923d85e4de065e509" },
|
||||||
"snacks.nvim": { "branch": "main", "commit": "ad9ede6a9cddf16cedbd31b8932d6dcdee9b716e" },
|
"snacks.nvim": { "branch": "main", "commit": "ad9ede6a9cddf16cedbd31b8932d6dcdee9b716e" },
|
||||||
"tiny-inline-diagnostic.nvim": { "branch": "main", "commit": "ba133b3e932416e4b9507095731a6d7276878fe8" },
|
"tiny-inline-diagnostic.nvim": { "branch": "main", "commit": "57a0eb84b2008c76e77930639890d9874195b1e1" },
|
||||||
"vgit.nvim": { "branch": "main", "commit": "7e147e8cb2f160ae3c8d353005666f636d34acb2" },
|
"vgit.nvim": { "branch": "main", "commit": "7e147e8cb2f160ae3c8d353005666f636d34acb2" },
|
||||||
"which-key.nvim": { "branch": "main", "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" },
|
"which-key.nvim": { "branch": "main", "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" },
|
||||||
"yazi.nvim": { "branch": "main", "commit": "172bd64a4c2d3adbe2e0ef56289f47ffe139ca55" },
|
"yazi.nvim": { "branch": "main", "commit": "172bd64a4c2d3adbe2e0ef56289f47ffe139ca55" },
|
||||||
|
|||||||
@@ -4,6 +4,16 @@ local autocmd = vim.api.nvim_create_autocmd
|
|||||||
|
|
||||||
autocmd({ "BufRead", "BufNewFile" }, { pattern = "*.wesl", command = "setfiletype wesl" })
|
autocmd({ "BufRead", "BufNewFile" }, { pattern = "*.wesl", command = "setfiletype wesl" })
|
||||||
|
|
||||||
|
-- Start treesitter highlighting for any buffer with an available parser
|
||||||
|
autocmd("FileType", {
|
||||||
|
callback = function(args)
|
||||||
|
local lang = vim.treesitter.language.get_lang(args.match)
|
||||||
|
if lang and vim.treesitter.language.add(lang) then
|
||||||
|
vim.treesitter.start(args.buf, lang)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
-- Register wgsl as the treesitter language for wesl files
|
-- Register wgsl as the treesitter language for wesl files
|
||||||
vim.treesitter.language.register("wgsl", "wesl")
|
vim.treesitter.language.register("wgsl", "wesl")
|
||||||
|
|
||||||
|
|||||||
@@ -118,6 +118,3 @@ require("fzf-lua").setup({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
-- Setup fzf-lua as vim.ui.select provider
|
|
||||||
require("fzf-lua").register_ui_select()
|
|
||||||
|
|||||||
@@ -1,24 +1,6 @@
|
|||||||
-- LSP capabilities (with blink.cmp completion support)
|
-- LSP capabilities (blink.cmp augments these automatically)
|
||||||
local capabilities = vim.lsp.protocol.make_client_capabilities()
|
local capabilities = vim.lsp.protocol.make_client_capabilities()
|
||||||
|
|
||||||
capabilities.textDocument.completion.completionItem = {
|
|
||||||
documentationFormat = { "markdown", "plaintext" },
|
|
||||||
snippetSupport = true,
|
|
||||||
preselectSupport = true,
|
|
||||||
insertReplaceSupport = true,
|
|
||||||
labelDetailsSupport = true,
|
|
||||||
deprecatedSupport = true,
|
|
||||||
commitCharactersSupport = true,
|
|
||||||
tagSupport = { valueSet = { 1 } },
|
|
||||||
resolveSupport = {
|
|
||||||
properties = {
|
|
||||||
"documentation",
|
|
||||||
"detail",
|
|
||||||
"additionalTextEdits",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
-- on_attach function with LSP keybindings
|
-- on_attach function with LSP keybindings
|
||||||
local on_attach = function(client, bufnr)
|
local on_attach = function(client, bufnr)
|
||||||
-- Attach navic for breadcrumb tracking
|
-- Attach navic for breadcrumb tracking
|
||||||
@@ -57,18 +39,10 @@ local on_attach = function(client, bufnr)
|
|||||||
map("n", "<leader>q", vim.diagnostic.setloclist, opts "Set loclist")
|
map("n", "<leader>q", vim.diagnostic.setloclist, opts "Set loclist")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Disable semantic tokens (performance optimization)
|
|
||||||
local on_init = function(client, _)
|
|
||||||
if client.supports_method "textDocument/semanticTokens" then
|
|
||||||
client.server_capabilities.semanticTokensProvider = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local servers = {
|
local servers = {
|
||||||
rust_analyzer = {
|
rust_analyzer = {
|
||||||
filetypes = { "rust" },
|
filetypes = { "rust" },
|
||||||
on_attach = on_attach,
|
on_attach = on_attach,
|
||||||
on_init = on_init,
|
|
||||||
capabilities = capabilities,
|
capabilities = capabilities,
|
||||||
settings = {
|
settings = {
|
||||||
["rust-analyzer"] = {
|
["rust-analyzer"] = {
|
||||||
@@ -88,31 +62,26 @@ local servers = {
|
|||||||
csharp_ls = {
|
csharp_ls = {
|
||||||
filetypes = { "cs" },
|
filetypes = { "cs" },
|
||||||
on_attach = on_attach,
|
on_attach = on_attach,
|
||||||
on_init = on_init,
|
|
||||||
capabilities = capabilities,
|
capabilities = capabilities,
|
||||||
},
|
},
|
||||||
clangd = {
|
clangd = {
|
||||||
filetypes = { "c", "cpp", "objc", "objcpp" },
|
filetypes = { "c", "cpp", "objc", "objcpp" },
|
||||||
on_attach = on_attach,
|
on_attach = on_attach,
|
||||||
on_init = on_init,
|
|
||||||
capabilities = capabilities,
|
capabilities = capabilities,
|
||||||
},
|
},
|
||||||
glsl_analyzer = {
|
glsl_analyzer = {
|
||||||
filetypes = { "glsl" },
|
filetypes = { "glsl" },
|
||||||
on_attach = on_attach,
|
on_attach = on_attach,
|
||||||
on_init = on_init,
|
|
||||||
capabilities = capabilities,
|
capabilities = capabilities,
|
||||||
},
|
},
|
||||||
wgsl_analyzer = {
|
wgsl_analyzer = {
|
||||||
filetypes = { "wgsl", "wesl" },
|
filetypes = { "wgsl", "wesl" },
|
||||||
on_attach = on_attach,
|
on_attach = on_attach,
|
||||||
on_init = on_init,
|
|
||||||
capabilities = capabilities,
|
capabilities = capabilities,
|
||||||
},
|
},
|
||||||
pylsp = {
|
pylsp = {
|
||||||
filetypes = { "python" },
|
filetypes = { "python" },
|
||||||
on_attach = on_attach,
|
on_attach = on_attach,
|
||||||
on_init = on_init,
|
|
||||||
capabilities = capabilities,
|
capabilities = capabilities,
|
||||||
},
|
},
|
||||||
ron_lsp = {
|
ron_lsp = {
|
||||||
@@ -120,10 +89,9 @@ local servers = {
|
|||||||
filetypes = { "ron" },
|
filetypes = { "ron" },
|
||||||
root_dir = function(fname)
|
root_dir = function(fname)
|
||||||
local util = require("lspconfig.util")
|
local util = require("lspconfig.util")
|
||||||
return util.root_pattern("Cargo.toml", ".git")(fname) or vim.loop.cwd()
|
return util.root_pattern("Cargo.toml", ".git")(fname) or vim.uv.cwd()
|
||||||
end,
|
end,
|
||||||
on_attach = on_attach,
|
on_attach = on_attach,
|
||||||
on_init = on_init,
|
|
||||||
capabilities = capabilities,
|
capabilities = capabilities,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,10 +36,6 @@ end, { desc = "Format file" })
|
|||||||
map("n", "<leader>/", "gcc", { desc = "Toggle comment", remap = true })
|
map("n", "<leader>/", "gcc", { desc = "Toggle comment", remap = true })
|
||||||
map("v", "<leader>/", "gc", { desc = "Toggle comment", remap = true })
|
map("v", "<leader>/", "gc", { desc = "Toggle comment", remap = true })
|
||||||
|
|
||||||
-- === LSP Mappings ===
|
|
||||||
|
|
||||||
map("n", "<leader>ds", vim.diagnostic.setloclist, { desc = "LSP diagnostic loclist" })
|
|
||||||
|
|
||||||
-- === Barbar buffer navigation ===
|
-- === Barbar buffer navigation ===
|
||||||
|
|
||||||
map("n", "<Tab>", "<cmd>BufferNext<cr>", { desc = "Next buffer" })
|
map("n", "<Tab>", "<cmd>BufferNext<cr>", { desc = "Next buffer" })
|
||||||
@@ -96,7 +92,7 @@ map('n', '<leader>fd', function() fzf.diagnostics_document({ severity_limit = vi
|
|||||||
map('n', '<leader>fD', function() fzf.diagnostics_workspace({ severity_limit = vim.diagnostic.severity.ERROR }) end, { desc = "Workspace diagnostics" })
|
map('n', '<leader>fD', function() fzf.diagnostics_workspace({ severity_limit = vim.diagnostic.severity.ERROR }) end, { desc = "Workspace diagnostics" })
|
||||||
map('n', '<leader>fr', function() fzf.lsp_references() end, { desc = 'References' })
|
map('n', '<leader>fr', function() fzf.lsp_references() end, { desc = 'References' })
|
||||||
map('n', '<leader>fW', function() vim.diagnostic.open_float() end, { desc = "Open diagnostics window" })
|
map('n', '<leader>fW', function() vim.diagnostic.open_float() end, { desc = "Open diagnostics window" })
|
||||||
map("n", "<leader>ca", function() vim.lsp.buf.code_action() end, { desc = 'Code action'})
|
-- <leader>ca is mapped per-buffer in configs/lspconfig.lua on_attach
|
||||||
|
|
||||||
-- === Themery ===
|
-- === Themery ===
|
||||||
|
|
||||||
|
|||||||
@@ -86,3 +86,6 @@ vim.env.PATH = table.concat({ vim.fn.stdpath "data", "mason", "bin" }, sep) .. d
|
|||||||
|
|
||||||
-- User overrides
|
-- User overrides
|
||||||
o.scrolloff = 10 -- Keep 10 lines visible above/below cursor
|
o.scrolloff = 10 -- Keep 10 lines visible above/below cursor
|
||||||
|
|
||||||
|
-- Experimental: improved command-line and message UI
|
||||||
|
pcall(function() require('vim._core.ui2').enable() end)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
-- LSP, completion, treesitter, and code formatting
|
-- LSP, completion, and code formatting
|
||||||
return {
|
return {
|
||||||
-- LSP server manager
|
-- LSP server manager
|
||||||
{
|
{
|
||||||
@@ -32,25 +32,13 @@ return {
|
|||||||
end,
|
end,
|
||||||
},
|
},
|
||||||
|
|
||||||
-- Syntax highlighting
|
-- Treesitter parser manager
|
||||||
{
|
{
|
||||||
"nvim-treesitter/nvim-treesitter",
|
"nvim-treesitter/nvim-treesitter",
|
||||||
event = { "BufReadPost", "BufNewFile" },
|
|
||||||
cmd = { "TSInstall", "TSBufEnable", "TSBufDisable", "TSModuleInfo" },
|
|
||||||
build = ":TSUpdate",
|
build = ":TSUpdate",
|
||||||
opts = {
|
cmd = { "TSInstall", "TSUpdate" },
|
||||||
ensure_installed = {
|
config = function()
|
||||||
"lua", "vim", "vimdoc",
|
require("nvim-treesitter").setup()
|
||||||
"rust", "c", "cpp", "glsl", "wgsl", "python",
|
|
||||||
},
|
|
||||||
highlight = {
|
|
||||||
enable = true,
|
|
||||||
use_languagetree = true,
|
|
||||||
},
|
|
||||||
indent = { enable = false },
|
|
||||||
},
|
|
||||||
config = function(_, opts)
|
|
||||||
require("nvim-treesitter.configs").setup(opts)
|
|
||||||
end,
|
end,
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -85,6 +73,7 @@ return {
|
|||||||
list = { selection = { auto_insert = false } },
|
list = { selection = { auto_insert = false } },
|
||||||
},
|
},
|
||||||
sources = {
|
sources = {
|
||||||
|
default = { 'lsp', 'path', 'buffer' },
|
||||||
transform_items = function(_, items)
|
transform_items = function(_, items)
|
||||||
return vim.tbl_filter(function(item)
|
return vim.tbl_filter(function(item)
|
||||||
return item.kind ~= require('blink.cmp.types').CompletionItemKind.Snippet
|
return item.kind ~= require('blink.cmp.types').CompletionItemKind.Snippet
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ return {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
select = {
|
select = {
|
||||||
enabled = false,
|
enabled = true,
|
||||||
},
|
},
|
||||||
indent = {
|
indent = {
|
||||||
enabled = true,
|
enabled = true,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
name: explorer
|
name: explorer
|
||||||
description: Comprehensive codebase and knowledge-base explorer. Maps architecture, traces dependencies, synthesizes cross-cutting context with full code snippets and rationale. Use for deep refactoring, architectural decisions, or understanding complex subsystems. Do NOT use when the user has already provided explicit file paths or when a direct file read would suffice — only invoke for open-ended exploration where the relevant files are unknown.
|
description: Comprehensive codebase and knowledge-base explorer. Maps architecture, traces dependencies, synthesizes cross-cutting context with full code snippets and rationale. Use for deep refactoring, architectural decisions, or understanding complex subsystems. Do NOT use when the user has already provided explicit file paths or when a direct file read would suffice — only invoke for open-ended exploration where the relevant files are unknown.
|
||||||
tools: read, bash, write, mcp:qmd, mcp:opty
|
tools: read, bash, write, mcp:qmd, mcp:opty
|
||||||
model: opencode/big-pickle
|
model: opencode-go/mimo-v2-pro
|
||||||
defaultProgress: true
|
defaultProgress: true
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
name: planner
|
name: planner
|
||||||
description: Creates detailed implementation plans from scout context and task requirements. Writes the plan to a file for the next agent in the chain.
|
description: Creates detailed implementation plans from scout context and task requirements. Writes the plan to a file for the next agent in the chain.
|
||||||
tools: read, write, grep, find, ls
|
tools: read, write, grep, find, ls
|
||||||
model: opencode/qwen3.6-plus-free
|
model: anthropic/claude-opus-4-6
|
||||||
output: plan.md
|
output: plan.md
|
||||||
defaultReads: scout.md
|
defaultReads: scout.md
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
---
|
---
|
||||||
name: scout
|
name: scout
|
||||||
description: Fast codebase recon. Finds relevant files, types, and patterns, then writes structured context for the next agent in the chain.
|
description: Fast codebase recon. Finds relevant files, types, and patterns, then writes structured context for the next agent in the chain.
|
||||||
tools: read, write, grep, find, ls, bash, mcp:opty, mcp:qmd
|
tools: read, write, grep, find, ls, bash
|
||||||
|
skills: opty, qmd
|
||||||
model: opencode-go/mimo-v2-pro
|
model: opencode-go/mimo-v2-pro
|
||||||
output: scout.md
|
output: scout.md
|
||||||
---
|
---
|
||||||
@@ -21,17 +22,17 @@ When your task contains `[Write to: path]`, write your COMPLETE report to that e
|
|||||||
Without `[Write to:]`, output your full report as text.
|
Without `[Write to:]`, output your full report as text.
|
||||||
|
|
||||||
## Tools
|
## Tools
|
||||||
- **opty** — semantic/HDC code search: use `opty_opty_query` to find functions, types, imports by meaning; `opty_opty_ast` for a structural overview of a file or the project
|
- **opty** — semantic/HDC code search via CLI: `opty query "description"` to find functions/types/imports by meaning; output includes file + line number
|
||||||
- **qmd** — knowledge base search: use `qmd_query` to find docs, notes, or prior context by keyword or vector; `qmd_get` / `qmd_multi_get` to retrieve full documents
|
- **qmd** — knowledge base search via CLI: `qmd query $'lex: X\nvec: Y'` to find docs/notes by keyword or vector; `qmd get <path>` / `qmd multi-get <glob>` to retrieve full documents
|
||||||
- **grep/find/bash** — fallback for exact patterns, file discovery, or anything the semantic tools miss
|
- **grep/find/bash** — for exact patterns, file discovery, or anything the semantic tools miss
|
||||||
- **read** — read specific file sections once you know where to look
|
- **read** — read specific file sections once you know where to look
|
||||||
|
|
||||||
## Strategy
|
## Strategy
|
||||||
1. Use `opty_opty_query` to semantically locate relevant functions/types (fast, no file reading needed)
|
1. Use `opty query "..."` to semantically locate relevant functions/types (fast, no file reading needed)
|
||||||
2. Use `qmd_query` to check if there's relevant documentation or prior context in the knowledge base
|
2. Use `qmd query "..."` to check if there's relevant documentation or prior context in the knowledge base
|
||||||
3. grep/find for exact patterns or when semantic search isn't precise enough
|
3. grep/find for exact patterns or when semantic search isn't precise enough
|
||||||
4. Read key sections (not entire files — target the relevant functions/types)
|
4. Read key sections (not entire files — target the relevant functions/types)
|
||||||
5. Use `opty_opty_ast` on key files to quickly understand their structure without reading everything
|
5. For file structure overview, use grep for exports/types or read the top ~50 lines of a file
|
||||||
6. Identify types, interfaces, key functions
|
6. Identify types, interfaces, key functions
|
||||||
7. Note dependencies between files
|
7. Note dependencies between files
|
||||||
8. Flag anything surprising or risky
|
8. Flag anything surprising or risky
|
||||||
|
|||||||
1186
pi/.pi/agent/extensions/claude-agent-sdk/index.ts
Normal file
1186
pi/.pi/agent/extensions/claude-agent-sdk/index.ts
Normal file
File diff suppressed because it is too large
Load Diff
1522
pi/.pi/agent/extensions/claude-agent-sdk/package-lock.json
generated
Normal file
1522
pi/.pi/agent/extensions/claude-agent-sdk/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
11
pi/.pi/agent/extensions/claude-agent-sdk/package.json
Normal file
11
pi/.pi/agent/extensions/claude-agent-sdk/package.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"name": "claude-agent-sdk",
|
||||||
|
"type": "module",
|
||||||
|
"dependencies": {
|
||||||
|
"@anthropic-ai/claude-agent-sdk": "^0.2.92",
|
||||||
|
"change-case": "^5.4.4"
|
||||||
|
},
|
||||||
|
"pi": {
|
||||||
|
"extensions": ["./index.ts"]
|
||||||
|
}
|
||||||
|
}
|
||||||
12
pi/.pi/agent/extensions/exa-mcp.json
Normal file
12
pi/.pi/agent/extensions/exa-mcp.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"url": "https://mcp.exa.ai/mcp",
|
||||||
|
"apiKey": null,
|
||||||
|
"tools": [
|
||||||
|
"web_search_exa",
|
||||||
|
"get_code_context_exa"
|
||||||
|
],
|
||||||
|
"timeoutMs": 30000,
|
||||||
|
"protocolVersion": "2025-06-18",
|
||||||
|
"maxBytes": 51200,
|
||||||
|
"maxLines": 2000
|
||||||
|
}
|
||||||
@@ -36,8 +36,8 @@ export function writeUsageCache(cache: UsageCache): void {
|
|||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ProviderKey = "codex" | "claude" | "zai" | "gemini" | "antigravity";
|
export type ProviderKey = "codex" | "claude" | "zai" | "gemini" | "antigravity" | "opencode-go";
|
||||||
export type OAuthProviderId = "openai-codex" | "anthropic" | "google-gemini-cli" | "google-antigravity";
|
export type OAuthProviderId = "openai-codex" | "anthropic" | "google-gemini-cli" | "google-antigravity" | "opencode-go";
|
||||||
|
|
||||||
export interface AuthData {
|
export interface AuthData {
|
||||||
"openai-codex"?: { access?: string; refresh?: string; expires?: number };
|
"openai-codex"?: { access?: string; refresh?: string; expires?: number };
|
||||||
@@ -45,6 +45,7 @@ export interface AuthData {
|
|||||||
zai?: { key?: string; access?: string; refresh?: string; expires?: number };
|
zai?: { key?: string; access?: string; refresh?: string; expires?: number };
|
||||||
"google-gemini-cli"?: { access?: string; refresh?: string; projectId?: string; expires?: number };
|
"google-gemini-cli"?: { access?: string; refresh?: string; projectId?: string; expires?: number };
|
||||||
"google-antigravity"?: { access?: string; refresh?: string; projectId?: string; expires?: number };
|
"google-antigravity"?: { access?: string; refresh?: string; projectId?: string; expires?: number };
|
||||||
|
"opencode-go"?: { key?: string; access?: string };
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UsageData {
|
export interface UsageData {
|
||||||
@@ -61,6 +62,127 @@ export interface UsageData {
|
|||||||
|
|
||||||
export type UsageByProvider = Record<ProviderKey, UsageData | null>;
|
export type UsageByProvider = Record<ProviderKey, UsageData | null>;
|
||||||
|
|
||||||
|
// OpenCode Go usage tracking (local, since no API exists yet)
|
||||||
|
export interface OpenCodeGoLocalUsage {
|
||||||
|
/** Dollar value used in the 5-hour window */
|
||||||
|
fiveHourUsed: number;
|
||||||
|
/** Dollar value used in the weekly window */
|
||||||
|
weeklyUsed: number;
|
||||||
|
/** Dollar value used in the monthly window */
|
||||||
|
monthlyUsed: number;
|
||||||
|
/** Timestamp of the last update */
|
||||||
|
lastUpdated: number;
|
||||||
|
/** When the current 5-hour window started */
|
||||||
|
fiveHourWindowStart: number;
|
||||||
|
/** When the current week started (Unix ms) */
|
||||||
|
weekStart: number;
|
||||||
|
/** When the current month started (Unix ms) */
|
||||||
|
monthStart: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const OPENCODE_GO_USAGE_FILE = path.join(os.homedir(), ".pi", "agent", "opencode-go-usage.json");
|
||||||
|
const OPENCODE_GO_FIVE_HOUR_LIMIT = 12;
|
||||||
|
const OPENCODE_GO_WEEKLY_LIMIT = 30;
|
||||||
|
const OPENCODE_GO_MONTHLY_LIMIT = 60;
|
||||||
|
const OPENCODE_GO_FIVE_HOUR_MS = 5 * 60 * 60 * 1000;
|
||||||
|
|
||||||
|
export function readOpenCodeGoUsage(): OpenCodeGoLocalUsage | null {
|
||||||
|
try {
|
||||||
|
const raw = fs.readFileSync(OPENCODE_GO_USAGE_FILE, "utf-8");
|
||||||
|
const parsed = JSON.parse(raw);
|
||||||
|
if (typeof parsed?.lastUpdated === "number") return parsed as OpenCodeGoLocalUsage;
|
||||||
|
} catch {}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function writeOpenCodeGoUsage(usage: OpenCodeGoLocalUsage): void {
|
||||||
|
try {
|
||||||
|
const dir = path.dirname(OPENCODE_GO_USAGE_FILE);
|
||||||
|
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
||||||
|
const tmp = `${OPENCODE_GO_USAGE_FILE}.tmp-${process.pid}-${Date.now()}`;
|
||||||
|
fs.writeFileSync(tmp, JSON.stringify(usage, null, 2));
|
||||||
|
fs.renameSync(tmp, OPENCODE_GO_USAGE_FILE);
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resetOpenCodeGoUsageIfNeeded(existing: OpenCodeGoLocalUsage | null): OpenCodeGoLocalUsage {
|
||||||
|
const now = Date.now();
|
||||||
|
const nowDate = new Date(now);
|
||||||
|
|
||||||
|
// Start with defaults
|
||||||
|
let usage: OpenCodeGoLocalUsage = existing ?? {
|
||||||
|
fiveHourUsed: 0,
|
||||||
|
weeklyUsed: 0,
|
||||||
|
monthlyUsed: 0,
|
||||||
|
lastUpdated: now,
|
||||||
|
fiveHourWindowStart: now,
|
||||||
|
weekStart: now,
|
||||||
|
monthStart: now,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Reset 5-hour window if expired
|
||||||
|
if (now - usage.fiveHourWindowStart >= OPENCODE_GO_FIVE_HOUR_MS) {
|
||||||
|
usage.fiveHourUsed = 0;
|
||||||
|
usage.fiveHourWindowStart = now;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset weekly window (Monday-based)
|
||||||
|
const dayOfWeek = nowDate.getDay();
|
||||||
|
const daysSinceMonday = dayOfWeek === 0 ? 6 : dayOfWeek - 1;
|
||||||
|
const thisMonday = new Date(nowDate);
|
||||||
|
thisMonday.setDate(nowDate.getDate() - daysSinceMonday);
|
||||||
|
thisMonday.setHours(0, 0, 0, 0);
|
||||||
|
if (usage.weekStart < thisMonday.getTime()) {
|
||||||
|
usage.weeklyUsed = 0;
|
||||||
|
usage.weekStart = thisMonday.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset monthly window (1st of month)
|
||||||
|
const thisMonthStart = new Date(nowDate.getFullYear(), nowDate.getMonth(), 1);
|
||||||
|
if (usage.monthStart < thisMonthStart.getTime()) {
|
||||||
|
usage.monthlyUsed = 0;
|
||||||
|
usage.monthStart = thisMonthStart.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
usage.lastUpdated = now;
|
||||||
|
return usage;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function addOpenCodeGoSpend(dollars: number): void {
|
||||||
|
let usage = resetOpenCodeGoUsageIfNeeded(readOpenCodeGoUsage());
|
||||||
|
usage.fiveHourUsed += dollars;
|
||||||
|
usage.weeklyUsed += dollars;
|
||||||
|
usage.monthlyUsed += dollars;
|
||||||
|
usage.lastUpdated = Date.now();
|
||||||
|
writeOpenCodeGoUsage(usage);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getOpenCodeGoUsageData(): UsageData {
|
||||||
|
const usage = resetOpenCodeGoUsageIfNeeded(readOpenCodeGoUsage());
|
||||||
|
if (!usage) {
|
||||||
|
return { session: 0, weekly: 0, error: "no local usage data" };
|
||||||
|
}
|
||||||
|
|
||||||
|
const sessionPct = Math.min(100, (usage.fiveHourUsed / OPENCODE_GO_FIVE_HOUR_LIMIT) * 100);
|
||||||
|
const weeklyPct = Math.min(100, (usage.weeklyUsed / OPENCODE_GO_WEEKLY_LIMIT) * 100);
|
||||||
|
|
||||||
|
// Calculate resets
|
||||||
|
const fiveHourEnd = usage.fiveHourWindowStart + OPENCODE_GO_FIVE_HOUR_MS;
|
||||||
|
const fiveHourRemaining = Math.max(0, fiveHourEnd - Date.now());
|
||||||
|
|
||||||
|
const weekEnd = usage.weekStart + 7 * 24 * 60 * 60 * 1000;
|
||||||
|
const weekRemaining = Math.max(0, weekEnd - Date.now());
|
||||||
|
|
||||||
|
return {
|
||||||
|
session: sessionPct,
|
||||||
|
weekly: weeklyPct,
|
||||||
|
sessionResetsIn: formatDuration(Math.round(fiveHourRemaining / 1000)),
|
||||||
|
weeklyResetsIn: formatDuration(Math.round(weekRemaining / 1000)),
|
||||||
|
extraSpend: usage.monthlyUsed,
|
||||||
|
extraLimit: OPENCODE_GO_MONTHLY_LIMIT,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export interface UsageEndpoints {
|
export interface UsageEndpoints {
|
||||||
zai: string;
|
zai: string;
|
||||||
gemini: string;
|
gemini: string;
|
||||||
@@ -600,12 +722,14 @@ export function detectProvider(
|
|||||||
if (typeof model === "string") return null;
|
if (typeof model === "string") return null;
|
||||||
|
|
||||||
const provider = (model.provider || "").toLowerCase();
|
const provider = (model.provider || "").toLowerCase();
|
||||||
|
const id = (model.id || "").toLowerCase();
|
||||||
|
|
||||||
if (provider === "openai-codex") return "codex";
|
if (provider === "openai-codex") return "codex";
|
||||||
if (provider === "anthropic") return "claude";
|
if (provider === "anthropic") return "claude";
|
||||||
if (provider === "zai") return "zai";
|
if (provider === "zai") return "zai";
|
||||||
if (provider === "google-gemini-cli") return "gemini";
|
if (provider === "google-gemini-cli") return "gemini";
|
||||||
if (provider === "google-antigravity") return "antigravity";
|
if (provider === "google-antigravity") return "antigravity";
|
||||||
|
if (provider === "opencode-go" || id.startsWith("opencode-go/")) return "opencode-go";
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -615,6 +739,7 @@ export function providerToOAuthProviderId(active: ProviderKey | null): OAuthProv
|
|||||||
if (active === "claude") return "anthropic";
|
if (active === "claude") return "anthropic";
|
||||||
if (active === "gemini") return "google-gemini-cli";
|
if (active === "gemini") return "google-gemini-cli";
|
||||||
if (active === "antigravity") return "google-antigravity";
|
if (active === "antigravity") return "google-antigravity";
|
||||||
|
if (active === "opencode-go") return "opencode-go";
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -629,6 +754,9 @@ export function canShowForProvider(active: ProviderKey | null, auth: AuthData |
|
|||||||
if (active === "antigravity") {
|
if (active === "antigravity") {
|
||||||
return !!(auth["google-antigravity"]?.access || auth["google-antigravity"]?.refresh) && !!endpoints.antigravity;
|
return !!(auth["google-antigravity"]?.access || auth["google-antigravity"]?.refresh) && !!endpoints.antigravity;
|
||||||
}
|
}
|
||||||
|
if (active === "opencode-go") {
|
||||||
|
return !!(auth["opencode-go"]?.key || auth["opencode-go"]?.access);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -654,6 +782,7 @@ export async function fetchAllUsages(config: FetchAllUsagesConfig = {}): Promise
|
|||||||
zai: null,
|
zai: null,
|
||||||
gemini: null,
|
gemini: null,
|
||||||
antigravity: null,
|
antigravity: null,
|
||||||
|
"opencode-go": null,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!auth) return results;
|
if (!auth) return results;
|
||||||
@@ -733,6 +862,11 @@ export async function fetchAllUsages(config: FetchAllUsagesConfig = {}): Promise
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OpenCode Go uses local tracking (no public API yet)
|
||||||
|
if (authData["opencode-go"]?.key || authData["opencode-go"]?.access) {
|
||||||
|
results["opencode-go"] = getOpenCodeGoUsageData();
|
||||||
|
}
|
||||||
|
|
||||||
await Promise.all(tasks);
|
await Promise.all(tasks);
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ const PROVIDER_LABELS: Record<ProviderKey, string> = {
|
|||||||
zai: "Z.AI",
|
zai: "Z.AI",
|
||||||
gemini: "Gemini",
|
gemini: "Gemini",
|
||||||
antigravity: "Antigravity",
|
antigravity: "Antigravity",
|
||||||
|
"opencode-go": "Go",
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -163,6 +164,7 @@ class UsageSelectorComponent extends Container implements Focusable {
|
|||||||
{ key: "zai", name: "Z.AI" },
|
{ key: "zai", name: "Z.AI" },
|
||||||
{ key: "gemini", name: "Gemini" },
|
{ key: "gemini", name: "Gemini" },
|
||||||
{ key: "antigravity", name: "Antigravity" },
|
{ key: "antigravity", name: "Antigravity" },
|
||||||
|
{ key: "opencode-go", name: "Go" },
|
||||||
];
|
];
|
||||||
this.allItems = [];
|
this.allItems = [];
|
||||||
for (const p of providers) {
|
for (const p of providers) {
|
||||||
@@ -287,7 +289,7 @@ interface PollOptions {
|
|||||||
export default function (pi: ExtensionAPI) {
|
export default function (pi: ExtensionAPI) {
|
||||||
const endpoints = resolveUsageEndpoints();
|
const endpoints = resolveUsageEndpoints();
|
||||||
const state: UsageState = {
|
const state: UsageState = {
|
||||||
codex: null, claude: null, zai: null, gemini: null, antigravity: null,
|
codex: null, claude: null, zai: null, gemini: null, antigravity: null, "opencode-go": null,
|
||||||
lastPoll: 0, activeProvider: null,
|
lastPoll: 0, activeProvider: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -433,6 +435,10 @@ export default function (pi: ExtensionAPI) {
|
|||||||
result = creds?.access
|
result = creds?.access
|
||||||
? await fetchGoogleUsage(creds.access, endpoints.gemini, creds.projectId, "gemini", { endpoints })
|
? await fetchGoogleUsage(creds.access, endpoints.gemini, creds.projectId, "gemini", { endpoints })
|
||||||
: { session: 0, weekly: 0, error: "missing access token (try /login again)" };
|
: { session: 0, weekly: 0, error: "missing access token (try /login again)" };
|
||||||
|
} else if (active === "opencode-go") {
|
||||||
|
// OpenCode Go uses local tracking (no public usage API yet)
|
||||||
|
const { getOpenCodeGoUsageData } = await import("./core");
|
||||||
|
result = getOpenCodeGoUsageData();
|
||||||
} else {
|
} else {
|
||||||
const creds = effectiveAuth["google-antigravity"];
|
const creds = effectiveAuth["google-antigravity"];
|
||||||
result = creds?.access
|
result = creds?.access
|
||||||
@@ -561,6 +567,22 @@ export default function (pi: ExtensionAPI) {
|
|||||||
void poll({ forceFresh: true });
|
void poll({ forceFresh: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Listen for OpenCode Go spend events from other extensions
|
||||||
|
pi.events.on("opencode-go:spend", async (amount: number) => {
|
||||||
|
if (typeof amount === "number" && amount > 0) {
|
||||||
|
const { addOpenCodeGoSpend } = await import("./core");
|
||||||
|
addOpenCodeGoSpend(amount);
|
||||||
|
// Invalidate cache and re-poll
|
||||||
|
const cache = readUsageCache();
|
||||||
|
if (cache?.data?.["opencode-go"]) {
|
||||||
|
const nextCache: import("./core").UsageCache = { ...cache, data: { ...cache.data } };
|
||||||
|
delete nextCache.data["opencode-go"];
|
||||||
|
writeUsageCache(nextCache);
|
||||||
|
}
|
||||||
|
void poll({ forceFresh: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// ── /usage command ───────────────────────────────────────────────────────
|
// ── /usage command ───────────────────────────────────────────────────────
|
||||||
|
|
||||||
pi.registerCommand("usage", {
|
pi.registerCommand("usage", {
|
||||||
|
|||||||
@@ -23,6 +23,15 @@
|
|||||||
"maxTokens": 131072,
|
"maxTokens": 131072,
|
||||||
"cost": { "input": 1.0, "output": 3.2, "cacheRead": 0.2, "cacheWrite": 0 }
|
"cost": { "input": 1.0, "output": 3.2, "cacheRead": 0.2, "cacheWrite": 0 }
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "glm-5.1",
|
||||||
|
"name": "GLM-5.1",
|
||||||
|
"reasoning": true,
|
||||||
|
"input": ["text"],
|
||||||
|
"contextWindow": 204800,
|
||||||
|
"maxTokens": 131072,
|
||||||
|
"cost": { "input": 1.0, "output": 3.2, "cacheRead": 0.2, "cacheWrite": 0 }
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "kimi-k2.5",
|
"id": "kimi-k2.5",
|
||||||
"name": "Kimi K2.5",
|
"name": "Kimi K2.5",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
description: "Maximum quality pipeline — deep scout, Max planning, Opus plan review, approval gate, Sonnet coding, Opus code review"
|
description: "Maximum quality pipeline — deep scout, thorough planning, plan review, approval gate, coding, code review"
|
||||||
---
|
---
|
||||||
|
|
||||||
Use the subagent tool to implement with maximum quality. This is for high-risk or architecturally significant changes.
|
Use the subagent tool to implement with maximum quality. This is for high-risk or architecturally significant changes.
|
||||||
@@ -30,7 +30,7 @@ If the user requests changes, revise the plan (re-run planner with the feedback)
|
|||||||
- For each coder run, include the approved plan verbatim: "Implement the following plan step(s). Do NOT deviate.\n\n<plan>\n{the approved plan steps}\n</plan>"
|
- For each coder run, include the approved plan verbatim: "Implement the following plan step(s). Do NOT deviate.\n\n<plan>\n{the approved plan steps}\n</plan>"
|
||||||
- For multiple independent steps, run them in parallel using separate coder-claude tasks, each assigned to specific files/plan steps to avoid conflicts
|
- For multiple independent steps, run them in parallel using separate coder-claude tasks, each assigned to specific files/plan steps to avoid conflicts
|
||||||
|
|
||||||
## Step 4: Opus review
|
## Step 4: Code review
|
||||||
Run the "reviewer" agent on all changes with this task: "Review all changes made for: $@\n\nCheck for correctness, edge cases, error handling, type safety, and consistency with the approved plan."
|
Run the "reviewer" agent on all changes with this task: "Review all changes made for: $@\n\nCheck for correctness, edge cases, error handling, type safety, and consistency with the approved plan."
|
||||||
|
|
||||||
## Step 5: Fix
|
## Step 5: Fix
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ If the user requests changes to the plan, revise and present again before implem
|
|||||||
## Step 3: Implement
|
## Step 3: Implement
|
||||||
|
|
||||||
Once approved:
|
Once approved:
|
||||||
- Execute the plan steps using "coder" for sequential steps, or "coder-parallel" with parallel tasks if the plan identified parallelizable steps
|
- Execute the plan steps using the "coder" agent
|
||||||
- When running coder, always wrap the plan step(s) in the task: "Implement the following plan step(s). Do NOT deviate.\n\n<plan>\n{the approved plan steps}\n</plan>"
|
- When running coder, always wrap the plan step(s) in the task: "Implement the following plan step(s). Do NOT deviate.\n\n<plan>\n{the approved plan steps}\n</plan>"
|
||||||
- Run the "reviewer" agent on all changes
|
- Run the "reviewer" agent on all changes
|
||||||
- If NEEDS_FIXES, run the "fixer" agent with the review output
|
- If NEEDS_FIXES, run the "fixer" agent with the review output
|
||||||
@@ -43,26 +43,13 @@ After the final step, summarize: what was done, what files changed, what was rev
|
|||||||
- **NEVER skip the approval gate**. Always present the plan and wait.
|
- **NEVER skip the approval gate**. Always present the plan and wait.
|
||||||
- Always pass scout context forward using {previous} in chain mode — this is how the planner and plan-reviewer receive the scout's findings.
|
- Always pass scout context forward using {previous} in chain mode — this is how the planner and plan-reviewer receive the scout's findings.
|
||||||
- When running the coder, always include the approved plan verbatim in the task so the coder has full context.
|
- When running the coder, always include the approved plan verbatim in the task so the coder has full context.
|
||||||
- For parallel coder tasks, clearly assign each coder to specific files/plan steps to avoid conflicts.
|
|
||||||
|
|
||||||
## Agent Failure and Fallback
|
## Agent Failure and Fallback
|
||||||
|
|
||||||
When a subagent returns empty output or an error (rate limit, credit exhaustion, connection failure):
|
When a subagent returns empty output or an error (rate limit, credit exhaustion, connection failure):
|
||||||
|
|
||||||
1. **Retry once** with the same agent and model — transient failures are common.
|
1. **Retry once** with the same agent and model — transient failures are common.
|
||||||
2. **If still failing, retry with the cross-family fallback model** using the `model` override parameter:
|
2. **If still failing, retry with the cross-family fallback model** using the `model` override parameter. See the fallback table in the `subagent-implement` SKILL.md for the current primary/fallback mapping.
|
||||||
|
|
||||||
| Agent | Primary model | Fallback model |
|
|
||||||
|-------|--------------|----------------|
|
|
||||||
| scout | zai/glm-4.7-flash | anthropic/claude-haiku-4-5 |
|
|
||||||
| deep-scout, coder-parallel | zai/glm-4.7 | anthropic/claude-sonnet-4-6 |
|
|
||||||
| planner, coder | zai/glm-5.1 | anthropic/claude-opus-4-6 |
|
|
||||||
| reviewer-quick, explorer | anthropic/claude-haiku-4-5 | zai/glm-4.7-flash |
|
|
||||||
| coder-claude, fixer | anthropic/claude-sonnet-4-6 | zai/glm-5.1 |
|
|
||||||
| plan-reviewer, reviewer | anthropic/claude-opus-4-6 | zai/glm-5.1 |
|
|
||||||
|
|
||||||
Example: `subagent({ agent: "scout", task: "...", model: "anthropic/claude-haiku-4-5" })`
|
|
||||||
|
|
||||||
3. **If the fallback also fails**, do the work yourself (read the relevant files directly and produce the scout/plan/review output inline). Inform the user which agent failed, what error was returned, and what you did instead.
|
3. **If the fallback also fails**, do the work yourself (read the relevant files directly and produce the scout/plan/review output inline). Inform the user which agent failed, what error was returned, and what you did instead.
|
||||||
|
|
||||||
Do NOT silently absorb failures. Always surface them to the user even when working around them.
|
Do NOT silently absorb failures. Always surface them to the user even when working around them.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
description: "Scout + plan + Opus plan review — no implementation"
|
description: "Scout + plan + plan review — no implementation"
|
||||||
---
|
---
|
||||||
|
|
||||||
Use the subagent tool with a chain to plan (but NOT implement) the following:
|
Use the subagent tool with a chain to plan (but NOT implement) the following:
|
||||||
@@ -19,8 +19,5 @@ Present the plan and the review to me. Do NOT proceed to implementation.
|
|||||||
If any agent returns empty output or an error (rate limit, credit exhaustion, connection failure):
|
If any agent returns empty output or an error (rate limit, credit exhaustion, connection failure):
|
||||||
|
|
||||||
1. Retry once with the same agent.
|
1. Retry once with the same agent.
|
||||||
2. If still failing, retry with the cross-family fallback using the `model` override:
|
2. If still failing, retry with the cross-family fallback using the `model` override. See the fallback table in the `subagent-plan` SKILL.md for the current mapping.
|
||||||
- scout (zai/glm-4.7-flash fails) → `model: "anthropic/claude-haiku-4-5"`
|
|
||||||
- planner (zai/glm-5.1 fails) → `model: "anthropic/claude-opus-4-6"`
|
|
||||||
- plan-reviewer (anthropic/claude-opus-4-6 fails) → `model: "zai/glm-5.1"`
|
|
||||||
3. If the fallback also fails, do the work yourself and tell me which agent failed and why.
|
3. If the fallback also fails, do the work yourself and tell me which agent failed and why.
|
||||||
|
|||||||
37
pi/.pi/agent/skills/opty/SKILL.md
Normal file
37
pi/.pi/agent/skills/opty/SKILL.md
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
---
|
||||||
|
name: opty
|
||||||
|
description: Semantic code search using HDC (Hyperdimensional Computing). Finds functions, types, imports, and variables in the indexed codebase by meaning. Use when searching for code by concept — e.g. "error handling functions", "database types", "authentication flow".
|
||||||
|
compatibility: Requires opty CLI and a running daemon. Install from source or binary.
|
||||||
|
allowed-tools: Bash(opty:*)
|
||||||
|
---
|
||||||
|
|
||||||
|
# Opty — HDC Code Search
|
||||||
|
|
||||||
|
Semantic code search via Hyperdimensional Computing. Indexes the codebase and finds relevant functions, types, and imports by meaning rather than exact text. The daemon auto-starts when you run any opty command.
|
||||||
|
|
||||||
|
## Query
|
||||||
|
|
||||||
|
```bash
|
||||||
|
opty query "natural language description of what you're looking for"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output is TOON format — compact, LLM-optimized:
|
||||||
|
```
|
||||||
|
functions[N]{name,signature,file,line}:
|
||||||
|
functionName,signature,path/to/file.ts,42
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
## Other Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
opty status # Show indexed file/unit count and watched directory
|
||||||
|
opty reindex # Force re-scan after major file changes or stale results
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tips
|
||||||
|
|
||||||
|
- Query by concept, not exact names: `"connection pool exhaustion"` not `"ConnectionPoolError"`
|
||||||
|
- Results include file + line number — use `read` to get the actual code
|
||||||
|
- `opty status` shows which directory is indexed (the daemon is per-project)
|
||||||
|
- After large refactors, run `opty reindex` if results seem stale
|
||||||
89
pi/.pi/agent/skills/qmd/SKILL.md
Normal file
89
pi/.pi/agent/skills/qmd/SKILL.md
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
---
|
||||||
|
name: qmd
|
||||||
|
description: Search markdown knowledge bases, notes, and documentation using the qmd CLI. Use when searching notes, finding documents, or looking up information in the knowledge base.
|
||||||
|
license: MIT
|
||||||
|
compatibility: Requires qmd CLI. Install via `npm install -g @tobilu/qmd`.
|
||||||
|
metadata:
|
||||||
|
author: tobi
|
||||||
|
version: "2.0.0"
|
||||||
|
allowed-tools: Bash(qmd:*)
|
||||||
|
---
|
||||||
|
|
||||||
|
# QMD - Quick Markdown Search
|
||||||
|
|
||||||
|
Local search engine for markdown content. Use via the `qmd` CLI (bash).
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
!`qmd status 2>/dev/null || echo "Not installed: npm install -g @tobilu/qmd"`
|
||||||
|
|
||||||
|
## CLI Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
qmd query "question" # Auto-expand + rerank (recommended)
|
||||||
|
qmd query $'lex: X\nvec: Y' # Structured query document
|
||||||
|
qmd query $'expand: question' # Explicit expand
|
||||||
|
qmd search "keywords" # BM25 only (no LLM)
|
||||||
|
qmd get "path/to/file.md" # Retrieve a document by path
|
||||||
|
qmd get "#abc123" # Retrieve by docid
|
||||||
|
qmd get "path/to/file.md:100" -l 50 # Retrieve starting at line 100, 50 lines
|
||||||
|
qmd multi-get "journals/2026-*.md" -l 40 # Batch fetch by glob
|
||||||
|
qmd multi-get notes/foo.md,notes/bar.md # Comma-separated list
|
||||||
|
```
|
||||||
|
|
||||||
|
## Query Types
|
||||||
|
|
||||||
|
| Type | Method | Input |
|
||||||
|
|------|--------|-------|
|
||||||
|
| `lex` | BM25 | Keywords — exact terms, names, code |
|
||||||
|
| `vec` | Vector | Question — natural language |
|
||||||
|
| `hyde` | Vector | Answer — hypothetical result (50-100 words) |
|
||||||
|
|
||||||
|
## Writing Good Queries
|
||||||
|
|
||||||
|
**lex (keyword)**
|
||||||
|
- 2-5 terms, no filler words
|
||||||
|
- Exact phrase: `"connection pool"` (quoted)
|
||||||
|
- Exclude terms: `performance -sports` (minus prefix)
|
||||||
|
- Code identifiers work: `handleError async`
|
||||||
|
|
||||||
|
**vec (semantic)**
|
||||||
|
- Full natural language question
|
||||||
|
- Be specific: `"how does the rate limiter handle burst traffic"`
|
||||||
|
|
||||||
|
**hyde (hypothetical document)**
|
||||||
|
- Write 50-100 words of what the *answer* looks like
|
||||||
|
- Use the vocabulary you expect in the result
|
||||||
|
|
||||||
|
**expand (auto-expand)**
|
||||||
|
- Single-line query (implicit) or `expand: question`
|
||||||
|
- Lets a local LLM generate lex/vec/hyde variations
|
||||||
|
- Do not mix with other typed lines
|
||||||
|
|
||||||
|
## Combining Types
|
||||||
|
|
||||||
|
| Goal | Approach |
|
||||||
|
|------|----------|
|
||||||
|
| Know exact terms | `lex` only |
|
||||||
|
| Don't know vocabulary | Single-line (implicit expand) or `vec` |
|
||||||
|
| Best recall | `lex` + `vec` |
|
||||||
|
| Complex topic | `lex` + `vec` + `hyde` |
|
||||||
|
|
||||||
|
First query gets 2x weight — put your strongest signal first.
|
||||||
|
|
||||||
|
## Lex Syntax
|
||||||
|
|
||||||
|
| Syntax | Meaning | Example |
|
||||||
|
|--------|---------|---------|
|
||||||
|
| `term` | Prefix match | `perf` matches "performance" |
|
||||||
|
| `"phrase"` | Exact phrase | `"rate limiter"` |
|
||||||
|
| `-term` | Exclude | `performance -sports` |
|
||||||
|
|
||||||
|
## Collection Filtering
|
||||||
|
|
||||||
|
```bash
|
||||||
|
qmd query --collections docs "question"
|
||||||
|
qmd query --collections docs,notes "question"
|
||||||
|
```
|
||||||
|
|
||||||
|
Omit to search all collections.
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"geminiApiKey": "AIzaSyAwY4Fyq9-9EvtjOqUAWP2TIYc02QxR9w8"
|
"provider": "auto"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,15 +9,32 @@ config.font_size = 11.0
|
|||||||
config.colors = theme.colors()
|
config.colors = theme.colors()
|
||||||
|
|
||||||
-- Window
|
-- Window
|
||||||
config.enable_tab_bar = false
|
config.enable_tab_bar = true
|
||||||
config.window_close_confirmation = 'NeverPrompt'
|
config.window_close_confirmation = 'NeverPrompt'
|
||||||
|
|
||||||
|
-- Only show tab bar when there are multiple tabs
|
||||||
|
wezterm.on('update-right-status', function(window, pane)
|
||||||
|
local overrides = window:get_config_overrides() or {}
|
||||||
|
local tabs = window:mux_window():tabs()
|
||||||
|
local show = #tabs > 1
|
||||||
|
if overrides.enable_tab_bar ~= show then
|
||||||
|
overrides.enable_tab_bar = show
|
||||||
|
window:set_config_overrides(overrides)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
-- Wayland specific fixes
|
-- Wayland specific fixes
|
||||||
config.enable_wayland = true
|
config.enable_wayland = true
|
||||||
|
|
||||||
-- Enable Kitty keyboard protocol for better key disambiguation (Ctrl+I vs Tab)
|
-- Enable Kitty keyboard protocol for better key disambiguation (Ctrl+I vs Tab)
|
||||||
config.enable_kitty_keyboard = true
|
config.enable_kitty_keyboard = true
|
||||||
|
|
||||||
|
-- Keybindings
|
||||||
|
config.keys = {
|
||||||
|
{ key = 'LeftArrow', mods = 'CTRL|SHIFT', action = wezterm.action.ActivateTabRelative(-1) },
|
||||||
|
{ key = 'RightArrow', mods = 'CTRL|SHIFT', action = wezterm.action.ActivateTabRelative(1) },
|
||||||
|
}
|
||||||
|
|
||||||
-- Machine-local overrides (not tracked in dotfiles)
|
-- Machine-local overrides (not tracked in dotfiles)
|
||||||
-- Create ~/.config/wezterm/local.lua returning a function that mutates config
|
-- Create ~/.config/wezterm/local.lua returning a function that mutates config
|
||||||
local ok, local_config = pcall(require, 'local')
|
local ok, local_config = pcall(require, 'local')
|
||||||
|
|||||||
Reference in New Issue
Block a user