@revfleet/hscli 0.8.12 → 0.9.1

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 (158) hide show
  1. package/CHANGELOG.md +197 -1
  2. package/README.md +243 -10
  3. package/dist/cli.js +27 -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/evidence.d.ts +68 -0
  9. package/dist/commands/agent/evidence.js +358 -0
  10. package/dist/commands/agent/evidence.js.map +1 -0
  11. package/dist/commands/agent/index.d.ts +3 -0
  12. package/dist/commands/agent/index.js +223 -0
  13. package/dist/commands/agent/index.js.map +1 -0
  14. package/dist/commands/agent/recipes.d.ts +13 -0
  15. package/dist/commands/agent/recipes.js +108 -0
  16. package/dist/commands/agent/recipes.js.map +1 -0
  17. package/dist/commands/agent/runner.d.ts +16 -0
  18. package/dist/commands/agent/runner.js +165 -0
  19. package/dist/commands/agent/runner.js.map +1 -0
  20. package/dist/commands/audit/index.js +4 -0
  21. package/dist/commands/audit/index.js.map +1 -1
  22. package/dist/commands/auth/index.js +64 -7
  23. package/dist/commands/auth/index.js.map +1 -1
  24. package/dist/commands/automation/index.js +30 -0
  25. package/dist/commands/automation/index.js.map +1 -1
  26. package/dist/commands/backup/index.d.ts +12 -0
  27. package/dist/commands/backup/index.js +459 -0
  28. package/dist/commands/backup/index.js.map +1 -0
  29. package/dist/commands/cms/content-ops.js +1 -1
  30. package/dist/commands/cms/content-ops.js.map +1 -1
  31. package/dist/commands/communication-preferences/index.js +207 -7
  32. package/dist/commands/communication-preferences/index.js.map +1 -1
  33. package/dist/commands/content-permissions/index.d.ts +22 -0
  34. package/dist/commands/content-permissions/index.js +141 -0
  35. package/dist/commands/content-permissions/index.js.map +1 -0
  36. package/dist/commands/context/index.d.ts +3 -0
  37. package/dist/commands/context/index.js +182 -0
  38. package/dist/commands/context/index.js.map +1 -0
  39. package/dist/commands/crm/associations.js +38 -0
  40. package/dist/commands/crm/associations.js.map +1 -1
  41. package/dist/commands/crm/custom-objects.js +39 -2
  42. package/dist/commands/crm/custom-objects.js.map +1 -1
  43. package/dist/commands/crm/dated.js +3 -3
  44. package/dist/commands/crm/dated.js.map +1 -1
  45. package/dist/commands/crm/migration.js +210 -2
  46. package/dist/commands/crm/migration.js.map +1 -1
  47. package/dist/commands/crm/properties.js +2 -1
  48. package/dist/commands/crm/properties.js.map +1 -1
  49. package/dist/commands/crm/property-batch.d.ts +1 -0
  50. package/dist/commands/crm/property-batch.js +44 -5
  51. package/dist/commands/crm/property-batch.js.map +1 -1
  52. package/dist/commands/crm/shared.js +21 -2
  53. package/dist/commands/crm/shared.js.map +1 -1
  54. package/dist/commands/crm/sync.js +1 -1
  55. package/dist/commands/crm/sync.js.map +1 -1
  56. package/dist/commands/doctor/index.js +193 -0
  57. package/dist/commands/doctor/index.js.map +1 -1
  58. package/dist/commands/email-tracking/index.d.ts +16 -0
  59. package/dist/commands/email-tracking/index.js +314 -0
  60. package/dist/commands/email-tracking/index.js.map +1 -0
  61. package/dist/commands/extensions/index.js +1 -1
  62. package/dist/commands/extensions/index.js.map +1 -1
  63. package/dist/commands/forms/index.js +15 -2
  64. package/dist/commands/forms/index.js.map +1 -1
  65. package/dist/commands/forms/legacy-v2.d.ts +7 -2
  66. package/dist/commands/forms/legacy-v2.js +103 -7
  67. package/dist/commands/forms/legacy-v2.js.map +1 -1
  68. package/dist/commands/guide/index.d.ts +1 -1
  69. package/dist/commands/guide/index.js +37 -4
  70. package/dist/commands/guide/index.js.map +1 -1
  71. package/dist/commands/internal/catalog.d.ts +1 -0
  72. package/dist/commands/internal/catalog.js +2 -0
  73. package/dist/commands/internal/catalog.js.map +1 -0
  74. package/dist/commands/internal/index.d.ts +26 -0
  75. package/dist/commands/internal/index.js +823 -0
  76. package/dist/commands/internal/index.js.map +1 -0
  77. package/dist/commands/internal-session.d.ts +15 -0
  78. package/dist/commands/internal-session.js +152 -0
  79. package/dist/commands/internal-session.js.map +1 -0
  80. package/dist/commands/lists/index.js +1 -1
  81. package/dist/commands/lists/index.js.map +1 -1
  82. package/dist/commands/marketing/email-audit.d.ts +32 -0
  83. package/dist/commands/marketing/email-audit.js +121 -0
  84. package/dist/commands/marketing/email-audit.js.map +1 -0
  85. package/dist/commands/marketing/index.js +2 -0
  86. package/dist/commands/marketing/index.js.map +1 -1
  87. package/dist/commands/mcp.js +5 -3
  88. package/dist/commands/mcp.js.map +1 -1
  89. package/dist/commands/playbooks/index.d.ts +3 -0
  90. package/dist/commands/playbooks/index.js +228 -0
  91. package/dist/commands/playbooks/index.js.map +1 -0
  92. package/dist/commands/portals/index.d.ts +3 -0
  93. package/dist/commands/portals/index.js +132 -0
  94. package/dist/commands/portals/index.js.map +1 -0
  95. package/dist/commands/reports/index.d.ts +3 -0
  96. package/dist/commands/reports/index.js +479 -0
  97. package/dist/commands/reports/index.js.map +1 -0
  98. package/dist/commands/sales-content/index.d.ts +13 -0
  99. package/dist/commands/sales-content/index.js +59 -0
  100. package/dist/commands/sales-content/index.js.map +1 -0
  101. package/dist/commands/sales-templates/index.d.ts +3 -0
  102. package/dist/commands/sales-templates/index.js +88 -0
  103. package/dist/commands/sales-templates/index.js.map +1 -0
  104. package/dist/commands/seed/cms.js +28 -45
  105. package/dist/commands/seed/cms.js.map +1 -1
  106. package/dist/commands/sequences/index.d.ts +18 -0
  107. package/dist/commands/sequences/index.js +263 -0
  108. package/dist/commands/sequences/index.js.map +1 -0
  109. package/dist/commands/settings/index.js +450 -102
  110. package/dist/commands/settings/index.js.map +1 -1
  111. package/dist/commands/settings/site-settings.d.ts +3 -0
  112. package/dist/commands/settings/site-settings.js +106 -0
  113. package/dist/commands/settings/site-settings.js.map +1 -0
  114. package/dist/commands/ui/index.js +14 -4
  115. package/dist/commands/ui/index.js.map +1 -1
  116. package/dist/commands/workflows/index.js +2 -0
  117. package/dist/commands/workflows/index.js.map +1 -1
  118. package/dist/commands/workflows/preflight.d.ts +23 -0
  119. package/dist/commands/workflows/preflight.js +295 -0
  120. package/dist/commands/workflows/preflight.js.map +1 -0
  121. package/dist/core/action-contract.d.ts +43 -0
  122. package/dist/core/action-contract.js +207 -0
  123. package/dist/core/action-contract.js.map +1 -0
  124. package/dist/core/auth.d.ts +6 -0
  125. package/dist/core/auth.js +85 -0
  126. package/dist/core/auth.js.map +1 -1
  127. package/dist/core/http.d.ts +8 -0
  128. package/dist/core/http.js +37 -5
  129. package/dist/core/http.js.map +1 -1
  130. package/dist/core/id-maps.d.ts +27 -0
  131. package/dist/core/id-maps.js +204 -0
  132. package/dist/core/id-maps.js.map +1 -0
  133. package/dist/core/output.d.ts +2 -1
  134. package/dist/core/output.js +34 -0
  135. package/dist/core/output.js.map +1 -1
  136. package/dist/mcp/profiles.d.ts +14 -0
  137. package/dist/mcp/profiles.js +68 -0
  138. package/dist/mcp/profiles.js.map +1 -0
  139. package/dist/mcp/server.d.ts +5 -3
  140. package/dist/mcp/server.js +22 -5
  141. package/dist/mcp/server.js.map +1 -1
  142. package/docs/CAPABILITY_LIBRARY.md +29 -8
  143. package/docs/COMMAND_TREE.md +99 -17
  144. package/docs/COMPARISON.md +8 -5
  145. package/docs/COOKBOOK.md +124 -5
  146. package/docs/INTERNAL-ENDPOINTS-DISCOVERY.md +813 -0
  147. package/docs/INTERNAL-ENDPOINTS.md +371 -0
  148. package/docs/INTERNAL_ENDPOINTS.md +243 -0
  149. package/docs/MARKETING_SETUP.md +21 -1
  150. package/docs/MCP.md +28 -89
  151. package/docs/MCP_TOOL_CATALOG.md +192 -0
  152. package/docs/MIGRATION_ADAPTERS.md +115 -0
  153. package/docs/PORTAL_BACKUP.md +212 -0
  154. package/docs/PUBLISHING.md +1 -1
  155. package/docs/SALES_CONTENT_INTERNAL_PUNCH_LIST.md +504 -0
  156. package/docs/TUTORIALS/secure-agent-writes.md +49 -0
  157. package/docs/WHY_HOW_WHAT.md +10 -4
  158. package/package.json +4 -2
@@ -1,6 +1,6 @@
1
1
  # COMMAND_TREE
2
2
 
3
- > Updated: 2026-04-17 for 0.3.0
3
+ > Updated: 2026-07-10 for 0.9.1
4
4
  > See also: [COMMAND_COMPATIBILITY.md](COMMAND_COMPATIBILITY.md) · [ARCHITECTURE.md](ARCHITECTURE.md) · [MCP.md](MCP.md)
5
5
 
6
6
  High-level map of every hscli command. For detailed args and examples per command, run `hscli <domain> <cmd> --help`.
@@ -8,7 +8,7 @@ High-level map of every hscli command. For detailed args and examples per comman
8
8
  ## Global flags (apply to every command)
9
9
 
10
10
  - `--profile <name>` — Auth profile (default: `default`)
11
- - `--json` / `--format <table|csv|yaml|json>` — Output format
11
+ - `--json` / `--format <table|csv|yaml|json|jsonl>` — Output format (`jsonl` streams one compact envelope per result)
12
12
  - `--dry-run` — Simulate without mutating
13
13
  - `--force` — Required for live writes / deletes
14
14
  - `--policy-file <path>` — Load write/delete policy
@@ -25,29 +25,63 @@ High-level map of every hscli command. For detailed args and examples per comman
25
25
  - `hscli auth logout [--profile <name>]`
26
26
  - `hscli auth profiles` — list profiles
27
27
  - `hscli auth profile-show [--profile <name>]`
28
+ - `hscli auth whoami` — show profile, auth mode, portal/user identity, scopes, routing, and expiry without secrets
28
29
  - `hscli auth token-info`
29
30
  - `hscli auth set-mode <profile> read-only|read-write`
30
31
  - `hscli auth set-hublet <profile> <hublet>` — persist hublet-aware API routing
31
32
  - `hscli auth oauth-url --client-id <id> --redirect-uri <uri> --scope <scopes>`
32
- - `hscli auth oauth-exchange --client-id <id> --client-secret <secret> --redirect-uri <uri> --code <code>`
33
+ - `hscli auth oauth-exchange --client-id <id> --client-secret-env <env> --redirect-uri <uri> --code <code>`
34
+ - `hscli auth refresh [--profile <name>]` — refresh an OAuth profile immediately; normal requests refresh automatically before expiry
33
35
  - `hscli auth vault-encrypt` | `vault-decrypt` | `vault-rotate` — encrypted token vault
34
36
 
35
37
  ## Doctor
36
38
 
37
39
  - `hscli doctor capabilities [--refresh]` — probe portal tier + scopes
40
+ - `hscli doctor parity` — summarize hscli coverage across public API, internal-adapter, hybrid, and UI-only HubSpot surfaces
38
41
  - `hscli doctor scopes list|presets|explain|diff` — local HubSpot scope catalog and preset diffing
39
42
 
40
43
  ## Guide
41
44
 
42
45
  - `hscli ui` / `hscli home` — terminal home for profile context, safety state, next action, and operator workflows
43
- - `hscli guide [--goal portal-migration|setup|read|fetch|write|guardrails|property-preflight|audit-trace|explore]` — guided workflows for common operator tasks
46
+ - `hscli guide [--goal portal-migration|portal-backup|setup|read|fetch|write|guardrails|property-preflight|audit-trace|explore]` — guided workflows for common operator tasks
44
47
  - `hscli /migration` — portal/schema migration workflow
48
+ - `hscli /backup` — 360-degree portal backup workflow
45
49
  - `hscli /setup` — auth, hublet routing, scopes, and capability setup
46
50
  - `hscli /read` — safe source-portal read workflow
47
51
  - `hscli /fetch` / `hscli /get` — get records or metadata without mutating the portal
48
52
  - `hscli /write` — target-portal write workflow with dry-run + trace
49
53
  - `hscli /guardrails` — policy, read-only, trace, and scope checks
50
54
 
55
+ ## Agent
56
+
57
+ - `hscli agent list` — list deterministic operator recipes (`portal-baseline`, `data-cleanup`, `pipeline-risk`, `automation-risk`)
58
+ - `hscli agent plan <recipe>` — render a public-API-first, audit-friendly runbook without executing HubSpot requests
59
+ - `hscli agent run <recipe> [--output <dir>] [--resume] [--continue-on-error]` — execute a read-only runbook into a resumable local evidence directory
60
+ - `hscli agent evidence export <run-directory> [--output <file>]` — create signed aggregate-only `revfleet.hscli-evidence/v1` JSON; raw steps and identities remain local
61
+ - `hscli agent evidence submit <run-directory> [--backend-url <origin>] [--api-key-env <name>]` — submit signed aggregate evidence to an explicit RevFleet origin (`REVFLEET_BACKEND_URL` is the fallback); does not create a full scan score
62
+ - `hscli agent schedule render <recipe> [--target cron|github-actions|launchd] [--cron "0 8 * * 1"]` — render a schedule artifact; does not install it
63
+
64
+ ## Context
65
+
66
+ - `hscli context build [--sample-limit 1..100]` — read a small public-API portal profile for agent/runbook context: portal metadata, owners, teams, workflows, CRM sample totals, profile classification, recommended runbooks, and operator questions. Read-only.
67
+
68
+ ## Portals
69
+
70
+ - `hscli portals list` — local inventory of auth profiles/portal metadata without exposing tokens or calling HubSpot
71
+ - `hscli portals plan [--profiles live,sandbox] [--runbook data-cleanup|pipeline-risk|automation-risk] [--include-context] [--sample-limit 1..100]` — render explicit per-profile context/runbook commands. Plan-only: no HubSpot requests.
72
+
73
+ ## Backup
74
+
75
+ - `hscli backup plan --portal-id <id> [--out-dir <path>] [--include-internal] [--internal-mode claude-extension|browser-session|manual]` — render a HubSpot 360 downgrade/migration backup runbook. Plan-only: no HubSpot requests, no local file writes.
76
+
77
+ ## Internal Capture
78
+
79
+ - `hscli internal surfaces` — list allowlisted browser-session capture surfaces and guardrails. No HubSpot requests.
80
+ - `hscli internal coverage` — summarize the internal endpoint docs, allowlisted capture surface counts, read-like POST counts, parameterized endpoints, and promotion policy for future guarded write/replay adapters. No HubSpot requests.
81
+ - `hscli internal capture --surface <id> --portal-id <id> --cookie-file <file> --out-dir <dir>` — capture one allowlisted internal surface to JSON plus `capture-manifest.json`.
82
+ - `hscli internal capture --surface <id> --endpoint <endpoint-id> --body-file <endpoint-id=path> --portal-id <id> --cookie-file <file> --out-dir <dir>` — capture one allowlisted read-only POST/search/RPC endpoint with an explicit JSON body and request-body hash proof.
83
+ - `hscli internal capture --all --portal-id <id> --cookie-file <file> --out-dir <dir>` — capture every allowlisted endpoint that has enough inputs; placeholder/body-heavy endpoints are skipped into the manifest.
84
+
51
85
  ## CRM (23 sub-command files)
52
86
 
53
87
  Objects:
@@ -55,14 +89,14 @@ Objects:
55
89
  - `hscli crm quotes|products|line-items|goals list|get|search|create|update|delete [...]`
56
90
  - `hscli crm payments|invoices|subscriptions list|get [...]` — commerce
57
91
  - `hscli crm custom-objects schemas list|get|create|update|delete`
58
- - `hscli crm custom-objects records list|get|search|create|update|delete`
92
+ - `hscli crm custom-objects records list|get|search|create|update|delete|batch-read|batch-create|batch-update|batch-archive`
59
93
  - `hscli crm engagements (notes|calls|tasks|emails|meetings) list|get|create|update|delete`
60
94
  - `hscli crm activities export <objectType> <recordId>` — export recoverable record activities: engagements, memberships, selected property history
61
95
 
62
96
  Properties + pipelines + associations:
63
97
  - `hscli crm properties list|get|create|batch-create|update|delete` + `hscli crm properties groups list|create|update|delete`
64
98
  - `hscli crm pipelines list|get|create|update|delete` + `hscli crm pipelines stages create|update|delete`
65
- - `hscli crm associations list|get|create|delete`
99
+ - `hscli crm associations list|batch-read|batch-create|create|delete`
66
100
  - `hscli crm owners list|get`
67
101
 
68
102
  Imports + sync + introspection:
@@ -76,6 +110,7 @@ Imports + sync + introspection:
76
110
 
77
111
  - `hscli marketing emails list|get|create|update|delete`
78
112
  - `hscli marketing emails stats <emailId>` — **per-email engagement metrics**
113
+ - `hscli marketing emails utm-audit [--active-only] [--max-pages n]` — **scan emails for manual utm_\* tags** (blast radius of switching source tracking to REWRITE_ALL)
79
114
  - `hscli marketing campaigns list|get|create|update|delete`
80
115
  - `hscli marketing ads accounts|campaigns list|get`
81
116
  - `hscli marketing social accounts|posts list|get`
@@ -86,19 +121,35 @@ Imports + sync + introspection:
86
121
  - `hscli marketing events list|get|create|update|delete`
87
122
  - `hscli marketing behavioral-events list|get|create|update`
88
123
 
89
- ## Sales (4 files)
124
+ ## Email tracking (browser-session)
125
+
126
+ Per-email open+click tracking via the internal edit-publish buffer — flips `disableAllTracking` on drafts **and** published/automated emails, bypassing the client-side REWRITE_ALL gate (no portal-wide UTM setting change needed). Needs `--cookie`/`--csrf`/`--portal-id`.
127
+
128
+ - `hscli email-tracking disable|enable --ids <ids>|--ids-file <path>` — turn open+click tracking off/on (dry-run/force gated; republishes published emails, no re-send)
129
+ - `hscli email-tracking status --ids <ids>` — read current `disableAllTracking` + publish state
130
+ - `hscli email-tracking gate` — explain the 5 site-settings conditions that gate the in-app toggle (read-only)
131
+ - `hscli email-tracking test-send --id <id> --to <addr> [--plain-text]` — send a test copy (no workflow enrollment)
132
+ - `hscli email-tracking resolve-link <url>` — resolve a `hubspotlinks.com/Ctc/…` link to its destination + UTM params
133
+
134
+ ## Sales (3 files)
90
135
 
91
136
  - `hscli sales sequences list|get|enrollments`
92
137
  - `hscli sales meetings list|get|create|update`
93
- - `hscli sales calling list|get`
94
- - `hscli sales goals list|get`
138
+ - `hscli sales calling settings|recordings list`
139
+
140
+ ## Sales Content Internal
141
+
142
+ - `hscli sales-content search` — internal browser-session discovery across sequences, templates, playbooks, documents, and snippets
143
+ - `hscli sequences list|get|create|delete|migrate` — internal full-fidelity sequence read/write/migration surface
144
+ - `hscli sales-templates list|get|usage|create` — internal sales-template read/write surface
145
+ - `hscli playbooks list|get|questions|create|update|delete|migrate` — internal playbook read/write/migration surface via Chirp RPC
95
146
 
96
147
  ## Service (4 files)
97
148
 
98
149
  - `hscli service conversations list|get|send-message`
99
150
  - `hscli service feedback list|get`
100
151
  - `hscli service chatflows list|get|create|update|delete`
101
- - `hscli service knowledge-base articles list|get|create|update|delete`
152
+ - `hscli service kb status`
102
153
  - `hscli service pipelines list|get|create|update`
103
154
 
104
155
  ## CMS
@@ -119,6 +170,10 @@ Imports + sync + introspection:
119
170
 
120
171
  - `hscli reporting dashboards list|get`
121
172
  - `hscli reporting reports list|get`
173
+ - `hscli reports pull object-fill-rate --object <type> [--properties <csv>]`
174
+ - `hscli reports pull property-distribution --object <type> --property <name>`
175
+ - `hscli reports pull email-recipients --campaign-ids <ids> [--event-types <csv>] [--contact-properties <csv>]` — uses contact `email` as an internal enrichment key, but only emits requested contact properties
176
+ - `hscli reports pull source-target-parity --source-profile <profile> --target-profile <profile> --objects <csv>`
122
177
 
123
178
  ## Exports
124
179
 
@@ -127,10 +182,18 @@ Imports + sync + introspection:
127
182
 
128
183
  ## Settings
129
184
 
130
- - `hscli settings users list|get|create|update|delete` + `roles list`
185
+ - `hscli settings users list|get|create|update|delete` + `roles list` — `create` suppresses invite emails unless `--allow-invite-email` is passed
131
186
  - `hscli settings teams list`
132
- - `hscli settings permission-sets list|get|create|update|delete` — internal session-auth endpoint
133
- - `hscli settings business-units list`
187
+ - `hscli settings permission-sets list|get|create|update|delete|clone` — internal session-auth endpoint
188
+ - `hscli settings permission-sets users list|get|batch-read|assign|assign-batch` — internal app-users payloads and permission-set assignments
189
+ - `hscli settings permission-sets assignments list` — portal-wide user-to-permission-set assignment map
190
+ - `hscli settings permission-sets roles list|get` + `role-categories` + `scopes` — atomic role catalog and scope buckets used by permission sets
191
+ - `hscli settings permission-sets audit assignment-history|role-change-history|user-access --data <json>` — allowlisted permission audit Chirp RPCs
192
+ - `hscli settings permission-sets seats` + `seat-assignments list|update` — seat catalog and user seat assignments
193
+ - `hscli settings permission-sets templates list|get|create` — HubSpot/custom permission templates
194
+ - `hscli settings flp list|object|property|access-state|blocklist|bypass-users` — internal field-level permission inventory
195
+ - `hscli settings business-units list|capture|create-internal` — public list plus internal session-auth capture/create for full BU metadata
196
+ - `hscli settings site-settings get [--full]|set --key <k> --value <v>` — portal CMS/email site settings (source-tracking / UTM mode, identity + click tracking) via internal session-auth; `set` is allowlisted to tracking keys + guarded
134
197
  - `hscli settings currencies list`
135
198
  - `hscli settings gdpr delete-contact <id>`
136
199
  - `hscli settings audit-logs list [--filters]`
@@ -142,9 +205,18 @@ Imports + sync + introspection:
142
205
  - `hscli account private-apps` — **list private apps installed (integration audit)**
143
206
  - `hscli account api-usage` — daily API usage totals
144
207
 
208
+ ## Internal Adapters
209
+
210
+ - `hscli doctor internal-adapters` — list allowlisted browser-session setup/migration adapters. hscli intentionally does not expose a generic internal API passthrough.
211
+ - Browser-session adapters only accept HubSpot app hosts for `--ui-domain` and filter cookie-file exports to that host before sending cookies.
212
+
145
213
  ## Communication preferences
146
214
 
147
- - `hscli communication-preferences status|definitions|update`
215
+ - `hscli communication-preferences subscription-types` — legacy alias for definitions list
216
+ - `hscli communication-preferences definitions list|create` — public read + guarded replay helper with `--business-unit-map`; public definition create may return HTTP 405 on real portals
217
+ - `hscli communication-preferences definitions create-internal` — browser-session migration adapter for Email > Subscription Types creation; rejects non-Email channels
218
+ - `hscli communication-preferences status|subscribe|unsubscribe`
219
+ - `hscli communication-preferences v4 status-batch-read|status-update-batch|subscribe-batch|unsubscribe-batch|subscriptions-list|channels-list`; `subscriptions-list` reads `/communication-preferences/v4/definitions`
148
220
 
149
221
  ## Conversations
150
222
 
@@ -160,12 +232,15 @@ Imports + sync + introspection:
160
232
 
161
233
  ## Workflows
162
234
 
163
- - `hscli workflows flows list|get` + `actions list|get` + `sequences list|get`
235
+ - `hscli workflows preflight --data <payload> [--id-map-dir <dir>] [--strict]` check replay payloads for unresolved source IDs
236
+ - `hscli workflows flows list|get|create|update|enable|disable`
237
+ - `hscli workflows v3 list|get|create|delete|enroll|unenroll|enrollments`
238
+ - `hscli workflows id-map <id>` — resolve v3 workflowId ↔ v4 flowId
164
239
 
165
240
  ## Files + Forms + Domains + Site-search + Timeline
166
241
 
167
242
  - `hscli files list|get|upload|delete`
168
- - `hscli forms list|get|create|update|translate-v2|submissions list`
243
+ - `hscli forms list|get|create|update|translate-v2|submissions list` — legacy v2 translator supports property preflight, group splitting, and `--subscription-type-map`
169
244
  - `hscli domains list|get`
170
245
  - `hscli site-search list --type <type>`
171
246
  - `hscli timeline events list|create`
@@ -183,10 +258,17 @@ Imports + sync + introspection:
183
258
 
184
259
  ## MCP server
185
260
 
186
- - `hscli mcp` — start MCP server over stdio. ~125 tools across the full surface. Profile-isolated via `HSCLI_MCP_PROFILE`.
261
+ - `hscli mcp [--surface minimal|crm|migration|full]` — start the profile-isolated stdio MCP server. Defaults to 29 essential tools; `full` exposes all 180 tools, including raw API access. Use `HSCLI_MCP_PROFILE` and `HSCLI_MCP_SURFACE` when the client cannot pass flags.
187
262
 
188
263
  Full tool catalog and Claude Desktop / Cursor config in [MCP.md](MCP.md).
189
264
 
265
+ ## Agent runbooks
266
+
267
+ - `hscli agent run portal-baseline --output <dir> [--continue-on-error]` — first-run evidence bundle covering identity, capabilities, users, teams, deal pipelines, CRM data readiness, workflows, and request telemetry.
268
+ - `hscli agent run data-cleanup|pipeline-risk|automation-risk --output <dir>` — focused recurring evidence runbooks.
269
+ - `hscli agent plan <recipe>` — render exact commands without calling HubSpot.
270
+ - `hscli agent contract create|inspect|verify|apply` — seal and verify approved write argument arrays; execution still requires `--execute` plus global `--force`.
271
+
190
272
  ## Seed (dev + testing)
191
273
 
192
274
  - `hscli seed --all [--dry-run]` — seed a test portal with the 48-asset baseline
@@ -2,11 +2,14 @@
2
2
 
3
3
  A factual inventory of what `hscli` exposes via its CLI and MCP server surface, and the HubSpot operations it covers. No comparisons, no marketing framing — just what's in the box.
4
4
 
5
- Last updated: 2026-04-22 (v0.8.0)
5
+ Last updated: 2026-07-09 (v0.9.0)
6
6
 
7
7
  ## MCP tool surface
8
8
 
9
- `hscli mcp` exposes two tool families over stdio:
9
+ `hscli mcp` exposes native, HubSpot-compatible, and hscli extension tool
10
+ families over stdio. Registration is filtered through the `minimal`, `crm`,
11
+ `migration`, or `full` surface; see the generated
12
+ [MCP tool catalog](MCP_TOOL_CATALOG.md) for the authoritative 180-tool matrix.
10
13
 
11
14
  ### Native tool family (per-object)
12
15
 
@@ -118,8 +121,8 @@ Per-endpoint tier mapping: [docs/TIERS.md](TIERS.md).
118
121
  | Method | Supported | Notes |
119
122
  |---|:---:|---|
120
123
  | HubSpot Private App token | ✅ | Primary. Scriptable / machine-to-machine / CI. |
121
- | OAuth authorization code | Partial | Available for developer apps via `hscli auth login --oauth` |
122
- | OAuth refresh-token rotation | ✅ | Persisted in `~/.revfleet/auth.json` (or encrypted `auth.enc`) |
124
+ | OAuth authorization code | | Available for developer apps via `hscli auth oauth-url` + `hscli auth oauth-exchange` |
125
+ | OAuth refresh-token rotation | ✅ | Automatic before expiry; persisted in `~/.revfleet/auth.json` (or encrypted `auth.enc`) |
123
126
  | Legacy `hapikey` | ❌ | Retired by HubSpot (June 2023) |
124
127
 
125
128
  ## Safety model
@@ -128,7 +131,7 @@ Per-endpoint tier mapping: [docs/TIERS.md](TIERS.md).
128
131
  - **Policy-as-code.** `--policy-file <path>` (or `HSCLI_POLICY_FILE`) evaluates rules with method + path globs, time windows (tz-aware), change-ticket requirements, approval gates. See [docs/POLICY_EXAMPLE.json](POLICY_EXAMPLE.json).
129
132
  - **Change tickets.** `--change-ticket <id>` required by policy for guarded writes; value is written to telemetry.
130
133
  - **Path scope allowlisting.** All requests must resolve to an approved HubSpot API path root; traversal is rejected.
131
- - **Idempotency keys.** Every write includes an `Idempotency-Key` header for replay-safe retries.
134
+ - **Retry correlation.** Writes reuse one correlation key across retries. Native idempotency is relied on only for endpoints that document it; action contracts plus read-only verification protect broader write flows.
132
135
  - **Token redaction.** Bearer tokens, `token=`, `api_key=`, and `Authorization:` values are scrubbed from every output and error payload.
133
136
  - **Rate-limit awareness.** Reads HubSpot's `X-HubSpot-RateLimit-*` headers; proactive throttling + daily quota reset in the portal's declared timezone.
134
137
  - **Capability probing.** Endpoints are fingerprinted by `portalId + scopes`; `--strict-capabilities` fails fast on unsupported endpoints before issuing a network call.
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
@@ -815,6 +863,76 @@ hscli /write
815
863
  hscli /guardrails
816
864
  ```
817
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
+
818
936
  ### Check hublet configuration consistency
819
937
 
820
938
  Verifies that hscli's detected hublet, token prefix, and `@hubspot/cli` config all agree:
@@ -850,6 +968,7 @@ All commands support `--format` and `--json` flags.
850
968
 
851
969
  ```bash
852
970
  hscli crm contacts list --format json
971
+ hscli crm contacts list --format jsonl # one compact envelope per result
853
972
  hscli crm contacts list --format csv
854
973
  hscli crm contacts list --format yaml
855
974
  hscli crm contacts list --format table # default
@@ -873,8 +992,8 @@ hscli --telemetry-file ./telemetry.jsonl crm deals create --force \
873
992
  ### Manage staging and production side by side
874
993
 
875
994
  ```bash
876
- hscli auth login --token "pat-na1-staging-token" --profile staging
877
- 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
878
997
 
879
998
  # Read from staging
880
999
  hscli --profile staging crm contacts search --query "test"