summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.envrc37
-rw-r--r--.tioconfig33
-rw-r--r--devenv.lock103
-rw-r--r--devenv.nix90
-rw-r--r--devenv.yaml12
-rw-r--r--secrets.yaml36
6 files changed, 311 insertions, 0 deletions
diff --git a/.envrc b/.envrc
new file mode 100644
index 0000000..eb8dfa4
--- /dev/null
+++ b/.envrc
@@ -0,0 +1,37 @@
+#!/usr/bin/env bash
+
+export DIRENV_WARN_TIMEOUT=10s
+
+case "$(uname -s)" in
+*BSD)
+ # mise v # TODO: wait to re-appear on ports
+ ;;
+*)
+ eval "$(devenv direnvrc)"
+ export DEVENV_TUI=false
+ use devenv
+
+ export CONFIG_MQTT_DEFAULT_HOST="10.0.0.198"
+ export LIKEC4_WORKSPACE="${PWD}/docs"
+
+ PULUMI_CONFIG_PASSPHRASE="$(sops -d --extract '["PULUMI_CONFIG_PASSPHRASE"]' secrets.yaml)"
+ CONFIG_MQTT_DEFAULT_USERNAME="$(sops -d --extract '["CONFIG_MQTT_DEFAULT_USERNAME"]' secrets.yaml)"
+ CONFIG_MQTT_DEFAULT_PASSWORD="$(sops -d --extract '["CONFIG_MQTT_DEFAULT_PASSWORD"]' secrets.yaml)"
+ CONFIG_WIFI_CREDENTIALS_STATIC_SSID="$(sops -d --extract '["CONFIG_WIFI_CREDENTIALS_STATIC_SSID"]' secrets.yaml)"
+ CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="$(sops -d --extract '["CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD"]' secrets.yaml)"
+
+ export PULUMI_CONFIG_PASSPHRASE
+ export CONFIG_MQTT_DEFAULT_USERNAME
+ export CONFIG_MQTT_DEFAULT_PASSWORD
+ export CONFIG_WIFI_CREDENTIALS_STATIC_SSID
+ export CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD
+
+ # Nix python.withPackages on macOS does not propagate the wrapped env's
+ # site-packages to subprocess Python invocations. Twister hits this when
+ # spawning `west flash`, causing "Missing jsonschema dependency" exits.
+ # Force the wrapped env's site-packages onto PYTHONPATH so subprocess
+ # imports resolve. Derived from `west` so it survives Nix store rehashes.
+ WEST_PYTHON_PREFIX="$(dirname "$(dirname "$(readlink -f "$(command -v west)")")")"
+ export PYTHONPATH="${WEST_PYTHON_PREFIX}/lib/python3.14/site-packages"
+ ;;
+esac
diff --git a/.tioconfig b/.tioconfig
new file mode 100644
index 0000000..64499d4
--- /dev/null
+++ b/.tioconfig
@@ -0,0 +1,33 @@
+[default]
+baudrate = 115200
+databits = 8
+stopbits = 1
+parity = none
+flow = none
+
+timestamp = false
+
+color = bold # doesn't fight with ANSI codes the firmware emits
+
+# INLCRNL maps incoming LF to CR-LF so embedded firmware that emits bare \n
+# renders correctly. Zephyr's LOG_INF already uses \r\n; this is defensive.
+map = INLCRNL
+
+no-reconnect = false # auto-reconnect is the default. Every chip reset, 'west flash', and USB re-enumeration just resumes the session
+
+[walter]
+device = /dev/cu.usbmodem2101
+color = 12
+
+# log = true
+# log-file = /Users/mfarabi/workspace/apidae-systems/src/logs/tio/walter.log
+# log-append = true
+# log-strip = true # Strip ANSI escapes from the log file (keeps logs grep-friendly) while preserving them on stdout (so the live view is still colored)
+
+[usbmodem-%1]
+pattern = ^usbmodem([0-9]+)$
+device = /dev/cu.usbmodem%m1
+
+[usbserial-%1]
+pattern = ^usbserial-([0-9]+)$
+device = /dev/cu.usbserial-%m1
diff --git a/devenv.lock b/devenv.lock
new file mode 100644
index 0000000..4f4b3f4
--- /dev/null
+++ b/devenv.lock
@@ -0,0 +1,103 @@
+{
+ "nodes": {
+ "devenv": {
+ "locked": {
+ "dir": "src/modules",
+ "lastModified": 1778546030,
+ "narHash": "sha256-Fsly+oPQRmfwMCovH4qCkhjHnTi7k3KUwS1o16Qj5Lk=",
+ "owner": "cachix",
+ "repo": "devenv",
+ "rev": "bc9c0ba8d505476908739dbc5706e06b76afd091",
+ "type": "github"
+ },
+ "original": {
+ "dir": "src/modules",
+ "owner": "cachix",
+ "repo": "devenv",
+ "type": "github"
+ }
+ },
+ "nixpkgs": {
+ "inputs": {
+ "nixpkgs-src": "nixpkgs-src"
+ },
+ "locked": {
+ "lastModified": 1778507786,
+ "narHash": "sha256-HzSQCKMsMr8r55LwM1JuzIOB+8bzk0FEv6sItKvsfoY=",
+ "owner": "cachix",
+ "repo": "devenv-nixpkgs",
+ "rev": "8f24a228a782e24576b155d1e39f0d914b380691",
+ "type": "github"
+ },
+ "original": {
+ "owner": "cachix",
+ "ref": "rolling",
+ "repo": "devenv-nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs-src": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1778274207,
+ "narHash": "sha256-I4puXmX1iovcCHZlRmztO3vW0mAbbRvq4F8wgIMQ1MM=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "b3da656039dc7a6240f27b2ef8cc6a3ef3bccae7",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixpkgs-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs-unstable": {
+ "locked": {
+ "lastModified": 1778458615,
+ "narHash": "sha256-cY07EsdhBJ8tFXPzDYevgqxRev9ZLxFonuq9wmq5kwg=",
+ "owner": "nixos",
+ "repo": "nixpkgs",
+ "rev": "c6e5ca3c836a5f4dd9af9f2c1fc1c38f0fac988a",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nixos",
+ "ref": "nixpkgs-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "devenv": "devenv",
+ "nixpkgs": "nixpkgs",
+ "nixpkgs-unstable": "nixpkgs-unstable",
+ "rust-overlay": "rust-overlay"
+ }
+ },
+ "rust-overlay": {
+ "inputs": {
+ "nixpkgs": [
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1778469574,
+ "narHash": "sha256-NTZzJ7xJvMXOonYqut3WLUhryeZj5QuuL0ANcqS7d30=",
+ "owner": "oxalica",
+ "repo": "rust-overlay",
+ "rev": "4852a8aa041c94af55e136cde5b8b6d42c3563e8",
+ "type": "github"
+ },
+ "original": {
+ "owner": "oxalica",
+ "repo": "rust-overlay",
+ "type": "github"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+} \ No newline at end of file
diff --git a/devenv.nix b/devenv.nix
new file mode 100644
index 0000000..3c70e45
--- /dev/null
+++ b/devenv.nix
@@ -0,0 +1,90 @@
+{
+ lib,
+ pkgs,
+ config,
+ inputs,
+ ...
+}:
+{
+ name = "apidae-systems";
+
+ infoSections = {
+ name = [ config.name ];
+ };
+
+ scripts = {
+ slides.exec = "bun dev";
+ up.exec = ''devenv up "$@"'';
+ clean.exec = "git clean -fdX";
+ docs.exec = "bunx likec4 start";
+ tio.exec = ''HOME="$DEVENV_ROOT" ${pkgs.tio}/bin/tio "$@"'';
+ };
+
+ enterShell = ''
+ export PATH="$HOME/.cargo/bin:$PATH";
+
+ if [ -f "\$\{ESPUP_EXPORT_FILE:-}" ]; then
+ . "$ESPUP_EXPORT_FILE"
+ elif [ -f "$HOME/export-esp.sh" ]; then
+ . "$HOME/export-esp.sh"
+ fi
+
+ if command -v xtensa-esp-elf-gcc >/dev/null 2>&1; then
+ echo -e "\033[36m[devenv:embassy]:\033[0m\033[32m Espressif Rust toolchain ready 🦀\033[0m"
+ else
+ echo -e "\033[36m[devenv:embassy]:\033[0m\033[34m xtensa-esp-elf-gcc \033[0m\033[31mtoolchain not found ⚠️\033[0m"
+ echo -e "\033[36m[devenv:embassy]:\033[0m\033[33m install with \033[0m\033[35mespup install && direnv allow\033[0m\n"
+ fi
+ '';
+
+ cachix = {
+ enable = true;
+ pull = [
+ "cachix"
+ "oxalica"
+ "devenv"
+ "nixpkgs"
+ "mfarabi"
+ "nix-community"
+ "pre-commit-hooks"
+ ];
+ };
+
+ languages = rec {
+ nix.enable = true;
+ shell.enable = true;
+ cplusplus.enable = true;
+
+ c = {
+ enable = true;
+ debugger = pkgs.gdb;
+ };
+
+ rust = {
+ enable = true;
+ channel = "stable";
+ # lld.enable = true; # FIXME: breaks dioxus
+ # mold.enable = true; # FIXME: breaks loco
+
+ components = [
+ "rustc"
+ "cargo"
+ "clippy"
+ "rustfmt"
+ "rust-std"
+ "rust-src"
+ "rust-analyzer"
+ ];
+ };
+
+ typescript.enable = javascript.enable;
+
+ javascript = rec {
+ enable = true;
+ bun.enable = enable;
+ package = pkgs.nodejs_24;
+ # FIXME: find out why this crashes for intel macbooks
+ # pnpm.enable = !(pkgs.stdenv.isDarwin && pkgs.stdenv.isx86_64);
+ };
+ };
+}
diff --git a/devenv.yaml b/devenv.yaml
new file mode 100644
index 0000000..4086210
--- /dev/null
+++ b/devenv.yaml
@@ -0,0 +1,12 @@
+# yaml-language-server: $schema=https://devenv.sh/devenv.schema.json
+allowUnfree: true
+inputs:
+ nixpkgs:
+ url: github:cachix/devenv-nixpkgs/rolling
+ nixpkgs-unstable:
+ url: github:nixos/nixpkgs/nixpkgs-unstable
+ rust-overlay:
+ url: github:oxalica/rust-overlay
+ inputs:
+ nixpkgs:
+ follows: nixpkgs
diff --git a/secrets.yaml b/secrets.yaml
new file mode 100644
index 0000000..4dbafd9
--- /dev/null
+++ b/secrets.yaml
@@ -0,0 +1,36 @@
+BORE_SECRET: ENC[AES256_GCM,data:w/yACL2m2B0=,iv:LW4IgnDVm1QeqHdaGBm9Jo+NDBcUcRlIF/QjOH0r2Sc=,tag:7m1q1LMQ/7Sy+q/QyQ7lvg==,type:str]
+PULUMI_CONFIG_PASSPHRASE: ENC[AES256_GCM,data:EmvRVPiYrA==,iv:avW55lALFRlOdXM99zopJ8pbdMI3t3gRGr1WBv6aTiY=,tag:RfGgSl3FrqmM2TTVUsAHnA==,type:str]
+CONFIG_MQTT_DEFAULT_USERNAME: ENC[AES256_GCM,data:A7Bq4O121Q==,iv:fgJKiJ4PAhQAx4KpeNZjyGwieWCyQ3PvshBr5noFIk4=,tag:RtHP72DFQSz53IfvFSCTVQ==,type:str]
+CONFIG_MQTT_DEFAULT_PASSWORD: ENC[AES256_GCM,data:PHUFLROIwA==,iv:PeOB81UJVgKbtteK9Lpum4ka8JI8Bjese+JAbcmKdWM=,tag:LdMT1d4k41pcm2+GQj5UDQ==,type:str]
+CONFIG_WIFI_CREDENTIALS_STATIC_SSID: ENC[AES256_GCM,data:qSxVTlG6,iv:YlWlVdK3odmyfvlAwmgngqXrJX9uydlbfXu+CoYFuKE=,tag:ZTMhfvVuENx2batPohIygg==,type:str]
+CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD: ENC[AES256_GCM,data:uEHQuOaROFsGffdByA==,iv:PUnl87JpC1ga5rw9DdQJFRWGYRRJS58p7BjU7qUsi38=,tag:fs6VUCh4yjxYhCrsfy/rBw==,type:str]
+HOME_ASSISTANT_USERNAME: ENC[AES256_GCM,data:xek5e0wxQg==,iv:ZH6VP+q/g5PTnLctp97gf2F7NU5xBBqz7DoRjWXxYCw=,tag:g5BxgiugsVwYg6KKoSpIfg==,type:str]
+HOME_ASSISTANT_PASSWORD: ENC[AES256_GCM,data:FQB8P3JGAA==,iv:3SnJHadI96es0qOoA44U7Y5rFNwEzJFGUfzZKGx/cFI=,tag:n7uCDNIXFA+kdipuPCGzlA==,type:str]
+PG_SUPERUSER_PASSWORD: ENC[AES256_GCM,data:OYv9KaoEXg==,iv:JwoSv/ESbMFdlEdRn+8CZBDfQJ4EUPVx27ZLeKuufWY=,tag:c42qM3HoDq/BXgrIvTAinQ==,type:str]
+RAD_PASSPHRASE: ENC[AES256_GCM,data:hQ+k4SBUwA==,iv:MGPAHHRbAhczf5v9+Pfnn0T1q7ShKZTH6d9OJ+HRiOg=,tag:N7zMvX8E42UMVy16e+F/Yw==,type:str]
+GRAFANA_ADMIN_PASSWORD: ENC[AES256_GCM,data:WQ8PYmF+OQ==,iv:4u2/4ybcIe2M882FTOUp3PQ2ZbnmGxtLLGBBQ9vaHdQ=,tag:a0d4ZRxY5HMh6TQF+WvDMQ==,type:str]
+GRAFANA_SMTP_USER: ENC[AES256_GCM,data:RghJU9UAvKUJO03CKTcxcjnNucZA9MI=,iv:T2+8tX9YEWoLQB3ao60qq7cE+Hgr5FuuqOye+UK+T6I=,tag:8dijd/cmh+z8H4+xe0ad4A==,type:str]
+GF_AUTH_GITHUB_CLIENT_ID": ENC[AES256_GCM,data:iKQKWQILGXkduNgjfyQriixo0XQ=,iv:OhFS7b6SadQPfBeQvhpTZMh38uS5StK/6mVmOeILnQ0=,tag:miZbSoof1U4DfDFW0X+ciA==,type:str]
+GF_AUTH_GITHUB_CLIENT_SECRET: ENC[AES256_GCM,data:KjYJu30/fWUDqOQMwksaFStrTND+N1/c+cxC6rug5nZZqQPdlxPLPw==,iv:Rxyjg9sgh/JPXuYhCmYoIzgOzyNCX1+relxfVKWnOjI=,tag:4C8dGpwHsk3dUw7w/xryIQ==,type:str]
+GF_AUTH_GOOGLE_CLIENT_ID: ENC[AES256_GCM,data:m9vek+/NtSQw28sFWX9YFnLSVCeyDAoEtmIkbKceKb8tnopbO6fJolxzOY7TtPRqGEEP124dEZeqA1vWtBiA0SGKF2/fwhkS,iv:zaRLRMfh/Er8yY2A7M45DYIAeOI8Gy3ggf8UsJi06AA=,tag:4hPT2LDTDvEeMDLt40Qw1g==,type:str]
+GF_AUTH_GOOGLE_CLIENT_SECRET: ENC[AES256_GCM,data:B41d/yX3itZDvg6oDn4pOhAKcfLyj0QuvPPtDffdjwiRMaw=,iv:WrR6q+fTz/r95RLUN6Rb6jbfTf3sA1K9TDG8ahn5nNM=,tag:jbLCUH96MMXmYx9bA3k42A==,type:str]
+GF_SMTP_PASSWORD: ENC[AES256_GCM,data:8aATf53mPHcVwDJhddaKJjbELQ==,iv:LxivSQfyd/CuhEs+4BjnBL8apngsz0aL28taiIl93K0=,tag:55MLL2QvluAmEdhrErkA1w==,type:str]
+AUTHENTIK_SECRET_KEY: ENC[AES256_GCM,data:LU1Ogzs8zKPE2X70CetYN2cfjvRvkkI6NXOLF3mNRe57luM9FL6NtMknNWw=,iv:aQOuDf1LXO6cVKjwxkInxDpI0G8Fg+5/yUh9j6fDksM=,tag:An18RxZGBqD/2QojeXevsQ==,type:str]
+AUTHENTIK_PG_PASSWORD: ENC[AES256_GCM,data:du3iuMRPS0RnvoXulFggYrOZk8d1GTBL,iv:MuKpn5u2eFmjtpcXKRf5HrH9vRzgrFTjEdmHxa0xK8g=,tag:V8Vx4Q8wQhXmM4kiwgZyUw==,type:str]
+sops:
+ lastmodified: "2026-05-05T04:04:00Z"
+ mac: ENC[AES256_GCM,data:112JDZhhyqXOtBIeDJszNksT5bNU7X4Dzceheq7AmcFrdXaj155tC2AzEZFjdva6Z76GDeqLf5/DLzzt+4dHThINQhQwdu+VTwsrj+O0KnBS//e8AnF3iI5OHcDLr1CEDfnpuxpD5vJPTZtoSK26p4Rm3RxsCppm5Jd7YP2SBGQ=,iv:HqBp7knGv2rNca6luep2Ld0CwVs+LoyT9EVbhQgv1yo=,tag:zNzRBnyG7oVX6xB+CQ+y3w==,type:str]
+ pgp:
+ - created_at: "2026-04-28T20:44:44Z"
+ enc: |-
+ -----BEGIN PGP MESSAGE-----
+
+ hF4DT/zq4TKK4tISAQdAsu9uPEWXNO7M/qnQdGfEilgsWtSHZBP5bJz2NwOOHRMw
+ J2617MRtb6QdXlB+eS0Ay3Zm6FOz2GgCJoU79og+mmz2bgMw0bT2CFU9AH7cMa3Z
+ 0l4BSPBOLh97VfTj8edFinEVOm7Sm/IrQKAGMYgy1RI4yoaPm66tRJGj3Zxv8t4C
+ 0Aq0qYtBNL3oloqYMMyQdGOblnq3UvxNRunxa9XQR8VlcvvnZ/Lcsd5vQizVxo60
+ =U2wP
+ -----END PGP MESSAGE-----
+ fp: CBCB4080280BF78518B3047B306B94DA2CE6198A
+ unencrypted_suffix: _unencrypted
+ version: 3.12.2