feat: optional / skippable {{VALUE}} / {{VDATE}} prompts#1297
Conversation
- |optional flag (bare, pre-extracted before the usesOptions decision so shorthand defaults survive; keyed optional:<bool> form) on VALUE/NAME, option lists, and VDATE (new pure vdateSyntax.ts parser; regex unchanged) - '' is now an answered value for VDATE variables too: prompt gate is undefined-aware (#872 parity) — script-set '' renders empty instead of re-prompting; the ' ' workaround stays byte-identical - optional tokens bypass default-on-empty (cleared prefilled box = empty); required tokens keep default-wins (pinned) - optional VDATE: blank input/Skip resolves empty; non-blank garbage still errors (typo protection); required parse errors gain an |optional tip - Skip button + hint in input/wide/date prompts (a resolution, never a rejection); suggesters get instructions footer + Mod+Shift+Enter skip - one-page modal: (optional) badges, dropdown 'Skip (leave empty)' entry (first option stays preselected), optional blank date stores '', required blank/unparseable dates omit the key so the sequential prompt still fires, Esc now rejects 'cancelled' instead of hanging waitForClose - empty-file-name guard, preview formatter no longer renders the flag as '(default: optional)', format-syntax suggester entries, docs + examples Closes #1259
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAdds end-to-end support for ChangesOptional prompts feature (VALUE and VDATE tokens)
Estimated code review effort Possibly related PRs
Suggested labels
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install timed out. The project may have too many dependencies for the sandbox. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Deploying quickadd with
|
| Latest commit: |
5246e17
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://5db7c88f.quickadd.pages.dev |
| Branch Preview URL: | https://1259-feature-request-optiona.quickadd.pages.dev |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/engine/TemplateEngine.ts`:
- Around line 522-526: The current guard in TemplateEngine.ts only checks
formattedFileName.trim(), which misses cases where the path ends with a slash
(e.g. "Folder/") and therefore has no basename, allowing generation of paths
like "/.md"; update the validation in the method that throws the error to also
ensure the final path segment (basename) is non-empty—e.g., trim trailing
slashes and verify path.basename(formattedFileName.trim()) (or equivalent logic)
yields a non-empty filename (and not just an extension) before proceeding, and
throw the existing error if that check fails.
In `@src/preflight/RequirementCollector.ts`:
- Around line 241-251: The optionality aggregation currently runs for all
requirement types and can let a VDATE occurrence change optional on non-date
requirements; restrict this by applying the optional aggregation only when
existing.type === "date" (same guard used for default backfill). Update the
logic around the existing.optional assignment in RequirementCollector (the block
that currently sets existing.optional = (existing.optional ?? false) &&
optional) so it is executed only for date requirements (or combine it into the
existing.type === "date" conditional) and leave non-date requirements untouched.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: b126f7e4-2ebc-4c03-a129-591c2307be70
📒 Files selected for processing (28)
docs/docs/Advanced/onePageInputs.mddocs/docs/FormatSyntax.mdsrc/constants.tssrc/engine/TemplateEngine.tssrc/engine/TemplateInsertEngine.tssrc/formatters/completeFormatter.tssrc/formatters/formatDisplayFormatter.tssrc/formatters/formatSyntax.docs-examples.test.tssrc/formatters/formatter-optional.test.tssrc/formatters/formatter.tssrc/gui/GenericInputPrompt/GenericInputPrompt.tssrc/gui/GenericSuggester/genericSuggester.tssrc/gui/GenericWideInputPrompt/GenericWideInputPrompt.tssrc/gui/InputSuggester/inputSuggester.tssrc/gui/VDateInputPrompt/VDateInputPrompt.tssrc/gui/suggesters/formatSyntaxSuggester.tssrc/preflight/OnePageInputModal.test.tssrc/preflight/OnePageInputModal.tssrc/preflight/RequirementCollector.test.tssrc/preflight/RequirementCollector.tssrc/preflight/collectChoiceRequirements.tssrc/styles.csssrc/types/inputPrompt.tssrc/utils/pipeSyntax.tssrc/utils/valueSyntax.test.tssrc/utils/valueSyntax.tssrc/utils/vdateSyntax.test.tssrc/utils/vdateSyntax.ts
- guard degenerate capture targets ('notes/.md' from an optional token left
empty) with a clear ChoiceAbortError instead of creating the file
- api.requestInputs: pass the optional field through to the one-page form and
backfill omitted blank-date keys with '' so every requested id resolves
- replaceDateVariableInString: use a replacer function so $-patterns in
stored values are literal (a pre-seeded '$&' previously hung the loop)
- neutral empty-file-name error message (no longer blames |optional
unconditionally); drop the dead TemplateEngine.getFormattedFilePath
- collector: scanDateTokens is the single VDATE requirement recorder (the
promptForVariable registration block was unreachable and lacked the AND rule)
- drop the redundant didSkip flag; share installSkipAffordance between the
two suggesters; share extractBareFlagPart between the VALUE/VDATE grammars
2103267 to
48e46a2
Compare
…ting
Review feedback (CodeRabbit): 'Projects/{{VALUE:name|optional}}' skipped
resolved to 'Projects/' which passed the whole-string guard and still
created 'Projects/.md'. Validate the leaf segment instead, and mirror the
check in TemplateInsertEngine's move-offer pre-check.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/engine/CaptureChoiceEngine.ts`:
- Around line 818-821: Replace the manual basename extraction with the existing
utility: instead of computing basename from finalPath via regex chains, call the
imported basenameWithoutMdOrCanvas on finalPath to produce the same value;
update the const named basename (in CaptureChoiceEngine around the block that
currently computes basename from finalPath) to use
basenameWithoutMdOrCanvas(finalPath) so duplication is removed and behavior
stays consistent with other uses in this file.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 11fedcf2-bbba-4f17-bc50-076b2dde0585
📒 Files selected for processing (14)
src/engine/CaptureChoiceEngine.tssrc/engine/TemplateEngine.tssrc/formatters/formatter-optional.test.tssrc/formatters/formatter.tssrc/gui/GenericInputPrompt/GenericInputPrompt.tssrc/gui/GenericSuggester/genericSuggester.tssrc/gui/InputSuggester/inputSuggester.tssrc/gui/VDateInputPrompt/VDateInputPrompt.tssrc/gui/suggesters/utils.tssrc/preflight/RequirementCollector.tssrc/quickAddApi.tssrc/utils/pipeSyntax.tssrc/utils/valueSyntax.tssrc/utils/vdateSyntax.ts
🚧 Files skipped from review as they are similar to previous changes (6)
- src/formatters/formatter-optional.test.ts
- src/utils/pipeSyntax.ts
- src/gui/VDateInputPrompt/VDateInputPrompt.ts
- src/utils/vdateSyntax.ts
- src/formatters/formatter.ts
- src/engine/TemplateEngine.ts
Review feedback (CodeRabbit): the hand-rolled basename extraction duplicated the existing pathUtils helper already used in this file.
# [2.13.0](2.12.3...2.13.0) (2026-06-11) ### Bug Fixes * **ai:** match provider endpoints by hostname, not URL substring ([#1242](#1242)) ([c48ce52](c48ce52)) * **capture:** preserve content when file creation fails ([#1270](#1270)) ([8e58562](8e58562)) * **choices:** bug fixes + polish for the choices view ([#1262](#1262)) ([be083db](be083db)), closes [#1257](#1257) [#1261](#1261) * ignore unresolved field tokens in suggestions ([#1271](#1271)) ([c374be9](c374be9)) * keep non-breaking-space-only captures instead of dropping them as empty ([#1296](#1296)) ([37a9398](37a9398)), closes [#760](#760) * **macros:** keep commands from vanishing when reordering in the macro editor ([#1244](#1244)) ([539605d](539605d)) * preserve prompt drafts until choice execution commits ([0b08863](0b08863)), closes [#1275](#1275) * resolve three verified bugs surfaced by the core-logic tests ([#1246](#1246)) ([#1247](#1247)) ([d2333fe](d2333fe)) * store one-page FIELD inputs under the runtime FIELD: variable key ([#1295](#1295)) ([9ccc86a](9ccc86a)), closes [#1184](#1184) * suppress yes/no prompt pointer press ([#1273](#1273)) ([d31b8f4](d31b8f4)) ### Features * **a11y:** keyboard & ARIA pass on the choice & macro GUIs ([#1251](#1251)) ([9247e00](9247e00)) * **api:** add cursor option for input prompts ([#1272](#1272)) ([f05284e](f05284e)) * apply template to existing note ([#1293](#1293)) ([7f4d35d](7f4d35d)), closes [#526](#526) * **capture:** add insert-before write position ([#1274](#1274)) ([7a6e95f](7a6e95f)) * **choices:** highlight folders as drop targets while dragging + empty-folder hint ([#1264](#1264)) ([ff69ce8](ff69ce8)) * migrate settings to the Obsidian 1.13 declarative API; raise minAppVersion to 1.13.0 ([#1255](#1255)) ([fcb22f6](fcb22f6)) * optional / skippable {{VALUE}} / {{VDATE}} prompts ([#1297](#1297)) ([e629deb](e629deb)), closes [#1259](#1259) * **packages:** capability-review preview for package import ([#1287](#1287)) ([ba9cf00](ba9cf00)) * rework the add-choice UX — explained types, Multi-as-folder, add-into-folder ([#1257](#1257)) ([c02b1ab](c02b1ab)) * search nested choices in the choice picker ([#1294](#1294)) ([1b84cc3](1b84cc3)), closes [#1185](#1185)
|
🎉 This PR is included in version 2.13.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
|
🚀 Release has been published: v2.13.0 |
Adds a first-class way to make prompts optional: a
|optionaltoken flag on{{VALUE}}/{{NAME}}, option lists, and{{VDATE}}, with Skip affordances in every prompt surface and empty-allowed optional fields in the One-Page Input modal.What this adds
|optionalflag — bare form is pre-extracted before the shorthand-default decision, so{{VALUE:x|tomorrow|optional}}keeps its default; keyedoptional:<bool>also supported (wins over the bare flag). New purevdateSyntax.tsparses the VDATE post-pipe segment order-insensitively (|tomorrow|optional≡|optional|tomorrow);DATE_VARIABLE_REGEXunchanged.""now counts as an answered value for{{VDATE}}too (prompt gate is undefined-aware, matching the{{VALUE}}contract from Fix: Empty string variables no longer trigger prompts #872). A script-set""renders empty instead of re-prompting; the" "workaround stays byte-identical.tomorowcan never silently become "no date"); required-date parse errors now end with a tip pointing at|optional."", required-blank/unparseable dates omit their key so the sequential date prompt still fires, and Esc now rejects"cancelled"instead of leavingwaitForClosepending forever.<folder>/.md), format-syntax popup entries, settings preview no longer renders the flag as(default: optional).{{VDATE:due,[📅 ]YYYY-MM-DD|optional}}(renders📅 2026-06-14when answered, nothing when skipped — covers the Tasks-plugin single-line case with zero extra grammar), the scripting""contract, and a correction to the false claim that pipes can be escaped inside VDATE formats.Behavior changes to call out in release notes
{{VALUE:x|optional}}no longer means default-text "optional" — escape hatch:|default:optional. Multi-part shorthand defaults containing the exact word also change (a|optional|b→a|b+ optional).""(alsonull/0/false) on a VDATE variable renders instead of re-prompting — this is the fix requested in the issue; usedelete variables.x/ leave unset to force a prompt.api.requestInputs: a required blank date field now omits its key from the result (was"") — necessary so the sequential re-prompt keeps firing under the new gate.Review notes
formatter.ts,=== undefined) with the one-page omit-key change (OnePageInputModal.submit) — they must never be separated, which is why this ships as one PR.api.format/folder-path/selector exits; whole-line|trimdeletes user text on the exact Tasks-capture line it targets). The[📅 ]format-literal recipe covers the residue cases instead.GenericWideInputPrompt.ts, no shiftKey guard), so a chord can only be added later with a real conflict pass.|optional(pipe segment means filters),api.inputPrompt({skippable}), prompt ordering (separate ask in the forum thread — should get its own issue at close-out).Verification
Formattersemantics, collector AND-rule, one-page modal incl. Esc fix);bun run build-with-lintclean.""/" "contracts, Skip flows in text/wide/date prompts, cleared-default WYSIWYG vs required default-wins, suggester footer + hotkey skip, required-blank-date error tip, Koen's task-line recipe end-to-end, Esc-still-aborts. Manual QA sheet for the remaining eyes-on checks lives in the dev vault (QA-1259 Optional Prompts.md).Fixes #1259
Summary by CodeRabbit
New Features
Documentation
Bug Fixes
Tests