@revfleet/hscli 0.5.3 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,217 @@
1
+ import { readFileSync, writeFileSync, existsSync, readdirSync, mkdirSync } from "node:fs";
2
+ import { dirname, join, resolve } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { CliError, printResult } from "../../core/output.js";
5
+ import { readPolicyFile, findMatchingRule } from "../../core/policy.js";
6
+ function getTemplatesDir() {
7
+ // Templates ship alongside the built dist/. When running via `hscli` binary,
8
+ // we need to walk up from the module's dist location to find the docs/ dir.
9
+ // This only matters for installed npm package — in dev mode tsc outputs
10
+ // into dist/ and the docs/ dir is at the repo root.
11
+ const thisFile = fileURLToPath(import.meta.url);
12
+ // dist/commands/policy/index.js → repo root
13
+ const candidates = [
14
+ resolve(dirname(thisFile), "../../../docs/policy-templates"),
15
+ resolve(dirname(thisFile), "../../../../docs/policy-templates"),
16
+ resolve(dirname(thisFile), "../../docs/policy-templates"),
17
+ ];
18
+ for (const candidate of candidates) {
19
+ if (existsSync(candidate))
20
+ return candidate;
21
+ }
22
+ // Last resort — this will only fail at runtime if templates are missing
23
+ return resolve(dirname(thisFile), "../../../docs/policy-templates");
24
+ }
25
+ function getPolicyPath(ctx) {
26
+ return ctx.policyFile?.trim() || process.env.HSCLI_POLICY_FILE?.trim();
27
+ }
28
+ export function registerPolicy(program, getCtx) {
29
+ const policy = program.command("policy").description("Manage policy-as-code: audit the active policy, list/extract built-in templates, validate your own files.");
30
+ policy
31
+ .command("list")
32
+ .description("Show the active policy (from --policy-file or HSCLI_POLICY_FILE). Parses + summarizes all rules by profile.")
33
+ .action(async () => {
34
+ const ctx = getCtx();
35
+ const path = getPolicyPath(ctx);
36
+ if (!path) {
37
+ printResult(ctx, {
38
+ active: false,
39
+ message: "No policy file set. Pass --policy-file <path> or set HSCLI_POLICY_FILE env var.",
40
+ suggestions: [
41
+ "hscli policy templates # list built-in templates",
42
+ "hscli policy templates extract read-only --to ./policy.json",
43
+ ],
44
+ });
45
+ return;
46
+ }
47
+ const config = readPolicyFile(path);
48
+ const summary = {
49
+ active: true,
50
+ file: path,
51
+ version: config.version ?? 1,
52
+ profiles: Object.fromEntries(Object.entries(config.profiles ?? {}).map(([name, cfg]) => [
53
+ name,
54
+ {
55
+ defaultAction: cfg.defaultAction ?? "allow",
56
+ ruleCount: cfg.rules?.length ?? 0,
57
+ ruleNames: (cfg.rules ?? []).map(r => r.name || "(unnamed)"),
58
+ legacyFlags: {
59
+ allowWrite: cfg.allowWrite,
60
+ allowDelete: cfg.allowDelete,
61
+ requireChangeTicket: cfg.requireChangeTicket,
62
+ },
63
+ },
64
+ ])),
65
+ hasDefaults: Boolean(config.defaults),
66
+ blockedPrefixes: config.blockedMethodPathPrefixes,
67
+ };
68
+ printResult(ctx, summary);
69
+ });
70
+ policy
71
+ .command("show-matching")
72
+ .description("Print which policy rule (if any) would be applied to a hypothetical request. Useful for verifying rules before shipping.")
73
+ .argument("<method>", "HTTP method: GET, POST, PATCH, PUT, DELETE")
74
+ .argument("<path>", "Request path (e.g. /crm/v3/objects/contacts/123)")
75
+ .option("--profile <name>", "Profile to evaluate against (defaults to the current --profile)")
76
+ .action(async (method, requestPath, opts) => {
77
+ const ctx = getCtx();
78
+ const policyPath = getPolicyPath(ctx);
79
+ if (!policyPath) {
80
+ throw new CliError("NO_POLICY_FILE", "No policy file configured. Pass --policy-file or set HSCLI_POLICY_FILE.");
81
+ }
82
+ const config = readPolicyFile(policyPath);
83
+ const profile = opts.profile || ctx.profile;
84
+ const profileConfig = config.profiles?.[profile] ?? config.defaults ?? {};
85
+ const matched = findMatchingRule(profileConfig, method, requestPath);
86
+ if (matched) {
87
+ printResult(ctx, {
88
+ profile,
89
+ request: { method, path: requestPath },
90
+ matchedRule: matched,
91
+ effectiveAction: matched.action ?? "allow",
92
+ });
93
+ }
94
+ else {
95
+ printResult(ctx, {
96
+ profile,
97
+ request: { method, path: requestPath },
98
+ matchedRule: null,
99
+ effectiveAction: profileConfig.defaultAction ?? "allow",
100
+ note: "No rule matched. Falling back to the profile's defaultAction.",
101
+ });
102
+ }
103
+ });
104
+ policy
105
+ .command("validate")
106
+ .description("Parse + semantic-check a policy file without enforcing it.")
107
+ .argument("[file]", "Policy file path (default: the active --policy-file / HSCLI_POLICY_FILE)")
108
+ .action(async (fileArg) => {
109
+ const ctx = getCtx();
110
+ const path = fileArg || getPolicyPath(ctx);
111
+ if (!path) {
112
+ throw new CliError("NO_POLICY_FILE", "No file passed and no active policy configured.");
113
+ }
114
+ try {
115
+ const config = readPolicyFile(path);
116
+ const issues = [];
117
+ const warnings = [];
118
+ for (const [profileName, cfg] of Object.entries(config.profiles ?? {})) {
119
+ for (const rule of cfg.rules ?? []) {
120
+ if (!rule.match)
121
+ warnings.push(`[${profileName}] rule '${rule.name ?? "(unnamed)"}' has no match criteria — will match everything`);
122
+ if (rule.action && rule.action !== "allow" && rule.action !== "deny")
123
+ issues.push(`[${profileName}] rule '${rule.name ?? "(unnamed)"}' has invalid action '${rule.action}' (must be 'allow' or 'deny')`);
124
+ if (rule.window?.days && !/^[a-z]{3}(-[a-z]{3}|(,[a-z]{3})*)$/i.test(rule.window.days.trim())) {
125
+ warnings.push(`[${profileName}] rule '${rule.name ?? "(unnamed)"}' has non-standard window.days syntax: '${rule.window.days}'`);
126
+ }
127
+ if (rule.window?.hours && !/^\d{1,2}-\d{1,2}$/.test(rule.window.hours)) {
128
+ issues.push(`[${profileName}] rule '${rule.name ?? "(unnamed)"}' has invalid window.hours: '${rule.window.hours}' (must be 'HH-HH' 24h format)`);
129
+ }
130
+ }
131
+ }
132
+ printResult(ctx, {
133
+ valid: issues.length === 0,
134
+ file: path,
135
+ version: config.version ?? 1,
136
+ profileCount: Object.keys(config.profiles ?? {}).length,
137
+ totalRules: Object.values(config.profiles ?? {}).reduce((s, c) => s + (c.rules?.length ?? 0), 0),
138
+ issues,
139
+ warnings,
140
+ });
141
+ }
142
+ catch (err) {
143
+ if (err instanceof CliError)
144
+ throw err;
145
+ throw new CliError("POLICY_PARSE_ERROR", err instanceof Error ? err.message : String(err));
146
+ }
147
+ });
148
+ const templates = policy.command("templates").description("Built-in policy templates for common trust scenarios");
149
+ templates
150
+ .command("list")
151
+ .description("List available built-in policy templates")
152
+ .action(async () => {
153
+ const ctx = getCtx();
154
+ const dir = getTemplatesDir();
155
+ if (!existsSync(dir)) {
156
+ throw new CliError("TEMPLATES_DIR_MISSING", `Template directory not found: ${dir}`);
157
+ }
158
+ const files = readdirSync(dir).filter(f => f.endsWith(".json"));
159
+ const templatesWithMeta = files.map(f => {
160
+ try {
161
+ const content = JSON.parse(readFileSync(join(dir, f), "utf8"));
162
+ return { name: f.replace(/\.json$/, ""), version: content.version, description: content.description ?? "(no description)" };
163
+ }
164
+ catch {
165
+ return { name: f.replace(/\.json$/, ""), version: undefined, description: "(failed to parse)" };
166
+ }
167
+ });
168
+ printResult(ctx, {
169
+ count: templatesWithMeta.length,
170
+ templates: templatesWithMeta,
171
+ note: "Use `hscli policy templates show <name>` to view; `hscli policy templates extract <name> --to <file>` to copy.",
172
+ });
173
+ });
174
+ templates
175
+ .command("show")
176
+ .description("Print a template's content")
177
+ .argument("<name>", "Template name (from `hscli policy templates list`)")
178
+ .action(async (name) => {
179
+ const ctx = getCtx();
180
+ const path = join(getTemplatesDir(), `${name}.json`);
181
+ if (!existsSync(path)) {
182
+ throw new CliError("TEMPLATE_NOT_FOUND", `Template '${name}' not found. Available: ${readdirSync(getTemplatesDir()).filter(f => f.endsWith(".json")).map(f => f.replace(/\.json$/, "")).join(", ")}`);
183
+ }
184
+ const content = JSON.parse(readFileSync(path, "utf8"));
185
+ printResult(ctx, content);
186
+ });
187
+ templates
188
+ .command("extract")
189
+ .description("Copy a built-in template to a local file for editing")
190
+ .argument("<name>", "Template name")
191
+ .requiredOption("--to <file>", "Destination file path")
192
+ .action(async (name, opts) => {
193
+ const ctx = getCtx();
194
+ const srcPath = join(getTemplatesDir(), `${name}.json`);
195
+ if (!existsSync(srcPath)) {
196
+ throw new CliError("TEMPLATE_NOT_FOUND", `Template '${name}' not found.`);
197
+ }
198
+ const dest = String(opts.to);
199
+ if (existsSync(dest)) {
200
+ throw new CliError("DEST_FILE_EXISTS", `Destination file already exists: ${dest}. Delete it first or choose another path.`);
201
+ }
202
+ mkdirSync(dirname(dest), { recursive: true });
203
+ const content = readFileSync(srcPath, "utf8");
204
+ writeFileSync(dest, content, { encoding: "utf8", mode: 0o644 });
205
+ printResult(ctx, {
206
+ extracted: true,
207
+ from: srcPath,
208
+ to: dest,
209
+ nextSteps: [
210
+ `hscli policy validate ${dest}`,
211
+ `hscli --policy-file ${dest} crm contacts list`,
212
+ `export HSCLI_POLICY_FILE=${dest}`,
213
+ ],
214
+ });
215
+ });
216
+ }
217
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/policy/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ import type { CliContext } from "../../core/output.js";
3
+ export declare function registerTrace(program: Command, getCtx: () => CliContext): void;