@oh-my-pi/pi-coding-agent 14.0.5 → 14.1.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.
- package/CHANGELOG.md +120 -0
- package/package.json +8 -8
- package/src/async/index.ts +1 -0
- package/src/async/job-manager.ts +43 -10
- package/src/async/support.ts +5 -0
- package/src/cli/list-models.ts +96 -57
- package/src/commit/agentic/tools/analyze-file.ts +1 -2
- package/src/commit/model-selection.ts +16 -13
- package/src/config/mcp-schema.json +1 -1
- package/src/config/model-equivalence.ts +675 -0
- package/src/config/model-registry.ts +242 -45
- package/src/config/model-resolver.ts +282 -65
- package/src/config/settings-schema.ts +27 -3
- package/src/config/settings.ts +1 -1
- package/src/cursor.ts +64 -23
- package/src/edit/index.ts +254 -89
- package/src/edit/modes/chunk.ts +336 -57
- package/src/edit/modes/hashline.ts +51 -26
- package/src/edit/modes/patch.ts +16 -10
- package/src/edit/modes/replace.ts +15 -7
- package/src/edit/renderer.ts +248 -94
- package/src/export/html/template.css +82 -0
- package/src/export/html/template.generated.ts +1 -1
- package/src/export/html/template.js +614 -97
- package/src/extensibility/custom-tools/types.ts +0 -3
- package/src/extensibility/extensions/loader.ts +16 -0
- package/src/extensibility/extensions/runner.ts +2 -7
- package/src/extensibility/extensions/types.ts +8 -4
- package/src/internal-urls/docs-index.generated.ts +4 -4
- package/src/internal-urls/jobs-protocol.ts +2 -1
- package/src/ipy/executor.ts +447 -52
- package/src/ipy/kernel.ts +39 -13
- package/src/lsp/client.ts +55 -1
- package/src/lsp/index.ts +8 -0
- package/src/lsp/types.ts +6 -0
- package/src/main.ts +6 -2
- package/src/memories/index.ts +7 -6
- package/src/modes/acp/acp-agent.ts +4 -1
- package/src/modes/components/bash-execution.ts +16 -4
- package/src/modes/components/model-selector.ts +221 -64
- package/src/modes/components/status-line/presets.ts +17 -6
- package/src/modes/components/status-line/segments.ts +15 -0
- package/src/modes/components/status-line-segment-editor.ts +1 -0
- package/src/modes/components/status-line.ts +7 -1
- package/src/modes/components/tool-execution.ts +145 -75
- package/src/modes/controllers/command-controller.ts +42 -1
- package/src/modes/controllers/event-controller.ts +4 -1
- package/src/modes/controllers/extension-ui-controller.ts +28 -5
- package/src/modes/controllers/input-controller.ts +9 -3
- package/src/modes/controllers/selector-controller.ts +17 -6
- package/src/modes/interactive-mode.ts +19 -3
- package/src/modes/print-mode.ts +13 -4
- package/src/modes/prompt-action-autocomplete.ts +3 -5
- package/src/modes/rpc/rpc-mode.ts +8 -2
- package/src/modes/shared.ts +2 -2
- package/src/modes/types.ts +1 -0
- package/src/modes/utils/ui-helpers.ts +1 -0
- package/src/prompts/system/system-prompt.md +5 -1
- package/src/prompts/tools/bash.md +16 -1
- package/src/prompts/tools/cancel-job.md +1 -1
- package/src/prompts/tools/chunk-edit.md +191 -163
- package/src/prompts/tools/hashline.md +11 -11
- package/src/prompts/tools/patch.md +10 -5
- package/src/prompts/tools/{await.md → poll.md} +1 -1
- package/src/prompts/tools/read-chunk.md +12 -3
- package/src/prompts/tools/read.md +9 -0
- package/src/prompts/tools/task.md +2 -2
- package/src/prompts/tools/vim.md +98 -0
- package/src/prompts/tools/write.md +1 -0
- package/src/sdk.ts +758 -725
- package/src/session/agent-session.ts +187 -40
- package/src/session/session-manager.ts +50 -4
- package/src/slash-commands/builtin-registry.ts +17 -0
- package/src/task/executor.ts +9 -5
- package/src/task/index.ts +3 -5
- package/src/task/types.ts +2 -2
- package/src/tools/bash.ts +240 -57
- package/src/tools/cancel-job.ts +2 -1
- package/src/tools/find.ts +5 -2
- package/src/tools/grep.ts +77 -8
- package/src/tools/index.ts +48 -19
- package/src/tools/inspect-image.ts +1 -1
- package/src/tools/{await-tool.ts → poll-tool.ts} +38 -31
- package/src/tools/python.ts +293 -278
- package/src/tools/read.ts +218 -1
- package/src/tools/sqlite-reader.ts +623 -0
- package/src/tools/submit-result.ts +5 -2
- package/src/tools/todo-write.ts +8 -2
- package/src/tools/vim.ts +966 -0
- package/src/tools/write.ts +187 -1
- package/src/utils/commit-message-generator.ts +1 -0
- package/src/utils/edit-mode.ts +2 -1
- package/src/utils/git.ts +24 -1
- package/src/utils/session-color.ts +55 -0
- package/src/utils/title-generator.ts +16 -7
- package/src/vim/buffer.ts +309 -0
- package/src/vim/commands.ts +382 -0
- package/src/vim/engine.ts +2426 -0
- package/src/vim/parser.ts +151 -0
- package/src/vim/render.ts +252 -0
- package/src/vim/types.ts +197 -0
package/src/modes/print-mode.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* - `omp --mode json "prompt"` - JSON event stream
|
|
7
7
|
*/
|
|
8
8
|
import type { AssistantMessage, ImageContent } from "@oh-my-pi/pi-ai";
|
|
9
|
+
import { sanitizeText } from "@oh-my-pi/pi-natives";
|
|
9
10
|
import type { AgentSession } from "../session/agent-session";
|
|
10
11
|
|
|
11
12
|
/**
|
|
@@ -72,11 +73,14 @@ export async function runPrintMode(session: AgentSession, options: PrintModeOpti
|
|
|
72
73
|
},
|
|
73
74
|
getThinkingLevel: () => session.thinkingLevel,
|
|
74
75
|
setThinkingLevel: level => session.setThinkingLevel(level),
|
|
76
|
+
getSessionName: () => session.sessionManager.getSessionName(),
|
|
77
|
+
setSessionName: async name => {
|
|
78
|
+
await session.sessionManager.setSessionName(name, "user");
|
|
79
|
+
},
|
|
75
80
|
},
|
|
76
81
|
// ExtensionContextActions
|
|
77
82
|
{
|
|
78
83
|
getModel: () => session.model,
|
|
79
|
-
getSearchDb: () => session.searchDb,
|
|
80
84
|
isIdle: () => !session.isStreaming,
|
|
81
85
|
abort: () => session.abort(),
|
|
82
86
|
hasPendingMessages: () => session.queuedMessageCount > 0,
|
|
@@ -166,14 +170,19 @@ export async function runPrintMode(session: AgentSession, options: PrintModeOpti
|
|
|
166
170
|
|
|
167
171
|
// Check for error/aborted
|
|
168
172
|
if (assistantMsg.stopReason === "error" || assistantMsg.stopReason === "aborted") {
|
|
169
|
-
|
|
170
|
-
process.
|
|
173
|
+
const errorLine = sanitizeText(assistantMsg.errorMessage || `Request ${assistantMsg.stopReason}`);
|
|
174
|
+
const flushed = process.stderr.write(`${errorLine}\n`);
|
|
175
|
+
if (flushed) {
|
|
176
|
+
process.exit(1);
|
|
177
|
+
} else {
|
|
178
|
+
process.stderr.once("drain", () => process.exit(1));
|
|
179
|
+
}
|
|
171
180
|
}
|
|
172
181
|
|
|
173
182
|
// Output text content
|
|
174
183
|
for (const content of assistantMsg.content) {
|
|
175
184
|
if (content.type === "text") {
|
|
176
|
-
process.stdout.write(`${content.text}\n`);
|
|
185
|
+
process.stdout.write(`${sanitizeText(content.text)}\n`);
|
|
177
186
|
}
|
|
178
187
|
}
|
|
179
188
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { SearchDb } from "@oh-my-pi/pi-natives";
|
|
2
1
|
import {
|
|
3
2
|
type AutocompleteItem,
|
|
4
3
|
type AutocompleteProvider,
|
|
@@ -24,7 +23,6 @@ interface PromptActionAutocompleteItem extends AutocompleteItem {
|
|
|
24
23
|
interface PromptActionAutocompleteOptions {
|
|
25
24
|
commands: SlashCommand[];
|
|
26
25
|
basePath: string;
|
|
27
|
-
searchDb?: SearchDb;
|
|
28
26
|
keybindings: KeybindingsManager;
|
|
29
27
|
copyCurrentLine: () => void;
|
|
30
28
|
copyPrompt: () => void;
|
|
@@ -92,8 +90,8 @@ export class PromptActionAutocompleteProvider implements AutocompleteProvider {
|
|
|
92
90
|
#baseProvider: CombinedAutocompleteProvider;
|
|
93
91
|
#actions: PromptActionDefinition[];
|
|
94
92
|
|
|
95
|
-
constructor(commands: SlashCommand[], basePath: string, actions: PromptActionDefinition[]
|
|
96
|
-
this.#baseProvider = new CombinedAutocompleteProvider(commands, basePath
|
|
93
|
+
constructor(commands: SlashCommand[], basePath: string, actions: PromptActionDefinition[]) {
|
|
94
|
+
this.#baseProvider = new CombinedAutocompleteProvider(commands, basePath);
|
|
97
95
|
this.#actions = actions;
|
|
98
96
|
}
|
|
99
97
|
|
|
@@ -229,5 +227,5 @@ export function createPromptActionAutocompleteProvider(
|
|
|
229
227
|
},
|
|
230
228
|
];
|
|
231
229
|
|
|
232
|
-
return new PromptActionAutocompleteProvider(options.commands, options.basePath, actions
|
|
230
|
+
return new PromptActionAutocompleteProvider(options.commands, options.basePath, actions);
|
|
233
231
|
}
|
|
@@ -440,11 +440,14 @@ export async function runRpcMode(session: AgentSession): Promise<never> {
|
|
|
440
440
|
},
|
|
441
441
|
getThinkingLevel: () => session.thinkingLevel,
|
|
442
442
|
setThinkingLevel: level => session.setThinkingLevel(level),
|
|
443
|
+
getSessionName: () => session.sessionManager.getSessionName(),
|
|
444
|
+
setSessionName: async name => {
|
|
445
|
+
await session.sessionManager.setSessionName(name, "user");
|
|
446
|
+
},
|
|
443
447
|
},
|
|
444
448
|
// ExtensionContextActions
|
|
445
449
|
{
|
|
446
450
|
getModel: () => session.agent.state.model,
|
|
447
|
-
getSearchDb: () => session.searchDb,
|
|
448
451
|
isIdle: () => !session.isStreaming,
|
|
449
452
|
abort: () => session.abort(),
|
|
450
453
|
hasPendingMessages: () => session.queuedMessageCount > 0,
|
|
@@ -751,7 +754,10 @@ export async function runRpcMode(session: AgentSession): Promise<never> {
|
|
|
751
754
|
if (!name) {
|
|
752
755
|
return error(id, "set_session_name", "Session name cannot be empty");
|
|
753
756
|
}
|
|
754
|
-
session.setSessionName(name);
|
|
757
|
+
const applied = await session.setSessionName(name, "user");
|
|
758
|
+
if (!applied) {
|
|
759
|
+
return error(id, "set_session_name", "Session name cannot be empty");
|
|
760
|
+
}
|
|
755
761
|
return success(id, "set_session_name");
|
|
756
762
|
}
|
|
757
763
|
|
package/src/modes/shared.ts
CHANGED
|
@@ -5,10 +5,10 @@ import { theme } from "./theme/theme";
|
|
|
5
5
|
// Text Sanitization
|
|
6
6
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
7
7
|
|
|
8
|
-
/** Sanitize text for display in a single-line status.
|
|
8
|
+
/** Sanitize text for display in a single-line status. Strips C0/C1 control characters (including ANSI ESC), collapses whitespace, trims. */
|
|
9
9
|
export function sanitizeStatusText(text: string): string {
|
|
10
10
|
return text
|
|
11
|
-
.replace(/[\
|
|
11
|
+
.replace(/[\u0000-\u001f\u007f-\u009f]/g, " ")
|
|
12
12
|
.replace(/ +/g, " ")
|
|
13
13
|
.trim();
|
|
14
14
|
}
|
package/src/modes/types.ts
CHANGED
|
@@ -187,6 +187,7 @@ export interface InteractiveModeContext {
|
|
|
187
187
|
handleCompactCommand(customInstructions?: string): Promise<void>;
|
|
188
188
|
handleHandoffCommand(customInstructions?: string): Promise<void>;
|
|
189
189
|
handleMoveCommand(targetPath: string): Promise<void>;
|
|
190
|
+
handleRenameCommand(title: string): Promise<void>;
|
|
190
191
|
handleMemoryCommand(text: string): Promise<void>;
|
|
191
192
|
handleSTTToggle(): Promise<void>;
|
|
192
193
|
executeCompaction(customInstructionsOrOptions?: string | CompactOptions, isAuto?: boolean): Promise<void>;
|
|
@@ -54,6 +54,7 @@ Push back when warranted: state the downside, propose an alternative, but **MUST
|
|
|
54
54
|
- (1) Correctness first, (2) Brevity second, (3) Politeness third.
|
|
55
55
|
- Prefer concise, information-dense writing.
|
|
56
56
|
- Avoid repeating the user's request or narrating routine tool calls.
|
|
57
|
+
- Do not give time estimates or predictions for how long tasks will take. Focus on what needs to be done, not how long it might take.
|
|
57
58
|
</communication>
|
|
58
59
|
|
|
59
60
|
<instruction-priority>
|
|
@@ -101,6 +102,8 @@ You generate code inside-out: starting at the function body, working outward. Th
|
|
|
101
102
|
- **DRY at 2.** When you write the same pattern a second time, stop and extract a shared helper. Two copies is a maintenance fork. Three copies is a bug.
|
|
102
103
|
- Write maintainable code. Add brief comments when they clarify non-obvious intent, invariants, edge cases, or tradeoffs. Prefer explaining why over restating what the code already does.
|
|
103
104
|
- **Earn every line.** A 12-line switch for a 3-way mapping is a lookup table. A one-liner wrapper that exists only for test access is a design smell.
|
|
105
|
+
- **No speculative complexity.** Do not create helpers, utilities, or abstractions for one-time operations. Do not design for hypothetical future requirements. Three similar lines of code is better than a premature abstraction. The right amount of complexity is what the task actually requires.
|
|
106
|
+
- **Trust internal code.** Do not add error handling, fallbacks, or validation for scenarios that cannot happen. Only validate at system boundaries — user input, external APIs, network responses. Do not use feature flags or backwards-compatibility shims when you can just change the code.
|
|
104
107
|
</code-integrity>
|
|
105
108
|
|
|
106
109
|
<stakes>
|
|
@@ -338,7 +341,8 @@ You are not making code that works. You are making code that communicates — to
|
|
|
338
341
|
**One job, one level of abstraction.** If you need "and" to describe what something does, it should be two things. Code that mixes levels — orchestrating a flow while also handling parsing, formatting, or low-level manipulation — has no coherent owner and no coherent test. Each piece operates at one level and delegates everything else.
|
|
339
342
|
**Fix where the invariant is violated, not where the violation is observed.** If a function returns the wrong thing, fix the function — not the caller's workaround. If a type is wrong, fix the type — not the cast. The right fix location is always where the contract is broken.
|
|
340
343
|
**New code makes old code obsolete. Remove it.** When you introduce an abstraction, find what it replaces: old helpers, compatibility branches, stale tests, documentation describing removed behavior. Remove them in the same change.
|
|
341
|
-
**No forwarding addresses.** Deleted or moved code leaves no trace — no `// moved to X` comments, no re-exports from the old location, no aliases kept "for now.
|
|
344
|
+
**No forwarding addresses.** Deleted or moved code leaves no trace — no `// moved to X` comments, no re-exports from the old location, no aliases kept "for now," no renaming unused parameters to `_var`, no `// removed` tombstones. If something is unused, delete it completely.
|
|
345
|
+
**Prefer editing over creating.** Do not create new files unless they are necessary to achieve the goal. Editing an existing file prevents file bloat and builds on existing work. A new file must earn its existence.
|
|
342
346
|
**After writing, inhabit the call site.** Read your own code as someone who has never seen the implementation. Does the interface honestly reflect what happened? Is any accepted input silently discarded? Does any pattern exist in more than one place? Fix it.
|
|
343
347
|
When a tool call fails, read the full error before doing anything else. When a file changed since you last read it, re-read before editing.
|
|
344
348
|
{{#has tools "ask"}}- You **MUST** ask before destructive commands like `git checkout/restore/reset`, overwriting changes, or deleting code you didn't write.{{else}}- You **MUST NOT** run destructive git commands, overwrite changes, or delete code you didn't write.{{/has}}
|
|
@@ -12,8 +12,23 @@ Executes bash command in shell session for terminal operations like git, bun, ca
|
|
|
12
12
|
- Internal URLs are also auto-resolved to filesystem paths before execution.
|
|
13
13
|
{{#if asyncEnabled}}
|
|
14
14
|
- Use `async: true` for long-running commands when you don't need immediate output; the call returns a background job ID and the result is delivered automatically as a follow-up.
|
|
15
|
+
{{/if}}
|
|
16
|
+
{{#if autoBackgroundEnabled}}
|
|
17
|
+
- Long-running non-PTY bash commands may auto-background after about {{autoBackgroundThresholdSeconds}}s and continue as background jobs automatically.
|
|
18
|
+
{{/if}}
|
|
19
|
+
{{#if asyncEnabled}}
|
|
20
|
+
{{else}}
|
|
21
|
+
{{#if autoBackgroundEnabled}}
|
|
22
|
+
- Auto-backgrounded jobs use the same background-job pipeline as explicit async execution.
|
|
23
|
+
{{/if}}
|
|
24
|
+
{{/if}}
|
|
25
|
+
{{#if asyncEnabled}}
|
|
15
26
|
- Use `read jobs://` to inspect all background jobs and `read jobs://<job-id>` for detailed status/output when needed.
|
|
16
|
-
- When you need to wait for async results before continuing, call `
|
|
27
|
+
- When you need to wait for async results before continuing, call `poll` — it blocks until jobs complete. Do NOT poll `read jobs://` in a loop or yield and hope for delivery.
|
|
28
|
+
{{else}}
|
|
29
|
+
{{#if autoBackgroundEnabled}}
|
|
30
|
+
- If a command auto-backgrounds, use `read jobs://` to inspect jobs and `poll` when you need to wait for completion instead of polling in a loop.
|
|
31
|
+
{{/if}}
|
|
17
32
|
{{/if}}
|
|
18
33
|
</instruction>
|
|
19
34
|
|