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 devOpen 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 contentEach 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
| Suffix | Defines |
|---|---|
*.object.ts | Data model |
*.hook.ts | Server-side lifecycle logic |
*.actions.ts | UI actions and AI-callable action bodies |
*.flow.ts | Automation |
*.skill.ts | AI skill |
*.page.ts | UI page |
*.view.ts | List or kanban view |
*.dashboard.ts | Dashboard |
*.report.ts | Report |
*.sharing.ts | Sharing rule |
*.profile.ts | Permission 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 testThe shortcut is:
pnpm verify