@gethmy/mcp 2.1.1 → 2.1.3

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/cli.js CHANGED
@@ -27083,6 +27083,20 @@ async function assembleContext(options) {
27083
27083
  }
27084
27084
  } catch {}
27085
27085
  }
27086
+ if (candidates.length < 20) {
27087
+ try {
27088
+ const wsResult = await client3.listMemoryEntities({
27089
+ workspace_id: workspaceId,
27090
+ scope: "workspace",
27091
+ limit: 20
27092
+ });
27093
+ if (wsResult.entities?.length > 0) {
27094
+ const existingIds = new Set(candidates.map((c) => c.id));
27095
+ const additional = wsResult.entities.map(mapToContextEntity).filter((e) => !existingIds.has(e.id));
27096
+ candidates.push(...additional);
27097
+ }
27098
+ } catch {}
27099
+ }
27086
27100
  if (candidates.length === 0) {
27087
27101
  return {
27088
27102
  context: "",
@@ -30745,1685 +30759,143 @@ class HarmonyMCPServer {
30745
30759
  }
30746
30760
  }
30747
30761
 
30748
- // src/tui/setup.ts
30749
- import {
30750
- existsSync as existsSync6,
30751
- lstatSync,
30752
- mkdirSync as mkdirSync4,
30753
- symlinkSync,
30754
- unlinkSync
30755
- } from "node:fs";
30756
- import { homedir as homedir4 } from "node:os";
30757
- import { dirname as dirname2, join as join5 } from "node:path";
30762
+ // src/skills.ts
30763
+ import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "node:fs";
30764
+ import { dirname } from "node:path";
30765
+ var SKILLS_VERSION = "3";
30766
+ var VERSION_MARKER_PREFIX = "<!-- skills-version:";
30767
+ var HARMONY_WORKFLOW_PROMPT = `# Harmony Card Workflow
30758
30768
 
30759
- // ../../node_modules/@clack/core/dist/index.mjs
30760
- var import_sisteransi = __toESM(require_src(), 1);
30761
- var import_picocolors = __toESM(require_picocolors(), 1);
30762
- import { stdin as j, stdout as M } from "node:process";
30763
- import * as g from "node:readline";
30764
- import O from "node:readline";
30765
- import { Writable as X } from "node:stream";
30766
- function DD({ onlyFirst: e = false } = {}) {
30767
- const t = ["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?(?:\\u0007|\\u001B\\u005C|\\u009C))", "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))"].join("|");
30768
- return new RegExp(t, e ? undefined : "g");
30769
- }
30770
- var uD = DD();
30771
- function P(e) {
30772
- if (typeof e != "string")
30773
- throw new TypeError(`Expected a \`string\`, got \`${typeof e}\``);
30774
- return e.replace(uD, "");
30775
- }
30776
- function L(e) {
30777
- return e && e.__esModule && Object.prototype.hasOwnProperty.call(e, "default") ? e.default : e;
30778
- }
30779
- var W = { exports: {} };
30780
- (function(e) {
30781
- var u = {};
30782
- e.exports = u, u.eastAsianWidth = function(F) {
30783
- var s = F.charCodeAt(0), i = F.length == 2 ? F.charCodeAt(1) : 0, D = s;
30784
- return 55296 <= s && s <= 56319 && 56320 <= i && i <= 57343 && (s &= 1023, i &= 1023, D = s << 10 | i, D += 65536), D == 12288 || 65281 <= D && D <= 65376 || 65504 <= D && D <= 65510 ? "F" : D == 8361 || 65377 <= D && D <= 65470 || 65474 <= D && D <= 65479 || 65482 <= D && D <= 65487 || 65490 <= D && D <= 65495 || 65498 <= D && D <= 65500 || 65512 <= D && D <= 65518 ? "H" : 4352 <= D && D <= 4447 || 4515 <= D && D <= 4519 || 4602 <= D && D <= 4607 || 9001 <= D && D <= 9002 || 11904 <= D && D <= 11929 || 11931 <= D && D <= 12019 || 12032 <= D && D <= 12245 || 12272 <= D && D <= 12283 || 12289 <= D && D <= 12350 || 12353 <= D && D <= 12438 || 12441 <= D && D <= 12543 || 12549 <= D && D <= 12589 || 12593 <= D && D <= 12686 || 12688 <= D && D <= 12730 || 12736 <= D && D <= 12771 || 12784 <= D && D <= 12830 || 12832 <= D && D <= 12871 || 12880 <= D && D <= 13054 || 13056 <= D && D <= 19903 || 19968 <= D && D <= 42124 || 42128 <= D && D <= 42182 || 43360 <= D && D <= 43388 || 44032 <= D && D <= 55203 || 55216 <= D && D <= 55238 || 55243 <= D && D <= 55291 || 63744 <= D && D <= 64255 || 65040 <= D && D <= 65049 || 65072 <= D && D <= 65106 || 65108 <= D && D <= 65126 || 65128 <= D && D <= 65131 || 110592 <= D && D <= 110593 || 127488 <= D && D <= 127490 || 127504 <= D && D <= 127546 || 127552 <= D && D <= 127560 || 127568 <= D && D <= 127569 || 131072 <= D && D <= 194367 || 177984 <= D && D <= 196605 || 196608 <= D && D <= 262141 ? "W" : 32 <= D && D <= 126 || 162 <= D && D <= 163 || 165 <= D && D <= 166 || D == 172 || D == 175 || 10214 <= D && D <= 10221 || 10629 <= D && D <= 10630 ? "Na" : D == 161 || D == 164 || 167 <= D && D <= 168 || D == 170 || 173 <= D && D <= 174 || 176 <= D && D <= 180 || 182 <= D && D <= 186 || 188 <= D && D <= 191 || D == 198 || D == 208 || 215 <= D && D <= 216 || 222 <= D && D <= 225 || D == 230 || 232 <= D && D <= 234 || 236 <= D && D <= 237 || D == 240 || 242 <= D && D <= 243 || 247 <= D && D <= 250 || D == 252 || D == 254 || D == 257 || D == 273 || D == 275 || D == 283 || 294 <= D && D <= 295 || D == 299 || 305 <= D && D <= 307 || D == 312 || 319 <= D && D <= 322 || D == 324 || 328 <= D && D <= 331 || D == 333 || 338 <= D && D <= 339 || 358 <= D && D <= 359 || D == 363 || D == 462 || D == 464 || D == 466 || D == 468 || D == 470 || D == 472 || D == 474 || D == 476 || D == 593 || D == 609 || D == 708 || D == 711 || 713 <= D && D <= 715 || D == 717 || D == 720 || 728 <= D && D <= 731 || D == 733 || D == 735 || 768 <= D && D <= 879 || 913 <= D && D <= 929 || 931 <= D && D <= 937 || 945 <= D && D <= 961 || 963 <= D && D <= 969 || D == 1025 || 1040 <= D && D <= 1103 || D == 1105 || D == 8208 || 8211 <= D && D <= 8214 || 8216 <= D && D <= 8217 || 8220 <= D && D <= 8221 || 8224 <= D && D <= 8226 || 8228 <= D && D <= 8231 || D == 8240 || 8242 <= D && D <= 8243 || D == 8245 || D == 8251 || D == 8254 || D == 8308 || D == 8319 || 8321 <= D && D <= 8324 || D == 8364 || D == 8451 || D == 8453 || D == 8457 || D == 8467 || D == 8470 || 8481 <= D && D <= 8482 || D == 8486 || D == 8491 || 8531 <= D && D <= 8532 || 8539 <= D && D <= 8542 || 8544 <= D && D <= 8555 || 8560 <= D && D <= 8569 || D == 8585 || 8592 <= D && D <= 8601 || 8632 <= D && D <= 8633 || D == 8658 || D == 8660 || D == 8679 || D == 8704 || 8706 <= D && D <= 8707 || 8711 <= D && D <= 8712 || D == 8715 || D == 8719 || D == 8721 || D == 8725 || D == 8730 || 8733 <= D && D <= 8736 || D == 8739 || D == 8741 || 8743 <= D && D <= 8748 || D == 8750 || 8756 <= D && D <= 8759 || 8764 <= D && D <= 8765 || D == 8776 || D == 8780 || D == 8786 || 8800 <= D && D <= 8801 || 8804 <= D && D <= 8807 || 8810 <= D && D <= 8811 || 8814 <= D && D <= 8815 || 8834 <= D && D <= 8835 || 8838 <= D && D <= 8839 || D == 8853 || D == 8857 || D == 8869 || D == 8895 || D == 8978 || 9312 <= D && D <= 9449 || 9451 <= D && D <= 9547 || 9552 <= D && D <= 9587 || 9600 <= D && D <= 9615 || 9618 <= D && D <= 9621 || 9632 <= D && D <= 9633 || 9635 <= D && D <= 9641 || 9650 <= D && D <= 9651 || 9654 <= D && D <= 9655 || 9660 <= D && D <= 9661 || 9664 <= D && D <= 9665 || 9670 <= D && D <= 9672 || D == 9675 || 9678 <= D && D <= 9681 || 9698 <= D && D <= 9701 || D == 9711 || 9733 <= D && D <= 9734 || D == 9737 || 9742 <= D && D <= 9743 || 9748 <= D && D <= 9749 || D == 9756 || D == 9758 || D == 9792 || D == 9794 || 9824 <= D && D <= 9825 || 9827 <= D && D <= 9829 || 9831 <= D && D <= 9834 || 9836 <= D && D <= 9837 || D == 9839 || 9886 <= D && D <= 9887 || 9918 <= D && D <= 9919 || 9924 <= D && D <= 9933 || 9935 <= D && D <= 9953 || D == 9955 || 9960 <= D && D <= 9983 || D == 10045 || D == 10071 || 10102 <= D && D <= 10111 || 11093 <= D && D <= 11097 || 12872 <= D && D <= 12879 || 57344 <= D && D <= 63743 || 65024 <= D && D <= 65039 || D == 65533 || 127232 <= D && D <= 127242 || 127248 <= D && D <= 127277 || 127280 <= D && D <= 127337 || 127344 <= D && D <= 127386 || 917760 <= D && D <= 917999 || 983040 <= D && D <= 1048573 || 1048576 <= D && D <= 1114109 ? "A" : "N";
30785
- }, u.characterLength = function(F) {
30786
- var s = this.eastAsianWidth(F);
30787
- return s == "F" || s == "W" || s == "A" ? 2 : 1;
30788
- };
30789
- function t(F) {
30790
- return F.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF]/g) || [];
30791
- }
30792
- u.length = function(F) {
30793
- for (var s = t(F), i = 0, D = 0;D < s.length; D++)
30794
- i = i + this.characterLength(s[D]);
30795
- return i;
30796
- }, u.slice = function(F, s, i) {
30797
- textLen = u.length(F), s = s || 0, i = i || 1, s < 0 && (s = textLen + s), i < 0 && (i = textLen + i);
30798
- for (var D = "", C = 0, n = t(F), E = 0;E < n.length; E++) {
30799
- var a = n[E], o = u.length(a);
30800
- if (C >= s - (o == 2 ? 1 : 0))
30801
- if (C + o <= i)
30802
- D += a;
30803
- else
30804
- break;
30805
- C += o;
30806
- }
30807
- return D;
30808
- };
30809
- })(W);
30810
- var tD = W.exports;
30811
- var eD = L(tD);
30812
- var FD = function() {
30813
- return /\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|(?:\uD83E\uDDD1\uD83C\uDFFF\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFC-\uDFFF])|\uD83D\uDC68(?:\uD83C\uDFFB(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))?|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])\uFE0F|\u200D(?:(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D[\uDC66\uDC67])|\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC)?|(?:\uD83D\uDC69(?:\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69]))|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC69(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83E\uDDD1(?:\u200D(?:\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDE36\u200D\uD83C\uDF2B|\uD83C\uDFF3\uFE0F\u200D\u26A7|\uD83D\uDC3B\u200D\u2744|(?:(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\uD83C\uDFF4\u200D\u2620|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])\u200D[\u2640\u2642]|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u2600-\u2604\u260E\u2611\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26B0\u26B1\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0\u26F1\u26F4\u26F7\u26F8\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u3030\u303D\u3297\u3299]|\uD83C[\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]|\uD83D[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3])\uFE0F|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDE35\u200D\uD83D\uDCAB|\uD83D\uDE2E\u200D\uD83D\uDCA8|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83E\uDDD1(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83D\uDC69(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF6\uD83C\uDDE6|\uD83C\uDDF4\uD83C\uDDF2|\uD83D\uDC08\u200D\u2B1B|\u2764\uFE0F\u200D(?:\uD83D\uDD25|\uD83E\uDE79)|\uD83D\uDC41\uFE0F|\uD83C\uDFF3\uFE0F|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|[#\*0-9]\uFE0F\u20E3|\u2764\uFE0F|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|\uD83C\uDFF4|(?:[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270C\u270D]|\uD83D[\uDD74\uDD90])(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC08\uDC15\uDC3B\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE2E\uDE35\uDE36\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5]|\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD]|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF]|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0D\uDD0E\uDD10-\uDD17\uDD1D\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78\uDD7A-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCB\uDDD0\uDDE0-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6]|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDD77\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g;
30814
- };
30815
- var sD = L(FD);
30816
- function p(e, u = {}) {
30817
- if (typeof e != "string" || e.length === 0 || (u = { ambiguousIsNarrow: true, ...u }, e = P(e), e.length === 0))
30818
- return 0;
30819
- e = e.replace(sD(), " ");
30820
- const t = u.ambiguousIsNarrow ? 1 : 2;
30821
- let F = 0;
30822
- for (const s of e) {
30823
- const i = s.codePointAt(0);
30824
- if (i <= 31 || i >= 127 && i <= 159 || i >= 768 && i <= 879)
30825
- continue;
30826
- switch (eD.eastAsianWidth(s)) {
30827
- case "F":
30828
- case "W":
30829
- F += 2;
30830
- break;
30831
- case "A":
30832
- F += t;
30833
- break;
30834
- default:
30835
- F += 1;
30836
- }
30837
- }
30838
- return F;
30839
- }
30840
- var w = 10;
30841
- var N = (e = 0) => (u) => `\x1B[${u + e}m`;
30842
- var I = (e = 0) => (u) => `\x1B[${38 + e};5;${u}m`;
30843
- var R = (e = 0) => (u, t, F) => `\x1B[${38 + e};2;${u};${t};${F}m`;
30844
- var r = { modifier: { reset: [0, 0], bold: [1, 22], dim: [2, 22], italic: [3, 23], underline: [4, 24], overline: [53, 55], inverse: [7, 27], hidden: [8, 28], strikethrough: [9, 29] }, color: { black: [30, 39], red: [31, 39], green: [32, 39], yellow: [33, 39], blue: [34, 39], magenta: [35, 39], cyan: [36, 39], white: [37, 39], blackBright: [90, 39], gray: [90, 39], grey: [90, 39], redBright: [91, 39], greenBright: [92, 39], yellowBright: [93, 39], blueBright: [94, 39], magentaBright: [95, 39], cyanBright: [96, 39], whiteBright: [97, 39] }, bgColor: { bgBlack: [40, 49], bgRed: [41, 49], bgGreen: [42, 49], bgYellow: [43, 49], bgBlue: [44, 49], bgMagenta: [45, 49], bgCyan: [46, 49], bgWhite: [47, 49], bgBlackBright: [100, 49], bgGray: [100, 49], bgGrey: [100, 49], bgRedBright: [101, 49], bgGreenBright: [102, 49], bgYellowBright: [103, 49], bgBlueBright: [104, 49], bgMagentaBright: [105, 49], bgCyanBright: [106, 49], bgWhiteBright: [107, 49] } };
30845
- Object.keys(r.modifier);
30846
- var iD = Object.keys(r.color);
30847
- var CD = Object.keys(r.bgColor);
30848
- [...iD, ...CD];
30849
- function rD() {
30850
- const e = new Map;
30851
- for (const [u, t] of Object.entries(r)) {
30852
- for (const [F, s] of Object.entries(t))
30853
- r[F] = { open: `\x1B[${s[0]}m`, close: `\x1B[${s[1]}m` }, t[F] = r[F], e.set(s[0], s[1]);
30854
- Object.defineProperty(r, u, { value: t, enumerable: false });
30855
- }
30856
- return Object.defineProperty(r, "codes", { value: e, enumerable: false }), r.color.close = "\x1B[39m", r.bgColor.close = "\x1B[49m", r.color.ansi = N(), r.color.ansi256 = I(), r.color.ansi16m = R(), r.bgColor.ansi = N(w), r.bgColor.ansi256 = I(w), r.bgColor.ansi16m = R(w), Object.defineProperties(r, { rgbToAnsi256: { value: (u, t, F) => u === t && t === F ? u < 8 ? 16 : u > 248 ? 231 : Math.round((u - 8) / 247 * 24) + 232 : 16 + 36 * Math.round(u / 255 * 5) + 6 * Math.round(t / 255 * 5) + Math.round(F / 255 * 5), enumerable: false }, hexToRgb: { value: (u) => {
30857
- const t = /[a-f\d]{6}|[a-f\d]{3}/i.exec(u.toString(16));
30858
- if (!t)
30859
- return [0, 0, 0];
30860
- let [F] = t;
30861
- F.length === 3 && (F = [...F].map((i) => i + i).join(""));
30862
- const s = Number.parseInt(F, 16);
30863
- return [s >> 16 & 255, s >> 8 & 255, s & 255];
30864
- }, enumerable: false }, hexToAnsi256: { value: (u) => r.rgbToAnsi256(...r.hexToRgb(u)), enumerable: false }, ansi256ToAnsi: { value: (u) => {
30865
- if (u < 8)
30866
- return 30 + u;
30867
- if (u < 16)
30868
- return 90 + (u - 8);
30869
- let t, F, s;
30870
- if (u >= 232)
30871
- t = ((u - 232) * 10 + 8) / 255, F = t, s = t;
30872
- else {
30873
- u -= 16;
30874
- const C = u % 36;
30875
- t = Math.floor(u / 36) / 5, F = Math.floor(C / 6) / 5, s = C % 6 / 5;
30876
- }
30877
- const i = Math.max(t, F, s) * 2;
30878
- if (i === 0)
30879
- return 30;
30880
- let D = 30 + (Math.round(s) << 2 | Math.round(F) << 1 | Math.round(t));
30881
- return i === 2 && (D += 60), D;
30882
- }, enumerable: false }, rgbToAnsi: { value: (u, t, F) => r.ansi256ToAnsi(r.rgbToAnsi256(u, t, F)), enumerable: false }, hexToAnsi: { value: (u) => r.ansi256ToAnsi(r.hexToAnsi256(u)), enumerable: false } }), r;
30883
- }
30884
- var ED = rD();
30885
- var d = new Set(["\x1B", "›"]);
30886
- var oD = 39;
30887
- var y = "\x07";
30888
- var V = "[";
30889
- var nD = "]";
30890
- var G = "m";
30891
- var _ = `${nD}8;;`;
30892
- var z2 = (e) => `${d.values().next().value}${V}${e}${G}`;
30893
- var K = (e) => `${d.values().next().value}${_}${e}${y}`;
30894
- var aD = (e) => e.split(" ").map((u) => p(u));
30895
- var k = (e, u, t) => {
30896
- const F = [...u];
30897
- let s = false, i = false, D = p(P(e[e.length - 1]));
30898
- for (const [C, n] of F.entries()) {
30899
- const E = p(n);
30900
- if (D + E <= t ? e[e.length - 1] += n : (e.push(n), D = 0), d.has(n) && (s = true, i = F.slice(C + 1).join("").startsWith(_)), s) {
30901
- i ? n === y && (s = false, i = false) : n === G && (s = false);
30902
- continue;
30903
- }
30904
- D += E, D === t && C < F.length - 1 && (e.push(""), D = 0);
30905
- }
30906
- !D && e[e.length - 1].length > 0 && e.length > 1 && (e[e.length - 2] += e.pop());
30907
- };
30908
- var hD = (e) => {
30909
- const u = e.split(" ");
30910
- let t = u.length;
30911
- for (;t > 0 && !(p(u[t - 1]) > 0); )
30912
- t--;
30913
- return t === u.length ? e : u.slice(0, t).join(" ") + u.slice(t).join("");
30914
- };
30915
- var lD = (e, u, t = {}) => {
30916
- if (t.trim !== false && e.trim() === "")
30917
- return "";
30918
- let F = "", s, i;
30919
- const D = aD(e);
30920
- let C = [""];
30921
- for (const [E, a] of e.split(" ").entries()) {
30922
- t.trim !== false && (C[C.length - 1] = C[C.length - 1].trimStart());
30923
- let o = p(C[C.length - 1]);
30924
- if (E !== 0 && (o >= u && (t.wordWrap === false || t.trim === false) && (C.push(""), o = 0), (o > 0 || t.trim === false) && (C[C.length - 1] += " ", o++)), t.hard && D[E] > u) {
30925
- const c = u - o, f = 1 + Math.floor((D[E] - c - 1) / u);
30926
- Math.floor((D[E] - 1) / u) < f && C.push(""), k(C, a, u);
30927
- continue;
30928
- }
30929
- if (o + D[E] > u && o > 0 && D[E] > 0) {
30930
- if (t.wordWrap === false && o < u) {
30931
- k(C, a, u);
30932
- continue;
30933
- }
30934
- C.push("");
30935
- }
30936
- if (o + D[E] > u && t.wordWrap === false) {
30937
- k(C, a, u);
30938
- continue;
30939
- }
30940
- C[C.length - 1] += a;
30941
- }
30942
- t.trim !== false && (C = C.map((E) => hD(E)));
30943
- const n = [...C.join(`
30944
- `)];
30945
- for (const [E, a] of n.entries()) {
30946
- if (F += a, d.has(a)) {
30947
- const { groups: c } = new RegExp(`(?:\\${V}(?<code>\\d+)m|\\${_}(?<uri>.*)${y})`).exec(n.slice(E).join("")) || { groups: {} };
30948
- if (c.code !== undefined) {
30949
- const f = Number.parseFloat(c.code);
30950
- s = f === oD ? undefined : f;
30951
- } else
30952
- c.uri !== undefined && (i = c.uri.length === 0 ? undefined : c.uri);
30953
- }
30954
- const o = ED.codes.get(Number(s));
30955
- n[E + 1] === `
30956
- ` ? (i && (F += K("")), s && o && (F += z2(o))) : a === `
30957
- ` && (s && o && (F += z2(s)), i && (F += K(i)));
30958
- }
30959
- return F;
30960
- };
30961
- function Y(e, u, t) {
30962
- return String(e).normalize().replace(/\r\n/g, `
30963
- `).split(`
30964
- `).map((F) => lD(F, u, t)).join(`
30965
- `);
30966
- }
30967
- var xD = ["up", "down", "left", "right", "space", "enter", "cancel"];
30968
- var B = { actions: new Set(xD), aliases: new Map([["k", "up"], ["j", "down"], ["h", "left"], ["l", "right"], ["\x03", "cancel"], ["escape", "cancel"]]) };
30969
- function $(e, u) {
30970
- if (typeof e == "string")
30971
- return B.aliases.get(e) === u;
30972
- for (const t of e)
30973
- if (t !== undefined && $(t, u))
30974
- return true;
30975
- return false;
30976
- }
30977
- function BD(e, u) {
30978
- if (e === u)
30979
- return;
30980
- const t = e.split(`
30981
- `), F = u.split(`
30982
- `), s = [];
30983
- for (let i = 0;i < Math.max(t.length, F.length); i++)
30984
- t[i] !== F[i] && s.push(i);
30985
- return s;
30986
- }
30987
- var AD = globalThis.process.platform.startsWith("win");
30988
- var S = Symbol("clack:cancel");
30989
- function pD(e) {
30990
- return e === S;
30991
- }
30992
- function m(e, u) {
30993
- const t = e;
30994
- t.isTTY && t.setRawMode(u);
30995
- }
30996
- function fD({ input: e = j, output: u = M, overwrite: t = true, hideCursor: F = true } = {}) {
30997
- const s = g.createInterface({ input: e, output: u, prompt: "", tabSize: 1 });
30998
- g.emitKeypressEvents(e, s), e.isTTY && e.setRawMode(true);
30999
- const i = (D, { name: C, sequence: n }) => {
31000
- const E = String(D);
31001
- if ($([E, C, n], "cancel")) {
31002
- F && u.write(import_sisteransi.cursor.show), process.exit(0);
31003
- return;
31004
- }
31005
- if (!t)
31006
- return;
31007
- const a = C === "return" ? 0 : -1, o = C === "return" ? -1 : 0;
31008
- g.moveCursor(u, a, o, () => {
31009
- g.clearLine(u, 1, () => {
31010
- e.once("keypress", i);
31011
- });
31012
- });
31013
- };
31014
- return F && u.write(import_sisteransi.cursor.hide), e.once("keypress", i), () => {
31015
- e.off("keypress", i), F && u.write(import_sisteransi.cursor.show), e.isTTY && !AD && e.setRawMode(false), s.terminal = false, s.close();
31016
- };
31017
- }
31018
- var gD = Object.defineProperty;
31019
- var vD = (e, u, t) => (u in e) ? gD(e, u, { enumerable: true, configurable: true, writable: true, value: t }) : e[u] = t;
31020
- var h = (e, u, t) => (vD(e, typeof u != "symbol" ? u + "" : u, t), t);
30769
+ Start work on a Harmony card. Card reference: $ARGUMENTS
31021
30770
 
31022
- class x {
31023
- constructor(u, t = true) {
31024
- h(this, "input"), h(this, "output"), h(this, "_abortSignal"), h(this, "rl"), h(this, "opts"), h(this, "_render"), h(this, "_track", false), h(this, "_prevFrame", ""), h(this, "_subscribers", new Map), h(this, "_cursor", 0), h(this, "state", "initial"), h(this, "error", ""), h(this, "value");
31025
- const { input: F = j, output: s = M, render: i, signal: D, ...C } = u;
31026
- this.opts = C, this.onKeypress = this.onKeypress.bind(this), this.close = this.close.bind(this), this.render = this.render.bind(this), this._render = i.bind(this), this._track = t, this._abortSignal = D, this.input = F, this.output = s;
31027
- }
31028
- unsubscribe() {
31029
- this._subscribers.clear();
31030
- }
31031
- setSubscriber(u, t) {
31032
- const F = this._subscribers.get(u) ?? [];
31033
- F.push(t), this._subscribers.set(u, F);
31034
- }
31035
- on(u, t) {
31036
- this.setSubscriber(u, { cb: t });
31037
- }
31038
- once(u, t) {
31039
- this.setSubscriber(u, { cb: t, once: true });
31040
- }
31041
- emit(u, ...t) {
31042
- const F = this._subscribers.get(u) ?? [], s = [];
31043
- for (const i of F)
31044
- i.cb(...t), i.once && s.push(() => F.splice(F.indexOf(i), 1));
31045
- for (const i of s)
31046
- i();
31047
- }
31048
- prompt() {
31049
- return new Promise((u, t) => {
31050
- if (this._abortSignal) {
31051
- if (this._abortSignal.aborted)
31052
- return this.state = "cancel", this.close(), u(S);
31053
- this._abortSignal.addEventListener("abort", () => {
31054
- this.state = "cancel", this.close();
31055
- }, { once: true });
31056
- }
31057
- const F = new X;
31058
- F._write = (s, i, D) => {
31059
- this._track && (this.value = this.rl?.line.replace(/\t/g, ""), this._cursor = this.rl?.cursor ?? 0, this.emit("value", this.value)), D();
31060
- }, this.input.pipe(F), this.rl = O.createInterface({ input: this.input, output: F, tabSize: 2, prompt: "", escapeCodeTimeout: 50, terminal: true }), O.emitKeypressEvents(this.input, this.rl), this.rl.prompt(), this.opts.initialValue !== undefined && this._track && this.rl.write(this.opts.initialValue), this.input.on("keypress", this.onKeypress), m(this.input, true), this.output.on("resize", this.render), this.render(), this.once("submit", () => {
31061
- this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), m(this.input, false), u(this.value);
31062
- }), this.once("cancel", () => {
31063
- this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), m(this.input, false), u(S);
31064
- });
31065
- });
31066
- }
31067
- onKeypress(u, t) {
31068
- if (this.state === "error" && (this.state = "active"), t?.name && (!this._track && B.aliases.has(t.name) && this.emit("cursor", B.aliases.get(t.name)), B.actions.has(t.name) && this.emit("cursor", t.name)), u && (u.toLowerCase() === "y" || u.toLowerCase() === "n") && this.emit("confirm", u.toLowerCase() === "y"), u === "\t" && this.opts.placeholder && (this.value || (this.rl?.write(this.opts.placeholder), this.emit("value", this.opts.placeholder))), u && this.emit("key", u.toLowerCase()), t?.name === "return") {
31069
- if (this.opts.validate) {
31070
- const F = this.opts.validate(this.value);
31071
- F && (this.error = F instanceof Error ? F.message : F, this.state = "error", this.rl?.write(this.value));
31072
- }
31073
- this.state !== "error" && (this.state = "submit");
31074
- }
31075
- $([u, t?.name, t?.sequence], "cancel") && (this.state = "cancel"), (this.state === "submit" || this.state === "cancel") && this.emit("finalize"), this.render(), (this.state === "submit" || this.state === "cancel") && this.close();
31076
- }
31077
- close() {
31078
- this.input.unpipe(), this.input.removeListener("keypress", this.onKeypress), this.output.write(`
31079
- `), m(this.input, false), this.rl?.close(), this.rl = undefined, this.emit(`${this.state}`, this.value), this.unsubscribe();
31080
- }
31081
- restoreCursor() {
31082
- const u = Y(this._prevFrame, process.stdout.columns, { hard: true }).split(`
31083
- `).length - 1;
31084
- this.output.write(import_sisteransi.cursor.move(-999, u * -1));
31085
- }
31086
- render() {
31087
- const u = Y(this._render(this) ?? "", process.stdout.columns, { hard: true });
31088
- if (u !== this._prevFrame) {
31089
- if (this.state === "initial")
31090
- this.output.write(import_sisteransi.cursor.hide);
31091
- else {
31092
- const t = BD(this._prevFrame, u);
31093
- if (this.restoreCursor(), t && t?.length === 1) {
31094
- const F = t[0];
31095
- this.output.write(import_sisteransi.cursor.move(0, F)), this.output.write(import_sisteransi.erase.lines(1));
31096
- const s = u.split(`
31097
- `);
31098
- this.output.write(s[F]), this._prevFrame = u, this.output.write(import_sisteransi.cursor.move(0, s.length - F - 1));
31099
- return;
31100
- }
31101
- if (t && t?.length > 1) {
31102
- const F = t[0];
31103
- this.output.write(import_sisteransi.cursor.move(0, F)), this.output.write(import_sisteransi.erase.down());
31104
- const s = u.split(`
31105
- `).slice(F);
31106
- this.output.write(s.join(`
31107
- `)), this._prevFrame = u;
31108
- return;
31109
- }
31110
- this.output.write(import_sisteransi.erase.down());
31111
- }
31112
- this.output.write(u), this.state === "initial" && (this.state = "active"), this._prevFrame = u;
31113
- }
31114
- }
31115
- }
30771
+ ## 1. Find & Fetch Card
31116
30772
 
31117
- class dD extends x {
31118
- get cursor() {
31119
- return this.value ? 0 : 1;
31120
- }
31121
- get _value() {
31122
- return this.cursor === 0;
31123
- }
31124
- constructor(u) {
31125
- super(u, false), this.value = !!u.initialValue, this.on("value", () => {
31126
- this.value = this._value;
31127
- }), this.on("confirm", (t) => {
31128
- this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = t, this.state = "submit", this.close();
31129
- }), this.on("cursor", () => {
31130
- this.value = !this.value;
31131
- });
31132
- }
31133
- }
31134
- var A;
31135
- A = new WeakMap;
31136
- var kD = Object.defineProperty;
31137
- var $D = (e, u, t) => (u in e) ? kD(e, u, { enumerable: true, configurable: true, writable: true, value: t }) : e[u] = t;
31138
- var H = (e, u, t) => ($D(e, typeof u != "symbol" ? u + "" : u, t), t);
31139
- var SD = class extends x {
31140
- constructor(u) {
31141
- super(u, false), H(this, "options"), H(this, "cursor", 0), this.options = u.options, this.value = [...u.initialValues ?? []], this.cursor = Math.max(this.options.findIndex(({ value: t }) => t === u.cursorAt), 0), this.on("key", (t) => {
31142
- t === "a" && this.toggleAll();
31143
- }), this.on("cursor", (t) => {
31144
- switch (t) {
31145
- case "left":
31146
- case "up":
31147
- this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
31148
- break;
31149
- case "down":
31150
- case "right":
31151
- this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
31152
- break;
31153
- case "space":
31154
- this.toggleValue();
31155
- break;
31156
- }
31157
- });
31158
- }
31159
- get _value() {
31160
- return this.options[this.cursor].value;
31161
- }
31162
- toggleAll() {
31163
- const u = this.value.length === this.options.length;
31164
- this.value = u ? [] : this.options.map((t) => t.value);
31165
- }
31166
- toggleValue() {
31167
- const u = this.value.includes(this._value);
31168
- this.value = u ? this.value.filter((t) => t !== this._value) : [...this.value, this._value];
31169
- }
31170
- };
31171
- var OD = Object.defineProperty;
31172
- var PD = (e, u, t) => (u in e) ? OD(e, u, { enumerable: true, configurable: true, writable: true, value: t }) : e[u] = t;
31173
- var J = (e, u, t) => (PD(e, typeof u != "symbol" ? u + "" : u, t), t);
30773
+ Parse the reference and fetch the card:
30774
+ - \`#42\` or \`42\` → \`harmony_get_card_by_short_id\` with \`shortId: 42\`
30775
+ - UUID \`harmony_get_card\` with \`cardId\`
30776
+ - Name/text → \`harmony_search_cards\` with \`query\`
31174
30777
 
31175
- class LD extends x {
31176
- constructor(u) {
31177
- super(u, false), J(this, "options"), J(this, "cursor", 0), this.options = u.options, this.cursor = this.options.findIndex(({ value: t }) => t === u.initialValue), this.cursor === -1 && (this.cursor = 0), this.changeValue(), this.on("cursor", (t) => {
31178
- switch (t) {
31179
- case "left":
31180
- case "up":
31181
- this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
31182
- break;
31183
- case "down":
31184
- case "right":
31185
- this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
31186
- break;
31187
- }
31188
- this.changeValue();
31189
- });
31190
- }
31191
- get _value() {
31192
- return this.options[this.cursor];
31193
- }
31194
- changeValue() {
31195
- this.value = this._value.value;
31196
- }
31197
- }
31198
- class RD extends x {
31199
- get valueWithCursor() {
31200
- if (this.state === "submit")
31201
- return this.value;
31202
- if (this.cursor >= this.value.length)
31203
- return `${this.value}█`;
31204
- const u = this.value.slice(0, this.cursor), [t, ...F] = this.value.slice(this.cursor);
31205
- return `${u}${import_picocolors.default.inverse(t)}${F.join("")}`;
31206
- }
31207
- get cursor() {
31208
- return this._cursor;
31209
- }
31210
- constructor(u) {
31211
- super(u), this.on("finalize", () => {
31212
- this.value || (this.value = u.defaultValue);
31213
- });
31214
- }
31215
- }
30778
+ ## 2. Get Board State
31216
30779
 
31217
- // ../../node_modules/@clack/prompts/dist/index.mjs
31218
- var import_picocolors2 = __toESM(require_picocolors(), 1);
31219
- var import_sisteransi2 = __toESM(require_src(), 1);
31220
- import y2 from "node:process";
31221
- function ce() {
31222
- return y2.platform !== "win32" ? y2.env.TERM !== "linux" : !!y2.env.CI || !!y2.env.WT_SESSION || !!y2.env.TERMINUS_SUBLIME || y2.env.ConEmuTask === "{cmd::Cmder}" || y2.env.TERM_PROGRAM === "Terminus-Sublime" || y2.env.TERM_PROGRAM === "vscode" || y2.env.TERM === "xterm-256color" || y2.env.TERM === "alacritty" || y2.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
31223
- }
31224
- var V2 = ce();
31225
- var u = (t, n) => V2 ? t : n;
31226
- var le = u("◆", "*");
31227
- var L2 = u("■", "x");
31228
- var W2 = u("▲", "x");
31229
- var C = u("◇", "o");
31230
- var ue = u("┌", "T");
31231
- var o = u("│", "|");
31232
- var d2 = u("└", "—");
31233
- var k2 = u("●", ">");
31234
- var P2 = u("○", " ");
31235
- var A2 = u("◻", "[•]");
31236
- var T = u("◼", "[+]");
31237
- var F = u("◻", "[ ]");
31238
- var $e = u("▪", "•");
31239
- var _2 = u("─", "-");
31240
- var me = u("╮", "+");
31241
- var de = u("├", "+");
31242
- var pe = u("╯", "+");
31243
- var q = u("●", "•");
31244
- var D = u("◆", "*");
31245
- var U = u("▲", "!");
31246
- var K2 = u("■", "x");
31247
- var b2 = (t) => {
31248
- switch (t) {
31249
- case "initial":
31250
- case "active":
31251
- return import_picocolors2.default.cyan(le);
31252
- case "cancel":
31253
- return import_picocolors2.default.red(L2);
31254
- case "error":
31255
- return import_picocolors2.default.yellow(W2);
31256
- case "submit":
31257
- return import_picocolors2.default.green(C);
31258
- }
31259
- };
31260
- var G2 = (t) => {
31261
- const { cursor: n, options: r2, style: i } = t, s = t.maxItems ?? Number.POSITIVE_INFINITY, c = Math.max(process.stdout.rows - 4, 0), a = Math.min(c, Math.max(s, 5));
31262
- let l2 = 0;
31263
- n >= l2 + a - 3 ? l2 = Math.max(Math.min(n - a + 3, r2.length - a), 0) : n < l2 + 2 && (l2 = Math.max(n - 2, 0));
31264
- const $2 = a < r2.length && l2 > 0, g2 = a < r2.length && l2 + a < r2.length;
31265
- return r2.slice(l2, l2 + a).map((p2, v2, f) => {
31266
- const j2 = v2 === 0 && $2, E = v2 === f.length - 1 && g2;
31267
- return j2 || E ? import_picocolors2.default.dim("...") : i(p2, v2 + l2 === n);
31268
- });
31269
- };
31270
- var he = (t) => new RD({ validate: t.validate, placeholder: t.placeholder, defaultValue: t.defaultValue, initialValue: t.initialValue, render() {
31271
- const n = `${import_picocolors2.default.gray(o)}
31272
- ${b2(this.state)} ${t.message}
31273
- `, r2 = t.placeholder ? import_picocolors2.default.inverse(t.placeholder[0]) + import_picocolors2.default.dim(t.placeholder.slice(1)) : import_picocolors2.default.inverse(import_picocolors2.default.hidden("_")), i = this.value ? this.valueWithCursor : r2;
31274
- switch (this.state) {
31275
- case "error":
31276
- return `${n.trim()}
31277
- ${import_picocolors2.default.yellow(o)} ${i}
31278
- ${import_picocolors2.default.yellow(d2)} ${import_picocolors2.default.yellow(this.error)}
31279
- `;
31280
- case "submit":
31281
- return `${n}${import_picocolors2.default.gray(o)} ${import_picocolors2.default.dim(this.value || t.placeholder)}`;
31282
- case "cancel":
31283
- return `${n}${import_picocolors2.default.gray(o)} ${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(this.value ?? ""))}${this.value?.trim() ? `
31284
- ${import_picocolors2.default.gray(o)}` : ""}`;
31285
- default:
31286
- return `${n}${import_picocolors2.default.cyan(o)} ${i}
31287
- ${import_picocolors2.default.cyan(d2)}
31288
- `;
31289
- }
31290
- } }).prompt();
31291
- var ye = (t) => {
31292
- const n = t.active ?? "Yes", r2 = t.inactive ?? "No";
31293
- return new dD({ active: n, inactive: r2, initialValue: t.initialValue ?? true, render() {
31294
- const i = `${import_picocolors2.default.gray(o)}
31295
- ${b2(this.state)} ${t.message}
31296
- `, s = this.value ? n : r2;
31297
- switch (this.state) {
31298
- case "submit":
31299
- return `${i}${import_picocolors2.default.gray(o)} ${import_picocolors2.default.dim(s)}`;
31300
- case "cancel":
31301
- return `${i}${import_picocolors2.default.gray(o)} ${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(s))}
31302
- ${import_picocolors2.default.gray(o)}`;
31303
- default:
31304
- return `${i}${import_picocolors2.default.cyan(o)} ${this.value ? `${import_picocolors2.default.green(k2)} ${n}` : `${import_picocolors2.default.dim(P2)} ${import_picocolors2.default.dim(n)}`} ${import_picocolors2.default.dim("/")} ${this.value ? `${import_picocolors2.default.dim(P2)} ${import_picocolors2.default.dim(r2)}` : `${import_picocolors2.default.green(k2)} ${r2}`}
31305
- ${import_picocolors2.default.cyan(d2)}
31306
- `;
31307
- }
31308
- } }).prompt();
31309
- };
31310
- var ve = (t) => {
31311
- const n = (r2, i) => {
31312
- const s = r2.label ?? String(r2.value);
31313
- switch (i) {
31314
- case "selected":
31315
- return `${import_picocolors2.default.dim(s)}`;
31316
- case "active":
31317
- return `${import_picocolors2.default.green(k2)} ${s} ${r2.hint ? import_picocolors2.default.dim(`(${r2.hint})`) : ""}`;
31318
- case "cancelled":
31319
- return `${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(s))}`;
31320
- default:
31321
- return `${import_picocolors2.default.dim(P2)} ${import_picocolors2.default.dim(s)}`;
31322
- }
31323
- };
31324
- return new LD({ options: t.options, initialValue: t.initialValue, render() {
31325
- const r2 = `${import_picocolors2.default.gray(o)}
31326
- ${b2(this.state)} ${t.message}
31327
- `;
31328
- switch (this.state) {
31329
- case "submit":
31330
- return `${r2}${import_picocolors2.default.gray(o)} ${n(this.options[this.cursor], "selected")}`;
31331
- case "cancel":
31332
- return `${r2}${import_picocolors2.default.gray(o)} ${n(this.options[this.cursor], "cancelled")}
31333
- ${import_picocolors2.default.gray(o)}`;
31334
- default:
31335
- return `${r2}${import_picocolors2.default.cyan(o)} ${G2({ cursor: this.cursor, options: this.options, maxItems: t.maxItems, style: (i, s) => n(i, s ? "active" : "inactive") }).join(`
31336
- ${import_picocolors2.default.cyan(o)} `)}
31337
- ${import_picocolors2.default.cyan(d2)}
31338
- `;
31339
- }
31340
- } }).prompt();
31341
- };
31342
- var fe = (t) => {
31343
- const n = (r2, i) => {
31344
- const s = r2.label ?? String(r2.value);
31345
- return i === "active" ? `${import_picocolors2.default.cyan(A2)} ${s} ${r2.hint ? import_picocolors2.default.dim(`(${r2.hint})`) : ""}` : i === "selected" ? `${import_picocolors2.default.green(T)} ${import_picocolors2.default.dim(s)} ${r2.hint ? import_picocolors2.default.dim(`(${r2.hint})`) : ""}` : i === "cancelled" ? `${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(s))}` : i === "active-selected" ? `${import_picocolors2.default.green(T)} ${s} ${r2.hint ? import_picocolors2.default.dim(`(${r2.hint})`) : ""}` : i === "submitted" ? `${import_picocolors2.default.dim(s)}` : `${import_picocolors2.default.dim(F)} ${import_picocolors2.default.dim(s)}`;
31346
- };
31347
- return new SD({ options: t.options, initialValues: t.initialValues, required: t.required ?? true, cursorAt: t.cursorAt, validate(r2) {
31348
- if (this.required && r2.length === 0)
31349
- return `Please select at least one option.
31350
- ${import_picocolors2.default.reset(import_picocolors2.default.dim(`Press ${import_picocolors2.default.gray(import_picocolors2.default.bgWhite(import_picocolors2.default.inverse(" space ")))} to select, ${import_picocolors2.default.gray(import_picocolors2.default.bgWhite(import_picocolors2.default.inverse(" enter ")))} to submit`))}`;
31351
- }, render() {
31352
- const r2 = `${import_picocolors2.default.gray(o)}
31353
- ${b2(this.state)} ${t.message}
31354
- `, i = (s, c) => {
31355
- const a = this.value.includes(s.value);
31356
- return c && a ? n(s, "active-selected") : a ? n(s, "selected") : n(s, c ? "active" : "inactive");
31357
- };
31358
- switch (this.state) {
31359
- case "submit":
31360
- return `${r2}${import_picocolors2.default.gray(o)} ${this.options.filter(({ value: s }) => this.value.includes(s)).map((s) => n(s, "submitted")).join(import_picocolors2.default.dim(", ")) || import_picocolors2.default.dim("none")}`;
31361
- case "cancel": {
31362
- const s = this.options.filter(({ value: c }) => this.value.includes(c)).map((c) => n(c, "cancelled")).join(import_picocolors2.default.dim(", "));
31363
- return `${r2}${import_picocolors2.default.gray(o)} ${s.trim() ? `${s}
31364
- ${import_picocolors2.default.gray(o)}` : ""}`;
31365
- }
31366
- case "error": {
31367
- const s = this.error.split(`
31368
- `).map((c, a) => a === 0 ? `${import_picocolors2.default.yellow(d2)} ${import_picocolors2.default.yellow(c)}` : ` ${c}`).join(`
31369
- `);
31370
- return `${r2 + import_picocolors2.default.yellow(o)} ${G2({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
31371
- ${import_picocolors2.default.yellow(o)} `)}
31372
- ${s}
31373
- `;
31374
- }
31375
- default:
31376
- return `${r2}${import_picocolors2.default.cyan(o)} ${G2({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
31377
- ${import_picocolors2.default.cyan(o)} `)}
31378
- ${import_picocolors2.default.cyan(d2)}
31379
- `;
31380
- }
31381
- } }).prompt();
31382
- };
31383
- var xe = (t = "") => {
31384
- process.stdout.write(`${import_picocolors2.default.gray(d2)} ${import_picocolors2.default.red(t)}
30780
+ Call \`harmony_get_board\` to get columns and labels. From the response:
30781
+ - Find the "In Progress" (or "Progress") column ID
30782
+ - Find the "agent" label ID
31385
30783
 
31386
- `);
31387
- };
31388
- var Se = (t = "") => {
31389
- process.stdout.write(`${import_picocolors2.default.gray(o)}
31390
- ${import_picocolors2.default.gray(d2)} ${t}
30784
+ ## 3. Setup Card for Work
31391
30785
 
31392
- `);
31393
- };
31394
- var M2 = { message: (t = "", { symbol: n = import_picocolors2.default.gray(o) } = {}) => {
31395
- const r2 = [`${import_picocolors2.default.gray(o)}`];
31396
- if (t) {
31397
- const [i, ...s] = t.split(`
31398
- `);
31399
- r2.push(`${n} ${i}`, ...s.map((c) => `${import_picocolors2.default.gray(o)} ${c}`));
31400
- }
31401
- process.stdout.write(`${r2.join(`
31402
- `)}
31403
- `);
31404
- }, info: (t) => {
31405
- M2.message(t, { symbol: import_picocolors2.default.blue(q) });
31406
- }, success: (t) => {
31407
- M2.message(t, { symbol: import_picocolors2.default.green(D) });
31408
- }, step: (t) => {
31409
- M2.message(t, { symbol: import_picocolors2.default.green(C) });
31410
- }, warn: (t) => {
31411
- M2.message(t, { symbol: import_picocolors2.default.yellow(U) });
31412
- }, warning: (t) => {
31413
- M2.warn(t);
31414
- }, error: (t) => {
31415
- M2.message(t, { symbol: import_picocolors2.default.red(K2) });
31416
- } };
31417
- var J2 = `${import_picocolors2.default.gray(o)} `;
31418
- var Y2 = ({ indicator: t = "dots" } = {}) => {
31419
- const n = V2 ? ["◒", "◐", "◓", "◑"] : ["•", "o", "O", "0"], r2 = V2 ? 80 : 120, i = process.env.CI === "true";
31420
- let s, c, a = false, l2 = "", $2, g2 = performance.now();
31421
- const p2 = (m2) => {
31422
- const h2 = m2 > 1 ? "Something went wrong" : "Canceled";
31423
- a && N2(h2, m2);
31424
- }, v2 = () => p2(2), f = () => p2(1), j2 = () => {
31425
- process.on("uncaughtExceptionMonitor", v2), process.on("unhandledRejection", v2), process.on("SIGINT", f), process.on("SIGTERM", f), process.on("exit", p2);
31426
- }, E = () => {
31427
- process.removeListener("uncaughtExceptionMonitor", v2), process.removeListener("unhandledRejection", v2), process.removeListener("SIGINT", f), process.removeListener("SIGTERM", f), process.removeListener("exit", p2);
31428
- }, B2 = () => {
31429
- if ($2 === undefined)
31430
- return;
31431
- i && process.stdout.write(`
31432
- `);
31433
- const m2 = $2.split(`
31434
- `);
31435
- process.stdout.write(import_sisteransi2.cursor.move(-999, m2.length - 1)), process.stdout.write(import_sisteransi2.erase.down(m2.length));
31436
- }, R2 = (m2) => m2.replace(/\.+$/, ""), O2 = (m2) => {
31437
- const h2 = (performance.now() - m2) / 1000, w2 = Math.floor(h2 / 60), I2 = Math.floor(h2 % 60);
31438
- return w2 > 0 ? `[${w2}m ${I2}s]` : `[${I2}s]`;
31439
- }, H2 = (m2 = "") => {
31440
- a = true, s = fD(), l2 = R2(m2), g2 = performance.now(), process.stdout.write(`${import_picocolors2.default.gray(o)}
31441
- `);
31442
- let h2 = 0, w2 = 0;
31443
- j2(), c = setInterval(() => {
31444
- if (i && l2 === $2)
31445
- return;
31446
- B2(), $2 = l2;
31447
- const I2 = import_picocolors2.default.magenta(n[h2]);
31448
- if (i)
31449
- process.stdout.write(`${I2} ${l2}...`);
31450
- else if (t === "timer")
31451
- process.stdout.write(`${I2} ${l2} ${O2(g2)}`);
31452
- else {
31453
- const z3 = ".".repeat(Math.floor(w2)).slice(0, 3);
31454
- process.stdout.write(`${I2} ${l2}${z3}`);
31455
- }
31456
- h2 = h2 + 1 < n.length ? h2 + 1 : 0, w2 = w2 < n.length ? w2 + 0.125 : 0;
31457
- }, r2);
31458
- }, N2 = (m2 = "", h2 = 0) => {
31459
- a = false, clearInterval(c), B2();
31460
- const w2 = h2 === 0 ? import_picocolors2.default.green(C) : h2 === 1 ? import_picocolors2.default.red(L2) : import_picocolors2.default.red(W2);
31461
- l2 = R2(m2 ?? l2), t === "timer" ? process.stdout.write(`${w2} ${l2} ${O2(g2)}
31462
- `) : process.stdout.write(`${w2} ${l2}
31463
- `), E(), s();
31464
- };
31465
- return { start: H2, stop: N2, message: (m2 = "") => {
31466
- l2 = R2(m2 ?? l2);
31467
- } };
31468
- };
30786
+ Execute these in sequence:
30787
+ 1. \`harmony_move_card\` → Move to "In Progress" column
30788
+ 2. \`harmony_add_label_to_card\` Add "agent" label
30789
+ 3. \`harmony_start_agent_session\`:
30790
+ - \`cardId\`: Card UUID
30791
+ - \`agentIdentifier\`: Your agent identifier
30792
+ - \`agentName\`: Your agent name
30793
+ - \`currentTask\`: "Analyzing card requirements"
31469
30794
 
31470
- // src/tui/agents.ts
31471
- import { existsSync as existsSync3 } from "node:fs";
31472
- import { homedir as homedir2 } from "node:os";
31473
- import { join as join3 } from "node:path";
31474
- var AGENT_DEFINITIONS = [
31475
- {
31476
- id: "claude",
31477
- name: "Claude Code",
31478
- description: "Anthropic CLI agent",
31479
- hint: "/hmy <card>",
31480
- globalPaths: [join3(homedir2(), ".claude")],
31481
- localPaths: [".claude"]
31482
- },
31483
- {
31484
- id: "codex",
31485
- name: "Codex",
31486
- description: "OpenAI coding agent",
31487
- hint: "/prompts:hmy <card>",
31488
- globalPaths: [join3(homedir2(), ".codex")],
31489
- localPaths: ["AGENTS.md"]
31490
- },
31491
- {
31492
- id: "cursor",
31493
- name: "Cursor",
31494
- description: "AI-powered IDE",
31495
- hint: "MCP tools available automatically",
31496
- globalPaths: [],
31497
- localPaths: [".cursor", ".cursorrules"]
31498
- },
31499
- {
31500
- id: "windsurf",
31501
- name: "Windsurf",
31502
- description: "Codeium AI IDE",
31503
- hint: "MCP tools available automatically",
31504
- globalPaths: [join3(homedir2(), ".codeium", "windsurf")],
31505
- localPaths: [".windsurf", ".windsurfrules"]
31506
- }
31507
- ];
31508
- function detectAgents(cwd = process.cwd()) {
31509
- return AGENT_DEFINITIONS.map((def) => {
31510
- const globalPath = def.globalPaths.find((p2) => existsSync3(p2)) || null;
31511
- const localPath = def.localPaths.find((p2) => existsSync3(join3(cwd, p2))) || null;
31512
- return {
31513
- id: def.id,
31514
- name: def.name,
31515
- detected: !!(globalPath || localPath),
31516
- globalPath,
31517
- localPath: localPath ? join3(cwd, localPath) : null,
31518
- description: def.description,
31519
- hint: def.hint
31520
- };
31521
- });
31522
- }
30795
+ ## 4. Generate Work Prompt
31523
30796
 
31524
- // src/tui/docs.ts
31525
- import { existsSync as existsSync4, readdirSync as readdirSync2, readFileSync as readFileSync3, statSync } from "node:fs";
31526
- import { isAbsolute, join as join4, resolve, sep as sep2 } from "node:path";
30797
+ Call \`harmony_generate_prompt\` with:
30798
+ - \`cardId\` or \`shortId\` (+ \`projectId\` if using shortId)
30799
+ - \`variant\`: Select based on task:
30800
+ - \`"execute"\` (default) → Clear tasks, bug fixes, well-defined work
30801
+ - \`"analysis"\` → Complex features, unclear requirements
30802
+ - \`"draft"\` → Medium complexity, want feedback first
31527
30803
 
31528
- // src/tui/theme.ts
31529
- var pc = __toESM(require_picocolors(), 1);
31530
- var symbols = {
31531
- harmony: "▲",
31532
- check: "✓",
31533
- cross: "✗",
31534
- bullet: "•",
31535
- arrow: "→",
31536
- arrowRight: "▸",
31537
- dot: "●",
31538
- dotEmpty: "○",
31539
- info: "ℹ",
31540
- warning: "⚠",
31541
- pointer: "❯"
31542
- };
31543
- var colors = {
31544
- brand: (text) => pc.cyan(text),
31545
- brandBold: (text) => pc.bold(pc.cyan(text)),
31546
- success: (text) => pc.green(text),
31547
- error: (text) => pc.red(text),
31548
- warning: (text) => pc.yellow(text),
31549
- info: (text) => pc.blue(text),
31550
- dim: (text) => pc.dim(text),
31551
- bold: (text) => pc.bold(text),
31552
- muted: (text) => pc.gray(text),
31553
- highlight: (text) => pc.cyan(text),
31554
- link: (text) => pc.underline(pc.cyan(text))
31555
- };
31556
- var messages = {
31557
- header: () => {
31558
- return `
31559
- ${colors.brandBold(" HARMONY")}
31560
- ${colors.dim(" Project management for AI agents")}
30804
+ The generated prompt provides role framing, focus areas, subtasks, linked cards, and suggested outputs.
30805
+
30806
+ ## 5. Display Card Summary
30807
+
30808
+ Show the user: Card title, short ID, role, priority, labels, due date, description, and subtasks.
30809
+
30810
+ ## 6. Implement Solution
30811
+
30812
+ Work on the card following the generated prompt's guidance. Update progress at milestones:
30813
+ - \`harmony_update_agent_progress\` with \`progressPercent\` (0-100), \`currentTask\`, \`status\`, \`blockers\`
30814
+
30815
+ **Progress checkpoints:** 20% (exploration), 50% (implementation), 80% (testing), 100% (done)
30816
+
30817
+ ## 7. Complete Work
30818
+
30819
+ When finished:
30820
+ 1. \`harmony_end_agent_session\` with \`status: "completed"\`, \`progressPercent: 100\`
30821
+ 2. \`harmony_move_card\` to "Review" column
30822
+ 3. Summarize accomplishments
30823
+
30824
+ If pausing: \`harmony_end_agent_session\` with \`status: "paused"\`
30825
+
30826
+ ## Key Tools Reference
30827
+
30828
+ **Cards:** \`harmony_get_card\`, \`harmony_get_card_by_short_id\`, \`harmony_search_cards\`, \`harmony_create_card\`, \`harmony_update_card\`, \`harmony_move_card\`, \`harmony_delete_card\`, \`harmony_assign_card\`
30829
+
30830
+ **Subtasks:** \`harmony_create_subtask\`, \`harmony_toggle_subtask\`, \`harmony_delete_subtask\`
30831
+
30832
+ **Labels:** \`harmony_add_label_to_card\`, \`harmony_remove_label_from_card\`, \`harmony_create_label\`
30833
+
30834
+ **Links:** \`harmony_add_link_to_card\`, \`harmony_remove_link_from_card\`, \`harmony_get_card_links\`
30835
+
30836
+ **Board:** \`harmony_get_board\`, \`harmony_list_projects\`, \`harmony_get_context\`, \`harmony_set_project_context\`
30837
+
30838
+ **Sessions:** \`harmony_start_agent_session\`, \`harmony_update_agent_progress\`, \`harmony_end_agent_session\`, \`harmony_get_agent_session\`
30839
+
30840
+ **AI:** \`harmony_generate_prompt\`, \`harmony_process_command\`
31561
30841
  `;
31562
- },
31563
- done: (message) => {
31564
- return `${colors.success(symbols.check)} ${message}`;
31565
- },
31566
- fail: (message) => {
31567
- return `${colors.error(symbols.cross)} ${message}`;
31568
- },
31569
- skip: (message) => {
31570
- return `${colors.dim("-")} ${colors.dim(message)}`;
31571
- },
31572
- step: (number5, total, message) => {
31573
- return `${colors.dim(`[${number5}/${total}]`)} ${message}`;
31574
- },
31575
- fileCreated: (path) => {
31576
- return ` ${colors.success(symbols.check)} ${colors.dim(path)}`;
31577
- },
31578
- fileSkipped: (path) => {
31579
- return ` ${colors.dim(symbols.bullet)} ${colors.dim(path)} ${colors.dim("(exists)")}`;
31580
- },
31581
- fileError: (path, error48) => {
31582
- return ` ${colors.error(symbols.cross)} ${path}: ${colors.error(error48)}`;
31583
- }
31584
- };
31585
- function formatPath(path, homeDir) {
31586
- if (path.startsWith(homeDir)) {
31587
- return `~${path.slice(homeDir.length)}`;
31588
- }
31589
- return path;
31590
- }
30842
+ var HMY_SKILL_CONTENT = `# Harmony Card Workflow
31591
30843
 
31592
- // src/tui/docs.ts
31593
- var IGNORED_DIRS = new Set([
31594
- "node_modules",
31595
- ".git",
31596
- "dist",
31597
- "build",
31598
- ".next",
31599
- ".nuxt",
31600
- ".output",
31601
- ".vercel",
31602
- ".turbo",
31603
- ".cache",
31604
- "coverage",
31605
- ".harmony-worktrees",
31606
- "__pycache__",
31607
- "target",
31608
- "vendor"
31609
- ]);
31610
- function readJson(filePath) {
31611
- try {
31612
- return JSON.parse(readFileSync3(filePath, "utf-8"));
31613
- } catch {
31614
- return null;
31615
- }
31616
- }
31617
- function readText(filePath) {
31618
- try {
31619
- return readFileSync3(filePath, "utf-8");
31620
- } catch {
31621
- return null;
31622
- }
31623
- }
31624
- function listDirs(dirPath) {
31625
- try {
31626
- return readdirSync2(dirPath).filter((entry) => {
31627
- if (IGNORED_DIRS.has(entry) || entry.startsWith("."))
31628
- return false;
31629
- try {
31630
- return statSync(join4(dirPath, entry)).isDirectory();
31631
- } catch {
31632
- return false;
31633
- }
31634
- });
31635
- } catch {
31636
- return [];
31637
- }
31638
- }
31639
- var DIR_DESCRIPTIONS = {
31640
- components: "UI components",
31641
- pages: "Route-level pages",
31642
- routes: "Route-level pages",
31643
- views: "Route-level pages",
31644
- hooks: "Custom hooks",
31645
- lib: "Utilities",
31646
- utils: "Utilities",
31647
- api: "API / server code",
31648
- server: "API / server code",
31649
- contexts: "State management",
31650
- store: "State management",
31651
- stores: "State management",
31652
- types: "Type definitions",
31653
- styles: "Stylesheets",
31654
- public: "Static assets",
31655
- static: "Static assets",
31656
- assets: "Static assets",
31657
- supabase: "Supabase backend",
31658
- functions: "Edge functions",
31659
- packages: "Monorepo packages",
31660
- apps: "Monorepo applications",
31661
- src: "Source code",
31662
- test: "Tests",
31663
- tests: "Tests",
31664
- __tests__: "Tests",
31665
- scripts: "Build / utility scripts",
31666
- config: "Configuration",
31667
- docs: "Documentation",
31668
- migrations: "Database migrations",
31669
- prisma: "Prisma schema & migrations",
31670
- e2e: "End-to-end tests",
31671
- cypress: "Cypress tests"
31672
- };
31673
- function describeDir(name) {
31674
- return DIR_DESCRIPTIONS[name.toLowerCase()] ?? name;
31675
- }
31676
- function scanProject(cwd) {
31677
- let packageManager = null;
31678
- if (existsSync4(join4(cwd, "bun.lock")) || existsSync4(join4(cwd, "bun.lockb"))) {
31679
- packageManager = "bun";
31680
- } else if (existsSync4(join4(cwd, "pnpm-lock.yaml"))) {
31681
- packageManager = "pnpm";
31682
- } else if (existsSync4(join4(cwd, "yarn.lock"))) {
31683
- packageManager = "yarn";
31684
- } else if (existsSync4(join4(cwd, "package.json"))) {
31685
- packageManager = "npm";
31686
- }
31687
- const pkg = readJson(join4(cwd, "package.json"));
31688
- const scripts = pkg && typeof pkg.scripts === "object" && pkg.scripts !== null ? pkg.scripts : {};
31689
- let language = "unknown";
31690
- if (existsSync4(join4(cwd, "tsconfig.json"))) {
31691
- language = "typescript";
31692
- } else if (existsSync4(join4(cwd, "go.mod"))) {
31693
- language = "go";
31694
- } else if (existsSync4(join4(cwd, "Cargo.toml"))) {
31695
- language = "rust";
31696
- } else if (existsSync4(join4(cwd, "setup.py")) || existsSync4(join4(cwd, "pyproject.toml"))) {
31697
- language = "python";
31698
- } else if (pkg) {
31699
- language = "javascript";
31700
- }
31701
- let framework = null;
31702
- if (pkg) {
31703
- const deps = {
31704
- ...typeof pkg.dependencies === "object" ? pkg.dependencies : {},
31705
- ...typeof pkg.devDependencies === "object" ? pkg.devDependencies : {}
31706
- };
31707
- if (deps.next) {
31708
- framework = "next";
31709
- } else if (deps.react && deps.vite) {
31710
- framework = "react+vite";
31711
- } else if (deps.react) {
31712
- framework = "react";
31713
- } else if (deps.vue && deps.vite) {
31714
- framework = "vue+vite";
31715
- } else if (deps.vue && deps.nuxt) {
31716
- framework = "nuxt";
31717
- } else if (deps.vue) {
31718
- framework = "vue";
31719
- } else if (deps.astro) {
31720
- framework = "astro";
31721
- } else if (deps.svelte) {
31722
- framework = "svelte";
31723
- } else if (deps.express) {
31724
- framework = "express";
31725
- } else if (deps.fastify) {
31726
- framework = "fastify";
31727
- } else if (deps.hono) {
31728
- framework = "hono";
31729
- }
31730
- }
31731
- let linter = null;
31732
- if (existsSync4(join4(cwd, "biome.json")) || existsSync4(join4(cwd, "biome.jsonc"))) {
31733
- linter = "biome";
31734
- } else {
31735
- const eslintFiles = [
31736
- ".eslintrc",
31737
- ".eslintrc.js",
31738
- ".eslintrc.cjs",
31739
- ".eslintrc.json",
31740
- ".eslintrc.yml",
31741
- ".eslintrc.yaml",
31742
- "eslint.config.js",
31743
- "eslint.config.mjs",
31744
- "eslint.config.cjs",
31745
- "eslint.config.ts"
31746
- ];
31747
- if (eslintFiles.some((f) => existsSync4(join4(cwd, f)))) {
31748
- linter = "eslint";
31749
- } else {
31750
- const prettierFiles = [
31751
- ".prettierrc",
31752
- ".prettierrc.js",
31753
- ".prettierrc.json",
31754
- ".prettierrc.yml",
31755
- ".prettierrc.yaml",
31756
- "prettier.config.js",
31757
- "prettier.config.mjs"
31758
- ];
31759
- if (prettierFiles.some((f) => existsSync4(join4(cwd, f)))) {
31760
- linter = "prettier";
31761
- }
31762
- }
31763
- }
31764
- let indentStyle = null;
31765
- const biome = readJson(join4(cwd, "biome.json")) ?? readJson(join4(cwd, "biome.jsonc"));
31766
- if (biome) {
31767
- const formatter = biome.formatter;
31768
- if (formatter) {
31769
- const type = formatter.indentStyle === "tab" ? "tab" : "space";
31770
- const width = typeof formatter.indentWidth === "number" ? formatter.indentWidth : 2;
31771
- indentStyle = { type, width };
31772
- }
31773
- }
31774
- if (!indentStyle) {
31775
- const editorConfig = readText(join4(cwd, ".editorconfig"));
31776
- if (editorConfig) {
31777
- const styleMatch = editorConfig.match(/indent_style\s*=\s*(space|tab)/);
31778
- const sizeMatch = editorConfig.match(/indent_size\s*=\s*(\d+)/);
31779
- if (styleMatch) {
31780
- indentStyle = {
31781
- type: styleMatch[1],
31782
- width: sizeMatch ? Number.parseInt(sizeMatch[1], 10) : 2
31783
- };
31784
- }
31785
- }
31786
- }
31787
- const dirs = listDirs(cwd);
31788
- const srcDirs = existsSync4(join4(cwd, "src")) ? listDirs(join4(cwd, "src")) : [];
31789
- const monorepo = existsSync4(join4(cwd, "packages")) || existsSync4(join4(cwd, "apps"));
31790
- const existingDocs = {
31791
- agentsMd: existsSync4(join4(cwd, "AGENTS.md")),
31792
- claudeMd: existsSync4(join4(cwd, "CLAUDE.md")),
31793
- docsDir: existsSync4(join4(cwd, "docs")),
31794
- architectureMd: existsSync4(join4(cwd, "docs", "architecture.md"))
31795
- };
31796
- return {
31797
- packageManager,
31798
- scripts,
31799
- language,
31800
- framework,
31801
- linter,
31802
- indentStyle,
31803
- dirs,
31804
- srcDirs,
31805
- monorepo,
31806
- existingDocs
31807
- };
31808
- }
31809
- function runCmd(pm) {
31810
- if (pm === "bun")
31811
- return "bun run";
31812
- if (pm === "pnpm")
31813
- return "pnpm run";
31814
- if (pm === "yarn")
31815
- return "yarn";
31816
- return "npm run";
31817
- }
31818
- function describeScript(name) {
31819
- const map3 = {
31820
- dev: "Dev server",
31821
- start: "Start server",
31822
- build: "Production build",
31823
- lint: "Lint",
31824
- "lint:fix": "Lint + autofix",
31825
- format: "Format code",
31826
- test: "Run tests",
31827
- "test:watch": "Run tests (watch)",
31828
- "test:e2e": "End-to-end tests",
31829
- typecheck: "Type-check",
31830
- "type-check": "Type-check",
31831
- preview: "Preview production build",
31832
- deploy: "Deploy",
31833
- generate: "Code generation",
31834
- migrate: "Run migrations",
31835
- seed: "Seed database",
31836
- clean: "Clean build artifacts",
31837
- prepare: "Prepare (husky, etc.)"
31838
- };
31839
- return map3[name] ?? "";
31840
- }
31841
- function generateAgentsMd(info, _cwd) {
31842
- const lang = info.language === "typescript" ? "TypeScript" : info.language === "javascript" ? "JavaScript" : info.language;
31843
- const frameworkLabel = info.framework ? `${info.framework} ` : "";
31844
- const monoLabel = info.monorepo ? " (monorepo)" : "";
31845
- const lines = [];
31846
- lines.push("# AGENTS.md");
31847
- lines.push("");
31848
- lines.push(`${frameworkLabel}${lang} project${monoLabel}.`);
31849
- lines.push("");
31850
- const scriptEntries = Object.entries(info.scripts);
31851
- if (scriptEntries.length > 0 && info.packageManager) {
31852
- const prefix = runCmd(info.packageManager);
31853
- lines.push("## Commands");
31854
- lines.push("");
31855
- lines.push("```bash");
31856
- const commands = scriptEntries.map(([name]) => `${prefix} ${name}`);
31857
- const maxLen = Math.max(...commands.map((c) => c.length));
31858
- for (let i = 0;i < scriptEntries.length; i++) {
31859
- const [name] = scriptEntries[i];
31860
- const cmd = commands[i];
31861
- const desc = describeScript(name);
31862
- if (desc) {
31863
- lines.push(`${cmd}${" ".repeat(maxLen - cmd.length + 4)}# ${desc}`);
31864
- } else {
31865
- lines.push(cmd);
31866
- }
31867
- }
31868
- lines.push("```");
31869
- lines.push("");
31870
- }
31871
- lines.push("## Code Standards");
31872
- lines.push("");
31873
- const langLabel = info.language === "typescript" ? "TypeScript" : "JavaScript";
31874
- if (info.language === "typescript" || info.language === "javascript") {
31875
- lines.push(`- ${langLabel} with ES modules`);
31876
- }
31877
- if (info.indentStyle) {
31878
- const unit = info.indentStyle.type === "tab" ? "tab" : "space";
31879
- lines.push(`- ${info.indentStyle.width}-${unit} indentation`);
31880
- }
31881
- if (info.linter) {
31882
- lines.push(`- Linted with ${info.linter}`);
31883
- }
31884
- lines.push("");
31885
- lines.push("## Architecture");
31886
- lines.push("");
31887
- for (const dir of info.dirs) {
31888
- lines.push(`- \`${dir}/\` — ${describeDir(dir)}`);
31889
- }
31890
- if (info.srcDirs.length > 0) {
31891
- for (const sub of info.srcDirs) {
31892
- lines.push(` - \`src/${sub}/\` — ${describeDir(sub)}`);
31893
- }
31894
- }
31895
- lines.push("");
31896
- return lines.join(`
31897
- `);
31898
- }
31899
- function generateClaudeMd(info) {
31900
- const lines = [];
31901
- lines.push("# CLAUDE.md");
31902
- lines.push("");
31903
- lines.push("@AGENTS.md");
31904
- if (info.existingDocs.architectureMd || info.dirs.includes("docs")) {
31905
- lines.push("@docs/architecture.md");
31906
- }
31907
- lines.push("");
31908
- return lines.join(`
31909
- `);
31910
- }
31911
- function generateArchitectureMd(info, _cwd) {
31912
- const lines = [];
31913
- lines.push("# Architecture");
31914
- lines.push("");
31915
- lines.push("## Directory Structure");
31916
- lines.push("");
31917
- for (const dir of info.dirs) {
31918
- lines.push(`- \`${dir}/\` — ${describeDir(dir)}`);
31919
- }
31920
- if (info.srcDirs.length > 0) {
31921
- lines.push("");
31922
- lines.push("### `src/`");
31923
- lines.push("");
31924
- for (const sub of info.srcDirs) {
31925
- lines.push(`- \`src/${sub}/\` — ${describeDir(sub)}`);
31926
- }
31927
- }
31928
- lines.push("");
31929
- return lines.join(`
31930
- `);
31931
- }
31932
- var VAGUE_STANDARDS = [
31933
- "follow best practices",
31934
- "use best practices",
31935
- "keep it clean",
31936
- "write clean code",
31937
- "maintain code quality",
31938
- "ensure quality",
31939
- "use proper naming",
31940
- "follow conventions",
31941
- "be consistent"
31942
- ];
31943
- function verifyDocs(cwd) {
31944
- const issues = [];
31945
- const claudeMd = readText(join4(cwd, "CLAUDE.md"));
31946
- const agentsMd = readText(join4(cwd, "AGENTS.md"));
31947
- const pkg = readJson(join4(cwd, "package.json"));
31948
- const pkgScripts = pkg && typeof pkg.scripts === "object" && pkg.scripts !== null ? pkg.scripts : {};
31949
- const projectRoot = resolve(cwd);
31950
- if (claudeMd) {
31951
- const importedFiles = [];
31952
- for (const line of claudeMd.split(`
31953
- `)) {
31954
- const match = line.match(/^@(.+)$/);
31955
- if (match) {
31956
- const refPath = match[1].trim();
31957
- if (isAbsolute(refPath)) {
31958
- issues.push({
31959
- severity: "error",
31960
- file: "CLAUDE.md",
31961
- message: `@ reference uses an absolute path: ${refPath}`,
31962
- fix: "Use a project-relative path under the repository root"
31963
- });
31964
- continue;
31965
- }
31966
- const resolvedPath = resolve(projectRoot, refPath);
31967
- if (resolvedPath !== projectRoot && !resolvedPath.startsWith(projectRoot + sep2)) {
31968
- issues.push({
31969
- severity: "error",
31970
- file: "CLAUDE.md",
31971
- message: `@ reference escapes project root: ${refPath}`,
31972
- fix: "Remove traversal segments (../) and keep references inside the repo"
31973
- });
31974
- continue;
31975
- }
31976
- importedFiles.push({ ref: refPath, resolved: resolvedPath });
31977
- if (!existsSync4(resolvedPath)) {
31978
- issues.push({
31979
- severity: "error",
31980
- file: "CLAUDE.md",
31981
- message: `Referenced file does not exist: ${refPath}`,
31982
- fix: `Remove the @${refPath} line or create the file`
31983
- });
31984
- }
31985
- }
31986
- }
31987
- const claudeLines = claudeMd.split(`
31988
- `).length;
31989
- if (claudeLines > 100) {
31990
- issues.push({
31991
- severity: "warning",
31992
- file: "CLAUDE.md",
31993
- message: `CLAUDE.md is ${claudeLines} lines (recommended: under 100)`,
31994
- fix: "Move detailed content to AGENTS.md or docs/ files and use @imports"
31995
- });
31996
- }
31997
- if (importedFiles.length > 0) {
31998
- const claudeHeadings = extractHeadings(claudeMd);
31999
- for (const { ref: refPath, resolved: resolvedPath } of importedFiles) {
32000
- const refContent = readText(resolvedPath);
32001
- if (!refContent)
32002
- continue;
32003
- const refHeadings = extractHeadings(refContent);
32004
- for (const heading of claudeHeadings) {
32005
- if (refHeadings.has(heading)) {
32006
- issues.push({
32007
- severity: "warning",
32008
- file: "CLAUDE.md",
32009
- message: `Section "${heading}" duplicates content from @${refPath}`,
32010
- fix: `Remove the "${heading}" section — it's already included via @import`
32011
- });
32012
- }
32013
- }
32014
- }
32015
- }
32016
- }
32017
- if (agentsMd) {
32018
- const agentsLines = agentsMd.split(`
32019
- `);
32020
- const contextLines = [];
32021
- let pastFirstHeading = false;
32022
- let hitNextSection = false;
32023
- for (const line of agentsLines) {
32024
- if (!pastFirstHeading) {
32025
- if (line.startsWith("# ")) {
32026
- pastFirstHeading = true;
32027
- }
32028
- continue;
32029
- }
32030
- if (line.startsWith("## ")) {
32031
- hitNextSection = true;
32032
- break;
32033
- }
32034
- const trimmed = line.trim();
32035
- if (trimmed)
32036
- contextLines.push(trimmed);
32037
- }
32038
- if (pastFirstHeading && !hitNextSection && contextLines.length === 0) {
32039
- issues.push({
32040
- severity: "warning",
32041
- file: "AGENTS.md",
32042
- message: "Missing project context line after the title heading",
32043
- fix: "Add a single-line description: stack + what the project does"
32044
- });
32045
- } else if (contextLines.length > 1) {
32046
- issues.push({
32047
- severity: "warning",
32048
- file: "AGENTS.md",
32049
- message: `Project context should be exactly 1 line, found ${contextLines.length}`,
32050
- fix: "Condense to a single line: stack + what the project does"
32051
- });
32052
- }
32053
- const codeBlockRe = /```[\s\S]*?```/g;
32054
- let blockMatch;
32055
- while ((blockMatch = codeBlockRe.exec(agentsMd)) !== null) {
32056
- const block = blockMatch[0];
32057
- const cmdRe = /(?:bun|npm|pnpm|yarn)\s+(?:run\s+)?(\S+)/g;
32058
- let cmdMatch;
32059
- while ((cmdMatch = cmdRe.exec(block)) !== null) {
32060
- const scriptName = cmdMatch[1];
32061
- const builtins = new Set([
32062
- "install",
32063
- "init",
32064
- "create",
32065
- "exec",
32066
- "dlx",
32067
- "x",
32068
- "test",
32069
- "start"
32070
- ]);
32071
- if (builtins.has(scriptName))
32072
- continue;
32073
- if (Object.keys(pkgScripts).length > 0 && !(scriptName in pkgScripts)) {
32074
- issues.push({
32075
- severity: "warning",
32076
- file: "AGENTS.md",
32077
- message: `Command references script "${scriptName}" which is not in package.json`,
32078
- fix: `Update the command or add "${scriptName}" to package.json scripts`
32079
- });
32080
- }
32081
- }
32082
- }
32083
- const standardsSection = extractSection(agentsMd, "Code Standards");
32084
- if (standardsSection) {
32085
- const lower = standardsSection.toLowerCase();
32086
- for (const phrase of VAGUE_STANDARDS) {
32087
- if (lower.includes(phrase)) {
32088
- issues.push({
32089
- severity: "warning",
32090
- file: "AGENTS.md",
32091
- message: `Code Standards contains vague phrase: "${phrase}"`,
32092
- fix: "Replace with specific, verifiable conventions derived from config files"
32093
- });
32094
- }
32095
- }
32096
- }
32097
- if (Object.keys(pkgScripts).length > 0) {
32098
- const hasTestScript = Object.keys(pkgScripts).some((k3) => k3 === "test" || k3.startsWith("test:"));
32099
- if (!hasTestScript) {
32100
- const mentionsNoTest = agentsMd.toLowerCase().includes("no test");
32101
- if (!mentionsNoTest) {
32102
- issues.push({
32103
- severity: "warning",
32104
- file: "AGENTS.md",
32105
- message: "No test script in package.json and AGENTS.md doesn't mention it",
32106
- fix: 'Add a note like "No test framework. Verify changes with `bun run build`."'
32107
- });
32108
- }
32109
- }
32110
- }
32111
- checkBacktickPaths(agentsMd, "AGENTS.md", cwd, issues);
32112
- }
32113
- const archMd = readText(join4(cwd, "docs", "architecture.md"));
32114
- if (archMd) {
32115
- checkBacktickPaths(archMd, "docs/architecture.md", cwd, issues);
32116
- }
32117
- return issues;
32118
- }
32119
- function extractHeadings(content) {
32120
- const headings = new Set;
32121
- for (const line of content.split(`
32122
- `)) {
32123
- const match = line.match(/^#{2,3}\s+(.+)$/);
32124
- if (match) {
32125
- headings.add(match[1].trim());
32126
- }
32127
- }
32128
- return headings;
32129
- }
32130
- function extractSection(content, heading) {
32131
- const lines = content.split(`
32132
- `);
32133
- let capturing = false;
32134
- const result = [];
32135
- for (const line of lines) {
32136
- if (capturing) {
32137
- if (line.match(/^#{1,2}\s/))
32138
- break;
32139
- result.push(line);
32140
- } else if (line.match(new RegExp(`^##\\s+${heading.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`, "i"))) {
32141
- capturing = true;
32142
- }
32143
- }
32144
- return result.length > 0 ? result.join(`
32145
- `) : null;
32146
- }
32147
- function checkBacktickPaths(content, file2, cwd, issues) {
32148
- const pathRe = /`((?:src\/|packages\/|apps\/|supabase\/|docs\/)[^`]+)`/g;
32149
- let match;
32150
- const checked = new Set;
32151
- const root = resolve(cwd);
32152
- while ((match = pathRe.exec(content)) !== null) {
32153
- const refPath = match[1].replace(/\/$/, "");
32154
- if (checked.has(refPath))
32155
- continue;
32156
- checked.add(refPath);
32157
- const resolvedRef = resolve(root, refPath);
32158
- if (resolvedRef !== root && !resolvedRef.startsWith(root + sep2))
32159
- continue;
32160
- if (!existsSync4(resolvedRef)) {
32161
- issues.push({
32162
- severity: "warning",
32163
- file: file2,
32164
- message: `Referenced path does not exist: ${refPath}`,
32165
- fix: `Update or remove the \`${refPath}\` reference`
32166
- });
32167
- }
32168
- }
32169
- }
32170
- async function runDocsStep(cwd) {
32171
- const info = scanProject(cwd);
32172
- const hasDocs = info.existingDocs.agentsMd || info.existingDocs.claudeMd;
32173
- if (!hasDocs) {
32174
- const shouldGenerate = await ye({
32175
- message: "No project docs found. Generate AGENTS.md and CLAUDE.md?",
32176
- initialValue: true
32177
- });
32178
- if (pD(shouldGenerate) || !shouldGenerate) {
32179
- return { files: [], issues: [], skipped: true };
32180
- }
32181
- const files = [];
32182
- files.push({
32183
- path: join4(cwd, "AGENTS.md"),
32184
- content: generateAgentsMd(info, cwd),
32185
- type: "text"
32186
- });
32187
- files.push({
32188
- path: join4(cwd, "CLAUDE.md"),
32189
- content: generateClaudeMd(info),
32190
- type: "text"
32191
- });
32192
- if (info.dirs.includes("docs") || info.srcDirs.length > 0) {
32193
- files.push({
32194
- path: join4(cwd, "docs", "architecture.md"),
32195
- content: generateArchitectureMd(info, cwd),
32196
- type: "text"
32197
- });
32198
- }
32199
- M2.success(`Generated ${files.length} doc file(s): ${files.map((f) => f.path.replace(cwd + "/", "")).join(", ")}`);
32200
- return { files, issues: [], skipped: false };
32201
- }
32202
- const shouldVerify = await ye({
32203
- message: "Project docs found. Verify for issues?",
32204
- initialValue: false
32205
- });
32206
- if (pD(shouldVerify) || !shouldVerify) {
32207
- return { files: [], issues: [], skipped: true };
32208
- }
32209
- const issues = verifyDocs(cwd);
32210
- if (issues.length === 0) {
32211
- M2.success("No issues found in project docs.");
32212
- } else {
32213
- for (const issue2 of issues) {
32214
- const prefix = `${colors.bold(issue2.file)}:`;
32215
- if (issue2.severity === "error") {
32216
- M2.error(`${prefix} ${issue2.message}`);
32217
- } else {
32218
- M2.warning(`${prefix} ${issue2.message}`);
32219
- }
32220
- if (issue2.fix) {
32221
- M2.message(` ${symbols.arrow} ${colors.dim(issue2.fix)}`);
32222
- }
32223
- }
32224
- M2.info(`Found ${issues.length} issue(s) (${issues.filter((i) => i.severity === "error").length} errors, ${issues.filter((i) => i.severity === "warning").length} warnings)`);
32225
- }
32226
- return { files: [], issues, skipped: false };
32227
- }
32228
-
32229
- // src/tui/writer.ts
32230
- import { existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
32231
- import { homedir as homedir3 } from "node:os";
32232
- import { dirname } from "node:path";
32233
- function ensureDir(dirPath) {
32234
- if (!existsSync5(dirPath)) {
32235
- mkdirSync3(dirPath, { recursive: true, mode: 493 });
32236
- }
32237
- }
32238
- function writeFile(filePath, content, options = {}) {
32239
- const exists = existsSync5(filePath);
32240
- if (exists && !options.force) {
32241
- return { path: filePath, action: "skip" };
32242
- }
32243
- try {
32244
- ensureDir(dirname(filePath));
32245
- const mode = filePath.includes(".harmony-mcp") ? 384 : 420;
32246
- writeFileSync3(filePath, content, { mode });
32247
- return { path: filePath, action: exists ? "update" : "create" };
32248
- } catch (error48) {
32249
- return {
32250
- path: filePath,
32251
- action: "skip",
32252
- error: error48 instanceof Error ? error48.message : String(error48)
32253
- };
32254
- }
32255
- }
32256
- function mergeJsonFile(filePath, updates, options = {}) {
32257
- const exists = existsSync5(filePath);
32258
- if (!exists) {
32259
- try {
32260
- ensureDir(dirname(filePath));
32261
- writeFileSync3(filePath, JSON.stringify(updates, null, 2), {
32262
- mode: 420
32263
- });
32264
- return { path: filePath, action: "create" };
32265
- } catch (error48) {
32266
- return {
32267
- path: filePath,
32268
- action: "skip",
32269
- error: error48 instanceof Error ? error48.message : String(error48)
32270
- };
32271
- }
32272
- }
32273
- try {
32274
- const existing = JSON.parse(readFileSync4(filePath, "utf-8"));
32275
- if (updates.mcpServers && existing.mcpServers) {
32276
- const existingServers = existing.mcpServers;
32277
- const updateServers = updates.mcpServers;
32278
- existing.mcpServers = { ...existingServers, ...updateServers };
32279
- } else {
32280
- Object.assign(existing, updates);
32281
- }
32282
- writeFileSync3(filePath, JSON.stringify(existing, null, 2), { mode: 420 });
32283
- return { path: filePath, action: "merge" };
32284
- } catch {
32285
- if (options.force) {
32286
- try {
32287
- writeFileSync3(filePath, JSON.stringify(updates, null, 2), {
32288
- mode: 420
32289
- });
32290
- return { path: filePath, action: "update" };
32291
- } catch (error48) {
32292
- return {
32293
- path: filePath,
32294
- action: "skip",
32295
- error: error48 instanceof Error ? error48.message : String(error48)
32296
- };
32297
- }
32298
- }
32299
- return {
32300
- path: filePath,
32301
- action: "skip",
32302
- error: "Could not parse existing file"
32303
- };
32304
- }
32305
- }
32306
- function appendToToml(filePath, section, content, options = {}) {
32307
- const exists = existsSync5(filePath);
32308
- if (!exists) {
32309
- try {
32310
- ensureDir(dirname(filePath));
32311
- writeFileSync3(filePath, content, { mode: 420 });
32312
- return { path: filePath, action: "create" };
32313
- } catch (error48) {
32314
- return {
32315
- path: filePath,
32316
- action: "skip",
32317
- error: error48 instanceof Error ? error48.message : String(error48)
32318
- };
32319
- }
32320
- }
32321
- try {
32322
- const existing = readFileSync4(filePath, "utf-8");
32323
- if (existing.includes(section)) {
32324
- if (options.force) {
32325
- const updated = existing.replace(new RegExp(`\\[${section.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\][\\s\\S]*?(?=\\[|$)`), content.trim() + `
32326
-
32327
- `);
32328
- writeFileSync3(filePath, updated, { mode: 420 });
32329
- return { path: filePath, action: "update" };
32330
- }
32331
- return { path: filePath, action: "skip" };
32332
- }
32333
- writeFileSync3(filePath, existing + `
32334
- ` + content, { mode: 420 });
32335
- return { path: filePath, action: "merge" };
32336
- } catch (error48) {
32337
- return {
32338
- path: filePath,
32339
- action: "skip",
32340
- error: error48 instanceof Error ? error48.message : String(error48)
32341
- };
32342
- }
32343
- }
32344
- async function writeFilesWithProgress(files, options = {}) {
32345
- const results = [];
32346
- const home = homedir3();
32347
- const spinner = Y2();
32348
- spinner.start("Writing configuration files...");
32349
- for (const file2 of files) {
32350
- let result;
32351
- if (file2.type === "json") {
32352
- const jsonContent = JSON.parse(file2.content);
32353
- result = mergeJsonFile(file2.path, jsonContent, options);
32354
- } else if (file2.type === "toml" && file2.tomlSection) {
32355
- result = appendToToml(file2.path, file2.tomlSection, file2.content, options);
32356
- } else {
32357
- result = writeFile(file2.path, file2.content, options);
32358
- }
32359
- results.push(result);
32360
- await new Promise((resolve2) => setTimeout(resolve2, 50));
32361
- }
32362
- spinner.stop("Files written");
32363
- for (const result of results) {
32364
- const displayPath = formatPath(result.path, home);
32365
- if (result.error) {
32366
- console.log(messages.fileError(displayPath, result.error));
32367
- } else if (result.action === "skip") {
32368
- console.log(messages.fileSkipped(displayPath));
32369
- } else {
32370
- const actionLabel = result.action === "merge" ? "updated" : "created";
32371
- console.log(` ${colors.success("✓")} ${colors.dim(displayPath)} ${colors.dim(`(${actionLabel})`)}`);
32372
- }
32373
- }
32374
- return results;
32375
- }
32376
- function getWriteSummary(files, options = {}) {
32377
- const toCreate = [];
32378
- const toUpdate = [];
32379
- const toSkip = [];
32380
- const home = homedir3();
32381
- for (const file2 of files) {
32382
- const displayPath = formatPath(file2.path, home);
32383
- const exists = existsSync5(file2.path);
32384
- if (exists && !options.force) {
32385
- toSkip.push(displayPath);
32386
- } else if (exists) {
32387
- toUpdate.push(displayPath);
32388
- } else {
32389
- toCreate.push(displayPath);
32390
- }
32391
- }
32392
- return { toCreate, toUpdate, toSkip };
32393
- }
30844
+ User input: $ARGUMENTS
32394
30845
 
32395
- // src/tui/setup.ts
32396
- var GLOBAL_SKILLS_DIR = join5(homedir4(), ".agents", "skills");
32397
- var API_URL = "https://gethmy.com/api";
32398
- var HARMONY_WORKFLOW_PROMPT = `# Harmony Card Workflow
30846
+ ## 0. Detect Intent
32399
30847
 
32400
- Start work on a Harmony card. Card reference: $ARGUMENTS
30848
+ Parse \`$ARGUMENTS\` to determine what the user wants:
32401
30849
 
32402
- ## 1. Find & Fetch Card
30850
+ | Pattern | Intent | Go to |
30851
+ |---|---|---|
30852
+ | \`create ...\` or \`new ...\` | **Create** a new card | Step A |
30853
+ | \`#42\`, \`42\`, UUID, or card name (no action verb) | **Work on** an existing card | Step B |
30854
+ | \`move #42 to Done\`, \`update #42 ...\`, \`assign #42 ...\` | **Quick action** on a card | Step C |
30855
+ | \`show #42\`, \`view #42\`, \`status #42\` | **View** card details | Step D |
30856
+
30857
+ If ambiguous, ask the user what they'd like to do.
30858
+
30859
+ ---
30860
+
30861
+ ## Step A: Create Card
30862
+
30863
+ Create a card without starting work on it.
30864
+
30865
+ 1. Parse the title and any details from the arguments (e.g., \`create Add dark mode toggle\` → title: "Add dark mode toggle")
30866
+ 2. Call \`harmony_create_card\` with:
30867
+ - \`title\`: extracted title
30868
+ - \`description\`: if the user provided details beyond the title
30869
+ - \`priority\`, \`columnId\`, \`assigneeId\`: only if explicitly specified
30870
+ 3. Show the created card: title, short ID, column, and a link if available.
30871
+ 4. **Stop here.** Do not start an agent session or begin implementation.
30872
+
30873
+ ---
30874
+
30875
+ ## Step B: Work on Existing Card
30876
+
30877
+ Start work on a Harmony card.
30878
+
30879
+ ### B1. Find & Fetch Card
32403
30880
 
32404
30881
  Parse the reference and fetch the card:
32405
30882
  - \`#42\` or \`42\` → \`harmony_get_card_by_short_id\` with \`shortId: 42\`
32406
30883
  - UUID → \`harmony_get_card\` with \`cardId\`
32407
30884
  - Name/text → \`harmony_search_cards\` with \`query\`
32408
30885
 
32409
- ## 2. Get Board State
32410
-
32411
- Call \`harmony_get_board\` to get columns and labels. From the response:
32412
- - Find the "In Progress" (or "Progress") column ID
32413
- - Find the "agent" label ID
30886
+ ### B2. Start Agent Session
32414
30887
 
32415
- ## 3. Setup Card for Work
30888
+ Call \`harmony_start_agent_session\` with:
30889
+ - \`cardId\`: Card UUID
30890
+ - \`agentIdentifier\`: Your agent identifier
30891
+ - \`agentName\`: Your agent name
30892
+ - \`currentTask\`: A specific description of the first thing you'll do (e.g., "Exploring codebase to understand auth flow"), NOT a generic phrase like "Analyzing card requirements"
30893
+ - \`moveToColumn\`: "In Progress"
30894
+ - \`addLabels\`: ["agent"]
32416
30895
 
32417
- Execute these in sequence:
32418
- 1. \`harmony_move_card\` → Move to "In Progress" column
32419
- 2. \`harmony_add_label_to_card\` → Add "agent" label
32420
- 3. \`harmony_start_agent_session\`:
32421
- - \`cardId\`: Card UUID
32422
- - \`agentIdentifier\`: Your agent identifier
32423
- - \`agentName\`: Your agent name
32424
- - \`currentTask\`: "Analyzing card requirements"
30896
+ This single call moves the card, adds the label, auto-assigns, and starts the session.
32425
30897
 
32426
- ## 4. Generate Work Prompt
30898
+ ### B3. Generate Work Prompt
32427
30899
 
32428
30900
  Call \`harmony_generate_prompt\` with:
32429
30901
  - \`cardId\` or \`shortId\` (+ \`projectId\` if using shortId)
@@ -32434,26 +30906,56 @@ Call \`harmony_generate_prompt\` with:
32434
30906
 
32435
30907
  The generated prompt provides role framing, focus areas, subtasks, linked cards, and suggested outputs.
32436
30908
 
32437
- ## 5. Display Card Summary
30909
+ ### B4. Display Card Summary
32438
30910
 
32439
30911
  Show the user: Card title, short ID, role, priority, labels, due date, description, and subtasks.
32440
30912
 
32441
- ## 6. Implement Solution
30913
+ ### B5. Implement Solution
32442
30914
 
32443
- Work on the card following the generated prompt's guidance. Update progress at milestones:
32444
- - \`harmony_update_agent_progress\` with \`progressPercent\` (0-100), \`currentTask\`, \`status\`, \`blockers\`
30915
+ Work on the card following the generated prompt's guidance.
32445
30916
 
32446
- **Progress checkpoints:** 20% (exploration), 50% (implementation), 80% (testing), 100% (done)
30917
+ **REQUIRED: Update progress at each milestone** by calling \`harmony_update_agent_progress\`. This is not optional — the card's live status badge depends on these updates.
32447
30918
 
32448
- ## 7. Complete Work
30919
+ | Milestone | \`progressPercent\` | Example \`currentTask\` |
30920
+ |---|---|---|
30921
+ | After exploring codebase & understanding requirements | 20 | "Reading auth middleware and identifying affected routes" |
30922
+ | When starting implementation | 50 | "Refactoring token validation in auth.ts" |
30923
+ | When moving to testing/verification | 80 | "Running build and verifying changes compile" |
30924
+ | When done, before ending session | 100 | "All changes complete, ready for review" |
30925
+
30926
+ Always set \`currentTask\` to a specific description of what you're actually doing — never leave it as "Analyzing card requirements" or other generic text.
30927
+
30928
+ ### B6. Complete Work
32449
30929
 
32450
30930
  When finished:
32451
- 1. \`harmony_end_agent_session\` with \`status: "completed"\`, \`progressPercent: 100\`
32452
- 2. \`harmony_move_card\` to "Review" column
32453
- 3. Summarize accomplishments
30931
+ 1. \`harmony_end_agent_session\` with \`status: "completed"\`, \`progressPercent: 100\`, \`moveToColumn: "Review"\`
30932
+ 2. Summarize accomplishments
32454
30933
 
32455
30934
  If pausing: \`harmony_end_agent_session\` with \`status: "paused"\`
32456
30935
 
30936
+ ---
30937
+
30938
+ ## Step C: Quick Action
30939
+
30940
+ Fetch the card first (same as B1), then perform the requested action:
30941
+ - **Move:** \`harmony_move_card\` with target column
30942
+ - **Update:** \`harmony_update_card\` with changed fields
30943
+ - **Assign:** \`harmony_assign_card\`
30944
+ - **Label:** \`harmony_add_label_to_card\` / \`harmony_remove_label_from_card\`
30945
+ - **Archive:** \`harmony_archive_card\`
30946
+
30947
+ Show confirmation and stop. Do not start an agent session.
30948
+
30949
+ ---
30950
+
30951
+ ## Step D: View Card
30952
+
30953
+ Fetch the card (same as B1) and display: title, short ID, column, priority, labels, assignee, due date, description, subtasks, and links.
30954
+
30955
+ Do not start an agent session.
30956
+
30957
+ ---
30958
+
32457
30959
  ## Key Tools Reference
32458
30960
 
32459
30961
  **Cards:** \`harmony_get_card\`, \`harmony_get_card_by_short_id\`, \`harmony_search_cards\`, \`harmony_create_card\`, \`harmony_update_card\`, \`harmony_move_card\`, \`harmony_delete_card\`, \`harmony_assign_card\`
@@ -32470,7 +30972,7 @@ If pausing: \`harmony_end_agent_session\` with \`status: "paused"\`
32470
30972
 
32471
30973
  **AI:** \`harmony_generate_prompt\`, \`harmony_process_command\`
32472
30974
  `;
32473
- var HARMONY_PLAN_PROMPT = `# Harmony Plan Workflow
30975
+ var HMY_PLAN_CONTENT = `# Harmony Plan Workflow
32474
30976
 
32475
30977
  Create a new plan or work on an existing one. Argument: $ARGUMENTS
32476
30978
 
@@ -32630,59 +31132,1811 @@ Create a structured markdown document:
32630
31132
 
32631
31133
  [Continue for all tasks...]
32632
31134
 
32633
- ## Risks & Mitigations
32634
- | Risk | Mitigation |
32635
- |------|------------|
32636
- | ... | ... |
31135
+ ## Risks & Mitigations
31136
+ | Risk | Mitigation |
31137
+ |------|------------|
31138
+ | ... | ... |
31139
+
31140
+ ## Success Criteria
31141
+ - [ ] [Measurable criterion]
31142
+ \\\`\\\`\\\`
31143
+
31144
+ ### 2B.4 — Create Plan
31145
+
31146
+ Call \`harmony_create_plan\` with:
31147
+ - \`title\`: The plan title
31148
+ - \`content\`: Full markdown document from Step 2B.3
31149
+ - \`source\`: \`"agent"\`
31150
+ - \`workflowPhase\`: \`"plan"\`
31151
+ - \`tasks\`: Array of tasks from the Tasks section, each with:
31152
+ - \`content\`: Task title + brief description
31153
+ - \`priority\`: \`"high"\`, \`"medium"\`, or \`"low"\`
31154
+ - \`status\`: \`"pending"\`
31155
+
31156
+ ### 2B.5 — User Approval
31157
+
31158
+ Show the user:
31159
+ - Plan URL: \`https://gethmy.com/plans/{id}\`
31160
+ - Number of tasks created
31161
+ - Brief summary
31162
+
31163
+ Then ask: **"Ready to execute? I'll create board cards from these tasks and start the execution phase."**
31164
+
31165
+ Options:
31166
+ 1. **Yes, advance to Execute** — proceed to Step 2B.6
31167
+ 2. **Let me review first** — end here, they can advance later from the UI
31168
+ 3. **Make changes** — iterate on the plan
31169
+
31170
+ ### 2B.6 — Advance to Execute
31171
+
31172
+ Call \`harmony_advance_plan\` with:
31173
+ - \`planId\`: The plan ID from Step 2B.4
31174
+ - \`phase\`: \`"execute"\`
31175
+ - \`summary\`: A 2-3 sentence summary of the key decisions made during planning
31176
+
31177
+ Report the result:
31178
+ - "Created N cards in 'To Do'. Use \`/hmy #<id>\` to start working on any card."
31179
+ - List the created cards with their short IDs
31180
+
31181
+ ## Key Tools Reference
31182
+
31183
+ **Discovery:** \`harmony_list_plans\`, \`harmony_get_plan\`, \`harmony_get_card_by_short_id\`
31184
+ **Context:** \`harmony_get_board\`, \`harmony_recall\`, \`harmony_memory_search\`
31185
+ **Planning:** \`harmony_create_plan\`, \`harmony_advance_plan\`, \`harmony_update_plan\`
31186
+ **Execution:** \`harmony_create_card\`, \`harmony_update_card\`
31187
+ `;
31188
+ var SKILL_DEFINITIONS = {
31189
+ hmy: {
31190
+ name: "hmy",
31191
+ description: "Work with Harmony cards — create, view, update, or start working on them. Use when given a card reference like #42, or commands like create, move, update.",
31192
+ argumentHint: "<command or card-reference>",
31193
+ content: HMY_SKILL_CONTENT
31194
+ },
31195
+ "hmy-plan": {
31196
+ name: "hmy-plan",
31197
+ description: "Create a new plan or work on an existing one. Use when asked to plan a feature, execute a plan, review a plan, or given a plan reference.",
31198
+ argumentHint: "[plan name, ID, or topic to plan]",
31199
+ content: HMY_PLAN_CONTENT
31200
+ }
31201
+ };
31202
+ function buildSkillFile(skillId, agentId) {
31203
+ const skill = SKILL_DEFINITIONS[skillId];
31204
+ if (!skill) {
31205
+ throw new Error(`Unknown skill: ${skillId}`);
31206
+ }
31207
+ let content = skill.content;
31208
+ if (agentId === "claude") {
31209
+ content = content.replace("Your agent identifier", "claude-code").replace("Your agent name", "Claude Code");
31210
+ }
31211
+ const frontmatter = `---
31212
+ name: ${skill.name}
31213
+ description: ${skill.description}
31214
+ argument-hint: ${skill.argumentHint}
31215
+ ---`;
31216
+ return `${frontmatter}
31217
+
31218
+ ${content}
31219
+ ${VERSION_MARKER_PREFIX}${SKILLS_VERSION} -->`;
31220
+ }
31221
+ function parseSkillVersion(content) {
31222
+ const match = content.match(/<!-- skills-version:(\d+) -->/);
31223
+ return match ? match[1] : null;
31224
+ }
31225
+ function findSkillFiles(paths) {
31226
+ const results = [];
31227
+ for (const filePath of paths) {
31228
+ if (!existsSync3(filePath))
31229
+ continue;
31230
+ for (const skillId of Object.keys(SKILL_DEFINITIONS)) {
31231
+ if (filePath.includes(`/${skillId}/`) || filePath.includes(`/${skillId}.md`)) {
31232
+ results.push({ skillId, filePath });
31233
+ break;
31234
+ }
31235
+ }
31236
+ }
31237
+ return results;
31238
+ }
31239
+ async function refreshSkills() {
31240
+ try {
31241
+ const status = areSkillsInstalled();
31242
+ if (!status.installed) {
31243
+ return;
31244
+ }
31245
+ const skillFiles = findSkillFiles(status.paths);
31246
+ if (skillFiles.length > 0) {
31247
+ const samplePath = skillFiles[0].filePath;
31248
+ for (const skillId of Object.keys(SKILL_DEFINITIONS)) {
31249
+ const alreadyFound = skillFiles.some((sf) => sf.skillId === skillId);
31250
+ if (alreadyFound)
31251
+ continue;
31252
+ let siblingPath;
31253
+ if (samplePath.endsWith("SKILL.md")) {
31254
+ const parentDir = dirname(dirname(samplePath));
31255
+ siblingPath = `${parentDir}/${skillId}/SKILL.md`;
31256
+ } else {
31257
+ const parentDir = dirname(samplePath);
31258
+ siblingPath = `${parentDir}/${skillId}.md`;
31259
+ }
31260
+ if (existsSync3(siblingPath)) {
31261
+ skillFiles.push({ skillId, filePath: siblingPath });
31262
+ }
31263
+ }
31264
+ }
31265
+ if (skillFiles.length === 0) {
31266
+ return;
31267
+ }
31268
+ let updated = false;
31269
+ for (const { skillId, filePath } of skillFiles) {
31270
+ try {
31271
+ const currentContent = readFileSync3(filePath, "utf-8");
31272
+ const currentVersion = parseSkillVersion(currentContent);
31273
+ if (currentVersion === null || Number(currentVersion) < Number(SKILLS_VERSION)) {
31274
+ const newContent = buildSkillFile(skillId, "claude");
31275
+ const dir = dirname(filePath);
31276
+ if (!existsSync3(dir)) {
31277
+ mkdirSync3(dir, { recursive: true });
31278
+ }
31279
+ writeFileSync3(filePath, newContent);
31280
+ updated = true;
31281
+ }
31282
+ } catch {}
31283
+ }
31284
+ if (updated) {
31285
+ console.error(`Harmony: Updated skills to v${SKILLS_VERSION}`);
31286
+ }
31287
+ } catch {}
31288
+ }
31289
+
31290
+ // src/tui/setup.ts
31291
+ import {
31292
+ existsSync as existsSync7,
31293
+ lstatSync,
31294
+ mkdirSync as mkdirSync5,
31295
+ symlinkSync,
31296
+ unlinkSync
31297
+ } from "node:fs";
31298
+ import { homedir as homedir4 } from "node:os";
31299
+ import { dirname as dirname3, join as join5 } from "node:path";
31300
+
31301
+ // ../../node_modules/@clack/core/dist/index.mjs
31302
+ var import_sisteransi = __toESM(require_src(), 1);
31303
+ var import_picocolors = __toESM(require_picocolors(), 1);
31304
+ import { stdin as j, stdout as M } from "node:process";
31305
+ import * as g from "node:readline";
31306
+ import O from "node:readline";
31307
+ import { Writable as X } from "node:stream";
31308
+ function DD({ onlyFirst: e = false } = {}) {
31309
+ const t = ["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?(?:\\u0007|\\u001B\\u005C|\\u009C))", "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))"].join("|");
31310
+ return new RegExp(t, e ? undefined : "g");
31311
+ }
31312
+ var uD = DD();
31313
+ function P(e) {
31314
+ if (typeof e != "string")
31315
+ throw new TypeError(`Expected a \`string\`, got \`${typeof e}\``);
31316
+ return e.replace(uD, "");
31317
+ }
31318
+ function L(e) {
31319
+ return e && e.__esModule && Object.prototype.hasOwnProperty.call(e, "default") ? e.default : e;
31320
+ }
31321
+ var W = { exports: {} };
31322
+ (function(e) {
31323
+ var u = {};
31324
+ e.exports = u, u.eastAsianWidth = function(F) {
31325
+ var s = F.charCodeAt(0), i = F.length == 2 ? F.charCodeAt(1) : 0, D = s;
31326
+ return 55296 <= s && s <= 56319 && 56320 <= i && i <= 57343 && (s &= 1023, i &= 1023, D = s << 10 | i, D += 65536), D == 12288 || 65281 <= D && D <= 65376 || 65504 <= D && D <= 65510 ? "F" : D == 8361 || 65377 <= D && D <= 65470 || 65474 <= D && D <= 65479 || 65482 <= D && D <= 65487 || 65490 <= D && D <= 65495 || 65498 <= D && D <= 65500 || 65512 <= D && D <= 65518 ? "H" : 4352 <= D && D <= 4447 || 4515 <= D && D <= 4519 || 4602 <= D && D <= 4607 || 9001 <= D && D <= 9002 || 11904 <= D && D <= 11929 || 11931 <= D && D <= 12019 || 12032 <= D && D <= 12245 || 12272 <= D && D <= 12283 || 12289 <= D && D <= 12350 || 12353 <= D && D <= 12438 || 12441 <= D && D <= 12543 || 12549 <= D && D <= 12589 || 12593 <= D && D <= 12686 || 12688 <= D && D <= 12730 || 12736 <= D && D <= 12771 || 12784 <= D && D <= 12830 || 12832 <= D && D <= 12871 || 12880 <= D && D <= 13054 || 13056 <= D && D <= 19903 || 19968 <= D && D <= 42124 || 42128 <= D && D <= 42182 || 43360 <= D && D <= 43388 || 44032 <= D && D <= 55203 || 55216 <= D && D <= 55238 || 55243 <= D && D <= 55291 || 63744 <= D && D <= 64255 || 65040 <= D && D <= 65049 || 65072 <= D && D <= 65106 || 65108 <= D && D <= 65126 || 65128 <= D && D <= 65131 || 110592 <= D && D <= 110593 || 127488 <= D && D <= 127490 || 127504 <= D && D <= 127546 || 127552 <= D && D <= 127560 || 127568 <= D && D <= 127569 || 131072 <= D && D <= 194367 || 177984 <= D && D <= 196605 || 196608 <= D && D <= 262141 ? "W" : 32 <= D && D <= 126 || 162 <= D && D <= 163 || 165 <= D && D <= 166 || D == 172 || D == 175 || 10214 <= D && D <= 10221 || 10629 <= D && D <= 10630 ? "Na" : D == 161 || D == 164 || 167 <= D && D <= 168 || D == 170 || 173 <= D && D <= 174 || 176 <= D && D <= 180 || 182 <= D && D <= 186 || 188 <= D && D <= 191 || D == 198 || D == 208 || 215 <= D && D <= 216 || 222 <= D && D <= 225 || D == 230 || 232 <= D && D <= 234 || 236 <= D && D <= 237 || D == 240 || 242 <= D && D <= 243 || 247 <= D && D <= 250 || D == 252 || D == 254 || D == 257 || D == 273 || D == 275 || D == 283 || 294 <= D && D <= 295 || D == 299 || 305 <= D && D <= 307 || D == 312 || 319 <= D && D <= 322 || D == 324 || 328 <= D && D <= 331 || D == 333 || 338 <= D && D <= 339 || 358 <= D && D <= 359 || D == 363 || D == 462 || D == 464 || D == 466 || D == 468 || D == 470 || D == 472 || D == 474 || D == 476 || D == 593 || D == 609 || D == 708 || D == 711 || 713 <= D && D <= 715 || D == 717 || D == 720 || 728 <= D && D <= 731 || D == 733 || D == 735 || 768 <= D && D <= 879 || 913 <= D && D <= 929 || 931 <= D && D <= 937 || 945 <= D && D <= 961 || 963 <= D && D <= 969 || D == 1025 || 1040 <= D && D <= 1103 || D == 1105 || D == 8208 || 8211 <= D && D <= 8214 || 8216 <= D && D <= 8217 || 8220 <= D && D <= 8221 || 8224 <= D && D <= 8226 || 8228 <= D && D <= 8231 || D == 8240 || 8242 <= D && D <= 8243 || D == 8245 || D == 8251 || D == 8254 || D == 8308 || D == 8319 || 8321 <= D && D <= 8324 || D == 8364 || D == 8451 || D == 8453 || D == 8457 || D == 8467 || D == 8470 || 8481 <= D && D <= 8482 || D == 8486 || D == 8491 || 8531 <= D && D <= 8532 || 8539 <= D && D <= 8542 || 8544 <= D && D <= 8555 || 8560 <= D && D <= 8569 || D == 8585 || 8592 <= D && D <= 8601 || 8632 <= D && D <= 8633 || D == 8658 || D == 8660 || D == 8679 || D == 8704 || 8706 <= D && D <= 8707 || 8711 <= D && D <= 8712 || D == 8715 || D == 8719 || D == 8721 || D == 8725 || D == 8730 || 8733 <= D && D <= 8736 || D == 8739 || D == 8741 || 8743 <= D && D <= 8748 || D == 8750 || 8756 <= D && D <= 8759 || 8764 <= D && D <= 8765 || D == 8776 || D == 8780 || D == 8786 || 8800 <= D && D <= 8801 || 8804 <= D && D <= 8807 || 8810 <= D && D <= 8811 || 8814 <= D && D <= 8815 || 8834 <= D && D <= 8835 || 8838 <= D && D <= 8839 || D == 8853 || D == 8857 || D == 8869 || D == 8895 || D == 8978 || 9312 <= D && D <= 9449 || 9451 <= D && D <= 9547 || 9552 <= D && D <= 9587 || 9600 <= D && D <= 9615 || 9618 <= D && D <= 9621 || 9632 <= D && D <= 9633 || 9635 <= D && D <= 9641 || 9650 <= D && D <= 9651 || 9654 <= D && D <= 9655 || 9660 <= D && D <= 9661 || 9664 <= D && D <= 9665 || 9670 <= D && D <= 9672 || D == 9675 || 9678 <= D && D <= 9681 || 9698 <= D && D <= 9701 || D == 9711 || 9733 <= D && D <= 9734 || D == 9737 || 9742 <= D && D <= 9743 || 9748 <= D && D <= 9749 || D == 9756 || D == 9758 || D == 9792 || D == 9794 || 9824 <= D && D <= 9825 || 9827 <= D && D <= 9829 || 9831 <= D && D <= 9834 || 9836 <= D && D <= 9837 || D == 9839 || 9886 <= D && D <= 9887 || 9918 <= D && D <= 9919 || 9924 <= D && D <= 9933 || 9935 <= D && D <= 9953 || D == 9955 || 9960 <= D && D <= 9983 || D == 10045 || D == 10071 || 10102 <= D && D <= 10111 || 11093 <= D && D <= 11097 || 12872 <= D && D <= 12879 || 57344 <= D && D <= 63743 || 65024 <= D && D <= 65039 || D == 65533 || 127232 <= D && D <= 127242 || 127248 <= D && D <= 127277 || 127280 <= D && D <= 127337 || 127344 <= D && D <= 127386 || 917760 <= D && D <= 917999 || 983040 <= D && D <= 1048573 || 1048576 <= D && D <= 1114109 ? "A" : "N";
31327
+ }, u.characterLength = function(F) {
31328
+ var s = this.eastAsianWidth(F);
31329
+ return s == "F" || s == "W" || s == "A" ? 2 : 1;
31330
+ };
31331
+ function t(F) {
31332
+ return F.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF]/g) || [];
31333
+ }
31334
+ u.length = function(F) {
31335
+ for (var s = t(F), i = 0, D = 0;D < s.length; D++)
31336
+ i = i + this.characterLength(s[D]);
31337
+ return i;
31338
+ }, u.slice = function(F, s, i) {
31339
+ textLen = u.length(F), s = s || 0, i = i || 1, s < 0 && (s = textLen + s), i < 0 && (i = textLen + i);
31340
+ for (var D = "", C = 0, n = t(F), E = 0;E < n.length; E++) {
31341
+ var a = n[E], o = u.length(a);
31342
+ if (C >= s - (o == 2 ? 1 : 0))
31343
+ if (C + o <= i)
31344
+ D += a;
31345
+ else
31346
+ break;
31347
+ C += o;
31348
+ }
31349
+ return D;
31350
+ };
31351
+ })(W);
31352
+ var tD = W.exports;
31353
+ var eD = L(tD);
31354
+ var FD = function() {
31355
+ return /\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|(?:\uD83E\uDDD1\uD83C\uDFFF\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFC-\uDFFF])|\uD83D\uDC68(?:\uD83C\uDFFB(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))?|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])\uFE0F|\u200D(?:(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D[\uDC66\uDC67])|\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC)?|(?:\uD83D\uDC69(?:\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69]))|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC69(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83E\uDDD1(?:\u200D(?:\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDE36\u200D\uD83C\uDF2B|\uD83C\uDFF3\uFE0F\u200D\u26A7|\uD83D\uDC3B\u200D\u2744|(?:(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\uD83C\uDFF4\u200D\u2620|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])\u200D[\u2640\u2642]|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u2600-\u2604\u260E\u2611\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26B0\u26B1\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0\u26F1\u26F4\u26F7\u26F8\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u3030\u303D\u3297\u3299]|\uD83C[\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]|\uD83D[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3])\uFE0F|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDE35\u200D\uD83D\uDCAB|\uD83D\uDE2E\u200D\uD83D\uDCA8|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83E\uDDD1(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83D\uDC69(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF6\uD83C\uDDE6|\uD83C\uDDF4\uD83C\uDDF2|\uD83D\uDC08\u200D\u2B1B|\u2764\uFE0F\u200D(?:\uD83D\uDD25|\uD83E\uDE79)|\uD83D\uDC41\uFE0F|\uD83C\uDFF3\uFE0F|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|[#\*0-9]\uFE0F\u20E3|\u2764\uFE0F|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|\uD83C\uDFF4|(?:[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270C\u270D]|\uD83D[\uDD74\uDD90])(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC08\uDC15\uDC3B\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE2E\uDE35\uDE36\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5]|\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD]|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF]|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0D\uDD0E\uDD10-\uDD17\uDD1D\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78\uDD7A-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCB\uDDD0\uDDE0-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6]|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDD77\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g;
31356
+ };
31357
+ var sD = L(FD);
31358
+ function p(e, u = {}) {
31359
+ if (typeof e != "string" || e.length === 0 || (u = { ambiguousIsNarrow: true, ...u }, e = P(e), e.length === 0))
31360
+ return 0;
31361
+ e = e.replace(sD(), " ");
31362
+ const t = u.ambiguousIsNarrow ? 1 : 2;
31363
+ let F = 0;
31364
+ for (const s of e) {
31365
+ const i = s.codePointAt(0);
31366
+ if (i <= 31 || i >= 127 && i <= 159 || i >= 768 && i <= 879)
31367
+ continue;
31368
+ switch (eD.eastAsianWidth(s)) {
31369
+ case "F":
31370
+ case "W":
31371
+ F += 2;
31372
+ break;
31373
+ case "A":
31374
+ F += t;
31375
+ break;
31376
+ default:
31377
+ F += 1;
31378
+ }
31379
+ }
31380
+ return F;
31381
+ }
31382
+ var w = 10;
31383
+ var N = (e = 0) => (u) => `\x1B[${u + e}m`;
31384
+ var I = (e = 0) => (u) => `\x1B[${38 + e};5;${u}m`;
31385
+ var R = (e = 0) => (u, t, F) => `\x1B[${38 + e};2;${u};${t};${F}m`;
31386
+ var r = { modifier: { reset: [0, 0], bold: [1, 22], dim: [2, 22], italic: [3, 23], underline: [4, 24], overline: [53, 55], inverse: [7, 27], hidden: [8, 28], strikethrough: [9, 29] }, color: { black: [30, 39], red: [31, 39], green: [32, 39], yellow: [33, 39], blue: [34, 39], magenta: [35, 39], cyan: [36, 39], white: [37, 39], blackBright: [90, 39], gray: [90, 39], grey: [90, 39], redBright: [91, 39], greenBright: [92, 39], yellowBright: [93, 39], blueBright: [94, 39], magentaBright: [95, 39], cyanBright: [96, 39], whiteBright: [97, 39] }, bgColor: { bgBlack: [40, 49], bgRed: [41, 49], bgGreen: [42, 49], bgYellow: [43, 49], bgBlue: [44, 49], bgMagenta: [45, 49], bgCyan: [46, 49], bgWhite: [47, 49], bgBlackBright: [100, 49], bgGray: [100, 49], bgGrey: [100, 49], bgRedBright: [101, 49], bgGreenBright: [102, 49], bgYellowBright: [103, 49], bgBlueBright: [104, 49], bgMagentaBright: [105, 49], bgCyanBright: [106, 49], bgWhiteBright: [107, 49] } };
31387
+ Object.keys(r.modifier);
31388
+ var iD = Object.keys(r.color);
31389
+ var CD = Object.keys(r.bgColor);
31390
+ [...iD, ...CD];
31391
+ function rD() {
31392
+ const e = new Map;
31393
+ for (const [u, t] of Object.entries(r)) {
31394
+ for (const [F, s] of Object.entries(t))
31395
+ r[F] = { open: `\x1B[${s[0]}m`, close: `\x1B[${s[1]}m` }, t[F] = r[F], e.set(s[0], s[1]);
31396
+ Object.defineProperty(r, u, { value: t, enumerable: false });
31397
+ }
31398
+ return Object.defineProperty(r, "codes", { value: e, enumerable: false }), r.color.close = "\x1B[39m", r.bgColor.close = "\x1B[49m", r.color.ansi = N(), r.color.ansi256 = I(), r.color.ansi16m = R(), r.bgColor.ansi = N(w), r.bgColor.ansi256 = I(w), r.bgColor.ansi16m = R(w), Object.defineProperties(r, { rgbToAnsi256: { value: (u, t, F) => u === t && t === F ? u < 8 ? 16 : u > 248 ? 231 : Math.round((u - 8) / 247 * 24) + 232 : 16 + 36 * Math.round(u / 255 * 5) + 6 * Math.round(t / 255 * 5) + Math.round(F / 255 * 5), enumerable: false }, hexToRgb: { value: (u) => {
31399
+ const t = /[a-f\d]{6}|[a-f\d]{3}/i.exec(u.toString(16));
31400
+ if (!t)
31401
+ return [0, 0, 0];
31402
+ let [F] = t;
31403
+ F.length === 3 && (F = [...F].map((i) => i + i).join(""));
31404
+ const s = Number.parseInt(F, 16);
31405
+ return [s >> 16 & 255, s >> 8 & 255, s & 255];
31406
+ }, enumerable: false }, hexToAnsi256: { value: (u) => r.rgbToAnsi256(...r.hexToRgb(u)), enumerable: false }, ansi256ToAnsi: { value: (u) => {
31407
+ if (u < 8)
31408
+ return 30 + u;
31409
+ if (u < 16)
31410
+ return 90 + (u - 8);
31411
+ let t, F, s;
31412
+ if (u >= 232)
31413
+ t = ((u - 232) * 10 + 8) / 255, F = t, s = t;
31414
+ else {
31415
+ u -= 16;
31416
+ const C = u % 36;
31417
+ t = Math.floor(u / 36) / 5, F = Math.floor(C / 6) / 5, s = C % 6 / 5;
31418
+ }
31419
+ const i = Math.max(t, F, s) * 2;
31420
+ if (i === 0)
31421
+ return 30;
31422
+ let D = 30 + (Math.round(s) << 2 | Math.round(F) << 1 | Math.round(t));
31423
+ return i === 2 && (D += 60), D;
31424
+ }, enumerable: false }, rgbToAnsi: { value: (u, t, F) => r.ansi256ToAnsi(r.rgbToAnsi256(u, t, F)), enumerable: false }, hexToAnsi: { value: (u) => r.ansi256ToAnsi(r.hexToAnsi256(u)), enumerable: false } }), r;
31425
+ }
31426
+ var ED = rD();
31427
+ var d = new Set(["\x1B", "›"]);
31428
+ var oD = 39;
31429
+ var y = "\x07";
31430
+ var V = "[";
31431
+ var nD = "]";
31432
+ var G = "m";
31433
+ var _ = `${nD}8;;`;
31434
+ var z2 = (e) => `${d.values().next().value}${V}${e}${G}`;
31435
+ var K = (e) => `${d.values().next().value}${_}${e}${y}`;
31436
+ var aD = (e) => e.split(" ").map((u) => p(u));
31437
+ var k = (e, u, t) => {
31438
+ const F = [...u];
31439
+ let s = false, i = false, D = p(P(e[e.length - 1]));
31440
+ for (const [C, n] of F.entries()) {
31441
+ const E = p(n);
31442
+ if (D + E <= t ? e[e.length - 1] += n : (e.push(n), D = 0), d.has(n) && (s = true, i = F.slice(C + 1).join("").startsWith(_)), s) {
31443
+ i ? n === y && (s = false, i = false) : n === G && (s = false);
31444
+ continue;
31445
+ }
31446
+ D += E, D === t && C < F.length - 1 && (e.push(""), D = 0);
31447
+ }
31448
+ !D && e[e.length - 1].length > 0 && e.length > 1 && (e[e.length - 2] += e.pop());
31449
+ };
31450
+ var hD = (e) => {
31451
+ const u = e.split(" ");
31452
+ let t = u.length;
31453
+ for (;t > 0 && !(p(u[t - 1]) > 0); )
31454
+ t--;
31455
+ return t === u.length ? e : u.slice(0, t).join(" ") + u.slice(t).join("");
31456
+ };
31457
+ var lD = (e, u, t = {}) => {
31458
+ if (t.trim !== false && e.trim() === "")
31459
+ return "";
31460
+ let F = "", s, i;
31461
+ const D = aD(e);
31462
+ let C = [""];
31463
+ for (const [E, a] of e.split(" ").entries()) {
31464
+ t.trim !== false && (C[C.length - 1] = C[C.length - 1].trimStart());
31465
+ let o = p(C[C.length - 1]);
31466
+ if (E !== 0 && (o >= u && (t.wordWrap === false || t.trim === false) && (C.push(""), o = 0), (o > 0 || t.trim === false) && (C[C.length - 1] += " ", o++)), t.hard && D[E] > u) {
31467
+ const c = u - o, f = 1 + Math.floor((D[E] - c - 1) / u);
31468
+ Math.floor((D[E] - 1) / u) < f && C.push(""), k(C, a, u);
31469
+ continue;
31470
+ }
31471
+ if (o + D[E] > u && o > 0 && D[E] > 0) {
31472
+ if (t.wordWrap === false && o < u) {
31473
+ k(C, a, u);
31474
+ continue;
31475
+ }
31476
+ C.push("");
31477
+ }
31478
+ if (o + D[E] > u && t.wordWrap === false) {
31479
+ k(C, a, u);
31480
+ continue;
31481
+ }
31482
+ C[C.length - 1] += a;
31483
+ }
31484
+ t.trim !== false && (C = C.map((E) => hD(E)));
31485
+ const n = [...C.join(`
31486
+ `)];
31487
+ for (const [E, a] of n.entries()) {
31488
+ if (F += a, d.has(a)) {
31489
+ const { groups: c } = new RegExp(`(?:\\${V}(?<code>\\d+)m|\\${_}(?<uri>.*)${y})`).exec(n.slice(E).join("")) || { groups: {} };
31490
+ if (c.code !== undefined) {
31491
+ const f = Number.parseFloat(c.code);
31492
+ s = f === oD ? undefined : f;
31493
+ } else
31494
+ c.uri !== undefined && (i = c.uri.length === 0 ? undefined : c.uri);
31495
+ }
31496
+ const o = ED.codes.get(Number(s));
31497
+ n[E + 1] === `
31498
+ ` ? (i && (F += K("")), s && o && (F += z2(o))) : a === `
31499
+ ` && (s && o && (F += z2(s)), i && (F += K(i)));
31500
+ }
31501
+ return F;
31502
+ };
31503
+ function Y(e, u, t) {
31504
+ return String(e).normalize().replace(/\r\n/g, `
31505
+ `).split(`
31506
+ `).map((F) => lD(F, u, t)).join(`
31507
+ `);
31508
+ }
31509
+ var xD = ["up", "down", "left", "right", "space", "enter", "cancel"];
31510
+ var B = { actions: new Set(xD), aliases: new Map([["k", "up"], ["j", "down"], ["h", "left"], ["l", "right"], ["\x03", "cancel"], ["escape", "cancel"]]) };
31511
+ function $(e, u) {
31512
+ if (typeof e == "string")
31513
+ return B.aliases.get(e) === u;
31514
+ for (const t of e)
31515
+ if (t !== undefined && $(t, u))
31516
+ return true;
31517
+ return false;
31518
+ }
31519
+ function BD(e, u) {
31520
+ if (e === u)
31521
+ return;
31522
+ const t = e.split(`
31523
+ `), F = u.split(`
31524
+ `), s = [];
31525
+ for (let i = 0;i < Math.max(t.length, F.length); i++)
31526
+ t[i] !== F[i] && s.push(i);
31527
+ return s;
31528
+ }
31529
+ var AD = globalThis.process.platform.startsWith("win");
31530
+ var S = Symbol("clack:cancel");
31531
+ function pD(e) {
31532
+ return e === S;
31533
+ }
31534
+ function m(e, u) {
31535
+ const t = e;
31536
+ t.isTTY && t.setRawMode(u);
31537
+ }
31538
+ function fD({ input: e = j, output: u = M, overwrite: t = true, hideCursor: F = true } = {}) {
31539
+ const s = g.createInterface({ input: e, output: u, prompt: "", tabSize: 1 });
31540
+ g.emitKeypressEvents(e, s), e.isTTY && e.setRawMode(true);
31541
+ const i = (D, { name: C, sequence: n }) => {
31542
+ const E = String(D);
31543
+ if ($([E, C, n], "cancel")) {
31544
+ F && u.write(import_sisteransi.cursor.show), process.exit(0);
31545
+ return;
31546
+ }
31547
+ if (!t)
31548
+ return;
31549
+ const a = C === "return" ? 0 : -1, o = C === "return" ? -1 : 0;
31550
+ g.moveCursor(u, a, o, () => {
31551
+ g.clearLine(u, 1, () => {
31552
+ e.once("keypress", i);
31553
+ });
31554
+ });
31555
+ };
31556
+ return F && u.write(import_sisteransi.cursor.hide), e.once("keypress", i), () => {
31557
+ e.off("keypress", i), F && u.write(import_sisteransi.cursor.show), e.isTTY && !AD && e.setRawMode(false), s.terminal = false, s.close();
31558
+ };
31559
+ }
31560
+ var gD = Object.defineProperty;
31561
+ var vD = (e, u, t) => (u in e) ? gD(e, u, { enumerable: true, configurable: true, writable: true, value: t }) : e[u] = t;
31562
+ var h = (e, u, t) => (vD(e, typeof u != "symbol" ? u + "" : u, t), t);
31563
+
31564
+ class x {
31565
+ constructor(u, t = true) {
31566
+ h(this, "input"), h(this, "output"), h(this, "_abortSignal"), h(this, "rl"), h(this, "opts"), h(this, "_render"), h(this, "_track", false), h(this, "_prevFrame", ""), h(this, "_subscribers", new Map), h(this, "_cursor", 0), h(this, "state", "initial"), h(this, "error", ""), h(this, "value");
31567
+ const { input: F = j, output: s = M, render: i, signal: D, ...C } = u;
31568
+ this.opts = C, this.onKeypress = this.onKeypress.bind(this), this.close = this.close.bind(this), this.render = this.render.bind(this), this._render = i.bind(this), this._track = t, this._abortSignal = D, this.input = F, this.output = s;
31569
+ }
31570
+ unsubscribe() {
31571
+ this._subscribers.clear();
31572
+ }
31573
+ setSubscriber(u, t) {
31574
+ const F = this._subscribers.get(u) ?? [];
31575
+ F.push(t), this._subscribers.set(u, F);
31576
+ }
31577
+ on(u, t) {
31578
+ this.setSubscriber(u, { cb: t });
31579
+ }
31580
+ once(u, t) {
31581
+ this.setSubscriber(u, { cb: t, once: true });
31582
+ }
31583
+ emit(u, ...t) {
31584
+ const F = this._subscribers.get(u) ?? [], s = [];
31585
+ for (const i of F)
31586
+ i.cb(...t), i.once && s.push(() => F.splice(F.indexOf(i), 1));
31587
+ for (const i of s)
31588
+ i();
31589
+ }
31590
+ prompt() {
31591
+ return new Promise((u, t) => {
31592
+ if (this._abortSignal) {
31593
+ if (this._abortSignal.aborted)
31594
+ return this.state = "cancel", this.close(), u(S);
31595
+ this._abortSignal.addEventListener("abort", () => {
31596
+ this.state = "cancel", this.close();
31597
+ }, { once: true });
31598
+ }
31599
+ const F = new X;
31600
+ F._write = (s, i, D) => {
31601
+ this._track && (this.value = this.rl?.line.replace(/\t/g, ""), this._cursor = this.rl?.cursor ?? 0, this.emit("value", this.value)), D();
31602
+ }, this.input.pipe(F), this.rl = O.createInterface({ input: this.input, output: F, tabSize: 2, prompt: "", escapeCodeTimeout: 50, terminal: true }), O.emitKeypressEvents(this.input, this.rl), this.rl.prompt(), this.opts.initialValue !== undefined && this._track && this.rl.write(this.opts.initialValue), this.input.on("keypress", this.onKeypress), m(this.input, true), this.output.on("resize", this.render), this.render(), this.once("submit", () => {
31603
+ this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), m(this.input, false), u(this.value);
31604
+ }), this.once("cancel", () => {
31605
+ this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), m(this.input, false), u(S);
31606
+ });
31607
+ });
31608
+ }
31609
+ onKeypress(u, t) {
31610
+ if (this.state === "error" && (this.state = "active"), t?.name && (!this._track && B.aliases.has(t.name) && this.emit("cursor", B.aliases.get(t.name)), B.actions.has(t.name) && this.emit("cursor", t.name)), u && (u.toLowerCase() === "y" || u.toLowerCase() === "n") && this.emit("confirm", u.toLowerCase() === "y"), u === "\t" && this.opts.placeholder && (this.value || (this.rl?.write(this.opts.placeholder), this.emit("value", this.opts.placeholder))), u && this.emit("key", u.toLowerCase()), t?.name === "return") {
31611
+ if (this.opts.validate) {
31612
+ const F = this.opts.validate(this.value);
31613
+ F && (this.error = F instanceof Error ? F.message : F, this.state = "error", this.rl?.write(this.value));
31614
+ }
31615
+ this.state !== "error" && (this.state = "submit");
31616
+ }
31617
+ $([u, t?.name, t?.sequence], "cancel") && (this.state = "cancel"), (this.state === "submit" || this.state === "cancel") && this.emit("finalize"), this.render(), (this.state === "submit" || this.state === "cancel") && this.close();
31618
+ }
31619
+ close() {
31620
+ this.input.unpipe(), this.input.removeListener("keypress", this.onKeypress), this.output.write(`
31621
+ `), m(this.input, false), this.rl?.close(), this.rl = undefined, this.emit(`${this.state}`, this.value), this.unsubscribe();
31622
+ }
31623
+ restoreCursor() {
31624
+ const u = Y(this._prevFrame, process.stdout.columns, { hard: true }).split(`
31625
+ `).length - 1;
31626
+ this.output.write(import_sisteransi.cursor.move(-999, u * -1));
31627
+ }
31628
+ render() {
31629
+ const u = Y(this._render(this) ?? "", process.stdout.columns, { hard: true });
31630
+ if (u !== this._prevFrame) {
31631
+ if (this.state === "initial")
31632
+ this.output.write(import_sisteransi.cursor.hide);
31633
+ else {
31634
+ const t = BD(this._prevFrame, u);
31635
+ if (this.restoreCursor(), t && t?.length === 1) {
31636
+ const F = t[0];
31637
+ this.output.write(import_sisteransi.cursor.move(0, F)), this.output.write(import_sisteransi.erase.lines(1));
31638
+ const s = u.split(`
31639
+ `);
31640
+ this.output.write(s[F]), this._prevFrame = u, this.output.write(import_sisteransi.cursor.move(0, s.length - F - 1));
31641
+ return;
31642
+ }
31643
+ if (t && t?.length > 1) {
31644
+ const F = t[0];
31645
+ this.output.write(import_sisteransi.cursor.move(0, F)), this.output.write(import_sisteransi.erase.down());
31646
+ const s = u.split(`
31647
+ `).slice(F);
31648
+ this.output.write(s.join(`
31649
+ `)), this._prevFrame = u;
31650
+ return;
31651
+ }
31652
+ this.output.write(import_sisteransi.erase.down());
31653
+ }
31654
+ this.output.write(u), this.state === "initial" && (this.state = "active"), this._prevFrame = u;
31655
+ }
31656
+ }
31657
+ }
32637
31658
 
32638
- ## Success Criteria
32639
- - [ ] [Measurable criterion]
32640
- \\\`\\\`\\\`
31659
+ class dD extends x {
31660
+ get cursor() {
31661
+ return this.value ? 0 : 1;
31662
+ }
31663
+ get _value() {
31664
+ return this.cursor === 0;
31665
+ }
31666
+ constructor(u) {
31667
+ super(u, false), this.value = !!u.initialValue, this.on("value", () => {
31668
+ this.value = this._value;
31669
+ }), this.on("confirm", (t) => {
31670
+ this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = t, this.state = "submit", this.close();
31671
+ }), this.on("cursor", () => {
31672
+ this.value = !this.value;
31673
+ });
31674
+ }
31675
+ }
31676
+ var A;
31677
+ A = new WeakMap;
31678
+ var kD = Object.defineProperty;
31679
+ var $D = (e, u, t) => (u in e) ? kD(e, u, { enumerable: true, configurable: true, writable: true, value: t }) : e[u] = t;
31680
+ var H = (e, u, t) => ($D(e, typeof u != "symbol" ? u + "" : u, t), t);
31681
+ var SD = class extends x {
31682
+ constructor(u) {
31683
+ super(u, false), H(this, "options"), H(this, "cursor", 0), this.options = u.options, this.value = [...u.initialValues ?? []], this.cursor = Math.max(this.options.findIndex(({ value: t }) => t === u.cursorAt), 0), this.on("key", (t) => {
31684
+ t === "a" && this.toggleAll();
31685
+ }), this.on("cursor", (t) => {
31686
+ switch (t) {
31687
+ case "left":
31688
+ case "up":
31689
+ this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
31690
+ break;
31691
+ case "down":
31692
+ case "right":
31693
+ this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
31694
+ break;
31695
+ case "space":
31696
+ this.toggleValue();
31697
+ break;
31698
+ }
31699
+ });
31700
+ }
31701
+ get _value() {
31702
+ return this.options[this.cursor].value;
31703
+ }
31704
+ toggleAll() {
31705
+ const u = this.value.length === this.options.length;
31706
+ this.value = u ? [] : this.options.map((t) => t.value);
31707
+ }
31708
+ toggleValue() {
31709
+ const u = this.value.includes(this._value);
31710
+ this.value = u ? this.value.filter((t) => t !== this._value) : [...this.value, this._value];
31711
+ }
31712
+ };
31713
+ var OD = Object.defineProperty;
31714
+ var PD = (e, u, t) => (u in e) ? OD(e, u, { enumerable: true, configurable: true, writable: true, value: t }) : e[u] = t;
31715
+ var J = (e, u, t) => (PD(e, typeof u != "symbol" ? u + "" : u, t), t);
32641
31716
 
32642
- ### 2B.4 Create Plan
31717
+ class LD extends x {
31718
+ constructor(u) {
31719
+ super(u, false), J(this, "options"), J(this, "cursor", 0), this.options = u.options, this.cursor = this.options.findIndex(({ value: t }) => t === u.initialValue), this.cursor === -1 && (this.cursor = 0), this.changeValue(), this.on("cursor", (t) => {
31720
+ switch (t) {
31721
+ case "left":
31722
+ case "up":
31723
+ this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
31724
+ break;
31725
+ case "down":
31726
+ case "right":
31727
+ this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
31728
+ break;
31729
+ }
31730
+ this.changeValue();
31731
+ });
31732
+ }
31733
+ get _value() {
31734
+ return this.options[this.cursor];
31735
+ }
31736
+ changeValue() {
31737
+ this.value = this._value.value;
31738
+ }
31739
+ }
31740
+ class RD extends x {
31741
+ get valueWithCursor() {
31742
+ if (this.state === "submit")
31743
+ return this.value;
31744
+ if (this.cursor >= this.value.length)
31745
+ return `${this.value}█`;
31746
+ const u = this.value.slice(0, this.cursor), [t, ...F] = this.value.slice(this.cursor);
31747
+ return `${u}${import_picocolors.default.inverse(t)}${F.join("")}`;
31748
+ }
31749
+ get cursor() {
31750
+ return this._cursor;
31751
+ }
31752
+ constructor(u) {
31753
+ super(u), this.on("finalize", () => {
31754
+ this.value || (this.value = u.defaultValue);
31755
+ });
31756
+ }
31757
+ }
32643
31758
 
32644
- Call \`harmony_create_plan\` with:
32645
- - \`title\`: The plan title
32646
- - \`content\`: Full markdown document from Step 2B.3
32647
- - \`source\`: \`"agent"\`
32648
- - \`workflowPhase\`: \`"plan"\`
32649
- - \`tasks\`: Array of tasks from the Tasks section, each with:
32650
- - \`content\`: Task title + brief description
32651
- - \`priority\`: \`"high"\`, \`"medium"\`, or \`"low"\`
32652
- - \`status\`: \`"pending"\`
31759
+ // ../../node_modules/@clack/prompts/dist/index.mjs
31760
+ var import_picocolors2 = __toESM(require_picocolors(), 1);
31761
+ var import_sisteransi2 = __toESM(require_src(), 1);
31762
+ import y2 from "node:process";
31763
+ function ce() {
31764
+ return y2.platform !== "win32" ? y2.env.TERM !== "linux" : !!y2.env.CI || !!y2.env.WT_SESSION || !!y2.env.TERMINUS_SUBLIME || y2.env.ConEmuTask === "{cmd::Cmder}" || y2.env.TERM_PROGRAM === "Terminus-Sublime" || y2.env.TERM_PROGRAM === "vscode" || y2.env.TERM === "xterm-256color" || y2.env.TERM === "alacritty" || y2.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
31765
+ }
31766
+ var V2 = ce();
31767
+ var u = (t, n) => V2 ? t : n;
31768
+ var le = u("◆", "*");
31769
+ var L2 = u("■", "x");
31770
+ var W2 = u("▲", "x");
31771
+ var C = u("◇", "o");
31772
+ var ue = u("┌", "T");
31773
+ var o = u("│", "|");
31774
+ var d2 = u("└", "—");
31775
+ var k2 = u("●", ">");
31776
+ var P2 = u("○", " ");
31777
+ var A2 = u("◻", "[•]");
31778
+ var T = u("◼", "[+]");
31779
+ var F = u("◻", "[ ]");
31780
+ var $e = u("▪", "•");
31781
+ var _2 = u("─", "-");
31782
+ var me = u("╮", "+");
31783
+ var de = u("├", "+");
31784
+ var pe = u("╯", "+");
31785
+ var q = u("●", "•");
31786
+ var D = u("◆", "*");
31787
+ var U = u("▲", "!");
31788
+ var K2 = u("■", "x");
31789
+ var b2 = (t) => {
31790
+ switch (t) {
31791
+ case "initial":
31792
+ case "active":
31793
+ return import_picocolors2.default.cyan(le);
31794
+ case "cancel":
31795
+ return import_picocolors2.default.red(L2);
31796
+ case "error":
31797
+ return import_picocolors2.default.yellow(W2);
31798
+ case "submit":
31799
+ return import_picocolors2.default.green(C);
31800
+ }
31801
+ };
31802
+ var G2 = (t) => {
31803
+ const { cursor: n, options: r2, style: i } = t, s = t.maxItems ?? Number.POSITIVE_INFINITY, c = Math.max(process.stdout.rows - 4, 0), a = Math.min(c, Math.max(s, 5));
31804
+ let l2 = 0;
31805
+ n >= l2 + a - 3 ? l2 = Math.max(Math.min(n - a + 3, r2.length - a), 0) : n < l2 + 2 && (l2 = Math.max(n - 2, 0));
31806
+ const $2 = a < r2.length && l2 > 0, g2 = a < r2.length && l2 + a < r2.length;
31807
+ return r2.slice(l2, l2 + a).map((p2, v2, f) => {
31808
+ const j2 = v2 === 0 && $2, E = v2 === f.length - 1 && g2;
31809
+ return j2 || E ? import_picocolors2.default.dim("...") : i(p2, v2 + l2 === n);
31810
+ });
31811
+ };
31812
+ var he = (t) => new RD({ validate: t.validate, placeholder: t.placeholder, defaultValue: t.defaultValue, initialValue: t.initialValue, render() {
31813
+ const n = `${import_picocolors2.default.gray(o)}
31814
+ ${b2(this.state)} ${t.message}
31815
+ `, r2 = t.placeholder ? import_picocolors2.default.inverse(t.placeholder[0]) + import_picocolors2.default.dim(t.placeholder.slice(1)) : import_picocolors2.default.inverse(import_picocolors2.default.hidden("_")), i = this.value ? this.valueWithCursor : r2;
31816
+ switch (this.state) {
31817
+ case "error":
31818
+ return `${n.trim()}
31819
+ ${import_picocolors2.default.yellow(o)} ${i}
31820
+ ${import_picocolors2.default.yellow(d2)} ${import_picocolors2.default.yellow(this.error)}
31821
+ `;
31822
+ case "submit":
31823
+ return `${n}${import_picocolors2.default.gray(o)} ${import_picocolors2.default.dim(this.value || t.placeholder)}`;
31824
+ case "cancel":
31825
+ return `${n}${import_picocolors2.default.gray(o)} ${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(this.value ?? ""))}${this.value?.trim() ? `
31826
+ ${import_picocolors2.default.gray(o)}` : ""}`;
31827
+ default:
31828
+ return `${n}${import_picocolors2.default.cyan(o)} ${i}
31829
+ ${import_picocolors2.default.cyan(d2)}
31830
+ `;
31831
+ }
31832
+ } }).prompt();
31833
+ var ye = (t) => {
31834
+ const n = t.active ?? "Yes", r2 = t.inactive ?? "No";
31835
+ return new dD({ active: n, inactive: r2, initialValue: t.initialValue ?? true, render() {
31836
+ const i = `${import_picocolors2.default.gray(o)}
31837
+ ${b2(this.state)} ${t.message}
31838
+ `, s = this.value ? n : r2;
31839
+ switch (this.state) {
31840
+ case "submit":
31841
+ return `${i}${import_picocolors2.default.gray(o)} ${import_picocolors2.default.dim(s)}`;
31842
+ case "cancel":
31843
+ return `${i}${import_picocolors2.default.gray(o)} ${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(s))}
31844
+ ${import_picocolors2.default.gray(o)}`;
31845
+ default:
31846
+ return `${i}${import_picocolors2.default.cyan(o)} ${this.value ? `${import_picocolors2.default.green(k2)} ${n}` : `${import_picocolors2.default.dim(P2)} ${import_picocolors2.default.dim(n)}`} ${import_picocolors2.default.dim("/")} ${this.value ? `${import_picocolors2.default.dim(P2)} ${import_picocolors2.default.dim(r2)}` : `${import_picocolors2.default.green(k2)} ${r2}`}
31847
+ ${import_picocolors2.default.cyan(d2)}
31848
+ `;
31849
+ }
31850
+ } }).prompt();
31851
+ };
31852
+ var ve = (t) => {
31853
+ const n = (r2, i) => {
31854
+ const s = r2.label ?? String(r2.value);
31855
+ switch (i) {
31856
+ case "selected":
31857
+ return `${import_picocolors2.default.dim(s)}`;
31858
+ case "active":
31859
+ return `${import_picocolors2.default.green(k2)} ${s} ${r2.hint ? import_picocolors2.default.dim(`(${r2.hint})`) : ""}`;
31860
+ case "cancelled":
31861
+ return `${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(s))}`;
31862
+ default:
31863
+ return `${import_picocolors2.default.dim(P2)} ${import_picocolors2.default.dim(s)}`;
31864
+ }
31865
+ };
31866
+ return new LD({ options: t.options, initialValue: t.initialValue, render() {
31867
+ const r2 = `${import_picocolors2.default.gray(o)}
31868
+ ${b2(this.state)} ${t.message}
31869
+ `;
31870
+ switch (this.state) {
31871
+ case "submit":
31872
+ return `${r2}${import_picocolors2.default.gray(o)} ${n(this.options[this.cursor], "selected")}`;
31873
+ case "cancel":
31874
+ return `${r2}${import_picocolors2.default.gray(o)} ${n(this.options[this.cursor], "cancelled")}
31875
+ ${import_picocolors2.default.gray(o)}`;
31876
+ default:
31877
+ return `${r2}${import_picocolors2.default.cyan(o)} ${G2({ cursor: this.cursor, options: this.options, maxItems: t.maxItems, style: (i, s) => n(i, s ? "active" : "inactive") }).join(`
31878
+ ${import_picocolors2.default.cyan(o)} `)}
31879
+ ${import_picocolors2.default.cyan(d2)}
31880
+ `;
31881
+ }
31882
+ } }).prompt();
31883
+ };
31884
+ var fe = (t) => {
31885
+ const n = (r2, i) => {
31886
+ const s = r2.label ?? String(r2.value);
31887
+ return i === "active" ? `${import_picocolors2.default.cyan(A2)} ${s} ${r2.hint ? import_picocolors2.default.dim(`(${r2.hint})`) : ""}` : i === "selected" ? `${import_picocolors2.default.green(T)} ${import_picocolors2.default.dim(s)} ${r2.hint ? import_picocolors2.default.dim(`(${r2.hint})`) : ""}` : i === "cancelled" ? `${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(s))}` : i === "active-selected" ? `${import_picocolors2.default.green(T)} ${s} ${r2.hint ? import_picocolors2.default.dim(`(${r2.hint})`) : ""}` : i === "submitted" ? `${import_picocolors2.default.dim(s)}` : `${import_picocolors2.default.dim(F)} ${import_picocolors2.default.dim(s)}`;
31888
+ };
31889
+ return new SD({ options: t.options, initialValues: t.initialValues, required: t.required ?? true, cursorAt: t.cursorAt, validate(r2) {
31890
+ if (this.required && r2.length === 0)
31891
+ return `Please select at least one option.
31892
+ ${import_picocolors2.default.reset(import_picocolors2.default.dim(`Press ${import_picocolors2.default.gray(import_picocolors2.default.bgWhite(import_picocolors2.default.inverse(" space ")))} to select, ${import_picocolors2.default.gray(import_picocolors2.default.bgWhite(import_picocolors2.default.inverse(" enter ")))} to submit`))}`;
31893
+ }, render() {
31894
+ const r2 = `${import_picocolors2.default.gray(o)}
31895
+ ${b2(this.state)} ${t.message}
31896
+ `, i = (s, c) => {
31897
+ const a = this.value.includes(s.value);
31898
+ return c && a ? n(s, "active-selected") : a ? n(s, "selected") : n(s, c ? "active" : "inactive");
31899
+ };
31900
+ switch (this.state) {
31901
+ case "submit":
31902
+ return `${r2}${import_picocolors2.default.gray(o)} ${this.options.filter(({ value: s }) => this.value.includes(s)).map((s) => n(s, "submitted")).join(import_picocolors2.default.dim(", ")) || import_picocolors2.default.dim("none")}`;
31903
+ case "cancel": {
31904
+ const s = this.options.filter(({ value: c }) => this.value.includes(c)).map((c) => n(c, "cancelled")).join(import_picocolors2.default.dim(", "));
31905
+ return `${r2}${import_picocolors2.default.gray(o)} ${s.trim() ? `${s}
31906
+ ${import_picocolors2.default.gray(o)}` : ""}`;
31907
+ }
31908
+ case "error": {
31909
+ const s = this.error.split(`
31910
+ `).map((c, a) => a === 0 ? `${import_picocolors2.default.yellow(d2)} ${import_picocolors2.default.yellow(c)}` : ` ${c}`).join(`
31911
+ `);
31912
+ return `${r2 + import_picocolors2.default.yellow(o)} ${G2({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
31913
+ ${import_picocolors2.default.yellow(o)} `)}
31914
+ ${s}
31915
+ `;
31916
+ }
31917
+ default:
31918
+ return `${r2}${import_picocolors2.default.cyan(o)} ${G2({ options: this.options, cursor: this.cursor, maxItems: t.maxItems, style: i }).join(`
31919
+ ${import_picocolors2.default.cyan(o)} `)}
31920
+ ${import_picocolors2.default.cyan(d2)}
31921
+ `;
31922
+ }
31923
+ } }).prompt();
31924
+ };
31925
+ var xe = (t = "") => {
31926
+ process.stdout.write(`${import_picocolors2.default.gray(d2)} ${import_picocolors2.default.red(t)}
32653
31927
 
32654
- ### 2B.5 — User Approval
31928
+ `);
31929
+ };
31930
+ var Se = (t = "") => {
31931
+ process.stdout.write(`${import_picocolors2.default.gray(o)}
31932
+ ${import_picocolors2.default.gray(d2)} ${t}
32655
31933
 
32656
- Show the user:
32657
- - Plan URL: \`https://gethmy.com/plans/{id}\`
32658
- - Number of tasks created
32659
- - Brief summary
31934
+ `);
31935
+ };
31936
+ var M2 = { message: (t = "", { symbol: n = import_picocolors2.default.gray(o) } = {}) => {
31937
+ const r2 = [`${import_picocolors2.default.gray(o)}`];
31938
+ if (t) {
31939
+ const [i, ...s] = t.split(`
31940
+ `);
31941
+ r2.push(`${n} ${i}`, ...s.map((c) => `${import_picocolors2.default.gray(o)} ${c}`));
31942
+ }
31943
+ process.stdout.write(`${r2.join(`
31944
+ `)}
31945
+ `);
31946
+ }, info: (t) => {
31947
+ M2.message(t, { symbol: import_picocolors2.default.blue(q) });
31948
+ }, success: (t) => {
31949
+ M2.message(t, { symbol: import_picocolors2.default.green(D) });
31950
+ }, step: (t) => {
31951
+ M2.message(t, { symbol: import_picocolors2.default.green(C) });
31952
+ }, warn: (t) => {
31953
+ M2.message(t, { symbol: import_picocolors2.default.yellow(U) });
31954
+ }, warning: (t) => {
31955
+ M2.warn(t);
31956
+ }, error: (t) => {
31957
+ M2.message(t, { symbol: import_picocolors2.default.red(K2) });
31958
+ } };
31959
+ var J2 = `${import_picocolors2.default.gray(o)} `;
31960
+ var Y2 = ({ indicator: t = "dots" } = {}) => {
31961
+ const n = V2 ? ["◒", "◐", "◓", "◑"] : ["•", "o", "O", "0"], r2 = V2 ? 80 : 120, i = process.env.CI === "true";
31962
+ let s, c, a = false, l2 = "", $2, g2 = performance.now();
31963
+ const p2 = (m2) => {
31964
+ const h2 = m2 > 1 ? "Something went wrong" : "Canceled";
31965
+ a && N2(h2, m2);
31966
+ }, v2 = () => p2(2), f = () => p2(1), j2 = () => {
31967
+ process.on("uncaughtExceptionMonitor", v2), process.on("unhandledRejection", v2), process.on("SIGINT", f), process.on("SIGTERM", f), process.on("exit", p2);
31968
+ }, E = () => {
31969
+ process.removeListener("uncaughtExceptionMonitor", v2), process.removeListener("unhandledRejection", v2), process.removeListener("SIGINT", f), process.removeListener("SIGTERM", f), process.removeListener("exit", p2);
31970
+ }, B2 = () => {
31971
+ if ($2 === undefined)
31972
+ return;
31973
+ i && process.stdout.write(`
31974
+ `);
31975
+ const m2 = $2.split(`
31976
+ `);
31977
+ process.stdout.write(import_sisteransi2.cursor.move(-999, m2.length - 1)), process.stdout.write(import_sisteransi2.erase.down(m2.length));
31978
+ }, R2 = (m2) => m2.replace(/\.+$/, ""), O2 = (m2) => {
31979
+ const h2 = (performance.now() - m2) / 1000, w2 = Math.floor(h2 / 60), I2 = Math.floor(h2 % 60);
31980
+ return w2 > 0 ? `[${w2}m ${I2}s]` : `[${I2}s]`;
31981
+ }, H2 = (m2 = "") => {
31982
+ a = true, s = fD(), l2 = R2(m2), g2 = performance.now(), process.stdout.write(`${import_picocolors2.default.gray(o)}
31983
+ `);
31984
+ let h2 = 0, w2 = 0;
31985
+ j2(), c = setInterval(() => {
31986
+ if (i && l2 === $2)
31987
+ return;
31988
+ B2(), $2 = l2;
31989
+ const I2 = import_picocolors2.default.magenta(n[h2]);
31990
+ if (i)
31991
+ process.stdout.write(`${I2} ${l2}...`);
31992
+ else if (t === "timer")
31993
+ process.stdout.write(`${I2} ${l2} ${O2(g2)}`);
31994
+ else {
31995
+ const z3 = ".".repeat(Math.floor(w2)).slice(0, 3);
31996
+ process.stdout.write(`${I2} ${l2}${z3}`);
31997
+ }
31998
+ h2 = h2 + 1 < n.length ? h2 + 1 : 0, w2 = w2 < n.length ? w2 + 0.125 : 0;
31999
+ }, r2);
32000
+ }, N2 = (m2 = "", h2 = 0) => {
32001
+ a = false, clearInterval(c), B2();
32002
+ const w2 = h2 === 0 ? import_picocolors2.default.green(C) : h2 === 1 ? import_picocolors2.default.red(L2) : import_picocolors2.default.red(W2);
32003
+ l2 = R2(m2 ?? l2), t === "timer" ? process.stdout.write(`${w2} ${l2} ${O2(g2)}
32004
+ `) : process.stdout.write(`${w2} ${l2}
32005
+ `), E(), s();
32006
+ };
32007
+ return { start: H2, stop: N2, message: (m2 = "") => {
32008
+ l2 = R2(m2 ?? l2);
32009
+ } };
32010
+ };
32660
32011
 
32661
- Then ask: **"Ready to execute? I'll create board cards from these tasks and start the execution phase."**
32012
+ // src/tui/agents.ts
32013
+ import { existsSync as existsSync4 } from "node:fs";
32014
+ import { homedir as homedir2 } from "node:os";
32015
+ import { join as join3 } from "node:path";
32016
+ var AGENT_DEFINITIONS = [
32017
+ {
32018
+ id: "claude",
32019
+ name: "Claude Code",
32020
+ description: "Anthropic CLI agent",
32021
+ hint: "/hmy <card>",
32022
+ globalPaths: [join3(homedir2(), ".claude")],
32023
+ localPaths: [".claude"]
32024
+ },
32025
+ {
32026
+ id: "codex",
32027
+ name: "Codex",
32028
+ description: "OpenAI coding agent",
32029
+ hint: "/prompts:hmy <card>",
32030
+ globalPaths: [join3(homedir2(), ".codex")],
32031
+ localPaths: ["AGENTS.md"]
32032
+ },
32033
+ {
32034
+ id: "cursor",
32035
+ name: "Cursor",
32036
+ description: "AI-powered IDE",
32037
+ hint: "MCP tools available automatically",
32038
+ globalPaths: [],
32039
+ localPaths: [".cursor", ".cursorrules"]
32040
+ },
32041
+ {
32042
+ id: "windsurf",
32043
+ name: "Windsurf",
32044
+ description: "Codeium AI IDE",
32045
+ hint: "MCP tools available automatically",
32046
+ globalPaths: [join3(homedir2(), ".codeium", "windsurf")],
32047
+ localPaths: [".windsurf", ".windsurfrules"]
32048
+ }
32049
+ ];
32050
+ function detectAgents(cwd = process.cwd()) {
32051
+ return AGENT_DEFINITIONS.map((def) => {
32052
+ const globalPath = def.globalPaths.find((p2) => existsSync4(p2)) || null;
32053
+ const localPath = def.localPaths.find((p2) => existsSync4(join3(cwd, p2))) || null;
32054
+ return {
32055
+ id: def.id,
32056
+ name: def.name,
32057
+ detected: !!(globalPath || localPath),
32058
+ globalPath,
32059
+ localPath: localPath ? join3(cwd, localPath) : null,
32060
+ description: def.description,
32061
+ hint: def.hint
32062
+ };
32063
+ });
32064
+ }
32662
32065
 
32663
- Options:
32664
- 1. **Yes, advance to Execute** proceed to Step 2B.6
32665
- 2. **Let me review first** end here, they can advance later from the UI
32666
- 3. **Make changes** — iterate on the plan
32066
+ // src/tui/docs.ts
32067
+ import { existsSync as existsSync5, readdirSync as readdirSync2, readFileSync as readFileSync4, statSync } from "node:fs";
32068
+ import { isAbsolute, join as join4, resolve, sep as sep2 } from "node:path";
32667
32069
 
32668
- ### 2B.6 — Advance to Execute
32070
+ // src/tui/theme.ts
32071
+ var pc = __toESM(require_picocolors(), 1);
32072
+ var symbols = {
32073
+ harmony: "▲",
32074
+ check: "✓",
32075
+ cross: "✗",
32076
+ bullet: "•",
32077
+ arrow: "→",
32078
+ arrowRight: "▸",
32079
+ dot: "●",
32080
+ dotEmpty: "○",
32081
+ info: "ℹ",
32082
+ warning: "⚠",
32083
+ pointer: "❯"
32084
+ };
32085
+ var colors = {
32086
+ brand: (text) => pc.cyan(text),
32087
+ brandBold: (text) => pc.bold(pc.cyan(text)),
32088
+ success: (text) => pc.green(text),
32089
+ error: (text) => pc.red(text),
32090
+ warning: (text) => pc.yellow(text),
32091
+ info: (text) => pc.blue(text),
32092
+ dim: (text) => pc.dim(text),
32093
+ bold: (text) => pc.bold(text),
32094
+ muted: (text) => pc.gray(text),
32095
+ highlight: (text) => pc.cyan(text),
32096
+ link: (text) => pc.underline(pc.cyan(text))
32097
+ };
32098
+ var messages = {
32099
+ header: () => {
32100
+ return `
32101
+ ${colors.brandBold(" HARMONY")}
32102
+ ${colors.dim(" Project management for AI agents")}
32103
+ `;
32104
+ },
32105
+ done: (message) => {
32106
+ return `${colors.success(symbols.check)} ${message}`;
32107
+ },
32108
+ fail: (message) => {
32109
+ return `${colors.error(symbols.cross)} ${message}`;
32110
+ },
32111
+ skip: (message) => {
32112
+ return `${colors.dim("-")} ${colors.dim(message)}`;
32113
+ },
32114
+ step: (number5, total, message) => {
32115
+ return `${colors.dim(`[${number5}/${total}]`)} ${message}`;
32116
+ },
32117
+ fileCreated: (path) => {
32118
+ return ` ${colors.success(symbols.check)} ${colors.dim(path)}`;
32119
+ },
32120
+ fileSkipped: (path) => {
32121
+ return ` ${colors.dim(symbols.bullet)} ${colors.dim(path)} ${colors.dim("(exists)")}`;
32122
+ },
32123
+ fileError: (path, error48) => {
32124
+ return ` ${colors.error(symbols.cross)} ${path}: ${colors.error(error48)}`;
32125
+ }
32126
+ };
32127
+ function formatPath(path, homeDir) {
32128
+ if (path.startsWith(homeDir)) {
32129
+ return `~${path.slice(homeDir.length)}`;
32130
+ }
32131
+ return path;
32132
+ }
32669
32133
 
32670
- Call \`harmony_advance_plan\` with:
32671
- - \`planId\`: The plan ID from Step 2B.4
32672
- - \`phase\`: \`"execute"\`
32673
- - \`summary\`: A 2-3 sentence summary of the key decisions made during planning
32134
+ // src/tui/docs.ts
32135
+ var IGNORED_DIRS = new Set([
32136
+ "node_modules",
32137
+ ".git",
32138
+ "dist",
32139
+ "build",
32140
+ ".next",
32141
+ ".nuxt",
32142
+ ".output",
32143
+ ".vercel",
32144
+ ".turbo",
32145
+ ".cache",
32146
+ "coverage",
32147
+ ".harmony-worktrees",
32148
+ "__pycache__",
32149
+ "target",
32150
+ "vendor"
32151
+ ]);
32152
+ function readJson(filePath) {
32153
+ try {
32154
+ return JSON.parse(readFileSync4(filePath, "utf-8"));
32155
+ } catch {
32156
+ return null;
32157
+ }
32158
+ }
32159
+ function readText(filePath) {
32160
+ try {
32161
+ return readFileSync4(filePath, "utf-8");
32162
+ } catch {
32163
+ return null;
32164
+ }
32165
+ }
32166
+ function listDirs(dirPath) {
32167
+ try {
32168
+ return readdirSync2(dirPath).filter((entry) => {
32169
+ if (IGNORED_DIRS.has(entry) || entry.startsWith("."))
32170
+ return false;
32171
+ try {
32172
+ return statSync(join4(dirPath, entry)).isDirectory();
32173
+ } catch {
32174
+ return false;
32175
+ }
32176
+ });
32177
+ } catch {
32178
+ return [];
32179
+ }
32180
+ }
32181
+ var DIR_DESCRIPTIONS = {
32182
+ components: "UI components",
32183
+ pages: "Route-level pages",
32184
+ routes: "Route-level pages",
32185
+ views: "Route-level pages",
32186
+ hooks: "Custom hooks",
32187
+ lib: "Utilities",
32188
+ utils: "Utilities",
32189
+ api: "API / server code",
32190
+ server: "API / server code",
32191
+ contexts: "State management",
32192
+ store: "State management",
32193
+ stores: "State management",
32194
+ types: "Type definitions",
32195
+ styles: "Stylesheets",
32196
+ public: "Static assets",
32197
+ static: "Static assets",
32198
+ assets: "Static assets",
32199
+ supabase: "Supabase backend",
32200
+ functions: "Edge functions",
32201
+ packages: "Monorepo packages",
32202
+ apps: "Monorepo applications",
32203
+ src: "Source code",
32204
+ test: "Tests",
32205
+ tests: "Tests",
32206
+ __tests__: "Tests",
32207
+ scripts: "Build / utility scripts",
32208
+ config: "Configuration",
32209
+ docs: "Documentation",
32210
+ migrations: "Database migrations",
32211
+ prisma: "Prisma schema & migrations",
32212
+ e2e: "End-to-end tests",
32213
+ cypress: "Cypress tests"
32214
+ };
32215
+ function describeDir(name) {
32216
+ return DIR_DESCRIPTIONS[name.toLowerCase()] ?? name;
32217
+ }
32218
+ function scanProject(cwd) {
32219
+ let packageManager = null;
32220
+ if (existsSync5(join4(cwd, "bun.lock")) || existsSync5(join4(cwd, "bun.lockb"))) {
32221
+ packageManager = "bun";
32222
+ } else if (existsSync5(join4(cwd, "pnpm-lock.yaml"))) {
32223
+ packageManager = "pnpm";
32224
+ } else if (existsSync5(join4(cwd, "yarn.lock"))) {
32225
+ packageManager = "yarn";
32226
+ } else if (existsSync5(join4(cwd, "package.json"))) {
32227
+ packageManager = "npm";
32228
+ }
32229
+ const pkg = readJson(join4(cwd, "package.json"));
32230
+ const scripts = pkg && typeof pkg.scripts === "object" && pkg.scripts !== null ? pkg.scripts : {};
32231
+ let language = "unknown";
32232
+ if (existsSync5(join4(cwd, "tsconfig.json"))) {
32233
+ language = "typescript";
32234
+ } else if (existsSync5(join4(cwd, "go.mod"))) {
32235
+ language = "go";
32236
+ } else if (existsSync5(join4(cwd, "Cargo.toml"))) {
32237
+ language = "rust";
32238
+ } else if (existsSync5(join4(cwd, "setup.py")) || existsSync5(join4(cwd, "pyproject.toml"))) {
32239
+ language = "python";
32240
+ } else if (pkg) {
32241
+ language = "javascript";
32242
+ }
32243
+ let framework = null;
32244
+ if (pkg) {
32245
+ const deps = {
32246
+ ...typeof pkg.dependencies === "object" ? pkg.dependencies : {},
32247
+ ...typeof pkg.devDependencies === "object" ? pkg.devDependencies : {}
32248
+ };
32249
+ if (deps.next) {
32250
+ framework = "next";
32251
+ } else if (deps.react && deps.vite) {
32252
+ framework = "react+vite";
32253
+ } else if (deps.react) {
32254
+ framework = "react";
32255
+ } else if (deps.vue && deps.vite) {
32256
+ framework = "vue+vite";
32257
+ } else if (deps.vue && deps.nuxt) {
32258
+ framework = "nuxt";
32259
+ } else if (deps.vue) {
32260
+ framework = "vue";
32261
+ } else if (deps.astro) {
32262
+ framework = "astro";
32263
+ } else if (deps.svelte) {
32264
+ framework = "svelte";
32265
+ } else if (deps.express) {
32266
+ framework = "express";
32267
+ } else if (deps.fastify) {
32268
+ framework = "fastify";
32269
+ } else if (deps.hono) {
32270
+ framework = "hono";
32271
+ }
32272
+ }
32273
+ let linter = null;
32274
+ if (existsSync5(join4(cwd, "biome.json")) || existsSync5(join4(cwd, "biome.jsonc"))) {
32275
+ linter = "biome";
32276
+ } else {
32277
+ const eslintFiles = [
32278
+ ".eslintrc",
32279
+ ".eslintrc.js",
32280
+ ".eslintrc.cjs",
32281
+ ".eslintrc.json",
32282
+ ".eslintrc.yml",
32283
+ ".eslintrc.yaml",
32284
+ "eslint.config.js",
32285
+ "eslint.config.mjs",
32286
+ "eslint.config.cjs",
32287
+ "eslint.config.ts"
32288
+ ];
32289
+ if (eslintFiles.some((f) => existsSync5(join4(cwd, f)))) {
32290
+ linter = "eslint";
32291
+ } else {
32292
+ const prettierFiles = [
32293
+ ".prettierrc",
32294
+ ".prettierrc.js",
32295
+ ".prettierrc.json",
32296
+ ".prettierrc.yml",
32297
+ ".prettierrc.yaml",
32298
+ "prettier.config.js",
32299
+ "prettier.config.mjs"
32300
+ ];
32301
+ if (prettierFiles.some((f) => existsSync5(join4(cwd, f)))) {
32302
+ linter = "prettier";
32303
+ }
32304
+ }
32305
+ }
32306
+ let indentStyle = null;
32307
+ const biome = readJson(join4(cwd, "biome.json")) ?? readJson(join4(cwd, "biome.jsonc"));
32308
+ if (biome) {
32309
+ const formatter = biome.formatter;
32310
+ if (formatter) {
32311
+ const type = formatter.indentStyle === "tab" ? "tab" : "space";
32312
+ const width = typeof formatter.indentWidth === "number" ? formatter.indentWidth : 2;
32313
+ indentStyle = { type, width };
32314
+ }
32315
+ }
32316
+ if (!indentStyle) {
32317
+ const editorConfig = readText(join4(cwd, ".editorconfig"));
32318
+ if (editorConfig) {
32319
+ const styleMatch = editorConfig.match(/indent_style\s*=\s*(space|tab)/);
32320
+ const sizeMatch = editorConfig.match(/indent_size\s*=\s*(\d+)/);
32321
+ if (styleMatch) {
32322
+ indentStyle = {
32323
+ type: styleMatch[1],
32324
+ width: sizeMatch ? Number.parseInt(sizeMatch[1], 10) : 2
32325
+ };
32326
+ }
32327
+ }
32328
+ }
32329
+ const dirs = listDirs(cwd);
32330
+ const srcDirs = existsSync5(join4(cwd, "src")) ? listDirs(join4(cwd, "src")) : [];
32331
+ const monorepo = existsSync5(join4(cwd, "packages")) || existsSync5(join4(cwd, "apps"));
32332
+ const existingDocs = {
32333
+ agentsMd: existsSync5(join4(cwd, "AGENTS.md")),
32334
+ claudeMd: existsSync5(join4(cwd, "CLAUDE.md")),
32335
+ docsDir: existsSync5(join4(cwd, "docs")),
32336
+ architectureMd: existsSync5(join4(cwd, "docs", "architecture.md"))
32337
+ };
32338
+ return {
32339
+ packageManager,
32340
+ scripts,
32341
+ language,
32342
+ framework,
32343
+ linter,
32344
+ indentStyle,
32345
+ dirs,
32346
+ srcDirs,
32347
+ monorepo,
32348
+ existingDocs
32349
+ };
32350
+ }
32351
+ function runCmd(pm) {
32352
+ if (pm === "bun")
32353
+ return "bun run";
32354
+ if (pm === "pnpm")
32355
+ return "pnpm run";
32356
+ if (pm === "yarn")
32357
+ return "yarn";
32358
+ return "npm run";
32359
+ }
32360
+ function describeScript(name) {
32361
+ const map3 = {
32362
+ dev: "Dev server",
32363
+ start: "Start server",
32364
+ build: "Production build",
32365
+ lint: "Lint",
32366
+ "lint:fix": "Lint + autofix",
32367
+ format: "Format code",
32368
+ test: "Run tests",
32369
+ "test:watch": "Run tests (watch)",
32370
+ "test:e2e": "End-to-end tests",
32371
+ typecheck: "Type-check",
32372
+ "type-check": "Type-check",
32373
+ preview: "Preview production build",
32374
+ deploy: "Deploy",
32375
+ generate: "Code generation",
32376
+ migrate: "Run migrations",
32377
+ seed: "Seed database",
32378
+ clean: "Clean build artifacts",
32379
+ prepare: "Prepare (husky, etc.)"
32380
+ };
32381
+ return map3[name] ?? "";
32382
+ }
32383
+ function generateAgentsMd(info, _cwd) {
32384
+ const lang = info.language === "typescript" ? "TypeScript" : info.language === "javascript" ? "JavaScript" : info.language;
32385
+ const frameworkLabel = info.framework ? `${info.framework} ` : "";
32386
+ const monoLabel = info.monorepo ? " (monorepo)" : "";
32387
+ const lines = [];
32388
+ lines.push("# AGENTS.md");
32389
+ lines.push("");
32390
+ lines.push(`${frameworkLabel}${lang} project${monoLabel}.`);
32391
+ lines.push("");
32392
+ const scriptEntries = Object.entries(info.scripts);
32393
+ if (scriptEntries.length > 0 && info.packageManager) {
32394
+ const prefix = runCmd(info.packageManager);
32395
+ lines.push("## Commands");
32396
+ lines.push("");
32397
+ lines.push("```bash");
32398
+ const commands = scriptEntries.map(([name]) => `${prefix} ${name}`);
32399
+ const maxLen = Math.max(...commands.map((c) => c.length));
32400
+ for (let i = 0;i < scriptEntries.length; i++) {
32401
+ const [name] = scriptEntries[i];
32402
+ const cmd = commands[i];
32403
+ const desc = describeScript(name);
32404
+ if (desc) {
32405
+ lines.push(`${cmd}${" ".repeat(maxLen - cmd.length + 4)}# ${desc}`);
32406
+ } else {
32407
+ lines.push(cmd);
32408
+ }
32409
+ }
32410
+ lines.push("```");
32411
+ lines.push("");
32412
+ }
32413
+ lines.push("## Code Standards");
32414
+ lines.push("");
32415
+ const langLabel = info.language === "typescript" ? "TypeScript" : "JavaScript";
32416
+ if (info.language === "typescript" || info.language === "javascript") {
32417
+ lines.push(`- ${langLabel} with ES modules`);
32418
+ }
32419
+ if (info.indentStyle) {
32420
+ const unit = info.indentStyle.type === "tab" ? "tab" : "space";
32421
+ lines.push(`- ${info.indentStyle.width}-${unit} indentation`);
32422
+ }
32423
+ if (info.linter) {
32424
+ lines.push(`- Linted with ${info.linter}`);
32425
+ }
32426
+ lines.push("");
32427
+ lines.push("## Architecture");
32428
+ lines.push("");
32429
+ for (const dir of info.dirs) {
32430
+ lines.push(`- \`${dir}/\` — ${describeDir(dir)}`);
32431
+ }
32432
+ if (info.srcDirs.length > 0) {
32433
+ for (const sub of info.srcDirs) {
32434
+ lines.push(` - \`src/${sub}/\` — ${describeDir(sub)}`);
32435
+ }
32436
+ }
32437
+ lines.push("");
32438
+ return lines.join(`
32439
+ `);
32440
+ }
32441
+ function generateClaudeMd(info) {
32442
+ const lines = [];
32443
+ lines.push("# CLAUDE.md");
32444
+ lines.push("");
32445
+ lines.push("@AGENTS.md");
32446
+ if (info.existingDocs.architectureMd || info.dirs.includes("docs")) {
32447
+ lines.push("@docs/architecture.md");
32448
+ }
32449
+ lines.push("");
32450
+ return lines.join(`
32451
+ `);
32452
+ }
32453
+ function generateArchitectureMd(info, _cwd) {
32454
+ const lines = [];
32455
+ lines.push("# Architecture");
32456
+ lines.push("");
32457
+ lines.push("## Directory Structure");
32458
+ lines.push("");
32459
+ for (const dir of info.dirs) {
32460
+ lines.push(`- \`${dir}/\` — ${describeDir(dir)}`);
32461
+ }
32462
+ if (info.srcDirs.length > 0) {
32463
+ lines.push("");
32464
+ lines.push("### `src/`");
32465
+ lines.push("");
32466
+ for (const sub of info.srcDirs) {
32467
+ lines.push(`- \`src/${sub}/\` — ${describeDir(sub)}`);
32468
+ }
32469
+ }
32470
+ lines.push("");
32471
+ return lines.join(`
32472
+ `);
32473
+ }
32474
+ var VAGUE_STANDARDS = [
32475
+ "follow best practices",
32476
+ "use best practices",
32477
+ "keep it clean",
32478
+ "write clean code",
32479
+ "maintain code quality",
32480
+ "ensure quality",
32481
+ "use proper naming",
32482
+ "follow conventions",
32483
+ "be consistent"
32484
+ ];
32485
+ function verifyDocs(cwd) {
32486
+ const issues = [];
32487
+ const claudeMd = readText(join4(cwd, "CLAUDE.md"));
32488
+ const agentsMd = readText(join4(cwd, "AGENTS.md"));
32489
+ const pkg = readJson(join4(cwd, "package.json"));
32490
+ const pkgScripts = pkg && typeof pkg.scripts === "object" && pkg.scripts !== null ? pkg.scripts : {};
32491
+ const projectRoot = resolve(cwd);
32492
+ if (claudeMd) {
32493
+ const importedFiles = [];
32494
+ for (const line of claudeMd.split(`
32495
+ `)) {
32496
+ const match = line.match(/^@(.+)$/);
32497
+ if (match) {
32498
+ const refPath = match[1].trim();
32499
+ if (isAbsolute(refPath)) {
32500
+ issues.push({
32501
+ severity: "error",
32502
+ file: "CLAUDE.md",
32503
+ message: `@ reference uses an absolute path: ${refPath}`,
32504
+ fix: "Use a project-relative path under the repository root"
32505
+ });
32506
+ continue;
32507
+ }
32508
+ const resolvedPath = resolve(projectRoot, refPath);
32509
+ if (resolvedPath !== projectRoot && !resolvedPath.startsWith(projectRoot + sep2)) {
32510
+ issues.push({
32511
+ severity: "error",
32512
+ file: "CLAUDE.md",
32513
+ message: `@ reference escapes project root: ${refPath}`,
32514
+ fix: "Remove traversal segments (../) and keep references inside the repo"
32515
+ });
32516
+ continue;
32517
+ }
32518
+ importedFiles.push({ ref: refPath, resolved: resolvedPath });
32519
+ if (!existsSync5(resolvedPath)) {
32520
+ issues.push({
32521
+ severity: "error",
32522
+ file: "CLAUDE.md",
32523
+ message: `Referenced file does not exist: ${refPath}`,
32524
+ fix: `Remove the @${refPath} line or create the file`
32525
+ });
32526
+ }
32527
+ }
32528
+ }
32529
+ const claudeLines = claudeMd.split(`
32530
+ `).length;
32531
+ if (claudeLines > 100) {
32532
+ issues.push({
32533
+ severity: "warning",
32534
+ file: "CLAUDE.md",
32535
+ message: `CLAUDE.md is ${claudeLines} lines (recommended: under 100)`,
32536
+ fix: "Move detailed content to AGENTS.md or docs/ files and use @imports"
32537
+ });
32538
+ }
32539
+ if (importedFiles.length > 0) {
32540
+ const claudeHeadings = extractHeadings(claudeMd);
32541
+ for (const { ref: refPath, resolved: resolvedPath } of importedFiles) {
32542
+ const refContent = readText(resolvedPath);
32543
+ if (!refContent)
32544
+ continue;
32545
+ const refHeadings = extractHeadings(refContent);
32546
+ for (const heading of claudeHeadings) {
32547
+ if (refHeadings.has(heading)) {
32548
+ issues.push({
32549
+ severity: "warning",
32550
+ file: "CLAUDE.md",
32551
+ message: `Section "${heading}" duplicates content from @${refPath}`,
32552
+ fix: `Remove the "${heading}" section — it's already included via @import`
32553
+ });
32554
+ }
32555
+ }
32556
+ }
32557
+ }
32558
+ }
32559
+ if (agentsMd) {
32560
+ const agentsLines = agentsMd.split(`
32561
+ `);
32562
+ const contextLines = [];
32563
+ let pastFirstHeading = false;
32564
+ let hitNextSection = false;
32565
+ for (const line of agentsLines) {
32566
+ if (!pastFirstHeading) {
32567
+ if (line.startsWith("# ")) {
32568
+ pastFirstHeading = true;
32569
+ }
32570
+ continue;
32571
+ }
32572
+ if (line.startsWith("## ")) {
32573
+ hitNextSection = true;
32574
+ break;
32575
+ }
32576
+ const trimmed = line.trim();
32577
+ if (trimmed)
32578
+ contextLines.push(trimmed);
32579
+ }
32580
+ if (pastFirstHeading && !hitNextSection && contextLines.length === 0) {
32581
+ issues.push({
32582
+ severity: "warning",
32583
+ file: "AGENTS.md",
32584
+ message: "Missing project context line after the title heading",
32585
+ fix: "Add a single-line description: stack + what the project does"
32586
+ });
32587
+ } else if (contextLines.length > 1) {
32588
+ issues.push({
32589
+ severity: "warning",
32590
+ file: "AGENTS.md",
32591
+ message: `Project context should be exactly 1 line, found ${contextLines.length}`,
32592
+ fix: "Condense to a single line: stack + what the project does"
32593
+ });
32594
+ }
32595
+ const codeBlockRe = /```[\s\S]*?```/g;
32596
+ let blockMatch;
32597
+ while ((blockMatch = codeBlockRe.exec(agentsMd)) !== null) {
32598
+ const block = blockMatch[0];
32599
+ const cmdRe = /(?:bun|npm|pnpm|yarn)\s+(?:run\s+)?(\S+)/g;
32600
+ let cmdMatch;
32601
+ while ((cmdMatch = cmdRe.exec(block)) !== null) {
32602
+ const scriptName = cmdMatch[1];
32603
+ const builtins = new Set([
32604
+ "install",
32605
+ "init",
32606
+ "create",
32607
+ "exec",
32608
+ "dlx",
32609
+ "x",
32610
+ "test",
32611
+ "start"
32612
+ ]);
32613
+ if (builtins.has(scriptName))
32614
+ continue;
32615
+ if (Object.keys(pkgScripts).length > 0 && !(scriptName in pkgScripts)) {
32616
+ issues.push({
32617
+ severity: "warning",
32618
+ file: "AGENTS.md",
32619
+ message: `Command references script "${scriptName}" which is not in package.json`,
32620
+ fix: `Update the command or add "${scriptName}" to package.json scripts`
32621
+ });
32622
+ }
32623
+ }
32624
+ }
32625
+ const standardsSection = extractSection(agentsMd, "Code Standards");
32626
+ if (standardsSection) {
32627
+ const lower = standardsSection.toLowerCase();
32628
+ for (const phrase of VAGUE_STANDARDS) {
32629
+ if (lower.includes(phrase)) {
32630
+ issues.push({
32631
+ severity: "warning",
32632
+ file: "AGENTS.md",
32633
+ message: `Code Standards contains vague phrase: "${phrase}"`,
32634
+ fix: "Replace with specific, verifiable conventions derived from config files"
32635
+ });
32636
+ }
32637
+ }
32638
+ }
32639
+ if (Object.keys(pkgScripts).length > 0) {
32640
+ const hasTestScript = Object.keys(pkgScripts).some((k3) => k3 === "test" || k3.startsWith("test:"));
32641
+ if (!hasTestScript) {
32642
+ const mentionsNoTest = agentsMd.toLowerCase().includes("no test");
32643
+ if (!mentionsNoTest) {
32644
+ issues.push({
32645
+ severity: "warning",
32646
+ file: "AGENTS.md",
32647
+ message: "No test script in package.json and AGENTS.md doesn't mention it",
32648
+ fix: 'Add a note like "No test framework. Verify changes with `bun run build`."'
32649
+ });
32650
+ }
32651
+ }
32652
+ }
32653
+ checkBacktickPaths(agentsMd, "AGENTS.md", cwd, issues);
32654
+ }
32655
+ const archMd = readText(join4(cwd, "docs", "architecture.md"));
32656
+ if (archMd) {
32657
+ checkBacktickPaths(archMd, "docs/architecture.md", cwd, issues);
32658
+ }
32659
+ return issues;
32660
+ }
32661
+ function extractHeadings(content) {
32662
+ const headings = new Set;
32663
+ for (const line of content.split(`
32664
+ `)) {
32665
+ const match = line.match(/^#{2,3}\s+(.+)$/);
32666
+ if (match) {
32667
+ headings.add(match[1].trim());
32668
+ }
32669
+ }
32670
+ return headings;
32671
+ }
32672
+ function extractSection(content, heading) {
32673
+ const lines = content.split(`
32674
+ `);
32675
+ let capturing = false;
32676
+ const result = [];
32677
+ for (const line of lines) {
32678
+ if (capturing) {
32679
+ if (line.match(/^#{1,2}\s/))
32680
+ break;
32681
+ result.push(line);
32682
+ } else if (line.match(new RegExp(`^##\\s+${heading.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`, "i"))) {
32683
+ capturing = true;
32684
+ }
32685
+ }
32686
+ return result.length > 0 ? result.join(`
32687
+ `) : null;
32688
+ }
32689
+ function checkBacktickPaths(content, file2, cwd, issues) {
32690
+ const pathRe = /`((?:src\/|packages\/|apps\/|supabase\/|docs\/)[^`]+)`/g;
32691
+ let match;
32692
+ const checked = new Set;
32693
+ const root = resolve(cwd);
32694
+ while ((match = pathRe.exec(content)) !== null) {
32695
+ const refPath = match[1].replace(/\/$/, "");
32696
+ if (checked.has(refPath))
32697
+ continue;
32698
+ checked.add(refPath);
32699
+ const resolvedRef = resolve(root, refPath);
32700
+ if (resolvedRef !== root && !resolvedRef.startsWith(root + sep2))
32701
+ continue;
32702
+ if (!existsSync5(resolvedRef)) {
32703
+ issues.push({
32704
+ severity: "warning",
32705
+ file: file2,
32706
+ message: `Referenced path does not exist: ${refPath}`,
32707
+ fix: `Update or remove the \`${refPath}\` reference`
32708
+ });
32709
+ }
32710
+ }
32711
+ }
32712
+ async function runDocsStep(cwd) {
32713
+ const info = scanProject(cwd);
32714
+ const hasDocs = info.existingDocs.agentsMd || info.existingDocs.claudeMd;
32715
+ if (!hasDocs) {
32716
+ const shouldGenerate = await ye({
32717
+ message: "No project docs found. Generate AGENTS.md and CLAUDE.md?",
32718
+ initialValue: true
32719
+ });
32720
+ if (pD(shouldGenerate) || !shouldGenerate) {
32721
+ return { files: [], issues: [], skipped: true };
32722
+ }
32723
+ const files = [];
32724
+ files.push({
32725
+ path: join4(cwd, "AGENTS.md"),
32726
+ content: generateAgentsMd(info, cwd),
32727
+ type: "text"
32728
+ });
32729
+ files.push({
32730
+ path: join4(cwd, "CLAUDE.md"),
32731
+ content: generateClaudeMd(info),
32732
+ type: "text"
32733
+ });
32734
+ if (info.dirs.includes("docs") || info.srcDirs.length > 0) {
32735
+ files.push({
32736
+ path: join4(cwd, "docs", "architecture.md"),
32737
+ content: generateArchitectureMd(info, cwd),
32738
+ type: "text"
32739
+ });
32740
+ }
32741
+ M2.success(`Generated ${files.length} doc file(s): ${files.map((f) => f.path.replace(cwd + "/", "")).join(", ")}`);
32742
+ return { files, issues: [], skipped: false };
32743
+ }
32744
+ const shouldVerify = await ye({
32745
+ message: "Project docs found. Verify for issues?",
32746
+ initialValue: false
32747
+ });
32748
+ if (pD(shouldVerify) || !shouldVerify) {
32749
+ return { files: [], issues: [], skipped: true };
32750
+ }
32751
+ const issues = verifyDocs(cwd);
32752
+ if (issues.length === 0) {
32753
+ M2.success("No issues found in project docs.");
32754
+ } else {
32755
+ for (const issue2 of issues) {
32756
+ const prefix = `${colors.bold(issue2.file)}:`;
32757
+ if (issue2.severity === "error") {
32758
+ M2.error(`${prefix} ${issue2.message}`);
32759
+ } else {
32760
+ M2.warning(`${prefix} ${issue2.message}`);
32761
+ }
32762
+ if (issue2.fix) {
32763
+ M2.message(` ${symbols.arrow} ${colors.dim(issue2.fix)}`);
32764
+ }
32765
+ }
32766
+ M2.info(`Found ${issues.length} issue(s) (${issues.filter((i) => i.severity === "error").length} errors, ${issues.filter((i) => i.severity === "warning").length} warnings)`);
32767
+ }
32768
+ return { files: [], issues, skipped: false };
32769
+ }
32674
32770
 
32675
- Report the result:
32676
- - "Created N cards in 'To Do'. Use \`/hmy #<id>\` to start working on any card."
32677
- - List the created cards with their short IDs
32771
+ // src/tui/writer.ts
32772
+ import { existsSync as existsSync6, mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "node:fs";
32773
+ import { homedir as homedir3 } from "node:os";
32774
+ import { dirname as dirname2 } from "node:path";
32775
+ function ensureDir(dirPath) {
32776
+ if (!existsSync6(dirPath)) {
32777
+ mkdirSync4(dirPath, { recursive: true, mode: 493 });
32778
+ }
32779
+ }
32780
+ function writeFile(filePath, content, options = {}) {
32781
+ const exists = existsSync6(filePath);
32782
+ if (exists && !options.force) {
32783
+ return { path: filePath, action: "skip" };
32784
+ }
32785
+ try {
32786
+ ensureDir(dirname2(filePath));
32787
+ const mode = filePath.includes(".harmony-mcp") ? 384 : 420;
32788
+ writeFileSync4(filePath, content, { mode });
32789
+ return { path: filePath, action: exists ? "update" : "create" };
32790
+ } catch (error48) {
32791
+ return {
32792
+ path: filePath,
32793
+ action: "skip",
32794
+ error: error48 instanceof Error ? error48.message : String(error48)
32795
+ };
32796
+ }
32797
+ }
32798
+ function mergeJsonFile(filePath, updates, options = {}) {
32799
+ const exists = existsSync6(filePath);
32800
+ if (!exists) {
32801
+ try {
32802
+ ensureDir(dirname2(filePath));
32803
+ writeFileSync4(filePath, JSON.stringify(updates, null, 2), {
32804
+ mode: 420
32805
+ });
32806
+ return { path: filePath, action: "create" };
32807
+ } catch (error48) {
32808
+ return {
32809
+ path: filePath,
32810
+ action: "skip",
32811
+ error: error48 instanceof Error ? error48.message : String(error48)
32812
+ };
32813
+ }
32814
+ }
32815
+ try {
32816
+ const existing = JSON.parse(readFileSync5(filePath, "utf-8"));
32817
+ if (updates.mcpServers && existing.mcpServers) {
32818
+ const existingServers = existing.mcpServers;
32819
+ const updateServers = updates.mcpServers;
32820
+ existing.mcpServers = { ...existingServers, ...updateServers };
32821
+ } else {
32822
+ Object.assign(existing, updates);
32823
+ }
32824
+ writeFileSync4(filePath, JSON.stringify(existing, null, 2), { mode: 420 });
32825
+ return { path: filePath, action: "merge" };
32826
+ } catch {
32827
+ if (options.force) {
32828
+ try {
32829
+ writeFileSync4(filePath, JSON.stringify(updates, null, 2), {
32830
+ mode: 420
32831
+ });
32832
+ return { path: filePath, action: "update" };
32833
+ } catch (error48) {
32834
+ return {
32835
+ path: filePath,
32836
+ action: "skip",
32837
+ error: error48 instanceof Error ? error48.message : String(error48)
32838
+ };
32839
+ }
32840
+ }
32841
+ return {
32842
+ path: filePath,
32843
+ action: "skip",
32844
+ error: "Could not parse existing file"
32845
+ };
32846
+ }
32847
+ }
32848
+ function appendToToml(filePath, section, content, options = {}) {
32849
+ const exists = existsSync6(filePath);
32850
+ if (!exists) {
32851
+ try {
32852
+ ensureDir(dirname2(filePath));
32853
+ writeFileSync4(filePath, content, { mode: 420 });
32854
+ return { path: filePath, action: "create" };
32855
+ } catch (error48) {
32856
+ return {
32857
+ path: filePath,
32858
+ action: "skip",
32859
+ error: error48 instanceof Error ? error48.message : String(error48)
32860
+ };
32861
+ }
32862
+ }
32863
+ try {
32864
+ const existing = readFileSync5(filePath, "utf-8");
32865
+ if (existing.includes(section)) {
32866
+ if (options.force) {
32867
+ const updated = existing.replace(new RegExp(`\\[${section.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\][\\s\\S]*?(?=\\[|$)`), content.trim() + `
32678
32868
 
32679
- ## Key Tools Reference
32869
+ `);
32870
+ writeFileSync4(filePath, updated, { mode: 420 });
32871
+ return { path: filePath, action: "update" };
32872
+ }
32873
+ return { path: filePath, action: "skip" };
32874
+ }
32875
+ writeFileSync4(filePath, existing + `
32876
+ ` + content, { mode: 420 });
32877
+ return { path: filePath, action: "merge" };
32878
+ } catch (error48) {
32879
+ return {
32880
+ path: filePath,
32881
+ action: "skip",
32882
+ error: error48 instanceof Error ? error48.message : String(error48)
32883
+ };
32884
+ }
32885
+ }
32886
+ async function writeFilesWithProgress(files, options = {}) {
32887
+ const results = [];
32888
+ const home = homedir3();
32889
+ const spinner = Y2();
32890
+ spinner.start("Writing configuration files...");
32891
+ for (const file2 of files) {
32892
+ let result;
32893
+ if (file2.type === "json") {
32894
+ const jsonContent = JSON.parse(file2.content);
32895
+ result = mergeJsonFile(file2.path, jsonContent, options);
32896
+ } else if (file2.type === "toml" && file2.tomlSection) {
32897
+ result = appendToToml(file2.path, file2.tomlSection, file2.content, options);
32898
+ } else {
32899
+ result = writeFile(file2.path, file2.content, options);
32900
+ }
32901
+ results.push(result);
32902
+ await new Promise((resolve2) => setTimeout(resolve2, 50));
32903
+ }
32904
+ spinner.stop("Files written");
32905
+ for (const result of results) {
32906
+ const displayPath = formatPath(result.path, home);
32907
+ if (result.error) {
32908
+ console.log(messages.fileError(displayPath, result.error));
32909
+ } else if (result.action === "skip") {
32910
+ console.log(messages.fileSkipped(displayPath));
32911
+ } else {
32912
+ const actionLabel = result.action === "merge" ? "updated" : "created";
32913
+ console.log(` ${colors.success("✓")} ${colors.dim(displayPath)} ${colors.dim(`(${actionLabel})`)}`);
32914
+ }
32915
+ }
32916
+ return results;
32917
+ }
32918
+ function getWriteSummary(files, options = {}) {
32919
+ const toCreate = [];
32920
+ const toUpdate = [];
32921
+ const toSkip = [];
32922
+ const home = homedir3();
32923
+ for (const file2 of files) {
32924
+ const displayPath = formatPath(file2.path, home);
32925
+ const exists = existsSync6(file2.path);
32926
+ if (exists && !options.force) {
32927
+ toSkip.push(displayPath);
32928
+ } else if (exists) {
32929
+ toUpdate.push(displayPath);
32930
+ } else {
32931
+ toCreate.push(displayPath);
32932
+ }
32933
+ }
32934
+ return { toCreate, toUpdate, toSkip };
32935
+ }
32680
32936
 
32681
- **Discovery:** \`harmony_list_plans\`, \`harmony_get_plan\`, \`harmony_get_card_by_short_id\`
32682
- **Context:** \`harmony_get_board\`, \`harmony_recall\`, \`harmony_memory_search\`
32683
- **Planning:** \`harmony_create_plan\`, \`harmony_advance_plan\`, \`harmony_update_plan\`
32684
- **Execution:** \`harmony_create_card\`, \`harmony_update_card\`
32685
- `;
32937
+ // src/tui/setup.ts
32938
+ var GLOBAL_SKILLS_DIR = join5(homedir4(), ".agents", "skills");
32939
+ var API_URL = "https://gethmy.com/api";
32686
32940
  async function registerMcpServer() {
32687
32941
  try {
32688
32942
  const { execSync } = await import("node:child_process");
@@ -32695,16 +32949,16 @@ async function registerMcpServer() {
32695
32949
  }
32696
32950
  }
32697
32951
  async function writeMcpConfigFallback(home) {
32698
- const { readFileSync: readFileSync5, writeFileSync: writeFileSync4, mkdirSync: mkdirSync5, existsSync: existsSync7 } = await import("node:fs");
32952
+ const { readFileSync: readFileSync6, writeFileSync: writeFileSync5, mkdirSync: mkdirSync6, existsSync: existsSync8 } = await import("node:fs");
32699
32953
  const settingsPath = join5(home, ".claude", "settings.json");
32700
- const settingsDir = dirname2(settingsPath);
32701
- if (!existsSync7(settingsDir)) {
32702
- mkdirSync5(settingsDir, { recursive: true });
32954
+ const settingsDir = dirname3(settingsPath);
32955
+ if (!existsSync8(settingsDir)) {
32956
+ mkdirSync6(settingsDir, { recursive: true });
32703
32957
  }
32704
32958
  let settings = {};
32705
- if (existsSync7(settingsPath)) {
32959
+ if (existsSync8(settingsPath)) {
32706
32960
  try {
32707
- settings = JSON.parse(readFileSync5(settingsPath, "utf-8"));
32961
+ settings = JSON.parse(readFileSync6(settingsPath, "utf-8"));
32708
32962
  } catch {}
32709
32963
  }
32710
32964
  const mcpServers = settings.mcpServers || {};
@@ -32713,7 +32967,7 @@ async function writeMcpConfigFallback(home) {
32713
32967
  args: ["-y", "@gethmy/mcp@latest", "serve"]
32714
32968
  };
32715
32969
  settings.mcpServers = mcpServers;
32716
- writeFileSync4(settingsPath, JSON.stringify(settings, null, 2));
32970
+ writeFileSync5(settingsPath, JSON.stringify(settings, null, 2));
32717
32971
  }
32718
32972
  async function validateApiKey(apiKey, apiUrl = API_URL) {
32719
32973
  try {
@@ -32784,22 +33038,8 @@ function getAgentFiles(agentId, cwd, installMode = "global") {
32784
33038
  const symlinks = [];
32785
33039
  switch (agentId) {
32786
33040
  case "claude": {
32787
- const skillContent = `---
32788
- name: hmy
32789
- description: Start working on a Harmony card. Use when given a card reference like #42, UUID, or card name to implement.
32790
- argument-hint: <card-reference>
32791
- ---
32792
-
32793
- ${HARMONY_WORKFLOW_PROMPT.replace("Your agent identifier", "claude-code").replace("Your agent name", "Claude Code")}
32794
- `;
32795
- const planSkillContent = `---
32796
- name: hmy-plan
32797
- description: Create a new plan or work on an existing one. Use when asked to plan a feature, execute a plan, review a plan, or given a plan reference.
32798
- argument-hint: [plan name, ID, or topic to plan]
32799
- ---
32800
-
32801
- ${HARMONY_PLAN_PROMPT.replace("$ARGUMENTS", "$ARGUMENTS")}
32802
- `;
33041
+ const skillContent = buildSkillFile("hmy", "claude");
33042
+ const planSkillContent = buildSkillFile("hmy-plan", "claude");
32803
33043
  if (installMode === "global") {
32804
33044
  files.push({
32805
33045
  path: join5(GLOBAL_SKILLS_DIR, "hmy", "SKILL.md"),
@@ -33227,7 +33467,9 @@ async function runSetup(options = {}) {
33227
33467
  console.log(` ${colors.bold("Project:")} ${selectedProjectName || selectedProjectId}`);
33228
33468
  }
33229
33469
  if (allFiles.length > 0) {
33230
- const summary = getWriteSummary(allFiles, { force: options.force });
33470
+ const summary = getWriteSummary(allFiles, {
33471
+ force: options.force || needsSkills
33472
+ });
33231
33473
  if (summary.toCreate.length > 0) {
33232
33474
  console.log("");
33233
33475
  console.log(` ${colors.success("Files to create:")}`);
@@ -33268,14 +33510,16 @@ async function runSetup(options = {}) {
33268
33510
  }
33269
33511
  console.log("");
33270
33512
  if (allFiles.length > 0) {
33271
- await writeFilesWithProgress(allFiles, { force: options.force });
33513
+ await writeFilesWithProgress(allFiles, {
33514
+ force: options.force || needsSkills
33515
+ });
33272
33516
  }
33273
33517
  if (allSymlinks.length > 0) {
33274
33518
  for (const symlink of allSymlinks) {
33275
33519
  try {
33276
- const linkDir = dirname2(symlink.link);
33277
- if (!existsSync6(linkDir)) {
33278
- mkdirSync4(linkDir, { recursive: true });
33520
+ const linkDir = dirname3(symlink.link);
33521
+ if (!existsSync7(linkDir)) {
33522
+ mkdirSync5(linkDir, { recursive: true });
33279
33523
  }
33280
33524
  let linkExists = false;
33281
33525
  try {
@@ -33351,6 +33595,7 @@ var require2 = createRequire2(import.meta.url);
33351
33595
  var { version: version2 } = require2("../package.json");
33352
33596
  program.name("@gethmy/mcp").description("MCP server for Harmony Kanban board").version(version2);
33353
33597
  program.command("serve").description("Start the MCP server (stdio transport)").action(async () => {
33598
+ await refreshSkills();
33354
33599
  const server = new HarmonyMCPServer;
33355
33600
  await server.run();
33356
33601
  });