[Sync] opencode 2.x
This commit is contained in:
@@ -132,8 +132,10 @@ Because configs are symlinks into the repo, **you almost never run `install.sh`
|
|||||||
| fl's Hyprland | overrides ~9 hypr files (`hyprland.conf`, keybinds, windowrules, theme colors, monitors); inherits the rest from `gui` |
|
| fl's Hyprland | overrides ~9 hypr files (`hyprland.conf`, keybinds, windowrules, theme colors, monitors); inherits the rest from `gui` |
|
||||||
| Unique apps | in the owning host overlay (fl: llamacpp/evremap; lw: xremap) |
|
| Unique apps | in the owning host overlay (fl: llamacpp/evremap; lw: xremap) |
|
||||||
|
|
||||||
`aichat`, `pi`, and `opencode` are **single shared configs** in `common` (LAN-first, with the cloud
|
`aichat`, `pi`, and `opencode` share one config in `common` (LAN-first, with the cloud provider also
|
||||||
provider also listed so any host can switch) — no per-host overrides.
|
listed so any host can switch). `lw` carries a host overlay of all three that adds its local CPU
|
||||||
|
llama.cpp models — mirror edits between the common and `lw` copies. The opencode tree is documented
|
||||||
|
in `common/.config/opencode/README.md`.
|
||||||
|
|
||||||
## HyDE dependency (important for GUI hosts)
|
## HyDE dependency (important for GUI hosts)
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,17 @@ set -gx EDITOR nvim
|
|||||||
set -gx PAGER less
|
set -gx PAGER less
|
||||||
set -gx QT_FONT_DPI 96
|
set -gx QT_FONT_DPI 96
|
||||||
set -gx PI_SKIP_VERSION_CHECK 1
|
set -gx PI_SKIP_VERSION_CHECK 1
|
||||||
# opencode GPT/Codex OAuth overlay — only where `opencode auth login` stored an OpenAI credential,
|
# opencode GPT/Codex OAuth overlay (~/.config/opencode/openai-gpt.jsonc). opencode 2.x ignores
|
||||||
# so hosts without the login don't get an unusable provider in the model picker.
|
# OPENCODE_CONFIG / OPENCODE_CONFIG_CONTENT, but it merges a second global file, opencode.jsonc.
|
||||||
if test -r ~/.local/share/opencode/auth.json; and grep -q '"openai"' ~/.local/share/opencode/auth.json
|
# Link the overlay under that name only where `opencode auth login` stored an OpenAI credential,
|
||||||
set -gx OPENCODE_CONFIG "$HOME/.config/opencode/openai-gpt.jsonc"
|
# so other hosts don't get an unusable provider; drop our link again if the login goes away.
|
||||||
|
# (Alternative: ship the link from the host's dots overlay instead of this startup check.)
|
||||||
|
set -l _oc_auth ~/.local/share/opencode/auth.json
|
||||||
|
set -l _oc_link ~/.config/opencode/opencode.jsonc
|
||||||
|
if test -r $_oc_auth; and grep -q '"openai"' $_oc_auth
|
||||||
|
test -e $_oc_link; or ln -s openai-gpt.jsonc $_oc_link
|
||||||
|
else if test -L $_oc_link; and test (readlink $_oc_link) = openai-gpt.jsonc
|
||||||
|
rm $_oc_link
|
||||||
end
|
end
|
||||||
set -gx MANPAGER "nvim +Man!"
|
set -gx MANPAGER "nvim +Man!"
|
||||||
# fzf's built-in walker is the one search tool that ignores .ignore files, so point it at
|
# fzf's built-in walker is the one search tool that ignores .ignore files, so point it at
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
# opencode config
|
||||||
|
|
||||||
|
Config tree for [opencode](https://opencode.ai) (2.x), tuned for **small local models** behind a
|
||||||
|
llama.cpp router. Stowed into `~/.config/opencode/` as per-file symlinks; editing here edits the live
|
||||||
|
config (restart opencode, or `opencode service restart`, to pick changes up — the 2.x background
|
||||||
|
service caches config).
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
| Path | What |
|
||||||
|
|---|---|
|
||||||
|
| `opencode.json` | Providers, permissions, primary agents, defaults. Written in the v1 schema, which 2.x still accepts. |
|
||||||
|
| `openai-gpt.jsonc` | Optional GPT/Codex OAuth overlay (OpenAI provider + `opencode-openai-codex-auth` plugin). Not loaded by itself — see *GPT overlay*. |
|
||||||
|
| `AGENTS.md` | Global rules prepended to every session. Same text as the pi config's `AGENTS.md`: terse, verify-before-asserting, small-model friendly. |
|
||||||
|
| `agents/*.md` | Four subagents with real prompts and scoped permissions: `code-reviewer`, `test-runner` (hidden), `doc-writer` (edits docs only), `security-auditor` (hidden). |
|
||||||
|
| `commands/*.md` | `/commit` (Conventional Commits message, never commits) and `/review` (read-only diff review), both on the `plan` agent. |
|
||||||
|
| `plugins/verbose/` | 2.x TUI plugin: `<leader>v`, `/verbose`, or the palette entry toggles the *verbose view* — thinking blocks expanded and tool calls ungrouped — reading the live state from the built-in toggles so a mixed state converges. `server.ts` is a no-op half required by the loader. |
|
||||||
|
| `themes/catppuccin-mocha.json` | Catppuccin Mocha (dark) / Latte (light) theme following the pi theme's semantic mapping. Built-in `catppuccin` exists too; this one matches pi. |
|
||||||
|
| `tui.json` | TUI settings in the v1 schema (2.x compat): theme, leader timeout, stacked diffs, block cursor, attention notifications, a few extra keybinds. |
|
||||||
|
|
||||||
|
The sandbox wrapper lives in `../fish/functions/opencodes.fish`: `opencodes` runs opencode under
|
||||||
|
bwrap with the stowed config dirs, `~/.cache/opencode`, state and data bound, and only the needed
|
||||||
|
environment passed through. Extra arguments go to opencode.
|
||||||
|
|
||||||
|
## Providers and models
|
||||||
|
|
||||||
|
Two OpenAI-compatible providers point at the same llama.cpp router: `llama.cpp` on the LAN and
|
||||||
|
`duskadiy` through the public hostname (`apiKey` from `$DUSKADIY_API_KEY`). Model ids are the preset
|
||||||
|
section names in `fl/.config/llamacpp/config.ini`; keep the lists in sync with it and with the pi and
|
||||||
|
aichat configs. Both providers use a one-hour request timeout — the default five minutes cut off
|
||||||
|
long local replies.
|
||||||
|
|
||||||
|
Decisions that look odd but are deliberate:
|
||||||
|
|
||||||
|
- **No `small_model`.** The router runs `--models-max 1`; any second model id evicts the resident one.
|
||||||
|
With `small_model` unset, title generation falls back to the session's model. Subagents carry no
|
||||||
|
pinned model for the same reason — the task tool uses the caller's model.
|
||||||
|
- **No `temperature` / `top_p` from opencode.** Verified by capturing request bodies: only
|
||||||
|
`max_tokens` is sent, so the router presets own sampling.
|
||||||
|
- **`reasoning: true`** only on the presets that actually think (no `reasoning-budget = 0`);
|
||||||
|
GLM also replays `reasoning_content` in history because its preset sets `reasoning-preserve`.
|
||||||
|
- **`snapshot: false`** — file-change undo is not used. **`tool_output`** capped at 200 lines /
|
||||||
|
16 KiB for 24k-context models. **`compaction.reserved`/`prune`** are inert at this context size.
|
||||||
|
- **`question: allow`** everywhere so agents ask instead of guessing.
|
||||||
|
|
||||||
|
## Agents
|
||||||
|
|
||||||
|
`auto` is the default agent and cycles with `build` and `plan` on Tab. It runs without prompts except
|
||||||
|
for the serious set — git history rewriting and pushing, `rm`, killing processes, `systemctl`,
|
||||||
|
network transfers, package installs — which ask, and `sudo`/`dd`/`mkfs`/secret-file reads, which are
|
||||||
|
denied. Colors: build primary, plan info, auto yellow. All three cap agentic iterations at 30.
|
||||||
|
|
||||||
|
Permission rules resolve **global first, agent rules appended, last match wins**, so an agent that
|
||||||
|
wants a blanket rule must restate its own denies after it (the `auto` block does).
|
||||||
|
|
||||||
|
## GPT overlay
|
||||||
|
|
||||||
|
`openai-gpt.jsonc` is a template. opencode 2.x ignores `OPENCODE_CONFIG`, but it merges a second
|
||||||
|
global file named `opencode.jsonc`. `fish/config.fish` links `opencode.jsonc → openai-gpt.jsonc`
|
||||||
|
only on a host whose `~/.local/share/opencode/auth.json` holds an OpenAI credential (from
|
||||||
|
`opencode auth login`), and removes the link again when the login is gone.
|
||||||
|
|
||||||
|
## Host overlays
|
||||||
|
|
||||||
|
`lw/.config/opencode/opencode.json` is a fork of the common file that adds the laptop's local CPU
|
||||||
|
llama.cpp provider (`lwcpp`). Mirror every edit between the two.
|
||||||
|
|
||||||
|
## Lifting pieces into a stock opencode
|
||||||
|
|
||||||
|
Everything is plain files: copy `agents/`, `commands/`, `plugins/verbose/` or the theme into your own
|
||||||
|
`~/.config/opencode/`. The plugin needs 2.x (it uses the `keymap.layer` / `dispatch` API and is
|
||||||
|
discovered as a directory under `plugins/`). The permission blocks in `opencode.json` are independent
|
||||||
|
of the providers and can be pasted as-is.
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://opencode.ai/config.json",
|
"$schema": "https://opencode.ai/config.json",
|
||||||
"model": "llama.cpp/gemma-4-26B-A4B-it-UD-IQ4_XS",
|
"model": "llama.cpp/gemma-4-26B-A4B-it-UD-IQ4_XS",
|
||||||
|
"default_agent": "auto",
|
||||||
"instructions": ["CLAUDE.md", "AGENTS.md"],
|
"instructions": ["CLAUDE.md", "AGENTS.md"],
|
||||||
"share": "disabled",
|
"share": "disabled",
|
||||||
"autoupdate": "notify",
|
"autoupdate": "notify",
|
||||||
@@ -303,47 +304,6 @@
|
|||||||
"grep * .env*": "deny"
|
"grep * .env*": "deny"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"code-reviewer": {
|
|
||||||
"description": "Reviews code for best practices and potential issues",
|
|
||||||
"prompt": "You are a code reviewer. Focus on security, performance, and maintainability.",
|
|
||||||
"mode": "subagent",
|
|
||||||
"permission": {
|
|
||||||
"edit": "deny"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"test-runner": {
|
|
||||||
"description": "Runs and interprets test suites",
|
|
||||||
"prompt": "You are a test runner. Focus on identifying failing tests and providing clear reproduction steps.",
|
|
||||||
"mode": "subagent",
|
|
||||||
"hidden": true,
|
|
||||||
"permission": {
|
|
||||||
"edit": "deny"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"doc-writer": {
|
|
||||||
"description": "Maintains project documentation and docstrings",
|
|
||||||
"prompt": "You are a technical writer. Focus on clarity, accuracy, and keeping documentation in sync with code changes.",
|
|
||||||
"mode": "subagent",
|
|
||||||
"permission": {
|
|
||||||
"edit": {
|
|
||||||
"*": "deny",
|
|
||||||
"**/*.md": "allow",
|
|
||||||
"**/*.mdx": "allow",
|
|
||||||
"**/*.markdown": "allow",
|
|
||||||
"**/*.txt": "allow",
|
|
||||||
"**/*.rst": "allow"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"security-auditor": {
|
|
||||||
"description": "Scans for security vulnerabilities and hardcoded secrets",
|
|
||||||
"prompt": "You are a security auditor. Focus on OWASP principles, secret detection, and dependency vulnerabilities.",
|
|
||||||
"mode": "subagent",
|
|
||||||
"hidden": true,
|
|
||||||
"permission": {
|
|
||||||
"edit": "deny"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// opencode v2 plugin "coja.verbose" — server half. Intentionally empty: all behaviour is in ./tui.ts.
|
||||||
|
// A local plugin is a DIRECTORY under ~/.config/opencode/plugins/ whose `server`/`index` and `tui`
|
||||||
|
// modules are resolved by name (packages/plugin/src/host.ts resolve()). No imports on purpose:
|
||||||
|
// `define()` is an identity helper, and a dependency-free module needs no node_modules.
|
||||||
|
export default {
|
||||||
|
id: "coja.verbose",
|
||||||
|
setup() {},
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
// opencode v2 TUI plugin: one key toggles the "verbose view".
|
||||||
|
//
|
||||||
|
// v2 dropped the v1 tool-details / timestamps / generic-output toggles. The session view now has two
|
||||||
|
// display toggles that matter: thinking blocks (session.thinking show|hide) and exploration grouping
|
||||||
|
// (session.grouping auto|none — "auto" folds read/glob/grep tool calls into one collapsed group).
|
||||||
|
// Verbose = thinking expanded AND tool calls shown individually. Both settings persist in the TUI config.
|
||||||
|
//
|
||||||
|
// State is read from the built-in commands' live titles (the only plugin-visible signal):
|
||||||
|
// session.toggle.thinking → "Collapse thinking" while expanded, else "Expand thinking"
|
||||||
|
// session.toggle.exploration_grouping → "Show tool calls individually" while grouped, else "Group related tool calls"
|
||||||
|
// then only the toggles that differ from the target are dispatched, so a mixed state converges.
|
||||||
|
//
|
||||||
|
// Auto-discovered from ~/.config/opencode/plugins/verbose/ (server.ts + this file). Key configurable
|
||||||
|
// via plugin options; default <leader>v. Also /verbose and a command-palette entry.
|
||||||
|
const THINKING = "session.toggle.thinking"
|
||||||
|
const GROUPING = "session.toggle.exploration_grouping"
|
||||||
|
|
||||||
|
type Command = { readonly id?: string; readonly title?: string }
|
||||||
|
type Context = {
|
||||||
|
readonly options?: Readonly<Record<string, unknown>>
|
||||||
|
readonly keymap: {
|
||||||
|
layer(input: () => { readonly commands?: readonly unknown[] }): void
|
||||||
|
dispatch(id: string, input?: string): void
|
||||||
|
commands(): readonly Command[]
|
||||||
|
}
|
||||||
|
readonly ui: { readonly toast: { show(o: { message: string; variant?: string; duration?: number }): void } }
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
id: "coja.verbose",
|
||||||
|
setup(context: Context) {
|
||||||
|
const key = typeof context.options?.key === "string" && context.options.key ? (context.options.key as string) : "<leader>v"
|
||||||
|
const title = (id: string) => context.keymap.commands().find((c) => c.id === id)?.title ?? ""
|
||||||
|
|
||||||
|
context.keymap.layer(() => ({
|
||||||
|
commands: [
|
||||||
|
{
|
||||||
|
id: "verbose.toggle",
|
||||||
|
title: "Toggle verbose view (expand thinking, ungroup tool calls)",
|
||||||
|
group: "Session",
|
||||||
|
bind: key,
|
||||||
|
palette: true,
|
||||||
|
slash: { name: "verbose" },
|
||||||
|
run() {
|
||||||
|
const thinkingTitle = title(THINKING)
|
||||||
|
const groupingTitle = title(GROUPING)
|
||||||
|
if (!thinkingTitle && !groupingTitle) {
|
||||||
|
context.ui.toast.show({ message: "Verbose view: open a session first", variant: "warning", duration: 2000 })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const thinkingVerbose = thinkingTitle.startsWith("Collapse")
|
||||||
|
const groupingVerbose = groupingTitle.startsWith("Group")
|
||||||
|
const on = !(thinkingVerbose && groupingVerbose)
|
||||||
|
if (thinkingTitle && thinkingVerbose !== on) context.keymap.dispatch(THINKING)
|
||||||
|
if (groupingTitle && groupingVerbose !== on) context.keymap.dispatch(GROUPING)
|
||||||
|
context.ui.toast.show({ message: on ? "Verbose view on" : "Verbose view off", variant: "info", duration: 1500 })
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}))
|
||||||
|
},
|
||||||
|
}
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
// opencode TUI plugin: one key toggles the whole "verbose view".
|
|
||||||
//
|
|
||||||
// The session view keeps four independent display toggles in the TUI's persisted KV store
|
|
||||||
// (~/.local/state/opencode/kv.json). Built-in commands only flip one each. This plugin reads all
|
|
||||||
// four and drives them to the same state: if every one is on, turn all off; otherwise turn all on.
|
|
||||||
// Writing the KV keys directly is what the built-in toggles do too (kv.signal is a reactive
|
|
||||||
// store), so the open session re-renders immediately and the choice survives restarts.
|
|
||||||
//
|
|
||||||
// Declared in tui.json: "plugin": [["./tui-plugins/verbose.ts", { "key": "<leader>v" }]]
|
|
||||||
// (TUI plugins are never auto-discovered, and this dir is deliberately NOT ~/.config/opencode/plugins/,
|
|
||||||
// which the server-side plugin loader scans and would reject a TUI-only module.)
|
|
||||||
// Also available as /verbose and from the command palette.
|
|
||||||
import type { TuiPlugin, TuiPluginApi, TuiPluginModule } from "@opencode-ai/plugin/tui"
|
|
||||||
|
|
||||||
// KV keys + values as used by packages/tui/src/routes/session/index.tsx and context/thinking.ts (v1.18.29)
|
|
||||||
const KEYS = {
|
|
||||||
details: "tool_details_visibility", // boolean, default true
|
|
||||||
generic: "generic_tool_output_visibility", // boolean, default false
|
|
||||||
timestamps: "timestamps", // "show" | "hide", default "hide"
|
|
||||||
thinking: "thinking_mode", // "show" | "hide", default "hide"
|
|
||||||
} as const
|
|
||||||
|
|
||||||
const COMMAND = "verbose.toggle"
|
|
||||||
|
|
||||||
function current(api: TuiPluginApi) {
|
|
||||||
return {
|
|
||||||
details: api.kv.get<boolean>(KEYS.details, true) === true,
|
|
||||||
generic: api.kv.get<boolean>(KEYS.generic, false) === true,
|
|
||||||
timestamps: api.kv.get<string>(KEYS.timestamps, "hide") === "show",
|
|
||||||
thinking: api.kv.get<string>(KEYS.thinking, "hide") === "show",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function apply(api: TuiPluginApi, on: boolean) {
|
|
||||||
api.kv.set(KEYS.details, on)
|
|
||||||
api.kv.set(KEYS.generic, on)
|
|
||||||
api.kv.set(KEYS.timestamps, on ? "show" : "hide")
|
|
||||||
api.kv.set(KEYS.thinking, on ? "show" : "hide")
|
|
||||||
}
|
|
||||||
|
|
||||||
const tui: TuiPlugin = async (api, options) => {
|
|
||||||
const opts = (options ?? {}) as Record<string, unknown>
|
|
||||||
const key = typeof opts.key === "string" && opts.key.length > 0 ? opts.key : "<leader>v"
|
|
||||||
|
|
||||||
api.keymap.registerLayer({
|
|
||||||
mode: "base",
|
|
||||||
commands: [
|
|
||||||
{
|
|
||||||
name: COMMAND,
|
|
||||||
title: "Toggle verbose view (tool details, generic output, thinking, timestamps)",
|
|
||||||
category: "Session",
|
|
||||||
namespace: "palette",
|
|
||||||
slashName: "verbose",
|
|
||||||
run() {
|
|
||||||
const state = current(api)
|
|
||||||
const on = !Object.values(state).every(Boolean)
|
|
||||||
apply(api, on)
|
|
||||||
api.ui.toast({
|
|
||||||
variant: "info",
|
|
||||||
message: on ? "Verbose view on" : "Verbose view off",
|
|
||||||
duration: 1500,
|
|
||||||
})
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
bindings: [{ key, cmd: COMMAND, desc: "Toggle verbose view" }],
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const plugin: TuiPluginModule & { id: string } = { id: "coja.verbose", tui }
|
|
||||||
export default plugin
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://opencode.ai/tui.json",
|
"$schema": "https://opencode.ai/tui.json",
|
||||||
"theme": "lucent-orng",
|
"theme": "lucent-orng",
|
||||||
"plugin": [["./tui-plugins/verbose.ts", { "key": "<leader>v" }]],
|
|
||||||
"leader_timeout": 1500,
|
"leader_timeout": 1500,
|
||||||
"diff_style": "stacked",
|
"diff_style": "stacked",
|
||||||
"cursor": { "style": "block", "blinking": false },
|
"cursor": { "style": "block", "blinking": false },
|
||||||
@@ -11,8 +10,6 @@
|
|||||||
"prompt_stash_pop": "<leader>o",
|
"prompt_stash_pop": "<leader>o",
|
||||||
"session_fork": "<leader>f",
|
"session_fork": "<leader>f",
|
||||||
"messages_last_user": "<leader>k",
|
"messages_last_user": "<leader>k",
|
||||||
"display_thinking": "<leader>i",
|
"display_thinking": "<leader>i"
|
||||||
"tool_details": "<leader>d",
|
|
||||||
"session_toggle_timestamps": "<leader>w"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://opencode.ai/config.json",
|
"$schema": "https://opencode.ai/config.json",
|
||||||
"model": "llama.cpp/gemma-4-26B-A4B-it-UD-IQ4_XS",
|
"model": "llama.cpp/gemma-4-26B-A4B-it-UD-IQ4_XS",
|
||||||
|
"default_agent": "auto",
|
||||||
"instructions": ["CLAUDE.md", "AGENTS.md"],
|
"instructions": ["CLAUDE.md", "AGENTS.md"],
|
||||||
"share": "disabled",
|
"share": "disabled",
|
||||||
"autoupdate": "notify",
|
"autoupdate": "notify",
|
||||||
@@ -321,47 +322,6 @@
|
|||||||
"grep * .env*": "deny"
|
"grep * .env*": "deny"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"code-reviewer": {
|
|
||||||
"description": "Reviews code for best practices and potential issues",
|
|
||||||
"prompt": "You are a code reviewer. Focus on security, performance, and maintainability.",
|
|
||||||
"mode": "subagent",
|
|
||||||
"permission": {
|
|
||||||
"edit": "deny"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"test-runner": {
|
|
||||||
"description": "Runs and interprets test suites",
|
|
||||||
"prompt": "You are a test runner. Focus on identifying failing tests and providing clear reproduction steps.",
|
|
||||||
"mode": "subagent",
|
|
||||||
"hidden": true,
|
|
||||||
"permission": {
|
|
||||||
"edit": "deny"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"doc-writer": {
|
|
||||||
"description": "Maintains project documentation and docstrings",
|
|
||||||
"prompt": "You are a technical writer. Focus on clarity, accuracy, and keeping documentation in sync with code changes.",
|
|
||||||
"mode": "subagent",
|
|
||||||
"permission": {
|
|
||||||
"edit": {
|
|
||||||
"*": "deny",
|
|
||||||
"**/*.md": "allow",
|
|
||||||
"**/*.mdx": "allow",
|
|
||||||
"**/*.markdown": "allow",
|
|
||||||
"**/*.txt": "allow",
|
|
||||||
"**/*.rst": "allow"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"security-auditor": {
|
|
||||||
"description": "Scans for security vulnerabilities and hardcoded secrets",
|
|
||||||
"prompt": "You are a security auditor. Focus on OWASP principles, secret detection, and dependency vulnerabilities.",
|
|
||||||
"mode": "subagent",
|
|
||||||
"hidden": true,
|
|
||||||
"permission": {
|
|
||||||
"edit": "deny"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user