@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 +1979 -1734
- package/dist/index.js +14 -0
- package/dist/lib/cli.js +2 -0
- package/dist/lib/context-assembly.js +21 -0
- package/dist/lib/skills.js +569 -0
- package/dist/lib/tui/setup.js +12 -310
- package/package.json +1 -1
- package/src/cli.ts +2 -0
- package/src/context-assembly.ts +21 -0
- package/src/skills.ts +607 -0
- package/src/tui/setup.ts +12 -313
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/
|
|
30749
|
-
import {
|
|
30750
|
-
|
|
30751
|
-
|
|
30752
|
-
|
|
30753
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
31118
|
-
|
|
31119
|
-
|
|
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
|
-
|
|
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
|
-
|
|
31218
|
-
|
|
31219
|
-
|
|
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
|
-
|
|
31395
|
-
|
|
31396
|
-
|
|
31397
|
-
|
|
31398
|
-
|
|
31399
|
-
|
|
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
|
-
|
|
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
|
-
|
|
31525
|
-
|
|
31526
|
-
|
|
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
|
-
|
|
31529
|
-
|
|
31530
|
-
|
|
31531
|
-
|
|
31532
|
-
|
|
31533
|
-
|
|
31534
|
-
|
|
31535
|
-
|
|
31536
|
-
|
|
31537
|
-
|
|
31538
|
-
|
|
31539
|
-
|
|
31540
|
-
|
|
31541
|
-
|
|
31542
|
-
|
|
31543
|
-
|
|
31544
|
-
|
|
31545
|
-
|
|
31546
|
-
|
|
31547
|
-
|
|
31548
|
-
|
|
31549
|
-
|
|
31550
|
-
|
|
31551
|
-
|
|
31552
|
-
|
|
31553
|
-
|
|
31554
|
-
|
|
31555
|
-
|
|
31556
|
-
|
|
31557
|
-
|
|
31558
|
-
|
|
31559
|
-
|
|
31560
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
30848
|
+
Parse \`$ARGUMENTS\` to determine what the user wants:
|
|
32401
30849
|
|
|
32402
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
30913
|
+
### B5. Implement Solution
|
|
32442
30914
|
|
|
32443
|
-
Work on the card following the generated prompt's guidance.
|
|
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
|
-
**
|
|
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
|
-
|
|
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.
|
|
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
|
|
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
|
-
|
|
32639
|
-
|
|
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
|
-
|
|
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
|
-
|
|
32645
|
-
|
|
32646
|
-
|
|
32647
|
-
|
|
32648
|
-
|
|
32649
|
-
-
|
|
32650
|
-
|
|
32651
|
-
|
|
32652
|
-
|
|
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
|
-
|
|
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
|
-
|
|
32657
|
-
|
|
32658
|
-
|
|
32659
|
-
|
|
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
|
-
|
|
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
|
-
|
|
32664
|
-
|
|
32665
|
-
|
|
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
|
-
|
|
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
|
-
|
|
32671
|
-
|
|
32672
|
-
|
|
32673
|
-
|
|
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
|
-
|
|
32676
|
-
|
|
32677
|
-
|
|
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
|
-
|
|
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
|
-
|
|
32682
|
-
|
|
32683
|
-
|
|
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:
|
|
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 =
|
|
32701
|
-
if (!
|
|
32702
|
-
|
|
32954
|
+
const settingsDir = dirname3(settingsPath);
|
|
32955
|
+
if (!existsSync8(settingsDir)) {
|
|
32956
|
+
mkdirSync6(settingsDir, { recursive: true });
|
|
32703
32957
|
}
|
|
32704
32958
|
let settings = {};
|
|
32705
|
-
if (
|
|
32959
|
+
if (existsSync8(settingsPath)) {
|
|
32706
32960
|
try {
|
|
32707
|
-
settings = JSON.parse(
|
|
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
|
-
|
|
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
|
-
|
|
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, {
|
|
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, {
|
|
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 =
|
|
33277
|
-
if (!
|
|
33278
|
-
|
|
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
|
});
|