com.elestrago.unity.package-tools 2.0.10 → 2.1.0

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.
Files changed (27) hide show
  1. package/CAHNGELOG.md +16 -0
  2. package/Documentation~/api.md +502 -0
  3. package/Documentation~/manual.md +140 -0
  4. package/Documentation~/samples.md +73 -0
  5. package/Editor/Drawers/CopyEntryPropertyDrawer.cs +95 -0
  6. package/Editor/Drawers/CopyEntryPropertyDrawer.cs.meta +2 -0
  7. package/Editor/EditorConstants.cs +6 -0
  8. package/Editor/Inspectors/PackageManifestConfigInspector.cs +31 -0
  9. package/Editor/PackageManifestConfig.cs +20 -0
  10. package/Editor/Tools/FileTools.cs +73 -0
  11. package/Samples~/ClaudeSkills/unity-package-docs/SKILL.md +309 -0
  12. package/Samples~/ClaudeSkills/unity-package-docs/assets/README.md.template +42 -0
  13. package/Samples~/ClaudeSkills/unity-package-docs/assets/api-chunk.md.template +41 -0
  14. package/Samples~/ClaudeSkills/unity-package-docs/assets/api-index.md.template +26 -0
  15. package/Samples~/ClaudeSkills/unity-package-docs/assets/api.md.template +43 -0
  16. package/Samples~/ClaudeSkills/unity-package-docs/assets/manual.md.template +57 -0
  17. package/Samples~/ClaudeSkills/unity-package-docs/assets/samples.md.template +56 -0
  18. package/Samples~/ClaudeSkills/unity-package-docs/scripts/scan_package.py +504 -0
  19. package/Samples~/ClaudeSkills/unity-package-docs/unity-package-docs/SKILL.md +309 -0
  20. package/Samples~/ClaudeSkills/unity-package-docs/unity-package-docs/assets/README.md.template +42 -0
  21. package/Samples~/ClaudeSkills/unity-package-docs/unity-package-docs/assets/api-chunk.md.template +41 -0
  22. package/Samples~/ClaudeSkills/unity-package-docs/unity-package-docs/assets/api-index.md.template +26 -0
  23. package/Samples~/ClaudeSkills/unity-package-docs/unity-package-docs/assets/api.md.template +43 -0
  24. package/Samples~/ClaudeSkills/unity-package-docs/unity-package-docs/assets/manual.md.template +57 -0
  25. package/Samples~/ClaudeSkills/unity-package-docs/unity-package-docs/assets/samples.md.template +56 -0
  26. package/Samples~/ClaudeSkills/unity-package-docs/unity-package-docs/scripts/scan_package.py +504 -0
  27. package/package.json +9 -4
package/CAHNGELOG.md CHANGED
@@ -2,6 +2,22 @@
2
2
 
3
3
  ---
4
4
 
5
+ ## [2.1.0](https://gitlab.com/elestrago-pkg/package-tool/-/tags/2.1.0)
6
+
7
+ ### Added
8
+
9
+ - Added `copyEntries` on `PackageManifestConfig` for staging external content into the project before export. See `Documentation~/manual.md`.
10
+
11
+ ---
12
+
13
+ ## [2.0.11](https://gitlab.com/elestrago-pkg/package-tool/-/tags/2.0.11)
14
+
15
+ ### Fixed
16
+
17
+ - Test publish package using NPM trusted publisher
18
+
19
+ ---
20
+
5
21
  ## [2.0.10](https://gitlab.com/elestrago-pkg/package-tool/-/tags/2.0.10)
6
22
 
7
23
  ### Fixed
@@ -0,0 +1,502 @@
1
+ <!-- generated by unity-package-docs; safe to regenerate -->
2
+
3
+ # Package Tool — API Reference
4
+
5
+ Comprehensive reference for every public/internal type and member. Generated from source; do not edit by hand.
6
+
7
+ ## Contents
8
+
9
+ - [`PackageTool`](#packagetool) — Root namespace. Hosts the `PackageManifestConfig` ScriptableObject, the editor constants, the CI entry point, and the package-source `MenuItems` class.
10
+ - [`PackageTool.Drawers`](#packagetooldrawers) — `PropertyDrawer` implementations for the nested `[Serializable]` types on `PackageManifestConfig` (`Author`, `Dependency`, `Sample`, `CopyEntry`).
11
+ - [`PackageTool.Inspectors`](#packagetoolinspectors) — `UnityEditor.Editor` for `PackageManifestConfig` — renders the tab-aware IMGUI inspector that drives all export buttons.
12
+ - [`PackageTool.Tools`](#packagetooltools) — Stateless helpers used during export and code generation: file copy, git probing, command-line parsing, code emission, GUI layout primitives, and the `PackageJsonModel` DTO.
13
+ - [`PackageTool.Utils.PackageInitialize`](#packagetoolutilspackageinitialize) — The `Init Package` flow — `EditorWindow`, scaffold logic, and template strings for new packages.
14
+
15
+ ## `PackageTool`
16
+
17
+ Root namespace. Hosts the `PackageManifestConfig` ScriptableObject, the editor constants, the CI entry point, and the package-source `MenuItems` class.
18
+
19
+ ### CIUtils
20
+
21
+ ```csharp
22
+ public static class CIUtils
23
+ ```
24
+
25
+ **Source:** `Assets/Package/PackageTool/Editor/CIUtils.cs:14`
26
+
27
+ Continuous-integration API for package tools.
28
+
29
+ **Members:**
30
+
31
+ | Kind | Name | Signature | Summary |
32
+ |------|------|-----------|---------|
33
+ | method | `Generate` | `public static void Generate()` | Attempts to use zero or more `PackageManifestConfig` assets to generate legacy Unity packages and Unity source. |
34
+ | method | `PrepareDll` | `public static void PrepareDll()` | |
35
+
36
+ ### EditorConstants
37
+
38
+ ```csharp
39
+ internal static class EditorConstants
40
+ ```
41
+
42
+ **Source:** `Assets/Package/PackageTool/Editor/EditorConstants.cs:32`
43
+
44
+ Internal constants and readonly fields for package tools usage.
45
+
46
+ **Members:**
47
+
48
+ | Kind | Name | Signature | Summary |
49
+ |------|------|-----------|---------|
50
+ | field | `DEFAULT_PACKAGE_VERSION` | `public const string DEFAULT_PACKAGE_VERSION` | |
51
+ | field | `DEFAULT_UNITY_VERSION` | `public const string DEFAULT_UNITY_VERSION` | |
52
+ | field | `PACKAGE_JSON_FILENAME` | `public const string PACKAGE_JSON_FILENAME` | |
53
+ | field | `WILDCARD_FILTER` | `public const string WILDCARD_FILTER` | |
54
+ | field | `ASSET_EXTENSION` | `public const string ASSET_EXTENSION` | |
55
+ | field | `META_EXTENSION` | `public const string META_EXTENSION` | |
56
+ | field | `META_FORMAT` | `public const string META_FORMAT` | |
57
+ | field | `GENERATED_FOLDER_NAME` | `public const string GENERATED_FOLDER_NAME` | |
58
+ | field | `UNITY_PACKAGE_NAME_FORMAT` | `public const string UNITY_PACKAGE_NAME_FORMAT` | |
59
+ | field | `EMPTY_SPACE` | `public const char EMPTY_SPACE` | |
60
+ | field | `UNDERSCORE` | `public const char UNDERSCORE` | |
61
+ | field | `GROUP_BOX` | `public const string GROUP_BOX` | |
62
+ | field | `EDITOR_FOLDER_ICON` | `public const string EDITOR_FOLDER_ICON` | |
63
+ | field | `EDITOR_FILE_ICON` | `public const string EDITOR_FILE_ICON` | |
64
+ | field | `PACKAGE_JSON_HEADER` | `public const string PACKAGE_JSON_HEADER` | |
65
+ | field | `PACKAGE_CONTENT_HEADER` | `public const string PACKAGE_CONTENT_HEADER` | |
66
+ | field | `PACKAGE_ACTIONS_HEADER` | `public const string PACKAGE_ACTIONS_HEADER` | |
67
+ | field | `SOURCE_PATHS_HEADER_LABEL` | `public const string SOURCE_PATHS_HEADER_LABEL` | |
68
+ | field | `SOURCE_PATH_ELEMENT_LABEL_FORMAT` | `public const string SOURCE_PATH_ELEMENT_LABEL_FORMAT` | |
69
+ | field | `IGNORE_PATHS_HEADER_LABEL` | `public const string IGNORE_PATHS_HEADER_LABEL` | |
70
+ | field | `KEYWORDS_HEADER_LABEL` | `public const string KEYWORDS_HEADER_LABEL` | |
71
+ | field | `KEYWORD_ELEMENT_LABEL_FORMAT` | `public const string KEYWORD_ELEMENT_LABEL_FORMAT` | |
72
+ | field | `DEPENDENCY_HEADER_LABEL` | `public const string DEPENDENCY_HEADER_LABEL` | |
73
+ | field | `DEPENDENCY_ELEMENT_LABEL_FORMAT` | `public const string DEPENDENCY_ELEMENT_LABEL_FORMAT` | |
74
+ | field | `GENERATE_VERSION_CONSTANTS_BUTTON_TEXT` | `public const string GENERATE_VERSION_CONSTANTS_BUTTON_TEXT` | |
75
+ | field | `UPDATE_PACKAGE_BUTTON_TEXT` | `public const string UPDATE_PACKAGE_BUTTON_TEXT` | |
76
+ | field | `EXPORT_LEGACY_PACKAGE_BUTTON_TEXT` | `public const string EXPORT_LEGACY_PACKAGE_BUTTON_TEXT` | |
77
+ | field | `SELECT_SOURCE_PATH_FILE_PICKER_TITLE` | `public const string SELECT_SOURCE_PATH_FILE_PICKER_TITLE` | |
78
+ | field | `SELECT_SOURCE_PATH_PICKER_FOLDER_TITLE` | `public const string SELECT_SOURCE_PATH_PICKER_FOLDER_TITLE` | |
79
+ | field | `SELECT_PACKAGE_EXPORT_PATH_PICKER_TITLE` | `public const string SELECT_PACKAGE_EXPORT_PATH_PICKER_TITLE` | |
80
+ | field | `SELECT_VERSION_CONSTANTS_PATH_PICKER_TITLE` | `public const string SELECT_VERSION_CONSTANTS_PATH_PICKER_TITLE` | |
81
+ | field | `SELECT_SAMPLES_PATH_FOLDER_TITLE` | `public const string SELECT_SAMPLES_PATH_FOLDER_TITLE` | |
82
+ | field | `PROGRESS_BAR_TITLE` | `public const string PROGRESS_BAR_TITLE` | |
83
+ | field | `PROGRESS_BAR_TITLE_LEGACY` | `public const string PROGRESS_BAR_TITLE_LEGACY` | |
84
+ | field | `COMPILING_PROGRESS_MESSAGE` | `public const string COMPILING_PROGRESS_MESSAGE` | |
85
+ | field | `FOLDER_PATH_PICKER_HEIGHT` | `public const float FOLDER_PATH_PICKER_HEIGHT` | |
86
+ | field | `FOLDER_PATH_PICKER_BUFFER` | `public const float FOLDER_PATH_PICKER_BUFFER` | |
87
+ | field | `SAMPLES_FOLDER_NAME` | `public const string SAMPLES_FOLDER_NAME` | |
88
+ | field | `SAMPLES_HEADER_LABEL` | `public const string SAMPLES_HEADER_LABEL` | |
89
+ | field | `SAMPLES_ELEMENT_LABEL_FORMAT` | `public const string SAMPLES_ELEMENT_LABEL_FORMAT` | |
90
+ | field | `COPY_ENTRIES_HEADER_LABEL` | `public const string COPY_ENTRIES_HEADER_LABEL` | |
91
+ | field | `COPY_ENTRY_ELEMENT_LABEL_FORMAT` | `public const string COPY_ENTRY_ELEMENT_LABEL_FORMAT` | |
92
+ | field | `COPY_ENTRY_SOURCE_LABEL` | `public const string COPY_ENTRY_SOURCE_LABEL` | |
93
+ | field | `COPY_ENTRY_DESTINATION_LABEL` | `public const string COPY_ENTRY_DESTINATION_LABEL` | |
94
+ | field | `SELECT_COPY_DESTINATION_FOLDER_PICKER_TITLE` | `public const string SELECT_COPY_DESTINATION_FOLDER_PICKER_TITLE` | |
95
+
96
+ ### MenuItems
97
+
98
+ ```csharp
99
+ internal static class MenuItems
100
+ ```
101
+
102
+ **Source:** `Assets/Package/PackageTool/Editor/MenuItems.cs:6`
103
+
104
+ ### PackageManifestConfig
105
+
106
+ ```csharp
107
+ public sealed class PackageManifestConfig : ScriptableObject
108
+ ```
109
+
110
+ **Source:** `Assets/Package/PackageTool/Editor/PackageManifestConfig.cs:37`
111
+ **Attributes:** `[CreateAssetMenu(fileName = "PackageManifestConfig", menuName = "JCMG/PackageTools/PackageManifestConfig")]`
112
+ **Base:** `ScriptableObject`
113
+
114
+ `PackageManifestConfig` is an asset config representing a Unity Package. It allows for defining the data used on the package json file, the locations of source files/assets that make up the package, and a destination for th package source to be distributed at.
115
+
116
+ **Members:**
117
+
118
+ | Kind | Name | Signature | Summary |
119
+ |------|------|-----------|---------|
120
+ | property | `Id` | `public string Id` | A unique id for this `PackageManifestConfig` instance. |
121
+ | field | `homepage` | `public string homepage` | |
122
+ | field | `sourcePath` | `public string sourcePath` | A collection of paths to folders and files for the source for the package. |
123
+ | field | `documentationPath` | `public string documentationPath` | |
124
+ | field | `readmePath` | `public string readmePath` | |
125
+ | field | `changelogPath` | `public string changelogPath` | |
126
+ | field | `licensePath` | `public string licensePath` | |
127
+ | field | `license` | `public string license` | |
128
+ | field | `packageIgnorePaths` | `public string[] packageIgnorePaths` | A collection of file/folder paths to exclude from the package. |
129
+ | field | `packageDestinationPath` | `public string packageDestinationPath` | A path to the package source distribution contents. |
130
+ | field | `legacyPackageDestinationPath` | `public string legacyPackageDestinationPath` | The relative path to the folder where the legacy package will be exported to. |
131
+ | field | `packageName` | `public string packageName` | The fully-qualified package name. |
132
+ | field | `displayName` | `public string displayName` | The package name as it appears in the Package Manager window. |
133
+ | field | `packageVersion` | `public string packageVersion` | The semantic version of the package in MAJOR.MINOR.PATCH format. |
134
+ | field | `unityVersion` | `public string unityVersion` | The version of Unity in semantic version format like 2018.1. |
135
+ | field | `description` | `public string description` | A description of the package. |
136
+ | field | `category` | `public string category` | The category the package belongs in. |
137
+ | field | `author` | `public Author author` | The author of this package. |
138
+ | field | `keywords` | `public string[] keywords` | A collection of keywords that describe the package. |
139
+ | field | `dependencies` | `public Dependency[] dependencies` | A collection of packages that this package depends on. |
140
+ | field | `samples` | `public Sample[] samples` | |
141
+ | field | `copyEntries` | `public CopyEntry[] copyEntries` | A collection of additional source-to-destination copy operations performed during export. |
142
+ | field | `versionConstantsPath` | `public string versionConstantsPath` | A path to the where the VersionConstants.cs file should be created/updated |
143
+ | field | `versionConstantsNamespace` | `public string versionConstantsNamespace` | The namespace the generated VersionConstants class will be in. If left blank, this will be the global namespace. |
144
+ | method | `GenerateJson` | `public string GenerateJson()` | Returns a Json `string` representation. |
145
+
146
+ ### PackageManifestConfig.Author
147
+
148
+ ```csharp
149
+ public sealed class Author
150
+ ```
151
+
152
+ **Source:** `Assets/Package/PackageTool/Editor/PackageManifestConfig.cs:62`
153
+ **Attributes:** `[Serializable]`
154
+
155
+ Describes the author of this package.
156
+
157
+ **Members:**
158
+
159
+ | Kind | Name | Signature | Summary |
160
+ |------|------|-----------|---------|
161
+ | field | `name` | `public string name` | |
162
+ | field | `email` | `public string email` | |
163
+ | field | `url` | `public string url` | |
164
+
165
+ ### PackageManifestConfig.CopyEntry
166
+
167
+ ```csharp
168
+ public sealed class CopyEntry
169
+ ```
170
+
171
+ **Source:** `Assets/Package/PackageTool/Editor/PackageManifestConfig.cs:92`
172
+ **Attributes:** `[Serializable]`
173
+
174
+ Describes a copy operation that mirrors a source file or folder into a destination folder inside the project. When the source is a folder, the same-named subfolder of the destination is replaced with the source folder's content. When the source is a file, the same-named file inside the destination folder is replaced. An empty or non-existent destination path falls back to the project root.
175
+
176
+ **Members:**
177
+
178
+ | Kind | Name | Signature | Summary |
179
+ |------|------|-----------|---------|
180
+ | field | `sourcePath` | `public string sourcePath` | |
181
+ | field | `destinationPath` | `public string destinationPath` | |
182
+
183
+ ### PackageManifestConfig.Dependency
184
+
185
+ ```csharp
186
+ public sealed class Dependency
187
+ ```
188
+
189
+ **Source:** `Assets/Package/PackageTool/Editor/PackageManifestConfig.cs:43`
190
+ **Attributes:** `[Serializable]`
191
+
192
+ Describes a dependency that this package requires.
193
+
194
+ **Members:**
195
+
196
+ | Kind | Name | Signature | Summary |
197
+ |------|------|-----------|---------|
198
+ | field | `packageName` | `public string packageName` | The name of the dependent package. |
199
+ | field | `packageVersion` | `public string packageVersion` | The semantic version of the dependent package in MAJOR.MINOR.PATCH format. |
200
+
201
+ ### PackageManifestConfig.Sample
202
+
203
+ ```csharp
204
+ public sealed class Sample
205
+ ```
206
+
207
+ **Source:** `Assets/Package/PackageTool/Editor/PackageManifestConfig.cs:73`
208
+ **Attributes:** `[Serializable]`
209
+
210
+ Describes the samples of this package.
211
+
212
+ **Members:**
213
+
214
+ | Kind | Name | Signature | Summary |
215
+ |------|------|-----------|---------|
216
+ | field | `sourcePath` | `public string sourcePath` | |
217
+ | field | `displayName` | `public string displayName` | |
218
+ | field | `description` | `public string description` | |
219
+ | field | `folderName` | `public string folderName` | |
220
+
221
+ ## `PackageTool.Drawers`
222
+
223
+ `PropertyDrawer` implementations for the nested `[Serializable]` types on `PackageManifestConfig` (`Author`, `Dependency`, `Sample`, `CopyEntry`).
224
+
225
+ ### AuthorPropertyDrawer
226
+
227
+ ```csharp
228
+ internal sealed class AuthorPropertyDrawer : PropertyDrawer
229
+ ```
230
+
231
+ **Source:** `Assets/Package/PackageTool/Editor/Drawers/AuthorPropertyDrawer.cs:34`
232
+ **Attributes:** `[CustomPropertyDrawer(typeof(PackageManifestConfig.Author))]`
233
+ **Base:** `PropertyDrawer`
234
+
235
+ A property drawer for drawing `Author`
236
+
237
+ **Members:**
238
+
239
+ | Kind | Name | Signature | Summary |
240
+ |------|------|-----------|---------|
241
+ | method | `OnGUI` | `public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)` | |
242
+ | method | `GetPropertyHeight` | `public override float GetPropertyHeight(SerializedProperty property, GUIContent label)` | |
243
+
244
+ ### CopyEntryPropertyDrawer
245
+
246
+ ```csharp
247
+ internal sealed class CopyEntryPropertyDrawer : PropertyDrawer
248
+ ```
249
+
250
+ **Source:** `Assets/Package/PackageTool/Editor/Drawers/CopyEntryPropertyDrawer.cs:8`
251
+ **Attributes:** `[CustomPropertyDrawer(typeof(PackageManifestConfig.CopyEntry))]`
252
+ **Base:** `PropertyDrawer`
253
+
254
+ **Members:**
255
+
256
+ | Kind | Name | Signature | Summary |
257
+ |------|------|-----------|---------|
258
+ | method | `OnGUI` | `public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)` | |
259
+ | method | `GetPropertyHeight` | `public override float GetPropertyHeight(SerializedProperty property, GUIContent label)` | |
260
+
261
+ ### DependencyPropertyDrawer
262
+
263
+ ```csharp
264
+ internal sealed class DependencyPropertyDrawer : PropertyDrawer
265
+ ```
266
+
267
+ **Source:** `Assets/Package/PackageTool/Editor/Drawers/DependencyPropertyDrawer.cs:34`
268
+ **Attributes:** `[CustomPropertyDrawer(typeof(PackageManifestConfig.Dependency))]`
269
+ **Base:** `PropertyDrawer`
270
+
271
+ A property drawer for drawing `Dependency`
272
+
273
+ **Members:**
274
+
275
+ | Kind | Name | Signature | Summary |
276
+ |------|------|-----------|---------|
277
+ | method | `OnGUI` | `public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)` | |
278
+ | method | `GetPropertyHeight` | `public override float GetPropertyHeight(SerializedProperty property, GUIContent label)` | |
279
+
280
+ ### SamplePropertyDrawer
281
+
282
+ ```csharp
283
+ public class SamplePropertyDrawer : PropertyDrawer
284
+ ```
285
+
286
+ **Source:** `Assets/Package/PackageTool/Editor/Drawers/SamplePropertyDrawer.cs:8`
287
+ **Attributes:** `[CustomPropertyDrawer(typeof(PackageManifestConfig.Sample))]`
288
+ **Base:** `PropertyDrawer`
289
+
290
+ **Members:**
291
+
292
+ | Kind | Name | Signature | Summary |
293
+ |------|------|-----------|---------|
294
+ | method | `OnGUI` | `public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)` | |
295
+ | method | `GetPropertyHeight` | `public override float GetPropertyHeight(SerializedProperty property, GUIContent label)` | |
296
+
297
+ ## `PackageTool.Inspectors`
298
+
299
+ `UnityEditor.Editor` for `PackageManifestConfig` — renders the tab-aware IMGUI inspector that drives all export buttons.
300
+
301
+ ### PackageManifestConfigInspector
302
+
303
+ ```csharp
304
+ internal sealed class PackageManifestConfigInspector : UnityEditor.Editor
305
+ ```
306
+
307
+ **Source:** `Assets/Package/PackageTool/Editor/Inspectors/PackageManifestConfigInspector.cs:33`
308
+ **Attributes:** `[CustomEditor(typeof(PackageManifestConfig))]`
309
+ **Base:** `UnityEditor.Editor`
310
+
311
+ **Members:**
312
+
313
+ | Kind | Name | Signature | Summary |
314
+ |------|------|-----------|---------|
315
+ | method | `OnInspectorGUI` | `public override void OnInspectorGUI()` | |
316
+
317
+ ## `PackageTool.Tools`
318
+
319
+ Stateless helpers used during export and code generation: file copy, git probing, command-line parsing, code emission, GUI layout primitives, and the `PackageJsonModel` DTO.
320
+
321
+ ### CodeGenTools
322
+
323
+ ```csharp
324
+ internal static class CodeGenTools
325
+ ```
326
+
327
+ **Source:** `Assets/Package/PackageTool/Editor/Tools/CodeGenTools.cs:36`
328
+
329
+ Helper methods for code-gen.
330
+
331
+ **Members:**
332
+
333
+ | Kind | Name | Signature | Summary |
334
+ |------|------|-----------|---------|
335
+ | method | `GenerateVersionConstants` | `public static void GenerateVersionConstants(PackageManifestConfig config)` | |
336
+
337
+ ### CommandLineTools
338
+
339
+ ```csharp
340
+ public static class CommandLineTools
341
+ ```
342
+
343
+ **Source:** `Assets/Package/PackageTool/Editor/Tools/CommandLineTools.cs:33`
344
+
345
+ Helper methods for command-line usage
346
+
347
+ **Members:**
348
+
349
+ | Kind | Name | Signature | Summary |
350
+ |------|------|-----------|---------|
351
+ | method | `GetKVPCommandLineArguments` | `public static Dictionary<string, object> GetKVPCommandLineArguments()` | Returns a more easily-searchable `Dictionary{TKey,TValue}` of command-line arguments. |
352
+
353
+ ### FileTools
354
+
355
+ ```csharp
356
+ internal static class FileTools
357
+ ```
358
+
359
+ **Source:** `Assets/Package/PackageTool/Editor/Tools/FileTools.cs:38`
360
+
361
+ Helper methods for dealing with files/directories
362
+
363
+ **Members:**
364
+
365
+ | Kind | Name | Signature | Summary |
366
+ |------|------|-----------|---------|
367
+ | method | `ConvertToRelativePath` | `public static string ConvertToRelativePath(string fullFilePath, string referencePath)` | Converts `fullFilePath` into a relative file path from `referencePath`. |
368
+ | method | `CreateOrUpdatePackageSource` | `public static void CreateOrUpdatePackageSource(PackageManifestConfig packageManifest)` | Creates or updates the existing package contents of `PackageManifestConfig` `packageManifest`. |
369
+ | method | `CopyDocumentationToDirectory` | `public static void CopyDocumentationToDirectory(PackageManifestConfig packageManifest)` | |
370
+ | method | `CopyEntriesToProject` | `public static void CopyEntriesToProject(PackageManifestConfig packageManifest)` | Stages each configured `CopyEntry` into the project before the rest of the export runs. A folder source's content is merged directly into `destinationPath` (same-named files are overwritten, unrelated files in the destination are left alone). A file source overwrites destination/{filename}. A blank destination resolves to the project root; a non-blank destination that does not yet exist is created. Missing sources log a warning and are skipped. |
371
+ | method | `IsFile` | `public static bool IsFile(string path)` | Returns true if the `path` is for a file, otherwise false. |
372
+ | method | `GetAllFilesRecursively` | `internal static IEnumerable<string> GetAllFilesRecursively(string folderPath)` | Recursive find all files starting at root folder at path `folderPath` and return a list of absolute paths to those files. |
373
+
374
+ ### GUILayoutTools
375
+
376
+ ```csharp
377
+ internal static class GUILayoutTools
378
+ ```
379
+
380
+ **Source:** `Assets/Package/PackageTool/Editor/Tools/GUILayoutTools.cs:34`
381
+
382
+ Helper methods for Unity Editor GUI.
383
+
384
+ **Members:**
385
+
386
+ | Kind | Name | Signature | Summary |
387
+ |------|------|-----------|---------|
388
+ | method | `DrawFolderPicker` | `public static void DrawFolderPicker(Rect rect, SerializedProperty property, string title)` | Draw a folder picker button in `Rect` `rect` that allows setting a relative folder path value on `SerializedProperty` `property`. |
389
+ | method | `DrawSourceFolderPicker` | `public static void DrawSourceFolderPicker(Rect rect, SerializedProperty property, string title)` | |
390
+ | method | `DrawFilePicker` | `public static void DrawFilePicker(Rect rect, SerializedProperty property, string title)` | Draw a file picker button in `Rect` `rect` that allows setting a relative file path value on `SerializedProperty` `property`. |
391
+ | method | `DrawFolderPickerLayout` | `public static void DrawFolderPickerLayout(SerializedProperty property, string title)` | Draw a folder picker button using `GUILayout` that allows setting a relative folder path value on `SerializedProperty` `property`. |
392
+ | method | `DrawFilePickerLayout` | `public static void DrawFilePickerLayout(SerializedProperty property, string title)` | |
393
+
394
+ ### GitTools
395
+
396
+ ```csharp
397
+ public static class GitTools
398
+ ```
399
+
400
+ **Source:** `Assets/Package/PackageTool/Editor/Tools/GitTools.cs:33`
401
+
402
+ Helper methods for retrieving git information
403
+
404
+ **Members:**
405
+
406
+ | Kind | Name | Signature | Summary |
407
+ |------|------|-----------|---------|
408
+ | method | `Run` | `public static string Run(string cmd)` | |
409
+ | method | `GetBranch` | `public static string GetBranch()` | |
410
+ | method | `GetLongHeadHash` | `public static string GetLongHeadHash()` | |
411
+
412
+ ### PackageJsonModel
413
+
414
+ ```csharp
415
+ public class PackageJsonModel
416
+ ```
417
+
418
+ **Source:** `Assets/Package/PackageTool/Editor/Tools/PackageJsonModel.cs:7`
419
+
420
+ **Members:**
421
+
422
+ | Kind | Name | Signature | Summary |
423
+ |------|------|-----------|---------|
424
+ | method | `CreateFromManifest` | `public static PackageJsonModel CreateFromManifest(PackageManifestConfig manifest)` | |
425
+
426
+ ### PackageManifestTools
427
+
428
+ ```csharp
429
+ internal static class PackageManifestTools
430
+ ```
431
+
432
+ **Source:** `Assets/Package/PackageTool/Editor/Tools/PackageManifestTools.cs:34`
433
+
434
+ Helper methods for the Package Manifest Tools
435
+
436
+ **Members:**
437
+
438
+ | Kind | Name | Signature | Summary |
439
+ |------|------|-----------|---------|
440
+ | method | `GenerateJson` | `public static string GenerateJson(PackageManifestConfig manifest)` | Returns a Json `string` representation of the `PackageManifestConfig` `manifest`. |
441
+ | method | `GetAllConfigs` | `public static PackageManifestConfig[] GetAllConfigs()` | Retrieves all `PackageManifestConfig` instances in the project. |
442
+
443
+ ### UnityFileTools
444
+
445
+ ```csharp
446
+ internal static class UnityFileTools
447
+ ```
448
+
449
+ **Source:** `Assets/Package/PackageTool/Editor/Tools/UnityFileTools.cs:36`
450
+
451
+ Helper methods for dealing with files/directories in the Unity Assets folder.
452
+
453
+ **Members:**
454
+
455
+ | Kind | Name | Signature | Summary |
456
+ |------|------|-----------|---------|
457
+ | method | `CompileLegacyPackage` | `public static void CompileLegacyPackage(PackageManifestConfig config)` | Gather all of the files/folders for the package and export them to the pre-defined location at `legacyPackageDestinationPath`. |
458
+
459
+ ## `PackageTool.Utils.PackageInitialize`
460
+
461
+ The `Init Package` flow — `EditorWindow`, scaffold logic, and template strings for new packages.
462
+
463
+ ### PackageInitializeTemplates
464
+
465
+ ```csharp
466
+ public static class PackageInitializeTemplates
467
+ ```
468
+
469
+ **Source:** `Assets/Package/PackageTool/Editor/Utils/PackageInitialize/PackageInitializeTemplates.cs:5`
470
+
471
+ ### PackageInitializeUtil
472
+
473
+ ```csharp
474
+ public static class PackageInitializeUtil
475
+ ```
476
+
477
+ **Source:** `Assets/Package/PackageTool/Editor/Utils/PackageInitialize/PackageInitializeUtil.cs:7`
478
+
479
+ **Members:**
480
+
481
+ | Kind | Name | Signature | Summary |
482
+ |------|------|-----------|---------|
483
+ | field | `ASSETS_FOLDER_NAME` | `public const string ASSETS_FOLDER_NAME` | |
484
+ | field | `RELEASE_FOLDER_NAME` | `public const string RELEASE_FOLDER_NAME` | |
485
+ | method | `Init` | `public static void Init(string scope, PackageManifestConfig config)` | |
486
+ | method | `CreateFolderInProject` | `public static void CreateFolderInProject(string directoryPath)` | |
487
+ | method | `CreateFolderInAssets` | `public static void CreateFolderInAssets(string directoryPath)` | |
488
+
489
+ ### PackageInitializeWindow
490
+
491
+ ```csharp
492
+ public class PackageInitializeWindow : EditorWindow
493
+ ```
494
+
495
+ **Source:** `Assets/Package/PackageTool/Editor/Utils/PackageInitialize/PackageInitializeWindow.cs:7`
496
+ **Base:** `EditorWindow`
497
+
498
+ **Members:**
499
+
500
+ | Kind | Name | Signature | Summary |
501
+ |------|------|-----------|---------|
502
+ | method | `Open` | `public static void Open()` | |
@@ -0,0 +1,140 @@
1
+ <!-- generated by unity-package-docs; safe to regenerate -->
2
+
3
+ # Package Tool — Manual
4
+
5
+ ## Overview
6
+
7
+ The Package Tool is an Editor-only utility for authoring and publishing Unity packages from inside a Unity project. The package's source files, samples, documentation, README, CHANGELOG, and `package.json` are all described by a single `PackageManifestConfig` ScriptableObject; invoking **Export Package Source** assembles the package layout under `packageDestinationPath` ready for publication.
8
+
9
+ The same `PackageManifestConfig` drives an interactive Editor inspector and a CI batch-mode entry point. The editor inspector exposes per-section tabs (package metadata, content/export, actions) and reorderable lists for keywords, dependencies, samples, and copy entries; the CI side reads command-line key/value pairs and runs the same export pipeline without UI.
10
+
11
+ Beyond export, the tool ships an **Init Package** scaffolder (`Tools/PackageTools/Init Package`) that lays down a `PackageManifestConfig.asset`, README/CHANGELOG/LICENSE, `Documentation~/`, `Samples~/`, and an Editor folder using the names you supply; a **VersionConstants.cs** generator that emits a `public const string VERSION = "…";` style file at a configurable path; a **PrepareDll** menu item that flips DLL plugin platform flags before export; and a `copyEntries` mechanism for staging external content (Claude skills, generated assets, vendored data) into project paths before the rest of the export runs.
12
+
13
+ Package name: `com.elestrago.unity.package-tools`
14
+ Package source: `Assets/Package/PackageTool`
15
+
16
+ ## Architecture
17
+
18
+ ```
19
+ PackageTool
20
+ ├── Drawers
21
+ ├── Inspectors
22
+ ├── Tools
23
+ └── Utils
24
+ └── PackageInitialize
25
+ ```
26
+
27
+ `PackageTool` (root) holds the configuration ScriptableObject [`PackageManifestConfig`](api.md#packagemanifestconfig) at `Assets/Package/PackageTool/Editor/PackageManifestConfig.cs:37`, the user-facing string table [`EditorConstants`](api.md#editorconstants) at `Assets/Package/PackageTool/Editor/EditorConstants.cs:32`, the CI batch entry point [`CIUtils`](api.md#ciutils) at `Assets/Package/PackageTool/Editor/CIUtils.cs:14`, and [`MenuItems`](api.md#menuitems) at `Assets/Package/PackageTool/Editor/MenuItems.cs:6`.
28
+
29
+ `PackageTool.Drawers` contains `PropertyDrawer` subclasses for the nested data types on `PackageManifestConfig`: [`AuthorPropertyDrawer`](api.md#authorpropertydrawer) (`Assets/Package/PackageTool/Editor/Drawers/AuthorPropertyDrawer.cs:34`), [`DependencyPropertyDrawer`](api.md#dependencypropertydrawer), [`SamplePropertyDrawer`](api.md#samplepropertydrawer), and [`CopyEntryPropertyDrawer`](api.md#copyentrypropertydrawer). All four are IMGUI drawers with manual `Rect` math.
30
+
31
+ `PackageTool.Inspectors` has a single class, [`PackageManifestConfigInspector`](api.md#packagemanifestconfiginspector) at `Assets/Package/PackageTool/Editor/Inspectors/PackageManifestConfigInspector.cs:33` — a tab-based `UnityEditor.Editor` that drives every export button and renders the reorderable lists (keywords, dependencies, samples, copy entries).
32
+
33
+ `PackageTool.Tools` is the helpers layer. [`FileTools`](api.md#filetools) owns the export pipeline (`CreateOrUpdatePackageSource`); [`CodeGenTools`](api.md#codegentools) emits `VersionConstants.cs`; [`PackageManifestTools`](api.md#packagemanifesttools) discovers configs and serializes `package.json`; [`GitTools`](api.md#gittools) probes branch/HEAD for the version token chain; [`CommandLineTools`](api.md#commandlinetools) parses CI key/value args; [`GUILayoutTools`](api.md#guilayouttools) provides reusable file/folder picker drawers; [`UnityFileTools`](api.md#unityfiletools) handles legacy `.unitypackage` compilation; and [`PackageJsonModel`](api.md#packagejsonmodel) is the JSON DTO with its `Author`/`Repository`/`Bugs`/`Sample` sub-models.
34
+
35
+ `PackageTool.Utils.PackageInitialize` is the Init Package flow: [`PackageInitializeWindow`](api.md#packageinitializewindow) is the `EditorWindow`, [`PackageInitializeUtil`](api.md#packageinitializeutil) creates folders and the config asset, and [`PackageInitializeTemplates`](api.md#packageinitializetemplates) holds the README/CHANGELOG/LICENSE string templates.
36
+
37
+ ## Assemblies
38
+
39
+ | Assembly | Root Namespace | Platforms | References |
40
+ |----------|----------------|-----------|------------|
41
+ | `Playdarium.PackageTool.Editor` | `—` | Editor | — |
42
+
43
+ ## Entry Points
44
+
45
+ - `[MenuItem("Tools/PackageTools/PrepareDll")]` → `CIUtils.PrepareDll` at `Assets/Package/PackageTool/Editor/CIUtils.cs:197`. Maps to the **Tools/PackageTools/PrepareDll** entry in the Unity menu bar.
46
+ - `[MenuItem("Tools/PackageTools/Init Package")]` → `PackageInitializeWindow.Open` (declared inline in `Assets/Package/PackageTool/Editor/MenuItems.cs`); opens the scaffolder window.
47
+ - `[CreateAssetMenu(menuName = "JCMG/PackageTools/PackageManifestConfig")]` → `PackageManifestConfig` at `Assets/Package/PackageTool/Editor/PackageManifestConfig.cs:37`. Available under **Assets > Create > JCMG/PackageTools/PackageManifestConfig**.
48
+ - `CIUtils.Generate` at `Assets/Package/PackageTool/Editor/CIUtils.cs:65` — batch-mode entry point invoked via `unity -batchmode -executeMethod PackageTool.CIUtils.Generate <key>=<value>`. Reads keys parsed by [`CommandLineTools.GetKVPCommandLineArguments`](api.md#commandlinetools); see the **CI command-line keys** section in `extension-points` for the supported keys.
49
+ - `CIUtils.PrepareDll` at `Assets/Package/PackageTool/Editor/CIUtils.cs:197` — exits the Editor when run under CI (`CI` env var set); fixes DLL plugin platform flags first. Also available as `Tools/PackageTools/PrepareDll` for interactive use.
50
+ - `PackageInitializeWindow.Open` at `Assets/Package/PackageTool/Editor/Utils/PackageInitialize/PackageInitializeWindow.cs:7` — opens the scaffolder via `Tools/PackageTools/Init Package`.
51
+
52
+ Inspector buttons on `PackageManifestConfig` assets (drawn by `PackageManifestConfigInspector.OnInspectorGUI`):
53
+
54
+ - **Generate VersionConstants.cs** → `CodeGenTools.GenerateVersionConstants(config)` at `Assets/Package/PackageTool/Editor/Tools/CodeGenTools.cs:36`.
55
+ - **Export Package Source** → `FileTools.CreateOrUpdatePackageSource(config)` at `Assets/Package/PackageTool/Editor/Tools/FileTools.cs:59`.
56
+ - **Export as Legacy Package** → `UnityFileTools.CompileLegacyPackage(config)` at `Assets/Package/PackageTool/Editor/Tools/UnityFileTools.cs:36`.
57
+
58
+ ## Data Model
59
+
60
+ ### [`PackageManifestConfig`](api.md#packagemanifestconfig) — `ScriptableObject`
61
+
62
+ Defined at `Assets/Package/PackageTool/Editor/PackageManifestConfig.cs:37`. Created via **Assets > Create > JCMG/PackageTools/PackageManifestConfig**. Public fields, by section:
63
+
64
+ - **Package json metadata:** `homepage`, `packageName`, `displayName`, `packageVersion`, `unityVersion`, `description`, `category`, `license`, `keywords` (`string[]`), `author` (`Author`), `dependencies` (`Dependency[]`).
65
+ - **Package content paths:** `sourcePath`, `documentationPath` (default `Documentation~`), `readmePath` (default `README.md`), `changelogPath` (default `CHANGELOG.md`), `licensePath` (default `LICENSE`), `packageIgnorePaths` (`string[]`).
66
+ - **Export targets:** `packageDestinationPath`, `legacyPackageDestinationPath`.
67
+ - **Staging:** `samples` ([`Sample[]`](api.md#packagemanifestconfigsample)), `copyEntries` ([`CopyEntry[]`](api.md#packagemanifestconfigcopyentry)).
68
+ - **Code generation:** `versionConstantsPath`, `versionConstantsNamespace`.
69
+ - **Hidden:** `_id` (Guid; surfaced via `Id` property; used by `CIUtils.Generate id=<guid>` filtering).
70
+
71
+ Nested `[Serializable]` types, each with a `PropertyDrawer` in `PackageTool.Drawers`:
72
+
73
+ - [`Author`](api.md#packagemanifestconfigauthor) — `name`, `email`, `url` (`string`).
74
+ - [`Dependency`](api.md#packagemanifestconfigdependency) — `packageName`, `packageVersion` (`string`); `IsEmpty()` is true when either is blank.
75
+ - [`Sample`](api.md#packagemanifestconfigsample) — `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** in the next section.
77
+
78
+ ### Export pipeline
79
+
80
+ `FileTools.CreateOrUpdatePackageSource(config)` at `Assets/Package/PackageTool/Editor/Tools/FileTools.cs:59` runs the steps below in order:
81
+
82
+ 1. Write `package.json` to `Assets/PackageManifest/Generated/<id>/package.json` (Unity needs a meta file to copy the meta downstream).
83
+ 2. Wipe and recreate `packageDestinationPath` (e.g. `Release/`).
84
+ 3. Copy `package.json` and its meta into `packageDestinationPath`.
85
+ 4. **`CopyEntriesToProject(config)`** — stage external content into the project; see below.
86
+ 5. **`CopyDocumentationToDirectory(config)`** — copy `readmePath`, `changelogPath`, `licensePath` into `sourcePath`; rebuild `sourcePath/Documentation~/` from `documentationPath`.
87
+ 6. **`RecursivelyCopyDirectoriesAndFiles(config, sourcePath, packageDestinationPath)`** — copy the package source tree, honoring `packageIgnorePaths`.
88
+ 7. **`CopySamplesToDirectory(config)`** — wipe `packageDestinationPath/Samples~/` and copy each [`Sample`](api.md#packagemanifestconfigsample)'s `sourcePath` to `Samples~/{folderName}`, skipping `.meta` files.
89
+
90
+ ### Copy Entries staging
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`.
93
+
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
+
96
+ **File source.** `destinationPath/{filename}` is overwritten.
97
+
98
+ **Destination path resolution.**
99
+
100
+ - Blank `destinationPath` → `EditorConstants.ProjectPath` (the repo root).
101
+ - Non-blank `destinationPath` is resolved via `Path.GetFullPath` (so relative paths are cwd-relative — Unity Editor cwd is the project root) and **created on demand** if it doesn't yet exist.
102
+ - A missing **source** path logs `[Package Tools] Copy entry source [...] does not exist, skipping.` and continues with the next entry.
103
+
104
+ **Chained-with-Sample workflow.** A common shape: define a `Sample` whose `sourcePath` is `Assets/Samples~/<Name>` and a `CopyEntry` whose `destinationPath` is the same folder. The CopyEntry stages external content into `Assets/Samples~/<Name>`, then `CopySamplesToDirectory` ships that content into `<packageDestinationPath>/Samples~/<folderName>`. Because `~`-suffixed folders are ignored by Unity's asset importer, the staged Assets-side copy does not pollute the project import.
105
+
106
+ ## Editor UI Approach
107
+
108
+ IMGUI throughout — no UI Toolkit. There are no `.uxml` or `.uss` files in the package. UI is split into:
109
+
110
+ - An `EditorWindow` with `OnGUI`: [`PackageInitializeWindow`](api.md#packageinitializewindow) at `Assets/Package/PackageTool/Editor/Utils/PackageInitialize/PackageInitializeWindow.cs:7`.
111
+ - A `UnityEditor.Editor` with `OnInspectorGUI`: [`PackageManifestConfigInspector`](api.md#packagemanifestconfiginspector) at `Assets/Package/PackageTool/Editor/Inspectors/PackageManifestConfigInspector.cs:33` — uses `EditorGUILayout`, `EditorGUI.ChangeCheckScope`, and `ReorderableList` for keywords, dependencies, samples, copy entries.
112
+ - Four `PropertyDrawer`s with `OnGUI(Rect, ...)` and manual rect math in `PackageTool.Drawers` (one per `[Serializable]` nested type on `PackageManifestConfig`).
113
+ - Reusable IMGUI primitives in [`GUILayoutTools`](api.md#guilayouttools) — `DrawFilePicker`, `DrawFolderPicker`, plus `*Layout` variants. Reach for these for any path-input UI instead of rolling your own picker.
114
+
115
+ ## Extension Points
116
+
117
+ ### CI command-line keys
118
+
119
+ `CIUtils.Generate` reads keys parsed by [`CommandLineTools.GetKVPCommandLineArguments`](api.md#commandlinetools). Keys are case-insensitive (lowercased on parse) and values are passed as `<key>=<value>` pairs after `-executeMethod PackageTool.CIUtils.Generate`:
120
+
121
+ - `id=<guid>[,<guid>...]` — restrict to specific `PackageManifestConfig._id`s. Omit to process all configs found by `PackageManifestTools.GetAllConfigs`.
122
+ - `version=<semver>` — overrides `packageVersion` on every processed config (and marks the asset dirty).
123
+ - `preview=<bool>` — parsed but not currently applied.
124
+ - `generateversionconstants=<bool>` — when true, runs `CodeGenTools.GenerateVersionConstants` before export.
125
+
126
+ To add a new key, edit `Assets/Package/PackageTool/Editor/CIUtils.cs` (constants block at lines 17–20, parsing pattern in `Generate()` lines 91–113); do **not** touch `CommandLineTools.cs` — its parsing already handles arbitrary keys.
127
+
128
+ ### VersionConstants template tokens
129
+
130
+ `CodeGenTools.GenerateVersionConstants(config)` substitutes a `${token}` set into the embedded `TEMPLATE` / `GLOBAL_TEMPLATE` strings (chain at `Assets/Package/PackageTool/Editor/Tools/CodeGenTools.cs:131`) using values from the config, `DateTime`, and [`GitTools`](api.md#gittools). Adding a new token is a two-edit change: append the template line and add a `.Replace("${token}", value)` call.
131
+
132
+ ### Init Package fields
133
+
134
+ `PackageInitializeWindow` lays down a `PackageManifestConfig.asset`, README, CHANGELOG, LICENSE, and `Documentation~/` / `Samples~/` folders from a flat set of `DrawTextField` inputs at `Assets/Package/PackageTool/Editor/Utils/PackageInitialize/PackageInitializeWindow.cs:32`. The scaffold logic and string templates live in [`PackageInitializeUtil`](api.md#packageinitializeutil) and [`PackageInitializeTemplates`](api.md#packageinitializetemplates); changes that affect generated content must thread through both.
135
+
136
+ ### Custom drawers, menu items, helpers
137
+
138
+ - New `PropertyDrawer`: add `Assets/Package/PackageTool/Editor/Drawers/{Type}PropertyDrawer.cs`, mark `internal sealed class : PropertyDrawer`, override `OnGUI(Rect, ...)` + `GetPropertyHeight`.
139
+ - New `MenuItem`: add to `Editor/MenuItems.cs` (or alongside the class that owns the action, as `CIUtils.PrepareDll` does).
140
+ - New helper: add `Editor/Tools/{Name}.cs`, mark `internal static class`, namespace `PackageTool.Tools`. Mirror [`FileTools`](api.md#filetools) or [`GitTools`](api.md#gittools) for shape.