diff --git a/.changeset/fit-card-descriptions.md b/.changeset/fit-card-descriptions.md new file mode 100644 index 00000000..e1bf19e9 --- /dev/null +++ b/.changeset/fit-card-descriptions.md @@ -0,0 +1,5 @@ +--- +"@inkeep/open-knowledge": patch +--- + +Stop starter-pack and other card descriptions from overflowing their cards. The "Codebase wiki" starter pack and the slash-command MirrorSource / Mirror block previews had descriptions long enough to wrap to many lines and stretch their cards; those are now concise. The description text on the starter-pack picker, the slash-command block preview, the Navigator project-launcher cards, and the share-receive dialog is now line-clamped, so any long description truncates cleanly instead of distorting the layout. diff --git a/packages/app/src/components/NavigatorApp.tsx b/packages/app/src/components/NavigatorApp.tsx index d1625713..40376673 100644 --- a/packages/app/src/components/NavigatorApp.tsx +++ b/packages/app/src/components/NavigatorApp.tsx @@ -356,7 +356,7 @@ function NavigatorCard({ title, description, onClick, dataTestId, Icon }: Naviga {Icon ? : null} {title} - {description} + {description} ); } diff --git a/packages/app/src/components/PackCardGrid.tsx b/packages/app/src/components/PackCardGrid.tsx index 91230072..064afc42 100644 --- a/packages/app/src/components/PackCardGrid.tsx +++ b/packages/app/src/components/PackCardGrid.tsx @@ -161,7 +161,9 @@ function PackCard({ pack, onSelect }: PackCardProps) {

{pack.name}

-

{pack.description}

+

+ {pack.description} +

); diff --git a/packages/app/src/components/ShareReceiveDialog.tsx b/packages/app/src/components/ShareReceiveDialog.tsx index 33ba89eb..4329f475 100644 --- a/packages/app/src/components/ShareReceiveDialog.tsx +++ b/packages/app/src/components/ShareReceiveDialog.tsx @@ -497,8 +497,6 @@ function ShareReceiveDialogInner({ const cloneEnabled = cloneController !== undefined && !cloneRunning; const cloneLabel = cloneRunning ? t`Cloning...` : t`Clone to a new folder`; - const shareOwner = share.owner; - const shareRepo = share.repo; const lookingForUrl = canonicalGitHubRemoteUrl(expected); const signedInLogin = authStatus?.authenticated ? authStatus.login : undefined; const cloneErrorMessage = cloneError?.detail ? formatCloneErrorMessage(cloneError.detail) : ''; @@ -605,10 +603,8 @@ function ShareReceiveDialogInner({ aria-disabled={cloneController !== undefined && !cloneEnabled} > {cloneLabel} - - - Downloads {shareOwner}/{shareRepo} from GitHub. - + + Downloads a fresh copy from GitHub. diff --git a/packages/app/src/editor/slash-command/SlashCommandMenu.tsx b/packages/app/src/editor/slash-command/SlashCommandMenu.tsx index 2efb5504..1a8af788 100644 --- a/packages/app/src/editor/slash-command/SlashCommandMenu.tsx +++ b/packages/app/src/editor/slash-command/SlashCommandMenu.tsx @@ -146,7 +146,7 @@ export function SlashCommandMenu({
{selectedItem.preview.render()}
-

+

{selectedItem.preview.description}

diff --git a/packages/app/src/editor/slash-command/component-items.test.ts b/packages/app/src/editor/slash-command/component-items.test.ts index 25bd0963..8945dbf6 100644 --- a/packages/app/src/editor/slash-command/component-items.test.ts +++ b/packages/app/src/editor/slash-command/component-items.test.ts @@ -65,6 +65,18 @@ describe('getComponentItems (slash menu)', () => { expect(items.some((i) => i.name === `component-${compatName}`)).toBe(false); } }); + + test('every component preview description fits the slash aside 3-line budget (<= 120 chars)', () => { + const MAX_PREVIEW_DESCRIPTION_LENGTH = 120; + const descriptions = getComponentItems() + .map((i) => i.preview?.description) + .filter((d): d is string => typeof d === 'string'); + expect(descriptions.length).toBeGreaterThan(0); + const tooLong = descriptions + .filter((d) => d.length > MAX_PREVIEW_DESCRIPTION_LENGTH) + .map((d) => `${d.length} chars: ${d.slice(0, 50)}`); + expect(tooLong).toEqual([]); + }); }); describe('createChildNode — default props on slash insert', () => { diff --git a/packages/app/src/editor/slash-command/component-items.tsx b/packages/app/src/editor/slash-command/component-items.tsx index f30125b7..37307f3e 100644 --- a/packages/app/src/editor/slash-command/component-items.tsx +++ b/packages/app/src/editor/slash-command/component-items.tsx @@ -220,7 +220,7 @@ const PREVIEW_CONFIG: Record = { ), }, Mirror: { - description: msg`Read-only copy of a MirrorSource block from another doc. Edit at the source — every Mirror reflects the change live.`, + description: msg`Read-only copy of a MirrorSource block from another doc. Edit at the source and it updates live.`, render: () => (
@@ -242,7 +242,7 @@ const PREVIEW_CONFIG: Record = { ), }, MirrorSource: { - description: msg`Mark a block as the source of truth. Mirror references elsewhere render this content read-only and update live as you edit here.`, + description: msg`Mark a block as the source of truth. Mirrors elsewhere update live as you edit it.`, render: () => (
diff --git a/packages/app/src/locales/en/messages.json b/packages/app/src/locales/en/messages.json index 07c7e58f..51758f92 100644 --- a/packages/app/src/locales/en/messages.json +++ b/packages/app/src/locales/en/messages.json @@ -10,9 +10,6 @@ "-3ois8": ["Hard break"], "-8PP0T": ["Match case"], "-K0AvT": ["Disconnect"], - "-KCZ6n": [ - "Mark a block as the source of truth. Mirror references elsewhere render this content read-only and update live as you edit here." - ], "-LHLx7": ["edited template"], "-QCLWk": ["Templates available"], "-Qw-1t": ["GitHub authentication failed. Try signing in again."], @@ -348,9 +345,6 @@ "8PmoQF": ["Open the insert menu in an empty or active text position."], "8RtNI0": ["Failed to load documents"], "8S1E33": ["Search recent projects..."], - "8TLE9g": [ - "Read-only copy of a MirrorSource block from another doc. Edit at the source — every Mirror reflects the change live." - ], "8XQRON": ["Loading repositories"], "8_brI5": ["Name is required"], "8cS0nH": ["Config sharing unavailable: ", ["0"], "."], @@ -1274,6 +1268,9 @@ "_TF8ep": ["Failed to render PDF"], "_VRtd7": ["Couldn't send the selection — please try again."], "_W-elG": ["(inline)"], + "_WPP7e": [ + "Read-only copy of a MirrorSource block from another doc. Edit at the source and it updates live." + ], "_XWY2J": ["Terminal disabled"], "_bth6g": ["Claude Code is installed, but OpenKnowledge tools aren't connected to it yet."], "_eguJc": ["Uploading"], @@ -1415,6 +1412,9 @@ "el312q": ["Install skills into"], "emgiet": ["Authoritative content; mirrored verbatim everywhere it's referenced."], "eneWvv": ["Draft"], + "epuNYK": [ + "Mark a block as the source of truth. Mirrors elsewhere update live as you edit it." + ], "euc6Ns": ["Duplicate"], "evs0iw": ["Tags matching \"", ["tagListQuery"], "\""], "f1XQyZ": ["Move block"], @@ -1437,6 +1437,7 @@ "fbsiBw": ["Something went wrong starting the terminal."], "fcgvCA": ["Claude"], "fiMNLl": ["Sync settings not yet loaded — try again in a moment"], + "fj5YiP": ["Downloads a fresh copy from GitHub."], "fo0VXg": ["Uninstall"], "fqSfXY": ["Replace"], "fwhX-N": ["Indent or outdent source"], @@ -1555,7 +1556,6 @@ "jBVUXo": ["Couldn't open the terminal — please try again."], "jEZ6Lf": ["provisional"], "jEdF24": ["Missing page: ", ["linkTitle"], ". Click to create."], - "jGJy-9": ["Downloads ", ["shareOwner"], "/", ["shareRepo"], " from GitHub."], "jKd3AP": ["Could not enable the terminal: ", ["0"]], "jPUPvG": ["Couldn't resolve the conflict for ", ["filePath"], "."], "jRHdCz": ["Failed to load PDF"], diff --git a/packages/app/src/locales/en/messages.po b/packages/app/src/locales/en/messages.po index f0a213a0..1a2f8135 100644 --- a/packages/app/src/locales/en/messages.po +++ b/packages/app/src/locales/en/messages.po @@ -2169,8 +2169,8 @@ msgid "Download started" msgstr "Download started" #: src/components/ShareReceiveDialog.tsx -msgid "Downloads {shareOwner}/{shareRepo} from GitHub." -msgstr "Downloads {shareOwner}/{shareRepo} from GitHub." +msgid "Downloads a fresh copy from GitHub." +msgstr "Downloads a fresh copy from GitHub." #: src/components/SkillEditorActions.tsx #: src/components/SkillStateBadge.tsx @@ -3572,8 +3572,8 @@ msgid "Map the architecture" msgstr "Map the architecture" #: src/editor/slash-command/component-items.tsx -msgid "Mark a block as the source of truth. Mirror references elsewhere render this content read-only and update live as you edit here." -msgstr "Mark a block as the source of truth. Mirror references elsewhere render this content read-only and update live as you edit here." +msgid "Mark a block as the source of truth. Mirrors elsewhere update live as you edit it." +msgstr "Mark a block as the source of truth. Mirrors elsewhere update live as you edit it." #: src/components/EditorModeToggle.tsx msgid "Markdown" @@ -4837,8 +4837,8 @@ msgid "Read through this codebase and draft a technical spec for the most comple msgstr "Read through this codebase and draft a technical spec for the most complex module: an overview, the architecture, key files, and open questions, all linked from a specs index page." #: src/editor/slash-command/component-items.tsx -msgid "Read-only copy of a MirrorSource block from another doc. Edit at the source — every Mirror reflects the change live." -msgstr "Read-only copy of a MirrorSource block from another doc. Edit at the source — every Mirror reflects the change live." +msgid "Read-only copy of a MirrorSource block from another doc. Edit at the source and it updates live." +msgstr "Read-only copy of a MirrorSource block from another doc. Edit at the source and it updates live." #: src/components/TrashFailureModal.tsx msgid "Reason: {reason}" diff --git a/packages/app/src/locales/pseudo/messages.json b/packages/app/src/locales/pseudo/messages.json index f3e59392..9539593b 100644 --- a/packages/app/src/locales/pseudo/messages.json +++ b/packages/app/src/locales/pseudo/messages.json @@ -10,9 +10,6 @@ "-3ois8": ["Ĥàŕď ƀŕēàķ"], "-8PP0T": ["Ḿàţćĥ ćàśē"], "-K0AvT": ["Ďĩśćōńńēćţ"], - "-KCZ6n": [ - "Ḿàŕķ à ƀĺōćķ àś ţĥē śōũŕćē ōƒ ţŕũţĥ. Ḿĩŕŕōŕ ŕēƒēŕēńćēś ēĺśēŵĥēŕē ŕēńďēŕ ţĥĩś ćōńţēńţ ŕēàď-ōńĺŷ àńď ũƥďàţē ĺĩvē àś ŷōũ ēďĩţ ĥēŕē." - ], "-LHLx7": ["ēďĩţēď ţēḿƥĺàţē"], "-QCLWk": ["Ţēḿƥĺàţēś àvàĩĺàƀĺē"], "-Qw-1t": ["ĜĩţĤũƀ àũţĥēńţĩćàţĩōń ƒàĩĺēď. Ţŕŷ śĩĝńĩńĝ ĩń àĝàĩń."], @@ -348,9 +345,6 @@ "8PmoQF": ["Ōƥēń ţĥē ĩńśēŕţ ḿēńũ ĩń àń ēḿƥţŷ ōŕ àćţĩvē ţēxţ ƥōśĩţĩōń."], "8RtNI0": ["Ƒàĩĺēď ţō ĺōàď ďōćũḿēńţś"], "8S1E33": ["Śēàŕćĥ ŕēćēńţ ƥŕōĴēćţś..."], - "8TLE9g": [ - "Ŕēàď-ōńĺŷ ćōƥŷ ōƒ à ḾĩŕŕōŕŚōũŕćē ƀĺōćķ ƒŕōḿ àńōţĥēŕ ďōć. Ēďĩţ àţ ţĥē śōũŕćē — ēvēŕŷ Ḿĩŕŕōŕ ŕēƒĺēćţś ţĥē ćĥàńĝē ĺĩvē." - ], "8XQRON": ["Ĺōàďĩńĝ ŕēƥōśĩţōŕĩēś"], "8_brI5": ["Ńàḿē ĩś ŕēǫũĩŕēď"], "8cS0nH": ["Ćōńƒĩĝ śĥàŕĩńĝ ũńàvàĩĺàƀĺē: ", ["0"], "."], @@ -1274,6 +1268,9 @@ "_TF8ep": ["Ƒàĩĺēď ţō ŕēńďēŕ ƤĎƑ"], "_VRtd7": ["Ćōũĺďń'ţ śēńď ţĥē śēĺēćţĩōń — ƥĺēàśē ţŕŷ àĝàĩń."], "_W-elG": ["(ĩńĺĩńē)"], + "_WPP7e": [ + "Ŕēàď-ōńĺŷ ćōƥŷ ōƒ à ḾĩŕŕōŕŚōũŕćē ƀĺōćķ ƒŕōḿ àńōţĥēŕ ďōć. Ēďĩţ àţ ţĥē śōũŕćē àńď ĩţ ũƥďàţēś ĺĩvē." + ], "_XWY2J": ["Ţēŕḿĩńàĺ ďĩśàƀĺēď"], "_bth6g": ["Ćĺàũďē Ćōďē ĩś ĩńśţàĺĺēď, ƀũţ ŌƥēńĶńōŵĺēďĝē ţōōĺś àŕēń'ţ ćōńńēćţēď ţō ĩţ ŷēţ."], "_eguJc": ["Ũƥĺōàďĩńĝ"], @@ -1415,6 +1412,9 @@ "el312q": ["Ĩńśţàĺĺ śķĩĺĺś ĩńţō"], "emgiet": ["Àũţĥōŕĩţàţĩvē ćōńţēńţ; ḿĩŕŕōŕēď vēŕƀàţĩḿ ēvēŕŷŵĥēŕē ĩţ'ś ŕēƒēŕēńćēď."], "eneWvv": ["Ďŕàƒţ"], + "epuNYK": [ + "Ḿàŕķ à ƀĺōćķ àś ţĥē śōũŕćē ōƒ ţŕũţĥ. Ḿĩŕŕōŕś ēĺśēŵĥēŕē ũƥďàţē ĺĩvē àś ŷōũ ēďĩţ ĩţ." + ], "euc6Ns": ["Ďũƥĺĩćàţē"], "evs0iw": ["Ţàĝś ḿàţćĥĩńĝ \"", ["tagListQuery"], "\""], "f1XQyZ": ["Ḿōvē ƀĺōćķ"], @@ -1437,6 +1437,7 @@ "fbsiBw": ["Śōḿēţĥĩńĝ ŵēńţ ŵŕōńĝ śţàŕţĩńĝ ţĥē ţēŕḿĩńàĺ."], "fcgvCA": ["Ćĺàũďē"], "fiMNLl": ["Śŷńć śēţţĩńĝś ńōţ ŷēţ ĺōàďēď — ţŕŷ àĝàĩń ĩń à ḿōḿēńţ"], + "fj5YiP": ["Ďōŵńĺōàďś à ƒŕēśĥ ćōƥŷ ƒŕōḿ ĜĩţĤũƀ."], "fo0VXg": ["Ũńĩńśţàĺĺ"], "fqSfXY": ["Ŕēƥĺàćē"], "fwhX-N": ["Ĩńďēńţ ōŕ ōũţďēńţ śōũŕćē"], @@ -1555,7 +1556,6 @@ "jBVUXo": ["Ćōũĺďń'ţ ōƥēń ţĥē ţēŕḿĩńàĺ — ƥĺēàśē ţŕŷ àĝàĩń."], "jEZ6Lf": ["ƥŕōvĩśĩōńàĺ"], "jEdF24": ["Ḿĩśśĩńĝ ƥàĝē: ", ["linkTitle"], ". Ćĺĩćķ ţō ćŕēàţē."], - "jGJy-9": ["Ďōŵńĺōàďś ", ["shareOwner"], "/", ["shareRepo"], " ƒŕōḿ ĜĩţĤũƀ."], "jKd3AP": ["Ćōũĺď ńōţ ēńàƀĺē ţĥē ţēŕḿĩńàĺ: ", ["0"]], "jPUPvG": ["Ćōũĺďń'ţ ŕēśōĺvē ţĥē ćōńƒĺĩćţ ƒōŕ ", ["filePath"], "."], "jRHdCz": ["Ƒàĩĺēď ţō ĺōàď ƤĎƑ"], diff --git a/packages/app/src/locales/pseudo/messages.po b/packages/app/src/locales/pseudo/messages.po index 2a401405..16568788 100644 --- a/packages/app/src/locales/pseudo/messages.po +++ b/packages/app/src/locales/pseudo/messages.po @@ -2164,7 +2164,7 @@ msgid "Download started" msgstr "" #: src/components/ShareReceiveDialog.tsx -msgid "Downloads {shareOwner}/{shareRepo} from GitHub." +msgid "Downloads a fresh copy from GitHub." msgstr "" #: src/components/SkillEditorActions.tsx @@ -3567,7 +3567,7 @@ msgid "Map the architecture" msgstr "" #: src/editor/slash-command/component-items.tsx -msgid "Mark a block as the source of truth. Mirror references elsewhere render this content read-only and update live as you edit here." +msgid "Mark a block as the source of truth. Mirrors elsewhere update live as you edit it." msgstr "" #: src/components/EditorModeToggle.tsx @@ -4832,7 +4832,7 @@ msgid "Read through this codebase and draft a technical spec for the most comple msgstr "" #: src/editor/slash-command/component-items.tsx -msgid "Read-only copy of a MirrorSource block from another doc. Edit at the source — every Mirror reflects the change live." +msgid "Read-only copy of a MirrorSource block from another doc. Edit at the source and it updates live." msgstr "" #: src/components/TrashFailureModal.tsx diff --git a/packages/server/src/seed/starter.test.ts b/packages/server/src/seed/starter.test.ts index e46cca8f..842944d4 100644 --- a/packages/server/src/seed/starter.test.ts +++ b/packages/server/src/seed/starter.test.ts @@ -168,6 +168,14 @@ describe('STARTER_PACKS — all packs structural validation', () => { } }); + const MAX_PACK_DESCRIPTION_LENGTH = 64; + test(`every pack description fits the picker card's 2-line budget (<= ${MAX_PACK_DESCRIPTION_LENGTH} chars)`, () => { + const tooLong = Object.values(STARTER_PACKS) + .filter((pack) => pack.description.length > MAX_PACK_DESCRIPTION_LENGTH) + .map((pack) => `${pack.id} (${pack.description.length} chars)`); + expect(tooLong).toEqual([]); + }); + test('every folder starterTemplate + extraTemplates resolves to a body in pack.templates', () => { for (const pack of Object.values(STARTER_PACKS)) { for (const folder of pack.folders) { diff --git a/packages/server/src/seed/starter.ts b/packages/server/src/seed/starter.ts index ea92b4b6..675419d7 100644 --- a/packages/server/src/seed/starter.ts +++ b/packages/server/src/seed/starter.ts @@ -1390,7 +1390,7 @@ export const STARTER_PACKS: Readonly> = { 'codebase-wiki': { id: 'codebase-wiki', name: 'Codebase wiki', - description: 'Architecture, modules, and flows.', + description: 'A wiki to help navigate your codebase.', defaultSubfolder: undefined, folders: CODEBASE_WIKI_FOLDERS, templates: CODEBASE_WIKI_TEMPLATES,