analyze-project-architecture

LLM-based architectural analysis that transforms raw project data into meaningful structure

16 stars

Best use case

analyze-project-architecture is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

LLM-based architectural analysis that transforms raw project data into meaningful structure

Teams using analyze-project-architecture should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/analyze-project-architecture/SKILL.md --create-dirs "https://raw.githubusercontent.com/diegosouzapw/awesome-omni-skill/main/skills/development/analyze-project-architecture/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/analyze-project-architecture/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How analyze-project-architecture Compares

Feature / Agentanalyze-project-architectureStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

LLM-based architectural analysis that transforms raw project data into meaningful structure

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# Analyze Project Architecture Skill

## Enforcement Rules

### Script Execution
1. Run scripts EXACTLY as documented - no improvisation
2. All scripts use: `python3 .plan/execute-script.py {notation} ...`

### Workflow Behavior
1. Complete all steps in sequence
2. After each module enrichment → proceed to next module
3. Only stop when all modules are enriched

### Prohibited Actions
- Skipping modules without enrichment
- Leaving `responsibility` or `key_packages` empty
- Omitting `--reasoning` parameters (traceability is required)
- Summarizing what you're about to do instead of doing it

---

## What This Skill Provides

**Discovery**: Run extension API to collect raw module data

**Enrichment**: LLM analyzes documentation and code to add semantic understanding

**Persistence**: Store enriched data for solution-outline consumption

---

## Scripts

| Script | Notation | Purpose |
|--------|----------|---------|
| architecture | `plan-marshall:analyze-project-architecture:architecture` | Main CLI for all operations |

### Command Groups

| Group | API | Purpose |
|-------|-----|---------|
| `discover`, `init` | [manage-api](standards/manage-api.md) | Setup commands |
| `derived`, `derived-module` | [manage-api](standards/manage-api.md) | Read raw discovered data |
| `enrich *` | [manage-api](standards/manage-api.md) | Write enrichment data |
| `info`, `module`, `modules`, `commands`, `resolve` | [client-api](standards/client-api.md) | Consumer queries |

---

## Step 1: Discover Modules

Run extension API discovery:

```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture discover --force
```

**Output**: `.plan/project-architecture/derived-data.json`

Always overwrites existing data to ensure fresh discovery.

---

## Step 1.5: Review Build Profiles (Maven Only)

**Condition**: Only if any module has `build_systems` containing `maven`.

Check derived-data.json for NO-MATCH-FOUND profiles in `modules.*.metadata.profiles`.

**If Maven modules exist AND unmatched profiles found**:

Load skill `pm-dev-java:manage-maven-profiles` and follow its workflow to:
1. Ask user about each unmatched profile (Ignore/Skip/Map)
2. Apply configuration via `run_config` commands
3. Re-run discovery to apply changes

**If no Maven modules OR no unmatched profiles** → Skip to Step 2.

---

## Step 2: Initialize Enrichment File

Check if `llm-enriched.json` already exists:

```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture init --check
```

**If file exists**, ask user:

```yaml
AskUserQuestion:
  question: "llm-enriched.json already exists. What do you want to do?"
  header: "Enrichment"
  options:
    - label: "Skip"
      description: "Keep existing enrichments, continue to next step"
    - label: "Replace"
      description: "Discard existing enrichments, start fresh"
  multiSelect: false
```

**Based on user choice**:

| Choice | Command |
|--------|---------|
| Skip | Proceed to Step 3 |
| Replace | `architecture init --force` |

**If file does not exist**:

```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture init
```

This creates empty enrichment structure for each module found in derived-data.json.

---

## Step 3: Load Discovered Data

Load the raw discovered data in TOON format:

```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture derived
```

**Output (TOON)**:
```toon
project:
  name: {project-name}
  root: {project-root}

modules[N]{name,path,build_systems,readme,description}:
module-a,module-a,maven,module-a/README.adoc,Description from pom
module-b,module-b,maven,,
module-c,module-c,maven+npm,module-c/README.md,
```

The output shows raw extension API discovery results:
- Module names and paths
- Build systems (joined with `+` for hybrid)
- README paths (if detected)
- Descriptions (from build files, if available)

Read referenced READMEs for modules that have them:
```bash
Read {readme path from derived output}
```

---

## Step 4: Enrich Project Description

Based on the README and module descriptions, write a 1-2 sentence project description.

**Always provide reasoning** to document the source:

```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture \
  enrich project --description "{extracted project description}" \
  --reasoning "{source: README.md introduction | inferred from module names | pom.xml description}"
```

**Reasoning examples**:
- "From README.md first paragraph"
- "Inferred from module structure and pom.xml descriptions"
- "Aggregated from child module responsibilities"

---

## Step 5: Get Module List

```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture modules
```

**Output (TOON)**:
```toon
modules[N]:
  - module-a
  - module-b
  - ...
```

---

## Step 6: Enrich Each Module

**For each module in the list**, execute Steps 6a-6e:

### Step 6a: Read Module Documentation

Get raw discovered data for the module:

```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture derived-module --name {module-name}
```

**Output (TOON)**:
```toon
module:
  name: {module-name}
  path: {module-path}
  build_systems: maven

paths:
  readme: {module}/README.adoc
  sources[N]:
    - src/main/java
  tests[N]:
    - src/test/java

metadata:
  description: {from build file if available}
  packaging: jar

packages[N]{name,path,package_info}:
com.example.core,src/main/java/com/example/core,src/main/java/com/example/core/package-info.java
com.example.util,src/main/java/com/example/util,

dependencies[N]:
  - groupId:artifactId:scope
```

Read the referenced documentation:
```bash
Read {paths.readme}
Read {package_info path}  # for packages with package_info
```

If no documentation available, sample 2-3 source files from packages.

### Step 6b: Determine Module Purpose

Analyze to determine `purpose` value:

| Signal | Purpose Value |
|--------|---------------|
| packaging=jar, no runtime deps | `library` |
| Quarkus extension annotations | `extension` |
| Build-time processor, deployment | `deployment` |
| Main class, application entry | `runtime` |
| packaging=pom at root | `parent` |
| Only test files | `integration-tests` |
| JMH benchmarks | `benchmark` |

### Step 6c: Write Module Responsibility

Write 1-3 sentences describing what the module does.

**Good examples**:
- "Validates JWT tokens from multiple identity providers using a pipeline approach"
- "Provides Quarkus CDI integration for the core validation library"
- "Coordinates build configuration for all child modules"

**Bad examples** (avoid):
- "Core module" (too vague)
- "Main package for processing" (says nothing)

**Always provide reasoning** for traceability:

```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture \
  enrich module --name {module-name} \
  --responsibility "{1-3 sentence description}" \
  --responsibility-reasoning "{source: README overview | package-info.java | inferred from class names}" \
  --purpose {purpose-value} \
  --purpose-reasoning "{signal: packaging=jar with no main class | Quarkus extension annotations}"
```

**Reasoning examples**:
- Responsibility: "From module README.adoc overview section"
- Responsibility: "Inferred from package-info.java and primary class names"
- Purpose: "packaging=jar, no runtime dependencies, no main class"
- Purpose: "Contains @BuildStep annotations indicating Quarkus deployment module"

### Step 6d: Identify Key Packages

Select 2-4 architecturally significant packages per module.

For each key package, write 1-2 sentence description:

**Good examples**:
- "Provides the token validation pipeline with pluggable validators"
- "Contains domain models for tokens, claims, and validation results"

```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture \
  enrich package --module {module-name} \
  --package {full.package.name} \
  --description "{1-2 sentence description}"
```

Repeat for each key package (2-4 packages).

### Step 6d-2: Identify Key Dependencies

From the derived-module output (Step 6a), analyze the `dependencies` list to identify architecturally significant dependencies.

**Selection criteria** - Include dependencies that:
- Define the module's core technology (frameworks, runtime libraries)
- Provide essential APIs the module builds upon
- Define the runtime contract (provided-scope dependencies like `quarkus-core`, `servlet-api`)
- Are unique to this module's purpose (not ubiquitous across all modules)

**Exclude from key dependencies**:
- Ubiquitous utilities (commons-lang, guava, slf4j) unless central to module purpose
- Pure code-generation tools (lombok) that don't define architecture
- Standard test frameworks (junit, mockito) - implied by testing profile
- Transitive dependencies not directly used

**Include despite scope**:
- Provided-scope framework APIs (these define the runtime contract)
- Test-scope if architecturally distinctive (testcontainers, wiremock, arquillian)
- Compile-scope annotation libraries that define contracts (jspecify, checker-qual)

**For multi-module projects**, also identify `internal_dependencies`:
- Other modules in this project that this module depends on
- Look for dependencies with same groupId as the project

**Good examples**:
- `io.quarkus:quarkus-core` (provided) - Defines runtime framework contract
- `jakarta.servlet-api` (provided) - Defines servlet container contract
- `org.eclipse.microprofile.jwt:microprofile-jwt-auth-api` - Core API this module implements
- `org.jspecify:jspecify` - Defines null-safety contract
- `org.testcontainers:testcontainers` (test) - Architecturally distinctive testing approach

**Bad examples** (exclude):
- `org.junit.jupiter:junit-jupiter-api` - Standard test framework, implied by profile
- `org.projectlombok:lombok` - Code generation tool, doesn't define architecture
- `org.slf4j:slf4j-api` - Ubiquitous logging facade
- `org.apache.commons:commons-lang3` - Generic utility, not distinctive

```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture \
  enrich dependencies --module {module-name} \
  --key "{comma-separated list of groupId:artifactId}" \
  --internal "{comma-separated list of internal module names}" \
  --reasoning "{why these dependencies are architecturally significant}"
```

**Example**:
```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture \
  enrich dependencies --module oauth-sheriff-core \
  --key "io.quarkus:quarkus-core,org.eclipse.microprofile.jwt:microprofile-jwt-auth-api" \
  --reasoning "Quarkus runtime and MicroProfile JWT API define the module's integration contract"
```

For single-module projects or leaf modules with no internal dependencies, omit `--internal`.

### Step 6e: Determine Skills by Profile

Assign skills organized by execution profile (implementation, unit-testing, integration-testing, benchmark-testing, documentation).

**Step 6e.1: List Available Domains**

Get all configured skill domains:

```bash
python3 .plan/execute-script.py plan-marshall:manage-plan-marshall-config:plan-marshall-config \
  skill-domains list
```

**Output (TOON)**:
```toon
status: success
domains:
  - system
  - java
  - javascript
  - plan-marshall-plugin-dev
count: 4
```

**Step 6e.2: Determine Applicable Domain**

Based on the module analysis from Steps 6a-6d, determine which domain applies.

**Signals to consider** (from derived-module output and documentation):
- Source file extensions (`.java`, `.kt`, `.js`, `.ts`)
- Dependencies (groupId/artifactId patterns, npm packages)
- Framework annotations in code
- Build file configurations
- Module description and purpose

**Examples of domain applicability**:

| Signal | Domain |
|--------|--------|
| Java sources, javax/jakarta imports | `java` |
| Kotlin sources, kotlin-stdlib | `java` (or future `kotlin`) |
| JavaScript/TypeScript sources | `javascript` |
| plugin.json, marketplace structure | `plan-marshall-plugin-dev` |
| Quarkus dependencies | `java` + CUI-specific if CUI deps present |
| `doc/` or `docs/` with `.adoc` files | `documentation` (as additional profile) |

**Step 6e.3: Get Skills by Profile**

For the applicable domain, get the pre-assembled skills by profile:

```bash
python3 .plan/execute-script.py plan-marshall:manage-plan-marshall-config:plan-marshall-config \
  get-skills-by-profile --domain {domain-key}
```

**Output (TOON)**:
```toon
status: success
domain: java
skills_by_profile:
  implementation:
    - pm-dev-java:java-core
    - pm-dev-java:java-null-safety
    - pm-dev-java:java-lombok
    - pm-dev-java:java-cdi
    - pm-dev-java:java-maintenance
  unit-testing:
    - pm-dev-java:java-core
    - pm-dev-java:java-null-safety
    - pm-dev-java:java-lombok
    - pm-dev-java:junit-core
    - pm-dev-java:junit-integration
  integration-testing:
    - pm-dev-java:java-core
    - pm-dev-java:java-null-safety
    - pm-dev-java:java-lombok
    - pm-dev-java:junit-core
    - pm-dev-java:junit-integration
  benchmark-testing:
    - pm-dev-java:java-core
    - pm-dev-java:java-null-safety
    - pm-dev-java:java-lombok
    - pm-dev-java:junit-core
    - pm-dev-java:junit-integration
```

**Step 6e.4: Filter Skills Based on Module Signals**

Optionally filter the skills based on module signals:

| Module Signal | Action |
|---------------|--------|
| No CDI annotations | Remove `java-cdi` from implementation |
| No Lombok annotations | Remove `java-lombok` from all profiles |
| No integration tests (*IT.java) | Remove integration-testing profile entirely |
| No benchmarks (*Benchmark.java) | Remove benchmark-testing profile entirely |

**Step 6e.4b: Add Documentation Profile (Cross-Domain)**

If module has AsciiDoc documentation, add `documentation` profile from `documentation` domain:

**Detection**: Check if module has `doc/` or `docs/` directory with `.adoc` files.

```bash
# Check for AsciiDoc docs in module
ls {module-path}/doc/*.adoc 2>/dev/null || ls {module-path}/docs/*.adoc 2>/dev/null
```

**If `.adoc` files found**:

1. Get documentation skills:
```bash
python3 .plan/execute-script.py plan-marshall:manage-plan-marshall-config:plan-marshall-config \
  get-skills-by-profile --domain documentation
```

2. Add `documentation` profile to the module's `skills_by_profile`:
```json
{
  "implementation": [...],
  "module_testing": [...],
  "documentation": ["pm-documents:ref-documentation", "pm-documents:manage-adr", ...]
}
```

**Key principle**: Documentation is a separate task type (like testing), not a variant of implementation. A module can have both `implementation` AND `documentation` profiles.

**Step 6e.5: Apply Skills by Profile**

**Include reasoning** about filtering decisions:

```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture \
  enrich skills-by-profile --module {module-name} \
  --skills-json '{"implementation": ["pm-dev-java:java-core", "pm-dev-java:java-cdi"], "module_testing": ["pm-dev-java:java-core", "pm-dev-java:junit-core"]}' \
  --reasoning "{filtering applied: removed java-lombok (no @Data annotations found), kept java-cdi (CDI beans present)}"
```

**Reasoning examples**:
- "Base java domain, no filtering applied"
- "Removed java-cdi (no CDI annotations), removed integration_testing (no *IT.java files)"
- "Added cui-testing-http based on MockWebServer test dependency"
- "Added documentation profile (module has doc/*.adoc files)"

The `skills_by_profile` structure flows to:
1. **solution-outline**: Copies to deliverable as `skills-implementation`, `skills-testing`, etc.
2. **task-plan**: Uses pre-resolved skills when creating tasks (no runtime lookup)

---

## Step 7: Verify Enrichment

After all modules are enriched, verify completeness:

```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture info
```

Check that:
- [ ] Every module has non-empty `responsibility`
- [ ] Every module has valid `purpose`
- [ ] Every module has 2-4 `key_packages` with descriptions
- [ ] Every module has `key_dependencies` identified (unless module has no compile-scope deps)
- [ ] Every module has `skills_by_profile` with at least `implementation` and `unit-testing` profiles

If any module is incomplete → return to Step 6 for that module.

---

## Step 8: Output Summary

Display completion summary:

```
Architecture analysis complete.

Project: {project name}
Modules enriched: {count}

Files created:
  - .plan/project-architecture/derived-data.json
  - .plan/project-architecture/llm-enriched.json

Next steps:
  - Solution outline will use this data for placement decisions
  - Run 'architecture.py module --name X' to query module details
```

---

## Error Handling

### Extension API Not Available

```
Error: Extension API not found.

Resolution:
1. Verify domain bundles installed (pm-dev-java, pm-dev-frontend)
2. Run /marshall-steward to configure project
3. Re-run this skill
```

### No Modules Discovered

```
Error: No modules found in project.

Resolution:
1. Verify project has build files (pom.xml, package.json, build.gradle)
2. Check that domain bundle matches project type
3. Re-run discovery
```

### Documentation Not Found

If module has no README or package-info:
1. Analyze source code directly
2. Check parent module for context
3. Note in responsibility: "Inferred from source analysis"

---

## Deferred Loading

For detailed specifications, load on demand:

| Reference | When to Load |
|-----------|--------------|
| [manage-api.md](standards/manage-api.md) | Manage commands (setup, read raw, enrich) |
| [client-api.md](standards/client-api.md) | Client commands (merged data for consumers) |
| [architecture-persistence.md](standards/architecture-persistence.md) | Field schemas and formats |
| [architecture-workflow.md](standards/architecture-workflow.md) | Workflow phase details |
| [documentation-sources.md](standards/documentation-sources.md) | Reading strategy details |
| `pm-dev-java:manage-maven-profiles` | Maven profile classification (Step 1.5) |

---

## Integration

This skill is invoked by:
- **marshall-steward wizard** Step 6b (after discovery)
- **Direct activation** when regenerating project structure

Output is consumed by:
- **solution-outline** Step 0 (module placement)
- **task-plan** (command resolution)

---

## Post-Implementation Enrichment

During verification phase or after implementation, capture learnings:

### Add Implementation Tip

```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture \
  enrich tip --module {module-name} --tip "Use @ApplicationScoped for singleton services"
```

### Add Learned Insight

```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture \
  enrich insight --module {module-name} --insight "Heavy validation happens in boundary layer"
```

### Add Best Practice

```bash
python3 .plan/execute-script.py plan-marshall:analyze-project-architecture:architecture \
  enrich best-practice --module {module-name} --practice "Always validate tokens before extracting claims"
```

These accumulate over time and are included in module output for future reference.

Related Skills

analyze-rust-optimizations

16
from diegosouzapw/awesome-omni-skill

This skill performs thorough analysis of Rust libraries to find optimization opportunities. It should be used when reviewing Rust code for performance improvements, memory efficiency, or when profiling indicates bottlenecks. Focuses on runtime performance and memory usage through dynamic profiling tools and static code analysis.

analyze-pr-performance

16
from diegosouzapw/awesome-omni-skill

Analyze code review pipeline performance for a specific PR. Use when investigating slow PRs, identifying bottlenecks, or debugging performance issues in code reviews.

analyze

16
from diegosouzapw/awesome-omni-skill

Deep analysis and investigation

analyze-m1-module-for-migration

16
from diegosouzapw/awesome-omni-skill

Systematically analyze a Magento 1 module to determine its purpose, usage, and migration requirements for Magento 2. Use when you need to decide whether to migrate a M1 module, find alternatives, or skip it.

analyze-function

16
from diegosouzapw/awesome-omni-skill

Deep line-by-line analysis of a function or method. Explains what each line does, why it's written that way, performance implications, edge cases, and design patterns. Use when user says "analyze-function", "analyze {function}", "deep dive on {function}", or "explain {function} line by line".

analyze-friction

16
from diegosouzapw/awesome-omni-skill

Orchestrate 3-stage friction analysis workflow across conversations. Extracts raw friction, abstracts patterns, and presents for approval. Use when user wants to analyze conversation history for improvement opportunities.

analyze-codebase

16
from diegosouzapw/awesome-omni-skill

Analyze a codebase to generate a comprehensive architecture and structure report. Use when user wants to understand a codebase, explore project structure, or generate analysis.

analyze-code

16
from diegosouzapw/awesome-omni-skill

Deep code analysis using consultant agent. Identifies technical debt, risks, and improvement opportunities.

analyze-code-structure

16
from diegosouzapw/awesome-omni-skill

Examine code organization and identify structural patterns. Use when reviewing module design.

analyze-architecture

16
from diegosouzapw/awesome-omni-skill

Comprehensive brownfield architecture analysis for existing codebases. Discovers structure, identifies patterns, assesses quality, calculates production readiness, and provides actionable recommendations. Use when analyzing existing codebases to understand architecture, assess quality, or prepare for modernization.

aidb-architecture

16
from diegosouzapw/awesome-omni-skill

Comprehensive architectural reference for AIDB core and MCP integration. Covers 6-layer architecture (MCP, Service, Session, Adapter, DAP Client, Protocol), component organization, data flow patterns, and design decisions. Use when explaining overall system design or understanding how layers interact.

agentic_architecture

16
from diegosouzapw/awesome-omni-skill

Enforces high-level architectural thinking, separation of concerns, and scalability checks before coding.