feat(robin): M1 System Presence — journald/kmsg/inotify watcher, pattern classifier, tray badge, chat panel #2
3 changed files with 41 additions and 1 deletions
11
package-lock.json
generated
11
package-lock.json
generated
|
|
@ -8,6 +8,7 @@
|
||||||
"name": "robin",
|
"name": "robin",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@tauri-apps/api": "^2.11.0",
|
||||||
"vue": "^3.5.34"
|
"vue": "^3.5.34"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
@ -398,6 +399,16 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@tauri-apps/api": {
|
||||||
|
"version": "2.11.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.11.0.tgz",
|
||||||
|
"integrity": "sha512-7CinYODhky9lmO23xHnUFv0Xt43fbtWMyxZcLcRBlFkcgXKuEirBvHpmtJ89YMhyeGcq20Wuc47Fa4XjyniywA==",
|
||||||
|
"license": "Apache-2.0 OR MIT",
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/tauri"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@tybys/wasm-util": {
|
"node_modules/@tybys/wasm-util": {
|
||||||
"version": "0.10.2",
|
"version": "0.10.2",
|
||||||
"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz",
|
"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz",
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@tauri-apps/api": "^2.11.0",
|
||||||
"vue": "^3.5.34"
|
"vue": "^3.5.34"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
||||||
|
|
@ -33,13 +33,41 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, nextTick } from 'vue'
|
import { ref, nextTick, onMounted, onUnmounted } from 'vue'
|
||||||
|
import { invoke } from '@tauri-apps/api/core'
|
||||||
|
import { listen, type UnlistenFn } from '@tauri-apps/api/event'
|
||||||
|
|
||||||
interface Message { role: 'user' | 'robin'; content: string }
|
interface Message { role: 'user' | 'robin'; content: string }
|
||||||
|
interface RobinEvent { pattern_id: string; title: string; body: string; severity: string; timestamp: number }
|
||||||
|
|
||||||
const messages = ref<Message[]>([])
|
const messages = ref<Message[]>([])
|
||||||
const input = ref('')
|
const input = ref('')
|
||||||
const messagesEl = ref<HTMLElement | null>(null)
|
const messagesEl = ref<HTMLElement | null>(null)
|
||||||
|
let unlisten: UnlistenFn | null = null
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
// Drain any events that fired while the panel was closed
|
||||||
|
const pending = await invoke<RobinEvent[]>('get_pending_events')
|
||||||
|
for (const e of pending) {
|
||||||
|
pushRobinEvent(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listen for live events while panel is open
|
||||||
|
unlisten = await listen<RobinEvent>('robin:event', ({ payload }) => {
|
||||||
|
pushRobinEvent(payload)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
unlisten?.()
|
||||||
|
})
|
||||||
|
|
||||||
|
function pushRobinEvent(e: RobinEvent) {
|
||||||
|
messages.value.push({ role: 'robin', content: `**${e.title}**\n\n${e.body}` })
|
||||||
|
nextTick(() => {
|
||||||
|
messagesEl.value?.scrollTo({ top: messagesEl.value.scrollHeight, behavior: 'smooth' })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
async function send() {
|
async function send() {
|
||||||
const text = input.value.trim()
|
const text = input.value.trim()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue