@earendil-works/pi-coding-agent 0.86.0 → 0.86.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +1 -0
  3. package/dist/bundle/chunks/{chunk-7YM6BE7Y.js → chunk-CMRUVXTE.js} +23 -22
  4. package/dist/bundle/chunks/{chunk-7IOYH2SY.js → chunk-HTEQD2HM.js} +1 -1
  5. package/dist/bundle/chunks/meta.js +2 -0
  6. package/dist/bundle/chunks/{openai-completions-KQPOPEVM.js → openai-completions-CYGM3XXP.js} +1 -1
  7. package/dist/bundle/chunks/{virtual-modules-XW5APVUE.js → virtual-modules-MGTKWDID.js} +1 -1
  8. package/dist/bundle/cli-runtime.js +3 -0
  9. package/dist/bundle/cli.js +4 -2
  10. package/dist/bundle/index.js +1 -1
  11. package/dist/bundle/rpc-entry.js +1 -1
  12. package/dist/cli/args.d.ts.map +1 -1
  13. package/dist/cli/args.js +1 -0
  14. package/dist/cli/args.js.map +1 -1
  15. package/dist/core/model-resolver.d.ts.map +1 -1
  16. package/dist/core/model-resolver.js +1 -0
  17. package/dist/core/model-resolver.js.map +1 -1
  18. package/dist/modes/interactive/bug-report.d.ts +2 -0
  19. package/dist/modes/interactive/bug-report.d.ts.map +1 -1
  20. package/dist/modes/interactive/bug-report.js +2 -5
  21. package/dist/modes/interactive/bug-report.js.map +1 -1
  22. package/dist/modes/interactive/components/extension-editor.d.ts +4 -1
  23. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  24. package/dist/modes/interactive/components/extension-editor.js +7 -2
  25. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  26. package/dist/modes/interactive/interactive-mode.d.ts +2 -1
  27. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  28. package/dist/modes/interactive/interactive-mode.js +10 -3
  29. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  30. package/dist/utils/clipboard-image.d.ts.map +1 -1
  31. package/dist/utils/clipboard-image.js +1 -12
  32. package/dist/utils/clipboard-image.js.map +1 -1
  33. package/dist/utils/clipboard.d.ts.map +1 -1
  34. package/dist/utils/clipboard.js +74 -20
  35. package/dist/utils/clipboard.js.map +1 -1
  36. package/dist/utils/wsl.d.ts +3 -0
  37. package/dist/utils/wsl.d.ts.map +1 -0
  38. package/dist/utils/wsl.js +15 -0
  39. package/dist/utils/wsl.js.map +1 -0
  40. package/docs/providers.md +8 -0
  41. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  42. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  43. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  44. package/examples/extensions/gondolin/package-lock.json +2 -2
  45. package/examples/extensions/gondolin/package.json +1 -1
  46. package/examples/extensions/sandbox/package-lock.json +2 -2
  47. package/examples/extensions/sandbox/package.json +1 -1
  48. package/examples/extensions/with-deps/package-lock.json +2 -2
  49. package/examples/extensions/with-deps/package.json +1 -1
  50. package/npm-shrinkwrap.json +20 -20
  51. package/package.json +8 -8
@@ -1 +1 @@
1
- {"version":3,"file":"bug-report.js","sourceRoot":"","sources":["../../../src/modes/interactive/bug-report.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from \"node:path\";\nimport type { Container, EditorComponent, TUI } from \"@earendil-works/pi-tui\";\nimport { getAuthCredential } from \"../../cli/auth-command.ts\";\nimport type { AgentSession } from \"../../core/agent-session.ts\";\nimport {\n\tBUG_REPORT_CUSTOM_ENTRY_TYPE,\n\ttype BugReportBundle,\n\ttype BugReportSessionEntryData,\n\tbugReportArchiveFileName,\n\tcollectBugReportDiagnostics,\n\tcollectBugReportMetadata,\n\twriteBugReportArchive,\n} from \"../../core/bug-report.ts\";\nimport { uploadBugReport } from \"../../core/bug-report-upload.ts\";\nimport { clearCrashLog, readCrashLog } from \"../../core/crash-log.ts\";\nimport { getRadiusGatewayUrl, RADIUS_PROVIDER_ID } from \"../../core/radius.ts\";\nimport { serializeSessionBranch } from \"../../core/session-export.ts\";\nimport { BorderedLoader } from \"./components/bordered-loader.ts\";\nimport { ExtensionInputComponent } from \"./components/extension-input.ts\";\nimport { ExtensionSelectorComponent } from \"./components/extension-selector.ts\";\nimport { createShareTrailingEntries } from \"./session-share.ts\";\nimport { theme } from \"./theme/theme.ts\";\n\ninterface BugReportContext {\n\tsession: AgentSession;\n\tui: TUI;\n\teditorContainer: Container;\n\teditor: EditorComponent;\n\tshowStatus: (message: string) => void;\n\tshowError: (message: string) => void;\n}\n\ninterface BugReportOptions {\n\thint?: string;\n\tincludeSession: boolean;\n\tincludeSummary: boolean;\n\tdelivery: \"upload\" | \"zip\";\n}\n\ntype Overlay = Container & { dispose?: () => void };\n\nconst DISCLAIMER =\n\t\"This report goes to the Pi developers (Earendil) and is not shared publicly. It includes your pi version, operating system, the current model and provider configuration (without API keys), loaded extensions, settings, and provider error diagnostics from this session.\";\nconst TRANSCRIPT_NOTE =\n\t\"The transcript contains your messages, model output, tool calls and their results, including file contents and command output read during this session.\";\n\n/** Run the `/bug` flow: consent, optional summary, then upload or export. */\nexport async function reportBug(context: BugReportContext, initialHint?: string): Promise<void> {\n\tconst options = await promptForOptions(context, initialHint);\n\tif (!options) {\n\t\tcontext.showStatus(\"Bug report cancelled\");\n\t\treturn;\n\t}\n\n\tlet summary: string | undefined;\n\tif (options.includeSummary) {\n\t\tconst loader = showLoader(\n\t\t\tcontext,\n\t\t\t`Writing summary with ${context.session.model?.name ?? \"the current model\"}...`,\n\t\t);\n\t\ttry {\n\t\t\tsummary = await context.session.summarizeForBugReport({ hint: options.hint, signal: loader.signal });\n\t\t} catch (error: unknown) {\n\t\t\trestoreEditor(context, loader);\n\t\t\tif (loader.signal.aborted) context.showStatus(\"Bug report cancelled\");\n\t\t\telse context.showError(`Failed to write bug report summary: ${errorMessage(error)}`);\n\t\t\treturn;\n\t\t}\n\t\trestoreEditor(context, loader);\n\t\tif (loader.signal.aborted) {\n\t\t\tcontext.showStatus(\"Bug report cancelled\");\n\t\t\treturn;\n\t\t}\n\t}\n\n\tlet bundle: BugReportBundle;\n\ttry {\n\t\tbundle = buildBundle(context.session, options, summary);\n\t} catch (error: unknown) {\n\t\tcontext.showError(`Failed to build bug report: ${errorMessage(error)}`);\n\t\treturn;\n\t}\n\n\tif (options.delivery === \"upload\") {\n\t\tconst failure = await upload(context, bundle);\n\t\tif (failure === undefined) return;\n\t\tconst fallback = await choose(\n\t\t\tcontext,\n\t\t\t\"Upload failed\",\n\t\t\t[\"Export as Zip\", \"Cancel\"],\n\t\t\t`${failure}\\n\\nExport the report as a zip archive instead?`,\n\t\t);\n\t\tif (fallback !== \"Export as Zip\") {\n\t\t\tcontext.showStatus(\"Bug report cancelled\");\n\t\t\treturn;\n\t\t}\n\t}\n\tawait exportZip(context, bundle);\n}\n\nasync function promptForOptions(\n\tcontext: BugReportContext,\n\tinitialHint: string | undefined,\n): Promise<BugReportOptions | undefined> {\n\tconst hint = await input(context, \"Report a bug\", `${DISCLAIMER}\\n\\nWhat went wrong? (optional)`, initialHint);\n\tif (hint === null) return undefined;\n\tconst transcript = await choose(\n\t\tcontext,\n\t\t\"Include the session transcript?\",\n\t\t[\"Yes, include the transcript\", \"No\"],\n\t\tTRANSCRIPT_NOTE,\n\t);\n\tif (!transcript) return undefined;\n\tconst includeSession = transcript !== \"No\";\n\tlet includeSummary = false;\n\tif (!includeSession) {\n\t\tconst model = context.session.model;\n\t\tconst summary = await choose(\n\t\t\tcontext,\n\t\t\t`Attach a summary written by ${model?.name ?? \"the current model\"} instead?`,\n\t\t\t[\"Yes, generate a summary\", \"No\"],\n\t\t\t`The transcript is sent to ${model?.provider ?? \"your provider\"} with your credentials and tokens. Only the generated summary is attached; the transcript stays on your machine.`,\n\t\t);\n\t\tif (!summary) return undefined;\n\t\tincludeSummary = summary !== \"No\";\n\t}\n\tconst description = hint.trim();\n\tconst delivery = await choose(\n\t\tcontext,\n\t\t\"Bug report\",\n\t\t[\"Upload Report\", \"Export as Zip\", \"Cancel\"],\n\t\t`Description: ${description || \"none\"}\\nTranscript: ${includeSession ? \"included\" : \"not included\"}\\nSummary: ${includeSummary ? `written by ${context.session.model?.name ?? \"the current model\"}` : \"none\"}\\n\\nUpload sends the report to ${new URL(getRadiusGatewayUrl()).host}. Export writes a zip archive to the current directory instead.`,\n\t);\n\tif (!delivery || delivery === \"Cancel\") return undefined;\n\treturn {\n\t\thint: description || undefined,\n\t\tincludeSession,\n\t\tincludeSummary,\n\t\tdelivery: delivery === \"Upload Report\" ? \"upload\" : \"zip\",\n\t};\n}\n\nfunction buildBundle(session: AgentSession, options: BugReportOptions, summary: string | undefined): BugReportBundle {\n\tconst extensions = session.resourceLoader.getExtensions();\n\treturn {\n\t\tmetadata: collectBugReportMetadata({\n\t\t\thint: options.hint,\n\t\t\tsessionId: session.sessionId,\n\t\t\tcwd: session.sessionManager.getCwd(),\n\t\t\tincludeSession: options.includeSession,\n\t\t\tincludeSummary: summary !== undefined,\n\t\t\tmessageCount: session.messages.length,\n\t\t\tmodel: session.model,\n\t\t\tmodelRuntime: session.modelRuntime,\n\t\t\tthinkingLevel: session.thinkingLevel,\n\t\t\textensions: extensions.extensions,\n\t\t\textensionErrors: extensions.errors,\n\t\t\tglobalSettings: session.settingsManager.getGlobalSettings(),\n\t\t\tprojectSettings: session.settingsManager.getProjectSettings(),\n\t\t}),\n\t\tdiagnostics: collectBugReportDiagnostics(session.sessionManager, readCrashLog()),\n\t\tsummary,\n\t\tsessionJsonl: options.includeSession\n\t\t\t? serializeSessionBranch(session.sessionManager, (parentId, timestamp) =>\n\t\t\t\t\tcreateShareTrailingEntries(session, parentId, timestamp),\n\t\t\t\t)\n\t\t\t: undefined,\n\t};\n}\n\nasync function upload(context: BugReportContext, bundle: BugReportBundle): Promise<string | undefined> {\n\tconst loader = showLoader(context, \"Uploading bug report...\");\n\ttry {\n\t\tconst provider = context.session.modelRuntime.getProvider(RADIUS_PROVIDER_ID);\n\t\tconst token = provider\n\t\t\t? getAuthCredential(\n\t\t\t\t\tawait context.session.modelRuntime.getAuth(RADIUS_PROVIDER_ID, { minOAuthValidityMs: 5 * 60_000 }),\n\t\t\t\t)\n\t\t\t: undefined;\n\t\tconst result = await uploadBugReport(bundle, { token, signal: loader.signal });\n\t\trestoreEditor(context, loader);\n\t\trecordInSession(context.session, bundle, { delivery: \"upload\" });\n\t\tcontext.showStatus(`Bug report uploaded. Report ID: ${result.id}`);\n\t\treturn undefined;\n\t} catch (error: unknown) {\n\t\trestoreEditor(context, loader);\n\t\tif (loader.signal.aborted) {\n\t\t\tcontext.showStatus(\"Bug report cancelled\");\n\t\t\treturn undefined;\n\t\t}\n\t\treturn errorMessage(error);\n\t}\n}\n\nasync function exportZip(context: BugReportContext, bundle: BugReportBundle): Promise<void> {\n\tconst archivePath = path.join(process.cwd(), bugReportArchiveFileName(bundle.metadata.id));\n\ttry {\n\t\tawait writeBugReportArchive(bundle, archivePath);\n\t} catch (error: unknown) {\n\t\tcontext.showError(`Failed to write bug report: ${errorMessage(error)}`);\n\t\treturn;\n\t}\n\trecordInSession(context.session, bundle, { delivery: \"zip\", path: archivePath });\n\tcontext.showStatus(`Bug report exported to: ${archivePath}\\nReport ID: ${bundle.metadata.id}`);\n}\n\nfunction recordInSession(\n\tsession: AgentSession,\n\tbundle: BugReportBundle,\n\tdelivery: Pick<BugReportSessionEntryData, \"delivery\" | \"path\">,\n): void {\n\tsession.sessionManager.appendCustomEntry(BUG_REPORT_CUSTOM_ENTRY_TYPE, {\n\t\tid: bundle.metadata.id,\n\t\tcreatedAt: bundle.metadata.createdAt,\n\t\thint: bundle.metadata.hint,\n\t\tsessionIncluded: bundle.metadata.session.included,\n\t\tsummaryIncluded: bundle.metadata.session.summaryIncluded,\n\t\t...delivery,\n\t} satisfies BugReportSessionEntryData);\n\tif (bundle.diagnostics.crashes.length > 0) clearCrashLog();\n}\n\nfunction input(\n\tcontext: BugReportContext,\n\ttitle: string,\n\tdescription: string,\n\tinitialValue?: string,\n): Promise<string | null> {\n\treturn new Promise((resolve) => {\n\t\tlet component: ExtensionInputComponent;\n\t\tconst finish = (value: string | null) => {\n\t\t\trestoreEditor(context, component);\n\t\t\tresolve(value);\n\t\t};\n\t\tcomponent = new ExtensionInputComponent(\n\t\t\ttitle,\n\t\t\tundefined,\n\t\t\t(value) => finish(value),\n\t\t\t() => finish(null),\n\t\t\t{\n\t\t\t\tinitialValue,\n\t\t\t\tdescription,\n\t\t\t},\n\t\t);\n\t\tshowOverlay(context, component);\n\t});\n}\n\nfunction choose(\n\tcontext: BugReportContext,\n\ttitle: string,\n\toptions: string[],\n\tdescription?: string,\n): Promise<string | undefined> {\n\treturn new Promise((resolve) => {\n\t\tlet component: ExtensionSelectorComponent;\n\t\tconst finish = (value?: string) => {\n\t\t\trestoreEditor(context, component);\n\t\t\tresolve(value);\n\t\t};\n\t\tcomponent = new ExtensionSelectorComponent(title, options, finish, () => finish(), {\n\t\t\ttui: context.ui,\n\t\t\tdescription,\n\t\t});\n\t\tshowOverlay(context, component);\n\t});\n}\n\nfunction showLoader(context: BugReportContext, message: string): BorderedLoader {\n\tconst loader = new BorderedLoader(context.ui, theme, message);\n\tshowOverlay(context, loader);\n\treturn loader;\n}\n\nfunction showOverlay(context: BugReportContext, component: Overlay): void {\n\tcontext.editorContainer.clear();\n\tcontext.editorContainer.addChild(component);\n\tcontext.ui.setFocus(component);\n\tcontext.ui.requestRender();\n}\n\nfunction restoreEditor(context: BugReportContext, component: Overlay): void {\n\tcomponent.dispose?.();\n\tcontext.editorContainer.clear();\n\tcontext.editorContainer.addChild(context.editor);\n\tcontext.ui.setFocus(context.editor);\n\tcontext.ui.requestRender();\n}\n\nfunction errorMessage(error: unknown): string {\n\treturn error instanceof Error ? error.message : \"Unknown error\";\n}\n"]}
1
+ {"version":3,"file":"bug-report.js","sourceRoot":"","sources":["../../../src/modes/interactive/bug-report.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from \"node:path\";\nimport type { Container, EditorComponent, TUI } from \"@earendil-works/pi-tui\";\nimport { getAuthCredential } from \"../../cli/auth-command.ts\";\nimport type { AgentSession } from \"../../core/agent-session.ts\";\nimport {\n\tBUG_REPORT_CUSTOM_ENTRY_TYPE,\n\ttype BugReportBundle,\n\ttype BugReportSessionEntryData,\n\tbugReportArchiveFileName,\n\tcollectBugReportDiagnostics,\n\tcollectBugReportMetadata,\n\twriteBugReportArchive,\n} from \"../../core/bug-report.ts\";\nimport { uploadBugReport } from \"../../core/bug-report-upload.ts\";\nimport { clearCrashLog, readCrashLog } from \"../../core/crash-log.ts\";\nimport type { KeybindingsManager } from \"../../core/keybindings.ts\";\nimport { getRadiusGatewayUrl, RADIUS_PROVIDER_ID } from \"../../core/radius.ts\";\nimport { serializeSessionBranch } from \"../../core/session-export.ts\";\nimport { BorderedLoader } from \"./components/bordered-loader.ts\";\nimport { ExtensionEditorComponent } from \"./components/extension-editor.ts\";\nimport { ExtensionSelectorComponent } from \"./components/extension-selector.ts\";\nimport { createShareTrailingEntries } from \"./session-share.ts\";\nimport { theme } from \"./theme/theme.ts\";\n\ninterface BugReportContext {\n\tsession: AgentSession;\n\tui: TUI;\n\teditorContainer: Container;\n\teditor: EditorComponent;\n\tkeybindings: KeybindingsManager;\n\tshowStatus: (message: string) => void;\n\tshowError: (message: string) => void;\n}\n\ninterface BugReportOptions {\n\thint?: string;\n\tincludeSession: boolean;\n\tincludeSummary: boolean;\n\tdelivery: \"upload\" | \"zip\";\n}\n\ntype Overlay = Container & { dispose?: () => void };\n\nconst DISCLAIMER =\n\t\"This report goes to the Pi developers (Earendil) and is not shared publicly. It includes your pi version, operating system, the current model and provider configuration (without API keys), loaded extensions, settings, and provider error diagnostics from this session.\";\nconst TRANSCRIPT_NOTE =\n\t\"The transcript contains your messages, model output, tool calls and their results, including file contents and command output read during this session.\";\n\n/** Run the `/bug` flow: consent, optional summary, then upload or export. */\nexport async function reportBug(context: BugReportContext, initialHint?: string): Promise<void> {\n\tconst options = await promptForOptions(context, initialHint);\n\tif (!options) {\n\t\tcontext.showStatus(\"Bug report cancelled\");\n\t\treturn;\n\t}\n\n\tlet summary: string | undefined;\n\tif (options.includeSummary) {\n\t\tconst loader = showLoader(\n\t\t\tcontext,\n\t\t\t`Writing summary with ${context.session.model?.name ?? \"the current model\"}...`,\n\t\t);\n\t\ttry {\n\t\t\tsummary = await context.session.summarizeForBugReport({ hint: options.hint, signal: loader.signal });\n\t\t} catch (error: unknown) {\n\t\t\trestoreEditor(context, loader);\n\t\t\tif (loader.signal.aborted) context.showStatus(\"Bug report cancelled\");\n\t\t\telse context.showError(`Failed to write bug report summary: ${errorMessage(error)}`);\n\t\t\treturn;\n\t\t}\n\t\trestoreEditor(context, loader);\n\t\tif (loader.signal.aborted) {\n\t\t\tcontext.showStatus(\"Bug report cancelled\");\n\t\t\treturn;\n\t\t}\n\t}\n\n\tlet bundle: BugReportBundle;\n\ttry {\n\t\tbundle = buildBundle(context.session, options, summary);\n\t} catch (error: unknown) {\n\t\tcontext.showError(`Failed to build bug report: ${errorMessage(error)}`);\n\t\treturn;\n\t}\n\n\tif (options.delivery === \"upload\") {\n\t\tconst failure = await upload(context, bundle);\n\t\tif (failure === undefined) return;\n\t\tconst fallback = await choose(\n\t\t\tcontext,\n\t\t\t\"Upload failed\",\n\t\t\t[\"Export as Zip\", \"Cancel\"],\n\t\t\t`${failure}\\n\\nExport the report as a zip archive instead?`,\n\t\t);\n\t\tif (fallback !== \"Export as Zip\") {\n\t\t\tcontext.showStatus(\"Bug report cancelled\");\n\t\t\treturn;\n\t\t}\n\t}\n\tawait exportZip(context, bundle);\n}\n\nasync function promptForOptions(\n\tcontext: BugReportContext,\n\tinitialHint: string | undefined,\n): Promise<BugReportOptions | undefined> {\n\tconst hint = await input(context, \"Report a bug\", `${DISCLAIMER}\\n\\nWhat went wrong? (optional)`, initialHint);\n\tif (hint === null) return undefined;\n\tconst transcript = await choose(\n\t\tcontext,\n\t\t\"Include the session transcript?\",\n\t\t[\"Yes, include the transcript\", \"No\"],\n\t\tTRANSCRIPT_NOTE,\n\t);\n\tif (!transcript) return undefined;\n\tconst includeSession = transcript !== \"No\";\n\tlet includeSummary = false;\n\tif (!includeSession) {\n\t\tconst model = context.session.model;\n\t\tconst summary = await choose(\n\t\t\tcontext,\n\t\t\t`Attach a summary written by ${model?.name ?? \"the current model\"} instead?`,\n\t\t\t[\"Yes, generate a summary\", \"No\"],\n\t\t\t`The transcript is sent to ${model?.provider ?? \"your provider\"} with your credentials and tokens. Only the generated summary is attached; the transcript stays on your machine.`,\n\t\t);\n\t\tif (!summary) return undefined;\n\t\tincludeSummary = summary !== \"No\";\n\t}\n\tconst description = hint.trim();\n\tconst delivery = await choose(\n\t\tcontext,\n\t\t\"Bug report\",\n\t\t[\"Upload Report\", \"Export as Zip\", \"Cancel\"],\n\t\t`Description: ${description || \"none\"}\\nTranscript: ${includeSession ? \"included\" : \"not included\"}\\nSummary: ${includeSummary ? `written by ${context.session.model?.name ?? \"the current model\"}` : \"none\"}\\n\\nUpload sends the report to ${new URL(getRadiusGatewayUrl()).host}. Export writes a zip archive to the current directory instead.`,\n\t);\n\tif (!delivery || delivery === \"Cancel\") return undefined;\n\treturn {\n\t\thint: description || undefined,\n\t\tincludeSession,\n\t\tincludeSummary,\n\t\tdelivery: delivery === \"Upload Report\" ? \"upload\" : \"zip\",\n\t};\n}\n\nfunction buildBundle(session: AgentSession, options: BugReportOptions, summary: string | undefined): BugReportBundle {\n\tconst extensions = session.resourceLoader.getExtensions();\n\treturn {\n\t\tmetadata: collectBugReportMetadata({\n\t\t\thint: options.hint,\n\t\t\tsessionId: session.sessionId,\n\t\t\tcwd: session.sessionManager.getCwd(),\n\t\t\tincludeSession: options.includeSession,\n\t\t\tincludeSummary: summary !== undefined,\n\t\t\tmessageCount: session.messages.length,\n\t\t\tmodel: session.model,\n\t\t\tmodelRuntime: session.modelRuntime,\n\t\t\tthinkingLevel: session.thinkingLevel,\n\t\t\textensions: extensions.extensions,\n\t\t\textensionErrors: extensions.errors,\n\t\t\tglobalSettings: session.settingsManager.getGlobalSettings(),\n\t\t\tprojectSettings: session.settingsManager.getProjectSettings(),\n\t\t}),\n\t\tdiagnostics: collectBugReportDiagnostics(session.sessionManager, readCrashLog()),\n\t\tsummary,\n\t\tsessionJsonl: options.includeSession\n\t\t\t? serializeSessionBranch(session.sessionManager, (parentId, timestamp) =>\n\t\t\t\t\tcreateShareTrailingEntries(session, parentId, timestamp),\n\t\t\t\t)\n\t\t\t: undefined,\n\t};\n}\n\nasync function upload(context: BugReportContext, bundle: BugReportBundle): Promise<string | undefined> {\n\tconst loader = showLoader(context, \"Uploading bug report...\");\n\ttry {\n\t\tconst provider = context.session.modelRuntime.getProvider(RADIUS_PROVIDER_ID);\n\t\tconst token = provider\n\t\t\t? getAuthCredential(\n\t\t\t\t\tawait context.session.modelRuntime.getAuth(RADIUS_PROVIDER_ID, { minOAuthValidityMs: 5 * 60_000 }),\n\t\t\t\t)\n\t\t\t: undefined;\n\t\tconst result = await uploadBugReport(bundle, { token, signal: loader.signal });\n\t\trestoreEditor(context, loader);\n\t\trecordInSession(context.session, bundle, { delivery: \"upload\" });\n\t\tcontext.showStatus(`Bug report uploaded. Report ID: ${result.id}`);\n\t\treturn undefined;\n\t} catch (error: unknown) {\n\t\trestoreEditor(context, loader);\n\t\tif (loader.signal.aborted) {\n\t\t\tcontext.showStatus(\"Bug report cancelled\");\n\t\t\treturn undefined;\n\t\t}\n\t\treturn errorMessage(error);\n\t}\n}\n\nasync function exportZip(context: BugReportContext, bundle: BugReportBundle): Promise<void> {\n\tconst archivePath = path.join(process.cwd(), bugReportArchiveFileName(bundle.metadata.id));\n\ttry {\n\t\tawait writeBugReportArchive(bundle, archivePath);\n\t} catch (error: unknown) {\n\t\tcontext.showError(`Failed to write bug report: ${errorMessage(error)}`);\n\t\treturn;\n\t}\n\trecordInSession(context.session, bundle, { delivery: \"zip\", path: archivePath });\n\tcontext.showStatus(`Bug report exported to: ${archivePath}\\nReport ID: ${bundle.metadata.id}`);\n}\n\nfunction recordInSession(\n\tsession: AgentSession,\n\tbundle: BugReportBundle,\n\tdelivery: Pick<BugReportSessionEntryData, \"delivery\" | \"path\">,\n): void {\n\tsession.sessionManager.appendCustomEntry(BUG_REPORT_CUSTOM_ENTRY_TYPE, {\n\t\tid: bundle.metadata.id,\n\t\tcreatedAt: bundle.metadata.createdAt,\n\t\thint: bundle.metadata.hint,\n\t\tsessionIncluded: bundle.metadata.session.included,\n\t\tsummaryIncluded: bundle.metadata.session.summaryIncluded,\n\t\t...delivery,\n\t} satisfies BugReportSessionEntryData);\n\tif (bundle.diagnostics.crashes.length > 0) clearCrashLog();\n}\n\nfunction input(\n\tcontext: BugReportContext,\n\ttitle: string,\n\tdescription: string,\n\tinitialValue?: string,\n): Promise<string | null> {\n\treturn new Promise((resolve) => {\n\t\tlet component: ExtensionEditorComponent;\n\t\tconst finish = (value: string | null) => {\n\t\t\trestoreEditor(context, component);\n\t\t\tresolve(value);\n\t\t};\n\t\tcomponent = new ExtensionEditorComponent(\n\t\t\tcontext.ui,\n\t\t\tcontext.keybindings,\n\t\t\ttitle,\n\t\t\tinitialValue,\n\t\t\t(value) => finish(value),\n\t\t\t() => finish(null),\n\t\t\t{ description },\n\t\t\tcontext.session.settingsManager.getExternalEditorCommand(),\n\t\t);\n\t\tshowOverlay(context, component);\n\t});\n}\n\nfunction choose(\n\tcontext: BugReportContext,\n\ttitle: string,\n\toptions: string[],\n\tdescription?: string,\n): Promise<string | undefined> {\n\treturn new Promise((resolve) => {\n\t\tlet component: ExtensionSelectorComponent;\n\t\tconst finish = (value?: string) => {\n\t\t\trestoreEditor(context, component);\n\t\t\tresolve(value);\n\t\t};\n\t\tcomponent = new ExtensionSelectorComponent(title, options, finish, () => finish(), {\n\t\t\ttui: context.ui,\n\t\t\tdescription,\n\t\t});\n\t\tshowOverlay(context, component);\n\t});\n}\n\nfunction showLoader(context: BugReportContext, message: string): BorderedLoader {\n\tconst loader = new BorderedLoader(context.ui, theme, message);\n\tshowOverlay(context, loader);\n\treturn loader;\n}\n\nfunction showOverlay(context: BugReportContext, component: Overlay): void {\n\tcontext.editorContainer.clear();\n\tcontext.editorContainer.addChild(component);\n\tcontext.ui.setFocus(component);\n\tcontext.ui.requestRender();\n}\n\nfunction restoreEditor(context: BugReportContext, component: Overlay): void {\n\tcomponent.dispose?.();\n\tcontext.editorContainer.clear();\n\tcontext.editorContainer.addChild(context.editor);\n\tcontext.ui.setFocus(context.editor);\n\tcontext.ui.requestRender();\n}\n\nfunction errorMessage(error: unknown): string {\n\treturn error instanceof Error ? error.message : \"Unknown error\";\n}\n"]}
@@ -4,6 +4,9 @@
4
4
  */
5
5
  import { Container, type EditorOptions, type Focusable, type TUI } from "@earendil-works/pi-tui";
6
6
  import type { KeybindingsManager } from "../../../core/keybindings.ts";
7
+ export interface ExtensionEditorOptions extends EditorOptions {
8
+ description?: string;
9
+ }
7
10
  export declare class ExtensionEditorComponent extends Container implements Focusable {
8
11
  private editor;
9
12
  private onSubmitCallback;
@@ -14,7 +17,7 @@ export declare class ExtensionEditorComponent extends Container implements Focus
14
17
  private _focused;
15
18
  get focused(): boolean;
16
19
  set focused(value: boolean);
17
- constructor(tui: TUI, keybindings: KeybindingsManager, title: string, prefill: string | undefined, onSubmit: (value: string) => void, onCancel: () => void, options?: EditorOptions, externalEditorCommand?: string);
20
+ constructor(tui: TUI, keybindings: KeybindingsManager, title: string, prefill: string | undefined, onSubmit: (value: string) => void, onCancel: () => void, options?: ExtensionEditorOptions, externalEditorCommand?: string);
18
21
  handleInput(keyData: string): void;
19
22
  private handleOpenExternalEditor;
20
23
  }
@@ -1 +1 @@
1
- {"version":3,"file":"extension-editor.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/extension-editor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,SAAS,EAET,KAAK,aAAa,EAClB,KAAK,SAAS,EAId,KAAK,GAAG,EACR,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAMvE,qBAAa,wBAAyB,SAAQ,SAAU,YAAW,SAAS;IAC3E,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,gBAAgB,CAA0B;IAClD,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,qBAAqB,CAAS;IAEtC,OAAO,CAAC,QAAQ,CAAS;IACzB,IAAI,OAAO,IAAI,OAAO,CAErB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAGzB;IAED,YACC,GAAG,EAAE,GAAG,EACR,WAAW,EAAE,kBAAkB,EAC/B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EACjC,QAAQ,EAAE,MAAM,IAAI,EACpB,OAAO,CAAC,EAAE,aAAa,EACvB,qBAAqB,CAAC,EAAE,MAAM,EAiD9B;IAED,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAgBjC;YAEa,wBAAwB;CAgBtC","sourcesContent":["/**\n * Multi-line editor component for extensions.\n * Supports Ctrl+G for external editor.\n */\n\nimport {\n\tContainer,\n\tEditor,\n\ttype EditorOptions,\n\ttype Focusable,\n\tgetKeybindings,\n\tSpacer,\n\tText,\n\ttype TUI,\n} from \"@earendil-works/pi-tui\";\nimport type { KeybindingsManager } from \"../../../core/keybindings.ts\";\nimport { editInExternalEditor } from \"../external-editor.ts\";\nimport { getEditorTheme, theme } from \"../theme/theme.ts\";\nimport { DynamicBorder } from \"./dynamic-border.ts\";\nimport { keyHint } from \"./keybinding-hints.ts\";\n\nexport class ExtensionEditorComponent extends Container implements Focusable {\n\tprivate editor: Editor;\n\tprivate onSubmitCallback: (value: string) => void;\n\tprivate onCancelCallback: () => void;\n\tprivate tui: TUI;\n\tprivate keybindings: KeybindingsManager;\n\tprivate externalEditorCommand: string;\n\n\tprivate _focused = false;\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.editor.focused = value;\n\t}\n\n\tconstructor(\n\t\ttui: TUI,\n\t\tkeybindings: KeybindingsManager,\n\t\ttitle: string,\n\t\tprefill: string | undefined,\n\t\tonSubmit: (value: string) => void,\n\t\tonCancel: () => void,\n\t\toptions?: EditorOptions,\n\t\texternalEditorCommand?: string,\n\t) {\n\t\tsuper();\n\n\t\tthis.tui = tui;\n\t\tthis.keybindings = keybindings;\n\t\tthis.externalEditorCommand =\n\t\t\texternalEditorCommand ||\n\t\t\tprocess.env.VISUAL ||\n\t\t\tprocess.env.EDITOR ||\n\t\t\t(process.platform === \"win32\" ? \"notepad\" : \"nano\");\n\t\tthis.onSubmitCallback = onSubmit;\n\t\tthis.onCancelCallback = onCancel;\n\n\t\t// Add top border\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Add title\n\t\tthis.addChild(new Text(theme.fg(\"accent\", title), 1, 0));\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Create editor\n\t\tthis.editor = new Editor(tui, getEditorTheme(), options);\n\t\tif (prefill) {\n\t\t\tthis.editor.setText(prefill);\n\t\t}\n\t\t// Wire up Enter to submit (Shift+Enter for newlines, like the main editor)\n\t\tthis.editor.onSubmit = (text: string) => {\n\t\t\tthis.onSubmitCallback(text);\n\t\t};\n\t\tthis.addChild(this.editor);\n\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Add hint\n\t\tconst hint =\n\t\t\tkeyHint(\"tui.select.confirm\", \"submit\") +\n\t\t\t\" \" +\n\t\t\tkeyHint(\"tui.input.newLine\", \"newline\") +\n\t\t\t\" \" +\n\t\t\tkeyHint(\"tui.select.cancel\", \"cancel\") +\n\t\t\t` ${keyHint(\"app.editor.external\", \"external editor\")}`;\n\t\tthis.addChild(new Text(hint, 1, 0));\n\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Add bottom border\n\t\tthis.addChild(new DynamicBorder());\n\t}\n\n\thandleInput(keyData: string): void {\n\t\tconst kb = getKeybindings();\n\t\t// Escape or Ctrl+C to cancel\n\t\tif (kb.matches(keyData, \"tui.select.cancel\")) {\n\t\t\tthis.onCancelCallback();\n\t\t\treturn;\n\t\t}\n\n\t\t// External editor (app keybinding)\n\t\tif (this.keybindings.matches(keyData, \"app.editor.external\")) {\n\t\t\tvoid this.handleOpenExternalEditor();\n\t\t\treturn;\n\t\t}\n\n\t\t// Forward to editor\n\t\tthis.editor.handleInput(keyData);\n\t}\n\n\tprivate async handleOpenExternalEditor(): Promise<void> {\n\t\tconst content = this.editor.getText();\n\t\tthis.tui.stop();\n\t\ttry {\n\t\t\tconst result = await editInExternalEditor({\n\t\t\t\tcommand: this.externalEditorCommand,\n\t\t\t\tcontent,\n\t\t\t});\n\t\t\tif (result.status === \"complete\") {\n\t\t\t\tthis.editor.setText(result.content);\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.tui.start();\n\t\t\tthis.tui.requestRender(true);\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"extension-editor.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/extension-editor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,SAAS,EAET,KAAK,aAAa,EAClB,KAAK,SAAS,EAId,KAAK,GAAG,EACR,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAMvE,MAAM,WAAW,sBAAuB,SAAQ,aAAa;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,wBAAyB,SAAQ,SAAU,YAAW,SAAS;IAC3E,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,gBAAgB,CAA0B;IAClD,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,qBAAqB,CAAS;IAEtC,OAAO,CAAC,QAAQ,CAAS;IACzB,IAAI,OAAO,IAAI,OAAO,CAErB;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,OAAO,EAGzB;IAED,YACC,GAAG,EAAE,GAAG,EACR,WAAW,EAAE,kBAAkB,EAC/B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EACjC,QAAQ,EAAE,MAAM,IAAI,EACpB,OAAO,CAAC,EAAE,sBAAsB,EAChC,qBAAqB,CAAC,EAAE,MAAM,EAsD9B;IAED,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAgBjC;YAEa,wBAAwB;CAgBtC","sourcesContent":["/**\n * Multi-line editor component for extensions.\n * Supports Ctrl+G for external editor.\n */\n\nimport {\n\tContainer,\n\tEditor,\n\ttype EditorOptions,\n\ttype Focusable,\n\tgetKeybindings,\n\tSpacer,\n\tText,\n\ttype TUI,\n} from \"@earendil-works/pi-tui\";\nimport type { KeybindingsManager } from \"../../../core/keybindings.ts\";\nimport { editInExternalEditor } from \"../external-editor.ts\";\nimport { getEditorTheme, theme } from \"../theme/theme.ts\";\nimport { DynamicBorder } from \"./dynamic-border.ts\";\nimport { keyHint } from \"./keybinding-hints.ts\";\n\nexport interface ExtensionEditorOptions extends EditorOptions {\n\tdescription?: string;\n}\n\nexport class ExtensionEditorComponent extends Container implements Focusable {\n\tprivate editor: Editor;\n\tprivate onSubmitCallback: (value: string) => void;\n\tprivate onCancelCallback: () => void;\n\tprivate tui: TUI;\n\tprivate keybindings: KeybindingsManager;\n\tprivate externalEditorCommand: string;\n\n\tprivate _focused = false;\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.editor.focused = value;\n\t}\n\n\tconstructor(\n\t\ttui: TUI,\n\t\tkeybindings: KeybindingsManager,\n\t\ttitle: string,\n\t\tprefill: string | undefined,\n\t\tonSubmit: (value: string) => void,\n\t\tonCancel: () => void,\n\t\toptions?: ExtensionEditorOptions,\n\t\texternalEditorCommand?: string,\n\t) {\n\t\tsuper();\n\n\t\tthis.tui = tui;\n\t\tthis.keybindings = keybindings;\n\t\tthis.externalEditorCommand =\n\t\t\texternalEditorCommand ||\n\t\t\tprocess.env.VISUAL ||\n\t\t\tprocess.env.EDITOR ||\n\t\t\t(process.platform === \"win32\" ? \"notepad\" : \"nano\");\n\t\tthis.onSubmitCallback = onSubmit;\n\t\tthis.onCancelCallback = onCancel;\n\t\tconst { description, ...editorOptions } = options ?? {};\n\n\t\t// Add top border\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Add title and optional description\n\t\tthis.addChild(new Text(theme.fg(\"accent\", title), 1, 0));\n\t\tif (description) {\n\t\t\tthis.addChild(new Spacer(1));\n\t\t\tthis.addChild(new Text(theme.fg(\"text\", description), 1, 0));\n\t\t}\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Create editor\n\t\tthis.editor = new Editor(tui, getEditorTheme(), editorOptions);\n\t\tif (prefill) {\n\t\t\tthis.editor.setText(prefill);\n\t\t}\n\t\t// Wire up Enter to submit (Shift+Enter for newlines, like the main editor)\n\t\tthis.editor.onSubmit = (text: string) => {\n\t\t\tthis.onSubmitCallback(text);\n\t\t};\n\t\tthis.addChild(this.editor);\n\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Add hint\n\t\tconst hint =\n\t\t\tkeyHint(\"tui.select.confirm\", \"submit\") +\n\t\t\t\" \" +\n\t\t\tkeyHint(\"tui.input.newLine\", \"newline\") +\n\t\t\t\" \" +\n\t\t\tkeyHint(\"tui.select.cancel\", \"cancel\") +\n\t\t\t` ${keyHint(\"app.editor.external\", \"external editor\")}`;\n\t\tthis.addChild(new Text(hint, 1, 0));\n\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Add bottom border\n\t\tthis.addChild(new DynamicBorder());\n\t}\n\n\thandleInput(keyData: string): void {\n\t\tconst kb = getKeybindings();\n\t\t// Escape or Ctrl+C to cancel\n\t\tif (kb.matches(keyData, \"tui.select.cancel\")) {\n\t\t\tthis.onCancelCallback();\n\t\t\treturn;\n\t\t}\n\n\t\t// External editor (app keybinding)\n\t\tif (this.keybindings.matches(keyData, \"app.editor.external\")) {\n\t\t\tvoid this.handleOpenExternalEditor();\n\t\t\treturn;\n\t\t}\n\n\t\t// Forward to editor\n\t\tthis.editor.handleInput(keyData);\n\t}\n\n\tprivate async handleOpenExternalEditor(): Promise<void> {\n\t\tconst content = this.editor.getText();\n\t\tthis.tui.stop();\n\t\ttry {\n\t\t\tconst result = await editInExternalEditor({\n\t\t\t\tcommand: this.externalEditorCommand,\n\t\t\t\tcontent,\n\t\t\t});\n\t\t\tif (result.status === \"complete\") {\n\t\t\t\tthis.editor.setText(result.content);\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.tui.start();\n\t\t\tthis.tui.requestRender(true);\n\t\t}\n\t}\n}\n"]}
@@ -33,14 +33,19 @@ export class ExtensionEditorComponent extends Container {
33
33
  (process.platform === "win32" ? "notepad" : "nano");
34
34
  this.onSubmitCallback = onSubmit;
35
35
  this.onCancelCallback = onCancel;
36
+ const { description, ...editorOptions } = options ?? {};
36
37
  // Add top border
37
38
  this.addChild(new DynamicBorder());
38
39
  this.addChild(new Spacer(1));
39
- // Add title
40
+ // Add title and optional description
40
41
  this.addChild(new Text(theme.fg("accent", title), 1, 0));
42
+ if (description) {
43
+ this.addChild(new Spacer(1));
44
+ this.addChild(new Text(theme.fg("text", description), 1, 0));
45
+ }
41
46
  this.addChild(new Spacer(1));
42
47
  // Create editor
43
- this.editor = new Editor(tui, getEditorTheme(), options);
48
+ this.editor = new Editor(tui, getEditorTheme(), editorOptions);
44
49
  if (prefill) {
45
50
  this.editor.setText(prefill);
46
51
  }
@@ -1 +1 @@
1
- {"version":3,"file":"extension-editor.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/extension-editor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Multi-line editor component for extensions.\n * Supports Ctrl+G for external editor.\n */\n\nimport {\n\tContainer,\n\tEditor,\n\ttype EditorOptions,\n\ttype Focusable,\n\tgetKeybindings,\n\tSpacer,\n\tText,\n\ttype TUI,\n} from \"@earendil-works/pi-tui\";\nimport type { KeybindingsManager } from \"../../../core/keybindings.ts\";\nimport { editInExternalEditor } from \"../external-editor.ts\";\nimport { getEditorTheme, theme } from \"../theme/theme.ts\";\nimport { DynamicBorder } from \"./dynamic-border.ts\";\nimport { keyHint } from \"./keybinding-hints.ts\";\n\nexport class ExtensionEditorComponent extends Container implements Focusable {\n\tprivate editor: Editor;\n\tprivate onSubmitCallback: (value: string) => void;\n\tprivate onCancelCallback: () => void;\n\tprivate tui: TUI;\n\tprivate keybindings: KeybindingsManager;\n\tprivate externalEditorCommand: string;\n\n\tprivate _focused = false;\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.editor.focused = value;\n\t}\n\n\tconstructor(\n\t\ttui: TUI,\n\t\tkeybindings: KeybindingsManager,\n\t\ttitle: string,\n\t\tprefill: string | undefined,\n\t\tonSubmit: (value: string) => void,\n\t\tonCancel: () => void,\n\t\toptions?: EditorOptions,\n\t\texternalEditorCommand?: string,\n\t) {\n\t\tsuper();\n\n\t\tthis.tui = tui;\n\t\tthis.keybindings = keybindings;\n\t\tthis.externalEditorCommand =\n\t\t\texternalEditorCommand ||\n\t\t\tprocess.env.VISUAL ||\n\t\t\tprocess.env.EDITOR ||\n\t\t\t(process.platform === \"win32\" ? \"notepad\" : \"nano\");\n\t\tthis.onSubmitCallback = onSubmit;\n\t\tthis.onCancelCallback = onCancel;\n\n\t\t// Add top border\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Add title\n\t\tthis.addChild(new Text(theme.fg(\"accent\", title), 1, 0));\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Create editor\n\t\tthis.editor = new Editor(tui, getEditorTheme(), options);\n\t\tif (prefill) {\n\t\t\tthis.editor.setText(prefill);\n\t\t}\n\t\t// Wire up Enter to submit (Shift+Enter for newlines, like the main editor)\n\t\tthis.editor.onSubmit = (text: string) => {\n\t\t\tthis.onSubmitCallback(text);\n\t\t};\n\t\tthis.addChild(this.editor);\n\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Add hint\n\t\tconst hint =\n\t\t\tkeyHint(\"tui.select.confirm\", \"submit\") +\n\t\t\t\" \" +\n\t\t\tkeyHint(\"tui.input.newLine\", \"newline\") +\n\t\t\t\" \" +\n\t\t\tkeyHint(\"tui.select.cancel\", \"cancel\") +\n\t\t\t` ${keyHint(\"app.editor.external\", \"external editor\")}`;\n\t\tthis.addChild(new Text(hint, 1, 0));\n\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Add bottom border\n\t\tthis.addChild(new DynamicBorder());\n\t}\n\n\thandleInput(keyData: string): void {\n\t\tconst kb = getKeybindings();\n\t\t// Escape or Ctrl+C to cancel\n\t\tif (kb.matches(keyData, \"tui.select.cancel\")) {\n\t\t\tthis.onCancelCallback();\n\t\t\treturn;\n\t\t}\n\n\t\t// External editor (app keybinding)\n\t\tif (this.keybindings.matches(keyData, \"app.editor.external\")) {\n\t\t\tvoid this.handleOpenExternalEditor();\n\t\t\treturn;\n\t\t}\n\n\t\t// Forward to editor\n\t\tthis.editor.handleInput(keyData);\n\t}\n\n\tprivate async handleOpenExternalEditor(): Promise<void> {\n\t\tconst content = this.editor.getText();\n\t\tthis.tui.stop();\n\t\ttry {\n\t\t\tconst result = await editInExternalEditor({\n\t\t\t\tcommand: this.externalEditorCommand,\n\t\t\t\tcontent,\n\t\t\t});\n\t\t\tif (result.status === \"complete\") {\n\t\t\t\tthis.editor.setText(result.content);\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.tui.start();\n\t\t\tthis.tui.requestRender(true);\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"extension-editor.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/extension-editor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Multi-line editor component for extensions.\n * Supports Ctrl+G for external editor.\n */\n\nimport {\n\tContainer,\n\tEditor,\n\ttype EditorOptions,\n\ttype Focusable,\n\tgetKeybindings,\n\tSpacer,\n\tText,\n\ttype TUI,\n} from \"@earendil-works/pi-tui\";\nimport type { KeybindingsManager } from \"../../../core/keybindings.ts\";\nimport { editInExternalEditor } from \"../external-editor.ts\";\nimport { getEditorTheme, theme } from \"../theme/theme.ts\";\nimport { DynamicBorder } from \"./dynamic-border.ts\";\nimport { keyHint } from \"./keybinding-hints.ts\";\n\nexport interface ExtensionEditorOptions extends EditorOptions {\n\tdescription?: string;\n}\n\nexport class ExtensionEditorComponent extends Container implements Focusable {\n\tprivate editor: Editor;\n\tprivate onSubmitCallback: (value: string) => void;\n\tprivate onCancelCallback: () => void;\n\tprivate tui: TUI;\n\tprivate keybindings: KeybindingsManager;\n\tprivate externalEditorCommand: string;\n\n\tprivate _focused = false;\n\tget focused(): boolean {\n\t\treturn this._focused;\n\t}\n\tset focused(value: boolean) {\n\t\tthis._focused = value;\n\t\tthis.editor.focused = value;\n\t}\n\n\tconstructor(\n\t\ttui: TUI,\n\t\tkeybindings: KeybindingsManager,\n\t\ttitle: string,\n\t\tprefill: string | undefined,\n\t\tonSubmit: (value: string) => void,\n\t\tonCancel: () => void,\n\t\toptions?: ExtensionEditorOptions,\n\t\texternalEditorCommand?: string,\n\t) {\n\t\tsuper();\n\n\t\tthis.tui = tui;\n\t\tthis.keybindings = keybindings;\n\t\tthis.externalEditorCommand =\n\t\t\texternalEditorCommand ||\n\t\t\tprocess.env.VISUAL ||\n\t\t\tprocess.env.EDITOR ||\n\t\t\t(process.platform === \"win32\" ? \"notepad\" : \"nano\");\n\t\tthis.onSubmitCallback = onSubmit;\n\t\tthis.onCancelCallback = onCancel;\n\t\tconst { description, ...editorOptions } = options ?? {};\n\n\t\t// Add top border\n\t\tthis.addChild(new DynamicBorder());\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Add title and optional description\n\t\tthis.addChild(new Text(theme.fg(\"accent\", title), 1, 0));\n\t\tif (description) {\n\t\t\tthis.addChild(new Spacer(1));\n\t\t\tthis.addChild(new Text(theme.fg(\"text\", description), 1, 0));\n\t\t}\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Create editor\n\t\tthis.editor = new Editor(tui, getEditorTheme(), editorOptions);\n\t\tif (prefill) {\n\t\t\tthis.editor.setText(prefill);\n\t\t}\n\t\t// Wire up Enter to submit (Shift+Enter for newlines, like the main editor)\n\t\tthis.editor.onSubmit = (text: string) => {\n\t\t\tthis.onSubmitCallback(text);\n\t\t};\n\t\tthis.addChild(this.editor);\n\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Add hint\n\t\tconst hint =\n\t\t\tkeyHint(\"tui.select.confirm\", \"submit\") +\n\t\t\t\" \" +\n\t\t\tkeyHint(\"tui.input.newLine\", \"newline\") +\n\t\t\t\" \" +\n\t\t\tkeyHint(\"tui.select.cancel\", \"cancel\") +\n\t\t\t` ${keyHint(\"app.editor.external\", \"external editor\")}`;\n\t\tthis.addChild(new Text(hint, 1, 0));\n\n\t\tthis.addChild(new Spacer(1));\n\n\t\t// Add bottom border\n\t\tthis.addChild(new DynamicBorder());\n\t}\n\n\thandleInput(keyData: string): void {\n\t\tconst kb = getKeybindings();\n\t\t// Escape or Ctrl+C to cancel\n\t\tif (kb.matches(keyData, \"tui.select.cancel\")) {\n\t\t\tthis.onCancelCallback();\n\t\t\treturn;\n\t\t}\n\n\t\t// External editor (app keybinding)\n\t\tif (this.keybindings.matches(keyData, \"app.editor.external\")) {\n\t\t\tvoid this.handleOpenExternalEditor();\n\t\t\treturn;\n\t\t}\n\n\t\t// Forward to editor\n\t\tthis.editor.handleInput(keyData);\n\t}\n\n\tprivate async handleOpenExternalEditor(): Promise<void> {\n\t\tconst content = this.editor.getText();\n\t\tthis.tui.stop();\n\t\ttry {\n\t\t\tconst result = await editInExternalEditor({\n\t\t\t\tcommand: this.externalEditorCommand,\n\t\t\t\tcontent,\n\t\t\t});\n\t\t\tif (result.status === \"complete\") {\n\t\t\t\tthis.editor.setText(result.content);\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.tui.start();\n\t\t\tthis.tui.requestRender(true);\n\t\t}\n\t}\n}\n"]}
@@ -2,7 +2,7 @@
2
2
  * Interactive mode for the coding agent.
3
3
  * Handles TUI rendering and user interaction, delegating business logic to AgentSession.
4
4
  */
5
- import type { ImageContent } from "@earendil-works/pi-ai/compat";
5
+ import { type ImageContent } from "@earendil-works/pi-ai/compat";
6
6
  import { type Terminal } from "@earendil-works/pi-tui";
7
7
  import { type AgentSessionRuntime } from "../../core/agent-session-runtime.ts";
8
8
  import type { AgentSessionRuntimeDiagnostic } from "../../core/agent-session-services.ts";
@@ -184,6 +184,7 @@ export declare class InteractiveMode {
184
184
  private recordCrash;
185
185
  private crashReportInstructions;
186
186
  private suggestBugReport;
187
+ private maybeSuggestBugReport;
187
188
  private renderCurrentSessionState;
188
189
  /**
189
190
  * Get a registered tool definition by name (for custom rendering).