Agent Capability Analysis
The javascript-ember skill by jaredlander is an open-source community AI agent skill for Claude Code and other IDE workflows, helping agents execute tasks with better context, repeatability, and domain-specific guidance.
Ideal Agent Persona
Perfect for Frontend Agents needing advanced Ember.js development capabilities for modern web applications
Core Value
Empowers agents to write modern, performant Ember.js applications following Ember Octane conventions and current best practices, utilizing context7 MCP for project-specific conventions and architectural patterns, and leveraging Chrome extensions for optimizing web application performance
↓ Capabilities Granted for javascript-ember
! Prerequisites & Limits
- Requires context7 MCP for project-specific documentation
- Ember.js and Chrome extension expertise necessary
- Limited to Ember Octane conventions and current best practices
Browser Sandbox Environment
⚡️ Ready to unleash?
Experience this Agent in a zero-setup browser environment powered by WebContainers. No installation required.
javascript-ember
Install javascript-ember, an AI agent skill for AI agent workflows and automation. Works with Claude Code, Cursor, and Windsurf with one-command setup.
Expert Ember.js Development
Write modern, performant Ember.js applications following Ember Octane conventions and current best practices.
Critical First Step: Use context7 MCP
ALWAYS use context7 MCP before writing or editing ANY Ember code - Before generating, modifying, or reviewing any Ember code, you MUST use the context7 MCP to check for relevant documentation. Context7 provides project-specific conventions, architectural patterns, coding standards, and technical decisions that override these general guidelines.
When to Use context7
Use context7 MCP in these situations:
- Before writing any new Ember component, route, service, or model
- Before modifying existing Ember code
- When implementing features that might have project-specific patterns
- When unsure about architectural decisions
- Before suggesting refactors or improvements
How to Use context7
javascript1// Example: Check for Ember component patterns before creating a component 2// Use the context7 MCP to search for relevant documentation 3// Query examples: 4// - "ember component patterns" 5// - "ember routing conventions" 6// - "ember data models" 7// - "ember testing standards" 8// - "glimmer component lifecycle" 9 10// Apply the documentation from context7 to your implementation
If context7 returns relevant documentation, follow it EXACTLY even if it conflicts with this skill's general guidance. Project-specific conventions always take precedence.
Core Principles
- Embrace Ember Octane - Use Glimmer components, tracked properties, and native classes
- Convention over configuration - Follow Ember's resolver patterns and file structure
- Use the platform - Prefer native JavaScript features over framework-specific abstractions when possible
- Composition through services and modifiers - Extract reusable logic into services and UI behavior into modifiers
- Data down, actions up (DDAU) - Maintain clear data flow patterns
Context7 MCP Workflow
Before implementing any Ember code, follow this workflow:
-
Query context7 - Search for relevant documentation using specific terms:
- Component type (e.g., "ember glimmer component")
- Feature area (e.g., "ember routing", "ember data")
- Specific pattern (e.g., "form validation", "authentication")
-
Review results - Read any returned documentation carefully
- Note project-specific naming conventions
- Identify required patterns or abstractions
- Check for mandatory testing requirements
- Look for deprecated approaches to avoid
-
Apply documentation - Implement code following context7 guidance
- Use project-specific utilities and helpers
- Follow established architectural patterns
- Match existing code style and structure
- Include required metadata or annotations
-
Fall back to general patterns - If context7 has no relevant docs, use this skill's patterns
- Apply standard Ember Octane conventions
- Follow community best practices
- Use examples from this skill as templates
Remember: context7 documentation always overrides this skill's general guidance.
Context7 Query Examples
When implementing different types of Ember code, use these query patterns:
For Components:
- "ember component patterns"
- "ember component architecture"
- "glimmer component conventions"
- "[specific component type]" (e.g., "button component", "form component")
- "component props" or "component arguments"
- "component lifecycle"
- "component testing"
For Routes:
- "ember routing patterns"
- "ember route conventions"
- "route data loading"
- "route guards" or "route authentication"
- "nested routes"
- "query parameters"
For Ember Data:
- "ember data models"
- "ember data adapters"
- "ember data serializers"
- "api integration"
- "data relationships"
- "data layer patterns"
For Services:
- "ember services"
- "service patterns"
- "shared state management"
- "[specific service]" (e.g., "authentication service", "api service")
For Testing:
- "ember testing"
- "component testing"
- "integration tests"
- "acceptance tests"
- "test patterns"
- "test data" or "fixtures"
For Styling:
- "ember styling"
- "css conventions"
- "component styles"
- "tailwind" or "[css framework]"
When Editing Existing Code:
- Search for the specific feature: "user profile", "login form", etc.
- Search for the pattern you're implementing: "form validation", "dropdown menu"
- Search for utilities you might need: "validation utilities", "date helpers"
Modern Ember Patterns (Octane+)
Glimmer Components
javascript1// app/components/user-profile.js 2import Component from '@glimmer/component'; 3import { tracked } from '@glimmer/tracking'; 4import { action } from '@ember/object'; 5import { inject as service } from '@ember/service'; 6 7export default class UserProfileComponent extends Component { 8 @service currentUser; 9 @service router; 10 11 @tracked isEditing = false; 12 @tracked formData = null; 13 14 constructor(owner, args) { 15 super(owner, args); 16 // Use constructor for one-time setup 17 this.formData = { ...this.args.user }; 18 } 19 20 @action 21 toggleEdit() { 22 this.isEditing = !this.isEditing; 23 if (this.isEditing) { 24 this.formData = { ...this.args.user }; 25 } 26 } 27 28 @action 29 async saveUser(event) { 30 event.preventDefault(); 31 32 try { 33 await this.args.onSave(this.formData); 34 this.isEditing = false; 35 } catch (error) { 36 // Handle error 37 console.error('Save failed:', error); 38 } 39 } 40 41 @action 42 updateField(field, event) { 43 this.formData = { 44 ...this.formData, 45 [field]: event.target.value 46 }; 47 } 48}
handlebars1{{! app/components/user-profile.hbs }} 2<div class="user-profile"> 3 {{#if this.isEditing}} 4 <form {{on "submit" this.saveUser}}> 5 <label> 6 Name: 7 <input 8 type="text" 9 value={{this.formData.name}} 10 {{on "input" (fn this.updateField "name")}} 11 /> 12 </label> 13 14 <label> 15 Email: 16 <input 17 type="email" 18 value={{this.formData.email}} 19 {{on "input" (fn this.updateField "email")}} 20 /> 21 </label> 22 23 <button type="submit">Save</button> 24 <button type="button" {{on "click" this.toggleEdit}}>Cancel</button> 25 </form> 26 {{else}} 27 <div class="profile-display"> 28 <h2>{{@user.name}}</h2> 29 <p>{{@user.email}}</p> 30 31 {{#if this.currentUser.canEdit}} 32 <button {{on "click" this.toggleEdit}}>Edit Profile</button> 33 {{/if}} 34 </div> 35 {{/if}} 36</div>
Tracked Properties and Getters
javascript1import Component from '@glimmer/component'; 2import { tracked } from '@glimmer/tracking'; 3import { cached } from '@glimmer/tracking'; 4 5export default class DataGridComponent extends Component { 6 @tracked sortColumn = 'name'; 7 @tracked sortDirection = 'asc'; 8 @tracked filterText = ''; 9 10 // Use @cached for expensive computations that depend on tracked properties 11 @cached 12 get filteredData() { 13 const { filterText } = this; 14 if (!filterText) return this.args.data; 15 16 const lower = filterText.toLowerCase(); 17 return this.args.data.filter(item => 18 item.name.toLowerCase().includes(lower) || 19 item.email.toLowerCase().includes(lower) 20 ); 21 } 22 23 @cached 24 get sortedData() { 25 const data = [...this.filteredData]; 26 const { sortColumn, sortDirection } = this; 27 28 return data.sort((a, b) => { 29 const aVal = a[sortColumn]; 30 const bVal = b[sortColumn]; 31 const result = aVal < bVal ? -1 : aVal > bVal ? 1 : 0; 32 return sortDirection === 'asc' ? result : -result; 33 }); 34 } 35}
Services
javascript1// app/services/notification.js 2import Service from '@ember/service'; 3import { tracked } from '@glimmer/tracking'; 4import { action } from '@ember/object'; 5 6export default class NotificationService extends Service { 7 @tracked notifications = []; 8 9 @action 10 add(message, type = 'info', duration = 5000) { 11 const id = Date.now() + Math.random(); 12 const notification = { id, message, type }; 13 14 this.notifications = [...this.notifications, notification]; 15 16 if (duration > 0) { 17 setTimeout(() => this.remove(id), duration); 18 } 19 20 return id; 21 } 22 23 @action 24 remove(id) { 25 this.notifications = this.notifications.filter(n => n.id !== id); 26 } 27 28 @action 29 success(message, duration) { 30 return this.add(message, 'success', duration); 31 } 32 33 @action 34 error(message, duration = 10000) { 35 return this.add(message, 'error', duration); 36 } 37 38 @action 39 clear() { 40 this.notifications = []; 41 } 42}
Custom Modifiers
javascript1// app/modifiers/click-outside.js 2import { modifier } from 'ember-modifier'; 3 4export default modifier((element, [callback]) => { 5 function handleClick(event) { 6 if (!element.contains(event.target)) { 7 callback(event); 8 } 9 } 10 11 document.addEventListener('click', handleClick, true); 12 13 return () => { 14 document.removeEventListener('click', handleClick, true); 15 }; 16});
handlebars1{{! Usage }} 2<div {{click-outside this.closeDropdown}} class="dropdown"> 3 {{! dropdown content }} 4</div>
Routing
Route Definitions
javascript1// app/router.js 2import EmberRouter from '@ember/routing/router'; 3import config from 'my-app/config/environment'; 4 5export default class Router extends EmberRouter { 6 location = config.locationType; 7 rootURL = config.rootURL; 8} 9 10Router.map(function () { 11 this.route('dashboard', { path: '/' }); 12 13 this.route('users', function () { 14 this.route('index', { path: '/' }); 15 this.route('new'); 16 this.route('user', { path: '/:user_id' }, function () { 17 this.route('edit'); 18 this.route('settings'); 19 }); 20 }); 21 22 this.route('not-found', { path: '/*path' }); 23});
Route Class
javascript1// app/routes/users/user.js 2import Route from '@ember/routing/route'; 3import { inject as service } from '@ember/service'; 4 5export default class UsersUserRoute extends Route { 6 @service store; 7 @service router; 8 9 async model(params) { 10 try { 11 return await this.store.findRecord('user', params.user_id, { 12 include: 'profile,settings' 13 }); 14 } catch (error) { 15 if (error.errors?.[0]?.status === '404') { 16 this.router.transitionTo('not-found'); 17 } 18 throw error; 19 } 20 } 21 22 // Redirect if user doesn't have permission 23 afterModel(model) { 24 if (!this.currentUser.canViewUser(model)) { 25 this.router.transitionTo('dashboard'); 26 } 27 } 28 29 // Reset controller state on exit 30 resetController(controller, isExiting) { 31 if (isExiting) { 32 controller.setProperties({ 33 queryParams: {}, 34 isEditing: false 35 }); 36 } 37 } 38}
Loading and Error States
javascript1// app/routes/users/user/loading.js 2import Route from '@ember/routing/route'; 3 4export default class UsersUserLoadingRoute extends Route {}
handlebars1{{! app/templates/users/user/loading.hbs }} 2<div class="loading-spinner"> 3 <p>Loading user...</p> 4</div>
Ember Data
Models
javascript1// app/models/user.js 2import Model, { attr, hasMany, belongsTo } from '@ember-data/model'; 3 4export default class UserModel extends Model { 5 @attr('string') name; 6 @attr('string') email; 7 @attr('date') createdAt; 8 @attr('boolean', { defaultValue: true }) isActive; 9 @attr('number') loginCount; 10 11 @belongsTo('profile', { async: true, inverse: 'user' }) profile; 12 @hasMany('post', { async: true, inverse: 'author' }) posts; 13 14 // Computed properties still work but use native getters 15 get displayName() { 16 return this.name || this.email?.split('@')[0] || 'Anonymous'; 17 } 18 19 get isNewUser() { 20 const daysSinceCreation = (Date.now() - this.createdAt) / (1000 * 60 * 60 * 24); 21 return daysSinceCreation < 7; 22 } 23}
Custom Adapters
javascript1// app/adapters/application.js 2import JSONAPIAdapter from '@ember-data/adapter/json-api'; 3import { inject as service } from '@ember/service'; 4 5export default class ApplicationAdapter extends JSONAPIAdapter { 6 @service session; 7 8 host = 'https://api.example.com'; 9 namespace = 'v1'; 10 11 get headers() { 12 const headers = {}; 13 14 if (this.session.isAuthenticated) { 15 headers['Authorization'] = `Bearer ${this.session.data.authenticated.token}`; 16 } 17 18 return headers; 19 } 20 21 handleResponse(status, headers, payload, requestData) { 22 if (status === 401) { 23 this.session.invalidate(); 24 } 25 26 return super.handleResponse(status, headers, payload, requestData); 27 } 28}
Custom Serializers
javascript1// app/serializers/application.js 2import JSONAPISerializer from '@ember-data/serializer/json-api'; 3 4export default class ApplicationSerializer extends JSONAPISerializer { 5 // Normalize date strings to Date objects 6 normalizeDateFields(hash) { 7 const dateFields = ['createdAt', 'updatedAt', 'publishedAt']; 8 9 dateFields.forEach(field => { 10 if (hash[field]) { 11 hash[field] = new Date(hash[field]); 12 } 13 }); 14 15 return hash; 16 } 17 18 normalize(modelClass, resourceHash) { 19 this.normalizeDateFields(resourceHash.attributes || {}); 20 return super.normalize(modelClass, resourceHash); 21 } 22}
Testing
Component Integration Tests
javascript1// tests/integration/components/user-profile-test.js 2import { module, test } from 'qunit'; 3import { setupRenderingTest } from 'ember-qunit'; 4import { render, click, fillIn } from '@ember/test-helpers'; 5import { hbs } from 'ember-cli-htmlbars'; 6 7module('Integration | Component | user-profile', function (hooks) { 8 setupRenderingTest(hooks); 9 10 test('it displays user information', async function (assert) { 11 this.set('user', { 12 name: 'Jane Doe', 13 email: 'jane@example.com' 14 }); 15 16 await render(hbs`<UserProfile @user={{this.user}} />`); 17 18 assert.dom('h2').hasText('Jane Doe'); 19 assert.dom('p').hasText('jane@example.com'); 20 }); 21 22 test('it allows editing when canEdit is true', async function (assert) { 23 this.owner.lookup('service:current-user').canEdit = true; 24 this.set('user', { 25 name: 'Jane Doe', 26 email: 'jane@example.com' 27 }); 28 this.set('onSave', () => {}); 29 30 await render(hbs` 31 <UserProfile @user={{this.user}} @onSave={{this.onSave}} /> 32 `); 33 34 await click('button:contains("Edit Profile")'); 35 36 assert.dom('form').exists(); 37 assert.dom('input[type="text"]').hasValue('Jane Doe'); 38 39 await fillIn('input[type="text"]', 'Jane Smith'); 40 await click('button[type="submit"]'); 41 42 assert.dom('form').doesNotExist(); 43 }); 44});
Route/Acceptance Tests
javascript1// tests/acceptance/user-flow-test.js 2import { module, test } from 'qunit'; 3import { visit, currentURL, click, fillIn } from '@ember/test-helpers'; 4import { setupApplicationTest } from 'ember-qunit'; 5import { setupMirage } from 'ember-cli-mirage/test-support'; 6 7module('Acceptance | user flow', function (hooks) { 8 setupApplicationTest(hooks); 9 setupMirage(hooks); 10 11 test('visiting /users and creating a new user', async function (assert) { 12 await visit('/users'); 13 14 assert.strictEqual(currentURL(), '/users'); 15 assert.dom('h1').hasText('Users'); 16 17 await click('a:contains("New User")'); 18 assert.strictEqual(currentURL(), '/users/new'); 19 20 await fillIn('[data-test-name-input]', 'John Doe'); 21 await fillIn('[data-test-email-input]', 'john@example.com'); 22 await click('[data-test-submit]'); 23 24 assert.strictEqual(currentURL(), '/users/1'); 25 assert.dom('[data-test-user-name]').hasText('John Doe'); 26 }); 27});
Performance Optimization
See references/performance.md for comprehensive optimization strategies.
Quick Reference
| Problem | Solution |
|---|---|
| Unnecessary component re-renders | Use @cached for expensive getters |
| Large lists | Use ember-collection or virtual scrolling |
| Slow Ember Data queries | Optimize includes, use custom serializers |
| Bundle size | Use route-based code splitting, lazy engines |
| Memory leaks | Properly clean up in willDestroy, cancel timers |
Critical Anti-patterns
javascript1// ❌ Mutating tracked properties directly 2this.items.push(newItem); // Won't trigger reactivity 3 4// ✅ Replace the entire array 5this.items = [...this.items, newItem]; 6 7// ❌ Creating new functions in templates 8{{on "click" (fn this.handleClick item)}} 9 10// ✅ Use actions or stable references 11@action handleItemClick(item) { /* ... */ } 12{{on "click" (fn this.handleItemClick item)}} 13 14// ❌ Not using @cached for expensive computations 15get expensiveComputation() { 16 return this.data.filter(/* complex logic */); 17} 18 19// ✅ Use @cached 20@cached 21get expensiveComputation() { 22 return this.data.filter(/* complex logic */); 23}
Project Structure
app/
├── components/ # Glimmer components
│ └── user-profile/
│ ├── component.js
│ ├── index.hbs
│ └── styles.css
├── controllers/ # Controllers (use sparingly in Octane)
├── helpers/ # Template helpers
├── modifiers/ # Custom modifiers
├── models/ # Ember Data models
├── routes/ # Route classes
├── services/ # Services
├── templates/ # Route templates
├── adapters/ # Ember Data adapters
├── serializers/ # Ember Data serializers
├── styles/ # Global styles
└── app.js
tests/
├── integration/ # Component tests
├── unit/ # Unit tests (models, services, etc.)
└── acceptance/ # Full application tests
Tooling Recommendations
| Category | Tool | Notes |
|---|---|---|
| CLI | ember-cli | Official tooling |
| Testing | QUnit + ember-qunit | Built-in, well integrated |
| Linting | ESLint + ember-template-lint | Catch template issues |
| Formatting | Prettier | Use with ember-template-lint |
| Mocking | ember-cli-mirage | API mocking for tests |
| State management | Services + tracked | Built-in, no extra deps |
| HTTP | fetch or ember-fetch | Native or polyfilled |
Common Patterns
Form Handling with Validation
javascript1// app/components/registration-form.js 2import Component from '@glimmer/component'; 3import { tracked } from '@glimmer/tracking'; 4import { action } from '@ember/object'; 5import { inject as service } from '@ember/service'; 6 7export default class RegistrationFormComponent extends Component { 8 @service notification; 9 10 @tracked email = ''; 11 @tracked password = ''; 12 @tracked confirmPassword = ''; 13 @tracked errors = {}; 14 @tracked isSubmitting = false; 15 16 get isValid() { 17 return ( 18 this.email && 19 this.password.length >= 8 && 20 this.password === this.confirmPassword && 21 Object.keys(this.errors).length === 0 22 ); 23 } 24 25 @action 26 updateEmail(event) { 27 this.email = event.target.value; 28 this.validateEmail(); 29 } 30 31 @action 32 updatePassword(event) { 33 this.password = event.target.value; 34 this.validatePassword(); 35 } 36 37 @action 38 updateConfirmPassword(event) { 39 this.confirmPassword = event.target.value; 40 this.validateConfirmPassword(); 41 } 42 43 validateEmail() { 44 const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; 45 46 if (!this.email) { 47 this.errors = { ...this.errors, email: 'Email is required' }; 48 } else if (!emailRegex.test(this.email)) { 49 this.errors = { ...this.errors, email: 'Invalid email format' }; 50 } else { 51 const { email, ...rest } = this.errors; 52 this.errors = rest; 53 } 54 } 55 56 validatePassword() { 57 if (this.password.length < 8) { 58 this.errors = { ...this.errors, password: 'Password must be at least 8 characters' }; 59 } else { 60 const { password, ...rest } = this.errors; 61 this.errors = rest; 62 } 63 64 // Re-validate confirm password if it's filled 65 if (this.confirmPassword) { 66 this.validateConfirmPassword(); 67 } 68 } 69 70 validateConfirmPassword() { 71 if (this.password !== this.confirmPassword) { 72 this.errors = { ...this.errors, confirmPassword: 'Passwords do not match' }; 73 } else { 74 const { confirmPassword, ...rest } = this.errors; 75 this.errors = rest; 76 } 77 } 78 79 @action 80 async submit(event) { 81 event.preventDefault(); 82 83 if (!this.isValid) return; 84 85 this.isSubmitting = true; 86 87 try { 88 await this.args.onSubmit({ 89 email: this.email, 90 password: this.password 91 }); 92 93 this.notification.success('Registration successful!'); 94 } catch (error) { 95 this.notification.error(error.message || 'Registration failed'); 96 } finally { 97 this.isSubmitting = false; 98 } 99 } 100}
Infinite Scroll with Modifier
javascript1// app/modifiers/infinite-scroll.js 2import { modifier } from 'ember-modifier'; 3 4export default modifier((element, [callback], { threshold = 200 }) => { 5 let isLoading = false; 6 7 function handleScroll() { 8 if (isLoading) return; 9 10 const { scrollTop, scrollHeight, clientHeight } = element; 11 const distanceFromBottom = scrollHeight - (scrollTop + clientHeight); 12 13 if (distanceFromBottom < threshold) { 14 isLoading = true; 15 callback().finally(() => { 16 isLoading = false; 17 }); 18 } 19 } 20 21 element.addEventListener('scroll', handleScroll, { passive: true }); 22 23 return () => { 24 element.removeEventListener('scroll', handleScroll); 25 }; 26});
TypeScript Support
Ember has strong TypeScript support. Enable it with:
bash1ember install ember-cli-typescript
typescript1// app/components/user-profile.ts 2import Component from '@glimmer/component'; 3import { tracked } from '@glimmer/tracking'; 4import { action } from '@ember/object'; 5import type { TOC } from '@ember/component/template-only'; 6 7interface UserProfileArgs { 8 user: { 9 name: string; 10 email: string; 11 avatarUrl?: string; 12 }; 13 onSave: (data: UserData) => Promise<void>; 14 canEdit?: boolean; 15} 16 17interface UserData { 18 name: string; 19 email: string; 20} 21 22export default class UserProfileComponent extends Component<UserProfileArgs> { 23 @tracked isEditing = false; 24 @tracked formData: UserData | null = null; 25 26 @action 27 async saveUser(event: SubmitEvent): Promise<void> { 28 event.preventDefault(); 29 30 if (!this.formData) return; 31 32 await this.args.onSave(this.formData); 33 this.isEditing = false; 34 } 35} 36 37// Template-only component signature 38export interface GreetingSignature { 39 Element: HTMLDivElement; 40 Args: { 41 name: string; 42 }; 43} 44 45const Greeting: TOC<GreetingSignature> = <template> 46 <div ...attributes>Hello {{@name}}!</div> 47</template>; 48 49export default Greeting;
Remember: Always Use context7 MCP First!
Before implementing any Ember code, query the context7 MCP for relevant project documentation. Context7 provides project-specific guidelines that always supersede these general best practices.
Quick context7 Query Guide
Before writing components:
- Query: "ember component patterns", "glimmer component", "component architecture"
Before routing work:
- Query: "ember routing", "route patterns", "navigation"
Before Ember Data:
- Query: "ember data models", "api integration", "data layer"
Before tests:
- Query: "ember testing", "test patterns", "test requirements"
When editing existing code:
- Query the specific feature or pattern you're working with
The context7 MCP is your source of truth for this project's Ember conventions.
FAQ & Installation Steps
These questions and steps mirror the structured data on this page for better search understanding.
? Frequently Asked Questions
What is javascript-ember?
Perfect for Frontend Agents needing advanced Ember.js development capabilities for modern web applications A Chrome extension to fix speed issues in the Freshbooks website
How do I install javascript-ember?
Run the command: npx killer-skills add jaredlander/freshbooks-speed/javascript-ember. It works with Cursor, Windsurf, VS Code, Claude Code, and 19+ other IDEs.
What are the use cases for javascript-ember?
Key use cases include: Debugging speed issues in web applications using Chrome extensions, Generating Ember.js code following current best practices, Optimizing Freshbooks website performance with custom Chrome extensions.
Which IDEs are compatible with javascript-ember?
This skill is compatible with Cursor, Windsurf, VS Code, Trae, Claude Code, OpenClaw, Aider, Codex, OpenCode, Goose, Cline, Roo Code, Kiro, Augment Code, Continue, GitHub Copilot, Sourcegraph Cody, and Amazon Q Developer. Use the Killer-Skills CLI for universal one-command installation.
Are there any limitations for javascript-ember?
Requires context7 MCP for project-specific documentation. Ember.js and Chrome extension expertise necessary. Limited to Ember Octane conventions and current best practices.
↓ How To Install
-
1. Open your terminal
Open the terminal or command line in your project directory.
-
2. Run the install command
Run: npx killer-skills add jaredlander/freshbooks-speed/javascript-ember. The CLI will automatically detect your IDE or AI agent and configure the skill.
-
3. Start using the skill
The skill is now active. Your AI agent can use javascript-ember immediately in the current project.