@amirhosseinnateghi/vibed-cli 0.1.0 → 0.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/dist/index.js +247 -139
  2. package/package.json +5 -2
package/dist/index.js CHANGED
@@ -6018,141 +6018,6 @@ import { dirname, extname, isAbsolute, join as join2, resolve } from "node:path"
6018
6018
 
6019
6019
  // ../sandbox/src/index.ts
6020
6020
  var import_node_html_parser = __toESM(require_dist(), 1);
6021
- var FORBIDDEN_API_PATTERNS = [
6022
- { re: /getUserMedia/, name: "getUserMedia" },
6023
- { re: /navigator\s*\.\s*geolocation/, name: "geolocation" },
6024
- { re: /new\s+Notification|Notification\s*\.\s*requestPermission/, name: "Notification" },
6025
- { re: /serviceWorker/, name: "serviceWorker" },
6026
- { re: /openDatabase/, name: "openDatabase" },
6027
- { re: /PaymentRequest|navigator\s*\.\s*payments/, name: "PaymentRequest" },
6028
- { re: /navigator\s*\.\s*credentials|PublicKeyCredential|WebAuthn/, name: "WebAuthn" },
6029
- { re: /requestPointerLock/, name: "pointerLock" }
6030
- // allowed via gesture only; flag
6031
- ];
6032
- var TOP_NAV_PATTERNS = [
6033
- /window\s*\.\s*top/,
6034
- /window\s*\.\s*parent\s*\.\s*location/,
6035
- /\btop\s*\.\s*location/,
6036
- /\bparent\s*\.\s*location/
6037
- ];
6038
- var BRAND_NAMES = [
6039
- "google",
6040
- "gmail",
6041
- "apple",
6042
- "icloud",
6043
- "microsoft",
6044
- "outlook",
6045
- "paypal",
6046
- "facebook",
6047
- "instagram",
6048
- "telegram",
6049
- "whatsapp",
6050
- "metamask",
6051
- "binance",
6052
- "coinbase"
6053
- ];
6054
- function extractExternalHosts(html) {
6055
- const scrubbed = html.replace(/\bxmlns(:[a-z0-9-]+)?\s*=\s*("[^"]*"|'[^']*')/gi, "").replace(/<!DOCTYPE[^>]*>/gi, "");
6056
- const hosts = /* @__PURE__ */ new Set();
6057
- const re = /https?:\/\/([a-z0-9.-]+)/gi;
6058
- let m;
6059
- while (m = re.exec(scrubbed)) {
6060
- const host = m[1]?.toLowerCase();
6061
- if (host) hosts.add(host);
6062
- }
6063
- return [...hosts];
6064
- }
6065
- function looksLikeHtml(root) {
6066
- const hasEl = root.querySelector("*") != null;
6067
- return hasEl;
6068
- }
6069
- function validate(html, opts) {
6070
- const errors = [];
6071
- const warnings = [];
6072
- const size = Buffer.byteLength(html, "utf8");
6073
- if (size > opts.maxBytes) {
6074
- errors.push({
6075
- code: "SIZE_EXCEEDED",
6076
- message: `Artifact is ${size} bytes; limit is ${opts.maxBytes}.`
6077
- });
6078
- }
6079
- const root = (0, import_node_html_parser.parse)(html, {
6080
- lowerCaseTagName: true,
6081
- comment: true,
6082
- voidTag: { closingSlash: true }
6083
- });
6084
- if (!looksLikeHtml(root)) {
6085
- errors.push({ code: "NOT_HTML", message: "Content is not parseable as HTML." });
6086
- return { ok: false, errors, warnings };
6087
- }
6088
- if (root.querySelector("iframe, frame, object, embed")) {
6089
- errors.push({
6090
- code: "FRAME_TAG",
6091
- message: "Frames are not allowed (iframe/frame/object/embed)."
6092
- });
6093
- }
6094
- if (root.querySelector("base")) {
6095
- errors.push({ code: "BASE_TAG", message: "<base> tags are not allowed." });
6096
- }
6097
- for (const meta of root.querySelectorAll("meta")) {
6098
- if ((meta.getAttribute("http-equiv") || "").toLowerCase() === "refresh") {
6099
- errors.push({ code: "META_REFRESH", message: "meta-refresh redirects are not allowed." });
6100
- break;
6101
- }
6102
- }
6103
- for (const input of root.querySelectorAll("input")) {
6104
- if ((input.getAttribute("type") || "").toLowerCase() === "password") {
6105
- errors.push({
6106
- code: "PASSWORD_INPUT",
6107
- message: 'Password inputs are not allowed (<input type="password">).'
6108
- });
6109
- break;
6110
- }
6111
- }
6112
- for (const re of TOP_NAV_PATTERNS) {
6113
- if (re.test(html)) {
6114
- errors.push({
6115
- code: "TOP_NAVIGATION",
6116
- message: "Top-level navigation attempts are not allowed.",
6117
- detail: re.source
6118
- });
6119
- break;
6120
- }
6121
- }
6122
- for (const { re, name } of FORBIDDEN_API_PATTERNS) {
6123
- if (re.test(html)) {
6124
- errors.push({
6125
- code: "FORBIDDEN_API",
6126
- message: `Forbidden API used: ${name}.`,
6127
- detail: name
6128
- });
6129
- }
6130
- }
6131
- const hosts = extractExternalHosts(html);
6132
- const offending = hosts.filter(
6133
- (h) => !opts.allowedOrigins.some((allowed) => h === allowed || h.endsWith("." + allowed))
6134
- );
6135
- for (const host of offending) {
6136
- errors.push({
6137
- code: "EXTERNAL_URL",
6138
- message: `External URL not in allowlist: ${host}`,
6139
- detail: host
6140
- });
6141
- }
6142
- const lower = html.toLowerCase();
6143
- const hasCredField = root.querySelector('input[type="email"], input[type="text"], input[type="tel"]') != null && /(password|passcode|otp|verify|sign\s*in|log\s*in|account)/i.test(html);
6144
- if (hasCredField) {
6145
- const brand = BRAND_NAMES.find((b) => lower.includes(b));
6146
- if (brand) {
6147
- warnings.push({
6148
- code: "BRAND_CREDENTIAL",
6149
- message: `Possible phishing: brand "${brand}" near a credential field.`,
6150
- detail: brand
6151
- });
6152
- }
6153
- }
6154
- return { ok: errors.length === 0, errors, warnings };
6155
- }
6156
6021
 
6157
6022
  // ../shared/src/constants.ts
6158
6023
  var CATEGORIES = [
@@ -6181,6 +6046,17 @@ var config = {
6181
6046
  MODERATION_AUTOPUBLISH: boolEnv("MODERATION_AUTOPUBLISH", true),
6182
6047
  BUILDER_MODE: strEnv("BUILDER_MODE", "mock"),
6183
6048
  // 'mock' | 'live'
6049
+ // Builder LLM — non-secret routing only (this object ships to the client).
6050
+ // The platform API key is read server-side from process.env.BUILDER_API_KEY.
6051
+ // Which platform provider serves the builder: 'gapgpt' | 'openrouter'.
6052
+ BUILDER_PROVIDER: strEnv("BUILDER_PROVIDER", "gapgpt"),
6053
+ BUILDER_BASE_URL: strEnv("BUILDER_BASE_URL", "https://api.gapgpt.app/v1"),
6054
+ BUILDER_MODEL: strEnv("BUILDER_MODEL", "claude-sonnet-4-20250514"),
6055
+ // Light model that auto-tags the experience category. Falls back to a keyword
6056
+ // heuristic if the call fails.
6057
+ BUILDER_CLASSIFIER_MODEL: strEnv("BUILDER_CLASSIFIER_MODEL", "gemini-2.5-flash"),
6058
+ BUILDER_MAX_TOKENS: intEnv("BUILDER_MAX_TOKENS", 8192),
6059
+ BUILDER_MAX_MESSAGES: intEnv("BUILDER_MAX_MESSAGES", 30),
6184
6060
  DEFAULT_LOCALE: strEnv("DEFAULT_LOCALE", "en")
6185
6061
  };
6186
6062
  function strEnv(key, fallback) {
@@ -6203,6 +6079,37 @@ function boolEnv(key, fallback) {
6203
6079
  return v === "true" || v === "1";
6204
6080
  }
6205
6081
 
6082
+ // ../shared/src/policy.ts
6083
+ function boolEnv2(key, fallback) {
6084
+ const v = typeof process !== "undefined" ? process.env[key] : void 0;
6085
+ if (v == null || v === "") return fallback;
6086
+ return v === "true" || v === "1";
6087
+ }
6088
+ var POST_RULES = [
6089
+ { id: "size_limit", code: "SIZE_EXCEEDED", title: "Size limit", default: true, env: "RULE_SIZE_LIMIT" },
6090
+ { id: "frames", code: "FRAME_TAG", title: "No frames", default: true, env: "RULE_FRAMES" },
6091
+ { id: "base_tag", code: "BASE_TAG", title: "No <base> tag", default: true, env: "RULE_BASE_TAG" },
6092
+ { id: "meta_refresh", code: "META_REFRESH", title: "No meta-refresh", default: true, env: "RULE_META_REFRESH" },
6093
+ { id: "password_input", code: "PASSWORD_INPUT", title: "No password inputs", default: true, env: "RULE_PASSWORD_INPUT" },
6094
+ { id: "top_navigation", code: "TOP_NAVIGATION", title: "No top-navigation", default: true, env: "RULE_TOP_NAVIGATION" },
6095
+ { id: "forbidden_apis", code: "FORBIDDEN_API", title: "No forbidden APIs (payments, background, capture\u2026)", default: true, env: "RULE_FORBIDDEN_APIS" },
6096
+ { id: "external_urls", code: "EXTERNAL_URL", title: "No off-allowlist external URLs", default: true, env: "RULE_EXTERNAL_URLS" },
6097
+ { id: "external_scripts", code: "EXTERNAL_SCRIPT", title: "No creator-selected JS packages (external <script>)", default: false, env: "RULE_EXTERNAL_SCRIPTS" },
6098
+ { id: "external_links", code: "EXTERNAL_LINK", title: "No direct external links (<a> off-site)", default: false, env: "RULE_EXTERNAL_LINKS" },
6099
+ // Enforced by injecting a viewport clip at sanitize (not a reject) — a static
6100
+ // scan can't tell whether a post actually scrolls, so we make it can't.
6101
+ { id: "no_vertical_scroll", code: "SANITIZE_CLIP", title: "No vertical page scroll (fit the viewport)", default: true, env: "RULE_NO_VERTICAL_SCROLL" }
6102
+ ];
6103
+ function resolvePolicy() {
6104
+ const rules = {};
6105
+ for (const r of POST_RULES) rules[r.id] = boolEnv2(r.env, r.default);
6106
+ return { enabled: boolEnv2("POST_RESTRICTIONS_ENABLED", true), rules };
6107
+ }
6108
+ var postPolicy = resolvePolicy();
6109
+ function ruleActive(id, policy = postPolicy) {
6110
+ return policy.enabled && policy.rules[id] === true;
6111
+ }
6112
+
6206
6113
  // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/external.js
6207
6114
  var external_exports = {};
6208
6115
  __export(external_exports, {
@@ -10284,8 +10191,19 @@ var createBuildSchema = external_exports.object({
10284
10191
  mode: external_exports.enum(["ai", "remix"]),
10285
10192
  remixParentId: external_exports.string().uuid().optional()
10286
10193
  });
10194
+ var builderAttachmentSchema = external_exports.object({
10195
+ kind: external_exports.enum(["image", "file"]),
10196
+ name: external_exports.string().max(200),
10197
+ dataUrl: external_exports.string().max(8e6).optional(),
10198
+ // ~6MB image as base64 data URL
10199
+ text: external_exports.string().max(5e4).optional()
10200
+ });
10287
10201
  var builderMessageSchema = external_exports.object({
10288
- content: external_exports.string().min(1).max(4e3)
10202
+ content: external_exports.string().max(4e3).default(""),
10203
+ attachments: external_exports.array(builderAttachmentSchema).max(6).optional(),
10204
+ model: external_exports.string().max(100).optional()
10205
+ }).refine((v) => v.content.trim().length > 0 || (v.attachments?.length ?? 0) > 0, {
10206
+ message: "Send a message or an attachment."
10289
10207
  });
10290
10208
  var importSchema = external_exports.object({
10291
10209
  html: external_exports.string().min(1).optional(),
@@ -10296,6 +10214,7 @@ var importSchema = external_exports.object({
10296
10214
  var saveSchema = external_exports.object({
10297
10215
  collectionId: external_exports.string().uuid().optional()
10298
10216
  });
10217
+ var AI_PROVIDERS = ["gapgpt", "moonshot", "openai", "openrouter"];
10299
10218
  var collectionSchema = external_exports.object({
10300
10219
  name: external_exports.string().min(1).max(60)
10301
10220
  });
@@ -10313,8 +10232,8 @@ var patchMeSchema = external_exports.object({
10313
10232
  // once
10314
10233
  });
10315
10234
  var aiConnectionSchema = external_exports.object({
10316
- provider: external_exports.enum(["openai", "anthropic"]),
10317
- apiKey: external_exports.string().min(8)
10235
+ provider: external_exports.enum(AI_PROVIDERS),
10236
+ apiKey: external_exports.string().trim().min(12).max(300)
10318
10237
  });
10319
10238
  var feedQuerySchema = external_exports.object({
10320
10239
  tab: external_exports.enum(["explore", "following"]).default("explore"),
@@ -10330,6 +10249,24 @@ var searchQuerySchema = external_exports.object({
10330
10249
  limit: external_exports.coerce.number().int().min(1).max(30).default(15)
10331
10250
  });
10332
10251
 
10252
+ // ../shared/src/models.ts
10253
+ var BUILDER_MODELS = [
10254
+ // ── Free (selectable now) — good quality, reasonable price ─────────
10255
+ { id: "claude-sonnet-4-20250514", label: "Claude Sonnet 4", tier: "free", note: "Best for polished HTML", vision: true },
10256
+ { id: "gemini-2.5-flash", label: "Gemini 2.5 Flash", tier: "free", note: "Fast \xB7 great UI \xB7 cheap", vision: true },
10257
+ { id: "gpt-4o-mini", label: "GPT-4o mini", tier: "free", note: "Cheap & reliable", vision: true },
10258
+ { id: "gpt-5-mini", label: "GPT-5 mini", tier: "free", note: "Newer, capable", vision: true },
10259
+ { id: "gpt-5.1-codex", label: "GPT-5.1 Codex", tier: "free", note: "Code specialist" },
10260
+ { id: "deepseek-v4-pro", label: "DeepSeek V4 Pro", tier: "free", note: "Strong coder \xB7 great value" },
10261
+ { id: "deepseek-v4-flash", label: "DeepSeek V4 Flash", tier: "free", note: "Fast \xB7 very cheap" },
10262
+ { id: "gapgpt-qwen-3.6", label: "Qwen 3.6", tier: "free", note: "Good value" },
10263
+ // ── Subscription (locked until billing is enabled) — premium ──────
10264
+ { id: "claude-opus-4-8", label: "Claude Opus 4.8", tier: "subscription", note: "Top quality", vision: true },
10265
+ { id: "gpt-5.2-pro", label: "GPT-5.2 Pro", tier: "subscription", note: "Premium" },
10266
+ { id: "gemini-3-pro-preview", label: "Gemini 3 Pro", tier: "subscription", note: "Premium", vision: true }
10267
+ ];
10268
+ var FREE_IDS = new Set(BUILDER_MODELS.filter((m) => m.tier === "free").map((m) => m.id));
10269
+
10333
10270
  // ../shared/src/tokens.ts
10334
10271
  var colors = {
10335
10272
  brand: "#6C4CF1",
@@ -10361,6 +10298,175 @@ var toggle = {
10361
10298
  knobTo: "22px"
10362
10299
  };
10363
10300
 
10301
+ // ../sandbox/src/index.ts
10302
+ var FORBIDDEN_API_PATTERNS = [
10303
+ { re: /getUserMedia/, name: "getUserMedia" },
10304
+ { re: /navigator\s*\.\s*geolocation/, name: "geolocation" },
10305
+ { re: /new\s+Notification|Notification\s*\.\s*requestPermission/, name: "Notification" },
10306
+ { re: /serviceWorker/, name: "serviceWorker" },
10307
+ { re: /openDatabase/, name: "openDatabase" },
10308
+ { re: /PaymentRequest|navigator\s*\.\s*payments/, name: "PaymentRequest" },
10309
+ { re: /navigator\s*\.\s*credentials|PublicKeyCredential|WebAuthn/, name: "WebAuthn" },
10310
+ { re: /requestPointerLock/, name: "pointerLock" }
10311
+ // allowed via gesture only; flag
10312
+ ];
10313
+ var TOP_NAV_PATTERNS = [
10314
+ /window\s*\.\s*top/,
10315
+ /window\s*\.\s*parent\s*\.\s*location/,
10316
+ /\btop\s*\.\s*location/,
10317
+ /\bparent\s*\.\s*location/
10318
+ ];
10319
+ var BRAND_NAMES = [
10320
+ "google",
10321
+ "gmail",
10322
+ "apple",
10323
+ "icloud",
10324
+ "microsoft",
10325
+ "outlook",
10326
+ "paypal",
10327
+ "facebook",
10328
+ "instagram",
10329
+ "telegram",
10330
+ "whatsapp",
10331
+ "metamask",
10332
+ "binance",
10333
+ "coinbase"
10334
+ ];
10335
+ function extractExternalHosts(html) {
10336
+ const scrubbed = html.replace(/\bxmlns(:[a-z0-9-]+)?\s*=\s*("[^"]*"|'[^']*')/gi, "").replace(/<!DOCTYPE[^>]*>/gi, "");
10337
+ const hosts = /* @__PURE__ */ new Set();
10338
+ const re = /https?:\/\/([a-z0-9.-]+)/gi;
10339
+ let m;
10340
+ while (m = re.exec(scrubbed)) {
10341
+ const host = m[1]?.toLowerCase();
10342
+ if (host) hosts.add(host);
10343
+ }
10344
+ return [...hosts];
10345
+ }
10346
+ function looksLikeHtml(root) {
10347
+ const hasEl = root.querySelector("*") != null;
10348
+ return hasEl;
10349
+ }
10350
+ function validate(html, opts) {
10351
+ const errors = [];
10352
+ const warnings = [];
10353
+ const size = Buffer.byteLength(html, "utf8");
10354
+ const policy = opts.policy ?? postPolicy;
10355
+ const on = (id) => ruleActive(id, policy);
10356
+ if (on("size_limit") && size > opts.maxBytes) {
10357
+ errors.push({
10358
+ code: "SIZE_EXCEEDED",
10359
+ message: `Artifact is ${size} bytes; limit is ${opts.maxBytes}.`
10360
+ });
10361
+ }
10362
+ const root = (0, import_node_html_parser.parse)(html, {
10363
+ lowerCaseTagName: true,
10364
+ comment: true,
10365
+ voidTag: { closingSlash: true }
10366
+ });
10367
+ if (!looksLikeHtml(root)) {
10368
+ errors.push({ code: "NOT_HTML", message: "Content is not parseable as HTML." });
10369
+ return { ok: false, errors, warnings };
10370
+ }
10371
+ if (on("frames") && root.querySelector("iframe, frame, object, embed")) {
10372
+ errors.push({
10373
+ code: "FRAME_TAG",
10374
+ message: "Frames are not allowed (iframe/frame/object/embed)."
10375
+ });
10376
+ }
10377
+ if (on("base_tag") && root.querySelector("base")) {
10378
+ errors.push({ code: "BASE_TAG", message: "<base> tags are not allowed." });
10379
+ }
10380
+ if (on("meta_refresh")) {
10381
+ for (const meta of root.querySelectorAll("meta")) {
10382
+ if ((meta.getAttribute("http-equiv") || "").toLowerCase() === "refresh") {
10383
+ errors.push({ code: "META_REFRESH", message: "meta-refresh redirects are not allowed." });
10384
+ break;
10385
+ }
10386
+ }
10387
+ }
10388
+ if (on("password_input")) {
10389
+ for (const input of root.querySelectorAll("input")) {
10390
+ if ((input.getAttribute("type") || "").toLowerCase() === "password") {
10391
+ errors.push({
10392
+ code: "PASSWORD_INPUT",
10393
+ message: 'Password inputs are not allowed (<input type="password">).'
10394
+ });
10395
+ break;
10396
+ }
10397
+ }
10398
+ }
10399
+ if (on("top_navigation")) {
10400
+ for (const re of TOP_NAV_PATTERNS) {
10401
+ if (re.test(html)) {
10402
+ errors.push({
10403
+ code: "TOP_NAVIGATION",
10404
+ message: "Top-level navigation attempts are not allowed.",
10405
+ detail: re.source
10406
+ });
10407
+ break;
10408
+ }
10409
+ }
10410
+ }
10411
+ if (on("forbidden_apis")) {
10412
+ for (const { re, name } of FORBIDDEN_API_PATTERNS) {
10413
+ if (re.test(html)) {
10414
+ errors.push({ code: "FORBIDDEN_API", message: `Forbidden API used: ${name}.`, detail: name });
10415
+ }
10416
+ }
10417
+ }
10418
+ if (on("external_urls")) {
10419
+ const hosts = extractExternalHosts(html);
10420
+ const offending = hosts.filter(
10421
+ (h) => !opts.allowedOrigins.some((allowed) => h === allowed || h.endsWith("." + allowed))
10422
+ );
10423
+ for (const host of offending) {
10424
+ errors.push({
10425
+ code: "EXTERNAL_URL",
10426
+ message: `External URL not in allowlist: ${host}`,
10427
+ detail: host
10428
+ });
10429
+ }
10430
+ }
10431
+ if (on("external_scripts")) {
10432
+ for (const s of root.querySelectorAll("script")) {
10433
+ const src = s.getAttribute("src");
10434
+ if (src && /^(https?:)?\/\//i.test(src.trim())) {
10435
+ errors.push({
10436
+ code: "EXTERNAL_SCRIPT",
10437
+ message: `External script not allowed (inline your code): ${src}`,
10438
+ detail: src
10439
+ });
10440
+ }
10441
+ }
10442
+ }
10443
+ if (on("external_links")) {
10444
+ for (const a of root.querySelectorAll("a")) {
10445
+ const href = (a.getAttribute("href") || "").trim();
10446
+ if (/^(https?:)?\/\//i.test(href)) {
10447
+ errors.push({
10448
+ code: "EXTERNAL_LINK",
10449
+ message: `External link not allowed: ${href}`,
10450
+ detail: href
10451
+ });
10452
+ }
10453
+ }
10454
+ }
10455
+ const lower = html.toLowerCase();
10456
+ const hasCredField = root.querySelector('input[type="email"], input[type="text"], input[type="tel"]') != null && /(password|passcode|otp|verify|sign\s*in|log\s*in|account)/i.test(html);
10457
+ if (hasCredField) {
10458
+ const brand = BRAND_NAMES.find((b) => lower.includes(b));
10459
+ if (brand) {
10460
+ warnings.push({
10461
+ code: "BRAND_CREDENTIAL",
10462
+ message: `Possible phishing: brand "${brand}" near a credential field.`,
10463
+ detail: brand
10464
+ });
10465
+ }
10466
+ }
10467
+ return { ok: errors.length === 0, errors, warnings };
10468
+ }
10469
+
10364
10470
  // src/bundle.ts
10365
10471
  var MIME = {
10366
10472
  ".css": "text/css",
@@ -10634,7 +10740,9 @@ var FIXES = {
10634
10740
  TOP_NAVIGATION: "Remove top-level navigation (window.top / parent.location). The artifact runs sandboxed and can't drive the page it's embedded in.",
10635
10741
  FORBIDDEN_API: "This browser API is blocked in the sandbox (e.g. getUserMedia, geolocation, serviceWorker, Notification, PaymentRequest, WebAuthn). Remove it or gate it behind a no-op fallback.",
10636
10742
  PASSWORD_INPUT: `Password inputs aren't allowed (anti-phishing). Remove <input type="password">.`,
10637
- EXTERNAL_URL: "References a host that isn't on the allowlist \u2014 often a call to your own backend/API or a third-party script. vibed artifacts are a single static file: inline the asset, drop the call, or move it to an allowlisted CDN (fonts.googleapis.com, cdn.jsdelivr.net, unpkg.com, cdnjs.cloudflare.com, fonts.gstatic.com)."
10743
+ EXTERNAL_URL: "References a host that isn't on the allowlist \u2014 often a call to your own backend/API or a third-party script. vibed artifacts are a single static file: inline the asset, drop the call, or move it to an allowlisted CDN (fonts.googleapis.com, cdn.jsdelivr.net, unpkg.com, cdnjs.cloudflare.com, fonts.gstatic.com).",
10744
+ EXTERNAL_SCRIPT: "Loads JavaScript from an external <script src>. Creator-selected packages aren't allowed \u2014 inline the code you need directly into the file.",
10745
+ EXTERNAL_LINK: "Links off the platform (<a href> to another site). Posts can't send viewers elsewhere \u2014 remove the link or make it in-page (e.g. an anchor to a section)."
10638
10746
  };
10639
10747
  var KB = 1024;
10640
10748
  function fmtSize(bytes) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amirhosseinnateghi/vibed-cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "make it vibed — check, bundle, and publish a project to vibed from the terminal",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -11,7 +11,10 @@
11
11
  ".": "./dist/index.js",
12
12
  "./lib": "./src/lib.ts"
13
13
  },
14
- "files": ["dist", "README.md"],
14
+ "files": [
15
+ "dist",
16
+ "README.md"
17
+ ],
15
18
  "publishConfig": {
16
19
  "access": "public"
17
20
  },