From f6a801b1ac54398eab756a2ce32761969b0a17ac Mon Sep 17 00:00:00 2001 From: v6ole Date: Fri, 22 May 2026 12:16:21 +0800 Subject: [PATCH] chore: add AI tool configs and fix server.py indentation --- .claude/settings.json | 28 +++++++++++ .claude/skills/debug-issue/skill.md | 27 ++++++++++ .claude/skills/explore-codebase/skill.md | 28 +++++++++++ .claude/skills/refactor-safely/skill.md | 28 +++++++++++ .claude/skills/review-changes/skill.md | 29 +++++++++++ .cursorrules | 38 +++++++++++++++ .gemini/hooks/crg-session-start.sh | 15 ++++++ .gemini/hooks/crg-update.sh | 10 ++++ .gemini/settings.json | 30 ++++++++++++ .gemini/skills/debug-issue/SKILL.md | 27 ++++++++++ .gemini/skills/explore-codebase/SKILL.md | 28 +++++++++++ .gemini/skills/refactor-safely/SKILL.md | 28 +++++++++++ .gemini/skills/review-changes/SKILL.md | 29 +++++++++++ .github/code-review-graph.instruction.md | 46 ++++++++++++++++++ .gitignore | 3 ++ .kiro/steering/code-review-graph.md | 38 +++++++++++++++ .mcp.json | 14 ++++++ .opencode.json | 15 ++++++ .qoder/mcp.json | 14 ++++++ .qoder/settings.json | 28 +++++++++++ .vscode/mcp.json | 14 ++++++ .windsurfrules | 38 +++++++++++++++ AGENTS.md | 38 +++++++++++++++ CLAUDE.md | 38 +++++++++++++++ GEMINI.md | 38 +++++++++++++++ QODER.md | 38 +++++++++++++++ __pycache__/device_connector.cpython-312.pyc | Bin 37855 -> 37950 bytes __pycache__/device_prompts.cpython-312.pyc | Bin 15042 -> 15147 bytes __pycache__/network_devices.cpython-312.pyc | Bin 22459 -> 22570 bytes __pycache__/server.cpython-312.pyc | Bin 67389 -> 67886 bytes server.py | 4 +- .../__pycache__/__init__.cpython-312.pyc | Bin 3582 -> 3627 bytes 32 files changed, 709 insertions(+), 2 deletions(-) create mode 100644 .claude/settings.json create mode 100644 .claude/skills/debug-issue/skill.md create mode 100644 .claude/skills/explore-codebase/skill.md create mode 100644 .claude/skills/refactor-safely/skill.md create mode 100644 .claude/skills/review-changes/skill.md create mode 100644 .cursorrules create mode 100755 .gemini/hooks/crg-session-start.sh create mode 100755 .gemini/hooks/crg-update.sh create mode 100644 .gemini/settings.json create mode 100644 .gemini/skills/debug-issue/SKILL.md create mode 100644 .gemini/skills/explore-codebase/SKILL.md create mode 100644 .gemini/skills/refactor-safely/SKILL.md create mode 100644 .gemini/skills/review-changes/SKILL.md create mode 100644 .github/code-review-graph.instruction.md create mode 100644 .kiro/steering/code-review-graph.md create mode 100644 .mcp.json create mode 100644 .opencode.json create mode 100644 .qoder/mcp.json create mode 100644 .qoder/settings.json create mode 100644 .vscode/mcp.json create mode 100644 .windsurfrules create mode 100644 AGENTS.md create mode 100644 CLAUDE.md create mode 100644 GEMINI.md create mode 100644 QODER.md diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..09655b8 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,28 @@ +{ + "hooks": { + "PostToolUse": [ + { + "matcher": "Edit|Write|Bash", + "hooks": [ + { + "type": "command", + "command": "git rev-parse --git-dir >/dev/null 2>&1 && code-review-graph update --skip-flows --repo \"/home/v6ole/PythonProject/NetBrain_MCP\" || true", + "timeout": 30 + } + ] + } + ], + "SessionStart": [ + { + "matcher": "", + "hooks": [ + { + "type": "command", + "command": "git rev-parse --git-dir >/dev/null 2>&1 && code-review-graph status --repo \"/home/v6ole/PythonProject/NetBrain_MCP\" || echo 'Not a git repo, skipping'", + "timeout": 10 + } + ] + } + ] + } +} diff --git a/.claude/skills/debug-issue/skill.md b/.claude/skills/debug-issue/skill.md new file mode 100644 index 0000000..ef1b38a --- /dev/null +++ b/.claude/skills/debug-issue/skill.md @@ -0,0 +1,27 @@ +--- +name: Debug Issue +description: Systematically debug issues using graph-powered code navigation +--- + +## Debug Issue + +Use the knowledge graph to systematically trace and debug issues. + +### Steps + +1. Use `semantic_search_nodes` to find code related to the issue. +2. Use `query_graph` with `callers_of` and `callees_of` to trace call chains. +3. Use `get_flow` to see full execution paths through suspected areas. +4. Run `detect_changes` to check if recent changes caused the issue. +5. Use `get_impact_radius` on suspected files to see what else is affected. + +### Tips + +- Check both callers and callees to understand the full context. +- Look at affected flows to find the entry point that triggers the bug. +- Recent changes are the most common source of new issues. + +## Token Efficiency Rules +- ALWAYS start with `get_minimal_context(task="")` before any other graph tool. +- Use `detail_level="minimal"` on all calls. Only escalate to "standard" when minimal is insufficient. +- Target: complete any review/debug/refactor task in ≤5 tool calls and ≤800 total output tokens. diff --git a/.claude/skills/explore-codebase/skill.md b/.claude/skills/explore-codebase/skill.md new file mode 100644 index 0000000..dc7ad10 --- /dev/null +++ b/.claude/skills/explore-codebase/skill.md @@ -0,0 +1,28 @@ +--- +name: Explore Codebase +description: Navigate and understand codebase structure using the knowledge graph +--- + +## Explore Codebase + +Use the code-review-graph MCP tools to explore and understand the codebase. + +### Steps + +1. Run `list_graph_stats` to see overall codebase metrics. +2. Run `get_architecture_overview` for high-level community structure. +3. Use `list_communities` to find major modules, then `get_community` for details. +4. Use `semantic_search_nodes` to find specific functions or classes. +5. Use `query_graph` with patterns like `callers_of`, `callees_of`, `imports_of` to trace relationships. +6. Use `list_flows` and `get_flow` to understand execution paths. + +### Tips + +- Start broad (stats, architecture) then narrow down to specific areas. +- Use `children_of` on a file to see all its functions and classes. +- Use `find_large_functions` to identify complex code. + +## Token Efficiency Rules +- ALWAYS start with `get_minimal_context(task="")` before any other graph tool. +- Use `detail_level="minimal"` on all calls. Only escalate to "standard" when minimal is insufficient. +- Target: complete any review/debug/refactor task in ≤5 tool calls and ≤800 total output tokens. diff --git a/.claude/skills/refactor-safely/skill.md b/.claude/skills/refactor-safely/skill.md new file mode 100644 index 0000000..cf84420 --- /dev/null +++ b/.claude/skills/refactor-safely/skill.md @@ -0,0 +1,28 @@ +--- +name: Refactor Safely +description: Plan and execute safe refactoring using dependency analysis +--- + +## Refactor Safely + +Use the knowledge graph to plan and execute refactoring with confidence. + +### Steps + +1. Use `refactor_tool` with mode="suggest" for community-driven refactoring suggestions. +2. Use `refactor_tool` with mode="dead_code" to find unreferenced code. +3. For renames, use `refactor_tool` with mode="rename" to preview all affected locations. +4. Use `apply_refactor_tool` with the refactor_id to apply renames. +5. After changes, run `detect_changes` to verify the refactoring impact. + +### Safety Checks + +- Always preview before applying (rename mode gives you an edit list). +- Check `get_impact_radius` before major refactors. +- Use `get_affected_flows` to ensure no critical paths are broken. +- Run `find_large_functions` to identify decomposition targets. + +## Token Efficiency Rules +- ALWAYS start with `get_minimal_context(task="")` before any other graph tool. +- Use `detail_level="minimal"` on all calls. Only escalate to "standard" when minimal is insufficient. +- Target: complete any review/debug/refactor task in ≤5 tool calls and ≤800 total output tokens. diff --git a/.claude/skills/review-changes/skill.md b/.claude/skills/review-changes/skill.md new file mode 100644 index 0000000..6bb3558 --- /dev/null +++ b/.claude/skills/review-changes/skill.md @@ -0,0 +1,29 @@ +--- +name: Review Changes +description: Perform a structured code review using change detection and impact +--- + +## Review Changes + +Perform a thorough, risk-aware code review using the knowledge graph. + +### Steps + +1. Run `detect_changes` to get risk-scored change analysis. +2. Run `get_affected_flows` to find impacted execution paths. +3. For each high-risk function, run `query_graph` with pattern="tests_for" to check test coverage. +4. Run `get_impact_radius` to understand the blast radius. +5. For any untested changes, suggest specific test cases. + +### Output Format + +Provide findings grouped by risk level (high/medium/low) with: +- What changed and why it matters +- Test coverage status +- Suggested improvements +- Overall merge recommendation + +## Token Efficiency Rules +- ALWAYS start with `get_minimal_context(task="")` before any other graph tool. +- Use `detail_level="minimal"` on all calls. Only escalate to "standard" when minimal is insufficient. +- Target: complete any review/debug/refactor task in ≤5 tool calls and ≤800 total output tokens. diff --git a/.cursorrules b/.cursorrules new file mode 100644 index 0000000..d3dc9b4 --- /dev/null +++ b/.cursorrules @@ -0,0 +1,38 @@ + +## MCP Tools: code-review-graph + +**IMPORTANT: This project has a knowledge graph. ALWAYS use the +code-review-graph MCP tools BEFORE using Grep/Glob/Read to explore +the codebase.** The graph is faster, cheaper (fewer tokens), and gives +you structural context (callers, dependents, test coverage) that file +scanning cannot. + +### When to use graph tools FIRST + +- **Exploring code**: `semantic_search_nodes` or `query_graph` instead of Grep +- **Understanding impact**: `get_impact_radius` instead of manually tracing imports +- **Code review**: `detect_changes` + `get_review_context` instead of reading entire files +- **Finding relationships**: `query_graph` with callers_of/callees_of/imports_of/tests_for +- **Architecture questions**: `get_architecture_overview` + `list_communities` + +Fall back to Grep/Glob/Read **only** when the graph doesn't cover what you need. + +### Key Tools + +| Tool | Use when | +| ------ | ---------- | +| `detect_changes` | Reviewing code changes — gives risk-scored analysis | +| `get_review_context` | Need source snippets for review — token-efficient | +| `get_impact_radius` | Understanding blast radius of a change | +| `get_affected_flows` | Finding which execution paths are impacted | +| `query_graph` | Tracing callers, callees, imports, tests, dependencies | +| `semantic_search_nodes` | Finding functions/classes by name or keyword | +| `get_architecture_overview` | Understanding high-level codebase structure | +| `refactor_tool` | Planning renames, finding dead code | + +### Workflow + +1. The graph auto-updates on file changes (via hooks). +2. Use `detect_changes` for code review. +3. Use `get_affected_flows` to understand impact. +4. Use `query_graph` pattern="tests_for" to check coverage. diff --git a/.gemini/hooks/crg-session-start.sh b/.gemini/hooks/crg-session-start.sh new file mode 100755 index 0000000..bf9943c --- /dev/null +++ b/.gemini/hooks/crg-session-start.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +# code-review-graph: session start status (Gemini CLI hook) +# Must output ONLY JSON on stdout. Logs go to stderr. Never blocks the session. +set -euo pipefail + +cat > /dev/null || true + +msg="$(code-review-graph status --repo "/home/v6ole/PythonProject/NetBrain_MCP" 2>&1 | head -n 1 || true)" + +CRG_MSG="$msg" python3 -c ' +import json,os +m=os.environ.get("CRG_MSG","") +print(json.dumps({"systemMessage":m,"suppressOutput":True})) +' 2>/dev/null || echo '{"suppressOutput": true}' +exit 0 diff --git a/.gemini/hooks/crg-update.sh b/.gemini/hooks/crg-update.sh new file mode 100755 index 0000000..8ad8157 --- /dev/null +++ b/.gemini/hooks/crg-update.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +# code-review-graph: incremental update after write/replace (Gemini CLI hook) +# Must output ONLY JSON on stdout. Low-noise: no systemMessage. +set -euo pipefail + +cat > /dev/null || true + +code-review-graph update --skip-flows --repo "/home/v6ole/PythonProject/NetBrain_MCP" >/dev/null 2>&1 || true +echo '{"suppressOutput": true}' +exit 0 diff --git a/.gemini/settings.json b/.gemini/settings.json new file mode 100644 index 0000000..1e574a0 --- /dev/null +++ b/.gemini/settings.json @@ -0,0 +1,30 @@ +{ + "hooks": { + "SessionStart": [ + { + "matcher": "", + "hooks": [ + { + "type": "command", + "command": "bash .gemini/hooks/crg-session-start.sh", + "name": "code-review-graph status", + "timeout": 10000 + } + ] + } + ], + "AfterTool": [ + { + "matcher": "write_file|replace", + "hooks": [ + { + "type": "command", + "command": "bash .gemini/hooks/crg-update.sh", + "name": "code-review-graph update", + "timeout": 30000 + } + ] + } + ] + } +} diff --git a/.gemini/skills/debug-issue/SKILL.md b/.gemini/skills/debug-issue/SKILL.md new file mode 100644 index 0000000..b1926f9 --- /dev/null +++ b/.gemini/skills/debug-issue/SKILL.md @@ -0,0 +1,27 @@ +--- +name: debug-issue +description: Systematically debug issues using graph-powered code navigation +--- + +## Debug Issue + +Use the knowledge graph to systematically trace and debug issues. + +### Steps + +1. Use `semantic_search_nodes` to find code related to the issue. +2. Use `query_graph` with `callers_of` and `callees_of` to trace call chains. +3. Use `get_flow` to see full execution paths through suspected areas. +4. Run `detect_changes` to check if recent changes caused the issue. +5. Use `get_impact_radius` on suspected files to see what else is affected. + +### Tips + +- Check both callers and callees to understand the full context. +- Look at affected flows to find the entry point that triggers the bug. +- Recent changes are the most common source of new issues. + +## Token Efficiency Rules +- ALWAYS start with `get_minimal_context(task="")` before any other graph tool. +- Use `detail_level="minimal"` on all calls. Only escalate to "standard" when minimal is insufficient. +- Target: complete any review/debug/refactor task in ≤5 tool calls and ≤800 total output tokens. diff --git a/.gemini/skills/explore-codebase/SKILL.md b/.gemini/skills/explore-codebase/SKILL.md new file mode 100644 index 0000000..38afda2 --- /dev/null +++ b/.gemini/skills/explore-codebase/SKILL.md @@ -0,0 +1,28 @@ +--- +name: explore-codebase +description: Navigate and understand codebase structure using the knowledge graph +--- + +## Explore Codebase + +Use the code-review-graph MCP tools to explore and understand the codebase. + +### Steps + +1. Run `list_graph_stats` to see overall codebase metrics. +2. Run `get_architecture_overview` for high-level community structure. +3. Use `list_communities` to find major modules, then `get_community` for details. +4. Use `semantic_search_nodes` to find specific functions or classes. +5. Use `query_graph` with patterns like `callers_of`, `callees_of`, `imports_of` to trace relationships. +6. Use `list_flows` and `get_flow` to understand execution paths. + +### Tips + +- Start broad (stats, architecture) then narrow down to specific areas. +- Use `children_of` on a file to see all its functions and classes. +- Use `find_large_functions` to identify complex code. + +## Token Efficiency Rules +- ALWAYS start with `get_minimal_context(task="")` before any other graph tool. +- Use `detail_level="minimal"` on all calls. Only escalate to "standard" when minimal is insufficient. +- Target: complete any review/debug/refactor task in ≤5 tool calls and ≤800 total output tokens. diff --git a/.gemini/skills/refactor-safely/SKILL.md b/.gemini/skills/refactor-safely/SKILL.md new file mode 100644 index 0000000..c6e721a --- /dev/null +++ b/.gemini/skills/refactor-safely/SKILL.md @@ -0,0 +1,28 @@ +--- +name: refactor-safely +description: Plan and execute safe refactoring using dependency analysis +--- + +## Refactor Safely + +Use the knowledge graph to plan and execute refactoring with confidence. + +### Steps + +1. Use `refactor_tool` with mode="suggest" for community-driven refactoring suggestions. +2. Use `refactor_tool` with mode="dead_code" to find unreferenced code. +3. For renames, use `refactor_tool` with mode="rename" to preview all affected locations. +4. Use `apply_refactor_tool` with the refactor_id to apply renames. +5. After changes, run `detect_changes` to verify the refactoring impact. + +### Safety Checks + +- Always preview before applying (rename mode gives you an edit list). +- Check `get_impact_radius` before major refactors. +- Use `get_affected_flows` to ensure no critical paths are broken. +- Run `find_large_functions` to identify decomposition targets. + +## Token Efficiency Rules +- ALWAYS start with `get_minimal_context(task="")` before any other graph tool. +- Use `detail_level="minimal"` on all calls. Only escalate to "standard" when minimal is insufficient. +- Target: complete any review/debug/refactor task in ≤5 tool calls and ≤800 total output tokens. diff --git a/.gemini/skills/review-changes/SKILL.md b/.gemini/skills/review-changes/SKILL.md new file mode 100644 index 0000000..7d1f106 --- /dev/null +++ b/.gemini/skills/review-changes/SKILL.md @@ -0,0 +1,29 @@ +--- +name: review-changes +description: Perform a structured code review using change detection and impact +--- + +## Review Changes + +Perform a thorough, risk-aware code review using the knowledge graph. + +### Steps + +1. Run `detect_changes` to get risk-scored change analysis. +2. Run `get_affected_flows` to find impacted execution paths. +3. For each high-risk function, run `query_graph` with pattern="tests_for" to check test coverage. +4. Run `get_impact_radius` to understand the blast radius. +5. For any untested changes, suggest specific test cases. + +### Output Format + +Provide findings grouped by risk level (high/medium/low) with: +- What changed and why it matters +- Test coverage status +- Suggested improvements +- Overall merge recommendation + +## Token Efficiency Rules +- ALWAYS start with `get_minimal_context(task="")` before any other graph tool. +- Use `detail_level="minimal"` on all calls. Only escalate to "standard" when minimal is insufficient. +- Target: complete any review/debug/refactor task in ≤5 tool calls and ≤800 total output tokens. diff --git a/.github/code-review-graph.instruction.md b/.github/code-review-graph.instruction.md new file mode 100644 index 0000000..28bbc6d --- /dev/null +++ b/.github/code-review-graph.instruction.md @@ -0,0 +1,46 @@ +--- +applyTo: '**' +description: >- + Use code-review-graph MCP tools for token-efficient + codebase exploration and code review. +--- + + +## MCP Tools: code-review-graph + +**IMPORTANT: This project has a knowledge graph. ALWAYS use the +code-review-graph MCP tools BEFORE using file/search tools to +explore the codebase.** The graph is faster, cheaper (fewer +tokens), and gives you structural context (callers, dependents, +test coverage) that file scanning cannot. + +### When to use graph tools FIRST + +- **Exploring code**: `semantic_search_nodes` or `query_graph` +- **Understanding impact**: `get_impact_radius` +- **Code review**: `detect_changes` + `get_review_context` +- **Finding relationships**: `query_graph` callers_of/callees_of +- **Architecture questions**: `get_architecture_overview` + +Fall back to file/search tools **only** when the graph doesn't +cover what you need. + +### Key Tools + +| Tool | Use when | +| ------ | ---------- | +| `detect_changes` | Risk-scored change analysis | +| `get_review_context` | Token-efficient source snippets | +| `get_impact_radius` | Blast radius of a change | +| `get_affected_flows` | Impacted execution paths | +| `query_graph` | Trace callers, callees, imports, tests | +| `semantic_search_nodes` | Find functions/classes by keyword | +| `get_architecture_overview` | High-level structure | +| `refactor_tool` | Rename planning, dead code | + +### Workflow + +1. The graph auto-updates on file changes (via hooks). +2. Use `detect_changes` for code review. +3. Use `get_affected_flows` to understand impact. +4. Use `query_graph` pattern="tests_for" to check coverage. diff --git a/.gitignore b/.gitignore index 36b13f1..d2739a9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +<<<<<<< HEAD # ---> Python # Byte-compiled / optimized / DLL files __pycache__/ @@ -174,3 +175,5 @@ cython_debug/ # PyPI configuration file .pypirc +# Added by code-review-graph +.code-review-graph/ diff --git a/.kiro/steering/code-review-graph.md b/.kiro/steering/code-review-graph.md new file mode 100644 index 0000000..d3dc9b4 --- /dev/null +++ b/.kiro/steering/code-review-graph.md @@ -0,0 +1,38 @@ + +## MCP Tools: code-review-graph + +**IMPORTANT: This project has a knowledge graph. ALWAYS use the +code-review-graph MCP tools BEFORE using Grep/Glob/Read to explore +the codebase.** The graph is faster, cheaper (fewer tokens), and gives +you structural context (callers, dependents, test coverage) that file +scanning cannot. + +### When to use graph tools FIRST + +- **Exploring code**: `semantic_search_nodes` or `query_graph` instead of Grep +- **Understanding impact**: `get_impact_radius` instead of manually tracing imports +- **Code review**: `detect_changes` + `get_review_context` instead of reading entire files +- **Finding relationships**: `query_graph` with callers_of/callees_of/imports_of/tests_for +- **Architecture questions**: `get_architecture_overview` + `list_communities` + +Fall back to Grep/Glob/Read **only** when the graph doesn't cover what you need. + +### Key Tools + +| Tool | Use when | +| ------ | ---------- | +| `detect_changes` | Reviewing code changes — gives risk-scored analysis | +| `get_review_context` | Need source snippets for review — token-efficient | +| `get_impact_radius` | Understanding blast radius of a change | +| `get_affected_flows` | Finding which execution paths are impacted | +| `query_graph` | Tracing callers, callees, imports, tests, dependencies | +| `semantic_search_nodes` | Finding functions/classes by name or keyword | +| `get_architecture_overview` | Understanding high-level codebase structure | +| `refactor_tool` | Planning renames, finding dead code | + +### Workflow + +1. The graph auto-updates on file changes (via hooks). +2. Use `detect_changes` for code review. +3. Use `get_affected_flows` to understand impact. +4. Use `query_graph` pattern="tests_for" to check coverage. diff --git a/.mcp.json b/.mcp.json new file mode 100644 index 0000000..fea55fc --- /dev/null +++ b/.mcp.json @@ -0,0 +1,14 @@ +{ + "mcpServers": { + "code-review-graph": { + "command": "/usr/bin/python3", + "args": [ + "-m", + "code_review_graph", + "serve" + ], + "cwd": "/home/v6ole/PythonProject/NetBrain_MCP", + "type": "stdio" + } + } +} diff --git a/.opencode.json b/.opencode.json new file mode 100644 index 0000000..8106aec --- /dev/null +++ b/.opencode.json @@ -0,0 +1,15 @@ +{ + "mcpServers": { + "code-review-graph": { + "command": "/usr/bin/python3", + "args": [ + "-m", + "code_review_graph", + "serve" + ], + "cwd": "/home/v6ole/PythonProject/NetBrain_MCP", + "type": "stdio", + "env": [] + } + } +} diff --git a/.qoder/mcp.json b/.qoder/mcp.json new file mode 100644 index 0000000..fea55fc --- /dev/null +++ b/.qoder/mcp.json @@ -0,0 +1,14 @@ +{ + "mcpServers": { + "code-review-graph": { + "command": "/usr/bin/python3", + "args": [ + "-m", + "code_review_graph", + "serve" + ], + "cwd": "/home/v6ole/PythonProject/NetBrain_MCP", + "type": "stdio" + } + } +} diff --git a/.qoder/settings.json b/.qoder/settings.json new file mode 100644 index 0000000..09655b8 --- /dev/null +++ b/.qoder/settings.json @@ -0,0 +1,28 @@ +{ + "hooks": { + "PostToolUse": [ + { + "matcher": "Edit|Write|Bash", + "hooks": [ + { + "type": "command", + "command": "git rev-parse --git-dir >/dev/null 2>&1 && code-review-graph update --skip-flows --repo \"/home/v6ole/PythonProject/NetBrain_MCP\" || true", + "timeout": 30 + } + ] + } + ], + "SessionStart": [ + { + "matcher": "", + "hooks": [ + { + "type": "command", + "command": "git rev-parse --git-dir >/dev/null 2>&1 && code-review-graph status --repo \"/home/v6ole/PythonProject/NetBrain_MCP\" || echo 'Not a git repo, skipping'", + "timeout": 10 + } + ] + } + ] + } +} diff --git a/.vscode/mcp.json b/.vscode/mcp.json new file mode 100644 index 0000000..e0084d1 --- /dev/null +++ b/.vscode/mcp.json @@ -0,0 +1,14 @@ +{ + "servers": { + "code-review-graph": { + "command": "/usr/bin/python3", + "args": [ + "-m", + "code_review_graph", + "serve" + ], + "cwd": "/home/v6ole/PythonProject/NetBrain_MCP", + "type": "stdio" + } + } +} diff --git a/.windsurfrules b/.windsurfrules new file mode 100644 index 0000000..d3dc9b4 --- /dev/null +++ b/.windsurfrules @@ -0,0 +1,38 @@ + +## MCP Tools: code-review-graph + +**IMPORTANT: This project has a knowledge graph. ALWAYS use the +code-review-graph MCP tools BEFORE using Grep/Glob/Read to explore +the codebase.** The graph is faster, cheaper (fewer tokens), and gives +you structural context (callers, dependents, test coverage) that file +scanning cannot. + +### When to use graph tools FIRST + +- **Exploring code**: `semantic_search_nodes` or `query_graph` instead of Grep +- **Understanding impact**: `get_impact_radius` instead of manually tracing imports +- **Code review**: `detect_changes` + `get_review_context` instead of reading entire files +- **Finding relationships**: `query_graph` with callers_of/callees_of/imports_of/tests_for +- **Architecture questions**: `get_architecture_overview` + `list_communities` + +Fall back to Grep/Glob/Read **only** when the graph doesn't cover what you need. + +### Key Tools + +| Tool | Use when | +| ------ | ---------- | +| `detect_changes` | Reviewing code changes — gives risk-scored analysis | +| `get_review_context` | Need source snippets for review — token-efficient | +| `get_impact_radius` | Understanding blast radius of a change | +| `get_affected_flows` | Finding which execution paths are impacted | +| `query_graph` | Tracing callers, callees, imports, tests, dependencies | +| `semantic_search_nodes` | Finding functions/classes by name or keyword | +| `get_architecture_overview` | Understanding high-level codebase structure | +| `refactor_tool` | Planning renames, finding dead code | + +### Workflow + +1. The graph auto-updates on file changes (via hooks). +2. Use `detect_changes` for code review. +3. Use `get_affected_flows` to understand impact. +4. Use `query_graph` pattern="tests_for" to check coverage. diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..d3dc9b4 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,38 @@ + +## MCP Tools: code-review-graph + +**IMPORTANT: This project has a knowledge graph. ALWAYS use the +code-review-graph MCP tools BEFORE using Grep/Glob/Read to explore +the codebase.** The graph is faster, cheaper (fewer tokens), and gives +you structural context (callers, dependents, test coverage) that file +scanning cannot. + +### When to use graph tools FIRST + +- **Exploring code**: `semantic_search_nodes` or `query_graph` instead of Grep +- **Understanding impact**: `get_impact_radius` instead of manually tracing imports +- **Code review**: `detect_changes` + `get_review_context` instead of reading entire files +- **Finding relationships**: `query_graph` with callers_of/callees_of/imports_of/tests_for +- **Architecture questions**: `get_architecture_overview` + `list_communities` + +Fall back to Grep/Glob/Read **only** when the graph doesn't cover what you need. + +### Key Tools + +| Tool | Use when | +| ------ | ---------- | +| `detect_changes` | Reviewing code changes — gives risk-scored analysis | +| `get_review_context` | Need source snippets for review — token-efficient | +| `get_impact_radius` | Understanding blast radius of a change | +| `get_affected_flows` | Finding which execution paths are impacted | +| `query_graph` | Tracing callers, callees, imports, tests, dependencies | +| `semantic_search_nodes` | Finding functions/classes by name or keyword | +| `get_architecture_overview` | Understanding high-level codebase structure | +| `refactor_tool` | Planning renames, finding dead code | + +### Workflow + +1. The graph auto-updates on file changes (via hooks). +2. Use `detect_changes` for code review. +3. Use `get_affected_flows` to understand impact. +4. Use `query_graph` pattern="tests_for" to check coverage. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..d3dc9b4 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,38 @@ + +## MCP Tools: code-review-graph + +**IMPORTANT: This project has a knowledge graph. ALWAYS use the +code-review-graph MCP tools BEFORE using Grep/Glob/Read to explore +the codebase.** The graph is faster, cheaper (fewer tokens), and gives +you structural context (callers, dependents, test coverage) that file +scanning cannot. + +### When to use graph tools FIRST + +- **Exploring code**: `semantic_search_nodes` or `query_graph` instead of Grep +- **Understanding impact**: `get_impact_radius` instead of manually tracing imports +- **Code review**: `detect_changes` + `get_review_context` instead of reading entire files +- **Finding relationships**: `query_graph` with callers_of/callees_of/imports_of/tests_for +- **Architecture questions**: `get_architecture_overview` + `list_communities` + +Fall back to Grep/Glob/Read **only** when the graph doesn't cover what you need. + +### Key Tools + +| Tool | Use when | +| ------ | ---------- | +| `detect_changes` | Reviewing code changes — gives risk-scored analysis | +| `get_review_context` | Need source snippets for review — token-efficient | +| `get_impact_radius` | Understanding blast radius of a change | +| `get_affected_flows` | Finding which execution paths are impacted | +| `query_graph` | Tracing callers, callees, imports, tests, dependencies | +| `semantic_search_nodes` | Finding functions/classes by name or keyword | +| `get_architecture_overview` | Understanding high-level codebase structure | +| `refactor_tool` | Planning renames, finding dead code | + +### Workflow + +1. The graph auto-updates on file changes (via hooks). +2. Use `detect_changes` for code review. +3. Use `get_affected_flows` to understand impact. +4. Use `query_graph` pattern="tests_for" to check coverage. diff --git a/GEMINI.md b/GEMINI.md new file mode 100644 index 0000000..d3dc9b4 --- /dev/null +++ b/GEMINI.md @@ -0,0 +1,38 @@ + +## MCP Tools: code-review-graph + +**IMPORTANT: This project has a knowledge graph. ALWAYS use the +code-review-graph MCP tools BEFORE using Grep/Glob/Read to explore +the codebase.** The graph is faster, cheaper (fewer tokens), and gives +you structural context (callers, dependents, test coverage) that file +scanning cannot. + +### When to use graph tools FIRST + +- **Exploring code**: `semantic_search_nodes` or `query_graph` instead of Grep +- **Understanding impact**: `get_impact_radius` instead of manually tracing imports +- **Code review**: `detect_changes` + `get_review_context` instead of reading entire files +- **Finding relationships**: `query_graph` with callers_of/callees_of/imports_of/tests_for +- **Architecture questions**: `get_architecture_overview` + `list_communities` + +Fall back to Grep/Glob/Read **only** when the graph doesn't cover what you need. + +### Key Tools + +| Tool | Use when | +| ------ | ---------- | +| `detect_changes` | Reviewing code changes — gives risk-scored analysis | +| `get_review_context` | Need source snippets for review — token-efficient | +| `get_impact_radius` | Understanding blast radius of a change | +| `get_affected_flows` | Finding which execution paths are impacted | +| `query_graph` | Tracing callers, callees, imports, tests, dependencies | +| `semantic_search_nodes` | Finding functions/classes by name or keyword | +| `get_architecture_overview` | Understanding high-level codebase structure | +| `refactor_tool` | Planning renames, finding dead code | + +### Workflow + +1. The graph auto-updates on file changes (via hooks). +2. Use `detect_changes` for code review. +3. Use `get_affected_flows` to understand impact. +4. Use `query_graph` pattern="tests_for" to check coverage. diff --git a/QODER.md b/QODER.md new file mode 100644 index 0000000..d3dc9b4 --- /dev/null +++ b/QODER.md @@ -0,0 +1,38 @@ + +## MCP Tools: code-review-graph + +**IMPORTANT: This project has a knowledge graph. ALWAYS use the +code-review-graph MCP tools BEFORE using Grep/Glob/Read to explore +the codebase.** The graph is faster, cheaper (fewer tokens), and gives +you structural context (callers, dependents, test coverage) that file +scanning cannot. + +### When to use graph tools FIRST + +- **Exploring code**: `semantic_search_nodes` or `query_graph` instead of Grep +- **Understanding impact**: `get_impact_radius` instead of manually tracing imports +- **Code review**: `detect_changes` + `get_review_context` instead of reading entire files +- **Finding relationships**: `query_graph` with callers_of/callees_of/imports_of/tests_for +- **Architecture questions**: `get_architecture_overview` + `list_communities` + +Fall back to Grep/Glob/Read **only** when the graph doesn't cover what you need. + +### Key Tools + +| Tool | Use when | +| ------ | ---------- | +| `detect_changes` | Reviewing code changes — gives risk-scored analysis | +| `get_review_context` | Need source snippets for review — token-efficient | +| `get_impact_radius` | Understanding blast radius of a change | +| `get_affected_flows` | Finding which execution paths are impacted | +| `query_graph` | Tracing callers, callees, imports, tests, dependencies | +| `semantic_search_nodes` | Finding functions/classes by name or keyword | +| `get_architecture_overview` | Understanding high-level codebase structure | +| `refactor_tool` | Planning renames, finding dead code | + +### Workflow + +1. The graph auto-updates on file changes (via hooks). +2. Use `detect_changes` for code review. +3. Use `get_affected_flows` to understand impact. +4. Use `query_graph` pattern="tests_for" to check coverage. diff --git a/__pycache__/device_connector.cpython-312.pyc b/__pycache__/device_connector.cpython-312.pyc index b9a01d3f181a4582a52a47fc708542d8973fb830..e0b45c21e8f2574526b0f8534e46f9e3b8f65463 100644 GIT binary patch delta 2939 zcmai#3s6+&6@c%5@4j()2n(_-EGsOqunR?0UJ6}|4BJE?Sug_(<#o4!0*iN--~*(| zNVNsRrfxYT4~^O$7DX*5k^HtFL(chT+8WV*BS z-E+?WpYxyp{O7;-y%*WnUShQuv|0^Ae+AdWwhW%pPRP>=vfA98uB@llx;tE1l{>s` z?ygF~y~Wky%_?_!ON6HOu7*t;Dzkhu^23DqeUBk~N%KP10BbAF*g#PHi!KQU}xf;D0o!gzB662tI$ zP;7LNG*I<8Xg&lD)@D|rfH$l^V(sjS z3>yi#sWU#mc1~xxX|(z*nUk^s4f*{#M^T-MxllmrHRM8JNfcEsg^?PK>{7Triz=6y zl{Mka<&~sHE4!RzK)D#_&N23MI(#La)GB3HGD=vgykjG^8reIUlH>IRyP-CMxlurB zwXz$9*;Kx1CADF)n>Mu1t4Tdwe_lhVxrGS3wVvhvvR+Pu z-eTqTN+owo$<=Fo7jr7OO~bTomSw_btlqPT2P~o!Z;d^Ax06K zC@icHh4K`%2mjYHwuDV5Ppds z$%tuq%#lpa!Zt^=;v^cTV8pSPRQPm1_^XL|*uCAU= zm(b*O3H#wpRkT8?;Uv6WWut+=uF6+@O5YV8KNM8kRaf=4d(1Mm1$I|Ya`fplZr-d8 znZcD$Q}nEWZH+oO(4dd^6Rt-=O&`26{n5c`kv!rjGLhR@Q7V#JKU{2RB$vR}xH{w& z^!+Vj7CIU?k#jKHxL)@=G`xy<4e>g~7kVkSsYyQ&JceN1gS(Q7`Y!bl<-I~XZVN+5 z=W+$DGQriv2M$Im{gN}0x+7R&Y!P7^QG?D=9#1z=~_ zYWj7X>AKI!{N($7cv-NQ{0$v~EfTyuKgR(nr-LXBJ_syG%VJ3uyA(1#1!M}^J*DJ` z@3hA(Q{2VDQ?SsR<-qVF*Xr{A*Db9N`l2LVMP;C#_tEeb;tRw-5QT^-aBhE$yy1I( z`@qBa=KenNYdGHj?0~e1uW??mL8Ojvd>EjBN}}B3723N4c`rHWQ95qXEX^Vx{eOrE z<|DO^bmVy29u0m<;eCe={;=Dqyv^Lf$33EDe=S6 z@lSsIbYc$;!X$ol^w@{vuYPdug>r$=8Nvo?q>c8So5M>i@Q82g+`xvimhPw-=P%jO zRkQ_m1R;CY6OGTYr;t-)>g5)Na34nY8V00Ok@^8&V2gQ)a(c}=J+!dh9qnFW4g&@6 z;{>WsM6i#fw_h1XPy|ww${DQg!w&G^J0wy1VQWL$z6}a1N2@yn+xEq&u3F0OF=}-f zjP4tZpwG{unega++Q3z~=1ckM(=53QFAbTh-^0a}OUsDm5pE--;z>=YURtbcI3CPR zy4``}hlJr6dY9J@XOI$K^KdCqe2H_vfnSZJCaLlCq}UZ`4BpN=s3H#d?vJ<$xdUyZ z1!NLVjBY3A!7vuD$Nm+Um)V^SW!3g4H#!=e)s>YMPgDsb;2bND#HJQQ9G%^6VeyM_ z9L|oJ$bPs!mZ*@9a1_27Td$Db19zZ!JVobMt?P92JsqwhA(bXZ|BNREc8>o{Jr|aI zk6{Tch)aDKwbvT}HT!W!ySlF+e%zccv!atp+Pnbd(DCjSG2 CryNTF delta 2765 zcmaKueNa@_6~N!wx9{yP2toN+Sax9%7Fb}R1{6?1R|5$~P^y?=BXNOUmB?4$E=4m- zh$ESRqI?`n(}-4*PNh+sls9c`t(o|bX=?pwbTm9o!b~(1$LW}kQEQr--t!jS4ime> z{Px^)?>X<>^YNDV$2FfH(nOq&hzR4@r}Hgi<@GO<>YG|Cm#Vj4qb|=O#ppJh=o+y< zV#|4pnJ<67>XLz(KQ5LP_*rTUJc+kchnUM((;ELzTy|RtpXGlRPcBI{q<86G)^E%3 zq~p(QYkoj$OkV=|)A!AV0+iFUVLpDIoZ`*GSb z4O?7H2N$osn4ub8GCIw!Fz#|bxJ2#cf_Y5-#0Db4LhcHN}VNis|<~E;K8X(0l3A+iE40eqaL-III6wZS}`C4IeB)pB<^2>q(VNxGX zm8Y`N)js_hlsxtsMdU$sK1$M?1bVLICJYny2r`ybWIWl&L`Cmy_4qoQ z{F_6eDYMo#wRqb){AH5VCP{CRMH=BSj#Q*s$b({N@@?2y-_-2&C_-~ntJfzTq7&nI zx#BgblsByS!T|5!^0iA?|Ls`2#;HcH1{uoGQ>r6xYe$P$s`q~ohPkU^45ETb()|O#j5QQ zN;vfh%ldcq$r02utliXhxqz7sS*CH?JVp4B@E5{Iguh~QgGroX;!8Gku87A&{ShF_ z6AeWIOySK`nTL z)T;<4LIUCXLu|tro1Ji7KGJN|h{0mxN38`gB0p&T7q3-dse<21&Sn1~gHSVsCgta} zp~kS6q#X|(OX_25X&Iay?D8#yaXjWLhd1Q!eKxIli#FfJtgU$!hePF8d)xiU z!9pe}g3m8CwFl##QPkaR-ySwIiej>Vfe?yE9ay#2RAwLhwZ{i9&(}?9*g^z6&{HM% zcBg5(gIOTk?+E`PJYeY1Ggz+=4BdETyS0Pv8-D*A5PI!*# zr{hutHa;yrmeTg-Ccku!9EIjgeb=rbooc6c5E)C)kOwgsnwrQ^ULV!oNACu!`k|)A z&feu>7SFPK7(eJuRSS4z#N^dQ~L z6jExWDT11~N;+hinWzi2ABsyI=3vqBC;dh?v3>p7uvGqie>sSE=@67d zy^55fnY>9$0?N4#|IX|DBc~|3h!gvpauGI_h3Bi!e0+oMGvrpN_a&}dz&=< zzCVb%p%fTK`;b*sYqc9!4V8%MsNcllq4ZcqzqqB%)6wiLm24~u_Q&~5cxGrPfANVl wbPs3pT$By_hj;OpVskJVlQmo%F2$V4Y8^xlc7Mas_q~ny658N7JctMW3q8pCx&QzG diff --git a/__pycache__/device_prompts.cpython-312.pyc b/__pycache__/device_prompts.cpython-312.pyc index 98f9e997970fc984b82e2383e81f065a04059d34..13121bab5e791a5ca38dee7a9f0f33456804e09a 100644 GIT binary patch delta 533 zcmX?9y1I<-G%qg~0}wb~#d8 z2UM11Zca8B#bFG1fBY1(dLYtObD-t{SG<3@O}`69h#Wc_!!UNHX$H z{vavJ$OmFG^Vcv=77!L!7XYggoXftN5uz`hIhX;-6d|y@Fv1j=PH~aBtS~(#oDjW0 zTZNEKXBC~xnj$uNqOLN(cnt&4H4<}~t3Ym(1d55NrAVbnOEJI<0ZYh$NSFx7DVnmI z|LcY@aoyrbNlh&%PEF0;9Bg3E1Pso}Mn`~Tgz;j*WS|~*p!17w0f`2NFLIOL%PUUS zHK`H!AjZHY&@a;|(=9i{>Jq2w=0zq`m{_xb>Q`;HHs@hvOr7juVW0vspa>*dlnEjn zK!hET_{Cw9o1apelWJE~vU!fhdq(pZMn<+3!5KkJ}f!UuqnVFbAaDaqA V)iE(M`Z0dwVPF)w${-3h4FG(qgf9R9 delta 418 zcmZ2ocBqu^G%qg~0}xCrR?7&n-pE(W&3J2a54RcPt<8tI!x;q>+^k~!QcIkQ5;OCB zodaSvJMk`;Wz?9wUQ%zfgtizXW5#5C9sS9DIy~&0HB7S^Qn)5B)DdOmp1e?3l96Zf zMIf6O%;uZSs4L0N4^|^ESrNz<1ha*Z)PvPbE>sa?6ol$2)RkdM5uJQfSJ_*vh5=~2 z_*~{HpmS3svLr#yMg=v@DUvBtQVgpZA>v?_(jXEhlFl5=peeK2T`z=b^HKwQCZK1Z z8XW5a9qK?102A4x8Nkl+v73yQ1RFtd{Q?%>x)2*;WL9U;xn@LUyQcjQs>= ff97OnV*0=V68@CN#LVc&_>qT!QRFIvDA+UrxhiKB diff --git a/__pycache__/network_devices.cpython-312.pyc b/__pycache__/network_devices.cpython-312.pyc index bc04856bf5574eb0ad4ffc85d6c9c6fef83ebc8c..c09b0e350831c4a253e955bf13369b750c36300f 100644 GIT binary patch delta 2973 zcmai0eNa@_6@PbkS@s)PWCMhdtc&0R@}Yoi7G&ki0E+Ao(I!Q*VV`7W*$4Nnz&1u! zn`w-bTJ*LJRTDL~BYs4o&m<&i3{$niwtq-4;Jk4raoT1&?X()oOgh_{PVc!(U52q! zhWWko?)kd+oZmffKfa94k0Imlj7A+t|1xG1b`OmkZz@+i3SSa>_`?1&!Os`Agn};# zffg+6<~xIh&3v#LdwhY8Ej2BL($~sk2t}m*ajz**3F+0YA_W?Q#;beI5YpQXWP@gx zS=M-YzE|Y=Zd^i>G~12jh-C$t)Hn^YrnauGrM0fE30IJNmSmEsHKDcSNo~F=Auarj z)TmV=otrvgfTziJT|RP?`|)YyE#2q3c2EFRlaRg`wM!TDoeJVMrDZUU7t|O)1PD^F zYjH9;lABCkFqz^Pmr1v&3^hydm@wMd1BL+r0iX|nMPSbH_z`+JuHWO|!!MeVZHeXR z1?h0&ETS8E!mu?3)Zd1Wy-S?d#p zT>|d$1eXQCL)2bG6j*^c94238rlXTmBy%4cVtasN$_X7Eo-z)u0*1OSrb=K)3leg<$1AP(R-1zF|y(Y~?MLfeYinXv&>%78Es z+q&=vDHaRX5QPv1R9>32AHgeI+_T zs&b#SU!bOPoG-}th&T+gO6cVSc$|s5MIk_w?dj>o7Z>lAF6&V=|0OlY?*Y6I@GhCk zeKY4XDvBOj-7xn+&84OvG~BVSI-7AiW6rv6+PZGWS~|}m?Rv65FTIUE7u1}|Je)OW zwoRLDr&`C>-!?iQP=h)&(RbI7_@jo`8;1R-HjdRzTE8&Veyaq{0}Ypvc}tUe$Cfi^ zTQ_Z6H)nH9+Z;1C=R9Z7t|foU>sn8r3mJ={bEeHXqse0fw~bX0x&ciVFNVHl$sR=$ zag&}e49`I92J%Y&6OXYRY!8udv%x;9SZxNO^JL?UWkY$)uvmzPq-ZvyRh_ zQTLgO;mx%1Nkx>ah0eJG*K~nvrl9&CoHeQR%wNhCO8O*!fBL&cw^KHOZ^=~g-JHC$ zq0^zUq%(VOt;hoB66&1ioXd4h=elNctLM4IBq!-}o>Rgzv%;aF@xOt@WM@S_eJO#L z5^|(sSPf^vFH1Rq03<>1;0S^xN0$unjIZ^X?C2RIc(6T$d zEVDYAnRQIvO+C9r%-W&s=0kJ@FVs}2H`BW>o+ggkviRc#^PEDPPx@*zmGmhct(`}X zhue6z-mZ=w_kW&L8Ow*SlTYd^5KkiYeR{?X#*z`Kf77Rm>Yu}o;rOzeeZ9r#y^NZG z4hAf(E~DNOZ&3Xa-~t(F+^8Oay?;cmHd=@7thCQsTqEvL_vIbuc1&1i)>IwsyJc}5 z+(hA?-oo^aOy7R4eWH72O#|o~LEm^!pY(tHO-%2k{;gvhKd2wCKi>}SPH=aAm0%$+ zHo4K1bfxJAs)dS0kSp3dExSe0!LqDwv7b0>S}*0w6!~OJB^n|B+A@faQLgMDzi)oq z4EGT)<;yX$cWWg&D}A)}W0cLb%TlnIi(O$KvMF-hU5g~?E4LjbvMw+;xOMbrP+F@C z-5}4kZt;L4z5>982z+4i9RT(vWOTeoUuD&cg5bx001cZ;Y)G-uq=L0S1F(VeSCIY& za3A0s_8lAr5#T*()w9_MjgrmVn$tpbL5}weU0sytvQi9*_!1aS5^3AsEOtVcCN>6R zbBpbEl(e?3Oo?bJdIawtKfeJhDNpD>Cl--IZTqy-30air$cu=6`)U;v%C_4KI<#WA OWPziPg;c_CZ~G56Oe>xM delta 2996 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 oZsVo$)i_3izO>v`p?gkaJ^>o zMZIa~ls>&>Fmn8Mzd=LP&UJl;6xZc1rjd>`vaLv2lE$4dlF~GCBBUT03MZ!)#LS+^ zosNir!s%PF<@7{NiIqQ{Ybi9#(367Z==gU80`xm70eZco z^GDiL;8&W+pN+wWv$5E4Hc>#@%JZdZu9yCHmXtjK#>1=Azjp}wq6}scjud9iFEa0- zCoiQ5uK?F3*AJJ11s&V>Sa$t}hFo4s9;0h6XOZXVZ!gaxZ_|HXj_!CI{Adl6t(7mL zV_6u2kh&M)5rpA*%l=5iHW(IYb_!+79XrS##vaEJSlmt^#h%1i0;q?dw9P{d&m+TZ z1a`1xX>){a9!IW(2|X~P-L4B)zQ!zn>zl*lmTi|_IItpxVzZQ5_ zv`bBH_|s;S^d{YXHC{Ll4L{N|SD#&h!(}hNE;D$p1<*O{EJ^vJ?{tJh)M8R!jR@5cK3 zY3_HEV-Eu9_JgsG_QL8tNZf_|HiWy8QMm$}S7A8| z6th19dk-7zW^)W1SVFvm6rMe#KOfkc$WKVk%zK5|FC7D;&RbgK&Im(40EmhjpmwIblb z&8;n5STwV!tg@tFu7n3J2~R+7b>;l>`E%zNFOl$^BjGVc!V`d7Sy5O}CgENz;m#@H z7Ux#O%Z9y0f(K^Y%J2_|!JLFU7n_yhNA%5T$wxD~{8RKP0EVjU+Co zBTo!B)VZteVoRefPx=m8;XmhSrtki+h|HmuYjBzq$v^GH{rhhsz!KSUf=9<4ZSIeN#jz^mStp{|U}GhMkm@JH3S+ejhla(FoW z-RnG9*ke36d*8;Ztc?7Nh)02Kp4J^x6eN0FHYp){Cwe&iJ($(Q_f+(#59M8DW#q2{ zer)qdJ374lvzYvBGHaB4Ec@gm?U4?jRFFnR$7}`BG7lqhG0@-^6L6o(H9WHuq^cHB^r G!v6tFt9erZ delta 11562 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 diff --git a/server.py b/server.py index b71b5e9..8b1347a 100644 --- a/server.py +++ b/server.py @@ -421,8 +421,8 @@ async def connect_device(device_id: str, credential_id: str) -> Dict[str, Any]: command = "show version" else: command = "show version" - - logger.info(f"尝试获取版本信息,平台: {platform},命令: {command}") + + logger.info(f"尝试获取版本信息,平台: {platform},命令: {command}") # 直接使用Scrapli连接对象发送命令 if hasattr(connector.connection, "send_command"): diff --git a/templates/command_templates/__pycache__/__init__.cpython-312.pyc b/templates/command_templates/__pycache__/__init__.cpython-312.pyc index 2919c0383f55cb8acbffe3ca46c64703bfce828a..fadeab3f7fe06af25ddd116fb1a2b55e75177121 100644 GIT binary patch delta 409 zcmew-y;_F%G%qg~0}v=&SU*`b* zlGNOSoWzpUV*TX&+}y;xlz4>5WOX)GM)l3UY`2&ggC}cn7IEn)z^$Fd$;`+t39?WM zM2Jsb!4=Le2VyFM2=&Qa+#2ypK&B=~5yV{}VGSU0i!Hl6u_(Q`NCm`UNh{4uzQtCQ zT3nh_QlttLD&_zZ3Q$m_22v!Fo>~%*?!Y3G%@euV8QDyLDvER_&*PD2l$pGb$JQV0 z3LTKBDTt5;5g?Zose=fR@>}fj@rgM(@$p4kK;CB{W&m6Ci^C>2KczG$)vm}6D8>lH W#cL;f@mevtF-~sfEoHF|wu@k=dnDoV`E^K}l0DM`&O$Vn_oEsjaf&&^HDONmE_O!j0`WmMao&vuK6(Q~pF zXVKlqx9rgJhuK|S7?JoO+bVchyb~yNDV}Ql;2{Hk5A0WiH|SR1oA!uF$2UR4x8Nk gl+v73yCPel7$XoDubEuNYsF|ac@u9biw#f!0HMHJdH?_b