grix-connector
Version:
Connect local AI coding agents (Claude, Codex, Gemini, Qwen, DeepSeek, Cursor, OpenCode, Pi, OpenHuman, Reasonix) to the Grix scheduling platform. Also serves as an OpenClaw plugin for Grix channel transport.
2 lines (1 loc) • 2.21 kB
JavaScript
import{watch as s}from"node:fs";class r{store;onActivity;onStop;onStopFailure;onCompactResult;onCompactStart;onConfigChange;onPermissionRequest;debounceMs;pollIntervalMs;watcher=null;pollTimer=null;debounceTimer=null;lastObservedAt=0;currentActivity=null;constructor(t){this.store=t.hookSignalStore,this.onActivity=t.onActivity,this.onStop=t.onStop,this.onStopFailure=t.onStopFailure,this.onCompactResult=t.onCompactResult,this.onCompactStart=t.onCompactStart,this.onConfigChange=t.onConfigChange,this.onPermissionRequest=t.onPermissionRequest,this.debounceMs=t.debounceMs??200,this.pollIntervalMs=t.watchIntervalMs??500}start(){this.stop(),this.lastObservedAt=Date.now();try{this.watcher=s(this.store.filePath,()=>{this.onFileChange().catch(()=>{})}),this.watcher.on("error",()=>{})}catch{}this.pollTimer=setInterval(()=>{this.onFileChange().catch(()=>{})},this.pollIntervalMs)}stop(){this.watcher&&(this.watcher.close(),this.watcher=null),this.pollTimer&&(clearInterval(this.pollTimer),this.pollTimer=null),this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=null)}async onFileChange(){const e=(await this.store.readState()).recent_events.filter(i=>i.event_at>this.lastObservedAt).sort((i,o)=>i.event_at-o.event_at);if(e.length!==0){this.lastObservedAt=e[e.length-1].event_at;for(const i of e)this.processEvent(i)}}processEvent(t){switch(t.hook_event_name){case"Stop":this.clearActivity(),this.onStop?.();break;case"StopFailure":this.clearActivity(),this.onStopFailure?.();break;case"PreToolUse":case"PostToolUse":case"PostToolUseFailure":{const e={event_name:t.hook_event_name,tool_name:t.detail};t.tool_input&&(e.tool_input=t.tool_input),this.applyActivity(e);break}case"PreCompact":this.onCompactStart?.(t.detail);break;case"PostCompact":this.onCompactResult?.(t.detail,t.tool_input??"");break;case"ConfigChange":this.onConfigChange?.(t.detail);break;case"PermissionRequest":this.onPermissionRequest?.(t.detail,t.tool_input);break;default:break}}applyActivity(t){this.currentActivity=t,this.onActivity(t)}clearActivity(){this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=null),this.currentActivity=null,this.onActivity(null)}}export{r as ActivityStatusManager};