fathom-cli 0.2.4 → 0.3.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.
- package/README.md +59 -51
- package/dist/chunk-FILMHRDQ.js +2055 -0
- package/dist/chunk-FILMHRDQ.js.map +1 -0
- package/dist/chunk-MNGU6SI4.js +6680 -0
- package/dist/chunk-MNGU6SI4.js.map +1 -0
- package/dist/chunk-SEGVTWSK.js +44 -0
- package/dist/chunk-SEGVTWSK.js.map +1 -0
- package/dist/chunk-TXIC6BY4.js +169 -0
- package/dist/chunk-TXIC6BY4.js.map +1 -0
- package/dist/data/guardrails/gdpr-basic.yaml +19 -0
- package/dist/data/guardrails/hipaa-basic.yaml +19 -0
- package/dist/data/guardrails/owasp-top-10.yaml +16 -0
- package/dist/data/guardrails/pci-basic.yaml +19 -0
- package/dist/data/guardrails/soc2-basic.yaml +19 -0
- package/dist/data/guardrails/wcag-aa.yaml +16 -0
- package/dist/dist-KXBSLOHP.js +506 -0
- package/dist/dist-KXBSLOHP.js.map +1 -0
- package/dist/dist-XKZLNUDU.js +34 -0
- package/dist/dist-XKZLNUDU.js.map +1 -0
- package/dist/fileFromPath-AY5NHOFK.js +131 -0
- package/dist/fileFromPath-AY5NHOFK.js.map +1 -0
- package/dist/index.js +14397 -18315
- package/dist/index.js.map +1 -1
- package/dist/openai-CLPZFCUS.js +10933 -0
- package/dist/openai-CLPZFCUS.js.map +1 -0
- package/package.json +23 -7
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
9
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
10
|
+
}) : x)(function(x) {
|
|
11
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
12
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
13
|
+
});
|
|
14
|
+
var __commonJS = (cb, mod) => function __require2() {
|
|
15
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
16
|
+
};
|
|
17
|
+
var __export = (target, all) => {
|
|
18
|
+
for (var name in all)
|
|
19
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
20
|
+
};
|
|
21
|
+
var __copyProps = (to, from, except, desc) => {
|
|
22
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
23
|
+
for (let key of __getOwnPropNames(from))
|
|
24
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
25
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
26
|
+
}
|
|
27
|
+
return to;
|
|
28
|
+
};
|
|
29
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
30
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
31
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
32
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
33
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
34
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
35
|
+
mod
|
|
36
|
+
));
|
|
37
|
+
|
|
38
|
+
export {
|
|
39
|
+
__require,
|
|
40
|
+
__commonJS,
|
|
41
|
+
__export,
|
|
42
|
+
__toESM
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=chunk-SEGVTWSK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
external_exports,
|
|
4
|
+
jsYaml
|
|
5
|
+
} from "./chunk-MNGU6SI4.js";
|
|
6
|
+
|
|
7
|
+
// ../intent/dist/index.js
|
|
8
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs";
|
|
9
|
+
import { join } from "path";
|
|
10
|
+
import { readFileSync as readFileSync2, readdirSync } from "fs";
|
|
11
|
+
import { resolve } from "path";
|
|
12
|
+
var ValueSchema = external_exports.object({
|
|
13
|
+
name: external_exports.string(),
|
|
14
|
+
description: external_exports.string(),
|
|
15
|
+
priority: external_exports.enum(["critical", "high", "medium", "low"]).default("medium"),
|
|
16
|
+
details: external_exports.string().optional()
|
|
17
|
+
});
|
|
18
|
+
var BudgetSchema = external_exports.object({
|
|
19
|
+
monthly_limit: external_exports.number().positive(),
|
|
20
|
+
alert_threshold: external_exports.number().min(0).max(1).default(0.8),
|
|
21
|
+
prefer_batch: external_exports.boolean().default(false),
|
|
22
|
+
currency: external_exports.string().default("USD")
|
|
23
|
+
});
|
|
24
|
+
var GuardrailsSchema = external_exports.object({
|
|
25
|
+
security: external_exports.object({
|
|
26
|
+
templates: external_exports.array(external_exports.string()).default([]),
|
|
27
|
+
custom: external_exports.array(external_exports.string()).default([])
|
|
28
|
+
}).optional(),
|
|
29
|
+
quality: external_exports.array(external_exports.string()).default([]),
|
|
30
|
+
process: external_exports.array(external_exports.string()).default([])
|
|
31
|
+
});
|
|
32
|
+
var TechSchema = external_exports.object({
|
|
33
|
+
stack: external_exports.array(external_exports.string()).default([]),
|
|
34
|
+
opinions: external_exports.array(external_exports.string()).default([])
|
|
35
|
+
});
|
|
36
|
+
var ProvidersSchema = external_exports.object({
|
|
37
|
+
preferred: external_exports.string().optional(),
|
|
38
|
+
api_key_env: external_exports.string().optional(),
|
|
39
|
+
fallback: external_exports.string().optional(),
|
|
40
|
+
local_models: external_exports.array(external_exports.string()).default([])
|
|
41
|
+
});
|
|
42
|
+
var IntentSchema = external_exports.object({
|
|
43
|
+
project: external_exports.string(),
|
|
44
|
+
description: external_exports.string(),
|
|
45
|
+
audience: external_exports.string().optional(),
|
|
46
|
+
values: external_exports.array(ValueSchema).default([]),
|
|
47
|
+
budget: BudgetSchema.optional(),
|
|
48
|
+
guardrails: GuardrailsSchema.optional(),
|
|
49
|
+
tech: TechSchema.optional(),
|
|
50
|
+
providers: ProvidersSchema.optional()
|
|
51
|
+
});
|
|
52
|
+
var GuardrailTemplateSchema = external_exports.object({
|
|
53
|
+
name: external_exports.string(),
|
|
54
|
+
description: external_exports.string(),
|
|
55
|
+
category: external_exports.enum(["security", "quality"]),
|
|
56
|
+
status: external_exports.string().optional(),
|
|
57
|
+
rules: external_exports.array(external_exports.string())
|
|
58
|
+
});
|
|
59
|
+
var INTENT_DIR = ".fathom";
|
|
60
|
+
var INTENT_FILE = "intent.yaml";
|
|
61
|
+
function intentPath(dir) {
|
|
62
|
+
return join(dir, INTENT_DIR, INTENT_FILE);
|
|
63
|
+
}
|
|
64
|
+
async function loadIntent(dir) {
|
|
65
|
+
const filePath = intentPath(dir);
|
|
66
|
+
if (!existsSync(filePath)) {
|
|
67
|
+
throw new Error(`Intent file not found: ${filePath}`);
|
|
68
|
+
}
|
|
69
|
+
const content = readFileSync(filePath, "utf-8");
|
|
70
|
+
const raw = jsYaml.load(content);
|
|
71
|
+
return IntentSchema.parse(raw);
|
|
72
|
+
}
|
|
73
|
+
async function saveIntent(dir, intent) {
|
|
74
|
+
const validated = IntentSchema.parse(intent);
|
|
75
|
+
const fathomDir = join(dir, INTENT_DIR);
|
|
76
|
+
if (!existsSync(fathomDir)) {
|
|
77
|
+
mkdirSync(fathomDir, { recursive: true });
|
|
78
|
+
}
|
|
79
|
+
const content = jsYaml.dump(validated, {
|
|
80
|
+
lineWidth: 120,
|
|
81
|
+
noRefs: true,
|
|
82
|
+
quotingType: '"',
|
|
83
|
+
forceQuotes: false
|
|
84
|
+
});
|
|
85
|
+
writeFileSync(intentPath(dir), content, "utf-8");
|
|
86
|
+
}
|
|
87
|
+
function detectIntent(dir) {
|
|
88
|
+
return existsSync(intentPath(dir));
|
|
89
|
+
}
|
|
90
|
+
function findDataDir() {
|
|
91
|
+
const base = import.meta.dirname ?? __dirname;
|
|
92
|
+
const bundled = resolve(base, "data", "guardrails");
|
|
93
|
+
try {
|
|
94
|
+
readdirSync(bundled);
|
|
95
|
+
return bundled;
|
|
96
|
+
} catch {
|
|
97
|
+
return resolve(base, "..", "data", "guardrails");
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
function loadTemplate(name) {
|
|
101
|
+
const dir = findDataDir();
|
|
102
|
+
const filePath = resolve(dir, `${name}.yaml`);
|
|
103
|
+
let content;
|
|
104
|
+
try {
|
|
105
|
+
content = readFileSync2(filePath, "utf-8");
|
|
106
|
+
} catch {
|
|
107
|
+
throw new Error(
|
|
108
|
+
`Unknown guardrail template: "${name}". Use listTemplates() to see available templates.`
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
const raw = jsYaml.load(content);
|
|
112
|
+
return GuardrailTemplateSchema.parse(raw);
|
|
113
|
+
}
|
|
114
|
+
function listTemplates() {
|
|
115
|
+
const dir = findDataDir();
|
|
116
|
+
const files = readdirSync(dir).filter((f) => f.endsWith(".yaml"));
|
|
117
|
+
return files.map((file) => {
|
|
118
|
+
const content = readFileSync2(resolve(dir, file), "utf-8");
|
|
119
|
+
const raw = jsYaml.load(content);
|
|
120
|
+
return {
|
|
121
|
+
name: raw.name,
|
|
122
|
+
description: raw.description,
|
|
123
|
+
category: raw.category,
|
|
124
|
+
status: raw.status
|
|
125
|
+
};
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
function resolveGuardrails(intent) {
|
|
129
|
+
const result = {
|
|
130
|
+
security: [],
|
|
131
|
+
quality: [],
|
|
132
|
+
process: []
|
|
133
|
+
};
|
|
134
|
+
if (!intent.guardrails) {
|
|
135
|
+
return result;
|
|
136
|
+
}
|
|
137
|
+
const { guardrails } = intent;
|
|
138
|
+
if (guardrails.security) {
|
|
139
|
+
for (const templateName of guardrails.security.templates) {
|
|
140
|
+
const template = loadTemplate(templateName);
|
|
141
|
+
if (template.category === "security") {
|
|
142
|
+
result.security.push(...template.rules);
|
|
143
|
+
} else if (template.category === "quality") {
|
|
144
|
+
result.quality.push(...template.rules);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
result.security.push(...guardrails.security.custom);
|
|
148
|
+
}
|
|
149
|
+
result.quality.push(...guardrails.quality);
|
|
150
|
+
result.process.push(...guardrails.process);
|
|
151
|
+
return result;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export {
|
|
155
|
+
ValueSchema,
|
|
156
|
+
BudgetSchema,
|
|
157
|
+
GuardrailsSchema,
|
|
158
|
+
TechSchema,
|
|
159
|
+
ProvidersSchema,
|
|
160
|
+
IntentSchema,
|
|
161
|
+
GuardrailTemplateSchema,
|
|
162
|
+
loadIntent,
|
|
163
|
+
saveIntent,
|
|
164
|
+
detectIntent,
|
|
165
|
+
loadTemplate,
|
|
166
|
+
listTemplates,
|
|
167
|
+
resolveGuardrails
|
|
168
|
+
};
|
|
169
|
+
//# sourceMappingURL=chunk-TXIC6BY4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../intent/src/schema.ts","../../intent/src/loader.ts","../../intent/src/guardrails.ts"],"sourcesContent":["import { z } from \"zod\";\n\n// ── Value schema ────────────────────────────────────────────\n\nexport const ValueSchema = z.object({\n name: z.string(),\n description: z.string(),\n priority: z.enum([\"critical\", \"high\", \"medium\", \"low\"]).default(\"medium\"),\n details: z.string().optional(),\n});\n\nexport type Value = z.infer<typeof ValueSchema>;\n\n// ── Budget schema ───────────────────────────────────────────\n\nexport const BudgetSchema = z.object({\n monthly_limit: z.number().positive(),\n alert_threshold: z.number().min(0).max(1).default(0.8),\n prefer_batch: z.boolean().default(false),\n currency: z.string().default(\"USD\"),\n});\n\nexport type Budget = z.infer<typeof BudgetSchema>;\n\n// ── Guardrails schema ───────────────────────────────────────\n\nexport const GuardrailsSchema = z.object({\n security: z\n .object({\n templates: z.array(z.string()).default([]),\n custom: z.array(z.string()).default([]),\n })\n .optional(),\n quality: z.array(z.string()).default([]),\n process: z.array(z.string()).default([]),\n});\n\nexport type Guardrails = z.infer<typeof GuardrailsSchema>;\n\n// ── Tech schema ─────────────────────────────────────────────\n\nexport const TechSchema = z.object({\n stack: z.array(z.string()).default([]),\n opinions: z.array(z.string()).default([]),\n});\n\nexport type Tech = z.infer<typeof TechSchema>;\n\n// ── Providers schema ────────────────────────────────────────\n\nexport const ProvidersSchema = z.object({\n preferred: z.string().optional(),\n api_key_env: z.string().optional(),\n fallback: z.string().optional(),\n local_models: z.array(z.string()).default([]),\n});\n\nexport type Providers = z.infer<typeof ProvidersSchema>;\n\n// ── Intent schema (top-level) ───────────────────────────────\n\nexport const IntentSchema = z.object({\n project: z.string(),\n description: z.string(),\n audience: z.string().optional(),\n values: z.array(ValueSchema).default([]),\n budget: BudgetSchema.optional(),\n guardrails: GuardrailsSchema.optional(),\n tech: TechSchema.optional(),\n providers: ProvidersSchema.optional(),\n});\n\nexport type IntentConfig = z.infer<typeof IntentSchema>;\n\n// ── Guardrail template schema ───────────────────────────────\n\nexport const GuardrailTemplateSchema = z.object({\n name: z.string(),\n description: z.string(),\n category: z.enum([\"security\", \"quality\"]),\n status: z.string().optional(),\n rules: z.array(z.string()),\n});\n\nexport type GuardrailTemplate = z.infer<typeof GuardrailTemplateSchema>;\n\n// ── Resolved guardrails (flat output) ───────────────────────\n\nexport interface ResolvedGuardrails {\n security: string[];\n quality: string[];\n process: string[];\n}\n\nexport interface TemplateInfo {\n name: string;\n description: string;\n category: string;\n status?: string;\n}\n","import { readFileSync, writeFileSync, mkdirSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport yaml from \"js-yaml\";\nimport { IntentSchema, type IntentConfig } from \"./schema.js\";\n\nconst INTENT_DIR = \".fathom\";\nconst INTENT_FILE = \"intent.yaml\";\n\nfunction intentPath(dir: string): string {\n return join(dir, INTENT_DIR, INTENT_FILE);\n}\n\n/**\n * Load and validate intent from a project directory.\n * Reads `.fathom/intent.yaml`, parses YAML, validates with Zod.\n */\nexport async function loadIntent(dir: string): Promise<IntentConfig> {\n const filePath = intentPath(dir);\n\n if (!existsSync(filePath)) {\n throw new Error(`Intent file not found: ${filePath}`);\n }\n\n const content = readFileSync(filePath, \"utf-8\");\n const raw = yaml.load(content);\n return IntentSchema.parse(raw);\n}\n\n/**\n * Validate and save intent to a project directory.\n * Writes validated YAML to `.fathom/intent.yaml`. Creates `.fathom/` if needed.\n */\nexport async function saveIntent(dir: string, intent: IntentConfig): Promise<void> {\n // Validate before writing\n const validated = IntentSchema.parse(intent);\n\n const fathomDir = join(dir, INTENT_DIR);\n if (!existsSync(fathomDir)) {\n mkdirSync(fathomDir, { recursive: true });\n }\n\n const content = yaml.dump(validated, {\n lineWidth: 120,\n noRefs: true,\n quotingType: '\"',\n forceQuotes: false,\n });\n\n writeFileSync(intentPath(dir), content, \"utf-8\");\n}\n\n/**\n * Synchronously check if `.fathom/intent.yaml` exists in a directory.\n */\nexport function detectIntent(dir: string): boolean {\n return existsSync(intentPath(dir));\n}\n","import { readFileSync, readdirSync } from \"node:fs\";\nimport { resolve, basename } from \"node:path\";\nimport yaml from \"js-yaml\";\nimport {\n GuardrailTemplateSchema,\n type GuardrailTemplate,\n type IntentConfig,\n type ResolvedGuardrails,\n type TemplateInfo,\n} from \"./schema.js\";\n\nfunction findDataDir(): string {\n const base = import.meta.dirname ?? __dirname;\n // Try bundled location first (dist/data/ when installed from npm)\n const bundled = resolve(base, \"data\", \"guardrails\");\n try {\n readdirSync(bundled);\n return bundled;\n } catch {\n // Fall back to monorepo location (packages/intent/data/guardrails from dist/)\n return resolve(base, \"..\", \"data\", \"guardrails\");\n }\n}\n\n/**\n * Load a guardrail template by name.\n */\nexport function loadTemplate(name: string): GuardrailTemplate {\n const dir = findDataDir();\n const filePath = resolve(dir, `${name}.yaml`);\n\n let content: string;\n try {\n content = readFileSync(filePath, \"utf-8\");\n } catch {\n throw new Error(\n `Unknown guardrail template: \"${name}\". Use listTemplates() to see available templates.`,\n );\n }\n\n const raw = yaml.load(content);\n return GuardrailTemplateSchema.parse(raw);\n}\n\n/**\n * List all available guardrail templates.\n */\nexport function listTemplates(): TemplateInfo[] {\n const dir = findDataDir();\n const files = readdirSync(dir).filter((f) => f.endsWith(\".yaml\"));\n\n return files.map((file) => {\n const content = readFileSync(resolve(dir, file), \"utf-8\");\n const raw = yaml.load(content) as Record<string, unknown>;\n return {\n name: raw.name as string,\n description: raw.description as string,\n category: raw.category as string,\n status: raw.status as string | undefined,\n };\n });\n}\n\n/**\n * Resolve all guardrail templates and custom rules from an intent config\n * into a flat categorized object.\n */\nexport function resolveGuardrails(intent: IntentConfig): ResolvedGuardrails {\n const result: ResolvedGuardrails = {\n security: [],\n quality: [],\n process: [],\n };\n\n if (!intent.guardrails) {\n return result;\n }\n\n const { guardrails } = intent;\n\n // Expand security templates\n if (guardrails.security) {\n for (const templateName of guardrails.security.templates) {\n const template = loadTemplate(templateName);\n if (template.category === \"security\") {\n result.security.push(...template.rules);\n } else if (template.category === \"quality\") {\n result.quality.push(...template.rules);\n }\n }\n\n // Add custom security rules\n result.security.push(...guardrails.security.custom);\n }\n\n // Add quality rules (these are direct string rules, not template refs)\n result.quality.push(...guardrails.quality);\n\n // Add process rules\n result.process.push(...guardrails.process);\n\n return result;\n}\n"],"mappings":";;;;;;;ACAA,SAAS,cAAc,eAAe,WAAW,kBAAkB;AACnE,SAAS,YAAY;ACDrB,SAAS,gBAAAA,eAAc,mBAAmB;AAC1C,SAAS,eAAyB;AFG3B,IAAM,cAAc,iBAAE,OAAO;EAClC,MAAM,iBAAE,OAAO;EACf,aAAa,iBAAE,OAAO;EACtB,UAAU,iBAAE,KAAK,CAAC,YAAY,QAAQ,UAAU,KAAK,CAAC,EAAE,QAAQ,QAAQ;EACxE,SAAS,iBAAE,OAAO,EAAE,SAAS;AAC/B,CAAC;AAMM,IAAM,eAAe,iBAAE,OAAO;EACnC,eAAe,iBAAE,OAAO,EAAE,SAAS;EACnC,iBAAiB,iBAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,GAAG;EACrD,cAAc,iBAAE,QAAQ,EAAE,QAAQ,KAAK;EACvC,UAAU,iBAAE,OAAO,EAAE,QAAQ,KAAK;AACpC,CAAC;AAMM,IAAM,mBAAmB,iBAAE,OAAO;EACvC,UAAU,iBACP,OAAO;IACN,WAAW,iBAAE,MAAM,iBAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;IACzC,QAAQ,iBAAE,MAAM,iBAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;EACxC,CAAC,EACA,SAAS;EACZ,SAAS,iBAAE,MAAM,iBAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;EACvC,SAAS,iBAAE,MAAM,iBAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;AACzC,CAAC;AAMM,IAAM,aAAa,iBAAE,OAAO;EACjC,OAAO,iBAAE,MAAM,iBAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;EACrC,UAAU,iBAAE,MAAM,iBAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;AAC1C,CAAC;AAMM,IAAM,kBAAkB,iBAAE,OAAO;EACtC,WAAW,iBAAE,OAAO,EAAE,SAAS;EAC/B,aAAa,iBAAE,OAAO,EAAE,SAAS;EACjC,UAAU,iBAAE,OAAO,EAAE,SAAS;EAC9B,cAAc,iBAAE,MAAM,iBAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;AAC9C,CAAC;AAMM,IAAM,eAAe,iBAAE,OAAO;EACnC,SAAS,iBAAE,OAAO;EAClB,aAAa,iBAAE,OAAO;EACtB,UAAU,iBAAE,OAAO,EAAE,SAAS;EAC9B,QAAQ,iBAAE,MAAM,WAAW,EAAE,QAAQ,CAAC,CAAC;EACvC,QAAQ,aAAa,SAAS;EAC9B,YAAY,iBAAiB,SAAS;EACtC,MAAM,WAAW,SAAS;EAC1B,WAAW,gBAAgB,SAAS;AACtC,CAAC;AAMM,IAAM,0BAA0B,iBAAE,OAAO;EAC9C,MAAM,iBAAE,OAAO;EACf,aAAa,iBAAE,OAAO;EACtB,UAAU,iBAAE,KAAK,CAAC,YAAY,SAAS,CAAC;EACxC,QAAQ,iBAAE,OAAO,EAAE,SAAS;EAC5B,OAAO,iBAAE,MAAM,iBAAE,OAAO,CAAC;AAC3B,CAAC;AC7ED,IAAM,aAAa;AACnB,IAAM,cAAc;AAEpB,SAAS,WAAW,KAAqB;AACvC,SAAO,KAAK,KAAK,YAAY,WAAW;AAC1C;AAMA,eAAsB,WAAW,KAAoC;AACnE,QAAM,WAAW,WAAW,GAAG;AAE/B,MAAI,CAAC,WAAW,QAAQ,GAAG;AACzB,UAAM,IAAI,MAAM,0BAA0B,QAAQ,EAAE;EACtD;AAEA,QAAM,UAAU,aAAa,UAAU,OAAO;AAC9C,QAAM,MAAM,OAAK,KAAK,OAAO;AAC7B,SAAO,aAAa,MAAM,GAAG;AAC/B;AAMA,eAAsB,WAAW,KAAa,QAAqC;AAEjF,QAAM,YAAY,aAAa,MAAM,MAAM;AAE3C,QAAM,YAAY,KAAK,KAAK,UAAU;AACtC,MAAI,CAAC,WAAW,SAAS,GAAG;AAC1B,cAAU,WAAW,EAAE,WAAW,KAAK,CAAC;EAC1C;AAEA,QAAM,UAAU,OAAK,KAAK,WAAW;IACnC,WAAW;IACX,QAAQ;IACR,aAAa;IACb,aAAa;EACf,CAAC;AAED,gBAAc,WAAW,GAAG,GAAG,SAAS,OAAO;AACjD;AAKO,SAAS,aAAa,KAAsB;AACjD,SAAO,WAAW,WAAW,GAAG,CAAC;AACnC;AC7CA,SAAS,cAAsB;AAC7B,QAAM,OAAO,YAAY,WAAW;AAEpC,QAAM,UAAU,QAAQ,MAAM,QAAQ,YAAY;AAClD,MAAI;AACF,gBAAY,OAAO;AACnB,WAAO;EACT,QAAQ;AAEN,WAAO,QAAQ,MAAM,MAAM,QAAQ,YAAY;EACjD;AACF;AAKO,SAAS,aAAa,MAAiC;AAC5D,QAAM,MAAM,YAAY;AACxB,QAAM,WAAW,QAAQ,KAAK,GAAG,IAAI,OAAO;AAE5C,MAAI;AACJ,MAAI;AACF,cAAUC,cAAa,UAAU,OAAO;EAC1C,QAAQ;AACN,UAAM,IAAI;MACR,gCAAgC,IAAI;IACtC;EACF;AAEA,QAAM,MAAMC,OAAK,KAAK,OAAO;AAC7B,SAAO,wBAAwB,MAAM,GAAG;AAC1C;AAKO,SAAS,gBAAgC;AAC9C,QAAM,MAAM,YAAY;AACxB,QAAM,QAAQ,YAAY,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,OAAO,CAAC;AAEhE,SAAO,MAAM,IAAI,CAAC,SAAS;AACzB,UAAM,UAAUD,cAAa,QAAQ,KAAK,IAAI,GAAG,OAAO;AACxD,UAAM,MAAMC,OAAK,KAAK,OAAO;AAC7B,WAAO;MACL,MAAM,IAAI;MACV,aAAa,IAAI;MACjB,UAAU,IAAI;MACd,QAAQ,IAAI;IACd;EACF,CAAC;AACH;AAMO,SAAS,kBAAkB,QAA0C;AAC1E,QAAM,SAA6B;IACjC,UAAU,CAAC;IACX,SAAS,CAAC;IACV,SAAS,CAAC;EACZ;AAEA,MAAI,CAAC,OAAO,YAAY;AACtB,WAAO;EACT;AAEA,QAAM,EAAE,WAAW,IAAI;AAGvB,MAAI,WAAW,UAAU;AACvB,eAAW,gBAAgB,WAAW,SAAS,WAAW;AACxD,YAAM,WAAW,aAAa,YAAY;AAC1C,UAAI,SAAS,aAAa,YAAY;AACpC,eAAO,SAAS,KAAK,GAAG,SAAS,KAAK;MACxC,WAAW,SAAS,aAAa,WAAW;AAC1C,eAAO,QAAQ,KAAK,GAAG,SAAS,KAAK;MACvC;IACF;AAGA,WAAO,SAAS,KAAK,GAAG,WAAW,SAAS,MAAM;EACpD;AAGA,SAAO,QAAQ,KAAK,GAAG,WAAW,OAAO;AAGzC,SAAO,QAAQ,KAAK,GAAG,WAAW,OAAO;AAEzC,SAAO;AACT;","names":["readFileSync","readFileSync","yaml"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
name: gdpr-basic
|
|
2
|
+
description: GDPR Basic Compliance Guidelines
|
|
3
|
+
category: security
|
|
4
|
+
rules:
|
|
5
|
+
- "Collect explicit, informed, and freely given consent before processing personal data — pre-checked boxes are not valid consent"
|
|
6
|
+
- "Practice data minimization — only collect and retain personal data that is strictly necessary for the stated purpose"
|
|
7
|
+
- "Implement right to deletion (right to be forgotten) — users must be able to request complete removal of their personal data"
|
|
8
|
+
- "Implement data portability — provide users a machine-readable export (JSON/CSV) of all their personal data on request"
|
|
9
|
+
- "Implement right of access — users must be able to view all personal data you hold about them within 30 days of request"
|
|
10
|
+
- "Apply privacy by design — build data protection into system architecture from the start, not as an afterthought"
|
|
11
|
+
- "Maintain a Record of Processing Activities (ROPA) documenting what data you collect, why, and how long you keep it"
|
|
12
|
+
- "Implement breach notification — report personal data breaches to the supervisory authority within 72 hours of discovery"
|
|
13
|
+
- "Obtain explicit consent before setting non-essential cookies or tracking — implement a compliant cookie consent banner"
|
|
14
|
+
- "Do not transfer personal data outside the EEA without appropriate safeguards (SCCs, adequacy decisions, or BCRs)"
|
|
15
|
+
- "Define and enforce data retention periods — automatically delete or anonymize personal data when the retention period expires"
|
|
16
|
+
- "Implement granular consent management — users must be able to withdraw consent as easily as they gave it"
|
|
17
|
+
- "Conduct Data Protection Impact Assessments (DPIA) before processing that is likely to result in high risk to individuals"
|
|
18
|
+
- "Pseudonymize personal data wherever possible — separate identifying information from the data being processed"
|
|
19
|
+
- "Never use personal data for purposes beyond what was explicitly communicated at the time of collection without new consent"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
name: hipaa-basic
|
|
2
|
+
description: HIPAA Basic Compliance Guidelines
|
|
3
|
+
category: security
|
|
4
|
+
rules:
|
|
5
|
+
- "Encrypt all Protected Health Information (PHI) at rest using AES-256 — this includes databases, backups, and file storage"
|
|
6
|
+
- "Encrypt all PHI in transit using TLS 1.2+ — never send health data over unencrypted channels"
|
|
7
|
+
- "Apply the minimum necessary principle — only request, display, and process the specific PHI fields needed for the task"
|
|
8
|
+
- "Implement role-based access control (RBAC) so users only see PHI relevant to their job function"
|
|
9
|
+
- "Log all access to PHI with immutable audit trails — record who accessed what, when, and why"
|
|
10
|
+
- "Retain audit logs for at least six years as required by HIPAA retention rules"
|
|
11
|
+
- "Never include PHI in URLs, query parameters, client-side storage, or application logs"
|
|
12
|
+
- "Require unique user IDs and enforce multi-factor authentication for all systems containing PHI"
|
|
13
|
+
- "Implement automatic session timeout (15 minutes or less of inactivity) for applications accessing PHI"
|
|
14
|
+
- "Verify that all third-party services handling PHI have signed a Business Associate Agreement (BAA) before integration"
|
|
15
|
+
- "Implement a breach notification mechanism — HIPAA requires notification within 60 days of discovering a breach"
|
|
16
|
+
- "Provide a mechanism for patients to request access to, amendment of, and an accounting of disclosures of their PHI"
|
|
17
|
+
- "Run regular risk assessments on all systems that store, process, or transmit PHI — document findings and remediation"
|
|
18
|
+
- "Ensure PHI is completely and irreversibly deleted when no longer needed — including backups and replicas"
|
|
19
|
+
- "De-identify data according to HIPAA Safe Harbor (remove all 18 identifiers) before using it for analytics or testing"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
name: owasp-top-10
|
|
2
|
+
description: OWASP Top 10 Web Application Security Risks
|
|
3
|
+
category: security
|
|
4
|
+
rules:
|
|
5
|
+
- "Validate and sanitize all user input server-side — never trust client-side validation alone"
|
|
6
|
+
- "Use parameterized queries or prepared statements — never concatenate user input into SQL"
|
|
7
|
+
- "Implement proper authentication with secure password hashing (bcrypt/argon2) and session management"
|
|
8
|
+
- "Apply principle of least privilege — users and services should only access what they need"
|
|
9
|
+
- "Never expose sensitive data in error messages, logs, or API responses"
|
|
10
|
+
- "Use HTTPS everywhere — never transmit sensitive data over unencrypted connections"
|
|
11
|
+
- "Validate Content-Type headers and reject unexpected content types"
|
|
12
|
+
- "Implement rate limiting on authentication endpoints and sensitive operations"
|
|
13
|
+
- "Keep dependencies updated and audit for known vulnerabilities regularly"
|
|
14
|
+
- "Encode output contextually (HTML, URL, JavaScript) to prevent XSS"
|
|
15
|
+
- "Use CSRF tokens for state-changing operations"
|
|
16
|
+
- "Never store secrets, API keys, or credentials in source code or client-side storage"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
name: pci-basic
|
|
2
|
+
description: PCI DSS Basic Compliance Guidelines
|
|
3
|
+
category: security
|
|
4
|
+
rules:
|
|
5
|
+
- "Never store full card numbers (PAN) in plaintext — use tokenization or truncation (first 6/last 4 only)"
|
|
6
|
+
- "Never log, print, or include in error messages: full PAN, CVV/CVC, PIN, or magnetic stripe data"
|
|
7
|
+
- "Encrypt cardholder data at rest using AES-256 or equivalent — manage keys separately from encrypted data"
|
|
8
|
+
- "Transmit cardholder data only over TLS 1.2+ — reject connections using older protocols"
|
|
9
|
+
- "Isolate payment processing systems from the general application network — use dedicated subnets or services"
|
|
10
|
+
- "Restrict access to cardholder data to only the services and personnel that absolutely need it"
|
|
11
|
+
- "Use unique credentials for every user and service account that accesses payment systems — no shared accounts"
|
|
12
|
+
- "Enforce multi-factor authentication for all administrative access to payment processing environments"
|
|
13
|
+
- "Log all access to cardholder data and payment systems — include who, what, when, and from where"
|
|
14
|
+
- "Retain audit logs for at least one year, with a minimum of three months immediately available for analysis"
|
|
15
|
+
- "Run vulnerability scans on all payment-facing systems quarterly and after any significant change"
|
|
16
|
+
- "Never use vendor-supplied default passwords or settings on any system in the cardholder data environment"
|
|
17
|
+
- "Mask PAN when displayed — show no more than first 6 and last 4 digits unless there is a legitimate business need"
|
|
18
|
+
- "Implement a web application firewall (WAF) or rigorous code review for all public-facing payment applications"
|
|
19
|
+
- "Maintain an inventory of all system components in scope for PCI DSS and review scope annually"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
name: soc2-basic
|
|
2
|
+
description: SOC 2 Basic Compliance Guidelines
|
|
3
|
+
category: security
|
|
4
|
+
rules:
|
|
5
|
+
- "Enforce multi-factor authentication (MFA) for all user and administrative access to production systems"
|
|
6
|
+
- "Implement role-based access control (RBAC) with least-privilege — review and recertify access quarterly"
|
|
7
|
+
- "Log all system access, configuration changes, and data operations to a centralized, tamper-evident logging system"
|
|
8
|
+
- "Establish a formal change management process — all production changes require review, approval, and rollback plans"
|
|
9
|
+
- "Conduct regular vulnerability scans and penetration tests — remediate critical findings within defined SLAs"
|
|
10
|
+
- "Implement automated monitoring and alerting for system availability, performance anomalies, and security events"
|
|
11
|
+
- "Maintain and test an incident response plan — define roles, escalation paths, communication templates, and post-mortem processes"
|
|
12
|
+
- "Encrypt sensitive data at rest (AES-256) and in transit (TLS 1.2+) across all system components"
|
|
13
|
+
- "Perform vendor security assessments before onboarding third-party services that process or store customer data"
|
|
14
|
+
- "Implement automated backups with defined RPO/RTO targets and test restoration procedures at least annually"
|
|
15
|
+
- "Enforce separation of duties — no single person should be able to deploy code, approve changes, and access production data"
|
|
16
|
+
- "Revoke access to all systems within 24 hours of employee termination or role change"
|
|
17
|
+
- "Maintain a documented and enforced data classification policy — label data as public, internal, confidential, or restricted"
|
|
18
|
+
- "Implement network segmentation — isolate production, staging, and development environments from each other"
|
|
19
|
+
- "Require security awareness training for all employees and contractors with access to customer data at least annually"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
name: wcag-aa
|
|
2
|
+
description: WCAG 2.1 Level AA Accessibility Guidelines
|
|
3
|
+
category: quality
|
|
4
|
+
rules:
|
|
5
|
+
- "All images must have descriptive alt text (or empty alt for decorative images)"
|
|
6
|
+
- "Ensure color contrast ratio of at least 4.5:1 for normal text, 3:1 for large text"
|
|
7
|
+
- "All interactive elements must be keyboard accessible with visible focus indicators"
|
|
8
|
+
- "Form inputs must have associated labels — use htmlFor/id or aria-label"
|
|
9
|
+
- "Use semantic HTML elements (nav, main, header, footer, article, section) for document structure"
|
|
10
|
+
- "Provide skip navigation links for keyboard users"
|
|
11
|
+
- "Ensure all content is readable and functional at 200% zoom"
|
|
12
|
+
- "Use aria-live regions for dynamic content updates that should be announced to screen readers"
|
|
13
|
+
- "Never use color alone to convey information — supplement with text, icons, or patterns"
|
|
14
|
+
- "Provide text alternatives for all non-text content (video captions, audio transcripts)"
|
|
15
|
+
- "Ensure touch targets are at least 44x44px on mobile"
|
|
16
|
+
- "Support reduced-motion preferences via prefers-reduced-motion media query"
|