feat(cli): add global option to disable automatic session title changes#504
feat(cli): add global option to disable automatic session title changes#504chenbojian wants to merge 4 commits intotiann:mainfrom
Conversation
Add `enableAutoTitle` setting in `~/.hapi/settings.json` that controls whether the agent automatically renames chat sessions via the `change_title` MCP tool. When set to `false`, the title instruction is omitted from system prompts and the tool is not registered. Closes tiann#271
There was a problem hiding this comment.
Review mode: initial
Findings
- [Major]
enableAutoTitle=falsedoes not fully disable automatic title changes outside Claude. The new guard removes the HTTP-side tool incli/src/claude/utils/startHappyServer.ts:45, but Codex/OpenCode still launch the shared stdio bridge, and that bridge still unconditionally advertiseschange_titleincli/src/codex/happyMcpStdioBridge.ts:72. That leaves the tool visible and callable in the non-Claude modes this PR claims to cover.
Summary
enableAutoTitle=falsecurrently suppresses prompt text, but not end-to-end tool exposure for Codex/OpenCode.- Not found in tests: coverage for the MCP bridge/tool advertisement path when
enableAutoTitleisfalse.
Testing
- Not run (automation)
HAPI Bot
| }; | ||
| } | ||
| }); | ||
| if (shouldEnableAutoTitle()) { |
There was a problem hiding this comment.
[MAJOR] enableAutoTitle=false only removes the tool from the HTTP MCP server here. Codex and OpenCode still go through buildHapiMcpBridge(...), and cli/src/codex/happyMcpStdioBridge.ts:72 still unconditionally re-registers change_title, so those modes can still see and call the title tool.
Suggested fix:
const client = await ensureHttpClient();
const { tools } = await client.listTools();
if (tools.some((tool) => tool.name === 'change_title')) {
server.registerTool<any, any>('change_title', {
description: 'Change the title of the current chat session',
title: 'Change Chat Title',
inputSchema: changeTitleInputSchema,
}, async (args: Record<string, unknown>) => {
return client.callTool({ name: 'change_title', arguments: args });
});
}…false The STDIO MCP bridge unconditionally registered the change_title tool, leaving it visible in Codex/OpenCode even when enableAutoTitle was false.
There was a problem hiding this comment.
Findings
- No actionable findings in the updated diff.
Summary
- Review mode: follow-up after new commits
- No new diff-attributable correctness, security, or maintainability issues found.
- Residual risk: not found in repo/docs/tests, targeted coverage for
enableAutoTitle=falsethrough the non-Claude launch paths touched here, especiallycli/src/codex/happyMcpStdioBridge.ts:68,cli/src/opencode/opencodeLocalLauncher.ts:274, andcli/src/opencode/opencodeRemoteLauncher.ts:120.
Testing
- Not run (automation)
HAPI Bot
There was a problem hiding this comment.
Findings
- [Major] Disabling auto title still clears Codex developer instructions —
cli/src/codex/utils/systemPrompt.ts:11now represents the disabled state as'', but the existing Codex launch/config paths still pass that value as an explicit override (cli/src/codex/codexLocal.ts:74,cli/src/codex/utils/appServerConfig.ts:86). For a user who setsenableAutoTitle=false, HAPI will senddeveloper_instructions=""instead of omitting only the HAPI title prompt, which can wipe their Codex-level developer instructions/config for the session.
Suggested fix:// cli/src/codex/codexLocal.ts if (codexSystemPrompt) { args.push(...buildDeveloperInstructionsArg(codexSystemPrompt)); } // cli/src/codex/utils/appServerConfig.ts const developerInstructions = [baseInstructions, args.developerInstructions] .filter(Boolean) .join('\n\n'); const configWithInstructions = { ...config, ...(developerInstructions ? { developer_instructions: developerInstructions } : {}), ...(args.mode.modelReasoningEffort ? { model_reasoning_effort: args.mode.modelReasoningEffort } : {}) };
Summary
- Review mode: follow-up after new commits
- One correctness regression found in the Codex disabled-auto-title path.
- Residual risk: no end-to-end coverage found for
enableAutoTitle=falseacross Codex/OpenCode launchers.
Testing
- Not run (automation:
bun/bunxnot found in PATH)
HAPI Bot
| If the task focus changes significantly later, call the title tool again with a better title. | ||
| `); | ||
| `) | ||
| : ''; |
There was a problem hiding this comment.
[MAJOR] When enableAutoTitle=false, this exports an empty string, but the Codex launch/config paths still send that as an explicit developer_instructions="" override (codexLocal.ts:74, appServerConfig.ts:86). That disables more than the HAPI title prompt: it can clear a user's Codex developer instructions/config for the session. Omit the override when the HAPI prompt is empty.
Suggested fix:
// cli/src/codex/codexLocal.ts
if (codexSystemPrompt) {
args.push(...buildDeveloperInstructionsArg(codexSystemPrompt));
}
// cli/src/codex/utils/appServerConfig.ts
const developerInstructions = [baseInstructions, args.developerInstructions]
.filter(Boolean)
.join('\n\n');
const configWithInstructions = {
...config,
...(developerInstructions ? { developer_instructions: developerInstructions } : {}),
...(args.mode.modelReasoningEffort ? { model_reasoning_effort: args.mode.modelReasoningEffort } : {})
};
Summary
enableAutoTitlesetting in~/.hapi/settings.json(defaults totrue)false, the title instruction is omitted from system prompts (Claude, Codex, OpenCode) and thechange_titleMCP tool is not registeredSupport part of #271
Test plan
"enableAutoTitle": falsein~/.hapi/settings.json→ start a session → verify no title-change tool calls and no title instruction in prompttrue→ verify behavior unchangedbun run typecheckincli/— passesbunx vitest run src/claude/utils/claudeSettings.test.ts— all 11 tests pass