zmarketplace 0.4.5 → 0.4.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.ts +29 -42
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zmarketplace",
3
- "version": "0.4.5",
3
+ "version": "0.4.7",
4
4
  "description": "Cross-agent marketplace search: find, audit, and install plugins/skills/themes/prompts across pi, omp, claude code, opencode, gemini cli, and codex",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/index.ts CHANGED
@@ -58,23 +58,16 @@ async function browseResults(results: PackageResult[], ctx: Ctx): Promise<void>
58
58
  const pageEnd = Math.min(pageStart + PAGE_SIZE, results.length);
59
59
  const page = results.slice(pageStart, pageEnd);
60
60
 
61
- const options = page.map((r, i) => {
62
- const globalIdx = pageStart + i;
63
- return { label: formatResultOption(r, globalIdx).label, description: r.installCommand ?? "" };
64
- });
61
+ const options: string[] = page.map((r, i) => formatResultOption(r, pageStart + i).label);
65
62
 
66
- // Pagination controls
67
63
  if (pageStart > 0) {
68
- const prevStart = Math.max(0, pageStart - PAGE_SIZE) + 1;
69
- const prevEnd = pageStart;
70
- options.push({ label: `← Previous (${prevStart}-${prevEnd})`, description: "" });
64
+ const ps = Math.max(0, pageStart - PAGE_SIZE) + 1;
65
+ options.push(`← Previous (${ps}-${pageStart})`);
71
66
  }
72
67
  if (pageEnd < results.length) {
73
- const nextStart = pageEnd + 1;
74
- const nextEnd = Math.min(pageEnd + PAGE_SIZE, results.length);
75
- options.push({ label: `→ Next (${nextStart}-${nextEnd})`, description: "" });
68
+ options.push(`→ Next (${pageEnd + 1}-${Math.min(pageEnd + PAGE_SIZE, results.length)})`);
76
69
  }
77
- options.push({ label: "↩ Done", description: "" });
70
+ options.push("↩ Done");
78
71
 
79
72
  const title = `zmarketplace: ${results.length} results (page ${Math.floor(pageStart / PAGE_SIZE) + 1}/${Math.ceil(results.length / PAGE_SIZE)})`;
80
73
  const selected = await ctx.ui.select(title, options);
@@ -103,29 +96,23 @@ async function packageDetail(pkg: PackageResult, ctx: Ctx): Promise<void> {
103
96
  "⬇ Install (audit first)",
104
97
  "🔒 Audit only",
105
98
  "↩ Back to results",
106
- "━━━ Package ━━━",
107
- `📦 ${detail.name} v${detail.version ?? "?"}`,
99
+ `📦 ${detail.name} v${detail.version ?? "?"} ${detail.license ?? "?"} · ${detail.dependencyCount ?? "?"} deps · ${detail.size ? (detail.size / 1024).toFixed(0) + "KB" : "?"}`,
108
100
  detail.description || "",
109
- `License: ${detail.license ?? "?"} Deps: ${detail.dependencyCount ?? "?"} Size: ${detail.size ? (detail.size / 1024).toFixed(1) + " KB" : "?"}`,
110
- `Published: ${detail.publishedAt?.slice(0, 10) ?? "?"}`,
111
101
  ];
112
- if (detail.keywords?.length) lines.push(`Keywords: ${detail.keywords.join(", ")}`);
113
102
  if (detail.npmUrl) lines.push(`🔗 ${detail.npmUrl}`);
114
103
  if (repoBase) lines.push(`🔗 ${repoBase}`);
115
104
 
116
105
  if (detail.readme) {
117
- lines.push("━━━ README (enter on 🔗/🖼 to open) ━━━");
106
+ lines.push("━━━ README (40 lines — enter on 🔗 to open) ━━━");
118
107
  const rl = detail.readme
119
- .replace(/!\[.*?\]\((https?:\/\/[^)]+)\)/g, "\n🖼 IMAGE: $1\n")
120
- .replace(/!\[.*?\]\(([^)]+)\)/g, (_m, p) => `\n🖼 IMAGE: ${repoBase ? repoBase + "/raw/main/" + p.replace(/^\.\//, "") : p}\n`)
108
+ .replace(/!\[.*?\]\((https?:\/\/[^)]+)\)/g, "\n🖼 $1\n")
109
+ .replace(/!\[.*?\]\(([^)]+)\)/g, (_m, p) => `\n🖼 ${repoBase ? repoBase + "/raw/main/" + p.replace(/^\.\//, "") : p}\n`)
121
110
  .replace(/\[([^\]]+)\]\((https?:\/\/[^)]+)\)/g, "$1 → $2")
122
- .replace(/<img[^>]*src=["']([^"']+)["'][^>]*>/gi, (_m, p) => `\n🖼 IMAGE: ${p}\n`)
123
- .replace(/<a[^>]*href=["']([^"']+)["'][^>]*>(.*?)<\/a>/gi, "$2 → $1")
124
111
  .replace(/<[^>]+>/g, "")
125
112
  .split("\n").map(l => l.trimEnd()).filter(l => l.length > 0)
126
- .slice(0, 150);
113
+ .slice(0, 40);
127
114
  lines.push(...rl);
128
- if (detail.readme.length > 8000) lines.push("...(truncated — see npm for full README)");
115
+ lines.push("...(see npm for full README)");
129
116
  }
130
117
 
131
118
  while (true) {
@@ -173,25 +160,26 @@ async function doInstall(pkg: PackageResult, ctx: Ctx): Promise<void> {
173
160
  "",
174
161
  ];
175
162
 
176
- // Build install options
177
- const cmds: Array<{ label: string; description: string }> = [];
163
+ // Build install options as plain strings
164
+ const cmds: string[] = [];
165
+ const cmdMap = new Map<string, string>();
178
166
  const seen = new Set<string>();
167
+ const addCmd = (label: string, command: string) => { cmds.push(label); cmdMap.set(label, command); };
168
+
179
169
  for (const eco of pkg.ecosystems) {
180
170
  if ((eco === "pi" || eco === "omp") && !seen.has("pi")) {
181
171
  seen.add("pi");
182
- auditLines.push("🥧 pi install");
183
- cmds.push({ label: "🥧 pi install", description: `pi install npm:${pkg.name}` });
184
- cmds.push({ label: "⌥ omp install", description: `omp plugin install npm:${pkg.name}` });
185
- auditLines.push("⌥ omp install");
172
+ addCmd("🥧 pi install", `pi install npm:${pkg.name}`);
173
+ addCmd(" omp install", `omp plugin install npm:${pkg.name}`);
186
174
  }
187
- if (eco === "claude" && !seen.has("claude")) { seen.add("claude"); cmds.push({ label: "🤖 claude", description: `claude plugin install npm:${pkg.name}` }); auditLines.push("🤖 claude install"); }
188
- if (eco === "opencode" && !seen.has("opencode")) { seen.add("opencode"); cmds.push({ label: "🔓 opencode", description: `opencode plugin ${pkg.name}` }); auditLines.push("🔓 opencode install"); }
189
- if (eco === "gemini" && !seen.has("gemini")) { seen.add("gemini"); cmds.push({ label: "💎 gemini", description: `gemini extension install ${pkg.repository ?? pkg.name}` }); auditLines.push("💎 gemini install"); }
190
- if (eco === "codex" && !seen.has("codex")) { seen.add("codex"); cmds.push({ label: "🔲 codex", description: `codex plugin add npm:${pkg.name}` }); auditLines.push("🔲 codex install"); }
175
+ if (eco === "claude" && !seen.has("claude")) { seen.add("claude"); addCmd("🤖 claude", `claude plugin install npm:${pkg.name}`); }
176
+ if (eco === "opencode" && !seen.has("opencode")) { seen.add("opencode"); addCmd("🔓 opencode", `opencode plugin ${pkg.name}`); }
177
+ if (eco === "gemini" && !seen.has("gemini")) { seen.add("gemini"); addCmd("💎 gemini", `gemini extension install ${pkg.repository ?? pkg.name}`); }
178
+ if (eco === "codex" && !seen.has("codex")) { seen.add("codex"); addCmd("🔲 codex", `codex plugin add npm:${pkg.name}`); }
191
179
  }
192
- if (!seen.has("npm")) { cmds.push({ label: "📦 npm", description: `npm install ${pkg.name}` }); auditLines.push("📦 npm install"); }
193
- cmds.push({ label: "⚡ bunx", description: `bunx ${pkg.name}` });
194
- cmds.push({ label: "↩ Cancel", description: "" });
180
+ if (!seen.has("npm")) addCmd("📦 npm", `npm install ${pkg.name}`);
181
+ addCmd("⚡ bunx", `bunx ${pkg.name}`);
182
+ cmds.push("↩ Cancel");
195
183
 
196
184
  // High risk confirmation
197
185
  if (report.risk === "critical" || report.risk === "high") {
@@ -199,11 +187,10 @@ async function doInstall(pkg: PackageResult, ctx: Ctx): Promise<void> {
199
187
  if (!proceed) { ctx.ui.notify("Cancelled.", "info"); return; }
200
188
  }
201
189
 
202
- const choice = await ctx.ui.select(`Install ${pkg.name} — Audit: ${report.risk}`, cmds);
203
- if (!choice || choice.includes("Cancel")) return;
204
- const selected = cmds.find(c => c.label === choice);
205
- if (!selected) return;
206
- ctx.ui.notify(`✅ Run:\n ${selected.description}`, "info");
190
+ const choice = await ctx.ui.select(`Install ${pkg.name} — Risk: ${report.risk}`, cmds);
191
+ if (!choice || choice === "Cancel") return;
192
+ const command = cmdMap.get(choice);
193
+ if (command) ctx.ui.notify(`✅ Run:\n ${command}`, "info");
207
194
  }
208
195
 
209
196
  // ── Factory ────────────────────────────────────────────────────────────────