diff --git a/src/ModelPublisher.Core/Models/ReleaseManifest.cs b/src/ModelPublisher.Core/Models/ReleaseManifest.cs
index ab93190..0853a45 100644
--- a/src/ModelPublisher.Core/Models/ReleaseManifest.cs
+++ b/src/ModelPublisher.Core/Models/ReleaseManifest.cs
@@ -38,10 +38,28 @@ public string ResolveFilePath(string relativePath)
return Path.GetFullPath(Path.Combine(ManifestDirectory, relativePath));
}
+ ///
+ /// Returns the description with the platform's disclaimer appended, formatted for the platform
+ /// (markdown if supported, plain text otherwise).
+ ///
public string GetDescription(IPlatformPublisher publisher)
- => publisher.SupportsMarkdown
- ? Description
- : MarkdownHelper.ToPlainText(Description);
+ {
+ var markdown = AppendDisclaimer(Description, publisher.Disclaimer);
+ return publisher.SupportsMarkdown ? markdown : MarkdownHelper.ToPlainText(markdown);
+ }
+
+ ///
+ /// Returns the description with the platform's disclaimer appended, always as markdown.
+ /// Use this when the caller handles its own format conversion (e.g. TipTap HTML injection).
+ ///
+ public string GetDescriptionMarkdown(IPlatformPublisher publisher)
+ => AppendDisclaimer(Description, publisher.Disclaimer);
+
+ private static string AppendDisclaimer(string description, string disclaimer)
+ {
+ if (string.IsNullOrWhiteSpace(disclaimer)) return description;
+ return $"{description}\n\n---\n\n{disclaimer}";
+ }
}
public class ManifestFiles
diff --git a/src/ModelPublisher.Core/Platforms/Cults3DPublisher.cs b/src/ModelPublisher.Core/Platforms/Cults3DPublisher.cs
index 6d80552..cc1565e 100644
--- a/src/ModelPublisher.Core/Platforms/Cults3DPublisher.cs
+++ b/src/ModelPublisher.Core/Platforms/Cults3DPublisher.cs
@@ -22,6 +22,8 @@ public class Cults3DPublisher : IPlatformPublisher
public bool IsFreeOnly => true;
public bool SupportsMarkdown => true;
+ public string Disclaimer => "";
+
public async Task PublishFreeAsync(ReleaseManifest manifest, IPage page, CancellationToken ct = default)
{
try
diff --git a/src/ModelPublisher.Core/Platforms/IPlatformPublisher.cs b/src/ModelPublisher.Core/Platforms/IPlatformPublisher.cs
index f93721f..76d9bc9 100644
--- a/src/ModelPublisher.Core/Platforms/IPlatformPublisher.cs
+++ b/src/ModelPublisher.Core/Platforms/IPlatformPublisher.cs
@@ -17,6 +17,12 @@ public interface IPlatformPublisher
bool SupportsMarkdown => false;
+ ///
+ /// Platform-specific disclaimer appended to the bottom of every description (markdown format).
+ /// Return empty string to omit.
+ ///
+ string Disclaimer => "";
+
Task PublishFreeAsync(ReleaseManifest manifest, IPage page, CancellationToken ct = default);
Task PublishPremiumAsync(ReleaseManifest manifest, IPage page, CancellationToken ct = default);
diff --git a/src/ModelPublisher.Core/Platforms/MakerOnlinePublisher.cs b/src/ModelPublisher.Core/Platforms/MakerOnlinePublisher.cs
index 8f8447c..fc3da35 100644
--- a/src/ModelPublisher.Core/Platforms/MakerOnlinePublisher.cs
+++ b/src/ModelPublisher.Core/Platforms/MakerOnlinePublisher.cs
@@ -21,6 +21,8 @@ public class MakerOnlinePublisher : IPlatformPublisher
public bool IsFreeOnly => true;
public bool SupportsMarkdown => true;
+ public string Disclaimer => "";
+
public async Task PublishFreeAsync(ReleaseManifest manifest, IPage page, CancellationToken ct = default)
{
try
diff --git a/src/ModelPublisher.Core/Platforms/MakerWorldPublisher.cs b/src/ModelPublisher.Core/Platforms/MakerWorldPublisher.cs
index 61dc88f..7aafee5 100644
--- a/src/ModelPublisher.Core/Platforms/MakerWorldPublisher.cs
+++ b/src/ModelPublisher.Core/Platforms/MakerWorldPublisher.cs
@@ -21,6 +21,8 @@ public class MakerWorldPublisher : IPlatformPublisher
public bool IsFreeOnly => true;
public bool SupportsMarkdown => true;
+ public string Disclaimer => "";
+
public async Task PublishFreeAsync(ReleaseManifest manifest, IPage page, CancellationToken ct = default)
{
try
diff --git a/src/ModelPublisher.Core/Platforms/PatreonPublisher.cs b/src/ModelPublisher.Core/Platforms/PatreonPublisher.cs
index 56531e2..cae236a 100644
--- a/src/ModelPublisher.Core/Platforms/PatreonPublisher.cs
+++ b/src/ModelPublisher.Core/Platforms/PatreonPublisher.cs
@@ -32,6 +32,8 @@ public class PatreonPublisher : IPlatformPublisher
public bool IsFreeOnly => true; // Patreon posts aren't free, but we do not have both free and premium tiers
public bool SupportsMarkdown => false;
+ public string Disclaimer => "";
+
public async Task PublishFreeAsync(ReleaseManifest manifest, IPage page, CancellationToken ct = default)
{
try
diff --git a/src/ModelPublisher.Core/Platforms/PrintablesPublisher.cs b/src/ModelPublisher.Core/Platforms/PrintablesPublisher.cs
index aa62fa3..9a64d9b 100644
--- a/src/ModelPublisher.Core/Platforms/PrintablesPublisher.cs
+++ b/src/ModelPublisher.Core/Platforms/PrintablesPublisher.cs
@@ -16,6 +16,8 @@ public class PrintablesPublisher : IPlatformPublisher
public bool IsFreeOnly => false;
public bool SupportsMarkdown => false;
+ public string Disclaimer => "";
+
public async Task PublishFreeAsync(ReleaseManifest manifest, IPage page,
CancellationToken ct = default)
{
@@ -93,7 +95,7 @@ await page
.CheckAsync();
// Step 8: Description — inject HTML directly into TipTap's ProseMirror div
- var descHtml = MarkdownHelper.ToTipTapHtml(manifest.Description);
+ var descHtml = MarkdownHelper.ToTipTapHtml(manifest.GetDescriptionMarkdown(this));
var descEditor = page.Locator("section")
.Filter(new() { HasText = "Description" })
.GetByRole(AriaRole.Textbox);
diff --git a/src/ModelPublisher.Core/Platforms/ThangsPublisher.cs b/src/ModelPublisher.Core/Platforms/ThangsPublisher.cs
index 124c812..3bdc96d 100644
--- a/src/ModelPublisher.Core/Platforms/ThangsPublisher.cs
+++ b/src/ModelPublisher.Core/Platforms/ThangsPublisher.cs
@@ -20,6 +20,8 @@ public class ThangsPublisher : IPlatformPublisher
public bool IsFreeOnly => false;
public bool SupportsMarkdown => true;
+
+ public string Disclaimer => "";
public async Task PublishFreeAsync(ReleaseManifest manifest, IPage page, CancellationToken ct = default)
{