@ztffn/presentation-generator-plugin 1.0.9 → 1.1.1

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.
Files changed (2) hide show
  1. package/bin/index.js +40 -21
  2. package/package.json +1 -1
package/bin/index.js CHANGED
@@ -9,6 +9,7 @@ const readline = require("readline");
9
9
 
10
10
  const NPM_PACKAGE = "@ztffn/presentation-generator-plugin";
11
11
  const PLUGIN_NAME = "presentation-generator";
12
+ const MARKETPLACE_NAME = "local-plugins";
12
13
  const GLOBAL_INSTALL_DIR = path.join(os.homedir(), ".claude", "plugins", PLUGIN_NAME);
13
14
  const PROJECT_INSTALL_DIR = path.join(process.cwd(), ".claude", "plugins", PLUGIN_NAME);
14
15
  const CURRENT_VERSION = require("../package.json").version;
@@ -160,24 +161,40 @@ async function resolveInstallTarget() {
160
161
  };
161
162
  }
162
163
 
163
- function writeSettings(settingsPath, installDir) {
164
- let settings = {};
165
- if (fs.existsSync(settingsPath)) {
166
- try {
167
- settings = JSON.parse(fs.readFileSync(settingsPath, "utf8"));
168
- } catch {
169
- settings = {};
170
- }
164
+ function ensureMarketplaceJson(pluginsDir) {
165
+ const metaDir = path.join(pluginsDir, ".claude-plugin");
166
+ const marketplacePath = path.join(metaDir, "marketplace.json");
167
+
168
+ let existing = { name: MARKETPLACE_NAME, owner: { name: "Local" }, plugins: [] };
169
+ if (fs.existsSync(marketplacePath)) {
170
+ try { existing = JSON.parse(fs.readFileSync(marketplacePath, "utf8")); } catch {}
171
171
  }
172
172
 
173
- if (!settings.enabledPlugins || typeof settings.enabledPlugins !== "object" || Array.isArray(settings.enabledPlugins)) {
174
- settings.enabledPlugins = {};
173
+ const alreadyListed = (existing.plugins || []).some((p) => p.name === PLUGIN_NAME);
174
+ if (!alreadyListed) {
175
+ existing.plugins = existing.plugins || [];
176
+ existing.plugins.push({
177
+ name: PLUGIN_NAME,
178
+ source: `./${PLUGIN_NAME}`,
179
+ description: "Generate complete graph-based presentations from natural language briefs",
180
+ });
181
+ fs.mkdirSync(metaDir, { recursive: true });
182
+ fs.writeFileSync(marketplacePath, JSON.stringify(existing, null, 2) + "\n");
175
183
  }
184
+ }
176
185
 
177
- settings.enabledPlugins[PLUGIN_NAME] = installDir;
186
+ function registerWithClaude(installDir, scope) {
187
+ const pluginsDir = path.dirname(installDir);
188
+ ensureMarketplaceJson(pluginsDir);
178
189
 
179
- fs.mkdirSync(path.dirname(settingsPath), { recursive: true });
180
- fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
190
+ try {
191
+ execSync(`claude plugin marketplace add "${pluginsDir}"`, { stdio: "pipe" });
192
+ } catch {
193
+ // marketplace may already be registered — continue
194
+ }
195
+
196
+ const scopeFlag = scope === "project" ? "--scope project" : "--scope user";
197
+ execSync(`claude plugin install ${PLUGIN_NAME}@${MARKETPLACE_NAME} ${scopeFlag}`, { stdio: "pipe" });
181
198
  }
182
199
 
183
200
  function removeFromSettings(settingsPath) {
@@ -185,8 +202,9 @@ function removeFromSettings(settingsPath) {
185
202
  try {
186
203
  const settings = JSON.parse(fs.readFileSync(settingsPath, "utf8"));
187
204
  if (!settings.enabledPlugins || typeof settings.enabledPlugins !== "object") return;
188
- if (PLUGIN_NAME in settings.enabledPlugins) {
189
- delete settings.enabledPlugins[PLUGIN_NAME];
205
+ const key = `${PLUGIN_NAME}@${MARKETPLACE_NAME}`;
206
+ if (key in settings.enabledPlugins) {
207
+ delete settings.enabledPlugins[key];
190
208
  fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
191
209
  console.log(`Removed entry from ${settingsPath}`);
192
210
  }
@@ -228,7 +246,7 @@ async function install() {
228
246
  process.exit(1);
229
247
  }
230
248
 
231
- const { installDir, settingsPath, scope } = await resolveInstallTarget();
249
+ const { installDir, scope } = await resolveInstallTarget();
232
250
 
233
251
  console.log(`\nInstalling presentation-generator plugin...`);
234
252
  await downloadAndExtract(meta.version, meta.tarball, installDir);
@@ -237,7 +255,7 @@ async function install() {
237
255
  console.log(`\nInstalled v${meta.version} to: ${label}`);
238
256
 
239
257
  console.log("\nRegistering plugin with Claude Code...");
240
- writeSettings(settingsPath, installDir);
258
+ registerWithClaude(installDir, scope);
241
259
 
242
260
  const settingsLabel = scope === "project" ? ".claude/settings.json" : "~/.claude/settings.json";
243
261
  console.log(`Plugin registered in ${settingsLabel} ✓`);
@@ -259,9 +277,9 @@ async function update() {
259
277
  process.exit(1);
260
278
  }
261
279
 
262
- for (const [installDir, settingsPath, label] of [
263
- [GLOBAL_INSTALL_DIR, path.join(os.homedir(), ".claude", "settings.json"), "Global"],
264
- [PROJECT_INSTALL_DIR, path.join(process.cwd(), ".claude", "settings.json"), "Project"],
280
+ for (const [installDir, label] of [
281
+ [GLOBAL_INSTALL_DIR, "Global"],
282
+ [PROJECT_INSTALL_DIR, "Project"],
265
283
  ]) {
266
284
  if (!fs.existsSync(installDir)) continue;
267
285
 
@@ -273,7 +291,8 @@ async function update() {
273
291
 
274
292
  console.log(`\n${label}: updating v${before || "unknown"} → v${meta.version}...`);
275
293
  await downloadAndExtract(meta.version, meta.tarball, installDir);
276
- writeSettings(settingsPath, installDir);
294
+ const updateScope = installDir === GLOBAL_INSTALL_DIR ? "user" : "project";
295
+ registerWithClaude(installDir, updateScope);
277
296
  console.log(`${label}: updated to v${meta.version} ✓`);
278
297
  }
279
298
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ztffn/presentation-generator-plugin",
3
- "version": "1.0.9",
3
+ "version": "1.1.1",
4
4
  "description": "Claude Code plugin for generating graph-based presentations",
5
5
  "bin": {
6
6
  "presentation-generator-plugin": "bin/index.js"