Detailed changes
@@ -1,5 +1,31 @@
-export const REPO_SYSTEM_PROMPT = `You are a research assistant focused on answering the user's question by exploring a git repository in the workspace.
+export interface RepoPromptContext {
+ currentTime: string;
+ hasHistory: boolean;
+}
-Use read and grep to inspect files. Use git tools to explore history and refs. Prefer concrete file references and explain where information comes from.
+export function buildRepoPrompt(ctx: RepoPromptContext): string {
+ const historyGuidance = ctx.hasHistory
+ ? "\nGit history is available. Blame and log can reveal why code exists and how it evolved. Use them when the question involves \"why\" or \"when,\" or when current code is confusing without context."
+ : "";
-Be concise and answer directly.`;
+ const historyEnv = ctx.hasHistory
+ ? "Git history: available (full clone)"
+ : "Git history: limited (shallow clone)";
+
+ return `You are a librarian of source code. You know the stacks—every file, every commit, every branch is a volume you can pull from the shelf. Your job is to find exactly the right reference for the question at hand, no more and no less.
+
+<approach>
+If you need orientation, look first for agent instruction files (AGENTS.md, CLAUDE.md, .cursorrules, .github/copilot-instructions.md) — these often describe the project's architecture, conventions, and key commands. Failing that, check the README. Otherwise, go straight to targeted search.
+
+For large files, search first to find the relevant sections, then read those specifically. Stop once you have enough evidence to answer.${historyGuidance}
+</approach>
+
+<answering>
+Be precise. Only cite files, lines, and commits you actually examined. Reference specific file paths and line ranges. When citing git history, include commit hashes. If you cannot find sufficient information, say so and explain what you explored.
+</answering>
+
+<environment>
+Current time: ${ctx.currentTime}
+${historyEnv}
+</environment>`;
+}
@@ -1,7 +1,21 @@
-export const WEB_SYSTEM_PROMPT = `You are a research assistant focused on answering the user's question using web sources.
+export interface WebPromptContext {
+ currentTime: string;
+}
-You have tools to search the web, fetch URLs into markdown, and read or grep files in the workspace.
+export function buildWebPrompt(ctx: WebPromptContext): string {
+ return `You are a field researcher. You go out into the world, find the best sources, and bring back what matters. Not everything, just what answers the question.
-Use web_search to find sources. Use web_fetch to retrieve a URL. When content is large, it may be stored in the workspace; use read and grep to explore it.
+<approach>
+Prefer primary and official sources over blogs and SEO pages.
-Be concise, cite sources with URLs, and answer directly.`;
+When content is large, use grep to find the sections that matter, then read those specifically. Stop once you have enough evidence to answer.
+</approach>
+
+<answering>
+Be direct. Only cite URLs you actually accessed. Include version or date when it matters. If sources conflict, note the discrepancy. If you cannot find sufficient information, say so and explain what you tried.
+</answering>
+
+<environment>
+Current time: ${ctx.currentTime}
+</environment>`;
+}
@@ -13,7 +13,7 @@ import { createGitDiffTool } from "../../agent/tools/git/diff.js";
import { createGitRefsTool } from "../../agent/tools/git/refs.js";
import { createGitCheckoutTool } from "../../agent/tools/git/checkout.js";
import { runAgent } from "../../agent/runner.js";
-import { REPO_SYSTEM_PROMPT } from "../../agent/prompts/repo.js";
+import { buildRepoPrompt } from "../../agent/prompts/repo.js";
import { createEventLogger, printUsageSummary } from "../output.js";
import { CloneError } from "../../util/errors.js";
import simpleGit from "simple-git";
@@ -40,7 +40,10 @@ export async function runRepoCommand(options: RepoCommandOptions): Promise<void>
try {
const logger = createEventLogger({ verbose: options.verbose });
- let systemPrompt = REPO_SYSTEM_PROMPT;
+ let systemPrompt = buildRepoPrompt({
+ currentTime: new Date().toISOString(),
+ hasHistory: options.full,
+ });
const promptPath = overrides.repo.system_prompt_path;
if (promptPath) {
systemPrompt = await readFile(expandHomePath(promptPath), "utf8");
@@ -11,7 +11,7 @@ import { createFindTool } from "../../agent/tools/find.js";
import { createWebFetchTool } from "../../agent/tools/web-fetch.js";
import { createWebSearchTool } from "../../agent/tools/web-search.js";
import { runAgent } from "../../agent/runner.js";
-import { WEB_SYSTEM_PROMPT } from "../../agent/prompts/web.js";
+import { buildWebPrompt } from "../../agent/prompts/web.js";
import { createEventLogger, printUsageSummary } from "../output.js";
import { ConfigError, FetchError } from "../../util/errors.js";
@@ -51,7 +51,9 @@ export async function runWebCommand(options: WebCommandOptions): Promise<void> {
throw new ConfigError("Web fetch requires TABSTACK_API_KEY (set via environment or config)");
}
- let systemPrompt = WEB_SYSTEM_PROMPT;
+ let systemPrompt = buildWebPrompt({
+ currentTime: new Date().toISOString(),
+ });
const promptPath = overrides.web.system_prompt_path;
if (promptPath) {
systemPrompt = await readFile(expandHomePath(promptPath), "utf8");
@@ -79,14 +81,16 @@ export async function runWebCommand(options: WebCommandOptions): Promise<void> {
} else {
const filename = `web/${basename(new URL(options.url).pathname) || "index"}.md`;
await writeWorkspaceFile(workspace.path, filename, text);
- seededContext = `Fetched content stored at ${filename}`;
+ seededContext = `Content from ${options.url} was too large to include directly. It has been saved to ${filename} in your workspace.`;
}
} catch (error: any) {
throw new FetchError(options.url, error?.message ?? String(error));
}
}
- const query = seededContext ? `${options.query}\n\n${seededContext}` : options.query;
+ const query = seededContext
+ ? `${options.query}\n\n<attached_content url="${options.url}">\n${seededContext}\n</attached_content>`
+ : options.query;
const result = await runAgent(query, {
model: overrides.web.model ?? overrides.defaults.model,