> ## Documentation Index
> Fetch the complete documentation index at: https://docs.endorlabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Working with dependency filters

> Learn how to implement and use dependency filters to search, prioritize, and manage dependencies across your organization.

export const DependencyFilterBuilder = () => {
  const COPY_FEEDBACK_MS = 2000;
  const DELETE_ICON_PX = 16;
  const PLACEHOLDER_PREVIEW = 'Enter a condition to generate a filter...';
  const nextIdRef = useRef(1);
  const makeRowId = () => {
    nextIdRef.current += 1;
    return 'dfb-row-' + String(nextIdRef.current);
  };
  const [rows, setRows] = useState([{
    id: 'dfb-row-1',
    field: '',
    operator: '',
    value: ''
  }]);
  const [copied, setCopied] = useState(false);
  const [isDark, setIsDark] = useState(false);
  useEffect(() => {
    const check = () => {
      const root = document.documentElement;
      setIsDark(root.dataset.theme === 'dark' || root.classList.contains('dark'));
    };
    check();
    const observer = new MutationObserver(check);
    observer.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ['data-theme', 'class']
    });
    return () => observer.disconnect();
  }, []);
  const ENUMS = {
    ecosystem: [{
      value: 'ECOSYSTEM_C',
      label: 'C/C++'
    }, {
      value: 'ECOSYSTEM_CARGO',
      label: 'Cargo'
    }, {
      value: 'ECOSYSTEM_COCOAPOD',
      label: 'CocoaPods'
    }, {
      value: 'ECOSYSTEM_CONAN',
      label: 'Conan'
    }, {
      value: 'ECOSYSTEM_CONTAINER',
      label: 'Container'
    }, {
      value: 'ECOSYSTEM_GEM',
      label: 'RubyGems'
    }, {
      value: 'ECOSYSTEM_GITHUB_ACTION',
      label: 'GitHub Action'
    }, {
      value: 'ECOSYSTEM_GO',
      label: 'Go'
    }, {
      value: 'ECOSYSTEM_HUGGING_FACE',
      label: 'Hugging Face'
    }, {
      value: 'ECOSYSTEM_MAVEN',
      label: 'Maven'
    }, {
      value: 'ECOSYSTEM_NPM',
      label: 'npm'
    }, {
      value: 'ECOSYSTEM_NUGET',
      label: 'NuGet'
    }, {
      value: 'ECOSYSTEM_PACKAGIST',
      label: 'Packagist'
    }, {
      value: 'ECOSYSTEM_PYPI',
      label: 'PyPI'
    }, {
      value: 'ECOSYSTEM_SWIFT',
      label: 'Swift'
    }],
    reachability: [{
      value: 'REACHABILITY_TYPE_REACHABLE',
      label: 'Reachable'
    }, {
      value: 'REACHABILITY_TYPE_UNREACHABLE',
      label: 'Unreachable'
    }, {
      value: 'REACHABILITY_TYPE_UNKNOWN',
      label: 'Potentially Reachable'
    }],
    scope: [{
      value: 'DEPENDENCY_SCOPE_NORMAL',
      label: 'Normal'
    }, {
      value: 'DEPENDENCY_SCOPE_TEST',
      label: 'Test'
    }, {
      value: 'DEPENDENCY_SCOPE_BUILD',
      label: 'Build'
    }],
    discoveryType: [{
      value: 'DISCOVERY_TYPE_MANIFEST',
      label: 'Manifest'
    }, {
      value: 'DISCOVERY_TYPE_PHANTOM',
      label: 'Phantom'
    }, {
      value: 'DISCOVERY_TYPE_SEGMENT_MATCH',
      label: 'Segment Match'
    }]
  };
  const OPERATOR_SETS = {
    string: [{
      value: '==',
      label: 'equals'
    }, {
      value: '!=',
      label: 'not equals'
    }, {
      value: 'in',
      label: 'in'
    }, {
      value: 'matches',
      label: 'matches'
    }],
    numeric: [{
      value: '==',
      label: 'equals'
    }, {
      value: '!=',
      label: 'not equals'
    }, {
      value: '>',
      label: 'greater than'
    }, {
      value: '>=',
      label: 'greater or equal'
    }, {
      value: '<',
      label: 'less than'
    }, {
      value: '<=',
      label: 'less or equal'
    }],
    boolean: [{
      value: '==',
      label: 'equals'
    }, {
      value: '!=',
      label: 'not equals'
    }],
    enum: [{
      value: '==',
      label: 'equals'
    }, {
      value: '!=',
      label: 'not equals'
    }, {
      value: 'in',
      label: 'in'
    }, {
      value: 'not in',
      label: 'not in'
    }],
    timestamp: [{
      value: '==',
      label: 'equals'
    }, {
      value: '!=',
      label: 'not equals'
    }, {
      value: '>',
      label: 'after'
    }, {
      value: '>=',
      label: 'on or after'
    }, {
      value: '<',
      label: 'before'
    }, {
      value: '<=',
      label: 'on or before'
    }]
  };
  const FIELDS = [{
    value: 'meta.name',
    label: 'Dependency Name',
    type: 'string',
    description: 'Filters by the dependency package version name in the format ecosystem://package@version.'
  }, {
    value: 'meta.parent_uuid',
    label: 'Parent UUID',
    type: 'string',
    description: 'Filters by the root package version UUID that declares or pulls in the dependency.'
  }, {
    value: 'spec.importer_data.project_uuid',
    label: 'Importing Project UUID',
    type: 'string',
    description: 'Filters by the project that contains the dependency. Use to list all dependencies for a given project.'
  }, {
    value: 'spec.importer_data.package_version_uuid',
    label: 'Importing Package Version UUID',
    type: 'string',
    description: 'Filters by the root package version that declares or pulls in the dependency.'
  }, {
    value: 'spec.importer_data.package_name',
    label: 'Importing Package Name',
    type: 'string',
    description: 'Filters by the qualified name of the importing package, without version.'
  }, {
    value: 'spec.importer_data.package_version_name',
    label: 'Importing Package Version Name',
    type: 'string',
    description: 'Filters by the fully qualified name of the root package version.'
  }, {
    value: 'spec.importer_data.callgraph_available',
    label: 'Call Graph Available',
    type: 'boolean',
    description: 'Filters by whether a call graph is available for the root package version.'
  }, {
    value: 'spec.dependency_data.ecosystem',
    label: 'Ecosystem',
    type: 'enum',
    enumKey: 'ecosystem',
    description: 'Filters by dependency ecosystem, such as npm, Maven, or PyPI.'
  }, {
    value: 'spec.dependency_data.scope',
    label: 'Dependency Scope',
    type: 'enum',
    enumKey: 'scope',
    description: 'Filters by dependency scope: Normal, Test, or Build.'
  }, {
    value: 'spec.dependency_data.discovery_type',
    label: 'Discovery Type',
    type: 'enum',
    enumKey: 'discoveryType',
    description: 'Filters by discovery method: manifest, phantom, or segment match.'
  }, {
    value: 'spec.dependency_data.reachable',
    label: 'Reachability',
    type: 'enum',
    enumKey: 'reachability',
    description: 'Filters by reachability status: reachable, potentially reachable, or unreachable.'
  }, {
    value: 'spec.dependency_data.direct',
    label: 'Direct',
    type: 'boolean',
    description: 'Filters by whether the dependency is direct or transitive.'
  }, {
    value: 'spec.dependency_data.public',
    label: 'Public',
    type: 'boolean',
    description: 'Filters by whether the dependency is from a public or private source.'
  }, {
    value: 'spec.dependency_data.vendored',
    label: 'Vendored',
    type: 'boolean',
    description: 'Filters by whether the dependency is vendored or embedded in your repository.'
  }, {
    value: 'spec.dependency_data.approximation',
    label: 'Approximation',
    type: 'boolean',
    description: 'Filters by whether the dependency is approximate (estimated from unresolved dependency data).'
  }, {
    value: 'spec.dependency_data.pinned',
    label: 'Pinned',
    type: 'boolean',
    description: 'Filters by whether the dependency version is pinned.'
  }, {
    value: 'spec.dependency_data.patched',
    label: 'Patched',
    type: 'boolean',
    description: 'Filters by whether the dependency version has a patch.'
  }, {
    value: 'spec.dependency_data.eol',
    label: 'End-of-Life',
    type: 'boolean',
    description: 'Filters by whether the dependency is end-of-life.'
  }, {
    value: 'spec.dependency_data.last_commit',
    label: 'Last Commit',
    type: 'timestamp',
    description: 'Filters by the date of the last commit or modification in the dependency version.'
  }, {
    value: 'spec.dependency_data.eol_timestamp',
    label: 'End-of-Life Date',
    type: 'timestamp',
    description: 'Filters by the end-of-life timestamp of the dependency package version.'
  }, {
    value: 'spec.dependency_data.parent_count',
    label: 'Parent Count',
    type: 'numeric',
    description: 'Filters by the number of direct parents of the dependency in the dependency graph.'
  }, {
    value: 'spec.dependency_data.namespace',
    label: 'Namespace',
    type: 'string',
    description: 'Filters by the namespace to which the dependency package version belongs.'
  }, {
    value: 'spec.dependency_data.package_name',
    label: 'Dependency Package Name',
    type: 'string',
    description: 'Filters by the qualified dependency package name.'
  }, {
    value: 'spec.dependency_data.project_uuid',
    label: 'Dependency Project UUID',
    type: 'string',
    description: 'Filters by the project UUID to which the dependency package version belongs.'
  }, {
    value: 'spec.dependency_data.package_version_uuid',
    label: 'Dependency Package Version UUID',
    type: 'string',
    description: 'Filters by the UUID of the dependency package version object.'
  }];
  const STRING_QUOTE_FIELDS = new Set(FIELDS.filter(f => f.type === 'string').map(f => f.value));
  const TIMESTAMP_FIELDS = new Set(FIELDS.filter(f => f.type === 'timestamp').map(f => f.value));
  const ENUM_FIELDS = new Set(FIELDS.filter(f => f.type === 'enum').map(f => f.value));
  const resolveFieldDef = fieldValue => FIELDS.find(f => f.value === fieldValue);
  const operatorsForFieldDef = fieldDef => {
    if (!fieldDef) {
      return OPERATOR_SETS.string;
    }
    const key = (fieldDef.type in OPERATOR_SETS) ? fieldDef.type : 'string';
    return OPERATOR_SETS[key];
  };
  const valueKindForRow = fieldDef => {
    if (!fieldDef) {
      return 'text';
    }
    if (fieldDef.type === 'boolean') {
      return 'boolean';
    }
    if (fieldDef.type === 'enum') {
      return 'enum';
    }
    return 'text';
  };
  const formatPreviewValue = (field, operator, raw) => {
    const out = raw.trim();
    if (!out) {
      return '';
    }
    if (TIMESTAMP_FIELDS.has(field)) {
      if (out.startsWith('-') || out.startsWith('+')) {
        return 'now(' + out + ')';
      }
      if ((/^\d{4}-\d{2}-\d{2}/).test(out)) {
        return 'date(' + out + ')';
      }
      return out;
    }
    if (ENUM_FIELDS.has(field)) {
      if ((operator === 'in' || operator === 'not in') && !out.startsWith('[')) {
        return '[' + out + ']';
      }
      return out;
    }
    if (STRING_QUOTE_FIELDS.has(field) && !out.startsWith('"')) {
      return '"' + out + '"';
    }
    return out;
  };
  const computePreview = () => {
    const fieldGroups = {};
    for (const row of rows) {
      const {field, operator, value} = row;
      const trimmed = typeof value === 'string' ? value.trim() : '';
      if (!field || !operator || !trimmed) {
        continue;
      }
      const formatted = formatPreviewValue(field, operator, trimmed);
      if (!formatted) {
        continue;
      }
      const clause = field + ' ' + operator + ' ' + formatted;
      if (!fieldGroups[field]) {
        fieldGroups[field] = [];
      }
      fieldGroups[field].push(clause);
    }
    const keys = Object.keys(fieldGroups);
    if (keys.length === 0) {
      return PLACEHOLDER_PREVIEW;
    }
    const parts = keys.map(field => {
      const groupConditions = fieldGroups[field];
      if (groupConditions.length > 1) {
        return '(' + groupConditions.join(' or ') + ')';
      }
      return groupConditions[0];
    });
    return parts.join(' and ');
  };
  const previewText = computePreview();
  const updateRow = (id, patch) => {
    setRows(prev => prev.map(r => r.id === id ? {
      ...r,
      ...patch
    } : r));
  };
  const handleFieldChange = (id, fieldValue) => {
    updateRow(id, {
      field: fieldValue,
      operator: '',
      value: ''
    });
  };
  const handleAddRow = () => {
    setRows(prev => [...prev, {
      id: makeRowId(),
      field: '',
      operator: '',
      value: ''
    }]);
  };
  const handleRemoveRow = id => {
    setRows(prev => {
      if (prev.length <= 1) {
        return prev;
      }
      return prev.filter(r => r.id !== id);
    });
  };
  const handleCopy = () => {
    if (!previewText || previewText === PLACEHOLDER_PREVIEW) {
      return;
    }
    const markCopied = () => {
      setCopied(true);
      setTimeout(() => setCopied(false), COPY_FEEDBACK_MS);
    };
    try {
      navigator.clipboard.writeText(previewText).then(markCopied).catch(() => {
        globalThis.alert('Unable to copy. Select the expression and copy it manually.');
      });
    } catch {
      globalThis.alert('Unable to copy. Select the expression and copy it manually.');
    }
  };
  const bgMain = isDark ? '#1e1e1e' : '#ffffff';
  const bgSection = isDark ? '#161b22' : '#ffffff';
  const textColor = isDark ? '#e6edf3' : '#111827';
  const mutedColor = isDark ? 'rgba(230,237,243,0.75)' : '#6b7280';
  const labelSectionColor = isDark ? '#e6edf3' : '#4b5563';
  const inputBg = isDark ? '#0d1117' : '#ffffff';
  const MINT_BORDER_LIGHT = '#a8e6cf';
  const borderOuter = isDark ? 'rgba(38, 208, 124, 0.35)' : MINT_BORDER_LIGHT;
  const borderInput = isDark ? 'rgba(38, 208, 124, 0.35)' : '#d1d5db';
  const borderSection = isDark ? 'rgba(38, 208, 124, 0.2)' : MINT_BORDER_LIGHT;
  const accentMint = isDark ? 'rgba(38, 208, 124, 0.85)' : '#5cb896';
  const accentMintBorder = isDark ? 'rgba(38, 208, 124, 0.5)' : MINT_BORDER_LIGHT;
  const copyIconColor = isDark ? 'rgba(38, 208, 124, 0.9)' : '#22c55e';
  const containerStyle = {
    background: bgMain,
    border: '1px solid ' + borderOuter,
    borderRadius: '16px',
    padding: '1.25rem',
    margin: '1rem 0',
    fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
    boxShadow: 'none',
    color: textColor
  };
  const sectionStyle = {
    marginBottom: '0.75rem',
    background: bgSection,
    borderRadius: '12px',
    padding: '0.75rem',
    border: '1px solid ' + borderSection
  };
  const labelStyle = {
    display: 'block',
    fontWeight: 500,
    marginBottom: '0.35rem',
    color: labelSectionColor,
    fontSize: '0.8rem',
    textTransform: 'uppercase',
    letterSpacing: '0.5px'
  };
  const controlStyle = {
    width: '100%',
    padding: '0.5rem 0.75rem',
    border: '1px solid ' + borderInput,
    borderRadius: '8px',
    fontSize: '0.85rem',
    background: inputBg,
    color: textColor,
    cursor: 'pointer',
    boxSizing: 'border-box',
    outline: 'none'
  };
  const rowWrapStyle = {
    marginBottom: '0.6rem'
  };
  const rowStyle = {
    display: 'flex',
    gap: '0.4rem',
    alignItems: 'center',
    flexWrap: 'wrap'
  };
  const rowDescriptionStyle = {
    margin: '0.25rem 0 0',
    paddingLeft: '0.15rem',
    fontSize: '0.75rem',
    lineHeight: 1.4,
    color: mutedColor,
    fontStyle: 'italic'
  };
  const previewBoxStyle = {
    position: 'relative',
    background: inputBg,
    border: '1px solid ' + borderSection,
    borderRadius: '8px',
    padding: '0.75rem',
    paddingRight: '2.75rem',
    marginTop: '0.5rem'
  };
  const preStyle = {
    margin: 0,
    whiteSpace: 'pre-wrap',
    wordBreak: 'break-all',
    fontFamily: 'Monaco, Menlo, Ubuntu Mono, monospace',
    fontSize: '0.8rem',
    lineHeight: 1.4,
    color: isDark ? textColor : '#374151'
  };
  const btnPrimaryOutline = {
    padding: '0.25rem 0.5rem',
    fontSize: '0.75rem',
    fontWeight: 500,
    borderRadius: '8px',
    cursor: 'pointer',
    border: '1px solid ' + accentMintBorder,
    background: 'transparent',
    color: accentMint
  };
  const btnDangerOutline = {
    display: 'inline-flex',
    alignItems: 'center',
    justifyContent: 'center',
    padding: '0.35rem',
    minWidth: '2rem',
    minHeight: '2rem',
    borderRadius: '8px',
    cursor: 'pointer',
    border: '1px solid rgba(220, 53, 69, 0.45)',
    background: 'transparent',
    color: '#f85149'
  };
  const btnCopyStyle = {
    position: 'absolute',
    top: '0.5rem',
    right: '0.5rem',
    background: 'transparent',
    border: 'none',
    color: copyIconColor,
    cursor: 'pointer',
    padding: '0.25rem',
    fontSize: '0.85rem'
  };
  const renderEnumSelect = (row, fieldDef) => {
    const key = fieldDef.enumKey;
    const opts = ENUMS[key] || [];
    return <select aria-label="Filter value" className="dfb-value dfb-control" style={{
      ...controlStyle,
      flex: 1,
      minWidth: '140px'
    }} value={row.value} disabled={!row.operator} onChange={e => updateRow(row.id, {
      value: e.target.value
    })}>
        <option value="">Select value…</option>
        {opts.map(o => <option key={o.value} value={o.value}>
            {o.label}
          </option>)}
      </select>;
  };
  const renderBooleanSelect = row => <select aria-label="Filter value" className="dfb-value dfb-control" style={{
    ...controlStyle,
    flex: 1,
    minWidth: '100px'
  }} value={row.value} disabled={!row.operator} onChange={e => updateRow(row.id, {
    value: e.target.value
  })}>
      <option value="">Select value…</option>
      <option value="true">true</option>
      <option value="false">false</option>
    </select>;
  const renderValueControl = (row, fieldDef) => {
    const kind = valueKindForRow(fieldDef);
    if (kind === 'boolean') {
      return renderBooleanSelect(row);
    }
    if (kind === 'enum') {
      return renderEnumSelect(row, fieldDef);
    }
    const isTimestamp = fieldDef && fieldDef.type === 'timestamp';
    const placeholder = isTimestamp ? 'e.g. -168h or date(2024-01-01)' : 'Value';
    return <input type="text" aria-label="Filter value" className="dfb-value dfb-control" style={{
      ...controlStyle,
      flex: 1,
      minWidth: '120px'
    }} placeholder={placeholder} value={row.value} disabled={!row.operator} onChange={e => updateRow(row.id, {
      value: e.target.value
    })} />;
  };
  const renderRow = row => {
    const fieldDef = resolveFieldDef(row.field);
    const opList = operatorsForFieldDef(fieldDef);
    const showRemove = rows.length > 1;
    return <div key={row.id} style={rowWrapStyle}>
        <div style={rowStyle}>
          <select aria-label="Filter attribute" className="dfb-control" style={{
      ...controlStyle,
      flex: '2 1 180px',
      minWidth: '160px'
    }} value={row.field} onChange={e => handleFieldChange(row.id, e.target.value)}>
            <option value="">Select attribute…</option>
            {FIELDS.map(f => <option key={f.value} value={f.value} title={f.description}>
                {f.label}
              </option>)}
          </select>

          <select aria-label="Filter operator" className="dfb-control" style={{
      ...controlStyle,
      flex: '0.9 1 100px',
      minWidth: '120px'
    }} value={row.operator} onChange={e => updateRow(row.id, {
      operator: e.target.value
    })} disabled={!row.field}>
            <option value="">Select operator…</option>
            {opList.map(op => <option key={op.value} value={op.value}>
                {op.label}
              </option>)}
          </select>

          {renderValueControl(row, fieldDef)}

          {showRemove ? <button type="button" style={btnDangerOutline} onClick={() => handleRemoveRow(row.id)} aria-label="Remove condition" title="Remove condition">
              <svg xmlns="http://www.w3.org/2000/svg" width={DELETE_ICON_PX} height={DELETE_ICON_PX} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
                <polyline points="3 6 5 6 21 6" />
                <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
                <line x1="10" y1="11" x2="10" y2="17" />
                <line x1="14" y1="11" x2="14" y2="17" />
              </svg>
            </button> : null}
        </div>
        {fieldDef && fieldDef.description ? <div style={rowDescriptionStyle}>{fieldDef.description}</div> : null}
      </div>;
  };
  const dfbThemeClass = isDark ? 'dfb-dark' : 'dfb-light';
  return <div className={'not-prose dependency-filter-builder ' + dfbThemeClass} style={containerStyle}>
      <style>
        {`
          .dependency-filter-builder.dfb-light input.dfb-value::placeholder {
            color: #9ca3af;
          }
          .dependency-filter-builder.dfb-dark input.dfb-value::placeholder {
            color: rgba(230, 237, 243, 0.45);
          }
          .dependency-filter-builder.dfb-light select option {
            color: #111827;
            background: #f3f4f6;
          }
          .dependency-filter-builder.dfb-dark select option {
            color: #e6edf3;
            background: #161b22;
          }
          .dependency-filter-builder.dfb-light .dfb-control:focus {
            border-color: #a8e6cf;
            box-shadow: 0 0 0 2px rgba(168, 230, 207, 0.45);
          }
          .dependency-filter-builder.dfb-dark .dfb-control:focus {
            border-color: rgba(38, 208, 124, 0.55);
            box-shadow: 0 0 0 2px rgba(38, 208, 124, 0.2);
          }
          .dependency-filter-builder .dfb-control:disabled {
            opacity: 0.55;
            cursor: not-allowed;
          }
        `}
      </style>
      <div style={{
    marginBottom: '1rem'
  }}>
        <h3 style={{
    color: textColor,
    margin: '0 0 0.25rem',
    fontWeight: 600,
    fontSize: '1.1rem'
  }}>
          Dependency Filter Builder
        </h3>
        <p style={{
    color: mutedColor,
    margin: 0,
    fontSize: '0.85rem',
    lineHeight: 1.4
  }}>
          Construct advanced dependency filters using the API-style syntax.
        </p>
      </div>

      <div style={sectionStyle}>
        <div style={{
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'space-between',
    marginBottom: '0.5rem',
    flexWrap: 'wrap',
    gap: '0.5rem'
  }}>
          <span style={{
    ...labelStyle,
    marginBottom: 0
  }}>Build your filter</span>
          <button type="button" style={btnPrimaryOutline} onClick={handleAddRow}>
            + Add condition
          </button>
        </div>
        <div>{rows.map(row => renderRow(row))}</div>
      </div>

      <div style={sectionStyle}>
        <span style={labelStyle}>Generated filter expression</span>
        <div style={previewBoxStyle}>
          <pre style={preStyle}>{previewText}</pre>
          <button type="button" style={btnCopyStyle} onClick={handleCopy} aria-label={copied ? 'Copied' : 'Copy filter expression to clipboard'} title="Copy to clipboard">
            {copied ? 'Copied' : 'Copy'}
          </button>
        </div>
        <p style={{
    fontSize: '0.8rem',
    color: mutedColor,
    margin: '0.5rem 0 0'
  }}>
          Copy this expression and paste it into the{' '}
          <strong style={{
    color: textColor
  }}>Advanced Filter</strong> box in the Dependencies UI.
        </p>
      </div>
    </div>;
};

export const YamlTable = ({children, data: propData, content}) => {
  const KV_RE = /^([A-Za-z][A-Za-z0-9_()/#\s-]+?):\s*(.+)$/;
  const INLINE_MD_RE = /(\[([^\]]+)\]\(([^)]+)\))|(`([^`]+)`)|(\*\*([^*]+)\*\*)|(\*([^*]+)\*)/g;
  const YES_RE = /^-yes-$/i;
  const NO_RE = /^-no-$/i;
  const LIMITED_RE = /^-(limited|partial)-$/i;
  const NA_RE = /^-(na|none)-$/i;
  const NA2_RE = /^-na2-$/i;
  const SIMPLE_TAG_RE = /(<br\s*\/?>)|(<p\s*\/?>)|(-note-)|(-warning-)/gi;
  const tryParseKV = trimmed => {
    const m = KV_RE.exec(trimmed);
    return m ? {
      key: m[1],
      value: m[2].trim()
    } : null;
  };
  const registerKey = (key, seenKeys, orderedKeys) => {
    if (!seenKeys.has(key)) {
      orderedKeys.push(key);
      seenKeys.add(key);
    }
  };
  const flushEntry = (currentEntry, entries) => {
    if (Object.keys(currentEntry).length > 0) entries.push(currentEntry);
  };
  const parseDashPrefixed = (lines, entries, orderedKeys, seenKeys) => {
    let currentEntry = {};
    let inEntry = false;
    for (const line of lines) {
      const trimmed = line.trim();
      if (trimmed.startsWith('- ')) {
        if (inEntry) entries.push(currentEntry);
        currentEntry = {};
        inEntry = true;
        const kv = tryParseKV(trimmed.substring(2).trim());
        if (kv) {
          registerKey(kv.key, seenKeys, orderedKeys);
          currentEntry[kv.key] = kv.value;
        }
      } else if (inEntry && trimmed !== '') {
        const kv = tryParseKV(trimmed);
        if (kv) {
          registerKey(kv.key, seenKeys, orderedKeys);
          currentEntry[kv.key] = kv.value;
        }
      }
    }
    flushEntry(currentEntry, entries);
  };
  const parseBlankSeparated = (lines, entries, orderedKeys, seenKeys) => {
    let currentEntry = {};
    let inEntry = false;
    for (const line of lines) {
      const trimmed = line.trim();
      if (trimmed === '') {
        if (inEntry) {
          flushEntry(currentEntry, entries);
          currentEntry = {};
          inEntry = false;
        }
        continue;
      }
      const kv = tryParseKV(trimmed);
      if (!kv) continue;
      const isNewEntry = !line.startsWith(' ') && !line.startsWith('\t');
      if (isNewEntry && inEntry && Object.keys(currentEntry).length > 0) {
        entries.push(currentEntry);
        currentEntry = {};
      }
      registerKey(kv.key, seenKeys, orderedKeys);
      currentEntry[kv.key] = kv.value;
      inEntry = true;
    }
    flushEntry(currentEntry, entries);
  };
  const normalizeEntries = (entries, orderedKeys) => entries.map(entry => {
    const filled = {};
    for (const key of orderedKeys) filled[key] = entry[key] || '';
    return filled;
  });
  const parseYamlTableContent = contentStr => {
    if (!contentStr) return [];
    const entries = [];
    const orderedKeys = [];
    const seenKeys = new Set();
    const lines = contentStr.split('\n');
    if (lines.some(line => line.trim().startsWith('- '))) {
      parseDashPrefixed(lines, entries, orderedKeys, seenKeys);
    } else {
      parseBlankSeparated(lines, entries, orderedKeys, seenKeys);
    }
    return normalizeEntries(entries, orderedKeys);
  };
  const processText = text => {
    if (!text) return text;
    const parts = [];
    let keyIndex = 0;
    let lastIndex = 0;
    let match;
    while ((match = INLINE_MD_RE.exec(text)) !== null) {
      if (match.index > lastIndex) parts.push(text.slice(lastIndex, match.index));
      if (match[1]) {
        parts.push(<a key={keyIndex++} href={match[3]}>{match[2]}</a>);
      } else if (match[4]) {
        parts.push(<code key={keyIndex++}>{match[5]}</code>);
      } else if (match[6]) {
        parts.push(<strong key={keyIndex++}>{match[7]}</strong>);
      } else if (match[8]) {
        parts.push(<em key={keyIndex++}>{match[9]}</em>);
      }
      lastIndex = match.index + match[0].length;
    }
    if (lastIndex < text.length) parts.push(text.slice(lastIndex));
    if (parts.length === 0) return text;
    const keyRef = {
      current: keyIndex
    };
    return expandHtmlTags(parts, keyRef);
  };
  const processBadges = text => {
    if (!text || typeof text !== 'string') return text;
    if (YES_RE.test(text)) return <span className="yt-badge-yes" role="img" aria-label="Supported" title="Supported">✓</span>;
    if (NO_RE.test(text)) return <span className="yt-badge-no" role="img" aria-label="Not supported" title="Not supported">✗</span>;
    if (LIMITED_RE.test(text)) return <span className="yt-badge-limited" role="img" aria-label="Partially supported" title="Partially supported">◐</span>;
    if (NA_RE.test(text) || NA2_RE.test(text)) return <span className="yt-sr-only" title="Not applicable">Not applicable</span>;
    return processText(text);
  };
  const cellClassName = text => {
    if (!text || typeof text !== 'string') return undefined;
    if (NA_RE.test(text)) return 'yt-cell-na';
    if (NA2_RE.test(text)) return 'yt-cell-na2';
    return undefined;
  };
  const expandSimpleTags = (str, keyRef) => {
    const result = [];
    let last = 0;
    SIMPLE_TAG_RE.lastIndex = 0;
    let m;
    while ((m = SIMPLE_TAG_RE.exec(str)) !== null) {
      if (m.index > last) result.push(str.slice(last, m.index));
      if (m[1]) {
        result.push(<br key={keyRef.current++} />);
      } else if (m[2]) {
        result.push(<br key={keyRef.current++} />, <br key={keyRef.current++} />);
      } else if (m[3]) {
        result.push(<span key={keyRef.current++} className="yt-badge-note" style={{
          fontWeight: 600
        }}>Note: </span>);
      } else if (m[4]) {
        result.push(<span key={keyRef.current++} className="yt-badge-warning" style={{
          fontWeight: 600
        }}>Warning: </span>);
      }
      last = m.index + m[0].length;
    }
    if (last < str.length) result.push(str.slice(last));
    return result;
  };
  const expandHtmlTags = (chunks, keyRef) => {
    const out = [];
    for (const chunk of chunks) {
      if (typeof chunk === 'string') {
        out.push(...expandSimpleTags(chunk, keyRef));
      } else {
        out.push(chunk);
      }
    }
    return out;
  };
  const extractText = node => {
    if (node === null || node === undefined) return '';
    if (typeof node === 'string') return node;
    if (typeof node === 'number') return String(node);
    if (typeof node === 'boolean') return '';
    if (Array.isArray(node)) return node.map(extractText).join('');
    if (node && typeof node === 'object' && node.type) {
      const props = node.props || ({});
      if (typeof props.children === 'string') return props.children;
      if (props.children) return extractText(props.children);
      return '';
    }
    return String(node || '');
  };
  const [mounted, setMounted] = useState(false);
  useEffect(() => {
    setMounted(true);
  }, []);
  const data = useMemo(() => {
    if (propData) return propData;
    if (content && typeof content === 'string') return parseYamlTableContent(content);
    if (!children) return [];
    if (typeof children === 'string') return parseYamlTableContent(children);
    const childrenArray = Array.isArray(children) ? children : [children];
    return parseYamlTableContent(childrenArray.map(extractText).join('').trim());
  }, [children, propData, content]);
  const columns = useMemo(() => {
    if (!data || data.length === 0) return [];
    const firstRow = data[0];
    if (!firstRow || typeof firstRow !== 'object') return [];
    return Object.keys(firstRow);
  }, [data]);
  if (!mounted) return null;
  if (!data || data.length === 0) return null;
  const rowKey = row => columns.map(c => row[c] || '').join('|');
  return <table>
      <thead>
        <tr>
          {columns.map(col => <th key={col}>{col.replaceAll('_', ' ')}</th>)}
        </tr>
      </thead>
      <tbody>
        {data.map(row => <tr key={rowKey(row)}>
            {columns.map(col => <td key={col} className={cellClassName(row[col])}>{processBadges(row[col])}</td>)}
          </tr>)}
      </tbody>
    </table>;
};

Filters enable targeted queries on dependencies based on attributes such as ecosystem, reachability, direct versus transitive usage, discovery type, approximate resolution, severity, and Endor scores.

This guide explains how dependency filters work, how to apply and combine them effectively, and provides practical examples to support triage, audit, and reporting workflows across your dependency inventory.

## How filters work

Each filter consists of three parts.

* **Key**: The attribute you want to filter (for example, `Ecosystems`, `Dependency Reachability`, and `Direct`).
* **Operator**: The comparison logic (for example, `equals`, `in`, and `greater than` ).
* **Value**: The target value to evaluate (for example, `Maven` and `Yes`).

Dependency filters use standard comparison operators to evaluate criteria. See [Filter operators](/developers-api/rest-api/using-the-rest-api/filters#operators) for detailed information about available operators and their usage when using the API.

When you apply multiple filters, the system combines them using logical AND operations across filters for different fields and logical OR operations across filters for the same field.

For example:

* **Filter 1**: `Ecosystems in: npm`
* **Filter 2**: `Dependency Reachability: Potentially Reachable`
* **Filter 3**: `Direct: Yes`
* **Filter 4**: `Dependency Scopes: Normal`

<img src="https://mintcdn.com/endorlabs-b4795f4f/deISr2DfATZg293W/images/best-practices/dependency-filters/dependency-filters/multiple-filters.webp?fit=max&auto=format&n=deISr2DfATZg293W&q=85&s=7d5a8739a63be8afb5e87c823ac1bd8f" alt="Multiple dependency filters applied" style={{width: '80%'}} width="2580" height="1095" data-path="images/best-practices/dependency-filters/dependency-filters/multiple-filters.webp" />

This combination returns only dependencies that are in the npm ecosystem, potentially reachable in your code, direct, and have normal scope.

## Filter implementation techniques

You can use the following filter types to manage your dependencies effectively.

* [Preset filters](#preset-filters): Use the filter bar in the Endor Labs user interface to quickly segment dependencies by common attributes.
* [Filter dependencies using API](#filter-dependencies-using-api): Use the REST API or endorctl for complex queries and logical combinations.

### Preset filters

The following examples demonstrate how to apply preset filters for common dependency scenarios.

#### Filter dependencies by project

Use the **Projects** filter to show only dependencies used by one or more selected projects. You can search by project name or tags, and click **Add Filter**.

For example, to view only dependencies used by a specific application, search by project name or tags

<img src="https://mintcdn.com/endorlabs-b4795f4f/deISr2DfATZg293W/images/best-practices/dependency-filters/dependency-filters/filter-project-name.webp?fit=max&auto=format&n=deISr2DfATZg293W&q=85&s=f07c36343f921894a4bae6247b102e64" alt="Filter by project" style={{width: '80%'}} width="2580" height="825" data-path="images/best-practices/dependency-filters/dependency-filters/filter-project-name.webp" />

#### Filter dependencies by ecosystem

Use the **Ecosystems** filter to segment dependencies by package manager or language for targeted security policies, license compliance, or ecosystem-specific upgrade campaigns.

For example, to focus on Maven dependencies for a Java security assessment, use the `Ecosystems in: Maven` filter.

<img src="https://mintcdn.com/endorlabs-b4795f4f/deISr2DfATZg293W/images/best-practices/dependency-filters/dependency-filters/filter-ecosystem.webp?fit=max&auto=format&n=deISr2DfATZg293W&q=85&s=6e6491f63487ba9896eb82ab209a610f" alt="Filter by ecosystem" style={{width: '80%'}} width="2580" height="1105" data-path="images/best-practices/dependency-filters/dependency-filters/filter-ecosystem.webp" />

#### Filter dependencies by reachability

Use the **Dependency Reachability** filter to focus on dependencies that are reachable from your application code. Reachable dependencies are the ones that execute at runtime and increase your exposure to vulnerabilities. You can filter by **Reachable**, **Potentially Reachable**, or **Unreachable** dependency.

For example, to prioritize remediation of dependencies your application might call at runtime, use the `Dependency Reachability: Potentially Reachable` filter.

<img src="https://mintcdn.com/endorlabs-b4795f4f/deISr2DfATZg293W/images/best-practices/dependency-filters/dependency-filters/filter-dependency-reachability.webp?fit=max&auto=format&n=deISr2DfATZg293W&q=85&s=e63df4f4699914a50c027394409a6218" alt="Filter by dependency reachability" style={{width: '80%'}} width="2580" height="1150" data-path="images/best-practices/dependency-filters/dependency-filters/filter-dependency-reachability.webp" />

#### Filter dependencies by scope

Use the **Dependency Scopes** filter to separate production dependencies from those used only for testing or build-time tasks, so that you can target the right ones for policies and reports.

You can filter by:

* **Normal**: Production dependencies consumed by the application at run time.
* **Test**: Dependencies used only in test scope, such as test frameworks and test-only libraries.
* **Build**: Dependencies used only at build or development time, such as compilers, build tools, or dev-only tools.

For example, to show only production dependencies, use the `Dependency Scopes: Normal` filter.

<img src="https://mintcdn.com/endorlabs-b4795f4f/deISr2DfATZg293W/images/best-practices/dependency-filters/dependency-filters/filter-dependency-scope.webp?fit=max&auto=format&n=deISr2DfATZg293W&q=85&s=15c448f53246624c15a3cf38a3ade8ee" alt="Filter by dependency scope" style={{width: '80%'}} width="2580" height="1112" data-path="images/best-practices/dependency-filters/dependency-filters/filter-dependency-scope.webp" />

#### Filter dependencies by declaration

Use the **Direct** filter to distinguish between dependencies you declare explicitly in your manifests and those pulled in transitively.

For example, to view only direct dependencies, use the `Direct: Yes` filter.

<img src="https://mintcdn.com/endorlabs-b4795f4f/deISr2DfATZg293W/images/best-practices/dependency-filters/dependency-filters/filter-direct.webp?fit=max&auto=format&n=deISr2DfATZg293W&q=85&s=aabae512c3357443925fa6114742935b" alt="Filter by direct" style={{width: '80%'}} width="2580" height="1150" data-path="images/best-practices/dependency-filters/dependency-filters/filter-direct.webp" />

#### Filter dependencies by public

Use the **Public** filter to show dependencies from public registries (npm, Maven Central, PyPI) or from private sources.

For example, to view only dependencies from public package sources, use the `Public: Yes` filter.

<img src="https://mintcdn.com/endorlabs-b4795f4f/deISr2DfATZg293W/images/best-practices/dependency-filters/dependency-filters/filter-public.webp?fit=max&auto=format&n=deISr2DfATZg293W&q=85&s=2066b7214815fb79b81844c7d9a34993" alt="Filter by public" style={{width: '80%'}} width="2580" height="1100" data-path="images/best-practices/dependency-filters/dependency-filters/filter-public.webp" />

#### Filter dependencies by vendored

Use the **Vendored** filter to scope results by whether your repository embeds dependency artifacts, such as version-controlled source or shaded JARs, rather than resolving them from a package registry.

For example, to exclude vendored artifacts from a license review, use the `Vendored: No` filter.

<img src="https://mintcdn.com/endorlabs-b4795f4f/deISr2DfATZg293W/images/best-practices/dependency-filters/dependency-filters/filter-vendored.webp?fit=max&auto=format&n=deISr2DfATZg293W&q=85&s=e3348c85804e97476c78a4f35ce0d2d2" alt="Filter by vendored" style={{width: '80%'}} width="2580" height="1098" data-path="images/best-practices/dependency-filters/dependency-filters/filter-vendored.webp" />

#### Filter dependencies by approximation

Use the **Approximation** filter to distinguish dependencies inferred during fallback dependency resolution from dependencies fully resolved from manifests and lockfiles. Approximate dependencies can still appear in findings, but they may be less accurate than fully resolved dependencies.

For example, to review only dependencies discovered through approximate resolution, use the `Approximation: Yes` filter.

See [Approximate scans](/scan/sca/approximate-scans) for more information on approximate resolution.

<img src="https://mintcdn.com/endorlabs-b4795f4f/deISr2DfATZg293W/images/best-practices/dependency-filters/dependency-filters/filter-approximation.webp?fit=max&auto=format&n=deISr2DfATZg293W&q=85&s=37c3e115af25a6538718ea0799c315cd" alt="Filter by approximation" style={{width: '80%'}} width="2580" height="1106" data-path="images/best-practices/dependency-filters/dependency-filters/filter-approximation.webp" />

#### Filter dependencies by discovery type

Use the **Discovery Type** filter to restrict results by how the dependency was found. You can filter by **Manifest** (declared in a manifest), **Phantom** (phantom or imported dependency analysis), or **Segment match** (code segment match).

For example, to focus on phantom dependencies, use the `Discovery Type: Phantom` filter.

<img src="https://mintcdn.com/endorlabs-b4795f4f/deISr2DfATZg293W/images/best-practices/dependency-filters/dependency-filters/filter-discovery-type.webp?fit=max&auto=format&n=deISr2DfATZg293W&q=85&s=8a77948a2eae9625d46f0138477c1acb" alt="Filter by discovery type" style={{width: '80%'}} width="2580" height="1100" data-path="images/best-practices/dependency-filters/dependency-filters/filter-discovery-type.webp" />

#### Filter dependencies by pinned

Use the **Pinned** filter to tell whether the dependency version is pinned to a specific version or range. Unpinned direct dependencies are a common operational and supply chain risk because builds can pull different versions over time.

For example, to list only pinned dependencies, use the `Pinned: Yes` filter.

<img src="https://mintcdn.com/endorlabs-b4795f4f/deISr2DfATZg293W/images/best-practices/dependency-filters/dependency-filters/filter-pinned.webp?fit=max&auto=format&n=deISr2DfATZg293W&q=85&s=d9d3307b982136b3dfd133838ebc3999" alt="Filter by pinned" style={{width: '80%'}} width="2580" height="1150" data-path="images/best-practices/dependency-filters/dependency-filters/filter-pinned.webp" />

#### Filter dependencies by scan timestamp

Use the **Last Scanned** filter to identify dependencies with stale security data that require fresh scans for current security posture. You can select from predefined time ranges or use the calendar to select a specific date.

For example, to identify dependencies scanned within the last 24 hours, use the `Last Scanned: Last Day` filter.

<img src="https://mintcdn.com/endorlabs-b4795f4f/deISr2DfATZg293W/images/best-practices/dependency-filters/dependency-filters/filter-last-scanned.webp?fit=max&auto=format&n=deISr2DfATZg293W&q=85&s=f73d19e233993a237ea013970d33a1ab" alt="Filter by last scanned" style={{width: '80%'}} width="2592" height="1132" data-path="images/best-practices/dependency-filters/dependency-filters/filter-last-scanned.webp" />

#### Filter dependencies by release date

Use the **Released** filter to focus on recently released dependency versions for upgrade planning or to track new releases. You can select from predefined time ranges or use the calendar to select a specific date.

For example, to find dependencies released in the last week, use the `Released: Last Week` filter.

<img src="https://mintcdn.com/endorlabs-b4795f4f/deISr2DfATZg293W/images/best-practices/dependency-filters/dependency-filters/filter-released.webp?fit=max&auto=format&n=deISr2DfATZg293W&q=85&s=82f72b9ebee1673d003f64c51114c31d" alt="Filter by release date" style={{width: '80%'}} width="2559" height="610" data-path="images/best-practices/dependency-filters/dependency-filters/filter-released.webp" />

### Filter dependencies using API

For complex queries, use the advanced filter syntax to combine multiple attributes and apply logical operators. Use the [Dependency filter builder](#interactive-filter-builder) to assemble conditions interactively.

The following table lists the available attributes for dependency filters.

<YamlTable>
  {`


    - Title: Dependency Package Version Name
    Key: \`meta.name\`
    Description: Filters dependencies by the dependency package version name in the format \`ecosystem://package@version\`.

    - Title: Parent UUID
    Key: \`meta.parent_uuid\`
    Description: Filters dependencies by the root package version UUID that declares or pulls in the dependency.

    - Title: Importing Project UUID
    Key: \`spec.importer_data.project_uuid\`
    Description: Filters dependencies by the project that contains them. Use to list all dependencies for a given project.

    - Title: Importing Package Version UUID
    Key: \`spec.importer_data.package_version_uuid\`
    Description: Filters dependencies by the root package version that declares or pulls in the dependency.

    - Title: Importing Package Name
    Key: \`spec.importer_data.package_name\`
    Description: Filters dependencies by the qualified name of the importing package, without version.

    - Title: Importing Package Version Name
    Key: \`spec.importer_data.package_version_name\`
    Description: Filters dependencies by the fully qualified name of the root package version.

    - Title: Call Graph Available
    Key: \`spec.importer_data.callgraph_available\`
    Description: Filters by whether a call graph is available for the root package version.

    - Title: Dependency Project UUID
    Key: \`spec.dependency_data.project_uuid\`
    Description: Filters by the project UUID to which the dependency package version belongs.

    - Title: Dependency Package Version UUID
    Key: \`spec.dependency_data.package_version_uuid\`
    Description: Filters by the UUID of the dependency package version object.

    - Title: Dependency Package Name
    Key: \`spec.dependency_data.package_name\`
    Description: Filters by the qualified dependency package name.

    - Title: Ecosystem
    Key: \`spec.dependency_data.ecosystem\`
    Description: Filters by dependency ecosystem, such as npm, Maven, or PyPI.

    - Title: Direct
    Key: \`spec.dependency_data.direct\`
    Description: Filters by whether the dependency is direct or transitive.

    - Title: Reachability
    Key: \`spec.dependency_data.reachable\`
    Description: Filters by reachability status, such as reachable, potentially reachable, or unreachable.

    - Title: Dependency Scope
    Key: \`spec.dependency_data.scope\`
    Description: Filters by dependency scope, such as Build, Normal, or Test.

    - Title: Public
    Key: \`spec.dependency_data.public\`
    Description: Filters by whether the dependency is from a public or a private source.

    - Title: Vendored
    Key: \`spec.dependency_data.vendored\`
    Description: Filters by whether the dependency is vendored or embedded in your repository.

    - Title: Approximation
    Key: \`spec.dependency_data.approximation\`
    Description: Filters by whether the dependency is approximate (estimated from unresolved dependency data).

    - Title: Pinned
    Key: \`spec.dependency_data.pinned\`
    Description: Filters by pinned status of the dependency version.

    - Title: Patched
    Key: \`spec.dependency_data.patched\`
    Description: Filters by patch status of the dependency version.

    - Title: End-of-Life
    Key: \`spec.dependency_data.eol\`
    Description: Filters by whether the dependency is end-of-life.

    - Title: Last Commit
    Key: \`spec.dependency_data.last_commit\`
    Description: Filters by the date of the last commit or modification in the dependency version.

    - Title: End-of-Life Timestamp
    Key: \`spec.dependency_data.eol_timestamp\`
    Description: Filters by the end-of-life timestamp of the dependency package version.

    - Title: Namespace
    Key: \`spec.dependency_data.namespace\`
    Description: Filters by the namespace to which the dependency package version belongs.

    - Title: Discovery Type
    Key: \`spec.dependency_data.discovery_type\`
    Description: Filters by discovery method: manifest, phantom, or segment match.

    - Title: Parent Count
    Key: \`spec.dependency_data.parent_count\`
    Description: Filters by the number of direct parents of the dependency in the dependency graph.


    `}
</YamlTable>

#### Interactive filter builder

<DependencyFilterBuilder />

#### API filter use cases

The following examples demonstrate how to combine these attributes for common security and compliance workflows.

<AccordionGroup>
  <Accordion title="Identify direct dependencies in a project">
    List only direct dependencies for a given project.

    ```bash theme={null}
    spec.importer_data.project_uuid==<project-uuid> and spec.dependency_data.direct==true
    ```
  </Accordion>

  <Accordion title="Find direct and reachable dependencies of a package version">
    Focus on direct dependencies of a root package version that are also reachable, for prioritization.

    ```bash theme={null}
    spec.importer_data.package_version_uuid==<package-version-uuid> and spec.dependency_data.direct==true and spec.dependency_data.reachable==REACHABILITY_TYPE_REACHABLE
    ```
  </Accordion>

  <Accordion title="Identify end-of-life dependencies in the namespace">
    Find dependencies that are end-of-life across the namespace for upgrade or replacement planning.

    ```bash theme={null}
    spec.dependency_data.eol==true
    ```
  </Accordion>

  <Accordion title="Find reachable npm dependencies in the namespace">
    Limit to npm dependencies that are reachable from application code, across the namespace.

    ```bash theme={null}
    spec.dependency_data.ecosystem==ECOSYSTEM_NPM and spec.dependency_data.reachable==REACHABILITY_TYPE_REACHABLE
    ```
  </Accordion>

  <Accordion title="Find non-vendored and public dependencies">
    Find all public and non-vendored dependencies across the namespace for license or supply chain review.

    ```bash theme={null}
    spec.dependency_data.vendored==false and spec.dependency_data.public==true
    ```
  </Accordion>

  <Accordion title="Identify all patched dependencies in the namespace">
    Query across the namespace for dependencies that have a patch, without scoping by project.

    ```bash theme={null}
    spec.dependency_data.patched==true
    ```
  </Accordion>
</AccordionGroup>
