Add-In ManagerDescription
Add-In Manager enables you to easily build and re-build Add-In files, manage versions of an add-in over time, directly access source files, and have extra customizations for your add-in. Now with version 2.0 of Add-In Manager, you can control your entire JSL application development life-cycle now that you can deploy your add-ins out to your users directly from Add-In Manager!
Quickly Build Add-Ins
The fundamental feature of Add-In Manager is the ability to build a JMP add-in file directly from source files. This feature was initially included in my Custom Add-In Builder add-in and Add-In Manager has taken the basics of that add-in and improved upon it.

Deploy an Add-In to Users
With version 2.0 of Add-In Manager, you can now deploy (or push) add-ins out to your users directly from Add-In Manager. You can deploy to a TEST location for your users to test out your add-in and you can also deploy to a PROD location.

When deploying to PROD, a JSL script with an Associative Array is automatically updated with the latest publish date/time. This Associative Array can be used by an auto-generated 'updateCheck.jsl' script that can compare the build date of the user's add-in to the build date according to the Associative Array. If a newer version of the add-in is available, the user will see the following window, where they can choose to update to the latest version. This concept using an Associative Array to check for updates was adapted from @brady_brady's method of using a table with publish dates. This method is described in @Jeff_Perkinson's post How to write self-updating JMP add-ins.

Manage Versions of an Add-In
Add-In Manager has the ability to automatically keep a version history of an add-in file each time a new one is built. It allows you to install, restore, or delete a previous version of an add-in. You can optionally include a comment for each build so you can keep track of what changes went into each version.

Making Extra Add-In Customizations
Add-In Manager allows you to make a few customizations to your add-in that previously required manual changes to XML. Below are the extra customizations available in Add-In Manager.
- Max JMP Version
- Built-in JMP Icons for menu items
- Insert before position for specifying a position for a menu item
- Custom menu bar – create your own menu or use an existing menu other than “Add-Ins”
- New in Add-In Manager 2.0: Multiple main menu's within a single add-in

Accessing Source Files Directly from JMP
On the Files tab within Add-In Manager, you can open files in your source folder directly from JMP by double-clicking on the desired file in the table.

Automatic Management of Custom Metadata
With Add-In Manager version 2.0, you can create your own custom metadata in addition to the metadata automatically included and managed by Add-In Manager.

Managing Previously Installed Add-Ins
From the Installed tab, you can enable, disable, or register installed add-ins as well register add-ins that are not installed.

System Requirements
This add-in is supported on Windows and Mac operating systems with JMP 13 or higher.
Blog Series
Add-In Manager, Part 1: Defining and building a JMP add-In
Add-In Manager, Part 2: Deploying auto-updating add-ins to users
Add-In Manager, Part 3: Advanced customization
Changelog
Version 1.1-1.3 (October 16, 2017)
- Fixed a few cases that caused the add-in to throw an error
- Added new preferences for controlling whether menus and toolbars are shown
Version 2.0 (November 22, 2017)
- Added support for deploying add-ins to TEST and PROD locations.
- Added support for custom metadata via an Associative Array that can be included in your scripts.
- Added ability to have multiple main menus in a single add-in.
- Added ability to copy and paste menu items in the Menu Item Tree.
- Added support for establishing a source folder from an existing 'jmpaddin' file.
- Added ability to check for a new version, pulled directly from the JMP Community.
- Added preference to automatically install add-ins after being built.
- Removed support for building multiple add-ins at a time, for various reasons.
- Squashed other various bugs.
Version 2.1 (February 26, 2018)
- Added preference to exclude invisible files and folders (i.e. files/folders that start with a period). This is useful if you're using a version control system, like Git.
- The customMetadata.jsl file is now ignored when determining if you have the latest version installed.
Version 2.2 (March 8, 2018)
- Fixed an issue when adding more than two top-level main menus.
- Added new icons to selection screen. Removed icons only available on one OS.
Version 2.3 (April 6, 2018)
- Fixed error on Mac caused when a source folder was renamed or deleted
- Preferences window now works even if you don't have the Consolas font installed on your computer.
Version 2.4 (January 9, 2020)
- Allow inserting menu items either before or after other items, instead of only allowing inserting after.
- Add 15 and 16 as min/max JMP version numbers.
Version 2.5 (February 5, 2020)
- Improve readability when using macOS Dark Mode and Windows High Contrast mode in JMP 15.
- Fix alert shown when opening preferences on Mac.
Version 2.6 (June 4, 2020)
- Fixed bug with parsing add-ins with custom menus.
- Added diagnostic info for parsing errors to help with future issues.
Version 2.7 (June 10, 2020)
- Add workaround for temporary bug in JMP 16 EA
Version 2.8 (September 24, 2020)
- Fixed issue unzipping add-ins with subfolders
- Added option to automatically create a folder when using an add-in template (on by default).
Version 2.9 (February 4, 2021)
- Changed some date formatting to Locale formats
- Fixed the check for update feature
Version 3.0 (January 18, 2022)
- XML special characters (such as '&') should no longer break addin.jmpcust files.
Version 3.1 (March 4, 2022)
- Fixed date format warning for some locales when archiving add-ins.
Let me know if you find any issues!
Current Version=3.1
2.9
Add-In Manager enables you to easily build and re-build Add-In files, manage versions of an add-in over time, directly access source files, have extra customizations for your add-in, and deploy your add-ins out to your users.

UtilitiesRe: Add-In Manager@Justin_Chilton JMP17 is displaying empty menu structures for my add-ins where JMP16 is showing menu items. It is the same for all three addins. See my earlier message on Sep 14th 2021.

Re: Add-In Manager@Justin_Chilton, @nathan-clark I am finally coming back to my TEST Addin Auto Update function. I think I did get it running OK with the exception that the Add In manager is not writing out the Metadata Folder for the TEST setup.
Any chance to enable this ? otherwise one needs to manually update these files every time which is rather error prone.
Henning
Re: Add-In ManagerHi @Justin_Chilton
While trying various things after posting the question, I suspected that the file was damaged by the internal industry security system.
When I received the file from the outside and proceeded with the reinstallation, it was installed normally.

I will keep the questions and answers for the same case.
Thank you always, Justin
Dave_Ryu.
Re: Add-In ManagerHi @Justin_Chilton
I am receiving a lot of help building using Add-In Manager.
I was using it well up to v2.9, but the following error occurs when reinstalling.
This error occurs in both v2.9 and the latest version of v3.1.
When I run the installation file, the error occurs immediately and does not proceed.
Can you tell me how to take action for the error?

Many Thanks.
Dave_Ryu.
Re: Add-In ManagerHI @Justin_Chilton, I ran into this error below when I was deploying to a TEST folder. Appreciate the add-in otherwise! This should have been a standard feature in JMP 
Error Message:
{"argument should be character"(1, 2, "Concat", Bad Argument(currentAddinInfo["Name"]), "You have not saved your updated information for the " || /*###*/currentAddinInfo["Name"] || /*###*/" add-in." /*###*/)}
Error: argument should be character
1 time(s).
Type: Error
Function Name: Concat
Bad Argument: currentAddinInfo["Name"]
Function being executed: "You have not saved your updated information for the " || /*###*/currentAddinInfo["Name"] || /*###*/" add-in." /*###*/
Call Stack:
saveButtonCheck
refreshAddinTableBox
deploySelected
Re: Add-In Manager@Justin_Chilton thank you for the suggestion. You are correct that what I wanted can be handled by include(). Thanks for the tip on <
Not sure why my zip didn't work, but I was doing it on a Mac, and all the entries disappeared after my manual attempt. Now that I got include working there's no need for manual edits anyway.
Re: Add-In Manager@steveylin, simply zipping the add-in contents and renaming to xxx.jmpaddin should work, you just have to ensure that the jmpcust and def files are at the root of the jmpaddin zip file.
Alternatively, I would suggest adding your path as an include() for "Run thi JSL" instead of using the script directly using a path. This would avoid the need to manually edit the jmpcust file. I am not sure why path would not be working for you, but this is the setup I actually use for my add-ins.

I like to use <
Re: Add-In ManagerI'm a novice trying to get addin working. I got it to work referencing a directory, but it defaults to "text" and I have to manually change to "path"
"path">$ADDIN_HOME(com.cirrus.pejmpscriptsMac)\pe-jmp-scripts\Check_Duplicate_Measurements.jsl
The problem I have is I'm able to modify .jmpcust to get it to work on my computer, but I can't export it. Is there an easy way to take the addin.def/addin.jmpcust and compress it myself? I'm hoping it's something easy and I don't have to use add-in manager.
I tried using zip and renaming but that didn't work.
Regards,
Steve
Re: Add-In ManagerHi @Justin_Chilton, I recently came got this error in deploying a new Prod version.
Error Message:
{"argument should be character"(1, 2, "Concat", Bad Argument(currentAddinInfo["Name"]), "You have not saved your updated information for the " || /*###*/currentAddinInfo["Name"] || /*###*/" add-in." /*###*/)}
Error: argument should be character
1 time(s).
Type: Error
Function Name: Concat
Bad Argument: currentAddinInfo["Name"]
Function being executed: "You have not saved your updated information for the " || /*###*/currentAddinInfo["Name"] || /*###*/" add-in." /*###*/
Call Stack:
saveButtonCheck
refreshAddinTableBox
deploySelected
Re: Add-In ManagerHi Nathan,
Yes, I did build it first and I didn't get any errors. But I get the deploy message anyway.
John
Re: Add-In Manager@Gido_vanderStar ,
It looks like you are probably using a different locale than I am, which is causing the unknown format error. I just updated the add-in (v3.1) which makes the date format used during the archiving process respect the date format for your locale.
Re: Add-In Manager@john_madden Did you click the build button first? That's the button next to the save icon. That will build the addin and place it in the development folder.
Then you can install DEV .... Or you can deploy a TEST or PROD build of the addin. (you need to deploy a TEST or PROD addin before you can install the TEST or PROD addin.
Re: Add-In ManagerHi Justin,
When I try to install my add-in (which AIM builds just fine), I get an error "The DEV/TEST/PROD add-in does not exist". What could I be doing wrong?
John
AIM 3.0, JMP Pro EA 17.0b6, OS X 12.2.1
Re: Add-In ManagerHi @Justin_Chilton ,
Thanks for this plugin. Just wanted to report one annoyance. When installing or deploying an add-in, I get the following message about 50 times in the Log:
Unknown format: m/d/y h:m
Using latest (v3.0) version of the add-in, in JMP 16.0.0, Windows10.
Re: Add-In Manager@vohwinkelh0 I harvested Justin's auto update code, and it would be pretty easy - I believe - to make a few updates to allow what you are talking about.
Depending how you have it integrated, you may be able to play with your local code to make those updates. As it stands, the code has a step that basically sees if the installed version is PROD and t hen checks for a newer build. I believe you could do the process if the installed version is PROD OR TEST ... and check the deployment area metadata to see if there is a newer PROD build.
It may be something you could look into to cover your needs until bandwidth opens up 
Re: Add-In Manager@pauldeen, thanks for reporting that! It should be fixed in v3.0.
Re: Add-In Manager@vohwinkelh0, that sounds like a great idea for a feature in Add-in Manager. It sounds like you would need some sort of separate TEST (or beta) versioning? Unfortunately, I currently don't have the bandwidth to implement something like that, but I am sure it could be done by adding some custom metadata fields and using those in your code to know if it is a TEST build.
Re: Add-In Manager@Justin_Chilton entering a & in the tooltip field causes a malfunction on write to addin.jmpcust which causes it to no longer be parseable. (JMP 16.1 Windows 10).
Re: Add-In Manager@Justin_Chilton do you know if there is a way to implement the auto update function as well on TEST? I frequently stumble upon the fact that I hand out the TEST to users to test a feature, however once PROD updates they are not getting that update deployed since the TEST Addin does not automatically check wheter there is a new PROD version ?
Re: Add-In ManagerThanks @pauldeen! Didn't know the addinLoad.jsl functionality is available (hidden in the guide). That solution works for my problem!
Re: Add-In Manager@Djtjhin You can either deploy an empty addin to all computers with a addinLoad.jsl that includes your custom functions
Or
You could use your IT department to role out a jmpStartAdmin.jsl file which contains your custom functions as described here, no addin needed.
Re: Add-In ManagerHey @Justin_Chilton, I'm trying to use the add-in manager to deploy user-defined custom function which ideally runs on startup. Could you recommend the best way to do this using the add-in manager ?
Re: Add-In Manager@Justin_Chilton JMP17EA2 displays empty menu structures again, no errors in the log. Thanks for this addin, it should be integrated in JMP directly!
Re: Add-In Manager@Justin_Chilton @MikeD_Anderson
Thanks a lot for the response! I actually just stumbled upon the ability to do that the other day, but you beat me to posting it on here.
@MikeD_Anderson- the info about the fast JMP startup is really good to know, the app scripts were definitely starting to get pretty huge, so this helps a lot.
Part of what I was hoping to accomplish with the Add-In Manager was skipping the step of having to export the .jmpappsource to a .jsl or .jmpapp every time I wanted to test something, so what I ended up with was the code below. I'm not quite sure how it works, but when using OpenFile(), the .jmpappsource doesn't launch the app builder, and the app can be run directly. Exactly what I needed!
app = JMPApp();
app << OpenFile("$ADDIN_HOME(com.example.addin)\MyApp.jmpappsource");
app << Run;Re: Add-In Manager@mringqui & @Justin_Chilton - just a little color commentary on the method Justin mentions. You need to first compile the jmp app source file into a .jmpapp file. This can be done under File > Export when you're in application builder. You then include the .jmpapp file in the add-in package and open the .jmpapp file:
open("$ADDIN_HOME(com.example.me.myaddin)/MyApp.jmpapp");
This is what it looks like the JMP default Addin wizard.

Note that this has some nice knock-on effects over just imbedding the JSL directly. The biggest is that, for really big apps it will stop JMP being slow at start up. All the code needs to be parsed on start up - so if your script is really big or you have a ton of them, it can slow things down - a problem I had with the STK. Imbedding as an app means JMP just has to parse one line of code at start-up. There are some others, but that's the most important one IMO.
Re: Add-In Manager@mringqui, Thanks for reaching out. I was thinking that this would require some changes to the Add-in manager add-in, but @MikeD_Anderson showed me how to do this with how add-in manager already works.
Instead of setting a file to be run, use a script that runs the JMP app source file. You would just paste this into the text box for "Run this JSL."
Include("$ADDIN_HOME(com.example.me.myaddin)/MyApp.jmpappsource");</CODE></PRE></LINGO-BODY><LINGO-SUB id="lingo-sub-394777" slang="en-US">Re: Add-In Manager</LINGO-SUB><LINGO-BODY id="lingo-body-394777" slang="en-US"><P>Hi, great work! I'm hoping to create an add-in that uses a .jmpappsource file as the "Run JSL in this file" Action for the menu item. Is this something that could easily be added? Right now, being forced to use a .jsl file is limiting my ability to use the Add-In manager in a convenient way. Thanks!</P></LINGO-BODY><LINGO-SUB id="lingo-sub-386516" slang="en-US">Re: Add-In Manager</LINGO-SUB><LINGO-BODY id="lingo-body-386516" slang="en-US"><P><A href="https://community.jmp.com/t5/user/viewprofilepage/user-id/1855" target="_blank">@Justin_Chilton</A><BR />I use a combination of the $ADDIN_HOME and Get Default Directory() depending on where/how I need to include things. And for many of my includes, I do have a set of libraries which are common to many of my tools and I do treat them as a separate addin altogether. Then any tool I do make simply includes the file from $ADDIN_HOME and all of the library functions are available to me or anyone else who may want to use them.<BR /><BR />I am unsure why <A href="https://community.jmp.com/t5/user/viewprofilepage/user-id/2173" target="_blank">@tsl</A> has to add that extra layer to the zip. From my perspective, leaving it much like the organization in the his first hierarchy would make things more simple overall, but not knowing all the specifics of that infrastructure, there may be something I'm missing.<BR />Typically, the only update I need to make to a .jmpcust file, once the original stuff is set, is to update the display name for a version update (which I do in my repo, but could be done in addin manager).</P></LINGO-BODY><LINGO-SUB id="lingo-sub-386499" slang="en-US">Re: Add-In Manager</LINGO-SUB><LINGO-BODY id="lingo-body-386499" slang="en-US"><P>Thanks for the clarification <A href="https://community.jmp.com/t5/user/viewprofilepage/user-id/2173" target="_blank">@tsl</A>. It looks like to me that it could work with a few changes to your process. </P>
<OL>
<LI>Don't change the $ADDIN_HOME folder, and instead use relative paths and Get Default Directory(). This also makes it easier to develop the add-in as well because any references to that would be for the installed version.</LI>
<LI>Use a variable to determine the relative path location of CommonFiles and use that in your includes, since the location varies between a production add-in and the development repo.</LI>
</OL>
<P>Alternatively, you can scrap the idea all together of copying CommonFiles into each add-in. You can create a separate add-in entry for CommonFiles (it would have no command items), and require that the user to install that in addition to the add-in. This would mean that there is only one copy of the CommonFiles for the user (this may be a good thing or a bad thing depending on how often you test all add-ins after updating CommonFiles. With this, you could include the files using the $Addin_Home path variable, but you would still have to figure out how to include them from development. This might be similar to what <A href="https://community.jmp.com/t5/user/viewprofilepage/user-id/6649" target="_blank">@nathan-clark</A> is doing, but I am not sure.</P>
<P>Yet another alternative is that instead of me implementing the copy for you (someone restrictive), I can just implement a very flexible post-processing script that you can define. Say, you define a function that takes a reference to the ZipArchive, and you can manipulate it how you see fit. This solution probably requires the least change by you and me.</P>
<P>Sorry for all of the rambling, but hopefully one of these suggestions puts us in the right direction!</P></LINGO-BODY><LINGO-SUB id="lingo-sub-386453" slang="en-US">Re: Add-In Manager</LINGO-SUB><LINGO-BODY id="lingo-body-386453" slang="en-US"><P><A href="https://community.jmp.com/t5/user/viewprofilepage/user-id/1855" target="_blank">@Justin_Chilton</A> , yes, you are describing something very close to what I do. Let me elaborate a little, showing what happens if I use the Addin Manager. ( And I'm still exploring and learning how it works, so forgive me if I'm miss-representing what it can do ! )</P><P> </P><P>After building the Add-in, where I let the Source Folder be Addin_1\Source, I have a file we'll call Addin_1.jmpaddin sitting in the Addin_1\Release folder.</P><P>I rename that to a .zip extension, open it and take a look. I find it looks like this :</P><P> </P><P><SPAN class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Addin_Initial_Folder_Structure.png" style="width: 217px;"><span class="lia-inline-image-display-wrapper" image-alt="Addin_Initial_Folder_Structure.png" style="width: 217px;"><img src="https://us.v-cdn.net/6038925/uploads/images/32932i1AD28B843A933FC3/Addin_Initial_Folder_Structure.png" role="button" title="Addin_Initial_Folder_Structure.png" alt="Addin_Initial_Folder_Structure.png" /></span></SPAN></P><P> </P><P>(There are also a couple of XML files I use for managing some things, but we can skip those for simplicity )</P><P>I then manually change the zip by making a new folder within the .zip and dragging all the Source_1, etc files into that new sub-folder. I leave the addin.jmpcust and add.def in the root level, because otherwise the add-in won't install. I also leave CustomMetaData.jsl in the root level because I'm guessing that's where it needs to be.</P><P>I then drag into the .zip the CommonFiles folder that I also need. My final Zip structure looks like this :</P><P><SPAN class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Addin_Final_Folder_Structure.png" style="width: 220px;"><span class="lia-inline-image-display-wrapper" image-alt="Addin_Final_Folder_Structure.png" style="width: 220px;"><img src="https://us.v-cdn.net/6038925/uploads/images/32933i3C14631B2CA97BE7/Addin_Final_Folder_Structure.png" role="button" title="Addin_Final_Folder_Structure.png" alt="Addin_Final_Folder_Structure.png" /></span></SPAN></P><P>I then have one more thing to do : the <ACTION type=""path""> lines in the .jmpcust file need to be edited now. Whereas it says </ACTION></P><P>$ADDIN_HOME(com.x.y.z)\Source_1\Code_1.jsl</P><P>I need to change it to read</P><P>$ADDIN_HOME(com.x.y.z)\Addin_1\Source_1\Code_1.jsl</P><P>Which I can do with a Search / Replace in a text editor.</P><P>With all these steps done I can then deploy and install the Add-in and it all works.</P><P> </P><P>To your last comment, because this add-in is a suite of tools, each one has it's own "Source" subfolder within Addin_1, so in order to reference the CommonFiles, my Include() statements in Code_1.jsl etc does have an extra "..\" to go up one extra level to correctly find the include files.</P><P> </P></LINGO-BODY><LINGO-SUB id="lingo-sub-385991" slang="en-US">Re: Add-In Manager</LINGO-SUB><LINGO-BODY id="lingo-body-385991" slang="en-US"><P><A href="https://community.jmp.com/t5/user/viewprofilepage/user-id/2173" target="_blank">@tsl</A> <BR />I do something similar with subversion, and I use the addin manager post any Repo activities. Once all code is committed, I export to a location which becomes the "source" for the addin (a local or network folder). Personally, I manage my .jmpcust files and .def files in my repo so those get exported as well, but you could just export code and make the .def and .jmpcust files with Addin Manager (it will create the files in the source folder, and in my case, exporting new stuff from the repo will only overwrite files being exported).<BR /><BR />Then I use his tool to handle all of the packaging, archiving and distributing to my production folders (this is always what took the most time to do manually, anyways). To make things easier on myself, since I also had many addins being managed pre-Addin Manager, I also manually edited the jmp file which stores all of the information (addin, name, source folders, etc) so I had all my addins ready to go when I started the addin rather than adding them through that interface manually).</P><P> </P><P>In addition to the addin itself, there are also some functions included which I have updated to allow my users to get notified and automatically update addins as new releases are put into production.</P></LINGO-BODY><LINGO-SUB id="lingo-sub-385979" slang="en-US">Re: Add-In Manager</LINGO-SUB><LINGO-BODY id="lingo-body-385979" slang="en-US"><P><A href="https://community.jmp.com/t5/user/viewprofilepage/user-id/2173" target="_blank">@tsl</A>, what does the file structure look like for the add-in when you zip it up manually?</P>
<P>I imagine since your code includes relative paths to the CommonFiles directory that your add-in looks something like this? <SPAN style="font-family: inherit;">Is the Release folder not included in the addin file? </SPAN></P>
<P> </P>
<PRE>Addin_1.jmpaddin
|_Addin
|_Source<BR /> |_Code.jsl<BR /> |_Release<BR /> |_Something?<BR /> |_CommonFiles</PRE>
<P>In the above structure, the 'Addin' folder only exists to keep the folder structure the same for your relative paths. Is this the case for you?</P>
<P>I think I can add a new optional directory path that can be copied into the add-in file as part of the build process. However, we still need to solve the directory issue. To solve that, the idea I have is to add a small snippet to set the location of the CommonFiles directory, and use that for all of your common file includes. Alternatively, you could create a 'IncludeCommonFile()' function that tried to include from production location and failover to the dev location</P>
<P> </P>
<PRE><CODE class=" language-jsl">commonFilesDir = Directory Exists("../CommonFiles/",
"../CommonFiles/", // production location
"../../CommonFiles/" // development location
);
//or
IncludeCommonFile = Function({file},
Try(Include("../CommonFiles/" || file), Include("../../CommonFiles/" || file));
);
This would give you the following structure, and I *think* would work if I were to add a shared folder feature. The one hiccup I can think of this would be that if you have additional folders within Source, then the Include function would not work, or you would need additional '../' in your includes using the directory variable.
Addin_1.jmpaddin
|_Source
|_Code.jsl
|_CommonFiles
Re: Add-In ManagerHi @Justin_Chilton ,
I have just discovered your Add-in Manager and am intrigued. I have been manually managing add-ins for years now, up to and including manually editing .jmpcust files. I see opportunity to make my life much easier with your Add-in manager. However, I am wondering how to make it support what I want to do.
I will refer to the attached image of the proposed folder structure. The idea is there is a folder containing JMP code, we'll call it RepositoryRoot here. This folder is in a GIT lab repository and is shared and sync'd between two or more JSL developers.
Each developer owns an Add-in with in the repository. Let's call them Addin_1 and Addin_2. Those Add-ins are in their own respective sub-folders within the Repository.
There is also a folder we'll call CommonFiles within the Repository which contains some standard JSL library files that both Add-ins use.
These standard library files are included in the individual add-ins, for example a JSL file within Addin_1\Source might have a line like
include("..\..\CommonFiles\LibraryFile1.jsl");

So the question is how could we leverage this structure with the Add-in Manager ? I run into problems with two possible options :
1) If in the Add-in Manager I let "RepositoryRoot" be the Source Folder, then it creates Addin.def and Addin.jmpcust in RepositoryRoot. This doesn't work because we can only have one addin.def in a given source folder and we want to have separate add-ins with separate developers, but sharing code.
2) If I let "RespositoryRoot\Addin_1\Source" be the Source Folder, then addin.def and addin.jmpcust get created in the Source folder of Addin_1's sub folder. And that's good because it's contained in its own folder. BUT, I can't see any way to add the CommonFiles folder from two levels up in the directory tree to the add-in. The code requires that common files folder, but we want to keep it at the higher level for code sharing and sync'ing.
I understand that ultimately the "CommonFiles" folder does have to get duplicated into each final .jmpaddin file before the Add-in is released.
The hope was that we could find an Add-in manager capability that would manage that for us. Our alternate is to manually create .zip file and set up the folder structure the way we need it , then change the extension to .jmpaddin prior to publishing.
If you have ideas or would consider having the Add-in manager support this capability, that would be great.
many thanks
Tom
Re: Add-In ManagerThank you for your reply @Justin_Chilton ! I ended up enforcing a light-theme for jmp to avoid the color issue altogether. I will try your suggestions, clicking on the escape key to solve the lag time.
Re: Add-In ManagerHi @alavy ,
I am not sure what is going on with the slow response time. I will have to do some further investigating to see if it is an issue with my add-in or a problem with JMP. However, I did find a decent workaround. The first time you click into a text edit box, hold the escape key until the text is no longer in focus. Now all of the edit boxes should work without any delay after you click into them.
As for the color scheme, I am not sure what would cause this. Any version of the add-in after 2.5 should have proper coloring for dark themes. I think the only way to reproduce that issue is if you switch from light to dark theme while JMP is open. I always get the view below with the gray theme.

Re: Add-In ManagerHey @Justin_Chilton ,
I am using v2.9 of the add-in on JMP 15.1 running on MacOS. I encounter a VERY slow response time any time I need to enter text into any of the text boxes of the add-in. This is so slow that it renders the add-in unusable.
A second, smaller issue, is that none of the color schemes work properly with JMP set in dark-mode. The color of the text in the text boxes is too light and cannot be read against the background color.

Re: Add-In Manager@Justin_Chilton I believe I do have write access as I can see that the old addin was archived correctly and the new addin was updated, yet I still see the error. I'm not sure which step specifically that failed. With regards to the mounted network drive, unfortunately I'm probably out of depth on that one. I'm not sure about that status, but perhaps I can ask around my colleagues to find out more.
Re: Add-In Manager@Djtjhin, it sounds like it is very likely related to it being a sharepoint location. Can you confirm that you have write access to that location by creating a file in File Explorer? Even if you do have permission, JMP may not have permission as an application. Are you using a regular network path or are you saving through a mounted network drive? Mounting your sharepoint server as a network drive can resolve issues around permissions, as JMP can just save to the mounted drive. With the regular network path, credentials may be required, which is something JMP does not support.
Re: Add-In ManagerThanks for clarifying Justin!
Follow up question, I receive the following error message as I was trying to deploy to production. The destination folder is actually a sharepoint. I'm not sure if that's the reason or perhaps there's a workaround.
Error Message:
{"File not open in Write mode. "(1, {1}, 2, "Save Text File", Save Text File /*###*/(filepath, str))}
Error: File not open in Write mode.
1 time(s).
Data Table Indices: 1
Type: Error
Function Name: Save Text File
Function being executed: Save Text File /*###*/(filepath, str)
Call Stack:
deploySelected
Re: Add-In Manager@Djtjhin,
I would recommend putting the statement in each command to have the check whenever the add-in is used and not every time the user launches JMP. Also, there have been issues with updating add-ins at startup, so doing that when a user clicks and add-in command is a safer way to do it.
Re: Add-In Manager@Justin_Chilton can I clarify a response you provided Sebastien previously ? So, will the auto-update statement (below) work if I place it in the "start-up Script" (snapshot) ? Or we should only include the auto-update statement under each command script ?
Include( "$ADDIN_HOME(com.jmp.myaddin)\updateCheck.jsl" );
com.jmp.juchil.addinmanager:checkForUpdate();

Thanks
Daniel
Re: Add-In ManagerConfirmed, it works again, thanks!
Re: Add-In ManagerThanks @pauldeen. I think there were several different factors colliding for this. For one, the error should be resolved in the final JMP 16.0 release, but was in there for EA8. Additionally, this error likely happens because your Locale does not support the date format I used. To fix this, and be more Locale friendly, I have updated some places where I format dates to use Locale Date Time instead of specific formats. This should fix the error and put the dates in a more friendly format.
Re: Add-In ManagerThanks for the 2.8 fix on the folders!
I have a new one for you:
Opened Add-in manager, selected an add-in:

Running JMP 16EA8.
No problem with the same thing on JMP 15.2.0 both under windows 10
Re: Add-In Manager@Justin_Chilton Thank you! I'll try that.
Re: Add-In Manager@pauldeen, I just uploaded a new version (v2.8) which fixes that subfolder issue you were seeing. I also added a checkbox option to automatically create a folder for you, like you originally had expected it to work.
Re: Add-In Manager@Sburel, You can add that code anywhere you would like to check for an update, such as at the start of a menu item command. This could make it so that when a user clicks on the command, it will check for a new version before launching the add-in.
If I recall correctly, there was an issue with using this code in the addinLoad.jsl file, which would cause it to check at JMP start-up time, but there were issues with re-installing the add-in while the add-in is still being loaded. This issue may or may not be still an issue.
-Justin
Re: Add-In Manager@Justin_Chilton
Really cool addin. Works Really well. However, I've been struggling to use auto-update function. In particular, I'm confused with the appropriate file/location to add the following code snippet
Include( "$ADDIN_HOME(com.jmp.myaddin)\updateCheck.jsl" );
com.jmp.juchil.addinmanager:checkForUpdate();
Best
Sebastien
Re: Add-In Manager@Justin_Chilton Ah yes creating an empty folder gets you past this screen. The name of the folder seems to not be important, only the fact that it is empty.
On testing I found this other bug:
If I take your Add-In Manager v2.7.jmpaddin and create the empty folder then load it up like this, I get past the adding screen but with a big error: The same happens with other add ins that have sub folders inside them.

Re: Add-In Manager@pauldeen The source folder is where the jmpaddin file will get unzipped too (I probably should have made it automatically create the folder, but I guess I didn't). I suggest creating a folder called "ASM Training Material" within the "Desktop" folder and setting that as the source folder. The source folder can't have anything in it because it would all end up zipped in the add-in.
Re: Add-In Manager@Justin_Chilton When adding a add-in from a existing .jmpaddin file we have a bug at this screen:

You cannot leave the source folder blank and if you put anything in there you get a warning that it needs to be blank when starting from a jmpaddin file..
Re: Add-In Managerworks like a charm. Thank you Henning
Re: Add-In ManagerHi @vohwinkelh0,
Thanks for reporting this. I saw that error a few days ago and your comment reminded me, so I finally was able to track down the issue to an bug with one of the file/directory functions.
I have updated the add-in on this page to workaround this issue for now, but I also noted the issue in JMP so that we can address it before JMP 16 is released.
Thanks,
Justin
Re: Add-In ManagerJustin,
I am getting an Error with your Add In as part of the JMP16EA programs. You want me to file a bug report there or should i post it here ?
Henning
Re: Add-In ManagerThanks a lot for sharing... will try it next week.
Re: Add-In Manager@guillaumebugnon So I use this function in a for loop for encrypting the scripts.
encryptScript = Function({filepath},
{defaultLocal},
errortxt = "";
winCount = N Items (Window ());
scriptWin = Open (filePath);
scriptWin << Bring Window to Front;
Wait (1);
Main Menu ("Encrypt Script");
windowList = Window ();
encryptedWin = windowList[nitems(windowList)]; // get reference to encrypted script window (i.e. the last window)
//TODO: Implement without Try
Try (
encryptedScript = encryptedWin[Script Box(1)] << Get Text;
save text file(filePath, encryptedScript);
ConsoleMsg("File Encrypted: "||filepath); // hoping this goes to stdout
,
errortxt ||= char(exception_msg) || "\!r\!n";
);
Try (scriptWin << Close WIndow());
Try (encryptedWin << Close WIndow());
Return (errortxt)
);
Then I have another autoit script that goes through and types in the password and presses enter.
It's definitely not a perfect solution and your wish list item would be way better.
Re: Add-In Manager@pauldeen,
Thanks for reporting that issue with the custom menu add-ins. I just uploaded a new version that should fix this.
-Justin
Re: Add-In Manager@Justin_Chilton thanks for your answer.
it might be useful to have a jsl capabale function that can encrypt other jsl files (or some other way to do that).
I watched @vince_faller presentation this morning (french time). Nice one.
We also have some Devops process but need to automate more.
Guillaume
Re: Add-In Manager
@guillaumebugnon,
@vince_faller might have some tips on encrypting scripts. However, I would need to add a feature to Add-In Manager to be able to allow modifying the files to be added before the zip process.
I think @vince_faller also did a presentation/webcast yesterday that might be useful to you here: https://www.brighttalk.com/webcast/18305/412912
- Justin
Re: Add-In ManagerHello everybody,
Does anyone have a tips or experience for encrypting scripts before they're zipped up in the jmpaddin file?
Thanks
Regards,
Guillaume
Re: Add-In Manager
Running on JMP15 Windows 10, addin manager can no longer parse the menu structure from an existing add-in.
To reproduce: Create a new addin and rename the top level menu using custom. Create a command and save the addin definition.
Close addin manager, re-open and try to see the menu items tab for the just created Add-in (make sure you view this one first before looking at any of your other addins menu structure).
To get this to work, create a second add-in where you do not change the top menu item but leave it at the default "Add-Ins". Save this addin. Close add-in manager, open again, first view the menu structure of the one with the default top level name and then go view the menu structure of the custom one. It all works again.
Re: Add-In Manager#2 started with JMP15/OSX15, but I haven't tried out 2.4 yet and will get back to you.
Re: Add-In ManagerThanks, Justin!!
Re: Add-In ManagerHi @john_madden,
Thanks for reaching out and apologies for the delay.
#1 should be addressed in v2.4 which I just uploaded here.
For #2, I am not able to replicate this issue on Windows, but I will investigate further on Mac. Do you happen to know if this issue started with a specific JMP version number (i.e. JMP 14/15) or with a macOS version (10.14/15) or has it always happened for you?
Thanks,
Justin
Re: Add-In ManagerHi Justin,
I'm having a couple of issues with Add-In manager under JMP 15/Mac OS 10.15.
(1) [trivial] maximum/minimum JMP version options needs to include 15
(2) [less trivial] Entering text into text boxes in a number of panes within the manager seems (partially) broken. I can enter text (e.g. Add-In Name, Version etc) by pasting, but not by typing.
Thanks.
John Madden
Re: Add-In ManagerHi there, I have started using Add-In manager after many years of managing changes manually. However, I recently had an issue with the Menu items not being visible I updated to JMP 14.3.0 recently, not sure if this is related. I had no issues with this before.
As you can see there are no errors in the build or deployment flagged so I'm at a loss as to what is happening.
Any help or suggestions are appreciated as I really don't want to have to rebuild it from scratch.
Regards,
Derek.

Re: Add-In ManagerHi Adam,
Appologies for the delayed reply. Based on the error message you are seeing when removing the try, it looks like my assumption about the updateCheck script being able to find the customMetadata file was correct. I see where you have the '
aa = Include( "$ADDIN_HOME(com.jmpTest.myjmpaddin)\customMetadata.jsl" );' part of your script. However, you don't actually need to include the file there. Instead, you want to change the include within the updateCheck.jsl script. It should look something like the following (around line 11).
customMetadata_aa = Include( "<SPAN>$ADDIN_HOME(com.jmpTest.myjmpaddin)\</SPAN>customMetadata.jsl" );
Let me know if you have any additional questions.
Regards,
Justin
Re: Add-In ManagerHello Justin,
As this is my first Add-In and I am an infant in regards to JMP experience (around 11 months of use), I may begin asking simple questions now as I work through activating the update-check function. I have created a simple test add-in to focus on only the update function so I can understand this functionality before applying it to my more robust program.
THE SCRIPT:
aa = Include( "$ADDIN_HOME(com.jmpTest.myjmpaddin)\customMetadata.jsl" );
Include( "$ADDIN_HOME(com.jmpTest.myjmpaddin)\updateCheck.jsl" );
com.jmp.juchil.addinmanager:checkForUpdate();
New Window ("Test 3",
Panel Box ("Test 3",
Text Box("Test 3")
)
);
Responding to your questions:
- Did I have the "Create Metadata File" preference set?
- I did have the checkbox selected for "Create Metadata File", but I did not have the custom metadata code containing the include statement within my script. I have added this line of code to the row immediately before the update check code as you can see above, but it did not correct the issue.
- What is the directory structure of my addin?
- In the middle section of the Add-In Manager window, Under the Files tab, addin.def, addin.jmpcust, customMetadata.jsl, and updateCheck.jsl all exist within the same folder. That folder exists in the same parent folder as the addin file itself (.jmpaddin).
- This folder exists on my C drive, NOT on the server. Should I have saved these files to the server as well?
- In the bottom section, Prod tab, I have all three options saving to a server location. They each have their own folder, and all three folders exist within the same parent folder.
- ARCHIVE – only contains previous iterations of the add-in as I deploy.
- META – only contains the file publishedAddins.jsl
- PROD – only contains the add-in installer file .jmpaddin
- What error message do I receive when commenting out “Try()”
- I receive the error message “Error with file: Path is invalid: \customMetadata.jsl”
- I have tried changing the above location path from the $ADDIN_HOME... language to the exact location on my C drive as it is called out in the File tab (middle section). It did not help, I received the same error message.
Thank you for your assistance!
-Adam
Re: Add-In ManagerHi @Adam_R,
Thanks for all the work on the details! A few questions and things to try:
- Do you have the "Create Metadata File" preference set under the "Custom Metadata" preference group? This file is required for the update script to pass.
- What is the directory structure like for your addin? Is the script calling 'com.jmp.juchil.addinmanager:checkForUpdate' in a lower level folder? If so, the updateCheck.jsl file is expecting it to be in the same folder where the folder is being called from, making the function not work. A workaround for this is to add another JSL file at the root level of your addin (same as customMetadata.jsl and updateCheck.jsl) that calls the updateCheck function and just include that file in the lower level JSL script. Another option is to edit the updateCheck.jsl script to use '$addin_home(com.jmp.myaddin)/customMetadata.jsl' instead of just the relative file name. If this is the issue, I can update the addin to make this more flexible where it's not so dependent on the default directory of where you call the function.
- The updateCheck.jsl script is implemented so it fails silently using a Try() so to not mess with the workflow of your add-in. So, if neither of the first two suggestions fix it, could you comment out the Try() within the updateCheck.jsl file and let me know what error message you get when you attempt to check for an update?
Let me know if you have any questions.
Regards,
Justin
Re: Add-In ManagerHello Justin,
Add-In Manager v2.3 is working wonderfully in all aspects for me but one, I am unable to get the updateCheck to correctly push updates. Some facts:
- My code outside of the update check runs correctly.
- My PROD folders "Metadata" and "Deployment" are both on server locations under the same parent folder, and I have verified users have access to them both.
- Within the Preferences section, I have selected "Include Update Check Script", and copied the include statement provided in this section into my code. I have edited the add-in ID section of this statement from (com.jmp.myaddin) to match my add-in. I did not edit anything else within this statement and did not edit anything within the updateCheck.jsl script.
- When making changes to the add-in and deploying to PROD, I have verified that the "pubDate" within the publishedAddins.jsl file located in the Metadata server file has changed with each deployment
- I have had users download an existing version of the file located within the PROD folder, close JMP, reopen JMP, and run the add-in with success.
- I have deployed a newer iteration to PROD, verified the pubDate changed, and requested the previous user to reopen JMP and run the existing add-in. The user is never prompted to update the add-in.
- I have had the same user go into the PROD folder and reinstall the add-in, which has successfully updated the Add-In.
Re: Add-In ManagerHi Aubrey,
The Include statement within the updateCheck.jsl script uses a relative path to the customMetadata.jsl file. As long as both of those files are in the same folder, it should work properly. What does the folder structure look like for your add-in?
Feel free to send me a private message if you need to send anything you don't want on this public post.
Thanks,
Justin
Re: Add-In ManagerJustin,
I'm having an issue with the autoupdate feature. I have traced the issue back to the updateCheck.jsl script.
The following line fails, then the try statement exits.
customMetadata_aa = Include("customMetadata.jsl" );
If I add the following to the file path there are no issues and it looks like things work as advertised.
$ADDIN_HOME(my_addin_here)
Am I supposed to be doing this for each addin or should this be automatic?
Thanks,
Aubrey
Re: Add-In ManagerJustin,
Version 2.3 works like a charm on my Mac! Thank you!!!
John
Re: Add-In Manager@Justin_Chilton Thanks! I'll give that a try.
Re: Add-In Manager@john_madden,
Thanks for reporting this! It looks like you are using a Mac, and you must have renamed or deleted one of your source folders. I have added a check for this now (v2.3) so it should not fail anymore.
Re: Add-In Manager@nathan-clark,
If you still have version 1.3 of the add-in, you can change the ID and menu item name for that version and use it along side the new version. Version 1 allows you to use check boxes to build multiple at a time and should be able to hook up with the data table used by version 2. There were a lot of architectural changes in v2.0 so unfortunately I had to remove the checkboxes. I have it on my list to add those back in the future.
Re: Add-In ManagerHi Justin,
In JMP 14.0.1, I keep getting this error:
Error Message: {"argument should be list"(1, 2, "Concat Items", Concat Items /*###*/(errorList, " "))} Error: argument should be list 1 time(s). Type: Error Function Name: Concat Items Function being executed: Concat Items /*###*/(errorList, " ") Call Stack: getLastModifiedDateOfNewestFile getStatusIcon refreshAddinTableBox initialize
Any ideas? This is Manager 2.2.
John
Re: Add-In Manager@Justin_Chilton
Thanks again for this addin. I am finally getting up to speed with the new version and taking advantage of some of your improvments on what I was doing manually
My one ask, and I'm not sure if this is possible, is to be able to build several addins at once. I know the bottom panels for information and directories are addin specific, but perhaps those could disappear if more than one addin is selected. Then all selected could be DEVd/Deployed/etc.
I manange over 40 addins right now and I often make updates in batches so being able to do a bunch of all of the addins at once would be amazing!
Re: Add-In ManagerThank you for this! Now creating and updating add-ins so easy that I develop and improve my own add-ins more often than in the dark ages before this tool.
Re: Add-In ManagerI want to be so good, and charitable and thank JMP developers for the 13th version of a software program that I love to teach with. I've had it since version 5.0, with it's well thumbed paper manuals and to be honest nothing has been added that is of any value to me since that version. But loving version 5.0 as I did, I have happily and willingly upgraded each year. And then the ROC-Curve & partial Area Under the Curve Analysis script came along which was beautiful in JMP12. I have set up a teaching session to show my students about ROC curves.... and I upgraded to v13...... and now it doesn't display the curves. boo.
Re: Add-In ManagerHi @tejvishnu,
Yes, JMP 13 is required to install this add-in. Unfortunately, I was not able to make this add-in compatible with JMP 12. I have updated the post to include this this information.
Thanks,
Justin
Re: Add-In ManagerThe add-in does not seem to get installed on my computer. This seems to be the issue with some of the recently uploaded add-ins. Does this add-in require JMP-13?
I have JMP 12.2 on my computer.