@fleox-agent-crm/agentcrm 0.0.0-stage → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/LICENSE +143 -0
  2. package/README.md +223 -2
  3. package/changelog.json +57 -0
  4. package/dist/admin/admin-files.json +26 -0
  5. package/dist/admin/assets/chartsImpl-CE2akJat.js +91 -0
  6. package/dist/admin/assets/firebase-BHSUggRo.js +2 -0
  7. package/dist/admin/assets/gitJson-BulGh2KV.js +3 -0
  8. package/dist/admin/assets/index-DidVVK7L.js +1181 -0
  9. package/dist/admin/assets/index-hMXwHSvN.css +1 -0
  10. package/dist/admin/assets/index.esm-BFc7vwnl.js +400 -0
  11. package/dist/admin/assets/index.esm-CtEQZRb1.js +1651 -0
  12. package/dist/admin/assets/index.esm-Dum0J07z.js +16 -0
  13. package/dist/admin/assets/index.esm2017-EOzKbpUS.js +390 -0
  14. package/dist/admin/assets/lucide-react.min-DEDlHCPj.js +6 -0
  15. package/dist/admin/assets/sdk-CnrLnlRo.js +1717 -0
  16. package/dist/admin/config.js +3 -0
  17. package/dist/admin/favicon.svg +1 -0
  18. package/dist/admin/index.html +139 -0
  19. package/dist/admin/runtime/agentcrm-runtime.js +104 -0
  20. package/dist/admin/runtime/lucide-react.js +791 -0
  21. package/dist/admin/runtime/react-dom-client.js +17 -0
  22. package/dist/admin/runtime/react-dom.js +20 -0
  23. package/dist/admin/runtime/react-i18next.js +19 -0
  24. package/dist/admin/runtime/react-jsx-runtime.js +17 -0
  25. package/dist/admin/runtime/react.js +22 -0
  26. package/dist/agent/agentcrm.mjs +3932 -0
  27. package/dist/agent/chunks/_commonjsHelpers-ClciMIcB.mjs +14 -0
  28. package/dist/agent/chunks/activities-Cj_SIOay.mjs +227 -0
  29. package/dist/agent/chunks/api-B6OqNVWp.mjs +97 -0
  30. package/dist/agent/chunks/appearance-BaShelzt.mjs +174 -0
  31. package/dist/agent/chunks/automations-BWrvLqP6.mjs +698 -0
  32. package/dist/agent/chunks/backup-ClSmxmFZ.mjs +103 -0
  33. package/dist/agent/chunks/batch-CVETiJj5.mjs +142 -0
  34. package/dist/agent/chunks/compact-CsFPaAAq.mjs +69 -0
  35. package/dist/agent/chunks/context-CxFfqS4D.mjs +65 -0
  36. package/dist/agent/chunks/core-Dy7vY9H6.mjs +255 -0
  37. package/dist/agent/chunks/dedupe-BepmsaHv.mjs +123 -0
  38. package/dist/agent/chunks/encoding-C9MzdP95.mjs +36 -0
  39. package/dist/agent/chunks/exportCsv-B5hRvkNm.mjs +95 -0
  40. package/dist/agent/chunks/extCheck--7lmVvl7.mjs +193 -0
  41. package/dist/agent/chunks/extPackage-BGl5Oqs8.mjs +115 -0
  42. package/dist/agent/chunks/extScaffold-DqxI7R1e.mjs +320 -0
  43. package/dist/agent/chunks/extensionActions-D2HtpQz4.mjs +48 -0
  44. package/dist/agent/chunks/extensions-BP1k60md.mjs +151 -0
  45. package/dist/agent/chunks/featureRegistry-C9nbVShp.mjs +149 -0
  46. package/dist/agent/chunks/fields-B0bitgmr.mjs +476 -0
  47. package/dist/agent/chunks/files-CjsPJSR6.mjs +158 -0
  48. package/dist/agent/chunks/files-q8Xu5bft.mjs +367 -0
  49. package/dist/agent/chunks/firebase-DxGVQV9E.mjs +454 -0
  50. package/dist/agent/chunks/firebaseRules-iori-s7U.mjs +221 -0
  51. package/dist/agent/chunks/forms-BKU5F9WF.mjs +847 -0
  52. package/dist/agent/chunks/gitJson-fjr8mcHe.mjs +528 -0
  53. package/dist/agent/chunks/hosting-Bme7LxPc.mjs +144 -0
  54. package/dist/agent/chunks/http-Bk9ICb7I.mjs +127 -0
  55. package/dist/agent/chunks/ids-CvnmrMJX.mjs +59 -0
  56. package/dist/agent/chunks/ids-u-noYcy5.mjs +14 -0
  57. package/dist/agent/chunks/importCsv-DmE_sBch.mjs +334 -0
  58. package/dist/agent/chunks/index-B-4W0-P4.mjs +535 -0
  59. package/dist/agent/chunks/index-BM8qeGOb.mjs +2489 -0
  60. package/dist/agent/chunks/index-Bnmav-Oh.mjs +311 -0
  61. package/dist/agent/chunks/index-CRkw3_iF.mjs +147 -0
  62. package/dist/agent/chunks/index-CWrrF1wl.mjs +111 -0
  63. package/dist/agent/chunks/index-DUSdTBkz.mjs +2988 -0
  64. package/dist/agent/chunks/index-RCmo-uld.mjs +26 -0
  65. package/dist/agent/chunks/index-w03ReRs4.mjs +9780 -0
  66. package/dist/agent/chunks/install-CpHoUFtL.mjs +188 -0
  67. package/dist/agent/chunks/jsx-runtime-Ca2uwGDr.mjs +76 -0
  68. package/dist/agent/chunks/loader-C9nm3iwx.mjs +184 -0
  69. package/dist/agent/chunks/lucide-react.min-Bt3gtepY.mjs +64 -0
  70. package/dist/agent/chunks/memory-WNR3VHUJ.mjs +56 -0
  71. package/dist/agent/chunks/migrate-CsClnnN8.mjs +182 -0
  72. package/dist/agent/chunks/modules-CqdVQVJb.mjs +177 -0
  73. package/dist/agent/chunks/nodeImport-BPCt5uMu.mjs +38 -0
  74. package/dist/agent/chunks/package-DWbn3t2R.mjs +194 -0
  75. package/dist/agent/chunks/papaparse-DjBYnQM2.mjs +1285 -0
  76. package/dist/agent/chunks/pipelines-DCdRBNBV.mjs +234 -0
  77. package/dist/agent/chunks/plan-C0TBrU92.mjs +254 -0
  78. package/dist/agent/chunks/pluginRegistry-DyHtlkcr.mjs +83 -0
  79. package/dist/agent/chunks/query-C5nJB_3C.mjs +192 -0
  80. package/dist/agent/chunks/records-DoqiT9xR.mjs +2191 -0
  81. package/dist/agent/chunks/registry-Ceexawxl.mjs +182 -0
  82. package/dist/agent/chunks/registry-DijAKZ24.mjs +431 -0
  83. package/dist/agent/chunks/relations-B9TynBmA.mjs +191 -0
  84. package/dist/agent/chunks/reports-BB59N6ke.mjs +189 -0
  85. package/dist/agent/chunks/runtime-DHo7ZEEO.mjs +14852 -0
  86. package/dist/agent/chunks/runtimeConfig-CCOFg1RM.mjs +250 -0
  87. package/dist/agent/chunks/s3-Dz50-NuA.mjs +903 -0
  88. package/dist/agent/chunks/schema-7-4-qtSS.mjs +203 -0
  89. package/dist/agent/chunks/schema-DlHt2PxI.mjs +367 -0
  90. package/dist/agent/chunks/sdk-whvfg786.mjs +43644 -0
  91. package/dist/agent/chunks/seed-CugPGYZL.mjs +523 -0
  92. package/dist/agent/chunks/server-ISwlDRCN.mjs +242 -0
  93. package/dist/agent/chunks/settings-BtvR_jdm.mjs +76 -0
  94. package/dist/agent/chunks/standardObjects-CheqfDqa.mjs +243 -0
  95. package/dist/agent/chunks/stats-CfeJssSS.mjs +51 -0
  96. package/dist/agent/chunks/store-5gqRSKXg.mjs +122 -0
  97. package/dist/agent/chunks/themes-DPZFv3yc.mjs +43 -0
  98. package/dist/agent/chunks/tools-Bew8lxKx.mjs +844 -0
  99. package/dist/agent/chunks/types-BOy9PUl7.mjs +44 -0
  100. package/dist/agent/chunks/users-DI1BvS0f.mjs +107 -0
  101. package/dist/agent/chunks/utils-DmI8FtXP.mjs +83 -0
  102. package/dist/agent/chunks/views-fO_BM5U_.mjs +109 -0
  103. package/dist/version.json +7 -0
  104. package/package.json +97 -4
  105. package/plugin/.claude-plugin/plugin.json +17 -0
  106. package/plugin/skills/agentcrm-admin/SKILL.md +191 -0
  107. package/plugin/skills/agentcrm-admin/references/appearance.md +26 -0
  108. package/plugin/skills/agentcrm-admin/references/import.md +16 -0
  109. package/plugin/skills/agentcrm-admin/references/records.md +30 -0
  110. package/plugin/skills/agentcrm-admin/references/schema.md +59 -0
  111. package/plugin/skills/agentcrm-extensions/SKILL.md +93 -0
  112. package/plugin/skills/agentcrm-extensions/references/module-recipes.md +213 -0
  113. package/plugin/skills/agentcrm-extensions/references/runtime-api.md +41 -0
  114. package/plugin/skills/agentcrm-extensions/references/testing.md +76 -0
  115. package/plugin/skills/agentcrm-extensions/references/theme-recipes.md +65 -0
  116. package/plugin/skills/agentcrm-install/SKILL.md +116 -0
  117. package/plugin/skills/agentcrm-install/references/firebase.md +18 -0
  118. package/plugin/skills/agentcrm-install/references/github.md +20 -0
  119. package/plugin/skills/agentcrm-install/references/mcp.md +17 -0
  120. package/plugin/skills/agentcrm-install/references/plans.md +45 -0
  121. package/plugin/skills/agentcrm-install/references/s3.md +24 -0
  122. package/plugin/skills/agentcrm-manage/SKILL.md +108 -0
  123. package/plugin/skills/agentcrm-manage/references/cron.md +11 -0
  124. package/plugin/skills/agentcrm-manage/references/doctor.md +18 -0
  125. package/plugin/skills/agentcrm-sales/SKILL.md +92 -0
  126. package/plugin/skills/agentcrm-sales/references/enrichment.md +13 -0
  127. package/plugin/skills/agentcrm-sales/references/playbooks.md +29 -0
  128. package/plugin/skills/agentcrm-sales/references/weekly-report.md +27 -0
  129. package/types/agentcrm-runtime.d.ts +894 -0
@@ -0,0 +1,41 @@
1
+ # `@agent-crm/runtime` at a glance
2
+
3
+ The full reference with every signature is `docs/runtime-api-reference.md` in the AgentCRM repository; the authoritative types are the project's `types/agentcrm-runtime.d.ts` (read it when in doubt, it is self-contained). Extension API version: 1.0.0. Besides this module a bundle may import only `react`, `react/jsx-runtime`, `react-dom`, `react-dom/client`, `react-i18next`, `lucide-react`.
4
+
5
+ Hooks and components work only in React components the admin renders (pages, slots, settings pages). AI tools, automation actions and `register()` hooks also run in the CLI / MCP server (Node, no DOM): there, only use `ops.*` with the `ctx` argument.
6
+
7
+ ## Definitions
8
+
9
+ - `defineModule({ id, apiVersion, feature?, register?(api), aiTools?, automationActions?, settingsPage? })`
10
+ - `defineTheme({ id, apiVersion, name, description?, appearance, css? })`
11
+ - `apiVersion`, `minApiVersion`: what the running admin accepts.
12
+ - `feature`: `routes [{ path, element, roles? }]`, `navItems [{ id, label, icon, to, section: main|workspace|bottom, order?, roles? }]`, `i18n { en, fr }`, `slots { recordDetailTabs, recordDetailPanels, recordActions, dashboardWidgets, settingsSections, topBar, globalOverlays }`, `onStart?(env)`.
13
+ - `register(api)`: `api.addAction(hook, fn)`, `api.addFilter(hook, fn)`, `api.registerAiTool(tool)`, `api.registerAutomationAction(def)`, `api.onDispose(fn)`, `api.moduleId`. Removed automatically on disable / upgrade.
14
+
15
+ ## Engine: `ops`
16
+
17
+ Every op takes the context first: `useOps()` in components, `ctx` in tools / actions / hooks. Typed: `listRecords(ctx, objectId, { filters, sorts, search, limit })` → `{ items, total }`, `getRecord`, `createRecord(ctx, objectId, fields)`, `updateRecord(ctx, id, fields)`, `deleteRecord`, `listActivities(ctx, { target })`, `addNote(ctx, { object, id }, body, title?)`, `createTask(ctx, { title, dueAt?, assigneeId?, targets? })`, `completeTask`, `listPipelines`, `pipelineOfRecord`, `moveStage(ctx, recordId, stage)`, `forecast`, `listObjects`, `getSettings`, `listUsers`, `listModules`, `getModuleConfig(ctx, id)`, `setModuleConfig(ctx, id, value)`, `getAppearance`. Every other op of the engine (`createObject`, `createField`, `searchRecords`, `createAutomation`, `runReport`…) is there too, typed `unknown`: cast it to its signature.
18
+
19
+ Filters: `{ field, op, value }` with op `eq, neq, contains, notContains, empty, notEmpty, gt, gte, lt, lte, in, notIn, before, after, withinDays`. Sorts: `{ field, dir: "asc" | "desc" }`.
20
+
21
+ ## Data hooks (live)
22
+
23
+ `useCrm`, `useOps`, `useCan(action)`, `useCurrentUser`, `useCollection(name)`, `useObjects`, `useObject(id)`, `useRecords(objectId)`, `useRecord(id)`, `useActivities(recordId)`, `usePipelines(objectId)`, `useViews(objectId)`, `useUsers`, `useSettings`, `useModuleConfig(id)`, `useModuleEnabled(id)`, `useAppearance`.
24
+
25
+ Permissions for `useCan`: `records.read`, `records.write`, `records.delete`, `activities.write`, `schema.write`, `settings.write`, `users.write`, `automations.write`, `modules.write`, `appearance.write`, `extensions.write`…
26
+
27
+ ## Router
28
+
29
+ `useNavigate`, `useParams`, `useSearchParams`, `useLocation`, `Link`, `NavLink`, `paths` (`dashboard()`, `objectList(objectId, viewId?)`, `record(objectId, recordId)`, `tasks()`, `automations()`, `forms()`, `reports()`, `settings(section?)`), `recordHref(objectId, recordId)`.
30
+
31
+ ## Plugin registry
32
+
33
+ `addAction`, `removeAction`, `addFilter`, `removeFilter`, `doAction`, `applyFilters`, `registerAiTool`, `registerAutomationAction`. CRM actions: `record.created`, `record.updated`, `record.deleted`, `record.restored`, `stage.changed`, `activity.created`, `activity.updated`, `activity.completed` (handler: `(ctx, payload)`).
34
+
35
+ ## UI kit
36
+
37
+ `Button`, `IconButton`, `Input`, `Textarea`, `Select`, `Label`, `FormField`, `Checkbox`, `Switch`, `Modal`, `Drawer`, `Card`, `Badge`, `Avatar`, `Tabs`, `Tooltip`, `Spinner`, `EmptyState`, `PageHeader`, `Kbd`, `Dropdown`, `Table`, `THead`, `TBody`, `Tr`, `Th`, `Td`, `FieldValue`, `FieldInput`, `ObjectIcon`, `Markdown`, `confirmDialog`, `toast`, `cn`, `newId`. Tailwind classes of the admin work (`text-surface-500`, `bg-accent-500`, `dark:`…) and follow the workspace appearance.
38
+
39
+ ## i18n and formatters
40
+
41
+ `i18n`, `addBundles(ns, { en, fr })`, `activeLocale()`, `intlLocale()`; `formatFieldValue`, `formatCurrency(n, currency, locale, compact?)`, `formatNumber`, `formatDate`, `formatDateTime`, `formatRelative`, `recordLabel(object, record)`, `coerceFieldValue(field, raw)`, `isEmptyFieldValue`.
@@ -0,0 +1,76 @@
1
+ # Test, pack, install, upgrade, debug
2
+
3
+ ## The loop
4
+
5
+ ```bash
6
+ npm run typecheck # tsc against types/agentcrm-runtime.d.ts
7
+ npm run build # vite build → dist/bundle.js
8
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 ext check . --json # what the admin will see
9
+ ```
10
+
11
+ `ext check` reads `manifest.json` + `dist/bundle.js` (+ `src/style.css` for themes declaring it) from a project, `manifest.json` + `bundle.js` from an unpacked folder, or a ZIP. Then:
12
+
13
+ | Field | Meaning |
14
+ |---|---|
15
+ | `data.valid` | false = the admin would refuse or fail to load it (exit code 1). |
16
+ | `data.errors[]` | `{ code, message, hint }`: `manifest`, `incompatibleApi`, `imports` (a bare import the admin doesn't provide), `noDefaultExport`, `devJsx`, `tooLarge`, `missingStyle`, `notBuilt`, `load` (the bundle threw or its default export is wrong), `appearance` (theme values). |
17
+ | `data.warnings[]` | `i18n` (no French), `toolName`, `toolDescription`, `actionId`, `nav` (entry without a route), `empty`, `dependency`, `toolCall` (a tool failed when called with `{}` on demo data), `author`, `ignored`. |
18
+ | `data.registered` | routes, navItems, slots (ids per slot), settingsPage, i18n key counts, aiTools, automationActions, hooks. |
19
+ | `data.toolCalls` | each AI tool without required inputs, called once on a demo CRM (`--no-call` skips). |
20
+ | `data.theme` | a theme's resolved values and CSS size. |
21
+
22
+ The check runs the bundle in Node with the real loader and runtime, in a throw-away demo CRM (30 companies, 80 people, 40 deals): nothing reaches a real site. It does not render React components; open the admin for that (below).
23
+
24
+ ## Pack and install
25
+
26
+ ```bash
27
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 ext pack . --json # → <id>-<version>.zip
28
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 ext install acme-quotes-0.1.0.zip --site acme --json
29
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 ext install acme-quotes-0.1.0.zip --site acme --yes --json
30
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 ext list --site acme --json
31
+ ```
32
+
33
+ - The plan (`needsConfirmation: true`) shows `id`, `kind`, `name`, `version`, `author`, `mode` (`install` / `upgrade` with `from`), `dependsOn`, `size`, `warnings` and the trust warning. **Show it to the user and ask before `--yes`.**
34
+ - After `--yes`, `data.load.status` is `loaded` when the bundle ran in the CLI session. `error` comes with `data.load.error`.
35
+ - A module whose dependencies are off is installed disabled (see `warnings`); enable them first or `ext enable <id> --cascade`.
36
+ - `ext install <dir>` works on a built project too (no ZIP needed).
37
+ - The admin alternative: Settings, Modules, Installed extensions, drop the ZIP, review, tick "I trust the author".
38
+
39
+ ## Upgrade
40
+
41
+ Bump `version` in `manifest.json`, build, check, install again: `mode: "upgrade"`, `from: "<old>"`. The enabled state and the module config are kept; open admins reload the new bundle live.
42
+
43
+ ## Use it
44
+
45
+ ```bash
46
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 tools list --site acme --json # its AI tools (source: "extension")
47
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 tools call acme_quotes_list --site acme --input '{}' --json
48
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 modules list --site acme --json # appears as a module (source: "extension")
49
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 automations run --site acme --json # its automation actions run here too
50
+ ```
51
+
52
+ To see the UI, open the CRM's admin (its hosted URL, see `site show`, or `npx -y @fleox-agent-crm/agentcrm@0.3.0 serve` for a local copy), and check the page, the tabs and widgets in light and dark mode and in French (language switcher in the user menu or the Cmd+K palette).
53
+
54
+ ## Disable, uninstall, export
55
+
56
+ ```bash
57
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 ext disable acme-quotes --site acme --yes --json
58
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 ext enable acme-quotes --site acme --yes --json
59
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 ext uninstall acme-quotes --site acme --yes --json
60
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 ext export acme-quotes --site acme --out backup.zip --json
61
+ ```
62
+
63
+ Disabling keeps the package and its config; uninstalling keeps the config (a re-install restores it). Data the module created (records, objects, notes) is never deleted by either.
64
+
65
+ ## When it breaks
66
+
67
+ | Symptom | Cause / fix |
68
+ |---|---|
69
+ | `imports` error: `react-router-dom`, `date-fns`… | Only react, react/jsx-runtime, react-dom, react-dom/client, react-i18next, lucide-react and @agent-crm/runtime are external. Use the runtime's router (`Link`, `useNavigate`, `paths`) and formatters (`formatDate`…), or let Vite bundle the library (remove it from `external`). |
70
+ | `load`: "bundle id … doesn't match manifest id" | The default export's `id` must equal `manifest.json`'s. Same for `apiVersion`. |
71
+ | `load`: "AI tool … already exists" | Tool names are global: prefix them with the module id. |
72
+ | `devJsx` / "jsxDEV is not a function" | Build in production mode (the scaffold's `vite.config.ts` does). |
73
+ | Hooks are invalid / "Invalid hook call" | A second React got bundled: keep `react` external. |
74
+ | The admin is blank after installing | Open it with `?safe=1` (or hold Shift while it loads), then `ext disable <id> --yes`. |
75
+ | A tool works in the admin but not in the CLI | The CLI has no DOM: keep `document` / `window` / `localStorage` out of AI tools, automation actions and hooks. |
76
+ | `ext list` says `load: error` | `ext check` the same package; the error is in `loadError`. |
@@ -0,0 +1,65 @@
1
+ # Theme recipes
2
+
3
+ A theme (`ext new theme <id>`) is `src/index.ts` (`defineTheme`) + an optional `src/style.css` (declared as `"style": "style.css"` in `manifest.json`). Installed and enabled, it appears in Settings, Appearance as a preset; applying it (`appearance preset <id>`) selects it as `themeId`. Its values fill everything the workspace didn't set explicitly; a user can still override any value afterwards. Logo, favicon and custom CSS stay workspace settings.
4
+
5
+ **First ask whether a theme is needed at all:** a brand color, a font, rounded corners or a dark sidebar are plain appearance settings (`agentcrm-admin` skill, `appearance set`). A theme is for a reusable, shareable look (several CRMs, a client, a marketplace) or for CSS that goes beyond the settings.
6
+
7
+ ## Values
8
+
9
+ ```ts
10
+ import { defineTheme } from "@agent-crm/runtime";
11
+
12
+ export default defineTheme({
13
+ id: "acme-brand",
14
+ apiVersion: "1.0.0",
15
+ name: "Acme",
16
+ description: "Acme green, warm grays, dark sidebar.",
17
+ appearance: {
18
+ accent: "#0f766e", // any #rrggbb; a 50…950 scale is generated (500 = this color)
19
+ neutral: "stone", // zinc | slate | stone | gray | neutral
20
+ radius: "lg", // none | sm | md | lg | xl
21
+ density: "comfortable", // compact | comfortable
22
+ font: "inter", // system (no network) | inter | geist | roboto | open-sans | lato | source-sans-3 | ibm-plex-sans | dm-sans | manrope | work-sans | plus-jakarta-sans | figtree | outfit | nunito-sans | poppins | space-grotesk
23
+ sidebar: "dark", // default | dark | accent
24
+ buttons: "accent", // neutral (near-black) | accent
25
+ contrast: "normal", // normal | high
26
+ defaultMode: "system", // system | light | dark (users who never toggled)
27
+ },
28
+ });
29
+ ```
30
+
31
+ Any subset works; unknown keys or bad values make `ext check` fail. Don't set `logo`, `favicon`, `preset` or `themeId` in a theme.
32
+
33
+ ## Brand from a logo or a hex
34
+
35
+ 1. Get the brand color: the user's hex, or the dominant non-gray color of their logo (read the SVG fill, or sample the PNG). Prefer a mid-tone (lightness 40 to 60 %): very light colors make unreadable buttons; the scale generator keeps the hue but white text needs contrast.
36
+ 2. Pick `neutral` by temperature: cool blues / teals → `slate`, warm oranges / reds / greens → `stone`, otherwise `zinc`.
37
+ 3. `buttons: "accent"` for a colorful brand, `"neutral"` for a sober one; `sidebar: "accent"` only for strong brands.
38
+ 4. Without a theme, the same values go straight to the workspace: `appearance set --accent … --neutral … --yes` and `appearance logo logo.svg --yes`.
39
+
40
+ ## CSS
41
+
42
+ `style.css` (and `css` in `defineTheme`, same effect) is injected while the theme is selected, before the workspace's custom CSS. Style through the design tokens rather than class names, which can change:
43
+
44
+ ```css
45
+ /* Colors are "r g b" triplets. */
46
+ html:root {
47
+ --srf-50: 250 250 249; /* page background in light mode */
48
+ }
49
+ html:root .acrm-sidebar-accent {} /* the colored sidebar */
50
+ html[data-density="compact"] {} /* density / contrast / radius / buttons / sidebar are data- attributes on <html> */
51
+ .dark h1 { color: rgb(var(--acc-300)); } /* dark mode = .dark on <html> */
52
+ ```
53
+
54
+ Variables: `--acc-50` … `--acc-950` (accent scale), `--srf-50` … `--srf-950` + `--srf-850` (neutral scale), `--acc-fg`, `--primary`, `--primary-hover`, `--primary-fg`, `--radius-scale` (multiplies every radius), `--font-sans`, `--row-h`, `--ctl-h`, `--card-pad`, `--card-head-py`, `--page-py`. Attributes on `<html>`: `data-density`, `data-sidebar`, `data-contrast`, `data-buttons`, `data-radius`. Limits: style.css 256 KB. No `@import` of remote fonts (the CRM loads Google Fonts only when `font` asks for one).
55
+
56
+ ## Test
57
+
58
+ ```bash
59
+ npm run build
60
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 ext check . --json
61
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 ext install . --site acme --yes --json
62
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 appearance preset acme-brand --site acme --json
63
+ ```
64
+
65
+ `ext check` prints the resolved values (`data.theme.appearance`) and the CSS size. `appearance preset` prints the before / after plan; add `--yes` to apply. Open the admin to look at it (light and dark, a table and a record page).
@@ -0,0 +1,116 @@
1
+ ---
2
+ name: agentcrm-install
3
+ description: Install a new AgentCRM (static, AI-drivable CRM) for the user - ask where the CRM data lives (encrypted files on an S3-compatible bucket, a private GitHub / GitLab repo or a local folder, or Firebase / a private git repo as JSON), then where the admin app is hosted (S3, GitHub / GitLab / Cloudflare Pages, local folder), help create the keys and tokens without ever asking for secrets in the chat, write the install plan, install and verify with doctor. Use when the user wants to create, set up or install a CRM with AgentCRM.
4
+ license: PolyForm-Noncommercial-1.0.0
5
+ compatibility: Requires Node.js 20+ and network access to the chosen storage. Works in Claude Code and any agent that can run shell commands.
6
+ metadata:
7
+ version: "0.3.0"
8
+ repository: "https://github.com/fleox/agentcrm"
9
+ allowed-tools: Bash Read Write
10
+ ---
11
+
12
+ # Install an AgentCRM
13
+
14
+ AgentCRM is a HubSpot / Twenty-style CRM (companies, people, deals, pipelines, activities, tasks, custom objects, views, automations, lead forms, reports) that is 100% static: there is no AgentCRM server. The data lives on storage the user owns (encrypted by default); the admin is a static web app hosted anywhere; the `agentcrm` CLI and its MCP server drive the same engine headless.
15
+
16
+ **Language:** talk to the user in their language; keep commands, files and plans in English.
17
+
18
+ Every command is `npx -y @fleox-agent-crm/agentcrm@0.3.0 <command> --json` (Node.js 20+). Each prints ONE JSON object: `{"ok": true, "data": ...}` or `{"ok": false, "error": {"code", "message", "hint"}}`. When `ok` is false, read `error.hint` and act on it. Exit code 2 = a usage error in your command.
19
+
20
+ ## 1. Start with status and options
21
+
22
+ ```bash
23
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 status --json
24
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 options --json
25
+ ```
26
+
27
+ `status` shows CRMs this computer already manages (maybe the user wants `agentcrm-manage` instead). `options` lists backends, data locations, hostings, credential types and the plan format.
28
+
29
+ ## 2. Ask about the DATA first
30
+
31
+ The CRM holds personal data (contacts, emails, phone numbers). Ask, in this order, and recommend the first answer:
32
+
33
+ 1. **Encrypted files on storage the user owns** (backend `journal`, the default). Where?
34
+ - an **S3-compatible bucket** (AWS S3, Cloudflare R2, OVHcloud, Scaleway, Backblaze, MinIO) - best for teams and speed. Must be a PRIVATE bucket, separate from the hosting bucket.
35
+ - a **private GitHub or GitLab repository** - simple if the user already lives on GitHub; one commit per write.
36
+ - a **folder on this computer** - single computer, no account. Advise backing it up.
37
+ 2. **Firebase** (backend `firebase`) - real-time teams with logins and per-user roles. See references/firebase.md.
38
+ 3. **A private git repo as readable JSON** (backend `git-json`) - readable history, but deleted records stay in the git history: warn the user.
39
+ 4. **This browser only** - for trying it: `npx -y @fleox-agent-crm/agentcrm@0.3.0 serve --json`, then "This browser" in the wizard. The CLI can't reach it.
40
+
41
+ Encryption: the journal is encrypted with AES-256-GCM by default. A passphrase is generated at install and stored only on this computer. Never offer to turn it off unless the user insists and the location is strictly private.
42
+
43
+ ## 3. Then ask where the ADMIN is hosted
44
+
45
+ The admin app holds no data and no secret (its `config.js` is public by design):
46
+
47
+ - `s3` - a public bucket with static website hosting, behind HTTPS (CDN or the bucket's https endpoint).
48
+ - `github-pages` - a GitHub repo served by Pages (`https://<owner>.github.io/<repo>`).
49
+ - `gitlab-pages`, `cloudflare-pages` - same idea.
50
+ - `local-folder` - a folder of this computer (serve it with `serve --dir`).
51
+ - no hosting (`"hosting": false`) - the user runs `serve` when needed.
52
+
53
+ HTTPS is required: browsers only allow the admin's request signing and encryption on secure pages.
54
+
55
+ ## 4. Credentials - never in the chat
56
+
57
+ Secrets (keys, tokens, passwords, passphrases) are NEVER typed into the conversation and never written in a plan. The user stores each one in their own terminal; in Claude Code they type `! npx -y @fleox-agent-crm/agentcrm@0.3.0 credentials set s3:main` (hidden prompt). Alternatives that keep secrets out of the chat:
58
+
59
+ - `--from-env KEY_ID,SECRET` - variables the user already exported (CI, `.env`).
60
+ - `--from-aws-profile <profile>` - an existing aws CLI profile (s3).
61
+ - `--from-gh` - the token of the signed-in GitHub CLI (github).
62
+
63
+ ```bash
64
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 credentials list --json
65
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 credentials types --json
66
+ ```
67
+
68
+ How to create each key with least privilege: references/s3.md, references/github.md, references/firebase.md. One account can serve several CRMs (`s3:main` for both the data bucket and the hosting bucket is fine).
69
+
70
+ ## 5. Write the plan, dry-run, install
71
+
72
+ Write `plan.json` (no secrets, only account ids):
73
+
74
+ ```json
75
+ {
76
+ "alias": "acme-crm",
77
+ "name": "Acme CRM",
78
+ "owner": { "name": "Ada Lovelace", "email": "ada@acme.com" },
79
+ "data": {
80
+ "backend": "journal",
81
+ "location": { "type": "s3", "settings": { "endpoint": "https://s3.gra.io.cloud.ovh.net", "region": "gra", "bucket": "acme-crm-data" }, "credential": "s3:main" },
82
+ "root": "agentcrm"
83
+ },
84
+ "hosting": { "type": "s3", "settings": { "endpoint": "https://s3.gra.io.cloud.ovh.net", "region": "gra", "bucket": "acme-crm-admin", "siteUrl": "https://crm.acme.com", "publicRead": true }, "credential": "s3:main" },
85
+ "demo": false
86
+ }
87
+ ```
88
+
89
+ More examples (GitHub repo data + GitHub Pages, local folder, Firebase): references/plans.md. `owner` becomes the first CRM admin, and the CLI acts as that user. `demo: true` adds a realistic sample dataset - offer it for a first look, not for a production CRM.
90
+
91
+ ```bash
92
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 install --plan plan.json --dry-run --json
93
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 install --plan plan.json --json
94
+ ```
95
+
96
+ The dry run checks every access and writes nothing. Fix `check-failed` errors with their hint (permissions, names, CORS) before installing. An existing dataset in the same place is kept; only what's missing is seeded.
97
+
98
+ ## 6. Save the passphrase - blocking step
99
+
100
+ When the result has `savePassphrase`, stop and do it with the user before anything else:
101
+
102
+ 1. `npx -y @fleox-agent-crm/agentcrm@0.3.0 credentials copy passphrase:<alias> --json` puts it on the clipboard (never print it).
103
+ 2. The user pastes it into their password manager now.
104
+ 3. The user proves it: in their own terminal, `! npx -y @fleox-agent-crm/agentcrm@0.3.0 credentials verify passphrase:<alias>`, pasting FROM the password manager. It must say "verified".
105
+
106
+ Without the passphrase nobody can read the data, ever.
107
+
108
+ ## 7. Verify
109
+
110
+ ```bash
111
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 doctor --site <alias> --json
112
+ ```
113
+
114
+ Every failing check has a `fix`. The most common one on buckets is CORS: the result prints the exact JSON rule for the data bucket - help the user apply it (references/s3.md). Then give the user the admin URL (`data.adminUrl` of the install) and explain: each new browser asks once for the storage keys and the passphrase, which stay in that browser.
115
+
116
+ Next: run the CRM with the `agentcrm-admin` skill, sales workflows with `agentcrm-sales`, health and updates with `agentcrm-manage`. To let Claude Desktop / Claude Code / Cursor use the CRM directly, see references/mcp.md.
@@ -0,0 +1,18 @@
1
+ # Firebase backend
2
+
3
+ 1. Create a Firebase project (console.firebase.google.com), add a Web app and copy its config (apiKey, authDomain, projectId, appId...). The web apiKey is public by design.
4
+ 2. Enable Authentication → Sign-in method → Email/Password (and Google if wanted).
5
+ 3. Create Firestore (production mode) and publish the AgentCRM security rules (see docs/firebase.md in the repository).
6
+ 4. Create the first admin account (Authentication → Users → Add user). The user stores its login: `! npx -y @fleox-agent-crm/agentcrm@0.3.0 credentials set firebase:<name>` (email + password at hidden prompts).
7
+ 5. Plan:
8
+
9
+ ```json
10
+ {
11
+ "alias": "team-crm",
12
+ "owner": { "name": "Ada", "email": "ada@acme.com" },
13
+ "data": { "backend": "firebase", "firebase": { "apiKey": "...", "authDomain": "acme.firebaseapp.com", "projectId": "acme", "appId": "1:..." }, "credential": "firebase:acme", "signInMethods": ["password", "google"] },
14
+ "hosting": { "type": "github-pages", "settings": { "owner": "acme", "repo": "crm" }, "credential": "github:acme" }
15
+ }
16
+ ```
17
+
18
+ Roles live in Firestore (`users/{uid}`) and are enforced by the rules.
@@ -0,0 +1,20 @@
1
+ # GitHub / GitLab for AgentCRM
2
+
3
+ ## Token
4
+
5
+ Fine-grained personal access token: https://github.com/settings/personal-access-tokens/new
6
+
7
+ - Repository access: only the data repository (PRIVATE) and, if used, the admin hosting repository.
8
+ - Permissions: Contents read and write; Metadata read-only; Pages read and write (optional, lets the CLI enable Pages).
9
+
10
+ The user stores it: `! npx -y @fleox-agent-crm/agentcrm@0.3.0 credentials set github:<login>`, or reuses the GitHub CLI login: `npx -y @fleox-agent-crm/agentcrm@0.3.0 credentials set github:<login> --from-gh --json`.
11
+
12
+ GitLab: project → Settings → Access tokens, scope `api`, role Developer; store as `gitlab:<name>`.
13
+
14
+ ## Data repository
15
+
16
+ Must be private: the install refuses a public data repository. Journal files are committed with `[skip ci]`. With `git-json`, every past value stays in the history (deleting a record does not erase it from git): tell the user.
17
+
18
+ ## Admin on GitHub Pages
19
+
20
+ A second repository (it may be public: it only holds the app and a `config.js` without secrets). Plan: `"hosting": { "type": "github-pages", "settings": { "owner": "acme", "repo": "acme-crm" } }` - the credential defaults to the data one when both are on GitHub. Pages takes about a minute to serve a new commit; re-run `doctor` after that.
@@ -0,0 +1,17 @@
1
+ # Use the CRM from an MCP client
2
+
3
+ `agentcrm mcp` is a stdio MCP server: tools = the AI tool catalog (search, list, get, create, update, delete, merge records, notes, activities, tasks, pipeline moves, reports, CSV import), resources = schema and pipelines, prompts = pipeline review, follow-up email, lead qualification. `--read-only` hides every tool that writes.
4
+
5
+ Claude Code:
6
+
7
+ ```bash
8
+ claude mcp add agentcrm -- npx -y @fleox-agent-crm/agentcrm@0.3.0 mcp --site <alias>
9
+ ```
10
+
11
+ Claude Desktop (`claude_desktop_config.json`) and Cursor (`.cursor/mcp.json`):
12
+
13
+ ```json
14
+ { "mcpServers": { "agentcrm": { "command": "npx", "args": ["-y", "@fleox-agent-crm/agentcrm@0.3.0", "mcp", "--site", "<alias>"] } } }
15
+ ```
16
+
17
+ The server uses the credentials of this computer (`~/.agentcrm`) and acts as the site's CLI user.
@@ -0,0 +1,45 @@
1
+ # Install plan examples
2
+
3
+ ## Encrypted journal in a private GitHub repo, admin on GitHub Pages
4
+
5
+ ```json
6
+ {
7
+ "alias": "acme",
8
+ "owner": { "name": "Ada Lovelace", "email": "ada@acme.com" },
9
+ "data": { "backend": "journal", "location": { "type": "github", "settings": { "owner": "acme", "repo": "acme-crm-data" }, "credential": "github:acme" } },
10
+ "hosting": { "type": "github-pages", "settings": { "owner": "acme", "repo": "acme-crm" } }
11
+ }
12
+ ```
13
+
14
+ ## Local folder, no hosting (one computer)
15
+
16
+ ```json
17
+ {
18
+ "alias": "solo",
19
+ "owner": { "name": "Me", "email": "me@example.com" },
20
+ "data": { "backend": "journal", "location": { "type": "local-folder", "settings": { "path": "/Users/me/Documents/crm" } } },
21
+ "hosting": false,
22
+ "demo": true
23
+ }
24
+ ```
25
+
26
+ Use it from the browser with `npx -y @fleox-agent-crm/agentcrm@0.3.0 serve --json` and the folder picker.
27
+
28
+ ## git-json in a private repo
29
+
30
+ ```json
31
+ {
32
+ "alias": "team",
33
+ "owner": { "name": "Ada", "email": "ada@acme.com" },
34
+ "data": { "backend": "git-json", "git": { "provider": "github", "owner": "acme", "repo": "crm-json", "branch": "main" }, "credential": "github:acme" },
35
+ "hosting": { "type": "cloudflare-pages", "settings": { "provider": "github", "owner": "acme", "repo": "crm-admin", "siteUrl": "https://crm-admin.pages.dev" } }
36
+ }
37
+ ```
38
+
39
+ ## Fields
40
+
41
+ - `alias`: lower-case letters, digits, dashes.
42
+ - `owner`: first admin (email required).
43
+ - `data.encryption`: omitted = encrypted with a new passphrase `passphrase:<alias>`; `{ "credential": "passphrase:<name>" }` = existing passphrase (reuse a dataset); `false` = plain (discouraged).
44
+ - `hosting.folder`: admin folder on the hosting, default `admin`.
45
+ - `currency`, `locale`: defaults for money and dates.
@@ -0,0 +1,24 @@
1
+ # S3-compatible storage for AgentCRM
2
+
3
+ Use TWO buckets: a PRIVATE one for the data (journal backend) and a public one for the admin app. One access key can cover both.
4
+
5
+ ## Access key (least privilege)
6
+
7
+ - **AWS**: IAM user with a policy on both buckets: `s3:GetObject`, `s3:PutObject`, `s3:DeleteObject` on `arn:aws:s3:::<bucket>/*` and `s3:ListBucket` on `arn:aws:s3:::<bucket>`. Store it: `! npx -y @fleox-agent-crm/agentcrm@0.3.0 credentials set s3:main`, or import a profile with `--from-aws-profile <name>`.
8
+ - **Cloudflare R2**: R2 → Manage API tokens → Object Read & Write, scoped to the buckets. Endpoint `https://<account-id>.r2.cloudflarestorage.com`, region `auto`.
9
+ - **OVHcloud**: Public Cloud → Object Storage → S3 users; endpoint `https://s3.<region>.io.cloud.ovh.net`. Set `publicRead: true` on the hosting bucket.
10
+ - **Scaleway**: endpoint `https://s3.<region>.scw.cloud`.
11
+
12
+ ## CORS on the data bucket
13
+
14
+ The browser admin reads and writes the data bucket directly, so the bucket needs a CORS rule for the admin's origin. `doctor` prints the exact JSON; it looks like:
15
+
16
+ ```json
17
+ [{ "AllowedOrigins": ["https://crm.acme.com"], "AllowedMethods": ["GET", "PUT", "DELETE", "HEAD"], "AllowedHeaders": ["authorization", "content-type", "cache-control", "x-amz-*"], "ExposeHeaders": ["ETag"], "MaxAgeSeconds": 3600 }]
18
+ ```
19
+
20
+ AWS: bucket → Permissions → CORS. R2: bucket → Settings → CORS policy. With the aws CLI: `aws s3api put-bucket-cors --bucket <bucket> --cors-configuration file://cors.json` (wrap the array as `{"CORSRules": [...]}`).
21
+
22
+ ## Hosting bucket
23
+
24
+ Enable static website hosting (index document `index.html`) or put a CDN in front (CloudFront, Cloudflare) with HTTPS. `siteUrl` in the plan is that public HTTPS URL; the admin is served at `<siteUrl>/admin/`.
@@ -0,0 +1,108 @@
1
+ ---
2
+ name: agentcrm-manage
3
+ description: Check, repair and update existing AgentCRM CRMs - list the CRMs this computer manages, register one installed elsewhere (another computer, the setup wizard), attach credentials, run the health check (data access, passphrase, dataset, hosted admin, config.js, CORS, data exposure) and apply its fixes, detect newer AgentCRM releases and offer to update hosted admins, compact the data, set up scheduled automations. Use when the user asks about one of their CRMs, says something is broken, or wants to update.
4
+ license: PolyForm-Noncommercial-1.0.0
5
+ compatibility: Requires Node.js 20+.
6
+ metadata:
7
+ version: "0.3.0"
8
+ repository: "https://github.com/fleox/agentcrm"
9
+ allowed-tools: Bash Read Write
10
+ ---
11
+
12
+ # Manage AgentCRM sites
13
+
14
+ This skill covers the CRMs themselves (registry, health, updates, maintenance). To work with the data - records, pipelines, imports - use `agentcrm-admin`; for sales workflows, `agentcrm-sales`.
15
+
16
+ **Language:** talk to the user in their language; keep commands and files in English.
17
+
18
+ Every command is `npx -y @fleox-agent-crm/agentcrm@0.3.0 <command> --json` (Node.js 20+); read `error.hint` whenever `ok` is false.
19
+
20
+ ## Always start with status
21
+
22
+ ```bash
23
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 status --json
24
+ ```
25
+
26
+ - `data.tool.updateAvailable: true` -> tell the user AgentCRM `data.tool.latest` exists and offer to update the skills first (Claude Code: `/plugin marketplace update agentcrm`, then `/reload-plugins`).
27
+ - A site with `state: "update"` -> summarise `update.changes` (breaking first), then offer `deploy-admin` (below). Never update silently.
28
+ - `state: "newer"` -> the hosted admin is newer than this tool: update the skills / tool first.
29
+ - `state: "unreachable"` -> run `doctor` for that site.
30
+ - `data.advice` already phrases these; relay it.
31
+
32
+ ## Which CRM?
33
+
34
+ ```bash
35
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 site list --json
36
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 site show <alias> --json
37
+ ```
38
+
39
+ Commands take `--site <alias>`; always pass it. Without it the tool uses `AGENTCRM_SITE`, the folder's `agentcrm.json` (`{ "site": "<alias>" }`), the only site, or the default chosen with `site use <alias>` - otherwise it fails with `site-required`: ask the user which CRM. Say which CRM you are working on before changing anything.
40
+
41
+ Registry commands: `site use <alias>`, `site rename <from> <to>`, `site forget <alias>` (local only - nothing is deleted online).
42
+
43
+ ## Register a CRM installed elsewhere
44
+
45
+ ```bash
46
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 site add <alias> --admin-url https://crm.acme.com/admin/ --data-credential s3:main --passphrase-credential passphrase:acme --hosting-credential s3:main --json
47
+ ```
48
+
49
+ - It reads the admin's public `config.js`, opens the data (proving the credentials) and reads the hosting from the dataset.
50
+ - `--data-credential`: the data location key (journal), the git token (git-json) or the Firebase login.
51
+ - `--passphrase-credential`: encrypted journals. The user stores the passphrase from their password manager: `! npx -y @fleox-agent-crm/agentcrm@0.3.0 credentials set passphrase:<alias>`.
52
+ - `--user <email>`: the CRM user the CLI acts as (default: the first admin).
53
+ - A CRM in a local folder without a hosted admin: `site add <alias> --runtime @config.json --data-path /path/to/folder`.
54
+ - `warnings` lists what is still missing; fix later with `site credentials <alias> --hosting-credential <account>` (`""` removes one).
55
+ - Errors `passphrase-required` / `passphrase-wrong`: store the right passphrase and retry.
56
+
57
+ ## Health check
58
+
59
+ ```bash
60
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 doctor --site <alias> --json
61
+ ```
62
+
63
+ `data.checks[]` has `id`, `status` (ok / warn / fail / skip), `message` and, for problems, `fix`. Exit code 1 when a check fails. Walk the user through each fix, most important first:
64
+
65
+ - `data-access` fail -> credentials or passphrase (see `fix`).
66
+ - `dataset` fail -> `doctor --site <alias> --repair --json` seeds what's missing (idempotent, keeps data).
67
+ - `cors-data` warn -> the data bucket lacks a CORS rule for the admin origin; `fix` holds the exact JSON (see the `agentcrm-install` skill, references/s3.md).
68
+ - `data-exposure` fail -> the unencrypted dataset is public: make it private NOW, then move it.
69
+ - `config-js` fail with secrets -> revoke those keys immediately, then `deploy-admin`.
70
+ - `https` fail -> the admin needs HTTPS.
71
+ - `purge` / `journal` warn -> compaction (below).
72
+
73
+ Details of every check: references/doctor.md.
74
+
75
+ ## Update a hosted admin
76
+
77
+ ```bash
78
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 deploy-admin --site <alias> --json
79
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 deploy-admin --site <alias> --yes --json
80
+ ```
81
+
82
+ Without `--yes` it prints the plan (`needsConfirmation: true`, versions, file count): show it, ask, then re-run with `--yes`. `--all` covers every CRM with a hosting. It refuses downgrades and admins that store a newer data format. GitHub / GitLab Pages need a minute before `doctor` sees the new version.
83
+
84
+ ## Compact (GDPR erasure)
85
+
86
+ Deleted records stay restorable until compaction. To erase them physically and shrink the journal:
87
+
88
+ ```bash
89
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 compact --site <alias> --json
90
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 compact --site <alias> --yes --json
91
+ ```
92
+
93
+ Show the plan (records purged) and confirm first: it can't be undone. Run it from one place at a time.
94
+
95
+ ## Scheduled automations and lead forms (no server)
96
+
97
+ Scheduled / inactivity automations and lead form ingestion run when the admin is open, or from a cron. The recommended cron is a GitHub Actions workflow in a private repo: references/cron.md. Locally:
98
+
99
+ ```bash
100
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 automations run --site <alias> --yes --json
101
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 forms ingest --site <alias> --yes --json
102
+ ```
103
+
104
+ ## Overview of one CRM
105
+
106
+ ```bash
107
+ npx -y @fleox-agent-crm/agentcrm@0.3.0 stats --site <alias> --json
108
+ ```
@@ -0,0 +1,11 @@
1
+ # Scheduled automations with GitHub Actions
2
+
3
+ AgentCRM has no server, so time-based work (schedule / inactivity automations, ingesting lead form submissions) runs from a scheduled GitHub Actions workflow in a PRIVATE repository the user owns.
4
+
5
+ 1. Create a private repo (e.g. `acme/crm-cron`).
6
+ 2. Add repository secrets (Settings → Secrets and variables → Actions): `AGENTCRM_S3_KEY_ID`, `AGENTCRM_S3_SECRET`, `AGENTCRM_PASSPHRASE` (the dataset passphrase), and the site's public config as `AGENTCRM_RUNTIME` (the object of the admin's `config.js`, JSON).
7
+ 3. Copy `docs/templates/agentcrm-cron.yml` of the AgentCRM repository to `.github/workflows/agentcrm-cron.yml`.
8
+
9
+ The workflow stores the credentials with `credentials set … --from-env`, registers the CRM with `site add --runtime`, then runs `automations run --yes` and `forms ingest --yes` every hour. Each run writes only journal segments (no conflict with users editing at the same time).
10
+
11
+ Keep the passphrase secret strictly in the private repo; anyone with it can read the CRM.
@@ -0,0 +1,18 @@
1
+ # doctor checks
2
+
3
+ | id | What it proves | Typical fix |
4
+ |---|---|---|
5
+ | credential-data / -hosting / -passphrase | The accounts the site references are stored on this computer | The user runs `credentials set <account>` in their own terminal |
6
+ | encryption | The journal is encrypted | Keep the location private; migrate with `export json` into a new encrypted install |
7
+ | data-repo | The git data repo is private and writable | Make the repo private; check the token's Contents permission |
8
+ | data-access | The dataset opens (keys, passphrase, network) | Follow the hint (passphrase-required / passphrase-wrong / storage) |
9
+ | dataset | Standard objects, a pipeline, settings, an active admin exist | `doctor --repair` |
10
+ | cli-user | The CLI acts as an admin | `site credentials <alias> --user <admin email>` |
11
+ | purge | Soft-deleted records still stored | `compact` (plan, then `--yes`) |
12
+ | journal | Segments since the last snapshot (loading speed) | `compact --yes` |
13
+ | https | The admin is served over HTTPS | CDN / custom domain with TLS / Pages |
14
+ | admin | The admin page is served | `deploy-admin --yes`; Pages: wait a minute |
15
+ | admin-version | Hosted admin vs this release | `deploy-admin` (plan, then `--yes`) |
16
+ | config-js | config.js exists, matches the backend and holds no secret | `deploy-admin --yes`; revoke leaked keys first |
17
+ | cors-data | The data bucket answers a CORS preflight for the admin origin | Apply the printed CORS JSON to the bucket |
18
+ | data-exposure | The dataset is not downloadable from the public site | Separate private bucket |