-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathJustfile
More file actions
451 lines (357 loc) · 16 KB
/
Copy pathJustfile
File metadata and controls
451 lines (357 loc) · 16 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
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
# =============================================================================
# Justfile — Development and deployment commands for the Synapse MCP server
#
# Usage: just <recipe> (install just: cargo install just)
# =============================================================================
# List all available recipes
default:
@just --list
# ── Development ───────────────────────────────────────────────────────────────
# Run the MCP server in development mode (HTTP transport 40080, no auth)
# WARNING: SYNAPSE_MCP_NO_AUTH=true is safe only because HOST is 127.0.0.1 (loopback)
dev:
SYNAPSE_MCP_HOST=127.0.0.1 SYNAPSE_MCP_NO_AUTH=true cargo run -- serve mcp
# Run in stdio MCP transport mode (for Claude Desktop or direct pipe)
mcp:
cargo run -- mcp
# Run a quick CLI host-status check (smoke test without a running server)
greet:
cargo run -- flux host status
# Run the doctor pre-flight check
doctor:
cargo run -- doctor
# ── Building ──────────────────────────────────────────────────────────────────
# Compile debug build (fast, includes debug symbols)
build:
cargo build
# Compile optimized release build (slower compile, much faster runtime)
build-release:
cargo build --release
# Build the Next.js web UI static export (required before cargo build embeds it)
# Output lands in apps/web/out/ and is baked into the binary via the `web` feature
build-web:
bash scripts/build-web.sh
# Watch apps/web for changes and rebuild on save (requires watchexec: cargo install watchexec-cli)
web-watch:
bash scripts/web-watch.sh
# Build the full binary with embedded web assets (runs build-web first)
build-full: build-web build-release
# Compile optimized release build (short alias used across the Rust server repos)
release: build-release
# ── Code quality ──────────────────────────────────────────────────────────────
# Run cargo check (fast syntax/type check, no binary output)
check:
cargo check
# Check Rust formatting without modifying files (used in CI + lefthook)
fmt-check:
cargo fmt -- --check
# Run the full test suite using cargo-nextest (faster, better output than cargo test)
# Install nextest: cargo install cargo-nextest
test:
cargo nextest run
# Run tests with the CI profile (fail-fast, 2 retries — mirrors CI)
test-ci:
cargo nextest run --profile ci
# Run clippy with warnings as errors (matches CI)
lint:
cargo clippy --all-targets -- -D warnings
# Format all Rust source files
fmt:
cargo fmt
# Auto-fix clippy warnings and format in one pass
fix:
cargo fmt
cargo clippy --fix --all-targets --allow-dirty --allow-staged
# Format all TOML files (requires taplo: cargo install taplo-cli)
fmt-toml:
taplo format
# Check TOML format without modifying files (used in CI + lefthook)
check-toml:
taplo check
# Run license, vulnerability, and source checks (requires cargo-deny: cargo install cargo-deny)
deny:
cargo deny check
# Watch Rust checks interactively (requires bacon: cargo install bacon)
watch:
bacon
# Generate Rust coverage report (requires cargo-llvm-cov)
test-cov:
mkdir -p target/llvm-cov/profiles
LLVM_PROFILE_FILE="target/llvm-cov/profiles/%p-%m.profraw" cargo llvm-cov --html --workspace --all-features
# Report dependency updates without modifying Cargo.lock
deps-check:
bash scripts/check-dependency-updates.sh
# Fail if changed blobs exceed the repo size budget
blob-size-check:
python3 scripts/check-blob-size.py
# Check coupled files such as Justfile/lefthook and scripts/docs
coupled-files-check:
bash scripts/check-coupled-files.sh
# Check tracked source/config/docs for non-ASCII characters
ascii-check:
bash scripts/run-ascii-check.sh
# Replace common smart punctuation with ASCII in tracked source/config/docs
ascii-fix:
bash scripts/run-ascii-check.sh --fix
# Check staged source files against line-count budgets
file-size-check:
bash scripts/check-file-size.sh
# NO MONOLITHS: advisory at 400 real-code lines, hard-fail at 1000 (repo-wide)
module-size-check:
bash scripts/check-rust-module-size.sh
# Regenerate MCP schema contract docs from src/mcp/schemas.rs
schema-docs:
python3 scripts/check-schema-docs.py --write
# Verify MCP schema contract docs and action surfaces are in sync
schema-docs-check:
python3 scripts/check-schema-docs.py --check
# Regenerate OpenAPI docs for the REST API surface
openapi:
python3 scripts/check-openapi.py --write
# Verify generated OpenAPI docs are current
openapi-check:
python3 scripts/check-openapi.py --check
# Reject stale template identities, ports, and duplicate action registries
identity-contract-check:
python3 scripts/check-identity-contract.py
# Validate scaffold intent JSON Schema and checked-in examples
scaffold-contract-check:
python3 scripts/check-scaffold-intent-contract.py
# Check static contracts from docs/PATTERNS.md
patterns-check:
cargo xtask patterns
# Check PATTERNS.md contracts and fail on warnings
patterns-strict:
cargo xtask patterns --strict
# Emit PATTERNS.md contract findings as JSON
patterns-json:
cargo xtask patterns --json
# Run shell/Rust-adjacent template invariant smoke tests
template-features:
bash scripts/test-template-features.sh
# Run fast template-specific checks
template-check:
just patterns-check
just module-size-check
just validate-plugin
just schema-docs-check
just openapi-check
just scaffold-contract-check
just template-features
# Run all local quality checks in sequence: fmt-check → lint → check → test
verify:
just fmt-check
just lint
just check
just test
# Run all quality checks in sequence (mirrors CI pipeline)
# Delegates to cargo xtask ci for the full suite (fmt, clippy, nextest, taplo, audit)
ci:
cargo xtask ci
# Remove build artifacts and generated files
clean:
cargo clean
rm -rf .cache/ dist/
# ── xtask automation ─────────────────────────────────────────────────────────
# Local operator convenience: build the release binary and copy it to dist/.
# GitHub releases publish binaries as artifacts; this recipe does not update main.
dist:
cargo xtask dist
# Create AGENTS.md and GEMINI.md symlinks next to every CLAUDE.md in the repo.
# Pattern §32: CLAUDE.md is the single source of truth for project instructions.
# Run after adding any new CLAUDE.md file.
symlink-docs:
cargo xtask symlink-docs
# Inline version of symlink-docs — no xtask required.
# TEMPLATE: Use this if xtask is unavailable (e.g. before first cargo build).
symlink-docs-inline:
find . -name "CLAUDE.md" -not -path "./.git/*" -not -path "./target/*" \
-exec sh -c 'dir=$(dirname "$1"); ln -sf CLAUDE.md "${dir}/AGENTS.md"; ln -sf CLAUDE.md "${dir}/GEMINI.md"; echo " link ${dir}/AGENTS.md + ${dir}/GEMINI.md"' _ {} \;
# Validate required environment variables are set before starting the server.
check-env:
cargo xtask check-env
# Install common development tools used by this Justfile
install-tools:
#!/usr/bin/env bash
set -euo pipefail
if ! command -v cargo-binstall >/dev/null 2>&1; then
cargo install cargo-binstall
fi
cargo binstall cargo-nextest --quiet --no-confirm
cargo binstall taplo-cli --quiet --no-confirm
cargo binstall cargo-deny --quiet --no-confirm
cargo binstall bacon --quiet --no-confirm
cargo binstall cargo-llvm-cov --quiet --no-confirm
cargo binstall lefthook --quiet --no-confirm
cargo binstall cargo-audit --quiet --no-confirm
if [ -d apps/web ]; then
(cd apps/web && pnpm install)
fi
# Alias for install-tools, matching the other Rust workspace convention
bootstrap: install-tools
# Install lefthook git hooks
install-hooks:
lefthook install
# Uninstall lefthook git hooks
uninstall-hooks:
lefthook uninstall
# ── Utilities ─────────────────────────────────────────────────────────────────
# Generate a cryptographically random bearer token for SYNAPSE_MCP_TOKEN
# Copy the output into your .env file
gen-token:
openssl rand -hex 32
# Copy .env.example to .env (safe — won't overwrite an existing .env)
setup:
cp -n .env.example .env || echo ".env already exists — skipping"
@echo "Edit .env and fill in your credentials"
# ── Docker ────────────────────────────────────────────────────────────────────
# Build the Docker image from source (does not start the container)
docker-build:
docker build -f config/Dockerfile -t synapse .
# Start the Docker Compose stack in detached mode
# TEMPLATE: The compose file references the "jakenet" external network.
# Create it first if it doesn't exist: docker network create jakenet
docker-up:
docker compose up -d
# Stop and remove the Docker Compose stack (data volume persists)
docker-down:
docker compose down
# Short alias for docker-up
up: docker-up
# Short alias for docker-down
down: docker-down
# Restart the running container (faster than down+up; no image rebuild)
restart:
docker compose restart
# Rebuild the Docker image from source and restart the stack
docker-rebuild:
docker compose build --no-cache
docker compose up -d --force-recreate
# Follow Docker container logs
docker-logs:
docker compose logs -f
# Short alias for docker-logs
logs:
docker compose logs -f
# ── Health & diagnostics ──────────────────────────────────────────────────────
# Check the MCP server health endpoint (no auth required)
# TEMPLATE: Change port 40080 if you use a different port
health:
#!/usr/bin/env bash
set -euo pipefail
if command -v jq >/dev/null 2>&1; then
curl -sf http://localhost:40080/health | jq .
else
curl -sf http://localhost:40080/health | python3 -m json.tool
fi
# Verify that the running Docker/systemd service matches the current artifact
runtime-current:
bash scripts/check-runtime-current.sh --expected-binary target/release/synapse
# Smoke-test the protected MCP HTTP auth path (requires running bearer-auth server)
auth-smoke:
bash scripts/test-mcp-auth.sh
# Call the host status action via MCP HTTP (requires SYNAPSE_MCP_TOKEN in env)
status:
#!/usr/bin/env bash
set -euo pipefail
TOKEN="${SYNAPSE_MCP_TOKEN:-}"
if [[ -z "${TOKEN}" ]]; then
echo "Set SYNAPSE_MCP_TOKEN or use 'just dev' (no-auth mode)"
exit 1
fi
curl -sf http://localhost:40080/mcp \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"flux","arguments":{"action":"host","subaction":"status"}}}' \
| { if command -v jq >/dev/null 2>&1; then jq .; else python3 -m json.tool; fi; }
# ── Plugin ────────────────────────────────────────────────────────────────────
# Repair: stop, rebuild, and restart via systemd user unit or Docker Compose
repair:
bash scripts/repair.sh
# Copy the release binary into plugin bin/ for local plugin packaging.
build-plugin: build-release
#!/bin/sh
set -eu
target_dir="${CARGO_TARGET_DIR:-target}"
if [ ! -x "${target_dir}/release/synapse" ] && [ -x ".cache/cargo/release/synapse" ]; then
target_dir=".cache/cargo"
fi
mkdir -p bin plugins/synapse/bin
install -m 755 "${target_dir}/release/synapse" bin/synapse
install -m 755 "${target_dir}/release/synapse" plugins/synapse/bin/synapse
echo "Installed bin/synapse and plugins/synapse/bin/synapse"
# Explicit binary artifact sync. This replaces hidden Cargo rustc-wrapper side effects.
sync-bin: build-plugin
# Install the release binary into bin/ (alias for build-plugin kept for compatibility)
install: build-plugin
# Install the release binary on the local PATH for runtime smoke testing
install-local: build-release
mkdir -p "${HOME}/.local/bin"
install -m 755 target/release/synapse "${HOME}/.local/bin/synapse"
@echo "Installed ${HOME}/.local/bin/synapse"
# Validate all plugin manifests, MCP config, monitors, and skills
validate-plugin:
bash scripts/validate-plugin-layout.sh
# Validate all plugin skills have required SKILL.md fields
validate-skills: validate-plugin
# ── mcporter ─────────────────────────────────────────────────────────────────
# Run mcporter-based integration tests (requires running server + mcporter CLI)
# TEMPLATE: Ensure the server is running first: just dev or just docker-up
test-mcporter:
#!/usr/bin/env bash
set -euo pipefail
if ! command -v mcporter &>/dev/null; then
echo "mcporter not found. Install it first."
exit 1
fi
bash tests/mcporter/test-mcp.sh
# Run the release-readiness gate
pre-release:
bash scripts/pre-release-check.sh
# Generate a standalone CLI for this server via mcporter (requires running server)
# TEMPLATE: Update port and token env var name in scripts/generate-cli.sh
generate-cli:
bash scripts/generate-cli.sh
# ── Publishing ────────────────────────────────────────────────────────────────
# Bump the crate version using cargo-edit and regenerate Cargo.lock.
# Requires cargo-edit: cargo install cargo-edit
bump-version version:
cargo set-version {{version}}
cargo generate-lockfile
# Bump version, tag, and push (triggers CI publish workflow)
# Updates Cargo.toml + Cargo.lock only — plugin manifests have no version field
# (GitHub SHA is the version for plugins; every push is a new release automatically)
# TEMPLATE: Requires main branch + clean working tree
publish bump="patch":
#!/usr/bin/env bash
set -euo pipefail
[ "$(git branch --show-current)" = "main" ] || { echo "Switch to main first"; exit 1; }
[ -z "$(git status --porcelain)" ] || { echo "Commit or stash changes first"; exit 1; }
git pull origin main
CURRENT=$(grep -m1 "^version" Cargo.toml | sed 's/.*"\(.*\)".*/\1/')
IFS="." read -r major minor patch <<< "${CURRENT}"
case "{{bump}}" in
major) major=$((major+1)); minor=0; patch=0 ;;
minor) minor=$((minor+1)); patch=0 ;;
patch) patch=$((patch+1)) ;;
*) echo "Usage: just publish [major|minor|patch]"; exit 1 ;;
esac
NEW="${major}.${minor}.${patch}"
echo "Version: ${CURRENT} → ${NEW}"
just bump-version "${NEW}"
git add -A && git commit -m "release: v${NEW}" && git tag "v${NEW}" && git push origin main --tags
echo "Tagged v${NEW} — publish workflow will run automatically"
# ── Reference docs ────────────────────────────────────────────────────────────
# Refresh local reference documentation (crawls + repomix)
refresh-docs:
bash scripts/refresh-docs.sh
# Refresh docs — repomix packs only (no crawl)
refresh-docs-repomix:
bash scripts/refresh-docs.sh --skip-crawl
# Refresh docs — crawl only (no repomix)
refresh-docs-crawl:
bash scripts/refresh-docs.sh --skip-repomix
# Dry-run: print what would be refreshed
refresh-docs-dry:
bash scripts/refresh-docs.sh --dry-run