@amirhosseinnateghi/vibed-mcp 0.1.8 → 0.2.0
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/dist/index.js +251 -12
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -6083,6 +6083,9 @@ var config = {
|
|
|
6083
6083
|
// completion the server drops a notification (§7.1) — so a slow build never
|
|
6084
6084
|
// traps them staring at a spinner.
|
|
6085
6085
|
BUILDER_SLOW_MS: intEnv("BUILDER_SLOW_MS", 12e3),
|
|
6086
|
+
/** Lite edits (ف۷) kill switch: set to "off" to force every edit turn back to
|
|
6087
|
+
* whole-file regeneration without deploying code. */
|
|
6088
|
+
BUILDER_LITE_EDITS: strEnv("BUILDER_LITE_EDITS", "on"),
|
|
6086
6089
|
DEFAULT_LOCALE: strEnv("DEFAULT_LOCALE", "en")
|
|
6087
6090
|
};
|
|
6088
6091
|
function strEnv(key, fallback) {
|
|
@@ -10222,10 +10225,11 @@ var STORAGE = {
|
|
|
10222
10225
|
/** Max records returnable in one query page. */
|
|
10223
10226
|
QUERY_MAX_LIMIT: intEnv("STORE_QUERY_MAX_LIMIT", 100),
|
|
10224
10227
|
/**
|
|
10225
|
-
* Platform kill-switch for anonymous shared writes. ON by default
|
|
10226
|
-
* gate is per-post
|
|
10227
|
-
*
|
|
10228
|
-
*
|
|
10228
|
+
* Platform kill-switch for anonymous shared writes. ON by default. The real
|
|
10229
|
+
* gate is the per-post config (`anon_writes` + writePolicy `anyone`), which is
|
|
10230
|
+
* guest-writable BY DEFAULT (a shared vibe should work for whoever opens the
|
|
10231
|
+
* link) — an owner can lock it down per post. Set the env to `false` to disable
|
|
10232
|
+
* anon writes platform-wide regardless of per-post config.
|
|
10229
10233
|
*/
|
|
10230
10234
|
ANON_WRITES_AVAILABLE: boolEnv("STORE_ANON_WRITES_AVAILABLE", true)
|
|
10231
10235
|
};
|
|
@@ -10339,9 +10343,39 @@ var patchExperienceSchema = external_exports.object({
|
|
|
10339
10343
|
visibility: visibilitySchema.optional(),
|
|
10340
10344
|
coverMode: coverModeSchema.optional()
|
|
10341
10345
|
});
|
|
10346
|
+
var COMMENT_MEDIA = {
|
|
10347
|
+
quality: 0.82,
|
|
10348
|
+
maxEdge: 1600,
|
|
10349
|
+
maxBytes: 8 * 1024 * 1024,
|
|
10350
|
+
// video/* is the compressed comment clip (client-side MediaRecorder → mp4 on
|
|
10351
|
+
// iOS, webm on Chromium); the client never sends a raw camera video as-is.
|
|
10352
|
+
types: ["image/webp", "image/jpeg", "image/png", "image/gif", "video/mp4", "video/webm"]
|
|
10353
|
+
};
|
|
10354
|
+
var COMMENT_VIDEO = {
|
|
10355
|
+
maxDurationSec: 60,
|
|
10356
|
+
maxEdge: 720,
|
|
10357
|
+
// 1 Mbps → a 60s clip is ~7.5MB, comfortably under the 10MB request-body cap.
|
|
10358
|
+
bitsPerSecond: 1e6,
|
|
10359
|
+
crf: 30,
|
|
10360
|
+
maxUploadBytes: 120 * 1024 * 1024
|
|
10361
|
+
};
|
|
10362
|
+
var commentMediaSchema = external_exports.object({
|
|
10363
|
+
key: external_exports.string().min(1).max(300),
|
|
10364
|
+
type: external_exports.enum(COMMENT_MEDIA.types),
|
|
10365
|
+
w: external_exports.number().int().positive().max(2e4),
|
|
10366
|
+
h: external_exports.number().int().positive().max(2e4)
|
|
10367
|
+
});
|
|
10368
|
+
var commentVideoSchema = external_exports.object({ key: external_exports.string().min(1).max(300) });
|
|
10342
10369
|
var commentSchema = external_exports.object({
|
|
10343
|
-
body: external_exports.string().
|
|
10344
|
-
parentId: external_exports.string().uuid().optional()
|
|
10370
|
+
body: external_exports.string().max(500),
|
|
10371
|
+
parentId: external_exports.string().uuid().optional(),
|
|
10372
|
+
media: commentMediaSchema.optional(),
|
|
10373
|
+
// ready image/GIF (compressed client-side)
|
|
10374
|
+
video: commentVideoSchema.optional()
|
|
10375
|
+
// raw video → transcoded async in the worker
|
|
10376
|
+
}).refine((d) => d.body.trim().length > 0 || !!d.media || !!d.video, {
|
|
10377
|
+
message: "Write something or attach a photo or video.",
|
|
10378
|
+
path: ["body"]
|
|
10345
10379
|
});
|
|
10346
10380
|
var eventSchema = external_exports.object({
|
|
10347
10381
|
// "record"/"screenshot" fire when a viewer captures the vibe (see the in-iframe
|
|
@@ -10372,6 +10406,9 @@ var createTurnRequestSchema = external_exports.object({
|
|
|
10372
10406
|
// A voice turn carries no text yet — the worker transcribes `voice` first (م۷).
|
|
10373
10407
|
voice: voiceInputSchema.optional(),
|
|
10374
10408
|
model: external_exports.string().max(100).optional()
|
|
10409
|
+
// No editMode: lite edits (ف۷) proved themselves, so every edit takes that
|
|
10410
|
+
// path and the server decides — a client can't ask for the slow rewrite.
|
|
10411
|
+
// BUILDER_LITE_EDITS=off remains the fleet-wide kill switch.
|
|
10375
10412
|
}).refine((v) => v.content.trim().length > 0 || (v.attachments?.length ?? 0) > 0 || !!v.voice, {
|
|
10376
10413
|
message: "Send a message, an attachment, or a voice recording."
|
|
10377
10414
|
});
|
|
@@ -10476,6 +10513,183 @@ var notifPrefsPatchSchema = external_exports.object({
|
|
|
10476
10513
|
groups: external_exports.record(external_exports.enum(NOTIF_PREF_GROUPS), external_exports.boolean()).optional()
|
|
10477
10514
|
});
|
|
10478
10515
|
|
|
10516
|
+
// ../shared/src/remix.ts
|
|
10517
|
+
var REMIX_GUIDE = `# Make it remix-friendly
|
|
10518
|
+
|
|
10519
|
+
On vibed every published vibe is **remixable**: anyone can fork it and make it
|
|
10520
|
+
theirs, and the AI builder can be asked to change it. A vibe is only *really*
|
|
10521
|
+
remixable if a stranger \u2014 or a model editing it \u2014 can find the knobs without
|
|
10522
|
+
reading the whole file. Treat this as part of shipping, like mobile-first.
|
|
10523
|
+
|
|
10524
|
+
It pays off twice: edits to a well-structured file are applied as small precise
|
|
10525
|
+
patches instead of regenerating the whole thing, which is faster, cheaper, and
|
|
10526
|
+
far less likely to break what already worked.
|
|
10527
|
+
|
|
10528
|
+
## 1. One CONFIG block, at the top
|
|
10529
|
+
|
|
10530
|
+
Every tunable lives in a single object at the top of the script \u2014 the first
|
|
10531
|
+
thing anyone sees:
|
|
10532
|
+
|
|
10533
|
+
\`\`\`js
|
|
10534
|
+
const CONFIG = {
|
|
10535
|
+
// --- Feel ---
|
|
10536
|
+
gravity: 0.6,
|
|
10537
|
+
jumpForce: -11,
|
|
10538
|
+
pipeGap: 160,
|
|
10539
|
+
pipeSpeed: 2.4,
|
|
10540
|
+
// --- Look ---
|
|
10541
|
+
skyColor: "#7ec8ff",
|
|
10542
|
+
birdColor: "#ffd166",
|
|
10543
|
+
// --- Words (all user-facing text) ---
|
|
10544
|
+
title: "Tap to Fly",
|
|
10545
|
+
gameOverText: "Ouch! Tap to try again",
|
|
10546
|
+
scoreLabel: "Score",
|
|
10547
|
+
};
|
|
10548
|
+
\`\`\`
|
|
10549
|
+
|
|
10550
|
+
Rules that make it useful:
|
|
10551
|
+
- **Literal values only** \u2014 numbers, strings, colors. No computed expressions.
|
|
10552
|
+
- **Everything reads from CONFIG.** If a number appears twice in the logic, it
|
|
10553
|
+
belongs in CONFIG once.
|
|
10554
|
+
- **All user-facing text goes here too**, so rewording or translating a vibe is
|
|
10555
|
+
one edit, not a hunt.
|
|
10556
|
+
|
|
10557
|
+
## 2. Content separate from logic
|
|
10558
|
+
|
|
10559
|
+
Questions, levels, items, cards, prompts \u2014 a labelled array right after CONFIG:
|
|
10560
|
+
|
|
10561
|
+
\`\`\`js
|
|
10562
|
+
const QUESTIONS = [
|
|
10563
|
+
{ q: "Pick a color", options: ["Red", "Blue"], answer: 0 },
|
|
10564
|
+
// add more here \u2014 same shape
|
|
10565
|
+
];
|
|
10566
|
+
\`\`\`
|
|
10567
|
+
|
|
10568
|
+
Now "add five more questions" is a data edit anyone can make.
|
|
10569
|
+
|
|
10570
|
+
## 3. Predictable section order
|
|
10571
|
+
|
|
10572
|
+
Lay the script out in this order, each with a one-line banner comment:
|
|
10573
|
+
|
|
10574
|
+
\`\`\`js
|
|
10575
|
+
// ============ CONFIG ============
|
|
10576
|
+
// ============ CONTENT ===========
|
|
10577
|
+
// ============ STATE =============
|
|
10578
|
+
// ============ HELPERS ===========
|
|
10579
|
+
// ============ RENDER ============
|
|
10580
|
+
// ============ INPUT =============
|
|
10581
|
+
// ============ INIT ==============
|
|
10582
|
+
\`\`\`
|
|
10583
|
+
|
|
10584
|
+
A remixer (and a patching model) then knows where a change belongs before
|
|
10585
|
+
reading a single line.
|
|
10586
|
+
|
|
10587
|
+
## 4. Write it plainly
|
|
10588
|
+
|
|
10589
|
+
- Descriptive names: \`spawnEnemy()\`, not \`se()\`; \`playerSpeed\`, not \`ps\`.
|
|
10590
|
+
- Small functions that do one thing. One \`init()\` entry point, one game loop.
|
|
10591
|
+
- Two-space indent, no minification, no bundler output, no clever one-liners or
|
|
10592
|
+
chained ternaries.
|
|
10593
|
+
- A short comment at each seam someone would want to change:
|
|
10594
|
+
\`// Win condition \u2014 swap this for a timer, a score target, ...\`
|
|
10595
|
+
- Stable \`id\`/\`class\` names on the elements a remixer would target.
|
|
10596
|
+
- No dead code, and no copy-pasted near-identical blocks \u2014 factor them into one
|
|
10597
|
+
function. (Duplicated blocks also make an automated edit ambiguous, so it
|
|
10598
|
+
fails or lands in the wrong place.)
|
|
10599
|
+
|
|
10600
|
+
## 5. Quick self-check before publishing
|
|
10601
|
+
|
|
10602
|
+
- Could someone change the colors, speed, and all the words by editing only
|
|
10603
|
+
CONFIG?
|
|
10604
|
+
- Could they add one more level/question/item by editing only the content array?
|
|
10605
|
+
- Is there any magic number or user-facing string outside those two blocks?
|
|
10606
|
+
- Would a stranger know where to add a feature within ten seconds of scrolling?
|
|
10607
|
+
|
|
10608
|
+
If the answer to any of those is no, fix it before you publish \u2014 that is the
|
|
10609
|
+
difference between a vibe people fork and one they scroll past.`;
|
|
10610
|
+
var SMALL_VIBE_CHARS = 1200;
|
|
10611
|
+
var SMALL_VIBE_LINES = 40;
|
|
10612
|
+
var COMMENT_EXPECTED_LINES = 60;
|
|
10613
|
+
var SECTIONS_EXPECTED_LINES = 120;
|
|
10614
|
+
var MINIFIED_LINE_CHARS = 400;
|
|
10615
|
+
var MINIFIED_AVG_LINE_CHARS = 160;
|
|
10616
|
+
function authorScript(html) {
|
|
10617
|
+
const parts = [];
|
|
10618
|
+
const re = /<script\b([^>]*)>([\s\S]*?)<\/script\s*>/gi;
|
|
10619
|
+
let m;
|
|
10620
|
+
while (m = re.exec(html)) {
|
|
10621
|
+
const attrs = m[1] ?? "";
|
|
10622
|
+
if (/data-vibed-bridge/i.test(attrs)) continue;
|
|
10623
|
+
if (/\bsrc=/i.test(attrs)) continue;
|
|
10624
|
+
parts.push(m[2] ?? "");
|
|
10625
|
+
}
|
|
10626
|
+
return parts.join("\n");
|
|
10627
|
+
}
|
|
10628
|
+
function remixAudit(html) {
|
|
10629
|
+
const script = authorScript(html ?? "");
|
|
10630
|
+
const lines = script.split(/\r?\n/);
|
|
10631
|
+
const codeLines = lines.filter((l) => l.trim() !== "");
|
|
10632
|
+
const scriptLines = codeLines.length;
|
|
10633
|
+
const scriptChars = codeLines.reduce((n, l) => n + l.trim().length, 0);
|
|
10634
|
+
const avgLine = scriptLines > 0 ? scriptChars / scriptLines : 0;
|
|
10635
|
+
const findings = [];
|
|
10636
|
+
const longest = codeLines.reduce((n, l) => Math.max(n, l.trim().length), 0);
|
|
10637
|
+
const denselyPacked = scriptChars > 600 && avgLine > MINIFIED_AVG_LINE_CHARS;
|
|
10638
|
+
if (longest > MINIFIED_LINE_CHARS || denselyPacked) {
|
|
10639
|
+
findings.push({
|
|
10640
|
+
code: "MINIFIED",
|
|
10641
|
+
blocking: true,
|
|
10642
|
+
message: `The script averages ${Math.round(avgLine)} characters per line (longest ${longest}) \u2014 this looks minified or bundled.`,
|
|
10643
|
+
fix: "Publish readable source: turn off minification for the vibe build, or inline the unminified code."
|
|
10644
|
+
});
|
|
10645
|
+
}
|
|
10646
|
+
if (scriptLines >= SMALL_VIBE_LINES || scriptChars >= SMALL_VIBE_CHARS) {
|
|
10647
|
+
if (!/\b(?:const|let|var)\s+CONFIG\s*=/.test(script)) {
|
|
10648
|
+
findings.push({
|
|
10649
|
+
code: "NO_CONFIG",
|
|
10650
|
+
blocking: true,
|
|
10651
|
+
message: "No `const CONFIG = { ... }` block \u2014 a remixer has to hunt through the logic to change anything.",
|
|
10652
|
+
fix: "Move every tunable (speeds, sizes, colors, counts, durations) AND all user-facing text into one CONFIG object at the top, and read from it everywhere."
|
|
10653
|
+
});
|
|
10654
|
+
}
|
|
10655
|
+
const cryptic = /* @__PURE__ */ new Set();
|
|
10656
|
+
const decl = /\b(?:const|let|var)\s+([A-Za-z_$])\b(?!\s*[,)])/g;
|
|
10657
|
+
let d;
|
|
10658
|
+
while (d = decl.exec(script)) {
|
|
10659
|
+
const name = d[1];
|
|
10660
|
+
if (!"ijknxyt_".includes(name)) cryptic.add(name);
|
|
10661
|
+
}
|
|
10662
|
+
if (cryptic.size >= 5) {
|
|
10663
|
+
findings.push({
|
|
10664
|
+
code: "CRYPTIC_NAMES",
|
|
10665
|
+
blocking: true,
|
|
10666
|
+
message: `${cryptic.size} single-letter variables (${[...cryptic].slice(0, 6).join(", ")}) \u2014 the code reads as machine output.`,
|
|
10667
|
+
fix: "Give variables and functions descriptive names (`playerSpeed`, not `p`)."
|
|
10668
|
+
});
|
|
10669
|
+
}
|
|
10670
|
+
if (scriptLines >= COMMENT_EXPECTED_LINES) {
|
|
10671
|
+
const comments = codeLines.filter((l) => /^\s*(\/\/|\/\*|\*)/.test(l)).length;
|
|
10672
|
+
if (comments === 0) {
|
|
10673
|
+
findings.push({
|
|
10674
|
+
code: "NO_COMMENTS",
|
|
10675
|
+
blocking: false,
|
|
10676
|
+
message: "The script has no comments at all.",
|
|
10677
|
+
fix: "Add a short note at each seam a remixer would change (the win condition, the spawn rule, the scoring)."
|
|
10678
|
+
});
|
|
10679
|
+
}
|
|
10680
|
+
}
|
|
10681
|
+
if (scriptLines >= SECTIONS_EXPECTED_LINES && !/CONFIG\s*=+\s*$|=== *CONFIG|-- *CONFIG/im.test(script)) {
|
|
10682
|
+
findings.push({
|
|
10683
|
+
code: "NO_SECTIONS",
|
|
10684
|
+
blocking: false,
|
|
10685
|
+
message: "No section banners in a long script.",
|
|
10686
|
+
fix: "Split it with banner comments: CONFIG \u2192 CONTENT \u2192 STATE \u2192 helpers \u2192 render \u2192 input \u2192 init."
|
|
10687
|
+
});
|
|
10688
|
+
}
|
|
10689
|
+
}
|
|
10690
|
+
return { ok: !findings.some((f) => f.blocking), findings, scriptLines };
|
|
10691
|
+
}
|
|
10692
|
+
|
|
10479
10693
|
// ../shared/src/builderEvents.ts
|
|
10480
10694
|
var BUILD_EVENT_VERSION = 1;
|
|
10481
10695
|
var BUILD_PHASES = [
|
|
@@ -11133,8 +11347,10 @@ async function bundleProject(projectDir, opts = {}) {
|
|
|
11133
11347
|
allowedOrigins
|
|
11134
11348
|
});
|
|
11135
11349
|
const result = validate(html, { maxBytes, allowedOrigins, policy: opts.policy });
|
|
11350
|
+
const remix = remixAudit(html);
|
|
11136
11351
|
return {
|
|
11137
|
-
ok: result.ok,
|
|
11352
|
+
ok: result.ok && remix.ok,
|
|
11353
|
+
remix,
|
|
11138
11354
|
html,
|
|
11139
11355
|
policy: opts.policy,
|
|
11140
11356
|
entry: resolved.entry,
|
|
@@ -11195,12 +11411,28 @@ function formatReport(result) {
|
|
|
11195
11411
|
result.sizeBytes != null ? `size: ${fmtSize(result.sizeBytes)}` : null
|
|
11196
11412
|
].filter(Boolean).join(" \xB7 ");
|
|
11197
11413
|
if (where) out.push(where);
|
|
11414
|
+
const remixBlockers = (result.remix?.findings ?? []).filter((f) => f.blocking);
|
|
11198
11415
|
if (result.ok) {
|
|
11199
11416
|
out.push("\u2713 Vibeable \u2014 this project can be published to vibed.");
|
|
11200
|
-
} else {
|
|
11417
|
+
} else if (result.blockers.length > 0) {
|
|
11201
11418
|
out.push(`\u2717 Not vibeable yet \u2014 ${result.blockers.length} blocker(s):`);
|
|
11202
11419
|
out.push(...summarize(result).lines);
|
|
11203
11420
|
}
|
|
11421
|
+
if (remixBlockers.length > 0) {
|
|
11422
|
+
out.push("");
|
|
11423
|
+
out.push(`\u2717 Not remixable yet \u2014 ${remixBlockers.length} thing(s) to fix before publishing:`);
|
|
11424
|
+
for (const f of remixBlockers) {
|
|
11425
|
+
out.push(` \u2022 ${f.message}`);
|
|
11426
|
+
out.push(` \u2192 ${f.fix}`);
|
|
11427
|
+
}
|
|
11428
|
+
out.push(" Run `vibed remixable` for the full guide.");
|
|
11429
|
+
}
|
|
11430
|
+
const remixAdvice = (result.remix?.findings ?? []).filter((f) => !f.blocking);
|
|
11431
|
+
if (remixAdvice.length > 0) {
|
|
11432
|
+
out.push("");
|
|
11433
|
+
out.push("Remix polish (not blocking):");
|
|
11434
|
+
for (const f of remixAdvice) out.push(` \u2022 ${f.message} \u2192 ${f.fix}`);
|
|
11435
|
+
}
|
|
11204
11436
|
if (result.policy && ruleActive("no_vertical_scroll", result.policy)) {
|
|
11205
11437
|
out.push(
|
|
11206
11438
|
"",
|
|
@@ -11500,7 +11732,8 @@ async function deleteExperience(client, idOrUrl) {
|
|
|
11500
11732
|
}
|
|
11501
11733
|
|
|
11502
11734
|
// src/index.ts
|
|
11503
|
-
var
|
|
11735
|
+
var MCP_VERSION = true ? "0.2.0" : "0.0.0-dev";
|
|
11736
|
+
var SERVER_INFO = { name: "vibed", version: MCP_VERSION };
|
|
11504
11737
|
var PROTOCOL_VERSION = "2024-11-05";
|
|
11505
11738
|
var pendingLogin = null;
|
|
11506
11739
|
var str = (v, d = "") => typeof v === "string" ? v : d;
|
|
@@ -11512,9 +11745,15 @@ var TOOLS = [
|
|
|
11512
11745
|
inputSchema: { type: "object", properties: {} },
|
|
11513
11746
|
run: async () => STORAGE_GUIDE
|
|
11514
11747
|
},
|
|
11748
|
+
{
|
|
11749
|
+
name: "vibed_remix_guide",
|
|
11750
|
+
description: "How to write a vibe that others can actually REMIX \u2014 vibed's signature loop, where every published vibe is someone else's starting point (and may later be edited by the AI builder). Returns the authoring rules: one CONFIG block at the top holding every tunable and all user-facing text, content/data separated from logic, a predictable section order, and plainly written code. Call this BEFORE writing a vibe, and follow it while building \u2014 the same structure is what lets later edits be applied as small precise patches instead of rewriting the whole file.",
|
|
11751
|
+
inputSchema: { type: "object", properties: {} },
|
|
11752
|
+
run: async () => REMIX_GUIDE
|
|
11753
|
+
},
|
|
11515
11754
|
{
|
|
11516
11755
|
name: "vibed_check",
|
|
11517
|
-
description: "Bundle the project into a single HTML file and validate it against vibed's sandbox rules (no network/auth). Returns whether it's publishable and, if not, the blockers to fix. Run this before vibed_publish. If it warns BROWSER_STORAGE (localStorage etc. throw in the sandbox), call vibed_storage_guide and port to window.vibed.storage.",
|
|
11756
|
+
description: "Bundle the project into a single HTML file and validate it against vibed's sandbox rules (no network/auth). Returns whether it's publishable and, if not, the blockers to fix. Run this before vibed_publish. If it warns BROWSER_STORAGE (localStorage etc. throw in the sandbox), call vibed_storage_guide and port to window.vibed.storage. This also audits REMIX-FRIENDLINESS (readable code, a CONFIG block holding every tunable and all user-facing text) and REFUSES a file that fails \u2014 call vibed_remix_guide and fix it.",
|
|
11518
11757
|
inputSchema: {
|
|
11519
11758
|
type: "object",
|
|
11520
11759
|
properties: {
|
|
@@ -11582,7 +11821,7 @@ After the user approves, call vibed_login_wait.`;
|
|
|
11582
11821
|
},
|
|
11583
11822
|
{
|
|
11584
11823
|
name: "vibed_draft",
|
|
11585
|
-
description: "
|
|
11824
|
+
description: "THE DEFAULT for 'make it vibed' / 'publish to vibed': bundle the project and upload it as a PRIVATE draft, returning a hosted, sandboxed PREVIEW link (\u2026/p/<id>/) and a draftKey. Publishes NOTHING \u2014 the link is in no feed, profile, or search; only someone with it can open it. Give the user the preview link, then STOP and let them review \u2014 'make it vibed' means preview first, NOT publish. Only call vibed_publish after the user explicitly tells you to publish this draft. Requires sign-in. BEFORE drafting, make the single HTML file remix-friendly \u2014 a file-top comment, tunable constants (speed/difficulty/colors/text) grouped and labeled near the top, clear names, comments on the non-obvious WHY, readable not minified \u2014 because remix is core to vibed and its AI builder edits THIS file to fork it.",
|
|
11586
11825
|
inputSchema: {
|
|
11587
11826
|
type: "object",
|
|
11588
11827
|
properties: {
|
|
@@ -11613,7 +11852,7 @@ Show it to the user. To publish it, call vibed_publish with draftKey: ${d.draftA
|
|
|
11613
11852
|
},
|
|
11614
11853
|
{
|
|
11615
11854
|
name: "vibed_publish",
|
|
11616
|
-
description: "
|
|
11855
|
+
description: "Make a draft PUBLIC. Publishing is public and hard to undo \u2014 do NOT call this unless the user has EXPLICITLY told you to publish (e.g. 'publish it', 'post it', 'go ahead'). 'make it vibed' is NOT a publish instruction, and 'looks good' is not either \u2014 when unsure, ask and wait. Default flow: vibed_draft \u2192 user reviews the preview \u2192 user says publish \u2192 this. Pass draftKey (from vibed_draft) to promote the previewed draft (preferred); passing path bundles + publishes in one shot and SKIPS the preview \u2014 only do that if the user asked to skip it. Requires sign-in. Confirm the title and tags first. Returns the published URL.",
|
|
11617
11856
|
inputSchema: {
|
|
11618
11857
|
type: "object",
|
|
11619
11858
|
properties: {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amirhosseinnateghi/vibed-mcp",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "vibed MCP server
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "vibed MCP server \u2014 make it vibed from any MCP client (Codex, Cursor, Gemini, \u2026): check, login, and publish tools",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"access": "public"
|
|
16
16
|
},
|
|
17
17
|
"scripts": {
|
|
18
|
-
"build": "esbuild src/index.ts --bundle --platform=node --target=node20 --format=esm --outfile=dist/index.js && chmod +x dist/index.js",
|
|
18
|
+
"build": "esbuild src/index.ts --bundle --platform=node --target=node20 --format=esm --define:__VIBED_MCP_VERSION__='\"0.2.0\"' --outfile=dist/index.js && chmod +x dist/index.js",
|
|
19
19
|
"prepublishOnly": "pnpm build",
|
|
20
20
|
"dev": "tsx src/index.ts",
|
|
21
21
|
"typecheck": "tsc --noEmit",
|