← Files Catalyst by ZohoARCHIVED FILE

skills/catalyst-by-zoho/references/project-and-cli.md

19.9 KB · Oct 5, 2026 · 18:05 UTC

↓ Download file

# Project Structure & CLI Reference

> **⚠️ PRE-FLIGHT CHECK:** Before creating any project files, confirm that `.catalystrc` and `catalyst.json` already exist in the project directory. If they don't, STOP — do not create files, do not scaffold. Tell the user to run `catalyst init` in their terminal first. `catalyst.json`, `.catalystrc`, and `functions/` are auto-generated by the CLI and cannot be created manually. See the Pre-flight Gate in SKILL.md.

## Table of Contents
1. [Project Directory Structure](#project-directory-structure)
2. [catalyst.json Configuration](#catalystjson)
3. [.catalystrc — Project Identity File](#catalystrc--project-identity-file)
4. [catalyst-config.json for Functions](#catalyst-configjson-for-functions)
5. [catalyst-config.json for Client](#catalyst-configjson-for-client)
6. [CLI Installation & Login](#cli-installation--login)
7. [CLI Commands Reference](#cli-commands-reference)
8. [Local Testing](#local-testing)
9. [Deployment](#deployment)
10. [Environments](#environments)

---

## Project Directory Structure

When `catalyst init` is run, a standard project layout is created. Claude must always produce code that
matches this structure exactly, or deployment will fail.

```
my-catalyst-project/              # Project root (home directory)
├── catalyst.json                 # Auto-generated project config — NEVER create manually
├── .catalystrc                   # Auto-generated project identity — NEVER create manually
├── functions/                    # All server-side functions
│   ├── function_name_1/          # Each function is its own directory
│   │   ├── index.js              # Entry point (Node.js)
│   │   ├── catalyst-config.json  # Function-specific config (deployment/execution keys)
│   │   ├── package.json          # NPM dependencies
│   │   └── node_modules/         # Dependencies (auto-installed)
│   └── function_name_2/
│       ├── main.py               # Entry point (Python)
│       ├── catalyst-config.json
│       └── requirements.txt
├── my-slate-app/                 # Slate frontend app (PREFERRED for new projects)
│   ├── app/
│   │   ├── index.html            # Entry HTML file
│   │   ├── css/
│   │   └── js/
│   └── catalyst-config.json      # Slate app config
├── client/                       # ⚠️ LEGACY — Web Client Hosting (deprecated, use Slate instead)
│   ├── index.html
│   └── catalyst-config.json
└── appsail/                      # AppSail services (optional)
    ├── app.js                    # Express/Hapi/Koa etc.
    ├── catalyst-config.json
    └── package.json
```

Key rules:
- The `functions/` directory name is fixed and cannot be renamed
- Each function must be in its own subdirectory under `functions/`
- Each function directory must contain its own `catalyst-config.json`
- **For frontends, always use Slate** — select **Slate** during `catalyst init` (it's a component option alongside Functions, Client, AppSail). Do NOT select "Client" — it is legacy and being deprecated. Use `catalyst slate:create` only to add additional Slate apps later.
- `catalyst.json` and `.catalystrc` at the project root are auto-generated — **NEVER create them manually**
- The entire project structure (`functions/`, etc.) is created by `catalyst init` — do not create directories manually

---

## catalyst.json

`catalyst.json` at the project root holds **deployment configuration** — which functions, AppSail
services, and Slate apps to deploy. It is created and updated by the CLI; do not create it manually.

```json
{
  "functions": {
    "targets": ["myFunction1", "myFunction2"],
    "ignore": [],
    "source": "functions"
  },
  "appsail": {
    "targets": ["my-appsail-service"],
    "source": "appsail"
  },
  "slate": [
    { "name": "my-frontend", "source": "/absolute/path/to/client" }
  ]
}
```

Key rules:
- The `functions` block **must** include `targets`, `ignore`, and `source` — omitting any field
  causes the CLI error `"targets was found to be empty"`.
- Slate `source` **must be an absolute path**. A relative path causes:
  `"You are not in a catalyst app directory"`.
- `catalyst.json` is for deployment configuration only. Project identity (project ID, env ID,
  timezone) lives in `.catalystrc` — see the section below.

---

## .catalystrc — Project Identity File

Created automatically by `catalyst init` at the project root. Contains the actual project metadata
required for `catalyst deploy` and `catalyst push` to work.

```json
{
  "project_id": "4074000000163001",
  "project_domain": "myapp-60019947973.development",
  "env_id": "60019947973",
  "timezone": "Asia/Kolkata"
}
```

Key points:
- Created automatically by `catalyst init` — do not create manually.
- Contains `project_id`, `env_id`, `project_domain`, and `timezone`.
- If this file is missing or deleted, `catalyst deploy` will fail.
- Do not confuse with `catalyst.json` which holds deployment targets, not project identity.

---

## catalyst-config.json for Functions

Every function directory must contain this file. It tells Catalyst how to deploy and execute the function.

⚠️ **Structure:** The config uses two top-level keys: `deployment` (name, type, stack) and `execution` (entry point). Do NOT use a `function` key — it does not exist and will cause `catalyst deploy` to crash with a cryptic `TypeError`.

⚠️ **Entry point key:** The entry point is specified as `"main"` inside the `execution` block — NOT `"entry_point"`.

⚠️ **First deploy prerequisite:** Having a directory + `catalyst-config.json` is NOT enough for the first deploy. Run `catalyst functions:add` from the project root first (interactive — enter name, type, stack when prompted). This registers the function in `catalyst.json`. Only then will `catalyst deploy --only functions` work. Subsequent deploys do not need this step again.

### Node.js Advanced I/O Function:
```json
{
  "deployment": {
    "name": "my_advanced_io_function",
    "type": "advancedio",
    "stack": "node20",
    "env_variables": {}
  },
  "execution": {
    "main": "index.js"
  }
}
```

### Node.js Basic I/O Function:
```json
{
  "deployment": {
    "name": "my_basic_io_function",
    "type": "basicio",
    "stack": "node20",
    "env_variables": {}
  },
  "execution": {
    "main": "index.js"
  }
}
```

### Event Function:
```json
{
  "deployment": {
    "name": "my_event_function",
    "type": "event",
    "stack": "node20",
    "env_variables": {}
  },
  "execution": {
    "main": "index.js"
  }
}
```

### Cron Function:
```json
{
  "deployment": {
    "name": "my_cron_function",
    "type": "cron",
    "stack": "node20",
    "env_variables": {}
  },
  "execution": {
    "main": "index.js"
  }
}
```

### Job Function:
```json
{
  "deployment": {
    "name": "my_job_function",
    "type": "job",
    "stack": "node20",
    "env_variables": {}
  },
  "execution": {
    "main": "index.js"
  }
}
```

### Python Function:
```json
{
  "deployment": {
    "name": "my_python_function",
    "type": "basicio",
    "stack": "python39",
    "env_variables": {}
  },
  "execution": {
    "main": "main.py"
  }
}
```

### Java Function:
```json
{
  "deployment": {
    "name": "my_java_function",
    "type": "basicio",
    "stack": "java17",
    "env_variables": {}
  },
  "execution": {
    "main": "com.example.Main"
  }
}
```

**Supported stacks:**
- Node.js: `node20` *(recommended — actively supported)*, `node14`, `node16`, `node18` *(legacy — no upstream security patches)*
- Java: `java8`, `java11`, `java17`
- Python: `python39`

**Memory options:** 128, 256, 384, 512, 640, 768, 896, 1024 (in MB) — configured in the `deployment` block. (Applies to Functions only; AppSail memory is configured in the console: 256–2048 MB.)

---

## catalyst-config.json for Client

```json
{
  "name": "my_web_client"
}
```

---

## CLI Installation & Login

```bash
# Install CLI globally
npm install -g zcatalyst-cli

# Verify installation
catalyst --version

# Login to Zoho account (opens browser for OAuth)
catalyst login

# Check logged-in user
catalyst whoami

# Logout
catalyst logout
```

Prerequisites: Node.js v20 (LTS) and NPM.

---

## CLI Commands Reference

### 🚫 Interactive commands — MUST be run by the user manually

> **The following commands are fully interactive** — they use arrow-key selection menus, multi-step
> prompts, and TTY input that CANNOT be driven programmatically by an LLM or script. If you attempt
> to run these in a non-interactive terminal, they will either hang, select wrong defaults, or fail silently.
>
> **NEVER run these commands yourself. Always instruct the user to run them in their own terminal:**
>
> | Command | What it prompts for |
> |---------|-------------------|
> | `catalyst login` | Opens browser for Zoho OAuth — requires user interaction |
> | `catalyst init` | Project selection (arrow keys), component selection (checkboxes), function config |
> | `catalyst functions:add` | Function name, type (arrow keys), stack (arrow keys) |
> | `catalyst functions:delete` | Function selection (arrow keys), confirmation |
> | `catalyst slate:create` | Framework selection (arrow keys), app name, build config — use this to add Slate after `catalyst init` |
>
> **After the user completes these steps**, you can safely run non-interactive commands like
> `catalyst serve`, `catalyst deploy`, `npm install`, etc.

### What each interactive command asks (so you can guide the user)

**`catalyst init`** — Full project initialization. Prompts in order:
1. **Select a default Catalyst portal** — arrow keys to pick from user's Zoho portals/orgs
2. **Select a default Catalyst project** — arrow keys to pick an existing Catalyst project, or "Create a new project" (redirects to console)
3. **Which features to setup?** — checkboxes (Space to toggle, Enter to confirm): **Functions**, **Client**, **AppSail**, **Slate**. Select **Functions + Slate** for most apps. Do NOT select "Client" — it is legacy and being deprecated.

> ⚠️ **Slate prerequisite:** Before selecting Slate here, the user must first enable Slate in the Catalyst console: go to **console.catalyst.zoho.com → project → Slate** (left sidebar) → click **"Start Exploring"**. This is a one-time activation per project. Without it, Slate init will fail.
4. If **Functions** selected — npm package setup for the first function:
   - `package name:` — text input (e.g., `docvault_api`)
   - `entry point:` — text input (default: `index.js`)
   - `author:` — text input (default: logged-in Zoho email)
   - `Do you wish to install all dependencies now?` — Yes/No (recommend Yes)
5. If **Slate** selected — Slate Setup:
   - `Select a framework to start with:` — arrow keys (React + Vite, Next.js, Angular, Vue, Svelte, Astro, SolidJS, etc.)
   - `Please provide the name for your app:` — text input (e.g., `docvault-ui`)
   - Auto-detected config shown: Install Command, Build Command, Build Path, Deployment Name
   - `Do you want to modify these default configurations?` — Yes/No (recommend No for defaults)
   - `Please provide your Development Command:` — text input (default: `npm run dev -- --port $ZC_SLATE_PORT`)

After init completes, `.catalystrc` and `catalyst.json` are created automatically.

**`catalyst functions:add`** — Add a function to an initialized project. Prompts:
1. **Function name** — text input
2. **Function type** — arrow keys: Basic I/O, Advanced I/O, Event, Cron, Job
3. **Runtime stack** — arrow keys: node20, node18, node16, java17, java11, python39

**`catalyst slate:create`** — Add an **additional** Slate app to a project that already has Slate initialized. Prompts:
1. **Framework** — arrow keys: react-vite, nextjs, angular, vue, svelte, astro, solidjs, vite, etc.
2. **App name** — text input
3. **Confirm default config** — install command (npm install), build command (npm run build), build path. Enter N to accept defaults or Y to customize.

### Project Management
```bash
catalyst init                        # ⚠️ INTERACTIVE — user must run manually
catalyst init --project "MyProject"  # ⚠️ INTERACTIVE — user must run manually
catalyst projects:list               # ✅ Non-interactive — safe to run
catalyst use                         # ⚠️ INTERACTIVE — project selection menu
catalyst reset                       # ✅ Non-interactive — safe to run
```

### Function Management
```bash
catalyst functions:setup             # ⚠️ INTERACTIVE — user must run manually
catalyst functions:add               # ⚠️ INTERACTIVE — user must run manually
catalyst functions:shell             # ✅ Non-interactive — safe to run
catalyst functions:delete            # ⚠️ INTERACTIVE — user must run manually
catalyst functions:configure-memory  # ⚠️ INTERACTIVE — user must run manually
```

### Client Management (LEGACY — use Slate instead for new projects)
```bash
catalyst client:setup                # ⚠️ LEGACY — sets up deprecated Web Client Hosting. Use Slate instead.
catalyst client:delete               # Delete legacy web client
```

### AppSail Management
```bash
catalyst appsail:add                 # Add AppSail service
```

### Data Store
```bash
catalyst data:import                 # Import data into Data Store
catalyst data:export                 # Export data from Data Store
catalyst data:status                 # Check import/export status
```

### Slate
```bash
catalyst slate:create                # ⚠️ INTERACTIVE — Add an additional Slate app (framework + name + build config)
catalyst slate:link                  # ⚠️ INTERACTIVE — Link existing local dir to Slate service
catalyst slate:unlink                # Unlink a Slate app
catalyst serve --only slate          # Serve Slate app locally
catalyst deploy slate                # Deploy all Slate apps to Development
catalyst deploy slate -m "message"   # Deploy with a deployment message
catalyst deploy --only slate:appname # Deploy a specific Slate app
catalyst deploy slate --production   # Deploy to Production
```

### Pull & Export/Import
```bash
catalyst pull                        # Pull resources from remote
catalyst export                      # Export project as ZIP
catalyst import                      # Import project from ZIP
```

---

## Local Testing

```bash
# Serve all resources locally (functions + client)
catalyst serve

# Serve only functions
catalyst serve --only functions

# Serve only client
catalyst serve --only client

# Specify custom port
catalyst serve --port 3000

# Launch function shell for testing
catalyst functions:shell
```

When serving locally:
- Functions are available at `http://localhost:<port>/server/<function_name>/execute`
- Client is available at `http://localhost:<port>/app/index.html`
- The serve command connects to the remote Catalyst console for Data Store, File Store, etc.

### What works locally vs what doesn't

| Feature | Works with `catalyst serve`? | Notes |
|---------|------------------------------|-------|
| Basic I/O functions | Yes | Full local execution |
| Advanced I/O functions | Yes | Full local execution |
| Event functions | No | Triggered by platform events only |
| Cron functions | No | Triggered by scheduler only |
| Job functions | No | Triggered by Job Scheduling only |
| Data Store / ZCQL | Yes | Connects to remote Development environment |
| Cache | Yes | Connects to remote Development environment |
| Stratus | Yes | Connects to remote Development environment |
| Web Client | Yes | Served on localhost |
| AppSail | Partial | Use `node server.js` locally; no Catalyst auth layer |

For functions that can't be tested locally, deploy to Development and test there.
Use Tunneling (`catalyst tunnel`) to expose your local server to Catalyst for
webhook/event testing.

---

## Deployment

```bash
# Deploy all resources (functions + client + appsail)
catalyst deploy

# Deploy only functions — correct flag: --only functions (space, not --only-functions)
catalyst deploy --only functions

# Deploy only a specific function
catalyst deploy --only functions:my_function

# Deploy only client
catalyst deploy --only client

# Deploy only AppSail
catalyst deploy --only appsail

# Deploy to Slate (replace 'appname' with your Slate app name)
catalyst deploy --only slate:appname
```

⚠️ **Flag syntax (CLI v1.23.0+):** Use `--only <target>` with a space. The hyphenated `--only-functions` / `--only-client` forms do NOT exist and will throw "unknown option".

### Deployment package limits

| Component | Max package size | What's counted |
|-----------|-----------------|----------------|
| Function (zip) | 100 MB | Code + node_modules + assets |
| AppSail | 250 MB | Full build directory including node_modules |
| Slate (frontend) | 400 MB | Frontend build output (HTML/CSS/JS/assets) |

**To reduce function package size:**
- Use `npm install --production` to exclude devDependencies
- Add unnecessary files to `.catalystignore`
- Consider splitting large functions into smaller, focused ones
- Remove test files, documentation, and examples from node_modules

### Rolling back a deployment

Catalyst does not have a one-click rollback. To revert a bad deployment:

1. **From git:** Check out the previous working commit and redeploy:
```bash
   git checkout <previous-commit>
   catalyst deploy
```
2. **From console:** For AppSail, the console shows deployment history — you can
   redeploy a previous revision
3. **Blue/green via API Gateway:** Route traffic between two function versions
   by updating API Gateway routes

**Best practice:** Tag your git commits before each deployment so you can quickly
identify which version to roll back to.

### Slate — Manual Setup (without interactive slate:link)

`catalyst slate:link` is interactive-only and cannot be scripted or piped. To set up Slate
in automated or non-interactive environments:

**Step 1** — Create `.catalyst/slate-config.toml` inside the client directory:

```toml
framework = "static"
deployment_name = "default"
```

**Step 2** — Add the slate entry to `catalyst.json` (absolute source path required):

```json
"slate": [
  { "name": "my-frontend", "source": "/absolute/path/to/client" }
]
```

**Step 3** — Deploy:

```bash
catalyst deploy slate -m "initial deploy"
```

Slate URL format: `https://<project-domain>.onslate.in`
Example: `https://myapp-60019947973.development.onslate.in`

---

## Environments

Catalyst has two environments:

1. **Development (sandbox)**: Where CLI deploys go. Free to use within limits. Used for testing.
2. **Production**: Requires billing setup. Serves live traffic. Deployed separately from the console.

To deploy to production:
1. Set up billing in the Catalyst console (Settings → Billing)
2. Deploy to production from the console (not from CLI)
3. Production gets its own URL and domain mapping

The CLI always works with the Development environment. Production deployment is done through the web console.

### Dev-to-Prod promotion checklist

1. **Verify in Development** — all functions, AppSail services, and frontend working correctly
2. **Set up billing** — Catalyst Console → Settings → Billing (required for Production)
3. **Deploy to Production** — Console → Deploy → select Production environment
4. **Update environment variables** — Production uses separate env vars. Set them in the
   Console for each function and AppSail service
5. **Swap ZAIDs** — Production has different ZAIDs than Development. Update any hardcoded
   ZAID references in your code or use environment variables instead
6. **Reconfigure social login** — OAuth redirect URLs must point to the Production domain
7. **Map custom domain** — Console → Domain Mapping → add your production domain
8. **Test the full flow** — auth, data, file uploads, email — all on the Production URL
9. **Monitor** — enable APM and Application Alerts for Production

**Common pitfall:** Using Development ZAIDs in Production is the #1 cause of auth failures
after deployment. Always use environment variables for ZAIDs, never hardcode them.

SHA-256: e132e42f1b72f55b48e8e9a51a56e8a3ce9e2ca15d9973746f012c4e3eca45c1