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? Run
npm run devbefore setup. The public synthetic demo includes an optional guided tour, Component Lab, and example prompt guides without credentials, provider accounts,.envfiles, or personal data.
| Stage | What you do | What Zaati OS creates |
|---|---|---|
| 1. Test drive | Explore the demo, tour, sources, and blocks | A local dashboard with public synthetic data |
| 2. Go private | Run setup, then verify the ingestion tutorial | An ignored workspace without demo-only UI |
| 3. Connect your LLM | Generate and paste one private task prompt | Validated snapshots in a private repository |
| 4. 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
The contract is provider-neutral, but Zaati OS does not bundle source connectors. ChatGPT scheduled tasks are the target first hosted workflow, but v0.1.1 does not claim a hosted provider as end-to-end certified. Other capable LLMs, local models, n8n, cron, and custom commands can use the same contract when they already have the required approved tools.
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 devThe first visit offers a five-step tour. You can skip it immediately or reopen it from Start here. It explains registered sources, the safe JSON-to-component contract, the example prompt guides, and the private handoff.
When you are ready, stop the development server and run:
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. This local configuration switches the workspace to private mode, so synthetic example pages, Component Lab, copy-prompt guides, and the automatic tour all disappear together.
Good starter choices:
| Question | Recommended first answer |
|---|---|
| Source pack | daily |
| 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. The resulting pages are labeled Synthetic test data, but demo-only navigation and guides stay disabled. 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. Install its independent validation gate before connecting an LLM:
npm run data-repository:init -- --target ../zaati-data --code-repository YOUR_GITHUB_USERNAME/zaati-os --code-ref FULL_COMMIT_SHACommit the generated files and require Validate Zaati snapshots in branch protection. 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 | Trusted local or protected CI ingestion and deployment | 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 for a provider, a starter dashboard, the two repositories, and a schedule. It chooses registered dependencies and safe view types for the normal path.
It creates a short .permissions.md receipt for human review plus .scheduled-task.md with current contract locations, privacy limits, retries, deterministic paths, and pull-request publication rules.
In ChatGPT, Claude, Gemini, n8n, or another supported environment:
- Connect GitHub and grant permission to create branches and pull requests only in 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 generated permission receipt, repositories, sources, paths, and schedule.
- Run it manually once before enabling recurrence.
- Confirm that all selected snapshots arrive in one pull request and the independent check passes.
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 mergeable pull request if one snapshot fails
- stop without merging its own pull request
Pull-request publication and the independent validator are required for scheduled Git workflows.
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 for HTML, dashboard data, and an asset path.
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 and its independent validator is required.
- 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





