angular-agents-skills 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +205 -0
  3. package/adapters/claude/index.ts +53 -0
  4. package/adapters/codex/index.ts +55 -0
  5. package/adapters/copilot/index.ts +45 -0
  6. package/adapters/cursor/index.ts +51 -0
  7. package/adapters/opencode/index.ts +63 -0
  8. package/agents/angular-architect/agent.md +143 -0
  9. package/agents/angular-architect/configs/claude.yaml +3 -0
  10. package/agents/angular-architect/configs/codex.yaml +2 -0
  11. package/agents/angular-architect/configs/opencode.yaml +5 -0
  12. package/agents/angular-migrator/agent.md +146 -0
  13. package/agents/angular-migrator/configs/claude.yaml +3 -0
  14. package/agents/angular-migrator/configs/codex.yaml +2 -0
  15. package/agents/angular-migrator/configs/opencode.yaml +5 -0
  16. package/agents/angular-reviewer/agent.md +74 -0
  17. package/agents/angular-reviewer/configs/claude.yaml +3 -0
  18. package/agents/angular-reviewer/configs/codex.yaml +2 -0
  19. package/agents/angular-reviewer/configs/opencode.yaml +5 -0
  20. package/dist/adapters/claude/index.js +45 -0
  21. package/dist/adapters/codex/index.js +46 -0
  22. package/dist/adapters/copilot/index.js +37 -0
  23. package/dist/adapters/cursor/index.js +43 -0
  24. package/dist/adapters/opencode/index.js +53 -0
  25. package/dist/src/cli.js +293 -0
  26. package/dist/src/index.js +6 -0
  27. package/dist/src/registry.js +13 -0
  28. package/dist/src/types.js +1 -0
  29. package/package.json +45 -0
  30. package/skills/architecture/injection-tokens/SKILL.md +82 -0
  31. package/skills/architecture/overlay-animation-lifecycle/SKILL.md +98 -0
  32. package/skills/components/content-projection-ng/SKILL.md +89 -0
  33. package/skills/components/dynamic-components/SKILL.md +74 -0
  34. package/skills/components/modern-host-bindings/SKILL.md +71 -0
  35. package/skills/components/viewchild-contentchild-signals/SKILL.md +66 -0
  36. package/skills/libraries/library-versioning/SKILL.md +49 -0
  37. package/skills/libraries/monorepo-ng-packagr/SKILL.md +69 -0
  38. package/skills/libraries/standalone-component-library/SKILL.md +103 -0
  39. package/skills/performance/control-flow-syntax/SKILL.md +94 -0
  40. package/skills/performance/defer-blocks/SKILL.md +83 -0
  41. package/skills/quality/pr-reviewer/SKILL.md +131 -0
  42. package/skills/quality/vitest-angular-components/SKILL.md +88 -0
  43. package/skills/reactivity/signals-effects/SKILL.md +63 -0
  44. package/skills/reactivity/signals-inputs-outputs/SKILL.md +76 -0
  45. package/skills/reactivity/signals-state-management/SKILL.md +70 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dayerlin Bustamante
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,205 @@
1
+ # Angular AI
2
+
3
+ > AI-agnostic Angular agents and skills for any coding tool.
4
+
5
+ Install production-ready Angular knowledge into your AI coding agent. Agents and skills are defined once and installed into OpenCode, Claude Code, Codex, or any future tool.
6
+
7
+ ---
8
+
9
+ ## Architecture
10
+
11
+ ```
12
+ angular-agent-skills/
13
+ ├── agents/ # Universal agent definitions
14
+ │ ├── angular-architect/
15
+ │ │ ├── agent.yaml # Metadata (name, description, triggers, skills)
16
+ │ │ └── agent.md # Instructions (pure markdown)
17
+ │ ├── angular-migrator/
18
+ │ │ ├── agent.yaml
19
+ │ │ └── agent.md
20
+ │ └── angular-reviewer/
21
+ │ ├── agent.yaml
22
+ │ └── agent.md
23
+ ├── adapters/ # AI-specific format converters
24
+ │ ├── opencode.ts
25
+ │ ├── claude.ts
26
+ │ └── codex.ts
27
+ ├── skills/ # Reusable Angular knowledge
28
+ │ ├── architecture/
29
+ │ ├── components/
30
+ │ ├── libraries/
31
+ │ ├── performance/
32
+ │ ├── quality/
33
+ │ └── reactivity/
34
+ ├── src/ # CLI and core logic
35
+ │ ├── cli.ts
36
+ │ ├── registry.ts
37
+ │ ├── types.ts
38
+ │ └── index.ts
39
+ └── tests/ # Test suite
40
+ ```
41
+
42
+ ### Universal Agent Format
43
+
44
+ Each agent is a directory with two files:
45
+
46
+ - **`agent.yaml`** — Universal metadata (name, description, triggers, skills)
47
+ - **`agent.md`** — Pure markdown instructions (no frontmatter, no tool-specific syntax)
48
+
49
+ This is the single source of truth. Agents never depend on any specific AI tool.
50
+
51
+ ### Adapters
52
+
53
+ Adapters transform universal agents into tool-specific formats:
54
+
55
+ | Adapter | Output Format | Install Path |
56
+ |---|---|---|
57
+ | `opencode` | Markdown + YAML frontmatter | `.opencode/agents/` |
58
+ | `claude` | Markdown + YAML frontmatter | `.claude/agents/` |
59
+ | `codex` | TOML | `.codex/agents/` |
60
+
61
+ Adding a new AI tool requires only creating a new adapter file — no changes to agents or core logic.
62
+
63
+ ---
64
+
65
+ ## Installation
66
+
67
+ ### As CLI
68
+
69
+ ```bash
70
+ npm install -g angular-ai
71
+ ```
72
+
73
+ ### As dependency
74
+
75
+ ```bash
76
+ npm install angular-ai
77
+ ```
78
+
79
+ ---
80
+
81
+ ## Usage
82
+
83
+ ### Install an agent
84
+
85
+ ```bash
86
+ # For OpenCode
87
+ npx angular-ai install agent angular-architect --ai opencode
88
+
89
+ # For Claude Code
90
+ npx angular-ai install agent angular-architect --ai claude
91
+
92
+ # For Codex
93
+ npx angular-ai install agent angular-architect --ai codex
94
+ ```
95
+
96
+ ### Install for all tools
97
+
98
+ ```bash
99
+ npx angular-ai install agent angular-architect --all
100
+ ```
101
+
102
+ ### Custom target directory
103
+
104
+ ```bash
105
+ npx angular-ai install agent angular-architect \
106
+ --ai opencode \
107
+ --agent ./my-agents
108
+ ```
109
+
110
+ ### List available agents
111
+
112
+ ```bash
113
+ npx angular-ai list agents
114
+ ```
115
+
116
+ ### List available adapters
117
+
118
+ ```bash
119
+ npx angular-ai list adapters
120
+ ```
121
+
122
+ ---
123
+
124
+ ## Agents
125
+
126
+ | Agent | Purpose | Triggers |
127
+ |---|---|---|
128
+ | `angular-architect` | Generate components, services, libraries | create component, generar, scaffold |
129
+ | `angular-migrator` | Migrate legacy code to modern patterns | migrate, migrar, convert to signals |
130
+ | `angular-reviewer` | Review code for best practices | review, revisar, code review |
131
+
132
+ ---
133
+
134
+ ## Skills
135
+
136
+ Skills are reusable knowledge modules that agents reference:
137
+
138
+ | Category | Skills |
139
+ |---|---|
140
+ | **Architecture** | injection-tokens, overlay-animation-lifecycle |
141
+ | **Components** | dynamic-components, modern-host-bindings, content-projection-ng, viewchild-contentchild-signals |
142
+ | **Libraries** | standalone-component-library, monorepo-ng-packagr, library-versioning |
143
+ | **Performance** | defer-blocks, control-flow-syntax |
144
+ | **Quality** | pr-reviewer, vitest-angular-components |
145
+ | **Reactivity** | signals-state-management, signals-inputs-outputs, signals-effects |
146
+
147
+ ---
148
+
149
+ ## Development
150
+
151
+ ```bash
152
+ # Install dependencies
153
+ npm install
154
+
155
+ # Build
156
+ npm run build
157
+
158
+ # Run tests
159
+ npm test
160
+
161
+ # Type check
162
+ npm run lint
163
+ ```
164
+
165
+ ---
166
+
167
+ ## Adding a New Adapter
168
+
169
+ 1. Create `adapters/my-tool.ts`:
170
+ ```typescript
171
+ import type { Adapter, AdapterOutput, InstallOptions, UniversalAgent } from '../src/types.js';
172
+
173
+ export const myToolAdapter: Adapter = {
174
+ name: 'my-tool',
175
+ description: 'My AI Tool',
176
+ defaultDir: '.my-tool/agents',
177
+
178
+ generate(agent: UniversalAgent): AdapterOutput {
179
+ // Transform agent to tool-specific format
180
+ return {
181
+ filename: `${agent.metadata.name}.ext`,
182
+ content: `...`,
183
+ };
184
+ },
185
+
186
+ getInstallPath(options: InstallOptions): string {
187
+ const base = options.targetDir || this.defaultDir;
188
+ return `${base}/${options.agentName}.ext`;
189
+ },
190
+ };
191
+ ```
192
+
193
+ 2. Register in `src/cli.ts`:
194
+ ```typescript
195
+ import { myToolAdapter } from '../adapters/my-tool.js';
196
+ registerAdapter(myToolAdapter);
197
+ ```
198
+
199
+ 3. Done. The CLI now supports `--ai my-tool`.
200
+
201
+ ---
202
+
203
+ ## License
204
+
205
+ MIT
@@ -0,0 +1,53 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { parse as parseYaml } from 'yaml';
4
+ import type { Adapter, AdapterOutput, InstallOptions, UniversalAgent } from '../../src/types.js';
5
+
6
+ const DEFAULT_CONFIG: Record<string, unknown> = {
7
+ description: 'Angular agent for Claude',
8
+ name: 'angular-agent',
9
+ tools: 'Read, Grep, Glob, Edit, Write, Bash',
10
+ };
11
+
12
+ function loadConfigFromAgent(agentBasePath: string, ai: string): Record<string, unknown> {
13
+ const configPath = join(agentBasePath, 'configs', `${ai}.yaml`);
14
+
15
+ try {
16
+ return parseYaml(readFileSync(configPath, 'utf-8'));
17
+ } catch {
18
+ return {};
19
+ }
20
+ }
21
+
22
+ export function createClaudeAdapter(): Adapter {
23
+ return {
24
+ name: 'claude',
25
+ description: 'Claude Code',
26
+ defaultDir: '.claude/agents',
27
+ extension: 'md',
28
+
29
+ generate(agent: UniversalAgent, config?: Record<string, unknown>): AdapterOutput {
30
+ const agentConfig = loadConfigFromAgent(agent.basePath, 'claude');
31
+ const cfg = { ...DEFAULT_CONFIG, ...agentConfig, ...config };
32
+
33
+ const frontmatter = [
34
+ '---',
35
+ `name: ${cfg.name || agent.metadata.name}`,
36
+ `description: ${cfg.description || agent.metadata.description}`,
37
+ `tools: ${cfg.tools || 'Read, Grep, Glob, Edit, Write, Bash'}`,
38
+ '---',
39
+ '',
40
+ ];
41
+
42
+ return {
43
+ filename: `${agent.metadata.name}.md`,
44
+ content: frontmatter.join('\n') + agent.instructions.content,
45
+ };
46
+ },
47
+
48
+ getInstallPath(name: string, targetDir?: string): string {
49
+ const base = targetDir || this.defaultDir;
50
+ return `${base}/${name}.${this.extension}`;
51
+ },
52
+ };
53
+ }
@@ -0,0 +1,55 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { parse as parseYaml } from 'yaml';
4
+ import type { Adapter, AdapterOutput, InstallOptions, UniversalAgent } from '../../src/types.js';
5
+
6
+ const DEFAULT_CONFIG: Record<string, unknown> = {
7
+ description: 'Angular agent for Codex',
8
+ name: 'angular-agent',
9
+ };
10
+
11
+ function loadConfigFromAgent(agentBasePath: string, ai: string): Record<string, unknown> {
12
+ const configPath = join(agentBasePath, 'configs', `${ai}.yaml`);
13
+
14
+ try {
15
+ return parseYaml(readFileSync(configPath, 'utf-8'));
16
+ } catch {
17
+ return {};
18
+ }
19
+ }
20
+
21
+ export function createCodexAdapter(): Adapter {
22
+ return {
23
+ name: 'codex',
24
+ description: 'OpenAI Codex CLI',
25
+ defaultDir: '.codex/agents',
26
+ extension: 'toml',
27
+
28
+ generate(agent: UniversalAgent, config?: Record<string, unknown>): AdapterOutput {
29
+ const agentConfig = loadConfigFromAgent(agent.basePath, 'codex');
30
+ const cfg = { ...DEFAULT_CONFIG, ...agentConfig, ...config };
31
+
32
+ const escapedInstructions = agent.instructions.content
33
+ .replace(/\\/g, '\\\\')
34
+ .replace(/"/g, '\\"')
35
+ .replace(/\n/g, '\\n');
36
+
37
+ const content = [
38
+ `name = "${cfg.name || agent.metadata.name}"`,
39
+ `description = "${cfg.description || agent.metadata.description}"`,
40
+ `developer_instructions = "${escapedInstructions}"`,
41
+ '',
42
+ ].join('\n');
43
+
44
+ return {
45
+ filename: `${agent.metadata.name}.toml`,
46
+ content,
47
+ };
48
+ },
49
+
50
+ getInstallPath(name: string, targetDir?: string): string {
51
+ const base = targetDir || this.defaultDir;
52
+ return `${base}/${name}.${this.extension}`;
53
+ },
54
+ };
55
+ }
@@ -0,0 +1,45 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { parse as parseYaml } from 'yaml';
4
+ import type { Adapter, AdapterOutput, InstallOptions, UniversalAgent } from '../../src/types.js';
5
+
6
+ const DEFAULT_CONFIG: Record<string, unknown> = {
7
+ description: 'Angular agent for GitHub Copilot',
8
+ name: 'angular-agent',
9
+ };
10
+
11
+ function loadConfigFromAgent(agentBasePath: string, ai: string): Record<string, unknown> {
12
+ const configPath = join(agentBasePath, 'configs', `${ai}.yaml`);
13
+
14
+ try {
15
+ return parseYaml(readFileSync(configPath, 'utf-8'));
16
+ } catch {
17
+ return {};
18
+ }
19
+ }
20
+
21
+ export function createCopilotAdapter(): Adapter {
22
+ return {
23
+ name: 'copilot',
24
+ description: 'GitHub Copilot',
25
+ defaultDir: '.github',
26
+ extension: 'md',
27
+
28
+ generate(agent: UniversalAgent, config?: Record<string, unknown>): AdapterOutput {
29
+ const agentConfig = loadConfigFromAgent(agent.basePath, 'copilot');
30
+ const cfg = { ...DEFAULT_CONFIG, ...agentConfig, ...config };
31
+
32
+ const header = `# ${cfg.name || agent.metadata.name}\n\n${cfg.description || agent.metadata.description}\n\n`;
33
+
34
+ return {
35
+ filename: `copilot-instructions-${agent.metadata.name}.md`,
36
+ content: header + agent.instructions.content,
37
+ };
38
+ },
39
+
40
+ getInstallPath(name: string, targetDir?: string): string {
41
+ const base = targetDir || this.defaultDir;
42
+ return `${base}/${name}-instructions.${this.extension}`;
43
+ },
44
+ };
45
+ }
@@ -0,0 +1,51 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { parse as parseYaml } from 'yaml';
4
+ import type { Adapter, AdapterOutput, InstallOptions, UniversalAgent } from '../../src/types.js';
5
+
6
+ const DEFAULT_CONFIG: Record<string, unknown> = {
7
+ description: 'Angular agent for Cursor',
8
+ name: 'angular-agent',
9
+ };
10
+
11
+ function loadConfigFromAgent(agentBasePath: string, ai: string): Record<string, unknown> {
12
+ const configPath = join(agentBasePath, 'configs', `${ai}.yaml`);
13
+
14
+ try {
15
+ return parseYaml(readFileSync(configPath, 'utf-8'));
16
+ } catch {
17
+ return {};
18
+ }
19
+ }
20
+
21
+ export function createCursorAdapter(): Adapter {
22
+ return {
23
+ name: 'cursor',
24
+ description: 'Cursor AI IDE',
25
+ defaultDir: '.cursor/rules',
26
+ extension: 'mdc',
27
+
28
+ generate(agent: UniversalAgent, config?: Record<string, unknown>): AdapterOutput {
29
+ const agentConfig = loadConfigFromAgent(agent.basePath, 'cursor');
30
+ const cfg = { ...DEFAULT_CONFIG, ...agentConfig, ...config };
31
+
32
+ const frontmatter = [
33
+ '---',
34
+ `description: ${cfg.description || agent.metadata.description}`,
35
+ 'alwaysApply: false',
36
+ '---',
37
+ '',
38
+ ];
39
+
40
+ return {
41
+ filename: `${agent.metadata.name}.mdc`,
42
+ content: frontmatter.join('\n') + agent.instructions.content,
43
+ };
44
+ },
45
+
46
+ getInstallPath(name: string, targetDir?: string): string {
47
+ const base = targetDir || this.defaultDir;
48
+ return `${base}/${name}.${this.extension}`;
49
+ },
50
+ };
51
+ }
@@ -0,0 +1,63 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { join, dirname } from 'node:path';
3
+ import { parse as parseYaml } from 'yaml';
4
+ import type { Adapter, AdapterOutput, InstallOptions, UniversalAgent } from '../../src/types.js';
5
+
6
+ const DEFAULT_CONFIG: Record<string, unknown> = {
7
+ description: 'Angular agent for OpenCode',
8
+ mode: 'subagent',
9
+ permission: {
10
+ edit: 'allow',
11
+ bash: 'ask',
12
+ },
13
+ };
14
+
15
+ function loadConfigFromAgent(agentBasePath: string, ai: string): Record<string, unknown> {
16
+ const configPath = join(agentBasePath, 'configs', `${ai}.yaml`);
17
+
18
+ try {
19
+ return parseYaml(readFileSync(configPath, 'utf-8'));
20
+ } catch {
21
+ return {};
22
+ }
23
+ }
24
+
25
+ export function createOpenCodeAdapter(): Adapter {
26
+ return {
27
+ name: 'opencode',
28
+ description: 'OpenCode AI coding agent',
29
+ defaultDir: '.opencode/agents',
30
+ extension: 'md',
31
+
32
+ generate(agent: UniversalAgent, config?: Record<string, unknown>): AdapterOutput {
33
+ const agentConfig = loadConfigFromAgent(agent.basePath, 'opencode');
34
+ const cfg = { ...DEFAULT_CONFIG, ...agentConfig, ...config };
35
+
36
+ const frontmatter = [
37
+ '---',
38
+ `description: ${cfg.description || agent.metadata.description}`,
39
+ `mode: ${cfg.mode || 'subagent'}`,
40
+ ];
41
+
42
+ if (cfg.permission) {
43
+ frontmatter.push('permission:');
44
+ const perm = cfg.permission as Record<string, string>;
45
+ for (const [key, value] of Object.entries(perm)) {
46
+ frontmatter.push(` ${key}: ${value}`);
47
+ }
48
+ }
49
+
50
+ frontmatter.push('---', '');
51
+
52
+ return {
53
+ filename: `${agent.metadata.name}.md`,
54
+ content: frontmatter.join('\n') + agent.instructions.content,
55
+ };
56
+ },
57
+
58
+ getInstallPath(name: string, targetDir?: string): string {
59
+ const base = targetDir || this.defaultDir;
60
+ return `${base}/${name}.${this.extension}`;
61
+ },
62
+ };
63
+ }
@@ -0,0 +1,143 @@
1
+ # Angular Architect
2
+
3
+ You are an Angular architect who generates new components, services, and libraries following best practices and project conventions.
4
+
5
+ ## Core Skills
6
+
7
+ Load and follow the relevant skills from the project's `skills/` directory. The agent.yaml file lists which skills are relevant for this agent.
8
+
9
+ ## Generation Templates
10
+
11
+ ### Component Generation
12
+
13
+ When creating a new component, use this structure:
14
+
15
+ ```typescript
16
+ // component-name.component.ts
17
+ import { Component, input, output, computed, signal } from '@angular/core';
18
+
19
+ @Component({
20
+ selector: 'app-component-name',
21
+ standalone: true,
22
+ template: ``,
23
+ styles: []
24
+ })
25
+ export class ComponentNameComponent {
26
+ // Inputs (signal-based)
27
+ readonly data = input.required<Type>();
28
+ readonly disabled = input(false);
29
+
30
+ // Outputs
31
+ readonly itemClick = output<Item>();
32
+
33
+ // State
34
+ private readonly _internalState = signal<Type>();
35
+
36
+ // Computed
37
+ readonly derivedValue = computed(() => this.data().property);
38
+
39
+ // Methods
40
+ handleClick(item: Item): void {
41
+ this.itemClick.emit(item);
42
+ }
43
+ }
44
+ ```
45
+
46
+ ### Service Generation
47
+
48
+ ```typescript
49
+ // service-name.service.ts
50
+ import { Injectable, inject, signal } from '@angular/core';
51
+ import { SOME_CONFIG, SomeConfig } from './tokens';
52
+
53
+ @Injectable({ providedIn: 'root' })
54
+ export class ServiceNameService {
55
+ private readonly config = inject(SOME_CONFIG);
56
+ private readonly _state = signal<StateType>(initialState);
57
+
58
+ readonly state = this._state.asReadonly();
59
+
60
+ updateState(value: StateType): void {
61
+ this._state.set(value);
62
+ }
63
+ }
64
+ ```
65
+
66
+ ### InjectionToken Generation
67
+
68
+ ```typescript
69
+ // tokens.ts
70
+ import { InjectionToken } from '@angular/core';
71
+
72
+ export interface ComponentConfig {
73
+ // Configuration options
74
+ }
75
+
76
+ export const COMPONENT_CONFIG = new InjectionToken<ComponentConfig>('COMPONENT_CONFIG');
77
+
78
+ // Default factory
79
+ export function provideComponentConfig(config: Partial<ComponentConfig>): Provider {
80
+ return {
81
+ provide: COMPONENT_CONFIG,
82
+ useValue: { ...defaultConfig, ...config }
83
+ };
84
+ }
85
+ ```
86
+
87
+ ### Library Generation
88
+
89
+ For a new library, create:
90
+
91
+ ```
92
+ libs/
93
+ feature-name/
94
+ src/
95
+ lib/
96
+ components/
97
+ services/
98
+ tokens/
99
+ models/
100
+ index.ts
101
+ public-api.ts
102
+ ng-package.json
103
+ package.json
104
+ tsconfig.lib.json
105
+ ```
106
+
107
+ ## Decision Tree
108
+
109
+ When user requests generation:
110
+
111
+ 1. **What type?**
112
+ - Component → Use component template
113
+ - Service → Use service template
114
+ - Library → Use library structure
115
+ - Module (legacy) → Warn and suggest standalone
116
+
117
+ 2. **What features?**
118
+ - Needs configuration? → Create InjectionToken
119
+ - Needs state? → Use signals
120
+ - Needs lazy loading? → Add @defer in template
121
+ - Has children? → Add content projection
122
+
123
+ 3. **Where to place?**
124
+ - Check existing project structure
125
+ - Follow naming conventions
126
+ - Place in appropriate module/feature
127
+
128
+ ## Output
129
+
130
+ Always generate:
131
+ 1. Complete TypeScript file(s)
132
+ 2. Test file (if requested)
133
+ 3. Usage example
134
+ 4. Any required tokens or providers
135
+
136
+ ## Rules
137
+
138
+ - Always use standalone components
139
+ - Always use signal-based inputs/outputs
140
+ - Always use functional `inject()` instead of constructor
141
+ - Always include proper TypeScript types
142
+ - Follow existing project conventions (check `skills/` for reference)
143
+ - Write in Spanish when the user communicates in Spanish
@@ -0,0 +1,3 @@
1
+ name: angular-architect
2
+ description: Generate Angular architecture, components, and libraries following project conventions.
3
+ tools: Read, Grep, Glob, Edit, Write, Bash
@@ -0,0 +1,2 @@
1
+ name: angular-architect
2
+ description: Generate Angular architecture, components, and libraries following project conventions.
@@ -0,0 +1,5 @@
1
+ description: Generate Angular architecture, components, and libraries following project conventions.
2
+ mode: subagent
3
+ permission:
4
+ edit: allow
5
+ bash: ask