com.elestrago.unity.package-tools 2.4.0 → 2.5.1

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/CAHNGELOG.md CHANGED
@@ -2,6 +2,35 @@
2
2
 
3
3
  ---
4
4
 
5
+ ## [2.5.1](https://gitlab.com/elestrago-pkg/package-tool/-/tags/2.5.1)
6
+
7
+ ### Changed
8
+
9
+ - Broadened `unity-package-release` skill triggers to cover generic commit phrasings such as "commit all changes".
10
+
11
+ ---
12
+
13
+ ## [2.5.0](https://gitlab.com/elestrago-pkg/package-tool/-/tags/2.5.0)
14
+
15
+ ### Added
16
+
17
+ - Added `examples` section to `unity-package-docs` driven by `[CreateAssetMenu]`/`[MenuItem]`/public-static API entry points, one chunk per entry under `Documentation~/examples/`.
18
+
19
+ ### Changed
20
+
21
+ - Made `CommandLineTools`, `GitTools`, `PackageInitializeTemplates`, `PackageInitializeUtil`, and `GitTools.Run` non-public so the supported entry points are `CIUtils.Generate` and `Tools/PackageTools/Init Package`.
22
+
23
+ ### Removed
24
+
25
+ - Removed `samples` section from `unity-package-docs` (replaced by `examples`).
26
+
27
+ ### Fixed
28
+
29
+ - Fixed `unity-package-docs` scanner missing expression-bodied methods (`... => Body();`).
30
+ - Fixed broken nested-type anchor references in `Documentation~/manual.md` (e.g. `PackageManifestConfig.CopyEntry`).
31
+
32
+ ---
33
+
5
34
  ## [2.4.0](https://gitlab.com/elestrago-pkg/package-tool/-/tags/2.4.0)
6
35
 
7
36
  ### Added
@@ -0,0 +1,41 @@
1
+ <!-- generated by unity-package-docs; safe to regenerate -->
2
+
3
+ # Package Tool — Example: CIUtils.Generate
4
+
5
+ **Kind:** static-method
6
+
7
+ **Entry point:** [CIUtils](../api.md#ciutils)
8
+
9
+ **Declared at:** `Assets/Package/PackageTool/Editor/CIUtils.cs:65`
10
+
11
+ ## What it does
12
+
13
+ The CI entry point. Reads `id=<guid>[,<guid>...]`, `version=<semver>`, `preview=<bool>`, and `generateversionconstants=<bool>` from the command line (case-insensitive `key=value` pairs), filters the [PackageManifestConfig](../api.md#packagemanifestconfig) assets to process, optionally overrides each config's `packageVersion`, optionally runs [CodeGenTools.GenerateVersionConstants](../api.md#codegentools), and exports the package source via [FileTools.CreateOrUpdatePackageSource](../api.md#filetools). Wraps the work in `LockReloadAssemblies` + `StartAssetEditing` to avoid mid-export refreshes.
14
+
15
+ ## Snippet
16
+
17
+ ```bash
18
+ # Headless build — call from CI after PrepareDll has fixed plugin flags.
19
+ "$UNITY_PATH" \
20
+ -batchmode \
21
+ -quit \
22
+ -projectPath "$PROJECT_PATH" \
23
+ -executeMethod PackageTool.CIUtils.Generate \
24
+ -id ea4351b5-3f49-4afc-8996-ec7b9eb43204 \
25
+ -version 2.4.1 \
26
+ -generateversionconstants true \
27
+ -logFile -
28
+ ```
29
+
30
+ ```csharp
31
+ // Or invoke directly from an editor script — Generate() reads -id / -version /
32
+ // -generateversionconstants from Environment.GetCommandLineArgs itself.
33
+ PackageTool.CIUtils.Generate();
34
+ ```
35
+
36
+ ## Observable effect
37
+
38
+ - `Release/<packageName>/` is created or updated with the exported package layout (sources, package.json, README, CHANGELOG, LICENSE, Samples~, Documentation~).
39
+ - `Release/package.json` is rewritten with the version, dependencies, and samples block derived from the config.
40
+ - If `generateversionconstants=true`, a new `VersionConstants.cs` is emitted at the configured path before export.
41
+ - Console prints `[Package Tools]` lines summarizing what was processed; the editor does not exit (unlike `PrepareDll`).
@@ -0,0 +1,47 @@
1
+ <!-- generated by unity-package-docs; safe to regenerate -->
2
+
3
+ # Package Tool — Example: Create a PackageManifestConfig
4
+
5
+ **Kind:** create-asset
6
+
7
+ **Entry point:** [PackageManifestConfig](../api.md#packagemanifestconfig)
8
+
9
+ **Declared at:** `Assets/Package/PackageTool/Editor/PackageManifestConfig.cs:37`
10
+
11
+ **Create menu:** `Assets > Create > JCMG/PackageTools/PackageManifestConfig`
12
+
13
+ ## What it does
14
+
15
+ Creates the ScriptableObject that drives every other entry point — package name, version, sources, dependencies, samples, and the destination path the **Export Package Source** inspector button and `CIUtils.Generate` both read. One config asset per Unity package; everything else (CHANGELOG, README, asmdef wiring, exported `package.json`) is derived from its fields.
16
+
17
+ ## Snippet
18
+
19
+ ```csharp
20
+ using PackageTool;
21
+ using UnityEditor;
22
+ using UnityEngine;
23
+
24
+ public static class CreatePackageManifestConfigExample
25
+ {
26
+ [MenuItem("Tools/Examples/Create PackageManifestConfig")]
27
+ public static void Run()
28
+ {
29
+ var config = ScriptableObject.CreateInstance<PackageManifestConfig>();
30
+ config.packageName = "com.example.foo";
31
+ config.displayName = "Example Foo";
32
+ config.packageVersion = "0.1.0";
33
+ config.unityVersion = "2021.3";
34
+ config.sourcePath = "Assets/Package/Foo";
35
+ config.packageDestinationPath = "Release";
36
+
37
+ AssetDatabase.CreateAsset(config, "Assets/PackageManifest/PackageManifestConfig.asset");
38
+ AssetDatabase.SaveAssets();
39
+ }
40
+ }
41
+ ```
42
+
43
+ ## Observable effect
44
+
45
+ - A new asset appears at `Assets/PackageManifest/PackageManifestConfig.asset`.
46
+ - Selecting it in the Project view renders the inspector with **Generate VersionConstants.cs**, **Export Package Source**, and **Export as Legacy Package** buttons.
47
+ - The same `Assets > Create > JCMG/PackageTools/PackageManifestConfig` menu entry yields the same asset interactively if you prefer GUI.
@@ -0,0 +1,30 @@
1
+ <!-- generated by unity-package-docs; safe to regenerate -->
2
+
3
+ # Package Tool — Example: Init Package
4
+
5
+ **Kind:** menu-item
6
+
7
+ **Entry point:** [MenuItems](../api.md#menuitems)
8
+
9
+ **Declared at:** `Assets/Package/PackageTool/Editor/MenuItems.cs:9`
10
+
11
+ **Menu path:** `Tools/PackageTools/Init Package`
12
+
13
+ ## What it does
14
+
15
+ Opens the **Init Package** editor window ([PackageInitializeWindow](../api.md#packageinitializewindow)), which scaffolds a new Unity package: creates `Assets/Package/<scope>/` with `Editor/` (and optionally `Runtime/`), root files (`README.md`, `CAHNGELOG.md`, `LICENSE`), `Documentation~/`, and a sibling `PackageManifestConfig.asset` populated from the form's fields. The internal helpers that do the on-disk work are intentionally not part of the public surface — the window is the supported entry point.
16
+
17
+ ## Snippet
18
+
19
+ ```csharp
20
+ // MenuItems is internal, so other assemblies can't invoke OpenAboutModalDialog
21
+ // directly. Open the window via PackageInitializeWindow.Open(), or use the menu.
22
+ PackageTool.Utils.PackageInitialize.PackageInitializeWindow.Open();
23
+ // Or interactively: Tools > PackageTools > Init Package
24
+ ```
25
+
26
+ ## Observable effect
27
+
28
+ - The **Init Package** editor window opens. Fill in package name, display name, scope, author, license, and unity version, then click **Create**.
29
+ - On Create: `Assets/Package/<scope>/` and `Assets/PackageManifest/PackageManifestConfig.asset` are written; the inspector for the new config asset shows the **Generate VersionConstants.cs** / **Export Package Source** / **Export as Legacy Package** buttons.
30
+ - The project compiles after the next assembly reload.
@@ -0,0 +1,39 @@
1
+ <!-- generated by unity-package-docs; safe to regenerate -->
2
+
3
+ # Package Tool — Example: PrepareDll
4
+
5
+ **Kind:** menu-item
6
+
7
+ **Entry point:** [CIUtils](../api.md#ciutils)
8
+
9
+ **Declared at:** `Assets/Package/PackageTool/Editor/CIUtils.cs:197`
10
+
11
+ **Menu path:** `Tools/PackageTools/PrepareDll`
12
+
13
+ ## What it does
14
+
15
+ Fixes the platform flags on every plugin (`.dll`) under the configured package source before export, so the published package's `PluginImporter` settings match what the Editor needs (no spurious `Any Platform` toggles that would otherwise leak into consumers). When the `CI` environment variable is set, the method calls `EditorApplication.Exit` with code 0 on success or 1 on failure — designed to be the final step of a batch-mode build before the export job moves on.
16
+
17
+ ## Snippet
18
+
19
+ ```bash
20
+ # Run from CI or any shell — replace UNITY_PATH and PROJECT_PATH with your values.
21
+ "$UNITY_PATH" \
22
+ -batchmode \
23
+ -quit \
24
+ -projectPath "$PROJECT_PATH" \
25
+ -executeMethod PackageTool.CIUtils.PrepareDll \
26
+ -logFile -
27
+ # Or interactively: Tools > PackageTools > PrepareDll
28
+ ```
29
+
30
+ ```csharp
31
+ // Same call from an editor script (no Exit when CI env var is unset):
32
+ PackageTool.CIUtils.PrepareDll();
33
+ ```
34
+
35
+ ## Observable effect
36
+
37
+ - Every `.dll` under each `PackageManifestConfig.sourcePath` has its `PluginImporter` flags normalized; meta files are rewritten as a result and may show up in `git status`.
38
+ - Console prints `[Package Tools]` log lines for each plugin touched.
39
+ - In CI (`CI=1` or similar), the editor exits 0 on success or 1 if any plugin processing throws — wire this into your pipeline as the gate before `CIUtils.Generate`.
@@ -0,0 +1,25 @@
1
+ <!-- generated by unity-package-docs; safe to regenerate -->
2
+
3
+ # Package Tool — Examples
4
+
5
+ Short, focused usage examples that exercise this package's public API. Each example is independent and links into the API reference (`api.md`) for the type or member it calls. Snippets are paste-ready and use only public API — copy one into a fresh project to reach the same observable effect.
6
+
7
+ ## Quick start
8
+
9
+ Start with **Create a PackageManifestConfig** to produce the config asset that drives every other entry point, then run **Tools > PackageTools > Init Package** (`init-package`) to scaffold a new package skeleton against it. For automated builds, **CIUtils.Generate** is the batch-mode entry point and **Tools > PackageTools > PrepareDll** (`preparedll`) is the DLL platform-flag fix-up step that typically runs immediately before it.
10
+
11
+ ## Contents
12
+
13
+ | Example | Kind | Entry point |
14
+ |---------|------|-------------|
15
+ | [Create a PackageManifestConfig](examples/create-packagemanifestconfig.md) | create-asset | [PackageManifestConfig](api.md#packagemanifestconfig) |
16
+ | [Init Package](examples/init-package.md) | menu-item | [MenuItems](api.md#menuitems) |
17
+ | [PrepareDll](examples/preparedll.md) | menu-item | [CIUtils](api.md#ciutils) |
18
+ | [CIUtils.Generate](examples/ciutils-generate.md) | static-method | [CIUtils](api.md#ciutils) |
19
+
20
+ This package also ships Unity samples importable from Package Manager → Package Tool → Samples → `Example Sample`, `Claude Skills`. Those samples are not duplicated here — import them via Package Manager if you want the full asset content.
21
+
22
+ ## Notes
23
+
24
+ - The `PackageTool.Tools.*` (`CommandLineTools`, `GitTools`) and `PackageTool.Utils.PackageInitialize.*` (`PackageInitializeTemplates`, `PackageInitializeUtil`) helpers were public in earlier revisions and dropped to `internal` to make the public surface intentional. They still exist and are used by `CIUtils.Generate`/`Init Package` internally; they're just no longer documented as consumer-facing entry points.
25
+ - All entry points listed here are editor-only (single asmdef `Playdarium.PackageTool.Editor`, `includePlatforms: ["Editor"]`); call them from editor scripts or batch mode, not from runtime code.
@@ -64,16 +64,16 @@ Defined at `Assets/Package/PackageTool/Editor/PackageManifestConfig.cs:37`. Crea
64
64
  - **Package json metadata:** `homepage`, `packageName`, `displayName`, `packageVersion`, `unityVersion`, `description`, `category`, `license`, `keywords` (`string[]`), `author` (`Author`), `dependencies` (`Dependency[]`).
65
65
  - **Package content paths:** `sourcePath`, `documentationPath` (default `Documentation~`), `readmePath` (default `README.md`), `changelogPath` (default `CHANGELOG.md`), `licensePath` (default `LICENSE`), `packageIgnorePaths` (`string[]`).
66
66
  - **Export targets:** `packageDestinationPath`, `legacyPackageDestinationPath`.
67
- - **Staging:** `samples` ([`Sample[]`](api.md#sample)), `copyEntries` ([`CopyEntry[]`](api.md#packagemanifestconfigcopyentry)).
67
+ - **Staging:** `samples` ([`Sample[]`](api.md#sample)), `copyEntries` ([`CopyEntry[]`](api.md#packagemanifestconfig-copyentry)).
68
68
  - **Code generation:** `versionConstantsPath`, `versionConstantsNamespace`.
69
69
  - **Hidden:** `_id` (Guid; surfaced via `Id` property; used by `CIUtils.Generate id=<guid>` filtering).
70
70
 
71
71
  Nested `[Serializable]` types, each with a `PropertyDrawer` in `PackageTool.Drawers`:
72
72
 
73
73
  - [`Author`](api.md#author) — `name`, `email`, `url` (`string`).
74
- - [`Dependency`](api.md#packagemanifestconfigdependency) — `packageName`, `packageVersion` (`string`); `IsEmpty()` is true when either is blank.
74
+ - [`Dependency`](api.md#packagemanifestconfig-dependency) — `packageName`, `packageVersion` (`string`); `IsEmpty()` is true when either is blank.
75
75
  - [`Sample`](api.md#sample) — `sourcePath`, `displayName`, `description`, `folderName` (`string`); `IsEmpty()` is true when any of `displayName`/`sourcePath`/`folderName` is blank. Resulting on-disk path is `{packageDestinationPath}/Samples~/{folderName}`.
76
- - [`CopyEntry`](api.md#packagemanifestconfigcopyentry) — `sourcePath`, `destinationPath` (`string`); `IsEmpty()` is true when `sourcePath` is blank. See **Copy Entries staging** below.
76
+ - [`CopyEntry`](api.md#packagemanifestconfig-copyentry) — `sourcePath`, `destinationPath` (`string`); `IsEmpty()` is true when `sourcePath` is blank. See **Copy Entries staging** below.
77
77
 
78
78
  ### Export pipeline
79
79
 
@@ -89,7 +89,7 @@ Nested `[Serializable]` types, each with a `PropertyDrawer` in `PackageTool.Draw
89
89
 
90
90
  ### Copy Entries staging
91
91
 
92
- `copyEntries` is a `PackageManifestConfig` field added in 2.0.12. Each [`CopyEntry`](api.md#packagemanifestconfigcopyentry) names a source path and a destination folder; entries run **first** in the export pipeline (step 4 above) so downstream steps — including the recursive source copy and the `CopySamplesToDirectory` step — can pick up the staged content and ship it into `packageDestinationPath`.
92
+ `copyEntries` is a `PackageManifestConfig` field added in 2.0.12. Each [`CopyEntry`](api.md#packagemanifestconfig-copyentry) names a source path and a destination folder; entries run **first** in the export pipeline (step 4 above) so downstream steps — including the recursive source copy and the `CopySamplesToDirectory` step — can pick up the staged content and ship it into `packageDestinationPath`.
93
93
 
94
94
  **Folder source.** The folder's *content* is merged directly into `destinationPath` (no `destinationPath/{sourceName}` wrapper). Same-named files are overwritten via `File.Copy(..., overwrite: true)`; unrelated files already in the destination are left in place. This is the merge semantics needed to chain into a `Sample` whose `sourcePath` is the same folder.
95
95
 
@@ -30,7 +30,7 @@ namespace PackageTool.Tools
30
30
  /// <summary>
31
31
  /// Helper methods for command-line usage
32
32
  /// </summary>
33
- public static class CommandLineTools
33
+ internal static class CommandLineTools
34
34
  {
35
35
  // Command-Line Delimiters
36
36
  private const string ARGUMENT_DELIMITER_STR = "=";
@@ -65,4 +65,4 @@ namespace PackageTool.Tools
65
65
  return dict;
66
66
  }
67
67
  }
68
- }
68
+ }
@@ -30,11 +30,15 @@ namespace PackageTool.Tools
30
30
  /// <summary>
31
31
  /// Helper methods for retrieving git information
32
32
  /// </summary>
33
- public static class GitTools
33
+ internal static class GitTools
34
34
  {
35
35
  private const string GIT_APPLICATION = "git";
36
36
 
37
- public static string Run(string cmd)
37
+ public static string GetBranch() => Run("rev-parse --abbrev-ref HEAD");
38
+
39
+ public static string GetLongHeadHash() => Run("rev-parse HEAD");
40
+
41
+ private static string Run(string cmd)
38
42
  {
39
43
  // NOTE: This currently expects that you have git included in your PATH.
40
44
  var p = new Process();
@@ -52,15 +56,5 @@ namespace PackageTool.Tools
52
56
 
53
57
  return output;
54
58
  }
55
-
56
- public static string GetBranch()
57
- {
58
- return Run("rev-parse --abbrev-ref HEAD");
59
- }
60
-
61
- public static string GetLongHeadHash()
62
- {
63
- return Run("rev-parse HEAD");
64
- }
65
59
  }
66
- }
60
+ }
@@ -2,7 +2,7 @@ using System;
2
2
 
3
3
  namespace PackageTool.Utils.PackageInitialize
4
4
  {
5
- public static class PackageInitializeTemplates
5
+ internal static class PackageInitializeTemplates
6
6
  {
7
7
  public static string CreateChangelog(string homepage) => @$"# Changelog
8
8
 
@@ -4,7 +4,7 @@ using UnityEngine;
4
4
 
5
5
  namespace PackageTool.Utils.PackageInitialize
6
6
  {
7
- public static class PackageInitializeUtil
7
+ internal static class PackageInitializeUtil
8
8
  {
9
9
  public const string ASSETS_FOLDER_NAME = "Assets";
10
10
  public const string RELEASE_FOLDER_NAME = "Release";
package/README.md CHANGED
@@ -29,7 +29,7 @@ Add the package to `Packages/manifest.json`:
29
29
  }
30
30
  ],
31
31
  "dependencies": {
32
- "com.elestrago.unity.package-tools": "2.4.0"
32
+ "com.elestrago.unity.package-tools": "2.5.1"
33
33
  }
34
34
  }
35
35
  ```
@@ -60,7 +60,7 @@ CIUtils.Generate();
60
60
 
61
61
  - [Manual](Documentation~/manual.md) — concepts and architecture.
62
62
  - [API Reference](Documentation~/api.md) — every public type and member.
63
- - [Samples](Documentation~/samples.md) — how the sample project in this repo uses the package.
63
+ - [Examples](Documentation~/examples.md) — short usage examples for the public API.
64
64
 
65
65
  ## License
66
66
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: unity-package-docs
3
- description: Create or update AI-first documentation for a Unity package at the repository root — README.md plus Documentation~/manual.md, api.md, samples.md, all structured for dense AI ingestion with explicit file paths and explicit mapping between the package source and the sample project. Auto-chunks large API/manual/samples by namespace/section to keep navigation intact. Use when the user wants to generate or refresh Unity package docs from source. Works in any Unity package repo with one package per repo (discovered via package.json, with a fallback to PackageManifestConfig.asset for package-tool-based projects).
3
+ description: Create or update AI-first documentation for a Unity package at the repository root — README.md plus Documentation~/manual.md, api.md, examples.md, all structured for dense AI ingestion with explicit file paths and explicit links from each usage example into the API reference. Auto-chunks large API/manual by namespace/section, and emits one chunk per public API entry point (each `[CreateAssetMenu]`, `[MenuItem]`, and public static entry-point method) under Documentation~/examples/ as a focused short snippet, so a consumer reading the published docs learns how to call the package without importing Samples~/ via Package Manager. Use when the user wants to generate or refresh Unity package docs from source. Works in any Unity package repo with one package per repo (discovered via package.json, with a fallback to PackageManifestConfig.asset for package-tool-based projects).
4
4
  ---
5
5
 
6
6
  # unity-package-docs
@@ -15,12 +15,16 @@ Files created/updated at the repository root — **never** inside the package fo
15
15
  <repo-root>/
16
16
  ├── README.md
17
17
  └── Documentation~/
18
- ├── manual.md
19
- ├── api.md
20
- └── samples.md
18
+ ├── manual.md (or manual/<slug>.md chunks when over threshold)
19
+ ├── api.md (or api/<Namespace>.md chunks when over threshold)
20
+ ├── examples.md (always an index — see below)
21
+ └── examples/
22
+ └── <slug>.md (one chunk per public API entry point)
21
23
  ```
22
24
 
23
- The `Documentation~` folder name MUST include the trailing tilde (Unity convention — excludes it from asset import). Pre-existing files inside `Documentation~/` (e.g. screenshots) are left untouched; only the three `.md` files listed are managed.
25
+ The `Documentation~` folder name MUST include the trailing tilde (Unity convention — excludes it from asset import). Pre-existing files inside `Documentation~/` (e.g. screenshots) are left untouched; only the managed `.md` files (and their parent dirs under `manual/`, `api/`, `examples/`) are managed.
26
+
27
+ `examples.md` is always a small index linking to per-entry-point chunks. Each chunk under `examples/<slug>.md` is a short usage example (1 paragraph + ≤ ~20-line snippet) that calls into the public API documented in `api.md`. This is distinct from Unity's `Samples~/` folder, which the package author may ship for Package Manager → Samples → Import; the docs do **not** embed `Samples~/` source verbatim — examples are curated for "how do I use this API?", and `README.md` carries a one-line pointer at the available Unity samples for anyone who wants the importable content.
24
28
 
25
29
  Every generated `.md` file begins with this exact marker on line 1:
26
30
 
@@ -34,8 +38,8 @@ Every generated `.md` file begins with this exact marker on line 1:
34
38
  2. **Predictable structure.** Use the exact section names and order specified in each step below. Same anchor slugs every run so agents crawling multiple package docs can rely on the shape.
35
39
  3. **Explicit paths everywhere.** Every reference to source code uses `path/to/File.cs` relative to the repo root, with `:line` when pointing at a specific declaration. Never write "see the inspector class" — write `see Assets/Package/.../Inspectors/Foo.cs:33`.
36
40
  4. **Complete, tagged code blocks.** Every fenced block has a language tag (` ```csharp `, ` ```json `, ` ```yaml `, ` ```bash `). Snippets are paste-ready — no `// ...` elisions that lose context.
37
- 5. **Explicit package sample mapping.** In `samples.md`, every sample file is mapped to the exact package type(s) it instantiates or extends, with file paths on both sides. An agent reading the docs must be able to write equivalent code in a fresh project.
38
- 6. **No forward references to undocumented things.** If `manual.md` mentions a type, that type appears in `api.md` with a stable anchor. `samples.md` links into `api.md` rather than re-describing types.
41
+ 5. **Examples link into the API.** In `examples.md` and its chunks, every code example is anchored on a discoverable public API entry point (a `[CreateAssetMenu]`, `[MenuItem]`, or public static entry method) and links into the corresponding `api.md` anchor. Snippets are short, paste-ready, and call only public API. An agent reading the docs must be able to take any example, paste it into a fresh project, and reach the same observable effect.
42
+ 6. **No forward references to undocumented things.** If `manual.md` mentions a type, that type appears in `api.md` with a stable anchor. `examples.md` and chunks link into `api.md` rather than re-describing types.
39
43
 
40
44
  ## Skill args
41
45
 
@@ -44,8 +48,8 @@ Parse from the user input (default values shown):
44
48
  - `force=false` — when `true`, overwrite files even if they lack the generator marker.
45
49
  - `dry-run=false` — when `true`, print the would-be output to the conversation without writing any files.
46
50
  - `package=<path>` — override package-root auto-discovery (for repos with multiple packages or a non-standard layout).
47
- - `chunk-threshold-lines=800` — when a rendered Documentation~ file's draft exceeds this many lines, the file is split into chunks (see Step 3.5). Below the threshold, output is identical to today's single-file form. Set very high (e.g. `100000`) to disable chunking entirely.
48
- - `chunk-threshold-api=<n>`, `chunk-threshold-manual=<n>`, `chunk-threshold-samples=<n>` — per-file overrides of `chunk-threshold-lines`. Each defaults to the global value.
51
+ - `chunk-threshold-lines=800` — when a rendered `api.md` or `manual.md` draft exceeds this many lines, the file is split into chunks (see Step 3.5). Below the threshold, output is the single-file form. Set very high (e.g. `100000`) to disable chunking for those two files. **Does not gate `examples.md`** — examples are always per-entry-point chunked (see Step 6); the granularity is fixed by the API surface, not by line count.
52
+ - `chunk-threshold-api=<n>`, `chunk-threshold-manual=<n>` — per-file overrides of `chunk-threshold-lines`. Each defaults to the global value. `chunk-threshold-samples` and `chunk-threshold-examples` are accepted for backward compatibility but ignored.
49
53
 
50
54
  ## Pipeline (execute these steps in order)
51
55
 
@@ -86,7 +90,7 @@ From `package.json` (preferred) or `PackageManifestConfig.asset`, extract:
86
90
  | Samples | `samples` (array of `{path, displayName, description}`) | `samples` (array of `{sourcePath, folderName, displayName, description}`) |
87
91
  | Registry | `publishConfig.registry` | (not in config; omit) |
88
92
 
89
- For the config fallback, the **sample source paths** on disk are taken from `samples[].sourcePath`. For `package.json` projects, the on-disk sample paths are inside the package dir at `<package-root>/Samples~/<folderName>` (only present if previously exported); if absent, scan `Assets/Samples/`, `Samples/`, and `Assets/Example/` as fallback candidates.
93
+ The `samples[]` block is read for **README only** it drives the one-line Unity Samples~/ pointer described in Step 7 ("This package ships the following Package Manager samples: …"). It does NOT drive any content under `Documentation~/`. The docs section is `examples`, generated from the public API surface in Step 6, not from `Samples~/` files. Earlier revisions of this skill mirrored `Samples~/` source into the docs; that's been deprecated because the embedded source is duplicative of what Package Manager Samples → Import already provides, and most `Samples~/` content (scenes, prefabs, internal post-import scripts) doesn't teach API usage.
90
94
 
91
95
  ### Step 3 — Scan source
92
96
 
@@ -95,10 +99,11 @@ Run the bundled Python scanner. Its absolute path is `${SKILL_DIR}/scripts/scan_
95
99
  ```bash
96
100
  python3 "${SKILL_DIR}/scripts/scan_package.py" \
97
101
  --package "<package-root>" \
98
- --samples "<sample-dir-1>" --samples "<sample-dir-2>" \
99
102
  --repo-root .
100
103
  ```
101
104
 
105
+ The scanner still accepts `--samples <dir>` (and emits `samples[]` in its output) for backward compatibility, but **do not pass it** in this revision — the `examples` pipeline (Step 6) derives chunks from the public API surface (`types[]`, member `attributes`), not from `samples[]`. If `samples[]` happens to be non-empty in a stale invocation, the pipeline ignores it.
106
+
102
107
  The scanner emits JSON to stdout with this shape:
103
108
 
104
109
  ```json
@@ -127,38 +132,47 @@ The scanner emits JSON to stdout with this shape:
127
132
  ]
128
133
  }
129
134
  ],
130
- "samples": [
131
- {"path": "Assets/.../Foo.cs", "kind": "script", "namespace": "...", "packageTypesReferenced": ["Foo", "Bar"], "md5": "…", "lines": 42},
132
- {"path": "Assets/.../Scene.unity", "kind": "scene|prefab", "scriptsReferenced": [{"guid": "...", "resolvedTo": "Assets/.../Foo.cs"}], "md5": "…", "lines": 85}
133
- ]
135
+ "samples": []
134
136
  }
135
137
  ```
136
138
 
137
- Notes on the new `md5` / `lines` / `files` fields (added in this revision):
139
+ Notes on the `md5` / `lines` / `files` fields:
138
140
 
139
141
  - `files[]` lists every `.cs` file under the package root that the scanner read, with the MD5 of its raw bytes and its line count. Multiple types from the same file share the same MD5, so this list is the canonical per-file view; `types[i].md5` is a denormalized convenience.
140
142
  - `md5` is over **raw bytes** (no CRLF↔LF normalization). A line-ending swap counts as a change, which is intentional — if the bytes differ at all, the doc should be regenerated.
141
- - `samples[]` carries `md5`/`lines` only for individual sample files (scripts, scenes, prefabs). The scanner does not roll these up into the package `files[]` list.
143
+ - `samples[]` is present in the scanner's output schema but, in this revision of the skill, is not consumed by any step downstream of Step 3. Treat the field as legacy.
142
144
 
143
145
  Capture this JSON; the rest of the pipeline consumes it.
144
146
 
145
147
  ### Step 3.5 — Plan chunking
146
148
 
147
- For each Documentation~ file (`api.md`, `manual.md`, `samples.md`), decide whether to emit it as a single file or as a chunk index plus per-chunk files. Decision procedure:
149
+ `api.md` and `manual.md` use a size-gated decision; `examples.md` is always chunked, one chunk per discovered entry point.
150
+
151
+ **For `api.md` and `manual.md`:**
148
152
 
149
- 1. **Render to an in-memory buffer first.** Run the full Step 4/5/6 rendering logic into a string. Count its lines (`\n`-separated, EOF-trimmed).
150
- 2. **Resolve the threshold** for this file: use the file-specific arg if supplied (`chunk-threshold-api`, `chunk-threshold-manual`, `chunk-threshold-samples`), else the global `chunk-threshold-lines` (default 800).
153
+ 1. **Render to an in-memory buffer first.** Run the full Step 4/5 rendering logic into a string. Count its lines (`\n`-separated, EOF-trimmed).
154
+ 2. **Resolve the threshold** for this file: use the file-specific arg if supplied (`chunk-threshold-api`, `chunk-threshold-manual`), else the global `chunk-threshold-lines` (default 800).
151
155
  3. **Apply the structural floor.** Skip chunking even when the threshold is exceeded if the file is structurally unsplittable:
152
156
  - `api.md`: chunk only when `namespaces.length > 1`.
153
- - `samples.md`: chunk only when the sample mapping covers more than one file (i.e. `samples.length > 1`).
154
157
  - `manual.md`: chunk only when at least one H2 section in the draft individually exceeds the threshold. (Splitting a single oversized section yields no benefit.)
155
- 4. **Decide:** if `linesDrafted > threshold` AND the structural floor passes → **chunked**; else → **single-file** (write the draft as-is at Step 4/5/6's write step).
158
+ 4. **Decide:** if `linesDrafted > threshold` AND the structural floor passes → **chunked**; else → **single-file** (write the draft as-is at Step 4/5's write step).
159
+
160
+ **For `examples.md`: always chunked, one chunk per public API entry point.** No threshold check. The chunk set is computed directly from the scanner manifest's `types[]`/members, not from any line-count heuristic.
156
161
 
157
162
  For each file decided to chunk, plan the chunk set:
158
163
 
159
164
  - `api.md` → one chunk per namespace: `Documentation~/api/<Namespace>.md` (literal namespace, no slugification — e.g. `Documentation~/api/PackageTool.Tools.md`). Do NOT sub-split a single huge namespace.
160
- - `samples.md` → one chunk per top-level sample folder: `Documentation~/samples/<SampleFolderName>.md`. Sanitize `<SampleFolderName>` to `[A-Za-z0-9._-]` (replace any other character with `-`).
161
165
  - `manual.md` → one chunk per H2 section using this fixed slug set: `overview.md`, `architecture.md`, `assemblies.md`, `entry-points.md`, `data-model.md`, `editor-ui.md`, `extension-points.md` (these correspond 1:1 to the H2 sections in `manual.md.template`). Sections that render empty are omitted from the chunk set.
166
+ - `examples.md` → one chunk per discovered entry point. Enumerate, in this order (`exampleKind` shown in parens):
167
+ 1. **`[CreateAssetMenu]` types** (`exampleKind = create-asset`). Source: every `types[i]` with `attributes` containing `CreateAssetMenu(...)`. Slug = `create-` + `<TypeName>` lowercased + sanitized to `[a-z0-9-]`.
168
+ 2. **`[MenuItem]` methods** (`exampleKind = menu-item`). Source: every `members[]` member with an attribute matching `MenuItem("<path>")`. Slug = the last `/`-separated segment of the menu path, lowercased + sanitized to `[a-z0-9-]` (spaces collapse to `-`). Example: `Tools/PackageTools/Init Package` → `init-package`.
169
+ 3. **Public static entry-point methods** (`exampleKind = static-method`). Source: every `members[]` method on a `public static` type, with the method itself `public static`, that is NOT also already produced by rules 1 or 2 above. Slug = `<TypeName-lower>-<MethodName-lower>` sanitized. Example: `CIUtils.Generate` → `ciutils-generate`.
170
+
171
+ Chunk paths: `Documentation~/examples/<slug>.md` (flat directory, single level — no nesting). Disambiguation: if two entry points produce the same slug, append `-2`, `-3`, … in discovery order. Print one line per discovered example, e.g. `example-plan: create-packagemanifestconfig ← PackageManifestConfig [CreateAssetMenu]`.
172
+
173
+ Cap: if more than 20 candidates result from rule 3 (rare in tightly-scoped editor tools, common in libraries with many public statics), emit the first 20 sorted by `TypeName, MethodName` and warn `example-plan: capped at 20 static-method entry points (N skipped). Hand-author additional chunks under Documentation~/examples/ as needed (marker-gated, preserved on regen).`
174
+
175
+ **Sample inputs the skill should NOT promote to examples** (avoid noise): private/internal members, methods with `[Obsolete]`, partial-class internals, generated code (files under `Generated/`). Filter these out before the rules above.
162
176
 
163
177
  Build a **`crossRefMap`**: `{ typeAnchor → "<destination-relative-to-Documentation~>#<anchor>" }`, populated during the api decision:
164
178
 
@@ -167,13 +181,13 @@ Build a **`crossRefMap`**: `{ typeAnchor → "<destination-relative-to-Documenta
167
181
 
168
182
  `crossRefMap` is consumed by Steps 5 and 6 when emitting `[Type](…)` references. Renderers MUST NOT hard-code `api.md` in link destinations — always resolve via `crossRefMap`.
169
183
 
170
- Print one line per file decision, e.g. `chunk-plan: api.md → chunked (12 namespaces, draft=2143 lines, threshold=800)` or `chunk-plan: samples.md → single (draft=78 lines)`.
184
+ Print one line per file decision. Examples: `chunk-plan: api.md → chunked (12 namespaces, draft=2143 lines, threshold=800)`, `chunk-plan: manual.md → single (draft=312 lines)`, `chunk-plan: examples.md → chunked (always: 7 entry points → 7 chunks under Documentation~/examples/)`.
171
185
 
172
186
  ### Step 3.6 — Fast-update check (api only)
173
187
 
174
188
  Before rendering, build a **`skipSet`** of api outputs that can be left untouched because their underlying source files are bit-for-bit identical to the last run. This is an optimization, not a correctness step — skipping is always safe to opt out of (and is automatically opted out of below in well-defined situations).
175
189
 
176
- The check only applies to `api.md` and its chunks. `manual.md` and `samples.md` are skipped here because their content is synthesized across many files (manual) or driven by sample-side bytes already covered by `samples[i].md5` (samplesleft as future work; do not skip samples in this revision).
190
+ The check only applies to `api.md` and its chunks. `manual.md` is skipped here because its content is synthesized across many files. `examples.md` and its chunks are skipped because each example chunk is small and re-deriving it from the manifest is cheapadding fast-update for examples is left as future work.
177
191
 
178
192
  Procedure for **each** prospective api output (the single `api.md` in the single-file branch, or each `api/<Namespace>.md` in the chunked branch):
179
193
 
@@ -189,13 +203,13 @@ Print one line per check, e.g. `fast-update: api/PackageTool.Tools.md → skippe
189
203
 
190
204
  Steps 4/5/6 honor `skipSet` as follows:
191
205
 
192
- - An output path in `skipSet` is **not rewritten** — the existing file is preserved verbatim, and `crossRefMap` (which was built in Step 3.5 from the scanner manifest, independent of the existing file) is still used for downstream links from `manual.md` and `samples.md`. This works because anchors are derived from type names, which are part of the manifest, not parsed from the existing api file.
206
+ - An output path in `skipSet` is **not rewritten** — the existing file is preserved verbatim, and `crossRefMap` (which was built in Step 3.5 from the scanner manifest, independent of the existing file) is still used for downstream links from `manual.md` and `examples.md`. This works because anchors are derived from type names, which are part of the manifest, not parsed from the existing api file.
193
207
  - Stale-chunk removal (Steps 4/5/6) still runs over the full chunk directory; `skipSet` only governs *re-rendering*, not stale cleanup.
194
208
  - The Step 8 verifier still walks every emitted `.md` (including skipped ones), so a stale api file with a missing anchor is still caught.
195
209
 
196
210
  ### Step 4 — Render `Documentation~/api.md` first
197
211
 
198
- Render this file first because `manual.md` and `samples.md` link into its anchors (via `crossRefMap` from Step 3.5) and you want those anchors to exist.
212
+ Render this file first because `manual.md` and `examples.md` link into its anchors (via `crossRefMap` from Step 3.5) and you want those anchors to exist.
199
213
 
200
214
  Read `${SKILL_DIR}/assets/api.md.template`. Replace `{{displayName}}` with the discovered value. Replace `{{namespaceContentsList}}` with a bulleted index of namespaces, each linking to its anchor. Replace `{{perNamespaceSections}}` with one section per namespace following the structure documented in the template's HTML comment block.
201
215
 
@@ -240,7 +254,14 @@ Read `${SKILL_DIR}/assets/manual.md.template`. Fill each placeholder:
240
254
  - `{{editorUiProse}}` — Detect IMGUI vs UI Toolkit by checking for `.uxml`/`.uss` files under the package root and for types inheriting `EditorWindow` / `PropertyDrawer` / `UnityEditor.Editor`. State which approach is used and list representative file paths.
241
255
  - `{{extensionPointsList}}` — Public abstract types, public virtual methods, types ending in `Base`, or those marked `partial`. If none, write `None.`.
242
256
 
243
- **Resolving `[Type](…)` links.** When rendering any link to a package type, look it up in `crossRefMap` (built in Step 3.5). Use the value verbatim. Do NOT hard-code `api.md#anchor`. If the link is emitted from a manual chunk file (chunked branch), the value must be prefixed with `../` (because chunks live under `manual/`); the renderer prepends `../` to every `crossRefMap` value when emitting from a chunk file, and emits the bare value when emitting from the index-level `manual.md`. Same rule applies to samples in Step 6.
257
+ **Resolving `[Type](…)` links.** When rendering any link to a package type, look it up in `crossRefMap` (built in Step 3.5). Use the value verbatim, then prefix it based on the *depth* of the emitting file under `Documentation~/`:
258
+
259
+ - Top-level index files (`Documentation~/api.md`, `Documentation~/manual.md`, `Documentation~/examples.md`): depth 0, no prefix — emit the bare `crossRefMap` value.
260
+ - `Documentation~/manual/<slug>.md`: depth 1, prepend `../`.
261
+ - `Documentation~/api/<Namespace>.md`: depth 1, prepend `../`.
262
+ - `Documentation~/examples/<slug>.md`: depth 1, prepend `../`.
263
+
264
+ The depth rule generalizes for any future nesting: `depth = (number of "/" segments in the chunk path under Documentation~) - 1`, and the renderer prepends `"../" * depth`. Do NOT hard-code `api.md#anchor` anywhere — always go through `crossRefMap` + depth-prefix. Same rule applies to Step 6 example chunks.
244
265
 
245
266
  **Output (single-file branch, default):** if Step 3.5 decided manual is single-file, write the rendered draft to `Documentation~/manual.md` as-is.
246
267
 
@@ -250,27 +271,58 @@ Read `${SKILL_DIR}/assets/manual.md.template`. Fill each placeholder:
250
271
  2. **One index** at `Documentation~/manual.md` containing the generator marker, the H1 (`# {{displayName}} — Manual`), a `## Contents` Markdown table (`| Section | Description |`) linking each chunk (one row per emitted slug; description = the first sentence of that section's body), and one-line `## Notes`: `This manual is split by section; see files under \`manual/\`.`
251
272
  3. **Stale chunks:** before writing, list `Documentation~/manual/*.md`. For each existing file that starts with the generator marker and is NOT in the current chunk set, delete it and print `Removed stale: <path>`.
252
273
 
253
- ### Step 6 — Render `Documentation~/samples.md`
274
+ ### Step 6 — Render `Documentation~/examples.md` + per-entry-point chunks
275
+
276
+ `examples.md` is always emitted as a light **index**, with one chunk per public API entry point under `Documentation~/examples/<slug>.md`. The chunk set is computed in Step 3.5.
277
+
278
+ **Why examples, not sample-source mirroring.** Unity's `Samples~/` is shipped via Package Manager → Samples → Import; the source is reachable that way for anyone who wants the full importable content. Embedding `Samples~/` source verbatim under `Documentation~/` is duplicative and inflates what every consumer downloads. The high-value docs content is "**how do I use this package's API**" — short snippets that exercise a single entry point and link into `api.md` for the deeper reference. That is what every chunk under `Documentation~/examples/` is: a focused, paste-ready usage example.
279
+
280
+ #### Render the index — `Documentation~/examples.md`
281
+
282
+ Read `${SKILL_DIR}/assets/examples.md.template` (the index template). Fill placeholders:
283
+
284
+ - `{{contentsTableRows}}` — One Markdown table row per chunk: `| [<title>](examples/<slug>.md) | <exampleKind> | <entry-point> |` where:
285
+ - `<title>` is the human-readable title (see chunk titling below).
286
+ - `<exampleKind>` is `create-asset`, `menu-item`, or `static-method` from Step 3.5.
287
+ - `<entry-point>` is the link into `api.md` for the type or member, rendered via the bare `crossRefMap` value (depth 0).
288
+ - `{{quickStartProse}}` — one short paragraph (≤ 4 sentences) framing how a downstream consumer should approach these examples: each one is independent, all snippets target the public API only, and every example has a single observable effect listed in its chunk. If there is exactly one `[CreateAssetMenu]` and one `[MenuItem]`-tagged entry point, mention them by name as the recommended starting points.
289
+ - `{{samplesNote}}` — if the package declares any Unity `Samples~/` entries (`samples[]` in `package.json` or the config asset is non-empty), render a one-line paragraph: ``This package also ships Unity samples importable from Package Manager → <displayName> → Samples → `<sample1.displayName>`, `<sample2.displayName>`. Those samples are not duplicated here — import them via Package Manager if you want the full asset content.`` Otherwise omit the paragraph entirely (the placeholder expands to an empty line).
290
+ - `{{notesList}}` — conventions worth knowing at the index level. If none, write `None.`.
291
+
292
+ Type links in the index use the bare `crossRefMap` value (depth 0).
293
+
294
+ Write `Documentation~/examples.md`.
295
+
296
+ #### Render the per-entry-point chunks — `Documentation~/examples/<slug>.md`
297
+
298
+ For each entry point from Step 3.5, read `${SKILL_DIR}/assets/examples-chunk.md.template` and fill it. The chunk path is `Documentation~/examples/<slug>.md` (flat single level).
254
299
 
255
- Read `${SKILL_DIR}/assets/samples.md.template`. Fill placeholders:
300
+ Placeholders:
256
301
 
257
- - `{{sampleTree}}` — ASCII tree of the discovered sample dir(s), one line per file.
258
- - `{{sampleMappingSections}}` — One `### path` subsection per sample file, following the structure documented in the template's HTML comment. For scripts, list referenced package types as links resolved through `crossRefMap` (Step 3.5). For scenes/prefabs, list resolved script GUIDs as links resolved through `crossRefMap`.
259
- - `{{reproductionProse}}` One paragraph explaining how a downstream user reproduces the sample setup from scratch.
260
- - `{{reproductionSnippet}}` — Paste-ready `csharp` snippet using only public API documented in api.md (or its chunks). If the sample is empty, omit the snippet section entirely and write a stub (see edge cases).
261
- - `{{notesList}}` — Any sample-only conventions worth knowing.
302
+ - `{{displayName}}` — package display name.
303
+ - `{{exampleTitle}}` — the human-readable title:
304
+ - `create-asset`: `Create a <TypeName>` (e.g. `Create a PackageManifestConfig`).
305
+ - `menu-item`: derive from the last menu-path segment, Title-Cased (e.g. `Init Package`, `Prepare DLLs`).
306
+ - `static-method`: `<TypeName>.<MethodName>` (e.g. `CIUtils.Generate`).
307
+ - `{{exampleKind}}` — `create-asset` | `menu-item` | `static-method`.
308
+ - `{{entryPointLink}}` — link into `api.md` for the target type or member, via the depth-prefixed `crossRefMap` value (depth 1, prepend `../`). For `create-asset` and `static-method`, target the **type** anchor. For `menu-item`, target the type that declares the method (the method itself doesn't get its own anchor in `api.md`, but its `Line` shows up in the type's Members table).
309
+ - `{{sourceRef}}` — `**Declared at:** \`path:line\`` pointing at the underlying member (for menu-item) or type (for create-asset / static-method). For menu-item, also include the menu path: `**Menu path:** \`Tools/PackageTools/Init Package\``. For create-asset, include the `menuName` argument from the attribute: `**Create menu:** \`Assets > Create > <menuName>\``.
310
+ - `{{exampleProse}}` — 1-3 short sentences: what this entry point does, what observable effect to expect, and (where relevant) which other public types it commonly composes with. Avoid restating what's in `api.md`; the link covers that. The reader should come away knowing **when** to call this entry point and **why**.
311
+ - `{{exampleSnippet}}` — a fenced code block (`csharp` for create-asset and static-method; `csharp` or `bash` for menu-item depending on context — see below). ≤ ~20 lines. Uses **only** public API from the package and Unity. Paste-ready: complete `using` directives at the top if the snippet would not compile without them, no `// ...` elisions.
312
+ - `create-asset`: snippet shows the API call (`ScriptableObject.CreateInstance<T>()` + minimal field setup + `AssetDatabase.CreateAsset(...)`) as the programmatic equivalent of the menu entry. Prefer this over describing the menu click — agents need code.
313
+ - `menu-item`: when the menu does work the consumer might also want to script (e.g. CI/CLI), emit a `csharp` snippet calling the same method directly. When the menu is GUI-only (opens a window, runs an editor flow that requires user input), emit a `bash` snippet showing how to invoke it via Unity batch mode (`Unity -batchmode -quit -executeMethod <TypeName>.<MethodName> ...`) and a 1-line note `// Or interactively: <Menu path>`.
314
+ - `static-method`: snippet shows a direct call to the method with believable arguments, plus the surrounding setup needed to make the call compile.
315
+ - `{{observableEffectList}}` — bulleted list of what the consumer will see/find after running the snippet (`- <project>/Assets/.../Foo.asset is created`, `- A new package skeleton appears at <packageDestinationPath>/<packageName>/`, `- The console prints \`[Package Tools]\` Done. lines`, etc.). 1-4 bullets.
262
316
 
263
- **Resolving `[Type](…)` links.** Same rule as Step 5: look up every type link in `crossRefMap`. From chunked output, prepend `../` (chunks live under `samples/`); from the index-level `samples.md`, emit the bare value.
317
+ Type links inside chunk files use the **depth-prefixed** `crossRefMap` value per Step 5's rule (i.e. `../api.md#foo` for the single-file api branch, or `../api/PackageTool.Tools.md#foo` for the chunked branch).
264
318
 
265
- **Edge case — empty sample:** if no sample files exist (the dir is empty or absent), emit a single-file `Documentation~/samples.md` with the `<!-- generated -->` marker, the H1, and a single section: `## No sample content` containing one sentence: `No sample content present. Add files under \`<expected sample path>\` and re-run this skill.`. Do not fail and do not chunk.
319
+ #### Stale chunks
266
320
 
267
- **Output (single-file branch, default):** if Step 3.5 decided samples is single-file, write the rendered draft to `Documentation~/samples.md` as-is.
321
+ Before writing, list `Documentation~/examples/*.md` (flat, no recursion — examples chunks live one level deep). For each existing `.md` file that starts with the generator marker and is **not** in the current chunk set, delete it and print `Removed stale: <path>`. Files without the marker are left in place and a warning is printed; same rule as elsewhere — never silently destroy hand-edited content. Hand-authored chunks the maintainer added (without the marker) are preserved across re-runs and remain linked from the index only if they're explicitly added to `{{contentsTableRows}}` by hand — the auto-generator does not enumerate non-marker files.
268
322
 
269
- **Output (chunked branch):** if Step 3.5 decided samples is chunked, group sample files by their **top-level sample folder** (the first path segment under the sample root, e.g. `Assets/Example/Sample/Foo.cs` → folder `Sample`) and emit:
323
+ #### Edge case no entry points
270
324
 
271
- 1. **One chunk per top-level sample folder** at `Documentation~/samples/<SampleFolderName>.md` (sanitized to `[A-Za-z0-9._-]`). Each chunk contains the generator marker on line 1, H1 `# {{displayName}} Samples: <SampleFolderName>`, the per-sample `### path` subsections that belong to that folder, the per-folder `## Reproducing the Sample` prose + snippet, and `## Notes`. Inside chunks, `crossRefMap` link values are prefixed with `../`.
272
- 2. **One index** at `Documentation~/samples.md` containing the generator marker, H1, the global `## Sample Layout` tree, a `## Contents` Markdown table (`| Sample | Description |`) linking each chunk, and `## Notes`: `Samples are split by sample folder; see files under \`samples/\`.`
273
- 3. **Stale chunks:** before writing, list `Documentation~/samples/*.md`. For each existing file that starts with the generator marker and is NOT in the current chunk set, delete it and print `Removed stale: <path>`.
325
+ If the API surface yields zero entry points across rules 1-3 (rare; would mean no `[CreateAssetMenu]`, no `[MenuItem]`, and no public-static-method on a public type), emit only the index `Documentation~/examples.md` with the generator marker, the H1, the `{{samplesNote}}` line if applicable, and a single section `## No public entry points detected` containing one sentence: ``This package exposes no `[CreateAssetMenu]`, `[MenuItem]`, or public static entry-point methods. Hand-author example chunks under `Documentation~/examples/` describing how a downstream consumer should compose the public types in `api.md`.`` Do not create the `Documentation~/examples/` directory in this case.
274
326
 
275
327
  ### Step 7 — Render `README.md`
276
328
 
@@ -285,6 +337,7 @@ Read `${SKILL_DIR}/assets/README.md.template`. Fill placeholders:
285
337
  2. Else the first class with a `[MenuItem]` method → describe the menu path.
286
338
  3. Else the first public static method on a public type → describe a direct call.
287
339
  - `{{gettingStartedSnippet}}` — minimal `csharp` snippet exercising the primary entry point.
340
+ - `{{unitySamplesBullets}}` — if `samples[]` (from Step 2 metadata) is non-empty, render one bullet per declared Unity sample: ``- **<displayName>** — <description>. Import via Package Manager → <package displayName> → Samples → Import.`` If `samples[]` is empty or absent, replace the entire `## Unity Samples` section's content (including the placeholder line) with the single line `None — this package does not ship importable samples.` Use the README template's `{{unitySamplesSection}}` block guard if you prefer; the goal either way is a stable, predictable shape.
288
341
  - `{{licensePath}}` — path to the root `LICENSE` file (typically `LICENSE`).
289
342
 
290
343
  Write `README.md` at the repo root.
@@ -293,10 +346,11 @@ Write `README.md` at the repo root.
293
346
 
294
347
  After all files (including any chunks) are written:
295
348
 
296
- 1. Grep `README.md` for `Documentation~/manual.md`, `Documentation~/api.md`, `Documentation~/samples.md`. Confirm each file exists. Abort with a clear error if any link is broken. (These three top-level paths are unchanged whether the file is single or chunked — when chunked the file is a Contents-table index, but the path still resolves.)
297
- 2. Walk every emitted `.md` under `Documentation~/` (index files and chunk files). For each `[Type](…)` link extract the destination path (relative to the link's own file) and anchor. Resolve the destination to an absolute path under `Documentation~/`; confirm the file exists and contains an `### {anchor}` heading (case-insensitive, hyphen-normalized per Markdown's auto-slug rule). Print warnings (not errors) for any broken anchors. Replaces the legacy "grep `api.md#`" check, which is no longer sufficient because anchors now live in either `api.md` or `api/<Namespace>.md`.
298
- 3. Confirm every generated file — including every chunk under `Documentation~/api/`, `Documentation~/manual/`, `Documentation~/samples/` — starts with the generator marker on line 1.
349
+ 1. Grep `README.md` for `Documentation~/manual.md`, `Documentation~/api.md`, `Documentation~/examples.md`. Confirm each file exists. Abort with a clear error if any link is broken. (These three top-level paths are unchanged whether the file is single or chunked — when chunked the file is a Contents-table index, but the path still resolves.)
350
+ 2. Walk every emitted `.md` under `Documentation~/` (index files and chunk files: `api/<Namespace>.md`, `manual/<slug>.md`, `examples/<slug>.md`). For each `[Type](…)` link extract the destination path (relative to the link's own file) and anchor. Resolve the destination to an absolute path under `Documentation~/`; confirm the file exists and contains an `### {anchor}` heading (case-insensitive, hyphen-normalized per Markdown's auto-slug rule). Print warnings (not errors) for any broken anchors.
351
+ 3. Confirm every generated file — including every chunk under `Documentation~/api/`, `Documentation~/manual/`, and `Documentation~/examples/` — starts with the generator marker on line 1.
299
352
  4. Confirm no chunk file outside the current chunk set survived (the stale-removal in Steps 4/5/6 should have deleted them; this is a safety re-check).
353
+ 5. For each chunk in `Documentation~/examples/`, confirm the example snippet block (` ```csharp ` or ` ```bash `) is present and non-empty. This catches the regression where a chunk would be written without its snippet body.
300
354
 
301
355
  Print a summary: which files were created vs updated, which were skipped (and why), and which chunks were removed as stale.
302
356
 
@@ -312,11 +366,12 @@ For each output file:
312
366
 
313
367
  ### Stale chunks
314
368
 
315
- Chunk files (under `Documentation~/api/`, `Documentation~/manual/`, `Documentation~/samples/`) follow the same marker-on-line-1 contract as top-level generated files. Additionally:
369
+ Chunk files (under `Documentation~/api/`, `Documentation~/manual/`, `Documentation~/examples/`) follow the same marker-on-line-1 contract as top-level generated files. Additionally:
316
370
 
317
- 4. **Stale removal (marker-gated).** Before writing the chunk set for an area, list every `.md` file in that area's chunk directory. For each existing file that **starts with the generator marker** AND is **not in the current chunk set**, delete it and print `Removed stale: <path>`. Files without the marker are left in place and a warning is printed (matches rule 3 — never silently destroy hand-edited content).
318
- 5. **Mode flip (single ↔ chunked).** When a Documentation~ file flips from chunked to single-file between runs (e.g. the user removes namespaces until the threshold is no longer exceeded), every file in that area's chunk directory is treated as stale by rule 4: marker-bearing chunks are deleted, marker-absent files are warned about. The chunk directory itself is left in place even when empty (Unity treats empty directories as no-ops; do not `rmdir`).
319
- 6. **Force.** `force=true` extends rules 3 and 4 marker-absent files are overwritten (rule 3) and marker-absent chunks are also deleted when stale (rule 4 extension), matching the existing semantics for top-level files.
371
+ 4. **Stale removal (marker-gated).** Before writing the chunk set for an area, list every `.md` file in that area's chunk directory (flat — all three chunk dirs are single-level). For each existing file that **starts with the generator marker** AND is **not in the current chunk set**, delete it and print `Removed stale: <path>`. Files without the marker are left in place and a warning is printed (matches rule 3 — never silently destroy hand-edited content). Hand-authored example chunks (no marker) are preserved across re-runs; they show up under `examples/` but are not linked from `examples.md`'s auto-generated Contents table unless the maintainer adds the row by hand.
372
+ 5. **Mode flip (single ↔ chunked).** Applies to `api.md` and `manual.md` only — `examples.md` is always chunked and never flips. When `api.md` or `manual.md` flips from chunked to single-file between runs (e.g. the user removes namespaces until the threshold is no longer exceeded), every file in that area's chunk directory is treated as stale by rule 4: marker-bearing chunks are deleted, marker-absent files are warned about. The chunk directory itself is left in place even when empty (Unity treats empty directories as no-ops; do not `rmdir` api/manual dirs).
373
+ 6. **Migration from the legacy samples layout.** If `Documentation~/samples.md` or any path under `Documentation~/samples/` exists at the start of a run, delete every marker-bearing file in that tree and print `Removed legacy: <path>`. After deletion, `rmdir` any emptied directories under `Documentation~/samples/` and then the dir itself if empty. Files without the marker (i.e. hand-authored content the maintainer placed under `Documentation~/samples/`) are left alone and a warning is printed; the maintainer can move them under `Documentation~/examples/` manually. This migration runs once-per-repo — once the legacy paths are gone, subsequent runs see nothing to delete.
374
+ 7. **Force.** `force=true` extends rules 3 and 4 — marker-absent files are overwritten (rule 3) and marker-absent chunks are also deleted when stale (rule 4 extension), matching the existing semantics for top-level files.
320
375
 
321
376
  The pipeline as a whole is idempotent: re-running on an unchanged repo produces a no-op diff.
322
377
 
@@ -0,0 +1,40 @@
1
+ <!-- generated by unity-package-docs; safe to regenerate -->
2
+
3
+ # {{displayName}} — Example: {{exampleTitle}}
4
+
5
+ **Kind:** {{exampleKind}}
6
+
7
+ **Entry point:** {{entryPointLink}}
8
+
9
+ {{sourceRef}}
10
+
11
+ ## What it does
12
+
13
+ {{exampleProse}}
14
+
15
+ ## Snippet
16
+
17
+ {{exampleSnippet}}
18
+
19
+ ## Observable effect
20
+
21
+ {{observableEffectList}}
22
+
23
+ <!--
24
+ Slug rule (Step 3.5):
25
+ create-asset → create-<TypeName-lower> e.g. create-packagemanifestconfig
26
+ menu-item → <last-menu-path-segment-slug> e.g. init-package
27
+ static-method → <TypeName-lower>-<MethodName-lower> e.g. ciutils-generate
28
+
29
+ Snippet rule (Step 6 chunk section):
30
+ create-asset → ```csharp ... ScriptableObject.CreateInstance<T>() + AssetDatabase.CreateAsset(...) ...
31
+ menu-item → ```csharp direct call if the method is callable from code,
32
+ else ```bash with `Unity -batchmode -quit -executeMethod ...`.
33
+ Add a one-line `// Or interactively: <Menu path>` comment in either case.
34
+ static-method → ```csharp direct call with believable arguments + minimal compile-ready surroundings.
35
+
36
+ ≤ ~20 lines. No `// ...` elisions. `using` directives included when the snippet would not compile without them.
37
+
38
+ Hand-edit this chunk freely — it has the generator marker, so a re-run will overwrite it.
39
+ To preserve manual edits, delete the marker on line 1 (the regen will then skip-with-warning and your version stays).
40
+ -->
@@ -0,0 +1,36 @@
1
+ <!-- generated by unity-package-docs; safe to regenerate -->
2
+
3
+ # {{displayName}} — Examples
4
+
5
+ Short, focused usage examples that exercise this package's public API. Each example is independent and links into the API reference (`api.md`) for the type or member it calls. Snippets are paste-ready and use only public API — copy one into a fresh project to reach the same observable effect.
6
+
7
+ ## Quick start
8
+
9
+ {{quickStartProse}}
10
+
11
+ ## Contents
12
+
13
+ | Example | Kind | Entry point |
14
+ |---------|------|-------------|
15
+ {{contentsTableRows}}
16
+
17
+ <!--
18
+ One row per chunk under Documentation~/examples/<slug>.md.
19
+ Row format:
20
+ | [<title>](examples/<slug>.md) | create-asset | menu-item | static-method | [<TypeName>](crossRefMap[TypeName]) |
21
+
22
+ `<entry-point>` column links into api.md (depth 0, bare crossRefMap value).
23
+ For menu-item, the entry-point link targets the **type** that declares the
24
+ method (the method itself is shown in that type's Members table at the
25
+ referenced line).
26
+
27
+ Hand-authored chunks (no generator marker) are preserved across regens but
28
+ do NOT appear in this auto-generated table — add their rows by hand if you
29
+ want them indexed.
30
+ -->
31
+
32
+ {{samplesNote}}
33
+
34
+ ## Notes
35
+
36
+ {{notesList}}
@@ -128,7 +128,11 @@ METHOD_RE = re.compile(
128
128
  r"(?P<generic><[^>]*>)?\s*"
129
129
  r"\((?P<params>[^)]*)\)\s*"
130
130
  r"(?:where\s+[^{;=]+)?"
131
- r"\s*(?:[{;=]|=>)?\s*$"
131
+ # Accept any of: nothing (open brace on next line), `;` (declaration only / abstract),
132
+ # `{ … }` (single-line body), or `=> …;` (expression-bodied method, possibly with the
133
+ # whole right-hand side on the same line). Without `=>.*`, the regex misses
134
+ # `internal static void X() => Y();`-style declarations.
135
+ r"\s*(?:\{.*|;|=>.*)?\s*$"
132
136
  )
133
137
 
134
138
  PROPERTY_RE = re.compile(
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: unity-package-release
3
- description: Cut a release commit for any Unity package that uses the `com.elestrago.unity.package-tools` editor tool (the one that drives a `PackageManifestConfig` ScriptableObject and exports via the **Export Package Source** Inspector button). Discovers the config asset, package name, changelog filename, README install snippet, and publish flow at runtime via `scripts/discover_package.py`, so the same skill works in every package-tool consumer regardless of layout. Bumps the SO's `packageVersion`, updates the consumer-install version line in the project-root README (if one exists), prepends or appends an entry to the changelog (whatever filename the config's `changelogPath` resolves to), prompts the maintainer to run **Export Package Source** in Unity so the exported `Assets/Package/<X>/` artifacts and `Release/package.json` regenerate, stages exactly the touched files, and proposes a `V-{version} {summary}` commit. Detects the publish flow (GitLab elestrago CI, GitLab generic, GitHub Actions, or manual) and prints the matching handoff block — the skill never tags or pushes itself. Use whenever a package-tool maintainer wants to wrap pending changes into a release — phrasings like "bump the version", "cut a release", "update changelog and commit", "ship this as 2.x.y", "make a V- commit", or after a `/unity-package-tool-developer` run finishes its code edits. Refuses to run if no `PackageManifestConfig.asset` is found under `Assets/`.
3
+ description: Cut a release commit for any Unity package that uses the `com.elestrago.unity.package-tools` editor tool (the one that drives a `PackageManifestConfig` ScriptableObject and exports via the **Export Package Source** Inspector button). Discovers the config asset, package name, changelog filename, README install snippet, and publish flow at runtime via `scripts/discover_package.py`, so the same skill works in every package-tool consumer regardless of layout. Bumps the SO's `packageVersion`, updates the consumer-install version line in the project-root README (if one exists), prepends or appends an entry to the changelog (whatever filename the config's `changelogPath` resolves to), prompts the maintainer to run **Export Package Source** in Unity so the exported `Assets/Package/<X>/` artifacts and `Release/package.json` regenerate, stages exactly the touched files, and proposes a `V-{version} {summary}` commit. Detects the publish flow (GitLab elestrago CI, GitLab generic, GitHub Actions, or manual) and prints the matching handoff block — the skill never tags or pushes itself. Use whenever a package-tool maintainer wants to wrap pending changes into a release — both release-specific phrasings ("bump the version", "cut a release", "update changelog and commit", "ship this as 2.x.y", "make a V- commit", "release this", "finalize the changes", "publish this version") and generic commit phrasings ("commit all changes", "commit changes", "commit this", "let's commit", "make a commit", "create a commit", "stage and commit", "wrap this up"), and also after a `/unity-package-tool-developer` run finishes its code edits. In a package-tool repo, treat any plain "commit" request as a release-commit request — these repos do not have non-release commits, every shipped commit is a `V-{version}` release commit, so a bare "commit" phrasing from the maintainer is the cue to run the full version-bump → changelog → Export Package Source → commit flow rather than a raw `git commit`. Refuses to run if no `PackageManifestConfig.asset` is found under `Assets/`.
4
4
  ---
5
5
 
6
6
  # unity-package-release
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "com.elestrago.unity.package-tools",
3
- "version": "2.4.0",
3
+ "version": "2.5.1",
4
4
  "displayName": "Package Tool",
5
5
  "description": "Tool for create unity packages",
6
6
  "category": "unity",
7
7
  "unity": "2021.3",
8
8
  "homepage": "https://gitlab.com/elestrago-pkg/package-tool",
9
- "documentationUrl": "https://gitlab.com/elestrago-pkg/package-tool/-/blob/2.4.0/README.md",
10
- "changelogUrl": "https://gitlab.com/elestrago-pkg/package-tool/-/blob/2.4.0/CHANGELOG.md",
11
- "licensesUrl": "https://gitlab.com/elestrago-pkg/package-tool/-/blob/2.4.0/LICENSE",
9
+ "documentationUrl": "https://gitlab.com/elestrago-pkg/package-tool/-/blob/2.5.1/README.md",
10
+ "changelogUrl": "https://gitlab.com/elestrago-pkg/package-tool/-/blob/2.5.1/CHANGELOG.md",
11
+ "licensesUrl": "https://gitlab.com/elestrago-pkg/package-tool/-/blob/2.5.1/LICENSE",
12
12
  "license": "MIT",
13
13
  "keywords": [
14
14
  "unity",
@@ -1,107 +0,0 @@
1
- <!-- generated by unity-package-docs; safe to regenerate -->
2
-
3
- # Package Tool — Samples
4
-
5
- How the sample content in this repository uses the package. Each entry maps a sample file to the package types it exercises, so a reader can recreate the same setup against the public API.
6
-
7
- ## Sample Layout
8
-
9
- ```
10
- Assets/Example/Sample
11
- ├── Prefabs/ExamplePrefab.prefab
12
- └── Scene/SampleScene.unity
13
-
14
- Assets/Samples~/ClaudeSkills
15
- ├── Editor/ClaudeSkillsPostImport.cs
16
- ├── Editor/Playdarium.PackageTool.Samples.ClaudeSkills.Editor.asmdef
17
- ├── unity-package-docs/SKILL.md
18
- ├── unity-package-docs/assets/README.md.template
19
- ├── unity-package-docs/assets/api-chunk.md.template
20
- ├── unity-package-docs/assets/api-index.md.template
21
- ├── unity-package-docs/assets/api.md.template
22
- ├── unity-package-docs/assets/manual.md.template
23
- ├── unity-package-docs/assets/samples.md.template
24
- └── unity-package-docs/scripts/scan_package.py
25
- ```
26
-
27
- On export, `CopySamplesToDirectory` copies each sample root to `Release/Samples~/<folderName>/`, skipping `.meta` files. The shipped samples are consumable from the Package Manager **Samples** tab on the published package.
28
-
29
- ## Sample -> Package Type Mapping
30
-
31
- ### `Assets/Example/Sample/Prefabs/ExamplePrefab.prefab`
32
-
33
- Kind: prefab
34
-
35
- This sample asset references no scripts from the package. It exists as a structural demo (the importing user sees a working Scene/Prefab in the package's Samples tab) rather than as an API exercise.
36
-
37
- ### `Assets/Example/Sample/Scene/SampleScene.unity`
38
-
39
- Kind: scene
40
-
41
- This sample asset references no scripts from the package. It exists as a structural demo (the importing user sees a working Scene/Prefab in the package's Samples tab) rather than as an API exercise.
42
-
43
- ### `Assets/Samples~/ClaudeSkills/Editor/ClaudeSkillsPostImport.cs`
44
-
45
- Kind: script
46
-
47
- Editor-side post-import hook bundled with the **Claude Skills** sample. In a consumer project, after the user imports this package's Claude Skills sample, the script copies the staged `unity-package-docs/` skill folder out of the imported `Assets/Samples/<Package>/<Version>/ClaudeSkills/` location into the consumer project's `.claude/skills/` directory, then self-deletes (and cleans up empty ancestor folders) so subsequent imports do not duplicate work. It does not call into the package's runtime API — it is plumbing for the sample's primary content (`SKILL.md`, `scripts/scan_package.py`, and the `.md.template` files under `assets/`).
48
-
49
- Non-script assets that ship alongside this script (not enumerated above because the scanner only emits scripts/scenes/prefabs):
50
-
51
- - `Assets/Samples~/ClaudeSkills/unity-package-docs/SKILL.md` — the skill definition this sample exists to deliver.
52
- - `Assets/Samples~/ClaudeSkills/unity-package-docs/scripts/scan_package.py` — the scanner the skill invokes.
53
- - `Assets/Samples~/ClaudeSkills/unity-package-docs/assets/*.md.template` — the rendering templates.
54
-
55
- ## Reproducing the Sample
56
-
57
- **Example Sample (`Assets/Example/Sample`)** — structural only, no MonoBehaviour scripts to instantiate. To reproduce from scratch:
58
-
59
- 1. Create an empty Unity scene and a primitive prefab; both can live anywhere in `Assets/`.
60
- 2. Create a `PackageManifestConfig` asset via **Assets > Create > JCMG/PackageTools/PackageManifestConfig** and configure `sourcePath`, `packageDestinationPath`, and a [`Sample`](api.md#sample) entry whose `sourcePath` points at the folder holding the scene and prefab.
61
- 3. Click **Export Package Source** on the inspector — [`FileTools.CreateOrUpdatePackageSource`](api.md#filetools) runs the export pipeline (see `manual.md` -> **Export pipeline**) and the sample folder lands under `packageDestinationPath/Samples~/{folderName}`.
62
-
63
- **Claude Skills (`Assets/Samples~/ClaudeSkills`)** — pairs a Sample with a [`CopyEntry`](api.md#packagemanifestconfigcopyentry) so the skill's canonical source lives in `.claude/skills/unity-package-docs/` (where it is editable and used directly during development) and a synchronized copy is staged into `Assets/Samples~/ClaudeSkills/unity-package-docs/` before export. The Editor-side `ClaudeSkillsPostImport.cs` script bundled with the sample handles the reverse direction in consumer projects: on import it moves the skill folder out of `Assets/Samples/<Package>/<Version>/ClaudeSkills/unity-package-docs/` into the consumer's `.claude/skills/`.
64
-
65
- Minimal equivalent in C# for either sample style:
66
-
67
- ```csharp
68
- using PackageTool;
69
- using PackageTool.Tools;
70
- using UnityEditor;
71
- using UnityEngine;
72
-
73
- var config = ScriptableObject.CreateInstance<PackageManifestConfig>();
74
- config.packageName = "com.example.sample";
75
- config.displayName = "Example Sample Package";
76
- config.packageVersion = "1.0.0";
77
- config.unityVersion = "2021.3";
78
- config.sourcePath = "Assets/Example/Source";
79
- config.packageDestinationPath = "Release";
80
- config.samples = new[]
81
- {
82
- new PackageManifestConfig.Sample
83
- {
84
- sourcePath = "Assets/Example/Sample",
85
- displayName = "Example Sample",
86
- folderName = "ExampleSample",
87
- description = "This is example for check test samples",
88
- },
89
- };
90
- // Optional: stage external content into a Sample's sourcePath first.
91
- config.copyEntries = new[]
92
- {
93
- new PackageManifestConfig.CopyEntry
94
- {
95
- sourcePath = ".claude/skills/unity-package-docs",
96
- destinationPath = "Assets/Samples~/ClaudeSkills/unity-package-docs",
97
- },
98
- };
99
- AssetDatabase.CreateAsset(config, "Assets/Example/PackageManifestConfig.asset");
100
- FileTools.CreateOrUpdatePackageSource(config);
101
- ```
102
-
103
- ## Notes
104
-
105
- - The `Samples~/` folder name (trailing tilde) is a Unity convention: tilde-suffixed folders are excluded from the AssetDatabase import, so packaged samples don't pollute the consuming project until the user clicks **Import** in the Package Manager.
106
- - For samples that stage content from outside `Assets/` — e.g. a Claude skill folder, vendored data, or generated output — use a [`CopyEntry`](api.md#packagemanifestconfigcopyentry) with `destinationPath` pointing at the same `sourcePath` your `Sample` declares. The `CopyEntry` step runs first; `CopySamplesToDirectory` then ships the staged content into the package.
107
- - The `ClaudeSkillsPostImport` editor script only runs in consumer projects after they import the **Claude Skills** sample; it self-deletes after copying so a re-import does not duplicate work. It is not part of the package's primary API and is intentionally outside the `PackageTool` namespace.
@@ -1,56 +0,0 @@
1
- <!-- generated by unity-package-docs; safe to regenerate -->
2
-
3
- # {{displayName}} — Samples
4
-
5
- How the sample content in this repository uses the package. Each entry maps a sample file to the package types it exercises, so a reader can recreate the same setup against the public API.
6
-
7
- ## Sample Layout
8
-
9
- ```
10
- {{sampleTree}}
11
- ```
12
-
13
- ## Sample → Package Type Mapping
14
-
15
- {{sampleMappingSections}}
16
-
17
- <!--
18
- Each sample entry follows this exact shape:
19
-
20
- ### `{sample file path}`
21
-
22
- Kind: script | scene | prefab
23
-
24
- Package types referenced:
25
-
26
- - [`{TypeName}`]({crossRefMap[TypeName]}) — `{package source path}:{line}`
27
-
28
- For scenes/prefabs, list each MonoBehaviour script resolved via m_Script.guid:
29
-
30
- - GameObject `{name}` uses [`{TypeName}`]({crossRefMap[TypeName]}) — `{package source path}`
31
-
32
- Type links resolve through crossRefMap (Step 3.5), NOT a hard-coded
33
- api.md anchor — the destination may be api.md#foo (api single-file) or
34
- api/PackageTool.Tools.md#foo (api chunked).
35
-
36
- Omit "Package types referenced" if the file references none from this package.
37
-
38
- Chunking note (Step 6 chunked branch): when this file is split, entries
39
- are grouped by top-level sample folder into Documentation~/samples/<SampleFolderName>.md
40
- (filename sanitized to [A-Za-z0-9._-], non-matching chars replaced with `-`).
41
- Each chunk carries its own `## Reproducing the Sample` and `## Notes`
42
- sections. Inside chunk files, every `[Type](…)` link prepends `../` to
43
- the crossRefMap value.
44
- -->
45
-
46
- ## Reproducing the Sample
47
-
48
- {{reproductionProse}}
49
-
50
- ```csharp
51
- {{reproductionSnippet}}
52
- ```
53
-
54
- ## Notes
55
-
56
- {{notesList}}