@oh-my-pi/pi-coding-agent 3.13.1337 → 3.15.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.
Files changed (149) hide show
  1. package/CHANGELOG.md +88 -0
  2. package/docs/theme.md +38 -5
  3. package/examples/sdk/11-sessions.ts +2 -2
  4. package/package.json +7 -4
  5. package/src/cli/file-processor.ts +51 -2
  6. package/src/cli/plugin-cli.ts +25 -19
  7. package/src/cli/update-cli.ts +4 -3
  8. package/src/core/agent-session.ts +31 -4
  9. package/src/core/compaction/branch-summarization.ts +4 -32
  10. package/src/core/compaction/compaction.ts +6 -84
  11. package/src/core/compaction/utils.ts +2 -3
  12. package/src/core/custom-tools/types.ts +2 -0
  13. package/src/core/export-html/index.ts +1 -1
  14. package/src/core/hooks/index.ts +1 -1
  15. package/src/core/hooks/tool-wrapper.ts +0 -1
  16. package/src/core/hooks/types.ts +2 -2
  17. package/src/core/plugins/doctor.ts +9 -1
  18. package/src/core/sdk.ts +2 -1
  19. package/src/core/session-manager.ts +552 -41
  20. package/src/core/settings-manager.ts +174 -0
  21. package/src/core/system-prompt.ts +9 -14
  22. package/src/core/title-generator.ts +2 -8
  23. package/src/core/tools/ask.ts +19 -37
  24. package/src/core/tools/bash.ts +2 -37
  25. package/src/core/tools/edit.ts +2 -9
  26. package/src/core/tools/exa/render.ts +52 -48
  27. package/src/core/tools/find.ts +10 -8
  28. package/src/core/tools/grep.ts +45 -17
  29. package/src/core/tools/ls.ts +22 -2
  30. package/src/core/tools/lsp/clients/biome-client.ts +207 -0
  31. package/src/core/tools/lsp/clients/index.ts +49 -0
  32. package/src/core/tools/lsp/clients/lsp-linter-client.ts +98 -0
  33. package/src/core/tools/lsp/config.ts +3 -0
  34. package/src/core/tools/lsp/index.ts +107 -55
  35. package/src/core/tools/lsp/render.ts +192 -79
  36. package/src/core/tools/lsp/types.ts +27 -0
  37. package/src/core/tools/lsp/utils.ts +62 -22
  38. package/src/core/tools/notebook.ts +9 -1
  39. package/src/core/tools/output.ts +37 -14
  40. package/src/core/tools/read.ts +349 -34
  41. package/src/core/tools/renderers.ts +290 -89
  42. package/src/core/tools/review.ts +12 -5
  43. package/src/core/tools/task/agents.ts +5 -5
  44. package/src/core/tools/task/commands.ts +3 -3
  45. package/src/core/tools/task/executor.ts +33 -1
  46. package/src/core/tools/task/index.ts +93 -6
  47. package/src/core/tools/task/render.ts +147 -66
  48. package/src/core/tools/task/types.ts +14 -9
  49. package/src/core/tools/web-fetch.ts +242 -103
  50. package/src/core/tools/web-search/index.ts +64 -20
  51. package/src/core/tools/web-search/providers/exa.ts +68 -172
  52. package/src/core/tools/web-search/render.ts +264 -74
  53. package/src/core/tools/write.ts +2 -8
  54. package/src/main.ts +10 -6
  55. package/src/modes/cleanup.ts +23 -0
  56. package/src/modes/index.ts +9 -4
  57. package/src/modes/interactive/components/bash-execution.ts +6 -3
  58. package/src/modes/interactive/components/branch-summary-message.ts +1 -1
  59. package/src/modes/interactive/components/compaction-summary-message.ts +1 -1
  60. package/src/modes/interactive/components/dynamic-border.ts +1 -1
  61. package/src/modes/interactive/components/extensions/extension-dashboard.ts +4 -5
  62. package/src/modes/interactive/components/extensions/extension-list.ts +18 -16
  63. package/src/modes/interactive/components/extensions/inspector-panel.ts +8 -8
  64. package/src/modes/interactive/components/hook-message.ts +2 -2
  65. package/src/modes/interactive/components/hook-selector.ts +1 -1
  66. package/src/modes/interactive/components/model-selector.ts +22 -9
  67. package/src/modes/interactive/components/oauth-selector.ts +20 -4
  68. package/src/modes/interactive/components/plugin-settings.ts +4 -2
  69. package/src/modes/interactive/components/session-selector.ts +9 -6
  70. package/src/modes/interactive/components/settings-defs.ts +285 -1
  71. package/src/modes/interactive/components/settings-selector.ts +176 -3
  72. package/src/modes/interactive/components/status-line/index.ts +4 -0
  73. package/src/modes/interactive/components/status-line/presets.ts +94 -0
  74. package/src/modes/interactive/components/status-line/segments.ts +350 -0
  75. package/src/modes/interactive/components/status-line/separators.ts +55 -0
  76. package/src/modes/interactive/components/status-line/types.ts +81 -0
  77. package/src/modes/interactive/components/status-line-segment-editor.ts +357 -0
  78. package/src/modes/interactive/components/status-line.ts +169 -233
  79. package/src/modes/interactive/components/tool-execution.ts +446 -211
  80. package/src/modes/interactive/components/tree-selector.ts +17 -6
  81. package/src/modes/interactive/components/ttsr-notification.ts +4 -4
  82. package/src/modes/interactive/components/welcome.ts +27 -19
  83. package/src/modes/interactive/interactive-mode.ts +98 -13
  84. package/src/modes/interactive/theme/dark.json +3 -2
  85. package/src/modes/interactive/theme/defaults/dark-arctic.json +111 -0
  86. package/src/modes/interactive/theme/defaults/dark-catppuccin.json +106 -0
  87. package/src/modes/interactive/theme/defaults/dark-cyberpunk.json +109 -0
  88. package/src/modes/interactive/theme/defaults/dark-dracula.json +105 -0
  89. package/src/modes/interactive/theme/defaults/dark-forest.json +103 -0
  90. package/src/modes/interactive/theme/defaults/dark-github.json +112 -0
  91. package/src/modes/interactive/theme/defaults/dark-gruvbox.json +119 -0
  92. package/src/modes/interactive/theme/defaults/dark-monochrome.json +101 -0
  93. package/src/modes/interactive/theme/defaults/dark-monokai.json +105 -0
  94. package/src/modes/interactive/theme/defaults/dark-nord.json +104 -0
  95. package/src/modes/interactive/theme/defaults/dark-ocean.json +108 -0
  96. package/src/modes/interactive/theme/defaults/dark-one.json +107 -0
  97. package/src/modes/interactive/theme/defaults/dark-retro.json +99 -0
  98. package/src/modes/interactive/theme/defaults/dark-rose-pine.json +95 -0
  99. package/src/modes/interactive/theme/defaults/dark-solarized.json +96 -0
  100. package/src/modes/interactive/theme/defaults/dark-sunset.json +106 -0
  101. package/src/modes/interactive/theme/defaults/dark-synthwave.json +102 -0
  102. package/src/modes/interactive/theme/defaults/dark-tokyo-night.json +108 -0
  103. package/src/modes/interactive/theme/defaults/index.ts +67 -0
  104. package/src/modes/interactive/theme/defaults/light-arctic.json +106 -0
  105. package/src/modes/interactive/theme/defaults/light-catppuccin.json +105 -0
  106. package/src/modes/interactive/theme/defaults/light-cyberpunk.json +103 -0
  107. package/src/modes/interactive/theme/defaults/light-forest.json +107 -0
  108. package/src/modes/interactive/theme/defaults/light-github.json +114 -0
  109. package/src/modes/interactive/theme/defaults/light-gruvbox.json +115 -0
  110. package/src/modes/interactive/theme/defaults/light-monochrome.json +100 -0
  111. package/src/modes/interactive/theme/defaults/light-ocean.json +106 -0
  112. package/src/modes/interactive/theme/defaults/light-one.json +105 -0
  113. package/src/modes/interactive/theme/defaults/light-retro.json +105 -0
  114. package/src/modes/interactive/theme/defaults/light-solarized.json +101 -0
  115. package/src/modes/interactive/theme/defaults/light-sunset.json +106 -0
  116. package/src/modes/interactive/theme/defaults/light-synthwave.json +105 -0
  117. package/src/modes/interactive/theme/defaults/light-tokyo-night.json +118 -0
  118. package/src/modes/interactive/theme/light.json +3 -2
  119. package/src/modes/interactive/theme/theme-schema.json +120 -4
  120. package/src/modes/interactive/theme/theme.ts +1228 -14
  121. package/src/prompts/branch-summary-preamble.md +3 -0
  122. package/src/prompts/branch-summary.md +28 -0
  123. package/src/prompts/compaction-summary.md +34 -0
  124. package/src/prompts/compaction-turn-prefix.md +16 -0
  125. package/src/prompts/compaction-update-summary.md +41 -0
  126. package/src/prompts/init.md +30 -0
  127. package/src/{core/tools/task/bundled-agents → prompts}/reviewer.md +6 -0
  128. package/src/prompts/summarization-system.md +3 -0
  129. package/src/prompts/system-prompt.md +27 -0
  130. package/src/{core/tools/task/bundled-agents → prompts}/task.md +2 -0
  131. package/src/prompts/title-system.md +8 -0
  132. package/src/prompts/tools/ask.md +24 -0
  133. package/src/prompts/tools/bash.md +23 -0
  134. package/src/prompts/tools/edit.md +9 -0
  135. package/src/prompts/tools/find.md +6 -0
  136. package/src/prompts/tools/grep.md +12 -0
  137. package/src/prompts/tools/lsp.md +14 -0
  138. package/src/prompts/tools/output.md +23 -0
  139. package/src/prompts/tools/read.md +25 -0
  140. package/src/prompts/tools/web-fetch.md +8 -0
  141. package/src/prompts/tools/web-search.md +10 -0
  142. package/src/prompts/tools/write.md +10 -0
  143. package/src/commands/init.md +0 -20
  144. /package/src/{core/tools/task/bundled-commands → prompts}/architect-plan.md +0 -0
  145. /package/src/{core/tools/task/bundled-agents → prompts}/browser.md +0 -0
  146. /package/src/{core/tools/task/bundled-agents → prompts}/explore.md +0 -0
  147. /package/src/{core/tools/task/bundled-commands → prompts}/implement-with-critic.md +0 -0
  148. /package/src/{core/tools/task/bundled-commands → prompts}/implement.md +0 -0
  149. /package/src/{core/tools/task/bundled-agents → prompts}/plan.md +0 -0
@@ -8,6 +8,9 @@
8
8
  import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
9
9
  import type { AssistantMessage, Model, Usage } from "@oh-my-pi/pi-ai";
10
10
  import { complete, completeSimple } from "@oh-my-pi/pi-ai";
11
+ import compactionSummaryPrompt from "../../prompts/compaction-summary.md" with { type: "text" };
12
+ import compactionTurnPrefixPrompt from "../../prompts/compaction-turn-prefix.md" with { type: "text" };
13
+ import compactionUpdateSummaryPrompt from "../../prompts/compaction-update-summary.md" with { type: "text" };
11
14
  import { convertToLlm, createBranchSummaryMessage, createHookMessage } from "../messages";
12
15
  import type { CompactionEntry, SessionEntry } from "../session-manager";
13
16
  import {
@@ -383,77 +386,9 @@ export function findCutPoint(
383
386
  // Summarization
384
387
  // ============================================================================
385
388
 
386
- const SUMMARIZATION_PROMPT = `The messages above are a conversation to summarize. Create a structured context checkpoint summary that another LLM will use to continue the work.
389
+ const SUMMARIZATION_PROMPT = compactionSummaryPrompt;
387
390
 
388
- Use this EXACT format:
389
-
390
- ## Goal
391
- [What is the user trying to accomplish? Can be multiple items if the session covers different tasks.]
392
-
393
- ## Constraints & Preferences
394
- - [Any constraints, preferences, or requirements mentioned by user]
395
- - [Or "(none)" if none were mentioned]
396
-
397
- ## Progress
398
- ### Done
399
- - [x] [Completed tasks/changes]
400
-
401
- ### In Progress
402
- - [ ] [Current work]
403
-
404
- ### Blocked
405
- - [Issues preventing progress, if any]
406
-
407
- ## Key Decisions
408
- - **[Decision]**: [Brief rationale]
409
-
410
- ## Next Steps
411
- 1. [Ordered list of what should happen next]
412
-
413
- ## Critical Context
414
- - [Any data, examples, or references needed to continue]
415
- - [Or "(none)" if not applicable]
416
-
417
- Keep each section concise. Preserve exact file paths, function names, and error messages.`;
418
-
419
- const UPDATE_SUMMARIZATION_PROMPT = `The messages above are NEW conversation messages to incorporate into the existing summary provided in <previous-summary> tags.
420
-
421
- Update the existing structured summary with new information. RULES:
422
- - PRESERVE all existing information from the previous summary
423
- - ADD new progress, decisions, and context from the new messages
424
- - UPDATE the Progress section: move items from "In Progress" to "Done" when completed
425
- - UPDATE "Next Steps" based on what was accomplished
426
- - PRESERVE exact file paths, function names, and error messages
427
- - If something is no longer relevant, you may remove it
428
-
429
- Use this EXACT format:
430
-
431
- ## Goal
432
- [Preserve existing goals, add new ones if the task expanded]
433
-
434
- ## Constraints & Preferences
435
- - [Preserve existing, add new ones discovered]
436
-
437
- ## Progress
438
- ### Done
439
- - [x] [Include previously done items AND newly completed items]
440
-
441
- ### In Progress
442
- - [ ] [Current work - update based on progress]
443
-
444
- ### Blocked
445
- - [Current blockers - remove if resolved]
446
-
447
- ## Key Decisions
448
- - **[Decision]**: [Brief rationale] (preserve all previous, add new)
449
-
450
- ## Next Steps
451
- 1. [Update based on current state]
452
-
453
- ## Critical Context
454
- - [Preserve important context, add new if needed]
455
-
456
- Keep each section concise. Preserve exact file paths, function names, and error messages.`;
391
+ const UPDATE_SUMMARIZATION_PROMPT = compactionUpdateSummaryPrompt;
457
392
 
458
393
  /**
459
394
  * Generate a summary of the conversation using the LLM.
@@ -617,20 +552,7 @@ export function prepareCompaction(
617
552
  // Main compaction function
618
553
  // ============================================================================
619
554
 
620
- const TURN_PREFIX_SUMMARIZATION_PROMPT = `This is the PREFIX of a turn that was too large to keep. The SUFFIX (recent work) is retained.
621
-
622
- Summarize the prefix to provide context for the retained suffix:
623
-
624
- ## Original Request
625
- [What did the user ask for in this turn?]
626
-
627
- ## Early Progress
628
- - [Key decisions and work done in the prefix]
629
-
630
- ## Context for Suffix
631
- - [Information needed to understand the retained recent work]
632
-
633
- Be concise. Focus on what's needed to understand the kept suffix.`;
555
+ const TURN_PREFIX_SUMMARIZATION_PROMPT = compactionTurnPrefixPrompt;
634
556
 
635
557
  /**
636
558
  * Generate summaries for compaction using prepared data.
@@ -4,6 +4,7 @@
4
4
 
5
5
  import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
6
6
  import type { Message } from "@oh-my-pi/pi-ai";
7
+ import summarizationSystemPrompt from "../../prompts/summarization-system.md" with { type: "text" };
7
8
 
8
9
  // ============================================================================
9
10
  // File Operation Tracking
@@ -149,6 +150,4 @@ export function serializeConversation(messages: Message[]): string {
149
150
  // Summarization System Prompt
150
151
  // ============================================================================
151
152
 
152
- export const SUMMARIZATION_SYSTEM_PROMPT = `You are a context summarization assistant. Your task is to read a conversation between a user and an AI coding assistant, then produce a structured summary following the exact format specified.
153
-
154
- Do NOT continue the conversation. Do NOT respond to any questions in the conversation. ONLY output the structured summary.`;
153
+ export const SUMMARIZATION_SYSTEM_PROMPT = summarizationSystemPrompt;
@@ -76,6 +76,8 @@ export interface RenderResultOptions {
76
76
  expanded: boolean;
77
77
  /** Whether this is a partial/streaming result */
78
78
  isPartial: boolean;
79
+ /** Current spinner frame index for animated elements (0-9, only provided during partial results) */
80
+ spinnerFrame?: number;
79
81
  }
80
82
 
81
83
  export type CustomToolResult<TDetails = any> = AgentToolResult<TDetails>;
@@ -144,7 +144,7 @@ export async function exportFromFile(inputPath: string, options?: ExportOptions
144
144
 
145
145
  if (!existsSync(inputPath)) throw new Error(`File not found: ${inputPath}`);
146
146
 
147
- const sm = SessionManager.open(inputPath);
147
+ const sm = await SessionManager.open(inputPath);
148
148
  const sessionData: SessionData = {
149
149
  header: sm.getHeader(),
150
150
  entries: sm.getEntries(),
@@ -13,4 +13,4 @@ export {
13
13
  export { execCommand, HookRunner, type HookErrorListener } from "./runner";
14
14
  export { wrapToolsWithHooks, wrapToolWithHooks } from "./tool-wrapper";
15
15
  export * from "./types";
16
- export type { ReadonlySessionManager } from "../session-manager";
16
+ export type { UsageStatistics, ReadonlySessionManager } from "../session-manager";
@@ -59,7 +59,6 @@ export function wrapToolWithHooks<T>(tool: AgentTool<any, T>, hookRunner: HookRu
59
59
  input: params,
60
60
  content: result.content,
61
61
  details: result.details,
62
- isError: false,
63
62
  })) as ToolResultEventResult | undefined;
64
63
 
65
64
  // Apply modifications if any
@@ -129,7 +129,7 @@ export interface HookUIContext {
129
129
  *
130
130
  * @example
131
131
  * const theme = ctx.ui.theme;
132
- * ctx.ui.setStatus("my-hook", theme.fg("success", "✓") + " Ready");
132
+ * ctx.ui.setStatus("my-hook", theme.fg("success", theme.status.success) + " Ready");
133
133
  */
134
134
  readonly theme: Theme;
135
135
  }
@@ -410,7 +410,7 @@ interface ToolResultEventBase {
410
410
  /** Full content array (text and images) */
411
411
  content: (TextContent | ImageContent)[];
412
412
  /** Whether the tool execution was an error */
413
- isError: boolean;
413
+ isError?: boolean;
414
414
  }
415
415
 
416
416
  /** Tool result event for bash tool */
@@ -1,3 +1,4 @@
1
+ import { theme } from "../../modes/interactive/theme/theme";
1
2
  import type { DoctorCheck } from "./types";
2
3
 
3
4
  export async function runDoctorChecks(): Promise<DoctorCheck[]> {
@@ -42,10 +43,17 @@ export async function runDoctorChecks(): Promise<DoctorCheck[]> {
42
43
  }
43
44
 
44
45
  export function formatDoctorResults(checks: DoctorCheck[]): string {
46
+ // Note: This function returns plain text without theming as it may be called outside TUI context.
47
+ // For TUI usage, the plugin CLI handler applies theme colors.
45
48
  const lines: string[] = ["System Health Check", "=".repeat(40), ""];
46
49
 
47
50
  for (const check of checks) {
48
- const icon = check.status === "ok" ? "✓" : check.status === "warning" ? "!" : "✗";
51
+ const icon =
52
+ check.status === "ok"
53
+ ? theme.status.success
54
+ : check.status === "warning"
55
+ ? theme.status.warning
56
+ : theme.status.error;
49
57
  lines.push(`${icon} ${check.name}: ${check.message}`);
50
58
  }
51
59
 
package/src/core/sdk.ts CHANGED
@@ -32,6 +32,7 @@
32
32
  import { join } from "node:path";
33
33
  import { Agent, type ThinkingLevel } from "@oh-my-pi/pi-agent-core";
34
34
  import type { Model } from "@oh-my-pi/pi-ai";
35
+ import chalk from "chalk";
35
36
  // Import discovery to register all providers on startup
36
37
  import "../discovery";
37
38
  import { loadSync as loadCapability } from "../capability/index";
@@ -684,7 +685,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
684
685
  const mcpResult = await discoverAndLoadMCPTools(cwd, {
685
686
  onConnecting: (serverNames) => {
686
687
  if (options.hasUI && serverNames.length > 0) {
687
- process.stderr.write(`\x1b[90mConnecting to MCP servers: ${serverNames.join(", ")}...\x1b[0m\n`);
688
+ process.stderr.write(chalk.gray(`Connecting to MCP servers: ${serverNames.join(", ")}...\n`));
688
689
  }
689
690
  },
690
691
  enableProjectConfig: settingsManager.getMCPProjectConfigEnabled(),