@getfrontline/cli 1.0.1 → 1.0.4

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 (88) hide show
  1. package/README.md +246 -246
  2. package/dist/commands/auth/login.d.ts.map +1 -1
  3. package/dist/commands/auth/login.js +29 -4
  4. package/dist/commands/auth/login.js.map +1 -1
  5. package/dist/commands/auth/profiles.d.ts.map +1 -1
  6. package/dist/commands/auth/profiles.js +7 -11
  7. package/dist/commands/auth/profiles.js.map +1 -1
  8. package/dist/commands/object/activity.d.ts +3 -0
  9. package/dist/commands/object/activity.d.ts.map +1 -0
  10. package/dist/commands/object/{note.js → activity.js} +24 -19
  11. package/dist/commands/object/activity.js.map +1 -0
  12. package/dist/commands/object/export.js +3 -3
  13. package/dist/commands/object/field.js +5 -5
  14. package/dist/commands/object/index.js +10 -10
  15. package/dist/commands/object/index.js.map +1 -1
  16. package/dist/commands/object/option.js +4 -4
  17. package/dist/commands/object/record-type.js +4 -4
  18. package/dist/commands/object/record.js +8 -8
  19. package/dist/commands/object/relation.js +4 -4
  20. package/dist/commands/object/view.js +9 -9
  21. package/dist/commands/table/index.d.ts.map +1 -1
  22. package/dist/commands/table/index.js +0 -4
  23. package/dist/commands/table/index.js.map +1 -1
  24. package/dist/lib/cliVersion.d.ts +8 -0
  25. package/dist/lib/cliVersion.d.ts.map +1 -0
  26. package/dist/lib/cliVersion.js +26 -0
  27. package/dist/lib/cliVersion.js.map +1 -0
  28. package/dist/lib/config.js +1 -1
  29. package/dist/lib/config.js.map +1 -1
  30. package/dist/lib/errors.d.ts +3 -0
  31. package/dist/lib/errors.d.ts.map +1 -1
  32. package/dist/lib/errors.js +10 -1
  33. package/dist/lib/errors.js.map +1 -1
  34. package/dist/lib/helpEpilog.d.ts.map +1 -1
  35. package/dist/lib/helpEpilog.js +35 -35
  36. package/dist/lib/helpEpilog.js.map +1 -1
  37. package/dist/lib/httpClient.d.ts.map +1 -1
  38. package/dist/lib/httpClient.js +35 -16
  39. package/dist/lib/httpClient.js.map +1 -1
  40. package/dist/lib/output.d.ts +10 -0
  41. package/dist/lib/output.d.ts.map +1 -1
  42. package/dist/lib/output.js +28 -12
  43. package/dist/lib/output.js.map +1 -1
  44. package/dist/max/commands/auth/login.d.ts.map +1 -1
  45. package/dist/max/commands/auth/login.js +22 -5
  46. package/dist/max/commands/auth/login.js.map +1 -1
  47. package/dist/max/commands/chat/repl.d.ts +9 -0
  48. package/dist/max/commands/chat/repl.d.ts.map +1 -1
  49. package/dist/max/commands/chat/repl.js +15 -11
  50. package/dist/max/commands/chat/repl.js.map +1 -1
  51. package/dist/max/commands/chat/send.d.ts.map +1 -1
  52. package/dist/max/commands/chat/send.js +17 -0
  53. package/dist/max/commands/chat/send.js.map +1 -1
  54. package/dist/max/lib/httpClient.d.ts.map +1 -1
  55. package/dist/max/lib/httpClient.js +11 -4
  56. package/dist/max/lib/httpClient.js.map +1 -1
  57. package/dist/max/ui/banner.d.ts.map +1 -1
  58. package/dist/max/ui/banner.js +6 -6
  59. package/dist/max/ui/banner.js.map +1 -1
  60. package/dist/max.js +15 -3
  61. package/dist/max.js.map +1 -1
  62. package/dist/skills/aggregations/SKILL.md +7 -7
  63. package/dist/skills/auth-and-profiles/SKILL.md +1 -1
  64. package/dist/skills/crm-setup/SKILL.md +76 -48
  65. package/dist/skills/crud-operations/SKILL.md +2 -2
  66. package/dist/skills/export-and-delete/SKILL.md +5 -5
  67. package/dist/skills/files/SKILL.md +4 -4
  68. package/dist/skills/filter-and-query/SKILL.md +7 -7
  69. package/dist/skills/frontline-internals/SKILL.md +209 -0
  70. package/dist/skills/max-auth/SKILL.md +76 -76
  71. package/dist/skills/max-chat/SKILL.md +111 -111
  72. package/dist/skills/notes-and-tasks/SKILL.md +29 -29
  73. package/dist/skills/pipeline-setup/SKILL.md +13 -13
  74. package/dist/skills/relations/SKILL.md +20 -15
  75. package/dist/skills/resource-creation/SKILL.md +70 -1
  76. package/dist/skills/schema-design/SKILL.md +21 -14
  77. package/package.json +7 -7
  78. package/dist/commands/object/note.d.ts +0 -3
  79. package/dist/commands/object/note.d.ts.map +0 -1
  80. package/dist/commands/object/note.js.map +0 -1
  81. package/dist/commands/table/note.d.ts +0 -3
  82. package/dist/commands/table/note.d.ts.map +0 -1
  83. package/dist/commands/table/note.js +0 -62
  84. package/dist/commands/table/note.js.map +0 -1
  85. package/dist/commands/table/task.d.ts +0 -3
  86. package/dist/commands/table/task.d.ts.map +0 -1
  87. package/dist/commands/table/task.js +0 -88
  88. package/dist/commands/table/task.js.map +0 -1
@@ -6,15 +6,25 @@ description: >
6
6
  between entities, adding pipeline stages, populating data, and querying
7
7
  across related objects. Use as a reference when building any multi-entity
8
8
  business workflow from scratch.
9
+ IMPORTANT: Before designing new entities or fields, always read the
10
+ `frontline-internals` skill to understand what the system already handles
11
+ automatically (activity sync, consolidation, built-in objects).
9
12
  allowed-tools: Bash(frontline:*)
10
13
  ---
11
14
 
12
15
  # Building a CRM with the Frontline CLI
13
16
 
17
+ > [!IMPORTANT]
18
+ > **Read the [`frontline-internals`](../frontline-internals/SKILL.md) skill first.**
19
+ > It describes what the platform already handles automatically — including
20
+ > activity synchronization (emails, conversations, …) and periodic
21
+ > consolidation of fields like `Last Interaction`. Designing entities that
22
+ > duplicate built-in behaviour leads to split history and inconsistent data.
23
+
14
24
  This skill walks through building a complete CRM system: Companies, Contacts,
15
25
  and Deals — with relations, pipeline stages, record types, and views.
16
26
 
17
- > The built-in `sor__companies`, `sor__people`, and `sor__deals` objects already
27
+ > The built-in `companies`, `people`, and `deals` objects already
18
28
  > exist. This guide uses **custom objects** to show how to build everything from
19
29
  > scratch, but the same patterns apply when extending existing objects.
20
30
 
@@ -65,6 +75,8 @@ Use `object create` for business entities and `table create` for simple data.
65
75
  # Create a new "Embarques" table
66
76
  frontline table create embarques --data '{
67
77
  "displayName": "Embarques",
78
+ "emoji": "truck",
79
+ "icon_color": "orange",
68
80
  "columns": [
69
81
  { "name": "Nombre", "type": "string", "metadata": { "format": "text" } }
70
82
  ]
@@ -73,6 +85,8 @@ frontline table create embarques --data '{
73
85
  # Create a new "Pedidos" table
74
86
  frontline table create pedidos --data '{
75
87
  "displayName": "Pedidos",
88
+ "emoji": "package",
89
+ "icon_color": "blue",
76
90
  "columns": [
77
91
  { "name": "Nombre", "type": "string", "metadata": { "format": "text" } }
78
92
  ]
@@ -82,9 +96,9 @@ frontline table create pedidos --data '{
82
96
  The system also ships with these core objects:
83
97
 
84
98
  ```
85
- sor__companies — Companies
86
- sor__people — People (contacts)
87
- sor__deals — Deals (sales pipeline)
99
+ companies — Companies
100
+ people — People (contacts)
101
+ deals — Deals (sales pipeline)
88
102
  ```
89
103
 
90
104
  Verify they exist:
@@ -93,21 +107,35 @@ Verify they exist:
93
107
  frontline object list
94
108
  ```
95
109
 
110
+ ### Setting Icons on Existing Objects/Tables
111
+
112
+ ```bash
113
+ frontline object update deals --data '{"emoji": "handshake", "icon_color": "emerald"}'
114
+ frontline table update embarques --data '{"emoji": "delivery", "icon_color": "teal"}'
115
+ ```
116
+
117
+ ### Available Icon Colors
118
+
119
+ Use the `icon_color` field with a **color name** (case-insensitive):
120
+
121
+ `red`, `orange`, `amber`, `yellow`, `lime`, `green`, `emerald`, `teal`,
122
+ `cyan`, `sky`, `blue`, `indigo`, `violet`, `purple`, `pink`, `rose`
123
+
96
124
  ## Step 2 — Inspect & Extend the Schema
97
125
 
98
126
  ### View current fields
99
127
 
100
128
  ```bash
101
- frontline object field list sor__companies
102
- frontline object field list sor__people
103
- frontline object field list sor__deals
129
+ frontline object field list companies
130
+ frontline object field list people
131
+ frontline object field list deals
104
132
  ```
105
133
 
106
134
  ### Add custom fields
107
135
 
108
136
  ```bash
109
137
  # Add a "Lead Source" select field to People
110
- frontline object field create sor__people --data '{
138
+ frontline object field create people --data '{
111
139
  "name": "Lead Source",
112
140
  "type": "select",
113
141
  "metadata": { "mode": "singleSelect" }
@@ -115,20 +143,20 @@ frontline object field create sor__people --data '{
115
143
  # → Returns: { id: 15, name: "Lead Source", type: "select", ... }
116
144
 
117
145
  # Add options to the new field (use the field ID from above)
118
- frontline object option create sor__people 15 --data '{"name": "Website", "color": "Sky"}'
119
- frontline object option create sor__people 15 --data '{"name": "Referral", "color": "Emerald"}'
120
- frontline object option create sor__people 15 --data '{"name": "Cold Outreach", "color": "Gray"}'
121
- frontline object option create sor__people 15 --data '{"name": "Event", "color": "Lavender"}'
146
+ frontline object option create people 15 --data '{"name": "Website", "color": "Sky"}'
147
+ frontline object option create people 15 --data '{"name": "Referral", "color": "Emerald"}'
148
+ frontline object option create people 15 --data '{"name": "Cold Outreach", "color": "Gray"}'
149
+ frontline object option create people 15 --data '{"name": "Event", "color": "Lavender"}'
122
150
 
123
151
  # Add a "Probability %" number field to Deals
124
- frontline object field create sor__deals --data '{
152
+ frontline object field create deals --data '{
125
153
  "name": "Probability",
126
154
  "type": "number",
127
155
  "metadata": {}
128
156
  }'
129
157
 
130
158
  # Add a "Next Follow-up" date field to Deals
131
- frontline object field create sor__deals --data '{
159
+ frontline object field create deals --data '{
132
160
  "name": "Next Follow-up",
133
161
  "type": "dateOnly",
134
162
  "metadata": {}
@@ -140,13 +168,13 @@ frontline object field create sor__deals --data '{
140
168
  The built-in objects already have relations defined:
141
169
 
142
170
  ```bash
143
- frontline object schema sor__people
144
- # → relations: [{ name: "companies", target: "sor__companies", mode: "multi" }]
171
+ frontline object schema people
172
+ # → relations: [{ name: "companies", target: "companies", mode: "multi" }]
145
173
 
146
- frontline object schema sor__deals
174
+ frontline object schema deals
147
175
  # → relations: [
148
- # { name: "people", target: "sor__people", mode: "multi" },
149
- # { name: "company", target: "sor__companies", mode: "single" }
176
+ # { name: "people", target: "people", mode: "multi" },
177
+ # { name: "company", target: "companies", mode: "single" }
150
178
  # ]
151
179
  ```
152
180
 
@@ -157,14 +185,14 @@ The `name` field is what you use in all relation commands.
157
185
  ### Create companies
158
186
 
159
187
  ```bash
160
- frontline object record create sor__companies --data '{
188
+ frontline object record create companies --data '{
161
189
  "Name": "Acme Corp",
162
190
  "Domain": "acme.com",
163
191
  "Primary Location": "New York, USA"
164
192
  }'
165
193
  # → { id: "6625aaa...", ... }
166
194
 
167
- frontline object record create sor__companies --data '{
195
+ frontline object record create companies --data '{
168
196
  "Name": "TechStart Inc",
169
197
  "Domain": "techstart.io",
170
198
  "Primary Location": "San Francisco, USA"
@@ -175,7 +203,7 @@ frontline object record create sor__companies --data '{
175
203
  ### Create contacts
176
204
 
177
205
  ```bash
178
- frontline object record create sor__people --data '{
206
+ frontline object record create people --data '{
179
207
  "First Name": "Alice",
180
208
  "Last Name": "Johnson",
181
209
  "Email": "alice@acme.com",
@@ -184,7 +212,7 @@ frontline object record create sor__people --data '{
184
212
  }'
185
213
  # → { id: "6625ccc...", ... }
186
214
 
187
- frontline object record create sor__people --data '{
215
+ frontline object record create people --data '{
188
216
  "First Name": "Bob",
189
217
  "Last Name": "Smith",
190
218
  "Email": "bob@techstart.io",
@@ -196,10 +224,10 @@ frontline object record create sor__people --data '{
196
224
  ### Create deals
197
225
 
198
226
  ```bash
199
- # Use option IDs from `frontline object field list sor__deals`
227
+ # Use option IDs from `frontline object field list deals`
200
228
  # Stage options: 1=Lead, 2=In Progress, 3=Won, 4=Lost
201
229
 
202
- frontline object record create sor__deals --data '{
230
+ frontline object record create deals --data '{
203
231
  "Name": "Acme Enterprise License",
204
232
  "Stage": [2],
205
233
  "Value": 150000
@@ -213,36 +241,36 @@ frontline object record create sor__deals --data '{
213
241
 
214
242
  ```bash
215
243
  # Alice works at Acme
216
- frontline object relation link sor__people 6625ccc... Companies 6625aaa...
244
+ frontline object relation link people 6625ccc... Companies 6625aaa...
217
245
 
218
246
  # Bob works at TechStart
219
- frontline object relation link sor__people 6625ddd... Companies 6625bbb...
247
+ frontline object relation link people 6625ddd... Companies 6625bbb...
220
248
  ```
221
249
 
222
250
  ### Link deal → company and deal → person
223
251
 
224
252
  ```bash
225
253
  # The Acme deal belongs to Acme Corp
226
- frontline object relation link sor__deals 6625eee... Company 6625aaa...
254
+ frontline object relation link deals 6625eee... Company 6625aaa...
227
255
 
228
256
  # Alice is the contact for this deal
229
- frontline object relation link sor__deals 6625eee... People 6625ccc...
257
+ frontline object relation link deals 6625eee... People 6625ccc...
230
258
  ```
231
259
 
232
260
  ### Verify links
233
261
 
234
262
  ```bash
235
263
  # What company does Alice belong to?
236
- frontline object relation get sor__people 6625ccc... Companies
264
+ frontline object relation get people 6625ccc... Companies
237
265
 
238
266
  # Who are the contacts for the Acme deal?
239
- frontline object relation get sor__deals 6625eee... People
267
+ frontline object relation get deals 6625eee... People
240
268
 
241
269
  # Which deals belong to Acme Corp? (reverse lookup)
242
- frontline object relation find-by sor__deals Company 6625aaa...
270
+ frontline object relation find-by deals Company 6625aaa...
243
271
 
244
272
  # Which people work at Acme Corp? (reverse lookup)
245
- frontline object relation find-by sor__people Companies 6625aaa...
273
+ frontline object relation find-by people Companies 6625aaa...
246
274
  ```
247
275
 
248
276
  ## Step 6 — Set Up Pipeline Views
@@ -251,10 +279,10 @@ frontline object relation find-by sor__people Companies 6625aaa...
251
279
 
252
280
  ```bash
253
281
  # Get the field IDs to include in each record type
254
- frontline object field list sor__deals
282
+ frontline object field list deals
255
283
  # → Use the IDs for Name, Stage, Value, People, Company
256
284
 
257
- frontline object record-type create sor__deals --data '{
285
+ frontline object record-type create deals --data '{
258
286
  "name": "active_pipeline",
259
287
  "displayName": "Active Pipeline",
260
288
  "columnIds": [1, 2, 3, 5, 8]
@@ -267,14 +295,14 @@ frontline object record-type create sor__deals --data '{
267
295
  ```bash
268
296
  # Use the Stage field ID for grouping (e.g., field ID 2)
269
297
  # Create directly on the object (no record type needed)
270
- frontline object view create sor__deals --data '{
298
+ frontline object view create deals --data '{
271
299
  "name": "Pipeline Board",
272
300
  "type": "KANBAN",
273
301
  "metadata": { "groupingColumnId": 2 }
274
302
  }'
275
303
 
276
304
  # Or scoped to a specific record type with --record-type <id>
277
- frontline object view create sor__deals --record-type 7 --data '{
305
+ frontline object view create deals --record-type 7 --data '{
278
306
  "name": "Pipeline Board",
279
307
  "type": "KANBAN",
280
308
  "metadata": { "groupingColumnId": 2 }
@@ -289,13 +317,13 @@ Refine your views to show only the most important information:
289
317
 
290
318
  ```bash
291
319
  # Set order of columns/fields
292
- frontline object view update sor__deals <view-id> --column-order "Name, Stage, Value, Company"
320
+ frontline object view update deals <view-id> --column-order "Name, Stage, Value, Company"
293
321
 
294
322
  # Hide less relevant fields
295
- frontline object view update sor__deals <view-id> --hidden-columns "Created At, Updated At"
323
+ frontline object view update deals <view-id> --hidden-columns "Created At, Updated At"
296
324
 
297
325
  # Order fields in the record creation dialog
298
- frontline object view update sor__deals <view-id> --dialog-field-order "Name, Stage, Value, Probability"
326
+ frontline object view update deals <view-id> --dialog-field-order "Name, Stage, Value, Probability"
299
327
  ```
300
328
 
301
329
  ## Step 8 — Query Your CRM
@@ -303,7 +331,7 @@ frontline object view update sor__deals <view-id> --dialog-field-order "Name, St
303
331
  ### Find high-value deals
304
332
 
305
333
  ```bash
306
- frontline object record list sor__deals --query '{
334
+ frontline object record list deals --query '{
307
335
  "operator": "and",
308
336
  "conditions": [
309
337
  { "path": "[Value]", "operator": "gte", "value": 50000 },
@@ -315,7 +343,7 @@ frontline object record list sor__deals --query '{
315
343
  ### Find contacts with no company
316
344
 
317
345
  ```bash
318
- frontline object record list sor__people --query '{
346
+ frontline object record list people --query '{
319
347
  "path": "[Companies]", "operator": "isNull"
320
348
  }'
321
349
  ```
@@ -323,29 +351,29 @@ frontline object record list sor__people --query '{
323
351
  ### Search across fields
324
352
 
325
353
  ```bash
326
- frontline object record list sor__people --search "alice"
327
- frontline object record list sor__companies --search "tech"
354
+ frontline object record list people --search "alice"
355
+ frontline object record list companies --search "tech"
328
356
  ```
329
357
 
330
358
  ### Find all contacts at a specific company
331
359
 
332
360
  ```bash
333
- frontline object relation find-by sor__people Companies <company-id>
361
+ frontline object relation find-by people Companies <company-id>
334
362
  ```
335
363
 
336
364
  ## Step 8 — Export & Backup
337
365
 
338
366
  ```bash
339
367
  # Export all deals to spreadsheet
340
- frontline object export xlsx sor__deals --output deals_report.xlsx
368
+ frontline object export xlsx deals --output deals_report.xlsx
341
369
 
342
370
  # Export filtered data (only won deals)
343
- frontline object export csv sor__deals \
371
+ frontline object export csv deals \
344
372
  --query '{"path": "[Stage]", "operator": "containsAny", "value": [3]}' \
345
373
  --output won_deals.csv
346
374
 
347
375
  # Export all contacts
348
- frontline object export xlsx sor__people --output contacts_backup.xlsx
376
+ frontline object export xlsx people --output contacts_backup.xlsx
349
377
  ```
350
378
 
351
379
  ## Quick Command Reference
@@ -269,10 +269,10 @@ Create a new record type with a kanban view for a deals pipeline:
269
269
 
270
270
  ```bash
271
271
  # 1. Check current fields
272
- frontline object field list sor__deals
272
+ frontline object field list deals
273
273
 
274
274
  # 2. Create a record type (returns record_type_id)
275
- frontline object record-type create sor__deals --data '{
275
+ frontline object record-type create deals --data '{
276
276
  "name": "enterprise",
277
277
  "displayName": "Enterprise Deals",
278
278
  "columnIds": [1, 2, 5, 8]
@@ -23,10 +23,10 @@ frontline object export xlsx <name> [--output file.xlsx]
23
23
 
24
24
  ```bash
25
25
  # Export all people
26
- frontline object export xlsx sor__people
26
+ frontline object export xlsx people
27
27
 
28
28
  # Export with filter (high-value deals only)
29
- frontline object export xlsx sor__deals \
29
+ frontline object export xlsx deals \
30
30
  --query '{"path": "[Amount]", "operator": "gte", "value": 10000}' \
31
31
  --output big_deals.xlsx
32
32
 
@@ -46,7 +46,7 @@ frontline object export csv <name> [--output file.csv]
46
46
 
47
47
  ```bash
48
48
  # Export all records as CSV
49
- frontline object export csv sor__people --output people_backup.csv
49
+ frontline object export csv people --output people_backup.csv
50
50
  ```
51
51
 
52
52
  ### Default Output
@@ -86,11 +86,11 @@ Always export before deleting:
86
86
 
87
87
  ```bash
88
88
  # 1. Export everything
89
- frontline object export xlsx sor__legacy_deals --output legacy_deals_backup.xlsx
89
+ frontline object export xlsx legacy_deals --output legacy_deals_backup.xlsx
90
90
 
91
91
  # 2. Verify the export file exists and looks right
92
92
  ls -la legacy_deals_backup.xlsx
93
93
 
94
94
  # 3. Delete the object
95
- frontline object delete sor__legacy_deals
95
+ frontline object delete legacy_deals
96
96
  ```
@@ -55,16 +55,16 @@ frontline table file delete <table> <file-id>
55
55
 
56
56
  ```bash
57
57
  # 1. Find the row
58
- frontline object row list sor__deals --search "Acme Corp"
58
+ frontline object row list deals --search "Acme Corp"
59
59
  # → row ID = 6625abc123def456
60
60
 
61
61
  # 2. List attached files
62
- frontline object file list sor__deals 6625abc123def456
62
+ frontline object file list deals 6625abc123def456
63
63
  # → [{ id: 15, originalName: "contract_v2.pdf", size: 245000, ... }]
64
64
 
65
65
  # 3. Download a file
66
- frontline object file download sor__deals 15 --output ./contract_v2.pdf
66
+ frontline object file download deals 15 --output ./contract_v2.pdf
67
67
 
68
68
  # 4. Delete an outdated file
69
- frontline object file delete sor__deals 15
69
+ frontline object file delete deals 15
70
70
  ```
@@ -17,18 +17,18 @@ The `frontline table row list` and `frontline object record list` commands accep
17
17
 
18
18
  ```bash
19
19
  # Simple text search across all fields
20
- frontline object record list sor__people --search "john"
20
+ frontline object record list people --search "john"
21
21
 
22
22
  # Filter by a single condition
23
23
  # TIP: Use 'frontline object field list <name>' to find field names and tag IDs
24
- frontline object record list sor__deals --query '{
24
+ frontline object record list deals --query '{
25
25
  "path": "[Amount]",
26
26
  "operator": "gte",
27
27
  "value": 10000
28
28
  }'
29
29
 
30
30
  # Multiple conditions (AND)
31
- frontline object record list sor__deals --query '{
31
+ frontline object record list deals --query '{
32
32
  "operator": "and",
33
33
  "conditions": [
34
34
  { "path": "[Status]", "operator": "containsAny", "value": [1, 2] },
@@ -37,7 +37,7 @@ frontline object record list sor__deals --query '{
37
37
  }'
38
38
 
39
39
  # Sort results
40
- frontline object record list sor__people --sort '[{"path": "[Last Name]", "type": "asc"}]'
40
+ frontline object record list people --sort '[{"path": "[Last Name]", "type": "asc"}]'
41
41
  ```
42
42
 
43
43
  ## Path Format
@@ -176,8 +176,8 @@ frontline table row list my_table --page 1 --page-size 50
176
176
  ## Filter by Record Type (objects only)
177
177
 
178
178
  ```bash
179
- frontline object record list sor__people --record-type lead
180
- frontline object record list sor__deals --record-type "all"
179
+ frontline object record list people --record-type lead
180
+ frontline object record list deals --record-type "all"
181
181
  ```
182
182
 
183
183
  ## Full Example
@@ -185,7 +185,7 @@ frontline object record list sor__deals --record-type "all"
185
185
  Find all open deals worth over $10k, owned by a specific company, sorted by amount:
186
186
 
187
187
  ```bash
188
- frontline object record list sor__deals \
188
+ frontline object record list deals \
189
189
  --query '{
190
190
  "operator": "and",
191
191
  "conditions": [
@@ -0,0 +1,209 @@
1
+ ---
2
+ name: frontline-internals
3
+ description: >
4
+ Internal workings of the Frontline platform: how the base CRM objects
5
+ (Company, Deals, People, Tickets) relate to each other, how activity
6
+ synchronization works automatically for People and Companies, and how
7
+ periodic consolidation keeps CRM records up to date. Read this skill
8
+ before designing new entities or fields to avoid duplicating behavior
9
+ that the system already handles automatically.
10
+ allowed-tools: Bash(frontline:*)
11
+ ---
12
+
13
+ # Frontline Internal System Mechanics
14
+
15
+ Understanding how Frontline works internally is critical **before** designing
16
+ new objects, fields, or relations. Many common CRM needs are already handled
17
+ automatically by the platform.
18
+
19
+ ---
20
+
21
+ ## 1. Base Objects and Their Relationships
22
+
23
+ Frontline ships with four core objects that form the foundation of every
24
+ account. They are pre-provisioned and cannot be deleted.
25
+
26
+ ```
27
+ companies — Organizations / accounts
28
+ people — Individual contacts
29
+ deals — Sales opportunities
30
+ tickets — Support or service requests
31
+ ```
32
+
33
+ ### Built-in Relations
34
+
35
+ ```
36
+ People → Companies (many-to-many)
37
+ Deals → People (many-to-many)
38
+ Deals → Company (many-to-one)
39
+ Tickets → People (many-to-many)
40
+ Tickets → Company (many-to-one)
41
+ ```
42
+
43
+ > **Before creating a new entity**, check whether it fits naturally as a
44
+ > custom object linked to one of these four. Most vertical use cases (leads,
45
+ > vendors, partners, subscribers) are best modeled as extensions of People or
46
+ > Companies rather than standalone objects.
47
+
48
+ ---
49
+
50
+ ## 2. Automatic Activity Synchronization
51
+
52
+ When an account grants the required permissions, Frontline automatically
53
+ captures and attaches **activity records** to People and Company objects.
54
+ You do **not** need to create these manually or build pipelines to collect them.
55
+
56
+ ### Activity Types (peopleActivity / companyActivity)
57
+
58
+ Each activity record has a `type` field that identifies the source:
59
+
60
+ | Type | Description |
61
+ | --------------- | ------------------------------------------------------------ |
62
+ | `email` | Inbound or outbound emails linked to the contact or company |
63
+ | `conversation` | Chat/messaging interactions (Slack, etc.) |
64
+ | _(more coming)_ | The system is designed to receive additional types over time |
65
+
66
+ Activity records are stored as `peopleActivity` (for People) or
67
+ `companyActivity` (for Companies) and are surfaced automatically in the
68
+ record's activity feed.
69
+
70
+ ### What this means in practice
71
+
72
+ - **You do not need an "Emails" table.** Emails are synced automatically.
73
+ - **You do not need a "Conversations" table.** Those are synced automatically.
74
+ - If you need to query or filter activities, use the activity endpoints
75
+ rather than creating a parallel data structure.
76
+
77
+ > **Before building a new data pipeline or table to capture interactions**,
78
+ > verify whether that interaction type is already handled by the activity
79
+ > sync. Adding a duplicate table leads to split history and inconsistent data.
80
+
81
+ ---
82
+
83
+ ## 3. Periodic Consolidation
84
+
85
+ Beyond real-time activity sync, Frontline runs **periodic consolidation jobs**
86
+ that aggregate and summarize information at the People and Company level.
87
+
88
+ ### What gets consolidated
89
+
90
+ - **Last Interaction** — The most recent interaction date across all activity
91
+ types is computed and written to the People record. For Companies, this is
92
+ further propagated from all linked People: the Company's `Last Interaction`
93
+ always reflects the freshest interaction across any of its contacts.
94
+ - **Profile Insights (Structured AI Assessments)** — The system evaluates the
95
+ state of the relationship and record data.
96
+ - **For People**: Sentiment (very_positive to very_negative), Engagement
97
+ Level (highly_engaged to at_risk), key relationship description, identified
98
+ Risks (e.g., churn signals), and Opportunities.
99
+ - **For Companies**: Connection Strength (Strong/Medium/Weak), Key People
100
+ discovery (stakeholders), and Company Mission extraction.
101
+ - **Key Topics** — A list of the top 3-5 recurring themes in interactions
102
+ (e.g., "Pricing", "Onboarding", "Product Feedback").
103
+ - **Summaries** — Concise, professional overviews of the person or company
104
+ based on all recent context.
105
+
106
+ ### Implications for custom fields
107
+
108
+ - Do **not** build a custom "last email date" or "last activity date" field
109
+ and try to keep it in sync manually via hooks or external automation.
110
+ The system already maintains `Last Interaction` for this purpose.
111
+ - If you need a consolidation that does not yet exist, raise it as a
112
+ platform request rather than building a workaround.
113
+
114
+ ---
115
+
116
+ ## 4. Design Checklist — Before Adding New Entities or Fields
117
+
118
+ Use this checklist whenever you are about to create a new object, table, or field:
119
+
120
+ 1. **Is this already a base object?**
121
+ Check `frontline object list` — `companies`, `people`,
122
+ `deals`, `tickets` may already fit.
123
+
124
+ 2. **Is this interaction data?**
125
+ If the new entity stores emails, messages, calls, or any user-to-contact
126
+ interaction, check whether the activity sync already covers it before
127
+ building a custom table.
128
+
129
+ 3. **Is this a summary or aggregate?**
130
+ If the field would need to be recomputed based on interactions
131
+ (e.g., "last contacted", "interaction count"), check if periodic
132
+ consolidation already provides it via built-in fields.
133
+
134
+ 4. **Does a relation already exist?**
135
+ Run `frontline object schema <obj>` to inspect existing relations before
136
+ creating a new one. Duplicate relations cause inconsistent data.
137
+
138
+ 5. **Only then — extend or create.**
139
+ If none of the above covers the need, proceed to add a custom field
140
+ (see `crm-setup` skill) or create a new object/table.
141
+
142
+ ---
143
+
144
+ ## 5. Memories & Intelligent Consolidation
145
+
146
+ Beyond raw activity sync, Frontline uses AI to distill important facts and
147
+ structured data about People and Companies. This process is called
148
+ **Consolidation**.
149
+
150
+ ### What are "Memories"?
151
+
152
+ Memories are persistent, AI-distilled facts about a person or company that
153
+ provide context for future interactions. Unlike activity logs, memories are
154
+ long-lived and categorized.
155
+
156
+ **Categories include:**
157
+
158
+ - `DECISION`: Specific decisions made (e.g., "Decided to postpone the project until Q3").
159
+ - `AGREEMENT`: Agreed terms or commitments (e.g., "Agreed to a 20% discount for the first year").
160
+ - `PREFERENCE`: Personal or professional preferences (e.g., "Prefers morning meetings").
161
+ - `RISK`: Potential issues or red flags (e.g., "Customer is frustrated with current response times").
162
+ - `OTHER`: General facts or context (e.g., "Is a fan of the Golden State Warriors").
163
+
164
+ > **Example**: Instead of searching through 50 emails to find a contact's
165
+ > preferred communication channel, the system creates a `PREFERENCE` memory:
166
+ > _"Prefers being contacted via WhatsApp after 6pm."_
167
+
168
+ ### Structured Data Extracted
169
+
170
+ During periodic consolidation, the LLM extracts and updates specific data
171
+ points to keep record profiles fresh:
172
+
173
+ | Object | Data Point | Description / Examples |
174
+ | :---------- | :------------------- | :--------------------------------------------------------- |
175
+ | **People** | **Profile Insights** | Sentiment, Engagement, Risks, Opportunities, Key Topics |
176
+ | | **Summary** | Professional overview of persona and status |
177
+ | **Company** | **Profile Insights** | Connection Strength, Key Stakeholders, Mission |
178
+ | | **Firmographics** | Revenue, Employee count, Headquarters (from external sync) |
179
+
180
+ ### How this data is used
181
+
182
+ 1. **Intelligent Feed**: Memories and summaries are displayed in the CRM feed to
183
+ give users instant context without reading threads.
184
+ 2. **AI Reasoning (RAG)**: When an AI agent (or you, the developer) queries the
185
+ system, it retrieves these memories to generate responses that are
186
+ contextually aware.
187
+ 3. **Automated Triggers**: Consolidated fields (like `Last Interaction` or
188
+ `Connection Strength`) can trigger automated workflows.
189
+
190
+ ---
191
+
192
+ ## 6. Summary
193
+
194
+ ```
195
+ ┌─────────────────────────────────────────────────────────────────┐
196
+ │ WHAT FRONTLINE DOES AUTOMATICALLY │
197
+ │ │
198
+ │ • Syncs emails/conversations → people/company Activity │
199
+ │ • Consolidates Last Interaction & Connection Strength │
200
+ │ │
201
+ │ INTELLIGENT CONSOLIDATION │
202
+ │ • Distills "Memories" (Decisions, Preferences, Risks, etc.) │
203
+ │ • Extracts Structured Data (Summary, Insights, Firmographics) │
204
+ │ • Updates Vector Store for context-aware AI reasoning │
205
+ │ │
206
+ │ BASE OBJECTS │
207
+ │ companies people deals tickets │
208
+ └─────────────────────────────────────────────────────────────────┘
209
+ ```