This is the complete path from a fresh fork to a private Zaati OS dashboard powered by the LLM you already use.
You will end with:
- a public code fork that stays safe to share
- a separate private repository for personal snapshots
- one scheduled LLM workflow that refreshes several sources together
- a private dashboard protected by Cloudflare Access
Want to look around first? Stop after the synthetic tutorial. It needs no credentials, provider account,
.envfile, or personal data.
| Stage | What you do | What Zaati OS creates |
|---|---|---|
| 1. Test drive | Fork, install, and run the tutorial | A local dashboard with synthetic data |
| 2. Connect your LLM | Generate and paste one private task prompt | Validated snapshots in a private repository |
| 3. Deploy safely | Protect a hostname, then connect private data | Your private, always-available dashboard |
You need:
- Git
- Node.js 22 or newer
- a GitHub account
- an LLM or automation environment that can use your approved sources and write to GitHub
- a Cloudflare account and custom domain only when you are ready to deploy
ChatGPT, Claude, Gemini, local models, n8n, cron, and custom commands can all use the same generated contract. Provider menus differ, but the Zaati OS side does not.
Fork mohsinht/zaati-os, then clone your fork:
git clone https://github.com/YOUR_GITHUB_USERNAME/zaati-os.git
cd zaati-os
npm install
npm run setupThe setup assistant asks for your dashboard name, timezone, currency, starter sources, theme, and optional encrypted snapshot storage. It writes config/instance.local.json, which is ignored by Git and uses private file permissions.
Good starter choices:
| Question | Recommended first answer |
|---|---|
| Source pack | everyday |
| Palette | sage |
| Font | system |
| Headers | plain |
| Encryption | no for the synthetic tutorial, decide before real snapshots |
Rerun the wizard later with npm run setup -- --force.
npm run tutorialThe tutorial uses a credential-free mock LLM. It deliberately produces an invalid bundle once, receives safe validation feedback, retries, creates six synthetic snapshots atomically, and opens the local dashboard.
Nothing personal is written. If this screen opens, the complete local ingestion and rendering loop works.
Create a new private GitHub repository, for example YOUR_GITHUB_USERNAME/zaati-data. Do not fork the public code repository for this.
The LLM workflow will maintain this shape:
data/
snapshots/
<domain>/
<source>/
<YYYY>/<MM>/<YYYY-MM-DD>.json
Your code fork can stay public. Your data repository must stay private. See Private data repository for permissions, encryption, retention, and same-day reruns.
There is no required .env file for the local demo. .env.example is a reference for optional deployment configuration.
Keep values in the system that needs them:
| Value | Where it belongs | Commit it? |
|---|---|---|
| Dashboard name, timezone, theme | Ignored config/instance.local.json |
No |
| Generated LLM task prompt | Ignored .zaati/generated-prompts/ |
No |
| GitHub and source access | Your LLM provider's connection settings | No |
| Hostname and Worker name | GitHub production environment variables |
No |
| Cloudflare and data repository tokens | GitHub production environment secrets |
No |
| Optional snapshot key | Protected deployment secret or ignored local key file | No |
Never paste tokens into a generated prompt. Prefer provider-managed connections and narrow repository permissions.
Generate a copy-ready task prompt:
npm run prompt:createFor a useful first daily task, choose:
agenda:primaryinbox:attentionwork:focusoverview:daily, after its dependencies
Prompt Studio asks what each source should contain, which tools it may use, and which presentation blocks would help. It also asks for:
- your public Zaati OS code fork
- your private data repository
- provider and timezone
- schedule in plain language
- direct commit or pull request publication
It creates .zaati/generated-prompts/<task>.scheduled-task.md with the current schemas, privacy limits, retry protocol, deterministic paths, and atomic publication rules.
In ChatGPT, Claude, Gemini, n8n, or another supported environment:
- Connect GitHub and grant access to the private data repository.
- Connect only the source tools selected in Prompt Studio, for example calendar or email.
- Create a task, automation, or reusable workflow.
- Paste the complete generated scheduled-task prompt.
- Review the requested repositories, sources, paths, and schedule.
- Run it manually once before enabling recurrence.
- Confirm that all selected snapshots arrive in one commit or pull request.
The provider must read the current default branch contracts on every run. A copied prompt alone is not permanent authority to ignore newer schemas.
Check the private repository, not the public fork. A successful run should:
- write only registered dated snapshot paths
- update all selected sources together
- contain no credentials, raw provider exports, or unnecessary personal content
- preserve missing values, uncertainty, provenance, and warnings
- leave no partial commit if one snapshot fails
For safer review, keep pull-request publication until the workflow is stable.
If your LLM is exposed as a command that prints the exact JSON bundle:
your-llm-command | npm run snapshot:ingest -- --output-dir data/snapshotsKeep the real files under ignored data/snapshots/, or point ZAATI_DATA_DIR to a private local checkout, then run:
npm run data:validate
npm run devThe browser receives the facts required to render the dashboard. Treat the local session and every production hostname as private.
The safe order matters: deploy synthetic data, protect the hostname, verify Access from outside your session, then connect private snapshots.
In your code fork, create an environment named production.
Add these environment variables:
| Variable | Purpose |
|---|---|
ZAATI_WORKER_NAME |
Cloudflare Worker name |
ZAATI_HOSTNAME |
Exact custom hostname |
ZAATI_ACCESS_VERIFIED |
Set to true only after verification |
ZAATI_DATA_REPOSITORY |
Optional private repository, owner/name |
ZAATI_DATA_REF |
Private data branch, normally main |
ZAATI_AUTO_DEPLOY |
Enable only after a manual deployment passes |
Add these environment secrets:
| Secret | Purpose |
|---|---|
CLOUDFLARE_ACCOUNT_ID |
Target Cloudflare account |
CLOUDFLARE_API_TOKEN |
Scoped Workers edit token |
ZAATI_DATA_REPOSITORY_TOKEN |
Read-only access to one private data repository |
ZAATI_INSTANCE_CONFIG_JSON |
Optional complete instance configuration |
ZAATI_SNAPSHOT_KEY |
Optional key for encrypted snapshot storage |
Leave ZAATI_DATA_REPOSITORY unset. Run the Deploy private dashboard GitHub Actions workflow manually.
Create a Cloudflare Access self-hosted application for the exact hostname. Use exact email addresses or a constrained identity group, then test both an authorized browser and an incognito browser.
npm run access:verify -- life.example.comThe command must detect an unauthenticated Access challenge or denial.
Set the private data repository variable and its read-only token, set ZAATI_ACCESS_VERIFIED=true, then run the deployment workflow again. Only enable ZAATI_AUTO_DEPLOY=true after this manual run passes.
Read Private Cloudflare deployment for token scopes, Access policy guidance, encryption, caching, and rollback.
- The code fork contains no real snapshots or local instance file.
- The data repository is private.
- The LLM has only the GitHub and source access it needs.
- One manual bundle run succeeded before scheduling.
- The dashboard shows freshness, provenance, and honest missing states.
- Cloudflare Access challenges an incognito visitor.
-
npm run access:verify -- <hostname>passes. - Private snapshots were connected only after Access verification.
-
npm run checkpasses before application changes are merged.
- Prompt Studio, tune or automate prompt generation
- One-task daily bundle, refresh several domains in one run
- Add a domain, teach Zaati OS a new source
- Encrypted snapshots, protect repository copies at rest
- Theme Studio, personalize the interface
- Troubleshooting, diagnose common setup and deployment issues





