init-session.sh: a plan name with an embedded newline creates an unusable plan directory
Problem
init-session.sh "<name>" accepts a plan name that contains an embedded newline. slugify keeps the newline, mkdir -p creates a directory whose name contains it, the selector then rejects that id as an invalid slug, and init exits 1 with the directory left behind.
Scope: named-plan mode on the shell route (Linux, macOS, Git Bash) and only for a name that contains a newline, which normally comes from a script or an agent passing multi-line text as the argument. The default zero-argument root mode is not affected. The PowerShell twin already replaces newlines in Get-PlanSlug.
How to reproduce
sh scripts/init-session.sh "$(printf 'line one\nline two')"
ls .planning/Observed (Git Bash, 2026-09-17): a directory .planning/<date>-line-one<newline>line-two/ is created with the three planning files inside it, then the run prints Error: invalid plan ID. Use a named directory under .planning. and Error: could not safely update .../.planning/.active_plan. and exits 1. The pointer is not updated and the malformed directory stays behind.
Cause: slugify in skills/planning-with-files/scripts/init-session.sh pipes the name through tr '[:upper:]' '[:lower:]' and sed -e 's/[^a-z0-9]/-/g' .... sed works line by line, so the newline between the lines is never seen by the character class and survives into SLUG. PLAN_ID is then used in mkdir -p "$PLAN_DIR" before set-active-plan.sh validates it.
Suggested fix
- Strip
\rand\ninslugifybefore thesedstep (tr -d '\r\n'), so the slug is a single line. This matches the PowerShell twin. - Validate
PLAN_IDagainst the selector's slug rule beforemkdir -p(the same character setset-active-plan.shaccepts), and exit 1 with a clear message when it does not match, so nothing is created for an invalid name.
A regression test can pass a name with an embedded newline and assert exit code 0 with a single-line slug, or exit 1 with no directory created, depending on which behaviour is chosen. Making the slug single-line is the friendlier option.
Origin
Found by the v3.19.0 release review (PRs #247, #248, #249). Tracked as item 5 of #250 before that issue was split into one issue per item.
Source: OthmanAdi/planning-with-files