@mariozechner/pi-coding-agent 0.33.0 → 0.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +40 -1
- package/README.md +0 -1
- package/dist/cli/args.d.ts +5 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +18 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/core/agent-session.d.ts +24 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +65 -9
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +2 -1
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/custom-tools/loader.d.ts.map +1 -1
- package/dist/core/custom-tools/loader.js +1 -0
- package/dist/core/custom-tools/loader.js.map +1 -1
- package/dist/core/hooks/index.d.ts +1 -1
- package/dist/core/hooks/index.d.ts.map +1 -1
- package/dist/core/hooks/index.js.map +1 -1
- package/dist/core/hooks/loader.d.ts +56 -1
- package/dist/core/hooks/loader.d.ts.map +1 -1
- package/dist/core/hooks/loader.js +54 -2
- package/dist/core/hooks/loader.js.map +1 -1
- package/dist/core/hooks/runner.d.ts +33 -5
- package/dist/core/hooks/runner.d.ts.map +1 -1
- package/dist/core/hooks/runner.js +100 -9
- package/dist/core/hooks/runner.js.map +1 -1
- package/dist/core/hooks/types.d.ts +135 -3
- package/dist/core/hooks/types.d.ts.map +1 -1
- package/dist/core/hooks/types.js.map +1 -1
- package/dist/core/sdk.d.ts +3 -0
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +102 -27
- package/dist/core/sdk.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +32 -7
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts +2 -0
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +6 -0
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +19 -6
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +148 -42
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts +1 -0
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +3 -0
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +3 -0
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +16 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +6 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/docs/hooks.md +114 -4
- package/examples/hooks/README.md +3 -0
- package/examples/hooks/pirate.ts +44 -0
- package/examples/hooks/plan-mode.ts +548 -0
- package/examples/hooks/tools.ts +145 -0
- package/package.json +4 -4
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,0BAA0B;AAC1B,OAAO,EACN,YAAY,GAOZ,MAAM,yBAAyB,CAAC;AACjC,0BAA0B;AAC1B,OAAO,EAA8C,WAAW,EAAwB,MAAM,wBAAwB,CAAC;AACvH,aAAa;AACb,OAAO,EAMN,sBAAsB,EACtB,8BAA8B,EAC9B,OAAO,EACP,2BAA2B,EAC3B,cAAc,EAEd,YAAY,EACZ,kBAAkB,EAElB,qBAAqB,EACrB,eAAe,EACf,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,aAAa,GACb,MAAM,4BAA4B,CAAC;AAepC,OAAO,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAE3F,oCAAoC;AACpC,OAAO,EACN,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,iBAAiB,GACjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,6BAA6B;AAC7B,OAAO,EAEN,iBAAiB;AAGjB,UAAU;AACV,kBAAkB,EAClB,cAAc;AACd,kCAAkC;AAClC,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,cAAc,EACd,YAAY,EACZ,mBAAmB,EACnB,cAAc,EACd,eAAe;AACf,YAAY;AACZ,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,aAAa,EACb,cAAc,EACd,cAAc,EACd,qBAAqB,EAMrB,YAAY;AACZ,sCAAsC;AACtC,aAAa,GACb,MAAM,eAAe,CAAC;AACvB,OAAO,EAEN,mBAAmB,EAEnB,uBAAuB,EAIvB,wBAAwB,EAExB,qBAAqB,EAErB,mBAAmB,EAMnB,cAAc,GAGd,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAKN,eAAe,GAEf,MAAM,4BAA4B,CAAC;AACpC,SAAS;AACT,OAAO,EACN,qBAAqB,EAGrB,UAAU,EACV,iBAAiB,GAIjB,MAAM,kBAAkB,CAAC;AAC1B,QAAQ;AACR,OAAO,EAEN,QAAQ,EACR,WAAW,EACX,QAAQ,EAER,QAAQ,EAER,QAAQ,EAER,MAAM,EAGN,QAAQ,EAGR,SAAS,GACT,MAAM,uBAAuB,CAAC;AAC/B,mBAAmB;AACnB,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,0BAA0B;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,mDAAmD,CAAC;AACnF,6CAA6C;AAC7C,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,0BAA0B;AAC1B,OAAO,EACN,YAAY,GAOZ,MAAM,yBAAyB,CAAC;AACjC,0BAA0B;AAC1B,OAAO,EAA8C,WAAW,EAAwB,MAAM,wBAAwB,CAAC;AACvH,aAAa;AACb,OAAO,EAMN,sBAAsB,EACtB,8BAA8B,EAC9B,OAAO,EACP,2BAA2B,EAC3B,cAAc,EAEd,YAAY,EACZ,kBAAkB,EAElB,qBAAqB,EACrB,eAAe,EACf,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,aAAa,GACb,MAAM,4BAA4B,CAAC;AAepC,OAAO,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAE3F,oCAAoC;AACpC,OAAO,EACN,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,iBAAiB,GACjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,6BAA6B;AAC7B,OAAO,EAEN,iBAAiB;AAGjB,UAAU;AACV,kBAAkB,EAClB,cAAc;AACd,kCAAkC;AAClC,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,cAAc,EACd,YAAY,EACZ,mBAAmB,EACnB,cAAc,EACd,eAAe;AACf,YAAY;AACZ,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,aAAa,EACb,cAAc,EACd,cAAc,EACd,qBAAqB,EAMrB,YAAY;AACZ,sCAAsC;AACtC,aAAa,GACb,MAAM,eAAe,CAAC;AACvB,OAAO,EAEN,mBAAmB,EAEnB,uBAAuB,EAIvB,wBAAwB,EAExB,qBAAqB,EAErB,mBAAmB,EAMnB,cAAc,GAGd,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAKN,eAAe,GAEf,MAAM,4BAA4B,CAAC;AACpC,SAAS;AACT,OAAO,EACN,qBAAqB,EAGrB,UAAU,EACV,iBAAiB,GAIjB,MAAM,kBAAkB,CAAC;AAC1B,QAAQ;AACR,OAAO,EAEN,QAAQ,EACR,WAAW,EACX,QAAQ,EAER,QAAQ,EAER,QAAQ,EAER,MAAM,EAGN,QAAQ,EAGR,SAAS,GACT,MAAM,uBAAuB,CAAC;AAC/B,mBAAmB;AACnB,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,0BAA0B;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,mDAAmD,CAAC;AACnF,6CAA6C;AAC7C,OAAO,EACN,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,KAAK,GAEL,MAAM,oCAAoC,CAAC","sourcesContent":["// Core session management\nexport {\n\tAgentSession,\n\ttype AgentSessionConfig,\n\ttype AgentSessionEvent,\n\ttype AgentSessionEventListener,\n\ttype ModelCycleResult,\n\ttype PromptOptions,\n\ttype SessionStats,\n} from \"./core/agent-session.js\";\n// Auth and model registry\nexport { type ApiKeyCredential, type AuthCredential, AuthStorage, type OAuthCredential } from \"./core/auth-storage.js\";\n// Compaction\nexport {\n\ttype BranchPreparation,\n\ttype BranchSummaryResult,\n\ttype CollectEntriesResult,\n\ttype CompactionResult,\n\ttype CutPointResult,\n\tcalculateContextTokens,\n\tcollectEntriesForBranchSummary,\n\tcompact,\n\tDEFAULT_COMPACTION_SETTINGS,\n\testimateTokens,\n\ttype FileOperations,\n\tfindCutPoint,\n\tfindTurnStartIndex,\n\ttype GenerateBranchSummaryOptions,\n\tgenerateBranchSummary,\n\tgenerateSummary,\n\tgetLastAssistantUsage,\n\tprepareBranchEntries,\n\tserializeConversation,\n\tshouldCompact,\n} from \"./core/compaction/index.js\";\n// Custom tools\nexport type {\n\tAgentToolUpdateCallback,\n\tCustomTool,\n\tCustomToolAPI,\n\tCustomToolContext,\n\tCustomToolFactory,\n\tCustomToolSessionEvent,\n\tCustomToolsLoadResult,\n\tCustomToolUIContext,\n\tExecResult,\n\tLoadedCustomTool,\n\tRenderResultOptions,\n} from \"./core/custom-tools/index.js\";\nexport { discoverAndLoadCustomTools, loadCustomTools } from \"./core/custom-tools/index.js\";\nexport type * from \"./core/hooks/index.js\";\n// Hook system types and type guards\nexport {\n\tisBashToolResult,\n\tisEditToolResult,\n\tisFindToolResult,\n\tisGrepToolResult,\n\tisLsToolResult,\n\tisReadToolResult,\n\tisWriteToolResult,\n} from \"./core/hooks/index.js\";\nexport { convertToLlm } from \"./core/messages.js\";\nexport { ModelRegistry } from \"./core/model-registry.js\";\n// SDK for programmatic usage\nexport {\n\ttype BuildSystemPromptOptions,\n\tbuildSystemPrompt,\n\ttype CreateAgentSessionOptions,\n\ttype CreateAgentSessionResult,\n\t// Factory\n\tcreateAgentSession,\n\tcreateBashTool,\n\t// Tool factories (for custom cwd)\n\tcreateCodingTools,\n\tcreateEditTool,\n\tcreateFindTool,\n\tcreateGrepTool,\n\tcreateLsTool,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateWriteTool,\n\t// Discovery\n\tdiscoverAuthStorage,\n\tdiscoverContextFiles,\n\tdiscoverCustomTools,\n\tdiscoverHooks,\n\tdiscoverModels,\n\tdiscoverSkills,\n\tdiscoverSlashCommands,\n\ttype FileSlashCommand,\n\t// Hook types\n\ttype HookAPI,\n\ttype HookContext,\n\ttype HookFactory,\n\tloadSettings,\n\t// Pre-built tools (use process.cwd())\n\treadOnlyTools,\n} from \"./core/sdk.js\";\nexport {\n\ttype BranchSummaryEntry,\n\tbuildSessionContext,\n\ttype CompactionEntry,\n\tCURRENT_SESSION_VERSION,\n\ttype CustomEntry,\n\ttype CustomMessageEntry,\n\ttype FileEntry,\n\tgetLatestCompactionEntry,\n\ttype ModelChangeEntry,\n\tmigrateSessionEntries,\n\ttype NewSessionOptions,\n\tparseSessionEntries,\n\ttype SessionContext,\n\ttype SessionEntry,\n\ttype SessionEntryBase,\n\ttype SessionHeader,\n\ttype SessionInfo,\n\tSessionManager,\n\ttype SessionMessageEntry,\n\ttype ThinkingLevelChangeEntry,\n} from \"./core/session-manager.js\";\nexport {\n\ttype CompactionSettings,\n\ttype ImageSettings,\n\ttype RetrySettings,\n\ttype Settings,\n\tSettingsManager,\n\ttype SkillsSettings,\n} from \"./core/settings-manager.js\";\n// Skills\nexport {\n\tformatSkillsForPrompt,\n\ttype LoadSkillsFromDirOptions,\n\ttype LoadSkillsResult,\n\tloadSkills,\n\tloadSkillsFromDir,\n\ttype Skill,\n\ttype SkillFrontmatter,\n\ttype SkillWarning,\n} from \"./core/skills.js\";\n// Tools\nexport {\n\ttype BashToolDetails,\n\tbashTool,\n\tcodingTools,\n\teditTool,\n\ttype FindToolDetails,\n\tfindTool,\n\ttype GrepToolDetails,\n\tgrepTool,\n\ttype LsToolDetails,\n\tlsTool,\n\ttype ReadToolDetails,\n\ttype ReadToolOptions,\n\treadTool,\n\ttype ToolsOptions,\n\ttype TruncationResult,\n\twriteTool,\n} from \"./core/tools/index.js\";\n// Main entry point\nexport { main } from \"./main.js\";\n// UI components for hooks\nexport { BorderedLoader } from \"./modes/interactive/components/bordered-loader.js\";\n// Theme utilities for custom tools and hooks\nexport {\n\tgetMarkdownTheme,\n\tgetSelectListTheme,\n\tgetSettingsListTheme,\n\tTheme,\n\ttype ThemeColor,\n} from \"./modes/interactive/theme/theme.js\";\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;AAwRH,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,iBAuKxC","sourcesContent":["/**\n * Main entry point for the coding agent CLI.\n *\n * This file handles CLI argument parsing and translates them into\n * createAgentSession() options. The SDK does the heavy lifting.\n */\n\nimport { type ImageContent, supportsXhigh } from \"@mariozechner/pi-ai\";\nimport chalk from \"chalk\";\nimport { existsSync } from \"fs\";\nimport { join } from \"path\";\nimport { type Args, parseArgs, printHelp } from \"./cli/args.js\";\nimport { processFileArguments } from \"./cli/file-processor.js\";\nimport { listModels } from \"./cli/list-models.js\";\nimport { selectSession } from \"./cli/session-picker.js\";\nimport { CONFIG_DIR_NAME, getAgentDir, getModelsPath, VERSION } from \"./config.js\";\nimport type { AgentSession } from \"./core/agent-session.js\";\n\nimport type { LoadedCustomTool } from \"./core/custom-tools/index.js\";\nimport { exportFromFile } from \"./core/export-html/index.js\";\nimport type { HookUIContext } from \"./core/index.js\";\nimport type { ModelRegistry } from \"./core/model-registry.js\";\nimport { resolveModelScope, type ScopedModel } from \"./core/model-resolver.js\";\nimport { type CreateAgentSessionOptions, createAgentSession, discoverAuthStorage, discoverModels } from \"./core/sdk.js\";\nimport { SessionManager } from \"./core/session-manager.js\";\nimport { SettingsManager } from \"./core/settings-manager.js\";\nimport { resolvePromptInput } from \"./core/system-prompt.js\";\nimport { printTimings, time } from \"./core/timings.js\";\nimport { allTools } from \"./core/tools/index.js\";\nimport { runMigrations } from \"./migrations.js\";\nimport { InteractiveMode, runPrintMode, runRpcMode } from \"./modes/index.js\";\nimport { initTheme, stopThemeWatcher } from \"./modes/interactive/theme/theme.js\";\nimport { getChangelogPath, getNewEntries, parseChangelog } from \"./utils/changelog.js\";\nimport { ensureTool } from \"./utils/tools-manager.js\";\n\nasync function checkForNewVersion(currentVersion: string): Promise<string | undefined> {\n\ttry {\n\t\tconst response = await fetch(\"https://registry.npmjs.org/@mariozechner/pi-coding-agent/latest\");\n\t\tif (!response.ok) return undefined;\n\n\t\tconst data = (await response.json()) as { version?: string };\n\t\tconst latestVersion = data.version;\n\n\t\tif (latestVersion && latestVersion !== currentVersion) {\n\t\t\treturn latestVersion;\n\t\t}\n\n\t\treturn undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nasync function runInteractiveMode(\n\tsession: AgentSession,\n\tversion: string,\n\tchangelogMarkdown: string | undefined,\n\tmodelFallbackMessage: string | undefined,\n\tmodelsJsonError: string | undefined,\n\tmigratedProviders: string[],\n\tversionCheckPromise: Promise<string | undefined>,\n\tinitialMessages: string[],\n\tcustomTools: LoadedCustomTool[],\n\tsetToolUIContext: (uiContext: HookUIContext, hasUI: boolean) => void,\n\tinitialMessage?: string,\n\tinitialImages?: ImageContent[],\n\tfdPath: string | undefined = undefined,\n): Promise<void> {\n\tconst mode = new InteractiveMode(session, version, changelogMarkdown, customTools, setToolUIContext, fdPath);\n\n\tawait mode.init();\n\n\tversionCheckPromise.then((newVersion) => {\n\t\tif (newVersion) {\n\t\t\tmode.showNewVersionNotification(newVersion);\n\t\t}\n\t});\n\n\tmode.renderInitialMessages();\n\n\tif (migratedProviders.length > 0) {\n\t\tmode.showWarning(`Migrated credentials to auth.json: ${migratedProviders.join(\", \")}`);\n\t}\n\n\tif (modelsJsonError) {\n\t\tmode.showError(`models.json error: ${modelsJsonError}`);\n\t}\n\n\tif (modelFallbackMessage) {\n\t\tmode.showWarning(modelFallbackMessage);\n\t}\n\n\tif (initialMessage) {\n\t\ttry {\n\t\t\tawait session.prompt(initialMessage, { images: initialImages });\n\t\t} catch (error: unknown) {\n\t\t\tconst errorMessage = error instanceof Error ? error.message : \"Unknown error occurred\";\n\t\t\tmode.showError(errorMessage);\n\t\t}\n\t}\n\n\tfor (const message of initialMessages) {\n\t\ttry {\n\t\t\tawait session.prompt(message);\n\t\t} catch (error: unknown) {\n\t\t\tconst errorMessage = error instanceof Error ? error.message : \"Unknown error occurred\";\n\t\t\tmode.showError(errorMessage);\n\t\t}\n\t}\n\n\twhile (true) {\n\t\tconst userInput = await mode.getUserInput();\n\t\ttry {\n\t\t\tawait session.prompt(userInput);\n\t\t} catch (error: unknown) {\n\t\t\tconst errorMessage = error instanceof Error ? error.message : \"Unknown error occurred\";\n\t\t\tmode.showError(errorMessage);\n\t\t}\n\t}\n}\n\nasync function prepareInitialMessage(\n\tparsed: Args,\n\tautoResizeImages: boolean,\n): Promise<{\n\tinitialMessage?: string;\n\tinitialImages?: ImageContent[];\n}> {\n\tif (parsed.fileArgs.length === 0) {\n\t\treturn {};\n\t}\n\n\tconst { text, images } = await processFileArguments(parsed.fileArgs, { autoResizeImages });\n\n\tlet initialMessage: string;\n\tif (parsed.messages.length > 0) {\n\t\tinitialMessage = text + parsed.messages[0];\n\t\tparsed.messages.shift();\n\t} else {\n\t\tinitialMessage = text;\n\t}\n\n\treturn {\n\t\tinitialMessage,\n\t\tinitialImages: images.length > 0 ? images : undefined,\n\t};\n}\n\nfunction getChangelogForDisplay(parsed: Args, settingsManager: SettingsManager): string | undefined {\n\tif (parsed.continue || parsed.resume) {\n\t\treturn undefined;\n\t}\n\n\tconst lastVersion = settingsManager.getLastChangelogVersion();\n\tconst changelogPath = getChangelogPath();\n\tconst entries = parseChangelog(changelogPath);\n\n\tif (!lastVersion) {\n\t\tif (entries.length > 0) {\n\t\t\tsettingsManager.setLastChangelogVersion(VERSION);\n\t\t\treturn entries.map((e) => e.content).join(\"\\n\\n\");\n\t\t}\n\t} else {\n\t\tconst newEntries = getNewEntries(entries, lastVersion);\n\t\tif (newEntries.length > 0) {\n\t\t\tsettingsManager.setLastChangelogVersion(VERSION);\n\t\t\treturn newEntries.map((e) => e.content).join(\"\\n\\n\");\n\t\t}\n\t}\n\n\treturn undefined;\n}\n\nfunction createSessionManager(parsed: Args, cwd: string): SessionManager | undefined {\n\tif (parsed.noSession) {\n\t\treturn SessionManager.inMemory();\n\t}\n\tif (parsed.session) {\n\t\treturn SessionManager.open(parsed.session, parsed.sessionDir);\n\t}\n\tif (parsed.continue) {\n\t\treturn SessionManager.continueRecent(cwd, parsed.sessionDir);\n\t}\n\t// --resume is handled separately (needs picker UI)\n\t// If --session-dir provided without --continue/--resume, create new session there\n\tif (parsed.sessionDir) {\n\t\treturn SessionManager.create(cwd, parsed.sessionDir);\n\t}\n\t// Default case (new session) returns undefined, SDK will create one\n\treturn undefined;\n}\n\n/** Discover SYSTEM.md file if no CLI system prompt was provided */\nfunction discoverSystemPromptFile(): string | undefined {\n\t// Check project-local first: .pi/SYSTEM.md\n\tconst projectPath = join(process.cwd(), CONFIG_DIR_NAME, \"SYSTEM.md\");\n\tif (existsSync(projectPath)) {\n\t\treturn projectPath;\n\t}\n\n\t// Fall back to global: ~/.pi/agent/SYSTEM.md\n\tconst globalPath = join(getAgentDir(), \"SYSTEM.md\");\n\tif (existsSync(globalPath)) {\n\t\treturn globalPath;\n\t}\n\n\treturn undefined;\n}\n\nfunction buildSessionOptions(\n\tparsed: Args,\n\tscopedModels: ScopedModel[],\n\tsessionManager: SessionManager | undefined,\n\tmodelRegistry: ModelRegistry,\n): CreateAgentSessionOptions {\n\tconst options: CreateAgentSessionOptions = {};\n\n\t// Auto-discover SYSTEM.md if no CLI system prompt provided\n\tconst systemPromptSource = parsed.systemPrompt ?? discoverSystemPromptFile();\n\tconst resolvedSystemPrompt = resolvePromptInput(systemPromptSource, \"system prompt\");\n\tconst resolvedAppendPrompt = resolvePromptInput(parsed.appendSystemPrompt, \"append system prompt\");\n\n\tif (sessionManager) {\n\t\toptions.sessionManager = sessionManager;\n\t}\n\n\t// Model from CLI\n\tif (parsed.provider && parsed.model) {\n\t\tconst model = modelRegistry.find(parsed.provider, parsed.model);\n\t\tif (!model) {\n\t\t\tconsole.error(chalk.red(`Model ${parsed.provider}/${parsed.model} not found`));\n\t\t\tprocess.exit(1);\n\t\t}\n\t\toptions.model = model;\n\t} else if (scopedModels.length > 0 && !parsed.continue && !parsed.resume) {\n\t\toptions.model = scopedModels[0].model;\n\t}\n\n\t// Thinking level\n\tif (parsed.thinking) {\n\t\toptions.thinkingLevel = parsed.thinking;\n\t} else if (scopedModels.length > 0 && !parsed.continue && !parsed.resume) {\n\t\toptions.thinkingLevel = scopedModels[0].thinkingLevel;\n\t}\n\n\t// Scoped models for Ctrl+P cycling\n\tif (scopedModels.length > 0) {\n\t\toptions.scopedModels = scopedModels;\n\t}\n\n\t// API key from CLI - set in authStorage\n\t// (handled by caller before createAgentSession)\n\n\t// System prompt\n\tif (resolvedSystemPrompt && resolvedAppendPrompt) {\n\t\toptions.systemPrompt = `${resolvedSystemPrompt}\\n\\n${resolvedAppendPrompt}`;\n\t} else if (resolvedSystemPrompt) {\n\t\toptions.systemPrompt = resolvedSystemPrompt;\n\t} else if (resolvedAppendPrompt) {\n\t\toptions.systemPrompt = (defaultPrompt) => `${defaultPrompt}\\n\\n${resolvedAppendPrompt}`;\n\t}\n\n\t// Tools\n\tif (parsed.tools) {\n\t\toptions.tools = parsed.tools.map((name) => allTools[name]);\n\t}\n\n\t// Skills\n\tif (parsed.noSkills) {\n\t\toptions.skills = [];\n\t}\n\n\t// Additional hook paths from CLI\n\tif (parsed.hooks && parsed.hooks.length > 0) {\n\t\toptions.additionalHookPaths = parsed.hooks;\n\t}\n\n\t// Additional custom tool paths from CLI\n\tif (parsed.customTools && parsed.customTools.length > 0) {\n\t\toptions.additionalCustomToolPaths = parsed.customTools;\n\t}\n\n\treturn options;\n}\n\nexport async function main(args: string[]) {\n\ttime(\"start\");\n\n\t// Run migrations\n\tconst { migratedAuthProviders: migratedProviders } = runMigrations();\n\n\t// Create AuthStorage and ModelRegistry upfront\n\tconst authStorage = discoverAuthStorage();\n\tconst modelRegistry = discoverModels(authStorage);\n\ttime(\"discoverModels\");\n\n\tconst parsed = parseArgs(args);\n\ttime(\"parseArgs\");\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 !== undefined) {\n\t\tconst searchPattern = typeof parsed.listModels === \"string\" ? parsed.listModels : undefined;\n\t\tawait listModels(modelRegistry, searchPattern);\n\t\treturn;\n\t}\n\n\tif (parsed.export) {\n\t\ttry {\n\t\t\tconst outputPath = parsed.messages.length > 0 ? parsed.messages[0] : undefined;\n\t\t\tconst result = exportFromFile(parsed.export, outputPath);\n\t\t\tconsole.log(`Exported to: ${result}`);\n\t\t\treturn;\n\t\t} catch (error: unknown) {\n\t\t\tconst message = error instanceof Error ? error.message : \"Failed to export session\";\n\t\t\tconsole.error(chalk.red(`Error: ${message}`));\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\tif (parsed.mode === \"rpc\" && parsed.fileArgs.length > 0) {\n\t\tconsole.error(chalk.red(\"Error: @file arguments are not supported in RPC mode\"));\n\t\tprocess.exit(1);\n\t}\n\n\tconst cwd = process.cwd();\n\tconst settingsManager = SettingsManager.create(cwd);\n\ttime(\"SettingsManager.create\");\n\tconst { initialMessage, initialImages } = await prepareInitialMessage(parsed, settingsManager.getImageAutoResize());\n\ttime(\"prepareInitialMessage\");\n\tconst isInteractive = !parsed.print && parsed.mode === undefined;\n\tconst mode = parsed.mode || \"text\";\n\tinitTheme(settingsManager.getTheme(), isInteractive);\n\ttime(\"initTheme\");\n\n\tlet scopedModels: ScopedModel[] = [];\n\tconst modelPatterns = parsed.models ?? settingsManager.getEnabledModels();\n\tif (modelPatterns && modelPatterns.length > 0) {\n\t\tscopedModels = await resolveModelScope(modelPatterns, modelRegistry);\n\t\ttime(\"resolveModelScope\");\n\t}\n\n\t// Create session manager based on CLI flags\n\tlet sessionManager = createSessionManager(parsed, cwd);\n\ttime(\"createSessionManager\");\n\n\t// Handle --resume: show session picker\n\tif (parsed.resume) {\n\t\tconst sessions = SessionManager.list(cwd, parsed.sessionDir);\n\t\ttime(\"SessionManager.list\");\n\t\tif (sessions.length === 0) {\n\t\t\tconsole.log(chalk.dim(\"No sessions found\"));\n\t\t\treturn;\n\t\t}\n\t\tconst selectedPath = await selectSession(sessions);\n\t\ttime(\"selectSession\");\n\t\tif (!selectedPath) {\n\t\t\tconsole.log(chalk.dim(\"No session selected\"));\n\t\t\treturn;\n\t\t}\n\t\tsessionManager = SessionManager.open(selectedPath);\n\t}\n\n\tconst sessionOptions = buildSessionOptions(parsed, scopedModels, sessionManager, modelRegistry);\n\tsessionOptions.authStorage = authStorage;\n\tsessionOptions.modelRegistry = modelRegistry;\n\n\t// Handle CLI --api-key as runtime override (not persisted)\n\tif (parsed.apiKey) {\n\t\tif (!sessionOptions.model) {\n\t\t\tconsole.error(chalk.red(\"--api-key requires a model to be specified via --provider/--model or -m/--models\"));\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tauthStorage.setRuntimeApiKey(sessionOptions.model.provider, parsed.apiKey);\n\t}\n\n\ttime(\"buildSessionOptions\");\n\tconst { session, customToolsResult, modelFallbackMessage } = await createAgentSession(sessionOptions);\n\ttime(\"createAgentSession\");\n\n\tif (!isInteractive && !session.model) {\n\t\tconsole.error(chalk.red(\"No models available.\"));\n\t\tconsole.error(chalk.yellow(\"\\nSet an API key environment variable:\"));\n\t\tconsole.error(\" ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, etc.\");\n\t\tconsole.error(chalk.yellow(`\\nOr create ${getModelsPath()}`));\n\t\tprocess.exit(1);\n\t}\n\n\t// Clamp thinking level to model capabilities (for CLI override case)\n\tif (session.model && parsed.thinking) {\n\t\tlet effectiveThinking = parsed.thinking;\n\t\tif (!session.model.reasoning) {\n\t\t\teffectiveThinking = \"off\";\n\t\t} else if (effectiveThinking === \"xhigh\" && !supportsXhigh(session.model)) {\n\t\t\teffectiveThinking = \"high\";\n\t\t}\n\t\tif (effectiveThinking !== session.thinkingLevel) {\n\t\t\tsession.setThinkingLevel(effectiveThinking);\n\t\t}\n\t}\n\n\tif (mode === \"rpc\") {\n\t\tawait runRpcMode(session);\n\t} else if (isInteractive) {\n\t\tconst versionCheckPromise = checkForNewVersion(VERSION).catch(() => undefined);\n\t\tconst changelogMarkdown = getChangelogForDisplay(parsed, settingsManager);\n\n\t\tif (scopedModels.length > 0) {\n\t\t\tconst modelList = scopedModels\n\t\t\t\t.map((sm) => {\n\t\t\t\t\tconst thinkingStr = sm.thinkingLevel !== \"off\" ? `:${sm.thinkingLevel}` : \"\";\n\t\t\t\t\treturn `${sm.model.id}${thinkingStr}`;\n\t\t\t\t})\n\t\t\t\t.join(\", \");\n\t\t\tconsole.log(chalk.dim(`Model scope: ${modelList} ${chalk.gray(\"(Ctrl+P to cycle)\")}`));\n\t\t}\n\n\t\tconst fdPath = await ensureTool(\"fd\");\n\t\ttime(\"ensureTool(fd)\");\n\n\t\tprintTimings();\n\t\tawait runInteractiveMode(\n\t\t\tsession,\n\t\t\tVERSION,\n\t\t\tchangelogMarkdown,\n\t\t\tmodelFallbackMessage,\n\t\t\tmodelRegistry.getError(),\n\t\t\tmigratedProviders,\n\t\t\tversionCheckPromise,\n\t\t\tparsed.messages,\n\t\t\tcustomToolsResult.tools,\n\t\t\tcustomToolsResult.setUIContext,\n\t\t\tinitialMessage,\n\t\t\tinitialImages,\n\t\t\tfdPath,\n\t\t);\n\t} else {\n\t\tawait runPrintMode(session, mode, parsed.messages, initialMessage, initialImages);\n\t\tstopThemeWatcher();\n\t\tif (process.stdout.writableLength > 0) {\n\t\t\tawait new Promise<void>((resolve) => process.stdout.once(\"drain\", resolve));\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;AA0RH,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,iBAmMxC","sourcesContent":["/**\n * Main entry point for the coding agent CLI.\n *\n * This file handles CLI argument parsing and translates them into\n * createAgentSession() options. The SDK does the heavy lifting.\n */\n\nimport { type ImageContent, supportsXhigh } from \"@mariozechner/pi-ai\";\nimport chalk from \"chalk\";\nimport { existsSync } from \"fs\";\nimport { join } from \"path\";\nimport { type Args, parseArgs, printHelp } from \"./cli/args.js\";\nimport { processFileArguments } from \"./cli/file-processor.js\";\nimport { listModels } from \"./cli/list-models.js\";\nimport { selectSession } from \"./cli/session-picker.js\";\nimport { CONFIG_DIR_NAME, getAgentDir, getModelsPath, VERSION } from \"./config.js\";\nimport type { AgentSession } from \"./core/agent-session.js\";\n\nimport type { LoadedCustomTool } from \"./core/custom-tools/index.js\";\nimport { exportFromFile } from \"./core/export-html/index.js\";\nimport { discoverAndLoadHooks } from \"./core/hooks/index.js\";\nimport type { HookUIContext } from \"./core/index.js\";\nimport type { ModelRegistry } from \"./core/model-registry.js\";\nimport { resolveModelScope, type ScopedModel } from \"./core/model-resolver.js\";\nimport { type CreateAgentSessionOptions, createAgentSession, discoverAuthStorage, discoverModels } from \"./core/sdk.js\";\nimport { SessionManager } from \"./core/session-manager.js\";\nimport { SettingsManager } from \"./core/settings-manager.js\";\nimport { resolvePromptInput } from \"./core/system-prompt.js\";\nimport { printTimings, time } from \"./core/timings.js\";\nimport { allTools } from \"./core/tools/index.js\";\nimport { runMigrations } from \"./migrations.js\";\nimport { InteractiveMode, runPrintMode, runRpcMode } from \"./modes/index.js\";\nimport { initTheme, stopThemeWatcher } from \"./modes/interactive/theme/theme.js\";\nimport { getChangelogPath, getNewEntries, parseChangelog } from \"./utils/changelog.js\";\nimport { ensureTool } from \"./utils/tools-manager.js\";\n\nasync function checkForNewVersion(currentVersion: string): Promise<string | undefined> {\n\ttry {\n\t\tconst response = await fetch(\"https://registry.npmjs.org/@mariozechner/pi-coding-agent/latest\");\n\t\tif (!response.ok) return undefined;\n\n\t\tconst data = (await response.json()) as { version?: string };\n\t\tconst latestVersion = data.version;\n\n\t\tif (latestVersion && latestVersion !== currentVersion) {\n\t\t\treturn latestVersion;\n\t\t}\n\n\t\treturn undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nasync function runInteractiveMode(\n\tsession: AgentSession,\n\tversion: string,\n\tchangelogMarkdown: string | undefined,\n\tmodelFallbackMessage: string | undefined,\n\tmodelsJsonError: string | undefined,\n\tmigratedProviders: string[],\n\tversionCheckPromise: Promise<string | undefined>,\n\tinitialMessages: string[],\n\tcustomTools: LoadedCustomTool[],\n\tsetToolUIContext: (uiContext: HookUIContext, hasUI: boolean) => void,\n\tinitialMessage?: string,\n\tinitialImages?: ImageContent[],\n\tfdPath: string | undefined = undefined,\n): Promise<void> {\n\tconst mode = new InteractiveMode(session, version, changelogMarkdown, customTools, setToolUIContext, fdPath);\n\n\tawait mode.init();\n\n\tversionCheckPromise.then((newVersion) => {\n\t\tif (newVersion) {\n\t\t\tmode.showNewVersionNotification(newVersion);\n\t\t}\n\t});\n\n\tmode.renderInitialMessages();\n\n\tif (migratedProviders.length > 0) {\n\t\tmode.showWarning(`Migrated credentials to auth.json: ${migratedProviders.join(\", \")}`);\n\t}\n\n\tif (modelsJsonError) {\n\t\tmode.showError(`models.json error: ${modelsJsonError}`);\n\t}\n\n\tif (modelFallbackMessage) {\n\t\tmode.showWarning(modelFallbackMessage);\n\t}\n\n\tif (initialMessage) {\n\t\ttry {\n\t\t\tawait session.prompt(initialMessage, { images: initialImages });\n\t\t} catch (error: unknown) {\n\t\t\tconst errorMessage = error instanceof Error ? error.message : \"Unknown error occurred\";\n\t\t\tmode.showError(errorMessage);\n\t\t}\n\t}\n\n\tfor (const message of initialMessages) {\n\t\ttry {\n\t\t\tawait session.prompt(message);\n\t\t} catch (error: unknown) {\n\t\t\tconst errorMessage = error instanceof Error ? error.message : \"Unknown error occurred\";\n\t\t\tmode.showError(errorMessage);\n\t\t}\n\t}\n\n\twhile (true) {\n\t\tconst userInput = await mode.getUserInput();\n\t\ttry {\n\t\t\tawait session.prompt(userInput);\n\t\t} catch (error: unknown) {\n\t\t\tconst errorMessage = error instanceof Error ? error.message : \"Unknown error occurred\";\n\t\t\tmode.showError(errorMessage);\n\t\t}\n\t}\n}\n\nasync function prepareInitialMessage(\n\tparsed: Args,\n\tautoResizeImages: boolean,\n): Promise<{\n\tinitialMessage?: string;\n\tinitialImages?: ImageContent[];\n}> {\n\tif (parsed.fileArgs.length === 0) {\n\t\treturn {};\n\t}\n\n\tconst { text, images } = await processFileArguments(parsed.fileArgs, { autoResizeImages });\n\n\tlet initialMessage: string;\n\tif (parsed.messages.length > 0) {\n\t\tinitialMessage = text + parsed.messages[0];\n\t\tparsed.messages.shift();\n\t} else {\n\t\tinitialMessage = text;\n\t}\n\n\treturn {\n\t\tinitialMessage,\n\t\tinitialImages: images.length > 0 ? images : undefined,\n\t};\n}\n\nfunction getChangelogForDisplay(parsed: Args, settingsManager: SettingsManager): string | undefined {\n\tif (parsed.continue || parsed.resume) {\n\t\treturn undefined;\n\t}\n\n\tconst lastVersion = settingsManager.getLastChangelogVersion();\n\tconst changelogPath = getChangelogPath();\n\tconst entries = parseChangelog(changelogPath);\n\n\tif (!lastVersion) {\n\t\tif (entries.length > 0) {\n\t\t\tsettingsManager.setLastChangelogVersion(VERSION);\n\t\t\treturn entries.map((e) => e.content).join(\"\\n\\n\");\n\t\t}\n\t} else {\n\t\tconst newEntries = getNewEntries(entries, lastVersion);\n\t\tif (newEntries.length > 0) {\n\t\t\tsettingsManager.setLastChangelogVersion(VERSION);\n\t\t\treturn newEntries.map((e) => e.content).join(\"\\n\\n\");\n\t\t}\n\t}\n\n\treturn undefined;\n}\n\nfunction createSessionManager(parsed: Args, cwd: string): SessionManager | undefined {\n\tif (parsed.noSession) {\n\t\treturn SessionManager.inMemory();\n\t}\n\tif (parsed.session) {\n\t\treturn SessionManager.open(parsed.session, parsed.sessionDir);\n\t}\n\tif (parsed.continue) {\n\t\treturn SessionManager.continueRecent(cwd, parsed.sessionDir);\n\t}\n\t// --resume is handled separately (needs picker UI)\n\t// If --session-dir provided without --continue/--resume, create new session there\n\tif (parsed.sessionDir) {\n\t\treturn SessionManager.create(cwd, parsed.sessionDir);\n\t}\n\t// Default case (new session) returns undefined, SDK will create one\n\treturn undefined;\n}\n\n/** Discover SYSTEM.md file if no CLI system prompt was provided */\nfunction discoverSystemPromptFile(): string | undefined {\n\t// Check project-local first: .pi/SYSTEM.md\n\tconst projectPath = join(process.cwd(), CONFIG_DIR_NAME, \"SYSTEM.md\");\n\tif (existsSync(projectPath)) {\n\t\treturn projectPath;\n\t}\n\n\t// Fall back to global: ~/.pi/agent/SYSTEM.md\n\tconst globalPath = join(getAgentDir(), \"SYSTEM.md\");\n\tif (existsSync(globalPath)) {\n\t\treturn globalPath;\n\t}\n\n\treturn undefined;\n}\n\nfunction buildSessionOptions(\n\tparsed: Args,\n\tscopedModels: ScopedModel[],\n\tsessionManager: SessionManager | undefined,\n\tmodelRegistry: ModelRegistry,\n\tpreloadedHooks?: import(\"./core/hooks/index.js\").LoadedHook[],\n): CreateAgentSessionOptions {\n\tconst options: CreateAgentSessionOptions = {};\n\n\t// Auto-discover SYSTEM.md if no CLI system prompt provided\n\tconst systemPromptSource = parsed.systemPrompt ?? discoverSystemPromptFile();\n\tconst resolvedSystemPrompt = resolvePromptInput(systemPromptSource, \"system prompt\");\n\tconst resolvedAppendPrompt = resolvePromptInput(parsed.appendSystemPrompt, \"append system prompt\");\n\n\tif (sessionManager) {\n\t\toptions.sessionManager = sessionManager;\n\t}\n\n\t// Model from CLI\n\tif (parsed.provider && parsed.model) {\n\t\tconst model = modelRegistry.find(parsed.provider, parsed.model);\n\t\tif (!model) {\n\t\t\tconsole.error(chalk.red(`Model ${parsed.provider}/${parsed.model} not found`));\n\t\t\tprocess.exit(1);\n\t\t}\n\t\toptions.model = model;\n\t} else if (scopedModels.length > 0 && !parsed.continue && !parsed.resume) {\n\t\toptions.model = scopedModels[0].model;\n\t}\n\n\t// Thinking level\n\tif (parsed.thinking) {\n\t\toptions.thinkingLevel = parsed.thinking;\n\t} else if (scopedModels.length > 0 && !parsed.continue && !parsed.resume) {\n\t\toptions.thinkingLevel = scopedModels[0].thinkingLevel;\n\t}\n\n\t// Scoped models for Ctrl+P cycling\n\tif (scopedModels.length > 0) {\n\t\toptions.scopedModels = scopedModels;\n\t}\n\n\t// API key from CLI - set in authStorage\n\t// (handled by caller before createAgentSession)\n\n\t// System prompt\n\tif (resolvedSystemPrompt && resolvedAppendPrompt) {\n\t\toptions.systemPrompt = `${resolvedSystemPrompt}\\n\\n${resolvedAppendPrompt}`;\n\t} else if (resolvedSystemPrompt) {\n\t\toptions.systemPrompt = resolvedSystemPrompt;\n\t} else if (resolvedAppendPrompt) {\n\t\toptions.systemPrompt = (defaultPrompt) => `${defaultPrompt}\\n\\n${resolvedAppendPrompt}`;\n\t}\n\n\t// Tools\n\tif (parsed.tools) {\n\t\toptions.tools = parsed.tools.map((name) => allTools[name]);\n\t}\n\n\t// Skills\n\tif (parsed.noSkills) {\n\t\toptions.skills = [];\n\t}\n\n\t// Pre-loaded hooks (from early CLI flag discovery)\n\tif (preloadedHooks && preloadedHooks.length > 0) {\n\t\toptions.preloadedHooks = preloadedHooks;\n\t}\n\n\t// Additional custom tool paths from CLI\n\tif (parsed.customTools && parsed.customTools.length > 0) {\n\t\toptions.additionalCustomToolPaths = parsed.customTools;\n\t}\n\n\treturn options;\n}\n\nexport async function main(args: string[]) {\n\ttime(\"start\");\n\n\t// Run migrations\n\tconst { migratedAuthProviders: migratedProviders } = runMigrations();\n\n\t// Create AuthStorage and ModelRegistry upfront\n\tconst authStorage = discoverAuthStorage();\n\tconst modelRegistry = discoverModels(authStorage);\n\ttime(\"discoverModels\");\n\n\t// First pass: parse args to get --hook paths\n\tconst firstPass = parseArgs(args);\n\ttime(\"parseArgs-firstPass\");\n\n\t// Early load hooks to discover their CLI flags\n\tconst cwd = process.cwd();\n\tconst agentDir = getAgentDir();\n\tconst hookPaths = firstPass.hooks ?? [];\n\tconst { hooks: loadedHooks } = await discoverAndLoadHooks(hookPaths, cwd, agentDir);\n\ttime(\"discoverHookFlags\");\n\n\t// Collect all hook flags\n\tconst hookFlags = new Map<string, { type: \"boolean\" | \"string\" }>();\n\tfor (const hook of loadedHooks) {\n\t\tfor (const [name, flag] of hook.flags) {\n\t\t\thookFlags.set(name, { type: flag.type });\n\t\t}\n\t}\n\n\t// Second pass: parse args with hook flags\n\tconst parsed = parseArgs(args, hookFlags);\n\ttime(\"parseArgs\");\n\n\t// Pass flag values to hooks\n\tfor (const [name, value] of parsed.unknownFlags) {\n\t\tfor (const hook of loadedHooks) {\n\t\t\tif (hook.flags.has(name)) {\n\t\t\t\thook.setFlagValue(name, value);\n\t\t\t}\n\t\t}\n\t}\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 !== undefined) {\n\t\tconst searchPattern = typeof parsed.listModels === \"string\" ? parsed.listModels : undefined;\n\t\tawait listModels(modelRegistry, searchPattern);\n\t\treturn;\n\t}\n\n\tif (parsed.export) {\n\t\ttry {\n\t\t\tconst outputPath = parsed.messages.length > 0 ? parsed.messages[0] : undefined;\n\t\t\tconst result = exportFromFile(parsed.export, outputPath);\n\t\t\tconsole.log(`Exported to: ${result}`);\n\t\t\treturn;\n\t\t} catch (error: unknown) {\n\t\t\tconst message = error instanceof Error ? error.message : \"Failed to export session\";\n\t\t\tconsole.error(chalk.red(`Error: ${message}`));\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\tif (parsed.mode === \"rpc\" && parsed.fileArgs.length > 0) {\n\t\tconsole.error(chalk.red(\"Error: @file arguments are not supported in RPC mode\"));\n\t\tprocess.exit(1);\n\t}\n\n\tconst settingsManager = SettingsManager.create(cwd);\n\ttime(\"SettingsManager.create\");\n\tconst { initialMessage, initialImages } = await prepareInitialMessage(parsed, settingsManager.getImageAutoResize());\n\ttime(\"prepareInitialMessage\");\n\tconst isInteractive = !parsed.print && parsed.mode === undefined;\n\tconst mode = parsed.mode || \"text\";\n\tinitTheme(settingsManager.getTheme(), isInteractive);\n\ttime(\"initTheme\");\n\n\tlet scopedModels: ScopedModel[] = [];\n\tconst modelPatterns = parsed.models ?? settingsManager.getEnabledModels();\n\tif (modelPatterns && modelPatterns.length > 0) {\n\t\tscopedModels = await resolveModelScope(modelPatterns, modelRegistry);\n\t\ttime(\"resolveModelScope\");\n\t}\n\n\t// Create session manager based on CLI flags\n\tlet sessionManager = createSessionManager(parsed, cwd);\n\ttime(\"createSessionManager\");\n\n\t// Handle --resume: show session picker\n\tif (parsed.resume) {\n\t\tconst sessions = SessionManager.list(cwd, parsed.sessionDir);\n\t\ttime(\"SessionManager.list\");\n\t\tif (sessions.length === 0) {\n\t\t\tconsole.log(chalk.dim(\"No sessions found\"));\n\t\t\treturn;\n\t\t}\n\t\tconst selectedPath = await selectSession(sessions);\n\t\ttime(\"selectSession\");\n\t\tif (!selectedPath) {\n\t\t\tconsole.log(chalk.dim(\"No session selected\"));\n\t\t\treturn;\n\t\t}\n\t\tsessionManager = SessionManager.open(selectedPath);\n\t}\n\n\tconst sessionOptions = buildSessionOptions(parsed, scopedModels, sessionManager, modelRegistry, loadedHooks);\n\tsessionOptions.authStorage = authStorage;\n\tsessionOptions.modelRegistry = modelRegistry;\n\n\t// Handle CLI --api-key as runtime override (not persisted)\n\tif (parsed.apiKey) {\n\t\tif (!sessionOptions.model) {\n\t\t\tconsole.error(chalk.red(\"--api-key requires a model to be specified via --provider/--model or -m/--models\"));\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tauthStorage.setRuntimeApiKey(sessionOptions.model.provider, parsed.apiKey);\n\t}\n\n\ttime(\"buildSessionOptions\");\n\tconst { session, customToolsResult, modelFallbackMessage } = await createAgentSession(sessionOptions);\n\ttime(\"createAgentSession\");\n\n\tif (!isInteractive && !session.model) {\n\t\tconsole.error(chalk.red(\"No models available.\"));\n\t\tconsole.error(chalk.yellow(\"\\nSet an API key environment variable:\"));\n\t\tconsole.error(\" ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, etc.\");\n\t\tconsole.error(chalk.yellow(`\\nOr create ${getModelsPath()}`));\n\t\tprocess.exit(1);\n\t}\n\n\t// Clamp thinking level to model capabilities (for CLI override case)\n\tif (session.model && parsed.thinking) {\n\t\tlet effectiveThinking = parsed.thinking;\n\t\tif (!session.model.reasoning) {\n\t\t\teffectiveThinking = \"off\";\n\t\t} else if (effectiveThinking === \"xhigh\" && !supportsXhigh(session.model)) {\n\t\t\teffectiveThinking = \"high\";\n\t\t}\n\t\tif (effectiveThinking !== session.thinkingLevel) {\n\t\t\tsession.setThinkingLevel(effectiveThinking);\n\t\t}\n\t}\n\n\tif (mode === \"rpc\") {\n\t\tawait runRpcMode(session);\n\t} else if (isInteractive) {\n\t\tconst versionCheckPromise = checkForNewVersion(VERSION).catch(() => undefined);\n\t\tconst changelogMarkdown = getChangelogForDisplay(parsed, settingsManager);\n\n\t\tif (scopedModels.length > 0) {\n\t\t\tconst modelList = scopedModels\n\t\t\t\t.map((sm) => {\n\t\t\t\t\tconst thinkingStr = sm.thinkingLevel !== \"off\" ? `:${sm.thinkingLevel}` : \"\";\n\t\t\t\t\treturn `${sm.model.id}${thinkingStr}`;\n\t\t\t\t})\n\t\t\t\t.join(\", \");\n\t\t\tconsole.log(chalk.dim(`Model scope: ${modelList} ${chalk.gray(\"(Ctrl+P to cycle)\")}`));\n\t\t}\n\n\t\tconst fdPath = await ensureTool(\"fd\");\n\t\ttime(\"ensureTool(fd)\");\n\n\t\tprintTimings();\n\t\tawait runInteractiveMode(\n\t\t\tsession,\n\t\t\tVERSION,\n\t\t\tchangelogMarkdown,\n\t\t\tmodelFallbackMessage,\n\t\t\tmodelRegistry.getError(),\n\t\t\tmigratedProviders,\n\t\t\tversionCheckPromise,\n\t\t\tparsed.messages,\n\t\t\tcustomToolsResult.tools,\n\t\t\tcustomToolsResult.setUIContext,\n\t\t\tinitialMessage,\n\t\t\tinitialImages,\n\t\t\tfdPath,\n\t\t);\n\t} else {\n\t\tawait runPrintMode(session, mode, parsed.messages, initialMessage, initialImages);\n\t\tstopThemeWatcher();\n\t\tif (process.stdout.writableLength > 0) {\n\t\t\tawait new Promise<void>((resolve) => process.stdout.once(\"drain\", resolve));\n\t\t}\n\t\tprocess.exit(0);\n\t}\n}\n"]}
|
package/dist/main.js
CHANGED
|
@@ -14,6 +14,7 @@ import { listModels } from "./cli/list-models.js";
|
|
|
14
14
|
import { selectSession } from "./cli/session-picker.js";
|
|
15
15
|
import { CONFIG_DIR_NAME, getAgentDir, getModelsPath, VERSION } from "./config.js";
|
|
16
16
|
import { exportFromFile } from "./core/export-html/index.js";
|
|
17
|
+
import { discoverAndLoadHooks } from "./core/hooks/index.js";
|
|
17
18
|
import { resolveModelScope } from "./core/model-resolver.js";
|
|
18
19
|
import { createAgentSession, discoverAuthStorage, discoverModels } from "./core/sdk.js";
|
|
19
20
|
import { SessionManager } from "./core/session-manager.js";
|
|
@@ -161,7 +162,7 @@ function discoverSystemPromptFile() {
|
|
|
161
162
|
}
|
|
162
163
|
return undefined;
|
|
163
164
|
}
|
|
164
|
-
function buildSessionOptions(parsed, scopedModels, sessionManager, modelRegistry) {
|
|
165
|
+
function buildSessionOptions(parsed, scopedModels, sessionManager, modelRegistry, preloadedHooks) {
|
|
165
166
|
const options = {};
|
|
166
167
|
// Auto-discover SYSTEM.md if no CLI system prompt provided
|
|
167
168
|
const systemPromptSource = parsed.systemPrompt ?? discoverSystemPromptFile();
|
|
@@ -213,9 +214,9 @@ function buildSessionOptions(parsed, scopedModels, sessionManager, modelRegistry
|
|
|
213
214
|
if (parsed.noSkills) {
|
|
214
215
|
options.skills = [];
|
|
215
216
|
}
|
|
216
|
-
//
|
|
217
|
-
if (
|
|
218
|
-
options.
|
|
217
|
+
// Pre-loaded hooks (from early CLI flag discovery)
|
|
218
|
+
if (preloadedHooks && preloadedHooks.length > 0) {
|
|
219
|
+
options.preloadedHooks = preloadedHooks;
|
|
219
220
|
}
|
|
220
221
|
// Additional custom tool paths from CLI
|
|
221
222
|
if (parsed.customTools && parsed.customTools.length > 0) {
|
|
@@ -231,8 +232,33 @@ export async function main(args) {
|
|
|
231
232
|
const authStorage = discoverAuthStorage();
|
|
232
233
|
const modelRegistry = discoverModels(authStorage);
|
|
233
234
|
time("discoverModels");
|
|
234
|
-
|
|
235
|
+
// First pass: parse args to get --hook paths
|
|
236
|
+
const firstPass = parseArgs(args);
|
|
237
|
+
time("parseArgs-firstPass");
|
|
238
|
+
// Early load hooks to discover their CLI flags
|
|
239
|
+
const cwd = process.cwd();
|
|
240
|
+
const agentDir = getAgentDir();
|
|
241
|
+
const hookPaths = firstPass.hooks ?? [];
|
|
242
|
+
const { hooks: loadedHooks } = await discoverAndLoadHooks(hookPaths, cwd, agentDir);
|
|
243
|
+
time("discoverHookFlags");
|
|
244
|
+
// Collect all hook flags
|
|
245
|
+
const hookFlags = new Map();
|
|
246
|
+
for (const hook of loadedHooks) {
|
|
247
|
+
for (const [name, flag] of hook.flags) {
|
|
248
|
+
hookFlags.set(name, { type: flag.type });
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
// Second pass: parse args with hook flags
|
|
252
|
+
const parsed = parseArgs(args, hookFlags);
|
|
235
253
|
time("parseArgs");
|
|
254
|
+
// Pass flag values to hooks
|
|
255
|
+
for (const [name, value] of parsed.unknownFlags) {
|
|
256
|
+
for (const hook of loadedHooks) {
|
|
257
|
+
if (hook.flags.has(name)) {
|
|
258
|
+
hook.setFlagValue(name, value);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
236
262
|
if (parsed.version) {
|
|
237
263
|
console.log(VERSION);
|
|
238
264
|
return;
|
|
@@ -263,7 +289,6 @@ export async function main(args) {
|
|
|
263
289
|
console.error(chalk.red("Error: @file arguments are not supported in RPC mode"));
|
|
264
290
|
process.exit(1);
|
|
265
291
|
}
|
|
266
|
-
const cwd = process.cwd();
|
|
267
292
|
const settingsManager = SettingsManager.create(cwd);
|
|
268
293
|
time("SettingsManager.create");
|
|
269
294
|
const { initialMessage, initialImages } = await prepareInitialMessage(parsed, settingsManager.getImageAutoResize());
|
|
@@ -297,7 +322,7 @@ export async function main(args) {
|
|
|
297
322
|
}
|
|
298
323
|
sessionManager = SessionManager.open(selectedPath);
|
|
299
324
|
}
|
|
300
|
-
const sessionOptions = buildSessionOptions(parsed, scopedModels, sessionManager, modelRegistry);
|
|
325
|
+
const sessionOptions = buildSessionOptions(parsed, scopedModels, sessionManager, modelRegistry, loadedHooks);
|
|
301
326
|
sessionOptions.authStorage = authStorage;
|
|
302
327
|
sessionOptions.modelRegistry = modelRegistry;
|
|
303
328
|
// Handle CLI --api-key as runtime override (not persisted)
|
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 coding agent CLI.\n *\n * This file handles CLI argument parsing and translates them into\n * createAgentSession() options. The SDK does the heavy lifting.\n */\n\nimport { type ImageContent, supportsXhigh } from \"@mariozechner/pi-ai\";\nimport chalk from \"chalk\";\nimport { existsSync } from \"fs\";\nimport { join } from \"path\";\nimport { type Args, parseArgs, printHelp } from \"./cli/args.js\";\nimport { processFileArguments } from \"./cli/file-processor.js\";\nimport { listModels } from \"./cli/list-models.js\";\nimport { selectSession } from \"./cli/session-picker.js\";\nimport { CONFIG_DIR_NAME, getAgentDir, getModelsPath, VERSION } from \"./config.js\";\nimport type { AgentSession } from \"./core/agent-session.js\";\n\nimport type { LoadedCustomTool } from \"./core/custom-tools/index.js\";\nimport { exportFromFile } from \"./core/export-html/index.js\";\nimport type { HookUIContext } from \"./core/index.js\";\nimport type { ModelRegistry } from \"./core/model-registry.js\";\nimport { resolveModelScope, type ScopedModel } from \"./core/model-resolver.js\";\nimport { type CreateAgentSessionOptions, createAgentSession, discoverAuthStorage, discoverModels } from \"./core/sdk.js\";\nimport { SessionManager } from \"./core/session-manager.js\";\nimport { SettingsManager } from \"./core/settings-manager.js\";\nimport { resolvePromptInput } from \"./core/system-prompt.js\";\nimport { printTimings, time } from \"./core/timings.js\";\nimport { allTools } from \"./core/tools/index.js\";\nimport { runMigrations } from \"./migrations.js\";\nimport { InteractiveMode, runPrintMode, runRpcMode } from \"./modes/index.js\";\nimport { initTheme, stopThemeWatcher } from \"./modes/interactive/theme/theme.js\";\nimport { getChangelogPath, getNewEntries, parseChangelog } from \"./utils/changelog.js\";\nimport { ensureTool } from \"./utils/tools-manager.js\";\n\nasync function checkForNewVersion(currentVersion: string): Promise<string | undefined> {\n\ttry {\n\t\tconst response = await fetch(\"https://registry.npmjs.org/@mariozechner/pi-coding-agent/latest\");\n\t\tif (!response.ok) return undefined;\n\n\t\tconst data = (await response.json()) as { version?: string };\n\t\tconst latestVersion = data.version;\n\n\t\tif (latestVersion && latestVersion !== currentVersion) {\n\t\t\treturn latestVersion;\n\t\t}\n\n\t\treturn undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nasync function runInteractiveMode(\n\tsession: AgentSession,\n\tversion: string,\n\tchangelogMarkdown: string | undefined,\n\tmodelFallbackMessage: string | undefined,\n\tmodelsJsonError: string | undefined,\n\tmigratedProviders: string[],\n\tversionCheckPromise: Promise<string | undefined>,\n\tinitialMessages: string[],\n\tcustomTools: LoadedCustomTool[],\n\tsetToolUIContext: (uiContext: HookUIContext, hasUI: boolean) => void,\n\tinitialMessage?: string,\n\tinitialImages?: ImageContent[],\n\tfdPath: string | undefined = undefined,\n): Promise<void> {\n\tconst mode = new InteractiveMode(session, version, changelogMarkdown, customTools, setToolUIContext, fdPath);\n\n\tawait mode.init();\n\n\tversionCheckPromise.then((newVersion) => {\n\t\tif (newVersion) {\n\t\t\tmode.showNewVersionNotification(newVersion);\n\t\t}\n\t});\n\n\tmode.renderInitialMessages();\n\n\tif (migratedProviders.length > 0) {\n\t\tmode.showWarning(`Migrated credentials to auth.json: ${migratedProviders.join(\", \")}`);\n\t}\n\n\tif (modelsJsonError) {\n\t\tmode.showError(`models.json error: ${modelsJsonError}`);\n\t}\n\n\tif (modelFallbackMessage) {\n\t\tmode.showWarning(modelFallbackMessage);\n\t}\n\n\tif (initialMessage) {\n\t\ttry {\n\t\t\tawait session.prompt(initialMessage, { images: initialImages });\n\t\t} catch (error: unknown) {\n\t\t\tconst errorMessage = error instanceof Error ? error.message : \"Unknown error occurred\";\n\t\t\tmode.showError(errorMessage);\n\t\t}\n\t}\n\n\tfor (const message of initialMessages) {\n\t\ttry {\n\t\t\tawait session.prompt(message);\n\t\t} catch (error: unknown) {\n\t\t\tconst errorMessage = error instanceof Error ? error.message : \"Unknown error occurred\";\n\t\t\tmode.showError(errorMessage);\n\t\t}\n\t}\n\n\twhile (true) {\n\t\tconst userInput = await mode.getUserInput();\n\t\ttry {\n\t\t\tawait session.prompt(userInput);\n\t\t} catch (error: unknown) {\n\t\t\tconst errorMessage = error instanceof Error ? error.message : \"Unknown error occurred\";\n\t\t\tmode.showError(errorMessage);\n\t\t}\n\t}\n}\n\nasync function prepareInitialMessage(\n\tparsed: Args,\n\tautoResizeImages: boolean,\n): Promise<{\n\tinitialMessage?: string;\n\tinitialImages?: ImageContent[];\n}> {\n\tif (parsed.fileArgs.length === 0) {\n\t\treturn {};\n\t}\n\n\tconst { text, images } = await processFileArguments(parsed.fileArgs, { autoResizeImages });\n\n\tlet initialMessage: string;\n\tif (parsed.messages.length > 0) {\n\t\tinitialMessage = text + parsed.messages[0];\n\t\tparsed.messages.shift();\n\t} else {\n\t\tinitialMessage = text;\n\t}\n\n\treturn {\n\t\tinitialMessage,\n\t\tinitialImages: images.length > 0 ? images : undefined,\n\t};\n}\n\nfunction getChangelogForDisplay(parsed: Args, settingsManager: SettingsManager): string | undefined {\n\tif (parsed.continue || parsed.resume) {\n\t\treturn undefined;\n\t}\n\n\tconst lastVersion = settingsManager.getLastChangelogVersion();\n\tconst changelogPath = getChangelogPath();\n\tconst entries = parseChangelog(changelogPath);\n\n\tif (!lastVersion) {\n\t\tif (entries.length > 0) {\n\t\t\tsettingsManager.setLastChangelogVersion(VERSION);\n\t\t\treturn entries.map((e) => e.content).join(\"\\n\\n\");\n\t\t}\n\t} else {\n\t\tconst newEntries = getNewEntries(entries, lastVersion);\n\t\tif (newEntries.length > 0) {\n\t\t\tsettingsManager.setLastChangelogVersion(VERSION);\n\t\t\treturn newEntries.map((e) => e.content).join(\"\\n\\n\");\n\t\t}\n\t}\n\n\treturn undefined;\n}\n\nfunction createSessionManager(parsed: Args, cwd: string): SessionManager | undefined {\n\tif (parsed.noSession) {\n\t\treturn SessionManager.inMemory();\n\t}\n\tif (parsed.session) {\n\t\treturn SessionManager.open(parsed.session, parsed.sessionDir);\n\t}\n\tif (parsed.continue) {\n\t\treturn SessionManager.continueRecent(cwd, parsed.sessionDir);\n\t}\n\t// --resume is handled separately (needs picker UI)\n\t// If --session-dir provided without --continue/--resume, create new session there\n\tif (parsed.sessionDir) {\n\t\treturn SessionManager.create(cwd, parsed.sessionDir);\n\t}\n\t// Default case (new session) returns undefined, SDK will create one\n\treturn undefined;\n}\n\n/** Discover SYSTEM.md file if no CLI system prompt was provided */\nfunction discoverSystemPromptFile(): string | undefined {\n\t// Check project-local first: .pi/SYSTEM.md\n\tconst projectPath = join(process.cwd(), CONFIG_DIR_NAME, \"SYSTEM.md\");\n\tif (existsSync(projectPath)) {\n\t\treturn projectPath;\n\t}\n\n\t// Fall back to global: ~/.pi/agent/SYSTEM.md\n\tconst globalPath = join(getAgentDir(), \"SYSTEM.md\");\n\tif (existsSync(globalPath)) {\n\t\treturn globalPath;\n\t}\n\n\treturn undefined;\n}\n\nfunction buildSessionOptions(\n\tparsed: Args,\n\tscopedModels: ScopedModel[],\n\tsessionManager: SessionManager | undefined,\n\tmodelRegistry: ModelRegistry,\n): CreateAgentSessionOptions {\n\tconst options: CreateAgentSessionOptions = {};\n\n\t// Auto-discover SYSTEM.md if no CLI system prompt provided\n\tconst systemPromptSource = parsed.systemPrompt ?? discoverSystemPromptFile();\n\tconst resolvedSystemPrompt = resolvePromptInput(systemPromptSource, \"system prompt\");\n\tconst resolvedAppendPrompt = resolvePromptInput(parsed.appendSystemPrompt, \"append system prompt\");\n\n\tif (sessionManager) {\n\t\toptions.sessionManager = sessionManager;\n\t}\n\n\t// Model from CLI\n\tif (parsed.provider && parsed.model) {\n\t\tconst model = modelRegistry.find(parsed.provider, parsed.model);\n\t\tif (!model) {\n\t\t\tconsole.error(chalk.red(`Model ${parsed.provider}/${parsed.model} not found`));\n\t\t\tprocess.exit(1);\n\t\t}\n\t\toptions.model = model;\n\t} else if (scopedModels.length > 0 && !parsed.continue && !parsed.resume) {\n\t\toptions.model = scopedModels[0].model;\n\t}\n\n\t// Thinking level\n\tif (parsed.thinking) {\n\t\toptions.thinkingLevel = parsed.thinking;\n\t} else if (scopedModels.length > 0 && !parsed.continue && !parsed.resume) {\n\t\toptions.thinkingLevel = scopedModels[0].thinkingLevel;\n\t}\n\n\t// Scoped models for Ctrl+P cycling\n\tif (scopedModels.length > 0) {\n\t\toptions.scopedModels = scopedModels;\n\t}\n\n\t// API key from CLI - set in authStorage\n\t// (handled by caller before createAgentSession)\n\n\t// System prompt\n\tif (resolvedSystemPrompt && resolvedAppendPrompt) {\n\t\toptions.systemPrompt = `${resolvedSystemPrompt}\\n\\n${resolvedAppendPrompt}`;\n\t} else if (resolvedSystemPrompt) {\n\t\toptions.systemPrompt = resolvedSystemPrompt;\n\t} else if (resolvedAppendPrompt) {\n\t\toptions.systemPrompt = (defaultPrompt) => `${defaultPrompt}\\n\\n${resolvedAppendPrompt}`;\n\t}\n\n\t// Tools\n\tif (parsed.tools) {\n\t\toptions.tools = parsed.tools.map((name) => allTools[name]);\n\t}\n\n\t// Skills\n\tif (parsed.noSkills) {\n\t\toptions.skills = [];\n\t}\n\n\t// Additional hook paths from CLI\n\tif (parsed.hooks && parsed.hooks.length > 0) {\n\t\toptions.additionalHookPaths = parsed.hooks;\n\t}\n\n\t// Additional custom tool paths from CLI\n\tif (parsed.customTools && parsed.customTools.length > 0) {\n\t\toptions.additionalCustomToolPaths = parsed.customTools;\n\t}\n\n\treturn options;\n}\n\nexport async function main(args: string[]) {\n\ttime(\"start\");\n\n\t// Run migrations\n\tconst { migratedAuthProviders: migratedProviders } = runMigrations();\n\n\t// Create AuthStorage and ModelRegistry upfront\n\tconst authStorage = discoverAuthStorage();\n\tconst modelRegistry = discoverModels(authStorage);\n\ttime(\"discoverModels\");\n\n\tconst parsed = parseArgs(args);\n\ttime(\"parseArgs\");\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 !== undefined) {\n\t\tconst searchPattern = typeof parsed.listModels === \"string\" ? parsed.listModels : undefined;\n\t\tawait listModels(modelRegistry, searchPattern);\n\t\treturn;\n\t}\n\n\tif (parsed.export) {\n\t\ttry {\n\t\t\tconst outputPath = parsed.messages.length > 0 ? parsed.messages[0] : undefined;\n\t\t\tconst result = exportFromFile(parsed.export, outputPath);\n\t\t\tconsole.log(`Exported to: ${result}`);\n\t\t\treturn;\n\t\t} catch (error: unknown) {\n\t\t\tconst message = error instanceof Error ? error.message : \"Failed to export session\";\n\t\t\tconsole.error(chalk.red(`Error: ${message}`));\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\tif (parsed.mode === \"rpc\" && parsed.fileArgs.length > 0) {\n\t\tconsole.error(chalk.red(\"Error: @file arguments are not supported in RPC mode\"));\n\t\tprocess.exit(1);\n\t}\n\n\tconst cwd = process.cwd();\n\tconst settingsManager = SettingsManager.create(cwd);\n\ttime(\"SettingsManager.create\");\n\tconst { initialMessage, initialImages } = await prepareInitialMessage(parsed, settingsManager.getImageAutoResize());\n\ttime(\"prepareInitialMessage\");\n\tconst isInteractive = !parsed.print && parsed.mode === undefined;\n\tconst mode = parsed.mode || \"text\";\n\tinitTheme(settingsManager.getTheme(), isInteractive);\n\ttime(\"initTheme\");\n\n\tlet scopedModels: ScopedModel[] = [];\n\tconst modelPatterns = parsed.models ?? settingsManager.getEnabledModels();\n\tif (modelPatterns && modelPatterns.length > 0) {\n\t\tscopedModels = await resolveModelScope(modelPatterns, modelRegistry);\n\t\ttime(\"resolveModelScope\");\n\t}\n\n\t// Create session manager based on CLI flags\n\tlet sessionManager = createSessionManager(parsed, cwd);\n\ttime(\"createSessionManager\");\n\n\t// Handle --resume: show session picker\n\tif (parsed.resume) {\n\t\tconst sessions = SessionManager.list(cwd, parsed.sessionDir);\n\t\ttime(\"SessionManager.list\");\n\t\tif (sessions.length === 0) {\n\t\t\tconsole.log(chalk.dim(\"No sessions found\"));\n\t\t\treturn;\n\t\t}\n\t\tconst selectedPath = await selectSession(sessions);\n\t\ttime(\"selectSession\");\n\t\tif (!selectedPath) {\n\t\t\tconsole.log(chalk.dim(\"No session selected\"));\n\t\t\treturn;\n\t\t}\n\t\tsessionManager = SessionManager.open(selectedPath);\n\t}\n\n\tconst sessionOptions = buildSessionOptions(parsed, scopedModels, sessionManager, modelRegistry);\n\tsessionOptions.authStorage = authStorage;\n\tsessionOptions.modelRegistry = modelRegistry;\n\n\t// Handle CLI --api-key as runtime override (not persisted)\n\tif (parsed.apiKey) {\n\t\tif (!sessionOptions.model) {\n\t\t\tconsole.error(chalk.red(\"--api-key requires a model to be specified via --provider/--model or -m/--models\"));\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tauthStorage.setRuntimeApiKey(sessionOptions.model.provider, parsed.apiKey);\n\t}\n\n\ttime(\"buildSessionOptions\");\n\tconst { session, customToolsResult, modelFallbackMessage } = await createAgentSession(sessionOptions);\n\ttime(\"createAgentSession\");\n\n\tif (!isInteractive && !session.model) {\n\t\tconsole.error(chalk.red(\"No models available.\"));\n\t\tconsole.error(chalk.yellow(\"\\nSet an API key environment variable:\"));\n\t\tconsole.error(\" ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, etc.\");\n\t\tconsole.error(chalk.yellow(`\\nOr create ${getModelsPath()}`));\n\t\tprocess.exit(1);\n\t}\n\n\t// Clamp thinking level to model capabilities (for CLI override case)\n\tif (session.model && parsed.thinking) {\n\t\tlet effectiveThinking = parsed.thinking;\n\t\tif (!session.model.reasoning) {\n\t\t\teffectiveThinking = \"off\";\n\t\t} else if (effectiveThinking === \"xhigh\" && !supportsXhigh(session.model)) {\n\t\t\teffectiveThinking = \"high\";\n\t\t}\n\t\tif (effectiveThinking !== session.thinkingLevel) {\n\t\t\tsession.setThinkingLevel(effectiveThinking);\n\t\t}\n\t}\n\n\tif (mode === \"rpc\") {\n\t\tawait runRpcMode(session);\n\t} else if (isInteractive) {\n\t\tconst versionCheckPromise = checkForNewVersion(VERSION).catch(() => undefined);\n\t\tconst changelogMarkdown = getChangelogForDisplay(parsed, settingsManager);\n\n\t\tif (scopedModels.length > 0) {\n\t\t\tconst modelList = scopedModels\n\t\t\t\t.map((sm) => {\n\t\t\t\t\tconst thinkingStr = sm.thinkingLevel !== \"off\" ? `:${sm.thinkingLevel}` : \"\";\n\t\t\t\t\treturn `${sm.model.id}${thinkingStr}`;\n\t\t\t\t})\n\t\t\t\t.join(\", \");\n\t\t\tconsole.log(chalk.dim(`Model scope: ${modelList} ${chalk.gray(\"(Ctrl+P to cycle)\")}`));\n\t\t}\n\n\t\tconst fdPath = await ensureTool(\"fd\");\n\t\ttime(\"ensureTool(fd)\");\n\n\t\tprintTimings();\n\t\tawait runInteractiveMode(\n\t\t\tsession,\n\t\t\tVERSION,\n\t\t\tchangelogMarkdown,\n\t\t\tmodelFallbackMessage,\n\t\t\tmodelRegistry.getError(),\n\t\t\tmigratedProviders,\n\t\t\tversionCheckPromise,\n\t\t\tparsed.messages,\n\t\t\tcustomToolsResult.tools,\n\t\t\tcustomToolsResult.setUIContext,\n\t\t\tinitialMessage,\n\t\t\tinitialImages,\n\t\t\tfdPath,\n\t\t);\n\t} else {\n\t\tawait runPrintMode(session, mode, parsed.messages, initialMessage, initialImages);\n\t\tstopThemeWatcher();\n\t\tif (process.stdout.writableLength > 0) {\n\t\t\tawait new Promise<void>((resolve) => process.stdout.once(\"drain\", resolve));\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 coding agent CLI.\n *\n * This file handles CLI argument parsing and translates them into\n * createAgentSession() options. The SDK does the heavy lifting.\n */\n\nimport { type ImageContent, supportsXhigh } from \"@mariozechner/pi-ai\";\nimport chalk from \"chalk\";\nimport { existsSync } from \"fs\";\nimport { join } from \"path\";\nimport { type Args, parseArgs, printHelp } from \"./cli/args.js\";\nimport { processFileArguments } from \"./cli/file-processor.js\";\nimport { listModels } from \"./cli/list-models.js\";\nimport { selectSession } from \"./cli/session-picker.js\";\nimport { CONFIG_DIR_NAME, getAgentDir, getModelsPath, VERSION } from \"./config.js\";\nimport type { AgentSession } from \"./core/agent-session.js\";\n\nimport type { LoadedCustomTool } from \"./core/custom-tools/index.js\";\nimport { exportFromFile } from \"./core/export-html/index.js\";\nimport { discoverAndLoadHooks } from \"./core/hooks/index.js\";\nimport type { HookUIContext } from \"./core/index.js\";\nimport type { ModelRegistry } from \"./core/model-registry.js\";\nimport { resolveModelScope, type ScopedModel } from \"./core/model-resolver.js\";\nimport { type CreateAgentSessionOptions, createAgentSession, discoverAuthStorage, discoverModels } from \"./core/sdk.js\";\nimport { SessionManager } from \"./core/session-manager.js\";\nimport { SettingsManager } from \"./core/settings-manager.js\";\nimport { resolvePromptInput } from \"./core/system-prompt.js\";\nimport { printTimings, time } from \"./core/timings.js\";\nimport { allTools } from \"./core/tools/index.js\";\nimport { runMigrations } from \"./migrations.js\";\nimport { InteractiveMode, runPrintMode, runRpcMode } from \"./modes/index.js\";\nimport { initTheme, stopThemeWatcher } from \"./modes/interactive/theme/theme.js\";\nimport { getChangelogPath, getNewEntries, parseChangelog } from \"./utils/changelog.js\";\nimport { ensureTool } from \"./utils/tools-manager.js\";\n\nasync function checkForNewVersion(currentVersion: string): Promise<string | undefined> {\n\ttry {\n\t\tconst response = await fetch(\"https://registry.npmjs.org/@mariozechner/pi-coding-agent/latest\");\n\t\tif (!response.ok) return undefined;\n\n\t\tconst data = (await response.json()) as { version?: string };\n\t\tconst latestVersion = data.version;\n\n\t\tif (latestVersion && latestVersion !== currentVersion) {\n\t\t\treturn latestVersion;\n\t\t}\n\n\t\treturn undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nasync function runInteractiveMode(\n\tsession: AgentSession,\n\tversion: string,\n\tchangelogMarkdown: string | undefined,\n\tmodelFallbackMessage: string | undefined,\n\tmodelsJsonError: string | undefined,\n\tmigratedProviders: string[],\n\tversionCheckPromise: Promise<string | undefined>,\n\tinitialMessages: string[],\n\tcustomTools: LoadedCustomTool[],\n\tsetToolUIContext: (uiContext: HookUIContext, hasUI: boolean) => void,\n\tinitialMessage?: string,\n\tinitialImages?: ImageContent[],\n\tfdPath: string | undefined = undefined,\n): Promise<void> {\n\tconst mode = new InteractiveMode(session, version, changelogMarkdown, customTools, setToolUIContext, fdPath);\n\n\tawait mode.init();\n\n\tversionCheckPromise.then((newVersion) => {\n\t\tif (newVersion) {\n\t\t\tmode.showNewVersionNotification(newVersion);\n\t\t}\n\t});\n\n\tmode.renderInitialMessages();\n\n\tif (migratedProviders.length > 0) {\n\t\tmode.showWarning(`Migrated credentials to auth.json: ${migratedProviders.join(\", \")}`);\n\t}\n\n\tif (modelsJsonError) {\n\t\tmode.showError(`models.json error: ${modelsJsonError}`);\n\t}\n\n\tif (modelFallbackMessage) {\n\t\tmode.showWarning(modelFallbackMessage);\n\t}\n\n\tif (initialMessage) {\n\t\ttry {\n\t\t\tawait session.prompt(initialMessage, { images: initialImages });\n\t\t} catch (error: unknown) {\n\t\t\tconst errorMessage = error instanceof Error ? error.message : \"Unknown error occurred\";\n\t\t\tmode.showError(errorMessage);\n\t\t}\n\t}\n\n\tfor (const message of initialMessages) {\n\t\ttry {\n\t\t\tawait session.prompt(message);\n\t\t} catch (error: unknown) {\n\t\t\tconst errorMessage = error instanceof Error ? error.message : \"Unknown error occurred\";\n\t\t\tmode.showError(errorMessage);\n\t\t}\n\t}\n\n\twhile (true) {\n\t\tconst userInput = await mode.getUserInput();\n\t\ttry {\n\t\t\tawait session.prompt(userInput);\n\t\t} catch (error: unknown) {\n\t\t\tconst errorMessage = error instanceof Error ? error.message : \"Unknown error occurred\";\n\t\t\tmode.showError(errorMessage);\n\t\t}\n\t}\n}\n\nasync function prepareInitialMessage(\n\tparsed: Args,\n\tautoResizeImages: boolean,\n): Promise<{\n\tinitialMessage?: string;\n\tinitialImages?: ImageContent[];\n}> {\n\tif (parsed.fileArgs.length === 0) {\n\t\treturn {};\n\t}\n\n\tconst { text, images } = await processFileArguments(parsed.fileArgs, { autoResizeImages });\n\n\tlet initialMessage: string;\n\tif (parsed.messages.length > 0) {\n\t\tinitialMessage = text + parsed.messages[0];\n\t\tparsed.messages.shift();\n\t} else {\n\t\tinitialMessage = text;\n\t}\n\n\treturn {\n\t\tinitialMessage,\n\t\tinitialImages: images.length > 0 ? images : undefined,\n\t};\n}\n\nfunction getChangelogForDisplay(parsed: Args, settingsManager: SettingsManager): string | undefined {\n\tif (parsed.continue || parsed.resume) {\n\t\treturn undefined;\n\t}\n\n\tconst lastVersion = settingsManager.getLastChangelogVersion();\n\tconst changelogPath = getChangelogPath();\n\tconst entries = parseChangelog(changelogPath);\n\n\tif (!lastVersion) {\n\t\tif (entries.length > 0) {\n\t\t\tsettingsManager.setLastChangelogVersion(VERSION);\n\t\t\treturn entries.map((e) => e.content).join(\"\\n\\n\");\n\t\t}\n\t} else {\n\t\tconst newEntries = getNewEntries(entries, lastVersion);\n\t\tif (newEntries.length > 0) {\n\t\t\tsettingsManager.setLastChangelogVersion(VERSION);\n\t\t\treturn newEntries.map((e) => e.content).join(\"\\n\\n\");\n\t\t}\n\t}\n\n\treturn undefined;\n}\n\nfunction createSessionManager(parsed: Args, cwd: string): SessionManager | undefined {\n\tif (parsed.noSession) {\n\t\treturn SessionManager.inMemory();\n\t}\n\tif (parsed.session) {\n\t\treturn SessionManager.open(parsed.session, parsed.sessionDir);\n\t}\n\tif (parsed.continue) {\n\t\treturn SessionManager.continueRecent(cwd, parsed.sessionDir);\n\t}\n\t// --resume is handled separately (needs picker UI)\n\t// If --session-dir provided without --continue/--resume, create new session there\n\tif (parsed.sessionDir) {\n\t\treturn SessionManager.create(cwd, parsed.sessionDir);\n\t}\n\t// Default case (new session) returns undefined, SDK will create one\n\treturn undefined;\n}\n\n/** Discover SYSTEM.md file if no CLI system prompt was provided */\nfunction discoverSystemPromptFile(): string | undefined {\n\t// Check project-local first: .pi/SYSTEM.md\n\tconst projectPath = join(process.cwd(), CONFIG_DIR_NAME, \"SYSTEM.md\");\n\tif (existsSync(projectPath)) {\n\t\treturn projectPath;\n\t}\n\n\t// Fall back to global: ~/.pi/agent/SYSTEM.md\n\tconst globalPath = join(getAgentDir(), \"SYSTEM.md\");\n\tif (existsSync(globalPath)) {\n\t\treturn globalPath;\n\t}\n\n\treturn undefined;\n}\n\nfunction buildSessionOptions(\n\tparsed: Args,\n\tscopedModels: ScopedModel[],\n\tsessionManager: SessionManager | undefined,\n\tmodelRegistry: ModelRegistry,\n\tpreloadedHooks?: import(\"./core/hooks/index.js\").LoadedHook[],\n): CreateAgentSessionOptions {\n\tconst options: CreateAgentSessionOptions = {};\n\n\t// Auto-discover SYSTEM.md if no CLI system prompt provided\n\tconst systemPromptSource = parsed.systemPrompt ?? discoverSystemPromptFile();\n\tconst resolvedSystemPrompt = resolvePromptInput(systemPromptSource, \"system prompt\");\n\tconst resolvedAppendPrompt = resolvePromptInput(parsed.appendSystemPrompt, \"append system prompt\");\n\n\tif (sessionManager) {\n\t\toptions.sessionManager = sessionManager;\n\t}\n\n\t// Model from CLI\n\tif (parsed.provider && parsed.model) {\n\t\tconst model = modelRegistry.find(parsed.provider, parsed.model);\n\t\tif (!model) {\n\t\t\tconsole.error(chalk.red(`Model ${parsed.provider}/${parsed.model} not found`));\n\t\t\tprocess.exit(1);\n\t\t}\n\t\toptions.model = model;\n\t} else if (scopedModels.length > 0 && !parsed.continue && !parsed.resume) {\n\t\toptions.model = scopedModels[0].model;\n\t}\n\n\t// Thinking level\n\tif (parsed.thinking) {\n\t\toptions.thinkingLevel = parsed.thinking;\n\t} else if (scopedModels.length > 0 && !parsed.continue && !parsed.resume) {\n\t\toptions.thinkingLevel = scopedModels[0].thinkingLevel;\n\t}\n\n\t// Scoped models for Ctrl+P cycling\n\tif (scopedModels.length > 0) {\n\t\toptions.scopedModels = scopedModels;\n\t}\n\n\t// API key from CLI - set in authStorage\n\t// (handled by caller before createAgentSession)\n\n\t// System prompt\n\tif (resolvedSystemPrompt && resolvedAppendPrompt) {\n\t\toptions.systemPrompt = `${resolvedSystemPrompt}\\n\\n${resolvedAppendPrompt}`;\n\t} else if (resolvedSystemPrompt) {\n\t\toptions.systemPrompt = resolvedSystemPrompt;\n\t} else if (resolvedAppendPrompt) {\n\t\toptions.systemPrompt = (defaultPrompt) => `${defaultPrompt}\\n\\n${resolvedAppendPrompt}`;\n\t}\n\n\t// Tools\n\tif (parsed.tools) {\n\t\toptions.tools = parsed.tools.map((name) => allTools[name]);\n\t}\n\n\t// Skills\n\tif (parsed.noSkills) {\n\t\toptions.skills = [];\n\t}\n\n\t// Pre-loaded hooks (from early CLI flag discovery)\n\tif (preloadedHooks && preloadedHooks.length > 0) {\n\t\toptions.preloadedHooks = preloadedHooks;\n\t}\n\n\t// Additional custom tool paths from CLI\n\tif (parsed.customTools && parsed.customTools.length > 0) {\n\t\toptions.additionalCustomToolPaths = parsed.customTools;\n\t}\n\n\treturn options;\n}\n\nexport async function main(args: string[]) {\n\ttime(\"start\");\n\n\t// Run migrations\n\tconst { migratedAuthProviders: migratedProviders } = runMigrations();\n\n\t// Create AuthStorage and ModelRegistry upfront\n\tconst authStorage = discoverAuthStorage();\n\tconst modelRegistry = discoverModels(authStorage);\n\ttime(\"discoverModels\");\n\n\t// First pass: parse args to get --hook paths\n\tconst firstPass = parseArgs(args);\n\ttime(\"parseArgs-firstPass\");\n\n\t// Early load hooks to discover their CLI flags\n\tconst cwd = process.cwd();\n\tconst agentDir = getAgentDir();\n\tconst hookPaths = firstPass.hooks ?? [];\n\tconst { hooks: loadedHooks } = await discoverAndLoadHooks(hookPaths, cwd, agentDir);\n\ttime(\"discoverHookFlags\");\n\n\t// Collect all hook flags\n\tconst hookFlags = new Map<string, { type: \"boolean\" | \"string\" }>();\n\tfor (const hook of loadedHooks) {\n\t\tfor (const [name, flag] of hook.flags) {\n\t\t\thookFlags.set(name, { type: flag.type });\n\t\t}\n\t}\n\n\t// Second pass: parse args with hook flags\n\tconst parsed = parseArgs(args, hookFlags);\n\ttime(\"parseArgs\");\n\n\t// Pass flag values to hooks\n\tfor (const [name, value] of parsed.unknownFlags) {\n\t\tfor (const hook of loadedHooks) {\n\t\t\tif (hook.flags.has(name)) {\n\t\t\t\thook.setFlagValue(name, value);\n\t\t\t}\n\t\t}\n\t}\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 !== undefined) {\n\t\tconst searchPattern = typeof parsed.listModels === \"string\" ? parsed.listModels : undefined;\n\t\tawait listModels(modelRegistry, searchPattern);\n\t\treturn;\n\t}\n\n\tif (parsed.export) {\n\t\ttry {\n\t\t\tconst outputPath = parsed.messages.length > 0 ? parsed.messages[0] : undefined;\n\t\t\tconst result = exportFromFile(parsed.export, outputPath);\n\t\t\tconsole.log(`Exported to: ${result}`);\n\t\t\treturn;\n\t\t} catch (error: unknown) {\n\t\t\tconst message = error instanceof Error ? error.message : \"Failed to export session\";\n\t\t\tconsole.error(chalk.red(`Error: ${message}`));\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\tif (parsed.mode === \"rpc\" && parsed.fileArgs.length > 0) {\n\t\tconsole.error(chalk.red(\"Error: @file arguments are not supported in RPC mode\"));\n\t\tprocess.exit(1);\n\t}\n\n\tconst settingsManager = SettingsManager.create(cwd);\n\ttime(\"SettingsManager.create\");\n\tconst { initialMessage, initialImages } = await prepareInitialMessage(parsed, settingsManager.getImageAutoResize());\n\ttime(\"prepareInitialMessage\");\n\tconst isInteractive = !parsed.print && parsed.mode === undefined;\n\tconst mode = parsed.mode || \"text\";\n\tinitTheme(settingsManager.getTheme(), isInteractive);\n\ttime(\"initTheme\");\n\n\tlet scopedModels: ScopedModel[] = [];\n\tconst modelPatterns = parsed.models ?? settingsManager.getEnabledModels();\n\tif (modelPatterns && modelPatterns.length > 0) {\n\t\tscopedModels = await resolveModelScope(modelPatterns, modelRegistry);\n\t\ttime(\"resolveModelScope\");\n\t}\n\n\t// Create session manager based on CLI flags\n\tlet sessionManager = createSessionManager(parsed, cwd);\n\ttime(\"createSessionManager\");\n\n\t// Handle --resume: show session picker\n\tif (parsed.resume) {\n\t\tconst sessions = SessionManager.list(cwd, parsed.sessionDir);\n\t\ttime(\"SessionManager.list\");\n\t\tif (sessions.length === 0) {\n\t\t\tconsole.log(chalk.dim(\"No sessions found\"));\n\t\t\treturn;\n\t\t}\n\t\tconst selectedPath = await selectSession(sessions);\n\t\ttime(\"selectSession\");\n\t\tif (!selectedPath) {\n\t\t\tconsole.log(chalk.dim(\"No session selected\"));\n\t\t\treturn;\n\t\t}\n\t\tsessionManager = SessionManager.open(selectedPath);\n\t}\n\n\tconst sessionOptions = buildSessionOptions(parsed, scopedModels, sessionManager, modelRegistry, loadedHooks);\n\tsessionOptions.authStorage = authStorage;\n\tsessionOptions.modelRegistry = modelRegistry;\n\n\t// Handle CLI --api-key as runtime override (not persisted)\n\tif (parsed.apiKey) {\n\t\tif (!sessionOptions.model) {\n\t\t\tconsole.error(chalk.red(\"--api-key requires a model to be specified via --provider/--model or -m/--models\"));\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tauthStorage.setRuntimeApiKey(sessionOptions.model.provider, parsed.apiKey);\n\t}\n\n\ttime(\"buildSessionOptions\");\n\tconst { session, customToolsResult, modelFallbackMessage } = await createAgentSession(sessionOptions);\n\ttime(\"createAgentSession\");\n\n\tif (!isInteractive && !session.model) {\n\t\tconsole.error(chalk.red(\"No models available.\"));\n\t\tconsole.error(chalk.yellow(\"\\nSet an API key environment variable:\"));\n\t\tconsole.error(\" ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, etc.\");\n\t\tconsole.error(chalk.yellow(`\\nOr create ${getModelsPath()}`));\n\t\tprocess.exit(1);\n\t}\n\n\t// Clamp thinking level to model capabilities (for CLI override case)\n\tif (session.model && parsed.thinking) {\n\t\tlet effectiveThinking = parsed.thinking;\n\t\tif (!session.model.reasoning) {\n\t\t\teffectiveThinking = \"off\";\n\t\t} else if (effectiveThinking === \"xhigh\" && !supportsXhigh(session.model)) {\n\t\t\teffectiveThinking = \"high\";\n\t\t}\n\t\tif (effectiveThinking !== session.thinkingLevel) {\n\t\t\tsession.setThinkingLevel(effectiveThinking);\n\t\t}\n\t}\n\n\tif (mode === \"rpc\") {\n\t\tawait runRpcMode(session);\n\t} else if (isInteractive) {\n\t\tconst versionCheckPromise = checkForNewVersion(VERSION).catch(() => undefined);\n\t\tconst changelogMarkdown = getChangelogForDisplay(parsed, settingsManager);\n\n\t\tif (scopedModels.length > 0) {\n\t\t\tconst modelList = scopedModels\n\t\t\t\t.map((sm) => {\n\t\t\t\t\tconst thinkingStr = sm.thinkingLevel !== \"off\" ? `:${sm.thinkingLevel}` : \"\";\n\t\t\t\t\treturn `${sm.model.id}${thinkingStr}`;\n\t\t\t\t})\n\t\t\t\t.join(\", \");\n\t\t\tconsole.log(chalk.dim(`Model scope: ${modelList} ${chalk.gray(\"(Ctrl+P to cycle)\")}`));\n\t\t}\n\n\t\tconst fdPath = await ensureTool(\"fd\");\n\t\ttime(\"ensureTool(fd)\");\n\n\t\tprintTimings();\n\t\tawait runInteractiveMode(\n\t\t\tsession,\n\t\t\tVERSION,\n\t\t\tchangelogMarkdown,\n\t\t\tmodelFallbackMessage,\n\t\t\tmodelRegistry.getError(),\n\t\t\tmigratedProviders,\n\t\t\tversionCheckPromise,\n\t\t\tparsed.messages,\n\t\t\tcustomToolsResult.tools,\n\t\t\tcustomToolsResult.setUIContext,\n\t\t\tinitialMessage,\n\t\t\tinitialImages,\n\t\t\tfdPath,\n\t\t);\n\t} else {\n\t\tawait runPrintMode(session, mode, parsed.messages, initialMessage, initialImages);\n\t\tstopThemeWatcher();\n\t\tif (process.stdout.writableLength > 0) {\n\t\t\tawait new Promise<void>((resolve) => process.stdout.once(\"drain\", resolve));\n\t\t}\n\t\tprocess.exit(0);\n\t}\n}\n"]}
|
|
@@ -9,6 +9,8 @@ export declare class CustomEditor extends Editor {
|
|
|
9
9
|
onEscape?: () => void;
|
|
10
10
|
onCtrlD?: () => void;
|
|
11
11
|
onPasteImage?: () => void;
|
|
12
|
+
/** Handler for hook-registered shortcuts. Returns true if handled. */
|
|
13
|
+
onHookShortcut?: (data: string) => boolean;
|
|
12
14
|
constructor(theme: EditorTheme, keybindings: KeybindingsManager);
|
|
13
15
|
/**
|
|
14
16
|
* Register a handler for an app action.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom-editor.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/custom-editor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,WAAW,EAAc,MAAM,sBAAsB,CAAC;AAC5E,OAAO,KAAK,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAElF;;GAEG;AACH,qBAAa,YAAa,SAAQ,MAAM;IACvC,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,cAAc,CAAyC;IAGxD,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"custom-editor.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/custom-editor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,WAAW,EAAc,MAAM,sBAAsB,CAAC;AAC5E,OAAO,KAAK,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAElF;;GAEG;AACH,qBAAa,YAAa,SAAQ,MAAM;IACvC,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,cAAc,CAAyC;IAGxD,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IACjC,sEAAsE;IAC/D,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAElD,YAAY,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,kBAAkB,EAG9D;IAED;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI,CAErD;IAED,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAgD9B;CACD","sourcesContent":["import { Editor, type EditorTheme, matchesKey } from \"@mariozechner/pi-tui\";\nimport type { AppAction, KeybindingsManager } from \"../../../core/keybindings.js\";\n\n/**\n * Custom editor that handles app-level keybindings for coding-agent.\n */\nexport class CustomEditor extends Editor {\n\tprivate keybindings: KeybindingsManager;\n\tprivate actionHandlers: Map<AppAction, () => void> = new Map();\n\n\t// Special handlers that can be dynamically replaced\n\tpublic onEscape?: () => void;\n\tpublic onCtrlD?: () => void;\n\tpublic onPasteImage?: () => void;\n\t/** Handler for hook-registered shortcuts. Returns true if handled. */\n\tpublic onHookShortcut?: (data: string) => boolean;\n\n\tconstructor(theme: EditorTheme, keybindings: KeybindingsManager) {\n\t\tsuper(theme);\n\t\tthis.keybindings = keybindings;\n\t}\n\n\t/**\n\t * Register a handler for an app action.\n\t */\n\tonAction(action: AppAction, handler: () => void): void {\n\t\tthis.actionHandlers.set(action, handler);\n\t}\n\n\thandleInput(data: string): void {\n\t\t// Check hook-registered shortcuts first\n\t\tif (this.onHookShortcut?.(data)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Check for Ctrl+V to handle clipboard image paste\n\t\tif (matchesKey(data, \"ctrl+v\")) {\n\t\t\tthis.onPasteImage?.();\n\t\t\treturn;\n\t\t}\n\n\t\t// Check app keybindings first\n\n\t\t// Escape/interrupt - only if autocomplete is NOT active\n\t\tif (this.keybindings.matches(data, \"interrupt\")) {\n\t\t\tif (!this.isShowingAutocomplete()) {\n\t\t\t\t// Use dynamic onEscape if set, otherwise registered handler\n\t\t\t\tconst handler = this.onEscape ?? this.actionHandlers.get(\"interrupt\");\n\t\t\t\tif (handler) {\n\t\t\t\t\thandler();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Let parent handle escape for autocomplete cancellation\n\t\t\tsuper.handleInput(data);\n\t\t\treturn;\n\t\t}\n\n\t\t// Exit (Ctrl+D) - only when editor is empty\n\t\tif (this.keybindings.matches(data, \"exit\")) {\n\t\t\tif (this.getText().length === 0) {\n\t\t\t\tconst handler = this.onCtrlD ?? this.actionHandlers.get(\"exit\");\n\t\t\t\tif (handler) handler();\n\t\t\t}\n\t\t\treturn; // Always consume\n\t\t}\n\n\t\t// Check all other app actions\n\t\tfor (const [action, handler] of this.actionHandlers) {\n\t\t\tif (action !== \"interrupt\" && action !== \"exit\" && this.keybindings.matches(data, action)) {\n\t\t\t\thandler();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// Pass to parent for editor handling\n\t\tsuper.handleInput(data);\n\t}\n}\n"]}
|
|
@@ -9,6 +9,8 @@ export class CustomEditor extends Editor {
|
|
|
9
9
|
onEscape;
|
|
10
10
|
onCtrlD;
|
|
11
11
|
onPasteImage;
|
|
12
|
+
/** Handler for hook-registered shortcuts. Returns true if handled. */
|
|
13
|
+
onHookShortcut;
|
|
12
14
|
constructor(theme, keybindings) {
|
|
13
15
|
super(theme);
|
|
14
16
|
this.keybindings = keybindings;
|
|
@@ -20,6 +22,10 @@ export class CustomEditor extends Editor {
|
|
|
20
22
|
this.actionHandlers.set(action, handler);
|
|
21
23
|
}
|
|
22
24
|
handleInput(data) {
|
|
25
|
+
// Check hook-registered shortcuts first
|
|
26
|
+
if (this.onHookShortcut?.(data)) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
23
29
|
// Check for Ctrl+V to handle clipboard image paste
|
|
24
30
|
if (matchesKey(data, "ctrl+v")) {
|
|
25
31
|
this.onPasteImage?.();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom-editor.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/custom-editor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAoB,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAG5E;;GAEG;AACH,MAAM,OAAO,YAAa,SAAQ,MAAM;IAC/B,WAAW,CAAqB;IAChC,cAAc,GAA+B,IAAI,GAAG,EAAE,CAAC;IAE/D,oDAAoD;IAC7C,QAAQ,CAAc;IACtB,OAAO,CAAc;IACrB,YAAY,CAAc;
|
|
1
|
+
{"version":3,"file":"custom-editor.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/custom-editor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAoB,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAG5E;;GAEG;AACH,MAAM,OAAO,YAAa,SAAQ,MAAM;IAC/B,WAAW,CAAqB;IAChC,cAAc,GAA+B,IAAI,GAAG,EAAE,CAAC;IAE/D,oDAAoD;IAC7C,QAAQ,CAAc;IACtB,OAAO,CAAc;IACrB,YAAY,CAAc;IACjC,sEAAsE;IAC/D,cAAc,CAA6B;IAElD,YAAY,KAAkB,EAAE,WAA+B,EAAE;QAChE,KAAK,CAAC,KAAK,CAAC,CAAC;QACb,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IAAA,CAC/B;IAED;;OAEG;IACH,QAAQ,CAAC,MAAiB,EAAE,OAAmB,EAAQ;QACtD,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAA,CACzC;IAED,WAAW,CAAC,IAAY,EAAQ;QAC/B,wCAAwC;QACxC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YACjC,OAAO;QACR,CAAC;QAED,mDAAmD;QACnD,IAAI,UAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,CAAC;YAChC,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;YACtB,OAAO;QACR,CAAC;QAED,8BAA8B;QAE9B,wDAAwD;QACxD,IAAI,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,CAAC;YACjD,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE,EAAE,CAAC;gBACnC,4DAA4D;gBAC5D,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;gBACtE,IAAI,OAAO,EAAE,CAAC;oBACb,OAAO,EAAE,CAAC;oBACV,OAAO;gBACR,CAAC;YACF,CAAC;YACD,yDAAyD;YACzD,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YACxB,OAAO;QACR,CAAC;QAED,4CAA4C;QAC5C,IAAI,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;YAC5C,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACjC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBAChE,IAAI,OAAO;oBAAE,OAAO,EAAE,CAAC;YACxB,CAAC;YACD,OAAO,CAAC,iBAAiB;QAC1B,CAAC;QAED,8BAA8B;QAC9B,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACrD,IAAI,MAAM,KAAK,WAAW,IAAI,MAAM,KAAK,MAAM,IAAI,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;gBAC3F,OAAO,EAAE,CAAC;gBACV,OAAO;YACR,CAAC;QACF,CAAC;QAED,qCAAqC;QACrC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAAA,CACxB;CACD","sourcesContent":["import { Editor, type EditorTheme, matchesKey } from \"@mariozechner/pi-tui\";\nimport type { AppAction, KeybindingsManager } from \"../../../core/keybindings.js\";\n\n/**\n * Custom editor that handles app-level keybindings for coding-agent.\n */\nexport class CustomEditor extends Editor {\n\tprivate keybindings: KeybindingsManager;\n\tprivate actionHandlers: Map<AppAction, () => void> = new Map();\n\n\t// Special handlers that can be dynamically replaced\n\tpublic onEscape?: () => void;\n\tpublic onCtrlD?: () => void;\n\tpublic onPasteImage?: () => void;\n\t/** Handler for hook-registered shortcuts. Returns true if handled. */\n\tpublic onHookShortcut?: (data: string) => boolean;\n\n\tconstructor(theme: EditorTheme, keybindings: KeybindingsManager) {\n\t\tsuper(theme);\n\t\tthis.keybindings = keybindings;\n\t}\n\n\t/**\n\t * Register a handler for an app action.\n\t */\n\tonAction(action: AppAction, handler: () => void): void {\n\t\tthis.actionHandlers.set(action, handler);\n\t}\n\n\thandleInput(data: string): void {\n\t\t// Check hook-registered shortcuts first\n\t\tif (this.onHookShortcut?.(data)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Check for Ctrl+V to handle clipboard image paste\n\t\tif (matchesKey(data, \"ctrl+v\")) {\n\t\t\tthis.onPasteImage?.();\n\t\t\treturn;\n\t\t}\n\n\t\t// Check app keybindings first\n\n\t\t// Escape/interrupt - only if autocomplete is NOT active\n\t\tif (this.keybindings.matches(data, \"interrupt\")) {\n\t\t\tif (!this.isShowingAutocomplete()) {\n\t\t\t\t// Use dynamic onEscape if set, otherwise registered handler\n\t\t\t\tconst handler = this.onEscape ?? this.actionHandlers.get(\"interrupt\");\n\t\t\t\tif (handler) {\n\t\t\t\t\thandler();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Let parent handle escape for autocomplete cancellation\n\t\t\tsuper.handleInput(data);\n\t\t\treturn;\n\t\t}\n\n\t\t// Exit (Ctrl+D) - only when editor is empty\n\t\tif (this.keybindings.matches(data, \"exit\")) {\n\t\t\tif (this.getText().length === 0) {\n\t\t\t\tconst handler = this.onCtrlD ?? this.actionHandlers.get(\"exit\");\n\t\t\t\tif (handler) handler();\n\t\t\t}\n\t\t\treturn; // Always consume\n\t\t}\n\n\t\t// Check all other app actions\n\t\tfor (const [action, handler] of this.actionHandlers) {\n\t\t\tif (action !== \"interrupt\" && action !== \"exit\" && this.keybindings.matches(data, action)) {\n\t\t\t\thandler();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// Pass to parent for editor handling\n\t\tsuper.handleInput(data);\n\t}\n}\n"]}
|
|
@@ -41,9 +41,9 @@ export declare class InteractiveMode {
|
|
|
41
41
|
private hookSelector;
|
|
42
42
|
private hookInput;
|
|
43
43
|
private hookEditor;
|
|
44
|
+
private hookWidgets;
|
|
45
|
+
private widgetContainer;
|
|
44
46
|
private customTools;
|
|
45
|
-
private clipboardImages;
|
|
46
|
-
private clipboardImageCounter;
|
|
47
47
|
private get agent();
|
|
48
48
|
private get sessionManager();
|
|
49
49
|
private get settingsManager();
|
|
@@ -55,10 +55,27 @@ export declare class InteractiveMode {
|
|
|
55
55
|
* Show a tool error in the chat.
|
|
56
56
|
*/
|
|
57
57
|
private showToolError;
|
|
58
|
+
/**
|
|
59
|
+
* Set up keyboard shortcuts registered by hooks.
|
|
60
|
+
*/
|
|
61
|
+
private setupHookShortcuts;
|
|
58
62
|
/**
|
|
59
63
|
* Set hook status text in the footer.
|
|
60
64
|
*/
|
|
61
65
|
private setHookStatus;
|
|
66
|
+
/**
|
|
67
|
+
* Set a hook widget (string array or custom component).
|
|
68
|
+
*/
|
|
69
|
+
private setHookWidget;
|
|
70
|
+
private static readonly MAX_WIDGET_LINES;
|
|
71
|
+
/**
|
|
72
|
+
* Render all hook widgets to the widget container.
|
|
73
|
+
*/
|
|
74
|
+
private renderWidgets;
|
|
75
|
+
/**
|
|
76
|
+
* Create the HookUIContext for hooks and tools.
|
|
77
|
+
*/
|
|
78
|
+
private createHookUIContext;
|
|
62
79
|
/**
|
|
63
80
|
* Show a selector for hooks.
|
|
64
81
|
*/
|
|
@@ -99,10 +116,6 @@ export declare class InteractiveMode {
|
|
|
99
116
|
*/
|
|
100
117
|
private setupKeyHandlers;
|
|
101
118
|
private handleClipboardImagePaste;
|
|
102
|
-
/**
|
|
103
|
-
* Replace [image #N] markers with actual file paths and clear the image map.
|
|
104
|
-
*/
|
|
105
|
-
private replaceImageMarkers;
|
|
106
119
|
private setupEditorSubmitHandler;
|
|
107
120
|
private subscribeToAgent;
|
|
108
121
|
private handleEvent;
|