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,17 @@
1
+ export interface EnvVar {
2
+ name: string;
3
+ source: string;
4
+ hasDefault: boolean;
5
+ required: boolean;
6
+ description: string | null;
7
+ category: string;
8
+ }
9
+ /**
10
+ * Extract environment variables the project expects.
11
+ * Sources: .env.example, .env.sample, process.env references, config files.
12
+ */
13
+ export declare function extractEnvVars(root: string): EnvVar[];
14
+ /**
15
+ * Format env vars for skeleton inclusion.
16
+ */
17
+ export declare function formatEnvVars(vars: EnvVar[]): string;
@@ -0,0 +1,142 @@
1
+ import { readFileSync, existsSync } from "fs";
2
+ import { join } from "path";
3
+ import { glob } from "glob";
4
+ /**
5
+ * Extract environment variables the project expects.
6
+ * Sources: .env.example, .env.sample, process.env references, config files.
7
+ */
8
+ export function extractEnvVars(root) {
9
+ const vars = new Map();
10
+ // 1. Parse .env.example / .env.sample
11
+ const envFiles = [".env.example", ".env.sample", ".env.template", ".env.defaults"];
12
+ for (const ef of envFiles) {
13
+ const path = join(root, ef);
14
+ if (existsSync(path)) {
15
+ parseEnvFile(readFileSync(path, "utf-8"), ef, vars);
16
+ }
17
+ }
18
+ // 2. Scan source files for process.env / os.environ references
19
+ const sourceFiles = glob.sync("**/*.{ts,tsx,js,jsx,py}", {
20
+ cwd: root,
21
+ ignore: ["node_modules/**", "dist/**", "venv/**", ".venv/**", "test/**", "*.test.*"],
22
+ });
23
+ for (const f of sourceFiles) {
24
+ let content;
25
+ try {
26
+ content = readFileSync(join(root, f), "utf-8");
27
+ }
28
+ catch {
29
+ continue;
30
+ }
31
+ // JavaScript/TypeScript: process.env.VAR_NAME
32
+ const jsEnvRegex = /process\.env\.(\w+)/g;
33
+ for (const match of content.matchAll(jsEnvRegex)) {
34
+ addVar(vars, match[1], f, false);
35
+ }
36
+ // JavaScript/TypeScript: process.env['VAR_NAME'] or process.env["VAR_NAME"]
37
+ const jsEnvBracket = /process\.env\[['"](\w+)['"]\]/g;
38
+ for (const match of content.matchAll(jsEnvBracket)) {
39
+ addVar(vars, match[1], f, false);
40
+ }
41
+ // Python: os.environ['VAR'] or os.environ.get('VAR') or os.getenv('VAR')
42
+ const pyEnvRegex = /(?:os\.environ\[['"](\w+)['"]\]|os\.environ\.get\(\s*['"](\w+)['"]|os\.getenv\(\s*['"](\w+)['"])/g;
43
+ for (const match of content.matchAll(pyEnvRegex)) {
44
+ const name = match[1] || match[2] || match[3];
45
+ addVar(vars, name, f, match[0].includes(".get(") || match[0].includes("getenv"));
46
+ }
47
+ }
48
+ // 3. Check config files (next.config, vite.config, etc.)
49
+ const configFiles = glob.sync("{next,vite,nuxt,astro}.config.{ts,js,mjs}", { cwd: root });
50
+ for (const f of configFiles) {
51
+ try {
52
+ const content = readFileSync(join(root, f), "utf-8");
53
+ const envRefs = content.matchAll(/process\.env\.(\w+)/g);
54
+ for (const match of envRefs) {
55
+ addVar(vars, match[1], f, false);
56
+ }
57
+ }
58
+ catch { /* skip */ }
59
+ }
60
+ return [...vars.values()];
61
+ }
62
+ function parseEnvFile(content, source, vars) {
63
+ let lastComment = "";
64
+ for (const line of content.split("\n")) {
65
+ const trimmed = line.trim();
66
+ if (trimmed.startsWith("#")) {
67
+ lastComment = trimmed.slice(1).trim();
68
+ continue;
69
+ }
70
+ const match = trimmed.match(/^(\w+)\s*=\s*(.*)/);
71
+ if (match) {
72
+ const name = match[1];
73
+ const value = match[2].trim();
74
+ const hasDefault = value.length > 0 && value !== '""' && value !== "''";
75
+ vars.set(name, {
76
+ name,
77
+ source,
78
+ hasDefault,
79
+ required: !hasDefault,
80
+ description: lastComment || null,
81
+ category: categorizeEnvVar(name),
82
+ });
83
+ lastComment = "";
84
+ }
85
+ }
86
+ }
87
+ function addVar(vars, name, source, hasDefault) {
88
+ if (vars.has(name))
89
+ return; // .env.example takes precedence
90
+ // Skip common Node/system vars
91
+ if (["NODE_ENV", "PATH", "HOME", "USER", "PWD", "SHELL", "TERM"].includes(name))
92
+ return;
93
+ vars.set(name, {
94
+ name,
95
+ source,
96
+ hasDefault,
97
+ required: !hasDefault,
98
+ description: null,
99
+ category: categorizeEnvVar(name),
100
+ });
101
+ }
102
+ function categorizeEnvVar(name) {
103
+ const n = name.toUpperCase();
104
+ if (n.includes("DATABASE") || n.includes("DB_") || n.includes("POSTGRES") ||
105
+ n.includes("MYSQL") || n.includes("MONGO") || n.includes("REDIS"))
106
+ return "database";
107
+ if (n.includes("AUTH") || n.includes("JWT") || n.includes("SESSION") ||
108
+ n.includes("SECRET") || n.includes("OAUTH") || n.includes("TOKEN"))
109
+ return "auth";
110
+ if (n.includes("API") || n.includes("URL") || n.includes("ENDPOINT") ||
111
+ n.includes("HOST") || n.includes("PORT"))
112
+ return "api";
113
+ if (n.includes("AWS") || n.includes("S3") || n.includes("CLOUD") ||
114
+ n.includes("STRIPE") || n.includes("SENDGRID") || n.includes("TWILIO"))
115
+ return "services";
116
+ return "config";
117
+ }
118
+ /**
119
+ * Format env vars for skeleton inclusion.
120
+ */
121
+ export function formatEnvVars(vars) {
122
+ if (vars.length === 0)
123
+ return "";
124
+ const lines = ["Environment variables:"];
125
+ const byCategory = new Map();
126
+ for (const v of vars) {
127
+ if (!byCategory.has(v.category))
128
+ byCategory.set(v.category, []);
129
+ byCategory.get(v.category).push(v);
130
+ }
131
+ for (const [cat, catVars] of byCategory) {
132
+ const names = catVars.map((v) => {
133
+ let s = v.name;
134
+ if (v.required)
135
+ s += " (required)";
136
+ return s;
137
+ });
138
+ lines.push(` ${cat}: ${names.join(", ")}`);
139
+ }
140
+ return lines.join("\n");
141
+ }
142
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/extract/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAW5B;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAkB,CAAC;IAEvC,sCAAsC;IACtC,MAAM,QAAQ,GAAG,CAAC,cAAc,EAAE,aAAa,EAAE,eAAe,EAAE,eAAe,CAAC,CAAC;IACnF,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC5B,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,YAAY,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAED,+DAA+D;IAC/D,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,yBAAyB,EAAE;QACvD,GAAG,EAAE,IAAI;QACT,MAAM,EAAE,CAAC,iBAAiB,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,CAAC;KACrF,CAAC,CAAC;IAEH,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC5B,IAAI,OAAe,CAAC;QACpB,IAAI,CAAC;YACH,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QACjD,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QAED,8CAA8C;QAC9C,MAAM,UAAU,GAAG,sBAAsB,CAAC;QAC1C,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YACjD,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QACnC,CAAC;QAED,4EAA4E;QAC5E,MAAM,YAAY,GAAG,gCAAgC,CAAC;QACtD,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YACnD,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QACnC,CAAC;QAED,yEAAyE;QACzE,MAAM,UAAU,GAAG,mGAAmG,CAAC;QACvH,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YACjD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;YAC9C,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;QACnF,CAAC;IACH,CAAC;IAED,yDAAyD;IACzD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,2CAA2C,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1F,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YACrD,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CAAC;YACzD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC;IACxB,CAAC;IAED,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;AAC5B,CAAC;AAED,SAAS,YAAY,CAAC,OAAe,EAAE,MAAc,EAAE,IAAyB;IAC9E,IAAI,WAAW,GAAG,EAAE,CAAC;IACrB,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5B,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACtC,SAAS;QACX,CAAC;QACD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACjD,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACtB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC9B,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI,CAAC;YAExE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;gBACb,IAAI;gBACJ,MAAM;gBACN,UAAU;gBACV,QAAQ,EAAE,CAAC,UAAU;gBACrB,WAAW,EAAE,WAAW,IAAI,IAAI;gBAChC,QAAQ,EAAE,gBAAgB,CAAC,IAAI,CAAC;aACjC,CAAC,CAAC;YACH,WAAW,GAAG,EAAE,CAAC;QACnB,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,MAAM,CAAC,IAAyB,EAAE,IAAY,EAAE,MAAc,EAAE,UAAmB;IAC1F,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,gCAAgC;IAC5D,+BAA+B;IAC/B,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO;IAExF,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;QACb,IAAI;QACJ,MAAM;QACN,UAAU;QACV,QAAQ,EAAE,CAAC,UAAU;QACrB,WAAW,EAAE,IAAI;QACjB,QAAQ,EAAE,gBAAgB,CAAC,IAAI,CAAC;KACjC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAY;IACpC,MAAM,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAC7B,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC;QACrE,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,UAAU,CAAC;IACzF,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC;QAChE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,MAAM,CAAC;IACtF,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC;QAChE,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IAC3D,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;QAC5D,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,UAAU,CAAC;IAC9F,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,IAAc;IAC1C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEjC,MAAM,KAAK,GAAa,CAAC,wBAAwB,CAAC,CAAC;IACnD,MAAM,UAAU,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC/C,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC;YAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAChE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC;IAED,KAAK,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,UAAU,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YAC9B,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACf,IAAI,CAAC,CAAC,QAAQ;gBAAE,CAAC,IAAI,aAAa,CAAC;YACnC,OAAO,CAAC,CAAC;QACX,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,15 @@
1
+ export interface ErrorPattern {
2
+ file: string;
3
+ pattern: ErrorPatternType;
4
+ detail: string;
5
+ }
6
+ export type ErrorPatternType = "try_catch_style" | "error_class" | "result_type" | "guard_return" | "error_propagation" | "validation_style";
7
+ /**
8
+ * Detect the project's error handling patterns.
9
+ * Research shows AI generates 2x more error handling bugs — knowing the project's
10
+ * patterns prevents silent failures and inconsistent error handling.
11
+ */
12
+ export declare function detectErrorPatterns(filePaths: string[]): {
13
+ patterns: ErrorPattern[];
14
+ summary: string[];
15
+ };
@@ -0,0 +1,107 @@
1
+ import { readFileSync } from "fs";
2
+ import { extname } from "path";
3
+ /**
4
+ * Detect the project's error handling patterns.
5
+ * Research shows AI generates 2x more error handling bugs — knowing the project's
6
+ * patterns prevents silent failures and inconsistent error handling.
7
+ */
8
+ export function detectErrorPatterns(filePaths) {
9
+ const patterns = [];
10
+ const stats = {
11
+ tryCatch: 0,
12
+ customErrors: 0,
13
+ resultTypes: 0,
14
+ guardReturns: 0,
15
+ throws: 0,
16
+ zodValidation: 0,
17
+ manualValidation: 0,
18
+ filesScanned: 0,
19
+ };
20
+ for (const filePath of filePaths) {
21
+ const ext = extname(filePath);
22
+ if (![".ts", ".tsx", ".js", ".jsx", ".py", ".go", ".rs"].includes(ext))
23
+ continue;
24
+ let content;
25
+ try {
26
+ content = readFileSync(filePath, "utf-8");
27
+ }
28
+ catch {
29
+ continue;
30
+ }
31
+ stats.filesScanned++;
32
+ // Custom error classes
33
+ const customErrorMatch = content.match(/class\s+(\w+Error)\s+extends\s+(\w+Error|Error)/g);
34
+ if (customErrorMatch) {
35
+ stats.customErrors += customErrorMatch.length;
36
+ for (const m of customErrorMatch) {
37
+ const nameMatch = m.match(/class\s+(\w+)/);
38
+ if (nameMatch) {
39
+ patterns.push({
40
+ file: filePath,
41
+ pattern: "error_class",
42
+ detail: nameMatch[1],
43
+ });
44
+ }
45
+ }
46
+ }
47
+ // Result/Either types
48
+ if (content.includes("Result<") || content.includes("Either<") ||
49
+ content.includes("Result[") || content.includes("-> Result")) {
50
+ stats.resultTypes++;
51
+ patterns.push({
52
+ file: filePath,
53
+ pattern: "result_type",
54
+ detail: "Uses Result/Either type for error propagation",
55
+ });
56
+ }
57
+ // try/catch patterns
58
+ const tryCatchCount = (content.match(/\btry\s*\{/g) || []).length;
59
+ stats.tryCatch += tryCatchCount;
60
+ // Guard clause returns (early return on validation failure)
61
+ const guardMatches = content.match(/if\s*\([^)]*\)\s*(?:return|throw|raise)\b/g);
62
+ if (guardMatches) {
63
+ stats.guardReturns += guardMatches.length;
64
+ }
65
+ // throw new / raise patterns
66
+ const throwCount = (content.match(/throw\s+new\s+\w+/g) || []).length;
67
+ const raiseCount = (content.match(/raise\s+\w+/g) || []).length;
68
+ stats.throws += throwCount + raiseCount;
69
+ // Zod/Joi/Yup validation
70
+ if (content.includes(".parse(") || content.includes(".safeParse(") ||
71
+ content.includes("z.object(") || content.includes("Joi.object(") ||
72
+ content.includes("yup.object(")) {
73
+ stats.zodValidation++;
74
+ }
75
+ // Manual validation (typeof checks, instanceof)
76
+ const manualChecks = (content.match(/typeof\s+\w+\s*[!=]==?\s*['"]|instanceof\s+\w+/g) || []).length;
77
+ if (manualChecks > 3) {
78
+ stats.manualValidation++;
79
+ }
80
+ }
81
+ // Generate summary of detected patterns
82
+ const summary = [];
83
+ if (stats.customErrors > 0) {
84
+ const names = [...new Set(patterns.filter((p) => p.pattern === "error_class").map((p) => p.detail))];
85
+ summary.push(`Custom error classes: ${names.slice(0, 5).join(", ")}${names.length > 5 ? ` +${names.length - 5} more` : ""}`);
86
+ }
87
+ if (stats.resultTypes > 0) {
88
+ summary.push("Uses Result/Either types for error propagation (not exceptions)");
89
+ }
90
+ if (stats.tryCatch > stats.throws * 2 && stats.tryCatch > 5) {
91
+ summary.push("Prefers try/catch wrapping over throwing");
92
+ }
93
+ else if (stats.throws > stats.tryCatch && stats.throws > 3) {
94
+ summary.push("Throws errors to callers (expects upstream catch)");
95
+ }
96
+ if (stats.guardReturns > 5) {
97
+ summary.push("Uses guard clauses (early returns on validation failure)");
98
+ }
99
+ if (stats.zodValidation > 0) {
100
+ summary.push("Uses schema validation (Zod/Joi/Yup) for input validation");
101
+ }
102
+ else if (stats.manualValidation > 3) {
103
+ summary.push("Uses manual type checking for validation (typeof/instanceof)");
104
+ }
105
+ return { patterns, summary };
106
+ }
107
+ //# sourceMappingURL=error-patterns.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-patterns.js","sourceRoot":"","sources":["../../src/extract/error-patterns.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ export interface PageRoute {
2
+ path: string;
3
+ file: string;
4
+ layout: string | null;
5
+ isProtected: boolean;
6
+ }
7
+ export interface ComponentInfo {
8
+ name: string;
9
+ file: string;
10
+ props: string[];
11
+ children: boolean;
12
+ hooks: string[];
13
+ stateManagement: string[];
14
+ }
15
+ export interface FrontendInfo {
16
+ framework: string | null;
17
+ pages: PageRoute[];
18
+ components: ComponentInfo[];
19
+ stateStores: string[];
20
+ styling: string | null;
21
+ uiLibrary: string | null;
22
+ }
23
+ /**
24
+ * Extract frontend-specific context: pages, components, state, styling.
25
+ */
26
+ export declare function extractFrontend(root: string): FrontendInfo;
27
+ /**
28
+ * Format frontend info for skeleton inclusion.
29
+ */
30
+ export declare function formatFrontend(info: FrontendInfo): string;
@@ -0,0 +1,244 @@
1
+ import { readFileSync } from "fs";
2
+ import { glob } from "glob";
3
+ import { join, basename, dirname, extname } from "path";
4
+ /**
5
+ * Extract frontend-specific context: pages, components, state, styling.
6
+ */
7
+ export function extractFrontend(root) {
8
+ const info = {
9
+ framework: null,
10
+ pages: [],
11
+ components: [],
12
+ stateStores: [],
13
+ styling: null,
14
+ uiLibrary: null,
15
+ };
16
+ // Detect framework + styling + UI library from package.json
17
+ const pkgPath = join(root, "package.json");
18
+ try {
19
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
20
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
21
+ if (deps["next"])
22
+ info.framework = "next";
23
+ else if (deps["nuxt"])
24
+ info.framework = "nuxt";
25
+ else if (deps["@sveltejs/kit"])
26
+ info.framework = "sveltekit";
27
+ else if (deps["svelte"])
28
+ info.framework = "svelte";
29
+ else if (deps["vue"])
30
+ info.framework = "vue";
31
+ else if (deps["react"])
32
+ info.framework = "react";
33
+ else if (deps["@angular/core"])
34
+ info.framework = "angular";
35
+ if (deps["tailwindcss"])
36
+ info.styling = "tailwind";
37
+ else if (deps["styled-components"])
38
+ info.styling = "styled-components";
39
+ else if (deps["sass"] || deps["node-sass"])
40
+ info.styling = "scss";
41
+ else if (deps["@emotion/react"])
42
+ info.styling = "emotion";
43
+ if (deps["@shadcn/ui"] || deps["class-variance-authority"])
44
+ info.uiLibrary = "shadcn";
45
+ else if (deps["@mui/material"])
46
+ info.uiLibrary = "mui";
47
+ else if (deps["@chakra-ui/react"])
48
+ info.uiLibrary = "chakra";
49
+ else if (deps["@radix-ui/react-dialog"])
50
+ info.uiLibrary = "radix";
51
+ else if (deps["antd"])
52
+ info.uiLibrary = "antd";
53
+ }
54
+ catch { /* not a JS project */ }
55
+ // Extract pages
56
+ info.pages = extractPages(root, info.framework);
57
+ // Extract components
58
+ info.components = extractComponents(root);
59
+ // Extract state stores
60
+ info.stateStores = extractStateStores(root);
61
+ return info;
62
+ }
63
+ function extractPages(root, framework) {
64
+ const pages = [];
65
+ if (framework === "next") {
66
+ // Next.js App Router pages
67
+ const appPages = glob.sync("{src/app,app}/**/page.{tsx,jsx,ts,js}", { cwd: root });
68
+ for (const f of appPages) {
69
+ const path = "/" + dirname(f).replace(/^(?:src\/)?app\/?/, "").replace(/\(.*?\)\/?/g, "");
70
+ const content = tryRead(join(root, f));
71
+ const layoutFile = findLayout(root, f);
72
+ const isProtected = content?.includes("auth") || content?.includes("session") ||
73
+ content?.includes("getServerSession") || content?.includes("redirect") || false;
74
+ pages.push({
75
+ path: path || "/",
76
+ file: f,
77
+ layout: layoutFile,
78
+ isProtected,
79
+ });
80
+ }
81
+ // Next.js Pages Router
82
+ const pagesDir = glob.sync("pages/**/*.{tsx,jsx,ts,js}", {
83
+ cwd: root,
84
+ ignore: ["pages/api/**", "pages/_*"],
85
+ });
86
+ for (const f of pagesDir) {
87
+ const path = "/" + f.replace(/^pages\//, "").replace(/\.\w+$/, "").replace(/\/index$/, "");
88
+ pages.push({ path: path || "/", file: f, layout: null, isProtected: false });
89
+ }
90
+ }
91
+ if (framework === "vue" || framework === "nuxt") {
92
+ const vuePages = glob.sync("{pages,src/pages,src/views}/**/*.vue", { cwd: root });
93
+ for (const f of vuePages) {
94
+ const path = "/" + f.replace(/^(?:src\/)?(?:pages|views)\//, "").replace(/\.vue$/, "").replace(/\/index$/, "");
95
+ pages.push({ path, file: f, layout: null, isProtected: false });
96
+ }
97
+ }
98
+ if (framework === "sveltekit" || framework === "svelte") {
99
+ const sveltePages = glob.sync("src/routes/**/+page.svelte", { cwd: root });
100
+ for (const f of sveltePages) {
101
+ const path = "/" + dirname(f).replace(/^src\/routes\/?/, "").replace(/\(.*?\)\/?/g, "");
102
+ pages.push({ path: path || "/", file: f, layout: null, isProtected: false });
103
+ }
104
+ }
105
+ return pages;
106
+ }
107
+ function extractComponents(root) {
108
+ const components = [];
109
+ const componentFiles = glob.sync("{src/components,components,src/ui,app/components}/**/*.{tsx,jsx,vue,svelte}", {
110
+ cwd: root,
111
+ ignore: ["node_modules/**", "*.test.*", "*.spec.*", "*.stories.*"],
112
+ });
113
+ for (const f of componentFiles.slice(0, 50)) { // limit to 50
114
+ const content = tryRead(join(root, f));
115
+ if (!content)
116
+ continue;
117
+ const name = basename(f, extname(f));
118
+ const ext = extname(f);
119
+ const props = [];
120
+ const hooks = [];
121
+ let children = false;
122
+ if ([".tsx", ".jsx"].includes(ext)) {
123
+ // React props
124
+ const propsMatch = content.match(/(?:interface|type)\s+\w*Props\w*\s*(?:=\s*)?{([^}]*)}/);
125
+ if (propsMatch) {
126
+ const propLines = propsMatch[1].matchAll(/(\w+)\s*[?:]?\s*:/g);
127
+ for (const p of propLines)
128
+ props.push(p[1]);
129
+ if (propsMatch[1].includes("children"))
130
+ children = true;
131
+ }
132
+ // React hooks
133
+ const hookMatches = content.matchAll(/\buse(\w+)\s*\(/g);
134
+ for (const h of hookMatches) {
135
+ const hookName = `use${h[1]}`;
136
+ if (!hooks.includes(hookName))
137
+ hooks.push(hookName);
138
+ }
139
+ }
140
+ if (ext === ".vue") {
141
+ // Vue props
142
+ const vueProps = content.matchAll(/(\w+)\s*:\s*{\s*type:\s*(\w+)/g);
143
+ for (const p of vueProps)
144
+ props.push(p[1]);
145
+ }
146
+ components.push({
147
+ name,
148
+ file: f,
149
+ props: props.slice(0, 10),
150
+ children,
151
+ hooks: hooks.slice(0, 8),
152
+ stateManagement: [],
153
+ });
154
+ }
155
+ return components;
156
+ }
157
+ function extractStateStores(root) {
158
+ const stores = [];
159
+ // Zustand stores
160
+ const zustandFiles = glob.sync("**/*.{ts,tsx,js,jsx}", {
161
+ cwd: root,
162
+ ignore: ["node_modules/**", "dist/**"],
163
+ });
164
+ for (const f of zustandFiles) {
165
+ const content = tryRead(join(root, f));
166
+ if (!content)
167
+ continue;
168
+ if (content.includes("create(") && (content.includes("zustand") || content.includes("from 'zustand'"))) {
169
+ const nameMatch = content.match(/export\s+(?:const|let)\s+use(\w+)/);
170
+ if (nameMatch)
171
+ stores.push(`zustand:use${nameMatch[1]}`);
172
+ }
173
+ // Redux slices
174
+ if (content.includes("createSlice(")) {
175
+ const nameMatch = content.match(/name:\s*['"](\w+)['"]/);
176
+ if (nameMatch)
177
+ stores.push(`redux:${nameMatch[1]}`);
178
+ }
179
+ // React Context
180
+ if (content.includes("createContext(")) {
181
+ const nameMatch = content.match(/(?:export\s+)?const\s+(\w+Context)\s*=/);
182
+ if (nameMatch)
183
+ stores.push(`context:${nameMatch[1]}`);
184
+ }
185
+ }
186
+ return stores;
187
+ }
188
+ function findLayout(root, pageFile) {
189
+ let dir = dirname(join(root, pageFile));
190
+ while (dir.includes("app")) {
191
+ const layoutFile = glob.sync("layout.{tsx,jsx,ts,js}", { cwd: dir });
192
+ if (layoutFile.length > 0)
193
+ return join(dir, layoutFile[0]).replace(root + "/", "").replace(root + "\\", "");
194
+ dir = dirname(dir);
195
+ }
196
+ return null;
197
+ }
198
+ function tryRead(path) {
199
+ try {
200
+ return readFileSync(path, "utf-8");
201
+ }
202
+ catch {
203
+ return null;
204
+ }
205
+ }
206
+ /**
207
+ * Format frontend info for skeleton inclusion.
208
+ */
209
+ export function formatFrontend(info) {
210
+ const lines = [];
211
+ if (info.framework) {
212
+ let header = `Frontend: ${info.framework}`;
213
+ if (info.styling)
214
+ header += ` + ${info.styling}`;
215
+ if (info.uiLibrary)
216
+ header += ` + ${info.uiLibrary}`;
217
+ lines.push(header);
218
+ }
219
+ if (info.pages.length > 0) {
220
+ lines.push("Pages:");
221
+ for (const p of info.pages.slice(0, 20)) {
222
+ let line = ` ${p.path}`;
223
+ if (p.isProtected)
224
+ line += " (auth)";
225
+ lines.push(line);
226
+ }
227
+ if (info.pages.length > 20)
228
+ lines.push(` ... +${info.pages.length - 20} more`);
229
+ }
230
+ if (info.components.length > 0) {
231
+ lines.push(`Components: ${info.components.length} in total`);
232
+ const withProps = info.components.filter((c) => c.props.length > 0).slice(0, 10);
233
+ for (const c of withProps) {
234
+ lines.push(` <${c.name}> props: ${c.props.join(", ")}`);
235
+ }
236
+ }
237
+ if (info.stateStores.length > 0) {
238
+ lines.push(`State: ${info.stateStores.join(", ")}`);
239
+ }
240
+ if (lines.length === 0)
241
+ return "";
242
+ return lines.join("\n");
243
+ }
244
+ //# sourceMappingURL=frontend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontend.js","sourceRoot":"","sources":["../../src/extract/frontend.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export interface Gotcha {
2
+ file: string;
3
+ line: number;
4
+ category: GotchaCategory;
5
+ text: string;
6
+ }
7
+ export type GotchaCategory = "important_comment" | "guard_clause" | "state_transition" | "ordering_dep" | "side_effect" | "soft_delete" | "unique_constraint" | "cross_entity_read";
8
+ /**
9
+ * Extract gotchas from a source file.
10
+ * These are non-obvious constraints that cause bugs when AI misses them.
11
+ */
12
+ export declare function extractGotchas(filePath: string): Gotcha[];