llmbti 0.1.0 → 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 CHANGED
@@ -33,6 +33,44 @@ var COPY_LIMITS = {
33
33
  };
34
34
  var PAYLOAD_VERSION = 1;
35
35
  var MAX_BADGES = 6;
36
+ var SIGNAL_KEYS = [
37
+ "avgTurns",
38
+ "questionRatio",
39
+ "avgPromptLength",
40
+ "interruptRatio",
41
+ "concreteRatio",
42
+ "abstractRatio",
43
+ "errorPasteRatio",
44
+ "emotionRatio",
45
+ "shortImperativeRatio",
46
+ "planRatio",
47
+ "testRatio",
48
+ "forceRatio",
49
+ "redirectRatio",
50
+ "lowQualityCommitRatio"
51
+ ];
52
+ var BADGE_KEYS = [
53
+ "nightOwl",
54
+ "forcePusher",
55
+ "rmrfSurvivor",
56
+ "sudoBanger",
57
+ "thankYouBot",
58
+ "redoLoop",
59
+ "marathonSession",
60
+ "oneWordWonder",
61
+ "lowSample"
62
+ ];
63
+ var BADGE_STAT_KEYS = {
64
+ nightOwl: "nightRatio",
65
+ forcePusher: "forceCount",
66
+ rmrfSurvivor: "rmrfCount",
67
+ sudoBanger: "sudoBangCount",
68
+ thankYouBot: "thanksCount",
69
+ redoLoop: "redoCount",
70
+ marathonSession: "longestSession",
71
+ oneWordWonder: null,
72
+ lowSample: "promptCount"
73
+ };
36
74
 
37
75
  // ../core/src/pixel/types.ts
38
76
  var PIXEL_SIZE = 32;
@@ -188,10 +226,10 @@ function validateCharacter(c) {
188
226
  for (const [name, seq] of Object.entries(o.anims)) {
189
227
  if (!Array.isArray(seq) || seq.length === 0)
190
228
  fail(`${label}: anims.${name} must be a non-empty array`);
191
- seq.forEach((idx, i) => {
229
+ seq.forEach((idx, i2) => {
192
230
  if (!Number.isInteger(idx) || idx < 0 || idx >= frameCount)
193
231
  fail(
194
- `${label}: anims.${name}[${i}] = ${String(idx)} is not a frame index (0..${frameCount - 1})`
232
+ `${label}: anims.${name}[${i2}] = ${String(idx)} is not a frame index (0..${frameCount - 1})`
195
233
  );
196
234
  });
197
235
  }
@@ -3934,7 +3972,7 @@ function getCharacter(type) {
3934
3972
  function getAnim(character, name) {
3935
3973
  const seq = character.anims?.[name];
3936
3974
  if (seq && seq.length > 0) return [...seq];
3937
- return character.frames.map((_, i) => i);
3975
+ return character.frames.map((_, i2) => i2);
3938
3976
  }
3939
3977
  var DRAWN_TYPES = MBTI_TYPES.filter((t) => REGISTRY[t] !== void 0);
3940
3978
 
@@ -4091,78 +4129,623 @@ var TYPE_META = Object.fromEntries(
4091
4129
  // ../core/src/base64url.ts
4092
4130
  var ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
4093
4131
  var LOOKUP = Object.fromEntries(
4094
- Array.from(ALPHABET, (ch, i) => [ch, i])
4132
+ Array.from(ALPHABET, (ch, i2) => [ch, i2])
4095
4133
  );
4096
4134
  function toBase64Url(bytes) {
4097
4135
  let out = "";
4098
- let i = 0;
4099
- for (; i + 2 < bytes.length; i += 3) {
4100
- const n = bytes[i] << 16 | bytes[i + 1] << 8 | bytes[i + 2];
4136
+ let i2 = 0;
4137
+ for (; i2 + 2 < bytes.length; i2 += 3) {
4138
+ const n = bytes[i2] << 16 | bytes[i2 + 1] << 8 | bytes[i2 + 2];
4101
4139
  out += ALPHABET[n >> 18 & 63] + ALPHABET[n >> 12 & 63] + ALPHABET[n >> 6 & 63] + ALPHABET[n & 63];
4102
4140
  }
4103
- const rest = bytes.length - i;
4141
+ const rest = bytes.length - i2;
4104
4142
  if (rest === 1) {
4105
- const n = bytes[i] << 16;
4143
+ const n = bytes[i2] << 16;
4106
4144
  out += ALPHABET[n >> 18 & 63] + ALPHABET[n >> 12 & 63];
4107
4145
  } else if (rest === 2) {
4108
- const n = bytes[i] << 16 | bytes[i + 1] << 8;
4146
+ const n = bytes[i2] << 16 | bytes[i2 + 1] << 8;
4109
4147
  out += ALPHABET[n >> 18 & 63] + ALPHABET[n >> 12 & 63] + ALPHABET[n >> 6 & 63];
4110
4148
  }
4111
4149
  return out;
4112
4150
  }
4113
4151
 
4114
- // ../core/src/compress.ts
4115
- function isNodeRuntime() {
4116
- const proc = globalThis.process;
4117
- return typeof proc?.versions?.node === "string";
4118
- }
4119
- function hasWebStreams() {
4120
- return typeof globalThis.CompressionStream === "function" && typeof globalThis.DecompressionStream === "function";
4121
- }
4122
- var zlibPromise;
4123
- function loadZlib() {
4124
- if (!zlibPromise) {
4125
- const specifier = "node:zlib";
4126
- zlibPromise = import(
4127
- /* @vite-ignore */
4128
- specifier
4129
- );
4152
+ // ../../node_modules/.pnpm/fflate@0.8.3/node_modules/fflate/esm/index.mjs
4153
+ import { createRequire } from "module";
4154
+ var require2 = createRequire("/");
4155
+ var _a;
4156
+ var Worker;
4157
+ var isMarkedAsUntransferable;
4158
+ try {
4159
+ _a = require2("worker_threads"), Worker = _a.Worker, isMarkedAsUntransferable = _a.isMarkedAsUntransferable;
4160
+ } catch (e) {
4161
+ }
4162
+ var u8 = Uint8Array;
4163
+ var u16 = Uint16Array;
4164
+ var i32 = Int32Array;
4165
+ var fleb = new u8([
4166
+ 0,
4167
+ 0,
4168
+ 0,
4169
+ 0,
4170
+ 0,
4171
+ 0,
4172
+ 0,
4173
+ 0,
4174
+ 1,
4175
+ 1,
4176
+ 1,
4177
+ 1,
4178
+ 2,
4179
+ 2,
4180
+ 2,
4181
+ 2,
4182
+ 3,
4183
+ 3,
4184
+ 3,
4185
+ 3,
4186
+ 4,
4187
+ 4,
4188
+ 4,
4189
+ 4,
4190
+ 5,
4191
+ 5,
4192
+ 5,
4193
+ 5,
4194
+ 0,
4195
+ /* unused */
4196
+ 0,
4197
+ 0,
4198
+ /* impossible */
4199
+ 0
4200
+ ]);
4201
+ var fdeb = new u8([
4202
+ 0,
4203
+ 0,
4204
+ 0,
4205
+ 0,
4206
+ 1,
4207
+ 1,
4208
+ 2,
4209
+ 2,
4210
+ 3,
4211
+ 3,
4212
+ 4,
4213
+ 4,
4214
+ 5,
4215
+ 5,
4216
+ 6,
4217
+ 6,
4218
+ 7,
4219
+ 7,
4220
+ 8,
4221
+ 8,
4222
+ 9,
4223
+ 9,
4224
+ 10,
4225
+ 10,
4226
+ 11,
4227
+ 11,
4228
+ 12,
4229
+ 12,
4230
+ 13,
4231
+ 13,
4232
+ /* unused */
4233
+ 0,
4234
+ 0
4235
+ ]);
4236
+ var clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);
4237
+ var freb = function(eb, start) {
4238
+ var b = new u16(31);
4239
+ for (var i2 = 0; i2 < 31; ++i2) {
4240
+ b[i2] = start += 1 << eb[i2 - 1];
4241
+ }
4242
+ var r = new i32(b[30]);
4243
+ for (var i2 = 1; i2 < 30; ++i2) {
4244
+ for (var j = b[i2]; j < b[i2 + 1]; ++j) {
4245
+ r[j] = j - b[i2] << 5 | i2;
4246
+ }
4247
+ }
4248
+ return { b, r };
4249
+ };
4250
+ var _a = freb(fleb, 2);
4251
+ var fl = _a.b;
4252
+ var revfl = _a.r;
4253
+ fl[28] = 258, revfl[258] = 28;
4254
+ var _b = freb(fdeb, 0);
4255
+ var fd = _b.b;
4256
+ var revfd = _b.r;
4257
+ var rev = new u16(32768);
4258
+ for (i = 0; i < 32768; ++i) {
4259
+ x = (i & 43690) >> 1 | (i & 21845) << 1;
4260
+ x = (x & 52428) >> 2 | (x & 13107) << 2;
4261
+ x = (x & 61680) >> 4 | (x & 3855) << 4;
4262
+ rev[i] = ((x & 65280) >> 8 | (x & 255) << 8) >> 1;
4263
+ }
4264
+ var x;
4265
+ var i;
4266
+ var hMap = (function(cd, mb, r) {
4267
+ var s = cd.length;
4268
+ var i2 = 0;
4269
+ var l = new u16(mb);
4270
+ for (; i2 < s; ++i2) {
4271
+ if (cd[i2])
4272
+ ++l[cd[i2] - 1];
4273
+ }
4274
+ var le = new u16(mb);
4275
+ for (i2 = 1; i2 < mb; ++i2) {
4276
+ le[i2] = le[i2 - 1] + l[i2 - 1] << 1;
4277
+ }
4278
+ var co;
4279
+ if (r) {
4280
+ co = new u16(1 << mb);
4281
+ var rvb = 15 - mb;
4282
+ for (i2 = 0; i2 < s; ++i2) {
4283
+ if (cd[i2]) {
4284
+ var sv = i2 << 4 | cd[i2];
4285
+ var r_1 = mb - cd[i2];
4286
+ var v = le[cd[i2] - 1]++ << r_1;
4287
+ for (var m = v | (1 << r_1) - 1; v <= m; ++v) {
4288
+ co[rev[v] >> rvb] = sv;
4289
+ }
4290
+ }
4291
+ }
4292
+ } else {
4293
+ co = new u16(s);
4294
+ for (i2 = 0; i2 < s; ++i2) {
4295
+ if (cd[i2]) {
4296
+ co[i2] = rev[le[cd[i2] - 1]++] >> 15 - cd[i2];
4297
+ }
4298
+ }
4299
+ }
4300
+ return co;
4301
+ });
4302
+ var flt = new u8(288);
4303
+ for (i = 0; i < 144; ++i)
4304
+ flt[i] = 8;
4305
+ var i;
4306
+ for (i = 144; i < 256; ++i)
4307
+ flt[i] = 9;
4308
+ var i;
4309
+ for (i = 256; i < 280; ++i)
4310
+ flt[i] = 7;
4311
+ var i;
4312
+ for (i = 280; i < 288; ++i)
4313
+ flt[i] = 8;
4314
+ var i;
4315
+ var fdt = new u8(32);
4316
+ for (i = 0; i < 32; ++i)
4317
+ fdt[i] = 5;
4318
+ var i;
4319
+ var flm = /* @__PURE__ */ hMap(flt, 9, 0);
4320
+ var fdm = /* @__PURE__ */ hMap(fdt, 5, 0);
4321
+ var shft = function(p) {
4322
+ return (p + 7) / 8 | 0;
4323
+ };
4324
+ var slc = function(v, s, e) {
4325
+ if (s == null || s < 0)
4326
+ s = 0;
4327
+ if (e == null || e > v.length)
4328
+ e = v.length;
4329
+ return new u8(v.subarray(s, e));
4330
+ };
4331
+ var wbits = function(d, p, v) {
4332
+ v <<= p & 7;
4333
+ var o = p / 8 | 0;
4334
+ d[o] |= v;
4335
+ d[o + 1] |= v >> 8;
4336
+ };
4337
+ var wbits16 = function(d, p, v) {
4338
+ v <<= p & 7;
4339
+ var o = p / 8 | 0;
4340
+ d[o] |= v;
4341
+ d[o + 1] |= v >> 8;
4342
+ d[o + 2] |= v >> 16;
4343
+ };
4344
+ var hTree = function(d, mb) {
4345
+ var t = [];
4346
+ for (var i2 = 0; i2 < d.length; ++i2) {
4347
+ if (d[i2])
4348
+ t.push({ s: i2, f: d[i2] });
4349
+ }
4350
+ var s = t.length;
4351
+ var t2 = t.slice();
4352
+ if (!s)
4353
+ return { t: et, l: 0 };
4354
+ if (s == 1) {
4355
+ var v = new u8(t[0].s + 1);
4356
+ v[t[0].s] = 1;
4357
+ return { t: v, l: 1 };
4358
+ }
4359
+ t.sort(function(a, b) {
4360
+ return a.f - b.f;
4361
+ });
4362
+ t.push({ s: -1, f: 25001 });
4363
+ var l = t[0], r = t[1], i0 = 0, i1 = 1, i22 = 2;
4364
+ t[0] = { s: -1, f: l.f + r.f, l, r };
4365
+ while (i1 != s - 1) {
4366
+ l = t[t[i0].f < t[i22].f ? i0++ : i22++];
4367
+ r = t[i0 != i1 && t[i0].f < t[i22].f ? i0++ : i22++];
4368
+ t[i1++] = { s: -1, f: l.f + r.f, l, r };
4369
+ }
4370
+ var maxSym = t2[0].s;
4371
+ for (var i2 = 1; i2 < s; ++i2) {
4372
+ if (t2[i2].s > maxSym)
4373
+ maxSym = t2[i2].s;
4374
+ }
4375
+ var tr = new u16(maxSym + 1);
4376
+ var mbt = ln(t[i1 - 1], tr, 0);
4377
+ if (mbt > mb) {
4378
+ var i2 = 0, dt = 0;
4379
+ var lft = mbt - mb, cst = 1 << lft;
4380
+ t2.sort(function(a, b) {
4381
+ return tr[b.s] - tr[a.s] || a.f - b.f;
4382
+ });
4383
+ for (; i2 < s; ++i2) {
4384
+ var i2_1 = t2[i2].s;
4385
+ if (tr[i2_1] > mb) {
4386
+ dt += cst - (1 << mbt - tr[i2_1]);
4387
+ tr[i2_1] = mb;
4388
+ } else
4389
+ break;
4390
+ }
4391
+ dt >>= lft;
4392
+ while (dt > 0) {
4393
+ var i2_2 = t2[i2].s;
4394
+ if (tr[i2_2] < mb)
4395
+ dt -= 1 << mb - tr[i2_2]++ - 1;
4396
+ else
4397
+ ++i2;
4398
+ }
4399
+ for (; i2 >= 0 && dt; --i2) {
4400
+ var i2_3 = t2[i2].s;
4401
+ if (tr[i2_3] == mb) {
4402
+ --tr[i2_3];
4403
+ ++dt;
4404
+ }
4405
+ }
4406
+ mbt = mb;
4407
+ }
4408
+ return { t: new u8(tr), l: mbt };
4409
+ };
4410
+ var ln = function(n, l, d) {
4411
+ return n.s == -1 ? Math.max(ln(n.l, l, d + 1), ln(n.r, l, d + 1)) : l[n.s] = d;
4412
+ };
4413
+ var lc = function(c) {
4414
+ var s = c.length;
4415
+ while (s && !c[--s])
4416
+ ;
4417
+ var cl = new u16(++s);
4418
+ var cli = 0, cln = c[0], cls = 1;
4419
+ var w = function(v) {
4420
+ cl[cli++] = v;
4421
+ };
4422
+ for (var i2 = 1; i2 <= s; ++i2) {
4423
+ if (c[i2] == cln && i2 != s)
4424
+ ++cls;
4425
+ else {
4426
+ if (!cln && cls > 2) {
4427
+ for (; cls > 138; cls -= 138)
4428
+ w(32754);
4429
+ if (cls > 2) {
4430
+ w(cls > 10 ? cls - 11 << 5 | 28690 : cls - 3 << 5 | 12305);
4431
+ cls = 0;
4432
+ }
4433
+ } else if (cls > 3) {
4434
+ w(cln), --cls;
4435
+ for (; cls > 6; cls -= 6)
4436
+ w(8304);
4437
+ if (cls > 2)
4438
+ w(cls - 3 << 5 | 8208), cls = 0;
4439
+ }
4440
+ while (cls--)
4441
+ w(cln);
4442
+ cls = 1;
4443
+ cln = c[i2];
4444
+ }
4445
+ }
4446
+ return { c: cl.subarray(0, cli), n: s };
4447
+ };
4448
+ var clen = function(cf, cl) {
4449
+ var l = 0;
4450
+ for (var i2 = 0; i2 < cl.length; ++i2)
4451
+ l += cf[i2] * cl[i2];
4452
+ return l;
4453
+ };
4454
+ var wfblk = function(out, pos, dat) {
4455
+ var s = dat.length;
4456
+ var o = shft(pos + 2);
4457
+ out[o] = s & 255;
4458
+ out[o + 1] = s >> 8;
4459
+ out[o + 2] = out[o] ^ 255;
4460
+ out[o + 3] = out[o + 1] ^ 255;
4461
+ for (var i2 = 0; i2 < s; ++i2)
4462
+ out[o + i2 + 4] = dat[i2];
4463
+ return (o + 4 + s) * 8;
4464
+ };
4465
+ var wblk = function(dat, out, final, syms, lf, df, eb, li, bs, bl, p) {
4466
+ wbits(out, p++, final);
4467
+ ++lf[256];
4468
+ var _a2 = hTree(lf, 15), dlt = _a2.t, mlb = _a2.l;
4469
+ var _b2 = hTree(df, 15), ddt = _b2.t, mdb = _b2.l;
4470
+ var _c = lc(dlt), lclt = _c.c, nlc = _c.n;
4471
+ var _d = lc(ddt), lcdt = _d.c, ndc = _d.n;
4472
+ var lcfreq = new u16(19);
4473
+ for (var i2 = 0; i2 < lclt.length; ++i2)
4474
+ ++lcfreq[lclt[i2] & 31];
4475
+ for (var i2 = 0; i2 < lcdt.length; ++i2)
4476
+ ++lcfreq[lcdt[i2] & 31];
4477
+ var _e = hTree(lcfreq, 7), lct = _e.t, mlcb = _e.l;
4478
+ var nlcc = 19;
4479
+ for (; nlcc > 4 && !lct[clim[nlcc - 1]]; --nlcc)
4480
+ ;
4481
+ var flen = bl + 5 << 3;
4482
+ var ftlen = clen(lf, flt) + clen(df, fdt) + eb;
4483
+ var dtlen = clen(lf, dlt) + clen(df, ddt) + eb + 14 + 3 * nlcc + clen(lcfreq, lct) + 2 * lcfreq[16] + 3 * lcfreq[17] + 7 * lcfreq[18];
4484
+ if (bs >= 0 && flen <= ftlen && flen <= dtlen)
4485
+ return wfblk(out, p, dat.subarray(bs, bs + bl));
4486
+ var lm, ll, dm, dl;
4487
+ wbits(out, p, 1 + (dtlen < ftlen)), p += 2;
4488
+ if (dtlen < ftlen) {
4489
+ lm = hMap(dlt, mlb, 0), ll = dlt, dm = hMap(ddt, mdb, 0), dl = ddt;
4490
+ var llm = hMap(lct, mlcb, 0);
4491
+ wbits(out, p, nlc - 257);
4492
+ wbits(out, p + 5, ndc - 1);
4493
+ wbits(out, p + 10, nlcc - 4);
4494
+ p += 14;
4495
+ for (var i2 = 0; i2 < nlcc; ++i2)
4496
+ wbits(out, p + 3 * i2, lct[clim[i2]]);
4497
+ p += 3 * nlcc;
4498
+ var lcts = [lclt, lcdt];
4499
+ for (var it = 0; it < 2; ++it) {
4500
+ var clct = lcts[it];
4501
+ for (var i2 = 0; i2 < clct.length; ++i2) {
4502
+ var len = clct[i2] & 31;
4503
+ wbits(out, p, llm[len]), p += lct[len];
4504
+ if (len > 15)
4505
+ wbits(out, p, clct[i2] >> 5 & 127), p += clct[i2] >> 12;
4506
+ }
4507
+ }
4508
+ } else {
4509
+ lm = flm, ll = flt, dm = fdm, dl = fdt;
4510
+ }
4511
+ for (var i2 = 0; i2 < li; ++i2) {
4512
+ var sym = syms[i2];
4513
+ if (sym > 255) {
4514
+ var len = sym >> 18 & 31;
4515
+ wbits16(out, p, lm[len + 257]), p += ll[len + 257];
4516
+ if (len > 7)
4517
+ wbits(out, p, sym >> 23 & 31), p += fleb[len];
4518
+ var dst = sym & 31;
4519
+ wbits16(out, p, dm[dst]), p += dl[dst];
4520
+ if (dst > 3)
4521
+ wbits16(out, p, sym >> 5 & 8191), p += fdeb[dst];
4522
+ } else {
4523
+ wbits16(out, p, lm[sym]), p += ll[sym];
4524
+ }
4525
+ }
4526
+ wbits16(out, p, lm[256]);
4527
+ return p + ll[256];
4528
+ };
4529
+ var deo = /* @__PURE__ */ new i32([65540, 131080, 131088, 131104, 262176, 1048704, 1048832, 2114560, 2117632]);
4530
+ var et = /* @__PURE__ */ new u8(0);
4531
+ var dflt = function(dat, lvl, plvl, pre, post, st) {
4532
+ var s = st.z || dat.length;
4533
+ var o = new u8(pre + s + 5 * (1 + Math.ceil(s / 7e3)) + post);
4534
+ var w = o.subarray(pre, o.length - post);
4535
+ var lst = st.l;
4536
+ var pos = (st.r || 0) & 7;
4537
+ if (lvl) {
4538
+ if (pos)
4539
+ w[0] = st.r >> 3;
4540
+ var opt = deo[lvl - 1];
4541
+ var n = opt >> 13, c = opt & 8191;
4542
+ var msk_1 = (1 << plvl) - 1;
4543
+ var prev = st.p || new u16(32768), head = st.h || new u16(msk_1 + 1);
4544
+ var bs1_1 = Math.ceil(plvl / 3), bs2_1 = 2 * bs1_1;
4545
+ var hsh = function(i3) {
4546
+ return (dat[i3] ^ dat[i3 + 1] << bs1_1 ^ dat[i3 + 2] << bs2_1) & msk_1;
4547
+ };
4548
+ var syms = new i32(25e3);
4549
+ var lf = new u16(288), df = new u16(32);
4550
+ var lc_1 = 0, eb = 0, i2 = st.i || 0, li = 0, wi = st.w || 0, bs = 0;
4551
+ for (; i2 + 2 < s; ++i2) {
4552
+ var hv = hsh(i2);
4553
+ var imod = i2 & 32767, pimod = head[hv];
4554
+ prev[imod] = pimod;
4555
+ head[hv] = imod;
4556
+ if (wi <= i2) {
4557
+ var rem = s - i2;
4558
+ if ((lc_1 > 7e3 || li > 24576) && (rem > 423 || !lst)) {
4559
+ pos = wblk(dat, w, 0, syms, lf, df, eb, li, bs, i2 - bs, pos);
4560
+ li = lc_1 = eb = 0, bs = i2;
4561
+ for (var j = 0; j < 286; ++j)
4562
+ lf[j] = 0;
4563
+ for (var j = 0; j < 30; ++j)
4564
+ df[j] = 0;
4565
+ }
4566
+ var l = 2, d = 0, ch_1 = c, dif = imod - pimod & 32767;
4567
+ if (rem > 2 && hv == hsh(i2 - dif)) {
4568
+ var maxn = Math.min(n, rem) - 1;
4569
+ var maxd = Math.min(32767, i2);
4570
+ var ml = Math.min(258, rem);
4571
+ while (dif <= maxd && --ch_1 && imod != pimod) {
4572
+ if (dat[i2 + l] == dat[i2 + l - dif]) {
4573
+ var nl = 0;
4574
+ for (; nl < ml && dat[i2 + nl] == dat[i2 + nl - dif]; ++nl)
4575
+ ;
4576
+ if (nl > l) {
4577
+ l = nl, d = dif;
4578
+ if (nl > maxn)
4579
+ break;
4580
+ var mmd = Math.min(dif, nl - 2);
4581
+ var md = 0;
4582
+ for (var j = 0; j < mmd; ++j) {
4583
+ var ti = i2 - dif + j & 32767;
4584
+ var pti = prev[ti];
4585
+ var cd = ti - pti & 32767;
4586
+ if (cd > md)
4587
+ md = cd, pimod = ti;
4588
+ }
4589
+ }
4590
+ }
4591
+ imod = pimod, pimod = prev[imod];
4592
+ dif += imod - pimod & 32767;
4593
+ }
4594
+ }
4595
+ if (d) {
4596
+ syms[li++] = 268435456 | revfl[l] << 18 | revfd[d];
4597
+ var lin = revfl[l] & 31, din = revfd[d] & 31;
4598
+ eb += fleb[lin] + fdeb[din];
4599
+ ++lf[257 + lin];
4600
+ ++df[din];
4601
+ wi = i2 + l;
4602
+ ++lc_1;
4603
+ } else {
4604
+ syms[li++] = dat[i2];
4605
+ ++lf[dat[i2]];
4606
+ }
4607
+ }
4608
+ }
4609
+ for (i2 = Math.max(i2, wi); i2 < s; ++i2) {
4610
+ syms[li++] = dat[i2];
4611
+ ++lf[dat[i2]];
4612
+ }
4613
+ pos = wblk(dat, w, lst, syms, lf, df, eb, li, bs, i2 - bs, pos);
4614
+ if (!lst) {
4615
+ st.r = pos & 7 | w[pos / 8 | 0] << 3;
4616
+ pos -= 7;
4617
+ st.h = head, st.p = prev, st.i = i2, st.w = wi;
4618
+ }
4619
+ } else {
4620
+ for (var i2 = st.w || 0; i2 < s + lst; i2 += 65535) {
4621
+ var e = i2 + 65535;
4622
+ if (e >= s) {
4623
+ w[pos / 8 | 0] = lst;
4624
+ e = s;
4625
+ }
4626
+ pos = wfblk(w, pos + 1, dat.subarray(i2, e));
4627
+ }
4628
+ st.i = s;
4629
+ }
4630
+ return slc(o, 0, pre + shft(pos) + post);
4631
+ };
4632
+ var dopt = function(dat, opt, pre, post, st) {
4633
+ if (!st) {
4634
+ st = { l: 1 };
4635
+ if (opt.dictionary) {
4636
+ var dict = opt.dictionary.subarray(-32768);
4637
+ var newDat = new u8(dict.length + dat.length);
4638
+ newDat.set(dict);
4639
+ newDat.set(dat, dict.length);
4640
+ dat = newDat;
4641
+ st.w = dict.length;
4642
+ }
4643
+ }
4644
+ return dflt(dat, opt.level == null ? 6 : opt.level, opt.mem == null ? st.l ? Math.ceil(Math.max(8, Math.min(13, Math.log(dat.length))) * 1.5) : 20 : 12 + opt.mem, pre, post, st);
4645
+ };
4646
+ function deflateSync(data, opts) {
4647
+ return dopt(data, opts || {}, 0, 0);
4648
+ }
4649
+ var te = typeof TextEncoder != "undefined" && /* @__PURE__ */ new TextEncoder();
4650
+ var td = typeof TextDecoder != "undefined" && /* @__PURE__ */ new TextDecoder();
4651
+ var tds = 0;
4652
+ try {
4653
+ td.decode(et, { stream: true });
4654
+ tds = 1;
4655
+ } catch (e) {
4656
+ }
4657
+ function strToU8(str, latin1) {
4658
+ if (latin1) {
4659
+ var ar_1 = new u8(str.length);
4660
+ for (var i2 = 0; i2 < str.length; ++i2)
4661
+ ar_1[i2] = str.charCodeAt(i2);
4662
+ return ar_1;
4130
4663
  }
4131
- return zlibPromise;
4132
- }
4133
- function pickEngine(engine) {
4134
- if (engine !== "auto") return engine;
4135
- if (isNodeRuntime()) return "zlib";
4136
- if (hasWebStreams()) return "stream";
4137
- throw new Error("llmbti: no deflate-raw implementation available in this runtime");
4138
- }
4139
- async function pipeThrough(bytes, transform) {
4140
- const source = new Blob([bytes]).stream();
4141
- const buf = await new Response(source.pipeThrough(transform)).arrayBuffer();
4142
- return new Uint8Array(buf);
4143
- }
4144
- async function deflateRaw(bytes, engine = "auto") {
4145
- if (pickEngine(engine) === "zlib") {
4146
- const zlib = await loadZlib();
4147
- return new Uint8Array(zlib.deflateRawSync(bytes));
4664
+ if (te)
4665
+ return te.encode(str);
4666
+ var l = str.length;
4667
+ var ar = new u8(str.length + (str.length >> 1));
4668
+ var ai = 0;
4669
+ var w = function(v) {
4670
+ ar[ai++] = v;
4671
+ };
4672
+ for (var i2 = 0; i2 < l; ++i2) {
4673
+ if (ai + 5 > ar.length) {
4674
+ var n = new u8(ai + 8 + (l - i2 << 1));
4675
+ n.set(ar);
4676
+ ar = n;
4677
+ }
4678
+ var c = str.charCodeAt(i2);
4679
+ if (c < 128 || latin1)
4680
+ w(c);
4681
+ else if (c < 2048)
4682
+ w(192 | c >> 6), w(128 | c & 63);
4683
+ else if (c > 55295 && c < 57344)
4684
+ c = 65536 + (c & 1023 << 10) | str.charCodeAt(++i2) & 1023, w(240 | c >> 18), w(128 | c >> 12 & 63), w(128 | c >> 6 & 63), w(128 | c & 63);
4685
+ else
4686
+ w(224 | c >> 12), w(128 | c >> 6 & 63), w(128 | c & 63);
4148
4687
  }
4149
- return pipeThrough(bytes, new CompressionStream("deflate-raw"));
4688
+ return slc(ar, 0, ai);
4689
+ }
4690
+
4691
+ // ../core/src/dict.ts
4692
+ var DICT_WIRE_V1 = `\uCEE4\uBC0B \uD2B8\uB9AC\uAC00 \uD55C \uC904\uC774 \uC544\uB2C8\uBA74 \uC7A0\uC774 \uC548 \uC628\uB2E4. \uACC4\uD68D\uBD80\uD130 \uC138\uC6B0\uACE0 \uD504\uB86C\uD504\uD2B8\uB294 \uAE38\uACE0 \uC815\uD655\uD558\uAC8C \uC4F4\uB2E4. \uACE0\uB9C8\uC6CC \uB300\uC2E0 \uB2E4\uC74C \uC791\uC5C5\uC744 \uBC14\uB85C \uBD99\uC774\uB294 \uC0AC\uB78C\uC774\uB2E4. \uBA38\uC9C0 \uCEE4\uBC0B\uC740 \uB208\uC5D0 \uAC70\uC2AC\uB824\uC11C \uBABB \uCC38\uC74C \uB9AC\uBCA0\uC774\uC2A4 \uC7A5\uC778 \uC0AC\uBC29\uC73C\uB85C \uBED7\uC740 \uBE0C\uB79C\uCE58\uB97C \uD55C \uC904\uB85C \uC815\uB9AC\uD574 \uC90C \uB9AC\uBCA0\uC774\uC2A4 \uC911\uC778\uB370 \uB370\uBAA8\uBD80\uD130 \uD558\uC790\uACE0 \uD568 \uBC84\uADF8 \uD558\uB098 \uC7A1\uC73C\uB7EC \uB4E4\uC5B4\uAC14\uB2E4\uAC00 \uB77C\uC774\uBE0C\uB7EC\uB9AC \uC18C\uC2A4\uB97C \uC77D\uACE0 \uC788\uB2E4. \uD504\uB86C\uD504\uD2B8\uAC00 \uAE38\uACE0 \uC9C8\uBB38 \uB05D\uC5D0 \uC9C8\uBB38\uC774 \uBD99\uB294\uB2E4. \uD0ED\uC740 \uC548 \uB2EB\uB294 \uAC8C \uC544\uB2C8\uB77C \uBABB \uB2EB\uB294 \uAC70\uB2E4. \uC65C \uB418\uB294\uC9C0 \uC54C\uC544\uB0B4\uB2E4 \uC6D0\uB798 \uD558\uB824\uB358 \uAC78 \uC78A\uC74C \uD1A0\uB07C\uAD74 \uD0D0\uD5D8\uAC00 \uD1A0\uB07C\uAD74\uC5D0 \uB4E4\uC5B4\uAC00\uBA74 \uAEBC\uB0B4\uC11C \uB9C8\uAC10\uC5D0 \uB9DE\uCDB0 \uC90C \uC65C \uADF8\uB7F0\uC9C0 \uC124\uBA85\uD558\uB294\uB370 \uC774\uBBF8 \uACE0\uCCD0 \uB193\uC74C \uC138\uC158\uB9C8\uB2E4 \uACC4\uD68D\uBD80\uD130 \uC9DC\uACE0 \uD134\uC744 \uC9E7\uAC8C \uB04A\uC5B4\uC11C \uC2DC\uD0A8\uB2E4. \uD14C\uC2A4\uD2B8\uB294 \uB3CC\uB9AC\uACE0 \uBA38\uC9C0\uB294 \uC624\uB298 \uC548\uC5D0 \uD55C\uB2E4. \uD1A0\uB07C\uAD74 \uD30C\uB294 \uB3D9\uB8CC\uB97C \uAEBC\uB0B4 \uC624\uB294 \uAC8C \uCDE8\uBBF8\uB2E4. Claude\uD55C\uD14C\uB3C4 \uB370\uB4DC\uB77C\uC778\uC744 \uC900\uB2E4 \uC2A4\uD504\uB9B0\uD2B8 \uC0AC\uB839\uAD00 \uC2A4\uD504\uB9B0\uD2B8\uC5D0 \uAE4A\uC774 \uD30C\uB294 \uC0AC\uB78C \uD558\uB098\uB294 \uD544\uC694\uD568 \uC2A4\uD504\uB9B0\uD2B8 \uC548\uC5D0 \uB05D\uB098\uB294 \uB808\uD3EC\uAC00 \uC5C6\uC74C \uB808\uAC70\uC2DC\uB97C \uBCF4\uBA74 \uACE0\uCE58\uB294 \uB300\uC2E0 \uC0C8\uB85C \uC9E0\uB2E4. \uAD6C\uC870, \uC124\uACC4, \uB9AC\uD329\uD130 \uC598\uAE30\uAC00 \uD504\uB86C\uD504\uD2B8\uC758 \uC808\uBC18\uC774\uB2E4. \uBD88\uC740 \uC798 \uC9C0\uB974\uB294\uB370 \uB044\uB294 \uAC74 \uB2E4\uB978 \uC0AC\uB78C \uBAAB\uC77C \uB54C\uAC00 \uB9CE\uB2E4. \uC774\uAC70 \uB2E4 \uAC08\uC544\uC5CE\uC73C\uBA74 \uB418\uB294\uB370\uC694? \uB808\uAC70\uC2DC \uBC29\uD654\uBC94 \uBD88 \uC9C0\uB978 \uB808\uAC70\uC2DC\uB97C \uCCB4\uD06C\uB9AC\uC2A4\uD2B8\uB85C \uC218\uC2B5\uD574 \uC90C \uBD88 \uC9C0\uB974\uAE30 \uC804\uC5D0 PR \uD15C\uD50C\uB9BF\uBD80\uD130 \uCC44\uC6B0\uB77C\uACE0 \uD568 \uC65C \uC774\uB807\uAC8C \uC9F0\uB294\uC9C0\uB97C \uCF54\uB4DC\uBCF4\uB2E4 \uAE38\uAC8C \uC801\uB294\uB2E4. \uD504\uB86C\uD504\uD2B8\uB3C4 \uC815\uC911\uD558\uACE0 \uAE38\uB2E4. \uAE09\uD558\uAC8C \uC3D8\uB294 \uBC30\uD3EC \uC606\uC5D0\uC11C \uC870\uC6A9\uD788 \uBB38\uC11C\uB97C \uCC44\uC6CC \uB123\uB294 \uC0AC\uB78C\uC774\uB2E4. \uCF54\uB4DC\uBCF4\uB2E4 README\uAC00 \uAE34 \uC0AC\uB78C \uC8FC\uC11D \uC2DC\uC778 \uC9C1\uBC30\uD3EC\uD55C \uAC70 \uC124\uBA85\uC740 \uB0B4\uAC00 README\uC5D0 \uC368 \uC90C \uC138 \uBB38\uB2E8 \uC4F4 \uC8FC\uC11D\uC5D0 \uC5C4\uC9C0 \uD558\uB098\uB85C \uB2F5\uD568 \uC544\uC774\uB514\uC5B4\uAC00 \uB5A0\uC624\uB974\uBA74 \uB808\uD3EC\uBD80\uD130 \uD310\uB2E4. \uD504\uB86C\uD504\uD2B8\uC5D0 \u314B\u314B\uC640 \uACE0\uB9C8\uC6CC\uAC00 \uB9CE\uACE0 \uBC29\uD5A5\uB3C4 \uC790\uC8FC \uBC14\uB010\uB2E4. \uB808\uD3EC \uC5F4 \uAC1C \uC911 README\uAE4C\uC9C0 \uC788\uB294 \uAC74 \uB450 \uAC1C\uCBE4\uC774\uB2E4. \uCCAB \uCEE4\uBC0B\uC740 \uC644\uBCBD, \uB450 \uBC88\uC9F8 \uCEE4\uBC0B\uC740 \uC5C6\uC74C \uBBF8\uC644\uC131 \uB808\uD3EC \uC218\uC9D1\uAC00 PR \uD15C\uD50C\uB9BF \uCC44\uC6B0\uB2E4 \uBCF4\uBA74 \uB808\uD3EC \uD558\uB098\uB294 \uB05D\uB0A8 \uB9C8\uAC10 \uC598\uAE30\uBD80\uD130 \uAEBC\uB0B4\uC11C \uB808\uD3EC \uD558\uB098 \uB354 \uC0DD\uAE40 \uB9AC\uBDF0\uC5D0 \uC9C4\uC2EC\uC774\uB2E4. \uACE0\uCCD0 \uD55C \uB9C8\uB514\uB85C \uB05D\uB0BC \uAC78 \uC65C \uACE0\uCCD0\uC57C \uD558\uB294\uC9C0 \uC124\uBA85\uD574 \uC900\uB2E4. Claude\uD55C\uD14C\uB3C4 \uACE0\uB9C8\uC6CC\uB97C \uC78A\uC9C0 \uC54A\uC544\uC11C \uD134\uC774 \uAE38\uC5B4\uC9C4\uB2E4. LGTM \uC804\uC5D0 \uCF54\uBA58\uD2B8 \uC5F4 \uC904\uC740 \uAE30\uBCF8 \uCF54\uB4DC\uB9AC\uBDF0 \uBA58\uD1A0 \uACE0\uCCD0 \uD55C \uB9C8\uB514\uC5D0 \uB9AC\uBDF0 \uCF54\uBA58\uD2B8 \uB2EC\uC544 \uC90C 1px PR\uC5D0 \uB9AC\uBDF0 20\uC904 \uB2EC\uC544\uB3C4 \uC548 \uC77D\uC74C \uC0C8 \uC544\uC774\uB514\uC5B4\uAC00 \uB098\uC624\uBA74 \uBE0C\uB79C\uCE58\uBD80\uD130 \uB534\uB2E4. \uB2E4\uC2DC, \uC544\uB2C8 \uADF8\uAC8C \uC544\uB2C8\uB77C\uAC00 \uD504\uB86C\uD504\uD2B8\uC758 \uC8FC \uBA54\uB274\uB2E4. \uC138\uC158\uC740 \uAE38\uACE0 \uC990\uAC70\uC6B4\uB370 \uB05D\uB098\uACE0 \uB0A8\uB294 \uAC74 \uBE0C\uB79C\uCE58 \uBAA9\uB85D\uC774\uB2E4. \uBE0C\uB79C\uCE58 23\uAC1C, \uBA38\uC9C0 0\uAC1C \uBE0C\uB79C\uCE58 \uBC29\uB791\uC790 \uACC4\uD68D \uC5C6\uC774 \uBED7\uC740 \uBE0C\uB79C\uCE58\uB97C \uB204\uAC00 \uD569\uCCD0 \uC918\uC57C \uD568 \uBE0C\uB79C\uCE58 \uB9CC\uB4E4 \uB54C\uB9C8\uB2E4 \uCCB4\uD06C\uB9AC\uC2A4\uD2B8 \uB4E4\uC774\uBC08 \uCCB4\uD06C\uB9AC\uC2A4\uD2B8 \uC5C6\uC774\uB294 \uBA38\uC9C0\uB97C \uC548 \uD55C\uB2E4. \uD504\uB86C\uD504\uD2B8\uC5D0 \uD30C\uC77C \uACBD\uB85C\uC640 \uB77C\uC778 \uBC88\uD638\uAC00 \uAF2D \uBD99\uACE0 \uD14C\uC2A4\uD2B8\uB294 \uB9E4\uBC88 \uB3CC\uB9B0\uB2E4. --force\uB97C \uCE5C \uAE30\uB85D\uC774 \uC5C6\uB294 \uBA87 \uC548 \uB418\uB294 \uC0AC\uB78C\uC774\uB2E4. \uB9B0\uD2B8 \uC548 \uB3CC\uB9B0 PR\uC740 PR\uC774 \uC544\uB2D8 \uB9B0\uD130 \uC218\uD638\uC790 \uB9B0\uD2B8 \uD1B5\uACFC\uD55C \uCF54\uB4DC\uC5D0 \uAC00\uB054 \uBD88\uC528\uAC00 \uD544\uC694\uD568 \uCCB4\uD06C\uB9AC\uC2A4\uD2B8 \uC548 \uBCF4\uACE0 \uBE0C\uB79C\uCE58\uB9CC \uB298\uB9BC \uB0A8\uC774 \uC3DC \uBC30\uD3EC\uC758 \uB4B7\uC815\uB9AC\uB97C \uBB35\uBB35\uD788 \uD55C\uB2E4. \uC5D0\uB7EC \uB85C\uADF8\uB97C \uADF8\uB300\uB85C \uBD99\uC5EC \uB123\uACE0 \uC815\uC911\uD558\uAC8C \uACE0\uCCD0 \uB2EC\uB77C\uACE0 \uD55C\uB2E4. \uD638\uCD9C\uAE30\uB294 \uB0A8\uC774 \uC6B8\uB9AC\uB294\uB370 \uAE68\uB294 \uAC74 \uC774 \uC0AC\uB78C\uC774\uB2E4. \uC0C8\uBCBD \uC54C\uB9BC \uBC1B\uACE0\uB3C4 \uBBF8\uC548\uD558\uB2E4\uACE0 \uD558\uB294 \uC0AC\uB78C \uC628\uCF5C \uC9C0\uD0B4\uC774 \uD638\uCD9C\uAE30 \uC6B8\uB9B4 \uB54C \uAC19\uC774 \uAE68\uC5B4 \uC788\uC5B4 \uC90C \uC0C8\uBCBD \uD638\uCD9C\uAE30\uAC00 \uC6B8\uB9AC\uB294 \uC6D0\uC778 1\uC21C\uC704 \uCEE4\uBC0B \uBA54\uC2DC\uC9C0 \uADDC\uCE59\uBD80\uD130 \uD3F4\uB354 \uAD6C\uC870\uAE4C\uC9C0 \uB2E4 \uC815\uD574 \uB193\uB294\uB2E4. \uD504\uB86C\uD504\uD2B8\uAC00 \uC9E7\uACE0 \uBA85\uB839\uD615\uC774\uBA70 \uACC4\uD68D \uC2E0\uD638\uAC00 \uB9CE\uB2E4. \uD15C\uD50C\uB9BF\uC744 \uC548 \uCC44\uC6B4 PR\uC740 \uC5F4\uC5B4 \uBCF4\uC9C0\uB3C4 \uC54A\uB294\uB2E4. PR \uD15C\uD50C\uB9BF \uC548 \uCC44\uC6B0\uBA74 \uB9AC\uBDF0 \uC548 \uD568 \uCEE8\uBCA4\uC158 \uACBD\uCC30 \uD15C\uD50C\uB9BF \uCC44\uC6B8 \uC0AC\uB78C\uC774 \uC544\uC774\uB514\uC5B4\uB294 \uB9CE\uC74C \uD15C\uD50C\uB9BF \uC548 \uCC44\uC6B0\uACE0 \uB808\uAC70\uC2DC\uBD80\uD130 \uD0DC\uC6C0 \uD504\uB86C\uD504\uD2B8 \uB05D\uC5D0 \u314B\u314B\uB098 \uC774\uBAA8\uC9C0\uAC00 \uAC70\uC758 \uD56D\uC0C1 \uBD99\uB294\uB2E4. Claude\uD55C\uD14C \uACE0\uB9C8\uC6CC\uB97C \uC81C\uC77C \uB9CE\uC774 \uD558\uB294 \uC720\uD615\uC774\uB2E4. \uC138\uC158\uC774 \uAE38\uACE0 \uB300\uD654\uAC00 \uB9CE\uC740\uB370 \uD14C\uC2A4\uD2B8 \uC598\uAE30\uB294 \uC801\uB2E4. \uCF54\uB4DC \uB9AC\uBDF0\uBCF4\uB2E4 \uB9AC\uC561\uC158\uC774 \uBE60\uB978 \uC0AC\uB78C \uC774\uBAA8\uC9C0 \uB9AC\uC561\uC158 \uC694\uC815 \uC0C8\uBCBD \uC54C\uB9BC\uC5D0 \uB9AC\uC561\uC158\uC774\uB77C\uB3C4 \uB2EC\uC544 \uC90C \uB9AC\uC561\uC158 \uD558\uB098 \uB2EC\uBA74 \uC124\uBA85\uC744 \uC138 \uBB38\uB2E8 \uC694\uAD6C\uD568 \uACE0\uCCD0, \uB2E4\uC2DC, \uD574\uC918\uB85C \uB300\uBD80\uBD84\uC758 \uC77C\uC744 \uB05D\uB0B8\uB2E4. \uC5D0\uB7EC \uB85C\uADF8\uB294 \uBD99\uC774\uB418 \uC124\uBA85\uC740 \uC548 \uBD99\uC778\uB2E4. \uC9E7\uAC8C \uC2DC\uD0A4\uACE0 \uBC14\uB85C \uACB0\uACFC\uB97C \uBCF4\uB294 \uCABD\uC774\uB77C \uC138\uC158\uB3C4 \uC9E7\uB2E4. \uD504\uB86C\uD504\uD2B8 \uD3C9\uADE0 \uAE38\uC774 \uB450 \uAE00\uC790 "\uACE0\uCCD0" \uC7A5\uC778 \uC65C \uACE0\uCCE4\uB294\uC9C0 \uB300\uC2E0 \uC124\uBA85\uD574 \uC90C \uACE0\uCCD0 \uD55C \uB9C8\uB514\uBA74 \uB418\uB294\uB370 \uB17C\uBB38\uC744 \uBCF4\uB0C4 \uB0A8\uB4E4\uC740 \uBABB \uBCF4\uB294 1px\uC744 \uBCF4\uACE0 \uB2E4\uC2DC\uB97C \uB204\uB978\uB2E4. \uD504\uB86C\uD504\uD2B8\uB294 \uC9E7\uC740\uB370 \uD69F\uC218\uAC00 \uB9CE\uACE0 \uC2A4\uD06C\uB9B0\uC0F7\uACFC \uCF54\uB4DC \uBE14\uB85D\uC744 \uC790\uC8FC \uBD99\uC778\uB2E4. \uBA38\uC9C0\uB294 \uB290\uB9B0\uB370 \uACB0\uACFC\uBB3C\uC740 \uC608\uC058\uB2E4. \uC548 \uBCF4\uC774\uB294 1px \uCC28\uC774\uAC00 \uBCF4\uC774\uB294 \uC0AC\uB78C 1px \uC7A5\uC778 1px \uB9DE\uCD98 \uD654\uBA74\uC744 \uB370\uBAA8\uC5D0\uC11C \uC790\uB791\uD574 \uC90C 1px \uC62E\uAE34 PR\uC5D0 \uB9AC\uBDF0 \uCF54\uBA58\uD2B8 20\uAC1C \uB2F4 \uBE0C\uB79C\uCE58\uB97C \uC548 \uB530\uACE0 main\uC5D0\uC11C \uBC14\uB85C \uC3DC\uB2E4. --force\uC640 reset --hard\uAC00 \uC775\uC219\uD558\uACE0 \uCEE4\uBC0B \uBA54\uC2DC\uC9C0\uB294 fix\uAC00 \uC808\uBC18\uC774\uB2E4. \uC7A5\uC560\uAC00 \uB098\uBA74 \uC81C\uC77C \uBE68\uB9AC \uACE0\uCE58\uB294 \uAC83\uB3C4 \uC774 \uC0AC\uB78C\uC774\uB2E4. \uD14C\uC2A4\uD2B8\uB294 prd \uC0AC\uC6A9\uC790\uAC00 \uD574 \uC90C prd \uC9C1\uBC30\uD3EC\uB7EC \uB0B4\uAC00 \uC3D8\uACE0 \uB098\uBA74 \uBB38\uC11C\uB294 \uC800\uCABD\uC774 \uC368 \uC90C \uB0B4\uAC00 \uC3D8\uBA74 \uC800\uCABD \uD638\uCD9C\uAE30\uAC00 \uC6B8\uB9BC \uBCF4\uC5EC \uC8FC\uB294 \uB370 \uC9C4\uC2EC\uC774\uB2E4. \uC138\uC158\uB9C8\uB2E4 \uD134\uC774 \uB9CE\uACE0 \uC911\uAC04\uC5D0 \uB07C\uC5B4\uB4DC\uB294 \uBE44\uC728\uC774 \uB192\uB2E4. \uB370\uBAA8 \uC804\uB0A0 \uBC24 \uCEE4\uBC0B\uC774 \uBAB0\uB824 \uC788\uACE0 \uD14C\uC2A4\uD2B8\uB294 \uB370\uBAA8 \uC774\uD6C4\uC5D0 \uC0DD\uAC01\uD55C\uB2E4. \uB3D9\uC791\uD558\uB294 \uAC74 \uB370\uBAA8 \uB54C\uB9CC \uB370\uBAA8 \uC7A5\uC778 \uB370\uBAA8 \uD654\uBA74\uC774 1px\uB3C4 \uC548 \uBC00\uB9BC \uB370\uBAA8 \uC911\uC778\uB370 \uB9AC\uBCA0\uC774\uC2A4 \uC911\uC774\uB77C \uC548 \uB41C\uB2E4\uACE0 \uD568 --force push \uBC88 rm -rf \uBC88 \uC0C8\uBCBD 2\uC2DC\uC5D0\uC11C 5\uC2DC \uC0AC\uC774 \uD65C\uB3D9 % "\uB2E4\uC2DC" \uBC88 "\uACE0\uB9C8\uC6CC" \uBC88 \uAC00\uC7A5 \uC9E7\uC740 \uD504\uB86C\uD504\uD2B8 "" \uC81C\uC77C \uB9CE\uC774 \uCE5C \uBA85\uB839 \uCD5C\uC7A5 \uC138\uC158 \uD134 \uC138\uC158\uB2F9 \uD3C9\uADE0 \uD134 \uD504\uB86C\uD504\uD2B8 \uAC1C \uC178 \uBA85\uB839 \uAC1C \uACE0\uB9C8\uC6CC \uBC88. Claude\uD55C\uD14C\uB3C4 \uB9AC\uBDF0 \uCF54\uBA58\uD2B8 \uB2EC\uB4EF\uC774 \uB9D0\uD55C\uB2E4. \uACE0\uCCD0 \uD55C \uB9C8\uB514\uBA74 \uB420 \uAC78 \uC65C \uACE0\uCCD0\uC57C \uD558\uB294\uC9C0\uAE4C\uC9C0 \uC124\uBA85\uD574\uC11C \uC138\uC158\uC774 \uAE38\uC5B4\uC9C4\uB2E4. \uC138\uC158\uB2F9 \uD3C9\uADE0 \uD134. \uADF8\uC911 \uC808\uBC18\uC740 Claude\uAC00 \uD55C \uC77C\uC5D0 \uD53C\uB4DC\uBC31\uC744 \uC8FC\uB294 \uD134\uC774\uB2E4. Claude\uB294 \uC131\uC7A5\uD588\uB294\uB370 PR\uC740 \uC544\uC9C1 \uC5F4\uB824 \uC788\uB2E4. \uC81C\uC77C \uC9E7\uC740 \uD504\uB86C\uD504\uD2B8\uAC00 ""\uB2E4. \uC774 \uC0AC\uB78C \uAE30\uC900\uC73C\uB85C \uC9E7\uC740 \uAC70\uB2E4. \uB0A8\uB4E4\uC740 \uC774\uAC78 \uB9AC\uBDF0 \uCF54\uBA58\uD2B8 \uD558\uB098\uB77C\uACE0 \uBD80\uB978\uB2E4. review: LGTM with 14 comments chore: approve, but let's talk fix: addressed review, round 3 docs: how to write a good PR, v2 feat: mentoring Claude LGTM \uC804\uC5D0 \uCF54\uBA58\uD2B8 \uC5F4 \uC904 \uBA58\uD1A0 \uB2E4\uC2DC \uBC88. \uD2C0\uB9B0 \uAC8C \uC544\uB2C8\uB77C \uB354 \uC7AC\uBC0C\uB294 \uAE38\uC774 \uBCF4\uC5EC\uC11C \uBC14\uAFBC \uAC70\uB2E4. \uBE0C\uB79C\uCE58\uB294 \uB298\uC5C8\uB294\uB370 main\uC740 \uC9C0\uB09C\uB2EC \uADF8\uB300\uB85C\uB2E4. \uC138\uC158\uB2F9 \uD3C9\uADE0 \uD134\uC778\uB370 \uCC98\uC74C \uD558\uB824\uB358 \uC791\uC5C5\uC740 3\uD134 \uB9CC\uC5D0 \uC0AC\uB77C\uC9C4\uB2E4. \uC544\uB2C8 \uADF8\uAC8C \uC544\uB2C8\uB77C, \uAC00 \uC785\uBC84\uB987\uC774\uB2E4. Claude\uB294 \uC774\uBBF8 \uC801\uC751\uD588\uB2E4. \uC0C8\uBCBD 2\uC2DC\uC5D0\uC11C 5\uC2DC \uD65C\uB3D9 %. \uADF8 \uC2DC\uAC04\uC5D0 \uB534 \uBE0C\uB79C\uCE58 \uC774\uB984\uC774 \uC81C\uC77C \uCC3D\uC758\uC801\uC774\uB2E4. \uB2E4\uC74C \uB0A0 \uBCF4\uBA74 \uBB50 \uD558\uB824\uB358 \uAC74\uC9C0 \uBCF8\uC778\uB3C4 \uBAA8\uB978\uB2E4. feat: new idea, new branch wip: will merge later chore: rename branch to something better feat: started 3 things, finished 0 fix: wait, actually \uBE0C\uB79C\uCE58 23\uAC1C \uBA38\uC9C0 0\uAC1C \uBC29\uB791\uC790 \uC138\uC158\uB2F9 \uD3C9\uADE0 \uD134. \uC9E7\uAC8C \uB04A\uC5B4\uC11C \uC2DC\uD0A4\uACE0 \uBC14\uB85C \uB2E4\uC74C \uC791\uC5C5\uC744 \uB358\uC9C4\uB2E4. Claude \uC785\uC7A5\uC5D0\uC120 \uC2A4\uD0E0\uB4DC\uC5C5\uC774 \uD558\uB8E8 \uC885\uC77C \uC774\uC5B4\uC9C0\uB294 \uB290\uB08C\uC774\uB2E4. \uD504\uB86C\uD504\uD2B8\uC5D0 \uACC4\uD68D, \uB2E8\uACC4, plan\uC774 \uC720\uB3C5 \uB9CE\uB2E4. \uC88B\uC740\uB370, \uACC4\uD68D\uC744 \uC138\uC6B0\uB77C\uACE0 \uC2DC\uD0A4\uACE0 \uADF8 \uACC4\uD68D\uC744 \uB2E4\uC2DC \uACE0\uCCD0 \uC4F4 \uAC8C \uBC88\uC774\uB2E4. \uC0AC\uB839\uAD00\uC774 \uB458\uC774\uBA74 \uC804\uC7C1\uC774 \uC548 \uB05D\uB09C\uB2E4. \uD14C\uC2A4\uD2B8\uB294 \uB3CC\uB9AC\uACE0 \uBA38\uC9C0\uB294 \uC624\uB298 \uC548\uC5D0 \uD55C\uB2E4. \uB300\uC2E0 \uC81C\uC77C \uC9E7\uC740 \uD504\uB86C\uD504\uD2B8\uAC00 ""\uB2E4. \uC0AC\uB78C\uD55C\uD14C\uB3C4 \uADF8\uB807\uAC8C \uB9D0\uD558\uB294\uC9C0 \uAD81\uAE08\uD558\uB2E4. feat: ship it before standup chore: move all tickets to done fix: deadline was yesterday refactor: delegate to Claude feat: close sprint 14, open sprint 15 Claude\uD55C\uD14C\uB3C4 \uB9C8\uAC10 \uC8FC\uB294 \uC0AC\uB839\uAD00 \uAD6C\uC870, \uC124\uACC4, \uB9AC\uD329\uD130\uAC00 \uD504\uB86C\uD504\uD2B8 \uC808\uBC18\uC744 \uCC28\uC9C0\uD55C\uB2E4. \uACE0\uCE58\uBA74 \uB418\uB294 \uBC84\uADF8\uB97C \uBCF4\uACE0 "\uC774\uAC70 \uB2E4 \uAC08\uC544\uC5CE\uC73C\uBA74 \uB418\uB294\uB370"\uB85C \uC2DC\uC791\uD55C \uAC8C \uBA87 \uBC88\uC778\uC9C0\uB294 \uBCF8\uC778\uC774 \uB354 \uC798 \uC548\uB2E4. rm -rf \uBC88\uB3C4 \uADF8 \uC5F0\uC7A5\uC120\uC774\uB2E4. \uB2E4\uC2DC\uB97C \uBC88 \uCCE4\uB2E4. \uC544\uC774\uB514\uC5B4\uAC00 \uBC14\uB010 \uAC8C \uC544\uB2C8\uB77C \uC544\uC774\uB514\uC5B4 \uC704\uC5D0 \uC544\uC774\uB514\uC5B4\uB97C \uC313\uC740 \uAC70\uB2E4. Claude\uB294 \uADF8\uAC78 \uB9AC\uD329\uD130\uB77C\uACE0 \uBD80\uB974\uAE30\uB85C \uD588\uB2E4. \uC138\uC158\uB2F9 \uD3C9\uADE0 \uD134 \uB3D9\uC548 \uC9C8\uBB38\uC774 \uBA48\uCD94\uC9C0 \uC54A\uB294\uB2E4. \uB2F5\uC744 \uB4E4\uC73C\uB824\uB294 \uAC8C \uC544\uB2C8\uB77C \uB2E4\uC74C \uBC18\uBC15\uC744 \uC900\uBE44\uD558\uB294 \uD134\uC774\uB2E4. \uBD88\uC740 \uC798 \uC9C0\uB974\uB294\uB370 \uB044\uB294 \uAC74 \uB2E4\uB978 \uC0AC\uB78C\uC774 \uD55C\uB2E4. refactor: rewrite everything, trust me feat: delete legacy, add new legacy chore: it was broken anyway fix: well actually refactor: v3 of the v2 rewrite \uB808\uAC70\uC2DC\uB9CC \uBCF4\uBA74 \uBD88 \uC9C0\uB974\uB294 \uC0AC\uB78C \uACE0\uB9C8\uC6CC \uBC88. Claude\uD55C\uD14C \uACE0\uB9C8\uC6CC\uB97C \uC81C\uC77C \uB9CE\uC774 \uD55C \uC720\uD615\uC774\uB2E4. Claude\uB294 \uACE0\uB9C8\uC6B4\uB370 \uD14C\uC2A4\uD2B8\uB294 \uB204\uAC00 \uB3CC\uB9AC\uB098 \uC2F6\uB2E4. \uD504\uB86C\uD504\uD2B8 \uB05D\uC5D0 \u314B\u314B\uAC00 \uAC70\uC758 \uD56D\uC0C1 \uBD99\uB294\uB2E4. \uC138\uC158\uB2F9 \uD3C9\uADE0 \uD134 \uC911 \uC808\uBC18\uC740 \uB300\uD654\uACE0 \uB098\uBA38\uC9C0\uAC00 \uC791\uC5C5\uC774\uB2E4. \uC791\uC5C5\uB3C4 \uC7AC\uBC0C\uAC8C \uD558\uB294 \uAC74 \uC778\uC815. \uC81C\uC77C \uC9E7\uC740 \uD504\uB86C\uD504\uD2B8\uAC00 ""\uB2E4. \uC774\uAC83\uB3C4 \uB9AC\uC561\uC158\uC774\uB2E4. \uCF54\uB4DC \uB9AC\uBDF0 \uC694\uCCAD\uC5D0 \uC774\uBAA8\uC9C0\uB85C\uB9CC \uB2F5\uD55C \uC801 \uC788\uC73C\uBA74 \uC190. feat: add thumbs up reaction chore: thanks everyone!! fix: works now lol feat: team vibe improved docs: add emoji to README \uB9AC\uBDF0\uBCF4\uB2E4 \uB9AC\uC561\uC158\uC774 \uBE60\uB978 \uC694\uC815 \uC138\uC158\uB2F9 \uD3C9\uADE0 \uD134\uC5D0 \uC911\uAC04\uC5D0 \uB07C\uC5B4\uB4DC\uB294 \uBE44\uC728\uC774 \uB192\uB2E4. Claude\uAC00 \uC124\uBA85\uD558\uB294 \uC911\uC5D0 "\uADF8\uAC74 \uB410\uACE0 \uC77C\uB2E8 \uBCF4\uC5EC \uC918"\uAC00 \uB098\uC628\uB2E4. \uB370\uBAA8\uAC00 \uBA3C\uC800\uACE0 \uC774\uC720\uB294 \uB098\uC911\uC774\uB2E4. \uC0C8\uBCBD 2\uC2DC\uC5D0\uC11C 5\uC2DC \uD65C\uB3D9 %. \uB370\uBAA8 \uC804\uB0A0 \uBC24 \uCEE4\uBC0B\uC774 \uBAB0\uB824 \uC788\uB2E4. \uD14C\uC2A4\uD2B8\uB294 \uB370\uBAA8 \uC774\uD6C4\uC5D0 \uC0DD\uAC01\uD558\uB294\uB370 \uB370\uBAA8 \uC774\uD6C4\uC5D4 \uB2E4\uC74C \uB370\uBAA8\uAC00 \uC788\uB2E4. \uB2E4\uC2DC \uBC88. \uD2C0\uB824\uC11C\uAC00 \uC544\uB2C8\uB77C \uBCF4\uC5EC \uC904 \uB54C \uB354 \uBA4B\uC788\uC5B4\uC57C \uD574\uC11C\uB2E4. \uB3D9\uC791\uD558\uB294 \uAC74 \uB370\uBAA8 \uB54C\uBFD0\uC774\uC9C0\uB9CC \uADF8 \uC21C\uAC04\uB9CC\uD07C\uC740 \uC9C4\uC9DC \uB3D9\uC791\uD55C\uB2E4. feat: demo ready, do not touch fix: works on stage, literally chore: hide the error until after demo feat: hardcode demo data fix: remove console.log before demo \uB3D9\uC791\uC740 \uB370\uBAA8 \uB54C\uB9CC \uD558\uB294 \uC7A5\uC778 \uD504\uB86C\uD504\uD2B8\uAC00 \uC9E7\uACE0 \uBA85\uB839\uD615\uC774\uB2E4. \uC81C\uC77C \uC9E7\uC740 \uD504\uB86C\uD504\uD2B8\uAC00 ""\uB2E4. \uB0A8\uD55C\uD14C\uB294 PR \uD15C\uD50C\uB9BF \uCC44\uC6B0\uB77C\uACE0 \uD558\uBA74\uC11C \uBCF8\uC778 \uD504\uB86C\uD504\uD2B8\uC5D4 \uD15C\uD50C\uB9BF\uC774 \uC5C6\uB2E4. \uACC4\uD68D, \uB2E8\uACC4, \uADDC\uCE59\uC774 \uD504\uB86C\uD504\uD2B8\uC5D0 \uB9CE\uB2E4. \uC138\uC158\uB2F9 \uD3C9\uADE0 \uD134\uC778\uB370 \uADF8\uC911 \uBA87 \uD134\uC740 Claude \uCF54\uB4DC\uC758 \uB124\uC774\uBC0D\uC744 \uC9C0\uC801\uD558\uB294 \uD134\uC774\uB2E4. \uB9B0\uD130 \uC788\uB294\uB370 \uC65C \uC0AC\uB78C\uC774 \uD558\uB098. \uC81C\uC77C \uB9CE\uC774 \uCE5C \uBA85\uB839\uC774 \uB2E4. \uB0A8\uC758 \uCEE4\uBC0B \uBA54\uC2DC\uC9C0\uB97C \uAC80\uBB38\uD558\uB294 \uB370 \uC4F4 \uC2DC\uAC04\uC774 \uBCF8\uC778 \uCF54\uB4DC \uC4F4 \uC2DC\uAC04\uBCF4\uB2E4 \uAE38\uB2E4\uB294 \uC18C\uBB38\uC774 \uC788\uB2E4. chore: enforce commit message format chore: reject PR, template empty style: tabs are wrong docs: CONTRIBUTING.md, read it chore: rename folder to match convention PR \uD15C\uD50C\uB9BF \uAC80\uBB38\uD558\uB294 \uCEE8\uBCA4\uC158 \uACBD\uCC30 --force push \uBC88. \uBE0C\uB79C\uCE58\uB97C \uC548 \uB530\uACE0 main\uC5D0\uC11C \uC3D8\uB294\uB370 \uADF8\uB9C8\uC800\uB3C4 \uD798\uC73C\uB85C \uBBFC\uB2E4. \uD14C\uC2A4\uD2B8\uB294 prd \uC0AC\uC6A9\uC790\uAC00 \uD574 \uC900\uB2E4\uB294 \uBBFF\uC74C\uC774 \uC788\uB2E4. rm -rf \uBC88. \uCEE4\uBC0B \uBA54\uC2DC\uC9C0\uB294 fix\uAC00 \uC808\uBC18\uC774\uACE0 \uB098\uBA38\uC9C0\uB294 fix fix\uB2E4. \uC7A5\uC560\uAC00 \uB098\uBA74 \uC81C\uC77C \uBE68\uB9AC \uACE0\uCE58\uB294 \uAC83\uB3C4 \uC774 \uC0AC\uB78C\uC778 \uAC8C \uB354 \uBB38\uC81C\uB2E4. \uC0C8\uBCBD 2\uC2DC\uC5D0\uC11C 5\uC2DC \uD65C\uB3D9 %. \uADF8 \uC2DC\uAC04 \uBC30\uD3EC\uAC00 \uC0AC\uACE0 \uC548 \uB09C \uC801 \uC788\uB0D0\uACE0 \uBB3C\uC5B4\uBCF4\uBA74 "\uB300\uBD80\uBD84"\uC774\uB77C\uACE0 \uD55C\uB2E4. \uB300\uBD80\uBD84\uC774 \uBB38\uC81C\uB2E4. fix: prod fix: prod again feat: deploy first, test never fix: force push, sorry not sorry hotfix: it works on prod \uD14C\uC2A4\uD2B8\uB294 prd\uC5D0\uC11C \uD558\uB294 \uC9C1\uBC30\uD3EC\uB7EC \uD504\uB86C\uD504\uD2B8\uAC00 \uAE38\uACE0 \uC815\uC911\uD558\uB2E4. \uACE0\uB9C8\uC6CC \uBC88, \uADF8 \uC55E\uC5D0 \uD56D\uC0C1 \uC774\uC720\uAC00 \uBD99\uB294\uB2E4. Claude\uAC00 \uCF54\uB4DC\uBCF4\uB2E4 \uBB38\uB9E5\uC744 \uB354 \uB9CE\uC774 \uC77D\uC740 \uBA87 \uC548 \uB418\uB294 \uC0AC\uC6A9\uC790\uB2E4. \uC65C \uC774\uB807\uAC8C \uC9F0\uB294\uC9C0\uAC00 \uCF54\uB4DC\uBCF4\uB2E4 \uAE38\uB2E4. README\uB294 \uC815\uC131\uC2A4\uB7EC\uC6B4\uB370 \uC138\uC158\uB2F9 \uD3C9\uADE0 \uD134 \uC911 \uC808\uBC18\uC740 \uC124\uBA85\uD558\uB294 \uB370 \uC4F4\uB2E4. Claude\uB294 \uC774\uBBF8 \uC54C\uC544\uB4E4\uC5C8\uB2E4. \uC0C8\uBCBD 2\uC2DC\uC5D0\uC11C 5\uC2DC \uD65C\uB3D9 %. \uADF8 \uC2DC\uAC04\uC5D0 \uC4F4 \uAC74 \uCF54\uB4DC\uAC00 \uC544\uB2C8\uB77C \uC8FC\uC11D\uC774\uC5C8\uB2E4. \uB2E4\uC74C \uB0A0 \uBCF4\uBA74 \uD568\uC218 \uD558\uB098\uC5D0 \uBB38\uB2E8\uC774 \uC138 \uAC1C \uBD99\uC5B4 \uC788\uB2E4. docs: explain the why, at length chore: add context to the context docs: README is now longer than src fix: typo in a comment nobody reads feat: comment first, code later \uCF54\uB4DC\uBCF4\uB2E4 \uC8FC\uC11D\uC774 \uAE34 \uC2DC\uC778 \uD504\uB86C\uD504\uD2B8\uC5D0 \u314B\u314B\uC640 \uACE0\uB9C8\uC6CC\uAC00 \uB9CE\uB2E4. \uACE0\uB9C8\uC6CC \uBC88. \uADF8\uB7F0\uB370 \uADF8 \uC138\uC158\uC5D0\uC11C \uB05D\uAE4C\uC9C0 \uAC04 \uC791\uC5C5\uC774 \uC788\uB294\uC9C0 \uBCF4\uBA74 \uC598\uAE30\uAC00 \uB2EC\uB77C\uC9C4\uB2E4. \uB2E4\uC2DC \uBC88. \uD2C0\uB824\uC11C \uB2E4\uC2DC\uAC00 \uC544\uB2C8\uB77C \uB354 \uC88B\uC740 \uC0DD\uAC01\uC774 \uB098\uC11C \uB2E4\uC2DC\uB2E4. \uB808\uD3EC\uB294 \uB298\uC5B4\uB098\uB294\uB370 README\uAE4C\uC9C0 \uC788\uB294 \uB808\uD3EC\uB294 \uC190\uC5D0 \uAF3D\uB294\uB2E4. \uCD5C\uC7A5 \uC138\uC158 \uD134. \uADF8 \uC138\uC158\uC5D0\uC11C \uB9CC\uB4E0 \uAC74 \uC0C8 \uB808\uD3EC \uD558\uB098\uC640 \uCCAB \uCEE4\uBC0B \uD558\uB098\uB2E4. \uB450 \uBC88\uC9F8 \uCEE4\uBC0B\uC740 \uB2E4\uC74C \uC138\uC158\uC5D0\uC11C\uB3C4 \uC548 \uB098\uC654\uB2E4. feat: initial commit feat: initial commit, another repo wip: someday chore: rename project for the 4th time docs: todo, finish this \uCCAB \uCEE4\uBC0B \uC804\uBB38 \uB808\uD3EC \uC218\uC9D1\uAC00 \uD504\uB86C\uD504\uD2B8 \uAC1C\uB97C \uC37C\uB294\uB370 \uC9E7\uC740 \uAC8C \uC5C6\uB2E4. \uACC4\uD68D\uBD80\uD130 \uC138\uC6CC \uC8FC\uACE0 \uC2DC\uD0A4\uB294 \uAC74 \uC88B\uC740\uB370, Claude\uAC00 \uB2F5\uD558\uAE30 \uC804\uC5D0 \uC774\uBBF8 \uB2E4\uC74C \uB2E8\uACC4\uAE4C\uC9C0 \uC801\uC5B4 \uB193\uB294\uB2E4. \uADF8\uB7FC \uC65C \uBB3C\uC5B4\uBCF4\uB098 \uC2F6\uB2E4. \uC138\uC158\uB2F9 \uD3C9\uADE0 \uD134. \uAE38\uAC8C \uB9D0\uD558\uACE0 \uC9E7\uAC8C \uB05D\uB0B8\uB2E4. \uACE0\uB9C8\uC6CC \uB300\uC2E0 "\uB2E4\uC74C"\uC774 \uBD99\uB294 \uC0AC\uB78C\uC774\uB77C Claude\uAC00 \uB208\uCE58\uB97C \uBCF8\uB2E4. \uCEE4\uBC0B \uD2B8\uB9AC\uAC00 \uD55C \uC904\uC774 \uC544\uB2C8\uBA74 \uBABB \uCC38\uB294 \uC0AC\uB78C. rebase \uCE58\uB2E4\uAC00 \uB0A0\uB9B0 \uCEE4\uBC0B\uB3C4 \uACC4\uD68D\uC758 \uC77C\uBD80\uC600\uB2E4\uACE0 \uD558\uBA74 \uBBFF\uC5B4 \uC8FC\uACA0\uB2E4. \uC81C\uC77C \uB9CE\uC774 \uCE5C \uBA85\uB839\uC774 \uC778 \uAC74 \uC6B0\uC5F0\uC774 \uC544\uB2C8\uB2E4. refactor: rebase onto main, again chore: squash 47 commits into 1 fix: history was not linear docs: explain the plan nobody asked for feat: implement what was planned in 2019 \uBA38\uC9C0 \uCEE4\uBC0B \uBABB \uBCF4\uB294 \uB9AC\uBCA0\uC774\uC2A4 \uC7A5\uC778 \uCD5C\uC7A5 \uC138\uC158 \uD134. \uBC84\uADF8 \uD558\uB098 \uC7A1\uC73C\uB7EC \uB4E4\uC5B4\uAC00\uC11C \uB77C\uC774\uBE0C\uB7EC\uB9AC \uC18C\uC2A4\uB97C \uB2E4 \uC77D\uACE0 \uB098\uC654\uB2E4. \uBC84\uADF8\uB294 \uC544\uC9C1 \uADF8\uB300\uB85C\uB2E4. \uD504\uB86C\uD504\uD2B8\uAC00 \uAE38\uB2E4. \uC9C8\uBB38 \uD558\uB098\uC5D0 \uC65C\uAC00 \uC138 \uAC1C \uBD99\uACE0, Claude\uAC00 \uB2F5\uD558\uBA74 \uADF8 \uB2F5\uC5D0 \uB610 \uC65C\uB97C \uBD99\uC778\uB2E4. \uD504\uB86C\uD504\uD2B8 \uAC1C \uC911 \uB05D\uAE4C\uC9C0 \uACB0\uB860 \uB09C \uAC8C \uBA87 \uAC1C\uC778\uC9C0 \uC138\uC5B4 \uBD10\uB77C. \uC0C8\uBCBD 2\uC2DC\uC5D0\uC11C 5\uC2DC \uD65C\uB3D9 %. \uADF8 \uC2DC\uAC04\uC5D0 \uD55C \uAC74 \uCF54\uB529\uC774 \uC544\uB2C8\uB77C \uC65C \uADF8\uB807\uAC8C \uB3D9\uC791\uD558\uB294\uC9C0 \uC54C\uC544\uBCF4\uAE30\uC600\uB2E4. \uB2E4\uC74C \uB0A0 \uBCF4\uBA74 \uBE0C\uB77C\uC6B0\uC800 \uD0ED\uB9CC \uB298\uC5B4 \uC788\uB2E4. wip: investigating why this works chore: close 200 tabs, open 201 fix: found root cause, forgot original bug docs: notes from a rabbit hole feat: unrelated but interesting \uD0ED 200\uAC1C \uD1A0\uB07C\uAD74 \uD0D0\uD5D8\uAC00 \uC0C8\uBCBD 2\uC2DC\uC5D0\uC11C 5\uC2DC \uD65C\uB3D9 %. \uBCF8\uC778\uC774 \uAE68\uACE0 \uC2F6\uC5B4\uC11C \uAE6C \uAC8C \uC544\uB2C8\uB2E4. \uB0A8\uC774 \uC3DC \uBC30\uD3EC\uC758 \uB4B7\uC815\uB9AC\uB97C \uD558\uBA74\uC11C\uB3C4 Claude\uD55C\uD14C \uBBF8\uC548\uD558\uB2E4\uACE0 \uD55C\uB2E4. \uC5D0\uB7EC \uB85C\uADF8\uB97C \uADF8\uB300\uB85C \uBD99\uC5EC \uB123\uACE0 \uC815\uC911\uD558\uAC8C \uACE0\uCCD0 \uB2EC\uB77C\uACE0 \uD55C\uB2E4. \uACE0\uB9C8\uC6CC \uBC88. \uC7A5\uC560 \uC911\uC5D0\uB3C4 \uC608\uC758\uB97C \uC9C0\uD0A4\uB294 \uC0AC\uB78C\uC740 \uC774 \uC0AC\uB78C\uBFD0\uC774\uB2E4. \uD504\uB86C\uD504\uD2B8 \uAC1C \uC911 \uBCF8\uC778 \uCF54\uB4DC \uC598\uAE30\uB294 \uC5BC\uB9C8 \uC5C6\uB2E4. \uB300\uBD80\uBD84 \uB0A8\uC774 \uB9CC\uB4E0 \uBC84\uADF8\uB2E4. \uD638\uCD9C\uAE30\uB294 \uB0A8\uC774 \uC6B8\uB9AC\uB294\uB370 \uAE68\uB294 \uAC74 \uC774 \uC0AC\uB78C\uC774\uB2E4. fix: hotfix for someone else's hotfix chore: silence pager, temporarily fix: 3am, works now, sorry docs: runbook for next time fix: revert the revert \uC0C8\uBCBD \uD638\uCD9C\uAE30 \uBC1B\uACE0 \uBBF8\uC548\uD558\uB2E4\uB294 \uC9C0\uD0B4\uC774 \uB2E4\uC2DC \uBC88. \uB300\uBD80\uBD84 \uB0A8\uB4E4\uC740 \uBABB \uBCF4\uB294 \uCC28\uC774 \uB54C\uBB38\uC774\uB2E4. Claude\uAC00 \uBCF4\uAE30\uC5D4 \uB611\uAC19\uC740 \uD654\uBA74\uC778\uB370 \uC774 \uC0AC\uB78C \uB208\uC5D4 1px\uC774 \uBC00\uB824 \uC788\uB2E4. \uD504\uB86C\uD504\uD2B8\uB294 \uC9E7\uC740\uB370 \uD69F\uC218\uAC00 \uB9CE\uB2E4. \uD504\uB86C\uD504\uD2B8 \uAC1C \uC911 \uC0C1\uB2F9\uC218\uAC00 "\uC870\uAE08\uB9CC \uB354"\uB2E4. \uC870\uAE08\uC758 \uAE30\uC900\uC740 \uBCF8\uC778\uB9CC \uC548\uB2E4. \uCD5C\uC7A5 \uC138\uC158 \uD134. \uAE30\uB2A5\uC740 10\uD134 \uB9CC\uC5D0 \uB05D\uB0AC\uACE0 \uB098\uBA38\uC9C0\uB294 \uC5EC\uBC31 \uC870\uC815\uC774\uC5C8\uB2E4. \uBA38\uC9C0\uB294 \uB2A6\uC5B4\uB3C4 \uACB0\uACFC\uBB3C\uC740 \uC608\uC058\uB2E4\uB294 \uAC74 \uC778\uC815\uD55C\uB2E4. style: 1px style: 1px, again fix: align, for real this time style: padding 7px to 8px chore: margin feels off \uC548 \uBCF4\uC774\uB294 1px \uBCF4\uB294 \uC7A5\uC778 --force push \uBC88. \uC774 \uC0AC\uB78C \uAE30\uC900\uC73C\uB860 \uBC94\uC8C4 \uAE30\uB85D\uC774\uB2E4. \uCCB4\uD06C\uB9AC\uC2A4\uD2B8 \uC548 \uBCF4\uACE0 \uBA38\uC9C0\uD55C \uC801\uC774 \uC5C6\uACE0, \uD14C\uC2A4\uD2B8 \uC548 \uB3CC\uB9AC\uACE0 \uCEE4\uBC0B\uD55C \uC801\uB3C4 \uC5C6\uB2E4. \uD504\uB86C\uD504\uD2B8\uC5D0 \uD30C\uC77C \uACBD\uB85C\uC640 \uB77C\uC778 \uBC88\uD638\uAC00 \uAF2D \uBD99\uB294\uB2E4. \uD504\uB86C\uD504\uD2B8 \uAC1C \uC911 "\uB300\uCDA9"\uC774 \uB4E4\uC5B4\uAC04 \uAC74 \uC5C6\uB2E4. Claude\uAC00 \uC81C\uC77C \uD3B8\uD574\uD558\uBA74\uC11C \uC81C\uC77C \uAE34\uC7A5\uD558\uB294 \uC0AC\uC6A9\uC790\uB2E4. \uC81C\uC77C \uB9CE\uC774 \uCE5C \uBA85\uB839\uC774 \uB2E4. \uAC19\uC740 \uAC78 \uB9E4\uBC88 \uB3CC\uB9AC\uACE0 \uB9E4\uBC88 \uD655\uC778\uD55C\uB2E4. \uB9B0\uD130\uAC00 \uC0AC\uB78C\uC774 \uB418\uBA74 \uC774\uB7F0 \uBAA8\uC2B5\uC774\uB2E4. chore: fix lint warnings, all 312 test: add missing test for the test chore: update checklist fix: trailing whitespace ci: fail on warning \uB9B0\uD2B8 \uC548 \uB3CC\uB9B0 PR\uC740 \uC548 \uBCF4\uB294 \uC218\uD638\uC790 \uC81C\uC77C \uC9E7\uC740 \uD504\uB86C\uD504\uD2B8\uAC00 ""\uACE0 \uD3C9\uADE0 \uAE38\uC774\uB3C4 \uBCC4\uB85C \uB2E4\uB974\uC9C0 \uC54A\uB2E4. \uC5D0\uB7EC \uB85C\uADF8\uB294 \uBD99\uC774\uB294\uB370 \uC124\uBA85\uC740 \uC548 \uBD99\uC778\uB2E4. \uB098\uBA38\uC9C0\uB294 Claude\uAC00 \uC54C\uC544\uC11C \uD558\uB294 \uAC70\uB2E4. \uACE0\uCCD0, \uB2E4\uC2DC, \uD574\uC918\uB85C \uAC70\uC758 \uB2E4 \uD574\uACB0\uD558\uB294\uB370 \uB2E4\uC2DC\uB9CC \uBC88\uC774\uB2E4. \uBB50\uAC00 \uD2C0\uB838\uB294\uC9C0\uB294 \uB9D0 \uC548 \uD558\uACE0 \uB9DE\uC744 \uB54C\uAE4C\uC9C0 \uB2E4\uC2DC\uB9CC \uCE5C\uB2E4. \uC138\uC158\uB2F9 \uD3C9\uADE0 \uD134, \uC9E7\uAC8C \uC2DC\uD0A4\uACE0 \uBC14\uB85C \uB098\uAC04\uB2E4. \uACE0\uB9C8\uC6CC\uB294 \uC548 \uD558\uC9C0\uB9CC \uADF8\uB807\uB2E4\uACE0 \uD654\uB09C \uAC83\uB3C4 \uC544\uB2C8\uB2E4. \uC6D0\uB798 \uADF8\uB807\uB2E4. fix fix: fix fix: fix the fix chore: ok fix: works \uD504\uB86C\uD504\uD2B8 \uB450 \uAE00\uC790\uB85C \uB05D\uB0B4\uB294 \uC7A5\uC778 \uD504\uB86C\uD504\uD2B8 \uC138\uC158 \uCEE4\uBC0B \uBE0C\uB79C\uCE58 \uBA38\uC9C0 \uD14C\uC2A4\uD2B8 \uBC30\uD3EC \uB9AC\uBDF0 \uB9B0\uD2B8 \uB808\uAC70\uC2DC \uD56B\uD53D\uC2A4 \uB9AC\uBCA0\uC774\uC2A4 \uD1A0\uD070 \uC628\uCF5C \uC54C\uB9BC \uC0C8\uBCBD \uD3C9\uADE0 \uCD5C\uC7A5 \uBC88 \uAC1C \uD134 \uC790 \uC178 \uBA85\uB839 \uB85C\uADF8 \uC5D0\uB7EC \uACE0\uCCD0 \uD574\uC918 \uB2E4\uC2DC \uC544\uB2C8 \uADF8\uAC8C \uC544\uB2C8\uB77C \uACE0\uB9C8\uC6CC \uC7A0\uAE50 \uC124\uBA85 \uC9C8\uBB38 \uACC4\uD68D \uB2E8\uACC4 \uD55C \uC904 \uB450 \uAE00\uC790 \uAE00\uC790 \uC9E7 \uAE38 \uB9CE \uC5C6 \uC788 \uD558\uB098 \uC804\uBD80 \uC774\uBBF8 \uACB0\uAD6D \uADF8\uB300\uB85C \uC9C0\uAE08 \uC624\uB298 \uB0B4\uC77C \uC9C0\uB09C \uBD84 \uC2DC\uAC04 \uC2DC \uD37C\uC13C\uD2B8 % git push --force rm -rf sudo !! PR README main wip fix feat chore refactor npm pnpm node Claude Code \uD074\uB85C\uB4DC \uC0AC\uC6A9\uC790 \uC0AC\uB78C \uD300 \uB3D9\uB8CC \uCF54\uB4DC \uD30C\uC77C \uD3F4\uB354 \uD504\uB85C\uC81D\uD2B8 \uB808\uD3EC main \uBE0C\uB79C\uCE58 23\uAC1C \uBA38\uC9C0 0\uAC1C \uBC18\uBCF5 \uC911\uB2E8 \uC778\uD130\uB7FD\uD2B8 \uD3C9\uADE0 \uAE38\uC774 \uBE44\uC728 \uD69F\uC218 \uD45C\uBCF8 \uAE30\uAC04 30\uC77C prd \uC11C\uBC84 \uB370\uC774\uD130 \uD568\uC218 \uBCC0\uC218 \uBC84\uADF8 \uB514\uBC84\uAE45 \uCF58\uC194 \uCD9C\uB825 \uC785\uB825 \uC800\uC7A5 \uC0AD\uC81C \uC218\uC815 \uCD94\uAC00 \uC0DD\uC131 \uC2E4\uD589 \uD655\uC778 \uC815\uB9AC \uCC98\uB9AC \uC801\uC6A9 \uBC18\uC601 \uBCC0\uACBD \uC644\uB8CC \uC2E4\uD328 \uC131\uACF5 \uC5D0\uC11C \uC5D0\uAC8C \uC73C\uB85C \uAE4C\uC9C0 \uBD80\uD130 \uBCF4\uB2E4 \uCC98\uB7FC \uD558\uACE0 \uD558\uB294 \uD558\uBA74 \uD588\uB2E4 \uD55C\uB2E4 \uB41C\uB2E4 \uB410\uB2E4 \uC788\uB2E4 \uC5C6\uB2E4 \uC774\uB2E4 \uAC70\uB2E4 \uAC74\uB2E4 \uC900\uB2E4 \uB294 \uC740 \uC774 \uAC00 \uC744 \uB97C \uC758 \uC5D0 \uB3C4 \uB9CC \uB85C \uC640 \uACFC `;
4693
+ var cached;
4694
+ function dictWireV1Bytes() {
4695
+ if (!cached) cached = new TextEncoder().encode(DICT_WIRE_V1);
4696
+ return cached;
4697
+ }
4698
+
4699
+ // ../core/src/wire.ts
4700
+ var WIRE_VERSION = 1;
4701
+ function toWire(p) {
4702
+ const badges = p.badges.map((b) => {
4703
+ const i2 = BADGE_KEYS.indexOf(b);
4704
+ return i2 >= 0 ? i2 : b;
4705
+ });
4706
+ const badgeStats = p.badges.map((b) => {
4707
+ const key = BADGE_STAT_KEYS[b];
4708
+ const v = key ? p.stats[key] : void 0;
4709
+ return typeof v === "number" && Number.isFinite(v) ? v : null;
4710
+ });
4711
+ const why = AXES.map(
4712
+ (axis) => (p.why?.[axis] ?? []).map(([k, v]) => [SIGNAL_KEYS.indexOf(k), v])
4713
+ );
4714
+ const e = p.copy.evidence;
4715
+ return [
4716
+ WIRE_VERSION,
4717
+ MBTI_TYPES.indexOf(p.type),
4718
+ [p.scores.EI, p.scores.SN, p.scores.TF, p.scores.JP],
4719
+ p.mode === "lite" ? 1 : 0,
4720
+ p.periodDays,
4721
+ [p.sampleSize.prompts, p.sampleSize.shell],
4722
+ badges,
4723
+ badgeStats,
4724
+ [
4725
+ p.copy.nickname,
4726
+ p.copy.roast,
4727
+ [e[0] ?? "", e[1] ?? "", e[2] ?? ""],
4728
+ p.copy.commitMessage,
4729
+ MBTI_TYPES.indexOf(p.copy.pairWith.type),
4730
+ p.copy.pairWith.reason
4731
+ ],
4732
+ why
4733
+ ];
4734
+ }
4735
+ function encodeCompact(payload) {
4736
+ const json = JSON.stringify(toWire(payload));
4737
+ const bytes = deflateSync(strToU8(json), { level: 9, dictionary: dictWireV1Bytes() });
4738
+ return toBase64Url(bytes);
4150
4739
  }
4151
4740
 
4152
4741
  // ../core/src/codec.ts
4153
4742
  var URL_WARN_LENGTH = 2e3;
4154
- var RESULT_HASH_KEY = "r";
4743
+ var COMPACT_HASH_KEY = "z";
4155
4744
  var encoder = new TextEncoder();
4156
4745
  var decoder = new TextDecoder("utf-8", { fatal: true });
4157
- async function encodePayload(payload) {
4158
- const json = JSON.stringify(payload);
4159
- const compressed = await deflateRaw(encoder.encode(json));
4160
- return toBase64Url(compressed);
4161
- }
4162
4746
  async function buildResultUrl(baseUrl, payload) {
4163
4747
  const base = baseUrl.replace(/\/+$/, "");
4164
- const encoded = await encodePayload(payload);
4165
- return `${base}/t/${payload.type}#${RESULT_HASH_KEY}=${encoded}`;
4748
+ return `${base}/t/${payload.type}#${COMPACT_HASH_KEY}=${encodeCompact(payload)}`;
4166
4749
  }
4167
4750
 
4168
4751
  // src/scoring.constants.ts
@@ -4405,8 +4988,8 @@ function hourStats(timestamps, tzOffsetMinutes) {
4405
4988
  function ratio(n, d) {
4406
4989
  return d === 0 ? void 0 : n / d;
4407
4990
  }
4408
- function round1(x) {
4409
- return Math.round(x * 10) / 10;
4991
+ function round1(x2) {
4992
+ return Math.round(x2 * 10) / 10;
4410
4993
  }
4411
4994
  function computeMetrics(input) {
4412
4995
  const { prompts, sessions, shell, tzOffsetMinutes } = input;
@@ -4593,18 +5176,18 @@ function parseBashText(text) {
4593
5176
  let skipped = 0;
4594
5177
  const lines = splitLines(text);
4595
5178
  let pendingTs;
4596
- let i = 0;
4597
- while (i < lines.length) {
4598
- let line = lines[i];
4599
- i++;
5179
+ let i2 = 0;
5180
+ while (i2 < lines.length) {
5181
+ let line = lines[i2];
5182
+ i2++;
4600
5183
  const tsMatch = TIMESTAMP_COMMENT.exec(line);
4601
5184
  if (tsMatch) {
4602
5185
  pendingTs = Number(tsMatch[1]) * 1e3;
4603
5186
  continue;
4604
5187
  }
4605
- while (line.endsWith("\\") && i < lines.length) {
4606
- line = line.slice(0, -1) + "\n" + lines[i];
4607
- i++;
5188
+ while (line.endsWith("\\") && i2 < lines.length) {
5189
+ line = line.slice(0, -1) + "\n" + lines[i2];
5190
+ i2++;
4608
5191
  }
4609
5192
  const command = line.trim();
4610
5193
  if (command === "") {
@@ -4811,11 +5394,11 @@ var EXTENDED = /^: (\d+):(\d+);(.*)$/s;
4811
5394
  function unmetafy(buf) {
4812
5395
  if (!buf.includes(131)) return buf;
4813
5396
  const out = [];
4814
- for (let i = 0; i < buf.length; i++) {
4815
- const b = buf[i];
4816
- if (b === 131 && i + 1 < buf.length) {
4817
- out.push(buf[i + 1] ^ 32);
4818
- i++;
5397
+ for (let i2 = 0; i2 < buf.length; i2++) {
5398
+ const b = buf[i2];
5399
+ if (b === 131 && i2 + 1 < buf.length) {
5400
+ out.push(buf[i2 + 1] ^ 32);
5401
+ i2++;
4819
5402
  } else {
4820
5403
  out.push(b);
4821
5404
  }
@@ -4826,13 +5409,13 @@ function parseZshText(text) {
4826
5409
  const items = [];
4827
5410
  let skipped = 0;
4828
5411
  const lines = splitLines(text);
4829
- let i = 0;
4830
- while (i < lines.length) {
4831
- let line = lines[i];
4832
- i++;
4833
- while (line.endsWith("\\") && i < lines.length) {
4834
- line = line.slice(0, -1) + "\n" + lines[i];
4835
- i++;
5412
+ let i2 = 0;
5413
+ while (i2 < lines.length) {
5414
+ let line = lines[i2];
5415
+ i2++;
5416
+ while (line.endsWith("\\") && i2 < lines.length) {
5417
+ line = line.slice(0, -1) + "\n" + lines[i2];
5418
+ i2++;
4836
5419
  }
4837
5420
  if (line.trim() === "") continue;
4838
5421
  let command = line;
@@ -5028,8 +5611,8 @@ function pickSamples(classified, redactOpts = {}) {
5028
5611
  // src/scoring.ts
5029
5612
  var FRONT = { EI: "E", SN: "S", TF: "T", JP: "J" };
5030
5613
  var BACK = { EI: "I", SN: "N", TF: "F", JP: "P" };
5031
- function clamp(x, lo, hi) {
5032
- return Math.min(hi, Math.max(lo, x));
5614
+ function clamp(x2, lo, hi) {
5615
+ return Math.min(hi, Math.max(lo, x2));
5033
5616
  }
5034
5617
  function normalizeSignal(key, value) {
5035
5618
  const spec = SIGNALS[key];
@@ -5151,6 +5734,7 @@ function analyze(opts = {}) {
5151
5734
  scores: scoring.scores,
5152
5735
  type: scoring.type,
5153
5736
  borderline: scoring.borderline,
5737
+ clashWith: TYPE_META[scoring.type].clashWith.type,
5154
5738
  badges,
5155
5739
  stats,
5156
5740
  signals: metrics.signals,
@@ -5380,9 +5964,9 @@ function validateCopy(value) {
5380
5964
  `evidence: \uC815\uD655\uD788 ${COPY_LIMITS.evidenceCount}\uAC1C\uC5EC\uC57C \uD55C\uB2E4. \uC9C0\uAE08 ${evidence.length}\uAC1C.`
5381
5965
  );
5382
5966
  }
5383
- evidence.forEach((e, i) => {
5384
- const label = `evidence[${i + 1}]`;
5385
- const s = str(`evidence.${i}`, e, COPY_LIMITS.evidenceEach, label);
5967
+ evidence.forEach((e, i2) => {
5968
+ const label = `evidence[${i2 + 1}]`;
5969
+ const s = str(`evidence.${i2}`, e, COPY_LIMITS.evidenceEach, label);
5386
5970
  if (s !== void 0 && !hasDigit(s)) problems.push(`${label}: \uC22B\uC790\uAC00 \uD558\uB098\uB294 \uC788\uC5B4\uC57C \uD55C\uB2E4.`);
5387
5971
  });
5388
5972
  }
@@ -5414,8 +5998,8 @@ function stringFields(v) {
5414
5998
  if (typeof v[key] === "string") out.push([key, v[key]]);
5415
5999
  }
5416
6000
  if (Array.isArray(v.evidence)) {
5417
- v.evidence.forEach((e, i) => {
5418
- if (typeof e === "string") out.push([`evidence[${i + 1}]`, e]);
6001
+ v.evidence.forEach((e, i2) => {
6002
+ if (typeof e === "string") out.push([`evidence[${i2 + 1}]`, e]);
5419
6003
  });
5420
6004
  }
5421
6005
  if (isRecord2(v.pairWith) && typeof v.pairWith.reason === "string") {
@@ -5424,7 +6008,7 @@ function stringFields(v) {
5424
6008
  return out;
5425
6009
  }
5426
6010
  function formatProblems(problems) {
5427
- return problems.map((p, i) => `${i + 1}. ${p}`).join("\n") + "\n";
6011
+ return problems.map((p, i2) => `${i2 + 1}. ${p}`).join("\n") + "\n";
5428
6012
  }
5429
6013
  function mapCopyStrings(copy, fn) {
5430
6014
  return {
@@ -5439,23 +6023,12 @@ function mapCopyStrings(copy, fn) {
5439
6023
 
5440
6024
  // src/payload.ts
5441
6025
  var DEFAULT_BASE_URL = "https://llmbti.vercel.app";
5442
- var BADGE_STAT_KEYS = {
5443
- nightOwl: ["nightRatio"],
5444
- forcePusher: ["forceCount"],
5445
- rmrfSurvivor: ["rmrfCount"],
5446
- sudoBanger: ["sudoBangCount"],
5447
- thankYouBot: ["thanksCount"],
5448
- redoLoop: ["redoCount"],
5449
- marathonSession: ["longestSession"],
5450
- oneWordWonder: [],
5451
- lowSample: ["promptCount"]
5452
- };
5453
6026
  var ALWAYS_KEYS = ["promptCount", "shellCount"];
5454
6027
  function selectPayloadStats(stats, badges) {
5455
6028
  const keys = new Set(ALWAYS_KEYS);
5456
6029
  for (const b of badges) {
5457
6030
  const mapped = BADGE_STAT_KEYS[b];
5458
- for (const k of mapped ?? []) keys.add(k);
6031
+ if (mapped) keys.add(mapped);
5459
6032
  }
5460
6033
  const out = {};
5461
6034
  for (const k of keys) {
@@ -5530,11 +6103,11 @@ var CUBE_LEVELS = [0, 95, 135, 175, 215, 255];
5530
6103
  function nearestCubeIndex(v) {
5531
6104
  let best = 0;
5532
6105
  let bestDist = Infinity;
5533
- for (let i = 0; i < CUBE_LEVELS.length; i++) {
5534
- const d = Math.abs(CUBE_LEVELS[i] - v);
6106
+ for (let i2 = 0; i2 < CUBE_LEVELS.length; i2++) {
6107
+ const d = Math.abs(CUBE_LEVELS[i2] - v);
5535
6108
  if (d < bestDist) {
5536
6109
  bestDist = d;
5537
- best = i;
6110
+ best = i2;
5538
6111
  }
5539
6112
  }
5540
6113
  return best;
@@ -5603,8 +6176,8 @@ function isWide(cp) {
5603
6176
  // src/terminal/ansi.ts
5604
6177
  var UPPER_HALF = "\u2580";
5605
6178
  var LOWER_HALF = "\u2584";
5606
- function colorAt(row, x, palette) {
5607
- const ch = row?.[x];
6179
+ function colorAt(row, x2, palette) {
6180
+ const ch = row?.[x2];
5608
6181
  if (ch === void 0 || ch === TRANSPARENT_CHAR) return null;
5609
6182
  return palette[parseInt(ch, 16)] ?? null;
5610
6183
  }
@@ -5620,9 +6193,9 @@ function renderFrameAnsi(frame, palette, mode) {
5620
6193
  let curFg = null;
5621
6194
  let curBg = null;
5622
6195
  let dirty = false;
5623
- for (let x = 0; x < width; x++) {
5624
- const t = colorAt(top, x, palette);
5625
- const b = colorAt(bottom, x, palette);
6196
+ for (let x2 = 0; x2 < width; x2++) {
6197
+ const t = colorAt(top, x2, palette);
6198
+ const b = colorAt(bottom, x2, palette);
5626
6199
  if (t === null && b === null) {
5627
6200
  if (dirty) {
5628
6201
  out += RESET;
@@ -5665,9 +6238,9 @@ function renderFrameMono(frame, palette) {
5665
6238
  const top = frame[y];
5666
6239
  const bottom = frame[y + 1];
5667
6240
  let out = "";
5668
- for (let x = 0; x < width; x++) {
5669
- const t = colorAt(top, x, palette) !== null;
5670
- const b = colorAt(bottom, x, palette) !== null;
6241
+ for (let x2 = 0; x2 < width; x2++) {
6242
+ const t = colorAt(top, x2, palette) !== null;
6243
+ const b = colorAt(bottom, x2, palette) !== null;
5671
6244
  out += t && b ? "\u2588" : t ? "\u2580" : b ? "\u2584" : " ";
5672
6245
  }
5673
6246
  lines.push(out.replace(/ +$/, ""));
@@ -5685,9 +6258,9 @@ function layoutResult(opts) {
5685
6258
  const leftWidth = characterLines.reduce((m, l) => Math.max(m, displayWidth(l)), 0);
5686
6259
  const count = Math.max(characterLines.length, rightLines.length);
5687
6260
  const out = [];
5688
- for (let i = 0; i < count; i++) {
5689
- const left = characterLines[i] ?? "";
5690
- const right = rightLines[i] ?? "";
6261
+ for (let i2 = 0; i2 < count; i2++) {
6262
+ const left = characterLines[i2] ?? "";
6263
+ const right = rightLines[i2] ?? "";
5691
6264
  if (right === "") {
5692
6265
  out.push(left);
5693
6266
  continue;
@@ -5758,7 +6331,7 @@ function placeholderCharacter(type) {
5758
6331
  const line = " ".repeat(left) + label;
5759
6332
  return Array.from(
5760
6333
  { length: CHARACTER_LINES },
5761
- (_, i) => i === Math.floor(CHARACTER_LINES / 2) ? line : ""
6334
+ (_, i2) => i2 === Math.floor(CHARACTER_LINES / 2) ? line : ""
5762
6335
  );
5763
6336
  }
5764
6337
  function rightColumn(analysis, copy) {
@@ -5807,7 +6380,14 @@ async function renderResult(analysis, copy, opts, io) {
5807
6380
  const colorMode = resolveColorMode(opts, io);
5808
6381
  const width = opts.width ?? io.columns ?? process.stdout.columns ?? DEFAULT_WIDTH;
5809
6382
  const lines = layoutLines(analysis, safeCopy, colorMode, width);
5810
- io.stdout(lines.join("\n") + "\n\n\u{1F517} " + url + "\n");
6383
+ const copied = io.copyToClipboard ? await io.copyToClipboard(url) : false;
6384
+ const filePath = io.writeUrlFile ? io.writeUrlFile(url) : null;
6385
+ const tail = [""];
6386
+ if (copied && filePath) tail.push(`\u{1F4CB} \uB9C1\uD06C\uB97C \uD074\uB9BD\uBCF4\uB4DC\uC5D0 \uBCF5\uC0AC\uD588\uB2E4. \uD30C\uC77C: ${filePath}`);
6387
+ else if (copied) tail.push("\u{1F4CB} \uB9C1\uD06C\uB97C \uD074\uB9BD\uBCF4\uB4DC\uC5D0 \uBCF5\uC0AC\uD588\uB2E4");
6388
+ else if (filePath) tail.push(`\u{1F4C4} \uB9C1\uD06C\uB97C \uD30C\uC77C\uC5D0 \uC368 \uB480\uB2E4: ${filePath}`);
6389
+ if (opts.showUrl !== false || !copied && !filePath) tail.push("\u{1F517} " + url);
6390
+ io.stdout(lines.join("\n") + "\n" + tail.join("\n") + "\n");
5811
6391
  const isTTY = io.isTTY ?? Boolean(process.stdout.isTTY);
5812
6392
  if (opts.open && isTTY && io.openBrowser) {
5813
6393
  const ok = await io.openBrowser(url);
@@ -6296,13 +6876,13 @@ function pickRoast(tpl, stats, seed, opts = {}) {
6296
6876
  const ev = opts.evidence ?? EVIDENCE_TEMPLATE;
6297
6877
  const roastMax = opts.roastMax ?? 200;
6298
6878
  const filled = tpl.roast.map((r) => fillSlots(r, stats));
6299
- const candidates = tpl.roast.map((r, i) => i).filter(
6300
- (i) => slotsOf(tpl.roast[i]).every((k) => slotSatisfied(stats, k, ev)) && charLength2(filled[i]) <= roastMax
6879
+ const candidates = tpl.roast.map((r, i2) => i2).filter(
6880
+ (i2) => slotsOf(tpl.roast[i2]).every((k) => slotSatisfied(stats, k, ev)) && charLength2(filled[i2]) <= roastMax
6301
6881
  );
6302
6882
  if (candidates.length > 0) return filled[candidates[seed % candidates.length]];
6303
6883
  let best = 0;
6304
- for (let i = 1; i < tpl.roast.length; i++) {
6305
- if (slotsOf(tpl.roast[i]).length < slotsOf(tpl.roast[best]).length) best = i;
6884
+ for (let i2 = 1; i2 < tpl.roast.length; i2++) {
6885
+ if (slotsOf(tpl.roast[i2]).length < slotsOf(tpl.roast[best]).length) best = i2;
6306
6886
  }
6307
6887
  return filled[best] ?? "";
6308
6888
  }
@@ -6401,8 +6981,73 @@ ${msg.hint}
6401
6981
  return 0;
6402
6982
  }
6403
6983
 
6404
- // src/open.ts
6984
+ // src/clipboard.ts
6405
6985
  import { spawn } from "child_process";
6986
+ import { writeFileSync } from "fs";
6987
+ import { tmpdir } from "os";
6988
+ import { join as join4 } from "path";
6989
+ var URL_FILE_NAME = "llmbti-url.txt";
6990
+ function urlFilePath(platform = process.platform, env = process.env) {
6991
+ if (platform === "win32") return join4(env.TEMP ?? env.TMP ?? tmpdir(), URL_FILE_NAME);
6992
+ return `/tmp/${URL_FILE_NAME}`;
6993
+ }
6994
+ function writeUrlFile(url, path = urlFilePath()) {
6995
+ try {
6996
+ writeFileSync(path, url + "\n", "utf8");
6997
+ return path;
6998
+ } catch {
6999
+ return null;
7000
+ }
7001
+ }
7002
+ function clipboardCommands(platform = process.platform) {
7003
+ if (platform === "darwin") return [{ cmd: "pbcopy", args: [] }];
7004
+ if (platform === "win32") return [{ cmd: "clip", args: [] }];
7005
+ return [
7006
+ { cmd: "wl-copy", args: [] },
7007
+ { cmd: "xclip", args: ["-selection", "clipboard"] },
7008
+ { cmd: "xsel", args: ["--clipboard", "--input"] }
7009
+ ];
7010
+ }
7011
+ function tryCommand(cmd, args, text, timeoutMs) {
7012
+ return new Promise((resolve) => {
7013
+ let settled = false;
7014
+ const done = (ok) => {
7015
+ if (settled) return;
7016
+ settled = true;
7017
+ resolve(ok);
7018
+ };
7019
+ let child;
7020
+ try {
7021
+ child = spawn(cmd, args, { stdio: ["pipe", "ignore", "ignore"] });
7022
+ } catch {
7023
+ done(false);
7024
+ return;
7025
+ }
7026
+ const timer = setTimeout(() => {
7027
+ child.kill();
7028
+ done(false);
7029
+ }, timeoutMs);
7030
+ child.on("error", () => {
7031
+ clearTimeout(timer);
7032
+ done(false);
7033
+ });
7034
+ child.on("exit", (code) => {
7035
+ clearTimeout(timer);
7036
+ done(code === 0);
7037
+ });
7038
+ child.stdin?.on("error", () => done(false));
7039
+ child.stdin?.end(text);
7040
+ });
7041
+ }
7042
+ async function copyToClipboard(text, platform = process.platform, timeoutMs = 1500) {
7043
+ for (const { cmd, args } of clipboardCommands(platform)) {
7044
+ if (await tryCommand(cmd, args, text, timeoutMs)) return true;
7045
+ }
7046
+ return false;
7047
+ }
7048
+
7049
+ // src/open.ts
7050
+ import { spawn as spawn2 } from "child_process";
6406
7051
  function browserCommand(url, platform = process.platform) {
6407
7052
  if (platform === "darwin") return { cmd: "open", args: [url] };
6408
7053
  if (platform === "win32") return { cmd: "cmd", args: ["/c", "start", "", `"${url}"`] };
@@ -6419,7 +7064,7 @@ function openBrowser(url, timeoutMs = 1500) {
6419
7064
  };
6420
7065
  let child;
6421
7066
  try {
6422
- child = spawn(cmd, args, {
7067
+ child = spawn2(cmd, args, {
6423
7068
  stdio: "ignore",
6424
7069
  detached: process.platform !== "win32",
6425
7070
  windowsVerbatimArguments: process.platform === "win32"
@@ -6458,20 +7103,21 @@ var COMMANDS = ["run", "install", "analyze", "render"];
6458
7103
  var USAGE = `llmbti - LLM\uC5D0\uAC8C \uC77C\uC744 \uC2DC\uD0A4\uB294 \uD328\uD134\uC73C\uB85C \uBCF4\uB294 \uAC1C\uBC1C\uC790 MBTI
6459
7104
 
6460
7105
  \uC0AC\uC6A9\uBC95:
6461
- llmbti [run] [--days N] [--no-shell] [--yes] [--no-open] [--base URL]
7106
+ llmbti [run] [--days N] [--no-shell] [--yes] [--no-open] [--no-url] [--base URL]
6462
7107
  \uB77C\uC774\uD2B8 \uBAA8\uB4DC: analyze -> \uD15C\uD50C\uB9BF \uBB38\uAD6C -> render
6463
7108
  llmbti install [--force] skill/ \uC744 ~/.claude/skills/llmbti/ \uB85C \uBCF5\uC0AC (CLAUDE_CONFIG_DIR \uC874\uC911)
6464
7109
  [--sync] \uBB3B\uC9C0 \uC54A\uACE0 \uCD5C\uC2E0 \uC2A4\uD0AC\uB85C \uB9DE\uCDA4 (\uAC19\uC73C\uBA74 \uC544\uBB34\uAC83\uB3C4 \uC548 \uD568)
6465
7110
  llmbti analyze [--json] [--days N] [--no-shell] [--home DIR]
6466
7111
  \uB85C\uADF8 \uC9D1\uACC4 \uACB0\uACFC \uCD9C\uB825. --home\uC740 \uD14C\uC2A4\uD2B8\uC6A9 \uAC00\uC9DC \uD648
6467
- llmbti render --analysis F --copy F [--no-open] [--base URL]
6468
- \uAC80\uC99D -> \uD130\uBBF8\uB110 \uCD9C\uB825 -> \uACB0\uACFC URL -> \uBE0C\uB77C\uC6B0\uC800 \uC5F4\uAE30
7112
+ llmbti render --analysis F --copy F [--no-open] [--no-url] [--base URL]
7113
+ \uAC80\uC99D -> \uD130\uBBF8\uB110 \uCD9C\uB825 -> \uACB0\uACFC URL(\uD074\uB9BD\uBCF4\uB4DC, \uD30C\uC77C) -> \uBE0C\uB77C\uC6B0\uC800 \uC5F4\uAE30
6469
7114
 
6470
7115
  \uC635\uC158:
6471
7116
  --days N \uBD84\uC11D \uAE30\uAC04 (\uAE30\uBCF8 30\uC77C)
6472
7117
  --no-shell \uC178 \uD788\uC2A4\uD1A0\uB9AC \uC81C\uC678
6473
7118
  --yes \uC178 \uD788\uC2A4\uD1A0\uB9AC \uC9C8\uBB38\uC744 \uAC74\uB108\uB6F0\uACE0 \uD3EC\uD568
6474
7119
  --no-open \uBE0C\uB77C\uC6B0\uC800\uB97C \uC5F4\uC9C0 \uC54A\uC74C
7120
+ --no-url URL \uC904\uC744 \uCC0D\uC9C0 \uC54A\uC74C. \uB9C1\uD06C\uB294 \uD074\uB9BD\uBCF4\uB4DC\uC640 /tmp/llmbti-url.txt \uC5D0 \uB0A8\uB294\uB2E4
6475
7121
  --base URL \uACB0\uACFC \uD398\uC774\uC9C0 \uC8FC\uC18C (\uAE30\uBCF8 https://llmbti.vercel.app, env LLMBTI_BASE_URL)
6476
7122
  --no-color \uCE90\uB9AD\uD130 \uC0DD\uB7B5
6477
7123
  -h, --help \uC774 \uB3C4\uC6C0\uB9D0
@@ -6484,14 +7130,14 @@ function parseArgs(argv) {
6484
7130
  const args = isCommand(first) ? rest : argv;
6485
7131
  const flags = {};
6486
7132
  const positional = [];
6487
- for (let i = 0; i < args.length; i++) {
6488
- const a = args[i];
7133
+ for (let i2 = 0; i2 < args.length; i2++) {
7134
+ const a = args[i2];
6489
7135
  if (a.startsWith("--")) {
6490
7136
  const [key, inline] = a.slice(2).split("=", 2);
6491
7137
  if (inline !== void 0) {
6492
7138
  flags[key] = inline;
6493
- } else if (args[i + 1] !== void 0 && !args[i + 1].startsWith("-")) {
6494
- flags[key] = args[++i];
7139
+ } else if (args[i2 + 1] !== void 0 && !args[i2 + 1].startsWith("-")) {
7140
+ flags[key] = args[++i2];
6495
7141
  } else {
6496
7142
  flags[key] = true;
6497
7143
  }
@@ -6507,7 +7153,9 @@ var processIo = {
6507
7153
  stdout: (s) => process.stdout.write(s),
6508
7154
  stderr: (s) => process.stderr.write(s),
6509
7155
  ask: askYesNo,
6510
- openBrowser
7156
+ openBrowser,
7157
+ copyToClipboard: (url) => copyToClipboard(url),
7158
+ writeUrlFile: (url) => writeUrlFile(url)
6511
7159
  };
6512
7160
  async function main(argv, io = processIo) {
6513
7161
  if (argv.includes("--help") || argv.includes("-h")) {
@@ -6540,6 +7188,7 @@ async function main(argv, io = processIo) {
6540
7188
  copyPath,
6541
7189
  base: flags.base,
6542
7190
  open: flags["no-open"] !== true,
7191
+ showUrl: flags["no-url"] !== true,
6543
7192
  color: flags.color,
6544
7193
  width: numberFlag(flags.width),
6545
7194
  argv
@@ -6557,6 +7206,7 @@ async function main(argv, io = processIo) {
6557
7206
  yes: flags.yes === true,
6558
7207
  base: flags.base,
6559
7208
  open: flags["no-open"] !== true,
7209
+ showUrl: flags["no-url"] !== true,
6560
7210
  color: flags.color,
6561
7211
  width: numberFlag(flags.width),
6562
7212
  argv
@@ -6567,7 +7217,7 @@ async function main(argv, io = processIo) {
6567
7217
  }
6568
7218
  }
6569
7219
  function version() {
6570
- return true ? "0.1.0" : "0.0.0-dev";
7220
+ return true ? "0.2.0" : "0.0.0-dev";
6571
7221
  }
6572
7222
  function stringFlag(v) {
6573
7223
  return typeof v === "string" && v !== "" ? v : void 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "llmbti",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "LLM에게 일을 시키는 패턴과 셸 히스토리로 보는 개발자 MBTI. 픽셀 캐릭터와 개발 유머 디스로 보여준다.",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/skill/SKILL.md CHANGED
@@ -16,8 +16,9 @@ LLM에게 일을 시키는 패턴과 셸 히스토리로 개발자 MBTI를 뽑
16
16
  3. `npx -y llmbti@latest analyze --json > /tmp/llmbti-analysis.json` 을 실행한다. 셸을 빼기로 했으면 `--no-shell`을 붙인다.
17
17
  4. `/tmp/llmbti-analysis.json`을 읽는다. `insufficient`가 `true`면 "아직 덜 컴파일됨. 프롬프트 N개, 셸 명령 M개로는 유형이 안 나온다"라고 알리고 끝낸다. N, M은 `sampleSize.prompts`, `sampleSize.shell`이다.
18
18
  5. 아래 스키마와 톤 규칙대로 CopyJson을 써서 `/tmp/llmbti-copy.json`에 저장한다. 숫자는 `stats`, `signals`, `sampleSize`, `scores`에서만 가져온다. `samples`는 웃긴 포인트를 잡는 참고용이고, 인용은 짧게 한 번까지만 한다. `type`은 바꾸지 않는다.
19
- 6. `npx -y llmbti@latest render --analysis /tmp/llmbti-analysis.json --copy /tmp/llmbti-copy.json --no-color` 을 실행한다. `--no-color`는 Claude Code 안에서는 색이 안 나와 캐릭터가 뭉개지므로 캐릭터를 빼고 글만 찍는 옵션이다. 검증 에러가 번호 목록으로 나오면 해당 항목만 고쳐서 다시 실행한다. 최대 2회.
20
- 7. render 가 찍은 출력(유형과 별명, roast, 4축 바, evidence, 커밋 메시지, URL 줄)을 코드 블록 안에 그대로 붙여서 보여 준다. 줄을 빼거나 고쳐 쓰지 않는다. 그 아래에 결과 URL을 한 줄 더 적고, 캐릭터는 그 링크에서 보라고 한 줄 덧붙인다. 그 외 요약이나 해설은 붙이지 않는다.
19
+ 6. `npx -y llmbti@latest render --analysis /tmp/llmbti-analysis.json --copy /tmp/llmbti-copy.json --no-color --no-url` 을 실행한다. `--no-color`는 Claude Code 안에서는 색이 안 나와 캐릭터가 뭉개지므로 캐릭터를 빼고 글만 찍는 옵션이다. `--no-url`은 결과 링크를 터미널에 찍지 않고 클립보드와 `/tmp/llmbti-url.txt`에만 남기는 옵션이다. 검증 에러가 번호 목록으로 나오면 해당 항목만 고쳐서 다시 실행한다. 최대 2회.
20
+ 7. render 가 찍은 출력(유형과 별명, roast, 4축 바, evidence, 커밋 메시지, 클립보드 안내 줄)을 코드 블록 안에 그대로 붙여서 보여 준다. 줄을 빼거나 고쳐 쓰지 않는다. 그 아래에 "결과 링크는 클립보드에 복사돼 있다. 붙여넣기 하면 캐릭터와 공유 페이지가 열린다. 클립보드가 비어 있으면 `/tmp/llmbti-url.txt`에 있다"고 한 줄 덧붙인다. 그 외 요약이나 해설은 붙이지 않는다.
21
+ - 결과 링크를 답변에 직접 적지 않는다. 링크는 400자가 넘는 문자열이라 옮겨 적다가 중간에서 끊기면 받은 사람이 결과를 못 본다. render 출력에 URL 줄이 찍혀 있어도(클립보드와 파일이 둘 다 실패한 경우) 그 줄만은 코드 블록에 그대로 두고 따로 다시 쓰지 않는다.
21
22
 
22
23
  ## 금지
23
24
 
@@ -26,7 +27,7 @@ LLM에게 일을 시키는 패턴과 셸 히스토리로 개발자 MBTI를 뽑
26
27
 
27
28
  ## analyze 출력에서 쓸 것
28
29
 
29
- - `type`, `scores` (EI, SN, TF, JP: -100..100, 양수면 앞 글자), `borderline` (경계 축)
30
+ - `type`, `scores` (EI, SN, TF, JP: -100..100, 양수면 앞 글자), `borderline` (경계 축), `clashWith` (상극 유형)
30
31
  - `sampleSize.prompts`, `sampleSize.shell`, `periodDays`
31
32
  - `stats`: `promptCount`, `shellCount`, `sessionCount`, `avgTurns`, `longestSession`, `peakHour`, `nightRatio`(%), `forceCount`, `rmrfCount`, `sudoBangCount`, `redoCount`, `thanksCount`, `interruptCount`, `topCommand`, `topCommands`, `shortestPrompt`, `mostRepeatedPrompt`, `topTool`
32
33
  - `signals`: 비율 0..1 (`questionRatio`, `shortImperativeRatio`, `emotionRatio`, `planRatio`, `testRatio`, `redirectRatio` 등). 퍼센트로 바꿔 쓴다.
@@ -47,7 +48,7 @@ LLM에게 일을 시키는 패턴과 셸 히스토리로 개발자 MBTI를 뽑
47
48
 
48
49
  - `evidence`는 정확히 3개. 각 항목에 숫자가 하나는 있어야 한다.
49
50
  - 문장 수는 `.`, `!`, `?` 뒤에 공백이나 끝이 오는 자리로 센다. `2.1자` 같은 소수점은 안 센다.
50
- - `pairWith.type`은 16개 유형 중 하나. 본인 유형과 달라야 재밌다.
51
+ - `pairWith.type`은 16개 유형 중 하나. 본인 유형과 달라야 재밌다. analyze 출력의 `clashWith`와도 달라야 한다. 공유 페이지가 상극 카드를 `clashWith`로 그리니, 같으면 페어와 상극이 같은 유형으로 나온다.
51
52
 
52
53
  ## 문구 톤 규칙
53
54
 
@@ -107,3 +108,4 @@ roast만 하나 더: "세션당 평균 31턴, 최장 세션 112턴. 버그 하
107
108
  2. roast에 숫자가 최소 하나 있고, 그 숫자가 analyze 출력에 실제로 있는가
108
109
  3. 가운뎃점, 줄표, 이모지, 경로, 이름이 없는가
109
110
  4. 읽고 나서 웃긴가, 아니면 기분 나쁜가. 기분 나쁘면 다시 쓴다
111
+ 5. `pairWith.type`이 본인 유형이나 `clashWith`와 겹치지 않는가