The after-completion example put {{ output }} and {{ exitCode }} inside
single-quoted shell arguments, so and never expanded
after substituteShellAfterCompletedEnvRefs runs.
Update the apprise sample to use printf-based quoting that allows env
substitution, document the single-quote pitfall, and extend
TestShellAfterCompletedUsesOutputEnvSafely to assert stdout is
substituted as well as injection being blocked.
Route output and exitCode through OUTPUT/EXITCODE environment variables
instead of shell interpolation, and block shellAfterCompleted for webhook
actions.
Co-authored-by: Cursor <cursoragent@cursor.com>
Wrap regex: patterns in a non-capturing group before applying ^...$ so
alternation cannot bypass full-string matching. Return template parse
errors from buildShellAfterCommand, and guard nil binding/action before
building shellAfterCompleted commands.
StartActionAndWait and StartActionByGetAndWait now apply the same logs
permission check used by GetLogs and ExecutionStatus.
Co-authored-by: Cursor <cursoragent@cursor.com>
Block additional unvalidated argument types from shell actions, enforce
full-string custom regex matching, and allowlist http/https URL schemes.
Update checkbox integration test to use exec, matching the intended shell
vs exec split for choiceless checkbox arguments.
Co-authored-by: Cursor <cursoragent@cursor.com>
Sweep expired OAuth2 state entries, cap the map at 10000 entries, and
remove stale state on failed callback validation.
Co-authored-by: Cursor <cursoragent@cursor.com>
ParseChecklistValue now accepts JSON arrays or single bare values and rejects
legacy comma-separated input. Empty JSON segments are validated consistently,
and FormatChecklistValue returns marshal errors instead of an empty string
Use a single justification string for both requirement and templating so
empty values skip prompts while templates can prefill audit reasons at start.
Co-authored-by: Cursor <cursoragent@cursor.com>