mirror of
https://github.com/wavetermdev/waveterm
synced 2026-05-22 00:08:30 +00:00
* add automatic OSC 7 support to bash and zsh * add new wave OSC 16162 (planck length) to get up-to-date shell information into blockrtinfo. currently implemented only for zsh. bash will not support as rich of data as zsh, but we'll be able to do some. * new rtinfo will be used to provide better context for AI in the future, and to make sure AI is running safe commands. * added a small local machine description to tab context (so AI knows we're running on MacOS, Linux, or Windows)
107 lines
2.8 KiB
Go
107 lines
2.8 KiB
Go
// Copyright 2025, Command Line Inc.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package wstore
|
|
|
|
import (
|
|
"reflect"
|
|
"strings"
|
|
"sync"
|
|
|
|
"github.com/wavetermdev/waveterm/pkg/waveobj"
|
|
)
|
|
|
|
var (
|
|
blockRTInfoStore = make(map[waveobj.ORef]*waveobj.ObjRTInfo)
|
|
blockRTInfoMutex sync.RWMutex
|
|
)
|
|
|
|
// SetRTInfo merges the provided info map into the BlockRTInfo for the given ORef.
|
|
// Only updates fields that exist in the BlockRTInfo struct.
|
|
// Removes fields that have nil values.
|
|
func SetRTInfo(oref waveobj.ORef, info map[string]any) {
|
|
blockRTInfoMutex.Lock()
|
|
defer blockRTInfoMutex.Unlock()
|
|
|
|
rtInfo, exists := blockRTInfoStore[oref]
|
|
if !exists {
|
|
rtInfo = &waveobj.ObjRTInfo{}
|
|
blockRTInfoStore[oref] = rtInfo
|
|
}
|
|
|
|
rtInfoValue := reflect.ValueOf(rtInfo).Elem()
|
|
rtInfoType := rtInfoValue.Type()
|
|
|
|
// Build a map of json tags to field indices for quick lookup
|
|
jsonTagToField := make(map[string]int)
|
|
for i := 0; i < rtInfoType.NumField(); i++ {
|
|
field := rtInfoType.Field(i)
|
|
jsonTag := field.Tag.Get("json")
|
|
if jsonTag != "" {
|
|
// Remove omitempty and other options
|
|
tagParts := strings.Split(jsonTag, ",")
|
|
if len(tagParts) > 0 && tagParts[0] != "" {
|
|
jsonTagToField[tagParts[0]] = i
|
|
}
|
|
}
|
|
}
|
|
|
|
// Merge the info map into the struct
|
|
for key, value := range info {
|
|
fieldIndex, exists := jsonTagToField[key]
|
|
if !exists {
|
|
continue // Skip keys that don't exist in the struct
|
|
}
|
|
|
|
fieldValue := rtInfoValue.Field(fieldIndex)
|
|
if !fieldValue.CanSet() {
|
|
continue
|
|
}
|
|
|
|
if value == nil {
|
|
// Set to zero value (empty string for string fields)
|
|
fieldValue.Set(reflect.Zero(fieldValue.Type()))
|
|
} else {
|
|
// Convert and set the value
|
|
if valueStr, ok := value.(string); ok && fieldValue.Kind() == reflect.String {
|
|
fieldValue.SetString(valueStr)
|
|
} else if valueBool, ok := value.(bool); ok && fieldValue.Kind() == reflect.Bool {
|
|
fieldValue.SetBool(valueBool)
|
|
} else if fieldValue.Kind() == reflect.Int {
|
|
// Handle int fields - need to convert from various numeric types
|
|
switch v := value.(type) {
|
|
case int:
|
|
fieldValue.SetInt(int64(v))
|
|
case int64:
|
|
fieldValue.SetInt(v)
|
|
case float64:
|
|
fieldValue.SetInt(int64(v))
|
|
}
|
|
} else if fieldValue.Kind() == reflect.Interface {
|
|
// Handle any/interface{} fields
|
|
fieldValue.Set(reflect.ValueOf(value))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// GetRTInfo returns the BlockRTInfo for the given ORef, or nil if not found
|
|
func GetRTInfo(oref waveobj.ORef) *waveobj.ObjRTInfo {
|
|
blockRTInfoMutex.RLock()
|
|
defer blockRTInfoMutex.RUnlock()
|
|
|
|
if rtInfo, exists := blockRTInfoStore[oref]; exists {
|
|
// Return a copy to avoid external modification
|
|
copy := *rtInfo
|
|
return ©
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// DeleteRTInfo removes the BlockRTInfo for the given ORef
|
|
func DeleteRTInfo(oref waveobj.ORef) {
|
|
blockRTInfoMutex.Lock()
|
|
defer blockRTInfoMutex.Unlock()
|
|
|
|
delete(blockRTInfoStore, oref)
|
|
}
|