@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,158 @@
|
|
|
1
|
+
# Plugin Guide
|
|
2
|
+
|
|
3
|
+
hscli supports plugins that add new command groups without modifying the core codebase.
|
|
4
|
+
|
|
5
|
+
## Plugin Contract
|
|
6
|
+
|
|
7
|
+
A plugin is an ESM module that exports a `register` function:
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
import type { Command } from "commander";
|
|
11
|
+
import type { PluginContext } from "hscli/plugins";
|
|
12
|
+
|
|
13
|
+
export function register(program: Command, ctx: PluginContext): void {
|
|
14
|
+
const analytics = program.command("analytics").description("Analytics commands");
|
|
15
|
+
|
|
16
|
+
analytics
|
|
17
|
+
.command("report")
|
|
18
|
+
.option("--days <n>", "Days to look back", "30")
|
|
19
|
+
.action(async (opts) => {
|
|
20
|
+
const cliCtx = ctx.getCtx();
|
|
21
|
+
const client = ctx.createClient(cliCtx.profile);
|
|
22
|
+
const res = await client.request(`/crm/v3/objects/contacts?limit=${opts.days}`);
|
|
23
|
+
ctx.printResult(cliCtx, res);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## PluginContext API
|
|
29
|
+
|
|
30
|
+
| Method | Description |
|
|
31
|
+
|--------|-------------|
|
|
32
|
+
| `getCtx()` | Returns current CLI context (profile, flags). **Call inside `.action()`, not at registration time.** |
|
|
33
|
+
| `createClient(profile)` | Creates an authenticated HubSpot API client for the given profile. |
|
|
34
|
+
| `printResult(ctx, data)` | Prints structured output to stdout (respects `--json`, `--format`). |
|
|
35
|
+
| `printError(ctx, error)` | Prints structured error to stderr. |
|
|
36
|
+
| `CliError` | Constructor for structured errors: `new ctx.CliError("CODE", "message")`. |
|
|
37
|
+
| `maybeWrite(ctx, client, method, path, body?)` | Write-safe helper. Enforces `--dry-run`, `--force`, and `--policy-file` gates automatically. |
|
|
38
|
+
|
|
39
|
+
## Write Safety
|
|
40
|
+
|
|
41
|
+
Always use `ctx.maybeWrite()` for mutations. This enforces all safety gates:
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
analytics
|
|
45
|
+
.command("delete-report")
|
|
46
|
+
.argument("<id>")
|
|
47
|
+
.action(async (id) => {
|
|
48
|
+
const cliCtx = ctx.getCtx();
|
|
49
|
+
const client = ctx.createClient(cliCtx.profile);
|
|
50
|
+
const result = await ctx.maybeWrite(cliCtx, client, "DELETE", `/analytics/v1/reports/${id}`);
|
|
51
|
+
ctx.printResult(cliCtx, result);
|
|
52
|
+
});
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
- Without `--force`: throws `WRITE_CONFIRMATION_REQUIRED`
|
|
56
|
+
- With `--dry-run`: returns preview object without making the API call
|
|
57
|
+
- With `--policy-file`: enforces profile-level write/delete rules
|
|
58
|
+
|
|
59
|
+
## Plugin Discovery
|
|
60
|
+
|
|
61
|
+
### 1. npm packages (automatic)
|
|
62
|
+
|
|
63
|
+
Create an npm package with `"hscli-plugin"` in its `keywords`:
|
|
64
|
+
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"name": "hscli-plugin-analytics",
|
|
68
|
+
"keywords": ["hscli-plugin"],
|
|
69
|
+
"type": "module",
|
|
70
|
+
"main": "index.js",
|
|
71
|
+
"exports": { ".": "./index.js" }
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Install it alongside hscli:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
npm install hscli-plugin-analytics
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Auto-discovery is **opt-in** — since hscli handles bearer tokens,
|
|
82
|
+
silently importing every `node_modules` package with a matching keyword
|
|
83
|
+
is a supply-chain risk. To enable auto-discovery:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
HSCLI_PLUGIN_AUTO_DISCOVER=1 hscli ...
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
When enabled, hscli prints the resolved package list to stderr before
|
|
90
|
+
loading them, so a misconfigured `node_modules` can't inject token-path
|
|
91
|
+
code silently. For production use, prefer the explicit allowlist below.
|
|
92
|
+
|
|
93
|
+
### 2. HSCLI_PLUGINS env var (manual, always honored)
|
|
94
|
+
|
|
95
|
+
For local development or private plugins:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
HSCLI_PLUGINS=./my-plugin,/opt/plugins/custom hscli analytics report
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Comma-separated list of paths (relative to cwd) or npm package names.
|
|
102
|
+
|
|
103
|
+
## Local Development
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
mkdir hscli-plugin-analytics
|
|
107
|
+
cd hscli-plugin-analytics
|
|
108
|
+
|
|
109
|
+
cat > index.js << 'EOF'
|
|
110
|
+
export function register(program, ctx) {
|
|
111
|
+
program
|
|
112
|
+
.command("analytics")
|
|
113
|
+
.description("Analytics commands (plugin)")
|
|
114
|
+
.command("hello")
|
|
115
|
+
.action(() => {
|
|
116
|
+
const cliCtx = ctx.getCtx();
|
|
117
|
+
ctx.printResult(cliCtx, { message: "Hello from analytics plugin!" });
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
EOF
|
|
121
|
+
|
|
122
|
+
cd /path/to/hscli
|
|
123
|
+
HSCLI_PLUGINS=../hscli-plugin-analytics hscli analytics hello
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Error Handling
|
|
127
|
+
|
|
128
|
+
- Throw `ctx.CliError` for structured errors that follow hscli's error format.
|
|
129
|
+
- Plugin load failures are logged to stderr but never crash the CLI.
|
|
130
|
+
- If a plugin's `register()` throws, it is skipped and the rest of the CLI works normally.
|
|
131
|
+
|
|
132
|
+
## TypeScript Setup
|
|
133
|
+
|
|
134
|
+
For TypeScript plugins, target `ES2022` / `NodeNext` to match the host:
|
|
135
|
+
|
|
136
|
+
```json
|
|
137
|
+
{
|
|
138
|
+
"compilerOptions": {
|
|
139
|
+
"target": "ES2022",
|
|
140
|
+
"module": "NodeNext",
|
|
141
|
+
"moduleResolution": "NodeNext",
|
|
142
|
+
"outDir": "dist"
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Import types from hscli:
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
import type { PluginContext, HubcliPlugin } from "hscli/plugins";
|
|
151
|
+
import type { CliContext } from "hscli/output";
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Limitations
|
|
155
|
+
|
|
156
|
+
- Plugins cannot override built-in commands (Commander silently ignores duplicates).
|
|
157
|
+
- Plugins share the same process and Node.js context as the CLI.
|
|
158
|
+
- Plugin authors are responsible for their own error handling within `.action()` callbacks.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema-note": "hscli policy v2 — method+path glob rules, time windows, change-ticket + approval gates. First-match-wins per profile. Legacy v1 flat fields (allowWrite, allowDelete, requireChangeTicket) are still honored under `defaults` / per-profile for backward compat.",
|
|
3
|
+
"version": 2,
|
|
4
|
+
"profiles": {
|
|
5
|
+
"prod": {
|
|
6
|
+
"defaultAction": "deny",
|
|
7
|
+
"rules": [
|
|
8
|
+
{
|
|
9
|
+
"name": "allow-all-reads",
|
|
10
|
+
"match": { "method": "GET", "path": "**" },
|
|
11
|
+
"action": "allow"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"name": "block-gdpr-delete-anywhere",
|
|
15
|
+
"match": { "method": "*", "path": "**/gdpr-delete**" },
|
|
16
|
+
"action": "deny"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"name": "block-schema-deletes",
|
|
20
|
+
"match": { "method": "DELETE", "path": "/crm/v3/schemas/**" },
|
|
21
|
+
"action": "deny"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"name": "crm-writes-need-ticket-and-hours",
|
|
25
|
+
"match": { "method": "POST", "path": "/crm/v3/objects/**" },
|
|
26
|
+
"action": "allow",
|
|
27
|
+
"requireChangeTicket": true,
|
|
28
|
+
"window": { "tz": "US/Eastern", "hours": "09-17", "days": "mon-fri" }
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"name": "crm-updates-need-ticket-and-hours",
|
|
32
|
+
"match": { "method": "PATCH", "path": "/crm/v3/objects/**" },
|
|
33
|
+
"action": "allow",
|
|
34
|
+
"requireChangeTicket": true,
|
|
35
|
+
"window": { "tz": "US/Eastern", "hours": "09-17", "days": "mon-fri" }
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"name": "deletes-need-approval",
|
|
39
|
+
"match": { "method": "DELETE", "path": "/crm/v3/objects/**" },
|
|
40
|
+
"action": "allow",
|
|
41
|
+
"requireChangeTicket": true,
|
|
42
|
+
"requireApproval": "manual"
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
},
|
|
46
|
+
"sandbox": {
|
|
47
|
+
"defaultAction": "allow",
|
|
48
|
+
"rules": [
|
|
49
|
+
{
|
|
50
|
+
"name": "still-block-gdpr-delete",
|
|
51
|
+
"match": { "method": "*", "path": "**/gdpr-delete**" },
|
|
52
|
+
"action": "deny"
|
|
53
|
+
}
|
|
54
|
+
]
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|