pi-repoprompt-mcp 0.5.4 → 0.6.0
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/README.md +1 -2
- package/extensions/repoprompt-mcp/src/binding.ts +140 -101
- package/extensions/repoprompt-mcp/src/index.ts +6 -18
- package/extensions/repoprompt-mcp/src/result-normalization.ts +1 -2
- package/extensions/repoprompt-mcp/src/tool-forwarding-policy.ts +1 -2
- package/extensions/repoprompt-mcp/src/types.ts +0 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -53,7 +53,7 @@ Forked sessions inherit the parent session-plus-node's window, tab, and auto-sel
|
|
|
53
53
|
<img width="270" height="936" alt="Collapsed call/result summaries" src="https://raw.githubusercontent.com/w-winter/dot314/main/packages/pi-repoprompt-mcp/docs/images/collapsed-summaries.png" />
|
|
54
54
|
</p>
|
|
55
55
|
|
|
56
|
-
- RepoPrompt `apply_edits` calls are forwarded with `verbose: true` by default
|
|
56
|
+
- RepoPrompt `apply_edits` calls are forwarded with `verbose: true` by default, while the returned diff is normalized into `details.diff` and presented to the agent as a terse summary. The same is done for `file_actions create/delete` outputs, so you see all edited/created/deleted LOC with rich rendering but the extension prevents the context window from getting bloated by round-tripping tool I/O tokens
|
|
57
57
|
- Adaptive diff rendering for RepoPrompt `git` and `apply_edits` outputs by default (`diffViewMode: "auto"` picks split, unified, compact, or summary at render time based on pane width). This uses the active Pi theme's `toolDiffAdded`, `toolDiffRemoved`, and `toolDiffContext` colors (typically mapped to chosen hues for green and red), and its visual design and rendering logic are indebted to [MasuRii/pi-tool-display](https://github.com/MasuRii/pi-tool-display). Two different examples at different pane widths:
|
|
58
58
|
|
|
59
59
|
<p align="center">
|
|
@@ -207,7 +207,6 @@ but this is best-effort
|
|
|
207
207
|
|
|
208
208
|
## Readcache gotchas
|
|
209
209
|
|
|
210
|
-
- `raw: true` disables readcache (and rendering). Don't use unless debugging
|
|
211
210
|
- Need full content? use `bypass_cache: true` in `read_file` args
|
|
212
211
|
- Multi-root: use absolute or specific relative paths (MCP `read_file` has no `RootName:` disambiguation)
|
|
213
212
|
|
|
@@ -754,7 +754,7 @@ function parseTabFromJson(raw: unknown): RpTab | null {
|
|
|
754
754
|
}
|
|
755
755
|
|
|
756
756
|
const obj = raw as Record<string, unknown>;
|
|
757
|
-
const idRaw = obj.id ?? obj.tabId ?? obj.tab_id ?? obj.uuid;
|
|
757
|
+
const idRaw = obj.contextId ?? obj.context_id ?? obj.id ?? obj.tabId ?? obj.tab_id ?? obj.uuid;
|
|
758
758
|
if (typeof idRaw !== "string" || !idRaw.trim()) {
|
|
759
759
|
return null;
|
|
760
760
|
}
|
|
@@ -786,7 +786,20 @@ function collectTabsFromJson(raw: unknown): RpTab[] {
|
|
|
786
786
|
}
|
|
787
787
|
|
|
788
788
|
const obj = raw as Record<string, unknown>;
|
|
789
|
-
const containers = [
|
|
789
|
+
const containers = [
|
|
790
|
+
obj.tabs,
|
|
791
|
+
obj.contexts,
|
|
792
|
+
obj.tab,
|
|
793
|
+
obj.context,
|
|
794
|
+
obj.createdTab,
|
|
795
|
+
obj.created_tab,
|
|
796
|
+
obj.createdContext,
|
|
797
|
+
obj.created_context,
|
|
798
|
+
obj.selectedTab,
|
|
799
|
+
obj.selected_tab,
|
|
800
|
+
obj.selectedContext,
|
|
801
|
+
obj.selected_context,
|
|
802
|
+
];
|
|
790
803
|
|
|
791
804
|
for (const candidate of containers) {
|
|
792
805
|
const parsed = collectTabsFromJson(candidate);
|
|
@@ -835,7 +848,26 @@ function dedupeTabs(tabs: RpTab[]): RpTab[] {
|
|
|
835
848
|
|
|
836
849
|
function parseTabLine(line: string): RpTab | null {
|
|
837
850
|
const trimmed = line.trim();
|
|
838
|
-
if (!trimmed
|
|
851
|
+
if (!trimmed) {
|
|
852
|
+
return null;
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
const contextMatch = trimmed.match(/^[\u2022-]\s*(.+?)(?:\s+\[([^\]]+)\])?\s+—\s+context_id:\s*`([^`]+)`/i);
|
|
856
|
+
if (contextMatch) {
|
|
857
|
+
const state = contextMatch[2] ?? "";
|
|
858
|
+
return {
|
|
859
|
+
id: contextMatch[3].trim(),
|
|
860
|
+
name: stripTrailingTabStateAnnotations(contextMatch[1].trim()) || contextMatch[3].trim(),
|
|
861
|
+
isActive: /\bactive\b|\bin-focus\b/i.test(state)
|
|
862
|
+
? true
|
|
863
|
+
: /\bout-of-focus\b/i.test(state)
|
|
864
|
+
? false
|
|
865
|
+
: undefined,
|
|
866
|
+
isBound: /\bbound\b/i.test(state) ? true : undefined,
|
|
867
|
+
};
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
if (!trimmed.includes("`")) {
|
|
839
871
|
return null;
|
|
840
872
|
}
|
|
841
873
|
|
|
@@ -869,6 +901,17 @@ function parseTabLine(line: string): RpTab | null {
|
|
|
869
901
|
};
|
|
870
902
|
}
|
|
871
903
|
|
|
904
|
+
function parseTabsFromBindContextText(text: string): RpTab[] {
|
|
905
|
+
return dedupeTabs(
|
|
906
|
+
text
|
|
907
|
+
.split("\n")
|
|
908
|
+
.map((line) => line.trim())
|
|
909
|
+
.filter((line) => /—\s+context_id:\s*`[^`]+`/i.test(line))
|
|
910
|
+
.map(parseTabLine)
|
|
911
|
+
.filter((tab): tab is RpTab => tab !== null)
|
|
912
|
+
);
|
|
913
|
+
}
|
|
914
|
+
|
|
872
915
|
export function parseTabList(text: string): RpTab[] {
|
|
873
916
|
const tabs: RpTab[] = [];
|
|
874
917
|
let lastTab: RpTab | null = null;
|
|
@@ -899,132 +942,129 @@ function parseTabsFromJson(value: unknown): RpTab[] | null {
|
|
|
899
942
|
return tabs.length > 0 ? dedupeTabs(tabs) : null;
|
|
900
943
|
}
|
|
901
944
|
|
|
902
|
-
function
|
|
903
|
-
if (!
|
|
904
|
-
return
|
|
905
|
-
}
|
|
906
|
-
|
|
907
|
-
if (Array.isArray(value)) {
|
|
908
|
-
return value.length;
|
|
945
|
+
function findLiveTab(tabs: RpTab[], reference: string | undefined): RpTab | null {
|
|
946
|
+
if (!reference) {
|
|
947
|
+
return null;
|
|
909
948
|
}
|
|
910
949
|
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
}
|
|
950
|
+
return tabs.find((tab) => tab.id === reference || tab.name === reference) ?? null;
|
|
951
|
+
}
|
|
914
952
|
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
);
|
|
919
|
-
if (directCount !== undefined) {
|
|
920
|
-
return directCount;
|
|
921
|
-
}
|
|
953
|
+
function isExplicitlyEmptyTab(tab: RpTab): boolean {
|
|
954
|
+
return tab.selectedFileCount === 0;
|
|
955
|
+
}
|
|
922
956
|
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
957
|
+
function orderReusableTabCandidates(tabs: RpTab[]): RpTab[] {
|
|
958
|
+
const ordered = [
|
|
959
|
+
...tabs.filter((tab) => tab.isBound === true),
|
|
960
|
+
...tabs.filter((tab) => tab.isBound !== true && tab.isActive === true),
|
|
961
|
+
...tabs.filter((tab) => tab.isBound !== true && tab.isActive !== true),
|
|
962
|
+
];
|
|
929
963
|
|
|
930
|
-
return
|
|
964
|
+
return ordered.filter((tab, index) => ordered.findIndex((candidate) => candidate.id === tab.id) === index);
|
|
931
965
|
}
|
|
932
966
|
|
|
933
|
-
function
|
|
934
|
-
const
|
|
935
|
-
if (countMatch?.[1]) {
|
|
936
|
-
return parseCountMaybe(countMatch[1]);
|
|
937
|
-
}
|
|
967
|
+
function parseOracleSessionTabPrefixes(text: string): Set<string> {
|
|
968
|
+
const prefixes = new Set<string>();
|
|
938
969
|
|
|
939
|
-
|
|
940
|
-
|
|
970
|
+
for (const match of text.matchAll(/\btab=([A-F0-9-]{6,})(?:…|\b)/gi)) {
|
|
971
|
+
const prefix = match[1]?.trim().toUpperCase();
|
|
972
|
+
if (prefix) {
|
|
973
|
+
prefixes.add(prefix);
|
|
974
|
+
}
|
|
941
975
|
}
|
|
942
976
|
|
|
943
|
-
|
|
944
|
-
.split("\n")
|
|
945
|
-
.map((line) => line.trim())
|
|
946
|
-
.filter((line) => /^•\s*\[[^\]]+\]/.test(line)).length;
|
|
947
|
-
|
|
948
|
-
return sessionCount > 0 ? sessionCount : undefined;
|
|
977
|
+
return prefixes;
|
|
949
978
|
}
|
|
950
979
|
|
|
951
|
-
async function
|
|
952
|
-
|
|
980
|
+
async function fetchOracleSessionTabPrefixes(
|
|
981
|
+
windowId: number,
|
|
953
982
|
client: ReturnType<typeof getRpClient> = getRpClient()
|
|
954
|
-
): Promise<
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
const chatsToolName = resolveToolName(client.tools, "chats");
|
|
960
|
-
if (!chatsToolName) {
|
|
961
|
-
return undefined;
|
|
983
|
+
): Promise<Set<string> | null> {
|
|
984
|
+
const oracleUtilsToolName = resolveToolName(client.tools, "oracle_utils");
|
|
985
|
+
if (!oracleUtilsToolName) {
|
|
986
|
+
return null;
|
|
962
987
|
}
|
|
963
988
|
|
|
964
|
-
const result = await client.callTool(
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
limit: 1,
|
|
989
|
+
const result = await client.callTool(oracleUtilsToolName, {
|
|
990
|
+
op: "sessions",
|
|
991
|
+
limit: 200,
|
|
992
|
+
_windowID: windowId,
|
|
969
993
|
});
|
|
970
994
|
|
|
971
995
|
if (result.isError) {
|
|
972
|
-
return
|
|
973
|
-
}
|
|
974
|
-
|
|
975
|
-
const countFromJson = parseChatCountFromJson(extractJsonContent(result.content));
|
|
976
|
-
if (countFromJson !== undefined) {
|
|
977
|
-
return countFromJson;
|
|
996
|
+
return null;
|
|
978
997
|
}
|
|
979
998
|
|
|
980
|
-
return
|
|
999
|
+
return parseOracleSessionTabPrefixes(extractTextContent(result.content));
|
|
981
1000
|
}
|
|
982
1001
|
|
|
983
|
-
function
|
|
984
|
-
if (!
|
|
985
|
-
return
|
|
1002
|
+
function tabHasOracleHistory(tabId: string, sessionTabPrefixes: Set<string> | null): boolean {
|
|
1003
|
+
if (!sessionTabPrefixes || sessionTabPrefixes.size === 0) {
|
|
1004
|
+
return false;
|
|
986
1005
|
}
|
|
987
1006
|
|
|
988
|
-
|
|
989
|
-
|
|
1007
|
+
const normalizedTabId = tabId.trim().toUpperCase();
|
|
1008
|
+
for (const prefix of sessionTabPrefixes) {
|
|
1009
|
+
if (normalizedTabId.startsWith(prefix)) {
|
|
1010
|
+
return true;
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
990
1013
|
|
|
991
|
-
|
|
992
|
-
return tab.selectedFileCount === 0;
|
|
1014
|
+
return false;
|
|
993
1015
|
}
|
|
994
1016
|
|
|
995
|
-
async function
|
|
1017
|
+
async function hasEmptySelection(
|
|
1018
|
+
windowId: number,
|
|
996
1019
|
tab: RpTab,
|
|
997
1020
|
client: ReturnType<typeof getRpClient> = getRpClient()
|
|
998
1021
|
): Promise<boolean> {
|
|
999
|
-
if (
|
|
1022
|
+
if (isExplicitlyEmptyTab(tab)) {
|
|
1023
|
+
return true;
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
const manageSelectionToolName = resolveToolName(client.tools, "manage_selection");
|
|
1027
|
+
if (!manageSelectionToolName) {
|
|
1000
1028
|
return false;
|
|
1001
1029
|
}
|
|
1002
1030
|
|
|
1003
|
-
const
|
|
1004
|
-
|
|
1005
|
-
|
|
1031
|
+
const result = await client.callTool(manageSelectionToolName, {
|
|
1032
|
+
op: "get",
|
|
1033
|
+
view: "summary",
|
|
1034
|
+
_windowID: windowId,
|
|
1035
|
+
context_id: tab.id,
|
|
1036
|
+
});
|
|
1006
1037
|
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
if (emptyTabs.length === 0) {
|
|
1010
|
-
return [];
|
|
1038
|
+
if (result.isError) {
|
|
1039
|
+
return false;
|
|
1011
1040
|
}
|
|
1012
1041
|
|
|
1013
|
-
const
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
...emptyTabs.filter((tab) => tab.isBound !== true && tab.isActive !== true),
|
|
1017
|
-
];
|
|
1042
|
+
const text = extractTextContent(result.content);
|
|
1043
|
+
return /\b0 total tokens\b/i.test(text);
|
|
1044
|
+
}
|
|
1018
1045
|
|
|
1019
|
-
|
|
1046
|
+
async function isSafeReusableTab(
|
|
1047
|
+
windowId: number,
|
|
1048
|
+
tab: RpTab,
|
|
1049
|
+
sessionTabPrefixes: Set<string> | null,
|
|
1050
|
+
client: ReturnType<typeof getRpClient> = getRpClient()
|
|
1051
|
+
): Promise<boolean> {
|
|
1052
|
+
if (tabHasOracleHistory(tab.id, sessionTabPrefixes)) {
|
|
1053
|
+
return false;
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
return await hasEmptySelection(windowId, tab, client);
|
|
1020
1057
|
}
|
|
1021
1058
|
|
|
1022
1059
|
async function findReusableSafeTab(
|
|
1060
|
+
windowId: number,
|
|
1023
1061
|
tabs: RpTab[],
|
|
1024
1062
|
client: ReturnType<typeof getRpClient> = getRpClient()
|
|
1025
1063
|
): Promise<RpTab | null> {
|
|
1026
|
-
|
|
1027
|
-
|
|
1064
|
+
const sessionTabPrefixes = await fetchOracleSessionTabPrefixes(windowId, client);
|
|
1065
|
+
|
|
1066
|
+
for (const tab of orderReusableTabCandidates(tabs)) {
|
|
1067
|
+
if (await isSafeReusableTab(windowId, tab, sessionTabPrefixes, client)) {
|
|
1028
1068
|
return tab;
|
|
1029
1069
|
}
|
|
1030
1070
|
}
|
|
@@ -1066,14 +1106,14 @@ export async function fetchWindowTabs(
|
|
|
1066
1106
|
throw new Error("Not connected to RepoPrompt");
|
|
1067
1107
|
}
|
|
1068
1108
|
|
|
1069
|
-
const
|
|
1070
|
-
if (!
|
|
1109
|
+
const bindContextToolName = resolveToolName(client.tools, "bind_context");
|
|
1110
|
+
if (!bindContextToolName) {
|
|
1071
1111
|
return [];
|
|
1072
1112
|
}
|
|
1073
1113
|
|
|
1074
|
-
const result = await client.callTool(
|
|
1075
|
-
|
|
1076
|
-
|
|
1114
|
+
const result = await client.callTool(bindContextToolName, {
|
|
1115
|
+
op: "list",
|
|
1116
|
+
window_id: windowId,
|
|
1077
1117
|
});
|
|
1078
1118
|
|
|
1079
1119
|
if (result.isError) {
|
|
@@ -1086,7 +1126,7 @@ export async function fetchWindowTabs(
|
|
|
1086
1126
|
return tabsFromJson;
|
|
1087
1127
|
}
|
|
1088
1128
|
|
|
1089
|
-
return
|
|
1129
|
+
return parseTabsFromBindContextText(extractTextContent(result.content));
|
|
1090
1130
|
}
|
|
1091
1131
|
|
|
1092
1132
|
async function selectTab(
|
|
@@ -1094,16 +1134,15 @@ async function selectTab(
|
|
|
1094
1134
|
tabId: string,
|
|
1095
1135
|
client: ReturnType<typeof getRpClient> = getRpClient()
|
|
1096
1136
|
): Promise<void> {
|
|
1097
|
-
const
|
|
1098
|
-
if (!
|
|
1137
|
+
const bindContextToolName = resolveToolName(client.tools, "bind_context");
|
|
1138
|
+
if (!bindContextToolName) {
|
|
1099
1139
|
return;
|
|
1100
1140
|
}
|
|
1101
1141
|
|
|
1102
|
-
const result = await client.callTool(
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
...bindingWindowArgs(windowId),
|
|
1142
|
+
const result = await client.callTool(bindContextToolName, {
|
|
1143
|
+
op: "bind",
|
|
1144
|
+
window_id: windowId,
|
|
1145
|
+
context_id: tabId,
|
|
1107
1146
|
});
|
|
1108
1147
|
|
|
1109
1148
|
if (result.isError) {
|
|
@@ -1290,7 +1329,7 @@ export async function ensureBindingHasTab(
|
|
|
1290
1329
|
}
|
|
1291
1330
|
|
|
1292
1331
|
if (!binding.tab || reuseSoleEmptyTab || recoverIfMissing) {
|
|
1293
|
-
const reusableSafeTab = await findReusableSafeTab(liveTabs, client);
|
|
1332
|
+
const reusableSafeTab = await findReusableSafeTab(binding.windowId, liveTabs, client);
|
|
1294
1333
|
if (reusableSafeTab) {
|
|
1295
1334
|
return await adoptTab(reusableSafeTab, true);
|
|
1296
1335
|
}
|
|
@@ -1498,7 +1537,7 @@ export function getBindingArgs(): Record<string, unknown> {
|
|
|
1498
1537
|
};
|
|
1499
1538
|
|
|
1500
1539
|
if (currentBinding.tab) {
|
|
1501
|
-
args.
|
|
1540
|
+
args.context_id = currentBinding.tab;
|
|
1502
1541
|
}
|
|
1503
1542
|
|
|
1504
1543
|
return args;
|
|
@@ -546,9 +546,6 @@ const RpToolSchema = Type.Object({
|
|
|
546
546
|
confirmEdits: Type.Optional(
|
|
547
547
|
Type.Boolean({ description: "Confirm edit-like operations (required when confirmEdits is enabled)" })
|
|
548
548
|
),
|
|
549
|
-
|
|
550
|
-
// Formatting
|
|
551
|
-
raw: Type.Optional(Type.Boolean({ description: "Return raw output without formatting" })),
|
|
552
549
|
});
|
|
553
550
|
|
|
554
551
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -816,7 +813,7 @@ export default function repopromptMcp(pi: ExtensionAPI) {
|
|
|
816
813
|
function bindingArgsForAutoSelectionState(state: AutoSelectionEntryData): Record<string, unknown> {
|
|
817
814
|
return {
|
|
818
815
|
_windowID: state.windowId,
|
|
819
|
-
...(state.tab ? {
|
|
816
|
+
...(state.tab ? { context_id: state.tab } : {}),
|
|
820
817
|
};
|
|
821
818
|
}
|
|
822
819
|
|
|
@@ -1585,9 +1582,9 @@ export default function repopromptMcp(pi: ExtensionAPI) {
|
|
|
1585
1582
|
try {
|
|
1586
1583
|
await ensureTabScopedBinding(ctx, "RepoPrompt binding has no tab. Use /rp bind or /rp tab new first.");
|
|
1587
1584
|
|
|
1588
|
-
const
|
|
1589
|
-
if (!
|
|
1590
|
-
ctx.ui.notify("RepoPrompt tool '
|
|
1585
|
+
const oracleSendToolName = resolveToolName(client.tools, "oracle_send");
|
|
1586
|
+
if (!oracleSendToolName) {
|
|
1587
|
+
ctx.ui.notify("RepoPrompt tool 'oracle_send' not available", "error");
|
|
1591
1588
|
return;
|
|
1592
1589
|
}
|
|
1593
1590
|
|
|
@@ -1601,7 +1598,7 @@ export default function repopromptMcp(pi: ExtensionAPI) {
|
|
|
1601
1598
|
if (chatName) callArgs.chat_name = chatName;
|
|
1602
1599
|
if (chatId) callArgs.chat_id = chatId;
|
|
1603
1600
|
|
|
1604
|
-
const result = await client.callTool(
|
|
1601
|
+
const result = await client.callTool(oracleSendToolName, callArgs);
|
|
1605
1602
|
|
|
1606
1603
|
const text = extractTextContent(result.content);
|
|
1607
1604
|
|
|
@@ -1783,10 +1780,6 @@ Mode priority: call > describe > search > windows > bind > status`,
|
|
|
1783
1780
|
return new Text(theme.fg("error", "↳ " + textContent), 0, 0);
|
|
1784
1781
|
}
|
|
1785
1782
|
|
|
1786
|
-
if (details.raw) {
|
|
1787
|
-
return new Text(textContent, 0, 0);
|
|
1788
|
-
}
|
|
1789
|
-
|
|
1790
1783
|
const successPrefix = theme.fg("success", "↳ ");
|
|
1791
1784
|
const collapsedMaxLines = config.collapsedMaxLines ?? 15;
|
|
1792
1785
|
const normalizedToolName = typeof details.tool === "string" ? normalizeToolName(details.tool) : undefined;
|
|
@@ -2577,14 +2570,12 @@ Mode priority: call > describe > search > windows > bind > status`,
|
|
|
2577
2570
|
const forwardedUserArgs = buildForwardedUserArgs({
|
|
2578
2571
|
toolName: normalizedTool,
|
|
2579
2572
|
userArgs,
|
|
2580
|
-
raw: params.raw,
|
|
2581
2573
|
});
|
|
2582
2574
|
|
|
2583
2575
|
const mergedArgs = { ...forwardedUserArgs, ...bindingArgs };
|
|
2584
2576
|
|
|
2585
2577
|
const fileActionDeleteSnapshot = normalizedTool === "file_actions"
|
|
2586
2578
|
&& userArgs.action === "delete"
|
|
2587
|
-
&& params.raw !== true
|
|
2588
2579
|
&& typeof userArgs.path === "string"
|
|
2589
2580
|
? (() => {
|
|
2590
2581
|
try {
|
|
@@ -2611,7 +2602,6 @@ Mode priority: call > describe > search > windows > bind > status`,
|
|
|
2611
2602
|
|
|
2612
2603
|
const shouldReadcache =
|
|
2613
2604
|
config.readcacheReadFile === true &&
|
|
2614
|
-
params.raw !== true &&
|
|
2615
2605
|
normalizedTool === "read_file" &&
|
|
2616
2606
|
typeof userArgs.path === "string" &&
|
|
2617
2607
|
ctx !== undefined;
|
|
@@ -2668,9 +2658,8 @@ Mode priority: call > describe > search > windows > bind > status`,
|
|
|
2668
2658
|
: normalizeToolResultText({
|
|
2669
2659
|
toolName: normalizedTool,
|
|
2670
2660
|
text: textContent,
|
|
2671
|
-
raw: params.raw,
|
|
2672
2661
|
});
|
|
2673
|
-
const normalizedFileActionResult = result.isError
|
|
2662
|
+
const normalizedFileActionResult = result.isError
|
|
2674
2663
|
? null
|
|
2675
2664
|
: normalizeFileActionResult({
|
|
2676
2665
|
action: userArgs.action,
|
|
@@ -2733,7 +2722,6 @@ Mode priority: call > describe > search > windows > bind > status`,
|
|
|
2733
2722
|
warning: guardResult.warning,
|
|
2734
2723
|
editNoop,
|
|
2735
2724
|
rpReadcache: rpReadcache ?? undefined,
|
|
2736
|
-
raw: params.raw,
|
|
2737
2725
|
...(normalizedTextResult ? normalizedTextResult.details : {}),
|
|
2738
2726
|
...(normalizedFileActionResult ?? {}),
|
|
2739
2727
|
},
|
|
@@ -39,9 +39,8 @@ function normalizeDiffBlockCode(code: string): string {
|
|
|
39
39
|
export function normalizeToolResultText(args: {
|
|
40
40
|
toolName: string | undefined;
|
|
41
41
|
text: string;
|
|
42
|
-
raw: boolean | undefined;
|
|
43
42
|
}): ToolResultNormalization | null {
|
|
44
|
-
if (args.toolName !== "apply_edits" ||
|
|
43
|
+
if (args.toolName !== "apply_edits" || !args.text.includes("```diff")) {
|
|
45
44
|
return null;
|
|
46
45
|
}
|
|
47
46
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
export function buildForwardedUserArgs(args: {
|
|
2
2
|
toolName: string | undefined;
|
|
3
3
|
userArgs: Record<string, unknown>;
|
|
4
|
-
raw: boolean | undefined;
|
|
5
4
|
}): Record<string, unknown> {
|
|
6
5
|
const forwardedUserArgs: Record<string, unknown> = { ...args.userArgs };
|
|
7
6
|
|
|
@@ -9,7 +8,7 @@ export function buildForwardedUserArgs(args: {
|
|
|
9
8
|
delete forwardedUserArgs.bypass_cache;
|
|
10
9
|
}
|
|
11
10
|
|
|
12
|
-
if (args.toolName === "apply_edits"
|
|
11
|
+
if (args.toolName === "apply_edits") {
|
|
13
12
|
forwardedUserArgs.verbose = true;
|
|
14
13
|
}
|
|
15
14
|
|
|
@@ -152,9 +152,6 @@ export interface RpToolParams {
|
|
|
152
152
|
// Safety overrides
|
|
153
153
|
allowDelete?: boolean; // Allow delete operations
|
|
154
154
|
confirmEdits?: boolean; // Confirm edit-like operations when confirmEdits is enabled
|
|
155
|
-
|
|
156
|
-
// Formatting
|
|
157
|
-
raw?: boolean; // Return raw output without formatting
|
|
158
155
|
}
|
|
159
156
|
|
|
160
157
|
// ─────────────────────────────────────────────────────────────────────────────
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-repoprompt-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "A token-efficient RepoPrompt integration for Pi with automated and branch-safe workspace management",
|
|
5
5
|
"keywords": ["pi-package", "pi", "pi-coding-agent", "repoprompt", "mcp"],
|
|
6
6
|
"license": "MIT",
|