@revfleet/hscli 0.8.11 → 0.9.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 (154) hide show
  1. package/CHANGELOG.md +186 -0
  2. package/README.md +223 -10
  3. package/dist/cli.js +29 -3
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/agent/contracts.d.ts +3 -0
  6. package/dist/commands/agent/contracts.js +139 -0
  7. package/dist/commands/agent/contracts.js.map +1 -0
  8. package/dist/commands/agent/index.d.ts +3 -0
  9. package/dist/commands/agent/index.js +188 -0
  10. package/dist/commands/agent/index.js.map +1 -0
  11. package/dist/commands/agent/recipes.d.ts +13 -0
  12. package/dist/commands/agent/recipes.js +108 -0
  13. package/dist/commands/agent/recipes.js.map +1 -0
  14. package/dist/commands/agent/runner.d.ts +16 -0
  15. package/dist/commands/agent/runner.js +165 -0
  16. package/dist/commands/agent/runner.js.map +1 -0
  17. package/dist/commands/auth/index.js +64 -7
  18. package/dist/commands/auth/index.js.map +1 -1
  19. package/dist/commands/automation/index.js +30 -0
  20. package/dist/commands/automation/index.js.map +1 -1
  21. package/dist/commands/backup/index.d.ts +12 -0
  22. package/dist/commands/backup/index.js +459 -0
  23. package/dist/commands/backup/index.js.map +1 -0
  24. package/dist/commands/cms/content-ops.js +1 -1
  25. package/dist/commands/cms/content-ops.js.map +1 -1
  26. package/dist/commands/communication-preferences/index.js +207 -7
  27. package/dist/commands/communication-preferences/index.js.map +1 -1
  28. package/dist/commands/content-permissions/index.d.ts +22 -0
  29. package/dist/commands/content-permissions/index.js +141 -0
  30. package/dist/commands/content-permissions/index.js.map +1 -0
  31. package/dist/commands/context/index.d.ts +3 -0
  32. package/dist/commands/context/index.js +182 -0
  33. package/dist/commands/context/index.js.map +1 -0
  34. package/dist/commands/crm/associations.js +38 -0
  35. package/dist/commands/crm/associations.js.map +1 -1
  36. package/dist/commands/crm/custom-objects.js +39 -2
  37. package/dist/commands/crm/custom-objects.js.map +1 -1
  38. package/dist/commands/crm/dated.js +3 -3
  39. package/dist/commands/crm/dated.js.map +1 -1
  40. package/dist/commands/crm/migration.js +210 -2
  41. package/dist/commands/crm/migration.js.map +1 -1
  42. package/dist/commands/crm/properties.js +2 -1
  43. package/dist/commands/crm/properties.js.map +1 -1
  44. package/dist/commands/crm/property-batch.d.ts +1 -0
  45. package/dist/commands/crm/property-batch.js +44 -5
  46. package/dist/commands/crm/property-batch.js.map +1 -1
  47. package/dist/commands/crm/shared.js +21 -2
  48. package/dist/commands/crm/shared.js.map +1 -1
  49. package/dist/commands/crm/sync.js +1 -1
  50. package/dist/commands/crm/sync.js.map +1 -1
  51. package/dist/commands/doctor/index.js +193 -0
  52. package/dist/commands/doctor/index.js.map +1 -1
  53. package/dist/commands/email-tracking/index.d.ts +16 -0
  54. package/dist/commands/email-tracking/index.js +314 -0
  55. package/dist/commands/email-tracking/index.js.map +1 -0
  56. package/dist/commands/extensions/index.js +1 -1
  57. package/dist/commands/extensions/index.js.map +1 -1
  58. package/dist/commands/forms/index.js +15 -2
  59. package/dist/commands/forms/index.js.map +1 -1
  60. package/dist/commands/forms/legacy-v2.d.ts +7 -2
  61. package/dist/commands/forms/legacy-v2.js +103 -7
  62. package/dist/commands/forms/legacy-v2.js.map +1 -1
  63. package/dist/commands/guide/index.d.ts +3 -0
  64. package/dist/commands/guide/index.js +75 -16
  65. package/dist/commands/guide/index.js.map +1 -1
  66. package/dist/commands/internal/catalog.d.ts +1 -0
  67. package/dist/commands/internal/catalog.js +2 -0
  68. package/dist/commands/internal/catalog.js.map +1 -0
  69. package/dist/commands/internal/index.d.ts +26 -0
  70. package/dist/commands/internal/index.js +823 -0
  71. package/dist/commands/internal/index.js.map +1 -0
  72. package/dist/commands/internal-session.d.ts +15 -0
  73. package/dist/commands/internal-session.js +152 -0
  74. package/dist/commands/internal-session.js.map +1 -0
  75. package/dist/commands/lists/index.js +1 -1
  76. package/dist/commands/lists/index.js.map +1 -1
  77. package/dist/commands/marketing/email-audit.d.ts +32 -0
  78. package/dist/commands/marketing/email-audit.js +121 -0
  79. package/dist/commands/marketing/email-audit.js.map +1 -0
  80. package/dist/commands/marketing/index.js +2 -0
  81. package/dist/commands/marketing/index.js.map +1 -1
  82. package/dist/commands/mcp.js +5 -3
  83. package/dist/commands/mcp.js.map +1 -1
  84. package/dist/commands/playbooks/index.d.ts +3 -0
  85. package/dist/commands/playbooks/index.js +228 -0
  86. package/dist/commands/playbooks/index.js.map +1 -0
  87. package/dist/commands/portals/index.d.ts +3 -0
  88. package/dist/commands/portals/index.js +132 -0
  89. package/dist/commands/portals/index.js.map +1 -0
  90. package/dist/commands/reports/index.d.ts +3 -0
  91. package/dist/commands/reports/index.js +479 -0
  92. package/dist/commands/reports/index.js.map +1 -0
  93. package/dist/commands/sales-content/index.d.ts +13 -0
  94. package/dist/commands/sales-content/index.js +59 -0
  95. package/dist/commands/sales-content/index.js.map +1 -0
  96. package/dist/commands/sales-templates/index.d.ts +3 -0
  97. package/dist/commands/sales-templates/index.js +88 -0
  98. package/dist/commands/sales-templates/index.js.map +1 -0
  99. package/dist/commands/seed/cms.js +28 -45
  100. package/dist/commands/seed/cms.js.map +1 -1
  101. package/dist/commands/sequences/index.d.ts +18 -0
  102. package/dist/commands/sequences/index.js +263 -0
  103. package/dist/commands/sequences/index.js.map +1 -0
  104. package/dist/commands/settings/index.js +450 -102
  105. package/dist/commands/settings/index.js.map +1 -1
  106. package/dist/commands/settings/site-settings.d.ts +3 -0
  107. package/dist/commands/settings/site-settings.js +106 -0
  108. package/dist/commands/settings/site-settings.js.map +1 -0
  109. package/dist/commands/ui/index.d.ts +3 -0
  110. package/dist/commands/ui/index.js +422 -0
  111. package/dist/commands/ui/index.js.map +1 -0
  112. package/dist/commands/workflows/index.js +2 -0
  113. package/dist/commands/workflows/index.js.map +1 -1
  114. package/dist/commands/workflows/preflight.d.ts +23 -0
  115. package/dist/commands/workflows/preflight.js +295 -0
  116. package/dist/commands/workflows/preflight.js.map +1 -0
  117. package/dist/core/action-contract.d.ts +43 -0
  118. package/dist/core/action-contract.js +207 -0
  119. package/dist/core/action-contract.js.map +1 -0
  120. package/dist/core/auth.d.ts +6 -0
  121. package/dist/core/auth.js +85 -0
  122. package/dist/core/auth.js.map +1 -1
  123. package/dist/core/http.d.ts +8 -0
  124. package/dist/core/http.js +37 -5
  125. package/dist/core/http.js.map +1 -1
  126. package/dist/core/id-maps.d.ts +27 -0
  127. package/dist/core/id-maps.js +204 -0
  128. package/dist/core/id-maps.js.map +1 -0
  129. package/dist/core/output.d.ts +2 -1
  130. package/dist/core/output.js +34 -0
  131. package/dist/core/output.js.map +1 -1
  132. package/dist/mcp/profiles.d.ts +14 -0
  133. package/dist/mcp/profiles.js +68 -0
  134. package/dist/mcp/profiles.js.map +1 -0
  135. package/dist/mcp/server.d.ts +5 -3
  136. package/dist/mcp/server.js +22 -5
  137. package/dist/mcp/server.js.map +1 -1
  138. package/docs/CAPABILITY_LIBRARY.md +29 -8
  139. package/docs/COMMAND_TREE.md +98 -17
  140. package/docs/COMPARISON.md +8 -5
  141. package/docs/COOKBOOK.md +127 -5
  142. package/docs/INTERNAL-ENDPOINTS-DISCOVERY.md +813 -0
  143. package/docs/INTERNAL-ENDPOINTS.md +371 -0
  144. package/docs/INTERNAL_ENDPOINTS.md +243 -0
  145. package/docs/MARKETING_SETUP.md +21 -1
  146. package/docs/MCP.md +28 -89
  147. package/docs/MCP_TOOL_CATALOG.md +192 -0
  148. package/docs/MIGRATION_ADAPTERS.md +115 -0
  149. package/docs/PORTAL_BACKUP.md +212 -0
  150. package/docs/PUBLISHING.md +1 -1
  151. package/docs/SALES_CONTENT_INTERNAL_PUNCH_LIST.md +504 -0
  152. package/docs/TUTORIALS/secure-agent-writes.md +49 -0
  153. package/docs/WHY_HOW_WHAT.md +10 -4
  154. package/package.json +4 -2
package/docs/COOKBOOK.md CHANGED
@@ -11,7 +11,7 @@ All write operations are **dry-run by default**. Omit flags to see the safety er
11
11
  ### Login with a private app token
12
12
 
13
13
  ```bash
14
- hscli auth login --token "pat-eu1-a1b2c3d4-5678-9abc-def0-1234567890ab"
14
+ printf '%s' "$HUBSPOT_PRIVATE_APP_TOKEN" | hscli auth login --token-stdin
15
15
  ```
16
16
 
17
17
  Hublet is auto-detected from the token prefix (e.g. `pat-eu1-...` routes to `api-eu1.hubapi.com`).
@@ -80,14 +80,21 @@ hscli auth oauth-url \
80
80
  ### Exchange an OAuth code for a token
81
81
 
82
82
  ```bash
83
+ : "${HSCLI_OAUTH_CLIENT_SECRET:?set HSCLI_OAUTH_CLIENT_SECRET in your secret manager}"
83
84
  hscli auth oauth-exchange \
84
85
  --client-id "a1b2c3d4-5678-9abc-def0-1234567890ab" \
85
- --client-secret "secret-value" \
86
86
  --code "auth-code-from-redirect" \
87
87
  --redirect-uri "https://app.example.com/oauth/callback" \
88
88
  --profile oauth-prod
89
+
90
+ hscli --profile oauth-prod auth whoami
89
91
  ```
90
92
 
93
+ The access token refreshes automatically before expiry. hscli stores the
94
+ refresh token and the client-secret environment variable name, never the
95
+ client secret itself. Use `hscli --profile oauth-prod auth refresh` to force a
96
+ rotation while diagnosing an OAuth installation.
97
+
91
98
  ---
92
99
 
93
100
  ## 2. CRM Operations (Contacts, Companies, Deals, Tickets)
@@ -230,6 +237,13 @@ hscli crm custom-objects records create vehicles --force \
230
237
  --data '{"properties":{"vin":"1HGCM82633A004352","make":"Honda","model":"Accord"}}'
231
238
  ```
232
239
 
240
+ ### Batch-create custom object records
241
+
242
+ ```bash
243
+ hscli crm custom-objects records batch-create vehicles --force \
244
+ --data '{"inputs":[{"properties":{"vin":"1HGCM82633A004352","make":"Honda","model":"Accord"}}]}'
245
+ ```
246
+
233
247
  ### Search custom object records
234
248
 
235
249
  ```bash
@@ -310,6 +324,22 @@ hscli crm migration export-metadata \
310
324
 
311
325
  This captures property groups with their real labels/displayOrder, property definitions, deal/ticket pipelines with per-stage detail, custom object schemas, owners, teams, business units, currencies, and standard association labels. Use it before building replay payloads so pipeline IDs/stage IDs and owner/team mappings are explicit.
312
326
 
327
+ ### Apply migration ID maps to local payloads
328
+
329
+ ```bash
330
+ hscli crm migration id-map apply \
331
+ --data @contacts-upsert.json \
332
+ --field hubspot_owner_id=./id-maps/owners.json \
333
+ --field sales_owner=./id-maps/owners.json \
334
+ --field hs_owning_teams=./id-maps/teams.json \
335
+ --field hs_all_assigned_business_unit_ids=./id-maps/business-units.json \
336
+ --on-unmapped error \
337
+ --out contacts-upsert.remapped.json \
338
+ --report-out contacts-upsert.remap-report.json
339
+ ```
340
+
341
+ `id-map apply` rewrites local JSON only; it never calls HubSpot. It supports `{ inputs: [...] }` batch payloads, arrays, and single records. Use `--on-unmapped error` for final migrations. Use `--on-unmapped drop` only after documenting an explicit policy, for example dropping out-of-scope teams while preserving all mapped NA/GLO teams.
342
+
313
343
  ### Export recoverable record activities
314
344
 
315
345
  ```bash
@@ -363,7 +393,7 @@ hscli --force crm properties batch-create contacts \
363
393
  --data @contacts-properties.json
364
394
  ```
365
395
 
366
- `batch-create` skips `hs_*` reserved names, HubSpot-defined/read-only properties, and empty enumerations by default. It also removes enum options with blank labels/values before sending. If you prefer to keep a property whose enum options cannot be recovered, demote it to a free-text property:
396
+ `batch-create` skips HubSpot-reserved names (`hs_*`, `recurring_revenue_*`, and known reserved close-reason names), HubSpot-defined/read-only properties, and empty enumerations by default. It also removes enum options with blank labels/values before sending. Owner-reference enum properties keep `referencedObjectType` and automatically get `externalOptions: true`, which HubSpot requires for object-reference options. If you prefer to keep a property whose enum options cannot be recovered, demote it to a free-text property:
367
397
 
368
398
  ```bash
369
399
  hscli --dry-run crm properties batch-create contacts \
@@ -378,6 +408,8 @@ hscli --force crm properties batch-create 2-123456 \
378
408
  --data '{"inputs":[{"name":"migration_region","label":"Migration Region","type":"string","fieldType":"text","groupName":"customobjectinformation"}]}'
379
409
  ```
380
410
 
411
+ Do not use `crm custom-objects schemas update` to add properties to an existing custom object schema. HubSpot accepts that PATCH but silently ignores the `properties` array, so hscli now fails early and points you to `crm properties batch-create <objectType>`.
412
+
381
413
  ### Update a property label
382
414
 
383
415
  ```bash
@@ -398,6 +430,16 @@ hscli crm associations create deals 18294750312 companies 9182736450 --dry-run
398
430
  hscli crm associations create deals 18294750312 companies 9182736450 --force
399
431
  ```
400
432
 
433
+ ### Batch-create typed associations
434
+
435
+ ```bash
436
+ hscli crm associations batch-create contacts companies --dry-run \
437
+ --data '{"inputs":[{"from":{"id":"101"},"to":{"id":"202"},"types":[{"associationCategory":"HUBSPOT_DEFINED","associationTypeId":279}]}]}'
438
+
439
+ hscli crm associations batch-create contacts companies --force \
440
+ --data @contact-company-associations.json
441
+ ```
442
+
401
443
  ### Remove an association
402
444
 
403
445
  ```bash
@@ -505,6 +547,9 @@ hscli forms create --source-format v2 --strict --dry-run \
505
547
 
506
548
  hscli forms translate-v2 --data '{"name":"Legacy Webinar Signup","submitText":"Register","formFieldGroups":[{"fields":[{"name":"email","label":"Email","fieldType":"email","required":true}]}]}'
507
549
 
550
+ hscli forms create --source-format v2 --subscription-type-map ./id-maps/subscription-types.json --dry-run \
551
+ --data '{"name":"Legacy Webinar Signup","formFieldGroups":[{"fields":[{"name":"email","label":"Email","fieldType":"email"}]}]}'
552
+
508
553
  hscli forms update "f47ac10b-58cc-4372-a567-0e02b2c3d479" --force \
509
554
  --data '{"name":"Q2 Webinar Signup (Updated)"}'
510
555
  ```
@@ -540,6 +585,9 @@ hscli workflows flows get 39172845
540
585
 
541
586
  hscli workflows flows create --dry-run \
542
587
  --data '{"name":"New Lead Nurture Sequence","type":"PLATFORM_FLOW"}'
588
+
589
+ hscli workflows preflight --id-map-dir ./id-maps --strict \
590
+ --data '{"name":"Workflow export","actions":[],"suppressionListIds":[]}'
543
591
  ```
544
592
 
545
593
  ### Service conversations and feedback
@@ -805,13 +853,86 @@ The MCP server exposes the same operations as the CLI with the same safety model
805
853
  Use Claude-style slash commands when you want the CLI to tell you the next safe sequence:
806
854
 
807
855
  ```bash
856
+ hscli ui
808
857
  hscli /setup
809
858
  hscli /migration
810
859
  hscli /read
860
+ hscli /fetch
861
+ hscli /get
811
862
  hscli /write
812
863
  hscli /guardrails
813
864
  ```
814
865
 
866
+ ### Render an agent-safe runbook
867
+
868
+ Use `agent plan` when Codex, Claude Code, Cursor, or a scheduled worker needs a
869
+ deterministic HubSpot operator sequence. The command prints a plan; it does not
870
+ call HubSpot.
871
+
872
+ ```bash
873
+ hscli agent list
874
+ hscli --profile sandbox --policy-file ./policy.json --change-ticket CHG-123 \
875
+ agent plan automation-risk --json
876
+ ```
877
+
878
+ Render a schedule artifact without installing it:
879
+
880
+ ```bash
881
+ hscli --profile live agent schedule render pipeline-risk \
882
+ --target cron \
883
+ --cron "0 8 * * 1"
884
+ ```
885
+
886
+ Available recipes:
887
+
888
+ - `data-cleanup` — fill-rate, lifecycle, ownership, and audit review
889
+ - `pipeline-risk` — pipeline/stage metadata and deal data-quality review
890
+ - `automation-risk` — workflow inventory, workflow errors, email exposure, and audit review
891
+
892
+ Every follow-up command still goes through the normal hscli model: public APIs
893
+ first, `--force` for writes, optional `--policy-file`, optional
894
+ `--change-ticket`, shared rate-limit handling, redacted trace/audit output.
895
+
896
+ ### Build a portal context pack
897
+
898
+ Use `context build` before handing a portal to an agent or migration runbook. It
899
+ performs a small read-only public-API probe and returns deterministic signals:
900
+ portal metadata, owner/team counts, workflow count, CRM object totals/samples,
901
+ profile classification, recommended runbooks, and questions to ask the portal
902
+ owner before writing anything.
903
+
904
+ ```bash
905
+ hscli --profile source-read --json context build --sample-limit 25
906
+ ```
907
+
908
+ ### Manage several portals safely
909
+
910
+ Use `portals list` to see the local profile inventory without printing tokens or
911
+ calling HubSpot. Use `portals plan` when a source/sandbox/live workflow needs
912
+ the same read-only context or agent runbook across several portals.
913
+
914
+ ```bash
915
+ hscli --json portals list
916
+ hscli --json portals plan \
917
+ --profiles source-read,sandbox-read \
918
+ --runbook automation-risk \
919
+ --include-context \
920
+ --sample-limit 25
921
+ ```
922
+
923
+ The output is plan-only: every rendered command includes an explicit
924
+ `--profile`, so source and target portals stay separate.
925
+
926
+ ### Check API coverage parity
927
+
928
+ Use `doctor parity` to see which HubSpot areas hscli covers through public APIs,
929
+ which require explicit browser-session/internal adapters, which are hybrid, and
930
+ which remain UI-only/manual evidence.
931
+
932
+ ```bash
933
+ hscli --json doctor parity
934
+ ```
935
+
815
936
  ### Check hublet configuration consistency
816
937
 
817
938
  Verifies that hscli's detected hublet, token prefix, and `@hubspot/cli` config all agree:
@@ -847,6 +968,7 @@ All commands support `--format` and `--json` flags.
847
968
 
848
969
  ```bash
849
970
  hscli crm contacts list --format json
971
+ hscli crm contacts list --format jsonl # one compact envelope per result
850
972
  hscli crm contacts list --format csv
851
973
  hscli crm contacts list --format yaml
852
974
  hscli crm contacts list --format table # default
@@ -870,8 +992,8 @@ hscli --telemetry-file ./telemetry.jsonl crm deals create --force \
870
992
  ### Manage staging and production side by side
871
993
 
872
994
  ```bash
873
- hscli auth login --token "pat-na1-staging-token" --profile staging
874
- hscli auth login --token "pat-eu1-production-token" --profile production
995
+ printf '%s' "$HUBSPOT_STAGING_TOKEN" | hscli auth login --token-stdin --profile staging
996
+ printf '%s' "$HUBSPOT_PRODUCTION_TOKEN" | hscli auth login --token-stdin --profile production
875
997
 
876
998
  # Read from staging
877
999
  hscli --profile staging crm contacts search --query "test"