agent-relay-runner 0.36.2 → 0.37.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/package.json
CHANGED
package/src/adapter.ts
CHANGED
|
@@ -157,6 +157,13 @@ export interface ProviderAdapter {
|
|
|
157
157
|
// `options.readyTimeoutMs` lets the runner widen the provider-ready wait for the
|
|
158
158
|
// first (cold-start) delivery vs. a fast re-attempt after a ready signal (#329).
|
|
159
159
|
deliverInitialPrompt?(process: ManagedProcess, prompt: string, options?: { readyTimeoutMs?: number }): Promise<void>;
|
|
160
|
+
// When true, the adapter seeds the spawn-time initial prompt as a launch argument
|
|
161
|
+
// (Claude's positional `claude "<prompt>"`), so it's already delivered the instant the
|
|
162
|
+
// session starts. The runner must then NOT also deliver it post-launch via
|
|
163
|
+
// deliverInitialPrompt — that would double-deliver and re-introduce the send-keys
|
|
164
|
+
// onboarding race (#352). deliverInitialPrompt stays available for mid-session injection
|
|
165
|
+
// (dashboard chat box) and ongoing message delivery, which have no launch-arg equivalent.
|
|
166
|
+
seedsInitialPromptAtLaunch?: boolean;
|
|
160
167
|
deliver(process: ManagedProcess, messages: Message[]): Promise<void>;
|
|
161
168
|
onStatusChange(cb: (status: ProviderStatusUpdate) => void): void;
|
|
162
169
|
// Subscribe to session-mirror events from providers that emit them directly
|
package/src/adapters/claude.ts
CHANGED
|
@@ -15,6 +15,9 @@ import { claudeProviderMessageText } from "./claude-delivery";
|
|
|
15
15
|
|
|
16
16
|
export class ClaudeAdapter implements ProviderAdapter {
|
|
17
17
|
readonly provider = "claude";
|
|
18
|
+
// #352: initial prompt is seeded as Claude's positional launch arg (buildSpawnArgs) — reliable,
|
|
19
|
+
// no send-keys/onboarding race; tells the runner to skip the redundant post-launch delivery.
|
|
20
|
+
readonly seedsInitialPromptAtLaunch = true;
|
|
18
21
|
private statusCb: (status: ProviderStatusUpdate) => void = () => {};
|
|
19
22
|
private tmuxWatcher?: Timer;
|
|
20
23
|
private turnWatcher?: Timer;
|
|
@@ -226,7 +229,11 @@ export class ClaudeAdapter implements ProviderAdapter {
|
|
|
226
229
|
...providerArgs,
|
|
227
230
|
];
|
|
228
231
|
if (config.model) args.push("--model", config.model);
|
|
229
|
-
|
|
232
|
+
// #352: seed the prompt as Claude's positional arg for ALL launches (headless included) —
|
|
233
|
+
// `claude "<prompt>"` seeds the first turn via Claude's own input handling, immune to the
|
|
234
|
+
// send-keys/onboarding race that silently dropped headless spawns. Long/special-char briefs
|
|
235
|
+
// are shell-safe (shellEscape + launcher-script externalization in buildTmuxArgs).
|
|
236
|
+
if (config.prompt) args.push(String(config.prompt));
|
|
230
237
|
return {
|
|
231
238
|
command,
|
|
232
239
|
args,
|
package/src/runner.ts
CHANGED
|
@@ -600,7 +600,13 @@ export class AgentRunner {
|
|
|
600
600
|
|
|
601
601
|
private async deliverInitialPrompt(): Promise<void> {
|
|
602
602
|
const prompt = this.options.prompt?.trim();
|
|
603
|
-
if (prompt)
|
|
603
|
+
if (!prompt) return;
|
|
604
|
+
// #352: adapters that seed the prompt as a launch arg (Claude's positional prompt) already
|
|
605
|
+
// delivered it at session start. Returning BEFORE attemptInitialPromptDelivery avoids a
|
|
606
|
+
// double-delivery AND leaves pendingInitialPrompt unset, so the #329 ready-signal retry never
|
|
607
|
+
// arms — one prompt, one turn. Mid-session injectPrompt + message delivery are unaffected.
|
|
608
|
+
if (this.options.adapter.seedsInitialPromptAtLaunch) return;
|
|
609
|
+
await this.attemptInitialPromptDelivery(prompt, INITIAL_PROMPT_FIRST_READY_TIMEOUT_MS);
|
|
604
610
|
}
|
|
605
611
|
|
|
606
612
|
// Deliver the spawn-time first prompt, surviving a cold-start TUI that isn't input-ready yet
|