harmony-mcp 1.3.2 → 1.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -13786,6 +13786,134 @@ var require_dist = __commonJS((exports, module) => {
13786
13786
  exports.default = formatsPlugin;
13787
13787
  });
13788
13788
 
13789
+ // ../../node_modules/sisteransi/src/index.js
13790
+ var require_src = __commonJS((exports, module) => {
13791
+ var ESC = "\x1B";
13792
+ var CSI = `${ESC}[`;
13793
+ var beep = "\x07";
13794
+ var cursor = {
13795
+ to(x, y) {
13796
+ if (!y)
13797
+ return `${CSI}${x + 1}G`;
13798
+ return `${CSI}${y + 1};${x + 1}H`;
13799
+ },
13800
+ move(x, y) {
13801
+ let ret = "";
13802
+ if (x < 0)
13803
+ ret += `${CSI}${-x}D`;
13804
+ else if (x > 0)
13805
+ ret += `${CSI}${x}C`;
13806
+ if (y < 0)
13807
+ ret += `${CSI}${-y}A`;
13808
+ else if (y > 0)
13809
+ ret += `${CSI}${y}B`;
13810
+ return ret;
13811
+ },
13812
+ up: (count = 1) => `${CSI}${count}A`,
13813
+ down: (count = 1) => `${CSI}${count}B`,
13814
+ forward: (count = 1) => `${CSI}${count}C`,
13815
+ backward: (count = 1) => `${CSI}${count}D`,
13816
+ nextLine: (count = 1) => `${CSI}E`.repeat(count),
13817
+ prevLine: (count = 1) => `${CSI}F`.repeat(count),
13818
+ left: `${CSI}G`,
13819
+ hide: `${CSI}?25l`,
13820
+ show: `${CSI}?25h`,
13821
+ save: `${ESC}7`,
13822
+ restore: `${ESC}8`
13823
+ };
13824
+ var scroll = {
13825
+ up: (count = 1) => `${CSI}S`.repeat(count),
13826
+ down: (count = 1) => `${CSI}T`.repeat(count)
13827
+ };
13828
+ var erase = {
13829
+ screen: `${CSI}2J`,
13830
+ up: (count = 1) => `${CSI}1J`.repeat(count),
13831
+ down: (count = 1) => `${CSI}J`.repeat(count),
13832
+ line: `${CSI}2K`,
13833
+ lineEnd: `${CSI}K`,
13834
+ lineStart: `${CSI}1K`,
13835
+ lines(count) {
13836
+ let clear = "";
13837
+ for (let i = 0;i < count; i++)
13838
+ clear += this.line + (i < count - 1 ? cursor.up() : "");
13839
+ if (count)
13840
+ clear += cursor.left;
13841
+ return clear;
13842
+ }
13843
+ };
13844
+ module.exports = { cursor, scroll, erase, beep };
13845
+ });
13846
+
13847
+ // ../../node_modules/picocolors/picocolors.js
13848
+ var require_picocolors = __commonJS((exports, module) => {
13849
+ var p = process || {};
13850
+ var argv = p.argv || [];
13851
+ var env = p.env || {};
13852
+ var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
13853
+ var formatter = (open, close, replace = open) => (input) => {
13854
+ let string4 = "" + input, index = string4.indexOf(close, open.length);
13855
+ return ~index ? open + replaceClose(string4, close, replace, index) + close : open + string4 + close;
13856
+ };
13857
+ var replaceClose = (string4, close, replace, index) => {
13858
+ let result = "", cursor = 0;
13859
+ do {
13860
+ result += string4.substring(cursor, index) + replace;
13861
+ cursor = index + close.length;
13862
+ index = string4.indexOf(close, cursor);
13863
+ } while (~index);
13864
+ return result + string4.substring(cursor);
13865
+ };
13866
+ var createColors = (enabled = isColorSupported) => {
13867
+ let f = enabled ? formatter : () => String;
13868
+ return {
13869
+ isColorSupported: enabled,
13870
+ reset: f("\x1B[0m", "\x1B[0m"),
13871
+ bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
13872
+ dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
13873
+ italic: f("\x1B[3m", "\x1B[23m"),
13874
+ underline: f("\x1B[4m", "\x1B[24m"),
13875
+ inverse: f("\x1B[7m", "\x1B[27m"),
13876
+ hidden: f("\x1B[8m", "\x1B[28m"),
13877
+ strikethrough: f("\x1B[9m", "\x1B[29m"),
13878
+ black: f("\x1B[30m", "\x1B[39m"),
13879
+ red: f("\x1B[31m", "\x1B[39m"),
13880
+ green: f("\x1B[32m", "\x1B[39m"),
13881
+ yellow: f("\x1B[33m", "\x1B[39m"),
13882
+ blue: f("\x1B[34m", "\x1B[39m"),
13883
+ magenta: f("\x1B[35m", "\x1B[39m"),
13884
+ cyan: f("\x1B[36m", "\x1B[39m"),
13885
+ white: f("\x1B[37m", "\x1B[39m"),
13886
+ gray: f("\x1B[90m", "\x1B[39m"),
13887
+ bgBlack: f("\x1B[40m", "\x1B[49m"),
13888
+ bgRed: f("\x1B[41m", "\x1B[49m"),
13889
+ bgGreen: f("\x1B[42m", "\x1B[49m"),
13890
+ bgYellow: f("\x1B[43m", "\x1B[49m"),
13891
+ bgBlue: f("\x1B[44m", "\x1B[49m"),
13892
+ bgMagenta: f("\x1B[45m", "\x1B[49m"),
13893
+ bgCyan: f("\x1B[46m", "\x1B[49m"),
13894
+ bgWhite: f("\x1B[47m", "\x1B[49m"),
13895
+ blackBright: f("\x1B[90m", "\x1B[39m"),
13896
+ redBright: f("\x1B[91m", "\x1B[39m"),
13897
+ greenBright: f("\x1B[92m", "\x1B[39m"),
13898
+ yellowBright: f("\x1B[93m", "\x1B[39m"),
13899
+ blueBright: f("\x1B[94m", "\x1B[39m"),
13900
+ magentaBright: f("\x1B[95m", "\x1B[39m"),
13901
+ cyanBright: f("\x1B[96m", "\x1B[39m"),
13902
+ whiteBright: f("\x1B[97m", "\x1B[39m"),
13903
+ bgBlackBright: f("\x1B[100m", "\x1B[49m"),
13904
+ bgRedBright: f("\x1B[101m", "\x1B[49m"),
13905
+ bgGreenBright: f("\x1B[102m", "\x1B[49m"),
13906
+ bgYellowBright: f("\x1B[103m", "\x1B[49m"),
13907
+ bgBlueBright: f("\x1B[104m", "\x1B[49m"),
13908
+ bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
13909
+ bgCyanBright: f("\x1B[106m", "\x1B[49m"),
13910
+ bgWhiteBright: f("\x1B[107m", "\x1B[49m")
13911
+ };
13912
+ };
13913
+ module.exports = createColors();
13914
+ module.exports.createColors = createColors;
13915
+ });
13916
+
13789
13917
  // src/init.ts
13790
13918
  import { existsSync, mkdirSync, writeFileSync, readFileSync } from "node:fs";
13791
13919
  import { join, dirname } from "node:path";
@@ -13865,6 +13993,94 @@ If pausing: \`harmony_end_agent_session\` with \`status: "paused"\`
13865
13993
 
13866
13994
  **AI:** \`harmony_generate_prompt\`, \`harmony_process_command\`
13867
13995
  `;
13996
+ var HARMONY_STANDUP_PROMPT = `# Harmony Daily Standup
13997
+
13998
+ Generate a daily standup summary for the current project.
13999
+
14000
+ ## 1. Get Board State
14001
+
14002
+ Call \`harmony_get_board\` to get the full board state including:
14003
+ - All columns and their cards
14004
+ - Card priorities, assignees, and due dates
14005
+ - Active agent sessions
14006
+
14007
+ ## 2. Analyze Board
14008
+
14009
+ Organize the information into standup categories:
14010
+
14011
+ ### What was completed recently
14012
+ - Cards in "Done" or "Review" columns
14013
+ - Cards with recent activity (moved, updated)
14014
+
14015
+ ### What's in progress
14016
+ - Cards in "In Progress" column
14017
+ - Cards with active agent sessions (show progress %)
14018
+ - Who's working on what
14019
+
14020
+ ### What's blocked or at risk
14021
+ - High-priority cards not in progress
14022
+ - Overdue cards
14023
+ - Cards with blockers
14024
+
14025
+ ### What's coming up
14026
+ - Cards in "To Do" column
14027
+ - Upcoming due dates
14028
+
14029
+ ## 3. Present Summary
14030
+
14031
+ Format the summary as a clean, readable standup report:
14032
+ - Use bullet points for easy scanning
14033
+ - Highlight priorities and blockers
14034
+ - Include card short IDs for easy reference (e.g., #42)
14035
+ - Note any agent work in progress
14036
+ `;
14037
+ var HARMONY_CLEANUP_PROMPT = `# Harmony Board Cleanup
14038
+
14039
+ Analyze the board and suggest cleanup actions.
14040
+
14041
+ ## 1. Get Board State
14042
+
14043
+ Call \`harmony_get_board\` to get the full board state.
14044
+
14045
+ ## 2. Identify Issues
14046
+
14047
+ Look for:
14048
+
14049
+ ### Stale cards
14050
+ - Cards in "In Progress" for too long without updates
14051
+ - Cards with past due dates
14052
+ - Cards with no recent activity
14053
+
14054
+ ### Organizational issues
14055
+ - Cards missing priorities
14056
+ - Cards missing assignees in active columns
14057
+ - Empty descriptions on complex cards
14058
+
14059
+ ### Potential duplicates
14060
+ - Cards with similar titles
14061
+ - Use \`harmony_search_cards\` if needed to find related cards
14062
+
14063
+ ## 3. Suggest Actions
14064
+
14065
+ For each issue found, suggest a specific action:
14066
+ - Move stale cards back to backlog
14067
+ - Archive completed cards
14068
+ - Update missing information
14069
+ - Merge or link duplicates
14070
+
14071
+ Present suggestions as a prioritized list with:
14072
+ - Card reference (#ID)
14073
+ - Current state
14074
+ - Suggested action
14075
+ - Why it matters
14076
+
14077
+ ## 4. Optional: Execute Cleanup
14078
+
14079
+ If the user approves, execute the suggested actions:
14080
+ - Use \`harmony_move_card\` to reorganize
14081
+ - Use \`harmony_update_card\` to add missing info
14082
+ - Use \`harmony_add_link_to_card\` to link related cards
14083
+ `;
13868
14084
  function ensureDir(dirPath) {
13869
14085
  if (!existsSync(dirPath)) {
13870
14086
  mkdirSync(dirPath, { recursive: true });
@@ -13923,6 +14139,30 @@ ${HARMONY_WORKFLOW_PROMPT.replace("Your agent identifier", "claude-code").replac
13923
14139
  result.filesCreated.push(commandPath);
13924
14140
  if (skipped)
13925
14141
  result.filesSkipped.push(commandPath);
14142
+ const standupContent = `---
14143
+ description: Generate a daily standup summary for the current Harmony project
14144
+ ---
14145
+
14146
+ ${HARMONY_STANDUP_PROMPT}
14147
+ `;
14148
+ const standupPath = join(cwd, ".claude", "commands", "hmy-standup.md");
14149
+ const standupResult = writeFileIfNotExists(standupPath, standupContent, force);
14150
+ if (standupResult.created)
14151
+ result.filesCreated.push(standupPath);
14152
+ if (standupResult.skipped)
14153
+ result.filesSkipped.push(standupPath);
14154
+ const cleanupContent = `---
14155
+ description: Analyze the Harmony board and suggest cleanup actions for stale cards
14156
+ ---
14157
+
14158
+ ${HARMONY_CLEANUP_PROMPT}
14159
+ `;
14160
+ const cleanupPath = join(cwd, ".claude", "commands", "hmy-cleanup.md");
14161
+ const cleanupResult = writeFileIfNotExists(cleanupPath, cleanupContent, force);
14162
+ if (cleanupResult.created)
14163
+ result.filesCreated.push(cleanupPath);
14164
+ if (cleanupResult.skipped)
14165
+ result.filesSkipped.push(cleanupPath);
13926
14166
  const globalConfigPath = join(homedir(), ".claude", "settings.json");
13927
14167
  const mcpConfig = {
13928
14168
  mcpServers: {
@@ -14183,7 +14423,7 @@ var {
14183
14423
  } = import__.default;
14184
14424
 
14185
14425
  // src/cli.ts
14186
- import { createInterface } from "node:readline";
14426
+ import { createInterface as createInterface2 } from "node:readline";
14187
14427
 
14188
14428
  // ../../node_modules/zod/v4/core/core.js
14189
14429
  var NEVER = Object.freeze({
@@ -26204,23 +26444,11 @@ var RESOURCES = [
26204
26444
  mimeType: "application/json"
26205
26445
  }
26206
26446
  ];
26207
- var PROMPTS = {
26208
- harmony_daily_standup: {
26209
- name: "Daily Standup Summary",
26210
- description: "Generate a summary of recent activity and current work items",
26211
- arguments: [{ name: "projectId", description: "Project to summarize", required: false }]
26212
- },
26213
- harmony_board_cleanup: {
26214
- name: "Board Cleanup Suggestions",
26215
- description: "Identify stale cards and suggest cleanup actions",
26216
- arguments: []
26217
- }
26218
- };
26219
26447
 
26220
26448
  class HarmonyMCPServer {
26221
26449
  server;
26222
26450
  constructor() {
26223
- this.server = new Server({ name: "harmony-mcp", version: "1.0.0" }, { capabilities: { tools: {}, resources: {}, prompts: {} } });
26451
+ this.server = new Server({ name: "harmony-mcp", version: "1.0.0" }, { capabilities: { tools: {}, resources: {} } });
26224
26452
  this.setupHandlers();
26225
26453
  }
26226
26454
  setupHandlers() {
@@ -26268,58 +26496,6 @@ class HarmonyMCPServer {
26268
26496
  }
26269
26497
  throw new Error(`Unknown resource: ${uri}`);
26270
26498
  });
26271
- this.server.setRequestHandler(ListPromptsRequestSchema, async () => ({
26272
- prompts: Object.entries(PROMPTS).map(([name, prompt]) => ({
26273
- name,
26274
- description: prompt.description,
26275
- arguments: prompt.arguments
26276
- }))
26277
- }));
26278
- this.server.setRequestHandler(GetPromptRequestSchema, async (request) => {
26279
- const { name, arguments: args } = request.params;
26280
- if (name === "harmony_daily_standup") {
26281
- const projectId = args?.projectId || getActiveProjectId();
26282
- if (!projectId) {
26283
- return {
26284
- messages: [
26285
- {
26286
- role: "user",
26287
- content: { type: "text", text: "No project context. Please set a project first using harmony_set_project_context." }
26288
- }
26289
- ]
26290
- };
26291
- }
26292
- try {
26293
- const client2 = getClient();
26294
- const board = await client2.getBoard(projectId);
26295
- return {
26296
- messages: [
26297
- {
26298
- role: "user",
26299
- content: {
26300
- type: "text",
26301
- text: `Generate a daily standup summary for this Harmony project board:
26302
-
26303
- ${JSON.stringify(board, null, 2)}
26304
-
26305
- Include: cards moved recently, current in-progress items, blocked or high-priority items, and upcoming due dates.`
26306
- }
26307
- }
26308
- ]
26309
- };
26310
- } catch (error2) {
26311
- return {
26312
- messages: [
26313
- {
26314
- role: "user",
26315
- content: { type: "text", text: `Error: ${error2 instanceof Error ? error2.message : String(error2)}` }
26316
- }
26317
- ]
26318
- };
26319
- }
26320
- }
26321
- throw new Error(`Unknown prompt: ${name}`);
26322
- });
26323
26499
  }
26324
26500
  async handleToolCall(name, args) {
26325
26501
  if (!isConfigured()) {
@@ -26651,8 +26827,1353 @@ Include: cards moved recently, current in-progress items, blocked or high-priori
26651
26827
  }
26652
26828
  }
26653
26829
 
26830
+ // ../../node_modules/@clack/core/dist/index.mjs
26831
+ var import_sisteransi = __toESM(require_src(), 1);
26832
+ var import_picocolors = __toESM(require_picocolors(), 1);
26833
+ import { stdin as $, stdout as j } from "node:process";
26834
+ import * as f from "node:readline";
26835
+ import M from "node:readline";
26836
+ import { WriteStream as U } from "node:tty";
26837
+ function J({ onlyFirst: t = false } = {}) {
26838
+ const F = ["[\\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("|");
26839
+ return new RegExp(F, t ? undefined : "g");
26840
+ }
26841
+ var Q = J();
26842
+ function T(t) {
26843
+ if (typeof t != "string")
26844
+ throw new TypeError(`Expected a \`string\`, got \`${typeof t}\``);
26845
+ return t.replace(Q, "");
26846
+ }
26847
+ function O(t) {
26848
+ return t && t.__esModule && Object.prototype.hasOwnProperty.call(t, "default") ? t.default : t;
26849
+ }
26850
+ var P = { exports: {} };
26851
+ (function(t) {
26852
+ var u = {};
26853
+ t.exports = u, u.eastAsianWidth = function(e) {
26854
+ var s = e.charCodeAt(0), i = e.length == 2 ? e.charCodeAt(1) : 0, D = s;
26855
+ 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";
26856
+ }, u.characterLength = function(e) {
26857
+ var s = this.eastAsianWidth(e);
26858
+ return s == "F" || s == "W" || s == "A" ? 2 : 1;
26859
+ };
26860
+ function F(e) {
26861
+ return e.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF]/g) || [];
26862
+ }
26863
+ u.length = function(e) {
26864
+ for (var s = F(e), i = 0, D = 0;D < s.length; D++)
26865
+ i = i + this.characterLength(s[D]);
26866
+ return i;
26867
+ }, u.slice = function(e, s, i) {
26868
+ textLen = u.length(e), s = s || 0, i = i || 1, s < 0 && (s = textLen + s), i < 0 && (i = textLen + i);
26869
+ for (var D = "", C = 0, o = F(e), E = 0;E < o.length; E++) {
26870
+ var a = o[E], n = u.length(a);
26871
+ if (C >= s - (n == 2 ? 1 : 0))
26872
+ if (C + n <= i)
26873
+ D += a;
26874
+ else
26875
+ break;
26876
+ C += n;
26877
+ }
26878
+ return D;
26879
+ };
26880
+ })(P);
26881
+ var X = P.exports;
26882
+ var DD = O(X);
26883
+ var uD = function() {
26884
+ 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;
26885
+ };
26886
+ var FD = O(uD);
26887
+ function A(t, u = {}) {
26888
+ if (typeof t != "string" || t.length === 0 || (u = { ambiguousIsNarrow: true, ...u }, t = T(t), t.length === 0))
26889
+ return 0;
26890
+ t = t.replace(FD(), " ");
26891
+ const F = u.ambiguousIsNarrow ? 1 : 2;
26892
+ let e = 0;
26893
+ for (const s of t) {
26894
+ const i = s.codePointAt(0);
26895
+ if (i <= 31 || i >= 127 && i <= 159 || i >= 768 && i <= 879)
26896
+ continue;
26897
+ switch (DD.eastAsianWidth(s)) {
26898
+ case "F":
26899
+ case "W":
26900
+ e += 2;
26901
+ break;
26902
+ case "A":
26903
+ e += F;
26904
+ break;
26905
+ default:
26906
+ e += 1;
26907
+ }
26908
+ }
26909
+ return e;
26910
+ }
26911
+ var m = 10;
26912
+ var L = (t = 0) => (u) => `\x1B[${u + t}m`;
26913
+ var N = (t = 0) => (u) => `\x1B[${38 + t};5;${u}m`;
26914
+ var I = (t = 0) => (u, F, e) => `\x1B[${38 + t};2;${u};${F};${e}m`;
26915
+ 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] } };
26916
+ Object.keys(r.modifier);
26917
+ var tD = Object.keys(r.color);
26918
+ var eD = Object.keys(r.bgColor);
26919
+ [...tD, ...eD];
26920
+ function sD() {
26921
+ const t = new Map;
26922
+ for (const [u, F] of Object.entries(r)) {
26923
+ for (const [e, s] of Object.entries(F))
26924
+ r[e] = { open: `\x1B[${s[0]}m`, close: `\x1B[${s[1]}m` }, F[e] = r[e], t.set(s[0], s[1]);
26925
+ Object.defineProperty(r, u, { value: F, enumerable: false });
26926
+ }
26927
+ return Object.defineProperty(r, "codes", { value: t, enumerable: false }), r.color.close = "\x1B[39m", r.bgColor.close = "\x1B[49m", r.color.ansi = L(), r.color.ansi256 = N(), r.color.ansi16m = I(), r.bgColor.ansi = L(m), r.bgColor.ansi256 = N(m), r.bgColor.ansi16m = I(m), Object.defineProperties(r, { rgbToAnsi256: { value: (u, F, e) => u === F && F === e ? u < 8 ? 16 : u > 248 ? 231 : Math.round((u - 8) / 247 * 24) + 232 : 16 + 36 * Math.round(u / 255 * 5) + 6 * Math.round(F / 255 * 5) + Math.round(e / 255 * 5), enumerable: false }, hexToRgb: { value: (u) => {
26928
+ const F = /[a-f\d]{6}|[a-f\d]{3}/i.exec(u.toString(16));
26929
+ if (!F)
26930
+ return [0, 0, 0];
26931
+ let [e] = F;
26932
+ e.length === 3 && (e = [...e].map((i) => i + i).join(""));
26933
+ const s = Number.parseInt(e, 16);
26934
+ return [s >> 16 & 255, s >> 8 & 255, s & 255];
26935
+ }, enumerable: false }, hexToAnsi256: { value: (u) => r.rgbToAnsi256(...r.hexToRgb(u)), enumerable: false }, ansi256ToAnsi: { value: (u) => {
26936
+ if (u < 8)
26937
+ return 30 + u;
26938
+ if (u < 16)
26939
+ return 90 + (u - 8);
26940
+ let F, e, s;
26941
+ if (u >= 232)
26942
+ F = ((u - 232) * 10 + 8) / 255, e = F, s = F;
26943
+ else {
26944
+ u -= 16;
26945
+ const C = u % 36;
26946
+ F = Math.floor(u / 36) / 5, e = Math.floor(C / 6) / 5, s = C % 6 / 5;
26947
+ }
26948
+ const i = Math.max(F, e, s) * 2;
26949
+ if (i === 0)
26950
+ return 30;
26951
+ let D = 30 + (Math.round(s) << 2 | Math.round(e) << 1 | Math.round(F));
26952
+ return i === 2 && (D += 60), D;
26953
+ }, enumerable: false }, rgbToAnsi: { value: (u, F, e) => r.ansi256ToAnsi(r.rgbToAnsi256(u, F, e)), enumerable: false }, hexToAnsi: { value: (u) => r.ansi256ToAnsi(r.hexToAnsi256(u)), enumerable: false } }), r;
26954
+ }
26955
+ var iD = sD();
26956
+ var v = new Set(["\x1B", "›"]);
26957
+ var CD = 39;
26958
+ var w = "\x07";
26959
+ var W = "[";
26960
+ var rD = "]";
26961
+ var R = "m";
26962
+ var y = `${rD}8;;`;
26963
+ var V = (t) => `${v.values().next().value}${W}${t}${R}`;
26964
+ var z = (t) => `${v.values().next().value}${y}${t}${w}`;
26965
+ var ED = (t) => t.split(" ").map((u) => A(u));
26966
+ var _ = (t, u, F) => {
26967
+ const e = [...u];
26968
+ let s = false, i = false, D = A(T(t[t.length - 1]));
26969
+ for (const [C, o] of e.entries()) {
26970
+ const E = A(o);
26971
+ if (D + E <= F ? t[t.length - 1] += o : (t.push(o), D = 0), v.has(o) && (s = true, i = e.slice(C + 1).join("").startsWith(y)), s) {
26972
+ i ? o === w && (s = false, i = false) : o === R && (s = false);
26973
+ continue;
26974
+ }
26975
+ D += E, D === F && C < e.length - 1 && (t.push(""), D = 0);
26976
+ }
26977
+ !D && t[t.length - 1].length > 0 && t.length > 1 && (t[t.length - 2] += t.pop());
26978
+ };
26979
+ var nD = (t) => {
26980
+ const u = t.split(" ");
26981
+ let F = u.length;
26982
+ for (;F > 0 && !(A(u[F - 1]) > 0); )
26983
+ F--;
26984
+ return F === u.length ? t : u.slice(0, F).join(" ") + u.slice(F).join("");
26985
+ };
26986
+ var oD = (t, u, F = {}) => {
26987
+ if (F.trim !== false && t.trim() === "")
26988
+ return "";
26989
+ let e = "", s, i;
26990
+ const D = ED(t);
26991
+ let C = [""];
26992
+ for (const [E, a] of t.split(" ").entries()) {
26993
+ F.trim !== false && (C[C.length - 1] = C[C.length - 1].trimStart());
26994
+ let n = A(C[C.length - 1]);
26995
+ if (E !== 0 && (n >= u && (F.wordWrap === false || F.trim === false) && (C.push(""), n = 0), (n > 0 || F.trim === false) && (C[C.length - 1] += " ", n++)), F.hard && D[E] > u) {
26996
+ const B = u - n, p = 1 + Math.floor((D[E] - B - 1) / u);
26997
+ Math.floor((D[E] - 1) / u) < p && C.push(""), _(C, a, u);
26998
+ continue;
26999
+ }
27000
+ if (n + D[E] > u && n > 0 && D[E] > 0) {
27001
+ if (F.wordWrap === false && n < u) {
27002
+ _(C, a, u);
27003
+ continue;
27004
+ }
27005
+ C.push("");
27006
+ }
27007
+ if (n + D[E] > u && F.wordWrap === false) {
27008
+ _(C, a, u);
27009
+ continue;
27010
+ }
27011
+ C[C.length - 1] += a;
27012
+ }
27013
+ F.trim !== false && (C = C.map((E) => nD(E)));
27014
+ const o = [...C.join(`
27015
+ `)];
27016
+ for (const [E, a] of o.entries()) {
27017
+ if (e += a, v.has(a)) {
27018
+ const { groups: B } = new RegExp(`(?:\\${W}(?<code>\\d+)m|\\${y}(?<uri>.*)${w})`).exec(o.slice(E).join("")) || { groups: {} };
27019
+ if (B.code !== undefined) {
27020
+ const p = Number.parseFloat(B.code);
27021
+ s = p === CD ? undefined : p;
27022
+ } else
27023
+ B.uri !== undefined && (i = B.uri.length === 0 ? undefined : B.uri);
27024
+ }
27025
+ const n = iD.codes.get(Number(s));
27026
+ o[E + 1] === `
27027
+ ` ? (i && (e += z("")), s && n && (e += V(n))) : a === `
27028
+ ` && (s && n && (e += V(s)), i && (e += z(i)));
27029
+ }
27030
+ return e;
27031
+ };
27032
+ function G(t, u, F) {
27033
+ return String(t).normalize().replace(/\r\n/g, `
27034
+ `).split(`
27035
+ `).map((e) => oD(e, u, F)).join(`
27036
+ `);
27037
+ }
27038
+ var aD = ["up", "down", "left", "right", "space", "enter", "cancel"];
27039
+ var c = { actions: new Set(aD), aliases: new Map([["k", "up"], ["j", "down"], ["h", "left"], ["l", "right"], ["\x03", "cancel"], ["escape", "cancel"]]) };
27040
+ function k(t, u) {
27041
+ if (typeof t == "string")
27042
+ return c.aliases.get(t) === u;
27043
+ for (const F of t)
27044
+ if (F !== undefined && k(F, u))
27045
+ return true;
27046
+ return false;
27047
+ }
27048
+ function lD(t, u) {
27049
+ if (t === u)
27050
+ return;
27051
+ const F = t.split(`
27052
+ `), e = u.split(`
27053
+ `), s = [];
27054
+ for (let i = 0;i < Math.max(F.length, e.length); i++)
27055
+ F[i] !== e[i] && s.push(i);
27056
+ return s;
27057
+ }
27058
+ var xD = globalThis.process.platform.startsWith("win");
27059
+ var S = Symbol("clack:cancel");
27060
+ function BD(t) {
27061
+ return t === S;
27062
+ }
27063
+ function d(t, u) {
27064
+ const F = t;
27065
+ F.isTTY && F.setRawMode(u);
27066
+ }
27067
+ function cD({ input: t = $, output: u = j, overwrite: F = true, hideCursor: e = true } = {}) {
27068
+ const s = f.createInterface({ input: t, output: u, prompt: "", tabSize: 1 });
27069
+ f.emitKeypressEvents(t, s), t.isTTY && t.setRawMode(true);
27070
+ const i = (D, { name: C, sequence: o }) => {
27071
+ const E = String(D);
27072
+ if (k([E, C, o], "cancel")) {
27073
+ e && u.write(import_sisteransi.cursor.show), process.exit(0);
27074
+ return;
27075
+ }
27076
+ if (!F)
27077
+ return;
27078
+ const a = C === "return" ? 0 : -1, n = C === "return" ? -1 : 0;
27079
+ f.moveCursor(u, a, n, () => {
27080
+ f.clearLine(u, 1, () => {
27081
+ t.once("keypress", i);
27082
+ });
27083
+ });
27084
+ };
27085
+ return e && u.write(import_sisteransi.cursor.hide), t.once("keypress", i), () => {
27086
+ t.off("keypress", i), e && u.write(import_sisteransi.cursor.show), t.isTTY && !xD && t.setRawMode(false), s.terminal = false, s.close();
27087
+ };
27088
+ }
27089
+ var AD = Object.defineProperty;
27090
+ var pD = (t, u, F) => (u in t) ? AD(t, u, { enumerable: true, configurable: true, writable: true, value: F }) : t[u] = F;
27091
+ var h = (t, u, F) => (pD(t, typeof u != "symbol" ? u + "" : u, F), F);
27092
+
27093
+ class x {
27094
+ constructor(u, F = true) {
27095
+ 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");
27096
+ const { input: e = $, output: s = j, render: i, signal: D, ...C } = u;
27097
+ 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 = F, this._abortSignal = D, this.input = e, this.output = s;
27098
+ }
27099
+ unsubscribe() {
27100
+ this._subscribers.clear();
27101
+ }
27102
+ setSubscriber(u, F) {
27103
+ const e = this._subscribers.get(u) ?? [];
27104
+ e.push(F), this._subscribers.set(u, e);
27105
+ }
27106
+ on(u, F) {
27107
+ this.setSubscriber(u, { cb: F });
27108
+ }
27109
+ once(u, F) {
27110
+ this.setSubscriber(u, { cb: F, once: true });
27111
+ }
27112
+ emit(u, ...F) {
27113
+ const e = this._subscribers.get(u) ?? [], s = [];
27114
+ for (const i of e)
27115
+ i.cb(...F), i.once && s.push(() => e.splice(e.indexOf(i), 1));
27116
+ for (const i of s)
27117
+ i();
27118
+ }
27119
+ prompt() {
27120
+ return new Promise((u, F) => {
27121
+ if (this._abortSignal) {
27122
+ if (this._abortSignal.aborted)
27123
+ return this.state = "cancel", this.close(), u(S);
27124
+ this._abortSignal.addEventListener("abort", () => {
27125
+ this.state = "cancel", this.close();
27126
+ }, { once: true });
27127
+ }
27128
+ const e = new U(0);
27129
+ e._write = (s, i, D) => {
27130
+ this._track && (this.value = this.rl?.line.replace(/\t/g, ""), this._cursor = this.rl?.cursor ?? 0, this.emit("value", this.value)), D();
27131
+ }, this.input.pipe(e), this.rl = M.createInterface({ input: this.input, output: e, tabSize: 2, prompt: "", escapeCodeTimeout: 50 }), M.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), d(this.input, true), this.output.on("resize", this.render), this.render(), this.once("submit", () => {
27132
+ this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), d(this.input, false), u(this.value);
27133
+ }), this.once("cancel", () => {
27134
+ this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), d(this.input, false), u(S);
27135
+ });
27136
+ });
27137
+ }
27138
+ onKeypress(u, F) {
27139
+ if (this.state === "error" && (this.state = "active"), F?.name && (!this._track && c.aliases.has(F.name) && this.emit("cursor", c.aliases.get(F.name)), c.actions.has(F.name) && this.emit("cursor", F.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()), F?.name === "return") {
27140
+ if (this.opts.validate) {
27141
+ const e = this.opts.validate(this.value);
27142
+ e && (this.error = e instanceof Error ? e.message : e, this.state = "error", this.rl?.write(this.value));
27143
+ }
27144
+ this.state !== "error" && (this.state = "submit");
27145
+ }
27146
+ k([u, F?.name, F?.sequence], "cancel") && (this.state = "cancel"), (this.state === "submit" || this.state === "cancel") && this.emit("finalize"), this.render(), (this.state === "submit" || this.state === "cancel") && this.close();
27147
+ }
27148
+ close() {
27149
+ this.input.unpipe(), this.input.removeListener("keypress", this.onKeypress), this.output.write(`
27150
+ `), d(this.input, false), this.rl?.close(), this.rl = undefined, this.emit(`${this.state}`, this.value), this.unsubscribe();
27151
+ }
27152
+ restoreCursor() {
27153
+ const u = G(this._prevFrame, process.stdout.columns, { hard: true }).split(`
27154
+ `).length - 1;
27155
+ this.output.write(import_sisteransi.cursor.move(-999, u * -1));
27156
+ }
27157
+ render() {
27158
+ const u = G(this._render(this) ?? "", process.stdout.columns, { hard: true });
27159
+ if (u !== this._prevFrame) {
27160
+ if (this.state === "initial")
27161
+ this.output.write(import_sisteransi.cursor.hide);
27162
+ else {
27163
+ const F = lD(this._prevFrame, u);
27164
+ if (this.restoreCursor(), F && F?.length === 1) {
27165
+ const e = F[0];
27166
+ this.output.write(import_sisteransi.cursor.move(0, e)), this.output.write(import_sisteransi.erase.lines(1));
27167
+ const s = u.split(`
27168
+ `);
27169
+ this.output.write(s[e]), this._prevFrame = u, this.output.write(import_sisteransi.cursor.move(0, s.length - e - 1));
27170
+ return;
27171
+ }
27172
+ if (F && F?.length > 1) {
27173
+ const e = F[0];
27174
+ this.output.write(import_sisteransi.cursor.move(0, e)), this.output.write(import_sisteransi.erase.down());
27175
+ const s = u.split(`
27176
+ `).slice(e);
27177
+ this.output.write(s.join(`
27178
+ `)), this._prevFrame = u;
27179
+ return;
27180
+ }
27181
+ this.output.write(import_sisteransi.erase.down());
27182
+ }
27183
+ this.output.write(u), this.state === "initial" && (this.state = "active"), this._prevFrame = u;
27184
+ }
27185
+ }
27186
+ }
27187
+
27188
+ class fD extends x {
27189
+ get cursor() {
27190
+ return this.value ? 0 : 1;
27191
+ }
27192
+ get _value() {
27193
+ return this.cursor === 0;
27194
+ }
27195
+ constructor(u) {
27196
+ super(u, false), this.value = !!u.initialValue, this.on("value", () => {
27197
+ this.value = this._value;
27198
+ }), this.on("confirm", (F) => {
27199
+ this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = F, this.state = "submit", this.close();
27200
+ }), this.on("cursor", () => {
27201
+ this.value = !this.value;
27202
+ });
27203
+ }
27204
+ }
27205
+ var bD = Object.defineProperty;
27206
+ var mD = (t, u, F) => (u in t) ? bD(t, u, { enumerable: true, configurable: true, writable: true, value: F }) : t[u] = F;
27207
+ var Y = (t, u, F) => (mD(t, typeof u != "symbol" ? u + "" : u, F), F);
27208
+ var wD = class extends x {
27209
+ constructor(u) {
27210
+ super(u, false), Y(this, "options"), Y(this, "cursor", 0), this.options = u.options, this.value = [...u.initialValues ?? []], this.cursor = Math.max(this.options.findIndex(({ value: F }) => F === u.cursorAt), 0), this.on("key", (F) => {
27211
+ F === "a" && this.toggleAll();
27212
+ }), this.on("cursor", (F) => {
27213
+ switch (F) {
27214
+ case "left":
27215
+ case "up":
27216
+ this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
27217
+ break;
27218
+ case "down":
27219
+ case "right":
27220
+ this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
27221
+ break;
27222
+ case "space":
27223
+ this.toggleValue();
27224
+ break;
27225
+ }
27226
+ });
27227
+ }
27228
+ get _value() {
27229
+ return this.options[this.cursor].value;
27230
+ }
27231
+ toggleAll() {
27232
+ const u = this.value.length === this.options.length;
27233
+ this.value = u ? [] : this.options.map((F) => F.value);
27234
+ }
27235
+ toggleValue() {
27236
+ const u = this.value.includes(this._value);
27237
+ this.value = u ? this.value.filter((F) => F !== this._value) : [...this.value, this._value];
27238
+ }
27239
+ };
27240
+ class PD extends x {
27241
+ get valueWithCursor() {
27242
+ if (this.state === "submit")
27243
+ return this.value;
27244
+ if (this.cursor >= this.value.length)
27245
+ return `${this.value}█`;
27246
+ const u = this.value.slice(0, this.cursor), [F, ...e] = this.value.slice(this.cursor);
27247
+ return `${u}${import_picocolors.default.inverse(F)}${e.join("")}`;
27248
+ }
27249
+ get cursor() {
27250
+ return this._cursor;
27251
+ }
27252
+ constructor(u) {
27253
+ super(u), this.on("finalize", () => {
27254
+ this.value || (this.value = u.defaultValue);
27255
+ });
27256
+ }
27257
+ }
27258
+
27259
+ // ../../node_modules/@clack/prompts/dist/index.mjs
27260
+ var import_picocolors2 = __toESM(require_picocolors(), 1);
27261
+ var import_sisteransi2 = __toESM(require_src(), 1);
27262
+ import p from "node:process";
27263
+ function X2() {
27264
+ return p.platform !== "win32" ? p.env.TERM !== "linux" : !!p.env.CI || !!p.env.WT_SESSION || !!p.env.TERMINUS_SUBLIME || p.env.ConEmuTask === "{cmd::Cmder}" || p.env.TERM_PROGRAM === "Terminus-Sublime" || p.env.TERM_PROGRAM === "vscode" || p.env.TERM === "xterm-256color" || p.env.TERM === "alacritty" || p.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
27265
+ }
27266
+ var E = X2();
27267
+ var u = (s, n) => E ? s : n;
27268
+ var ee = u("◆", "*");
27269
+ var A2 = u("■", "x");
27270
+ var B = u("▲", "x");
27271
+ var S2 = u("◇", "o");
27272
+ var te = u("┌", "T");
27273
+ var a = u("│", "|");
27274
+ var m2 = u("└", "—");
27275
+ var j2 = u("●", ">");
27276
+ var R2 = u("○", " ");
27277
+ var V2 = u("◻", "[•]");
27278
+ var M2 = u("◼", "[+]");
27279
+ var G2 = u("◻", "[ ]");
27280
+ var se = u("▪", "•");
27281
+ var N2 = u("─", "-");
27282
+ var re = u("╮", "+");
27283
+ var ie = u("├", "+");
27284
+ var ne = u("╯", "+");
27285
+ var ae = u("●", "•");
27286
+ var oe = u("◆", "*");
27287
+ var ce = u("▲", "!");
27288
+ var le = u("■", "x");
27289
+ var y2 = (s) => {
27290
+ switch (s) {
27291
+ case "initial":
27292
+ case "active":
27293
+ return import_picocolors2.default.cyan(ee);
27294
+ case "cancel":
27295
+ return import_picocolors2.default.red(A2);
27296
+ case "error":
27297
+ return import_picocolors2.default.yellow(B);
27298
+ case "submit":
27299
+ return import_picocolors2.default.green(S2);
27300
+ }
27301
+ };
27302
+ var k2 = (s) => {
27303
+ const { cursor: n, options: t, style: i } = s, r2 = s.maxItems ?? Number.POSITIVE_INFINITY, c2 = Math.max(process.stdout.rows - 4, 0), o = Math.min(c2, Math.max(r2, 5));
27304
+ let l2 = 0;
27305
+ n >= l2 + o - 3 ? l2 = Math.max(Math.min(n - o + 3, t.length - o), 0) : n < l2 + 2 && (l2 = Math.max(n - 2, 0));
27306
+ const $2 = o < t.length && l2 > 0, d2 = o < t.length && l2 + o < t.length;
27307
+ return t.slice(l2, l2 + o).map((w2, b2, C) => {
27308
+ const I2 = b2 === 0 && $2, x2 = b2 === C.length - 1 && d2;
27309
+ return I2 || x2 ? import_picocolors2.default.dim("...") : i(w2, b2 + l2 === n);
27310
+ });
27311
+ };
27312
+ var ue = (s) => new PD({ validate: s.validate, placeholder: s.placeholder, defaultValue: s.defaultValue, initialValue: s.initialValue, render() {
27313
+ const n = `${import_picocolors2.default.gray(a)}
27314
+ ${y2(this.state)} ${s.message}
27315
+ `, t = s.placeholder ? import_picocolors2.default.inverse(s.placeholder[0]) + import_picocolors2.default.dim(s.placeholder.slice(1)) : import_picocolors2.default.inverse(import_picocolors2.default.hidden("_")), i = this.value ? this.valueWithCursor : t;
27316
+ switch (this.state) {
27317
+ case "error":
27318
+ return `${n.trim()}
27319
+ ${import_picocolors2.default.yellow(a)} ${i}
27320
+ ${import_picocolors2.default.yellow(m2)} ${import_picocolors2.default.yellow(this.error)}
27321
+ `;
27322
+ case "submit":
27323
+ return `${n}${import_picocolors2.default.gray(a)} ${import_picocolors2.default.dim(this.value || s.placeholder)}`;
27324
+ case "cancel":
27325
+ return `${n}${import_picocolors2.default.gray(a)} ${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(this.value ?? ""))}${this.value?.trim() ? `
27326
+ ${import_picocolors2.default.gray(a)}` : ""}`;
27327
+ default:
27328
+ return `${n}${import_picocolors2.default.cyan(a)} ${i}
27329
+ ${import_picocolors2.default.cyan(m2)}
27330
+ `;
27331
+ }
27332
+ } }).prompt();
27333
+ var me = (s) => {
27334
+ const n = s.active ?? "Yes", t = s.inactive ?? "No";
27335
+ return new fD({ active: n, inactive: t, initialValue: s.initialValue ?? true, render() {
27336
+ const i = `${import_picocolors2.default.gray(a)}
27337
+ ${y2(this.state)} ${s.message}
27338
+ `, r2 = this.value ? n : t;
27339
+ switch (this.state) {
27340
+ case "submit":
27341
+ return `${i}${import_picocolors2.default.gray(a)} ${import_picocolors2.default.dim(r2)}`;
27342
+ case "cancel":
27343
+ return `${i}${import_picocolors2.default.gray(a)} ${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(r2))}
27344
+ ${import_picocolors2.default.gray(a)}`;
27345
+ default:
27346
+ return `${i}${import_picocolors2.default.cyan(a)} ${this.value ? `${import_picocolors2.default.green(j2)} ${n}` : `${import_picocolors2.default.dim(R2)} ${import_picocolors2.default.dim(n)}`} ${import_picocolors2.default.dim("/")} ${this.value ? `${import_picocolors2.default.dim(R2)} ${import_picocolors2.default.dim(t)}` : `${import_picocolors2.default.green(j2)} ${t}`}
27347
+ ${import_picocolors2.default.cyan(m2)}
27348
+ `;
27349
+ }
27350
+ } }).prompt();
27351
+ };
27352
+ var pe = (s) => {
27353
+ const n = (t, i) => {
27354
+ const r2 = t.label ?? String(t.value);
27355
+ return i === "active" ? `${import_picocolors2.default.cyan(V2)} ${r2} ${t.hint ? import_picocolors2.default.dim(`(${t.hint})`) : ""}` : i === "selected" ? `${import_picocolors2.default.green(M2)} ${import_picocolors2.default.dim(r2)}` : i === "cancelled" ? `${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(r2))}` : i === "active-selected" ? `${import_picocolors2.default.green(M2)} ${r2} ${t.hint ? import_picocolors2.default.dim(`(${t.hint})`) : ""}` : i === "submitted" ? `${import_picocolors2.default.dim(r2)}` : `${import_picocolors2.default.dim(G2)} ${import_picocolors2.default.dim(r2)}`;
27356
+ };
27357
+ return new wD({ options: s.options, initialValues: s.initialValues, required: s.required ?? true, cursorAt: s.cursorAt, validate(t) {
27358
+ if (this.required && t.length === 0)
27359
+ return `Please select at least one option.
27360
+ ${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`))}`;
27361
+ }, render() {
27362
+ const t = `${import_picocolors2.default.gray(a)}
27363
+ ${y2(this.state)} ${s.message}
27364
+ `, i = (r2, c2) => {
27365
+ const o = this.value.includes(r2.value);
27366
+ return c2 && o ? n(r2, "active-selected") : o ? n(r2, "selected") : n(r2, c2 ? "active" : "inactive");
27367
+ };
27368
+ switch (this.state) {
27369
+ case "submit":
27370
+ return `${t}${import_picocolors2.default.gray(a)} ${this.options.filter(({ value: r2 }) => this.value.includes(r2)).map((r2) => n(r2, "submitted")).join(import_picocolors2.default.dim(", ")) || import_picocolors2.default.dim("none")}`;
27371
+ case "cancel": {
27372
+ const r2 = this.options.filter(({ value: c2 }) => this.value.includes(c2)).map((c2) => n(c2, "cancelled")).join(import_picocolors2.default.dim(", "));
27373
+ return `${t}${import_picocolors2.default.gray(a)} ${r2.trim() ? `${r2}
27374
+ ${import_picocolors2.default.gray(a)}` : ""}`;
27375
+ }
27376
+ case "error": {
27377
+ const r2 = this.error.split(`
27378
+ `).map((c2, o) => o === 0 ? `${import_picocolors2.default.yellow(m2)} ${import_picocolors2.default.yellow(c2)}` : ` ${c2}`).join(`
27379
+ `);
27380
+ return `${t + import_picocolors2.default.yellow(a)} ${k2({ options: this.options, cursor: this.cursor, maxItems: s.maxItems, style: i }).join(`
27381
+ ${import_picocolors2.default.yellow(a)} `)}
27382
+ ${r2}
27383
+ `;
27384
+ }
27385
+ default:
27386
+ return `${t}${import_picocolors2.default.cyan(a)} ${k2({ options: this.options, cursor: this.cursor, maxItems: s.maxItems, style: i }).join(`
27387
+ ${import_picocolors2.default.cyan(a)} `)}
27388
+ ${import_picocolors2.default.cyan(m2)}
27389
+ `;
27390
+ }
27391
+ } }).prompt();
27392
+ };
27393
+ var ve = (s = "") => {
27394
+ process.stdout.write(`${import_picocolors2.default.gray(m2)} ${import_picocolors2.default.red(s)}
27395
+
27396
+ `);
27397
+ };
27398
+ var fe = (s = "") => {
27399
+ process.stdout.write(`${import_picocolors2.default.gray(a)}
27400
+ ${import_picocolors2.default.gray(m2)} ${s}
27401
+
27402
+ `);
27403
+ };
27404
+ var v2 = { message: (s = "", { symbol: n = import_picocolors2.default.gray(a) } = {}) => {
27405
+ const t = [`${import_picocolors2.default.gray(a)}`];
27406
+ if (s) {
27407
+ const [i, ...r2] = s.split(`
27408
+ `);
27409
+ t.push(`${n} ${i}`, ...r2.map((c2) => `${import_picocolors2.default.gray(a)} ${c2}`));
27410
+ }
27411
+ process.stdout.write(`${t.join(`
27412
+ `)}
27413
+ `);
27414
+ }, info: (s) => {
27415
+ v2.message(s, { symbol: import_picocolors2.default.blue(ae) });
27416
+ }, success: (s) => {
27417
+ v2.message(s, { symbol: import_picocolors2.default.green(oe) });
27418
+ }, step: (s) => {
27419
+ v2.message(s, { symbol: import_picocolors2.default.green(S2) });
27420
+ }, warn: (s) => {
27421
+ v2.message(s, { symbol: import_picocolors2.default.yellow(ce) });
27422
+ }, warning: (s) => {
27423
+ v2.warn(s);
27424
+ }, error: (s) => {
27425
+ v2.message(s, { symbol: import_picocolors2.default.red(le) });
27426
+ } };
27427
+ var L2 = () => {
27428
+ const s = E ? ["◒", "◐", "◓", "◑"] : ["•", "o", "O", "0"], n = E ? 80 : 120, t = process.env.CI === "true";
27429
+ let i, r2, c2 = false, o = "", l2;
27430
+ const $2 = (h2) => {
27431
+ const g2 = h2 > 1 ? "Something went wrong" : "Canceled";
27432
+ c2 && P2(g2, h2);
27433
+ }, d2 = () => $2(2), w2 = () => $2(1), b2 = () => {
27434
+ process.on("uncaughtExceptionMonitor", d2), process.on("unhandledRejection", d2), process.on("SIGINT", w2), process.on("SIGTERM", w2), process.on("exit", $2);
27435
+ }, C = () => {
27436
+ process.removeListener("uncaughtExceptionMonitor", d2), process.removeListener("unhandledRejection", d2), process.removeListener("SIGINT", w2), process.removeListener("SIGTERM", w2), process.removeListener("exit", $2);
27437
+ }, I2 = () => {
27438
+ if (l2 === undefined)
27439
+ return;
27440
+ t && process.stdout.write(`
27441
+ `);
27442
+ const h2 = l2.split(`
27443
+ `);
27444
+ process.stdout.write(import_sisteransi2.cursor.move(-999, h2.length - 1)), process.stdout.write(import_sisteransi2.erase.down(h2.length));
27445
+ }, x2 = (h2) => h2.replace(/\.+$/, ""), O2 = (h2 = "") => {
27446
+ c2 = true, i = cD(), o = x2(h2), process.stdout.write(`${import_picocolors2.default.gray(a)}
27447
+ `);
27448
+ let g2 = 0, f2 = 0;
27449
+ b2(), r2 = setInterval(() => {
27450
+ if (t && o === l2)
27451
+ return;
27452
+ I2(), l2 = o;
27453
+ const W2 = import_picocolors2.default.magenta(s[g2]), _2 = t ? "..." : ".".repeat(Math.floor(f2)).slice(0, 3);
27454
+ process.stdout.write(`${W2} ${o}${_2}`), g2 = g2 + 1 < s.length ? g2 + 1 : 0, f2 = f2 < s.length ? f2 + 0.125 : 0;
27455
+ }, n);
27456
+ }, P2 = (h2 = "", g2 = 0) => {
27457
+ c2 = false, clearInterval(r2), I2();
27458
+ const f2 = g2 === 0 ? import_picocolors2.default.green(S2) : g2 === 1 ? import_picocolors2.default.red(A2) : import_picocolors2.default.red(B);
27459
+ o = x2(h2 ?? o), process.stdout.write(`${f2} ${o}
27460
+ `), C(), i();
27461
+ };
27462
+ return { start: O2, stop: P2, message: (h2 = "") => {
27463
+ o = x2(h2 ?? o);
27464
+ } };
27465
+ };
27466
+
27467
+ // src/tui/setup.ts
27468
+ import { homedir as homedir5 } from "node:os";
27469
+ import { join as join4 } from "node:path";
27470
+
27471
+ // src/tui/theme.ts
27472
+ var pc = __toESM(require_picocolors(), 1);
27473
+ var symbols = {
27474
+ harmony: "▲",
27475
+ check: "✓",
27476
+ cross: "✗",
27477
+ bullet: "•",
27478
+ arrow: "→",
27479
+ arrowRight: "▸",
27480
+ dot: "●",
27481
+ dotEmpty: "○",
27482
+ info: "ℹ",
27483
+ warning: "⚠",
27484
+ pointer: "❯"
27485
+ };
27486
+ var colors = {
27487
+ brand: (text) => pc.cyan(text),
27488
+ brandBold: (text) => pc.bold(pc.cyan(text)),
27489
+ success: (text) => pc.green(text),
27490
+ error: (text) => pc.red(text),
27491
+ warning: (text) => pc.yellow(text),
27492
+ info: (text) => pc.blue(text),
27493
+ dim: (text) => pc.dim(text),
27494
+ bold: (text) => pc.bold(text),
27495
+ muted: (text) => pc.gray(text),
27496
+ highlight: (text) => pc.cyan(text),
27497
+ link: (text) => pc.underline(pc.cyan(text))
27498
+ };
27499
+ var messages = {
27500
+ header: () => {
27501
+ return `
27502
+ ${colors.brandBold(" HARMONY")}
27503
+ ${colors.dim(" Project management for AI agents")}
27504
+ `;
27505
+ },
27506
+ done: (message) => {
27507
+ return `${colors.success(symbols.check)} ${message}`;
27508
+ },
27509
+ fail: (message) => {
27510
+ return `${colors.error(symbols.cross)} ${message}`;
27511
+ },
27512
+ skip: (message) => {
27513
+ return `${colors.dim("-")} ${colors.dim(message)}`;
27514
+ },
27515
+ step: (number4, total, message) => {
27516
+ return `${colors.dim(`[${number4}/${total}]`)} ${message}`;
27517
+ },
27518
+ fileCreated: (path) => {
27519
+ return ` ${colors.success(symbols.check)} ${colors.dim(path)}`;
27520
+ },
27521
+ fileSkipped: (path) => {
27522
+ return ` ${colors.dim(symbols.bullet)} ${colors.dim(path)} ${colors.dim("(exists)")}`;
27523
+ },
27524
+ fileError: (path, error2) => {
27525
+ return ` ${colors.error(symbols.cross)} ${path}: ${colors.error(error2)}`;
27526
+ }
27527
+ };
27528
+ function formatPath(path, homeDir) {
27529
+ if (path.startsWith(homeDir)) {
27530
+ return `~${path.slice(homeDir.length)}`;
27531
+ }
27532
+ return path;
27533
+ }
27534
+
27535
+ // src/tui/agents.ts
27536
+ import { existsSync as existsSync3 } from "node:fs";
27537
+ import { join as join3 } from "node:path";
27538
+ import { homedir as homedir3 } from "node:os";
27539
+ var AGENT_DEFINITIONS = [
27540
+ {
27541
+ id: "claude",
27542
+ name: "Claude Code",
27543
+ description: "Anthropic CLI agent",
27544
+ hint: "/hmy <card>",
27545
+ globalPaths: [join3(homedir3(), ".claude")],
27546
+ localPaths: [".claude"]
27547
+ },
27548
+ {
27549
+ id: "codex",
27550
+ name: "Codex",
27551
+ description: "OpenAI coding agent",
27552
+ hint: "/prompts:hmy <card>",
27553
+ globalPaths: [join3(homedir3(), ".codex")],
27554
+ localPaths: ["AGENTS.md"]
27555
+ },
27556
+ {
27557
+ id: "cursor",
27558
+ name: "Cursor",
27559
+ description: "AI-powered IDE",
27560
+ hint: "MCP tools available automatically",
27561
+ globalPaths: [],
27562
+ localPaths: [".cursor", ".cursorrules"]
27563
+ },
27564
+ {
27565
+ id: "windsurf",
27566
+ name: "Windsurf",
27567
+ description: "Codeium AI IDE",
27568
+ hint: "MCP tools available automatically",
27569
+ globalPaths: [join3(homedir3(), ".codeium", "windsurf")],
27570
+ localPaths: [".windsurf", ".windsurfrules"]
27571
+ }
27572
+ ];
27573
+ function detectAgents2(cwd = process.cwd()) {
27574
+ return AGENT_DEFINITIONS.map((def) => {
27575
+ const globalPath = def.globalPaths.find((p2) => existsSync3(p2)) || null;
27576
+ const localPath = def.localPaths.find((p2) => existsSync3(join3(cwd, p2))) || null;
27577
+ return {
27578
+ id: def.id,
27579
+ name: def.name,
27580
+ detected: !!(globalPath || localPath),
27581
+ globalPath,
27582
+ localPath: localPath ? join3(cwd, localPath) : null,
27583
+ description: def.description,
27584
+ hint: def.hint
27585
+ };
27586
+ });
27587
+ }
27588
+
27589
+ // src/tui/writer.ts
27590
+ import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "node:fs";
27591
+ import { dirname as dirname2 } from "node:path";
27592
+ import { homedir as homedir4 } from "node:os";
27593
+ function ensureDir2(dirPath) {
27594
+ if (!existsSync4(dirPath)) {
27595
+ mkdirSync3(dirPath, { recursive: true, mode: 493 });
27596
+ }
27597
+ }
27598
+ function writeFile(filePath, content, options = {}) {
27599
+ const exists = existsSync4(filePath);
27600
+ if (exists && !options.force) {
27601
+ return { path: filePath, action: "skip" };
27602
+ }
27603
+ try {
27604
+ ensureDir2(dirname2(filePath));
27605
+ const mode = filePath.includes(".harmony-mcp") ? 384 : 420;
27606
+ writeFileSync3(filePath, content, { mode });
27607
+ return { path: filePath, action: exists ? "update" : "create" };
27608
+ } catch (error2) {
27609
+ return {
27610
+ path: filePath,
27611
+ action: "skip",
27612
+ error: error2 instanceof Error ? error2.message : String(error2)
27613
+ };
27614
+ }
27615
+ }
27616
+ function mergeJsonFile2(filePath, updates, options = {}) {
27617
+ const exists = existsSync4(filePath);
27618
+ if (!exists) {
27619
+ try {
27620
+ ensureDir2(dirname2(filePath));
27621
+ writeFileSync3(filePath, JSON.stringify(updates, null, 2), { mode: 420 });
27622
+ return { path: filePath, action: "create" };
27623
+ } catch (error2) {
27624
+ return {
27625
+ path: filePath,
27626
+ action: "skip",
27627
+ error: error2 instanceof Error ? error2.message : String(error2)
27628
+ };
27629
+ }
27630
+ }
27631
+ try {
27632
+ const existing = JSON.parse(readFileSync3(filePath, "utf-8"));
27633
+ if (updates.mcpServers && existing.mcpServers) {
27634
+ const existingServers = existing.mcpServers;
27635
+ const updateServers = updates.mcpServers;
27636
+ if (existingServers.harmony && !options.force) {
27637
+ return { path: filePath, action: "skip" };
27638
+ }
27639
+ existing.mcpServers = { ...existingServers, ...updateServers };
27640
+ } else {
27641
+ Object.assign(existing, updates);
27642
+ }
27643
+ writeFileSync3(filePath, JSON.stringify(existing, null, 2), { mode: 420 });
27644
+ return { path: filePath, action: "merge" };
27645
+ } catch {
27646
+ if (options.force) {
27647
+ try {
27648
+ writeFileSync3(filePath, JSON.stringify(updates, null, 2), { mode: 420 });
27649
+ return { path: filePath, action: "update" };
27650
+ } catch (error2) {
27651
+ return {
27652
+ path: filePath,
27653
+ action: "skip",
27654
+ error: error2 instanceof Error ? error2.message : String(error2)
27655
+ };
27656
+ }
27657
+ }
27658
+ return { path: filePath, action: "skip", error: "Could not parse existing file" };
27659
+ }
27660
+ }
27661
+ function appendToToml(filePath, section, content, options = {}) {
27662
+ const exists = existsSync4(filePath);
27663
+ if (!exists) {
27664
+ try {
27665
+ ensureDir2(dirname2(filePath));
27666
+ writeFileSync3(filePath, content, { mode: 420 });
27667
+ return { path: filePath, action: "create" };
27668
+ } catch (error2) {
27669
+ return {
27670
+ path: filePath,
27671
+ action: "skip",
27672
+ error: error2 instanceof Error ? error2.message : String(error2)
27673
+ };
27674
+ }
27675
+ }
27676
+ try {
27677
+ const existing = readFileSync3(filePath, "utf-8");
27678
+ if (existing.includes(section)) {
27679
+ if (options.force) {
27680
+ const updated = existing.replace(new RegExp(`\\[${section.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\][\\s\\S]*?(?=\\[|$)`), content.trim() + `
27681
+
27682
+ `);
27683
+ writeFileSync3(filePath, updated, { mode: 420 });
27684
+ return { path: filePath, action: "update" };
27685
+ }
27686
+ return { path: filePath, action: "skip" };
27687
+ }
27688
+ writeFileSync3(filePath, existing + `
27689
+ ` + content, { mode: 420 });
27690
+ return { path: filePath, action: "merge" };
27691
+ } catch (error2) {
27692
+ return {
27693
+ path: filePath,
27694
+ action: "skip",
27695
+ error: error2 instanceof Error ? error2.message : String(error2)
27696
+ };
27697
+ }
27698
+ }
27699
+ async function writeFilesWithProgress(files, options = {}) {
27700
+ const results = [];
27701
+ const home = homedir4();
27702
+ const spinner = L2();
27703
+ spinner.start("Writing configuration files...");
27704
+ for (const file of files) {
27705
+ let result;
27706
+ if (file.type === "json") {
27707
+ const jsonContent = JSON.parse(file.content);
27708
+ result = mergeJsonFile2(file.path, jsonContent, options);
27709
+ } else if (file.type === "toml" && file.tomlSection) {
27710
+ result = appendToToml(file.path, file.tomlSection, file.content, options);
27711
+ } else {
27712
+ result = writeFile(file.path, file.content, options);
27713
+ }
27714
+ results.push(result);
27715
+ await new Promise((resolve) => setTimeout(resolve, 50));
27716
+ }
27717
+ spinner.stop("Files written");
27718
+ for (const result of results) {
27719
+ const displayPath = formatPath(result.path, home);
27720
+ if (result.error) {
27721
+ console.log(messages.fileError(displayPath, result.error));
27722
+ } else if (result.action === "skip") {
27723
+ console.log(messages.fileSkipped(displayPath));
27724
+ } else {
27725
+ const actionLabel = result.action === "merge" ? "updated" : "created";
27726
+ console.log(` ${colors.success("✓")} ${colors.dim(displayPath)} ${colors.dim(`(${actionLabel})`)}`);
27727
+ }
27728
+ }
27729
+ return results;
27730
+ }
27731
+ function getWriteSummary(files, options = {}) {
27732
+ const toCreate = [];
27733
+ const toUpdate = [];
27734
+ const toSkip = [];
27735
+ const home = homedir4();
27736
+ for (const file of files) {
27737
+ const displayPath = formatPath(file.path, home);
27738
+ const exists = existsSync4(file.path);
27739
+ if (exists && !options.force) {
27740
+ toSkip.push(displayPath);
27741
+ } else if (exists) {
27742
+ toUpdate.push(displayPath);
27743
+ } else {
27744
+ toCreate.push(displayPath);
27745
+ }
27746
+ }
27747
+ return { toCreate, toUpdate, toSkip };
27748
+ }
27749
+
27750
+ // src/tui/setup.ts
27751
+ var HARMONY_WORKFLOW_PROMPT2 = `# Harmony Card Workflow
27752
+
27753
+ Start work on a Harmony card. Card reference: $ARGUMENTS
27754
+
27755
+ ## 1. Find & Fetch Card
27756
+
27757
+ Parse the reference and fetch the card:
27758
+ - \`#42\` or \`42\` → \`harmony_get_card_by_short_id\` with \`shortId: 42\`
27759
+ - UUID → \`harmony_get_card\` with \`cardId\`
27760
+ - Name/text → \`harmony_search_cards\` with \`query\`
27761
+
27762
+ ## 2. Get Board State
27763
+
27764
+ Call \`harmony_get_board\` to get columns and labels. From the response:
27765
+ - Find the "In Progress" (or "Progress") column ID
27766
+ - Find the "agent" label ID
27767
+
27768
+ ## 3. Setup Card for Work
27769
+
27770
+ Execute these in sequence:
27771
+ 1. \`harmony_move_card\` → Move to "In Progress" column
27772
+ 2. \`harmony_add_label_to_card\` → Add "agent" label
27773
+ 3. \`harmony_start_agent_session\`:
27774
+ - \`cardId\`: Card UUID
27775
+ - \`agentIdentifier\`: Your agent identifier
27776
+ - \`agentName\`: Your agent name
27777
+ - \`currentTask\`: "Analyzing card requirements"
27778
+
27779
+ ## 4. Generate Work Prompt
27780
+
27781
+ Call \`harmony_generate_prompt\` with:
27782
+ - \`cardId\` or \`shortId\` (+ \`projectId\` if using shortId)
27783
+ - \`variant\`: Select based on task:
27784
+ - \`"execute"\` (default) → Clear tasks, bug fixes, well-defined work
27785
+ - \`"analysis"\` → Complex features, unclear requirements
27786
+ - \`"draft"\` → Medium complexity, want feedback first
27787
+
27788
+ The generated prompt provides role framing, focus areas, subtasks, linked cards, and suggested outputs.
27789
+
27790
+ ## 5. Display Card Summary
27791
+
27792
+ Show the user: Card title, short ID, role, priority, labels, due date, description, and subtasks.
27793
+
27794
+ ## 6. Implement Solution
27795
+
27796
+ Work on the card following the generated prompt's guidance. Update progress at milestones:
27797
+ - \`harmony_update_agent_progress\` with \`progressPercent\` (0-100), \`currentTask\`, \`status\`, \`blockers\`
27798
+
27799
+ **Progress checkpoints:** 20% (exploration), 50% (implementation), 80% (testing), 100% (done)
27800
+
27801
+ ## 7. Complete Work
27802
+
27803
+ When finished:
27804
+ 1. \`harmony_end_agent_session\` with \`status: "completed"\`, \`progressPercent: 100\`
27805
+ 2. \`harmony_move_card\` to "Review" column
27806
+ 3. Summarize accomplishments
27807
+
27808
+ If pausing: \`harmony_end_agent_session\` with \`status: "paused"\`
27809
+
27810
+ ## Key Tools Reference
27811
+
27812
+ **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\`
27813
+
27814
+ **Subtasks:** \`harmony_create_subtask\`, \`harmony_toggle_subtask\`, \`harmony_delete_subtask\`
27815
+
27816
+ **Labels:** \`harmony_add_label_to_card\`, \`harmony_remove_label_from_card\`, \`harmony_create_label\`
27817
+
27818
+ **Links:** \`harmony_add_link_to_card\`, \`harmony_remove_link_from_card\`, \`harmony_get_card_links\`
27819
+
27820
+ **Board:** \`harmony_get_board\`, \`harmony_list_projects\`, \`harmony_get_context\`, \`harmony_set_project_context\`
27821
+
27822
+ **Sessions:** \`harmony_start_agent_session\`, \`harmony_update_agent_progress\`, \`harmony_end_agent_session\`, \`harmony_get_agent_session\`
27823
+
27824
+ **AI:** \`harmony_generate_prompt\`, \`harmony_process_command\`
27825
+ `;
27826
+ async function validateApiKey(apiKey, apiUrl = "https://gethmy.com/api") {
27827
+ try {
27828
+ const response = await fetch(`${apiUrl}/v1/workspaces`, {
27829
+ method: "GET",
27830
+ headers: {
27831
+ "Content-Type": "application/json",
27832
+ "X-API-Key": apiKey
27833
+ }
27834
+ });
27835
+ if (!response.ok) {
27836
+ const data = await response.json().catch(() => ({}));
27837
+ return {
27838
+ valid: false,
27839
+ error: data.error || `API returned ${response.status}`
27840
+ };
27841
+ }
27842
+ const meResponse = await fetch(`${apiUrl}/v1/me`, {
27843
+ method: "GET",
27844
+ headers: {
27845
+ "Content-Type": "application/json",
27846
+ "X-API-Key": apiKey
27847
+ }
27848
+ });
27849
+ if (meResponse.ok) {
27850
+ const meData = await meResponse.json();
27851
+ return { valid: true, email: meData.user?.email };
27852
+ }
27853
+ return { valid: true };
27854
+ } catch (error2) {
27855
+ return {
27856
+ valid: false,
27857
+ error: error2 instanceof Error ? error2.message : "Connection failed"
27858
+ };
27859
+ }
27860
+ }
27861
+ function getAgentFiles(agentId, cwd) {
27862
+ const home = homedir5();
27863
+ const files = [];
27864
+ switch (agentId) {
27865
+ case "claude": {
27866
+ const commandContent = `---
27867
+ description: Start working on a Harmony card (moves to In Progress, adds agent label)
27868
+ argument-hint: <card-reference>
27869
+ ---
27870
+
27871
+ ${HARMONY_WORKFLOW_PROMPT2.replace("Your agent identifier", "claude-code").replace("Your agent name", "Claude Code")}
27872
+ `;
27873
+ files.push({
27874
+ path: join4(cwd, ".claude", "commands", "hmy.md"),
27875
+ content: commandContent,
27876
+ type: "text"
27877
+ });
27878
+ files.push({
27879
+ path: join4(home, ".claude", "settings.json"),
27880
+ content: JSON.stringify({
27881
+ mcpServers: {
27882
+ harmony: {
27883
+ command: "npx",
27884
+ args: ["-y", "harmony-mcp@latest", "serve"]
27885
+ }
27886
+ }
27887
+ }, null, 2),
27888
+ type: "json"
27889
+ });
27890
+ break;
27891
+ }
27892
+ case "codex": {
27893
+ const agentsContent = `# Harmony Integration
27894
+
27895
+ This project uses Harmony for task management. When working on tasks:
27896
+
27897
+ ## Starting Work on a Card
27898
+
27899
+ When given a card reference (e.g., #42 or a card name), follow this workflow:
27900
+
27901
+ 1. Use \`harmony_get_card_by_short_id\` or \`harmony_search_cards\` to find the card
27902
+ 2. Move the card to "In Progress" using \`harmony_move_card\`
27903
+ 3. Add the "agent" label using \`harmony_add_label_to_card\`
27904
+ 4. Start a session with \`harmony_start_agent_session\` (agentIdentifier: "codex", agentName: "OpenAI Codex")
27905
+ 5. Show the card details to the user
27906
+ 6. Use \`harmony_generate_prompt\` to get guidance, then implement the solution
27907
+ 7. Update progress periodically with \`harmony_update_agent_progress\`
27908
+ 8. When done, call \`harmony_end_agent_session\` and move to "Review"
27909
+
27910
+ ## Available Harmony Tools
27911
+
27912
+ - \`harmony_get_card\`, \`harmony_get_card_by_short_id\`, \`harmony_search_cards\` - Find cards
27913
+ - \`harmony_move_card\` - Move cards between columns
27914
+ - \`harmony_add_label_to_card\`, \`harmony_remove_label_from_card\` - Manage labels
27915
+ - \`harmony_start_agent_session\`, \`harmony_update_agent_progress\`, \`harmony_end_agent_session\` - Track work
27916
+ - \`harmony_get_board\` - Get board state
27917
+ - \`harmony_generate_prompt\` - Get role-based guidance and focus areas for the card
27918
+ `;
27919
+ files.push({
27920
+ path: join4(cwd, "AGENTS.md"),
27921
+ content: agentsContent,
27922
+ type: "text"
27923
+ });
27924
+ const promptContent = `---
27925
+ name: hmy
27926
+ description: Start working on a Harmony card
27927
+ arguments:
27928
+ - name: card
27929
+ description: Card reference (#42, UUID, or name)
27930
+ required: true
27931
+ ---
27932
+
27933
+ ${HARMONY_WORKFLOW_PROMPT2.replace("$ARGUMENTS", "{{card}}").replace("Your agent identifier", "codex").replace("Your agent name", "OpenAI Codex")}
27934
+ `;
27935
+ files.push({
27936
+ path: join4(home, ".codex", "prompts", "hmy.md"),
27937
+ content: promptContent,
27938
+ type: "text"
27939
+ });
27940
+ const tomlContent = `
27941
+ # Harmony MCP Server
27942
+ [mcp_servers.harmony]
27943
+ command = "npx"
27944
+ args = ["-y", "harmony-mcp@latest", "serve"]
27945
+ `;
27946
+ files.push({
27947
+ path: join4(home, ".codex", "config.toml"),
27948
+ content: tomlContent,
27949
+ type: "toml",
27950
+ tomlSection: "mcp_servers.harmony"
27951
+ });
27952
+ break;
27953
+ }
27954
+ case "cursor": {
27955
+ files.push({
27956
+ path: join4(cwd, ".cursor", "mcp.json"),
27957
+ content: JSON.stringify({
27958
+ mcpServers: {
27959
+ harmony: {
27960
+ command: "npx",
27961
+ args: ["-y", "harmony-mcp@latest", "serve"]
27962
+ }
27963
+ }
27964
+ }, null, 2),
27965
+ type: "json"
27966
+ });
27967
+ const ruleContent = `---
27968
+ description: Harmony card workflow rule
27969
+ globs:
27970
+ - "**/*"
27971
+ alwaysApply: false
27972
+ ---
27973
+
27974
+ # Harmony Integration
27975
+
27976
+ When the user asks you to work on a Harmony card (references like #42, card names, or UUIDs):
27977
+
27978
+ ${HARMONY_WORKFLOW_PROMPT2.replace("$ARGUMENTS", "the card reference").replace("Your agent identifier", "cursor").replace("Your agent name", "Cursor AI")}
27979
+ `;
27980
+ files.push({
27981
+ path: join4(cwd, ".cursor", "rules", "harmony.mdc"),
27982
+ content: ruleContent,
27983
+ type: "text"
27984
+ });
27985
+ break;
27986
+ }
27987
+ case "windsurf": {
27988
+ files.push({
27989
+ path: join4(home, ".codeium", "windsurf", "mcp_config.json"),
27990
+ content: JSON.stringify({
27991
+ mcpServers: {
27992
+ harmony: {
27993
+ command: "npx",
27994
+ args: ["-y", "harmony-mcp@latest", "serve"],
27995
+ disabled: false,
27996
+ alwaysAllow: []
27997
+ }
27998
+ }
27999
+ }, null, 2),
28000
+ type: "json"
28001
+ });
28002
+ const ruleContent = `---
28003
+ trigger: model_decision
28004
+ description: Activate when user asks to work on a Harmony card (references like #42, card names, or task management)
28005
+ ---
28006
+
28007
+ # Harmony Card Workflow
28008
+
28009
+ When working on a Harmony card:
28010
+
28011
+ ${HARMONY_WORKFLOW_PROMPT2.replace("$ARGUMENTS", "the card reference").replace("Your agent identifier", "windsurf").replace("Your agent name", "Windsurf AI")}
28012
+ `;
28013
+ files.push({
28014
+ path: join4(cwd, ".windsurf", "rules", "harmony.md"),
28015
+ content: ruleContent,
28016
+ type: "text"
28017
+ });
28018
+ break;
28019
+ }
28020
+ }
28021
+ return files;
28022
+ }
28023
+ async function runSetup(options = {}) {
28024
+ const cwd = process.cwd();
28025
+ const home = homedir5();
28026
+ console.clear();
28027
+ console.log(messages.header());
28028
+ const existingConfig = loadConfig();
28029
+ const alreadyConfigured = isConfigured();
28030
+ let apiKey = options.apiKey || existingConfig.apiKey;
28031
+ let userEmail;
28032
+ if (!apiKey || !apiKey.startsWith("hmy_")) {
28033
+ const keyInput = await ue({
28034
+ message: "Enter your Harmony API key",
28035
+ placeholder: "hmy_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
28036
+ validate: (value) => {
28037
+ if (!value)
28038
+ return "API key is required";
28039
+ if (!value.startsWith("hmy_"))
28040
+ return 'API key must start with "hmy_"';
28041
+ if (value.length < 20)
28042
+ return "API key is too short";
28043
+ return;
28044
+ }
28045
+ });
28046
+ if (BD(keyInput)) {
28047
+ ve("Setup cancelled");
28048
+ process.exit(0);
28049
+ }
28050
+ apiKey = keyInput;
28051
+ } else if (alreadyConfigured) {
28052
+ v2.info(`Using existing API key: ${apiKey.slice(0, 8)}...`);
28053
+ }
28054
+ const spinner = L2();
28055
+ spinner.start("Validating API key...");
28056
+ const validation = await validateApiKey(apiKey);
28057
+ if (!validation.valid) {
28058
+ spinner.stop(colors.error("API key validation failed"));
28059
+ v2.error(validation.error || "Could not connect to Harmony API");
28060
+ v2.info("Get an API key at: https://gethmy.com/settings/api-keys");
28061
+ process.exit(1);
28062
+ }
28063
+ userEmail = validation.email;
28064
+ spinner.stop(colors.success(userEmail ? `Connected as ${userEmail}` : "API key validated"));
28065
+ const detectedAgents = detectAgents2(cwd);
28066
+ const hasDetected = detectedAgents.some((a2) => a2.detected);
28067
+ let selectedAgents;
28068
+ if (options.agents && options.agents.length > 0) {
28069
+ selectedAgents = options.agents;
28070
+ } else {
28071
+ const agentOptions = detectedAgents.map((agent) => ({
28072
+ value: agent.id,
28073
+ label: agent.name,
28074
+ hint: agent.detected ? colors.success(`${agent.description} (detected)`) : colors.dim(`${agent.description}`)
28075
+ }));
28076
+ const agentSelection = await pe({
28077
+ message: "Select agents to configure",
28078
+ options: agentOptions,
28079
+ initialValues: detectedAgents.filter((a2) => a2.detected).map((a2) => a2.id),
28080
+ required: true
28081
+ });
28082
+ if (BD(agentSelection)) {
28083
+ ve("Setup cancelled");
28084
+ process.exit(0);
28085
+ }
28086
+ selectedAgents = agentSelection;
28087
+ }
28088
+ if (selectedAgents.length === 0) {
28089
+ v2.warning("No agents selected. Exiting.");
28090
+ process.exit(0);
28091
+ }
28092
+ const allFiles = [];
28093
+ allFiles.push({
28094
+ path: getConfigPath(),
28095
+ content: JSON.stringify({
28096
+ apiKey,
28097
+ apiUrl: "https://gethmy.com/api",
28098
+ userEmail: userEmail || null,
28099
+ activeWorkspaceId: null,
28100
+ activeProjectId: null
28101
+ }, null, 2),
28102
+ type: "text"
28103
+ });
28104
+ for (const agentId of selectedAgents) {
28105
+ const agentFiles = getAgentFiles(agentId, cwd);
28106
+ allFiles.push(...agentFiles);
28107
+ }
28108
+ const summary = getWriteSummary(allFiles, { force: options.force });
28109
+ console.log("");
28110
+ v2.step("Summary");
28111
+ console.log("");
28112
+ console.log(` ${colors.bold("Config:")} ${formatPath(getConfigPath(), home)}`);
28113
+ console.log(` ${colors.bold("Agents:")} ${selectedAgents.map((a2) => detectedAgents.find((d2) => d2.id === a2)?.name).join(", ")}`);
28114
+ if (summary.toCreate.length > 0) {
28115
+ console.log("");
28116
+ console.log(` ${colors.success("Files to create:")}`);
28117
+ for (const path of summary.toCreate) {
28118
+ console.log(` ${colors.dim("•")} ${path}`);
28119
+ }
28120
+ }
28121
+ if (summary.toUpdate.length > 0) {
28122
+ console.log("");
28123
+ console.log(` ${colors.info("Files to update:")}`);
28124
+ for (const path of summary.toUpdate) {
28125
+ console.log(` ${colors.dim("•")} ${path}`);
28126
+ }
28127
+ }
28128
+ if (summary.toSkip.length > 0 && !options.force) {
28129
+ console.log("");
28130
+ console.log(` ${colors.dim("Files to skip (already exist):")}`);
28131
+ for (const path of summary.toSkip) {
28132
+ console.log(` ${colors.dim("•")} ${path}`);
28133
+ }
28134
+ }
28135
+ console.log("");
28136
+ const shouldProceed = await me({
28137
+ message: "Proceed with setup?",
28138
+ initialValue: true
28139
+ });
28140
+ if (BD(shouldProceed) || !shouldProceed) {
28141
+ ve("Setup cancelled");
28142
+ process.exit(0);
28143
+ }
28144
+ console.log("");
28145
+ await writeFilesWithProgress(allFiles, { force: options.force });
28146
+ console.log("");
28147
+ fe(colors.success("Setup complete!"));
28148
+ console.log("");
28149
+ console.log(colors.bold(" Next steps:"));
28150
+ console.log("");
28151
+ if (selectedAgents.includes("claude")) {
28152
+ console.log(` ${colors.brand("Claude Code:")}`);
28153
+ console.log(` Run: ${colors.highlight("/hmy #42")} or ${colors.highlight('/hmy "Fix login bug"')}`);
28154
+ console.log("");
28155
+ }
28156
+ if (selectedAgents.includes("codex")) {
28157
+ console.log(` ${colors.brand("Codex:")}`);
28158
+ console.log(` Run: ${colors.highlight("/prompts:hmy #42")}`);
28159
+ console.log("");
28160
+ }
28161
+ if (selectedAgents.includes("cursor")) {
28162
+ console.log(` ${colors.brand("Cursor:")}`);
28163
+ console.log(` MCP tools available automatically. Mention card references to activate.`);
28164
+ console.log("");
28165
+ }
28166
+ if (selectedAgents.includes("windsurf")) {
28167
+ console.log(` ${colors.brand("Windsurf:")}`);
28168
+ console.log(` MCP tools available automatically. Mention card references to activate.`);
28169
+ console.log("");
28170
+ }
28171
+ console.log(` ${colors.dim("Need help? Visit https://gethmy.com/docs/mcp")}`);
28172
+ console.log("");
28173
+ }
28174
+
26654
28175
  // src/cli.ts
26655
- var rl = createInterface({
28176
+ var rl = createInterface2({
26656
28177
  input: process.stdin,
26657
28178
  output: process.stdout
26658
28179
  });
@@ -26808,7 +28329,15 @@ program.command("clear-user-email").description("Clear the configured user email
26808
28329
  console.log(`
26809
28330
  Auto-assignment is now disabled.`);
26810
28331
  });
26811
- program.command("init").description("Initialize Harmony MCP for AI coding agents (Claude Code, Codex, Cursor, Windsurf)").option("-a, --agent <agents...>", `Agent(s) to configure: ${SUPPORTED_AGENTS.join(", ")}`).option("--all", "Configure all supported agents").option("--detect", "Auto-detect installed agents and configure them").option("-f, --force", "Overwrite existing configuration files").option("-d, --directory <path>", "Project directory (default: current directory)").option("-w, --workspace <id>", "Set local workspace context for this project").option("-p, --project <id>", "Set local project context for this project").action(async (options) => {
28332
+ program.command("setup").description("Interactive setup wizard for Harmony MCP (recommended)").option("-f, --force", "Overwrite existing configuration files").option("-k, --api-key <key>", "API key (skips prompt)").option("-a, --agent <agents...>", "Agent(s) to configure: claude, codex, cursor, windsurf").action(async (options) => {
28333
+ rl.close();
28334
+ await runSetup({
28335
+ force: options.force,
28336
+ apiKey: options.apiKey,
28337
+ agents: options.agent
28338
+ });
28339
+ });
28340
+ program.command("init").description('Initialize Harmony MCP for AI coding agents (use "setup" for interactive wizard)').option("-a, --agent <agents...>", `Agent(s) to configure: ${SUPPORTED_AGENTS.join(", ")}`).option("--all", "Configure all supported agents").option("--detect", "Auto-detect installed agents and configure them").option("-f, --force", "Overwrite existing configuration files").option("-d, --directory <path>", "Project directory (default: current directory)").option("-w, --workspace <id>", "Set local workspace context for this project").option("-p, --project <id>", "Set local project context for this project").action(async (options) => {
26812
28341
  console.log(`Harmony MCP Initialization
26813
28342
  `);
26814
28343
  let agents = [];
@@ -26829,8 +28358,8 @@ Use --all to configure all agents, or --agent to specify specific ones.`);
26829
28358
  console.log(`Detected agents: ${agents.join(", ")}
26830
28359
  `);
26831
28360
  } else if (options.agent) {
26832
- agents = options.agent.filter((a) => SUPPORTED_AGENTS.includes(a));
26833
- const invalid = options.agent.filter((a) => !SUPPORTED_AGENTS.includes(a));
28361
+ agents = options.agent.filter((a2) => SUPPORTED_AGENTS.includes(a2));
28362
+ const invalid = options.agent.filter((a2) => !SUPPORTED_AGENTS.includes(a2));
26834
28363
  if (invalid.length > 0) {
26835
28364
  console.log(`Warning: Unknown agent(s) ignored: ${invalid.join(", ")}`);
26836
28365
  }
@@ -26896,11 +28425,11 @@ ${result.agent.toUpperCase()}:`);
26896
28425
  }
26897
28426
  if (result.filesCreated.length > 0) {
26898
28427
  console.log(" Created:");
26899
- result.filesCreated.forEach((f) => console.log(` ✓ ${f}`));
28428
+ result.filesCreated.forEach((f2) => console.log(` ✓ ${f2}`));
26900
28429
  }
26901
28430
  if (result.filesSkipped.length > 0) {
26902
28431
  console.log(" Skipped (already exists, use --force to overwrite):");
26903
- result.filesSkipped.forEach((f) => console.log(` - ${f}`));
28432
+ result.filesSkipped.forEach((f2) => console.log(` - ${f2}`));
26904
28433
  }
26905
28434
  if (result.filesCreated.length === 0 && result.filesSkipped.length === 0) {
26906
28435
  console.log(" No changes made");