fix(coding-agent): suppressed circular plan-yolo notice

Passed explicit plan-yolo state into print mode so the startup-default warning only describes bare headless runs.

Fixes #8312
This commit is contained in:
roboomp
2026-08-12 05:01:17 +00:00
parent 06aecdd51f
commit 3d35bda89d
4 changed files with 27 additions and 2 deletions
+4
View File
@@ -2,6 +2,10 @@
## [Unreleased]
### Fixed
- Fixed print mode claiming `plan.defaultOnStartup` was ignored and recommending `--plan-yolo` when that headless plan flow was already active ([#8312](https://github.com/can1357/oh-my-pi/issues/8312)).
## [17.2.15] - 2026-08-12
### Added
+1
View File
@@ -1787,6 +1787,7 @@ export async function runRootCommand(
initialMessage,
initialImages,
printThoughts: initialArgs.printThoughts,
planYolo: parsedArgs.planYolo,
});
if ($env.PI_TIMING) {
logger.printTimings();
@@ -27,6 +27,8 @@ export interface PrintModeOptions {
initialImages?: ImageContent[];
/** If true, include thinking blocks in text output */
printThoughts?: boolean;
/** Whether the caller explicitly started the headless plan flow. */
planYolo?: boolean;
}
/** Matches the longest built-in provider request deadline while bounding tool-loop stalls. */
@@ -87,7 +89,7 @@ export function printableEvent(event: AgentSessionEvent): unknown {
* Sends prompts to the agent and outputs the result.
*/
export async function runPrintMode(session: AgentSession, options: PrintModeOptions): Promise<void> {
const { mode, messages = [], initialMessage, initialImages, printThoughts } = options;
const { mode, messages = [], initialMessage, initialImages, printThoughts, planYolo = false } = options;
// process.stdout.write is fire-and-forget: a large final record (e.g. a
// multi-MB agent_end) can be dropped when the process exits before the pipe
@@ -138,7 +140,8 @@ export async function runPrintMode(session: AgentSession, options: PrintModeOpti
session.settings.get("plan.defaultOnStartup") &&
session.settings.get("plan.enabled") &&
session.sessionManager.buildSessionContext().messages.length === 0 &&
!session.sessionManager.getEntries().some(entry => entry.type === "mode_change");
!session.sessionManager.getEntries().some(entry => entry.type === "mode_change") &&
!planYolo;
if (planStartupIgnored) {
process.stderr.write(
"Note: plan.defaultOnStartup is ignored in print mode (no interactive surface to review the plan). Use --plan-yolo for a headless plan flow.\n",
@@ -198,6 +198,23 @@ describe("print mode working indicator", () => {
expect(stdoutOutput.join("")).toBe("final answer\n");
});
it("suppresses the startup-default note when the headless plan flow is already active", async () => {
const delayed = createDelayedSession(makeAssistantMessage("final answer"), { defaultPlanMode: true });
const run = runPrintMode(delayed.session, {
mode: "text",
initialMessage: "Reply with exactly: OK",
planYolo: true,
});
await delayed.promptStarted;
try {
expect(stderrOutput.join("")).not.toContain("plan.defaultOnStartup");
} finally {
delayed.resolvePrompt();
await run;
}
});
it("writes a text-mode working indicator before the prompt resolves and prints the final answer afterward", async () => {
const delayed = createDelayedSession(makeAssistantMessage("final answer"));
const run = runPrintMode(delayed.session, { mode: "text", initialMessage: "hello" });