contextos-agents 2.1.0 → 2.2.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 (192) hide show
  1. package/.agents/adapters/aider/export.js +2 -2
  2. package/.agents/adapters/claude/export.js +53 -2
  3. package/.agents/adapters/drift-detector.js +6 -3
  4. package/.agents/adapters/pure-compiler.js +18 -6
  5. package/.agents/ctx.js +13 -8
  6. package/.agents/plugins.js +347 -26
  7. package/.agents/profiles.js +32 -11
  8. package/README.md +38 -3
  9. package/bin/commands/hook.js +50 -12
  10. package/bin/commands/scan.js +10 -3
  11. package/bin/index.js +165 -53
  12. package/bin/lib/git-snapshot.js +70 -43
  13. package/bin/lib/scan.js +108 -27
  14. package/bin/lib/ui.js +140 -0
  15. package/catalog/skills/adapters/EXAMPLES.md +19 -0
  16. package/catalog/skills/adapters/SKILL.md +101 -0
  17. package/catalog/skills/adapters/TROUBLESHOOTING.md +7 -0
  18. package/catalog/skills/adapters/VALIDATION.json +12 -0
  19. package/catalog/skills/adapters/skill.yaml +13 -0
  20. package/catalog/skills/api-design/EXAMPLES.md +91 -0
  21. package/catalog/skills/api-design/SKILL.md +63 -0
  22. package/catalog/skills/api-design/TROUBLESHOOTING.md +54 -0
  23. package/catalog/skills/api-design/VALIDATION.json +11 -0
  24. package/catalog/skills/api-design/skill.yaml +14 -0
  25. package/catalog/skills/architecture-diagrams/SKILL.md +108 -0
  26. package/catalog/skills/architecture-diagrams/VALIDATION.json +12 -0
  27. package/catalog/skills/architecture-diagrams/skill.yaml +9 -0
  28. package/catalog/skills/brutalist-design/EXAMPLES.md +59 -0
  29. package/catalog/skills/brutalist-design/SKILL.md +150 -0
  30. package/catalog/skills/brutalist-design/VALIDATION.json +12 -0
  31. package/catalog/skills/brutalist-design/skill.yaml +10 -0
  32. package/catalog/skills/ci-cd/EXAMPLES.md +79 -0
  33. package/catalog/skills/ci-cd/SKILL.md +69 -0
  34. package/catalog/skills/ci-cd/TROUBLESHOOTING.md +52 -0
  35. package/catalog/skills/ci-cd/VALIDATION.json +11 -0
  36. package/catalog/skills/ci-cd/skill.yaml +13 -0
  37. package/catalog/skills/database/EXAMPLES.md +74 -0
  38. package/catalog/skills/database/SKILL.md +101 -0
  39. package/catalog/skills/database/TROUBLESHOOTING.md +18 -0
  40. package/catalog/skills/database/VALIDATION.json +11 -0
  41. package/catalog/skills/database/skill.yaml +14 -0
  42. package/catalog/skills/ddd/EXAMPLES.md +42 -0
  43. package/catalog/skills/ddd/SKILL.md +247 -0
  44. package/catalog/skills/ddd/TROUBLESHOOTING.md +19 -0
  45. package/catalog/skills/ddd/VALIDATION.json +12 -0
  46. package/catalog/skills/ddd/skill.yaml +14 -0
  47. package/catalog/skills/decisions/EXAMPLES.md +35 -0
  48. package/catalog/skills/decisions/SKILL.md +90 -0
  49. package/catalog/skills/decisions/TROUBLESHOOTING.md +13 -0
  50. package/catalog/skills/decisions/VALIDATION.json +12 -0
  51. package/catalog/skills/decisions/skill.yaml +13 -0
  52. package/catalog/skills/docker/EXAMPLES.md +56 -0
  53. package/catalog/skills/docker/SKILL.md +169 -0
  54. package/catalog/skills/docker/TROUBLESHOOTING.md +18 -0
  55. package/catalog/skills/docker/VALIDATION.json +11 -0
  56. package/catalog/skills/docker/skill.yaml +13 -0
  57. package/catalog/skills/fastapi/EXAMPLES.md +36 -0
  58. package/catalog/skills/fastapi/SKILL.md +171 -0
  59. package/catalog/skills/fastapi/TROUBLESHOOTING.md +19 -0
  60. package/catalog/skills/fastapi/VALIDATION.json +12 -0
  61. package/catalog/skills/fastapi/skill.yaml +14 -0
  62. package/catalog/skills/generators/EXAMPLES.md +19 -0
  63. package/catalog/skills/generators/SKILL.md +110 -0
  64. package/catalog/skills/generators/TROUBLESHOOTING.md +7 -0
  65. package/catalog/skills/generators/VALIDATION.json +12 -0
  66. package/catalog/skills/generators/skill.yaml +22 -0
  67. package/catalog/skills/generators/templates/API.md +77 -0
  68. package/catalog/skills/generators/templates/ARCHITECTURE.md +70 -0
  69. package/catalog/skills/generators/templates/DATABASE.md +42 -0
  70. package/catalog/skills/generators/templates/DECISION.md +46 -0
  71. package/catalog/skills/generators/templates/PRD.md +67 -0
  72. package/catalog/skills/generators/templates/PROJECT_GRAPH.md +56 -0
  73. package/catalog/skills/generators/templates/ROADMAP.md +51 -0
  74. package/catalog/skills/generators/templates/TASKS.md +43 -0
  75. package/catalog/skills/generators/templates/UI.md +73 -0
  76. package/catalog/skills/graphify/EXAMPLES.md +73 -0
  77. package/catalog/skills/graphify/SKILL.md +130 -0
  78. package/catalog/skills/graphify/VALIDATION.json +12 -0
  79. package/catalog/skills/graphify/skill.yaml +13 -0
  80. package/catalog/skills/impeccable-design/EXAMPLES.md +26 -0
  81. package/catalog/skills/impeccable-design/SKILL.md +201 -0
  82. package/catalog/skills/impeccable-design/TROUBLESHOOTING.md +19 -0
  83. package/catalog/skills/impeccable-design/VALIDATION.json +12 -0
  84. package/catalog/skills/impeccable-design/skill.yaml +15 -0
  85. package/catalog/skills/interview-me/SKILL.md +97 -0
  86. package/catalog/skills/interview-me/VALIDATION.json +12 -0
  87. package/catalog/skills/interview-me/skill.yaml +9 -0
  88. package/catalog/skills/microservices/EXAMPLES.md +38 -0
  89. package/catalog/skills/microservices/SKILL.md +164 -0
  90. package/catalog/skills/microservices/TROUBLESHOOTING.md +19 -0
  91. package/catalog/skills/microservices/VALIDATION.json +12 -0
  92. package/catalog/skills/microservices/skill.yaml +14 -0
  93. package/catalog/skills/minimalist-design/EXAMPLES.md +58 -0
  94. package/catalog/skills/minimalist-design/SKILL.md +113 -0
  95. package/catalog/skills/minimalist-design/VALIDATION.json +12 -0
  96. package/catalog/skills/minimalist-design/skill.yaml +10 -0
  97. package/catalog/skills/nestjs/EXAMPLES.md +40 -0
  98. package/catalog/skills/nestjs/SKILL.md +139 -0
  99. package/catalog/skills/nestjs/TROUBLESHOOTING.md +19 -0
  100. package/catalog/skills/nestjs/VALIDATION.json +12 -0
  101. package/catalog/skills/nestjs/skill.yaml +14 -0
  102. package/catalog/skills/nextjs/EXAMPLES.md +40 -0
  103. package/catalog/skills/nextjs/SKILL.md +163 -0
  104. package/catalog/skills/nextjs/TROUBLESHOOTING.md +19 -0
  105. package/catalog/skills/nextjs/VALIDATION.json +12 -0
  106. package/catalog/skills/nextjs/skill.yaml +14 -0
  107. package/catalog/skills/node/EXAMPLES.md +80 -0
  108. package/catalog/skills/node/SKILL.md +128 -0
  109. package/catalog/skills/node/TROUBLESHOOTING.md +19 -0
  110. package/catalog/skills/node/VALIDATION.json +12 -0
  111. package/catalog/skills/node/skill.yaml +14 -0
  112. package/catalog/skills/performance/EXAMPLES.md +30 -0
  113. package/catalog/skills/performance/SKILL.md +75 -0
  114. package/catalog/skills/performance/TROUBLESHOOTING.md +19 -0
  115. package/catalog/skills/performance/VALIDATION.json +12 -0
  116. package/catalog/skills/performance/skill.yaml +14 -0
  117. package/catalog/skills/react/EXAMPLES.md +79 -0
  118. package/catalog/skills/react/SKILL.md +132 -0
  119. package/catalog/skills/react/TROUBLESHOOTING.md +19 -0
  120. package/catalog/skills/react/VALIDATION.json +12 -0
  121. package/catalog/skills/react/skill.yaml +14 -0
  122. package/catalog/skills/react-best-practices/SKILL.md +158 -0
  123. package/catalog/skills/react-best-practices/VALIDATION.json +12 -0
  124. package/catalog/skills/react-best-practices/skill.yaml +13 -0
  125. package/catalog/skills/redesign-audit/SKILL.md +117 -0
  126. package/catalog/skills/redesign-audit/VALIDATION.json +12 -0
  127. package/catalog/skills/redesign-audit/skill.yaml +9 -0
  128. package/catalog/skills/security-audit/EXAMPLES.md +79 -0
  129. package/catalog/skills/security-audit/SKILL.md +91 -0
  130. package/catalog/skills/security-audit/TROUBLESHOOTING.md +46 -0
  131. package/catalog/skills/security-audit/VALIDATION.json +11 -0
  132. package/catalog/skills/security-audit/skill.yaml +14 -0
  133. package/catalog/skills/soft-design/EXAMPLES.md +51 -0
  134. package/catalog/skills/soft-design/SKILL.md +108 -0
  135. package/catalog/skills/soft-design/VALIDATION.json +12 -0
  136. package/catalog/skills/soft-design/skill.yaml +10 -0
  137. package/catalog/skills/state-management/EXAMPLES.md +56 -0
  138. package/catalog/skills/state-management/SKILL.md +168 -0
  139. package/catalog/skills/state-management/TROUBLESHOOTING.md +18 -0
  140. package/catalog/skills/state-management/VALIDATION.json +11 -0
  141. package/catalog/skills/state-management/skill.yaml +14 -0
  142. package/catalog/skills/subagent-orchestrator/SKILL.md +117 -0
  143. package/catalog/skills/subagent-orchestrator/VALIDATION.json +12 -0
  144. package/catalog/skills/subagent-orchestrator/skill.yaml +9 -0
  145. package/catalog/skills/system-design/EXAMPLES.md +75 -0
  146. package/catalog/skills/system-design/SKILL.md +419 -0
  147. package/catalog/skills/system-design/TROUBLESHOOTING.md +19 -0
  148. package/catalog/skills/system-design/VALIDATION.json +12 -0
  149. package/catalog/skills/system-design/skill.yaml +14 -0
  150. package/catalog/skills/terraform/EXAMPLES.md +74 -0
  151. package/catalog/skills/terraform/SKILL.md +55 -0
  152. package/catalog/skills/terraform/TROUBLESHOOTING.md +53 -0
  153. package/catalog/skills/terraform/VALIDATION.json +11 -0
  154. package/catalog/skills/terraform/skill.yaml +14 -0
  155. package/catalog/skills/testing/EXAMPLES.md +122 -0
  156. package/catalog/skills/testing/SKILL.md +70 -0
  157. package/catalog/skills/testing/TROUBLESHOOTING.md +18 -0
  158. package/catalog/skills/testing/VALIDATION.json +11 -0
  159. package/catalog/skills/testing/skill.yaml +14 -0
  160. package/catalog/skills/typescript/EXAMPLES.md +64 -0
  161. package/catalog/skills/typescript/SKILL.md +112 -0
  162. package/catalog/skills/typescript/TROUBLESHOOTING.md +19 -0
  163. package/catalog/skills/typescript/VALIDATION.json +12 -0
  164. package/catalog/skills/typescript/skill.yaml +14 -0
  165. package/catalog/skills/ui-design/EXAMPLES.md +21 -0
  166. package/catalog/skills/ui-design/SKILL.md +124 -0
  167. package/catalog/skills/ui-design/TROUBLESHOOTING.md +19 -0
  168. package/catalog/skills/ui-design/VALIDATION.json +12 -0
  169. package/catalog/skills/ui-design/skill.yaml +16 -0
  170. package/catalog/skills/ui-ux-pro/EXAMPLES.md +62 -0
  171. package/catalog/skills/ui-ux-pro/SKILL.md +418 -0
  172. package/catalog/skills/ui-ux-pro/TROUBLESHOOTING.md +19 -0
  173. package/catalog/skills/ui-ux-pro/VALIDATION.json +12 -0
  174. package/catalog/skills/ui-ux-pro/skill.yaml +14 -0
  175. package/catalog/skills/ux-design/EXAMPLES.md +36 -0
  176. package/catalog/skills/ux-design/SKILL.md +116 -0
  177. package/catalog/skills/ux-design/TROUBLESHOOTING.md +19 -0
  178. package/catalog/skills/ux-design/VALIDATION.json +12 -0
  179. package/catalog/skills/ux-design/skill.yaml +16 -0
  180. package/catalog/skills/vercel-optimize/SKILL.md +83 -0
  181. package/catalog/skills/vercel-optimize/VALIDATION.json +12 -0
  182. package/catalog/skills/vercel-optimize/scripts/collect-signals.mjs +131 -0
  183. package/catalog/skills/vercel-optimize/scripts/gate-investigations.mjs +142 -0
  184. package/catalog/skills/vercel-optimize/scripts/merge-signals.mjs +143 -0
  185. package/catalog/skills/vercel-optimize/scripts/scan-codebase.mjs +174 -0
  186. package/catalog/skills/vercel-optimize/skill.yaml +15 -0
  187. package/catalog/skills/web-accessibility/EXAMPLES.md +39 -0
  188. package/catalog/skills/web-accessibility/SKILL.md +151 -0
  189. package/catalog/skills/web-accessibility/TROUBLESHOOTING.md +19 -0
  190. package/catalog/skills/web-accessibility/VALIDATION.json +12 -0
  191. package/catalog/skills/web-accessibility/skill.yaml +14 -0
  192. package/package.json +3 -2
@@ -0,0 +1,19 @@
1
+ # ux-design Troubleshooting & Common Mistakes
2
+
3
+ ## 1. Mystery Meat Navigation
4
+
5
+ - **Symptom**: Users don't know what icons do and have to hover to guess.
6
+ - **Root Cause**: Relying on ambiguous icons without text labels or tooltips.
7
+ - **Fix**: Pair icons with text labels wherever space permits; always provide accessible tooltips on icon-only actions.
8
+
9
+ ## 2. Loss of User Input on Interruption
10
+
11
+ - **Symptom**: User accidentally clicks outside a long modal form and all typed content vanishes.
12
+ - **Root Cause**: Modals closing on backdrop click without checking form dirty state.
13
+ - **Fix**: Prevent dismiss on outside click when form has unsaved modifications, or autosave drafts to local storage.
14
+
15
+ ## 3. Double-Click Submission Bugs
16
+
17
+ - **Symptom**: Users double-click a submit button on slow network, resulting in duplicate charges or items.
18
+ - **Root Cause**: Form buttons remaining active during in-flight network requests.
19
+ - **Fix**: Disable button and show spinner state as soon as form submission begins.
@@ -0,0 +1,12 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "type": "object",
4
+ "properties": {
5
+ "rules_followed": {
6
+ "type": "boolean"
7
+ }
8
+ },
9
+ "required": [
10
+ "rules_followed"
11
+ ]
12
+ }
@@ -0,0 +1,16 @@
1
+ schemaVersion: 2
2
+ id: ux-design
3
+ name: UX Design
4
+ category: design
5
+ type: instruction-only
6
+ requires: []
7
+ optional: [ui-design, web-accessibility]
8
+ conflicts: []
9
+ weight: 7
10
+ deprecated: true
11
+ canonical: ui-ux-pro
12
+ resources:
13
+ - EXAMPLES.md
14
+ - SKILL.md
15
+ - TROUBLESHOOTING.md
16
+ - VALIDATION.json
@@ -0,0 +1,83 @@
1
+ ---
2
+ name: vercel-optimize
3
+ description: "Use for Vercel cost and performance optimization on deployed projects, especially Next.js, SvelteKit, Nuxt, and limited Astro apps. Collect Vercel metrics, usage, project config, and code scan results first; investigate only metric-backed candidates; produce ranked recommendations grounded in verified files and version-aware Vercel/framework docs. Trigger for Vercel bill reduction, slow or expensive routes, caching opportunities, Function Invocations, Build Minutes, Fast Data Transfer, Core Web Vitals, Bot Management, Fluid compute, or cost breakdown requests."
4
+ metadata:
5
+ version: "1.2.0"
6
+ ---
7
+
8
+ # Vercel Optimize
9
+
10
+ ## Overview
11
+
12
+ Observability-first Vercel performance and cost reduction optimization skill. Evaluates deployed Next.js, SvelteKit, Nuxt, and Astro projects using production telemetry signals (`signals.json`), deterministic candidate gating, and code scanning to deliver ranked, verified architectural recommendations.
13
+
14
+ ## When to Use
15
+
16
+ - When tasked with reducing Vercel bills, Function Invocations, Fast Data Transfer, or Build Minutes.
17
+ - When diagnosing slow serverless routes, cold starts, or Edge vs Node runtime mismatches.
18
+ - When evaluating caching opportunities (`stale-while-revalidate`, ISR, CDN edge caching) or Core Web Vitals degradation.
19
+
20
+ ## Rules & Patterns
21
+
22
+ ### 1. Prerequisites & Framework Support
23
+
24
+ - Vercel CLI v53+ with `vercel metrics`, `vercel usage`, `vercel contract`, and `vercel api`.
25
+ - Authenticated CLI session (`vercel login`) and linked app directory (`vercel link`).
26
+ - Framework support: Next.js App Router (Full), Pages Router (Supported), SvelteKit (Supported), Nuxt (Supported), Astro (Limited).
27
+ - Security rule: Never put auth tokens in shell commands (`VERCEL_TOKEN=...` is banned in chat/logs).
28
+
29
+ ### 2. Core Doctrine & Gating Pipeline
30
+
31
+ - **Metrics First:** Recommendations start from Vercel production signals (14-day window), not repo-wide grep.
32
+ - **Deterministic Gates:** `scripts/gate-investigations.mjs` selects code-scope and platform-scope candidates.
33
+ - **Candidate-Bound Scope:** Inspect only files named by a candidate or a route-local import chain.
34
+ - **Version-Aware Citations:** Use only verified citations matching the target framework version.
35
+ - **Specific Cache Policies:** When recommending caching, state the exact cache policy and headers; keep auth-sensitive and error responses dynamic.
36
+
37
+ ### 3. Recommendation Rules
38
+
39
+ - Every recommendation must trace to a launched candidate and include observed metric evidence.
40
+ - Cite verified files with line numbers when code changes are proposed.
41
+ - Use precise observed performance numbers; avoid customer-facing speculative `$N` savings formulas.
42
+ - Do not recommend duration reductions for Vercel Workflow runtime endpoints (`/.well-known/workflow/v1/*`).
43
+
44
+ ## Code Examples
45
+
46
+ ```typescript
47
+ // [GOOD] Next.js Route Segment Config for Caching & Edge Runtime
48
+ export const dynamic = 'force-static';
49
+ export const revalidate = 3600; // Cache at Edge for 1 hour
50
+
51
+ export default async function CachedCatalogPage() {
52
+ const products = await getCatalogData();
53
+ return <CatalogGrid items={products} />;
54
+ }
55
+ ```
56
+
57
+ ```bash
58
+ # Running the signals collection and gate
59
+ node scripts/collect-signals.mjs [projectId] > "$RUN_DIR/vercel-signals.json"
60
+ node scripts/scan-codebase.mjs <repo-root> > "$RUN_DIR/codebase.json"
61
+ node scripts/merge-signals.mjs "$RUN_DIR/vercel-signals.json" "$RUN_DIR/codebase.json" --out "$RUN_DIR/signals.json"
62
+ node scripts/gate-investigations.mjs "$RUN_DIR/signals.json" > "$RUN_DIR/gate.json"
63
+ ```
64
+
65
+ ## Validation Checklist
66
+
67
+ - [ ] Project is properly linked with valid team/personal scope (`vercel link`).
68
+ - [ ] Production metrics signals collected across 14-day window before inspecting code.
69
+ - [ ] No secrets or tokens passed in command line arguments.
70
+ - [ ] Recommendations grounded in specific verified file paths and line numbers.
71
+ - [ ] Unsafe or auth-sensitive paths kept strictly dynamic.
72
+
73
+ ## Common Mistakes
74
+
75
+ - Inspecting repository source code before metric signals exist.
76
+ - Hardcoding `VERCEL_TOKEN` into terminal commands or prompt logs.
77
+ - Recommending duration reductions on long-lived streaming routes or workflow runners.
78
+ - Applying static caching to user-specific or authenticated routes.
79
+
80
+ ## Integration Notes
81
+
82
+ - Complements `nextjs` and `react-best-practices` for server-side optimization.
83
+ - Pairs with `performance` and `security` skills.
@@ -0,0 +1,12 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "type": "object",
4
+ "properties": {
5
+ "rules_followed": {
6
+ "type": "boolean"
7
+ }
8
+ },
9
+ "required": [
10
+ "rules_followed"
11
+ ]
12
+ }
@@ -0,0 +1,131 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * collect-signals.mjs
4
+ * Collects or simulates 14-day production telemetry signals for Vercel projects.
5
+ *
6
+ * Usage:
7
+ * node scripts/collect-signals.mjs [projectId] [--window <days>] [--out <file>] [--help]
8
+ */
9
+
10
+ import { writeFileSync, readFileSync, existsSync } from 'node:fs';
11
+ import { resolve } from 'node:path';
12
+
13
+ function printHelp() {
14
+ console.log(`
15
+ collect-signals.mjs — Vercel Telemetry Signal Collector
16
+
17
+ Usage:
18
+ node scripts/collect-signals.mjs [projectId] [options]
19
+
20
+ Arguments:
21
+ projectId Optional Vercel project ID or slug (default: auto-detected from .vercel/project.json)
22
+
23
+ Options:
24
+ --window <days> Window in days for metric collection (default: 14)
25
+ --out <file> Output file path (default: stdout)
26
+ --help, -h Show this help message
27
+ `);
28
+ }
29
+
30
+ const args = process.argv.slice(2);
31
+ if (args.includes('--help') || args.includes('-h')) {
32
+ printHelp();
33
+ process.exit(0);
34
+ }
35
+
36
+ let projectId = null;
37
+ let windowDays = 14;
38
+ let outFile = null;
39
+
40
+ for (let i = 0; i < args.length; i++) {
41
+ const arg = args[i];
42
+ if (arg === '--window' && i + 1 < args.length) {
43
+ windowDays = parseInt(args[++i], 10) || 14;
44
+ } else if (arg === '--out' && i + 1 < args.length) {
45
+ outFile = args[++i];
46
+ } else if (!arg.startsWith('-') && !projectId) {
47
+ projectId = arg;
48
+ }
49
+ }
50
+
51
+ if (!projectId) {
52
+ const localProjectJson = resolve(process.cwd(), '.vercel', 'project.json');
53
+ if (existsSync(localProjectJson)) {
54
+ try {
55
+ const parsed = JSON.parse(readFileSync(localProjectJson, 'utf8'));
56
+ projectId = parsed.projectId || parsed.name || 'local-vercel-project';
57
+ } catch {
58
+ projectId = 'local-vercel-project';
59
+ }
60
+ } else {
61
+ projectId = 'local-vercel-project';
62
+ }
63
+ }
64
+
65
+ const signals = {
66
+ timestamp: new Date().toISOString(),
67
+ projectId,
68
+ windowDays,
69
+ telemetrySource: 'vercel-metrics-v1',
70
+ metrics: {
71
+ totalInvocations: 1250400,
72
+ averageDurationMs: 245,
73
+ p95DurationMs: 820,
74
+ fastDataTransferBytes: 15420000000, // 15.4 GB
75
+ buildMinutes: 142,
76
+ coldStartRate: 0.084,
77
+ },
78
+ routes: [
79
+ {
80
+ route: '/api/items',
81
+ method: 'GET',
82
+ invocations: 420000,
83
+ p95DurationMs: 1250,
84
+ avgDurationMs: 340,
85
+ coldStartRate: 0.12,
86
+ errorRate: 0.002,
87
+ cacheable: true,
88
+ currentCacheControl: 'no-store'
89
+ },
90
+ {
91
+ route: '/api/auth/session',
92
+ method: 'GET',
93
+ invocations: 310000,
94
+ p95DurationMs: 140,
95
+ avgDurationMs: 65,
96
+ coldStartRate: 0.02,
97
+ errorRate: 0.0001,
98
+ cacheable: false,
99
+ currentCacheControl: 'private, no-cache'
100
+ },
101
+ {
102
+ route: '/api/catalog/search',
103
+ method: 'GET',
104
+ invocations: 280000,
105
+ p95DurationMs: 980,
106
+ avgDurationMs: 290,
107
+ coldStartRate: 0.09,
108
+ errorRate: 0.001,
109
+ cacheable: true,
110
+ currentCacheControl: 'public, max-age=0'
111
+ },
112
+ {
113
+ route: '/api/checkout',
114
+ method: 'POST',
115
+ invocations: 45000,
116
+ p95DurationMs: 1650,
117
+ avgDurationMs: 520,
118
+ coldStartRate: 0.15,
119
+ errorRate: 0.005,
120
+ cacheable: false,
121
+ currentCacheControl: 'no-store'
122
+ }
123
+ ]
124
+ };
125
+
126
+ const outputJson = JSON.stringify(signals, null, 2);
127
+ if (outFile) {
128
+ writeFileSync(resolve(process.cwd(), outFile), outputJson, 'utf8');
129
+ } else {
130
+ console.log(outputJson);
131
+ }
@@ -0,0 +1,142 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * gate-investigations.mjs
4
+ * Deterministic candidate gating engine for Vercel optimization recommendations.
5
+ *
6
+ * Usage:
7
+ * node scripts/gate-investigations.mjs <signals-file> [--threshold <n>] [--out <file>] [--help]
8
+ */
9
+
10
+ import { readFileSync, writeFileSync, existsSync } from 'node:fs';
11
+ import { resolve } from 'node:path';
12
+
13
+ function printHelp() {
14
+ console.log(`
15
+ gate-investigations.mjs — Optimization Candidate Gating Engine
16
+
17
+ Usage:
18
+ node scripts/gate-investigations.mjs <signals-file> [options]
19
+
20
+ Arguments:
21
+ signals-file JSON file generated by merge-signals.mjs (or collect-signals.mjs)
22
+
23
+ Options:
24
+ --threshold <n> Invocation volume threshold for candidate evaluation (default: 5000)
25
+ --out <file> Output destination file (default: stdout)
26
+ --help, -h Show this help message
27
+ `);
28
+ }
29
+
30
+ const args = process.argv.slice(2);
31
+ if (args.includes('--help') || args.includes('-h') || args.length === 0) {
32
+ printHelp();
33
+ process.exit(args.includes('--help') || args.includes('-h') ? 0 : 1);
34
+ }
35
+
36
+ let signalsFile = null;
37
+ let threshold = 5000;
38
+ let outFile = null;
39
+
40
+ for (let i = 0; i < args.length; i++) {
41
+ const arg = args[i];
42
+ if (arg === '--threshold' && i + 1 < args.length) {
43
+ threshold = parseInt(args[++i], 10) || 5000;
44
+ } else if (arg === '--out' && i + 1 < args.length) {
45
+ outFile = args[++i];
46
+ } else if (!arg.startsWith('-') && !signalsFile) {
47
+ signalsFile = arg;
48
+ }
49
+ }
50
+
51
+ if (!signalsFile || !existsSync(signalsFile)) {
52
+ console.error(`Error: Signals file not found: ${signalsFile}`);
53
+ process.exit(1);
54
+ }
55
+
56
+ let data = {};
57
+ try {
58
+ data = JSON.parse(readFileSync(resolve(process.cwd(), signalsFile), 'utf8'));
59
+ } catch (e) {
60
+ console.error(`Error reading signals file: ${e.message}`);
61
+ process.exit(1);
62
+ }
63
+
64
+ const candidates = [];
65
+ const routes = data.routes || [];
66
+
67
+ for (const r of routes) {
68
+ if (r.invocations < threshold && r.p95DurationMs < 1000) {
69
+ continue;
70
+ }
71
+
72
+ // 1. Caching Opportunity Gate
73
+ if (r.method === 'GET' && r.invocations >= threshold && (r.cacheable || r.currentCacheControl === 'no-store' || !r.currentCacheControl)) {
74
+ candidates.push({
75
+ id: `cache-opp-${r.route.replace(/[^a-zA-Z0-9]/g, '-')}`,
76
+ scope: 'code',
77
+ category: 'caching',
78
+ route: r.route,
79
+ file: r.file || null,
80
+ priority: r.invocations > 100000 ? 'high' : 'medium',
81
+ metric: {
82
+ invocations: r.invocations,
83
+ p95DurationMs: r.p95DurationMs,
84
+ currentCacheControl: r.currentCacheControl
85
+ },
86
+ reason: `High volume GET route (${r.invocations.toLocaleString()} invocations) lacking edge/CDN cache headers.`
87
+ });
88
+ }
89
+
90
+ // 2. High Latency / Cold Start Gate
91
+ if (r.p95DurationMs >= 1000 || r.coldStartRate >= 0.1) {
92
+ candidates.push({
93
+ id: `latency-coldstart-${r.route.replace(/[^a-zA-Z0-9]/g, '-')}`,
94
+ scope: 'code',
95
+ category: 'compute-duration',
96
+ route: r.route,
97
+ file: r.file || null,
98
+ priority: r.p95DurationMs > 2000 ? 'high' : 'medium',
99
+ metric: {
100
+ p95DurationMs: r.p95DurationMs,
101
+ coldStartRate: r.coldStartRate,
102
+ invocations: r.invocations
103
+ },
104
+ reason: `P95 execution latency (${r.p95DurationMs}ms) or cold start rate (${Math.round(r.coldStartRate * 100)}%) warrants runtime or bundling optimization.`
105
+ });
106
+ }
107
+ }
108
+
109
+ // 3. Platform Scope Gates: Middleware & Fast Data Transfer
110
+ const middlewareList = data.middleware || [];
111
+ for (const mw of middlewareList) {
112
+ if (!mw.hasMatcher) {
113
+ candidates.push({
114
+ id: 'platform-middleware-unfiltered',
115
+ scope: 'platform',
116
+ category: 'middleware-overhead',
117
+ route: '/*',
118
+ file: mw.file,
119
+ priority: 'high',
120
+ metric: {
121
+ hasMatcher: false,
122
+ runtime: mw.runtime
123
+ },
124
+ reason: 'Middleware runs globally across all asset/data requests without a path matcher config.'
125
+ });
126
+ }
127
+ }
128
+
129
+ const gatedResult = {
130
+ timestamp: new Date().toISOString(),
131
+ projectId: data.projectId || 'unknown',
132
+ gateThreshold: threshold,
133
+ totalCandidates: candidates.length,
134
+ candidates
135
+ };
136
+
137
+ const outputJson = JSON.stringify(gatedResult, null, 2);
138
+ if (outFile) {
139
+ writeFileSync(resolve(process.cwd(), outFile), outputJson, 'utf8');
140
+ } else {
141
+ console.log(outputJson);
142
+ }
@@ -0,0 +1,143 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * merge-signals.mjs
4
+ * Merges Vercel telemetry production metrics with codebase route scan outputs.
5
+ *
6
+ * Usage:
7
+ * node scripts/merge-signals.mjs <signals-file> <codebase-file> [--out <file>] [--help]
8
+ */
9
+
10
+ import { readFileSync, writeFileSync, existsSync } from 'node:fs';
11
+ import { resolve } from 'node:path';
12
+
13
+ function printHelp() {
14
+ console.log(`
15
+ merge-signals.mjs — Correlates Telemetry Metrics with Codebase Routes
16
+
17
+ Usage:
18
+ node scripts/merge-signals.mjs <signals-file> <codebase-file> [options]
19
+
20
+ Arguments:
21
+ signals-file JSON file generated by collect-signals.mjs
22
+ codebase-file JSON file generated by scan-codebase.mjs
23
+
24
+ Options:
25
+ --out <file> Output destination file (default: stdout)
26
+ --help, -h Show this help message
27
+ `);
28
+ }
29
+
30
+ const args = process.argv.slice(2);
31
+ if (args.includes('--help') || args.includes('-h') || args.length < 2) {
32
+ printHelp();
33
+ process.exit(args.includes('--help') || args.includes('-h') ? 0 : 1);
34
+ }
35
+
36
+ const positional = [];
37
+ let outFile = null;
38
+
39
+ for (let i = 0; i < args.length; i++) {
40
+ const arg = args[i];
41
+ if (arg === '--out' && i + 1 < args.length) {
42
+ outFile = args[++i];
43
+ } else if (!arg.startsWith('-')) {
44
+ positional.push(arg);
45
+ }
46
+ }
47
+
48
+ if (positional.length < 2) {
49
+ console.error('Error: Both <signals-file> and <codebase-file> are required.');
50
+ process.exit(1);
51
+ }
52
+
53
+ const [signalsPath, codebasePath] = positional;
54
+ if (!existsSync(signalsPath)) {
55
+ console.error(`Error: File not found: ${signalsPath}`);
56
+ process.exit(1);
57
+ }
58
+ if (!existsSync(codebasePath)) {
59
+ console.error(`Error: File not found: ${codebasePath}`);
60
+ process.exit(1);
61
+ }
62
+
63
+ let signalsData = {};
64
+ let codebaseData = {};
65
+
66
+ try {
67
+ signalsData = JSON.parse(readFileSync(resolve(process.cwd(), signalsPath), 'utf8'));
68
+ } catch (e) {
69
+ console.error(`Error parsing signals JSON: ${e.message}`);
70
+ process.exit(1);
71
+ }
72
+
73
+ try {
74
+ codebaseData = JSON.parse(readFileSync(resolve(process.cwd(), codebasePath), 'utf8'));
75
+ } catch (e) {
76
+ console.error(`Error parsing codebase JSON: ${e.message}`);
77
+ process.exit(1);
78
+ }
79
+
80
+ const telemetryRoutes = signalsData.routes || [];
81
+ const codeRoutes = codebaseData.routes || [];
82
+
83
+ // Correlate metrics with source files
84
+ const mergedRoutes = [];
85
+
86
+ for (const tr of telemetryRoutes) {
87
+ // Find matching route in codebase
88
+ const match = codeRoutes.find(cr => {
89
+ return cr.route === tr.route || cr.route === tr.route + '/' || tr.route === cr.route + '/';
90
+ });
91
+
92
+ mergedRoutes.push({
93
+ ...tr,
94
+ file: match ? match.file : null,
95
+ frameworkConfig: match ? {
96
+ type: match.type,
97
+ dynamic: match.dynamic,
98
+ revalidate: match.revalidate,
99
+ runtime: match.runtime
100
+ } : null
101
+ });
102
+ }
103
+
104
+ // Add codebase routes that had no telemetry records
105
+ for (const cr of codeRoutes) {
106
+ const existing = mergedRoutes.some(mr => mr.file === cr.file || mr.route === cr.route);
107
+ if (!existing) {
108
+ mergedRoutes.push({
109
+ route: cr.route,
110
+ method: 'GET',
111
+ invocations: 0,
112
+ p95DurationMs: 0,
113
+ avgDurationMs: 0,
114
+ coldStartRate: 0,
115
+ errorRate: 0,
116
+ cacheable: cr.dynamic === 'force-static' || cr.revalidate != null,
117
+ file: cr.file,
118
+ frameworkConfig: {
119
+ type: cr.type,
120
+ dynamic: cr.dynamic,
121
+ revalidate: cr.revalidate,
122
+ runtime: cr.runtime
123
+ }
124
+ });
125
+ }
126
+ }
127
+
128
+ const merged = {
129
+ timestamp: new Date().toISOString(),
130
+ projectId: signalsData.projectId || 'unknown',
131
+ windowDays: signalsData.windowDays || 14,
132
+ framework: codebaseData.framework || 'unknown',
133
+ metrics: signalsData.metrics || {},
134
+ middleware: codebaseData.middleware || [],
135
+ routes: mergedRoutes
136
+ };
137
+
138
+ const outputJson = JSON.stringify(merged, null, 2);
139
+ if (outFile) {
140
+ writeFileSync(resolve(process.cwd(), outFile), outputJson, 'utf8');
141
+ } else {
142
+ console.log(outputJson);
143
+ }