@aefree/pi-unity 0.9.1 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +159 -122
- package/index.ts +10 -10
- package/package.json +1 -1
- package/skills/unity-interactive-playmode-authoring/SKILL.md +1 -1
- package/skills/unity-pipeline-workflows/SKILL.md +1 -1
- package/src/unity-pipeline.ts +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project follows semantic versioning for public package releases.
|
|
7
7
|
|
|
8
|
+
## [0.9.2] - 2026-08-08
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- Allow connected Pipeline tools to exit Play Mode by default when required, while retaining session-scoped opt-out control and verified lifecycle transitions.
|
|
13
|
+
|
|
8
14
|
## [0.9.1] - 2026-08-05
|
|
9
15
|
|
|
10
16
|
### Added
|
package/README.md
CHANGED
|
@@ -1,110 +1,142 @@
|
|
|
1
1
|
# Pi Unity
|
|
2
2
|
|
|
3
|
-
Pi
|
|
4
|
-
|
|
5
|
-
## Contents
|
|
6
|
-
|
|
7
|
-
- skill: `unity-debugging`
|
|
8
|
-
- skill: `unity-pipeline-workflows`
|
|
9
|
-
- skill: `unity-batchmode-tests`
|
|
10
|
-
- skill: `unity-interactive-playmode-authoring`
|
|
11
|
-
- skill: `auditing-unity-agent-guidance`
|
|
12
|
-
- tool: `unity_guidance_audit`
|
|
13
|
-
- tool: `unity_project_status`
|
|
14
|
-
- tool: `unity_pipeline_recompile`
|
|
15
|
-
- tool: `unity_pipeline_run_tests`
|
|
16
|
-
- tool: `unity_pipeline_eval`
|
|
17
|
-
- tool: `unity_pipeline_inspect`
|
|
18
|
-
- tool: `unity_inspect_artifacts`
|
|
19
|
-
- tool: `unity_open_editor`
|
|
20
|
-
- tool: `unity_launch_batchmode`
|
|
21
|
-
- tool: `unity_run_test_batch`
|
|
22
|
-
- commands: `/unity-open`, `/unity-playmode-exit`
|
|
23
|
-
|
|
24
|
-
## Skill boundaries
|
|
25
|
-
|
|
26
|
-
Each packaged skill owns a distinct kind of Unity work:
|
|
27
|
-
|
|
28
|
-
- `unity-debugging` owns reusable diagnostic strategy across Editor, runtime, package, asset, lifecycle, callback, and feature-activation problems.
|
|
29
|
-
- `unity-pipeline-workflows` owns connected compilation and focused test execution through an already-running exact-copy Pipeline Editor.
|
|
30
|
-
- `unity-batchmode-tests` owns isolated or report-producing Unity Test Framework execution.
|
|
31
|
-
- `unity-interactive-playmode-authoring` owns explicit temporary inspection and tuning of live runtime state, followed by deliberate persistence when requested.
|
|
32
|
-
- `auditing-unity-agent-guidance` owns review and migration of project-local Unity automation instructions.
|
|
33
|
-
|
|
34
|
-
Operation-specific failure handling remains with the owning operational skill. `unity-debugging` owns reusable diagnostic strategy, not every troubleshooting instruction associated with Unity operations.
|
|
3
|
+
Pi tools and skills for reliable Unity Editor, Pipeline, batchmode, testing, and project-guidance workflows.
|
|
35
4
|
|
|
36
5
|
## Install
|
|
37
6
|
|
|
7
|
+
From npm:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pi install npm:@aefree/pi-unity
|
|
11
|
+
```
|
|
12
|
+
|
|
38
13
|
From GitHub:
|
|
39
14
|
|
|
40
15
|
```bash
|
|
41
16
|
pi install git:git@github.com:aefreedman/pi-unity.git
|
|
42
17
|
```
|
|
43
18
|
|
|
44
|
-
|
|
19
|
+
For local development:
|
|
45
20
|
|
|
46
21
|
```bash
|
|
47
22
|
pi install <path-to-pi-unity>
|
|
23
|
+
pi install -l <path-to-pi-unity> # project-local
|
|
48
24
|
```
|
|
49
25
|
|
|
50
|
-
|
|
26
|
+
Pi discovers the extension from `index.ts` and packaged skills from `skills/`.
|
|
51
27
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
28
|
+
## Included tools
|
|
29
|
+
|
|
30
|
+
### Connected Pipeline
|
|
31
|
+
|
|
32
|
+
Use these tools with an already-open exact Unity project copy that has a reachable `com.unity.pipeline` instance:
|
|
33
|
+
|
|
34
|
+
- `unity_project_status` — inspect lockfiles, matching Unity processes, Pipeline reachability, package version, and advertised commands without launching Unity.
|
|
35
|
+
- `unity_pipeline_recompile` — recompile through Pipeline with exact-copy preflight, bounded polling, and compact compiler evidence.
|
|
36
|
+
- `unity_pipeline_run_tests` — run one focused EditMode or PlayMode selection with bounded polling and aggregate results.
|
|
37
|
+
- `unity_pipeline_eval` — execute bounded project-specific C# through Pipeline's Roslyn REPL.
|
|
38
|
+
- `unity_pipeline_inspect` — dispatch supported package-owned inspection commands and return structured evidence.
|
|
39
|
+
|
|
40
|
+
Connected recompilation follows Unity's Script Changes While Playing policy and never preemptively sends `editor_stop`. Connected tests may exit Play Mode through advertised `editor_stop` when necessary, then verify Edit Mode before dispatch. Play Mode exit is allowed by default; `/unity-playmode-exit allow|disallow|status` controls the current session.
|
|
41
|
+
|
|
42
|
+
A timeout is uncertain: work may still be running. The tools do not silently cancel, retry, launch another Editor, or switch to batchmode.
|
|
43
|
+
|
|
44
|
+
### Editor and batchmode
|
|
45
|
+
|
|
46
|
+
- `unity_open_editor` — open the Unity Editor GUI.
|
|
47
|
+
- `unity_launch_batchmode` — run a bounded batchmode command through Unity CLI or the direct Editor executable.
|
|
48
|
+
- `unity_run_test_batch` — run one isolated or report-producing Unity Test Framework platform with generated XML and log paths.
|
|
49
|
+
- `unity_inspect_artifacts` — summarize existing Unity Test Framework XML and Unity logs without launching Unity.
|
|
50
|
+
|
|
51
|
+
Use connected tests when the exact project is already open and Pipeline testing is reachable. Use `unity_run_test_batch` for closed projects, CI-style isolation, categories or multiple filters, graphics-dependent PlayMode tests, or required NUnit XML/log evidence.
|
|
52
|
+
|
|
53
|
+
Batchmode runs use `-nographics` by default. Set `useGraphics: true` only for screenshots, visual capture, render checks, or graphics-dependent tests. Unity permits only one process per project folder, so all launch routes verify the exact project and use a per-project mutex.
|
|
54
|
+
|
|
55
|
+
### Guidance audit
|
|
56
|
+
|
|
57
|
+
- `unity_guidance_audit` — inspect AGENTS.md, CLAUDE.md, Copilot, and Cursor instructions for outdated or unsafe Unity automation guidance without editing them.
|
|
58
|
+
|
|
59
|
+
### Commands
|
|
60
|
+
|
|
61
|
+
- `/unity-open` — open the current Unity project copy or choose a nearby copy.
|
|
62
|
+
- `/unity-playmode-exit` — allow, disallow, or inspect Play Mode exit behavior for the current session.
|
|
63
|
+
|
|
64
|
+
## Included skills
|
|
55
65
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
-
|
|
59
|
-
- `unity-
|
|
60
|
-
-
|
|
61
|
-
-
|
|
62
|
-
-
|
|
63
|
-
|
|
64
|
-
- `
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
-
|
|
85
|
-
-
|
|
86
|
-
-
|
|
87
|
-
-
|
|
88
|
-
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
66
|
+
Each skill owns a distinct workflow:
|
|
67
|
+
|
|
68
|
+
- `unity-debugging` — evidence-first diagnosis of Editor, runtime, package, asset, lifecycle, callback, and feature-activation problems.
|
|
69
|
+
- `unity-pipeline-workflows` — connected compilation and focused tests through an already-running exact-copy Pipeline Editor.
|
|
70
|
+
- `unity-batchmode-tests` — isolated or report-producing Unity Test Framework execution.
|
|
71
|
+
- `unity-interactive-playmode-authoring` — temporary live runtime inspection and tuning followed by deliberate persistence when requested.
|
|
72
|
+
- `auditing-unity-agent-guidance` — review and migration of project-local Unity automation instructions.
|
|
73
|
+
|
|
74
|
+
Operation-specific recovery belongs to the operational skill. `unity-debugging` supplies the reusable diagnostic strategy rather than duplicating every workflow's failure handling.
|
|
75
|
+
|
|
76
|
+
## Choosing a workflow
|
|
77
|
+
|
|
78
|
+
| Situation | Preferred route |
|
|
79
|
+
| --- | --- |
|
|
80
|
+
| Open exact-copy Editor with reachable Pipeline | Connected Pipeline tools |
|
|
81
|
+
| Closed project or intentional CI isolation | `unity_run_test_batch` or `unity_launch_batchmode` |
|
|
82
|
+
| Required NUnit XML or Unity log evidence | `unity_run_test_batch` |
|
|
83
|
+
| Existing failed-run artifacts | `unity_inspect_artifacts` |
|
|
84
|
+
| Project-specific C# query or operation | `unity_pipeline_eval` |
|
|
85
|
+
| Supported structured project inspection | `unity_pipeline_inspect` |
|
|
86
|
+
| Open the GUI explicitly | `unity_open_editor` or `/unity-open` |
|
|
87
|
+
|
|
88
|
+
Pass an explicit project `path` when multiple copies may be discovered. Pipeline routing compares canonical paths so similarly named copies are not treated as interchangeable.
|
|
89
|
+
|
|
90
|
+
## Pipeline safety and evidence
|
|
91
|
+
|
|
92
|
+
The connected compile and test tools:
|
|
93
|
+
|
|
94
|
+
- require advertised commands before dispatch;
|
|
95
|
+
- verify the exact project copy and Pipeline identity;
|
|
96
|
+
- poll internally with fixed deadlines and bounded backoff;
|
|
97
|
+
- reject malformed or semantically failing nested results;
|
|
98
|
+
- require a known positive test count and zero failures before reporting a pass;
|
|
99
|
+
- discard passing-test records while retaining bounded failure diagnostics;
|
|
100
|
+
- detect pre-existing or clearly displaced test runs when available correlation fields permit it.
|
|
101
|
+
|
|
102
|
+
Another connected client is not a project lock. When Pipeline returns stable correlation fields, conflicting status is reported as displaced and uncertain. If Pipeline omits stable run identity, a competing same-mode, same-filter run may be indistinguishable from the requested run; the tool cannot prove exclusive ownership from shared Editor status alone.
|
|
103
|
+
|
|
104
|
+
### Pipeline eval
|
|
105
|
+
|
|
106
|
+
`unity_pipeline_eval` compiles C# with Roslyn and runs it on the connected Editor main thread. It is a live REPL, not an expression-only or statically read-only evaluator.
|
|
95
107
|
|
|
96
108
|
```text
|
|
97
109
|
{ code: "return UnityEditor.EditorSettings.scriptChangesDuringPlay;" }
|
|
98
110
|
{ code: "var s = UnityEngine.Application.dataPath; return s.Length;" }
|
|
99
111
|
```
|
|
100
112
|
|
|
101
|
-
Use `unity_pipeline_inspect`
|
|
113
|
+
Use `unity_pipeline_inspect` when a purpose-built structured command fits. Use eval for bounded project-specific work that matches the user's intent. Prefer typed tools when they provide stronger lifecycle, polling, validation, or recovery semantics.
|
|
114
|
+
|
|
115
|
+
## Launch and process safeguards
|
|
116
|
+
|
|
117
|
+
`unity_open_editor` and batchmode tools prefer the installed Unity CLI and can fall back to the direct Editor executable. Set `launcher` to `auto`, `unity-cli`, or `editor-executable` when explicit routing is needed.
|
|
118
|
+
|
|
119
|
+
Before launching, pi-unity checks:
|
|
120
|
+
|
|
121
|
+
- running Unity processes targeting the exact project;
|
|
122
|
+
- Unity CLI status and Pipeline instances;
|
|
123
|
+
- native `Temp/UnityLockfile` state;
|
|
124
|
+
- the package-owned per-project launch mutex.
|
|
102
125
|
|
|
103
|
-
|
|
126
|
+
Unknown process state blocks launch. Direct Editor execution blocks native lockfiles. Unity CLI may handle a stale lockfile only after pi-unity verifies that no matching Unity process remains.
|
|
127
|
+
|
|
128
|
+
A batchmode call may close a matching Unity process only when all of the following are true:
|
|
129
|
+
|
|
130
|
+
1. isolated execution was deliberately selected;
|
|
131
|
+
2. the call sets `closeBlockingUnityProcess: true`;
|
|
132
|
+
3. `piUnity.allowCloseRunningUnityProcess` is enabled;
|
|
133
|
+
4. any configured test-only restriction permits the operation.
|
|
134
|
+
|
|
135
|
+
The package selects and revalidates the process itself; it never accepts a model-supplied PID. It may remove only the exact project's stale lockfile after a same-call guarded closure and verification that no matching process remains.
|
|
104
136
|
|
|
105
137
|
## Settings
|
|
106
138
|
|
|
107
|
-
|
|
139
|
+
Pi-unity reads optional settings from global `~/.pi/agent/settings.json` and, for trusted projects, project `.pi/settings.json`:
|
|
108
140
|
|
|
109
141
|
```json
|
|
110
142
|
{
|
|
@@ -116,22 +148,43 @@ Because `eval` reaches the same engine and Editor APIs as project code, its secu
|
|
|
116
148
|
}
|
|
117
149
|
```
|
|
118
150
|
|
|
119
|
-
- `allowCloseRunningUnityProcess` defaults to `false`.
|
|
120
|
-
- `closeRunningUnityProcessOnlyForTests` defaults to `true
|
|
121
|
-
- `closeRunningUnityProcessTimeoutMs` defaults to `30000` and is clamped
|
|
151
|
+
- `allowCloseRunningUnityProcess` defaults to `false`.
|
|
152
|
+
- `closeRunningUnityProcessOnlyForTests` defaults to `true`.
|
|
153
|
+
- `closeRunningUnityProcessTimeoutMs` defaults to `30000` and is clamped from 1000 to 120000 milliseconds.
|
|
122
154
|
|
|
123
|
-
|
|
155
|
+
## Optional integrations
|
|
124
156
|
|
|
125
|
-
|
|
157
|
+
`@aefree/pi-project-artifacts` and `@aefree/pi-file-discovery` are optional peer integrations. Core Unity tools work without them.
|
|
126
158
|
|
|
127
|
-
|
|
159
|
+
Pi-unity uses a global registry rendezvous so independently installed Git, local, or npm packages can compose without sibling source paths:
|
|
128
160
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
161
|
+
- The project-artifacts integration contributes an optional Unity profile for solution and memory metadata.
|
|
162
|
+
- The file-discovery integration recommends excluding generated Unity directories from broad searches while preserving exact searches inside those directories.
|
|
163
|
+
|
|
164
|
+
The optional peer integrations are session-scoped, reverse-load-order safe, and transactional. A malformed advertised integration contract fails visibly; an unavailable optional package does not prevent the Unity extension from loading.
|
|
165
|
+
|
|
166
|
+
### Optional artifact metadata
|
|
167
|
+
|
|
168
|
+
When project artifacts are active, solution and memory Markdown may use:
|
|
169
|
+
|
|
170
|
+
```yaml
|
|
171
|
+
---
|
|
172
|
+
engine: unity
|
|
173
|
+
unity_version: "6000.0"
|
|
174
|
+
unity_packages:
|
|
175
|
+
- com.unity.inputsystem
|
|
176
|
+
render_pipeline: urp
|
|
177
|
+
platforms:
|
|
178
|
+
- windows
|
|
179
|
+
- android
|
|
180
|
+
---
|
|
132
181
|
```
|
|
133
182
|
|
|
134
|
-
|
|
183
|
+
Supported `render_pipeline` values are `builtin`, `urp`, `hdrp`, `custom`, and `agnostic`. All fields are optional, and undeclared project metadata remains open and raw-filterable.
|
|
184
|
+
|
|
185
|
+
### File-discovery filtering
|
|
186
|
+
|
|
187
|
+
Broad Unity project searches may exclude `Library`, `Temp`, `Logs`, `obj`, `Build`, `Builds`, `UserSettings`, and `.vs`. An exact generated root—including `Library/PackageCache/...`—remains searchable. Filter failures degrade filtering rather than blocking inspection.
|
|
135
188
|
|
|
136
189
|
## Package layout
|
|
137
190
|
|
|
@@ -139,58 +192,42 @@ See `evals/auditing-unity-agent-guidance/README.md` for the rubric.
|
|
|
139
192
|
pi-unity/
|
|
140
193
|
index.ts
|
|
141
194
|
src/
|
|
142
|
-
unity-
|
|
195
|
+
unity-artifact-profile.ts
|
|
143
196
|
unity-batchmode.ts
|
|
144
197
|
unity-cli.ts
|
|
198
|
+
unity-core.ts
|
|
199
|
+
unity-file-discovery-filter.ts
|
|
200
|
+
unity-guidance-audit.ts
|
|
145
201
|
unity-launch.ts
|
|
202
|
+
unity-pipeline.ts
|
|
146
203
|
unity-processes.ts
|
|
147
204
|
unity-project-lock.ts
|
|
148
205
|
unity-projects.ts
|
|
206
|
+
unity-test-batch.ts
|
|
149
207
|
skills/
|
|
150
|
-
unity-debugging/
|
|
151
|
-
SKILL.md
|
|
152
208
|
auditing-unity-agent-guidance/
|
|
153
|
-
SKILL.md
|
|
154
|
-
references/
|
|
155
|
-
assets/
|
|
156
|
-
unity-pipeline-workflows/
|
|
157
|
-
SKILL.md
|
|
158
209
|
unity-batchmode-tests/
|
|
159
|
-
|
|
210
|
+
unity-debugging/
|
|
211
|
+
unity-interactive-playmode-authoring/
|
|
212
|
+
unity-pipeline-workflows/
|
|
160
213
|
tests/
|
|
161
214
|
```
|
|
162
215
|
|
|
163
|
-
##
|
|
164
|
-
|
|
165
|
-
When `@aefree/pi-project-artifacts` is also active in a Unity workspace, solution and memory Markdown may use the following profile-enriched fields:
|
|
166
|
-
|
|
167
|
-
```yaml
|
|
168
|
-
---
|
|
169
|
-
engine: unity
|
|
170
|
-
unity_version: "6000.0"
|
|
171
|
-
unity_packages:
|
|
172
|
-
- com.unity.inputsystem
|
|
173
|
-
render_pipeline: urp
|
|
174
|
-
platforms:
|
|
175
|
-
- windows
|
|
176
|
-
- android
|
|
177
|
-
---
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
Supported `render_pipeline` values are `builtin`, `urp`, `hdrp`, `custom`, and `agnostic`. Keep `unity_version` quoted because Unity versions are identifiers rather than numeric values. Omit inapplicable fields instead of adding placeholders. These fields improve exact retrieval and diagnostics but are not required for indexing or raw filtering.
|
|
181
|
-
|
|
182
|
-
## Testing
|
|
216
|
+
## Development and validation
|
|
183
217
|
|
|
184
218
|
```bash
|
|
219
|
+
npm ci
|
|
185
220
|
npm test
|
|
186
|
-
npm pack --dry-run
|
|
221
|
+
npm pack --dry-run --json
|
|
187
222
|
```
|
|
188
223
|
|
|
189
|
-
The
|
|
224
|
+
The auditing skill also has an opt-in provider-backed behavioral eval under `evals/auditing-unity-agent-guidance/`; it is intentionally not part of `npm test`.
|
|
225
|
+
|
|
226
|
+
The registry-clean `package-lock.json` is committed. Optional development packages resolve from the public registry, and the npm archive contains no copied dependency tree, sibling `file:` dependency, or workspace link.
|
|
190
227
|
|
|
191
|
-
##
|
|
228
|
+
## Unity Pipeline project side effect
|
|
192
229
|
|
|
193
|
-
|
|
230
|
+
Starting `com.unity.pipeline@0.3.1-exp.1` assigns `Application.runInBackground = true`, which Unity persists as `PlayerSettings.runInBackground` in `ProjectSettings/ProjectSettings.asset`. Review that tracked change alongside `manifest.json` and `packages-lock.json` when installing Pipeline in a Unity project.
|
|
194
231
|
|
|
195
232
|
## License
|
|
196
233
|
|
package/index.ts
CHANGED
|
@@ -571,7 +571,7 @@ async function buildProjectStatusReport(
|
|
|
571
571
|
ctx: ExtensionContext,
|
|
572
572
|
candidate: UnityProjectCandidate,
|
|
573
573
|
signal?: AbortSignal,
|
|
574
|
-
allowAutonomousPlayModeExit =
|
|
574
|
+
allowAutonomousPlayModeExit = true,
|
|
575
575
|
): Promise<{ text: string; details: UnityToolDetails }> {
|
|
576
576
|
const lockState = await inspectUnityProjectBusyState(candidate.projectRoot);
|
|
577
577
|
const cliStatus = await listRunningUnityCliEditorsForProject(candidate.projectRoot);
|
|
@@ -597,7 +597,7 @@ async function buildProjectStatusReport(
|
|
|
597
597
|
`- Pipeline command discovery: ${cliCapabilities.commandDiscoverySucceeded ? `${cliCapabilities.advertisedCommands.length}/${cliCapabilities.advertisedCommandCount} command(s) reported${cliCapabilities.advertisedCommandsTruncated ? " (bounded/truncated)" : ""}` : cliCapabilities.commandDiscovery}`,
|
|
598
598
|
`- piUnity.allowCloseRunningUnityProcess: ${piUnitySettings.allowCloseRunningUnityProcess ? "enabled" : "disabled"}`,
|
|
599
599
|
`- piUnity.closeRunningUnityProcessOnlyForTests: ${piUnitySettings.closeRunningUnityProcessOnlyForTests ? "enabled" : "disabled"}`,
|
|
600
|
-
`- Session
|
|
600
|
+
`- Session Play Mode exit: ${allowAutonomousPlayModeExit ? "allowed" : "disabled"}`,
|
|
601
601
|
];
|
|
602
602
|
|
|
603
603
|
if (runningProcesses.length > 0) {
|
|
@@ -1192,9 +1192,9 @@ export default function freeUnityPi(pi: ExtensionAPI) {
|
|
|
1192
1192
|
// Lifecycle handles are session-scoped.
|
|
1193
1193
|
const registrations = new WeakMap<object, ScopeRegistrations>();
|
|
1194
1194
|
const playModeExitAuthorization = new WeakMap<object, boolean>();
|
|
1195
|
-
const sessionAllowsAutonomousPlayModeExit = (ctx: ExtensionContext): boolean => playModeExitAuthorization.get(ctx.sessionManager) ??
|
|
1195
|
+
const sessionAllowsAutonomousPlayModeExit = (ctx: ExtensionContext): boolean => playModeExitAuthorization.get(ctx.sessionManager) ?? true;
|
|
1196
1196
|
const restoreSessionSettings = (ctx: ExtensionContext): void => {
|
|
1197
|
-
let allowed =
|
|
1197
|
+
let allowed = true;
|
|
1198
1198
|
const getBranch = (ctx.sessionManager as { getBranch?: () => Array<{ type: string; customType?: string; data?: unknown }> }).getBranch;
|
|
1199
1199
|
for (const entry of getBranch?.call(ctx.sessionManager) ?? []) {
|
|
1200
1200
|
if (entry.type !== "custom" || entry.customType !== "pi-unity-session-settings-v1") continue;
|
|
@@ -1202,7 +1202,7 @@ export default function freeUnityPi(pi: ExtensionAPI) {
|
|
|
1202
1202
|
if (typeof data?.allowAutonomousPlayModeExit === "boolean") allowed = data.allowAutonomousPlayModeExit;
|
|
1203
1203
|
}
|
|
1204
1204
|
playModeExitAuthorization.set(ctx.sessionManager, allowed);
|
|
1205
|
-
ctx.ui.setStatus?.("pi-unity-playmode-exit", allowed ? "Unity Play Mode exit:
|
|
1205
|
+
ctx.ui.setStatus?.("pi-unity-playmode-exit", allowed ? undefined : "Unity Play Mode exit: disabled");
|
|
1206
1206
|
};
|
|
1207
1207
|
const unregisterScope = (current: ScopeRegistrations | undefined): boolean => {
|
|
1208
1208
|
if (current === undefined) return false;
|
|
@@ -1264,7 +1264,7 @@ export default function freeUnityPi(pi: ExtensionAPI) {
|
|
|
1264
1264
|
if (changed) pi.events.emit("pi-unity:capabilities-changed", { scope, contractVersion: 1, action: "unregistered" });
|
|
1265
1265
|
});
|
|
1266
1266
|
pi.registerCommand("unity-playmode-exit", {
|
|
1267
|
-
description: "Allow,
|
|
1267
|
+
description: "Allow, disable, or show Play Mode exit behavior for this Pi session (default: allowed).",
|
|
1268
1268
|
getArgumentCompletions: (prefix: string) => ["allow", "disallow", "status"]
|
|
1269
1269
|
.filter((value) => value.startsWith(prefix.trim().toLowerCase()))
|
|
1270
1270
|
.map((value) => ({ value, label: value })),
|
|
@@ -1278,8 +1278,8 @@ export default function freeUnityPi(pi: ExtensionAPI) {
|
|
|
1278
1278
|
}
|
|
1279
1279
|
const allowed = sessionAllowsAutonomousPlayModeExit(ctx);
|
|
1280
1280
|
if (action !== "status") pi.appendEntry("pi-unity-session-settings-v1", { allowAutonomousPlayModeExit: allowed });
|
|
1281
|
-
ctx.ui.setStatus?.("pi-unity-playmode-exit", allowed ? "Unity Play Mode exit:
|
|
1282
|
-
ctx.ui.notify(`
|
|
1281
|
+
ctx.ui.setStatus?.("pi-unity-playmode-exit", allowed ? undefined : "Unity Play Mode exit: disabled");
|
|
1282
|
+
ctx.ui.notify(`Unity Play Mode exit is ${allowed ? "allowed" : "disabled"} for this session.`, allowed ? "info" : "warning");
|
|
1283
1283
|
},
|
|
1284
1284
|
});
|
|
1285
1285
|
|
|
@@ -1397,7 +1397,7 @@ export default function freeUnityPi(pi: ExtensionAPI) {
|
|
|
1397
1397
|
promptSnippet: "Recompile an already-open Unity Pipeline project in one bounded connected call without shell polling.",
|
|
1398
1398
|
promptGuidelines: [
|
|
1399
1399
|
"Use unity_pipeline_recompile for connected recompilation of an already-open exact Unity project copy instead of raw Unity CLI status loops.",
|
|
1400
|
-
"unity_pipeline_recompile never sends editor_stop. In Play Mode it honors Unity's Script Changes While Playing policy
|
|
1400
|
+
"unity_pipeline_recompile never sends editor_stop. In Play Mode it honors Unity's Script Changes While Playing policy, including policies that may exit Play Mode.",
|
|
1401
1401
|
"unity_pipeline_recompile never launches, closes, saves, retries, cancels Unity, or overrides Unity's script-change policy; its timeout means the operation may still be running.",
|
|
1402
1402
|
],
|
|
1403
1403
|
parameters: PIPELINE_RECOMPILE_PARAMS,
|
|
@@ -1424,7 +1424,7 @@ export default function freeUnityPi(pi: ExtensionAPI) {
|
|
|
1424
1424
|
promptSnippet: "Run focused connected Unity EditMode or PlayMode tests in one bounded call without shell polling; aggregate passing results stay compact.",
|
|
1425
1425
|
promptGuidelines: [
|
|
1426
1426
|
"Use unity_pipeline_run_tests for one focused connected Unity test platform when the exact Editor is already open and reachable.",
|
|
1427
|
-
"unity_pipeline_run_tests
|
|
1427
|
+
"unity_pipeline_run_tests may exit Play Mode through advertised editor_stop when needed, then verifies Edit Mode before dispatching tests.",
|
|
1428
1428
|
"Use unity_run_test_batch instead of unity_pipeline_run_tests for closed projects, isolation, complex filters/categories, or required NUnit XML/log evidence.",
|
|
1429
1429
|
"unity_pipeline_run_tests does not cancel uncertain work or switch to batchmode after timeout; report that the connected run may still be running.",
|
|
1430
1430
|
],
|
package/package.json
CHANGED
|
@@ -71,7 +71,7 @@ A request to persist authorizes the durable source/asset edit, but lifecycle cha
|
|
|
71
71
|
1. Capture the final runtime values and the owning coordinate space, dimensions, scale, or other context needed to convert them into authored values.
|
|
72
72
|
2. Identify the authoritative source or serialized field and trace how it becomes the runtime value. Do not write a visual coordinate into a guessed representation.
|
|
73
73
|
3. Determine whether persistence triggers asset import, script compilation, domain reload, or runtime reconstruction, and whether the current instance can consume the change.
|
|
74
|
-
4. Inspect `editor_status`. If Play Mode must stop,
|
|
74
|
+
4. Inspect `editor_status`. If Play Mode must stop, dispatch the advertised `editor_stop` and verify Play Mode exited.
|
|
75
75
|
5. Apply the durable edit with the owning file/asset tool.
|
|
76
76
|
6. Use the `unity-pipeline-workflows` skill for any required connected compilation and terminal status validation.
|
|
77
77
|
7. Re-enter Play Mode only when requested. Report temporary live confirmation and durable verification as separate evidence.
|
|
@@ -22,7 +22,7 @@ A timeout or malformed response is uncertain: the Unity operation may still be r
|
|
|
22
22
|
|
|
23
23
|
1. Pass an explicit `path` when multiple project copies may be found; paths identify copies, not display names.
|
|
24
24
|
2. The typed tools require a reachable exact-copy Pipeline and advertised `editor_status` plus operation commands. A different connected client is not itself a project lock.
|
|
25
|
-
3.
|
|
25
|
+
3. `unity_pipeline_recompile` never sends `editor_stop` or overrides Unity's Script Changes While Playing preference. Known recompile-and-continue, stop-and-recompile, and defer policies proceed according to Unity's configured behavior. Pipeline 0.4 does not currently expose that preference, so the tool reports the unavailable policy while allowing recompilation to proceed. `unity_pipeline_run_tests` may dispatch advertised `editor_stop` when needed, then verifies Edit Mode before running tests. The tools never enter Play Mode, pause, save, launch, or close Unity; recompilation may perform Unity's normal asset refresh/import and script-change behavior.
|
|
26
26
|
4. Test success requires a well-formed terminal result, a known positive executed count, and zero failures. An asynchronous initiation with `Total: 0` and `running` is nonterminal.
|
|
27
27
|
5. Passing test records are intentionally discarded. Failures retain only a bounded set of failed/inconclusive names, messages, and stack excerpts.
|
|
28
28
|
|
package/src/unity-pipeline.ts
CHANGED
|
@@ -316,7 +316,7 @@ async function executeCommand(deps: PipelineDependencies, projectRoot: string, c
|
|
|
316
316
|
if (deadline !== undefined) ensureBeforeDeadline(deadline, now, command);
|
|
317
317
|
return result;
|
|
318
318
|
}
|
|
319
|
-
async function requirePreflight(deps: PipelineDependencies, projectRoot: string, unityVersion: string, commands: string[], operation: "recompile" | "tests", signal: AbortSignal | undefined, deadline: number, now: () => number, allowAutonomousExitPlayMode =
|
|
319
|
+
async function requirePreflight(deps: PipelineDependencies, projectRoot: string, unityVersion: string, commands: string[], operation: "recompile" | "tests", signal: AbortSignal | undefined, deadline: number, now: () => number, allowAutonomousExitPlayMode = true): Promise<{ capabilities: UnityCliProjectCapabilities; exitedPlayMode: boolean; playModeHandling: UnityPipelinePlayModeHandling; scriptChangesWhilePlaying?: UnityScriptChangesWhilePlayingPolicy }> {
|
|
320
320
|
const capabilities = await inspectWithDeadline(deps, projectRoot, unityVersion, signal, deadline, now, "preflight");
|
|
321
321
|
const error = capabilityError(capabilities, commands); if (error) throw new Error(error);
|
|
322
322
|
let editor = await executeCommand(deps, projectRoot, "editor_status", [], signal, deadline, now);
|
|
@@ -335,13 +335,13 @@ async function requirePreflight(deps: PipelineDependencies, projectRoot: string,
|
|
|
335
335
|
const policyDescription = policy === "stop_and_recompile"
|
|
336
336
|
? "Unity's Script Changes While Playing policy may stop Play Mode to recompile"
|
|
337
337
|
: "Pipeline editor_status does not expose Unity's Script Changes While Playing policy, so recompilation may continue, defer, or stop Play Mode";
|
|
338
|
-
if (!allowAutonomousExitPlayMode) throw new Error(`${policyDescription};
|
|
338
|
+
if (!allowAutonomousExitPlayMode) throw new Error(`${policyDescription}; Play Mode exit is disabled for this session, so recompile was not started.`);
|
|
339
339
|
// RecompileCommand owns AssetDatabase.Refresh. Do not preempt it with editor_stop or override Unity's policy.
|
|
340
340
|
playModeHandling = policy === "stop_and_recompile" ? "unity_policy_may_exit" : "policy_unknown";
|
|
341
341
|
}
|
|
342
342
|
} else if (status.lifecycle !== "compatible") {
|
|
343
|
-
// Test execution has separate lifecycle semantics: stop explicitly
|
|
344
|
-
if (!allowAutonomousExitPlayMode) throw new Error("Unity Editor is in Play Mode or paused;
|
|
343
|
+
// Test execution has separate lifecycle semantics: stop explicitly, then verify Edit Mode.
|
|
344
|
+
if (!allowAutonomousExitPlayMode) throw new Error("Unity Editor is in Play Mode or paused; Play Mode exit is disabled for this session, so tests were not started.");
|
|
345
345
|
const stopError = capabilityError(capabilities, ["editor_stop"]); if (stopError) throw new Error(stopError);
|
|
346
346
|
const stopped = await executeCommand(deps, projectRoot, "editor_stop", [], signal, deadline, now);
|
|
347
347
|
if (stopped.error) throw new Error("Unity Pipeline editor_stop failed; tests were not started and Play Mode state is uncertain.");
|