@cyrusxc5/better-ego-browser 0.0.0-stage → 0.3.3
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/LICENSE +21 -0
- package/README.en.md +109 -0
- package/README.md +108 -2
- package/THIRD_PARTY_LICENSE.txt +21 -0
- package/UPSTREAM.json +9 -0
- package/cordis.patch.yml +3 -0
- package/docs/demo.json +27 -0
- package/docs/images/dsh-ego-lite-windows-github.png +0 -0
- package/docs/images/ego-lite-windows-spaces.png +0 -0
- package/dsh/loopback/browser-action.mjs +21 -0
- package/dsh/loopback/server.mjs +108 -0
- package/dsh/plugin.mjs +20 -0
- package/dsh/skill-provider.mjs +20 -0
- package/package.json +65 -6
- package/skills/ego-browser/SKILL.md +42 -0
- package/skills/ego-browser/agents/openai.yaml +7 -0
- package/skills/ego-browser/assets/composer-icon.png +0 -0
- package/skills/ego-browser/assets/logo.png +0 -0
- package/skills/ego-browser/learnings/github/browser-tools/repo-stats.js +10 -0
- package/skills/ego-browser/learnings/github/manifest.json +61 -0
- package/skills/ego-browser/learnings/github/notes/overview.md +21 -0
- package/skills/ego-browser/learnings/github/tools/open-issues.js +24 -0
- package/skills/ego-browser/learnings/github/tools/search-repos.js +30 -0
- package/skills/ego-browser/learnings/google/browser-tools/autocomplete.js +11 -0
- package/skills/ego-browser/learnings/google/manifest.json +40 -0
- package/skills/ego-browser/learnings/google/notes/overview.md +20 -0
- package/skills/ego-browser/learnings/google/tools/search-extract.js +25 -0
- package/skills/ego-browser/learnings/x-com/browser-tools/extract-post.js +9 -0
- package/skills/ego-browser/learnings/x-com/manifest.json +51 -0
- package/skills/ego-browser/learnings/x-com/notes/overview.md +18 -0
- package/skills/ego-browser/learnings/x-com/notes/timeline.md +16 -0
- package/skills/ego-browser/learnings/x-com/tools/search-users.js +18 -0
- package/skills/ego-browser/learnings/x-com/tools/timeline.js +21 -0
- package/skills/ego-browser/references/clearing-state.md +64 -0
- package/skills/ego-browser/references/install-macos.md +59 -0
- package/skills/ego-browser/references/install-windows.md +58 -0
- package/skills/ego-browser/references/install.md +38 -0
- package/skills/ego-browser/scripts/install.sh +234 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
#v1.5 2026.06.04 17:16
|
|
3
|
+
|
|
4
|
+
set -eu
|
|
5
|
+
|
|
6
|
+
# Default package URL and installation paths.
|
|
7
|
+
DMG_URL_ARM64="https://cdn.ego.app/setup/macos/arm64/egolite-fHoqgZ74bOEM.dmg"
|
|
8
|
+
DMG_URL_X64="https://cdn.ego.app/setup/macos/x64/egolite-fHoqgZ74bOEM.dmg"
|
|
9
|
+
APP_NAME="ego lite"
|
|
10
|
+
APP_BUNDLE_NAME="$APP_NAME.app"
|
|
11
|
+
APP_PATH="/Applications/$APP_BUNDLE_NAME"
|
|
12
|
+
USER_APP_PATH="$HOME/Applications/$APP_BUNDLE_NAME"
|
|
13
|
+
EGO_BROWSER_HELPER_NAME="ego-browser"
|
|
14
|
+
|
|
15
|
+
# Temporary directories created when mounting the DMG; cleaned up on exit.
|
|
16
|
+
TEMP_DIR=""
|
|
17
|
+
MOUNT_DIR=""
|
|
18
|
+
DMG_ATTACHED=""
|
|
19
|
+
|
|
20
|
+
log() {
|
|
21
|
+
printf '%s\n' "$*" >&2
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
die() {
|
|
25
|
+
log "error: $*"
|
|
26
|
+
exit 1
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
require_command() {
|
|
30
|
+
command -v "$1" >/dev/null 2>&1 || die "missing required command: $1"
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
select_dmg_url() {
|
|
34
|
+
if [ "$(uname -m)" = "arm64" ]; then
|
|
35
|
+
printf '%s\n' "$DMG_URL_ARM64"
|
|
36
|
+
else
|
|
37
|
+
printf '%s\n' "$DMG_URL_X64"
|
|
38
|
+
fi
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
run_with_sudo_if_needed() {
|
|
42
|
+
# Try without elevated privileges first; fall back to sudo to avoid unnecessary prompts.
|
|
43
|
+
if "$@"; then
|
|
44
|
+
return 0
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
if [ "$(id -u)" -eq 0 ]; then
|
|
48
|
+
return 1
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
require_command sudo
|
|
52
|
+
sudo "$@"
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
cleanup() {
|
|
56
|
+
# Detach the DMG and remove the temp directory on success, failure, or Ctrl+C.
|
|
57
|
+
if [ "$DMG_ATTACHED" = "1" ]; then
|
|
58
|
+
if ! hdiutil detach "$MOUNT_DIR" -quiet >/dev/null 2>&1; then
|
|
59
|
+
log "warning: failed to detach $MOUNT_DIR"
|
|
60
|
+
fi
|
|
61
|
+
DMG_ATTACHED=""
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
if [ -n "$TEMP_DIR" ] && [ -d "$TEMP_DIR" ]; then
|
|
65
|
+
rm -rf "$TEMP_DIR" >/dev/null 2>&1 ||
|
|
66
|
+
log "warning: failed to remove temporary directory: $TEMP_DIR"
|
|
67
|
+
fi
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
strip_quarantine_attributes() {
|
|
71
|
+
app_path="$1"
|
|
72
|
+
run_with_sudo_if_needed xattr -dr com.apple.quarantine "$app_path" \
|
|
73
|
+
>/dev/null 2>&1 || true
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
trap cleanup EXIT HUP INT TERM
|
|
77
|
+
|
|
78
|
+
find_ego_browser_in_app() {
|
|
79
|
+
app_path="$1"
|
|
80
|
+
|
|
81
|
+
[ -d "$app_path/Contents" ] || return 1
|
|
82
|
+
|
|
83
|
+
# A Chromium app bundle may contain multiple versions; prefer the one under Current.
|
|
84
|
+
for candidate in "$app_path"/Contents/Frameworks/*.framework/Versions/Current/Helpers/"$EGO_BROWSER_HELPER_NAME"; do
|
|
85
|
+
if [ -x "$candidate" ]; then
|
|
86
|
+
printf '%s\n' "$candidate"
|
|
87
|
+
return 0
|
|
88
|
+
fi
|
|
89
|
+
done
|
|
90
|
+
|
|
91
|
+
# ego-browser may live in various locations inside the bundle; search under Contents.
|
|
92
|
+
browser_path=$(
|
|
93
|
+
find "$app_path/Contents" -type f -name "$EGO_BROWSER_HELPER_NAME" 2>/dev/null |
|
|
94
|
+
while IFS= read -r candidate; do
|
|
95
|
+
if [ -x "$candidate" ]; then
|
|
96
|
+
printf '%s\n' "$candidate"
|
|
97
|
+
break
|
|
98
|
+
fi
|
|
99
|
+
done
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
if [ -n "$browser_path" ]; then
|
|
103
|
+
printf '%s\n' "$browser_path"
|
|
104
|
+
return 0
|
|
105
|
+
fi
|
|
106
|
+
|
|
107
|
+
return 1
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
is_ego_lite_app() {
|
|
111
|
+
app_path="$1"
|
|
112
|
+
|
|
113
|
+
# The directory exists and contains a working ego-browser — ego lite is considered installed.
|
|
114
|
+
[ -d "$app_path" ] || return 1
|
|
115
|
+
find_ego_browser_in_app "$app_path" >/dev/null
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
find_ego_lite_app() {
|
|
119
|
+
for app_path in "$APP_PATH" "$USER_APP_PATH"; do
|
|
120
|
+
if is_ego_lite_app "$app_path"; then
|
|
121
|
+
printf '%s\n' "$app_path"
|
|
122
|
+
return 0
|
|
123
|
+
fi
|
|
124
|
+
done
|
|
125
|
+
|
|
126
|
+
for apps_dir in "$(dirname "$APP_PATH")" "$(dirname "$USER_APP_PATH")"; do
|
|
127
|
+
[ -d "$apps_dir" ] || continue
|
|
128
|
+
|
|
129
|
+
app_path=$(
|
|
130
|
+
find "$apps_dir" -maxdepth 1 -type d -iname "$APP_BUNDLE_NAME" 2>/dev/null |
|
|
131
|
+
while IFS= read -r candidate; do
|
|
132
|
+
if is_ego_lite_app "$candidate"; then
|
|
133
|
+
printf '%s\n' "$candidate"
|
|
134
|
+
break
|
|
135
|
+
fi
|
|
136
|
+
done
|
|
137
|
+
)
|
|
138
|
+
if [ -n "$app_path" ]; then
|
|
139
|
+
printf '%s\n' "$app_path"
|
|
140
|
+
return 0
|
|
141
|
+
fi
|
|
142
|
+
done
|
|
143
|
+
|
|
144
|
+
return 1
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
install_ego_lite() {
|
|
148
|
+
require_command curl
|
|
149
|
+
require_command hdiutil
|
|
150
|
+
|
|
151
|
+
# Download and mount the DMG in an isolated temp directory to avoid polluting the CWD.
|
|
152
|
+
temp_base_dir=${TMPDIR:-/tmp}
|
|
153
|
+
temp_base_dir=${temp_base_dir%/}
|
|
154
|
+
TEMP_DIR=$(mktemp -d "$temp_base_dir/ego-lite-install.XXXXXX")
|
|
155
|
+
MOUNT_DIR="$TEMP_DIR/mount"
|
|
156
|
+
dmg_path="$TEMP_DIR/egolite.dmg"
|
|
157
|
+
dmg_url=$(select_dmg_url)
|
|
158
|
+
mkdir -p "$MOUNT_DIR"
|
|
159
|
+
|
|
160
|
+
log "$APP_NAME is not installed. Downloading $dmg_url ..."
|
|
161
|
+
curl -fL --retry 3 --output "$dmg_path" "$dmg_url" ||
|
|
162
|
+
die "failed to download $APP_NAME from $dmg_url"
|
|
163
|
+
|
|
164
|
+
log "Mounting installer ..."
|
|
165
|
+
hdiutil attach "$dmg_path" -nobrowse -readonly -mountpoint "$MOUNT_DIR" \
|
|
166
|
+
>/dev/null
|
|
167
|
+
DMG_ATTACHED="1"
|
|
168
|
+
|
|
169
|
+
# Handle DMGs that contain the app bundle directly.
|
|
170
|
+
app_in_dmg=$(
|
|
171
|
+
find "$MOUNT_DIR" -maxdepth 2 \
|
|
172
|
+
-type d -iname "$APP_BUNDLE_NAME" |
|
|
173
|
+
head -n 1
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
if [ -n "$app_in_dmg" ]; then
|
|
177
|
+
staged_app="$TEMP_DIR/$APP_BUNDLE_NAME"
|
|
178
|
+
|
|
179
|
+
log "Installing $APP_NAME to $APP_PATH ..."
|
|
180
|
+
ditto "$app_in_dmg" "$staged_app" ||
|
|
181
|
+
die "failed to stage $APP_NAME from installer"
|
|
182
|
+
find_ego_browser_in_app "$staged_app" >/dev/null ||
|
|
183
|
+
die "installed $APP_NAME does not contain $EGO_BROWSER_HELPER_NAME"
|
|
184
|
+
|
|
185
|
+
# Strip quarantine attributes to prevent Gatekeeper from blocking the first launch.
|
|
186
|
+
log "Removing quarantine attributes from $APP_NAME ..."
|
|
187
|
+
xattr -dr com.apple.quarantine "$staged_app" \
|
|
188
|
+
>/dev/null 2>&1 || true
|
|
189
|
+
|
|
190
|
+
if [ -d "$APP_PATH" ]; then
|
|
191
|
+
run_with_sudo_if_needed rm -rf "$APP_PATH" ||
|
|
192
|
+
die "failed to replace existing $APP_PATH"
|
|
193
|
+
fi
|
|
194
|
+
run_with_sudo_if_needed mv "$staged_app" "$APP_PATH" ||
|
|
195
|
+
die "failed to move $APP_NAME to $APP_PATH"
|
|
196
|
+
return 0
|
|
197
|
+
fi
|
|
198
|
+
|
|
199
|
+
# Fall back to pkg installer if the DMG contains a .pkg instead of an app bundle.
|
|
200
|
+
pkg_in_dmg=$(
|
|
201
|
+
find "$MOUNT_DIR" -maxdepth 2 -type f -name "*.pkg" |
|
|
202
|
+
head -n 1
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
if [ -n "$pkg_in_dmg" ]; then
|
|
206
|
+
log "Installing $APP_NAME package ..."
|
|
207
|
+
run_with_sudo_if_needed installer -pkg "$pkg_in_dmg" -target / ||
|
|
208
|
+
die "failed to install $APP_NAME package"
|
|
209
|
+
return 0
|
|
210
|
+
fi
|
|
211
|
+
|
|
212
|
+
die "cannot find $APP_NAME app or pkg in mounted DMG"
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
main() {
|
|
216
|
+
[ "$(uname -s)" = "Darwin" ] || die "this script only supports macOS; on Windows and other platforms install from https://lite.ego.app/"
|
|
217
|
+
|
|
218
|
+
# Install first if not present; otherwise use the ego-browser bundled inside the app.
|
|
219
|
+
installed_app_path=$(find_ego_lite_app || true)
|
|
220
|
+
if [ -z "$installed_app_path" ]; then
|
|
221
|
+
install_ego_lite
|
|
222
|
+
installed_app_path=$(find_ego_lite_app || true)
|
|
223
|
+
[ -n "$installed_app_path" ] ||
|
|
224
|
+
die "$APP_NAME install completed, but app was not found"
|
|
225
|
+
fi
|
|
226
|
+
|
|
227
|
+
strip_quarantine_attributes "$installed_app_path"
|
|
228
|
+
cleanup
|
|
229
|
+
|
|
230
|
+
log "Launching $APP_NAME ..."
|
|
231
|
+
exec open "$installed_app_path"
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
main
|