briefed 0.1.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.
Files changed (117) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +118 -0
  3. package/dist/bench/metrics.d.ts +31 -0
  4. package/dist/bench/metrics.js +122 -0
  5. package/dist/bench/metrics.js.map +1 -0
  6. package/dist/bench/runner.d.ts +27 -0
  7. package/dist/bench/runner.js +184 -0
  8. package/dist/bench/runner.js.map +1 -0
  9. package/dist/cli.d.ts +2 -0
  10. package/dist/cli.js +42 -0
  11. package/dist/cli.js.map +1 -0
  12. package/dist/commands/bench.d.ts +11 -0
  13. package/dist/commands/bench.js +23 -0
  14. package/dist/commands/bench.js.map +1 -0
  15. package/dist/commands/doctor.d.ts +5 -0
  16. package/dist/commands/doctor.js +246 -0
  17. package/dist/commands/doctor.js.map +1 -0
  18. package/dist/commands/init.d.ts +8 -0
  19. package/dist/commands/init.js +319 -0
  20. package/dist/commands/init.js.map +1 -0
  21. package/dist/commands/stats.d.ts +5 -0
  22. package/dist/commands/stats.js +87 -0
  23. package/dist/commands/stats.js.map +1 -0
  24. package/dist/deliver/ci.d.ts +4 -0
  25. package/dist/deliver/ci.js +62 -0
  26. package/dist/deliver/ci.js.map +1 -0
  27. package/dist/deliver/claudemd.d.ts +9 -0
  28. package/dist/deliver/claudemd.js +51 -0
  29. package/dist/deliver/claudemd.js.map +1 -0
  30. package/dist/deliver/cross-tool.d.ts +10 -0
  31. package/dist/deliver/cross-tool.js +49 -0
  32. package/dist/deliver/cross-tool.js.map +1 -0
  33. package/dist/deliver/git-hook.d.ts +10 -0
  34. package/dist/deliver/git-hook.js +104 -0
  35. package/dist/deliver/git-hook.js.map +1 -0
  36. package/dist/deliver/hooks.d.ts +9 -0
  37. package/dist/deliver/hooks.js +315 -0
  38. package/dist/deliver/hooks.js.map +1 -0
  39. package/dist/extract/complexity.d.ts +16 -0
  40. package/dist/extract/complexity.js +46 -0
  41. package/dist/extract/complexity.js.map +1 -0
  42. package/dist/extract/conventions.d.ts +18 -0
  43. package/dist/extract/conventions.js +143 -0
  44. package/dist/extract/conventions.js.map +1 -0
  45. package/dist/extract/depgraph.d.ts +12 -0
  46. package/dist/extract/depgraph.js +70 -0
  47. package/dist/extract/depgraph.js.map +1 -0
  48. package/dist/extract/env.d.ts +17 -0
  49. package/dist/extract/env.js +142 -0
  50. package/dist/extract/env.js.map +1 -0
  51. package/dist/extract/error-patterns.d.ts +15 -0
  52. package/dist/extract/error-patterns.js +107 -0
  53. package/dist/extract/error-patterns.js.map +1 -0
  54. package/dist/extract/frontend.d.ts +30 -0
  55. package/dist/extract/frontend.js +244 -0
  56. package/dist/extract/frontend.js.map +1 -0
  57. package/dist/extract/gotchas.d.ts +12 -0
  58. package/dist/extract/gotchas.js +145 -0
  59. package/dist/extract/gotchas.js.map +1 -0
  60. package/dist/extract/history.d.ts +29 -0
  61. package/dist/extract/history.js +91 -0
  62. package/dist/extract/history.js.map +1 -0
  63. package/dist/extract/infra.d.ts +27 -0
  64. package/dist/extract/infra.js +226 -0
  65. package/dist/extract/infra.js.map +1 -0
  66. package/dist/extract/monorepo.d.ts +16 -0
  67. package/dist/extract/monorepo.js +135 -0
  68. package/dist/extract/monorepo.js.map +1 -0
  69. package/dist/extract/routes.d.ts +16 -0
  70. package/dist/extract/routes.js +156 -0
  71. package/dist/extract/routes.js.map +1 -0
  72. package/dist/extract/scanner.d.ts +18 -0
  73. package/dist/extract/scanner.js +109 -0
  74. package/dist/extract/scanner.js.map +1 -0
  75. package/dist/extract/schema.d.ts +28 -0
  76. package/dist/extract/schema.js +192 -0
  77. package/dist/extract/schema.js.map +1 -0
  78. package/dist/extract/scripts.d.ts +18 -0
  79. package/dist/extract/scripts.js +104 -0
  80. package/dist/extract/scripts.js.map +1 -0
  81. package/dist/extract/security.d.ts +20 -0
  82. package/dist/extract/security.js +95 -0
  83. package/dist/extract/security.js.map +1 -0
  84. package/dist/extract/signatures.d.ts +33 -0
  85. package/dist/extract/signatures.js +608 -0
  86. package/dist/extract/signatures.js.map +1 -0
  87. package/dist/extract/staleness.d.ts +16 -0
  88. package/dist/extract/staleness.js +108 -0
  89. package/dist/extract/staleness.js.map +1 -0
  90. package/dist/extract/tests.d.ts +16 -0
  91. package/dist/extract/tests.js +175 -0
  92. package/dist/extract/tests.js.map +1 -0
  93. package/dist/extract/usage-examples.d.ts +17 -0
  94. package/dist/extract/usage-examples.js +115 -0
  95. package/dist/extract/usage-examples.js.map +1 -0
  96. package/dist/generate/index-file.d.ts +29 -0
  97. package/dist/generate/index-file.js +168 -0
  98. package/dist/generate/index-file.js.map +1 -0
  99. package/dist/generate/rules.d.ts +6 -0
  100. package/dist/generate/rules.js +94 -0
  101. package/dist/generate/rules.js.map +1 -0
  102. package/dist/generate/skeleton.d.ts +14 -0
  103. package/dist/generate/skeleton.js +145 -0
  104. package/dist/generate/skeleton.js.map +1 -0
  105. package/dist/learn/tracker.d.ts +54 -0
  106. package/dist/learn/tracker.js +129 -0
  107. package/dist/learn/tracker.js.map +1 -0
  108. package/dist/utils/detect.d.ts +16 -0
  109. package/dist/utils/detect.js +188 -0
  110. package/dist/utils/detect.js.map +1 -0
  111. package/dist/utils/pagerank.d.ts +19 -0
  112. package/dist/utils/pagerank.js +52 -0
  113. package/dist/utils/pagerank.js.map +1 -0
  114. package/dist/utils/tokens.d.ts +11 -0
  115. package/dist/utils/tokens.js +27 -0
  116. package/dist/utils/tokens.js.map +1 -0
  117. package/package.json +43 -0
@@ -0,0 +1,192 @@
1
+ import { readFileSync } from "fs";
2
+ import { join } from "path";
3
+ import { glob } from "glob";
4
+ /**
5
+ * Extract database schema from ORM definition files.
6
+ * Supports: Prisma, Drizzle, Django models, SQLAlchemy, TypeORM entities.
7
+ */
8
+ export function extractSchemas(root) {
9
+ const models = [];
10
+ // Prisma
11
+ const prismaFiles = glob.sync("**/schema.prisma", { cwd: root, ignore: ["node_modules/**"] });
12
+ for (const f of prismaFiles) {
13
+ models.push(...parsePrisma(readFileSync(join(root, f), "utf-8"), f));
14
+ }
15
+ // Drizzle
16
+ const drizzleFiles = glob.sync("**/{schema,db}.{ts,js}", { cwd: root, ignore: ["node_modules/**", "dist/**"] });
17
+ for (const f of drizzleFiles) {
18
+ const content = readFileSync(join(root, f), "utf-8");
19
+ if (content.includes("pgTable") || content.includes("mysqlTable") || content.includes("sqliteTable")) {
20
+ models.push(...parseDrizzle(content, f));
21
+ }
22
+ }
23
+ // Django models
24
+ const djangoFiles = glob.sync("**/models.py", { cwd: root, ignore: ["venv/**", ".venv/**"] });
25
+ for (const f of djangoFiles) {
26
+ const content = readFileSync(join(root, f), "utf-8");
27
+ if (content.includes("models.Model")) {
28
+ models.push(...parseDjango(content, f));
29
+ }
30
+ }
31
+ // TypeORM entities
32
+ const typeormFiles = glob.sync("**/*.entity.{ts,js}", { cwd: root, ignore: ["node_modules/**", "dist/**"] });
33
+ for (const f of typeormFiles) {
34
+ models.push(...parseTypeORM(readFileSync(join(root, f), "utf-8"), f));
35
+ }
36
+ return models;
37
+ }
38
+ function parsePrisma(content, source) {
39
+ const models = [];
40
+ const modelRegex = /model\s+(\w+)\s*\{([\s\S]*?)\n\}/g;
41
+ for (const match of content.matchAll(modelRegex)) {
42
+ const name = match[1];
43
+ const body = match[2];
44
+ const fields = [];
45
+ const relations = [];
46
+ for (const line of body.split("\n")) {
47
+ const trimmed = line.trim();
48
+ if (!trimmed || trimmed.startsWith("//") || trimmed.startsWith("@@"))
49
+ continue;
50
+ const fieldMatch = trimmed.match(/^(\w+)\s+(\w+)(\[\])?([\?!]?)\s*(.*)/);
51
+ if (fieldMatch) {
52
+ const [, fname, ftype, isArray, optional, rest] = fieldMatch;
53
+ const isRelation = /^[A-Z]/.test(ftype) && ftype !== "String" && ftype !== "Int" &&
54
+ ftype !== "Float" && ftype !== "Boolean" && ftype !== "DateTime" &&
55
+ ftype !== "Json" && ftype !== "Bytes" && ftype !== "BigInt" && ftype !== "Decimal";
56
+ if (isRelation) {
57
+ relations.push({
58
+ field: fname,
59
+ target: ftype,
60
+ type: isArray ? "one-to-many" : "one-to-one",
61
+ });
62
+ }
63
+ else {
64
+ fields.push({
65
+ name: fname,
66
+ type: isArray ? `${ftype}[]` : ftype,
67
+ optional: optional === "?",
68
+ unique: rest.includes("@unique"),
69
+ default: rest.match(/@default\((.+?)\)/)?.[1] || null,
70
+ isPk: rest.includes("@id"),
71
+ });
72
+ }
73
+ }
74
+ }
75
+ models.push({ name, fields, relations, source });
76
+ }
77
+ return models;
78
+ }
79
+ function parseDrizzle(content, source) {
80
+ const models = [];
81
+ const tableRegex = /(?:export\s+const\s+)?(\w+)\s*=\s*(?:pgTable|mysqlTable|sqliteTable)\s*\(\s*['"](\w+)['"]\s*,\s*\{([\s\S]*?)\}\s*\)/g;
82
+ for (const match of content.matchAll(tableRegex)) {
83
+ const varName = match[1];
84
+ const tableName = match[2];
85
+ const body = match[3];
86
+ const fields = [];
87
+ const fieldRegex = /(\w+)\s*:\s*(\w+)\s*\(\s*['"]?(\w+)?['"]?\s*\)/g;
88
+ for (const fm of body.matchAll(fieldRegex)) {
89
+ fields.push({
90
+ name: fm[1],
91
+ type: fm[2],
92
+ optional: body.includes(`${fm[1]}`) && body.includes(".default("),
93
+ unique: false,
94
+ default: null,
95
+ isPk: fm[2] === "serial" || body.includes(`${fm[1]}`) && body.includes(".primaryKey()"),
96
+ });
97
+ }
98
+ models.push({ name: tableName, fields, relations: [], source });
99
+ }
100
+ return models;
101
+ }
102
+ function parseDjango(content, source) {
103
+ const models = [];
104
+ const classRegex = /class\s+(\w+)\s*\(.*?models\.Model.*?\)\s*:([\s\S]*?)(?=\nclass\s|\n\S|$)/g;
105
+ for (const match of content.matchAll(classRegex)) {
106
+ const name = match[1];
107
+ const body = match[2];
108
+ const fields = [];
109
+ const relations = [];
110
+ const fieldRegex = /(\w+)\s*=\s*models\.(\w+)\s*\(/g;
111
+ for (const fm of body.matchAll(fieldRegex)) {
112
+ const fieldType = fm[2];
113
+ if (["ForeignKey", "OneToOneField", "ManyToManyField"].includes(fieldType)) {
114
+ const targetMatch = body.slice(fm.index).match(/models\.\w+\(\s*['"]?(\w+)/);
115
+ relations.push({
116
+ field: fm[1],
117
+ target: targetMatch?.[1] || "unknown",
118
+ type: fieldType === "ManyToManyField" ? "many-to-many" : fieldType === "OneToOneField" ? "one-to-one" : "one-to-many",
119
+ });
120
+ }
121
+ else {
122
+ fields.push({
123
+ name: fm[1],
124
+ type: fieldType,
125
+ optional: body.includes("null=True") || body.includes("blank=True"),
126
+ unique: body.includes("unique=True"),
127
+ default: null,
128
+ isPk: fieldType === "AutoField" || fm[1] === "id",
129
+ });
130
+ }
131
+ }
132
+ models.push({ name, fields, relations, source });
133
+ }
134
+ return models;
135
+ }
136
+ function parseTypeORM(content, source) {
137
+ const models = [];
138
+ const classMatch = content.match(/class\s+(\w+)/);
139
+ if (!classMatch)
140
+ return models;
141
+ const name = classMatch[1];
142
+ const fields = [];
143
+ const relations = [];
144
+ const colRegex = /@(?:Column|PrimaryGeneratedColumn|PrimaryColumn)\s*\(([^)]*)\)\s*\n\s*(\w+)\s*[!?]?\s*:\s*(\w+)/g;
145
+ for (const m of content.matchAll(colRegex)) {
146
+ fields.push({
147
+ name: m[2],
148
+ type: m[3],
149
+ optional: m[0].includes("nullable: true"),
150
+ unique: m[0].includes("unique: true"),
151
+ default: null,
152
+ isPk: m[0].includes("PrimaryGeneratedColumn") || m[0].includes("PrimaryColumn"),
153
+ });
154
+ }
155
+ const relRegex = /@(?:ManyToOne|OneToMany|OneToOne|ManyToMany)\s*\([^)]*\)\s*\n\s*(\w+)\s*[!?]?\s*:\s*(\w+)/g;
156
+ for (const m of content.matchAll(relRegex)) {
157
+ const relType = m[0].includes("ManyToMany") ? "many-to-many" : m[0].includes("OneToMany") ? "one-to-many" : "one-to-one";
158
+ relations.push({ field: m[1], target: m[2], type: relType });
159
+ }
160
+ models.push({ name, fields, relations, source });
161
+ return models;
162
+ }
163
+ /**
164
+ * Format schemas for skeleton inclusion.
165
+ */
166
+ export function formatSchemas(models) {
167
+ if (models.length === 0)
168
+ return "";
169
+ const lines = ["Database schema:"];
170
+ for (const m of models) {
171
+ const fieldList = m.fields
172
+ .map((f) => {
173
+ let s = `${f.name}: ${f.type}`;
174
+ if (f.isPk)
175
+ s += " (pk)";
176
+ if (f.unique)
177
+ s += " (unique)";
178
+ if (f.optional)
179
+ s += "?";
180
+ if (f.default)
181
+ s += ` = ${f.default}`;
182
+ return s;
183
+ })
184
+ .join(", ");
185
+ const relList = m.relations
186
+ .map((r) => `${r.field} → ${r.target} (${r.type})`)
187
+ .join(", ");
188
+ lines.push(` ${m.name}: ${fieldList}${relList ? ` | ${relList}` : ""}`);
189
+ }
190
+ return lines.join("\n");
191
+ }
192
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/extract/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ export interface ProjectScripts {
2
+ build: string | null;
3
+ dev: string | null;
4
+ test: string | null;
5
+ lint: string | null;
6
+ start: string | null;
7
+ deploy: string | null;
8
+ other: Record<string, string>;
9
+ }
10
+ /**
11
+ * Extract build/test/dev commands from package.json, Makefile, etc.
12
+ * Claude needs to know how to run things.
13
+ */
14
+ export declare function extractScripts(root: string): ProjectScripts;
15
+ /**
16
+ * Format scripts for skeleton inclusion.
17
+ */
18
+ export declare function formatScripts(scripts: ProjectScripts): string;
@@ -0,0 +1,104 @@
1
+ import { readFileSync, existsSync } from "fs";
2
+ import { join } from "path";
3
+ /**
4
+ * Extract build/test/dev commands from package.json, Makefile, etc.
5
+ * Claude needs to know how to run things.
6
+ */
7
+ export function extractScripts(root) {
8
+ const scripts = {
9
+ build: null,
10
+ dev: null,
11
+ test: null,
12
+ lint: null,
13
+ start: null,
14
+ deploy: null,
15
+ other: {},
16
+ };
17
+ // package.json
18
+ const pkgPath = join(root, "package.json");
19
+ if (existsSync(pkgPath)) {
20
+ try {
21
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
22
+ const s = pkg.scripts || {};
23
+ scripts.build = s.build || null;
24
+ scripts.dev = s.dev || s.serve || s.start?.includes("--watch") ? (s.dev || s.serve) : null;
25
+ scripts.test = s.test || s["test:unit"] || null;
26
+ scripts.lint = s.lint || s["lint:fix"] || null;
27
+ scripts.start = s.start || null;
28
+ scripts.deploy = s.deploy || s.release || null;
29
+ // Collect other interesting scripts
30
+ for (const [name, cmd] of Object.entries(s)) {
31
+ if (["build", "dev", "test", "lint", "start", "deploy", "serve", "postinstall", "prepare", "precommit"].includes(name))
32
+ continue;
33
+ if (typeof cmd === "string" && name.length < 20) {
34
+ scripts.other[name] = cmd;
35
+ }
36
+ }
37
+ }
38
+ catch { /* skip */ }
39
+ }
40
+ // Makefile
41
+ const makefilePath = join(root, "Makefile");
42
+ if (existsSync(makefilePath)) {
43
+ try {
44
+ const content = readFileSync(makefilePath, "utf-8");
45
+ const targets = content.matchAll(/^(\w[\w-]*)\s*:/gm);
46
+ for (const match of targets) {
47
+ const target = match[1];
48
+ if (target === "build" && !scripts.build)
49
+ scripts.build = `make build`;
50
+ if (target === "test" && !scripts.test)
51
+ scripts.test = `make test`;
52
+ if (target === "dev" && !scripts.dev)
53
+ scripts.dev = `make dev`;
54
+ if (target === "lint" && !scripts.lint)
55
+ scripts.lint = `make lint`;
56
+ if (target === "deploy" && !scripts.deploy)
57
+ scripts.deploy = `make deploy`;
58
+ }
59
+ }
60
+ catch { /* skip */ }
61
+ }
62
+ // Go
63
+ if (existsSync(join(root, "go.mod"))) {
64
+ if (!scripts.build)
65
+ scripts.build = "go build ./...";
66
+ if (!scripts.test)
67
+ scripts.test = "go test ./...";
68
+ }
69
+ // Rust
70
+ if (existsSync(join(root, "Cargo.toml"))) {
71
+ if (!scripts.build)
72
+ scripts.build = "cargo build";
73
+ if (!scripts.test)
74
+ scripts.test = "cargo test";
75
+ }
76
+ // Python
77
+ if (existsSync(join(root, "pyproject.toml"))) {
78
+ if (!scripts.test)
79
+ scripts.test = "pytest";
80
+ }
81
+ return scripts;
82
+ }
83
+ /**
84
+ * Format scripts for skeleton inclusion.
85
+ */
86
+ export function formatScripts(scripts) {
87
+ const lines = ["Commands:"];
88
+ if (scripts.build)
89
+ lines.push(` build: ${scripts.build}`);
90
+ if (scripts.dev)
91
+ lines.push(` dev: ${scripts.dev}`);
92
+ if (scripts.test)
93
+ lines.push(` test: ${scripts.test}`);
94
+ if (scripts.lint)
95
+ lines.push(` lint: ${scripts.lint}`);
96
+ if (scripts.start)
97
+ lines.push(` start: ${scripts.start}`);
98
+ if (scripts.deploy)
99
+ lines.push(` deploy: ${scripts.deploy}`);
100
+ if (lines.length === 1)
101
+ return ""; // no scripts found
102
+ return lines.join("\n");
103
+ }
104
+ //# sourceMappingURL=scripts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scripts.js","sourceRoot":"","sources":["../../src/extract/scripts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ export interface SecurityWarning {
2
+ file: string;
3
+ line: number;
4
+ type: SecurityIssueType;
5
+ detail: string;
6
+ }
7
+ export type SecurityIssueType = "api_key" | "password" | "secret" | "private_key" | "connection_string" | "token" | "sensitive_file";
8
+ /**
9
+ * Check if a file should be excluded from context output for security reasons.
10
+ */
11
+ export declare function isSensitiveFile(filePath: string): boolean;
12
+ /**
13
+ * Scan a file for sensitive data patterns.
14
+ * Returns warnings but does NOT include the actual secret values.
15
+ */
16
+ export declare function scanForSecrets(filePath: string): SecurityWarning[];
17
+ /**
18
+ * Redact sensitive values from text before including in context.
19
+ */
20
+ export declare function redactSecrets(text: string): string;
@@ -0,0 +1,95 @@
1
+ import { readFileSync } from "fs";
2
+ import { basename } from "path";
3
+ /** Files that should NEVER be included in context output */
4
+ const SENSITIVE_FILENAMES = new Set([
5
+ ".env",
6
+ ".env.local",
7
+ ".env.production",
8
+ ".env.development",
9
+ "credentials.json",
10
+ "service-account.json",
11
+ "secrets.yaml",
12
+ "secrets.yml",
13
+ ".npmrc",
14
+ ".pypirc",
15
+ "id_rsa",
16
+ "id_ed25519",
17
+ ".pem",
18
+ ".key",
19
+ ]);
20
+ /** Patterns that indicate sensitive values in code */
21
+ const SECRET_PATTERNS = [
22
+ { regex: /(?:api[_-]?key|apikey)\s*[:=]\s*['"][^'"]{8,}/i, type: "api_key", label: "API key" },
23
+ { regex: /(?:password|passwd|pwd)\s*[:=]\s*['"][^'"]+/i, type: "password", label: "password" },
24
+ { regex: /(?:secret|client_secret)\s*[:=]\s*['"][^'"]{8,}/i, type: "secret", label: "secret" },
25
+ { regex: /-----BEGIN (?:RSA |EC |DSA )?PRIVATE KEY-----/i, type: "private_key", label: "private key" },
26
+ { regex: /(?:postgres|mysql|mongodb|redis):\/\/\w+:[^@]+@/i, type: "connection_string", label: "connection string with credentials" },
27
+ { regex: /(?:bearer|token)\s+[a-zA-Z0-9_\-.]{20,}/i, type: "token", label: "auth token" },
28
+ { regex: /(?:aws_secret_access_key|AWS_SECRET)\s*[:=]\s*['"]?[A-Za-z0-9/+=]{20,}/i, type: "secret", label: "AWS secret key" },
29
+ { regex: /(?:ghp_|github_pat_)[a-zA-Z0-9]{30,}/i, type: "token", label: "GitHub token" },
30
+ { regex: /sk-[a-zA-Z0-9]{20,}/i, type: "api_key", label: "OpenAI/Stripe secret key" },
31
+ ];
32
+ /**
33
+ * Check if a file should be excluded from context output for security reasons.
34
+ */
35
+ export function isSensitiveFile(filePath) {
36
+ const name = basename(filePath);
37
+ if (SENSITIVE_FILENAMES.has(name))
38
+ return true;
39
+ if (name.endsWith(".pem") || name.endsWith(".key") || name.endsWith(".p12"))
40
+ return true;
41
+ if (name.startsWith(".env"))
42
+ return true;
43
+ return false;
44
+ }
45
+ /**
46
+ * Scan a file for sensitive data patterns.
47
+ * Returns warnings but does NOT include the actual secret values.
48
+ */
49
+ export function scanForSecrets(filePath) {
50
+ const warnings = [];
51
+ // Skip binary files
52
+ try {
53
+ const content = readFileSync(filePath, "utf-8");
54
+ const lines = content.split("\n");
55
+ for (let i = 0; i < lines.length; i++) {
56
+ const line = lines[i];
57
+ // Skip comments that reference secrets generically
58
+ if (line.trim().startsWith("//") || line.trim().startsWith("#")) {
59
+ // Still check for actual hardcoded values in comments
60
+ if (!line.includes("=") && !line.includes(":"))
61
+ continue;
62
+ }
63
+ for (const pattern of SECRET_PATTERNS) {
64
+ if (pattern.regex.test(line)) {
65
+ // Don't flag env var references (process.env.X, os.environ, etc.)
66
+ if (line.includes("process.env") || line.includes("os.environ") ||
67
+ line.includes("${") || line.includes("getenv")) {
68
+ continue;
69
+ }
70
+ warnings.push({
71
+ file: filePath,
72
+ line: i + 1,
73
+ type: pattern.type,
74
+ detail: `Possible ${pattern.label} found — not included in context output`,
75
+ });
76
+ }
77
+ }
78
+ }
79
+ }
80
+ catch {
81
+ // Can't read file — skip
82
+ }
83
+ return warnings;
84
+ }
85
+ /**
86
+ * Redact sensitive values from text before including in context.
87
+ */
88
+ export function redactSecrets(text) {
89
+ let result = text;
90
+ for (const pattern of SECRET_PATTERNS) {
91
+ result = result.replace(pattern.regex, `[REDACTED ${pattern.label}]`);
92
+ }
93
+ return result;
94
+ }
95
+ //# sourceMappingURL=security.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.js","sourceRoot":"","sources":["../../src/extract/security.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Extracted symbol from a source file.
3
+ * Represents exports, functions, classes, types — the structural skeleton.
4
+ */
5
+ export interface Symbol {
6
+ name: string;
7
+ kind: SymbolKind;
8
+ signature: string;
9
+ description: string | null;
10
+ exported: boolean;
11
+ line: number;
12
+ }
13
+ export type SymbolKind = "function" | "class" | "interface" | "type" | "enum" | "variable" | "method" | "component" | "route" | "unknown";
14
+ /**
15
+ * Import reference found in a file.
16
+ */
17
+ export interface ImportRef {
18
+ source: string;
19
+ names: string[];
20
+ isRelative: boolean;
21
+ }
22
+ export interface FileExtraction {
23
+ path: string;
24
+ symbols: Symbol[];
25
+ imports: ImportRef[];
26
+ lineCount: number;
27
+ }
28
+ /**
29
+ * Extract symbols and imports from a source file.
30
+ * Uses regex-based extraction (fast, no WASM dependency).
31
+ * Covers TypeScript, JavaScript, Python, Go, Rust, Java.
32
+ */
33
+ export declare function extractFile(filePath: string, rootPath: string): FileExtraction;