Skip to content

feat: support custom delimiters in the serve web workbench#7

Merged
machado144 merged 4 commits into
mainfrom
feature/serve-runtime-delimiters
Jul 1, 2026
Merged

feat: support custom delimiters in the serve web workbench#7
machado144 merged 4 commits into
mainfrom
feature/serve-runtime-delimiters

Conversation

@machado144

Copy link
Copy Markdown
Contributor

Summary

  • The serve web workbench could only ever display the active [[ ]] delimiter pair (set at startup via --startDelim/--endDelim); changing it meant restarting the server. This adds an editable pair next to the directory path — type a new pair and click Set to validate, apply, and rescan instantly, no restart.
  • The new pair is stored on the running Server and read by settings(), so it applies uniformly to Local, Clone, and Generate — the same single source of truth the CLI already uses.
  • Zero new matching/replacement logic: this reuses the exact same workflow.Engine / services.Replacer functions the CLI's template, clone, and generate commands already exercise (regexp.QuoteMeta-escaped regex for apply, strings.Index literal scan for preview — both already covered by services/replacer_test.go).
  • Adds ValidateDelimiters, which closes a real bug found while building this: the literal scan (services/replacer.go) finds delimiters with strings.Index, which returns 0 without consuming input for an empty needle — an empty/empty pair would spin forever on any non-empty file, hanging the request goroutine. Empty, equal, and mutually-containing delimiter pairs are now rejected up front (400 + clear message), and a rejected change leaves the previous pair active.
  • Also fixes a lock-discipline gap: settings() and handleIndex now read startDelim/endDelim under Server.mu, since they're mutable at runtime now instead of fixed at construction (verified race-free with go test -race).
  • Docs updated: README.md, docs/user/README.md, docs/AI/README.md, EXAMPLES.md, COMMANDS.md.
  • Includes a small, separate first commit swapping the placeholder banner for the new logo and adding a recorded demo GIF of the workbench.

Test plan

  • go build ./..., go vet ./..., gofmt -l clean on touched files
  • go test ./... -race — full suite green, including the new tests, no data races
  • New unit tests for ValidateDelimiters (table-driven): valid custom/default/unicode/regex-metachar/equal-length-non-overlapping pairs, plus empty/whitespace-only/equal/mutually-containing rejections
  • Regression test (TestSetDelimitersRejectsEmptyWithoutHanging) that guards the empty-pair hang bug with a 2s timeout, so it fails loudly instead of hanging CI if the validation is ever removed
  • HTTP-level feature test proving a full before/after: default pair only sees one placeholder, switching delimiters rescans and finds the other, then /api/apply writes the file using the new pair while an unrelated file using the old pair is untouched
  • HTTP-level test that a rejected /api/delimiters call returns 400 with a message and leaves server state (and subsequent scans) unchanged
  • Method-not-allowed and malformed-JSON edge cases on the new endpoint
  • Concurrency test hammering SetDelimiters/Scan from goroutines simultaneously (clean under -race)
  • Manually exercised in a real browser end-to-end (screenshots below): scanned a dir with default delimiters, switched to <%/%> live, watched the placeholder list update and old matches disappear, applied successfully, then confirmed the validation error path shows a clear message and leaves state untouched

Before → after (live in browser)

Default [[ ]] scan After setting <% %> Rejected invalid pair
finds NAME only finds GREETING only, banner confirms rescan red banner: "start and end delimiters must be different", state unchanged

🤖 Generated with Claude Code

machado144 and others added 2 commits July 1, 2026 19:50
Swap the AI-generated placeholder banner.png for the polished yankrun-logo.png mascot, and add a recorded GIF of the serve workbench (scan -> fill -> preview -> apply) to the README so the UI is visible without running it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
CLI users could already set --startDelim/--endDelim, but the web workbench only ever displayed the pair it started with - changing it meant restarting the server. Add an editable delimiter pair next to the directory path: typing a new pair and clicking Set validates it, updates the running server, and rescans immediately. Local, Clone, and Generate all read from the same server state, so the change applies everywhere without a restart.

The change reuses the exact same workflow.Engine/services.Replacer functions the CLI already exercises - no new matching or replacement logic. New validation (ValidateDelimiters) closes a real bug found while building this: the literal scan in services/replacer.go finds delimiters with strings.Index, which returns 0 without consuming input for an empty needle, so an empty/empty pair would spin forever on any non-empty file. Empty, equal, and mutually-containing delimiter pairs are now rejected before they reach the scanner, and the previous pair stays active if a change is rejected.

Also fixes a lock-discipline gap: settings() and handleIndex now read startDelim/endDelim under Server.mu, since they're mutable now instead of fixed at construction.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown

StructLint — All checks passed

85 rules validated against .structlint.yaml. No violations found.

View full run · Powered by StructLint

machado144 and others added 2 commits July 1, 2026 19:54
It was only reachable by expanding the collapsed <details> for the serve command, so it was effectively invisible on first read. Move it right under the tagline where it's visible without clicking anything.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
doc/serve-demo.gif failed the naming-pattern check because .gif wasn't in the allowed extension list, alongside the existing .png/.jpg/.svg.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@machado144 machado144 merged commit 1b5ea1a into main Jul 1, 2026
6 checks passed
@machado144 machado144 deleted the feature/serve-runtime-delimiters branch July 1, 2026 18:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant