forked from moltis-org/moltis
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathjustfile
More file actions
427 lines (356 loc) · 15.1 KB
/
justfile
File metadata and controls
427 lines (356 loc) · 15.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
# Default recipe (runs when just is called without arguments)
default:
@just --list
# Keep local formatting/linting toolchain aligned with CI/release workflows.
nightly_toolchain := "nightly-2025-11-30"
# Format Rust code
format:
cargo +{{nightly_toolchain}} fmt --all
# Check if code is formatted
format-check:
cargo +{{nightly_toolchain}} fmt --all -- --check
# Run live provider E2E scenarios (sources .envrc when present).
provider-e2e-daily:
./scripts/run-provider-e2e-daily.sh
# Verify Cargo.lock is in sync with workspace manifests.
lockfile-check:
cargo fetch --locked
# Lint Rust code using clippy (OS-aware: macOS excludes CUDA features)
lint: lockfile-check
#!/usr/bin/env bash
set -euo pipefail
if [ "$(uname -s)" = "Darwin" ]; then
cargo +{{nightly_toolchain}} clippy -Z unstable-options --workspace --all-targets --exclude moltis-providers --exclude moltis-gateway --timings -- -D warnings
cargo +{{nightly_toolchain}} clippy -Z unstable-options -p moltis-providers --all-targets --features local-llm-metal --timings -- -D warnings
cargo +{{nightly_toolchain}} clippy -Z unstable-options -p moltis-gateway --all-targets --features local-llm-metal --timings -- -D warnings
else
cargo +{{nightly_toolchain}} clippy -Z unstable-options --workspace --all-features --all-targets --timings -- -D warnings
fi
# Build Tailwind CSS for the web UI.
build-css:
cd crates/web/ui && ./build.sh
# Build the project
build: build-css
cargo build
# Build in release mode
build-release:
cargo build --release
# Build embedded WASM guest tools and pre-compile to .cwasm for AOT loading.
wasm-tools:
cargo build --target wasm32-wasip2 -p moltis-wasm-calc -p moltis-wasm-web-fetch -p moltis-wasm-web-search --release
cargo run -p moltis-wasm-precompile --release
# Build just the release WASM artifacts expected by embedded-wasm builds.
build-wasm-artifacts: wasm-tools
@echo "Built target/wasm32-wasip2/release/{moltis_wasm_calc,moltis_wasm_web_fetch,moltis_wasm_web_search}.{wasm,cwasm}"
# Build release after ensuring embedded WASM artifacts are present.
build-release-with-wasm: build-wasm-artifacts
cargo build --release
# Run local dev server with workspace-local config/data dirs.
dev-server:
MOLTIS_CONFIG_DIR=.moltis/config MOLTIS_DATA_DIR=.moltis/ cargo run --bin moltis
# Build Debian package for the current architecture
deb: build-release build-wasm-artifacts
bash ./scripts/stage-wasm-package-assets.sh target/release
cargo deb -p moltis --no-build
# Build Debian package for amd64
deb-amd64: build-wasm-artifacts
cargo build --release --target x86_64-unknown-linux-gnu
bash ./scripts/stage-wasm-package-assets.sh target/x86_64-unknown-linux-gnu/release
cargo deb -p moltis --no-build --target x86_64-unknown-linux-gnu
# Build Debian package for arm64
deb-arm64: build-wasm-artifacts
cargo build --release --target aarch64-unknown-linux-gnu
bash ./scripts/stage-wasm-package-assets.sh target/aarch64-unknown-linux-gnu/release
cargo deb -p moltis --no-build --target aarch64-unknown-linux-gnu
# Build Debian packages for all architectures
deb-all: deb-amd64 deb-arm64
# Build Arch package for the current architecture
arch-pkg: build-release
#!/usr/bin/env bash
set -euo pipefail
VERSION="${MOLTIS_VERSION:-$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)"/\1/')}"
ARCH=$(uname -m)
PKG_DIR="target/arch-pkg"
rm -rf "$PKG_DIR"
mkdir -p "$PKG_DIR/usr/bin"
cp target/release/moltis "$PKG_DIR/usr/bin/moltis"
chmod 755 "$PKG_DIR/usr/bin/moltis"
cat > "$PKG_DIR/.PKGINFO" <<PKGINFO
pkgname = moltis
pkgver = ${VERSION}-1
pkgdesc = Personal AI gateway inspired by OpenClaw
url = https://www.moltis.org/
arch = ${ARCH}
license = MIT
PKGINFO
cd "$PKG_DIR"
fakeroot -- tar --zstd -cf "../../moltis-${VERSION}-1-${ARCH}.pkg.tar.zst" .PKGINFO usr/
echo "Built moltis-${VERSION}-1-${ARCH}.pkg.tar.zst"
# Build Arch package for x86_64
arch-pkg-x86_64:
#!/usr/bin/env bash
set -euo pipefail
cargo build --release --target x86_64-unknown-linux-gnu
VERSION="${MOLTIS_VERSION:-$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)"/\1/')}"
PKG_DIR="target/arch-pkg-x86_64"
rm -rf "$PKG_DIR"
mkdir -p "$PKG_DIR/usr/bin"
cp target/x86_64-unknown-linux-gnu/release/moltis "$PKG_DIR/usr/bin/moltis"
chmod 755 "$PKG_DIR/usr/bin/moltis"
cat > "$PKG_DIR/.PKGINFO" <<PKGINFO
pkgname = moltis
pkgver = ${VERSION}-1
pkgdesc = Personal AI gateway inspired by OpenClaw
url = https://www.moltis.org/
arch = x86_64
license = MIT
PKGINFO
cd "$PKG_DIR"
fakeroot -- tar --zstd -cf "../../moltis-${VERSION}-1-x86_64.pkg.tar.zst" .PKGINFO usr/
echo "Built moltis-${VERSION}-1-x86_64.pkg.tar.zst"
# Build Arch package for aarch64
arch-pkg-aarch64:
#!/usr/bin/env bash
set -euo pipefail
cargo build --release --target aarch64-unknown-linux-gnu
VERSION="${MOLTIS_VERSION:-$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)"/\1/')}"
PKG_DIR="target/arch-pkg-aarch64"
rm -rf "$PKG_DIR"
mkdir -p "$PKG_DIR/usr/bin"
cp target/aarch64-unknown-linux-gnu/release/moltis "$PKG_DIR/usr/bin/moltis"
chmod 755 "$PKG_DIR/usr/bin/moltis"
cat > "$PKG_DIR/.PKGINFO" <<PKGINFO
pkgname = moltis
pkgver = ${VERSION}-1
pkgdesc = Personal AI gateway inspired by OpenClaw
url = https://www.moltis.org/
arch = aarch64
license = MIT
PKGINFO
cd "$PKG_DIR"
fakeroot -- tar --zstd -cf "../../moltis-${VERSION}-1-aarch64.pkg.tar.zst" .PKGINFO usr/
echo "Built moltis-${VERSION}-1-aarch64.pkg.tar.zst"
# Build Arch packages for all architectures
arch-pkg-all: arch-pkg-x86_64 arch-pkg-aarch64
# Build RPM package for the current architecture
rpm: build-release
cargo generate-rpm -p crates/cli
# Build RPM package for x86_64
rpm-x86_64:
cargo build --release --target x86_64-unknown-linux-gnu
cargo generate-rpm -p crates/cli --target x86_64-unknown-linux-gnu
# Build RPM package for aarch64
rpm-aarch64:
cargo build --release --target aarch64-unknown-linux-gnu
cargo generate-rpm -p crates/cli --target aarch64-unknown-linux-gnu
# Build RPM packages for all architectures
rpm-all: rpm-x86_64 rpm-aarch64
# Build AppImage for the current architecture
appimage: build-release
#!/usr/bin/env bash
set -euo pipefail
VERSION="${MOLTIS_VERSION:-$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)"/\1/')}"
ARCH=$(uname -m)
APP_DIR="target/moltis.AppDir"
rm -rf "$APP_DIR"
mkdir -p "$APP_DIR/usr/bin"
cp target/release/moltis "$APP_DIR/usr/bin/moltis"
chmod 755 "$APP_DIR/usr/bin/moltis"
cat > "$APP_DIR/moltis.desktop" <<DESKTOP
[Desktop Entry]
Type=Application
Name=Moltis
Exec=moltis
Icon=moltis
Categories=Network;
Terminal=true
DESKTOP
cat > "$APP_DIR/moltis.svg" <<SVG
<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256"><rect width="256" height="256" fill="#333"/><text x="128" y="140" font-size="120" text-anchor="middle" fill="white">M</text></svg>
SVG
ln -sf moltis.svg "$APP_DIR/.DirIcon"
cat > "$APP_DIR/AppRun" <<'APPRUN'
#!/bin/sh
SELF=$(readlink -f "$0")
HERE=${SELF%/*}
exec "$HERE/usr/bin/moltis" "$@"
APPRUN
chmod +x "$APP_DIR/AppRun"
if [ ! -f target/appimagetool ]; then
wget -q "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-${ARCH}.AppImage" -O target/appimagetool
chmod +x target/appimagetool
fi
ARCH=${ARCH} target/appimagetool --appimage-extract-and-run "$APP_DIR" "moltis-${VERSION}-${ARCH}.AppImage"
echo "Built moltis-${VERSION}-${ARCH}.AppImage"
# Build Snap package
snap:
snapcraft
# Build Flatpak
flatpak:
cd flatpak && flatpak-builder --repo=repo --force-clean builddir org.moltbot.Moltis.yml
# Run all CI checks (format, lint, build, test)
ci: format-check lint i18n-check build-css build test
# Compile once, then run Rust tests and E2E tests in parallel.
# Uses the same nightly toolchain as clippy/local-validate so the build cache
# is shared — no double-compilation.
build-test: build-css
#!/usr/bin/env bash
set -euo pipefail
echo "==> Building all workspace targets (bins + tests)..."
if [ "$(uname -s)" = "Darwin" ]; then
cargo +{{nightly_toolchain}} build --workspace --all-targets --exclude moltis-providers --exclude moltis-gateway
cargo +{{nightly_toolchain}} build -p moltis-providers --all-targets --features local-llm-metal
cargo +{{nightly_toolchain}} build -p moltis-gateway --all-targets --features local-llm-metal
else
cargo +{{nightly_toolchain}} build --workspace --all-features --all-targets
fi
echo "==> Build complete. Running Rust tests and E2E tests in parallel..."
RUST_LOG="$(mktemp)"
E2E_LOG="$(mktemp)"
trap 'rm -f "${RUST_LOG}" "${E2E_LOG}"' EXIT
if [ "$(uname -s)" = "Darwin" ]; then
(
cargo +{{nightly_toolchain}} nextest run --workspace --exclude moltis-providers --exclude moltis-gateway
cargo +{{nightly_toolchain}} nextest run -p moltis-providers --features local-llm-metal
cargo +{{nightly_toolchain}} nextest run -p moltis-gateway --features local-llm-metal
) > "${RUST_LOG}" 2>&1 &
else
cargo +{{nightly_toolchain}} nextest run --all-features > "${RUST_LOG}" 2>&1 &
fi
TEST_PID=$!
(cd crates/web/ui && npm run e2e) > "${E2E_LOG}" 2>&1 &
E2E_PID=$!
TEST_EXIT=0; E2E_EXIT=0
wait "${TEST_PID}" || TEST_EXIT=$?
wait "${E2E_PID}" || E2E_EXIT=$?
if [ "${TEST_EXIT}" -ne 0 ]; then
echo "==> Rust tests FAILED (exit ${TEST_EXIT}):"
cat "${RUST_LOG}"
else
echo "==> Rust tests PASSED"
fi
if [ "${E2E_EXIT}" -ne 0 ]; then
echo "==> E2E tests FAILED (exit ${E2E_EXIT}):"
cat "${E2E_LOG}"
else
echo "==> E2E tests PASSED"
fi
exit $(( TEST_EXIT > 0 ? TEST_EXIT : E2E_EXIT ))
# Run the same Rust preflight gates used before release packaging.
release-preflight: lint
cargo +{{nightly_toolchain}} fmt --all -- --check
# Sync repo-root install.sh into website/install.sh for Cloudflare deployment.
sync-website-install:
./scripts/sync-website-install.sh
# Ensure repo-root install.sh and website/install.sh are identical.
check-website-install-sync:
./scripts/check-website-install-sync.sh
# Dispatch release workflow from GitHub Actions (normal mode).
release-workflow ref='main':
gh workflow run release.yml --ref {{ref}} -f dry_run=false
# Dispatch release workflow from GitHub Actions (dry-run mode).
release-workflow-dry ref='main':
gh workflow run release.yml --ref {{ref}} -f dry_run=true
# Dispatch both release workflow modes for the same ref (dry-run then normal).
release-workflow-both ref='main':
gh workflow run release.yml --ref {{ref}} -f dry_run=true
gh workflow run release.yml --ref {{ref}} -f dry_run=false
# Regenerate CHANGELOG.md from git history and tags.
changelog:
git-cliff --config cliff.toml --output CHANGELOG.md
# Preview unreleased changelog entries from commits since the last tag.
changelog-unreleased:
git-cliff --config cliff.toml --unreleased
# Generate release entries for unreleased commits under the provided version.
changelog-release version:
git-cliff --config cliff.toml --unreleased --tag "{{version}}" --strip all
# Commit all changes, push branch, create/update PR, and run local validation.
# All args are optional; defaults are auto-generated from branch + changed files.
ship commit_message='' pr_title='' pr_body='':
./scripts/ship-pr.sh {{ quote(commit_message) }} {{ quote(pr_title) }} {{ quote(pr_body) }}
# Run all tests (nightly to share build cache with clippy/lint, OS-aware)
test:
#!/usr/bin/env bash
set -euo pipefail
if [ "$(uname -s)" = "Darwin" ]; then
cargo +{{nightly_toolchain}} nextest run --workspace --exclude moltis-providers --exclude moltis-gateway
cargo +{{nightly_toolchain}} nextest run -p moltis-providers --features local-llm-metal
cargo +{{nightly_toolchain}} nextest run -p moltis-gateway --features local-llm-metal
else
cargo +{{nightly_toolchain}} nextest run --workspace --all-features
fi
# Run contract test suites (channel, provider, memory, tools)
contract-tests:
cargo test -p moltis-channels contract
cargo test -p moltis-providers contract
cargo test -p moltis-memory contract
cargo test -p moltis-tools contract
# Verify locale key parity across frontend i18n bundles.
i18n-check:
./scripts/i18n-check.sh
# Install browser tooling for gateway web UI e2e tests.
ui-e2e-install:
cd crates/web/ui && npm install && npm run e2e:install
# Run gateway web UI e2e tests (Playwright).
ui-e2e:
cargo +{{nightly_toolchain}} build --bin moltis
cd crates/web/ui && npm run e2e
# Run gateway web UI e2e tests with headed browser.
ui-e2e-headed:
cargo +{{nightly_toolchain}} build --bin moltis
cd crates/web/ui && npm run e2e:headed
# Build all Linux packages (deb + rpm + arch + appimage) for all architectures
packages-all: deb-all rpm-all arch-pkg-all
# Build Rust static library and generated C header for the macOS app.
swift-build-rust:
./scripts/build-swift-bridge.sh
# Generate Xcode project from YAML spec in apps/macos.
swift-generate:
./scripts/generate-swift-project.sh
# Lint macOS app sources with SwiftLint.
swift-lint:
./scripts/lint-swift.sh
# Build Swift macOS app.
swift-build: swift-build-rust swift-generate
./scripts/build-swift.sh
# Run Swift app unit tests.
swift-test: swift-build-rust swift-generate
./scripts/test-swift.sh
# Build and launch the Swift macOS app locally.
swift-run: swift-build-rust swift-generate
./scripts/run-swift.sh
# Open generated project in Xcode.
swift-open: swift-build-rust swift-generate
open apps/macos/Moltis.xcodeproj
# Generate iOS app Xcode project.
ios-generate:
./scripts/generate-ios-project.sh
# Generate Apollo GraphQL types for iOS.
ios-graphql:
cargo run -p moltis-schema-export -- apps/ios/GraphQL/Schema/schema.graphqls
./scripts/generate-ios-graphql.sh
# Build iOS app (generic iOS destination, no signing).
ios-build: ios-graphql ios-generate
xcodebuild -project apps/ios/Moltis.xcodeproj -scheme Moltis -configuration Debug -destination "generic/platform=iOS" CODE_SIGNING_ALLOWED=NO build
# Lint iOS app sources with SwiftLint.
ios-lint:
cd apps/ios && swiftlint
# Open iOS project in Xcode (regenerates GraphQL types and project first).
ios-open: ios-graphql ios-generate
open apps/ios/Moltis.xcodeproj
# Build the APNS push relay.
courier-build:
cargo build -p moltis-courier --release
# Cross-compile courier for linux/x86_64.
courier-cross:
cargo build -p moltis-courier --release --target x86_64-unknown-linux-gnu
# Deploy courier to remote server(s) via Ansible.
courier-deploy:
cd apps/courier/deploy && ansible-playbook playbook.yml
# Run the APNS push relay (dev).
courier-run *ARGS:
cargo run -p moltis-courier -- {{ARGS}}
# Serve the website locally with SSR partial injection (default port 4000).
website-dev:
node website/scripts/build-changelog.mjs
node website/scripts/dev-server.mjs