The Next Up blocks showed the main command first, then /clear as a <sub> footnote saying 'first'. Users would copy-paste the command before noticing they should have cleared first. This restructures all 41 instances across 19 workflow files and 2 reference files so /clear appears before the command as a clear sequential instruction. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -11,9 +11,9 @@ Standard format for presenting next steps after completing a command or workflow
|
||||
|
||||
**{identifier}: {name}** — {one-line description}
|
||||
|
||||
`{command to copy-paste}`
|
||||
`/clear` then:
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
`{command to copy-paste}`
|
||||
|
||||
---
|
||||
|
||||
@@ -29,7 +29,7 @@ Standard format for presenting next steps after completing a command or workflow
|
||||
1. **Always show what it is** — name + description, never just a command path
|
||||
2. **Pull context from source** — ROADMAP.md for phases, PLAN.md `<objective>` for plans
|
||||
3. **Command in inline code** — backticks, easy to copy-paste, renders as clickable link
|
||||
4. **`/clear` explanation** — always include, keeps it concise but explains why
|
||||
4. **`/clear` first** — always show `/clear` before the command so users run it in the correct order
|
||||
5. **"Also available" not "Other options"** — sounds more app-like
|
||||
6. **Visual separators** — `---` above and below to make it stand out
|
||||
|
||||
@@ -44,9 +44,9 @@ Standard format for presenting next steps after completing a command or workflow
|
||||
|
||||
**02-03: Refresh Token Rotation** — Add /api/auth/refresh with sliding expiry
|
||||
|
||||
`/gsd:execute-phase 2`
|
||||
`/clear` then:
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
`/gsd:execute-phase 2`
|
||||
|
||||
---
|
||||
|
||||
@@ -69,9 +69,9 @@ Add note that this is the last plan and what comes after:
|
||||
**02-03: Refresh Token Rotation** — Add /api/auth/refresh with sliding expiry
|
||||
<sub>Final plan in Phase 2</sub>
|
||||
|
||||
`/gsd:execute-phase 2`
|
||||
`/clear` then:
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
`/gsd:execute-phase 2`
|
||||
|
||||
---
|
||||
|
||||
@@ -91,9 +91,9 @@ Add note that this is the last plan and what comes after:
|
||||
|
||||
**Phase 2: Authentication** — JWT login flow with refresh tokens
|
||||
|
||||
`/gsd:plan-phase 2`
|
||||
`/clear` then:
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
`/gsd:plan-phase 2`
|
||||
|
||||
---
|
||||
|
||||
@@ -120,9 +120,9 @@ Show completion status before next action:
|
||||
|
||||
**Phase 3: Core Features** — User dashboard, settings, and data export
|
||||
|
||||
`/gsd:plan-phase 3`
|
||||
`/clear` then:
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
`/gsd:plan-phase 3`
|
||||
|
||||
---
|
||||
|
||||
@@ -145,14 +145,14 @@ When there's no clear primary action:
|
||||
|
||||
**Phase 3: Core Features** — User dashboard, settings, and data export
|
||||
|
||||
`/clear` then one of:
|
||||
|
||||
**To plan directly:** `/gsd:plan-phase 3`
|
||||
|
||||
**To discuss context first:** `/gsd:discuss-phase 3`
|
||||
|
||||
**To research unknowns:** `/gsd:research-phase 3`
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
|
||||
---
|
||||
```
|
||||
|
||||
@@ -169,9 +169,9 @@ All 4 phases shipped
|
||||
|
||||
**Start v1.1** — questioning → research → requirements → roadmap
|
||||
|
||||
`/gsd:new-milestone`
|
||||
`/clear` then:
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
`/gsd:new-milestone`
|
||||
|
||||
---
|
||||
```
|
||||
|
||||
@@ -108,9 +108,9 @@ Always at end of major completions.
|
||||
|
||||
**{Identifier}: {Name}** — {one-line description}
|
||||
|
||||
`{copy-paste command}`
|
||||
`/clear` then:
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
`{copy-paste command}`
|
||||
|
||||
───────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
@@ -87,9 +87,9 @@ Roadmap updated: .planning/ROADMAP.md
|
||||
|
||||
**Phase {N}: {description}**
|
||||
|
||||
`/gsd:plan-phase {N}`
|
||||
`/clear` then:
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
`/gsd:plan-phase {N}`
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -229,9 +229,9 @@ All requirements covered. Cross-phase integration verified. E2E flows complete.
|
||||
|
||||
**Complete milestone** — archive and tag
|
||||
|
||||
/gsd:complete-milestone {version}
|
||||
/clear then:
|
||||
|
||||
<sub>/clear first → fresh context window</sub>
|
||||
/gsd:complete-milestone {version}
|
||||
|
||||
───────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -274,9 +274,9 @@ Phases needing validation: run `/gsd:validate-phase {N}` for each flagged phase.
|
||||
|
||||
**Plan gap closure** — create phases to complete milestone
|
||||
|
||||
/gsd:plan-milestone-gaps
|
||||
/clear then:
|
||||
|
||||
<sub>/clear first → fresh context window</sub>
|
||||
/gsd:plan-milestone-gaps
|
||||
|
||||
───────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -316,9 +316,9 @@ All requirements met. No critical blockers. Accumulated tech debt needs review.
|
||||
|
||||
**B. Plan cleanup phase** — address debt before completing
|
||||
|
||||
/gsd:plan-milestone-gaps
|
||||
/clear then:
|
||||
|
||||
<sub>/clear first → fresh context window</sub>
|
||||
/gsd:plan-milestone-gaps
|
||||
|
||||
───────────────────────────────────────────────────────────────
|
||||
</offer_next>
|
||||
|
||||
@@ -719,9 +719,9 @@ Tag: v[X.Y]
|
||||
|
||||
**Start Next Milestone** — questioning → research → requirements → roadmap
|
||||
|
||||
`/gsd:new-milestone`
|
||||
`/clear` then:
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
`/gsd:new-milestone`
|
||||
|
||||
---
|
||||
```
|
||||
|
||||
@@ -597,9 +597,9 @@ Created: .planning/phases/${PADDED_PHASE}-${SLUG}/${PADDED_PHASE}-CONTEXT.md
|
||||
|
||||
**Phase ${PHASE}: {phase_name}** — {Goal from ROADMAP.md}
|
||||
|
||||
`/gsd:plan-phase ${PHASE}`
|
||||
`/clear` then:
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
`/gsd:plan-phase ${PHASE}`
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -975,9 +975,9 @@ Created: .planning/phases/${PADDED_PHASE}-${SLUG}/${PADDED_PHASE}-CONTEXT.md
|
||||
|
||||
**Phase ${PHASE}: [Name]** — [Goal from ROADMAP.md]
|
||||
|
||||
`/gsd:plan-phase ${PHASE} ${GSD_WS}`
|
||||
`/clear` then:
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
`/gsd:plan-phase ${PHASE} ${GSD_WS}`
|
||||
|
||||
---
|
||||
|
||||
@@ -1115,8 +1115,9 @@ This keeps the auto-advance chain flat — discuss, plan, and execute all run at
|
||||
|
||||
Auto-advance pipeline finished: discuss → plan → execute
|
||||
|
||||
/clear then:
|
||||
|
||||
Next: /gsd:discuss-phase ${NEXT_PHASE} ${WAS_CHAIN ? "--chain" : "--auto"} ${GSD_WS}
|
||||
<sub>/clear first → fresh context window</sub>
|
||||
```
|
||||
- **PLANNING COMPLETE** → Planning done, execution didn't complete:
|
||||
```
|
||||
|
||||
@@ -976,9 +976,9 @@ Items saved to `{phase_num}-HUMAN-UAT.md` — they will appear in `/gsd:progress
|
||||
---
|
||||
## ▶ Next Up
|
||||
|
||||
`/gsd:plan-phase {X} --gaps ${GSD_WS}`
|
||||
`/clear` then:
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
`/gsd:plan-phase {X} --gaps ${GSD_WS}`
|
||||
|
||||
Also: `cat {phase_dir}/{phase_num}-VERIFICATION.md` — full report
|
||||
Also: `/gsd:verify-work {X} ${GSD_WS}` — manual testing first
|
||||
|
||||
@@ -93,9 +93,9 @@ Project state updated: .planning/STATE.md
|
||||
|
||||
**Phase {decimal_phase}: {description}** -- urgent insertion
|
||||
|
||||
`/gsd:plan-phase {decimal_phase}`
|
||||
`/clear` then:
|
||||
|
||||
<sub>`/clear` first -> fresh context window</sub>
|
||||
`/gsd:plan-phase {decimal_phase}`
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -349,9 +349,9 @@ Created .planning/codebase/:
|
||||
|
||||
**Initialize project** — use codebase context for planning
|
||||
|
||||
`/gsd:new-project`
|
||||
`/clear` then:
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
`/gsd:new-project`
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -465,9 +465,9 @@ node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" commit "docs: create milest
|
||||
|
||||
**Phase [N]: [Phase Name]** — [Goal]
|
||||
|
||||
`/gsd:discuss-phase [N] ${GSD_WS}` — gather context and clarify approach
|
||||
`/clear` then:
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
`/gsd:discuss-phase [N] ${GSD_WS}` — gather context and clarify approach
|
||||
|
||||
Also: `/gsd:plan-phase [N] ${GSD_WS}` — skip discussion, plan directly
|
||||
```
|
||||
|
||||
@@ -1194,9 +1194,9 @@ PHASE1_HAS_UI=$(echo "$PHASE1_SECTION" | grep -qi "UI hint.*yes" && echo "true"
|
||||
|
||||
**Phase 1: [Phase Name]** — [Goal from ROADMAP.md]
|
||||
|
||||
/gsd:discuss-phase 1 — gather context and clarify approach
|
||||
/clear then:
|
||||
|
||||
<sub>/clear first → fresh context window</sub>
|
||||
/gsd:discuss-phase 1 — gather context and clarify approach
|
||||
|
||||
---
|
||||
|
||||
@@ -1216,9 +1216,9 @@ PHASE1_HAS_UI=$(echo "$PHASE1_SECTION" | grep -qi "UI hint.*yes" && echo "true"
|
||||
|
||||
**Phase 1: [Phase Name]** — [Goal from ROADMAP.md]
|
||||
|
||||
/gsd:discuss-phase 1 — gather context and clarify approach
|
||||
/clear then:
|
||||
|
||||
<sub>/clear first → fresh context window</sub>
|
||||
/gsd:discuss-phase 1 — gather context and clarify approach
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -163,9 +163,9 @@ node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" commit "docs(roadmap): add
|
||||
|
||||
**Plan first gap closure phase**
|
||||
|
||||
`/gsd:plan-phase {N}`
|
||||
`/clear` then:
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
`/gsd:plan-phase {N}`
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -940,9 +940,9 @@ Verification: {Passed | Passed with override | Skipped}
|
||||
|
||||
**Execute Phase {X}** — run all {N} plans
|
||||
|
||||
/gsd:execute-phase {X} ${GSD_WS}
|
||||
/clear then:
|
||||
|
||||
<sub>/clear first → fresh context window</sub>
|
||||
/gsd:execute-phase {X} ${GSD_WS}
|
||||
|
||||
───────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
@@ -215,9 +215,9 @@ Read its `<objective>` section.
|
||||
|
||||
**{phase}-{plan}: [Plan Name]** — [objective summary from PLAN.md]
|
||||
|
||||
`/gsd:execute-phase {phase} ${GSD_WS}`
|
||||
`/clear` then:
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
`/gsd:execute-phase {phase} ${GSD_WS}`
|
||||
|
||||
---
|
||||
```
|
||||
@@ -245,9 +245,9 @@ PHASE_HAS_UI=$(echo "$PHASE_SECTION" | grep -qi "UI hint.*yes" && echo "true" ||
|
||||
**Phase {N}: {Name}** — {Goal from ROADMAP.md}
|
||||
<sub>✓ Context gathered, ready to plan</sub>
|
||||
|
||||
`/gsd:plan-phase {phase-number} ${GSD_WS}`
|
||||
`/clear` then:
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
`/gsd:plan-phase {phase-number} ${GSD_WS}`
|
||||
|
||||
---
|
||||
```
|
||||
@@ -261,9 +261,9 @@ PHASE_HAS_UI=$(echo "$PHASE_SECTION" | grep -qi "UI hint.*yes" && echo "true" ||
|
||||
|
||||
**Phase {N}: {Name}** — {Goal from ROADMAP.md}
|
||||
|
||||
`/gsd:discuss-phase {phase}` — gather context and clarify approach
|
||||
`/clear` then:
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
`/gsd:discuss-phase {phase}` — gather context and clarify approach
|
||||
|
||||
---
|
||||
|
||||
@@ -284,9 +284,9 @@ PHASE_HAS_UI=$(echo "$PHASE_SECTION" | grep -qi "UI hint.*yes" && echo "true" ||
|
||||
|
||||
**Phase {N}: {Name}** — {Goal from ROADMAP.md}
|
||||
|
||||
`/gsd:discuss-phase {phase} ${GSD_WS}` — gather context and clarify approach
|
||||
`/clear` then:
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
`/gsd:discuss-phase {phase} ${GSD_WS}` — gather context and clarify approach
|
||||
|
||||
---
|
||||
|
||||
@@ -310,9 +310,9 @@ UAT.md exists with gaps (diagnosed issues). User needs to plan fixes.
|
||||
|
||||
**{phase_num}-UAT.md** has {N} gaps requiring fixes.
|
||||
|
||||
`/gsd:plan-phase {phase} --gaps ${GSD_WS}`
|
||||
`/clear` then:
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
`/gsd:plan-phase {phase} --gaps ${GSD_WS}`
|
||||
|
||||
---
|
||||
|
||||
@@ -336,9 +336,9 @@ UAT.md exists with `status: partial` — testing session ended before all items
|
||||
|
||||
**{phase_num}-UAT.md** has {N} unresolved tests (pending, blocked, or skipped).
|
||||
|
||||
`/gsd:verify-work {phase} ${GSD_WS}` — resume testing from where you left off
|
||||
`/clear` then:
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
`/gsd:verify-work {phase} ${GSD_WS}` — resume testing from where you left off
|
||||
|
||||
---
|
||||
|
||||
@@ -392,9 +392,9 @@ NEXT_HAS_UI=$(echo "$NEXT_PHASE_SECTION" | grep -qi "UI hint.*yes" && echo "true
|
||||
|
||||
**Phase {Z+1}: {Name}** — {Goal from ROADMAP.md}
|
||||
|
||||
`/gsd:discuss-phase {Z+1}` — gather context and clarify approach
|
||||
`/clear` then:
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
`/gsd:discuss-phase {Z+1}` — gather context and clarify approach
|
||||
|
||||
---
|
||||
|
||||
@@ -417,9 +417,9 @@ NEXT_HAS_UI=$(echo "$NEXT_PHASE_SECTION" | grep -qi "UI hint.*yes" && echo "true
|
||||
|
||||
**Phase {Z+1}: {Name}** — {Goal from ROADMAP.md}
|
||||
|
||||
`/gsd:discuss-phase {Z+1} ${GSD_WS}` — gather context and clarify approach
|
||||
`/clear` then:
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
`/gsd:discuss-phase {Z+1} ${GSD_WS}` — gather context and clarify approach
|
||||
|
||||
---
|
||||
|
||||
@@ -445,9 +445,9 @@ All {N} phases finished!
|
||||
|
||||
**Complete Milestone** — archive and prepare for next
|
||||
|
||||
`/gsd:complete-milestone ${GSD_WS}`
|
||||
`/clear` then:
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
`/gsd:complete-milestone ${GSD_WS}`
|
||||
|
||||
---
|
||||
|
||||
@@ -476,9 +476,9 @@ Ready to plan the next milestone.
|
||||
|
||||
**Start Next Milestone** — questioning → research → requirements → roadmap
|
||||
|
||||
`/gsd:new-milestone ${GSD_WS}`
|
||||
`/clear` then:
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
`/gsd:new-milestone ${GSD_WS}`
|
||||
|
||||
---
|
||||
```
|
||||
|
||||
@@ -235,9 +235,9 @@ Based on user selection, route to appropriate workflow:
|
||||
|
||||
**{phase}-{plan}: [Plan Name]** — [objective from PLAN.md]
|
||||
|
||||
`/gsd:execute-phase {phase} ${GSD_WS}`
|
||||
`/clear` then:
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
`/gsd:execute-phase {phase} ${GSD_WS}`
|
||||
|
||||
---
|
||||
```
|
||||
@@ -249,9 +249,9 @@ Based on user selection, route to appropriate workflow:
|
||||
|
||||
**Phase [N]: [Name]** — [Goal from ROADMAP.md]
|
||||
|
||||
`/gsd:plan-phase [phase-number] ${GSD_WS}`
|
||||
`/clear` then:
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
`/gsd:plan-phase [phase-number] ${GSD_WS}`
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -475,9 +475,9 @@ Exit skill and invoke SlashCommand("/gsd:discuss-phase [X+1] --auto ${GSD_WS}")
|
||||
|
||||
**Phase [X+1]: [Name]** — [Goal from ROADMAP.md]
|
||||
|
||||
`/gsd:discuss-phase [X+1] ${GSD_WS}` — gather context and clarify approach
|
||||
`/clear` then:
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
`/gsd:discuss-phase [X+1] ${GSD_WS}` — gather context and clarify approach
|
||||
|
||||
---
|
||||
|
||||
@@ -500,9 +500,9 @@ Exit skill and invoke SlashCommand("/gsd:discuss-phase [X+1] --auto ${GSD_WS}")
|
||||
**Phase [X+1]: [Name]** — [Goal from ROADMAP.md]
|
||||
<sub>✓ Context gathered, ready to plan</sub>
|
||||
|
||||
`/gsd:plan-phase [X+1] ${GSD_WS}`
|
||||
`/clear` then:
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
`/gsd:plan-phase [X+1] ${GSD_WS}`
|
||||
|
||||
---
|
||||
|
||||
@@ -610,9 +610,9 @@ Exit skill and invoke SlashCommand("/gsd:complete-milestone {version} ${GSD_WS}"
|
||||
|
||||
**Complete Milestone {version}** — archive and prepare for next
|
||||
|
||||
`/gsd:complete-milestone {version} ${GSD_WS}`
|
||||
`/clear` then:
|
||||
|
||||
<sub>`/clear` first → fresh context window</sub>
|
||||
`/gsd:complete-milestone {version} ${GSD_WS}`
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -263,9 +263,9 @@ Dimensions: 6/6 passed
|
||||
|
||||
**Plan Phase {N}** — planner will use UI-SPEC.md as design context
|
||||
|
||||
`/gsd:plan-phase {N}`
|
||||
`/clear` then:
|
||||
|
||||
<sub>/clear first → fresh context window</sub>
|
||||
`/gsd:plan-phase {N}`
|
||||
|
||||
───────────────────────────────────────────────────────────────
|
||||
```
|
||||
|
||||
@@ -138,11 +138,11 @@ Full review: {path to UI-REVIEW.md}
|
||||
|
||||
## ▶ Next
|
||||
|
||||
`/clear` then one of:
|
||||
|
||||
- `/gsd:verify-work {N}` — UAT testing
|
||||
- `/gsd:plan-phase {N+1}` — plan next phase
|
||||
|
||||
<sub>/clear first → fresh context window</sub>
|
||||
|
||||
───────────────────────────────────────────────────────────────
|
||||
```
|
||||
|
||||
|
||||
164
tests/next-up-clear-order.test.cjs
Normal file
164
tests/next-up-clear-order.test.cjs
Normal file
@@ -0,0 +1,164 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Next Up /clear Order Tests (#1623)
|
||||
*
|
||||
* Validates that /clear always appears BEFORE the command in Next Up blocks,
|
||||
* not as a <sub> footnote after the command. Users should see /clear first
|
||||
* so they run it before copy-pasting the actual command.
|
||||
*/
|
||||
|
||||
const { test, describe } = require('node:test');
|
||||
const assert = require('node:assert');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const glob = require('path');
|
||||
|
||||
const GSD_ROOT = path.join(__dirname, '..', 'get-shit-done');
|
||||
const UI_BRAND = path.join(GSD_ROOT, 'references', 'ui-brand.md');
|
||||
const CONTINUATION_FORMAT = path.join(GSD_ROOT, 'references', 'continuation-format.md');
|
||||
const WORKFLOWS_DIR = path.join(GSD_ROOT, 'workflows');
|
||||
|
||||
/**
|
||||
* Recursively collect all .md files in a directory.
|
||||
*/
|
||||
function collectMarkdownFiles(dir) {
|
||||
const results = [];
|
||||
if (!fs.existsSync(dir)) return results;
|
||||
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
||||
const full = path.join(dir, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
results.push(...collectMarkdownFiles(full));
|
||||
} else if (entry.name.endsWith('.md')) {
|
||||
results.push(full);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
describe('ui-brand.md — Next Up template has /clear before command', () => {
|
||||
const content = fs.readFileSync(UI_BRAND, 'utf-8');
|
||||
|
||||
test('Next Up block template does not use <sub>/clear pattern', () => {
|
||||
const subClearPattern = /<sub>[^<]*\/clear[^<]*<\/sub>/gi;
|
||||
const matches = content.match(subClearPattern);
|
||||
assert.strictEqual(
|
||||
matches,
|
||||
null,
|
||||
'ui-brand.md must not contain <sub>/clear</sub> pattern — /clear should appear before the command'
|
||||
);
|
||||
});
|
||||
|
||||
test('Next Up block template shows /clear then: before {copy-paste command}', () => {
|
||||
// Extract the Next Up Block section
|
||||
const nextUpSection = content.slice(
|
||||
content.indexOf('## Next Up Block'),
|
||||
content.indexOf('## Error Box')
|
||||
);
|
||||
assert.ok(nextUpSection.length > 0, 'Should find Next Up Block section');
|
||||
|
||||
const clearIndex = nextUpSection.indexOf('/clear');
|
||||
const commandIndex = nextUpSection.indexOf('{copy-paste command}');
|
||||
assert.ok(clearIndex > -1, 'Should contain /clear');
|
||||
assert.ok(commandIndex > -1, 'Should contain {copy-paste command}');
|
||||
assert.ok(
|
||||
clearIndex < commandIndex,
|
||||
`/clear (at ${clearIndex}) must appear before {copy-paste command} (at ${commandIndex})`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('continuation-format.md — Next Up examples have /clear before commands', () => {
|
||||
const content = fs.readFileSync(CONTINUATION_FORMAT, 'utf-8');
|
||||
|
||||
test('no <sub>/clear patterns remain', () => {
|
||||
const subClearPattern = /<sub>[^<]*\/clear[^<]*<\/sub>/gi;
|
||||
const matches = content.match(subClearPattern);
|
||||
assert.strictEqual(
|
||||
matches,
|
||||
null,
|
||||
'continuation-format.md must not contain <sub>/clear</sub> pattern'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('workflow files — no <sub>/clear patterns in Next Up blocks', () => {
|
||||
const workflowFiles = collectMarkdownFiles(WORKFLOWS_DIR);
|
||||
|
||||
test('found workflow .md files to scan', () => {
|
||||
assert.ok(
|
||||
workflowFiles.length > 0,
|
||||
`Expected workflow .md files in ${WORKFLOWS_DIR}`
|
||||
);
|
||||
});
|
||||
|
||||
test('no workflow file contains <sub> with /clear', () => {
|
||||
const subClearPattern = /<sub>[^<]*\/clear[^<]*<\/sub>/gi;
|
||||
const failures = [];
|
||||
|
||||
for (const filePath of workflowFiles) {
|
||||
const content = fs.readFileSync(filePath, 'utf-8');
|
||||
const matches = content.match(subClearPattern);
|
||||
if (matches) {
|
||||
failures.push({
|
||||
file: path.relative(GSD_ROOT, filePath),
|
||||
matches: matches.length,
|
||||
examples: matches.slice(0, 3),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
assert.strictEqual(
|
||||
failures.length,
|
||||
0,
|
||||
`Found <sub>/clear</sub> pattern in ${failures.length} workflow file(s):\n` +
|
||||
failures
|
||||
.map(
|
||||
(f) =>
|
||||
` ${f.file}: ${f.matches} match(es) — e.g. ${f.examples[0]}`
|
||||
)
|
||||
.join('\n')
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('reference files — no <sub>/clear patterns', () => {
|
||||
const referencesDir = path.join(GSD_ROOT, 'references');
|
||||
const refFiles = collectMarkdownFiles(referencesDir);
|
||||
|
||||
test('found reference .md files to scan', () => {
|
||||
assert.ok(
|
||||
refFiles.length > 0,
|
||||
`Expected reference .md files in ${referencesDir}`
|
||||
);
|
||||
});
|
||||
|
||||
test('no reference file contains <sub> with /clear', () => {
|
||||
const subClearPattern = /<sub>[^<]*\/clear[^<]*<\/sub>/gi;
|
||||
const failures = [];
|
||||
|
||||
for (const filePath of refFiles) {
|
||||
const content = fs.readFileSync(filePath, 'utf-8');
|
||||
const matches = content.match(subClearPattern);
|
||||
if (matches) {
|
||||
failures.push({
|
||||
file: path.relative(GSD_ROOT, filePath),
|
||||
matches: matches.length,
|
||||
examples: matches.slice(0, 3),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
assert.strictEqual(
|
||||
failures.length,
|
||||
0,
|
||||
`Found <sub>/clear</sub> pattern in ${failures.length} reference file(s):\n` +
|
||||
failures
|
||||
.map(
|
||||
(f) =>
|
||||
` ${f.file}: ${f.matches} match(es) — e.g. ${f.examples[0]}`
|
||||
)
|
||||
.join('\n')
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user