@oh-my-pi/pi-coding-agent 16.0.3 → 16.0.4
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 +8 -0
- package/dist/cli.js +377 -97
- package/dist/types/cli/args.d.ts +1 -0
- package/dist/types/commands/launch.d.ts +3 -0
- package/dist/types/config/settings-schema.d.ts +1 -1
- package/dist/types/edit/file-snapshot-store.d.ts +2 -0
- package/package.json +12 -12
- package/src/cli/args.ts +3 -0
- package/src/cli/flag-tables.ts +1 -0
- package/src/commands/launch.ts +3 -0
- package/src/config/settings-schema.ts +1 -1
- package/src/edit/file-snapshot-store.ts +12 -3
- package/src/internal-urls/docs-index.generated.ts +81 -81
- package/src/main.ts +6 -4
- package/src/modes/components/tips.txt +2 -1
- package/src/prompts/system/system-prompt.md +2 -0
- package/src/session/agent-session.ts +7 -4
- package/src/tools/read.ts +26 -0
package/src/main.ts
CHANGED
|
@@ -124,11 +124,9 @@ async function checkForNewVersion(currentVersion: string): Promise<string | unde
|
|
|
124
124
|
}
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
+
// Todo settings are caller-controlled in protocol modes. Do not host-default them:
|
|
128
|
+
// embedders need project-level opt-outs for reminder/prelude prompt injection.
|
|
127
129
|
const HOST_DEFAULTED_SETTING_PATHS: SettingPath[] = [
|
|
128
|
-
"todo.enabled",
|
|
129
|
-
"todo.reminders",
|
|
130
|
-
"todo.reminders.max",
|
|
131
|
-
"todo.eager",
|
|
132
130
|
"task.isolation.mode",
|
|
133
131
|
"task.isolation.merge",
|
|
134
132
|
"task.isolation.commits",
|
|
@@ -1041,6 +1039,10 @@ export async function runRootCommand(
|
|
|
1041
1039
|
if (parsedArgs.hideThinking) {
|
|
1042
1040
|
settingsInstance.override("hideThinkingBlock", true);
|
|
1043
1041
|
}
|
|
1042
|
+
// Apply --advisor CLI flag (ephemeral, not persisted)
|
|
1043
|
+
if (parsedArgs.advisor) {
|
|
1044
|
+
settingsInstance.override("advisor.enabled", true);
|
|
1045
|
+
}
|
|
1044
1046
|
|
|
1045
1047
|
await logger.time(
|
|
1046
1048
|
"initTheme:final",
|
|
@@ -19,4 +19,5 @@ Press ctrl+r to search your prompt history and reuse a past message
|
|
|
19
19
|
`/shake` rips heavy tool results out of context to reclaim tokens without a full /compact — `/shake images` drops just images
|
|
20
20
|
Pair up live: `/collab` shares your session through an end-to-end encrypted relay link — a teammate runs `/join <link>` to watch tool calls stream and prompt the agent from their own omp
|
|
21
21
|
Press ← ← to drill into a running or finished agent and inspect its tool calls and transcript
|
|
22
|
-
Hit a Codex rate limit? `/usage reset` spends a saved reset credit to immediately restore your quota
|
|
22
|
+
Hit a Codex rate limit? `/usage reset` spends a saved reset credit to immediately restore your quota
|
|
23
|
+
No native tool_calling? Inference provider botches parsing them? `PI_DIALECT=glm|kimi|anthropic…` rolls it locally for them!
|
|
@@ -117,6 +117,8 @@ ENV
|
|
|
117
117
|
|
|
118
118
|
# Skills & Rules
|
|
119
119
|
{{#if skills.length}}
|
|
120
|
+
Skills are specialized knowledge. Scan descriptions for your task domain.
|
|
121
|
+
If a skill applies, you MUST read `skill://<name>` before proceeding.
|
|
120
122
|
<skills>
|
|
121
123
|
{{#each skills}}
|
|
122
124
|
- {{name}}: {{description}}
|
|
@@ -8164,14 +8164,17 @@ export class AgentSession {
|
|
|
8164
8164
|
maxAttempts: remindersMax,
|
|
8165
8165
|
});
|
|
8166
8166
|
|
|
8167
|
-
|
|
8168
|
-
// Inject reminder and continue the conversation
|
|
8169
|
-
this.agent.appendMessage({
|
|
8167
|
+
const reminderMessage: Message = {
|
|
8170
8168
|
role: "developer",
|
|
8171
8169
|
content: [{ type: "text", text: reminder }],
|
|
8172
8170
|
attribution: "agent",
|
|
8173
8171
|
timestamp: Date.now(),
|
|
8174
|
-
}
|
|
8172
|
+
};
|
|
8173
|
+
|
|
8174
|
+
this.#todoReminderAwaitingProgress = true;
|
|
8175
|
+
// Inject reminder and persist it so the JSONL transcript matches model context.
|
|
8176
|
+
this.agent.appendMessage(reminderMessage);
|
|
8177
|
+
this.sessionManager.appendMessage(reminderMessage);
|
|
8175
8178
|
this.#scheduleAgentContinue({ generation: this.#promptGeneration });
|
|
8176
8179
|
}
|
|
8177
8180
|
|
package/src/tools/read.ts
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
canonicalSnapshotKey,
|
|
15
15
|
getFileSnapshotStore,
|
|
16
16
|
recordFileSnapshot,
|
|
17
|
+
recordSeenLines,
|
|
17
18
|
recordSeenLinesFromBody,
|
|
18
19
|
SNAPSHOT_MAX_BYTES,
|
|
19
20
|
} from "../edit/file-snapshot-store";
|
|
@@ -288,6 +289,20 @@ function countTextLines(text: string): number {
|
|
|
288
289
|
return text.split("\n").length;
|
|
289
290
|
}
|
|
290
291
|
|
|
292
|
+
function contiguousLineNumbers(startLine: number, count: number): number[] {
|
|
293
|
+
const lines: number[] = [];
|
|
294
|
+
for (let offset = 0; offset < count; offset++) lines.push(startLine + offset);
|
|
295
|
+
return lines;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
function lineNumbersFromEntries(entries: readonly LineEntry[]): number[] {
|
|
299
|
+
const lines: number[] = [];
|
|
300
|
+
for (const entry of entries) {
|
|
301
|
+
if (entry.kind === "line") lines.push(entry.lineNumber);
|
|
302
|
+
}
|
|
303
|
+
return lines;
|
|
304
|
+
}
|
|
305
|
+
|
|
291
306
|
/** Inclusive line range describing one elided span in a structural summary. */
|
|
292
307
|
interface ElidedRange {
|
|
293
308
|
start: number;
|
|
@@ -1041,8 +1056,10 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
1041
1056
|
)
|
|
1042
1057
|
: undefined;
|
|
1043
1058
|
let emittedHashlineHeader = false;
|
|
1059
|
+
let seenLines: number[] | undefined;
|
|
1044
1060
|
const formatText = (content: string, startNum: number): string => {
|
|
1045
1061
|
details.displayContent = { text: content, startLine: startNum };
|
|
1062
|
+
if (shouldAddHashLines) seenLines = contiguousLineNumbers(startNum, countTextLines(content));
|
|
1046
1063
|
const formatted = formatTextWithMode(content, startNum, shouldAddHashLines, shouldAddLineNumbers);
|
|
1047
1064
|
if (!hashContext || emittedHashlineHeader) return formatted;
|
|
1048
1065
|
emittedHashlineHeader = true;
|
|
@@ -1054,6 +1071,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
1054
1071
|
text: lineEntriesToPlainText(entries, BRACKET_CONTEXT_ELLIPSIS),
|
|
1055
1072
|
startLine: firstLine?.kind === "line" ? firstLine.lineNumber : startNum,
|
|
1056
1073
|
};
|
|
1074
|
+
if (shouldAddHashLines) seenLines = lineNumbersFromEntries(entries);
|
|
1057
1075
|
const formatted = formatLineEntriesWithMode(entries, shouldAddHashLines, shouldAddLineNumbers);
|
|
1058
1076
|
if (!hashContext || emittedHashlineHeader) return formatted;
|
|
1059
1077
|
emittedHashlineHeader = true;
|
|
@@ -1121,6 +1139,9 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
1121
1139
|
: formatLineEntries(buildLineEntries(endLine), startLineDisplay);
|
|
1122
1140
|
}
|
|
1123
1141
|
|
|
1142
|
+
if (hashContext?.tag && options.sourcePath && seenLines) {
|
|
1143
|
+
recordSeenLines(this.session, options.sourcePath, hashContext.tag, seenLines);
|
|
1144
|
+
}
|
|
1124
1145
|
resultBuilder.text(outputText);
|
|
1125
1146
|
if (truncationInfo) {
|
|
1126
1147
|
resultBuilder.truncation(truncationInfo.result, truncationInfo.options);
|
|
@@ -1165,6 +1186,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
1165
1186
|
: undefined;
|
|
1166
1187
|
let emittedHashlineHeader = false;
|
|
1167
1188
|
|
|
1189
|
+
let seenLines: number[] | undefined;
|
|
1168
1190
|
const resultBuilder = toolResult(details);
|
|
1169
1191
|
if (options.sourcePath) resultBuilder.sourcePath(options.sourcePath);
|
|
1170
1192
|
if (options.sourceUrl) resultBuilder.sourceUrl(options.sourceUrl);
|
|
@@ -1190,6 +1212,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
1190
1212
|
outputText = rawParts.length > 0 ? rawParts.join("\n\n…\n\n") : "";
|
|
1191
1213
|
} else if (visibleSpans.length > 0) {
|
|
1192
1214
|
const entries = buildLineEntriesWithBlockContext(allLines, visibleSpans, { path: options.sourcePath });
|
|
1215
|
+
if (shouldAddHashLines) seenLines = lineNumbersFromEntries(entries);
|
|
1193
1216
|
const firstLine = entries.find(entry => entry.kind === "line");
|
|
1194
1217
|
if (firstLine?.kind === "line") {
|
|
1195
1218
|
details.displayContent = {
|
|
@@ -1208,6 +1231,9 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
1208
1231
|
}
|
|
1209
1232
|
const finalText =
|
|
1210
1233
|
notices.length > 0 ? (outputText ? `${outputText}\n${notices.join("\n")}` : notices.join("\n")) : outputText;
|
|
1234
|
+
if (hashContext?.tag && options.sourcePath && seenLines) {
|
|
1235
|
+
recordSeenLines(this.session, options.sourcePath, hashContext.tag, seenLines);
|
|
1236
|
+
}
|
|
1211
1237
|
resultBuilder.text(finalText);
|
|
1212
1238
|
return resultBuilder.done();
|
|
1213
1239
|
}
|