Skip to content

Commit 6722e6a

Browse files
committed
release: v6.2.1 — lockstep dep pins + bump-version script + README audit
Fixes the CI 'Package graph (lockstep + deps)' gate (internal com.neoxider.* pins were stuck at 6.0.0 while packages were 6.2.0). Adds tools/bump_version.py to move version + pins together in lockstep with a CI-matching self-check.
1 parent ba790a9 commit 6722e6a

8 files changed

Lines changed: 136 additions & 16 deletions

File tree

Assets/CoreAI/CHANGELOG.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,26 @@
11
# Changelog
22

3+
## [6.2.1] - 2026-07-23
4+
5+
### Fixed
6+
7+
- Package **lockstep** restored: the 6.0→6.2 version bumps advanced each package's `version` but left the
8+
internal `com.neoxider.*` dependency pins at `6.0.0`, so the CI "Package graph (lockstep + deps)" gate
9+
failed with 11 mismatches. All six packages now pin the shared version. (supersedes the `v6.2.0` tag,
10+
whose published `package.json` files still carried the stale `6.0.0` pins)
11+
12+
### Added
13+
14+
- `tools/bump_version.py` — one command bumps every `Assets/*/package.json` `version` **and** every
15+
internal `com.neoxider.*` dependency pin to a target version in lockstep, then self-verifies with the
16+
same rule the CI gate enforces (`python tools/bump_version.py 6.2.1`, or `--check` to verify only).
17+
18+
### Docs
19+
20+
- Root **README** audit: corrected the package count (six, including the new **CoreAI MCP Server**
21+
package), fixed a wrong tool class name (`WorldCommandTool``WorldLlmTool` / `world_command`), and
22+
reflected the 6.2.0 features (mod runtime self-heal, vision **Detect** self-probe, Hub sub-tabs).
23+
324
## [6.2.0] - 2026-07-23
425

526
### Added

Assets/CoreAI/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "com.neoxider.coreai",
3-
"version": "6.2.0",
3+
"version": "6.2.1",
44
"displayName": "CoreAI",
55
"unity": "6000.0",
66
"description": "Portable C# core for CoreAI \u2014 LLM agents that call your game code. Orchestration, function-calling tools, agent memory, AgentBuilder, SkillSet, and production resilience (retries, timeouts, rate limits), with no UnityEngine dependency. LLM and Lua are optional modules (COREAI_NO_LLM / COREAI_NO_LUA), so the core compiles without them \u2014 install only what your game uses. Unity integration ships in com.neoxider.coreaiunity.",
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "com.neoxider.coreaibenchmark",
3-
"version": "6.2.0",
3+
"version": "6.2.1",
44
"displayName": "CoreAI Benchmark",
55
"unity": "6000.0",
66
"description": "LLM game-creation benchmark harness and scenarios for CoreAI: drives execute_lua and world_command through real PlayMode scenarios (G1-G8), grades tool correctness, reasoning, instruction adherence, and determinism, and reports suite/role fitness scores. Depends on com.neoxider.coreai / com.neoxider.coreaiunity / com.neoxider.coreaimods.",
@@ -11,8 +11,8 @@
1111
"license": "PolyForm-Noncommercial-1.0.0",
1212
"licensesUrl": "https://github.com/NeoXider/CoreAI/blob/main/LICENSE",
1313
"dependencies": {
14-
"com.neoxider.coreai": "6.2.0",
15-
"com.neoxider.coreaiunity": "6.2.0",
16-
"com.neoxider.coreaimods": "6.2.0"
14+
"com.neoxider.coreai": "6.2.1",
15+
"com.neoxider.coreaiunity": "6.2.1",
16+
"com.neoxider.coreaimods": "6.2.1"
1717
}
1818
}

Assets/CoreAIHub/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "com.neoxider.coreaihub",
3-
"version": "6.2.0",
3+
"version": "6.2.1",
44
"displayName": "CoreAI Hub (UI Toolkit)",
55
"unity": "6000.0",
66
"description": "Optional UI Toolkit window for CoreAI: a tabbed Hub that renders pages registered into CoreAI's HubPageRegistry (Chat, Settings, Statistics, Mods, and C#/Lua-authored pages). Lazy per-tab content, live tab rebuild on register/unregister, semi-transparent runtime panel, and a future path to Unity 6.5 world-space PanelRenderer. Install this package only when you want the built-in Hub window; without it CoreAI still exposes the registry so you can render pages on your own uGUI/UITK canvas via the API. Depends on com.neoxider.coreai.",
@@ -11,7 +11,7 @@
1111
"license": "PolyForm-Noncommercial-1.0.0",
1212
"licensesUrl": "https://github.com/NeoXider/CoreAI/blob/main/LICENSE",
1313
"dependencies": {
14-
"com.neoxider.coreai": "6.2.0",
15-
"com.neoxider.coreaiunity": "6.2.0"
14+
"com.neoxider.coreai": "6.2.1",
15+
"com.neoxider.coreaiunity": "6.2.1"
1616
}
1717
}

Assets/CoreAIMcp/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "com.neoxider.coreaimcp",
3-
"version": "6.2.0",
3+
"version": "6.2.1",
44
"displayName": "CoreAI MCP Server",
55
"unity": "6000.0",
66
"description": "Optional Model Context Protocol (MCP) server that runs INSIDE a live CoreAI game session (play mode or a build) so an external agent - Claude Code and any other MCP client - can drive the running game over a standard protocol. Exposes the in-game Command Bar surface (execute_lua, manage_mods, get_mod_logs, and, when present, world_command + screenshot) as MCP tools over localhost streamable HTTP. Off by default: drop a CoreAiMcpServer component into a scene (or call CoreAiMcpServer.StartServer). Localhost-only, opt-in, no auth - never expose beyond loopback. Depends on com.neoxider.coreaimods; world/screenshot tools register only when those services exist in the current composition.",
@@ -11,7 +11,7 @@
1111
"license": "PolyForm-Noncommercial-1.0.0",
1212
"licensesUrl": "https://github.com/NeoXider/CoreAI/blob/main/LICENSE",
1313
"dependencies": {
14-
"com.neoxider.coreaimods": "6.2.0",
15-
"com.neoxider.coreaiunity": "6.2.0"
14+
"com.neoxider.coreaimods": "6.2.1",
15+
"com.neoxider.coreaiunity": "6.2.1"
1616
}
1717
}

Assets/CoreAIMods/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "com.neoxider.coreaimods",
3-
"version": "6.2.0",
3+
"version": "6.2.1",
44
"displayName": "CoreAI Mods (Lua)",
55
"unity": "6000.0",
66
"description": "Lua modding layer for CoreAI: the Lua-CSharp sandbox (managed, AOT-safe, WebGL/IL2CPP-ready — bundled, no external package), execute_lua and manage_mods tools, the Lua Modding skill, the mod runtime, persistent mod stores, gameplay bindings, and mod UI. Depends on com.neoxider.coreai / com.neoxider.coreaiunity. Install this package only when you want AI/player-authored Lua mods; without it CoreAI compiles Lua-free.",
@@ -11,7 +11,7 @@
1111
"license": "PolyForm-Noncommercial-1.0.0",
1212
"licensesUrl": "https://github.com/NeoXider/CoreAI/blob/main/LICENSE",
1313
"dependencies": {
14-
"com.neoxider.coreai": "6.2.0",
15-
"com.neoxider.coreaiunity": "6.2.0"
14+
"com.neoxider.coreai": "6.2.1",
15+
"com.neoxider.coreaiunity": "6.2.1"
1616
}
1717
}

Assets/CoreAiUnity/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "com.neoxider.coreaiunity",
3-
"version": "6.2.0",
3+
"version": "6.2.1",
44
"displayName": "CoreAI Unity",
55
"unity": "6000.0",
66
"description": "Unity framework for LLM-powered NPCs and agents that call your game code \u2014 drop-in chat UI, function-calling tools, persistent memory, token-by-token streaming, and per-role LLM routing. Runs on a local GGUF model (via LLMUnity) or any OpenAI-compatible API; proven on a 4 GB local model. Unity layer for com.neoxider.coreai.",
@@ -11,6 +11,6 @@
1111
"license": "PolyForm-Noncommercial-1.0.0",
1212
"licensesUrl": "https://github.com/NeoXider/CoreAI/blob/main/LICENSE",
1313
"dependencies": {
14-
"com.neoxider.coreai": "6.2.0"
14+
"com.neoxider.coreai": "6.2.1"
1515
}
1616
}

tools/bump_version.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#!/usr/bin/env python3
2+
"""Bump every CoreAI UPM package to one version, in lockstep.
3+
4+
The repo ships six packages under Assets/*/ that release together. This sets the
5+
`version` field AND every internal `com.neoxider.*` dependency pin in each
6+
package.json to the target version, then verifies the result against the same
7+
rule the CI "Package graph (lockstep + deps)" gate enforces (one shared version,
8+
internal pins equal to it). Formatting and line endings are preserved (targeted
9+
regex, not a JSON re-dump).
10+
11+
Usage:
12+
python tools/bump_version.py 6.2.1 # write the bump to every package.json
13+
python tools/bump_version.py --check # verify lockstep only, no writes
14+
"""
15+
import glob
16+
import json
17+
import os
18+
import re
19+
import sys
20+
21+
SEMVER = re.compile(r"^\d+\.\d+\.\d+(?:-[0-9A-Za-z.]+)?$")
22+
VERSION_FIELD = re.compile(r'("version"\s*:\s*")[^"]*(")')
23+
INTERNAL_PIN = re.compile(r'("com\.neoxider\.[a-z0-9.]+"\s*:\s*")[^"]*(")')
24+
25+
26+
def package_files():
27+
return sorted(glob.glob("Assets/*/package.json"))
28+
29+
30+
def bump_file(path, version):
31+
with open(path, encoding="utf-8", newline="") as f:
32+
text = f.read()
33+
text, n_version = VERSION_FIELD.subn(r"\g<1>" + version + r"\g<2>", text, count=1)
34+
text, n_pins = INTERNAL_PIN.subn(r"\g<1>" + version + r"\g<2>", text)
35+
with open(path, "w", encoding="utf-8", newline="") as f:
36+
f.write(text)
37+
return n_version, n_pins
38+
39+
40+
def check():
41+
"""Return True when every package shares one version and every internal pin matches it."""
42+
pkgs = {}
43+
for path in package_files():
44+
with open(path, encoding="utf-8") as f:
45+
data = json.load(f)
46+
pkgs[data["name"]] = (data.get("version", ""), data.get("dependencies", {}))
47+
48+
ok = True
49+
versions = {v[0] for v in pkgs.values()}
50+
if len(versions) != 1:
51+
print(f"ERROR: package versions are not in lockstep: {sorted(versions)}")
52+
ok = False
53+
for name, (_ver, deps) in pkgs.items():
54+
for dep, dver in deps.items():
55+
if dep.startswith("com.neoxider.") and dep in pkgs and dver != pkgs[dep][0]:
56+
print(f"ERROR: {name} pins {dep}@{dver} but that package is {pkgs[dep][0]}")
57+
ok = False
58+
print("packages:", {n: v[0] for n, v in sorted(pkgs.items())})
59+
return ok
60+
61+
62+
def main(argv):
63+
# Run from the repo root regardless of the caller's cwd.
64+
os.chdir(os.path.join(os.path.dirname(os.path.abspath(__file__)), ".."))
65+
66+
if not argv or argv[0] in ("-h", "--help"):
67+
print(__doc__)
68+
return 0
69+
70+
if argv[0] == "--check":
71+
return 0 if check() else 1
72+
73+
version = argv[0].lstrip("v")
74+
if not SEMVER.match(version):
75+
print(f"ERROR: '{version}' is not a valid semver (expected e.g. 6.2.1)")
76+
return 2
77+
78+
files = package_files()
79+
if not files:
80+
print("ERROR: no Assets/*/package.json found")
81+
return 2
82+
83+
total_pins = 0
84+
for path in files:
85+
n_version, n_pins = bump_file(path, version)
86+
total_pins += n_pins
87+
print(f" {path}: version x{n_version}, internal pins x{n_pins}")
88+
print(f"bumped {len(files)} packages to {version} ({total_pins} internal pins)")
89+
90+
if not check():
91+
print("LOCKSTEP CHECK FAILED after bump")
92+
return 1
93+
print(f"LOCKSTEP CHECK PASSED for {version}")
94+
print("Next: add a CHANGELOG entry, commit, tag, and release.")
95+
return 0
96+
97+
98+
if __name__ == "__main__":
99+
sys.exit(main(sys.argv[1:]))

0 commit comments

Comments
 (0)