Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion understand-anything-plugin/agents/project-scanner.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ From these, synthesize:
- **`name`** -- in priority order: `package.json` `name`, `Cargo.toml` `[package].name`, `go.mod` module path's last segment, `pyproject.toml` `[project].name` or `[tool.poetry].name`, else the directory name of the project root.
- **`rawDescription`** -- the `description` field from `package.json` (or its equivalent in the matching manifest), or `""` if none.
- **`readmeHead`** -- the first ~10 lines of `README.md` (or equivalent), or `""` if no README exists.
- **`frameworks`** -- match dependency names against known frameworks: `react`, `vue`, `svelte`, `@angular/core`, `express`, `fastify`, `koa`, `next`, `nuxt`, `vite`, `vitest`, `jest`, `mocha`, `tailwindcss`, `prisma`, `typeorm`, `sequelize`, `mongoose`, `redux`, `zustand`, `mobx`; Python: `django`, `djangorestframework`, `fastapi`, `flask`, `sqlalchemy`, `alembic`, `celery`, `pydantic`, `uvicorn`, `gunicorn`, `aiohttp`, `tornado`, `starlette`, `pytest`, `hypothesis`, `channels`; Ruby: `rails`, `railties`, `sinatra`, `grape`, `rspec`, `sidekiq`, `activerecord`, `actionpack`, `devise`, `pundit`; Go: `github.com/gin-gonic/gin`, `github.com/labstack/echo`, `github.com/gofiber/fiber`, `github.com/go-chi/chi`, `gorm.io/gorm`; Rust: `actix-web`, `axum`, `rocket`, `diesel`, `tokio`, `serde`, `warp`; JVM: `spring-boot`, `spring-web`, `spring-data`, `quarkus`, `micronaut`, `hibernate`, `jakarta`, `junit`, `ktor`. Also infer infrastructure tools from manifest presence: add `Docker` if `Dockerfile` exists in the file list, `Docker Compose` if `docker-compose.yml`/`docker-compose.yaml` exists, `Terraform` if any `*.tf`, `GitHub Actions` if `.github/workflows/*.yml`, `GitLab CI` if `.gitlab-ci.yml`, `Jenkins` if `Jenkinsfile`.
- **`frameworks`** -- match dependency names against known frameworks: `react`, `vue`, `svelte`, `angular` (match `@angular/core` in dependencies), `express`, `fastify`, `koa`, `next`, `nuxt`, `vite`, `vitest`, `jest`, `mocha`, `tailwindcss`, `prisma`, `typeorm`, `sequelize`, `mongoose`, `redux`, `zustand`, `mobx`; Python: `django`, `djangorestframework`, `fastapi`, `flask`, `sqlalchemy`, `alembic`, `celery`, `pydantic`, `uvicorn`, `gunicorn`, `aiohttp`, `tornado`, `starlette`, `pytest`, `hypothesis`, `channels`; Ruby: `rails`, `railties`, `sinatra`, `grape`, `rspec`, `sidekiq`, `activerecord`, `actionpack`, `devise`, `pundit`; Go: `github.com/gin-gonic/gin`, `github.com/labstack/echo`, `github.com/gofiber/fiber`, `github.com/go-chi/chi`, `gorm.io/gorm`; Rust: `actix-web`, `axum`, `rocket`, `diesel`, `tokio`, `serde`, `warp`; JVM: `spring-boot`, `spring-web`, `spring-data`, `quarkus`, `micronaut`, `hibernate`, `jakarta`, `junit`, `ktor`. Also infer infrastructure tools from manifest presence: add `Docker` if `Dockerfile` exists in the file list, `Docker Compose` if `docker-compose.yml`/`docker-compose.yaml` exists, `Terraform` if any `*.tf`, `GitHub Actions` if `.github/workflows/*.yml`, `GitLab CI` if `.gitlab-ci.yml`, `Jenkins` if `Jenkinsfile`.
- **`languages`** -- the deduplicated, alphabetically-sorted top-level language set you observe across the manifests + the bundled script's per-file language tally (you will read this from Step B's output).

If the manifest is missing or malformed, leave the corresponding field empty rather than guessing.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,9 @@ describe("FrameworkRegistry", () => {
});

describe("createDefault", () => {
it("registers all 10 built-in framework configs", () => {
it("registers all 11 built-in framework configs", () => {
const registry = FrameworkRegistry.createDefault();
expect(registry.getAllFrameworks()).toHaveLength(10);
expect(registry.getAllFrameworks()).toHaveLength(11);
});

it("includes frameworks for multiple languages", () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { FrameworkConfig } from "../types.js";

export const angularConfig = {
id: "angular",
displayName: "Angular",
languages: ["typescript", "javascript"],
detectionKeywords: ["@angular/core", "@angular/common", "@angular/router"],
manifestFiles: ["package.json"],
promptSnippetPath: "./frameworks/angular.md",
entryPoints: [
"src/main.ts",
"src/app/app.component.ts",
"src/app/app.config.ts",
"src/app/app.routes.ts",
"src/app/app.module.ts",
],
layerHints: {
components: "ui",
services: "service",
guards: "middleware",
interceptors: "middleware",
pipes: "utility",
directives: "utility",
models: "types",
environments: "config",
},
} satisfies FrameworkConfig;
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { reactConfig } from "./react.js";
import { nextjsConfig } from "./nextjs.js";
import { expressConfig } from "./express.js";
import { vueConfig } from "./vue.js";
import { angularConfig } from "./angular.js";
import { springConfig } from "./spring.js";
import { railsConfig } from "./rails.js";
import { ginConfig } from "./gin.js";
Expand All @@ -19,6 +20,7 @@ export const builtinFrameworkConfigs: FrameworkConfig[] = [
nextjsConfig,
expressConfig,
vueConfig,
angularConfig,
springConfig,
railsConfig,
ginConfig,
Expand All @@ -32,6 +34,7 @@ export {
nextjsConfig,
expressConfig,
vueConfig,
angularConfig,
springConfig,
railsConfig,
ginConfig,
Expand Down
73 changes: 73 additions & 0 deletions understand-anything-plugin/skills/understand/frameworks/angular.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Angular Framework Addendum

> Injected into file-analyzer and architecture-analyzer prompts when Angular is detected.
> Do NOT use as a standalone prompt — always appended to the base prompt template.

## Angular Project Structure

When analyzing an Angular project, apply these additional conventions on top of the base analysis rules.

### Canonical File Roles

| File / Pattern | Role | Tags |
|---|---|---|
| `src/main.ts` | Application bootstrap — calls `bootstrapApplication()` or `platformBrowserDynamic().bootstrapModule()` | `entry-point`, `config` |
| `src/app/app.component.ts` | Root application component — top-level shell and router outlet | `entry-point`, `ui` |
| `src/app/app.config.ts` | Standalone app configuration — providers, router, interceptors, animations | `config` |
| `src/app/app.routes.ts`, `src/app/app-routing.module.ts` | Route definitions — path-to-component mapping, lazy routes, guards | `config`, `routing` |
| `src/app/app.module.ts` | Root NgModule (legacy) — declares bootstrap component, imports feature modules | `config` |
| `**/*.component.ts` | UI components — template, styles, and component class with selector | `ui` |
| `**/*.component.html` | Component templates — declarative view markup bound to the component class | `ui` |
| `**/*.component.scss`, `**/*.component.css` | Component-scoped styles | `ui` |
| `**/*.import.const.ts` | Standalone component import bundles — grouped `imports` arrays for reuse | `config`, `utility` |
| `**/*.service.ts` | Injectable services — business logic, HTTP clients, state, facades | `service` |
| `**/*.guard.ts` | Route guards — `CanActivate`, `CanDeactivate`, `CanMatch` authorization/navigation checks | `middleware`, `routing` |
| `**/*.interceptor.ts` | HTTP interceptors — request/response mutation, auth headers, error handling | `middleware`, `service` |
| `**/*.resolver.ts` | Route resolvers — prefetch data before route activation | `service`, `routing` |
| `**/*.pipe.ts` | Template pipes — synchronous value transformations in templates | `utility` |
| `**/*.directive.ts` | Attribute and structural directives — DOM behavior and template control flow | `utility` |
| `**/*.module.ts` | Feature NgModules (legacy) — group declarations, imports, providers, routing | `config` |
| `**/models/*.ts`, `**/interfaces/*.ts` | Domain models, DTOs, and shared TypeScript interfaces | `type-definition` |
| `environments/*.ts` | Environment-specific configuration (API URLs, feature flags) | `config` |
| `**/*.spec.ts` | Unit and integration tests (Jasmine/Karma or Jest) | `test` |

### Edge Patterns to Look For

**Component composition** — When a parent component template references a child component selector (e.g., `<app-user-card>`), create `contains` edges from the parent component to the child. Check both inline templates and external `.component.html` files. `imports` arrays in standalone components list direct composition dependencies.

**Dependency injection** — When a class constructor or `inject()` call requests a service/token, create `depends_on` edges from the consumer to the provider. Follow `providedIn: 'root'`, route-level `providers`, and `bootstrapApplication({ providers: [...] })` to trace where services are registered. Factory providers and `InjectionToken` bindings are config-to-service edges.

**Input/output bindings** — When a parent passes `[input]` or listens to `(output)` on a child selector, create `depends_on` edges from parent to child. `input()` / `output()` signal-based APIs and legacy `@Input()` / `@Output()` decorators both indicate parent-child data coupling.

**Router configuration** — When `app.routes.ts` or a routing module maps paths to components or `loadChildren`/`loadComponent` lazy imports, create `configures` edges from the router file to each routed component or lazy chunk entry. Guards and resolvers referenced in route definitions add middleware edges.

**NgModule wiring (legacy)** — When an `*.module.ts` file lists components in `declarations` or modules in `imports`, create `contains` and `depends_on` edges reflecting the module graph. `RouterModule.forChild(routes)` links feature modules to their route tables.

**HTTP and state flow** — When a component or resolver calls a service method that returns an `Observable` or `Promise`, create `depends_on` from the consumer to the service. NgRx/store actions, selectors, and effects form a state subgraph: components `dispatch` actions, effects `depend_on` services, selectors `depend_on` state slices.

**Standalone import bundles** — When a `*.import.const.ts` file exports a shared `imports` array consumed by multiple standalone components, create `depends_on` edges from each consumer component to the bundle and from the bundle to its listed dependencies.

### Architectural Layers for Angular

Assign nodes to these layers when detected:

| Layer ID | Layer Name | What Goes Here |
|---|---|---|
| `layer:ui` | UI Layer | `*.component.ts`, templates, feature/page components, layouts |
| `layer:service` | Service Layer | `*.service.ts`, facades, API clients, NgRx stores/effects, resolvers |
| `layer:middleware` | Middleware Layer | `*.guard.ts`, `*.interceptor.ts`, route guards, HTTP middleware |
| `layer:config` | Config Layer | `app.config.ts`, `app.module.ts`, `app.routes.ts`, `environments/`, `*.module.ts`, `*.import.const.ts` |
| `layer:utility` | Utility Layer | `*.pipe.ts`, `*.directive.ts`, pure helpers, shared validators |
| `layer:types` | Types Layer | `models/`, `interfaces/`, shared DTOs and type definitions |
| `layer:test` | Test Layer | `*.spec.ts`, test harnesses and mocks |

### Notable Patterns to Capture in languageLesson

- **Standalone components over NgModules**: Modern Angular (v14+) favors `standalone: true` components with explicit `imports` arrays; `bootstrapApplication()` replaces `NgModule`-based bootstrapping in new projects
- **Signals and computed state**: `signal()`, `computed()`, and `effect()` provide fine-grained reactivity — trace signal reads/writes when analyzing component state flow
- **Dependency injection hierarchy**: Services use `@Injectable({ providedIn: 'root' })` for app-wide singletons; feature-scoped providers live on routes or component `providers` arrays
- **RxJS for async streams**: HTTP, router events, and complex async flows use Observables — `subscribe`, `async` pipe, and operators (`map`, `switchMap`, `catchError`) indicate data-flow paths
- **OnPush change detection**: Components with `changeDetection: ChangeDetectionStrategy.OnPush` only re-render when inputs change or events fire — marks performance-sensitive UI
- **Lazy-loaded feature routes**: `loadComponent` and `loadChildren` split the app into lazy chunks — each lazy entry is a feature boundary worth capturing as a module node
- **Control flow syntax**: Built-in `@if`, `@for`, and `@switch` in templates replace structural directives (`*ngIf`, `*ngFor`) — both styles may coexist during migration
- **Import const bundles**: `componentName.import.const.ts` files centralize standalone `imports` for large components — a project-specific composition pattern that reduces duplication across related views