For Developers

How to clone, run, and extend HotCRM as an ObjectStack marketplace app.

For Developers

This page is for engineers working with the HotCRM source repo.

Prerequisites

  • Node.js 20+
  • pnpm 10+
  • A clone of objectstack-ai/hotcrm

Run locally

git clone https://github.com/objectstack-ai/hotcrm.git
cd hotcrm
pnpm install
pnpm dev

Open http://localhost:4001. The app boots with seed data on first start.

Repository shape

HotCRM builds one ObjectStack artifact that carries two packages (ADR-0130): app.objectstack.hotcrm, the type: app package in src/sales/, and the service module app.objectstack.hotcrm.service in src/service/. Each has an index.ts with its own defineStack(); objectstack.composition.ts builds the two stacks and objectstack.config.ts composes them into the artifact. A directory under src/ is a package of the layout: src/revenue/ and src/marketing/ are still registered by the app package until each is packaged on its own. A file may import from its own directory or from src/sales/ — never sideways between modules.

hotcrm/
├── objectstack.config.ts
├── objectstack.composition.ts
├── src/
│   ├── sales/          # the `type: app` package — account, contact, lead, opportunity, forecast, task, event
│   ├── service/        # the service module — case, knowledge_article, article_feedback
│   ├── revenue/        # registered by the app package for now — product, opportunity_line_item, quote, quote_line_item, contract
│   ├── marketing/      # registered by the app package for now — campaign, campaign_member
│   └── docs/           # package docs, shipped inside the built artifact
├── apps/docs/          # Fumadocs app
└── content/docs/       # documentation content

Each package holds the metadata-type subdirectories it uses, and the same suffix protocol applies inside every one of them:

src/sales/
├── objects/            # *.object.ts schemas, and the *.hook.ts beside each one
├── actions/            # UI actions and executable action bodies
├── flows/              # automation flows
├── skills/             # AI skills
├── apps/, views/, pages/
├── dashboards/, reports/, datasets/
├── mappings/           # import column-to-field projections
├── profiles/, sharing/
├── translations/
├── data/               # seed data
└── interfaces/         # shared types (an empty barrel today)

HotCRM authors skills, not agents: the two app-owned copilots and the directory that held them were retired, and AI capability now comes from the platform assistant every ObjectStack environment provides. See AI Skills.

File suffix protocol

SuffixDefines
*.object.tsData model
*.hook.tsServer-side lifecycle logic
*.actions.tsUI actions and AI-callable action bodies
*.flow.tsAutomation
*.skill.tsAI skill
*.page.tsUI page
*.view.tsList or kanban view
*.dashboard.tsDashboard
*.report.tsReport
*.sharing.tsSharing rule
*.profile.tsPermission profile

Common tasks

Add or change an object

Edit or add a file under src/*/objects/, then export it from src/*/objects/index.ts.

import { ObjectSchema, Field } from '@objectstack/spec/data';

export const Warranty = ObjectSchema.create({
  name: 'crm_warranty',
  label: 'Warranty',
  fields: {
    name: Field.text({ label: 'Warranty Name', required: true }),
    crm_account: Field.lookup('crm_account', { label: 'Account' }),
  },
});

Add an AI skill

Create src/*/skills/<name>.skill.ts and export it from src/*/skills/index.ts. Exporting it from that barrel is the whole wiring step — the skill attaches to the platform assistant (ask), and this app defines no agent of its own.

Add UI metadata

Use src/*/views/ for list and kanban views, src/*/pages/ for record pages, and src/*/actions/ for buttons and modal actions.

Verify changes

pnpm validate
pnpm typecheck
pnpm build
pnpm test

The shortcut is:

pnpm verify

Where to go next

On this page