@codemap-ai/cli 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.
- package/.claude-plugin/plugin.json +12 -0
- package/.codex-plugin/plugin.json +35 -0
- package/.cursor-plugin/plugin.json +16 -0
- package/agent-pack/README.md +44 -0
- package/agent-pack/agents/codemap-explorer.md +12 -0
- package/agent-pack/commands/feature-area.md +8 -0
- package/agent-pack/rules/install.md +35 -0
- package/agent-pack/rules/mcp-first.md +18 -0
- package/agent-pack/rules/task-lifecycle.md +11 -0
- package/agent-pack/rules/workflow-skills.md +97 -0
- package/agent-pack/skills/brainstorming/SKILL.md +41 -0
- package/agent-pack/skills/executing-plans/SKILL.md +26 -0
- package/agent-pack/skills/feature-area-investigation/SKILL.md +15 -0
- package/agent-pack/skills/interpreting-codemap-output/SKILL.md +29 -0
- package/agent-pack/skills/mcp-first-exploration/SKILL.md +10 -0
- package/agent-pack/skills/safe-edit-and-reimport/SKILL.md +18 -0
- package/agent-pack/skills/symbol-level-debugging/SKILL.md +15 -0
- package/agent-pack/skills/test-driven-development/SKILL.md +36 -0
- package/agent-pack/skills/token-efficient-code-review/SKILL.md +15 -0
- package/agent-pack/skills/verification-before-completion/SKILL.md +25 -0
- package/agent-pack/skills/writing-plans/SKILL.md +32 -0
- package/agent-pack/templates/AGENTS.md +21 -0
- package/agent-pack/templates/CLAUDE.md +19 -0
- package/agent-pack/templates/COPILOT.md +75 -0
- package/agent-pack/templates/GEMINI.md +77 -0
- package/agent-pack/templates/design-spec.md +34 -0
- package/agent-pack/templates/implementation-plan.md +26 -0
- package/agent-pack/templates/opencode-AGENTS.md +76 -0
- package/agent-pack/templates/opencode-INSTALL.md +5 -0
- package/agent-pack/templates/verification-report.md +18 -0
- package/dist/chat-terminal-DFFYQ6AF.js +1743 -0
- package/dist/chunk-A2QHID6K.js +34 -0
- package/dist/chunk-AXGGL47C.js +457 -0
- package/dist/chunk-FFFJKKKM.js +218262 -0
- package/dist/chunk-KWYP3ADN.js +1742 -0
- package/dist/chunk-WNJNT3FC.js +216 -0
- package/dist/chunk-YRXVMFXS.js +99 -0
- package/dist/index.js +9225 -0
- package/dist/login-screen-2DJBDM47.js +143 -0
- package/dist/pi-tui-app-GVZ3AN42.js +2073 -0
- package/package.json +59 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import{createRequire as __cmr}from"node:module";import{fileURLToPath as __f2p}from"node:url";import{dirname as __dn}from"node:path";var require=__cmr(import.meta.url);var __filename=__f2p(import.meta.url);var __dirname=__dn(__filename);
|
|
2
|
+
import {
|
|
3
|
+
readMcpServerConfigs,
|
|
4
|
+
readPriorityResources
|
|
5
|
+
} from "./chunk-FFFJKKKM.js";
|
|
6
|
+
|
|
7
|
+
// src/cli-agent/chat/mcp-tools/mcp-tool-client.ts
|
|
8
|
+
import { existsSync } from "fs";
|
|
9
|
+
import { createRequire } from "module";
|
|
10
|
+
import path from "path";
|
|
11
|
+
import { fileURLToPath } from "url";
|
|
12
|
+
import { MCPClient } from "@mastra/mcp";
|
|
13
|
+
var require2 = createRequire(import.meta.url);
|
|
14
|
+
var DEFAULT_PRIORITY_RESOURCES = [
|
|
15
|
+
"codemap://project/context",
|
|
16
|
+
"codemap://rules/agent-workflow"
|
|
17
|
+
];
|
|
18
|
+
var CodeMapMcpToolClient = class {
|
|
19
|
+
_mcpClient;
|
|
20
|
+
_extraConfigs = /* @__PURE__ */ new Map();
|
|
21
|
+
_serverConfig;
|
|
22
|
+
_cachedToolCount = 0;
|
|
23
|
+
constructor() {
|
|
24
|
+
const runtime = resolvePackageRuntime();
|
|
25
|
+
const codemapServer = resolveServerCommand(runtime);
|
|
26
|
+
this._serverConfig = {
|
|
27
|
+
command: codemapServer.command,
|
|
28
|
+
args: codemapServer.args,
|
|
29
|
+
env: { CODEMAP_TOOL_MODE: "full" }
|
|
30
|
+
};
|
|
31
|
+
this._mcpClient = new MCPClient({
|
|
32
|
+
id: "codemap-chat-client",
|
|
33
|
+
servers: {
|
|
34
|
+
codemap: {
|
|
35
|
+
command: codemapServer.command,
|
|
36
|
+
args: codemapServer.args,
|
|
37
|
+
env: { ...process.env, CODEMAP_TOOL_MODE: "full" },
|
|
38
|
+
stderr: "pipe"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
getServerConfig() {
|
|
44
|
+
return this._serverConfig;
|
|
45
|
+
}
|
|
46
|
+
getExtraServerConfigs() {
|
|
47
|
+
return Object.fromEntries(this._extraConfigs);
|
|
48
|
+
}
|
|
49
|
+
async connectExtras() {
|
|
50
|
+
const configs = await readMcpServerConfigs();
|
|
51
|
+
for (const [name, config] of configs) {
|
|
52
|
+
this._extraConfigs.set(name, config);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
addExtraServer(name, config) {
|
|
56
|
+
this._extraConfigs.set(name, config);
|
|
57
|
+
}
|
|
58
|
+
removeExtraServer(name) {
|
|
59
|
+
return this._extraConfigs.delete(name);
|
|
60
|
+
}
|
|
61
|
+
getServerStatuses() {
|
|
62
|
+
const statuses = [
|
|
63
|
+
{ name: "codemap", connected: this._cachedToolCount > 0, tools: this._cachedToolCount }
|
|
64
|
+
];
|
|
65
|
+
for (const [name] of this._extraConfigs) {
|
|
66
|
+
statuses.push({ name, connected: true, tools: 0 });
|
|
67
|
+
}
|
|
68
|
+
return statuses;
|
|
69
|
+
}
|
|
70
|
+
async listAllowedTools() {
|
|
71
|
+
const toolsets = await this._mcpClient.listToolsets();
|
|
72
|
+
const tools = toolsets["codemap"] ?? {};
|
|
73
|
+
return Object.entries(tools).map(([name, tool]) => ({
|
|
74
|
+
name,
|
|
75
|
+
description: tool.description ?? "",
|
|
76
|
+
inputSchema: tool.inputSchema ?? {}
|
|
77
|
+
}));
|
|
78
|
+
}
|
|
79
|
+
async listChatTools() {
|
|
80
|
+
const toolsets = await this._mcpClient.listToolsets();
|
|
81
|
+
const tools = toolsets["codemap"] ?? {};
|
|
82
|
+
return Object.entries(tools).map(([name, tool]) => ({
|
|
83
|
+
type: "function",
|
|
84
|
+
function: {
|
|
85
|
+
name,
|
|
86
|
+
description: tool.description ?? "",
|
|
87
|
+
parameters: tool.inputSchema ?? {}
|
|
88
|
+
}
|
|
89
|
+
}));
|
|
90
|
+
}
|
|
91
|
+
/** Returns Mastra tool definitions for sharing with the harness (avoids a second child process).
|
|
92
|
+
* Keys are prefixed with the server name (e.g. "codemap_explore_task") so that
|
|
93
|
+
* formatToolDisplayName can strip the prefix and show "codemap · explore_task" in the UI.
|
|
94
|
+
*/
|
|
95
|
+
async getMastraTools() {
|
|
96
|
+
const toolsets = await this._mcpClient.listToolsets();
|
|
97
|
+
const prefixed = {};
|
|
98
|
+
for (const [serverName, serverTools] of Object.entries(toolsets)) {
|
|
99
|
+
for (const [toolName, tool] of Object.entries(serverTools)) {
|
|
100
|
+
prefixed[`${serverName}_${toolName}`] = tool;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
this._cachedToolCount = Object.keys(toolsets["codemap"] ?? {}).length;
|
|
104
|
+
return prefixed;
|
|
105
|
+
}
|
|
106
|
+
async callTool(name, args) {
|
|
107
|
+
const toolsets = await this._mcpClient.listToolsets();
|
|
108
|
+
const tool = (toolsets["codemap"] ?? {})[name];
|
|
109
|
+
if (!tool?.execute) {
|
|
110
|
+
throw new Error(`MCP tool not found: ${name}`);
|
|
111
|
+
}
|
|
112
|
+
const raw = await tool.execute(args, void 0);
|
|
113
|
+
return formatToolResult(raw);
|
|
114
|
+
}
|
|
115
|
+
async listResources() {
|
|
116
|
+
const allResources = await this._mcpClient.resources.list();
|
|
117
|
+
return (allResources["codemap"] ?? []).map((r) => ({
|
|
118
|
+
uri: r.uri,
|
|
119
|
+
name: r.name ?? r.uri
|
|
120
|
+
}));
|
|
121
|
+
}
|
|
122
|
+
async readResource(uri) {
|
|
123
|
+
const result = await this._mcpClient.resources.read("codemap", uri);
|
|
124
|
+
return result.contents.filter((c) => "text" in c).map((c) => c.text).join("\n");
|
|
125
|
+
}
|
|
126
|
+
async close() {
|
|
127
|
+
await this._mcpClient.disconnect();
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
async function fetchResourceContext(toolClient) {
|
|
131
|
+
const configured = await readPriorityResources();
|
|
132
|
+
const priorityUris = configured.length > 0 ? configured : DEFAULT_PRIORITY_RESOURCES;
|
|
133
|
+
const resources = await toolClient.listResources();
|
|
134
|
+
const toFetch = priorityUris.filter(
|
|
135
|
+
(uri) => resources.some((r) => r.uri === uri)
|
|
136
|
+
);
|
|
137
|
+
if (toFetch.length === 0) return null;
|
|
138
|
+
const parts = [];
|
|
139
|
+
for (const uri of toFetch) {
|
|
140
|
+
try {
|
|
141
|
+
const text = await toolClient.readResource(uri);
|
|
142
|
+
if (text) parts.push(text);
|
|
143
|
+
} catch {
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return parts.length > 0 ? parts.join("\n\n---\n\n") : null;
|
|
147
|
+
}
|
|
148
|
+
function formatToolResult(raw) {
|
|
149
|
+
if (raw === null || raw === void 0) return { content: "" };
|
|
150
|
+
if (typeof raw === "object" && raw !== null && "content" in raw) {
|
|
151
|
+
const result = raw;
|
|
152
|
+
if (Array.isArray(result.content)) {
|
|
153
|
+
const text = result.content.filter((c) => c.type === "text").map((c) => c.text ?? "").join("\n");
|
|
154
|
+
return {
|
|
155
|
+
content: text,
|
|
156
|
+
structuredContent: result.structuredContent,
|
|
157
|
+
isError: result.isError
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (typeof raw === "object" && raw !== null && "summary" in raw) {
|
|
162
|
+
const structured = raw;
|
|
163
|
+
const summary = String(structured.summary ?? "");
|
|
164
|
+
return { content: summary, structuredContent: structured };
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
content: typeof raw === "string" ? raw : JSON.stringify(raw, null, 2),
|
|
168
|
+
structuredContent: raw
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
function findPackageRoot(startDir) {
|
|
172
|
+
let dir = startDir;
|
|
173
|
+
while (true) {
|
|
174
|
+
if (existsSync(path.join(dir, "package.json"))) return dir;
|
|
175
|
+
const parent = path.dirname(dir);
|
|
176
|
+
if (parent === dir) break;
|
|
177
|
+
dir = parent;
|
|
178
|
+
}
|
|
179
|
+
return startDir;
|
|
180
|
+
}
|
|
181
|
+
function resolvePackageRuntime() {
|
|
182
|
+
const currentFile = fileURLToPath(import.meta.url);
|
|
183
|
+
const packageRoot = findPackageRoot(path.dirname(currentFile));
|
|
184
|
+
return {
|
|
185
|
+
packageRoot,
|
|
186
|
+
isSourceRuntime: currentFile.includes(`${path.sep}src${path.sep}`)
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
function resolveServerCommand(runtime) {
|
|
190
|
+
const { packageRoot, isSourceRuntime } = runtime;
|
|
191
|
+
if (isSourceRuntime) {
|
|
192
|
+
return {
|
|
193
|
+
command: process.execPath,
|
|
194
|
+
args: [
|
|
195
|
+
require2.resolve("tsx/cli"),
|
|
196
|
+
path.join(packageRoot, "src", "index.ts")
|
|
197
|
+
]
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
const distEntry = path.join(packageRoot, "dist", "index.js");
|
|
201
|
+
if (existsSync(distEntry)) {
|
|
202
|
+
return { command: process.execPath, args: [distEntry] };
|
|
203
|
+
}
|
|
204
|
+
return {
|
|
205
|
+
command: process.execPath,
|
|
206
|
+
args: [
|
|
207
|
+
require2.resolve("tsx/cli"),
|
|
208
|
+
path.join(packageRoot, "src", "index.ts")
|
|
209
|
+
]
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export {
|
|
214
|
+
CodeMapMcpToolClient,
|
|
215
|
+
fetchResourceContext
|
|
216
|
+
};
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import{createRequire as __cmr}from"node:module";import{fileURLToPath as __f2p}from"node:url";import{dirname as __dn}from"node:path";var require=__cmr(import.meta.url);var __filename=__f2p(import.meta.url);var __dirname=__dn(__filename);
|
|
2
|
+
|
|
3
|
+
// src/cli-agent/chat/ui/ink-utils.ts
|
|
4
|
+
var RESET = "\x1B[0m";
|
|
5
|
+
var BOLD = "\x1B[1m";
|
|
6
|
+
var DIM = "\x1B[2m";
|
|
7
|
+
function fg(r, g, b) {
|
|
8
|
+
return `\x1B[38;2;${r};${g};${b}m`;
|
|
9
|
+
}
|
|
10
|
+
function gradientStr(text, from, to, bold = true) {
|
|
11
|
+
const chars = [...text];
|
|
12
|
+
return chars.map((ch, i) => {
|
|
13
|
+
const t = chars.length <= 1 ? 0 : i / (chars.length - 1);
|
|
14
|
+
const r = Math.round(from.r + (to.r - from.r) * t);
|
|
15
|
+
const g = Math.round(from.g + (to.g - from.g) * t);
|
|
16
|
+
const b = Math.round(from.b + (to.b - from.b) * t);
|
|
17
|
+
return `${bold ? BOLD : ""}${fg(r, g, b)}${ch}${RESET}`;
|
|
18
|
+
}).join("");
|
|
19
|
+
}
|
|
20
|
+
function truncate(text, max) {
|
|
21
|
+
if (text.length <= max) return text;
|
|
22
|
+
return text.slice(0, max - 1) + "\u2026";
|
|
23
|
+
}
|
|
24
|
+
function formatElapsed(ms) {
|
|
25
|
+
const s = Math.floor(ms / 1e3);
|
|
26
|
+
if (s < 60) return `${s}s`;
|
|
27
|
+
return `${Math.floor(s / 60)}m ${s % 60}s`;
|
|
28
|
+
}
|
|
29
|
+
function formatTokenCount(n) {
|
|
30
|
+
if (n < 1e3) return String(n);
|
|
31
|
+
return `${(n / 1e3).toFixed(1)}k`;
|
|
32
|
+
}
|
|
33
|
+
function formatTime(ts) {
|
|
34
|
+
const d = new Date(ts ?? Date.now());
|
|
35
|
+
return [d.getHours(), d.getMinutes(), d.getSeconds()].map((n) => String(n).padStart(2, "0")).join(":");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// src/cli-agent/chat/ui/pi-tui/theme.ts
|
|
39
|
+
function bg(r, g, b) {
|
|
40
|
+
return `\x1B[48;2;${r};${g};${b}m`;
|
|
41
|
+
}
|
|
42
|
+
var C_CYAN = `${BOLD}${fg(88, 213, 247)}`;
|
|
43
|
+
var C_BLUE = fg(122, 184, 255);
|
|
44
|
+
var C_PINK = fg(244, 114, 182);
|
|
45
|
+
var C_GRAY = fg(156, 163, 175);
|
|
46
|
+
var C_MUTED = fg(107, 114, 128);
|
|
47
|
+
var C_WHITE = fg(229, 231, 235);
|
|
48
|
+
var C_GREEN = fg(16, 185, 129);
|
|
49
|
+
var C_YELLOW = fg(245, 158, 11);
|
|
50
|
+
var C_RED = fg(239, 68, 68);
|
|
51
|
+
var C_PURPLE = fg(155, 140, 255);
|
|
52
|
+
var C_ACTION = C_CYAN;
|
|
53
|
+
var C_AI = `${BOLD}${C_PURPLE}`;
|
|
54
|
+
var C_ARCH = C_PINK;
|
|
55
|
+
var C_INFO = fg(34, 211, 238);
|
|
56
|
+
var C_SUCCESS = C_GREEN;
|
|
57
|
+
var C_WARNING = C_YELLOW;
|
|
58
|
+
var C_ERROR = C_RED;
|
|
59
|
+
var BG_SURFACE = bg(17, 24, 39);
|
|
60
|
+
var BG_SURFACE_SOFT = bg(22, 27, 46);
|
|
61
|
+
var BG_USER = bg(55, 65, 81);
|
|
62
|
+
var SPINNER = [
|
|
63
|
+
"\u280B",
|
|
64
|
+
"\u2819",
|
|
65
|
+
"\u2839",
|
|
66
|
+
"\u2838",
|
|
67
|
+
"\u283C",
|
|
68
|
+
"\u2834",
|
|
69
|
+
"\u2826",
|
|
70
|
+
"\u2827",
|
|
71
|
+
"\u2807",
|
|
72
|
+
"\u280F"
|
|
73
|
+
];
|
|
74
|
+
|
|
75
|
+
export {
|
|
76
|
+
RESET,
|
|
77
|
+
BOLD,
|
|
78
|
+
DIM,
|
|
79
|
+
gradientStr,
|
|
80
|
+
truncate,
|
|
81
|
+
formatElapsed,
|
|
82
|
+
formatTokenCount,
|
|
83
|
+
formatTime,
|
|
84
|
+
C_CYAN,
|
|
85
|
+
C_GRAY,
|
|
86
|
+
C_MUTED,
|
|
87
|
+
C_WHITE,
|
|
88
|
+
C_GREEN,
|
|
89
|
+
C_RED,
|
|
90
|
+
C_PURPLE,
|
|
91
|
+
C_ACTION,
|
|
92
|
+
C_AI,
|
|
93
|
+
C_ARCH,
|
|
94
|
+
C_SUCCESS,
|
|
95
|
+
C_WARNING,
|
|
96
|
+
C_ERROR,
|
|
97
|
+
BG_USER,
|
|
98
|
+
SPINNER
|
|
99
|
+
};
|