R1
This commit is contained in:
Executable
+25
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
VERSION="${JARVIS_VERSION:-$(node -p "require('${ROOT_DIR}/package.json').version")}"
|
||||
ARCH="${JARVIS_DEB_ARCH:-$(dpkg --print-architecture)}"
|
||||
OUT_DIR="${ROOT_DIR}/dist"
|
||||
PKG_DIR="${OUT_DIR}/jarvis-qvac_${VERSION}_${ARCH}"
|
||||
rm -rf "${PKG_DIR}"
|
||||
mkdir -p "${PKG_DIR}/DEBIAN" "${PKG_DIR}/usr/lib/jarvis-qvac" "${PKG_DIR}/usr/share/doc/jarvis-qvac"
|
||||
cat > "${PKG_DIR}/DEBIAN/control" <<EOF
|
||||
Package: jarvis-qvac
|
||||
Version: ${VERSION}
|
||||
Section: utils
|
||||
Priority: optional
|
||||
Architecture: ${ARCH}
|
||||
Maintainer: JARVIS-QVAC maintainers
|
||||
Description: Local GPU-backed GNOME voice assistant
|
||||
JARVIS-QVAC is a local-first voice assistant for Ubuntu GNOME.
|
||||
EOF
|
||||
tar --exclude='.git' --exclude='./.agents' --exclude='./.codex' --exclude='./dist' --exclude='./node_modules' --exclude='*/node_modules' --exclude='*/__pycache__' --exclude='*.pyc' -cf - -C "${ROOT_DIR}" . | tar -xf - -C "${PKG_DIR}/usr/lib/jarvis-qvac"
|
||||
cp "${ROOT_DIR}/README.md" "${PKG_DIR}/usr/share/doc/jarvis-qvac/README.md"
|
||||
cp "${ROOT_DIR}/docs/RELEASE.md" "${PKG_DIR}/usr/share/doc/jarvis-qvac/RELEASE.md"
|
||||
dpkg-deb --build --root-owner-group "${PKG_DIR}" "${OUT_DIR}/jarvis-qvac_${VERSION}_${ARCH}.deb" >/dev/null
|
||||
rm -rf "${PKG_DIR}"
|
||||
echo "${OUT_DIR}/jarvis-qvac_${VERSION}_${ARCH}.deb"
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
OUT_DIR="${ROOT_DIR}/dist"
|
||||
mkdir -p "${OUT_DIR}"
|
||||
rm -f "${OUT_DIR}/jarvis-qvac-extension.zip"
|
||||
( cd "${ROOT_DIR}/apps/gnome-extension" && zip -q -r "${OUT_DIR}/jarvis-qvac-extension.zip" "[email protected]" -x '*/__pycache__/*' -x '*.pyc' )
|
||||
test -s "${OUT_DIR}/jarvis-qvac-extension.zip"
|
||||
echo "${OUT_DIR}/jarvis-qvac-extension.zip"
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
cd "${ROOT_DIR}"
|
||||
mkdir -p dist
|
||||
rm -f dist/jarvis-qvac_*.deb dist/jarvis-qvac-extension.zip dist/SHA256SUMS
|
||||
bash packaging/build-extension.sh
|
||||
bash packaging/build-deb.sh
|
||||
(cd dist && sha256sum jarvis-qvac_*.deb jarvis-qvac-extension.zip > SHA256SUMS)
|
||||
echo "Release artifacts written to ${ROOT_DIR}/dist"
|
||||
Executable
+46
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
cd "${ROOT_DIR}"
|
||||
echo "JARVIS-QVAC first-run setup"
|
||||
echo "The daemon is GPU-gated and keeps QVAC behind one master owner."
|
||||
echo
|
||||
echo "[1/4] GPU and QVAC preflight"
|
||||
npm run gpu-doctor || true
|
||||
npm run qvac:doctor || true
|
||||
echo
|
||||
echo "[2/4] Microphone and PipeWire preflight"
|
||||
npm run voice-doctor || true
|
||||
echo
|
||||
echo "[3/5] Wake phrase and model profile"
|
||||
read -r -p "Wake phrase [hey jarvis]: " WAKE_PHRASE
|
||||
WAKE_PHRASE="${WAKE_PHRASE:-hey jarvis}"
|
||||
read -r -p "Model profile [laptop-8gb/laptop-16gb/desktop-gpu] (default: laptop-16gb): " MODEL_PROFILE
|
||||
MODEL_PROFILE="${MODEL_PROFILE:-laptop-16gb}"
|
||||
case "${MODEL_PROFILE}" in
|
||||
laptop-8gb|laptop-16gb|desktop-gpu) ;;
|
||||
*) echo "Unknown model profile: ${MODEL_PROFILE}" >&2; exit 2 ;;
|
||||
esac
|
||||
read -r -p "Enable TTS preview? [Y/n]: " TTS_CHOICE
|
||||
TTS_ENABLED=true
|
||||
[[ "${TTS_CHOICE:-Y}" =~ ^[Nn]$ ]] && TTS_ENABLED=false
|
||||
mkdir -p "${HOME}/.config/jarvis"
|
||||
node -e 'const fs=require("fs"); const p=process.argv[1], phrase=process.argv[2], profile=process.argv[3], tts=process.argv[4]==="true"; let c={}; try{c=JSON.parse(fs.readFileSync(p,"utf8"))}catch{}; Object.assign(c,{wakePhrase:phrase,modelProfile:profile,ttsEnabled:tts}); fs.writeFileSync(p,JSON.stringify(c,null,2)+"\n")' "${HOME}/.config/jarvis/config.json" "${WAKE_PHRASE}" "${MODEL_PROFILE}" "${TTS_ENABLED}"
|
||||
echo "Saved wake phrase: ${WAKE_PHRASE}; model profile: ${MODEL_PROFILE}; TTS: ${TTS_ENABLED}"
|
||||
echo
|
||||
echo "[4/5] TTS preview"
|
||||
if [[ "${TTS_ENABLED}" == true && -n "${DBUS_SESSION_BUS_ADDRESS:-}" ]]; then
|
||||
busctl --user call io.qvac.Jarvis /io/qvac/Jarvis io.qvac.Jarvis.Session Say s "JARVIS local voice preview" || true
|
||||
else
|
||||
echo "Session D-Bus is unavailable or TTS is disabled; preview skipped."
|
||||
fi
|
||||
echo
|
||||
echo "[5/5] Typed smoke test"
|
||||
read -r -p "Type a test prompt (default: say hello): " PROMPT
|
||||
PROMPT="${PROMPT:-say hello}"
|
||||
if command -v busctl >/dev/null && [[ -n "${DBUS_SESSION_BUS_ADDRESS:-}" ]]; then
|
||||
busctl --user call io.qvac.Jarvis /io/qvac/Jarvis io.qvac.Jarvis.Session Ask s "${PROMPT}" || true
|
||||
else
|
||||
echo "Session D-Bus is unavailable; saved setup and skipped live prompt."
|
||||
fi
|
||||
echo "First-run setup complete. Start with: systemctl --user enable --now jarvisd.service"
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
APP_DIR="${HOME}/.local/share/jarvis-qvac"
|
||||
EXT_DIR="${HOME}/.local/share/gnome-shell/extensions/[email protected]"
|
||||
CONFIG_DIR="${HOME}/.config/jarvis"
|
||||
CACHE_DIR="${XDG_CACHE_HOME:-${HOME}/.cache}/jarvis/models"
|
||||
mkdir -p "${APP_DIR}" "${EXT_DIR}" "${CONFIG_DIR}" "${HOME}/.config/systemd/user" "${CACHE_DIR}"
|
||||
tar --exclude='.git' --exclude='./.agents' --exclude='./.codex' --exclude='./dist' --exclude='./node_modules' --exclude='*/node_modules' --exclude='*/__pycache__' --exclude='*.pyc' -cf - -C "${ROOT_DIR}" . | tar -xf - -C "${APP_DIR}"
|
||||
if [[ ! -d "${APP_DIR}/node_modules" ]]; then
|
||||
( cd "${APP_DIR}" && npm ci --omit=dev --ignore-scripts )
|
||||
fi
|
||||
rm -rf "${EXT_DIR}"
|
||||
mkdir -p "${EXT_DIR}"
|
||||
cp -a "${ROOT_DIR}/apps/gnome-extension/[email protected]/." "${EXT_DIR}/"
|
||||
cp "${ROOT_DIR}/packaging/jarvisd.service" "${HOME}/.config/systemd/user/jarvisd.service"
|
||||
if [[ ! -f "${CONFIG_DIR}/qvac.config.json" ]]; then
|
||||
sed "s#__JARVIS_CACHE__#${CACHE_DIR}#g" "${ROOT_DIR}/packaging/qvac.config.template.json" > "${CONFIG_DIR}/qvac.config.json"
|
||||
fi
|
||||
if [[ "${1:-}" == "--enable" ]]; then
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user enable --now jarvisd.service
|
||||
fi
|
||||
echo "Installed JARVIS-QVAC to ${APP_DIR}"
|
||||
echo "Run: ${APP_DIR}/packaging/first-run.sh"
|
||||
@@ -0,0 +1,17 @@
|
||||
[Unit]
|
||||
Description=JARVIS-QVAC local voice assistant
|
||||
After=pipewire.service wireplumber.service graphical-session.target
|
||||
Wants=pipewire.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
WorkingDirectory=%h/.local/share/jarvis-qvac
|
||||
ExecStart=/usr/bin/node %h/.local/share/jarvis-qvac/daemon/index.js
|
||||
Environment=QVAC_CONFIG_PATH=%h/.config/jarvis/qvac.config.json
|
||||
Environment=JARVIS_GPU_REQUIRED=1
|
||||
Environment=JARVIS_QVAC_OWNER=jarvisd
|
||||
Restart=on-failure
|
||||
RestartSec=2
|
||||
|
||||
[Install]
|
||||
WantedBy=graphical-session.target
|
||||
Executable
+39
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
: "${GITEA_SERVER_URL:?GITEA_SERVER_URL is required}"
|
||||
: "${GITEA_REPOSITORY:?GITEA_REPOSITORY is required}"
|
||||
: "${GITEA_SHA:?GITEA_SHA is required}"
|
||||
: "${RELEASE_TOKEN:?RELEASE_TOKEN is required}"
|
||||
|
||||
API="${GITEA_SERVER_URL%/}/api/v1/repos/${GITEA_REPOSITORY}"
|
||||
AUTH=(-H "Authorization: token ${RELEASE_TOKEN}" -H 'Accept: application/json' -H 'Content-Type: application/json')
|
||||
TAG="rolling"
|
||||
|
||||
release_json="$(curl -fsS "${AUTH[@]}" "${API}/releases/tags/${TAG}" 2>/dev/null || true)"
|
||||
if [[ -n "${release_json}" ]]; then
|
||||
release_id="$(jq -r '.id // empty' <<<"${release_json}")"
|
||||
if [[ -n "${release_id}" ]]; then
|
||||
curl -fsS -X DELETE "${AUTH[@]}" "${API}/releases/${release_id}" >/dev/null
|
||||
fi
|
||||
fi
|
||||
|
||||
tag_payload="$(jq -nc --arg sha "${GITEA_SHA}" '{new_target:$sha, force:true}')"
|
||||
if ! curl -fsS -X PATCH "${AUTH[@]}" "${API}/git/refs/tags/${TAG}" --data "${tag_payload}" >/dev/null 2>&1; then
|
||||
create_tag="$(jq -nc --arg sha "${GITEA_SHA}" --arg ref "refs/tags/${TAG}" '{ref:$ref, sha:$sha}')"
|
||||
curl -fsS -X POST "${AUTH[@]}" "${API}/git/refs" --data "${create_tag}" >/dev/null
|
||||
fi
|
||||
|
||||
release_payload="$(jq -nc --arg tag "${TAG}" --arg sha "${GITEA_SHA}" \
|
||||
'{tag_name:$tag, target_commitish:$sha, name:("Rolling " + ($sha[0:12])), body:"Automated Gitea rolling release from main.", draft:false, prerelease:true}')"
|
||||
created="$(curl -fsS -X POST "${AUTH[@]}" "${API}/releases" --data "${release_payload}")"
|
||||
release_id="$(jq -r '.id // empty' <<<"${created}")"
|
||||
test -n "${release_id}"
|
||||
|
||||
for asset in dist/jarvis-qvac_*.deb dist/jarvis-qvac-extension.zip dist/SHA256SUMS; do
|
||||
[[ -f "${asset}" ]] || continue
|
||||
curl -fsS -X POST "${AUTH[@]}" \
|
||||
"${API}/releases/${release_id}/assets?name=$(basename "${asset}")" \
|
||||
-H 'Content-Type: application/octet-stream' --data-binary "@${asset}" >/dev/null
|
||||
done
|
||||
echo "Published Gitea rolling release ${TAG} for ${GITEA_SHA:0:12}"
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"cacheDirectory": "__JARVIS_CACHE__",
|
||||
"serve": {
|
||||
"host": "127.0.0.1",
|
||||
"port": 11434,
|
||||
"models": {
|
||||
"jarvis-master": {
|
||||
"model": "QWEN3_5_4B_MULTIMODAL_Q4_K_M",
|
||||
"default": true,
|
||||
"preload": false,
|
||||
"config": { "ctx_size": 8192 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Executable
+14
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
cd "${ROOT_DIR}"
|
||||
command -v dpkg-deb >/dev/null
|
||||
command -v zip >/dev/null
|
||||
bash packaging/build-release.sh >/tmp/jarvis-package-test.log
|
||||
DEB="$(find dist -maxdepth 1 -name 'jarvis-qvac_*.deb' -print -quit)"
|
||||
test -n "${DEB}"
|
||||
dpkg-deb --info "${DEB}" >/dev/null
|
||||
dpkg-deb --contents "${DEB}" | grep 'usr/lib/jarvis-qvac/daemon/index.js' >/dev/null
|
||||
unzip -t dist/jarvis-qvac-extension.zip >/dev/null
|
||||
test -s dist/SHA256SUMS
|
||||
echo "package smoke test passed"
|
||||
Executable
+14
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
if [[ "${1:-}" != "--yes" ]]; then
|
||||
echo "Refusing to uninstall without --yes. Jarvis data is preserved by default." >&2
|
||||
exit 2
|
||||
fi
|
||||
systemctl --user disable --now jarvisd.service 2>/dev/null || true
|
||||
rm -f "${HOME}/.config/systemd/user/jarvisd.service"
|
||||
rm -rf "${HOME}/.local/share/jarvis-qvac" "${HOME}/.local/share/gnome-shell/extensions/[email protected]"
|
||||
systemctl --user daemon-reload 2>/dev/null || true
|
||||
if [[ "${2:-}" == "--purge-data" ]]; then
|
||||
rm -rf "${HOME}/.local/share/jarvis" "${HOME}/.cache/jarvis" "${HOME}/Jarvis"
|
||||
fi
|
||||
echo "JARVIS-QVAC removed; user data was preserved unless --purge-data was supplied."
|
||||
Reference in New Issue
Block a user