···11+---
22+description: Exploratory read-only agent for searching, analyzing, and asking questions about the codebase.
33+mode: primary
44+temperature: 0.1
55+tools:
66+tools:
77+ read: true
88+ glob: true
99+ grep: true
1010+ edit: false
1111+ bash: true
1212+ todowrite: false
1313+ todoread: false
1414+permission:
1515+ edit: deny
1616+ bash:
1717+ "*": ask
1818+ "ls *": allow
1919+ "cat *": allow
2020+ "grep *": allow
2121+ "find *": allow
2222+ "rg *": allow
2323+ "fd *": allow
2424+ "git diff*": allow
2525+ "git log*": allow
2626+ "git status": allow
2727+ "git show*": allow
2828+---
2929+3030+You are the "Ask" agent, a senior software architect and codebase explorer. Your purpose is entirely exploratory and analytical. The user interacting with you is a domain expert and fellow senior engineer. They will ask you to search for things, trace execution paths, and analyze high-level architectural patterns or complex implementation details.
3131+3232+# Core Directives:
3333+3434+1. **Strictly Read-Only:** You operate in a purely exploratory environment. Do not attempt to modify, refactor, or write new code to the file system.
3535+3636+2. **Active Exploration & Precision:** Leverage read-only bash commands (`grep`, `rg`, `find`, `cat`, `ls`) to actively traverse the codebase. Do not guess—base all your answers on actual code reality. Always ground your analysis with precise, valid file paths and line references.
3737+3838+3. **Expert-Level Analysis:** Communicate peer-to-peer. Assume the user has deep technical fluency. Focus your explanations on architectural patterns, system constraints, data flow, and idiomatic usage. Gloss over basic syntax or trivial lexical differences. Get straight to the point without introductory fluff or over-explaining standard concepts.
3939+4040+4. **Proactive Investigation:** If given a high-level query (e.g., "Where is the auth middleware?"), autonomously locate the relevant implementations, trace the usage patterns, and present a concise, highly technical summary of the underlying mechanics.
4141+4242+5. **Boundary Enforcement:** If the user requests code modifications, politely decline, remind them of your read-only constraints, and advise them to use the `build` agent to apply changes.
···11-# Global Coding Rules
22-33-## NO STUBS - ABSOLUTE RULE
44-55-- NEVER write `TODO`, `FIXME`, `pass`, `...`, `unimplemented!()`
66-- NEVER write empty function bodies or placeholder returns
77-- If too complex for one turn: throw an error/exception with a clear reason
88-99-## Core Rules
1010-1111-1. **READ BEFORE WRITE**: Always read a file before editing.
1212-2. **FULL FEATURES**: Complete the feature, don't stop partway.
1313-3. **ERROR HANDLING**: No panics/crashes on bad input.
1414-4. **SECURITY**: Validate input, parameterized queries, no hardcoded secrets.
1515-5. **NO DEAD CODE**: Remove or complete incomplete code.
1616-1717-## Chainlink Lifecycle Management
1818-1919-You MUST use Chainlink to track all work:
2020-2121-- **Session Start**: `chainlink session start` - shows previous handoff
2222-- **Session Work**: `chainlink session work <id>` - mark current focus
2323-- **Progress**: `chainlink comment <id> "..."` - update regularly
2424-- **Session End**: `chainlink session end --notes "..."` - REQUIRED before stopping
2525-2626-### Handoff Notes Format
2727-2828-```markdown
2929-**Accomplished:**
3030-- Completed feature X
3131-- Added tests for Y
3232-3333-**In Progress:**
3434-- Working on feature Z
3535-3636-**Next:**
3737-- Complete feature Z
3838-- Run tests
3939-4040-**Blockers:**
4141-- None
4242-```
4343-4444-## Code Quality Requirements
4545-4646-- **NO DEAD CODE**: Remove unused functions, variables, imports
4747-- **NO HARDCODED SECRETS**: Use environment variables, configs
4848-- **COMMIT FREQUENTLY**: Small, focused commits
4949-- **DESCRIPTIVE COMMITS**: Explain WHY, not just WHAT
5050-5151-## Security
5252-5353-- Validate ALL inputs (user, network, config)
5454-- Use parameterized queries for database access
5555-- Never log sensitive data (passwords, tokens, keys)
5656-- Follow principle of least privilege
-95
modules/opencode/rules/go.md
···11-### Go Best Practices
22-33-Follow [Effective Go](https://go.dev/doc/effective_go) and [Go Code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments).
44-55-#### Code Style & Structure
66-77-- **Existing Style**: The best Go style is the existing style. Adapt to existing patterns and conventions in the codebase as much as possible.
88-- **Small Interfaces**: Keep interfaces small (often 1-3 methods). "The bigger the interface, the weaker the abstraction."
99-- **Deep Modules**: Design modules with simple interfaces that hide significant complexity (deep vs. shallow).
1010-- **Align Left**: Keep the "happy path" aligned to the left.
1111-- **Early Returns**: Use guard clauses to handle errors and edge cases early, reducing nesting.
1212-- **Avoid Else**: Avoid `else` blocks; they often indicate complex branching that can be flattened with early returns.
1313-- **No Naked Returns**: Avoid using named return parameters for actual returns.
1414-- **Latest Features**: Leverage modern Go features (generics, `any`, `net/http` routing enhancements, `log/slog`, `t.Context()`).
1515-- **Simple Functions**: Write small, focused functions that do one thing well.
1616-- **Avoid God Objects**: Don't create types that try to do everything. Use composition.
1717-- **Pure Code**: Prefer pure functions where possible.
1818-- **Easy to Mock**: Accept interfaces, return structs. Use dependency injection.
1919-2020-#### Error Handling
2121-2222-Always check and handle errors immediately. Wrap errors with context.
2323-2424-```go
2525-// GOOD: Early returns, aligned left, no else
2626-func readConfig(path string) (*Config, error) {
2727- data, err := os.ReadFile(path)
2828- if err != nil {
2929- return nil, fmt.Errorf("read config: %w", err)
3030- }
3131-3232- var config Config
3333- if err := json.Unmarshal(data, &config); err != nil {
3434- return nil, fmt.Errorf("parse config: %w", err)
3535- }
3636-3737- return &config, nil
3838-}
3939-4040-// BAD: Nested, use of else, harder to follow
4141-func readConfig(path string) (*Config, error) {
4242- data, err := os.ReadFile(path)
4343- if err == nil {
4444- var config Config
4545- err = json.Unmarshal(data, &config)
4646- if err == nil {
4747- return &config, nil
4848- } else {
4949- return nil, err
5050- }
5151- } else {
5252- return nil, err
5353- }
5454-}
5555-```
5656-5757-#### Concurrency & Sync
5858-5959-- **Package sync**: Use `sync.Mutex`, `sync.RWMutex`, `sync.Once`, and `sync.Pool` extensively.
6060-- **sync.WaitGroup**: Use for waiting on multiple goroutines.
6161-- **Channels**: Use for coordination between goroutines.
6262-- **Context**: Always propagate `context.Context`. Use `t.Context()` in tests for automatic cleanup.
6363-- **Atomic**: Use `sync/atomic` for simple counter/state updates.
6464-6565-#### Testing
6666-6767-Use the standard `testing` package effectively.
6868-6969-- **Table-Driven Tests**: Use anonymous structs for test cases with clear `name`, `got`, and `want` fields.
7070-- **t.Context()**: Use `t.Context()` for test-scoped context that cancels when the test finishes.
7171-- **Few Functions, Good Tables**: Prefer one robust test function with a comprehensive table over many small test functions.
7272-- **Helper Functions**: Use `t.Helper()` in functions that assist in testing to keep stack traces clean.
7373-7474-```go
7575-func TestSum(t *testing.T) {
7676- tests := []struct {
7777- name string
7878- args []int
7979- want int
8080- }{
8181- {"empty", []int{}, 0},
8282- {"single", []int{1}, 1},
8383- {"multiple", []int{1, 2, 3}, 6},
8484- {"negative", []int{1, -1}, 0},
8585- }
8686-8787- for _, tt := range tests {
8888- t.Run(tt.name, func(t *testing.T) {
8989- if got := Sum(tt.args); got != tt.want {
9090- t.Errorf("Sum() = %v, want %v", got, tt.want)
9191- }
9292- })
9393- }
9494-}
9595-```
-36
modules/opencode/rules/javascript.md
···11-### JavaScript Best Practices
22-33-#### Code Style
44-- Use `const` by default, `let` when needed, never `var`
55-- Use arrow functions for callbacks
66-- Use template literals over string concatenation
77-- Use destructuring for object/array access
88-99-#### Error Handling
1010-```javascript
1111-// GOOD: Proper async error handling
1212-async function fetchUser(id) {
1313- try {
1414- const response = await fetch(`/api/users/${id}`);
1515- if (!response.ok) {
1616- throw new Error(`HTTP ${response.status}`);
1717- }
1818- return await response.json();
1919- } catch (error) {
2020- console.error('Failed to fetch user:', error);
2121- throw error; // Re-throw or handle appropriately
2222- }
2323-}
2424-2525-// BAD: Ignoring errors
2626-async function fetchUser(id) {
2727- const response = await fetch(`/api/users/${id}`);
2828- return response.json(); // No error handling
2929-}
3030-```
3131-3232-#### Security
3333-- Never use `eval()` or `innerHTML` with user input
3434-- Validate all input on both client and server
3535-- Use `textContent` instead of `innerHTML` when possible
3636-- Sanitize URLs before navigation or fetch
-306
modules/opencode/rules/nix.md
···11-# Nix Best Practices
22-33-## Code Style
44-55-- Use `nixfmt` for formatting (set as formatter in flake, run `nix fmt` before committing)
66-- Follow the [Nixpkgs contributing guide](https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md) for style conventions
77-- Use descriptive variable names that explain purpose
88-- Prefer `let ... in` blocks for local bindings over deep nesting
99-- Keep derivations and functions small and composable
1010-- Use `lib.mkIf`, `lib.mkWhen`, `lib.optionals` for conditional logic
1111-- Use `lib.getExe` and `lib.getExe'` for accessing package executables
1212-1313-## Error Handling
1414-1515-```nix
1616-# GOOD: Proper error handling with builtins.tryEval
1717-let
1818- configPath = ./config.json;
1919- config = builtins.tryEval (builtins.fromJSON (builtins.readFile configPath));
2020-in
2121-if config.success then config.value else throw "Failed to parse config"
2222-2323-# GOOD: Using assert statements for validation
2424-assert lib.assertMsg (cfg.port > 0 && cfg.port < 65536) "Port must be between 1 and 65535";
2525-cfg
2626-2727-# GOOD: Using lib.mapAttrs' with lib.nameValuePair for building attribute sets
2828-lib.mapAttrs' (argName: argValue:
2929- lib.nameValuePair "${argName}+${dir.name}" {
3030- action = {
3131- "${argValue}-${dir.value}" = [ ];
3232- };
3333- }
3434-) act
3535-3636-# BAD: Silent failures or incomplete error messages
3737-let
3838- data = builtins.readFile configPath;
3939- config = builtins.fromJSON data; # Will throw cryptic error if invalid
4040-in config
4141-```
4242-4343-## Nix Module System
4444-4545-- Use `lib.mkOptionType`, `lib.mkDefault`, `lib.mkForce` appropriately
4646-- Prefer `mkOption` with proper `type`, `default`, and `description` fields
4747-- Use `mkIf` for conditional module options rather than deep nesting
4848-- Keep modules focused - one module per responsibility
4949-- Use `imports` to compose modules rather than duplicating code
5050-- Use `lib.getExe pkgs.packageName` for executable paths in configuration
5151-5252-```nix
5353-# GOOD: Well-structured module option
5454-{ lib, config, ... }:
5555-{
5656- options.my.username = lib.mkOption {
5757- type = lib.types.str;
5858- description = "The username for the current user.";
5959- default = "kar";
6060- };
6161-6262- config = lib.mkIf (config.my.username != "root") {
6363- users.users.${config.my.username} = {
6464- home = "/home/${config.my.username}";
6565- initialPassword = "";
6666- isNormalUser = true;
6767- extraGroups = [
6868- "networkmanager"
6969- "docker"
7070- "wheel"
7171- ];
7272- };
7373- };
7474-}
7575-```
7676-7777-## Flake Patterns
7878-7979-- Use `flake-parts` for modular flake structure
8080-- Use `withSystem` for system-specific configuration
8181-- Provide `devShells`, `packages`, `checks`, `formatter` per system
8282-- Lock `nixpkgs` reference using channel URLs or specific revisions
8383-- Provide formatter and linter in `devShells`
8484-- Use `nixConfig` for Nix configuration (experimental features, substituters)
8585-8686-## System Management
8787-8888-- Use `easy-hosts` for organizing hosts by class (desktop, server, wsl) and tags
8989-- Define shared modules for all systems in `config.easy-hosts.shared.modules`
9090-- Use perClass and perTag for class-specific and tag-specific modules
9191-- Use `mkSystem'` for creating individual systems with proper specialArgs
9292-9393-## Overlay Patterns
9494-9595-- Use `overrideAttrs` for patching existing packages
9696-- Use `fetchurl` or `fetchFromGitHub` for patches with hash verification
9797-- Use `callPackage` to add packages to overlay
9898-- Keep overlays focused and well-documented
9999-100100-## Package Building
101101-102102-- Use `pkgs.buildGoModule` for Go packages with proper vendorHash
103103-- Use `pkgs.fetchFromGitHub` for GitHub sources with hash verification
104104-- Set `env.CGO_ENABLED`, `flags`, and `ldflags` appropriately for Go
105105-- Include proper `meta` with description, homepage, license, maintainers
106106-- Use `trimpath` and static linking flags for production binaries
107107-108108-## Security
109109-110110-- Never commit secrets or API keys in Nix files
111111-- Use `sops-nix` for secrets management in production
112112-- Use sandbox mode in `nix.conf` (`sandbox = true`) for builds
113113-- Review network access in derivations - use `allowedRequisites` for purity
114114-- Use `fetchFromGitHub` or `fetchurl` with hash verification
115115-116116-## Dependency Management
117117-118118-- Use specific Git revisions/commits for Git dependencies (not branches)
119119-- Always include `sha256` hash for fetch functions
120120-- Use `inputs.nixpkgs.follows` to avoid duplicating inputs
121121-- Pin `nixpkgs` in production configurations using `flake.lock`
122122-- Prefer `flake-inputs` over `builtins.fetchTarball` for external sources
123123-- Use `callPackage` pattern for package dependencies
124124-125125-## Testing
126126-127127-- Use `nix-instantiate --parse` to check for syntax errors
128128-- Use `nix-build` with `-A` to test specific attributes
129129-- Write checks in `perSystem.checks` for package testing
130130-- Use `nix flake check` for flake validation
131131-- Test modules with `nixos-rebuild dry-build` or `nixos-rebuild test`
132132-133133-## Evaluation
134134-135135-- Use `lib.warnIf` and `lib.deprecated` for deprecation notices
136136-- Avoid `builtins.trace` in production code (use for debugging only)
137137-- Use `lib.lists.foldl'` or `lib.lists.foldl'` for strict left folds
138138-- Prefer `lib.mapAttrs` and `lib.mapAttrs'` over `builtins.map` for attribute sets
139139-- Use `lib.filterAttrs` for filtering attributes
140140-- Use `lib.mergeAttrsList` for merging lists of attribute sets
141141-- Use `lib.attrsToList` for converting attributes to list of name-value pairs
142142-143143-## Performance
144144-145145-- Use `lib.optionals` and `lib.concatMap` for list operations
146146-- Avoid deep recursion - use `foldl'` for accumulation
147147-- Use `overrideAttrs` for modifying packages instead of rewriting
148148-- Prefer `stdenv.mkDerivation` over raw `derivation` for packages
149149-- Use `pkgs.callPackage` with explicit arguments for clarity
150150-151151-## Home-Manager Module System
152152-153153-Home-manager modules manage user-level configuration (home directory, user packages, programs).
154154-155155-### Module Structure
156156-157157-```
158158-modules/
159159- dev/
160160- home.nix # Home-manager module with osConfig parameter
161161- nixos.nix # NixOS module importing home.nix via homeModules
162162- shell/
163163- default.nix # Imports sub-modules
164164- nushell.nix # Actual configuration
165165-```
166166-167167-### Home-Manager Module Pattern
168168-169169-```nix
170170-# modules/dev/shell/default.nix
171171-{
172172- imports = [
173173- ./atuin.nix
174174- ./nushell.nix
175175- ./starship.nix
176176- ./zellij.nix
177177- ];
178178-}
179179-```
180180-181181-### Home-Manager with osConfig
182182-183183-```nix
184184-# modules/dev/home.nix
185185-{
186186- osConfig ? { },
187187- lib,
188188- ...
189189-}:
190190-let
191191- inherit (lib) mkEnableOption;
192192-in
193193-{
194194- # Inherit options from NixOS module configuration
195195- config.dev = {
196196- inherit (osConfig.dev or { })
197197- shell
198198- editor
199199- vcs
200200- tools
201201- ;
202202- };
203203-204204- # Define options (mirrors NixOS module)
205205- options.dev = {
206206- enable = mkEnableOption "all development tools";
207207- shell.enable = mkEnableOption "shell-related tools";
208208- editor.enable = mkEnableOption "editor tools";
209209- vcs.enable = mkEnableOption "version control tools";
210210- tools.enable = mkEnableOption "development utilities";
211211- };
212212-213213- # Import sub-modules
214214- imports = [
215215- ./shell
216216- ./editor
217217- ./vcs
218218- ./tools
219219- ];
220220-}
221221-```
222222-223223-### Flake Integration
224224-225225-```nix
226226-# flake.nix modules section
227227-{
228228- imports = [ ../systems ];
229229-230230- perSystem = { ... }: {
231231- # ...
232232- };
233233-234234- flake = {
235235- homeModules = {
236236- dev = import ./dev/home.nix;
237237- desktop = import ./desktop/home.nix;
238238- };
239239-240240- nixosModules = {
241241- dev = import ./dev/nixos.nix;
242242- desktop = import ./desktop/nixos.nix;
243243- };
244244- };
245245-}
246246-```
247247-248248-### Usage in System Configuration
249249-250250-```nix
251251-# systems/kiwi.nix (NixOS)
252252-{
253253- imports = [
254254- inputs.self.nixosModules.dev
255255- # ... other modules
256256- ];
257257-258258- dev.enable = true;
259259- dev.shell.enable = true;
260260-}
261261-```
262262-263263-```nix
264264-# modules/desktop/home.nix (Home-Manager)
265265-{ config, self, ... }:
266266-{
267267- imports = [
268268- self.homeModules.dev
269269- # ... other home modules
270270- ];
271271-272272- dev.enable = true;
273273-}
274274-```
275275-276276-### Key Differences from NixOS Modules
277277-278278-| Aspect | NixOS Module | Home-Manager Module |
279279-|--------|--------------|---------------------|
280280-| Special args | `{ config, lib, pkgs, ... }` | `{ config, lib, pkgs, osConfig ? {}, ... }` |
281281-| System config | Direct access to `config.*` | Inherits via `osConfig.dev` |
282282-| User packages | `home.packages` | `home.packages` |
283283-| Programs | `programs.*` | `programs.*` |
284284-| System services | `services.*` | Not available |
285285-286286-### XDG Directories
287287-288288-Home-manager manages XDG directories via `xdg.configFile`, `xdg.dataFile`, etc.:
289289-290290-```nix
291291-{ config, ... }:
292292-{
293293- xdg.configFile."opencode/agents" = {
294294- source = ./agents;
295295- recursive = true;
296296- };
297297-298298- programs.opencode = {
299299- enable = true;
300300- package = opencodePkg;
301301- settings = {
302302- theme = "catppuccin-macchiato";
303303- };
304304- };
305305-}
306306-```
-35
modules/opencode/rules/typescript.md
···11-### TypeScript Best Practices
22-33-#### Code Style
44-- Use strict mode (`"strict": true` in tsconfig.json)
55-- Prefer `interface` over `type` for object shapes
66-- Use `const` by default, `let` when needed, never `var`
77-- Enable `noImplicitAny` and `strictNullChecks`
88-99-#### Type Safety
1010-```typescript
1111-// GOOD: Explicit types and null handling
1212-function getUser(id: string): User | undefined {
1313- return users.get(id);
1414-}
1515-1616-const user = getUser(id);
1717-if (user) {
1818- console.log(user.name); // TypeScript knows user is defined
1919-}
2020-2121-// BAD: Type assertions to bypass safety
2222-const user = getUser(id) as User; // Dangerous if undefined
2323-console.log(user.name); // Might crash
2424-```
2525-2626-#### Error Handling
2727-- Use try/catch for async operations
2828-- Define custom error types for domain errors
2929-- Never swallow errors silently
3030-3131-#### Security
3232-- Validate all user input at API boundaries
3333-- Use parameterized queries for database operations
3434-- Sanitize data before rendering in DOM (prevent XSS)
3535-- Never use `eval()` or `Function()` with user input