pi-ui-extend 0.1.8 → 0.1.9

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 (166) hide show
  1. package/README.md +34 -0
  2. package/bin/pix.mjs +4 -4
  3. package/dist/app/app.js +38 -38
  4. package/dist/app/{cli.d.ts → cli/cli.d.ts} +1 -1
  5. package/dist/app/{cli.js → cli/cli.js} +1 -1
  6. package/dist/app/{install.js → cli/install.js} +2 -2
  7. package/dist/app/{command-controller.d.ts → commands/command-controller.d.ts} +1 -1
  8. package/dist/app/{command-host.d.ts → commands/command-host.d.ts} +3 -3
  9. package/dist/app/{command-model-actions.d.ts → commands/command-model-actions.d.ts} +1 -1
  10. package/dist/app/{command-model-actions.js → commands/command-model-actions.js} +2 -2
  11. package/dist/app/{command-navigation-actions.d.ts → commands/command-navigation-actions.d.ts} +1 -1
  12. package/dist/app/{command-navigation-actions.js → commands/command-navigation-actions.js} +5 -5
  13. package/dist/app/{command-registry.d.ts → commands/command-registry.d.ts} +1 -1
  14. package/dist/app/{command-runtime.js → commands/command-runtime.js} +1 -1
  15. package/dist/app/{command-session-actions.js → commands/command-session-actions.js} +3 -3
  16. package/dist/app/{shell-controller.d.ts → commands/shell-controller.d.ts} +1 -1
  17. package/dist/app/{shell-controller.js → commands/shell-controller.js} +1 -1
  18. package/dist/app/{slash-commands.d.ts → commands/slash-commands.d.ts} +2 -2
  19. package/dist/app/{slash-commands.js → commands/slash-commands.js} +1 -1
  20. package/dist/app/{extension-actions-controller.d.ts → extensions/extension-actions-controller.d.ts} +1 -1
  21. package/dist/app/{extension-actions-controller.js → extensions/extension-actions-controller.js} +1 -1
  22. package/dist/app/{extension-ui-controller.d.ts → extensions/extension-ui-controller.d.ts} +3 -3
  23. package/dist/app/{extension-ui-controller.js → extensions/extension-ui-controller.js} +3 -3
  24. package/dist/app/{input-action-controller.d.ts → input/input-action-controller.d.ts} +7 -7
  25. package/dist/app/{input-action-controller.js → input/input-action-controller.js} +3 -3
  26. package/dist/app/{input-controller.d.ts → input/input-controller.d.ts} +3 -3
  27. package/dist/app/{input-controller.js → input/input-controller.js} +1 -1
  28. package/dist/app/{input-paste-handler.d.ts → input/input-paste-handler.d.ts} +1 -1
  29. package/dist/app/{input-paste-handler.js → input/input-paste-handler.js} +3 -3
  30. package/dist/app/{native-modifiers.js → input/native-modifiers.js} +2 -2
  31. package/dist/app/{prompt-enhancer-controller.d.ts → input/prompt-enhancer-controller.d.ts} +5 -5
  32. package/dist/app/{prompt-enhancer-controller.js → input/prompt-enhancer-controller.js} +3 -3
  33. package/dist/app/{voice-controller.d.ts → input/voice-controller.d.ts} +1 -1
  34. package/dist/app/{voice-controller.js → input/voice-controller.js} +2 -2
  35. package/dist/app/{model-ref.d.ts → model/model-ref.d.ts} +1 -1
  36. package/dist/app/{model-ref.js → model/model-ref.js} +1 -1
  37. package/dist/app/{model-usage-controller.js → model/model-usage-controller.js} +1 -1
  38. package/dist/app/{model-usage-status.d.ts → model/model-usage-status.d.ts} +1 -1
  39. package/dist/app/{model-usage-status.js → model/model-usage-status.js} +1 -1
  40. package/dist/app/{menu-items-controller.d.ts → popup/menu-items-controller.d.ts} +4 -4
  41. package/dist/app/{menu-items-controller.js → popup/menu-items-controller.js} +5 -5
  42. package/dist/app/{popup-action-controller.d.ts → popup/popup-action-controller.d.ts} +4 -4
  43. package/dist/app/{popup-action-controller.js → popup/popup-action-controller.js} +2 -2
  44. package/dist/app/{popup-menu-controller.d.ts → popup/popup-menu-controller.d.ts} +4 -4
  45. package/dist/app/{popup-menu-controller.js → popup/popup-menu-controller.js} +7 -7
  46. package/dist/app/{conversation-entry-renderer.d.ts → rendering/conversation-entry-renderer.d.ts} +3 -3
  47. package/dist/app/{conversation-entry-renderer.js → rendering/conversation-entry-renderer.js} +3 -3
  48. package/dist/app/{conversation-shell-renderer.d.ts → rendering/conversation-shell-renderer.d.ts} +1 -1
  49. package/dist/app/{conversation-shell-renderer.js → rendering/conversation-shell-renderer.js} +1 -1
  50. package/dist/app/{conversation-tool-renderer.d.ts → rendering/conversation-tool-renderer.d.ts} +3 -3
  51. package/dist/app/{conversation-tool-renderer.js → rendering/conversation-tool-renderer.js} +7 -7
  52. package/dist/app/{conversation-viewport.d.ts → rendering/conversation-viewport.d.ts} +3 -3
  53. package/dist/app/{dcp-stats.js → rendering/dcp-stats.js} +1 -1
  54. package/dist/app/{editor-layout-renderer.d.ts → rendering/editor-layout-renderer.d.ts} +3 -3
  55. package/dist/app/{editor-layout-renderer.js → rendering/editor-layout-renderer.js} +2 -2
  56. package/dist/app/{editor-panels.d.ts → rendering/editor-panels.d.ts} +2 -2
  57. package/dist/app/{editor-panels.js → rendering/editor-panels.js} +4 -4
  58. package/dist/app/{message-content.d.ts → rendering/message-content.d.ts} +1 -1
  59. package/dist/app/{message-content.js → rendering/message-content.js} +1 -1
  60. package/dist/app/{render-controller.d.ts → rendering/render-controller.d.ts} +6 -6
  61. package/dist/app/{render-controller.js → rendering/render-controller.js} +5 -5
  62. package/dist/app/{render-text.d.ts → rendering/render-text.d.ts} +2 -2
  63. package/dist/app/{render-text.js → rendering/render-text.js} +3 -3
  64. package/dist/app/{status-line-renderer.d.ts → rendering/status-line-renderer.d.ts} +4 -4
  65. package/dist/app/{status-line-renderer.js → rendering/status-line-renderer.js} +4 -4
  66. package/dist/app/{tab-line-renderer.d.ts → rendering/tab-line-renderer.d.ts} +3 -3
  67. package/dist/app/{tab-line-renderer.js → rendering/tab-line-renderer.js} +2 -2
  68. package/dist/app/{toast-controller.d.ts → rendering/toast-controller.d.ts} +1 -1
  69. package/dist/app/{toast-controller.js → rendering/toast-controller.js} +2 -2
  70. package/dist/app/{toast-renderer.d.ts → rendering/toast-renderer.d.ts} +3 -3
  71. package/dist/app/{toast-renderer.js → rendering/toast-renderer.js} +3 -3
  72. package/dist/app/{tool-block-renderer.d.ts → rendering/tool-block-renderer.d.ts} +5 -5
  73. package/dist/app/{tool-block-renderer.js → rendering/tool-block-renderer.js} +2 -2
  74. package/dist/app/runtime.js +1 -1
  75. package/dist/app/{blink-controller.js → screen/blink-controller.js} +1 -1
  76. package/dist/app/{image-click-targets.d.ts → screen/image-click-targets.d.ts} +2 -2
  77. package/dist/app/{image-opener.d.ts → screen/image-opener.d.ts} +1 -1
  78. package/dist/app/{mouse-controller.d.ts → screen/mouse-controller.d.ts} +13 -9
  79. package/dist/app/{mouse-controller.js → screen/mouse-controller.js} +56 -28
  80. package/dist/app/{screen-selection.d.ts → screen/screen-selection.d.ts} +1 -1
  81. package/dist/app/{screen-styler.d.ts → screen/screen-styler.d.ts} +2 -2
  82. package/dist/app/{screen-styler.js → screen/screen-styler.js} +4 -4
  83. package/dist/app/{scroll-controller.d.ts → screen/scroll-controller.d.ts} +3 -3
  84. package/dist/app/{scroll-controller.js → screen/scroll-controller.js} +1 -1
  85. package/dist/app/{status-controller.d.ts → screen/status-controller.d.ts} +2 -2
  86. package/dist/app/{status-controller.js → screen/status-controller.js} +1 -1
  87. package/dist/app/{queued-message-controller.d.ts → session/queued-message-controller.d.ts} +2 -2
  88. package/dist/app/{queued-message-controller.js → session/queued-message-controller.js} +2 -2
  89. package/dist/app/{request-history.js → session/request-history.js} +2 -2
  90. package/dist/app/{session-event-controller.d.ts → session/session-event-controller.d.ts} +3 -3
  91. package/dist/app/{session-event-controller.js → session/session-event-controller.js} +3 -3
  92. package/dist/app/{session-history.d.ts → session/session-history.d.ts} +1 -1
  93. package/dist/app/{session-history.js → session/session-history.js} +3 -3
  94. package/dist/app/{session-lifecycle-controller.d.ts → session/session-lifecycle-controller.d.ts} +2 -2
  95. package/dist/app/{session-lifecycle-controller.js → session/session-lifecycle-controller.js} +4 -4
  96. package/dist/app/{session-search.d.ts → session/session-search.d.ts} +1 -1
  97. package/dist/app/{session-search.js → session/session-search.js} +3 -3
  98. package/dist/app/{tabs-controller.d.ts → session/tabs-controller.d.ts} +2 -2
  99. package/dist/app/{tabs-controller.js → session/tabs-controller.js} +4 -4
  100. package/dist/app/{subagents-files.d.ts → subagents/subagents-files.d.ts} +1 -1
  101. package/dist/app/{subagents-files.js → subagents/subagents-files.js} +1 -1
  102. package/dist/app/{subagents-model.d.ts → subagents/subagents-model.d.ts} +1 -1
  103. package/dist/app/{subagents-model.js → subagents/subagents-model.js} +4 -4
  104. package/dist/app/{subagents-widget-controller.d.ts → subagents/subagents-widget-controller.d.ts} +1 -1
  105. package/dist/app/{subagents-widget-controller.js → subagents/subagents-widget-controller.js} +2 -2
  106. package/dist/app/{terminal-bell-sound-controller.js → terminal/terminal-bell-sound-controller.js} +1 -1
  107. package/dist/app/{terminal-controller.js → terminal/terminal-controller.js} +2 -2
  108. package/dist/app/{todo-model.d.ts → todo/todo-model.d.ts} +1 -1
  109. package/dist/app/{todo-model.js → todo/todo-model.js} +3 -3
  110. package/dist/app/{todo-widget-controller.d.ts → todo/todo-widget-controller.d.ts} +1 -1
  111. package/dist/app/{todo-widget-controller.js → todo/todo-widget-controller.js} +2 -2
  112. package/dist/app/types.d.ts +2 -2
  113. package/dist/app/{workspace-actions-controller.d.ts → workspace/workspace-actions-controller.d.ts} +1 -1
  114. package/dist/app/{workspace-actions-controller.js → workspace/workspace-actions-controller.js} +3 -3
  115. package/dist/main.js +2 -2
  116. package/external/pi-tools-suite/README.md +78 -0
  117. package/external/pi-tools-suite/src/async-subagents/core/agent-strategy.ts +4 -0
  118. package/external/pi-tools-suite/src/async-subagents/core/spawn.ts +6 -1
  119. package/external/pi-tools-suite/src/dcp/prompts.ts +4 -0
  120. package/external/pi-tools-suite/src/default-pi-tools-suite-config.ts +271 -0
  121. package/external/pi-tools-suite/src/index.ts +1 -0
  122. package/external/pi-tools-suite/src/opencode-import/commands.ts +86 -0
  123. package/external/pi-tools-suite/src/opencode-import/importer.ts +208 -0
  124. package/external/pi-tools-suite/src/opencode-import/index.ts +25 -0
  125. package/package.json +1 -1
  126. /package/dist/app/{install.d.ts → cli/install.d.ts} +0 -0
  127. /package/dist/app/{startup-checks.d.ts → cli/startup-checks.d.ts} +0 -0
  128. /package/dist/app/{startup-checks.js → cli/startup-checks.js} +0 -0
  129. /package/dist/app/{startup-info.d.ts → cli/startup-info.d.ts} +0 -0
  130. /package/dist/app/{startup-info.js → cli/startup-info.js} +0 -0
  131. /package/dist/app/{update.d.ts → cli/update.d.ts} +0 -0
  132. /package/dist/app/{update.js → cli/update.js} +0 -0
  133. /package/dist/app/{command-controller.js → commands/command-controller.js} +0 -0
  134. /package/dist/app/{command-host.js → commands/command-host.js} +0 -0
  135. /package/dist/app/{command-registry.js → commands/command-registry.js} +0 -0
  136. /package/dist/app/{command-runtime.d.ts → commands/command-runtime.d.ts} +0 -0
  137. /package/dist/app/{command-session-actions.d.ts → commands/command-session-actions.d.ts} +0 -0
  138. /package/dist/app/{shell-command.d.ts → commands/shell-command.d.ts} +0 -0
  139. /package/dist/app/{shell-command.js → commands/shell-command.js} +0 -0
  140. /package/dist/app/{extension-event-bus.d.ts → extensions/extension-event-bus.d.ts} +0 -0
  141. /package/dist/app/{extension-event-bus.js → extensions/extension-event-bus.js} +0 -0
  142. /package/dist/app/{native-modifiers.d.ts → input/native-modifiers.d.ts} +0 -0
  143. /package/dist/app/{terminal-edit-shortcuts.d.ts → input/terminal-edit-shortcuts.d.ts} +0 -0
  144. /package/dist/app/{terminal-edit-shortcuts.js → input/terminal-edit-shortcuts.js} +0 -0
  145. /package/dist/app/{model-usage-controller.d.ts → model/model-usage-controller.d.ts} +0 -0
  146. /package/dist/app/{conversation-viewport.js → rendering/conversation-viewport.js} +0 -0
  147. /package/dist/app/{dcp-stats.d.ts → rendering/dcp-stats.d.ts} +0 -0
  148. /package/dist/app/{blink-controller.d.ts → screen/blink-controller.d.ts} +0 -0
  149. /package/dist/app/{clipboard.d.ts → screen/clipboard.d.ts} +0 -0
  150. /package/dist/app/{clipboard.js → screen/clipboard.js} +0 -0
  151. /package/dist/app/{file-link-opener.d.ts → screen/file-link-opener.d.ts} +0 -0
  152. /package/dist/app/{file-link-opener.js → screen/file-link-opener.js} +0 -0
  153. /package/dist/app/{file-links.d.ts → screen/file-links.d.ts} +0 -0
  154. /package/dist/app/{file-links.js → screen/file-links.js} +0 -0
  155. /package/dist/app/{image-click-targets.js → screen/image-click-targets.js} +0 -0
  156. /package/dist/app/{image-opener.js → screen/image-opener.js} +0 -0
  157. /package/dist/app/{screen-selection.js → screen/screen-selection.js} +0 -0
  158. /package/dist/app/{request-history.d.ts → session/request-history.d.ts} +0 -0
  159. /package/dist/app/{nerd-font-controller.d.ts → terminal/nerd-font-controller.d.ts} +0 -0
  160. /package/dist/app/{nerd-font-controller.js → terminal/nerd-font-controller.js} +0 -0
  161. /package/dist/app/{terminal-bell-sound-controller.d.ts → terminal/terminal-bell-sound-controller.d.ts} +0 -0
  162. /package/dist/app/{terminal-controller.d.ts → terminal/terminal-controller.d.ts} +0 -0
  163. /package/dist/app/{terminal-output-buffer.d.ts → terminal/terminal-output-buffer.d.ts} +0 -0
  164. /package/dist/app/{terminal-output-buffer.js → terminal/terminal-output-buffer.js} +0 -0
  165. /package/dist/app/{workspace-undo.d.ts → workspace/workspace-undo.d.ts} +0 -0
  166. /package/dist/app/{workspace-undo.js → workspace/workspace-undo.js} +0 -0
@@ -1,7 +1,7 @@
1
- import { ANSI_RESET, colorize } from "../theme.js";
2
- import { renderMarkdownLine } from "../markdown-format.js";
3
- import { syntaxHighlightSegmentsForLine } from "../syntax-highlight.js";
4
- import { padOrTrimPlain } from "./render-text.js";
1
+ import { ANSI_RESET, colorize } from "../../theme.js";
2
+ import { renderMarkdownLine } from "../../markdown-format.js";
3
+ import { syntaxHighlightSegmentsForLine } from "../../syntax-highlight.js";
4
+ import { padOrTrimPlain } from "../rendering/render-text.js";
5
5
  import { orderedSelection } from "./screen-selection.js";
6
6
  export class ScreenStyler {
7
7
  host;
@@ -1,6 +1,6 @@
1
- import type { ConversationViewport } from "./conversation-viewport.js";
2
- import type { EditorLayoutRenderer } from "./editor-layout-renderer.js";
3
- import type { RenderedLine } from "./types.js";
1
+ import type { ConversationViewport } from "../rendering/conversation-viewport.js";
2
+ import type { EditorLayoutRenderer } from "../rendering/editor-layout-renderer.js";
3
+ import type { RenderedLine } from "../types.js";
4
4
  export type AppScrollMetrics = {
5
5
  bodyHeight: number;
6
6
  viewportColumns: number;
@@ -1,4 +1,4 @@
1
- import { sanitizeText } from "./render-text.js";
1
+ import { sanitizeText } from "../rendering/render-text.js";
2
2
  export class AppScrollController {
3
3
  host;
4
4
  scrollFromBottom = 0;
@@ -1,7 +1,7 @@
1
1
  import type { AgentSession } from "@earendil-works/pi-coding-agent";
2
- import type { Theme } from "../theme.js";
2
+ import type { Theme } from "../../theme.js";
3
3
  import type { AppBlinkController } from "./blink-controller.js";
4
- import type { SessionActivity } from "./types.js";
4
+ import type { SessionActivity } from "../types.js";
5
5
  export type AppStatusControllerHost = {
6
6
  readonly cwd: string;
7
7
  readonly theme: Theme;
@@ -1,6 +1,6 @@
1
1
  import { spawnSync } from "node:child_process";
2
2
  import { basename } from "node:path";
3
- import { GIT_BRANCH_CACHE_MS } from "./constants.js";
3
+ import { GIT_BRANCH_CACHE_MS } from "../constants.js";
4
4
  const STATUS_DOT_BLINK_KEY = "status-dot";
5
5
  export class AppStatusController {
6
6
  host;
@@ -1,6 +1,6 @@
1
1
  import type { AgentSession, AgentSessionRuntime } from "@earendil-works/pi-coding-agent";
2
- import type { ImageContent } from "../input-editor.js";
3
- import type { Entry, SessionActivity, SubmittedUserMessage } from "./types.js";
2
+ import type { ImageContent } from "../../input-editor.js";
3
+ import type { Entry, SessionActivity, SubmittedUserMessage } from "../types.js";
4
4
  export type AppQueuedMessageControllerHost = {
5
5
  runtime(): AgentSessionRuntime | undefined;
6
6
  requireRuntime(): AgentSessionRuntime;
@@ -1,5 +1,5 @@
1
- import { createId } from "./id.js";
2
- import { stringifyUnknown, submittedUserDisplayText } from "./message-content.js";
1
+ import { createId } from "../id.js";
2
+ import { stringifyUnknown, submittedUserDisplayText } from "../rendering/message-content.js";
3
3
  export class AppQueuedMessageController {
4
4
  host;
5
5
  deferredUserMessages = [];
@@ -1,8 +1,8 @@
1
1
  import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
2
2
  import { dirname, join } from "node:path";
3
3
  import { getAgentDir } from "@earendil-works/pi-coding-agent";
4
- import { REQUEST_HISTORY_MAX_BYTES, REQUEST_HISTORY_MAX_ENTRIES, REQUEST_HISTORY_MAX_ENTRY_BYTES, REQUEST_HISTORY_VERSION, } from "./constants.js";
5
- import { isRecord } from "./guards.js";
4
+ import { REQUEST_HISTORY_MAX_BYTES, REQUEST_HISTORY_MAX_ENTRIES, REQUEST_HISTORY_MAX_ENTRY_BYTES, REQUEST_HISTORY_VERSION, } from "../constants.js";
5
+ import { isRecord } from "../guards.js";
6
6
  export class AppRequestHistory {
7
7
  host;
8
8
  entries = [];
@@ -1,7 +1,7 @@
1
1
  import type { AgentSessionEvent, AgentSessionRuntime } from "@earendil-works/pi-coding-agent";
2
- import type { ConversationViewport } from "./conversation-viewport.js";
3
- import type { Entry, SessionActivity } from "./types.js";
4
- import type { WorkspaceMutation, WorkspaceMutationPreparation } from "./workspace-undo.js";
2
+ import type { ConversationViewport } from "../rendering/conversation-viewport.js";
3
+ import type { Entry, SessionActivity } from "../types.js";
4
+ import type { WorkspaceMutation, WorkspaceMutationPreparation } from "../workspace/workspace-undo.js";
5
5
  export type AppSessionEventControllerHost = {
6
6
  readonly entries: Entry[];
7
7
  runtime(): AgentSessionRuntime | undefined;
@@ -1,7 +1,7 @@
1
- import { createId } from "./id.js";
2
- import { extractImageContents, renderContent, renderUserMessageContent, stringifyUnknown } from "./message-content.js";
1
+ import { createId } from "../id.js";
2
+ import { extractImageContents, renderContent, renderUserMessageContent, stringifyUnknown } from "../rendering/message-content.js";
3
3
  import { customMessageEntry, loadSessionHistoryEntries, loadSessionHistoryEntriesAsync } from "./session-history.js";
4
- import { isRecord } from "./guards.js";
4
+ import { isRecord } from "../guards.js";
5
5
  export class AppSessionEventController {
6
6
  host;
7
7
  entryRenderVersions = new Map();
@@ -1,4 +1,4 @@
1
- import type { Entry } from "./types.js";
1
+ import type { Entry } from "../types.js";
2
2
  type SubagentsToolResultObserveOptions = {
3
3
  showSnapshot?: boolean;
4
4
  };
@@ -1,6 +1,6 @@
1
- import { isRecord } from "./guards.js";
2
- import { createId } from "./id.js";
3
- import { extractImageContents, renderContent, renderUserMessageContent, stringifyUnknown } from "./message-content.js";
1
+ import { isRecord } from "../guards.js";
2
+ import { createId } from "../id.js";
3
+ import { extractImageContents, renderContent, renderUserMessageContent, stringifyUnknown } from "../rendering/message-content.js";
4
4
  const SYSTEM_CUSTOM_MESSAGE_TYPE = "pix-system";
5
5
  const HISTORICAL_SUBAGENTS_OBSERVATION = { showSnapshot: false };
6
6
  const DEFAULT_HISTORY_CHUNK_SIZE = 50;
@@ -1,6 +1,6 @@
1
1
  import type { AgentSession, AgentSessionEvent, AgentSessionRuntime, ExtensionCommandContextActions, ExtensionError } from "@earendil-works/pi-coding-agent";
2
- import type { InputEditor } from "../input-editor.js";
3
- import type { AppOptions, Entry, PixExtensionUIContext, SessionActivity } from "./types.js";
2
+ import type { InputEditor } from "../../input-editor.js";
3
+ import type { AppOptions, Entry, PixExtensionUIContext, SessionActivity } from "../types.js";
4
4
  export type AppSessionLifecycleHost = {
5
5
  options: AppOptions;
6
6
  createRuntime(): Promise<AgentSessionRuntime>;
@@ -1,7 +1,7 @@
1
- import { createId } from "./id.js";
2
- import { stringifyUnknown } from "./message-content.js";
3
- import { collectStartupAvailabilityIssues } from "./startup-checks.js";
4
- import { createStartupInfoMessage, isEmptyStartupSession } from "./startup-info.js";
1
+ import { createId } from "../id.js";
2
+ import { stringifyUnknown } from "../rendering/message-content.js";
3
+ import { collectStartupAvailabilityIssues } from "../cli/startup-checks.js";
4
+ import { createStartupInfoMessage, isEmptyStartupSession } from "../cli/startup-info.js";
5
5
  export class AppSessionLifecycleController {
6
6
  host;
7
7
  unsubscribe;
@@ -1,5 +1,5 @@
1
1
  import { type SessionInfo } from "@earendil-works/pi-coding-agent";
2
- import type { Entry, PixMenuItem } from "./types.js";
2
+ import type { Entry, PixMenuItem } from "../types.js";
3
3
  export type SessionSearchMatch = {
4
4
  sessionEntryId?: string;
5
5
  role?: string;
@@ -1,7 +1,7 @@
1
1
  import { SessionManager } from "@earendil-works/pi-coding-agent";
2
- import { isRecord } from "./guards.js";
3
- import { renderContent, renderUserMessageContent } from "./message-content.js";
4
- import { sanitizeText } from "./render-text.js";
2
+ import { isRecord } from "../guards.js";
3
+ import { renderContent, renderUserMessageContent } from "../rendering/message-content.js";
4
+ import { sanitizeText } from "../rendering/render-text.js";
5
5
  const DEFAULT_MAX_SEARCH_RESULTS = 50;
6
6
  const DEFAULT_SNIPPET_LENGTH = 160;
7
7
  const DEFAULT_SCROLL_SAMPLE_LENGTH = 80;
@@ -1,6 +1,6 @@
1
1
  import { type AgentSession, type AgentSessionRuntime } from "@earendil-works/pi-coding-agent";
2
- import type { AppBlinkController } from "./blink-controller.js";
3
- import type { AppOptions, Entry, SessionActivity, SessionTab } from "./types.js";
2
+ import type { AppBlinkController } from "../screen/blink-controller.js";
3
+ import type { AppOptions, Entry, SessionActivity, SessionTab } from "../types.js";
4
4
  export type TabInputState = {
5
5
  text: string;
6
6
  cursor: number;
@@ -3,10 +3,10 @@ import { existsSync } from "node:fs";
3
3
  import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
4
4
  import { dirname, join, resolve } from "node:path";
5
5
  import { getAgentDir, SessionManager, } from "@earendil-works/pi-coding-agent";
6
- import { isRecord } from "./guards.js";
7
- import { createId } from "./id.js";
8
- import { createStartupInfoMessage, isEmptyStartupSession } from "./startup-info.js";
9
- import { tabPanelRows } from "./tab-line-renderer.js";
6
+ import { isRecord } from "../guards.js";
7
+ import { createId } from "../id.js";
8
+ import { createStartupInfoMessage, isEmptyStartupSession } from "../cli/startup-info.js";
9
+ import { tabPanelRows } from "../rendering/tab-line-renderer.js";
10
10
  const TAB_STATE_VERSION = 2;
11
11
  const MAX_RESTORED_TABS = 8;
12
12
  const TAB_ATTENTION_BLINK_KEY = "tab-attention";
@@ -1,4 +1,4 @@
1
- import type { SubagentAgentState, SubagentRegistry } from "./types.js";
1
+ import type { SubagentAgentState, SubagentRegistry } from "../types.js";
2
2
  export declare function subagentsRegistryPath(cwd: string): string;
3
3
  export declare function readSubagentRegistry(cwd: string): Promise<SubagentRegistry | undefined>;
4
4
  export declare function readSubagentRunStateFromFiles(runDir: string, options?: {
@@ -1,6 +1,6 @@
1
1
  import { readFile, readdir, realpath, stat } from "node:fs/promises";
2
2
  import { join, resolve } from "node:path";
3
- import { SUBAGENT_PARENT_SESSION_FILE, SUBAGENTS_REGISTRY_FILE, SUBAGENTS_RUN_ROOT } from "./constants.js";
3
+ import { SUBAGENT_PARENT_SESSION_FILE, SUBAGENTS_REGISTRY_FILE, SUBAGENTS_RUN_ROOT } from "../constants.js";
4
4
  import { isSubagentRegistry } from "./subagents-model.js";
5
5
  export function subagentsRegistryPath(cwd) {
6
6
  return join(cwd, SUBAGENTS_RUN_ROOT, SUBAGENTS_REGISTRY_FILE);
@@ -1,4 +1,4 @@
1
- import type { SubagentActiveStatus, SubagentAgentState, SubagentsLiveStateEvent, SubagentRegistry, SubagentRegistryAgent, SubagentRegistryRun, SubagentRenderMode, SubagentRunRenderDetails, SubagentStatus, SubagentTaskPreview, SubagentTerminalStatus } from "./types.js";
1
+ import type { SubagentActiveStatus, SubagentAgentState, SubagentsLiveStateEvent, SubagentRegistry, SubagentRegistryAgent, SubagentRegistryRun, SubagentRenderMode, SubagentRunRenderDetails, SubagentStatus, SubagentTaskPreview, SubagentTerminalStatus } from "../types.js";
2
2
  export declare function isSubagentsToolName(toolName: string): boolean;
3
3
  export declare function isSubagentStatus(value: unknown): value is SubagentStatus;
4
4
  export declare function isSubagentActiveStatus(value: SubagentStatus): value is SubagentActiveStatus;
@@ -1,8 +1,8 @@
1
1
  import { basename, isAbsolute, join, resolve } from "node:path";
2
- import { SUBAGENT_ACTIVE_STATUSES, SUBAGENT_RENDER_MODES, SUBAGENT_STATUSES, SUBAGENT_TERMINAL_STATUSES, SUBAGENTS_TOOL_NAME, SUBAGENTS_TOOL_NAME_PREFIX, } from "./constants.js";
3
- import { isRecord, isStringArray } from "./guards.js";
4
- import { APP_ICONS } from "./icons.js";
5
- import { stripProviderFromModelRef } from "./model-ref.js";
2
+ import { SUBAGENT_ACTIVE_STATUSES, SUBAGENT_RENDER_MODES, SUBAGENT_STATUSES, SUBAGENT_TERMINAL_STATUSES, SUBAGENTS_TOOL_NAME, SUBAGENTS_TOOL_NAME_PREFIX, } from "../constants.js";
3
+ import { isRecord, isStringArray } from "../guards.js";
4
+ import { APP_ICONS } from "../icons.js";
5
+ import { stripProviderFromModelRef } from "../model/model-ref.js";
6
6
  export function isSubagentsToolName(toolName) {
7
7
  return toolName === SUBAGENTS_TOOL_NAME || toolName.startsWith(SUBAGENTS_TOOL_NAME_PREFIX);
8
8
  }
@@ -1,4 +1,4 @@
1
- import type { SubagentsWidgetState } from "./types.js";
1
+ import type { SubagentsWidgetState } from "../types.js";
2
2
  export type SubagentsToolResultObserveOptions = {
3
3
  showSnapshot?: boolean;
4
4
  };
@@ -1,7 +1,7 @@
1
1
  import { watch } from "node:fs";
2
2
  import { join, resolve } from "node:path";
3
- import { SUBAGENTS_POLL_INTERVAL_MS, SUBAGENTS_RUN_ROOT } from "./constants.js";
4
- import { stringifyUnknown } from "./message-content.js";
3
+ import { SUBAGENTS_POLL_INTERVAL_MS, SUBAGENTS_RUN_ROOT } from "../constants.js";
4
+ import { stringifyUnknown } from "../rendering/message-content.js";
5
5
  import { readSubagentRegistry, readSubagentRunStateFromFiles, subagentRunHasParentSession } from "./subagents-files.js";
6
6
  import { activeSubagentStates, allSubagentStatesTerminal, isSubagentRunRenderDetails, isSubagentsLiveStateEvent, isSubagentsToolName, resolveSubagentRunDir, } from "./subagents-model.js";
7
7
  const SUBAGENTS_FILE_WATCH_DEBOUNCE_MS = 75;
@@ -2,7 +2,7 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
2
  import { homedir } from "node:os";
3
3
  import { dirname, join } from "node:path";
4
4
  import { applyEdits, modify, parse as parseJsonc } from "jsonc-parser";
5
- import { APP_ICONS } from "./icons.js";
5
+ import { APP_ICONS } from "../icons.js";
6
6
  const TERMINAL_BELL_CONFIG_KEY = "terminalBell";
7
7
  const SOUND_CONFIG_KEY = "sound";
8
8
  export function getPiToolsSuiteUserConfigPath(homeDir = homedir()) {
@@ -1,5 +1,5 @@
1
- import { ANSI_RESET } from "../theme.js";
2
- import { DISABLE_BRACKETED_PASTE, DISABLE_TERMINAL_KEY_REPORTING, DISABLE_TERMINAL_WRAP, CLEAR_TERMINAL, ENABLE_BRACKETED_PASTE, ENABLE_TERMINAL_KEY_REPORTING, ENABLE_TERMINAL_WRAP, HIDE_CURSOR, RUNTIME_DISPOSE_GRACE_MS, SHOW_CURSOR, } from "./constants.js";
1
+ import { ANSI_RESET } from "../../theme.js";
2
+ import { DISABLE_BRACKETED_PASTE, DISABLE_TERMINAL_KEY_REPORTING, DISABLE_TERMINAL_WRAP, CLEAR_TERMINAL, ENABLE_BRACKETED_PASTE, ENABLE_TERMINAL_KEY_REPORTING, ENABLE_TERMINAL_WRAP, HIDE_CURSOR, RUNTIME_DISPOSE_GRACE_MS, SHOW_CURSOR, } from "../constants.js";
3
3
  export class AppTerminalController {
4
4
  host;
5
5
  terminalEnabled = false;
@@ -1,4 +1,4 @@
1
- import type { StyledSegment, TodoAction, TodoDetails, TodoLiveStateEvent, TodoPriority, TodoStatus, TodoTask, TodoTaskLinePart, TodoTaskRow } from "./types.js";
1
+ import type { StyledSegment, TodoAction, TodoDetails, TodoLiveStateEvent, TodoPriority, TodoStatus, TodoTask, TodoTaskLinePart, TodoTaskRow } from "../types.js";
2
2
  export declare function isTodoAction(value: unknown): value is TodoAction;
3
3
  export declare function isTodoStatus(value: unknown): value is TodoStatus;
4
4
  export declare function isTodoPriority(value: unknown): value is TodoPriority;
@@ -1,6 +1,6 @@
1
- import { TODO_ACTIONS, TODO_PRIORITIES, TODO_STATUSES } from "./constants.js";
2
- import { isNumberArray, isRecord, isStringArray } from "./guards.js";
3
- import { APP_ICONS } from "./icons.js";
1
+ import { TODO_ACTIONS, TODO_PRIORITIES, TODO_STATUSES } from "../constants.js";
2
+ import { isNumberArray, isRecord, isStringArray } from "../guards.js";
3
+ import { APP_ICONS } from "../icons.js";
4
4
  export function isTodoAction(value) {
5
5
  return typeof value === "string" && TODO_ACTIONS.includes(value);
6
6
  }
@@ -1,4 +1,4 @@
1
- import type { TodoDetails } from "./types.js";
1
+ import type { TodoDetails } from "../types.js";
2
2
  export type TodoWidgetControllerHost = {
3
3
  sessionFile?(): string | undefined;
4
4
  isRunning(): boolean;
@@ -1,6 +1,6 @@
1
1
  import { resolve } from "node:path";
2
- import { TODO_TOOL_NAME } from "./constants.js";
3
- import { stringifyUnknown } from "./message-content.js";
2
+ import { TODO_TOOL_NAME } from "../constants.js";
3
+ import { stringifyUnknown } from "../rendering/message-content.js";
4
4
  import { hasOpenTodoTasks, isTodoDetails, isTodoLiveStateEvent } from "./todo-model.js";
5
5
  export class AppTodoWidgetController {
6
6
  host;
@@ -3,8 +3,8 @@ import type { ImageContent } from "../input-editor.js";
3
3
  import type { SyntaxLineHighlight } from "../syntax-highlight.js";
4
4
  import type { ThemeName } from "../theme.js";
5
5
  import type { ToastKind, ToastNotifier } from "../ui.js";
6
- import type { RenderedLink } from "./file-links.js";
7
- import type { WorkspaceMutation } from "./workspace-undo.js";
6
+ import type { RenderedLink } from "./screen/file-links.js";
7
+ import type { WorkspaceMutation } from "./workspace/workspace-undo.js";
8
8
  import type { SUBAGENT_ACTIVE_STATUSES, SUBAGENT_RENDER_MODES, SUBAGENT_STATUSES, SUBAGENT_TERMINAL_STATUSES, THINKING_LEVELS, TODO_ACTIONS, TODO_PRIORITIES, TODO_STATUSES } from "./constants.js";
9
9
  export type ThinkingLevel = (typeof THINKING_LEVELS)[number];
10
10
  export type NativeModifierKey = "shift" | "command" | "control" | "option";
@@ -1,5 +1,5 @@
1
1
  import { type AgentSessionRuntime } from "@earendil-works/pi-coding-agent";
2
- import type { Entry } from "./types.js";
2
+ import type { Entry } from "../types.js";
3
3
  import { type WorkspaceMutation, type WorkspaceMutationFromToolInput, type WorkspaceMutationPreparation } from "./workspace-undo.js";
4
4
  export type AppWorkspaceActionsControllerHost = {
5
5
  readonly entries: Entry[];
@@ -1,7 +1,7 @@
1
1
  import { getAgentDir } from "@earendil-works/pi-coding-agent";
2
- import { copyTextToClipboard } from "./clipboard.js";
3
- import { isRecord } from "./guards.js";
4
- import { createId } from "./id.js";
2
+ import { copyTextToClipboard } from "../screen/clipboard.js";
3
+ import { isRecord } from "../guards.js";
4
+ import { createId } from "../id.js";
5
5
  import { loadWorkspaceUndoIndex, prepareWorkspaceMutation, revertWorkspaceMutations, saveWorkspaceUndoIndex, workspaceMutationFromToolExecution, workspaceUndoIndexKey, } from "./workspace-undo.js";
6
6
  export class AppWorkspaceActionsController {
7
7
  host;
package/dist/main.js CHANGED
@@ -1,6 +1,6 @@
1
- import { parseArgs } from "./app/cli.js";
1
+ import { parseArgs } from "./app/cli/cli.js";
2
2
  import { PiUiExtendApp } from "./app/app.js";
3
- import { stringifyUnknown } from "./app/message-content.js";
3
+ import { stringifyUnknown } from "./app/rendering/message-content.js";
4
4
  async function main() {
5
5
  const options = parseArgs(process.argv.slice(2));
6
6
  const app = new PiUiExtendApp(options);
@@ -73,6 +73,84 @@ DCP settings are stored only under `dcp` in the user shared config file `~/.conf
73
73
 
74
74
  `minContextPercent` / `maxContextPercent` accept legacy fractions (`0.25`), percent strings (`"25%"`), or absolute token counts when Pi knows the current model context window. `minContextLimit` / `maxContextLimit` and `modelMinContextLimits` / `modelMaxContextLimits` are explicit absolute-or-percent aliases. If `compress.protectUserMessages` is enabled, range compression appends selected user messages verbatim instead of rejecting the range; individual message compression still skips protected raw user messages. Protected tool outputs are copied into summaries for tools protected by name or `protectedFilePatterns`; protected `subagents` result reads also try to include the saved `result.md` artifact when available.
75
75
 
76
+ ## LSP setup
77
+
78
+ The LSP module reads language-server definitions from `lsp.servers` in the shared config file:
79
+
80
+ ```text
81
+ ~/.config/pi/pi-tools-suite.jsonc
82
+ ```
83
+
84
+ Install the language servers used by the bundled example config. The commands below are written for macOS/Linux with a POSIX shell; most npm, `dotnet`, `pip`, and `rustup` commands also work on Windows, but paths and the GDScript wrapper differ.
85
+
86
+ ```bash
87
+ # TypeScript / JavaScript
88
+ npm install -g typescript typescript-language-server
89
+
90
+ # Python
91
+ python3 -m pip install --user python-lsp-server
92
+
93
+ # C# / Unity
94
+ dotnet tool install -g Microsoft.CodeAnalysis.LanguageServer
95
+
96
+ # GDScript / Godot
97
+ # Install Godot 4.x and make sure the `godot` command is on PATH.
98
+ # macOS Homebrew example. On other OSes, use the official Godot installer/package.
99
+ brew install --cask godot
100
+
101
+ # Ruby
102
+ brew install ruby-lsp
103
+ # or, if using RubyGems directly:
104
+ gem install ruby-lsp
105
+
106
+ # Rust
107
+ rustup component add rust-analyzer
108
+
109
+ # Markdown
110
+ npm install -g vscode-langservers-extracted
111
+ ```
112
+
113
+ Extra runtime requirements:
114
+
115
+ - The GDScript wrapper also needs `nc` and `python3`; both are available by default on most macOS/Linux setups. The wrapper starts Godot headless on a free localhost port and the LSP manager kills the whole process group on shutdown/abort.
116
+ - C# expects `~/.dotnet/tools` on `PATH`, or an explicit `bin` path such as `~/.dotnet/tools/roslyn-language-server` in the config.
117
+ - Rust diagnostics require a Rust project root such as `Cargo.toml`.
118
+ - C#/Unity diagnostics require a project root such as `*.csproj`, `*.sln`, or Unity `ProjectSettings/ProjectVersion.txt`.
119
+ - Markdown link diagnostics are provided by `vscode-markdown-language-server` when validation is enabled; Mermaid fence checks are supplemented locally by pi-tools-suite, so no separate Mermaid LSP is required for the default diagnostics.
120
+
121
+ OS notes:
122
+
123
+ - macOS/Linux: the sample commands and default GDScript wrapper are intended to work as-is once the binaries are on `PATH`.
124
+ - Windows: npm, Python, .NET, Ruby, Rust, and Markdown servers can be installed natively, but adjust executable paths, for example `%USERPROFILE%\.dotnet\tools\roslyn-language-server.exe`. The bundled GDScript wrapper uses `bash`, `nc`, POSIX signals, and process groups, so use WSL/Git Bash or replace that server command with a Windows-specific wrapper.
125
+ - Package-manager commands vary by distro. Replace `brew install ...` with your OS package manager or the official installer where appropriate.
126
+
127
+ Minimal shared config shape:
128
+
129
+ ```jsonc
130
+ {
131
+ "lsp": {
132
+ "servers": [
133
+ {
134
+ "id": "typescript",
135
+ "include": ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx", "**/*.mjs"],
136
+ "rootMarkers": ["tsconfig.json", "package.json"],
137
+ "bin": "typescript-language-server",
138
+ "args": ["--stdio"],
139
+ "languageIdByExtension": {
140
+ ".ts": "typescript",
141
+ ".tsx": "typescriptreact",
142
+ ".js": "javascript",
143
+ ".jsx": "javascriptreact",
144
+ ".mjs": "javascript"
145
+ }
146
+ }
147
+ ]
148
+ }
149
+ }
150
+ ```
151
+
152
+ Project-local overrides can be added in `.pi/pi-tools-suite.jsonc`; pi-tools-suite asks for trust before using project-local LSP binaries.
153
+
76
154
  ## Async sub-agents
77
155
 
78
156
  Sub-agent model routing normally follows task overrides, subagent type config, then `ASYNC_SUBAGENTS_MODEL` / `PI_SUBAGENTS_MODEL` fallbacks. Set `ASYNC_SUBAGENTS_FORCE_CURRENT_MODEL=1` (or `PI_SUBAGENTS_FORCE_CURRENT_MODEL=1`) to ignore task/config/env model choices and launch every sub-agent with the current parent session model. When this flag is enabled, any `--model` entries in sub-agent extra args are stripped so they cannot override the current model.
@@ -16,6 +16,8 @@ This is an orchestration hint for Pi, not a replacement for the user's instructi
16
16
 
17
17
  Default posture: orchestration-first for non-GPT models. For broad, multi-file, ambiguous, review/audit, frontend, test-strategy, architecture, or root-cause work, prefer ultrawork mode: split independent tracks and spawn focused async subagents with the configured roles. Keep the parent context lean, collect compact results only when needed, synthesize the findings, then verify before finishing.
18
18
 
19
+ Before DCP/compress while work is unfinished, keep one in_progress todo with objective + next step; compression summaries must preserve Active objective and Next step.
20
+
19
21
  Do not over-delegate trivial work. For a simple question, one known file, exact lookup, typo, or narrow edit, solve directly with the cheapest suitable tool.
20
22
  </agent_strategy>`;
21
23
 
@@ -24,6 +26,8 @@ This is a GPT-compatible execution hint for Pi, not a replacement for the user's
24
26
 
25
27
  Default posture: autonomous deep worker. Build context directly, make concrete progress, edit and verify end-to-end. Use async subagents and ultrawork mode when the user asks for parallel/delegated work or when independent tracks will clearly reduce risk, but do not force orchestration onto narrow tasks.
26
28
 
29
+ Before DCP/compress while work is unfinished, keep one in_progress todo with objective + next step; compression summaries must preserve Active objective and Next step.
30
+
27
31
  For broad work, keep delegation explicit and bounded: spawn focused review/research/tests/frontend/deep tracks, read compact results, make the final decisions in the parent session, and report only what matters.
28
32
  </agent_strategy>`;
29
33
 
@@ -375,7 +375,12 @@ export function spawnAgent(
375
375
  ...(promptImages ? { images: promptImages } : {}),
376
376
  }),
377
377
  ].join(""));
378
- proc.stdin.end();
378
+ // Keep stdin open while the RPC prompt is running. pi RPC mode treats stdin
379
+ // EOF as a shutdown request, while the prompt command itself is handled
380
+ // asynchronously after preflight. Closing stdin here can therefore terminate
381
+ // the child before message_end/agent_end events are emitted, producing exit 0
382
+ // with no result.md. The child is terminated explicitly after agent_end,
383
+ // timeout, stop, or process error.
379
384
 
380
385
  const pid = proc.pid!;
381
386
  fs.writeFileSync(path.join(agentDir, "pid"), String(pid), "utf-8");
@@ -28,6 +28,8 @@ Summaries should be proportional to future usefulness, not proportional to the a
28
28
 
29
29
  Use \`compress\` as steady housekeeping while you work. After any completed implementation + verification slice, compress that closed slice before replying or starting a new task unless the next step needs exact raw logs/diffs. Do not carry large stale tool outputs across task boundaries.
30
30
 
31
+ Before compressing while work is unfinished, ensure one \`todo in_progress\` captures the active objective and next step.
32
+
31
33
  When a \`<dcp-system-reminder>\` appears, treat it as an active instruction for the next safe action, not as background advice. Before making another exploratory tool call or starting a new subtask, check whether any earlier slice is closed; if yes, call \`compress\` first. Do not merely acknowledge the reminder or postpone it across multiple tool calls.
32
34
 
33
35
  CADENCE, SIGNALS, AND LATENCY
@@ -83,6 +85,8 @@ If a \`<dcp-system-reminder>\` is present in context, treat it as a direct instr
83
85
  THE SUMMARY
84
86
  Your summary must be COMPLETE FOR CONTINUATION, not a transcript rewrite. Preserve only information that will plausibly matter later: user intent, accepted constraints, decisions, files/symbols changed or inspected, exact errors that are still actionable, verification status, and next steps.
85
87
 
88
+ If active unfinished work exists, start with \`Active objective\` and \`Next step\`.
89
+
86
90
  Default to a compact structured summary (roughly 5-15 bullets for a normal completed work slice). Grow beyond that only when the compressed range contains multiple independent decisions, unresolved blockers, or precise state that is genuinely required to continue.
87
91
 
88
92
  Do not copy long raw code, JSON, diffs, logs, or tool output into summaries. Prefer semantic descriptions such as “updated foo.json so scene_assets_1.zai-svg has maxConcurrentRuns set to 5.” Include exact snippets only when the literal text is required for safe continuation, and keep them short and single-line.