@oh-my-pi/pi-coding-agent 14.1.2 → 14.2.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 +47 -2
- package/package.json +8 -8
- package/scripts/build-binary.ts +61 -0
- package/src/autoresearch/helpers.ts +10 -0
- package/src/autoresearch/index.ts +1 -11
- package/src/autoresearch/tools/init-experiment.ts +1 -10
- package/src/autoresearch/tools/log-experiment.ts +1 -11
- package/src/autoresearch/tools/run-experiment.ts +1 -10
- package/src/bun-imports.d.ts +6 -0
- package/src/cli/plugin-cli.ts +23 -45
- package/src/commit/agentic/tools/propose-commit.ts +1 -14
- package/src/commit/agentic/tools/split-commit.ts +1 -15
- package/src/commit/utils.ts +15 -1
- package/src/config/model-registry.ts +3 -3
- package/src/config/prompt-templates.ts +4 -12
- package/src/config/settings-schema.ts +27 -2
- package/src/config/settings.ts +1 -1
- package/src/dap/session.ts +8 -2
- package/src/discovery/claude-plugins.ts +61 -6
- package/src/discovery/codex.ts +2 -15
- package/src/discovery/gemini.ts +2 -15
- package/src/discovery/helpers.ts +40 -1
- package/src/discovery/opencode.ts +2 -15
- package/src/edit/apply-patch/index.ts +87 -0
- package/src/edit/apply-patch/parser.ts +174 -0
- package/src/edit/diff.ts +3 -14
- package/src/edit/index.ts +67 -3
- package/src/edit/modes/apply-patch.lark +19 -0
- package/src/edit/modes/apply-patch.ts +63 -0
- package/src/edit/modes/chunk.ts +6 -2
- package/src/edit/modes/hashline.ts +3 -3
- package/src/edit/modes/replace.ts +2 -13
- package/src/edit/read-file.ts +18 -0
- package/src/edit/renderer.ts +61 -33
- package/src/extensibility/extensions/compact-handler.ts +40 -0
- package/src/extensibility/extensions/runner.ts +11 -29
- package/src/extensibility/utils.ts +7 -1
- package/src/internal-urls/docs-index.generated.ts +9 -2
- package/src/lsp/client.ts +14 -5
- package/src/lsp/index.ts +53 -10
- package/src/lsp/render.ts +14 -2
- package/src/lsp/types.ts +2 -0
- package/src/main.ts +1 -0
- package/src/mcp/manager.ts +29 -48
- package/src/memories/index.ts +7 -1
- package/src/modes/acp/acp-agent.ts +3 -16
- package/src/modes/components/model-selector.ts +15 -24
- package/src/modes/components/plugin-settings.ts +16 -5
- package/src/modes/components/read-tool-group.ts +92 -9
- package/src/modes/components/settings-defs.ts +18 -0
- package/src/modes/components/settings-selector.ts +2 -6
- package/src/modes/components/tool-execution.ts +61 -28
- package/src/modes/controllers/event-controller.ts +3 -1
- package/src/modes/controllers/extension-ui-controller.ts +99 -150
- package/src/modes/controllers/selector-controller.ts +3 -12
- package/src/modes/interactive-mode.ts +4 -2
- package/src/modes/print-mode.ts +4 -22
- package/src/modes/rpc/rpc-mode.ts +18 -38
- package/src/modes/shared.ts +10 -1
- package/src/modes/utils/ui-helpers.ts +6 -2
- package/src/plan-mode/approved-plan.ts +5 -4
- package/src/prompts/system/subagent-system-prompt.md +4 -4
- package/src/prompts/system/subagent-user-prompt.md +2 -2
- package/src/prompts/system/system-prompt.md +208 -243
- package/src/prompts/tools/apply-patch.md +67 -0
- package/src/prompts/tools/ast-edit.md +18 -23
- package/src/prompts/tools/ast-grep.md +25 -32
- package/src/prompts/tools/bash.md +11 -23
- package/src/prompts/tools/debug.md +8 -22
- package/src/prompts/tools/find.md +0 -4
- package/src/prompts/tools/grep.md +3 -5
- package/src/prompts/tools/hashline.md +16 -10
- package/src/prompts/tools/python.md +10 -14
- package/src/prompts/tools/read.md +17 -24
- package/src/prompts/tools/task.md +57 -21
- package/src/prompts/tools/todo-write.md +45 -67
- package/src/session/agent-session.ts +4 -4
- package/src/session/session-manager.ts +15 -7
- package/src/session/streaming-output.ts +24 -0
- package/src/slash-commands/builtin-registry.ts +3 -14
- package/src/task/executor.ts +13 -34
- package/src/task/index.ts +82 -18
- package/src/task/simple-mode.ts +27 -0
- package/src/task/template.ts +17 -3
- package/src/task/types.ts +77 -30
- package/src/tools/ask.ts +2 -4
- package/src/tools/ast-edit.ts +41 -17
- package/src/tools/ast-grep.ts +8 -27
- package/src/tools/bash-skill-urls.ts +9 -7
- package/src/tools/bash.ts +66 -24
- package/src/tools/browser.ts +1 -1
- package/src/tools/fetch.ts +1 -14
- package/src/tools/file-recorder.ts +35 -0
- package/src/tools/find.ts +25 -29
- package/src/tools/gh-format.ts +12 -0
- package/src/tools/gh-renderer.ts +1 -8
- package/src/tools/gh.ts +6 -13
- package/src/tools/grep.ts +103 -59
- package/src/tools/jtd-to-json-schema.ts +16 -0
- package/src/tools/match-line-format.ts +20 -0
- package/src/tools/path-utils.ts +61 -5
- package/src/tools/plan-mode-guard.ts +6 -5
- package/src/tools/python.ts +1 -1
- package/src/tools/read.ts +1 -1
- package/src/tools/render-utils.ts +38 -6
- package/src/tools/renderers.ts +1 -0
- package/src/tools/resolve.ts +12 -3
- package/src/tools/ssh.ts +3 -11
- package/src/tools/submit-result.ts +1 -13
- package/src/tools/todo-write.ts +137 -103
- package/src/tools/vim.ts +1 -1
- package/src/tools/write.ts +2 -23
- package/src/tui/code-cell.ts +12 -7
- package/src/utils/edit-mode.ts +3 -2
- package/src/utils/git.ts +1 -1
- package/src/vim/engine.ts +41 -58
- package/src/web/scrapers/crates-io.ts +1 -14
- package/src/web/scrapers/types.ts +13 -0
- package/src/web/search/providers/base.ts +13 -0
- package/src/web/search/providers/brave.ts +2 -5
- package/src/web/search/providers/codex.ts +20 -24
- package/src/web/search/providers/gemini.ts +39 -1
- package/src/web/search/providers/jina.ts +2 -5
- package/src/web/search/providers/kagi.ts +3 -8
- package/src/web/search/providers/kimi.ts +3 -7
- package/src/web/search/providers/parallel.ts +3 -8
- package/src/web/search/providers/synthetic.ts +3 -7
- package/src/web/search/providers/tavily.ts +15 -11
- package/src/web/search/providers/utils.ts +36 -0
- package/src/web/search/providers/zai.ts +3 -7
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,52 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [14.2.0] - 2026-04-23
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added an `apply_patch` edit mode that accepts Codex `*** Begin Patch` envelopes, shares patch-mode execution and diagnostics, and renders streaming per-file diffs in the TUI.
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- Changed Spark models to default to `apply_patch` edit mode instead of `replace`.
|
|
14
|
+
- Tightened the contract for `SearchParams.recency` in `web/search/providers/base.ts`: providers MUST interpret recency as a pure time filter and MUST NOT use it as an implicit signal to change topic scope, content domain, or ranking strategy.
|
|
15
|
+
- Inline read tool previews are now optional via `read.toolResultPreview` and default to off
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- Fixed `apply_patch` streaming previews to avoid showing the missing `*** End Patch` parse error while the patch body is still arriving.
|
|
20
|
+
- Fixed diagnostics rendering to replace tabs before TUI output, preventing compiler messages from breaking tree alignment.
|
|
21
|
+
- Fixed compiled `omp` binaries to ignore project-local `bunfig.toml` and `.env` autoloading at startup, preventing unrelated project config from crashing or preloading code into the CLI
|
|
22
|
+
- Fixed edit tool diff and replace operations to report missing-file failures as `File not found: <path>` errors instead of raw filesystem ENOENT errors
|
|
23
|
+
- Fixed `local://` URL path leak on Linux where `//` collapsing to `/` produced `local:/path` forms that bypassed the internal protocol handler and leaked as filesystem paths, breaking plan mode file resolution
|
|
24
|
+
- Fixed Darwin compiled binaries failing to start under Bun 1.3.12 by ad-hoc signing local and release binary builds after applying Bun's no-codesign workaround ([#754](https://github.com/can1357/oh-my-pi/issues/754))
|
|
25
|
+
- Fixed Tavily web search silently returning off-topic news articles when `--recency` was set. The provider was unconditionally coupling `topic: "news"` to recency, which scoped Tavily's index to news publications and excluded documentation, release notes, GitHub, and all non-news technical content. Technical queries with `--recency` now return the correct corpus.
|
|
26
|
+
- Fixed status-line sanitization to strip OSC, DCS, PM, APC, and 8-bit CSI escape sequences instead of leaving payload fragments in the UI
|
|
27
|
+
- Fixed inline read tool previews to avoid rendering duplicate summary rows above the same code cell
|
|
28
|
+
|
|
29
|
+
## [14.1.3] - 2026-04-17
|
|
30
|
+
|
|
31
|
+
### Breaking Changes
|
|
32
|
+
|
|
33
|
+
- Replaced the legacy `todo_write` `ops`-based API (`replace`, `update`, `add_task`, and `remove_task`) with direct top-level fields, requiring migration of any callers using the old request shape
|
|
34
|
+
- Removed in-place updates to existing task `content`, `details`, and `notes` via `todo_write`; note changes now append through `add_notes`
|
|
35
|
+
- Phased task definitions in `todo_write` now reject `notes` on initial creation, so notes must be added later with `add_notes`
|
|
36
|
+
|
|
37
|
+
### Added
|
|
38
|
+
|
|
39
|
+
- Added `complete`, `start`, `abandon`, `remove`, `add_notes`, and `add_tasks` parameters to `todo_write` so callers can complete, jump to, drop, and annotate tasks without op wrappers
|
|
40
|
+
- Added direct `add_phase` support as a top-level argument for inserting a new phase in `todo_write`
|
|
41
|
+
- Added `task.simple` with `default`, `schema-free`, and `independent` modes so the task tool can disable task-call `schema` and shared `context` inputs while preserving agent-defined and inherited subagent schemas
|
|
42
|
+
|
|
43
|
+
### Changed
|
|
44
|
+
|
|
45
|
+
- Changed `add_tasks` to insert tasks by phase name or ID and allow multiple tasks to be added in one call
|
|
46
|
+
|
|
47
|
+
### Fixed
|
|
48
|
+
|
|
49
|
+
- Fixed task calls in `schema-free` and `independent` modes to return clear mode-specific errors when disallowed `context` or `schema` inputs are provided
|
|
50
|
+
- Fixed newly generated session IDs to use UUIDv7 for new, forked, and branched sessions while preserving resumed session IDs
|
|
5
51
|
## [14.1.1] - 2026-04-14
|
|
6
52
|
|
|
7
53
|
### Breaking Changes
|
|
@@ -183,7 +229,6 @@
|
|
|
183
229
|
|
|
184
230
|
- Fixed typo in system prompt: 'backwards compatibiltity' → 'backwards compatibility'
|
|
185
231
|
|
|
186
|
-
|
|
187
232
|
## [14.0.3] - 2026-04-09
|
|
188
233
|
|
|
189
234
|
### Fixed
|
|
@@ -7082,4 +7127,4 @@ Initial public release.
|
|
|
7082
7127
|
- Git branch display in footer
|
|
7083
7128
|
- Message queueing during streaming responses
|
|
7084
7129
|
- OAuth integration for Gmail and Google Calendar access
|
|
7085
|
-
- HTML export with syntax highlighting and collapsible sections
|
|
7130
|
+
- HTML export with syntax highlighting and collapsible sections
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-coding-agent",
|
|
4
|
-
"version": "14.1
|
|
4
|
+
"version": "14.2.1",
|
|
5
5
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://github.com/can1357/oh-my-pi",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"omp": "src/cli.ts"
|
|
32
32
|
},
|
|
33
33
|
"scripts": {
|
|
34
|
-
"build": "bun
|
|
34
|
+
"build": "bun scripts/build-binary.ts",
|
|
35
35
|
"check": "biome check . && bun run check:types",
|
|
36
36
|
"check:types": "tsgo -p tsconfig.json --noEmit",
|
|
37
37
|
"lint": "biome lint .",
|
|
@@ -46,12 +46,12 @@
|
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@agentclientprotocol/sdk": "0.16.1",
|
|
48
48
|
"@mozilla/readability": "^0.6",
|
|
49
|
-
"@oh-my-pi/omp-stats": "14.1
|
|
50
|
-
"@oh-my-pi/pi-agent-core": "14.1
|
|
51
|
-
"@oh-my-pi/pi-ai": "14.1
|
|
52
|
-
"@oh-my-pi/pi-natives": "14.1
|
|
53
|
-
"@oh-my-pi/pi-tui": "14.1
|
|
54
|
-
"@oh-my-pi/pi-utils": "14.1
|
|
49
|
+
"@oh-my-pi/omp-stats": "14.2.1",
|
|
50
|
+
"@oh-my-pi/pi-agent-core": "14.2.1",
|
|
51
|
+
"@oh-my-pi/pi-ai": "14.2.1",
|
|
52
|
+
"@oh-my-pi/pi-natives": "14.2.1",
|
|
53
|
+
"@oh-my-pi/pi-tui": "14.2.1",
|
|
54
|
+
"@oh-my-pi/pi-utils": "14.2.1",
|
|
55
55
|
"@sinclair/typebox": "^0.34",
|
|
56
56
|
"@xterm/headless": "^6.0",
|
|
57
57
|
"ajv": "^8.18",
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
|
|
5
|
+
const packageDir = path.join(import.meta.dir, "..");
|
|
6
|
+
const outputPath = path.join(packageDir, "dist", "omp");
|
|
7
|
+
|
|
8
|
+
function shouldAdhocSignDarwinBinary(): boolean {
|
|
9
|
+
return process.platform === "darwin";
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async function runCommand(command: string[], env: NodeJS.ProcessEnv = Bun.env): Promise<void> {
|
|
13
|
+
const proc = Bun.spawn(command, {
|
|
14
|
+
cwd: packageDir,
|
|
15
|
+
env,
|
|
16
|
+
stdout: "inherit",
|
|
17
|
+
stderr: "inherit",
|
|
18
|
+
});
|
|
19
|
+
const exitCode = await proc.exited;
|
|
20
|
+
if (exitCode !== 0) {
|
|
21
|
+
throw new Error(`Command failed with exit code ${exitCode}: ${command.join(" ")}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async function main(): Promise<void> {
|
|
26
|
+
await runCommand(["bun", "--cwd=../stats", "scripts/generate-client-bundle.ts", "--generate"]);
|
|
27
|
+
try {
|
|
28
|
+
await runCommand(["bun", "--cwd=../natives", "run", "embed:native"]);
|
|
29
|
+
try {
|
|
30
|
+
const buildEnv = shouldAdhocSignDarwinBinary() ? { ...Bun.env, BUN_NO_CODESIGN_MACHO_BINARY: "1" } : Bun.env;
|
|
31
|
+
await runCommand(
|
|
32
|
+
[
|
|
33
|
+
"bun",
|
|
34
|
+
"build",
|
|
35
|
+
"--compile",
|
|
36
|
+
"--define",
|
|
37
|
+
"PI_COMPILED=true",
|
|
38
|
+
"--external",
|
|
39
|
+
"mupdf",
|
|
40
|
+
"--root",
|
|
41
|
+
"../..",
|
|
42
|
+
"./src/cli.ts",
|
|
43
|
+
"--outfile",
|
|
44
|
+
"dist/omp",
|
|
45
|
+
],
|
|
46
|
+
buildEnv,
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
// Bun 1.3.12 emits a truncated Mach-O signature on darwin builds.
|
|
50
|
+
if (shouldAdhocSignDarwinBinary()) {
|
|
51
|
+
await runCommand(["codesign", "--force", "--sign", "-", outputPath]);
|
|
52
|
+
}
|
|
53
|
+
} finally {
|
|
54
|
+
await runCommand(["bun", "--cwd=../natives", "run", "embed:native", "--reset"]);
|
|
55
|
+
}
|
|
56
|
+
} finally {
|
|
57
|
+
await runCommand(["bun", "--cwd=../stats", "scripts/generate-client-bundle.ts", "--reset"]);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
await main();
|
|
@@ -505,3 +505,13 @@ function clonePendingAsiValue(value: unknown): ASIValue | undefined {
|
|
|
505
505
|
}
|
|
506
506
|
return undefined;
|
|
507
507
|
}
|
|
508
|
+
|
|
509
|
+
export function collectLoggedRunNumbers(results: readonly { runNumber: number | null }[]): Set<number> {
|
|
510
|
+
const runNumbers = new Set<number>();
|
|
511
|
+
for (const result of results) {
|
|
512
|
+
if (result.runNumber !== null) {
|
|
513
|
+
runNumbers.add(result.runNumber);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
return runNumbers;
|
|
517
|
+
}
|
|
@@ -8,6 +8,7 @@ import { pathMatchesContractPath } from "./contract";
|
|
|
8
8
|
import { createDashboardController } from "./dashboard";
|
|
9
9
|
import { ensureAutoresearchBranch } from "./git";
|
|
10
10
|
import {
|
|
11
|
+
collectLoggedRunNumbers,
|
|
11
12
|
formatNum,
|
|
12
13
|
isAutoresearchCommittableFile,
|
|
13
14
|
isAutoresearchLocalStatePath,
|
|
@@ -485,17 +486,6 @@ function findBestResult(runtime: AutoresearchRuntime): ExperimentResult | null {
|
|
|
485
486
|
}
|
|
486
487
|
return best;
|
|
487
488
|
}
|
|
488
|
-
|
|
489
|
-
function collectLoggedRunNumbers(results: ExperimentResult[]): Set<number> {
|
|
490
|
-
const runNumbers = new Set<number>();
|
|
491
|
-
for (const result of results) {
|
|
492
|
-
if (result.runNumber !== null) {
|
|
493
|
-
runNumbers.add(result.runNumber);
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
return runNumbers;
|
|
497
|
-
}
|
|
498
|
-
|
|
499
489
|
function summaryToChecks(summary: PendingRunSummary | null): ChecksResult | null {
|
|
500
490
|
if (!summary || summary.checksPass === null) {
|
|
501
491
|
return null;
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
} from "../contract";
|
|
16
16
|
import {
|
|
17
17
|
abandonUnloggedAutoresearchRuns,
|
|
18
|
+
collectLoggedRunNumbers,
|
|
18
19
|
isAutoresearchShCommand,
|
|
19
20
|
readMaxExperiments,
|
|
20
21
|
readPendingRunSummary,
|
|
@@ -383,13 +384,3 @@ export function createInitExperimentTool(
|
|
|
383
384
|
function renderInitCall(name: string, theme: Theme): string {
|
|
384
385
|
return `${theme.fg("toolTitle", theme.bold("init_experiment"))} ${theme.fg("accent", truncateToWidth(replaceTabs(name), 100))}`;
|
|
385
386
|
}
|
|
386
|
-
|
|
387
|
-
function collectLoggedRunNumbers(results: ExperimentState["results"]): Set<number> {
|
|
388
|
-
const runNumbers = new Set<number>();
|
|
389
|
-
for (const result of results) {
|
|
390
|
-
if (result.runNumber !== null) {
|
|
391
|
-
runNumbers.add(result.runNumber);
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
return runNumbers;
|
|
395
|
-
}
|
|
@@ -12,6 +12,7 @@ import { applyAutoresearchContractToExperimentState } from "../apply-contract-to
|
|
|
12
12
|
import { loadAutoresearchScriptSnapshot, pathMatchesContractPath, readAutoresearchContract } from "../contract";
|
|
13
13
|
import { computeRunModifiedPaths, getCurrentAutoresearchBranch, parseWorkDirDirtyPathsWithStatus } from "../git";
|
|
14
14
|
import {
|
|
15
|
+
collectLoggedRunNumbers,
|
|
15
16
|
formatNum,
|
|
16
17
|
inferMetricUnitFromName,
|
|
17
18
|
isAutoresearchCommittableFile,
|
|
@@ -472,17 +473,6 @@ function persistRun(workDir: string, experiment: ExperimentResult): void {
|
|
|
472
473
|
const jsonlPath = path.join(workDir, "autoresearch.jsonl");
|
|
473
474
|
fs.appendFileSync(jsonlPath, `${JSON.stringify(entry)}\n`);
|
|
474
475
|
}
|
|
475
|
-
|
|
476
|
-
function collectLoggedRunNumbers(results: ExperimentResult[]): Set<number> {
|
|
477
|
-
const runNumbers = new Set<number>();
|
|
478
|
-
for (const result of results) {
|
|
479
|
-
if (result.runNumber !== null) {
|
|
480
|
-
runNumbers.add(result.runNumber);
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
return runNumbers;
|
|
484
|
-
}
|
|
485
|
-
|
|
486
476
|
function validateObservedStatus(
|
|
487
477
|
status: ExperimentResult["status"],
|
|
488
478
|
pendingRun: { checksPass: boolean | null; passed: boolean },
|
|
@@ -11,6 +11,7 @@ import { replaceTabs, shortenPath, truncateToWidth } from "../../tools/render-ut
|
|
|
11
11
|
import * as git from "../../utils/git";
|
|
12
12
|
import { parseWorkDirDirtyPaths } from "../git";
|
|
13
13
|
import {
|
|
14
|
+
collectLoggedRunNumbers,
|
|
14
15
|
EXPERIMENT_MAX_BYTES,
|
|
15
16
|
EXPERIMENT_MAX_LINES,
|
|
16
17
|
formatElapsed,
|
|
@@ -666,13 +667,3 @@ function isProgressDetails(value: unknown): value is RunExperimentProgressDetail
|
|
|
666
667
|
if (typeof value !== "object" || value === null) return false;
|
|
667
668
|
return "phase" in value && value.phase === "running";
|
|
668
669
|
}
|
|
669
|
-
|
|
670
|
-
function collectLoggedRunNumbers(results: Array<{ runNumber: number | null }>): Set<number> {
|
|
671
|
-
const runNumbers = new Set<number>();
|
|
672
|
-
for (const result of results) {
|
|
673
|
-
if (result.runNumber !== null) {
|
|
674
|
-
runNumbers.add(result.runNumber);
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
return runNumbers;
|
|
678
|
-
}
|
package/src/bun-imports.d.ts
CHANGED
package/src/cli/plugin-cli.ts
CHANGED
|
@@ -831,42 +831,7 @@ async function handleEnable(
|
|
|
831
831
|
plugins: string[],
|
|
832
832
|
flags: { json?: boolean; scope?: "user" | "project" },
|
|
833
833
|
): Promise<void> {
|
|
834
|
-
|
|
835
|
-
console.error(chalk.red(`Usage: ${APP_NAME} plugin enable <plugin> ...`));
|
|
836
|
-
process.exit(1);
|
|
837
|
-
}
|
|
838
|
-
|
|
839
|
-
const mktMgr = await makeMarketplaceManager();
|
|
840
|
-
const installedPlugins = new Set((await mktMgr.listInstalledPlugins()).map(p => p.id));
|
|
841
|
-
|
|
842
|
-
for (const name of plugins) {
|
|
843
|
-
if (installedPlugins.has(name)) {
|
|
844
|
-
try {
|
|
845
|
-
await mktMgr.setPluginEnabled(name, true, flags.scope);
|
|
846
|
-
if (flags.json) {
|
|
847
|
-
console.log(JSON.stringify({ enabled: name }));
|
|
848
|
-
} else {
|
|
849
|
-
console.log(chalk.green(`${theme.status.success} Enabled ${name}`));
|
|
850
|
-
}
|
|
851
|
-
} catch (err) {
|
|
852
|
-
console.error(chalk.red(`${theme.status.error} Failed to enable ${name}: ${err}`));
|
|
853
|
-
process.exit(1);
|
|
854
|
-
}
|
|
855
|
-
continue;
|
|
856
|
-
}
|
|
857
|
-
|
|
858
|
-
try {
|
|
859
|
-
await manager.setEnabled(name, true);
|
|
860
|
-
if (flags.json) {
|
|
861
|
-
console.log(JSON.stringify({ enabled: name }));
|
|
862
|
-
} else {
|
|
863
|
-
console.log(chalk.green(`${theme.status.success} Enabled ${name}`));
|
|
864
|
-
}
|
|
865
|
-
} catch (err) {
|
|
866
|
-
console.error(chalk.red(`${theme.status.error} Failed to enable ${name}: ${err}`));
|
|
867
|
-
process.exit(1);
|
|
868
|
-
}
|
|
869
|
-
}
|
|
834
|
+
return handleSetEnabled(manager, plugins, flags, true);
|
|
870
835
|
}
|
|
871
836
|
|
|
872
837
|
async function handleDisable(
|
|
@@ -874,8 +839,21 @@ async function handleDisable(
|
|
|
874
839
|
plugins: string[],
|
|
875
840
|
flags: { json?: boolean; scope?: "user" | "project" },
|
|
876
841
|
): Promise<void> {
|
|
842
|
+
return handleSetEnabled(manager, plugins, flags, false);
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
async function handleSetEnabled(
|
|
846
|
+
manager: PluginManager,
|
|
847
|
+
plugins: string[],
|
|
848
|
+
flags: { json?: boolean; scope?: "user" | "project" },
|
|
849
|
+
enabled: boolean,
|
|
850
|
+
): Promise<void> {
|
|
851
|
+
const action = enabled ? "enable" : "disable";
|
|
852
|
+
const pastTense = enabled ? "Enabled" : "Disabled";
|
|
853
|
+
const jsonKey = enabled ? "enabled" : "disabled";
|
|
854
|
+
|
|
877
855
|
if (plugins.length === 0) {
|
|
878
|
-
console.error(chalk.red(`Usage: ${APP_NAME} plugin
|
|
856
|
+
console.error(chalk.red(`Usage: ${APP_NAME} plugin ${action} <plugin> ...`));
|
|
879
857
|
process.exit(1);
|
|
880
858
|
}
|
|
881
859
|
|
|
@@ -885,28 +863,28 @@ async function handleDisable(
|
|
|
885
863
|
for (const name of plugins) {
|
|
886
864
|
if (installedPlugins.has(name)) {
|
|
887
865
|
try {
|
|
888
|
-
await mktMgr.setPluginEnabled(name,
|
|
866
|
+
await mktMgr.setPluginEnabled(name, enabled, flags.scope);
|
|
889
867
|
if (flags.json) {
|
|
890
|
-
console.log(JSON.stringify({
|
|
868
|
+
console.log(JSON.stringify({ [jsonKey]: name }));
|
|
891
869
|
} else {
|
|
892
|
-
console.log(chalk.green(`${theme.status.success}
|
|
870
|
+
console.log(chalk.green(`${theme.status.success} ${pastTense} ${name}`));
|
|
893
871
|
}
|
|
894
872
|
} catch (err) {
|
|
895
|
-
console.error(chalk.red(`${theme.status.error} Failed to
|
|
873
|
+
console.error(chalk.red(`${theme.status.error} Failed to ${action} ${name}: ${err}`));
|
|
896
874
|
process.exit(1);
|
|
897
875
|
}
|
|
898
876
|
continue;
|
|
899
877
|
}
|
|
900
878
|
|
|
901
879
|
try {
|
|
902
|
-
await manager.setEnabled(name,
|
|
880
|
+
await manager.setEnabled(name, enabled);
|
|
903
881
|
if (flags.json) {
|
|
904
|
-
console.log(JSON.stringify({
|
|
882
|
+
console.log(JSON.stringify({ [jsonKey]: name }));
|
|
905
883
|
} else {
|
|
906
|
-
console.log(chalk.green(`${theme.status.success}
|
|
884
|
+
console.log(chalk.green(`${theme.status.success} ${pastTense} ${name}`));
|
|
907
885
|
}
|
|
908
886
|
} catch (err) {
|
|
909
|
-
console.error(chalk.red(`${theme.status.error} Failed to
|
|
887
|
+
console.error(chalk.red(`${theme.status.error} Failed to ${action} ${name}: ${err}`));
|
|
910
888
|
process.exit(1);
|
|
911
889
|
}
|
|
912
890
|
}
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
} from "../../../commit/agentic/validation";
|
|
11
11
|
import { validateAnalysis } from "../../../commit/analysis/validation";
|
|
12
12
|
import type { CommitType, ConventionalAnalysis, ConventionalDetail } from "../../../commit/types";
|
|
13
|
+
import { normalizeDetails } from "../../../commit/utils";
|
|
13
14
|
import type { CustomTool } from "../../../extensibility/custom-tools/types";
|
|
14
15
|
import * as git from "../../../utils/git";
|
|
15
16
|
import { commitTypeSchema, detailSchema } from "./schemas.js";
|
|
@@ -35,20 +36,6 @@ interface ProposalResponse {
|
|
|
35
36
|
};
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
function normalizeDetails(
|
|
39
|
-
details: Array<{
|
|
40
|
-
text: string;
|
|
41
|
-
changelog_category?: ConventionalDetail["changelogCategory"];
|
|
42
|
-
user_visible?: boolean;
|
|
43
|
-
}>,
|
|
44
|
-
): ConventionalDetail[] {
|
|
45
|
-
return details.map(detail => ({
|
|
46
|
-
text: detail.text.trim(),
|
|
47
|
-
changelogCategory: detail.user_visible ? detail.changelog_category : undefined,
|
|
48
|
-
userVisible: detail.user_visible ?? false,
|
|
49
|
-
}));
|
|
50
|
-
}
|
|
51
|
-
|
|
52
39
|
export function createProposeCommitTool(cwd: string, state: CommitAgentState): CustomTool<typeof proposeCommitSchema> {
|
|
53
40
|
return {
|
|
54
41
|
name: "propose_commit",
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
validateTypeConsistency,
|
|
11
11
|
} from "../../../commit/agentic/validation";
|
|
12
12
|
import { validateScope } from "../../../commit/analysis/validation";
|
|
13
|
-
import
|
|
13
|
+
import { normalizeDetails } from "../../../commit/utils";
|
|
14
14
|
import type { CustomTool } from "../../../extensibility/custom-tools/types";
|
|
15
15
|
import * as git from "../../../utils/git";
|
|
16
16
|
import { commitTypeSchema, detailSchema } from "./schemas.js";
|
|
@@ -49,20 +49,6 @@ interface SplitCommitResponse {
|
|
|
49
49
|
proposal?: SplitCommitPlan;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
function normalizeDetails(
|
|
53
|
-
details: Array<{
|
|
54
|
-
text: string;
|
|
55
|
-
changelog_category?: ConventionalDetail["changelogCategory"];
|
|
56
|
-
user_visible?: boolean;
|
|
57
|
-
}>,
|
|
58
|
-
): ConventionalDetail[] {
|
|
59
|
-
return details.map(detail => ({
|
|
60
|
-
text: detail.text.trim(),
|
|
61
|
-
changelogCategory: detail.user_visible ? detail.changelog_category : undefined,
|
|
62
|
-
userVisible: detail.user_visible ?? false,
|
|
63
|
-
}));
|
|
64
|
-
}
|
|
65
|
-
|
|
66
52
|
export function createSplitCommitTool(
|
|
67
53
|
cwd: string,
|
|
68
54
|
state: CommitAgentState,
|
package/src/commit/utils.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AssistantMessage, ToolCall } from "@oh-my-pi/pi-ai";
|
|
2
|
-
import type { ChangelogCategory, ConventionalAnalysis } from "./types";
|
|
2
|
+
import type { ChangelogCategory, ConventionalAnalysis, ConventionalDetail } from "./types";
|
|
3
3
|
|
|
4
4
|
export function extractToolCall(message: AssistantMessage, name: string): ToolCall | undefined {
|
|
5
5
|
return message.content.find(content => content.type === "toolCall" && content.name === name) as ToolCall | undefined;
|
|
@@ -42,3 +42,17 @@ export function normalizeAnalysis(parsed: {
|
|
|
42
42
|
issueRefs: parsed.issue_refs ?? [],
|
|
43
43
|
};
|
|
44
44
|
}
|
|
45
|
+
|
|
46
|
+
export function normalizeDetails(
|
|
47
|
+
details: Array<{
|
|
48
|
+
text: string;
|
|
49
|
+
changelog_category?: ConventionalDetail["changelogCategory"];
|
|
50
|
+
user_visible?: boolean;
|
|
51
|
+
}>,
|
|
52
|
+
): ConventionalDetail[] {
|
|
53
|
+
return details.map(detail => ({
|
|
54
|
+
text: detail.text.trim(),
|
|
55
|
+
changelogCategory: detail.user_visible ? detail.changelog_category : undefined,
|
|
56
|
+
userVisible: detail.user_visible ?? false,
|
|
57
|
+
}));
|
|
58
|
+
}
|
|
@@ -1886,7 +1886,7 @@ export class ModelRegistry {
|
|
|
1886
1886
|
* Get API key for a model.
|
|
1887
1887
|
*/
|
|
1888
1888
|
async getApiKey(model: Model<Api>, sessionId?: string): Promise<string | undefined> {
|
|
1889
|
-
if (this.#keylessProviders.has(model.provider)) {
|
|
1889
|
+
if (this.#keylessProviders.has(model.provider) && !this.authStorage.hasAuth(model.provider)) {
|
|
1890
1890
|
return kNoAuth;
|
|
1891
1891
|
}
|
|
1892
1892
|
return this.authStorage.getApiKey(model.provider, sessionId, { baseUrl: model.baseUrl, modelId: model.id });
|
|
@@ -1896,14 +1896,14 @@ export class ModelRegistry {
|
|
|
1896
1896
|
* Get API key for a provider (e.g., "openai").
|
|
1897
1897
|
*/
|
|
1898
1898
|
async getApiKeyForProvider(provider: string, sessionId?: string, baseUrl?: string): Promise<string | undefined> {
|
|
1899
|
-
if (this.#keylessProviders.has(provider)) {
|
|
1899
|
+
if (this.#keylessProviders.has(provider) && !this.authStorage.hasAuth(provider)) {
|
|
1900
1900
|
return kNoAuth;
|
|
1901
1901
|
}
|
|
1902
1902
|
return this.authStorage.getApiKey(provider, sessionId, { baseUrl });
|
|
1903
1903
|
}
|
|
1904
1904
|
|
|
1905
1905
|
async #peekApiKeyForProvider(provider: string): Promise<string | undefined> {
|
|
1906
|
-
if (this.#keylessProviders.has(provider)) {
|
|
1906
|
+
if (this.#keylessProviders.has(provider) && !this.authStorage.hasAuth(provider)) {
|
|
1907
1907
|
return kNoAuth;
|
|
1908
1908
|
}
|
|
1909
1909
|
return this.authStorage.peekApiKey(provider);
|
|
@@ -31,18 +31,10 @@ prompt.registerHelper("jtdToTypeScript", (schema: unknown): string => {
|
|
|
31
31
|
}
|
|
32
32
|
});
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
* Name
|
|
39
|
-
* ═══════════════════════════════
|
|
40
|
-
*/
|
|
41
|
-
export function sectionSeparator(name: string): string {
|
|
42
|
-
return `\n\n═══════════${name}═══════════\n`;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
prompt.registerHelper("SECTION_SEPERATOR", (name: unknown): string => sectionSeparator(String(name)));
|
|
34
|
+
// `sectionSeparator` + SECTION_SEPARATOR helper live in pi-utils/prompt so every
|
|
35
|
+
// template consumer gets them registered without a coupling back to this module.
|
|
36
|
+
// Re-exported here for call sites that already reference the coding-agent path.
|
|
37
|
+
export { sectionSeparator } from "@oh-my-pi/pi-utils/prompt";
|
|
46
38
|
|
|
47
39
|
function formatHashlineRef(lineNum: unknown, content: unknown): { num: number; text: string; ref: string } {
|
|
48
40
|
const num = typeof lineNum === "number" ? lineNum : Number.parseInt(String(lineNum), 10);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { THINKING_EFFORTS } from "@oh-my-pi/pi-ai";
|
|
2
|
+
import { TASK_SIMPLE_MODES } from "../task/simple-mode";
|
|
2
3
|
|
|
3
4
|
/** Unified settings schema - single source of truth for all settings.
|
|
4
5
|
* Unified settings schema - single source of truth for all settings.
|
|
@@ -885,6 +886,8 @@ export const SETTINGS_SCHEMA = {
|
|
|
885
886
|
|
|
886
887
|
"memories.rolloutPayloadPercent": { type: "number", default: 0.7 },
|
|
887
888
|
|
|
889
|
+
"memories.phase1InputTokenLimit": { type: "number", default: 4000 },
|
|
890
|
+
|
|
888
891
|
"memories.fallbackTokenLimit": { type: "number", default: 16000 },
|
|
889
892
|
|
|
890
893
|
"memories.summaryInjectionTokenLimit": { type: "number", default: 5000 },
|
|
@@ -952,12 +955,12 @@ export const SETTINGS_SCHEMA = {
|
|
|
952
955
|
// Edit tool
|
|
953
956
|
"edit.mode": {
|
|
954
957
|
type: "enum",
|
|
955
|
-
values: ["replace", "patch", "hashline", "chunk", "vim"] as const,
|
|
958
|
+
values: ["replace", "patch", "hashline", "chunk", "vim", "apply_patch"] as const,
|
|
956
959
|
default: "hashline",
|
|
957
960
|
ui: {
|
|
958
961
|
tab: "editing",
|
|
959
962
|
label: "Edit Mode",
|
|
960
|
-
description: "Select the edit tool variant (replace, patch, hashline, chunk, or
|
|
963
|
+
description: "Select the edit tool variant (replace, patch, hashline, chunk, vim, or apply_patch)",
|
|
961
964
|
},
|
|
962
965
|
},
|
|
963
966
|
|
|
@@ -1033,6 +1036,16 @@ export const SETTINGS_SCHEMA = {
|
|
|
1033
1036
|
},
|
|
1034
1037
|
},
|
|
1035
1038
|
|
|
1039
|
+
"read.toolResultPreview": {
|
|
1040
|
+
type: "boolean",
|
|
1041
|
+
default: false,
|
|
1042
|
+
ui: {
|
|
1043
|
+
tab: "editing",
|
|
1044
|
+
label: "Inline Read Previews",
|
|
1045
|
+
description: "Render read tool results inline in the transcript instead of summary rows",
|
|
1046
|
+
},
|
|
1047
|
+
},
|
|
1048
|
+
|
|
1036
1049
|
"read.prosechunks": {
|
|
1037
1050
|
type: "boolean",
|
|
1038
1051
|
default: false,
|
|
@@ -1506,6 +1519,18 @@ export const SETTINGS_SCHEMA = {
|
|
|
1506
1519
|
},
|
|
1507
1520
|
},
|
|
1508
1521
|
|
|
1522
|
+
"task.simple": {
|
|
1523
|
+
type: "enum",
|
|
1524
|
+
values: TASK_SIMPLE_MODES,
|
|
1525
|
+
default: "default",
|
|
1526
|
+
ui: {
|
|
1527
|
+
tab: "tasks",
|
|
1528
|
+
label: "Task Input Mode",
|
|
1529
|
+
description: "How much shared structure the task tool accepts (default, schema-free, or independent)",
|
|
1530
|
+
submenu: true,
|
|
1531
|
+
},
|
|
1532
|
+
},
|
|
1533
|
+
|
|
1509
1534
|
"task.maxConcurrency": {
|
|
1510
1535
|
type: "number",
|
|
1511
1536
|
default: 32,
|
package/src/config/settings.ts
CHANGED
|
@@ -326,7 +326,7 @@ export class Settings {
|
|
|
326
326
|
|
|
327
327
|
/**
|
|
328
328
|
* Get the edit variant for a specific model.
|
|
329
|
-
* Returns "patch", "replace", "hashline", "chunk", "vim", or null (use global default).
|
|
329
|
+
* Returns "patch", "replace", "hashline", "chunk", "vim", "apply_patch", or null (use global default).
|
|
330
330
|
*/
|
|
331
331
|
getEditVariantForModel(model: string | undefined): EditMode | null {
|
|
332
332
|
if (!model) return null;
|
package/src/dap/session.ts
CHANGED
|
@@ -1075,11 +1075,17 @@ export class DapSessionManager {
|
|
|
1075
1075
|
* MUST be called before the command that triggers the event.
|
|
1076
1076
|
*/
|
|
1077
1077
|
#prepareStopOutcome(session: DapSession, signal?: AbortSignal, timeoutMs: number = 30_000): Promise<unknown> {
|
|
1078
|
-
|
|
1078
|
+
const promises = [
|
|
1079
1079
|
session.client.waitForEvent("stopped", undefined, signal, timeoutMs),
|
|
1080
1080
|
session.client.waitForEvent("terminated", undefined, signal, timeoutMs),
|
|
1081
1081
|
session.client.waitForEvent("exited", undefined, signal, timeoutMs),
|
|
1082
|
-
]
|
|
1082
|
+
];
|
|
1083
|
+
// Promise.race leaves the losing waiters pending; their timeouts would
|
|
1084
|
+
// otherwise surface as unhandled rejections once they fire.
|
|
1085
|
+
for (const p of promises) {
|
|
1086
|
+
p.catch(() => {});
|
|
1087
|
+
}
|
|
1088
|
+
return Promise.race(promises);
|
|
1083
1089
|
}
|
|
1084
1090
|
|
|
1085
1091
|
/**
|