een-api-toolkit 0.3.85 → 0.3.91

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 (50) hide show
  1. package/.claude/agents/een-devices-agent.md +21 -0
  2. package/.claude/agents/een-ptz-agent.md +235 -0
  3. package/CHANGELOG.md +51 -22
  4. package/dist/index.cjs +3 -3
  5. package/dist/index.cjs.map +1 -1
  6. package/dist/index.d.ts +400 -0
  7. package/dist/index.js +1079 -951
  8. package/dist/index.js.map +1 -1
  9. package/docs/AI-CONTEXT.md +3 -1
  10. package/docs/ai-reference/AI-AUTH.md +1 -1
  11. package/docs/ai-reference/AI-AUTOMATIONS.md +1 -1
  12. package/docs/ai-reference/AI-DEVICES.md +1 -1
  13. package/docs/ai-reference/AI-EVENT-DATA-SCHEMAS.md +1 -1
  14. package/docs/ai-reference/AI-EVENTS.md +1 -1
  15. package/docs/ai-reference/AI-GROUPING.md +1 -1
  16. package/docs/ai-reference/AI-JOBS.md +1 -1
  17. package/docs/ai-reference/AI-MEDIA.md +1 -1
  18. package/docs/ai-reference/AI-PTZ.md +158 -0
  19. package/docs/ai-reference/AI-SETUP.md +1 -1
  20. package/docs/ai-reference/AI-USERS.md +1 -1
  21. package/examples/vue-ptz/.env.example +4 -0
  22. package/examples/vue-ptz/README.md +221 -0
  23. package/examples/vue-ptz/e2e/app.spec.ts +58 -0
  24. package/examples/vue-ptz/e2e/auth.spec.ts +296 -0
  25. package/examples/vue-ptz/index.html +13 -0
  26. package/examples/vue-ptz/package-lock.json +1729 -0
  27. package/examples/vue-ptz/package.json +29 -0
  28. package/examples/vue-ptz/playwright.config.ts +49 -0
  29. package/examples/vue-ptz/screenshot-ptz.png +0 -0
  30. package/examples/vue-ptz/src/App.vue +154 -0
  31. package/examples/vue-ptz/src/components/ApiLog.vue +387 -0
  32. package/examples/vue-ptz/src/components/CameraSelector.vue +155 -0
  33. package/examples/vue-ptz/src/components/DirectionPad.vue +350 -0
  34. package/examples/vue-ptz/src/components/LiveVideoPlayer.vue +248 -0
  35. package/examples/vue-ptz/src/components/PositionDisplay.vue +206 -0
  36. package/examples/vue-ptz/src/components/PositionInput.vue +190 -0
  37. package/examples/vue-ptz/src/components/PresetManager.vue +538 -0
  38. package/examples/vue-ptz/src/composables/useApiLog.ts +89 -0
  39. package/examples/vue-ptz/src/main.ts +22 -0
  40. package/examples/vue-ptz/src/router/index.ts +61 -0
  41. package/examples/vue-ptz/src/views/Callback.vue +76 -0
  42. package/examples/vue-ptz/src/views/Home.vue +199 -0
  43. package/examples/vue-ptz/src/views/Login.vue +32 -0
  44. package/examples/vue-ptz/src/views/Logout.vue +59 -0
  45. package/examples/vue-ptz/src/views/PtzControl.vue +173 -0
  46. package/examples/vue-ptz/src/vite-env.d.ts +12 -0
  47. package/examples/vue-ptz/tsconfig.json +21 -0
  48. package/examples/vue-ptz/tsconfig.node.json +11 -0
  49. package/examples/vue-ptz/vite.config.ts +12 -0
  50. package/package.json +1 -1
@@ -403,6 +403,27 @@ if (isCameraOnline(camera.status)) {
403
403
  }
404
404
  ```
405
405
 
406
+ ## PTZ Camera Support
407
+
408
+ When the user asks about PTZ (Pan/Tilt/Zoom) camera controls, presets, or camera movement,
409
+ **delegate to the `een-ptz-agent`** which has specialized knowledge of:
410
+ - `getPtzPosition()`, `movePtz()`, `getPtzSettings()`, `updatePtzSettings()`
411
+ - Direction pad controls, click-to-center, preset management
412
+ - PTZ automation modes (homeReturn, tour, manualOnly)
413
+
414
+ To check if a camera supports PTZ, use `getCamera(id, { include: ['capabilities'] })` and check
415
+ the nested `capabilities.ptz.capable` field:
416
+
417
+ ```typescript
418
+ const result = await getCamera(cameraId, { include: ['capabilities'] })
419
+ const capabilities = result.data?.capabilities as { ptz?: { capable?: boolean } } | undefined
420
+ if (capabilities?.ptz?.capable) {
421
+ // This camera supports PTZ - use een-ptz-agent for PTZ-specific tasks
422
+ }
423
+ ```
424
+
425
+ **IMPORTANT:** The capability is at `capabilities.ptz.capable` (nested object), NOT `capabilities.ptzCapable`.
426
+
406
427
  ## Constraints
407
428
  - Always check authentication before API calls
408
429
  - Use appropriate status filters to reduce payload
@@ -0,0 +1,235 @@
1
+ ---
2
+ name: een-ptz-agent
3
+ description: |
4
+ Use this agent when working with PTZ camera controls: getting position,
5
+ moving cameras, managing presets, or implementing PTZ control UI
6
+ with the een-api-toolkit.
7
+ model: inherit
8
+ color: orange
9
+ ---
10
+
11
+ You are an expert in PTZ (Pan/Tilt/Zoom) camera control with the een-api-toolkit.
12
+
13
+ ## Examples
14
+
15
+ <example>
16
+ Context: User wants to add PTZ controls to their app.
17
+ user: "How do I add PTZ controls to my camera view?"
18
+ assistant: "I'll use the een-ptz-agent to help implement PTZ controls using movePtz() and getPtzPosition()."
19
+ <Task tool call to launch een-ptz-agent>
20
+ </example>
21
+
22
+ <example>
23
+ Context: User wants to manage PTZ presets.
24
+ user: "How do I save and load PTZ presets?"
25
+ assistant: "I'll use the een-ptz-agent to implement preset management with getPtzSettings() and updatePtzSettings()."
26
+ <Task tool call to launch een-ptz-agent>
27
+ </example>
28
+
29
+ <example>
30
+ Context: User wants click-to-center functionality.
31
+ user: "How do I make the camera center on where I click in the video?"
32
+ assistant: "I'll use the een-ptz-agent to implement click-to-center using movePtz() with the centerOn move type."
33
+ <Task tool call to launch een-ptz-agent>
34
+ </example>
35
+
36
+ ## Context Files
37
+ - docs/AI-CONTEXT.md (overview)
38
+ - docs/ai-reference/AI-AUTH.md (auth is required)
39
+ - docs/ai-reference/AI-DEVICES.md (camera selection)
40
+ - docs/ai-reference/AI-PTZ.md (primary reference)
41
+ - docs/ai-reference/AI-MEDIA.md (live video integration)
42
+
43
+ ## Reference Examples
44
+ - examples/vue-ptz/ (complete PTZ control app with live video)
45
+
46
+ ## Your Capabilities
47
+ 1. Get current PTZ position with getPtzPosition()
48
+ 2. Move cameras with movePtz() (position, direction, centerOn)
49
+ 3. Get PTZ settings and presets with getPtzSettings()
50
+ 4. Update settings, presets, and mode with updatePtzSettings()
51
+ 5. Implement direction pad controls
52
+ 6. Implement click-to-center on live video
53
+ 7. Manage PTZ presets (save, load, delete)
54
+ 8. Configure automation modes (homeReturn, tour, manualOnly)
55
+
56
+ ## Key Types
57
+
58
+ ### PtzPosition
59
+ ```typescript
60
+ interface PtzPosition {
61
+ x?: number // Pan (horizontal)
62
+ y?: number // Tilt (vertical)
63
+ z?: number // Zoom level
64
+ }
65
+ ```
66
+
67
+ ### PtzMove (discriminated union)
68
+ ```typescript
69
+ // Absolute position
70
+ { moveType: 'position', x?: number, y?: number, z?: number }
71
+
72
+ // Relative direction
73
+ { moveType: 'direction', direction: PtzDirection[], stepSize?: PtzStepSize }
74
+
75
+ // Center on point in frame
76
+ { moveType: 'centerOn', relativeX: number, relativeY: number }
77
+
78
+ type PtzDirection = 'up' | 'down' | 'left' | 'right' | 'in' | 'out'
79
+ type PtzStepSize = 'small' | 'medium' | 'large'
80
+ ```
81
+
82
+ ### PtzSettings
83
+ ```typescript
84
+ interface PtzSettings {
85
+ presets: PtzPreset[]
86
+ homePreset: string | null
87
+ mode: PtzMode // 'homeReturn' | 'tour' | 'manualOnly'
88
+ autoStartDelay: number // seconds
89
+ }
90
+
91
+ interface PtzPreset {
92
+ name: string
93
+ position: PtzPosition
94
+ timeAtPreset: number // seconds at preset during tour
95
+ }
96
+ ```
97
+
98
+ ### PtzSettingsUpdate
99
+ ```typescript
100
+ interface PtzSettingsUpdate {
101
+ presets?: PtzPreset[]
102
+ homePreset?: string | null
103
+ mode?: PtzMode
104
+ autoStartDelay?: number
105
+ }
106
+ ```
107
+
108
+ ## Key Functions
109
+
110
+ ### getPtzPosition(cameraId)
111
+ Get current camera position:
112
+ ```typescript
113
+ import { getPtzPosition } from 'een-api-toolkit'
114
+
115
+ const { data, error } = await getPtzPosition('camera-123')
116
+ if (data) {
117
+ console.log(`Pan: ${data.x}, Tilt: ${data.y}, Zoom: ${data.z}`)
118
+ }
119
+ ```
120
+
121
+ ### movePtz(cameraId, move)
122
+ Move camera with three move types:
123
+ ```typescript
124
+ import { movePtz } from 'een-api-toolkit'
125
+
126
+ // Absolute position
127
+ await movePtz('camera-123', { moveType: 'position', x: 0.5, y: -0.3, z: 2.0 })
128
+
129
+ // Direction with step size
130
+ await movePtz('camera-123', {
131
+ moveType: 'direction',
132
+ direction: ['up', 'left'],
133
+ stepSize: 'medium'
134
+ })
135
+
136
+ // Center on point in video frame (0.0 to 1.0)
137
+ await movePtz('camera-123', {
138
+ moveType: 'centerOn',
139
+ relativeX: 0.75,
140
+ relativeY: 0.5
141
+ })
142
+ ```
143
+
144
+ ### getPtzSettings(cameraId)
145
+ Get presets and automation settings:
146
+ ```typescript
147
+ import { getPtzSettings } from 'een-api-toolkit'
148
+
149
+ const { data, error } = await getPtzSettings('camera-123')
150
+ if (data) {
151
+ console.log('Mode:', data.mode)
152
+ console.log('Presets:', data.presets.map(p => p.name))
153
+ console.log('Home:', data.homePreset)
154
+ }
155
+ ```
156
+
157
+ ### updatePtzSettings(cameraId, settings)
158
+ Update settings (partial update - only provided fields change):
159
+ ```typescript
160
+ import { updatePtzSettings } from 'een-api-toolkit'
161
+
162
+ // Change mode
163
+ await updatePtzSettings('camera-123', { mode: 'tour' })
164
+
165
+ // To add a preset, first fetch existing presets and append the new one
166
+ const { data: settings } = await getPtzSettings('camera-123')
167
+ const newPreset = { name: 'Entrance', position: { x: 0, y: 0, z: 1 }, timeAtPreset: 10 }
168
+ await updatePtzSettings('camera-123', {
169
+ presets: [...(settings?.presets ?? []), newPreset],
170
+ homePreset: 'Entrance'
171
+ })
172
+ ```
173
+
174
+ ## Click-to-Center Pattern
175
+
176
+ ```typescript
177
+ function handleVideoClick(event: MouseEvent) {
178
+ const video = event.currentTarget as HTMLVideoElement
179
+ const rect = video.getBoundingClientRect()
180
+ const relativeX = (event.clientX - rect.left) / rect.width
181
+ const relativeY = (event.clientY - rect.top) / rect.height
182
+
183
+ movePtz(cameraId, {
184
+ moveType: 'centerOn',
185
+ relativeX,
186
+ relativeY
187
+ })
188
+ }
189
+ ```
190
+
191
+ ## Error Handling
192
+
193
+ | Error Code | Meaning | Action |
194
+ |------------|---------|--------|
195
+ | AUTH_REQUIRED | Not authenticated | Redirect to login |
196
+ | NOT_FOUND | Camera not found or no PTZ support | Show "not found" message |
197
+ | FORBIDDEN | No permission | Show access denied message |
198
+ | VALIDATION_ERROR | Empty camera ID | Fix input |
199
+ | API_ERROR | Server error | Show error, allow retry |
200
+
201
+ ## Detecting PTZ-Capable Cameras
202
+
203
+ To check if a camera supports PTZ, fetch it with `include: ['capabilities']` and check the
204
+ nested `capabilities.ptz.capable` field. The structure is:
205
+
206
+ ```typescript
207
+ // Response from getCamera(id, { include: ['capabilities'] })
208
+ {
209
+ capabilities: {
210
+ ptz: {
211
+ capable: true, // Camera supports PTZ
212
+ panTilt: true, // Supports pan/tilt
213
+ zoom: true, // Supports zoom
214
+ positionMove: true, // Supports absolute position moves
215
+ directionMove: true, // Supports directional moves
216
+ centerOnMove: true, // Supports center-on moves
217
+ fisheye: false // Whether camera is fisheye
218
+ }
219
+ }
220
+ }
221
+ ```
222
+
223
+ **IMPORTANT:** The PTZ capability is at `capabilities.ptz.capable` (nested under a `ptz` object),
224
+ NOT at `capabilities.ptzCapable` (flat). Always use `capabilities?.ptz?.capable` to check.
225
+
226
+ Also check `effectivePermissions.controlPTZ` to verify the user has permission to move the camera,
227
+ and `effectivePermissions.editPTZStations` for managing presets.
228
+
229
+ ## Constraints
230
+ - Always check authentication before API calls
231
+ - Verify camera has PTZ capability (`capabilities.ptz.capable`) before showing controls
232
+ - Check user permissions (`effectivePermissions.controlPTZ`) before enabling movement
233
+ - Poll position periodically (every 5s) for position display
234
+ - Handle 204 responses for PUT/PATCH (no response body)
235
+ - Use encodeURIComponent for camera IDs in URLs
package/CHANGELOG.md CHANGED
@@ -2,24 +2,10 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
- ## [0.3.85] - 2026-02-17
5
+ ## [0.3.91] - 2026-02-21
6
6
 
7
7
  ### Release Summary
8
8
 
9
- #### PR #113: fix: address three security review findings
10
- ## Summary
11
- - **HIGH**: Validate hostname before persisting OAuth token — `setBaseUrl()` now returns boolean; `handleAuthCallback()` checks it before calling `setToken()`, preventing token persistence when hostname is rejected
12
- - **MEDIUM**: Pin external proxy repo clone in CI workflows (`validate-pr`, `test-release`) to commit SHA `4e8f45f` to prevent supply chain attacks
13
- - **LOW**: Remove unnecessary `id-token: write` permission from `claude-code-review` workflow
14
-
15
- ## Test plan
16
- - [x] 644/644 unit tests pass
17
- - [x] 225/225 E2E tests pass across all 11 example apps
18
- - [x] Lint clean, build succeeds
19
- - [ ] Validate-PR workflow passes on this PR
20
-
21
- 🤖 Generated with [Claude Code](https://claude.com/claude-code)
22
-
23
9
  #### PR #118: Release v0.3.85 - API coverage docs and workflow security fix
24
10
  ## Summary
25
11
 
@@ -51,23 +37,66 @@ v0.3.85
51
37
 
52
38
  🤖 Generated with [Claude Code](https://claude.com/claude-code)
53
39
 
40
+ #### PR #128: Release v0.3.89: PTZ camera control API and vue-ptz example
41
+ ## Summary
42
+
43
+ This release adds PTZ (Pan/Tilt/Zoom) camera control support to the toolkit:
44
+
45
+ - **PTZ API functions**: `getPtzPosition()`, `movePtz()`, `getPtzSettings()`, `updatePtzSettings()` with full TypeScript types
46
+ - **PTZ types**: `PtzPosition`, `PtzMove` (discriminated union: position/direction/centerOn), `PtzSettings`, `PtzPreset`, `PtzSettingsUpdate`
47
+ - **vue-ptz example app**: Complete PTZ control application with live video, direction pad, click-to-center, position display, preset management, and API call logging
48
+ - **Camera capabilities**: Added `capabilities` field to `Camera` type for PTZ detection via `include: ['capabilities']`
49
+ - **Documentation**: AI-PTZ.md reference doc, een-ptz-agent, updated AI-CONTEXT.md and CLAUDE.md
50
+ - **E2E tests**: Conditional PTZ API tests that exercise position read, direction move, and preset loading when a PTZ camera is available
51
+
52
+ ### Additional changes
53
+ - Dependabot: CodeQL action bump to 4.32.3
54
+ - CI: Use floating v1 tag for claude-code-action instead of SHA pin
55
+
56
+ ## Commits
57
+
58
+ - `c552fd0` feat: add PTZ camera control API and vue-ptz example app
59
+ - `6a12649` fix: use single getCameras call with include and pagination for PTZ discovery
60
+ - `2b04b26` fix: address review findings in vue-ptz example app
61
+ - `92a18e4` fix: address remaining review findings
62
+ - `4d01c2c` fix: use floating v1 tag for claude-code-action instead of SHA pin
63
+ - `3f197ba` chore(deps): bump github/codeql-action from 4.32.2 to 4.32.3
64
+
65
+ ## Test Results
66
+
67
+ | Check | Result |
68
+ |-------|--------|
69
+ | Lint | Pass (0 errors) |
70
+ | Unit tests | 681 passed (24 suites) |
71
+ | Build | Pass |
72
+ | E2E (12 apps) | All passed |
73
+ | Security review | No vulnerabilities found |
74
+ | Confidential data scan | Clean |
75
+
76
+ **Version**: 0.3.89
77
+
78
+ 🤖 Generated with [Claude Code](https://claude.com/claude-code)
79
+
54
80
 
55
81
  ### Detailed Changes
56
82
 
57
83
  #### Features
58
- - feat: add EEN API coverage documentation and agent
84
+ - feat: add PTZ camera control API and vue-ptz example app
59
85
 
60
86
  #### Bug Fixes
61
- - fix: restrict npm-publish workflow_dispatch to production branch
62
- - fix: restrict workflow_dispatch to production branch to prevent supply chain attack
87
+ - fix: address remaining PR #128 review findings
88
+ - fix: address PR #128 review findings
89
+ - fix: address remaining review findings
90
+ - fix: address review findings in vue-ptz example app
91
+ - fix: use single getCameras call with include and pagination for PTZ discovery
92
+ - fix: use floating v1 tag for claude-code-action instead of SHA pin
63
93
 
64
94
  #### Other Changes
65
- - docs: rename een-api-coverage-agent to api-coverage-agent
66
- - docs: add missing agents to README agent list
95
+ - chore(deps): bump github/codeql-action from 4.32.2 to 4.32.3
67
96
 
68
97
  ### Links
69
98
  - [npm package](https://www.npmjs.com/package/een-api-toolkit)
70
- - [Full Changelog](https://github.com/klaushofrichter/een-api-toolkit/compare/v0.3.82...v0.3.85)
99
+ - [Full Changelog](https://github.com/klaushofrichter/een-api-toolkit/compare/v0.3.85...v0.3.91)
71
100
 
72
101
  ---
73
- *Released: 2026-02-17 11:45:53 CST*
102
+ *Released: 2026-02-21 17:41:30 CST*