feat: user-customizable draft welcome starters
Let users curate the draft welcome chips: pin existing commands and skills as starters, remove them, and drag to reorder — all inline on the draft screen via a '+' picker dialog and per-chip remove, with no separate settings UI. A starter references a command or skill; its scope is inherited from the item (user-scope -> global, project-scope -> per-project). Global starters persist to settings.json (useUIStore + client/server sanitizers); project starters persist to the project config alongside worktree setup commands. The two scopes form ordered namespaces shown global-first then project, reorderable only within each group. The six built-in Session magic-prompt commands are the default global set and stay available in the picker for re-pinning if removed; they keep their bespoke icons, while user commands/skills fall back to the Commands/Skills section icons. Chip labels are normalized (/simplify-code -> 'Simplify code'). Missing commands/skills are skipped rather than shown broken. Drag-to-reorder works on desktop and mobile: rectSortingStrategy for the wrapping multi-row layout, CSS.Translate (no scale) so the lifted chip doesn't stretch, and MouseSensor + long-press TouchSensor so taps still submit and swipes still scroll. The '+' picker is a searchable dialog on every surface.
This commit is contained in:
@@ -145,6 +145,21 @@ export const createSettingsHelpers = (dependencies) => {
|
||||
.filter((entry) => typeof entry === 'string' && entry.length > 0)
|
||||
);
|
||||
}
|
||||
if (Array.isArray(candidate.draftStarters)) {
|
||||
const seenStarters = new Set();
|
||||
const starters = [];
|
||||
for (const entry of candidate.draftStarters) {
|
||||
if (!entry || typeof entry !== 'object') continue;
|
||||
const type = entry.type === 'command' || entry.type === 'skill' ? entry.type : null;
|
||||
const name = typeof entry.name === 'string' ? entry.name.trim() : '';
|
||||
if (!type || !name) continue;
|
||||
const key = `${type}:${name}`;
|
||||
if (seenStarters.has(key)) continue;
|
||||
seenStarters.add(key);
|
||||
starters.push({ type, name });
|
||||
}
|
||||
result.draftStarters = starters;
|
||||
}
|
||||
|
||||
|
||||
if (typeof candidate.uiFont === 'string' && candidate.uiFont.length > 0) {
|
||||
|
||||
Reference in New Issue
Block a user