mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-11-15 10:59:32 +01:00
fix(auto-compact): send a multi-line focus prompt as one line
Auto-compact writes `/compact <prompt>\r` through writeViaMux when the token count crosses the threshold, unattended. AutoCompactSchema.prompt accepts line breaks, so a prompt set through the API can hold several lines. The mux used to strip them and run the lines together; it now pastes multi-line text as one block, and the check that re-presses a stranded Enter cannot recognise that paste in the composer. That is the case respawn's update and kickstart prompts were already joined for. The join moves out of respawn-controller into a shared toSingleLine() (src/utils/single-line.ts), used by both respawn steps and by auto-compact. Behaviour for respawn is unchanged. The respawn test file becomes test/unattended-single-line-prompt.test.ts and gains an auto-compact block that feeds a real Session a token count over its threshold and reads what reaches writeViaMux. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
3392a69290
commit
cf999c1296
6 files changed
+87
-31
No files matched your search
+10
-17
@@ -49,7 +49,13 @@ import { Session } from './session.js';
|
||||
import { AiIdleChecker, type AiCheckState } from './ai-idle-checker.js';
|
||||
import { AiPlanChecker } from './ai-plan-checker.js';
|
||||
import type { TeamWatcher } from './team-watcher.js';
|
||||
import { BufferAccumulator, ANSI_ESCAPE_PATTERN_SIMPLE, assertNever, CleanupManager } from './utils/index.js';
|
||||
import {
|
||||
BufferAccumulator,
|
||||
ANSI_ESCAPE_PATTERN_SIMPLE,
|
||||
assertNever,
|
||||
CleanupManager,
|
||||
toSingleLine,
|
||||
} from './utils/index.js';
|
||||
import { MAX_RESPAWN_BUFFER_SIZE, TRIM_RESPAWN_BUFFER_TO as RESPAWN_BUFFER_TRIM_SIZE } from './config/buffer-limits.js';
|
||||
import {
|
||||
isCompletionMessage,
|
||||
@@ -503,19 +509,6 @@ function formatRemainingSeconds(ms: number): number {
|
||||
return Math.max(0, Math.ceil(ms / 1000));
|
||||
}
|
||||
|
||||
/**
|
||||
* A respawn prompt as the one line it is sent as: every run of line breaks, with the
|
||||
* whitespace around it, becomes a single space; a single-line prompt is returned as
|
||||
* is. The config may hold several lines (the settings fields are textareas), but the
|
||||
* steps run unattended through `writeViaMux`, and the check that re-presses a stranded
|
||||
* Enter cannot recognise a multi-line paste in the composer. Cron rejects multi-line
|
||||
* prompts for the same reason; respawn joins them instead, so a saved multi-line
|
||||
* config is still sent rather than refused.
|
||||
*/
|
||||
export function singleLineRespawnPrompt(prompt: string): string {
|
||||
return prompt.replace(/\s*[\r\n]+\s*/g, ' ');
|
||||
}
|
||||
|
||||
/** Default configuration values */
|
||||
const DEFAULT_CONFIG: RespawnConfig = {
|
||||
idleTimeoutMs: 10000, // 10 seconds of no activity after prompt (legacy, still used as fallback)
|
||||
@@ -1634,7 +1627,7 @@ export class RespawnController extends EventEmitter {
|
||||
this.config.interStepDelayMs,
|
||||
async () => {
|
||||
if (this._state === 'stopped') return;
|
||||
const prompt = singleLineRespawnPrompt(this.config.kickstartPrompt!);
|
||||
const prompt = toSingleLine(this.config.kickstartPrompt!);
|
||||
this.logAction('command', `Sending kickstart: "${prompt.substring(0, 40)}..."`);
|
||||
await this.session.writeViaMux(prompt + '\r'); // \r triggers key.return in Ink/Claude CLI
|
||||
// COD-51: stop() may have run during the await; re-check before reviving the
|
||||
@@ -2839,11 +2832,11 @@ export class RespawnController extends EventEmitter {
|
||||
|
||||
// Use RALPH_STATUS RECOMMENDATION if available, otherwise fall back to config
|
||||
const statusBlock = this.session.ralphTracker?.lastStatusBlock;
|
||||
let updatePrompt = singleLineRespawnPrompt(this.config.updatePrompt);
|
||||
let updatePrompt = toSingleLine(this.config.updatePrompt);
|
||||
|
||||
if (statusBlock?.recommendation) {
|
||||
// Append RECOMMENDATION to the update prompt, on the same single line
|
||||
// (see singleLineRespawnPrompt)
|
||||
// (see toSingleLine)
|
||||
const rec = statusBlock.recommendation.replace(/\n/g, ' ').substring(0, 200);
|
||||
updatePrompt = `${updatePrompt} (Claude's last recommendation: ${rec})`;
|
||||
this.logAction('ralph', `Using RECOMMENDATION: ${rec.substring(0, 50)}...`);
|
||||
|
||||
Reference in new issue
Block a user