@quantiya/codevibe-claude-plugin 1.0.35 → 1.0.36

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codevibe-claude",
3
- "version": "1.0.35",
3
+ "version": "1.0.36",
4
4
  "description": "Sync Claude Code sessions with iOS mobile app via AWS backend. Control Claude Code from your phone with real-time bidirectional synchronization.",
5
5
  "author": {
6
6
  "name": "CodeVibe Team"
@@ -61,7 +61,26 @@ if [ -n "$TRANSCRIPT_PATH" ] && [ -f "$TRANSCRIPT_PATH" ]; then
61
61
  # Tool_result user messages have content blocks of type "tool_result". We
62
62
  # find the INDEX of the last real user prompt in file order, then take every
63
63
  # subsequent assistant message (they're all part of the current turn).
64
- ASSISTANT_MESSAGES=$(jq -r --slurp --arg sent "$SENT_UUIDS_CONTENT" '
64
+ #
65
+ # Bug #292 (2026-05-09): the PermissionRequest hook fires AT THE MOMENT
66
+ # Claude Code is appending the AskUserQuestion tool_use line to the
67
+ # transcript. If the hook reads the file mid-flush, jq --slurp encounters
68
+ # a partial JSON line and fails. With `2>/dev/null` swallowing the error,
69
+ # ASSISTANT_MESSAGES becomes empty and every preceding assistant text
70
+ # block (including the response that prompted the AskUserQuestion) is
71
+ # silently dropped on mobile. AskUserQuestion is most affected because
72
+ # its tool_use payload (questions/options/descriptions) is much larger
73
+ # than Edit/Write/Bash, widening the partial-write race window.
74
+ #
75
+ # Fix: detect partial write via trailing-newline check, drop last line
76
+ # ONLY when the file ends without a newline (= write in flight). When
77
+ # the file ends with a newline, all entries are fully flushed and we
78
+ # parse all of them. This preserves any fully-written final entry.
79
+ # POSIX `tail -c 1` + bash `$( )` (which strips trailing newlines) →
80
+ # empty result iff file ends with `\n`. POSIX sed; macOS + Linux safe.
81
+ # Stderr captured to log instead of /dev/null so future filter errors
82
+ # surface during debugging rather than failing silently.
83
+ read -r -d '' JQ_FILTER <<'JQEOF' || true
65
84
  # Index of the last "real" user prompt. A real prompt has .message.content
66
85
  # that is EITHER a string (simple text prompt) OR an array containing at
67
86
  # least one content block of type "text" (mixed content). Tool_result user
@@ -94,7 +113,18 @@ if [ -n "$TRANSCRIPT_PATH" ] && [ -f "$TRANSCRIPT_PATH" ]; then
94
113
  select(.text | length > 0) |
95
114
  "\(.uuid)\t\(.text | @base64)"
96
115
  end
97
- ' "$TRANSCRIPT_PATH" 2>/dev/null)
116
+ JQEOF
117
+ JQ_STDERR=$(mktemp)
118
+ if [ -n "$(tail -c 1 "$TRANSCRIPT_PATH")" ]; then
119
+ log "WARN" "Transcript last line is partial; dropping for jq parse"
120
+ ASSISTANT_MESSAGES=$(sed '$d' "$TRANSCRIPT_PATH" | jq -r --slurp --arg sent "$SENT_UUIDS_CONTENT" "$JQ_FILTER" 2>"$JQ_STDERR")
121
+ else
122
+ ASSISTANT_MESSAGES=$(jq -r --slurp --arg sent "$SENT_UUIDS_CONTENT" "$JQ_FILTER" "$TRANSCRIPT_PATH" 2>"$JQ_STDERR")
123
+ fi
124
+ if [ -s "$JQ_STDERR" ]; then
125
+ log "WARN" "jq parse stderr (assistant extraction): $(cat "$JQ_STDERR")"
126
+ fi
127
+ rm -f "$JQ_STDERR"
98
128
 
99
129
  if [ -n "$ASSISTANT_MESSAGES" ]; then
100
130
  while IFS=$'\t' read -r MSG_UUID MSG_TEXT_B64; do
package/hooks/stop.sh CHANGED
@@ -60,7 +60,16 @@ fi
60
60
  # Output format: tab-separated lines: uuid\ttype\tcontent
61
61
  # type is "text" for base64-encoded assistant text, "tool_use" for JSON tool uses
62
62
  # Text is base64-encoded because it may contain newlines which break line-by-line read
63
- TRANSCRIPT_EVENTS=$(jq -r --slurp --arg sent "$SENT_UUIDS_CONTENT" '
63
+ # Bug #292 (2026-05-09): a partial last line in the transcript (file is
64
+ # being concurrently appended) makes jq --slurp fail; with `2>/dev/null`
65
+ # swallowing the error, every assistant text/tool_use in the current turn
66
+ # is silently dropped on mobile. R1 round-1 corrected the initial fix:
67
+ # Stop fires AFTER the turn finalizes, so the last line is usually a fully
68
+ # written assistant entry and unconditionally dropping it would cause its
69
+ # OWN regression. Detect partial-write via trailing-newline check and only
70
+ # drop the last line when the file ends WITHOUT a newline. Stderr captured
71
+ # instead of /dev/null so future filter errors surface.
72
+ read -r -d '' JQ_FILTER <<'JQEOF' || true
64
73
  # Index of the last "real" user prompt. A real prompt has .message.content
65
74
  # that is EITHER a string (simple text prompt) OR an array containing at
66
75
  # least one content block of type "text" (mixed content). Tool_result user
@@ -105,7 +114,18 @@ TRANSCRIPT_EVENTS=$(jq -r --slurp --arg sent "$SENT_UUIDS_CONTENT" '
105
114
  "\($msg.uuid)\ttool_use\t\(. | tojson | @base64)"
106
115
  )
107
116
  end
108
- ' "$TRANSCRIPT_PATH" 2>/dev/null)
117
+ JQEOF
118
+ JQ_STDERR=$(mktemp)
119
+ if [ -n "$(tail -c 1 "$TRANSCRIPT_PATH")" ]; then
120
+ log "WARN" "Transcript last line is partial; dropping for jq parse"
121
+ TRANSCRIPT_EVENTS=$(sed '$d' "$TRANSCRIPT_PATH" | jq -r --slurp --arg sent "$SENT_UUIDS_CONTENT" "$JQ_FILTER" 2>"$JQ_STDERR")
122
+ else
123
+ TRANSCRIPT_EVENTS=$(jq -r --slurp --arg sent "$SENT_UUIDS_CONTENT" "$JQ_FILTER" "$TRANSCRIPT_PATH" 2>"$JQ_STDERR")
124
+ fi
125
+ if [ -s "$JQ_STDERR" ]; then
126
+ log "WARN" "jq parse stderr (transcript events): $(cat "$JQ_STDERR")"
127
+ fi
128
+ rm -f "$JQ_STDERR"
109
129
 
110
130
  log "DEBUG" "Transcript parsing complete"
111
131
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quantiya/codevibe-claude-plugin",
3
- "version": "1.0.35",
3
+ "version": "1.0.36",
4
4
  "description": "Control Claude Code from your iPhone and Android — real-time sync, approve file edits, send prompts by voice. Part of CodeVibe.",
5
5
  "main": "dist/server.js",
6
6
  "bin": {