From 4f1db10704cbe724e236f34818ca4a3ec95b1f0f Mon Sep 17 00:00:00 2001
From: Kian Jones <11655409+kianjones9@users.noreply.github.com>
Date: Thu, 19 Mar 2026 16:31:59 -0700
Subject: [PATCH] feat(new): accept optional conversation name argument and
polish `/resume` results (#1451)
---
src/cli/App.tsx | 19 +++++++++++++--
src/cli/components/ConversationSelector.tsx | 24 +++++++------------
.../agent/model-preset-refresh.wiring.test.ts | 5 ++--
.../bootstrap-reminders-reset-wiring.test.ts | 2 +-
4 files changed, 29 insertions(+), 21 deletions(-)
diff --git a/src/cli/App.tsx b/src/cli/App.tsx
index ca49d3e..23f0776 100644
--- a/src/cli/App.tsx
+++ b/src/cli/App.tsx
@@ -8130,10 +8130,14 @@ export default function App({
}
// Special handling for /new command - start new conversation
- if (msg.trim() === "/new") {
+ const newMatch = msg.trim().match(/^\/new(?:\s+(.+))?$/);
+ if (newMatch) {
+ const conversationName = newMatch[1]?.trim();
const cmd = commandRunner.start(
msg.trim(),
- "Starting new conversation...",
+ conversationName
+ ? `Starting new conversation: ${conversationName}...`
+ : "Starting new conversation...",
);
// New conversations should not inherit pending reasoning-tier debounce.
@@ -8150,8 +8154,14 @@ export default function App({
const conversation = await client.conversations.create({
agent_id: agentId,
isolated_block_labels: [...ISOLATED_BLOCK_LABELS],
+ ...(conversationName && { summary: conversationName }),
});
+ // If we created the conversation with an explicit summary, mark it as set
+ // to prevent auto-summary from first user message overwriting it
+ if (conversationName) {
+ hasSetConversationSummaryRef.current = true;
+ }
await maybeCarryOverActiveConversationModel(conversation.id);
// Update conversationId state
@@ -13939,6 +13949,11 @@ If using apply_patch, use this exact relative patch path: ${applyPatchRelativePa
messageHistory: resumeData.messageHistory,
};
+ // If the conversation already has a summary, prevent auto-summary from overwriting it
+ if (selectorContext?.summary) {
+ hasSetConversationSummaryRef.current = true;
+ }
+
settingsManager.setLocalLastSession(
{ agentId, conversationId: convId },
process.cwd(),
diff --git a/src/cli/components/ConversationSelector.tsx b/src/cli/components/ConversationSelector.tsx
index 6a5fab7..3f92e1e 100644
--- a/src/cli/components/ConversationSelector.tsx
+++ b/src/cli/components/ConversationSelector.tsx
@@ -441,20 +441,6 @@ export function ConversationSelector({
const bracket = {"⎿ "};
const indent = " "; // Same width as "⎿ " for alignment
- // Priority 1: Summary
- if (conv.summary) {
- return (
-
- {bracket}
-
- {conv.summary.length > 57
- ? `${conv.summary.slice(0, 54)}...`
- : conv.summary}
-
-
- );
- }
-
// Priority 2: Preview lines with emoji prefixes
if (previewLines.length > 0) {
return (
@@ -516,9 +502,15 @@ export function ConversationSelector({
bold={isSelected}
color={isSelected ? colors.selector.itemHighlighted : undefined}
>
- {isDefault ? "default" : conv.id}
+ {conv.summary
+ ? `${conv.summary.length > 40 ? `${conv.summary.slice(0, 37)}...` : conv.summary} (${conv.id})`
+ : isDefault
+ ? "default"
+ : conv.id}
- {isDefault && (agent's default conversation)}
+ {!conv.summary && isDefault && (
+ (agent's default conversation)
+ )}
{isCurrent && (
(current)
)}
diff --git a/src/tests/agent/model-preset-refresh.wiring.test.ts b/src/tests/agent/model-preset-refresh.wiring.test.ts
index 6d5d011..58c4459 100644
--- a/src/tests/agent/model-preset-refresh.wiring.test.ts
+++ b/src/tests/agent/model-preset-refresh.wiring.test.ts
@@ -153,8 +153,9 @@ describe("model preset refresh wiring", () => {
) ?? [];
expect(carryOverCalls.length).toBeGreaterThanOrEqual(3);
- const newCmdAnchor = source.indexOf('if (msg.trim() === "/new")');
- expect(newCmdAnchor).toBeGreaterThanOrEqual(0);
+ const newCmdAnchor = source.indexOf(
+ "const newMatch = msg.trim().match(/^\\/new(?:\\s+(.+))?$/);",
+ );
const newCmdWindow = source.slice(newCmdAnchor, newCmdAnchor + 1800);
expect(newCmdWindow).toContain(
"await maybeCarryOverActiveConversationModel(conversation.id);",
diff --git a/src/tests/cli/bootstrap-reminders-reset-wiring.test.ts b/src/tests/cli/bootstrap-reminders-reset-wiring.test.ts
index 3f79bdd..2f8ef3c 100644
--- a/src/tests/cli/bootstrap-reminders-reset-wiring.test.ts
+++ b/src/tests/cli/bootstrap-reminders-reset-wiring.test.ts
@@ -29,7 +29,7 @@ describe("bootstrap reminder reset wiring", () => {
const anchors = [
'origin: "agent-switch"',
'const inputCmd = "/new";', // new-agent creation flow
- 'if (msg.trim() === "/new")',
+ "const newMatch = msg.trim().match(/^\\/new(?:\\s+(.+))?$/);",
'if (msg.trim() === "/clear")',
'origin: "resume-direct"',
'if (action.type === "switch_conversation")', // queued conversation switch flow