@niroai/niro 0.3.4 → 0.3.6
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/package.json +1 -1
- package/src/mcp/setup.js +149 -5
- package/src/mcp/teardown.js +8 -6
package/package.json
CHANGED
package/src/mcp/setup.js
CHANGED
|
@@ -41,17 +41,27 @@ const NIRO_MD_MARKER = "<!-- niro-mcp -->";
|
|
|
41
41
|
* own notes added below the block survive uninstall — see teardown.js removeMarkerSection).
|
|
42
42
|
* Each begins with a leading "\n" because install does `existing + section`.
|
|
43
43
|
*/
|
|
44
|
+
/**
|
|
45
|
+
* Explore-first rule, shared by every client's markdown section. Prose alone is weak, but this is the
|
|
46
|
+
* one lever some clients (Codex, Copilot CLI, Factory, OpenCode, Windsurf) have — they support no hooks,
|
|
47
|
+
* so their ONLY always-on nudge is this file. For Claude Code it reinforces the PreToolUse Grep|Glob|Read
|
|
48
|
+
* hook (NIRO_EXPLORE_COMMAND), which fires once per session/repo/branch; this stays in force for the rest
|
|
49
|
+
* of the session. Wording is imperative and names concrete tools so the agent knows what to call instead
|
|
50
|
+
* of native search.
|
|
51
|
+
*/
|
|
52
|
+
const NIRO_EXPLORE_FIRST_SENTENCE = "MUST FOLLOW: before you run grep, find, glob, or open a file to hunt for something, first check whether a Niro tool answers it (code_grep for content search, resolve_fqn and get_source_code for a known symbol, find_handler and find_api_endpoints for entry points). Use the connection tools (get_call_chain, get_reverse_call_chain, get_blast_radius, get_impact_analysis, get_service_topology) to understand how code connects BEFORE deciding which file to read or search next, rather than reading files to rebuild that picture by hand. Native search is the fallback for what Niro does not cover (config files, docs, logs, generated output, non-code text) or when the tools are unavailable.";
|
|
53
|
+
|
|
44
54
|
const NIRO_MULTI_REPO_SENTENCE = "The temporary project answer is per (repo, BRANCH): after you create/switch a branch in a repo — and before your first edit on that branch — call should_create_temp_project with the repo's git url, its CURRENT branch, and its `.niro-project` id if present, then run `niro new-temp-project` in its folder if needs_temp_project is true. Re-check after every branch change (a `false` from another branch does NOT carry over); this applies to every repo you touch, including when the session started in a parent folder that is not itself a git repo.";
|
|
45
|
-
const NIRO_CLAUDE_MD_SECTION = `\n${NIRO_MD_MARKER}\n## Niro MCP\nNiro MCP tools are available for code intelligence. Use them (call chains, blast radius, impact analysis, source lookup) before falling back to native grep/read for code questions.\nBefore adding/writing any new code, you MUST use the find_reusable_code tool from niro to figure out if there is anything reusable.\n${NIRO_MULTI_REPO_SENTENCE}\n`;
|
|
46
|
-
const NIRO_CODEX_MD_SECTION = `\n${NIRO_MD_MARKER}\n## Niro MCP\nNiro MCP code-intelligence tools and the \`niro-skill\` are available (call chains, blast radius, impact analysis, source lookup). Prefer them over grep/read for questions about this codebase; the niro-skill has the full tool-routing playbook. Before adding or writing any new code, use find_reusable_code to check for reusable code. If the niro tools are not present or the repo is not indexed, use native tools.\n${NIRO_MULTI_REPO_SENTENCE}\n`;
|
|
47
|
-
const NIRO_WINDSURF_MD_SECTION = `\n${NIRO_MD_MARKER}\n## Niro MCP\nNiro MCP code-intelligence tools and the niro-skill are available. Prefer them over grep/read for questions about this codebase (structure, call chains, blast radius, impact, data flows, reuse); the niro-skill has the full routing playbook. Before writing any new code, use find_reusable_code. If the niro tools are not present or the repo is not indexed, use native tools.\n${NIRO_MULTI_REPO_SENTENCE}\n`;
|
|
55
|
+
const NIRO_CLAUDE_MD_SECTION = `\n${NIRO_MD_MARKER}\n## Niro MCP\nNiro MCP tools are available for code intelligence. Use them (call chains, blast radius, impact analysis, source lookup) before falling back to native grep/read for code questions.\nBefore adding/writing any new code, you MUST use the find_reusable_code tool from niro to figure out if there is anything reusable.\n${NIRO_EXPLORE_FIRST_SENTENCE}\n${NIRO_MULTI_REPO_SENTENCE}\n`;
|
|
56
|
+
const NIRO_CODEX_MD_SECTION = `\n${NIRO_MD_MARKER}\n## Niro MCP\nNiro MCP code-intelligence tools and the \`niro-skill\` are available (call chains, blast radius, impact analysis, source lookup). Prefer them over grep/read for questions about this codebase; the niro-skill has the full tool-routing playbook. Before adding or writing any new code, use find_reusable_code to check for reusable code. If the niro tools are not present or the repo is not indexed, use native tools.\n${NIRO_EXPLORE_FIRST_SENTENCE}\n${NIRO_MULTI_REPO_SENTENCE}\n`;
|
|
57
|
+
const NIRO_WINDSURF_MD_SECTION = `\n${NIRO_MD_MARKER}\n## Niro MCP\nNiro MCP code-intelligence tools and the niro-skill are available. Prefer them over grep/read for questions about this codebase (structure, call chains, blast radius, impact, data flows, reuse); the niro-skill has the full routing playbook. Before writing any new code, use find_reusable_code. If the niro tools are not present or the repo is not indexed, use native tools.\n${NIRO_EXPLORE_FIRST_SENTENCE}\n${NIRO_MULTI_REPO_SENTENCE}\n`;
|
|
48
58
|
/**
|
|
49
59
|
* Shared generic section for clients whose "always-on instructions" file has no companion
|
|
50
60
|
* skill mechanism we've verified (Gemini CLI's GEMINI.md, GitHub Copilot CLI's
|
|
51
61
|
* copilot-instructions.md, Factory's AGENTS.md, OpenCode's AGENTS.md) — one wording, reused
|
|
52
62
|
* across those destination files (teardown matches it per-file, so reuse is safe).
|
|
53
63
|
*/
|
|
54
|
-
const NIRO_GENERIC_MD_SECTION = `\n${NIRO_MD_MARKER}\n## Niro MCP\nNiro MCP code-intelligence tools are available (call chains, blast radius, impact analysis, source lookup). Prefer them over grep/read for questions about this codebase. Before adding or writing any new code, use find_reusable_code to check for reusable code. If the niro tools are not present or the repo is not indexed, use native tools.\n${NIRO_MULTI_REPO_SENTENCE}\n`;
|
|
64
|
+
const NIRO_GENERIC_MD_SECTION = `\n${NIRO_MD_MARKER}\n## Niro MCP\nNiro MCP code-intelligence tools are available (call chains, blast radius, impact analysis, source lookup). Prefer them over grep/read for questions about this codebase. Before adding or writing any new code, use find_reusable_code to check for reusable code. If the niro tools are not present or the repo is not indexed, use native tools.\n${NIRO_EXPLORE_FIRST_SENTENCE}\n${NIRO_MULTI_REPO_SENTENCE}\n`;
|
|
55
65
|
|
|
56
66
|
/** All niro markdown sections — the uninstaller tries each for an exact removal. */
|
|
57
67
|
const NIRO_MD_SECTIONS = [NIRO_CLAUDE_MD_SECTION, NIRO_CODEX_MD_SECTION, NIRO_WINDSURF_MD_SECTION, NIRO_GENERIC_MD_SECTION];
|
|
@@ -116,6 +126,18 @@ function isNiroPreToolUseHook(h) {
|
|
|
116
126
|
return cmds.some((c) => c.includes("should_create_temp_project") || c.includes("should_sandbox_repo"));
|
|
117
127
|
}
|
|
118
128
|
|
|
129
|
+
/**
|
|
130
|
+
* True if `h` is niro's PreToolUse explore-first reminder entry (matcher Grep|Glob|Read). Keyed on the
|
|
131
|
+
* unique `niro-explore-` marker-file prefix so a foreign PreToolUse hook on the same matcher is never
|
|
132
|
+
* touched. Shared by installer (upgrade-in-place) and uninstaller (removal).
|
|
133
|
+
*/
|
|
134
|
+
function isNiroExploreHook(h) {
|
|
135
|
+
const cmds = [];
|
|
136
|
+
if (h && Array.isArray(h.hooks)) h.hooks.forEach((i) => i && typeof i.command === "string" && cmds.push(i.command));
|
|
137
|
+
if (h && typeof h.command === "string") cmds.push(h.command);
|
|
138
|
+
return cmds.some((c) => c.includes("niro-explore-"));
|
|
139
|
+
}
|
|
140
|
+
|
|
119
141
|
/**
|
|
120
142
|
* Writes a niro-managed skill/rule file, refreshing it when the generated content has
|
|
121
143
|
* changed. These files are GENERATED (not hand-edited), so refresh-on-change is correct:
|
|
@@ -541,6 +563,7 @@ async function setupClaudeCode(apiKey, mcpServerUrl) {
|
|
|
541
563
|
addClaudeCodePostCompactHook();
|
|
542
564
|
addClaudeCodeUserPromptHook();
|
|
543
565
|
addClaudeCodePreToolUseHook();
|
|
566
|
+
addClaudeCodeExploreHook();
|
|
544
567
|
addClaudeCodeMemory();
|
|
545
568
|
addClaudeCodeSkill();
|
|
546
569
|
addClaudeCodeCliSkill();
|
|
@@ -777,6 +800,88 @@ function addClaudeCodePreToolUseHook() {
|
|
|
777
800
|
}
|
|
778
801
|
}
|
|
779
802
|
|
|
803
|
+
/**
|
|
804
|
+
* The niro PreToolUse hook command (matcher Grep|Glob|Read). Prose instructions (CLAUDE.md, the
|
|
805
|
+
* UserPromptSubmit hook, the niro skill) tell Claude to prefer niro tools for code exploration, but in
|
|
806
|
+
* practice that only sticks when a task is phrased as a discovery question — a task phrased as "fix X" or
|
|
807
|
+
* "add Y" skips straight to native search with no interruption. This hook is the deterministic backstop:
|
|
808
|
+
* once per (session, repo, branch), the first native Grep/Glob/Read call in a niro-indexed repo gets an
|
|
809
|
+
* advisory reminder to prefer niro's structural tools instead — regardless of how the task was phrased.
|
|
810
|
+
*
|
|
811
|
+
* Dependency-free (no jq): reads the PreToolUse JSON on stdin. Read supplies `file_path`; Grep/Glob supply
|
|
812
|
+
* `path` (often omitted, meaning cwd) — so this tries file_path, then path, then the hook's own `cwd`
|
|
813
|
+
* field, then falls back to $PWD. Walks up for a `.niro-project` marker (silent outside indexed repos)
|
|
814
|
+
* and dedupes via a marker file keyed by session_id + repo root + branch, same scheme as the Edit|Write
|
|
815
|
+
* temp-project hook but under the distinct `niro-explore-` prefix so the two hooks never collide.
|
|
816
|
+
*/
|
|
817
|
+
const NIRO_EXPLORE_COMMAND = [
|
|
818
|
+
'IN="$(cat)"',
|
|
819
|
+
// Read gives file_path; Grep/Glob give path (may be absent); fall back to cwd, then $PWD.
|
|
820
|
+
`f="$(printf '%s' "$IN" | grep -oE '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed -E 's/.*:[[:space:]]*"([^"]*)"/\\1/')"`,
|
|
821
|
+
`[ -z "$f" ] && f="$(printf '%s' "$IN" | grep -oE '"path"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed -E 's/.*:[[:space:]]*"([^"]*)"/\\1/')"`,
|
|
822
|
+
`[ -z "$f" ] && f="$(printf '%s' "$IN" | grep -oE '"cwd"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed -E 's/.*:[[:space:]]*"([^"]*)"/\\1/')"`,
|
|
823
|
+
'[ -z "$f" ] && f="$PWD"',
|
|
824
|
+
'd0="$f"; [ -d "$d0" ] || d0="$(dirname "$f")"',
|
|
825
|
+
'r="$(git -C "$d0" rev-parse --show-toplevel 2>/dev/null)"',
|
|
826
|
+
'[ -z "$r" ] && exit 0',
|
|
827
|
+
// only remind inside a niro-indexed tree
|
|
828
|
+
'd="$r"; ok=0; while [ -n "$d" ] && [ "$d" != "/" ]; do if [ -f "$d/.niro-project" ]; then ok=1; break; fi; d="$(dirname "$d")"; done',
|
|
829
|
+
'[ "$ok" = 0 ] && exit 0',
|
|
830
|
+
`s="$(printf '%s' "$IN" | grep -oE '"session_id"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed -E 's/.*:[[:space:]]*"([^"]*)"/\\1/')"`,
|
|
831
|
+
// Branch-aware dedup, same rationale as the Edit|Write hook: a stale answer from a different branch must not
|
|
832
|
+
// silence the reminder after a branch switch.
|
|
833
|
+
'b="$(git -C "$r" rev-parse --abbrev-ref HEAD 2>/dev/null)"',
|
|
834
|
+
`k="$(printf '%s\\n%s\\n%s' "$s" "$r" "$b" | cksum | cut -d' ' -f1)"`,
|
|
835
|
+
'm="${TMPDIR:-/tmp}/niro-explore-$k"',
|
|
836
|
+
'[ -f "$m" ] && exit 0',
|
|
837
|
+
'touch "$m"',
|
|
838
|
+
// Advisory context injection ONLY — no permissionDecision, so it never blocks the read/search.
|
|
839
|
+
`printf '%s' '{"hookSpecificOutput":{"hookEventName":"PreToolUse","additionalContext":"This is a niro-indexed repo. For code structure/behavior/call-chain/impact/reuse questions - including ones that come up mid-task while implementing or fixing something, not just standalone discovery questions - prefer niro MCP tools (get_source_code, code_grep, get_call_chain, get_blast_radius, get_impact_analysis, find_reusable_code, get_class_structure, etc.) over native Grep/Glob/Read. Fall back to native tools silently for out-of-scope questions (config files, docs, runtime state, non-code content). Shown once per repo per branch per session."}}'`,
|
|
840
|
+
].join('; ');
|
|
841
|
+
|
|
842
|
+
/**
|
|
843
|
+
* Adds the PreToolUse (Grep|Glob|Read) explore-first reminder hook to ~/.claude/settings.json. Idempotent:
|
|
844
|
+
* upgrades a stale niro entry in place, never touches a foreign PreToolUse hook on the same matcher
|
|
845
|
+
* (matched by the niro-explore- marker via isNiroExploreHook).
|
|
846
|
+
*/
|
|
847
|
+
function addClaudeCodeExploreHook() {
|
|
848
|
+
const settingsPath = path.join(process.env.HOME || "", ".claude", "settings.json");
|
|
849
|
+
let settings = {};
|
|
850
|
+
try {
|
|
851
|
+
if (fs.existsSync(settingsPath)) settings = JSON.parse(fs.readFileSync(settingsPath, "utf-8"));
|
|
852
|
+
} catch {
|
|
853
|
+
// Corrupt or missing — start fresh
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
if (!settings.hooks) settings.hooks = {};
|
|
857
|
+
if (!settings.hooks.PreToolUse) settings.hooks.PreToolUse = [];
|
|
858
|
+
|
|
859
|
+
const entry = { matcher: "Grep|Glob|Read", hooks: [{ type: "command", command: NIRO_EXPLORE_COMMAND }] };
|
|
860
|
+
const alreadyCurrent = settings.hooks.PreToolUse.some(
|
|
861
|
+
(h) => Array.isArray(h.hooks) && h.hooks.some((i) => i && i.command === NIRO_EXPLORE_COMMAND),
|
|
862
|
+
);
|
|
863
|
+
if (alreadyCurrent) {
|
|
864
|
+
console.log(" PreToolUse explore-first hook already up to date — skipping.\n");
|
|
865
|
+
return;
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
const hadStale = settings.hooks.PreToolUse.some(isNiroExploreHook);
|
|
869
|
+
settings.hooks.PreToolUse = settings.hooks.PreToolUse.filter((h) => !isNiroExploreHook(h));
|
|
870
|
+
settings.hooks.PreToolUse.push(entry);
|
|
871
|
+
|
|
872
|
+
try {
|
|
873
|
+
fs.mkdirSync(path.dirname(settingsPath), { recursive: true });
|
|
874
|
+
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
875
|
+
console.log(` PreToolUse explore-first hook ${hadStale ? "upgraded" : "added"} in ~/.claude/settings.json`);
|
|
876
|
+
console.log(" → Before the first native Grep/Glob/Read in a niro-indexed repo, Claude is reminded once/session/branch");
|
|
877
|
+
console.log(" to prefer niro tools — even mid-task, not just for standalone discovery questions.\n");
|
|
878
|
+
} catch (err) {
|
|
879
|
+
console.warn(` Could not write ~/.claude/settings.json: ${err.message}`);
|
|
880
|
+
console.warn(" Add manually to the PreToolUse array in ~/.claude/settings.json:\n");
|
|
881
|
+
console.warn(JSON.stringify(entry, null, 2) + "\n");
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
|
|
780
885
|
/** Body of the `niro` skill (long-form tool-routing playbook). */
|
|
781
886
|
const NIRO_SKILL = `---
|
|
782
887
|
name: niro-skill
|
|
@@ -791,6 +896,16 @@ code — structure, behavior, impact, data/event flows, semantics — prefer the
|
|
|
791
896
|
native grep/read. For anything outside the indexed code (config files, docs, runtime state),
|
|
792
897
|
use your native tools.
|
|
793
898
|
|
|
899
|
+
## Explore first — MUST FOLLOW
|
|
900
|
+
|
|
901
|
+
Before you run grep, find, glob, or open a file to hunt for something, check whether a Niro
|
|
902
|
+
tool answers it: \`code_grep\` for content search, \`resolve_fqn\` + \`get_source_code\` for a known
|
|
903
|
+
symbol, \`find_handler\` / \`find_api_endpoints\` for entry points. Use the connection tools
|
|
904
|
+
(\`get_call_chain\`, \`get_reverse_call_chain\`, \`get_blast_radius\`, \`get_impact_analysis\`,
|
|
905
|
+
\`get_service_topology\`) to understand how the code connects BEFORE you decide which file to
|
|
906
|
+
read or search next, instead of reading files to rebuild that picture by hand. Native search
|
|
907
|
+
stays the fallback for what Niro does not cover, and when the tools are unavailable.
|
|
908
|
+
|
|
794
909
|
\`project_id\` auto-resolves from a \`.niro-project\` file at the repo root — omit it. If there
|
|
795
910
|
is no such file, call \`list_projects\` and pass the chosen \`project_id\`.
|
|
796
911
|
|
|
@@ -908,6 +1023,7 @@ temporary index of your branch (\`niro new-temp-project\` to create, \`niro disc
|
|
|
908
1023
|
| Full path from A to B (prefer \`to_service\` for cross-service) | \`trace_execution_path\` |
|
|
909
1024
|
| HTTP endpoints a service exposes | \`find_api_endpoints\` |
|
|
910
1025
|
| Outbound HTTP calls a service makes | \`find_outbound_http_calls\` |
|
|
1026
|
+
| Service-to-service call map (who calls whom), as a Mermaid diagram | \`get_service_topology\` |
|
|
911
1027
|
| What handles an outgoing HTTP call / event | \`find_handler\` |
|
|
912
1028
|
|
|
913
1029
|
**Change safely**
|
|
@@ -1191,6 +1307,13 @@ alwaysApply: false
|
|
|
1191
1307
|
The niro MCP server exposes code-intelligence tools for this codebase. Prefer them over
|
|
1192
1308
|
grep/read for any question answerable from the indexed code.
|
|
1193
1309
|
|
|
1310
|
+
MUST FOLLOW — explore first: before you run grep, find, glob, or open a file to hunt for
|
|
1311
|
+
something, check whether a niro tool answers it (code_grep, resolve_fqn + get_source_code,
|
|
1312
|
+
find_handler, find_api_endpoints). Use the connection tools (get_call_chain,
|
|
1313
|
+
get_reverse_call_chain, get_blast_radius, get_impact_analysis, get_service_topology) to see
|
|
1314
|
+
how the code connects BEFORE deciding which file to read or search next. Native search is the
|
|
1315
|
+
fallback for what niro does not cover, and when the tools are unavailable.
|
|
1316
|
+
|
|
1194
1317
|
Availability self-check FIRST — if the niro tools are not present in this session, or the
|
|
1195
1318
|
repo is not indexed (no project resolves / a tool reports "not indexed"), fall back to
|
|
1196
1319
|
native tools silently and do not mention Niro.
|
|
@@ -1207,7 +1330,7 @@ Routing (most specific wins):
|
|
|
1207
1330
|
<!-- how_does_x_work temporarily disabled (hidden MCP tool) — re-add "how_does_x_work (forward flow) | " to the understand line below when re-enabled -->
|
|
1208
1331
|
- understand: explain_code (AI docs) | get_source_code | get_class_structure
|
|
1209
1332
|
- navigate: get_call_chain (callees) | get_reverse_call_chain (callers) | trace_execution_path (A to B)
|
|
1210
|
-
- HTTP: find_api_endpoints | find_outbound_http_calls | find_handler
|
|
1333
|
+
- HTTP: find_api_endpoints | find_outbound_http_calls | find_handler | get_service_topology (service-to-service map, Mermaid)
|
|
1211
1334
|
<!-- why_could_x_happen temporarily disabled (hidden MCP tool) — re-add "why_could_x_happen | " to the debug line below when re-enabled -->
|
|
1212
1335
|
- debug: find_known_issues | get_state_at_entry
|
|
1213
1336
|
- data & events: get_data_resource_usage | get_event_producers_and_handlers
|
|
@@ -1478,6 +1601,13 @@ Niro code-intelligence MCP tools are available for the current codebase. Prefer
|
|
|
1478
1601
|
grep/read for questions about structure, call chains, blast radius, impact, data flows, and
|
|
1479
1602
|
reuse. Before writing or adding any new code, use \`find_reusable_code\` first.
|
|
1480
1603
|
|
|
1604
|
+
MUST FOLLOW — explore first: before you run grep, find, glob, or open a file to hunt for
|
|
1605
|
+
something, check whether a niro tool answers it (\`code_grep\`, \`resolve_fqn\` +
|
|
1606
|
+
\`get_source_code\`, \`find_handler\`, \`find_api_endpoints\`). Use the connection tools
|
|
1607
|
+
(\`get_call_chain\`, \`get_reverse_call_chain\`, \`get_blast_radius\`, \`get_impact_analysis\`,
|
|
1608
|
+
\`get_service_topology\`) to see how the code connects BEFORE deciding which file to read or
|
|
1609
|
+
search next. Native search is the fallback for what niro does not cover.
|
|
1610
|
+
|
|
1481
1611
|
If the niro tools are not present in this session, or the repo is not indexed (no project
|
|
1482
1612
|
resolves), fall back to native tools silently — do not mention Niro's absence.
|
|
1483
1613
|
`;
|
|
@@ -1516,6 +1646,13 @@ Niro code-intelligence MCP tools are available for the current codebase. Prefer
|
|
|
1516
1646
|
grep/read for questions about structure, call chains, blast radius, impact, data flows, and
|
|
1517
1647
|
reuse. Before writing or adding any new code, use \`find_reusable_code\` first.
|
|
1518
1648
|
|
|
1649
|
+
MUST FOLLOW — explore first: before you run grep, find, glob, or open a file to hunt for
|
|
1650
|
+
something, check whether a niro tool answers it (\`code_grep\`, \`resolve_fqn\` +
|
|
1651
|
+
\`get_source_code\`, \`find_handler\`, \`find_api_endpoints\`). Use the connection tools
|
|
1652
|
+
(\`get_call_chain\`, \`get_reverse_call_chain\`, \`get_blast_radius\`, \`get_impact_analysis\`,
|
|
1653
|
+
\`get_service_topology\`) to see how the code connects BEFORE deciding which file to read or
|
|
1654
|
+
search next. Native search is the fallback for what niro does not cover.
|
|
1655
|
+
|
|
1519
1656
|
If the niro tools are not present in this session, or the repo is not indexed (no project
|
|
1520
1657
|
resolves), fall back to native tools silently — do not mention Niro's absence.
|
|
1521
1658
|
`;
|
|
@@ -1957,10 +2094,17 @@ module.exports = {
|
|
|
1957
2094
|
isNiroPostCompactHook,
|
|
1958
2095
|
isNiroUserPromptHook,
|
|
1959
2096
|
isNiroPreToolUseHook,
|
|
2097
|
+
isNiroExploreHook,
|
|
1960
2098
|
userHome,
|
|
1961
2099
|
// Exposed for content regression tests (e.g. the cross-project routing guidance).
|
|
1962
2100
|
NIRO_SKILL,
|
|
1963
2101
|
NIRO_CLI_SKILL,
|
|
2102
|
+
// Exposed for tests: the explore-first rule must reach EVERY client's always-on instruction surface.
|
|
2103
|
+
NIRO_EXPLORE_FIRST_SENTENCE,
|
|
2104
|
+
NIRO_CURSOR_RULE,
|
|
2105
|
+
NIRO_CLINE_RULE,
|
|
2106
|
+
NIRO_KIRO_STEERING,
|
|
2107
|
+
upsertNiroMarkerSection,
|
|
1964
2108
|
// Exposed for tests: URL resolution replaced the install-time prompt.
|
|
1965
2109
|
resolveMcpServerUrl,
|
|
1966
2110
|
SAAS_URL,
|
package/src/mcp/teardown.js
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
*
|
|
6
6
|
* `niro mcp uninstall` removes everything `niro mcp install` wrote, per editor:
|
|
7
7
|
* - the MCP server registration (claude/codex CLI, or the editor's JSON config)
|
|
8
|
-
* - the niro hooks in ~/.claude/settings.json (PostCompact + UserPromptSubmit + PreToolUse
|
|
8
|
+
* - the niro hooks in ~/.claude/settings.json (PostCompact + UserPromptSubmit + PreToolUse: both the
|
|
9
|
+
* Edit|Write temp-project reminder and the Grep|Glob|Read explore-first reminder)
|
|
9
10
|
* - the niro section in markdown config (CLAUDE.md / AGENTS.md / Windsurf rules)
|
|
10
11
|
* - the generated skills (~/.claude/skills, the shared ~/.agents/skills)
|
|
11
12
|
* - Cursor's "niro:*" allowlist entry and project rule
|
|
@@ -38,6 +39,7 @@ const {
|
|
|
38
39
|
isNiroPostCompactHook,
|
|
39
40
|
isNiroUserPromptHook,
|
|
40
41
|
isNiroPreToolUseHook,
|
|
42
|
+
isNiroExploreHook,
|
|
41
43
|
userHome,
|
|
42
44
|
} = require("./setup");
|
|
43
45
|
|
|
@@ -122,10 +124,10 @@ function removeMarkerSectionBounded(content, marker) {
|
|
|
122
124
|
}
|
|
123
125
|
|
|
124
126
|
/**
|
|
125
|
-
* Strip niro's PostCompact
|
|
126
|
-
* settings object (mutates and returns it). Uses the same matchers
|
|
127
|
-
* arrays / an empty `hooks` object are pruned so the file stays tidy. Other hooks
|
|
128
|
-
* untouched. Returns { settings, removed } where `removed` is the count deleted.
|
|
127
|
+
* Strip niro's PostCompact, UserPromptSubmit, and PreToolUse (temp-project + explore-first) hook
|
|
128
|
+
* entries from a parsed Claude Code settings object (mutates and returns it). Uses the same matchers
|
|
129
|
+
* install uses. Empty arrays / an empty `hooks` object are pruned so the file stays tidy. Other hooks
|
|
130
|
+
* are untouched. Returns { settings, removed } where `removed` is the count deleted.
|
|
129
131
|
*/
|
|
130
132
|
function filterNiroHooks(settings) {
|
|
131
133
|
let removed = 0;
|
|
@@ -148,7 +150,7 @@ function filterNiroHooks(settings) {
|
|
|
148
150
|
}
|
|
149
151
|
if (Array.isArray(hooks.PreToolUse)) {
|
|
150
152
|
const before = hooks.PreToolUse.length;
|
|
151
|
-
hooks.PreToolUse = hooks.PreToolUse.filter((h) => !isNiroPreToolUseHook(h));
|
|
153
|
+
hooks.PreToolUse = hooks.PreToolUse.filter((h) => !isNiroPreToolUseHook(h) && !isNiroExploreHook(h));
|
|
152
154
|
removed += before - hooks.PreToolUse.length;
|
|
153
155
|
if (hooks.PreToolUse.length === 0) delete hooks.PreToolUse;
|
|
154
156
|
}
|