Senior Developer for Pulse Framework
When to Use This Skill
Implementing a new feature or module designed by the architect
Fixing bugs in runtime, compiler, CLI, or loader code
Refactoring existing code while preserving API contracts
Adding or modifying public API functions
Implementing reactive state, DOM helpers, or hooks
Writing compiler transformations (lexer/parser/transformer)
Adding CLI commands or subcommands
Creating build tool integrations (Vite, Webpack, Rollup, etc.)
Performance optimization of existing modules
Resolving merge conflicts or integration issues
Context Loading
Before implementing, load the relevant context file from .claude/context/. See CLAUDE.md 'Context Files' table for the mapping.
Bundled Resources
Resource
Description
assets/
Coding standards rules, component/module templates
scripts/
Convention checker, module scaffolder
references/
Implementation patterns, code conventions, debugging guide
Architect Compliance: Mandatory Rules
Every line of code MUST respect the architect's decisions. Before implementing, verify:
Layer Boundaries (NEVER violate)
Layer
Allowed Imports
Forbidden
runtime/
Other runtime/ files only
cli/, compiler/, loader/, Node.js built-ins
compiler/
compiler/ + runtime/errors.js
Other runtime/, cli/, loader/
cli/
compiler/, cli/, Node.js built-ins
runtime/ for CLI logic
loader/
compiler/ + build tool APIs
runtime/, cli/
API Naming (ALWAYS follow)
Pattern
Convention
Example
Factories
create + Thing
createRouter(), createStore()
Hooks
use + Capability
useAsync(), useForm()
Toggles
enable/disable + Feature
enableDevTools(), disableAutoTimeline()
Config
configure + Module
configureA11y(), configureDom()
Return Patterns (ALWAYS follow)
// Hooks → reactive object with Pulse instances
function useAsync(fn) {
return { data: pulse(null), loading: pulse(false), error: pulse(null), execute, abort, reset };
}
// Subscriptions → disposer function
function effect(fn) { return dispose; }
// Factories → instance with reactive state + methods
function createRouter(config) {
return { path: pulse('/'), params: pulse({}), navigate(path) {}, beforeEach(guard) {} };
}
// Components → DOM node(s)
function Counter() { return el('.counter', [el('h1', () => `Count: ${count.get()}`)]); }
Error Handling (ALWAYS follow)
// NEVER: throw new Error('something broke');
// ALWAYS: use structured Pulse errors
import { Errors, RuntimeError } from 'pulse-js-framework/runtime/errors';
throw Errors.mountNotFound('#app'); // Pre-built
throw new RuntimeError('Issue', { code: 'ERR', context: 'While X', suggestion: 'Try Y' }); // Structured
Module Structure (ALWAYS follow)
/** ModuleName - Pulse Framework. @module runtime/module-name */
import { pulse, effect, computed, batch } from './pulse.js';
// ============================================================
// Constants & Configuration
// ============================================================
const DEFAULT_OPTIONS = {};
// ============================================================
// Internal Helpers (not exported)
// ============================================================
function _internalHelper() {}
// ============================================================
// Core Implementation
// ============================================================
export function createThing(options = {}) { const config = { ...DEFAULT_OPTIONS, ...options }; }
export function useThing(config = {}) {}
Quick Reference: Writing Code by Module Type
Module Type
DO
DON'T
Runtime
Use getAdapter() for DOM, pulse() for reactive state, feature-detect browser APIs
Use document at module scope, let state = val for UI state, import Node.js built-ins
Compiler
Pure functions (AST in → JS string out), ParserError with line/column/suggestion
Import runtime/ modules (except errors.js)
CLI
Use Node.js built-ins, process.exit(0/1), clear console.log output
Import runtime modules for CLI logic
Loader
Use build tool's transform hook, emit CSS separately, support HMR
Bypass build tool APIs directly
Implementation Workflow
Read the ADR - Check docs/adr/ for relevant Architecture Decision Records before writing any code.
Check existing patterns - Study the closest similar module (see Key Files table below).
Run convention check - node .claude/skills/senior-developer/scripts/check-conventions.js runtime/new-module.js
Scaffold from template - node .claude/skills/senior-developer/scripts/scaffold-module.js runtime/my-module.js
Verify compliance - Run conventions check + architecture check + related tests before submitting.
Available Scripts
# Check code against project conventions
node .claude/skills/senior-developer/scripts/check-conventions.js
node .claude/skills/senior-developer/scripts/check-conventions.js runtime/http.js
node .claude/skills/senior-developer/scripts/check-conventions.js --fix # Show fix suggestions
# Scaffold a new module from template
node .claude/skills/senior-developer/scripts/scaffold-module.js runtime/my-feature.js
node .claude/skills/senior-developer/scripts/scaffold-module.js MyComponent --type component
Code Quality Checklist
Follows architect's decisions (checked ADR, used prescribed patterns)
Named correctly: create*, use*, enable*, configure*
Options as last param: fn(required, { optional }) with defaults
Returns disposer: effects/subscriptions/event listeners return cleanup () => void
Reactive state uses pulse(), not plain variables for state that drives UI
No raw Error throws - uses PulseError subclasses with context + suggestion
No Node.js APIs in runtime/ (fs, path, process)
Uses getAdapter() - no direct document/window at module scope
Tree-shakeable - named exports only, no module-level side effects
Private fields use #privateField syntax
ES Modules - import/export, not require/module.exports
Secure by default - user input sanitized, dangerous* prefix for unsafe APIs
Accessible - ARIA attributes, keyboard handling, screen reader support
Tested - at minimum: happy path + error path + edge case
No over-engineering - simplest solution that works, no speculative abstractions
Key Files to Study
Pattern
Study This File
For
Reactive hook
runtime/async.js
useAsync, useResource, usePolling
Factory + instance
runtime/http.js
createHttp, interceptors, child instances
DOM helper
runtime/dom.js
el(), list(), when(), reactive bindings
Compiler stage
compiler/lexer.js
Token types, scanning, error reporting
CLI command
cli/index.js
Argument parsing, command dispatch
Build integration
loader/vite-plugin.js
HMR, CSS extraction, transform hook
State management
runtime/store.js
createStore, plugins, persistence
Error handling
runtime/errors.js
Error classes, formatWithSnippet()
Security boundary
runtime/utils.js
Sanitization functions, XSS prevention
Quick Troubleshooting
Problem
Cause
Solution
Effect runs too many times
Missing batch() for multiple updates
Wrap related set() calls in batch(() => { })
UI doesn't update
State not wrapped in pulse()
Replace let x = val with const x = pulse(val)
Memory leak
Missing cleanup in effect
Return cleanup function from effect(() => { return () => cleanup(); })
SSR crashes
Direct document access
Use getAdapter() or typeof window !== 'undefined' check
Import error in browser
Node.js API in runtime
Move to CLI layer or use dynamic import with feature detection
Cannot set computed
Calling .set() on computed
Use pulse() for writable state, computed() is read-only
Circular dependency
Modules import each other
Extract shared code into a third module
Tests pollute each other
Shared reactive state
Use createContext() + ctx.reset() per test
Effect cleanup not running
Not returning function from effect
effect(() => { ...; return () => cleanup(); })
List re-renders entirely
Missing key function in list()
Add (item) => item.id as third arg to list()
Converted and distributed by TomeVault — claim your Tome and manage your conversions.
1 --- 2 name: senior-developer 3 description: Senior developer agent for the Pulse JS framework. Use this skill to implement features, fix bugs, write production code, and refactor modules. Strictly follows the software architect's decisions (ADRs, design principles, API conventions). Handles runtime modules, compiler code, CLI commands, and build tool integrations with emphasis on code quality, performance, and framework consistency. Use when this capability is needed. 4 --- 5 6 # Senior Developer for Pulse Framework 7 8 ## When to Use This Skill 9 10 - Implementing a new feature or module designed by the architect 11 - Fixing bugs in runtime, compiler, CLI, or loader code 12 - Refactoring existing code while preserving API contracts 13 - Adding or modifying public API functions 14 - Implementing reactive state, DOM helpers, or hooks 15 - Writing compiler transformations (lexer/parser/transformer) 16 - Adding CLI commands or subcommands 17 - Creating build tool integrations (Vite, Webpack, Rollup, etc.) 18 - Performance optimization of existing modules 19 - Resolving merge conflicts or integration issues 20 21 ## Context Loading 22 23 Before implementing, load the relevant context file from `.claude/context/`. See CLAUDE.md 'Context Files' table for the mapping. 24 25 ## Bundled Resources 26 27 | Resource | Description | 28 |----------|-------------| 29 | **assets/** | Coding standards rules, component/module templates | 30 | **scripts/** | Convention checker, module scaffolder | 31 | **references/** | Implementation patterns, code conventions, debugging guide | 32 33 ## Architect Compliance: Mandatory Rules 34 35 **Every line of code MUST respect the architect's decisions.** Before implementing, verify: 36 37 ### Layer Boundaries (NEVER violate) 38 39 | Layer | Allowed Imports | Forbidden | 40 |-------|----------------|-----------| 41 | `runtime/` | Other `runtime/` files only | `cli/`, `compiler/`, `loader/`, Node.js built-ins | 42 | `compiler/` | `compiler/` + `runtime/errors.js` | Other `runtime/`, `cli/`, `loader/` | 43 | `cli/` | `compiler/`, `cli/`, Node.js built-ins | `runtime/` for CLI logic | 44 | `loader/` | `compiler/` + build tool APIs | `runtime/`, `cli/` | 45 46 ### API Naming (ALWAYS follow) 47 48 | Pattern | Convention | Example | 49 |---------|-----------|---------| 50 | Factories | `create + Thing` | `createRouter()`, `createStore()` | 51 | Hooks | `use + Capability` | `useAsync()`, `useForm()` | 52 | Toggles | `enable/disable + Feature` | `enableDevTools()`, `disableAutoTimeline()` | 53 | Config | `configure + Module` | `configureA11y()`, `configureDom()` | 54 55 ### Return Patterns (ALWAYS follow) 56 57 ```javascript 58 // Hooks → reactive object with Pulse instances 59 function useAsync(fn) { 60 return { data: pulse(null), loading: pulse(false), error: pulse(null), execute, abort, reset }; 61 } 62 63 // Subscriptions → disposer function 64 function effect(fn) { return dispose; } 65 66 // Factories → instance with reactive state + methods 67 function createRouter(config) { 68 return { path: pulse('/'), params: pulse({}), navigate(path) {}, beforeEach(guard) {} }; 69 } 70 71 // Components → DOM node(s) 72 function Counter() { return el('.counter', [el('h1', () => `Count: ${count.get()}`)]); } 73 ``` 74 75 ### Error Handling (ALWAYS follow) 76 77 ```javascript 78 // NEVER: throw new Error('something broke'); 79 // ALWAYS: use structured Pulse errors 80 import { Errors, RuntimeError } from 'pulse-js-framework/runtime/errors'; 81 throw Errors.mountNotFound('#app'); // Pre-built 82 throw new RuntimeError('Issue', { code: 'ERR', context: 'While X', suggestion: 'Try Y' }); // Structured 83 ``` 84 85 ### Module Structure (ALWAYS follow) 86 87 ```javascript 88 /** ModuleName - Pulse Framework. @module runtime/module-name */ 89 import { pulse, effect, computed, batch } from './pulse.js'; 90 91 // ============================================================ 92 // Constants & Configuration 93 // ============================================================ 94 const DEFAULT_OPTIONS = {}; 95 96 // ============================================================ 97 // Internal Helpers (not exported) 98 // ============================================================ 99 function _internalHelper() {} 100 101 // ============================================================ 102 // Core Implementation 103 // ============================================================ 104 export function createThing(options = {}) { const config = { ...DEFAULT_OPTIONS, ...options }; } 105 export function useThing(config = {}) {} 106 ``` 107 108 ## Quick Reference: Writing Code by Module Type 109 110 | Module Type | DO | DON'T | 111 |-------------|-----|-------| 112 | **Runtime** | Use `getAdapter()` for DOM, `pulse()` for reactive state, feature-detect browser APIs | Use `document` at module scope, `let state = val` for UI state, import Node.js built-ins | 113 | **Compiler** | Pure functions (AST in → JS string out), `ParserError` with `line`/`column`/`suggestion` | Import `runtime/` modules (except `errors.js`) | 114 | **CLI** | Use Node.js built-ins, `process.exit(0/1)`, clear `console.log` output | Import runtime modules for CLI logic | 115 | **Loader** | Use build tool's transform hook, emit CSS separately, support HMR | Bypass build tool APIs directly | 116 117 ## Implementation Workflow 118 119 1. **Read the ADR** - Check `docs/adr/` for relevant Architecture Decision Records before writing any code. 120 2. **Check existing patterns** - Study the closest similar module (see Key Files table below). 121 3. **Run convention check** - `node .claude/skills/senior-developer/scripts/check-conventions.js runtime/new-module.js` 122 4. **Scaffold from template** - `node .claude/skills/senior-developer/scripts/scaffold-module.js runtime/my-module.js` 123 5. **Verify compliance** - Run conventions check + architecture check + related tests before submitting. 124 125 ## Available Scripts 126 127 ```bash 128 # Check code against project conventions 129 node .claude/skills/senior-developer/scripts/check-conventions.js 130 node .claude/skills/senior-developer/scripts/check-conventions.js runtime/http.js 131 node .claude/skills/senior-developer/scripts/check-conventions.js --fix # Show fix suggestions 132 133 # Scaffold a new module from template 134 node .claude/skills/senior-developer/scripts/scaffold-module.js runtime/my-feature.js 135 node .claude/skills/senior-developer/scripts/scaffold-module.js MyComponent --type component 136 ``` 137 138 ## Code Quality Checklist 139 140 - [ ] Follows architect's decisions (checked ADR, used prescribed patterns) 141 - [ ] Named correctly: `create*`, `use*`, `enable*`, `configure*` 142 - [ ] Options as last param: `fn(required, { optional })` with defaults 143 - [ ] Returns disposer: effects/subscriptions/event listeners return cleanup `() => void` 144 - [ ] Reactive state uses `pulse()`, not plain variables for state that drives UI 145 - [ ] No raw `Error` throws - uses `PulseError` subclasses with `context` + `suggestion` 146 - [ ] No Node.js APIs in `runtime/` (`fs`, `path`, `process`) 147 - [ ] Uses `getAdapter()` - no direct `document`/`window` at module scope 148 - [ ] Tree-shakeable - named exports only, no module-level side effects 149 - [ ] Private fields use `#privateField` syntax 150 - [ ] ES Modules - `import`/`export`, not `require`/`module.exports` 151 - [ ] Secure by default - user input sanitized, `dangerous*` prefix for unsafe APIs 152 - [ ] Accessible - ARIA attributes, keyboard handling, screen reader support 153 - [ ] Tested - at minimum: happy path + error path + edge case 154 - [ ] No over-engineering - simplest solution that works, no speculative abstractions 155 156 ## Key Files to Study 157 158 | Pattern | Study This File | For | 159 |---------|----------------|-----| 160 | Reactive hook | `runtime/async.js` | `useAsync`, `useResource`, `usePolling` | 161 | Factory + instance | `runtime/http.js` | `createHttp`, interceptors, child instances | 162 | DOM helper | `runtime/dom.js` | `el()`, `list()`, `when()`, reactive bindings | 163 | Compiler stage | `compiler/lexer.js` | Token types, scanning, error reporting | 164 | CLI command | `cli/index.js` | Argument parsing, command dispatch | 165 | Build integration | `loader/vite-plugin.js` | HMR, CSS extraction, transform hook | 166 | State management | `runtime/store.js` | `createStore`, plugins, persistence | 167 | Error handling | `runtime/errors.js` | Error classes, `formatWithSnippet()` | 168 | Security boundary | `runtime/utils.js` | Sanitization functions, XSS prevention | 169 170 ## Quick Troubleshooting 171 172 | Problem | Cause | Solution | 173 |---------|-------|---------| 174 | Effect runs too many times | Missing `batch()` for multiple updates | Wrap related `set()` calls in `batch(() => { })` | 175 | UI doesn't update | State not wrapped in `pulse()` | Replace `let x = val` with `const x = pulse(val)` | 176 | Memory leak | Missing cleanup in effect | Return cleanup function from `effect(() => { return () => cleanup(); })` | 177 | SSR crashes | Direct `document` access | Use `getAdapter()` or `typeof window !== 'undefined'` check | 178 | Import error in browser | Node.js API in runtime | Move to CLI layer or use dynamic import with feature detection | 179 | `Cannot set computed` | Calling `.set()` on computed | Use `pulse()` for writable state, `computed()` is read-only | 180 | Circular dependency | Modules import each other | Extract shared code into a third module | 181 | Tests pollute each other | Shared reactive state | Use `createContext()` + `ctx.reset()` per test | 182 | Effect cleanup not running | Not returning function from effect | `effect(() => { ...; return () => cleanup(); })` | 183 | List re-renders entirely | Missing key function in `list()` | Add `(item) => item.id` as third arg to `list()` | 184 185 --- 186 > Converted and distributed by [TomeVault](https://tomevault.io/claim/vincenthirtz) — claim your Tome and manage your conversions. 187 <!-- tomevault:4.0:skill_md:2026-04-13 -->