Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/agents/prompts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ export interface PromptContext {
// Capacity / pipeline management
maxInFlightItems?: number;

// Squint codebase intelligence
squintEnabled?: boolean;

// Future extensibility
[key: string]: unknown;
}
Expand Down Expand Up @@ -340,6 +343,11 @@ export function getTemplateVariables(): Array<{
group: 'Capacity',
description: 'Maximum number of items allowed in the active pipeline at once (default: 1)',
},
{
name: 'squintEnabled',
group: 'Squint',
description: 'Whether the repository has a Squint database (.squint.db) available',
},
];
}

Expand Down
9 changes: 5 additions & 4 deletions src/agents/prompts/templates/implementation.eta
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ You are an expert software engineer implementing features and fixing issues base
### Phase 1: Understand

1. **Review the pre-loaded work item data** and verify your pre-populated todo list matches the implementation plan
2. **Consult the pre-loaded Squint overview** — identify which features and modules relate to the <%= it.workItemNoun || 'card' %>
<% if (it.squintEnabled) { %>2. **Consult the pre-loaded Squint overview** — identify which features and modules relate to the <%= it.workItemNoun || 'card' %>
3. **MANDATORY: Drill into features and modules before reading any source files:**
- `squint features show <slug> --json` for each relevant feature — returns its flows, modules involved, and interactions
- `squint flows show <slug> --json` for each relevant flow — returns the ordered interaction chain with entry point and definition-level call trace across modules
- `squint modules show <path> --json` for each module area the <%= it.workItemNoun || 'card' %> touches — returns members, outgoing/incoming interactions, flows, and features
- This reveals cross-cutting dependencies (e.g., backend response shapes that frontend tests must match) that you will MISS by reading individual files
4. **Read codebase guidelines** - CLAUDE.md, AGENTS.md (these are meta-docs about conventions)
5. **THEN read source files** — only the files Squint identified as relevant. Use `squint symbols list --file <path> --json` to understand a file's full architectural role before reading its source.
5. **THEN read source files** — only the files Squint identified as relevant. Use `squint symbols list --file <path> --json` to understand a file's full architectural role before reading its source.<% } else { %>2. **Read codebase guidelines** - CLAUDE.md, AGENTS.md (these are meta-docs about conventions)
3. **Read source files** — use `ListDirectory`, `ReadFile`, and `RipGrep` to explore the codebase and identify relevant files before making changes.<% } %>

### Phase 2: Prepare

Expand All @@ -23,8 +24,8 @@ You are an expert software engineer implementing features and fixing issues base
### Phase 3: Implement

6. **For each file to modify:**
- Use `squint symbols list --file <path> --json` via Tmux first — this aggregates all symbols, relationships, interactions, and flows for the file
- Read 1-2 similar files for patterns and conventions
<% if (it.squintEnabled) { %> - Use `squint symbols list --file <path> --json` via Tmux first — this aggregates all symbols, relationships, interactions, and flows for the file
<% } %> - Read 1-2 similar files for patterns and conventions
- Make changes
- Verify no diagnostics errors before moving to next file
- Write tests leveraging patterns and helpers you found
Expand Down
17 changes: 13 additions & 4 deletions src/agents/prompts/templates/partials/squint-exploration.eta
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<% if (it.squintEnabled) { %>
### Squint Codebase Intelligence Protocol (MANDATORY)

**DO NOT read source files until you have completed these drill-down steps.**
Expand Down Expand Up @@ -98,7 +99,15 @@ squint symbols list --kind function --domain <name> --json
- Searching for specific string patterns or regex
- Config files, tests, or non-code files that squint doesn't index
- Any file squint identified as relevant — squint shows structure, files show content

#### If no SquintOverview was pre-loaded

The repository has no Squint database. Skip these steps and proceed directly to reading files.
<% } else { %>
### Codebase Exploration Protocol

The repository has no Squint database. Skip squint steps and proceed directly to reading files.

Use these tools to explore the codebase:
- `ListDirectory` — list directory contents to understand structure
- `ReadFile` — read file contents for implementation details
- `RipGrep` — search for patterns in code (regex, respects gitignore)
- `AstGrep` — AST-aware code search (use $VAR for captures)
- `Tmux` — run shell commands (for exploration: grep, find, etc.)
<% } %>
2 changes: 1 addition & 1 deletion src/agents/prompts/templates/partials/tmux.eta
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ Use the Tmux gadget for ALL shell commands:
- With pipes: `command="npm test 2>&1 | head -50"`
- With globs: `command="find . -name '*.ts' | xargs wc -l"`

Use unique session names like: "npm-install", "test-run", "lint-check", "build", "typecheck", "squint-modules", "squint-features"
Use unique session names like: "npm-install", "test-run", "lint-check", "build", "typecheck"<% if (it.squintEnabled) { %>, "squint-modules", "squint-features"<% } %>
6 changes: 4 additions & 2 deletions src/agents/prompts/templates/planning.eta
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,17 @@ CRITICAL:
You are running in a cloned copy of the project repository. Before creating your plan:

1. **Read the <%= it.workItemNoun || 'card' %>** to identify scope signals (file names, components, features, domain terms)
2. **Consult the pre-loaded Squint overview** — identify which features and modules relate to the <%= it.workItemNoun || 'card' %>
<% if (it.squintEnabled) { %>2. **Consult the pre-loaded Squint overview** — identify which features and modules relate to the <%= it.workItemNoun || 'card' %>
3. **MANDATORY: Drill into features, flows, and modules before reading any files:**
- `squint features show <slug> --json` for each relevant feature — returns flows, modules involved, interactions
- `squint flows show <slug> --json` for key flows — returns ordered interaction steps and the definition-level call trace showing which function calls which across module boundaries
- `squint modules show <path> --json` for each module area — returns members, outgoing/incoming interactions, flows
- DO NOT SKIP — plans that miss cross-cutting dependencies (e.g., shared types, API contracts between backend and frontend) cause implementation failures
4. **THEN read specific files** — only files Squint identified as relevant. Use `squint symbols list --file <path> --json` to understand a file's architectural role before reading source.
5. **Understand existing patterns** — how does the codebase already solve similar problems?
6. **Map terminology** — <%= it.workItemNoun || 'card' %> may use different terms than code
6. **Map terminology** — <%= it.workItemNoun || 'card' %> may use different terms than code<% } else { %>2. **Explore the codebase** using `ListDirectory`, `ReadFile`, `RipGrep`, and `Tmux` to identify relevant files and patterns.
3. **Understand existing patterns** — how does the codebase already solve similar problems?
4. **Map terminology** — <%= it.workItemNoun || 'card' %> may use different terms than code<% } %>

<%~ include("partials/squint-exploration") %>

Expand Down
5 changes: 3 additions & 2 deletions src/agents/prompts/templates/respond-to-planning-comment.eta
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@ You are running in a cloned copy of the project repository. Before updating the

1. **Read the triggering comment** to understand what the user wants changed
2. **Read the current <%= it.workItemNoun || 'card' %>** to understand the existing plan
3. **Consult the pre-loaded Squint overview** — identify which features and modules relate to the requested changes
<% if (it.squintEnabled) { %>3. **Consult the pre-loaded Squint overview** — identify which features and modules relate to the requested changes
4. **MANDATORY: Drill into features, flows, and modules before reading any files:**
- `squint features show <slug> --json` for each relevant feature — returns flows, modules involved, interactions
- `squint flows show <slug> --json` for key flows — returns ordered interaction steps and the definition-level call trace showing which function calls which across module boundaries
- `squint modules show <path> --json` for each module area — returns members, outgoing/incoming interactions, flows
- DO NOT SKIP — plans that miss cross-cutting dependencies (e.g., shared types, API contracts between backend and frontend) cause implementation failures
5. **THEN read specific files** — only files Squint identified as relevant. Use `squint symbols list --file <path> --json` to understand a file's architectural role before reading source.
6. **Understand existing patterns** — how does the codebase already solve similar problems?
6. **Understand existing patterns** — how does the codebase already solve similar problems?<% } else { %>3. **Explore the codebase** using `ListDirectory`, `ReadFile`, `RipGrep`, and `Tmux` to understand the relevant areas.
4. **Understand existing patterns** — how does the codebase already solve similar problems?<% } %>

<%~ include("partials/squint-exploration") %>

Expand Down
40 changes: 30 additions & 10 deletions src/agents/prompts/templates/review.eta
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ CRITICAL:

**Accuracy over thoroughness**: A review with zero comments that correctly approves good code is better than a review that invents problems. Only report issues you can demonstrate.

**Architecture-aware**: Code can be correct yet harmful. A well-tested function in the wrong module, a clean implementation that duplicates an existing pattern, a performant solution that creates tight coupling — these are real problems even though every line compiles and every test passes. Use squint to see the forest, not just the trees.
**Architecture-aware**: Code can be correct yet harmful. A well-tested function in the wrong module, a clean implementation that duplicates an existing pattern, a performant solution that creates tight coupling — these are real problems even though every line compiles and every test passes.<% if (it.squintEnabled) { %> Use squint to see the forest, not just the trees.<% } %>

## Process

### Phase 1: Strategic Analysis

1. **Understand the change**: Read the PR description and all modified files. Understand WHAT changed and WHY. An initial comment has already been posted on the PR acknowledging the review is in progress.

2. **Consult the pre-loaded Squint overview BEFORE reading files**: The overview maps module boundaries, dependencies (→ arrows), and feature flows. Use `squint modules show <path> --json` via Tmux to drill into modules touched by the PR. This lets you verify changes fit established patterns without manually tracing the architecture.
<% if (it.squintEnabled) { %>2. **Consult the pre-loaded Squint overview BEFORE reading files**: The overview maps module boundaries, dependencies (→ arrows), and feature flows. Use `squint modules show <path> --json` via Tmux to drill into modules touched by the PR. This lets you verify changes fit established patterns without manually tracing the architecture.

<%~ include("partials/squint-exploration") %>

Expand Down Expand Up @@ -52,6 +52,26 @@ Beyond general exploration, use squint specifically to detect conflicts and viol
**Feature/UX Impact:**
- Trace affected feature flows with `squint features show`. Does the change create inconsistent behavior?
- What does the user see when this code fails? Edge cases in UX?
<% } else { %>2. **Explore the codebase** using `ListDirectory`, `ReadFile`, `RipGrep`, and `Tmux` to understand the context of the changes. Read CLAUDE.md and README.md for project conventions.

3. **Analyze architectural impact**: Before reading implementation details, answer these strategic questions:

**Boundary & Responsibility:**
- Is logic in the right layer? (business logic in controllers = bad)
- Do new dependencies point in the correct direction?

**Pattern Consistency:**
- How does the codebase already solve this kind of problem?
- Does the PR introduce a "second way" to do something already done one way?

**Design Simplicity:**
- Could the same goal be achieved with fewer files/abstractions/layers?
- Does the PR introduce indirection not justified by current complexity?

**Feature/UX Impact:**
- Does the change create inconsistent behavior?
- What does the user see when this code fails? Edge cases in UX?
<% } %>

### Phase 2: Tactical Verification

Expand Down Expand Up @@ -80,7 +100,7 @@ Issues that **must** be fixed before merge:
- Correctness bugs (with failing scenario)
- Data loss or corruption risks
- Breaking changes to public APIs
- Dependency cycle introduction (confirmed via squint)
- Dependency cycle introduction<% if (it.squintEnabled) { %> (confirmed via squint)<% } %>
- Responsibility violation (business logic where it can't be tested/reused)

### SHOULD_FIX (use REQUEST_CHANGES or COMMENT)
Expand All @@ -90,7 +110,7 @@ Real issues worth addressing:
- Incomplete implementations that will cause problems
- Test coverage gaps for critical paths
- Pattern conflict (second way to do something already done consistently one way)
- Abstraction misfit (new abstraction misaligned with module boundaries per squint)
- Abstraction misfit (new abstraction misaligned with module boundaries<% if (it.squintEnabled) { %> per squint<% } %>)
- Unnecessary complexity (indirection not justified by current requirements)

### NITPICK (skip or brief COMMENT)
Expand Down Expand Up @@ -138,13 +158,13 @@ Style and preferences - mention only if egregious:

Answer these during Phase 1 — they catch design problems that line-by-line review misses:

1. **Does this change belong here?** — Is the code in the right module? Does it align with the feature boundaries squint shows? Would a developer looking for this functionality find it where it lives?
1. **Does this change belong here?** — Is the code in the right module?<% if (it.squintEnabled) { %> Does it align with the feature boundaries squint shows?<% } %> Would a developer looking for this functionality find it where it lives?

2. **Does this conflict with existing patterns?** — Use `squint symbols show` and `squint features show` to find analogous code. Does the PR follow the same conventions? Is it introducing a second way to do something the codebase already does one way? A single instance is not a "pattern" — look for consistent repetition before flagging a conflict.
2. **Does this conflict with existing patterns?** —<% if (it.squintEnabled) { %> Use `squint symbols show` and `squint features show` to find analogous code.<% } %> Does the PR follow the same conventions? Is it introducing a second way to do something the codebase already does one way? A single instance is not a "pattern" — look for consistent repetition before flagging a conflict.

3. **Is this the simplest solution?** — Could the same goal be achieved by extending existing code rather than creating new abstractions? Does every new file, class, or layer of indirection earn its keep against current (not hypothetical) complexity?

4. **What does the user experience?** — Trace user-facing flows affected by this change via `squint features show`. What does the user see when this code succeeds? When it fails? Are error states handled in a way the user can act on?
4. **What does the user experience?** — <% if (it.squintEnabled) { %>Trace user-facing flows affected by this change via `squint features show`. <% } %>What does the user see when this code succeeds? When it fails? Are error states handled in a way the user can act on?

## Anti-Patterns to Avoid

Expand Down Expand Up @@ -177,7 +197,7 @@ Answer these during Phase 1 — they catch design problems that line-by-line rev
- A 5-line bug fix doesn't need an architectural essay.

### Don't flag pattern conflicts without evidence
- Cite the existing pattern via squint — show the analogous code that does it differently.
- <% if (it.squintEnabled) { %>Cite the existing pattern via squint — show the analogous code that does it differently.<% } else { %>Cite the existing pattern — show the analogous code that does it differently.<% } %>
- A single instance is not a "pattern." Look for at least 2-3 consistent examples before claiming a conflict.

## Review Decision
Expand Down Expand Up @@ -207,8 +227,8 @@ Use CreatePRReview with:

## Architecture & Design
[Only if strategic issues found — skip entirely for clean PRs]
- **[SHOULD_FIX] Pattern conflict**: ...with squint evidence
- **[BLOCKING] Dependency violation**: ...with squint evidence
- **[SHOULD_FIX] Pattern conflict**: ...with evidence<% if (it.squintEnabled) { %> (squint: `squint symbols show <name>`)<% } %>
- **[BLOCKING] Dependency violation**: ...with evidence<% if (it.squintEnabled) { %> (squint: `squint modules show <path>`)<% } %>

## Code Issues
[Only if tactical issues found — skip entirely for clean PRs]
Expand Down
6 changes: 4 additions & 2 deletions src/agents/prompts/templates/splitting.eta
Original file line number Diff line number Diff line change
Expand Up @@ -81,15 +81,17 @@ For technical/infrastructure work, adapt the format:
You are running in a cloned copy of the project repository. Before creating stories:

1. **Read the <%= it.workItemNoun || 'card' %>** to identify scope signals (file names, components, features, domain terms)
2. **Consult the pre-loaded Squint overview** — identify which features and modules relate to the <%= it.workItemNoun || 'card' %>
<% if (it.squintEnabled) { %>2. **Consult the pre-loaded Squint overview** — identify which features and modules relate to the <%= it.workItemNoun || 'card' %>
3. **MANDATORY: Drill into features, flows, and modules before reading any files:**
- `squint features show <slug> --json` for each relevant feature — returns flows, modules involved, interactions
- `squint flows show <slug> --json` for key flows — returns ordered interaction steps and the definition-level call trace across module boundaries
- `squint modules show <path> --json` for each module area — returns members, outgoing/incoming interactions, flows
- DO NOT SKIP — accurate story sizing requires understanding cross-cutting dependencies
4. **THEN read specific files** — only files Squint identified as relevant. Use `squint symbols list --file <path> --json` to understand a file's architectural role before reading source.
5. **Understand existing patterns** — how does the codebase already solve similar problems?
6. **Map terminology** — <%= it.workItemNoun || 'card' %> may use different terms than the code
6. **Map terminology** — <%= it.workItemNoun || 'card' %> may use different terms than the code<% } else { %>2. **Explore the codebase** using `ListDirectory`, `ReadFile`, `RipGrep`, and `Tmux` to identify relevant files and patterns.
3. **Understand existing patterns** — how does the codebase already solve similar problems?
4. **Map terminology** — <%= it.workItemNoun || 'card' %> may use different terms than the code<% } %>

<%~ include("partials/squint-exploration") %>

Expand Down
4 changes: 4 additions & 0 deletions src/agents/shared/promptContext.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { getJiraConfig, getTrelloConfig } from '../../pm/config.js';
import { getPMProviderOrNull } from '../../pm/index.js';
import type { ProjectConfig } from '../../types/index.js';
import { resolveSquintDbPath } from '../../utils/squintDb.js';
import type { PromptContext } from '../prompts/index.js';

function getListIds(project: ProjectConfig) {
Expand Down Expand Up @@ -51,10 +52,12 @@ export function buildPromptContext(
originalWorkItemUrl: string;
detectedAgentType: string;
},
repoDir?: string,
): PromptContext {
const pmProvider = getPMProviderOrNull();
const listIds = getListIds(project);
const terminology = getPromptTerminology(pmProvider?.type);
const squintEnabled = repoDir ? resolveSquintDbPath(repoDir) !== null : false;

return {
workItemId,
Expand All @@ -65,6 +68,7 @@ export function buildPromptContext(
pmType: pmProvider?.type,
...terminology,
maxInFlightItems: project.maxInFlightItems ?? 1,
squintEnabled,
...(prContext && {
prNumber: prContext.prNumber,
prBranch: prContext.prBranch,
Expand Down
2 changes: 2 additions & 0 deletions src/backends/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ async function buildExecutionPlan(
project,
input.triggerType,
prContext,
undefined,
repoDir,
);

// Load DB partials for template include resolution
Expand Down
3 changes: 3 additions & 0 deletions src/backends/codex/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ const ALLOWED_ENV_EXACT = new Set([

// Codex auth
'OPENAI_API_KEY',

// Squint
'SQUINT_DB_PATH',
]);

const ALLOWED_ENV_PREFIXES = SHARED_ALLOWED_ENV_PREFIXES;
Expand Down
3 changes: 3 additions & 0 deletions src/backends/opencode/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ const ALLOWED_ENV_EXACT = new Set([
'OPENAI_API_KEY',
'ANTHROPIC_API_KEY',
'OPENROUTER_API_KEY',

// Squint
'SQUINT_DB_PATH',
]);

const ALLOWED_ENV_PREFIXES = SHARED_ALLOWED_ENV_PREFIXES;
Expand Down
Loading
Loading