@oh-my-pi/pi-coding-agent 14.6.1 → 14.6.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.
- package/CHANGELOG.md +12 -0
- package/package.json +7 -7
- package/src/config/settings-schema.ts +10 -0
- package/src/config/settings.ts +4 -0
- package/src/modes/components/settings-selector.ts +2 -0
- package/src/modes/components/status-line.ts +4 -1
- package/src/modes/controllers/mcp-command-controller.ts +23 -0
- package/src/modes/controllers/selector-controller.ts +7 -0
- package/src/modes/interactive-mode.ts +3 -2
- package/src/ssh/connection-manager.ts +1 -1
- package/src/tools/output-meta.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [14.6.2] - 2026-05-03
|
|
6
|
+
### Added
|
|
7
|
+
|
|
8
|
+
- Added `statusLine.sessionAccent` to disable session-name accent coloring for the editor border and status line gap ([#918](https://github.com/can1357/oh-my-pi/issues/918))
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- Disabled repeated OSC 11 background-color polling under WSL to avoid Windows terminal tab crashes while keeping initial and event-driven appearance detection ([#914](https://github.com/can1357/oh-my-pi/issues/914))
|
|
13
|
+
|
|
14
|
+
- Fixed SSH ControlMaster socket paths to use OpenSSH's connection hash (`%C`) so connections to the same host with different users, ports, or jump hosts do not share a master session.
|
|
15
|
+
|
|
16
|
+
|
|
5
17
|
## [14.6.1] - 2026-05-02
|
|
6
18
|
### Changed
|
|
7
19
|
|
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.6.
|
|
4
|
+
"version": "14.6.2",
|
|
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",
|
|
@@ -46,12 +46,12 @@
|
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@agentclientprotocol/sdk": "0.20.0",
|
|
48
48
|
"@mozilla/readability": "^0.6.0",
|
|
49
|
-
"@oh-my-pi/omp-stats": "14.6.
|
|
50
|
-
"@oh-my-pi/pi-agent-core": "14.6.
|
|
51
|
-
"@oh-my-pi/pi-ai": "14.6.
|
|
52
|
-
"@oh-my-pi/pi-natives": "14.6.
|
|
53
|
-
"@oh-my-pi/pi-tui": "14.6.
|
|
54
|
-
"@oh-my-pi/pi-utils": "14.6.
|
|
49
|
+
"@oh-my-pi/omp-stats": "14.6.2",
|
|
50
|
+
"@oh-my-pi/pi-agent-core": "14.6.2",
|
|
51
|
+
"@oh-my-pi/pi-ai": "14.6.2",
|
|
52
|
+
"@oh-my-pi/pi-natives": "14.6.2",
|
|
53
|
+
"@oh-my-pi/pi-tui": "14.6.2",
|
|
54
|
+
"@oh-my-pi/pi-utils": "14.6.2",
|
|
55
55
|
"@puppeteer/browsers": "^2.13.0",
|
|
56
56
|
"@sinclair/typebox": "^0.34.49",
|
|
57
57
|
"@xterm/headless": "^6.0.0",
|
|
@@ -304,6 +304,16 @@ export const SETTINGS_SCHEMA = {
|
|
|
304
304
|
submenu: true,
|
|
305
305
|
},
|
|
306
306
|
},
|
|
307
|
+
|
|
308
|
+
"statusLine.sessionAccent": {
|
|
309
|
+
type: "boolean",
|
|
310
|
+
default: true,
|
|
311
|
+
ui: {
|
|
312
|
+
tab: "appearance",
|
|
313
|
+
label: "Session Accent",
|
|
314
|
+
description: "Use the session name color for the editor border and status line gap",
|
|
315
|
+
},
|
|
316
|
+
},
|
|
307
317
|
"tools.artifactSpillThreshold": {
|
|
308
318
|
type: "number",
|
|
309
319
|
default: 50,
|
package/src/config/settings.ts
CHANGED
|
@@ -713,6 +713,10 @@ const SETTING_HOOKS: Partial<Record<SettingPath, SettingHook<any>>> = {
|
|
|
713
713
|
let globalInstance: Settings | null = null;
|
|
714
714
|
let globalInstancePromise: Promise<Settings> | null = null;
|
|
715
715
|
|
|
716
|
+
export function isSettingsInitialized(): boolean {
|
|
717
|
+
return globalInstance !== null;
|
|
718
|
+
}
|
|
719
|
+
|
|
716
720
|
/**
|
|
717
721
|
* Reset the global singleton for testing.
|
|
718
722
|
* @internal
|
|
@@ -194,6 +194,7 @@ export interface StatusLinePreviewSettings {
|
|
|
194
194
|
leftSegments?: StatusLineSegmentId[];
|
|
195
195
|
rightSegments?: StatusLineSegmentId[];
|
|
196
196
|
separator?: StatusLineSeparatorStyle;
|
|
197
|
+
sessionAccent?: boolean;
|
|
197
198
|
}
|
|
198
199
|
|
|
199
200
|
export interface SettingsCallbacks {
|
|
@@ -563,6 +564,7 @@ export class SettingsSelectorComponent extends Container {
|
|
|
563
564
|
leftSegments: settings.get("statusLine.leftSegments"),
|
|
564
565
|
rightSegments: settings.get("statusLine.rightSegments"),
|
|
565
566
|
separator: settings.get("statusLine.separator"),
|
|
567
|
+
sessionAccent: settings.get("statusLine.sessionAccent"),
|
|
566
568
|
};
|
|
567
569
|
this.callbacks.onStatusLinePreview?.(statusLineSettings);
|
|
568
570
|
this.#updateStatusPreview();
|
|
@@ -36,6 +36,7 @@ export interface StatusLineSettings {
|
|
|
36
36
|
separator?: StatusLineSeparatorStyle;
|
|
37
37
|
segmentOptions?: StatusLineSegmentOptions;
|
|
38
38
|
showHookStatus?: boolean;
|
|
39
|
+
sessionAccent?: boolean;
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -80,6 +81,7 @@ export class StatusLineComponent implements Component {
|
|
|
80
81
|
separator: settings.get("statusLine.separator"),
|
|
81
82
|
showHookStatus: settings.get("statusLine.showHookStatus"),
|
|
82
83
|
segmentOptions: settings.getGroup("statusLine").segmentOptions,
|
|
84
|
+
sessionAccent: settings.get("statusLine.sessionAccent"),
|
|
83
85
|
};
|
|
84
86
|
}
|
|
85
87
|
|
|
@@ -514,7 +516,8 @@ export class StatusLineComponent implements Component {
|
|
|
514
516
|
leftWidth = groupWidth(left, leftCapWidth, leftSepWidth);
|
|
515
517
|
rightWidth = groupWidth(right, rightCapWidth, rightSepWidth);
|
|
516
518
|
const gapWidth = Math.max(1, topFillWidth - leftWidth - rightWidth);
|
|
517
|
-
const sessionName =
|
|
519
|
+
const sessionName =
|
|
520
|
+
effectiveSettings.sessionAccent !== false ? this.session.sessionManager?.getSessionName() : undefined;
|
|
518
521
|
const accentHex = sessionName ? getSessionAccentHex(sessionName) : undefined;
|
|
519
522
|
const gapColor = getSessionAccentAnsi(accentHex) ?? theme.getFgAnsi("border");
|
|
520
523
|
const gapFill = `${gapColor}${theme.boxRound.horizontal.repeat(gapWidth)}\x1b[39m`;
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Handles /mcp subcommands for managing MCP servers.
|
|
5
5
|
*/
|
|
6
|
+
import * as path from "node:path";
|
|
6
7
|
import { Spacer, Text } from "@oh-my-pi/pi-tui";
|
|
7
8
|
import { getMCPConfigPath, getProjectDir } from "@oh-my-pi/pi-utils";
|
|
8
9
|
import type { SourceMeta } from "../../capability/types";
|
|
@@ -656,6 +657,28 @@ export class MCPCommandController {
|
|
|
656
657
|
if (projectConfig.mcpServers?.[name]) {
|
|
657
658
|
return { filePath: projectPath, scope: "project", config: projectConfig.mcpServers[name] };
|
|
658
659
|
}
|
|
660
|
+
|
|
661
|
+
// Check standalone fallback files (mcp.json, .mcp.json) in the project root —
|
|
662
|
+
// these match the discovery paths used by the mcp-json provider. Reads run in
|
|
663
|
+
// parallel (mirroring user/project above) but precedence is preserved by the
|
|
664
|
+
// for-loop's iteration order: mcp.json wins over .mcp.json on a same-name hit.
|
|
665
|
+
const standalonePaths = [path.join(cwd, "mcp.json"), path.join(cwd, ".mcp.json")];
|
|
666
|
+
const fallbackConfigs = await Promise.all(
|
|
667
|
+
standalonePaths.map(async fallbackPath => {
|
|
668
|
+
try {
|
|
669
|
+
return await readMCPConfigFile(fallbackPath);
|
|
670
|
+
} catch {
|
|
671
|
+
// Malformed JSON in a standalone file — skip and continue lookup.
|
|
672
|
+
return null;
|
|
673
|
+
}
|
|
674
|
+
}),
|
|
675
|
+
);
|
|
676
|
+
for (const [index, fallbackConfig] of fallbackConfigs.entries()) {
|
|
677
|
+
const config = fallbackConfig?.mcpServers?.[name];
|
|
678
|
+
if (config) {
|
|
679
|
+
return { filePath: standalonePaths[index]!, scope: "project", config };
|
|
680
|
+
}
|
|
681
|
+
}
|
|
659
682
|
return null;
|
|
660
683
|
}
|
|
661
684
|
|
|
@@ -118,6 +118,7 @@ export class SelectorController {
|
|
|
118
118
|
rightSegments: settings.get("statusLine.rightSegments"),
|
|
119
119
|
separator: settings.get("statusLine.separator"),
|
|
120
120
|
showHookStatus: settings.get("statusLine.showHookStatus"),
|
|
121
|
+
sessionAccent: settings.get("statusLine.sessionAccent"),
|
|
121
122
|
...previewSettings,
|
|
122
123
|
});
|
|
123
124
|
this.ctx.updateEditorTopBorder();
|
|
@@ -140,6 +141,7 @@ export class SelectorController {
|
|
|
140
141
|
rightSegments: settings.get("statusLine.rightSegments"),
|
|
141
142
|
separator: settings.get("statusLine.separator"),
|
|
142
143
|
showHookStatus: settings.get("statusLine.showHookStatus"),
|
|
144
|
+
sessionAccent: settings.get("statusLine.sessionAccent"),
|
|
143
145
|
});
|
|
144
146
|
this.ctx.updateEditorTopBorder();
|
|
145
147
|
this.ctx.ui.requestRender();
|
|
@@ -332,8 +334,12 @@ export class SelectorController {
|
|
|
332
334
|
break;
|
|
333
335
|
}
|
|
334
336
|
case "statusLinePreset":
|
|
337
|
+
case "statusLine.preset":
|
|
335
338
|
case "statusLineSeparator":
|
|
339
|
+
case "statusLine.separator":
|
|
336
340
|
case "statusLineShowHooks":
|
|
341
|
+
case "statusLine.showHookStatus":
|
|
342
|
+
case "statusLine.sessionAccent":
|
|
337
343
|
case "statusLineSegments":
|
|
338
344
|
case "statusLineModelThinking":
|
|
339
345
|
case "statusLinePathAbbreviate":
|
|
@@ -351,6 +357,7 @@ export class SelectorController {
|
|
|
351
357
|
rightSegments: settings.get("statusLine.rightSegments"),
|
|
352
358
|
separator: settings.get("statusLine.separator"),
|
|
353
359
|
showHookStatus: settings.get("statusLine.showHookStatus"),
|
|
360
|
+
sessionAccent: settings.get("statusLine.sessionAccent"),
|
|
354
361
|
segmentOptions: settings.get("statusLine.segmentOptions"),
|
|
355
362
|
};
|
|
356
363
|
this.ctx.statusLine.updateSettings(statusLineSettings);
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
import { APP_NAME, getProjectDir, hsvToRgb, isEnoent, logger, postmortem, prompt } from "@oh-my-pi/pi-utils";
|
|
29
29
|
import chalk from "chalk";
|
|
30
30
|
import { KeybindingsManager } from "../config/keybindings";
|
|
31
|
-
import { type Settings, settings } from "../config/settings";
|
|
31
|
+
import { isSettingsInitialized, type Settings, settings } from "../config/settings";
|
|
32
32
|
import type {
|
|
33
33
|
ExtensionUIContext,
|
|
34
34
|
ExtensionUIDialogOptions,
|
|
@@ -644,7 +644,8 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
644
644
|
} else if (this.isPythonMode) {
|
|
645
645
|
this.editor.borderColor = theme.getPythonModeBorderColor();
|
|
646
646
|
} else {
|
|
647
|
-
const
|
|
647
|
+
const accentEnabled = !isSettingsInitialized() || settings.get("statusLine.sessionAccent") !== false;
|
|
648
|
+
const sessionName = accentEnabled ? this.sessionManager.getSessionName() : undefined;
|
|
648
649
|
const hex = sessionName ? getSessionAccentHex(sessionName) : undefined;
|
|
649
650
|
const ansi = getSessionAccentAnsi(hex);
|
|
650
651
|
if (ansi) {
|
|
@@ -25,7 +25,7 @@ export interface SSHHostInfo {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
const CONTROL_DIR = getSshControlDir();
|
|
28
|
-
const CONTROL_PATH = path.join(CONTROL_DIR, "%
|
|
28
|
+
const CONTROL_PATH = path.join(CONTROL_DIR, "%C.sock");
|
|
29
29
|
const HOST_INFO_DIR = getRemoteHostDir();
|
|
30
30
|
const HOST_INFO_VERSION = 2;
|
|
31
31
|
|
package/src/tools/output-meta.ts
CHANGED
|
@@ -465,6 +465,7 @@ async function spillLargeResultToArtifact(
|
|
|
465
465
|
): Promise<AgentToolResult> {
|
|
466
466
|
const sessionManager = context?.sessionManager;
|
|
467
467
|
if (!sessionManager) return result;
|
|
468
|
+
if (toolName === "read") return result;
|
|
468
469
|
const { threshold, tailBytes, tailLines } = getSpillConfig(context?.settings);
|
|
469
470
|
|
|
470
471
|
// Skip if tool already saved an artifact
|