@live-change/frontend-template 0.9.199 → 0.9.200

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 (44) hide show
  1. package/.claude/rules/live-change-backend-actions-views-triggers.md +62 -0
  2. package/.claude/rules/live-change-backend-event-sourcing.md +186 -0
  3. package/.claude/rules/live-change-backend-models-and-relations.md +72 -0
  4. package/.claude/rules/live-change-frontend-vue-primevue.md +26 -0
  5. package/.claude/settings.json +32 -0
  6. package/.claude/skills/create-skills-and-rules/SKILL.md +248 -0
  7. package/.claude/skills/live-change-backend-change-triggers/SKILL.md +186 -0
  8. package/.claude/skills/live-change-design-actions-views-triggers/SKILL.md +462 -0
  9. package/.claude/skills/live-change-design-models-relations/SKILL.md +230 -0
  10. package/.claude/skills/live-change-design-service/SKILL.md +133 -0
  11. package/.claude/skills/live-change-frontend-accessible-objects/SKILL.md +384 -0
  12. package/.claude/skills/live-change-frontend-accessible-objects.md +383 -0
  13. package/.claude/skills/live-change-frontend-action-buttons/SKILL.md +129 -0
  14. package/.claude/skills/live-change-frontend-action-form/SKILL.md +149 -0
  15. package/.claude/skills/live-change-frontend-analytics/SKILL.md +147 -0
  16. package/.claude/skills/live-change-frontend-command-forms/SKILL.md +216 -0
  17. package/.claude/skills/live-change-frontend-data-views/SKILL.md +183 -0
  18. package/.claude/skills/live-change-frontend-editor-form/SKILL.md +240 -0
  19. package/.claude/skills/live-change-frontend-locale-time/SKILL.md +172 -0
  20. package/.claude/skills/live-change-frontend-page-list-detail/SKILL.md +201 -0
  21. package/.claude/skills/live-change-frontend-range-list/SKILL.md +129 -0
  22. package/.claude/skills/live-change-frontend-ssr-setup/SKILL.md +119 -0
  23. package/.cursor/rules/live-change-backend-actions-views-triggers.mdc +88 -0
  24. package/.cursor/rules/live-change-backend-event-sourcing.mdc +185 -0
  25. package/.cursor/rules/live-change-backend-models-and-relations.mdc +62 -0
  26. package/.cursor/skills/create-skills-and-rules.md +248 -0
  27. package/.cursor/skills/live-change-backend-change-triggers.md +186 -0
  28. package/.cursor/skills/live-change-design-actions-views-triggers.md +178 -79
  29. package/.cursor/skills/live-change-design-models-relations.md +112 -50
  30. package/.cursor/skills/live-change-design-service.md +1 -0
  31. package/.cursor/skills/live-change-frontend-accessible-objects.md +384 -0
  32. package/.cursor/skills/live-change-frontend-action-buttons.md +1 -0
  33. package/.cursor/skills/live-change-frontend-action-form.md +9 -3
  34. package/.cursor/skills/live-change-frontend-analytics.md +1 -0
  35. package/.cursor/skills/live-change-frontend-command-forms.md +1 -0
  36. package/.cursor/skills/live-change-frontend-data-views.md +1 -0
  37. package/.cursor/skills/live-change-frontend-editor-form.md +135 -72
  38. package/.cursor/skills/live-change-frontend-locale-time.md +1 -0
  39. package/.cursor/skills/live-change-frontend-page-list-detail.md +1 -0
  40. package/.cursor/skills/live-change-frontend-range-list.md +1 -0
  41. package/.cursor/skills/live-change-frontend-ssr-setup.md +1 -0
  42. package/front/src/router.js +2 -1
  43. package/opencode.json +10 -0
  44. package/package.json +52 -50
@@ -0,0 +1,248 @@
1
+ ---
2
+ name: create-skills-and-rules
3
+ description: Create or update Claude Code skills and Cursor rules/skills with proper format and frontmatter, and configure OpenCode
4
+ ---
5
+
6
+ # Skill: create-skills-and-rules
7
+
8
+ Use this skill when you need to **create or update skills and rules** for Claude Code (`.claude/`), Cursor (`.cursor/`), and OpenCode (`opencode.json`).
9
+
10
+ ## Directory structure
11
+
12
+ ```
13
+ .claude/
14
+ rules/ *.md – always-loaded project instructions
15
+ skills/ <name>/SKILL.md – step-by-step guides, invocable or auto-matched by description
16
+ .cursor/
17
+ rules/ *.mdc – Cursor rules with description/globs/alwaysApply frontmatter
18
+ skills/ *.md – flat files, same content as .claude/skills/ (Cursor reads them as reference)
19
+ opencode.json – OpenCode config: instructions array points to .claude/rules/*.md
20
+ ```
21
+
22
+ **Cross-tool compatibility:**
23
+ - **Claude Code** reads both flat files and directory-based skills from `.claude/skills/`
24
+ - **OpenCode** reads **only** directory-based skills (`.claude/skills/<name>/SKILL.md`) — flat files are ignored
25
+ - **Cursor** reads flat files from `.cursor/skills/*.md` as reference documents
26
+ - Rules are loaded by OpenCode via `opencode.json` `instructions` array
27
+
28
+ **Standard format:** Always use directory-based skills (`<name>/SKILL.md`) for compatibility with all tools.
29
+
30
+ ## Step 1 – Decide: rule or skill
31
+
32
+ | Type | Purpose | When loaded |
33
+ |---|---|---|
34
+ | **Rule** | Constraints, conventions, best practices | Automatically, based on `globs` or `alwaysApply` |
35
+ | **Skill** | Step-by-step implementation guide | When description matches task, or invoked via `/skill-name` |
36
+
37
+ Rules say **what to do / not do**. Skills say **how to do it step by step**.
38
+
39
+ ## Step 2 – Create a skill (`.claude/skills/<name>/SKILL.md`)
40
+
41
+ ### Create the directory and file
42
+
43
+ ```bash
44
+ mkdir -p .claude/skills/my-skill-name
45
+ # then create .claude/skills/my-skill-name/SKILL.md
46
+ ```
47
+
48
+ ### Required frontmatter
49
+
50
+ ```yaml
51
+ ---
52
+ name: my-skill-name
53
+ description: Short description of what this skill does and when to use it
54
+ ---
55
+ ```
56
+
57
+ | Field | Required by | Description |
58
+ |---|---|---|
59
+ | `name` | OpenCode, Claude Code | Must match directory name exactly. Lowercase, hyphens only, regex `^[a-z0-9]+(-[a-z0-9]+)*$`, max 64 chars |
60
+ | `description` | All tools | When to use — Claude/OpenCode match this to decide auto-invocation |
61
+
62
+ ### Optional frontmatter fields (Claude Code only)
63
+
64
+ ```yaml
65
+ ---
66
+ name: my-skill
67
+ description: What this skill does
68
+ user-invocable: true
69
+ disable-model-invocation: false
70
+ allowed-tools: Read, Grep, Bash
71
+ context: fork
72
+ agent: Explore
73
+ argument-hint: [filename]
74
+ model: sonnet
75
+ ---
76
+ ```
77
+
78
+ | Field | Default | Description |
79
+ |---|---|---|
80
+ | `user-invocable` | `true` | Show in `/` menu |
81
+ | `disable-model-invocation` | `false` | Prevent auto-loading by Claude |
82
+ | `allowed-tools` | – | Tools allowed without asking (e.g. `Read, Grep, Bash`) |
83
+ | `context` | – | Set to `fork` to run in isolated subagent |
84
+ | `agent` | – | Subagent type when `context: fork` (`Explore`, `Plan`, etc.) |
85
+ | `argument-hint` | – | Hint for autocomplete (e.g. `[issue-number]`) |
86
+ | `model` | inherited | Model override (`sonnet`, `opus`, `haiku`) |
87
+
88
+ OpenCode ignores unknown frontmatter fields, so these are safe to include.
89
+
90
+ ### Dynamic substitutions in skill content
91
+
92
+ - `$ARGUMENTS` – all arguments passed when invoking
93
+ - `$ARGUMENTS[0]`, `$1` – specific argument by index
94
+ - `${CLAUDE_SESSION_ID}` – current session ID
95
+ - `${CLAUDE_SKILL_DIR}` – directory containing SKILL.md
96
+
97
+ ### Body structure
98
+
99
+ ```markdown
100
+ ---
101
+ name: my-skill-name
102
+ description: Build X with Y and Z
103
+ ---
104
+
105
+ # Skill: my-skill-name
106
+
107
+ Use this skill when you build **X** using Y and Z.
108
+
109
+ ## When to use
110
+
111
+ - Bullet list of scenarios
112
+
113
+ ## Step 1 – First step
114
+
115
+ Explanation + code example.
116
+
117
+ ## Step 2 – Second step
118
+
119
+ Explanation + code example.
120
+ ```
121
+
122
+ Keep skills under 500 lines. Use clear step numbering. Include real code examples.
123
+
124
+ ## Step 3 – Create a Claude Code rule (`.claude/rules/<name>.md`)
125
+
126
+ ### Frontmatter
127
+
128
+ ```yaml
129
+ ---
130
+ description: Short description of this rule's purpose
131
+ globs: **/front/src/**/*.{vue,js,ts}
132
+ ---
133
+ ```
134
+
135
+ | Field | Description |
136
+ |---|---|
137
+ | `description` | What this rule covers (used for matching) |
138
+ | `globs` | File patterns that trigger this rule (e.g. `**/*.js`, `**/services/**/*.js`) |
139
+
140
+ ### Body structure
141
+
142
+ ```markdown
143
+ ---
144
+ description: Rules for X development
145
+ globs: **/*.js
146
+ ---
147
+
148
+ # Title
149
+
150
+ ## Section 1
151
+
152
+ - Rule bullet points
153
+ - Code examples
154
+
155
+ ## Section 2
156
+
157
+ - More rules
158
+ ```
159
+
160
+ Rules are concise. Lead with the constraint, then show a code example.
161
+
162
+ ## Step 4 – Create Cursor rule (`.cursor/rules/<name>.mdc`)
163
+
164
+ Same content as the Claude rule, but with Cursor-specific frontmatter:
165
+
166
+ ```yaml
167
+ ---
168
+ description: Short description of this rule's purpose
169
+ globs: **/front/src/**/*.{vue,js,ts}
170
+ alwaysApply: false
171
+ ---
172
+ ```
173
+
174
+ | Field | Default | Description |
175
+ |---|---|---|
176
+ | `description` | – | What the rule does; Cursor uses this to decide when to apply |
177
+ | `globs` | – | Comma-separated file patterns (e.g. `**/*.tsx, src/**/*.js`) |
178
+ | `alwaysApply` | `false` | If `true`, applies to every session regardless of context |
179
+
180
+ **Notes:**
181
+ - Do NOT quote glob patterns in frontmatter
182
+ - Keep rules short (target 25 lines, max 50 lines for best Cursor performance)
183
+ - The `.mdc` extension is required for Cursor
184
+
185
+ ## Step 5 – Register rules in OpenCode (`opencode.json`)
186
+
187
+ OpenCode reads `.claude/skills/<name>/SKILL.md` natively for skills (no extra step needed). But rules must be registered in `opencode.json`:
188
+
189
+ ```json
190
+ {
191
+ "$schema": "https://opencode.ai/config.json",
192
+ "instructions": [
193
+ ".claude/rules/live-change-backend-architecture.md",
194
+ ".claude/rules/live-change-frontend-vue-primevue.md"
195
+ ]
196
+ }
197
+ ```
198
+
199
+ When you **create a new rule**, add its path to the `instructions` array in `opencode.json`.
200
+
201
+ When you **create a new skill**, no `opencode.json` change is needed — OpenCode discovers skills from `.claude/skills/<name>/SKILL.md` automatically.
202
+
203
+ **Important:** OpenCode ignores the `globs` frontmatter from Claude Code rules. All instructions listed in `opencode.json` are always loaded.
204
+
205
+ ## Step 6 – Mirror Cursor skills (`.cursor/skills/<name>.md`)
206
+
207
+ Copy the skill content to `.cursor/skills/` as a **flat file** (Cursor reads flat `.md` files as reference):
208
+
209
+ ```bash
210
+ cp .claude/skills/my-skill-name/SKILL.md .cursor/skills/my-skill-name.md
211
+ ```
212
+
213
+ The content is the same (including `name` in frontmatter). Cursor ignores unknown frontmatter fields.
214
+
215
+ ## Step 7 – Mirror to sub-projects
216
+
217
+ If the project has sub-projects with their own `.claude/` and `.cursor/` directories, copy the files there too:
218
+
219
+ ```bash
220
+ for dir in automation auto-firma; do
221
+ # Skills: directory format for .claude, flat for .cursor
222
+ mkdir -p "$dir/.claude/skills/my-skill-name"
223
+ cp .claude/skills/my-skill-name/SKILL.md "$dir/.claude/skills/my-skill-name/SKILL.md"
224
+ cp .claude/skills/my-skill-name/SKILL.md "$dir/.cursor/skills/my-skill-name.md"
225
+
226
+ # Rules
227
+ cp .claude/rules/my-rule.md "$dir/.claude/rules/"
228
+ cp .cursor/rules/my-rule.mdc "$dir/.cursor/rules/"
229
+ done
230
+ ```
231
+
232
+ ## Naming conventions
233
+
234
+ - Use lowercase with hyphens: `live-change-frontend-editor-form`
235
+ - Must match regex `^[a-z0-9]+(-[a-z0-9]+)*$` (OpenCode requirement)
236
+ - Prefix with domain: `live-change-frontend-*`, `live-change-backend-*`
237
+ - Skills describe actions: `*-editor-form`, `*-range-list`, `*-action-buttons`
238
+ - Rules describe scope: `*-vue-primevue`, `*-models-and-relations`
239
+
240
+ ## Checklist
241
+
242
+ - [ ] Directory created: `.claude/skills/<name>/SKILL.md`
243
+ - [ ] Frontmatter has both `name` (matching dir) and `description`
244
+ - [ ] `.cursor/skills/<name>.md` mirrored (flat file, same content)
245
+ - [ ] `.claude/rules/*.md` created (if rule)
246
+ - [ ] `.cursor/rules/*.mdc` created with `globs` + `alwaysApply` (if rule)
247
+ - [ ] `opencode.json` `instructions` array updated (if new rule)
248
+ - [ ] Sub-projects updated (automation, auto-firma)
@@ -0,0 +1,186 @@
1
+ ---
2
+ name: live-change-backend-change-triggers
3
+ description: React to model changes with automatic change triggers from the relations plugin
4
+ ---
5
+
6
+ # Skill: live-change-backend-change-triggers (Claude Code)
7
+
8
+ Use this skill when you need to **react to model changes** — run logic when a record is created, updated, or deleted.
9
+
10
+ ## When to use
11
+
12
+ - You need to keep derived data in sync when a model changes (e.g. create/cancel a timer when a schedule is created/updated/deleted).
13
+ - You want to initialize related resources when a model is created.
14
+ - You need cross-service reactions to model lifecycle events.
15
+ - You want custom cleanup logic on delete.
16
+
17
+ ## How it works
18
+
19
+ The relations plugin automatically fires change triggers for every model that uses relations (`propertyOf`, `itemOf`, `userItem`, `propertyOfAny`, etc.). You just define a trigger with the matching name.
20
+
21
+ ## Step 1 – Understand the naming convention
22
+
23
+ For a model `MyModel` in service `myService`, these triggers are fired automatically:
24
+
25
+ | Trigger name | When |
26
+ |---|---|
27
+ | `createMyService_MyModel` | On create |
28
+ | `updateMyService_MyModel` | On update |
29
+ | `deleteMyService_MyModel` | On delete |
30
+ | `changeMyService_MyModel` | On any change |
31
+ | `createObject` / `updateObject` / `deleteObject` / `changeObject` | Generic (all models) |
32
+
33
+ The pattern is: `{changeType}{ServiceName}_{ModelName}` where service name is capitalized.
34
+
35
+ ## Step 2 – Define a change trigger (recommended: use `change*`)
36
+
37
+ The `change*` variant covers all cases. Check `data` and `oldData` to distinguish create/update/delete:
38
+
39
+ ```javascript
40
+ definition.trigger({
41
+ name: 'changeMyService_MyModel',
42
+ properties: {
43
+ object: {
44
+ type: MyModel,
45
+ validation: ['nonEmpty'],
46
+ },
47
+ data: {
48
+ type: Object,
49
+ },
50
+ oldData: {
51
+ type: Object,
52
+ }
53
+ },
54
+ async execute({ object, data, oldData }, { service, trigger, triggerService }, emit) {
55
+ if(oldData) {
56
+ // Updated or deleted — clean up old state
57
+ }
58
+ if(data) {
59
+ // Created or updated — set up new state
60
+ }
61
+ }
62
+ })
63
+ ```
64
+
65
+ How to distinguish:
66
+
67
+ | `oldData` | `data` | Meaning |
68
+ |---|---|---|
69
+ | `null` | `{...}` | Created |
70
+ | `{...}` | `{...}` | Updated |
71
+ | `{...}` | `null` | Deleted |
72
+
73
+ ## Step 3 – Real example: cron-service reacting to Schedule changes
74
+
75
+ The cron-service uses `changeCron_Schedule` to automatically manage timers when schedules are created, updated, or deleted:
76
+
77
+ ```javascript
78
+ // Source: live-change-stack/services/cron-service/schedule.js
79
+
80
+ definition.trigger({
81
+ name: 'changeCron_Schedule',
82
+ properties: {
83
+ object: {
84
+ type: Schedule,
85
+ validation: ['nonEmpty'],
86
+ },
87
+ data: {
88
+ type: Object,
89
+ },
90
+ oldData: {
91
+ type: Object,
92
+ }
93
+ },
94
+ execute: async ({ object, data, oldData }, { service, trigger, triggerService }, emit) => {
95
+ if(oldData) {
96
+ // Cancel old timer on update or delete
97
+ await triggerService({
98
+ service: 'timer',
99
+ type: 'cancelTimerIfExists',
100
+ }, {
101
+ timer: 'cron_Schedule_' + object
102
+ })
103
+ await ScheduleInfo.delete(object)
104
+ }
105
+ if(data) {
106
+ // Create new timer on create or update
107
+ await processSchedule({ id: object, ...data }, { triggerService })
108
+ }
109
+ }
110
+ })
111
+ ```
112
+
113
+ This means: when a user creates a Schedule via the UI or API, the timer is automatically set up. When they update it, the old timer is canceled and a new one created. When they delete it, the timer is canceled.
114
+
115
+ ## Step 4 – Specific lifecycle triggers (alternative)
116
+
117
+ If you only care about one lifecycle event, use the specific variant:
118
+
119
+ ```javascript
120
+ // React only to creation
121
+ definition.trigger({
122
+ name: 'createBilling_Billing',
123
+ properties: {
124
+ object: { type: Billing }
125
+ },
126
+ async execute({ object }, { triggerService }, emit) {
127
+ // Initialize balance when billing is created
128
+ const existingBalance = await app.serviceViewGet('balance', 'balance', {
129
+ ownerType: 'billing_Billing', owner: object
130
+ })
131
+ if(!existingBalance) {
132
+ await triggerService({
133
+ service: 'balance',
134
+ type: 'balance_setOrUpdateBalance',
135
+ }, { ownerType: 'billing_Billing', owner: object })
136
+ }
137
+ }
138
+ })
139
+ ```
140
+
141
+ ## Step 5 – Full trigger parameters
142
+
143
+ All change triggers receive:
144
+
145
+ ```javascript
146
+ {
147
+ objectType, // e.g. 'cron_Schedule' (service_Model)
148
+ object, // record ID
149
+ identifiers, // parent identifiers from the model's relations
150
+ data, // new data (null on delete)
151
+ oldData, // old data (null on create)
152
+ changeType // 'create', 'update', or 'delete'
153
+ }
154
+ ```
155
+
156
+ The `identifiers` object contains the parent references defined in the model's relations (e.g. for `itemOf: { what: Device }`, identifiers would include `{ device: '...' }`).
157
+
158
+ ## Step 6 – Cross-service triggers
159
+
160
+ Change triggers work across services. Define the trigger in any service — the framework routes it by name:
161
+
162
+ ```javascript
163
+ // In serviceA, react to changes in serviceB's Model
164
+ const SomeModel = definition.foreignModel('serviceB', 'SomeModel')
165
+
166
+ definition.trigger({
167
+ name: 'changeServiceB_SomeModel',
168
+ properties: {
169
+ object: { type: SomeModel },
170
+ data: { type: Object },
171
+ oldData: { type: Object }
172
+ },
173
+ async execute({ object, data, oldData }, { triggerService }) {
174
+ // React to changes in SomeModel from serviceB
175
+ }
176
+ })
177
+ ```
178
+
179
+ ## Common patterns
180
+
181
+ | Pattern | Trigger to use | Example |
182
+ |---|---|---|
183
+ | Keep derived data in sync | `changeSvc_Model` | Cron: cancel/create timers on schedule change |
184
+ | Initialize on creation | `createSvc_Model` | Billing: create balance when billing created |
185
+ | Custom cleanup on delete | `deleteSvc_Model` | Custom: archive or notify before deletion |
186
+ | React to any model change | `changeObject` | Audit: log all changes across all models |