opencrush 0.3.15 → 0.3.17

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 +192 -132
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -35591,7 +35591,7 @@ function kt(e2, t2, r2, o2, n2, a2) {
35591
35591
  g2 = e3;
35592
35592
  }));
35593
35593
  let E2 = Promise.resolve(void 0);
35594
- return u(((P2, W2) => {
35594
+ return u(((P2, W3) => {
35595
35595
  let k2;
35596
35596
  function O2() {
35597
35597
  if (w2) return;
@@ -35642,7 +35642,7 @@ function kt(e2, t2, r2, o2, n2, a2) {
35642
35642
  z2(void 0, e3, t3);
35643
35643
  }
35644
35644
  function F2(e3, t3) {
35645
- return S2 = true, l2.releaseLock(), i2.releaseLock(), void 0 !== a2 && a2.removeEventListener("abort", k2), e3 ? W2(t3) : P2(void 0), null;
35645
+ return S2 = true, l2.releaseLock(), i2.releaseLock(), void 0 !== a2 && a2.removeEventListener("abort", k2), e3 ? W3(t3) : P2(void 0), null;
35646
35646
  }
35647
35647
  w2 || (b(i2.closed, B2, A2), b(l2.closed, (function() {
35648
35648
  return S2 || (R2 = "closed"), null;
@@ -41872,6 +41872,7 @@ var init_llm_direct = __esm({
41872
41872
  "src/llm-direct.ts"() {
41873
41873
  PROVIDER_META = {
41874
41874
  openai: { baseURL: "", defaultModel: "gpt-4o-mini" },
41875
+ xai: { baseURL: "https://api.x.ai/v1", defaultModel: "grok-4-1-fast-non-reasoning" },
41875
41876
  deepseek: { baseURL: "https://api.deepseek.com", defaultModel: "deepseek-chat" },
41876
41877
  qwen: { baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1", defaultModel: "qwen-max" },
41877
41878
  kimi: { baseURL: "https://api.moonshot.cn/v1", defaultModel: "moonshot-v1-8k" },
@@ -41992,6 +41993,18 @@ var init_llm_direct = __esm({
41992
41993
  requiresVPN: true,
41993
41994
  isLocal: false
41994
41995
  },
41996
+ {
41997
+ id: "xai",
41998
+ name: "xAI (Grok)",
41999
+ emoji: "\u26A1",
42000
+ tagline: "$25 free credit on signup, fast reasoning",
42001
+ taglineCN: "$25\u514D\u8D39\u989D\u5EA6\uFF0C\u63A8\u7406\u5FEB",
42002
+ keyUrl: "https://console.x.ai",
42003
+ keyUrlCN: "https://console.x.ai",
42004
+ envKey: "XAI_API_KEY",
42005
+ requiresVPN: true,
42006
+ isLocal: false
42007
+ },
41995
42008
  // ── Local ──
41996
42009
  {
41997
42010
  id: "ollama",
@@ -127539,6 +127552,7 @@ RULES:
127539
127552
  ];
127540
127553
  OPENAI_COMPAT_PROVIDERS = {
127541
127554
  openai: { baseURL: "", defaultModel: "gpt-4o-mini" },
127555
+ xai: { baseURL: "https://api.x.ai/v1", defaultModel: "grok-4-1-fast-non-reasoning" },
127542
127556
  deepseek: { baseURL: "https://api.deepseek.com", defaultModel: "deepseek-chat" },
127543
127557
  qwen: { baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1", defaultModel: "qwen-max" },
127544
127558
  kimi: { baseURL: "https://api.moonshot.cn/v1", defaultModel: "moonshot-v1-8k" },
@@ -127710,6 +127724,7 @@ RULES:
127710
127724
  resolveApiKey(config) {
127711
127725
  const map4 = {
127712
127726
  openai: config.openaiApiKey,
127727
+ xai: config.xaiApiKey,
127713
127728
  deepseek: config.deepseekApiKey,
127714
127729
  qwen: config.qwenApiKey,
127715
127730
  kimi: config.kimiApiKey,
@@ -140322,9 +140337,9 @@ var init_esm_GWSBNV3N = __esm({
140322
140337
  function Q2() {
140323
140338
  if (F2) return O2;
140324
140339
  F2 = 1;
140325
- const e2 = 2147483647, s2 = 36, c2 = 1, o2 = 26, t2 = 38, d2 = 700, z2 = 72, y2 = 128, g2 = "-", P2 = /^xn--/, V2 = /[^\0-\x7F]/, G2 = /[\x2E\u3002\uFF0E\uFF61]/g, W2 = { overflow: "Overflow: input needs wider integers to process", "not-basic": "Illegal input >= 0x80 (not a basic code point)", "invalid-input": "Invalid input" }, C2 = s2 - c2, h2 = Math.floor, I2 = String.fromCharCode;
140340
+ const e2 = 2147483647, s2 = 36, c2 = 1, o2 = 26, t2 = 38, d2 = 700, z2 = 72, y2 = 128, g2 = "-", P2 = /^xn--/, V2 = /[^\0-\x7F]/, G2 = /[\x2E\u3002\uFF0E\uFF61]/g, W3 = { overflow: "Overflow: input needs wider integers to process", "not-basic": "Illegal input >= 0x80 (not a basic code point)", "invalid-input": "Invalid input" }, C2 = s2 - c2, h2 = Math.floor, I2 = String.fromCharCode;
140326
140341
  function v2(a2) {
140327
- throw new RangeError(W2[a2]);
140342
+ throw new RangeError(W3[a2]);
140328
140343
  }
140329
140344
  function U2(a2, i2) {
140330
140345
  const m2 = [];
@@ -140433,7 +140448,7 @@ var init_esm_GWSBNV3N = __esm({
140433
140448
  }
140434
140449
  return null;
140435
140450
  };
140436
- var H2 = { DOMAIN_TOO_SHORT: "Domain name too short.", DOMAIN_TOO_LONG: "Domain name too long. It should be no more than 255 chars.", LABEL_STARTS_WITH_DASH: "Domain name label can not start with a dash.", LABEL_ENDS_WITH_DASH: "Domain name label can not end with a dash.", LABEL_TOO_LONG: "Domain name label should be at most 63 chars long.", LABEL_TOO_SHORT: "Domain name label should be at least 1 character long.", LABEL_INVALID_CHARS: "Domain name label can only contain alphanumeric characters or dashes." };
140451
+ var H3 = { DOMAIN_TOO_SHORT: "Domain name too short.", DOMAIN_TOO_LONG: "Domain name too long. It should be no more than 255 chars.", LABEL_STARTS_WITH_DASH: "Domain name label can not start with a dash.", LABEL_ENDS_WITH_DASH: "Domain name label can not end with a dash.", LABEL_TOO_LONG: "Domain name label should be at most 63 chars long.", LABEL_TOO_SHORT: "Domain name label should be at least 1 character long.", LABEL_INVALID_CHARS: "Domain name label can only contain alphanumeric characters or dashes." };
140437
140452
  var oa = (e2) => {
140438
140453
  const s2 = A2.toASCII(e2);
140439
140454
  if (s2.length < 1) return "DOMAIN_TOO_SHORT";
@@ -140453,7 +140468,7 @@ var init_esm_GWSBNV3N = __esm({
140453
140468
  let s2 = e2.slice(0).toLowerCase();
140454
140469
  s2.charAt(s2.length - 1) === "." && (s2 = s2.slice(0, s2.length - 1));
140455
140470
  const c2 = oa(s2);
140456
- if (c2) return { input: e2, error: { message: H2[c2], code: c2 } };
140471
+ if (c2) return { input: e2, error: { message: H3[c2], code: c2 } };
140457
140472
  const o2 = { input: e2, tld: null, sld: null, domain: null, subdomain: null, listed: false }, t2 = s2.split(".");
140458
140473
  if (t2[t2.length - 1] === "local") return o2;
140459
140474
  const d2 = () => (/xn--/.test(s2) && (o2.domain && (o2.domain = A2.toASCII(o2.domain)), o2.subdomain && (o2.subdomain = A2.toASCII(o2.subdomain))), o2), z2 = aa(s2);
@@ -140469,7 +140484,7 @@ var init_esm_GWSBNV3N = __esm({
140469
140484
  };
140470
140485
  var sa = { parse: _3, get: N2, isValid: R2 };
140471
140486
  exports2.default = sa;
140472
- exports2.errorCodes = H2;
140487
+ exports2.errorCodes = H3;
140473
140488
  exports2.get = N2;
140474
140489
  exports2.isValid = R2;
140475
140490
  exports2.parse = _3;
@@ -184171,7 +184186,7 @@ var require_dist4 = __commonJS({
184171
184186
  })(e3)) in t3 ? Object.defineProperty(t3, e3, { value: r22, enumerable: true, configurable: true, writable: true }) : t3[e3] = r22, t3;
184172
184187
  }
184173
184188
  __name(u2, "u");
184174
- var l2, f2, s2, y2 = r2(425), p2 = y2.AggregateError, g2 = y2.AggregateErrorPrototype, v2 = y2.Array, h2 = y2.ArrayBuffer, d2 = y2.ArrayBufferPrototype, b2 = y2.ArrayIsArray, m2 = y2.ArrayPrototype, S2 = y2.ArrayPrototypeFilter, P2 = y2.ArrayPrototypeForEach, x2 = y2.ArrayPrototypeIncludes, w2 = y2.ArrayPrototypeIndexOf, A2 = y2.ArrayPrototypeJoin, O2 = y2.ArrayPrototypeMap, _3 = y2.ArrayPrototypePop, j2 = y2.ArrayPrototypePush, E2 = y2.ArrayPrototypePushApply, k2 = y2.ArrayPrototypeSlice, I2 = y2.ArrayPrototypeSort, R2 = y2.ArrayPrototypeSplice, L2 = y2.ArrayPrototypeUnshift, T2 = y2.BigIntPrototypeValueOf, B2 = y2.Boolean, z2 = y2.BooleanPrototype, M2 = y2.BooleanPrototypeValueOf, C2 = y2.DataView, D2 = y2.DataViewPrototype, N2 = y2.Date, F2 = y2.DatePrototype, W2 = y2.DatePrototypeGetTime, H2 = y2.DatePrototypeToISOString, U2 = y2.DatePrototypeToString, G2 = y2.Error, V2 = y2.ErrorPrototype, Z2 = y2.ErrorPrototypeToString, $2 = y2.Function, Y2 = y2.FunctionPrototype, q2 = y2.FunctionPrototypeBind, J2 = y2.FunctionPrototypeCall, K2 = y2.FunctionPrototypeSymbolHasInstance, Q2 = y2.FunctionPrototypeToString, X2 = y2.JSONStringify, tt2 = y2.Map, et2 = y2.MapPrototype, rt2 = y2.MapPrototypeEntries, nt2 = y2.MapPrototypeGetSize, ot2 = y2.MathFloor, at2 = y2.MathMax, it2 = y2.MathMin, ct2 = y2.MathRound, ut2 = y2.MathSqrt, lt2 = y2.MathTrunc, ft2 = y2.Number, st2 = y2.NumberIsFinite, yt2 = y2.NumberIsNaN, pt2 = y2.NumberParseFloat, gt2 = y2.NumberParseInt, vt2 = y2.NumberPrototype, ht2 = y2.NumberPrototypeToString, dt2 = y2.NumberPrototypeValueOf, bt2 = y2.Object, mt2 = y2.ObjectAssign, St2 = y2.ObjectDefineProperty, Pt2 = y2.ObjectGetOwnPropertyDescriptor, xt2 = y2.ObjectGetOwnPropertyNames, wt2 = y2.ObjectGetOwnPropertySymbols, At2 = y2.ObjectGetPrototypeOf, Ot2 = y2.ObjectIs, _t2 = y2.ObjectKeys, jt2 = y2.ObjectPrototype, Et2 = y2.ObjectPrototypeHasOwnProperty, kt2 = y2.ObjectPrototypePropertyIsEnumerable, It2 = y2.ObjectSeal, Rt2 = y2.ObjectSetPrototypeOf, Lt2 = y2.Promise, Tt2 = y2.PromisePrototype, Bt2 = y2.RangeError, zt2 = y2.RangeErrorPrototype, Mt2 = y2.ReflectApply, Ct2 = y2.ReflectOwnKeys, Dt2 = y2.RegExp, Nt2 = y2.RegExpPrototype, Ft2 = y2.RegExpPrototypeExec, Wt2 = y2.RegExpPrototypeSymbolReplace, Ht2 = y2.RegExpPrototypeSymbolSplit, Ut2 = y2.RegExpPrototypeToString, Gt2 = y2.SafeMap, Vt2 = y2.SafeSet, Zt2 = y2.SafeStringIterator, $t2 = y2.Set, Yt2 = y2.SetPrototype, qt2 = y2.SetPrototypeGetSize, Jt2 = y2.SetPrototypeValues, Kt2 = y2.String, Qt2 = y2.StringPrototype, Xt2 = y2.StringPrototypeCharCodeAt, te2 = y2.StringPrototypeCodePointAt, ee2 = y2.StringPrototypeEndsWith, re2 = y2.StringPrototypeIncludes, ne2 = y2.StringPrototypeIndexOf, oe2 = y2.StringPrototypeLastIndexOf, ae2 = y2.StringPrototypeNormalize, ie2 = y2.StringPrototypePadEnd, ce2 = y2.StringPrototypePadStart, ue2 = y2.StringPrototypeRepeat, le2 = y2.StringPrototypeReplace, fe2 = y2.StringPrototypeReplaceAll, se2 = y2.StringPrototypeSlice, ye2 = y2.StringPrototypeSplit, pe2 = y2.StringPrototypeStartsWith, ge2 = y2.StringPrototypeToLowerCase, ve2 = y2.StringPrototypeTrim, he2 = y2.StringPrototypeValueOf, de2 = y2.SymbolIterator, be2 = y2.SymbolPrototypeToString, me2 = y2.SymbolPrototypeValueOf, Se2 = y2.SymbolToPrimitive, Pe2 = y2.SymbolToStringTag, xe2 = y2.TypeError, we2 = y2.TypeErrorPrototype, Ae2 = y2.TypedArray, Oe2 = y2.TypedArrayPrototype, _e2 = y2.TypedArrayPrototypeGetLength, je2 = y2.TypedArrayPrototypeGetSymbolToStringTag, Ee2 = y2.Uint8Array, ke2 = y2.WeakMap, Ie2 = y2.WeakMapPrototype, Re2 = y2.WeakSet, Le2 = y2.WeakSetPrototype, Te2 = y2.globalThis, Be2 = y2.internalBinding, ze2 = y2.uncurryThis, Me2 = r2(153), Ce2 = Me2.constants, De2 = Ce2.ALL_PROPERTIES, Ne2 = Ce2.ONLY_ENUMERABLE, Fe2 = Ce2.kPending, We2 = Ce2.kRejected, He2 = Me2.getOwnNonIndexProperties, Ue2 = Me2.getPromiseDetails, Ge2 = Me2.getProxyDetails, Ve2 = Me2.previewEntries, Ze2 = Me2.getConstructorName, $e2 = Me2.getExternalValue, Ye2 = Me2.Proxy, qe2 = r2(923), Je2 = qe2.customInspectSymbol, Ke2 = qe2.isError, Qe2 = qe2.join, Xe2 = qe2.removeColors, tr2 = r2(924).isStackOverflowError, er2 = r2(617), rr2 = er2.isAsyncFunction, nr2 = er2.isGeneratorFunction, or2 = er2.isAnyArrayBuffer, ar2 = er2.isArrayBuffer, ir2 = er2.isArgumentsObject, cr2 = er2.isBoxedPrimitive, ur2 = er2.isDataView, lr2 = er2.isExternal, fr2 = er2.isMap, sr2 = er2.isMapIterator, yr2 = er2.isModuleNamespaceObject, pr2 = er2.isNativeError, gr2 = er2.isPromise, vr2 = er2.isSet, hr2 = er2.isSetIterator, dr2 = er2.isWeakMap, br2 = er2.isWeakSet, mr2 = er2.isRegExp, Sr2 = er2.isDate, Pr = er2.isTypedArray, xr = er2.isStringObject, wr2 = er2.isNumberObject, Ar = er2.isBooleanObject, Or2 = er2.isBigIntObject, _r2 = r2(229), jr = r2(705).BuiltinModule, Er = r2(116), kr = Er.validateObject, Ir = Er.validateString, Rr2 = Er.kValidateObjectAllowArray;
184189
+ var l2, f2, s2, y2 = r2(425), p2 = y2.AggregateError, g2 = y2.AggregateErrorPrototype, v2 = y2.Array, h2 = y2.ArrayBuffer, d2 = y2.ArrayBufferPrototype, b2 = y2.ArrayIsArray, m2 = y2.ArrayPrototype, S2 = y2.ArrayPrototypeFilter, P2 = y2.ArrayPrototypeForEach, x2 = y2.ArrayPrototypeIncludes, w2 = y2.ArrayPrototypeIndexOf, A2 = y2.ArrayPrototypeJoin, O2 = y2.ArrayPrototypeMap, _3 = y2.ArrayPrototypePop, j2 = y2.ArrayPrototypePush, E2 = y2.ArrayPrototypePushApply, k2 = y2.ArrayPrototypeSlice, I2 = y2.ArrayPrototypeSort, R2 = y2.ArrayPrototypeSplice, L2 = y2.ArrayPrototypeUnshift, T2 = y2.BigIntPrototypeValueOf, B2 = y2.Boolean, z2 = y2.BooleanPrototype, M2 = y2.BooleanPrototypeValueOf, C2 = y2.DataView, D2 = y2.DataViewPrototype, N2 = y2.Date, F2 = y2.DatePrototype, W3 = y2.DatePrototypeGetTime, H3 = y2.DatePrototypeToISOString, U2 = y2.DatePrototypeToString, G2 = y2.Error, V2 = y2.ErrorPrototype, Z2 = y2.ErrorPrototypeToString, $2 = y2.Function, Y2 = y2.FunctionPrototype, q2 = y2.FunctionPrototypeBind, J2 = y2.FunctionPrototypeCall, K2 = y2.FunctionPrototypeSymbolHasInstance, Q2 = y2.FunctionPrototypeToString, X2 = y2.JSONStringify, tt2 = y2.Map, et2 = y2.MapPrototype, rt2 = y2.MapPrototypeEntries, nt2 = y2.MapPrototypeGetSize, ot2 = y2.MathFloor, at2 = y2.MathMax, it2 = y2.MathMin, ct2 = y2.MathRound, ut2 = y2.MathSqrt, lt2 = y2.MathTrunc, ft2 = y2.Number, st2 = y2.NumberIsFinite, yt2 = y2.NumberIsNaN, pt2 = y2.NumberParseFloat, gt2 = y2.NumberParseInt, vt2 = y2.NumberPrototype, ht2 = y2.NumberPrototypeToString, dt2 = y2.NumberPrototypeValueOf, bt2 = y2.Object, mt2 = y2.ObjectAssign, St2 = y2.ObjectDefineProperty, Pt2 = y2.ObjectGetOwnPropertyDescriptor, xt2 = y2.ObjectGetOwnPropertyNames, wt2 = y2.ObjectGetOwnPropertySymbols, At2 = y2.ObjectGetPrototypeOf, Ot2 = y2.ObjectIs, _t2 = y2.ObjectKeys, jt2 = y2.ObjectPrototype, Et2 = y2.ObjectPrototypeHasOwnProperty, kt2 = y2.ObjectPrototypePropertyIsEnumerable, It2 = y2.ObjectSeal, Rt2 = y2.ObjectSetPrototypeOf, Lt2 = y2.Promise, Tt2 = y2.PromisePrototype, Bt2 = y2.RangeError, zt2 = y2.RangeErrorPrototype, Mt2 = y2.ReflectApply, Ct2 = y2.ReflectOwnKeys, Dt2 = y2.RegExp, Nt2 = y2.RegExpPrototype, Ft2 = y2.RegExpPrototypeExec, Wt2 = y2.RegExpPrototypeSymbolReplace, Ht2 = y2.RegExpPrototypeSymbolSplit, Ut2 = y2.RegExpPrototypeToString, Gt2 = y2.SafeMap, Vt2 = y2.SafeSet, Zt2 = y2.SafeStringIterator, $t2 = y2.Set, Yt2 = y2.SetPrototype, qt2 = y2.SetPrototypeGetSize, Jt2 = y2.SetPrototypeValues, Kt2 = y2.String, Qt2 = y2.StringPrototype, Xt2 = y2.StringPrototypeCharCodeAt, te2 = y2.StringPrototypeCodePointAt, ee2 = y2.StringPrototypeEndsWith, re2 = y2.StringPrototypeIncludes, ne2 = y2.StringPrototypeIndexOf, oe2 = y2.StringPrototypeLastIndexOf, ae2 = y2.StringPrototypeNormalize, ie2 = y2.StringPrototypePadEnd, ce2 = y2.StringPrototypePadStart, ue2 = y2.StringPrototypeRepeat, le2 = y2.StringPrototypeReplace, fe2 = y2.StringPrototypeReplaceAll, se2 = y2.StringPrototypeSlice, ye2 = y2.StringPrototypeSplit, pe2 = y2.StringPrototypeStartsWith, ge2 = y2.StringPrototypeToLowerCase, ve2 = y2.StringPrototypeTrim, he2 = y2.StringPrototypeValueOf, de2 = y2.SymbolIterator, be2 = y2.SymbolPrototypeToString, me2 = y2.SymbolPrototypeValueOf, Se2 = y2.SymbolToPrimitive, Pe2 = y2.SymbolToStringTag, xe2 = y2.TypeError, we2 = y2.TypeErrorPrototype, Ae2 = y2.TypedArray, Oe2 = y2.TypedArrayPrototype, _e2 = y2.TypedArrayPrototypeGetLength, je2 = y2.TypedArrayPrototypeGetSymbolToStringTag, Ee2 = y2.Uint8Array, ke2 = y2.WeakMap, Ie2 = y2.WeakMapPrototype, Re2 = y2.WeakSet, Le2 = y2.WeakSetPrototype, Te2 = y2.globalThis, Be2 = y2.internalBinding, ze2 = y2.uncurryThis, Me2 = r2(153), Ce2 = Me2.constants, De2 = Ce2.ALL_PROPERTIES, Ne2 = Ce2.ONLY_ENUMERABLE, Fe2 = Ce2.kPending, We2 = Ce2.kRejected, He2 = Me2.getOwnNonIndexProperties, Ue2 = Me2.getPromiseDetails, Ge2 = Me2.getProxyDetails, Ve2 = Me2.previewEntries, Ze2 = Me2.getConstructorName, $e2 = Me2.getExternalValue, Ye2 = Me2.Proxy, qe2 = r2(923), Je2 = qe2.customInspectSymbol, Ke2 = qe2.isError, Qe2 = qe2.join, Xe2 = qe2.removeColors, tr2 = r2(924).isStackOverflowError, er2 = r2(617), rr2 = er2.isAsyncFunction, nr2 = er2.isGeneratorFunction, or2 = er2.isAnyArrayBuffer, ar2 = er2.isArrayBuffer, ir2 = er2.isArgumentsObject, cr2 = er2.isBoxedPrimitive, ur2 = er2.isDataView, lr2 = er2.isExternal, fr2 = er2.isMap, sr2 = er2.isMapIterator, yr2 = er2.isModuleNamespaceObject, pr2 = er2.isNativeError, gr2 = er2.isPromise, vr2 = er2.isSet, hr2 = er2.isSetIterator, dr2 = er2.isWeakMap, br2 = er2.isWeakSet, mr2 = er2.isRegExp, Sr2 = er2.isDate, Pr = er2.isTypedArray, xr = er2.isStringObject, wr2 = er2.isNumberObject, Ar = er2.isBooleanObject, Or2 = er2.isBigIntObject, _r2 = r2(229), jr = r2(705).BuiltinModule, Er = r2(116), kr = Er.validateObject, Ir = Er.validateString, Rr2 = Er.kValidateObjectAllowArray;
184175
184190
  function Lr(t3) {
184176
184191
  return (f2 = f2 || r2(802)).pathToFileURL(t3).href;
184177
184192
  }
@@ -184460,7 +184475,7 @@ var require_dist4 = __commonJS({
184460
184475
  var V22 = sn(u3, l3, "RegExp");
184461
184476
  if ("RegExp " !== V22 && (v33 = "".concat(V22).concat(v33)), 0 === i3.length && void 0 === c22 || n22 > t4.depth && null !== t4.depth) return t4.stylize(v33, "regexp");
184462
184477
  } else if (Sr2(e4)) {
184463
- v33 = yt2(W2(e4)) ? U2(e4) : H2(e4);
184478
+ v33 = yt2(W3(e4)) ? U2(e4) : H3(e4);
184464
184479
  var Z22 = sn(u3, l3, "Date");
184465
184480
  if ("Date " !== Z22 && (v33 = "".concat(Z22).concat(v33)), 0 === i3.length && void 0 === c22) return t4.stylize(v33, "date");
184466
184481
  } else if (Ke2(e4)) {
@@ -185697,7 +185712,7 @@ var require_dist4 = __commonJS({
185697
185712
  var e3 = t3.name, r22 = t3.original;
185698
185713
  P2[e3] = r22, z2(r22, P2, e3), z2(r22.prototype, P2, "".concat(e3, "Prototype"));
185699
185714
  }), P2.IteratorPrototype = Reflect.getPrototypeOf(P2.ArrayIteratorPrototype);
185700
- var M2 = P2.ArrayPrototypeForEach, C2 = P2.FinalizationRegistry, D2 = P2.FunctionPrototypeCall, N2 = P2.Map, F2 = P2.ObjectFreeze, W2 = P2.ObjectSetPrototypeOf, H2 = P2.RegExp, U2 = P2.Set, G2 = P2.SymbolIterator, V2 = P2.WeakMap, Z2 = P2.WeakRef, $2 = P2.WeakSet, Y2 = /* @__PURE__ */ __name(function(t3, e3) {
185715
+ var M2 = P2.ArrayPrototypeForEach, C2 = P2.FinalizationRegistry, D2 = P2.FunctionPrototypeCall, N2 = P2.Map, F2 = P2.ObjectFreeze, W3 = P2.ObjectSetPrototypeOf, H3 = P2.RegExp, U2 = P2.Set, G2 = P2.SymbolIterator, V2 = P2.WeakMap, Z2 = P2.WeakRef, $2 = P2.WeakSet, Y2 = /* @__PURE__ */ __name(function(t3, e3) {
185701
185716
  var r22 = (function() {
185702
185717
  return f2(/* @__PURE__ */ __name(function e4(r3) {
185703
185718
  u2(this, e4), this._iterator = t3(r3);
@@ -185707,7 +185722,7 @@ var require_dist4 = __commonJS({
185707
185722
  return this;
185708
185723
  }, "value") }]);
185709
185724
  })();
185710
- return W2(r22.prototype, null), F2(r22.prototype), F2(r22), r22;
185725
+ return W3(r22.prototype, null), F2(r22.prototype), F2(r22), r22;
185711
185726
  }, "Y");
185712
185727
  P2.SafeArrayIterator = Y2(P2.ArrayPrototypeSymbolIterator, P2.ArrayIteratorPrototypeNext), P2.SafeStringIterator = Y2(P2.StringPrototypeSymbolIterator, P2.StringIteratorPrototypeNext);
185713
185728
  var q2 = /* @__PURE__ */ __name(function(t3, e3) {
@@ -185732,7 +185747,7 @@ var require_dist4 = __commonJS({
185732
185747
  }
185733
185748
  });
185734
185749
  } else q2(t3.prototype, e3.prototype);
185735
- return q2(t3, e3), W2(e3.prototype, null), F2(e3.prototype), F2(e3), e3;
185750
+ return q2(t3, e3), W3(e3.prototype, null), F2(e3.prototype), F2(e3), e3;
185736
185751
  }, "J");
185737
185752
  P2.makeSafe = J2, P2.SafeMap = J2(N2, (function(t3) {
185738
185753
  function e3(t4) {
@@ -185778,8 +185793,8 @@ var require_dist4 = __commonJS({
185778
185793
  if ("config" === t3) return { hasIntl: false };
185779
185794
  throw new Error('unknown module: "'.concat(t3, '"'));
185780
185795
  }, P2._stringPrototypeReplaceAll = function(t3, e3, r22) {
185781
- return "[object regexp]" === Object.prototype.toString.call(e3).toLowerCase() ? t3.replace(e3, r22) : t3.replace(new H2(e3, "g"), r22);
185782
- }, P2.StringPrototypeReplaceAll = P2.StringPrototypeReplaceAll || P2._stringPrototypeReplaceAll, W2(P2, null), F2(P2), t22.exports = P2;
185796
+ return "[object regexp]" === Object.prototype.toString.call(e3).toLowerCase() ? t3.replace(e3, r22) : t3.replace(new H3(e3, "g"), r22);
185797
+ }, P2.StringPrototypeReplaceAll = P2.StringPrototypeReplaceAll || P2._stringPrototypeReplaceAll, W3(P2, null), F2(P2), t22.exports = P2;
185783
185798
  }, 569: (t22, e22, r2) => {
185784
185799
  function n2(t3) {
185785
185800
  return n2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(t4) {
@@ -186055,7 +186070,7 @@ var require_dist4 = __commonJS({
186055
186070
  }, l2(t3, e3);
186056
186071
  }
186057
186072
  __name(l2, "l");
186058
- var f2, s2, y2 = r2(425), p2 = y2.ArrayIsArray, g2 = y2.ArrayPrototypeIncludes, v2 = y2.ArrayPrototypeIndexOf, h2 = y2.ArrayPrototypeJoin, d2 = y2.ArrayPrototypePush, b2 = y2.ArrayPrototypeSlice, m2 = y2.ArrayPrototypeSplice, S2 = y2.Error, P2 = y2.ErrorCaptureStackTrace, x2 = y2.JSONStringify, w2 = y2.ObjectDefineProperty, A2 = y2.ReflectApply, O2 = y2.RegExpPrototypeExec, _3 = y2.SafeMap, j2 = y2.SafeWeakMap, E2 = y2.String, k2 = y2.StringPrototypeEndsWith, I2 = y2.StringPrototypeIncludes, R2 = y2.StringPrototypeIndexOf, L2 = y2.StringPrototypeSlice, T2 = y2.StringPrototypeToLowerCase, B2 = y2.Symbol, z2 = y2.TypeError, M2 = B2("kIsNodeError"), C2 = new _3(), D2 = {}, N2 = /^[A-Z][a-zA-Z0-9]*$/, F2 = ["string", "function", "number", "object", "Function", "Object", "boolean", "bigint", "symbol"], W2 = new j2(), H2 = r2(229), U2 = null;
186073
+ var f2, s2, y2 = r2(425), p2 = y2.ArrayIsArray, g2 = y2.ArrayPrototypeIncludes, v2 = y2.ArrayPrototypeIndexOf, h2 = y2.ArrayPrototypeJoin, d2 = y2.ArrayPrototypePush, b2 = y2.ArrayPrototypeSlice, m2 = y2.ArrayPrototypeSplice, S2 = y2.Error, P2 = y2.ErrorCaptureStackTrace, x2 = y2.JSONStringify, w2 = y2.ObjectDefineProperty, A2 = y2.ReflectApply, O2 = y2.RegExpPrototypeExec, _3 = y2.SafeMap, j2 = y2.SafeWeakMap, E2 = y2.String, k2 = y2.StringPrototypeEndsWith, I2 = y2.StringPrototypeIncludes, R2 = y2.StringPrototypeIndexOf, L2 = y2.StringPrototypeSlice, T2 = y2.StringPrototypeToLowerCase, B2 = y2.Symbol, z2 = y2.TypeError, M2 = B2("kIsNodeError"), C2 = new _3(), D2 = {}, N2 = /^[A-Z][a-zA-Z0-9]*$/, F2 = ["string", "function", "number", "object", "Function", "Object", "boolean", "bigint", "symbol"], W3 = new j2(), H3 = r2(229), U2 = null;
186059
186074
  function G2(t3, e3) {
186060
186075
  var r22 = (function(t4) {
186061
186076
  function r3() {
@@ -186095,7 +186110,7 @@ var require_dist4 = __commonJS({
186095
186110
  __name(V2, "V");
186096
186111
  function Z2(t3, e3, r22) {
186097
186112
  var n22 = C2.get(t3);
186098
- if ("function" == typeof n22) return H2(n22.length <= e3.length, "Code: ".concat(t3, "; The provided arguments length (").concat(e3.length, ") does not ") + "match the required ones (".concat(n22.length, ").")), A2(n22, r22, e3);
186113
+ if ("function" == typeof n22) return H3(n22.length <= e3.length, "Code: ".concat(t3, "; The provided arguments length (").concat(e3.length, ") does not ") + "match the required ones (".concat(n22.length, ").")), A2(n22, r22, e3);
186099
186114
  }
186100
186115
  __name(Z2, "Z");
186101
186116
  var $2 = B2("kEnhanceStackBeforeInspector");
@@ -186157,11 +186172,11 @@ var require_dist4 = __commonJS({
186157
186172
  s2 = t4.message, f2 = t4.name;
186158
186173
  }
186159
186174
  return t3 && t3.name === f2 && t3.message === s2;
186160
- }, "isStackOverflowError"), kEnhanceStackBeforeInspector: $2, kIsNodeError: M2, overrideStackTrace: W2 }, V2("ERR_INTERNAL_ASSERTION", function(t3) {
186175
+ }, "isStackOverflowError"), kEnhanceStackBeforeInspector: $2, kIsNodeError: M2, overrideStackTrace: W3 }, V2("ERR_INTERNAL_ASSERTION", function(t3) {
186161
186176
  var e3 = "This is caused by either a bug in Node.js or incorrect usage of Node.js internals.\nPlease open an issue with this stack trace at https://github.com/nodejs/node/issues\n";
186162
186177
  return void 0 === t3 ? e3 : "".concat(t3, "\n").concat(e3);
186163
186178
  }, S2), V2("ERR_INVALID_ARG_TYPE", function(t3, e3, r22) {
186164
- H2("string" == typeof t3, "'name' must be a string"), p2(e3) || (e3 = [e3]);
186179
+ H3("string" == typeof t3, "'name' must be a string"), p2(e3) || (e3 = [e3]);
186165
186180
  var o22 = "The ";
186166
186181
  if (k2(t3, " argument")) o22 += "".concat(t3, " ");
186167
186182
  else {
@@ -186209,7 +186224,7 @@ var require_dist4 = __commonJS({
186209
186224
  try {
186210
186225
  for (f22.s(); !(i22 = f22.n()).done; ) {
186211
186226
  var s22 = i22.value;
186212
- H2("string" == typeof s22, "All expected entries have to be of type string"), g2(F2, s22) ? d2(c22, T2(s22)) : null !== O2(N2, s22) ? d2(u22, s22) : (H2("object" !== s22, 'The value "object" should be written as "Object"'), d2(l22, s22));
186227
+ H3("string" == typeof s22, "All expected entries have to be of type string"), g2(F2, s22) ? d2(c22, T2(s22)) : null !== O2(N2, s22) ? d2(u22, s22) : (H3("object" !== s22, 'The value "object" should be written as "Object"'), d2(l22, s22));
186213
186228
  }
186214
186229
  } catch (t4) {
186215
186230
  f22.e(t4);
@@ -199704,10 +199719,10 @@ var require_cjs7 = __commonJS({
199704
199719
  return "[object Set]" === m22(e3);
199705
199720
  }
199706
199721
  __name(N2, "N");
199707
- function W2(e3) {
199722
+ function W3(e3) {
199708
199723
  return "[object WeakMap]" === m22(e3);
199709
199724
  }
199710
- __name(W2, "W");
199725
+ __name(W3, "W");
199711
199726
  function $2(e3) {
199712
199727
  return "[object WeakSet]" === m22(e3);
199713
199728
  }
@@ -199736,10 +199751,10 @@ var require_cjs7 = __commonJS({
199736
199751
  return "undefined" != typeof SharedArrayBuffer && (J2.working ? J2(e3) : e3 instanceof SharedArrayBuffer);
199737
199752
  }
199738
199753
  __name(_3, "_");
199739
- function H2(e3) {
199754
+ function H3(e3) {
199740
199755
  return O2(e3, h22);
199741
199756
  }
199742
- __name(H2, "H");
199757
+ __name(H3, "H");
199743
199758
  function Z2(e3) {
199744
199759
  return O2(e3, j2);
199745
199760
  }
@@ -199764,8 +199779,8 @@ var require_cjs7 = __commonJS({
199764
199779
  return "undefined" != typeof Map && (T22.working ? T22(e3) : e3 instanceof Map);
199765
199780
  }, N2.working = "undefined" != typeof Set && N2(/* @__PURE__ */ new Set()), o$2.isSet = function(e3) {
199766
199781
  return "undefined" != typeof Set && (N2.working ? N2(e3) : e3 instanceof Set);
199767
- }, W2.working = "undefined" != typeof WeakMap && W2(/* @__PURE__ */ new WeakMap()), o$2.isWeakMap = function(e3) {
199768
- return "undefined" != typeof WeakMap && (W2.working ? W2(e3) : e3 instanceof WeakMap);
199782
+ }, W3.working = "undefined" != typeof WeakMap && W3(/* @__PURE__ */ new WeakMap()), o$2.isWeakMap = function(e3) {
199783
+ return "undefined" != typeof WeakMap && (W3.working ? W3(e3) : e3 instanceof WeakMap);
199769
199784
  }, $2.working = "undefined" != typeof WeakSet && $2(/* @__PURE__ */ new WeakSet()), o$2.isWeakSet = function(e3) {
199770
199785
  return $2(e3);
199771
199786
  }, C2.working = "undefined" != typeof ArrayBuffer && C2(new ArrayBuffer()), o$2.isArrayBuffer = V2, G2.working = "undefined" != typeof ArrayBuffer && "undefined" != typeof DataView && G2(new DataView(new ArrayBuffer(1), 0, 1)), o$2.isDataView = R2, J2.working = "undefined" != typeof SharedArrayBuffer && J2(new SharedArrayBuffer()), o$2.isSharedArrayBuffer = _3, o$2.isAsyncFunction = function(e3) {
@@ -199778,8 +199793,8 @@ var require_cjs7 = __commonJS({
199778
199793
  return "[object Generator]" === m22(e3);
199779
199794
  }, o$2.isWebAssemblyCompiledModule = function(e3) {
199780
199795
  return "[object WebAssembly.Module]" === m22(e3);
199781
- }, o$2.isNumberObject = H2, o$2.isStringObject = Z2, o$2.isBooleanObject = q2, o$2.isBigIntObject = K2, o$2.isSymbolObject = L2, o$2.isBoxedPrimitive = function(e3) {
199782
- return H2(e3) || Z2(e3) || q2(e3) || K2(e3) || L2(e3);
199796
+ }, o$2.isNumberObject = H3, o$2.isStringObject = Z2, o$2.isBooleanObject = q2, o$2.isBigIntObject = K2, o$2.isSymbolObject = L2, o$2.isBoxedPrimitive = function(e3) {
199797
+ return H3(e3) || Z2(e3) || q2(e3) || K2(e3) || L2(e3);
199783
199798
  }, o$2.isAnyArrayBuffer = function(e3) {
199784
199799
  return l$1 && (V2(e3) || _3(e3));
199785
199800
  }, ["isProxy", "isExternal", "isModuleNamespaceObject"].forEach(function(e3) {
@@ -244763,6 +244778,7 @@ async function startOpencrush() {
244763
244778
  // International
244764
244779
  anthropicApiKey: config.ANTHROPIC_API_KEY,
244765
244780
  openaiApiKey: config.OPENAI_API_KEY,
244781
+ xaiApiKey: config.XAI_API_KEY,
244766
244782
  // Chinese providers
244767
244783
  deepseekApiKey: config.DEEPSEEK_API_KEY,
244768
244784
  qwenApiKey: config.DASHSCOPE_API_KEY,
@@ -244948,6 +244964,7 @@ function loadConfig() {
244948
244964
  // International
244949
244965
  ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY,
244950
244966
  OPENAI_API_KEY: process.env.OPENAI_API_KEY,
244967
+ XAI_API_KEY: process.env.XAI_API_KEY,
244951
244968
  // Chinese providers
244952
244969
  DEEPSEEK_API_KEY: process.env.DEEPSEEK_API_KEY,
244953
244970
  DASHSCOPE_API_KEY: process.env.DASHSCOPE_API_KEY,
@@ -245012,11 +245029,11 @@ function validateConfig(config) {
245012
245029
  console.log(source_default.gray(' Run "npx opencrush@latest setup" to configure, or edit .env directly'));
245013
245030
  process.exit(1);
245014
245031
  }
245015
- const hasLLM = config.ANTHROPIC_API_KEY || config.OPENAI_API_KEY || config.DEEPSEEK_API_KEY || config.DASHSCOPE_API_KEY || config.MOONSHOT_API_KEY || config.ZHIPU_API_KEY || config.MINIMAX_API_KEY || config.LLM_PROVIDER === "ollama";
245032
+ const hasLLM = config.ANTHROPIC_API_KEY || config.OPENAI_API_KEY || config.XAI_API_KEY || config.DEEPSEEK_API_KEY || config.DASHSCOPE_API_KEY || config.MOONSHOT_API_KEY || config.ZHIPU_API_KEY || config.MINIMAX_API_KEY || config.LLM_PROVIDER === "ollama";
245016
245033
  if (!hasLLM) {
245017
245034
  console.log(source_default.red("\n \u274C No LLM API key configured"));
245018
245035
  console.log(source_default.gray(" Add one of these to .env:"));
245019
- console.log(source_default.gray(" ANTHROPIC_API_KEY / OPENAI_API_KEY / DEEPSEEK_API_KEY"));
245036
+ console.log(source_default.gray(" ANTHROPIC_API_KEY / OPENAI_API_KEY / XAI_API_KEY / DEEPSEEK_API_KEY"));
245020
245037
  console.log(source_default.gray(" DASHSCOPE_API_KEY / MOONSHOT_API_KEY / ZHIPU_API_KEY / MINIMAX_API_KEY"));
245021
245038
  console.log(source_default.gray(" Or set LLM_PROVIDER=ollama for local inference"));
245022
245039
  process.exit(1);
@@ -245115,7 +245132,7 @@ function maybeOpenCard(name) {
245115
245132
  }
245116
245133
  function generateEnvFile(values) {
245117
245134
  const sections = {
245118
- "# \u2500\u2500 AI Provider \u2500\u2500": ["LLM_PROVIDER", "LLM_MODEL", "ANTHROPIC_API_KEY", "OPENAI_API_KEY", "DEEPSEEK_API_KEY", "DASHSCOPE_API_KEY", "MOONSHOT_API_KEY", "ZHIPU_API_KEY", "MINIMAX_API_KEY", "OLLAMA_BASE_URL", "OLLAMA_MODEL", "JINA_API_KEY"],
245135
+ "# \u2500\u2500 AI Provider \u2500\u2500": ["LLM_PROVIDER", "LLM_MODEL", "ANTHROPIC_API_KEY", "OPENAI_API_KEY", "XAI_API_KEY", "DEEPSEEK_API_KEY", "DASHSCOPE_API_KEY", "MOONSHOT_API_KEY", "ZHIPU_API_KEY", "MINIMAX_API_KEY", "OLLAMA_BASE_URL", "OLLAMA_MODEL", "JINA_API_KEY"],
245119
245136
  "# \u2500\u2500 Character \u2500\u2500": ["CHARACTER_NAME"],
245120
245137
  "# \u2500\u2500 Messaging Platforms \u2500\u2500": ["DISCORD_BOT_TOKEN", "DISCORD_OWNER_ID", "DISCORD_CLIENT_ID", "TELEGRAM_BOT_TOKEN", "TELEGRAM_OWNER_ID", "WHATSAPP_ENABLED"],
245121
245138
  "# \u2500\u2500 Media (Selfies, Voice, Video) \u2500\u2500": ["FAL_KEY", "IMAGE_MODEL", "IMAGE_REFERENCE_MODEL", "TTS_PROVIDER", "ELEVENLABS_API_KEY", "ELEVENLABS_VOICE_ID", "FISH_AUDIO_API_KEY", "FISH_AUDIO_VOICE_ID"],
@@ -245185,6 +245202,7 @@ async function runSetupWizard() {
245185
245202
  const providerChoices = [
245186
245203
  PROVIDER_INFO.find((p2) => p2.id === "anthropic"),
245187
245204
  PROVIDER_INFO.find((p2) => p2.id === "openai"),
245205
+ PROVIDER_INFO.find((p2) => p2.id === "xai"),
245188
245206
  PROVIDER_INFO.find((p2) => p2.id === "deepseek"),
245189
245207
  PROVIDER_INFO.find((p2) => p2.id === "qwen"),
245190
245208
  PROVIDER_INFO.find((p2) => p2.id === "kimi"),
@@ -245217,6 +245235,8 @@ async function runSetupWizard() {
245217
245235
  console.log(source_default.gray(' Sign up \u2192 API Keys \u2192 Create Key \u2192 copy the key (starts with "sk-ant-")\n'));
245218
245236
  } else if (llmProvider === "openai") {
245219
245237
  console.log(source_default.gray(" Sign up \u2192 API Keys \u2192 Create new secret key\n"));
245238
+ } else if (llmProvider === "xai") {
245239
+ console.log(source_default.gray(" Sign up \u2192 get $25 free credit \u2192 copy API key\n"));
245220
245240
  } else if (llmProvider === "deepseek") {
245221
245241
  console.log(source_default.gray(" Sign up \u2192 API Keys \u2192 Create key (new users get free credits)\n"));
245222
245242
  }
@@ -245550,7 +245570,7 @@ async function runSetupWizard() {
245550
245570
  `) + source_default.cyan(" npx opencrush@latest start\n\n") + source_default.white(`Edit ${pro.their} personality:
245551
245571
  `) + source_default.cyan(` characters/${characterName}/SOUL.md
245552
245572
 
245553
- `) + (setupMode === "quick" ? source_default.gray("Unlock voice/browser/Twitter: run setup again \u2192 Full setup\n\n") : "") + source_default.gray("https://github.com/Hollandchirs/Opencrush"),
245573
+ `) + (setupMode === "quick" ? source_default.gray("Unlock voice/browser/Twitter: run setup again \u2192 Full setup\n\n") : "") + source_default.gray("https://github.com/heloraai/Opencrush"),
245554
245574
  { padding: 1, margin: 1, borderStyle: "round", borderColor: "magenta" }
245555
245575
  ));
245556
245576
  const { startNow } = await esm_default12.prompt([{
@@ -245597,112 +245617,125 @@ function parseIdentity(identityPath) {
245597
245617
  const nameMatch = content.match(/^#\s+(.+)$/m);
245598
245618
  const name = ((_a3 = nameMatch == null ? void 0 : nameMatch[1]) == null ? void 0 : _a3.trim()) ?? "Unknown";
245599
245619
  const ageMatch = content.match(/\*\*Age:\*\*\s*(\d+)/i);
245600
- const age = (ageMatch == null ? void 0 : ageMatch[1]) ?? "??";
245620
+ const age = (ageMatch == null ? void 0 : ageMatch[1]) ?? "";
245601
245621
  const fromMatch = content.match(/\*\*From:\*\*\s*(.+)/i);
245602
- const locationRaw = ((_b2 = fromMatch == null ? void 0 : fromMatch[1]) == null ? void 0 : _b2.trim()) ?? "Unknown";
245603
- const location = locationRaw.replace(/\s*\(.*\)/, "").split(" \u2014 ")[0].trim();
245622
+ const locationRaw = ((_b2 = fromMatch == null ? void 0 : fromMatch[1]) == null ? void 0 : _b2.trim()) ?? "";
245623
+ const location = locationRaw.replace(/\s*\(.*\)/, "").split(" \u2014 ")[0].split(" - ")[0].trim();
245624
+ const cleanLocation = location.length > 40 || location.toLowerCase().startsWith("says ") ? "" : location;
245625
+ const jobMatch = content.match(/\*\*Job:\*\*\s*(.+)/i);
245626
+ const jobRaw = ((_c = jobMatch == null ? void 0 : jobMatch[1]) == null ? void 0 : _c.trim()) ?? "";
245627
+ const job = jobRaw.split(/[—–\.\+]/).map((s2) => s2.trim()).filter(Boolean)[0] ?? "";
245604
245628
  const hobbiesMatch = content.match(/\*\*Hobbies:\*\*\s*(.+)/i);
245605
245629
  const hobbiesRaw = (hobbiesMatch == null ? void 0 : hobbiesMatch[1]) ?? "";
245606
- const tags = hobbiesRaw.split(",").map((t2) => t2.trim()).filter(Boolean).slice(0, 5);
245607
- const bgMatch = content.match(/## (?:Background|Appearance)\s*\n+(.+)/i);
245608
- const description = ((_d = (_c = bgMatch == null ? void 0 : bgMatch[1]) == null ? void 0 : _c.trim().split(".")[0]) == null ? void 0 : _d.trim()) ?? name;
245609
- const { data: meta } = (0, import_gray_matter3.default)(raw);
245610
- const gender = meta.gender ?? "female";
245611
- return { name, age, location, tags, description, gender };
245612
- }
245613
- function pickGradient(name) {
245614
- const gradients = [
245615
- { from: "#1a1a2e", to: "#16213e" },
245616
- // deep navy
245617
- { from: "#2d1b3d", to: "#1a1a2e" },
245618
- // purple-dark
245619
- { from: "#1b2d2d", to: "#0f1f1f" },
245620
- // teal-dark
245621
- { from: "#2d1b1b", to: "#1a1a1a" },
245622
- // warm dark
245623
- { from: "#1b2d1b", to: "#0f1f0f" },
245624
- // forest dark
245625
- { from: "#2d2d1b", to: "#1f1f0f" }
245626
- // amber dark
245627
- ];
245628
- const hash = name.split("").reduce((acc, ch) => acc + ch.charCodeAt(0), 0);
245629
- return gradients[hash % gradients.length];
245630
- }
245631
- function createSvgOverlay(data, gradient) {
245632
- const textX = PORTRAIT_X + PORTRAIT_SIZE + 50;
245633
- const maxTagX = WIDTH - 30;
245634
- const nameY = 210;
245635
- const metaY = nameY + 45;
245636
- const tagStartY = metaY + 50;
245630
+ const tags = splitRespectingParens(hobbiesRaw).map((t2) => t2.trim()).filter(Boolean).map((t2) => t2.length > 30 ? t2.split(/[,(]/)[0].trim() : t2).filter((t2) => t2.length > 1).slice(0, 5);
245631
+ let vibe = "";
245632
+ const soulPath = identityPath.replace("IDENTITY.md", "SOUL.md");
245633
+ if ((0, import_fs18.existsSync)(soulPath)) {
245634
+ const soul = (0, import_fs18.readFileSync)(soulPath, "utf-8");
245635
+ const line = soul.split("\n").find((l2) => l2.trim() && !l2.startsWith("#") && !l2.startsWith("-"));
245636
+ if (line) vibe = ((_d = line.trim().split(".")[0]) == null ? void 0 : _d.trim()) ?? "";
245637
+ }
245638
+ return { name, age, location: cleanLocation, job, tags, vibe };
245639
+ }
245640
+ function splitRespectingParens(str2) {
245641
+ const result = [];
245642
+ let depth = 0, current = "";
245643
+ for (const ch of str2) {
245644
+ if (ch === "(") depth++;
245645
+ else if (ch === ")") depth--;
245646
+ if (ch === "," && depth === 0) {
245647
+ result.push(current);
245648
+ current = "";
245649
+ } else current += ch;
245650
+ }
245651
+ if (current) result.push(current);
245652
+ return result;
245653
+ }
245654
+ function escapeXml(str2) {
245655
+ return str2.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
245656
+ }
245657
+ function buildTextOverlay(data) {
245658
+ const S2 = SCALE;
245659
+ const textX = 56 * S2;
245660
+ const panelW = 520 * S2;
245661
+ const availW = panelW - textX - 30 * S2;
245662
+ let y2 = 80 * S2;
245663
+ const nameY = y2;
245664
+ y2 += 50 * S2;
245665
+ const meta = [data.age, data.location].filter(Boolean).join(" \xB7 ");
245666
+ const metaY = y2;
245667
+ if (meta) y2 += 32 * S2;
245668
+ const jobY = y2;
245669
+ if (data.job) y2 += 30 * S2;
245670
+ y2 += 12 * S2;
245671
+ const tagStartY = y2;
245637
245672
  let inlineTags = "";
245638
245673
  let offsetX = textX;
245639
245674
  let rowY = tagStartY;
245640
- const rowHeight = 30;
245641
- const maxRows = 2;
245675
+ const rowH = 28 * S2;
245642
245676
  let currentRow = 1;
245677
+ const maxRows = 2;
245678
+ const charW = 6.2 * S2;
245679
+ const padW = 16 * S2;
245643
245680
  for (const tag of data.tags) {
245644
- const label = tag.length > 18 ? tag.slice(0, 17) + "\u2026" : tag;
245645
- const w2 = label.length * 7.5 + 16;
245646
- if (offsetX + w2 > maxTagX) {
245681
+ const maxChars = Math.floor((availW - padW) / charW);
245682
+ const label = tag.length > maxChars ? tag.slice(0, maxChars - 1) + "\u2026" : tag;
245683
+ const w2 = Math.ceil(label.length * charW + padW);
245684
+ if (offsetX + w2 > textX + availW) {
245647
245685
  if (currentRow >= maxRows) break;
245648
245686
  currentRow++;
245649
245687
  offsetX = textX;
245650
- rowY += rowHeight;
245688
+ rowY += rowH;
245651
245689
  }
245652
245690
  inlineTags += `
245653
- <rect x="${offsetX}" y="${rowY - 14}" width="${w2}" height="22" rx="11" fill="rgba(255,255,255,0.10)" />
245654
- <text x="${offsetX + 8}" y="${rowY + 1}" font-family="system-ui, -apple-system, sans-serif" font-size="12" fill="#c0c0c0">${escapeXml(label)}</text>
245691
+ <rect x="${offsetX}" y="${rowY - 13 * S2}" width="${w2}" height="${24 * S2}" rx="${12 * S2}" fill="rgba(255,255,255,0.12)" />
245692
+ <text x="${offsetX + 8 * S2}" y="${rowY + 3 * S2}" font-family="system-ui, -apple-system, sans-serif" font-size="${11 * S2}" fill="#ddd">${escapeXml(label)}</text>
245655
245693
  `;
245656
- offsetX += w2 + 6;
245657
- }
245658
- const descriptionY = tagStartY + currentRow * rowHeight + 14;
245659
- return `<svg width="${WIDTH}" height="${HEIGHT}" xmlns="http://www.w3.org/2000/svg">
245694
+ offsetX += w2 + 6 * S2;
245695
+ }
245696
+ const vibeY = tagStartY + currentRow * rowH + 20 * S2;
245697
+ const jobMax = Math.floor(availW / (7 * S2));
245698
+ const vibeMax = Math.floor(availW / (6.5 * S2));
245699
+ const jobText = data.job.length > jobMax ? data.job.slice(0, jobMax - 1) + "\u2026" : data.job;
245700
+ const vibeText = data.vibe.length > vibeMax ? data.vibe.slice(0, vibeMax - 1) + "\u2026" : data.vibe;
245701
+ return `<svg width="${panelW}" height="${H2}" xmlns="http://www.w3.org/2000/svg">
245702
+ <!-- Gradient panel background -->
245660
245703
  <defs>
245661
- <linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
245662
- <stop offset="0%" stop-color="${gradient.from}" />
245663
- <stop offset="100%" stop-color="${gradient.to}" />
245704
+ <linearGradient id="panel" x1="0" y1="0" x2="1" y2="0">
245705
+ <stop offset="0%" stop-color="rgba(0,0,0,0.85)" />
245706
+ <stop offset="100%" stop-color="rgba(0,0,0,0.65)" />
245664
245707
  </linearGradient>
245665
- <clipPath id="circle">
245666
- <circle cx="${PORTRAIT_X + PORTRAIT_SIZE / 2}" cy="${PORTRAIT_Y + PORTRAIT_SIZE / 2}" r="${PORTRAIT_SIZE / 2}" />
245667
- </clipPath>
245668
245708
  </defs>
245709
+ <rect width="${panelW}" height="${H2}" fill="url(#panel)" />
245669
245710
 
245670
- <rect width="${WIDTH}" height="${HEIGHT}" fill="url(#bg)" />
245671
-
245672
- <circle cx="${PORTRAIT_X + PORTRAIT_SIZE / 2}" cy="${PORTRAIT_Y + PORTRAIT_SIZE / 2}" r="${PORTRAIT_SIZE / 2 + 2}" fill="none" stroke="rgba(255,255,255,0.12)" stroke-width="2" />
245711
+ <!-- Name -->
245712
+ <text x="${textX}" y="${nameY}" font-family="system-ui, -apple-system, sans-serif" font-size="${42 * S2}" font-weight="bold" fill="white">${escapeXml(data.name)}</text>
245673
245713
 
245674
- <text x="${textX}" y="${nameY}" font-family="system-ui, -apple-system, sans-serif" font-size="44" font-weight="bold" fill="white">${escapeXml(data.name)}</text>
245714
+ <!-- Meta -->
245715
+ ${meta ? `<text x="${textX}" y="${metaY}" font-family="system-ui, -apple-system, sans-serif" font-size="${16 * S2}" fill="rgba(255,255,255,0.7)">${escapeXml(meta)}</text>` : ""}
245675
245716
 
245676
- <text x="${textX}" y="${metaY}" font-family="system-ui, -apple-system, sans-serif" font-size="16" fill="#a0a0a0">${escapeXml(data.age)} \xB7 ${escapeXml(truncate(data.location, 35))}</text>
245717
+ <!-- Job -->
245718
+ ${data.job ? `<text x="${textX}" y="${jobY}" font-family="system-ui, -apple-system, sans-serif" font-size="${13 * S2}" fill="rgba(255,255,255,0.5)">${escapeXml(jobText)}</text>` : ""}
245677
245719
 
245720
+ <!-- Tags -->
245678
245721
  ${inlineTags}
245679
245722
 
245680
- <text x="${textX}" y="${descriptionY}" font-family="system-ui, -apple-system, sans-serif" font-size="14" fill="#b0b0b0" font-style="italic">${escapeXml(truncate(data.description, 60))}</text>
245723
+ <!-- Vibe -->
245724
+ ${data.vibe ? `<text x="${textX}" y="${vibeY}" font-family="system-ui, -apple-system, sans-serif" font-size="${13 * S2}" fill="rgba(255,255,255,0.55)" font-style="italic">${escapeXml(vibeText)}</text>` : ""}
245681
245725
 
245682
- <rect x="0" y="${HEIGHT - 44}" width="${WIDTH}" height="44" fill="rgba(0,0,0,0.3)" />
245683
- <text x="36" y="${HEIGHT - 17}" font-family="system-ui, -apple-system, sans-serif" font-size="14" font-weight="bold" fill="#ff69b4">Opencrush</text>
245684
- <text x="${WIDTH - 36}" y="${HEIGHT - 17}" font-family="system-ui, -apple-system, sans-serif" font-size="12" fill="#888" text-anchor="end">github.com/Hollandchirs/Opencrush</text>
245726
+ <!-- Bottom branding -->
245727
+ <text x="${textX}" y="${H2 - 28 * S2}" font-family="system-ui, -apple-system, sans-serif" font-size="${14 * S2}" font-weight="bold" fill="#ff69b4">Opencrush</text>
245728
+ <text x="${panelW - 30 * S2}" y="${H2 - 28 * S2}" font-family="system-ui, -apple-system, sans-serif" font-size="${10 * S2}" fill="rgba(255,255,255,0.3)" text-anchor="end">github.com/heloraai/Opencrush</text>
245685
245729
  </svg>`;
245686
245730
  }
245687
- function escapeXml(str2) {
245688
- return str2.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
245689
- }
245690
- function truncate(str2, max) {
245691
- return str2.length > max ? str2.slice(0, max - 1) + "\u2026" : str2;
245692
- }
245693
245731
  async function generateCard(characterName) {
245694
245732
  const sharp = (await import("sharp")).default;
245695
245733
  const { ROOT_DIR: ROOT_DIR3 } = await Promise.resolve().then(() => (init_paths(), paths_exports));
245696
245734
  const charDir = (0, import_path12.join)(ROOT_DIR3, "characters", characterName);
245697
- if (!(0, import_fs18.existsSync)(charDir)) {
245698
- throw new Error(`Character "${characterName}" not found in characters/`);
245699
- }
245735
+ if (!(0, import_fs18.existsSync)(charDir)) throw new Error(`Character "${characterName}" not found in characters/`);
245700
245736
  const identityPath = (0, import_path12.join)(charDir, "IDENTITY.md");
245701
- if (!(0, import_fs18.existsSync)(identityPath)) {
245702
- throw new Error(`Missing IDENTITY.md for character "${characterName}"`);
245703
- }
245737
+ if (!(0, import_fs18.existsSync)(identityPath)) throw new Error(`Missing IDENTITY.md for character "${characterName}"`);
245704
245738
  const data = parseIdentity(identityPath);
245705
- const gradient = pickGradient(data.name);
245706
245739
  const imageExts = [".jpeg", ".jpg", ".png", ".webp"];
245707
245740
  let refImagePath;
245708
245741
  for (const ext of imageExts) {
@@ -245712,44 +245745,71 @@ async function generateCard(characterName) {
245712
245745
  break;
245713
245746
  }
245714
245747
  }
245715
- const svgOverlay = createSvgOverlay(data, gradient);
245716
- const svgBuffer = Buffer.from(svgOverlay);
245717
- let card = sharp(svgBuffer, { density: 300 }).resize(WIDTH, HEIGHT);
245718
- if (refImagePath) {
245719
- const circleMask = Buffer.from(
245720
- `<svg width="${PORTRAIT_SIZE}" height="${PORTRAIT_SIZE}">
245721
- <circle cx="${PORTRAIT_SIZE / 2}" cy="${PORTRAIT_SIZE / 2}" r="${PORTRAIT_SIZE / 2}" fill="white" />
245722
- </svg>`
245723
- );
245724
- const portrait = await sharp(refImagePath).resize(PORTRAIT_SIZE, PORTRAIT_SIZE, { fit: "cover", position: "top" }).composite([{ input: circleMask, blend: "dest-in" }]).png().toBuffer();
245725
- card = sharp(await card.png().toBuffer()).composite([
245726
- {
245727
- input: portrait,
245728
- top: PORTRAIT_Y,
245729
- left: PORTRAIT_X
245730
- }
245731
- ]);
245732
- }
245748
+ if (!refImagePath) {
245749
+ return generateFallbackCard(charDir, characterName, data);
245750
+ }
245751
+ const bgBlur = await sharp(refImagePath).resize(W2, H2, { fit: "cover", position: "center" }).blur(40).modulate({ brightness: 0.35, saturation: 0.6 }).png().toBuffer();
245752
+ const portraitW = Math.round(W2 * 0.56);
245753
+ const portrait = await sharp(refImagePath).resize(portraitW, H2, { fit: "cover", position: "top" }).png().toBuffer();
245754
+ const fadeW = portraitW;
245755
+ const fadeMask = Buffer.from(
245756
+ `<svg width="${fadeW}" height="${H2}">
245757
+ <defs>
245758
+ <linearGradient id="fade" x1="0" y1="0" x2="1" y2="0">
245759
+ <stop offset="0%" stop-color="white" />
245760
+ <stop offset="70%" stop-color="white" />
245761
+ <stop offset="100%" stop-color="black" />
245762
+ </linearGradient>
245763
+ </defs>
245764
+ <rect width="${fadeW}" height="${H2}" fill="url(#fade)" />
245765
+ </svg>`
245766
+ );
245767
+ const maskedPortrait = await sharp(portrait).composite([{ input: fadeMask, blend: "dest-in" }]).png().toBuffer();
245768
+ const panelW = Math.round(520 * SCALE);
245769
+ const textSvg = buildTextOverlay(data);
245770
+ const textPanel = await sharp(Buffer.from(textSvg)).resize(panelW, H2).png().toBuffer();
245771
+ const card = sharp(bgBlur).composite([
245772
+ { input: maskedPortrait, left: 0, top: 0 },
245773
+ { input: textPanel, left: W2 - panelW, top: 0 }
245774
+ ]);
245775
+ const outputPath = (0, import_path12.join)(charDir, "card.png");
245776
+ await card.png({ quality: 95 }).toFile(outputPath);
245777
+ console.log(source_default.green(`
245778
+ Card generated: characters/${characterName}/card.png`));
245779
+ console.log(source_default.gray(` ${W2}x${H2} PNG
245780
+ `));
245781
+ return outputPath;
245782
+ }
245783
+ async function generateFallbackCard(charDir, characterName, data) {
245784
+ const sharp = (await import("sharp")).default;
245785
+ const S2 = SCALE;
245786
+ const gradient = `<svg width="${W2}" height="${H2}">
245787
+ <defs><linearGradient id="bg" x1="0" y1="0" x2="0.5" y2="1">
245788
+ <stop offset="0%" stop-color="#1a1a2e" /><stop offset="100%" stop-color="#16213e" />
245789
+ </linearGradient></defs>
245790
+ <rect width="${W2}" height="${H2}" fill="url(#bg)" />
245791
+ <text x="${W2 / 2}" y="${H2 / 2 - 20 * S2}" font-family="system-ui" font-size="${48 * S2}" font-weight="bold" fill="white" text-anchor="middle">${escapeXml(data.name)}</text>
245792
+ <text x="${W2 / 2}" y="${H2 / 2 + 30 * S2}" font-family="system-ui" font-size="${16 * S2}" fill="#999" text-anchor="middle">${escapeXml([data.age, data.location, data.job].filter(Boolean).join(" \xB7 "))}</text>
245793
+ <text x="${36 * S2}" y="${H2 - 20 * S2}" font-family="system-ui" font-size="${14 * S2}" font-weight="bold" fill="#ff69b4">Opencrush</text>
245794
+ </svg>`;
245733
245795
  const outputPath = (0, import_path12.join)(charDir, "card.png");
245734
- await card.png().toFile(outputPath);
245796
+ await sharp(Buffer.from(gradient)).resize(W2, H2).png().toFile(outputPath);
245735
245797
  console.log(source_default.green(`
245736
245798
  Card generated: characters/${characterName}/card.png`));
245737
- console.log(source_default.gray(` ${WIDTH}x${HEIGHT} PNG
245799
+ console.log(source_default.gray(` ${W2}x${H2} PNG (no reference image)
245738
245800
  `));
245739
245801
  return outputPath;
245740
245802
  }
245741
- var import_fs18, import_path12, import_gray_matter3, WIDTH, HEIGHT, PORTRAIT_SIZE, PORTRAIT_X, PORTRAIT_Y;
245803
+ var import_fs18, import_path12, import_gray_matter3, SCALE, W2, H2;
245742
245804
  var init_card = __esm({
245743
245805
  "src/card.ts"() {
245744
245806
  import_fs18 = require("fs");
245745
245807
  import_path12 = require("path");
245746
245808
  import_gray_matter3 = __toESM(require_gray_matter());
245747
245809
  init_source();
245748
- WIDTH = 1200;
245749
- HEIGHT = 630;
245750
- PORTRAIT_SIZE = 260;
245751
- PORTRAIT_X = 80;
245752
- PORTRAIT_Y = (HEIGHT - PORTRAIT_SIZE) / 2 - 10;
245810
+ SCALE = 2;
245811
+ W2 = 1200 * SCALE;
245812
+ H2 = 630 * SCALE;
245753
245813
  }
245754
245814
  });
245755
245815
 
@@ -246159,7 +246219,7 @@ async function main2() {
246159
246219
  ${source_default.gray(ROOT_DIR + "/characters/")} Your companion's blueprint files
246160
246220
 
246161
246221
  ${source_default.bold("Documentation:")}
246162
- ${source_default.gray("https://github.com/Hollandchirs/Opencrush")}
246222
+ ${source_default.gray("https://github.com/heloraai/Opencrush")}
246163
246223
  `);
246164
246224
  break;
246165
246225
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencrush",
3
- "version": "0.3.15",
3
+ "version": "0.3.17",
4
4
  "description": "Your AI companion lives on your device. She watches dramas, listens to music, and thinks of you.",
5
5
  "bin": {
6
6
  "opencrush": "dist/index.js"