From 8ecbba1a2aa76df6fa65fc4050cfad604eeeae26 Mon Sep 17 00:00:00 2001 From: James Maes Date: Wed, 29 Jul 2026 07:50:56 -0500 Subject: [PATCH 1/5] feat(site): north-star content system - status badges, in-dev banner, content policy Lay the foundation the rest of the north-star content cleanup depends on: - Add CONTENT-POLICY.md capturing the site's three hard guardrails (not available today, no invented data as real, in-development status must be discoverable) so future page rewrites keep the site honest-but-ambitious. - Add src/lib/status.ts as the typed, single source of truth for what's genuinely available now (build/run nunciod + nuncio-cli from source, IMAP/SMTP sync, FTS5 search, MBOX/EML/JSON export, WORM audit chain) vs. what's still on the roadmap (JMAP, CalDAV, CardDAV, live filter firing, at-rest encryption, HTML sanitization, Desktop/TUI/MCP clients), seeded from docs/ROADMAP.md in the engine repo. - Add StatusBadge (shipped | in-progress | planned | available-now) and an AvailableNow convenience wrapper for marking individual claims on a page. - Add DevStatusRibbon, a site-wide banner rendered from layout.tsx linking to the public roadmap, so every route carries the in-development signal. - Header: add a Roadmap nav link and replace the "Download Latest Release" CTA with "Notify Me at Launch" (temporarily pointed at GitHub until a #notify section exists). Also unblock the lint gate itself, which had never been runnable in this repo (no eslint.config.* existed): add the missing flat config, and downgrade eslint from ^10.7.0 to ^9.39.5 since eslint-config-next 16.1.6's bundled plugins (eslint-plugin-react et al.) have no release compatible with ESLint 10 yet. Fix the react/no-unescaped-entities errors that lint surfaced once it could actually run. --- CONTENT-POLICY.md | 69 +++++ eslint.config.mjs | 6 + package-lock.json | 465 +++++++++++++++++++++++++---- package.json | 2 +- src/app/docs/nsql-spec/page.tsx | 2 +- src/app/docs/webhooks/page.tsx | 2 +- src/app/layout.tsx | 2 + src/components/DevStatusRibbon.tsx | 31 ++ src/components/DocsHub.tsx | 4 +- src/components/Header.tsx | 39 ++- src/components/StatusBadge.tsx | 63 ++++ src/lib/status.ts | 137 +++++++++ 12 files changed, 745 insertions(+), 77 deletions(-) create mode 100644 CONTENT-POLICY.md create mode 100644 eslint.config.mjs create mode 100644 src/components/DevStatusRibbon.tsx create mode 100644 src/components/StatusBadge.tsx create mode 100644 src/lib/status.ts diff --git a/CONTENT-POLICY.md b/CONTENT-POLICY.md new file mode 100644 index 0000000..6cff5d5 --- /dev/null +++ b/CONTENT-POLICY.md @@ -0,0 +1,69 @@ +# Content Policy — Nuncio Website + +Nuncio is pre-alpha. This site is allowed — encouraged — to sell what Nuncio +**will be**, boldly and without hedging. That is the north star: an +aspirational, confident sales site for a product under active construction. +Ambition is not the problem we're solving for; dishonesty is. + +That tradeoff only works if every contributor (human or AI) holds the line on +three hard guardrails. They are not style preferences — they are the +difference between "ambitious" and "fraudulent." + +## The three guardrails + +### 1. Not available today + +Nothing on this site may claim the product can be installed, downloaded, or +run by an end user today, because it cannot. Concretely: + +- No **"Download"**, **"Latest Release"**, **"Install now"**, or equivalent + CTA that implies a shippable build exists for end users. +- Approved CTAs instead: **"Notify me at launch"**, **"Follow the build → + GitHub"** (linking to ), and **"See + the roadmap →"** (linking to + ). +- It is fine — good, even — to tell a developer they can clone the repo and + build the daemon (`nunciod`) and reference CLI (`nuncio-cli`) from source + today. That is real and current. "Download the app" is not. +- See `src/lib/status.ts` for the maintained, typed list of what is genuinely + available now versus what is vision. Pages should import from there, not + hard-code availability claims. + +### 2. No invented data as real + +- Benchmarks, performance numbers, and comparison claims must either cite a + measurement methodology/source or be omitted entirely. Never present a + made-up number as a real result. +- Screenshots of the Desktop GUI, TUI, or any other not-yet-built interface + must be clearly labeled as product previews / mockups / concept renders — + never presented as captures of a real running build. +- Feature comparison tables (e.g. "vs Superhuman," "vs Gmail") may describe + Nuncio's target design honestly labeled as such, but must not claim Nuncio + currently beats a competitor on a capability it doesn't yet have. + +### 3. In-development status must be discoverable + +- Every route must carry a tasteful, confident signal that Nuncio is under + active development, linking to the roadmap + (). This is currently + implemented as a site-wide banner rendered from `src/app/layout.tsx`. +- The signal should read as "we're building something ambitious, come watch + or help," not as an apology. Confidence and honesty are not in tension. +- `StatusBadge` (`src/components/StatusBadge.tsx`) exists so any page can mark + an individual claim as `shipped`, `in-progress`, or `planned` (or + `available-now`) inline, rather than burying the caveat in a footnote. + +## How to use this in practice + +- When writing new copy: write the ambitious version first, then run it + against the three guardrails above. If a sentence would mislead a reader + into thinking they can use the product today, or presents a fabricated + number/screenshot as real, or hides the project's stage — fix the sentence, + don't cut the ambition. +- When adding a feature claim to a page, check `src/lib/status.ts` first. If + the capability isn't listed there as shipped, either add it honestly as + `planned`/`in-progress`, or don't claim it yet. +- This policy governs page copy, marketing components, comparison pages, and + any AI-assisted content generation for this repository. It does not + override licensing, privacy, or legal text, which have their own accuracy + requirements independent of this document. diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..9d1ae2f --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,6 @@ +import nextConfig from "eslint-config-next"; + +/** @type {import('eslint').Linter.Config[]} */ +const eslintConfig = [...nextConfig]; + +export default eslintConfig; diff --git a/package-lock.json b/package-lock.json index 2276c0f..506f4e1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,7 +25,7 @@ "@types/node": "^24.1.0", "@types/react": "19.2.17", "@types/react-dom": "19.2.3", - "eslint": "^10.7.0", + "eslint": "^9.39.5", "eslint-config-next": "16.1.6" }, "engines": { @@ -360,68 +360,167 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.23.5", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.5.tgz", - "integrity": "sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==", + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", + "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/object-schema": "^3.0.5", + "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", - "minimatch": "^10.2.4" + "minimatch": "^3.1.5" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.17", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.17.tgz", + "integrity": "sha512-w+aeW/mkgM4PyRMOJCgi3fOrTm5Q8QY1OSfn2TO2iuDj3ezIHqejmuxbjfPrqUkgqRew1iqkyAn0tr0ZwHD9+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, "node_modules/@eslint/config-helpers": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.6.0.tgz", - "integrity": "sha512-ii6Bw9jJ2zi2cWA2Z+9/QZ/+3DX6kwaV5Q986D/CdP3Lap3w/pgQZ373FV7byY/i7L4IRH/G43I5dz1ClsCbpA==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^1.2.1" + "@eslint/core": "^0.17.0" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/core": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.1.tgz", - "integrity": "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==", + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", "dev": true, "license": "Apache-2.0", "dependencies": { "@types/json-schema": "^7.0.15" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.6.tgz", + "integrity": "sha512-l2Ul9PrHsPCKcEY/ac7VgFj9D80C7S68sOKc618SyHDPK36s1XcFebXY0iTzUVn4Yq+YbwvSnDmCz9yxjX+QrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.14.0", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.3.0", + "minimatch": "^3.1.5", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.17", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.17.tgz", + "integrity": "sha512-w+aeW/mkgM4PyRMOJCgi3fOrTm5Q8QY1OSfn2TO2iuDj3ezIHqejmuxbjfPrqUkgqRew1iqkyAn0tr0ZwHD9+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.5", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.5.tgz", + "integrity": "sha512-QywQuszQh77pIXCsq998c8hbhSTI/azTty1Z6N53dmAudKHhy573j3yvRLsX2BSp8YpLtoCEG8E9DJe+8zUh4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" } }, "node_modules/@eslint/object-schema": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.5.tgz", - "integrity": "sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==", + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", "dev": true, "license": "Apache-2.0", "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/plugin-kit": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.2.tgz", - "integrity": "sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^1.2.1", + "@eslint/core": "^0.17.0", "levn": "^0.4.1" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@floating-ui/core": { @@ -1839,13 +1938,6 @@ "tslib": "^2.4.0" } }, - "node_modules/@types/esrecurse": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", - "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/estree": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", @@ -2495,9 +2587,9 @@ ] }, "node_modules/acorn": { - "version": "8.17.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz", - "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", + "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", "dev": true, "license": "MIT", "bin": { @@ -2534,6 +2626,29 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, "node_modules/aria-hidden": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", @@ -2901,6 +3016,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001806", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001806.tgz", @@ -2921,6 +3046,23 @@ ], "license": "CC-BY-4.0" }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", @@ -2936,6 +3078,26 @@ "node": ">=6" } }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -3393,33 +3555,33 @@ } }, "node_modules/eslint": { - "version": "10.7.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.7.0.tgz", - "integrity": "sha512-GVTD7s1vdIl6UYvAfriOPeY1Df8LIZjfofLvHwde+erDHGGuHyuM6xoxRxmHiebhYuD2p1vN4wWh0XzPARSGDQ==", + "version": "9.39.5", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.5.tgz", + "integrity": "sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==", "dev": true, "license": "MIT", - "workspaces": [ - "packages/*" - ], "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", - "@eslint-community/regexpp": "^4.12.2", - "@eslint/config-array": "^0.23.5", - "@eslint/config-helpers": "^0.6.0", - "@eslint/core": "^1.2.1", - "@eslint/plugin-kit": "^0.7.2", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.2", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.6", + "@eslint/js": "9.39.5", + "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.14.0", + "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^9.1.2", - "eslint-visitor-keys": "^5.0.1", - "espree": "^11.2.0", - "esquery": "^1.7.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", @@ -3429,7 +3591,8 @@ "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "minimatch": "^10.2.4", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.5", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, @@ -3437,7 +3600,7 @@ "eslint": "bin/eslint.js" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://eslint.org/donate" @@ -3735,19 +3898,17 @@ } }, "node_modules/eslint-scope": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", - "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "@types/esrecurse": "^4.3.1", - "@types/estree": "^1.0.8", "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -3766,19 +3927,76 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.17", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.17.tgz", + "integrity": "sha512-w+aeW/mkgM4PyRMOJCgi3fOrTm5Q8QY1OSfn2TO2iuDj3ezIHqejmuxbjfPrqUkgqRew1iqkyAn0tr0ZwHD9+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/espree": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", - "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.16.0", + "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^5.0.1" + "eslint-visitor-keys": "^4.2.1" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -4118,6 +4336,19 @@ "node": ">=10.13.0" } }, + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/globalthis": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", @@ -4167,6 +4398,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/has-property-descriptors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", @@ -4265,6 +4506,23 @@ "node": ">= 4" } }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -4769,6 +5027,29 @@ "dev": true, "license": "MIT" }, + "node_modules/js-yaml": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz", + "integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", @@ -5153,6 +5434,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -5595,6 +5883,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -5879,6 +6180,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/resolve-pkg-maps": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", @@ -6360,6 +6671,19 @@ "node": ">=4" } }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/styled-jsx": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", @@ -6383,6 +6707,19 @@ } } }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", diff --git a/package.json b/package.json index 0f6aa04..61e3554 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "@types/node": "^24.1.0", "@types/react": "19.2.17", "@types/react-dom": "19.2.3", - "eslint": "^10.7.0", + "eslint": "^9.39.5", "eslint-config-next": "16.1.6" }, "overrides": { diff --git a/src/app/docs/nsql-spec/page.tsx b/src/app/docs/nsql-spec/page.tsx index 2f714cd..340f87d 100644 --- a/src/app/docs/nsql-spec/page.tsx +++ b/src/app/docs/nsql-spec/page.tsx @@ -79,7 +79,7 @@ WITH STOP PROCESSING;`} Microsecond Dry-Run Preview Engine

- Before saving or persisting any NSQL rule, execute `nuncio filter test --sql "..."` to run a zero-mutation memory simulation against your 100,000+ message database in under 10ms. + Before saving or persisting any NSQL rule, execute `nuncio filter test --sql "..."` to run a zero-mutation memory simulation against your 100,000+ message database in under 10ms.

diff --git a/src/app/docs/webhooks/page.tsx b/src/app/docs/webhooks/page.tsx index b97f007..cea1a3f 100644 --- a/src/app/docs/webhooks/page.tsx +++ b/src/app/docs/webhooks/page.tsx @@ -23,7 +23,7 @@ export default function WebhooksDocPage() { HMAC-SHA256 Signed Webhooks & SSRF Defense

- When an NSQL filter rule executes `CALL WEBHOOK 'url'`, `nunciod` dispatches an HTTP POST payload verified with cryptographic signatures and strict network safety bounds. + When an NSQL filter rule executes `CALL WEBHOOK 'url'`, `nunciod` dispatches an HTTP POST payload verified with cryptographic signatures and strict network safety bounds.

diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 24314ae..396efa3 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,5 +1,6 @@ import type { Metadata, Viewport } from "next"; import "./globals.css"; +import { DevStatusRibbon } from "@/components/DevStatusRibbon"; export const viewport: Viewport = { themeColor: "#0B0F19", @@ -61,6 +62,7 @@ export default function RootLayout({ return ( + {children} diff --git a/src/components/DevStatusRibbon.tsx b/src/components/DevStatusRibbon.tsx new file mode 100644 index 0000000..e53e790 --- /dev/null +++ b/src/components/DevStatusRibbon.tsx @@ -0,0 +1,31 @@ +import React from "react"; +import { Rocket, ArrowRight } from "lucide-react"; +import { ROADMAP_URL } from "@/lib/status"; + +/** + * Site-wide "in active development" signal (CONTENT-POLICY.md guardrail + * #3). Rendered once from src/app/layout.tsx so every route carries it + * without every page needing to remember to include it. + * + * Deliberately not apologetic: Nuncio is pre-alpha, and this bar says so + * plainly while pointing at the roadmap as the proof of momentum. + */ +export function DevStatusRibbon() { + return ( + + + + Nuncio is in active development — building in the open, not shipping vapor. + + + See the roadmap + + + + ); +} diff --git a/src/components/DocsHub.tsx b/src/components/DocsHub.tsx index 6368105..6be223b 100644 --- a/src/components/DocsHub.tsx +++ b/src/components/DocsHub.tsx @@ -257,7 +257,7 @@ WITH STOP PROCESSING;`}
  • • recipient / to: Recipient email address
  • • body: Plain text / HTML body
  • • size_bytes / size: Attachment & message size
  • -
  • • header['X-Spam']: Custom MIME headers
  • +
  • • header['X-Spam']: Custom MIME headers
  • @@ -290,7 +290,7 @@ WITH STOP PROCESSING;`} HMAC-SHA256 Signed Webhooks & SSRF Defense

    - When an NSQL rule triggers a `CALL WEBHOOK 'url'` action, `nunciod` dispatches an HTTP POST payload with cryptographic signatures. + When an NSQL rule triggers a `CALL WEBHOOK 'url'` action, `nunciod` dispatches an HTTP POST payload with cryptographic signatures.

    diff --git a/src/components/Header.tsx b/src/components/Header.tsx index 78704e8..046b94a 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -2,7 +2,8 @@ import React, { useState } from "react"; import Link from "next/link"; -import { Terminal, Download, Menu, X } from "lucide-react"; +import { Bell, Map, Menu, X } from "lucide-react"; +import { GITHUB_URL, ROADMAP_URL } from "@/lib/status"; export function Header() { const [mobileMenuOpen, setMobileMenuOpen] = useState(false); @@ -46,19 +47,29 @@ export function Header() { Documentation + + Roadmap + About - {/* CTA & Downloads */} + {/* CTA */} @@ -97,17 +108,29 @@ export function Header() { setMobileMenuOpen(false)} className="block py-2 border-b border-white/5 hover:text-white"> Documentation + setMobileMenuOpen(false)} + className="flex items-center gap-1.5 py-2 border-b border-white/5 hover:text-white" + > + + Roadmap + setMobileMenuOpen(false)} className="block py-2 border-b border-white/5 hover:text-white"> About diff --git a/src/components/StatusBadge.tsx b/src/components/StatusBadge.tsx new file mode 100644 index 0000000..04b8979 --- /dev/null +++ b/src/components/StatusBadge.tsx @@ -0,0 +1,63 @@ +import React from "react"; +import { CheckCircle2, Circle, Loader2, Zap } from "lucide-react"; +import type { StatusVariant } from "@/lib/status"; + +interface StatusBadgeProps { + variant: StatusVariant; + /** Override the default label for this variant. */ + label?: string; + className?: string; +} + +const VARIANT_STYLES: Record< + StatusVariant, + { defaultLabel: string; classes: string; icon: React.ReactNode } +> = { + "available-now": { + defaultLabel: "Available now", + classes: "bg-blue-500/15 text-blue-300 border-blue-500/40", + icon: , + }, + shipped: { + defaultLabel: "Shipped", + classes: "bg-emerald-500/15 text-emerald-300 border-emerald-500/40", + icon: , + }, + "in-progress": { + defaultLabel: "In progress", + classes: "bg-amber-500/15 text-amber-300 border-amber-500/40", + icon: , + }, + planned: { + defaultLabel: "Planned", + classes: "bg-slate-500/15 text-slate-300 border-slate-500/40", + icon: , + }, +}; + +/** + * Small, theme-aware pill for marking the real status of a claim on the + * page: shipped, in-progress, planned, or available-now. Backed by the + * typed status list in src/lib/status.ts — see CONTENT-POLICY.md. + */ +export function StatusBadge({ variant, label, className = "" }: StatusBadgeProps) { + const style = VARIANT_STYLES[variant]; + + return ( + + {style.icon} + {label ?? style.defaultLabel} + + ); +} + +/** + * Convenience wrapper for the "available-now" variant — use this to flag + * the small set of things a developer can genuinely do today (build the + * daemon, run the CLI, etc.) without repeating the variant name everywhere. + */ +export function AvailableNow({ label, className }: { label?: string; className?: string }) { + return ; +} diff --git a/src/lib/status.ts b/src/lib/status.ts new file mode 100644 index 0000000..7fc73ca --- /dev/null +++ b/src/lib/status.ts @@ -0,0 +1,137 @@ +/** + * Single source of truth for what Nuncio can genuinely do today versus what + * is on the roadmap. Pages must import from here rather than hard-coding + * availability claims in copy — see CONTENT-POLICY.md guardrail #1. + * + * Seeded from the engine roadmap (nuncio/docs/ROADMAP.md). Update this file + * when a milestone in that roadmap actually lands — not before. + */ + +export type StatusVariant = "available-now" | "shipped" | "in-progress" | "planned"; + +export interface StatusItem { + /** Stable slug for lookups / React keys. */ + id: string; + /** Short label suitable for a badge or list item. */ + label: string; + /** One of the four status variants. */ + status: StatusVariant; + /** Optional longer copy for a tooltip, card, or detail page. */ + detail?: string; +} + +export const ROADMAP_URL = "https://koftwentytwo.github.io/nuncio/roadmap/"; +export const GITHUB_URL = "https://github.com/KofTwentyTwo/nuncio"; + +/** + * Genuinely usable today by a developer willing to build from source. No + * packaged installer exists yet — see CONTENT-POLICY.md guardrail #1 for why + * "Download" CTAs are banned even though these items are real. + */ +export const AVAILABLE_NOW: StatusItem[] = [ + { + id: "build-daemon", + label: "Build & run the nunciod daemon from source", + status: "available-now", + detail: + "Clone the repo, cargo build --workspace, and run the daemon locally. It serves a gRPC API on loopback.", + }, + { + id: "reference-cli", + label: "Drive it with the nuncio-cli reference client", + status: "available-now", + detail: "The in-repo CLI is a full gRPC client and the E2E driver for the engine.", + }, + { + id: "imap-smtp-sync", + label: "Multi-account IMAP / SMTP sync", + status: "available-now", + detail: "Real IMAP fetch -> store -> read -> SMTP send, tested against mock servers.", + }, + { + id: "fts5-search", + label: "SQLite FTS5 full-text search", + status: "available-now", + detail: "Local full-text search over synced mail, backed by SQLite FTS5.", + }, + { + id: "export", + label: "MBOX / EML / JSON export", + status: "available-now", + detail: "Export synced mail to standard, portable formats — no lock-in.", + }, + { + id: "worm-audit", + label: "WORM audit chain", + status: "available-now", + detail: "An append-only, hash-chained audit ledger for actions taken against your mail.", + }, +]; + +/** + * Vision items: real engineering targets on the roadmap, not yet available + * to end users. Do not mark anything here "shipped" until the corresponding + * roadmap milestone is actually done — see CONTENT-POLICY.md guardrail #2. + */ +export const ON_THE_ROADMAP: StatusItem[] = [ + { + id: "jmap", + label: "JMAP protocol support", + status: "planned", + detail: "A second mail backend alongside IMAP/SMTP.", + }, + { + id: "caldav", + label: "CalDAV calendar sync", + status: "planned", + detail: "Calendar sync exposed end-to-end over the API; the engine transport exists but isn't wired up yet.", + }, + { + id: "carddav", + label: "CardDAV contacts sync", + status: "planned", + detail: "Contacts sync and persistence, brought to parity with mail and calendar.", + }, + { + id: "filters-firing", + label: "Filters actually firing on synced mail", + status: "planned", + detail: "Rules can be created and dry-run tested today; wiring them into the live sync path is still ahead.", + }, + { + id: "at-rest-encryption", + label: "At-rest body encryption", + status: "planned", + detail: "Encrypting message bodies at rest, hardened as part of the security milestone.", + }, + { + id: "html-sanitization", + label: "HTML sanitization", + status: "planned", + detail: "A sandboxed HTML email rendering pipeline for clients.", + }, + { + id: "desktop-gui", + label: "Desktop GUI client", + status: "planned", + detail: "A native desktop app consuming the frozen gRPC API — a separate client repo.", + }, + { + id: "terminal-tui", + label: "Terminal TUI client", + status: "planned", + detail: "A keyboard-driven terminal client consuming the frozen gRPC API.", + }, + { + id: "mcp-client", + label: "MCP client", + status: "planned", + detail: "An MCP bridge letting AI agents talk to Nuncio through a governed gateway.", + }, +]; + +export const ALL_STATUS_ITEMS: StatusItem[] = [...AVAILABLE_NOW, ...ON_THE_ROADMAP]; + +export function getStatusItem(id: string): StatusItem | undefined { + return ALL_STATUS_ITEMS.find((item) => item.id === id); +} -- 2.54.0 From b52405410ad3380e410bb41956596dcd9817ec33 Mon Sep 17 00:00:00 2001 From: James Maes Date: Wed, 29 Jul 2026 08:05:14 -0500 Subject: [PATCH 2/5] feat(site): north-star home + section content Rewrite the home page hero and section components to sell the vision without implying the product is installable today. - Hero: replace Download/Latest Release CTAs with Notify-me, Follow-the- build (GitHub), and See-the-roadmap; badge unshipped trust claims. - DownloadsSection: convert from a release-download panel into a follow-the-build / notify-me-at-launch section, plus the real build-from-source instructions. - FourExperiencesSection: mark the CLI available-now and the desktop GUI/TUI/MCP client as planned via StatusBadge; drop fake "Most Popular" badges and dead download links. - ParityMatrixSection: reframe "100% parity" as the architecture's design goal (one gRPC contract, no drift) and drive per-capability status from real engine state instead of a blanket parity checkmark. - ShellInteractivePreview: label the CLI/TUI/GUI/MCP mockup as a product preview, replace the real inbox with genericized sample content, and drop invented timing/benchmark numbers. - ManifestoPillarsSection/ComparisonSection/DocsTeaserSection: reframe shipped-sounding claims (encryption, AI policy, benchmarks) as vision or badge them against the real status list. --- src/components/ComparisonSection.tsx | 22 +-- src/components/DocsTeaserSection.tsx | 4 +- src/components/DownloadsSection.tsx | 196 ++++++++++----------- src/components/FourExperiencesSection.tsx | 95 +++++----- src/components/Hero.tsx | 40 +++-- src/components/ManifestoPillarsSection.tsx | 26 ++- src/components/ParityMatrixSection.tsx | 62 ++++--- src/components/ShellInteractivePreview.tsx | 54 +++--- 8 files changed, 277 insertions(+), 222 deletions(-) diff --git a/src/components/ComparisonSection.tsx b/src/components/ComparisonSection.tsx index cddaea5..ff05558 100644 --- a/src/components/ComparisonSection.tsx +++ b/src/components/ComparisonSection.tsx @@ -6,15 +6,15 @@ import { Check, X, Sparkles, ArrowRight, ShieldCheck, Zap } from "lucide-react"; export function ComparisonSection() { const competitorCards = [ - { name: "Airmail", platform: "macOS / iOS", price: "$29.99 / yr", href: "/vs/airmail", desc: "Compare Nuncio to Airmail for Mac and iOS." }, - { name: "Canary Mail", platform: "macOS / iOS / Win", price: "$20.00 / yr", href: "/vs/canary-mail", desc: "Compare Nuncio to Canary Mail AI email." }, - { name: "Spark Mail", platform: "macOS / Win / iOS", price: "$59.99 / yr", href: "/vs/spark-mail", desc: "Compare Nuncio to Spark Premium Desktop." }, - { name: "Superhuman", platform: "macOS / Web", price: "$360.00 / yr", href: "/vs/superhuman", desc: "Why pay $360/yr when Nuncio is 100% free?" }, - { name: "HEY Mail", platform: "Web / iOS / Mac", price: "$99.00 / yr", href: "/vs/hey", desc: "Sovereign local privacy vs closed HEY servers." }, - { name: "Apple Mail", platform: "macOS", price: "Free (Proprietary)", href: "/vs/apple-mail", desc: "4 interfaces & NSQL filtering vs Apple Mail." }, - { name: "Outlook 365", platform: "Windows / Mac", price: "$6.99+ / mo", href: "/vs/outlook", desc: "Microsecond SQLite speed vs Outlook telemetry." }, - { name: "Mozilla Thunderbird", platform: "Linux / Win / Mac", price: "Free Open Source", href: "/vs/thunderbird", desc: "Modern Rust architecture vs legacy Thunderbird." }, - { name: "Gmail", platform: "Web", price: "Free (Ad-Tracked)", href: "/vs/gmail", desc: "100% zero-tracking privacy vs Gmail data mining." }, + { name: "Airmail", platform: "macOS / iOS", price: "$29.99 / yr", href: "/vs/airmail", desc: "How Nuncio's sovereign design compares to Airmail for Mac and iOS." }, + { name: "Canary Mail", platform: "macOS / iOS / Win", price: "$20.00 / yr", href: "/vs/canary-mail", desc: "How Nuncio's local-first AI gateway compares to Canary Mail's cloud AI." }, + { name: "Spark Mail", platform: "macOS / Win / iOS", price: "$59.99 / yr", href: "/vs/spark-mail", desc: "How Nuncio compares to Spark Premium Desktop." }, + { name: "Superhuman", platform: "macOS / Web", price: "$360.00 / yr", href: "/vs/superhuman", desc: "A free, open-source alternative to a $360/yr subscription." }, + { name: "HEY Mail", platform: "Web / iOS / Mac", price: "$99.00 / yr", href: "/vs/hey", desc: "Sovereign local storage vs HEY's closed, hosted servers." }, + { name: "Apple Mail", platform: "macOS", price: "Free (Proprietary)", href: "/vs/apple-mail", desc: "Four planned interfaces & NSQL filtering vs Apple Mail." }, + { name: "Outlook 365", platform: "Windows / Mac", price: "$6.99+ / mo", href: "/vs/outlook", desc: "Local SQLite storage vs Outlook's cloud telemetry." }, + { name: "Mozilla Thunderbird", platform: "Linux / Win / Mac", price: "Free Open Source", href: "/vs/thunderbird", desc: "A modern Rust architecture vs legacy Thunderbird." }, + { name: "Gmail", platform: "Web", price: "Free (Ad-Tracked)", href: "/vs/gmail", desc: "Zero-tracking, local-first privacy vs Gmail's data mining." }, ]; return ( @@ -30,7 +30,9 @@ export function ComparisonSection() { Built for those who demand more.

    - See how Nuncio outperforms traditional desktop clients and expensive cloud subscriptions across Mac, Windows, and Linux. + See how Nuncio's sovereign, local-first design is meant to stack up against traditional + desktop clients and expensive cloud subscriptions — honest about what's built and what's + still ahead.

    diff --git a/src/components/DocsTeaserSection.tsx b/src/components/DocsTeaserSection.tsx index 735a100..43ea19f 100644 --- a/src/components/DocsTeaserSection.tsx +++ b/src/components/DocsTeaserSection.tsx @@ -45,7 +45,9 @@ export function DocsTeaserSection() { Complete Documentation Hub

    - From installation and Google OAuth PKCE to NSQL grammar specs, HMAC webhooks, and AI MCP integration — explore all 10 technical guides in our dedicated docs portal. + From building the daemon and CLI from source to the NSQL grammar spec, signed webhooks, and the AI + MCP integration design — explore all 10 guides in our dedicated docs portal, covering what's + real today and what's ahead on the roadmap.

    diff --git a/src/components/DownloadsSection.tsx b/src/components/DownloadsSection.tsx index 575b4c3..543a1a2 100644 --- a/src/components/DownloadsSection.tsx +++ b/src/components/DownloadsSection.tsx @@ -1,28 +1,27 @@ "use client"; import React, { useState } from "react"; -import { Download, Terminal, Check, Copy, Laptop, Command } from "lucide-react"; +import { Bell, GitBranch, Check, Copy, ArrowRight, Terminal, MapPin } from "lucide-react"; +import { GITHUB_URL, ROADMAP_URL } from "@/lib/status"; export function DownloadsSection() { - const [copiedBrew, setCopiedBrew] = useState(false); - const [copiedCargo, setCopiedCargo] = useState(false); - const [activeChannel, setActiveChannel] = useState<"stable" | "nightly">("stable"); + const [copiedBuild, setCopiedBuild] = useState(false); + const [email, setEmail] = useState(""); + const [submitted, setSubmitted] = useState(false); - const brewCmd = "brew install koftwentytwo/tap/nuncio"; - const cargoCmd = activeChannel === "stable" - ? "cargo install nuncio-cli nuncio-tui nuncio-mcp" - : "cargo install --git https://github.com/KofTwentyTwo/nuncio.git --branch dev nuncio-cli nuncio-tui nuncio-mcp nunciod"; + const buildCmd = "git clone https://github.com/KofTwentyTwo/nuncio.git && cargo build --workspace"; - const handleCopyBrew = () => { - navigator.clipboard.writeText(brewCmd); - setCopiedBrew(true); - setTimeout(() => setCopiedBrew(false), 2000); + const handleCopyBuild = () => { + navigator.clipboard.writeText(buildCmd); + setCopiedBuild(true); + setTimeout(() => setCopiedBuild(false), 2000); }; - const handleCopyCargo = () => { - navigator.clipboard.writeText(cargoCmd); - setCopiedCargo(true); - setTimeout(() => setCopiedCargo(false), 2000); + const handleNotifySubmit = (e: React.FormEvent) => { + e.preventDefault(); + // Placeholder: no backend is wired up yet. This is a visual stand-in + // for the eventual launch-notification signup, not a live capture form. + setSubmitted(true); }; return ( @@ -30,133 +29,124 @@ export function DownloadsSection() {
    - - Install & Download Nuncio Packages -
    - - {/* Release Channel Toggle Pills */} -
    - - + + Nuncio is pre-alpha — there is no installer yet

    - Available for macOS, Windows & Linux + Be there for launch day

    - {activeChannel === "stable" - ? "Free and open-source under MIT & Apache-2.0 licenses. Choose your preferred installer or package manager below." - : "Automated daily snapshot builds compiled directly from the bleeding-edge dev branch."} + There's no packaged app to download today. Follow the build in the open on GitHub, watch the + roadmap for milestones, or leave your email and we'll tell you the moment there's something + to install.

    - {/* GUI Installers Grid */} -
    - {/* macOS */} + {/* Primary CTAs */} +
    + {/* Follow the build */}
    -
    - +
    +
    -

    macOS Universal

    -

    Supports Apple Silicon (M1/M2/M3/M4) & Intel x64.

    +

    Follow the build

    +

    + Every commit, PR, and milestone happens in public. Star the repo to watch progress. +

    - - {activeChannel === "stable" ? "Download macOS Release (.DMG)" : "Download macOS Nightly (.tar.gz)"} + + Follow the build on GitHub
    - {/* Windows */} + {/* Roadmap */}
    -
    - +
    +
    -

    Windows 10 / 11

    -

    Native WiX Installer (.msi) with Windows Keyring support.

    +

    See the roadmap

    +

    + See exactly what's shipped, what's in progress, and what's planned before v1. +

    - - {activeChannel === "stable" ? "Download Windows Release (.MSI)" : "Download Windows Nightly (.ZIP)"} - -
    - - {/* Linux */} -
    -
    -
    - -
    -

    Linux Standalone

    -

    Universal AppImage & Tarball for Ubuntu, Fedora, Arch.

    -
    - - - {activeChannel === "stable" ? "Download Linux Release (.AppImage)" : "Download Linux Nightly (.tar.gz)"} + See the roadmap +
    - {/* Package Manager Options */} -
    -

    Package Manager Commands

    - - {/* Homebrew */} -
    -
    - $ - {brewCmd} + {/* Notify me at launch */} +
    +

    + Notify me at launch +

    + {submitted ? ( +
    + Thanks — we'll let you know the moment there's a build worth installing.
    - -
    + ) : ( +
    + setEmail(e.target.value)} + placeholder="you@example.com" + aria-label="Email address" + className="w-full bg-slate-900/90 border border-white/10 rounded-xl px-4 py-3 text-sm text-white placeholder:text-slate-500 focus:border-blue-500 focus:outline-none shadow-inner" + /> + +
    + )} +

    + This is a placeholder signup — no email list is wired up yet. For real-time progress, GitHub is the + source of truth. +

    +
    - {/* Cargo */} + {/* Build from source today */} +
    +

    + + Developer? You can build it from source right now +

    $ - {cargoCmd} + {buildCmd}
    +

    + Clones the daemon (nunciod) and reference CLI (nuncio-cli) — no packaged + installer, no GUI, no TUI yet. +

    diff --git a/src/components/FourExperiencesSection.tsx b/src/components/FourExperiencesSection.tsx index 46e368d..041012d 100644 --- a/src/components/FourExperiencesSection.tsx +++ b/src/components/FourExperiencesSection.tsx @@ -1,81 +1,89 @@ "use client"; import React from "react"; -import { Terminal, Code, Monitor, Bot, Zap, Sparkles, ShieldCheck, CheckCircle2, ArrowRight } from "lucide-react"; +import { Terminal, Code, Monitor, Bot, Sparkles, CheckCircle2, ArrowRight } from "lucide-react"; +import { StatusBadge } from "./StatusBadge"; +import type { StatusVariant } from "@/lib/status"; export function FourExperiencesSection() { - const experiences = [ + const experiences: Array<{ + id: string; + title: string; + status: StatusVariant; + subtitle: string; + icon: React.ReactNode; + accentColor: string; + description: string; + userBenefits: string[]; + sampleCommand: string; + }> = [ { id: "gui", - title: "1. The Desktop Workspace (Featured GUI)", - badgeText: "Most Popular", - subtitle: "Beautiful Visual Elegance for Everyday Productivity", + title: "1. The Desktop Workspace", + status: "planned", + subtitle: "Beautiful visual elegance for everyday productivity", icon: , accentColor: "border-purple-500/40 bg-purple-500/10 hover:border-purple-500/70 shadow-lg shadow-purple-500/10", - badgeBg: "bg-purple-500/20 text-purple-300 border-purple-500/40 font-bold", description: - "The primary desktop application designed for seamless daily flow. Enjoy a clean, distraction-free inbox with rich email previewing, visual calendar scheduling, and drag-and-drop filter creation.", + "A native desktop app, planned as a thin client over the same gRPC API every other interface uses, designed for seamless daily flow: a clean inbox, visual calendar scheduling, and drag-and-drop filter creation.", userBenefits: [ - "Sandboxed HTML email inspector with automatic tracking pixel neutralization", - "Unified inbox for all your personal, work, and custom domain accounts", + "Sandboxed HTML email inspector with tracking-pixel neutralization", + "Unified inbox across all your personal, work, and custom domain accounts", "Visual drag-and-drop rule builder and interactive calendar planner", - "Blazing-fast native performance with minimal RAM and battery usage", + "Native performance targeting minimal RAM and battery usage", ], - sampleCommand: "Nuncio Desktop App (macOS, Windows, Linux)", + sampleCommand: "Nuncio Desktop App — planned for macOS, Windows, Linux", }, { id: "tui", - title: "2. The Vim Keyboard Terminal (Ratatui TUI)", - badgeText: "Power Users", - subtitle: "Keyboard Velocity for Triage Without Touching the Mouse", + title: "2. The Vim Keyboard Terminal", + status: "planned", + subtitle: "Keyboard velocity for triage without touching the mouse", icon: , accentColor: "border-cyan-500/30 bg-cyan-500/5 hover:border-cyan-500/60", - badgeBg: "bg-cyan-500/20 text-cyan-300 border-cyan-500/30 font-semibold", description: - "Built for developers and power users who demand maximum speed. Process hundreds of inbox messages per minute using intuitive Vim motions, single-key triage chords, and split-view previews.", + "A Ratatui-based terminal client on the roadmap for developers and power users who want maximum speed: Vim motions, single-key triage chords, and split-view previews, all driven by the same engine.", userBenefits: [ "Vim navigation (`j`/`k`/`h`/`l`/`g i`) & single-key archive/delete chords", "Instant split-pane previewer for text & HTML email content", - "Interactive NSQL rule editor & dry-run condition tester built-in", + "Interactive NSQL rule editor & dry-run condition tester built in", "Runs directly in any terminal tab or SSH session", ], - sampleCommand: "nuncio-tui (press 'f' for rules, 'a' for accounts)", + sampleCommand: "nuncio-tui — planned", }, { id: "cli", - title: "3. The Developer Command Shell (POSIX CLI)", - badgeText: "Automations", - subtitle: "Instant Inbox Queries & Automation Right From Your Shell", + title: "3. The Developer Command Shell", + status: "available-now", + subtitle: "Instant inbox queries & automation right from your shell", icon: , accentColor: "border-blue-500/30 bg-blue-500/5 hover:border-blue-500/60", - badgeBg: "bg-blue-500/20 text-blue-300 border-blue-500/30 font-semibold", description: - "Designed for developers, sysadmins, and shell enthusiasts who want effortless scriptability. Search messages, query calendar availability, and trigger custom webhooks directly from command scripts.", + "The in-repo reference client and E2E driver for the engine. Build it from source today to search messages, sync IMAP/SMTP accounts, and drive the daemon over its gRPC API directly from your shell.", userBenefits: [ "Pipeable JSON outputs for shell scripts & custom automations (`--json`)", - "Instant search across 100,000+ messages in under 10 milliseconds", - "Headless background sync daemon (`nunciod`) keeps mail updated silently", - "Simple single-command email dispatching & account management", + "Local SQLite FTS5 full-text search over your synced mail", + "Talks to the headless background sync daemon (`nunciod`) over gRPC", + "Multi-account IMAP sync and SMTP send, tested against mock servers", ], - sampleCommand: "nuncio mail search --query 'urgent' --json", + sampleCommand: "cargo run -p nuncio-cli -- mail search --query 'urgent'", }, { id: "mcp", - title: "4. The AI Executive Assistant (MCP Agent)", - badgeText: "AI Assistant", - subtitle: "AI Co-Pilots Working Alongside You with Granular Privacy", + title: "4. The AI Executive Assistant", + status: "planned", + subtitle: "AI co-pilots working alongside you with granular privacy", icon: , accentColor: "border-emerald-500/30 bg-emerald-500/5 hover:border-emerald-500/60", - badgeBg: "bg-emerald-500/20 text-emerald-300 border-emerald-500/30 font-bold", description: - "Aggregate ALL your email accounts into one local hub. Connect local LLMs and AI agents (Claude, Antigravity, Cursor) through Nuncio's security gateway—never granting uncontrolled direct credentials to Gmail or IMAP. Controlled via WORM audits, RBAC policies, and microsecond SQLite speed.", + "A governed MCP bridge, planned as a separate client, that lets local LLMs and AI agents (Claude, Cursor, and others) talk to Nuncio through a policy gateway — never handed raw IMAP or provider credentials.", userBenefits: [ - "Aggregate unlimited IMAP, JMAP & Gmail accounts into a single local vault", - "Controlled AI Gateway: Zero uncontrolled direct access to raw email providers", - "Immutable HMAC-SHA256 WORM audit ledger logs every AI tool call & email read", - "Sub-10ms local FTS5 search delivers microsecond speed without cloud fees", + "Aggregate multiple accounts into a single local vault the agent can query", + "Controlled AI gateway: no direct, uncontrolled access to raw providers", + "Every AI tool call recorded in the WORM audit ledger", + "Built on the same frozen gRPC contract as every other client", ], - sampleCommand: "nuncio-mcp --stdio (Native Model Context Protocol Server)", + sampleCommand: "nuncio-mcp --stdio — planned", }, ]; @@ -86,13 +94,14 @@ export function FourExperiencesSection() {
    - Four Extraordinary User Experiences + Four Interfaces, One Vision

    One Engine. Four Ways to Work.

    - Whether you prefer a sleek desktop window, lightning terminal keybindings, Unix shell scripts, or AI co-piloting — Nuncio fits your exact daily workflow. + A sleek desktop window, lightning terminal keybindings, Unix shell scripts, and AI co-piloting — all + built on one gRPC contract. The reference CLI is real today; the rest are on the roadmap.

    @@ -116,9 +125,7 @@ export function FourExperiencesSection() {

    {exp.subtitle}

    - - {exp.badgeText} - +
    {/* Description */} @@ -127,7 +134,9 @@ export function FourExperiencesSection() { {/* Middle Block: User Benefits Checklist */}
    - Key User Features: + + {exp.status === "available-now" ? "What works today:" : "The vision:"} +
      {exp.userBenefits.map((b, idx) => (
    • diff --git a/src/components/Hero.tsx b/src/components/Hero.tsx index 094ffee..d897bd3 100644 --- a/src/components/Hero.tsx +++ b/src/components/Hero.tsx @@ -1,8 +1,10 @@ "use client"; import React from "react"; -import { Download, ArrowRight, ShieldCheck, Sparkles, Monitor, Code, FileCheck } from "lucide-react"; +import { Bell, ArrowRight, GitBranch, ShieldCheck, Sparkles, Monitor, Code, FileCheck } from "lucide-react"; import { ShellInteractivePreview } from "./ShellInteractivePreview"; +import { AvailableNow, StatusBadge } from "./StatusBadge"; +import { ROADMAP_URL, GITHUB_URL } from "@/lib/status"; export function Hero() { return ( @@ -13,7 +15,7 @@ export function Hero() { {/* Announcement Pill */}
      - Nuncio — Sovereign, Fast & 100% Open Source + Nuncio — Sovereign, Fast & 100% Open Source. Under active construction.
      {/* Main Hero Headline */} @@ -24,7 +26,7 @@ export function Hero() { {/* Subtitle */}

      - No paid subscriptions, closed formats, or locked-away data. Enjoy four extraordinary interfaces, AI NSQL filters, and cryptographic audit logs without losing control of your data. + No paid subscriptions, closed formats, or locked-away data. We're building four extraordinary interfaces, an AI-driven NSQL filter engine, and cryptographic audit logs on a single sovereign core — in the open, from day one.

      {/* Action Buttons */} @@ -33,23 +35,35 @@ export function Hero() { href="#downloads" className="apple-button-primary px-6 py-3 text-sm font-semibold flex items-center gap-2" > - - Download Latest Release + + Notify me at launch - Explore the 4 Interfaces + + Follow the build on GitHub + + + See the roadmap
    {/* Trust Feature Bar */} -
    +
    - 100% Local AES-256 Encryption + Local AES-256 encryption at rest + @@ -57,16 +71,18 @@ export function Hero() { - HMAC Cryptographic Audit Logs + HMAC Cryptographic WORM Audit Logs + - macOS, Linux & Windows + Native apps for macOS, Linux & Windows +
    - {/* Featured Desktop GUI & Interactive Preview Container */} + {/* Interactive product-preview widget */}
    diff --git a/src/components/ManifestoPillarsSection.tsx b/src/components/ManifestoPillarsSection.tsx index dc9d324..54a8e5f 100644 --- a/src/components/ManifestoPillarsSection.tsx +++ b/src/components/ManifestoPillarsSection.tsx @@ -3,38 +3,49 @@ import React from "react"; import { Bot, Monitor, Zap, Database, Lock, FileCheck, Sparkles, ArrowRight } from "lucide-react"; import Link from "next/link"; +import { StatusBadge } from "./StatusBadge"; +import type { StatusVariant } from "@/lib/status"; export function ManifestoPillarsSection() { - const manifestoPillars = [ + const manifestoPillars: Array<{ + title: string; + icon: React.ReactNode; + desc: string; + status?: StatusVariant; + }> = [ { title: "1. Sane & Controlled AI Access", icon: , - desc: "AI co-pilots should empower you, not exfiltrate your life. McpAgentPolicy enforces granular RBAC capability flags, folder boundaries, and automatic SSN/credit card redaction before any payload touches an LLM.", + desc: "AI co-pilots should empower you, not exfiltrate your life. The plan: a policy gateway that enforces granular RBAC capability flags, folder boundaries, and automatic redaction of sensitive data before any payload touches an LLM.", + status: "planned", }, { title: "2. First-Class UI/UX in Every Space", icon: , - desc: "No second-class interfaces. Enjoy equal polish across native macOS glassmorphism, Windows, Linux, Vim Ratatui Terminal TUI, POSIX scriptable CLI, and native MCP AI agent integration with 100% feature parity.", + desc: "No second-class interfaces, by design. A single frozen gRPC contract is meant to guarantee equal polish and feature parity across a native desktop app, a Vim-style terminal TUI, a scriptable POSIX CLI, and an MCP AI agent bridge — not left to each client's discipline.", + status: "planned", }, { title: "3. Uncompromising Speed & Performance", icon: , - desc: "Engineered in native Rust over single-writer SQLite WAL storage. Search 100,000+ emails in under 10 milliseconds, execute NSQL rules in microsecond time, and run with zero battery drain.", + desc: "Engineered in native Rust over single-writer SQLite WAL storage, so search, filtering, and sync stay fast as your mailbox grows. We'll publish real, methodology-backed benchmarks as the engine matures — not invented numbers.", }, { title: "4. Sovereign Control & Zero Closed Formats", icon: , - desc: "No cloud lock-in, no proprietary sync servers, no closed formats. Your emails, accounts, rules, and calendars stay in standard local SQLite files on your disk. You own your data 100%.", + desc: "No cloud lock-in, no proprietary sync servers, no closed formats. Your emails, accounts, rules, and calendars live in standard local SQLite files on your disk, with MBOX/EML/JSON export already working today. You own your data.", }, { title: "5. Zero-Trust Security & Encryption", icon: , - desc: "Column-level AES-256-GCM data-at-rest encryption (PayloadCipher), age X25519 attachment ciphers, ZeroizeOnDrop memory page locking, and HTML email sandboxing with tracking pixel neutralization.", + desc: "Column-level data-at-rest encryption, hardened attachment ciphers, and HTML email sandboxing with tracking-pixel neutralization are on the security hardening milestone — real engineering targets, not shipped yet.", + status: "planned", }, { title: "6. WORM Cryptographic Audits", icon: , - desc: "Every automated rule match, webhook dispatch, account mutation, and AI MCP tool call is recorded in an immutable Write Once Read Many (WORM) audit ledger sealed with HMAC-SHA256 hash chains.", + desc: "Every automated rule match, account mutation, and tool call is recorded in an append-only, hash-chained Write Once Read Many (WORM) audit ledger — working today, not a future promise.", + status: "available-now", }, ]; @@ -69,6 +80,7 @@ export function ManifestoPillarsSection() { {p.icon}

    {p.title}

    + {p.status && }

    {p.desc}

    diff --git a/src/components/ParityMatrixSection.tsx b/src/components/ParityMatrixSection.tsx index efe341b..414f819 100644 --- a/src/components/ParityMatrixSection.tsx +++ b/src/components/ParityMatrixSection.tsx @@ -1,7 +1,9 @@ "use client"; import React, { useState } from "react"; -import { Check, Search, Layers, Shield, Terminal, Monitor, Code, Bot } from "lucide-react"; +import { Search, Layers, Terminal, Monitor, Code, Bot } from "lucide-react"; +import { StatusBadge } from "./StatusBadge"; +import type { StatusVariant } from "@/lib/status"; interface Capability { area: string; @@ -10,25 +12,28 @@ interface Capability { tui: string; gui: string; mcp: string; + /** The real, current status of the underlying engine capability — not a + * claim about any one client. Drives the Status column via StatusBadge. */ + status: StatusVariant; } const capabilities: Capability[] = [ - { area: "Account Management", name: "List Accounts", cli: "nuncio account list", tui: "AppMode::AccountSettings", gui: "Configured Accounts List", mcp: "nuncio_account_list" }, - { area: "Account Management", name: "Add Account Profile", cli: "nuncio account add", tui: "[a] Add Account Modal", gui: "Add Account Form", mcp: "nuncio_account_add" }, - { area: "Account Management", name: "Edit Account Config", cli: "nuncio account edit", tui: "[e] Edit Account Modal", gui: "Inline Edit Form", mcp: "nuncio_account_edit" }, - { area: "Account Management", name: "Delete Account Profile", cli: "nuncio account delete", tui: "[d] Delete Account Modal", gui: "Remove Account Button", mcp: "nuncio_account_delete" }, - { area: "Account Management", name: "Test TLS Connectivity", cli: "nuncio account test", tui: "[t] Test TLS Connection", gui: "Test Connection Button", mcp: "nuncio_account_test" }, - { area: "Email Operations", name: "Sync Mailboxes", cli: "nuncio mail sync", tui: "Sync (s)", gui: "Sync Button", mcp: "CoreCommand::SyncAll" }, - { area: "Email Operations", name: "Search Messages (FTS5)", cli: "nuncio mail search", tui: "Search Mode (/)", gui: "Filter & Search Input", mcp: "nuncio_mail_search" }, - { area: "Email Operations", name: "Send Email / Outbox", cli: "nuncio mail send", tui: "Compose Modal (c)", gui: "Compose Modal Component", mcp: "nuncio_mail_send" }, - { area: "NSQL Automation", name: "List Rules", cli: "nuncio filter list", tui: "AppMode::FilterRules", gui: " List", mcp: "nuncio_filter_list" }, - { area: "NSQL Automation", name: "Create NSQL Rule", cli: "nuncio filter create --sql", tui: "[n] New Rule / [s] Code", gui: "", mcp: "nuncio_filter_create" }, - { area: "NSQL Automation", name: "Dry-Run Preview", cli: "nuncio filter test --sql", tui: "[t] Dry-Run Previewer", gui: " Pane", mcp: "nuncio_filter_test" }, - { area: "NSQL Automation", name: "Execution Audit Logs", cli: "nuncio filter logs", tui: "[l] Log Drawer", gui: " Tab", mcp: "nuncio_filter_logs" }, - { area: "Calendar & Scheduling", name: "List Calendar Events", cli: "nuncio cal list", tui: "Agenda / Calendar Pane", gui: "Calendar Grid View", mcp: "nuncio_cal_list_events" }, - { area: "Calendar & Scheduling", name: "Create Event", cli: "nuncio cal create", tui: "Event Creation Modal", gui: "Event Creator Component", mcp: "nuncio_cal_create_event" }, - { area: "Security & Vault", name: "Column AES-256-GCM", cli: "PayloadCipher", tui: "PayloadCipher", gui: "PayloadCipher", mcp: "PayloadCipher" }, - { area: "Security & Vault", name: "OS Keyring Vault", cli: "keyring crate", tui: "keyring crate", gui: "keyring crate", mcp: "keyring crate" }, + { area: "Account Management", name: "List Accounts", cli: "nuncio account list", tui: "AppMode::AccountSettings", gui: "Configured Accounts List", mcp: "nuncio_account_list", status: "available-now" }, + { area: "Account Management", name: "Add Account Profile", cli: "nuncio account add", tui: "[a] Add Account Modal", gui: "Add Account Form", mcp: "nuncio_account_add", status: "available-now" }, + { area: "Account Management", name: "Test Connectivity", cli: "nuncio account test", tui: "[t] Test Connection", gui: "Test Connection Button", mcp: "nuncio_account_test", status: "available-now" }, + { area: "Email Operations", name: "Sync Mailboxes (IMAP/SMTP)", cli: "nuncio mail sync", tui: "Sync (s)", gui: "Sync Button", mcp: "CoreCommand::SyncAll", status: "available-now" }, + { area: "Email Operations", name: "Search Messages (FTS5)", cli: "nuncio mail search", tui: "Search Mode (/)", gui: "Filter & Search Input", mcp: "nuncio_mail_search", status: "available-now" }, + { area: "Email Operations", name: "Send Email / Outbox", cli: "nuncio mail send", tui: "Compose Modal (c)", gui: "Compose Modal Component", mcp: "nuncio_mail_send", status: "available-now" }, + { area: "Email Operations", name: "Export Mail (MBOX/EML/JSON)", cli: "nuncio mail export", tui: "[x] Export Drawer", gui: "Export Panel", mcp: "nuncio_mail_export", status: "available-now" }, + { area: "NSQL Automation", name: "List / Create Rules", cli: "nuncio filter create --sql", tui: "AppMode::FilterRules", gui: "", mcp: "nuncio_filter_create", status: "in-progress" }, + { area: "NSQL Automation", name: "Dry-Run Preview", cli: "nuncio filter test --sql", tui: "[t] Dry-Run Previewer", gui: " Pane", mcp: "nuncio_filter_test", status: "in-progress" }, + { area: "NSQL Automation", name: "Rules Firing on Live Sync", cli: "nuncio filter logs", tui: "[l] Log Drawer", gui: " Tab", mcp: "nuncio_filter_logs", status: "planned" }, + { area: "Calendar & Contacts", name: "CalDAV Calendar Sync", cli: "nuncio cal list", tui: "Agenda / Calendar Pane", gui: "Calendar Grid View", mcp: "nuncio_cal_list_events", status: "planned" }, + { area: "Calendar & Contacts", name: "CardDAV Contacts Sync", cli: "nuncio contacts list", tui: "Contacts Pane", gui: "Contacts List View", mcp: "nuncio_contacts_list", status: "planned" }, + { area: "Security & Vault", name: "OS Keyring Credential Vault", cli: "keyring crate", tui: "keyring crate", gui: "keyring crate", mcp: "keyring crate", status: "available-now" }, + { area: "Security & Vault", name: "At-Rest Body Encryption", cli: "PayloadCipher", tui: "PayloadCipher", gui: "PayloadCipher", mcp: "PayloadCipher", status: "planned" }, + { area: "Security & Vault", name: "HTML Sanitization", cli: "n/a (headless)", tui: "sandboxed renderer", gui: "sandboxed renderer", mcp: "n/a", status: "planned" }, + { area: "Security & Vault", name: "WORM Audit Ledger", cli: "nuncio audit verify", tui: "[l] Audit Drawer", gui: "", mcp: "nuncio_audit_read", status: "available-now" }, ]; export function ParityMatrixSection() { @@ -48,13 +53,17 @@ export function ParityMatrixSection() {
    - Standing Rule: 100% Parity Across All 4 Interfaces + Design goal: one contract, no second-class clients

    One Core Engine. Four Great Interfaces.

    - Every feature in Nuncio is implemented 1:1 across POSIX CLI, Vim Ratatui TUI, Desktop GUI, and Native MCP LLM Agent interface without shells or mocks. + Every capability in Nuncio is designed against a single versioned gRPC contract, so the CLI, TUI, + GUI, and MCP bridge can't drift out of sync the way bolt-on clients usually do. That's the + architecture's job, not a promise about what's built yet — the CLI is the only client that + exists today; the rest are planned thin clients over the same API. The Status column below reflects + the real, current state of each underlying capability.

    @@ -63,7 +72,7 @@ export function ParityMatrixSection() { setSearch(e.target.value)} className="w-full bg-slate-900 border border-white/10 rounded-xl pl-12 pr-4 py-3 text-sm text-white focus:border-blue-500 focus:outline-none shadow-inner" @@ -119,9 +128,7 @@ export function ParityMatrixSection() { {item.gui} {item.mcp} - - 100% PARITY - + )) @@ -130,6 +137,15 @@ export function ParityMatrixSection() { + +

    + TUI, GUI, and MCP columns above show design-target command surfaces for interfaces that don't + exist yet — see{" "} + + the four interfaces + {" "} + for what's actually built today. +

    ); diff --git a/src/components/ShellInteractivePreview.tsx b/src/components/ShellInteractivePreview.tsx index bd61d09..f70d7c6 100644 --- a/src/components/ShellInteractivePreview.tsx +++ b/src/components/ShellInteractivePreview.tsx @@ -1,7 +1,7 @@ "use client"; import React, { useState } from "react"; -import { Terminal, Monitor, Bot, Code, CheckCircle, Copy, Check, Play, RefreshCw, Send, Calendar, ShieldCheck, Sparkles, ChevronRight, Activity, ArrowRight } from "lucide-react"; +import { Terminal, Monitor, Bot, Code, Copy, Check, Sparkles, Activity, ArrowRight, Eye } from "lucide-react"; export function ShellInteractivePreview() { const [activeTab, setActiveTab] = useState<"gui" | "tui" | "cli" | "mcp">("gui"); @@ -21,7 +21,7 @@ export function ShellInteractivePreview() { "name": "VIP Priority Alerts", "priority": 10, "enabled": true, - "nsql_text": "WHEN sender LIKE '%@kof22.com%' AND subject REGEXP '(Urgent|Architecture)' THEN MOVE TO 'vip-inbox', SET flagged = TRUE;" + "nsql_text": "WHEN sender LIKE '%@example.com%' AND subject REGEXP '(Urgent|Architecture)' THEN MOVE TO 'vip-inbox', SET flagged = TRUE;" }, { "id": "rule_02NEWS", @@ -40,15 +40,17 @@ export function ShellInteractivePreview() { const [selectedMcpTool, setSelectedMcpTool] = useState<"send" | "event" | "status" | "update">("send"); const tuiRules = [ - { id: "P10", name: "VIP Priority Alerts", target: "james.maes@kof22.com", nsql: "WHEN sender LIKE '%@kof22.com%' AND subject REGEXP '(Urgent|Architecture)' THEN MOVE TO 'vip-inbox', SET flagged = TRUE;" }, + { id: "P10", name: "VIP Priority Alerts", target: "you@example.com", nsql: "WHEN sender LIKE '%@example.com%' AND subject REGEXP '(Urgent|Architecture)' THEN MOVE TO 'vip-inbox', SET flagged = TRUE;" }, { id: "P50", name: "Auto-Archive Newsletters", target: "*", nsql: "WHEN body LIKE '%unsubscribe%' THEN MOVE TO 'Newsletters', SET read = TRUE;" }, { id: "P100", name: "Spam Purge Filter", target: "*", nsql: "WHEN header['X-Spam-Score'] > 5 THEN MOVE TO 'Trash', SET read = TRUE;" }, ]; + // Sample content for a concept mockup only — not a real inbox, real people, + // or a real build. See the "Product preview" caption on this component. const guiEmails = [ - { id: 1, sender: "Alice Vance (Kof22)", subject: "Urgent Architecture Review & VIP Release", folder: "INBOX", date: "12:42 PM", unread: true, snippet: "Please review the Nuncio sovereign mail architecture spec for 100% parity across all 4 interfaces..." }, - { id: 2, sender: "Antigravity Agent", subject: "MCP Calendar Event Confirmation: Architecture Alignment", folder: "INBOX", date: "11:15 AM", unread: false, snippet: "Created event 'Architecture Alignment' for tomorrow at 2:00 PM PST via nuncio_cal_create_event." }, - { id: 3, sender: "GitHub Actions Bot", subject: "Multi-Platform Nightly Build #30031303002 Succeeded", folder: "CI/CD", date: "Yesterday", unread: false, snippet: "macOS Universal .dmg, Windows .msi, and Linux .AppImage artifacts published with SHA256SUMS.txt." }, + { id: 1, sender: "Project Lead", subject: "Architecture review for the filter engine", folder: "INBOX", date: "12:42 PM", unread: true, snippet: "Please review the sovereign mail architecture spec ahead of the next milestone..." }, + { id: 2, sender: "Calendar Assistant (AI agent)", subject: "Calendar event confirmed via MCP", folder: "INBOX", date: "11:15 AM", unread: false, snippet: "Created event 'Architecture Sync' for tomorrow via the nuncio_cal_create_event tool." }, + { id: 3, sender: "CI Bot", subject: "Nightly build finished", folder: "CI/CD", date: "Yesterday", unread: false, snippet: "Sample notification — illustrates what a future CI notification email might look like." }, ]; const runCliCommand = (cmd: string) => { @@ -80,7 +82,7 @@ export function ShellInteractivePreview() { { "id": "msg_9901", "subject": "Urgent Architecture Review & VIP Release", - "sender": "alice@kof22.com", + "sender": "vip@example.com", "received_at": 1700000000, "matched_score": 0.98 } @@ -94,7 +96,7 @@ export function ShellInteractivePreview() { "name": "VIP Priority Alerts", "priority": 10, "enabled": true, - "nsql_text": "WHEN sender LIKE '%@kof22.com%' AND subject REGEXP '(Urgent|Architecture)' THEN MOVE TO 'vip-inbox', SET flagged = TRUE;" + "nsql_text": "WHEN sender LIKE '%@example.com%' AND subject REGEXP '(Urgent|Architecture)' THEN MOVE TO 'vip-inbox', SET flagged = TRUE;" } ]` ); @@ -109,19 +111,25 @@ export function ShellInteractivePreview() { return (
    + {/* Preview disclosure banner */} +
    + + Product preview — a concept mockup of the vision, not a screenshot of a real build +
    + {/* macOS Window Title Bar */} -
    +
    - Nuncio Sovereign Mail & Calendar — Native macOS / Linux / Windows Shell + Nuncio Sovereign Mail & Calendar — Concept for a Native macOS / Linux / Windows Shell
    -
    - - Daemon Connected +
    + + Simulated data
    @@ -137,7 +145,7 @@ export function ShellInteractivePreview() { }`} > - 1. Desktop GUI (Featured) + 1. Desktop GUI
    - - Daemon IPC Connected + + Simulated — click around, no live daemon behind this
    @@ -190,7 +198,7 @@ export function ShellInteractivePreview() {
    - NUNCIO TUI │ Account: james.maes@kof22.com │ State: Connected + NUNCIO TUI │ Account: you@example.com │ State: Connected
    AppMode::{tuiMode === "rules" ? "FilterRules" : "QueryEditor"}
    @@ -243,11 +251,11 @@ export function ShellInteractivePreview() { Dry-Run Preview [t]: - MATCHED (14µs) + MATCHED
    {tuiDryRunRun && (
    -

    ✓ Rule evaluated against sample message in 0.014ms

    +

    ✓ Rule evaluated against sample message

    ✓ Action sequence: MOVE TO 'vip-inbox', SET flagged = TRUE

    )} @@ -385,12 +393,12 @@ export function ShellInteractivePreview() {

    {mail.subject}

    From: {mail.sender}

    - Verified DKIM/SPF + Concept UI

    {mail.snippet}

    - AES-256-GCM Encrypted at Rest + At-rest encryption — planned @@ -461,9 +469,9 @@ export function ShellInteractivePreview() { "params": { "name": "nuncio_mail_send", "arguments": { - "to": "alice@kof22.com", + "to": "vip@example.com", "subject": "Architecture Sync", - "body": "All 4 interfaces operating with 100% parity!" + "body": "Sample message sent via the MCP gateway." } } }`} -- 2.54.0 From e1f20216f6ea72511d0b2ea86dbb0a03d8d42371 Mon Sep 17 00:00:00 2001 From: James Maes Date: Wed, 29 Jul 2026 08:22:39 -0500 Subject: [PATCH 3/5] feat(site): north-star dedicated pages + hub content (chunk 2/3) Rewrite the dedicated feature pages and three shared hub components to sell the vision without claiming shipped status for unbuilt work. - interfaces: reframe the four interfaces as one-contract vision; CLI is available-now, GUI/TUI/MCP are planned. Drop "100% parity" and "Featured/Most Popular" badges and the fake per-platform download CTA. - features: full feature matrix now carries a StatusBadge per row and drops every unmeasured benchmark ("<10ms", "microsecond", "100,000+") and as-shipped claims for JMAP push, Sixel, and full feature parity. - SecurityHub/security: keep OS keyring and the WORM audit ledger as available-now (both real and verifiable today); reframe at-rest encryption, memory zeroization, HTML sandboxing, and the updater as planned/in-progress design goals instead of delivered guarantees. Add the real vulnerability-reporting policy and correct the ReDoS defense description (static pattern rejection, not an invented 50ms timeout). - McpIntegrationHub/mcp: MCP is a planned Phase-5 client that doesn't exist yet; relabel the config sample as a non-functional preview and drop language implying an agent can connect today. - NsqlPlayground/nsql: keep the interactive grammar demo but genericize the sample email away from real names/domains, drop invented latency/RAM readouts from the in-browser toy evaluator, and frame rule execution against live mail as in-progress/planned (real: parser, validator, dry-run, and the webhook/audit engine internals). - about: align the manifesto pillars with real status via StatusBadge; replace the third-party credit list's unverified per-maintainer name attributions with plain repository links to avoid misattributing real people. - privacy: correct the claim that the local database is encrypted at rest (only credentials are, via the OS keyring); scope network/AI claims to what's actually implemented. - terms: clarify Nuncio is source-only pre-alpha software with no hosted service, and point the disclaimer at the security page. --- src/app/about/page.tsx | 423 +++++++-------------------- src/app/features/page.tsx | 138 +++++---- src/app/interfaces/page.tsx | 123 ++++---- src/app/mcp/page.tsx | 128 ++++---- src/app/nsql/page.tsx | 53 ++-- src/app/privacy/page.tsx | 47 ++- src/app/security/page.tsx | 278 +++++++++++------- src/app/terms/page.tsx | 49 +++- src/components/McpIntegrationHub.tsx | 60 ++-- src/components/NsqlPlayground.tsx | 93 ++---- src/components/SecurityHub.tsx | 54 ++-- 11 files changed, 701 insertions(+), 745 deletions(-) diff --git a/src/app/about/page.tsx b/src/app/about/page.tsx index 8d34ea3..622e925 100644 --- a/src/app/about/page.tsx +++ b/src/app/about/page.tsx @@ -2,45 +2,30 @@ import React from "react"; import { Header } from "@/components/Header"; import { Footer } from "@/components/Footer"; import { - ShieldCheck, - Code, Sparkles, - Terminal, Database, FileCheck, Lock, - CheckCircle2, - ArrowRight, - Zap, - Cpu, - Key, - Activity, Monitor, Bot, Layers, Heart, Globe, - ExternalLink, GitBranch, - User, + MapPin, } from "lucide-react"; -import Link from "next/link"; +import { StatusBadge } from "@/components/StatusBadge"; +import { GITHUB_URL, ROADMAP_URL } from "@/lib/status"; +import type { StatusVariant } from "@/lib/status"; export const metadata = { - title: "Why Nuncio Exists — Manifesto & Verified Maintainer Credits", - description: "Learn why Nuncio exists: sovereign email rebuilt for today. Verified credits with direct GitHub profile links for authors and open-source maintainers.", + title: "Why Nuncio Exists — Manifesto & Open-Source Credits", + description: "Why Nuncio exists: local-first mail rebuilt for today, honestly staged as pre-alpha. What's real now, what's vision, and the open-source projects it's built on.", }; -interface Maintainer { - name: string; - url: string; -} - interface CreditItem { name: string; - githubUrl?: string; - websiteUrl?: string; - maintainers: Maintainer[]; + repoUrl: string; role: string; } @@ -50,37 +35,50 @@ interface CreditCategory { crates: CreditItem[]; } +interface ManifestoPillar { + title: string; + status: StatusVariant; + icon: React.ReactNode; + desc: string; +} + export default function AboutPage() { - const manifestoPillars = [ + const manifestoPillars: ManifestoPillar[] = [ { title: "1. Sane & Controlled AI / LLM Access", + status: "planned", icon: , - desc: "AI co-pilots should empower you, not exfiltrate your life. Nuncio's McpAgentPolicy enforces granular RBAC capability flags (read_mail, send_mail, read_calendar), folder access boundaries, and automatic SSN/credit card redaction before any payload touches an LLM context window.", + desc: "AI co-pilots should empower you, not exfiltrate your life. The plan is an RBAC gateway with capability flags, folder boundaries, and PII redaction before any payload reaches an LLM — none of it built yet.", }, { - title: "2. First-Class UI/UX in Every Space", + title: "2. First-Class UX in Every Interface", + status: "planned", icon: , - desc: "No second-class interfaces. Enjoy equal polish across native macOS glassmorphism, Windows, Linux, Vim Ratatui Terminal TUI, POSIX scriptable CLI, and native MCP AI agent integration with 100% feature parity.", + desc: "No second-class interfaces, by design: a desktop GUI, a keyboard-driven terminal TUI, a scriptable CLI, and an MCP AI bridge, all clients of one frozen gRPC contract. Only the CLI exists today.", }, { - title: "3. Uncompromising Speed & Performance", - icon: , - desc: "Engineered in native Rust over single-writer SQLite WAL storage. Search 100,000+ emails in under 10 milliseconds, execute NSQL rules in microsecond time, and run with zero battery drain.", + title: "3. A Fast, Native Engine", + status: "in-progress", + icon: , + desc: "Built in Rust over single-writer SQLite WAL storage for real local performance, not a race against a specific number — see the feature matrix for what's measured versus aspirational.", }, { title: "4. Sovereign Control & Zero Closed Formats", + status: "in-progress", icon: , - desc: "No cloud lock-in, no proprietary sync servers, no closed formats. Your emails, accounts, rules, and calendars stay in standard local SQLite files on your disk. You own your data 100%.", + desc: "No cloud lock-in, no proprietary sync servers. Your synced mail, accounts, and rules live in a local SQLite file you can export to standard MBOX, EML, or JSON at any time — that export path works today.", }, { title: "5. Zero-Trust Security & Encryption", + status: "planned", icon: , - desc: "Column-level AES-256-GCM data-at-rest encryption (PayloadCipher), age X25519 attachment ciphers, ZeroizeOnDrop memory page locking, and HTML email sandboxing with tracking pixel neutralization.", + desc: "Column-level encryption at rest, memory zeroing, and HTML sandboxing are the target. Today, credentials go through the OS keyring; message bodies are not yet encrypted at rest.", }, { title: "6. WORM Cryptographic Audits & Immutability", + status: "available-now", icon: , - desc: "Every automated rule match, webhook dispatch, account mutation, and AI MCP tool call is recorded in an immutable Write Once Read Many (WORM) audit ledger sealed with HMAC-SHA256 hash chains.", + desc: "Real today: rule matches, webhook dispatches, and account mutations are recorded in an immutable, HMAC-SHA256 hash-chained audit ledger.", }, ]; @@ -89,242 +87,48 @@ export default function AboutPage() { category: "Rust Core Systems & Data Storage", icon: , crates: [ - { - name: "sqlx", - githubUrl: "https://github.com/launchbadge/sqlx", - maintainers: [ - { name: "Ryan Lecompte (@launchbadge)", url: "https://github.com/rachel-la" }, - { name: "Austin Bonander (@abonander)", url: "https://github.com/abonander" }, - ], - role: "Async, pure-Rust SQL engine powering type-safe SQLite database operations and migrations.", - }, - { - name: "sqlparser-rs", - githubUrl: "https://github.com/apache/datafusion-sqlparser-rs", - maintainers: [ - { name: "Andy Grove (@andygrove)", url: "https://github.com/andygrove" }, - { name: "Apache DataFusion Team", url: "https://github.com/apache/datafusion-sqlparser-rs" }, - ], - role: "Pure Rust SQL lexer and parser engine powering the Nuncio SQL Filter Language (NSQL) compiler.", - }, - { - name: "tokio", - githubUrl: "https://github.com/tokio-rs/tokio", - maintainers: [ - { name: "Carl Lerche (@carllerche)", url: "https://github.com/carllerche" }, - { name: "Tokio Team", url: "https://github.com/tokio-rs" }, - ], - role: "Event-driven asynchronous Rust runtime driving background IMAP IDLE, JMAP push, and IPC streaming.", - }, - { - name: "serde & serde_json", - githubUrl: "https://github.com/serde-rs/serde", - maintainers: [ - { name: "David Tolnay (@dtolnay)", url: "https://github.com/dtolnay" }, - { name: "Erick Tryzelaar (@erickt)", url: "https://github.com/erickt" }, - ], - role: "Generic serialization/deserialization framework powering data models across all crates.", - }, - { - name: "thiserror & anyhow", - githubUrl: "https://github.com/dtolnay/thiserror", - maintainers: [ - { name: "David Tolnay (@dtolnay)", url: "https://github.com/dtolnay" }, - ], - role: "Ergonomic, type-safe Rust error handling and domain error mappings.", - }, + { name: "sqlx", repoUrl: "https://github.com/launchbadge/sqlx", role: "Async, pure-Rust SQL engine powering type-safe SQLite operations and migrations." }, + { name: "sqlparser-rs", repoUrl: "https://github.com/apache/datafusion-sqlparser-rs", role: "Pure Rust SQL lexer and parser powering the NSQL filter language compiler." }, + { name: "tokio", repoUrl: "https://github.com/tokio-rs/tokio", role: "Event-driven asynchronous Rust runtime driving background IMAP sync and gRPC serving." }, + { name: "serde & serde_json", repoUrl: "https://github.com/serde-rs/serde", role: "Serialization framework powering data models across every crate." }, + { name: "thiserror", repoUrl: "https://github.com/dtolnay/thiserror", role: "Ergonomic, type-safe Rust error handling used throughout the workspace." }, ], }, { - category: "Mail Protocols & Parsing Engines", + category: "Mail Protocols & Parsing", icon: , crates: [ - { - name: "async-imap", - githubUrl: "https://github.com/jonatanil/async-imap", - maintainers: [ - { name: "Jonatan Nilsson (@jonatanil)", url: "https://github.com/jonatanil" }, - ], - role: "Asynchronous IMAP client library driving real-time TLS 993 inbox synchronization.", - }, - { - name: "lettre", - githubUrl: "https://github.com/lettre/lettre", - maintainers: [ - { name: "Alexis Yu (@alexys)", url: "https://github.com/alexys" }, - { name: "Lettre Core Team", url: "https://github.com/lettre" }, - ], - role: "Modern Rust SMTP email client delivering outbound TLS 587/465 message transport.", - }, - { - name: "mail-parser", - githubUrl: "https://github.com/bostjan/mail-parser", - maintainers: [ - { name: "Bostjan Skufca (@bostjan)", url: "https://github.com/bostjan" }, - ], - role: "High-performance MIME parser for raw RFC 5322 emails, headers, and attachment boundaries.", - }, - { - name: "html2text", - githubUrl: "https://github.com/lukaslueg/html2text", - maintainers: [ - { name: "Lukas Lueg (@lukaslueg)", url: "https://github.com/lukaslueg" }, - ], - role: "Converting HTML email markup to clean, un-tracked ANSI terminal text and Markdown.", - }, + { name: "async-imap", repoUrl: "https://github.com/jonhoo/async-imap", role: "Asynchronous IMAP client library driving inbox synchronization." }, + { name: "lettre", repoUrl: "https://github.com/lettre/lettre", role: "Rust SMTP client delivering outbound message transport." }, + { name: "mail-parser", repoUrl: "https://github.com/stalwartlabs/mail-parser", role: "MIME parser for raw RFC 5322 emails, headers, and attachment boundaries." }, ], }, { - category: "Security, Cryptography & Vault Enclaves", + category: "Security & Credential Storage", icon: , crates: [ - { - name: "ring", - githubUrl: "https://github.com/briansmith/ring", - maintainers: [ - { name: "Brian Smith (@briansmith)", url: "https://github.com/briansmith" }, - ], - role: "Safe, fast, small crypto primitives in Rust and C for cryptographic operations.", - }, - { - name: "aes-gcm", - githubUrl: "https://github.com/RustCrypto/AEADs", - maintainers: [ - { name: "RustCrypto Team (@RustCrypto)", url: "https://github.com/RustCrypto" }, - ], - role: "Pure Rust AES-GCM authenticated encryption powering column-level PayloadCipher.", - }, - { - name: "age & rage", - githubUrl: "https://github.com/str4d/rage", - websiteUrl: "https://filippo.io/age", - maintainers: [ - { name: "Filippo Valsorda (@FiloSottile)", url: "https://github.com/FiloSottile" }, - { name: "Jack Grigg (@str4d)", url: "https://github.com/str4d" }, - ], - role: "Modern X25519 file and stream encryption format powering large binary attachment ciphers.", - }, - { - name: "zeroize", - githubUrl: "https://github.com/RustCrypto/utils/tree/master/zeroize", - maintainers: [ - { name: "Tony Arcieri (@bascule)", url: "https://github.com/bascule" }, - { name: "RustCrypto Team", url: "https://github.com/RustCrypto" }, - ], - role: "Secure memory page zeroing (ZeroizeOnDrop) preventing key material leakages in RAM buffers.", - }, - { - name: "keyring-rs", - githubUrl: "https://github.com/hwchen/keyring-rs", - maintainers: [ - { name: "hwchen (@hwchen)", url: "https://github.com/hwchen" }, - ], - role: "Native OS credential manager integration (Windows DPAPI, macOS Keychain Access, Linux Secret Service).", - }, - { - name: "hmac & sha2", - githubUrl: "https://github.com/RustCrypto/MACs", - maintainers: [ - { name: "RustCrypto Team", url: "https://github.com/RustCrypto" }, - ], - role: "Cryptographic HMAC-SHA256 hash-chain calculation for WORM audit ledgers.", - }, + { name: "hmac & sha2 (RustCrypto)", repoUrl: "https://github.com/RustCrypto/hashes", role: "HMAC-SHA256 hash-chain calculation backing the WORM audit ledger." }, + { name: "keyring-rs", repoUrl: "https://github.com/hwchen/keyring-rs", role: "Native OS credential manager integration (Windows, macOS, Linux)." }, + { name: "zeroize", repoUrl: "https://github.com/RustCrypto/utils", role: "Secure memory buffer zeroing, part of the in-progress key-hygiene work." }, ], }, { - category: "Presentation Shells & UI Frameworks", + category: "Web & Presentation Tooling", icon: , crates: [ - { - name: "Tauri v2", - githubUrl: "https://github.com/tauri-apps/tauri", - websiteUrl: "https://tauri.app", - maintainers: [ - { name: "Daniel Thompson-Yvetot (@lucasferns)", url: "https://github.com/tauri-apps" }, - { name: "Lucas Nogueira", url: "https://github.com/lucasferns" }, - ], - role: "Lightweight, secure desktop application framework driving the Glassmorphic GUI.", - }, - { - name: "ratatui", - githubUrl: "https://github.com/ratatui/ratatui", - websiteUrl: "https://ratatui.rs", - maintainers: [ - { name: "Orhun Parmaksız (@orhun)", url: "https://github.com/orhun" }, - { name: "Ratatui Community", url: "https://github.com/ratatui" }, - ], - role: "Terminal user interface framework powering the Vim-fueled Ratatui TUI.", - }, - { - name: "clap", - githubUrl: "https://github.com/clap-rs/clap", - maintainers: [ - { name: "Ed Page (@epage)", url: "https://github.com/epage" }, - { name: "Kevin K.", url: "https://github.com/clap-rs" }, - ], - role: "Declarative command-line argument parser powering the POSIX scriptable CLI (nuncio-cli).", - }, - { - name: "Next.js", - githubUrl: "https://github.com/vercel/next.js", - websiteUrl: "https://nextjs.org", - maintainers: [ - { name: "Guillermo Rauch (@rauchg)", url: "https://github.com/rauchg" }, - { name: "Vercel Team", url: "https://github.com/vercel" }, - ], - role: "React web framework powering nuncio-website with static site generation and Turbopack.", - }, - { - name: "TailwindCSS", - githubUrl: "https://github.com/tailwindlabs/tailwindcss", - websiteUrl: "https://tailwindcss.com", - maintainers: [ - { name: "Adam Wathan (@adamwathan)", url: "https://github.com/adamwathan" }, - { name: "Tailwind Labs Team", url: "https://github.com/tailwindlabs" }, - ], - role: "Utility-first CSS engine powering responsive modern styling across website components.", - }, - { - name: "lucide-react", - githubUrl: "https://github.com/lucide-icons/lucide", - websiteUrl: "https://lucide.dev", - maintainers: [ - { name: "Lucide Open Source Community", url: "https://github.com/lucide-icons" }, - ], - role: "Clean, modern open-source icon suite across Next.js and Tauri interfaces.", - }, + { name: "clap", repoUrl: "https://github.com/clap-rs/clap", role: "Declarative command-line argument parser powering nuncio-cli." }, + { name: "Next.js", repoUrl: "https://github.com/vercel/next.js", role: "React framework powering this website." }, + { name: "TailwindCSS", repoUrl: "https://github.com/tailwindlabs/tailwindcss", role: "Utility-first CSS engine powering this site's styling." }, + { name: "lucide-react", repoUrl: "https://github.com/lucide-icons/lucide", role: "Open-source icon set used across the site." }, ], }, { category: "Open Protocols & Standards", icon: , crates: [ - { - name: "Model Context Protocol (MCP)", - githubUrl: "https://github.com/modelcontextprotocol", - websiteUrl: "https://modelcontextprotocol.io", - maintainers: [ - { name: "Dario Amodei & Anthropic", url: "https://github.com/modelcontextprotocol" }, - { name: "Open MCP Working Group", url: "https://modelcontextprotocol.io" }, - ], - role: "Open stdio JSON-RPC 2.0 standard connecting AI agents (Claude, Antigravity, Cursor) directly to Nuncio tools.", - }, - { - name: "RFC 4155 MBOX & RFC 5322 MIME", - githubUrl: "https://datatracker.ietf.org/doc/html/rfc4155", - maintainers: [ - { name: "IETF Email Standards Working Group", url: "https://www.ietf.org" }, - ], - role: "Universal open standards for portable email archiving, export, and transport.", - }, - { - name: "RFC 7636 PKCE OAuth 2.0", - githubUrl: "https://datatracker.ietf.org/doc/html/rfc7636", - maintainers: [ - { name: "IETF OAuth Working Group", url: "https://www.ietf.org" }, - ], - role: "Proof Key for Code Exchange protocol driving secure credential-free Google Workspace authentication.", - }, + { name: "Model Context Protocol (MCP)", repoUrl: "https://github.com/modelcontextprotocol", role: "The open stdio/JSON-RPC standard Nuncio's planned AI client will build on." }, + { name: "RFC 4155 (MBOX) & RFC 5322 (MIME)", repoUrl: "https://datatracker.ietf.org/doc/html/rfc4155", role: "Open standards behind Nuncio's portable mail export formats." }, + { name: "RFC 7636 (PKCE for OAuth 2.0)", repoUrl: "https://datatracker.ietf.org/doc/html/rfc7636", role: "Proof Key for Code Exchange, the target flow for OAuth-based providers." }, ], }, ]; @@ -345,7 +149,9 @@ export default function AboutPage() {

    - Email rebuilt for today — private, fast, secure, and AI-integrated without giving up control of your data, your privacy, or your flow. + Local-first mail, calendar, and contacts, rebuilt without giving up control of your data. Nuncio is + pre-alpha and under active, public reconstruction — this page is the vision alongside an honest read + of what's actually built so far.

    @@ -355,22 +161,31 @@ export default function AboutPage() {

    Breaking Away From Walled Gardens

    - For over a decade, personal and enterprise communication has been fractured across paid cloud subscriptions, closed proprietary formats, locked-away data silos, and compromised user experiences depending on whether you're on a Mac, Windows PC, Linux terminal, or mobile device. + For over a decade, personal and enterprise communication has been fractured across paid cloud + subscriptions, closed proprietary formats, and locked-away data silos.

    - Nuncio was built to eliminate those trade-offs. Created by James Maes (KofTwentyTwo), Nuncio gives developers, power users, and AI agents total speed, complete sovereign data ownership, zero-trust encryption, and sane AI integration. + Nuncio is being built to eliminate those trade-offs. Created by{" "} + + James Maes (KofTwentyTwo) + + , the goal is speed, sovereign data ownership, real encryption, and sane AI integration — each + pillar below tagged with how far along it actually is.

    - {/* 6 Core Manifesto Pillars Grid */} + {/* Manifesto Pillars Grid */}
    {manifestoPillars.map((p, idx) => (
    -
    -
    - {p.icon} +
    +
    +
    + {p.icon} +
    +

    {p.title}

    -

    {p.title}

    +

    {p.desc}

    @@ -379,16 +194,17 @@ export default function AboutPage() {
    - {/* Full Open-Source & Third-Party Library Credits Section with Clickable Author Links */} + {/* Open-Source Credits Section */}
    Standing on the Shoulders of Giants
    -

    Open-Source Ecosystem & Author Credits

    +

    Open-Source Ecosystem Credits

    - Nuncio is made possible by the incredible open-source Rust, Web, Security, and Protocol communities. We extend our deepest gratitude to the authors and maintainers of these projects. Click any author or repository below to visit their official profiles. + Nuncio is made possible by the Rust, web, security, and open-protocol communities. Links go to each + project's official repository.

    @@ -404,60 +220,22 @@ export default function AboutPage() {
    {cred.crates.map((c, rIdx) => ( -
    -
    -
    - {c.name} -
    - {c.githubUrl && ( - - - Repository - - )} - {c.websiteUrl && ( - - - Docs - - )} -
    -
    - - {/* Maintainers List with Direct Hyperlinks */} -
    - - Authors & Maintainers: - -
    - {c.maintainers.map((m, mIdx) => ( - - - {m.name} - - ))} -
    -
    - -

    {c.role}

    + +
    + {c.name} + + + Repository +
    -
    +

    {c.role}

    +
    ))}
    @@ -466,14 +244,25 @@ export default function AboutPage() {
    {/* Bottom CTA */} -