drafted 1.11.27 → 1.11.29
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/install-mcp.sh +113 -1
- package/package.json +1 -1
package/install-mcp.sh
CHANGED
|
@@ -215,7 +215,23 @@ export PATH="$HOME/.drafted/npm-global/bin:$PATH"
|
|
|
215
215
|
|
|
216
216
|
step "Installing Drafted"
|
|
217
217
|
|
|
218
|
-
|
|
218
|
+
# Retry with back-off: a fresh `npm publish` can briefly 404/ETARGET on the CDN
|
|
219
|
+
# edge before the tarball propagates, so an updater that fires the instant a new
|
|
220
|
+
# version lands would otherwise report a spurious "update failed". Ride it out.
|
|
221
|
+
install_drafted_pkg() {
|
|
222
|
+
attempts=5; delay=4; n=1
|
|
223
|
+
while :; do
|
|
224
|
+
if npm install -g drafted@latest --force; then return 0; fi
|
|
225
|
+
if [ "$n" -ge "$attempts" ]; then return 1; fi
|
|
226
|
+
echo -e " ${YELLOW}npm install failed (attempt $n/$attempts) — retrying in ${delay}s (a new release may still be propagating to the npm CDN)...${RESET}"
|
|
227
|
+
sleep "$delay"
|
|
228
|
+
n=$((n + 1)); delay=$((delay * 2))
|
|
229
|
+
done
|
|
230
|
+
}
|
|
231
|
+
if ! install_drafted_pkg; then
|
|
232
|
+
echo -e " ${RED}npm install -g drafted@latest failed after multiple attempts.${RESET}"
|
|
233
|
+
exit 1
|
|
234
|
+
fi
|
|
219
235
|
hash -r 2>/dev/null || true
|
|
220
236
|
NPM_ROOT="$(npm root -g 2>/dev/null || true)"
|
|
221
237
|
MCP_SERVER_MODULE="$NPM_ROOT/drafted/mcp/server.mjs"
|
|
@@ -579,6 +595,92 @@ fi
|
|
|
579
595
|
|
|
580
596
|
# ── Update menu bar helper ───────────────────────────────────────
|
|
581
597
|
|
|
598
|
+
# Idempotently remove the legacy Swift menu-bar updater so it can neither run alongside the
|
|
599
|
+
# new desktop app nor be resurrected at next login. Safe to call when nothing legacy exists.
|
|
600
|
+
retire_legacy_updater() {
|
|
601
|
+
local uid legacy_plist
|
|
602
|
+
uid="$(id -u)"
|
|
603
|
+
legacy_plist="$HOME/Library/LaunchAgents/live.drafted.updater.plist"
|
|
604
|
+
launchctl bootout "gui/$uid/live.drafted.updater" >/dev/null 2>&1 || true
|
|
605
|
+
if [ -f "$legacy_plist" ]; then
|
|
606
|
+
launchctl bootout "gui/$uid" "$legacy_plist" >/dev/null 2>&1 || true
|
|
607
|
+
fi
|
|
608
|
+
rm -f "$legacy_plist" >/dev/null 2>&1 || true
|
|
609
|
+
pkill -x DraftedUpdater >/dev/null 2>&1 || true
|
|
610
|
+
rm -rf "/Applications/Drafted Updater.app" "$HOME/Applications/Drafted Updater.app" >/dev/null 2>&1 || true
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
# Install (or detect) the Tauri desktop app that replaces the legacy menu-bar updater.
|
|
614
|
+
# Returns 0 ONLY when a valid Drafted.app is present afterward, so the caller can safely
|
|
615
|
+
# retire the legacy updater. Returns 1 when no new bundle is available yet — the caller then
|
|
616
|
+
# falls back to building the legacy Swift updater, so users are never left without a tray.
|
|
617
|
+
install_desktop_app() {
|
|
618
|
+
local install_dir app_bundle app_exe uid plist tmp tarball url
|
|
619
|
+
install_dir="/Applications"
|
|
620
|
+
[ -w "$install_dir" ] || install_dir="$HOME/Applications"
|
|
621
|
+
mkdir -p "$install_dir"
|
|
622
|
+
app_bundle="$install_dir/Drafted.app"
|
|
623
|
+
|
|
624
|
+
if [ -n "${DRAFTED_DESKTOP_APP:-}" ] && [ -d "${DRAFTED_DESKTOP_APP}" ]; then
|
|
625
|
+
# Local prebuilt bundle — lets us test the cutover before the CDN endpoint exists.
|
|
626
|
+
rm -rf "$app_bundle" >/dev/null 2>&1 || true
|
|
627
|
+
ditto "${DRAFTED_DESKTOP_APP}" "$app_bundle" >/dev/null 2>&1 || true
|
|
628
|
+
else
|
|
629
|
+
# Signed bundle tarball (expects Drafted.app at the archive root). Until this endpoint is
|
|
630
|
+
# published the request 404s and we fall through to legacy — that is the cutover gate.
|
|
631
|
+
url="${DRAFTED_DESKTOP_URL:-$INSTALL_SERVER/desktop/Drafted-macos.tar.gz}"
|
|
632
|
+
tmp="$(mktemp -d)"
|
|
633
|
+
tarball="$tmp/Drafted-macos.tar.gz"
|
|
634
|
+
if curl -fsSL --max-time 120 "$url" -o "$tarball" >/dev/null 2>&1; then
|
|
635
|
+
rm -rf "$app_bundle" >/dev/null 2>&1 || true
|
|
636
|
+
tar -xzf "$tarball" -C "$install_dir" >/dev/null 2>&1 || true
|
|
637
|
+
fi
|
|
638
|
+
rm -rf "$tmp" >/dev/null 2>&1 || true
|
|
639
|
+
fi
|
|
640
|
+
|
|
641
|
+
# Validate: a real bundle whose declared executable exists. The bundle dir is Drafted.app
|
|
642
|
+
# (productName) but the binary is the Cargo bin name (drafted-desktop), so read the actual
|
|
643
|
+
# name from Info.plist rather than assuming. If absent/invalid, signal "not available yet".
|
|
644
|
+
local exe_name
|
|
645
|
+
exe_name="$(/usr/libexec/PlistBuddy -c 'Print :CFBundleExecutable' "$app_bundle/Contents/Info.plist" 2>/dev/null || true)"
|
|
646
|
+
app_exe="$app_bundle/Contents/MacOS/$exe_name"
|
|
647
|
+
if [ -z "$exe_name" ] || [ ! -x "$app_exe" ]; then
|
|
648
|
+
return 1
|
|
649
|
+
fi
|
|
650
|
+
|
|
651
|
+
# Clear quarantine so Gatekeeper doesn't block a freshly downloaded bundle.
|
|
652
|
+
xattr -dr com.apple.quarantine "$app_bundle" >/dev/null 2>&1 || true
|
|
653
|
+
|
|
654
|
+
# Register run-at-login for the new app (mirrors the legacy launch agent).
|
|
655
|
+
uid="$(id -u)"
|
|
656
|
+
plist="$HOME/Library/LaunchAgents/live.drafted.desktop.plist"
|
|
657
|
+
mkdir -p "$HOME/Library/LaunchAgents"
|
|
658
|
+
cat > "$plist" <<PLIST
|
|
659
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
660
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
661
|
+
<plist version="1.0">
|
|
662
|
+
<dict>
|
|
663
|
+
<key>Label</key>
|
|
664
|
+
<string>live.drafted.desktop</string>
|
|
665
|
+
<key>ProgramArguments</key>
|
|
666
|
+
<array>
|
|
667
|
+
<string>open</string>
|
|
668
|
+
<string>-a</string>
|
|
669
|
+
<string>$app_bundle</string>
|
|
670
|
+
</array>
|
|
671
|
+
<key>RunAtLoad</key>
|
|
672
|
+
<true/>
|
|
673
|
+
<key>KeepAlive</key>
|
|
674
|
+
<false/>
|
|
675
|
+
</dict>
|
|
676
|
+
</plist>
|
|
677
|
+
PLIST
|
|
678
|
+
launchctl bootout "gui/$uid" "$plist" >/dev/null 2>&1 || true
|
|
679
|
+
launchctl bootstrap "gui/$uid" "$plist" >/dev/null 2>&1 || true
|
|
680
|
+
open "$app_bundle" >/dev/null 2>&1 || true
|
|
681
|
+
return 0
|
|
682
|
+
}
|
|
683
|
+
|
|
582
684
|
install_update_menu_icon() {
|
|
583
685
|
if [ "${DRAFTED_HEADLESS:-}" = "1" ]; then
|
|
584
686
|
echo -e " ${YELLOW}Headless mode: skipping update menu icon.${RESET}"
|
|
@@ -588,6 +690,16 @@ install_update_menu_icon() {
|
|
|
588
690
|
echo -e " ${YELLOW}Update menu icon is only installed on macOS by this script.${RESET}"
|
|
589
691
|
return 0
|
|
590
692
|
fi
|
|
693
|
+
|
|
694
|
+
# Prefer the Tauri desktop app. If it installs (or is already present and valid), retire the
|
|
695
|
+
# legacy Swift updater so the two can never run side by side or be resurrected at next login.
|
|
696
|
+
if install_desktop_app; then
|
|
697
|
+
retire_legacy_updater
|
|
698
|
+
ok "Drafted desktop app"
|
|
699
|
+
return 0
|
|
700
|
+
fi
|
|
701
|
+
echo -e " ${YELLOW}Desktop app bundle not available yet; using the menu bar updater.${RESET}"
|
|
702
|
+
|
|
591
703
|
if ! command -v swiftc >/dev/null 2>&1; then
|
|
592
704
|
echo -e " ${YELLOW}Swift compiler not found; skipping macOS menu bar updater.${RESET}"
|
|
593
705
|
return 0
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "drafted",
|
|
3
|
-
"version": "1.11.
|
|
3
|
+
"version": "1.11.29",
|
|
4
4
|
"description": "Drafted — visual thinking surface for humans and AI agents. Renders HTML, markdown, images, and code as frames on a zoomable canvas, with MCP tools for AI agents and real-time sync for humans.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|