@sahyll/ai 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -317,69 +317,9 @@ var require_lib = __commonJS((exports, module) => {
317
317
  which.sync = whichSync;
318
318
  });
319
319
 
320
- // node_modules/sisteransi/src/index.js
321
- var require_src = __commonJS((exports, module) => {
322
- var ESC = "\x1B";
323
- var CSI = `${ESC}[`;
324
- var beep = "\x07";
325
- var cursor = {
326
- to(x, y) {
327
- if (!y)
328
- return `${CSI}${x + 1}G`;
329
- return `${CSI}${y + 1};${x + 1}H`;
330
- },
331
- move(x, y) {
332
- let ret = "";
333
- if (x < 0)
334
- ret += `${CSI}${-x}D`;
335
- else if (x > 0)
336
- ret += `${CSI}${x}C`;
337
- if (y < 0)
338
- ret += `${CSI}${-y}A`;
339
- else if (y > 0)
340
- ret += `${CSI}${y}B`;
341
- return ret;
342
- },
343
- up: (count = 1) => `${CSI}${count}A`,
344
- down: (count = 1) => `${CSI}${count}B`,
345
- forward: (count = 1) => `${CSI}${count}C`,
346
- backward: (count = 1) => `${CSI}${count}D`,
347
- nextLine: (count = 1) => `${CSI}E`.repeat(count),
348
- prevLine: (count = 1) => `${CSI}F`.repeat(count),
349
- left: `${CSI}G`,
350
- hide: `${CSI}?25l`,
351
- show: `${CSI}?25h`,
352
- save: `${ESC}7`,
353
- restore: `${ESC}8`
354
- };
355
- var scroll = {
356
- up: (count = 1) => `${CSI}S`.repeat(count),
357
- down: (count = 1) => `${CSI}T`.repeat(count)
358
- };
359
- var erase = {
360
- screen: `${CSI}2J`,
361
- up: (count = 1) => `${CSI}1J`.repeat(count),
362
- down: (count = 1) => `${CSI}J`.repeat(count),
363
- line: `${CSI}2K`,
364
- lineEnd: `${CSI}K`,
365
- lineStart: `${CSI}1K`,
366
- lines(count) {
367
- let clear = "";
368
- for (let i = 0;i < count; i++)
369
- clear += this.line + (i < count - 1 ? cursor.up() : "");
370
- if (count)
371
- clear += cursor.left;
372
- return clear;
373
- }
374
- };
375
- module.exports = { cursor, scroll, erase, beep };
376
- });
377
-
378
320
  // src/index.ts
379
- var import_picocolors5 = __toESM(require_picocolors(), 1);
380
- import { spawn as spawn5 } from "node:child_process";
381
- import fs8 from "node:fs/promises";
382
- import path7 from "node:path";
321
+ var import_picocolors2 = __toESM(require_picocolors(), 1);
322
+ import fs3 from "node:fs/promises";
383
323
 
384
324
  // src/agents.ts
385
325
  var import_which = __toESM(require_lib(), 1);
@@ -387,194 +327,113 @@ import fs from "node:fs/promises";
387
327
  import os from "node:os";
388
328
  import path from "node:path";
389
329
  var HOME = os.homedir();
390
- var braceDollar = (v) => "${" + v + "}";
391
- var envBrace = (v) => "{env:" + v + "}";
392
- var plainDollar = (v) => "$" + v;
393
- function bearer(c, interp) {
394
- if (c.authMode === "none")
395
- return;
396
- return c.authMode === "env" ? `Bearer ${interp(c.envVarName)}` : `Bearer ${c.token}`;
397
- }
398
- function httpEntry(interp, opts = {}) {
399
- const typeValue = opts.typeValue === undefined ? "http" : opts.typeValue;
400
- const urlField = opts.urlField ?? "url";
401
- return (c) => {
402
- const e = {};
403
- if (typeValue)
404
- e.type = typeValue;
405
- e[urlField] = c.url;
406
- if (opts.extra)
407
- Object.assign(e, opts.extra);
408
- const h = bearer(c, interp);
409
- if (h)
410
- e.headers = { Authorization: h };
411
- return e;
412
- };
413
- }
414
- function codexEntry(c) {
415
- if (c.authMode === "none")
416
- return { url: c.url };
417
- if (c.authMode === "env")
418
- return { url: c.url, bearer_token_env_var: c.envVarName };
419
- return { url: c.url, http_headers: { Authorization: `Bearer ${c.token}` } };
330
+ function vscodeUserMcp() {
331
+ if (process.platform === "darwin") {
332
+ return path.join(HOME, "Library", "Application Support", "Code", "User", "mcp.json");
333
+ }
334
+ if (process.platform === "win32") {
335
+ return path.join(process.env.APPDATA ?? path.join(HOME, "AppData", "Roaming"), "Code", "User", "mcp.json");
336
+ }
337
+ return path.join(HOME, ".config", "Code", "User", "mcp.json");
420
338
  }
339
+ var httpType = (url) => ({ type: "http", url });
340
+ var urlOnly = (url) => ({ url });
341
+ var httpUrlField = (url) => ({ httpUrl: url });
342
+ var opencodeRemote = (url) => ({ type: "remote", url, enabled: true });
343
+ var windsurfUrl = (url) => ({ serverUrl: url });
421
344
  var AGENTS = [
422
345
  {
423
346
  id: "claude",
424
347
  label: "Claude Code",
425
- kind: "cli",
426
- bin: "claude",
427
- binPaths: [
428
- path.join(HOME, ".claude", "local", "claude"),
429
- path.join(HOME, ".local", "bin", "claude"),
430
- "/opt/homebrew/bin/claude",
431
- "/usr/local/bin/claude"
432
- ],
433
- installCmd: ["npm", "install", "-g", "@anthropic-ai/claude-code"],
434
- scope: "project",
435
- configPath: ".mcp.json",
348
+ configPath: path.join(HOME, ".claude.json"),
436
349
  format: "json",
437
350
  containerKey: "mcpServers",
438
- authMode: "env",
439
- markers: [".mcp.json", ".claude"],
440
- entry: httpEntry(braceDollar)
351
+ entry: httpType,
352
+ bin: "claude",
353
+ homeMarkers: [".claude", ".claude.json"]
441
354
  },
442
355
  {
443
356
  id: "codex",
444
357
  label: "Codex",
445
- kind: "cli",
446
- bin: "codex",
447
- binPaths: [path.join(HOME, ".local", "bin", "codex"), "/opt/homebrew/bin/codex", "/usr/local/bin/codex"],
448
- installCmd: ["npm", "install", "-g", "@openai/codex"],
449
- scope: "project",
450
- configPath: path.join(".codex", "config.toml"),
358
+ configPath: path.join(HOME, ".codex", "config.toml"),
451
359
  format: "toml",
452
360
  containerKey: "mcp_servers",
453
- authMode: "env",
454
- markers: [".codex"],
455
- entry: codexEntry
361
+ entry: urlOnly,
362
+ bin: "codex",
363
+ homeMarkers: [".codex"]
456
364
  },
457
365
  {
458
366
  id: "gemini",
459
367
  label: "Gemini CLI",
460
- kind: "cli",
461
- bin: "gemini",
462
- binPaths: [path.join(HOME, ".local", "bin", "gemini"), "/opt/homebrew/bin/gemini", "/usr/local/bin/gemini"],
463
- installCmd: ["npm", "install", "-g", "@google/gemini-cli"],
464
- scope: "project",
465
- configPath: path.join(".gemini", "settings.json"),
368
+ configPath: path.join(HOME, ".gemini", "settings.json"),
466
369
  format: "json",
467
370
  containerKey: "mcpServers",
468
- authMode: "env",
469
- markers: [".gemini"],
470
- homeMarkers: [".gemini"],
471
- entry: httpEntry(braceDollar, { typeValue: null, urlField: "httpUrl" })
371
+ entry: httpUrlField,
372
+ bin: "gemini",
373
+ homeMarkers: [".gemini"]
472
374
  },
473
375
  {
474
376
  id: "opencode",
475
377
  label: "OpenCode",
476
- kind: "cli",
477
- bin: "opencode",
478
- binPaths: [path.join(HOME, ".local", "bin", "opencode"), "/opt/homebrew/bin/opencode", "/usr/local/bin/opencode"],
479
- installCmd: ["npm", "install", "-g", "opencode-ai"],
480
- scope: "project",
481
- configPath: "opencode.json",
378
+ configPath: path.join(HOME, ".config", "opencode", "opencode.json"),
482
379
  format: "json",
483
380
  containerKey: "mcp",
484
- authMode: "env",
485
- markers: ["opencode.json", ".opencode"],
486
- entry: httpEntry(envBrace, { typeValue: "remote", extra: { enabled: true } })
381
+ entry: opencodeRemote,
382
+ bin: "opencode",
383
+ homeMarkers: [path.join(".config", "opencode")]
487
384
  },
488
385
  {
489
386
  id: "copilot",
490
387
  label: "Copilot CLI",
491
- kind: "cli",
492
- bin: "copilot",
493
- binPaths: [path.join(HOME, ".local", "bin", "copilot")],
494
- installCmd: ["npm", "install", "-g", "@github/copilot"],
495
- scope: "global",
496
388
  configPath: path.join(HOME, ".copilot", "mcp-config.json"),
497
389
  format: "json",
498
390
  containerKey: "mcpServers",
499
- authMode: "env",
500
- homeMarkers: [".copilot"],
501
- entry: httpEntry(plainDollar)
391
+ entry: httpType,
392
+ bin: "copilot",
393
+ homeMarkers: [".copilot"]
502
394
  },
503
395
  {
504
396
  id: "cursor",
505
397
  label: "Cursor",
506
- kind: "gui",
507
- scope: "project",
508
- configPath: path.join(".cursor", "mcp.json"),
398
+ configPath: path.join(HOME, ".cursor", "mcp.json"),
509
399
  format: "json",
510
400
  containerKey: "mcpServers",
511
- authMode: "literal",
512
- markers: [".cursor"],
513
- homeMarkers: [".cursor"],
514
- entry: httpEntry(braceDollar)
401
+ entry: urlOnly,
402
+ homeMarkers: [".cursor"]
515
403
  },
516
404
  {
517
405
  id: "windsurf",
518
406
  label: "Windsurf",
519
- kind: "gui",
520
- scope: "project",
521
- configPath: path.join(".windsurf", "mcp_config.json"),
407
+ configPath: path.join(HOME, ".codeium", "windsurf", "mcp_config.json"),
522
408
  format: "json",
523
409
  containerKey: "mcpServers",
524
- authMode: "literal",
525
- markers: [".windsurf"],
526
- homeMarkers: [".codeium", ".windsurf"],
527
- entry: httpEntry(braceDollar)
410
+ entry: windsurfUrl,
411
+ homeMarkers: [".codeium", ".windsurf"]
528
412
  },
529
413
  {
530
414
  id: "vscode",
531
415
  label: "VS Code / Copilot",
532
- kind: "gui",
533
- scope: "project",
534
- configPath: path.join(".vscode", "mcp.json"),
416
+ configPath: vscodeUserMcp(),
535
417
  format: "json",
536
418
  containerKey: "servers",
537
- authMode: "literal",
538
- markers: [path.join(".vscode", "mcp.json"), path.join(".github", "copilot-instructions.md")],
539
- vscodeExt: true,
540
- entry: httpEntry(braceDollar)
419
+ entry: httpType,
420
+ vscodeExt: true
541
421
  }
542
422
  ];
543
- var LAUNCHABLE = AGENTS.filter((a) => a.kind === "cli");
544
- function findAgent(id) {
545
- return AGENTS.find((a) => a.id === id);
423
+ function configFileFor(agent) {
424
+ return agent.configPath;
546
425
  }
547
- function configFileFor(agent, cwd) {
548
- return agent.scope === "global" ? agent.configPath : path.join(cwd, agent.configPath);
549
- }
550
- async function findBin(agent) {
551
- if (agent.bin) {
552
- try {
553
- return await import_which.default(agent.bin);
554
- } catch {}
555
- }
556
- for (const p of agent.binPaths ?? []) {
557
- if (await exists(p))
558
- return p;
559
- }
560
- return null;
561
- }
562
- async function detectAgents(cwd, include = []) {
426
+ async function detectAgents() {
563
427
  const out = [];
564
428
  for (const a of AGENTS) {
565
- if (a.id === "claude" || include.includes(a.id) || await isDetected(a, cwd)) {
429
+ if (await isDetected(a))
566
430
  out.push(a);
567
- }
568
431
  }
569
432
  return out;
570
433
  }
571
- async function isDetected(a, cwd) {
572
- if (a.bin && await findBin(a))
434
+ async function isDetected(a) {
435
+ if (a.bin && await onPath(a.bin))
573
436
  return true;
574
- for (const m of a.markers ?? []) {
575
- if (await exists(path.join(cwd, m)))
576
- return true;
577
- }
578
437
  for (const m of a.homeMarkers ?? []) {
579
438
  if (await exists(path.join(HOME, m)))
580
439
  return true;
@@ -583,11 +442,16 @@ async function isDetected(a, cwd) {
583
442
  return true;
584
443
  return false;
585
444
  }
445
+ async function onPath(bin) {
446
+ try {
447
+ await import_which.default(bin);
448
+ return true;
449
+ } catch {
450
+ return false;
451
+ }
452
+ }
586
453
  async function hasVscodeCopilot() {
587
- const roots = [
588
- path.join(HOME, ".vscode", "extensions"),
589
- path.join(HOME, ".vscode-insiders", "extensions")
590
- ];
454
+ const roots = [path.join(HOME, ".vscode", "extensions"), path.join(HOME, ".vscode-insiders", "extensions")];
591
455
  for (const root of roots) {
592
456
  try {
593
457
  const entries = await fs.readdir(root);
@@ -606,1262 +470,191 @@ async function exists(p) {
606
470
  }
607
471
  }
608
472
 
609
- // src/config.ts
473
+ // src/mcp-writer.ts
610
474
  import fs2 from "node:fs/promises";
611
-
612
- // src/paths.ts
613
475
  import path2 from "node:path";
614
- import os2 from "node:os";
615
- function xdgConfigHome() {
616
- return process.env.XDG_CONFIG_HOME || path2.join(os2.homedir(), ".config");
617
- }
618
- var juspayConfigDir = path2.join(xdgConfigHome(), "juspay");
619
- var juspayConfigPath = path2.join(juspayConfigDir, "config.json");
620
- var juspayOauthPath = path2.join(juspayConfigDir, "oauth.json");
621
476
 
622
- // src/config.ts
623
- async function readConfig() {
624
- let raw;
625
- try {
626
- raw = await fs2.readFile(juspayConfigPath, "utf8");
627
- } catch (err) {
628
- if (err.code === "ENOENT")
629
- return null;
630
- throw err;
631
- }
632
- const parsed = JSON.parse(raw);
633
- if (!isConfig(parsed)) {
634
- throw new Error(`Invalid config at ${juspayConfigPath}. Expected { merchant_id, client_id, environment }. ` + "Re-run `npx @sahyll/ai init` to recreate.");
635
- }
636
- return parsed;
637
- }
638
- async function writeConfig(config) {
639
- await fs2.mkdir(juspayConfigDir, { recursive: true });
640
- await fs2.writeFile(juspayConfigPath, JSON.stringify(config, null, 2) + `
641
- `, "utf8");
642
- await fs2.chmod(juspayConfigPath, 384);
643
- }
644
- function isConfig(value) {
645
- if (!value || typeof value !== "object")
646
- return false;
647
- const v = value;
648
- return typeof v.merchant_id === "string" && v.merchant_id.length > 0 && typeof v.client_id === "string" && v.client_id.length > 0 && (v.environment === "sandbox" || v.environment === "production");
477
+ // node_modules/smol-toml/dist/error.js
478
+ /*!
479
+ * Copyright (c) Squirrel Chat et al., All rights reserved.
480
+ * SPDX-License-Identifier: BSD-3-Clause
481
+ *
482
+ * Redistribution and use in source and binary forms, with or without
483
+ * modification, are permitted provided that the following conditions are met:
484
+ *
485
+ * 1. Redistributions of source code must retain the above copyright notice, this
486
+ * list of conditions and the following disclaimer.
487
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
488
+ * this list of conditions and the following disclaimer in the
489
+ * documentation and/or other materials provided with the distribution.
490
+ * 3. Neither the name of the copyright holder nor the names of its contributors
491
+ * may be used to endorse or promote products derived from this software without
492
+ * specific prior written permission.
493
+ *
494
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
495
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
496
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
497
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
498
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
499
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
500
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
501
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
502
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
503
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
504
+ */
505
+ function getLineColFromPtr(string, ptr) {
506
+ let lines = string.slice(0, ptr).split(/\r\n|\n|\r/g);
507
+ return [lines.length, lines.pop().length + 1];
649
508
  }
650
-
651
- // src/servers.ts
652
- var JUSPAY_MCP_ISSUER = "https://mcp.juspay.in/dashboard";
653
- var JUSPAY_MCP_ENDPOINT = "https://mcp.juspay.in/dashboard/juspay-dashboard-stream";
654
- var DOCS_MCP_ENDPOINT = "https://mcp.juspay.in/dashboard/juspay-docs-stream";
655
- var DOCS_MCP_NAME = "docs-mcp-server";
656
- var DASHBOARD_MCP_NAME = "juspay-mcp";
657
- var OUR_MCP_NAMES = [DOCS_MCP_NAME, DASHBOARD_MCP_NAME];
658
- var MCP_TOKEN_VAR = "JUSPAY_MCP_TOKEN";
659
- var SKILLS_PACKAGE = "sahyll/juspay-skills/skills/integrate";
660
- var PACKAGE_NAME = "@sahyll/ai";
661
- var CLI_VERSION = "0.4.1";
662
- var USER_AGENT = `juspay-ai-cli/${CLI_VERSION} (+https://juspay.in)`;
663
-
664
- // src/mcp-call.ts
665
- async function callMcpTool(endpoint, bearer2, tool, args = {}) {
666
- let sessionId;
667
- const initResult = await rpc(endpoint, bearer2, sessionId, {
668
- jsonrpc: "2.0",
669
- id: 1,
670
- method: "initialize",
671
- params: {
672
- protocolVersion: "2025-06-18",
673
- capabilities: {},
674
- clientInfo: { name: "juspay-ai-cli", version: CLI_VERSION }
509
+ function makeCodeBlock(string, line, column) {
510
+ let lines = string.split(/\r\n|\n|\r/g);
511
+ let codeblock = "";
512
+ let numberLen = (Math.log10(line + 1) | 0) + 1;
513
+ for (let i = line - 1;i <= line + 1; i++) {
514
+ let l = lines[i - 1];
515
+ if (!l)
516
+ continue;
517
+ codeblock += i.toString().padEnd(numberLen, " ");
518
+ codeblock += ": ";
519
+ codeblock += l;
520
+ codeblock += `
521
+ `;
522
+ if (i === line) {
523
+ codeblock += " ".repeat(numberLen + column + 2);
524
+ codeblock += `^
525
+ `;
675
526
  }
676
- });
677
- sessionId = initResult.sessionId;
678
- if ("error" in initResult.body) {
679
- throw new Error(`MCP initialize failed: ${initResult.body.error.message}`);
680
- }
681
- await postNotification(endpoint, bearer2, sessionId, {
682
- jsonrpc: "2.0",
683
- method: "notifications/initialized"
684
- });
685
- const callResult = await rpc(endpoint, bearer2, sessionId, {
686
- jsonrpc: "2.0",
687
- id: 2,
688
- method: "tools/call",
689
- params: { name: tool, arguments: args }
690
- });
691
- if ("error" in callResult.body) {
692
- throw new Error(`MCP tool '${tool}' failed: ${callResult.body.error.message}`);
693
527
  }
694
- return callResult.body.result;
528
+ return codeblock;
695
529
  }
696
- async function rpc(endpoint, bearer2, sessionId, payload) {
697
- const res = await fetch(endpoint, {
698
- method: "POST",
699
- headers: buildHeaders(bearer2, sessionId),
700
- body: JSON.stringify(payload)
701
- });
702
- if (!res.ok) {
703
- const text = await res.text().catch(() => "");
704
- throw new Error(`MCP HTTP ${res.status}: ${text.slice(0, 400)}`);
530
+
531
+ class TomlError extends Error {
532
+ line;
533
+ column;
534
+ codeblock;
535
+ constructor(message, options) {
536
+ const [line, column] = getLineColFromPtr(options.toml, options.ptr);
537
+ const codeblock = makeCodeBlock(options.toml, line, column);
538
+ super(`Invalid TOML document: ${message}
539
+
540
+ ${codeblock}`, options);
541
+ this.line = line;
542
+ this.column = column;
543
+ this.codeblock = codeblock;
705
544
  }
706
- const sid = res.headers.get("mcp-session-id") ?? sessionId;
707
- const body = await readJsonRpc(res);
708
- return { body, sessionId: sid ?? undefined };
709
545
  }
710
- async function postNotification(endpoint, bearer2, sessionId, payload) {
711
- await fetch(endpoint, {
712
- method: "POST",
713
- headers: buildHeaders(bearer2, sessionId),
714
- body: JSON.stringify(payload)
715
- });
546
+
547
+ // node_modules/smol-toml/dist/util.js
548
+ /*!
549
+ * Copyright (c) Squirrel Chat et al., All rights reserved.
550
+ * SPDX-License-Identifier: BSD-3-Clause
551
+ *
552
+ * Redistribution and use in source and binary forms, with or without
553
+ * modification, are permitted provided that the following conditions are met:
554
+ *
555
+ * 1. Redistributions of source code must retain the above copyright notice, this
556
+ * list of conditions and the following disclaimer.
557
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
558
+ * this list of conditions and the following disclaimer in the
559
+ * documentation and/or other materials provided with the distribution.
560
+ * 3. Neither the name of the copyright holder nor the names of its contributors
561
+ * may be used to endorse or promote products derived from this software without
562
+ * specific prior written permission.
563
+ *
564
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
565
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
566
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
567
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
568
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
569
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
570
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
571
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
572
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
573
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
574
+ */
575
+ function isEscaped(str, ptr) {
576
+ let i = 0;
577
+ while (str[ptr - ++i] === "\\")
578
+ ;
579
+ return --i && i % 2;
716
580
  }
717
- function buildHeaders(bearer2, sessionId) {
718
- const h = {
719
- "Content-Type": "application/json",
720
- Accept: "application/json, text/event-stream",
721
- Authorization: `Bearer ${bearer2}`,
722
- "User-Agent": USER_AGENT
723
- };
724
- if (sessionId)
725
- h["Mcp-Session-Id"] = sessionId;
726
- return h;
581
+ function indexOfNewline(str, start = 0, end = str.length) {
582
+ let idx = str.indexOf(`
583
+ `, start);
584
+ if (str[idx - 1] === "\r")
585
+ idx--;
586
+ return idx <= end ? idx : -1;
727
587
  }
728
- async function readJsonRpc(res) {
729
- const ct = res.headers.get("content-type") ?? "";
730
- const text = await res.text();
731
- if (ct.includes("text/event-stream")) {
732
- for (const line of text.split(/\r?\n/)) {
733
- if (line.startsWith("data:")) {
734
- const json = line.slice(5).trim();
735
- if (json)
736
- return JSON.parse(json);
737
- }
588
+ function skipComment(str, ptr) {
589
+ for (let i = ptr;i < str.length; i++) {
590
+ let c = str[i];
591
+ if (c === `
592
+ `)
593
+ return i;
594
+ if (c === "\r" && str[i + 1] === `
595
+ `)
596
+ return i + 1;
597
+ if (c < " " && c !== "\t" || c === "") {
598
+ throw new TomlError("control characters are not allowed in comments", {
599
+ toml: str,
600
+ ptr
601
+ });
738
602
  }
739
- throw new Error("SSE response contained no JSON-RPC payload.");
740
603
  }
741
- return JSON.parse(text);
742
- }
743
-
744
- // src/oauth.ts
745
- var import_picocolors = __toESM(require_picocolors(), 1);
746
- import crypto from "node:crypto";
747
- import http from "node:http";
748
- import { spawn } from "node:child_process";
749
- var REDIRECT_PORT = 33418;
750
- var REDIRECT_URI = `http://localhost:${REDIRECT_PORT}/callback`;
751
- var OAUTH_TIMEOUT_MS = 5 * 60 * 1000;
752
- var SCOPES = [
753
- "analytics:read",
754
- "orders:read",
755
- "orders:write",
756
- "settings:read",
757
- "gateways:read",
758
- "reports:read",
759
- "users:read",
760
- "alerts:read"
761
- ].join(" ");
762
- async function runOAuthFlow(issuer) {
763
- const meta = await discover(issuer);
764
- const dcr = await registerClient(meta.registration_endpoint);
765
- const verifier = base64url(crypto.randomBytes(32));
766
- const challenge = base64url(crypto.createHash("sha256").update(verifier).digest());
767
- const state = base64url(crypto.randomBytes(16));
768
- const { code, returnedState } = await captureCode((codeUrl) => {
769
- const authUrl = meta.authorization_endpoint + "?" + new URLSearchParams({
770
- response_type: "code",
771
- client_id: dcr.client_id,
772
- redirect_uri: REDIRECT_URI,
773
- scope: SCOPES,
774
- state,
775
- code_challenge: challenge,
776
- code_challenge_method: "S256"
777
- }).toString();
778
- process.stdout.write(" " + import_picocolors.default.dim(`If the browser doesn't open: ${authUrl}
779
- `));
780
- openBrowser(authUrl);
781
- return codeUrl;
782
- });
783
- if (returnedState !== state) {
784
- throw new Error("OAuth state mismatch — aborting.");
785
- }
786
- const tok = await exchangeCode({
787
- tokenEndpoint: meta.token_endpoint,
788
- code,
789
- verifier,
790
- clientId: dcr.client_id,
791
- clientSecret: dcr.client_secret
792
- });
793
- const issuedAt = Math.floor(Date.now() / 1000);
794
- return {
795
- issuer,
796
- client_id: dcr.client_id,
797
- client_secret: dcr.client_secret,
798
- access_token: tok.access_token,
799
- refresh_token: tok.refresh_token,
800
- expires_at: issuedAt + tok.expires_in,
801
- scope: tok.scope ?? SCOPES
802
- };
803
- }
804
- async function refreshOAuthFlow(state) {
805
- const meta = await discover(state.issuer);
806
- const tok = await refreshToken({
807
- tokenEndpoint: meta.token_endpoint,
808
- refreshToken: state.refresh_token,
809
- clientId: state.client_id,
810
- clientSecret: state.client_secret
811
- });
812
- const issuedAt = Math.floor(Date.now() / 1000);
813
- return {
814
- issuer: state.issuer,
815
- client_id: state.client_id,
816
- client_secret: state.client_secret,
817
- access_token: tok.access_token,
818
- refresh_token: tok.refresh_token ?? state.refresh_token,
819
- expires_at: issuedAt + tok.expires_in,
820
- scope: tok.scope ?? state.scope
821
- };
604
+ return str.length;
822
605
  }
823
- async function discover(issuer) {
824
- const url = issuer.replace(/\/$/, "") + "/.well-known/oauth-authorization-server";
825
- const r = await fetchJson(url);
826
- if (!r.authorization_endpoint || !r.token_endpoint || !r.registration_endpoint) {
827
- throw new Error(`Auth server metadata at ${url} is missing required endpoints.`);
606
+ function skipVoid(str, ptr, banNewLines, banComments) {
607
+ let c;
608
+ while (true) {
609
+ while ((c = str[ptr]) === " " || c === "\t" || !banNewLines && (c === `
610
+ ` || c === "\r" && str[ptr + 1] === `
611
+ `))
612
+ ptr++;
613
+ if (banComments || c !== "#")
614
+ break;
615
+ ptr = skipComment(str, ptr);
828
616
  }
829
- return r;
617
+ return ptr;
830
618
  }
831
- async function registerClient(registrationEndpoint) {
832
- const body = {
833
- client_name: "juspay-ai-cli",
834
- redirect_uris: [REDIRECT_URI],
835
- grant_types: ["authorization_code", "refresh_token"],
836
- response_types: ["code"],
837
- scope: SCOPES
838
- };
839
- const r = await fetchJson(registrationEndpoint, {
840
- method: "POST",
841
- headers: { "Content-Type": "application/json" },
842
- body: JSON.stringify(body)
843
- });
844
- if (!r.client_id || !r.client_secret) {
845
- throw new Error("Dynamic client registration did not return client_id/client_secret.");
619
+ function skipUntil(str, ptr, sep, end, banNewLines = false) {
620
+ if (!end) {
621
+ ptr = indexOfNewline(str, ptr);
622
+ return ptr < 0 ? str.length : ptr;
846
623
  }
847
- return r;
848
- }
849
- async function exchangeCode(params) {
850
- const form = new URLSearchParams({
851
- grant_type: "authorization_code",
852
- code: params.code,
853
- redirect_uri: REDIRECT_URI,
854
- client_id: params.clientId,
855
- client_secret: params.clientSecret,
856
- code_verifier: params.verifier
857
- });
858
- const r = await fetchJson(params.tokenEndpoint, {
859
- method: "POST",
860
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
861
- body: form.toString()
862
- });
863
- if (!r.access_token || !r.refresh_token || typeof r.expires_in !== "number") {
864
- throw new Error("Token endpoint did not return access_token/refresh_token/expires_in.");
624
+ for (let i = ptr;i < str.length; i++) {
625
+ let c = str[i];
626
+ if (c === "#") {
627
+ i = indexOfNewline(str, i);
628
+ } else if (c === sep) {
629
+ return i + 1;
630
+ } else if (c === end || banNewLines && (c === `
631
+ ` || c === "\r" && str[i + 1] === `
632
+ `)) {
633
+ return i;
634
+ }
865
635
  }
866
- return r;
867
- }
868
- async function refreshToken(params) {
869
- const form = new URLSearchParams({
870
- grant_type: "refresh_token",
871
- refresh_token: params.refreshToken,
872
- client_id: params.clientId,
873
- client_secret: params.clientSecret
874
- });
875
- const r = await fetchJson(params.tokenEndpoint, {
876
- method: "POST",
877
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
878
- body: form.toString()
636
+ throw new TomlError("cannot find end of structure", {
637
+ toml: str,
638
+ ptr
879
639
  });
880
- if (!r.access_token || typeof r.expires_in !== "number") {
881
- throw new Error("Refresh token endpoint did not return access_token/expires_in.");
640
+ }
641
+ function getStringEnd(str, seek) {
642
+ let first = str[seek];
643
+ let target = first === str[seek + 1] && str[seek + 1] === str[seek + 2] ? str.slice(seek, seek + 3) : first;
644
+ seek += target.length - 1;
645
+ do
646
+ seek = str.indexOf(target, ++seek);
647
+ while (seek > -1 && first !== "'" && isEscaped(str, seek));
648
+ if (seek > -1) {
649
+ seek += target.length;
650
+ if (target.length > 1) {
651
+ if (str[seek] === first)
652
+ seek++;
653
+ if (str[seek] === first)
654
+ seek++;
655
+ }
882
656
  }
883
- return r;
884
- }
885
- function captureCode(startBrowser) {
886
- return new Promise((resolve, reject) => {
887
- let timer = null;
888
- const cleanup = () => {
889
- if (timer)
890
- clearTimeout(timer);
891
- server.close();
892
- };
893
- const server = http.createServer((req, res) => {
894
- if (!req.url)
895
- return;
896
- const u = new URL(req.url, REDIRECT_URI);
897
- if (u.pathname !== "/callback") {
898
- res.writeHead(404);
899
- res.end();
900
- return;
901
- }
902
- const code = u.searchParams.get("code");
903
- const returnedState = u.searchParams.get("state") ?? "";
904
- const error = u.searchParams.get("error");
905
- res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
906
- if (error) {
907
- res.end(`<h2>Sign-in failed: ${escapeHtml(error)}</h2><p>You can close this tab.</p>`);
908
- cleanup();
909
- reject(new Error(`OAuth error from authorization server: ${error}`));
910
- return;
911
- }
912
- if (!code) {
913
- res.end("<h2>Missing code.</h2><p>You can close this tab.</p>");
914
- cleanup();
915
- reject(new Error("Authorization server callback was missing the code parameter."));
916
- return;
917
- }
918
- res.end("<h2>Signed in successfully.</h2><p>You can close this tab and return to the terminal.</p>");
919
- cleanup();
920
- resolve({ code, returnedState });
921
- });
922
- server.on("error", (err) => {
923
- cleanup();
924
- if (err.code === "EADDRINUSE") {
925
- reject(new Error(`Port ${REDIRECT_PORT} is already in use. Close whatever is using it and re-run \`npx @sahyll/ai init\`.`));
926
- } else {
927
- reject(err);
928
- }
929
- });
930
- server.listen(REDIRECT_PORT, "127.0.0.1", () => {
931
- startBrowser(REDIRECT_URI);
932
- timer = setTimeout(() => {
933
- cleanup();
934
- reject(new Error(`Sign-in timed out after ${OAUTH_TIMEOUT_MS / 60000} minutes. Re-run \`npx @sahyll/ai init\` to retry.`));
935
- }, OAUTH_TIMEOUT_MS);
936
- });
937
- });
938
- }
939
- function openBrowser(url) {
940
- const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
941
- const args = process.platform === "win32" ? ["", url] : [url];
942
- spawn(cmd, args, { stdio: "ignore", detached: true, shell: process.platform === "win32" }).unref();
943
- }
944
- async function fetchJson(url, init) {
945
- let res;
946
- try {
947
- res = await fetch(url, {
948
- ...init,
949
- headers: {
950
- Accept: "application/json",
951
- "User-Agent": USER_AGENT,
952
- ...init?.headers ?? {}
953
- }
954
- });
955
- } catch (err) {
956
- const cause = err.cause;
957
- const detail = cause?.code ? `${cause.code}${cause.message ? ` — ${cause.message}` : ""}` : err.message;
958
- throw new Error(`Could not reach ${url}
959
- ${detail}`);
960
- }
961
- if (!res.ok) {
962
- const text = await res.text().catch(() => "");
963
- throw new Error(`HTTP ${res.status} from ${url}${text ? `: ${text.slice(0, 300)}` : ""}`);
964
- }
965
- return res.json();
966
- }
967
- function base64url(buf) {
968
- return buf.toString("base64").replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
969
- }
970
- function escapeHtml(s) {
971
- return s.replace(/[&<>"']/g, (c) => c === "&" ? "&amp;" : c === "<" ? "&lt;" : c === ">" ? "&gt;" : c === '"' ? "&quot;" : "&#39;");
972
- }
973
-
974
- // src/oauth-config.ts
975
- import fs3 from "node:fs/promises";
976
- async function readOAuth() {
977
- let raw;
978
- try {
979
- raw = await fs3.readFile(juspayOauthPath, "utf8");
980
- } catch (err) {
981
- if (err.code === "ENOENT")
982
- return null;
983
- throw err;
984
- }
985
- const parsed = JSON.parse(raw);
986
- if (!isOAuthState(parsed)) {
987
- throw new Error(`Invalid OAuth state at ${juspayOauthPath}. Re-run \`npx @sahyll/ai init\` to recreate.`);
988
- }
989
- return parsed;
990
- }
991
- async function writeOAuth(state) {
992
- await fs3.mkdir(juspayConfigDir, { recursive: true });
993
- await fs3.writeFile(juspayOauthPath, JSON.stringify(state, null, 2) + `
994
- `, "utf8");
995
- await fs3.chmod(juspayOauthPath, 384);
996
- }
997
- function isOAuthState(value) {
998
- if (!value || typeof value !== "object")
999
- return false;
1000
- const v = value;
1001
- return typeof v.issuer === "string" && typeof v.client_id === "string" && typeof v.client_secret === "string" && typeof v.access_token === "string" && typeof v.refresh_token === "string" && typeof v.expires_at === "number" && typeof v.scope === "string";
1002
- }
1003
-
1004
- // src/ui.ts
1005
- var import_picocolors2 = __toESM(require_picocolors(), 1);
1006
- var ANSI_RE = /\x1B\[[0-9;]*m/g;
1007
- function visibleLen(s) {
1008
- return s.replace(ANSI_RE, "").length;
1009
- }
1010
- var SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
1011
-
1012
- class Spinner {
1013
- timer = null;
1014
- frame = 0;
1015
- message;
1016
- interactive;
1017
- constructor(message) {
1018
- this.message = message;
1019
- this.interactive = Boolean(process.stdout.isTTY);
1020
- }
1021
- start() {
1022
- if (!this.interactive) {
1023
- process.stdout.write(" " + import_picocolors2.default.dim("→ ") + this.message + `
1024
- `);
1025
- return this;
1026
- }
1027
- process.stdout.write("\x1B[?25l");
1028
- this.render();
1029
- this.timer = setInterval(() => this.render(), 80);
1030
- return this;
1031
- }
1032
- update(message) {
1033
- this.message = message;
1034
- if (!this.interactive) {
1035
- process.stdout.write(" " + import_picocolors2.default.dim("→ ") + message + `
1036
- `);
1037
- }
1038
- }
1039
- done(finalMessage) {
1040
- this.stop();
1041
- process.stdout.write(" " + import_picocolors2.default.green("✓ ") + finalMessage + `
1042
- `);
1043
- }
1044
- fail(finalMessage) {
1045
- this.stop();
1046
- process.stdout.write(" " + import_picocolors2.default.red("✗ ") + finalMessage + `
1047
- `);
1048
- }
1049
- render() {
1050
- const glyph = import_picocolors2.default.cyan(SPINNER_FRAMES[this.frame]);
1051
- process.stdout.write("\r\x1B[K " + glyph + " " + this.message);
1052
- this.frame = (this.frame + 1) % SPINNER_FRAMES.length;
1053
- }
1054
- stop() {
1055
- if (this.timer) {
1056
- clearInterval(this.timer);
1057
- this.timer = null;
1058
- }
1059
- if (this.interactive) {
1060
- process.stdout.write("\r\x1B[K");
1061
- process.stdout.write("\x1B[?25h");
1062
- }
1063
- }
1064
- }
1065
- function spin(message) {
1066
- return new Spinner(message).start();
1067
- }
1068
- function banner() {
1069
- process.stdout.write(`
1070
- `);
1071
- process.stdout.write(" " + import_picocolors2.default.cyan(import_picocolors2.default.bold("Juspay for AI agents")) + `
1072
- `);
1073
- process.stdout.write(`
1074
- `);
1075
- }
1076
- function step(msg) {
1077
- process.stdout.write(" " + import_picocolors2.default.dim("→ ") + msg + `
1078
- `);
1079
- }
1080
- function done(msg) {
1081
- process.stdout.write(" " + import_picocolors2.default.green("✓ ") + msg + `
1082
- `);
1083
- }
1084
- function info(msg) {
1085
- process.stdout.write(" " + import_picocolors2.default.dim(msg) + `
1086
- `);
1087
- }
1088
- function warn(msg) {
1089
- process.stdout.write(" " + import_picocolors2.default.yellow("⚠ ") + msg + `
1090
- `);
1091
- }
1092
- function summaryBox(title, rows) {
1093
- const labelWidth = Math.max(...rows.map((r) => visibleLen(r.label)));
1094
- const composed = rows.map((r) => {
1095
- const padding = " ".repeat(labelWidth - visibleLen(r.label) + 2);
1096
- return import_picocolors2.default.green("✓ ") + import_picocolors2.default.bold(r.label) + padding + r.value;
1097
- });
1098
- const widest = Math.max(visibleLen(` Setup `) + title.length, ...composed.map(visibleLen));
1099
- const innerWidth = Math.max(widest + 4, 44);
1100
- const top = " " + import_picocolors2.default.dim("╭─ ") + import_picocolors2.default.bold(title) + " " + import_picocolors2.default.dim("─".repeat(innerWidth - title.length - 4)) + import_picocolors2.default.dim("╮");
1101
- const empty = " " + import_picocolors2.default.dim("│") + " ".repeat(innerWidth) + import_picocolors2.default.dim("│");
1102
- const bottom = " " + import_picocolors2.default.dim("╰" + "─".repeat(innerWidth) + "╯");
1103
- process.stdout.write(`
1104
- `);
1105
- process.stdout.write(top + `
1106
- `);
1107
- process.stdout.write(empty + `
1108
- `);
1109
- for (const line of composed) {
1110
- const pad = " ".repeat(Math.max(0, innerWidth - visibleLen(line) - 4));
1111
- process.stdout.write(" " + import_picocolors2.default.dim("│") + " " + line + pad + " " + import_picocolors2.default.dim("│") + `
1112
- `);
1113
- }
1114
- process.stdout.write(empty + `
1115
- `);
1116
- process.stdout.write(bottom + `
1117
- `);
1118
- }
1119
-
1120
- // src/init.ts
1121
- async function runInit(opts = {}) {
1122
- const tokens = await acquireTokens({ force: opts.force ?? false });
1123
- const expiresOn = new Date(tokens.expires_at * 1000).toDateString();
1124
- done(`Authenticated · session valid until ${expiresOn}`);
1125
- const s = spin("Fetching merchant details...");
1126
- let merchantId;
1127
- try {
1128
- merchantId = await fetchMerchantId(tokens.access_token);
1129
- } catch (err) {
1130
- s.fail("Could not fetch merchant details");
1131
- throw err;
1132
- }
1133
- s.done(`Merchant: ${merchantId}`);
1134
- return {
1135
- merchant_id: merchantId,
1136
- client_id: merchantId,
1137
- environment: opts.env ?? "production"
1138
- };
1139
- }
1140
- async function acquireTokens(opts) {
1141
- if (!opts.force) {
1142
- const existing = await readOAuth().catch(() => null);
1143
- if (existing && isStillValid(existing)) {
1144
- try {
1145
- const refreshed = await refreshOAuthFlow(existing);
1146
- await writeOAuth(refreshed);
1147
- return refreshed;
1148
- } catch {
1149
- return existing;
1150
- }
1151
- }
1152
- }
1153
- step("Opening browser for sign-in...");
1154
- const fresh = await runOAuthFlow(JUSPAY_MCP_ISSUER);
1155
- await writeOAuth(fresh);
1156
- return fresh;
1157
- }
1158
- function isStillValid(state) {
1159
- const skewSeconds = 24 * 60 * 60;
1160
- return state.expires_at > Math.floor(Date.now() / 1000) + skewSeconds;
1161
- }
1162
- async function fetchMerchantId(bearer2) {
1163
- const result = await callMcpTool(JUSPAY_MCP_ENDPOINT, bearer2, "juspay_get_merchant_details", {});
1164
- const merchantId = extractMerchantId(result);
1165
- if (!merchantId) {
1166
- throw new Error("Could not find merchantId in juspay_get_merchant_details response. " + "Report this issue if it persists.");
1167
- }
1168
- return merchantId;
1169
- }
1170
- function extractMerchantId(result) {
1171
- if (!result || typeof result !== "object")
1172
- return;
1173
- const r = result;
1174
- if (typeof r.merchantId === "string")
1175
- return r.merchantId;
1176
- if (r.structuredContent && typeof r.structuredContent === "object") {
1177
- const sc = r.structuredContent;
1178
- if (typeof sc.merchantId === "string")
1179
- return sc.merchantId;
1180
- }
1181
- if (Array.isArray(r.content)) {
1182
- for (const item of r.content) {
1183
- if (item && typeof item === "object") {
1184
- const it = item;
1185
- if (it.type === "text" && typeof it.text === "string") {
1186
- try {
1187
- const parsed = JSON.parse(it.text);
1188
- if (typeof parsed.merchantId === "string")
1189
- return parsed.merchantId;
1190
- } catch {}
1191
- }
1192
- }
1193
- }
1194
- }
1195
- return;
1196
- }
1197
-
1198
- // src/launcher.ts
1199
- import { spawn as spawn2 } from "node:child_process";
1200
- import fs4 from "node:fs/promises";
1201
- import os3 from "node:os";
1202
- import path3 from "node:path";
1203
-
1204
- // node_modules/@clack/core/dist/index.mjs
1205
- var import_sisteransi = __toESM(require_src(), 1);
1206
- import { stdin as j, stdout as M } from "node:process";
1207
- import O from "node:readline";
1208
- import { Writable as X } from "node:stream";
1209
- function DD({ onlyFirst: e = false } = {}) {
1210
- const t = ["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?(?:\\u0007|\\u001B\\u005C|\\u009C))", "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))"].join("|");
1211
- return new RegExp(t, e ? undefined : "g");
1212
- }
1213
- var uD = DD();
1214
- function P(e) {
1215
- if (typeof e != "string")
1216
- throw new TypeError(`Expected a \`string\`, got \`${typeof e}\``);
1217
- return e.replace(uD, "");
1218
- }
1219
- function L(e) {
1220
- return e && e.__esModule && Object.prototype.hasOwnProperty.call(e, "default") ? e.default : e;
1221
- }
1222
- var W = { exports: {} };
1223
- (function(e) {
1224
- var u = {};
1225
- e.exports = u, u.eastAsianWidth = function(F) {
1226
- var s = F.charCodeAt(0), i = F.length == 2 ? F.charCodeAt(1) : 0, D = s;
1227
- 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";
1228
- }, u.characterLength = function(F) {
1229
- var s = this.eastAsianWidth(F);
1230
- return s == "F" || s == "W" || s == "A" ? 2 : 1;
1231
- };
1232
- function t(F) {
1233
- return F.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF]/g) || [];
1234
- }
1235
- u.length = function(F) {
1236
- for (var s = t(F), i = 0, D = 0;D < s.length; D++)
1237
- i = i + this.characterLength(s[D]);
1238
- return i;
1239
- }, u.slice = function(F, s, i) {
1240
- textLen = u.length(F), s = s || 0, i = i || 1, s < 0 && (s = textLen + s), i < 0 && (i = textLen + i);
1241
- for (var D = "", r = 0, n = t(F), E = 0;E < n.length; E++) {
1242
- var a = n[E], o = u.length(a);
1243
- if (r >= s - (o == 2 ? 1 : 0))
1244
- if (r + o <= i)
1245
- D += a;
1246
- else
1247
- break;
1248
- r += o;
1249
- }
1250
- return D;
1251
- };
1252
- })(W);
1253
- var tD = W.exports;
1254
- var eD = L(tD);
1255
- var FD = function() {
1256
- 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;
1257
- };
1258
- var sD = L(FD);
1259
- function p(e, u = {}) {
1260
- if (typeof e != "string" || e.length === 0 || (u = { ambiguousIsNarrow: true, ...u }, e = P(e), e.length === 0))
1261
- return 0;
1262
- e = e.replace(sD(), " ");
1263
- const t = u.ambiguousIsNarrow ? 1 : 2;
1264
- let F = 0;
1265
- for (const s of e) {
1266
- const i = s.codePointAt(0);
1267
- if (i <= 31 || i >= 127 && i <= 159 || i >= 768 && i <= 879)
1268
- continue;
1269
- switch (eD.eastAsianWidth(s)) {
1270
- case "F":
1271
- case "W":
1272
- F += 2;
1273
- break;
1274
- case "A":
1275
- F += t;
1276
- break;
1277
- default:
1278
- F += 1;
1279
- }
1280
- }
1281
- return F;
1282
- }
1283
- var w = 10;
1284
- var N = (e = 0) => (u) => `\x1B[${u + e}m`;
1285
- var I = (e = 0) => (u) => `\x1B[${38 + e};5;${u}m`;
1286
- var R = (e = 0) => (u, t, F) => `\x1B[${38 + e};2;${u};${t};${F}m`;
1287
- var C = { 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] } };
1288
- Object.keys(C.modifier);
1289
- var iD = Object.keys(C.color);
1290
- var rD = Object.keys(C.bgColor);
1291
- [...iD, ...rD];
1292
- function CD() {
1293
- const e = new Map;
1294
- for (const [u, t] of Object.entries(C)) {
1295
- for (const [F, s] of Object.entries(t))
1296
- C[F] = { open: `\x1B[${s[0]}m`, close: `\x1B[${s[1]}m` }, t[F] = C[F], e.set(s[0], s[1]);
1297
- Object.defineProperty(C, u, { value: t, enumerable: false });
1298
- }
1299
- return Object.defineProperty(C, "codes", { value: e, enumerable: false }), C.color.close = "\x1B[39m", C.bgColor.close = "\x1B[49m", C.color.ansi = N(), C.color.ansi256 = I(), C.color.ansi16m = R(), C.bgColor.ansi = N(w), C.bgColor.ansi256 = I(w), C.bgColor.ansi16m = R(w), Object.defineProperties(C, { rgbToAnsi256: { value: (u, t, F) => u === t && t === F ? u < 8 ? 16 : u > 248 ? 231 : Math.round((u - 8) / 247 * 24) + 232 : 16 + 36 * Math.round(u / 255 * 5) + 6 * Math.round(t / 255 * 5) + Math.round(F / 255 * 5), enumerable: false }, hexToRgb: { value: (u) => {
1300
- const t = /[a-f\d]{6}|[a-f\d]{3}/i.exec(u.toString(16));
1301
- if (!t)
1302
- return [0, 0, 0];
1303
- let [F] = t;
1304
- F.length === 3 && (F = [...F].map((i) => i + i).join(""));
1305
- const s = Number.parseInt(F, 16);
1306
- return [s >> 16 & 255, s >> 8 & 255, s & 255];
1307
- }, enumerable: false }, hexToAnsi256: { value: (u) => C.rgbToAnsi256(...C.hexToRgb(u)), enumerable: false }, ansi256ToAnsi: { value: (u) => {
1308
- if (u < 8)
1309
- return 30 + u;
1310
- if (u < 16)
1311
- return 90 + (u - 8);
1312
- let t, F, s;
1313
- if (u >= 232)
1314
- t = ((u - 232) * 10 + 8) / 255, F = t, s = t;
1315
- else {
1316
- u -= 16;
1317
- const r = u % 36;
1318
- t = Math.floor(u / 36) / 5, F = Math.floor(r / 6) / 5, s = r % 6 / 5;
1319
- }
1320
- const i = Math.max(t, F, s) * 2;
1321
- if (i === 0)
1322
- return 30;
1323
- let D = 30 + (Math.round(s) << 2 | Math.round(F) << 1 | Math.round(t));
1324
- return i === 2 && (D += 60), D;
1325
- }, enumerable: false }, rgbToAnsi: { value: (u, t, F) => C.ansi256ToAnsi(C.rgbToAnsi256(u, t, F)), enumerable: false }, hexToAnsi: { value: (u) => C.ansi256ToAnsi(C.hexToAnsi256(u)), enumerable: false } }), C;
1326
- }
1327
- var ED = CD();
1328
- var d = new Set(["\x1B", "›"]);
1329
- var oD = 39;
1330
- var y = "\x07";
1331
- var V = "[";
1332
- var nD = "]";
1333
- var G = "m";
1334
- var _ = `${nD}8;;`;
1335
- var z = (e) => `${d.values().next().value}${V}${e}${G}`;
1336
- var K = (e) => `${d.values().next().value}${_}${e}${y}`;
1337
- var aD = (e) => e.split(" ").map((u) => p(u));
1338
- var k = (e, u, t) => {
1339
- const F = [...u];
1340
- let s = false, i = false, D = p(P(e[e.length - 1]));
1341
- for (const [r, n] of F.entries()) {
1342
- const E = p(n);
1343
- if (D + E <= t ? e[e.length - 1] += n : (e.push(n), D = 0), d.has(n) && (s = true, i = F.slice(r + 1).join("").startsWith(_)), s) {
1344
- i ? n === y && (s = false, i = false) : n === G && (s = false);
1345
- continue;
1346
- }
1347
- D += E, D === t && r < F.length - 1 && (e.push(""), D = 0);
1348
- }
1349
- !D && e[e.length - 1].length > 0 && e.length > 1 && (e[e.length - 2] += e.pop());
1350
- };
1351
- var hD = (e) => {
1352
- const u = e.split(" ");
1353
- let t = u.length;
1354
- for (;t > 0 && !(p(u[t - 1]) > 0); )
1355
- t--;
1356
- return t === u.length ? e : u.slice(0, t).join(" ") + u.slice(t).join("");
1357
- };
1358
- var lD = (e, u, t = {}) => {
1359
- if (t.trim !== false && e.trim() === "")
1360
- return "";
1361
- let F = "", s, i;
1362
- const D = aD(e);
1363
- let r = [""];
1364
- for (const [E, a] of e.split(" ").entries()) {
1365
- t.trim !== false && (r[r.length - 1] = r[r.length - 1].trimStart());
1366
- let o = p(r[r.length - 1]);
1367
- if (E !== 0 && (o >= u && (t.wordWrap === false || t.trim === false) && (r.push(""), o = 0), (o > 0 || t.trim === false) && (r[r.length - 1] += " ", o++)), t.hard && D[E] > u) {
1368
- const c = u - o, f = 1 + Math.floor((D[E] - c - 1) / u);
1369
- Math.floor((D[E] - 1) / u) < f && r.push(""), k(r, a, u);
1370
- continue;
1371
- }
1372
- if (o + D[E] > u && o > 0 && D[E] > 0) {
1373
- if (t.wordWrap === false && o < u) {
1374
- k(r, a, u);
1375
- continue;
1376
- }
1377
- r.push("");
1378
- }
1379
- if (o + D[E] > u && t.wordWrap === false) {
1380
- k(r, a, u);
1381
- continue;
1382
- }
1383
- r[r.length - 1] += a;
1384
- }
1385
- t.trim !== false && (r = r.map((E) => hD(E)));
1386
- const n = [...r.join(`
1387
- `)];
1388
- for (const [E, a] of n.entries()) {
1389
- if (F += a, d.has(a)) {
1390
- const { groups: c } = new RegExp(`(?:\\${V}(?<code>\\d+)m|\\${_}(?<uri>.*)${y})`).exec(n.slice(E).join("")) || { groups: {} };
1391
- if (c.code !== undefined) {
1392
- const f = Number.parseFloat(c.code);
1393
- s = f === oD ? undefined : f;
1394
- } else
1395
- c.uri !== undefined && (i = c.uri.length === 0 ? undefined : c.uri);
1396
- }
1397
- const o = ED.codes.get(Number(s));
1398
- n[E + 1] === `
1399
- ` ? (i && (F += K("")), s && o && (F += z(o))) : a === `
1400
- ` && (s && o && (F += z(s)), i && (F += K(i)));
1401
- }
1402
- return F;
1403
- };
1404
- function Y(e, u, t) {
1405
- return String(e).normalize().replace(/\r\n/g, `
1406
- `).split(`
1407
- `).map((F) => lD(F, u, t)).join(`
1408
- `);
1409
- }
1410
- var xD = ["up", "down", "left", "right", "space", "enter", "cancel"];
1411
- var B = { actions: new Set(xD), aliases: new Map([["k", "up"], ["j", "down"], ["h", "left"], ["l", "right"], ["\x03", "cancel"], ["escape", "cancel"]]) };
1412
- function $(e, u) {
1413
- if (typeof e == "string")
1414
- return B.aliases.get(e) === u;
1415
- for (const t of e)
1416
- if (t !== undefined && $(t, u))
1417
- return true;
1418
- return false;
1419
- }
1420
- function BD(e, u) {
1421
- if (e === u)
1422
- return;
1423
- const t = e.split(`
1424
- `), F = u.split(`
1425
- `), s = [];
1426
- for (let i = 0;i < Math.max(t.length, F.length); i++)
1427
- t[i] !== F[i] && s.push(i);
1428
- return s;
1429
- }
1430
- var AD = globalThis.process.platform.startsWith("win");
1431
- var S = Symbol("clack:cancel");
1432
- function pD(e) {
1433
- return e === S;
1434
- }
1435
- function m(e, u) {
1436
- const t = e;
1437
- t.isTTY && t.setRawMode(u);
1438
- }
1439
- var gD = Object.defineProperty;
1440
- var vD = (e, u, t) => (u in e) ? gD(e, u, { enumerable: true, configurable: true, writable: true, value: t }) : e[u] = t;
1441
- var h = (e, u, t) => (vD(e, typeof u != "symbol" ? u + "" : u, t), t);
1442
-
1443
- class x {
1444
- constructor(u, t = true) {
1445
- 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");
1446
- const { input: F = j, output: s = M, render: i, signal: D, ...r } = u;
1447
- this.opts = r, this.onKeypress = this.onKeypress.bind(this), this.close = this.close.bind(this), this.render = this.render.bind(this), this._render = i.bind(this), this._track = t, this._abortSignal = D, this.input = F, this.output = s;
1448
- }
1449
- unsubscribe() {
1450
- this._subscribers.clear();
1451
- }
1452
- setSubscriber(u, t) {
1453
- const F = this._subscribers.get(u) ?? [];
1454
- F.push(t), this._subscribers.set(u, F);
1455
- }
1456
- on(u, t) {
1457
- this.setSubscriber(u, { cb: t });
1458
- }
1459
- once(u, t) {
1460
- this.setSubscriber(u, { cb: t, once: true });
1461
- }
1462
- emit(u, ...t) {
1463
- const F = this._subscribers.get(u) ?? [], s = [];
1464
- for (const i of F)
1465
- i.cb(...t), i.once && s.push(() => F.splice(F.indexOf(i), 1));
1466
- for (const i of s)
1467
- i();
1468
- }
1469
- prompt() {
1470
- return new Promise((u, t) => {
1471
- if (this._abortSignal) {
1472
- if (this._abortSignal.aborted)
1473
- return this.state = "cancel", this.close(), u(S);
1474
- this._abortSignal.addEventListener("abort", () => {
1475
- this.state = "cancel", this.close();
1476
- }, { once: true });
1477
- }
1478
- const F = new X;
1479
- F._write = (s, i, D) => {
1480
- this._track && (this.value = this.rl?.line.replace(/\t/g, ""), this._cursor = this.rl?.cursor ?? 0, this.emit("value", this.value)), D();
1481
- }, this.input.pipe(F), this.rl = O.createInterface({ input: this.input, output: F, tabSize: 2, prompt: "", escapeCodeTimeout: 50, terminal: true }), O.emitKeypressEvents(this.input, this.rl), this.rl.prompt(), this.opts.initialValue !== undefined && this._track && this.rl.write(this.opts.initialValue), this.input.on("keypress", this.onKeypress), m(this.input, true), this.output.on("resize", this.render), this.render(), this.once("submit", () => {
1482
- this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), m(this.input, false), u(this.value);
1483
- }), this.once("cancel", () => {
1484
- this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), m(this.input, false), u(S);
1485
- });
1486
- });
1487
- }
1488
- onKeypress(u, t) {
1489
- if (this.state === "error" && (this.state = "active"), t?.name && (!this._track && B.aliases.has(t.name) && this.emit("cursor", B.aliases.get(t.name)), B.actions.has(t.name) && this.emit("cursor", t.name)), u && (u.toLowerCase() === "y" || u.toLowerCase() === "n") && this.emit("confirm", u.toLowerCase() === "y"), u === "\t" && this.opts.placeholder && (this.value || (this.rl?.write(this.opts.placeholder), this.emit("value", this.opts.placeholder))), u && this.emit("key", u.toLowerCase()), t?.name === "return") {
1490
- if (!this.value && this.opts.placeholder && (this.rl?.write(this.opts.placeholder), this.emit("value", this.opts.placeholder)), this.opts.validate) {
1491
- const F = this.opts.validate(this.value);
1492
- F && (this.error = F instanceof Error ? F.message : F, this.state = "error", this.rl?.write(this.value));
1493
- }
1494
- this.state !== "error" && (this.state = "submit");
1495
- }
1496
- $([u, t?.name, t?.sequence], "cancel") && (this.state = "cancel"), (this.state === "submit" || this.state === "cancel") && this.emit("finalize"), this.render(), (this.state === "submit" || this.state === "cancel") && this.close();
1497
- }
1498
- close() {
1499
- this.input.unpipe(), this.input.removeListener("keypress", this.onKeypress), this.output.write(`
1500
- `), m(this.input, false), this.rl?.close(), this.rl = undefined, this.emit(`${this.state}`, this.value), this.unsubscribe();
1501
- }
1502
- restoreCursor() {
1503
- const u = Y(this._prevFrame, process.stdout.columns, { hard: true }).split(`
1504
- `).length - 1;
1505
- this.output.write(import_sisteransi.cursor.move(-999, u * -1));
1506
- }
1507
- render() {
1508
- const u = Y(this._render(this) ?? "", process.stdout.columns, { hard: true });
1509
- if (u !== this._prevFrame) {
1510
- if (this.state === "initial")
1511
- this.output.write(import_sisteransi.cursor.hide);
1512
- else {
1513
- const t = BD(this._prevFrame, u);
1514
- if (this.restoreCursor(), t && t?.length === 1) {
1515
- const F = t[0];
1516
- this.output.write(import_sisteransi.cursor.move(0, F)), this.output.write(import_sisteransi.erase.lines(1));
1517
- const s = u.split(`
1518
- `);
1519
- this.output.write(s[F]), this._prevFrame = u, this.output.write(import_sisteransi.cursor.move(0, s.length - F - 1));
1520
- return;
1521
- }
1522
- if (t && t?.length > 1) {
1523
- const F = t[0];
1524
- this.output.write(import_sisteransi.cursor.move(0, F)), this.output.write(import_sisteransi.erase.down());
1525
- const s = u.split(`
1526
- `).slice(F);
1527
- this.output.write(s.join(`
1528
- `)), this._prevFrame = u;
1529
- return;
1530
- }
1531
- this.output.write(import_sisteransi.erase.down());
1532
- }
1533
- this.output.write(u), this.state === "initial" && (this.state = "active"), this._prevFrame = u;
1534
- }
1535
- }
1536
- }
1537
-
1538
- class dD extends x {
1539
- get cursor() {
1540
- return this.value ? 0 : 1;
1541
- }
1542
- get _value() {
1543
- return this.cursor === 0;
1544
- }
1545
- constructor(u) {
1546
- super(u, false), this.value = !!u.initialValue, this.on("value", () => {
1547
- this.value = this._value;
1548
- }), this.on("confirm", (t) => {
1549
- this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = t, this.state = "submit", this.close();
1550
- }), this.on("cursor", () => {
1551
- this.value = !this.value;
1552
- });
1553
- }
1554
- }
1555
- var A;
1556
- A = new WeakMap;
1557
-
1558
- // node_modules/@clack/prompts/dist/index.mjs
1559
- var import_picocolors3 = __toESM(require_picocolors(), 1);
1560
- var import_sisteransi2 = __toESM(require_src(), 1);
1561
- import y2 from "node:process";
1562
- function ce() {
1563
- return y2.platform !== "win32" ? y2.env.TERM !== "linux" : !!y2.env.CI || !!y2.env.WT_SESSION || !!y2.env.TERMINUS_SUBLIME || y2.env.ConEmuTask === "{cmd::Cmder}" || y2.env.TERM_PROGRAM === "Terminus-Sublime" || y2.env.TERM_PROGRAM === "vscode" || y2.env.TERM === "xterm-256color" || y2.env.TERM === "alacritty" || y2.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
1564
- }
1565
- var V2 = ce();
1566
- var u = (t, n) => V2 ? t : n;
1567
- var le = u("◆", "*");
1568
- var L2 = u("■", "x");
1569
- var W2 = u("▲", "x");
1570
- var C2 = u("◇", "o");
1571
- var ue = u("┌", "T");
1572
- var o = u("│", "|");
1573
- var d2 = u("└", "—");
1574
- var k2 = u("●", ">");
1575
- var P2 = u("○", " ");
1576
- var A2 = u("◻", "[•]");
1577
- var T = u("◼", "[+]");
1578
- var F = u("◻", "[ ]");
1579
- var $e = u("▪", "•");
1580
- var _2 = u("─", "-");
1581
- var me = u("╮", "+");
1582
- var de = u("├", "+");
1583
- var pe = u("╯", "+");
1584
- var q = u("●", "•");
1585
- var D = u("◆", "*");
1586
- var U = u("▲", "!");
1587
- var K2 = u("■", "x");
1588
- var b2 = (t) => {
1589
- switch (t) {
1590
- case "initial":
1591
- case "active":
1592
- return import_picocolors3.default.cyan(le);
1593
- case "cancel":
1594
- return import_picocolors3.default.red(L2);
1595
- case "error":
1596
- return import_picocolors3.default.yellow(W2);
1597
- case "submit":
1598
- return import_picocolors3.default.green(C2);
1599
- }
1600
- };
1601
- var ye = (t) => {
1602
- const n = t.active ?? "Yes", r = t.inactive ?? "No";
1603
- return new dD({ active: n, inactive: r, initialValue: t.initialValue ?? true, render() {
1604
- const i = `${import_picocolors3.default.gray(o)}
1605
- ${b2(this.state)} ${t.message}
1606
- `, s = this.value ? n : r;
1607
- switch (this.state) {
1608
- case "submit":
1609
- return `${i}${import_picocolors3.default.gray(o)} ${import_picocolors3.default.dim(s)}`;
1610
- case "cancel":
1611
- return `${i}${import_picocolors3.default.gray(o)} ${import_picocolors3.default.strikethrough(import_picocolors3.default.dim(s))}
1612
- ${import_picocolors3.default.gray(o)}`;
1613
- default:
1614
- return `${i}${import_picocolors3.default.cyan(o)} ${this.value ? `${import_picocolors3.default.green(k2)} ${n}` : `${import_picocolors3.default.dim(P2)} ${import_picocolors3.default.dim(n)}`} ${import_picocolors3.default.dim("/")} ${this.value ? `${import_picocolors3.default.dim(P2)} ${import_picocolors3.default.dim(r)}` : `${import_picocolors3.default.green(k2)} ${r}`}
1615
- ${import_picocolors3.default.cyan(d2)}
1616
- `;
1617
- }
1618
- } }).prompt();
1619
- };
1620
- var J = `${import_picocolors3.default.gray(o)} `;
1621
-
1622
- // src/launcher.ts
1623
- async function ensureAgentBin(agent) {
1624
- const found = await findBin(agent);
1625
- if (found)
1626
- return found;
1627
- if (!agent.installCmd)
1628
- return null;
1629
- const ok = await ye({
1630
- message: `${agent.label} isn't installed. Install it with \`${agent.installCmd.join(" ")}\`?`,
1631
- initialValue: true
1632
- });
1633
- if (pD(ok) || !ok) {
1634
- info(`Skipping. Install it yourself with: ${agent.installCmd.join(" ")}`);
1635
- return null;
1636
- }
1637
- await runInstall(agent.installCmd);
1638
- return findBin(agent);
1639
- }
1640
- function launchAgent(bin, args, token) {
1641
- const child = spawn2(bin, args, {
1642
- stdio: "inherit",
1643
- env: { ...process.env, [MCP_TOKEN_VAR]: token }
1644
- });
1645
- child.on("exit", (code) => process.exit(code ?? 0));
1646
- }
1647
- async function prepareAgentLaunch(agent) {
1648
- if (agent.id === "claude")
1649
- await clearClaudeNeedsAuthCache();
1650
- }
1651
- async function clearClaudeNeedsAuthCache() {
1652
- const file = path3.join(os3.homedir(), ".claude", "mcp-needs-auth-cache.json");
1653
- let cache;
1654
- try {
1655
- cache = JSON.parse(await fs4.readFile(file, "utf8"));
1656
- } catch {
1657
- return;
1658
- }
1659
- let changed = false;
1660
- for (const name of OUR_MCP_NAMES) {
1661
- if (Object.prototype.hasOwnProperty.call(cache, name)) {
1662
- delete cache[name];
1663
- changed = true;
1664
- }
1665
- }
1666
- if (!changed)
1667
- return;
1668
- await fs4.writeFile(file, JSON.stringify(cache, null, 2) + `
1669
- `, { mode: 384 });
1670
- }
1671
- function runInstall(cmd) {
1672
- return new Promise((resolve, reject) => {
1673
- const [bin, ...args] = cmd;
1674
- const child = spawn2(bin, args, { stdio: "inherit" });
1675
- child.on("error", reject);
1676
- child.on("exit", (code) => code === 0 ? resolve() : reject(new Error(`\`${cmd.join(" ")}\` exited ${code}`)));
1677
- });
1678
- }
1679
-
1680
- // src/mcp-writer.ts
1681
- import fs5 from "node:fs/promises";
1682
- import path4 from "node:path";
1683
-
1684
- // node_modules/smol-toml/dist/error.js
1685
- /*!
1686
- * Copyright (c) Squirrel Chat et al., All rights reserved.
1687
- * SPDX-License-Identifier: BSD-3-Clause
1688
- *
1689
- * Redistribution and use in source and binary forms, with or without
1690
- * modification, are permitted provided that the following conditions are met:
1691
- *
1692
- * 1. Redistributions of source code must retain the above copyright notice, this
1693
- * list of conditions and the following disclaimer.
1694
- * 2. Redistributions in binary form must reproduce the above copyright notice,
1695
- * this list of conditions and the following disclaimer in the
1696
- * documentation and/or other materials provided with the distribution.
1697
- * 3. Neither the name of the copyright holder nor the names of its contributors
1698
- * may be used to endorse or promote products derived from this software without
1699
- * specific prior written permission.
1700
- *
1701
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1702
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1703
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1704
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
1705
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1706
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
1707
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
1708
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
1709
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1710
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1711
- */
1712
- function getLineColFromPtr(string, ptr) {
1713
- let lines = string.slice(0, ptr).split(/\r\n|\n|\r/g);
1714
- return [lines.length, lines.pop().length + 1];
1715
- }
1716
- function makeCodeBlock(string, line, column) {
1717
- let lines = string.split(/\r\n|\n|\r/g);
1718
- let codeblock = "";
1719
- let numberLen = (Math.log10(line + 1) | 0) + 1;
1720
- for (let i = line - 1;i <= line + 1; i++) {
1721
- let l2 = lines[i - 1];
1722
- if (!l2)
1723
- continue;
1724
- codeblock += i.toString().padEnd(numberLen, " ");
1725
- codeblock += ": ";
1726
- codeblock += l2;
1727
- codeblock += `
1728
- `;
1729
- if (i === line) {
1730
- codeblock += " ".repeat(numberLen + column + 2);
1731
- codeblock += `^
1732
- `;
1733
- }
1734
- }
1735
- return codeblock;
1736
- }
1737
-
1738
- class TomlError extends Error {
1739
- line;
1740
- column;
1741
- codeblock;
1742
- constructor(message, options) {
1743
- const [line, column] = getLineColFromPtr(options.toml, options.ptr);
1744
- const codeblock = makeCodeBlock(options.toml, line, column);
1745
- super(`Invalid TOML document: ${message}
1746
-
1747
- ${codeblock}`, options);
1748
- this.line = line;
1749
- this.column = column;
1750
- this.codeblock = codeblock;
1751
- }
1752
- }
1753
-
1754
- // node_modules/smol-toml/dist/util.js
1755
- /*!
1756
- * Copyright (c) Squirrel Chat et al., All rights reserved.
1757
- * SPDX-License-Identifier: BSD-3-Clause
1758
- *
1759
- * Redistribution and use in source and binary forms, with or without
1760
- * modification, are permitted provided that the following conditions are met:
1761
- *
1762
- * 1. Redistributions of source code must retain the above copyright notice, this
1763
- * list of conditions and the following disclaimer.
1764
- * 2. Redistributions in binary form must reproduce the above copyright notice,
1765
- * this list of conditions and the following disclaimer in the
1766
- * documentation and/or other materials provided with the distribution.
1767
- * 3. Neither the name of the copyright holder nor the names of its contributors
1768
- * may be used to endorse or promote products derived from this software without
1769
- * specific prior written permission.
1770
- *
1771
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1772
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1773
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1774
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
1775
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1776
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
1777
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
1778
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
1779
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1780
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1781
- */
1782
- function isEscaped(str, ptr) {
1783
- let i = 0;
1784
- while (str[ptr - ++i] === "\\")
1785
- ;
1786
- return --i && i % 2;
1787
- }
1788
- function indexOfNewline(str, start = 0, end = str.length) {
1789
- let idx = str.indexOf(`
1790
- `, start);
1791
- if (str[idx - 1] === "\r")
1792
- idx--;
1793
- return idx <= end ? idx : -1;
1794
- }
1795
- function skipComment(str, ptr) {
1796
- for (let i = ptr;i < str.length; i++) {
1797
- let c = str[i];
1798
- if (c === `
1799
- `)
1800
- return i;
1801
- if (c === "\r" && str[i + 1] === `
1802
- `)
1803
- return i + 1;
1804
- if (c < " " && c !== "\t" || c === "") {
1805
- throw new TomlError("control characters are not allowed in comments", {
1806
- toml: str,
1807
- ptr
1808
- });
1809
- }
1810
- }
1811
- return str.length;
1812
- }
1813
- function skipVoid(str, ptr, banNewLines, banComments) {
1814
- let c;
1815
- while (true) {
1816
- while ((c = str[ptr]) === " " || c === "\t" || !banNewLines && (c === `
1817
- ` || c === "\r" && str[ptr + 1] === `
1818
- `))
1819
- ptr++;
1820
- if (banComments || c !== "#")
1821
- break;
1822
- ptr = skipComment(str, ptr);
1823
- }
1824
- return ptr;
1825
- }
1826
- function skipUntil(str, ptr, sep, end, banNewLines = false) {
1827
- if (!end) {
1828
- ptr = indexOfNewline(str, ptr);
1829
- return ptr < 0 ? str.length : ptr;
1830
- }
1831
- for (let i = ptr;i < str.length; i++) {
1832
- let c = str[i];
1833
- if (c === "#") {
1834
- i = indexOfNewline(str, i);
1835
- } else if (c === sep) {
1836
- return i + 1;
1837
- } else if (c === end || banNewLines && (c === `
1838
- ` || c === "\r" && str[i + 1] === `
1839
- `)) {
1840
- return i;
1841
- }
1842
- }
1843
- throw new TomlError("cannot find end of structure", {
1844
- toml: str,
1845
- ptr
1846
- });
1847
- }
1848
- function getStringEnd(str, seek) {
1849
- let first = str[seek];
1850
- let target = first === str[seek + 1] && str[seek + 1] === str[seek + 2] ? str.slice(seek, seek + 3) : first;
1851
- seek += target.length - 1;
1852
- do
1853
- seek = str.indexOf(target, ++seek);
1854
- while (seek > -1 && first !== "'" && isEscaped(str, seek));
1855
- if (seek > -1) {
1856
- seek += target.length;
1857
- if (target.length > 1) {
1858
- if (str[seek] === first)
1859
- seek++;
1860
- if (str[seek] === first)
1861
- seek++;
1862
- }
1863
- }
1864
- return seek;
657
+ return seek;
1865
658
  }
1866
659
 
1867
660
  // node_modules/smol-toml/dist/date.js
@@ -2362,22 +1155,22 @@ function parseInlineTable(str, ptr, depth, integersAsBigInt) {
2362
1155
  ptr = skipComment(str, ptr);
2363
1156
  else if (c !== " " && c !== "\t" && c !== `
2364
1157
  ` && c !== "\r") {
2365
- let k3;
1158
+ let k;
2366
1159
  let t = res;
2367
1160
  let hasOwn = false;
2368
1161
  let [key, keyEndPtr] = parseKey(str, ptr - 1);
2369
1162
  for (let i = 0;i < key.length; i++) {
2370
1163
  if (i)
2371
- t = hasOwn ? t[k3] : t[k3] = {};
2372
- k3 = key[i];
2373
- if ((hasOwn = Object.hasOwn(t, k3)) && (typeof t[k3] !== "object" || seen.has(t[k3]))) {
1164
+ t = hasOwn ? t[k] : t[k] = {};
1165
+ k = key[i];
1166
+ if ((hasOwn = Object.hasOwn(t, k)) && (typeof t[k] !== "object" || seen.has(t[k]))) {
2374
1167
  throw new TomlError("trying to redefine an already defined value", {
2375
1168
  toml: str,
2376
1169
  ptr
2377
1170
  });
2378
1171
  }
2379
- if (!hasOwn && k3 === "__proto__") {
2380
- Object.defineProperty(t, k3, { enumerable: true, configurable: true, writable: true });
1172
+ if (!hasOwn && k === "__proto__") {
1173
+ Object.defineProperty(t, k, { enumerable: true, configurable: true, writable: true });
2381
1174
  }
2382
1175
  }
2383
1176
  if (hasOwn) {
@@ -2388,7 +1181,7 @@ function parseInlineTable(str, ptr, depth, integersAsBigInt) {
2388
1181
  }
2389
1182
  let [value, valueEndPtr] = extractValue(str, keyEndPtr, "}", depth - 1, integersAsBigInt);
2390
1183
  seen.add(value);
2391
- t[k3] = value;
1184
+ t[k] = value;
2392
1185
  ptr = valueEndPtr;
2393
1186
  }
2394
1187
  }
@@ -2414,9 +1207,9 @@ function parseArray(str, ptr, depth, integersAsBigInt) {
2414
1207
  ptr = skipComment(str, ptr);
2415
1208
  else if (c !== " " && c !== "\t" && c !== `
2416
1209
  ` && c !== "\r") {
2417
- let e2 = extractValue(str, ptr - 1, "]", depth - 1, integersAsBigInt);
2418
- res.push(e2[0]);
2419
- ptr = e2[1];
1210
+ let e = extractValue(str, ptr - 1, "]", depth - 1, integersAsBigInt);
1211
+ res.push(e[0]);
1212
+ ptr = e[1];
2420
1213
  }
2421
1214
  }
2422
1215
  if (!c) {
@@ -2458,33 +1251,33 @@ function parseArray(str, ptr, depth, integersAsBigInt) {
2458
1251
  */
2459
1252
  function peekTable(key, table, meta, type) {
2460
1253
  let t = table;
2461
- let m2 = meta;
2462
- let k3;
1254
+ let m = meta;
1255
+ let k;
2463
1256
  let hasOwn = false;
2464
1257
  let state;
2465
1258
  for (let i = 0;i < key.length; i++) {
2466
1259
  if (i) {
2467
- t = hasOwn ? t[k3] : t[k3] = {};
2468
- m2 = (state = m2[k3]).c;
1260
+ t = hasOwn ? t[k] : t[k] = {};
1261
+ m = (state = m[k]).c;
2469
1262
  if (type === 0 && (state.t === 1 || state.t === 2)) {
2470
1263
  return null;
2471
1264
  }
2472
1265
  if (state.t === 2) {
2473
- let l2 = t.length - 1;
2474
- t = t[l2];
2475
- m2 = m2[l2].c;
1266
+ let l = t.length - 1;
1267
+ t = t[l];
1268
+ m = m[l].c;
2476
1269
  }
2477
1270
  }
2478
- k3 = key[i];
2479
- if ((hasOwn = Object.hasOwn(t, k3)) && m2[k3]?.t === 0 && m2[k3]?.d) {
1271
+ k = key[i];
1272
+ if ((hasOwn = Object.hasOwn(t, k)) && m[k]?.t === 0 && m[k]?.d) {
2480
1273
  return null;
2481
1274
  }
2482
1275
  if (!hasOwn) {
2483
- if (k3 === "__proto__") {
2484
- Object.defineProperty(t, k3, { enumerable: true, configurable: true, writable: true });
2485
- Object.defineProperty(m2, k3, { enumerable: true, configurable: true, writable: true });
1276
+ if (k === "__proto__") {
1277
+ Object.defineProperty(t, k, { enumerable: true, configurable: true, writable: true });
1278
+ Object.defineProperty(m, k, { enumerable: true, configurable: true, writable: true });
2486
1279
  }
2487
- m2[k3] = {
1280
+ m[k] = {
2488
1281
  t: i < key.length - 1 && type === 2 ? 3 : type,
2489
1282
  d: false,
2490
1283
  i: 0,
@@ -2492,16 +1285,16 @@ function peekTable(key, table, meta, type) {
2492
1285
  };
2493
1286
  }
2494
1287
  }
2495
- state = m2[k3];
1288
+ state = m[k];
2496
1289
  if (state.t !== type && !(type === 1 && state.t === 3)) {
2497
1290
  return null;
2498
1291
  }
2499
1292
  if (type === 2) {
2500
1293
  if (!state.d) {
2501
1294
  state.d = true;
2502
- t[k3] = [];
1295
+ t[k] = [];
2503
1296
  }
2504
- t[k3].push(t = {});
1297
+ t[k].push(t = {});
2505
1298
  state.c[state.i++] = state = { t: 1, d: false, i: 0, c: {} };
2506
1299
  }
2507
1300
  if (state.d) {
@@ -2509,51 +1302,51 @@ function peekTable(key, table, meta, type) {
2509
1302
  }
2510
1303
  state.d = true;
2511
1304
  if (type === 1) {
2512
- t = hasOwn ? t[k3] : t[k3] = {};
1305
+ t = hasOwn ? t[k] : t[k] = {};
2513
1306
  } else if (type === 0 && hasOwn) {
2514
1307
  return null;
2515
1308
  }
2516
- return [k3, t, state.c];
1309
+ return [k, t, state.c];
2517
1310
  }
2518
1311
  function parse(toml, { maxDepth = 1000, integersAsBigInt } = {}) {
2519
1312
  let res = {};
2520
1313
  let meta = {};
2521
1314
  let tbl = res;
2522
- let m2 = meta;
1315
+ let m = meta;
2523
1316
  for (let ptr = skipVoid(toml, 0);ptr < toml.length; ) {
2524
1317
  if (toml[ptr] === "[") {
2525
1318
  let isTableArray = toml[++ptr] === "[";
2526
- let k3 = parseKey(toml, ptr += +isTableArray, "]");
1319
+ let k = parseKey(toml, ptr += +isTableArray, "]");
2527
1320
  if (isTableArray) {
2528
- if (toml[k3[1] - 1] !== "]") {
1321
+ if (toml[k[1] - 1] !== "]") {
2529
1322
  throw new TomlError("expected end of table declaration", {
2530
1323
  toml,
2531
- ptr: k3[1] - 1
1324
+ ptr: k[1] - 1
2532
1325
  });
2533
1326
  }
2534
- k3[1]++;
1327
+ k[1]++;
2535
1328
  }
2536
- let p2 = peekTable(k3[0], res, meta, isTableArray ? 2 : 1);
2537
- if (!p2) {
1329
+ let p = peekTable(k[0], res, meta, isTableArray ? 2 : 1);
1330
+ if (!p) {
2538
1331
  throw new TomlError("trying to redefine an already defined table or value", {
2539
1332
  toml,
2540
1333
  ptr
2541
1334
  });
2542
1335
  }
2543
- m2 = p2[2];
2544
- tbl = p2[1];
2545
- ptr = k3[1];
1336
+ m = p[2];
1337
+ tbl = p[1];
1338
+ ptr = k[1];
2546
1339
  } else {
2547
- let k3 = parseKey(toml, ptr);
2548
- let p2 = peekTable(k3[0], tbl, m2, 0);
2549
- if (!p2) {
1340
+ let k = parseKey(toml, ptr);
1341
+ let p = peekTable(k[0], tbl, m, 0);
1342
+ if (!p) {
2550
1343
  throw new TomlError("trying to redefine an already defined table or value", {
2551
1344
  toml,
2552
1345
  ptr
2553
1346
  });
2554
1347
  }
2555
- let v = extractValue(toml, k3[1], undefined, maxDepth, integersAsBigInt);
2556
- p2[1][p2[0]] = v[0];
1348
+ let v = extractValue(toml, k[1], undefined, maxDepth, integersAsBigInt);
1349
+ p[1][p[0]] = v[0];
2557
1350
  ptr = v[1];
2558
1351
  }
2559
1352
  ptr = skipVoid(toml, ptr, true);
@@ -2658,12 +1451,12 @@ function stringifyInlineTable(obj, depth, numberAsFloat) {
2658
1451
  return "{}";
2659
1452
  let res = "{ ";
2660
1453
  for (let i = 0;i < keys.length; i++) {
2661
- let k3 = keys[i];
1454
+ let k = keys[i];
2662
1455
  if (i)
2663
1456
  res += ", ";
2664
- res += BARE_KEY.test(k3) ? k3 : formatString(k3);
1457
+ res += BARE_KEY.test(k) ? k : formatString(k);
2665
1458
  res += " = ";
2666
- res += stringifyValue(obj[k3], extendedTypeOf(obj[k3]), depth - 1, numberAsFloat);
1459
+ res += stringifyValue(obj[k], extendedTypeOf(obj[k]), depth - 1, numberAsFloat);
2667
1460
  }
2668
1461
  return res + " }";
2669
1462
  }
@@ -2702,24 +1495,24 @@ function stringifyTable(tableKey, obj, prefix, depth, numberAsFloat) {
2702
1495
  let tables = "";
2703
1496
  let keys = Object.keys(obj);
2704
1497
  for (let i = 0;i < keys.length; i++) {
2705
- let k3 = keys[i];
2706
- if (obj[k3] !== null && obj[k3] !== undefined) {
2707
- let type = extendedTypeOf(obj[k3]);
1498
+ let k = keys[i];
1499
+ if (obj[k] !== null && obj[k] !== undefined) {
1500
+ let type = extendedTypeOf(obj[k]);
2708
1501
  if (type === "symbol" || type === "function") {
2709
1502
  throw new TypeError(`cannot serialize values of type '${type}'`);
2710
1503
  }
2711
- let key = BARE_KEY.test(k3) ? k3 : formatString(k3);
2712
- if (type === "array" && isArrayOfTables(obj[k3])) {
1504
+ let key = BARE_KEY.test(k) ? k : formatString(k);
1505
+ if (type === "array" && isArrayOfTables(obj[k])) {
2713
1506
  tables += (tables && `
2714
- `) + stringifyArrayTable(obj[k3], prefix ? `${prefix}.${key}` : key, depth - 1, numberAsFloat);
1507
+ `) + stringifyArrayTable(obj[k], prefix ? `${prefix}.${key}` : key, depth - 1, numberAsFloat);
2715
1508
  } else if (type === "object") {
2716
1509
  let tblKey = prefix ? `${prefix}.${key}` : key;
2717
1510
  tables += (tables && `
2718
- `) + stringifyTable(tblKey, obj[k3], tblKey, depth - 1, numberAsFloat);
1511
+ `) + stringifyTable(tblKey, obj[k], tblKey, depth - 1, numberAsFloat);
2719
1512
  } else {
2720
1513
  preamble += key;
2721
1514
  preamble += " = ";
2722
- preamble += stringifyValue(obj[k3], type, depth, numberAsFloat);
1515
+ preamble += stringifyValue(obj[k], type, depth, numberAsFloat);
2723
1516
  preamble += `
2724
1517
  `;
2725
1518
  }
@@ -2772,36 +1565,37 @@ function stringify(obj, { maxDepth = 1000, numbersAsFloat = false } = {}) {
2772
1565
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2773
1566
  */
2774
1567
 
1568
+ // src/servers.ts
1569
+ var JUSPAY_MCP_ENDPOINT = "https://mcp.juspay.in/dashboard/juspay-dashboard-stream";
1570
+ var DOCS_MCP_ENDPOINT = "https://mcp.juspay.in/dashboard/juspay-docs-stream";
1571
+ var DOCS_MCP_NAME = "docs-mcp-server";
1572
+ var DASHBOARD_MCP_NAME = "juspay-mcp";
1573
+ var OUR_MCP_NAMES = [DOCS_MCP_NAME, DASHBOARD_MCP_NAME];
1574
+ var SKILLS_PACKAGE = "sahyll/juspay-skills/skills/integrate";
1575
+ var PACKAGE_NAME = "@sahyll/ai";
1576
+ var CLI_VERSION = "0.5.0";
1577
+ var USER_AGENT = `juspay-ai-cli/${CLI_VERSION} (+https://juspay.in)`;
1578
+
2775
1579
  // src/mcp-writer.ts
2776
- var TOKEN_RE = /^[\w._:+\-/=]+$/;
2777
- async function writeMcp(agent, ctx) {
2778
- if (agent.authMode === "literal" && !TOKEN_RE.test(ctx.token)) {
2779
- throw new Error("Bearer token contains unexpected characters; refusing to write config.");
2780
- }
2781
- const file = configFileFor(agent, ctx.cwd);
1580
+ async function writeMcp(agent) {
1581
+ const file = configFileFor(agent);
2782
1582
  const entries = {
2783
- [DOCS_MCP_NAME]: agent.entry({ url: DOCS_MCP_ENDPOINT, authMode: "none", token: ctx.token, envVarName: MCP_TOKEN_VAR }),
2784
- [DASHBOARD_MCP_NAME]: agent.entry({
2785
- url: JUSPAY_MCP_ENDPOINT,
2786
- authMode: agent.authMode,
2787
- token: ctx.token,
2788
- envVarName: MCP_TOKEN_VAR
2789
- })
1583
+ [DOCS_MCP_NAME]: agent.entry(DOCS_MCP_ENDPOINT),
1584
+ [DASHBOARD_MCP_NAME]: agent.entry(JUSPAY_MCP_ENDPOINT)
2790
1585
  };
2791
- await fs5.mkdir(path4.dirname(file), { recursive: true });
1586
+ await fs2.mkdir(path2.dirname(file), { recursive: true });
2792
1587
  if (agent.format === "json") {
2793
1588
  await mergeJson(file, agent.containerKey, entries);
2794
1589
  } else {
2795
1590
  await mergeToml(file, agent.containerKey, entries);
2796
1591
  }
2797
- await fs5.chmod(file, 384).catch(() => {});
2798
1592
  return file;
2799
1593
  }
2800
- async function removeMcp(agent, cwd) {
2801
- const file = configFileFor(agent, cwd);
1594
+ async function removeMcp(agent) {
1595
+ const file = configFileFor(agent);
2802
1596
  let raw;
2803
1597
  try {
2804
- raw = await fs5.readFile(file, "utf8");
1598
+ raw = await fs2.readFile(file, "utf8");
2805
1599
  } catch {
2806
1600
  return false;
2807
1601
  }
@@ -2820,505 +1614,325 @@ async function removeMcp(agent, cwd) {
2820
1614
  return false;
2821
1615
  const out = agent.format === "json" ? JSON.stringify(config, null, 2) + `
2822
1616
  ` : stringify(config);
2823
- await fs5.writeFile(file, out, { mode: 384 });
1617
+ await fs2.writeFile(file, out);
2824
1618
  return true;
2825
1619
  }
1620
+ async function readExisting(file, format) {
1621
+ let raw;
1622
+ try {
1623
+ raw = await fs2.readFile(file, "utf8");
1624
+ } catch (err) {
1625
+ if (err.code === "ENOENT")
1626
+ return null;
1627
+ throw err;
1628
+ }
1629
+ if (raw.trim() === "")
1630
+ return null;
1631
+ try {
1632
+ return format === "json" ? JSON.parse(raw) : parse(raw);
1633
+ } catch {
1634
+ throw new Error(`${file} isn't valid ${format.toUpperCase()}; refusing to overwrite it. Fix or remove it, then re-run.`);
1635
+ }
1636
+ }
2826
1637
  async function mergeJson(file, containerKey, entries) {
2827
- let config = {};
2828
- try {
2829
- config = JSON.parse(await fs5.readFile(file, "utf8"));
2830
- } catch {}
1638
+ const config = await readExisting(file, "json") ?? {};
2831
1639
  const container = config[containerKey] && typeof config[containerKey] === "object" ? config[containerKey] : {};
2832
1640
  Object.assign(container, entries);
2833
1641
  config[containerKey] = container;
2834
- await fs5.writeFile(file, JSON.stringify(config, null, 2) + `
2835
- `, { mode: 384 });
1642
+ await fs2.writeFile(file, JSON.stringify(config, null, 2) + `
1643
+ `);
2836
1644
  }
2837
1645
  async function mergeToml(file, containerKey, entries) {
2838
- let config = {};
2839
- try {
2840
- config = parse(await fs5.readFile(file, "utf8"));
2841
- } catch {}
1646
+ const config = await readExisting(file, "toml") ?? {};
2842
1647
  const container = config[containerKey] && typeof config[containerKey] === "object" ? config[containerKey] : {};
2843
1648
  Object.assign(container, entries);
2844
1649
  config[containerKey] = container;
2845
- await fs5.writeFile(file, stringify(config), { mode: 384 });
1650
+ await fs2.writeFile(file, stringify(config));
2846
1651
  }
2847
1652
 
2848
1653
  // src/skills-installer.ts
2849
- import { spawn as spawn3 } from "node:child_process";
2850
- import fs6 from "node:fs/promises";
2851
- import path5 from "node:path";
2852
- var OUR_SKILL = "integrate";
2853
- function addSkills(cwd) {
2854
- return runSkills(["add", SKILLS_PACKAGE], cwd);
1654
+ import { spawn } from "node:child_process";
1655
+ function addSkills() {
1656
+ return runSkills(["add", SKILLS_PACKAGE]);
2855
1657
  }
2856
- async function ensureClaudeSkillLink(cwd) {
2857
- const src = path5.join(cwd, ".agents", "skills", OUR_SKILL);
2858
- try {
2859
- await fs6.access(src);
2860
- } catch {
2861
- return;
2862
- }
2863
- const dest = path5.join(cwd, ".claude", "skills", OUR_SKILL);
2864
- await fs6.mkdir(path5.dirname(dest), { recursive: true });
2865
- try {
2866
- await fs6.lstat(dest);
2867
- return;
2868
- } catch {}
2869
- const relTarget = path5.join("..", "..", ".agents", "skills", OUR_SKILL);
1658
+ async function removeSkills() {
2870
1659
  try {
2871
- await fs6.symlink(relTarget, dest, "dir");
1660
+ await runSkills(["remove", SKILLS_PACKAGE, "-y"]);
1661
+ return true;
2872
1662
  } catch {
2873
- await fs6.cp(src, dest, { recursive: true });
2874
- }
2875
- }
2876
- async function removeSkills(cwd) {
2877
- const removed = [];
2878
- const dirs = [
2879
- path5.join(cwd, ".agents", "skills", OUR_SKILL),
2880
- path5.join(cwd, ".claude", "skills", OUR_SKILL)
2881
- ];
2882
- for (const dir of dirs) {
2883
- try {
2884
- await fs6.access(dir);
2885
- await fs6.rm(dir, { recursive: true, force: true });
2886
- removed.push(path5.relative(cwd, dir));
2887
- } catch {}
1663
+ return false;
2888
1664
  }
2889
- return removed;
2890
1665
  }
2891
- function runSkills(args, cwd) {
1666
+ function runSkills(args) {
2892
1667
  return new Promise((resolve, reject) => {
2893
- const child = spawn3("npx", ["-y", "skills", ...args], { cwd, stdio: "inherit" });
1668
+ const child = spawn("npx", ["-y", "skills", ...args], { stdio: "inherit" });
2894
1669
  child.on("error", reject);
2895
1670
  child.on("exit", (code) => code === 0 ? resolve() : reject(new Error(`skills ${args[0]} exited ${code}`)));
2896
1671
  });
2897
1672
  }
2898
1673
 
2899
- // src/setup.ts
2900
- var import_picocolors4 = __toESM(require_picocolors(), 1);
2901
- var import_which2 = __toESM(require_lib(), 1);
2902
- import { spawn as spawn4 } from "node:child_process";
2903
- import fs7 from "node:fs/promises";
2904
- import path6 from "node:path";
2905
- async function runSetup(cwd, token, include = []) {
2906
- const agents = await detectAgents(cwd, include);
2907
- const labels = [];
2908
- const configs = [];
2909
- const gitignore = [];
2910
- const s = spin(`Configuring MCP for ${agents.length} agent(s)...`);
2911
- for (const a of agents) {
2912
- try {
2913
- const file = await writeMcp(a, { cwd, token });
2914
- configs.push(file);
2915
- labels.push(a.label);
2916
- if (a.authMode === "literal" && a.scope === "project") {
2917
- gitignore.push(path6.relative(cwd, file));
2918
- }
2919
- } catch (err) {
2920
- info(`${a.label}: ${err.message}`);
1674
+ // src/ui.ts
1675
+ var import_picocolors = __toESM(require_picocolors(), 1);
1676
+ var ANSI_RE = /\x1B\[[0-9;]*m/g;
1677
+ function visibleLen(s) {
1678
+ return s.replace(ANSI_RE, "").length;
1679
+ }
1680
+ var SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
1681
+
1682
+ class Spinner {
1683
+ timer = null;
1684
+ frame = 0;
1685
+ message;
1686
+ interactive;
1687
+ constructor(message) {
1688
+ this.message = message;
1689
+ this.interactive = Boolean(process.stdout.isTTY);
1690
+ }
1691
+ start() {
1692
+ if (!this.interactive) {
1693
+ process.stdout.write(" " + import_picocolors.default.dim("→ ") + this.message + `
1694
+ `);
1695
+ return this;
2921
1696
  }
1697
+ process.stdout.write("\x1B[?25l");
1698
+ this.render();
1699
+ this.timer = setInterval(() => this.render(), 80);
1700
+ return this;
2922
1701
  }
2923
- s.done(`Configured ${labels.join(", ")}`);
2924
- if (gitignore.length > 0)
2925
- await updateGitignore(cwd, gitignore);
2926
- step("Installing skills follow the prompts below:");
2927
- try {
2928
- await addSkills(cwd);
2929
- await ensureClaudeSkillLink(cwd);
2930
- done("Skills installed (.agents/skills/ + .claude/skills/)");
2931
- } catch (err) {
2932
- warn(`Skills install failed: ${err.message}`);
1702
+ update(message) {
1703
+ this.message = message;
1704
+ if (!this.interactive) {
1705
+ process.stdout.write(" " + import_picocolors.default.dim(" ") + message + `
1706
+ `);
1707
+ }
2933
1708
  }
2934
- return { cwd, agents: labels, configs };
2935
- }
2936
- async function ensureGlobalCli() {
2937
- try {
2938
- await import_which2.default("juspay");
2939
- return;
2940
- } catch {}
2941
- const sp = spin("Installing the `juspay` command globally...");
2942
- try {
2943
- await run("npm", ["install", "-g", PACKAGE_NAME]);
2944
- } catch (err) {
2945
- sp.fail(`Couldn't install the juspay command automatically: ${err.message}`);
2946
- info(`Install it yourself: npm i -g ${PACKAGE_NAME} (then: juspay claude)`);
2947
- return;
1709
+ done(finalMessage) {
1710
+ this.stop();
1711
+ process.stdout.write(" " + import_picocolors.default.green("✓ ") + finalMessage + `
1712
+ `);
2948
1713
  }
2949
- try {
2950
- await import_which2.default("juspay");
2951
- sp.done("Installed the `juspay` command launch with: juspay claude");
2952
- } catch {
2953
- sp.fail("Installed `juspay`, but it isn't on your PATH.");
2954
- info(`npm's global bin dir isn't on PATH. Add it (and put this in ~/.zshrc):`);
2955
- info(` export PATH="$(npm prefix -g)/bin:$PATH"`);
2956
- info("Then launch with: juspay claude");
1714
+ fail(finalMessage) {
1715
+ this.stop();
1716
+ process.stdout.write(" " + import_picocolors.default.red("✗ ") + finalMessage + `
1717
+ `);
2957
1718
  }
2958
- }
2959
- function run(bin, args) {
2960
- return new Promise((resolve, reject) => {
2961
- const child = spawn4(bin, args, { stdio: "ignore" });
2962
- child.on("error", reject);
2963
- child.on("exit", (code) => code === 0 ? resolve() : reject(new Error(`${bin} exited ${code}`)));
2964
- });
2965
- }
2966
- async function updateGitignore(cwd, relPaths) {
2967
- const gitignorePath = path6.join(cwd, ".gitignore");
2968
- const hasGitignore = await exists2(gitignorePath);
2969
- if (!hasGitignore && !await isInsideGitRepo(cwd))
2970
- return;
2971
- const existing = hasGitignore ? await fs7.readFile(gitignorePath, "utf8") : "";
2972
- const marker = "# Juspay AI CLI — token-bearing configs; do not commit";
2973
- const known = new Set(existing.split(/\r?\n/));
2974
- const toAdd = relPaths.filter((p2) => !known.has(p2));
2975
- if (toAdd.length === 0)
2976
- return;
2977
- const header = existing.includes(marker) ? "" : marker + `
2978
- `;
2979
- const block = `
2980
- ` + header + toAdd.join(`
2981
- `) + `
2982
- `;
2983
- const updated = existing === "" || existing.endsWith(`
2984
- `) ? existing + block : existing + `
2985
- ` + block;
2986
- await fs7.writeFile(gitignorePath, updated, "utf8");
2987
- process.stdout.write(" " + import_picocolors4.default.dim(`→ Added ${toAdd.join(", ")} to .gitignore (token-bearing)
2988
- `));
2989
- }
2990
- async function exists2(p2) {
2991
- try {
2992
- await fs7.access(p2);
2993
- return true;
2994
- } catch {
2995
- return false;
1719
+ render() {
1720
+ const glyph = import_picocolors.default.cyan(SPINNER_FRAMES[this.frame]);
1721
+ process.stdout.write("\r\x1B[K " + glyph + " " + this.message);
1722
+ this.frame = (this.frame + 1) % SPINNER_FRAMES.length;
2996
1723
  }
2997
- }
2998
- async function isInsideGitRepo(dir) {
2999
- let current = path6.resolve(dir);
3000
- while (true) {
3001
- if (await exists2(path6.join(current, ".git")))
3002
- return true;
3003
- const parent = path6.dirname(current);
3004
- if (parent === current)
3005
- return false;
3006
- current = parent;
1724
+ stop() {
1725
+ if (this.timer) {
1726
+ clearInterval(this.timer);
1727
+ this.timer = null;
1728
+ }
1729
+ if (this.interactive) {
1730
+ process.stdout.write("\r\x1B[K");
1731
+ process.stdout.write("\x1B[?25h");
1732
+ }
3007
1733
  }
3008
1734
  }
3009
-
3010
- // src/token.ts
3011
- async function getToken() {
3012
- const oauth = await readOAuth();
3013
- if (!oauth)
3014
- throw new Error("No session found. Run `npx @sahyll/ai` first.");
3015
- return oauth.access_token;
3016
- }
3017
-
3018
- // src/index.ts
3019
- var SESSION_SKEW_SECONDS = 24 * 60 * 60;
3020
- function isUnderNpx() {
3021
- return process.env.npm_command === "exec" || (process.env.npm_execpath || "").includes("npx") || (process.env.npm_config_user_agent || "").includes("npx") || (process.env.INIT_CWD || process.cwd()).includes("_npx");
1735
+ function spin(message) {
1736
+ return new Spinner(message).start();
3022
1737
  }
3023
- function homeShort(p2) {
3024
- return p2.replace(process.env.HOME ?? "~", "~");
1738
+ function banner() {
1739
+ process.stdout.write(`
1740
+ `);
1741
+ process.stdout.write(" " + import_picocolors.default.cyan(import_picocolors.default.bold("Juspay for AI agents")) + `
1742
+ `);
1743
+ process.stdout.write(`
1744
+ `);
3025
1745
  }
3026
- function showBanner() {
3027
- banner();
1746
+ function step(msg) {
1747
+ process.stdout.write(" " + import_picocolors.default.dim("→ ") + msg + `
1748
+ `);
3028
1749
  }
3029
- function showHelp(underNpx) {
3030
- if (underNpx) {
3031
- process.stdout.write(` Usage: npx ${PACKAGE_NAME} [command]
3032
-
1750
+ function done(msg) {
1751
+ process.stdout.write(" " + import_picocolors.default.green("✓ ") + msg + `
3033
1752
  `);
3034
- process.stdout.write(import_picocolors5.default.dim(` Sets up Juspay MCP + skills for this project and installs the
3035
- `));
3036
- process.stdout.write(import_picocolors5.default.dim(" `juspay` command. Launch agents afterwards with `juspay <agent>`.\n\n"));
3037
- process.stdout.write(` Commands:
1753
+ }
1754
+ function info(msg) {
1755
+ process.stdout.write(" " + import_picocolors.default.dim(msg) + `
3038
1756
  `);
3039
- process.stdout.write(" (no command) Sign in + set up MCP + skills, install the `juspay` command\n");
3040
- process.stdout.write(` init Same as above (add --force to re-run sign-in)
1757
+ }
1758
+ function warn(msg) {
1759
+ process.stdout.write(" " + import_picocolors.default.yellow("⚠ ") + msg + `
3041
1760
  `);
3042
- process.stdout.write(` update Re-write configs + re-install skills
1761
+ }
1762
+ function summaryBox(title, rows) {
1763
+ const labelWidth = Math.max(...rows.map((r) => visibleLen(r.label)));
1764
+ const composed = rows.map((r) => {
1765
+ const padding = " ".repeat(labelWidth - visibleLen(r.label) + 2);
1766
+ return import_picocolors.default.green("✓ ") + import_picocolors.default.bold(r.label) + padding + r.value;
1767
+ });
1768
+ const widest = Math.max(visibleLen(` Setup `) + title.length, ...composed.map(visibleLen));
1769
+ const innerWidth = Math.max(widest + 4, 44);
1770
+ const top = " " + import_picocolors.default.dim("╭─ ") + import_picocolors.default.bold(title) + " " + import_picocolors.default.dim("─".repeat(innerWidth - title.length - 4)) + import_picocolors.default.dim("╮");
1771
+ const empty = " " + import_picocolors.default.dim("│") + " ".repeat(innerWidth) + import_picocolors.default.dim("│");
1772
+ const bottom = " " + import_picocolors.default.dim("╰" + "─".repeat(innerWidth) + "╯");
1773
+ process.stdout.write(`
3043
1774
  `);
3044
- process.stdout.write(` list List skills installed in this project
1775
+ process.stdout.write(top + `
3045
1776
  `);
3046
- process.stdout.write(` logout Clear stored credentials
1777
+ process.stdout.write(empty + `
3047
1778
  `);
3048
- process.stdout.write(` uninstall Remove EVERYTHING: the juspay command, credentials,
1779
+ for (const line of composed) {
1780
+ const pad = " ".repeat(Math.max(0, innerWidth - visibleLen(line) - 4));
1781
+ process.stdout.write(" " + import_picocolors.default.dim("│") + " " + line + pad + " " + import_picocolors.default.dim("│") + `
3049
1782
  `);
3050
- process.stdout.write(` and this project's MCP + skills
1783
+ }
1784
+ process.stdout.write(empty + `
3051
1785
  `);
3052
- process.stdout.write(` help Show this help
3053
-
1786
+ process.stdout.write(bottom + `
3054
1787
  `);
3055
- process.stdout.write(" After setup, launch an agent: " + import_picocolors5.default.cyan("juspay claude") + import_picocolors5.default.dim(` (or codex, gemini, opencode, copilot)
1788
+ }
3056
1789
 
3057
- `));
3058
- return;
1790
+ // src/setup.ts
1791
+ async function runSetup() {
1792
+ const agents = await detectAgents();
1793
+ if (agents.length === 0) {
1794
+ warn("No supported AI agents detected on this machine.");
1795
+ info("Install one (claude, codex, gemini, opencode, copilot, cursor, windsurf) and re-run.");
1796
+ return { agents: [], configs: [] };
1797
+ }
1798
+ const labels = [];
1799
+ const configs = [];
1800
+ const s = spin(`Adding Juspay MCP to ${agents.length} agent(s)...`);
1801
+ for (const a of agents) {
1802
+ try {
1803
+ const file = await writeMcp(a);
1804
+ configs.push(file);
1805
+ labels.push(a.label);
1806
+ } catch (err) {
1807
+ info(`${a.label}: ${err.message}`);
1808
+ }
1809
+ }
1810
+ s.done(`Configured ${labels.join(", ")}`);
1811
+ step("Installing skills — choose your agents in the prompt below:");
1812
+ try {
1813
+ await addSkills();
1814
+ done("Skills installed");
1815
+ } catch (err) {
1816
+ warn(`Skills install failed: ${err.message}`);
3059
1817
  }
3060
- process.stdout.write(` Usage: juspay <agent|command>
1818
+ return { agents: labels, configs };
1819
+ }
3061
1820
 
3062
- `);
3063
- process.stdout.write(import_picocolors5.default.dim(` Launch an AI agent with Juspay MCP + skills enabled.
1821
+ // src/index.ts
1822
+ function showHelp() {
1823
+ banner();
1824
+ process.stdout.write(` Usage: npx ${PACKAGE_NAME} [command]
3064
1825
 
3065
- `));
3066
- process.stdout.write(` Agents (launchable):
3067
- `);
3068
- process.stdout.write(" " + LAUNCHABLE.map((a) => a.id).join(", ") + `
3069
1826
  `);
3070
- process.stdout.write(import_picocolors5.default.dim(` (cursor, windsurf, vscode are GUI apps configured; open them yourself)
1827
+ process.stdout.write(import_picocolors2.default.dim(` Adds the Juspay MCP server + skills to every AI agent installed on this
1828
+ `));
1829
+ process.stdout.write(import_picocolors2.default.dim(` machine (user scope). Each agent authenticates the MCP itself on first use.
3071
1830
 
3072
1831
  `));
3073
1832
  process.stdout.write(` Commands:
3074
1833
  `);
3075
- process.stdout.write(` <agent> Launch that agent (sets up this project on first run)
3076
- `);
3077
- process.stdout.write(` update Re-write configs + re-install skills
1834
+ process.stdout.write(` (no command) Detect agents, add the Juspay MCP + skills to each
3078
1835
  `);
3079
- process.stdout.write(` list List skills installed in this project
1836
+ process.stdout.write(` uninstall Remove the Juspay MCP + skills from all agents
3080
1837
  `);
3081
- process.stdout.write(` uninstall Remove Juspay MCP + skills from this project
3082
- `);
3083
- process.stdout.write(` logout Clear stored credentials
1838
+ process.stdout.write(` list Show which agents have the Juspay MCP configured
3084
1839
  `);
3085
1840
  process.stdout.write(` help Show this help
3086
1841
 
3087
1842
  `);
3088
- process.stdout.write(" First time? Run " + import_picocolors5.default.cyan(`npx ${PACKAGE_NAME}`) + import_picocolors5.default.dim(` to sign in and set up.
3089
-
3090
- `));
3091
- }
3092
- function parseEnv(args) {
3093
- const i = args.indexOf("--env");
3094
- if (i === -1)
3095
- return;
3096
- const val = args[i + 1];
3097
- if (val !== "sandbox" && val !== "production") {
3098
- throw new Error("--env must be 'sandbox' or 'production'.");
3099
- }
3100
- return val;
3101
- }
3102
- async function ensureSession(args) {
3103
- const cfg = await readConfig().catch(() => null);
3104
- const oauth = await readOAuth().catch(() => null);
3105
- const valid = oauth && oauth.expires_at > Math.floor(Date.now() / 1000) + SESSION_SKEW_SECONDS;
3106
- if (cfg && valid)
3107
- return;
3108
- const fresh = await runInit({ env: parseEnv(args) });
3109
- await writeConfig(fresh);
3110
- }
3111
- async function projectConfigured(cwd) {
3112
- try {
3113
- await fs8.access(path7.join(cwd, ".agents", "skills", "integrate"));
3114
- return true;
3115
- } catch {
3116
- return false;
3117
- }
3118
1843
  }
3119
- async function runList() {
3120
- const skillsDir = path7.join(process.cwd(), ".agents", "skills");
3121
- let entries = [];
3122
- try {
3123
- const dirents = await fs8.readdir(skillsDir, { withFileTypes: true });
3124
- entries = dirents.filter((d3) => d3.isDirectory() || d3.isSymbolicLink()).map((d3) => d3.name);
3125
- } catch {
3126
- entries = [];
3127
- }
3128
- if (entries.length === 0) {
3129
- process.stdout.write(" " + import_picocolors5.default.yellow("⚠ ") + `No skills in this project. Run \`npx ${PACKAGE_NAME}\`.
1844
+ function nextSteps(result) {
1845
+ process.stdout.write(`
1846
+ ` + import_picocolors2.default.bold("Next steps") + `
3130
1847
  `);
3131
- return;
3132
- }
3133
- process.stdout.write(" " + import_picocolors5.default.cyan("Skills in this project (.agents/skills/):") + `
1848
+ process.stdout.write(" " + import_picocolors2.default.dim("Open any configured agent and authenticate the Juspay MCP (one-time):") + `
3134
1849
  `);
3135
- for (const skill of entries)
3136
- process.stdout.write(` • ${skill}
1850
+ process.stdout.write(" " + import_picocolors2.default.dim("• Claude Code: run ") + import_picocolors2.default.cyan("/mcp") + import_picocolors2.default.dim(" → select ") + import_picocolors2.default.cyan(DASHBOARD_MCP_NAME) + import_picocolors2.default.dim(" → Authenticate") + `
3137
1851
  `);
3138
- }
3139
- async function removeProjectArtifacts(cwd) {
3140
- const removedMcp = [];
3141
- for (const a of AGENTS) {
3142
- if (await removeMcp(a, cwd))
3143
- removedMcp.push(a.label);
3144
- }
3145
- if (removedMcp.length > 0) {
3146
- done(`Removed Juspay MCP from: ${removedMcp.join(", ")}`);
3147
- } else {
3148
- info("• No Juspay MCP entries found in this project");
3149
- }
3150
- const removedSkills = await removeSkills(cwd);
3151
- if (removedSkills.length > 0) {
3152
- done(`Removed skills from: ${removedSkills.join(", ")}`);
3153
- } else {
3154
- info("• No Juspay skills found in this project");
3155
- }
3156
- }
3157
- async function runUninstall() {
3158
- await removeProjectArtifacts(process.cwd());
3159
- process.stdout.write(`
3160
- ` + import_picocolors5.default.cyan("Juspay context removed from this project.") + `
1852
+ process.stdout.write(" " + import_picocolors2.default.dim("• Codex: ") + import_picocolors2.default.cyan("codex mcp login " + DASHBOARD_MCP_NAME) + `
1853
+ `);
1854
+ process.stdout.write(" " + import_picocolors2.default.dim("• Others: they prompt to sign in the first time the MCP is used") + `
3161
1855
  `);
3162
- process.stdout.write(import_picocolors5.default.dim(" (Per-project — run `juspay uninstall` in other projects to clean them too.)\n"));
3163
- process.stdout.write(import_picocolors5.default.dim(` (To remove the tool itself: npx ${PACKAGE_NAME} uninstall)
3164
-
3165
- `));
3166
- }
3167
- async function runFullUninstall() {
3168
- await removeProjectArtifacts(process.cwd());
3169
- await fs8.rm(juspayConfigDir, { recursive: true, force: true });
3170
- done(`Cleared stored credentials (${homeShort(juspayConfigDir)})`);
3171
- const sp = spin(`Uninstalling the juspay command (npm rm -g ${PACKAGE_NAME})...`);
3172
- try {
3173
- await run2("npm", ["rm", "-g", PACKAGE_NAME]);
3174
- sp.done("Uninstalled the juspay command");
3175
- } catch (err) {
3176
- sp.fail(`Could not remove it automatically (${err.message}). Run: npm rm -g ${PACKAGE_NAME}`);
3177
- }
3178
1856
  process.stdout.write(`
3179
- ` + import_picocolors5.default.cyan("Juspay fully removed.") + `
1857
+ ` + import_picocolors2.default.dim("docs-mcp-server needs no auth. Remove everything: ") + import_picocolors2.default.cyan(`npx ${PACKAGE_NAME} uninstall`) + `
3180
1858
 
3181
1859
  `);
3182
1860
  }
3183
- async function runLogout() {
3184
- await fs8.rm(juspayConfigDir, { recursive: true, force: true });
3185
- done(`Cleared stored credentials (${homeShort(juspayConfigDir)})`);
1861
+ async function printSetupSummary(result) {
1862
+ const rows = [
1863
+ { label: "Agents ", value: result.agents.join(", ") },
1864
+ { label: "MCPs ", value: "docs-mcp-server, juspay-mcp (agent-authenticated)" },
1865
+ { label: "Skills ", value: "integrate (global)" }
1866
+ ];
1867
+ summaryBox("Setup complete", rows);
1868
+ nextSteps(result);
3186
1869
  }
3187
- function nextSteps() {
1870
+ async function runUninstall() {
1871
+ const removed = [];
1872
+ for (const a of AGENTS) {
1873
+ if (await removeMcp(a).catch(() => false))
1874
+ removed.push(a.label);
1875
+ }
1876
+ if (removed.length > 0)
1877
+ done(`Removed Juspay MCP from: ${removed.join(", ")}`);
1878
+ else
1879
+ info("• No Juspay MCP entries found");
1880
+ if (await removeSkills())
1881
+ done("Removed Juspay skills");
1882
+ else
1883
+ info("• Skills not auto-removed — remove the `integrate` skill from your agents if needed");
3188
1884
  process.stdout.write(`
3189
- ` + import_picocolors5.default.bold("Next steps") + `
3190
- `);
3191
- process.stdout.write(" " + import_picocolors5.default.dim("Launch an agent (MCP + skills already wired in):") + `
3192
- `);
3193
- process.stdout.write(" " + import_picocolors5.default.cyan("juspay claude") + import_picocolors5.default.dim(" # or codex, gemini, opencode, copilot") + `
1885
+ ` + import_picocolors2.default.cyan("Juspay removed.") + `
3194
1886
 
3195
1887
  `);
3196
- process.stdout.write(" " + import_picocolors5.default.dim("Project cleanup (MCP + skills): ") + import_picocolors5.default.cyan("juspay uninstall") + `
1888
+ }
1889
+ async function runList() {
1890
+ const configured = [];
1891
+ for (const a of AGENTS) {
1892
+ try {
1893
+ const raw = await fs3.readFile(configFileFor(a), "utf8");
1894
+ if (raw.includes(DASHBOARD_MCP_NAME))
1895
+ configured.push(a.label);
1896
+ } catch {}
1897
+ }
1898
+ if (configured.length === 0) {
1899
+ process.stdout.write(" " + import_picocolors2.default.yellow("⚠ ") + `No agents configured. Run \`npx ${PACKAGE_NAME}\`.
1900
+ `);
1901
+ return;
1902
+ }
1903
+ process.stdout.write(" " + import_picocolors2.default.cyan("Juspay MCP is configured in:") + `
3197
1904
  `);
3198
- process.stdout.write(" " + import_picocolors5.default.dim("Remove the tool entirely: ") + import_picocolors5.default.cyan(`npx ${PACKAGE_NAME} uninstall`) + `
3199
-
1905
+ for (const label of configured)
1906
+ process.stdout.write(` • ${label}
3200
1907
  `);
3201
1908
  }
3202
- async function printSetupSummary(result) {
3203
- const oauth = await readOAuth().catch(() => null);
3204
- const cfg = await readConfig().catch(() => null);
3205
- const rows = [];
3206
- if (oauth) {
3207
- rows.push({ label: "Session ", value: `valid until ${new Date(oauth.expires_at * 1000).toDateString()}` });
3208
- }
3209
- if (cfg) {
3210
- rows.push({ label: "Merchant ", value: cfg.merchant_id });
3211
- rows.push({ label: "Environment", value: cfg.environment });
3212
- }
3213
- rows.push({ label: "MCPs ", value: "docs-mcp-server, juspay-mcp" });
3214
- if (result.agents.length > 0)
3215
- rows.push({ label: "Agents ", value: result.agents.join(", ") });
3216
- rows.push({ label: "Skills ", value: "integrate (.agents/skills/)" });
3217
- rows.push({ label: "Project ", value: homeShort(result.cwd) });
3218
- summaryBox("Setup complete", rows);
3219
- nextSteps();
3220
- }
3221
- function run2(bin, args) {
3222
- return new Promise((resolve, reject) => {
3223
- const child = spawn5(bin, args, { stdio: "ignore" });
3224
- child.on("error", reject);
3225
- child.on("exit", (code) => code === 0 ? resolve() : reject(new Error(`${bin} exited ${code}`)));
3226
- });
3227
- }
3228
1909
  async function main() {
3229
1910
  const args = process.argv.slice(2);
3230
1911
  const command = args[0];
3231
- const underNpx = isUnderNpx();
3232
- const invocation = underNpx ? `npx ${PACKAGE_NAME}` : "juspay";
3233
1912
  if (command === "help" || command === "--help" || command === "-h") {
3234
- showBanner();
3235
- showHelp(underNpx);
1913
+ showHelp();
3236
1914
  return;
3237
1915
  }
1916
+ banner();
3238
1917
  if (command === "uninstall") {
3239
- showBanner();
3240
- if (underNpx)
3241
- await runFullUninstall();
3242
- else
3243
- await runUninstall();
3244
- return;
3245
- }
3246
- if (command === "logout") {
3247
- showBanner();
3248
- await runLogout();
1918
+ await runUninstall();
3249
1919
  return;
3250
1920
  }
3251
1921
  if (command === "list") {
3252
- showBanner();
3253
1922
  await runList();
3254
1923
  return;
3255
1924
  }
3256
- showBanner();
3257
- const cwd = process.cwd();
3258
- if (command === "update") {
3259
- await ensureSession(args);
3260
- const token2 = await getToken();
3261
- const result = await runSetup(cwd, token2);
3262
- done(`Updated ${result.agents.join(", ")} in ${homeShort(result.cwd)}`);
3263
- return;
3264
- }
3265
- if (command === "init") {
3266
- const force = args.includes("--force");
3267
- const cfg = await runInit({ env: parseEnv(args), force });
3268
- await writeConfig(cfg);
3269
- const token2 = await getToken();
3270
- const result = await runSetup(cwd, token2);
3271
- await ensureGlobalCli();
3272
- await printSetupSummary(result);
3273
- return;
3274
- }
3275
1925
  if (!command) {
3276
- if (underNpx) {
3277
- await ensureSession(args);
3278
- const token2 = await getToken();
3279
- const result = await runSetup(cwd, token2);
3280
- await ensureGlobalCli();
1926
+ const result = await runSetup();
1927
+ if (result.agents.length > 0)
3281
1928
  await printSetupSummary(result);
3282
- } else {
3283
- showHelp(false);
3284
- }
3285
- return;
3286
- }
3287
- const agent = findAgent(command);
3288
- if (!agent) {
3289
- throw new Error(`Unknown command or agent '${command}'. Run \`${invocation} help\`.`);
3290
- }
3291
- if (underNpx) {
3292
- warn(`Launching agents is done with the \`juspay\` command — e.g. \`juspay ${agent.id}\`.`);
3293
- info(`Run \`npx ${PACKAGE_NAME}\` (no agent) to sign in and set up first; it installs the \`juspay\` command.`);
3294
- return;
3295
- }
3296
- await ensureSession(args);
3297
- const token = await getToken();
3298
- if (!await projectConfigured(cwd)) {
3299
- const result = await runSetup(cwd, token, [agent.id]);
3300
- await printSetupSummary(result);
3301
- } else {
3302
- await writeMcp(agent, { cwd, token }).catch((err) => {
3303
- warn(`Could not refresh ${agent.label} MCP config: ${err.message}`);
3304
- });
3305
- }
3306
- if (agent.kind === "gui") {
3307
- info(`${agent.label} is a GUI app — configured for this project. Just open it.`);
3308
- return;
3309
- }
3310
- const bin = await ensureAgentBin(agent);
3311
- if (!bin) {
3312
- warn(`${agent.label} isn't available. This project is configured — install it and re-run \`juspay ${agent.id}\`.`);
3313
1929
  return;
3314
1930
  }
3315
- step(`Launching ${agent.label}...`);
3316
- await prepareAgentLaunch(agent);
3317
- launchAgent(bin, args.slice(1), token);
1931
+ throw new Error(`Unknown command '${command}'. Run \`npx ${PACKAGE_NAME} help\`.`);
3318
1932
  }
3319
1933
  main().catch((err) => {
3320
1934
  const message = err instanceof Error ? err.message : String(err);
3321
- process.stderr.write(import_picocolors5.default.red("✗ ") + message + `
1935
+ process.stderr.write(import_picocolors2.default.red("✗ ") + message + `
3322
1936
  `);
3323
1937
  process.exit(1);
3324
1938
  });