diff --git a/README.md b/README.md index 04efe8311..74b1caffc 100644 --- a/README.md +++ b/README.md @@ -198,7 +198,7 @@ Understand-Anything works across multiple AI coding platforms. ``` -### One-line install (Codex / OpenCode / OpenClaw / Antigravity / Gemini CLI / Pi Agent / Vibe CLI / VS Code Copilot / Hermes / Cline / KIMI CLI / Trae / Nanobot / Kiro) +### One-line install (Codex / OpenCode / OpenClaw / Antigravity / Gemini CLI / Pi Agent / Vibe CLI / VS Code Copilot / Hermes / Cline / KIMI CLI / Trae / Nanobot / Kiro / AdaL) **macOS / Linux:** @@ -217,7 +217,7 @@ The installer clones the repo to `~/.understand-anything/repo` and creates the r > **Note on invoking skills:** the invocation prefix differs per platform. Most platforms use slash commands (`/understand`), but **Codex uses `$` instead** — type `$understand`, not `/understand`. If neither prefix is recognized on your platform, just ask in plain language: *"Use the understand skill to analyze this project."* -- Supported `` values: `gemini`, `codex`, `opencode`, `pi`, `openclaw`, `antigravity`, `vibe`, `vscode`, `hermes`, `cline`, `kimi`, `trae`, `nanobot`, `kiro` +- Supported `` values: `gemini`, `codex`, `opencode`, `pi`, `openclaw`, `antigravity`, `vibe`, `vscode`, `hermes`, `cline`, `kimi`, `trae`, `nanobot`, `kiro`, `adal` - Update later: `./install.sh --update` - Uninstall: `./install.sh --uninstall ` @@ -239,6 +239,16 @@ For personal skills (available across all projects), run the `install.sh` above copilot plugin install Egonex-AI/Understand-Anything:understand-anything-plugin ``` +### AdaL CLI + +```bash +curl -fsSL https://raw.githubusercontent.com/Egonex-AI/Understand-Anything/main/install.sh | bash -s adal +``` + +After installation, the skills are symlinked into `~/.adal/skills/`. Restart your AdaL CLI session to pick up the skills. + +For personal skills (available across all projects), run the `install.sh` above with the `adal` platform. + ### Kiro CLI / IDE ```bash @@ -272,6 +282,7 @@ For personal skills (available across all projects), run the `install.sh` above | Trae | ✅ Supported | `install.sh trae` | | Nanobot | ✅ Supported | `install.sh nanobot` | | Kiro CLI / IDE | ✅ Supported | `install.sh kiro` | +| AdaL CLI | ✅ Supported | `install.sh adal` | --- diff --git a/READMEs/README.es-ES.md b/READMEs/README.es-ES.md index 69a6e2d65..5abe8c07d 100644 --- a/READMEs/README.es-ES.md +++ b/READMEs/README.es-ES.md @@ -257,6 +257,7 @@ Para habilidades personales (disponibles en todos los proyectos), ejecuta el `in | KIMI CLI | ✅ Soportado | `install.sh kimi` | | Nanobot | ✅ Soportado | `install.sh nanobot` | | Kiro CLI / IDE | ✅ Soportado | `install.sh kiro` | +| AdaL CLI | ✅ Soportado | `install.sh adal` | --- diff --git a/READMEs/README.ja-JP.md b/READMEs/README.ja-JP.md index 0cb341654..b01423479 100644 --- a/READMEs/README.ja-JP.md +++ b/READMEs/README.ja-JP.md @@ -270,6 +270,7 @@ curl -fsSL https://raw.githubusercontent.com/Egonex-AI/Understand-Anything/main/ | Trae | ✅ サポート | `install.sh trae` | | Nanobot | ✅ サポート | `install.sh nanobot` | | Kiro CLI / IDE | ✅ サポート | `install.sh kiro` | +| AdaL CLI | ✅ サポート | `install.sh adal` | --- diff --git a/READMEs/README.ko-KR.md b/READMEs/README.ko-KR.md index 25ad0420f..63079a86a 100644 --- a/READMEs/README.ko-KR.md +++ b/READMEs/README.ko-KR.md @@ -257,6 +257,7 @@ curl -fsSL https://raw.githubusercontent.com/Egonex-AI/Understand-Anything/main/ | KIMI CLI | ✅ 지원 | `install.sh kimi` | | Nanobot | ✅ 지원 | `install.sh nanobot` | | Kiro CLI / IDE | ✅ 지원 | `install.sh kiro` | +| AdaL CLI | ✅ 지원 | `install.sh adal` | --- diff --git a/READMEs/README.ru-RU.md b/READMEs/README.ru-RU.md index a13dfc893..cdaeb28d7 100644 --- a/READMEs/README.ru-RU.md +++ b/READMEs/README.ru-RU.md @@ -258,6 +258,7 @@ curl -fsSL https://raw.githubusercontent.com/Egonex-AI/Understand-Anything/main/ | KIMI CLI | ✅ Поддерживается | `install.sh kimi` | | Nanobot | ✅ Поддерживается | `install.sh nanobot` | | Kiro CLI / IDE | ✅ Поддерживается | `install.sh kiro` | +| AdaL CLI | ✅ Поддерживается | `install.sh adal` | --- diff --git a/READMEs/README.tr-TR.md b/READMEs/README.tr-TR.md index e1fb6c80b..fd111ef85 100644 --- a/READMEs/README.tr-TR.md +++ b/READMEs/README.tr-TR.md @@ -258,6 +258,7 @@ Tüm projelerde kullanmak için kişisel beceri olarak kurmak istersen yukarıda | KIMI CLI | ✅ Destekleniyor | `install.sh kimi` | | Nanobot | ✅ Destekleniyor | `install.sh nanobot` | | Kiro CLI / IDE | ✅ Destekleniyor | `install.sh kiro` | +| AdaL CLI | ✅ Destekleniyor | `install.sh adal` | --- diff --git a/READMEs/README.zh-CN.md b/READMEs/README.zh-CN.md index d3ba928fe..d9ec8c287 100644 --- a/READMEs/README.zh-CN.md +++ b/READMEs/README.zh-CN.md @@ -257,6 +257,7 @@ curl -fsSL https://raw.githubusercontent.com/Egonex-AI/Understand-Anything/main/ | KIMI CLI | ✅ 支持 | `install.sh kimi` | | Nanobot | ✅ 支持 | `install.sh nanobot` | | Kiro CLI / IDE | ✅ 支持 | `install.sh kiro` | +| AdaL CLI | ✅ 支持 | `install.sh adal` | --- diff --git a/READMEs/README.zh-TW.md b/READMEs/README.zh-TW.md index f7b145fc1..35596d497 100644 --- a/READMEs/README.zh-TW.md +++ b/READMEs/README.zh-TW.md @@ -257,6 +257,7 @@ curl -fsSL https://raw.githubusercontent.com/Egonex-AI/Understand-Anything/main/ | KIMI CLI | ✅ 支援 | `install.sh kimi` | | Nanobot | ✅ 支援 | `install.sh nanobot` | | Kiro CLI / IDE | ✅ 支援 | `install.sh kiro` | +| AdaL CLI | ✅ 支援 | `install.sh adal` | --- diff --git a/install.ps1 b/install.ps1 index 77c6595e4..4e1451c2c 100644 --- a/install.ps1 +++ b/install.ps1 @@ -42,6 +42,7 @@ $Platforms = [ordered]@{ trae = @{ Target = (Join-Path $HOME '.trae\skills'); Style = 'per-skill' } nanobot = @{ Target = (Join-Path $HOME '.nanobot\workspace\skills'); Style = 'per-skill' } kiro = @{ Target = (Join-Path $HOME '.kiro\skills'); Style = 'per-skill' } + adal = @{ Target = (Join-Path $HOME '.adal\skills'); Style = 'per-skill' } } function Show-Usage { @@ -245,6 +246,9 @@ function Cmd-Install([string]$Id) { if ($Id -eq 'kiro') { Write-Host "`n Usage: kiro-cli chat --agent understand `"Analyze this project`"" } + if ($Id -eq 'adal') { + Write-Host "`n Tip: AdaL uses /plugin commands — install via the marketplace: /plugin marketplace add Egonex-AI/Understand-Anything then /plugin install understand-anything (or run install.ps1 adal)." + } } function Cmd-Uninstall([string]$Id) { diff --git a/install.sh b/install.sh index eb7336f46..a0882bfd4 100755 --- a/install.sh +++ b/install.sh @@ -42,6 +42,7 @@ kimi|$HOME/.kimi/skills|folder trae|$HOME/.trae/skills|per-skill nanobot|$HOME/.nanobot/workspace/skills|per-skill kiro|$HOME/.kiro/skills|per-skill +adal|$HOME/.adal/skills|per-skill EOF } @@ -232,6 +233,9 @@ KIROEOF if [[ "$id" == "kiro" ]]; then printf '\n Usage: kiro-cli chat --agent understand "Analyze this project"\n' fi + if [[ "$id" == "adal" ]]; then + printf '\n Tip: AdaL uses /plugin commands — install via the marketplace: /plugin marketplace add Egonex-AI/Understand-Anything then /plugin install understand-anything (or run install.sh adal).\n' + fi } cmd_uninstall() { diff --git a/understand-anything-plugin/packages/dashboard/src/utils/__tests__/edgeAggregation.test.ts b/understand-anything-plugin/packages/dashboard/src/utils/__tests__/edgeAggregation.test.ts index f5196c337..c468d162e 100644 --- a/understand-anything-plugin/packages/dashboard/src/utils/__tests__/edgeAggregation.test.ts +++ b/understand-anything-plugin/packages/dashboard/src/utils/__tests__/edgeAggregation.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect } from "vitest"; -import { aggregateContainerEdges } from "../edgeAggregation"; -import type { GraphEdge, EdgeType } from "@understand-anything/core/types"; +import { aggregateContainerEdges, aggregateLayerEdges, computePortals } from "../edgeAggregation"; +import type { GraphEdge, EdgeType, KnowledgeGraph, Layer } from "@understand-anything/core/types"; const ce = (source: string, target: string, type: EdgeType = "calls"): GraphEdge => ({ source, @@ -10,6 +10,17 @@ const ce = (source: string, target: string, type: EdgeType = "calls"): GraphEdge weight: 1, }); +function makeGraph(layers: Layer[], edges: GraphEdge[]): KnowledgeGraph { + return { + version: "1.0", + project: { name: "test", languages: [], frameworks: [], description: "", analyzedAt: "", gitCommitHash: "" }, + nodes: [], + edges, + layers, + tour: [], + }; +} + describe("aggregateContainerEdges", () => { it("returns empty arrays for empty input", () => { const r = aggregateContainerEdges([], new Map()); @@ -77,3 +88,92 @@ describe("aggregateContainerEdges", () => { expect(r.interContainerAggregated).toHaveLength(2); }); }); + +// --------------------------------------------------------------------------- +// aggregateLayerEdges +// --------------------------------------------------------------------------- +describe("aggregateLayerEdges", () => { + const layers: Layer[] = [ + { id: "layer:presentation", name: "Presentation", description: "", nodeIds: ["p1", "p2"] }, + { id: "layer:api", name: "API", description: "", nodeIds: ["a1"] }, + { id: "layer:services", name: "Services", description: "", nodeIds: ["s1"] }, + ]; + + it("returns empty array for no cross-layer edges", () => { + const g = makeGraph(layers, [ce("p1", "p2")]); + expect(aggregateLayerEdges(g)).toEqual([]); + }); + + it("normalizes edge direction to architectural order (top→bottom)", () => { + // Edge from services (index 2) to presentation (index 0) should be + // normalized to presentation→services. + const g = makeGraph(layers, [ce("s1", "p1")]); + const result = aggregateLayerEdges(g); + expect(result).toHaveLength(1); + expect(result[0].sourceLayerId).toBe("layer:presentation"); + expect(result[0].targetLayerId).toBe("layer:services"); + }); + + it("merges bidirectional edges into one aggregated edge", () => { + const g = makeGraph(layers, [ce("p1", "a1"), ce("a1", "p1")]); + const result = aggregateLayerEdges(g); + expect(result).toHaveLength(1); + expect(result[0].count).toBe(2); + expect(result[0].sourceLayerId).toBe("layer:presentation"); + expect(result[0].targetLayerId).toBe("layer:api"); + }); + + it("collects multiple edge types", () => { + const g = makeGraph(layers, [ + ce("p1", "a1", "calls"), + ce("p1", "a1", "imports"), + ]); + const result = aggregateLayerEdges(g); + expect(result).toHaveLength(1); + expect(result[0].edgeTypes.sort()).toEqual(["calls", "imports"]); + }); + + it("ignores intra-layer edges", () => { + const g = makeGraph(layers, [ce("p1", "p2"), ce("a1", "a1")]); + expect(aggregateLayerEdges(g)).toEqual([]); + }); +}); + +// --------------------------------------------------------------------------- +// computePortals +// --------------------------------------------------------------------------- +describe("computePortals", () => { + const layers: Layer[] = [ + { id: "layer:presentation", name: "Presentation", description: "", nodeIds: ["p1"] }, + { id: "layer:api", name: "API", description: "", nodeIds: ["a1"] }, + { id: "layer:services", name: "Services", description: "", nodeIds: ["s1"] }, + ]; + + it("finds connected layers regardless of edge direction", () => { + // Edge from services→presentation (reverse architectural order) + const g = makeGraph(layers, [ce("s1", "p1")]); + const portals = computePortals(g, "layer:presentation"); + expect(portals).toHaveLength(1); + expect(portals[0].layerId).toBe("layer:services"); + expect(portals[0].connectionCount).toBe(1); + }); + + it("returns empty for isolated layer", () => { + const g = makeGraph(layers, [ce("p1", "a1")]); + const portals = computePortals(g, "layer:services"); + expect(portals).toEqual([]); + }); + + it("counts connections from precomputed aggregation", () => { + const g = makeGraph(layers, [ + ce("p1", "a1"), + ce("p1", "a1", "imports"), + ce("p1", "s1"), + ]); + const agg = aggregateLayerEdges(g); + const portals = computePortals(g, "layer:presentation", agg); + expect(portals).toHaveLength(2); + const apiPortal = portals.find((p) => p.layerId === "layer:api"); + expect(apiPortal?.connectionCount).toBe(2); + }); +}); diff --git a/understand-anything-plugin/packages/dashboard/src/utils/edgeAggregation.ts b/understand-anything-plugin/packages/dashboard/src/utils/edgeAggregation.ts index 3e47a7e60..f09ea3105 100644 Binary files a/understand-anything-plugin/packages/dashboard/src/utils/edgeAggregation.ts and b/understand-anything-plugin/packages/dashboard/src/utils/edgeAggregation.ts differ