@revfleet/hscli 0.8.6 → 0.8.10
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.
- package/CHANGELOG.md +240 -0
- package/CONTRIBUTING.md +120 -0
- package/README.md +14 -6
- package/brand/readme-hero.svg +25 -0
- package/dist/cli.js +10 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/account/index.js +5 -6
- package/dist/commands/account/index.js.map +1 -1
- package/dist/commands/api/index.js +43 -3
- package/dist/commands/api/index.js.map +1 -1
- package/dist/commands/auth/index.js +32 -6
- package/dist/commands/auth/index.js.map +1 -1
- package/dist/commands/cms/hubdb.js +64 -1
- package/dist/commands/cms/hubdb.js.map +1 -1
- package/dist/commands/cms/index.js +27 -0
- package/dist/commands/cms/index.js.map +1 -1
- package/dist/commands/cms/source-code.js +21 -0
- package/dist/commands/cms/source-code.js.map +1 -1
- package/dist/commands/communication-preferences/index.js +11 -12
- package/dist/commands/communication-preferences/index.js.map +1 -1
- package/dist/commands/crm/shared.d.ts +1 -0
- package/dist/commands/crm/shared.js +3 -4
- package/dist/commands/crm/shared.js.map +1 -1
- package/dist/commands/events/index.js +7 -8
- package/dist/commands/events/index.js.map +1 -1
- package/dist/commands/marketing/index.js +58 -3
- package/dist/commands/marketing/index.js.map +1 -1
- package/dist/commands/settings/index.js +12 -13
- package/dist/commands/settings/index.js.map +1 -1
- package/dist/commands/workflows/index.js +43 -0
- package/dist/commands/workflows/index.js.map +1 -1
- package/dist/core/http.d.ts +27 -0
- package/dist/core/http.js +102 -18
- package/dist/core/http.js.map +1 -1
- package/dist/core/plugins.d.ts +5 -2
- package/dist/core/plugins.js +18 -1
- package/dist/core/plugins.js.map +1 -1
- package/dist/core/telemetry-context.d.ts +13 -0
- package/dist/core/telemetry-context.js +30 -0
- package/dist/core/telemetry-context.js.map +1 -0
- package/dist/mcp/hubspot-modules.d.ts +30 -0
- package/dist/mcp/hubspot-modules.js +305 -0
- package/dist/mcp/hubspot-modules.js.map +1 -0
- package/dist/mcp/server.d.ts +2 -0
- package/dist/mcp/server.js +30 -26
- package/dist/mcp/server.js.map +1 -1
- package/docs/ARCHITECTURE.md +39 -0
- package/docs/CAPABILITY_LIBRARY.md +638 -0
- package/docs/CMS_SETUP.md +349 -0
- package/docs/COMMAND_COMPATIBILITY.md +24 -0
- package/docs/COMMAND_TREE.md +183 -0
- package/docs/COMMERCE_SETUP.md +400 -0
- package/docs/COMPARISON.md +146 -0
- package/docs/COOKBOOK.md +800 -0
- package/docs/INTEGRATIONS_NOTIFICATIONS_SETUP.md +352 -0
- package/docs/MARKETING_SETUP.md +503 -0
- package/docs/MCP.md +171 -0
- package/docs/OPERATIONAL_PLAYBOOKS.md +322 -0
- package/docs/OPERATIONS_SETUP.md +362 -0
- package/docs/PLUGIN_GUIDE.md +158 -0
- package/docs/POLICY_EXAMPLE.json +57 -0
- package/docs/PORTAL_SETUP.md +683 -0
- package/docs/PUBLISHING.md +154 -0
- package/docs/RELEASE_GOVERNANCE.md +34 -0
- package/docs/REPORTING_SETUP.md +310 -0
- package/docs/ROADMAP-DATE-BASED-API.md +103 -0
- package/docs/ROADMAP_PHASE1_TO_3.md +96 -0
- package/docs/SAFETY_MODEL.md +37 -0
- package/docs/SALES_SETUP.md +369 -0
- package/docs/SERVICE_SETUP.md +403 -0
- package/docs/TESTING_PLAN.md +89 -0
- package/docs/TIERS.md +320 -0
- package/docs/TUTORIALS/audit-portal-writes.md +150 -0
- package/docs/TUTORIALS/secure-agent-writes.md +177 -0
- package/docs/TUTORIALS/trace-replay-repro.md +147 -0
- package/docs/WHY_HOW_WHAT.md +81 -0
- package/package.json +7 -2
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# Tutorial: Reproduce a bug with trace + replay
|
|
2
|
+
|
|
3
|
+
**Time:** ~10 min
|
|
4
|
+
**Prerequisites:** `hscli` installed, a HubSpot Private App token authenticated, at least one portal to test against.
|
|
5
|
+
|
|
6
|
+
Your agent "works fine in staging, fails in prod." Or: "Monday it fetched 500 contacts, Tuesday it fetched 120." You need to see *exactly* what happened, compare runs, and replay the read portion safely to isolate the divergence.
|
|
7
|
+
|
|
8
|
+
`hscli trace` records every request to a JSONL file with enough detail to reconstruct and replay the session.
|
|
9
|
+
|
|
10
|
+
## Step 1 — start recording
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
hscli trace start --include-bodies
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Output:
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"started": true,
|
|
20
|
+
"file": "/Users/you/.revfleet/trace-2026-04-21T09-14-22-123Z.jsonl",
|
|
21
|
+
"session": { ... }
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
A state file at `~/.revfleet/trace-session.json` tells the HTTP client to append every request to the trace file until you stop.
|
|
26
|
+
|
|
27
|
+
`--include-bodies` captures request and response payloads (redacted for secrets). Omit it for tiny trace files when you only need metadata (method, path, status, latency).
|
|
28
|
+
|
|
29
|
+
## Step 2 — reproduce the scenario
|
|
30
|
+
|
|
31
|
+
Run whatever failed. This can be:
|
|
32
|
+
- A sequence of `hscli` commands in a shell script
|
|
33
|
+
- An MCP agent connected to `hscli mcp` (every tool call is tagged with `toolName`)
|
|
34
|
+
- A custom integration hitting `hscli api request ...`
|
|
35
|
+
|
|
36
|
+
Example:
|
|
37
|
+
```bash
|
|
38
|
+
hscli crm contacts list --limit 100
|
|
39
|
+
hscli crm companies list --limit 50
|
|
40
|
+
hscli --force crm contacts create --data '{"properties":{"email":"test@example.com"}}'
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Step 3 — stop + inspect
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
hscli trace stop
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Output shows the trace file path, duration, event count, and file size.
|
|
50
|
+
|
|
51
|
+
### Summary
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
hscli trace stats ~/.revfleet/trace-2026-04-21T09-14-22-123Z.jsonl
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Breaks down by method, status, profile, tool (if MCP), latency percentiles (p50/p95/p99/max), write vs read count.
|
|
58
|
+
|
|
59
|
+
### Errors only
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
hscli trace errors ~/.revfleet/trace-2026-04-21T09-14-22-123Z.jsonl
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Filter for specific events
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
hscli trace show <file> --filter "status=>=400,method=POST"
|
|
69
|
+
hscli trace show <file> --filter "path=/crm/v3/objects/contacts,status=!200"
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Supported operators: `=`, `!` (not equal), `>=`, `<=`, `>`, `<`, plus substring match when no operator is used.
|
|
73
|
+
|
|
74
|
+
## Step 4 — compare two runs
|
|
75
|
+
|
|
76
|
+
This is the killer feature for reproducibility. Record the same scenario twice — once on staging, once on prod:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# Staging
|
|
80
|
+
hscli trace start --out ./staging.jsonl
|
|
81
|
+
./run-scenario.sh
|
|
82
|
+
hscli trace stop
|
|
83
|
+
|
|
84
|
+
# Prod
|
|
85
|
+
hscli trace start --out ./prod.jsonl
|
|
86
|
+
./run-scenario.sh
|
|
87
|
+
hscli trace stop
|
|
88
|
+
|
|
89
|
+
# Diff
|
|
90
|
+
hscli trace diff ./staging.jsonl ./prod.jsonl
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
`trace diff` normalizes numeric path segments (e.g. `/crm/v3/objects/contacts/123` → `/crm/v3/objects/contacts/{id}`) so you see structural divergence, not id noise. The output tells you:
|
|
94
|
+
|
|
95
|
+
- `onlyInA` — calls the staging run made but prod didn't
|
|
96
|
+
- `onlyInB` — calls prod made but staging didn't
|
|
97
|
+
- `countChanges` — keys with a different number of hits (cursor pagination edge cases live here)
|
|
98
|
+
- `statusChanges` — same call but different status in each run (the bug's fingerprint)
|
|
99
|
+
- `divergent` — single boolean flag for CI
|
|
100
|
+
|
|
101
|
+
## Step 5 — replay GETs
|
|
102
|
+
|
|
103
|
+
To test a fix, you often want to re-run the same reads against a different profile or a patched client:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
hscli --profile staging trace replay ./prod.jsonl
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Default is **dry-run** — it reports what *would* be replayed. Writes (`POST/PUT/PATCH/DELETE`) are filtered out entirely; they're never replayable, to avoid accidental re-mutation.
|
|
110
|
+
|
|
111
|
+
To actually re-issue the GETs:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
hscli --force --profile staging trace replay ./prod.jsonl
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
You'll get a list of each path, status, and duration — perfect for confirming a capability-probe cache invalidation, a rate-limit reshuffle, or a schema migration.
|
|
118
|
+
|
|
119
|
+
## Step 6 — tail live (optional)
|
|
120
|
+
|
|
121
|
+
If you want to watch events stream in during a long scenario:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# In one terminal
|
|
125
|
+
hscli trace start
|
|
126
|
+
|
|
127
|
+
# In another
|
|
128
|
+
hscli trace tail # tails the active session
|
|
129
|
+
# or
|
|
130
|
+
hscli trace tail <file> --format json
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Compact mode shows `status ts method path latency [toolName]` per line. `--format json` streams the full event for pipe-to-`jq` workflows.
|
|
134
|
+
|
|
135
|
+
## What you get
|
|
136
|
+
|
|
137
|
+
- Every request is an auditable line of JSON — method, path, status, duration, profile, tool (for MCP), optional bodies.
|
|
138
|
+
- Two runs of the same scenario can be diffed, and differences surface structurally (not as a wall of id changes).
|
|
139
|
+
- Read-side replay lets you isolate whether a bug is client-side or portal-side.
|
|
140
|
+
- Pair with `hscli audit` (see the [audit tutorial](audit-portal-writes.md)) to roll traces up into *who did what when*.
|
|
141
|
+
|
|
142
|
+
## Tips
|
|
143
|
+
|
|
144
|
+
- Trace files are append-only JSONL — safe to `tail -f`, pipe into `jq`, feed into observability tools.
|
|
145
|
+
- Set `HSCLI_TRACE_BODIES=1` if you want the HTTP layer to always capture bodies without needing `--include-bodies`.
|
|
146
|
+
- Keep traces out of git — add `~/.revfleet/trace-*.jsonl` to `.gitignore` or write to `/tmp`.
|
|
147
|
+
- Trace works for every `hscli` command and every MCP tool — the recording lives in the HTTP layer, not in the command handler.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# WHY / HOW / WHAT
|
|
2
|
+
|
|
3
|
+
> See also: [ARCHITECTURE.md](ARCHITECTURE.md) · [SAFETY_MODEL.md](SAFETY_MODEL.md) · [ROADMAP_PHASE1_TO_3.md](ROADMAP_PHASE1_TO_3.md)
|
|
4
|
+
|
|
5
|
+
## WHY this CLI exists
|
|
6
|
+
`hscli` exists to give operators a safe, automatable, production-grade command interface to HubSpot APIs without needing to write code each time. It solves three operational problems:
|
|
7
|
+
- **Speed:** repetitive CRM operations become scriptable and repeatable.
|
|
8
|
+
- **Safety:** write controls prevent accidental destructive mutations.
|
|
9
|
+
- **Reliability:** consistent output + retry behavior reduce brittle ad-hoc scripts.
|
|
10
|
+
|
|
11
|
+
## WHAT has been built (and what remains)
|
|
12
|
+
|
|
13
|
+
### Built now
|
|
14
|
+
- Foundation CLI architecture with global flags:
|
|
15
|
+
- `--profile` for auth profile selection
|
|
16
|
+
- `--json` for machine-readable output
|
|
17
|
+
- `--dry-run` for mutation simulation
|
|
18
|
+
- `--force` for explicit write confirmation
|
|
19
|
+
- `--policy-file` + `--change-ticket` for policy-governed writes
|
|
20
|
+
- `--telemetry-file` for request-level telemetry
|
|
21
|
+
- CRM object support:
|
|
22
|
+
- contacts/companies/deals/tickets: list/get/search/create/update/delete/merge/batch
|
|
23
|
+
- pagination/filter flags on read/search paths
|
|
24
|
+
- Schema and relationship support:
|
|
25
|
+
- properties: list/get/create/update
|
|
26
|
+
- associations: list/create/remove
|
|
27
|
+
- owners: list
|
|
28
|
+
- pipelines: list/get
|
|
29
|
+
- custom objects: schema + record management
|
|
30
|
+
- engagements: notes/calls/tasks/emails/meetings
|
|
31
|
+
- sync: incremental pull workflow
|
|
32
|
+
- Cross-domain support:
|
|
33
|
+
- marketing, forms, files, cms, workflows, service command groups
|
|
34
|
+
- raw API passthrough (`api request`) with existing safety controls
|
|
35
|
+
- Core protections:
|
|
36
|
+
- write gate (`--force`) + dry-run preview
|
|
37
|
+
- policy middleware for writes/deletes
|
|
38
|
+
- secret redaction in output/error serialization
|
|
39
|
+
- profile environment isolation via `HSCLI_HOME`
|
|
40
|
+
- request scope guard, timeout, retries, and correlation id
|
|
41
|
+
- Auth model expansion:
|
|
42
|
+
- profile listing/inspection
|
|
43
|
+
- OAuth authorize URL + code exchange
|
|
44
|
+
- token introspection
|
|
45
|
+
|
|
46
|
+
### Still remaining
|
|
47
|
+
- richer input schema validation (field-level and enum constraints)
|
|
48
|
+
- release signing/provenance automation
|
|
49
|
+
- external HubSpot sandbox e2e coverage expansion
|
|
50
|
+
|
|
51
|
+
## HOW architecture, safety, and reliability work
|
|
52
|
+
|
|
53
|
+
## Architecture
|
|
54
|
+
- `src/cli.ts`: global options and execution context
|
|
55
|
+
- `src/commands/**`: command handlers by domain
|
|
56
|
+
- `src/core/auth.ts`: profile-based token store with filesystem permissions
|
|
57
|
+
- `src/core/http.ts`: HTTP transport, retry/backoff, normalized error behavior
|
|
58
|
+
- `src/core/output.ts`: unified output/error envelopes + redaction
|
|
59
|
+
|
|
60
|
+
## Safety controls
|
|
61
|
+
- **Write confirmation pathway:** all mutating commands route through `maybeWrite`.
|
|
62
|
+
- If `--dry-run`: command returns mutation preview only, no network write.
|
|
63
|
+
- If live write without `--force`: blocked with `WRITE_CONFIRMATION_REQUIRED`.
|
|
64
|
+
- If `--force`: write executes.
|
|
65
|
+
- **Policy guardrail pathway:** optional policy file can block writes/deletes or require change tickets by profile.
|
|
66
|
+
- **No plaintext token logs:** token values are never intentionally printed.
|
|
67
|
+
- **Redaction pipeline:** output and error payloads are sanitized for token/authorization/secret-like keys and bearer strings.
|
|
68
|
+
- **Profile isolation:** `HSCLI_HOME` can isolate credentials per environment/workload.
|
|
69
|
+
|
|
70
|
+
## Reliability controls
|
|
71
|
+
- Retry policy for rate-limit and transient server failures with request timeout.
|
|
72
|
+
- Request correlation IDs and optional telemetry output.
|
|
73
|
+
- Stable `CliError` envelope with machine-readable code/status/details.
|
|
74
|
+
- Consistent JSON mode for automation workflows.
|
|
75
|
+
|
|
76
|
+
## Threat model snapshot
|
|
77
|
+
- **Token theft:** mitigated by file permission restrictions + redaction + profile isolation.
|
|
78
|
+
- **Replay/misuse of credentials:** reduced by scope-minimal private app tokens and environment separation.
|
|
79
|
+
- **Payload injection / malformed writes:** JSON parsing guardrails and explicit write intent gate.
|
|
80
|
+
- **Unsafe writes:** default block unless `--force` or `--dry-run`.
|
|
81
|
+
- **Operational misuse:** deterministic outputs and explicit errors enable safe CI/script handling.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@revfleet/hscli",
|
|
3
|
-
"version": "0.8.
|
|
4
|
-
"description": "Agentic HubSpot CLI + MCP server.
|
|
3
|
+
"version": "0.8.10",
|
|
4
|
+
"description": "Agentic HubSpot CLI + MCP server. Covers ~all documented public endpoints (1180 across 55+ command domains). Reachability is tier/scope/auth-model gated — UI-only surfaces and deprecated APIs excluded. Enterprise safety rails, self-hosted.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"hscli": "dist/cli.js"
|
|
@@ -56,8 +56,13 @@
|
|
|
56
56
|
},
|
|
57
57
|
"files": [
|
|
58
58
|
"dist",
|
|
59
|
+
"docs/*.md",
|
|
60
|
+
"docs/TUTORIALS/*.md",
|
|
61
|
+
"docs/POLICY_EXAMPLE.json",
|
|
59
62
|
"docs/policy-templates",
|
|
63
|
+
"brand/readme-hero.svg",
|
|
60
64
|
"README.md",
|
|
65
|
+
"CONTRIBUTING.md",
|
|
61
66
|
"LICENSE",
|
|
62
67
|
"SECURITY.md",
|
|
63
68
|
"CHANGELOG.md"
|