diff --git a/diagram/SKILL.md b/diagram/SKILL.md index 9e5a41066c..a17f0adeea 100644 --- a/diagram/SKILL.md +++ b/diagram/SKILL.md @@ -1,7 +1,7 @@ --- name: diagram version: 1.0.0 -description: "Turn an English description (or mermaid source) into a diagram triplet: the source, an editable .excalidraw file you can open (gstack)" +description: "Turn an English description (or mermaid source) into a diagram triplet: the source, an editable .excalidraw file you can open on excalidraw.com, and rendered SVG + PNG. (gstack)" allowed-tools: - Bash - Read @@ -21,9 +21,8 @@ triggers: ## When to invoke this skill -on excalidraw.com, -and rendered SVG + PNG (clean mermaid style; the .excalidraw carries the -hand-drawn aesthetic). Fully offline. +The SVG/PNG use clean mermaid style; the +.excalidraw carries the hand-drawn aesthetic. Fully offline. Use when asked to "make a diagram", "draw the architecture", "create a flowchart", "diagram this", or "visualize this flow". diff --git a/diagram/SKILL.md.tmpl b/diagram/SKILL.md.tmpl index 9e19a52c6b..38acdf16cc 100644 --- a/diagram/SKILL.md.tmpl +++ b/diagram/SKILL.md.tmpl @@ -4,8 +4,8 @@ version: 1.0.0 description: | Turn an English description (or mermaid source) into a diagram triplet: the source, an editable .excalidraw file you can open on excalidraw.com, - and rendered SVG + PNG (clean mermaid style; the .excalidraw carries the - hand-drawn aesthetic). Fully offline. + and rendered SVG + PNG. The SVG/PNG use clean mermaid style; the + .excalidraw carries the hand-drawn aesthetic. Fully offline. Use when asked to "make a diagram", "draw the architecture", "create a flowchart", "diagram this", or "visualize this flow". (gstack) allowed-tools: diff --git a/gstack/llms.txt b/gstack/llms.txt index efe522f901..979acf3e7c 100644 --- a/gstack/llms.txt +++ b/gstack/llms.txt @@ -26,7 +26,7 @@ Conventions: - [/design-review](design-review/SKILL.md): Designer's eye QA: finds visual inconsistency, spacing issues, hierarchy problems, AI slop patterns, and slow interactions — then fixes them. - [/design-shotgun](design-shotgun/SKILL.md): Design shotgun: generate multiple AI design variants, open a comparison board, collect structured feedback, and iterate. - [/devex-review](devex-review/SKILL.md): Live developer experience audit. -- [/diagram](diagram/SKILL.md): Turn an English description (or mermaid source) into a diagram triplet: the source, an editable .excalidraw file you can open on excalidraw.com, and rendered SVG + PNG (clean mermaid style; the .excalidraw carries the hand-drawn aesthetic). +- [/diagram](diagram/SKILL.md): Turn an English description (or mermaid source) into a diagram triplet: the source, an editable .excalidraw file you can open on excalidraw.com, and rendered SVG + PNG. - [/document-generate](document-generate/SKILL.md): Generate missing documentation from scratch for a feature, module, or entire project. - [/document-release](document-release/SKILL.md): Post-ship documentation update. - [/freeze](freeze/SKILL.md): Restrict file edits to a specific directory for the session. diff --git a/scripts/gen-skill-docs.ts b/scripts/gen-skill-docs.ts index 71aa1a34ca..4c54492e84 100644 --- a/scripts/gen-skill-docs.ts +++ b/scripts/gen-skill-docs.ts @@ -322,7 +322,7 @@ export function splitCatalogDescription(description: string): CatalogParts { // the period to be followed by whitespace OR end-of-text. // First normalize to single-line for sentence detection, then back out. const collapsed = working.replace(/\s+/g, ' ').trim(); - const sentenceMatch = collapsed.match(/^([^.!?]*[.!?])(?:\s|$)/); + const sentenceMatch = collapsed.match(/^((?:[^.!?]|[.!?](?!\s|$))*[.!?])(?:\s|$)/); // sentenceLead is the FULL first sentence (no truncation). We compute routing // from this position, then optionally truncate the displayed lead afterwards. // Truncating first then computing routing was the v1.45.0.0 bug — when the diff --git a/scripts/proactive-suggestions.json b/scripts/proactive-suggestions.json index d08c608533..f4c49e56e8 100644 --- a/scripts/proactive-suggestions.json +++ b/scripts/proactive-suggestions.json @@ -79,8 +79,8 @@ "voice_line": "Voice triggers (speech-to-text aliases): \"dx audit\", \"test the developer experience\", \"try the onboarding\", \"developer experience test\"." }, "diagram": { - "lead": "Turn an English description (or mermaid source) into a diagram triplet: the source, an editable .excalidraw file you can open", - "routing": "on excalidraw.com,\nand rendered SVG + PNG (clean mermaid style; the .excalidraw carries the\nhand-drawn aesthetic). Fully offline.\nUse when asked to \"make a diagram\", \"draw the architecture\", \"create a\nflowchart\", \"diagram this\", or \"visualize this flow\".", + "lead": "Turn an English description (or mermaid source) into a diagram triplet: the source, an editable .excalidraw file you can open on excalidraw.com, and rendered SVG + PNG.", + "routing": "The SVG/PNG use clean mermaid style; the\n.excalidraw carries the hand-drawn aesthetic. Fully offline.\nUse when asked to \"make a diagram\", \"draw the architecture\", \"create a\nflowchart\", \"diagram this\", or \"visualize this flow\".", "voice_line": null }, "document-generate": { @@ -264,8 +264,8 @@ "voice_line": null }, "sync-gbrain": { - "lead": "Keep gbrain current with this repo's code and refresh agent search guidance in CLAUDE.md. Wraps the gstack-gbrain-sync orchestrator with state", - "routing": "probing, native code-surface registration, capability checks,\nand a verdict block. Re-runnable, idempotent. Use when: \"sync gbrain\",\n\"refresh gbrain\", \"re-index this repo\", \"gbrain search isn't finding\nthings\".", + "lead": "Keep gbrain current with this repo's code and refresh agent search guidance in CLAUDE.md.", + "routing": "Wraps the gstack-gbrain-sync orchestrator with\nstate probing, native code-surface registration, capability checks,\nand a verdict block. Re-runnable, idempotent. Use when: \"sync gbrain\",\n\"refresh gbrain\", \"re-index this repo\", \"gbrain search isn't finding\nthings\".", "voice_line": null }, "unfreeze": { diff --git a/sync-gbrain/SKILL.md b/sync-gbrain/SKILL.md index bfaf291d22..8c00ab5e36 100644 --- a/sync-gbrain/SKILL.md +++ b/sync-gbrain/SKILL.md @@ -2,7 +2,7 @@ name: sync-gbrain preamble-tier: 2 version: 1.0.0 -description: Keep gbrain current with this repo's code and refresh agent search guidance in CLAUDE.md. Wraps the gstack-gbrain-sync orchestrator with state (gstack) +description: Keep gbrain current with this repo's code and refresh agent search guidance in CLAUDE.md. (gstack) triggers: - sync gbrain - refresh gbrain @@ -23,7 +23,8 @@ allowed-tools: ## When to invoke this skill -probing, native code-surface registration, capability checks, +Wraps the gstack-gbrain-sync orchestrator with +state probing, native code-surface registration, capability checks, and a verdict block. Re-runnable, idempotent. Use when: "sync gbrain", "refresh gbrain", "re-index this repo", "gbrain search isn't finding things". diff --git a/test/catalog-trim.test.ts b/test/catalog-trim.test.ts index 82e46bdfe3..1c6d2279df 100644 --- a/test/catalog-trim.test.ts +++ b/test/catalog-trim.test.ts @@ -95,31 +95,21 @@ describe('splitCatalogDescription', () => { expect(parts.routingProse).toBe('With routing prose afterward.'); }); - test('embedded-period descriptions: known limitation falls back to first-20-words', () => { - // KNOWN LIMITATION: the sentence regex `^([^.!?]*[.!?])(?:\\s|$)` stops - // at the FIRST `.`-then-non-whitespace because [^.!?]* is greedy and - // can't backtrack past a non-period char. For "DESIGN.md and v1.45.0.0 - // in the lead. Use when..." the regex fails entirely and the lead falls - // back to the first 20 words (~the whole short input). - // - // The real-world impact is small: descriptions like "DESIGN.md" or "v1.45" - // appearing in the middle of the FIRST sentence are rare. When they do - // occur, the lead simply becomes the full description (no body section - // generated) — same as a description without a period. The trim CI gate - // still keeps the per-skill size budget honest. - // - // If this gap matters later, replace the regex with a sentence tokenizer - // (compromise.js / Intl.Segmenter) — until then we accept the fallback. + test('embedded periods do not end the lead sentence', () => { const desc = 'Skill that mentions DESIGN.md and v1.45.0.0 in the lead. ' + 'Use when asked to do something.'; const parts = splitCatalogDescription(desc); - // Actual behavior: lead absorbs the whole input via the word-count fallback. - expect(parts.lead.length).toBeGreaterThan(0); - // routingProse may be empty when the fallback consumes everything. - // The test exists to detect REGRESSIONS (lead becoming oddly short like - // "Skill that mentions DESIGN.") not to assert ideal behavior. - expect(parts.lead).toContain('Skill that mentions'); + expect(parts.lead).toBe('Skill that mentions DESIGN.md and v1.45.0.0 in the lead.'); + expect(parts.routingProse).toBe('Use when asked to do something.'); + }); + + test('URL periods do not end the lead sentence', () => { + const parts = splitCatalogDescription( + 'Open https://example.com/docs and inspect it. Use when asked to check docs.', + ); + expect(parts.lead).toBe('Open https://example.com/docs and inspect it.'); + expect(parts.routingProse).toBe('Use when asked to check docs.'); }); test('description without a period uses first ~20 words as lead', () => {