popeye-cli 2.2.0 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (323) hide show
  1. package/dist/adapters/gemini.d.ts +14 -0
  2. package/dist/adapters/gemini.d.ts.map +1 -1
  3. package/dist/adapters/gemini.js +41 -6
  4. package/dist/adapters/gemini.js.map +1 -1
  5. package/dist/adapters/grok.d.ts +14 -0
  6. package/dist/adapters/grok.d.ts.map +1 -1
  7. package/dist/adapters/grok.js +42 -6
  8. package/dist/adapters/grok.js.map +1 -1
  9. package/dist/adapters/openai.d.ts +10 -0
  10. package/dist/adapters/openai.d.ts.map +1 -1
  11. package/dist/adapters/openai.js +44 -5
  12. package/dist/adapters/openai.js.map +1 -1
  13. package/dist/cli/commands/create.js +1 -1
  14. package/dist/cli/commands/create.js.map +1 -1
  15. package/dist/cli/interactive.d.ts.map +1 -1
  16. package/dist/cli/interactive.js +324 -20
  17. package/dist/cli/interactive.js.map +1 -1
  18. package/dist/generators/all.d.ts.map +1 -1
  19. package/dist/generators/all.js +3 -2
  20. package/dist/generators/all.js.map +1 -1
  21. package/dist/generators/doc-parser.d.ts +21 -6
  22. package/dist/generators/doc-parser.d.ts.map +1 -1
  23. package/dist/generators/doc-parser.js +55 -4
  24. package/dist/generators/doc-parser.js.map +1 -1
  25. package/dist/generators/templates/fullstack.js +1 -1
  26. package/dist/generators/templates/website-components.js +1 -1
  27. package/dist/generators/templates/website-components.js.map +1 -1
  28. package/dist/generators/templates/website-config.d.ts +4 -1
  29. package/dist/generators/templates/website-config.d.ts.map +1 -1
  30. package/dist/generators/templates/website-config.js +17 -11
  31. package/dist/generators/templates/website-config.js.map +1 -1
  32. package/dist/generators/templates/website-conversion.js +1 -1
  33. package/dist/generators/templates/website-conversion.js.map +1 -1
  34. package/dist/generators/templates/website-landing.js +1 -1
  35. package/dist/generators/templates/website-landing.js.map +1 -1
  36. package/dist/generators/templates/website-layout.d.ts +36 -4
  37. package/dist/generators/templates/website-layout.d.ts.map +1 -1
  38. package/dist/generators/templates/website-layout.js +466 -23
  39. package/dist/generators/templates/website-layout.js.map +1 -1
  40. package/dist/generators/templates/website-pricing.js +1 -1
  41. package/dist/generators/templates/website-pricing.js.map +1 -1
  42. package/dist/generators/templates/website-sections.js +1 -1
  43. package/dist/generators/templates/website-sections.js.map +1 -1
  44. package/dist/generators/templates/website-seo.d.ts.map +1 -1
  45. package/dist/generators/templates/website-seo.js +4 -1
  46. package/dist/generators/templates/website-seo.js.map +1 -1
  47. package/dist/generators/templates/website.d.ts +1 -1
  48. package/dist/generators/templates/website.d.ts.map +1 -1
  49. package/dist/generators/templates/website.js +1 -1
  50. package/dist/generators/templates/website.js.map +1 -1
  51. package/dist/generators/website-content-ai.d.ts +52 -0
  52. package/dist/generators/website-content-ai.d.ts.map +1 -0
  53. package/dist/generators/website-content-ai.js +141 -0
  54. package/dist/generators/website-content-ai.js.map +1 -0
  55. package/dist/generators/website-content-scanner.d.ts +1 -1
  56. package/dist/generators/website-content-scanner.d.ts.map +1 -1
  57. package/dist/generators/website-content-scanner.js +98 -1
  58. package/dist/generators/website-content-scanner.js.map +1 -1
  59. package/dist/generators/website-context.d.ts +34 -1
  60. package/dist/generators/website-context.d.ts.map +1 -1
  61. package/dist/generators/website-context.js +131 -9
  62. package/dist/generators/website-context.js.map +1 -1
  63. package/dist/generators/website-debug.d.ts +12 -0
  64. package/dist/generators/website-debug.d.ts.map +1 -1
  65. package/dist/generators/website-debug.js +16 -0
  66. package/dist/generators/website-debug.js.map +1 -1
  67. package/dist/generators/website.d.ts.map +1 -1
  68. package/dist/generators/website.js +26 -4
  69. package/dist/generators/website.js.map +1 -1
  70. package/dist/pipeline/auto-recovery.d.ts +56 -0
  71. package/dist/pipeline/auto-recovery.d.ts.map +1 -0
  72. package/dist/pipeline/auto-recovery.js +185 -0
  73. package/dist/pipeline/auto-recovery.js.map +1 -0
  74. package/dist/pipeline/change-request.d.ts +39 -0
  75. package/dist/pipeline/change-request.d.ts.map +1 -1
  76. package/dist/pipeline/change-request.js +40 -1
  77. package/dist/pipeline/change-request.js.map +1 -1
  78. package/dist/pipeline/check-runner.d.ts +30 -1
  79. package/dist/pipeline/check-runner.d.ts.map +1 -1
  80. package/dist/pipeline/check-runner.js +122 -1
  81. package/dist/pipeline/check-runner.js.map +1 -1
  82. package/dist/pipeline/command-resolver.d.ts.map +1 -1
  83. package/dist/pipeline/command-resolver.js +33 -2
  84. package/dist/pipeline/command-resolver.js.map +1 -1
  85. package/dist/pipeline/consensus/arbitrator-query.d.ts +22 -0
  86. package/dist/pipeline/consensus/arbitrator-query.d.ts.map +1 -0
  87. package/dist/pipeline/consensus/arbitrator-query.js +70 -0
  88. package/dist/pipeline/consensus/arbitrator-query.js.map +1 -0
  89. package/dist/pipeline/consensus/consensus-runner.d.ts +131 -7
  90. package/dist/pipeline/consensus/consensus-runner.d.ts.map +1 -1
  91. package/dist/pipeline/consensus/consensus-runner.js +809 -35
  92. package/dist/pipeline/consensus/consensus-runner.js.map +1 -1
  93. package/dist/pipeline/cr-lifecycle.d.ts +42 -0
  94. package/dist/pipeline/cr-lifecycle.d.ts.map +1 -0
  95. package/dist/pipeline/cr-lifecycle.js +89 -0
  96. package/dist/pipeline/cr-lifecycle.js.map +1 -0
  97. package/dist/pipeline/gate-engine.d.ts +1 -0
  98. package/dist/pipeline/gate-engine.d.ts.map +1 -1
  99. package/dist/pipeline/gate-engine.js +26 -7
  100. package/dist/pipeline/gate-engine.js.map +1 -1
  101. package/dist/pipeline/orchestrator.d.ts +1 -1
  102. package/dist/pipeline/orchestrator.d.ts.map +1 -1
  103. package/dist/pipeline/orchestrator.js +306 -16
  104. package/dist/pipeline/orchestrator.js.map +1 -1
  105. package/dist/pipeline/packets/consensus-packet-builder.d.ts +15 -4
  106. package/dist/pipeline/packets/consensus-packet-builder.d.ts.map +1 -1
  107. package/dist/pipeline/packets/consensus-packet-builder.js +29 -17
  108. package/dist/pipeline/packets/consensus-packet-builder.js.map +1 -1
  109. package/dist/pipeline/phases/architecture.d.ts.map +1 -1
  110. package/dist/pipeline/phases/architecture.js +5 -3
  111. package/dist/pipeline/phases/architecture.js.map +1 -1
  112. package/dist/pipeline/phases/audit.d.ts.map +1 -1
  113. package/dist/pipeline/phases/audit.js +5 -3
  114. package/dist/pipeline/phases/audit.js.map +1 -1
  115. package/dist/pipeline/phases/consensus-architecture.d.ts.map +1 -1
  116. package/dist/pipeline/phases/consensus-architecture.js +10 -1
  117. package/dist/pipeline/phases/consensus-architecture.js.map +1 -1
  118. package/dist/pipeline/phases/consensus-master-plan.d.ts.map +1 -1
  119. package/dist/pipeline/phases/consensus-master-plan.js +10 -3
  120. package/dist/pipeline/phases/consensus-master-plan.js.map +1 -1
  121. package/dist/pipeline/phases/consensus-role-plans.d.ts.map +1 -1
  122. package/dist/pipeline/phases/consensus-role-plans.js +10 -1
  123. package/dist/pipeline/phases/consensus-role-plans.js.map +1 -1
  124. package/dist/pipeline/phases/done.d.ts.map +1 -1
  125. package/dist/pipeline/phases/done.js +9 -4
  126. package/dist/pipeline/phases/done.js.map +1 -1
  127. package/dist/pipeline/phases/intake.d.ts.map +1 -1
  128. package/dist/pipeline/phases/intake.js +7 -3
  129. package/dist/pipeline/phases/intake.js.map +1 -1
  130. package/dist/pipeline/phases/phase-context.d.ts +2 -0
  131. package/dist/pipeline/phases/phase-context.d.ts.map +1 -1
  132. package/dist/pipeline/phases/phase-context.js +3 -1
  133. package/dist/pipeline/phases/phase-context.js.map +1 -1
  134. package/dist/pipeline/phases/production-gate.d.ts.map +1 -1
  135. package/dist/pipeline/phases/production-gate.js +28 -3
  136. package/dist/pipeline/phases/production-gate.js.map +1 -1
  137. package/dist/pipeline/phases/qa-validation.d.ts.map +1 -1
  138. package/dist/pipeline/phases/qa-validation.js +38 -5
  139. package/dist/pipeline/phases/qa-validation.js.map +1 -1
  140. package/dist/pipeline/phases/recovery-loop.d.ts +2 -0
  141. package/dist/pipeline/phases/recovery-loop.d.ts.map +1 -1
  142. package/dist/pipeline/phases/recovery-loop.js +200 -6
  143. package/dist/pipeline/phases/recovery-loop.js.map +1 -1
  144. package/dist/pipeline/phases/review.d.ts.map +1 -1
  145. package/dist/pipeline/phases/review.js +58 -28
  146. package/dist/pipeline/phases/review.js.map +1 -1
  147. package/dist/pipeline/phases/role-planning.d.ts.map +1 -1
  148. package/dist/pipeline/phases/role-planning.js +18 -2
  149. package/dist/pipeline/phases/role-planning.js.map +1 -1
  150. package/dist/pipeline/phases/stuck.d.ts.map +1 -1
  151. package/dist/pipeline/phases/stuck.js +10 -0
  152. package/dist/pipeline/phases/stuck.js.map +1 -1
  153. package/dist/pipeline/repo-snapshot.d.ts.map +1 -1
  154. package/dist/pipeline/repo-snapshot.js +3 -0
  155. package/dist/pipeline/repo-snapshot.js.map +1 -1
  156. package/dist/pipeline/role-execution-adapter.d.ts +2 -1
  157. package/dist/pipeline/role-execution-adapter.d.ts.map +1 -1
  158. package/dist/pipeline/role-execution-adapter.js +22 -7
  159. package/dist/pipeline/role-execution-adapter.js.map +1 -1
  160. package/dist/pipeline/skill-loader.d.ts +19 -0
  161. package/dist/pipeline/skill-loader.d.ts.map +1 -1
  162. package/dist/pipeline/skill-loader.js +22 -0
  163. package/dist/pipeline/skill-loader.js.map +1 -1
  164. package/dist/pipeline/skills/coverage-gate.d.ts +44 -0
  165. package/dist/pipeline/skills/coverage-gate.d.ts.map +1 -0
  166. package/dist/pipeline/skills/coverage-gate.js +143 -0
  167. package/dist/pipeline/skills/coverage-gate.js.map +1 -0
  168. package/dist/pipeline/skills/usage-registry.d.ts +48 -0
  169. package/dist/pipeline/skills/usage-registry.d.ts.map +1 -0
  170. package/dist/pipeline/skills/usage-registry.js +55 -0
  171. package/dist/pipeline/skills/usage-registry.js.map +1 -0
  172. package/dist/pipeline/strategy-context.d.ts +20 -0
  173. package/dist/pipeline/strategy-context.d.ts.map +1 -0
  174. package/dist/pipeline/strategy-context.js +55 -0
  175. package/dist/pipeline/strategy-context.js.map +1 -0
  176. package/dist/pipeline/type-defs/artifacts.d.ts +25 -5
  177. package/dist/pipeline/type-defs/artifacts.d.ts.map +1 -1
  178. package/dist/pipeline/type-defs/artifacts.js +4 -0
  179. package/dist/pipeline/type-defs/artifacts.js.map +1 -1
  180. package/dist/pipeline/type-defs/audit.d.ts +25 -13
  181. package/dist/pipeline/type-defs/audit.d.ts.map +1 -1
  182. package/dist/pipeline/type-defs/checks.d.ts +18 -8
  183. package/dist/pipeline/type-defs/checks.d.ts.map +1 -1
  184. package/dist/pipeline/type-defs/checks.js +4 -0
  185. package/dist/pipeline/type-defs/checks.js.map +1 -1
  186. package/dist/pipeline/type-defs/packets.d.ts +104 -18
  187. package/dist/pipeline/type-defs/packets.d.ts.map +1 -1
  188. package/dist/pipeline/type-defs/packets.js +17 -1
  189. package/dist/pipeline/type-defs/packets.js.map +1 -1
  190. package/dist/pipeline/type-defs/state.d.ts +160 -16
  191. package/dist/pipeline/type-defs/state.d.ts.map +1 -1
  192. package/dist/pipeline/type-defs/state.js +26 -1
  193. package/dist/pipeline/type-defs/state.js.map +1 -1
  194. package/dist/shared/text-utils.d.ts +23 -0
  195. package/dist/shared/text-utils.d.ts.map +1 -0
  196. package/dist/shared/text-utils.js +66 -0
  197. package/dist/shared/text-utils.js.map +1 -0
  198. package/dist/shared/website-strategy-format.d.ts +18 -0
  199. package/dist/shared/website-strategy-format.d.ts.map +1 -0
  200. package/dist/shared/website-strategy-format.js +47 -0
  201. package/dist/shared/website-strategy-format.js.map +1 -0
  202. package/dist/state/index.d.ts +2 -0
  203. package/dist/state/index.d.ts.map +1 -1
  204. package/dist/state/index.js +57 -8
  205. package/dist/state/index.js.map +1 -1
  206. package/dist/types/consensus.d.ts +1 -0
  207. package/dist/types/consensus.d.ts.map +1 -1
  208. package/dist/types/consensus.js.map +1 -1
  209. package/dist/types/website-strategy.d.ts +1 -1
  210. package/dist/types/workflow.d.ts +447 -0
  211. package/dist/types/workflow.d.ts.map +1 -1
  212. package/dist/types/workflow.js +3 -0
  213. package/dist/types/workflow.js.map +1 -1
  214. package/dist/upgrade/handlers.d.ts.map +1 -1
  215. package/dist/upgrade/handlers.js +6 -3
  216. package/dist/upgrade/handlers.js.map +1 -1
  217. package/dist/workflow/consensus.d.ts.map +1 -1
  218. package/dist/workflow/consensus.js +1 -0
  219. package/dist/workflow/consensus.js.map +1 -1
  220. package/dist/workflow/website-strategy.d.ts.map +1 -1
  221. package/dist/workflow/website-strategy.js +2 -29
  222. package/dist/workflow/website-strategy.js.map +1 -1
  223. package/dist/workflow/website-updater.d.ts.map +1 -1
  224. package/dist/workflow/website-updater.js +3 -2
  225. package/dist/workflow/website-updater.js.map +1 -1
  226. package/package.json +1 -1
  227. package/src/adapters/gemini.ts +51 -6
  228. package/src/adapters/grok.ts +51 -6
  229. package/src/adapters/openai.ts +53 -5
  230. package/src/cli/commands/create.ts +1 -1
  231. package/src/cli/interactive.ts +333 -19
  232. package/src/generators/all.ts +3 -2
  233. package/src/generators/doc-parser.ts +75 -15
  234. package/src/generators/templates/fullstack.ts +1 -1
  235. package/src/generators/templates/website-components.ts +1 -1
  236. package/src/generators/templates/website-config.ts +23 -11
  237. package/src/generators/templates/website-conversion.ts +1 -1
  238. package/src/generators/templates/website-landing.ts +1 -1
  239. package/src/generators/templates/website-layout.ts +491 -23
  240. package/src/generators/templates/website-pricing.ts +1 -1
  241. package/src/generators/templates/website-sections.ts +1 -1
  242. package/src/generators/templates/website-seo.ts +4 -1
  243. package/src/generators/templates/website.ts +3 -0
  244. package/src/generators/website-content-ai.ts +186 -0
  245. package/src/generators/website-content-scanner.ts +113 -1
  246. package/src/generators/website-context.ts +151 -12
  247. package/src/generators/website-debug.ts +26 -0
  248. package/src/generators/website.ts +28 -3
  249. package/src/pipeline/auto-recovery.ts +283 -0
  250. package/src/pipeline/change-request.ts +63 -1
  251. package/src/pipeline/check-runner.ts +141 -2
  252. package/src/pipeline/command-resolver.ts +34 -2
  253. package/src/pipeline/consensus/arbitrator-query.ts +101 -0
  254. package/src/pipeline/consensus/consensus-runner.ts +1099 -42
  255. package/src/pipeline/cr-lifecycle.ts +103 -0
  256. package/src/pipeline/gate-engine.ts +35 -7
  257. package/src/pipeline/orchestrator.ts +361 -16
  258. package/src/pipeline/packets/consensus-packet-builder.ts +44 -18
  259. package/src/pipeline/phases/architecture.ts +6 -3
  260. package/src/pipeline/phases/audit.ts +6 -3
  261. package/src/pipeline/phases/consensus-architecture.ts +10 -1
  262. package/src/pipeline/phases/consensus-master-plan.ts +10 -3
  263. package/src/pipeline/phases/consensus-role-plans.ts +10 -1
  264. package/src/pipeline/phases/done.ts +15 -4
  265. package/src/pipeline/phases/intake.ts +7 -3
  266. package/src/pipeline/phases/phase-context.ts +6 -1
  267. package/src/pipeline/phases/production-gate.ts +41 -3
  268. package/src/pipeline/phases/qa-validation.ts +51 -5
  269. package/src/pipeline/phases/recovery-loop.ts +229 -7
  270. package/src/pipeline/phases/review.ts +73 -30
  271. package/src/pipeline/phases/role-planning.ts +21 -2
  272. package/src/pipeline/phases/stuck.ts +10 -0
  273. package/src/pipeline/repo-snapshot.ts +3 -0
  274. package/src/pipeline/role-execution-adapter.ts +30 -4
  275. package/src/pipeline/skill-loader.ts +33 -0
  276. package/src/pipeline/skills/coverage-gate.ts +199 -0
  277. package/src/pipeline/skills/usage-registry.ts +87 -0
  278. package/src/pipeline/strategy-context.ts +60 -0
  279. package/src/pipeline/type-defs/artifacts.ts +4 -0
  280. package/src/pipeline/type-defs/checks.ts +4 -0
  281. package/src/pipeline/type-defs/packets.ts +18 -1
  282. package/src/pipeline/type-defs/state.ts +26 -1
  283. package/src/shared/text-utils.ts +70 -0
  284. package/src/shared/website-strategy-format.ts +56 -0
  285. package/src/state/index.ts +60 -8
  286. package/src/types/consensus.ts +1 -0
  287. package/src/types/workflow.ts +6 -0
  288. package/src/upgrade/handlers.ts +9 -3
  289. package/src/workflow/consensus.ts +1 -0
  290. package/src/workflow/website-strategy.ts +2 -36
  291. package/src/workflow/website-updater.ts +4 -2
  292. package/tests/adapters/gemini.test.ts +165 -0
  293. package/tests/adapters/grok.test.ts +137 -0
  294. package/tests/adapters/openai.test.ts +128 -0
  295. package/tests/generators/doc-parser.test.ts +88 -9
  296. package/tests/generators/quality-gate.test.ts +19 -3
  297. package/tests/generators/website-components.test.ts +34 -0
  298. package/tests/generators/website-content-ai.test.ts +308 -0
  299. package/tests/generators/website-content-scanner.test.ts +86 -0
  300. package/tests/generators/website-context.test.ts +3 -2
  301. package/tests/integration/smokestack-scaffold.test.ts +385 -0
  302. package/tests/pipeline/auto-recovery.test.ts +337 -0
  303. package/tests/pipeline/change-request.test.ts +70 -0
  304. package/tests/pipeline/command-resolver.test.ts +42 -0
  305. package/tests/pipeline/consensus/arbitrator-query.test.ts +107 -0
  306. package/tests/pipeline/consensus-runner.test.ts +1333 -10
  307. package/tests/pipeline/consensus-scoring.test.ts +602 -18
  308. package/tests/pipeline/gate-engine.test.ts +34 -0
  309. package/tests/pipeline/install-check.test.ts +261 -0
  310. package/tests/pipeline/orchestrator.test.ts +1506 -15
  311. package/tests/pipeline/packets/builders.test.ts +29 -6
  312. package/tests/pipeline/phases/role-planning.strategy.test.ts +204 -0
  313. package/tests/pipeline/pipeline-persistence.test.ts +230 -0
  314. package/tests/pipeline/recovery-loop-guidance.test.ts +280 -0
  315. package/tests/pipeline/role-execution-adapter.test.ts +88 -0
  316. package/tests/pipeline/skills/coverage-gate.test.ts +370 -0
  317. package/tests/pipeline/skills/usage-registry.test.ts +114 -0
  318. package/tests/pipeline/strategy-context.test.ts +148 -0
  319. package/tests/shared/text-utils.test.ts +155 -0
  320. package/tests/state/progress-analysis.test.ts +375 -0
  321. package/tests/upgrade/handlers.test.ts +33 -2
  322. package/tests/workflow/consensus.test.ts +6 -0
  323. package/tsconfig.json +1 -1
@@ -10,7 +10,7 @@ import type { GenerationResult } from './python.js';
10
10
  import { generateFullstackProject } from './fullstack.js';
11
11
  import { generateWebsiteProject } from './website.js';
12
12
  import type { WebsiteContentContext } from './website-context.js';
13
- import { buildWebsiteContext, validateWebsiteContext, resolveBrandAssets } from './website-context.js';
13
+ import { buildWebsiteContext, validateWebsiteContext, resolveBrandAssets, extractDocPathsFromText } from './website-context.js';
14
14
  import { loadWebsiteStrategy } from '../workflow/website-strategy.js';
15
15
  import {
16
16
  generateDesignTokensPackage as generateDesignTokensPackageImpl,
@@ -393,7 +393,8 @@ export async function generateAllProject(
393
393
  let contextWarning: string | undefined;
394
394
  if (!contentContext) {
395
395
  try {
396
- contentContext = await buildWebsiteContext(projectDir, projectName);
396
+ const extraDocPaths = spec.idea ? extractDocPathsFromText(spec.idea) : [];
397
+ contentContext = await buildWebsiteContext(projectDir, projectName, spec.idea, extraDocPaths);
397
398
  } catch (e) {
398
399
  contextWarning = e instanceof Error ? e.message : 'Unknown error building website context';
399
400
  // Proceed with defaults, but warning is logged below
@@ -281,22 +281,33 @@ function extractFeaturesFromSource(
281
281
  return features;
282
282
  }
283
283
 
284
- /**
285
- * Extract pricing tiers from docs
286
- * Parses markdown tables and "Plan Positioning" sections
287
- */
288
- export function extractPricing(
289
- docs: string
290
- ): Array<{
284
+ /** Pricing tier as extracted from docs */
285
+ export interface PricingTier {
291
286
  name: string; price: string; period?: string;
292
287
  description: string; features: string[];
293
288
  cta: string; featured?: boolean;
294
- }> | undefined {
295
- const tiers: Array<{
296
- name: string; price: string; period?: string;
297
- description: string; features: string[];
298
- cta: string; featured?: boolean;
299
- }> = [];
289
+ }
290
+
291
+ /** Result of pricing extraction with provenance tracking */
292
+ export interface PricingExtractionResult {
293
+ tiers: PricingTier[];
294
+ source: 'docs' | 'none';
295
+ evidence?: {
296
+ matchedSection?: string;
297
+ matchedRows: number;
298
+ extractionMethod: 'known_plan_names' | 'table_fallback';
299
+ };
300
+ }
301
+
302
+ /**
303
+ * Extract pricing tiers from docs with provenance tracking
304
+ * Parses markdown tables and "Plan Positioning" sections
305
+ *
306
+ * @param docs - Combined documentation text
307
+ * @returns Extraction result with tiers, source provenance, and evidence
308
+ */
309
+ export function extractPricing(docs: string): PricingExtractionResult {
310
+ const tiers: PricingTier[] = [];
300
311
 
301
312
  // Find the pricing section to avoid matching design token tables
302
313
  // Reason: "Plan-Based Color Usage" matches "Plans?" - require "Pricing" keyword
@@ -307,8 +318,11 @@ export function extractPricing(
307
318
 
308
319
  // Look for pricing overview table rows with plan names and actual prices
309
320
  const priceMap = new Map<string, string>();
321
+ let extractionMethod: 'known_plan_names' | 'table_fallback' | undefined;
322
+
310
323
  const tableRows = searchArea.match(/^\|[^|]*(?:Free|Pro|Enterprise|Starter|Growth|Team|Business)[^|]*\|.+\|$/gm);
311
324
  if (tableRows) {
325
+ extractionMethod = 'known_plan_names';
312
326
  for (const row of tableRows) {
313
327
  const cells = row.split('|').map((c) => c.trim()).filter(Boolean);
314
328
  if (cells.length >= 2) {
@@ -325,7 +339,41 @@ export function extractPricing(
325
339
  }
326
340
  }
327
341
 
328
- if (priceMap.size === 0) return undefined;
342
+ // Fallback: if no known plan names found, scan pricing section for any row with price-like cell
343
+ if (priceMap.size === 0 && pricingSection) {
344
+ const allRows = pricingSection[0].match(/^\|.+\|$/gm);
345
+ if (allRows && allRows.length >= 3) {
346
+ // Detect which column is the price column from the header row
347
+ const headerCells = allRows[0].split('|').map((c) => c.trim()).filter(Boolean);
348
+ let priceColIndex = headerCells.findIndex((h) => /price|cost|monthly|\$/i.test(h));
349
+ if (priceColIndex < 0) priceColIndex = 1; // default: 2nd column
350
+
351
+ for (const row of allRows.slice(2)) {
352
+ const cells = row.split('|').map((c) => c.trim()).filter(Boolean);
353
+ if (cells.length < 2) continue;
354
+ const planName = cells[0].replace(/[🟢🔵🟣⚪🟡🟠🔴]\s*/g, '').replace(/\*\*/g, '').trim();
355
+ // Skip separator rows and header-like rows
356
+ if (/^[-=\s]+$/.test(planName) || /^(Plan|Tier|Name|Feature)/i.test(planName)) continue;
357
+
358
+ // Check price column and adjacent column for price-like content
359
+ for (const idx of [priceColIndex, priceColIndex === 1 ? 2 : 1]) {
360
+ if (idx >= cells.length) continue;
361
+ const price = cells[idx].replace(/<br>/g, ' / ').replace(/\*\*/g, '').trim();
362
+ const looksLikePrice = /^free$/i.test(price) || /^\$/.test(price)
363
+ || /^custom/i.test(price) || /^contact/i.test(price);
364
+ if (looksLikePrice && !priceMap.has(planName)) {
365
+ priceMap.set(planName, price);
366
+ break;
367
+ }
368
+ }
369
+ }
370
+ if (priceMap.size > 0) extractionMethod = 'table_fallback';
371
+ }
372
+ }
373
+
374
+ if (priceMap.size === 0) {
375
+ return { tiers: [], source: 'none' };
376
+ }
329
377
 
330
378
  // Look for plan descriptions
331
379
  const descMap = new Map<string, string>();
@@ -410,7 +458,19 @@ export function extractPricing(
410
458
  tier.features = tier.features.slice(0, 6);
411
459
  }
412
460
 
413
- return tiers.length > 0 ? tiers : undefined;
461
+ if (tiers.length === 0) {
462
+ return { tiers: [], source: 'none' };
463
+ }
464
+
465
+ return {
466
+ tiers,
467
+ source: 'docs',
468
+ evidence: {
469
+ matchedSection: pricingSection ? pricingSection[0].split('\n')[0] : undefined,
470
+ matchedRows: priceMap.size,
471
+ extractionMethod: extractionMethod!,
472
+ },
473
+ };
414
474
  }
415
475
 
416
476
  /**
@@ -765,7 +765,7 @@ export function generateFrontendPackageJson(projectName: string): string {
765
765
  '@vitest/coverage-v8': '^2.0.0',
766
766
  autoprefixer: '^10.4.0',
767
767
  eslint: '^9.0.0',
768
- 'eslint-plugin-react-hooks': '^4.6.0',
768
+ 'eslint-plugin-react-hooks': '^5.0.0',
769
769
  'eslint-plugin-react-refresh': '^0.4.0',
770
770
  postcss: '^8.4.0',
771
771
  tailwindcss: '^3.4.0',
@@ -15,7 +15,7 @@ function escapeJsx(str: string): string {
15
15
  .replace(/\\/g, '\\\\')
16
16
  .replace(/'/g, "\\'")
17
17
  .replace(/`/g, '\\`')
18
- .replace(/\$/g, '\\$');
18
+ .replace(/\$(?=\{)/g, '\\$');
19
19
  }
20
20
 
21
21
  /**
@@ -93,7 +93,24 @@ module.exports = nextConfig;
93
93
  /**
94
94
  * Generate website tsconfig.json
95
95
  */
96
- export function generateWebsiteTsconfig(): string {
96
+ export function generateWebsiteTsconfig(options?: {
97
+ workspaceMode?: boolean;
98
+ projectName?: string;
99
+ }): string {
100
+ const paths: Record<string, string[]> = {
101
+ '@/*': ['./src/*'],
102
+ };
103
+
104
+ // Add workspace package path aliases so tsc can resolve imports
105
+ if (options?.workspaceMode && options?.projectName) {
106
+ paths[`@${options.projectName}/design-tokens/*`] = ['../../packages/design-tokens/src/*'];
107
+ paths[`@${options.projectName}/design-tokens`] = ['../../packages/design-tokens/src/index.ts'];
108
+ paths[`@${options.projectName}/ui/*`] = ['../../packages/ui/src/*'];
109
+ paths[`@${options.projectName}/ui`] = ['../../packages/ui/src/index.ts'];
110
+ }
111
+
112
+ const pathsJson = JSON.stringify(paths, null, 6).replace(/\n/g, '\n ');
113
+
97
114
  return `{
98
115
  "compilerOptions": {
99
116
  "target": "ES2017",
@@ -114,12 +131,10 @@ export function generateWebsiteTsconfig(): string {
114
131
  "name": "next"
115
132
  }
116
133
  ],
117
- "paths": {
118
- "@/*": ["./src/*"]
119
- }
134
+ "paths": ${pathsJson}
120
135
  },
121
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
122
- "exclude": ["node_modules"]
136
+ "include": ["next-env.d.ts", "src/**/*.ts", "src/**/*.tsx", ".next/types/**/*.ts"],
137
+ "exclude": ["node_modules", "tests"]
123
138
  }
124
139
  `;
125
140
  }
@@ -421,12 +436,9 @@ vi.mock('next/navigation', () => ({
421
436
  usePathname: () => '/',
422
437
  }));
423
438
 
424
- // Mock next/image
439
+ // Mock next/image (plain object mock, no JSX in .ts files)
425
440
  vi.mock('next/image', () => ({
426
- default: (props: Record<string, unknown>) => {
427
- // eslint-disable-next-line @next/next/no-img-element, jsx-a11y/alt-text
428
- return <img {...props} />;
429
- },
441
+ default: (props: Record<string, unknown>) => props,
430
442
  }));
431
443
  `;
432
444
  }
@@ -13,7 +13,7 @@ function escapeJsx(str: string): string {
13
13
  .replace(/\\/g, '\\\\')
14
14
  .replace(/'/g, "\\'")
15
15
  .replace(/`/g, '\\`')
16
- .replace(/\$/g, '\\$');
16
+ .replace(/\$(?=\{)/g, '\\$');
17
17
  }
18
18
 
19
19
  /**
@@ -26,7 +26,7 @@ function escapeJsx(str: string): string {
26
26
  .replace(/\\/g, '\\\\')
27
27
  .replace(/'/g, "\\'")
28
28
  .replace(/`/g, '\\`')
29
- .replace(/\$/g, '\\$');
29
+ .replace(/\$(?=\{)/g, '\\$');
30
30
  }
31
31
 
32
32
  /**