openclaw-opencode-bridge 2.1.1 โ†’ 2.1.2

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclaw-opencode-bridge",
3
- "version": "2.1.1",
3
+ "version": "2.1.2",
4
4
  "description": "Bridge OpenClaw messaging channels to OpenCode via tmux persistent sessions",
5
5
  "main": "./lib/onboard.js",
6
6
  "bin": {
@@ -37,10 +37,10 @@
37
37
  "name": "Febrian",
38
38
  "email": "febro.aw20@gmail.com"
39
39
  },
40
- "homepage": "https://febro.fun",
40
+ "homepage": "http://febro.fun",
41
41
  "license": "MIT",
42
42
  "repository": {
43
43
  "type": "git",
44
- "url": "https://github.com/bettep-dev/openclaw-opencode-bridge"
44
+ "url": "https://github.com/AganFebro/openclaw-opencode-bridge"
45
45
  }
46
46
  }
@@ -1,5 +1,5 @@
1
1
  #!/bin/bash
2
- # bridge-version: 5
2
+ # bridge-version: 6
3
3
  # Start fresh session asynchronously and send instruction
4
4
  MSG="$1"
5
5
  OPENCODE="{{OPENCODE_BIN}}"
@@ -9,6 +9,7 @@ WORKSPACE="{{WORKSPACE}}"
9
9
  LOG_FILE="/tmp/opencode-bridge-send.log"
10
10
  BASE_TIMEOUT_SEC=45
11
11
  MAX_TIMEOUT_SEC=300
12
+ LOCK_WAIT_SEC=600
12
13
 
13
14
  if [ -z "$MSG" ]; then
14
15
  echo "ERROR: No message provided"
@@ -28,6 +29,21 @@ normalize_text() {
28
29
  | sed -E 's/^๐Ÿ”—[[:space:]]*//; s/^["'\''`]+|["'\''`]+$//g; s/[[:space:]]+/ /g; s/^[[:space:]]+|[[:space:]]+$//g'
29
30
  }
30
31
 
32
+ acquire_bridge_lock() {
33
+ local safe_channel safe_target lock_file
34
+ safe_channel="$(printf '%s' "$CHANNEL" | sed -E 's/[^a-zA-Z0-9._-]/_/g')"
35
+ safe_target="$(printf '%s' "$TARGET" | sed -E 's/[^a-zA-Z0-9._-]/_/g')"
36
+ lock_file="/tmp/opencode-bridge-${safe_channel}-${safe_target}.lock"
37
+
38
+ if command -v flock >/dev/null 2>&1; then
39
+ exec 200>"$lock_file"
40
+ flock -w "$LOCK_WAIT_SEC" 200
41
+ return $?
42
+ fi
43
+
44
+ return 0
45
+ }
46
+
31
47
  compute_timeout() {
32
48
  local msg="$1"
33
49
  local timeout="$BASE_TIMEOUT_SEC"
@@ -62,38 +78,48 @@ is_trivial_echo() {
62
78
  [ -n "$message_norm" ] && [ "$output_norm" = "$message_norm" ]
63
79
  }
64
80
 
65
- extract_embedded_send_message() {
81
+ extract_last_marked_block() {
66
82
  local raw="$1"
67
- local line message
68
-
69
- line="$(printf '%s\n' "$raw" | grep -E 'openclaw message send --channel' | tail -n 1)"
70
- [ -z "$line" ] && return 0
71
-
72
- if printf '%s' "$line" | grep -q -- "-m '"; then
73
- message="$(printf '%s' "$line" | sed -n "s/.* -m '\(.*\)'.*/\1/p")"
74
- elif printf '%s' "$line" | grep -q -- '-m "'; then
75
- message="$(printf '%s' "$line" | sed -n 's/.* -m "\(.*\)".*/\1/p')"
83
+ if ! printf '%s' "$raw" | grep -q '๐Ÿ”—'; then
84
+ return 0
76
85
  fi
77
86
 
78
- printf '%s' "$(trim_text "$message")"
87
+ printf '%s\n' "$raw" | awk '
88
+ {
89
+ pos = index($0, "๐Ÿ”—");
90
+ if (pos > 0) {
91
+ out = substr($0, pos);
92
+ capture = 1;
93
+ next;
94
+ }
95
+ if (capture) {
96
+ out = out "\n" $0;
97
+ }
98
+ }
99
+ END {
100
+ if (capture) print out;
101
+ }'
79
102
  }
80
103
 
81
104
  sanitize_output() {
82
105
  local raw="$1"
83
- local extracted cleaned
84
-
85
- extracted="$(extract_embedded_send_message "$raw")"
86
- if [ -n "$extracted" ]; then
87
- printf '%s' "$extracted"
88
- return 0
89
- fi
106
+ local cleaned marked
90
107
 
91
108
  cleaned="$(printf '%s' "$raw" \
92
109
  | tr '\r' '\n' \
93
110
  | sed -E $'s/\x1B\\[[0-9;?]*[ -/]*[@-~]//g; s/\x1B\\][^\a]*(\a|\x1B\\\\)//g')"
94
111
 
112
+ cleaned="$(printf '%s\n' "$cleaned" | sed -E 's/\[[0-9]{1,3}m//g')"
113
+
95
114
  cleaned="$(printf '%s\n' "$cleaned" | grep -Ev \
96
- '^[[:space:]]*$|^[[:space:]]*(build ยท|โ—‡ Doctor warnings)[[:space:]]*$|^[[:space:]]*openclaw message send --channel[[:space:]]+|^[[:space:]]*Sent via Telegram|^[[:space:]]*\[[0-9]{1,3}m|^[[:space:]]*\[(telegram|discord|slack|whatsapp|signal|irc|matrix|line|mattermost|teams)\]|autoSelectFamily=|dnsResultOrder=|^[[:space:]]*[โ”‚โ”Œโ”โ””โ”˜โ”œโ”คโ”ฌโ”ดโ”ผโ”€โ•โ•ญโ•ฎโ•ฐโ•ฏ]+[[:space:]]*$|^[[:space:]]*\$[[:space:]]*\[[0-9]{1,3}m')"
115
+ '^[[:space:]]*$|^[[:space:]]*(build[[:space:]]*ยท|โ—‡[[:space:]]+Doctor warnings)[[:space:]]*$|^[[:space:]]*โ—‡[[:space:]]+|^[[:space:]]*[โ†โ†’โ†ณ].*|^[[:space:]]*Wrote file successfully\.?$|^[[:space:]]*(\$[[:space:]]*)?openclaw message send --channel[[:space:]]+|^[[:space:]]*error:[[:space:]]*too many arguments for '\''send'\''.*$|^[[:space:]]*Sent via Telegram|^[[:space:]]*\[(telegram|discord|slack|whatsapp|signal|irc|matrix|line|mattermost|teams)\]|autoSelectFamily=|dnsResultOrder=|^[[:space:]]*[โ”‚โ”Œโ”โ””โ”˜โ”œโ”คโ”ฌโ”ดโ”ผโ”€โ•โ•ญโ•ฎโ•ฐโ•ฏ]+[[:space:]]*$')"
116
+
117
+ marked="$(extract_last_marked_block "$cleaned")"
118
+ if [ -n "$marked" ]; then
119
+ cleaned="$marked"
120
+ fi
121
+
122
+ cleaned="$(printf '%s\n' "$cleaned" | sed -E 's/^๐Ÿ”—[[:space:]]*//')"
97
123
 
98
124
  printf '%s' "$(trim_text "$cleaned")"
99
125
  }
@@ -140,6 +166,12 @@ run_with_timeout() {
140
166
  cd "$WORKSPACE" || exit 1
141
167
  FULL_MSG="[${CHANNEL}:${TARGET}] $MSG"
142
168
 
169
+ if ! acquire_bridge_lock; then
170
+ openclaw message send --channel "$CHANNEL" --target "$TARGET" -m "Bridge is still processing a previous request. Please retry in a moment."
171
+ printf '[%s] /ccn lock timeout after %ss\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$LOCK_WAIT_SEC"
172
+ exit 0
173
+ fi
174
+
143
175
  run_result="$(run_with_timeout --fork "$FULL_MSG")"
144
176
  rc="$(printf '%s' "$run_result" | head -n 1)"
145
177
  output="$(printf '%s' "$run_result" | tail -n +2)"
@@ -1,5 +1,5 @@
1
1
  #!/bin/bash
2
- # bridge-version: 5
2
+ # bridge-version: 6
3
3
  # Dispatch instruction to OpenCode asynchronously and relay response
4
4
  MSG="$1"
5
5
  OPENCODE="{{OPENCODE_BIN}}"
@@ -9,6 +9,7 @@ WORKSPACE="{{WORKSPACE}}"
9
9
  LOG_FILE="/tmp/opencode-bridge-send.log"
10
10
  BASE_TIMEOUT_SEC=45
11
11
  MAX_TIMEOUT_SEC=300
12
+ LOCK_WAIT_SEC=600
12
13
 
13
14
  if [ -z "$MSG" ]; then
14
15
  echo "ERROR: No message provided"
@@ -28,6 +29,21 @@ normalize_text() {
28
29
  | sed -E 's/^๐Ÿ”—[[:space:]]*//; s/^["'\''`]+|["'\''`]+$//g; s/[[:space:]]+/ /g; s/^[[:space:]]+|[[:space:]]+$//g'
29
30
  }
30
31
 
32
+ acquire_bridge_lock() {
33
+ local safe_channel safe_target lock_file
34
+ safe_channel="$(printf '%s' "$CHANNEL" | sed -E 's/[^a-zA-Z0-9._-]/_/g')"
35
+ safe_target="$(printf '%s' "$TARGET" | sed -E 's/[^a-zA-Z0-9._-]/_/g')"
36
+ lock_file="/tmp/opencode-bridge-${safe_channel}-${safe_target}.lock"
37
+
38
+ if command -v flock >/dev/null 2>&1; then
39
+ exec 200>"$lock_file"
40
+ flock -w "$LOCK_WAIT_SEC" 200
41
+ return $?
42
+ fi
43
+
44
+ return 0
45
+ }
46
+
31
47
  compute_timeout() {
32
48
  local msg="$1"
33
49
  local timeout="$BASE_TIMEOUT_SEC"
@@ -62,38 +78,48 @@ is_trivial_echo() {
62
78
  [ -n "$message_norm" ] && [ "$output_norm" = "$message_norm" ]
63
79
  }
64
80
 
65
- extract_embedded_send_message() {
81
+ extract_last_marked_block() {
66
82
  local raw="$1"
67
- local line message
68
-
69
- line="$(printf '%s\n' "$raw" | grep -E 'openclaw message send --channel' | tail -n 1)"
70
- [ -z "$line" ] && return 0
71
-
72
- if printf '%s' "$line" | grep -q -- "-m '"; then
73
- message="$(printf '%s' "$line" | sed -n "s/.* -m '\(.*\)'.*/\1/p")"
74
- elif printf '%s' "$line" | grep -q -- '-m "'; then
75
- message="$(printf '%s' "$line" | sed -n 's/.* -m "\(.*\)".*/\1/p')"
83
+ if ! printf '%s' "$raw" | grep -q '๐Ÿ”—'; then
84
+ return 0
76
85
  fi
77
86
 
78
- printf '%s' "$(trim_text "$message")"
87
+ printf '%s\n' "$raw" | awk '
88
+ {
89
+ pos = index($0, "๐Ÿ”—");
90
+ if (pos > 0) {
91
+ out = substr($0, pos);
92
+ capture = 1;
93
+ next;
94
+ }
95
+ if (capture) {
96
+ out = out "\n" $0;
97
+ }
98
+ }
99
+ END {
100
+ if (capture) print out;
101
+ }'
79
102
  }
80
103
 
81
104
  sanitize_output() {
82
105
  local raw="$1"
83
- local extracted cleaned
84
-
85
- extracted="$(extract_embedded_send_message "$raw")"
86
- if [ -n "$extracted" ]; then
87
- printf '%s' "$extracted"
88
- return 0
89
- fi
106
+ local cleaned marked
90
107
 
91
108
  cleaned="$(printf '%s' "$raw" \
92
109
  | tr '\r' '\n' \
93
110
  | sed -E $'s/\x1B\\[[0-9;?]*[ -/]*[@-~]//g; s/\x1B\\][^\a]*(\a|\x1B\\\\)//g')"
94
111
 
112
+ cleaned="$(printf '%s\n' "$cleaned" | sed -E 's/\[[0-9]{1,3}m//g')"
113
+
95
114
  cleaned="$(printf '%s\n' "$cleaned" | grep -Ev \
96
- '^[[:space:]]*$|^[[:space:]]*(build ยท|โ—‡ Doctor warnings)[[:space:]]*$|^[[:space:]]*openclaw message send --channel[[:space:]]+|^[[:space:]]*Sent via Telegram|^[[:space:]]*\[[0-9]{1,3}m|^[[:space:]]*\[(telegram|discord|slack|whatsapp|signal|irc|matrix|line|mattermost|teams)\]|autoSelectFamily=|dnsResultOrder=|^[[:space:]]*[โ”‚โ”Œโ”โ””โ”˜โ”œโ”คโ”ฌโ”ดโ”ผโ”€โ•โ•ญโ•ฎโ•ฐโ•ฏ]+[[:space:]]*$|^[[:space:]]*\$[[:space:]]*\[[0-9]{1,3}m')"
115
+ '^[[:space:]]*$|^[[:space:]]*(build[[:space:]]*ยท|โ—‡[[:space:]]+Doctor warnings)[[:space:]]*$|^[[:space:]]*โ—‡[[:space:]]+|^[[:space:]]*[โ†โ†’โ†ณ].*|^[[:space:]]*Wrote file successfully\.?$|^[[:space:]]*(\$[[:space:]]*)?openclaw message send --channel[[:space:]]+|^[[:space:]]*error:[[:space:]]*too many arguments for '\''send'\''.*$|^[[:space:]]*Sent via Telegram|^[[:space:]]*\[(telegram|discord|slack|whatsapp|signal|irc|matrix|line|mattermost|teams)\]|autoSelectFamily=|dnsResultOrder=|^[[:space:]]*[โ”‚โ”Œโ”โ””โ”˜โ”œโ”คโ”ฌโ”ดโ”ผโ”€โ•โ•ญโ•ฎโ•ฐโ•ฏ]+[[:space:]]*$')"
116
+
117
+ marked="$(extract_last_marked_block "$cleaned")"
118
+ if [ -n "$marked" ]; then
119
+ cleaned="$marked"
120
+ fi
121
+
122
+ cleaned="$(printf '%s\n' "$cleaned" | sed -E 's/^๐Ÿ”—[[:space:]]*//')"
97
123
 
98
124
  printf '%s' "$(trim_text "$cleaned")"
99
125
  }
@@ -140,6 +166,12 @@ run_with_timeout() {
140
166
  cd "$WORKSPACE" || exit 1
141
167
  FULL_MSG="[${CHANNEL}:${TARGET}] $MSG"
142
168
 
169
+ if ! acquire_bridge_lock; then
170
+ openclaw message send --channel "$CHANNEL" --target "$TARGET" -m "Bridge is still processing a previous request. Please retry in a moment."
171
+ printf '[%s] /cc lock timeout after %ss\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$LOCK_WAIT_SEC"
172
+ exit 0
173
+ fi
174
+
143
175
  run_result="$(run_with_timeout --continue "$FULL_MSG")"
144
176
  rc="$(printf '%s' "$run_result" | head -n 1)"
145
177
  output="$(printf '%s' "$run_result" | tail -n +2)"