@nano-step/skill-manager 5.5.3 → 5.6.1
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 -10
- 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/rri-t-testing/SKILL.md +224 -0
- package/skills/rri-t-testing/assets/rri-t-coverage-dashboard.md +138 -0
- package/skills/rri-t-testing/assets/rri-t-memory-protocol.md +271 -0
- package/skills/rri-t-testing/assets/rri-t-persona-interview.md +249 -0
- package/skills/rri-t-testing/assets/rri-t-quality-scorecard.md +122 -0
- package/skills/rri-t-testing/assets/rri-t-risk-matrix.md +87 -0
- package/skills/rri-t-testing/assets/rri-t-stress-matrix.md +100 -0
- package/skills/rri-t-testing/assets/rri-t-test-case.md +181 -0
- package/skills/rri-t-testing/assets/rri-t-testability-gate.md +131 -0
- package/skills/rri-t-testing/assets/rri-t-traceability-matrix.md +105 -0
- package/skills/rri-t-testing/skill.json +9 -0
- 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.1";
|
|
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",
|
|
@@ -19,15 +19,6 @@ nano-brain supports two access methods. Try MCP first; if unavailable, use CLI.
|
|
|
19
19
|
|
|
20
20
|
### Session Workflow
|
|
21
21
|
|
|
22
|
-
**Start of session:** Check memory for relevant past context before exploring the codebase.
|
|
23
|
-
```
|
|
24
|
-
# MCP (if available):
|
|
25
|
-
memory_query("what have we done regarding {current task topic}")
|
|
26
|
-
|
|
27
|
-
# CLI fallback:
|
|
28
|
-
npx nano-brain query "what have we done regarding {current task topic}"
|
|
29
|
-
```
|
|
30
|
-
|
|
31
22
|
**End of session:** Save key decisions, patterns discovered, and debugging insights.
|
|
32
23
|
```
|
|
33
24
|
# MCP (if available):
|
|
@@ -37,10 +28,25 @@ memory_write("## Summary\n- Decision: ...\n- Why: ...\n- Files: ...")
|
|
|
37
28
|
# File: ~/.nano-brain/memory/YYYY-MM-DD-summary.md
|
|
38
29
|
```
|
|
39
30
|
|
|
40
|
-
###
|
|
31
|
+
### Code Intelligence Tools
|
|
32
|
+
|
|
33
|
+
nano-brain also provides symbol-level code analysis (requires `memory_index_codebase` first):
|
|
34
|
+
|
|
35
|
+
| I want to... | MCP Tool |
|
|
36
|
+
|--------------|----------|
|
|
37
|
+
| Understand a symbol's callers/callees/flows | `code_context(name="functionName")` |
|
|
38
|
+
| Assess risk of changing a symbol | `code_impact(target="className", direction="upstream")` |
|
|
39
|
+
| Map my git changes to affected symbols | `code_detect_changes(scope="all")` |
|
|
40
|
+
|
|
41
|
+
Use `file_path` parameter to disambiguate when multiple symbols share the same name.
|
|
42
|
+
|
|
43
|
+
### When to Search Memory vs Codebase vs Code Intelligence
|
|
41
44
|
|
|
42
45
|
- **"Have we done this before?"** → `memory_query` or `npx nano-brain query` (searches past sessions)
|
|
43
46
|
- **"Where is this in the code?"** → grep / ast-grep (searches current files)
|
|
44
47
|
- **"How does this concept work here?"** → Both (memory for past context + grep for current code)
|
|
48
|
+
- **"What calls this function?"** → `code_context` (symbol graph relationships)
|
|
49
|
+
- **"What breaks if I change X?"** → `code_impact` (dependency + flow analysis)
|
|
50
|
+
- **"What did my changes affect?"** → `code_detect_changes` (git diff to symbol mapping)
|
|
45
51
|
|
|
46
52
|
<!-- 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
|
}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rri-t-testing
|
|
3
|
+
description: RRI-T v2 - Rapid Risk-Informed Testing with BMAD-enhanced risk scoring, traceability, quality gates, and nano-brain memory persistence
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# RRI-T v2.0 Testing Skill
|
|
7
|
+
|
|
8
|
+
Rapid Risk-Informed Testing methodology for AI agents. Guides systematic QA testing through 6 phases with risk scoring, traceability, quality gates, and cross-session memory persistence.
|
|
9
|
+
|
|
10
|
+
## When to Use
|
|
11
|
+
|
|
12
|
+
- Testing a new feature before release
|
|
13
|
+
- Validating a bug fix with regression coverage
|
|
14
|
+
- Assessing release readiness with quality gates
|
|
15
|
+
- Building test cases from requirements with traceability
|
|
16
|
+
- Resuming interrupted testing sessions via nano-brain
|
|
17
|
+
|
|
18
|
+
## Input Parameters
|
|
19
|
+
|
|
20
|
+
| Parameter | Required | Description |
|
|
21
|
+
|-----------|----------|-------------|
|
|
22
|
+
| `feature` | Yes | Feature name or PR reference |
|
|
23
|
+
| `tier` | No | Testing depth: `full` (default), `standard`, `minimal` |
|
|
24
|
+
| `acceptance_criteria` | No | List of acceptance criteria or link to spec |
|
|
25
|
+
| `environment` | No | Target environment (dev/staging/prod) |
|
|
26
|
+
|
|
27
|
+
## Workflow Phases
|
|
28
|
+
|
|
29
|
+
### Phase 0: ASSESS
|
|
30
|
+
|
|
31
|
+
Run testability gate, score risk, classify category, select tier, make go/no-go decision.
|
|
32
|
+
|
|
33
|
+
**Steps:**
|
|
34
|
+
1. Load `assets/rri-t-testability-gate.md` template
|
|
35
|
+
2. Validate prerequisites (environment, test data, deployment, acceptance criteria)
|
|
36
|
+
3. Assess testability (locators, API docs, auth flows, error states, baselines)
|
|
37
|
+
4. Score risk: Probability (1-3) x Impact (1-3) = Score (1-9)
|
|
38
|
+
5. Classify category: TECH / SEC / PERF / DATA / BUS / OPS
|
|
39
|
+
6. Select tier based on score
|
|
40
|
+
7. Decision: PROCEED / CONCERNS / BLOCK
|
|
41
|
+
|
|
42
|
+
**Output:** `00-assess.md`, `risk-matrix.md`
|
|
43
|
+
|
|
44
|
+
**MEMORY SAVE:** `rri-t/{feature}/assess` - Save risk register, tier, decision
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
### Phase 1: PREPARE
|
|
49
|
+
|
|
50
|
+
Define test scope, assign personas, select dimensions based on tier.
|
|
51
|
+
|
|
52
|
+
**Steps:**
|
|
53
|
+
1. Define test scope based on tier selection
|
|
54
|
+
2. Assign personas (5 for Full, 3 for Standard, 1 for Minimal)
|
|
55
|
+
3. Select dimensions (7 for Full, 4 for Standard, 2 for Minimal)
|
|
56
|
+
4. Set coverage targets per tier
|
|
57
|
+
5. Create output directory structure
|
|
58
|
+
|
|
59
|
+
**Output:** `01-prepare.md`
|
|
60
|
+
|
|
61
|
+
**MEMORY SAVE:** `rri-t/{feature}/prepare` - Save scope, persona assignments, dimension targets
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
### Phase 2: DISCOVER
|
|
66
|
+
|
|
67
|
+
Run persona interviews, map to dimensions, consolidate findings.
|
|
68
|
+
|
|
69
|
+
**Steps:**
|
|
70
|
+
1. Load `assets/rri-t-persona-interview.md` template
|
|
71
|
+
2. Run persona interviews using risk-tagged questions
|
|
72
|
+
3. Map questions to dimensions (D1-D7)
|
|
73
|
+
4. Consolidate findings into risk register update
|
|
74
|
+
5. Generate raw test ideas
|
|
75
|
+
|
|
76
|
+
**Output:** `02-discover.md`
|
|
77
|
+
|
|
78
|
+
**MEMORY SAVE:** `rri-t/{feature}/discover` - Save interview findings, test ideas, updated risks
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
### Phase 3: STRUCTURE
|
|
83
|
+
|
|
84
|
+
Create test cases, select stress axes, build traceability matrix.
|
|
85
|
+
|
|
86
|
+
**Steps:**
|
|
87
|
+
1. Load `assets/rri-t-test-case.md` template
|
|
88
|
+
2. Create test cases with Q-A-R-P-T format + risk category + traceability
|
|
89
|
+
3. Load `assets/rri-t-stress-matrix.md` and select relevant stress axes
|
|
90
|
+
4. Build traceability matrix using `assets/rri-t-traceability-matrix.md`
|
|
91
|
+
5. Identify coverage gaps
|
|
92
|
+
|
|
93
|
+
**Output:** `03-structure.md`, `traceability.md`
|
|
94
|
+
|
|
95
|
+
**MEMORY SAVE:** `rri-t/{feature}/structure` - Save test cases, traceability, gaps
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
### Phase 4: EXECUTE
|
|
100
|
+
|
|
101
|
+
Execute test cases via Playwright MCP, capture evidence, record results.
|
|
102
|
+
|
|
103
|
+
**Steps:**
|
|
104
|
+
1. Execute test cases using Playwright MCP browser automation
|
|
105
|
+
2. Capture evidence (screenshots, console logs, network requests)
|
|
106
|
+
3. Record results: PASS / FAIL / PAINFUL / MISSING
|
|
107
|
+
4. Calculate quality score using `assets/rri-t-quality-scorecard.md`
|
|
108
|
+
5. Log bugs found
|
|
109
|
+
|
|
110
|
+
**Output:** `04-execute.md`, `quality-scorecard.md`
|
|
111
|
+
|
|
112
|
+
**MEMORY SAVE:** `rri-t/{feature}/execute` - Save results, bugs, quality score
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
### Phase 5: ANALYZE
|
|
117
|
+
|
|
118
|
+
Fill coverage dashboard, apply gate rules, generate final report.
|
|
119
|
+
|
|
120
|
+
**Steps:**
|
|
121
|
+
1. Load `assets/rri-t-coverage-dashboard.md` template
|
|
122
|
+
2. Fill coverage dashboard with results
|
|
123
|
+
3. Complete traceability matrix with test results
|
|
124
|
+
4. Apply gate decision rules (PASS/CONCERNS/FAIL/WAIVED)
|
|
125
|
+
5. Generate final report
|
|
126
|
+
6. Extract reusable patterns for knowledge base
|
|
127
|
+
|
|
128
|
+
**Output:** `05-analyze.md`, `coverage-dashboard.md`
|
|
129
|
+
|
|
130
|
+
**MEMORY SAVE:** `rri-t/{feature}/analyze` - Save gate decision, report, lessons learned, reusable patterns
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Output Directory Structure
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
rri-t-{feature}/
|
|
138
|
+
00-assess.md # Phase 0: Testability gate + risk assessment
|
|
139
|
+
01-prepare.md # Phase 1: Scope, personas, dimensions
|
|
140
|
+
02-discover.md # Phase 2: Interview findings, test ideas
|
|
141
|
+
03-structure.md # Phase 3: Test cases, stress selections
|
|
142
|
+
04-execute.md # Phase 4: Execution log, evidence
|
|
143
|
+
05-analyze.md # Phase 5: Final analysis, recommendations
|
|
144
|
+
risk-matrix.md # Risk register with PxI scoring
|
|
145
|
+
traceability.md # Requirement-to-test mapping
|
|
146
|
+
quality-scorecard.md # 0-100 quality scoring
|
|
147
|
+
coverage-dashboard.md # Coverage metrics, gate decision
|
|
148
|
+
evidence/ # Screenshots, logs
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Templates
|
|
152
|
+
|
|
153
|
+
| Template | Purpose |
|
|
154
|
+
|----------|---------|
|
|
155
|
+
| `rri-t-testability-gate.md` | Phase 0 readiness checklist |
|
|
156
|
+
| `rri-t-risk-matrix.md` | PxI risk scoring template |
|
|
157
|
+
| `rri-t-traceability-matrix.md` | Requirement-to-test mapping |
|
|
158
|
+
| `rri-t-quality-scorecard.md` | 0-100 quality scoring |
|
|
159
|
+
| `rri-t-memory-protocol.md` | nano-brain save/resume protocol |
|
|
160
|
+
| `rri-t-test-case.md` | Q-A-R-P-T test case format |
|
|
161
|
+
| `rri-t-persona-interview.md` | 5-persona interview template |
|
|
162
|
+
| `rri-t-coverage-dashboard.md` | Coverage metrics dashboard |
|
|
163
|
+
| `rri-t-stress-matrix.md` | 8-axis stress testing scenarios |
|
|
164
|
+
|
|
165
|
+
## 7 Dimensions
|
|
166
|
+
|
|
167
|
+
| ID | Dimension | Target Coverage |
|
|
168
|
+
|----|-----------|-----------------|
|
|
169
|
+
| D1 | UI/UX | >= 85% |
|
|
170
|
+
| D2 | API | >= 85% |
|
|
171
|
+
| D3 | Performance | >= 70% |
|
|
172
|
+
| D4 | Security | >= 85% |
|
|
173
|
+
| D5 | Data Integrity | >= 85% |
|
|
174
|
+
| D6 | Infrastructure | >= 70% |
|
|
175
|
+
| D7 | Edge Cases | >= 85% |
|
|
176
|
+
|
|
177
|
+
## 5 Personas
|
|
178
|
+
|
|
179
|
+
| Persona | Focus |
|
|
180
|
+
|---------|-------|
|
|
181
|
+
| End User | Daily usage, speed, clarity, data safety |
|
|
182
|
+
| Business Analyst | Business rules, permissions, data consistency |
|
|
183
|
+
| QA Destroyer | Edge cases, race conditions, malformed inputs |
|
|
184
|
+
| DevOps Tester | Load, recovery, observability, scalability |
|
|
185
|
+
| Security Auditor | Auth, access control, data exposure, audit trails |
|
|
186
|
+
|
|
187
|
+
## Tier Selection
|
|
188
|
+
|
|
189
|
+
| Tier | Risk Score | Personas | Dimensions | Stress Axes | Est. Time |
|
|
190
|
+
|------|------------|----------|------------|-------------|-----------|
|
|
191
|
+
| Full | 6-9 | 5 | 7 | 8 | 2-4 hours |
|
|
192
|
+
| Standard | 3-5 | 3 | 4 | 4 | 1-2 hours |
|
|
193
|
+
| Minimal | 1-2 | 1 | 2 | 2 | 30-60 min |
|
|
194
|
+
|
|
195
|
+
## Release Gates
|
|
196
|
+
|
|
197
|
+
| State | Criteria |
|
|
198
|
+
|-------|----------|
|
|
199
|
+
| PASS | P0 coverage = 100% AND P1 >= 90% AND overall >= 80% |
|
|
200
|
+
| CONCERNS | P0 = 100% AND P1 = 80-89% AND mitigations documented |
|
|
201
|
+
| FAIL | P0 < 100% OR P1 < 80% OR unresolved security issues |
|
|
202
|
+
| WAIVED | FAIL + business approval + owner + expiry + remediation plan |
|
|
203
|
+
|
|
204
|
+
## Risk Categories
|
|
205
|
+
|
|
206
|
+
| Code | Category | Description |
|
|
207
|
+
|------|----------|-------------|
|
|
208
|
+
| TECH | Technical | Architecture/integration fragility |
|
|
209
|
+
| SEC | Security | Security vulnerabilities |
|
|
210
|
+
| PERF | Performance | Performance/scalability issues |
|
|
211
|
+
| DATA | Data | Data integrity/corruption |
|
|
212
|
+
| BUS | Business | Business logic errors |
|
|
213
|
+
| OPS | Operational | Deployment/operational issues |
|
|
214
|
+
|
|
215
|
+
## Guardrails
|
|
216
|
+
|
|
217
|
+
- Always run Phase 0 ASSESS before testing
|
|
218
|
+
- Score risk before testing (PxI formula)
|
|
219
|
+
- Use Q-A-R-P-T format for all test cases
|
|
220
|
+
- Map every test case to a requirement (traceability)
|
|
221
|
+
- Capture evidence for all FAIL and PAINFUL results
|
|
222
|
+
- Save to nano-brain after every phase
|
|
223
|
+
- Never skip security dimension for SEC-category risks
|
|
224
|
+
- Document all waivers with owner, expiry, remediation
|