@windyroad/voice-tone 0.5.11-preview.721 → 0.5.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -185,28 +185,59 @@ except Exception:
|
|
|
185
185
|
DRAFT=$(printf '%s' "$COMMAND" | python3 -c "
|
|
186
186
|
import sys, re
|
|
187
187
|
cmd = sys.stdin.read()
|
|
188
|
-
#
|
|
188
|
+
# P364: bash double-quote unescape. The double-quoted body capture groups
|
|
189
|
+
# carry RAW shell-escaped command text — an orchestrator must backslash-escape
|
|
190
|
+
# backticks (and \$, \", \\) inside \"...\" to survive bash parsing, e.g.
|
|
191
|
+
# --body \"Fixed in \\\`code\\\` ...\". The PostToolUse mark hook hashes the
|
|
192
|
+
# LOGICAL <draft> body (plain backticks), so the gate must undo those escapes
|
|
193
|
+
# or the two marker keys diverge → permanent deny-after-PASS. Inside double
|
|
194
|
+
# quotes a backslash is special ONLY before \$ \` \" \\ or a newline (line
|
|
195
|
+
# continuation); single-quoted and <<'EOF' forms are literal and need none.
|
|
196
|
+
# Single left-to-right pass so an escaped backslash adjacent to another escape
|
|
197
|
+
# (\\\\\` -> backslash + backtick) is NOT mis-collapsed. chr() literals keep
|
|
198
|
+
# this source free of the very metacharacters the surrounding shell double
|
|
199
|
+
# quotes would otherwise eat.
|
|
200
|
+
def unescape_dq(s):
|
|
201
|
+
out = []
|
|
202
|
+
i = 0
|
|
203
|
+
n = len(s)
|
|
204
|
+
special = set([chr(36), chr(96), chr(34), chr(92), chr(10)])
|
|
205
|
+
while i < n:
|
|
206
|
+
if s[i] == chr(92) and i + 1 < n and s[i + 1] in special:
|
|
207
|
+
if s[i + 1] != chr(10):
|
|
208
|
+
out.append(s[i + 1])
|
|
209
|
+
i += 2
|
|
210
|
+
else:
|
|
211
|
+
out.append(s[i])
|
|
212
|
+
i += 1
|
|
213
|
+
return ''.join(out)
|
|
214
|
+
# (pattern, flags, unescape) — first match wins. unescape=True for the
|
|
215
|
+
# double-quoted forms only (P364).
|
|
189
216
|
patterns = [
|
|
190
217
|
# HEREDOC body — matches a here-doc with EOF delimiter (quoted or
|
|
191
218
|
# unquoted). The literal '<<' is written as the char-class pair
|
|
192
219
|
# [<][<] so bash's command-substitution parser does NOT mis-parse
|
|
193
220
|
# this regex as a real here-doc operator (P082 implementation note).
|
|
194
|
-
# DOTALL so the body can span newlines.
|
|
195
|
-
|
|
221
|
+
# DOTALL so the body can span newlines. Left literal: the AI-canonical
|
|
222
|
+
# form is the quoted <<'EOF' heredoc, whose body bash does not unescape.
|
|
223
|
+
(r\"[<][<]\s*['\\\"]?EOF['\\\"]?\s*\n(.*?)\nEOF\", re.DOTALL, False),
|
|
196
224
|
# gh issue/pr + npm publish --body 'TEXT' / --body \"TEXT\" (existing).
|
|
197
|
-
(r\"--body[= ]'([^']*)'\", 0),
|
|
198
|
-
(r'--body[= ]\"([^\"]*)\"', 0),
|
|
225
|
+
(r\"--body[= ]'([^']*)'\", 0, False),
|
|
226
|
+
(r'--body[= ]\"([^\"]*)\"', 0, True),
|
|
199
227
|
# gh api --field summary='TEXT' / --field summary=\"TEXT\" (existing).
|
|
200
|
-
(r\"--field [a-zA-Z_]+='([^']*)'\", 0),
|
|
201
|
-
(r'--field [a-zA-Z_]+=\"([^\"]*)\"', 0),
|
|
228
|
+
(r\"--field [a-zA-Z_]+='([^']*)'\", 0, False),
|
|
229
|
+
(r'--field [a-zA-Z_]+=\"([^\"]*)\"', 0, True),
|
|
202
230
|
# git commit -m / --message single-line literal forms (P082 Phase 1).
|
|
203
|
-
(r\"(?:-m|--message)[= ]'([^']*)'\", 0),
|
|
204
|
-
(r'(?:-m|--message)[= ]\"([^\"]*)\"', 0),
|
|
231
|
+
(r\"(?:-m|--message)[= ]'([^']*)'\", 0, False),
|
|
232
|
+
(r'(?:-m|--message)[= ]\"([^\"]*)\"', 0, True),
|
|
205
233
|
]
|
|
206
|
-
for pat, flags in patterns:
|
|
234
|
+
for pat, flags, unescape in patterns:
|
|
207
235
|
m = re.search(pat, cmd, flags)
|
|
208
236
|
if m:
|
|
209
|
-
|
|
237
|
+
body = m.group(1)
|
|
238
|
+
if unescape:
|
|
239
|
+
body = unescape_dq(body)
|
|
240
|
+
print(body)
|
|
210
241
|
break
|
|
211
242
|
" 2>/dev/null || echo "")
|
|
212
243
|
;;
|
|
@@ -322,3 +322,37 @@ run_hook() {
|
|
|
322
322
|
[ "$status" -eq 0 ]
|
|
323
323
|
[ -z "$output" ]
|
|
324
324
|
}
|
|
325
|
+
|
|
326
|
+
# ---------------------------------------------------------------------------
|
|
327
|
+
# P364 — backtick-bearing double-quoted --body marker-key mismatch.
|
|
328
|
+
# The voice-tone gate shares the byte-identical canonical external-comms-gate.sh
|
|
329
|
+
# (ADR-017 sync), so the P364 shell-unescape fix applies here too: a body with
|
|
330
|
+
# backslash-escaped backticks in --body "..." must unescape to the logical
|
|
331
|
+
# <draft> body the PostToolUse mark hook hashes, or the PASS marker never
|
|
332
|
+
# permits. DISTINCT from P276 / P010 (whitespace / frontmatter).
|
|
333
|
+
# ---------------------------------------------------------------------------
|
|
334
|
+
|
|
335
|
+
@test "P364: backtick-bearing double-quoted --body permits when marker keyed on the unescaped logical body" {
|
|
336
|
+
LOGICAL='Tidied the wording in `external-comms-gate` for the patch.'
|
|
337
|
+
SURFACE="gh-issue-comment"
|
|
338
|
+
KEY=$(printf '%s\n%s' "$LOGICAL" "$SURFACE" | shasum -a 256 | cut -d' ' -f1)
|
|
339
|
+
touch "${RDIR}/external-comms-voice-tone-reviewed-${KEY}"
|
|
340
|
+
|
|
341
|
+
CMD='gh issue comment 42 --body "Tidied the wording in \`external-comms-gate\` for the patch."'
|
|
342
|
+
INPUT=$(build_bash_input "$CMD")
|
|
343
|
+
run_hook "$INPUT"
|
|
344
|
+
[ "$status" -eq 0 ]
|
|
345
|
+
[ -z "$output" ]
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
@test "P364: single-quoted --body with literal backticks stays literal (no unescaping applied)" {
|
|
349
|
+
LOGICAL='Tidied the wording in `plain_span` here.'
|
|
350
|
+
SURFACE="gh-issue-comment"
|
|
351
|
+
KEY=$(printf '%s\n%s' "$LOGICAL" "$SURFACE" | shasum -a 256 | cut -d' ' -f1)
|
|
352
|
+
touch "${RDIR}/external-comms-voice-tone-reviewed-${KEY}"
|
|
353
|
+
|
|
354
|
+
INPUT=$(build_bash_input "gh issue comment 42 --body 'Tidied the wording in \`plain_span\` here.'")
|
|
355
|
+
run_hook "$INPUT"
|
|
356
|
+
[ "$status" -eq 0 ]
|
|
357
|
+
[ -z "$output" ]
|
|
358
|
+
}
|