macha-ai 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,107 @@
1
+ import { execa } from "execa";
2
+ export class MCPClient {
3
+ servers = new Map();
4
+ msgId = 1;
5
+ async connect(server) {
6
+ if (server.transport !== "stdio" || !server.command)
7
+ return;
8
+ const proc = execa(server.command, server.args || [], {
9
+ stdio: ["pipe", "pipe", "pipe"],
10
+ all: false,
11
+ });
12
+ const state = { process: proc, buffer: "", pending: new Map() };
13
+ this.servers.set(server.id, state);
14
+ proc.stdout?.on("data", (chunk) => {
15
+ state.buffer += chunk.toString();
16
+ const lines = state.buffer.split("\n");
17
+ state.buffer = lines.pop() || "";
18
+ for (const line of lines) {
19
+ if (!line.trim())
20
+ continue;
21
+ try {
22
+ const msg = JSON.parse(line);
23
+ if (msg.id !== undefined) {
24
+ const pending = state.pending.get(msg.id);
25
+ if (pending) {
26
+ state.pending.delete(msg.id);
27
+ if (msg.error) {
28
+ pending.reject(new Error(msg.error.message));
29
+ }
30
+ else {
31
+ pending.resolve(msg.result);
32
+ }
33
+ }
34
+ }
35
+ }
36
+ catch {
37
+ }
38
+ }
39
+ });
40
+ await this.send(server.id, "initialize", {
41
+ protocolVersion: "2024-11-05",
42
+ capabilities: { tools: {}, resources: {} },
43
+ clientInfo: { name: "macha", version: "0.1.0" },
44
+ });
45
+ }
46
+ async send(serverId, method, params) {
47
+ const state = this.servers.get(serverId);
48
+ if (!state)
49
+ throw new Error(`MCP server ${serverId} not connected`);
50
+ const id = this.msgId++;
51
+ const msg = { jsonrpc: "2.0", id, method, params };
52
+ return new Promise((resolve, reject) => {
53
+ state.pending.set(id, { resolve, reject });
54
+ state.process.stdin?.write(JSON.stringify(msg) + "\n");
55
+ setTimeout(() => {
56
+ if (state.pending.has(id)) {
57
+ state.pending.delete(id);
58
+ reject(new Error("MCP request timed out"));
59
+ }
60
+ }, 10000);
61
+ });
62
+ }
63
+ async listTools(serverId, serverName) {
64
+ try {
65
+ const result = (await this.send(serverId, "tools/list", {}));
66
+ return (result?.tools || []).map((t) => ({
67
+ ...t,
68
+ serverId,
69
+ serverName,
70
+ inputSchema: t.inputSchema || {},
71
+ }));
72
+ }
73
+ catch {
74
+ return [];
75
+ }
76
+ }
77
+ async callTool(serverId, toolName, args) {
78
+ try {
79
+ const result = (await this.send(serverId, "tools/call", {
80
+ name: toolName,
81
+ arguments: args,
82
+ }));
83
+ return (result?.content || [])
84
+ .filter((c) => c.type === "text")
85
+ .map((c) => c.text)
86
+ .join("\n");
87
+ }
88
+ catch (e) {
89
+ const err = e;
90
+ return `Error: ${err.message || String(e)}`;
91
+ }
92
+ }
93
+ async disconnectAll() {
94
+ for (const [, state] of this.servers) {
95
+ try {
96
+ state.process.kill();
97
+ }
98
+ catch {
99
+ }
100
+ }
101
+ this.servers.clear();
102
+ }
103
+ getConnectedIds() {
104
+ return Array.from(this.servers.keys());
105
+ }
106
+ }
107
+ export const mcpClient = new MCPClient();
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "macha-ai",
3
+ "version": "0.1.0",
4
+ "description": "A beautiful terminal AI coding assistant — like Claude Code and OpenCode. Supports any OpenAI-compatible provider, MCP servers, file tools, and command execution.",
5
+ "type": "module",
6
+ "bin": {
7
+ "macha": "./bin/macha.js"
8
+ },
9
+ "files": [
10
+ "bin/",
11
+ "dist/"
12
+ ],
13
+ "keywords": [
14
+ "ai",
15
+ "cli",
16
+ "terminal",
17
+ "coding-assistant",
18
+ "openai",
19
+ "claude",
20
+ "llm",
21
+ "tui",
22
+ "mcp",
23
+ "agent"
24
+ ],
25
+ "author": "devansh",
26
+ "license": "MIT",
27
+ "repository": {
28
+ "type": "git",
29
+ "url": ""
30
+ },
31
+ "engines": {
32
+ "node": ">=18.0.0"
33
+ },
34
+ "scripts": {
35
+ "dev": "tsx src/index.tsx",
36
+ "build": "tsc -p tsconfig.build.json && node -e \"import('fs').then(fs=>fs.chmodSync('bin/macha.js',0o755))\"",
37
+ "prepublishOnly": "pnpm run build",
38
+ "typecheck": "tsc --noEmit"
39
+ },
40
+ "dependencies": {
41
+ "chalk": "^5.4.1",
42
+ "commander": "^13.1.0",
43
+ "conf": "^13.1.0",
44
+ "execa": "^9.6.0",
45
+ "fast-glob": "^3.3.3",
46
+ "ink": "^5.2.0",
47
+ "ink-select-input": "^6.0.0",
48
+ "ink-spinner": "^5.0.0",
49
+ "ink-text-input": "^6.0.0",
50
+ "openai": "^4.103.0",
51
+ "react": "^18.3.1",
52
+ "strip-ansi": "^7.1.0",
53
+ "wrap-ansi": "^9.0.0"
54
+ },
55
+ "devDependencies": {
56
+ "@types/node": "^22.15.29",
57
+ "@types/react": "^18.3.23",
58
+ "tsx": "^4.21.0",
59
+ "typescript": "~5.9.3"
60
+ }
61
+ }