@raymondchins/agentmap 0.6.1 → 0.7.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/README.md +21 -0
- package/agentmap.mjs +83 -2
- package/package.json +2 -1
- package/skills/SKILL.md +71 -0
- package/skills/cursor-rule.mdc +27 -0
- package/skills/install.mjs +97 -0
package/README.md
CHANGED
|
@@ -185,6 +185,25 @@ internally on `tool_name`. For reference, or to wire it by hand:
|
|
|
185
185
|
That's the "forced to use it" in the tagline: the map stays current on its own, and the
|
|
186
186
|
agent is steered to it the moment it reaches for a dependency-shaped grep or Bash search.
|
|
187
187
|
|
|
188
|
+
### 3. Agent skills (Cursor, Claude Code, Codex)
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
npx @raymondchins/agentmap --install-skill
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Copies a packaged **SKILL.md** (Claude Code / Codex / OpenCode) and a **Cursor rule**
|
|
195
|
+
(`.cursor/rules/agentmap.mdc`, `alwaysApply: true`) into the current repo or global
|
|
196
|
+
agent directories. Options:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
agentmap --install-skill --platform cursor # Cursor rule only
|
|
200
|
+
agentmap --install-skill --platform claude # .claude/skills/agentmap/SKILL.md
|
|
201
|
+
agentmap --install-skill --global --platform claude # ~/.claude/skills/...
|
|
202
|
+
agentmap --install-skill --dry-run # preview paths, no writes
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Pair with `--install-hooks` (Claude Code) or `--mcp` (Cursor MCP).
|
|
206
|
+
|
|
188
207
|
---
|
|
189
208
|
|
|
190
209
|
## Quickstart
|
|
@@ -481,6 +500,8 @@ $ node agentmap.mjs --print | jq '.hubs[0]'
|
|
|
481
500
|
| `--version` / `-v` | Print the version from `package.json` and exit 0. |
|
|
482
501
|
| `--json` | **Global modifier.** When present, every command prints exactly one JSON object to stdout (no prose). Shapes vary per command: `--json --hubs` → `{command,fileCount,sha,hubs:[string]}`, `--json --find X` → `{command,query,matches:[{file,name,kind}]}`, `--json --relates X` → `{command,file,pagerank,exports,imports,dependents,related}`, `--json --any X` → `{command,query,kind,…payload}`, etc. Bare `--json` (no query flag) → `{command:"build",fileCount,features,topHub}`. |
|
|
483
502
|
| `--install-hooks` | Copy `hooks/post-commit` into `.git/hooks/` (chmod 0755), ensure `.claude/agentmap.json` is in `.gitignore`, and auto-wire the Claude Code `PreToolUse(Grep)` nudge into `.claude/settings.json` (merge-safe + idempotent). Exit 0 on success, stderr + exit 1 on failure. |
|
|
503
|
+
| `--hook-status` | Report whether the post-commit hook, PreToolUse nudge, and `.gitignore` entry are installed (no writes). |
|
|
504
|
+
| `--install-skill` | Install packaged agent skill + Cursor rule (`--platform claude\|cursor\|agents\|all`, default `all`; `--project` default, or `--global`; `--dry-run` preview). |
|
|
484
505
|
| `--mcp` | Start agentmap as a **stdio MCP server** so non-Claude-Code agents (Cursor, Cline, any MCP client) can call every flag as a first-class tool. |
|
|
485
506
|
|
|
486
507
|
**Exit-code contract:** `0` = success / match / help / version; `1` = query returned zero results (`--any`, `--find`, `--relates`, `--feature` with no match); `2` = usage error (missing required arg, unknown flag). Any token starting with `-` that matches no known flag prints an error to stderr and exits 2.
|
package/agentmap.mjs
CHANGED
|
@@ -917,6 +917,60 @@ function installHooks({ dryRun = false } = {}) {
|
|
|
917
917
|
console.log("\nDone — the map auto-refreshes on commit, and greps are nudged to agentmap first.");
|
|
918
918
|
}
|
|
919
919
|
|
|
920
|
+
// Marker string baked into hooks/post-commit — used by --hook-status to detect our
|
|
921
|
+
// hook even when chained with other tools in the same file.
|
|
922
|
+
const POST_COMMIT_MARKER = "agentmap — git post-commit hook";
|
|
923
|
+
const NUDGE_REL = ".claude/hooks/agentmap-nudge.mjs";
|
|
924
|
+
const MAP_IGNORE_LINE = ".claude/agentmap/";
|
|
925
|
+
|
|
926
|
+
function hookStatus() {
|
|
927
|
+
const gitDir = sh("git rev-parse --git-dir");
|
|
928
|
+
if (!gitDir) {
|
|
929
|
+
console.log("not a git repository — run inside the repo you want to check");
|
|
930
|
+
return;
|
|
931
|
+
}
|
|
932
|
+
const hooksDir = `${gitDir}/hooks`;
|
|
933
|
+
const postCommitPath = `${hooksDir}/post-commit`;
|
|
934
|
+
|
|
935
|
+
let postCommit = "not installed";
|
|
936
|
+
if (existsSync(postCommitPath)) {
|
|
937
|
+
const body = readFileSync(postCommitPath, "utf8");
|
|
938
|
+
postCommit = body.includes(POST_COMMIT_MARKER) ? "installed" : "not installed (hook exists but agentmap not found)";
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
let nudge = existsSync(NUDGE_REL) ? "installed" : "not installed";
|
|
942
|
+
|
|
943
|
+
let grepWire = "not wired";
|
|
944
|
+
let bashWire = "not wired";
|
|
945
|
+
const settingsPath = ".claude/settings.json";
|
|
946
|
+
if (existsSync(settingsPath)) {
|
|
947
|
+
try {
|
|
948
|
+
const settings = parseSettings(readFileSync(settingsPath, "utf8"), settingsPath);
|
|
949
|
+
const entries = settings.hooks?.PreToolUse || [];
|
|
950
|
+
const has = (matcher) => entries.some(
|
|
951
|
+
(e) => e?.matcher === matcher && Array.isArray(e?.hooks) && e.hooks.some((h) => typeof h?.command === "string" && h.command.includes("agentmap-nudge")),
|
|
952
|
+
);
|
|
953
|
+
grepWire = has("Grep") ? "wired" : "not wired";
|
|
954
|
+
bashWire = has("Bash") ? "wired" : "not wired";
|
|
955
|
+
} catch {
|
|
956
|
+
grepWire = "not wired (invalid settings.json)";
|
|
957
|
+
bashWire = "not wired (invalid settings.json)";
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
let gitignore = "missing entry";
|
|
962
|
+
if (existsSync(".gitignore")) {
|
|
963
|
+
const ok = readFileSync(".gitignore", "utf8").split(/\r?\n/).some((l) => l.trim() === MAP_IGNORE_LINE);
|
|
964
|
+
gitignore = ok ? "ok" : "missing entry";
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
console.log(`post-commit: ${postCommit}`);
|
|
968
|
+
console.log(`nudge (${NUDGE_REL}): ${nudge}`);
|
|
969
|
+
console.log(`PreToolUse(Grep): ${grepWire}`);
|
|
970
|
+
console.log(`PreToolUse(Bash): ${bashWire}`);
|
|
971
|
+
console.log(`.gitignore (${MAP_IGNORE_LINE}): ${gitignore}`);
|
|
972
|
+
}
|
|
973
|
+
|
|
920
974
|
// ---------------------------------------------------------------------------
|
|
921
975
|
// --setup-mcp: register the agentmap MCP server in the global configs of
|
|
922
976
|
// MCP-capable IDEs that aren't Claude Code (which uses --install-hooks instead).
|
|
@@ -998,7 +1052,8 @@ const out = (obj, prose) => { if (wantJson) console.log(JSON.stringify(obj)); el
|
|
|
998
1052
|
// NOT in this set is an unknown flag → usage error (exit 2), not a silent build.
|
|
999
1053
|
const KNOWN = new Set([
|
|
1000
1054
|
"--json", "--print",
|
|
1001
|
-
"--help", "-h", "--version", "-v", "--install-hooks", "--
|
|
1055
|
+
"--help", "-h", "--version", "-v", "--install-hooks", "--hook-status", "--install-skill", "--platform", "--project", "--global",
|
|
1056
|
+
"--dry-run", "--setup-mcp", "--mcp",
|
|
1002
1057
|
"--any", "--find", "--relates", "--map", "--focus", "--tokens",
|
|
1003
1058
|
"--symbols", "--feature", "--features", "--hubs",
|
|
1004
1059
|
]);
|
|
@@ -1007,7 +1062,7 @@ const KNOWN = new Set([
|
|
|
1007
1062
|
// so a dash-leading query like `--any "-O/bin/sh"` is bound as the query, not
|
|
1008
1063
|
// mistaken for an unknown flag. (arg() already rejects a "--"-leading value, so
|
|
1009
1064
|
// `--any --foo` still falls through to the missing-arg guard instead.)
|
|
1010
|
-
const VALUE_FLAGS = new Set(["--any", "--find", "--relates", "--feature", "--focus", "--tokens", "--symbols"]);
|
|
1065
|
+
const VALUE_FLAGS = new Set(["--any", "--find", "--relates", "--feature", "--focus", "--tokens", "--symbols", "--platform"]);
|
|
1011
1066
|
const valueIdx = new Set();
|
|
1012
1067
|
for (let i = 0; i < args.length - 1; i++) if (VALUE_FLAGS.has(args[i])) valueIdx.add(i + 1);
|
|
1013
1068
|
|
|
@@ -1035,6 +1090,9 @@ Maintenance:
|
|
|
1035
1090
|
--install-hooks [--dry-run]
|
|
1036
1091
|
install git post-commit + copy the PreToolUse nudge +
|
|
1037
1092
|
wire .claude/settings.json (--dry-run = preview, no writes)
|
|
1093
|
+
--install-skill [--platform claude|cursor|agents|all] [--project|--global] [--dry-run]
|
|
1094
|
+
install SKILL.md / Cursor rule for coding agents
|
|
1095
|
+
--hook-status report whether agentmap git/nudge wiring is installed
|
|
1038
1096
|
--setup-mcp [--dry-run]
|
|
1039
1097
|
configure MCP server for OpenCode & Antigravity IDE
|
|
1040
1098
|
(--dry-run = preview, no writes)
|
|
@@ -1073,6 +1131,29 @@ else if (has("--install-hooks")) {
|
|
|
1073
1131
|
try { installHooks({ dryRun: has("--dry-run") }); process.exit(0); }
|
|
1074
1132
|
catch (e) { console.error(`agentmap --install-hooks failed: ${e?.message || e}`); process.exit(1); }
|
|
1075
1133
|
}
|
|
1134
|
+
// --install-skill: copy packaged SKILL.md / Cursor rule (see skills/install.mjs).
|
|
1135
|
+
else if (has("--install-skill")) {
|
|
1136
|
+
try {
|
|
1137
|
+
// lazy import keeps skills/install.mjs (and its package.json read) OFF the
|
|
1138
|
+
// hot path — warm --any/--find queries must not load it.
|
|
1139
|
+
const { installSkill } = await import("./skills/install.mjs");
|
|
1140
|
+
installSkill({
|
|
1141
|
+
platforms: arg("--platform") || "all",
|
|
1142
|
+
project: !has("--global"),
|
|
1143
|
+
global: has("--global"),
|
|
1144
|
+
dryRun: has("--dry-run"),
|
|
1145
|
+
});
|
|
1146
|
+
process.exit(0);
|
|
1147
|
+
} catch (e) {
|
|
1148
|
+
console.error(`agentmap --install-skill failed: ${e?.message || e}`);
|
|
1149
|
+
process.exit(1);
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
// --hook-status: report post-commit / nudge / settings wiring (no writes).
|
|
1153
|
+
else if (has("--hook-status")) {
|
|
1154
|
+
try { hookStatus(); process.exit(0); }
|
|
1155
|
+
catch (e) { console.error(`agentmap --hook-status failed: ${e?.message || e}`); process.exit(1); }
|
|
1156
|
+
}
|
|
1076
1157
|
// --setup-mcp: configure MCP server for OpenCode & Antigravity IDE.
|
|
1077
1158
|
else if (has("--setup-mcp")) {
|
|
1078
1159
|
try { setupMcp({ dryRun: has("--dry-run") }); process.exit(0); }
|
package/package.json
CHANGED
package/skills/SKILL.md
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agentmap
|
|
3
|
+
description: >-
|
|
4
|
+
Use for TypeScript/JavaScript codebase navigation — symbol lookup, blast radius,
|
|
5
|
+
reuse checks, and repo orientation. Prefer agentmap before serial grep when
|
|
6
|
+
exploring imports, exports, or where a symbol lives. Package is
|
|
7
|
+
@raymondchins/agentmap (not the unrelated npm package agentmap).
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# agentmap
|
|
11
|
+
|
|
12
|
+
Queryable, ranked **import graph** for TS/JS repos (PageRank hubs, symbol ranking, token-budgeted digest). Faster and more accurate than grep for structural questions.
|
|
13
|
+
|
|
14
|
+
## When to use
|
|
15
|
+
|
|
16
|
+
- **Where is X defined?** / **who imports this file?** / **what breaks if I edit this?**
|
|
17
|
+
- **Reuse check** before adding a util, component, or type
|
|
18
|
+
- **Session start** — orient to a large monorepo cheaply
|
|
19
|
+
|
|
20
|
+
## When not to use
|
|
21
|
+
|
|
22
|
+
- Raw string / config value search (try `agentmap --any` first — layer 4 is live `git grep`)
|
|
23
|
+
- Non-TS/JS files, runtime call graphs, or full semantic "how does it work?" (use codebase search)
|
|
24
|
+
- Next-style `--feature` on TanStack Router / non-`app/` layouts (often empty)
|
|
25
|
+
|
|
26
|
+
## Commands (run in repo root)
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# Smart router — default first move
|
|
30
|
+
agentmap --any <query>
|
|
31
|
+
|
|
32
|
+
# Reuse / symbol definition
|
|
33
|
+
agentmap --find <SymbolName>
|
|
34
|
+
|
|
35
|
+
# Blast radius (exports, imports, dependents, related files)
|
|
36
|
+
agentmap --relates <path/to/file.ts>
|
|
37
|
+
|
|
38
|
+
# Token-budgeted ranked digest
|
|
39
|
+
agentmap --map --tokens 400
|
|
40
|
+
agentmap --map --focus <path> --tokens 400
|
|
41
|
+
|
|
42
|
+
# Hub files (PageRank)
|
|
43
|
+
agentmap --hubs
|
|
44
|
+
|
|
45
|
+
# JSON for tools
|
|
46
|
+
agentmap --json --any <query>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Install: `npm i -g @raymondchins/agentmap` or `npx @raymondchins/agentmap`. Map cache: `.claude/agentmap/` (gitignored).
|
|
50
|
+
|
|
51
|
+
## Agent platforms
|
|
52
|
+
|
|
53
|
+
| Platform | Setup |
|
|
54
|
+
|----------|--------|
|
|
55
|
+
| **Claude Code** | `agentmap --install-hooks` (post-commit refresh + PreToolUse grep nudge) |
|
|
56
|
+
| **Cursor / MCP clients** | `agentmap --mcp` in MCP config, or Shell + commands above |
|
|
57
|
+
| **This skill** | `agentmap --install-skill` |
|
|
58
|
+
|
|
59
|
+
## Workflow
|
|
60
|
+
|
|
61
|
+
1. If the map may be stale after edits, run `agentmap` (no flags) or rely on post-commit hook.
|
|
62
|
+
2. Start with `agentmap --any <symbol or topic>`.
|
|
63
|
+
3. Before editing a hub file, run `agentmap --relates <that-file>`.
|
|
64
|
+
4. Fall back to grep only when agentmap returns no useful structure hit.
|
|
65
|
+
|
|
66
|
+
## Package name
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
npx @raymondchins/agentmap --any Procedure
|
|
70
|
+
# NOT: npm install agentmap (different package)
|
|
71
|
+
```
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: agentmap ranked TS/JS repo map
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
This project can use **agentmap** (`@raymondchins/agentmap`) — a queryable import/symbol map at `.claude/agentmap/`.
|
|
7
|
+
|
|
8
|
+
**Before Grep/Glob for structural questions** (where is a symbol, who imports a file, reuse check, blast radius), prefer:
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
agentmap --any <query> # file → symbol → feature → git-grep fallback
|
|
12
|
+
agentmap --find <Symbol> # exported symbols matching name
|
|
13
|
+
agentmap --relates <file.ts> # imports, dependents, related files
|
|
14
|
+
agentmap --map --tokens 400 # cheap repo orientation
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Use Read/Grep directly when:
|
|
18
|
+
|
|
19
|
+
1. agentmap already oriented you and you need exact lines to edit
|
|
20
|
+
2. The map is missing — run `agentmap` once to build `.claude/agentmap/`
|
|
21
|
+
3. Searching raw strings, logs, or non-TS files
|
|
22
|
+
|
|
23
|
+
**Cursor MCP (optional):** `agentmap --mcp` exposes the same queries as tools.
|
|
24
|
+
|
|
25
|
+
**Note:** `--features` only detects Next.js `app/` routes; TanStack `src/routes/` repos often show `features (0)`.
|
|
26
|
+
|
|
27
|
+
Package: `@raymondchins/agentmap` — not the unrelated PyPI/npm `agentmap` package.
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// --install-skill: copy packaged SKILL.md / Cursor rule into project or global
|
|
3
|
+
// agent directories (project or global scope).
|
|
4
|
+
|
|
5
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync, renameSync } from "node:fs";
|
|
6
|
+
import { homedir } from "node:os";
|
|
7
|
+
import { join, dirname } from "node:path";
|
|
8
|
+
import { fileURLToPath } from "node:url";
|
|
9
|
+
|
|
10
|
+
const SKILLS_DIR = dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
|
|
12
|
+
/** @type {Record<string, { label: string; src: string; dest: (root: string) => string; projectOnly?: boolean }>} */
|
|
13
|
+
const PLATFORMS = {
|
|
14
|
+
claude: {
|
|
15
|
+
label: "Claude Code",
|
|
16
|
+
src: join(SKILLS_DIR, "SKILL.md"),
|
|
17
|
+
dest: (root) => join(root, ".claude", "skills", "agentmap", "SKILL.md"),
|
|
18
|
+
},
|
|
19
|
+
agents: {
|
|
20
|
+
label: "Codex / OpenCode (.agents)",
|
|
21
|
+
src: join(SKILLS_DIR, "SKILL.md"),
|
|
22
|
+
dest: (root) => join(root, ".agents", "skills", "agentmap", "SKILL.md"),
|
|
23
|
+
},
|
|
24
|
+
cursor: {
|
|
25
|
+
label: "Cursor",
|
|
26
|
+
src: join(SKILLS_DIR, "cursor-rule.mdc"),
|
|
27
|
+
dest: (root) => join(root, ".cursor", "rules", "agentmap.mdc"),
|
|
28
|
+
projectOnly: true,
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
function atomicWrite(dest, body) {
|
|
33
|
+
mkdirSync(dirname(dest), { recursive: true });
|
|
34
|
+
const tmp = `${dest}.tmp`;
|
|
35
|
+
writeFileSync(tmp, body, "utf8");
|
|
36
|
+
renameSync(tmp, dest);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function parsePlatforms(raw) {
|
|
40
|
+
if (!raw || raw === "all") return ["claude", "cursor", "agents"];
|
|
41
|
+
const names = raw.split(/[,+]/).map((s) => s.trim().toLowerCase()).filter(Boolean);
|
|
42
|
+
for (const n of names) {
|
|
43
|
+
if (!PLATFORMS[n]) {
|
|
44
|
+
throw new Error(`unknown platform '${n}' — choose: ${Object.keys(PLATFORMS).join(", ")}, all`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return names;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function gitAddHint(paths) {
|
|
51
|
+
const unique = [...new Set(paths.map((p) => p.replace(/\/[^/]+$/, "") || p))];
|
|
52
|
+
if (unique.length) console.log(`\nOptional: git add ${unique.map((p) => `"${p}"`).join(" ")}`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @param {{ platforms?: string; project?: boolean; global?: boolean; dryRun?: boolean }} opts
|
|
57
|
+
*/
|
|
58
|
+
export function installSkill({ platforms: platformsArg = "all", project = true, global: globalScope = false, dryRun = false } = {}) {
|
|
59
|
+
if (project && globalScope) throw new Error("use either --project or --global, not both");
|
|
60
|
+
// read version lazily (inside the function, not at module load) so importing
|
|
61
|
+
// this module is side-effect-free / off the CLI hot path.
|
|
62
|
+
const VERSION = JSON.parse(readFileSync(join(SKILLS_DIR, "..", "package.json"), "utf8")).version;
|
|
63
|
+
const scope = globalScope ? "global" : "project";
|
|
64
|
+
const root = globalScope ? homedir() : process.cwd();
|
|
65
|
+
const names = parsePlatforms(platformsArg);
|
|
66
|
+
const targets = [];
|
|
67
|
+
|
|
68
|
+
if (dryRun) console.log(`--dry-run: would install agentmap skill (${scope} scope):`);
|
|
69
|
+
|
|
70
|
+
for (const name of names) {
|
|
71
|
+
const cfg = PLATFORMS[name];
|
|
72
|
+
if (cfg.projectOnly && globalScope) {
|
|
73
|
+
console.log(` skip ${cfg.label}: Cursor rule is project-scoped only (re-run with --project)`);
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (!existsSync(cfg.src)) throw new Error(`packaged skill missing: ${cfg.src}`);
|
|
77
|
+
const dest = cfg.dest(root);
|
|
78
|
+
const body = readFileSync(cfg.src, "utf8");
|
|
79
|
+
const versionFile = join(dirname(dest), ".agentmap_version");
|
|
80
|
+
|
|
81
|
+
if (dryRun) {
|
|
82
|
+
console.log(` ${cfg.label}: ${dest}`);
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
atomicWrite(dest, body);
|
|
87
|
+
writeFileSync(versionFile, VERSION + "\n", "utf8");
|
|
88
|
+
console.log(` ${cfg.label} → ${dest}`);
|
|
89
|
+
targets.push(dest);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (!dryRun && targets.length) {
|
|
93
|
+
console.log(`\nagentmap --install-skill: installed ${targets.length} file(s) (${scope}).`);
|
|
94
|
+
if (!globalScope) gitAddHint(targets);
|
|
95
|
+
console.log("Pair with: agentmap --install-hooks (Claude Code) or agentmap --mcp (Cursor MCP).");
|
|
96
|
+
}
|
|
97
|
+
}
|