[{"data":1,"prerenderedAt":34},["ShallowReactive",2],{"doc:en:plugins\u002Fmanifest":3},{"title":4,"lede":5,"html":6,"headings":7},"The manifest","Every Escouade plugin describes itself in an escouade-plugin.json file at the root of its folder. This page is its reference: each field, what Escouade checks, how it installs a plugin and why it disables one.","\u003Ch2 id=\"a-complete-example\">A complete example\u003C\u002Fh2>\n\u003Cpre>\u003Ccode class=\"language-json\">{\n  &quot;$schema&quot;: &quot;https:\u002F\u002Fescouade.dev\u002Fschemas\u002Fplugin-1.json&quot;,\n  &quot;id&quot;: &quot;dev.exemple.slack&quot;,\n  &quot;name&quot;: &quot;Slack&quot;,\n  &quot;version&quot;: &quot;1.2.0&quot;,\n  &quot;description&quot;: { &quot;fr&quot;: &quot;Les tickets à tester dans un salon Slack.&quot;, &quot;en&quot;: &quot;Tickets to review in a Slack channel.&quot; },\n  &quot;author&quot;: { &quot;name&quot;: &quot;Exemple&quot;, &quot;url&quot;: &quot;https:\u002F\u002Fexemple.dev&quot; },\n  &quot;license&quot;: &quot;MIT&quot;,\n  &quot;repository&quot;: &quot;https:\u002F\u002Fgithub.com\u002Fexemple\u002Fescouade-slack&quot;,\n  &quot;escouade&quot;: { &quot;api&quot;: &quot;1&quot;, &quot;min&quot;: &quot;2.1.0&quot; },\n  &quot;run&quot;: { &quot;command&quot;: &quot;bin\u002Fescouade-slack&quot;, &quot;windows&quot;: &quot;bin\u002Fescouade-slack.exe&quot; },\n  &quot;activation&quot;: [&quot;event:ticket.column&quot;],\n  &quot;permissions&quot;: {\n    &quot;events&quot;: [&quot;ticket.*&quot;],\n    &quot;network&quot;: [&quot;hooks.slack.com&quot;],\n    &quot;secrets&quot;: [&quot;webhook&quot;]\n  },\n  &quot;contributes&quot;: {\n    &quot;settings&quot;: [{ &quot;key&quot;: &quot;channel&quot;, &quot;type&quot;: &quot;string&quot;, &quot;title&quot;: { &quot;fr&quot;: &quot;Salon&quot;, &quot;en&quot;: &quot;Channel&quot; } }],\n    &quot;secrets&quot;: [{ &quot;key&quot;: &quot;webhook&quot;, &quot;title&quot;: { &quot;fr&quot;: &quot;Adresse du webhook&quot;, &quot;en&quot;: &quot;Webhook URL&quot; } }]\n  }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>The \u003Ccode class=\"key\">$schema\u003C\u002Fcode> line gives completion and checks in VS Code and the editors that read JSON schemas. The schema is published at \u003Ccode>https:\u002F\u002Fescouade.dev\u002Fschemas\u002Fplugin-1.json\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Ch2 id=\"the-fields\">The fields\u003C\u002Fh2>\n\u003Cdiv class=\"table\">\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Field\u003C\u002Fth>\n\u003Cth>Required\u003C\u002Fth>\n\u003Cth>What it says\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\u003Ctr>\n\u003Ctd>\u003Ccode class=\"key\">id\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>yes\u003C\u002Ftd>\n\u003Ctd>The plugin’s unique id, a reversed domain name in lower case: \u003Ccode class=\"key\">dev.exemple.slack\u003C\u002Fcode>. The \u003Ccode class=\"key\">dev.escouade.*\u003C\u002Fcode> ids are kept for Escouade’s own plugins.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode class=\"key\">name\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>yes\u003C\u002Ftd>\n\u003Ctd>Its name: one text, or a text per language.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode class=\"key\">version\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>yes\u003C\u002Ftd>\n\u003Ctd>Its version, in three numbers: \u003Ccode class=\"key\">1.2.0\u003C\u002Fcode>, \u003Ccode class=\"key\">0.3.0-beta.1\u003C\u002Fcode>. The same as the version’s git tag.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode class=\"key\">description\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>no\u003C\u002Ftd>\n\u003Ctd>What it does, in a sentence: one text, or a text per language.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode class=\"key\">author\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>no\u003C\u002Ftd>\n\u003Ctd>Who made it: \u003Ccode class=\"key\">name\u003C\u002Fcode> required, \u003Ccode class=\"key\">url\u003C\u002Fcode> and \u003Ccode class=\"key\">email\u003C\u002Fcode> optional.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode class=\"key\">license\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>no\u003C\u002Ftd>\n\u003Ctd>Its license, as an SPDX identifier: \u003Ccode class=\"key\">MIT\u003C\u002Fcode>, \u003Ccode class=\"key\">Apache-2.0\u003C\u002Fcode>.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode class=\"key\">repository\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>no\u003C\u002Ftd>\n\u003Ctd>The address of its repository, in \u003Ccode class=\"key\">https:\u002F\u002F\u003C\u002Fcode>.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode class=\"key\">escouade\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>yes\u003C\u002Ftd>\n\u003Ctd>The Escouade it was written for: \u003Ccode class=\"key\">api\u003C\u002Fcode>, \u003Ccode class=\"key\">min\u003C\u002Fcode> and \u003Ccode class=\"key\">max\u003C\u002Fcode> (see below).\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode class=\"key\">run\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>no\u003C\u002Ftd>\n\u003Ctd>Its program. Without one, the plugin is declarative: nothing runs.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode class=\"key\">activation\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>no\u003C\u002Ftd>\n\u003Ctd>What starts it, for example \u003Ccode class=\"key\">event:ticket.column\u003C\u002Fcode>. Without an activation, its program does not run.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode class=\"key\">permissions\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>no\u003C\u002Ftd>\n\u003Ctd>What it asks for: \u003Ccode class=\"key\">events\u003C\u002Fcode>, \u003Ccode class=\"key\">network\u003C\u002Fcode>, \u003Ccode class=\"key\">secrets\u003C\u002Fcode>, \u003Ccode class=\"key\">commands\u003C\u002Fcode> (lists) and \u003Ccode class=\"key\">decide\u003C\u002Fcode> (\u003Ccode class=\"key\">true\u003C\u002Fcode> or \u003Ccode class=\"key\">false\u003C\u002Fcode>).\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode class=\"key\">contributes\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>no\u003C\u002Ftd>\n\u003Ctd>Its extension points: what it adds to Escouade.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode class=\"key\">store\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>no\u003C\u002Ftd>\n\u003Ctd>What the marketplace shows of it: \u003Ccode class=\"key\">categories\u003C\u002Fcode>, \u003Ccode class=\"key\">keywords\u003C\u002Fcode>, \u003Ccode class=\"key\">screenshots\u003C\u002Fcode>, \u003Ccode class=\"key\">docs\u003C\u002Fcode>.\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\u003C\u002Ftable>\u003C\u002Fdiv>\n\u003Ch3 id=\"texts-in-two-languages\">Texts in two languages\u003C\u002Fh3>\n\u003Cp>\u003Ccode class=\"key\">name\u003C\u002Fcode>, \u003Ccode class=\"key\">description\u003C\u002Fcode> and the titles of settings take one text, or an object of texts per language: \u003Ccode>{ &quot;fr&quot;: &quot;Salon&quot;, &quot;en&quot;: &quot;Channel&quot; }\u003C\u002Fcode>. Escouade shows the one in the interface’s language, else the English one, else the French one. An object needs at least \u003Ccode class=\"key\">en\u003C\u002Fcode> or \u003Ccode class=\"key\">fr\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Ch3 id=\"the-range-of-escouade\">The range of Escouade\u003C\u002Fh3>\n\u003Cul>\n\u003Cli>\u003Ccode class=\"key\">api\u003C\u002Fcode>: the major version of the plugins’ protocol the plugin speaks, in quotes: \u003Ccode class=\"key\">&quot;1&quot;\u003C\u002Fcode>. Escouade 2.1 serves version 1.\u003C\u002Fli>\n\u003Cli>\u003Ccode class=\"key\">min\u003C\u002Fcode>: the oldest version of Escouade the plugin was tried with, \u003Ccode class=\"key\">2.1.0\u003C\u002Fcode> or \u003Ccode class=\"key\">2.1\u003C\u002Fcode>.\u003C\u002Fli>\n\u003Cli>\u003Ccode class=\"key\">max\u003C\u002Fcode> (optional): the newest. \u003Ccode class=\"key\">2.4\u003C\u002Fcode> covers every 2.4.x.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>A plugin of another API, or for an Escouade out of its range, stays installed but disabled, and Escouade says why: for example “This plugin needs Escouade 2.3.0 or newer; you have 2.1.0. Update Escouade.”\u003C\u002Fp>\n\u003Ch3 id=\"the-program\">The program\u003C\u002Fh3>\n\u003Cp>\u003Ccode class=\"key\">command\u003C\u002Fcode> is the path of the program in the plugin’s folder; \u003Ccode class=\"key\">windows\u003C\u002Fcode>, \u003Ccode class=\"key\">macos\u003C\u002Fcode> and \u003Ccode class=\"key\">linux\u003C\u002Fcode> give another one for each system that has its own; \u003Ccode class=\"key\">args\u003C\u002Fcode> adds arguments. An absolute path, or one that climbs up with \u003Ccode class=\"key\">..\u003C\u002Fcode>, is refused: a plugin only starts what it brings.\u003C\u002Fp>\n\u003Ch3 id=\"the-extension-points\">The extension points\u003C\u002Fh3>\n\u003Cp>\u003Ccode class=\"key\">contributes\u003C\u002Fcode> gathers what the plugin adds. Escouade already checks their shape:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Ccode class=\"key\">settings\u003C\u002Fcode>: its settings, each with a key (\u003Ccode class=\"key\">key\u003C\u002Fcode>), a type (\u003Ccode class=\"key\">string\u003C\u002Fcode>, \u003Ccode class=\"key\">number\u003C\u002Fcode>, \u003Ccode class=\"key\">boolean\u003C\u002Fcode> or \u003Ccode class=\"key\">select\u003C\u002Fcode>) and a title (\u003Ccode class=\"key\">title\u003C\u002Fcode>);\u003C\u002Fli>\n\u003Cli>\u003Ccode class=\"key\">secrets\u003C\u002Fcode>: the secrets it keeps, each with a key and a title;\u003C\u002Fli>\n\u003Cli>\u003Ccode class=\"key\">accounts\u003C\u002Fcode>: a kind of account, shared by its other points;\u003C\u002Fli>\n\u003Cli>\u003Ccode class=\"key\">ticketSources\u003C\u002Fcode>, \u003Ccode class=\"key\">forges\u003C\u002Fcode> and \u003Ccode class=\"key\">harnesses\u003C\u002Fcode>: a source of the Kanban, a code host, a harness; each with an \u003Ccode class=\"key\">id\u003C\u002Fcode>, and the account it uses (\u003Ccode class=\"key\">account\u003C\u002Fcode>) among those of \u003Ccode class=\"key\">accounts\u003C\u002Fcode>;\u003C\u002Fli>\n\u003Cli>\u003Ccode class=\"key\">themes\u003C\u002Fcode>, \u003Ccode class=\"key\">webhooks\u003C\u002Fcode>, \u003Ccode class=\"key\">commands\u003C\u002Fcode>, \u003Ccode class=\"key\">menus\u003C\u002Fcode>, \u003Ccode class=\"key\">statusBar\u003C\u002Fcode>, \u003Ccode class=\"key\">badges\u003C\u002Fcode>, \u003Ccode class=\"key\">projectTemplates\u003C\u002Fcode> and \u003Ccode class=\"key\">escouadeYml\u003C\u002Fcode>: described with the versions that bring them in.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>One plugin can hold several points: a GitHub plugin gives its issues to the Kanban and follows its PRs on a single account.\u003C\u002Fp>\n\u003Ch2 id=\"what-escouade-checks\">What Escouade checks\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>\u003Cstrong>An invalid manifest loads nothing.\u003C\u002Fstrong> Escouade says why, field by field, with the field’s path: “\u003Ccode class=\"key\">escouade.min\u003C\u002Fcode> is missing.”, “\u003Ccode>contributes.settings[0].type\u003C\u002Fcode> is one of: string, number, boolean, select.”\u003C\u002Fli>\n\u003Cli>\u003Cstrong>An unknown field is ignored.\u003C\u002Fstrong> A manifest written for a newer Escouade loads all the same; the ignored fields are listed.\u003C\u002Fli>\n\u003Cli>The same check runs on the marketplace when an author submits a plugin: both report the same errors (\u003Ca href=\"\u002Fen\u002Fdocs\u002Fplugins\u002Fpublishing\u002F\">publishing on the store\u003C\u002Fa>).\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2 id=\"installing-a-plugin\">Installing a plugin\u003C\u002Fh2>\n\u003Cp>Escouade installs a plugin in three ways:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>From a folder\u003C\u002Fstrong>: the folder is copied to \u003Ccode>~\u002F.escouade\u002Fplugins\u002F&lt;id&gt;\u002F\u003C\u002Fcode>, without its git history, and pinned by the SHA-256 fingerprint of its files.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>From a git repository and a tag\u003C\u002Fstrong> (\u003Ccode class=\"key\">v1.2.0\u003C\u002Fcode>): Escouade clones that tag alone, copies it to the same place, and pins it by its commit. A plugin is always pinned to a version; installing another tag replaces the previous one.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>A folder in development\u003C\u002Fstrong>: loaded where it is, without a copy, and read again as soon as one of its files changes. This is the mode for plugin authors.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>The list of installed plugins, their origin and their fingerprint are in \u003Ccode>~\u002F.escouade\u002Fplugins.json\u003C\u002Fcode>. A copy whose files changed since it was installed is disabled, with the reason.\u003C\u002Fp>\n\u003Cp>The Settings › Plugins tab, which installs, enables and uninstalls plugins from the interface, comes with the rest of 2.1. No plugin runs a program yet: this version reads and checks the manifests.\u003C\u002Fp>\n",[8,12,15,19,22,25,28,31],{"id":9,"text":10,"depth":11},"a-complete-example","A complete example",2,{"id":13,"text":14,"depth":11},"the-fields","The fields",{"id":16,"text":17,"depth":18},"texts-in-two-languages","Texts in two languages",3,{"id":20,"text":21,"depth":18},"the-range-of-escouade","The range of Escouade",{"id":23,"text":24,"depth":18},"the-program","The program",{"id":26,"text":27,"depth":18},"the-extension-points","The extension points",{"id":29,"text":30,"depth":11},"what-escouade-checks","What Escouade checks",{"id":32,"text":33,"depth":11},"installing-a-plugin","Installing a plugin",1793278987090]