Skip to content

Add glob-style wildcard support for Data Extractor item keys#3206

Merged
mcosgriff merged 13 commits intomainfrom
2973-data-extractor-wildcard-support
Apr 17, 2026
Merged

Add glob-style wildcard support for Data Extractor item keys#3206
mcosgriff merged 13 commits intomainfrom
2973-data-extractor-wildcard-support

Conversation

@mcosgriff
Copy link
Copy Markdown
Contributor

@mcosgriff mcosgriff commented Apr 10, 2026

Summary

  • Add glob pattern support (*, ?, []) for packet and item names in the Data Extractor, allowing users to add multiple items with a single entry
    • * — matches any number of characters. TEMP* matches TEMP1, TEMP2, TEMP_ANYTHING
    • ? — matches exactly one character. TEMP? matches TEMP1, TEMP2 but not TEMP10 or TEMP
    • [] — matches one character from a set. TEMP[13] matches TEMP1 and TEMP3 but not TEMP2
  • Backend expands globs server-side before streaming, supporting item globs, packet globs, combined globs, and LATEST + glob
  • Packet and item selectors switch to combobox (free-text + dropdown) in the Data Extractor via new allowGlob prop on TargetPacketItemChooser
  • Refactor streaming key parsing — Extract StreamingKey (Data.define) to replace key.split('__')[N] indexing scattered across StreamingObject, StreamingApi, and LoggedStreamingThread. Key fields like target_name, packet_name, and item_name are now accessed by name instead of positional index.

Changes

  • StreamingKey — add has_glob? method
  • StreamingApi — add expand_item_globs(), wired into add() and remove()
  • TargetPacketItemChooser — new allowGlob prop switches packet/item selectors to v-combobox
  • DataExtractor.vue — enable allow-glob, add keyMap fallback for expanded keys
  • 18 new unit tests for has_glob? and expand_item_globs

Test plan

  • cd openc3-cosmos-cmd-tlm-api && OPENC3_DEVEL=../openc3 bundle exec rspec spec/models/streaming_key_spec.rb spec/models/streaming_api_spec.rb
  • Open Data Extractor, select a target, type TEMP* in the item field, click Add Item, process — verify all matching TEMP items appear in the output
  • Try packet glob: type HEALTH* as packet, * as item — verify all items from matching packets stream
  • Try LATEST + glob: select LATEST packet, type TEMP* — verify expansion works
  • Verify normal (non-glob) item selection still works as before

Using just just build-deps-force && just dev-data-extractor

Closes #2973

Replace ad-hoc key.split('__') + positional index access with an   immutable StreamingKey value object. This centralizes the parsing logic for streaming key strings (DECOM__TLM__INST__PARAMS__VALUE1__CONVERTED, etc.) and makes field access self-documenting via named attributes.

- Add StreamingKey Data.define with .parse and #to_key_string
 - Refactor StreamingObject#initialize to delegate parsing to StreamingKey
 - Refactor StreamingApi#build_item_collection and #expand_all_packets
 - Replace redundant object.key.split in LoggedStreamingThread#stream_items with direct attribute access
 - Add streaming_key_spec.rb with 22 unit tests
Add support for glob patterns (*, ?, []) in Data Extractor packet and item name fields, allowing users to select multiple items with a single entry (e.g., TEMP* matches TEMP1, TEMP2, TEMP3).

Backend:
 - Add StreamingKey#has_glob? to detect wildcard characters in key fields
- Add StreamingApi#expand_item_globs to expand glob patterns into  concrete item keys before streaming, supporting:
 - Item globs on a specific packet (HEALTH_STATUS/TEMP*)
 - Packet globs with concrete or glob items (HEALTH*/TEMP*)
 - LATEST + item globs (LATEST/TEMP*)
 - Wire expand_item_globs into add() and remove() flows

Frontend:
- Add allowGlob prop to TargetPacketItemChooser that switches packet and item selectors from v-autocomplete to v-combobox for free-text     entry of glob patterns
- Enable allow-glob on the Data Extractor chooser
- Add keyMap fallback in buildHeaders() and createFile() so glob-expanded keys decode correctly
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 10, 2026

Codecov Report

❌ Patch coverage is 94.01709% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 78.36%. Comparing base (0bec3f1) to head (5217f36).
⚠️ Report is 59 commits behind head on main.

Files with missing lines Patch % Lines
...nc3-cosmos-cmd-tlm-api/app/models/streaming_api.rb 89.70% 7 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3206      +/-   ##
==========================================
+ Coverage   78.33%   78.36%   +0.03%     
==========================================
  Files         674      675       +1     
  Lines       55402    55531     +129     
  Branches      728      728              
==========================================
+ Hits        43401    43519     +118     
- Misses      11923    11934      +11     
  Partials       78       78              
Flag Coverage Δ
python 79.64% <ø> (+0.03%) ⬆️
ruby-api 82.98% <94.01%> (+0.02%) ⬆️
ruby-backend 81.54% <ø> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread openc3-cosmos-cmd-tlm-api/app/models/streaming_api.rb Fixed
…lobs

Remove unused local variable from destructuring to resolve code quality finding.
Use explicit RuntimeError class instead of raising a string literal,
remove unnecessary regex escape characters, and add Angular-style
commit message generator command.

Co-Authored-By: Claude noreply@anthropic.com
Move require_relative statements before OpenC3.require_file calls
to satisfy SonarCloud import ordering rule. Revert explicit
RuntimeError class since raise already defaults to it.

Co-Authored-By: Claude noreply@anthropic.com
@mcosgriff
Copy link
Copy Markdown
Contributor Author

mcosgriff commented Apr 10, 2026

  • TEMP? => TEMP1, TEMP2, TEMP3, TEMP4
  • TEMP1* => TEMP1HIGH, TEMP1LOW, TEMP1MAX, TEMP1MEAN, TEMP1MIN, TEMP1STDDEV, TEMP1_MEGA, TEMP1_MICRO, TEMP1
  • TEMP* => TEMP1HIGH, TEMP1LOW, TEMP1MAX, TEMP1MEAN, TEMP1MIN, TEMP1STDDEV, TEMP1_MEGA, TEMP1_MICRO, TEMP1, TEMP2, TEMP3, TEMP3
  • TEMP[1234] => TEMP1, TEMP2, TEMP3, TEMP4
  • TEMP[1234] & TEMP1 & TEMP2 & TEMP3 & TEMP4 => TEMP1, TEMP2, TEMP3, TEMP4
  • T**P? => TEMP1, TEMP2, TEMP3, TEMP4

Make wildcard/glob support opt-in via a checkbox in the Mode menu
instead of always-on. Fix v-combobox returning full item objects
instead of value strings in TargetPacketItemChooser. Add root
justfile with dev server commands for all UI plugins.

Co-Authored-By: Claude noreply@anthropic.com
@mcosgriff
Copy link
Copy Markdown
Contributor Author

image

@mcosgriff
Copy link
Copy Markdown
Contributor Author

image

…d off

Watch the allowGlob prop and reset packet/item fields containing
glob characters when wildcards are disabled, preventing stale
wildcard patterns from being submitted. Add Ruby justfile for
openc3/ core development commands.

Co-Authored-By: Claude noreply@anthropic.com
@mcosgriff
Copy link
Copy Markdown
Contributor Author

image

Validate packet name against known packets before making get_tlm
calls when Allow Wildcards is enabled. Prevents 500 errors from
partial text input like "H" being sent as a packet name.

Co-Authored-By: Claude noreply@anthropic.com
@mcosgriff
Copy link
Copy Markdown
Contributor Author

Quality Gate Failed Quality Gate failed

Failed conditions 1 New issue 11.0% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

I made the change and then it complained about a redundant exception

…oser

Collapse multiline arrow functions onto single lines to satisfy
the prettier/prettier eslint rule.

Co-Authored-By: Claude noreply@anthropic.com
Add lint, lint-fix, lint-all, and lint-fix-all recipes to the root
justfile. Document the requirement to run pnpm lint after editing
Vue/JS files in CLAUDE.md. Fix prettier formatting for long find
callback in TargetPacketItemChooser.

Co-Authored-By: Claude noreply@anthropic.com
@mcosgriff mcosgriff marked this pull request as ready for review April 10, 2026 22:25
…ation

Extract repeated patterns from expand_all_packets and expand_item_globs
into reusable private helpers and StreamingKey methods to bring SonarCloud
duplication under the 3% threshold.

Co-Authored-By: Claude noreply@anthropic.com
@mcosgriff mcosgriff self-assigned this Apr 13, 2026
Copy link
Copy Markdown
Contributor

@ryan-pratt ryan-pratt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks fine, just not sure if we need to add a feature item to the backlog re my comment on the API calls

# This file may also be used under the terms of a commercial license
# if purchased from OpenC3, Inc.

StreamingKey = Data.define(:stream_mode, :cmd_or_tlm, :target_name, :packet_name, :item_name, :value_type, :reduced_type) do
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, this is a good refactor

if (value !== null) {
this.updatePacketDetails(value)
if (this.allowGlob && typeof value === 'string') {
// In glob mode, only call the API if the value matches a known packet
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The API calls get important info e.g. whether a command is hazardous. I don't really understand the ux for using a glob for commands, so maybe this is fine as-is, but we might want to add the ability in the API to check for hazardous commands matched by a glob.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point it's safe today because allowGlob defaults to false on the prop, so tools have to explicitly opt in and only Data Extractor is setting to true. I will add

globEnabled: function () {
  return this.allowGlob && this.mode === 'tlm'
}

to make sure the mode is only telemetry.

When glob mode is active, free-text packet names skip the updatePacketDetails API call where hazardous command metadata is fetched. Gate glob behind mode === 'tlm' so command tools can never bypass hazardous checks.

Co-Authored-By: Claude noreply@anthropic.com
@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
1 New issue
9.8% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@mcosgriff mcosgriff merged commit 50bf578 into main Apr 17, 2026
54 of 56 checks passed
@mcosgriff mcosgriff deleted the 2973-data-extractor-wildcard-support branch April 17, 2026 21:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Data Extractor wildcard support

2 participants