Remove CLAUDE.md
This commit is contained in:
@@ -1,222 +0,0 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This repo **is** a `dotnet new` project template (identity `SCPSL.LabApi.PluginTemplate`,
|
||||
shortName `labapi-plugin`), not a runnable plugin. It scaffolds SCP: Secret Laboratory
|
||||
LabAPI plugins.
|
||||
|
||||
The next section only applies while you're editing **this template repository**
|
||||
(i.e. a `.template.config/` folder is present next to this file). It does not apply
|
||||
if you're instead looking at a plugin someone already generated from this template —
|
||||
that folder never contains `.template.config/`, and its `EntryPoint.cs`/`Config.cs`
|
||||
are ordinary project files at that point, not template scaffolding.
|
||||
|
||||
## Repo is template *source* — read before touching any file
|
||||
|
||||
`.template.config/template.json` sets this folder's name as the template's
|
||||
`sourceName` and defines one text-replacement `symbol`, `PluginAuthor`. The dotnet
|
||||
templating engine does a literal, repo-wide **string replacement** at generation
|
||||
time — not semantic renaming — driven by that config:
|
||||
|
||||
- The folder/project name (`sourceName` in `template.json`, currently this repo's own
|
||||
folder name) → whatever `-n`/`--name` the consumer passes to `dotnet new`.
|
||||
- The placeholder value of the `PluginAuthor` symbol (the string currently sitting in
|
||||
`EntryPoint.cs`'s `Author` property) → the consumer's `--PluginAuthor`.
|
||||
|
||||
Open `template.json` to see the exact current literal for each — don't hardcode them
|
||||
again here or anywhere else in prose, because this file itself ships inside every
|
||||
generated project and any exact match gets rewritten too (self-referential text like
|
||||
"the project is called X" would silently turn into nonsense after generation).
|
||||
|
||||
Consequences:
|
||||
- Never introduce an exact match of one of those two literals elsewhere in the repo
|
||||
unless you intend it to be substituted too.
|
||||
- If you add a new thing that should be configurable at generation time, add a symbol
|
||||
to `template.json` (`type: parameter`, `replaces: "<literal>"`) instead of
|
||||
hardcoding a magic string.
|
||||
- `EntryPoint` and `Config` (the class names) are **not** substituted and must stay
|
||||
literally named that — LabAPI's `PluginLoader` discovers plugins by type
|
||||
inheritance, not by name, and the file names `EntryPoint.cs`/`Config.cs` are a fixed
|
||||
part of this template's contract. Only the *namespace* tracks the project name.
|
||||
|
||||
## Repo layout (only what affects decisions)
|
||||
|
||||
- Repo root holds only template-source/maintenance files that must **never** ship in
|
||||
a generated project: `.git/`, `.gitignore`, `.editorconfig`, `CLAUDE.md`, and
|
||||
`.template.config/`. None of these are copied to generated output — see "content/
|
||||
vs. repo root" below.
|
||||
- `.template.config/template.json` — template identity, the `PluginAuthor` symbol,
|
||||
a `sources` entry that maps `./content` → the output root (this is what keeps the
|
||||
root-level files above out of every generated project), `primaryOutputs` (points at
|
||||
the project file using its pre-substitution literal name, relative to `content/` —
|
||||
that's correct and expected, not a bug), and one `postAction`: the standard
|
||||
dotnet-templating "restore NuGet packages" action (id `210D431B-...`; skipped in
|
||||
Visual Studio, which restores on its own).
|
||||
- `.template.config/ide.host.json` — Visual Studio-only UI hints for the New Project
|
||||
wizard. It does **not** rename the `PluginAuthor` symbol (a flag can't contain a
|
||||
space); it only maps the symbol's `id` to a human-readable `name.text` label shown
|
||||
in VS's UI, via `isVisible: "true"` (VS hides a symbol from that UI unless
|
||||
explicitly marked visible here). Ignored entirely by `dotnet new` on the CLI.
|
||||
- `content/` — the actual buildable project, and the only folder the `sources`
|
||||
mapping in `template.json` copies into generated output: `LabApiPluginTemplate.csproj`,
|
||||
`EntryPoint.cs`, `Config.cs`, and `content/CLAUDE.md`. Add any new file that should
|
||||
ship with generated plugins in here, not at the repo root.
|
||||
- `content/CLAUDE.md` is a **different file** from this one (the repo-root
|
||||
`CLAUDE.md`, which is template-editing guidance and never ships). It's the project
|
||||
memory a generated plugin ships with, so Claude Code has LabAPI/toolchain/style
|
||||
context automatically in every plugin generated from this template, without
|
||||
depending on any C#/.NET/LabAPI Skill existing in the catalog (none currently does —
|
||||
re-check with `SearchSkills`/`ToolSearch` before assuming that's still true). Keep
|
||||
its LabAPI-contract/toolchain/style sections in sync with this file's equivalent
|
||||
sections when either changes; `content/CLAUDE.md` omits everything specific to
|
||||
editing *this* template repo (symbols, `sources` mapping, `sourceName` traps, the
|
||||
verification workflow below) since none of that applies to a generated plugin.
|
||||
- No `.sln`, no test project, no CI, no packaging (`.nupkg`) project, no GitHub
|
||||
Copilot instructions file currently exist in this folder. Don't assume any of them.
|
||||
This repo itself does have its own git history (see `git log`) — that's unrelated
|
||||
to whether a *generated* project gets one, which is what "Git on generation" below
|
||||
covers.
|
||||
|
||||
## `content/` vs. repo root — why the project isn't at the repo root
|
||||
|
||||
Early versions of this template had the `.csproj`/`.cs` files sitting directly next
|
||||
to `.gitignore`/`.editorconfig`/`CLAUDE.md`/`.template.config/` at the repo root, with
|
||||
no `sources` entry in `template.json`. Because `dotnet new` copies everything under
|
||||
the mounted template root except `.template.config/` by default, every one of those
|
||||
maintenance files silently ended up inside every generated plugin too.
|
||||
|
||||
The fix: `content/` holds only what should be copied, and `template.json` declares
|
||||
`"sources": [{ "source": "./content", "target": "./" }]`. Files outside `./content`
|
||||
(root-level `.gitignore`, `.editorconfig`, `CLAUDE.md`) are never touched by
|
||||
generation — no exclude-list to maintain.
|
||||
|
||||
Do **not** nest a folder named `LabApiPluginTemplate` inside `content/` (e.g.
|
||||
`content/LabApiPluginTemplate/EntryPoint.cs`). `sourceName` substitution renames any
|
||||
folder whose name matches it, so an inner folder named after the project would get
|
||||
renamed too, producing a doubled-up output path like
|
||||
`<output>/<ProjectName>/<ProjectName>/<ProjectName>.csproj` instead of the flat
|
||||
`<output>/<ProjectName>/<ProjectName>.csproj` consumers expect. Keep the `.csproj`/
|
||||
`.cs` files directly under `content/`.
|
||||
|
||||
## Git on generation — why there's no automated `git init`
|
||||
|
||||
A generated project is **not** a git repository, and there is no `postAction` that
|
||||
tries to make it one. This was verified, not assumed — re-verified against the
|
||||
`dotnet` 10.0.400 SDK on this machine while working on this exact question:
|
||||
|
||||
- `dotnet new`'s only postAction capable of running an arbitrary process is the
|
||||
"Run script" action (id `3A7C4B45-...`). Wiring it to run `git init`/`git add`/
|
||||
`git commit` hangs forever in any non-interactive shell: the CLI's script-execution
|
||||
security gate demands an explicit `Y` typed at a
|
||||
`Do you want to run this action [Y(yes)|N(no)]?` prompt, once per script action.
|
||||
`dotnet new create --help` on this SDK exposes no `--allow-scripts` or equivalent
|
||||
flag to pre-approve it (unlike the NuGet-restore postAction, which the CLI treats
|
||||
as trusted and never gates). Do not reintroduce "Run script" postActions for this
|
||||
without re-verifying that gate no longer applies on whatever SDK is current then.
|
||||
- A previous revision compensated with a `SkipGit` symbol plus a "display manual
|
||||
instructions" postAction that just printed the `git init` one-liner. That has been
|
||||
removed — it wasn't automation, just a reminder to run a command any git user
|
||||
already knows, so it wasn't worth the extra symbol/postAction/`ide.host.json` entry.
|
||||
- Visual Studio's own "New Project" dialog already has a built-in "Create new Git
|
||||
repository" checkbox that works for any template, including this one, with zero
|
||||
template-side configuration — so VS users get real automatic git init for free.
|
||||
CLI users just run `git init` themselves after generating.
|
||||
|
||||
## LabAPI contract (verified against northwood-studios/LabAPI source, not guessed)
|
||||
|
||||
`Plugin<TConfig>` (`LabApi.Loader.Features.Plugins`) requires implementing:
|
||||
`Name`, `Description`, `Author`, `RequiredApiVersion` (all abstract get-only) plus
|
||||
`Enable()`/`Disable()`. Overridable but optional: `Version` (defaults to the
|
||||
assembly's version), `Priority` (`LoadPriority`, defaults to `Medium`),
|
||||
`ConfigFileName` (defaults to `"config.yml"`). `Config` is a plain `class` with a
|
||||
public parameterless constructor and public get/set properties — the base class
|
||||
(de)serializes it via YamlDotNet automatically; don't hand-roll config I/O.
|
||||
|
||||
**Never invent a LabAPI class/namespace/method/property/attribute.** Before using one
|
||||
you haven't already seen in this repo, check the restored package (`LabApi.dll` +
|
||||
`LabApi.xml` under `%userprofile%\.nuget\packages\northwood.labapi\<version>\lib\net48\`)
|
||||
or https://github.com/northwood-studios/LabAPI. If you can't verify a member exists,
|
||||
say so instead of guessing. No Skill/plugin specific to C#, .NET, MSBuild, NuGet, or
|
||||
LabAPI exists in the Claude Code skill catalog as of this writing — check
|
||||
`ToolSearch`/`SearchSkills` for one before editing in case that has changed, but don't
|
||||
assume one exists.
|
||||
|
||||
## Toolchain choices — don't "fix" these without being asked
|
||||
|
||||
- The project's `TargetFramework` is `netstandard2.1` on purpose, even though
|
||||
LabAPI's own docs and the `Northwood.LabAPI` NuGet package only target
|
||||
`net48`/`net481`. This is a deliberate compatibility choice (compiled output still
|
||||
loads under the game's Mono/.NET Framework 4.8 host) that trades away some
|
||||
netstandard2.1 BCL/language surface .NET Framework can't actually run (e.g. default
|
||||
interface members). Don't switch it to `net48`, don't add multi-targeting, unless
|
||||
the user asks.
|
||||
- `LangVersion` is pinned explicitly (currently `14.0`) — don't let it drift to
|
||||
`latest`.
|
||||
- The `.csproj` suppresses exactly two warnings, both scoped as narrowly as MSBuild
|
||||
allows, because of the netstandard2.1/net48-only-package combination above:
|
||||
`NU1701` (via a per-`PackageReference` `<NoWarn>`, not a project-wide one) and
|
||||
`MSB3270` (via `ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch=None`). Don't
|
||||
broaden either into a blanket suppression and don't remove them without
|
||||
understanding why (both are explained here, not in the `.csproj` — this repo's
|
||||
code style forbids comments, including in the `.csproj`, see "Code style" below).
|
||||
- The `Northwood.LabAPI` `PackageReference` uses a floating `Version="*"` on purpose,
|
||||
so every `dotnet restore` always pulls whatever is the latest stable release on
|
||||
NuGet at that moment — there's no version to bump here. This is intentionally
|
||||
**not** wired to `EntryPoint.cs`'s `RequiredApiVersion`, which can't be a floating
|
||||
value (`System.Version` has no such concept and would throw at runtime if it tried).
|
||||
`RequiredApiVersion` is a separate, manually-maintained literal representing the
|
||||
minimum LabAPI version the scaffolded code is known to work with — bump it by hand
|
||||
if you verify compatibility with a newer release, don't try to auto-sync it with the
|
||||
floating restore. Also be aware a floating version means a plugin generated today can
|
||||
restore a different (newer) LabAPI release than one generated last week, with no
|
||||
pinning — that's the deliberate trade-off of "always latest" over reproducibility.
|
||||
|
||||
## Code style for anything you write here
|
||||
|
||||
- No `//`, `/* */`, `///`, or XML (`<!-- -->`) comments unless the user explicitly
|
||||
asks for comments/documentation in that request. No comments restating
|
||||
self-explanatory code. `EntryPoint.cs`/`Config.cs`/the `.csproj` are already
|
||||
comment-free — keep them that way and follow the same standard for any new file.
|
||||
- All text embedded in code defaults to **English**: string/log/console messages,
|
||||
exception messages, `[Description]`/config text, any user-facing string. Example:
|
||||
`Logger.Info("Plugin initialized successfully")`, not a Spanish equivalent.
|
||||
- This never applies to identifiers the user picked — project name, namespace,
|
||||
class/method/property/variable names stay exactly as requested (standard C# casing
|
||||
rules aside). Honor an explicit request for a specific piece of text in another
|
||||
language.
|
||||
|
||||
## How to verify a change (no test suite exists — this is the actual check)
|
||||
|
||||
There is no automated test project. Verify any template change by actually
|
||||
generating a project from it and building that output. Replace `<repo-name>` below
|
||||
with this repo's actual folder name (the value you'd see in `sourceName`):
|
||||
|
||||
```bash
|
||||
dotnet new uninstall .
|
||||
dotnet new install .
|
||||
dotnet new labapi-plugin -n VerifyPlugin -o ../_verify/VerifyPlugin
|
||||
cd ../_verify/VerifyPlugin
|
||||
dotnet build
|
||||
```
|
||||
|
||||
Expect `Build succeeded. 0 Warning(s) 0 Error(s)`. If it isn't 0/0, the change broke
|
||||
either the template's own warning suppressions or something in `EntryPoint.cs`/
|
||||
`Config.cs`/the `.csproj`.
|
||||
|
||||
Notes:
|
||||
- Re-run `dotnet new uninstall .` + `dotnet new install .` after **any** edit to
|
||||
`.template.config/template.json` or the scaffolded files — the template cache
|
||||
keys off the installed path and stale content otherwise gets regenerated.
|
||||
- `dotnet build` also works directly inside `content/` (the placeholder project is
|
||||
itself valid and compilable), but that only proves the *unsubstituted* placeholder
|
||||
compiles — it does not exercise symbol substitution or the `sources` mapping.
|
||||
Always additionally verify through an actual `dotnet new` generation before calling
|
||||
a change done.
|
||||
- If `dotnet new install .` warns about another installed template sharing this
|
||||
identity (`SCPSL.LabApi.PluginTemplate`) from a different path — e.g. this repo's
|
||||
own parent folder having been installed by an earlier mistaken
|
||||
`dotnet new install .` run one level up — that other install shadows this one and
|
||||
your edits won't be exercised. Run `dotnet new uninstall <that other path>` first.
|
||||
- On Windows, if cleaning up `../_verify` fails with "resource busy", run
|
||||
`dotnet build-server shutdown` first, then retry; if it still won't delete, fall
|
||||
back to PowerShell's `Remove-Item -Recurse -Force`.
|
||||
- Delete the `../_verify` scratch output when done; it isn't part of the template.
|
||||
Reference in New Issue
Block a user