mirror of
https://github.com/clawdbot/clawdbot.git
synced 2026-01-31 19:37:45 +01:00
VoiceWake: document escape path and reset stale forward command
This commit is contained in:
@@ -157,6 +157,7 @@ final class AppState: ObservableObject {
|
||||
|
||||
var storedForwardCommand = UserDefaults.standard
|
||||
.string(forKey: voiceWakeForwardCommandKey) ?? defaultVoiceWakeForwardCommand
|
||||
// Guard against older prefs missing flags; the forwarder depends on these for replies.
|
||||
if !storedForwardCommand.contains("--deliver") || !storedForwardCommand.contains("--session") {
|
||||
storedForwardCommand = defaultVoiceWakeForwardCommand
|
||||
UserDefaults.standard.set(storedForwardCommand, forKey: voiceWakeForwardCommandKey)
|
||||
|
||||
@@ -108,21 +108,23 @@ final class HealthStore: ObservableObject {
|
||||
env: env,
|
||||
timeout: 15)
|
||||
|
||||
guard response.ok, let data = response.payload, !data.isEmpty else {
|
||||
self.lastError = response.message ?? "health probe failed"
|
||||
if onDemand { self.snapshot = nil }
|
||||
// Always try to decode JSON even when the CLI exits non-zero; it prints the
|
||||
// failure snapshot before exiting so we can surface a useful message.
|
||||
if let data = response.payload, !data.isEmpty,
|
||||
let decoded = try? JSONDecoder().decode(HealthSnapshot.self, from: data)
|
||||
{
|
||||
self.snapshot = decoded
|
||||
if response.ok {
|
||||
self.lastSuccess = Date()
|
||||
self.lastError = nil
|
||||
} else {
|
||||
self.lastError = self.describeFailure(from: decoded)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
do {
|
||||
let decoded = try JSONDecoder().decode(HealthSnapshot.self, from: data)
|
||||
self.snapshot = decoded
|
||||
self.lastSuccess = Date()
|
||||
self.lastError = nil
|
||||
} catch {
|
||||
self.lastError = error.localizedDescription
|
||||
if onDemand { self.snapshot = nil }
|
||||
}
|
||||
self.lastError = response.message ?? "health probe failed"
|
||||
if onDemand { self.snapshot = nil }
|
||||
}
|
||||
|
||||
var state: HealthState {
|
||||
@@ -147,6 +149,22 @@ final class HealthStore: ObservableObject {
|
||||
}
|
||||
return "linked · auth \(auth) · socket ok"
|
||||
}
|
||||
|
||||
private func describeFailure(from snap: HealthSnapshot) -> String {
|
||||
if !snap.web.linked {
|
||||
return "Not linked — run clawdis login"
|
||||
}
|
||||
if let connect = snap.web.connect, !connect.ok {
|
||||
let code = connect.status.map { "status \($0)" } ?? "status unknown"
|
||||
let elapsed = connect.elapsedMs.map { "\(Int($0))ms" } ?? "unknown duration"
|
||||
let reason = connect.error ?? "connect failed"
|
||||
return "\(reason) (\(code), \(elapsed))"
|
||||
}
|
||||
if !snap.ipc.exists {
|
||||
return "IPC socket missing at \(snap.ipc.path)"
|
||||
}
|
||||
return "health probe failed"
|
||||
}
|
||||
}
|
||||
|
||||
func msToAge(_ ms: Double) -> String {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
onlyBuiltDependencies:
|
||||
- '@whiskeysockets/baileys'
|
||||
- esbuild
|
||||
- sharp
|
||||
|
||||
@@ -3,7 +3,7 @@ set -euo pipefail
|
||||
|
||||
APP_BUNDLE="${1:-dist/Clawdis.app}"
|
||||
IDENTITY="${SIGN_IDENTITY:-}"
|
||||
ENT_TMP=$(mktemp /tmp/clawdis-entitlements.XXXXXX.plist)
|
||||
ENT_TMP=$(mktemp -t clawdis-entitlements)
|
||||
|
||||
if [ ! -d "$APP_BUNDLE" ]; then
|
||||
echo "App bundle not found: $APP_BUNDLE" >&2
|
||||
@@ -51,6 +51,8 @@ cat > "$ENT_TMP" <<'PLIST'
|
||||
<dict>
|
||||
<key>com.apple.security.hardened-runtime</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.allow-jit</key>
|
||||
<true/>
|
||||
<key>com.apple.security.automation.apple-events</key>
|
||||
<true/>
|
||||
<key>com.apple.security.device.audio-input</key>
|
||||
@@ -75,6 +77,13 @@ if [ -f "$APP_BUNDLE/Contents/MacOS/ClawdisCLI" ]; then
|
||||
echo "Signing CLI helper"; sign_item "$APP_BUNDLE/Contents/MacOS/ClawdisCLI"
|
||||
fi
|
||||
|
||||
# Sign bundled relay runtime bits (bun, native addons, libvips dylibs)
|
||||
if [ -d "$APP_BUNDLE/Contents/Resources/Relay" ]; then
|
||||
find "$APP_BUNDLE/Contents/Resources/Relay" -type f \( -name "bun" -o -name "*.node" -o -name "*.dylib" \) -print0 | while IFS= read -r -d '' f; do
|
||||
echo "Signing relay payload: $f"; sign_item "$f"
|
||||
done
|
||||
fi
|
||||
|
||||
# Sign any embedded frameworks/dylibs if they ever appear
|
||||
if [ -d "$APP_BUNDLE/Contents/Frameworks" ]; then
|
||||
find "$APP_BUNDLE/Contents/Frameworks" \( -name "*.framework" -o -name "*.dylib" \) -print0 | while IFS= read -r -d '' f; do
|
||||
|
||||
@@ -15,6 +15,9 @@ GIT_COMMIT=$(cd "$ROOT_DIR" && git rev-parse --short HEAD 2>/dev/null || echo "u
|
||||
APP_VERSION="${APP_VERSION:-$PKG_VERSION}"
|
||||
APP_BUILD="${APP_BUILD:-$PKG_VERSION}"
|
||||
|
||||
echo "📦 Building JS (pnpm build)"
|
||||
(cd "$ROOT_DIR" && pnpm build)
|
||||
|
||||
cd "$ROOT_DIR/apps/macos"
|
||||
|
||||
echo "🔨 Building $PRODUCT (debug)"
|
||||
@@ -26,6 +29,7 @@ echo "🧹 Cleaning old app bundle"
|
||||
rm -rf "$APP_ROOT"
|
||||
mkdir -p "$APP_ROOT/Contents/MacOS"
|
||||
mkdir -p "$APP_ROOT/Contents/Resources"
|
||||
mkdir -p "$APP_ROOT/Contents/Resources/Relay"
|
||||
|
||||
echo "📄 Writing Info.plist"
|
||||
cat > "$APP_ROOT/Contents/Info.plist" <<PLIST
|
||||
@@ -79,6 +83,36 @@ cp "$ROOT_DIR/apps/macos/Sources/Clawdis/Resources/Clawdis.icns" "$APP_ROOT/Cont
|
||||
echo "📦 Copying WebChat resources"
|
||||
rsync -a "$ROOT_DIR/apps/macos/Sources/Clawdis/Resources/WebChat" "$APP_ROOT/Contents/Resources/"
|
||||
|
||||
RELAY_DIR="$APP_ROOT/Contents/Resources/Relay"
|
||||
BUN_SRC="${BUN_PATH:-$(command -v bun || true)}"
|
||||
if [ -z "$BUN_SRC" ] || [ ! -x "$BUN_SRC" ]; then
|
||||
echo "bun binary not found (set BUN_PATH to override)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "🧰 Staging relay runtime (bun + dist + node_modules)"
|
||||
cp "$BUN_SRC" "$RELAY_DIR/bun"
|
||||
chmod +x "$RELAY_DIR/bun"
|
||||
rsync -a --delete --exclude "Clawdis.app" "$ROOT_DIR/dist/" "$RELAY_DIR/dist/"
|
||||
cp "$ROOT_DIR/package.json" "$RELAY_DIR/"
|
||||
cp "$ROOT_DIR/pnpm-lock.yaml" "$RELAY_DIR/"
|
||||
if [ -f "$ROOT_DIR/.npmrc" ]; then
|
||||
cp "$ROOT_DIR/.npmrc" "$RELAY_DIR/"
|
||||
fi
|
||||
|
||||
echo "📦 Installing prod node_modules into bundle (hoisted, scripts enabled for sharp)"
|
||||
PNPM_STORE_DIR="$RELAY_DIR/.pnpm-store" \
|
||||
PNPM_HOME="$HOME/Library/pnpm" \
|
||||
pnpm install \
|
||||
--prod \
|
||||
--frozen-lockfile \
|
||||
--config.node-linker=hoisted \
|
||||
--config.ignore-workspace-root-check=true \
|
||||
--config.shared-workspace-lockfile=false \
|
||||
--modules-dir "$RELAY_DIR/node_modules" \
|
||||
--lockfile-dir "$ROOT_DIR" \
|
||||
--dir "$RELAY_DIR"
|
||||
|
||||
if [ -f "$CLI_BIN" ]; then
|
||||
echo "🔧 Copying CLI helper"
|
||||
cp "$CLI_BIN" "$APP_ROOT/Contents/MacOS/ClawdisCLI"
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
setHeartbeatsEnabled,
|
||||
type WebMonitorTuning,
|
||||
} from "../provider-web.js";
|
||||
import { defaultRuntime } from "../runtime.js";
|
||||
import { defaultRuntime, type RuntimeEnv } from "../runtime.js";
|
||||
import { VERSION } from "../version.js";
|
||||
import {
|
||||
resolveHeartbeatSeconds,
|
||||
@@ -252,10 +252,12 @@ Examples:
|
||||
}
|
||||
|
||||
const logs: string[] = [];
|
||||
const runtime = {
|
||||
const runtime: RuntimeEnv = {
|
||||
log: (msg: string) => logs.push(String(msg)),
|
||||
error: (msg: string) => logs.push(String(msg)),
|
||||
exit: (_code: number) => {},
|
||||
exit: (_code: number): never => {
|
||||
throw new Error("agentCommand requested exit");
|
||||
},
|
||||
};
|
||||
|
||||
const opts: {
|
||||
|
||||
Reference in New Issue
Block a user