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.
- package/package.json +1 -1
- package/src/index.ts +29 -42
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zmarketplace",
|
|
3
|
-
"version": "0.4.
|
|
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
|
|
69
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
"
|
|
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
|
|
106
|
+
lines.push("━━━ README (40 lines — enter on 🔗 to open) ━━━");
|
|
118
107
|
const rl = detail.readme
|
|
119
|
-
.replace(/!\[.*?\]\((https?:\/\/[^)]+)\)/g, "\n🖼
|
|
120
|
-
.replace(/!\[.*?\]\(([^)]+)\)/g, (_m, 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,
|
|
113
|
+
.slice(0, 40);
|
|
127
114
|
lines.push(...rl);
|
|
128
|
-
|
|
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:
|
|
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
|
-
|
|
183
|
-
|
|
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");
|
|
188
|
-
if (eco === "opencode" && !seen.has("opencode")) { seen.add("opencode");
|
|
189
|
-
if (eco === "gemini" && !seen.has("gemini")) { seen.add("gemini");
|
|
190
|
-
if (eco === "codex" && !seen.has("codex")) { seen.add("codex");
|
|
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"))
|
|
193
|
-
|
|
194
|
-
cmds.push(
|
|
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} —
|
|
203
|
-
if (!choice || choice
|
|
204
|
-
const
|
|
205
|
-
if (
|
|
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 ────────────────────────────────────────────────────────────────
|