@oh-my-pi/pi-coding-agent 15.0.0 → 15.0.2

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 (165) hide show
  1. package/CHANGELOG.md +79 -0
  2. package/examples/extensions/plan-mode.ts +0 -1
  3. package/package.json +10 -10
  4. package/scripts/build-binary.ts +5 -0
  5. package/src/autoresearch/helpers.ts +17 -0
  6. package/src/autoresearch/tools/log-experiment.ts +9 -17
  7. package/src/autoresearch/tools/run-experiment.ts +2 -17
  8. package/src/capability/skill.ts +7 -0
  9. package/src/cli/list-models.ts +1 -1
  10. package/src/cli/shell-cli.ts +3 -13
  11. package/src/cli/update-cli.ts +1 -1
  12. package/src/cli.ts +10 -29
  13. package/src/commands/commit.ts +10 -0
  14. package/src/commit/agentic/tools/propose-changelog.ts +8 -1
  15. package/src/commit/analysis/conventional.ts +8 -66
  16. package/src/commit/map-reduce/reduce-phase.ts +6 -65
  17. package/src/commit/pipeline.ts +2 -2
  18. package/src/commit/shared-llm.ts +89 -0
  19. package/src/config/config-file.ts +210 -0
  20. package/src/config/model-equivalence.ts +8 -11
  21. package/src/config/model-registry.ts +44 -3
  22. package/src/config/model-resolver.ts +1 -4
  23. package/src/config/settings-schema.ts +82 -1
  24. package/src/config/settings.ts +1 -1
  25. package/src/config.ts +3 -219
  26. package/src/discovery/claude-plugins.ts +19 -7
  27. package/src/edit/renderer.ts +7 -1
  28. package/src/eval/js/executor.ts +3 -0
  29. package/src/eval/js/shared/rewrite-imports.ts +2 -2
  30. package/src/eval/py/executor.ts +5 -0
  31. package/src/eval/py/runner.py +42 -11
  32. package/src/eval/py/runtime.ts +1 -0
  33. package/src/exa/factory.ts +2 -2
  34. package/src/exa/mcp-client.ts +74 -1
  35. package/src/exec/bash-executor.ts +5 -1
  36. package/src/export/html/template.generated.ts +1 -1
  37. package/src/export/html/template.js +0 -11
  38. package/src/extensibility/extensions/get-commands-handler.ts +77 -0
  39. package/src/extensibility/extensions/runner.ts +1 -1
  40. package/src/extensibility/extensions/types.ts +89 -223
  41. package/src/extensibility/hooks/types.ts +89 -314
  42. package/src/extensibility/plugins/legacy-pi-compat.ts +48 -31
  43. package/src/extensibility/shared-events.ts +343 -0
  44. package/src/extensibility/skills.ts +9 -0
  45. package/src/goals/index.ts +3 -0
  46. package/src/goals/runtime.ts +500 -0
  47. package/src/goals/state.ts +37 -0
  48. package/src/goals/tools/goal-tool.ts +237 -0
  49. package/src/hashline/anchors.ts +2 -2
  50. package/src/hashline/input.ts +2 -1
  51. package/src/hashline/parser.ts +27 -3
  52. package/src/hindsight/mental-models.ts +1 -1
  53. package/src/internal-urls/agent-protocol.ts +1 -20
  54. package/src/internal-urls/artifact-protocol.ts +1 -19
  55. package/src/internal-urls/docs-index.generated.ts +11 -12
  56. package/src/internal-urls/registry-helpers.ts +25 -0
  57. package/src/internal-urls/router.ts +8 -0
  58. package/src/internal-urls/types.ts +21 -0
  59. package/src/lsp/config.ts +15 -6
  60. package/src/lsp/defaults.json +6 -2
  61. package/src/main.ts +11 -2
  62. package/src/mcp/oauth-flow.ts +20 -0
  63. package/src/modes/acp/acp-agent.ts +327 -95
  64. package/src/modes/components/assistant-message.ts +14 -8
  65. package/src/modes/components/bash-execution.ts +24 -63
  66. package/src/modes/components/custom-message.ts +14 -40
  67. package/src/modes/components/eval-execution.ts +27 -57
  68. package/src/modes/components/execution-shared.ts +102 -0
  69. package/src/modes/components/hook-message.ts +17 -49
  70. package/src/modes/components/mcp-add-wizard.ts +26 -5
  71. package/src/modes/components/message-frame.ts +88 -0
  72. package/src/modes/components/model-selector.ts +1 -1
  73. package/src/modes/components/session-observer-overlay.ts +6 -2
  74. package/src/modes/components/session-selector.ts +1 -1
  75. package/src/modes/components/status-line/segments.ts +93 -8
  76. package/src/modes/components/status-line/types.ts +4 -0
  77. package/src/modes/components/status-line.ts +28 -10
  78. package/src/modes/components/tool-execution.ts +7 -8
  79. package/src/modes/controllers/command-controller-shared.ts +108 -0
  80. package/src/modes/controllers/command-controller.ts +13 -4
  81. package/src/modes/controllers/event-controller.ts +36 -7
  82. package/src/modes/controllers/extension-ui-controller.ts +3 -2
  83. package/src/modes/controllers/input-controller.ts +13 -0
  84. package/src/modes/controllers/mcp-command-controller.ts +56 -61
  85. package/src/modes/controllers/ssh-command-controller.ts +18 -57
  86. package/src/modes/interactive-mode.ts +624 -52
  87. package/src/modes/print-mode.ts +16 -86
  88. package/src/modes/rpc/host-uris.ts +235 -0
  89. package/src/modes/rpc/rpc-mode.ts +41 -88
  90. package/src/modes/rpc/rpc-types.ts +57 -0
  91. package/src/modes/runtime-init.ts +116 -0
  92. package/src/modes/theme/defaults/dark-poimandres.json +3 -0
  93. package/src/modes/theme/defaults/light-poimandres.json +3 -0
  94. package/src/modes/theme/theme.ts +24 -6
  95. package/src/modes/types.ts +14 -3
  96. package/src/modes/utils/context-usage.ts +13 -13
  97. package/src/modes/utils/ui-helpers.ts +10 -3
  98. package/src/plan-mode/approved-plan.ts +35 -1
  99. package/src/prompts/goals/goal-budget-limit.md +16 -0
  100. package/src/prompts/goals/goal-continuation.md +28 -0
  101. package/src/prompts/goals/goal-mode-active.md +23 -0
  102. package/src/prompts/system/plan-mode-active.md +5 -5
  103. package/src/prompts/system/plan-mode-tool-decision-reminder.md +1 -1
  104. package/src/prompts/tools/bash.md +6 -0
  105. package/src/prompts/tools/github.md +4 -4
  106. package/src/prompts/tools/goal.md +13 -0
  107. package/src/prompts/tools/hashline.md +101 -117
  108. package/src/prompts/tools/read.md +55 -36
  109. package/src/prompts/tools/resolve.md +6 -5
  110. package/src/sdk.ts +12 -5
  111. package/src/session/agent-session.ts +428 -106
  112. package/src/session/blob-store.ts +36 -3
  113. package/src/session/messages.ts +67 -2
  114. package/src/session/session-manager.ts +131 -12
  115. package/src/session/session-storage.ts +33 -15
  116. package/src/session/streaming-output.ts +309 -13
  117. package/src/slash-commands/builtin-registry.ts +18 -0
  118. package/src/ssh/ssh-executor.ts +5 -0
  119. package/src/system-prompt.ts +4 -2
  120. package/src/task/discovery.ts +5 -2
  121. package/src/task/executor.ts +19 -8
  122. package/src/task/index.ts +3 -0
  123. package/src/task/render.ts +21 -15
  124. package/src/task/types.ts +4 -0
  125. package/src/tools/ast-edit.ts +21 -120
  126. package/src/tools/ast-grep.ts +21 -119
  127. package/src/tools/bash-command-fixup.ts +47 -0
  128. package/src/tools/bash-interactive.ts +9 -1
  129. package/src/tools/bash.ts +66 -19
  130. package/src/tools/browser/attach.ts +3 -3
  131. package/src/tools/browser/launch.ts +81 -18
  132. package/src/tools/browser/registry.ts +1 -5
  133. package/src/tools/browser/render.ts +2 -2
  134. package/src/tools/browser/tab-supervisor.ts +51 -14
  135. package/src/tools/conflict-detect.ts +15 -4
  136. package/src/tools/eval.ts +12 -2
  137. package/src/tools/find.ts +20 -38
  138. package/src/tools/gh.ts +44 -10
  139. package/src/tools/index.ts +22 -11
  140. package/src/tools/inspect-image.ts +3 -10
  141. package/src/tools/job.ts +16 -7
  142. package/src/tools/output-meta.ts +202 -37
  143. package/src/tools/path-utils.ts +125 -2
  144. package/src/tools/read.ts +548 -237
  145. package/src/tools/render-utils.ts +92 -0
  146. package/src/tools/renderers.ts +2 -0
  147. package/src/tools/resolve.ts +72 -44
  148. package/src/tools/search.ts +120 -186
  149. package/src/tools/ssh.ts +3 -2
  150. package/src/tools/write.ts +64 -9
  151. package/src/utils/file-mentions.ts +1 -1
  152. package/src/utils/image-loading.ts +7 -3
  153. package/src/utils/image-resize.ts +32 -43
  154. package/src/vim/parser.ts +0 -17
  155. package/src/vim/render.ts +1 -1
  156. package/src/vim/types.ts +1 -1
  157. package/src/web/search/providers/anthropic.ts +5 -0
  158. package/src/web/search/providers/exa.ts +3 -0
  159. package/src/web/search/providers/gemini.ts +40 -95
  160. package/src/web/search/providers/jina.ts +5 -2
  161. package/src/web/search/providers/zai.ts +5 -2
  162. package/src/prompts/tools/exit-plan-mode.md +0 -6
  163. package/src/tools/exit-plan-mode.ts +0 -97
  164. package/src/utils/fuzzy.ts +0 -108
  165. package/src/utils/image-convert.ts +0 -27
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Shared helpers for internal-url protocol handlers that resolve IDs against
3
+ * registered agent sessions.
4
+ */
5
+ import { AgentRegistry } from "../registry/agent-registry";
6
+
7
+ /**
8
+ * Snapshot of artifacts dirs for every registered session, deduped.
9
+ *
10
+ * Prefers `sessionManager.getArtifactsDir()` because subagents adopt their
11
+ * parent's `ArtifactManager` and report the parent's dir there; dedup then
12
+ * collapses parent + N subagents (the whole agent tree) to one entry. Falls
13
+ * back to the raw session file (with the `.jsonl` suffix stripped) when no
14
+ * live session reference is attached.
15
+ */
16
+ export function artifactsDirsFromRegistry(): string[] {
17
+ const dirs: string[] = [];
18
+ for (const ref of AgentRegistry.global().list()) {
19
+ const dir =
20
+ ref.session?.sessionManager.getArtifactsDir() ?? (ref.sessionFile ? ref.sessionFile.slice(0, -6) : null);
21
+ if (!dir) continue;
22
+ if (!dirs.includes(dir)) dirs.push(dir);
23
+ }
24
+ return dirs;
25
+ }
@@ -50,6 +50,14 @@ export class InternalUrlRouter {
50
50
  this.#handlers.set(handler.scheme.toLowerCase(), handler);
51
51
  }
52
52
 
53
+ unregister(scheme: string): boolean {
54
+ return this.#handlers.delete(scheme.toLowerCase());
55
+ }
56
+
57
+ getHandler(scheme: string): ProtocolHandler | undefined {
58
+ return this.#handlers.get(scheme.toLowerCase());
59
+ }
60
+
53
61
  canHandle(input: string): boolean {
54
62
  const match = input.match(/^([a-z][a-z0-9+.-]*):\/\//i);
55
63
  if (!match) return false;
@@ -63,6 +63,18 @@ export interface ResolveContext {
63
63
  signal?: AbortSignal;
64
64
  }
65
65
 
66
+ /**
67
+ * Caller context for write operations dispatched to host-owned URI handlers.
68
+ * Mirrors {@link ResolveContext} so handlers that share read/write state can
69
+ * accept the same shape.
70
+ */
71
+ export interface WriteContext {
72
+ /** Working directory of the calling session. */
73
+ cwd?: string;
74
+ /** Caller's abort signal. */
75
+ signal?: AbortSignal;
76
+ }
77
+
66
78
  /**
67
79
  * Handler for a specific internal URL scheme (e.g., agent://, memory://, skill://, mcp://).
68
80
  */
@@ -86,4 +98,13 @@ export interface ProtocolHandler {
86
98
  * @throws Error with user-friendly message if resolution fails
87
99
  */
88
100
  resolve(url: InternalUrl, context?: ResolveContext): Promise<InternalResource>;
101
+ /**
102
+ * Optional write hook. When present, the write tool dispatches
103
+ * `write(url, content)` to this handler instead of writing to a filesystem
104
+ * path. The handler is responsible for any persistence and validation.
105
+ *
106
+ * Handlers that omit this method are treated as read-only; the write tool
107
+ * surfaces a clear "not writable" error when invoked against them.
108
+ */
109
+ write?(url: InternalUrl, content: string, context?: WriteContext): Promise<void>;
89
110
  }
package/src/lsp/config.ts CHANGED
@@ -154,16 +154,25 @@ function applyRuntimeDefaults(servers: Record<string, ServerConfig>): Record<str
154
154
  * Check if any root marker file exists in the directory
155
155
  */
156
156
  export function hasRootMarkers(cwd: string, markers: string[]): boolean {
157
+ let entries: string[] | null = null;
157
158
  for (const marker of markers) {
158
- // Handle glob-like patterns (e.g., "*.cabal")
159
+ // Handle glob-like patterns (e.g., "*.cabal"). Root markers live at the
160
+ // project root, so a one-level readdir is sufficient — and avoids
161
+ // Bun.Glob descending into node_modules for patterns like "**/*.cabal".
159
162
  if (marker.includes("*")) {
160
- try {
161
- const scan = new Bun.Glob(marker).scanSync({ cwd, onlyFiles: false });
162
- for (const _ of scan) {
163
+ if (entries === null) {
164
+ try {
165
+ entries = fs.readdirSync(cwd);
166
+ } catch {
167
+ entries = [];
168
+ logger.warn("Failed to list directory for glob root marker.", { marker, cwd });
169
+ }
170
+ }
171
+ const glob = new Bun.Glob(marker);
172
+ for (const entry of entries) {
173
+ if (glob.match(entry)) {
163
174
  return true;
164
175
  }
165
- } catch {
166
- logger.warn("Failed to resolve glob root marker.", { marker, cwd });
167
176
  }
168
177
  continue;
169
178
  }
@@ -5,7 +5,11 @@
5
5
  "fileTypes": [".rs"],
6
6
  "rootMarkers": ["Cargo.toml", "rust-analyzer.toml"],
7
7
  "initOptions": {},
8
- "settings": {},
8
+ "settings": {
9
+ "rust-analyzer": {
10
+ "checkOnSave": false
11
+ }
12
+ },
9
13
  "capabilities": {
10
14
  "flycheck": true,
11
15
  "ssr": true,
@@ -424,7 +428,7 @@
424
428
  "args": ["server"],
425
429
  "fileTypes": [".md", ".markdown"],
426
430
  "rootMarkers": [".marksman.toml", ".git"],
427
- "warmupTimeoutMs": 15000
431
+ "warmupTimeoutMs": 2000
428
432
  },
429
433
  "texlab": {
430
434
  "command": "texlab",
package/src/main.ts CHANGED
@@ -129,7 +129,7 @@ export async function submitInteractiveInput(
129
129
  InteractiveMode,
130
130
  "markPendingSubmissionStarted" | "finishPendingSubmission" | "showError" | "checkShutdownRequested"
131
131
  >,
132
- session: Pick<AgentSession, "prompt">,
132
+ session: Pick<AgentSession, "prompt" | "promptCustomMessage">,
133
133
  input: SubmittedUserInput,
134
134
  ): Promise<void> {
135
135
  if (input.cancelled) {
@@ -141,7 +141,16 @@ export async function submitInteractiveInput(
141
141
  if (!input.started && !mode.markPendingSubmissionStarted(input)) {
142
142
  return;
143
143
  }
144
- await session.prompt(input.text, { images: input.images });
144
+ if (input.customType) {
145
+ await session.promptCustomMessage({
146
+ customType: input.customType,
147
+ content: input.text,
148
+ display: input.display ?? false,
149
+ attribution: "agent",
150
+ });
151
+ } else {
152
+ await session.prompt(input.text, { images: input.images });
153
+ }
145
154
  } catch (error: unknown) {
146
155
  const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
147
156
  mode.showError(errorMessage);
@@ -133,6 +133,26 @@ export class MCPOAuthFlow extends OAuthCallbackFlow {
133
133
  this.#resolvedClientId = this.#resolveClientId(config);
134
134
  }
135
135
 
136
+ /**
137
+ * Client id used during the authorization request. Returns the value supplied
138
+ * via {@link MCPOAuthConfig.clientId} or, when the server required dynamic
139
+ * client registration, the id issued during registration. `undefined` until
140
+ * {@link generateAuthUrl} (or {@link login}) has run for a server that needs
141
+ * a client id.
142
+ */
143
+ get resolvedClientId(): string | undefined {
144
+ return this.#resolvedClientId;
145
+ }
146
+
147
+ /**
148
+ * Client secret issued by dynamic client registration, if any. Always
149
+ * `undefined` for PKCE-only/public clients and when the caller supplies the
150
+ * client id via config.
151
+ */
152
+ get registeredClientSecret(): string | undefined {
153
+ return this.#registeredClientSecret;
154
+ }
155
+
136
156
  async generateAuthUrl(state: string, redirectUri: string): Promise<{ url: string; instructions?: string }> {
137
157
  if (!this.#resolvedClientId) {
138
158
  await this.#tryRegisterClient(redirectUri);