@mariozechner/pi-coding-agent 0.10.0 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/README.md +75 -13
- package/dist/export-html.d.ts.map +1 -1
- package/dist/export-html.js +213 -28
- package/dist/export-html.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +131 -8
- package/dist/main.js.map +1 -1
- package/dist/tools/edit.d.ts.map +1 -1
- package/dist/tools/edit.js +6 -3
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/index.d.ts +4 -4
- package/dist/tui/footer.d.ts +6 -0
- package/dist/tui/footer.d.ts.map +1 -1
- package/dist/tui/footer.js +37 -1
- package/dist/tui/footer.js.map +1 -1
- package/dist/tui/tui-renderer.d.ts.map +1 -1
- package/dist/tui/tui-renderer.js +2 -0
- package/dist/tui/tui-renderer.js.map +1 -1
- package/package.json +4 -4
package/dist/main.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Agent, ProviderTransport } from "@mariozechner/pi-agent-core";
|
|
2
2
|
import { ProcessTerminal, TUI } from "@mariozechner/pi-tui";
|
|
3
3
|
import chalk from "chalk";
|
|
4
|
-
import { existsSync, readFileSync } from "fs";
|
|
4
|
+
import { existsSync, readFileSync, statSync } from "fs";
|
|
5
5
|
import { homedir } from "os";
|
|
6
|
-
import { dirname, join, resolve } from "path";
|
|
6
|
+
import { dirname, extname, join, resolve } from "path";
|
|
7
7
|
import { fileURLToPath } from "url";
|
|
8
8
|
import { getChangelogPath, getNewEntries, parseChangelog } from "./changelog.js";
|
|
9
9
|
import { findModel, getApiKeyForModel, getAvailableModels } from "./model-config.js";
|
|
@@ -31,6 +31,7 @@ const defaultModelPerProvider = {
|
|
|
31
31
|
function parseArgs(args) {
|
|
32
32
|
const result = {
|
|
33
33
|
messages: [],
|
|
34
|
+
fileArgs: [],
|
|
34
35
|
};
|
|
35
36
|
for (let i = 0; i < args.length; i++) {
|
|
36
37
|
const arg = args[i];
|
|
@@ -82,17 +83,101 @@ function parseArgs(args) {
|
|
|
82
83
|
else if (arg === "--print" || arg === "-p") {
|
|
83
84
|
result.print = true;
|
|
84
85
|
}
|
|
86
|
+
else if (arg.startsWith("@")) {
|
|
87
|
+
result.fileArgs.push(arg.slice(1)); // Remove @ prefix
|
|
88
|
+
}
|
|
85
89
|
else if (!arg.startsWith("-")) {
|
|
86
90
|
result.messages.push(arg);
|
|
87
91
|
}
|
|
88
92
|
}
|
|
89
93
|
return result;
|
|
90
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* Map of file extensions to MIME types for common image formats
|
|
97
|
+
*/
|
|
98
|
+
const IMAGE_MIME_TYPES = {
|
|
99
|
+
".jpg": "image/jpeg",
|
|
100
|
+
".jpeg": "image/jpeg",
|
|
101
|
+
".png": "image/png",
|
|
102
|
+
".gif": "image/gif",
|
|
103
|
+
".webp": "image/webp",
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Check if a file is an image based on its extension
|
|
107
|
+
*/
|
|
108
|
+
function isImageFile(filePath) {
|
|
109
|
+
const ext = extname(filePath).toLowerCase();
|
|
110
|
+
return IMAGE_MIME_TYPES[ext] || null;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Expand ~ to home directory
|
|
114
|
+
*/
|
|
115
|
+
function expandPath(filePath) {
|
|
116
|
+
if (filePath === "~") {
|
|
117
|
+
return homedir();
|
|
118
|
+
}
|
|
119
|
+
if (filePath.startsWith("~/")) {
|
|
120
|
+
return homedir() + filePath.slice(1);
|
|
121
|
+
}
|
|
122
|
+
return filePath;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Process @file arguments into text content and image attachments
|
|
126
|
+
*/
|
|
127
|
+
function processFileArguments(fileArgs) {
|
|
128
|
+
let textContent = "";
|
|
129
|
+
const imageAttachments = [];
|
|
130
|
+
for (const fileArg of fileArgs) {
|
|
131
|
+
// Expand and resolve path
|
|
132
|
+
const expandedPath = expandPath(fileArg);
|
|
133
|
+
const absolutePath = resolve(expandedPath);
|
|
134
|
+
// Check if file exists
|
|
135
|
+
if (!existsSync(absolutePath)) {
|
|
136
|
+
console.error(chalk.red(`Error: File not found: ${absolutePath}`));
|
|
137
|
+
process.exit(1);
|
|
138
|
+
}
|
|
139
|
+
// Check if file is empty
|
|
140
|
+
const stats = statSync(absolutePath);
|
|
141
|
+
if (stats.size === 0) {
|
|
142
|
+
// Skip empty files
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
const mimeType = isImageFile(absolutePath);
|
|
146
|
+
if (mimeType) {
|
|
147
|
+
// Handle image file
|
|
148
|
+
const content = readFileSync(absolutePath);
|
|
149
|
+
const base64Content = content.toString("base64");
|
|
150
|
+
const attachment = {
|
|
151
|
+
id: `file-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,
|
|
152
|
+
type: "image",
|
|
153
|
+
fileName: absolutePath.split("/").pop() || absolutePath,
|
|
154
|
+
mimeType,
|
|
155
|
+
size: stats.size,
|
|
156
|
+
content: base64Content,
|
|
157
|
+
};
|
|
158
|
+
imageAttachments.push(attachment);
|
|
159
|
+
// Add text reference to image
|
|
160
|
+
textContent += `<file name="${absolutePath}"></file>\n`;
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
// Handle text file
|
|
164
|
+
try {
|
|
165
|
+
const content = readFileSync(absolutePath, "utf-8");
|
|
166
|
+
textContent += `<file name="${absolutePath}">\n${content}\n</file>\n`;
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
console.error(chalk.red(`Error: Could not read file ${absolutePath}: ${error.message}`));
|
|
170
|
+
process.exit(1);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return { textContent, imageAttachments };
|
|
175
|
+
}
|
|
91
176
|
function printHelp() {
|
|
92
177
|
console.log(`${chalk.bold("pi")} - AI coding assistant with read, bash, edit, write tools
|
|
93
178
|
|
|
94
179
|
${chalk.bold("Usage:")}
|
|
95
|
-
pi [options] [messages...]
|
|
180
|
+
pi [options] [@files...] [messages...]
|
|
96
181
|
|
|
97
182
|
${chalk.bold("Options:")}
|
|
98
183
|
--provider <name> Provider name (default: google)
|
|
@@ -116,6 +201,9 @@ ${chalk.bold("Examples:")}
|
|
|
116
201
|
# Interactive mode with initial prompt
|
|
117
202
|
pi "List all .ts files in src/"
|
|
118
203
|
|
|
204
|
+
# Include files in initial message
|
|
205
|
+
pi @prompt.md @image.png "What color is the sky?"
|
|
206
|
+
|
|
119
207
|
# Non-interactive mode (process and exit)
|
|
120
208
|
pi -p "List all .ts files in src/"
|
|
121
209
|
|
|
@@ -430,7 +518,7 @@ async function selectSession(sessionManager) {
|
|
|
430
518
|
ui.start();
|
|
431
519
|
});
|
|
432
520
|
}
|
|
433
|
-
async function runInteractiveMode(agent, sessionManager, settingsManager, version, changelogMarkdown = null, modelFallbackMessage = null, newVersion = null, scopedModels = [], initialMessages = []) {
|
|
521
|
+
async function runInteractiveMode(agent, sessionManager, settingsManager, version, changelogMarkdown = null, modelFallbackMessage = null, newVersion = null, scopedModels = [], initialMessages = [], initialMessage, initialAttachments) {
|
|
434
522
|
const renderer = new TuiRenderer(agent, sessionManager, settingsManager, version, changelogMarkdown, newVersion, scopedModels);
|
|
435
523
|
// Initialize TUI (subscribes to agent events internally)
|
|
436
524
|
await renderer.init();
|
|
@@ -440,7 +528,17 @@ async function runInteractiveMode(agent, sessionManager, settingsManager, versio
|
|
|
440
528
|
if (modelFallbackMessage) {
|
|
441
529
|
renderer.showWarning(modelFallbackMessage);
|
|
442
530
|
}
|
|
443
|
-
// Process initial
|
|
531
|
+
// Process initial message with attachments if provided (from @file args)
|
|
532
|
+
if (initialMessage) {
|
|
533
|
+
try {
|
|
534
|
+
await agent.prompt(initialMessage, initialAttachments);
|
|
535
|
+
}
|
|
536
|
+
catch (error) {
|
|
537
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
|
|
538
|
+
renderer.showError(errorMessage);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
// Process remaining initial messages if provided (from CLI args)
|
|
444
542
|
for (const message of initialMessages) {
|
|
445
543
|
try {
|
|
446
544
|
await agent.prompt(message);
|
|
@@ -464,7 +562,7 @@ async function runInteractiveMode(agent, sessionManager, settingsManager, versio
|
|
|
464
562
|
}
|
|
465
563
|
}
|
|
466
564
|
}
|
|
467
|
-
async function runSingleShotMode(agent, _sessionManager, messages, mode) {
|
|
565
|
+
async function runSingleShotMode(agent, _sessionManager, messages, mode, initialMessage, initialAttachments) {
|
|
468
566
|
if (mode === "json") {
|
|
469
567
|
// Subscribe to all events and output as JSON
|
|
470
568
|
agent.subscribe((event) => {
|
|
@@ -472,6 +570,11 @@ async function runSingleShotMode(agent, _sessionManager, messages, mode) {
|
|
|
472
570
|
console.log(JSON.stringify(event));
|
|
473
571
|
});
|
|
474
572
|
}
|
|
573
|
+
// Send initial message with attachments if provided
|
|
574
|
+
if (initialMessage) {
|
|
575
|
+
await agent.prompt(initialMessage, initialAttachments);
|
|
576
|
+
}
|
|
577
|
+
// Send remaining messages
|
|
475
578
|
for (const message of messages) {
|
|
476
579
|
await agent.prompt(message);
|
|
477
580
|
}
|
|
@@ -524,6 +627,26 @@ export async function main(args) {
|
|
|
524
627
|
printHelp();
|
|
525
628
|
return;
|
|
526
629
|
}
|
|
630
|
+
// Validate: RPC mode doesn't support @file arguments
|
|
631
|
+
if (parsed.mode === "rpc" && parsed.fileArgs.length > 0) {
|
|
632
|
+
console.error(chalk.red("Error: @file arguments are not supported in RPC mode"));
|
|
633
|
+
process.exit(1);
|
|
634
|
+
}
|
|
635
|
+
// Process @file arguments if any
|
|
636
|
+
let initialMessage;
|
|
637
|
+
let initialAttachments;
|
|
638
|
+
if (parsed.fileArgs.length > 0) {
|
|
639
|
+
const { textContent, imageAttachments } = processFileArguments(parsed.fileArgs);
|
|
640
|
+
// Combine file content with first plain text message (if any)
|
|
641
|
+
if (parsed.messages.length > 0) {
|
|
642
|
+
initialMessage = textContent + parsed.messages[0];
|
|
643
|
+
parsed.messages.shift(); // Remove first message as it's been combined
|
|
644
|
+
}
|
|
645
|
+
else {
|
|
646
|
+
initialMessage = textContent;
|
|
647
|
+
}
|
|
648
|
+
initialAttachments = imageAttachments.length > 0 ? imageAttachments : undefined;
|
|
649
|
+
}
|
|
527
650
|
// Initialize theme (before any TUI rendering)
|
|
528
651
|
const settingsManager = new SettingsManager();
|
|
529
652
|
const themeName = settingsManager.getTheme();
|
|
@@ -847,11 +970,11 @@ export async function main(args) {
|
|
|
847
970
|
console.log(chalk.dim(`Model scope: ${modelList} ${chalk.gray("(Ctrl+P to cycle)")}`));
|
|
848
971
|
}
|
|
849
972
|
// Interactive mode - use TUI (may have initial messages from CLI args)
|
|
850
|
-
await runInteractiveMode(agent, sessionManager, settingsManager, VERSION, changelogMarkdown, modelFallbackMessage, newVersion, scopedModels, parsed.messages);
|
|
973
|
+
await runInteractiveMode(agent, sessionManager, settingsManager, VERSION, changelogMarkdown, modelFallbackMessage, newVersion, scopedModels, parsed.messages, initialMessage, initialAttachments);
|
|
851
974
|
}
|
|
852
975
|
else {
|
|
853
976
|
// Non-interactive mode (--print flag or --mode flag)
|
|
854
|
-
await runSingleShotMode(agent, sessionManager, parsed.messages, mode);
|
|
977
|
+
await runSingleShotMode(agent, sessionManager, parsed.messages, mode, initialMessage, initialAttachments);
|
|
855
978
|
}
|
|
856
979
|
}
|
|
857
980
|
//# sourceMappingURL=main.js.map
|
package/dist/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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","sourcesContent":["import { Agent, ProviderTransport, type ThinkingLevel } from \"@mariozechner/pi-agent-core\";\nimport type { Api, KnownProvider, Model } from \"@mariozechner/pi-ai\";\nimport { ProcessTerminal, TUI } from \"@mariozechner/pi-tui\";\nimport chalk from \"chalk\";\nimport { existsSync, readFileSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { dirname, join, resolve } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { getChangelogPath, getNewEntries, parseChangelog } from \"./changelog.js\";\nimport { findModel, getApiKeyForModel, getAvailableModels } from \"./model-config.js\";\nimport { SessionManager } from \"./session-manager.js\";\nimport { SettingsManager } from \"./settings-manager.js\";\nimport { initTheme } from \"./theme/theme.js\";\nimport { codingTools } from \"./tools/index.js\";\nimport { SessionSelectorComponent } from \"./tui/session-selector.js\";\nimport { TuiRenderer } from \"./tui/tui-renderer.js\";\n\n// Get version from package.json\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst packageJson = JSON.parse(readFileSync(join(__dirname, \"../package.json\"), \"utf-8\"));\nconst VERSION = packageJson.version;\n\nconst defaultModelPerProvider: Record<KnownProvider, string> = {\n\tanthropic: \"claude-sonnet-4-5\",\n\topenai: \"gpt-5.1-codex\",\n\tgoogle: \"gemini-2.5-pro\",\n\topenrouter: \"openai/gpt-5.1-codex\",\n\txai: \"grok-4-fast-non-reasoning\",\n\tgroq: \"openai/gpt-oss-120b\",\n\tcerebras: \"zai-glm-4.6\",\n\tzai: \"glm-4.6\",\n};\n\ntype Mode = \"text\" | \"json\" | \"rpc\";\n\ninterface Args {\n\tprovider?: string;\n\tmodel?: string;\n\tapiKey?: string;\n\tsystemPrompt?: string;\n\tthinking?: ThinkingLevel;\n\tcontinue?: boolean;\n\tresume?: boolean;\n\thelp?: boolean;\n\tmode?: Mode;\n\tnoSession?: boolean;\n\tsession?: string;\n\tmodels?: string[];\n\tprint?: boolean;\n\tmessages: string[];\n}\n\nfunction parseArgs(args: string[]): Args {\n\tconst result: Args = {\n\t\tmessages: [],\n\t};\n\n\tfor (let i = 0; i < args.length; i++) {\n\t\tconst arg = args[i];\n\n\t\tif (arg === \"--help\" || arg === \"-h\") {\n\t\t\tresult.help = true;\n\t\t} else if (arg === \"--mode\" && i + 1 < args.length) {\n\t\t\tconst mode = args[++i];\n\t\t\tif (mode === \"text\" || mode === \"json\" || mode === \"rpc\") {\n\t\t\t\tresult.mode = mode;\n\t\t\t}\n\t\t} else if (arg === \"--continue\" || arg === \"-c\") {\n\t\t\tresult.continue = true;\n\t\t} else if (arg === \"--resume\" || arg === \"-r\") {\n\t\t\tresult.resume = true;\n\t\t} else if (arg === \"--provider\" && i + 1 < args.length) {\n\t\t\tresult.provider = args[++i];\n\t\t} else if (arg === \"--model\" && i + 1 < args.length) {\n\t\t\tresult.model = args[++i];\n\t\t} else if (arg === \"--api-key\" && i + 1 < args.length) {\n\t\t\tresult.apiKey = args[++i];\n\t\t} else if (arg === \"--system-prompt\" && i + 1 < args.length) {\n\t\t\tresult.systemPrompt = args[++i];\n\t\t} else if (arg === \"--no-session\") {\n\t\t\tresult.noSession = true;\n\t\t} else if (arg === \"--session\" && i + 1 < args.length) {\n\t\t\tresult.session = args[++i];\n\t\t} else if (arg === \"--models\" && i + 1 < args.length) {\n\t\t\tresult.models = args[++i].split(\",\").map((s) => s.trim());\n\t\t} else if (arg === \"--thinking\" && i + 1 < args.length) {\n\t\t\tconst level = args[++i];\n\t\t\tif (level === \"off\" || level === \"minimal\" || level === \"low\" || level === \"medium\" || level === \"high\") {\n\t\t\t\tresult.thinking = level;\n\t\t\t} else {\n\t\t\t\tconsole.error(\n\t\t\t\t\tchalk.yellow(\n\t\t\t\t\t\t`Warning: Invalid thinking level \"${level}\". Valid values: off, minimal, low, medium, high`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t} else if (arg === \"--print\" || arg === \"-p\") {\n\t\t\tresult.print = true;\n\t\t} else if (!arg.startsWith(\"-\")) {\n\t\t\tresult.messages.push(arg);\n\t\t}\n\t}\n\n\treturn result;\n}\n\nfunction printHelp() {\n\tconsole.log(`${chalk.bold(\"pi\")} - AI coding assistant with read, bash, edit, write tools\n\n${chalk.bold(\"Usage:\")}\n pi [options] [messages...]\n\n${chalk.bold(\"Options:\")}\n --provider <name> Provider name (default: google)\n --model <id> Model ID (default: gemini-2.5-flash)\n --api-key <key> API key (defaults to env vars)\n --system-prompt <text> System prompt (default: coding assistant prompt)\n --mode <mode> Output mode: text (default), json, or rpc\n --print, -p Non-interactive mode: process prompt and exit\n --continue, -c Continue previous session\n --resume, -r Select a session to resume\n --session <path> Use specific session file\n --no-session Don't save session (ephemeral)\n --models <patterns> Comma-separated model patterns for quick cycling with Ctrl+P\n --thinking <level> Set thinking level: off, minimal, low, medium, high\n --help, -h Show this help\n\n${chalk.bold(\"Examples:\")}\n # Interactive mode\n pi\n\n # Interactive mode with initial prompt\n pi \"List all .ts files in src/\"\n\n # Non-interactive mode (process and exit)\n pi -p \"List all .ts files in src/\"\n\n # Multiple messages (interactive)\n pi \"Read package.json\" \"What dependencies do we have?\"\n\n # Continue previous session\n pi --continue \"What did we discuss?\"\n\n # Use different model\n pi --provider openai --model gpt-4o-mini \"Help me refactor this code\"\n\n # Limit model cycling to specific models\n pi --models claude-sonnet,claude-haiku,gpt-4o\n\n # Cycle models with fixed thinking levels\n pi --models sonnet:high,haiku:low\n\n # Start with a specific thinking level\n pi --thinking high \"Solve this complex problem\"\n\n${chalk.bold(\"Environment Variables:\")}\n ANTHROPIC_API_KEY - Anthropic Claude API key\n ANTHROPIC_OAUTH_TOKEN - Anthropic OAuth token (alternative to API key)\n OPENAI_API_KEY - OpenAI GPT API key\n GEMINI_API_KEY - Google Gemini API key\n GROQ_API_KEY - Groq API key\n CEREBRAS_API_KEY - Cerebras API key\n XAI_API_KEY - xAI Grok API key\n OPENROUTER_API_KEY - OpenRouter API key\n ZAI_API_KEY - ZAI API key\n PI_CODING_AGENT_DIR - Session storage directory (default: ~/.pi/agent)\n\n${chalk.bold(\"Available Tools:\")}\n read - Read file contents\n bash - Execute bash commands\n edit - Edit files with find/replace\n write - Write files (creates/overwrites)\n`);\n}\n\nfunction buildSystemPrompt(customPrompt?: string): string {\n\t// Check if customPrompt is a file path that exists\n\tif (customPrompt && existsSync(customPrompt)) {\n\t\ttry {\n\t\t\tcustomPrompt = readFileSync(customPrompt, \"utf-8\");\n\t\t} catch (error) {\n\t\t\tconsole.error(chalk.yellow(`Warning: Could not read system prompt file ${customPrompt}: ${error}`));\n\t\t\t// Fall through to use as literal string\n\t\t}\n\t}\n\n\tif (customPrompt) {\n\t\t// Use custom prompt as base, then add context/datetime\n\t\tconst now = new Date();\n\t\tconst dateTime = now.toLocaleString(\"en-US\", {\n\t\t\tweekday: \"long\",\n\t\t\tyear: \"numeric\",\n\t\t\tmonth: \"long\",\n\t\t\tday: \"numeric\",\n\t\t\thour: \"2-digit\",\n\t\t\tminute: \"2-digit\",\n\t\t\tsecond: \"2-digit\",\n\t\t\ttimeZoneName: \"short\",\n\t\t});\n\n\t\tlet prompt = customPrompt;\n\n\t\t// Append project context files\n\t\tconst contextFiles = loadProjectContextFiles();\n\t\tif (contextFiles.length > 0) {\n\t\t\tprompt += \"\\n\\n# Project Context\\n\\n\";\n\t\t\tprompt += \"The following project context files have been loaded:\\n\\n\";\n\t\t\tfor (const { path: filePath, content } of contextFiles) {\n\t\t\t\tprompt += `## ${filePath}\\n\\n${content}\\n\\n`;\n\t\t\t}\n\t\t}\n\n\t\t// Add date/time and working directory last\n\t\tprompt += `\\nCurrent date and time: ${dateTime}`;\n\t\tprompt += `\\nCurrent working directory: ${process.cwd()}`;\n\n\t\treturn prompt;\n\t}\n\n\tconst now = new Date();\n\tconst dateTime = now.toLocaleString(\"en-US\", {\n\t\tweekday: \"long\",\n\t\tyear: \"numeric\",\n\t\tmonth: \"long\",\n\t\tday: \"numeric\",\n\t\thour: \"2-digit\",\n\t\tminute: \"2-digit\",\n\t\tsecond: \"2-digit\",\n\t\ttimeZoneName: \"short\",\n\t});\n\n\t// Get absolute path to README.md\n\tconst readmePath = resolve(join(__dirname, \"../README.md\"));\n\n\tlet prompt = `You are actually not Claude, you are Pi. You are an expert coding assistant. You help users with coding tasks by reading files, executing commands, editing code, and writing new files.\n\nAvailable tools:\n- read: Read file contents\n- bash: Execute bash commands (ls, grep, find, etc.)\n- edit: Make surgical edits to files (find exact text and replace)\n- write: Create or overwrite files\n\nGuidelines:\n- Always use bash tool for file operations like ls, grep, find\n- Use read to examine files before editing\n- Use edit for precise changes (old text must match exactly)\n- Use write only for new files or complete rewrites\n- Be concise in your responses\n- Show file paths clearly when working with files\n- When summarizing your actions, output plain text directly - do NOT use cat or bash to display what you did\n\nDocumentation:\n- Your own documentation (including custom model setup and theme creation) is at: ${readmePath}\n- 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.`;\n\n\t// Append project context files\n\tconst contextFiles = loadProjectContextFiles();\n\tif (contextFiles.length > 0) {\n\t\tprompt += \"\\n\\n# Project Context\\n\\n\";\n\t\tprompt += \"The following project context files have been loaded:\\n\\n\";\n\t\tfor (const { path: filePath, content } of contextFiles) {\n\t\t\tprompt += `## ${filePath}\\n\\n${content}\\n\\n`;\n\t\t}\n\t}\n\n\t// Add date/time and working directory last\n\tprompt += `\\nCurrent date and time: ${dateTime}`;\n\tprompt += `\\nCurrent working directory: ${process.cwd()}`;\n\n\treturn prompt;\n}\n\n/**\n * Look for AGENTS.md or CLAUDE.md in a directory (prefers AGENTS.md)\n */\nfunction loadContextFileFromDir(dir: string): { path: string; content: string } | null {\n\tconst candidates = [\"AGENTS.md\", \"CLAUDE.md\"];\n\tfor (const filename of candidates) {\n\t\tconst filePath = join(dir, filename);\n\t\tif (existsSync(filePath)) {\n\t\t\ttry {\n\t\t\t\treturn {\n\t\t\t\t\tpath: filePath,\n\t\t\t\t\tcontent: readFileSync(filePath, \"utf-8\"),\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(chalk.yellow(`Warning: Could not read ${filePath}: ${error}`));\n\t\t\t}\n\t\t}\n\t}\n\treturn null;\n}\n\n/**\n * Load all project context files in order:\n * 1. Global: ~/.pi/agent/AGENTS.md or CLAUDE.md\n * 2. Parent directories (top-most first) down to cwd\n * Each returns {path, content} for separate messages\n */\nfunction loadProjectContextFiles(): Array<{ path: string; content: string }> {\n\tconst contextFiles: Array<{ path: string; content: string }> = [];\n\n\t// 1. Load global context from ~/.pi/agent/\n\tconst homeDir = homedir();\n\tconst globalContextDir = resolve(process.env.PI_CODING_AGENT_DIR || join(homeDir, \".pi/agent/\"));\n\tconst globalContext = loadContextFileFromDir(globalContextDir);\n\tif (globalContext) {\n\t\tcontextFiles.push(globalContext);\n\t}\n\n\t// 2. Walk up from cwd to root, collecting all context files\n\tconst cwd = process.cwd();\n\tconst ancestorContextFiles: Array<{ path: string; content: string }> = [];\n\n\tlet currentDir = cwd;\n\tconst root = resolve(\"/\");\n\n\twhile (true) {\n\t\tconst contextFile = loadContextFileFromDir(currentDir);\n\t\tif (contextFile) {\n\t\t\t// Add to beginning so we get top-most parent first\n\t\t\tancestorContextFiles.unshift(contextFile);\n\t\t}\n\n\t\t// Stop if we've reached root\n\t\tif (currentDir === root) break;\n\n\t\t// Move up one directory\n\t\tconst parentDir = resolve(currentDir, \"..\");\n\t\tif (parentDir === currentDir) break; // Safety check\n\t\tcurrentDir = parentDir;\n\t}\n\n\t// Add ancestor files in order (top-most → cwd)\n\tcontextFiles.push(...ancestorContextFiles);\n\n\treturn contextFiles;\n}\n\nasync function checkForNewVersion(currentVersion: string): Promise<string | null> {\n\ttry {\n\t\tconst response = await fetch(\"https://registry.npmjs.org/@mariozechner/pi-coding-agent/latest\");\n\t\tif (!response.ok) return null;\n\n\t\tconst data = (await response.json()) as { version?: string };\n\t\tconst latestVersion = data.version;\n\n\t\tif (latestVersion && latestVersion !== currentVersion) {\n\t\t\treturn latestVersion;\n\t\t}\n\n\t\treturn null;\n\t} catch (error) {\n\t\t// Silently fail - don't disrupt the user experience\n\t\treturn null;\n\t}\n}\n\n/**\n * Resolve model patterns to actual Model objects with optional thinking levels\n * Format: \"pattern:level\" where :level is optional\n * For each pattern, finds all matching models and picks the best version:\n * 1. Prefer alias (e.g., claude-sonnet-4-5) over dated versions (claude-sonnet-4-5-20250929)\n * 2. If no alias, pick the latest dated version\n */\nasync function resolveModelScope(\n\tpatterns: string[],\n): Promise<Array<{ model: Model<Api>; thinkingLevel: ThinkingLevel }>> {\n\tconst { models: availableModels, error } = await getAvailableModels();\n\n\tif (error) {\n\t\tconsole.warn(chalk.yellow(`Warning: Error loading models: ${error}`));\n\t\treturn [];\n\t}\n\n\tconst scopedModels: Array<{ model: Model<Api>; thinkingLevel: ThinkingLevel }> = [];\n\n\tfor (const pattern of patterns) {\n\t\t// Parse pattern:level format\n\t\tconst parts = pattern.split(\":\");\n\t\tconst modelPattern = parts[0];\n\t\tlet thinkingLevel: ThinkingLevel = \"off\";\n\n\t\tif (parts.length > 1) {\n\t\t\tconst level = parts[1];\n\t\t\tif (level === \"off\" || level === \"minimal\" || level === \"low\" || level === \"medium\" || level === \"high\") {\n\t\t\t\tthinkingLevel = level;\n\t\t\t} else {\n\t\t\t\tconsole.warn(\n\t\t\t\t\tchalk.yellow(`Warning: Invalid thinking level \"${level}\" in pattern \"${pattern}\". Using \"off\" instead.`),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Check for provider/modelId format (provider is everything before the first /)\n\t\tconst slashIndex = modelPattern.indexOf(\"/\");\n\t\tif (slashIndex !== -1) {\n\t\t\tconst provider = modelPattern.substring(0, slashIndex);\n\t\t\tconst modelId = modelPattern.substring(slashIndex + 1);\n\t\t\tconst providerMatch = availableModels.find(\n\t\t\t\t(m) => m.provider.toLowerCase() === provider.toLowerCase() && m.id.toLowerCase() === modelId.toLowerCase(),\n\t\t\t);\n\t\t\tif (providerMatch) {\n\t\t\t\tif (\n\t\t\t\t\t!scopedModels.find(\n\t\t\t\t\t\t(sm) => sm.model.id === providerMatch.id && sm.model.provider === providerMatch.provider,\n\t\t\t\t\t)\n\t\t\t\t) {\n\t\t\t\t\tscopedModels.push({ model: providerMatch, thinkingLevel });\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// No exact provider/model match - fall through to other matching\n\t\t}\n\n\t\t// Check for exact ID match (case-insensitive)\n\t\tconst exactMatch = availableModels.find((m) => m.id.toLowerCase() === modelPattern.toLowerCase());\n\t\tif (exactMatch) {\n\t\t\t// Exact match found - use it directly\n\t\t\tif (!scopedModels.find((sm) => sm.model.id === exactMatch.id && sm.model.provider === exactMatch.provider)) {\n\t\t\t\tscopedModels.push({ model: exactMatch, thinkingLevel });\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\t// No exact match - fall back to partial matching\n\t\tconst matches = availableModels.filter(\n\t\t\t(m) =>\n\t\t\t\tm.id.toLowerCase().includes(modelPattern.toLowerCase()) ||\n\t\t\t\tm.name?.toLowerCase().includes(modelPattern.toLowerCase()),\n\t\t);\n\n\t\tif (matches.length === 0) {\n\t\t\tconsole.warn(chalk.yellow(`Warning: No models match pattern \"${modelPattern}\"`));\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Helper to check if a model ID looks like an alias (no date suffix)\n\t\t// Dates are typically in format: -20241022 or -20250929\n\t\tconst isAlias = (id: string): boolean => {\n\t\t\t// Check if ID ends with -latest\n\t\t\tif (id.endsWith(\"-latest\")) return true;\n\n\t\t\t// Check if ID ends with a date pattern (-YYYYMMDD)\n\t\t\tconst datePattern = /-\\d{8}$/;\n\t\t\treturn !datePattern.test(id);\n\t\t};\n\n\t\t// Separate into aliases and dated versions\n\t\tconst aliases = matches.filter((m) => isAlias(m.id));\n\t\tconst datedVersions = matches.filter((m) => !isAlias(m.id));\n\n\t\tlet bestMatch: Model<Api>;\n\n\t\tif (aliases.length > 0) {\n\t\t\t// Prefer alias - if multiple aliases, pick the one that sorts highest\n\t\t\taliases.sort((a, b) => b.id.localeCompare(a.id));\n\t\t\tbestMatch = aliases[0];\n\t\t} else {\n\t\t\t// No alias found, pick latest dated version\n\t\t\tdatedVersions.sort((a, b) => b.id.localeCompare(a.id));\n\t\t\tbestMatch = datedVersions[0];\n\t\t}\n\n\t\t// Avoid duplicates\n\t\tif (!scopedModels.find((sm) => sm.model.id === bestMatch.id && sm.model.provider === bestMatch.provider)) {\n\t\t\tscopedModels.push({ model: bestMatch, thinkingLevel });\n\t\t}\n\t}\n\n\treturn scopedModels;\n}\n\nasync function selectSession(sessionManager: SessionManager): Promise<string | null> {\n\treturn new Promise((resolve) => {\n\t\tconst ui = new TUI(new ProcessTerminal());\n\t\tlet resolved = false;\n\n\t\tconst selector = new SessionSelectorComponent(\n\t\t\tsessionManager,\n\t\t\t(path: string) => {\n\t\t\t\tif (!resolved) {\n\t\t\t\t\tresolved = true;\n\t\t\t\t\tui.stop();\n\t\t\t\t\tresolve(path);\n\t\t\t\t}\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tif (!resolved) {\n\t\t\t\t\tresolved = true;\n\t\t\t\t\tui.stop();\n\t\t\t\t\tresolve(null);\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\n\t\tui.addChild(selector);\n\t\tui.setFocus(selector.getSessionList());\n\t\tui.start();\n\t});\n}\n\nasync function runInteractiveMode(\n\tagent: Agent,\n\tsessionManager: SessionManager,\n\tsettingsManager: SettingsManager,\n\tversion: string,\n\tchangelogMarkdown: string | null = null,\n\tmodelFallbackMessage: string | null = null,\n\tnewVersion: string | null = null,\n\tscopedModels: Array<{ model: Model<Api>; thinkingLevel: ThinkingLevel }> = [],\n\tinitialMessages: string[] = [],\n): Promise<void> {\n\tconst renderer = new TuiRenderer(\n\t\tagent,\n\t\tsessionManager,\n\t\tsettingsManager,\n\t\tversion,\n\t\tchangelogMarkdown,\n\t\tnewVersion,\n\t\tscopedModels,\n\t);\n\n\t// Initialize TUI (subscribes to agent events internally)\n\tawait renderer.init();\n\n\t// Render any existing messages (from --continue mode)\n\trenderer.renderInitialMessages(agent.state);\n\n\t// Show model fallback warning at the end of the chat if applicable\n\tif (modelFallbackMessage) {\n\t\trenderer.showWarning(modelFallbackMessage);\n\t}\n\n\t// Process initial messages if provided (from CLI args)\n\tfor (const message of initialMessages) {\n\t\ttry {\n\t\t\tawait agent.prompt(message);\n\t\t} catch (error: unknown) {\n\t\t\tconst errorMessage = error instanceof Error ? error.message : \"Unknown error occurred\";\n\t\t\trenderer.showError(errorMessage);\n\t\t}\n\t}\n\n\t// Interactive loop\n\twhile (true) {\n\t\tconst userInput = await renderer.getUserInput();\n\n\t\t// Process the message - agent.prompt will add user message and trigger state updates\n\t\ttry {\n\t\t\tawait agent.prompt(userInput);\n\t\t} catch (error: unknown) {\n\t\t\t// Display error in the TUI by adding an error message to the chat\n\t\t\tconst errorMessage = error instanceof Error ? error.message : \"Unknown error occurred\";\n\t\t\trenderer.showError(errorMessage);\n\t\t}\n\t}\n}\n\nasync function runSingleShotMode(\n\tagent: Agent,\n\t_sessionManager: SessionManager,\n\tmessages: string[],\n\tmode: \"text\" | \"json\",\n): Promise<void> {\n\tif (mode === \"json\") {\n\t\t// Subscribe to all events and output as JSON\n\t\tagent.subscribe((event) => {\n\t\t\t// Output event as JSON (same format as session manager)\n\t\t\tconsole.log(JSON.stringify(event));\n\t\t});\n\t}\n\n\tfor (const message of messages) {\n\t\tawait agent.prompt(message);\n\t}\n\n\t// In text mode, only output the final assistant message\n\tif (mode === \"text\") {\n\t\tconst lastMessage = agent.state.messages[agent.state.messages.length - 1];\n\t\tif (lastMessage.role === \"assistant\") {\n\t\t\tfor (const content of lastMessage.content) {\n\t\t\t\tif (content.type === \"text\") {\n\t\t\t\t\tconsole.log(content.text);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nasync function runRpcMode(agent: Agent, _sessionManager: SessionManager): Promise<void> {\n\t// Subscribe to all events and output as JSON\n\tagent.subscribe((event) => {\n\t\tconsole.log(JSON.stringify(event));\n\t});\n\n\t// Listen for JSON input on stdin\n\tconst readline = await import(\"readline\");\n\tconst rl = readline.createInterface({\n\t\tinput: process.stdin,\n\t\toutput: process.stdout,\n\t\tterminal: false,\n\t});\n\n\trl.on(\"line\", async (line: string) => {\n\t\ttry {\n\t\t\tconst input = JSON.parse(line);\n\n\t\t\t// Handle different RPC commands\n\t\t\tif (input.type === \"prompt\" && input.message) {\n\t\t\t\tawait agent.prompt(input.message, input.attachments);\n\t\t\t} else if (input.type === \"abort\") {\n\t\t\t\tagent.abort();\n\t\t\t}\n\t\t} catch (error: any) {\n\t\t\t// Output error as JSON\n\t\t\tconsole.log(JSON.stringify({ type: \"error\", error: error.message }));\n\t\t}\n\t});\n\n\t// Keep process alive\n\treturn new Promise(() => {});\n}\n\nexport async function main(args: string[]) {\n\tconst parsed = parseArgs(args);\n\n\tif (parsed.help) {\n\t\tprintHelp();\n\t\treturn;\n\t}\n\n\t// Initialize theme (before any TUI rendering)\n\tconst settingsManager = new SettingsManager();\n\tconst themeName = settingsManager.getTheme();\n\tinitTheme(themeName);\n\n\t// Setup session manager\n\tconst sessionManager = new SessionManager(parsed.continue && !parsed.resume, parsed.session);\n\n\t// Disable session saving if --no-session flag is set\n\tif (parsed.noSession) {\n\t\tsessionManager.disable();\n\t}\n\n\t// Handle --resume flag: show session selector\n\tif (parsed.resume) {\n\t\tconst selectedSession = await selectSession(sessionManager);\n\t\tif (!selectedSession) {\n\t\t\tconsole.log(chalk.dim(\"No session selected\"));\n\t\t\treturn;\n\t\t}\n\t\t// Set the selected session as the active session\n\t\tsessionManager.setSessionFile(selectedSession);\n\t}\n\n\t// Resolve model scope early if provided (needed for initial model selection)\n\tlet scopedModels: Array<{ model: Model<Api>; thinkingLevel: ThinkingLevel }> = [];\n\tif (parsed.models && parsed.models.length > 0) {\n\t\tscopedModels = await resolveModelScope(parsed.models);\n\t}\n\n\t// Determine initial model using priority system:\n\t// 1. CLI args (--provider and --model)\n\t// 2. First model from --models scope\n\t// 3. Restored from session (if --continue or --resume)\n\t// 4. Saved default from settings.json\n\t// 5. First available model with valid API key\n\t// 6. null (allowed in interactive mode)\n\tlet initialModel: Model<Api> | null = null;\n\tlet initialThinking: ThinkingLevel = \"off\";\n\n\tif (parsed.provider && parsed.model) {\n\t\t// 1. CLI args take priority\n\t\tconst { model, error } = findModel(parsed.provider, parsed.model);\n\t\tif (error) {\n\t\t\tconsole.error(chalk.red(error));\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tif (!model) {\n\t\t\tconsole.error(chalk.red(`Model ${parsed.provider}/${parsed.model} not found`));\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tinitialModel = model;\n\t} else if (scopedModels.length > 0 && !parsed.continue && !parsed.resume) {\n\t\t// 2. Use first model from --models scope (skip if continuing/resuming session)\n\t\tinitialModel = scopedModels[0].model;\n\t\tinitialThinking = scopedModels[0].thinkingLevel;\n\t} else if (parsed.continue || parsed.resume) {\n\t\t// 3. Restore from session (will be handled below after loading session)\n\t\t// Leave initialModel as null for now\n\t}\n\n\tif (!initialModel) {\n\t\t// 3. Try saved default from settings\n\t\tconst defaultProvider = settingsManager.getDefaultProvider();\n\t\tconst defaultModel = settingsManager.getDefaultModel();\n\t\tif (defaultProvider && defaultModel) {\n\t\t\tconst { model, error } = findModel(defaultProvider, defaultModel);\n\t\t\tif (error) {\n\t\t\t\tconsole.error(chalk.red(error));\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\tinitialModel = model;\n\n\t\t\t// Also load saved thinking level if we're using saved model\n\t\t\tconst savedThinking = settingsManager.getDefaultThinkingLevel();\n\t\t\tif (savedThinking) {\n\t\t\t\tinitialThinking = savedThinking;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!initialModel) {\n\t\t// 4. Try first available model with valid API key\n\t\t// Prefer default model for each provider if available\n\t\tconst { models: availableModels, error } = await getAvailableModels();\n\n\t\tif (error) {\n\t\t\tconsole.error(chalk.red(error));\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tif (availableModels.length > 0) {\n\t\t\t// Try to find a default model from known providers\n\t\t\tfor (const provider of Object.keys(defaultModelPerProvider) as KnownProvider[]) {\n\t\t\t\tconst defaultModelId = defaultModelPerProvider[provider];\n\t\t\t\tconst match = availableModels.find((m) => m.provider === provider && m.id === defaultModelId);\n\t\t\t\tif (match) {\n\t\t\t\t\tinitialModel = match;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If no default found, use first available\n\t\t\tif (!initialModel) {\n\t\t\t\tinitialModel = availableModels[0];\n\t\t\t}\n\t\t}\n\t}\n\n\t// Determine mode early to know if we should print messages and fail early\n\t// Interactive mode: no --print flag and no --mode flag\n\t// Having initial messages doesn't make it non-interactive anymore\n\tconst isInteractive = !parsed.print && parsed.mode === undefined;\n\tconst mode = parsed.mode || \"text\";\n\t// Only print informational messages in interactive mode\n\t// Non-interactive modes (-p, --mode json, --mode rpc) should be silent except for output\n\tconst shouldPrintMessages = isInteractive;\n\n\t// Non-interactive mode: fail early if no model available\n\tif (!isInteractive && !initialModel) {\n\t\tconsole.error(chalk.red(\"No models available.\"));\n\t\tconsole.error(chalk.yellow(\"\\nSet an API key environment variable:\"));\n\t\tconsole.error(\" ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, etc.\");\n\t\tconsole.error(chalk.yellow(\"\\nOr create ~/.pi/agent/models.json\"));\n\t\tprocess.exit(1);\n\t}\n\n\t// Non-interactive mode: validate API key exists\n\tif (!isInteractive && initialModel) {\n\t\tconst apiKey = parsed.apiKey || (await getApiKeyForModel(initialModel));\n\t\tif (!apiKey) {\n\t\t\tconsole.error(chalk.red(`No API key found for ${initialModel.provider}`));\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\tconst systemPrompt = buildSystemPrompt(parsed.systemPrompt);\n\n\t// Load previous messages if continuing or resuming\n\t// This may update initialModel if restoring from session\n\tif (parsed.continue || parsed.resume) {\n\t\t// Load and restore model (overrides initialModel if found and has API key)\n\t\tconst savedModel = sessionManager.loadModel();\n\t\tif (savedModel) {\n\t\t\tconst { model: restoredModel, error } = findModel(savedModel.provider, savedModel.modelId);\n\n\t\t\tif (error) {\n\t\t\t\tconsole.error(chalk.red(error));\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\t// Check if restored model exists and has a valid API key\n\t\t\tconst hasApiKey = restoredModel ? !!(await getApiKeyForModel(restoredModel)) : false;\n\n\t\t\tif (restoredModel && hasApiKey) {\n\t\t\t\tinitialModel = restoredModel;\n\t\t\t\tif (shouldPrintMessages) {\n\t\t\t\t\tconsole.log(chalk.dim(`Restored model: ${savedModel.provider}/${savedModel.modelId}`));\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Model not found or no API key - fall back to default selection\n\t\t\t\tconst reason = !restoredModel ? \"model no longer exists\" : \"no API key available\";\n\n\t\t\t\tif (shouldPrintMessages) {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\tchalk.yellow(\n\t\t\t\t\t\t\t`Warning: Could not restore model ${savedModel.provider}/${savedModel.modelId} (${reason}).`,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// Ensure we have a valid model - use the same fallback logic\n\t\t\t\tif (!initialModel) {\n\t\t\t\t\tconst { models: availableModels, error: availableError } = await getAvailableModels();\n\t\t\t\t\tif (availableError) {\n\t\t\t\t\t\tconsole.error(chalk.red(availableError));\n\t\t\t\t\t\tprocess.exit(1);\n\t\t\t\t\t}\n\t\t\t\t\tif (availableModels.length > 0) {\n\t\t\t\t\t\t// Try to find a default model from known providers\n\t\t\t\t\t\tfor (const provider of Object.keys(defaultModelPerProvider) as KnownProvider[]) {\n\t\t\t\t\t\t\tconst defaultModelId = defaultModelPerProvider[provider];\n\t\t\t\t\t\t\tconst match = availableModels.find((m) => m.provider === provider && m.id === defaultModelId);\n\t\t\t\t\t\t\tif (match) {\n\t\t\t\t\t\t\t\tinitialModel = match;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// If no default found, use first available\n\t\t\t\t\t\tif (!initialModel) {\n\t\t\t\t\t\t\tinitialModel = availableModels[0];\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (initialModel && shouldPrintMessages) {\n\t\t\t\t\t\t\tconsole.log(chalk.dim(`Falling back to: ${initialModel.provider}/${initialModel.id}`));\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// No models available at all\n\t\t\t\t\t\tif (shouldPrintMessages) {\n\t\t\t\t\t\t\tconsole.error(chalk.red(\"\\nNo models available.\"));\n\t\t\t\t\t\t\tconsole.error(chalk.yellow(\"Set an API key environment variable:\"));\n\t\t\t\t\t\t\tconsole.error(\" ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, etc.\");\n\t\t\t\t\t\t\tconsole.error(chalk.yellow(\"\\nOr create ~/.pi/agent/models.json\"));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tprocess.exit(1);\n\t\t\t\t\t}\n\t\t\t\t} else if (shouldPrintMessages) {\n\t\t\t\t\tconsole.log(chalk.dim(`Falling back to: ${initialModel.provider}/${initialModel.id}`));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// CLI --thinking flag takes highest priority\n\tif (parsed.thinking) {\n\t\tinitialThinking = parsed.thinking;\n\t}\n\n\t// Create agent (initialModel can be null in interactive mode)\n\tconst agent = new Agent({\n\t\tinitialState: {\n\t\t\tsystemPrompt,\n\t\t\tmodel: initialModel as any, // Can be null\n\t\t\tthinkingLevel: initialThinking,\n\t\t\ttools: codingTools,\n\t\t},\n\t\tqueueMode: settingsManager.getQueueMode(),\n\t\ttransport: new ProviderTransport({\n\t\t\t// Dynamic API key lookup based on current model's provider\n\t\t\tgetApiKey: async () => {\n\t\t\t\tconst currentModel = agent.state.model;\n\t\t\t\tif (!currentModel) {\n\t\t\t\t\tthrow new Error(\"No model selected\");\n\t\t\t\t}\n\n\t\t\t\t// Try CLI override first\n\t\t\t\tif (parsed.apiKey) {\n\t\t\t\t\treturn parsed.apiKey;\n\t\t\t\t}\n\n\t\t\t\t// Use model-specific key lookup\n\t\t\t\tconst key = await getApiKeyForModel(currentModel);\n\t\t\t\tif (!key) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`No API key found for provider \"${currentModel.provider}\". Please set the appropriate environment variable or update ~/.pi/agent/models.json`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn key;\n\t\t\t},\n\t\t}),\n\t});\n\n\t// If initial thinking was requested but model doesn't support it, silently reset to off\n\tif (initialThinking !== \"off\" && initialModel && !initialModel.reasoning) {\n\t\tagent.setThinkingLevel(\"off\");\n\t}\n\n\t// Track if we had to fall back from saved model (to show in chat later)\n\tlet modelFallbackMessage: string | null = null;\n\n\t// Load previous messages if continuing or resuming\n\tif (parsed.continue || parsed.resume) {\n\t\tconst messages = sessionManager.loadMessages();\n\t\tif (messages.length > 0) {\n\t\t\tagent.replaceMessages(messages);\n\t\t}\n\n\t\t// Load and restore thinking level\n\t\tconst thinkingLevel = sessionManager.loadThinkingLevel() as ThinkingLevel;\n\t\tif (thinkingLevel) {\n\t\t\tagent.setThinkingLevel(thinkingLevel);\n\t\t\tif (shouldPrintMessages) {\n\t\t\t\tconsole.log(chalk.dim(`Restored thinking level: ${thinkingLevel}`));\n\t\t\t}\n\t\t}\n\n\t\t// Check if we had to fall back from saved model\n\t\tconst savedModel = sessionManager.loadModel();\n\t\tif (savedModel && initialModel) {\n\t\t\tconst savedMatches = initialModel.provider === savedModel.provider && initialModel.id === savedModel.modelId;\n\t\t\tif (!savedMatches) {\n\t\t\t\tconst { model: restoredModel, error } = findModel(savedModel.provider, savedModel.modelId);\n\t\t\t\tif (error) {\n\t\t\t\t\t// Config error - already shown above, just use generic message\n\t\t\t\t\tmodelFallbackMessage = `Could not restore model ${savedModel.provider}/${savedModel.modelId}. Using ${initialModel.provider}/${initialModel.id}.`;\n\t\t\t\t} else {\n\t\t\t\t\tconst reason = !restoredModel ? \"model no longer exists\" : \"no API key available\";\n\t\t\t\t\tmodelFallbackMessage = `Could not restore model ${savedModel.provider}/${savedModel.modelId} (${reason}). Using ${initialModel.provider}/${initialModel.id}.`;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Log loaded context files (they're already in the system prompt)\n\tif (shouldPrintMessages && !parsed.continue && !parsed.resume) {\n\t\tconst contextFiles = loadProjectContextFiles();\n\t\tif (contextFiles.length > 0) {\n\t\t\tconsole.log(chalk.dim(\"Loaded project context from:\"));\n\t\t\tfor (const { path: filePath } of contextFiles) {\n\t\t\t\tconsole.log(chalk.dim(` - ${filePath}`));\n\t\t\t}\n\t\t}\n\t}\n\n\t// Route to appropriate mode\n\tif (mode === \"rpc\") {\n\t\t// RPC mode - headless operation\n\t\tawait runRpcMode(agent, sessionManager);\n\t} else if (isInteractive) {\n\t\t// Check for new version (don't block startup if it takes too long)\n\t\tlet newVersion: string | null = null;\n\t\ttry {\n\t\t\tnewVersion = await Promise.race([\n\t\t\t\tcheckForNewVersion(VERSION),\n\t\t\t\tnew Promise<null>((resolve) => setTimeout(() => resolve(null), 1000)), // 1 second timeout\n\t\t\t]);\n\t\t} catch (e) {\n\t\t\t// Ignore errors\n\t\t}\n\n\t\t// Check if we should show changelog (only in interactive mode, only for new sessions)\n\t\tlet changelogMarkdown: string | null = null;\n\t\tif (!parsed.continue && !parsed.resume) {\n\t\t\tconst lastVersion = settingsManager.getLastChangelogVersion();\n\n\t\t\t// Check if we need to show changelog\n\t\t\tif (!lastVersion) {\n\t\t\t\t// First run - show all entries\n\t\t\t\tconst changelogPath = getChangelogPath();\n\t\t\t\tconst entries = parseChangelog(changelogPath);\n\t\t\t\tif (entries.length > 0) {\n\t\t\t\t\tchangelogMarkdown = entries.map((e) => e.content).join(\"\\n\\n\");\n\t\t\t\t\tsettingsManager.setLastChangelogVersion(VERSION);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Parse current and last versions\n\t\t\t\tconst changelogPath = getChangelogPath();\n\t\t\t\tconst entries = parseChangelog(changelogPath);\n\t\t\t\tconst newEntries = getNewEntries(entries, lastVersion);\n\n\t\t\t\tif (newEntries.length > 0) {\n\t\t\t\t\tchangelogMarkdown = newEntries.map((e) => e.content).join(\"\\n\\n\");\n\t\t\t\t\tsettingsManager.setLastChangelogVersion(VERSION);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Show model scope if provided\n\t\tif (scopedModels.length > 0) {\n\t\t\tconst modelList = scopedModels\n\t\t\t\t.map((sm) => {\n\t\t\t\t\tconst thinkingStr = sm.thinkingLevel !== \"off\" ? `:${sm.thinkingLevel}` : \"\";\n\t\t\t\t\treturn `${sm.model.id}${thinkingStr}`;\n\t\t\t\t})\n\t\t\t\t.join(\", \");\n\t\t\tconsole.log(chalk.dim(`Model scope: ${modelList} ${chalk.gray(\"(Ctrl+P to cycle)\")}`));\n\t\t}\n\n\t\t// Interactive mode - use TUI (may have initial messages from CLI args)\n\t\tawait runInteractiveMode(\n\t\t\tagent,\n\t\t\tsessionManager,\n\t\t\tsettingsManager,\n\t\t\tVERSION,\n\t\t\tchangelogMarkdown,\n\t\t\tmodelFallbackMessage,\n\t\t\tnewVersion,\n\t\t\tscopedModels,\n\t\t\tparsed.messages,\n\t\t);\n\t} else {\n\t\t// Non-interactive mode (--print flag or --mode flag)\n\t\tawait runSingleShotMode(agent, sessionManager, parsed.messages, mode);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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","sourcesContent":["import { Agent, type Attachment, ProviderTransport, type ThinkingLevel } from \"@mariozechner/pi-agent-core\";\nimport type { Api, KnownProvider, Model } from \"@mariozechner/pi-ai\";\nimport { ProcessTerminal, TUI } from \"@mariozechner/pi-tui\";\nimport chalk from \"chalk\";\nimport { existsSync, readFileSync, statSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { dirname, extname, join, resolve } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { getChangelogPath, getNewEntries, parseChangelog } from \"./changelog.js\";\nimport { findModel, getApiKeyForModel, getAvailableModels } from \"./model-config.js\";\nimport { SessionManager } from \"./session-manager.js\";\nimport { SettingsManager } from \"./settings-manager.js\";\nimport { initTheme } from \"./theme/theme.js\";\nimport { codingTools } from \"./tools/index.js\";\nimport { SessionSelectorComponent } from \"./tui/session-selector.js\";\nimport { TuiRenderer } from \"./tui/tui-renderer.js\";\n\n// Get version from package.json\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst packageJson = JSON.parse(readFileSync(join(__dirname, \"../package.json\"), \"utf-8\"));\nconst VERSION = packageJson.version;\n\nconst defaultModelPerProvider: Record<KnownProvider, string> = {\n\tanthropic: \"claude-sonnet-4-5\",\n\topenai: \"gpt-5.1-codex\",\n\tgoogle: \"gemini-2.5-pro\",\n\topenrouter: \"openai/gpt-5.1-codex\",\n\txai: \"grok-4-fast-non-reasoning\",\n\tgroq: \"openai/gpt-oss-120b\",\n\tcerebras: \"zai-glm-4.6\",\n\tzai: \"glm-4.6\",\n};\n\ntype Mode = \"text\" | \"json\" | \"rpc\";\n\ninterface Args {\n\tprovider?: string;\n\tmodel?: string;\n\tapiKey?: string;\n\tsystemPrompt?: string;\n\tthinking?: ThinkingLevel;\n\tcontinue?: boolean;\n\tresume?: boolean;\n\thelp?: boolean;\n\tmode?: Mode;\n\tnoSession?: boolean;\n\tsession?: string;\n\tmodels?: string[];\n\tprint?: boolean;\n\tmessages: string[];\n\tfileArgs: string[];\n}\n\nfunction parseArgs(args: string[]): Args {\n\tconst result: Args = {\n\t\tmessages: [],\n\t\tfileArgs: [],\n\t};\n\n\tfor (let i = 0; i < args.length; i++) {\n\t\tconst arg = args[i];\n\n\t\tif (arg === \"--help\" || arg === \"-h\") {\n\t\t\tresult.help = true;\n\t\t} else if (arg === \"--mode\" && i + 1 < args.length) {\n\t\t\tconst mode = args[++i];\n\t\t\tif (mode === \"text\" || mode === \"json\" || mode === \"rpc\") {\n\t\t\t\tresult.mode = mode;\n\t\t\t}\n\t\t} else if (arg === \"--continue\" || arg === \"-c\") {\n\t\t\tresult.continue = true;\n\t\t} else if (arg === \"--resume\" || arg === \"-r\") {\n\t\t\tresult.resume = true;\n\t\t} else if (arg === \"--provider\" && i + 1 < args.length) {\n\t\t\tresult.provider = args[++i];\n\t\t} else if (arg === \"--model\" && i + 1 < args.length) {\n\t\t\tresult.model = args[++i];\n\t\t} else if (arg === \"--api-key\" && i + 1 < args.length) {\n\t\t\tresult.apiKey = args[++i];\n\t\t} else if (arg === \"--system-prompt\" && i + 1 < args.length) {\n\t\t\tresult.systemPrompt = args[++i];\n\t\t} else if (arg === \"--no-session\") {\n\t\t\tresult.noSession = true;\n\t\t} else if (arg === \"--session\" && i + 1 < args.length) {\n\t\t\tresult.session = args[++i];\n\t\t} else if (arg === \"--models\" && i + 1 < args.length) {\n\t\t\tresult.models = args[++i].split(\",\").map((s) => s.trim());\n\t\t} else if (arg === \"--thinking\" && i + 1 < args.length) {\n\t\t\tconst level = args[++i];\n\t\t\tif (level === \"off\" || level === \"minimal\" || level === \"low\" || level === \"medium\" || level === \"high\") {\n\t\t\t\tresult.thinking = level;\n\t\t\t} else {\n\t\t\t\tconsole.error(\n\t\t\t\t\tchalk.yellow(\n\t\t\t\t\t\t`Warning: Invalid thinking level \"${level}\". Valid values: off, minimal, low, medium, high`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t} else if (arg === \"--print\" || arg === \"-p\") {\n\t\t\tresult.print = true;\n\t\t} else if (arg.startsWith(\"@\")) {\n\t\t\tresult.fileArgs.push(arg.slice(1)); // Remove @ prefix\n\t\t} else if (!arg.startsWith(\"-\")) {\n\t\t\tresult.messages.push(arg);\n\t\t}\n\t}\n\n\treturn result;\n}\n\n/**\n * Map of file extensions to MIME types for common image formats\n */\nconst IMAGE_MIME_TYPES: Record<string, string> = {\n\t\".jpg\": \"image/jpeg\",\n\t\".jpeg\": \"image/jpeg\",\n\t\".png\": \"image/png\",\n\t\".gif\": \"image/gif\",\n\t\".webp\": \"image/webp\",\n};\n\n/**\n * Check if a file is an image based on its extension\n */\nfunction isImageFile(filePath: string): string | null {\n\tconst ext = extname(filePath).toLowerCase();\n\treturn IMAGE_MIME_TYPES[ext] || null;\n}\n\n/**\n * Expand ~ to home directory\n */\nfunction expandPath(filePath: string): string {\n\tif (filePath === \"~\") {\n\t\treturn homedir();\n\t}\n\tif (filePath.startsWith(\"~/\")) {\n\t\treturn homedir() + filePath.slice(1);\n\t}\n\treturn filePath;\n}\n\n/**\n * Process @file arguments into text content and image attachments\n */\nfunction processFileArguments(fileArgs: string[]): { textContent: string; imageAttachments: Attachment[] } {\n\tlet textContent = \"\";\n\tconst imageAttachments: Attachment[] = [];\n\n\tfor (const fileArg of fileArgs) {\n\t\t// Expand and resolve path\n\t\tconst expandedPath = expandPath(fileArg);\n\t\tconst absolutePath = resolve(expandedPath);\n\n\t\t// Check if file exists\n\t\tif (!existsSync(absolutePath)) {\n\t\t\tconsole.error(chalk.red(`Error: File not found: ${absolutePath}`));\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\t// Check if file is empty\n\t\tconst stats = statSync(absolutePath);\n\t\tif (stats.size === 0) {\n\t\t\t// Skip empty files\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst mimeType = isImageFile(absolutePath);\n\n\t\tif (mimeType) {\n\t\t\t// Handle image file\n\t\t\tconst content = readFileSync(absolutePath);\n\t\t\tconst base64Content = content.toString(\"base64\");\n\n\t\t\tconst attachment: Attachment = {\n\t\t\t\tid: `file-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,\n\t\t\t\ttype: \"image\",\n\t\t\t\tfileName: absolutePath.split(\"/\").pop() || absolutePath,\n\t\t\t\tmimeType,\n\t\t\t\tsize: stats.size,\n\t\t\t\tcontent: base64Content,\n\t\t\t};\n\n\t\t\timageAttachments.push(attachment);\n\n\t\t\t// Add text reference to image\n\t\t\ttextContent += `<file name=\"${absolutePath}\"></file>\\n`;\n\t\t} else {\n\t\t\t// Handle text file\n\t\t\ttry {\n\t\t\t\tconst content = readFileSync(absolutePath, \"utf-8\");\n\t\t\t\ttextContent += `<file name=\"${absolutePath}\">\\n${content}\\n</file>\\n`;\n\t\t\t} catch (error: any) {\n\t\t\t\tconsole.error(chalk.red(`Error: Could not read file ${absolutePath}: ${error.message}`));\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { textContent, imageAttachments };\n}\n\nfunction printHelp() {\n\tconsole.log(`${chalk.bold(\"pi\")} - AI coding assistant with read, bash, edit, write tools\n\n${chalk.bold(\"Usage:\")}\n pi [options] [@files...] [messages...]\n\n${chalk.bold(\"Options:\")}\n --provider <name> Provider name (default: google)\n --model <id> Model ID (default: gemini-2.5-flash)\n --api-key <key> API key (defaults to env vars)\n --system-prompt <text> System prompt (default: coding assistant prompt)\n --mode <mode> Output mode: text (default), json, or rpc\n --print, -p Non-interactive mode: process prompt and exit\n --continue, -c Continue previous session\n --resume, -r Select a session to resume\n --session <path> Use specific session file\n --no-session Don't save session (ephemeral)\n --models <patterns> Comma-separated model patterns for quick cycling with Ctrl+P\n --thinking <level> Set thinking level: off, minimal, low, medium, high\n --help, -h Show this help\n\n${chalk.bold(\"Examples:\")}\n # Interactive mode\n pi\n\n # Interactive mode with initial prompt\n pi \"List all .ts files in src/\"\n\n # Include files in initial message\n pi @prompt.md @image.png \"What color is the sky?\"\n\n # Non-interactive mode (process and exit)\n pi -p \"List all .ts files in src/\"\n\n # Multiple messages (interactive)\n pi \"Read package.json\" \"What dependencies do we have?\"\n\n # Continue previous session\n pi --continue \"What did we discuss?\"\n\n # Use different model\n pi --provider openai --model gpt-4o-mini \"Help me refactor this code\"\n\n # Limit model cycling to specific models\n pi --models claude-sonnet,claude-haiku,gpt-4o\n\n # Cycle models with fixed thinking levels\n pi --models sonnet:high,haiku:low\n\n # Start with a specific thinking level\n pi --thinking high \"Solve this complex problem\"\n\n${chalk.bold(\"Environment Variables:\")}\n ANTHROPIC_API_KEY - Anthropic Claude API key\n ANTHROPIC_OAUTH_TOKEN - Anthropic OAuth token (alternative to API key)\n OPENAI_API_KEY - OpenAI GPT API key\n GEMINI_API_KEY - Google Gemini API key\n GROQ_API_KEY - Groq API key\n CEREBRAS_API_KEY - Cerebras API key\n XAI_API_KEY - xAI Grok API key\n OPENROUTER_API_KEY - OpenRouter API key\n ZAI_API_KEY - ZAI API key\n PI_CODING_AGENT_DIR - Session storage directory (default: ~/.pi/agent)\n\n${chalk.bold(\"Available Tools:\")}\n read - Read file contents\n bash - Execute bash commands\n edit - Edit files with find/replace\n write - Write files (creates/overwrites)\n`);\n}\n\nfunction buildSystemPrompt(customPrompt?: string): string {\n\t// Check if customPrompt is a file path that exists\n\tif (customPrompt && existsSync(customPrompt)) {\n\t\ttry {\n\t\t\tcustomPrompt = readFileSync(customPrompt, \"utf-8\");\n\t\t} catch (error) {\n\t\t\tconsole.error(chalk.yellow(`Warning: Could not read system prompt file ${customPrompt}: ${error}`));\n\t\t\t// Fall through to use as literal string\n\t\t}\n\t}\n\n\tif (customPrompt) {\n\t\t// Use custom prompt as base, then add context/datetime\n\t\tconst now = new Date();\n\t\tconst dateTime = now.toLocaleString(\"en-US\", {\n\t\t\tweekday: \"long\",\n\t\t\tyear: \"numeric\",\n\t\t\tmonth: \"long\",\n\t\t\tday: \"numeric\",\n\t\t\thour: \"2-digit\",\n\t\t\tminute: \"2-digit\",\n\t\t\tsecond: \"2-digit\",\n\t\t\ttimeZoneName: \"short\",\n\t\t});\n\n\t\tlet prompt = customPrompt;\n\n\t\t// Append project context files\n\t\tconst contextFiles = loadProjectContextFiles();\n\t\tif (contextFiles.length > 0) {\n\t\t\tprompt += \"\\n\\n# Project Context\\n\\n\";\n\t\t\tprompt += \"The following project context files have been loaded:\\n\\n\";\n\t\t\tfor (const { path: filePath, content } of contextFiles) {\n\t\t\t\tprompt += `## ${filePath}\\n\\n${content}\\n\\n`;\n\t\t\t}\n\t\t}\n\n\t\t// Add date/time and working directory last\n\t\tprompt += `\\nCurrent date and time: ${dateTime}`;\n\t\tprompt += `\\nCurrent working directory: ${process.cwd()}`;\n\n\t\treturn prompt;\n\t}\n\n\tconst now = new Date();\n\tconst dateTime = now.toLocaleString(\"en-US\", {\n\t\tweekday: \"long\",\n\t\tyear: \"numeric\",\n\t\tmonth: \"long\",\n\t\tday: \"numeric\",\n\t\thour: \"2-digit\",\n\t\tminute: \"2-digit\",\n\t\tsecond: \"2-digit\",\n\t\ttimeZoneName: \"short\",\n\t});\n\n\t// Get absolute path to README.md\n\tconst readmePath = resolve(join(__dirname, \"../README.md\"));\n\n\tlet prompt = `You are actually not Claude, you are Pi. You are an expert coding assistant. You help users with coding tasks by reading files, executing commands, editing code, and writing new files.\n\nAvailable tools:\n- read: Read file contents\n- bash: Execute bash commands (ls, grep, find, etc.)\n- edit: Make surgical edits to files (find exact text and replace)\n- write: Create or overwrite files\n\nGuidelines:\n- Always use bash tool for file operations like ls, grep, find\n- Use read to examine files before editing\n- Use edit for precise changes (old text must match exactly)\n- Use write only for new files or complete rewrites\n- Be concise in your responses\n- Show file paths clearly when working with files\n- When summarizing your actions, output plain text directly - do NOT use cat or bash to display what you did\n\nDocumentation:\n- Your own documentation (including custom model setup and theme creation) is at: ${readmePath}\n- 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.`;\n\n\t// Append project context files\n\tconst contextFiles = loadProjectContextFiles();\n\tif (contextFiles.length > 0) {\n\t\tprompt += \"\\n\\n# Project Context\\n\\n\";\n\t\tprompt += \"The following project context files have been loaded:\\n\\n\";\n\t\tfor (const { path: filePath, content } of contextFiles) {\n\t\t\tprompt += `## ${filePath}\\n\\n${content}\\n\\n`;\n\t\t}\n\t}\n\n\t// Add date/time and working directory last\n\tprompt += `\\nCurrent date and time: ${dateTime}`;\n\tprompt += `\\nCurrent working directory: ${process.cwd()}`;\n\n\treturn prompt;\n}\n\n/**\n * Look for AGENTS.md or CLAUDE.md in a directory (prefers AGENTS.md)\n */\nfunction loadContextFileFromDir(dir: string): { path: string; content: string } | null {\n\tconst candidates = [\"AGENTS.md\", \"CLAUDE.md\"];\n\tfor (const filename of candidates) {\n\t\tconst filePath = join(dir, filename);\n\t\tif (existsSync(filePath)) {\n\t\t\ttry {\n\t\t\t\treturn {\n\t\t\t\t\tpath: filePath,\n\t\t\t\t\tcontent: readFileSync(filePath, \"utf-8\"),\n\t\t\t\t};\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(chalk.yellow(`Warning: Could not read ${filePath}: ${error}`));\n\t\t\t}\n\t\t}\n\t}\n\treturn null;\n}\n\n/**\n * Load all project context files in order:\n * 1. Global: ~/.pi/agent/AGENTS.md or CLAUDE.md\n * 2. Parent directories (top-most first) down to cwd\n * Each returns {path, content} for separate messages\n */\nfunction loadProjectContextFiles(): Array<{ path: string; content: string }> {\n\tconst contextFiles: Array<{ path: string; content: string }> = [];\n\n\t// 1. Load global context from ~/.pi/agent/\n\tconst homeDir = homedir();\n\tconst globalContextDir = resolve(process.env.PI_CODING_AGENT_DIR || join(homeDir, \".pi/agent/\"));\n\tconst globalContext = loadContextFileFromDir(globalContextDir);\n\tif (globalContext) {\n\t\tcontextFiles.push(globalContext);\n\t}\n\n\t// 2. Walk up from cwd to root, collecting all context files\n\tconst cwd = process.cwd();\n\tconst ancestorContextFiles: Array<{ path: string; content: string }> = [];\n\n\tlet currentDir = cwd;\n\tconst root = resolve(\"/\");\n\n\twhile (true) {\n\t\tconst contextFile = loadContextFileFromDir(currentDir);\n\t\tif (contextFile) {\n\t\t\t// Add to beginning so we get top-most parent first\n\t\t\tancestorContextFiles.unshift(contextFile);\n\t\t}\n\n\t\t// Stop if we've reached root\n\t\tif (currentDir === root) break;\n\n\t\t// Move up one directory\n\t\tconst parentDir = resolve(currentDir, \"..\");\n\t\tif (parentDir === currentDir) break; // Safety check\n\t\tcurrentDir = parentDir;\n\t}\n\n\t// Add ancestor files in order (top-most → cwd)\n\tcontextFiles.push(...ancestorContextFiles);\n\n\treturn contextFiles;\n}\n\nasync function checkForNewVersion(currentVersion: string): Promise<string | null> {\n\ttry {\n\t\tconst response = await fetch(\"https://registry.npmjs.org/@mariozechner/pi-coding-agent/latest\");\n\t\tif (!response.ok) return null;\n\n\t\tconst data = (await response.json()) as { version?: string };\n\t\tconst latestVersion = data.version;\n\n\t\tif (latestVersion && latestVersion !== currentVersion) {\n\t\t\treturn latestVersion;\n\t\t}\n\n\t\treturn null;\n\t} catch (error) {\n\t\t// Silently fail - don't disrupt the user experience\n\t\treturn null;\n\t}\n}\n\n/**\n * Resolve model patterns to actual Model objects with optional thinking levels\n * Format: \"pattern:level\" where :level is optional\n * For each pattern, finds all matching models and picks the best version:\n * 1. Prefer alias (e.g., claude-sonnet-4-5) over dated versions (claude-sonnet-4-5-20250929)\n * 2. If no alias, pick the latest dated version\n */\nasync function resolveModelScope(\n\tpatterns: string[],\n): Promise<Array<{ model: Model<Api>; thinkingLevel: ThinkingLevel }>> {\n\tconst { models: availableModels, error } = await getAvailableModels();\n\n\tif (error) {\n\t\tconsole.warn(chalk.yellow(`Warning: Error loading models: ${error}`));\n\t\treturn [];\n\t}\n\n\tconst scopedModels: Array<{ model: Model<Api>; thinkingLevel: ThinkingLevel }> = [];\n\n\tfor (const pattern of patterns) {\n\t\t// Parse pattern:level format\n\t\tconst parts = pattern.split(\":\");\n\t\tconst modelPattern = parts[0];\n\t\tlet thinkingLevel: ThinkingLevel = \"off\";\n\n\t\tif (parts.length > 1) {\n\t\t\tconst level = parts[1];\n\t\t\tif (level === \"off\" || level === \"minimal\" || level === \"low\" || level === \"medium\" || level === \"high\") {\n\t\t\t\tthinkingLevel = level;\n\t\t\t} else {\n\t\t\t\tconsole.warn(\n\t\t\t\t\tchalk.yellow(`Warning: Invalid thinking level \"${level}\" in pattern \"${pattern}\". Using \"off\" instead.`),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Check for provider/modelId format (provider is everything before the first /)\n\t\tconst slashIndex = modelPattern.indexOf(\"/\");\n\t\tif (slashIndex !== -1) {\n\t\t\tconst provider = modelPattern.substring(0, slashIndex);\n\t\t\tconst modelId = modelPattern.substring(slashIndex + 1);\n\t\t\tconst providerMatch = availableModels.find(\n\t\t\t\t(m) => m.provider.toLowerCase() === provider.toLowerCase() && m.id.toLowerCase() === modelId.toLowerCase(),\n\t\t\t);\n\t\t\tif (providerMatch) {\n\t\t\t\tif (\n\t\t\t\t\t!scopedModels.find(\n\t\t\t\t\t\t(sm) => sm.model.id === providerMatch.id && sm.model.provider === providerMatch.provider,\n\t\t\t\t\t)\n\t\t\t\t) {\n\t\t\t\t\tscopedModels.push({ model: providerMatch, thinkingLevel });\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// No exact provider/model match - fall through to other matching\n\t\t}\n\n\t\t// Check for exact ID match (case-insensitive)\n\t\tconst exactMatch = availableModels.find((m) => m.id.toLowerCase() === modelPattern.toLowerCase());\n\t\tif (exactMatch) {\n\t\t\t// Exact match found - use it directly\n\t\t\tif (!scopedModels.find((sm) => sm.model.id === exactMatch.id && sm.model.provider === exactMatch.provider)) {\n\t\t\t\tscopedModels.push({ model: exactMatch, thinkingLevel });\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\t// No exact match - fall back to partial matching\n\t\tconst matches = availableModels.filter(\n\t\t\t(m) =>\n\t\t\t\tm.id.toLowerCase().includes(modelPattern.toLowerCase()) ||\n\t\t\t\tm.name?.toLowerCase().includes(modelPattern.toLowerCase()),\n\t\t);\n\n\t\tif (matches.length === 0) {\n\t\t\tconsole.warn(chalk.yellow(`Warning: No models match pattern \"${modelPattern}\"`));\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Helper to check if a model ID looks like an alias (no date suffix)\n\t\t// Dates are typically in format: -20241022 or -20250929\n\t\tconst isAlias = (id: string): boolean => {\n\t\t\t// Check if ID ends with -latest\n\t\t\tif (id.endsWith(\"-latest\")) return true;\n\n\t\t\t// Check if ID ends with a date pattern (-YYYYMMDD)\n\t\t\tconst datePattern = /-\\d{8}$/;\n\t\t\treturn !datePattern.test(id);\n\t\t};\n\n\t\t// Separate into aliases and dated versions\n\t\tconst aliases = matches.filter((m) => isAlias(m.id));\n\t\tconst datedVersions = matches.filter((m) => !isAlias(m.id));\n\n\t\tlet bestMatch: Model<Api>;\n\n\t\tif (aliases.length > 0) {\n\t\t\t// Prefer alias - if multiple aliases, pick the one that sorts highest\n\t\t\taliases.sort((a, b) => b.id.localeCompare(a.id));\n\t\t\tbestMatch = aliases[0];\n\t\t} else {\n\t\t\t// No alias found, pick latest dated version\n\t\t\tdatedVersions.sort((a, b) => b.id.localeCompare(a.id));\n\t\t\tbestMatch = datedVersions[0];\n\t\t}\n\n\t\t// Avoid duplicates\n\t\tif (!scopedModels.find((sm) => sm.model.id === bestMatch.id && sm.model.provider === bestMatch.provider)) {\n\t\t\tscopedModels.push({ model: bestMatch, thinkingLevel });\n\t\t}\n\t}\n\n\treturn scopedModels;\n}\n\nasync function selectSession(sessionManager: SessionManager): Promise<string | null> {\n\treturn new Promise((resolve) => {\n\t\tconst ui = new TUI(new ProcessTerminal());\n\t\tlet resolved = false;\n\n\t\tconst selector = new SessionSelectorComponent(\n\t\t\tsessionManager,\n\t\t\t(path: string) => {\n\t\t\t\tif (!resolved) {\n\t\t\t\t\tresolved = true;\n\t\t\t\t\tui.stop();\n\t\t\t\t\tresolve(path);\n\t\t\t\t}\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tif (!resolved) {\n\t\t\t\t\tresolved = true;\n\t\t\t\t\tui.stop();\n\t\t\t\t\tresolve(null);\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\n\t\tui.addChild(selector);\n\t\tui.setFocus(selector.getSessionList());\n\t\tui.start();\n\t});\n}\n\nasync function runInteractiveMode(\n\tagent: Agent,\n\tsessionManager: SessionManager,\n\tsettingsManager: SettingsManager,\n\tversion: string,\n\tchangelogMarkdown: string | null = null,\n\tmodelFallbackMessage: string | null = null,\n\tnewVersion: string | null = null,\n\tscopedModels: Array<{ model: Model<Api>; thinkingLevel: ThinkingLevel }> = [],\n\tinitialMessages: string[] = [],\n\tinitialMessage?: string,\n\tinitialAttachments?: Attachment[],\n): Promise<void> {\n\tconst renderer = new TuiRenderer(\n\t\tagent,\n\t\tsessionManager,\n\t\tsettingsManager,\n\t\tversion,\n\t\tchangelogMarkdown,\n\t\tnewVersion,\n\t\tscopedModels,\n\t);\n\n\t// Initialize TUI (subscribes to agent events internally)\n\tawait renderer.init();\n\n\t// Render any existing messages (from --continue mode)\n\trenderer.renderInitialMessages(agent.state);\n\n\t// Show model fallback warning at the end of the chat if applicable\n\tif (modelFallbackMessage) {\n\t\trenderer.showWarning(modelFallbackMessage);\n\t}\n\n\t// Process initial message with attachments if provided (from @file args)\n\tif (initialMessage) {\n\t\ttry {\n\t\t\tawait agent.prompt(initialMessage, initialAttachments);\n\t\t} catch (error: unknown) {\n\t\t\tconst errorMessage = error instanceof Error ? error.message : \"Unknown error occurred\";\n\t\t\trenderer.showError(errorMessage);\n\t\t}\n\t}\n\n\t// Process remaining initial messages if provided (from CLI args)\n\tfor (const message of initialMessages) {\n\t\ttry {\n\t\t\tawait agent.prompt(message);\n\t\t} catch (error: unknown) {\n\t\t\tconst errorMessage = error instanceof Error ? error.message : \"Unknown error occurred\";\n\t\t\trenderer.showError(errorMessage);\n\t\t}\n\t}\n\n\t// Interactive loop\n\twhile (true) {\n\t\tconst userInput = await renderer.getUserInput();\n\n\t\t// Process the message - agent.prompt will add user message and trigger state updates\n\t\ttry {\n\t\t\tawait agent.prompt(userInput);\n\t\t} catch (error: unknown) {\n\t\t\t// Display error in the TUI by adding an error message to the chat\n\t\t\tconst errorMessage = error instanceof Error ? error.message : \"Unknown error occurred\";\n\t\t\trenderer.showError(errorMessage);\n\t\t}\n\t}\n}\n\nasync function runSingleShotMode(\n\tagent: Agent,\n\t_sessionManager: SessionManager,\n\tmessages: string[],\n\tmode: \"text\" | \"json\",\n\tinitialMessage?: string,\n\tinitialAttachments?: Attachment[],\n): Promise<void> {\n\tif (mode === \"json\") {\n\t\t// Subscribe to all events and output as JSON\n\t\tagent.subscribe((event) => {\n\t\t\t// Output event as JSON (same format as session manager)\n\t\t\tconsole.log(JSON.stringify(event));\n\t\t});\n\t}\n\n\t// Send initial message with attachments if provided\n\tif (initialMessage) {\n\t\tawait agent.prompt(initialMessage, initialAttachments);\n\t}\n\n\t// Send remaining messages\n\tfor (const message of messages) {\n\t\tawait agent.prompt(message);\n\t}\n\n\t// In text mode, only output the final assistant message\n\tif (mode === \"text\") {\n\t\tconst lastMessage = agent.state.messages[agent.state.messages.length - 1];\n\t\tif (lastMessage.role === \"assistant\") {\n\t\t\tfor (const content of lastMessage.content) {\n\t\t\t\tif (content.type === \"text\") {\n\t\t\t\t\tconsole.log(content.text);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nasync function runRpcMode(agent: Agent, _sessionManager: SessionManager): Promise<void> {\n\t// Subscribe to all events and output as JSON\n\tagent.subscribe((event) => {\n\t\tconsole.log(JSON.stringify(event));\n\t});\n\n\t// Listen for JSON input on stdin\n\tconst readline = await import(\"readline\");\n\tconst rl = readline.createInterface({\n\t\tinput: process.stdin,\n\t\toutput: process.stdout,\n\t\tterminal: false,\n\t});\n\n\trl.on(\"line\", async (line: string) => {\n\t\ttry {\n\t\t\tconst input = JSON.parse(line);\n\n\t\t\t// Handle different RPC commands\n\t\t\tif (input.type === \"prompt\" && input.message) {\n\t\t\t\tawait agent.prompt(input.message, input.attachments);\n\t\t\t} else if (input.type === \"abort\") {\n\t\t\t\tagent.abort();\n\t\t\t}\n\t\t} catch (error: any) {\n\t\t\t// Output error as JSON\n\t\t\tconsole.log(JSON.stringify({ type: \"error\", error: error.message }));\n\t\t}\n\t});\n\n\t// Keep process alive\n\treturn new Promise(() => {});\n}\n\nexport async function main(args: string[]) {\n\tconst parsed = parseArgs(args);\n\n\tif (parsed.help) {\n\t\tprintHelp();\n\t\treturn;\n\t}\n\n\t// Validate: RPC mode doesn't support @file arguments\n\tif (parsed.mode === \"rpc\" && parsed.fileArgs.length > 0) {\n\t\tconsole.error(chalk.red(\"Error: @file arguments are not supported in RPC mode\"));\n\t\tprocess.exit(1);\n\t}\n\n\t// Process @file arguments if any\n\tlet initialMessage: string | undefined;\n\tlet initialAttachments: Attachment[] | undefined;\n\n\tif (parsed.fileArgs.length > 0) {\n\t\tconst { textContent, imageAttachments } = processFileArguments(parsed.fileArgs);\n\n\t\t// Combine file content with first plain text message (if any)\n\t\tif (parsed.messages.length > 0) {\n\t\t\tinitialMessage = textContent + parsed.messages[0];\n\t\t\tparsed.messages.shift(); // Remove first message as it's been combined\n\t\t} else {\n\t\t\tinitialMessage = textContent;\n\t\t}\n\n\t\tinitialAttachments = imageAttachments.length > 0 ? imageAttachments : undefined;\n\t}\n\n\t// Initialize theme (before any TUI rendering)\n\tconst settingsManager = new SettingsManager();\n\tconst themeName = settingsManager.getTheme();\n\tinitTheme(themeName);\n\n\t// Setup session manager\n\tconst sessionManager = new SessionManager(parsed.continue && !parsed.resume, parsed.session);\n\n\t// Disable session saving if --no-session flag is set\n\tif (parsed.noSession) {\n\t\tsessionManager.disable();\n\t}\n\n\t// Handle --resume flag: show session selector\n\tif (parsed.resume) {\n\t\tconst selectedSession = await selectSession(sessionManager);\n\t\tif (!selectedSession) {\n\t\t\tconsole.log(chalk.dim(\"No session selected\"));\n\t\t\treturn;\n\t\t}\n\t\t// Set the selected session as the active session\n\t\tsessionManager.setSessionFile(selectedSession);\n\t}\n\n\t// Resolve model scope early if provided (needed for initial model selection)\n\tlet scopedModels: Array<{ model: Model<Api>; thinkingLevel: ThinkingLevel }> = [];\n\tif (parsed.models && parsed.models.length > 0) {\n\t\tscopedModels = await resolveModelScope(parsed.models);\n\t}\n\n\t// Determine initial model using priority system:\n\t// 1. CLI args (--provider and --model)\n\t// 2. First model from --models scope\n\t// 3. Restored from session (if --continue or --resume)\n\t// 4. Saved default from settings.json\n\t// 5. First available model with valid API key\n\t// 6. null (allowed in interactive mode)\n\tlet initialModel: Model<Api> | null = null;\n\tlet initialThinking: ThinkingLevel = \"off\";\n\n\tif (parsed.provider && parsed.model) {\n\t\t// 1. CLI args take priority\n\t\tconst { model, error } = findModel(parsed.provider, parsed.model);\n\t\tif (error) {\n\t\t\tconsole.error(chalk.red(error));\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tif (!model) {\n\t\t\tconsole.error(chalk.red(`Model ${parsed.provider}/${parsed.model} not found`));\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tinitialModel = model;\n\t} else if (scopedModels.length > 0 && !parsed.continue && !parsed.resume) {\n\t\t// 2. Use first model from --models scope (skip if continuing/resuming session)\n\t\tinitialModel = scopedModels[0].model;\n\t\tinitialThinking = scopedModels[0].thinkingLevel;\n\t} else if (parsed.continue || parsed.resume) {\n\t\t// 3. Restore from session (will be handled below after loading session)\n\t\t// Leave initialModel as null for now\n\t}\n\n\tif (!initialModel) {\n\t\t// 3. Try saved default from settings\n\t\tconst defaultProvider = settingsManager.getDefaultProvider();\n\t\tconst defaultModel = settingsManager.getDefaultModel();\n\t\tif (defaultProvider && defaultModel) {\n\t\t\tconst { model, error } = findModel(defaultProvider, defaultModel);\n\t\t\tif (error) {\n\t\t\t\tconsole.error(chalk.red(error));\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\tinitialModel = model;\n\n\t\t\t// Also load saved thinking level if we're using saved model\n\t\t\tconst savedThinking = settingsManager.getDefaultThinkingLevel();\n\t\t\tif (savedThinking) {\n\t\t\t\tinitialThinking = savedThinking;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!initialModel) {\n\t\t// 4. Try first available model with valid API key\n\t\t// Prefer default model for each provider if available\n\t\tconst { models: availableModels, error } = await getAvailableModels();\n\n\t\tif (error) {\n\t\t\tconsole.error(chalk.red(error));\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tif (availableModels.length > 0) {\n\t\t\t// Try to find a default model from known providers\n\t\t\tfor (const provider of Object.keys(defaultModelPerProvider) as KnownProvider[]) {\n\t\t\t\tconst defaultModelId = defaultModelPerProvider[provider];\n\t\t\t\tconst match = availableModels.find((m) => m.provider === provider && m.id === defaultModelId);\n\t\t\t\tif (match) {\n\t\t\t\t\tinitialModel = match;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If no default found, use first available\n\t\t\tif (!initialModel) {\n\t\t\t\tinitialModel = availableModels[0];\n\t\t\t}\n\t\t}\n\t}\n\n\t// Determine mode early to know if we should print messages and fail early\n\t// Interactive mode: no --print flag and no --mode flag\n\t// Having initial messages doesn't make it non-interactive anymore\n\tconst isInteractive = !parsed.print && parsed.mode === undefined;\n\tconst mode = parsed.mode || \"text\";\n\t// Only print informational messages in interactive mode\n\t// Non-interactive modes (-p, --mode json, --mode rpc) should be silent except for output\n\tconst shouldPrintMessages = isInteractive;\n\n\t// Non-interactive mode: fail early if no model available\n\tif (!isInteractive && !initialModel) {\n\t\tconsole.error(chalk.red(\"No models available.\"));\n\t\tconsole.error(chalk.yellow(\"\\nSet an API key environment variable:\"));\n\t\tconsole.error(\" ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, etc.\");\n\t\tconsole.error(chalk.yellow(\"\\nOr create ~/.pi/agent/models.json\"));\n\t\tprocess.exit(1);\n\t}\n\n\t// Non-interactive mode: validate API key exists\n\tif (!isInteractive && initialModel) {\n\t\tconst apiKey = parsed.apiKey || (await getApiKeyForModel(initialModel));\n\t\tif (!apiKey) {\n\t\t\tconsole.error(chalk.red(`No API key found for ${initialModel.provider}`));\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\tconst systemPrompt = buildSystemPrompt(parsed.systemPrompt);\n\n\t// Load previous messages if continuing or resuming\n\t// This may update initialModel if restoring from session\n\tif (parsed.continue || parsed.resume) {\n\t\t// Load and restore model (overrides initialModel if found and has API key)\n\t\tconst savedModel = sessionManager.loadModel();\n\t\tif (savedModel) {\n\t\t\tconst { model: restoredModel, error } = findModel(savedModel.provider, savedModel.modelId);\n\n\t\t\tif (error) {\n\t\t\t\tconsole.error(chalk.red(error));\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\t// Check if restored model exists and has a valid API key\n\t\t\tconst hasApiKey = restoredModel ? !!(await getApiKeyForModel(restoredModel)) : false;\n\n\t\t\tif (restoredModel && hasApiKey) {\n\t\t\t\tinitialModel = restoredModel;\n\t\t\t\tif (shouldPrintMessages) {\n\t\t\t\t\tconsole.log(chalk.dim(`Restored model: ${savedModel.provider}/${savedModel.modelId}`));\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Model not found or no API key - fall back to default selection\n\t\t\t\tconst reason = !restoredModel ? \"model no longer exists\" : \"no API key available\";\n\n\t\t\t\tif (shouldPrintMessages) {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\tchalk.yellow(\n\t\t\t\t\t\t\t`Warning: Could not restore model ${savedModel.provider}/${savedModel.modelId} (${reason}).`,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// Ensure we have a valid model - use the same fallback logic\n\t\t\t\tif (!initialModel) {\n\t\t\t\t\tconst { models: availableModels, error: availableError } = await getAvailableModels();\n\t\t\t\t\tif (availableError) {\n\t\t\t\t\t\tconsole.error(chalk.red(availableError));\n\t\t\t\t\t\tprocess.exit(1);\n\t\t\t\t\t}\n\t\t\t\t\tif (availableModels.length > 0) {\n\t\t\t\t\t\t// Try to find a default model from known providers\n\t\t\t\t\t\tfor (const provider of Object.keys(defaultModelPerProvider) as KnownProvider[]) {\n\t\t\t\t\t\t\tconst defaultModelId = defaultModelPerProvider[provider];\n\t\t\t\t\t\t\tconst match = availableModels.find((m) => m.provider === provider && m.id === defaultModelId);\n\t\t\t\t\t\t\tif (match) {\n\t\t\t\t\t\t\t\tinitialModel = match;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// If no default found, use first available\n\t\t\t\t\t\tif (!initialModel) {\n\t\t\t\t\t\t\tinitialModel = availableModels[0];\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (initialModel && shouldPrintMessages) {\n\t\t\t\t\t\t\tconsole.log(chalk.dim(`Falling back to: ${initialModel.provider}/${initialModel.id}`));\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// No models available at all\n\t\t\t\t\t\tif (shouldPrintMessages) {\n\t\t\t\t\t\t\tconsole.error(chalk.red(\"\\nNo models available.\"));\n\t\t\t\t\t\t\tconsole.error(chalk.yellow(\"Set an API key environment variable:\"));\n\t\t\t\t\t\t\tconsole.error(\" ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, etc.\");\n\t\t\t\t\t\t\tconsole.error(chalk.yellow(\"\\nOr create ~/.pi/agent/models.json\"));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tprocess.exit(1);\n\t\t\t\t\t}\n\t\t\t\t} else if (shouldPrintMessages) {\n\t\t\t\t\tconsole.log(chalk.dim(`Falling back to: ${initialModel.provider}/${initialModel.id}`));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// CLI --thinking flag takes highest priority\n\tif (parsed.thinking) {\n\t\tinitialThinking = parsed.thinking;\n\t}\n\n\t// Create agent (initialModel can be null in interactive mode)\n\tconst agent = new Agent({\n\t\tinitialState: {\n\t\t\tsystemPrompt,\n\t\t\tmodel: initialModel as any, // Can be null\n\t\t\tthinkingLevel: initialThinking,\n\t\t\ttools: codingTools,\n\t\t},\n\t\tqueueMode: settingsManager.getQueueMode(),\n\t\ttransport: new ProviderTransport({\n\t\t\t// Dynamic API key lookup based on current model's provider\n\t\t\tgetApiKey: async () => {\n\t\t\t\tconst currentModel = agent.state.model;\n\t\t\t\tif (!currentModel) {\n\t\t\t\t\tthrow new Error(\"No model selected\");\n\t\t\t\t}\n\n\t\t\t\t// Try CLI override first\n\t\t\t\tif (parsed.apiKey) {\n\t\t\t\t\treturn parsed.apiKey;\n\t\t\t\t}\n\n\t\t\t\t// Use model-specific key lookup\n\t\t\t\tconst key = await getApiKeyForModel(currentModel);\n\t\t\t\tif (!key) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`No API key found for provider \"${currentModel.provider}\". Please set the appropriate environment variable or update ~/.pi/agent/models.json`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn key;\n\t\t\t},\n\t\t}),\n\t});\n\n\t// If initial thinking was requested but model doesn't support it, silently reset to off\n\tif (initialThinking !== \"off\" && initialModel && !initialModel.reasoning) {\n\t\tagent.setThinkingLevel(\"off\");\n\t}\n\n\t// Track if we had to fall back from saved model (to show in chat later)\n\tlet modelFallbackMessage: string | null = null;\n\n\t// Load previous messages if continuing or resuming\n\tif (parsed.continue || parsed.resume) {\n\t\tconst messages = sessionManager.loadMessages();\n\t\tif (messages.length > 0) {\n\t\t\tagent.replaceMessages(messages);\n\t\t}\n\n\t\t// Load and restore thinking level\n\t\tconst thinkingLevel = sessionManager.loadThinkingLevel() as ThinkingLevel;\n\t\tif (thinkingLevel) {\n\t\t\tagent.setThinkingLevel(thinkingLevel);\n\t\t\tif (shouldPrintMessages) {\n\t\t\t\tconsole.log(chalk.dim(`Restored thinking level: ${thinkingLevel}`));\n\t\t\t}\n\t\t}\n\n\t\t// Check if we had to fall back from saved model\n\t\tconst savedModel = sessionManager.loadModel();\n\t\tif (savedModel && initialModel) {\n\t\t\tconst savedMatches = initialModel.provider === savedModel.provider && initialModel.id === savedModel.modelId;\n\t\t\tif (!savedMatches) {\n\t\t\t\tconst { model: restoredModel, error } = findModel(savedModel.provider, savedModel.modelId);\n\t\t\t\tif (error) {\n\t\t\t\t\t// Config error - already shown above, just use generic message\n\t\t\t\t\tmodelFallbackMessage = `Could not restore model ${savedModel.provider}/${savedModel.modelId}. Using ${initialModel.provider}/${initialModel.id}.`;\n\t\t\t\t} else {\n\t\t\t\t\tconst reason = !restoredModel ? \"model no longer exists\" : \"no API key available\";\n\t\t\t\t\tmodelFallbackMessage = `Could not restore model ${savedModel.provider}/${savedModel.modelId} (${reason}). Using ${initialModel.provider}/${initialModel.id}.`;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Log loaded context files (they're already in the system prompt)\n\tif (shouldPrintMessages && !parsed.continue && !parsed.resume) {\n\t\tconst contextFiles = loadProjectContextFiles();\n\t\tif (contextFiles.length > 0) {\n\t\t\tconsole.log(chalk.dim(\"Loaded project context from:\"));\n\t\t\tfor (const { path: filePath } of contextFiles) {\n\t\t\t\tconsole.log(chalk.dim(` - ${filePath}`));\n\t\t\t}\n\t\t}\n\t}\n\n\t// Route to appropriate mode\n\tif (mode === \"rpc\") {\n\t\t// RPC mode - headless operation\n\t\tawait runRpcMode(agent, sessionManager);\n\t} else if (isInteractive) {\n\t\t// Check for new version (don't block startup if it takes too long)\n\t\tlet newVersion: string | null = null;\n\t\ttry {\n\t\t\tnewVersion = await Promise.race([\n\t\t\t\tcheckForNewVersion(VERSION),\n\t\t\t\tnew Promise<null>((resolve) => setTimeout(() => resolve(null), 1000)), // 1 second timeout\n\t\t\t]);\n\t\t} catch (e) {\n\t\t\t// Ignore errors\n\t\t}\n\n\t\t// Check if we should show changelog (only in interactive mode, only for new sessions)\n\t\tlet changelogMarkdown: string | null = null;\n\t\tif (!parsed.continue && !parsed.resume) {\n\t\t\tconst lastVersion = settingsManager.getLastChangelogVersion();\n\n\t\t\t// Check if we need to show changelog\n\t\t\tif (!lastVersion) {\n\t\t\t\t// First run - show all entries\n\t\t\t\tconst changelogPath = getChangelogPath();\n\t\t\t\tconst entries = parseChangelog(changelogPath);\n\t\t\t\tif (entries.length > 0) {\n\t\t\t\t\tchangelogMarkdown = entries.map((e) => e.content).join(\"\\n\\n\");\n\t\t\t\t\tsettingsManager.setLastChangelogVersion(VERSION);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Parse current and last versions\n\t\t\t\tconst changelogPath = getChangelogPath();\n\t\t\t\tconst entries = parseChangelog(changelogPath);\n\t\t\t\tconst newEntries = getNewEntries(entries, lastVersion);\n\n\t\t\t\tif (newEntries.length > 0) {\n\t\t\t\t\tchangelogMarkdown = newEntries.map((e) => e.content).join(\"\\n\\n\");\n\t\t\t\t\tsettingsManager.setLastChangelogVersion(VERSION);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Show model scope if provided\n\t\tif (scopedModels.length > 0) {\n\t\t\tconst modelList = scopedModels\n\t\t\t\t.map((sm) => {\n\t\t\t\t\tconst thinkingStr = sm.thinkingLevel !== \"off\" ? `:${sm.thinkingLevel}` : \"\";\n\t\t\t\t\treturn `${sm.model.id}${thinkingStr}`;\n\t\t\t\t})\n\t\t\t\t.join(\", \");\n\t\t\tconsole.log(chalk.dim(`Model scope: ${modelList} ${chalk.gray(\"(Ctrl+P to cycle)\")}`));\n\t\t}\n\n\t\t// Interactive mode - use TUI (may have initial messages from CLI args)\n\t\tawait runInteractiveMode(\n\t\t\tagent,\n\t\t\tsessionManager,\n\t\t\tsettingsManager,\n\t\t\tVERSION,\n\t\t\tchangelogMarkdown,\n\t\t\tmodelFallbackMessage,\n\t\t\tnewVersion,\n\t\t\tscopedModels,\n\t\t\tparsed.messages,\n\t\t\tinitialMessage,\n\t\t\tinitialAttachments,\n\t\t);\n\t} else {\n\t\t// Non-interactive mode (--print flag or --mode flag)\n\t\tawait runSingleShotMode(agent, sessionManager, parsed.messages, mode, initialMessage, initialAttachments);\n\t}\n}\n"]}
|
package/dist/tools/edit.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../src/tools/edit.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../src/tools/edit.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAmHrD,QAAA,MAAM,UAAU;;;;EAId,CAAC;AAEH,eAAO,MAAM,QAAQ,EAAE,SAAS,CAAC,OAAO,UAAU,CAmJjD,CAAC","sourcesContent":["import * as os from \"node:os\";\nimport type { AgentTool } from \"@mariozechner/pi-ai\";\nimport { Type } from \"@sinclair/typebox\";\nimport * as Diff from \"diff\";\nimport { constants } from \"fs\";\nimport { access, readFile, writeFile } from \"fs/promises\";\nimport { resolve as resolvePath } from \"path\";\n\n/**\n * Expand ~ to home directory\n */\nfunction expandPath(filePath: string): string {\n\tif (filePath === \"~\") {\n\t\treturn os.homedir();\n\t}\n\tif (filePath.startsWith(\"~/\")) {\n\t\treturn os.homedir() + filePath.slice(1);\n\t}\n\treturn filePath;\n}\n\n/**\n * Generate a unified diff string with line numbers and context\n */\nfunction generateDiffString(oldContent: string, newContent: string, contextLines = 4): string {\n\tconst parts = Diff.diffLines(oldContent, newContent);\n\tconst output: string[] = [];\n\n\tconst oldLines = oldContent.split(\"\\n\");\n\tconst newLines = newContent.split(\"\\n\");\n\tconst maxLineNum = Math.max(oldLines.length, newLines.length);\n\tconst lineNumWidth = String(maxLineNum).length;\n\n\tlet oldLineNum = 1;\n\tlet newLineNum = 1;\n\tlet lastWasChange = false;\n\n\tfor (let i = 0; i < parts.length; i++) {\n\t\tconst part = parts[i];\n\t\tconst raw = part.value.split(\"\\n\");\n\t\tif (raw[raw.length - 1] === \"\") {\n\t\t\traw.pop();\n\t\t}\n\n\t\tif (part.added || part.removed) {\n\t\t\t// Show the change\n\t\t\tfor (const line of raw) {\n\t\t\t\tif (part.added) {\n\t\t\t\t\tconst lineNum = String(newLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\toutput.push(`+${lineNum} ${line}`);\n\t\t\t\t\tnewLineNum++;\n\t\t\t\t} else {\n\t\t\t\t\t// removed\n\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\toutput.push(`-${lineNum} ${line}`);\n\t\t\t\t\toldLineNum++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tlastWasChange = true;\n\t\t} else {\n\t\t\t// Context lines - only show a few before/after changes\n\t\t\tconst nextPartIsChange = i < parts.length - 1 && (parts[i + 1].added || parts[i + 1].removed);\n\n\t\t\tif (lastWasChange || nextPartIsChange) {\n\t\t\t\t// Show context\n\t\t\t\tlet linesToShow = raw;\n\t\t\t\tlet skipStart = 0;\n\t\t\t\tlet skipEnd = 0;\n\n\t\t\t\tif (!lastWasChange) {\n\t\t\t\t\t// Show only last N lines as leading context\n\t\t\t\t\tskipStart = Math.max(0, raw.length - contextLines);\n\t\t\t\t\tlinesToShow = raw.slice(skipStart);\n\t\t\t\t}\n\n\t\t\t\tif (!nextPartIsChange && linesToShow.length > contextLines) {\n\t\t\t\t\t// Show only first N lines as trailing context\n\t\t\t\t\tskipEnd = linesToShow.length - contextLines;\n\t\t\t\t\tlinesToShow = linesToShow.slice(0, contextLines);\n\t\t\t\t}\n\n\t\t\t\t// Add ellipsis if we skipped lines at start\n\t\t\t\tif (skipStart > 0) {\n\t\t\t\t\toutput.push(` ${\"\".padStart(lineNumWidth, \" \")} ...`);\n\t\t\t\t\t// Update line numbers for the skipped leading context\n\t\t\t\t\toldLineNum += skipStart;\n\t\t\t\t\tnewLineNum += skipStart;\n\t\t\t\t}\n\n\t\t\t\tfor (const line of linesToShow) {\n\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\toutput.push(` ${lineNum} ${line}`);\n\t\t\t\t\toldLineNum++;\n\t\t\t\t\tnewLineNum++;\n\t\t\t\t}\n\n\t\t\t\t// Add ellipsis if we skipped lines at end\n\t\t\t\tif (skipEnd > 0) {\n\t\t\t\t\toutput.push(` ${\"\".padStart(lineNumWidth, \" \")} ...`);\n\t\t\t\t\t// Update line numbers for the skipped trailing context\n\t\t\t\t\toldLineNum += skipEnd;\n\t\t\t\t\tnewLineNum += skipEnd;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Skip these context lines entirely\n\t\t\t\toldLineNum += raw.length;\n\t\t\t\tnewLineNum += raw.length;\n\t\t\t}\n\n\t\t\tlastWasChange = false;\n\t\t}\n\t}\n\n\treturn output.join(\"\\n\");\n}\n\nconst editSchema = Type.Object({\n\tpath: Type.String({ description: \"Path to the file to edit (relative or absolute)\" }),\n\toldText: Type.String({ description: \"Exact text to find and replace (must match exactly)\" }),\n\tnewText: Type.String({ description: \"New text to replace the old text with\" }),\n});\n\nexport const editTool: AgentTool<typeof editSchema> = {\n\tname: \"edit\",\n\tlabel: \"edit\",\n\tdescription:\n\t\t\"Edit a file by replacing exact text. The oldText must match exactly (including whitespace). Use this for precise, surgical edits.\",\n\tparameters: editSchema,\n\texecute: async (\n\t\t_toolCallId: string,\n\t\t{ path, oldText, newText }: { path: string; oldText: string; newText: string },\n\t\tsignal?: AbortSignal,\n\t) => {\n\t\tconst absolutePath = resolvePath(expandPath(path));\n\n\t\treturn new Promise<{\n\t\t\tcontent: Array<{ type: \"text\"; text: string }>;\n\t\t\tdetails: { diff: string } | undefined;\n\t\t}>((resolve, reject) => {\n\t\t\t// Check if already aborted\n\t\t\tif (signal?.aborted) {\n\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlet aborted = false;\n\n\t\t\t// Set up abort handler\n\t\t\tconst onAbort = () => {\n\t\t\t\taborted = true;\n\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t};\n\n\t\t\tif (signal) {\n\t\t\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t}\n\n\t\t\t// Perform the edit operation\n\t\t\t(async () => {\n\t\t\t\ttry {\n\t\t\t\t\t// Check if file exists\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait access(absolutePath, constants.R_OK | constants.W_OK);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treject(new Error(`File not found: ${path}`));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Check if aborted before reading\n\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Read the file\n\t\t\t\t\tconst content = await readFile(absolutePath, \"utf-8\");\n\n\t\t\t\t\t// Check if aborted after reading\n\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Check if old text exists\n\t\t\t\t\tif (!content.includes(oldText)) {\n\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treject(\n\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t`Could not find the exact text in ${path}. The old text must match exactly including all whitespace and newlines.`,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Count occurrences\n\t\t\t\t\tconst occurrences = content.split(oldText).length - 1;\n\n\t\t\t\t\tif (occurrences > 1) {\n\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treject(\n\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t`Found ${occurrences} occurrences of the text in ${path}. The text must be unique. Please provide more context to make it unique.`,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Check if aborted before writing\n\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Perform replacement using indexOf + substring (raw string replace, no special character interpretation)\n\t\t\t\t\t// String.replace() interprets $ in the replacement string, so we do manual replacement\n\t\t\t\t\tconst index = content.indexOf(oldText);\n\t\t\t\t\tconst newContent = content.substring(0, index) + newText + content.substring(index + oldText.length);\n\n\t\t\t\t\t// Verify the replacement actually changed something\n\t\t\t\t\tif (content === newContent) {\n\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treject(\n\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t`No changes made to ${path}. The replacement produced identical content. This might indicate an issue with special characters or the text not existing as expected.`,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tawait writeFile(absolutePath, newContent, \"utf-8\");\n\n\t\t\t\t\t// Check if aborted after writing\n\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Clean up abort handler\n\t\t\t\t\tif (signal) {\n\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t}\n\n\t\t\t\t\tresolve({\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\ttext: `Successfully replaced text in ${path}. Changed ${oldText.length} characters to ${newText.length} characters.`,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t\tdetails: { diff: generateDiffString(content, newContent) },\n\t\t\t\t\t});\n\t\t\t\t} catch (error: any) {\n\t\t\t\t\t// Clean up abort handler\n\t\t\t\t\tif (signal) {\n\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!aborted) {\n\t\t\t\t\t\treject(error);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})();\n\t\t});\n\t},\n};\n"]}
|
package/dist/tools/edit.js
CHANGED
|
@@ -73,6 +73,9 @@ function generateDiffString(oldContent, newContent, contextLines = 4) {
|
|
|
73
73
|
// Add ellipsis if we skipped lines at start
|
|
74
74
|
if (skipStart > 0) {
|
|
75
75
|
output.push(` ${"".padStart(lineNumWidth, " ")} ...`);
|
|
76
|
+
// Update line numbers for the skipped leading context
|
|
77
|
+
oldLineNum += skipStart;
|
|
78
|
+
newLineNum += skipStart;
|
|
76
79
|
}
|
|
77
80
|
for (const line of linesToShow) {
|
|
78
81
|
const lineNum = String(oldLineNum).padStart(lineNumWidth, " ");
|
|
@@ -83,10 +86,10 @@ function generateDiffString(oldContent, newContent, contextLines = 4) {
|
|
|
83
86
|
// Add ellipsis if we skipped lines at end
|
|
84
87
|
if (skipEnd > 0) {
|
|
85
88
|
output.push(` ${"".padStart(lineNumWidth, " ")} ...`);
|
|
89
|
+
// Update line numbers for the skipped trailing context
|
|
90
|
+
oldLineNum += skipEnd;
|
|
91
|
+
newLineNum += skipEnd;
|
|
86
92
|
}
|
|
87
|
-
// Update line numbers for skipped lines
|
|
88
|
-
oldLineNum += skipStart + skipEnd;
|
|
89
|
-
newLineNum += skipStart + skipEnd;
|
|
90
93
|
}
|
|
91
94
|
else {
|
|
92
95
|
// Skip these context lines entirely
|