* refactor: move Electron app to main directory and enforce ts strict mode * chore: add pre-install plugins * remove duplicated initModel function Signed-off-by: James <james@jan.ai> * chore: correct module path * fix: dynamic import does not work with ts * chore: web should be able to run on target host browser * fix: history panel, should display conversations rather just blank state * chore: init default model * chore: pluggin in ts * fix: pre-pack model management * fix: compiled core should not include plugins * chore: refactor - invoke plugin function * refactor download/delete file Signed-off-by: James <james@jan.ai> * update prebuild lib Signed-off-by: James <james@jan.ai> * chore: yarn workspace * chore: update yarn workspace * chore: yarn workspace with nohoist * fix: llama-cpp-import * chore: fix data-plugin wrong module path * chore: correct build step * chore: - separate inference service (#212) - remove base-plugin Signed-off-by: James <james@jan.ai> Co-authored-by: James <james@jan.ai> * chore: update core plugins * chore: hide installation prompt and fix model load - management plugin * chore: remove legacy files; update readme * fix: refresh page lost the download state Signed-off-by: James <james@jan.ai> * fix: ai prompt not passed to plugin Signed-off-by: James <james@jan.ai> * chore: module import fix for production * chore: auto updater * chore: package is public * chore: fix yarn workspace config * update: model management uses Q4_K_M * chore: fix yarn scripts for publishing * chore: app updater - progress update message * chore: user confirms update action * adding some state for changing page store downloaded model to database Signed-off-by: James <james@jan.ai> * chore: refactor plugins into yarn workspace - a single command to publish all base plugins * chore update readme (#218) Co-authored-by: Hien To <tominhhien97@gmail.com> * change app name and app icon Signed-off-by: James <james@jan.ai> * remove: go-to-nowhere actions * chore: bundle core plugins from root and scan default plugins * fix: app crashes on different field name lookup * chore: css fix * chore: bind download progress to app ui * chore: bind active model * chore: simplify app splash-screen only centered jan icon * feature: system monitoring plugin (#196) * feat: Add function for system monitoring * chore: register plugin functions * chore: move to corresponding directory * chore: bind system monitoring data to UI --------- Co-authored-by: Louis <louis@jan.ai> * chore: add build:plugins step to README * chore: model searching and fix model name * fix: plugin file selected appearance * fix: create new conversation does not work * fix: delete conversation not update state - messages still exist * chore: fix asset path prefix * Add CICD for macos (#221) Co-authored-by: Hien To <tominhhien97@gmail.com> * chore: fix production plugin path * chore: add shell open url in external browser --------- Signed-off-by: James <james@jan.ai> Co-authored-by: James <james@jan.ai> Co-authored-by: NamH <NamNh0122@gmail.com> Co-authored-by: 0xSage <n@pragmatic.vc> Co-authored-by: hiento09 <136591877+hiento09@users.noreply.github.com> Co-authored-by: Hien To <tominhhien97@gmail.com> Co-authored-by: namvuong <22463238+vuonghoainam@users.noreply.github.com>
124 lines
4.0 KiB
JavaScript
124 lines
4.0 KiB
JavaScript
import { readFileSync } from "fs"
|
|
import { protocol } from 'electron'
|
|
import { normalize } from "path"
|
|
|
|
import Plugin from "./Plugin"
|
|
import { getAllPlugins, removePlugin, persistPlugins, installPlugins, getPlugin, getActivePlugins, addPlugin } from "./store"
|
|
import { pluginsPath as storedPluginsPath, setPluginsPath, getPluginsFile, setConfirmInstall } from './globals'
|
|
import router from "./router"
|
|
|
|
/**
|
|
* Sets up the required communication between the main and renderer processes.
|
|
* Additionally sets the plugins up using {@link usePlugins} if a pluginsPath is provided.
|
|
* @param {Object} options configuration for setting up the renderer facade.
|
|
* @param {confirmInstall} [options.confirmInstall] Function to validate that a plugin should be installed.
|
|
* @param {Boolean} [options.useFacade=true] Whether to make a facade to the plugins available in the renderer.
|
|
* @param {string} [options.pluginsPath] Optional path to the plugins folder.
|
|
* @returns {pluginManager|Object} A set of functions used to manage the plugin lifecycle if usePlugins is provided.
|
|
* @function
|
|
*/
|
|
export function init(options) {
|
|
if (!Object.prototype.hasOwnProperty.call(options, 'useFacade') || options.useFacade) {
|
|
// Store the confirmInstall function
|
|
setConfirmInstall(options.confirmInstall)
|
|
// Enable IPC to be used by the facade
|
|
router()
|
|
}
|
|
|
|
// Create plugins protocol to serve plugins to renderer
|
|
registerPluginProtocol()
|
|
|
|
// perform full setup if pluginsPath is provided
|
|
if (options.pluginsPath) {
|
|
return usePlugins(options.pluginsPath)
|
|
}
|
|
|
|
return {}
|
|
|
|
}
|
|
|
|
/**
|
|
* Create plugins protocol to provide plugins to renderer
|
|
* @private
|
|
* @returns {boolean} Whether the protocol registration was successful
|
|
*/
|
|
function registerPluginProtocol() {
|
|
return protocol.registerFileProtocol('plugin', (request, callback) => {
|
|
const entry = request.url.substr(8)
|
|
const url = normalize(storedPluginsPath + entry)
|
|
callback({ path: url })
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Set Pluggable Electron up to run from the pluginPath folder if it is provided and
|
|
* load plugins persisted in that folder.
|
|
* @param {string} pluginsPath Path to the plugins folder. Required if not yet set up.
|
|
* @returns {pluginManager} A set of functions used to manage the plugin lifecycle.
|
|
*/
|
|
export function usePlugins(pluginsPath) {
|
|
if (!pluginsPath) throw Error('A path to the plugins folder is required to use Pluggable Electron')
|
|
// Store the path to the plugins folder
|
|
setPluginsPath(pluginsPath)
|
|
|
|
// Remove any registered plugins
|
|
for (const plugin of getAllPlugins()) {
|
|
removePlugin(plugin.name, false)
|
|
}
|
|
|
|
// Read plugin list from plugins folder
|
|
const plugins = JSON.parse(readFileSync(getPluginsFile()))
|
|
try {
|
|
// Create and store a Plugin instance for each plugin in list
|
|
for (const p in plugins) {
|
|
loadPlugin(plugins[p])
|
|
}
|
|
persistPlugins()
|
|
|
|
} catch (error) {
|
|
// Throw meaningful error if plugin loading fails
|
|
throw new Error('Could not successfully rebuild list of installed plugins.\n'
|
|
+ error
|
|
+ '\nPlease check the plugins.json file in the plugins folder.')
|
|
}
|
|
|
|
// Return the plugin lifecycle functions
|
|
return getStore()
|
|
}
|
|
|
|
/**
|
|
* Check the given plugin object. If it is marked for uninstalling, the plugin files are removed.
|
|
* Otherwise a Plugin instance for the provided object is created and added to the store.
|
|
* @private
|
|
* @param {Object} plg Plugin info
|
|
*/
|
|
function loadPlugin(plg) {
|
|
// Create new plugin, populate it with plg details and save it to the store
|
|
const plugin = new Plugin()
|
|
|
|
for (const key in plg) {
|
|
plugin[key] = plg[key]
|
|
}
|
|
|
|
addPlugin(plugin, false)
|
|
plugin.subscribe('pe-persist', persistPlugins)
|
|
}
|
|
|
|
/**
|
|
* Returns the publicly available store functions.
|
|
* @returns {pluginManager} A set of functions used to manage the plugin lifecycle.
|
|
*/
|
|
export function getStore() {
|
|
if (!storedPluginsPath) {
|
|
throw new Error('The plugin path has not yet been set up. Please run usePlugins before accessing the store')
|
|
}
|
|
|
|
return {
|
|
installPlugins,
|
|
getPlugin,
|
|
getAllPlugins,
|
|
getActivePlugins,
|
|
removePlugin,
|
|
}
|
|
}
|