kennel 0.2.17 → 0.2.18

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.
@@ -16,6 +16,7 @@ export type ExternalPluginEntry = {
16
16
  };
17
17
  };
18
18
  export declare function kennelConfigPath(): string;
19
+ export declare const PLUGIN_SOURCE_IGNORED: Set<string>;
19
20
  export declare function validateExternalPlugin(inputUrl: string, options?: {
20
21
  directory?: string;
21
22
  }): Promise<ExternalPluginEntry>;
@@ -189,11 +189,13 @@ function entryByConvention(root, file, required) {
189
189
  return undefined;
190
190
  throw new Error(`Missing required plugin entry ${file} (expected ${file} or src/${file})`);
191
191
  }
192
+ // Generated files do not change the plugin source or trigger development rebuilds.
193
+ export const PLUGIN_SOURCE_IGNORED = new Set([".git", "node_modules", ".cache", ".turbo", "dist", "coverage"]);
192
194
  function contentHash(root) {
193
195
  const digest = createHash("sha256");
194
196
  const visit = (dir) => {
195
197
  for (const name of readdirSync(dir).sort()) {
196
- if (name === ".git" || name === "node_modules")
198
+ if (PLUGIN_SOURCE_IGNORED.has(name))
197
199
  continue;
198
200
  const path = join(dir, name);
199
201
  const rel = relative(root, path);
@@ -451,9 +453,14 @@ export function pluginSetKey(plugins = readExternalPlugins()) {
451
453
  return hash(JSON.stringify({
452
454
  buildIdentity: BUILD_IDENTITY,
453
455
  cli: cliVersion(),
454
- plugins: plugins.map((plugin) => ({ url: plugin.url, directory: plugin.directory ?? null, path: plugin.path ?? null, commit: plugin.commit, trigger: plugin.trigger, entries: plugin.entries })),
456
+ theme: existsSync(pluginThemePath()) ? hash(readFileSync(pluginThemePath(), "utf8")) : null,
457
+ plugins: plugins.map((plugin) => ({ url: plugin.url, directory: plugin.directory ?? null, path: plugin.path ?? null, commit: plugin.path ? contentHash(pluginRoot(plugin.path, plugin.directory)) : plugin.commit, trigger: plugin.trigger, entries: plugin.entries })),
455
458
  }));
456
459
  }
460
+ function pluginThemePath() {
461
+ const source = resolve(cliRoot(), "../../apps/web/src/theme.css");
462
+ return existsSync(source) ? source : join(webRoot(), "kennel-theme.css");
463
+ }
457
464
  /** Points the core runtime at a plugin build. */
458
465
  export function usePluginBuild(build) {
459
466
  process.env.KENNEL_KERNEL_KEY = build.key;
@@ -657,7 +664,7 @@ export async function ensurePluginBuild(plugins = readExternalPlugins(), options
657
664
  const key = pluginSetKey(plugins);
658
665
  if (plugins.length === 0)
659
666
  return { key, serverEntries: [], apiEntries: [] };
660
- const theme = options.theme ?? join(webRoot(), "kennel-theme.css");
667
+ const theme = options.theme ?? pluginThemePath();
661
668
  if (!existsSync(theme))
662
669
  throw new Error(`Kennel host theme is missing: ${theme}. Build the CLI first.`);
663
670
  const target = buildRoot(key);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kennel",
3
- "version": "0.2.17",
3
+ "version": "0.2.18",
4
4
  "description": "Open-source pop-up previews for AI output: markdown, HTML artifacts, email, images, code, tables, notes, and calendars, from the terminal or your agent session.",
5
5
  "type": "module",
6
6
  "license": "MIT",