Skip to content

feat: Stac VS Code Plugin#448

Open
divyanshub024 wants to merge 4 commits intodevfrom
dv/stac-vscode-plugin
Open

feat: Stac VS Code Plugin#448
divyanshub024 wants to merge 4 commits intodevfrom
dv/stac-vscode-plugin

Conversation

@divyanshub024
Copy link
Member

@divyanshub024 divyanshub024 commented Feb 13, 2026

Description

This PR introduces the initial implementation of the Stac VS Code extension, enabling developers to build and preview Server-Driven UI screens using the Stac framework directly inside VS Code.

Key features included in this PR:

Live Preview

  • Adds side-by-side preview support for @StacScreen annotated screens.
  • Supports platform simulation for Android, iOS, and Web.
  • Enables theme selection using @StacThemeRef annotations.
  • Automatically refreshes preview on save.
  • Implements fast JSON generation using runner strategy with build fallback.
  • Handles preview host lifecycle, including automatic port recovery.

Wrap Quick Fixes

  • Adds quick-fix actions (Cmd+.) to wrap widgets with Stac components.

  • Includes preset wrappers such as:

    • StacContainer
    • StacPadding
    • StacCenter
    • StacAlign
    • StacSizedBox
    • StacExpanded
  • Supports wrapping with any Stac widget using dynamic catalog generation.

Snippets

  • Adds context-aware snippets:

    • stac screen — create new Stac screen template
    • stac theme — create new Stac theme template
  • Snippets are only shown in Stac DSL contexts.

Type of Change

  • New feature (non-breaking change which adds functionality)
  • Bug fix
  • Breaking change
  • Code refactor
  • Documentation
  • Build configuration change
  • Chore

Summary by CodeRabbit

  • New Features

    • Introduced a new VS Code extension for Stac with live preview functionality, wrap quick fixes for widgets, and code snippets.
  • Documentation

    • Added comprehensive README and CHANGELOG documenting extension features, settings, commands, and troubleshooting.
  • Chores

    • Added project configuration for extension development, testing, linting, and packaging.

Co-authored-by: Codex
- Introduced two new snippets: `stac screen` for creating a new Stac screen template and `stac theme` for creating a new Stac theme template.
- Updated the extension description and documentation to reflect the new snippets.
- Removed the old snippet catalog as it is no longer needed with the new implementation.
- Adjusted the snippet completion provider to support the new snippet triggers.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 13, 2026

📝 Walkthrough

Walkthrough

This PR establishes the foundational development and deployment infrastructure for a new Stac VS Code extension, including test configuration, workspace settings, build tasks, linting rules, packaging exclusions, and comprehensive documentation.

Changes

Cohort / File(s) Summary
VS Code Workspace Configuration
tools/stac-vscode/.vscode/extensions.json, tools/stac-vscode/.vscode/launch.json, tools/stac-vscode/.vscode/settings.json, tools/stac-vscode/.vscode/tasks.json
Configures recommended extensions (ESLint, test runner), defines extension launch profile for development mode, manages file exclusions and TypeScript settings, and establishes npm watch task for background compilation.
Build and Test Setup
tools/stac-vscode/.vscode-test.mjs, tools/stac-vscode/eslint.config.mjs, tools/stac-vscode/.vscodeignore
Configures VS Code test CLI to discover tests in out/test/**/*.test.js, establishes ESLint rules for TypeScript files with import naming conventions and style enforcement, and specifies packaging exclusions for build artifacts and configuration files.
Documentation
tools/stac-vscode/README.md, tools/stac-vscode/CHANGELOG.md, tools/stac-vscode/LICENSE
Adds extension documentation covering features (live preview, quick fixes, snippets), v0.1.0 release notes, and MIT license terms.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Suggested reviewers

  • rahulbisht25
  • Potatomonsta

Poem

🐰 A burrow of configs, so neat and so tidy,
ESLint and tasks, all checked and all heady,
With tests that will run and launch files so fair,
A Stac extension takes shape in the air! 🌟

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: Stac VS Code Plugin' clearly summarizes the main change—introducing a new VS Code extension for the Stac framework. It is concise, specific, and directly reflects the primary purpose of this changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into dev

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dv/stac-vscode-plugin

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@tools/stac-vscode/eslint.config.mjs`:
- Around line 3-27: The second config block (the object containing plugins,
languageOptions, and rules) lacks a files filter so its TypeScript-specific
parser and rules apply to all files; fix by merging the two objects or adding
files: ["**/*.ts"] to that second object so the TypeScript parser and rules
(plugins/@typescript-eslint, languageOptions.parser, and rules like
"@typescript-eslint/naming-convention", curly, eqeqeq, no-throw-literal, semi)
only apply to .ts files.
🧹 Nitpick comments (3)
tools/stac-vscode/.vscodeignore (1)

1-11: Consider excluding test output from the packaged extension.

The compiled test files under out/test/ will be included in the VSIX package since only src/** (source) is excluded but not the compiled test output. Adding an exclusion prevents unnecessary bloat.

Suggested addition
 **/.vscode-test.*
+out/test/**
tools/stac-vscode/README.md (1)

39-42: Dart version requirement is valid—consider if 3.9.2+ is the true minimum.

Dart 3.9.2 is a legitimate, stable release (August 2025). However, if the extension works with earlier Dart 3.x versions, consider lowering the minimum requirement to improve adoption and compatibility for users on stable versions.

tools/stac-vscode/CHANGELOG.md (1)

5-5: Consider adding a release date to the version heading.

Changelogs conventionally include a date next to the version number (e.g., ## [0.1.0] - 2026-02-13) per Keep a Changelog conventions.

Comment on lines +3 to +27
export default [{
files: ["**/*.ts"],
}, {
plugins: {
"@typescript-eslint": typescriptEslint.plugin,
},

languageOptions: {
parser: typescriptEslint.parser,
ecmaVersion: 2022,
sourceType: "module",
},

rules: {
"@typescript-eslint/naming-convention": ["warn", {
selector: "import",
format: ["camelCase", "PascalCase"],
}],

curly: "warn",
eqeqeq: "warn",
"no-throw-literal": "warn",
semi: "warn",
},
}]; No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find . -name "eslint.config.mjs" -type f

Repository: StacDev/stac

Length of output: 166


🌐 Web query:

ESLint flat config files array configuration merging behavior independent config objects

💡 Result:

In ESLint flat config, the exported value is an array of independent config objects, but ESLint does not merge the whole array into one config up front.

What actually gets merged (and when)

For a given file, ESLint:

  1. Finds all config objects in the exported array whose files/ignores match that file, then
  2. Merges only those matching objects, from top → bottom of the array, where later objects override earlier ones on conflicts. [1][2]

This is the “flat cascade”: matching configs are merged; non-matching ones are irrelevant for that file. [1][2]

How the merge behaves (practical rules)

  • Conflicts: “last matching config wins” (e.g., same rule configured twice). [2]
  • Nested objects: are merged so you keep earlier keys unless overwritten (example in docs: languageOptions.globals from a base config plus test globals from a later config both end up present). [1]
  • Arrays / non-mergeable values: generally behave as “override” (the later value replaces the earlier value) rather than concatenation—unless ESLint has an explicit merge strategy for that specific key. (ESLint’s config system is built on schema-defined merge rules; where multiple configs match, the later value can “win”.) [1][3]

Minimal example

export default [
  { files: ["**/*.js"], rules: { semi: "error" } },
  { files: ["tests/**/*.js"], rules: { semi: "warn" } },
];

For tests/foo.js, both match, they’re merged top→bottom, and semi: "warn" wins. [2]

Sources: ESLint “Cascading Configuration Objects” docs (merge + nested object example) [1], ESLint flat config cascade blog post (merge order + last-wins example) [2], and the underlying config-array/schema approach that defines merge rules and last-match winning in conflicts [3].

References:
[1] https://eslint.org/docs/latest/use/configure/configuration-files (see “Cascading Configuration Objects”)
[2] https://eslint.org/blog/2022/08/new-config-system-part-2/
[3] https://jsr.io/%40eslint/config-array


🏁 Script executed:

cat -n ./tools/stac-vscode/eslint.config.mjs

Repository: StacDev/stac

Length of output: 831


The second config object has no files filter — rules apply to all files, not just *.ts.

In ESLint flat config, each array element is a separate config block. Config objects with no files property match all files. Here, the first object only specifies files: ["**/*.ts"] but has no rules, so it's inert. The second object contains all the rules and the TypeScript parser but lacks a files constraint, so it applies globally to all files — including non-TypeScript files like this .mjs file itself.

Merge them into a single config object with the files filter:

 export default [{
     files: ["**/*.ts"],
-}, {
     plugins: {
         "@typescript-eslint": typescriptEslint.plugin,
     },
 
     languageOptions: {
         parser: typescriptEslint.parser,
         ecmaVersion: 2022,
         sourceType: "module",
     },
 
     rules: {
         "@typescript-eslint/naming-convention": ["warn", {
             selector: "import",
             format: ["camelCase", "PascalCase"],
         }],
 
         curly: "warn",
         eqeqeq: "warn",
         "no-throw-literal": "warn",
         semi: "warn",
     },
 }];
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export default [{
files: ["**/*.ts"],
}, {
plugins: {
"@typescript-eslint": typescriptEslint.plugin,
},
languageOptions: {
parser: typescriptEslint.parser,
ecmaVersion: 2022,
sourceType: "module",
},
rules: {
"@typescript-eslint/naming-convention": ["warn", {
selector: "import",
format: ["camelCase", "PascalCase"],
}],
curly: "warn",
eqeqeq: "warn",
"no-throw-literal": "warn",
semi: "warn",
},
}];
export default [{
files: ["**/*.ts"],
plugins: {
"@typescript-eslint": typescriptEslint.plugin,
},
languageOptions: {
parser: typescriptEslint.parser,
ecmaVersion: 2022,
sourceType: "module",
},
rules: {
"@typescript-eslint/naming-convention": ["warn", {
selector: "import",
format: ["camelCase", "PascalCase"],
}],
curly: "warn",
eqeqeq: "warn",
"no-throw-literal": "warn",
semi: "warn",
},
}];
🤖 Prompt for AI Agents
In `@tools/stac-vscode/eslint.config.mjs` around lines 3 - 27, The second config
block (the object containing plugins, languageOptions, and rules) lacks a files
filter so its TypeScript-specific parser and rules apply to all files; fix by
merging the two objects or adding files: ["**/*.ts"] to that second object so
the TypeScript parser and rules (plugins/@typescript-eslint,
languageOptions.parser, and rules like "@typescript-eslint/naming-convention",
curly, eqeqeq, no-throw-literal, semi) only apply to .ts files.

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.

1 participant