edge-pi-cli 0.1.3 → 0.1.4
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/dist/cli/args.d.ts +2 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +3 -1
- package/dist/main.js.map +1 -1
- package/dist/model-factory.d.ts.map +1 -1
- package/dist/model-factory.js +28 -1
- package/dist/model-factory.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +3 -5
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/provider-options.d.ts +3 -0
- package/dist/provider-options.d.ts.map +1 -0
- package/dist/provider-options.js +27 -0
- package/dist/provider-options.js.map +1 -0
- package/dist/utils/format-ai-error.d.ts +2 -0
- package/dist/utils/format-ai-error.d.ts.map +1 -0
- package/dist/utils/format-ai-error.js +64 -0
- package/dist/utils/format-ai-error.js.map +1 -0
- package/package.json +2 -2
package/dist/cli/args.d.ts
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Simplified from the original CLI - no RPC, no extensions.
|
|
5
5
|
*/
|
|
6
|
-
import type { ThinkingLevel } from "edge-pi";
|
|
7
6
|
export type Mode = "text" | "json";
|
|
7
|
+
type ThinkingLevel = "off" | "minimal" | "low" | "medium" | "high";
|
|
8
8
|
export interface Args {
|
|
9
9
|
provider?: string;
|
|
10
10
|
model?: string;
|
|
@@ -32,4 +32,5 @@ export interface Args {
|
|
|
32
32
|
export declare function parseArgs(args: string[]): Args;
|
|
33
33
|
export declare function printHelp(): void;
|
|
34
34
|
export declare function printModels(): void;
|
|
35
|
+
export {};
|
|
35
36
|
//# sourceMappingURL=args.d.ts.map
|
package/dist/cli/args.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,MAAM,MAAM,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;AACnC,KAAK,aAAa,GAAG,KAAK,GAAG,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAInE,MAAM,WAAW,IAAI;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,QAAQ,GAAG,UAAU,GAAG,KAAK,CAAC;IACxC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA2E9C;AAED,wBAAgB,SAAS,IAAI,IAAI,CAoEhC;AAED,wBAAgB,WAAW,IAAI,IAAI,CAuBlC","sourcesContent":["/**\n * CLI argument parsing for edge-pi-cli.\n *\n * Simplified from the original CLI - no RPC, no extensions.\n */\n\nimport chalk from \"chalk\";\nimport { getLatestModels, listProviders } from \"../model-factory.js\";\n\nexport type Mode = \"text\" | \"json\";\ntype ThinkingLevel = \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\";\n\nconst VALID_THINKING_LEVELS = new Set([\"off\", \"minimal\", \"low\", \"medium\", \"high\"]);\n\nexport interface Args {\n\tprovider?: string;\n\tmodel?: string;\n\tapiKey?: string;\n\tsystemPrompt?: string;\n\tappendSystemPrompt?: string;\n\tthinking?: ThinkingLevel;\n\tcontinue?: boolean;\n\tresume?: boolean;\n\thelp?: boolean;\n\tversion?: boolean;\n\tlistModels?: boolean;\n\tmode?: Mode;\n\tnoSession?: boolean;\n\tsession?: string;\n\tsessionDir?: string;\n\ttoolSet?: \"coding\" | \"readonly\" | \"all\";\n\tnoSkills?: boolean;\n\tskills?: string[];\n\tprint?: boolean;\n\tverbose?: boolean;\n\tmessages: string[];\n\tfileArgs: string[];\n}\n\nexport function 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 === \"--version\" || arg === \"-v\") {\n\t\t\tresult.version = true;\n\t\t} else if (arg === \"--list-models\") {\n\t\t\tresult.listModels = 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\") {\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 === \"--append-system-prompt\" && i + 1 < args.length) {\n\t\t\tresult.appendSystemPrompt = 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 === \"--session-dir\" && i + 1 < args.length) {\n\t\t\tresult.sessionDir = args[++i];\n\t\t} else if (arg === \"--tools\" && i + 1 < args.length) {\n\t\t\tconst toolSet = args[++i];\n\t\t\tif (toolSet === \"coding\" || toolSet === \"readonly\" || toolSet === \"all\") {\n\t\t\t\tresult.toolSet = toolSet;\n\t\t\t} else {\n\t\t\t\tconsole.error(chalk.yellow(`Warning: Invalid tool set \"${toolSet}\". Valid values: coding, readonly, all`));\n\t\t\t}\n\t\t} else if (arg === \"--thinking\" && i + 1 < args.length) {\n\t\t\tconst level = args[++i];\n\t\t\tif (VALID_THINKING_LEVELS.has(level)) {\n\t\t\t\tresult.thinking = level as ThinkingLevel;\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: ${[...VALID_THINKING_LEVELS].join(\", \")}`,\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 === \"--skill\" && i + 1 < args.length) {\n\t\t\tresult.skills = result.skills ?? [];\n\t\t\tresult.skills.push(args[++i]);\n\t\t} else if (arg === \"--no-skills\") {\n\t\t\tresult.noSkills = true;\n\t\t} else if (arg === \"--verbose\") {\n\t\t\tresult.verbose = true;\n\t\t} else if (arg.startsWith(\"@\")) {\n\t\t\tresult.fileArgs.push(arg.slice(1));\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\nexport function printHelp(): void {\n\tconsole.log(`${chalk.bold(\"epi\")} - CLI for the edge-pi coding agent SDK\n\n${chalk.bold(\"Usage:\")}\n epi [options] [@files...] [messages...]\n\n${chalk.bold(\"Options:\")}\n --provider <name> Provider name (${listProviders().join(\", \")})\n --model <id> Model ID (auto-detected from provider)\n --api-key <key> API key (defaults to env vars)\n --system-prompt <text> Override the system prompt\n --append-system-prompt <text> Append text to the system prompt\n --mode <mode> Output mode: text (default) or json\n --print, -p Non-interactive mode: process prompt and exit\n --continue, -c Continue previous session\n --resume, -r Select and resume a previous session\n --session <path> Use specific session file\n --session-dir <dir> Directory for session storage\n --no-session Don't save session (ephemeral)\n --tools <set> Tool set: coding (default), readonly, or all\n --thinking <level> Thinking level: off, minimal, low, medium, high\n --skill <path> Load a skill file or directory (repeatable)\n --no-skills Disable skill discovery and loading\n --verbose Verbose output\n --list-models List latest supported models\n --help, -h Show this help\n --version, -v Show version number\n\n${chalk.bold(\"Examples:\")}\n # Interactive mode\n epi\n\n # Interactive mode with initial prompt\n epi \"List all .ts files in src/\"\n\n # Include files in initial message\n epi @prompt.md \"Refactor this\"\n\n # Non-interactive mode (process and exit)\n epi -p \"List all .ts files in src/\"\n\n # Continue previous session\n epi --continue \"What did we discuss?\"\n\n # Resume a previous session (interactive picker)\n epi --resume\n\n # Use specific latest models\n epi --provider anthropic --model claude-opus-4-6\n epi --provider openai --model gpt-5.3\n epi --provider openai-codex --model gpt-5.3-codex\n epi --provider google --model gemini-3-flash\n epi --provider github-copilot --model claude-sonnet-4.5\n\n # Read-only tools\n epi --tools readonly -p \"Review the code in src/\"\n\n${chalk.bold(\"Environment Variables:\")}\n ANTHROPIC_API_KEY Anthropic Claude API key\n OPENAI_API_KEY OpenAI GPT API key\n GEMINI_API_KEY Google Gemini API key\n COPILOT_GITHUB_TOKEN GitHub Copilot token (or GH_TOKEN / GITHUB_TOKEN)\n\n${chalk.bold(\"Tool Sets:\")}\n coding read, bash, edit, write (default)\n readonly read, grep, find, ls\n all read, bash, edit, write, grep, find, ls\n`);\n}\n\nexport function printModels(): void {\n\tconst latestModels = getLatestModels();\n\n\tconsole.log(`${chalk.bold(\"Latest Supported Models:\")}\\n`);\n\n\tfor (const [provider, models] of Object.entries(latestModels)) {\n\t\tconsole.log(`${chalk.bold(provider.toUpperCase())}:`);\n\t\tfor (const model of models) {\n\t\t\tconsole.log(` ${model}`);\n\t\t}\n\t\tconsole.log();\n\t}\n\n\tconsole.log(`${chalk.bold(\"Usage:\")}\n epi --provider <provider> --model <model> [message...]\n\n${chalk.bold(\"Examples:\")}\n epi --provider anthropic --model claude-opus-4-6 \"Hello\"\n epi --provider openai --model gpt-5.3 \"Hello\"\n epi --provider openai-codex --model gpt-5.3-codex \"Hello\"\n epi --provider google --model gemini-3-flash \"Hello\"\n epi --provider github-copilot --model claude-sonnet-4.5 \"Hello\"\n`);\n}\n"]}
|
package/dist/cli/args.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * CLI argument parsing for edge-pi-cli.\n *\n * Simplified from the original CLI - no RPC, no extensions.\n */\n\nimport chalk from \"chalk\";\nimport type { ThinkingLevel } from \"edge-pi\";\nimport { getLatestModels, listProviders } from \"../model-factory.js\";\n\nexport type Mode = \"text\" | \"json\";\n\nconst VALID_THINKING_LEVELS = new Set([\"off\", \"minimal\", \"low\", \"medium\", \"high\"]);\n\nexport interface Args {\n\tprovider?: string;\n\tmodel?: string;\n\tapiKey?: string;\n\tsystemPrompt?: string;\n\tappendSystemPrompt?: string;\n\tthinking?: ThinkingLevel;\n\tcontinue?: boolean;\n\tresume?: boolean;\n\thelp?: boolean;\n\tversion?: boolean;\n\tlistModels?: boolean;\n\tmode?: Mode;\n\tnoSession?: boolean;\n\tsession?: string;\n\tsessionDir?: string;\n\ttoolSet?: \"coding\" | \"readonly\" | \"all\";\n\tnoSkills?: boolean;\n\tskills?: string[];\n\tprint?: boolean;\n\tverbose?: boolean;\n\tmessages: string[];\n\tfileArgs: string[];\n}\n\nexport function 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 === \"--version\" || arg === \"-v\") {\n\t\t\tresult.version = true;\n\t\t} else if (arg === \"--list-models\") {\n\t\t\tresult.listModels = 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\") {\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 === \"--append-system-prompt\" && i + 1 < args.length) {\n\t\t\tresult.appendSystemPrompt = 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 === \"--session-dir\" && i + 1 < args.length) {\n\t\t\tresult.sessionDir = args[++i];\n\t\t} else if (arg === \"--tools\" && i + 1 < args.length) {\n\t\t\tconst toolSet = args[++i];\n\t\t\tif (toolSet === \"coding\" || toolSet === \"readonly\" || toolSet === \"all\") {\n\t\t\t\tresult.toolSet = toolSet;\n\t\t\t} else {\n\t\t\t\tconsole.error(chalk.yellow(`Warning: Invalid tool set \"${toolSet}\". Valid values: coding, readonly, all`));\n\t\t\t}\n\t\t} else if (arg === \"--thinking\" && i + 1 < args.length) {\n\t\t\tconst level = args[++i];\n\t\t\tif (VALID_THINKING_LEVELS.has(level)) {\n\t\t\t\tresult.thinking = level as ThinkingLevel;\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: ${[...VALID_THINKING_LEVELS].join(\", \")}`,\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 === \"--skill\" && i + 1 < args.length) {\n\t\t\tresult.skills = result.skills ?? [];\n\t\t\tresult.skills.push(args[++i]);\n\t\t} else if (arg === \"--no-skills\") {\n\t\t\tresult.noSkills = true;\n\t\t} else if (arg === \"--verbose\") {\n\t\t\tresult.verbose = true;\n\t\t} else if (arg.startsWith(\"@\")) {\n\t\t\tresult.fileArgs.push(arg.slice(1));\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\nexport function printHelp(): void {\n\tconsole.log(`${chalk.bold(\"epi\")} - CLI for the edge-pi coding agent SDK\n\n${chalk.bold(\"Usage:\")}\n epi [options] [@files...] [messages...]\n\n${chalk.bold(\"Options:\")}\n --provider <name> Provider name (${listProviders().join(\", \")})\n --model <id> Model ID (auto-detected from provider)\n --api-key <key> API key (defaults to env vars)\n --system-prompt <text> Override the system prompt\n --append-system-prompt <text> Append text to the system prompt\n --mode <mode> Output mode: text (default) or json\n --print, -p Non-interactive mode: process prompt and exit\n --continue, -c Continue previous session\n --resume, -r Select and resume a previous session\n --session <path> Use specific session file\n --session-dir <dir> Directory for session storage\n --no-session Don't save session (ephemeral)\n --tools <set> Tool set: coding (default), readonly, or all\n --thinking <level> Thinking level: off, minimal, low, medium, high\n --skill <path> Load a skill file or directory (repeatable)\n --no-skills Disable skill discovery and loading\n --verbose Verbose output\n --list-models List latest supported models\n --help, -h Show this help\n --version, -v Show version number\n\n${chalk.bold(\"Examples:\")}\n # Interactive mode\n epi\n\n # Interactive mode with initial prompt\n epi \"List all .ts files in src/\"\n\n # Include files in initial message\n epi @prompt.md \"Refactor this\"\n\n # Non-interactive mode (process and exit)\n epi -p \"List all .ts files in src/\"\n\n # Continue previous session\n epi --continue \"What did we discuss?\"\n\n # Resume a previous session (interactive picker)\n epi --resume\n\n # Use specific latest models\n epi --provider anthropic --model claude-opus-4-6\n epi --provider openai --model gpt-5.3\n epi --provider openai-codex --model gpt-5.3-codex\n epi --provider google --model gemini-3-flash\n epi --provider github-copilot --model claude-sonnet-4.5\n\n # Read-only tools\n epi --tools readonly -p \"Review the code in src/\"\n\n${chalk.bold(\"Environment Variables:\")}\n ANTHROPIC_API_KEY Anthropic Claude API key\n OPENAI_API_KEY OpenAI GPT API key\n GEMINI_API_KEY Google Gemini API key\n COPILOT_GITHUB_TOKEN GitHub Copilot token (or GH_TOKEN / GITHUB_TOKEN)\n\n${chalk.bold(\"Tool Sets:\")}\n coding read, bash, edit, write (default)\n readonly read, grep, find, ls\n all read, bash, edit, write, grep, find, ls\n`);\n}\n\nexport function printModels(): void {\n\tconst latestModels = getLatestModels();\n\n\tconsole.log(`${chalk.bold(\"Latest Supported Models:\")}\\n`);\n\n\tfor (const [provider, models] of Object.entries(latestModels)) {\n\t\tconsole.log(`${chalk.bold(provider.toUpperCase())}:`);\n\t\tfor (const model of models) {\n\t\t\tconsole.log(` ${model}`);\n\t\t}\n\t\tconsole.log();\n\t}\n\n\tconsole.log(`${chalk.bold(\"Usage:\")}\n epi --provider <provider> --model <model> [message...]\n\n${chalk.bold(\"Examples:\")}\n epi --provider anthropic --model claude-opus-4-6 \"Hello\"\n epi --provider openai --model gpt-5.3 \"Hello\"\n epi --provider openai-codex --model gpt-5.3-codex \"Hello\"\n epi --provider google --model gemini-3-flash \"Hello\"\n epi --provider github-copilot --model claude-sonnet-4.5 \"Hello\"\n`);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * CLI argument parsing for edge-pi-cli.\n *\n * Simplified from the original CLI - no RPC, no extensions.\n */\n\nimport chalk from \"chalk\";\nimport { getLatestModels, listProviders } from \"../model-factory.js\";\n\nexport type Mode = \"text\" | \"json\";\ntype ThinkingLevel = \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\";\n\nconst VALID_THINKING_LEVELS = new Set([\"off\", \"minimal\", \"low\", \"medium\", \"high\"]);\n\nexport interface Args {\n\tprovider?: string;\n\tmodel?: string;\n\tapiKey?: string;\n\tsystemPrompt?: string;\n\tappendSystemPrompt?: string;\n\tthinking?: ThinkingLevel;\n\tcontinue?: boolean;\n\tresume?: boolean;\n\thelp?: boolean;\n\tversion?: boolean;\n\tlistModels?: boolean;\n\tmode?: Mode;\n\tnoSession?: boolean;\n\tsession?: string;\n\tsessionDir?: string;\n\ttoolSet?: \"coding\" | \"readonly\" | \"all\";\n\tnoSkills?: boolean;\n\tskills?: string[];\n\tprint?: boolean;\n\tverbose?: boolean;\n\tmessages: string[];\n\tfileArgs: string[];\n}\n\nexport function 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 === \"--version\" || arg === \"-v\") {\n\t\t\tresult.version = true;\n\t\t} else if (arg === \"--list-models\") {\n\t\t\tresult.listModels = 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\") {\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 === \"--append-system-prompt\" && i + 1 < args.length) {\n\t\t\tresult.appendSystemPrompt = 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 === \"--session-dir\" && i + 1 < args.length) {\n\t\t\tresult.sessionDir = args[++i];\n\t\t} else if (arg === \"--tools\" && i + 1 < args.length) {\n\t\t\tconst toolSet = args[++i];\n\t\t\tif (toolSet === \"coding\" || toolSet === \"readonly\" || toolSet === \"all\") {\n\t\t\t\tresult.toolSet = toolSet;\n\t\t\t} else {\n\t\t\t\tconsole.error(chalk.yellow(`Warning: Invalid tool set \"${toolSet}\". Valid values: coding, readonly, all`));\n\t\t\t}\n\t\t} else if (arg === \"--thinking\" && i + 1 < args.length) {\n\t\t\tconst level = args[++i];\n\t\t\tif (VALID_THINKING_LEVELS.has(level)) {\n\t\t\t\tresult.thinking = level as ThinkingLevel;\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: ${[...VALID_THINKING_LEVELS].join(\", \")}`,\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 === \"--skill\" && i + 1 < args.length) {\n\t\t\tresult.skills = result.skills ?? [];\n\t\t\tresult.skills.push(args[++i]);\n\t\t} else if (arg === \"--no-skills\") {\n\t\t\tresult.noSkills = true;\n\t\t} else if (arg === \"--verbose\") {\n\t\t\tresult.verbose = true;\n\t\t} else if (arg.startsWith(\"@\")) {\n\t\t\tresult.fileArgs.push(arg.slice(1));\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\nexport function printHelp(): void {\n\tconsole.log(`${chalk.bold(\"epi\")} - CLI for the edge-pi coding agent SDK\n\n${chalk.bold(\"Usage:\")}\n epi [options] [@files...] [messages...]\n\n${chalk.bold(\"Options:\")}\n --provider <name> Provider name (${listProviders().join(\", \")})\n --model <id> Model ID (auto-detected from provider)\n --api-key <key> API key (defaults to env vars)\n --system-prompt <text> Override the system prompt\n --append-system-prompt <text> Append text to the system prompt\n --mode <mode> Output mode: text (default) or json\n --print, -p Non-interactive mode: process prompt and exit\n --continue, -c Continue previous session\n --resume, -r Select and resume a previous session\n --session <path> Use specific session file\n --session-dir <dir> Directory for session storage\n --no-session Don't save session (ephemeral)\n --tools <set> Tool set: coding (default), readonly, or all\n --thinking <level> Thinking level: off, minimal, low, medium, high\n --skill <path> Load a skill file or directory (repeatable)\n --no-skills Disable skill discovery and loading\n --verbose Verbose output\n --list-models List latest supported models\n --help, -h Show this help\n --version, -v Show version number\n\n${chalk.bold(\"Examples:\")}\n # Interactive mode\n epi\n\n # Interactive mode with initial prompt\n epi \"List all .ts files in src/\"\n\n # Include files in initial message\n epi @prompt.md \"Refactor this\"\n\n # Non-interactive mode (process and exit)\n epi -p \"List all .ts files in src/\"\n\n # Continue previous session\n epi --continue \"What did we discuss?\"\n\n # Resume a previous session (interactive picker)\n epi --resume\n\n # Use specific latest models\n epi --provider anthropic --model claude-opus-4-6\n epi --provider openai --model gpt-5.3\n epi --provider openai-codex --model gpt-5.3-codex\n epi --provider google --model gemini-3-flash\n epi --provider github-copilot --model claude-sonnet-4.5\n\n # Read-only tools\n epi --tools readonly -p \"Review the code in src/\"\n\n${chalk.bold(\"Environment Variables:\")}\n ANTHROPIC_API_KEY Anthropic Claude API key\n OPENAI_API_KEY OpenAI GPT API key\n GEMINI_API_KEY Google Gemini API key\n COPILOT_GITHUB_TOKEN GitHub Copilot token (or GH_TOKEN / GITHUB_TOKEN)\n\n${chalk.bold(\"Tool Sets:\")}\n coding read, bash, edit, write (default)\n readonly read, grep, find, ls\n all read, bash, edit, write, grep, find, ls\n`);\n}\n\nexport function printModels(): void {\n\tconst latestModels = getLatestModels();\n\n\tconsole.log(`${chalk.bold(\"Latest Supported Models:\")}\\n`);\n\n\tfor (const [provider, models] of Object.entries(latestModels)) {\n\t\tconsole.log(`${chalk.bold(provider.toUpperCase())}:`);\n\t\tfor (const model of models) {\n\t\t\tconsole.log(` ${model}`);\n\t\t}\n\t\tconsole.log();\n\t}\n\n\tconsole.log(`${chalk.bold(\"Usage:\")}\n epi --provider <provider> --model <model> [message...]\n\n${chalk.bold(\"Examples:\")}\n epi --provider anthropic --model claude-opus-4-6 \"Hello\"\n epi --provider openai --model gpt-5.3 \"Hello\"\n epi --provider openai-codex --model gpt-5.3-codex \"Hello\"\n epi --provider google --model gemini-3-flash \"Hello\"\n epi --provider github-copilot --model claude-sonnet-4.5 \"Hello\"\n`);\n}\n"]}
|
package/dist/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA8HH,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,iBAmMxC","sourcesContent":["/**\n * Main entry point for the edge-pi CLI.\n *\n * Handles argument parsing, model creation, skill loading,\n * session management, auth, and mode dispatch.\n */\n\nimport { existsSync, readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport chalk from \"chalk\";\nimport type { CodingAgentConfig } from \"edge-pi\";\nimport { CodingAgent, SessionManager } from \"edge-pi\";\nimport {\n\tAuthStorage,\n\tanthropicOAuthProvider,\n\tgithubCopilotOAuthProvider,\n\topenaiCodexOAuthProvider,\n} from \"./auth/index.js\";\nimport { parseArgs, printHelp, printModels } from \"./cli/args.js\";\nimport { loadContextFiles } from \"./context.js\";\nimport { createModel } from \"./model-factory.js\";\nimport { runInteractiveMode } from \"./modes/interactive-mode.js\";\nimport { runPrintMode } from \"./modes/print-mode.js\";\nimport { loadPrompts } from \"./prompts.js\";\nimport { SettingsManager } from \"./settings.js\";\nimport { formatSkillsForPrompt, loadSkills, type Skill } from \"./skills.js\";\nimport { findFd } from \"./utils/find-fd.js\";\n\nconst VERSION = \"0.1.0\";\nconst CONFIG_DIR_NAME = \".pi\";\n\nfunction getAgentDir(): string {\n\tconst envDir = process.env.PI_CODING_AGENT_DIR;\n\tif (envDir) {\n\t\tif (envDir === \"~\") return homedir();\n\t\tif (envDir.startsWith(\"~/\")) return homedir() + envDir.slice(1);\n\t\treturn envDir;\n\t}\n\treturn join(homedir(), CONFIG_DIR_NAME, \"agent\");\n}\n\nfunction getSessionsDir(): string {\n\treturn join(getAgentDir(), \"sessions\");\n}\n\nfunction getAuthPath(): string {\n\treturn join(getAgentDir(), \"auth.json\");\n}\n\n/**\n * Read all content from piped stdin.\n * Returns undefined if stdin is a TTY.\n */\nasync function readPipedStdin(): Promise<string | undefined> {\n\tif (process.stdin.isTTY) {\n\t\treturn undefined;\n\t}\n\treturn new Promise((resolve) => {\n\t\tlet data = \"\";\n\t\tprocess.stdin.setEncoding(\"utf8\");\n\t\tprocess.stdin.on(\"data\", (chunk) => {\n\t\t\tdata += chunk;\n\t\t});\n\t\tprocess.stdin.on(\"end\", () => {\n\t\t\tresolve(data.trim() || undefined);\n\t\t});\n\t\tprocess.stdin.resume();\n\t});\n}\n\n/**\n * Process @file arguments into text content.\n */\nfunction processFileArgs(fileArgs: string[]): string {\n\tconst parts: string[] = [];\n\tfor (const filePath of fileArgs) {\n\t\tconst resolved = resolve(filePath);\n\t\tif (!existsSync(resolved)) {\n\t\t\tconsole.error(chalk.yellow(`Warning: File not found: ${resolved}`));\n\t\t\tcontinue;\n\t\t}\n\t\ttry {\n\t\t\tconst content = readFileSync(resolved, \"utf-8\");\n\t\t\tparts.push(`<file path=\"${resolved}\">\\n${content}\\n</file>`);\n\t\t} catch (error) {\n\t\t\tconsole.error(chalk.yellow(`Warning: Could not read ${resolved}: ${(error as Error).message}`));\n\t\t}\n\t}\n\treturn parts.length > 0 ? `${parts.join(\"\\n\\n\")}\\n\\n` : \"\";\n}\n\n/**\n * Create a session directory path based on the current working directory.\n */\nfunction getProjectSessionDir(cwd: string): string {\n\tconst sanitized = cwd.replace(/\\//g, \"--\").replace(/^--/, \"\");\n\treturn join(getSessionsDir(), sanitized);\n}\n\n/**\n * Find the most recent session file in a directory.\n */\nfunction findRecentSession(sessionDir: string): string | undefined {\n\tif (!existsSync(sessionDir)) return undefined;\n\ttry {\n\t\tconst files = readdirSync(sessionDir)\n\t\t\t.filter((f: string) => f.endsWith(\".jsonl\"))\n\t\t\t.map((f: string) => ({\n\t\t\t\tname: f,\n\t\t\t\tpath: join(sessionDir, f),\n\t\t\t\tmtime: statSync(join(sessionDir, f)).mtime.getTime(),\n\t\t\t}))\n\t\t\t.sort((a: { mtime: number }, b: { mtime: number }) => b.mtime - a.mtime);\n\t\treturn files[0]?.path;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * Create and configure AuthStorage with built-in OAuth providers.\n */\nfunction createAuthStorage(): AuthStorage {\n\tconst authStorage = new AuthStorage(getAuthPath());\n\tauthStorage.registerProvider(anthropicOAuthProvider);\n\tauthStorage.registerProvider(githubCopilotOAuthProvider);\n\tauthStorage.registerProvider(openaiCodexOAuthProvider);\n\treturn authStorage;\n}\n\nexport async function main(args: string[]) {\n\tconst parsed = parseArgs(args);\n\n\tif (parsed.version) {\n\t\tconsole.log(VERSION);\n\t\treturn;\n\t}\n\n\tif (parsed.help) {\n\t\tprintHelp();\n\t\treturn;\n\t}\n\n\tif (parsed.listModels) {\n\t\tprintModels();\n\t\treturn;\n\t}\n\n\t// Read piped stdin\n\tconst stdinContent = await readPipedStdin();\n\tif (stdinContent !== undefined) {\n\t\tparsed.print = true;\n\t\tparsed.messages.unshift(stdinContent);\n\t}\n\n\t// Process @file arguments\n\tlet initialMessage: string | undefined;\n\tif (parsed.fileArgs.length > 0) {\n\t\tconst fileContent = processFileArgs(parsed.fileArgs);\n\t\tif (parsed.messages.length > 0) {\n\t\t\tinitialMessage = fileContent + parsed.messages.shift();\n\t\t} else {\n\t\t\tinitialMessage = fileContent;\n\t\t}\n\t}\n\n\tconst cwd = process.cwd();\n\tconst isInteractive = !parsed.print && parsed.mode === undefined;\n\tconst mode = parsed.mode || \"text\";\n\n\t// Set up auth storage\n\tconst authStorage = createAuthStorage();\n\n\t// Set up settings persistence\n\tconst settingsManager = SettingsManager.create(getAgentDir());\n\n\t// Apply CLI --api-key override\n\tif (parsed.apiKey && parsed.provider) {\n\t\tauthStorage.setRuntimeApiKey(parsed.provider, parsed.apiKey);\n\t}\n\n\t// Create model (async - may resolve OAuth tokens)\n\t// Fall back to saved defaults when CLI args are not specified\n\tconst { model, provider, modelId } = await createModel({\n\t\tprovider: parsed.provider ?? settingsManager.getDefaultProvider(),\n\t\tmodel: parsed.model ?? settingsManager.getDefaultModel(),\n\t\tapiKey: parsed.apiKey,\n\t\tauthStorage,\n\t});\n\n\t// Load skills\n\tlet skills: Skill[] = [];\n\tif (!parsed.noSkills) {\n\t\tconst skillResult = loadSkills({\n\t\t\tcwd,\n\t\t\tskillPaths: parsed.skills,\n\t\t\tincludeDefaults: true,\n\t\t});\n\t\tskills = skillResult.skills;\n\n\t\tif (parsed.verbose && skillResult.diagnostics.length > 0) {\n\t\t\tfor (const d of skillResult.diagnostics) {\n\t\t\t\tconsole.error(chalk.yellow(`Skill warning: ${d.message} (${d.path})`));\n\t\t\t}\n\t\t}\n\t}\n\n\t// Load context files (AGENTS.md)\n\tconst contextFiles = loadContextFiles(cwd);\n\tif (parsed.verbose && contextFiles.length > 0) {\n\t\tconsole.log(chalk.dim(`Loaded ${contextFiles.length} context file(s).`));\n\t}\n\n\t// Load prompt templates\n\tconst promptsResult = loadPrompts({ cwd });\n\tconst prompts = promptsResult.prompts;\n\tif (parsed.verbose && promptsResult.diagnostics.length > 0) {\n\t\tfor (const d of promptsResult.diagnostics) {\n\t\t\tconsole.error(chalk.yellow(`Prompt warning: ${d.message} (${d.path})`));\n\t\t}\n\t}\n\n\t// Find fd binary for @ file autocomplete\n\tconst fdPath = findFd();\n\n\t// Build system prompt additions\n\tconst skillsPrompt = formatSkillsForPrompt(skills);\n\tconst appendParts: string[] = [];\n\tif (skillsPrompt) {\n\t\tappendParts.push(skillsPrompt);\n\t}\n\tif (parsed.appendSystemPrompt) {\n\t\tappendParts.push(parsed.appendSystemPrompt);\n\t}\n\tconst appendSystemPrompt = appendParts.length > 0 ? appendParts.join(\"\\n\\n\") : undefined;\n\n\t// Set up session manager\n\tconst sessionDir = parsed.sessionDir ?? getProjectSessionDir(cwd);\n\tlet sessionManager: SessionManager | undefined;\n\tif (parsed.noSession) {\n\t\tsessionManager = SessionManager.inMemory(cwd);\n\t} else if (parsed.session) {\n\t\tsessionManager = SessionManager.open(parsed.session, parsed.sessionDir);\n\t} else if (parsed.resume) {\n\t\t// Start a new session; the TUI will show the session picker on startup\n\t\tsessionManager = SessionManager.create(cwd, sessionDir);\n\t} else if (parsed.continue) {\n\t\tconst recentFile = findRecentSession(sessionDir);\n\t\tif (recentFile) {\n\t\t\tsessionManager = SessionManager.open(recentFile, sessionDir);\n\t\t} else {\n\t\t\tif (parsed.verbose) {\n\t\t\t\tconsole.log(chalk.dim(\"No previous session found, starting new.\"));\n\t\t\t}\n\t\t\tsessionManager = SessionManager.create(cwd, sessionDir);\n\t\t}\n\t} else {\n\t\tsessionManager = SessionManager.create(cwd, sessionDir);\n\t}\n\n\t// Create agent config\n\tconst agentConfig: CodingAgentConfig = {\n\t\tmodel,\n\t\tcwd,\n\t\ttoolSet: parsed.toolSet ?? \"coding\",\n\t\tthinkingLevel: parsed.thinking,\n\t\tsessionManager,\n\t};\n\n\tif (parsed.systemPrompt) {\n\t\tagentConfig.systemPrompt = parsed.systemPrompt;\n\t\tif (appendSystemPrompt) {\n\t\t\tagentConfig.systemPrompt += `\\n\\n${appendSystemPrompt}`;\n\t\t}\n\t} else {\n\t\tagentConfig.systemPromptOptions = {\n\t\t\tappendSystemPrompt,\n\t\t\tcontextFiles,\n\t\t};\n\t}\n\n\t// Create agent (session messages are auto-restored from sessionManager)\n\tconst agent = new CodingAgent(agentConfig);\n\n\tif (parsed.verbose && agent.messages.length > 0) {\n\t\tconsole.log(chalk.dim(`Restored ${agent.messages.length} messages from session.`));\n\t}\n\n\t// Dispatch to mode\n\tif (isInteractive) {\n\t\tawait runInteractiveMode(agent, {\n\t\t\tinitialMessage,\n\t\t\tinitialMessages: parsed.messages,\n\t\t\tsessionDir,\n\t\t\tagentConfig,\n\t\t\tresumeOnStart: parsed.resume,\n\t\t\tskills,\n\t\t\tcontextFiles,\n\t\t\tprompts,\n\t\t\tverbose: parsed.verbose,\n\t\t\tprovider,\n\t\t\tmodelId,\n\t\t\tauthStorage,\n\t\t\tsettingsManager,\n\t\t\tfdPath,\n\t\t\tonModelChange: async (newProvider: string, newModelId: string) => {\n\t\t\t\tconst { model: newModel } = await createModel({\n\t\t\t\t\tprovider: newProvider,\n\t\t\t\t\tmodel: newModelId,\n\t\t\t\t\tauthStorage,\n\t\t\t\t});\n\t\t\t\treturn new CodingAgent({\n\t\t\t\t\t...agentConfig,\n\t\t\t\t\tmodel: newModel,\n\t\t\t\t});\n\t\t\t},\n\t\t});\n\t} else {\n\t\tawait runPrintMode(agent, {\n\t\t\tmode,\n\t\t\tmessages: parsed.messages,\n\t\t\tinitialMessage,\n\t\t});\n\t\tprocess.exit(0);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA+HH,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,iBAoMxC","sourcesContent":["/**\n * Main entry point for the edge-pi CLI.\n *\n * Handles argument parsing, model creation, skill loading,\n * session management, auth, and mode dispatch.\n */\n\nimport { existsSync, readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport chalk from \"chalk\";\nimport type { CodingAgentConfig } from \"edge-pi\";\nimport { CodingAgent, SessionManager } from \"edge-pi\";\nimport {\n\tAuthStorage,\n\tanthropicOAuthProvider,\n\tgithubCopilotOAuthProvider,\n\topenaiCodexOAuthProvider,\n} from \"./auth/index.js\";\nimport { parseArgs, printHelp, printModels } from \"./cli/args.js\";\nimport { loadContextFiles } from \"./context.js\";\nimport { createModel } from \"./model-factory.js\";\nimport { runInteractiveMode } from \"./modes/interactive-mode.js\";\nimport { runPrintMode } from \"./modes/print-mode.js\";\nimport { loadPrompts } from \"./prompts.js\";\nimport { buildProviderOptions } from \"./provider-options.js\";\nimport { SettingsManager } from \"./settings.js\";\nimport { formatSkillsForPrompt, loadSkills, type Skill } from \"./skills.js\";\nimport { findFd } from \"./utils/find-fd.js\";\n\nconst VERSION = \"0.1.0\";\nconst CONFIG_DIR_NAME = \".pi\";\n\nfunction getAgentDir(): string {\n\tconst envDir = process.env.PI_CODING_AGENT_DIR;\n\tif (envDir) {\n\t\tif (envDir === \"~\") return homedir();\n\t\tif (envDir.startsWith(\"~/\")) return homedir() + envDir.slice(1);\n\t\treturn envDir;\n\t}\n\treturn join(homedir(), CONFIG_DIR_NAME, \"agent\");\n}\n\nfunction getSessionsDir(): string {\n\treturn join(getAgentDir(), \"sessions\");\n}\n\nfunction getAuthPath(): string {\n\treturn join(getAgentDir(), \"auth.json\");\n}\n\n/**\n * Read all content from piped stdin.\n * Returns undefined if stdin is a TTY.\n */\nasync function readPipedStdin(): Promise<string | undefined> {\n\tif (process.stdin.isTTY) {\n\t\treturn undefined;\n\t}\n\treturn new Promise((resolve) => {\n\t\tlet data = \"\";\n\t\tprocess.stdin.setEncoding(\"utf8\");\n\t\tprocess.stdin.on(\"data\", (chunk) => {\n\t\t\tdata += chunk;\n\t\t});\n\t\tprocess.stdin.on(\"end\", () => {\n\t\t\tresolve(data.trim() || undefined);\n\t\t});\n\t\tprocess.stdin.resume();\n\t});\n}\n\n/**\n * Process @file arguments into text content.\n */\nfunction processFileArgs(fileArgs: string[]): string {\n\tconst parts: string[] = [];\n\tfor (const filePath of fileArgs) {\n\t\tconst resolved = resolve(filePath);\n\t\tif (!existsSync(resolved)) {\n\t\t\tconsole.error(chalk.yellow(`Warning: File not found: ${resolved}`));\n\t\t\tcontinue;\n\t\t}\n\t\ttry {\n\t\t\tconst content = readFileSync(resolved, \"utf-8\");\n\t\t\tparts.push(`<file path=\"${resolved}\">\\n${content}\\n</file>`);\n\t\t} catch (error) {\n\t\t\tconsole.error(chalk.yellow(`Warning: Could not read ${resolved}: ${(error as Error).message}`));\n\t\t}\n\t}\n\treturn parts.length > 0 ? `${parts.join(\"\\n\\n\")}\\n\\n` : \"\";\n}\n\n/**\n * Create a session directory path based on the current working directory.\n */\nfunction getProjectSessionDir(cwd: string): string {\n\tconst sanitized = cwd.replace(/\\//g, \"--\").replace(/^--/, \"\");\n\treturn join(getSessionsDir(), sanitized);\n}\n\n/**\n * Find the most recent session file in a directory.\n */\nfunction findRecentSession(sessionDir: string): string | undefined {\n\tif (!existsSync(sessionDir)) return undefined;\n\ttry {\n\t\tconst files = readdirSync(sessionDir)\n\t\t\t.filter((f: string) => f.endsWith(\".jsonl\"))\n\t\t\t.map((f: string) => ({\n\t\t\t\tname: f,\n\t\t\t\tpath: join(sessionDir, f),\n\t\t\t\tmtime: statSync(join(sessionDir, f)).mtime.getTime(),\n\t\t\t}))\n\t\t\t.sort((a: { mtime: number }, b: { mtime: number }) => b.mtime - a.mtime);\n\t\treturn files[0]?.path;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * Create and configure AuthStorage with built-in OAuth providers.\n */\nfunction createAuthStorage(): AuthStorage {\n\tconst authStorage = new AuthStorage(getAuthPath());\n\tauthStorage.registerProvider(anthropicOAuthProvider);\n\tauthStorage.registerProvider(githubCopilotOAuthProvider);\n\tauthStorage.registerProvider(openaiCodexOAuthProvider);\n\treturn authStorage;\n}\n\nexport async function main(args: string[]) {\n\tconst parsed = parseArgs(args);\n\n\tif (parsed.version) {\n\t\tconsole.log(VERSION);\n\t\treturn;\n\t}\n\n\tif (parsed.help) {\n\t\tprintHelp();\n\t\treturn;\n\t}\n\n\tif (parsed.listModels) {\n\t\tprintModels();\n\t\treturn;\n\t}\n\n\t// Read piped stdin\n\tconst stdinContent = await readPipedStdin();\n\tif (stdinContent !== undefined) {\n\t\tparsed.print = true;\n\t\tparsed.messages.unshift(stdinContent);\n\t}\n\n\t// Process @file arguments\n\tlet initialMessage: string | undefined;\n\tif (parsed.fileArgs.length > 0) {\n\t\tconst fileContent = processFileArgs(parsed.fileArgs);\n\t\tif (parsed.messages.length > 0) {\n\t\t\tinitialMessage = fileContent + parsed.messages.shift();\n\t\t} else {\n\t\t\tinitialMessage = fileContent;\n\t\t}\n\t}\n\n\tconst cwd = process.cwd();\n\tconst isInteractive = !parsed.print && parsed.mode === undefined;\n\tconst mode = parsed.mode || \"text\";\n\n\t// Set up auth storage\n\tconst authStorage = createAuthStorage();\n\n\t// Set up settings persistence\n\tconst settingsManager = SettingsManager.create(getAgentDir());\n\n\t// Apply CLI --api-key override\n\tif (parsed.apiKey && parsed.provider) {\n\t\tauthStorage.setRuntimeApiKey(parsed.provider, parsed.apiKey);\n\t}\n\n\t// Create model (async - may resolve OAuth tokens)\n\t// Fall back to saved defaults when CLI args are not specified\n\tconst { model, provider, modelId } = await createModel({\n\t\tprovider: parsed.provider ?? settingsManager.getDefaultProvider(),\n\t\tmodel: parsed.model ?? settingsManager.getDefaultModel(),\n\t\tapiKey: parsed.apiKey,\n\t\tauthStorage,\n\t});\n\n\t// Load skills\n\tlet skills: Skill[] = [];\n\tif (!parsed.noSkills) {\n\t\tconst skillResult = loadSkills({\n\t\t\tcwd,\n\t\t\tskillPaths: parsed.skills,\n\t\t\tincludeDefaults: true,\n\t\t});\n\t\tskills = skillResult.skills;\n\n\t\tif (parsed.verbose && skillResult.diagnostics.length > 0) {\n\t\t\tfor (const d of skillResult.diagnostics) {\n\t\t\t\tconsole.error(chalk.yellow(`Skill warning: ${d.message} (${d.path})`));\n\t\t\t}\n\t\t}\n\t}\n\n\t// Load context files (AGENTS.md)\n\tconst contextFiles = loadContextFiles(cwd);\n\tif (parsed.verbose && contextFiles.length > 0) {\n\t\tconsole.log(chalk.dim(`Loaded ${contextFiles.length} context file(s).`));\n\t}\n\n\t// Load prompt templates\n\tconst promptsResult = loadPrompts({ cwd });\n\tconst prompts = promptsResult.prompts;\n\tif (parsed.verbose && promptsResult.diagnostics.length > 0) {\n\t\tfor (const d of promptsResult.diagnostics) {\n\t\t\tconsole.error(chalk.yellow(`Prompt warning: ${d.message} (${d.path})`));\n\t\t}\n\t}\n\n\t// Find fd binary for @ file autocomplete\n\tconst fdPath = findFd();\n\n\t// Build system prompt additions\n\tconst skillsPrompt = formatSkillsForPrompt(skills);\n\tconst appendParts: string[] = [];\n\tif (skillsPrompt) {\n\t\tappendParts.push(skillsPrompt);\n\t}\n\tif (parsed.appendSystemPrompt) {\n\t\tappendParts.push(parsed.appendSystemPrompt);\n\t}\n\tconst appendSystemPrompt = appendParts.length > 0 ? appendParts.join(\"\\n\\n\") : undefined;\n\n\t// Set up session manager\n\tconst sessionDir = parsed.sessionDir ?? getProjectSessionDir(cwd);\n\tlet sessionManager: SessionManager | undefined;\n\tif (parsed.noSession) {\n\t\tsessionManager = SessionManager.inMemory(cwd);\n\t} else if (parsed.session) {\n\t\tsessionManager = SessionManager.open(parsed.session, parsed.sessionDir);\n\t} else if (parsed.resume) {\n\t\t// Start a new session; the TUI will show the session picker on startup\n\t\tsessionManager = SessionManager.create(cwd, sessionDir);\n\t} else if (parsed.continue) {\n\t\tconst recentFile = findRecentSession(sessionDir);\n\t\tif (recentFile) {\n\t\t\tsessionManager = SessionManager.open(recentFile, sessionDir);\n\t\t} else {\n\t\t\tif (parsed.verbose) {\n\t\t\t\tconsole.log(chalk.dim(\"No previous session found, starting new.\"));\n\t\t\t}\n\t\t\tsessionManager = SessionManager.create(cwd, sessionDir);\n\t\t}\n\t} else {\n\t\tsessionManager = SessionManager.create(cwd, sessionDir);\n\t}\n\n\t// Create agent config\n\tconst agentConfig: CodingAgentConfig = {\n\t\tmodel,\n\t\tcwd,\n\t\ttoolSet: parsed.toolSet ?? \"coding\",\n\t\tproviderOptions: buildProviderOptions(provider, parsed.thinking),\n\t\tsessionManager,\n\t};\n\n\tif (parsed.systemPrompt) {\n\t\tagentConfig.systemPrompt = parsed.systemPrompt;\n\t\tif (appendSystemPrompt) {\n\t\t\tagentConfig.systemPrompt += `\\n\\n${appendSystemPrompt}`;\n\t\t}\n\t} else {\n\t\tagentConfig.systemPromptOptions = {\n\t\t\tappendSystemPrompt,\n\t\t\tcontextFiles,\n\t\t};\n\t}\n\n\t// Create agent (session messages are auto-restored from sessionManager)\n\tconst agent = new CodingAgent(agentConfig);\n\n\tif (parsed.verbose && agent.messages.length > 0) {\n\t\tconsole.log(chalk.dim(`Restored ${agent.messages.length} messages from session.`));\n\t}\n\n\t// Dispatch to mode\n\tif (isInteractive) {\n\t\tawait runInteractiveMode(agent, {\n\t\t\tinitialMessage,\n\t\t\tinitialMessages: parsed.messages,\n\t\t\tsessionDir,\n\t\t\tagentConfig,\n\t\t\tresumeOnStart: parsed.resume,\n\t\t\tskills,\n\t\t\tcontextFiles,\n\t\t\tprompts,\n\t\t\tverbose: parsed.verbose,\n\t\t\tprovider,\n\t\t\tmodelId,\n\t\t\tauthStorage,\n\t\t\tsettingsManager,\n\t\t\tfdPath,\n\t\t\tonModelChange: async (newProvider: string, newModelId: string) => {\n\t\t\t\tconst { model: newModel } = await createModel({\n\t\t\t\t\tprovider: newProvider,\n\t\t\t\t\tmodel: newModelId,\n\t\t\t\t\tauthStorage,\n\t\t\t\t});\n\t\t\t\treturn new CodingAgent({\n\t\t\t\t\t...agentConfig,\n\t\t\t\t\tmodel: newModel,\n\t\t\t\t\tproviderOptions: buildProviderOptions(newProvider, parsed.thinking),\n\t\t\t\t});\n\t\t\t},\n\t\t});\n\t} else {\n\t\tawait runPrintMode(agent, {\n\t\t\tmode,\n\t\t\tmessages: parsed.messages,\n\t\t\tinitialMessage,\n\t\t});\n\t\tprocess.exit(0);\n\t}\n}\n"]}
|
package/dist/main.js
CHANGED
|
@@ -16,6 +16,7 @@ import { createModel } from "./model-factory.js";
|
|
|
16
16
|
import { runInteractiveMode } from "./modes/interactive-mode.js";
|
|
17
17
|
import { runPrintMode } from "./modes/print-mode.js";
|
|
18
18
|
import { loadPrompts } from "./prompts.js";
|
|
19
|
+
import { buildProviderOptions } from "./provider-options.js";
|
|
19
20
|
import { SettingsManager } from "./settings.js";
|
|
20
21
|
import { formatSkillsForPrompt, loadSkills } from "./skills.js";
|
|
21
22
|
import { findFd } from "./utils/find-fd.js";
|
|
@@ -240,7 +241,7 @@ export async function main(args) {
|
|
|
240
241
|
model,
|
|
241
242
|
cwd,
|
|
242
243
|
toolSet: parsed.toolSet ?? "coding",
|
|
243
|
-
|
|
244
|
+
providerOptions: buildProviderOptions(provider, parsed.thinking),
|
|
244
245
|
sessionManager,
|
|
245
246
|
};
|
|
246
247
|
if (parsed.systemPrompt) {
|
|
@@ -286,6 +287,7 @@ export async function main(args) {
|
|
|
286
287
|
return new CodingAgent({
|
|
287
288
|
...agentConfig,
|
|
288
289
|
model: newModel,
|
|
290
|
+
providerOptions: buildProviderOptions(newProvider, parsed.thinking),
|
|
289
291
|
});
|
|
290
292
|
},
|
|
291
293
|
});
|
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":["/**\n * Main entry point for the edge-pi CLI.\n *\n * Handles argument parsing, model creation, skill loading,\n * session management, auth, and mode dispatch.\n */\n\nimport { existsSync, readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport chalk from \"chalk\";\nimport type { CodingAgentConfig } from \"edge-pi\";\nimport { CodingAgent, SessionManager } from \"edge-pi\";\nimport {\n\tAuthStorage,\n\tanthropicOAuthProvider,\n\tgithubCopilotOAuthProvider,\n\topenaiCodexOAuthProvider,\n} from \"./auth/index.js\";\nimport { parseArgs, printHelp, printModels } from \"./cli/args.js\";\nimport { loadContextFiles } from \"./context.js\";\nimport { createModel } from \"./model-factory.js\";\nimport { runInteractiveMode } from \"./modes/interactive-mode.js\";\nimport { runPrintMode } from \"./modes/print-mode.js\";\nimport { loadPrompts } from \"./prompts.js\";\nimport { SettingsManager } from \"./settings.js\";\nimport { formatSkillsForPrompt, loadSkills, type Skill } from \"./skills.js\";\nimport { findFd } from \"./utils/find-fd.js\";\n\nconst VERSION = \"0.1.0\";\nconst CONFIG_DIR_NAME = \".pi\";\n\nfunction getAgentDir(): string {\n\tconst envDir = process.env.PI_CODING_AGENT_DIR;\n\tif (envDir) {\n\t\tif (envDir === \"~\") return homedir();\n\t\tif (envDir.startsWith(\"~/\")) return homedir() + envDir.slice(1);\n\t\treturn envDir;\n\t}\n\treturn join(homedir(), CONFIG_DIR_NAME, \"agent\");\n}\n\nfunction getSessionsDir(): string {\n\treturn join(getAgentDir(), \"sessions\");\n}\n\nfunction getAuthPath(): string {\n\treturn join(getAgentDir(), \"auth.json\");\n}\n\n/**\n * Read all content from piped stdin.\n * Returns undefined if stdin is a TTY.\n */\nasync function readPipedStdin(): Promise<string | undefined> {\n\tif (process.stdin.isTTY) {\n\t\treturn undefined;\n\t}\n\treturn new Promise((resolve) => {\n\t\tlet data = \"\";\n\t\tprocess.stdin.setEncoding(\"utf8\");\n\t\tprocess.stdin.on(\"data\", (chunk) => {\n\t\t\tdata += chunk;\n\t\t});\n\t\tprocess.stdin.on(\"end\", () => {\n\t\t\tresolve(data.trim() || undefined);\n\t\t});\n\t\tprocess.stdin.resume();\n\t});\n}\n\n/**\n * Process @file arguments into text content.\n */\nfunction processFileArgs(fileArgs: string[]): string {\n\tconst parts: string[] = [];\n\tfor (const filePath of fileArgs) {\n\t\tconst resolved = resolve(filePath);\n\t\tif (!existsSync(resolved)) {\n\t\t\tconsole.error(chalk.yellow(`Warning: File not found: ${resolved}`));\n\t\t\tcontinue;\n\t\t}\n\t\ttry {\n\t\t\tconst content = readFileSync(resolved, \"utf-8\");\n\t\t\tparts.push(`<file path=\"${resolved}\">\\n${content}\\n</file>`);\n\t\t} catch (error) {\n\t\t\tconsole.error(chalk.yellow(`Warning: Could not read ${resolved}: ${(error as Error).message}`));\n\t\t}\n\t}\n\treturn parts.length > 0 ? `${parts.join(\"\\n\\n\")}\\n\\n` : \"\";\n}\n\n/**\n * Create a session directory path based on the current working directory.\n */\nfunction getProjectSessionDir(cwd: string): string {\n\tconst sanitized = cwd.replace(/\\//g, \"--\").replace(/^--/, \"\");\n\treturn join(getSessionsDir(), sanitized);\n}\n\n/**\n * Find the most recent session file in a directory.\n */\nfunction findRecentSession(sessionDir: string): string | undefined {\n\tif (!existsSync(sessionDir)) return undefined;\n\ttry {\n\t\tconst files = readdirSync(sessionDir)\n\t\t\t.filter((f: string) => f.endsWith(\".jsonl\"))\n\t\t\t.map((f: string) => ({\n\t\t\t\tname: f,\n\t\t\t\tpath: join(sessionDir, f),\n\t\t\t\tmtime: statSync(join(sessionDir, f)).mtime.getTime(),\n\t\t\t}))\n\t\t\t.sort((a: { mtime: number }, b: { mtime: number }) => b.mtime - a.mtime);\n\t\treturn files[0]?.path;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * Create and configure AuthStorage with built-in OAuth providers.\n */\nfunction createAuthStorage(): AuthStorage {\n\tconst authStorage = new AuthStorage(getAuthPath());\n\tauthStorage.registerProvider(anthropicOAuthProvider);\n\tauthStorage.registerProvider(githubCopilotOAuthProvider);\n\tauthStorage.registerProvider(openaiCodexOAuthProvider);\n\treturn authStorage;\n}\n\nexport async function main(args: string[]) {\n\tconst parsed = parseArgs(args);\n\n\tif (parsed.version) {\n\t\tconsole.log(VERSION);\n\t\treturn;\n\t}\n\n\tif (parsed.help) {\n\t\tprintHelp();\n\t\treturn;\n\t}\n\n\tif (parsed.listModels) {\n\t\tprintModels();\n\t\treturn;\n\t}\n\n\t// Read piped stdin\n\tconst stdinContent = await readPipedStdin();\n\tif (stdinContent !== undefined) {\n\t\tparsed.print = true;\n\t\tparsed.messages.unshift(stdinContent);\n\t}\n\n\t// Process @file arguments\n\tlet initialMessage: string | undefined;\n\tif (parsed.fileArgs.length > 0) {\n\t\tconst fileContent = processFileArgs(parsed.fileArgs);\n\t\tif (parsed.messages.length > 0) {\n\t\t\tinitialMessage = fileContent + parsed.messages.shift();\n\t\t} else {\n\t\t\tinitialMessage = fileContent;\n\t\t}\n\t}\n\n\tconst cwd = process.cwd();\n\tconst isInteractive = !parsed.print && parsed.mode === undefined;\n\tconst mode = parsed.mode || \"text\";\n\n\t// Set up auth storage\n\tconst authStorage = createAuthStorage();\n\n\t// Set up settings persistence\n\tconst settingsManager = SettingsManager.create(getAgentDir());\n\n\t// Apply CLI --api-key override\n\tif (parsed.apiKey && parsed.provider) {\n\t\tauthStorage.setRuntimeApiKey(parsed.provider, parsed.apiKey);\n\t}\n\n\t// Create model (async - may resolve OAuth tokens)\n\t// Fall back to saved defaults when CLI args are not specified\n\tconst { model, provider, modelId } = await createModel({\n\t\tprovider: parsed.provider ?? settingsManager.getDefaultProvider(),\n\t\tmodel: parsed.model ?? settingsManager.getDefaultModel(),\n\t\tapiKey: parsed.apiKey,\n\t\tauthStorage,\n\t});\n\n\t// Load skills\n\tlet skills: Skill[] = [];\n\tif (!parsed.noSkills) {\n\t\tconst skillResult = loadSkills({\n\t\t\tcwd,\n\t\t\tskillPaths: parsed.skills,\n\t\t\tincludeDefaults: true,\n\t\t});\n\t\tskills = skillResult.skills;\n\n\t\tif (parsed.verbose && skillResult.diagnostics.length > 0) {\n\t\t\tfor (const d of skillResult.diagnostics) {\n\t\t\t\tconsole.error(chalk.yellow(`Skill warning: ${d.message} (${d.path})`));\n\t\t\t}\n\t\t}\n\t}\n\n\t// Load context files (AGENTS.md)\n\tconst contextFiles = loadContextFiles(cwd);\n\tif (parsed.verbose && contextFiles.length > 0) {\n\t\tconsole.log(chalk.dim(`Loaded ${contextFiles.length} context file(s).`));\n\t}\n\n\t// Load prompt templates\n\tconst promptsResult = loadPrompts({ cwd });\n\tconst prompts = promptsResult.prompts;\n\tif (parsed.verbose && promptsResult.diagnostics.length > 0) {\n\t\tfor (const d of promptsResult.diagnostics) {\n\t\t\tconsole.error(chalk.yellow(`Prompt warning: ${d.message} (${d.path})`));\n\t\t}\n\t}\n\n\t// Find fd binary for @ file autocomplete\n\tconst fdPath = findFd();\n\n\t// Build system prompt additions\n\tconst skillsPrompt = formatSkillsForPrompt(skills);\n\tconst appendParts: string[] = [];\n\tif (skillsPrompt) {\n\t\tappendParts.push(skillsPrompt);\n\t}\n\tif (parsed.appendSystemPrompt) {\n\t\tappendParts.push(parsed.appendSystemPrompt);\n\t}\n\tconst appendSystemPrompt = appendParts.length > 0 ? appendParts.join(\"\\n\\n\") : undefined;\n\n\t// Set up session manager\n\tconst sessionDir = parsed.sessionDir ?? getProjectSessionDir(cwd);\n\tlet sessionManager: SessionManager | undefined;\n\tif (parsed.noSession) {\n\t\tsessionManager = SessionManager.inMemory(cwd);\n\t} else if (parsed.session) {\n\t\tsessionManager = SessionManager.open(parsed.session, parsed.sessionDir);\n\t} else if (parsed.resume) {\n\t\t// Start a new session; the TUI will show the session picker on startup\n\t\tsessionManager = SessionManager.create(cwd, sessionDir);\n\t} else if (parsed.continue) {\n\t\tconst recentFile = findRecentSession(sessionDir);\n\t\tif (recentFile) {\n\t\t\tsessionManager = SessionManager.open(recentFile, sessionDir);\n\t\t} else {\n\t\t\tif (parsed.verbose) {\n\t\t\t\tconsole.log(chalk.dim(\"No previous session found, starting new.\"));\n\t\t\t}\n\t\t\tsessionManager = SessionManager.create(cwd, sessionDir);\n\t\t}\n\t} else {\n\t\tsessionManager = SessionManager.create(cwd, sessionDir);\n\t}\n\n\t// Create agent config\n\tconst agentConfig: CodingAgentConfig = {\n\t\tmodel,\n\t\tcwd,\n\t\ttoolSet: parsed.toolSet ?? \"coding\",\n\t\tthinkingLevel: parsed.thinking,\n\t\tsessionManager,\n\t};\n\n\tif (parsed.systemPrompt) {\n\t\tagentConfig.systemPrompt = parsed.systemPrompt;\n\t\tif (appendSystemPrompt) {\n\t\t\tagentConfig.systemPrompt += `\\n\\n${appendSystemPrompt}`;\n\t\t}\n\t} else {\n\t\tagentConfig.systemPromptOptions = {\n\t\t\tappendSystemPrompt,\n\t\t\tcontextFiles,\n\t\t};\n\t}\n\n\t// Create agent (session messages are auto-restored from sessionManager)\n\tconst agent = new CodingAgent(agentConfig);\n\n\tif (parsed.verbose && agent.messages.length > 0) {\n\t\tconsole.log(chalk.dim(`Restored ${agent.messages.length} messages from session.`));\n\t}\n\n\t// Dispatch to mode\n\tif (isInteractive) {\n\t\tawait runInteractiveMode(agent, {\n\t\t\tinitialMessage,\n\t\t\tinitialMessages: parsed.messages,\n\t\t\tsessionDir,\n\t\t\tagentConfig,\n\t\t\tresumeOnStart: parsed.resume,\n\t\t\tskills,\n\t\t\tcontextFiles,\n\t\t\tprompts,\n\t\t\tverbose: parsed.verbose,\n\t\t\tprovider,\n\t\t\tmodelId,\n\t\t\tauthStorage,\n\t\t\tsettingsManager,\n\t\t\tfdPath,\n\t\t\tonModelChange: async (newProvider: string, newModelId: string) => {\n\t\t\t\tconst { model: newModel } = await createModel({\n\t\t\t\t\tprovider: newProvider,\n\t\t\t\t\tmodel: newModelId,\n\t\t\t\t\tauthStorage,\n\t\t\t\t});\n\t\t\t\treturn new CodingAgent({\n\t\t\t\t\t...agentConfig,\n\t\t\t\t\tmodel: newModel,\n\t\t\t\t});\n\t\t\t},\n\t\t});\n\t} else {\n\t\tawait runPrintMode(agent, {\n\t\t\tmode,\n\t\t\tmessages: parsed.messages,\n\t\t\tinitialMessage,\n\t\t});\n\t\tprocess.exit(0);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Main entry point for the edge-pi CLI.\n *\n * Handles argument parsing, model creation, skill loading,\n * session management, auth, and mode dispatch.\n */\n\nimport { existsSync, readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport chalk from \"chalk\";\nimport type { CodingAgentConfig } from \"edge-pi\";\nimport { CodingAgent, SessionManager } from \"edge-pi\";\nimport {\n\tAuthStorage,\n\tanthropicOAuthProvider,\n\tgithubCopilotOAuthProvider,\n\topenaiCodexOAuthProvider,\n} from \"./auth/index.js\";\nimport { parseArgs, printHelp, printModels } from \"./cli/args.js\";\nimport { loadContextFiles } from \"./context.js\";\nimport { createModel } from \"./model-factory.js\";\nimport { runInteractiveMode } from \"./modes/interactive-mode.js\";\nimport { runPrintMode } from \"./modes/print-mode.js\";\nimport { loadPrompts } from \"./prompts.js\";\nimport { buildProviderOptions } from \"./provider-options.js\";\nimport { SettingsManager } from \"./settings.js\";\nimport { formatSkillsForPrompt, loadSkills, type Skill } from \"./skills.js\";\nimport { findFd } from \"./utils/find-fd.js\";\n\nconst VERSION = \"0.1.0\";\nconst CONFIG_DIR_NAME = \".pi\";\n\nfunction getAgentDir(): string {\n\tconst envDir = process.env.PI_CODING_AGENT_DIR;\n\tif (envDir) {\n\t\tif (envDir === \"~\") return homedir();\n\t\tif (envDir.startsWith(\"~/\")) return homedir() + envDir.slice(1);\n\t\treturn envDir;\n\t}\n\treturn join(homedir(), CONFIG_DIR_NAME, \"agent\");\n}\n\nfunction getSessionsDir(): string {\n\treturn join(getAgentDir(), \"sessions\");\n}\n\nfunction getAuthPath(): string {\n\treturn join(getAgentDir(), \"auth.json\");\n}\n\n/**\n * Read all content from piped stdin.\n * Returns undefined if stdin is a TTY.\n */\nasync function readPipedStdin(): Promise<string | undefined> {\n\tif (process.stdin.isTTY) {\n\t\treturn undefined;\n\t}\n\treturn new Promise((resolve) => {\n\t\tlet data = \"\";\n\t\tprocess.stdin.setEncoding(\"utf8\");\n\t\tprocess.stdin.on(\"data\", (chunk) => {\n\t\t\tdata += chunk;\n\t\t});\n\t\tprocess.stdin.on(\"end\", () => {\n\t\t\tresolve(data.trim() || undefined);\n\t\t});\n\t\tprocess.stdin.resume();\n\t});\n}\n\n/**\n * Process @file arguments into text content.\n */\nfunction processFileArgs(fileArgs: string[]): string {\n\tconst parts: string[] = [];\n\tfor (const filePath of fileArgs) {\n\t\tconst resolved = resolve(filePath);\n\t\tif (!existsSync(resolved)) {\n\t\t\tconsole.error(chalk.yellow(`Warning: File not found: ${resolved}`));\n\t\t\tcontinue;\n\t\t}\n\t\ttry {\n\t\t\tconst content = readFileSync(resolved, \"utf-8\");\n\t\t\tparts.push(`<file path=\"${resolved}\">\\n${content}\\n</file>`);\n\t\t} catch (error) {\n\t\t\tconsole.error(chalk.yellow(`Warning: Could not read ${resolved}: ${(error as Error).message}`));\n\t\t}\n\t}\n\treturn parts.length > 0 ? `${parts.join(\"\\n\\n\")}\\n\\n` : \"\";\n}\n\n/**\n * Create a session directory path based on the current working directory.\n */\nfunction getProjectSessionDir(cwd: string): string {\n\tconst sanitized = cwd.replace(/\\//g, \"--\").replace(/^--/, \"\");\n\treturn join(getSessionsDir(), sanitized);\n}\n\n/**\n * Find the most recent session file in a directory.\n */\nfunction findRecentSession(sessionDir: string): string | undefined {\n\tif (!existsSync(sessionDir)) return undefined;\n\ttry {\n\t\tconst files = readdirSync(sessionDir)\n\t\t\t.filter((f: string) => f.endsWith(\".jsonl\"))\n\t\t\t.map((f: string) => ({\n\t\t\t\tname: f,\n\t\t\t\tpath: join(sessionDir, f),\n\t\t\t\tmtime: statSync(join(sessionDir, f)).mtime.getTime(),\n\t\t\t}))\n\t\t\t.sort((a: { mtime: number }, b: { mtime: number }) => b.mtime - a.mtime);\n\t\treturn files[0]?.path;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * Create and configure AuthStorage with built-in OAuth providers.\n */\nfunction createAuthStorage(): AuthStorage {\n\tconst authStorage = new AuthStorage(getAuthPath());\n\tauthStorage.registerProvider(anthropicOAuthProvider);\n\tauthStorage.registerProvider(githubCopilotOAuthProvider);\n\tauthStorage.registerProvider(openaiCodexOAuthProvider);\n\treturn authStorage;\n}\n\nexport async function main(args: string[]) {\n\tconst parsed = parseArgs(args);\n\n\tif (parsed.version) {\n\t\tconsole.log(VERSION);\n\t\treturn;\n\t}\n\n\tif (parsed.help) {\n\t\tprintHelp();\n\t\treturn;\n\t}\n\n\tif (parsed.listModels) {\n\t\tprintModels();\n\t\treturn;\n\t}\n\n\t// Read piped stdin\n\tconst stdinContent = await readPipedStdin();\n\tif (stdinContent !== undefined) {\n\t\tparsed.print = true;\n\t\tparsed.messages.unshift(stdinContent);\n\t}\n\n\t// Process @file arguments\n\tlet initialMessage: string | undefined;\n\tif (parsed.fileArgs.length > 0) {\n\t\tconst fileContent = processFileArgs(parsed.fileArgs);\n\t\tif (parsed.messages.length > 0) {\n\t\t\tinitialMessage = fileContent + parsed.messages.shift();\n\t\t} else {\n\t\t\tinitialMessage = fileContent;\n\t\t}\n\t}\n\n\tconst cwd = process.cwd();\n\tconst isInteractive = !parsed.print && parsed.mode === undefined;\n\tconst mode = parsed.mode || \"text\";\n\n\t// Set up auth storage\n\tconst authStorage = createAuthStorage();\n\n\t// Set up settings persistence\n\tconst settingsManager = SettingsManager.create(getAgentDir());\n\n\t// Apply CLI --api-key override\n\tif (parsed.apiKey && parsed.provider) {\n\t\tauthStorage.setRuntimeApiKey(parsed.provider, parsed.apiKey);\n\t}\n\n\t// Create model (async - may resolve OAuth tokens)\n\t// Fall back to saved defaults when CLI args are not specified\n\tconst { model, provider, modelId } = await createModel({\n\t\tprovider: parsed.provider ?? settingsManager.getDefaultProvider(),\n\t\tmodel: parsed.model ?? settingsManager.getDefaultModel(),\n\t\tapiKey: parsed.apiKey,\n\t\tauthStorage,\n\t});\n\n\t// Load skills\n\tlet skills: Skill[] = [];\n\tif (!parsed.noSkills) {\n\t\tconst skillResult = loadSkills({\n\t\t\tcwd,\n\t\t\tskillPaths: parsed.skills,\n\t\t\tincludeDefaults: true,\n\t\t});\n\t\tskills = skillResult.skills;\n\n\t\tif (parsed.verbose && skillResult.diagnostics.length > 0) {\n\t\t\tfor (const d of skillResult.diagnostics) {\n\t\t\t\tconsole.error(chalk.yellow(`Skill warning: ${d.message} (${d.path})`));\n\t\t\t}\n\t\t}\n\t}\n\n\t// Load context files (AGENTS.md)\n\tconst contextFiles = loadContextFiles(cwd);\n\tif (parsed.verbose && contextFiles.length > 0) {\n\t\tconsole.log(chalk.dim(`Loaded ${contextFiles.length} context file(s).`));\n\t}\n\n\t// Load prompt templates\n\tconst promptsResult = loadPrompts({ cwd });\n\tconst prompts = promptsResult.prompts;\n\tif (parsed.verbose && promptsResult.diagnostics.length > 0) {\n\t\tfor (const d of promptsResult.diagnostics) {\n\t\t\tconsole.error(chalk.yellow(`Prompt warning: ${d.message} (${d.path})`));\n\t\t}\n\t}\n\n\t// Find fd binary for @ file autocomplete\n\tconst fdPath = findFd();\n\n\t// Build system prompt additions\n\tconst skillsPrompt = formatSkillsForPrompt(skills);\n\tconst appendParts: string[] = [];\n\tif (skillsPrompt) {\n\t\tappendParts.push(skillsPrompt);\n\t}\n\tif (parsed.appendSystemPrompt) {\n\t\tappendParts.push(parsed.appendSystemPrompt);\n\t}\n\tconst appendSystemPrompt = appendParts.length > 0 ? appendParts.join(\"\\n\\n\") : undefined;\n\n\t// Set up session manager\n\tconst sessionDir = parsed.sessionDir ?? getProjectSessionDir(cwd);\n\tlet sessionManager: SessionManager | undefined;\n\tif (parsed.noSession) {\n\t\tsessionManager = SessionManager.inMemory(cwd);\n\t} else if (parsed.session) {\n\t\tsessionManager = SessionManager.open(parsed.session, parsed.sessionDir);\n\t} else if (parsed.resume) {\n\t\t// Start a new session; the TUI will show the session picker on startup\n\t\tsessionManager = SessionManager.create(cwd, sessionDir);\n\t} else if (parsed.continue) {\n\t\tconst recentFile = findRecentSession(sessionDir);\n\t\tif (recentFile) {\n\t\t\tsessionManager = SessionManager.open(recentFile, sessionDir);\n\t\t} else {\n\t\t\tif (parsed.verbose) {\n\t\t\t\tconsole.log(chalk.dim(\"No previous session found, starting new.\"));\n\t\t\t}\n\t\t\tsessionManager = SessionManager.create(cwd, sessionDir);\n\t\t}\n\t} else {\n\t\tsessionManager = SessionManager.create(cwd, sessionDir);\n\t}\n\n\t// Create agent config\n\tconst agentConfig: CodingAgentConfig = {\n\t\tmodel,\n\t\tcwd,\n\t\ttoolSet: parsed.toolSet ?? \"coding\",\n\t\tproviderOptions: buildProviderOptions(provider, parsed.thinking),\n\t\tsessionManager,\n\t};\n\n\tif (parsed.systemPrompt) {\n\t\tagentConfig.systemPrompt = parsed.systemPrompt;\n\t\tif (appendSystemPrompt) {\n\t\t\tagentConfig.systemPrompt += `\\n\\n${appendSystemPrompt}`;\n\t\t}\n\t} else {\n\t\tagentConfig.systemPromptOptions = {\n\t\t\tappendSystemPrompt,\n\t\t\tcontextFiles,\n\t\t};\n\t}\n\n\t// Create agent (session messages are auto-restored from sessionManager)\n\tconst agent = new CodingAgent(agentConfig);\n\n\tif (parsed.verbose && agent.messages.length > 0) {\n\t\tconsole.log(chalk.dim(`Restored ${agent.messages.length} messages from session.`));\n\t}\n\n\t// Dispatch to mode\n\tif (isInteractive) {\n\t\tawait runInteractiveMode(agent, {\n\t\t\tinitialMessage,\n\t\t\tinitialMessages: parsed.messages,\n\t\t\tsessionDir,\n\t\t\tagentConfig,\n\t\t\tresumeOnStart: parsed.resume,\n\t\t\tskills,\n\t\t\tcontextFiles,\n\t\t\tprompts,\n\t\t\tverbose: parsed.verbose,\n\t\t\tprovider,\n\t\t\tmodelId,\n\t\t\tauthStorage,\n\t\t\tsettingsManager,\n\t\t\tfdPath,\n\t\t\tonModelChange: async (newProvider: string, newModelId: string) => {\n\t\t\t\tconst { model: newModel } = await createModel({\n\t\t\t\t\tprovider: newProvider,\n\t\t\t\t\tmodel: newModelId,\n\t\t\t\t\tauthStorage,\n\t\t\t\t});\n\t\t\t\treturn new CodingAgent({\n\t\t\t\t\t...agentConfig,\n\t\t\t\t\tmodel: newModel,\n\t\t\t\t\tproviderOptions: buildProviderOptions(newProvider, parsed.thinking),\n\t\t\t\t});\n\t\t\t},\n\t\t});\n\t} else {\n\t\tawait runPrintMode(agent, {\n\t\t\tmode,\n\t\t\tmessages: parsed.messages,\n\t\t\tinitialMessage,\n\t\t});\n\t\tprocess.exit(0);\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-factory.d.ts","sourceRoot":"","sources":["../src/model-factory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAGxC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"model-factory.d.ts","sourceRoot":"","sources":["../src/model-factory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAGxC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAI1D,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;CAC1E;AAmHD;;GAEG;AACH,wBAAgB,cAAc,CAAC,WAAW,CAAC,EAAE,WAAW,GAAG,cAAc,GAAG,SAAS,CAcpF;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAEpE;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,EAAE,CAExC;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAQ1D;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC1B,GAAG,OAAO,CAAC;IACX,KAAK,EAAE,aAAa,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CAChB,CAAC,CAwCD","sourcesContent":["/**\n * Model factory - creates Vercel AI SDK LanguageModel instances\n * from provider name + model ID + optional API key.\n *\n * Supports OAuth tokens for Anthropic (Bearer auth with special headers).\n */\n\nimport type { LanguageModel } from \"ai\";\nimport chalk from \"chalk\";\nimport { isAnthropicOAuthToken } from \"./auth/anthropic-oauth.js\";\nimport type { AuthStorage } from \"./auth/auth-storage.js\";\n\nconst OPENAI_CODEX_ACCOUNT_CLAIM = \"https://api.openai.com/auth\";\n\nexport interface ProviderConfig {\n\tname: string;\n\tenvVar: string;\n\tdefaultModel: string;\n\tcreateModel: (modelId: string, apiKey?: string) => Promise<LanguageModel>;\n}\n\nfunction extractOpenAICodexAccountId(token: string): string {\n\ttry {\n\t\tconst parts = token.split(\".\");\n\t\tif (parts.length !== 3) {\n\t\t\tthrow new Error(\"Invalid OAuth token format\");\n\t\t}\n\n\t\tconst payload = JSON.parse(Buffer.from(parts[1], \"base64url\").toString(\"utf-8\")) as Record<string, unknown>;\n\t\tconst authClaim = payload[OPENAI_CODEX_ACCOUNT_CLAIM] as Record<string, unknown> | undefined;\n\t\tconst accountId = authClaim?.chatgpt_account_id;\n\t\tif (typeof accountId !== \"string\" || accountId.length === 0) {\n\t\t\tthrow new Error(\"chatgpt_account_id claim missing\");\n\t\t}\n\t\treturn accountId;\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tthrow new Error(`Failed to extract ChatGPT account ID from OAuth token: ${message}`);\n\t}\n}\n\nasync function createAnthropicModelWithOAuth(modelId: string, apiKey: string): Promise<LanguageModel> {\n\tconst { createAnthropic } = await import(\"@ai-sdk/anthropic\");\n\n\tif (isAnthropicOAuthToken(apiKey)) {\n\t\tconst provider = createAnthropic({\n\t\t\tauthToken: apiKey,\n\t\t\theaders: {\n\t\t\t\t\"anthropic-beta\": \"claude-code-20250219,oauth-2025-04-20\",\n\t\t\t\t\"user-agent\": \"epi/0.1.0 (external, cli)\",\n\t\t\t},\n\t\t});\n\t\treturn provider(modelId);\n\t}\n\n\tconst provider = createAnthropic({ apiKey });\n\treturn provider(modelId);\n}\n\nconst providers: Record<string, ProviderConfig> = {\n\tanthropic: {\n\t\tname: \"anthropic\",\n\t\tenvVar: \"ANTHROPIC_API_KEY\",\n\t\tdefaultModel: \"claude-opus-4-6\",\n\t\tcreateModel: async (modelId: string, apiKey?: string) => {\n\t\t\tif (apiKey) {\n\t\t\t\treturn createAnthropicModelWithOAuth(modelId, apiKey);\n\t\t\t}\n\t\t\tconst { createAnthropic } = await import(\"@ai-sdk/anthropic\");\n\t\t\tconst provider = createAnthropic();\n\t\t\treturn provider(modelId);\n\t\t},\n\t},\n\topenai: {\n\t\tname: \"openai\",\n\t\tenvVar: \"OPENAI_API_KEY\",\n\t\tdefaultModel: \"gpt-5.3\",\n\t\tcreateModel: async (modelId: string, apiKey?: string) => {\n\t\t\tconst { createOpenAI } = await import(\"@ai-sdk/openai\");\n\t\t\tconst provider = createOpenAI(apiKey ? { apiKey } : undefined);\n\t\t\treturn provider(modelId);\n\t\t},\n\t},\n\tgoogle: {\n\t\tname: \"google\",\n\t\tenvVar: \"GEMINI_API_KEY\",\n\t\tdefaultModel: \"gemini-3-flash\",\n\t\tcreateModel: async (modelId: string, apiKey?: string) => {\n\t\t\tconst { createGoogleGenerativeAI } = await import(\"@ai-sdk/google\");\n\t\t\tconst provider = createGoogleGenerativeAI(apiKey ? { apiKey } : undefined);\n\t\t\treturn provider(modelId);\n\t\t},\n\t},\n\t\"openai-codex\": {\n\t\tname: \"openai-codex\",\n\t\tenvVar: \"OPENAI_API_KEY\",\n\t\tdefaultModel: \"gpt-5.3-codex\",\n\t\tcreateModel: async (modelId: string, apiKey?: string) => {\n\t\t\tconst { createOpenAI } = await import(\"@ai-sdk/openai\");\n\t\t\tconst accountId = apiKey ? extractOpenAICodexAccountId(apiKey) : undefined;\n\t\t\tconst provider = createOpenAI({\n\t\t\t\tapiKey: apiKey ?? \"\",\n\t\t\t\tbaseURL: \"https://chatgpt.com/backend-api/codex\",\n\t\t\t\theaders: {\n\t\t\t\t\t...(accountId ? { \"chatgpt-account-id\": accountId } : {}),\n\t\t\t\t\t\"OpenAI-Beta\": \"responses=experimental\",\n\t\t\t\t\toriginator: \"pi\",\n\t\t\t\t\t\"User-Agent\": \"epi/0.1.0 (external, cli)\",\n\t\t\t\t},\n\t\t\t});\n\t\t\treturn provider(modelId);\n\t\t},\n\t},\n\t\"github-copilot\": {\n\t\tname: \"github-copilot\",\n\t\tenvVar: \"GITHUB_TOKEN\",\n\t\tdefaultModel: \"claude-sonnet-4.5\",\n\t\tcreateModel: async (modelId: string, apiKey?: string) => {\n\t\t\tconst { createOpenAI } = await import(\"@ai-sdk/openai\");\n\t\t\tconst provider = createOpenAI({\n\t\t\t\tapiKey: apiKey ?? \"\",\n\t\t\t\tbaseURL: \"https://api.individual.githubcopilot.com\",\n\t\t\t\theaders: {\n\t\t\t\t\t\"User-Agent\": \"GitHubCopilotChat/0.35.0\",\n\t\t\t\t\t\"Editor-Version\": \"vscode/1.107.0\",\n\t\t\t\t\t\"Editor-Plugin-Version\": \"copilot-chat/0.35.0\",\n\t\t\t\t\t\"Copilot-Integration-Id\": \"vscode-chat\",\n\t\t\t\t},\n\t\t\t});\n\t\t\treturn provider.chat(modelId);\n\t\t},\n\t},\n};\n\n/**\n * Detect which provider to use based on AuthStorage or environment variables.\n */\nexport function detectProvider(authStorage?: AuthStorage): ProviderConfig | undefined {\n\tif (authStorage) {\n\t\tfor (const config of Object.values(providers)) {\n\t\t\tif (authStorage.hasAuth(config.name)) {\n\t\t\t\treturn config;\n\t\t\t}\n\t\t}\n\t}\n\tfor (const config of Object.values(providers)) {\n\t\tif (process.env[config.envVar]) {\n\t\t\treturn config;\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/**\n * Get a provider config by name.\n */\nexport function getProvider(name: string): ProviderConfig | undefined {\n\treturn providers[name];\n}\n\n/**\n * List all supported provider names.\n */\nexport function listProviders(): string[] {\n\treturn Object.keys(providers);\n}\n\n/**\n * Get the latest recommended models for each provider.\n */\nexport function getLatestModels(): Record<string, string[]> {\n\treturn {\n\t\tanthropic: [\"claude-opus-4-6\", \"claude-sonnet-4-5\", \"claude-haiku-4-5\"],\n\t\topenai: [\"gpt-5.2-codex\", \"gpt-5.3-codex\"],\n\t\tgoogle: [\"gemini-3-flash-preview\", \"gemini-3-pro-preview\"],\n\t\t\"openai-codex\": [\"gpt-5.3-codex\", \"gpt-5.2-codex\", \"gpt-5.1-codex-max\"],\n\t\t\"github-copilot\": [\"claude-sonnet-4.5\", \"gpt-5.2\", \"gemini-3-pro-preview\", \"gemini-3-flash-preview\"],\n\t};\n}\n\n/**\n * Create a LanguageModel from provider name, model ID, and optional API key.\n * Uses AuthStorage for credential resolution (OAuth + API key + env vars).\n */\nexport async function createModel(options: {\n\tprovider?: string;\n\tmodel?: string;\n\tapiKey?: string;\n\tauthStorage?: AuthStorage;\n}): Promise<{\n\tmodel: LanguageModel;\n\tprovider: string;\n\tmodelId: string;\n}> {\n\tconst { provider: providerName, model: modelId, apiKey, authStorage } = options;\n\n\tlet config: ProviderConfig | undefined;\n\n\tif (providerName) {\n\t\tconfig = getProvider(providerName);\n\t\tif (!config) {\n\t\t\tconsole.error(chalk.red(`Unknown provider: ${providerName}`));\n\t\t\tconsole.error(`Supported providers: ${listProviders().join(\", \")}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t} else {\n\t\tconfig = detectProvider(authStorage);\n\t\tif (!config) {\n\t\t\tconsole.error(chalk.red(\"No API key found. Set one of:\"));\n\t\t\tfor (const p of Object.values(providers)) {\n\t\t\t\tconsole.error(` ${p.envVar} (for ${p.name})`);\n\t\t\t}\n\t\t\tconsole.error(\"Or use: epi /login\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\tconst resolvedModelId = modelId ?? config.defaultModel;\n\n\t// Resolve API key: explicit > AuthStorage > env var\n\tlet resolvedApiKey = apiKey;\n\tif (!resolvedApiKey && authStorage) {\n\t\tresolvedApiKey = await authStorage.getApiKey(config.name);\n\t}\n\n\ttry {\n\t\tconst model = await config.createModel(resolvedModelId, resolvedApiKey);\n\t\treturn { model, provider: config.name, modelId: resolvedModelId };\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : \"Unknown error\";\n\t\tconsole.error(chalk.red(`Failed to create model ${config.name}/${resolvedModelId}: ${message}`));\n\t\tprocess.exit(1);\n\t}\n}\n"]}
|
package/dist/model-factory.js
CHANGED
|
@@ -6,6 +6,26 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import chalk from "chalk";
|
|
8
8
|
import { isAnthropicOAuthToken } from "./auth/anthropic-oauth.js";
|
|
9
|
+
const OPENAI_CODEX_ACCOUNT_CLAIM = "https://api.openai.com/auth";
|
|
10
|
+
function extractOpenAICodexAccountId(token) {
|
|
11
|
+
try {
|
|
12
|
+
const parts = token.split(".");
|
|
13
|
+
if (parts.length !== 3) {
|
|
14
|
+
throw new Error("Invalid OAuth token format");
|
|
15
|
+
}
|
|
16
|
+
const payload = JSON.parse(Buffer.from(parts[1], "base64url").toString("utf-8"));
|
|
17
|
+
const authClaim = payload[OPENAI_CODEX_ACCOUNT_CLAIM];
|
|
18
|
+
const accountId = authClaim?.chatgpt_account_id;
|
|
19
|
+
if (typeof accountId !== "string" || accountId.length === 0) {
|
|
20
|
+
throw new Error("chatgpt_account_id claim missing");
|
|
21
|
+
}
|
|
22
|
+
return accountId;
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
26
|
+
throw new Error(`Failed to extract ChatGPT account ID from OAuth token: ${message}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
9
29
|
async function createAnthropicModelWithOAuth(modelId, apiKey) {
|
|
10
30
|
const { createAnthropic } = await import("@ai-sdk/anthropic");
|
|
11
31
|
if (isAnthropicOAuthToken(apiKey)) {
|
|
@@ -61,9 +81,16 @@ const providers = {
|
|
|
61
81
|
defaultModel: "gpt-5.3-codex",
|
|
62
82
|
createModel: async (modelId, apiKey) => {
|
|
63
83
|
const { createOpenAI } = await import("@ai-sdk/openai");
|
|
84
|
+
const accountId = apiKey ? extractOpenAICodexAccountId(apiKey) : undefined;
|
|
64
85
|
const provider = createOpenAI({
|
|
65
86
|
apiKey: apiKey ?? "",
|
|
66
|
-
baseURL: "https://chatgpt.com/backend-api",
|
|
87
|
+
baseURL: "https://chatgpt.com/backend-api/codex",
|
|
88
|
+
headers: {
|
|
89
|
+
...(accountId ? { "chatgpt-account-id": accountId } : {}),
|
|
90
|
+
"OpenAI-Beta": "responses=experimental",
|
|
91
|
+
originator: "pi",
|
|
92
|
+
"User-Agent": "epi/0.1.0 (external, cli)",
|
|
93
|
+
},
|
|
67
94
|
});
|
|
68
95
|
return provider(modelId);
|
|
69
96
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-factory.js","sourceRoot":"","sources":["../src/model-factory.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Model factory - creates Vercel AI SDK LanguageModel instances\n * from provider name + model ID + optional API key.\n *\n * Supports OAuth tokens for Anthropic (Bearer auth with special headers).\n */\n\nimport type { LanguageModel } from \"ai\";\nimport chalk from \"chalk\";\nimport { isAnthropicOAuthToken } from \"./auth/anthropic-oauth.js\";\nimport type { AuthStorage } from \"./auth/auth-storage.js\";\n\nexport interface ProviderConfig {\n\tname: string;\n\tenvVar: string;\n\tdefaultModel: string;\n\tcreateModel: (modelId: string, apiKey?: string) => Promise<LanguageModel>;\n}\n\nasync function createAnthropicModelWithOAuth(modelId: string, apiKey: string): Promise<LanguageModel> {\n\tconst { createAnthropic } = await import(\"@ai-sdk/anthropic\");\n\n\tif (isAnthropicOAuthToken(apiKey)) {\n\t\tconst provider = createAnthropic({\n\t\t\tauthToken: apiKey,\n\t\t\theaders: {\n\t\t\t\t\"anthropic-beta\": \"claude-code-20250219,oauth-2025-04-20\",\n\t\t\t\t\"user-agent\": \"epi/0.1.0 (external, cli)\",\n\t\t\t},\n\t\t});\n\t\treturn provider(modelId);\n\t}\n\n\tconst provider = createAnthropic({ apiKey });\n\treturn provider(modelId);\n}\n\nconst providers: Record<string, ProviderConfig> = {\n\tanthropic: {\n\t\tname: \"anthropic\",\n\t\tenvVar: \"ANTHROPIC_API_KEY\",\n\t\tdefaultModel: \"claude-opus-4-6\",\n\t\tcreateModel: async (modelId: string, apiKey?: string) => {\n\t\t\tif (apiKey) {\n\t\t\t\treturn createAnthropicModelWithOAuth(modelId, apiKey);\n\t\t\t}\n\t\t\tconst { createAnthropic } = await import(\"@ai-sdk/anthropic\");\n\t\t\tconst provider = createAnthropic();\n\t\t\treturn provider(modelId);\n\t\t},\n\t},\n\topenai: {\n\t\tname: \"openai\",\n\t\tenvVar: \"OPENAI_API_KEY\",\n\t\tdefaultModel: \"gpt-5.3\",\n\t\tcreateModel: async (modelId: string, apiKey?: string) => {\n\t\t\tconst { createOpenAI } = await import(\"@ai-sdk/openai\");\n\t\t\tconst provider = createOpenAI(apiKey ? { apiKey } : undefined);\n\t\t\treturn provider(modelId);\n\t\t},\n\t},\n\tgoogle: {\n\t\tname: \"google\",\n\t\tenvVar: \"GEMINI_API_KEY\",\n\t\tdefaultModel: \"gemini-3-flash\",\n\t\tcreateModel: async (modelId: string, apiKey?: string) => {\n\t\t\tconst { createGoogleGenerativeAI } = await import(\"@ai-sdk/google\");\n\t\t\tconst provider = createGoogleGenerativeAI(apiKey ? { apiKey } : undefined);\n\t\t\treturn provider(modelId);\n\t\t},\n\t},\n\t\"openai-codex\": {\n\t\tname: \"openai-codex\",\n\t\tenvVar: \"OPENAI_API_KEY\",\n\t\tdefaultModel: \"gpt-5.3-codex\",\n\t\tcreateModel: async (modelId: string, apiKey?: string) => {\n\t\t\tconst { createOpenAI } = await import(\"@ai-sdk/openai\");\n\t\t\tconst provider = createOpenAI({\n\t\t\t\tapiKey: apiKey ?? \"\",\n\t\t\t\tbaseURL: \"https://chatgpt.com/backend-api\",\n\t\t\t});\n\t\t\treturn provider(modelId);\n\t\t},\n\t},\n\t\"github-copilot\": {\n\t\tname: \"github-copilot\",\n\t\tenvVar: \"GITHUB_TOKEN\",\n\t\tdefaultModel: \"claude-sonnet-4.5\",\n\t\tcreateModel: async (modelId: string, apiKey?: string) => {\n\t\t\tconst { createOpenAI } = await import(\"@ai-sdk/openai\");\n\t\t\tconst provider = createOpenAI({\n\t\t\t\tapiKey: apiKey ?? \"\",\n\t\t\t\tbaseURL: \"https://api.individual.githubcopilot.com\",\n\t\t\t\theaders: {\n\t\t\t\t\t\"User-Agent\": \"GitHubCopilotChat/0.35.0\",\n\t\t\t\t\t\"Editor-Version\": \"vscode/1.107.0\",\n\t\t\t\t\t\"Editor-Plugin-Version\": \"copilot-chat/0.35.0\",\n\t\t\t\t\t\"Copilot-Integration-Id\": \"vscode-chat\",\n\t\t\t\t},\n\t\t\t});\n\t\t\treturn provider.chat(modelId);\n\t\t},\n\t},\n};\n\n/**\n * Detect which provider to use based on AuthStorage or environment variables.\n */\nexport function detectProvider(authStorage?: AuthStorage): ProviderConfig | undefined {\n\tif (authStorage) {\n\t\tfor (const config of Object.values(providers)) {\n\t\t\tif (authStorage.hasAuth(config.name)) {\n\t\t\t\treturn config;\n\t\t\t}\n\t\t}\n\t}\n\tfor (const config of Object.values(providers)) {\n\t\tif (process.env[config.envVar]) {\n\t\t\treturn config;\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/**\n * Get a provider config by name.\n */\nexport function getProvider(name: string): ProviderConfig | undefined {\n\treturn providers[name];\n}\n\n/**\n * List all supported provider names.\n */\nexport function listProviders(): string[] {\n\treturn Object.keys(providers);\n}\n\n/**\n * Get the latest recommended models for each provider.\n */\nexport function getLatestModels(): Record<string, string[]> {\n\treturn {\n\t\tanthropic: [\"claude-opus-4-6\", \"claude-sonnet-4-5\", \"claude-haiku-4-5\"],\n\t\topenai: [\"gpt-5.2-codex\", \"gpt-5.3-codex\"],\n\t\tgoogle: [\"gemini-3-flash-preview\", \"gemini-3-pro-preview\"],\n\t\t\"openai-codex\": [\"gpt-5.3-codex\", \"gpt-5.2-codex\", \"gpt-5.1-codex-max\"],\n\t\t\"github-copilot\": [\"claude-sonnet-4.5\", \"gpt-5.2\", \"gemini-3-pro-preview\", \"gemini-3-flash-preview\"],\n\t};\n}\n\n/**\n * Create a LanguageModel from provider name, model ID, and optional API key.\n * Uses AuthStorage for credential resolution (OAuth + API key + env vars).\n */\nexport async function createModel(options: {\n\tprovider?: string;\n\tmodel?: string;\n\tapiKey?: string;\n\tauthStorage?: AuthStorage;\n}): Promise<{\n\tmodel: LanguageModel;\n\tprovider: string;\n\tmodelId: string;\n}> {\n\tconst { provider: providerName, model: modelId, apiKey, authStorage } = options;\n\n\tlet config: ProviderConfig | undefined;\n\n\tif (providerName) {\n\t\tconfig = getProvider(providerName);\n\t\tif (!config) {\n\t\t\tconsole.error(chalk.red(`Unknown provider: ${providerName}`));\n\t\t\tconsole.error(`Supported providers: ${listProviders().join(\", \")}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t} else {\n\t\tconfig = detectProvider(authStorage);\n\t\tif (!config) {\n\t\t\tconsole.error(chalk.red(\"No API key found. Set one of:\"));\n\t\t\tfor (const p of Object.values(providers)) {\n\t\t\t\tconsole.error(` ${p.envVar} (for ${p.name})`);\n\t\t\t}\n\t\t\tconsole.error(\"Or use: epi /login\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\tconst resolvedModelId = modelId ?? config.defaultModel;\n\n\t// Resolve API key: explicit > AuthStorage > env var\n\tlet resolvedApiKey = apiKey;\n\tif (!resolvedApiKey && authStorage) {\n\t\tresolvedApiKey = await authStorage.getApiKey(config.name);\n\t}\n\n\ttry {\n\t\tconst model = await config.createModel(resolvedModelId, resolvedApiKey);\n\t\treturn { model, provider: config.name, modelId: resolvedModelId };\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : \"Unknown error\";\n\t\tconsole.error(chalk.red(`Failed to create model ${config.name}/${resolvedModelId}: ${message}`));\n\t\tprocess.exit(1);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"model-factory.js","sourceRoot":"","sources":["../src/model-factory.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Model factory - creates Vercel AI SDK LanguageModel instances\n * from provider name + model ID + optional API key.\n *\n * Supports OAuth tokens for Anthropic (Bearer auth with special headers).\n */\n\nimport type { LanguageModel } from \"ai\";\nimport chalk from \"chalk\";\nimport { isAnthropicOAuthToken } from \"./auth/anthropic-oauth.js\";\nimport type { AuthStorage } from \"./auth/auth-storage.js\";\n\nconst OPENAI_CODEX_ACCOUNT_CLAIM = \"https://api.openai.com/auth\";\n\nexport interface ProviderConfig {\n\tname: string;\n\tenvVar: string;\n\tdefaultModel: string;\n\tcreateModel: (modelId: string, apiKey?: string) => Promise<LanguageModel>;\n}\n\nfunction extractOpenAICodexAccountId(token: string): string {\n\ttry {\n\t\tconst parts = token.split(\".\");\n\t\tif (parts.length !== 3) {\n\t\t\tthrow new Error(\"Invalid OAuth token format\");\n\t\t}\n\n\t\tconst payload = JSON.parse(Buffer.from(parts[1], \"base64url\").toString(\"utf-8\")) as Record<string, unknown>;\n\t\tconst authClaim = payload[OPENAI_CODEX_ACCOUNT_CLAIM] as Record<string, unknown> | undefined;\n\t\tconst accountId = authClaim?.chatgpt_account_id;\n\t\tif (typeof accountId !== \"string\" || accountId.length === 0) {\n\t\t\tthrow new Error(\"chatgpt_account_id claim missing\");\n\t\t}\n\t\treturn accountId;\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tthrow new Error(`Failed to extract ChatGPT account ID from OAuth token: ${message}`);\n\t}\n}\n\nasync function createAnthropicModelWithOAuth(modelId: string, apiKey: string): Promise<LanguageModel> {\n\tconst { createAnthropic } = await import(\"@ai-sdk/anthropic\");\n\n\tif (isAnthropicOAuthToken(apiKey)) {\n\t\tconst provider = createAnthropic({\n\t\t\tauthToken: apiKey,\n\t\t\theaders: {\n\t\t\t\t\"anthropic-beta\": \"claude-code-20250219,oauth-2025-04-20\",\n\t\t\t\t\"user-agent\": \"epi/0.1.0 (external, cli)\",\n\t\t\t},\n\t\t});\n\t\treturn provider(modelId);\n\t}\n\n\tconst provider = createAnthropic({ apiKey });\n\treturn provider(modelId);\n}\n\nconst providers: Record<string, ProviderConfig> = {\n\tanthropic: {\n\t\tname: \"anthropic\",\n\t\tenvVar: \"ANTHROPIC_API_KEY\",\n\t\tdefaultModel: \"claude-opus-4-6\",\n\t\tcreateModel: async (modelId: string, apiKey?: string) => {\n\t\t\tif (apiKey) {\n\t\t\t\treturn createAnthropicModelWithOAuth(modelId, apiKey);\n\t\t\t}\n\t\t\tconst { createAnthropic } = await import(\"@ai-sdk/anthropic\");\n\t\t\tconst provider = createAnthropic();\n\t\t\treturn provider(modelId);\n\t\t},\n\t},\n\topenai: {\n\t\tname: \"openai\",\n\t\tenvVar: \"OPENAI_API_KEY\",\n\t\tdefaultModel: \"gpt-5.3\",\n\t\tcreateModel: async (modelId: string, apiKey?: string) => {\n\t\t\tconst { createOpenAI } = await import(\"@ai-sdk/openai\");\n\t\t\tconst provider = createOpenAI(apiKey ? { apiKey } : undefined);\n\t\t\treturn provider(modelId);\n\t\t},\n\t},\n\tgoogle: {\n\t\tname: \"google\",\n\t\tenvVar: \"GEMINI_API_KEY\",\n\t\tdefaultModel: \"gemini-3-flash\",\n\t\tcreateModel: async (modelId: string, apiKey?: string) => {\n\t\t\tconst { createGoogleGenerativeAI } = await import(\"@ai-sdk/google\");\n\t\t\tconst provider = createGoogleGenerativeAI(apiKey ? { apiKey } : undefined);\n\t\t\treturn provider(modelId);\n\t\t},\n\t},\n\t\"openai-codex\": {\n\t\tname: \"openai-codex\",\n\t\tenvVar: \"OPENAI_API_KEY\",\n\t\tdefaultModel: \"gpt-5.3-codex\",\n\t\tcreateModel: async (modelId: string, apiKey?: string) => {\n\t\t\tconst { createOpenAI } = await import(\"@ai-sdk/openai\");\n\t\t\tconst accountId = apiKey ? extractOpenAICodexAccountId(apiKey) : undefined;\n\t\t\tconst provider = createOpenAI({\n\t\t\t\tapiKey: apiKey ?? \"\",\n\t\t\t\tbaseURL: \"https://chatgpt.com/backend-api/codex\",\n\t\t\t\theaders: {\n\t\t\t\t\t...(accountId ? { \"chatgpt-account-id\": accountId } : {}),\n\t\t\t\t\t\"OpenAI-Beta\": \"responses=experimental\",\n\t\t\t\t\toriginator: \"pi\",\n\t\t\t\t\t\"User-Agent\": \"epi/0.1.0 (external, cli)\",\n\t\t\t\t},\n\t\t\t});\n\t\t\treturn provider(modelId);\n\t\t},\n\t},\n\t\"github-copilot\": {\n\t\tname: \"github-copilot\",\n\t\tenvVar: \"GITHUB_TOKEN\",\n\t\tdefaultModel: \"claude-sonnet-4.5\",\n\t\tcreateModel: async (modelId: string, apiKey?: string) => {\n\t\t\tconst { createOpenAI } = await import(\"@ai-sdk/openai\");\n\t\t\tconst provider = createOpenAI({\n\t\t\t\tapiKey: apiKey ?? \"\",\n\t\t\t\tbaseURL: \"https://api.individual.githubcopilot.com\",\n\t\t\t\theaders: {\n\t\t\t\t\t\"User-Agent\": \"GitHubCopilotChat/0.35.0\",\n\t\t\t\t\t\"Editor-Version\": \"vscode/1.107.0\",\n\t\t\t\t\t\"Editor-Plugin-Version\": \"copilot-chat/0.35.0\",\n\t\t\t\t\t\"Copilot-Integration-Id\": \"vscode-chat\",\n\t\t\t\t},\n\t\t\t});\n\t\t\treturn provider.chat(modelId);\n\t\t},\n\t},\n};\n\n/**\n * Detect which provider to use based on AuthStorage or environment variables.\n */\nexport function detectProvider(authStorage?: AuthStorage): ProviderConfig | undefined {\n\tif (authStorage) {\n\t\tfor (const config of Object.values(providers)) {\n\t\t\tif (authStorage.hasAuth(config.name)) {\n\t\t\t\treturn config;\n\t\t\t}\n\t\t}\n\t}\n\tfor (const config of Object.values(providers)) {\n\t\tif (process.env[config.envVar]) {\n\t\t\treturn config;\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/**\n * Get a provider config by name.\n */\nexport function getProvider(name: string): ProviderConfig | undefined {\n\treturn providers[name];\n}\n\n/**\n * List all supported provider names.\n */\nexport function listProviders(): string[] {\n\treturn Object.keys(providers);\n}\n\n/**\n * Get the latest recommended models for each provider.\n */\nexport function getLatestModels(): Record<string, string[]> {\n\treturn {\n\t\tanthropic: [\"claude-opus-4-6\", \"claude-sonnet-4-5\", \"claude-haiku-4-5\"],\n\t\topenai: [\"gpt-5.2-codex\", \"gpt-5.3-codex\"],\n\t\tgoogle: [\"gemini-3-flash-preview\", \"gemini-3-pro-preview\"],\n\t\t\"openai-codex\": [\"gpt-5.3-codex\", \"gpt-5.2-codex\", \"gpt-5.1-codex-max\"],\n\t\t\"github-copilot\": [\"claude-sonnet-4.5\", \"gpt-5.2\", \"gemini-3-pro-preview\", \"gemini-3-flash-preview\"],\n\t};\n}\n\n/**\n * Create a LanguageModel from provider name, model ID, and optional API key.\n * Uses AuthStorage for credential resolution (OAuth + API key + env vars).\n */\nexport async function createModel(options: {\n\tprovider?: string;\n\tmodel?: string;\n\tapiKey?: string;\n\tauthStorage?: AuthStorage;\n}): Promise<{\n\tmodel: LanguageModel;\n\tprovider: string;\n\tmodelId: string;\n}> {\n\tconst { provider: providerName, model: modelId, apiKey, authStorage } = options;\n\n\tlet config: ProviderConfig | undefined;\n\n\tif (providerName) {\n\t\tconfig = getProvider(providerName);\n\t\tif (!config) {\n\t\t\tconsole.error(chalk.red(`Unknown provider: ${providerName}`));\n\t\t\tconsole.error(`Supported providers: ${listProviders().join(\", \")}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t} else {\n\t\tconfig = detectProvider(authStorage);\n\t\tif (!config) {\n\t\t\tconsole.error(chalk.red(\"No API key found. Set one of:\"));\n\t\t\tfor (const p of Object.values(providers)) {\n\t\t\t\tconsole.error(` ${p.envVar} (for ${p.name})`);\n\t\t\t}\n\t\t\tconsole.error(\"Or use: epi /login\");\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\tconst resolvedModelId = modelId ?? config.defaultModel;\n\n\t// Resolve API key: explicit > AuthStorage > env var\n\tlet resolvedApiKey = apiKey;\n\tif (!resolvedApiKey && authStorage) {\n\t\tresolvedApiKey = await authStorage.getApiKey(config.name);\n\t}\n\n\ttry {\n\t\tconst model = await config.createModel(resolvedModelId, resolvedApiKey);\n\t\treturn { model, provider: config.name, modelId: resolvedModelId };\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : \"Unknown error\";\n\t\tconsole.error(chalk.red(`Failed to create model ${config.name}/${resolvedModelId}: ${message}`));\n\t\tprocess.exit(1);\n\t}\n}\n"]}
|