@revfleet/hscli 0.7.1 → 0.8.2

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 (87) hide show
  1. package/CHANGELOG.md +139 -0
  2. package/LICENSE +1 -1
  3. package/README.md +118 -266
  4. package/SECURITY.md +2 -2
  5. package/dist/cli.js +25 -5
  6. package/dist/cli.js.map +1 -1
  7. package/dist/commands/api/index.d.ts +3 -0
  8. package/dist/commands/api/index.js.map +1 -1
  9. package/dist/commands/auth/index.js +6 -6
  10. package/dist/commands/auth/index.js.map +1 -1
  11. package/dist/commands/crm/companies.d.ts +3 -0
  12. package/dist/commands/crm/companies.js.map +1 -1
  13. package/dist/commands/crm/contacts.d.ts +3 -0
  14. package/dist/commands/crm/contacts.js.map +1 -1
  15. package/dist/commands/crm/custom-objects.d.ts +3 -0
  16. package/dist/commands/crm/custom-objects.js.map +1 -1
  17. package/dist/commands/crm/dated.d.ts +1 -1
  18. package/dist/commands/crm/dated.js +1 -1
  19. package/dist/commands/crm/deals.d.ts +3 -0
  20. package/dist/commands/crm/deals.js.map +1 -1
  21. package/dist/commands/crm/describe.d.ts +3 -0
  22. package/dist/commands/crm/describe.js.map +1 -1
  23. package/dist/commands/crm/engagements.d.ts +3 -0
  24. package/dist/commands/crm/engagements.js.map +1 -1
  25. package/dist/commands/crm/imports.d.ts +3 -0
  26. package/dist/commands/crm/imports.js.map +1 -1
  27. package/dist/commands/crm/owners.d.ts +3 -0
  28. package/dist/commands/crm/owners.js.map +1 -1
  29. package/dist/commands/crm/tickets.d.ts +3 -0
  30. package/dist/commands/crm/tickets.js.map +1 -1
  31. package/dist/commands/doctor/index.js +35 -35
  32. package/dist/commands/doctor/index.js.map +1 -1
  33. package/dist/commands/domains/shared.d.ts +3 -0
  34. package/dist/commands/domains/shared.js.map +1 -1
  35. package/dist/commands/events/index.d.ts +3 -0
  36. package/dist/commands/events/index.js.map +1 -1
  37. package/dist/commands/forms/index.d.ts +3 -0
  38. package/dist/commands/forms/index.js.map +1 -1
  39. package/dist/commands/legacy-v1/index.d.ts +1 -1
  40. package/dist/commands/legacy-v1/index.js +1 -1
  41. package/dist/commands/mcp.d.ts +3 -0
  42. package/dist/commands/mcp.js.map +1 -1
  43. package/dist/commands/seed/cms.js +19 -19
  44. package/dist/commands/seed/cms.js.map +1 -1
  45. package/dist/commands/seed/index.js +1 -1
  46. package/dist/commands/seed/index.js.map +1 -1
  47. package/dist/commands/seed/infra.js +14 -14
  48. package/dist/commands/seed/infra.js.map +1 -1
  49. package/dist/commands/seed/marketing.js +13 -13
  50. package/dist/commands/seed/marketing.js.map +1 -1
  51. package/dist/commands/webhooks/index.d.ts +3 -0
  52. package/dist/commands/webhooks/index.js.map +1 -1
  53. package/dist/commands/workflows/index.d.ts +3 -0
  54. package/dist/commands/workflows/index.js.map +1 -1
  55. package/dist/core/auth.d.ts +1 -1
  56. package/dist/core/auth.js +8 -25
  57. package/dist/core/auth.js.map +1 -1
  58. package/dist/core/capabilities.js +15 -15
  59. package/dist/core/capabilities.js.map +1 -1
  60. package/dist/core/http.js +3 -3
  61. package/dist/core/http.js.map +1 -1
  62. package/dist/core/output.d.ts +3 -0
  63. package/dist/core/output.js.map +1 -1
  64. package/dist/core/permissions.js +1 -1
  65. package/dist/core/permissions.js.map +1 -1
  66. package/dist/core/plugins.d.ts +2 -2
  67. package/dist/core/plugins.js +2 -2
  68. package/dist/core/plugins.js.map +1 -1
  69. package/dist/core/schema-cache.js +3 -3
  70. package/dist/core/schema-cache.js.map +1 -1
  71. package/dist/core/schemas.js +1 -1
  72. package/dist/core/schemas.js.map +1 -1
  73. package/dist/core/urls.d.ts +4 -4
  74. package/dist/core/urls.js +4 -4
  75. package/dist/core/vault.d.ts +5 -5
  76. package/dist/core/vault.js +14 -14
  77. package/dist/core/vault.js.map +1 -1
  78. package/dist/mcp/compat-hubspot.d.ts +34 -0
  79. package/dist/mcp/compat-hubspot.js +292 -0
  80. package/dist/mcp/compat-hubspot.js.map +1 -0
  81. package/dist/mcp/ext-tools.d.ts +24 -0
  82. package/dist/mcp/ext-tools.js +300 -0
  83. package/dist/mcp/ext-tools.js.map +1 -0
  84. package/dist/mcp/server.d.ts +38 -0
  85. package/dist/mcp/server.js +19 -10
  86. package/dist/mcp/server.js.map +1 -1
  87. package/package.json +4 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,144 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.8.2 - 2026-04-23
4
+
5
+ **Brand + polish release.** No runtime behavior changes for end users
6
+ beyond what CI already enforces — this is a pre-launch cut that ships
7
+ everything that's been on `main` since 0.8.1 alongside a consistent
8
+ visual identity and a codebase with zero "hubcli" references.
9
+
10
+ ### Visible change for `npm install -g` users
11
+
12
+ `hscli --help` now opens with the bracketed monogram banner:
13
+
14
+ ```
15
+ ┌──┐
16
+ │hs│ hscli · agentic HubSpot CLI + MCP server
17
+ └──┘ @revfleet/hscli · MIT · github.com/revfleet/hscli
18
+ ```
19
+
20
+ The banner matches the repo avatar and the `[hs]` monogram used on the
21
+ README hero + social preview. Same safety model, same command surface —
22
+ only the help-screen framing changes.
23
+
24
+ ### Documentation + repo polish
25
+
26
+ - **README** reworked with a confident headline ("Your HubSpot portal,
27
+ in one binary.") + three focused badges (npm · MIT · 1,180
28
+ endpoints). Progressive disclosure via a single `<details>` for the
29
+ full coverage list.
30
+ - **Brand identity** — `brand/` now contains the monogram, wordmark,
31
+ hero band, social preview (PNG + SVG), revfleet org avatar, and the
32
+ ASCII banner.
33
+ - **CODE_OF_CONDUCT.md** — Contributor Covenant v2.1 reference + a
34
+ short project-specific summary.
35
+ - **Doc cross-refs** — obsolete `[[wiki-link]]` style converted to real
36
+ markdown links throughout `docs/`. Dead `[[hubspot-rules]]`
37
+ references dropped.
38
+ - **POLICY_EXAMPLE.json** upgraded to the v2 schema introduced in
39
+ v0.7.0 (rule-based method+path globs, time windows, change-ticket +
40
+ approval gates).
41
+
42
+ ### Internal polish
43
+
44
+ - **ESLint** — stricter rules enabled: `eqeqeq` (safer for HubSpot IDs
45
+ that look numeric) and `prefer-const`.
46
+ - **Dependabot** — Monday schedule, labels for PR triage, TypeScript
47
+ major bumps excluded (manual triage, same pattern used for the 5→6
48
+ breakage).
49
+ - **`src/core/auth.ts`** — the `~/.hubcli/` legacy-fallback path was
50
+ dropped. The `getHubcliHomeDir` export alias was removed too.
51
+ Technically a breaking change for any external consumer that
52
+ imported the old name; none known to exist.
53
+ - **Release-checksums** script documented with a header comment.
54
+ - **Module headers** added to 17 command / core modules.
55
+
56
+ ### Privacy + scrub
57
+
58
+ - Package author field: `"Luigi Vermeulen (revfleet)"` → `"revfleet"`.
59
+ - Portal ID `147975758` removed from every code path where it
60
+ appeared as illustration or test fixture (replaced with `12345678`).
61
+ - Deleted `docs/TESTING/PORTAL-147975758-*.md` snapshot files.
62
+ - Deleted `docs/LAUNCH/` — four pre-launch marketing drafts with
63
+ named-competitor comparisons (Composio, peakmojo, lkm1developer,
64
+ CData, …) and CRMforge references. The repo now describes hscli on
65
+ its own terms only.
66
+ - Deleted `.hubcli-sync-contacts.json` (stale local state, last
67
+ touched 2026-03-19).
68
+
69
+ Git history was rewritten (49 commits, 10 tags repointed) so zero
70
+ "hubcli" references remain anywhere — code, docs, filenames, commit
71
+ messages, tags.
72
+
73
+ Tests: 255 pass. Typecheck + lint clean.
74
+
75
+ ## 0.8.1 - 2026-04-22
76
+
77
+ **Critical fix — globally-installed `hscli` binary was silent on all commands.**
78
+
79
+ The entry-point guard in `src/cli.ts` compared `import.meta.url` against
80
+ `resolve(process.argv[1])`, but `resolve()` does not follow symlinks.
81
+ A global npm install creates `~/.npm-global/bin/hscli` as a symlink into
82
+ `.../node_modules/@revfleet/hscli/dist/cli.js`; with the un-resolved
83
+ compare, the two paths never matched, so `run()` never fired and the
84
+ binary exited with code 0 and no output. Fix: resolve both sides with
85
+ `fs.realpathSync` and `fileURLToPath(import.meta.url)` before comparing.
86
+
87
+ This broke every `hscli <command>` invocation on every version since the
88
+ first publish (v0.5.3). It was masked locally because `npm run dev` /
89
+ `node dist/cli.js` don't go through the symlink. Anyone on npm installs
90
+ should upgrade immediately.
91
+
92
+ ## 0.8.0 - 2026-04-22
93
+
94
+ **MCP compatibility surface + extension tools.** HubSpot promoted their hosted Remote MCP server at `mcp.hubspot.com` to GA on 2026-04-13. This release makes `hscli mcp` a drop-in target for agents built against that surface, and adds a second tool family for everything HubSpot's hosted version doesn't cover.
95
+
96
+ ### New: HubSpot Remote MCP compatibility tools ([src/mcp/compat-hubspot.ts](src/mcp/compat-hubspot.ts))
97
+
98
+ All 11 tool names from `mcp.hubspot.com` are now registered on `hscli mcp`, with matching argument shapes and limits:
99
+
100
+ - `get_user_details`
101
+ - `search_crm_objects` (max 5 filter groups × 6 filters, max 200/page)
102
+ - `get_crm_objects` (max 100 IDs/call)
103
+ - `manage_crm_objects` — accepts `operation: "create" | "update" | "delete"`. **The `"delete"` operation is an hscli extension**; HubSpot's hosted version only supports create/update.
104
+ - `search_properties` (max 5 keywords)
105
+ - `get_properties`
106
+ - `search_owners` (max 100 results)
107
+ - `get_campaign_analytics`
108
+ - `get_campaign_contacts_by_type`
109
+ - `get_campaign_asset_types`
110
+ - `get_campaign_asset_metrics`
111
+
112
+ Result: an agent wired to HubSpot Remote MCP can swap its endpoint to `hscli mcp` without changing tool names or argument schemas, and gain `delete`, custom objects, and the full extension family below.
113
+
114
+ ### New: Extension MCP tools ([src/mcp/ext-tools.ts](src/mcp/ext-tools.ts))
115
+
116
+ Tools for surfaces HubSpot's hosted Remote MCP does not expose:
117
+
118
+ - **Workflows:** `workflows_list`, `workflows_get`, `workflows_enroll`, `workflows_unenroll`
119
+ - **Files:** `files_list`, `files_get`, `files_delete`, `files_signed_url`
120
+ - **Forms:** `forms_list`, `forms_get`, `forms_submissions`, `forms_submit`
121
+ - **Webhooks:** `webhooks_list_subscriptions`, `webhooks_create_subscription`, `webhooks_delete_subscription`
122
+ - **Marketing emails:** `marketing_emails_list`, `marketing_emails_get`, `marketing_emails_statistics`
123
+ - **HubDB:** `hubdb_tables_list`, `hubdb_rows_list`, `hubdb_row_create`, `hubdb_row_update`, `hubdb_publish`
124
+ - **CMS URL redirects:** `cms_redirects_list`, `cms_redirects_create`, `cms_redirects_delete`
125
+ - **Conversations:** `conversations_inboxes_list`, `conversations_threads_list`, `conversations_messages_send`
126
+
127
+ All of these already shipped in the CLI surface — this release makes them first-class MCP tools.
128
+
129
+ ### Docs
130
+
131
+ - **[docs/COMPARISON.md](docs/COMPARISON.md)** — factual inventory of `hscli`'s MCP + CLI surface and the HubSpot API coverage it ships with. No competitive framing — just what's in the box.
132
+ - **[docs/ROADMAP-DATE-BASED-API.md](docs/ROADMAP-DATE-BASED-API.md)** — plan for migrating from `/v3/` to `/YYYY-MM/` endpoints following HubSpot's April 2026 announcement. 3-phase opt-in rollout across v0.8 → v1.0.
133
+ - **[docs/PUBLISHING.md](docs/PUBLISHING.md)** — release runbook, including the passkey-based npm publish gotcha.
134
+
135
+ ### Tests
136
+
137
+ - **[tests/mcp.compat.test.ts](tests/mcp.compat.test.ts)** (15 tests) — every compat tool: catalog, argument shapes, HubSpot limits (filterGroups ≤ 5, IDs ≤ 100, keywords ≤ 5), path routing, `manage_crm_objects` dry-run default + hscli delete extension.
138
+ - **[tests/mcp.ext.test.ts](tests/mcp.ext.test.ts)** (17 tests) — catalog + routing + dry-run defaults across the extension family.
139
+
140
+ Full suite: 256 pass / 10 skipped (sandbox opt-in) / 0 fail.
141
+
3
142
  ## 0.7.1 - 2026-04-22
4
143
 
5
144
  **Stabilization release.** Hardens v0.7.0 with a test suite, tutorials,
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 Luigi Vermeulen
3
+ Copyright (c) 2026 Revfleet
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,349 +1,201 @@
1
- # hscli
1
+ <p align="center">
2
+ <img src="brand/readme-hero.svg" alt="hscli — agentic HubSpot CLI + MCP server" width="100%">
3
+ </p>
2
4
 
3
- [![CI](https://github.com/revfleet/hscli/actions/workflows/ci.yml/badge.svg)](https://github.com/revfleet/hscli/actions/workflows/ci.yml)
4
- [![npm version](https://img.shields.io/npm/v/@revfleet/hscli.svg)](https://www.npmjs.com/package/@revfleet/hscli)
5
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
6
- [![Node: >=20](https://img.shields.io/badge/Node-%3E%3D20-brightgreen)](package.json)
7
- [![HubSpot API coverage: 100%](https://img.shields.io/badge/HubSpot%20API-100%25%20(1180%20endpoints)-7c3aed)](docs/TIERS.md)
5
+ <p align="center">
6
+ <strong>Your HubSpot portal, in one binary.</strong>
7
+ </p>
8
8
 
9
- **The headless HubSpot CLI + MCP server. 100% public API coverage (1,180 endpoints, 55+ command domains), enterprise safety rails, self-hosted.**
9
+ <p align="center">
10
+ <a href="https://www.npmjs.com/package/@revfleet/hscli"><img src="https://img.shields.io/npm/v/@revfleet/hscli.svg?style=flat-square&color=22D3EE&labelColor=0F172A" alt="npm"></a>
11
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-22D3EE?style=flat-square&labelColor=0F172A" alt="MIT"></a>
12
+ <a href="docs/TIERS.md"><img src="https://img.shields.io/badge/HubSpot%20API-1%2C180%20endpoints-22D3EE?style=flat-square&labelColor=0F172A" alt="1,180 HubSpot endpoints"></a>
13
+ </p>
10
14
 
11
- ## Get started in 30 seconds
15
+ <p align="center">
16
+ <img src="docs/demo-hubspot.gif" alt="hscli writing into a HubSpot portal in real time — records appear in the UI as hscli creates them" width="100%">
17
+ </p>
12
18
 
13
- ```bash
14
- # 1. Install
15
- npm install -g @revfleet/hscli
16
-
17
- # 2. Auth with a HubSpot Private App token (create one at
18
- # Settings → Integrations → Private Apps → Create private app)
19
- printf '%s' 'pat-eu1-XXXX-XXXX-XXXX' | hscli auth login --token-stdin
20
-
21
- # 3. Read
22
- hscli crm contacts list --limit 5
23
-
24
- # 4. Write (dry-run by default, --force to execute)
25
- hscli --force crm contacts create --data '{"properties":{"email":"jane@example.com"}}'
26
-
27
- # 5. Run as an MCP server for Claude Desktop, Cursor, Claude Code
28
- hscli mcp
29
- ```
30
-
31
- That's the whole thing. For the full picture of what's available, read on.
19
+ <p align="center">
20
+ <sub>↳ Live tour · terminal writes, HubSpot reflects · ~60s on a real portal.</sub>
21
+ </p>
32
22
 
33
23
  ---
34
24
 
35
- <details>
36
- <summary><strong>Full coverage map (55+ domains)</strong></summary>
37
-
38
- hscli gives you one TypeScript binary that covers **every** endpoint of HubSpot's public API surface — verified against a scrape of HubSpot's own dev docs (1,178 source files, 1,180 endpoints). Whether an endpoint actually returns data on *your* portal depends on the HubSpot tier you're on (see [docs/TIERS.md](docs/TIERS.md)). hscli exposes them all.
39
-
40
- - **Full CRM** — contacts, companies, deals, tickets, leads, quotes, products, line items, orders, carts, discounts, fees, taxes, invoices, subscriptions, payments, goals, communications, users, feedback-submissions, custom objects, properties (+ legacy v1/v2), pipelines, associations v4 (+ labels CRUD + dated 2025-09), owners, imports, exports, engagements (notes/tasks/calls/meetings), sync, describe/validate, timeline, CRM Cards (UI Extensions), filter + count primitives on every object
41
- - **Marketing** — emails (v3 + legacy v1, per-email stats), campaigns, ads, social, SEO, landing pages, transactional, subscriptions, events (+ attendance + participations), behavioral events, forms, form integrations, legacy email events stream (per-recipient)
42
- - **Sales** — sequences (+ enroll/unenroll), meetings, calling, goals, scheduler (meeting links, book/reschedule/cancel), sales extensions (videoconferencing, accounting)
43
- - **Service** — conversations (threads, messages, inboxes, channels, channel-accounts, actors, custom-channels), feedback, chatflows, knowledge-base, ticket pipelines, visitor-identification
44
- - **CMS** — site pages, landing pages (+ folders), blog posts (+ authors + tags + blog-settings), HubDB (tables, rows, drafts, publishing), URL redirects, source-code, domains, SEO audit, site search, topics, audit-logs, comments, legacy content/api/v2 (Pages, Layouts, Templates, Modules, UrlMappings)
45
- - **Settings** — users, teams, business units, currencies, GDPR, audit-logs, communication preferences (v3 + v4 batch)
46
- - **Account** — info, audit-logs, private-apps, API usage
47
- - **Operations** — lists (+ folders + memberships), reporting, exports, workflows (v4 + legacy v2/v3), automation custom actions, webhooks (subscriptions), timeline (templates + events + integrators)
48
- - **Commerce Hub** — quotes, products, line-items, invoices, subscriptions, payments, orders, carts, discounts, fees, taxes, payments-subscriptions, tax rates
49
- - **Developer Platform** — feature flags, CRM cards, integrators timeline, media bridge (properties + schemas + settings + events), extensions (calling + videoconferencing + accounting + sales)
50
- - **Legacy v1/v2** — contacts-v1, companies-v2, deals-v1, owners-v2, engagements-v1, properties-legacy, reports-v2, calling-v1, channels, broadcast, appinstalls, marketing-emails-v1
51
- - **Niche** — email events, email events per-recipient stream, submissions, visitor-identification, scheduler, tax, appinstalls, marketing-extras, owners-extras
52
- - **Raw API** command with path-scope controls + OAuth flow support
53
- - **Built-in MCP server** over stdio (140+ tools) for Claude Desktop, Cursor, Claude Code, any MCP client
54
-
55
- Enterprise-grade from day one: `--dry-run`, `--force`, policy files, change tickets, capability probing, rate-limit intelligence, token redaction, path scope allowlisting, idempotency keys.
56
-
57
- </details>
25
+ ## Why
58
26
 
27
+ 1,180 HubSpot endpoints, one TypeScript binary. Every write blocked unless you explicitly `--force` it. Every request auditable. Token stays on your machine. MCP-ready for Claude Desktop, Cursor, and any agent that speaks the protocol.
59
28
 
60
- ## What hscli focuses on
29
+ No SaaS middleman, no proprietary dashboard, no "download the CLI, then also install the desktop app". Just a CLI that respects production.
61
30
 
62
- 1. **CLI-first with MCP as a peer surface.** Every MCP tool has a matching `hscli` command — same write gates, same redaction, same capability probing in both.
63
- 2. **Self-hosted and token-sovereign.** Your HubSpot private app token stays on your machine.
64
- 3. **Safety gates by default.** `--dry-run`, `--force`, policy files, change tickets, path scope allowlisting, idempotency keys on every write.
65
- 4. **HubSpot-native engineering.** Reads HubSpot's `X-HubSpot-RateLimit-*` headers, proactive throttling, capability probing by `portalId + scopes`, offline schema validation.
66
-
67
- ## "100% coverage" — what that means
68
-
69
- hscli's coverage claim is precise: **every one of HubSpot's 1,180 documented public API endpoints has a corresponding CLI subcommand.** This is verified against an automated scrape of HubSpot's developer documentation (committed at [docs/TESTING/PORTAL-147975758-COVERAGE.md](docs/TESTING/PORTAL-147975758-COVERAGE.md) and [PORTAL-147975758-WRITES.md](docs/TESTING/PORTAL-147975758-WRITES.md)).
70
-
71
- It does **not** mean every endpoint returns 2xx on your portal — HubSpot tier-locks hundreds of endpoints behind paid plans:
72
-
73
- | Portal profile | Reachable endpoints (read + write) |
74
- |---|---:|
75
- | Free account | ~550 / 1180 (46.6%) |
76
- | Starter hubs | ~640 / 1180 (54.2%) |
77
- | Professional hubs | ~890 / 1180 (75.4%) |
78
- | Enterprise hubs (all) + Commerce + Ops | ~1140 / 1180 (96.6%) |
79
- | Developer App OAuth install | adds ~30 app-dev endpoints |
80
- | Legacy hapikey (pre-June-2023 accounts) | adds ~40 zombie endpoints |
81
-
82
- See [docs/TIERS.md](docs/TIERS.md) for the exact endpoint → tier mapping.
83
-
84
- **If an endpoint your portal should access doesn't work**, open an [endpoint issue](https://github.com/revfleet/hscli/issues/new?template=endpoint_not_working.md) — we triage these fast.
85
-
86
- ## Install
87
-
88
- From npm (once published):
31
+ ## Install & auth
89
32
 
90
33
  ```bash
91
34
  npm install -g @revfleet/hscli
92
- ```
93
-
94
- From source:
95
-
96
- ```bash
97
- git clone https://github.com/revfleet/hscli.git
98
- cd hscli
99
- npm install
100
- npm run build
101
- ```
102
-
103
- ## Quickstart
104
-
105
- Save a token (recommended — avoids shell history):
106
-
107
- ```bash
108
- printf '%s' '<HUBSPOT_PRIVATE_APP_TOKEN>' | hscli auth login --token-stdin
109
- ```
110
-
111
- Inline token (also supported):
112
-
113
- ```bash
114
- hscli auth login --token <HUBSPOT_PRIVATE_APP_TOKEN>
115
- ```
116
-
117
- Read:
118
-
119
- ```bash
35
+ printf '%s' 'pat-eu1-XXXX-XXXX-XXXX' | hscli auth login --token-stdin
120
36
  hscli crm contacts list --limit 5
121
- hscli marketing emails stats 123456
122
- hscli sales sequences list
123
- hscli reporting dashboards list
124
- hscli settings teams list
125
37
  ```
126
38
 
127
- Dry-run write:
39
+ Create a Private App token at **Settings → Integrations → Private Apps → Create private app** in your HubSpot portal.
40
+
41
+ ## Write safely
128
42
 
129
43
  ```bash
130
- hscli --dry-run crm contacts create --data '{"properties":{"email":"test@example.com"}}'
131
- ```
44
+ # Blocked writes need explicit intent
45
+ hscli crm contacts create --data '{"properties":{"email":"jane@acme.com"}}'
46
+ # → WRITE_CONFIRMATION_REQUIRED
132
47
 
133
- Live write (explicit):
48
+ # Preview what the call would look like
49
+ hscli --dry-run crm contacts create --data '{"properties":{"email":"jane@acme.com"}}'
134
50
 
135
- ```bash
136
- hscli --force crm contacts create --data '{"properties":{"email":"test@example.com"}}'
51
+ # Execute — with an Idempotency-Key baked in automatically
52
+ hscli --force crm contacts create --data '{"properties":{"email":"jane@acme.com"}}'
137
53
  ```
138
54
 
139
- Policy-guarded delete with change ticket:
55
+ Policy file + change-ticket enforcement for ops teams:
140
56
 
141
57
  ```bash
142
- hscli --force --policy-file docs/POLICY_EXAMPLE.json --change-ticket CHG-123 \
58
+ hscli --force --policy-file ./policy.json --change-ticket CHG-123 \
143
59
  crm contacts delete 123
144
60
  ```
145
61
 
146
- <details>
147
- <summary><strong>Policy-as-code (v0.7)</strong> — glob matching, time windows, approval gates, built-in templates</summary>
62
+ ## Run as an MCP server
148
63
 
149
- Policy files let ops define *what* an agent is allowed to do not just *whether* it can write. Rule matching is first-match-wins: method + path glob (`*` within a segment, `**` across segments), optional time window (`window.hours`, `window.days`, `window.tz`), optional change-ticket requirement, optional approval gate.
64
+ Drop `hscli` into any MCP clientClaude Desktop, Cursor, Claude Code, or your own agent runtime.
150
65
 
151
66
  ```bash
152
- # List built-in templates (read-only, no-deletes, business-hours, compliance-strict, change-ticket-required)
153
- hscli policy templates list
154
-
155
- # Copy a template to edit locally
156
- hscli policy templates extract no-deletes --to ./policy.json
67
+ hscli mcp
68
+ ```
157
69
 
158
- # Validate before shipping
159
- hscli policy validate ./policy.json
70
+ For Claude Desktop, add to `claude_desktop_config.json`:
160
71
 
161
- # Dry-run which rule would fire for a hypothetical request
162
- hscli --policy-file ./policy.json \
163
- policy show-matching DELETE /crm/v3/objects/contacts/123
72
+ ```json
73
+ {
74
+ "mcpServers": {
75
+ "hscli": {
76
+ "command": "hscli",
77
+ "args": ["mcp"],
78
+ "env": { "HSCLI_MCP_PROFILE": "default" }
79
+ }
80
+ }
81
+ }
164
82
  ```
165
83
 
166
- Enforcement is automatic once `--policy-file` is set (or `HSCLI_POLICY_FILE` env var). Error codes (`POLICY_RULE_DENY`, `POLICY_DEFAULT_DENY`, `POLICY_CHANGE_TICKET_REQUIRED`, `POLICY_APPROVAL_REQUIRED`, `POLICY_OUT_OF_WINDOW`) are machine-readable.
84
+ The MCP server exposes three tool families:
167
85
 
168
- Tutorial: [docs/TUTORIALS/secure-agent-writes.md](docs/TUTORIALS/secure-agent-writes.md).
86
+ - **Per-object tools** — `crm_contacts_list`, `crm_deals_create`, `crm_custom_records_search`, …
87
+ - **HubSpot Remote MCP compat** — same tool names as `mcp.hubspot.com` (`search_crm_objects`, `manage_crm_objects`, …) so agents built for HubSpot's hosted MCP drop in without changes
88
+ - **Extension surface** — workflows, files, forms, webhooks, HubDB, conversations, and more, all with the same `--force` + policy gates as the CLI
169
89
 
170
- </details>
171
-
172
- <details>
173
- <summary><strong>Trace + replay (v0.6+)</strong> — observability of every request, human + MCP</summary>
90
+ Every MCP tool call goes through the same safety rails as the CLI. Token redaction is enforced on every response. `HSCLI_MCP_PROFILE` locks the stdio server to one auth profile to prevent cross-tenant access.
174
91
 
175
- `hscli trace` records every request to a JSONL file — method, path, status, latency, profile, `toolName` (when invoked from an MCP tool), optional request/response bodies. Useful for reproducibility, regression detection between portals, debugging agent behavior.
92
+ ## Observability
176
93
 
177
94
  ```bash
178
- # Start recording to ~/.revfleet/trace-<ts>.jsonl (or pass --out)
179
- hscli trace start --include-bodies --scope all
180
-
181
- # Run anything. Every request appends.
182
- hscli crm contacts list
183
- hscli mcp # MCP requests tagged with toolName
184
-
185
- # Stop; the file stays, session state clears.
95
+ hscli trace start # start recording every request
96
+ hscli --force crm contacts create … # → appends to the trace JSONL
186
97
  hscli trace stop
187
98
 
188
- # Inspect
189
- hscli trace show ./trace-<ts>.jsonl --filter status=>=400
190
- hscli trace stats ./trace-<ts>.jsonl # p50/p95/p99 latency, method breakdown
191
- hscli trace errors ./trace-<ts>.jsonl # only errors
192
- hscli trace diff ./run-a.jsonl ./run-b.jsonl # detect reproducibility divergence
193
-
194
- # Replay GETs (safe-by-default: dry-run unless --force)
195
- hscli trace replay ./trace-<ts>.jsonl
99
+ hscli trace stats ./trace-*.jsonl # p50/p95/p99 latency, method breakdown
100
+ hscli trace diff ./run-a.jsonl ./run-b.jsonl # spot reproducibility drift
101
+ hscli audit writes --since 24h # who wrote what, when
102
+ hscli audit by-tool # per-MCP-tool call count + error rate
196
103
  ```
197
104
 
198
- Writes (`POST/PUT/PATCH/DELETE`) are intentionally not replayable to prevent accidental re-mutation.
105
+ Every request hscli makes is append-only JSONL. Pair `trace` with `audit` for full "who did what when" provenance — no extra infrastructure required.
199
106
 
200
- Tutorial: [docs/TUTORIALS/trace-replay-repro.md](docs/TUTORIALS/trace-replay-repro.md).
201
-
202
- </details>
107
+ ## What's in the box
203
108
 
204
109
  <details>
205
- <summary><strong>Audit (v0.7)</strong> — &ldquo;who did what when&rdquo; across every recorded session</summary>
206
-
207
- `hscli audit` reads trace JSONL files (single file or an entire directory of `trace-*.jsonl`) and answers operational audit questions. Pairs with `trace` for full provenance.
208
-
209
- ```bash
210
- hscli audit timeline --since 24h # chronological event list, last 24h
211
- hscli audit who alice --since 7d # what has profile 'alice' done?
212
- hscli audit what /crm/v3/objects/contacts --since 7d # who touched this path?
213
- hscli audit writes --since 24h # all writes in the last 24h (+ failures)
214
- hscli audit by-tool # per-MCP-tool call count, error rate, avg latency
215
- ```
216
-
217
- Tutorial: [docs/TUTORIALS/audit-portal-writes.md](docs/TUTORIALS/audit-portal-writes.md).
110
+ <summary><strong>Full surface coverage</strong> — click to expand</summary>
111
+
112
+ - **CRM** contacts, companies, deals, tickets, leads, quotes, products, line items, orders, carts, discounts, fees, taxes, invoices, subscriptions, payments, goals, communications, users, custom objects, properties, pipelines, associations v4, owners, imports, exports, engagements, sync, describe/validate, timeline, CRM Cards
113
+ - **Marketing** — emails (v3 + legacy v1), campaigns, ads, social, SEO, landing pages, transactional, subscriptions, events, behavioral events, forms
114
+ - **Sales** — sequences, meetings, calling, scheduler, sales extensions
115
+ - **Service** conversations, feedback, chatflows, knowledge-base, ticket pipelines, visitor-identification
116
+ - **CMS** site/landing/blog pages, HubDB, URL redirects, source-code, domains, SEO audit
117
+ - **Settings** users, teams, business units, currencies, GDPR, audit-logs, communication preferences
118
+ - **Operations** lists, reporting, exports, workflows (v4 + legacy), automation, webhooks, timeline
119
+ - **Commerce Hub** — quotes, products, line-items, invoices, subscriptions, payments, orders, carts, taxes
120
+ - **Developer Platform** — feature flags, CRM cards, integrators timeline, media bridge, extensions
121
+ - **Legacy v1/v2** — every pre-v3 surface preserved for portals that still need them
122
+ - **Raw API** command with path-scope controls + full OAuth flow support
123
+
124
+ Enterprise defaults: `--dry-run`, `--force`, policy files, change tickets, capability probing, rate-limit intelligence, token redaction, path scope allowlisting, idempotency keys on every write.
218
125
 
219
126
  </details>
220
127
 
221
- ## Output modes
222
-
223
- ```bash
224
- hscli --json crm companies list --limit 3 # JSON envelope
225
- hscli --format csv crm contacts list --limit 5 # CSV
226
- hscli --format yaml crm deals get 123 # YAML
227
- ```
228
-
229
- ## MCP: AI agents as first-class consumers
230
-
231
- hscli ships a built-in MCP server over stdio with ~125 tools exposing the full surface:
232
-
233
- ```bash
234
- hscli mcp
235
- ```
236
-
237
- For Claude Desktop, add to `claude_desktop_config.json`:
238
-
239
- ```json
240
- {
241
- "mcpServers": {
242
- "hscli": {
243
- "command": "hscli",
244
- "args": ["mcp"],
245
- "env": {
246
- "HSCLI_MCP_PROFILE": "default"
247
- }
248
- }
249
- }
250
- }
251
- ```
252
-
253
- Restart Claude. Now Claude can list contacts, search deals, inspect workflows, and — with `--force` passed at tool-call time — perform safe writes. All CLI safety rails apply to MCP calls. Secrets are redacted from every tool response. `HSCLI_MCP_PROFILE` locks the stdio server to one auth profile to prevent cross-tenant access.
128
+ ### What "1,180 endpoints" means
254
129
 
255
- See [docs/MCP.md](docs/MCP.md) for the full tool catalog.
130
+ Every one of HubSpot's documented public API endpoints has a corresponding CLI subcommand — verified against an automated scrape of HubSpot's developer documentation.
256
131
 
257
- ## Capability / tier awareness
132
+ It does **not** mean every endpoint returns 2xx on your portal. HubSpot tier-locks hundreds of endpoints behind paid plans:
258
133
 
259
- Probe portal capabilities and cache them by `portalId + scopes`:
134
+ | Portal profile | Reachable endpoints |
135
+ |---|---:|
136
+ | Free | ~550 / 1,180 (47%) |
137
+ | Starter | ~640 / 1,180 (54%) |
138
+ | Professional | ~890 / 1,180 (75%) |
139
+ | Enterprise (all hubs) + Commerce + Ops | ~1,140 / 1,180 (97%) |
260
140
 
261
- ```bash
262
- hscli doctor capabilities --refresh
263
- ```
141
+ Exact endpoint → tier mapping in [docs/TIERS.md](docs/TIERS.md).
264
142
 
265
- Fail fast when a command hits an unsupported endpoint:
143
+ ## Design principles
266
144
 
267
- ```bash
268
- hscli --strict-capabilities marketing emails list
269
- ```
145
+ 1. **CLI-first, MCP as a peer.** Every MCP tool has a matching `hscli` command — same write gates, same redaction, same capability probing in both.
146
+ 2. **Self-hosted, token-sovereign.** Your HubSpot private app token stays on your machine. No telemetry, no phone-home.
147
+ 3. **Safe by default.** Mutations are blocked unless `--force` is explicit. `--dry-run` previews every write. Idempotency-Key on every mutation.
148
+ 4. **HubSpot-native.** Reads `X-HubSpot-RateLimit-*` headers, throttles proactively, caches capabilities by `portalId + scopes`, validates payloads offline.
270
149
 
271
- ## Schema introspection + offline validation
150
+ ## Output modes
272
151
 
273
152
  ```bash
274
- hscli crm describe contacts --refresh-cache
275
- hscli crm validate contacts --offline --data '{"properties":{"email":"x@example.com"}}'
153
+ hscli --json crm companies list --limit 3 # JSON envelope
154
+ hscli --format csv crm contacts list --limit 5 # CSV
155
+ hscli --format yaml crm deals get 123 # YAML
156
+ hscli --format table crm contacts list --limit 5 # table (default)
276
157
  ```
277
158
 
278
- Local schema cache means you can validate payloads without hitting HubSpot.
159
+ ## Terminal session
279
160
 
280
- ## Runtime safety model
161
+ The HubSpot-UI recording at the top shows the *outcome*. Here's the *cause* — the same fixture built and torn down entirely from the shell:
281
162
 
282
- - Mutations are **blocked** unless `--force` is passed (or intercepted by `--dry-run`)
283
- - Write/delete can be constrained by policy (`--policy-file`) and change-ticket enforcement
284
- - Requests are origin-locked to `https://api.hubapi.com` and restricted to approved API path roots
285
- - Path segments are hardened against traversal / control characters
286
- - Output and error payloads are redacted for secrets and token-like strings
287
- - Transport retries transient failures with exponential backoff
288
- - Rate-limit controller reads `X-HubSpot-RateLimit-*` headers and throttles proactively
289
- - All write / batch methods include `Idempotency-Key` for replay-safe retries
163
+ <p align="center">
164
+ <img src="docs/demo-terminal.gif" alt="hscli terminal walkthrough blank create associate → read → update → archive → blank" width="100%">
165
+ </p>
290
166
 
291
- Full threat model: [SECURITY.md](SECURITY.md).
167
+ [Source script](scripts/demo.sh) · [recording config](scripts/demo.tape) · [how the recordings are made](scripts/README.md)
292
168
 
293
169
  ## Caches
294
170
 
295
- Under `HSCLI_HOME` (default: `~/.revfleet`; legacy `~/.hubcli` is still honored for existing installs):
171
+ Under `HSCLI_HOME` (default: `~/.revfleet`):
296
172
 
297
- - `auth.json` — profile tokens (0600 permissions, 0700 directory)
173
+ - `auth.json` — profile tokens (0600, in a 0700 directory)
174
+ - `auth.enc` — optional encrypted vault when `HSCLI_VAULT_PASSPHRASE` is set
298
175
  - `capabilities.json` — portal/tier capability cache
299
- - `schema-cache.json` — CRM schema cache for describe/validate
300
- - `auth.enc` optional encrypted vault (when passphrase is set)
301
- - `trace-session.json` — active trace session state (v0.6+)
302
- - `trace-*.jsonl` — recorded request traces (v0.6+)
176
+ - `schema-cache.json` — CRM schema cache for describe / validate
177
+ - `trace-session.json` + `trace-*.jsonl` active trace + recorded sessions
303
178
 
304
179
  ## Documentation
305
180
 
306
181
  - [docs/COMMAND_TREE.md](docs/COMMAND_TREE.md) — full command surface
307
- - [docs/WHY_HOW_WHAT.md](docs/WHY_HOW_WHAT.md) — design philosophy
308
- - [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)
309
- - [docs/SAFETY_MODEL.md](docs/SAFETY_MODEL.md)
182
+ - [docs/COMPARISON.md](docs/COMPARISON.md) — MCP tool families, CLI groups, coverage, safety, observability
310
183
  - [docs/MCP.md](docs/MCP.md) — MCP server tool catalog
311
- - [docs/TESTING_PLAN.md](docs/TESTING_PLAN.md)
312
- - [docs/RELEASE_GOVERNANCE.md](docs/RELEASE_GOVERNANCE.md)
184
+ - [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) · [docs/SAFETY_MODEL.md](docs/SAFETY_MODEL.md) · [docs/WHY_HOW_WHAT.md](docs/WHY_HOW_WHAT.md)
185
+ - [docs/ROADMAP-DATE-BASED-API.md](docs/ROADMAP-DATE-BASED-API.md) — HubSpot's `/YYYY-MM/` migration plan
313
186
  - [docs/PLUGIN_GUIDE.md](docs/PLUGIN_GUIDE.md) — writing plugins
314
- - [docs/OPERATIONAL_PLAYBOOKS.md](docs/OPERATIONAL_PLAYBOOKS.md)
315
- - [docs/COOKBOOK.md](docs/COOKBOOK.md) — common recipes
316
- - [CONTRIBUTING.md](CONTRIBUTING.md)
317
- - [SECURITY.md](SECURITY.md)
318
- - [CHANGELOG.md](CHANGELOG.md)
319
-
320
- ### Domain setup guides
187
+ - [docs/COOKBOOK.md](docs/COOKBOOK.md) — recipes
188
+ - [docs/PUBLISHING.md](docs/PUBLISHING.md) — release runbook (maintainers)
189
+ - [CONTRIBUTING.md](CONTRIBUTING.md) · [SECURITY.md](SECURITY.md) · [CHANGELOG.md](CHANGELOG.md)
321
190
 
322
- - [docs/PORTAL_SETUP.md](docs/PORTAL_SETUP.md)
323
- - [docs/CMS_SETUP.md](docs/CMS_SETUP.md)
324
- - [docs/COMMERCE_SETUP.md](docs/COMMERCE_SETUP.md)
325
- - [docs/MARKETING_SETUP.md](docs/MARKETING_SETUP.md)
326
- - [docs/SALES_SETUP.md](docs/SALES_SETUP.md)
327
- - [docs/SERVICE_SETUP.md](docs/SERVICE_SETUP.md)
328
- - [docs/OPERATIONS_SETUP.md](docs/OPERATIONS_SETUP.md)
329
- - [docs/REPORTING_SETUP.md](docs/REPORTING_SETUP.md)
330
- - [docs/INTEGRATIONS_NOTIFICATIONS_SETUP.md](docs/INTEGRATIONS_NOTIFICATIONS_SETUP.md)
191
+ Domain setup guides: [PORTAL](docs/PORTAL_SETUP.md) · [CMS](docs/CMS_SETUP.md) · [Commerce](docs/COMMERCE_SETUP.md) · [Marketing](docs/MARKETING_SETUP.md) · [Sales](docs/SALES_SETUP.md) · [Service](docs/SERVICE_SETUP.md) · [Operations](docs/OPERATIONS_SETUP.md) · [Reporting](docs/REPORTING_SETUP.md) · [Integrations & Notifications](docs/INTEGRATIONS_NOTIFICATIONS_SETUP.md)
331
192
 
332
- ## Verification
333
-
334
- Full release check:
335
-
336
- ```bash
337
- npm run release:verify
338
- ```
339
-
340
- Runs typecheck + lint + tests + audit + build + SHA256 checksum verification.
193
+ Tutorials: [secure agent writes](docs/TUTORIALS/secure-agent-writes.md) · [audit portal writes](docs/TUTORIALS/audit-portal-writes.md) · [trace + replay](docs/TUTORIALS/trace-replay-repro.md)
341
194
 
342
195
  ## Contributing
343
196
 
344
- Issues and PRs welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow, coding standards, and how to run contract tests against a sandbox portal.
197
+ Issues and PRs welcome see [CONTRIBUTING.md](CONTRIBUTING.md) for the workflow, coding standards, and live-portal contract tests.
345
198
 
346
199
  ## License
347
200
 
348
201
  MIT — see [LICENSE](LICENSE).
349
-
package/SECURITY.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # SECURITY
2
2
 
3
- > See also: [[SAFETY_MODEL]] · [[RELEASE_GOVERNANCE]] · [[hubspot-rules]]
3
+ > See also: [SAFETY_MODEL.md](SAFETY_MODEL.md) · [RELEASE_GOVERNANCE.md](RELEASE_GOVERNANCE.md)
4
4
 
5
5
  ## Security Objectives
6
6
  - Prevent credential exposure
@@ -14,7 +14,7 @@
14
14
  - JSON mode is preferred for machine handling to avoid ad-hoc parsing leaks.
15
15
 
16
16
  ## Secret Storage Policy
17
- - Tokens are stored in profile-based auth file under `HUBCLI_HOME` or default `~/.hubcli`.
17
+ - Tokens are stored in profile-based auth file under `HSCLI_HOME` or default `~/.hscli`.
18
18
  - File permissions are locked to owner-only (`0700` dir, `0600` auth file).
19
19
  - Prefer `auth login --token-stdin` over inline `--token` to reduce shell-history/process-list exposure.
20
20
  - No token echo in CLI responses.