An immersive single-page web terminal that reveals Alexandre DO-O ALMEIDAβs rΓ©sumΓ© through typed commands. Everything is written in Rust, compiled to WebAssembly, and ships as a framework-free SPA for fast cold starts.
- ποΈ Web-only terminal UI with history, autocomplete, theming, achievements, and an AI Mode toggle.
- π¦ Static rΓ©sumΓ© data sourced from JSON so updates never require a recompile.
- π€ Optional AI concierge proxied through an Axum service that uses complete curated knowledge and persistent spending limits.
- π Build pipeline ships optimized WebAssembly + minified CSS in
static/, ready for any CDN with an optional Axum proxy.
- Generation: one OpenAI
gpt-5.6-lunacall, Chat Completions with reasoningnoneand a 640-token output cap. - Knowledge: all seven curated JSON sources, including expanded projects, publications, awards and testimonials beyond the one-page CV. No paid retrieval or vector database is needed.
- Follow-ups: the last three exchanges are kept in tab memory, bounded and validated by the server.
quitor refresh clears them. - Reliability: pre-call rate/concurrency limits, a 16-second server deadline, a 20-second browser deadline and a working classic terminal on failure.
- Spending: persistent USD ledger, conservative reservation followed by one reconciliation against reported input/output/cache usage. $0.50/minute, $2/hour and day, $10/30 days by default.
- Attribution:
sourcescontains validated section IDs, shown below each answer. Factual evaluation remains necessary; metadata alone does not establish correctness.
.
βββ Cargo.toml # Workspace root + WebAssembly crate manifest
βββ VERSION # Project version (sync via scripts/bump_version.py)
βββ Makefile # Build/test/deploy entry points (wasm-pack, Netlify, logs)
βββ netlify.toml # Netlify deploy config (redirects, cache headers)
βββ .env.example # Template for required/optional environment variables
βββ src/ # Rust/WebAssembly terminal (commands, state, renderer)
βββ server/ # Axum proxy (OpenAI relay, rate limiting, static host)
βββ static/
β βββ index.html # Terminal shell + module bootstrap
β βββ style.css # Source stylesheet (minified to style.min.css)
β βββ style.min.css # Minified styles generated by make build
β βββ data/ # RΓ©sumΓ© JSON (profile, skills, experience, education, projects)
β βββ images/ # Logos & Open Graph artwork
β βββ icons/ # Favicons & manifest assets
β βββ effects/ # Visual flourish assets (canvas, particles, etc.)
β βββ cv/ # Canonical HTML resume, PDF download and local assets
β βββ pkg/ # wasm-bindgen output mirrored from /pkg
βββ pkg/ # Raw wasm-pack artefacts (ignored by git)
βββ scripts/
β βββ bump_version.py # Bumps VERSION + Cargo manifests
β βββ live_smoke_test.py # Production smoke test
β βββ minify_css.py # CSS minifier invoked by make build
β βββ run_live_autotest.sh # CI helper for the smoke test
β βββ serve.py # Static dev server (writes server.log)
βββ screenshot_zqsdev.png # README showcase image
Install the prerequisites once:
rustup target add wasm32-unknown-unknown
cargo install wasm-packFetch dependencies and build the terminal bundle:
make buildInside the terminal, try:
help about skills experience
education projects testimonials contact
faq resume theme ai
clear
Flip on AI Mode with the toolbar button to ask natural-language questions. When disabled, helper chips provide quick access to the commands above.
# 1. Compile the WebAssembly bundle (writes static/pkg/)
make build
# 2. Run the full Rust stack (serves static assets + /api/ai)
export OPENAI_API_KEY=sk-your-key # required for AI mode
make serve # http://localhost:3000 by default
# Optional: static-only dev server (no AI proxy, logs to server.log)
make serve-static # http://localhost:8765 by defaultUseful overrides:
make serve HOST=127.0.0.1 SERVER_PORT=4000
make serve-static STATIC_PORT=9000make build always refreshes static/pkg/ and static/style.min.css, both of which must ship alongside the rest of static/ for deployment.
Edit static/data/*.json, run python3 scripts/validate_knowledge.py, build, and restart the backend after deploying data. The reviewed full-context ceiling is 64 KB. Builds require no AI credentials.
The migration verified all 44 live SQLite chunks against the JSON sources and the Pinecone index held 44 vectors. All original projects (including Micro Mages, Mistale, BeeToBee and TheClair), education, publications, awards and two full testimonials were preserved. The obsolete terminal-project description, role dates and availability FAQ were updated; Studi and agentic engineering were added.
Legacy build_rag.py, inspect_rag.py and make rag remain available for historical inspection only. Normal build and runtime never query Pinecone, call embeddings or open SQLite. The old index is left intact.
Official model reference: GPT-5.6 Luna. Rates verified on 2026-09-08: input $0.20, cache read $0.02, cache write $0.25, output $1.20 per million tokens. Set all rates explicitly when selecting another model.
make test # wasm-pack test --node + cargo test for the proxy
make fmt # cargo fmt across the workspace
make check # cargo check --target wasm32-unknown-unknownThe CI pipeline should run the same trio so local runs stay in lockstep with automation.
Run make autotest (or directly python3 scripts/live_smoke_test.py) to exercise the deployed site once end-to-end. It validates the Netlify bundle, the /api/data payloads, and sends two questions to the AI concierge. Install the lone dependency with pip install requests, then wire either command into your scheduler (cron, GitHub Actions, etc.). Optional flags:
python3 scripts/live_smoke_test.py --json-output live-smoke.json
python3 scripts/live_smoke_test.py --ai-question "What's new with Alexandre?"
# Or via make (flags are forwarded):
make autotest AUTOTEST_FLAGS="--json-output live-smoke.json"The script exits non-zero on failure so monitors can trigger alerts. Keep the two-question smoke suite bounded to respect the production rate limits. For cron jobs, scripts/run_live_autotest.sh wraps the Python entry point with sensible defaults.
If PUSHOVER_API_TOKEN and PUSHOVER_USER_KEY are present (in the environment, .env.local, or .env), the script will send a Pushover alert only when a check fails or the run ends early with skipped tests. Disable that behaviour with --no-pushover or AUTOTEST_FLAGS="--no-pushover" if needed.
- Copy the template:
cp .env.example .env
- Update at least
OPENAI_API_KEY=...if you plan to enable AI Mode locally.
OPENAI_API_KEY is the only required secret today. No other AI provider or vector-database credentials are needed. The proxy loads .env.local first, then .env, which keeps machine-specific overrides out of version control. Both files are ignored by git so real keys stay on your machine.
- β
Run
make buildandmake testbefore handing changes off sostatic/pkg/and the proxy both stay green. - β¬οΈ Bump the version with
python3 scripts/bump_version.py(touchesVERSION,Cargo.toml, andserver/Cargo.toml). The script defaults to patch releases; pass--minoror--majorwhen needed. - βοΈ Commit only the sources, regenerated assets under
static/pkg/, and version bumps. Artifacts in/pkg, local env files, and logs (server.log) are ignored by default.
- π The public resume is
https://cv.zqsdev.com/. The terminal uses this same canonical CV, in English and French. - π§Ύ Edit the JSON files in
static/data/to refresh profile details, experiences, and skills for the interactive terminal and AI knowledge base. - π Edit
static/cv/index.html(English),static/cv/fr.html(French) and the sharedstatic/cv/resume.cssfor the public resume. The approved base V4 is available asresume.pdfin English andresume-fr.pdfin French. Each static page links to its matching PDF and the other language, including without JavaScript.resume.jslocalizes the clipboard message, preserves terminal return context when switching language and fits the document inside the original PDF frame.
The server is optional at runtime; the public site is served from the static bundle.
βοΈ Netlify (www.zqsdev.com & zqsdev.com)
- π
netlify.tomlserves the HTML resume atcv.zqsdev.com;founding.zqsdev.com,devops.zqsdev.com,software.zqsdev.comand their old PDF links redirect to it.calendly.zqsdev.comstill forwards to Calendly. Keep the legacy domain aliases so existing shared links continue to work. - π
/api/*requests proxy through Netlify tohttps://api.zqsdev.com/api/:splat, keeping browser requests same-origin while hitting the Axum backend. - π Install the Netlify CLI (
npm install -g netlify-cli) and authenticate once withnetlify loginorNETLIFY_AUTH_TOKEN. - π
make deploy-previewβ runsmake buildthennetlify deploy --dir static --config netlify.toml. - π
make deploy-prodβ same flow with--prod. Pass extra flags viaNETLIFY_FLAGS(e.g.NETLIFY_FLAGS="--alias staging"). - π§ In Netlify, add the custom domains
founding.zqsdev.com,devops.zqsdev.com, andsoftware.zqsdev.com, then create the matching DNS records before production validation.
- π οΈ Run
make build. - π€ Publish the contents of
static/(includingstatic/pkg/) to your CDN or object store.
If you want AI Mode in production, deploy the proxy (e.g. on Fly.io, Railway, or a small VPS) with:
- π
OPENAI_API_KEYset. - βοΈ Optional
HOST,PORT, andSTATIC_DIRoverrides.
The proxy reads static/data/*.json at startup, forwards questions to gpt-5.6-luna, and enforces spend ceilings before gracefully falling back to the classic terminal experience when limits trigger.
- π§Ύ Unit file:
/etc/systemd/system/zqs-terminal.serviceruns/opt/zqsdev/bin/zqs-terminal-serveras thezqsdevuser withWorkingDirectory=/opt/zqsdev. - π‘οΈ Environment lives in
/etc/zqsdev/server.env, includingHOST=0.0.0.0,PORT=8787,STATIC_DIR=/opt/zqsdev/static, and the API keys used at runtime. - ποΈ Manage the service with
sudo systemctl status|restart zqs-terminal.service; logs stream to/opt/zqsdev/backend.log(mirrored here as./backend.log) and viajournalctl -u zqs-terminal.service. - π‘ Run
make backend-logto tail the rolling log from the repository root. - π Public ingress:
api.zqsdev.comterminates TLS with Nginx (config at/etc/nginx/sites-enabled/api.zqsdev.com) and proxies to the Axum service on127.0.0.1:8787. - The binary listens on port
8787/tcp(/api/ai) and restarts automatically on failure.
Built with π¦ Rust and β€οΈ by Alexandre DO-O ALMEIDA (ZQSDev). Enjoy the terminal! π
The V4 content is ordinary semantic HTML, in English and French; each language has a matching one-page PDF. These are translations of the same CV, not different role variants.
The original dark shell, rounded toolbar buttons and .page frame are preserved. On narrow screens the HTML reflows for reading, while printing preserves the A4 layout.
Run python3 -m unittest scripts.test_cv_site to check the static CV and routing contracts.
Portrait: final 1254x1254 PNG supplied by Alexandre on 2026-09-08, published without further editing. The HTML and PDF use the same image. Studi logo: Studi, Wikimedia Commons, CC BY 4.0, unmodified. PlayStation symbol: official PlayStation site. YC badge: typographic Y. VibeRank icon: official SVG, copied locally on 2026-09-08; links to Aleqsd's profile.
Toolbar: monochrome GitHub and LinkedIn SVG marks inherit the light text color to stay legible on the dark background. Language flags are decorative SVGs with visible language names.
