@xagent/x-cli 1.1.70 → 1.1.72

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  <!-- Test comment for PR creation -->
2
2
 
3
- ## 1.1.70 – Logo Assets & NPM Publication Complete
3
+ ## 1.1.72 – Logo Assets & NPM Publication Complete
4
4
 
5
5
  ✅ **Live on NPM**: [@xagent/x-cli](https://www.npmjs.com/package/@xagent/x-cli) - Fully published and ready for global installation
6
6
 
package/dist/index.js CHANGED
@@ -60,7 +60,8 @@ var init_settings_manager = __esm({
60
60
  "grok-3-mini-fast"
61
61
  ],
62
62
  verbosityLevel: "quiet",
63
- explainLevel: "brief"
63
+ explainLevel: "brief",
64
+ requireConfirmation: true
64
65
  };
65
66
  DEFAULT_PROJECT_SETTINGS = {
66
67
  model: "grok-code-fast-1"
@@ -9023,6 +9024,24 @@ Current working directory: ${process.cwd()}`
9023
9024
  async executeTool(toolCall) {
9024
9025
  try {
9025
9026
  const args = JSON.parse(toolCall.function.arguments);
9027
+ const settingsManager = getSettingsManager();
9028
+ const requireConfirmation = settingsManager.getUserSetting("requireConfirmation") ?? true;
9029
+ if (requireConfirmation) {
9030
+ const needsConfirmation = ["create_file", "str_replace_editor", "bash"].includes(toolCall.function.name);
9031
+ if (needsConfirmation) {
9032
+ const confirmationResult = await this.confirmationTool.requestConfirmation({
9033
+ operation: toolCall.function.name,
9034
+ filename: args.path || args.command || "unknown",
9035
+ description: `Execute ${toolCall.function.name} operation`
9036
+ });
9037
+ if (!confirmationResult.success) {
9038
+ return {
9039
+ success: false,
9040
+ error: confirmationResult.error || "Operation cancelled by user"
9041
+ };
9042
+ }
9043
+ }
9044
+ }
9026
9045
  switch (toolCall.function.name) {
9027
9046
  case "view_file":
9028
9047
  try {
@@ -14655,7 +14674,7 @@ ${guardrail.createdFrom ? `- Created from incident: ${guardrail.createdFrom}` :
14655
14674
  var package_default = {
14656
14675
  type: "module",
14657
14676
  name: "@xagent/x-cli",
14658
- version: "1.1.70",
14677
+ version: "1.1.72",
14659
14678
  description: "An open-source AI agent that brings the power of Grok directly into your terminal.",
14660
14679
  main: "dist/index.js",
14661
14680
  module: "dist/index.js",
@@ -15131,6 +15150,7 @@ function useInputHandler({
15131
15150
  { command: "/guardrails", description: "Manage prevention rules" },
15132
15151
  { command: "/comments", description: "Add code comments to files" },
15133
15152
  { command: "/commit-and-push", description: "AI commit & push to remote" },
15153
+ { command: "/smart-push", description: "Intelligent staging, commit message generation, and push" },
15134
15154
  { command: "/exit", description: "Exit the application" }
15135
15155
  ];
15136
15156
  const availableModels = useMemo(() => {
@@ -16368,6 +16388,72 @@ Operations will now ${newLevel === "off" ? "show no explanations" : newLevel ===
16368
16388
  setChatHistory((prev) => [...prev, userEntry]);
16369
16389
  setIsProcessing(true);
16370
16390
  try {
16391
+ const branchResult = await agent.executeBashCommand("git branch --show-current");
16392
+ const currentBranch = branchResult.output?.trim() || "unknown";
16393
+ const qualityCheckEntry = {
16394
+ type: "assistant",
16395
+ content: "\u{1F50D} **Running pre-push quality checks...**",
16396
+ timestamp: /* @__PURE__ */ new Date()
16397
+ };
16398
+ setChatHistory((prev) => [...prev, qualityCheckEntry]);
16399
+ const tsCheckEntry = {
16400
+ type: "assistant",
16401
+ content: "\u{1F4DD} Checking TypeScript...",
16402
+ timestamp: /* @__PURE__ */ new Date()
16403
+ };
16404
+ setChatHistory((prev) => [...prev, tsCheckEntry]);
16405
+ const tsResult = await agent.executeBashCommand("npm run typecheck");
16406
+ if (tsResult.success) {
16407
+ const tsSuccessEntry = {
16408
+ type: "tool_result",
16409
+ content: "\u2705 TypeScript check passed",
16410
+ timestamp: /* @__PURE__ */ new Date(),
16411
+ toolCall: {
16412
+ id: `ts_check_${Date.now()}`,
16413
+ type: "function",
16414
+ function: {
16415
+ name: "bash",
16416
+ arguments: JSON.stringify({ command: "npm run typecheck" })
16417
+ }
16418
+ },
16419
+ toolResult: tsResult
16420
+ };
16421
+ setChatHistory((prev) => [...prev, tsSuccessEntry]);
16422
+ } else {
16423
+ const tsFailEntry = {
16424
+ type: "assistant",
16425
+ content: `\u274C **TypeScript check failed**
16426
+
16427
+ ${tsResult.error || tsResult.output}`,
16428
+ timestamp: /* @__PURE__ */ new Date()
16429
+ };
16430
+ setChatHistory((prev) => [...prev, tsFailEntry]);
16431
+ setIsProcessing(false);
16432
+ clearInput();
16433
+ return true;
16434
+ }
16435
+ const lintCheckEntry = {
16436
+ type: "assistant",
16437
+ content: "\u{1F9F9} Running ESLint...",
16438
+ timestamp: /* @__PURE__ */ new Date()
16439
+ };
16440
+ setChatHistory((prev) => [...prev, lintCheckEntry]);
16441
+ const lintResult = await agent.executeBashCommand("npm run lint");
16442
+ const lintSuccessEntry = {
16443
+ type: "tool_result",
16444
+ content: "\u2705 ESLint check completed (warnings allowed)",
16445
+ timestamp: /* @__PURE__ */ new Date(),
16446
+ toolCall: {
16447
+ id: `lint_check_${Date.now()}`,
16448
+ type: "function",
16449
+ function: {
16450
+ name: "bash",
16451
+ arguments: JSON.stringify({ command: "npm run lint" })
16452
+ }
16453
+ },
16454
+ toolResult: lintResult
16455
+ };
16456
+ setChatHistory((prev) => [...prev, lintSuccessEntry]);
16371
16457
  const statusResult = await agent.executeBashCommand("git status --porcelain");
16372
16458
  if (!statusResult.success) {
16373
16459
  const errorEntry = {
@@ -16391,6 +16477,107 @@ Operations will now ${newLevel === "off" ? "show no explanations" : newLevel ===
16391
16477
  clearInput();
16392
16478
  return true;
16393
16479
  }
16480
+ const prePullAddResult = await agent.executeBashCommand("git add .");
16481
+ if (!prePullAddResult.success) {
16482
+ const errorEntry = {
16483
+ type: "assistant",
16484
+ content: `\u274C **Failed to stage changes**
16485
+
16486
+ ${prePullAddResult.error || "Unknown error"}`,
16487
+ timestamp: /* @__PURE__ */ new Date()
16488
+ };
16489
+ setChatHistory((prev) => [...prev, errorEntry]);
16490
+ setIsProcessing(false);
16491
+ clearInput();
16492
+ return true;
16493
+ }
16494
+ const stashResult = await agent.executeBashCommand("git stash push --include-untracked --message 'smart-push temporary stash'");
16495
+ if (!stashResult.success) {
16496
+ const errorEntry = {
16497
+ type: "assistant",
16498
+ content: `\u274C **Failed to stash changes**
16499
+
16500
+ ${stashResult.error || "Unknown error"}`,
16501
+ timestamp: /* @__PURE__ */ new Date()
16502
+ };
16503
+ setChatHistory((prev) => [...prev, errorEntry]);
16504
+ setIsProcessing(false);
16505
+ clearInput();
16506
+ return true;
16507
+ }
16508
+ const pullEntry = {
16509
+ type: "assistant",
16510
+ content: "\u{1F504} Pulling latest changes...",
16511
+ timestamp: /* @__PURE__ */ new Date()
16512
+ };
16513
+ setChatHistory((prev) => [...prev, pullEntry]);
16514
+ const rebaseCheck = await agent.executeBashCommand("test -d .git/rebase-apply -o -d .git/rebase-merge -o -f .git/MERGE_HEAD && echo 'ongoing' || echo 'clean'");
16515
+ if (rebaseCheck.output?.includes("ongoing")) {
16516
+ const cleanupEntry = {
16517
+ type: "assistant",
16518
+ content: "\u26A0\uFE0F Git operation in progress - cleaning up...",
16519
+ timestamp: /* @__PURE__ */ new Date()
16520
+ };
16521
+ setChatHistory((prev) => [...prev, cleanupEntry]);
16522
+ await agent.executeBashCommand("git rebase --abort 2>/dev/null || git merge --abort 2>/dev/null || true");
16523
+ }
16524
+ let pullResult = await agent.executeBashCommand(`git pull --rebase origin ${currentBranch}`);
16525
+ if (!pullResult.success) {
16526
+ pullResult = await agent.executeBashCommand(`git pull origin ${currentBranch}`);
16527
+ if (pullResult.success) {
16528
+ const mergeFallbackEntry = {
16529
+ type: "assistant",
16530
+ content: "\u26A0\uFE0F Rebase failed, fell back to merge",
16531
+ timestamp: /* @__PURE__ */ new Date()
16532
+ };
16533
+ setChatHistory((prev) => [...prev, mergeFallbackEntry]);
16534
+ }
16535
+ }
16536
+ if (pullResult.success) {
16537
+ const pullSuccessEntry = {
16538
+ type: "tool_result",
16539
+ content: pullResult.output?.includes("Successfully rebased") ? "\u2705 Successfully rebased local changes" : "\u2705 Successfully pulled latest changes",
16540
+ timestamp: /* @__PURE__ */ new Date()
16541
+ };
16542
+ setChatHistory((prev) => [...prev, pullSuccessEntry]);
16543
+ const popStashResult = await agent.executeBashCommand("git stash pop");
16544
+ if (!popStashResult.success) {
16545
+ const errorEntry = {
16546
+ type: "assistant",
16547
+ content: `\u26A0\uFE0F **Failed to restore stashed changes**
16548
+
16549
+ ${popStashResult.error || "Unknown error"}
16550
+
16551
+ \u{1F4A1} Your changes may be lost. Check git stash list.`,
16552
+ timestamp: /* @__PURE__ */ new Date()
16553
+ };
16554
+ setChatHistory((prev) => [...prev, errorEntry]);
16555
+ setIsProcessing(false);
16556
+ clearInput();
16557
+ return true;
16558
+ } else {
16559
+ const popSuccessEntry = {
16560
+ type: "tool_result",
16561
+ content: "\u2705 Changes restored from stash",
16562
+ timestamp: /* @__PURE__ */ new Date()
16563
+ };
16564
+ setChatHistory((prev) => [...prev, popSuccessEntry]);
16565
+ }
16566
+ } else {
16567
+ const pullFailEntry = {
16568
+ type: "assistant",
16569
+ content: `\u274C **Pull failed**
16570
+
16571
+ ${pullResult.error || pullResult.output}
16572
+
16573
+ \u{1F4A1} Check git status and resolve any conflicts`,
16574
+ timestamp: /* @__PURE__ */ new Date()
16575
+ };
16576
+ setChatHistory((prev) => [...prev, pullFailEntry]);
16577
+ setIsProcessing(false);
16578
+ clearInput();
16579
+ return true;
16580
+ }
16394
16581
  const addResult = await agent.executeBashCommand("git add .");
16395
16582
  if (!addResult.success) {
16396
16583
  const errorEntry = {
@@ -16421,13 +16608,15 @@ ${addResult.error || "Unknown error"}`,
16421
16608
  };
16422
16609
  setChatHistory((prev) => [...prev, addEntry]);
16423
16610
  const diffResult = await agent.executeBashCommand("git diff --cached");
16611
+ const maxDiffLength = 5e4;
16612
+ const truncatedDiff = diffResult.output ? diffResult.output.length > maxDiffLength ? diffResult.output.substring(0, maxDiffLength) + "\n... (truncated due to length)" : diffResult.output : "No staged changes shown";
16424
16613
  const commitPrompt = `Generate a concise, professional git commit message for these changes:
16425
16614
 
16426
16615
  Git Status:
16427
16616
  ${statusResult.output}
16428
16617
 
16429
16618
  Git Diff (staged changes):
16430
- ${diffResult.output || "No staged changes shown"}
16619
+ ${truncatedDiff}
16431
16620
 
16432
16621
  Follow conventional commit format (feat:, fix:, docs:, etc.) and keep it under 72 characters.
16433
16622
  Respond with ONLY the commit message, no additional text.`;
@@ -16435,51 +16624,70 @@ Respond with ONLY the commit message, no additional text.`;
16435
16624
  let streamingEntry = null;
16436
16625
  let accumulatedCommitContent = "";
16437
16626
  let lastCommitUpdateTime = Date.now();
16438
- for await (const chunk of agent.processUserMessageStream(commitPrompt)) {
16439
- if (chunk.type === "content" && chunk.content) {
16440
- accumulatedCommitContent += chunk.content;
16441
- const now = Date.now();
16442
- if (now - lastCommitUpdateTime >= 150) {
16443
- commitMessage += accumulatedCommitContent;
16444
- if (!streamingEntry) {
16445
- const newEntry = {
16446
- type: "assistant",
16447
- content: `\u{1F916} Generating commit message...
16627
+ try {
16628
+ for await (const chunk of agent.processUserMessageStream(commitPrompt)) {
16629
+ if (chunk.type === "content" && chunk.content) {
16630
+ accumulatedCommitContent += chunk.content;
16631
+ const now = Date.now();
16632
+ if (now - lastCommitUpdateTime >= 150) {
16633
+ commitMessage += accumulatedCommitContent;
16634
+ if (!streamingEntry) {
16635
+ const newEntry = {
16636
+ type: "assistant",
16637
+ content: `\u{1F916} Generating commit message...
16448
16638
 
16449
16639
  ${commitMessage}`,
16450
- timestamp: /* @__PURE__ */ new Date(),
16451
- isStreaming: true
16452
- };
16453
- setChatHistory((prev) => [...prev, newEntry]);
16454
- streamingEntry = newEntry;
16455
- } else {
16640
+ timestamp: /* @__PURE__ */ new Date(),
16641
+ isStreaming: true
16642
+ };
16643
+ setChatHistory((prev) => [...prev, newEntry]);
16644
+ streamingEntry = newEntry;
16645
+ } else {
16646
+ setChatHistory(
16647
+ (prev) => prev.map(
16648
+ (entry, idx) => idx === prev.length - 1 && entry.isStreaming ? {
16649
+ ...entry,
16650
+ content: `\u{1F916} Generating commit message...
16651
+
16652
+ ${commitMessage}`
16653
+ } : entry
16654
+ )
16655
+ );
16656
+ }
16657
+ accumulatedCommitContent = "";
16658
+ lastCommitUpdateTime = now;
16659
+ }
16660
+ } else if (chunk.type === "done") {
16661
+ if (streamingEntry) {
16456
16662
  setChatHistory(
16457
16663
  (prev) => prev.map(
16458
- (entry, idx) => idx === prev.length - 1 && entry.isStreaming ? {
16664
+ (entry) => entry.isStreaming ? {
16459
16665
  ...entry,
16460
- content: `\u{1F916} Generating commit message...
16461
-
16462
- ${commitMessage}`
16666
+ content: `\u2705 Generated commit message: "${commitMessage.trim()}"`,
16667
+ isStreaming: false
16463
16668
  } : entry
16464
16669
  )
16465
16670
  );
16466
16671
  }
16467
- accumulatedCommitContent = "";
16468
- lastCommitUpdateTime = now;
16469
- }
16470
- } else if (chunk.type === "done") {
16471
- if (streamingEntry) {
16472
- setChatHistory(
16473
- (prev) => prev.map(
16474
- (entry) => entry.isStreaming ? {
16475
- ...entry,
16476
- content: `\u2705 Generated commit message: "${commitMessage.trim()}"`,
16477
- isStreaming: false
16478
- } : entry
16479
- )
16480
- );
16672
+ break;
16481
16673
  }
16482
- break;
16674
+ }
16675
+ } catch (error) {
16676
+ commitMessage = "feat: update files";
16677
+ const errorEntry = {
16678
+ type: "assistant",
16679
+ content: `\u26A0\uFE0F **AI commit message generation failed**: ${error.message}
16680
+
16681
+ Using fallback message: "${commitMessage}"`,
16682
+ timestamp: /* @__PURE__ */ new Date()
16683
+ };
16684
+ setChatHistory((prev) => [...prev, errorEntry]);
16685
+ if (streamingEntry) {
16686
+ setChatHistory(
16687
+ (prev) => prev.map(
16688
+ (entry) => entry.isStreaming ? { ...entry, isStreaming: false } : entry
16689
+ )
16690
+ );
16483
16691
  }
16484
16692
  }
16485
16693
  const cleanCommitMessage = commitMessage.trim().replace(/^["']|["']$/g, "");
@@ -16540,7 +16748,7 @@ ${commitMessage}`
16540
16748
  timestamp: /* @__PURE__ */ new Date()
16541
16749
  };
16542
16750
  setChatHistory((prev) => [...prev, branchSuccessEntry]);
16543
- const prResult = await agent.executeBashCommand(`gh pr create --title "${cleanCommitMessage}" --body "Auto-generated PR from smart-push" --head ${featureBranch} --base main`);
16751
+ const prResult = await agent.executeBashCommand(`gh pr create --title "${cleanCommitMessage}" --body "Auto-generated PR from smart-push" --head ${featureBranch} --base ${currentBranch}`);
16544
16752
  if (prResult.success) {
16545
16753
  const prUrl = prResult.output?.match(/https:\/\/github\.com\/[^\s]+/)?.[0];
16546
16754
  const prSuccessEntry = {
@@ -16563,7 +16771,7 @@ ${commitMessage}`
16563
16771
 
16564
16772
  \u{1F4A1} **Create PR Manually**:
16565
16773
  \u2022 Go to GitHub repository
16566
- \u2022 Create PR from \`${featureBranch}\` \u2192 \`main\`
16774
+ \u2022 Create PR from \`${featureBranch}\` \u2192 \`${currentBranch}\`
16567
16775
  \u2022 Title: \`${cleanCommitMessage}\``,
16568
16776
  timestamp: /* @__PURE__ */ new Date()
16569
16777
  };
@@ -19398,6 +19606,43 @@ function createMCPCommand() {
19398
19606
  });
19399
19607
  return mcpCommand;
19400
19608
  }
19609
+
19610
+ // src/commands/set-name.ts
19611
+ init_settings_manager();
19612
+ function createSetNameCommand() {
19613
+ const setNameCommand = new Command("set-name");
19614
+ setNameCommand.description("Set a custom name for the AI assistant").argument("<name>", "The name to set for the assistant").action(async (name) => {
19615
+ try {
19616
+ const settingsManager = getSettingsManager();
19617
+ settingsManager.updateUserSetting("assistantName", name);
19618
+ console.log(chalk.green(`\u2705 Assistant name set to: ${name}`));
19619
+ } catch (error) {
19620
+ console.error(chalk.red(`\u274C Failed to set assistant name: ${error.message}`));
19621
+ process.exit(1);
19622
+ }
19623
+ });
19624
+ return setNameCommand;
19625
+ }
19626
+
19627
+ // src/commands/toggle-confirmations.ts
19628
+ init_settings_manager();
19629
+ function createToggleConfirmationsCommand() {
19630
+ const toggleCommand = new Command("toggle-confirmations");
19631
+ toggleCommand.description("Toggle the requirement for user confirmation on file operations and bash commands").action(async () => {
19632
+ try {
19633
+ const settingsManager = getSettingsManager();
19634
+ const currentValue = settingsManager.getUserSetting("requireConfirmation") ?? true;
19635
+ const newValue = !currentValue;
19636
+ settingsManager.updateUserSetting("requireConfirmation", newValue);
19637
+ console.log(chalk.green(`\u2705 Confirmation requirement ${newValue ? "enabled" : "disabled"}`));
19638
+ console.log(`File operations and bash commands will ${newValue ? "now" : "no longer"} require confirmation.`);
19639
+ } catch (error) {
19640
+ console.error(chalk.red(`\u274C Failed to toggle confirmations: ${error.message}`));
19641
+ process.exit(1);
19642
+ }
19643
+ });
19644
+ return toggleCommand;
19645
+ }
19401
19646
  var CONTEXT_BUDGET_BYTES = 280 * 1024;
19402
19647
  var MAX_SUMMARY_LENGTH = 2e3;
19403
19648
  function loadMarkdownDirectory(dirPath) {
@@ -19800,8 +20045,11 @@ program.name("grok").description(
19800
20045
  process.exit(1);
19801
20046
  }
19802
20047
  const agent = new GrokAgent(apiKey, baseURL, model, maxToolRounds);
20048
+ const settingsManager = getSettingsManager();
20049
+ const assistantName = settingsManager.getUserSetting("assistantName") || "X CLI";
19803
20050
  if (!options.quiet) {
19804
- console.log("\u{1F916} Starting X CLI Conversational Assistant...\n");
20051
+ console.log(`\u{1F916} Starting ${assistantName} Conversational Assistant...
20052
+ `);
19805
20053
  }
19806
20054
  if (!options.quiet) {
19807
20055
  try {
@@ -19880,6 +20128,8 @@ gitCommand.command("commit-and-push").description("Generate AI commit message an
19880
20128
  }
19881
20129
  });
19882
20130
  program.addCommand(createMCPCommand());
20131
+ program.addCommand(createSetNameCommand());
20132
+ program.addCommand(createToggleConfirmationsCommand());
19883
20133
  program.parse();
19884
20134
  //# sourceMappingURL=index.js.map
19885
20135
  //# sourceMappingURL=index.js.map