@xagent/x-cli 1.1.68 → 1.1.69
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 +12 -2
- package/dist/index.js +131 -8
- package/dist/index.js.map +1 -1
- package/docs/README.md +212 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<!-- Test comment for PR creation -->
|
|
2
2
|
|
|
3
|
-
## 1.1.
|
|
3
|
+
## 1.1.69 – 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
|
|
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,
|
|
7042
|
+
const dfs = (filePath, path31) => {
|
|
7043
7043
|
if (visiting.has(filePath)) {
|
|
7044
|
-
const cycleStart =
|
|
7045
|
-
const cycle =
|
|
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, [...
|
|
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
|
|
9034
|
-
let command = `cat "${
|
|
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' "${
|
|
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.
|
|
14658
|
+
version: "1.1.69",
|
|
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();
|