name a published extension for itself, not "extension.zip"
extension.zip says nothing once it is in a Downloads folder — not what it is, not which server it came from, and not which of two it is. The name comes from the extension's own manifest.json, which already carries what a browser will show: "Officer Browser Relay" becomes officer-browser-relay.zip. Generic, since extensions are meant to be a marketplace of them: any plugin shipping extension/ gets a file named after its own manifest, falling back to <appName>-extension.zip when that cannot be read — still better than extension.zip, and it never throws, because a broken extension manifest should fail the install for its own reason rather than because a file could not be named. Uninstall removes both names. An install from earlier today published extension.zip, and leaving that behind would serve a stale extension for a plugin that is gone. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { join } from 'node:path';
|
||||
import {
|
||||
deleteScreenForAllUsers,
|
||||
getDockPaths,
|
||||
@@ -20,7 +21,7 @@ import { publishAffordances, unpublishAffordances } from '../affordances/publish
|
||||
import { publishNotifications, unpublishNotifications } from '../notifications/publish';
|
||||
import { publishSkills, unpublishSkills } from '../skills/publish';
|
||||
import { refreshPluginMounts, snapshotPlugins } from './mount';
|
||||
import { publishExtension, unpublishExtension } from './zip';
|
||||
import { publishExtension, unpublishExtension, extensionFileName } from './zip';
|
||||
import { generatePluginSchemas, pushPluginSchema } from './schema';
|
||||
import { declaredTables, dropTables, existingTables } from './tables';
|
||||
import type { OnLog } from './run-logged';
|
||||
@@ -397,7 +398,8 @@ export async function installPlugin(
|
||||
// A browser extension, zipped from `extension/` and served UNAUTHENTICATED — see zip.ts. Built here
|
||||
// rather than committed, so it cannot fall behind the directory it is made from.
|
||||
if (await publishExtension(appName, plugin.dir).catch(() => false)) {
|
||||
await step(steps, onStep, `extension: published to /plugins/${appName}/extension.zip`);
|
||||
const file = extensionFileName(appName, join(plugin.dir, 'extension'));
|
||||
await step(steps, onStep, `extension: published to /plugins/${appName}/${file}`);
|
||||
}
|
||||
|
||||
// What this plugin needs an AGENT to know about itself. A plugin is a new surface arriving at
|
||||
@@ -529,7 +531,7 @@ export async function uninstallPlugin(appName: string, onStep?: OnStep, onLog?:
|
||||
}
|
||||
|
||||
await unpublishAssets(appName);
|
||||
await unpublishExtension(appName).catch(() => {});
|
||||
await unpublishExtension(appName, plugin?.dir).catch(() => {});
|
||||
// Same reasoning: a copy, with the original still in the plugin's directory. Removed so an agent stops
|
||||
// being told about a surface that is no longer there — an affordance for an uninstalled plugin is
|
||||
// worse than none, because it reads as true.
|
||||
|
||||
Reference in New Issue
Block a user