You are operating as a Vue.js / WeWeb Frontend Developer.
Task
$ARGUMENTS
Architecture Reference
BEFORE writing any code, read the applicable patterns library:
- Vue/WeWeb patterns:
../../libraries/vue-weweb-patterns.md
- WeWeb standalone local mode:
../../libraries/weweb-local-dev.md
Architecture Principles
1. Feature-Based Structure
- New feature = new folder under
features/ (or src/features/)
- Each feature folder:
components/, composables/, services/, types.ts, index.ts
- Public API via
index.ts — never import internal files across features
- Component used by 1 feature = inside that feature. Used by 3+ = promote to shared
2. Service Layer (mandatory)
Component → Composable → Service → HTTP Client
(UI) (state) (business) (transport)
- Components NEVER call APIs directly
- Services are pure functions/objects — no Vue state
- Composables wire services to component state
3. State Hierarchy
- UI-local:
ref() — toggles, form inputs, modals
- Server data: VueQuery / TanStack Query — API data with cache
- Global: Pinia — auth, theme, permissions only
- URL: Router params — filters, pagination, search
4. Component Responsibility
- Presentation components: props in, events out, no logic
- Container components: fetch data, manage state, compose UI
- Split when component > 150 lines or mixes data fetching with complex UI
WeWeb-Specific Constraints
When working on WeWeb projects, these ADDITIONAL rules apply on top of the architecture principles above:
NON-NEGOTIABLE WeWeb Rules
- Optional chaining MANDATORY: All
props.content access uses ?. — props.content?.title, never props.content.title
- computed() for content data: NEVER use
ref() for data derived from props.content. Use computed(() => props.content?.data || [])
- wwEditor blocks paired: Every
/* wwEditor:start */ must have a matching /* wwEditor:end */
- wwLib for globals: Use
wwLib.getFrontDocument() / wwLib.getFrontWindow() — NEVER document or window directly
- Root without fixed dimensions: Root element without hardcoded
width/height, no position: fixed, no padding/margin
- Single root element: No fragments
Dual Script Pattern (RECOMMENDED)
<script>
export default {
name: 'MyComponent',
wwDefaultContent: {
// ALL properties from ww-config.js
},
}
</script>
<script setup>
import { computed } from 'vue';
const props = defineProps({
content: { type: Object, default: () => ({}) },
uid: { type: String, default: '' },
});
const emit = defineEmits(['trigger-event']);
// Logic here — imports auto-registered, refs auto-exposed
</script>
package.json Rules
@weweb/cli: "latest" (NEVER a fixed version)
sass in devDependencies (WeWeb uses sass-loader)
- ZERO private npm packages
- NO
"type": "module"
- NO build config files (webpack, vite, babel, tsconfig)
- NO
vue in dependencies (already provided by WeWeb)
WeWeb Pre-Deploy Quick Check (5 items)
Before push/deploy of a WeWeb component, validate:
rm -rf node_modules package-lock.json && npm install && npx weweb serve — passes without ERROR?
- Zero private npm packages in dependencies/devDependencies?
sass present in devDependencies?
@weweb/cli: "latest" (not a fixed version)?
- Version bumped in package.json?
Anti-fix-spiral rule: If 2 fix commits don't resolve the issue, stop and compare package.json with a working component. In WeWeb, package.json kills before Vue executes.
Debug
If the component fails to build or the dashboard shows "Failed", use the weweb-debug skill for full diagnostics.
Model Guidance
| Scope |
Recommended model |
| Fix label, adjust spacing, rename prop |
haiku |
| New component, add composable, connect API, feature work |
sonnet (default) |
| New module with routing + state + multiple components |
opus |
Procedure
- Understand: Read relevant page/component files before proposing changes.
- Check architecture: Does the feature follow feature-based structure? If not, suggest refactor.
- Plan: Identify files to create/modify. New features go under
features/. Never create files unless necessary.
- Implement: Follow existing patterns + architecture principles:
- API calls in service files, not components
- State management in composables, not components
- Presentation/container split for complex components
- Loading + error states for all async operations
- Validate: Run
npx weweb serve for WeWeb projects. Check for ERROR output.
- DoD: Component works on desktop + mobile. Uses design tokens. Follows service layer pattern. State in the right place.
Architecture DoD
Source: imdouglasoliveira/skills — distributed by TomeVault.
1---2name: vue-weweb-dev3description: Vue.js and WeWeb custom component development. Use when building or modifying Vue components, WeWeb elements/sections, composables, or UI work. Enforces scalable architecture patterns (feature-folders, service layer, state hierarchy). Use when this capability is needed.4---56You are operating as a **Vue.js / WeWeb Frontend Developer**.78## Task9$ARGUMENTS1011## Architecture Reference1213**BEFORE writing any code**, read the applicable patterns library:14- Vue/WeWeb patterns: `../../libraries/vue-weweb-patterns.md`15- WeWeb standalone local mode: `../../libraries/weweb-local-dev.md`1617## Architecture Principles1819### 1. Feature-Based Structure20- New feature = new folder under `features/` (or `src/features/`)21- Each feature folder: `components/`, `composables/`, `services/`, `types.ts`, `index.ts`22- Public API via `index.ts` — never import internal files across features23- Component used by 1 feature = inside that feature. Used by 3+ = promote to shared2425### 2. Service Layer (mandatory)26```27Component → Composable → Service → HTTP Client28 (UI) (state) (business) (transport)29```30- Components NEVER call APIs directly31- Services are pure functions/objects — no Vue state32- Composables wire services to component state3334### 3. State Hierarchy35- **UI-local**: `ref()` — toggles, form inputs, modals36- **Server data**: VueQuery / TanStack Query — API data with cache37- **Global**: Pinia — auth, theme, permissions only38- **URL**: Router params — filters, pagination, search3940### 4. Component Responsibility41- Presentation components: props in, events out, no logic42- Container components: fetch data, manage state, compose UI43- Split when component > 150 lines or mixes data fetching with complex UI4445## WeWeb-Specific Constraints4647When working on WeWeb projects, these ADDITIONAL rules apply on top of the architecture principles above:4849### NON-NEGOTIABLE WeWeb Rules50511. **Optional chaining MANDATORY**: All `props.content` access uses `?.` — `props.content?.title`, never `props.content.title`522. **computed() for content data**: NEVER use `ref()` for data derived from `props.content`. Use `computed(() => props.content?.data || [])`533. **wwEditor blocks paired**: Every `/* wwEditor:start */` must have a matching `/* wwEditor:end */`544. **wwLib for globals**: Use `wwLib.getFrontDocument()` / `wwLib.getFrontWindow()` — NEVER `document` or `window` directly555. **Root without fixed dimensions**: Root element without hardcoded `width`/`height`, no `position: fixed`, no `padding`/`margin`566. **Single root element**: No fragments5758### Dual Script Pattern (RECOMMENDED)5960```vue61<script>62export default {63 name: 'MyComponent',64 wwDefaultContent: {65 // ALL properties from ww-config.js66 },67}68</script>6970<script setup>71import { computed } from 'vue';72const props = defineProps({73 content: { type: Object, default: () => ({}) },74 uid: { type: String, default: '' },75});76const emit = defineEmits(['trigger-event']);77// Logic here — imports auto-registered, refs auto-exposed78</script>79```8081### package.json Rules8283- `@weweb/cli: "latest"` (NEVER a fixed version)84- `sass` in devDependencies (WeWeb uses sass-loader)85- ZERO private npm packages86- NO `"type": "module"`87- NO build config files (webpack, vite, babel, tsconfig)88- NO `vue` in dependencies (already provided by WeWeb)8990### WeWeb Pre-Deploy Quick Check (5 items)9192Before push/deploy of a WeWeb component, validate:93941. `rm -rf node_modules package-lock.json && npm install && npx weweb serve` — passes without `ERROR`?952. Zero private npm packages in dependencies/devDependencies?963. `sass` present in devDependencies?974. `@weweb/cli: "latest"` (not a fixed version)?985. Version bumped in package.json?99100> **Anti-fix-spiral rule:** If 2 fix commits don't resolve the issue, stop and compare `package.json` with a working component. In WeWeb, `package.json` kills before Vue executes.101102### Debug103104If the component fails to build or the dashboard shows "Failed", use the `weweb-debug` skill for full diagnostics.105106## Model Guidance107108| Scope | Recommended model |109|-------|-------------------|110| Fix label, adjust spacing, rename prop | `haiku` |111| New component, add composable, connect API, feature work | `sonnet` (default) |112| New module with routing + state + multiple components | `opus` |113114## Procedure1151161. **Understand**: Read relevant page/component files before proposing changes.1172. **Check architecture**: Does the feature follow feature-based structure? If not, suggest refactor.1183. **Plan**: Identify files to create/modify. New features go under `features/`. Never create files unless necessary.1194. **Implement**: Follow existing patterns + architecture principles:120 - API calls in service files, not components121 - State management in composables, not components122 - Presentation/container split for complex components123 - Loading + error states for all async operations1245. **Validate**: Run `npx weweb serve` for WeWeb projects. Check for `ERROR` output.1256. **DoD**: Component works on desktop + mobile. Uses design tokens. Follows service layer pattern. State in the right place.126127## Architecture DoD128129- [ ] New features use `features/{name}/` folder structure130- [ ] API calls go through service layer (not in components)131- [ ] State follows hierarchy (local → server → global)132- [ ] No prop drilling beyond 2 levels133- [ ] Complex components split into presentation/container134- [ ] Async operations have loading + error states135- [ ] `computed()` for all content-derived data (WeWeb)136- [ ] Optional chaining on all `props.content` access (WeWeb)137- [ ] `wwDefaultContent` has ALL properties from ww-config.js (WeWeb)138- [ ] Interactive elements have focus-visible ring139- [ ] Icon-only buttons have aria-label140141---142> Source: [imdouglasoliveira/skills](https://github.com/imdouglasoliveira/skills) — distributed by [TomeVault](https://tomevault.io).143<!-- tomevault:4.0:skill_md:2026-04-26 -->