Skip to content

fix: sync meta_json.title in updateSessionTitle so ZCode App shows it#16

Merged
william0wang merged 1 commit into
mainfrom
chore/fix-title
Jul 13, 2026
Merged

fix: sync meta_json.title in updateSessionTitle so ZCode App shows it#16
william0wang merged 1 commit into
mainfrom
chore/fix-title

Conversation

@william0wang

Copy link
Copy Markdown
Owner

No description provided.

@william0wang william0wang merged commit 04e7ac5 into main Jul 13, 2026
1 check passed
@william0wang william0wang deleted the chore/fix-title branch July 13, 2026 02:48

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates updateSessionTitle to synchronize the updated session title into the meta_json field, ensuring that the ZCode App (which prioritizes meta_json over the title column) displays the correct title. The corresponding tests and mocks are also updated. The reviewer identified a critical issue where unconditionally setting meta["title"] = trimmed when title_overridden === 1 would overwrite the user's custom title in meta_json with the auto-generated one. To fix this, the reviewer suggested selecting the title column as well and preserving the user-defined title in meta_json when an override is present, along with updating the test mocks to support this new query.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/tasks-index.ts
Comment on lines +191 to +209
const row = con
.prepare("SELECT title_overridden, meta_json FROM tasks WHERE task_id=?")
.get(taskId) as { title_overridden: number; meta_json: string } | undefined;
if (!row) return false;

// The ZCode App reads title from meta_json first (falling back to the
// title column only when meta_json fails to parse). If we update only the
// column, the App keeps showing the stale meta_json title (empty at create
// time). So we patch meta_json.title in both branches below.
let metaJson: string;
try {
const meta = JSON.parse(row.meta_json ?? "{}") as Record<string, unknown>;
meta["title"] = trimmed;
metaJson = JSON.stringify(meta);
} catch {
// meta_json corrupt/unparseable — the App will fall back to the title
// column anyway, so skip the meta_json write rather than guessing.
metaJson = row.meta_json ?? "{}";
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

If the user has already overridden the title (row.title_overridden === 1), unconditionally setting meta["title"] = trimmed (the auto-generated title) will overwrite the user's custom title in meta_json. Since the App reads the title from meta_json first, this will cause the App to display the auto-generated title instead of the user's overridden title, breaking the override behavior.

To fix this, we should select the title column as well, and if title_overridden === 1, preserve the existing user-defined title in meta_json.

Suggested change
const row = con
.prepare("SELECT title_overridden, meta_json FROM tasks WHERE task_id=?")
.get(taskId) as { title_overridden: number; meta_json: string } | undefined;
if (!row) return false;
// The ZCode App reads title from meta_json first (falling back to the
// title column only when meta_json fails to parse). If we update only the
// column, the App keeps showing the stale meta_json title (empty at create
// time). So we patch meta_json.title in both branches below.
let metaJson: string;
try {
const meta = JSON.parse(row.meta_json ?? "{}") as Record<string, unknown>;
meta["title"] = trimmed;
metaJson = JSON.stringify(meta);
} catch {
// meta_json corrupt/unparseable — the App will fall back to the title
// column anyway, so skip the meta_json write rather than guessing.
metaJson = row.meta_json ?? "{}";
}
const row = con
.prepare("SELECT title, title_overridden, meta_json FROM tasks WHERE task_id=?")
.get(taskId) as { title: string; title_overridden: number; meta_json: string | null } | undefined;
if (!row) return false;
// The ZCode App reads title from meta_json first (falling back to the
// title column only when meta_json fails to parse). If we update only the
// column, the App keeps showing the stale meta_json title (empty at create
// time). So we patch meta_json.title in both branches below.
let metaJson: string;
try {
const meta = JSON.parse(row.meta_json ?? "{}") as Record<string, unknown>;
meta["title"] = row.title_overridden === 1 ? row.title : trimmed;
metaJson = JSON.stringify(meta);
} catch {
// meta_json corrupt/unparseable — the App will fall back to the title
// column anyway, so skip the meta_json write rather than guessing.
metaJson = row.meta_json ?? "{}";
}

Comment thread tests/tasks-index.test.ts
Comment on lines +101 to 116
// SELECT title_overridden, meta_json FROM tasks WHERE task_id=?
if (/^SELECT title_overridden/i.test(sql)) {
return {
get(taskId: string) {
for (const r of rows.values()) {
if (r.task_id === taskId) {
return { title_overridden: r.title_overridden } as const;
return {
title_overridden: r.title_overridden,
meta_json: r.meta_json,
} as const;
}
}
return undefined;
},
};
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Update the mock statement to support the new SELECT title, title_overridden, meta_json query format and return the title property, ensuring that the unit tests continue to pass.

Suggested change
// SELECT title_overridden, meta_json FROM tasks WHERE task_id=?
if (/^SELECT title_overridden/i.test(sql)) {
return {
get(taskId: string) {
for (const r of rows.values()) {
if (r.task_id === taskId) {
return { title_overridden: r.title_overridden } as const;
return {
title_overridden: r.title_overridden,
meta_json: r.meta_json,
} as const;
}
}
return undefined;
},
};
}
// SELECT title, title_overridden, meta_json FROM tasks WHERE task_id=?
if (/^SELECT (title, )?title_overridden/i.test(sql)) {
return {
get(taskId: string) {
for (const r of rows.values()) {
if (r.task_id === taskId) {
return {
title: r.title,
title_overridden: r.title_overridden,
meta_json: r.meta_json,
} as const;
}
}
return undefined;
},
};
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant