een-api-toolkit 0.3.22 → 0.3.30
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.
- package/.claude/agents/een-devices-agent.md +75 -6
- package/.claude/agents/een-media-agent.md +71 -12
- package/CHANGELOG.md +6 -155
- package/README.md +23 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js.map +1 -1
- package/docs/AI-CONTEXT.md +1 -1
- package/docs/ai-reference/AI-AUTH.md +1 -1
- package/docs/ai-reference/AI-DEVICES.md +1 -1
- package/docs/ai-reference/AI-EVENTS.md +1 -1
- package/docs/ai-reference/AI-MEDIA.md +1 -1
- package/docs/ai-reference/AI-SETUP.md +1 -1
- package/docs/ai-reference/AI-USERS.md +1 -1
- package/package.json +1 -1
|
@@ -71,8 +71,15 @@ type CameraStatus =
|
|
|
71
71
|
| 'offline'
|
|
72
72
|
| 'streaming'
|
|
73
73
|
| 'recording'
|
|
74
|
+
| 'registered'
|
|
75
|
+
| 'deviceOffline'
|
|
76
|
+
| 'bridgeOffline'
|
|
77
|
+
| 'invalidCredentials'
|
|
74
78
|
| 'error'
|
|
75
79
|
| 'unknown'
|
|
80
|
+
|
|
81
|
+
// Status can also be nested in an object:
|
|
82
|
+
// camera.status?.connectionStatus
|
|
76
83
|
```
|
|
77
84
|
|
|
78
85
|
### Bridge Interface
|
|
@@ -112,15 +119,28 @@ interface ListCamerasParams {
|
|
|
112
119
|
## Key Functions
|
|
113
120
|
|
|
114
121
|
### getCameras()
|
|
115
|
-
List cameras with optional filters
|
|
122
|
+
List cameras with optional filters.
|
|
123
|
+
|
|
124
|
+
**IMPORTANT:** The `status` field is NOT included by default. You must use `include: ['status']` to receive it:
|
|
125
|
+
|
|
116
126
|
```typescript
|
|
117
127
|
import { getCameras, type Camera, type ListCamerasParams } from 'een-api-toolkit'
|
|
118
128
|
|
|
119
129
|
const cameras = ref<Camera[]>([])
|
|
120
130
|
|
|
121
|
-
// Get all
|
|
131
|
+
// Get all cameras WITH status - include: ['status'] is required!
|
|
132
|
+
async function fetchCameras() {
|
|
133
|
+
const result = await getCameras({
|
|
134
|
+
include: ['status'], // Required to get camera.status
|
|
135
|
+
pageSize: 100
|
|
136
|
+
})
|
|
137
|
+
// Now camera.status will be populated
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Get all online cameras (still need include for display)
|
|
122
141
|
async function fetchOnlineCameras() {
|
|
123
142
|
const result = await getCameras({
|
|
143
|
+
include: ['status'], // Required to display status in UI
|
|
124
144
|
status__in: ['online', 'streaming', 'recording'],
|
|
125
145
|
pageSize: 100
|
|
126
146
|
})
|
|
@@ -224,17 +244,33 @@ async function fetchBridge(bridgeId: string) {
|
|
|
224
244
|
|
|
225
245
|
```vue
|
|
226
246
|
<script setup lang="ts">
|
|
227
|
-
import { ref, onMounted } from 'vue'
|
|
228
|
-
import { getCameras, type Camera, type ListCamerasParams } from 'een-api-toolkit'
|
|
247
|
+
import { ref, onMounted, computed } from 'vue'
|
|
248
|
+
import { getCameras, type Camera, type CameraStatus, type ListCamerasParams } from 'een-api-toolkit'
|
|
229
249
|
|
|
230
250
|
const cameras = ref<Camera[]>([])
|
|
231
251
|
const loading = ref(false)
|
|
232
252
|
const statusFilter = ref<string[]>(['online', 'streaming', 'recording'])
|
|
233
253
|
|
|
254
|
+
// Helper: status can be a string OR an object with connectionStatus
|
|
255
|
+
function getStatusString(status?: CameraStatus | { connectionStatus?: CameraStatus }): string | undefined {
|
|
256
|
+
if (!status) return undefined
|
|
257
|
+
if (typeof status === 'string') return status
|
|
258
|
+
return status.connectionStatus
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Computed property to pre-process cameras with status string (avoids calling helper multiple times in template)
|
|
262
|
+
const camerasWithStatus = computed(() =>
|
|
263
|
+
cameras.value.map(camera => ({
|
|
264
|
+
...camera,
|
|
265
|
+
statusString: getStatusString(camera.status),
|
|
266
|
+
}))
|
|
267
|
+
)
|
|
268
|
+
|
|
234
269
|
async function fetchCameras() {
|
|
235
270
|
loading.value = true
|
|
236
271
|
|
|
237
272
|
const params: ListCamerasParams = {
|
|
273
|
+
include: ['status'], // Required to receive status field
|
|
238
274
|
pageSize: 100
|
|
239
275
|
}
|
|
240
276
|
|
|
@@ -268,10 +304,13 @@ onMounted(fetchCameras)
|
|
|
268
304
|
|
|
269
305
|
<div v-if="loading">Loading cameras...</div>
|
|
270
306
|
|
|
307
|
+
<!-- Use computed property for better performance (status string computed once per camera) -->
|
|
271
308
|
<div class="camera-grid" v-else>
|
|
272
|
-
<div v-for="camera in
|
|
309
|
+
<div v-for="camera in camerasWithStatus" :key="camera.id" class="camera-card">
|
|
273
310
|
<h3>{{ camera.name }}</h3>
|
|
274
|
-
<span :class="camera.
|
|
311
|
+
<span :class="camera.statusString">
|
|
312
|
+
{{ camera.statusString || 'unknown' }}
|
|
313
|
+
</span>
|
|
275
314
|
</div>
|
|
276
315
|
</div>
|
|
277
316
|
</div>
|
|
@@ -287,8 +326,38 @@ onMounted(fetchCameras)
|
|
|
287
326
|
| FORBIDDEN | No permission | Show access denied message |
|
|
288
327
|
| API_ERROR | Server error | Show error, allow retry |
|
|
289
328
|
|
|
329
|
+
## Camera ID Usage
|
|
330
|
+
|
|
331
|
+
The `camera.id` property is used consistently across all toolkit functions:
|
|
332
|
+
- `getCameras()` returns cameras with `id` property
|
|
333
|
+
- `listFeeds({ deviceId: camera.id })` for feeds
|
|
334
|
+
- `getLiveImage({ cameraId: camera.id })` for images
|
|
335
|
+
- LivePlayer SDK: `{ cameraId: camera.id }` for live video
|
|
336
|
+
|
|
337
|
+
**Note:** Some legacy EEN documentation may refer to "ESN" (Electronic Serial Number). This is outdated terminology - the current API uses `id`. In the toolkit, always use `camera.id`.
|
|
338
|
+
|
|
339
|
+
## Checking Camera Status for Previews
|
|
340
|
+
|
|
341
|
+
Before loading previews or video, check if the camera is in a viewable state:
|
|
342
|
+
|
|
343
|
+
```typescript
|
|
344
|
+
function isCameraOnline(status?: CameraStatus | { connectionStatus?: CameraStatus }): boolean {
|
|
345
|
+
// Handle both string status and nested object status
|
|
346
|
+
const statusStr = typeof status === 'string' ? status : status?.connectionStatus
|
|
347
|
+
return statusStr === 'online' || statusStr === 'streaming' || statusStr === 'registered'
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Usage
|
|
351
|
+
if (isCameraOnline(camera.status)) {
|
|
352
|
+
// Safe to load preview or video
|
|
353
|
+
} else {
|
|
354
|
+
// Show "Camera offline" message
|
|
355
|
+
}
|
|
356
|
+
```
|
|
357
|
+
|
|
290
358
|
## Constraints
|
|
291
359
|
- Always check authentication before API calls
|
|
292
360
|
- Use appropriate status filters to reduce payload
|
|
293
361
|
- Handle pagination for accounts with many devices
|
|
294
362
|
- Use include[] to request only needed fields
|
|
363
|
+
- Check camera status before loading previews (offline cameras won't have streams)
|
|
@@ -58,12 +58,14 @@ assistant: "I'll use the een-media-agent to diagnose the HLS configuration and a
|
|
|
58
58
|
- Modify multipartUrl with query parameters
|
|
59
59
|
- Use multipartUrl without initMediaSession() first
|
|
60
60
|
- Assume timestamps are ISO 8601 (they use +00:00 format)
|
|
61
|
+
- Pass ANY arguments to LivePlayer constructor - it MUST be called as `new LivePlayer()` with no arguments
|
|
61
62
|
|
|
62
63
|
**ALWAYS:**
|
|
63
64
|
- Use getLiveImage() for simple thumbnails
|
|
64
65
|
- Use initMediaSession() before multipartUrl
|
|
65
66
|
- Use formatTimestamp() for EEN API timestamps
|
|
66
67
|
- Check authentication before media operations
|
|
68
|
+
- Pass config to LivePlayer's `start()` method, NOT the constructor
|
|
67
69
|
|
|
68
70
|
## Choosing the Right Preview Method
|
|
69
71
|
|
|
@@ -213,28 +215,82 @@ function setupHlsPlayer(videoElement: HTMLVideoElement, hlsUrl: string) {
|
|
|
213
215
|
|
|
214
216
|
## Live Video SDK Integration
|
|
215
217
|
|
|
216
|
-
For full-quality live video, use the EEN Live Video SDK:
|
|
218
|
+
For full-quality live video, use the EEN Live Video Web SDK:
|
|
217
219
|
|
|
218
220
|
```typescript
|
|
219
|
-
// Install: npm install @
|
|
221
|
+
// Install: npm install @een/live-video-web-sdk
|
|
220
222
|
|
|
221
|
-
import
|
|
223
|
+
import LivePlayer from '@een/live-video-web-sdk'
|
|
222
224
|
import { useAuthStore } from 'een-api-toolkit'
|
|
223
225
|
|
|
224
|
-
|
|
226
|
+
// Store player instance for cleanup
|
|
227
|
+
let livePlayer: LivePlayer | null = null
|
|
228
|
+
|
|
229
|
+
async function setupLiveVideo(videoElement: HTMLVideoElement, cameraId: string) {
|
|
225
230
|
const authStore = useAuthStore()
|
|
226
231
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
+
// CRITICAL: Create LivePlayer WITHOUT arguments
|
|
233
|
+
livePlayer = new LivePlayer()
|
|
234
|
+
|
|
235
|
+
// CRITICAL: Pass config to start(), NOT to constructor
|
|
236
|
+
await livePlayer.start({
|
|
237
|
+
videoElement, // HTML video element (required)
|
|
238
|
+
cameraId, // Camera device ID (required)
|
|
239
|
+
baseUrl: authStore.baseUrl, // EEN API base URL (required)
|
|
240
|
+
jwt: authStore.token // Auth token (required)
|
|
232
241
|
})
|
|
233
242
|
|
|
234
|
-
|
|
243
|
+
return livePlayer
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Clean up when done
|
|
247
|
+
function stopLiveVideo() {
|
|
248
|
+
if (livePlayer) {
|
|
249
|
+
livePlayer.stop()
|
|
250
|
+
livePlayer = null
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### IMPORTANT: LivePlayer Usage Pattern
|
|
256
|
+
|
|
257
|
+
**CORRECT pattern:**
|
|
258
|
+
```typescript
|
|
259
|
+
const player = new LivePlayer() // No arguments to constructor
|
|
260
|
+
await player.start(config) // Config passed to start()
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
**WRONG pattern (will cause "Video Stream is done" errors):**
|
|
264
|
+
```typescript
|
|
265
|
+
const player = new LivePlayer(config) // DON'T pass config here
|
|
266
|
+
await player.start() // This won't work correctly
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### IMPORTANT: Video Element Must Be in DOM
|
|
270
|
+
|
|
271
|
+
The video element MUST be rendered in the DOM before calling `player.start()`.
|
|
272
|
+
|
|
273
|
+
**Problem:** Using `v-if` to conditionally show the video element means it doesn't exist during loading:
|
|
274
|
+
```vue
|
|
275
|
+
<!-- WRONG: Video element doesn't exist when loading=true -->
|
|
276
|
+
<div v-if="loading">Loading...</div>
|
|
277
|
+
<video v-else ref="videoRef" /> <!-- Not in DOM during loading! -->
|
|
278
|
+
```
|
|
235
279
|
|
|
236
|
-
|
|
280
|
+
**Solution:** Always render the video element, use CSS to hide it:
|
|
281
|
+
```vue
|
|
282
|
+
<!-- CORRECT: Video element always exists in DOM -->
|
|
283
|
+
<div v-if="loading" class="loading-overlay">Loading...</div>
|
|
284
|
+
<div class="video-container" :class="{ hidden: loading }">
|
|
285
|
+
<video ref="videoRef" /> <!-- Always in DOM -->
|
|
286
|
+
</div>
|
|
287
|
+
|
|
288
|
+
<style>
|
|
289
|
+
.video-container.hidden {
|
|
290
|
+
visibility: hidden;
|
|
291
|
+
position: absolute;
|
|
237
292
|
}
|
|
293
|
+
</style>
|
|
238
294
|
```
|
|
239
295
|
|
|
240
296
|
## Error Handling
|
|
@@ -253,4 +309,7 @@ function setupLiveVideo(container: HTMLElement, cameraId: string) {
|
|
|
253
309
|
| Image not loading | Auth not in cookies | Call initMediaSession() first |
|
|
254
310
|
| Timestamp errors | Wrong format | Use formatTimestamp() |
|
|
255
311
|
| CORS errors | Direct API access | Use toolkit functions, not direct fetch |
|
|
256
|
-
| Black video | HLS auth missing | Configure xhrSetup with token |
|
|
312
|
+
| Black video (HLS) | HLS auth missing | Configure xhrSetup with token |
|
|
313
|
+
| "Video Stream is done" immediately | Config passed to LivePlayer constructor | MUST use `new LivePlayer()` with no args, then `player.start(config)` |
|
|
314
|
+
| "Video element not found" | Video element not in DOM | Ensure video element is rendered (not hidden by v-if) before SDK init |
|
|
315
|
+
| Black video, no errors (LivePlayer) | Video element hidden by v-if | Use CSS visibility/opacity instead of v-if for conditional video display |
|
package/CHANGELOG.md
CHANGED
|
@@ -2,170 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
-
## [0.3.
|
|
5
|
+
## [0.3.30] - 2026-01-23
|
|
6
6
|
|
|
7
7
|
### Release Summary
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
## Summary
|
|
11
|
-
|
|
12
|
-
- Added Preview, HD Image, and Video buttons to event modal lightboxes in vue-events and vue-event-subscriptions example apps
|
|
13
|
-
- Implemented proper authentication for media fetching using `getRecordedImage` and HLS player with Authorization headers
|
|
14
|
-
- Created `useHlsPlayer` composable for both apps following vue-alerts-metrics pattern
|
|
15
|
-
|
|
16
|
-
## Changes
|
|
17
|
-
|
|
18
|
-
- **vue-events**: Updated EventsModal.vue with media buttons and HLS video support
|
|
19
|
-
- **vue-event-subscriptions**: Updated LiveEvents.vue with media buttons and HLS video support
|
|
20
|
-
- Added hls.js dependency to both example apps
|
|
21
|
-
- Created composables/useHlsPlayer.ts in both apps
|
|
22
|
-
|
|
23
|
-
## Test Plan
|
|
24
|
-
|
|
25
|
-
- [x] Unit tests: 341 passed
|
|
26
|
-
- [x] Build: successful
|
|
27
|
-
- [x] E2E tests for all 8 example apps passed (123 total):
|
|
28
|
-
- vue-users: 14 passed
|
|
29
|
-
- vue-cameras: 13 passed
|
|
30
|
-
- vue-bridges: 13 passed
|
|
31
|
-
- vue-events: 16 passed
|
|
32
|
-
- vue-feeds: 12 passed
|
|
33
|
-
- vue-media: 20 passed
|
|
34
|
-
- vue-alerts-metrics: 20 passed
|
|
35
|
-
- vue-event-subscriptions: 15 passed
|
|
36
|
-
|
|
37
|
-
## Version
|
|
38
|
-
|
|
39
|
-
v0.3.20
|
|
40
|
-
|
|
41
|
-
## Commits
|
|
42
|
-
|
|
43
|
-
- 8f11b04 feat: Add media buttons to event modal lightboxes in vue-events and vue-event-subscriptions
|
|
44
|
-
|
|
45
|
-
🤖 Generated with [Claude Code](https://claude.com/claude-code)
|
|
46
|
-
|
|
47
|
-
#### PR #65: feat: Restructure AI documentation with specialized agents
|
|
48
|
-
## Summary
|
|
49
|
-
|
|
50
|
-
Restructures the AI documentation from a single monolithic file into domain-specific documents with specialized Claude agents for context-efficient AI assistance.
|
|
51
|
-
|
|
52
|
-
### Changes
|
|
53
|
-
|
|
54
|
-
**Documentation Split (7 files):**
|
|
55
|
-
- `AI-CONTEXT.md` - Overview and navigation (entry point)
|
|
56
|
-
- `AI-SETUP.md` - Vue 3 scaffolding, Pinia, Vite configuration
|
|
57
|
-
- `AI-AUTH.md` - OAuth flow, tokens, route guards
|
|
58
|
-
- `AI-USERS.md` - User management API
|
|
59
|
-
- `AI-DEVICES.md` - Cameras & Bridges API
|
|
60
|
-
- `AI-MEDIA.md` - Media, Feeds, Live Video, HLS
|
|
61
|
-
- `AI-EVENTS.md` - Events, Alerts, Metrics, SSE subscriptions
|
|
62
|
-
|
|
63
|
-
**Specialized Agents (6 new agents):**
|
|
64
|
-
- `een-setup-agent` - Vue 3 project setup assistance
|
|
65
|
-
- `een-auth-agent` - OAuth authentication help
|
|
66
|
-
- `een-users-agent` - User management features
|
|
67
|
-
- `een-devices-agent` - Camera and bridge operations
|
|
68
|
-
- `een-media-agent` - Video and media troubleshooting
|
|
69
|
-
- `een-events-agent` - Events and real-time streaming
|
|
70
|
-
|
|
71
|
-
**CLI Tool:**
|
|
72
|
-
- Added `npx een-setup-agents` command for easy agent installation
|
|
73
|
-
- Copies agents to `.claude/agents/` for automatic discovery
|
|
74
|
-
|
|
75
|
-
**Generation Script:**
|
|
76
|
-
- Refactored to generate split files by default
|
|
77
|
-
- `--single` flag for legacy monolithic output
|
|
78
|
-
- Extracts examples from actual Vue components
|
|
79
|
-
|
|
80
|
-
### Benefits
|
|
81
|
-
|
|
82
|
-
| Metric | Before | After (typical task) |
|
|
83
|
-
|--------|--------|---------------------|
|
|
84
|
-
| Tokens per task | ~15-18K | ~5-8K |
|
|
85
|
-
| Context preserved | Limited | Substantial |
|
|
86
|
-
| Agent specialization | None | 6 domain agents |
|
|
87
|
-
|
|
88
|
-
## Test Results
|
|
89
|
-
|
|
90
|
-
- **Lint:** ✅ Passed (1 pre-existing warning)
|
|
91
|
-
- **Unit Tests:** ✅ 341 passed
|
|
92
|
-
- **Build:** ✅ Successful
|
|
93
|
-
- **E2E Tests:** ✅ 70 passed across 8 example apps
|
|
94
|
-
|
|
95
|
-
## Version
|
|
96
|
-
|
|
97
|
-
`0.3.20`
|
|
98
|
-
|
|
99
|
-
## Commits
|
|
100
|
-
|
|
101
|
-
- `8e1cc78` feat: Restructure AI documentation into domain-specific files with specialized agents
|
|
102
|
-
|
|
103
|
-
---
|
|
104
|
-
|
|
105
|
-
🤖 Generated with [Claude Code](https://claude.ai/code)
|
|
106
|
-
|
|
107
|
-
#### PR #66: Release v0.3.20: AI Documentation Restructure
|
|
108
|
-
## Summary
|
|
109
|
-
|
|
110
|
-
This release restructures the AI documentation for improved context efficiency:
|
|
111
|
-
|
|
112
|
-
- **Split AI-CONTEXT.md** into 7 domain-specific documents (~2-4K tokens each vs 15K+ monolithic)
|
|
113
|
-
- **Added 6 specialized Claude agents** for domain-specific assistance
|
|
114
|
-
- **New CLI tool**: `npx een-setup-agents` for easy agent installation in consumer projects
|
|
115
|
-
- **Code quality fixes** addressing Gemini code review feedback
|
|
116
|
-
|
|
117
|
-
## Changes
|
|
118
|
-
|
|
119
|
-
### New Files
|
|
120
|
-
- `.claude/agents/` - 6 specialized agents (auth, users, devices, media, events, setup)
|
|
121
|
-
- `docs/ai-reference/` - 6 domain-specific AI reference documents
|
|
122
|
-
- `scripts/setup-agents.ts` - CLI tool for agent installation
|
|
123
|
-
|
|
124
|
-
### Modified
|
|
125
|
-
- `docs/AI-CONTEXT.md` - Now serves as overview with navigation
|
|
126
|
-
- `scripts/generate-ai-context.ts` - Rewritten to support split file generation
|
|
127
|
-
- `package.json` - Added bin entry and updated files array
|
|
128
|
-
- `CLAUDE.md` - Added agent documentation section
|
|
129
|
-
|
|
130
|
-
### Commits
|
|
131
|
-
- `8e1cc78` feat: Restructure AI documentation into domain-specific files with specialized agents
|
|
132
|
-
- `407db5f` fix: Address Gemini code review feedback
|
|
133
|
-
- `ecd6cfd` Merge pull request #65
|
|
134
|
-
|
|
135
|
-
## Test Results
|
|
136
|
-
|
|
137
|
-
- **Lint**: ✅ Passed (1 pre-existing warning)
|
|
138
|
-
- **Unit Tests**: ✅ 341 passed
|
|
139
|
-
- **Build**: ✅ Successful
|
|
140
|
-
- **E2E Tests**: ✅ 70 passed across 8 example apps
|
|
141
|
-
|
|
142
|
-
## Version
|
|
143
|
-
|
|
144
|
-
`0.3.20`
|
|
145
|
-
|
|
146
|
-
---
|
|
147
|
-
|
|
148
|
-
🤖 Generated with [Claude Code](https://claude.ai/code)
|
|
149
|
-
|
|
9
|
+
No PR descriptions available for this release.
|
|
150
10
|
|
|
151
11
|
### Detailed Changes
|
|
152
12
|
|
|
153
|
-
#### Features
|
|
154
|
-
- feat: Restructure AI documentation into domain-specific files with specialized agents
|
|
155
|
-
- feat: Add media buttons to event modal lightboxes in vue-events and vue-event-subscriptions
|
|
156
|
-
|
|
157
|
-
#### Bug Fixes
|
|
158
|
-
- fix: Add XSS protection for SVG overlays in events agent
|
|
159
|
-
- fix: Address Gemini code review feedback
|
|
160
|
-
- fix: Address code review feedback from PR #64
|
|
161
|
-
|
|
162
13
|
#### Other Changes
|
|
163
|
-
-
|
|
164
|
-
-
|
|
14
|
+
- refactor: Use computed property for camera status in devices agent
|
|
15
|
+
- docs: Document status field requirements in devices agent
|
|
165
16
|
|
|
166
17
|
### Links
|
|
167
18
|
- [npm package](https://www.npmjs.com/package/een-api-toolkit)
|
|
168
|
-
- [Full Changelog](https://github.com/klaushofrichter/een-api-toolkit/compare/v0.3.
|
|
19
|
+
- [Full Changelog](https://github.com/klaushofrichter/een-api-toolkit/compare/v0.3.28...v0.3.30)
|
|
169
20
|
|
|
170
21
|
---
|
|
171
|
-
*Released: 2026-01-
|
|
22
|
+
*Released: 2026-01-23 17:42:54 CST*
|
package/README.md
CHANGED
|
@@ -176,6 +176,29 @@ if (!cameraError) {
|
|
|
176
176
|
| **[AI Context](./docs/AI-CONTEXT.md)** | Single-file reference for AI assistants (also in npm package) |
|
|
177
177
|
| **[AI Prompts](./docs/Prompts.md)** | Example prompts for generating apps with AI |
|
|
178
178
|
|
|
179
|
+
## Claude Code Agents
|
|
180
|
+
|
|
181
|
+
The toolkit includes specialized [Claude Code](https://docs.anthropic.com/en/docs/claude-code) agents for AI-assisted development. These agents have deep knowledge of the EEN API and toolkit patterns.
|
|
182
|
+
|
|
183
|
+
> **Note:** These agents use Claude Code's specific format. To use with other AI assistants (Gemini CLI, Copilot, etc.), the agent specs would need conversion.
|
|
184
|
+
|
|
185
|
+
**Available agents:**
|
|
186
|
+
- `een-setup-agent` - Project scaffolding, Pinia setup, Vite configuration
|
|
187
|
+
- `een-auth-agent` - OAuth flows, route guards, token management
|
|
188
|
+
- `een-users-agent` - User listing and profile APIs
|
|
189
|
+
- `een-devices-agent` - Camera and bridge management
|
|
190
|
+
- `een-media-agent` - Live video, previews, HLS playback
|
|
191
|
+
- `een-events-agent` - Events, alerts, metrics, SSE subscriptions
|
|
192
|
+
|
|
193
|
+
**Installation:**
|
|
194
|
+
```bash
|
|
195
|
+
npx een-setup-agents
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
> **Important:** After running the setup script, **restart Claude Code** for the agents to become available.
|
|
199
|
+
|
|
200
|
+
See the [User Guide](./docs/USER-GUIDE.md#claude-code-agents) for detailed agent documentation.
|
|
201
|
+
|
|
179
202
|
## Example Applications
|
|
180
203
|
|
|
181
204
|
The `examples/` directory contains complete Vue 3 applications demonstrating toolkit features:
|