uilint-core 0.2.142 → 0.2.144
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-C7PUSJTD.js → chunk-J4LUG7RV.js} +106 -2
- package/dist/chunk-J4LUG7RV.js.map +1 -0
- package/dist/{index-DK-WAzmL.d.ts → index-rJqAK3nT.d.ts} +180 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +9 -1
- package/dist/node.d.ts +2 -2
- package/dist/node.js +9 -1
- package/dist/node.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-C7PUSJTD.js.map +0 -1
|
@@ -1427,4 +1427,183 @@ declare class PluginRegistry {
|
|
|
1427
1427
|
*/
|
|
1428
1428
|
declare const pluginRegistry: PluginRegistry;
|
|
1429
1429
|
|
|
1430
|
-
|
|
1430
|
+
/**
|
|
1431
|
+
* Operation Lifecycle Framework
|
|
1432
|
+
*
|
|
1433
|
+
* Shared types and factory functions for plugins that perform long-running
|
|
1434
|
+
* server-mediated operations (indexing, analysis, etc.).
|
|
1435
|
+
*
|
|
1436
|
+
* Plugins compose these into their own state/actions/messages rather than
|
|
1437
|
+
* inheriting from a base class.
|
|
1438
|
+
*
|
|
1439
|
+
* NO REACT CODE - Pure TypeScript.
|
|
1440
|
+
*/
|
|
1441
|
+
|
|
1442
|
+
/**
|
|
1443
|
+
* Status lifecycle for a long-running plugin operation.
|
|
1444
|
+
*
|
|
1445
|
+
* - "idle" -- nothing has run yet (initial state)
|
|
1446
|
+
* - "active" -- operation is in progress
|
|
1447
|
+
* - "complete" -- finished successfully
|
|
1448
|
+
* - "error" -- finished with an error
|
|
1449
|
+
*/
|
|
1450
|
+
type OperationStatus = "idle" | "active" | "complete" | "error";
|
|
1451
|
+
/**
|
|
1452
|
+
* Progress tracking for a long-running operation.
|
|
1453
|
+
*/
|
|
1454
|
+
interface OperationProgress {
|
|
1455
|
+
current: number;
|
|
1456
|
+
total: number;
|
|
1457
|
+
/** Optional human-readable context (e.g., file path, phase name) */
|
|
1458
|
+
message?: string;
|
|
1459
|
+
}
|
|
1460
|
+
/**
|
|
1461
|
+
* State shape for a long-running operation.
|
|
1462
|
+
*
|
|
1463
|
+
* Plugins embed this inside their own state interface:
|
|
1464
|
+
* ```typescript
|
|
1465
|
+
* interface MyPluginState {
|
|
1466
|
+
* indexing: OperationState<IndexStats>;
|
|
1467
|
+
* // ...other plugin-specific fields
|
|
1468
|
+
* }
|
|
1469
|
+
* ```
|
|
1470
|
+
*
|
|
1471
|
+
* @template TStats Type of the completion payload (e.g., IndexStats)
|
|
1472
|
+
*/
|
|
1473
|
+
interface OperationState<TStats = unknown> {
|
|
1474
|
+
/** Current operation status */
|
|
1475
|
+
status: OperationStatus;
|
|
1476
|
+
/** Progress info (null when idle or complete) */
|
|
1477
|
+
progress: OperationProgress | null;
|
|
1478
|
+
/** Completion stats from the last successful run */
|
|
1479
|
+
stats: TStats | null;
|
|
1480
|
+
/** Error message from the last failed run */
|
|
1481
|
+
lastError: string | null;
|
|
1482
|
+
}
|
|
1483
|
+
/**
|
|
1484
|
+
* Creates default initial state for an operation.
|
|
1485
|
+
*
|
|
1486
|
+
* @example
|
|
1487
|
+
* ```typescript
|
|
1488
|
+
* const initialState: MyState = {
|
|
1489
|
+
* indexing: createOperationInitialState<IndexStats>(),
|
|
1490
|
+
* };
|
|
1491
|
+
* ```
|
|
1492
|
+
*/
|
|
1493
|
+
declare function createOperationInitialState<TStats = unknown>(): OperationState<TStats>;
|
|
1494
|
+
/**
|
|
1495
|
+
* Creates standard computed values for an operation.
|
|
1496
|
+
*
|
|
1497
|
+
* Returns four computed selectors that can be spread (and optionally renamed)
|
|
1498
|
+
* into a plugin's `StateDefinition.computed`:
|
|
1499
|
+
*
|
|
1500
|
+
* - `isReady` -- status is "complete"
|
|
1501
|
+
* - `isActive` -- status is "active"
|
|
1502
|
+
* - `hasError` -- status is "error" or lastError is non-null
|
|
1503
|
+
* - `progressPercent` -- 0-100 number derived from progress
|
|
1504
|
+
*
|
|
1505
|
+
* @param getOp Extracts the OperationState from the full plugin state
|
|
1506
|
+
*
|
|
1507
|
+
* @example
|
|
1508
|
+
* ```typescript
|
|
1509
|
+
* const opComputed = createOperationComputed<MyState>((s) => s.indexing);
|
|
1510
|
+
* const stateDefinition = {
|
|
1511
|
+
* computed: {
|
|
1512
|
+
* isIndexReady: opComputed.isReady,
|
|
1513
|
+
* isIndexing: opComputed.isActive,
|
|
1514
|
+
* hasError: opComputed.hasError,
|
|
1515
|
+
* progressPercent: opComputed.progressPercent,
|
|
1516
|
+
* },
|
|
1517
|
+
* };
|
|
1518
|
+
* ```
|
|
1519
|
+
*/
|
|
1520
|
+
declare function createOperationComputed<TState>(getOp: (state: TState) => OperationState): {
|
|
1521
|
+
isReady: (state: TState) => boolean;
|
|
1522
|
+
isActive: (state: TState) => boolean;
|
|
1523
|
+
hasError: (state: TState) => boolean;
|
|
1524
|
+
progressPercent: (state: TState) => number;
|
|
1525
|
+
};
|
|
1526
|
+
/**
|
|
1527
|
+
* Configuration for creating operation action handlers.
|
|
1528
|
+
*/
|
|
1529
|
+
interface OperationActionConfig<TState, TStats> {
|
|
1530
|
+
/** Extract the OperationState from the full plugin state */
|
|
1531
|
+
getOp: (state: TState) => OperationState<TStats>;
|
|
1532
|
+
/** Produce a partial state update that sets the operation state */
|
|
1533
|
+
setOp: (op: OperationState<TStats>) => Partial<TState>;
|
|
1534
|
+
}
|
|
1535
|
+
/**
|
|
1536
|
+
* Creates the four standard lifecycle action handlers for an operation.
|
|
1537
|
+
*
|
|
1538
|
+
* Returns handlers keyed as:
|
|
1539
|
+
* - `"handle-{prefix}-start"`
|
|
1540
|
+
* - `"handle-{prefix}-progress"`
|
|
1541
|
+
* - `"handle-{prefix}-complete"`
|
|
1542
|
+
* - `"handle-{prefix}-error"`
|
|
1543
|
+
*
|
|
1544
|
+
* These can be spread into a plugin's `ActionHandlers` alongside
|
|
1545
|
+
* any plugin-specific actions.
|
|
1546
|
+
*
|
|
1547
|
+
* @param prefix Action name prefix (e.g., "indexing", "analysis")
|
|
1548
|
+
* @param config How to read/write the operation state from plugin state
|
|
1549
|
+
*
|
|
1550
|
+
* @example
|
|
1551
|
+
* ```typescript
|
|
1552
|
+
* export const myActions: ActionHandlers<MyState> = {
|
|
1553
|
+
* ...createOperationActions<MyState, IndexStats>("indexing", {
|
|
1554
|
+
* getOp: (s) => s.indexing,
|
|
1555
|
+
* setOp: (op) => ({ indexing: op }),
|
|
1556
|
+
* }),
|
|
1557
|
+
* // plugin-specific actions
|
|
1558
|
+
* "start-indexing": (ctx) => { ... },
|
|
1559
|
+
* };
|
|
1560
|
+
* ```
|
|
1561
|
+
*/
|
|
1562
|
+
declare function createOperationActions<TState, TStats>(prefix: string, config: OperationActionConfig<TState, TStats>): ActionHandlers<TState>;
|
|
1563
|
+
/**
|
|
1564
|
+
* Configuration for mapping WebSocket messages to operation actions.
|
|
1565
|
+
*/
|
|
1566
|
+
interface OperationMessageConfig {
|
|
1567
|
+
/** Prefix for action dispatch (e.g., "indexing", "analysis") */
|
|
1568
|
+
actionPrefix: string;
|
|
1569
|
+
/** WS message type for start (optional -- some operations don't have one) */
|
|
1570
|
+
startMessage?: string;
|
|
1571
|
+
/** WS message type for progress */
|
|
1572
|
+
progressMessage: string;
|
|
1573
|
+
/** WS message type for completion */
|
|
1574
|
+
completeMessage: string;
|
|
1575
|
+
/** WS message type for error */
|
|
1576
|
+
errorMessage: string;
|
|
1577
|
+
/** Extract progress payload from the raw WS message */
|
|
1578
|
+
extractProgress?: (message: unknown) => OperationProgress;
|
|
1579
|
+
/** Extract completion stats from the raw WS message */
|
|
1580
|
+
extractStats?: (message: unknown) => unknown;
|
|
1581
|
+
/** Extract error string from the raw WS message */
|
|
1582
|
+
extractError?: (message: unknown) => string;
|
|
1583
|
+
}
|
|
1584
|
+
/**
|
|
1585
|
+
* Creates WebSocket message handlers for a standard operation lifecycle.
|
|
1586
|
+
*
|
|
1587
|
+
* Each handler dispatches to the corresponding `handle-{prefix}-*` action.
|
|
1588
|
+
*
|
|
1589
|
+
* @example
|
|
1590
|
+
* ```typescript
|
|
1591
|
+
* export const myMessages: MessageHandlers<MyState> = {
|
|
1592
|
+
* ...createOperationMessageHandlers<MyState>({
|
|
1593
|
+
* actionPrefix: "indexing",
|
|
1594
|
+
* startMessage: "duplicates:indexing:start",
|
|
1595
|
+
* progressMessage: "duplicates:indexing:progress",
|
|
1596
|
+
* completeMessage: "duplicates:indexing:complete",
|
|
1597
|
+
* errorMessage: "duplicates:indexing:error",
|
|
1598
|
+
* extractProgress: (msg) => ({
|
|
1599
|
+
* current: (msg as any).current ?? 0,
|
|
1600
|
+
* total: (msg as any).total ?? 0,
|
|
1601
|
+
* message: (msg as any).message,
|
|
1602
|
+
* }),
|
|
1603
|
+
* }),
|
|
1604
|
+
* };
|
|
1605
|
+
* ```
|
|
1606
|
+
*/
|
|
1607
|
+
declare function createOperationMessageHandlers<TState>(config: OperationMessageConfig): MessageHandlers<TState>;
|
|
1608
|
+
|
|
1609
|
+
export { type ElementRole as $, type AnalysisResult as A, deserializeStyles as B, type ColorRule as C, type DOMSnapshot as D, type ExtractedStyles as E, createStyleSummary as F, truncateHTML as G, parseStyleGuide as H, type InstrumentationSpan as I, parseStyleGuideSections as J, extractStyleValues as K, type LLMInstrumentationCallbacks as L, extractTailwindAllowlist as M, generateStyleGuideFromStyles as N, type OllamaClientOptions as O, styleGuideToMarkdown as P, createEmptyStyleGuide as Q, validateStyleGuide as R, type StyleGuide as S, type TailwindThemeTokens as T, type UILintIssue as U, mergeStyleGuides as V, createColorRule as W, createTypographyRule as X, createSpacingRule as Y, createComponentRule as Z, type StyleSnapshot as _, logSuccess as a, type RuleOptionSchema as a$, type ElementSnapshot as a0, type GroupedSnapshot as a1, type ViolationCategory as a2, type ViolationSeverity as a3, type Violation as a4, type ConsistencyResult as a5, type AnalyzeConsistencyOptions as a6, buildConsistencyPrompt as a7, countElements as a8, hasAnalyzableGroups as a9, type DynamicValue as aA, type ConditionalValue as aB, type IconName as aC, type ActionReference as aD, type FetchConfig as aE, type HeaderSection as aF, type CodeViewerSection as aG, type CodePanelConfig as aH, type CodeComparisonSection as aI, type BadgeSection as aJ, type TextSection as aK, type ActionButton as aL, type ActionsSection as aM, type DividerSection as aN, type ConditionalSection as aO, type ListSection as aP, type ImageSection as aQ, type CardSection as aR, type ProgressSection as aS, type PanelSection as aT, type LoadingConfig as aU, type EmptyConfig as aV, type PanelDefinition as aW, type CommandDefinition as aX, type ToolbarActionDefinition as aY, type ToolbarGroupDefinition as aZ, type RuleOptionField as a_, parseGroupedSnapshot as aa, parseViolationsResponse as ab, validateViolations as ac, analyzeConsistency as ad, formatConsistencyViolations as ae, devLog as af, devWarn as ag, devError as ah, PluginRegistry as ai, PluginRegistrationError as aj, pluginRegistry as ak, type PluginRegistryEvent as al, type PluginRegistryListener as am, type PluginContext as an, type WebSocketService as ao, type BrowserActionResult as ap, type ActionHandler as aq, type ActionHandlers as ar, type MessageHandler as as, type MessageHandlers as at, type IssueAggregator as au, type InitializeHook as av, type DisposeHook as aw, type PluginWithHandlers as ax, type DataBinding as ay, type ExpressionBinding as az, logWarning as b, type RuleRequirement as b0, type RuleDefinition as b1, type PluginIssue as b2, type IssueContribution as b3, type ComputedValue as b4, type PersistConfig as b5, type StateDefinition as b6, type PluginDefinition as b7, isDataBinding as b8, isExpressionBinding as b9, isConditionalValue as ba, createOperationInitialState as bb, createOperationComputed as bc, createOperationActions as bd, createOperationMessageHandlers as be, type OperationStatus as bf, type OperationProgress as bg, type OperationState as bh, type OperationActionConfig as bi, type OperationMessageConfig as bj, logError as c, logDebug as d, createProgress as e, type UILintScanIssue as f, type UILintSourceScanResult as g, type TypographyRule as h, type SpacingRule as i, type ComponentRule as j, type SerializedStyles as k, logInfo as l, type ExtractedStyleValues as m, type StreamProgressCallback as n, OllamaClient as o, getOllamaClient as p, UILINT_DEFAULT_OLLAMA_MODEL as q, buildAnalysisPrompt as r, buildSourceAnalysisPrompt as s, buildSourceScanPrompt as t, buildStyleGuidePrompt as u, formatViolationsText as v, sanitizeIssues as w, extractStyles as x, extractStylesFromDOM as y, serializeStyles as z };
|
package/dist/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { aL as ActionButton, aq as ActionHandler, ar as ActionHandlers, aD as ActionReference, aM as ActionsSection, A as AnalysisResult, a6 as AnalyzeConsistencyOptions, aJ as BadgeSection, ap as BrowserActionResult, aR as CardSection, aI as CodeComparisonSection, aH as CodePanelConfig, aG as CodeViewerSection, C as ColorRule, aX as CommandDefinition, j as ComponentRule, b4 as ComputedValue, aO as ConditionalSection, aB as ConditionalValue, a5 as ConsistencyResult, D as DOMSnapshot, ay as DataBinding, aw as DisposeHook, aN as DividerSection, aA as DynamicValue, $ as ElementRole, a0 as ElementSnapshot, aV as EmptyConfig, az as ExpressionBinding, m as ExtractedStyleValues, E as ExtractedStyles, aE as FetchConfig, a1 as GroupedSnapshot, aF as HeaderSection, aC as IconName, aQ as ImageSection, av as InitializeHook, I as InstrumentationSpan, au as IssueAggregator, b3 as IssueContribution, L as LLMInstrumentationCallbacks, aP as ListSection, aU as LoadingConfig, as as MessageHandler, at as MessageHandlers, o as OllamaClient, O as OllamaClientOptions, aW as PanelDefinition, aT as PanelSection, b5 as PersistConfig, an as PluginContext, b7 as PluginDefinition, b2 as PluginIssue, aj as PluginRegistrationError, ai as PluginRegistry, al as PluginRegistryEvent, am as PluginRegistryListener, ax as PluginWithHandlers, aS as ProgressSection, b1 as RuleDefinition, a_ as RuleOptionField, a$ as RuleOptionSchema, b0 as RuleRequirement, k as SerializedStyles, i as SpacingRule, b6 as StateDefinition, n as StreamProgressCallback, S as StyleGuide, _ as StyleSnapshot, T as TailwindThemeTokens, aK as TextSection, aY as ToolbarActionDefinition, aZ as ToolbarGroupDefinition, h as TypographyRule, q as UILINT_DEFAULT_OLLAMA_MODEL, U as UILintIssue, f as UILintScanIssue, g as UILintSourceScanResult, a4 as Violation, a2 as ViolationCategory, a3 as ViolationSeverity, ao as WebSocketService, ad as analyzeConsistency, r as buildAnalysisPrompt, a7 as buildConsistencyPrompt, s as buildSourceAnalysisPrompt, t as buildSourceScanPrompt, u as buildStyleGuidePrompt, a8 as countElements, W as createColorRule, Z as createComponentRule, Q as createEmptyStyleGuide, Y as createSpacingRule, F as createStyleSummary, X as createTypographyRule, B as deserializeStyles, ah as devError, af as devLog, ag as devWarn, K as extractStyleValues, x as extractStyles, y as extractStylesFromDOM, M as extractTailwindAllowlist, ae as formatConsistencyViolations, v as formatViolationsText, N as generateStyleGuideFromStyles, p as getOllamaClient, a9 as hasAnalyzableGroups, ba as isConditionalValue, b8 as isDataBinding, b9 as isExpressionBinding, V as mergeStyleGuides, aa as parseGroupedSnapshot, H as parseStyleGuide, J as parseStyleGuideSections, ab as parseViolationsResponse, ak as pluginRegistry, w as sanitizeIssues, z as serializeStyles, P as styleGuideToMarkdown, G as truncateHTML, R as validateStyleGuide, ac as validateViolations } from './index-
|
|
1
|
+
export { aL as ActionButton, aq as ActionHandler, ar as ActionHandlers, aD as ActionReference, aM as ActionsSection, A as AnalysisResult, a6 as AnalyzeConsistencyOptions, aJ as BadgeSection, ap as BrowserActionResult, aR as CardSection, aI as CodeComparisonSection, aH as CodePanelConfig, aG as CodeViewerSection, C as ColorRule, aX as CommandDefinition, j as ComponentRule, b4 as ComputedValue, aO as ConditionalSection, aB as ConditionalValue, a5 as ConsistencyResult, D as DOMSnapshot, ay as DataBinding, aw as DisposeHook, aN as DividerSection, aA as DynamicValue, $ as ElementRole, a0 as ElementSnapshot, aV as EmptyConfig, az as ExpressionBinding, m as ExtractedStyleValues, E as ExtractedStyles, aE as FetchConfig, a1 as GroupedSnapshot, aF as HeaderSection, aC as IconName, aQ as ImageSection, av as InitializeHook, I as InstrumentationSpan, au as IssueAggregator, b3 as IssueContribution, L as LLMInstrumentationCallbacks, aP as ListSection, aU as LoadingConfig, as as MessageHandler, at as MessageHandlers, o as OllamaClient, O as OllamaClientOptions, bi as OperationActionConfig, bj as OperationMessageConfig, bg as OperationProgress, bh as OperationState, bf as OperationStatus, aW as PanelDefinition, aT as PanelSection, b5 as PersistConfig, an as PluginContext, b7 as PluginDefinition, b2 as PluginIssue, aj as PluginRegistrationError, ai as PluginRegistry, al as PluginRegistryEvent, am as PluginRegistryListener, ax as PluginWithHandlers, aS as ProgressSection, b1 as RuleDefinition, a_ as RuleOptionField, a$ as RuleOptionSchema, b0 as RuleRequirement, k as SerializedStyles, i as SpacingRule, b6 as StateDefinition, n as StreamProgressCallback, S as StyleGuide, _ as StyleSnapshot, T as TailwindThemeTokens, aK as TextSection, aY as ToolbarActionDefinition, aZ as ToolbarGroupDefinition, h as TypographyRule, q as UILINT_DEFAULT_OLLAMA_MODEL, U as UILintIssue, f as UILintScanIssue, g as UILintSourceScanResult, a4 as Violation, a2 as ViolationCategory, a3 as ViolationSeverity, ao as WebSocketService, ad as analyzeConsistency, r as buildAnalysisPrompt, a7 as buildConsistencyPrompt, s as buildSourceAnalysisPrompt, t as buildSourceScanPrompt, u as buildStyleGuidePrompt, a8 as countElements, W as createColorRule, Z as createComponentRule, Q as createEmptyStyleGuide, bd as createOperationActions, bc as createOperationComputed, bb as createOperationInitialState, be as createOperationMessageHandlers, Y as createSpacingRule, F as createStyleSummary, X as createTypographyRule, B as deserializeStyles, ah as devError, af as devLog, ag as devWarn, K as extractStyleValues, x as extractStyles, y as extractStylesFromDOM, M as extractTailwindAllowlist, ae as formatConsistencyViolations, v as formatViolationsText, N as generateStyleGuideFromStyles, p as getOllamaClient, a9 as hasAnalyzableGroups, ba as isConditionalValue, b8 as isDataBinding, b9 as isExpressionBinding, V as mergeStyleGuides, aa as parseGroupedSnapshot, H as parseStyleGuide, J as parseStyleGuideSections, ab as parseViolationsResponse, ak as pluginRegistry, w as sanitizeIssues, z as serializeStyles, P as styleGuideToMarkdown, G as truncateHTML, R as validateStyleGuide, ac as validateViolations } from './index-rJqAK3nT.js';
|
package/dist/index.js
CHANGED
|
@@ -13,6 +13,10 @@ import {
|
|
|
13
13
|
createColorRule,
|
|
14
14
|
createComponentRule,
|
|
15
15
|
createEmptyStyleGuide,
|
|
16
|
+
createOperationActions,
|
|
17
|
+
createOperationComputed,
|
|
18
|
+
createOperationInitialState,
|
|
19
|
+
createOperationMessageHandlers,
|
|
16
20
|
createSpacingRule,
|
|
17
21
|
createStyleSummary,
|
|
18
22
|
createTypographyRule,
|
|
@@ -44,7 +48,7 @@ import {
|
|
|
44
48
|
truncateHTML,
|
|
45
49
|
validateStyleGuide,
|
|
46
50
|
validateViolations
|
|
47
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-J4LUG7RV.js";
|
|
48
52
|
export {
|
|
49
53
|
OllamaClient,
|
|
50
54
|
PluginRegistrationError,
|
|
@@ -60,6 +64,10 @@ export {
|
|
|
60
64
|
createColorRule,
|
|
61
65
|
createComponentRule,
|
|
62
66
|
createEmptyStyleGuide,
|
|
67
|
+
createOperationActions,
|
|
68
|
+
createOperationComputed,
|
|
69
|
+
createOperationInitialState,
|
|
70
|
+
createOperationMessageHandlers,
|
|
63
71
|
createSpacingRule,
|
|
64
72
|
createStyleSummary,
|
|
65
73
|
createTypographyRule,
|
package/dist/node.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { D as DOMSnapshot, T as TailwindThemeTokens } from './index-
|
|
2
|
-
export { aL as ActionButton, aq as ActionHandler, ar as ActionHandlers, aD as ActionReference, aM as ActionsSection, A as AnalysisResult, a6 as AnalyzeConsistencyOptions, aJ as BadgeSection, ap as BrowserActionResult, aR as CardSection, aI as CodeComparisonSection, aH as CodePanelConfig, aG as CodeViewerSection, C as ColorRule, aX as CommandDefinition, j as ComponentRule, b4 as ComputedValue, aO as ConditionalSection, aB as ConditionalValue, a5 as ConsistencyResult, ay as DataBinding, aw as DisposeHook, aN as DividerSection, aA as DynamicValue, $ as ElementRole, a0 as ElementSnapshot, aV as EmptyConfig, az as ExpressionBinding, m as ExtractedStyleValues, E as ExtractedStyles, aE as FetchConfig, a1 as GroupedSnapshot, aF as HeaderSection, aC as IconName, aQ as ImageSection, av as InitializeHook, I as InstrumentationSpan, au as IssueAggregator, b3 as IssueContribution, L as LLMInstrumentationCallbacks, aP as ListSection, aU as LoadingConfig, as as MessageHandler, at as MessageHandlers, o as OllamaClient, O as OllamaClientOptions, aW as PanelDefinition, aT as PanelSection, b5 as PersistConfig, an as PluginContext, b7 as PluginDefinition, b2 as PluginIssue, aj as PluginRegistrationError, ai as PluginRegistry, al as PluginRegistryEvent, am as PluginRegistryListener, ax as PluginWithHandlers, aS as ProgressSection, b1 as RuleDefinition, a_ as RuleOptionField, a$ as RuleOptionSchema, b0 as RuleRequirement, k as SerializedStyles, i as SpacingRule, b6 as StateDefinition, n as StreamProgressCallback, S as StyleGuide, _ as StyleSnapshot, aK as TextSection, aY as ToolbarActionDefinition, aZ as ToolbarGroupDefinition, h as TypographyRule, q as UILINT_DEFAULT_OLLAMA_MODEL, U as UILintIssue, f as UILintScanIssue, g as UILintSourceScanResult, a4 as Violation, a2 as ViolationCategory, a3 as ViolationSeverity, ao as WebSocketService, ad as analyzeConsistency, r as buildAnalysisPrompt, a7 as buildConsistencyPrompt, s as buildSourceAnalysisPrompt, t as buildSourceScanPrompt, u as buildStyleGuidePrompt, a8 as countElements, W as createColorRule, Z as createComponentRule, Q as createEmptyStyleGuide, e as createProgress, Y as createSpacingRule, F as createStyleSummary, X as createTypographyRule, B as deserializeStyles, ah as devError, af as devLog, ag as devWarn, K as extractStyleValues, x as extractStyles, y as extractStylesFromDOM, M as extractTailwindAllowlist, ae as formatConsistencyViolations, v as formatViolationsText, N as generateStyleGuideFromStyles, p as getOllamaClient, a9 as hasAnalyzableGroups, ba as isConditionalValue, b8 as isDataBinding, b9 as isExpressionBinding, d as logDebug, c as logError, l as logInfo, a as logSuccess, b as logWarning, V as mergeStyleGuides, aa as parseGroupedSnapshot, H as parseStyleGuide, J as parseStyleGuideSections, ab as parseViolationsResponse, ak as pluginRegistry, w as sanitizeIssues, z as serializeStyles, P as styleGuideToMarkdown, G as truncateHTML, R as validateStyleGuide, ac as validateViolations } from './index-
|
|
1
|
+
import { D as DOMSnapshot, T as TailwindThemeTokens } from './index-rJqAK3nT.js';
|
|
2
|
+
export { aL as ActionButton, aq as ActionHandler, ar as ActionHandlers, aD as ActionReference, aM as ActionsSection, A as AnalysisResult, a6 as AnalyzeConsistencyOptions, aJ as BadgeSection, ap as BrowserActionResult, aR as CardSection, aI as CodeComparisonSection, aH as CodePanelConfig, aG as CodeViewerSection, C as ColorRule, aX as CommandDefinition, j as ComponentRule, b4 as ComputedValue, aO as ConditionalSection, aB as ConditionalValue, a5 as ConsistencyResult, ay as DataBinding, aw as DisposeHook, aN as DividerSection, aA as DynamicValue, $ as ElementRole, a0 as ElementSnapshot, aV as EmptyConfig, az as ExpressionBinding, m as ExtractedStyleValues, E as ExtractedStyles, aE as FetchConfig, a1 as GroupedSnapshot, aF as HeaderSection, aC as IconName, aQ as ImageSection, av as InitializeHook, I as InstrumentationSpan, au as IssueAggregator, b3 as IssueContribution, L as LLMInstrumentationCallbacks, aP as ListSection, aU as LoadingConfig, as as MessageHandler, at as MessageHandlers, o as OllamaClient, O as OllamaClientOptions, bi as OperationActionConfig, bj as OperationMessageConfig, bg as OperationProgress, bh as OperationState, bf as OperationStatus, aW as PanelDefinition, aT as PanelSection, b5 as PersistConfig, an as PluginContext, b7 as PluginDefinition, b2 as PluginIssue, aj as PluginRegistrationError, ai as PluginRegistry, al as PluginRegistryEvent, am as PluginRegistryListener, ax as PluginWithHandlers, aS as ProgressSection, b1 as RuleDefinition, a_ as RuleOptionField, a$ as RuleOptionSchema, b0 as RuleRequirement, k as SerializedStyles, i as SpacingRule, b6 as StateDefinition, n as StreamProgressCallback, S as StyleGuide, _ as StyleSnapshot, aK as TextSection, aY as ToolbarActionDefinition, aZ as ToolbarGroupDefinition, h as TypographyRule, q as UILINT_DEFAULT_OLLAMA_MODEL, U as UILintIssue, f as UILintScanIssue, g as UILintSourceScanResult, a4 as Violation, a2 as ViolationCategory, a3 as ViolationSeverity, ao as WebSocketService, ad as analyzeConsistency, r as buildAnalysisPrompt, a7 as buildConsistencyPrompt, s as buildSourceAnalysisPrompt, t as buildSourceScanPrompt, u as buildStyleGuidePrompt, a8 as countElements, W as createColorRule, Z as createComponentRule, Q as createEmptyStyleGuide, bd as createOperationActions, bc as createOperationComputed, bb as createOperationInitialState, be as createOperationMessageHandlers, e as createProgress, Y as createSpacingRule, F as createStyleSummary, X as createTypographyRule, B as deserializeStyles, ah as devError, af as devLog, ag as devWarn, K as extractStyleValues, x as extractStyles, y as extractStylesFromDOM, M as extractTailwindAllowlist, ae as formatConsistencyViolations, v as formatViolationsText, N as generateStyleGuideFromStyles, p as getOllamaClient, a9 as hasAnalyzableGroups, ba as isConditionalValue, b8 as isDataBinding, b9 as isExpressionBinding, d as logDebug, c as logError, l as logInfo, a as logSuccess, b as logWarning, V as mergeStyleGuides, aa as parseGroupedSnapshot, H as parseStyleGuide, J as parseStyleGuideSections, ab as parseViolationsResponse, ak as pluginRegistry, w as sanitizeIssues, z as serializeStyles, P as styleGuideToMarkdown, G as truncateHTML, R as validateStyleGuide, ac as validateViolations } from './index-rJqAK3nT.js';
|
|
3
3
|
export { default as pc } from 'picocolors';
|
|
4
4
|
|
|
5
5
|
/**
|
package/dist/node.js
CHANGED
|
@@ -13,6 +13,10 @@ import {
|
|
|
13
13
|
createColorRule,
|
|
14
14
|
createComponentRule,
|
|
15
15
|
createEmptyStyleGuide,
|
|
16
|
+
createOperationActions,
|
|
17
|
+
createOperationComputed,
|
|
18
|
+
createOperationInitialState,
|
|
19
|
+
createOperationMessageHandlers,
|
|
16
20
|
createProgress,
|
|
17
21
|
createSpacingRule,
|
|
18
22
|
createStyleSummary,
|
|
@@ -51,7 +55,7 @@ import {
|
|
|
51
55
|
truncateHTML,
|
|
52
56
|
validateStyleGuide,
|
|
53
57
|
validateViolations
|
|
54
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-J4LUG7RV.js";
|
|
55
59
|
|
|
56
60
|
// src/ollama/bootstrap.ts
|
|
57
61
|
import { spawn, spawnSync } from "child_process";
|
|
@@ -463,6 +467,10 @@ export {
|
|
|
463
467
|
createColorRule,
|
|
464
468
|
createComponentRule,
|
|
465
469
|
createEmptyStyleGuide,
|
|
470
|
+
createOperationActions,
|
|
471
|
+
createOperationComputed,
|
|
472
|
+
createOperationInitialState,
|
|
473
|
+
createOperationMessageHandlers,
|
|
466
474
|
createProgress,
|
|
467
475
|
createSpacingRule,
|
|
468
476
|
createStyleSummary,
|
package/dist/node.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ollama/bootstrap.ts","../src/scanner/html-parser.ts","../src/styleguide/reader.ts","../src/utils/workspace-root.ts","../src/tailwind/config-reader.ts"],"sourcesContent":["/**\n * Ollama bootstrapping utilities (Node.js only).\n *\n * Goals:\n * - Detect whether Ollama is installed.\n * - Ensure the Ollama daemon is running (best effort: start `ollama serve` detached).\n * - Ensure a given model is pulled (best effort: run `ollama pull <model>`).\n */\n\nimport { spawn, spawnSync } from \"child_process\";\nimport readline from \"readline\";\nimport { OllamaClient } from \"./client.js\";\nimport { UILINT_DEFAULT_OLLAMA_MODEL } from \"./defaults.js\";\n\nconst DEFAULT_OLLAMA_BASE_URL = \"http://localhost:11434\";\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction isInteractiveTTY(): boolean {\n return Boolean(process.stdin.isTTY && process.stdout.isTTY);\n}\n\nasync function promptYesNo(question: string): Promise<boolean> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n return await new Promise<boolean>((resolve) => {\n rl.question(`${question} (y/N) `, (answer) => {\n rl.close();\n const normalized = (answer || \"\").trim().toLowerCase();\n resolve(normalized === \"y\" || normalized === \"yes\");\n });\n });\n}\n\nexport function isOllamaInstalled(): boolean {\n const result = spawnSync(\"ollama\", [\"--version\"], { stdio: \"ignore\" });\n if (\n result.error &&\n (result.error as NodeJS.ErrnoException).code === \"ENOENT\"\n ) {\n return false;\n }\n return result.status === 0;\n}\n\nfunction isBrewInstalled(): boolean {\n const result = spawnSync(\"brew\", [\"--version\"], { stdio: \"ignore\" });\n if (\n result.error &&\n (result.error as NodeJS.ErrnoException).code === \"ENOENT\"\n ) {\n return false;\n }\n return result.status === 0;\n}\n\nfunction getInstallInstructions(): string[] {\n const lines: string[] = [\n \"Ollama is required for LLM-backed analysis.\",\n \"\",\n \"Install Ollama:\",\n \" - Download: https://ollama.ai\",\n ];\n\n if (process.platform === \"darwin\") {\n lines.push(\" - Homebrew: brew install ollama\");\n }\n\n lines.push(\"\");\n lines.push(\"Then start it:\");\n lines.push(\" ollama serve\");\n return lines;\n}\n\nasync function maybeInstallOllamaWithBrew(): Promise<boolean> {\n if (process.platform !== \"darwin\") return false;\n if (!isInteractiveTTY()) return false;\n\n if (!isBrewInstalled()) {\n // We can't auto-install without brew; leave instructions to the caller.\n return false;\n }\n\n const ok = await promptYesNo(\n \"Ollama is not installed. Install with Homebrew now?\"\n );\n if (!ok) return false;\n\n await new Promise<void>((resolve, reject) => {\n const child = spawn(\"brew\", [\"install\", \"ollama\"], { stdio: \"inherit\" });\n child.on(\"error\", reject);\n child.on(\"exit\", (code) => {\n if (code === 0) resolve();\n else reject(new Error(`brew install ollama failed (exit ${code})`));\n });\n });\n\n return isOllamaInstalled();\n}\n\nexport async function ensureOllamaInstalledOrExplain(): Promise<void> {\n if (isOllamaInstalled()) return;\n\n const installedViaBrew = await maybeInstallOllamaWithBrew();\n if (installedViaBrew) return;\n\n const extra: string[] = [];\n if (process.platform === \"darwin\" && !isBrewInstalled()) {\n extra.push(\"\");\n extra.push(\"Homebrew is not installed. Install it first, then run:\");\n extra.push(\" brew install ollama\");\n }\n\n throw new Error([...getInstallInstructions(), ...extra].join(\"\\n\"));\n}\n\nexport async function ensureOllamaRunning(options?: {\n timeoutMs?: number;\n baseUrl?: string;\n}): Promise<void> {\n await ensureOllamaInstalledOrExplain();\n\n const baseUrl = options?.baseUrl || DEFAULT_OLLAMA_BASE_URL;\n const client = new OllamaClient({ baseUrl });\n const timeoutMs = options?.timeoutMs ?? 10_000;\n\n if (await client.isAvailable()) return;\n\n // Best-effort background start. We do not stop it later.\n try {\n const child = spawn(\"ollama\", [\"serve\"], {\n detached: true,\n stdio: \"ignore\",\n });\n child.unref();\n } catch (err) {\n throw new Error(\n `Failed to start Ollama automatically.\\n\\n${getInstallInstructions().join(\n \"\\n\"\n )}\\n\\nDetails: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n\n const start = Date.now();\n while (Date.now() - start < timeoutMs) {\n if (await client.isAvailable()) return;\n await sleep(250);\n }\n\n throw new Error(\n [\n \"Ollama did not become ready in time.\",\n \"\",\n \"Try starting it manually:\",\n \" ollama serve\",\n ].join(\"\\n\")\n );\n}\n\nasync function fetchOllamaTags(baseUrl: string): Promise<string[]> {\n const res = await fetch(`${baseUrl}/api/tags`, {\n method: \"GET\",\n signal: AbortSignal.timeout(5000),\n });\n\n if (!res.ok) {\n throw new Error(`Ollama tags endpoint returned ${res.status}`);\n }\n\n const data = (await res.json()) as { models?: Array<{ name?: string }> };\n const names = (data.models ?? [])\n .map((m) => m.name)\n .filter((n): n is string => typeof n === \"string\");\n return names;\n}\n\nexport async function ensureOllamaModelPulled(options?: {\n model?: string;\n baseUrl?: string;\n}): Promise<void> {\n const desired = (options?.model || UILINT_DEFAULT_OLLAMA_MODEL).trim();\n if (!desired) return;\n\n const baseUrl = options?.baseUrl || DEFAULT_OLLAMA_BASE_URL;\n const tags = await fetchOllamaTags(baseUrl);\n if (tags.includes(desired)) return;\n\n await new Promise<void>((resolve, reject) => {\n const child = spawn(\"ollama\", [\"pull\", desired], { stdio: \"inherit\" });\n child.on(\"error\", reject);\n child.on(\"exit\", (code) => {\n if (code === 0) resolve();\n else reject(new Error(`ollama pull ${desired} failed (exit ${code})`));\n });\n });\n\n const tagsAfter = await fetchOllamaTags(baseUrl);\n if (!tagsAfter.includes(desired)) {\n throw new Error(\n `Model ${desired} did not appear in Ollama tags after pulling.`\n );\n }\n}\n\nexport async function ensureOllamaReady(options?: {\n model?: string;\n timeoutMs?: number;\n baseUrl?: string;\n}): Promise<void> {\n await ensureOllamaRunning({\n timeoutMs: options?.timeoutMs,\n baseUrl: options?.baseUrl,\n });\n await ensureOllamaModelPulled({\n model: options?.model,\n baseUrl: options?.baseUrl,\n });\n}\n","/**\n * HTML parser for extracting styles using JSDOM\n * Used by CLI and Node.js environments\n */\n\nimport { JSDOM } from \"jsdom\";\nimport type { DOMSnapshot, SerializedStyles } from \"../types.js\";\nimport { extractStyles, deserializeStyles, truncateHTML } from \"./style-extractor.js\";\n\nexport interface ParseOptions {\n /**\n * If true, tries to load and process linked stylesheets\n */\n loadStylesheets?: boolean;\n /**\n * Max length for HTML in snapshot\n */\n maxHtmlLength?: number;\n}\n\n/**\n * Parses raw HTML and extracts styles using JSDOM\n */\nexport function parseHTML(\n html: string,\n options: ParseOptions = {}\n): DOMSnapshot {\n const { maxHtmlLength = 50000 } = options;\n\n const dom = new JSDOM(html, {\n runScripts: \"outside-only\",\n pretendToBeVisual: true,\n });\n\n const { document, getComputedStyle } = dom.window;\n const root = document.body || document.documentElement;\n\n const styles = extractStyles(root, getComputedStyle);\n const elementCount = root.querySelectorAll(\"*\").length;\n\n return {\n html: truncateHTML(html, maxHtmlLength),\n styles,\n elementCount,\n timestamp: Date.now(),\n };\n}\n\n/**\n * Input format for CLI - can be raw HTML or pre-extracted JSON\n */\nexport interface CLIInput {\n html: string;\n styles?: SerializedStyles;\n}\n\n/**\n * Parses CLI input which can be either raw HTML or JSON with pre-extracted styles\n */\nexport function parseCLIInput(input: string): DOMSnapshot {\n // Try to parse as JSON first\n try {\n const parsed = JSON.parse(input) as CLIInput;\n \n if (parsed.html && parsed.styles) {\n // Pre-extracted styles from browser/test environment\n return {\n html: truncateHTML(parsed.html),\n styles: deserializeStyles(parsed.styles),\n elementCount: 0, // Not available for pre-extracted\n timestamp: Date.now(),\n };\n } else if (parsed.html) {\n // Just HTML in JSON format\n return parseHTML(parsed.html);\n }\n } catch {\n // Not JSON, treat as raw HTML\n }\n\n // Parse as raw HTML\n return parseHTML(input);\n}\n\n/**\n * Checks if a string looks like JSON\n */\nexport function isJSON(str: string): boolean {\n const trimmed = str.trim();\n return trimmed.startsWith(\"{\") || trimmed.startsWith(\"[\");\n}\n\n/**\n * Reads input from stdin\n */\nexport async function readStdin(): Promise<string> {\n const chunks: Uint8Array[] = [];\n \n return new Promise((resolve, reject) => {\n process.stdin.on(\"data\", (chunk: Buffer | string) => {\n chunks.push(typeof chunk === \"string\" ? Buffer.from(chunk) : chunk);\n });\n process.stdin.on(\"end\", () => resolve(Buffer.concat(chunks).toString(\"utf-8\")));\n process.stdin.on(\"error\", reject);\n });\n}\n\n/**\n * Detects if stdin has data\n */\nexport function hasStdin(): boolean {\n return !process.stdin.isTTY;\n}\n\n","/**\n * Style guide file operations\n */\n\nimport { readFile, writeFile, mkdir } from \"fs/promises\";\nimport { existsSync } from \"fs\";\nimport { join, dirname } from \"path\";\n\nexport const STYLEGUIDE_PATHS = [\n \".uilint/styleguide.md\",\n \"styleguide.md\",\n \".uilint/style-guide.md\",\n];\n\n/**\n * Walk upward from a starting directory and look specifically for `.uilint/styleguide.md`.\n *\n * This is intended for flows where the \"project root\" is ambiguous (e.g., analyzing\n * an arbitrary file path) and we want the nearest `.uilint` config on the way up.\n */\nexport function findUILintStyleGuideUpwards(startDir: string): string | null {\n let dir = startDir;\n for (;;) {\n const candidate = join(dir, \".uilint\", \"styleguide.md\");\n if (existsSync(candidate)) return candidate;\n\n const parent = dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\n/**\n * Finds the style guide file in a project\n */\nexport function findStyleGuidePath(projectPath: string): string | null {\n for (const relativePath of STYLEGUIDE_PATHS) {\n const fullPath = join(projectPath, relativePath);\n if (existsSync(fullPath)) {\n return fullPath;\n }\n }\n return null;\n}\n\n/**\n * Reads the style guide content\n */\nexport async function readStyleGuide(path: string): Promise<string> {\n return readFile(path, \"utf-8\");\n}\n\n/**\n * Reads style guide from project path, finding it automatically\n */\nexport async function readStyleGuideFromProject(\n projectPath: string\n): Promise<string | null> {\n const path = findStyleGuidePath(projectPath);\n if (!path) return null;\n return readStyleGuide(path);\n}\n\n/**\n * Writes style guide content to file\n */\nexport async function writeStyleGuide(\n path: string,\n content: string\n): Promise<void> {\n const dir = dirname(path);\n await mkdir(dir, { recursive: true });\n await writeFile(path, content, \"utf-8\");\n}\n\n/**\n * Gets the default style guide path for a project\n */\nexport function getDefaultStyleGuidePath(projectPath: string): string {\n return join(projectPath, \".uilint\", \"styleguide.md\");\n}\n\n/**\n * Checks if a style guide exists\n */\nexport function styleGuideExists(projectPath: string): boolean {\n return findStyleGuidePath(projectPath) !== null;\n}\n","/**\n * Resolve the workspace/repo root from an arbitrary starting directory.\n *\n * This is primarily used in monorepos where runtime `process.cwd()` may point at\n * a sub-app (e.g. `apps/web`) but UI linting assets live at the workspace root.\n */\nimport { existsSync, readFileSync } from \"fs\";\nimport { dirname, join } from \"path\";\n\nfunction hasWorkspacesField(dir: string): boolean {\n const pkgPath = join(dir, \"package.json\");\n if (!existsSync(pkgPath)) return false;\n try {\n const raw = readFileSync(pkgPath, \"utf-8\");\n const pkg = JSON.parse(raw) as { workspaces?: unknown };\n return !!pkg.workspaces;\n } catch {\n return false;\n }\n}\n\nfunction hasRootMarker(dir: string): boolean {\n // pnpm is the primary supported monorepo layout in this repo\n if (existsSync(join(dir, \"pnpm-workspace.yaml\"))) return true;\n // fallbacks for other setups\n if (existsSync(join(dir, \".git\"))) return true;\n if (hasWorkspacesField(dir)) return true;\n return false;\n}\n\n/**\n * Walks up from `startDir` to find a likely workspace root.\n *\n * If none is found, returns `startDir`.\n */\nexport function findWorkspaceRoot(startDir: string): string {\n let dir = startDir;\n let lastFallback: string | null = null;\n\n for (;;) {\n if (existsSync(join(dir, \"pnpm-workspace.yaml\"))) return dir;\n\n if (hasRootMarker(dir)) {\n // keep walking to prefer the highest-level marker (esp. .git)\n lastFallback = dir;\n }\n\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n\n return lastFallback || startDir;\n}\n","/**\n * Tailwind config reader (Node-only).\n *\n * Goals:\n * - Locate a Tailwind config file near a project directory.\n * - Load it (supports .ts via jiti).\n * - Produce compact token sets for styleguide + validation.\n *\n * Note: We intentionally extract tokens primarily from user-defined theme / extend\n * to avoid dumping Tailwind's full default palette into the style guide.\n */\n\nimport { existsSync } from \"fs\";\nimport { createRequire } from \"module\";\nimport { dirname, join } from \"path\";\nimport jiti from \"jiti\";\nimport type { TailwindThemeTokens } from \"../types.js\";\n\nconst CONFIG_CANDIDATES = [\n \"tailwind.config.ts\",\n \"tailwind.config.mts\",\n \"tailwind.config.cts\",\n \"tailwind.config.js\",\n \"tailwind.config.mjs\",\n \"tailwind.config.cjs\",\n];\n\nexport function findTailwindConfigPath(startDir: string): string | null {\n let dir = startDir;\n for (;;) {\n for (const name of CONFIG_CANDIDATES) {\n const full = join(dir, name);\n if (existsSync(full)) return full;\n }\n\n const parent = dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\nexport function readTailwindThemeTokens(\n projectDir: string\n): TailwindThemeTokens | null {\n const configPath = findTailwindConfigPath(projectDir);\n if (!configPath) return null;\n\n const loader = jiti(import.meta.url, { interopDefault: true });\n const loaded = loader(configPath) as Record<string, unknown>;\n const config = ((loaded?.default ?? loaded) as Record<string, unknown>);\n if (!config || typeof config !== \"object\") return null;\n\n // Best-effort: run resolveConfig to ensure config is valid/normalized.\n // We don’t use the resolved theme for token enumeration (to avoid defaults),\n // but we do want to surface loader/shape problems early for debugging.\n try {\n const require = createRequire(import.meta.url);\n const maybe = require(\"tailwindcss/resolveConfig\");\n const resolveConfig = (maybe?.default ?? maybe) as\n | ((cfg: Record<string, unknown>) => unknown)\n | undefined;\n if (typeof resolveConfig === \"function\") resolveConfig(config);\n } catch {\n // If resolve fails, still attempt to extract from raw object.\n }\n\n const theme: Record<string, unknown> =\n config.theme && typeof config.theme === \"object\" ? (config.theme as Record<string, unknown>) : {};\n const extend: Record<string, unknown> =\n theme.extend && typeof theme.extend === \"object\" ? (theme.extend as Record<string, unknown>) : {};\n\n const colors = new Set<string>();\n const spacingKeys = new Set<string>();\n const borderRadiusKeys = new Set<string>();\n const fontFamilyKeys = new Set<string>();\n const fontSizeKeys = new Set<string>();\n\n // Merge base + extend per category.\n addColorTokens(colors, theme.colors);\n addColorTokens(colors, extend.colors);\n\n addKeys(spacingKeys, theme.spacing);\n addKeys(spacingKeys, extend.spacing);\n\n addKeys(borderRadiusKeys, theme.borderRadius);\n addKeys(borderRadiusKeys, extend.borderRadius);\n\n addKeys(fontFamilyKeys, theme.fontFamily);\n addKeys(fontFamilyKeys, extend.fontFamily);\n\n addKeys(fontSizeKeys, theme.fontSize);\n addKeys(fontSizeKeys, extend.fontSize);\n\n // If user config didn’t specify tokens, we still return an object to signal\n // \"tailwind detected\", but with empty sets (downstream can choose defaults).\n return {\n configPath,\n colors: [...colors],\n spacingKeys: [...spacingKeys],\n borderRadiusKeys: [...borderRadiusKeys],\n fontFamilyKeys: [...fontFamilyKeys],\n fontSizeKeys: [...fontSizeKeys],\n };\n}\n\nfunction addKeys(out: Set<string>, obj: unknown): void {\n if (!obj || typeof obj !== \"object\") return;\n for (const key of Object.keys(obj as Record<string, unknown>)) {\n if (!key) continue;\n out.add(key);\n }\n}\n\nfunction addColorTokens(out: Set<string>, colors: unknown): void {\n if (!colors || typeof colors !== \"object\") return;\n\n for (const [name, value] of Object.entries(\n colors as Record<string, unknown>\n )) {\n if (!name) continue;\n\n if (typeof value === \"string\") {\n out.add(`tailwind:${name}`);\n continue;\n }\n\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n for (const shade of Object.keys(value as Record<string, unknown>)) {\n if (!shade) continue;\n out.add(`tailwind:${name}-${shade}`);\n }\n continue;\n }\n\n // Arrays / functions etc are ignored for token enumeration.\n }\n}\n"],"mappings":"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","names":["existsSync","dirname","join","existsSync","dirname","join","require"]}
|
|
1
|
+
{"version":3,"sources":["../src/ollama/bootstrap.ts","../src/scanner/html-parser.ts","../src/styleguide/reader.ts","../src/utils/workspace-root.ts","../src/tailwind/config-reader.ts"],"sourcesContent":["/**\n * Ollama bootstrapping utilities (Node.js only).\n *\n * Goals:\n * - Detect whether Ollama is installed.\n * - Ensure the Ollama daemon is running (best effort: start `ollama serve` detached).\n * - Ensure a given model is pulled (best effort: run `ollama pull <model>`).\n */\n\nimport { spawn, spawnSync } from \"child_process\";\nimport readline from \"readline\";\nimport { OllamaClient } from \"./client.js\";\nimport { UILINT_DEFAULT_OLLAMA_MODEL } from \"./defaults.js\";\n\nconst DEFAULT_OLLAMA_BASE_URL = \"http://localhost:11434\";\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction isInteractiveTTY(): boolean {\n return Boolean(process.stdin.isTTY && process.stdout.isTTY);\n}\n\nasync function promptYesNo(question: string): Promise<boolean> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n return await new Promise<boolean>((resolve) => {\n rl.question(`${question} (y/N) `, (answer) => {\n rl.close();\n const normalized = (answer || \"\").trim().toLowerCase();\n resolve(normalized === \"y\" || normalized === \"yes\");\n });\n });\n}\n\nexport function isOllamaInstalled(): boolean {\n const result = spawnSync(\"ollama\", [\"--version\"], { stdio: \"ignore\" });\n if (\n result.error &&\n (result.error as NodeJS.ErrnoException).code === \"ENOENT\"\n ) {\n return false;\n }\n return result.status === 0;\n}\n\nfunction isBrewInstalled(): boolean {\n const result = spawnSync(\"brew\", [\"--version\"], { stdio: \"ignore\" });\n if (\n result.error &&\n (result.error as NodeJS.ErrnoException).code === \"ENOENT\"\n ) {\n return false;\n }\n return result.status === 0;\n}\n\nfunction getInstallInstructions(): string[] {\n const lines: string[] = [\n \"Ollama is required for LLM-backed analysis.\",\n \"\",\n \"Install Ollama:\",\n \" - Download: https://ollama.ai\",\n ];\n\n if (process.platform === \"darwin\") {\n lines.push(\" - Homebrew: brew install ollama\");\n }\n\n lines.push(\"\");\n lines.push(\"Then start it:\");\n lines.push(\" ollama serve\");\n return lines;\n}\n\nasync function maybeInstallOllamaWithBrew(): Promise<boolean> {\n if (process.platform !== \"darwin\") return false;\n if (!isInteractiveTTY()) return false;\n\n if (!isBrewInstalled()) {\n // We can't auto-install without brew; leave instructions to the caller.\n return false;\n }\n\n const ok = await promptYesNo(\n \"Ollama is not installed. Install with Homebrew now?\"\n );\n if (!ok) return false;\n\n await new Promise<void>((resolve, reject) => {\n const child = spawn(\"brew\", [\"install\", \"ollama\"], { stdio: \"inherit\" });\n child.on(\"error\", reject);\n child.on(\"exit\", (code) => {\n if (code === 0) resolve();\n else reject(new Error(`brew install ollama failed (exit ${code})`));\n });\n });\n\n return isOllamaInstalled();\n}\n\nexport async function ensureOllamaInstalledOrExplain(): Promise<void> {\n if (isOllamaInstalled()) return;\n\n const installedViaBrew = await maybeInstallOllamaWithBrew();\n if (installedViaBrew) return;\n\n const extra: string[] = [];\n if (process.platform === \"darwin\" && !isBrewInstalled()) {\n extra.push(\"\");\n extra.push(\"Homebrew is not installed. Install it first, then run:\");\n extra.push(\" brew install ollama\");\n }\n\n throw new Error([...getInstallInstructions(), ...extra].join(\"\\n\"));\n}\n\nexport async function ensureOllamaRunning(options?: {\n timeoutMs?: number;\n baseUrl?: string;\n}): Promise<void> {\n await ensureOllamaInstalledOrExplain();\n\n const baseUrl = options?.baseUrl || DEFAULT_OLLAMA_BASE_URL;\n const client = new OllamaClient({ baseUrl });\n const timeoutMs = options?.timeoutMs ?? 10_000;\n\n if (await client.isAvailable()) return;\n\n // Best-effort background start. We do not stop it later.\n try {\n const child = spawn(\"ollama\", [\"serve\"], {\n detached: true,\n stdio: \"ignore\",\n });\n child.unref();\n } catch (err) {\n throw new Error(\n `Failed to start Ollama automatically.\\n\\n${getInstallInstructions().join(\n \"\\n\"\n )}\\n\\nDetails: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n\n const start = Date.now();\n while (Date.now() - start < timeoutMs) {\n if (await client.isAvailable()) return;\n await sleep(250);\n }\n\n throw new Error(\n [\n \"Ollama did not become ready in time.\",\n \"\",\n \"Try starting it manually:\",\n \" ollama serve\",\n ].join(\"\\n\")\n );\n}\n\nasync function fetchOllamaTags(baseUrl: string): Promise<string[]> {\n const res = await fetch(`${baseUrl}/api/tags`, {\n method: \"GET\",\n signal: AbortSignal.timeout(5000),\n });\n\n if (!res.ok) {\n throw new Error(`Ollama tags endpoint returned ${res.status}`);\n }\n\n const data = (await res.json()) as { models?: Array<{ name?: string }> };\n const names = (data.models ?? [])\n .map((m) => m.name)\n .filter((n): n is string => typeof n === \"string\");\n return names;\n}\n\nexport async function ensureOllamaModelPulled(options?: {\n model?: string;\n baseUrl?: string;\n}): Promise<void> {\n const desired = (options?.model || UILINT_DEFAULT_OLLAMA_MODEL).trim();\n if (!desired) return;\n\n const baseUrl = options?.baseUrl || DEFAULT_OLLAMA_BASE_URL;\n const tags = await fetchOllamaTags(baseUrl);\n if (tags.includes(desired)) return;\n\n await new Promise<void>((resolve, reject) => {\n const child = spawn(\"ollama\", [\"pull\", desired], { stdio: \"inherit\" });\n child.on(\"error\", reject);\n child.on(\"exit\", (code) => {\n if (code === 0) resolve();\n else reject(new Error(`ollama pull ${desired} failed (exit ${code})`));\n });\n });\n\n const tagsAfter = await fetchOllamaTags(baseUrl);\n if (!tagsAfter.includes(desired)) {\n throw new Error(\n `Model ${desired} did not appear in Ollama tags after pulling.`\n );\n }\n}\n\nexport async function ensureOllamaReady(options?: {\n model?: string;\n timeoutMs?: number;\n baseUrl?: string;\n}): Promise<void> {\n await ensureOllamaRunning({\n timeoutMs: options?.timeoutMs,\n baseUrl: options?.baseUrl,\n });\n await ensureOllamaModelPulled({\n model: options?.model,\n baseUrl: options?.baseUrl,\n });\n}\n","/**\n * HTML parser for extracting styles using JSDOM\n * Used by CLI and Node.js environments\n */\n\nimport { JSDOM } from \"jsdom\";\nimport type { DOMSnapshot, SerializedStyles } from \"../types.js\";\nimport { extractStyles, deserializeStyles, truncateHTML } from \"./style-extractor.js\";\n\nexport interface ParseOptions {\n /**\n * If true, tries to load and process linked stylesheets\n */\n loadStylesheets?: boolean;\n /**\n * Max length for HTML in snapshot\n */\n maxHtmlLength?: number;\n}\n\n/**\n * Parses raw HTML and extracts styles using JSDOM\n */\nexport function parseHTML(\n html: string,\n options: ParseOptions = {}\n): DOMSnapshot {\n const { maxHtmlLength = 50000 } = options;\n\n const dom = new JSDOM(html, {\n runScripts: \"outside-only\",\n pretendToBeVisual: true,\n });\n\n const { document, getComputedStyle } = dom.window;\n const root = document.body || document.documentElement;\n\n const styles = extractStyles(root, getComputedStyle);\n const elementCount = root.querySelectorAll(\"*\").length;\n\n return {\n html: truncateHTML(html, maxHtmlLength),\n styles,\n elementCount,\n timestamp: Date.now(),\n };\n}\n\n/**\n * Input format for CLI - can be raw HTML or pre-extracted JSON\n */\nexport interface CLIInput {\n html: string;\n styles?: SerializedStyles;\n}\n\n/**\n * Parses CLI input which can be either raw HTML or JSON with pre-extracted styles\n */\nexport function parseCLIInput(input: string): DOMSnapshot {\n // Try to parse as JSON first\n try {\n const parsed = JSON.parse(input) as CLIInput;\n \n if (parsed.html && parsed.styles) {\n // Pre-extracted styles from browser/test environment\n return {\n html: truncateHTML(parsed.html),\n styles: deserializeStyles(parsed.styles),\n elementCount: 0, // Not available for pre-extracted\n timestamp: Date.now(),\n };\n } else if (parsed.html) {\n // Just HTML in JSON format\n return parseHTML(parsed.html);\n }\n } catch {\n // Not JSON, treat as raw HTML\n }\n\n // Parse as raw HTML\n return parseHTML(input);\n}\n\n/**\n * Checks if a string looks like JSON\n */\nexport function isJSON(str: string): boolean {\n const trimmed = str.trim();\n return trimmed.startsWith(\"{\") || trimmed.startsWith(\"[\");\n}\n\n/**\n * Reads input from stdin\n */\nexport async function readStdin(): Promise<string> {\n const chunks: Uint8Array[] = [];\n \n return new Promise((resolve, reject) => {\n process.stdin.on(\"data\", (chunk: Buffer | string) => {\n chunks.push(typeof chunk === \"string\" ? Buffer.from(chunk) : chunk);\n });\n process.stdin.on(\"end\", () => resolve(Buffer.concat(chunks).toString(\"utf-8\")));\n process.stdin.on(\"error\", reject);\n });\n}\n\n/**\n * Detects if stdin has data\n */\nexport function hasStdin(): boolean {\n return !process.stdin.isTTY;\n}\n\n","/**\n * Style guide file operations\n */\n\nimport { readFile, writeFile, mkdir } from \"fs/promises\";\nimport { existsSync } from \"fs\";\nimport { join, dirname } from \"path\";\n\nexport const STYLEGUIDE_PATHS = [\n \".uilint/styleguide.md\",\n \"styleguide.md\",\n \".uilint/style-guide.md\",\n];\n\n/**\n * Walk upward from a starting directory and look specifically for `.uilint/styleguide.md`.\n *\n * This is intended for flows where the \"project root\" is ambiguous (e.g., analyzing\n * an arbitrary file path) and we want the nearest `.uilint` config on the way up.\n */\nexport function findUILintStyleGuideUpwards(startDir: string): string | null {\n let dir = startDir;\n for (;;) {\n const candidate = join(dir, \".uilint\", \"styleguide.md\");\n if (existsSync(candidate)) return candidate;\n\n const parent = dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\n/**\n * Finds the style guide file in a project\n */\nexport function findStyleGuidePath(projectPath: string): string | null {\n for (const relativePath of STYLEGUIDE_PATHS) {\n const fullPath = join(projectPath, relativePath);\n if (existsSync(fullPath)) {\n return fullPath;\n }\n }\n return null;\n}\n\n/**\n * Reads the style guide content\n */\nexport async function readStyleGuide(path: string): Promise<string> {\n return readFile(path, \"utf-8\");\n}\n\n/**\n * Reads style guide from project path, finding it automatically\n */\nexport async function readStyleGuideFromProject(\n projectPath: string\n): Promise<string | null> {\n const path = findStyleGuidePath(projectPath);\n if (!path) return null;\n return readStyleGuide(path);\n}\n\n/**\n * Writes style guide content to file\n */\nexport async function writeStyleGuide(\n path: string,\n content: string\n): Promise<void> {\n const dir = dirname(path);\n await mkdir(dir, { recursive: true });\n await writeFile(path, content, \"utf-8\");\n}\n\n/**\n * Gets the default style guide path for a project\n */\nexport function getDefaultStyleGuidePath(projectPath: string): string {\n return join(projectPath, \".uilint\", \"styleguide.md\");\n}\n\n/**\n * Checks if a style guide exists\n */\nexport function styleGuideExists(projectPath: string): boolean {\n return findStyleGuidePath(projectPath) !== null;\n}\n","/**\n * Resolve the workspace/repo root from an arbitrary starting directory.\n *\n * This is primarily used in monorepos where runtime `process.cwd()` may point at\n * a sub-app (e.g. `apps/web`) but UI linting assets live at the workspace root.\n */\nimport { existsSync, readFileSync } from \"fs\";\nimport { dirname, join } from \"path\";\n\nfunction hasWorkspacesField(dir: string): boolean {\n const pkgPath = join(dir, \"package.json\");\n if (!existsSync(pkgPath)) return false;\n try {\n const raw = readFileSync(pkgPath, \"utf-8\");\n const pkg = JSON.parse(raw) as { workspaces?: unknown };\n return !!pkg.workspaces;\n } catch {\n return false;\n }\n}\n\nfunction hasRootMarker(dir: string): boolean {\n // pnpm is the primary supported monorepo layout in this repo\n if (existsSync(join(dir, \"pnpm-workspace.yaml\"))) return true;\n // fallbacks for other setups\n if (existsSync(join(dir, \".git\"))) return true;\n if (hasWorkspacesField(dir)) return true;\n return false;\n}\n\n/**\n * Walks up from `startDir` to find a likely workspace root.\n *\n * If none is found, returns `startDir`.\n */\nexport function findWorkspaceRoot(startDir: string): string {\n let dir = startDir;\n let lastFallback: string | null = null;\n\n for (;;) {\n if (existsSync(join(dir, \"pnpm-workspace.yaml\"))) return dir;\n\n if (hasRootMarker(dir)) {\n // keep walking to prefer the highest-level marker (esp. .git)\n lastFallback = dir;\n }\n\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n\n return lastFallback || startDir;\n}\n","/**\n * Tailwind config reader (Node-only).\n *\n * Goals:\n * - Locate a Tailwind config file near a project directory.\n * - Load it (supports .ts via jiti).\n * - Produce compact token sets for styleguide + validation.\n *\n * Note: We intentionally extract tokens primarily from user-defined theme / extend\n * to avoid dumping Tailwind's full default palette into the style guide.\n */\n\nimport { existsSync } from \"fs\";\nimport { createRequire } from \"module\";\nimport { dirname, join } from \"path\";\nimport jiti from \"jiti\";\nimport type { TailwindThemeTokens } from \"../types.js\";\n\nconst CONFIG_CANDIDATES = [\n \"tailwind.config.ts\",\n \"tailwind.config.mts\",\n \"tailwind.config.cts\",\n \"tailwind.config.js\",\n \"tailwind.config.mjs\",\n \"tailwind.config.cjs\",\n];\n\nexport function findTailwindConfigPath(startDir: string): string | null {\n let dir = startDir;\n for (;;) {\n for (const name of CONFIG_CANDIDATES) {\n const full = join(dir, name);\n if (existsSync(full)) return full;\n }\n\n const parent = dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\nexport function readTailwindThemeTokens(\n projectDir: string\n): TailwindThemeTokens | null {\n const configPath = findTailwindConfigPath(projectDir);\n if (!configPath) return null;\n\n const loader = jiti(import.meta.url, { interopDefault: true });\n const loaded = loader(configPath) as Record<string, unknown>;\n const config = ((loaded?.default ?? loaded) as Record<string, unknown>);\n if (!config || typeof config !== \"object\") return null;\n\n // Best-effort: run resolveConfig to ensure config is valid/normalized.\n // We don’t use the resolved theme for token enumeration (to avoid defaults),\n // but we do want to surface loader/shape problems early for debugging.\n try {\n const require = createRequire(import.meta.url);\n const maybe = require(\"tailwindcss/resolveConfig\");\n const resolveConfig = (maybe?.default ?? maybe) as\n | ((cfg: Record<string, unknown>) => unknown)\n | undefined;\n if (typeof resolveConfig === \"function\") resolveConfig(config);\n } catch {\n // If resolve fails, still attempt to extract from raw object.\n }\n\n const theme: Record<string, unknown> =\n config.theme && typeof config.theme === \"object\" ? (config.theme as Record<string, unknown>) : {};\n const extend: Record<string, unknown> =\n theme.extend && typeof theme.extend === \"object\" ? (theme.extend as Record<string, unknown>) : {};\n\n const colors = new Set<string>();\n const spacingKeys = new Set<string>();\n const borderRadiusKeys = new Set<string>();\n const fontFamilyKeys = new Set<string>();\n const fontSizeKeys = new Set<string>();\n\n // Merge base + extend per category.\n addColorTokens(colors, theme.colors);\n addColorTokens(colors, extend.colors);\n\n addKeys(spacingKeys, theme.spacing);\n addKeys(spacingKeys, extend.spacing);\n\n addKeys(borderRadiusKeys, theme.borderRadius);\n addKeys(borderRadiusKeys, extend.borderRadius);\n\n addKeys(fontFamilyKeys, theme.fontFamily);\n addKeys(fontFamilyKeys, extend.fontFamily);\n\n addKeys(fontSizeKeys, theme.fontSize);\n addKeys(fontSizeKeys, extend.fontSize);\n\n // If user config didn’t specify tokens, we still return an object to signal\n // \"tailwind detected\", but with empty sets (downstream can choose defaults).\n return {\n configPath,\n colors: [...colors],\n spacingKeys: [...spacingKeys],\n borderRadiusKeys: [...borderRadiusKeys],\n fontFamilyKeys: [...fontFamilyKeys],\n fontSizeKeys: [...fontSizeKeys],\n };\n}\n\nfunction addKeys(out: Set<string>, obj: unknown): void {\n if (!obj || typeof obj !== \"object\") return;\n for (const key of Object.keys(obj as Record<string, unknown>)) {\n if (!key) continue;\n out.add(key);\n }\n}\n\nfunction addColorTokens(out: Set<string>, colors: unknown): void {\n if (!colors || typeof colors !== \"object\") return;\n\n for (const [name, value] of Object.entries(\n colors as Record<string, unknown>\n )) {\n if (!name) continue;\n\n if (typeof value === \"string\") {\n out.add(`tailwind:${name}`);\n continue;\n }\n\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n for (const shade of Object.keys(value as Record<string, unknown>)) {\n if (!shade) continue;\n out.add(`tailwind:${name}-${shade}`);\n }\n continue;\n }\n\n // Arrays / functions etc are ignored for token enumeration.\n }\n}\n"],"mappings":"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","names":["existsSync","dirname","join","existsSync","dirname","join","require"]}
|