Bug: Phone/daemon-spawned sessions skip --append-system-prompt, losing auto-title behavior and shared skills
Summary
Sessions launched from the mobile app's "+ New Session" button (which invokes happy claude --happy-starting-mode remote --started-by daemon) receive a different, drastically smaller appendSystemPrompt than sessions launched from the terminal (happy claude, happy yolo).
The phone/daemon-spawn path only attaches a # Options helper block. The terminal-spawn path attaches a full prompt that includes the mcp__happy__change_title instruction plus all configured shared skills (Brainstorming, TDD, Git Checkpoint, etc.).
User-visible result: phone-initiated new sessions never auto-title, because the model is never told to call mcp__happy__change_title. Terminal-initiated sessions still auto-title correctly. Resumed sessions also still have titles because they inherit the original prompt.
Environment
- Happy CLI: 1.1.8
- Claude Code: 2.1.177 (native installer)
- Node: v22.22.3
- OS: Linux (Ubuntu, kernel 6.17)
- Daemon mode:
start-sync, healthy, port assigned dynamically
- Machine ID: redacted
Expected behavior
A new session created from the phone app's "+ New Session" button should receive the same --append-system-prompt value as a terminal-launched session — including the title-instruction prompt and any configured shared skills. The model should then proactively call mcp__happy__change_title on its first response and the chat title in the app should update from "new chat" to something descriptive.
Actual behavior
Phone-spawned sessions receive only the # Options helper block in appendSystemPrompt. The title-instruction and shared skills are missing. The chat title stays at "new chat" indefinitely.
Reproduction
- Tap + New Session in the mobile app, targeting a machine running Happy CLI 1.1.8 in daemon mode.
- Send any user message into the new session.
- Observe: title in the session list stays "new chat"; the model does not call
mcp__happy__change_title.
- For contrast, run
happy claude (or happy yolo) directly in a terminal on the same machine — the resulting session does get auto-titled correctly.
Log evidence
Two sessions from the same machine, same Happy CLI version, same morning:
Session A — terminal-launched happy yolo (PID 69182, 07:01:07) — works correctly
[07:01:04.253] Starting happy CLI with args: [ '/usr/bin/node',
'.../happy/dist/index.mjs', 'yolo' ]
...
[07:01:07.144] [ClaudeLocal] Args: [
"--append-system-prompt",
"ALWAYS when you start a new chat - you must call a tool
\"mcp__happy__change_title\" to set a chat title. When you think chat
title is not relevant anymore - call the tool again to change it...
[... + commit-message coauthor block + all shared skills:
Brainstorming, Caveman Mode, Git Checkpoint, Grill With Docs,
Test-Driven Development ...]",
"--mcp-config", "{\"mcpServers\":{\"happy\":{...}}}",
"--allowedTools", "mcp__happy__change_title",
"yolo",
"--settings", ".../session-hook-69182.json"
]
Session B — phone "+ New Session", daemon-spawned (PID 977249, 09:24:04) — title-instruction MISSING
[09:24:04.253] Starting happy CLI with args: [
'/usr/bin/node',
'.../happy/dist/index.mjs',
'claude',
'--happy-starting-mode', 'remote',
'--started-by', 'daemon',
'--permission-mode', 'bypassPermissions'
]
[09:24:04.281] [START] Options: startedBy=daemon, startingMode=remote
...
(No `[ClaudeLocal] Args` line ever logged.)
...
"appendSystemPrompt": "# Options\n\nYou have a way to give a user a easy
way to answer your questions if you know possible an... [truncated]"
grep "append" Session-B.log returns only 5 hits, all to the same truncated # Options block. There is no change_title string anywhere in Session B's launcher log.
grep "change_title" Session-A.log → 1 hit (in --append-system-prompt).
grep "change_title" Session-B.log → 0 hits.
Impact
- Loss of one of Happy's most useful UX features (auto-titling) on the most common new-session path (the phone button).
- Phone-initiated sessions silently lose access to all configured shared skills (
/brainstorming, /caveman, /git-checkpoint, /grill-with-docs, /tdd, etc.), making them feel less capable than terminal-initiated sessions.
- The user-visible symptom ("titles aren't changing anymore") gives no hint that the underlying cause is a much broader system-prompt divergence.
Suspected fix
The launch path branched on --started-by daemon / --happy-starting-mode remote should attach the same appendSystemPrompt payload as the terminal-launched path. Specifically, the routine in dist/index.mjs (or the chunk dist/index-q9G4ktSK.mjs / dist/index-JEiJokCS.cjs, which is where the title prompt + skills are concatenated) should be invoked for both launch flavors before spawning the claude binary.
Files referenced (from logs)
- Working:
~/.happy/logs/2026-06-14-07-01-03-pid-69182.log
- Broken:
~/.happy/logs/2026-06-14-09-24-03-pid-977249.log
- Launcher:
~/.npm-global/lib/node_modules/happy/scripts/claude_local_launcher.cjs
- Prompt-bearing chunk:
~/.npm-global/lib/node_modules/happy/dist/index-q9G4ktSK.mjs (contains the literal ALWAYS when you start a new chat string)
Workaround
Launch new sessions from the machine's terminal (happy claude or happy yolo) instead of the phone "+ New Session" button. The session then appears in the phone list and can be driven from the app with full auto-titling and shared-skill access.
Bug: Phone/daemon-spawned sessions skip
--append-system-prompt, losing auto-title behavior and shared skillsSummary
Sessions launched from the mobile app's "+ New Session" button (which invokes
happy claude --happy-starting-mode remote --started-by daemon) receive a different, drastically smallerappendSystemPromptthan sessions launched from the terminal (happy claude,happy yolo).The phone/daemon-spawn path only attaches a
# Optionshelper block. The terminal-spawn path attaches a full prompt that includes themcp__happy__change_titleinstruction plus all configured shared skills (Brainstorming, TDD, Git Checkpoint, etc.).User-visible result: phone-initiated new sessions never auto-title, because the model is never told to call
mcp__happy__change_title. Terminal-initiated sessions still auto-title correctly. Resumed sessions also still have titles because they inherit the original prompt.Environment
start-sync, healthy, port assigned dynamicallyExpected behavior
A new session created from the phone app's "+ New Session" button should receive the same
--append-system-promptvalue as a terminal-launched session — including the title-instruction prompt and any configured shared skills. The model should then proactively callmcp__happy__change_titleon its first response and the chat title in the app should update from "new chat" to something descriptive.Actual behavior
Phone-spawned sessions receive only the
# Optionshelper block inappendSystemPrompt. The title-instruction and shared skills are missing. The chat title stays at "new chat" indefinitely.Reproduction
mcp__happy__change_title.happy claude(orhappy yolo) directly in a terminal on the same machine — the resulting session does get auto-titled correctly.Log evidence
Two sessions from the same machine, same Happy CLI version, same morning:
Session A — terminal-launched
happy yolo(PID 69182, 07:01:07) — works correctlySession B — phone "+ New Session", daemon-spawned (PID 977249, 09:24:04) — title-instruction MISSING
grep "append" Session-B.logreturns only 5 hits, all to the same truncated# Optionsblock. There is nochange_titlestring anywhere in Session B's launcher log.grep "change_title" Session-A.log→ 1 hit (in--append-system-prompt).grep "change_title" Session-B.log→ 0 hits.Impact
/brainstorming,/caveman,/git-checkpoint,/grill-with-docs,/tdd, etc.), making them feel less capable than terminal-initiated sessions.Suspected fix
The launch path branched on
--started-by daemon/--happy-starting-mode remoteshould attach the sameappendSystemPromptpayload as the terminal-launched path. Specifically, the routine indist/index.mjs(or the chunkdist/index-q9G4ktSK.mjs/dist/index-JEiJokCS.cjs, which is where the title prompt + skills are concatenated) should be invoked for both launch flavors before spawning theclaudebinary.Files referenced (from logs)
~/.happy/logs/2026-06-14-07-01-03-pid-69182.log~/.happy/logs/2026-06-14-09-24-03-pid-977249.log~/.npm-global/lib/node_modules/happy/scripts/claude_local_launcher.cjs~/.npm-global/lib/node_modules/happy/dist/index-q9G4ktSK.mjs(contains the literalALWAYS when you start a new chatstring)Workaround
Launch new sessions from the machine's terminal (
happy claudeorhappy yolo) instead of the phone "+ New Session" button. The session then appears in the phone list and can be driven from the app with full auto-titling and shared-skill access.