I am curious as to why the add-in doesn't appear for you on windows but for the moment lets take that as a separate issue and table it for now (although if you figure it out i'd love to know).
The sample add-in you provided has the same behavior as my add-in, for me at least. I can see the item in the sketch menu until I go into "flat pattern" - then it's gone. When i exit flat pattern it returns. This is NOT an issue with simply being in the "Sheet Metal" environment - this is specific to the Flat Pattern "view"

I've written a framework to make writing add-ins less tedious so sharing my code would require a good bit of diving in and since the simple sample you shared exhibits the behavior I don't think we're at that point yet - although I'm more than willing to share my code. None the less here's a snip of my button creation.
In my add-in class:
def add_button(self):
self.remove_button()
button = super().add_button()
button.toolClipFilename = os.path.join(self.resource_dir, 'captions/Thumb.png')
panel = self.ui.allToolbarPanels.itemById('SketchPanel')
panel.controls.addCommand(button)
button.isPromotedByDefault = True
button.isPromoted = True
return button
def remove_button(self):
button = self.ui.commandDefinitions.itemById(self.command_id)
panel = self.ui.allToolbarPanels.itemById('SketchPanel')
button_control = panel.controls.itemById(self.command_id)
if button:
button.deleteMe()
if button_control:
button_control.deleteMe()
And in my base class (which the above code calls via super...)
def add_button(self):
"""Called at an appropriate time to add a button to one of Fusions menus.
Overriders of this method should call super(), then they can add the button to the Fusion menu system if desired.
Finally the button object must be returned.
Returns:
ButtonDefinition
"""
return self.ui.commandDefinitions.addButtonDefinition(
self.command_id,
self.command_name,
self.command_description,
self.resource_dir)