@xagent/x-cli 1.1.68 → 1.1.70

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.68 – Logo Assets & NPM Publication Complete
3
+ ## 1.1.70 – 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
 
@@ -47,6 +47,16 @@ A conversational AI CLI tool powered by Grok with **Claude Code-level intelligen
47
47
  - **📋 User Approval Workflow**: Complete plan review and confirmation before execution
48
48
  - **⚡ Performance Optimized**: Fast exploration (1-15 seconds) with intelligent caching and filtering
49
49
 
50
+ ### 🚀 **P5: Research → Recommend → Execute → Auto-Doc Workflow** (Latest)
51
+
52
+ - **🤖 Research Phase**: Intelligent context loading from `.agent/` docs with Issues/Options analysis
53
+ - **💡 Recommend Phase**: Structured decision framework with trade-offs, effort/risk analysis, and confidence scoring
54
+ - **⚡ Execute Phase**: Sequential TODO execution with adaptive recovery, real-time diffs, and safety guarantees
55
+ - **📝 Auto-Doc Phase**: Automatic completion documentation with lesson learning and SOP candidate detection
56
+ - **🛡️ Safety First**: All changes have patches, backups, and git commits; adaptive error recovery
57
+ - **🔄 Resilient**: Handles execution failures gracefully with re-planning capabilities
58
+ - **📚 Knowledge Base**: Builds institutional memory through automatic documentation accumulation
59
+
50
60
  ### 🎨 **P4: UX Refinement - Claude Code Feel**
51
61
 
52
62
  - **🎭 Enhanced Welcome Banner**: Professional ASCII art with context-aware status display
@@ -1087,7 +1097,7 @@ _Want to see your name here? Check out our [Contributing Guide](CONTRIBUTING.md)
1087
1097
  ### How to Contribute
1088
1098
 
1089
1099
  1. **Fork** the repository on GitHub
1090
- 2. **Clone** your fork locally: `git clone https://github.com/yourusername/x-cli-hurry-mode.git`
1100
+ 2. **Clone** your fork locally: `git clone https://github.com/yourusername/x-cli.git`
1091
1101
  3. **Create** a feature branch: `git checkout -b feature/your-feature-name`
1092
1102
  4. **Make** your changes and commit them: `git commit -m "feat: add awesome feature"`
1093
1103
  5. **Push** to your fork: `git push origin feature/your-feature-name`
package/dist/index.js CHANGED
@@ -7039,10 +7039,10 @@ var DependencyAnalyzerTool = class {
7039
7039
  const circularDeps = [];
7040
7040
  const visited = /* @__PURE__ */ new Set();
7041
7041
  const visiting = /* @__PURE__ */ new Set();
7042
- const dfs = (filePath, path30) => {
7042
+ const dfs = (filePath, path31) => {
7043
7043
  if (visiting.has(filePath)) {
7044
- const cycleStart = path30.indexOf(filePath);
7045
- const cycle = path30.slice(cycleStart).concat([filePath]);
7044
+ const cycleStart = path31.indexOf(filePath);
7045
+ const cycle = path31.slice(cycleStart).concat([filePath]);
7046
7046
  circularDeps.push({
7047
7047
  cycle: cycle.map((fp) => graph.nodes.get(fp)?.filePath || fp),
7048
7048
  severity: cycle.length <= 2 ? "error" : "warning",
@@ -7058,7 +7058,7 @@ var DependencyAnalyzerTool = class {
7058
7058
  if (node) {
7059
7059
  for (const dependency of node.dependencies) {
7060
7060
  if (graph.nodes.has(dependency)) {
7061
- dfs(dependency, [...path30, filePath]);
7061
+ dfs(dependency, [...path31, filePath]);
7062
7062
  }
7063
7063
  }
7064
7064
  }
@@ -9030,10 +9030,10 @@ Current working directory: ${process.cwd()}`
9030
9030
  return await this.textEditor.view(args.path, range);
9031
9031
  } catch (error) {
9032
9032
  console.warn(`view_file tool failed, falling back to bash: ${error.message}`);
9033
- const path30 = args.path;
9034
- let command = `cat "${path30}"`;
9033
+ const path31 = args.path;
9034
+ let command = `cat "${path31}"`;
9035
9035
  if (args.start_line && args.end_line) {
9036
- command = `sed -n '${args.start_line},${args.end_line}p' "${path30}"`;
9036
+ command = `sed -n '${args.start_line},${args.end_line}p' "${path31}"`;
9037
9037
  }
9038
9038
  return await this.bash.execute(command);
9039
9039
  }
@@ -14655,7 +14655,7 @@ ${guardrail.createdFrom ? `- Created from incident: ${guardrail.createdFrom}` :
14655
14655
  var package_default = {
14656
14656
  type: "module",
14657
14657
  name: "@xagent/x-cli",
14658
- version: "1.1.68",
14658
+ version: "1.1.70",
14659
14659
  description: "An open-source AI agent that brings the power of Grok directly into your terminal.",
14660
14660
  main: "dist/index.js",
14661
14661
  module: "dist/index.js",
@@ -14684,6 +14684,7 @@ var package_default = {
14684
14684
  "dev:watch": "npm run build && node --watch dist/index.js",
14685
14685
  start: "node dist/index.js",
14686
14686
  local: "npm run build && npm link && node dist/index.js",
14687
+ "test:workflow": "node scripts/test-workflow.js",
14687
14688
  "start:bun": "bun run dist/index.js",
14688
14689
  lint: "eslint . --ext .js,.jsx,.ts,.tsx",
14689
14690
  typecheck: "tsc --noEmit",
@@ -19397,6 +19398,119 @@ function createMCPCommand() {
19397
19398
  });
19398
19399
  return mcpCommand;
19399
19400
  }
19401
+ var CONTEXT_BUDGET_BYTES = 280 * 1024;
19402
+ var MAX_SUMMARY_LENGTH = 2e3;
19403
+ function loadMarkdownDirectory(dirPath) {
19404
+ if (!fs__default.existsSync(dirPath)) {
19405
+ return "";
19406
+ }
19407
+ const files = fs__default.readdirSync(dirPath).filter((file) => file.endsWith(".md")).sort();
19408
+ let content = "";
19409
+ for (const file of files) {
19410
+ const filePath = path7__default.join(dirPath, file);
19411
+ try {
19412
+ const fileContent = fs__default.readFileSync(filePath, "utf-8");
19413
+ content += `
19414
+
19415
+ === ${file} ===
19416
+
19417
+ ${fileContent}`;
19418
+ } catch (error) {
19419
+ console.warn(`Failed to read ${filePath}:`, error);
19420
+ }
19421
+ }
19422
+ return content;
19423
+ }
19424
+ function extractDateFromFilename(filename) {
19425
+ const match = filename.match(/^(\d{4}-\d{2}-\d{2})/);
19426
+ if (match) {
19427
+ return new Date(match[1]);
19428
+ }
19429
+ return /* @__PURE__ */ new Date(0);
19430
+ }
19431
+ function summarizeContent(content, maxLength = MAX_SUMMARY_LENGTH) {
19432
+ if (content.length <= maxLength) {
19433
+ return content;
19434
+ }
19435
+ const truncated = content.substring(0, maxLength);
19436
+ const lastNewline = truncated.lastIndexOf("\n\n");
19437
+ if (lastNewline > maxLength * 0.8) {
19438
+ return truncated.substring(0, lastNewline);
19439
+ }
19440
+ return truncated + "\n\n[...content truncated for context budget...]";
19441
+ }
19442
+ function loadTaskFiles(tasksDir, maxBudget) {
19443
+ if (!fs__default.existsSync(tasksDir)) {
19444
+ return [];
19445
+ }
19446
+ const files = fs__default.readdirSync(tasksDir).filter((file) => file.endsWith(".md")).map((filename) => {
19447
+ const filePath = path7__default.join(tasksDir, filename);
19448
+ const content = fs__default.readFileSync(filePath, "utf-8");
19449
+ return {
19450
+ filename,
19451
+ content,
19452
+ size: Buffer.byteLength(content, "utf-8"),
19453
+ date: extractDateFromFilename(filename),
19454
+ isSummarized: false
19455
+ };
19456
+ }).sort((a, b) => b.date.getTime() - a.date.getTime());
19457
+ const result = [];
19458
+ let usedBudget = 0;
19459
+ for (const file of files) {
19460
+ let finalContent = file.content;
19461
+ let isSummarized = false;
19462
+ if (usedBudget + file.size > maxBudget) {
19463
+ finalContent = summarizeContent(file.content);
19464
+ const summarizedSize = Buffer.byteLength(finalContent, "utf-8");
19465
+ if (usedBudget + summarizedSize > maxBudget) {
19466
+ continue;
19467
+ }
19468
+ usedBudget += summarizedSize;
19469
+ isSummarized = true;
19470
+ } else {
19471
+ usedBudget += file.size;
19472
+ }
19473
+ result.push({
19474
+ ...file,
19475
+ content: finalContent,
19476
+ isSummarized
19477
+ });
19478
+ }
19479
+ return result;
19480
+ }
19481
+ function loadContext(agentDir = ".agent") {
19482
+ const systemContent = loadMarkdownDirectory(path7__default.join(agentDir, "system"));
19483
+ const sopContent = loadMarkdownDirectory(path7__default.join(agentDir, "sop"));
19484
+ const systemSize = Buffer.byteLength(systemContent, "utf-8");
19485
+ const sopSize = Buffer.byteLength(sopContent, "utf-8");
19486
+ const taskBudget = Math.max(0, CONTEXT_BUDGET_BYTES - systemSize - sopSize);
19487
+ const tasks = loadTaskFiles(path7__default.join(agentDir, "tasks"), taskBudget);
19488
+ const totalSize = systemSize + sopSize + tasks.reduce((sum, task) => sum + Buffer.byteLength(task.content, "utf-8"), 0);
19489
+ const warnings = [];
19490
+ if (totalSize > CONTEXT_BUDGET_BYTES) {
19491
+ warnings.push(`Context size (${(totalSize / 1024).toFixed(1)}KB) exceeds budget (${CONTEXT_BUDGET_BYTES / 1024}KB)`);
19492
+ }
19493
+ return {
19494
+ system: systemContent,
19495
+ sop: sopContent,
19496
+ tasks,
19497
+ totalSize,
19498
+ warnings
19499
+ };
19500
+ }
19501
+ function formatContextStatus(pack) {
19502
+ const taskCount = pack.tasks.length;
19503
+ const summarizedCount = pack.tasks.filter((t) => t.isSummarized).length;
19504
+ const sizeKB = (pack.totalSize / 1024).toFixed(1);
19505
+ let status = `[x-cli] Context: loaded system docs, sop docs, ${taskCount} task docs (~${sizeKB} KB).`;
19506
+ if (summarizedCount > 0) {
19507
+ status += ` Summarized ${summarizedCount} older tasks for context budget.`;
19508
+ }
19509
+ if (pack.warnings.length > 0) {
19510
+ status += ` Warnings: ${pack.warnings.join("; ")}`;
19511
+ }
19512
+ return status;
19513
+ }
19400
19514
 
19401
19515
  // src/index.ts
19402
19516
  dotenv.config();
@@ -19689,6 +19803,15 @@ program.name("grok").description(
19689
19803
  if (!options.quiet) {
19690
19804
  console.log("\u{1F916} Starting X CLI Conversational Assistant...\n");
19691
19805
  }
19806
+ if (!options.quiet) {
19807
+ try {
19808
+ const contextPack = loadContext();
19809
+ const statusMessage = formatContextStatus(contextPack);
19810
+ console.log(statusMessage);
19811
+ } catch (error) {
19812
+ console.warn("\u26A0\uFE0F Failed to load .agent/ context:", error instanceof Error ? error.message : String(error));
19813
+ }
19814
+ }
19692
19815
  ensureUserSettingsDirectory();
19693
19816
  checkAutoCompact();
19694
19817
  checkStartupUpdates();