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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/ISSUE_TEMPLATE/bug-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
name: Bug report
about: Report a reproducible bug in Unity Resource RAG
title: "[bug] "
labels: ["bug"]
assignees: []
---

## Environment

- Unity version:
- OS:
- Package version:
- Sidecar version:
- Python version:

## Reproduction

1.
2.
3.

## Expected

## Actual

## Notes

- Logs:
- Screenshots or recordings:
- Extra context:
21 changes: 21 additions & 0 deletions .github/ISSUE_TEMPLATE/docs-issue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
name: Docs issue
about: Report a documentation problem or missing clarification
title: "[docs] "
labels: ["documentation"]
assignees: []
---

## Affected page or link

- Page:
- Link:

## What needs correction

## Expected correction

## Notes

- Suggested wording:
- Related issue or PR:
25 changes: 25 additions & 0 deletions .github/ISSUE_TEMPLATE/release-package-issue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
name: Release or package issue
about: Report a problem with an installed package or release artifact
title: "[release] "
labels: ["enhancement"]
assignees: []
---

## Environment

- Package install method:
- Sidecar bundle or source checkout:
- Artifact version:

## Problem

## Expected

## Actual

## Notes

- Install path or source path:
- Logs:
- Related release notes:
31 changes: 31 additions & 0 deletions .github/workflows/python-sidecar-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Python Sidecar CI

on:
push:
pull_request:

jobs:
validate:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Install Python dependencies
run: python -m pip install -r requirements.txt

- name: Run unit tests
run: python -m unittest discover -s tests -v

- name: Compile Python package
run: python -m compileall pipeline

- name: Build sidecar bundle smoke test
run: |
tmpdir="$(mktemp -d)"
python scripts/build_sidecar_bundle.py --output-dir "$tmpdir"
84 changes: 84 additions & 0 deletions .github/workflows/release-sidecar.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: Publish sidecar release asset

on:
push:
tags:
- "v*"
- "*.*.*"
release:
types:
- published

permissions:
contents: write

jobs:
publish-sidecar:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: "3.11"

- name: Install requirements
run: |
python -m pip install --upgrade pip
if [ -f requirements.txt ]; then
python -m pip install -r requirements.txt
fi

- name: Build sidecar bundle and archive it
id: build
run: |
build_json="$(python scripts/build_sidecar_bundle.py --output-dir dist)"
echo "$build_json"

bundle_root="$(BUILD_JSON="$build_json" python - <<'PY'
import json
import os

payload = json.loads(os.environ["BUILD_JSON"])
print(payload["bundleRoot"])
PY
)"
version="$(BUILD_JSON="$build_json" python - <<'PY'
import json
import os

payload = json.loads(os.environ["BUILD_JSON"])
print(payload["version"])
PY
)"

zip_path="dist/unity-resource-rag-sidecar-${version}.zip"
python - <<'PY' "$bundle_root" "$zip_path"
from pathlib import Path
import shutil
import sys

bundle_root = Path(sys.argv[1]).resolve()
zip_path = Path(sys.argv[2]).resolve()

shutil.make_archive(
str(zip_path.with_suffix("")),
"zip",
root_dir=bundle_root.parent,
base_dir=bundle_root.name,
)
PY

echo "bundle_root=$bundle_root" >> "$GITHUB_OUTPUT"
echo "version=$version" >> "$GITHUB_OUTPUT"
echo "zip_path=$zip_path" >> "$GITHUB_OUTPUT"

- name: Upload release asset
uses: softprops/action-gh-release@v2
with:
files: ${{ steps.build.outputs.zip_path }}
tag_name: ${{ github.event.release.tag_name || github.ref_name }}
fail_on_unmatched_files: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
48 changes: 48 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Contributing

Thanks for helping improve Unity Resource RAG.

## Local setup

Use Python 3.11 or 3.12 for the sidecar and test suite.

```bash
python3.12 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
```

If `python3.12` is not available, use another Python 3.11+ interpreter such as `python3.11`, `python3`, or the equivalent Windows launcher.

## Verification

Run the Python checks before you open a PR:

```bash
python -m unittest discover -s tests -v
python -m compileall pipeline
python scripts/build_sidecar_bundle.py --output-dir dist
```

The bundle smoke test should finish without errors and leave a portable sidecar bundle under the output directory.

## Unity smoke check

Do a minimal Unity validation before asking for review:

1. Open the project in a supported Unity editor.
2. Confirm `Window > Unity Resource RAG` opens.
3. Run `Quick Setup`.
4. Refresh the Readiness Dashboard and confirm the editor can see the package and sidecar path you expect.

If the change touches the package surface or editor integration, also verify the package loads in a clean project or a fresh project checkout.

## Quality cases

Use the existing `quality-case-report` issue template when you want to record a real validation run.

- Keep the report tied to one concrete project or screen.
- Include the reference source, blueprint path, and before/after artifacts.
- Capture what matched well, what did not, and the most useful follow-up ideas.

Do not replace the quality-case template with a generic bug report; it exists to preserve real project validation history.
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@

저장소 루트 문서:

- `docs/asset-aware-ui-rag-architecture.md`
- `specs/resource-schema.md`
- `specs/retrieval-ranking.md`
- `specs/ui-assembly-contract.md`
- [docs/asset-aware-ui-rag-architecture.md](https://github.com/Hanjo92/unity-resource-rag/blob/main/docs/asset-aware-ui-rag-architecture.md)
- [specs/resource-schema.md](https://github.com/Hanjo92/unity-resource-rag/blob/main/specs/resource-schema.md)
- [specs/retrieval-ranking.md](https://github.com/Hanjo92/unity-resource-rag/blob/main/specs/retrieval-ranking.md)
- [specs/ui-assembly-contract.md](https://github.com/Hanjo92/unity-resource-rag/blob/main/specs/ui-assembly-contract.md)

루트 문서들은 sidecar pipeline까지 포함한 전체 아키텍처를 설명하고,
패키지 내부 문서는 UPM 안에 들어가는 Unity 코드에 집중한다.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using UnityEditor;
using UnityEditor.PackageManager;
using UnityEngine;

namespace UnityResourceRag.Editor.ResourceIndexing
Expand Down Expand Up @@ -141,7 +142,7 @@ private static bool TryLoadBlueprint(

if (!string.IsNullOrWhiteSpace(parameters.blueprintPath))
{
string resolvedPath = ResourceCatalogStorage.ResolveProjectPath(parameters.blueprintPath, parameters.blueprintPath);
string resolvedPath = ResolveBlueprintPath(parameters.blueprintPath);
if (!File.Exists(resolvedPath))
{
error = $"Blueprint file not found: {resolvedPath}";
Expand All @@ -162,6 +163,36 @@ private static bool TryLoadBlueprint(
return false;
}

private static string ResolveBlueprintPath(string blueprintPath)
{
string trimmedPath = blueprintPath?.Trim();
if (string.IsNullOrWhiteSpace(trimmedPath))
{
return string.Empty;
}

if (Path.IsPathRooted(trimmedPath))
{
return Path.GetFullPath(trimmedPath).Replace('\\', '/');
}

string normalizedPath = trimmedPath.Replace('\\', '/');
if (normalizedPath.Equals("Samples~", StringComparison.OrdinalIgnoreCase) ||
normalizedPath.StartsWith("Samples~/", StringComparison.OrdinalIgnoreCase))
{
PackageInfo packageInfo = PackageInfo.FindForAssembly(Assembly.GetExecutingAssembly());
if (packageInfo != null && !string.IsNullOrWhiteSpace(packageInfo.resolvedPath))
{
string relativeSamplePath = normalizedPath.Equals("Samples~", StringComparison.OrdinalIgnoreCase)
? string.Empty
: normalizedPath.Substring("Samples~/".Length);
return Path.GetFullPath(Path.Combine(packageInfo.resolvedPath, "Samples~", relativeSamplePath)).Replace('\\', '/');
}
}

return ResourceCatalogStorage.ResolveProjectPath(trimmedPath, trimmedPath);
}

private static List<UiBlueprintIssue> ValidateBlueprint(UiBlueprintDocument blueprint)
{
var issues = new List<UiBlueprintIssue>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ public sealed class UnityResourceRagEditorSettings : ScriptableSingleton<UnityRe
private const string DefaultUnityMcpBaseUrl = "http://127.0.0.1:8080";
private const int DefaultUnityMcpTimeoutMs = 120000;
private const string SidecarBundleManifestFileName = "unity-resource-rag-sidecar.json";
private const int MinimumPythonMajorVersion = 3;
private const int MinimumPythonMinorVersion = 11;
private const string MinimumPythonVersionProbe = "import sys; raise SystemExit(0 if sys.version_info >= (3, 11) else 1)";
private static readonly Regex CommandTokenRegex = new Regex("\"([^\"]*)\"|(\\S+)", RegexOptions.Compiled);

[SerializeField] private UnityResourceRagAuthMode _authMode = UnityResourceRagAuthMode.UseExistingCodexLogin;
Expand Down Expand Up @@ -267,6 +270,9 @@ public static string GetDefaultPythonCommand()
return Application.platform == RuntimePlatform.WindowsEditor ? "py" : LegacyDefaultPythonExecutable;
}

public static string RequiredPythonVersionLabel =>
string.Format("{0}.{1}+", MinimumPythonMajorVersion, MinimumPythonMinorVersion);

public static string DefaultCodexAuthFilePath()
{
string codexHome = Environment.GetEnvironmentVariable("CODEX_HOME");
Expand Down Expand Up @@ -653,6 +659,8 @@ private static IEnumerable<string> EnumeratePythonCandidates(string sidecarRepoR
{
candidates.AddRange(new[]
{
"py -3.12",
"py -3.11",
"py -3",
"py",
"python",
Expand All @@ -663,11 +671,17 @@ private static IEnumerable<string> EnumeratePythonCandidates(string sidecarRepoR
{
candidates.AddRange(new[]
{
"/opt/homebrew/bin/python3.12",
"/opt/homebrew/bin/python3.11",
"/usr/local/bin/python3.12",
"/usr/local/bin/python3.11",
"/opt/homebrew/Caskroom/miniforge/base/bin/python3",
"/opt/homebrew/bin/python3",
"/opt/homebrew/bin/python",
"/usr/local/bin/python3",
"/usr/local/bin/python",
"python3.12",
"python3.11",
"python3",
"python",
});
Expand Down Expand Up @@ -709,7 +723,7 @@ private static bool CanRunSidecarImports(string pythonExecutable, string sidecar
ProcessStartInfo startInfo = CreateCommandStartInfo(
pythonExecutable,
string.IsNullOrWhiteSpace(sidecarRepoRoot) ? Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) : sidecarRepoRoot,
new[] { "-c", "import pydantic" });
new[] { "-c", MinimumPythonVersionProbe + "; import pydantic" });
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.UseShellExecute = false;
Expand Down Expand Up @@ -755,7 +769,7 @@ private static bool CanRunBasicPythonProbe(string pythonExecutable, string sidec
ProcessStartInfo startInfo = CreateCommandStartInfo(
pythonExecutable,
string.IsNullOrWhiteSpace(sidecarRepoRoot) ? Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) : sidecarRepoRoot,
new[] { "-c", "import sys; print(sys.executable)" });
new[] { "-c", MinimumPythonVersionProbe });
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.UseShellExecute = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ private static PreparedToolRun PrepareToolRun(UnityResourceRagEditorSettings set
{
immediateFailure = new UnityResourceRagLocalToolResult
{
Error = "No Python command that can load the sidecar requirements was found. Point Python Command to an interpreter where `pip install -r requirements.txt` has already been run.",
Error = $"No Python {UnityResourceRagEditorSettings.RequiredPythonVersionLabel} command that can load the sidecar requirements was found. Point Python Command to a Python {UnityResourceRagEditorSettings.RequiredPythonVersionLabel} interpreter where `pip install -r requirements.txt` has already been run.",
};
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public static bool TryRunAsync(UnityResourceRagEditorSettings settings, Action<U

if (!UnityResourceRagEditorSettings.TryDetectBootstrapPythonExecutable(settings.SidecarRepoRoot, out string bootstrapPython))
{
error = "No base Python command was found. Make sure Python 3 is installed, then try again.";
error = $"No Python {UnityResourceRagEditorSettings.RequiredPythonVersionLabel} command was found. Install a supported Python version or set Python Command to a Python {UnityResourceRagEditorSettings.RequiredPythonVersionLabel} interpreter.";
return false;
}

Expand Down
Loading
Loading