support appending content to the system prompt via cli argument

This commit is contained in:
Markus Ylisiurunen 2025-12-05 00:05:29 +02:00
parent 029a04c43b
commit ef8bb6c062
2 changed files with 62 additions and 50 deletions

3
.gitignore vendored
View file

@ -13,6 +13,7 @@ packages/*/dist-firefox/
# Editor files
.vscode/
.zed/
.idea/
*.swp
*.swo
@ -23,4 +24,4 @@ packages/*/dist-firefox/
coverage/
.nyc_output/
.pi_config/
tui-debug.log
tui-debug.log

View file

@ -45,6 +45,7 @@ interface Args {
model?: string;
apiKey?: string;
systemPrompt?: string;
appendSystemPrompt?: string;
thinking?: ThinkingLevel;
continue?: boolean;
resume?: boolean;
@ -88,6 +89,8 @@ function parseArgs(args: string[]): Args {
result.apiKey = args[++i];
} else if (arg === "--system-prompt" && i + 1 < args.length) {
result.systemPrompt = args[++i];
} else if (arg === "--append-system-prompt" && i + 1 < args.length) {
result.appendSystemPrompt = args[++i];
} else if (arg === "--no-session") {
result.noSession = true;
} else if (arg === "--session" && i + 1 < args.length) {
@ -231,22 +234,23 @@ ${chalk.bold("Usage:")}
${APP_NAME} [options] [@files...] [messages...]
${chalk.bold("Options:")}
--provider <name> Provider name (default: google)
--model <id> Model ID (default: gemini-2.5-flash)
--api-key <key> API key (defaults to env vars)
--system-prompt <text> System prompt (default: coding assistant prompt)
--mode <mode> Output mode: text (default), json, or rpc
--print, -p Non-interactive mode: process prompt and exit
--continue, -c Continue previous session
--resume, -r Select a session to resume
--session <path> Use specific session file
--no-session Don't save session (ephemeral)
--models <patterns> Comma-separated model patterns for quick cycling with Ctrl+P
--tools <tools> Comma-separated list of tools to enable (default: read,bash,edit,write)
Available: read, bash, edit, write, grep, find, ls
--thinking <level> Set thinking level: off, minimal, low, medium, high
--export <file> Export session file to HTML and exit
--help, -h Show this help
--provider <name> Provider name (default: google)
--model <id> Model ID (default: gemini-2.5-flash)
--api-key <key> API key (defaults to env vars)
--system-prompt <text> System prompt (default: coding assistant prompt)
--append-system-prompt <text> Append text or file contents to the system prompt
--mode <mode> Output mode: text (default), json, or rpc
--print, -p Non-interactive mode: process prompt and exit
--continue, -c Continue previous session
--resume, -r Select a session to resume
--session <path> Use specific session file
--no-session Don't save session (ephemeral)
--models <patterns> Comma-separated model patterns for quick cycling with Ctrl+P
--tools <tools> Comma-separated list of tools to enable (default: read,bash,edit,write)
Available: read, bash, edit, write, grep, find, ls
--thinking <level> Set thinking level: off, minimal, low, medium, high
--export <file> Export session file to HTML and exit
--help, -h Show this help
${chalk.bold("Examples:")}
# Interactive mode
@ -320,32 +324,47 @@ const toolDescriptions: Record<ToolName, string> = {
ls: "List directory contents",
};
function buildSystemPrompt(customPrompt?: string, selectedTools?: ToolName[]): string {
// Check if customPrompt is a file path that exists
if (customPrompt && existsSync(customPrompt)) {
function resolvePromptInput(input: string | undefined, description: string): string | undefined {
if (!input) {
return undefined;
}
if (existsSync(input)) {
try {
customPrompt = readFileSync(customPrompt, "utf-8");
return readFileSync(input, "utf-8");
} catch (error) {
console.error(chalk.yellow(`Warning: Could not read system prompt file ${customPrompt}: ${error}`));
// Fall through to use as literal string
console.error(chalk.yellow(`Warning: Could not read ${description} file ${input}: ${error}`));
return input;
}
}
if (customPrompt) {
// Use custom prompt as base, then add context/datetime
const now = new Date();
const dateTime = now.toLocaleString("en-US", {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
timeZoneName: "short",
});
return input;
}
let prompt = customPrompt;
function buildSystemPrompt(customPrompt?: string, selectedTools?: ToolName[], appendSystemPrompt?: string): string {
const resolvedCustomPrompt = resolvePromptInput(customPrompt, "system prompt");
const resolvedAppendPrompt = resolvePromptInput(appendSystemPrompt, "append system prompt");
const now = new Date();
const dateTime = now.toLocaleString("en-US", {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
timeZoneName: "short",
});
const appendSection = resolvedAppendPrompt ? `\n\n${resolvedAppendPrompt}` : "";
if (resolvedCustomPrompt) {
let prompt = resolvedCustomPrompt;
if (appendSection) {
prompt += appendSection;
}
// Append project context files
const contextFiles = loadProjectContextFiles();
@ -364,18 +383,6 @@ function buildSystemPrompt(customPrompt?: string, selectedTools?: ToolName[]): s
return prompt;
}
const now = new Date();
const dateTime = now.toLocaleString("en-US", {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
timeZoneName: "short",
});
// Get absolute path to README.md
const readmePath = getReadmePath();
@ -453,6 +460,10 @@ Documentation:
- Your own documentation (including custom model setup and theme creation) is at: ${readmePath}
- Read it when users ask about features, configuration, or setup, and especially if the user asks you to add a custom model or provider, or create a custom theme.`;
if (appendSection) {
prompt += appendSection;
}
// Append project context files
const contextFiles = loadProjectContextFiles();
if (contextFiles.length > 0) {
@ -1138,7 +1149,7 @@ export async function main(args: string[]) {
}
}
const systemPrompt = buildSystemPrompt(parsed.systemPrompt, parsed.tools);
const systemPrompt = buildSystemPrompt(parsed.systemPrompt, parsed.tools, parsed.appendSystemPrompt);
// Load previous messages if continuing or resuming
// This may update initialModel if restoring from session