@ztffn/presentation-generator-plugin 1.1.0 → 1.1.2

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.
@@ -45,11 +45,16 @@ Write the JSON to `_temp/presentation-draft.json`:
45
45
 
46
46
  ```json
47
47
  {
48
+ "meta": {
49
+ "name": "<deck title from _temp/presentation-outline.md>"
50
+ },
48
51
  "nodes": [ ... ],
49
52
  "edges": [ ... ]
50
53
  }
51
54
  ```
52
55
 
56
+ The `meta.name` value must be the presentation title exactly as it appears in the outline — verbatim, no reformatting.
57
+
53
58
  After writing, output a summary listing:
54
59
  - Total node count
55
60
  - Total edge count
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,36 +161,50 @@ async function resolveInstallTarget() {
160
161
  };
161
162
  }
162
163
 
163
- function writeSettings(settingsPath) {
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 (!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
+ }
185
+
186
+ function registerWithClaude(installDir, scope) {
187
+ const pluginsDir = path.dirname(installDir);
188
+ ensureMarketplaceJson(pluginsDir);
176
189
 
177
- if (!settings.enabledPlugins.includes(PLUGIN_NAME)) {
178
- settings.enabledPlugins.push(PLUGIN_NAME);
190
+ try {
191
+ execSync(`claude plugin marketplace add "${pluginsDir}"`, { stdio: "pipe" });
192
+ } catch {
193
+ // marketplace may already be registered — continue
179
194
  }
180
195
 
181
- fs.mkdirSync(path.dirname(settingsPath), { recursive: true });
182
- fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
196
+ const scopeFlag = scope === "project" ? "--scope project" : "--scope user";
197
+ execSync(`claude plugin install ${PLUGIN_NAME}@${MARKETPLACE_NAME} ${scopeFlag}`, { stdio: "pipe" });
183
198
  }
184
199
 
185
200
  function removeFromSettings(settingsPath) {
186
201
  if (!fs.existsSync(settingsPath)) return;
187
202
  try {
188
203
  const settings = JSON.parse(fs.readFileSync(settingsPath, "utf8"));
189
- if (!Array.isArray(settings.enabledPlugins)) return;
190
- const filtered = settings.enabledPlugins.filter((p) => p !== PLUGIN_NAME);
191
- if (filtered.length !== settings.enabledPlugins.length) {
192
- settings.enabledPlugins = filtered;
204
+ if (!settings.enabledPlugins || typeof settings.enabledPlugins !== "object") return;
205
+ const key = `${PLUGIN_NAME}@${MARKETPLACE_NAME}`;
206
+ if (key in settings.enabledPlugins) {
207
+ delete settings.enabledPlugins[key];
193
208
  fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
194
209
  console.log(`Removed entry from ${settingsPath}`);
195
210
  }
@@ -231,7 +246,7 @@ async function install() {
231
246
  process.exit(1);
232
247
  }
233
248
 
234
- const { installDir, settingsPath, scope } = await resolveInstallTarget();
249
+ const { installDir, scope } = await resolveInstallTarget();
235
250
 
236
251
  console.log(`\nInstalling presentation-generator plugin...`);
237
252
  await downloadAndExtract(meta.version, meta.tarball, installDir);
@@ -240,7 +255,7 @@ async function install() {
240
255
  console.log(`\nInstalled v${meta.version} to: ${label}`);
241
256
 
242
257
  console.log("\nRegistering plugin with Claude Code...");
243
- writeSettings(settingsPath);
258
+ registerWithClaude(installDir, scope);
244
259
 
245
260
  const settingsLabel = scope === "project" ? ".claude/settings.json" : "~/.claude/settings.json";
246
261
  console.log(`Plugin registered in ${settingsLabel} ✓`);
@@ -262,9 +277,9 @@ async function update() {
262
277
  process.exit(1);
263
278
  }
264
279
 
265
- for (const [installDir, settingsPath, label] of [
266
- [GLOBAL_INSTALL_DIR, path.join(os.homedir(), ".claude", "settings.json"), "Global"],
267
- [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"],
268
283
  ]) {
269
284
  if (!fs.existsSync(installDir)) continue;
270
285
 
@@ -276,7 +291,8 @@ async function update() {
276
291
 
277
292
  console.log(`\n${label}: updating v${before || "unknown"} → v${meta.version}...`);
278
293
  await downloadAndExtract(meta.version, meta.tarball, installDir);
279
- writeSettings(settingsPath);
294
+ const updateScope = installDir === GLOBAL_INSTALL_DIR ? "user" : "project";
295
+ registerWithClaude(installDir, updateScope);
280
296
  console.log(`${label}: updated to v${meta.version} ✓`);
281
297
  }
282
298
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ztffn/presentation-generator-plugin",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "description": "Claude Code plugin for generating graph-based presentations",
5
5
  "bin": {
6
6
  "presentation-generator-plugin": "bin/index.js"