Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
d112a5d
ci(windsurf): workflow for release notes
marc-romu Jun 24, 2025
b7d3fe9
feat(chat): add system prompt support to WebChat component
marc-romu Jul 9, 2025
bc9cebc
refactor(chat): enhance AI system prompt
marc-romu Jul 9, 2025
24cb2f4
refactor(chat): enhance AI system prompt
marc-romu Jul 9, 2025
1d8d2cc
refactor: code cleanup
marc-romu Jul 9, 2025
125bfbc
feat(chat): add system prompt input to AI Chat Component (#236)
marc-romu Jul 9, 2025
4e55c0d
docs: update version badge for dev
actions-user Jul 9, 2025
961ef82
docs: update version badge for dev to 0.3.4-dev.250709 (#237)
marc-romu Jul 9, 2025
441b5ae
refactor(config): renamed SmartHopper.Config to SmartHopper.Infrastru…
marc-romu Jul 9, 2025
07f8114
refactor(managers): moved AIContextManager to Infrastructure.Managers
marc-romu Jul 9, 2025
98bc169
refactor(managers): reorganized AIProvider, AIContext and AITool mana…
marc-romu Jul 9, 2025
8a19a9a
refactor(core): reorganization of SmartHopper.Core
marc-romu Jul 9, 2025
6d75c66
refactor: code cleanup
marc-romu Jul 9, 2025
49fcfd1
refactor: supress trailing shitespaces
marc-romu Jul 9, 2025
86098f0
refactor: renamed SmartHopper.Infrastructure.Configuration namespace …
marc-romu Jul 9, 2025
1807063
fix: missing webview resources in compilation
marc-romu Jul 9, 2025
421ebd2
refactor: reorganize project structure and rename SmartHopper.Config …
marc-romu Jul 9, 2025
76d27f4
feat(context): enhance context filtering with wildcard support and fl…
marc-romu Jul 10, 2025
4179279
refactor(context): debugging
marc-romu Jul 10, 2025
db341a1
feat(context): add support for excluding all providers/context (#239)
marc-romu Jul 10, 2025
dfc9415
docs: update version badge for dev
actions-user Jul 10, 2025
d3dd4d3
docs: update version badge for dev to 0.3.4-dev.250710 (#240)
marc-romu Jul 10, 2025
3f686cc
feat(gh_group): add component grouping functionality
marc-romu Jul 10, 2025
e8680d8
feat(ai): enhance component grouping and property management
marc-romu Jul 10, 2025
9b478d7
feat(ghgroup): add undo support
marc-romu Jul 10, 2025
6232961
feat(aitools): new group ai tool (#241)
marc-romu Jul 10, 2025
0ca2b64
fix(ghgroup)
marc-romu Jul 10, 2025
e531e5a
Merge branch 'dev' of https://github.com/architects-toolkit/SmartHopp…
marc-romu Jul 10, 2025
0177633
fix(github): label syncer not working
marc-romu Jul 10, 2025
aefef68
feat(listgenerate): new list generate ai tool
marc-romu Jul 10, 2025
1c28758
feat(listgenerate): new aitextlistgenerate component implementing lis…
marc-romu Jul 10, 2025
1db2d10
docs
marc-romu Jul 10, 2025
4a49e76
refactor(ghgroup): reorder requirements
marc-romu Jul 10, 2025
0e0d36b
refactor: remove trailing spaces
marc-romu Jul 10, 2025
96e5ece
feat(components): add list_generate AI tool and AITextListGenerate co…
marc-romu Jul 10, 2025
53541a5
docs
marc-romu Jul 10, 2025
635f278
refactor(aitools): update tool handling in AI providers
marc-romu Jul 11, 2025
22f9a9a
refactor: added docstrings
marc-romu Jul 11, 2025
948502b
feat(aitools): add category support to AITool class
marc-romu Jul 11, 2025
b205b65
feat(filtering): add advanced common filtering system for AI tools an…
marc-romu Jul 11, 2025
6a785f3
remove(componentbase): removed unused GetResponse in AiStatefulAsyncC…
marc-romu Jul 11, 2025
df1ba61
refactor: renamed Filtering to Filter
marc-romu Jul 11, 2025
1f7b7e1
fix: properly passing context filters to ai-powered aitools
marc-romu Jul 11, 2025
fd7ef10
refactor: code cleanup
marc-romu Jul 11, 2025
1c8aae5
feat(infrastructure): improve filtering capabilities with new Filter …
marc-romu Jul 11, 2025
3db2ab4
chore: prepare release 0.3.4-alpha with version update and code style…
actions-user Jul 11, 2025
a1c44aa
chore: prepare release 0.3.4-alpha with version update and code style…
marc-romu Jul 11, 2025
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
15 changes: 9 additions & 6 deletions .github/labels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,19 +119,22 @@
color: "000"
description: "Issues related to the DeepSeek provider"

# Feature Labels
- name: "feature: Settings"
# Scope Labels
- name: "scope: Settings"
color: "000"
description: "Issues related to the Settings menu"
- name: "feature: AI Tools"
- name: "scope: AI Tools"
color: "000"
description: "Issues related to the AI tools"
- name: "feature: Provider Manager"
- name: "scope: Provider Manager"
color: "000"
description: "Issues related to the Provider Manager"
- name: "feature: UI"
- name: "scope: Context Manager"
color: "000"
description: "Issues related to the Context Manager"
- name: "scope: UI"
color: "000"
description: "Issues related to the UI features"
- name: "feature: Toolbar menu"
- name: "scope: Toolbar menu"
color: "000"
description: "Issues related to the Toolbar menu"
5 changes: 2 additions & 3 deletions .github/workflows/github-labels-sync.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ on:
push:
branches:
- main
- dev
paths:
- .github/labels.yml
workflow_dispatch:
Expand All @@ -27,12 +28,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.PAT }}

- uses: micnncim/action-label-syncer@v1.3.0
env:
GITHUB_TOKEN: ${{ secrets.PAT }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
manifest: .github/labels.yml
prune: false
4 changes: 2 additions & 2 deletions .windsurf/rules/ai-tool-conventions.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
---
trigger: glob
globs: **/SmartHopper.Core.Grasshopper/Tools/*.cs
globs: **/SmartHopper.Core.Grasshopper/AITools/*.cs
---

# AI Tool conventions
- Implement IAIToolProvider in SmartHopper.Core.Grasshopper.Tools
- Implement IAIToolProvider in SmartHopper.Core.Grasshopper.AITools
- File name: scope_action.cs
- Define AITool metadata (Name, Description, schema)
- Auto-discover via AIToolManager
Expand Down
2 changes: 1 addition & 1 deletion .windsurf/rules/solution-structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ trigger: always_on
- SmartHopper.Core: Contains the core functionality
- SmartHopper.Core.Grasshopper: Type converters, utilities & tool definitions
- SmartHopper.Components: Grasshopper components (inherit ComponentBase/AIStatefulAsyncComponentBase)
- SmartHopper.Config: Configuration models & ProviderManager
- SmartHopper.Infrastructure: Settings, Provider manager, Context manager and AITool manager
- SmartHopper.Menu: Menu bar setup
- SmartHopper.Components.Test: xUnit tests (not for production)
- SmartHopper.Providers.*: AI provider projects
2 changes: 1 addition & 1 deletion .windsurf/rules/using-references-sorting.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
trigger: always_on
---

Place System references first, sorted alphabetically. Then sort other using references in alphabetic order.
Place System references first, sorted alphabetically. Then sort other references in alphabetic order.
2 changes: 1 addition & 1 deletion .windsurf/rules/webchat-cdn.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
trigger: glob
globs: src/SmartHopper.Core/AI/Chat/*
globs: src/SmartHopper.Core/UI/Chat/*
---

Always host third-party WebChat JS/CSS dependencies locally rather than using external CDNs (e.g. MathJax).
2 changes: 1 addition & 1 deletion .windsurf/rules/yak-package-management.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
trigger: glob
globs: .github/workflows/release-**.yml
globs: {.github/workflows/release-*.yml,yak-package}
---

# Yak Package Management for Rhino/Grasshopper
Expand Down
44 changes: 44 additions & 0 deletions .windsurf/workflows/release-notes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
description: Write the release notes
---

1. Analyze the last release in CHANGELOG.md

2. Return a title for the release in a code block, in plain text, with this format: "SmartHopper X.X.X(-alpha): Main Release Change". Examples: SmartHopper 0.3.2-alpha: Script Components Unleashed, SmartHopper 0.3.1-alpha: Tidy Up Your File!, SmartHopper 0.3.0-alpha: Powerful AI tools and enhanced security

3. Return the release notes in a markdown code block, following this format:

Brief sentence summarizing the release. (e.g. This alpha release packs powerful undo support, new scripting tools to create and review scripting components, and a sweeping refactor of our AI workflows in Grasshopper—plus fresh branding and quality-of-life fixes.)

## (emoji) Feature 1

Brief description of the feature, changes from previous releases... focusing on perceptible changes for the user.

## (emoji) Feature 2

Repeat features as necessary for the release.

## 🛠️ Technical Requirements

- Rhino 8.19 or above is required
- Windows 10/11 (MacOS has not been tested)
- Valid API keys for MistralAI, OpenAI or DeepSeek

## ⚠️ Important Notes

- This is an alpha release with some features still unstable or subject to change
- API keys are required, and usage costs apply based on your provider
- Documentation is currently under development

## 🤝 We Value Your Feedback!

Help shape SmartHopper's future by:
- Sharing your experiences with the new features
- Suggesting improvements via our [discussion](https://github.com/architects-toolkit/SmartHopper/discussions)
- Telling us what AI capabilities would help your workflow most

We hope you enjoy these new features and improvements!

Happy designing! 🎨

---
41 changes: 41 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,47 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.3.4-alpha] - 2025-07-11

### Added

- Added `Instructions` input to `AIChatComponent` ([#87](https://github.com/architects-toolkit/SmartHopper/issues/87))
- Added `systemPrompt` parameter to `WebChatUtils.ShowWebChatDialog`
- Context manager improvements:
- Added support for "-*" to exclude all providers/context in one go
- Added support for space as additional delimiters in filter strings
- Explicitly handle "*" wildcard to include all providers/context by default
- Added `gh_group` AI tool for grouping components by GUID, with support to custom names and colors
- Added `list_generate` AI tool for generating a list of items from a prompt and count ([#6](https://github.com/architects-toolkit/SmartHopper/issues/6))
- New `AITextListGenerate` component implementing `list_generate` AI tool with type 'text' ([#6](https://github.com/architects-toolkit/SmartHopper/issues/6))
- Added `Category` property to `AITool` with default value "General"
- New `Filter` class for common include/exclude patterns processing

### Changed

- Several improvements to `AIChatComponent`:
- Updated `WebChatDialog` to use provided system prompt or fall back to default
- Improved default system prompt for AI Chat to focus on a Grasshopper assistant, including tool call examples
- Added `gh_group` mention to default system prompt
- Modified manifest to reflect new instructions input feature in AI Chat Component
- Modified `AITextEvaluate`, `AITextGenerate`, `AIListEvaluate` and `AIListFilter` to exclude all context using the new "-*" filter
- Code reorganization:
- Reorganized `AIProvider`, `AIContext` and `AITool` managers
- Code cleanup in `AIChatComponent`, `WebChatDialog` and `WebChatUtils`
- Renamed `SmartHopper.Config` to `SmartHopper.Infrastructure`
- Renamed `SmartHopper.Config.Tests` to `SmartHopper.Infrastructure.Tests`
- Updated `StringConverter.StringToColor` to accept argb, rgb, html and known color names as input
- Change `GetResponse` parameter from `includeToolDefinitions` to `toolFilter`
- Updated AITool constructor to require category parameter
- Categorized existing tools with DataProcessing, Components, Knowledge and Scripting categories
- Updated unit tests to include category parameter
- Integrated the new `Filter` class in `GetFormattedTools` and `GetCurrentContext`

### Removed

- Removed unnecessary `GetModel` and `GetFormattedTools` methods in `OpenAIProvider`, `MistralAIProvider` and `TemplateProvider`
- Removed `GetResponse` method from `AIStatefulAsyncComponentBase` in favor of `CallAiToolAsync`

## [0.3.3-alpha] - 2025-06-23

### WIP
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# SmartHopper - AI-Powered Grasshopper3D Plugin

[![Version](https://img.shields.io/badge/version-0%2E3%2E3--alpha-orange)](https://github.com/architects-toolkit/SmartHopper/releases)
[![Version](https://img.shields.io/badge/version-0%2E3%2E4--alpha-orange)](https://github.com/architects-toolkit/SmartHopper/releases)
[![Status](https://img.shields.io/badge/status-Alpha-orange)](https://github.com/architects-toolkit/SmartHopper/releases)
[![Test results](https://img.shields.io/github/actions/workflow/status/architects-toolkit/SmartHopper/.github/workflows/ci-dotnet-tests.yml?label=.NET%20CI&logo=dotnet)](https://github.com/architects-toolkit/SmartHopper/actions/workflows/ci-dotnet-tests.yml)
[![Grasshopper](https://img.shields.io/badge/plugin_for-Grasshopper3D-darkgreen?logo=rhinoceros)](https://www.rhino3d.com/)
Expand Down Expand Up @@ -70,12 +70,12 @@ After installation, all SmartHopper components will be available in the Grasshop
| AI Chat Output (AiChatOutput)<br><sub>Receive some data from the AI Chat to your Grasshopper</sub> | ⚪ | - | - | - |
| AI Text Evaluate (AiTextEvaluate)<br><sub>Return a boolean from a text content using AI-powered checks</sub> | ⚪ | 🟡 | 🟠 | 🟢 |
| AI Text Generate (AiTextGenerate)<br><sub>Generate text content using AI</sub> | ⚪ | 🟡 | 🟠 | 🟢 |
| AI Text List Generate (AiTextListGenerate)<br><sub>Generate lists of text content using AI</sub> | ⚪ | 🟡 | 🟠 | 🟢 |
| AI Script Review (AiScriptReview)<br><sub>Make a review of a script, using AI</sub> | ⚪ | - | - | - |
| AI Script Edit (AiScriptEdit)<br><sub>Modify an existing script using AI</sub> | ⚪ | - | - | - |
| AI Script New (AiScriptNew)<br><sub>Generate a script using AI</sub> | ⚪ | - | - | - |
| AI List Evaluate (AiListEvaluate)<br><sub>Return a boolean from a list of elements using AI analysis</sub> | ⚪ | 🟡 | 🟠 | 🟢 |
| AI List Filter (AiListFilter)<br><sub>Process items in lists (reorder, shuffle, filter, etc.) based on AI-driven rules</sub> | ⚪ | 🟡 | 🟠 | 🟢 |
| AI List Generate (AiListGenerate)<br><sub>Generate lists dynamically using AI algorithms</sub> | ⚪ | - | - | - |
| AI JSON Generate (AiJsonGenerate)<br><sub>Generate an AI response in strict JSON output</sub> | ⚪ | - | - | - |
| AI GroupTitle (AiGroupTitle)<br><sub>Group components and set a meaningful title to the group</sub> | ⚪ | - | - | - |
| AI File Context (AiFileContext)<br><sub>Set a context for the current document</sub> | ⚪ | 🟡 | 🟠 | 🟢 |
Expand All @@ -97,6 +97,7 @@ AI Tools are the interface between AI and Grasshopper, allowing to, for example,
| text_generate | Generates text based on a prompt and optional instructions | ⚪ | 🟡 | 🟠 | 🟢 |
| list_evaluate | Evaluates a list based on a natural language question | ⚪ | 🟡 | 🟠 | 🟢 |
| list_filter | Filters a list based on natural language criteria | ⚪ | 🟡 | 🟠 | 🟢 |
| list_generate | Generates a list based on a natural language prompt | ⚪ | 🟡 | 🟠 | 🟢 |
| script_review | Review a script for potential issues using AI-powered checks | ⚪ | 🟡 | 🟠 | 🟢 |
| script_edit | Modify the script from an existing component | ⚪ | 🟡 | - | - |
| script_new | Place a new script component from a natural language prompt | ⚪ | 🟡 | 🟠 | 🟢 |
Expand Down
2 changes: 1 addition & 1 deletion Sign-Authenticode.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ if ($Generate) {
} elseif (Test-Path $Sign -PathType Container) {
Write-Host "Signing assemblies under directory: $Sign"
$items = Get-ChildItem -Path $Sign -Recurse -Filter "*.dll" |
Where-Object { $_.Name -like "SmartHopper.Providers.*.dll" -or $_.Name -eq "SmartHopper.Config.dll" }
Where-Object { $_.Name -like "SmartHopper.Providers.*.dll" -or $_.Name -eq "SmartHopper.Infrastructure.dll" }
} else {
Write-Error "Path '$Sign' is not a .dll file or directory"
exit 1
Expand Down
4 changes: 2 additions & 2 deletions SmartHopper.sln
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SmartHopper.Core.Grasshoppe
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SmartHopper.Components", "src\SmartHopper.Components\SmartHopper.Components.csproj", "{60732624-037C-4D6D-BC4C-588A0C25C338}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SmartHopper.Config", "src\SmartHopper.Config\SmartHopper.Config.csproj", "{A932CFFA-0C82-4A1F-92F2-003CDE1C94AC}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SmartHopper.Infrastructure", "src\SmartHopper.Infrastructure\SmartHopper.Infrastructure.csproj", "{A932CFFA-0C82-4A1F-92F2-003CDE1C94AC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SmartHopper.Menu", "src\SmartHopper.Menu\SmartHopper.Menu.csproj", "{B932CFFA-0C82-4A1F-92F2-003CDE1C94AD}"
EndProject
Expand All @@ -19,7 +19,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SmartHopper.Providers.Mistr
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SmartHopper.Providers.OpenAI", "src\SmartHopper.Providers.OpenAI\SmartHopper.Providers.OpenAI.csproj", "{087FFA5E-1049-459D-9C68-1C0B8E7F9EBC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SmartHopper.Config.Tests", "src\SmartHopper.Config.Tests\SmartHopper.Config.Tests.csproj", "{469B4BA9-C2CB-4270-8896-0F04DAF67887}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SmartHopper.Infrastructure.Tests", "src\SmartHopper.Infrastructure.Tests\SmartHopper.Infrastructure.Tests.csproj", "{469B4BA9-C2CB-4270-8896-0F04DAF67887}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{827E0CD3-B72D-47B6-A68D-7590B98EB39B}"
EndProject
Expand Down
2 changes: 1 addition & 1 deletion Solution.props
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<Project>
<PropertyGroup>
<SolutionVersion>0.3.3-alpha</SolutionVersion>
<SolutionVersion>0.3.4-alpha</SolutionVersion>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@
* Copyright (c) 2021 Speckle Systems
*/

using Grasshopper.Kernel;
using SmartHopper.Core.ComponentBase;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Threading;
using System.Threading.Tasks;
using Grasshopper.Kernel;
using Grasshopper.Kernel.Data;
using Grasshopper.Kernel.Types;
using System.Collections.Generic;
using System.Drawing;
using SmartHopper.Core.ComponentBase;

namespace SmartHopper.Components.Test.Misc
{
Expand Down Expand Up @@ -115,7 +115,7 @@ private async Task<long> CalculateNthPrime(int nthPrime, CancellationToken token

long b = 2;
bool isPrime = true;

while (b * b <= a)
{
token.ThrowIfCancellationRequested();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
* Copyright (c) 2021 Speckle Systems
*/

using Grasshopper.Kernel;
using SmartHopper.Core.ComponentBase;
using System;
using System.Drawing;
using System.Threading;
using System.Threading.Tasks;
using System.Drawing;
using Grasshopper.Kernel;
using SmartHopper.Core.ComponentBase;

namespace SmartHopper.Components.Test.Misc
{
Expand Down Expand Up @@ -83,7 +83,7 @@ public override async Task DoWorkAsync(CancellationToken token)

long b = 2;
bool isPrime = true;

while (b * b <= a)
{
token.ThrowIfCancellationRequested();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
* Copyright (c) 2021 Speckle Systems
*/

using Grasshopper.Kernel;
using SmartHopper.Core.ComponentBase;
using System;
using System.Drawing;
using System.Threading;
using System.Threading.Tasks;
using System.Drawing;
using Grasshopper.Kernel;
using SmartHopper.Core.ComponentBase;

namespace SmartHopper.Components.Test.Misc
{
Expand Down Expand Up @@ -84,7 +84,7 @@ public override async Task DoWorkAsync(CancellationToken token)

long b = 2;
bool isPrime = true;

while (b * b <= a)
{
token.ThrowIfCancellationRequested();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@
* Copyright (c) 2021 Speckle Systems
*/

using Grasshopper.Kernel;
using SmartHopper.Core.ComponentBase;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Threading;
using System.Threading.Tasks;
using Grasshopper.Kernel;
using Grasshopper.Kernel.Data;
using Grasshopper.Kernel.Types;
using System.Collections.Generic;
using System.Drawing;
using SmartHopper.Core.ComponentBase;

namespace SmartHopper.Components.Test.Misc
{
Expand Down Expand Up @@ -115,7 +115,7 @@ private async Task<long> CalculateNthPrime(int nthPrime, CancellationToken token

long b = 2;
bool isPrime = true;

while (b * b <= a)
{
token.ThrowIfCancellationRequested();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\SmartHopper.Config\SmartHopper.Config.csproj" />
<ProjectReference Include="..\SmartHopper.Infrastructure\SmartHopper.Infrastructure.csproj" />
<ProjectReference Include="..\SmartHopper.Core\SmartHopper.Core.csproj" />
<ProjectReference Include="..\SmartHopper.Core.Grasshopper\SmartHopper.Core.Grasshopper.csproj" />
</ItemGroup>
Expand Down
Loading
Loading