mpd-llm-cli 0.1.25 → 0.1.31

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/bundle/gemini.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { createRequire } from 'module'; const require = createRequire(import.meta.url); globalThis.__filename = require('url').fileURLToPath(import.meta.url); globalThis.__dirname = require('path').dirname(globalThis.__filename);
2
+ import { createRequire } from 'module'; const require = createRequire(import.meta.url); globalThis.require = require; globalThis.__filename = require('url').fileURLToPath(import.meta.url); globalThis.__dirname = require('path').dirname(globalThis.__filename);
3
3
  var __create = Object.create;
4
4
  var __defProp = Object.defineProperty;
5
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -70110,10 +70110,10 @@ async function cacheCredentials(credentials) {
70110
70110
  await fs7.writeFile(filePath, credString);
70111
70111
  }
70112
70112
  function getCachedCredentialPath() {
70113
- return path2.join(os3.homedir(), GEMINI_DIR, CREDENTIAL_FILENAME);
70113
+ return path2.join(os3.homedir(), MPDAI_DIR, CREDENTIAL_FILENAME);
70114
70114
  }
70115
70115
  function getGoogleAccountIdCachePath() {
70116
- return path2.join(os3.homedir(), GEMINI_DIR, GOOGLE_ACCOUNT_ID_FILENAME);
70116
+ return path2.join(os3.homedir(), MPDAI_DIR, GOOGLE_ACCOUNT_ID_FILENAME);
70117
70117
  }
70118
70118
  async function cacheGoogleAccountId(googleAccountId) {
70119
70119
  const filePath = getGoogleAccountIdCachePath();
@@ -70168,7 +70168,7 @@ async function getRawGoogleAccountId(client) {
70168
70168
  return null;
70169
70169
  }
70170
70170
  }
70171
- var import_google_auth_library2, OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET, OAUTH_SCOPE, HTTP_REDIRECT, SIGN_IN_SUCCESS_URL, SIGN_IN_FAILURE_URL, GEMINI_DIR, CREDENTIAL_FILENAME, GOOGLE_ACCOUNT_ID_FILENAME;
70171
+ var import_google_auth_library2, OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET, OAUTH_SCOPE, HTTP_REDIRECT, SIGN_IN_SUCCESS_URL, SIGN_IN_FAILURE_URL, MPDAI_DIR, CREDENTIAL_FILENAME, GOOGLE_ACCOUNT_ID_FILENAME;
70172
70172
  var init_oauth2 = __esm({
70173
70173
  "packages/core/dist/src/code_assist/oauth2.js"() {
70174
70174
  "use strict";
@@ -70186,7 +70186,7 @@ var init_oauth2 = __esm({
70186
70186
  HTTP_REDIRECT = 301;
70187
70187
  SIGN_IN_SUCCESS_URL = "https://developers.google.com/gemini-code-assist/auth_success_gemini";
70188
70188
  SIGN_IN_FAILURE_URL = "https://developers.google.com/gemini-code-assist/auth_failure_gemini";
70189
- GEMINI_DIR = ".gemini";
70189
+ MPDAI_DIR = ".mpdai";
70190
70190
  CREDENTIAL_FILENAME = "oauth_creds.json";
70191
70191
  GOOGLE_ACCOUNT_ID_FILENAME = "google_account_id";
70192
70192
  }
@@ -70520,7 +70520,7 @@ var init_setup = __esm({
70520
70520
  init_server();
70521
70521
  ProjectIdRequiredError = class extends Error {
70522
70522
  constructor() {
70523
- super("This account requires setting the GOOGLE_CLOUD_PROJECT env var. See https://goo.gle/gemini-cli-auth-docs#workspace-gca");
70523
+ super("This account requires setting the GOOGLE_CLOUD_PROJECT env var. See https://git.rakuten-it.com/projects/MPD-AI/repos/mpd-llm-cli/browse/docs/cli/authentication.md");
70524
70524
  }
70525
70525
  };
70526
70526
  }
@@ -78281,7 +78281,7 @@ async function createContentGeneratorConfig(model, authType) {
78281
78281
  return contentGeneratorConfig;
78282
78282
  }
78283
78283
  async function createContentGenerator(config2, sessionId2) {
78284
- const version3 = "0.1.25";
78284
+ const version3 = "0.1.31";
78285
78285
  const httpOptions = {
78286
78286
  headers: {
78287
78287
  "User-Agent": `GeminiCLI/${version3} (${process.platform}; ${process.arch})`
@@ -92912,6 +92912,12 @@ function _sanitizeParameters(schema, visited) {
92912
92912
  return;
92913
92913
  }
92914
92914
  visited.add(schema);
92915
+ if ("$schema" in schema) {
92916
+ delete schema.$schema;
92917
+ }
92918
+ if ("additionalProperties" in schema) {
92919
+ delete schema.additionalProperties;
92920
+ }
92915
92921
  if (schema.anyOf) {
92916
92922
  schema.default = void 0;
92917
92923
  for (const item of schema.anyOf) {
@@ -99694,13 +99700,13 @@ function getProjectHash(projectRoot) {
99694
99700
  }
99695
99701
  function getProjectTempDir(projectRoot) {
99696
99702
  const hash = getProjectHash(projectRoot);
99697
- return path4.join(os4.homedir(), GEMINI_DIR2, TMP_DIR_NAME, hash);
99703
+ return path4.join(os4.homedir(), MPDAI_DIR2, TMP_DIR_NAME, hash);
99698
99704
  }
99699
- var GEMINI_DIR2, TMP_DIR_NAME;
99705
+ var MPDAI_DIR2, TMP_DIR_NAME;
99700
99706
  var init_paths = __esm({
99701
99707
  "packages/core/dist/src/utils/paths.js"() {
99702
99708
  "use strict";
99703
- GEMINI_DIR2 = ".gemini";
99709
+ MPDAI_DIR2 = ".mpdai";
99704
99710
  TMP_DIR_NAME = "tmp";
99705
99711
  }
99706
99712
  });
@@ -110591,7 +110597,7 @@ var init_read_file = __esm({
110591
110597
  const fileService = this.config.getFileService();
110592
110598
  if (fileService.shouldGeminiIgnoreFile(params.absolute_path)) {
110593
110599
  const relativePath = makeRelative(params.absolute_path, this.rootDirectory);
110594
- return `File path '${shortenPath(relativePath)}' is ignored by .geminiignore pattern(s).`;
110600
+ return `File path '${shortenPath(relativePath)}' is ignored by .mpdaiignore pattern(s).`;
110595
110601
  }
110596
110602
  return null;
110597
110603
  }
@@ -119027,7 +119033,7 @@ function getAllGeminiMdFilenames() {
119027
119033
  return [currentGeminiMdFilename];
119028
119034
  }
119029
119035
  function getGlobalMemoryFilePath() {
119030
- return path13.join(homedir2(), GEMINI_CONFIG_DIR, getCurrentGeminiMdFilename());
119036
+ return path13.join(homedir2(), MPDAI_CONFIG_DIR, getCurrentGeminiMdFilename());
119031
119037
  }
119032
119038
  function ensureNewlineSeparation(currentContent) {
119033
119039
  if (currentContent.length === 0)
@@ -119038,7 +119044,7 @@ function ensureNewlineSeparation(currentContent) {
119038
119044
  return "\n";
119039
119045
  return "\n\n";
119040
119046
  }
119041
- var memoryToolSchemaData, memoryToolDescription, GEMINI_CONFIG_DIR, DEFAULT_CONTEXT_FILENAME, MEMORY_SECTION_HEADER, currentGeminiMdFilename, MemoryTool;
119047
+ var memoryToolSchemaData, memoryToolDescription, MPDAI_CONFIG_DIR, DEFAULT_CONTEXT_FILENAME, MEMORY_SECTION_HEADER, currentGeminiMdFilename, MemoryTool;
119042
119048
  var init_memoryTool = __esm({
119043
119049
  "packages/core/dist/src/tools/memoryTool.js"() {
119044
119050
  "use strict";
@@ -119076,7 +119082,7 @@ Do NOT use this tool:
119076
119082
 
119077
119083
  - \`fact\` (string, required): The specific fact or piece of information to remember. This should be a clear, self-contained statement. For example, if the user says "My favorite color is blue", the fact would be "My favorite color is blue".
119078
119084
  `;
119079
- GEMINI_CONFIG_DIR = ".gemini";
119085
+ MPDAI_CONFIG_DIR = ".mpdai";
119080
119086
  DEFAULT_CONTEXT_FILENAME = "MEMORY.md";
119081
119087
  MEMORY_SECTION_HEADER = "## Memory Added Memories";
119082
119088
  currentGeminiMdFilename = DEFAULT_CONTEXT_FILENAME;
@@ -119303,7 +119309,7 @@ Use this tool when the user's query implies needing the content of several files
119303
119309
  if (this.geminiIgnorePatterns.length > 0) {
119304
119310
  const geminiPatternsInEffect = this.geminiIgnorePatterns.filter((p) => finalExclusionPatternsForDescription.includes(p)).length;
119305
119311
  if (geminiPatternsInEffect > 0) {
119306
- excludeDesc += ` (includes ${geminiPatternsInEffect} from .geminiignore)`;
119312
+ excludeDesc += ` (includes ${geminiPatternsInEffect} from .mpdaiignore)`;
119307
119313
  }
119308
119314
  }
119309
119315
  return `Will attempt to read and concatenate files ${pathDesc}. ${excludeDesc}. File encoding: ${DEFAULT_ENCODING}. Separator: "${DEFAULT_OUTPUT_SEPARATOR_FORMAT.replace("{filePath}", "path/to/file.ext")}".`;
@@ -121479,8 +121485,8 @@ function many(p) {
121479
121485
  function many1(p) {
121480
121486
  return ab(p, many(p), (head, tail) => [head, ...tail]);
121481
121487
  }
121482
- function ab(pa, pb, join24) {
121483
- return (data, i) => mapOuter(pa(data, i), (ma) => mapInner(pb(data, ma.position), (vb, j) => join24(ma.value, vb, data, i, j)));
121488
+ function ab(pa, pb, join25) {
121489
+ return (data, i) => mapOuter(pa(data, i), (ma) => mapInner(pb(data, ma.position), (vb, j) => join25(ma.value, vb, data, i, j)));
121484
121490
  }
121485
121491
  function left(pa, pb) {
121486
121492
  return ab(pa, pb, (va) => va);
@@ -121488,8 +121494,8 @@ function left(pa, pb) {
121488
121494
  function right(pa, pb) {
121489
121495
  return ab(pa, pb, (va, vb) => vb);
121490
121496
  }
121491
- function abc(pa, pb, pc, join24) {
121492
- return (data, i) => mapOuter(pa(data, i), (ma) => mapOuter(pb(data, ma.position), (mb) => mapInner(pc(data, mb.position), (vc, j) => join24(ma.value, mb.value, vc, data, i, j))));
121497
+ function abc(pa, pb, pc, join25) {
121498
+ return (data, i) => mapOuter(pa(data, i), (ma) => mapOuter(pb(data, ma.position), (mb) => mapInner(pc(data, mb.position), (vc, j) => join25(ma.value, mb.value, vc, data, i, j))));
121493
121499
  }
121494
121500
  function middle(pa, pb, pc) {
121495
121501
  return abc(pa, pb, pc, (ra, rb) => rb);
@@ -126454,6 +126460,991 @@ ${modifiedResponseText}`,
126454
126460
  }
126455
126461
  });
126456
126462
 
126463
+ // packages/core/dist/src/tools/confluence-get-page.js
126464
+ var CONFLUENCE_FETCH_TIMEOUT_MS, CONFLUENCE_URL, ConfluenceGetPageTool;
126465
+ var init_confluence_get_page = __esm({
126466
+ "packages/core/dist/src/tools/confluence-get-page.js"() {
126467
+ "use strict";
126468
+ init_schemaValidator();
126469
+ init_tools();
126470
+ init_node();
126471
+ init_errors();
126472
+ CONFLUENCE_FETCH_TIMEOUT_MS = 3e4;
126473
+ CONFLUENCE_URL = "https://confluence.rakuten-it.com/confluence";
126474
+ ConfluenceGetPageTool = class _ConfluenceGetPageTool extends BaseTool {
126475
+ config;
126476
+ static Name = "confluence_get_page";
126477
+ constructor(config2) {
126478
+ super(_ConfluenceGetPageTool.Name, "ConfluenceGetPage", "Retrieves content from a Confluence page by its ID. Uses Personal Access Token from keys.json for authentication and can convert HTML content to markdown.", {
126479
+ properties: {
126480
+ page_id: {
126481
+ description: "The ID of the Confluence page to retrieve",
126482
+ type: Type.STRING
126483
+ },
126484
+ convert_to_markdown: {
126485
+ description: "Whether to convert HTML content to markdown format (default: true)",
126486
+ type: Type.STRING
126487
+ }
126488
+ },
126489
+ required: ["page_id"],
126490
+ type: Type.OBJECT
126491
+ });
126492
+ this.config = config2;
126493
+ }
126494
+ validateParams(params) {
126495
+ const errors = SchemaValidator.validate(this.schema.parameters, params);
126496
+ if (errors) {
126497
+ return errors;
126498
+ }
126499
+ if (!params.page_id || params.page_id.trim() === "") {
126500
+ return "The 'page_id' parameter cannot be empty.";
126501
+ }
126502
+ return null;
126503
+ }
126504
+ getDescription(params) {
126505
+ return `Retrieving Confluence page ${params.page_id} from ${CONFLUENCE_URL}`;
126506
+ }
126507
+ /**
126508
+ * Process HTML content to handle user mentions and page links
126509
+ */
126510
+ processHtmlContent(html, spaceKey, baseUrl) {
126511
+ let processed = html;
126512
+ processed = processed.replace(/<ac:link>[\s\S]*?<ri:user[^>]+ri:username="([^"]+)"\s*\/>[\s\S]*?<\/ac:link>/g, "@$1");
126513
+ processed = processed.replace(/<ac:link[^>]*>[\s\S]*?<ri:page[^>]+ri:content-title="([^"]*)"\s*ri:space-key="([^"]*)"\s*\/>[\s\S]*?<\/ac:link>/g, (match2, title) => {
126514
+ return title || "Page Link";
126515
+ });
126516
+ processed = processed.replace(/<\/?(span|div|p)[^>]*>/g, "\n");
126517
+ processed = processed.replace(/<strong>([^<]*)<\/strong>/g, "**$1**");
126518
+ processed = processed.replace(/<b>([^<]*)<\/b>/g, "**$1**");
126519
+ processed = processed.replace(/<em>([^<]*)<\/em>/g, "*$1*");
126520
+ processed = processed.replace(/<i>([^<]*)<\/i>/g, "*$1*");
126521
+ for (let i = 1; i <= 6; i++) {
126522
+ const tag = `h${i}`;
126523
+ const prefix = "#".repeat(i);
126524
+ processed = processed.replace(new RegExp(`<${tag}>([^<]*)</${tag}>`, "g"), `${prefix} $1`);
126525
+ }
126526
+ processed = processed.replace(/<li>([^<]*)<\/li>/g, "- $1\n");
126527
+ processed = processed.replace(/<ul[^>]*>/g, "\n");
126528
+ processed = processed.replace(/<\/ul>/g, "\n");
126529
+ processed = processed.replace(/<ol[^>]*>/g, "\n");
126530
+ processed = processed.replace(/<\/ol>/g, "\n");
126531
+ processed = processed.replace(/<a[^>]+href="([^"]*)"[^>]*>([^<]*)<\/a>/g, "[$2]($1)");
126532
+ processed = processed.replace(/<[^>]+>/g, "");
126533
+ processed = processed.replace(/\n{3,}/g, "\n\n");
126534
+ return processed.trim();
126535
+ }
126536
+ async execute(params, signal) {
126537
+ const validationError = this.validateParams(params);
126538
+ if (validationError) {
126539
+ return {
126540
+ llmContent: `Error: Invalid parameters provided. Reason: ${validationError}`,
126541
+ returnDisplay: validationError
126542
+ };
126543
+ }
126544
+ const { page_id, convert_to_markdown = true } = params;
126545
+ const personal_access_token = this.config.getConfluenceToken();
126546
+ if (!personal_access_token) {
126547
+ return {
126548
+ llmContent: "Error: Confluence Personal Access Token not found in keys.json. Please configure it first.",
126549
+ returnDisplay: "Confluence token not configured"
126550
+ };
126551
+ }
126552
+ try {
126553
+ const isCloud = CONFLUENCE_URL.includes(".atlassian.net");
126554
+ const apiUrl = `${CONFLUENCE_URL.replace(/\/$/, "")}/rest/api/content/${page_id}`;
126555
+ const paramsObj = new URLSearchParams({
126556
+ expand: "body.storage,version,space,children.attachment,ancestors"
126557
+ });
126558
+ const fullUrl = `${apiUrl}?${paramsObj.toString()}`;
126559
+ const headers = {
126560
+ "Accept": "application/json",
126561
+ "Content-Type": "application/json",
126562
+ "Authorization": `Bearer ${personal_access_token}`
126563
+ };
126564
+ const controller = new AbortController();
126565
+ const timeoutId = setTimeout(() => controller.abort(), CONFLUENCE_FETCH_TIMEOUT_MS);
126566
+ let response;
126567
+ try {
126568
+ response = await fetch(fullUrl, {
126569
+ method: "GET",
126570
+ headers,
126571
+ signal: signal || controller.signal
126572
+ });
126573
+ } finally {
126574
+ clearTimeout(timeoutId);
126575
+ }
126576
+ if (response.status === 401) {
126577
+ return {
126578
+ llmContent: "Error: Authentication failed (401). Personal Access Token may be invalid or expired.",
126579
+ returnDisplay: "Authentication failed (401)"
126580
+ };
126581
+ }
126582
+ if (response.status === 403) {
126583
+ return {
126584
+ llmContent: "Error: Access denied (403). Token may not have sufficient permissions.",
126585
+ returnDisplay: "Access denied (403)"
126586
+ };
126587
+ }
126588
+ if (response.status === 404) {
126589
+ return {
126590
+ llmContent: `Error: Page not found (404). Page ID ${page_id} may not exist.`,
126591
+ returnDisplay: `Page not found (404): ${page_id}`
126592
+ };
126593
+ }
126594
+ if (!response.ok) {
126595
+ const errorText = await response.text().catch(() => "Unknown error");
126596
+ return {
126597
+ llmContent: `Error: API call failed with status ${response.status}: ${errorText}`,
126598
+ returnDisplay: `API error (${response.status})`
126599
+ };
126600
+ }
126601
+ const pageData = await response.json();
126602
+ const content = pageData.body.storage.value;
126603
+ const spaceKey = pageData.space.key;
126604
+ const title = pageData.title;
126605
+ const version3 = pageData.version.number;
126606
+ const created = pageData.created;
126607
+ const updated = pageData.updated;
126608
+ let pageUrl;
126609
+ if (isCloud) {
126610
+ pageUrl = `${CONFLUENCE_URL}/spaces/${spaceKey}/pages/${pageData.id}`;
126611
+ } else {
126612
+ pageUrl = `${CONFLUENCE_URL}/pages/viewpage.action?pageId=${pageData.id}`;
126613
+ }
126614
+ let processedContent;
126615
+ let contentFormat;
126616
+ if (convert_to_markdown) {
126617
+ processedContent = this.processHtmlContent(content, spaceKey, CONFLUENCE_URL);
126618
+ contentFormat = "markdown";
126619
+ } else {
126620
+ processedContent = content;
126621
+ contentFormat = "storage";
126622
+ }
126623
+ const result = {
126624
+ id: pageData.id,
126625
+ title,
126626
+ type: pageData.type,
126627
+ status: pageData.status,
126628
+ created,
126629
+ updated,
126630
+ url: pageUrl,
126631
+ space: {
126632
+ key: spaceKey,
126633
+ name: pageData.space.name
126634
+ },
126635
+ version: version3,
126636
+ attachments: pageData.children?.attachment?.results || [],
126637
+ ancestors: pageData.ancestors || [],
126638
+ content: {
126639
+ value: processedContent,
126640
+ format: contentFormat
126641
+ }
126642
+ };
126643
+ const resultText = `# ${title}
126644
+
126645
+ **Page ID:** ${pageData.id}
126646
+ **Space:** ${spaceKey}
126647
+ **Version:** ${version3}
126648
+ **Created:** ${created}
126649
+ **Updated:** ${updated}
126650
+ **URL:** ${pageUrl}
126651
+
126652
+ ---
126653
+
126654
+ ${processedContent}
126655
+ `;
126656
+ return {
126657
+ llmContent: resultText,
126658
+ returnDisplay: `Retrieved Confluence page: ${title}`
126659
+ };
126660
+ } catch (error) {
126661
+ const errorMessage = `Error retrieving Confluence page ${page_id}: ${getErrorMessage(error)}`;
126662
+ console.error(errorMessage, error);
126663
+ return {
126664
+ llmContent: `Error: ${errorMessage}`,
126665
+ returnDisplay: `Error: ${errorMessage}`
126666
+ };
126667
+ }
126668
+ }
126669
+ };
126670
+ }
126671
+ });
126672
+
126673
+ // packages/core/dist/src/tools/jira-get-issue.js
126674
+ var JIRA_FETCH_TIMEOUT_MS, JIRA_URL, JiraGetIssueTool;
126675
+ var init_jira_get_issue = __esm({
126676
+ "packages/core/dist/src/tools/jira-get-issue.js"() {
126677
+ "use strict";
126678
+ init_schemaValidator();
126679
+ init_tools();
126680
+ init_node();
126681
+ init_errors();
126682
+ JIRA_FETCH_TIMEOUT_MS = 3e4;
126683
+ JIRA_URL = "https://jira.rakuten-it.com/jira";
126684
+ JiraGetIssueTool = class _JiraGetIssueTool extends BaseTool {
126685
+ config;
126686
+ static Name = "jira_get_issue";
126687
+ constructor(config2) {
126688
+ super(_JiraGetIssueTool.Name, "JiraGetIssue", "Retrieves content from a Jira issue by its key. Uses Personal Access Token from keys.json for authentication.", {
126689
+ properties: {
126690
+ issue_key: {
126691
+ description: "The Jira issue key to retrieve (e.g., PROJECT-123)",
126692
+ type: Type.STRING
126693
+ },
126694
+ expand: {
126695
+ description: 'Fields to expand in the response (e.g., "renderedFields,changelog")',
126696
+ type: Type.STRING
126697
+ },
126698
+ comment_limit: {
126699
+ description: 'Maximum number of comments to include (default: 10, use "all" for all comments)',
126700
+ type: Type.STRING
126701
+ }
126702
+ },
126703
+ required: ["issue_key"],
126704
+ type: Type.OBJECT
126705
+ });
126706
+ this.config = config2;
126707
+ }
126708
+ validateParams(params) {
126709
+ const errors = SchemaValidator.validate(this.schema.parameters, params);
126710
+ if (errors) {
126711
+ return errors;
126712
+ }
126713
+ if (!params.issue_key || params.issue_key.trim() === "") {
126714
+ return "The 'issue_key' parameter cannot be empty.";
126715
+ }
126716
+ const issueKeyPattern = /^[A-Z]+-\d+$/;
126717
+ if (!issueKeyPattern.test(params.issue_key.trim())) {
126718
+ return "The 'issue_key' must be in format PROJECT-123 (e.g., PROJ-456)";
126719
+ }
126720
+ return null;
126721
+ }
126722
+ getDescription(params) {
126723
+ return `Retrieving Jira issue ${params.issue_key} from ${JIRA_URL}`;
126724
+ }
126725
+ /**
126726
+ * Normalize comment limit to a number
126727
+ */
126728
+ normalizeCommentLimit(commentLimit) {
126729
+ if (commentLimit === void 0) {
126730
+ return 10;
126731
+ }
126732
+ if (typeof commentLimit === "number") {
126733
+ return commentLimit;
126734
+ }
126735
+ if (commentLimit === "all" || commentLimit === "") {
126736
+ return null;
126737
+ }
126738
+ try {
126739
+ return parseInt(commentLimit, 10);
126740
+ } catch {
126741
+ return 10;
126742
+ }
126743
+ }
126744
+ /**
126745
+ * Convert Jira formatted text to plain text
126746
+ */
126747
+ convertJiraTextToPlainText(content) {
126748
+ if (typeof content === "string") {
126749
+ return content;
126750
+ }
126751
+ if (typeof content === "object" && content !== null) {
126752
+ const obj = content;
126753
+ if (Array.isArray(obj.content)) {
126754
+ return this.extractTextFromContent(obj.content);
126755
+ }
126756
+ }
126757
+ return "";
126758
+ }
126759
+ /**
126760
+ * Extract text from Jira content structure
126761
+ */
126762
+ extractTextFromContent(content) {
126763
+ let text = "";
126764
+ for (const item of content) {
126765
+ if (typeof item === "object" && item !== null) {
126766
+ const obj = item;
126767
+ if (obj.text) {
126768
+ text += obj.text;
126769
+ }
126770
+ if (obj.content && Array.isArray(obj.content)) {
126771
+ text += this.extractTextFromContent(obj.content);
126772
+ }
126773
+ }
126774
+ }
126775
+ return text;
126776
+ }
126777
+ /**
126778
+ * Format date string
126779
+ */
126780
+ formatDate(dateStr) {
126781
+ if (!dateStr) {
126782
+ return "";
126783
+ }
126784
+ try {
126785
+ const date = new Date(dateStr);
126786
+ return date.toLocaleString();
126787
+ } catch {
126788
+ return dateStr;
126789
+ }
126790
+ }
126791
+ async execute(params, signal) {
126792
+ const validationError = this.validateParams(params);
126793
+ if (validationError) {
126794
+ return {
126795
+ llmContent: `Error: Invalid parameters provided. Reason: ${validationError}`,
126796
+ returnDisplay: validationError
126797
+ };
126798
+ }
126799
+ const { issue_key, expand: expand2, comment_limit } = params;
126800
+ const personal_access_token = this.config.getJiraToken();
126801
+ if (!personal_access_token) {
126802
+ return {
126803
+ llmContent: "Error: Jira Personal Access Token not found in keys.json. Please configure it first.",
126804
+ returnDisplay: "Jira token not configured"
126805
+ };
126806
+ }
126807
+ try {
126808
+ const apiUrl = `${JIRA_URL}/rest/api/2/issue/${issue_key}`;
126809
+ const queryParams = new URLSearchParams();
126810
+ const expandParams = expand2 ? expand2.split(",").map((s2) => s2.trim()) : [];
126811
+ if (!expandParams.includes("renderedFields")) {
126812
+ expandParams.push("renderedFields");
126813
+ }
126814
+ if (expandParams.length > 0) {
126815
+ queryParams.set("expand", expandParams.join(","));
126816
+ }
126817
+ const fullUrl = `${apiUrl}?${queryParams.toString()}`;
126818
+ const headers = {
126819
+ "Accept": "application/json",
126820
+ "Content-Type": "application/json",
126821
+ "Authorization": `Bearer ${personal_access_token}`
126822
+ };
126823
+ console.log("Jira API request:", {
126824
+ url: fullUrl,
126825
+ authMethod: "Bearer",
126826
+ tokenLength: personal_access_token.length,
126827
+ headers: { ...headers, Authorization: "Bearer ***" }
126828
+ });
126829
+ const controller = new AbortController();
126830
+ const timeoutId = setTimeout(() => controller.abort(), JIRA_FETCH_TIMEOUT_MS);
126831
+ let response;
126832
+ try {
126833
+ response = await fetch(fullUrl, {
126834
+ method: "GET",
126835
+ headers,
126836
+ signal: signal || controller.signal
126837
+ });
126838
+ } finally {
126839
+ clearTimeout(timeoutId);
126840
+ }
126841
+ if (response.status === 401) {
126842
+ return {
126843
+ llmContent: "Error: Authentication failed (401). Personal Access Token may be invalid or expired.",
126844
+ returnDisplay: "Authentication failed (401)"
126845
+ };
126846
+ }
126847
+ if (response.status === 403) {
126848
+ return {
126849
+ llmContent: "Error: Access denied (403). Token may not have sufficient permissions.",
126850
+ returnDisplay: "Access denied (403)"
126851
+ };
126852
+ }
126853
+ if (response.status === 404) {
126854
+ return {
126855
+ llmContent: `Error: Issue not found (404). Issue key ${issue_key} may not exist.`,
126856
+ returnDisplay: `Issue not found (404): ${issue_key}`
126857
+ };
126858
+ }
126859
+ if (!response.ok) {
126860
+ const errorText = await response.text().catch(() => "Unknown error");
126861
+ console.error(`Jira API error (${response.status}):`, errorText.substring(0, 500));
126862
+ return {
126863
+ llmContent: `Error: API call failed with status ${response.status}: ${errorText.substring(0, 200)}`,
126864
+ returnDisplay: `API error (${response.status})`
126865
+ };
126866
+ }
126867
+ const contentType = response.headers.get("content-type") || "";
126868
+ if (!contentType.includes("application/json")) {
126869
+ const responseText = await response.text();
126870
+ console.error("Jira API returned non-JSON response:", responseText.substring(0, 500));
126871
+ return {
126872
+ llmContent: "Error: Jira API returned non-JSON response. This usually means authentication failed. Please check your Personal Access Token in keys.json.",
126873
+ returnDisplay: "Authentication failed - invalid response format"
126874
+ };
126875
+ }
126876
+ const issueData = await response.json();
126877
+ const fields = issueData.fields || {};
126878
+ const summary = fields.summary || "";
126879
+ const status = fields.status?.name || "Unknown";
126880
+ const issueType = fields.issuetype?.name || "Unknown";
126881
+ const created = this.formatDate(fields.created);
126882
+ const updated = this.formatDate(fields.updated);
126883
+ const assignee = fields.assignee?.displayName || fields.assignee?.name || "Unassigned";
126884
+ const reporter = fields.reporter?.displayName || fields.reporter?.name || "Unknown";
126885
+ const description = this.convertJiraTextToPlainText(fields.description);
126886
+ const comments = fields.comment?.comments || [];
126887
+ const normalizedCommentLimit = this.normalizeCommentLimit(comment_limit);
126888
+ const limitedComments = normalizedCommentLimit !== null ? comments.slice(0, normalizedCommentLimit) : comments;
126889
+ const issueUrl = `${JIRA_URL}/browse/${issue_key}`;
126890
+ let resultText = `# ${issue_key}: ${summary}
126891
+
126892
+ `;
126893
+ resultText += `**Type**: ${issueType}
126894
+ `;
126895
+ resultText += `**Status**: ${status}
126896
+ `;
126897
+ resultText += `**Reporter**: ${reporter}
126898
+ `;
126899
+ resultText += `**Assignee**: ${assignee}
126900
+ `;
126901
+ resultText += `**Created**: ${created}
126902
+ `;
126903
+ resultText += `**Updated**: ${updated}
126904
+ `;
126905
+ resultText += `**URL**: ${issueUrl}
126906
+
126907
+ `;
126908
+ if (description) {
126909
+ resultText += `## Description
126910
+
126911
+ ${description}
126912
+
126913
+ `;
126914
+ }
126915
+ if (limitedComments.length > 0) {
126916
+ resultText += `## Comments (${limitedComments.length}${normalizedCommentLimit !== null ? ` of ${comments.length}` : ""})
126917
+
126918
+ `;
126919
+ for (const comment of limitedComments) {
126920
+ const commentAuthor = comment.author?.displayName || comment.author?.name || "Unknown";
126921
+ const commentBody = this.convertJiraTextToPlainText(comment.body);
126922
+ const commentCreated = this.formatDate(comment.created);
126923
+ if (commentBody) {
126924
+ resultText += `**${commentAuthor}** (${commentCreated}):
126925
+ ${commentBody}
126926
+
126927
+ `;
126928
+ }
126929
+ }
126930
+ }
126931
+ return {
126932
+ llmContent: resultText,
126933
+ returnDisplay: `Retrieved Jira issue: ${issue_key}`
126934
+ };
126935
+ } catch (error) {
126936
+ const errorMessage = `Error retrieving Jira issue ${issue_key}: ${getErrorMessage(error)}`;
126937
+ console.error(errorMessage, error);
126938
+ return {
126939
+ llmContent: `Error: ${errorMessage}`,
126940
+ returnDisplay: `Error: ${errorMessage}`
126941
+ };
126942
+ }
126943
+ }
126944
+ };
126945
+ }
126946
+ });
126947
+
126948
+ // packages/core/dist/src/tools/bitbucket-get-pr-diff.js
126949
+ var BITBUCKET_FETCH_TIMEOUT_MS, BITBUCKET_URL, BitbucketGetPrDiffTool;
126950
+ var init_bitbucket_get_pr_diff = __esm({
126951
+ "packages/core/dist/src/tools/bitbucket-get-pr-diff.js"() {
126952
+ "use strict";
126953
+ init_schemaValidator();
126954
+ init_tools();
126955
+ init_node();
126956
+ init_errors();
126957
+ BITBUCKET_FETCH_TIMEOUT_MS = 3e4;
126958
+ BITBUCKET_URL = "https://git.rakuten-it.com";
126959
+ BitbucketGetPrDiffTool = class _BitbucketGetPrDiffTool extends BaseTool {
126960
+ config;
126961
+ static Name = "bitbucket_get_pr_diff";
126962
+ constructor(config2) {
126963
+ super(_BitbucketGetPrDiffTool.Name, "BitbucketGetPrDiff", "Retrieves the diff content for a specified Bitbucket Pull Request. Uses Personal Access Token from keys.json for authentication.", {
126964
+ properties: {
126965
+ project_key: {
126966
+ description: "The unique identifier for the Bitbucket project that owns the PR",
126967
+ type: Type.STRING
126968
+ },
126969
+ repo_slug: {
126970
+ description: "The repository slug name that owns the PR",
126971
+ type: Type.STRING
126972
+ },
126973
+ pr_id: {
126974
+ description: "The Pull Request unique identifier",
126975
+ type: Type.NUMBER
126976
+ }
126977
+ },
126978
+ required: ["project_key", "repo_slug", "pr_id"],
126979
+ type: Type.OBJECT
126980
+ });
126981
+ this.config = config2;
126982
+ }
126983
+ validateParams(params) {
126984
+ const errors = SchemaValidator.validate(this.schema.parameters, params);
126985
+ if (errors) {
126986
+ return errors;
126987
+ }
126988
+ if (!params.project_key || params.project_key.trim() === "") {
126989
+ return "The 'project_key' parameter cannot be empty.";
126990
+ }
126991
+ if (!params.repo_slug || params.repo_slug.trim() === "") {
126992
+ return "The 'repo_slug' parameter cannot be empty.";
126993
+ }
126994
+ if (params.pr_id <= 0) {
126995
+ return "The 'pr_id' must be a positive number.";
126996
+ }
126997
+ return null;
126998
+ }
126999
+ getDescription(params) {
127000
+ return `Retrieving diff for Bitbucket PR #${params.pr_id} in ${params.project_key}/${params.repo_slug}`;
127001
+ }
127002
+ async execute(params, signal) {
127003
+ const validationError = this.validateParams(params);
127004
+ if (validationError) {
127005
+ return {
127006
+ llmContent: `Error: Invalid parameters provided. Reason: ${validationError}`,
127007
+ returnDisplay: validationError
127008
+ };
127009
+ }
127010
+ const { project_key, repo_slug, pr_id } = params;
127011
+ const personal_access_token = this.config.getBitbucketToken();
127012
+ if (!personal_access_token) {
127013
+ return {
127014
+ llmContent: "Error: Bitbucket Personal Access Token not found in keys.json. Please configure it first.",
127015
+ returnDisplay: "Bitbucket token not configured"
127016
+ };
127017
+ }
127018
+ try {
127019
+ const apiUrl = `${BITBUCKET_URL}/rest/api/1.0/projects/${project_key}/repos/${repo_slug}/pull-requests/${pr_id}/diff`;
127020
+ const headers = {
127021
+ "Authorization": `Bearer ${personal_access_token}`,
127022
+ "Accept": "text/plain"
127023
+ };
127024
+ console.log("Bitbucket API request:", {
127025
+ url: apiUrl,
127026
+ authMethod: "Bearer",
127027
+ tokenLength: personal_access_token.length,
127028
+ headers: { ...headers, Authorization: "Bearer ***" }
127029
+ });
127030
+ const controller = new AbortController();
127031
+ const timeoutId = setTimeout(() => controller.abort(), BITBUCKET_FETCH_TIMEOUT_MS);
127032
+ let response;
127033
+ try {
127034
+ response = await fetch(apiUrl, {
127035
+ method: "GET",
127036
+ headers,
127037
+ signal: signal || controller.signal
127038
+ });
127039
+ } finally {
127040
+ clearTimeout(timeoutId);
127041
+ }
127042
+ if (response.status === 401) {
127043
+ return {
127044
+ llmContent: "Error: Authentication failed (401). Personal Access Token may be invalid or expired.",
127045
+ returnDisplay: "Authentication failed (401)"
127046
+ };
127047
+ }
127048
+ if (response.status === 403) {
127049
+ return {
127050
+ llmContent: "Error: Access denied (403). Token may not have sufficient permissions.",
127051
+ returnDisplay: "Access denied (403)"
127052
+ };
127053
+ }
127054
+ if (response.status === 404) {
127055
+ return {
127056
+ llmContent: `Error: Pull Request not found (404). PR #${pr_id} in ${project_key}/${repo_slug} may not exist.`,
127057
+ returnDisplay: `PR not found (404): #${pr_id}`
127058
+ };
127059
+ }
127060
+ if (!response.ok) {
127061
+ const errorText = await response.text().catch(() => "Unknown error");
127062
+ console.error(`Bitbucket API error (${response.status}):`, errorText.substring(0, 500));
127063
+ return {
127064
+ llmContent: `Error: API call failed with status ${response.status}: ${errorText.substring(0, 200)}`,
127065
+ returnDisplay: `API error (${response.status})`
127066
+ };
127067
+ }
127068
+ const diffText = await response.text();
127069
+ let resultText = `# Pull Request Diff: ${project_key}/${repo_slug}#${pr_id}
127070
+
127071
+ `;
127072
+ resultText += `\`\`\`diff
127073
+ ${diffText}
127074
+ \`\`\``;
127075
+ return {
127076
+ llmContent: resultText,
127077
+ returnDisplay: `Retrieved diff for Bitbucket PR #${pr_id}`
127078
+ };
127079
+ } catch (error) {
127080
+ const errorMessage = `Error retrieving Bitbucket PR diff ${project_key}/${repo_slug}#${pr_id}: ${getErrorMessage(error)}`;
127081
+ console.error(errorMessage, error);
127082
+ return {
127083
+ llmContent: `Error: ${errorMessage}`,
127084
+ returnDisplay: `Error: ${errorMessage}`
127085
+ };
127086
+ }
127087
+ }
127088
+ };
127089
+ }
127090
+ });
127091
+
127092
+ // packages/core/dist/src/tools/bitbucket-add-pr-comment.js
127093
+ var BITBUCKET_FETCH_TIMEOUT_MS2, BITBUCKET_URL2, BitbucketAddPrCommentTool;
127094
+ var init_bitbucket_add_pr_comment = __esm({
127095
+ "packages/core/dist/src/tools/bitbucket-add-pr-comment.js"() {
127096
+ "use strict";
127097
+ init_schemaValidator();
127098
+ init_tools();
127099
+ init_node();
127100
+ init_errors();
127101
+ BITBUCKET_FETCH_TIMEOUT_MS2 = 3e4;
127102
+ BITBUCKET_URL2 = "https://git.rakuten-it.com";
127103
+ BitbucketAddPrCommentTool = class _BitbucketAddPrCommentTool extends BaseTool {
127104
+ config;
127105
+ static Name = "bitbucket_add_pr_comment";
127106
+ constructor(config2) {
127107
+ super(_BitbucketAddPrCommentTool.Name, "BitbucketAddPrComment", "Adds a general comment to a specified Bitbucket Pull Request. Uses Personal Access Token from keys.json for authentication.", {
127108
+ properties: {
127109
+ project_key: {
127110
+ description: "The unique identifier for the Bitbucket project that owns the PR",
127111
+ type: Type.STRING
127112
+ },
127113
+ repo_slug: {
127114
+ description: "The repository slug name that owns the PR",
127115
+ type: Type.STRING
127116
+ },
127117
+ pr_id: {
127118
+ description: "The Pull Request unique identifier",
127119
+ type: Type.NUMBER
127120
+ },
127121
+ comment_text: {
127122
+ description: "The text content of the comment to add",
127123
+ type: Type.STRING
127124
+ }
127125
+ },
127126
+ required: ["project_key", "repo_slug", "pr_id", "comment_text"],
127127
+ type: Type.OBJECT
127128
+ });
127129
+ this.config = config2;
127130
+ }
127131
+ validateParams(params) {
127132
+ const errors = SchemaValidator.validate(this.schema.parameters, params);
127133
+ if (errors) {
127134
+ return errors;
127135
+ }
127136
+ if (!params.project_key || params.project_key.trim() === "") {
127137
+ return "The 'project_key' parameter cannot be empty.";
127138
+ }
127139
+ if (!params.repo_slug || params.repo_slug.trim() === "") {
127140
+ return "The 'repo_slug' parameter cannot be empty.";
127141
+ }
127142
+ if (params.pr_id <= 0) {
127143
+ return "The 'pr_id' must be a positive number.";
127144
+ }
127145
+ if (!params.comment_text || params.comment_text.trim() === "") {
127146
+ return "The 'comment_text' parameter cannot be empty.";
127147
+ }
127148
+ return null;
127149
+ }
127150
+ getDescription(params) {
127151
+ return `Adding comment to Bitbucket PR #${params.pr_id} in ${params.project_key}/${params.repo_slug}`;
127152
+ }
127153
+ async execute(params, signal) {
127154
+ const validationError = this.validateParams(params);
127155
+ if (validationError) {
127156
+ return {
127157
+ llmContent: `Error: Invalid parameters provided. Reason: ${validationError}`,
127158
+ returnDisplay: validationError
127159
+ };
127160
+ }
127161
+ const { project_key, repo_slug, pr_id, comment_text } = params;
127162
+ const personal_access_token = this.config.getBitbucketToken();
127163
+ if (!personal_access_token) {
127164
+ return {
127165
+ llmContent: "Error: Bitbucket Personal Access Token not found in keys.json. Please configure it first.",
127166
+ returnDisplay: "Bitbucket token not configured"
127167
+ };
127168
+ }
127169
+ try {
127170
+ const apiUrl = `${BITBUCKET_URL2}/rest/api/latest/projects/${project_key}/repos/${repo_slug}/pull-requests/${pr_id}/comments`;
127171
+ const headers = {
127172
+ "Authorization": `Bearer ${personal_access_token}`,
127173
+ "Content-Type": "application/json"
127174
+ };
127175
+ const payload = {
127176
+ text: comment_text
127177
+ };
127178
+ console.log("Bitbucket API request:", {
127179
+ url: apiUrl,
127180
+ method: "POST",
127181
+ authMethod: "Bearer",
127182
+ tokenLength: personal_access_token.length,
127183
+ headers: { ...headers, Authorization: "Bearer ***" }
127184
+ });
127185
+ const controller = new AbortController();
127186
+ const timeoutId = setTimeout(() => controller.abort(), BITBUCKET_FETCH_TIMEOUT_MS2);
127187
+ let response;
127188
+ try {
127189
+ response = await fetch(apiUrl, {
127190
+ method: "POST",
127191
+ headers,
127192
+ body: JSON.stringify(payload),
127193
+ signal: signal || controller.signal
127194
+ });
127195
+ } finally {
127196
+ clearTimeout(timeoutId);
127197
+ }
127198
+ if (response.status === 401) {
127199
+ return {
127200
+ llmContent: "Error: Authentication failed (401). Personal Access Token may be invalid or expired.",
127201
+ returnDisplay: "Authentication failed (401)"
127202
+ };
127203
+ }
127204
+ if (response.status === 403) {
127205
+ return {
127206
+ llmContent: "Error: Access denied (403). Token may not have sufficient permissions.",
127207
+ returnDisplay: "Access denied (403)"
127208
+ };
127209
+ }
127210
+ if (response.status === 404) {
127211
+ return {
127212
+ llmContent: `Error: Pull Request not found (404). PR #${pr_id} in ${project_key}/${repo_slug} may not exist.`,
127213
+ returnDisplay: `PR not found (404): #${pr_id}`
127214
+ };
127215
+ }
127216
+ if (!response.ok) {
127217
+ const errorText = await response.text().catch(() => "Unknown error");
127218
+ console.error(`Bitbucket API error (${response.status}):`, errorText.substring(0, 500));
127219
+ return {
127220
+ llmContent: `Error: API call failed with status ${response.status}: ${errorText.substring(0, 200)}`,
127221
+ returnDisplay: `API error (${response.status})`
127222
+ };
127223
+ }
127224
+ const responseData = await response.json();
127225
+ let resultText = `# Comment added to Pull Request: ${project_key}/${repo_slug}#${pr_id}
127226
+
127227
+ `;
127228
+ resultText += `**Comment ID**: ${responseData.id || "Unknown"}
127229
+ `;
127230
+ resultText += `**Text**: ${comment_text}
127231
+ `;
127232
+ return {
127233
+ llmContent: resultText,
127234
+ returnDisplay: `Added comment to Bitbucket PR #${pr_id}`
127235
+ };
127236
+ } catch (error) {
127237
+ const errorMessage = `Error adding comment to Bitbucket PR ${project_key}/${repo_slug}#${pr_id}: ${getErrorMessage(error)}`;
127238
+ console.error(errorMessage, error);
127239
+ return {
127240
+ llmContent: `Error: ${errorMessage}`,
127241
+ returnDisplay: `Error: ${errorMessage}`
127242
+ };
127243
+ }
127244
+ }
127245
+ };
127246
+ }
127247
+ });
127248
+
127249
+ // packages/core/dist/src/tools/bitbucket-add-pr-inline-comment.js
127250
+ var BITBUCKET_FETCH_TIMEOUT_MS3, BITBUCKET_URL3, BitbucketAddPrInlineCommentTool;
127251
+ var init_bitbucket_add_pr_inline_comment = __esm({
127252
+ "packages/core/dist/src/tools/bitbucket-add-pr-inline-comment.js"() {
127253
+ "use strict";
127254
+ init_schemaValidator();
127255
+ init_tools();
127256
+ init_node();
127257
+ init_errors();
127258
+ BITBUCKET_FETCH_TIMEOUT_MS3 = 3e4;
127259
+ BITBUCKET_URL3 = "https://git.rakuten-it.com";
127260
+ BitbucketAddPrInlineCommentTool = class _BitbucketAddPrInlineCommentTool extends BaseTool {
127261
+ config;
127262
+ static Name = "bitbucket_add_pr_inline_comment";
127263
+ constructor(config2) {
127264
+ super(_BitbucketAddPrInlineCommentTool.Name, "BitbucketAddPrInlineComment", "Adds an inline comment to a specific file and line in a Bitbucket Pull Request diff. Uses Personal Access Token from keys.json for authentication.", {
127265
+ properties: {
127266
+ project_key: {
127267
+ description: "The unique identifier for the Bitbucket project that owns the PR",
127268
+ type: Type.STRING
127269
+ },
127270
+ repo_slug: {
127271
+ description: "The repository slug name that owns the PR",
127272
+ type: Type.STRING
127273
+ },
127274
+ pr_id: {
127275
+ description: "The Pull Request unique identifier",
127276
+ type: Type.NUMBER
127277
+ },
127278
+ file_path: {
127279
+ description: "The file path relative to repository root to add comment to",
127280
+ type: Type.STRING
127281
+ },
127282
+ line: {
127283
+ description: "The line number to add comment to",
127284
+ type: Type.NUMBER
127285
+ },
127286
+ comment_text: {
127287
+ description: "The text content of the inline comment to add",
127288
+ type: Type.STRING
127289
+ },
127290
+ line_type: {
127291
+ description: "The line type, default is ADDED, optional values: ADDED, REMOVED, CONTEXT",
127292
+ type: Type.STRING
127293
+ },
127294
+ file_type: {
127295
+ description: "The file type, default is TO, optional values: TO, FROM",
127296
+ type: Type.STRING
127297
+ }
127298
+ },
127299
+ required: ["project_key", "repo_slug", "pr_id", "file_path", "line", "comment_text"],
127300
+ type: Type.OBJECT
127301
+ });
127302
+ this.config = config2;
127303
+ }
127304
+ validateParams(params) {
127305
+ const errors = SchemaValidator.validate(this.schema.parameters, params);
127306
+ if (errors) {
127307
+ return errors;
127308
+ }
127309
+ if (!params.project_key || params.project_key.trim() === "") {
127310
+ return "The 'project_key' parameter cannot be empty.";
127311
+ }
127312
+ if (!params.repo_slug || params.repo_slug.trim() === "") {
127313
+ return "The 'repo_slug' parameter cannot be empty.";
127314
+ }
127315
+ if (params.pr_id <= 0) {
127316
+ return "The 'pr_id' must be a positive number.";
127317
+ }
127318
+ if (!params.file_path || params.file_path.trim() === "") {
127319
+ return "The 'file_path' parameter cannot be empty.";
127320
+ }
127321
+ if (params.line <= 0) {
127322
+ return "The 'line' must be a positive number.";
127323
+ }
127324
+ if (!params.comment_text || params.comment_text.trim() === "") {
127325
+ return "The 'comment_text' parameter cannot be empty.";
127326
+ }
127327
+ if (params.line_type && !["ADDED", "REMOVED", "CONTEXT"].includes(params.line_type)) {
127328
+ return "The 'line_type' must be one of: ADDED, REMOVED, CONTEXT";
127329
+ }
127330
+ if (params.file_type && !["TO", "FROM"].includes(params.file_type)) {
127331
+ return "The 'file_type' must be one of: TO, FROM";
127332
+ }
127333
+ return null;
127334
+ }
127335
+ getDescription(params) {
127336
+ return `Adding inline comment to Bitbucket PR #${params.pr_id} in ${params.project_key}/${params.repo_slug} at ${params.file_path}:${params.line}`;
127337
+ }
127338
+ async execute(params, signal) {
127339
+ const validationError = this.validateParams(params);
127340
+ if (validationError) {
127341
+ return {
127342
+ llmContent: `Error: Invalid parameters provided. Reason: ${validationError}`,
127343
+ returnDisplay: validationError
127344
+ };
127345
+ }
127346
+ const { project_key, repo_slug, pr_id, file_path, line, comment_text, line_type, file_type } = params;
127347
+ const personal_access_token = this.config.getBitbucketToken();
127348
+ if (!personal_access_token) {
127349
+ return {
127350
+ llmContent: "Error: Bitbucket Personal Access Token not found in keys.json. Please configure it first.",
127351
+ returnDisplay: "Bitbucket token not configured"
127352
+ };
127353
+ }
127354
+ try {
127355
+ const apiUrl = `${BITBUCKET_URL3}/rest/api/latest/projects/${project_key}/repos/${repo_slug}/pull-requests/${pr_id}/comments`;
127356
+ const headers = {
127357
+ "Authorization": `Bearer ${personal_access_token}`,
127358
+ "Content-Type": "application/json"
127359
+ };
127360
+ const payload = {
127361
+ text: comment_text,
127362
+ anchor: {
127363
+ path: file_path,
127364
+ line,
127365
+ lineType: line_type || "ADDED",
127366
+ fileType: file_type || "TO"
127367
+ }
127368
+ };
127369
+ console.log("Bitbucket API request:", {
127370
+ url: apiUrl,
127371
+ method: "POST",
127372
+ authMethod: "Bearer",
127373
+ tokenLength: personal_access_token.length,
127374
+ headers: { ...headers, Authorization: "Bearer ***" }
127375
+ });
127376
+ const controller = new AbortController();
127377
+ const timeoutId = setTimeout(() => controller.abort(), BITBUCKET_FETCH_TIMEOUT_MS3);
127378
+ let response;
127379
+ try {
127380
+ response = await fetch(apiUrl, {
127381
+ method: "POST",
127382
+ headers,
127383
+ body: JSON.stringify(payload),
127384
+ signal: signal || controller.signal
127385
+ });
127386
+ } finally {
127387
+ clearTimeout(timeoutId);
127388
+ }
127389
+ if (response.status === 401) {
127390
+ return {
127391
+ llmContent: "Error: Authentication failed (401). Personal Access Token may be invalid or expired.",
127392
+ returnDisplay: "Authentication failed (401)"
127393
+ };
127394
+ }
127395
+ if (response.status === 403) {
127396
+ return {
127397
+ llmContent: "Error: Access denied (403). Token may not have sufficient permissions.",
127398
+ returnDisplay: "Access denied (403)"
127399
+ };
127400
+ }
127401
+ if (response.status === 404) {
127402
+ return {
127403
+ llmContent: `Error: Pull Request not found (404). PR #${pr_id} in ${project_key}/${repo_slug} may not exist.`,
127404
+ returnDisplay: `PR not found (404): #${pr_id}`
127405
+ };
127406
+ }
127407
+ if (!response.ok) {
127408
+ const errorText = await response.text().catch(() => "Unknown error");
127409
+ console.error(`Bitbucket API error (${response.status}):`, errorText.substring(0, 500));
127410
+ return {
127411
+ llmContent: `Error: API call failed with status ${response.status}: ${errorText.substring(0, 200)}`,
127412
+ returnDisplay: `API error (${response.status})`
127413
+ };
127414
+ }
127415
+ const responseData = await response.json();
127416
+ let resultText = `# Inline comment added to Pull Request: ${project_key}/${repo_slug}#${pr_id}
127417
+
127418
+ `;
127419
+ resultText += `**File**: ${file_path}
127420
+ `;
127421
+ resultText += `**Line**: ${line}
127422
+ `;
127423
+ resultText += `**Line Type**: ${line_type || "ADDED"}
127424
+ `;
127425
+ resultText += `**File Type**: ${file_type || "TO"}
127426
+ `;
127427
+ resultText += `**Comment ID**: ${responseData.id || "Unknown"}
127428
+ `;
127429
+ resultText += `**Text**: ${comment_text}
127430
+ `;
127431
+ return {
127432
+ llmContent: resultText,
127433
+ returnDisplay: `Added inline comment to Bitbucket PR #${pr_id} at ${file_path}:${line}`
127434
+ };
127435
+ } catch (error) {
127436
+ const errorMessage = `Error adding inline comment to Bitbucket PR ${project_key}/${repo_slug}#${pr_id}: ${getErrorMessage(error)}`;
127437
+ console.error(errorMessage, error);
127438
+ return {
127439
+ llmContent: `Error: ${errorMessage}`,
127440
+ returnDisplay: `Error: ${errorMessage}`
127441
+ };
127442
+ }
127443
+ }
127444
+ };
127445
+ }
127446
+ });
127447
+
126457
127448
  // packages/core/dist/src/utils/getFolderStructure.js
126458
127449
  import * as fs18 from "fs/promises";
126459
127450
  import * as path17 from "path";
@@ -126835,7 +127826,7 @@ import fs20 from "node:fs";
126835
127826
  import process20 from "node:process";
126836
127827
  function getCoreSystemPrompt(userMemory) {
126837
127828
  let systemMdEnabled = false;
126838
- let systemMdPath = path19.join(GEMINI_CONFIG_DIR, "system.md");
127829
+ let systemMdPath = path19.join(MPDAI_CONFIG_DIR, "system.md");
126839
127830
  const systemMdVar = process20.env.GEMINI_SYSTEM_MD?.toLowerCase();
126840
127831
  if (systemMdVar && !["0", "false"].includes(systemMdVar)) {
126841
127832
  systemMdEnabled = true;
@@ -174596,7 +175587,7 @@ var require_homedir = __commonJS({
174596
175587
  "node_modules/resolve/lib/homedir.js"(exports2, module2) {
174597
175588
  "use strict";
174598
175589
  var os23 = __require("os");
174599
- module2.exports = os23.homedir || function homedir16() {
175590
+ module2.exports = os23.homedir || function homedir17() {
174600
175591
  var home = process.env.HOME;
174601
175592
  var user = process.env.LOGNAME || process.env.USER || process.env.LNAME || process.env.USERNAME;
174602
175593
  if (process.platform === "win32") {
@@ -175077,11 +176068,11 @@ var require_async2 = __commonJS({
175077
176068
  var normalizeOptions = require_normalize_options();
175078
176069
  var isCore = require_is_core_module();
175079
176070
  var realpathFS = process.platform !== "win32" && fs51.realpath && typeof fs51.realpath.native === "function" ? fs51.realpath.native : fs51.realpath;
175080
- var homedir16 = getHomedir();
176071
+ var homedir17 = getHomedir();
175081
176072
  var defaultPaths = function() {
175082
176073
  return [
175083
- path53.join(homedir16, ".node_modules"),
175084
- path53.join(homedir16, ".node_libraries")
176074
+ path53.join(homedir17, ".node_modules"),
176075
+ path53.join(homedir17, ".node_libraries")
175085
176076
  ];
175086
176077
  };
175087
176078
  var defaultIsFile = function isFile(file, cb) {
@@ -175567,11 +176558,11 @@ var require_sync = __commonJS({
175567
176558
  var nodeModulesPaths = require_node_modules_paths();
175568
176559
  var normalizeOptions = require_normalize_options();
175569
176560
  var realpathFS = process.platform !== "win32" && fs51.realpathSync && typeof fs51.realpathSync.native === "function" ? fs51.realpathSync.native : fs51.realpathSync;
175570
- var homedir16 = getHomedir();
176561
+ var homedir17 = getHomedir();
175571
176562
  var defaultPaths = function() {
175572
176563
  return [
175573
- path53.join(homedir16, ".node_modules"),
175574
- path53.join(homedir16, ".node_libraries")
176564
+ path53.join(homedir17, ".node_modules"),
176565
+ path53.join(homedir17, ".node_libraries")
175575
176566
  ];
175576
176567
  };
175577
176568
  var defaultIsFile = function isFile(file) {
@@ -175608,8 +176599,8 @@ var require_sync = __commonJS({
175608
176599
  }
175609
176600
  return x;
175610
176601
  };
175611
- var defaultReadPackageSync = function defaultReadPackageSync2(readFileSync16, pkgfile) {
175612
- var body = readFileSync16(pkgfile);
176602
+ var defaultReadPackageSync = function defaultReadPackageSync2(readFileSync19, pkgfile) {
176603
+ var body = readFileSync19(pkgfile);
175613
176604
  try {
175614
176605
  var pkg2 = JSON.parse(body);
175615
176606
  return pkg2;
@@ -175629,7 +176620,7 @@ var require_sync = __commonJS({
175629
176620
  }
175630
176621
  var opts = normalizeOptions(x, options);
175631
176622
  var isFile = opts.isFile || defaultIsFile;
175632
- var readFileSync16 = opts.readFileSync || fs51.readFileSync;
176623
+ var readFileSync19 = opts.readFileSync || fs51.readFileSync;
175633
176624
  var isDirectory = opts.isDirectory || defaultIsDir;
175634
176625
  var realpathSync2 = opts.realpathSync || defaultRealpathSync;
175635
176626
  var readPackageSync2 = opts.readPackageSync || defaultReadPackageSync;
@@ -175686,7 +176677,7 @@ var require_sync = __commonJS({
175686
176677
  if (!isFile(pkgfile)) {
175687
176678
  return loadpkg(path53.dirname(dir));
175688
176679
  }
175689
- var pkg2 = readPackageSync2(readFileSync16, pkgfile);
176680
+ var pkg2 = readPackageSync2(readFileSync19, pkgfile);
175690
176681
  if (pkg2 && opts.packageFilter) {
175691
176682
  pkg2 = opts.packageFilter(
175692
176683
  pkg2,
@@ -175700,7 +176691,7 @@ var require_sync = __commonJS({
175700
176691
  var pkgfile = path53.join(maybeRealpathSync(realpathSync2, x2, opts), "/package.json");
175701
176692
  if (isFile(pkgfile)) {
175702
176693
  try {
175703
- var pkg2 = readPackageSync2(readFileSync16, pkgfile);
176694
+ var pkg2 = readPackageSync2(readFileSync19, pkgfile);
175704
176695
  } catch (e2) {
175705
176696
  }
175706
176697
  if (pkg2 && opts.packageFilter) {
@@ -180708,7 +181699,7 @@ var init_user_id = __esm({
180708
181699
  "use strict";
180709
181700
  init_paths();
180710
181701
  homeDir = os7.homedir() ?? "";
180711
- geminiDir = path20.join(homeDir, GEMINI_DIR2);
181702
+ geminiDir = path20.join(homeDir, MPDAI_DIR2);
180712
181703
  installationIdFile = path20.join(geminiDir, "installation_id");
180713
181704
  }
180714
181705
  });
@@ -203445,7 +204436,7 @@ var init_fileDiscoveryService = __esm({
203445
204436
  "use strict";
203446
204437
  init_gitIgnoreParser();
203447
204438
  init_gitUtils();
203448
- GEMINI_IGNORE_FILE_NAME = ".geminiignore";
204439
+ GEMINI_IGNORE_FILE_NAME = ".mpdaiignore";
203449
204440
  FileDiscoveryService = class {
203450
204441
  gitIgnoreFilter = null;
203451
204442
  geminiIgnoreFilter = null;
@@ -203516,7 +204507,7 @@ var init_fileDiscoveryService = __esm({
203516
204507
  return false;
203517
204508
  }
203518
204509
  /**
203519
- * Returns loaded patterns from .geminiignore
204510
+ * Returns loaded patterns from .mpdaiignore
203520
204511
  */
203521
204512
  getGeminiIgnorePatterns() {
203522
204513
  return this.geminiIgnoreFilter?.getPatterns() ?? [];
@@ -208065,7 +209056,7 @@ var init_gitService = __esm({
208065
209056
  }
208066
209057
  getHistoryDir() {
208067
209058
  const hash = getProjectHash(this.projectRoot);
208068
- return path23.join(os8.homedir(), GEMINI_DIR2, "history", hash);
209059
+ return path23.join(os8.homedir(), MPDAI_DIR2, "history", hash);
208069
209060
  }
208070
209061
  async initialize() {
208071
209062
  if (!isGitRepository(this.projectRoot)) {
@@ -208346,7 +209337,7 @@ async function getGeminiMdFilePathsInternal(currentWorkingDirectory, userHomePat
208346
209337
  for (const geminiMdFilename of geminiMdFilenames) {
208347
209338
  const resolvedCwd = path26.resolve(currentWorkingDirectory);
208348
209339
  const resolvedHome = path26.resolve(userHomePath);
208349
- const globalMemoryPath = path26.join(resolvedHome, GEMINI_CONFIG_DIR, geminiMdFilename);
209340
+ const globalMemoryPath = path26.join(resolvedHome, MPDAI_CONFIG_DIR, geminiMdFilename);
208350
209341
  if (debugMode)
208351
209342
  logger3.debug(`Searching for ${geminiMdFilename} starting from CWD: ${resolvedCwd}`);
208352
209343
  if (debugMode)
@@ -208370,7 +209361,7 @@ async function getGeminiMdFilePathsInternal(currentWorkingDirectory, userHomePat
208370
209361
  if (debugMode) {
208371
209362
  logger3.debug(`Checking for ${geminiMdFilename} in (upward scan): ${currentDir}`);
208372
209363
  }
208373
- if (currentDir === path26.join(resolvedHome, GEMINI_CONFIG_DIR)) {
209364
+ if (currentDir === path26.join(resolvedHome, MPDAI_CONFIG_DIR)) {
208374
209365
  if (debugMode) {
208375
209366
  logger3.debug(`Upward scan reached global config dir path, stopping upward search here: ${currentDir}`);
208376
209367
  }
@@ -208516,6 +209507,9 @@ var init_telemetry = __esm({
208516
209507
  // packages/core/dist/src/config/config.js
208517
209508
  import * as path27 from "node:path";
208518
209509
  import process21 from "node:process";
209510
+ import { existsSync as existsSync6, readFileSync as readFileSync6 } from "node:fs";
209511
+ import { join as join11 } from "node:path";
209512
+ import { homedir as homedir6 } from "node:os";
208519
209513
  var ApprovalMode, MCPServerConfig, Config;
208520
209514
  var init_config2 = __esm({
208521
209515
  "packages/core/dist/src/config/config.js"() {
@@ -208532,6 +209526,11 @@ var init_config2 = __esm({
208532
209526
  init_read_many_files();
208533
209527
  init_web_fetch();
208534
209528
  init_web_search();
209529
+ init_confluence_get_page();
209530
+ init_jira_get_issue();
209531
+ init_bitbucket_get_pr_diff();
209532
+ init_bitbucket_add_pr_comment();
209533
+ init_bitbucket_add_pr_inline_comment();
208535
209534
  init_memoryTool();
208536
209535
  init_client3();
208537
209536
  init_fileDiscoveryService();
@@ -208798,7 +209797,7 @@ var init_config2 = __esm({
208798
209797
  return this.geminiClient;
208799
209798
  }
208800
209799
  getGeminiDir() {
208801
- return path27.join(this.targetDir, GEMINI_CONFIG_DIR);
209800
+ return path27.join(this.targetDir, MPDAI_CONFIG_DIR);
208802
209801
  }
208803
209802
  getProjectTempDir() {
208804
209803
  return getProjectTempDir(this.getProjectRoot());
@@ -208852,6 +209851,72 @@ var init_config2 = __esm({
208852
209851
  this.setGeminiMdFileCount(fileCount);
208853
209852
  return { memoryContent, fileCount };
208854
209853
  }
209854
+ /**
209855
+ * Get Confluence Advanced Access Token from keys.json
209856
+ * @returns The Personal Access Token or null if not found
209857
+ */
209858
+ getConfluenceToken() {
209859
+ try {
209860
+ const keysJsonPath = join11(homedir6(), ".mpdai", "keys.json");
209861
+ if (!existsSync6(keysJsonPath)) {
209862
+ return null;
209863
+ }
209864
+ const content = readFileSync6(keysJsonPath, "utf-8");
209865
+ const keys = JSON.parse(content);
209866
+ const confluenceKey = keys.find((key) => key.name === "confluence");
209867
+ if (confluenceKey && confluenceKey.value1) {
209868
+ return confluenceKey.value1;
209869
+ }
209870
+ return null;
209871
+ } catch (error) {
209872
+ console.error("Failed to read Confluence token from keys.json:", error);
209873
+ return null;
209874
+ }
209875
+ }
209876
+ /**
209877
+ * Get Jira Personal Access Token from keys.json
209878
+ * @returns The Personal Access Token or null if not found
209879
+ */
209880
+ getJiraToken() {
209881
+ try {
209882
+ const keysJsonPath = join11(homedir6(), ".mpdai", "keys.json");
209883
+ if (!existsSync6(keysJsonPath)) {
209884
+ return null;
209885
+ }
209886
+ const content = readFileSync6(keysJsonPath, "utf-8");
209887
+ const keys = JSON.parse(content);
209888
+ const jiraKey = keys.find((key) => key.name === "jira");
209889
+ if (jiraKey && jiraKey.value1) {
209890
+ return jiraKey.value1;
209891
+ }
209892
+ return null;
209893
+ } catch (error) {
209894
+ console.error("Failed to read Jira token from keys.json:", error);
209895
+ return null;
209896
+ }
209897
+ }
209898
+ /**
209899
+ * Get Bitbucket Personal Access Token from keys.json
209900
+ * @returns The Personal Access Token or null if not found
209901
+ */
209902
+ getBitbucketToken() {
209903
+ try {
209904
+ const keysJsonPath = join11(homedir6(), ".mpdai", "keys.json");
209905
+ if (!existsSync6(keysJsonPath)) {
209906
+ return null;
209907
+ }
209908
+ const content = readFileSync6(keysJsonPath, "utf-8");
209909
+ const keys = JSON.parse(content);
209910
+ const bitbucketKey = keys.find((key) => key.name === "bitbucket");
209911
+ if (bitbucketKey && bitbucketKey.value1) {
209912
+ return bitbucketKey.value1;
209913
+ }
209914
+ return null;
209915
+ } catch (error) {
209916
+ console.error("Failed to read Bitbucket token from keys.json:", error);
209917
+ return null;
209918
+ }
209919
+ }
208855
209920
  async createToolRegistry() {
208856
209921
  const registry = new ToolRegistry(this);
208857
209922
  const targetDir = this.getTargetDir();
@@ -208884,9 +209949,24 @@ var init_config2 = __esm({
208884
209949
  registerCoreTool(EditTool, this);
208885
209950
  registerCoreTool(WriteFileTool, this);
208886
209951
  }
208887
- if (process21.env.USE_GEMINI_TOOL) {
209952
+ const useMpdaiTool = process21.env.USE_MPDAI_TOOL !== "false";
209953
+ if (useMpdaiTool) {
208888
209954
  registerCoreTool(WebFetchTool, this);
208889
209955
  registerCoreTool(WebSearchTool, this);
209956
+ const confluenceToken = this.getConfluenceToken();
209957
+ if (confluenceToken) {
209958
+ registerCoreTool(ConfluenceGetPageTool, this);
209959
+ }
209960
+ const jiraToken = this.getJiraToken();
209961
+ if (jiraToken) {
209962
+ registerCoreTool(JiraGetIssueTool, this);
209963
+ }
209964
+ const bitbucketToken = this.getBitbucketToken();
209965
+ if (bitbucketToken) {
209966
+ registerCoreTool(BitbucketGetPrDiffTool, this);
209967
+ registerCoreTool(BitbucketAddPrCommentTool, this);
209968
+ registerCoreTool(BitbucketAddPrInlineCommentTool, this);
209969
+ }
208890
209970
  }
208891
209971
  await registry.discoverTools();
208892
209972
  return registry;
@@ -209923,8 +211003,6 @@ __export(dist_exports, {
209923
211003
  EndSessionEvent: () => EndSessionEvent,
209924
211004
  FileDiscoveryService: () => FileDiscoveryService,
209925
211005
  ForbiddenError: () => ForbiddenError,
209926
- GEMINI_CONFIG_DIR: () => GEMINI_CONFIG_DIR,
209927
- GEMINI_DIR: () => GEMINI_DIR2,
209928
211006
  GeminiChat: () => GeminiChat,
209929
211007
  GeminiClient: () => GeminiClient,
209930
211008
  GeminiEventType: () => GeminiEventType,
@@ -209940,6 +211018,8 @@ __export(dist_exports, {
209940
211018
  MCPServerStatus: () => MCPServerStatus,
209941
211019
  MCP_DEFAULT_TIMEOUT_MSEC: () => MCP_DEFAULT_TIMEOUT_MSEC,
209942
211020
  MEMORY_SECTION_HEADER: () => MEMORY_SECTION_HEADER,
211021
+ MPDAI_CONFIG_DIR: () => MPDAI_CONFIG_DIR,
211022
+ MPDAI_DIR: () => MPDAI_DIR2,
209943
211023
  MemoryTool: () => MemoryTool,
209944
211024
  MessageSenderType: () => MessageSenderType,
209945
211025
  OnboardUserStatusCode: () => OnboardUserStatusCode,
@@ -214095,9 +215175,9 @@ var init_lib3 = __esm({
214095
215175
  });
214096
215176
 
214097
215177
  // packages/cli/src/telemetry/langfuseConfig.ts
214098
- import { readFileSync as readFileSync6, existsSync as existsSync6 } from "fs";
214099
- import { join as join11 } from "path";
214100
- import { homedir as homedir6 } from "os";
215178
+ import { readFileSync as readFileSync7, existsSync as existsSync7 } from "fs";
215179
+ import { join as join12 } from "path";
215180
+ import { homedir as homedir7 } from "os";
214101
215181
  var LangfuseConfigManager;
214102
215182
  var init_langfuseConfig = __esm({
214103
215183
  "packages/cli/src/telemetry/langfuseConfig.ts"() {
@@ -214118,15 +215198,15 @@ var init_langfuseConfig = __esm({
214118
215198
  return this.config;
214119
215199
  }
214120
215200
  try {
214121
- const userConfigPath = join11(homedir6(), ".gemini", "settings.conf");
214122
- if (existsSync6(userConfigPath)) {
214123
- const configContent = readFileSync6(userConfigPath, "utf-8");
215201
+ const userConfigPath = join12(homedir7(), ".mpdai", "settings.conf");
215202
+ if (existsSync7(userConfigPath)) {
215203
+ const configContent = readFileSync7(userConfigPath, "utf-8");
214124
215204
  this.config = JSON.parse(configContent);
214125
215205
  return this.config;
214126
215206
  }
214127
- const projectConfigPath = join11(process.cwd(), ".langfuse", "settings.conf");
214128
- if (existsSync6(projectConfigPath)) {
214129
- const configContent = readFileSync6(projectConfigPath, "utf-8");
215207
+ const projectConfigPath = join12(process.cwd(), ".langfuse", "settings.conf");
215208
+ if (existsSync7(projectConfigPath)) {
215209
+ const configContent = readFileSync7(projectConfigPath, "utf-8");
214130
215210
  this.config = JSON.parse(configContent);
214131
215211
  return this.config;
214132
215212
  }
@@ -214158,9 +215238,9 @@ var init_langfuseConfig = __esm({
214158
215238
  });
214159
215239
 
214160
215240
  // packages/cli/src/telemetry/langfuseClient.ts
214161
- import { join as join12 } from "path";
214162
- import { homedir as homedir7 } from "os";
214163
- import { existsSync as existsSync7, readFileSync as readFileSync7 } from "fs";
215241
+ import { join as join13 } from "path";
215242
+ import { homedir as homedir8 } from "os";
215243
+ import { existsSync as existsSync8, readFileSync as readFileSync8 } from "fs";
214164
215244
  var LangfuseClient;
214165
215245
  var init_langfuseClient = __esm({
214166
215246
  "packages/cli/src/telemetry/langfuseClient.ts"() {
@@ -214262,7 +215342,7 @@ var init_langfuseClient = __esm({
214262
215342
  userId,
214263
215343
  metadata: {
214264
215344
  ...safeMetadata,
214265
- cli_version: this.safeString("0.1.25", "unknown"),
215345
+ cli_version: this.safeString("0.1.31", "unknown"),
214266
215346
  model: this.safeString(process.env.CUSTOM_LLM_MODEL_NAME, "gemini"),
214267
215347
  auth_type: process.env.USE_CUSTOM_LLM ? "custom_llm" : "google_oauth",
214268
215348
  environment: this.safeString(this.configManager.getConfig()?.environment, "unknown")
@@ -214574,9 +215654,9 @@ var init_langfuseClient = __esm({
214574
215654
  // 获取用户ID
214575
215655
  getUserId() {
214576
215656
  try {
214577
- const userJsonPath = join12(homedir7(), ".gemini", "user.json");
214578
- if (existsSync7(userJsonPath)) {
214579
- const content = readFileSync7(userJsonPath, "utf-8");
215657
+ const userJsonPath = join13(homedir8(), ".mpdai", "user.json");
215658
+ if (existsSync8(userJsonPath)) {
215659
+ const content = readFileSync8(userJsonPath, "utf-8");
214580
215660
  const userData = JSON.parse(content);
214581
215661
  if (userData.username) {
214582
215662
  return userData.username;
@@ -215429,7 +216509,7 @@ var init_langfuseIntegration = __esm({
215429
216509
  const metadata = {
215430
216510
  model: this.config.getModel(),
215431
216511
  auth_type: this.config.getContentGeneratorConfig()?.authType,
215432
- cli_version: "0.1.25",
216512
+ cli_version: "0.1.31",
215433
216513
  start_time: (/* @__PURE__ */ new Date()).toISOString(),
215434
216514
  session_id: this.sessionId
215435
216515
  };
@@ -215488,7 +216568,7 @@ var init_langfuseIntegration = __esm({
215488
216568
  totalCachedTokens: sessionStats.totalCachedTokens,
215489
216569
  totalPromptTokens: sessionStats.totalPromptTokens,
215490
216570
  metadata: {
215491
- cli_version: "0.1.25",
216571
+ cli_version: "0.1.31",
215492
216572
  auth_type: this.config.getContentGeneratorConfig()?.authType,
215493
216573
  session_end_time: (/* @__PURE__ */ new Date()).toISOString()
215494
216574
  }
@@ -215560,7 +216640,7 @@ var init_langfuseIntegration = __esm({
215560
216640
  error,
215561
216641
  metadata: {
215562
216642
  session_id: this.sessionId,
215563
- cli_version: "0.1.25",
216643
+ cli_version: "0.1.31",
215564
216644
  auth_type: this.config.getContentGeneratorConfig()?.authType
215565
216645
  }
215566
216646
  });
@@ -220730,9 +221810,9 @@ var require_normalize2 = __commonJS({
220730
221810
  });
220731
221811
 
220732
221812
  // packages/cli/src/config/mpdaiConfig.ts
220733
- import { readFileSync as readFileSync8, existsSync as existsSync9 } from "fs";
220734
- import { join as join14 } from "path";
220735
- import { homedir as homedir9 } from "os";
221813
+ import { readFileSync as readFileSync9, existsSync as existsSync10 } from "fs";
221814
+ import { join as join15 } from "path";
221815
+ import { homedir as homedir10 } from "os";
220736
221816
  var MpdaiConfigManager;
220737
221817
  var init_mpdaiConfig = __esm({
220738
221818
  "packages/cli/src/config/mpdaiConfig.ts"() {
@@ -220753,15 +221833,15 @@ var init_mpdaiConfig = __esm({
220753
221833
  return this.config;
220754
221834
  }
220755
221835
  try {
220756
- const userConfigPath = join14(homedir9(), ".gemini", "config.json");
220757
- if (existsSync9(userConfigPath)) {
220758
- const configContent = readFileSync8(userConfigPath, "utf-8");
221836
+ const userConfigPath = join15(homedir10(), ".mpdai", "config.json");
221837
+ if (existsSync10(userConfigPath)) {
221838
+ const configContent = readFileSync9(userConfigPath, "utf-8");
220759
221839
  this.config = JSON.parse(configContent);
220760
221840
  return this.config;
220761
221841
  }
220762
- const projectConfigPath = join14(process.cwd(), ".mpdai", "config.json");
220763
- if (existsSync9(projectConfigPath)) {
220764
- const configContent = readFileSync8(projectConfigPath, "utf-8");
221842
+ const projectConfigPath = join15(process.cwd(), ".mpdai", "config.json");
221843
+ if (existsSync10(projectConfigPath)) {
221844
+ const configContent = readFileSync9(projectConfigPath, "utf-8");
220765
221845
  this.config = JSON.parse(configContent);
220766
221846
  return this.config;
220767
221847
  }
@@ -222015,9 +223095,9 @@ var EnvConfigManager_exports = {};
222015
223095
  __export(EnvConfigManager_exports, {
222016
223096
  EnvConfigManager: () => EnvConfigManager
222017
223097
  });
222018
- import { readFileSync as readFileSync9, writeFileSync as writeFileSync3, existsSync as existsSync10, mkdirSync as mkdirSync3 } from "fs";
222019
- import { join as join15, dirname as dirname6 } from "path";
222020
- import { homedir as homedir10 } from "os";
223098
+ import { readFileSync as readFileSync10, writeFileSync as writeFileSync3, existsSync as existsSync11, mkdirSync as mkdirSync3 } from "fs";
223099
+ import { join as join16, dirname as dirname6 } from "path";
223100
+ import { homedir as homedir11 } from "os";
222021
223101
  var EnvConfigManager;
222022
223102
  var init_EnvConfigManager = __esm({
222023
223103
  "packages/cli/src/services/EnvConfigManager.ts"() {
@@ -222026,7 +223106,7 @@ var init_EnvConfigManager = __esm({
222026
223106
  envPaths;
222027
223107
  constructor() {
222028
223108
  this.envPaths = [
222029
- ".gemini/.env",
223109
+ ".mpdai/.env",
222030
223110
  // 项目级别的gemini配置
222031
223111
  ".env"
222032
223112
  // 项目级别的通用配置
@@ -222039,17 +223119,17 @@ var init_EnvConfigManager = __esm({
222039
223119
  let currentDir = startDir;
222040
223120
  while (true) {
222041
223121
  for (const envPath of this.envPaths) {
222042
- const fullPath = join15(currentDir, envPath);
222043
- if (existsSync10(fullPath)) {
223122
+ const fullPath = join16(currentDir, envPath);
223123
+ if (existsSync11(fullPath)) {
222044
223124
  return fullPath;
222045
223125
  }
222046
223126
  }
222047
- const parentDir = join15(currentDir, "..");
223127
+ const parentDir = join16(currentDir, "..");
222048
223128
  if (parentDir === currentDir) {
222049
- const homeDir2 = homedir10();
223129
+ const homeDir2 = homedir11();
222050
223130
  for (const envPath of this.envPaths) {
222051
- const fullPath = join15(homeDir2, envPath);
222052
- if (existsSync10(fullPath)) {
223131
+ const fullPath = join16(homeDir2, envPath);
223132
+ if (existsSync11(fullPath)) {
222053
223133
  return fullPath;
222054
223134
  }
222055
223135
  }
@@ -222064,7 +223144,7 @@ var init_EnvConfigManager = __esm({
222064
223144
  */
222065
223145
  readEnvFile(envPath) {
222066
223146
  try {
222067
- const content = readFileSync9(envPath, "utf-8");
223147
+ const content = readFileSync10(envPath, "utf-8");
222068
223148
  const envVars = {};
222069
223149
  content.split("\n").forEach((line) => {
222070
223150
  line = line.trim();
@@ -222109,7 +223189,7 @@ var init_EnvConfigManager = __esm({
222109
223189
  const isDebugMode = process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true";
222110
223190
  try {
222111
223191
  const dir = dirname6(envPath);
222112
- if (!existsSync10(dir)) {
223192
+ if (!existsSync11(dir)) {
222113
223193
  mkdirSync3(dir, { recursive: true });
222114
223194
  }
222115
223195
  const envContent = Object.entries(envConfig).map(([key, value]) => `${key}=${value}`).join("\n") + "\n";
@@ -222126,8 +223206,8 @@ var init_EnvConfigManager = __esm({
222126
223206
  * 更新或创建.env文件
222127
223207
  */
222128
223208
  updateEnvFile(model, targetPath) {
222129
- const envPath = targetPath || this.findEnvFile(process.cwd()) || join15(process.cwd(), ".gemini", ".env");
222130
- const existingConfig = existsSync10(envPath) ? this.readEnvFile(envPath) : {};
223209
+ const envPath = targetPath || this.findEnvFile(process.cwd()) || join16(process.cwd(), ".mpdai", ".env");
223210
+ const existingConfig = existsSync11(envPath) ? this.readEnvFile(envPath) : {};
222131
223211
  const newConfig = this.generateEnvConfig(model, existingConfig);
222132
223212
  this.writeEnvFile(newConfig, envPath);
222133
223213
  return envPath;
@@ -222512,9 +223592,9 @@ var AuthService_exports = {};
222512
223592
  __export(AuthService_exports, {
222513
223593
  AuthService: () => AuthService
222514
223594
  });
222515
- import { readFileSync as readFileSync10, writeFileSync as writeFileSync4, existsSync as existsSync11, mkdirSync as mkdirSync4 } from "fs";
222516
- import { join as join16 } from "path";
222517
- import { homedir as homedir11 } from "os";
223595
+ import { readFileSync as readFileSync11, writeFileSync as writeFileSync4, existsSync as existsSync12, mkdirSync as mkdirSync4 } from "fs";
223596
+ import { join as join17 } from "path";
223597
+ import { homedir as homedir12 } from "os";
222518
223598
  var readlineSync, AuthService;
222519
223599
  var init_AuthService = __esm({
222520
223600
  "packages/cli/src/services/AuthService.ts"() {
@@ -222524,18 +223604,20 @@ var init_AuthService = __esm({
222524
223604
  readlineSync = __toESM(require_readline_sync(), 1);
222525
223605
  AuthService = class {
222526
223606
  userJsonPath;
223607
+ keysJsonPath;
222527
223608
  authApiUrl;
222528
223609
  mpdaiConfig;
222529
223610
  constructor(authApiUrl) {
222530
223611
  this.mpdaiConfig = MpdaiConfigManager.getInstance();
222531
223612
  this.authApiUrl = authApiUrl || this.mpdaiConfig.getAuthUrl();
222532
- this.userJsonPath = join16(homedir11(), ".gemini", "user.json");
223613
+ this.userJsonPath = join17(homedir12(), ".mpdai", "user.json");
223614
+ this.keysJsonPath = join17(homedir12(), ".mpdai", "keys.json");
222533
223615
  }
222534
223616
  /**
222535
223617
  * 检查本地是否存在用户凭据文件
222536
223618
  */
222537
223619
  hasLocalCredentials() {
222538
- return existsSync11(this.userJsonPath);
223620
+ return existsSync12(this.userJsonPath);
222539
223621
  }
222540
223622
  /**
222541
223623
  * 从本地文件读取用户凭据
@@ -222545,7 +223627,7 @@ var init_AuthService = __esm({
222545
223627
  if (!this.hasLocalCredentials()) {
222546
223628
  return null;
222547
223629
  }
222548
- const content = readFileSync10(this.userJsonPath, "utf-8");
223630
+ const content = readFileSync11(this.userJsonPath, "utf-8");
222549
223631
  const credentials = JSON.parse(content);
222550
223632
  if (credentials.encodedPassword) {
222551
223633
  credentials.password = Buffer.from(credentials.encodedPassword, "base64").toString("utf-8");
@@ -222562,8 +223644,8 @@ var init_AuthService = __esm({
222562
223644
  */
222563
223645
  saveCredentials(credentials) {
222564
223646
  try {
222565
- const dir = join16(homedir11(), ".gemini");
222566
- if (!existsSync11(dir)) {
223647
+ const dir = join17(homedir12(), ".mpdai");
223648
+ if (!existsSync12(dir)) {
222567
223649
  mkdirSync4(dir, { recursive: true });
222568
223650
  }
222569
223651
  const credentialsToSave = {
@@ -222576,6 +223658,43 @@ var init_AuthService = __esm({
222576
223658
  throw error;
222577
223659
  }
222578
223660
  }
223661
+ /**
223662
+ * 检查本地是否存在 keys 文件
223663
+ */
223664
+ hasLocalKeys() {
223665
+ return existsSync12(this.keysJsonPath);
223666
+ }
223667
+ /**
223668
+ * 从本地文件读取 keys
223669
+ */
223670
+ getLocalKeys() {
223671
+ try {
223672
+ if (!this.hasLocalKeys()) {
223673
+ return null;
223674
+ }
223675
+ const content = readFileSync11(this.keysJsonPath, "utf-8");
223676
+ const keys = JSON.parse(content);
223677
+ return keys;
223678
+ } catch (error) {
223679
+ console.error("Failed to read keys:", error);
223680
+ return null;
223681
+ }
223682
+ }
223683
+ /**
223684
+ * 保存 keys 到本地文件
223685
+ */
223686
+ saveKeys(keys) {
223687
+ try {
223688
+ const dir = join17(homedir12(), ".mpdai");
223689
+ if (!existsSync12(dir)) {
223690
+ mkdirSync4(dir, { recursive: true });
223691
+ }
223692
+ writeFileSync4(this.keysJsonPath, JSON.stringify(keys, null, 2), "utf-8");
223693
+ } catch (error) {
223694
+ console.error("Failed to save keys:", error);
223695
+ throw error;
223696
+ }
223697
+ }
222579
223698
  /**
222580
223699
  * 调用认证接口获取用户数据
222581
223700
  */
@@ -222675,6 +223794,12 @@ var init_AuthService = __esm({
222675
223794
  if (!this.hasLocalCredentials()) {
222676
223795
  this.saveCredentials(credentials);
222677
223796
  }
223797
+ if (authResponse.keys && authResponse.keys.length > 0) {
223798
+ this.saveKeys(authResponse.keys);
223799
+ if (isDebugMode) {
223800
+ console.log(`Saved ${authResponse.keys.length} keys to local storage`);
223801
+ }
223802
+ }
222678
223803
  return authResponse;
222679
223804
  }
222680
223805
  /**
@@ -231670,7 +232795,7 @@ var require_require_directory = __commonJS({
231670
232795
  "node_modules/require-directory/index.js"(exports2, module2) {
231671
232796
  "use strict";
231672
232797
  var fs51 = __require("fs");
231673
- var join24 = __require("path").join;
232798
+ var join25 = __require("path").join;
231674
232799
  var resolve18 = __require("path").resolve;
231675
232800
  var dirname11 = __require("path").dirname;
231676
232801
  var defaultOptions2 = {
@@ -231707,7 +232832,7 @@ var require_require_directory = __commonJS({
231707
232832
  }
231708
232833
  path53 = !path53 ? dirname11(m.filename) : resolve18(dirname11(m.filename), path53);
231709
232834
  fs51.readdirSync(path53).forEach(function(filename) {
231710
- var joined = join24(path53, filename), files, key, obj;
232835
+ var joined = join25(path53, filename), files, key, obj;
231711
232836
  if (fs51.statSync(joined).isDirectory() && options.recurse) {
231712
232837
  files = requireDirectory(m, joined, options);
231713
232838
  if (Object.keys(files).length) {
@@ -235477,7 +236602,7 @@ var require_minimist = __commonJS({
235477
236602
  var require_rc = __commonJS({
235478
236603
  "node_modules/rc/index.js"(exports2, module2) {
235479
236604
  var cc = require_utils13();
235480
- var join24 = __require("path").join;
236605
+ var join25 = __require("path").join;
235481
236606
  var deepExtend = require_deep_extend();
235482
236607
  var etc = "/etc";
235483
236608
  var win = process.platform === "win32";
@@ -235502,15 +236627,15 @@ var require_rc = __commonJS({
235502
236627
  }
235503
236628
  if (!win)
235504
236629
  [
235505
- join24(etc, name2, "config"),
235506
- join24(etc, name2 + "rc")
236630
+ join25(etc, name2, "config"),
236631
+ join25(etc, name2 + "rc")
235507
236632
  ].forEach(addConfigFile);
235508
236633
  if (home)
235509
236634
  [
235510
- join24(home, ".config", name2, "config"),
235511
- join24(home, ".config", name2),
235512
- join24(home, "." + name2, "config"),
235513
- join24(home, "." + name2 + "rc")
236635
+ join25(home, ".config", name2, "config"),
236636
+ join25(home, ".config", name2),
236637
+ join25(home, "." + name2, "config"),
236638
+ join25(home, "." + name2 + "rc")
235514
236639
  ].forEach(addConfigFile);
235515
236640
  addConfigFile(cc.find("." + name2 + "rc"));
235516
236641
  if (env6.config) addConfigFile(env6.config);
@@ -251824,7 +252949,7 @@ import { promises as fs33 } from "fs";
251824
252949
  import path37 from "path";
251825
252950
 
251826
252951
  // packages/cli/src/generated/git-commit.ts
251827
- var GIT_COMMIT_INFO = "220545e (local modifications)";
252952
+ var GIT_COMMIT_INFO = "cc090d6";
251828
252953
 
251829
252954
  // node_modules/read-package-up/index.js
251830
252955
  import path35 from "node:path";
@@ -252037,7 +253162,7 @@ async function getPackageJson() {
252037
253162
  // packages/cli/src/utils/version.ts
252038
253163
  async function getCliVersion() {
252039
253164
  const pkgJson = await getPackageJson();
252040
- return "0.1.25";
253165
+ return "0.1.31";
252041
253166
  }
252042
253167
 
252043
253168
  // packages/cli/src/ui/commands/memoryCommand.ts
@@ -252134,7 +253259,7 @@ ${memoryContent}
252134
253259
  var helpCommand = {
252135
253260
  name: "help",
252136
253261
  altName: "?",
252137
- description: "for help on gemini-cli",
253262
+ description: "for help on mpdai-cli",
252138
253263
  action: (_context, _args) => {
252139
253264
  console.debug("Opening help UI ...");
252140
253265
  return {
@@ -252156,9 +253281,9 @@ var clearCommand = {
252156
253281
  };
252157
253282
 
252158
253283
  // packages/cli/src/ui/commands/logoutCommand.ts
252159
- import { existsSync as existsSync8, unlinkSync } from "fs";
252160
- import { join as join13 } from "path";
252161
- import { homedir as homedir8 } from "os";
253284
+ import { existsSync as existsSync9, unlinkSync } from "fs";
253285
+ import { join as join14 } from "path";
253286
+ import { homedir as homedir9 } from "os";
252162
253287
  var logoutCommand = {
252163
253288
  name: "logout",
252164
253289
  description: "logout and clear user credentials and settings, then exit",
@@ -252166,8 +253291,8 @@ var logoutCommand = {
252166
253291
  const now = /* @__PURE__ */ new Date();
252167
253292
  const { sessionStartTime } = context2.session.stats;
252168
253293
  const wallDuration = now.getTime() - sessionStartTime.getTime();
252169
- const userJsonPath = join13(homedir8(), ".gemini", "user.json");
252170
- if (existsSync8(userJsonPath)) {
253294
+ const userJsonPath = join14(homedir9(), ".mpdai", "user.json");
253295
+ if (existsSync9(userJsonPath)) {
252171
253296
  try {
252172
253297
  unlinkSync(userJsonPath);
252173
253298
  context2.ui.addItem({
@@ -252181,8 +253306,23 @@ var logoutCommand = {
252181
253306
  }, now.getTime());
252182
253307
  }
252183
253308
  }
252184
- const userSettingsPath = join13(homedir8(), ".gemini", "settings.json");
252185
- if (existsSync8(userSettingsPath)) {
253309
+ const keysJsonPath = join14(homedir9(), ".mpdai", "keys.json");
253310
+ if (existsSync9(keysJsonPath)) {
253311
+ try {
253312
+ unlinkSync(keysJsonPath);
253313
+ context2.ui.addItem({
253314
+ type: "info" /* INFO */,
253315
+ text: "\u2705 Keys cleared"
253316
+ }, now.getTime());
253317
+ } catch (error) {
253318
+ context2.ui.addItem({
253319
+ type: "error" /* ERROR */,
253320
+ text: `\u274C Failed to clear keys: ${error}`
253321
+ }, now.getTime());
253322
+ }
253323
+ }
253324
+ const userSettingsPath = join14(homedir9(), ".mpdai", "settings.json");
253325
+ if (existsSync9(userSettingsPath)) {
252186
253326
  try {
252187
253327
  unlinkSync(userSettingsPath);
252188
253328
  context2.ui.addItem({
@@ -252267,13 +253407,144 @@ var modelCommand = {
252267
253407
  }
252268
253408
  };
252269
253409
 
253410
+ // packages/cli/src/ui/commands/routerCommand.ts
253411
+ import { run as runRouter } from "@mpdai/router";
253412
+ import { showStatus, executeCodeCommand, runModelSelector } from "@mpdai/router";
253413
+ import { isServiceRunning, cleanupPidFile } from "@mpdai/router";
253414
+ import { PID_FILE, REFERENCE_COUNT_FILE } from "@mpdai/router";
253415
+ import { readFileSync as readFileSync12, existsSync as existsSync13, unlinkSync as unlinkSync2 } from "fs";
253416
+ async function waitForService(timeout2 = 1e4, initialDelay = 1e3) {
253417
+ await new Promise((resolve18) => setTimeout(resolve18, initialDelay));
253418
+ const startTime = Date.now();
253419
+ while (Date.now() - startTime < timeout2) {
253420
+ const isRunning = await isServiceRunning();
253421
+ if (isRunning) {
253422
+ await new Promise((resolve18) => setTimeout(resolve18, 500));
253423
+ return true;
253424
+ }
253425
+ await new Promise((resolve18) => setTimeout(resolve18, 100));
253426
+ }
253427
+ return false;
253428
+ }
253429
+ async function handleRouterStart() {
253430
+ await runRouter();
253431
+ }
253432
+ async function handleRouterStop() {
253433
+ try {
253434
+ const pid = parseInt(readFileSync12(PID_FILE, "utf-8"));
253435
+ process.kill(pid);
253436
+ cleanupPidFile();
253437
+ if (existsSync13(REFERENCE_COUNT_FILE)) {
253438
+ try {
253439
+ unlinkSync2(REFERENCE_COUNT_FILE);
253440
+ } catch (e2) {
253441
+ }
253442
+ }
253443
+ console.log("MPD AI router service has been successfully stopped.");
253444
+ } catch (e2) {
253445
+ console.log("Failed to stop the service. It may have already been stopped.");
253446
+ cleanupPidFile();
253447
+ }
253448
+ }
253449
+ async function handleRouterRestart() {
253450
+ try {
253451
+ const pid = parseInt(readFileSync12(PID_FILE, "utf-8"));
253452
+ process.kill(pid);
253453
+ cleanupPidFile();
253454
+ if (existsSync13(REFERENCE_COUNT_FILE)) {
253455
+ try {
253456
+ unlinkSync2(REFERENCE_COUNT_FILE);
253457
+ } catch (e2) {
253458
+ }
253459
+ }
253460
+ console.log("MPD AI router service has been stopped.");
253461
+ } catch (e2) {
253462
+ console.log("Service was not running or failed to stop.");
253463
+ cleanupPidFile();
253464
+ }
253465
+ console.log("Starting MPD AI router service...");
253466
+ await runRouter();
253467
+ }
253468
+ async function handleRouterStatus() {
253469
+ await showStatus();
253470
+ }
253471
+ async function handleRouterCode(args) {
253472
+ const isRunning = await isServiceRunning();
253473
+ if (!isRunning) {
253474
+ console.log("Service not running, starting service...");
253475
+ await runRouter();
253476
+ if (await waitForService()) {
253477
+ const codeArgs = args ? args.split(" ") : [];
253478
+ executeCodeCommand(codeArgs);
253479
+ } else {
253480
+ console.error("Service startup timeout, please manually run `mpdai router start` to start the service");
253481
+ process.exit(1);
253482
+ }
253483
+ } else {
253484
+ const codeArgs = args ? args.split(" ") : [];
253485
+ executeCodeCommand(codeArgs);
253486
+ }
253487
+ }
253488
+ async function handleRouterModel() {
253489
+ await runModelSelector();
253490
+ }
253491
+ var routerCommand = {
253492
+ name: "router",
253493
+ description: "Router commands for managing the MPD AI router service",
253494
+ subCommands: [
253495
+ {
253496
+ name: "start",
253497
+ description: "Start the router service",
253498
+ action: async (_context, _args) => {
253499
+ await handleRouterStart();
253500
+ }
253501
+ },
253502
+ {
253503
+ name: "stop",
253504
+ description: "Stop the router service",
253505
+ action: async (_context, _args) => {
253506
+ await handleRouterStop();
253507
+ }
253508
+ },
253509
+ {
253510
+ name: "restart",
253511
+ description: "Restart the router service",
253512
+ action: async (_context, _args) => {
253513
+ await handleRouterRestart();
253514
+ }
253515
+ },
253516
+ {
253517
+ name: "status",
253518
+ description: "Show router service status",
253519
+ action: async (_context, _args) => {
253520
+ await handleRouterStatus();
253521
+ }
253522
+ },
253523
+ {
253524
+ name: "code",
253525
+ description: "Execute Claude Code command",
253526
+ action: async (_context, args) => {
253527
+ await handleRouterCode(args);
253528
+ }
253529
+ },
253530
+ {
253531
+ name: "model",
253532
+ description: "Interactive model selection and configuration",
253533
+ action: async (_context, _args) => {
253534
+ await handleRouterModel();
253535
+ }
253536
+ }
253537
+ ]
253538
+ };
253539
+
252270
253540
  // packages/cli/src/services/CommandService.ts
252271
253541
  var loadBuiltInCommands = async () => [
252272
253542
  clearCommand,
252273
253543
  helpCommand,
252274
253544
  memoryCommand,
252275
253545
  logoutCommand,
252276
- modelCommand
253546
+ modelCommand,
253547
+ routerCommand
252277
253548
  ];
252278
253549
  var CommandService = class {
252279
253550
  constructor(commandLoader = loadBuiltInCommands) {
@@ -252416,9 +253687,9 @@ var useSlashCommandProcessor = (config2, settings, history, addItem, clearItems,
252416
253687
  // `/help` and `/clear` have been migrated and REMOVED from this list.
252417
253688
  {
252418
253689
  name: "docs",
252419
- description: "open full Gemini CLI documentation in your browser",
253690
+ description: "open full MPD AI CLI documentation in your browser",
252420
253691
  action: async (_mainCommand, _subCommand, _args) => {
252421
- const docsUrl = "https://goo.gle/gemini-cli-docs";
253692
+ const docsUrl = "http://lb-100-123-141-85.lbaas.jpe2f.dcnw.rakuten/management/docs/";
252422
253693
  if (process25.env.SANDBOX && process25.env.SANDBOX !== "sandbox-exec") {
252423
253694
  addMessage({
252424
253695
  type: "info" /* INFO */,
@@ -252516,7 +253787,7 @@ ${docsUrl}`,
252516
253787
  const mcpServers = config2?.getMcpServers() || {};
252517
253788
  const serverNames = Object.keys(mcpServers);
252518
253789
  if (serverNames.length === 0) {
252519
- const docsUrl = "https://goo.gle/gemini-cli-docs-mcp";
253790
+ const docsUrl = "http://lb-100-123-141-85.lbaas.jpe2f.dcnw.rakuten/management/docs/tools/mcp-server.html";
252520
253791
  if (process25.env.SANDBOX && process25.env.SANDBOX !== "sandbox-exec") {
252521
253792
  addMessage({
252522
253793
  type: "info" /* INFO */,
@@ -253076,7 +254347,7 @@ ${bugReportUrl}`,
253076
254347
  if (!checkpointDir) {
253077
254348
  addMessage({
253078
254349
  type: "error" /* ERROR */,
253079
- content: "Could not determine the .gemini directory path.",
254350
+ content: "Could not determine the .mpdai directory path.",
253080
254351
  timestamp: /* @__PURE__ */ new Date()
253081
254352
  });
253082
254353
  return;
@@ -269438,9 +270709,9 @@ init_dist3();
269438
270709
  var import_strip_json_comments = __toESM(require_strip_json_comments(), 1);
269439
270710
  import * as fs36 from "fs";
269440
270711
  import * as path40 from "path";
269441
- import { homedir as homedir12 } from "os";
269442
- var SETTINGS_DIRECTORY_NAME = ".gemini";
269443
- var USER_SETTINGS_DIR = path40.join(homedir12(), SETTINGS_DIRECTORY_NAME);
270712
+ import { homedir as homedir13 } from "os";
270713
+ var SETTINGS_DIRECTORY_NAME = ".mpdai";
270714
+ var USER_SETTINGS_DIR = path40.join(homedir13(), SETTINGS_DIRECTORY_NAME);
269444
270715
  var USER_SETTINGS_PATH = path40.join(USER_SETTINGS_DIR, "settings.json");
269445
270716
  var LoadedSettings = class {
269446
270717
  constructor(user, workspace, errors) {
@@ -269513,7 +270784,7 @@ function resolveEnvVarsInObject(obj) {
269513
270784
  function findEnvFile(startDir) {
269514
270785
  let currentDir = path40.resolve(startDir);
269515
270786
  while (true) {
269516
- const geminiEnvPath = path40.join(currentDir, GEMINI_CONFIG_DIR, ".env");
270787
+ const geminiEnvPath = path40.join(currentDir, MPDAI_CONFIG_DIR, ".env");
269517
270788
  if (fs36.existsSync(geminiEnvPath)) {
269518
270789
  return geminiEnvPath;
269519
270790
  }
@@ -269523,11 +270794,11 @@ function findEnvFile(startDir) {
269523
270794
  }
269524
270795
  const parentDir = path40.dirname(currentDir);
269525
270796
  if (parentDir === currentDir || !parentDir) {
269526
- const homeGeminiEnvPath = path40.join(homedir12(), GEMINI_CONFIG_DIR, ".env");
270797
+ const homeGeminiEnvPath = path40.join(homedir13(), MPDAI_CONFIG_DIR, ".env");
269527
270798
  if (fs36.existsSync(homeGeminiEnvPath)) {
269528
270799
  return homeGeminiEnvPath;
269529
270800
  }
269530
- const homeEnvPath = path40.join(homedir12(), ".env");
270801
+ const homeEnvPath = path40.join(homedir13(), ".env");
269531
270802
  if (fs36.existsSync(homeEnvPath)) {
269532
270803
  return homeEnvPath;
269533
270804
  }
@@ -271313,7 +272584,7 @@ function stripQuotes(val) {
271313
272584
  }
271314
272585
 
271315
272586
  // node_modules/yargs-parser/build/lib/index.js
271316
- import { readFileSync as readFileSync12 } from "fs";
272587
+ import { readFileSync as readFileSync14 } from "fs";
271317
272588
  var _a5;
271318
272589
  var _b;
271319
272590
  var _c;
@@ -271340,7 +272611,7 @@ var parser4 = new YargsParser({
271340
272611
  if (typeof __require !== "undefined") {
271341
272612
  return __require(path53);
271342
272613
  } else if (path53.match(/\.json$/)) {
271343
- return JSON.parse(readFileSync12(path53, "utf8"));
272614
+ return JSON.parse(readFileSync14(path53, "utf8"));
271344
272615
  } else {
271345
272616
  throw Error("only .json config files are supported in ESM");
271346
272617
  }
@@ -271668,17 +272939,17 @@ function sync_default(start, callback) {
271668
272939
 
271669
272940
  // node_modules/yargs/lib/platform-shims/esm.mjs
271670
272941
  import { inspect } from "util";
271671
- import { readFileSync as readFileSync14 } from "fs";
272942
+ import { readFileSync as readFileSync16 } from "fs";
271672
272943
  import { fileURLToPath as fileURLToPath7 } from "url";
271673
272944
  import { basename as basename4, dirname as dirname10, extname as extname2, relative as relative6, resolve as resolve17 } from "path";
271674
272945
 
271675
272946
  // node_modules/y18n/build/lib/platform-shims/node.js
271676
- import { readFileSync as readFileSync13, statSync as statSync3, writeFile as writeFile5 } from "fs";
272947
+ import { readFileSync as readFileSync15, statSync as statSync3, writeFile as writeFile5 } from "fs";
271677
272948
  import { format as format2 } from "util";
271678
272949
  import { resolve as resolve16 } from "path";
271679
272950
  var node_default = {
271680
272951
  fs: {
271681
- readFileSync: readFileSync13,
272952
+ readFileSync: readFileSync15,
271682
272953
  writeFile: writeFile5
271683
272954
  },
271684
272955
  format: format2,
@@ -271902,7 +273173,7 @@ var esm_default3 = {
271902
273173
  nextTick: process.nextTick,
271903
273174
  stdColumns: typeof process.stdout.columns !== "undefined" ? process.stdout.columns : null
271904
273175
  },
271905
- readFileSync: readFileSync14,
273176
+ readFileSync: readFileSync16,
271906
273177
  require: () => {
271907
273178
  throw new YError(REQUIRE_ERROR);
271908
273179
  },
@@ -271926,7 +273197,7 @@ import process29 from "node:process";
271926
273197
  import * as fs37 from "fs";
271927
273198
  import * as path41 from "path";
271928
273199
  import * as os11 from "os";
271929
- var EXTENSIONS_DIRECTORY_NAME = path41.join(".gemini", "extensions");
273200
+ var EXTENSIONS_DIRECTORY_NAME = path41.join(".mpdai", "extensions");
271930
273201
  var EXTENSIONS_CONFIG_FILENAME = "gemini-extension.json";
271931
273202
  function loadExtensions(workspaceDir) {
271932
273203
  const allExtensions = [
@@ -273120,7 +274391,7 @@ init_dist3();
273120
274391
  init_langfuseClient();
273121
274392
  import { execSync as execSync2 } from "child_process";
273122
274393
  import { promises as fs38 } from "fs";
273123
- import { join as join21 } from "path";
274394
+ import { join as join22 } from "path";
273124
274395
  var DataCollector = class {
273125
274396
  langfuseClient;
273126
274397
  constructor() {
@@ -273230,7 +274501,7 @@ var DataCollector = class {
273230
274501
  // 提取元数据
273231
274502
  extractMetadata(data) {
273232
274503
  return {
273233
- cli_version: "0.1.25",
274504
+ cli_version: "0.1.31",
273234
274505
  model: process.env.CUSTOM_LLM_MODEL_NAME || "gemini",
273235
274506
  auth_type: process.env.USE_CUSTOM_LLM ? "custom_llm" : "google_oauth",
273236
274507
  project_path: data.projectPath,
@@ -273447,7 +274718,7 @@ var DataCollector = class {
273447
274718
  const walkDir = async (dir) => {
273448
274719
  const entries = await fs38.readdir(dir, { withFileTypes: true });
273449
274720
  for (const entry of entries) {
273450
- const fullPath = join21(dir, entry.name);
274721
+ const fullPath = join22(dir, entry.name);
273451
274722
  if (entry.isDirectory()) {
273452
274723
  dirCount++;
273453
274724
  await walkDir(fullPath);
@@ -273650,7 +274921,7 @@ var ToolConfirmationMessage = ({
273650
274921
  }
273651
274922
  };
273652
274923
  let bodyContent = null;
273653
- let question2;
274924
+ let question3;
273654
274925
  const options = new Array();
273655
274926
  function availableBodyContentHeight() {
273656
274927
  if (options.length === 0) {
@@ -273685,7 +274956,7 @@ var ToolConfirmationMessage = ({
273685
274956
  }
273686
274957
  );
273687
274958
  }
273688
- question2 = `Apply this change?`;
274959
+ question3 = `Apply this change?`;
273689
274960
  options.push(
273690
274961
  {
273691
274962
  label: "Yes, allow once",
@@ -273712,7 +274983,7 @@ var ToolConfirmationMessage = ({
273712
274983
  );
273713
274984
  } else if (confirmationDetails.type === "exec") {
273714
274985
  const executionProps = confirmationDetails;
273715
- question2 = `Allow execution?`;
274986
+ question3 = `Allow execution?`;
273716
274987
  options.push(
273717
274988
  {
273718
274989
  label: "Yes, allow once",
@@ -273739,7 +275010,7 @@ var ToolConfirmationMessage = ({
273739
275010
  } else if (confirmationDetails.type === "info") {
273740
275011
  const infoProps = confirmationDetails;
273741
275012
  const displayUrls = infoProps.urls && !(infoProps.urls.length === 1 && infoProps.urls[0] === infoProps.prompt);
273742
- question2 = `Do you want to proceed?`;
275013
+ question3 = `Do you want to proceed?`;
273743
275014
  options.push(
273744
275015
  {
273745
275016
  label: "Yes, allow once",
@@ -273777,7 +275048,7 @@ var ToolConfirmationMessage = ({
273777
275048
  /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Box_default, { marginLeft: 1, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Text, { color: Colors.Gray, children: mcpProps.args ? JSON.stringify(mcpProps.args, null, 2) : "No parameters" }) })
273778
275049
  ] })
273779
275050
  ] });
273780
- question2 = `Allow execution of MCP tool "${mcpProps.toolName}" from server "${mcpProps.serverName}"?`;
275051
+ question3 = `Allow execution of MCP tool "${mcpProps.toolName}" from server "${mcpProps.serverName}"?`;
273781
275052
  options.push(
273782
275053
  {
273783
275054
  label: "Yes, allow once",
@@ -273797,7 +275068,7 @@ var ToolConfirmationMessage = ({
273797
275068
  }
273798
275069
  return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(Box_default, { flexDirection: "column", padding: 1, width: childWidth, children: [
273799
275070
  /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Box_default, { flexGrow: 1, flexShrink: 1, overflow: "hidden", marginBottom: 1, children: bodyContent }),
273800
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Box_default, { marginBottom: 1, flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Text, { wrap: "truncate", children: question2 }) }),
275071
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Box_default, { marginBottom: 1, flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Text, { wrap: "truncate", children: question3 }) }),
273801
275072
  /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Box_default, { flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
273802
275073
  RadioButtonSelect,
273803
275074
  {
@@ -273949,7 +275220,7 @@ var AboutBox = ({
273949
275220
  marginY: 1,
273950
275221
  width: "100%",
273951
275222
  children: [
273952
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Box_default, { marginBottom: 1, children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { bold: true, color: Colors.AccentPurple, children: "About Gemini CLI" }) }),
275223
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Box_default, { marginBottom: 1, children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { bold: true, color: Colors.AccentPurple, children: "About MPDAI CLI" }) }),
273953
275224
  /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(Box_default, { flexDirection: "row", children: [
273954
275225
  /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Box_default, { width: "35%", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { bold: true, color: Colors.LightBlue, children: "CLI Version" }) }),
273955
275226
  /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { children: cliVersion }) })
@@ -278661,7 +279932,7 @@ async function checkForUpdates() {
278661
279932
  shouldNotifyInNpmScript: true
278662
279933
  });
278663
279934
  if (notifier.update && import_semver3.default.gt(notifier.update.latest, notifier.update.current)) {
278664
- return null;
279935
+ return `A new version is available: ${notifier.update.current} \u2192 ${notifier.update.latest}`;
278665
279936
  }
278666
279937
  return null;
278667
279938
  } catch (e2) {
@@ -279181,8 +280452,8 @@ var App2 = ({ config: config2, settings, startupWarnings = [] }) => {
279181
280452
  {
279182
280453
  type: "info" /* INFO */,
279183
280454
  text: `\u26A1 Slow response times detected. Automatically switching from ${currentModel2} to ${fallbackModel} for faster responses for the remainder of this session.
279184
- \u26A1 To avoid this you can either upgrade to Standard tier. See: https://goo.gle/set-up-gemini-code-assist
279185
- \u26A1 Or you can utilize a Gemini API Key. See: https://goo.gle/gemini-cli-docs-auth#gemini-api-key
280455
+ \u26A1 To avoid this you can either upgrade to Standard tier. See: http://lb-100-123-141-85.lbaas.jpe2f.dcnw.rakuten/mpdaicli.html
280456
+ \u26A1 Or you can utilize a MPD API Key. See: http://lb-100-123-141-85.lbaas.jpe2f.dcnw.rakuten/management
279186
280457
  \u26A1 You can switch authentication methods by typing /auth`
279187
280458
  },
279188
280459
  Date.now()
@@ -280367,7 +281638,7 @@ var homeDirectoryCheck = {
280367
281638
  fs48.realpath(os21.homedir())
280368
281639
  ]);
280369
281640
  if (workspaceRealPath === homeRealPath) {
280370
- return "You are running Gemini CLI in your home directory. It is recommended to run in a project-specific directory.";
281641
+ return "You are running MPD AI CLI in your home directory. It is recommended to run in a project-specific directory.";
280371
281642
  }
280372
281643
  return null;
280373
281644
  } catch (_err) {
@@ -280497,10 +281768,10 @@ async function runNonInteractive(config2, input) {
280497
281768
  // packages/cli/src/utils/cleanup.ts
280498
281769
  init_dist3();
280499
281770
  import { promises as fs49 } from "fs";
280500
- import { join as join22 } from "path";
281771
+ import { join as join23 } from "path";
280501
281772
  async function cleanupCheckpoints() {
280502
281773
  const tempDir = getProjectTempDir(process.cwd());
280503
- const checkpointsDir = join22(tempDir, "checkpoints");
281774
+ const checkpointsDir = join23(tempDir, "checkpoints");
280504
281775
  try {
280505
281776
  await fs49.rm(checkpointsDir, { recursive: true, force: true });
280506
281777
  } catch {
@@ -280515,24 +281786,24 @@ init_EnvConfigManager();
280515
281786
  init_mpdaiConfig();
280516
281787
  import * as fs50 from "fs";
280517
281788
  import * as path52 from "path";
280518
- import { homedir as homedir15 } from "os";
281789
+ import { homedir as homedir16 } from "os";
280519
281790
  function initializeLangfuseConfig() {
280520
- const langfuseDir = path52.join(homedir15(), ".gemini");
281791
+ const langfuseDir = path52.join(homedir16(), ".mpdai");
280521
281792
  const settingsFile = path52.join(langfuseDir, "settings.conf");
280522
281793
  const isDebugMode = process.env.DEBUG === "true" || process.env.DEBUG_MODE === "true" || process.env.dev === "true";
280523
281794
  try {
280524
281795
  if (!fs50.existsSync(langfuseDir)) {
280525
281796
  if (isDebugMode) {
280526
- console.log("\u{1F4C1} Creating .gemini directory...");
281797
+ console.log("\u{1F4C1} Creating .mpdai directory...");
280527
281798
  }
280528
281799
  fs50.mkdirSync(langfuseDir, { recursive: true });
280529
281800
  if (isDebugMode) {
280530
- console.log("\u2705 .gemini directory created successfully");
281801
+ console.log("\u2705 .mpdai directory created successfully");
280531
281802
  }
280532
281803
  }
280533
281804
  if (!fs50.existsSync(settingsFile)) {
280534
281805
  if (isDebugMode) {
280535
- console.log("\u{1F4DD} Creating .gemini/settings.conf...");
281806
+ console.log("\u{1F4DD} Creating .mpdai/settings.conf...");
280536
281807
  }
280537
281808
  const defaultSettings = {
280538
281809
  "secretKey": "sk-lf-9da9fdd0-2198-41e6-a1fc-f1abeb08ddff",
@@ -280543,11 +281814,11 @@ function initializeLangfuseConfig() {
280543
281814
  };
280544
281815
  fs50.writeFileSync(settingsFile, JSON.stringify(defaultSettings, null, 2));
280545
281816
  if (isDebugMode) {
280546
- console.log("\u2705 .gemini/settings.conf created successfully");
281817
+ console.log("\u2705 .mpdai/settings.conf created successfully");
280547
281818
  }
280548
281819
  } else {
280549
281820
  if (isDebugMode) {
280550
- console.log("\u2705 .gemini/settings.conf already exists");
281821
+ console.log("\u2705 .mpdai/settings.conf already exists");
280551
281822
  }
280552
281823
  }
280553
281824
  } catch (error) {
@@ -280592,7 +281863,121 @@ function loadStartupConfig() {
280592
281863
 
280593
281864
  // packages/cli/src/gemini.tsx
280594
281865
  init_dist3();
281866
+
281867
+ // packages/cli/src/routerCli.ts
281868
+ import { run as runRouter2 } from "@mpdai/router";
281869
+ import { showStatus as showStatus2, executeCodeCommand as executeCodeCommand2, runModelSelector as runModelSelector2 } from "@mpdai/router";
281870
+ import { isServiceRunning as isServiceRunning2, cleanupPidFile as cleanupPidFile2 } from "@mpdai/router";
281871
+ import { PID_FILE as PID_FILE2, REFERENCE_COUNT_FILE as REFERENCE_COUNT_FILE2 } from "@mpdai/router";
281872
+ import { readFileSync as readFileSync18, existsSync as existsSync18, unlinkSync as unlinkSync3 } from "fs";
281873
+ async function waitForService2(timeout2 = 1e4, initialDelay = 1e3) {
281874
+ await new Promise((resolve18) => setTimeout(resolve18, initialDelay));
281875
+ const startTime = Date.now();
281876
+ while (Date.now() - startTime < timeout2) {
281877
+ const isRunning = await isServiceRunning2();
281878
+ if (isRunning) {
281879
+ await new Promise((resolve18) => setTimeout(resolve18, 500));
281880
+ return true;
281881
+ }
281882
+ await new Promise((resolve18) => setTimeout(resolve18, 100));
281883
+ }
281884
+ return false;
281885
+ }
281886
+ async function handleRouterCommand(command, args) {
281887
+ if (command !== "router") {
281888
+ return false;
281889
+ }
281890
+ const subCommand = args[0];
281891
+ const isRunning = await isServiceRunning2();
281892
+ switch (subCommand) {
281893
+ case "start":
281894
+ await runRouter2();
281895
+ return true;
281896
+ case "stop":
281897
+ try {
281898
+ const pid = parseInt(readFileSync18(PID_FILE2, "utf-8"));
281899
+ process.kill(pid);
281900
+ cleanupPidFile2();
281901
+ if (existsSync18(REFERENCE_COUNT_FILE2)) {
281902
+ try {
281903
+ unlinkSync3(REFERENCE_COUNT_FILE2);
281904
+ } catch (e2) {
281905
+ }
281906
+ }
281907
+ console.log("MPD AI router service has been successfully stopped.");
281908
+ } catch (e2) {
281909
+ console.log("Failed to stop the service. It may have already been stopped.");
281910
+ cleanupPidFile2();
281911
+ }
281912
+ return true;
281913
+ case "restart":
281914
+ try {
281915
+ const pid = parseInt(readFileSync18(PID_FILE2, "utf-8"));
281916
+ process.kill(pid);
281917
+ cleanupPidFile2();
281918
+ if (existsSync18(REFERENCE_COUNT_FILE2)) {
281919
+ try {
281920
+ unlinkSync3(REFERENCE_COUNT_FILE2);
281921
+ } catch (e2) {
281922
+ }
281923
+ }
281924
+ console.log("MPD AI router service has been stopped.");
281925
+ } catch (e2) {
281926
+ console.log("Service was not running or failed to stop.");
281927
+ cleanupPidFile2();
281928
+ }
281929
+ console.log("Starting MPD AI router service...");
281930
+ await runRouter2();
281931
+ return true;
281932
+ case "status":
281933
+ await showStatus2();
281934
+ return true;
281935
+ case "code":
281936
+ if (!isRunning) {
281937
+ console.log("Service not running, starting service...");
281938
+ await runRouter2();
281939
+ if (await waitForService2()) {
281940
+ const codeArgs = args.slice(1);
281941
+ executeCodeCommand2(codeArgs);
281942
+ } else {
281943
+ console.error("Service startup timeout, please manually run `mpdai router start` to start the service");
281944
+ process.exit(1);
281945
+ }
281946
+ } else {
281947
+ const codeArgs = args.slice(1);
281948
+ executeCodeCommand2(codeArgs);
281949
+ }
281950
+ return true;
281951
+ case "model":
281952
+ await runModelSelector2();
281953
+ return true;
281954
+ default:
281955
+ console.log(`
281956
+ Usage: mpdai router [command]
281957
+
281958
+ Commands:
281959
+ start Start server
281960
+ stop Stop server
281961
+ restart Restart server
281962
+ status Show server status
281963
+ code Execute claude command
281964
+ model Interactive model selection and configuration
281965
+
281966
+ Example:
281967
+ mpdai router start
281968
+ mpdai router code "Write a Hello World"
281969
+ mpdai router model
281970
+ `);
281971
+ return true;
281972
+ }
281973
+ }
281974
+
281975
+ // packages/cli/src/gemini.tsx
281976
+ var readlineSync2 = __toESM(require_readline_sync(), 1);
280595
281977
  var import_jsx_runtime52 = __toESM(require_jsx_runtime(), 1);
281978
+ import { executeCodeCommand as executeCodeCommand3 } from "@mpdai/router";
281979
+ import { isServiceRunning as isServiceRunning3 } from "@mpdai/router";
281980
+ import { run as runRouter3 } from "@mpdai/router";
280596
281981
  function getNodeMemoryArgs(config2) {
280597
281982
  const totalMemoryMB = os22.totalmem() / (1024 * 1024);
280598
281983
  const heapStats = v8.getHeapStatistics();
@@ -280628,7 +282013,110 @@ async function relaunchWithAdditionalArgs(additionalArgs) {
280628
282013
  await new Promise((resolve18) => child.on("close", resolve18));
280629
282014
  process.exit(0);
280630
282015
  }
282016
+ async function waitForService3(timeout2 = 1e4, initialDelay = 1e3) {
282017
+ await new Promise((resolve18) => setTimeout(resolve18, initialDelay));
282018
+ const startTime = Date.now();
282019
+ while (Date.now() - startTime < timeout2) {
282020
+ const isRunning = await isServiceRunning3();
282021
+ if (isRunning) {
282022
+ await new Promise((resolve18) => setTimeout(resolve18, 500));
282023
+ return true;
282024
+ }
282025
+ await new Promise((resolve18) => setTimeout(resolve18, 100));
282026
+ }
282027
+ return false;
282028
+ }
282029
+ async function installClaudeCode() {
282030
+ return new Promise((resolve18) => {
282031
+ console.log("Installing @anthropic-ai/claude-code@2.0.35...");
282032
+ const installProcess = spawn10("npm", ["install", "-g", "@anthropic-ai/claude-code@2.0.35"], {
282033
+ stdio: "inherit",
282034
+ shell: true
282035
+ });
282036
+ installProcess.on("close", (code) => {
282037
+ if (code === 0) {
282038
+ console.log("\u2705 Claude Code installed successfully!");
282039
+ resolve18(true);
282040
+ } else {
282041
+ console.error("\u274C Failed to install Claude Code");
282042
+ resolve18(false);
282043
+ }
282044
+ });
282045
+ installProcess.on("error", (error) => {
282046
+ console.error("\u274C Error installing Claude Code:", error.message);
282047
+ resolve18(false);
282048
+ });
282049
+ });
282050
+ }
282051
+ async function handleClaudeCodeCommand(args) {
282052
+ const isRunning = await isServiceRunning3();
282053
+ if (!isRunning) {
282054
+ console.log("Service not running, starting service...");
282055
+ runRouter3();
282056
+ if (!await waitForService3()) {
282057
+ console.error("Service startup timeout, please manually run `mpdai router start` to start the service");
282058
+ process.exit(1);
282059
+ }
282060
+ }
282061
+ try {
282062
+ const executeWithErrorHandling = () => {
282063
+ return new Promise((resolve18, reject) => {
282064
+ const checkProcess = spawn10("claude", ["--version"], {
282065
+ stdio: "pipe",
282066
+ shell: true
282067
+ });
282068
+ checkProcess.on("error", async (error) => {
282069
+ console.error("\u274C Claude Code is not installed or not found in PATH");
282070
+ console.log("\nTo install Claude Code, run:");
282071
+ console.log(" npm install -g @anthropic-ai/claude-code@2.0.35\n");
282072
+ if (process.stdin.isTTY && process.stdout.isTTY) {
282073
+ const answer = readlineSync2.question("Would you like to install it now? (y/n): ");
282074
+ const shouldInstall = answer.toLowerCase() === "y" || answer.toLowerCase() === "yes";
282075
+ if (shouldInstall) {
282076
+ const installed = await installClaudeCode();
282077
+ if (installed) {
282078
+ executeCodeCommand3(args);
282079
+ resolve18();
282080
+ } else {
282081
+ reject(new Error("Installation failed"));
282082
+ }
282083
+ } else {
282084
+ reject(new Error("User declined installation"));
282085
+ }
282086
+ } else {
282087
+ reject(new Error("Claude Code not found and cannot install in non-interactive mode"));
282088
+ }
282089
+ });
282090
+ checkProcess.on("close", (code) => {
282091
+ if (code === 0) {
282092
+ executeCodeCommand3(args);
282093
+ resolve18();
282094
+ } else {
282095
+ executeCodeCommand3(args);
282096
+ resolve18();
282097
+ }
282098
+ });
282099
+ });
282100
+ };
282101
+ await executeWithErrorHandling();
282102
+ } catch (error) {
282103
+ console.error("Failed to execute Claude Code command:", error instanceof Error ? error.message : String(error));
282104
+ process.exit(1);
282105
+ }
282106
+ return true;
282107
+ }
280631
282108
  async function main() {
282109
+ const args = process.argv.slice(2);
282110
+ if (args.length > 0 && args[0] === "router") {
282111
+ const handled = await handleRouterCommand("router", args.slice(1));
282112
+ if (handled) {
282113
+ return;
282114
+ }
282115
+ }
282116
+ if (args.length > 0 && args[0] === "claude" && args.length > 1 && args[1] === "code") {
282117
+ await handleClaudeCodeCommand(args.slice(2));
282118
+ return;
282119
+ }
280632
282120
  loadStartupConfig();
280633
282121
  const workspaceRoot = process.cwd();
280634
282122
  let settings = loadSettings(workspaceRoot);
@@ -280839,6 +282327,17 @@ async function performUserAuthentication() {
280839
282327
  if (isDebugMode) {
280840
282328
  console.log(`Environment configuration updated: ${envPath}`);
280841
282329
  }
282330
+ try {
282331
+ const { updateRouterConfigFromModel } = await import("@mpdai/router");
282332
+ await updateRouterConfigFromModel(defaultModel);
282333
+ if (isDebugMode) {
282334
+ console.log("Router configuration updated with default model");
282335
+ }
282336
+ } catch (error) {
282337
+ if (isDebugMode) {
282338
+ console.warn("Failed to update router-config.json:", error.message);
282339
+ }
282340
+ }
280842
282341
  if (authResponse.mcpServers && authResponse.mcpServers.length > 0) {
280843
282342
  if (isDebugMode) {
280844
282343
  console.log(`Found ${authResponse.mcpServers.length} MCP servers in user configuration`);