@qearlyao/familiar 0.1.1 → 0.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/README.md +9 -2
- package/dist/agent.js +0 -10
- package/dist/cli.js +3 -1
- package/dist/hot-reload.js +3 -1
- package/package.json +1 -1
- package/scripts/install.ps1 +65 -12
- package/scripts/install.sh +83 -9
package/README.md
CHANGED
|
@@ -30,7 +30,13 @@ irm https://raw.githubusercontent.com/qearlyao/familiar/main/scripts/install.ps1
|
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
The installer checks Node/npm, installs Familiar globally, and initializes
|
|
33
|
-
|
|
33
|
+
or refreshes missing default files in `~/.familiar`.
|
|
34
|
+
|
|
35
|
+
Installer options:
|
|
36
|
+
|
|
37
|
+
- macOS/Linux: `--workspace <path>`, `--with-browser`, `--install-browser-deps`, `--skip-init`, `--package <spec>`.
|
|
38
|
+
- Windows PowerShell: `-Workspace <path>`, `-WithBrowser`, `-InstallBrowserDeps`, `-SkipInit`, `-Package <spec>`, `-BrowserHarnessDir <path>`.
|
|
39
|
+
- `--package` / `-Package` installs the exact npm package spec you provide. Use trusted specs only.
|
|
34
40
|
|
|
35
41
|
Manual npm install:
|
|
36
42
|
|
|
@@ -171,7 +177,8 @@ Windows PowerShell:
|
|
|
171
177
|
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/qearlyao/familiar/main/scripts/install.ps1))) -WithBrowser
|
|
172
178
|
```
|
|
173
179
|
|
|
174
|
-
- `--with-browser` installs OpenCLI with npm and browser-harness from its upstream repo with `uv`; it requires `git`, `uv`, and Python 3.11+.
|
|
180
|
+
- `--with-browser` / `-WithBrowser` installs OpenCLI with npm and browser-harness from its upstream repo with `uv`; it requires `git`, `uv`, and Python 3.11+.
|
|
181
|
+
- If `uv` or Python 3.11+ is missing, the installer asks whether to install the missing browser dependency. Use `--install-browser-deps` / `-InstallBrowserDeps` for non-interactive installs.
|
|
175
182
|
- `browser-harness` is best for attaching to your already-running Chrome via CDP.
|
|
176
183
|
- OpenCLI is best for site adapters, owned sessions, and unattended Browser Bridge flows.
|
|
177
184
|
- OpenCLI: [jackwener/OpenCLI](https://github.com/jackwener/OpenCLI)
|
package/dist/agent.js
CHANGED
|
@@ -415,16 +415,6 @@ export async function createFamiliarAgent(config, settings, memoryService, optio
|
|
|
415
415
|
session.agent.state.tools = createFamiliarTools(config, session.mediaSink, () => session.referenceAttachments, memoryService);
|
|
416
416
|
session.agent.state.thinkingLevel = session.thinkingLevel;
|
|
417
417
|
};
|
|
418
|
-
const refreshSession = (session, sessionKey) => {
|
|
419
|
-
const { model } = resolveChannelModel(sessionKey);
|
|
420
|
-
const thinkingLevel = resolveChannelThinkingLevel(sessionKey, model).value;
|
|
421
|
-
session.model = model;
|
|
422
|
-
session.thinkingLevel = thinkingLevel;
|
|
423
|
-
session.agent.state.systemPrompt = systemPrompt;
|
|
424
|
-
session.agent.state.model = model;
|
|
425
|
-
session.agent.state.thinkingLevel = thinkingLevel;
|
|
426
|
-
session.agent.state.tools = createFamiliarTools(config, session.mediaSink, () => session.referenceAttachments, memoryService);
|
|
427
|
-
};
|
|
428
418
|
const prepareReload = async () => {
|
|
429
419
|
const nextConfig = (await options.reloadConfig?.()) ?? config;
|
|
430
420
|
const nextPersona = await loadPersona(nextConfig);
|
package/dist/cli.js
CHANGED
|
@@ -136,7 +136,9 @@ async function runDaemon(workspaceInput) {
|
|
|
136
136
|
setTimeout(() => void stop(75), RESTART_EXIT_DELAY_MS);
|
|
137
137
|
return "Restart requested. If Familiar is managed by launchd/systemd, it should come back automatically; otherwise run familiar run again.";
|
|
138
138
|
};
|
|
139
|
-
discordDaemon = await startDiscordDaemon(config, familiarAgent, settings, memoryService, {
|
|
139
|
+
discordDaemon = await startDiscordDaemon(config, familiarAgent, settings, memoryService, {
|
|
140
|
+
restart: requestRestart,
|
|
141
|
+
});
|
|
140
142
|
webDaemon = await startWebDaemon(config, familiarAgent, discordDaemon, { restart: requestRestart });
|
|
141
143
|
console.log(`familiar running for workspace ${config.workspacePath}`);
|
|
142
144
|
console.log("agent sessions are created per channel");
|
package/dist/hot-reload.js
CHANGED
|
@@ -91,7 +91,9 @@ export function startWorkspaceHotReload(options) {
|
|
|
91
91
|
(basename(dirPath) === SKILLS_DIR || relative(workspacePath, dirPath).startsWith(`${SKILLS_DIR}${sep}`))) {
|
|
92
92
|
void refreshSkillWatchers();
|
|
93
93
|
}
|
|
94
|
-
if (!filename ||
|
|
94
|
+
if (!filename ||
|
|
95
|
+
shouldReloadForPath(workspacePath, changedPath) ||
|
|
96
|
+
shouldReloadForPath(workspacePath, dirPath)) {
|
|
95
97
|
scheduleReload(relative(workspacePath, changedPath) || relative(workspacePath, dirPath) || ".");
|
|
96
98
|
}
|
|
97
99
|
});
|
package/package.json
CHANGED
package/scripts/install.ps1
CHANGED
|
@@ -3,6 +3,7 @@ param(
|
|
|
3
3
|
[string]$Package = "@qearlyao/familiar@latest",
|
|
4
4
|
[string]$BrowserHarnessDir = (Join-Path (Join-Path $HOME "Developer") "browser-harness"),
|
|
5
5
|
[switch]$WithBrowser,
|
|
6
|
+
[switch]$InstallBrowserDeps,
|
|
6
7
|
[switch]$SkipInit
|
|
7
8
|
)
|
|
8
9
|
|
|
@@ -14,6 +15,47 @@ function Require-Command($Name) {
|
|
|
14
15
|
}
|
|
15
16
|
}
|
|
16
17
|
|
|
18
|
+
function Update-BrowserDepPath {
|
|
19
|
+
$candidates = @((Join-Path $HOME ".local\bin"), (Join-Path $HOME ".cargo\bin"))
|
|
20
|
+
foreach ($candidate in $candidates) {
|
|
21
|
+
if ((Test-Path $candidate) -and (($env:PATH -split [IO.Path]::PathSeparator) -notcontains $candidate)) {
|
|
22
|
+
$env:PATH = "$candidate$([IO.Path]::PathSeparator)$env:PATH"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function Confirm-BrowserDepInstall($Message) {
|
|
28
|
+
if ($InstallBrowserDeps) {
|
|
29
|
+
return $true
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
$answer = Read-Host "$Message Install it now? [y/N]"
|
|
33
|
+
return $answer -match '^(y|yes)$'
|
|
34
|
+
} catch {
|
|
35
|
+
return $false
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function Install-Uv {
|
|
40
|
+
Write-Host "Installing uv for browser-harness..."
|
|
41
|
+
irm https://astral.sh/uv/install.ps1 | iex
|
|
42
|
+
Update-BrowserDepPath
|
|
43
|
+
if (-not (Get-Command uv -ErrorAction SilentlyContinue)) {
|
|
44
|
+
throw "uv installer finished, but uv is not on PATH. Open a new terminal or add $HOME\.local\bin to PATH."
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function Ensure-Uv {
|
|
49
|
+
if (Get-Command uv -ErrorAction SilentlyContinue) {
|
|
50
|
+
return
|
|
51
|
+
}
|
|
52
|
+
if (Confirm-BrowserDepInstall "uv is required for browser-harness but was not found.") {
|
|
53
|
+
Install-Uv
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
throw "Missing required command: uv. Rerun with -WithBrowser -InstallBrowserDeps to install uv and Python 3.11 automatically."
|
|
57
|
+
}
|
|
58
|
+
|
|
17
59
|
function Test-Python311($Command, $PythonArgs = @()) {
|
|
18
60
|
& $Command @PythonArgs -c "import sys; raise SystemExit(0 if sys.version_info >= (3, 11) else 1)" *> $null
|
|
19
61
|
return $LASTEXITCODE -eq 0
|
|
@@ -32,15 +74,31 @@ function Resolve-Python311 {
|
|
|
32
74
|
if ($py -and (Test-Python311 $py.Source @("-3.11"))) {
|
|
33
75
|
return @{ Command = $py.Source; Args = @("-3.11"); UvPython = "3.11" }
|
|
34
76
|
}
|
|
35
|
-
|
|
77
|
+
return $null
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function Ensure-Python311 {
|
|
81
|
+
$python311 = Resolve-Python311
|
|
82
|
+
if ($python311) {
|
|
83
|
+
return $python311
|
|
84
|
+
}
|
|
85
|
+
if (Confirm-BrowserDepInstall "Python 3.11+ is required for browser-harness but was not found.") {
|
|
86
|
+
Write-Host "Installing Python 3.11 with uv for browser-harness..."
|
|
87
|
+
& uv python install 3.11
|
|
88
|
+
if ($LASTEXITCODE -ne 0) {
|
|
89
|
+
throw "Python 3.11 install failed."
|
|
90
|
+
}
|
|
91
|
+
return @{ Command = "uv"; Args = @("python", "find", "3.11"); UvPython = "3.11" }
|
|
92
|
+
}
|
|
93
|
+
throw "browser-harness requires Python 3.11 or newer. Rerun with -WithBrowser -InstallBrowserDeps to install uv-managed Python 3.11 automatically."
|
|
36
94
|
}
|
|
37
95
|
|
|
38
96
|
Require-Command node
|
|
39
97
|
Require-Command npm
|
|
40
98
|
if ($WithBrowser) {
|
|
41
99
|
Require-Command git
|
|
42
|
-
|
|
43
|
-
$Python311 =
|
|
100
|
+
Ensure-Uv
|
|
101
|
+
$Python311 = Ensure-Python311
|
|
44
102
|
}
|
|
45
103
|
|
|
46
104
|
$nodeVersion = (& node -p "process.versions.node").Trim()
|
|
@@ -105,15 +163,10 @@ if (-not (Get-Command familiar -ErrorAction SilentlyContinue)) {
|
|
|
105
163
|
}
|
|
106
164
|
|
|
107
165
|
if (-not $SkipInit) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
Write-Host "Initializing workspace at $Workspace..."
|
|
113
|
-
& familiar init $Workspace
|
|
114
|
-
if ($LASTEXITCODE -ne 0) {
|
|
115
|
-
throw "familiar init failed."
|
|
116
|
-
}
|
|
166
|
+
Write-Host "Initializing or refreshing workspace defaults at $Workspace..."
|
|
167
|
+
& familiar init $Workspace
|
|
168
|
+
if ($LASTEXITCODE -ne 0) {
|
|
169
|
+
throw "familiar init failed."
|
|
117
170
|
}
|
|
118
171
|
}
|
|
119
172
|
|
package/scripts/install.sh
CHANGED
|
@@ -5,6 +5,7 @@ PACKAGE="@qearlyao/familiar@latest"
|
|
|
5
5
|
WORKSPACE="${HOME}/.familiar"
|
|
6
6
|
BROWSER_HARNESS_DIR="${HOME}/Developer/browser-harness"
|
|
7
7
|
WITH_BROWSER=0
|
|
8
|
+
INSTALL_BROWSER_DEPS=0
|
|
8
9
|
SKIP_INIT=0
|
|
9
10
|
|
|
10
11
|
usage() {
|
|
@@ -14,6 +15,8 @@ Usage: install.sh [options]
|
|
|
14
15
|
Options:
|
|
15
16
|
--workspace <path> Workspace path to initialize. Defaults to ~/.familiar.
|
|
16
17
|
--with-browser Also install optional OpenCLI and browser-harness helpers.
|
|
18
|
+
--install-browser-deps
|
|
19
|
+
With --with-browser, install missing uv/Python 3.11 browser deps without prompting.
|
|
17
20
|
--skip-init Install familiar but do not run familiar init.
|
|
18
21
|
--package <spec> npm package spec to install. Defaults to @qearlyao/familiar@latest.
|
|
19
22
|
Advanced: installs the exact npm spec provided; use trusted specs only.
|
|
@@ -35,6 +38,10 @@ while [ "$#" -gt 0 ]; do
|
|
|
35
38
|
WITH_BROWSER=1
|
|
36
39
|
shift
|
|
37
40
|
;;
|
|
41
|
+
--install-browser-deps)
|
|
42
|
+
INSTALL_BROWSER_DEPS=1
|
|
43
|
+
shift
|
|
44
|
+
;;
|
|
38
45
|
--skip-init)
|
|
39
46
|
SKIP_INIT=1
|
|
40
47
|
shift
|
|
@@ -66,6 +73,63 @@ need_command() {
|
|
|
66
73
|
fi
|
|
67
74
|
}
|
|
68
75
|
|
|
76
|
+
refresh_browser_dep_path() {
|
|
77
|
+
for candidate in "${HOME}/.local/bin" "${HOME}/.cargo/bin"; do
|
|
78
|
+
if [ -d "$candidate" ]; then
|
|
79
|
+
case ":${PATH}:" in
|
|
80
|
+
*":${candidate}:"*) ;;
|
|
81
|
+
*) PATH="${candidate}:${PATH}" ;;
|
|
82
|
+
esac
|
|
83
|
+
fi
|
|
84
|
+
done
|
|
85
|
+
export PATH
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
confirm_browser_dep_install() {
|
|
89
|
+
if [ "$INSTALL_BROWSER_DEPS" -eq 1 ]; then
|
|
90
|
+
return 0
|
|
91
|
+
fi
|
|
92
|
+
if [ -r /dev/tty ] && [ -w /dev/tty ]; then
|
|
93
|
+
printf "%s Install it now? [y/N] " "$1" >/dev/tty
|
|
94
|
+
read -r answer </dev/tty || answer=""
|
|
95
|
+
case "$answer" in
|
|
96
|
+
y | Y | yes | YES) return 0 ;;
|
|
97
|
+
esac
|
|
98
|
+
fi
|
|
99
|
+
return 1
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
install_uv() {
|
|
103
|
+
echo "Installing uv for browser-harness..."
|
|
104
|
+
if command -v curl >/dev/null 2>&1; then
|
|
105
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
106
|
+
elif command -v wget >/dev/null 2>&1; then
|
|
107
|
+
wget -qO- https://astral.sh/uv/install.sh | sh
|
|
108
|
+
else
|
|
109
|
+
echo "Missing curl or wget, which is required to install uv automatically." >&2
|
|
110
|
+
echo "Install uv manually from https://docs.astral.sh/uv/ and rerun with --with-browser." >&2
|
|
111
|
+
exit 1
|
|
112
|
+
fi
|
|
113
|
+
refresh_browser_dep_path
|
|
114
|
+
if ! command -v uv >/dev/null 2>&1; then
|
|
115
|
+
echo "uv installer finished, but uv is not on PATH. Open a new terminal or add ~/.local/bin to PATH." >&2
|
|
116
|
+
exit 1
|
|
117
|
+
fi
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
ensure_uv() {
|
|
121
|
+
if command -v uv >/dev/null 2>&1; then
|
|
122
|
+
return 0
|
|
123
|
+
fi
|
|
124
|
+
if confirm_browser_dep_install "uv is required for browser-harness but was not found."; then
|
|
125
|
+
install_uv
|
|
126
|
+
return 0
|
|
127
|
+
fi
|
|
128
|
+
echo "Missing required command: uv" >&2
|
|
129
|
+
echo "Rerun with --with-browser --install-browser-deps to install uv and Python 3.11 automatically." >&2
|
|
130
|
+
exit 1
|
|
131
|
+
}
|
|
132
|
+
|
|
69
133
|
find_python() {
|
|
70
134
|
PYTHON_PATH=""
|
|
71
135
|
for candidate in python3 python; do
|
|
@@ -77,7 +141,21 @@ find_python() {
|
|
|
77
141
|
fi
|
|
78
142
|
fi
|
|
79
143
|
done
|
|
80
|
-
|
|
144
|
+
return 1
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
ensure_python() {
|
|
148
|
+
if find_python; then
|
|
149
|
+
return 0
|
|
150
|
+
fi
|
|
151
|
+
if confirm_browser_dep_install "Python 3.11+ is required for browser-harness but was not found."; then
|
|
152
|
+
echo "Installing Python 3.11 with uv for browser-harness..."
|
|
153
|
+
uv python install 3.11
|
|
154
|
+
PYTHON_PATH="3.11"
|
|
155
|
+
return 0
|
|
156
|
+
fi
|
|
157
|
+
echo "browser-harness requires Python 3.11 or newer." >&2
|
|
158
|
+
echo "Rerun with --with-browser --install-browser-deps to install uv-managed Python 3.11 automatically." >&2
|
|
81
159
|
exit 1
|
|
82
160
|
}
|
|
83
161
|
|
|
@@ -85,8 +163,8 @@ need_command node
|
|
|
85
163
|
need_command npm
|
|
86
164
|
if [ "$WITH_BROWSER" -eq 1 ]; then
|
|
87
165
|
need_command git
|
|
88
|
-
|
|
89
|
-
|
|
166
|
+
ensure_uv
|
|
167
|
+
ensure_python
|
|
90
168
|
fi
|
|
91
169
|
|
|
92
170
|
NODE_VERSION="$(node -p "process.versions.node")"
|
|
@@ -127,12 +205,8 @@ if ! command -v familiar >/dev/null 2>&1; then
|
|
|
127
205
|
fi
|
|
128
206
|
|
|
129
207
|
if [ "$SKIP_INIT" -eq 0 ]; then
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
else
|
|
133
|
-
echo "Initializing workspace at ${WORKSPACE}..."
|
|
134
|
-
familiar init "$WORKSPACE"
|
|
135
|
-
fi
|
|
208
|
+
echo "Initializing or refreshing workspace defaults at ${WORKSPACE}..."
|
|
209
|
+
familiar init "$WORKSPACE"
|
|
136
210
|
fi
|
|
137
211
|
|
|
138
212
|
cat <<EOF
|