Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions frontend/eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import i18next from 'eslint-plugin-i18next'
import sonarjs from 'eslint-plugin-sonarjs'
import tseslint from 'typescript-eslint'

export default tseslint.config(
Expand All @@ -17,9 +18,19 @@ export default tseslint.config(
plugins: {
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
sonarjs,
},
rules: {
...reactHooks.configs.recommended.rules,
// Sonar-class quality gates (goal 0109 phase 2b), the TS
// counterparts of .golangci.yml's dupl/gocognit: thresholds and
// enables set from a full measurement run over src/, never
// aspiration (hit lists in the goal file). no-duplicate-string
// stays OFF -- Sonar's own default posture; i18n keys and
// testids are the documented noise class.
'sonarjs/cognitive-complexity': ['error', 15],
'sonarjs/no-duplicated-branches': 'error',
'sonarjs/no-identical-functions': 'error',
// eslint-plugin-react-hooks 6.x/7.x folded the React Compiler's
// lint rules into `recommended` (goal: dependency majors sweep,
// eslint 10 + react-hooks 7.1.1). `set-state-in-effect` flags
Expand Down
121 changes: 121 additions & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"eslint-plugin-i18next": "^6.1.5",
"eslint-plugin-react-hooks": "^7.1.1",
"eslint-plugin-react-refresh": "^0.5.4",
"eslint-plugin-sonarjs": "^4.2.0",
"globals": "^17.11.0",
"typescript": "^6.0.3",
"typescript-eslint": "^8.67.0",
Expand Down
1 change: 1 addition & 0 deletions frontend/src/app/WorkTabShell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ export function WorkTabShell({ pageLabel, pageIcon, titlebarSlot, children }: {
const workflowLabel = (id: string) => workflows?.find((w) => w.ID === id)?.Label
const requestLabel = (id: string) => requests?.find((r) => r.ID === id)?.Label

// eslint-disable-next-line sonarjs/cognitive-complexity -- legacy complexity grandfathered at gate adoption; pay down when touched (goal 0109 burn-down)
const renderTab = (tab: WorkTab) => {
switch (tab.kind) {
case 'workflow-edit':
Expand Down
1 change: 1 addition & 0 deletions frontend/src/app/pageMeta.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export function pageLabelFor(view: View, capabilities: { ID: string; Label: stri
// that section (CAPABILITY_ICON), so the band's first tab matches the
// selected nav item's silhouette. Settings/placeholder views have no
// capability icon; the tab simply shows no glyph there.
// eslint-disable-next-line sonarjs/cognitive-complexity -- legacy complexity grandfathered at gate adoption; pay down when touched (goal 0109 burn-down)
export function pageIconFor(view: View): ReactNode {
const key = view.kind === 'home' ? 'capability-home'
: view.kind === 'composition' ? 'capability-composition'
Expand Down
1 change: 1 addition & 0 deletions frontend/src/atlas/atlasBuildBoardNodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export type BoardCardRFNode = AtlasNoteCardRFNode | AtlasGroupRFNode | AtlasRegi
// non-draggable preview nodes anchored inside it (parentId +
// extent:'parent') -- one nesting level deep, regardless of board
// mode; a childless card renders as a flippable note (AtlasNoteCardNode).
// eslint-disable-next-line sonarjs/cognitive-complexity -- legacy complexity grandfathered at gate adoption; pay down when touched (goal 0109 burn-down)
export function buildBoardCardNodes({
cards, allCards, kinds, links, linkKinds, isFree, readOnly, boardWidth, freeMoves, arteries,
pulsedID, hintedID, hoveredFrameID, isSoleSelected, onOpenOverlay, handleDrill,
Expand Down
1 change: 1 addition & 0 deletions frontend/src/atlas/atlasOverlapResolution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const MAX_PASSES = 24
// yesterday-clear layout can overlap today with nobody having moved a
// card -- those collisions auto-resolve. A leaf-on-leaf overlap is
// hand placement and is left exactly where the user put it.
// eslint-disable-next-line sonarjs/cognitive-complexity -- legacy complexity grandfathered at gate adoption; pay down when touched (goal 0109 burn-down)
export function resolveFreeOverlaps(boxes: OverlapBox[]): OverlapMove[] {
const work = boxes.map((b) => ({ ...b }))
// Stable processing order: by id, so the same board always nudges
Expand Down
1 change: 1 addition & 0 deletions frontend/src/atlas/useAtlasCreation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ export function useAtlasCreation({ parentID, allCards, notes, readOnly, screenTo
// identity changing when the popover opens/closes is bounded and
// never feeds the sticky-node data path that caused the React #185
// loop this file's other comments describe.
// eslint-disable-next-line sonarjs/cognitive-complexity -- legacy complexity grandfathered at gate adoption; pay down when touched (goal 0109 burn-down)
const submitPopover = useCallback((kindID: string, title: string) => {
const pending = popover
if (!pending) return
Expand Down
1 change: 1 addition & 0 deletions frontend/src/atlas/useAtlasKeyboardNav.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export function useAtlasKeyboardNav<TNode extends RFNode>({
if (e.key in ARROW_KEYS && pendingNudgeRef.current.size > 0) flushNudge()
}

// eslint-disable-next-line sonarjs/cognitive-complexity -- legacy complexity grandfathered at gate adoption; pay down when touched (goal 0109 burn-down)
const onKeyDown = (e: KeyboardEvent) => {
if (isEditableTarget(e.target)) return
if (!isFocusInsideBoard(wrapperRef)) return
Expand Down
1 change: 1 addition & 0 deletions frontend/src/composition/CanvasNodeView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ function runStatusLabelFor(t: (key: string) => string): Record<NodeRunStatus, st
// icon/color/kind text is Mill's own (KIND_ICON/KIND_ICON_BG/KIND_LABEL,
// nodeKind.ts) since Mill's node kinds are Capture/Process/Apply, not
// that reference's fuller Input/Decision/Ruleset/... taxonomy.
// eslint-disable-next-line sonarjs/cognitive-complexity -- legacy complexity grandfathered at gate adoption; pay down when touched (goal 0109 burn-down)
export function CanvasNodeView({ id, data, selected }: NodeProps<CanvasNode>) {
const { t } = useTranslation('composition')
const RUN_STATUS_LABEL = runStatusLabelFor(t)
Expand Down
1 change: 1 addition & 0 deletions frontend/src/composition/NodeConfigFields.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ export function NodeConfigFields({ node, workflowId, attrs, nodeType, sameKindNo
// decisions 4-5), not a raw number field a user has to already
// know.
.filter((field) => !(node.data.nodeTypeID === 'decision-outcome' && field.Key === 'version'))
// eslint-disable-next-line sonarjs/cognitive-complexity -- legacy complexity grandfathered at gate adoption; pay down when touched (goal 0109 burn-down)
.map((field) => (
<FormControl key={`${field.Key}-${payloadNonce}`}>
<FormControl.Label>{field.Label}</FormControl.Label>
Expand Down
1 change: 1 addition & 0 deletions frontend/src/composition/TriggerRowLabel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ interface TriggerRowLabelProps {
// node's real type and config instead of a second, independent guess at
// the same thing. Shared by WorkflowsTable.tsx and CompositionView.tsx's
// InventoryList rows (docs/goals/0007, the former WorkflowsCards.tsx).
// eslint-disable-next-line sonarjs/cognitive-complexity -- legacy complexity grandfathered at gate adoption; pay down when touched (goal 0109 burn-down)
export function TriggerRowLabel({ workflow, armed, publishing, onPublish, onHotkeyChanged }: TriggerRowLabelProps) {
const { t } = useTranslation('composition')
const rootNode = findRootNode(workflow.Nodes, workflow.Edges)
Expand Down
1 change: 1 addition & 0 deletions frontend/src/composition/WorkflowRunsPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@ function WorkflowRunsPanel({ workflowId, attrs, initialRunId, onInitialRunConsum
</Stack>
{detail.error && <Text as="p" className={styles.error}>{detail.error}</Text>}

{/* eslint-disable-next-line sonarjs/cognitive-complexity -- legacy complexity grandfathered at gate adoption; pay down when touched (goal 0109 burn-down) */}
{detail.pending && (() => {
// A breakpoint or step-mode park is a DEBUG park
// (docs/adr/0031) -- distinct icon/wording/controls, never
Expand Down
1 change: 1 addition & 0 deletions frontend/src/configure/openapiSynth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ function fieldFromSchema(name: string, schema: JSONSchemaLike, placement: Manual
// non-JSON media types are silently skipped rather than guessed at.
// JSON only (no YAML) -- this runs in the browser with no YAML parser
// adopted for it; paste JSON, or keep editing via the raw-text mode.
// eslint-disable-next-line sonarjs/cognitive-complexity -- legacy complexity grandfathered at gate adoption; pay down when touched (goal 0109 burn-down)
export function parseOpenAPIToOperations(t: (key: string, opts?: Record<string, unknown>) => string, specText: string): { operations: ManualOperation[]; errors: string[] } {
let doc: { paths?: Record<string, Record<string, unknown>> }
try {
Expand Down
Loading