@ulpi/codemap 0.3.7 → 0.3.9
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 +40 -0
- package/dist/index.js +257 -14
- package/package.json +4 -2
- package/scripts/postinstall.js +36 -0
package/README.md
CHANGED
|
@@ -363,6 +363,46 @@ Add to `~/.config/zed/settings.json`:
|
|
|
363
363
|
}
|
|
364
364
|
```
|
|
365
365
|
|
|
366
|
+
### Multi-Project Setup
|
|
367
|
+
|
|
368
|
+
You can register multiple CodeMap MCP servers — one per codebase — so your AI agent can search across your frontend, backend, shared libraries, or any other project simultaneously. Each server indexes and serves its own project independently.
|
|
369
|
+
|
|
370
|
+
First, index each project:
|
|
371
|
+
|
|
372
|
+
```bash
|
|
373
|
+
codemap init && codemap index # current project
|
|
374
|
+
cd /path/to/frontend && codemap init && codemap index # another project
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
Then register them as MCP servers. The current project uses `codemap serve` with no extra arguments. Other projects use `--cwd` to point to their location:
|
|
378
|
+
|
|
379
|
+
#### Claude Code
|
|
380
|
+
|
|
381
|
+
Add to `.mcp.json` in your project root:
|
|
382
|
+
|
|
383
|
+
```json
|
|
384
|
+
{
|
|
385
|
+
"mcpServers": {
|
|
386
|
+
"codemap": {
|
|
387
|
+
"command": "codemap",
|
|
388
|
+
"args": ["serve"]
|
|
389
|
+
},
|
|
390
|
+
"codemap-frontend": {
|
|
391
|
+
"command": "codemap",
|
|
392
|
+
"args": ["serve", "--cwd", "/path/to/frontend"]
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
`"codemap"` serves the current project automatically. `"codemap-frontend"` serves a different codebase via `--cwd`. Add as many as you need — each gets its own set of 12 tools (`search_code`, `get_dependencies`, etc.) scoped to that project.
|
|
399
|
+
|
|
400
|
+
#### Other Editors
|
|
401
|
+
|
|
402
|
+
The same pattern works in any editor — add one entry with no `--cwd` for the local project, and additional entries with `--cwd` for other codebases. Use unique names (e.g. `codemap-api`, `codemap-shared`) so your AI agent can tell them apart.
|
|
403
|
+
|
|
404
|
+
Your AI agent will then have access to tools like `search_code`, `get_dependencies`, and `search_symbols` across all registered projects, making it easy to trace connections across your stack.
|
|
405
|
+
|
|
366
406
|
## MCP Tools Reference
|
|
367
407
|
|
|
368
408
|
| Tool | Description |
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import "./chunk-WR342MP3.js";
|
|
|
5
5
|
import "./chunk-2OBAJYRP.js";
|
|
6
6
|
|
|
7
7
|
// src/index.ts
|
|
8
|
-
import
|
|
8
|
+
import path14 from "path";
|
|
9
9
|
import { fileURLToPath } from "url";
|
|
10
10
|
|
|
11
11
|
// ../../packages/intelligence/codemap-engine/dist/index.js
|
|
@@ -4250,6 +4250,19 @@ function releaseCodemapLock(projectDir, branch) {
|
|
|
4250
4250
|
} catch {
|
|
4251
4251
|
}
|
|
4252
4252
|
}
|
|
4253
|
+
function isCodemapLocked(projectDir, branch) {
|
|
4254
|
+
const file = lockPath(projectDir, branch);
|
|
4255
|
+
const info = readLock(file);
|
|
4256
|
+
if (!info) return false;
|
|
4257
|
+
if (isStale(info)) {
|
|
4258
|
+
try {
|
|
4259
|
+
fs6.unlinkSync(file);
|
|
4260
|
+
} catch {
|
|
4261
|
+
}
|
|
4262
|
+
return false;
|
|
4263
|
+
}
|
|
4264
|
+
return true;
|
|
4265
|
+
}
|
|
4253
4266
|
function saveManifest(branchDir, manifest) {
|
|
4254
4267
|
fs7.mkdirSync(branchDir, { recursive: true });
|
|
4255
4268
|
const file = path7.join(branchDir, "manifest.json");
|
|
@@ -6164,13 +6177,14 @@ function registerStatus(program2) {
|
|
|
6164
6177
|
const projectDir = program2.opts().cwd || process.cwd();
|
|
6165
6178
|
const branch = getCurrentBranch(projectDir);
|
|
6166
6179
|
const statsFile = codemapStatsFile(projectDir, branch, getDataDir2());
|
|
6180
|
+
const indexing = isCodemapLocked(projectDir, branch);
|
|
6167
6181
|
let stats = null;
|
|
6168
6182
|
try {
|
|
6169
6183
|
stats = JSON.parse(fs14.readFileSync(statsFile, "utf-8"));
|
|
6170
6184
|
} catch {
|
|
6171
6185
|
}
|
|
6172
6186
|
if (opts.json) {
|
|
6173
|
-
console.log(JSON.stringify({ projectDir, branch, stats }, null, 2));
|
|
6187
|
+
console.log(JSON.stringify({ projectDir, branch, stats, indexing }, null, 2));
|
|
6174
6188
|
return;
|
|
6175
6189
|
}
|
|
6176
6190
|
console.log(chalk6.bold("Codemap Status"));
|
|
@@ -6179,6 +6193,10 @@ function registerStatus(program2) {
|
|
|
6179
6193
|
console.log(`Branch: ${branch}`);
|
|
6180
6194
|
console.log(`Data dir: ${getDataDir2()}`);
|
|
6181
6195
|
console.log();
|
|
6196
|
+
if (indexing) {
|
|
6197
|
+
console.log(chalk6.yellow("Indexing in progress..."));
|
|
6198
|
+
console.log();
|
|
6199
|
+
}
|
|
6182
6200
|
if (!stats) {
|
|
6183
6201
|
console.log(chalk6.yellow("No index found. Run `codemap index` first."));
|
|
6184
6202
|
return;
|
|
@@ -6869,13 +6887,10 @@ function registerCoupling(program2) {
|
|
|
6869
6887
|
const projectDir = program2.opts().cwd || process.cwd();
|
|
6870
6888
|
const branch = getCurrentBranch(projectDir);
|
|
6871
6889
|
const graphFile = depgraphGraphFile(projectDir, branch, getDataDir2());
|
|
6872
|
-
|
|
6873
|
-
|
|
6874
|
-
graph = loadGraph(graphFile);
|
|
6875
|
-
} catch {
|
|
6890
|
+
const graph = loadGraph(graphFile);
|
|
6891
|
+
if (!graph) {
|
|
6876
6892
|
console.error(chalk14.red("Dependency graph not available. Run `codemap index` first."));
|
|
6877
6893
|
process.exit(1);
|
|
6878
|
-
return;
|
|
6879
6894
|
}
|
|
6880
6895
|
let coupling = computeCoupling(graph);
|
|
6881
6896
|
if (opts.module) {
|
|
@@ -6914,13 +6929,10 @@ function registerGraphStats(program2) {
|
|
|
6914
6929
|
program2.command("graph-stats").description("Show aggregate dependency graph statistics").option("--json", "Output as JSON").action(async (opts) => {
|
|
6915
6930
|
const projectDir = program2.opts().cwd || process.cwd();
|
|
6916
6931
|
const branch = getCurrentBranch(projectDir);
|
|
6917
|
-
|
|
6918
|
-
|
|
6919
|
-
metrics = loadMetrics(depgraphMetricsFile(projectDir, branch, getDataDir2()));
|
|
6920
|
-
} catch {
|
|
6932
|
+
const metrics = loadMetrics(depgraphMetricsFile(projectDir, branch, getDataDir2()));
|
|
6933
|
+
if (!metrics) {
|
|
6921
6934
|
console.error(chalk15.red("Dependency metrics not available. Run `codemap index` first."));
|
|
6922
6935
|
process.exit(1);
|
|
6923
|
-
return;
|
|
6924
6936
|
}
|
|
6925
6937
|
const result = {
|
|
6926
6938
|
totalFiles: metrics.totalFiles,
|
|
@@ -7010,9 +7022,239 @@ function registerRebuild(program2) {
|
|
|
7010
7022
|
});
|
|
7011
7023
|
}
|
|
7012
7024
|
|
|
7025
|
+
// src/commands/statusline.ts
|
|
7026
|
+
import chalk17 from "chalk";
|
|
7027
|
+
import fs18 from "fs";
|
|
7028
|
+
import path13 from "path";
|
|
7029
|
+
import { homedir as homedir3 } from "os";
|
|
7030
|
+
|
|
7031
|
+
// src/commands/statusline-script.ts
|
|
7032
|
+
function buildStatuslineScript(originalCommand) {
|
|
7033
|
+
const escapedCmd = originalCommand.replace(/'/g, "'\\''");
|
|
7034
|
+
const originalSection = originalCommand ? `ORIGINAL_CMD='${escapedCmd}'
|
|
7035
|
+
echo "$SESSION_JSON" | eval "$ORIGINAL_CMD" 2>/dev/null || true` : "# (none)";
|
|
7036
|
+
return `#!/bin/bash
|
|
7037
|
+
# CodeMap statusline for Claude Code
|
|
7038
|
+
# Generated by: codemap statusline
|
|
7039
|
+
# Do not edit \u2014 re-run \`codemap statusline\` to regenerate.
|
|
7040
|
+
|
|
7041
|
+
set -euo pipefail
|
|
7042
|
+
|
|
7043
|
+
# Read session JSON from stdin (Claude Code pipes it)
|
|
7044
|
+
SESSION_JSON=$(cat)
|
|
7045
|
+
|
|
7046
|
+
# --- Original statusline ---
|
|
7047
|
+
${originalSection}
|
|
7048
|
+
|
|
7049
|
+
# --- CodeMap status ---
|
|
7050
|
+
# Resolve the working directory from session JSON
|
|
7051
|
+
current_dir=$(echo "$SESSION_JSON" | ${jsonExtract("cwd")} 2>/dev/null || pwd)
|
|
7052
|
+
|
|
7053
|
+
# Run codemap status --json for the project directory
|
|
7054
|
+
cm_json=$(codemap status --json --cwd "$current_dir" 2>/dev/null || true)
|
|
7055
|
+
|
|
7056
|
+
if [ -z "$cm_json" ]; then
|
|
7057
|
+
exit 0
|
|
7058
|
+
fi
|
|
7059
|
+
|
|
7060
|
+
# Parse fields
|
|
7061
|
+
stats_null=$(echo "$cm_json" | ${jsonExtract("stats")} 2>/dev/null || echo "null")
|
|
7062
|
+
if [ "$stats_null" = "null" ] || [ -z "$stats_null" ]; then
|
|
7063
|
+
echo "CM: \u2014 no index (run: codemap index)"
|
|
7064
|
+
exit 0
|
|
7065
|
+
fi
|
|
7066
|
+
|
|
7067
|
+
total_files=$(echo "$cm_json" | ${jsonPath("stats", "totalFiles")} 2>/dev/null || echo "0")
|
|
7068
|
+
total_chunks=$(echo "$cm_json" | ${jsonPath("stats", "totalChunks")} 2>/dev/null || echo "0")
|
|
7069
|
+
stale_files=$(echo "$cm_json" | ${jsonPath("stats", "staleFiles")} 2>/dev/null || echo "0")
|
|
7070
|
+
last_updated=$(echo "$cm_json" | ${jsonPath("stats", "lastUpdated")} 2>/dev/null || echo "")
|
|
7071
|
+
indexing=$(echo "$cm_json" | ${jsonExtract("indexing")} 2>/dev/null || echo "false")
|
|
7072
|
+
|
|
7073
|
+
# Format chunks (e.g. 12400 \u2192 12.4k)
|
|
7074
|
+
format_chunks() {
|
|
7075
|
+
local n=$1
|
|
7076
|
+
if [ "$n" -ge 1000 ]; then
|
|
7077
|
+
local k=$((n / 100))
|
|
7078
|
+
local whole=$((k / 10))
|
|
7079
|
+
local frac=$((k % 10))
|
|
7080
|
+
echo "\${whole}.\${frac}k"
|
|
7081
|
+
else
|
|
7082
|
+
echo "$n"
|
|
7083
|
+
fi
|
|
7084
|
+
}
|
|
7085
|
+
|
|
7086
|
+
# Calculate time ago
|
|
7087
|
+
time_ago() {
|
|
7088
|
+
local updated="$1"
|
|
7089
|
+
if [ -z "$updated" ]; then
|
|
7090
|
+
echo "unknown"
|
|
7091
|
+
return
|
|
7092
|
+
fi
|
|
7093
|
+
local now
|
|
7094
|
+
now=$(date +%s)
|
|
7095
|
+
local then_ts
|
|
7096
|
+
# macOS date -j vs GNU date
|
|
7097
|
+
if date -j -f "%Y-%m-%dT%H:%M:%S" "$(echo "$updated" | cut -c1-19)" +%s >/dev/null 2>&1; then
|
|
7098
|
+
then_ts=$(date -j -f "%Y-%m-%dT%H:%M:%S" "$(echo "$updated" | cut -c1-19)" +%s 2>/dev/null || echo "$now")
|
|
7099
|
+
else
|
|
7100
|
+
then_ts=$(date -d "$updated" +%s 2>/dev/null || echo "$now")
|
|
7101
|
+
fi
|
|
7102
|
+
local diff=$(( now - then_ts ))
|
|
7103
|
+
if [ "$diff" -lt 60 ]; then
|
|
7104
|
+
echo "\${diff}s ago"
|
|
7105
|
+
elif [ "$diff" -lt 3600 ]; then
|
|
7106
|
+
echo "$(( diff / 60 ))m ago"
|
|
7107
|
+
elif [ "$diff" -lt 86400 ]; then
|
|
7108
|
+
echo "$(( diff / 3600 ))h ago"
|
|
7109
|
+
else
|
|
7110
|
+
echo "$(( diff / 86400 ))d ago"
|
|
7111
|
+
fi
|
|
7112
|
+
}
|
|
7113
|
+
|
|
7114
|
+
# Watcher detection
|
|
7115
|
+
watcher_icon="\u25CB"
|
|
7116
|
+
if pgrep -f "codemap watch" >/dev/null 2>&1; then
|
|
7117
|
+
watcher_icon="\u25CF"
|
|
7118
|
+
fi
|
|
7119
|
+
|
|
7120
|
+
# Indexing indicator
|
|
7121
|
+
idx_icon=""
|
|
7122
|
+
if [ "$indexing" = "true" ]; then
|
|
7123
|
+
idx_icon=" IDX"
|
|
7124
|
+
fi
|
|
7125
|
+
|
|
7126
|
+
chunks_fmt=$(format_chunks "$total_chunks")
|
|
7127
|
+
|
|
7128
|
+
# Build status line
|
|
7129
|
+
line="CM: \${watcher_icon} \${total_files}f \${chunks_fmt}\u25C6"
|
|
7130
|
+
|
|
7131
|
+
if [ "$stale_files" -gt 0 ] 2>/dev/null; then
|
|
7132
|
+
line="\${line} \u26A0\${stale_files}"
|
|
7133
|
+
fi
|
|
7134
|
+
|
|
7135
|
+
line="\${line}\${idx_icon} | $(time_ago "$last_updated")"
|
|
7136
|
+
|
|
7137
|
+
echo "$line"
|
|
7138
|
+
`;
|
|
7139
|
+
}
|
|
7140
|
+
function jsonExtract(field) {
|
|
7141
|
+
return `grep -o '"${field}"[[:space:]]*:[[:space:]]*[^,}]*' | sed 's/.*:[[:space:]]*//' | sed 's/"//g' | head -1`;
|
|
7142
|
+
}
|
|
7143
|
+
function jsonPath(parent, child) {
|
|
7144
|
+
return `grep -o '"${child}"[[:space:]]*:[[:space:]]*[^,}]*' | sed 's/.*:[[:space:]]*//' | sed 's/"//g' | head -1`;
|
|
7145
|
+
}
|
|
7146
|
+
|
|
7147
|
+
// src/commands/statusline.ts
|
|
7148
|
+
var CLAUDE_DIR = path13.join(homedir3(), ".claude");
|
|
7149
|
+
var SETTINGS_FILE2 = path13.join(CLAUDE_DIR, "settings.json");
|
|
7150
|
+
var SCRIPT_FILE = path13.join(CLAUDE_DIR, "statusline-command.sh");
|
|
7151
|
+
var BACKUP_FILE = path13.join(CLAUDE_DIR, "statusline-command.sh.bak");
|
|
7152
|
+
function readSettings() {
|
|
7153
|
+
try {
|
|
7154
|
+
return JSON.parse(fs18.readFileSync(SETTINGS_FILE2, "utf-8"));
|
|
7155
|
+
} catch {
|
|
7156
|
+
return {};
|
|
7157
|
+
}
|
|
7158
|
+
}
|
|
7159
|
+
function writeSettings(settings) {
|
|
7160
|
+
fs18.mkdirSync(CLAUDE_DIR, { recursive: true });
|
|
7161
|
+
fs18.writeFileSync(SETTINGS_FILE2, JSON.stringify(settings, null, 2) + "\n");
|
|
7162
|
+
}
|
|
7163
|
+
function registerStatusline(program2) {
|
|
7164
|
+
program2.command("statusline").description("Install CodeMap status into Claude Code statusline").option("--uninstall", "Remove CodeMap from statusline and restore backup").action(async (opts) => {
|
|
7165
|
+
if (opts.uninstall) {
|
|
7166
|
+
uninstall();
|
|
7167
|
+
return;
|
|
7168
|
+
}
|
|
7169
|
+
install();
|
|
7170
|
+
});
|
|
7171
|
+
}
|
|
7172
|
+
function install() {
|
|
7173
|
+
const settings = readSettings();
|
|
7174
|
+
if (fs18.existsSync(SCRIPT_FILE)) {
|
|
7175
|
+
try {
|
|
7176
|
+
const existing = fs18.readFileSync(SCRIPT_FILE, "utf-8");
|
|
7177
|
+
if (existing.includes("Generated by: codemap statusline")) {
|
|
7178
|
+
console.log(chalk17.yellow("CodeMap statusline is already installed."));
|
|
7179
|
+
console.log(chalk17.dim("Run `codemap statusline --uninstall` to remove, then reinstall."));
|
|
7180
|
+
return;
|
|
7181
|
+
}
|
|
7182
|
+
} catch {
|
|
7183
|
+
}
|
|
7184
|
+
}
|
|
7185
|
+
const originalCommand = settings.statusline_command || "";
|
|
7186
|
+
if (originalCommand && originalCommand !== SCRIPT_FILE) {
|
|
7187
|
+
fs18.mkdirSync(CLAUDE_DIR, { recursive: true });
|
|
7188
|
+
fs18.writeFileSync(BACKUP_FILE, originalCommand);
|
|
7189
|
+
console.log(chalk17.dim(`Saved original statusline command to ${BACKUP_FILE}`));
|
|
7190
|
+
}
|
|
7191
|
+
const script = buildStatuslineScript(originalCommand !== SCRIPT_FILE ? originalCommand : "");
|
|
7192
|
+
fs18.mkdirSync(CLAUDE_DIR, { recursive: true });
|
|
7193
|
+
fs18.writeFileSync(SCRIPT_FILE, script, { mode: 493 });
|
|
7194
|
+
if (settings.statusline_command !== SCRIPT_FILE) {
|
|
7195
|
+
settings.statusline_command = SCRIPT_FILE;
|
|
7196
|
+
writeSettings(settings);
|
|
7197
|
+
console.log(chalk17.dim(`Updated ${SETTINGS_FILE2}`));
|
|
7198
|
+
}
|
|
7199
|
+
console.log();
|
|
7200
|
+
console.log(chalk17.green("CodeMap statusline installed."));
|
|
7201
|
+
if (originalCommand && originalCommand !== SCRIPT_FILE) {
|
|
7202
|
+
console.log(chalk17.dim("Your existing statusline is preserved \u2014 CodeMap appends to it."));
|
|
7203
|
+
}
|
|
7204
|
+
console.log();
|
|
7205
|
+
console.log("CodeMap will append to the statusline:");
|
|
7206
|
+
console.log(chalk17.cyan(" CM: \u25CF 842f 12.4k\u25C6 | 23m ago") + chalk17.dim(" \u2014 watcher running, index fresh"));
|
|
7207
|
+
console.log(chalk17.cyan(" CM: \u25CB 842f 12.4k\u25C6 \u26A03 | 2h ago") + chalk17.dim(" \u2014 no watcher, 3 stale files"));
|
|
7208
|
+
console.log(chalk17.cyan(" CM: \u25CB 842f 12.4k\u25C6 IDX | 5s ago") + chalk17.dim(" \u2014 indexing in progress"));
|
|
7209
|
+
console.log(chalk17.cyan(" CM: \u2014 no index (run: codemap index)") + chalk17.dim(" \u2014 not yet indexed"));
|
|
7210
|
+
console.log();
|
|
7211
|
+
console.log(chalk17.dim("Restart Claude Code to see the statusline."));
|
|
7212
|
+
console.log(chalk17.dim("Run `codemap statusline --uninstall` to remove."));
|
|
7213
|
+
console.log();
|
|
7214
|
+
console.log(chalk17.dim("Tip: Install codemap in multiple projects to give each Claude Code"));
|
|
7215
|
+
console.log(chalk17.dim("session its own code intelligence \u2014 frontend, backend, shared libs."));
|
|
7216
|
+
console.log(chalk17.dim("Run `codemap init` in any project to get started."));
|
|
7217
|
+
}
|
|
7218
|
+
function uninstall() {
|
|
7219
|
+
let originalCommand = "";
|
|
7220
|
+
if (fs18.existsSync(BACKUP_FILE)) {
|
|
7221
|
+
try {
|
|
7222
|
+
originalCommand = fs18.readFileSync(BACKUP_FILE, "utf-8").trim();
|
|
7223
|
+
} catch {
|
|
7224
|
+
}
|
|
7225
|
+
try {
|
|
7226
|
+
fs18.unlinkSync(BACKUP_FILE);
|
|
7227
|
+
} catch {
|
|
7228
|
+
}
|
|
7229
|
+
}
|
|
7230
|
+
if (fs18.existsSync(SCRIPT_FILE)) {
|
|
7231
|
+
try {
|
|
7232
|
+
const content = fs18.readFileSync(SCRIPT_FILE, "utf-8");
|
|
7233
|
+
if (content.includes("Generated by: codemap statusline")) {
|
|
7234
|
+
fs18.unlinkSync(SCRIPT_FILE);
|
|
7235
|
+
console.log(chalk17.dim("Removed statusline script."));
|
|
7236
|
+
}
|
|
7237
|
+
} catch {
|
|
7238
|
+
}
|
|
7239
|
+
}
|
|
7240
|
+
const settings = readSettings();
|
|
7241
|
+
if (originalCommand && originalCommand !== SCRIPT_FILE) {
|
|
7242
|
+
settings.statusline_command = originalCommand;
|
|
7243
|
+
writeSettings(settings);
|
|
7244
|
+
console.log(chalk17.dim(`Restored original statusline command.`));
|
|
7245
|
+
} else if (settings.statusline_command) {
|
|
7246
|
+
delete settings.statusline_command;
|
|
7247
|
+
writeSettings(settings);
|
|
7248
|
+
console.log(chalk17.dim("Cleared statusline_command from settings."));
|
|
7249
|
+
}
|
|
7250
|
+
console.log();
|
|
7251
|
+
console.log(chalk17.green("CodeMap statusline removed."));
|
|
7252
|
+
console.log(chalk17.dim("Restart Claude Code for changes to take effect."));
|
|
7253
|
+
}
|
|
7254
|
+
|
|
7013
7255
|
// src/index.ts
|
|
7014
|
-
var __dirname =
|
|
7015
|
-
var grammarsDir =
|
|
7256
|
+
var __dirname = path14.dirname(fileURLToPath(import.meta.url));
|
|
7257
|
+
var grammarsDir = path14.join(__dirname, "grammars");
|
|
7016
7258
|
setGrammarDir(grammarsDir);
|
|
7017
7259
|
var program = new Command();
|
|
7018
7260
|
program.name("codemap").description("Code intelligence CLI \u2014 hybrid search, dependency analysis, PageRank").version("0.3.5").option("--cwd <dir>", "Project directory (default: cwd)");
|
|
@@ -7033,4 +7275,5 @@ registerSummary(program);
|
|
|
7033
7275
|
registerCoupling(program);
|
|
7034
7276
|
registerGraphStats(program);
|
|
7035
7277
|
registerRebuild(program);
|
|
7278
|
+
registerStatusline(program);
|
|
7036
7279
|
program.parse();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ulpi/codemap",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.9",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Standalone code intelligence CLI — hybrid vector + BM25 search, dependency analysis, PageRank",
|
|
6
6
|
"bin": {
|
|
@@ -10,9 +10,11 @@
|
|
|
10
10
|
".": "./dist/index.js"
|
|
11
11
|
},
|
|
12
12
|
"files": [
|
|
13
|
-
"dist"
|
|
13
|
+
"dist",
|
|
14
|
+
"scripts/postinstall.js"
|
|
14
15
|
],
|
|
15
16
|
"scripts": {
|
|
17
|
+
"postinstall": "node scripts/postinstall.js",
|
|
16
18
|
"build": "tsup && node --import tsx scripts/copy-grammars.ts",
|
|
17
19
|
"typecheck": "tsc --noEmit",
|
|
18
20
|
"test": "vitest run",
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// Postinstall welcome message for `npm install -g @ulpi/codemap`
|
|
2
|
+
const cyan = (s) => `\x1b[36m${s}\x1b[0m`;
|
|
3
|
+
const dim = (s) => `\x1b[2m${s}\x1b[0m`;
|
|
4
|
+
const bold = (s) => `\x1b[1m${s}\x1b[0m`;
|
|
5
|
+
|
|
6
|
+
console.log();
|
|
7
|
+
console.log(bold("codemap") + " installed successfully.");
|
|
8
|
+
console.log();
|
|
9
|
+
console.log("Get started:");
|
|
10
|
+
console.log(` ${cyan("codemap init")} ${dim("# Choose embedding provider + model")}`);
|
|
11
|
+
console.log(` ${cyan("codemap index")} ${dim("# Index your project")}`);
|
|
12
|
+
console.log(` ${cyan("codemap search")} ${dim('"query"')} ${dim("# Search your code")}`);
|
|
13
|
+
console.log();
|
|
14
|
+
console.log("Add as an MCP server to give your AI agent code intelligence:");
|
|
15
|
+
console.log(` ${cyan("codemap serve")} ${dim("# Start MCP server (stdio)")}`);
|
|
16
|
+
console.log();
|
|
17
|
+
console.log("Multi-project: Index each codebase, then register one MCP server per project.");
|
|
18
|
+
console.log("Your AI agent gets code intelligence across your entire stack.");
|
|
19
|
+
console.log();
|
|
20
|
+
console.log(` ${dim("# Index each project once:")}`);
|
|
21
|
+
console.log(` ${dim("$")} ${cyan("codemap init")} && ${cyan("codemap index")} ${dim("# current project")}`);
|
|
22
|
+
console.log(` ${dim("$")} cd ~/projects/frontend && ${cyan("codemap init")} && ${cyan("codemap index")}`);
|
|
23
|
+
console.log();
|
|
24
|
+
console.log(` ${dim("# .mcp.json — add to the project where you use your AI agent:")}`);
|
|
25
|
+
console.log(` ${dim("{")}`)
|
|
26
|
+
console.log(` ${dim(' "mcpServers": {')}`);
|
|
27
|
+
console.log(` ${dim(' "codemap": {')}`);
|
|
28
|
+
console.log(` ${dim(' "command": "codemap", "args": ["serve"]')} ${dim("← this project")}`);
|
|
29
|
+
console.log(` ${dim(' },')}`);
|
|
30
|
+
console.log(` ${dim(' "codemap-frontend": {')}`);
|
|
31
|
+
console.log(` ${dim(' "command": "codemap", "args": ["serve", "--cwd",')}`);
|
|
32
|
+
console.log(` ${dim(' "/path/to/frontend"]')} ${dim("← another project")}`);
|
|
33
|
+
console.log(` ${dim(' }')}`);
|
|
34
|
+
console.log(` ${dim(" }")}`);
|
|
35
|
+
console.log(` ${dim("}")}`);
|
|
36
|
+
console.log();
|