@nano-step/skill-manager 5.5.3 → 5.6.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/dist/index.js +7 -5
- package/dist/installer.d.ts +2 -2
- package/dist/installer.js +17 -14
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +1 -1
- package/package.json +1 -1
- package/private-catalog.json +2 -2
- package/skills/nano-brain/AGENTS_SNIPPET.md +16 -1
- package/skills/nano-brain/SKILL.md +61 -19
- package/skills/nano-brain/references/code-intelligence.md +57 -0
- package/skills/nano-brain/skill.json +6 -3
- package/skills/skill-management/references/tool-categories.md +58 -0
package/dist/index.js
CHANGED
|
@@ -123,6 +123,7 @@ async function run() {
|
|
|
123
123
|
.command("install [name]")
|
|
124
124
|
.description("Install a skill from the catalog")
|
|
125
125
|
.option("--all", "Install all available skills")
|
|
126
|
+
.option("--force", "Force reinstall even if same version is installed")
|
|
126
127
|
.action(async (name, options) => {
|
|
127
128
|
const paths = await (0, utils_1.detectOpenCodePaths)();
|
|
128
129
|
await (0, state_1.migrateV4State)(paths.configDir, paths.stateFilePath, paths.skillsDir);
|
|
@@ -135,11 +136,11 @@ async function run() {
|
|
|
135
136
|
return;
|
|
136
137
|
}
|
|
137
138
|
for (const entry of catalog) {
|
|
138
|
-
await (0, installer_1.installSkill)(entry.manifest.name, paths);
|
|
139
|
+
await (0, installer_1.installSkill)(entry.manifest.name, paths, options.force);
|
|
139
140
|
}
|
|
140
141
|
}
|
|
141
142
|
else if (name) {
|
|
142
|
-
await (0, installer_1.installSkill)(name, paths);
|
|
143
|
+
await (0, installer_1.installSkill)(name, paths, options.force);
|
|
143
144
|
}
|
|
144
145
|
else {
|
|
145
146
|
console.error(chalk_1.default.red("Please specify a skill name or use --all."));
|
|
@@ -158,11 +159,12 @@ async function run() {
|
|
|
158
159
|
program
|
|
159
160
|
.command("update [name]")
|
|
160
161
|
.description("Update installed skill(s) to latest catalog version")
|
|
161
|
-
.
|
|
162
|
+
.option("--force", "Force update even if same version is installed")
|
|
163
|
+
.action(async (name, options) => {
|
|
162
164
|
const paths = await (0, utils_1.detectOpenCodePaths)();
|
|
163
165
|
await (0, state_1.migrateV4State)(paths.configDir, paths.stateFilePath, paths.skillsDir);
|
|
164
166
|
if (name) {
|
|
165
|
-
await (0, installer_1.updateSkill)(name, paths);
|
|
167
|
+
await (0, installer_1.updateSkill)(name, paths, options.force);
|
|
166
168
|
}
|
|
167
169
|
else {
|
|
168
170
|
const state = await (0, state_1.loadState)(paths.stateFilePath);
|
|
@@ -172,7 +174,7 @@ async function run() {
|
|
|
172
174
|
return;
|
|
173
175
|
}
|
|
174
176
|
for (const skillName of installed) {
|
|
175
|
-
await (0, installer_1.updateSkill)(skillName, paths);
|
|
177
|
+
await (0, installer_1.updateSkill)(skillName, paths, options.force);
|
|
176
178
|
}
|
|
177
179
|
}
|
|
178
180
|
});
|
package/dist/installer.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { OpenCodePaths } from "./utils";
|
|
2
|
-
export declare function installSkill(name: string, paths: OpenCodePaths): Promise<void>;
|
|
2
|
+
export declare function installSkill(name: string, paths: OpenCodePaths, force?: boolean): Promise<void>;
|
|
3
3
|
export declare function removeSkill(name: string, paths: OpenCodePaths): Promise<void>;
|
|
4
|
-
export declare function updateSkill(name: string, paths: OpenCodePaths): Promise<void>;
|
|
4
|
+
export declare function updateSkill(name: string, paths: OpenCodePaths, force?: boolean): Promise<void>;
|
package/dist/installer.js
CHANGED
|
@@ -14,11 +14,11 @@ const registry_1 = require("./registry");
|
|
|
14
14
|
const state_1 = require("./state");
|
|
15
15
|
const config_1 = require("./config");
|
|
16
16
|
const remote_registry_1 = require("./remote-registry");
|
|
17
|
-
async function installFromDir(manifest, sourceDir, paths, source) {
|
|
17
|
+
async function installFromDir(manifest, sourceDir, paths, source, force) {
|
|
18
18
|
const state = await (0, state_1.loadState)(paths.stateFilePath);
|
|
19
19
|
const existing = state.skills[manifest.name];
|
|
20
|
-
if (existing && existing.version === manifest.version) {
|
|
21
|
-
console.log(chalk_1.default.yellow(`Skill "${manifest.name}" is already installed at v${manifest.version}.`));
|
|
20
|
+
if (existing && existing.version === manifest.version && !force) {
|
|
21
|
+
console.log(chalk_1.default.yellow(`Skill "${manifest.name}" is already installed at v${manifest.version}. Use --force to reinstall.`));
|
|
22
22
|
return;
|
|
23
23
|
}
|
|
24
24
|
await (0, utils_1.ensureDirExists)(paths.skillsDir);
|
|
@@ -34,13 +34,14 @@ async function installFromDir(manifest, sourceDir, paths, source) {
|
|
|
34
34
|
};
|
|
35
35
|
await (0, state_1.saveState)(paths.stateFilePath, state);
|
|
36
36
|
const sourceLabel = source === "private" ? chalk_1.default.magenta(" (private)") : "";
|
|
37
|
-
|
|
37
|
+
const forceLabel = force && existing ? " (forced)" : "";
|
|
38
|
+
console.log(chalk_1.default.green(`✓ Installed ${manifest.name} v${manifest.version}${sourceLabel}${forceLabel}`));
|
|
38
39
|
}
|
|
39
|
-
async function installSkill(name, paths) {
|
|
40
|
+
async function installSkill(name, paths, force) {
|
|
40
41
|
const localManifest = await (0, registry_1.getSkillManifest)(paths.packageSkillsDir, name);
|
|
41
42
|
if (localManifest) {
|
|
42
43
|
const packageSkillDir = path_1.default.join(paths.packageSkillsDir, name);
|
|
43
|
-
await installFromDir(localManifest, packageSkillDir, paths, "public");
|
|
44
|
+
await installFromDir(localManifest, packageSkillDir, paths, "public", force);
|
|
44
45
|
return;
|
|
45
46
|
}
|
|
46
47
|
const remoteManifest = await (0, remote_registry_1.getRemoteSkillManifest)(name);
|
|
@@ -48,7 +49,7 @@ async function installSkill(name, paths) {
|
|
|
48
49
|
const tempDir = await (0, remote_registry_1.downloadSkillToTemp)(name);
|
|
49
50
|
if (tempDir) {
|
|
50
51
|
try {
|
|
51
|
-
await installFromDir(remoteManifest, tempDir, paths, "private");
|
|
52
|
+
await installFromDir(remoteManifest, tempDir, paths, "private", force);
|
|
52
53
|
}
|
|
53
54
|
finally {
|
|
54
55
|
await fs_extra_1.default.remove(tempDir);
|
|
@@ -95,7 +96,7 @@ async function removeSkill(name, paths) {
|
|
|
95
96
|
await (0, state_1.saveState)(paths.stateFilePath, state);
|
|
96
97
|
console.log(chalk_1.default.green(`✓ Removed ${name}`));
|
|
97
98
|
}
|
|
98
|
-
async function updateSkill(name, paths) {
|
|
99
|
+
async function updateSkill(name, paths, force) {
|
|
99
100
|
const state = await (0, state_1.loadState)(paths.stateFilePath);
|
|
100
101
|
if (!state.skills[name]) {
|
|
101
102
|
console.error(chalk_1.default.red(`Skill "${name}" is not installed. Use 'skill-manager install ${name}' first.`));
|
|
@@ -104,8 +105,8 @@ async function updateSkill(name, paths) {
|
|
|
104
105
|
const installed = state.skills[name];
|
|
105
106
|
const localManifest = await (0, registry_1.getSkillManifest)(paths.packageSkillsDir, name);
|
|
106
107
|
if (localManifest) {
|
|
107
|
-
if (installed.version === localManifest.version) {
|
|
108
|
-
console.log(chalk_1.default.yellow(`Skill "${name}" is already at v${localManifest.version} (up to date).`));
|
|
108
|
+
if (installed.version === localManifest.version && !force) {
|
|
109
|
+
console.log(chalk_1.default.yellow(`Skill "${name}" is already at v${localManifest.version} (up to date). Use --force to override.`));
|
|
109
110
|
return;
|
|
110
111
|
}
|
|
111
112
|
const packageSkillDir = path_1.default.join(paths.packageSkillsDir, name);
|
|
@@ -120,13 +121,14 @@ async function updateSkill(name, paths) {
|
|
|
120
121
|
location: installed.location,
|
|
121
122
|
};
|
|
122
123
|
await (0, state_1.saveState)(paths.stateFilePath, state);
|
|
123
|
-
|
|
124
|
+
const forceLabel = force && installed.version === localManifest.version ? " (forced)" : "";
|
|
125
|
+
console.log(chalk_1.default.green(`✓ Updated ${name} from v${installed.version} to v${localManifest.version}${forceLabel}`));
|
|
124
126
|
return;
|
|
125
127
|
}
|
|
126
128
|
const remoteManifest = await (0, remote_registry_1.getRemoteSkillManifest)(name);
|
|
127
129
|
if (remoteManifest) {
|
|
128
|
-
if (installed.version === remoteManifest.version) {
|
|
129
|
-
console.log(chalk_1.default.yellow(`Skill "${name}" is already at v${remoteManifest.version} (up to date).`));
|
|
130
|
+
if (installed.version === remoteManifest.version && !force) {
|
|
131
|
+
console.log(chalk_1.default.yellow(`Skill "${name}" is already at v${remoteManifest.version} (up to date). Use --force to override.`));
|
|
130
132
|
return;
|
|
131
133
|
}
|
|
132
134
|
const tempDir = await (0, remote_registry_1.downloadSkillToTemp)(name);
|
|
@@ -143,7 +145,8 @@ async function updateSkill(name, paths) {
|
|
|
143
145
|
location: installed.location,
|
|
144
146
|
};
|
|
145
147
|
await (0, state_1.saveState)(paths.stateFilePath, state);
|
|
146
|
-
|
|
148
|
+
const remoteForceLabel = force && installed.version === remoteManifest.version ? " (forced)" : "";
|
|
149
|
+
console.log(chalk_1.default.green(`✓ Updated ${name} from v${installed.version} to v${remoteManifest.version} (private)${remoteForceLabel}`));
|
|
147
150
|
}
|
|
148
151
|
finally {
|
|
149
152
|
await fs_extra_1.default.remove(tempDir);
|
package/dist/utils.d.ts
CHANGED
package/dist/utils.js
CHANGED
|
@@ -13,7 +13,7 @@ exports.writeText = writeText;
|
|
|
13
13
|
const path_1 = __importDefault(require("path"));
|
|
14
14
|
const os_1 = __importDefault(require("os"));
|
|
15
15
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
16
|
-
exports.MANAGER_VERSION = "5.
|
|
16
|
+
exports.MANAGER_VERSION = "5.6.0";
|
|
17
17
|
async function detectOpenCodePaths() {
|
|
18
18
|
const homeConfig = path_1.default.join(os_1.default.homedir(), ".config", "opencode");
|
|
19
19
|
const cwd = process.cwd();
|
package/package.json
CHANGED
package/private-catalog.json
CHANGED
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
},
|
|
17
17
|
{
|
|
18
18
|
"name": "pr-code-reviewer",
|
|
19
|
-
"version": "
|
|
20
|
-
"description": "
|
|
19
|
+
"version": "7.1.0",
|
|
20
|
+
"description": "PR review with MANDATORY cross-repo consumer search, nano-brain code intelligence, and better-context structural analysis. READ-ONLY — no comments, pushes, or code fixes."
|
|
21
21
|
},
|
|
22
22
|
{
|
|
23
23
|
"name": "rri-t-testing",
|
|
@@ -37,10 +37,25 @@ memory_write("## Summary\n- Decision: ...\n- Why: ...\n- Files: ...")
|
|
|
37
37
|
# File: ~/.nano-brain/memory/YYYY-MM-DD-summary.md
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
-
###
|
|
40
|
+
### Code Intelligence Tools
|
|
41
|
+
|
|
42
|
+
nano-brain also provides symbol-level code analysis (requires `memory_index_codebase` first):
|
|
43
|
+
|
|
44
|
+
| I want to... | MCP Tool |
|
|
45
|
+
|--------------|----------|
|
|
46
|
+
| Understand a symbol's callers/callees/flows | `code_context(name="functionName")` |
|
|
47
|
+
| Assess risk of changing a symbol | `code_impact(target="className", direction="upstream")` |
|
|
48
|
+
| Map my git changes to affected symbols | `code_detect_changes(scope="all")` |
|
|
49
|
+
|
|
50
|
+
Use `file_path` parameter to disambiguate when multiple symbols share the same name.
|
|
51
|
+
|
|
52
|
+
### When to Search Memory vs Codebase vs Code Intelligence
|
|
41
53
|
|
|
42
54
|
- **"Have we done this before?"** → `memory_query` or `npx nano-brain query` (searches past sessions)
|
|
43
55
|
- **"Where is this in the code?"** → grep / ast-grep (searches current files)
|
|
44
56
|
- **"How does this concept work here?"** → Both (memory for past context + grep for current code)
|
|
57
|
+
- **"What calls this function?"** → `code_context` (symbol graph relationships)
|
|
58
|
+
- **"What breaks if I change X?"** → `code_impact` (dependency + flow analysis)
|
|
59
|
+
- **"What did my changes affect?"** → `code_detect_changes` (git diff to symbol mapping)
|
|
45
60
|
|
|
46
61
|
<!-- OPENCODE-MEMORY:END -->
|
|
@@ -1,14 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: nano-brain
|
|
3
|
+
description: Provide persistent memory and code intelligence for AI coding agents; use for hybrid search, cross-session recall, symbol analysis, and impact checks.
|
|
4
|
+
compatibility: OpenCode
|
|
5
|
+
metadata:
|
|
6
|
+
author: nano-step
|
|
7
|
+
version: 2.1.0
|
|
8
|
+
---
|
|
9
|
+
|
|
1
10
|
# nano-brain
|
|
2
11
|
|
|
3
|
-
|
|
12
|
+
Provide persistent memory for AI coding agents. Run hybrid search (BM25 + semantic + LLM reranking) across past sessions, codebase, notes, and daily logs.
|
|
4
13
|
|
|
5
14
|
## Slash Commands
|
|
6
15
|
|
|
7
16
|
| Command | When |
|
|
8
17
|
|---------|------|
|
|
9
|
-
| `/nano-brain-init` |
|
|
10
|
-
| `/nano-brain-status` |
|
|
11
|
-
| `/nano-brain-reindex` |
|
|
18
|
+
| `/nano-brain-init` | Run first-time workspace setup |
|
|
19
|
+
| `/nano-brain-status` | Check health, embedding progress |
|
|
20
|
+
| `/nano-brain-reindex` | Run after branch switch, pull, or major changes |
|
|
12
21
|
|
|
13
22
|
## When to Use Memory
|
|
14
23
|
|
|
@@ -17,25 +26,44 @@ Persistent memory for AI coding agents. Hybrid search (BM25 + semantic + LLM rer
|
|
|
17
26
|
|
|
18
27
|
## Access Methods: MCP vs CLI
|
|
19
28
|
|
|
20
|
-
nano-brain
|
|
29
|
+
Access nano-brain via **MCP tools** (when the MCP server is configured) or **CLI** (always available).
|
|
21
30
|
|
|
22
31
|
**Detection:** Try calling `memory_status` MCP tool first. If it fails with "MCP server not found", fall back to CLI.
|
|
23
32
|
|
|
24
33
|
### MCP Tools (preferred when available)
|
|
25
34
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
- **`memory_search`** — recall a specific error string or function name from past sessions.
|
|
36
|
+
Example: `skill_mcp(mcp_name="nano-brain", tool_name="memory_search", arguments={ query: "ECONNREFUSED redis timeout" })`
|
|
37
|
+
- **`memory_vsearch`** — explore a fuzzy concept when you do not know the exact wording.
|
|
38
|
+
Example: `memory_vsearch("caching strategy for user sessions")`
|
|
39
|
+
- **`memory_query`** — get the best hybrid answer for a complex, multi-part question.
|
|
40
|
+
Example: `memory_query("how did we handle rate limiting in the payment service")`
|
|
41
|
+
- **`memory_get`** — pull one known doc by ID or path.
|
|
42
|
+
Example: `memory_get(id="#a1b2c3")`
|
|
43
|
+
- **`memory_multi_get`** — fetch a set of known docs by pattern.
|
|
44
|
+
Example: `memory_multi_get(pattern="decisions/2025-*/auth-*.md")`
|
|
45
|
+
- **`memory_write`** — log a decision or insight for future recall.
|
|
46
|
+
Example: `memory_write("## Decision: Use Redis Streams over Bull queues\n- Why: retries need ordered replay")`
|
|
47
|
+
- **`memory_set`** — store a keyed note you plan to update over time.
|
|
48
|
+
Example: `memory_set(key="payments-rate-limit", content="429s come from gateway, not nginx")`
|
|
49
|
+
- **`memory_delete`** — remove a stale keyed note that is no longer accurate.
|
|
50
|
+
Example: `memory_delete(key="legacy-redis-metrics")`
|
|
51
|
+
- **`memory_keys`** — list all keyed notes to see what is tracked.
|
|
52
|
+
Example: `memory_keys()`
|
|
53
|
+
- **`memory_status`** — verify MCP health or embedding progress before searching.
|
|
54
|
+
Example: `memory_status()`
|
|
55
|
+
- **`memory_index_codebase`** — index source files before using code intelligence tools.
|
|
56
|
+
Example: `memory_index_codebase(root="/Users/tamlh/workspaces/self/AI/Tools")`
|
|
57
|
+
- **`memory_update`** — refresh all indexes after big changes or repo syncs.
|
|
58
|
+
Example: `memory_update()`
|
|
59
|
+
- **`memory_focus`** — inspect dependencies for a specific file you are editing.
|
|
60
|
+
Example: `memory_focus(filePath="/src/api/routes/auth.ts")`
|
|
61
|
+
- **`memory_graph_stats`** — check dependency graph size and coverage.
|
|
62
|
+
Example: `memory_graph_stats()`
|
|
63
|
+
- **`memory_symbols`** — find where cross-repo infrastructure symbols are defined or used.
|
|
64
|
+
Example: `memory_symbols(type="redis_key", pattern="session:*")`
|
|
65
|
+
- **`memory_impact`** — see which repos or services are affected by a symbol.
|
|
66
|
+
Example: `memory_impact(type="mysql_table", pattern="orders")`
|
|
39
67
|
|
|
40
68
|
### CLI Fallback (always available)
|
|
41
69
|
|
|
@@ -69,9 +97,23 @@ Works with both MCP and CLI (`-c` flag):
|
|
|
69
97
|
- `memory` — curated notes only
|
|
70
98
|
- Omit — search everything (recommended)
|
|
71
99
|
|
|
100
|
+
## Code Intelligence Tools (MCP)
|
|
101
|
+
|
|
102
|
+
Use symbol-level analysis powered by Tree-sitter AST parsing. Require codebase indexing.
|
|
103
|
+
|
|
104
|
+
- **`code_context`** — trace callers, callees, and flows around a symbol.
|
|
105
|
+
Example: `code_context(name="processPayment")`
|
|
106
|
+
- **`code_impact`** — evaluate upstream or downstream risk before refactors.
|
|
107
|
+
Example: `code_impact(target="DatabaseClient", direction="upstream")`
|
|
108
|
+
- **`code_detect_changes`** — map current git diffs to symbols and flows.
|
|
109
|
+
Example: `code_detect_changes(scope="all")`
|
|
110
|
+
|
|
111
|
+
**Details and examples:** `references/code-intelligence.md`
|
|
112
|
+
|
|
72
113
|
## Memory vs Native Tools
|
|
73
114
|
|
|
74
115
|
Memory excels at **recall and semantics** — past sessions, conceptual search, cross-project knowledge.
|
|
75
116
|
Native tools (grep, ast-grep, glob) excel at **precise code patterns** — exact matches, AST structure.
|
|
117
|
+
Code intelligence tools excel at **structural relationships** — call graphs, impact analysis, flow detection.
|
|
76
118
|
|
|
77
|
-
**They are complementary.** Use
|
|
119
|
+
**They are complementary.** Use all three.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: nano-brain code intelligence
|
|
3
|
+
description: Use MCP code_context, code_impact, and code_detect_changes for symbol-level analysis, impact checks, and diff mapping.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Code Intelligence (nano-brain)
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Run code intelligence when symbol relationships, impact analysis, or diff-to-symbol mapping is needed. Ensure indexing is done with `memory_index_codebase` before using these tools.
|
|
11
|
+
|
|
12
|
+
## code_context — 360-degree symbol view
|
|
13
|
+
|
|
14
|
+
Return callers, callees, cluster membership, execution flows, and infrastructure connections for any function/class/method.
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
skill_mcp(mcp_name="nano-brain", tool_name="code_context", arguments={"name": "handleRequest"})
|
|
18
|
+
skill_mcp(mcp_name="nano-brain", tool_name="code_context", arguments={"name": "helper", "file_path": "/src/utils.ts"})
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Use `file_path` to disambiguate when multiple symbols share the same name.
|
|
22
|
+
|
|
23
|
+
## code_impact — dependency analysis
|
|
24
|
+
|
|
25
|
+
Traverse the symbol graph to find affected symbols and flows. Return a risk level (LOW/MEDIUM/HIGH/CRITICAL).
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
skill_mcp(mcp_name="nano-brain", tool_name="code_impact", arguments={"target": "DatabaseClient", "direction": "upstream"})
|
|
29
|
+
skill_mcp(mcp_name="nano-brain", tool_name="code_impact", arguments={"target": "processOrder", "direction": "downstream", "max_depth": 3})
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
- `upstream` = "who calls this?" (callers, consumers)
|
|
33
|
+
- `downstream` = "what does this call?" (callees, dependencies)
|
|
34
|
+
|
|
35
|
+
## code_detect_changes — git diff to symbol mapping
|
|
36
|
+
|
|
37
|
+
Map current git changes to affected symbols and execution flows.
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
skill_mcp(mcp_name="nano-brain", tool_name="code_detect_changes", arguments={"scope": "staged"})
|
|
41
|
+
skill_mcp(mcp_name="nano-brain", tool_name="code_detect_changes", arguments={"scope": "all"})
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Scopes: `unstaged`, `staged`, `all` (default).
|
|
45
|
+
|
|
46
|
+
## When to Use Code Intelligence vs Memory vs Native Tools
|
|
47
|
+
|
|
48
|
+
| Question | Tool |
|
|
49
|
+
|----------|------|
|
|
50
|
+
| "What calls function X?" | `code_context` |
|
|
51
|
+
| "What breaks if I change X?" | `code_impact` |
|
|
52
|
+
| "What did I change and what's affected?" | `code_detect_changes` |
|
|
53
|
+
| "Have we done this before?" | `memory_query` |
|
|
54
|
+
| "Find exact string in code" | grep / ast-grep |
|
|
55
|
+
| "How does auth work conceptually?" | `memory_vsearch` |
|
|
56
|
+
|
|
57
|
+
Code intelligence requires indexing. Run `memory_index_codebase` first if the workspace has not been indexed.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nano-brain",
|
|
3
|
-
"version": "1.0
|
|
4
|
-
"description": "Persistent memory for AI coding agents. Hybrid search
|
|
3
|
+
"version": "2.1.0",
|
|
4
|
+
"description": "Persistent memory and code intelligence for AI coding agents. Hybrid search, cross-session recall, symbol analysis, and impact checks.",
|
|
5
5
|
"compatibility": "OpenCode",
|
|
6
6
|
"agent": null,
|
|
7
7
|
"commands": [],
|
|
@@ -10,6 +10,9 @@
|
|
|
10
10
|
"persistence",
|
|
11
11
|
"search",
|
|
12
12
|
"context",
|
|
13
|
-
"sessions"
|
|
13
|
+
"sessions",
|
|
14
|
+
"code-intelligence",
|
|
15
|
+
"symbol-analysis",
|
|
16
|
+
"impact-analysis"
|
|
14
17
|
]
|
|
15
18
|
}
|
|
@@ -145,6 +145,58 @@ Notes:
|
|
|
145
145
|
- Tools require a page context; select or create a page first.
|
|
146
146
|
- Prefer take_snapshot for element discovery before click/hover/drag.
|
|
147
147
|
|
|
148
|
+
## Memory & Knowledge Category (Example)
|
|
149
|
+
|
|
150
|
+
Category name: Memory & Knowledge
|
|
151
|
+
Keywords: memory, search, recall, context, session, codebase, knowledge, symbol, impact, dependency, graph, focus
|
|
152
|
+
Description: Persistent memory, hybrid search, code intelligence, and cross-repo symbol analysis via nano-brain.
|
|
153
|
+
|
|
154
|
+
Example tools that might appear in this category:
|
|
155
|
+
- memory_search
|
|
156
|
+
- BM25 full-text keyword search across indexed documents.
|
|
157
|
+
- memory_vsearch
|
|
158
|
+
- Semantic vector search using embeddings.
|
|
159
|
+
- memory_query
|
|
160
|
+
- Full hybrid search with query expansion, RRF fusion, and LLM reranking.
|
|
161
|
+
- memory_get
|
|
162
|
+
- Retrieve a document by path or docid.
|
|
163
|
+
- memory_multi_get
|
|
164
|
+
- Batch retrieve documents by glob pattern or comma-separated list.
|
|
165
|
+
- memory_write
|
|
166
|
+
- Write content to daily log with workspace context.
|
|
167
|
+
- memory_set
|
|
168
|
+
- Set/update a keyed memory (overwrites previous value).
|
|
169
|
+
- memory_delete
|
|
170
|
+
- Delete a keyed memory.
|
|
171
|
+
- memory_keys
|
|
172
|
+
- List all keyed memories.
|
|
173
|
+
- memory_status
|
|
174
|
+
- Show index health, collection info, and model status.
|
|
175
|
+
- memory_index_codebase
|
|
176
|
+
- Index codebase files in the current workspace.
|
|
177
|
+
- memory_update
|
|
178
|
+
- Trigger immediate reindex of all collections.
|
|
179
|
+
- memory_focus
|
|
180
|
+
- Get dependency graph context for a specific file.
|
|
181
|
+
- memory_graph_stats
|
|
182
|
+
- Get statistics about the file dependency graph.
|
|
183
|
+
- memory_symbols
|
|
184
|
+
- Query cross-repo symbols (Redis keys, PubSub channels, MySQL tables, API endpoints, HTTP calls, Bull queues).
|
|
185
|
+
- memory_impact
|
|
186
|
+
- Analyze cross-repo impact of a symbol (writers vs readers, publishers vs subscribers).
|
|
187
|
+
- code_context
|
|
188
|
+
- 360-degree view of a code symbol — callers, callees, cluster, flows, infrastructure connections.
|
|
189
|
+
- code_impact
|
|
190
|
+
- Analyze impact of changing a symbol — upstream/downstream dependencies, affected flows, risk level.
|
|
191
|
+
- code_detect_changes
|
|
192
|
+
- Detect changed symbols and affected flows from git diff.
|
|
193
|
+
|
|
194
|
+
Notes:
|
|
195
|
+
- Memory tools require nano-brain MCP server to be configured.
|
|
196
|
+
- Code intelligence tools require prior indexing via memory_index_codebase.
|
|
197
|
+
- Use memory_query for best quality results (combines BM25 + vector + reranking).
|
|
198
|
+
- Use memory_search for exact keyword matches, memory_vsearch for conceptual search.
|
|
199
|
+
|
|
148
200
|
## GitHub Operations Category (Example)
|
|
149
201
|
|
|
150
202
|
Category name: GitHub Operations
|
|
@@ -220,13 +272,18 @@ Example tools that might appear in this category:
|
|
|
220
272
|
## Category Boundary Examples
|
|
221
273
|
Use these to avoid misclassification:
|
|
222
274
|
- "take a screenshot" -> Browser Automation
|
|
275
|
+
- "recall past decisions" -> Memory & Knowledge
|
|
223
276
|
- "list pull requests" -> GitHub Operations
|
|
224
277
|
- "list graphql queries" -> GraphQL Introspection
|
|
225
278
|
- "find docs for lodash" -> Documentation Lookup
|
|
279
|
+
- "what calls this function" -> Memory & Knowledge
|
|
280
|
+
- "search past sessions" -> Memory & Knowledge
|
|
226
281
|
|
|
227
282
|
## Common Intent Phrases by Category
|
|
228
283
|
Browser intents:
|
|
229
284
|
- "click", "hover", "fill form", "upload file", "take snapshot"
|
|
285
|
+
Memory intents:
|
|
286
|
+
- "recall", "remember", "past session", "what did we do", "search memory", "save decision", "code context", "impact analysis", "what calls", "dependency graph"
|
|
230
287
|
GitHub intents:
|
|
231
288
|
- "get PR", "list issues", "search repo", "read file"
|
|
232
289
|
GraphQL intents:
|
|
@@ -242,6 +299,7 @@ Docs intents:
|
|
|
242
299
|
|
|
243
300
|
## Category Ownership Notes (Semantic Only)
|
|
244
301
|
- Browser Automation: runtime web UI interaction and diagnostics.
|
|
302
|
+
- Memory & Knowledge: persistent cross-session memory, hybrid search, code intelligence, and cross-repo symbol analysis.
|
|
245
303
|
- GitHub Operations: repository metadata and collaboration artifacts.
|
|
246
304
|
- GraphQL Introspection: schema discovery and field metadata only.
|
|
247
305
|
- Documentation Lookup: documentation discovery and lookup.
|