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/about/page.tsx b/src/app/about/page.tsx index 8d34ea3..20a1036 100644 --- a/src/app/about/page.tsx +++ b/src/app/about/page.tsx @@ -2,45 +2,31 @@ 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 { GithubIcon } from "@/components/GithubIcon"; +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 +36,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 +88,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 +150,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 +162,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 +195,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 +221,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 +245,25 @@ export default function AboutPage() {
{/* Bottom CTA */} -
diff --git a/src/app/docs/account-setup/page.tsx b/src/app/docs/account-setup/page.tsx index 926f93f..2210fc5 100644 --- a/src/app/docs/account-setup/page.tsx +++ b/src/app/docs/account-setup/page.tsx @@ -2,11 +2,12 @@ import React from "react"; import { Header } from "@/components/Header"; import { Footer } from "@/components/Footer"; import { DocsLayout } from "@/components/DocsLayout"; -import { Key, Shield, Globe, Lock, Terminal, Sparkles } from "lucide-react"; +import { StatusBadge } from "@/components/StatusBadge"; +import { Key, Shield, Terminal, Lock } from "lucide-react"; export const metadata = { - title: "Account Setup & Provider Configuration — Nuncio Docs", - description: "Comprehensive guide to setting up IMAP, SMTP, JMAP, Google Workspace OAuth 2.0 PKCE, and CalDAV/CardDAV accounts in Nuncio.", + title: "Account Setup & Provider Configuration (Planned) — Nuncio Docs", + description: "The intended experience for connecting IMAP, SMTP, JMAP, and CalDAV/CardDAV accounts in Nuncio. Nuncio is pre-alpha; this page describes the design, not a flow you can complete with a real account today.", }; export default function AccountSetupDocPage() { @@ -17,61 +18,58 @@ export default function AccountSetupDocPage() {
- Getting Started • Step 2 + Getting Started • Planned

Account Setup & Provider Configuration

- Nuncio connects to unlimited email and calendar accounts across any standard IMAP/SMTP host, JMAP provider, or Google Workspace. + This page describes the intended end-user experience for connecting mail and calendar accounts. Nuncio + is pre-alpha: there is no polished onboarding flow for a real account yet, and this is not a + step-by-step guide you can follow today.

+
- {/* IMAP/SMTP Setup */} + {/* IMAP/SMTP Setup — real capability, developer path */}

- 1. Standard IMAP & SMTP Provider Setup + What Exists Today: IMAP/SMTP Sync in the Engine

- Add standard email accounts (ProtonMail Bridge, Fastmail, Posteo, custom domain servers) via CLI or GUI: + The underlying capability — real IMAP fetch, storage, and SMTP send, tested against mock servers — is + genuinely implemented in the engine you can build from source. The nuncio account add{" "} + and nuncio account list/show/edit/delete/test commands exist on the reference + CLI today for developers driving the daemon directly; there is no consumer-facing setup wizard around + them yet.

-
-{`# Add IMAP/SMTP account via CLI
-nuncio account add \\
-  --label "Work Mail" \\
-  --email "james.maes@kof22.com" \\
-  --imap "mail.kof22.com:993" \\
-  --smtp "mail.kof22.com:465"`}
-              
- {/* Google OAuth PKCE */} + {/* Planned providers */}

- 2. Google Workspace & Gmail OAuth 2.0 PKCE (`RFC 7636`) + Planned: Broader Provider Support

- Nuncio supports native OAuth 2.0 Proof Key for Code Exchange (`RFC 7636`). You never enter or store raw Google account passwords. + JMAP, CalDAV calendar sync, and CardDAV contacts sync are on the roadmap as additional protocol + backends alongside IMAP/SMTP. OAuth-based provider flows (for Gmail-style accounts) are part of that + same future account-setup experience and are not implemented yet.

-
-{`# Add Google account via CLI
-nuncio account add --provider google --email "user@company.com"
-
-# Nuncio opens http://127.0.0.1:9422/oauth/callback in your system browser.
-# Refresh tokens are encrypted and stored inside OS Keyring (DPAPI / Keychain Access).`}
-              
+
- {/* Keyring Enclave Notice */} + {/* Keyring Notice — real */}
- Zero Raw Passwords in SQLite Storage + Credentials Go Through the OS Keyring, Today

- All account passwords, OAuth 2.0 refresh tokens, and private SASL credentials are isolated directly inside your operating system's hardware-backed credential vault (macOS Keychain Access, Windows DPAPI, or Linux Secret Service via `keyring-rs`). SQLite databases store zero credential strings. + Account credentials are routed through the OS keyring rather than stored in plaintext or in SQLite — + that boundary is real in the engine now, and stays true regardless of which onboarding flow eventually + sits on top of it.

diff --git a/src/app/docs/export-backups/page.tsx b/src/app/docs/export-backups/page.tsx index b02c336..3426bda 100644 --- a/src/app/docs/export-backups/page.tsx +++ b/src/app/docs/export-backups/page.tsx @@ -2,11 +2,12 @@ import React from "react"; import { Header } from "@/components/Header"; import { Footer } from "@/components/Footer"; import { DocsLayout } from "@/components/DocsLayout"; -import { Terminal, Database, FileText, Archive, Sparkles } from "lucide-react"; +import { AvailableNow } from "@/components/StatusBadge"; +import { Terminal, Archive } from "lucide-react"; export const metadata = { - title: "Universal Portable Data Export & Automated Backups — Nuncio Docs", - description: "Complete guide to exporting email accounts, folders, and NSQL queries to MBOX, EML ZIP, JSON, and JSONL formats using nuncio mail export.", + title: "Data Export & Backups — Nuncio Docs", + description: "Export synced mail to MBOX, EML (zip), JSON, or JSON Lines with nuncio mail export — real and working today, from a source build of the engine.", }; export default function ExportBackupsDocPage() { @@ -20,10 +21,11 @@ export default function ExportBackupsDocPage() { Maintenance • Backups

- Universal Data Export & Automated CLI Backups + Data Export & Backups

- Nuncio empowers you to perform full backups or exports of all your emails, accounts, folders, or NSQL result sets into standard portable open formats without vendor lock-in. + Export synced mail to standard, portable, open formats with no vendor lock-in — this is one of the + genuinely working pieces of the engine you can build from source today.

@@ -31,20 +33,21 @@ export default function ExportBackupsDocPage() {

- 1. Headless CLI Automated Backup Commands + 1. `nuncio mail export`

- Run automated periodic backup scripts via POSIX shell scripts, systemd timers, or cron jobs using `nuncio mail export`: + Restrict an export to one account or one folder (the two flags are mutually exclusive); omit both to + export everything synced.

-{`# Export full account inbox to standard RFC 4155 MBOX format
-nuncio mail export --account "james.maes@kof22.com" --format mbox --output ~/backups/inbox.mbox
+{`# Export one account's synced mail to MBOX
+nuncio mail export --format mbox --out ~/backups/inbox.mbox --account 
 
-# Export specific folder to compressed EML ZIP archive with manifest.json
-nuncio mail export --folder "Archive" --format eml-zip --output ~/backups/archive.zip
+# Export one folder to a zip of raw .eml files plus manifest.json
+nuncio mail export --format eml --out ~/backups/archive.zip --folder 
 
-# Export NSQL filter query results to line-delimited JSONL for LLM data pipelines
-nuncio mail export --query "sender LIKE '%@kof22.com%'" --format jsonl --output ~/backups/kof22_vip.jsonl`}
+# Export everything synced to JSON Lines
+nuncio mail export --format jsonl --out ~/backups/all-mail.jsonl`}
               
@@ -52,20 +55,20 @@ nuncio mail export --query "sender LIKE '%@kof22.com%'" --format jsonl --output

- 2. Supported Portable Export Formats + 2. Supported Formats

- MBOX (`.mbox`) -

Standard RFC 4155 mailbox format compatible with Thunderbird, Apple Mail, and Python `mailbox` module.

+ MBOX (`--format mbox`) +

Standard mailbox format readable by Thunderbird, Apple Mail, and most mail tooling.

- EML ZIP Archive (`.zip`) -

Compressed archive containing raw `.eml` MIME message files and `manifest.json` metadata index.

+ EML zip (`--format eml`) +

A zip archive of individual `.eml` MIME files plus a `manifest.json` index.

- JSON (`.json`) & JSONL (`.jsonl`) -

Structured payload streams tailored for LLM fine-tuning, vector embeddings, and custom analytics.

+ JSON / JSON Lines (`--format json` / `jsonl`) +

Structured payloads suited to scripting, analytics, or feeding other tools.

diff --git a/src/app/docs/html-rendering/page.tsx b/src/app/docs/html-rendering/page.tsx index 3873f8e..7ff0e0d 100644 --- a/src/app/docs/html-rendering/page.tsx +++ b/src/app/docs/html-rendering/page.tsx @@ -2,11 +2,12 @@ import React from "react"; import { Header } from "@/components/Header"; import { Footer } from "@/components/Footer"; import { DocsLayout } from "@/components/DocsLayout"; -import { Layers, Monitor, Terminal, Bot, Shield, Eye } from "lucide-react"; +import { StatusBadge } from "@/components/StatusBadge"; +import { Layers, Monitor, Shield } from "lucide-react"; export const metadata = { - title: "HTML & Image Rendering Guide — Nuncio Docs", - description: "Comprehensive guide to HTML email parsing, inline image rendering (Kitty/iTerm2/Sixel), tracking beacon neutralization, and Markdown conversion.", + title: "HTML Email Rendering & Sandboxing (Planned) — Nuncio Docs", + description: "The plan for rendering HTML email safely: a sandboxed iframe with scripts disabled. HTML sanitization is on the roadmap and not implemented yet.", }; export default function HtmlRenderingDocPage() { @@ -17,57 +18,63 @@ export default function HtmlRenderingDocPage() {
- User Experience • Rendering + Security • Planned

- Rendering HTML & Inline Images Across Non-GUI Shells + HTML Email Rendering & Sandboxing

- Nuncio provides seamless HTML and image rendering mechanics across Terminal TUI, POSIX CLI, and AI MCP agents without compromising security. + Untrusted HTML in email is a real attack surface. The plan is a sandboxed rendering pipeline — + nothing on this page is built yet. +

+ +
+ + {/* The design */} +
+

+ + The Design: Sandbox First +

+

+ The intended approach, per the project's own security conventions, is to render untrusted HTML + email inside an <iframe sandbox> with JavaScript disabled, rather than trusting a + webview to render remote content directly. That includes stripping remote tracking pixels and blocking + external script and style injection before anything reaches the renderer.

- {/* Rendering Grid */} -
-
-
- - 1. Terminal TUI (Ratatui) +
+
+
+ Desktop GUI Rendering +

- Converts HTML to clean ANSI text via `html2text` with tracking pixels blocked. High-resolution images render inline using Kitty Graphics Protocol, iTerm2 Inline Images, or Sixel graphics. Press o to view in system browser. + Sandboxed iframe rendering inside the planned desktop client — not built.

- -
-
- - 2. POSIX CLI +
+
+ Terminal / CLI Rendering +

- nuncio mail show <id> prints formatted plain text. Use --html for markdown output, --raw-html for piping to `w3m`/`lynx`, or --open for browser trigger. -

-
- -
-
- - 3. AI MCP Agents -
-

- Converts HTML to token-efficient Markdown for LLM prompt contexts. Image attachments are passed as Base64 multimodal vision content blocks to Vision LLMs. + A plain-text or Markdown fallback for non-GUI clients is the intended direction, once those clients + exist.

- {/* Tracking Pixel Security Box */}
- - Automatic Tracking Pixel & Web Bug Neutralization + + Why This Isn't Rushed

- Nuncio automatically strips 1x1 tracking GIF/PNG pixels (`<img src="...track..." width="1" height="1">`), remote CSS `@import` triggers, and external script tags before rendering email payloads. + HTML sanitization is exactly the kind of security-sensitive surface we'd rather ship correctly and + later than ship early and wrong. It's tracked as a real milestone on the roadmap, not a checkbox + feature.

diff --git a/src/app/docs/interfaces/page.tsx b/src/app/docs/interfaces/page.tsx index 7457971..bf90096 100644 --- a/src/app/docs/interfaces/page.tsx +++ b/src/app/docs/interfaces/page.tsx @@ -2,27 +2,25 @@ import React from "react"; import { Header } from "@/components/Header"; import { Footer } from "@/components/Footer"; import { DocsLayout } from "@/components/DocsLayout"; -import { Monitor, Terminal, Code, Bot, Keyboard, Sparkles } from "lucide-react"; +import { StatusBadge, AvailableNow } from "@/components/StatusBadge"; +import { Monitor, Keyboard, Layers } from "lucide-react"; export const metadata = { - title: "Four Presentation Shells & Vim Keybindings Reference — Nuncio Docs", - description: "Complete guide and Vim keybinding reference table for Nuncio Desktop GUI, Vim Ratatui Terminal TUI, POSIX CLI, and Native MCP AI Server.", + title: "Client Interfaces (Planned) — Nuncio Docs", + description: "The reference CLI is a real gRPC client today. A desktop GUI, a terminal TUI, and an MCP AI client are planned as separate thin clients over the same contract, and none of them exist yet.", }; export default function InterfacesDocPage() { - const vimKeybindings = [ + const plannedKeybindings = [ { key: "j / k", action: "Move message focus cursor down / up" }, - { key: "h / l", action: "Switch pane focus between Folder Tree and Message Preview" }, - { key: "g i", action: "Jump focus directly to Inbox" }, - { key: "e", action: "Archive focused email chord" }, - { key: "s", action: "Toggle Star / Flag status" }, - { key: "# / d", action: "Move email to Trash" }, - { key: "f", action: "Open NSQL Filter Rules Modal" }, - { key: "a", action: "Open Account Switcher Modal" }, - { key: "/", action: "Focus FTS5 Trigram Full-Text Search Bar" }, - { key: "o", action: "Open raw HTML email in system browser" }, - { key: "u", action: "Check for background auto-updates" }, - { key: "q", action: "Quit TUI (daemon stays running in background)" }, + { key: "h / l", action: "Switch pane focus between folder tree and message preview" }, + { key: "e", action: "Archive focused email" }, + { key: "s", action: "Toggle star / flag status" }, + { key: "d", action: "Move email to trash" }, + { key: "f", action: "Open NSQL filter rules view" }, + { key: "a", action: "Open account switcher" }, + { key: "/", action: "Focus full-text search bar" }, + { key: "q", action: "Quit the TUI (daemon keeps running)" }, ]; return ( @@ -32,24 +30,79 @@ export default function InterfacesDocPage() {
- User Interfaces • Reference + Client Interfaces

- Four Presentation Shells & Keyboard Motion Table + Client Interfaces: One Contract, Several Clients

- Nuncio delivers 100% feature parity across all 4 presentation interfaces, synchronized in microsecond time over local length-prefixed IPC socket streams. + Nuncio's architecture is one daemon publishing a single versioned gRPC contract, consumed by + separate, thin client projects. Today that contract has exactly one working client. The rest below + is the intended design, not a working feature.

- {/* Vim Keybinding Reference */} + {/* The four "shells" honestly gated */} +
+
+
+ Reference CLI (`nuncio-cli`) + +
+

+ A scriptable, noun-verb command-line client and the project's own end-to-end test driver. + Build and run it today with cargo run -p nuncio-cli. +

+
+ +
+
+ Desktop GUI + +
+

+ A native desktop app consuming the frozen gRPC API, planned as a separate client repository. Not + built yet. +

+
+ +
+
+ Terminal TUI + +
+

+ A keyboard-driven terminal client over the same API. The keybinding table below is the intended + design for this client, not something you can run today. +

+
+ +
+
+ MCP AI Client + +
+

+ A governed bridge letting AI agents work with your mail through capability policies. See the{" "} + + MCP page + {" "} + for the full design. +

+
+
+ + {/* Planned Keybinding Reference */}
-

- - Vim Ratatui TUI (`nuncio-tui`) Motion Reference Table -

+
+

+ + Intended Terminal TUI Keybindings +

+ +
- {vimKeybindings.map((item, idx) => ( + {plannedKeybindings.map((item, idx) => (
{item.key} {item.action} @@ -58,35 +111,16 @@ export default function InterfacesDocPage() {
- {/* Four Shell Overview */} -
-
- 1. Tauri v2 Desktop GUI -

- Glassmorphic dark/light split-panes, live NSQL rule editor, WYSIWYG rich text composer, and native OS desktop notifications. -

-
- -
- 2. Vim Ratatui Terminal TUI -

- Sub-millisecond keyboard velocity, Kitty/iTerm2 inline image rendering, HTML-to-ANSI formatting, and single-key triage. -

-
- -
- 3. POSIX Scriptable CLI -

- Scriptable subcommand suite (`nuncio mail list`, `nuncio mail export`, `nuncio filter apply`) with deterministic `--json` piping. -

-
- -
- 4. Native MCP AI Server -

- Stdio stream protocol connecting Claude Desktop, Antigravity, and Cursor with McpAgentPolicy RBAC safety enclaves. -

-
+
+ + + What "Feature Parity" Means Here + +

+ Because every client is a thin layer over the same gRPC contract, feature parity across clients is a + property of the contract, not of separate implementations staying in sync by discipline. That is the + design goal for GUI, TUI, and MCP once they're built — it is not a claim that they exist today. +

diff --git a/src/app/docs/mcp/page.tsx b/src/app/docs/mcp/page.tsx index 5073d91..85429d1 100644 --- a/src/app/docs/mcp/page.tsx +++ b/src/app/docs/mcp/page.tsx @@ -2,11 +2,13 @@ import React from "react"; import { Header } from "@/components/Header"; import { Footer } from "@/components/Footer"; import { DocsLayout } from "@/components/DocsLayout"; -import { Bot, Shield, Terminal, Lock, Sparkles, CheckCircle2 } from "lucide-react"; +import { StatusBadge } from "@/components/StatusBadge"; +import { Bot, Shield, Lock } from "lucide-react"; +import Link from "next/link"; export const metadata = { - title: "Native Model Context Protocol (MCP) Setup & Security — Nuncio Docs", - description: "Complete guide for integrating Claude Desktop, Antigravity, and Cursor with Nuncio MCP Server and McpAgentPolicy RBAC security.", + title: "Model Context Protocol (MCP) — Planned — Nuncio Docs", + description: "The design for a governed MCP client that lets AI agents work with your mail through capability policies and an audit trail. Not built yet — see the full design on the MCP page.", }; export default function McpDocPage() { @@ -17,61 +19,73 @@ export default function McpDocPage() {
- AI Integration • MCP Server + AI Integration • Planned

- Native Model Context Protocol (`nuncio-mcp`) Integration + Model Context Protocol (MCP) Client

- Connect Claude Desktop, Antigravity, ChatGPT, Cursor, and custom LLMs safely to your local email and calendar database over stdio. + An MCP client is a planned, separate thin client over Nuncio's gRPC contract — the same one the + CLI already uses. It does not exist yet. Nothing on this page is runnable today.

+
- {/* Claude Desktop Config */} + {/* Design principles */} +
+
+ + + A Gateway, Not Direct Access + +

+ AI agents would never receive raw account credentials. Every action would pass through a policy + gateway that decides what a given agent is allowed to touch. +

+
+
+ + + Every Action, Audited + +

+ Agent tool calls would land in the same hash-chained WORM audit ledger the engine already uses for + account and rule mutations today. +

+
+
+ + {/* Target config shape, clearly marked as non-functional */}

- - 1. Claude Desktop Configuration (`claude_desktop_config.json`) + + Target Configuration Shape

+

+ This is what an MCP client config would look like once it exists. It will not connect to anything + today — there is no nuncio-mcp binary to run. +

 {`{
   "mcpServers": {
     "nuncio": {
       "command": "nuncio-mcp",
-      "args": ["--stdio"],
-      "env": {
-        "NUNCIO_LOG_LEVEL": "info"
-      }
+      "args": ["--stdio"]
     }
   }
 }`}
               
- {/* Security Enclave Table */} -
-

- - 2. McpAgentPolicy AI Security Gateway Features -

-
-
- Multi-Account Aggregation Hub -

Unify 10+ IMAP, Google Workspace, and JMAP accounts into a single stdio endpoint.

-
-
- Zero Direct Account Credentials -

LLMs interact exclusively through Nuncio tools; they never touch passwords or OAuth tokens.

-
-
- WORM Audit Hash Chains -

Every single MCP tool invocation is logged in an immutable HMAC-SHA256 hash-chain ledger.

-
-
- Microsecond Local Speed -

Sub-10ms local SQLite FTS5 search context retrieval with zero API cloud fee latency.

-
-
+
+

+ For the full design — the planned tool surface, the capability-policy model, and why a gateway instead + of direct access — see the{" "} + + MCP page + + . +

diff --git a/src/app/docs/nsql-spec/page.tsx b/src/app/docs/nsql-spec/page.tsx index 2f714cd..8b631be 100644 --- a/src/app/docs/nsql-spec/page.tsx +++ b/src/app/docs/nsql-spec/page.tsx @@ -2,11 +2,12 @@ import React from "react"; import { Header } from "@/components/Header"; import { Footer } from "@/components/Footer"; import { DocsLayout } from "@/components/DocsLayout"; -import { Cpu, Code, Shield, Sparkles, CheckCircle2 } from "lucide-react"; +import { StatusBadge, AvailableNow } from "@/components/StatusBadge"; +import { Cpu, Code, Sparkles } from "lucide-react"; export const metadata = { - title: "NSQL Filter Language Specification & Grammar — Nuncio Docs", - description: "Complete language specification, AST grammar rules, field definitions, operators, and action verbs for Nuncio SQL (NSQL).", + title: "NSQL Filter Language Specification — Nuncio Docs", + description: "The real NSQL grammar: fields, operators, and actions parsed and validated by the engine today. Rules can be authored and dry-run tested now; live rule-firing against synced mail is still on the roadmap.", }; export default function NsqlSpecDocPage() { @@ -20,66 +21,76 @@ export default function NsqlSpecDocPage() { NSQL Filter Engine • Language Spec

- NSQL Language Specification & AST Grammar + NSQL Language Specification

- NSQL (Nuncio SQL) compiles declarative filter expressions into typed Rust AST objects executed inside `nunciod` with microsecond latency. + NSQL (Nuncio SQL) is a real, implemented grammar, parsed and validated by nuncio-filter using{" "} + sqlparser-rs. You can create, validate, and dry-run test rules against your synced mail + today.

- {/* Grammar Form */} + {/* Grammar Form — the real grammar */}

- 1. Standard NSQL Statement Syntax + 1. Statement Syntax

-{`CREATE RULE "VIP Priority Route"
-ON ACCOUNT "james.maes@kof22.com"
-PRIORITY 10
-WHEN sender LIKE '%@kof22.com%' AND (subject REGEXP '(?i)(urgent|security)' OR size_bytes > 5242880)
-THEN MOVE TO 'vip-inbox', COPY TO 'Archive', SET read = TRUE, CALL WEBHOOK 'https://api.kof22.com/webhook'
-WITH STOP PROCESSING;`}
+{`[ON ACCOUNT '']
+[WHERE]    [AND|OR ]
+ACTION  [,  ...];`}
+              
+

+ Example, matching the parser's actual grammar (not a WHEN/THEN dialect): +

+
+{`ON ACCOUNT 'you@example.com'
+WHERE from CONTAINS '@example-crm.com' AND size > 5242880
+ACTION MOVE TO 'vip-inbox', FLAG;`}
               
- {/* Field Table */} + {/* Field / Operator / Action Table */}
- Target Fields + Fields & Operators
    -
  • • subject: Email subject line header string
  • -
  • • sender / from: Message sender email address
  • -
  • • recipient / to: Recipient address string
  • -
  • • body: Plain text / HTML email body content
  • -
  • • size_bytes / size: Total byte size of email payload
  • -
  • • has_attachment: Boolean flag for attachments
  • -
  • • header['X-Spam']: Custom MIME header key lookup
  • +
  • • subject, from, to, body
  • +
  • • has_attachment, size, folder, date, account
  • +
  • • header['X-Spam-Score']: header lookup —{" "} +
  • +
  • • Operators: = != CONTAINS NOT CONTAINS MATCHES > < >= <= IN NOT IN
- Action Clauses + Actions
    -
  • • MOVE TO 'folder': Relocate to target folder
  • -
  • • COPY TO 'folder': Copy to target folder
  • -
  • • SET read = TRUE: Mark email read
  • -
  • • SET flagged = TRUE: Star / flag message
  • -
  • • FORWARD TO 'email': Forward message payload
  • -
  • • CALL WEBHOOK 'url': Trigger HMAC signed POST
  • -
  • • DELETE: Move message directly to Trash
  • +
  • • MOVE TO 'folder' / COPY TO 'folder'
  • +
  • • MARK READ / MARK UNREAD
  • +
  • • FLAG / UNFLAG
  • +
  • • DELETE
  • +
  • • FORWARD TO 'email'
  • +
  • • CALL WEBHOOK 'url' — dispatcher is real,{" "} +
- {/* Dry-Run Engine Callout */} -
- - - Microsecond Dry-Run Preview Engine + {/* Honest status callout */} +
+ + + What Works Today vs What's Still Ahead

- 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. + The parser, validator, and match engine are genuinely implemented — account-scoped rules + (ON ACCOUNT) and non-ASCII parsing are correct and tested. Use{" "} + nuncio filter create --name "..." --sql "..." to save a rule, and{" "} + nuncio filter test --sql "..." --message-id <id> to dry-run it against a real + message — both are real today. What isn't wired up yet: the match-and-act engine doesn't run against + the live sync path, so saved rules don't currently take action on new mail as it arrives.

diff --git a/src/app/docs/page.tsx b/src/app/docs/page.tsx index 6fe9e72..3b632a3 100644 --- a/src/app/docs/page.tsx +++ b/src/app/docs/page.tsx @@ -2,6 +2,8 @@ import React from "react"; import { Header } from "@/components/Header"; import { Footer } from "@/components/Footer"; import { DOCS_NAVIGATION } from "@/lib/docs-navigation"; +import { StatusBadge } from "@/components/StatusBadge"; +import { GITHUB_URL, ROADMAP_URL } from "@/lib/status"; import { BookOpen, ArrowRight, @@ -15,12 +17,15 @@ import { Terminal, FileCheck, HelpCircle, + AlertTriangle, + MapPin, } from "lucide-react"; +import { GithubIcon } from "@/components/GithubIcon"; import Link from "next/link"; export const metadata = { - title: "Documentation & Knowledge Base — Nuncio", - description: "Complete technical manual, installation guide, NSQL filter language specification, protocol setup, and MCP LLM agent integration guide for Nuncio.", + title: "Documentation — Nuncio (Pre-Alpha)", + description: "Docs for the Nuncio engine: what genuinely builds and runs from source today (the daemon, CLI, sync, search, export, WORM audits) versus what's designed but not yet usable (GUI, TUI, MCP, live-firing filters, at-rest encryption, HTML sanitization). Nuncio is pre-alpha — not yet usable for real accounts.", }; const ICON_MAP: Record = { @@ -45,7 +50,7 @@ export default function DocsIndexPage() {
- Nuncio Knowledge Base & Technical Manual + Nuncio Documentation

@@ -53,8 +58,35 @@ export default function DocsIndexPage() {

- In-depth standalone guides for installation, protocol setup, NSQL filter rules, AI MCP integration, security whitepapers, and automated backups. + Guides for the engine you can build from source today, and honest design docs for what's still on + the roadmap: NSQL filter rules, the WORM audit ledger, export & recovery, and the planned MCP AI + gateway.

+ + {/* Prominent pre-alpha notice */} +
+
+ + Pre-alpha — not yet usable for real accounts +
+

+ Nuncio has no installer and no end-user onboarding flow. Pages here that describe a developer building + the daemon and CLI from source, running IMAP/SMTP sync, search, export, or the WORM audit ledger are + describing real, working code. Anything about a desktop GUI, terminal TUI, MCP AI client, live-firing + filters, at-rest encryption, or HTML sanitization is — + the design we're building toward, not something you can use today. +

+ +
{/* 10 Standalone Documentation Cards Grid */} diff --git a/src/app/docs/quickstart/page.tsx b/src/app/docs/quickstart/page.tsx index c20f44b..5f40bf6 100644 --- a/src/app/docs/quickstart/page.tsx +++ b/src/app/docs/quickstart/page.tsx @@ -2,11 +2,14 @@ import React from "react"; import { Header } from "@/components/Header"; import { Footer } from "@/components/Footer"; import { DocsLayout } from "@/components/DocsLayout"; -import { Download, Terminal, Check, Copy, Sparkles, Shield, Monitor, Layers } from "lucide-react"; +import { AvailableNow } from "@/components/StatusBadge"; +import { GITHUB_URL } from "@/lib/status"; +import { GithubIcon } from "@/components/GithubIcon"; +import { Download, Terminal, Sparkles } from "lucide-react"; export const metadata = { - title: "Quickstart & Installation Guide — Nuncio Docs", - description: "Comprehensive step-by-step guide to installing Nuncio across macOS, Windows, Linux, Homebrew, and Cargo Rust binaries.", + title: "Quickstart — Build & Run Nuncio From Source — Nuncio Docs", + description: "How to clone the Nuncio engine repository and build and run the daemon (nunciod) and reference CLI (nuncio-cli) from source today. There is no packaged installer yet — Nuncio is pre-alpha.", }; export default function QuickstartDocPage() { @@ -20,76 +23,74 @@ export default function QuickstartDocPage() { Getting Started • Step 1

- Quickstart & Multi-Platform Installation + Quickstart: Build & Run From Source

- Nuncio is 100% free, sovereign, and open-source under MIT & Apache-2.0 licenses. Choose your target platform below for instant setup. + Nuncio is pre-alpha — there is no installer, package, or download for end users yet. What is real: a + Cargo workspace you can clone and build today, which gives you a working daemon (nunciod) + and a reference CLI (nuncio-cli) that talks to it.

- {/* Homebrew section */} + {/* Clone + build */}

- Option 1: macOS & Linux via Homebrew Tap + 1. Clone & Build the Workspace

- The fastest way to install Nuncio CLI, TUI, MCP, and daemon binaries on macOS and Linux is using our official Homebrew tap: + Requires the Rust toolchain pinned in rust-toolchain.toml. Cargo will fetch it + automatically via rustup.

-{`# Add tap and install all Nuncio workspace binaries
-brew tap koftwentytwo/tap
-brew install nuncio`}
+{`git clone https://github.com/KofTwentyTwo/nuncio.git
+cd nuncio
+cargo build --workspace`}
               
- {/* Cargo section */} + {/* Run the daemon */}

- - Option 2: Cargo Rust Crates (Cross-Platform) + + 2. Run the Daemon (`nunciod`)

- If you have the Rust toolchain installed, build and install directly from crates.io with native CPU optimizations: + The daemon owns all state and serves a versioned gRPC API on loopback 127.0.0.1:9420, + behind a bearer token minted into your OS keyring on first run.

-
-{`cargo install nuncio-cli nuncio-tui nuncio-mcp nunciod`}
+              
+{`cargo run -p nunciod`}
               
- {/* Standalone Desktop Package Installers */} + {/* Drive it with the CLI */}

- - Option 3: Pre-Packaged Desktop GUI Installers + + 3. Drive It With the Reference CLI

-
-
- macOS Universal -

Apple Silicon (M1-M4) & Intel x64 `.dmg` disk image.

- Download .DMG → -
-
- Windows 10 / 11 -

WiX `.msi` installer with Windows DPAPI Keyring integration.

- Download .MSI → -
-
- Linux Standalone -

Universal `.AppImage` & Tarball for Ubuntu, Fedora, Arch.

- Download .AppImage → -
-
+

+ With the daemon running in one terminal, nuncio-cli is a full gRPC client and + the project's own end-to-end test driver: +

+
+{`cargo run -p nuncio-cli -- system status`}
+              
- {/* Hybrid Daemon Topology */} + {/* Honesty callout */}
- Daemon Auto-Spawning & IPC IPC Architecture (`nunciod`) + What This Gets You Today

- Nuncio operates on a zero-configuration hybrid daemon architecture. Launching any presentation interface (`nuncio`, `nuncio-tui`, `nuncio-gui`, `nuncio-mcp`) automatically auto-spawns `nunciod` in the background. All presentation shells share a single-writer SQLite WAL database instance with zero race conditions. + From source, you get real IMAP/SMTP sync, SQLite FTS5 full-text search, MBOX/EML/JSON/JSONL export, and + a hash-chained WORM audit ledger — driven entirely through the CLI. There is no desktop GUI, terminal + TUI, or MCP AI client yet; those are separate client projects planned on top of the same gRPC contract. + See the repository for + the current state of the workspace.

diff --git a/src/app/docs/recovery/page.tsx b/src/app/docs/recovery/page.tsx index 29ec5ff..081942f 100644 --- a/src/app/docs/recovery/page.tsx +++ b/src/app/docs/recovery/page.tsx @@ -2,11 +2,12 @@ import React from "react"; import { Header } from "@/components/Header"; import { Footer } from "@/components/Footer"; import { DocsLayout } from "@/components/DocsLayout"; -import { HelpCircle, Database, RefreshCw, Terminal, Sparkles } from "lucide-react"; +import { AvailableNow } from "@/components/StatusBadge"; +import { HelpCircle, RefreshCw, Terminal } from "lucide-react"; export const metadata = { - title: "Self-Healing Database Corruption Recovery — Nuncio Docs", - description: "Technical guide to PRAGMA quick_check(10) diagnostics, CorruptedBackupManager isolation, and SqliteRecoveryEngine stream salvage.", + title: "Database Corruption Recovery — Nuncio Docs", + description: "The automatic SQLite corruption detection, backup isolation, and stream-salvage recovery engine in nuncio-store. Real and tested today, from a source build of the engine.", }; export default function RecoveryDocPage() { @@ -20,10 +21,12 @@ export default function RecoveryDocPage() { Maintenance • Self-Healing

- Database Corruption Recovery & Stream Salvage Engine + Database Corruption Recovery

- If SQLite database corruption occurs due to an ungraceful system shutdown or hardware fault, Nuncio automatically isolates damaged files and salvages valid records into a fresh database. + If the local SQLite database is corrupted — an ungraceful shutdown, a disk fault — the engine + isolates the damaged file and salvages what it can into a fresh database automatically, with no + manual step required.

@@ -31,29 +34,25 @@ export default function RecoveryDocPage() {

- 1. Automatic Recovery Pipeline Steps + 1. What Happens Automatically

    -
  1. Startup Integrity Check (`PRAGMA quick_check(10)`): Executed every time `nunciod` or presentation shells open the database.
  2. -
  3. Corrupted Backup Isolation (`CorruptedBackupManager`): Damaged `.db`, `.db-wal`, and `.db-shm` files are moved to `~/.nuncio/corrupted_backups/nuncio_corrupted_<timestamp>.db`.
  4. -
  5. Stream Salvage Extraction (`SqliteRecoveryEngine`): Scans damaged B-trees to salvage valid `accounts`, `filter_rules`, and `filter_conditions`.
  6. -
  7. Daemon Background Remote Resync: Remote IMAP, JMAP, and Google accounts trigger background sync to rebuild local message caches seamlessly.
  8. +
  9. Integrity check on open: run every time the store is opened, detecting SQLite corruption versus an ordinary transient error (a distinct fix in the recovery code, since misclassifying a timeout as corruption would delete a perfectly good database).
  10. +
  11. Corrupted backup isolation (`CorruptedBackupManager`): damaged database files are moved aside into a dedicated backup directory rather than overwritten in place.
  12. +
  13. Stream salvage (`SqliteRecoveryEngine`): scans the damaged file for recoverable account configurations and NSQL filter rules, and restores what it can into a fresh database.
- {/* Diagnostics CLI */} -
-

- - 2. Manual Database Integrity CLI Commands -

-
-{`# Run manual SQLite integrity check
-nuncio store check-integrity
-
-# View isolated corrupted backups directory
-ls -l ~/.nuncio/corrupted_backups/`}
-              
+
+ + + No Manual Trigger Needed + +

+ This recovery path runs as part of opening the store, not as a CLI command you invoke — there is no + separate "run a recovery" step to remember. After a corrupted-and-recovered database, remote mail + accounts simply re-sync from the server to rebuild the local cache. +

diff --git a/src/app/docs/webhooks/page.tsx b/src/app/docs/webhooks/page.tsx index b97f007..85061df 100644 --- a/src/app/docs/webhooks/page.tsx +++ b/src/app/docs/webhooks/page.tsx @@ -2,11 +2,12 @@ import React from "react"; import { Header } from "@/components/Header"; import { Footer } from "@/components/Footer"; import { DocsLayout } from "@/components/DocsLayout"; -import { Code, Shield, Lock, Terminal, Sparkles } from "lucide-react"; +import { StatusBadge } from "@/components/StatusBadge"; +import { Code, Shield, Terminal } from "lucide-react"; export const metadata = { - title: "Outbound Signed Webhooks & SSRF Defense — Nuncio Docs", - description: "Technical specification for HMAC-SHA256 signed webhooks, JSON payloads, and SSRF security mitigations in Nuncio.", + title: "Outbound Webhooks & SSRF Defense — Nuncio Docs", + description: "The HMAC-SHA256 signed webhook dispatcher and SSRF defenses implemented in nuncio-filter. The dispatcher exists and is tested; it is not yet invoked from the live mail-sync path.", }; export default function WebhooksDocPage() { @@ -20,18 +21,21 @@ export default function WebhooksDocPage() { NSQL Engine • Webhook Security

- HMAC-SHA256 Signed Webhooks & SSRF Defense + Outbound 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. + An NSQL rule's CALL WEBHOOK 'url' action dispatches through{" "} + crates/nuncio-filter/src/webhook.rs: an HMAC-SHA256-signed HTTP POST with SSRF + defenses on the target URL. The dispatcher itself is implemented and tested.

+
{/* Payload Schema */}

- 1. Webhook JSON Request Payload Schema + 1. Webhook JSON Request Payload Shape

 {`{
@@ -39,10 +43,10 @@ export default function WebhooksDocPage() {
   "rule_id": "rule_vip_01",
   "rule_name": "VIP Priority Route",
   "message_id": "msg_892317823",
-  "account": "james.maes@kof22.com",
-  "sender": "alice@kof22.com",
+  "account": "you@example.com",
+  "sender": "alerts@example-crm.com",
   "subject": "Urgent Architecture Review",
-  "actions_taken": ["MOVE TO 'vip-inbox'", "CALL WEBHOOK 'https://api.kof22.com/webhook'"],
+  "actions_taken": ["MOVE TO 'vip-inbox'", "CALL WEBHOOK 'https://api.example.com/webhook'"],
   "matched_at": 1700000000
 }`}
               
@@ -52,14 +56,22 @@ export default function WebhooksDocPage() {
- 2. Code-Level SSRF Security Specifications + 2. SSRF Defenses in the Dispatcher
    -
  • Pre-Flight DNS Blacklist: Blocks `127.0.0.1`, `169.254.169.254` (cloud metadata endpoints), and private subnets (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`).
  • -
  • Zero Redirect Loop (`max_redirects(0)`): Rejects HTTP 301/302 redirects to prevent exfiltration.
  • -
  • HMAC-SHA256 Signature Header: Requests include `X-Nuncio-Signature` for server payload verification.
  • +
  • Pre-flight DNS blocking: rejects 127.0.0.1, 169.254.169.254 (cloud metadata endpoints), and private subnets (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16).
  • +
  • Zero redirect loop: rejects HTTP 301/302 redirects to prevent exfiltration.
  • +
  • HMAC-SHA256 signature header: requests carry an X-Nuncio-Signature header for the receiver to verify.
+ +
+

+ This is a real, tested piece of the engine — but because the filter match-and-act engine isn't yet + wired into the live mail-sync path, no webhook fires automatically against your inbox today. It fires + only when explicitly invoked in tests or once that wiring lands. +

+
diff --git a/src/app/docs/worm-audits/page.tsx b/src/app/docs/worm-audits/page.tsx index c42126d..9cc473c 100644 --- a/src/app/docs/worm-audits/page.tsx +++ b/src/app/docs/worm-audits/page.tsx @@ -2,11 +2,12 @@ import React from "react"; import { Header } from "@/components/Header"; import { Footer } from "@/components/Footer"; import { DocsLayout } from "@/components/DocsLayout"; -import { FileCheck, Shield, Lock, Terminal, Sparkles } from "lucide-react"; +import { AvailableNow } from "@/components/StatusBadge"; +import { FileCheck, Lock, Terminal } from "lucide-react"; export const metadata = { - title: "WORM Cryptographic Audit Hash Ledger — Nuncio Docs", - description: "Technical specification for Write Once Read Many (WORM) audit ledgers, HMAC-SHA256 hash chains, and CLI integrity verification in Nuncio.", + title: "WORM Audit Ledger — Nuncio Docs", + description: "The Write-Once-Read-Many, hash-chained audit ledger that records account and rule mutations. Real and working today, from a source build of the engine.", }; export default function WormAuditsDocPage() { @@ -17,42 +18,47 @@ export default function WormAuditsDocPage() {
- Compliance • WORM Audits + Security & Compliance

- Write Once Read Many (WORM) Audit Hash-Chain Ledger + WORM Audit Ledger

- Every automated rule execution, outbound webhook call, account mutation, and AI MCP tool call is recorded in an immutable audit ledger sealed with HMAC-SHA256 block hash chains. + Account and rule mutations are recorded in an append-only, hash-chained audit ledger. This is one of + the genuinely working pieces of the engine you can build from source today.

- {/* Cryptographic Hash Chain Math Formula */} + {/* Hash Chain Spec */}

- 1. HMAC-SHA256 Block Link Specification + 1. Hash-Chain Shape

- Each audit entry H_n is cryptographically bound to the preceding entry H_(n-1), preventing retroactive tampering or record deletion: + Each audit entry H_n is bound to the preceding entry H_(n-1), so any retroactive edit or deletion + breaks the chain and is detectable on verification:

-{`H_n = HMAC-SHA256(SecretKey, seq || timestamp || actor || action || payload_hash || H_n-1)`}
+{`H_n = HMAC-SHA256(secret_key, seq || timestamp || actor || action || payload_hash || H_n-1)`}
               
- {/* Verification CLI */} + {/* Real CLI */}

- 2. CLI Verification Tooling + 2. CLI Commands

-{`# Verify cryptographic hash chain integrity across all WORM ledger records
-nuncio store verify-audit-chain
+{`# List recent audit ledger records
+nuncio system audit list --limit 50 --offset 0
 
-# Output recent audit events as JSON stream for SIEM / SOC ingestion
-nuncio audit list --limit 50 --json`}
+# Verify the hash-chain integrity of the whole ledger
+nuncio system audit verify
+
+# Machine-readable output (the --json flag is global)
+nuncio --json system audit list --limit 50`}
               
diff --git a/src/app/features/page.tsx b/src/app/features/page.tsx index f323848..e3be313 100644 --- a/src/app/features/page.tsx +++ b/src/app/features/page.tsx @@ -1,84 +1,101 @@ import React from "react"; import { Header } from "@/components/Header"; import { Footer } from "@/components/Footer"; -import { CheckCircle2, ArrowRight, Sparkles, Monitor, Code, Lock, Database, RefreshCw, Mail, Calendar, Shield } from "lucide-react"; -import Link from "next/link"; +import { ArrowRight, Sparkles, Monitor, Code, Lock, Mail, Calendar, MapPin } from "lucide-react"; +import { StatusBadge } from "@/components/StatusBadge"; +import { GithubIcon } from "@/components/GithubIcon"; +import { GITHUB_URL, ROADMAP_URL } from "@/lib/status"; +import type { StatusVariant } from "@/lib/status"; export const metadata = { - title: "Nuncio Feature Matrix — Full Capability Directory", - description: "Comprehensive scannable table of all Nuncio capabilities: Core Email Engine, CalDAV/CardDAV Calendar, NSQL Automation, Four Presentation Shells, MCP AI, and Security.", + title: "Nuncio Feature Matrix — What's Shipped, What's Planned", + description: "A scannable directory of every Nuncio capability — Core Email Engine, Calendar/Contacts, NSQL Automation, four presentation shells, MCP AI, and Security — tagged with its real status: available now, in progress, or planned.", }; +interface FeatureRow { + feature: string; + scope: string; + benefit: string; + status: StatusVariant; +} + +interface FeatureCategory { + category: string; + icon: React.ReactNode; + rows: FeatureRow[]; +} + export default function FeaturesPage() { - const featureTables = [ + const featureTables: FeatureCategory[] = [ { category: "Core Email Engine & Inbox Power Tools", icon: , rows: [ - { feature: "Multi-Account Inbox Aggregation", scope: "Mail Engine", benefit: "Unify unlimited IMAP/SMTP, Google Workspace, and JMAP push accounts into a single local SQLite inbox." }, - { feature: "Native JMAP Protocol Engine (RFC 8620 / 8621)", scope: "JMAP Driver", benefit: "Ultra-low latency session discovery (.well-known/jmap), JSON-RPC method batching, and differential update sync." }, - { feature: "Microsecond SQLite FTS5 Search", scope: "Search Engine", benefit: "Trigram full-text index returning instant search results in <10ms across 100,000+ email messages." }, - { feature: "Vim Triage Motion Velocity", scope: "TUI & GUI", benefit: "Single-key triage chords (j/k/h/l/g i/e/s/d/#) for processing hundreds of emails per minute." }, - { feature: "Rich HTML & Inline Image Rendering", scope: "Reader Engine", benefit: "HTML-to-ANSI formatting with inline Kitty, iTerm2, and Sixel graphics protocols; press 'o' for browser view." }, - { feature: "Universal Portable Data Export", scope: "Export Engine", benefit: "Export full accounts, folders, or NSQL query results to standard RFC 4155 MBOX, EML ZIP archives, or JSON/JSONL." }, - { feature: "Tracking Beacon Neutralization", scope: "Reader Engine", benefit: "Automatic stripping of 1x1 tracking pixels, web bugs, and remote CSS import triggers before rendering." }, + { feature: "Multi-Account IMAP / SMTP Sync", scope: "Mail Engine", benefit: "Unify multiple IMAP/SMTP accounts into a single local SQLite inbox, tested against mock servers.", status: "available-now" }, + { feature: "JMAP Protocol Support", scope: "JMAP Driver", benefit: "A second mail backend alongside IMAP/SMTP, targeting session discovery and JSON-RPC batching per RFC 8620/8621.", status: "planned" }, + { feature: "SQLite FTS5 Full-Text Search", scope: "Search Engine", benefit: "Local full-text search over synced mail, backed by SQLite FTS5 — no cloud index required.", status: "available-now" }, + { feature: "Vim-Style Triage Motions", scope: "TUI & GUI", benefit: "Single-key triage chords for fast keyboard-driven inbox processing, once the TUI and GUI clients exist.", status: "planned" }, + { feature: "Rich HTML & Inline Image Rendering", scope: "Reader Engine", benefit: "HTML-to-text formatting for terminal display, with sandboxed HTML rendering as the target for the desktop GUI.", status: "planned" }, + { feature: "Portable Data Export (MBOX / EML / JSON)", scope: "Export Engine", benefit: "Export synced mail to standard, portable formats — no lock-in. Real and working today.", status: "available-now" }, + { feature: "Tracking Beacon Neutralization", scope: "Reader Engine", benefit: "Stripping 1x1 tracking pixels and remote CSS triggers before rendering, part of the HTML sanitization milestone.", status: "planned" }, ], }, { category: "Calendar & Contacts Management", icon: , rows: [ - { feature: "Natural Language Event Booking NLP Parser", scope: "Calendar NLP", benefit: "Create calendar events using human text ('Coffee with Bob next Tuesday at 2pm for 45 minutes')." }, - { feature: "Sovereign Contacts Engine (nuncio-contacts)", scope: "Contacts Engine", benefit: "Dedicated local SQLite contacts database with instant trigram FTS5 search index and vCard 4.0 generator." }, - { feature: "Multi-Provider CardDAV Synchronization", scope: "CardDAV Protocol", benefit: "Sync Google Contacts, Apple iCloud, Fastmail, and Nextcloud address books seamlessly over CardDAV." }, - { feature: "Automated Email Contact Harvesting", scope: "Mail / Contacts", benefit: "Automatically extracts name/email pairs from incoming and sent messages, updating interaction metrics." }, - { feature: "Native Event Scheduling & RSVP", scope: "Calendar Engine", benefit: "Accept, decline, or mark tentative on event invitations with automatic ICS payload updates." }, - { feature: "Google Calendar & Contacts OAuth 2.0", scope: "Auth Engine", benefit: "OAuth 2.0 PKCE loopback authentication with refresh token storage inside native OS Keyrings." }, + { feature: "Natural-Language Event Booking", scope: "Calendar NLP", benefit: "Create calendar events from plain text ('coffee with Bob next Tuesday at 2pm'), a target once CalDAV lands.", status: "planned" }, + { feature: "Local Contacts Store", scope: "Contacts Engine", benefit: "A dedicated local SQLite contacts database with search and vCard support is under active development.", status: "in-progress" }, + { feature: "CardDAV Contacts Sync", scope: "CardDAV Protocol", benefit: "Sync address books from Google, iCloud, Fastmail, and Nextcloud over CardDAV.", status: "planned" }, + { feature: "Automated Contact Harvesting", scope: "Mail / Contacts", benefit: "Extract name/email pairs from mail traffic and update interaction metrics automatically.", status: "planned" }, + { feature: "CalDAV Calendar Sync", scope: "Calendar Engine", benefit: "Calendar sync exposed end-to-end over the API; the transport exists in the engine but isn't wired up yet.", status: "planned" }, + { feature: "OAuth 2.0 PKCE for Google Calendar/Contacts", scope: "Auth Engine", benefit: "Loopback OAuth with refresh tokens stored in the OS keyring, once Calendar/Contacts protocols ship.", status: "planned" }, ], }, { - category: "Server-Side Email Filter Engine (NSQL)", + category: "NSQL Server-Side Filter Engine", icon: , rows: [ - { feature: "Nuncio SQL Parser (sqlparser 0.54)", scope: "Core Engine", benefit: "Compiles human-readable NSQL text into typed Rust AST representations with 6-pass validation." }, - { feature: "ON ACCOUNT & Domain Matching", scope: "NSQL / Rules", benefit: "Match rules against specific accounts, exact emails, or domain wildcards (*, %, %@company.com)." }, - { feature: "Pre-Ingestion Background Execution", scope: "nunciod Daemon", benefit: "Executes priority-ordered rules during background IMAP IDLE / JMAP push loops before database persistence." }, - { feature: "Dry-Run In-Memory Tester", scope: "All 4 Interfaces", benefit: "Test rules against inbox messages in microsecond time without database or network state mutations." }, - {feature: "WASM & QuickJS Sandboxed Plugin Engine", scope: "Plugin Runtime", benefit: "Execute custom WASI and QuickJS automation scripts with declared manifest security capabilities." }, - { feature: "HMAC Webhooks & SSRF Defense", scope: "Webhooks", benefit: "Dispatch signed webhooks with HMAC-SHA256, pre-flight DNS IP blacklisting, and redirect blocking." }, + { feature: "NSQL Parser & Compiler", scope: "Core Engine", benefit: "Compiles human-readable NSQL text into a typed Rust AST with multi-pass validation. Real and testable today.", status: "in-progress" }, + { feature: "ON ACCOUNT & Domain Matching", scope: "NSQL / Rules", benefit: "Match rules against specific accounts, exact addresses, or domain wildcards.", status: "in-progress" }, + { feature: "Dry-Run Rule Tester", scope: "CLI (today)", benefit: "Test a rule against a sample message without touching your database or network state. Works today via the CLI.", status: "in-progress" }, + { feature: "Rules Firing on Synced Mail", scope: "nunciod Daemon", benefit: "Running validated rules automatically during the live IMAP sync loop — the next milestone on the roadmap.", status: "planned" }, + { feature: "Signed Outbound Webhooks", scope: "Webhooks", benefit: "HMAC-SHA256 signed webhook dispatch with redirect blocking and private-IP defenses — implemented in the engine, not yet wired to live sync.", status: "in-progress" }, + { feature: "WASM / QuickJS Plugin Runtime", scope: "Plugin Runtime", benefit: "Sandboxed custom automation scripts with declared capability manifests.", status: "planned" }, ], }, { - category: "Four Presentation Shells (100% Feature Parity)", + category: "Four Presentation Shells", icon: , rows: [ - { feature: "Tauri v2 Native Desktop GUI", scope: "GUI", benefit: "Glassmorphic visual workspace, split-pane resizers, sandboxed HTML viewer, and visual drag-and-drop rule builder." }, - { feature: "Ratatui Terminal TUI", scope: "TUI", benefit: "Vim motions (j/k/h/l/g i/e/s), single-key triage chords, split-view text/HTML previewer, and live log inspector." }, - { feature: "POSIX Scriptable CLI", scope: "CLI", benefit: "Pipeable JSON output (--json), microsecond search, headless daemon management (nunciod), and shell automation." }, - { feature: "Native MCP AI Server", scope: "MCP AI", benefit: "Exposes mail, calendar, and rule tools to LLM agents (Claude Desktop, Antigravity, ChatGPT) via Model Context Protocol." }, + { feature: "POSIX Reference CLI", scope: "CLI", benefit: "Pipeable JSON output (--json), the E2E driver for the engine, and the only client that exists today.", status: "available-now" }, + { feature: "Native Desktop GUI", scope: "GUI", benefit: "A visual workspace, split panes, sandboxed HTML viewer, and drag-and-drop rule builder — planned as a separate client repo.", status: "planned" }, + { feature: "Terminal TUI", scope: "TUI", benefit: "Vim motions, single-key triage chords, and a split-view previewer for keyboard-first users.", status: "planned" }, + { feature: "MCP AI Client", scope: "MCP", benefit: "Exposes mail, calendar, and rule tools to LLM agents through a governed gateway.", status: "planned" }, ], }, { - category: "Native Model Context Protocol (MCP) AI Integration", + category: "Model Context Protocol (MCP) AI Integration", icon: , rows: [ - { feature: "Autonomous Local LLM Summarization & Triage", scope: "Local AI Engine", benefit: "Offline Ollama/llama.cpp thread 3-bullet executive recaps, action item extraction, and smart replies." }, - { feature: "Claude Desktop & LLM Integration", scope: "MCP Protocol", benefit: "Connect Claude Desktop, Antigravity, and Cursor directly to local mail and calendar databases over stdio." }, - { feature: "McpAgentPolicy RBAC Gateway", scope: "MCP Security", benefit: "Enforce fine-grained capability flags (read_mail, send_mail, read_calendar), folder whitelists, and PII redaction." }, - { feature: "Automatic PII Redaction", scope: "MCP Enclave", benefit: "Automatic masking of Social Security Numbers, Credit Cards, and private credentials before payloads touch LLMs." }, + { feature: "Local LLM Summarization & Triage", scope: "Local AI", benefit: "Offline thread summarization, action-item extraction, and smart replies — a future capability once the MCP client exists.", status: "planned" }, + { feature: "Claude Desktop & MCP Client Integration", scope: "MCP Protocol", benefit: "Connect AI agents to local mail and calendar data over stdio through a policy gateway.", status: "planned" }, + { feature: "RBAC Capability Gateway", scope: "MCP Security", benefit: "Fine-grained capability flags, folder whitelists, and audit logging for every agent tool call.", status: "planned" }, + { feature: "Automatic PII Redaction", scope: "MCP Enclave", benefit: "Masking sensitive identifiers before payloads reach an LLM context window.", status: "planned" }, ], }, { - category: "Sovereign Privacy, Security & Storage", + category: "Privacy, Security & Storage", icon: , rows: [ - { feature: "OpenPGP (RFC 3156) & S/MIME (RFC 8551) E2EE", scope: "E2EE Engine", benefit: "Native message signing, verification, encryption, and visual security badge rendering across all 4 UIs." }, - { feature: "AES-256-GCM Encryption at Rest", scope: "Storage", benefit: "Column-level encryption for email bodies and subject lines using PayloadCipher." }, - { feature: "age X25519 Attachment Ciphers", scope: "Storage", benefit: "Large binary attachment streams encrypted with age ciphers and 64KB chunk authentication." }, - { feature: "Memory Page Zeroing on Drop", scope: "Core Vault", benefit: "Keyring secrets and passphrase buffers locked in memory and zeroed out on drop via ZeroizeOnDrop." }, - { feature: "Strict HTML Email Sandboxing", scope: "GUI / TUI", benefit: "