@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 +519 -1905
- package/package.json +1 -1
- package/scripts/postinstall.js +2 -3
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
|
|
380
|
-
import
|
|
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
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
if (
|
|
395
|
-
return;
|
|
396
|
-
|
|
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
|
-
|
|
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
|
-
|
|
439
|
-
|
|
440
|
-
|
|
351
|
+
entry: httpType,
|
|
352
|
+
bin: "claude",
|
|
353
|
+
homeMarkers: [".claude", ".claude.json"]
|
|
441
354
|
},
|
|
442
355
|
{
|
|
443
356
|
id: "codex",
|
|
444
357
|
label: "Codex",
|
|
445
|
-
|
|
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
|
-
|
|
454
|
-
|
|
455
|
-
|
|
361
|
+
entry: urlOnly,
|
|
362
|
+
bin: "codex",
|
|
363
|
+
homeMarkers: [".codex"]
|
|
456
364
|
},
|
|
457
365
|
{
|
|
458
366
|
id: "gemini",
|
|
459
367
|
label: "Gemini CLI",
|
|
460
|
-
|
|
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
|
-
|
|
469
|
-
|
|
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
|
-
|
|
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
|
-
|
|
485
|
-
|
|
486
|
-
|
|
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
|
-
|
|
500
|
-
|
|
501
|
-
|
|
391
|
+
entry: httpType,
|
|
392
|
+
bin: "copilot",
|
|
393
|
+
homeMarkers: [".copilot"]
|
|
502
394
|
},
|
|
503
395
|
{
|
|
504
396
|
id: "cursor",
|
|
505
397
|
label: "Cursor",
|
|
506
|
-
|
|
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
|
-
|
|
512
|
-
|
|
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
|
-
|
|
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
|
-
|
|
525
|
-
|
|
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
|
-
|
|
533
|
-
scope: "project",
|
|
534
|
-
configPath: path.join(".vscode", "mcp.json"),
|
|
416
|
+
configPath: vscodeUserMcp(),
|
|
535
417
|
format: "json",
|
|
536
418
|
containerKey: "servers",
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
vscodeExt: true,
|
|
540
|
-
entry: httpEntry(braceDollar)
|
|
419
|
+
entry: httpType,
|
|
420
|
+
vscodeExt: true
|
|
541
421
|
}
|
|
542
422
|
];
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
return AGENTS.find((a) => a.id === id);
|
|
423
|
+
function configFileFor(agent) {
|
|
424
|
+
return agent.configPath;
|
|
546
425
|
}
|
|
547
|
-
function
|
|
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 (
|
|
429
|
+
if (await isDetected(a))
|
|
566
430
|
out.push(a);
|
|
567
|
-
}
|
|
568
431
|
}
|
|
569
432
|
return out;
|
|
570
433
|
}
|
|
571
|
-
async function isDetected(a
|
|
572
|
-
if (a.bin && await
|
|
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/
|
|
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
|
-
//
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
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
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
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
|
|
528
|
+
return codeblock;
|
|
695
529
|
}
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
const
|
|
704
|
-
|
|
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
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
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
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
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
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
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
|
|
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
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
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
|
|
617
|
+
return ptr;
|
|
830
618
|
}
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
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
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
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
|
-
|
|
867
|
-
|
|
868
|
-
|
|
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
|
-
|
|
881
|
-
|
|
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
|
|
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 === "&" ? "&" : c === "<" ? "<" : c === ">" ? ">" : c === '"' ? """ : "'");
|
|
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
|
|
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[
|
|
2372
|
-
|
|
2373
|
-
if ((hasOwn = Object.hasOwn(t,
|
|
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 &&
|
|
2380
|
-
Object.defineProperty(t,
|
|
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[
|
|
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
|
|
2418
|
-
res.push(
|
|
2419
|
-
ptr =
|
|
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
|
|
2462
|
-
let
|
|
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[
|
|
2468
|
-
|
|
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
|
|
2474
|
-
t = t[
|
|
2475
|
-
|
|
1266
|
+
let l = t.length - 1;
|
|
1267
|
+
t = t[l];
|
|
1268
|
+
m = m[l].c;
|
|
2476
1269
|
}
|
|
2477
1270
|
}
|
|
2478
|
-
|
|
2479
|
-
if ((hasOwn = Object.hasOwn(t,
|
|
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 (
|
|
2484
|
-
Object.defineProperty(t,
|
|
2485
|
-
Object.defineProperty(
|
|
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
|
-
|
|
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 =
|
|
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[
|
|
1295
|
+
t[k] = [];
|
|
2503
1296
|
}
|
|
2504
|
-
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[
|
|
1305
|
+
t = hasOwn ? t[k] : t[k] = {};
|
|
2513
1306
|
} else if (type === 0 && hasOwn) {
|
|
2514
1307
|
return null;
|
|
2515
1308
|
}
|
|
2516
|
-
return [
|
|
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
|
|
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
|
|
1319
|
+
let k = parseKey(toml, ptr += +isTableArray, "]");
|
|
2527
1320
|
if (isTableArray) {
|
|
2528
|
-
if (toml[
|
|
1321
|
+
if (toml[k[1] - 1] !== "]") {
|
|
2529
1322
|
throw new TomlError("expected end of table declaration", {
|
|
2530
1323
|
toml,
|
|
2531
|
-
ptr:
|
|
1324
|
+
ptr: k[1] - 1
|
|
2532
1325
|
});
|
|
2533
1326
|
}
|
|
2534
|
-
|
|
1327
|
+
k[1]++;
|
|
2535
1328
|
}
|
|
2536
|
-
let
|
|
2537
|
-
if (!
|
|
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
|
-
|
|
2544
|
-
tbl =
|
|
2545
|
-
ptr =
|
|
1336
|
+
m = p[2];
|
|
1337
|
+
tbl = p[1];
|
|
1338
|
+
ptr = k[1];
|
|
2546
1339
|
} else {
|
|
2547
|
-
let
|
|
2548
|
-
let
|
|
2549
|
-
if (!
|
|
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,
|
|
2556
|
-
|
|
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
|
|
1454
|
+
let k = keys[i];
|
|
2662
1455
|
if (i)
|
|
2663
1456
|
res += ", ";
|
|
2664
|
-
res += BARE_KEY.test(
|
|
1457
|
+
res += BARE_KEY.test(k) ? k : formatString(k);
|
|
2665
1458
|
res += " = ";
|
|
2666
|
-
res += stringifyValue(obj[
|
|
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
|
|
2706
|
-
if (obj[
|
|
2707
|
-
let type = extendedTypeOf(obj[
|
|
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(
|
|
2712
|
-
if (type === "array" && isArrayOfTables(obj[
|
|
1504
|
+
let key = BARE_KEY.test(k) ? k : formatString(k);
|
|
1505
|
+
if (type === "array" && isArrayOfTables(obj[k])) {
|
|
2713
1506
|
tables += (tables && `
|
|
2714
|
-
`) + stringifyArrayTable(obj[
|
|
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[
|
|
1511
|
+
`) + stringifyTable(tblKey, obj[k], tblKey, depth - 1, numberAsFloat);
|
|
2719
1512
|
} else {
|
|
2720
1513
|
preamble += key;
|
|
2721
1514
|
preamble += " = ";
|
|
2722
|
-
preamble += stringifyValue(obj[
|
|
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
|
-
|
|
2777
|
-
|
|
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(
|
|
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
|
|
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
|
|
2801
|
-
const file = configFileFor(agent
|
|
1594
|
+
async function removeMcp(agent) {
|
|
1595
|
+
const file = configFileFor(agent);
|
|
2802
1596
|
let raw;
|
|
2803
1597
|
try {
|
|
2804
|
-
raw = await
|
|
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
|
|
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
|
-
|
|
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
|
|
2835
|
-
|
|
1642
|
+
await fs2.writeFile(file, JSON.stringify(config, null, 2) + `
|
|
1643
|
+
`);
|
|
2836
1644
|
}
|
|
2837
1645
|
async function mergeToml(file, containerKey, entries) {
|
|
2838
|
-
|
|
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
|
|
1650
|
+
await fs2.writeFile(file, stringify(config));
|
|
2846
1651
|
}
|
|
2847
1652
|
|
|
2848
1653
|
// src/skills-installer.ts
|
|
2849
|
-
import { spawn
|
|
2850
|
-
|
|
2851
|
-
|
|
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
|
|
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
|
|
1660
|
+
await runSkills(["remove", SKILLS_PACKAGE, "-y"]);
|
|
1661
|
+
return true;
|
|
2872
1662
|
} catch {
|
|
2873
|
-
|
|
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
|
|
1666
|
+
function runSkills(args) {
|
|
2892
1667
|
return new Promise((resolve, reject) => {
|
|
2893
|
-
const child =
|
|
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/
|
|
2900
|
-
var
|
|
2901
|
-
var
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
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
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
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
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
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
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
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
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
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
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
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
|
-
|
|
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
|
|
3024
|
-
|
|
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
|
|
3027
|
-
|
|
1746
|
+
function step(msg) {
|
|
1747
|
+
process.stdout.write(" " + import_picocolors.default.dim("→ ") + msg + `
|
|
1748
|
+
`);
|
|
3028
1749
|
}
|
|
3029
|
-
function
|
|
3030
|
-
|
|
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
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
process.stdout.write(` Commands:
|
|
1753
|
+
}
|
|
1754
|
+
function info(msg) {
|
|
1755
|
+
process.stdout.write(" " + import_picocolors.default.dim(msg) + `
|
|
3038
1756
|
`);
|
|
3039
|
-
|
|
3040
|
-
|
|
1757
|
+
}
|
|
1758
|
+
function warn(msg) {
|
|
1759
|
+
process.stdout.write(" " + import_picocolors.default.yellow("⚠ ") + msg + `
|
|
3041
1760
|
`);
|
|
3042
|
-
|
|
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
|
-
|
|
1775
|
+
process.stdout.write(top + `
|
|
3045
1776
|
`);
|
|
3046
|
-
|
|
1777
|
+
process.stdout.write(empty + `
|
|
3047
1778
|
`);
|
|
3048
|
-
|
|
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
|
-
|
|
1783
|
+
}
|
|
1784
|
+
process.stdout.write(empty + `
|
|
3051
1785
|
`);
|
|
3052
|
-
|
|
3053
|
-
|
|
1786
|
+
process.stdout.write(bottom + `
|
|
3054
1787
|
`);
|
|
3055
|
-
|
|
1788
|
+
}
|
|
3056
1789
|
|
|
3057
|
-
|
|
3058
|
-
|
|
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
|
-
|
|
1818
|
+
return { agents: labels, configs };
|
|
1819
|
+
}
|
|
3061
1820
|
|
|
3062
|
-
|
|
3063
|
-
|
|
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(
|
|
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(`
|
|
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(`
|
|
1836
|
+
process.stdout.write(` uninstall Remove the Juspay MCP + skills from all agents
|
|
3080
1837
|
`);
|
|
3081
|
-
process.stdout.write(`
|
|
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
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3140
|
-
|
|
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
|
-
` +
|
|
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
|
|
3184
|
-
|
|
3185
|
-
|
|
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
|
|
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
|
-
` +
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
3235
|
-
showHelp(underNpx);
|
|
1913
|
+
showHelp();
|
|
3236
1914
|
return;
|
|
3237
1915
|
}
|
|
1916
|
+
banner();
|
|
3238
1917
|
if (command === "uninstall") {
|
|
3239
|
-
|
|
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
|
-
|
|
3277
|
-
|
|
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
|
-
|
|
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(
|
|
1935
|
+
process.stderr.write(import_picocolors2.default.red("✗ ") + message + `
|
|
3322
1936
|
`);
|
|
3323
1937
|
process.exit(1);
|
|
3324
1938
|
});
|