openbot 0.5.6 → 0.5.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/app/cli.js CHANGED
@@ -18,7 +18,7 @@ function checkNodeVersion() {
18
18
  }
19
19
  }
20
20
  checkNodeVersion();
21
- program.name('openbot').description('OpenBot CLI').version('0.5.6');
21
+ program.name('openbot').description('OpenBot CLI').version('0.5.7');
22
22
  program
23
23
  .command('start')
24
24
  .description('Start the OpenBot harness')
@@ -2,8 +2,14 @@
2
2
  export const resolvedPluginCache = new Map();
3
3
  /** Community plugin ids that have already been logged as loaded once. */
4
4
  export const loadedCommunityPlugins = new Set();
5
+ /** Bumped on invalidate so dynamic imports use a fresh Node ESM cache key. */
6
+ const pluginImportRevisions = new Map();
7
+ export function getPluginImportRevision(id) {
8
+ return pluginImportRevisions.get(id) ?? 0;
9
+ }
5
10
  /** Drop a single id from the in-memory resolver cache (e.g. after install/uninstall). */
6
11
  export function invalidatePlugin(id) {
7
12
  resolvedPluginCache.delete(id);
8
13
  loadedCommunityPlugins.delete(id);
14
+ pluginImportRevisions.set(id, (pluginImportRevisions.get(id) ?? 0) + 1);
9
15
  }
@@ -4,7 +4,7 @@ import { pathToFileURL } from 'node:url';
4
4
  import { storagePlugin } from '../../plugins/storage/index.js';
5
5
  import { pluginManagerPlugin } from '../../plugins/plugin-manager/index.js';
6
6
  import { DEFAULT_PLUGINS_DIR, getBaseDir } from '../../app/config.js';
7
- import { invalidatePlugin as clearResolvedPluginEntry, loadedCommunityPlugins, resolvedPluginCache, } from './plugin-cache.js';
7
+ import { getPluginImportRevision, invalidatePlugin as clearResolvedPluginEntry, loadedCommunityPlugins, resolvedPluginCache, } from './plugin-cache.js';
8
8
  let pluginsDir = null;
9
9
  const BUILT_IN = {
10
10
  [storagePlugin.id]: storagePlugin,
@@ -59,7 +59,8 @@ export async function resolvePlugin(id) {
59
59
  const distPath = path.join(pluginsDir, id, 'dist', 'index.js');
60
60
  if (existsSync(distPath)) {
61
61
  try {
62
- const module = await import(pathToFileURL(distPath).href);
62
+ const importUrl = `${pathToFileURL(distPath).href}?v=${getPluginImportRevision(id)}`;
63
+ const module = await import(importUrl);
63
64
  const parsed = parsePluginModule(module);
64
65
  if (!parsed) {
65
66
  console.warn(`[plugins] Plugin "${id}" at ${distPath} has no recognizable export.`);
@@ -89,6 +90,11 @@ export async function resolvePlugin(id) {
89
90
  export function invalidatePlugin(id) {
90
91
  clearResolvedPluginEntry(id);
91
92
  }
93
+ /** Invalidate and load a community plugin from disk (e.g. after install/upgrade). */
94
+ export async function reloadPlugin(id) {
95
+ clearResolvedPluginEntry(id);
96
+ return resolvePlugin(id);
97
+ }
92
98
  /** List built-in plugins (for marketplace/registry views). */
93
99
  export function listBuiltInPlugins() {
94
100
  return Object.values(BUILT_IN);
@@ -4,6 +4,7 @@ import path from 'node:path';
4
4
  import { exec } from 'node:child_process';
5
5
  import { promisify } from 'node:util';
6
6
  import { DEFAULT_PLUGINS_DIR, DEFAULT_MARKETPLACE_REGISTRY_URL, getBaseDir, loadConfig, } from '../../app/config.js';
7
+ import { reloadPlugin } from './registry.js';
7
8
  import { invalidatePlugin } from './plugin-cache.js';
8
9
  const execAsync = promisify(exec);
9
10
  function isLatestVersionAlias(version) {
@@ -190,7 +191,7 @@ export const pluginService = {
190
191
  console.warn(`[plugins] Failed to run npm install in ${finalPath}:`, e);
191
192
  }
192
193
  const pkgJson = JSON.parse(await fs.readFile(path.join(finalPath, 'package.json'), 'utf-8'));
193
- invalidatePlugin(packageName);
194
+ await reloadPlugin(packageName);
194
195
  return { name: pkgJson.name, version: pkgJson.version };
195
196
  }
196
197
  catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openbot",
3
- "version": "0.5.6",
3
+ "version": "0.5.7",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "engines": {
@@ -11,7 +11,7 @@
11
11
  "build": "tsc && mkdir -p dist/assets && cp src/assets/icon.svg dist/assets/icon.svg",
12
12
  "start": "node dist/app/cli.js start",
13
13
  "format": "prettier --write .",
14
- "push": "fly deploy --build-only --push --config deploy/fly.toml -a openbot-runtime --image-label v0.5.6"
14
+ "push": "fly deploy --build-only --push --config deploy/fly.toml -a openbot-runtime --image-label v0.5.7"
15
15
  },
16
16
  "bin": {
17
17
  "openbot": "./dist/app/cli.js"
package/src/app/cli.ts CHANGED
@@ -27,7 +27,7 @@ function checkNodeVersion() {
27
27
 
28
28
  checkNodeVersion();
29
29
 
30
- program.name('openbot').description('OpenBot CLI').version('0.5.6');
30
+ program.name('openbot').description('OpenBot CLI').version('0.5.7');
31
31
 
32
32
  program
33
33
  .command('start')
@@ -6,8 +6,16 @@ export const resolvedPluginCache = new Map<string, Plugin>();
6
6
  /** Community plugin ids that have already been logged as loaded once. */
7
7
  export const loadedCommunityPlugins = new Set<string>();
8
8
 
9
+ /** Bumped on invalidate so dynamic imports use a fresh Node ESM cache key. */
10
+ const pluginImportRevisions = new Map<string, number>();
11
+
12
+ export function getPluginImportRevision(id: string): number {
13
+ return pluginImportRevisions.get(id) ?? 0;
14
+ }
15
+
9
16
  /** Drop a single id from the in-memory resolver cache (e.g. after install/uninstall). */
10
17
  export function invalidatePlugin(id: string): void {
11
18
  resolvedPluginCache.delete(id);
12
19
  loadedCommunityPlugins.delete(id);
20
+ pluginImportRevisions.set(id, (pluginImportRevisions.get(id) ?? 0) + 1);
13
21
  }
@@ -7,6 +7,7 @@ import { storagePlugin } from '../../plugins/storage/index.js';
7
7
  import { pluginManagerPlugin } from '../../plugins/plugin-manager/index.js';
8
8
  import { DEFAULT_PLUGINS_DIR, getBaseDir } from '../../app/config.js';
9
9
  import {
10
+ getPluginImportRevision,
10
11
  invalidatePlugin as clearResolvedPluginEntry,
11
12
  loadedCommunityPlugins,
12
13
  resolvedPluginCache,
@@ -27,9 +28,7 @@ const BUILT_IN: Record<string, Plugin> = {
27
28
  export type ParsedPluginModule = Omit<Plugin, 'id'>;
28
29
 
29
30
  /** Normalize a dynamically imported plugin module. Supports `plugin`, `default`. */
30
- export function parsePluginModule(
31
- module: Record<string, unknown>,
32
- ): ParsedPluginModule | null {
31
+ export function parsePluginModule(module: Record<string, unknown>): ParsedPluginModule | null {
33
32
  const raw =
34
33
  (module.plugin as Record<string, unknown> | undefined) ??
35
34
  (module.default as Record<string, unknown> | undefined);
@@ -82,7 +81,8 @@ export async function resolvePlugin(id: string): Promise<Plugin | null> {
82
81
 
83
82
  if (existsSync(distPath)) {
84
83
  try {
85
- const module = await import(pathToFileURL(distPath).href);
84
+ const importUrl = `${pathToFileURL(distPath).href}?v=${getPluginImportRevision(id)}`;
85
+ const module = await import(importUrl);
86
86
  const parsed = parsePluginModule(module as Record<string, unknown>);
87
87
  if (!parsed) {
88
88
  console.warn(`[plugins] Plugin "${id}" at ${distPath} has no recognizable export.`);
@@ -114,6 +114,12 @@ export function invalidatePlugin(id: string): void {
114
114
  clearResolvedPluginEntry(id);
115
115
  }
116
116
 
117
+ /** Invalidate and load a community plugin from disk (e.g. after install/upgrade). */
118
+ export async function reloadPlugin(id: string): Promise<Plugin | null> {
119
+ clearResolvedPluginEntry(id);
120
+ return resolvePlugin(id);
121
+ }
122
+
117
123
  /** List built-in plugins (for marketplace/registry views). */
118
124
  export function listBuiltInPlugins(): Plugin[] {
119
125
  return Object.values(BUILT_IN);
@@ -10,6 +10,7 @@ import {
10
10
  loadConfig,
11
11
  resolvePath,
12
12
  } from '../../app/config.js';
13
+ import { reloadPlugin } from './registry.js';
13
14
  import { invalidatePlugin } from './plugin-cache.js';
14
15
  import { PluginRef } from './types.js';
15
16
 
@@ -273,7 +274,7 @@ export const pluginService = {
273
274
 
274
275
  const pkgJson = JSON.parse(await fs.readFile(path.join(finalPath, 'package.json'), 'utf-8'));
275
276
 
276
- invalidatePlugin(packageName);
277
+ await reloadPlugin(packageName);
277
278
  return { name: pkgJson.name, version: pkgJson.version };
278
279
  } catch (error) {
279
280
  console.error(`[plugins] Failed to install ${packageName}:`, error);