feat: import agents_and_robots platform as unibots (Matrix-out, unibus transport)

Reemplaza el scaffold del echobot por la plataforma completa de bots traida
desde ~/DataProyects/Github/agents_and_robots tras la operacion Matrix-out:
los bots ya no hablan por Matrix sino por el bus unibus (modelo todo-rooms +
E2E via shell/transportunibus sobre github.com/enmanuel/unibus/pkg/client).

- go.mod: replace de unibus -> ../unibus y de fn-registry -> ../../../.. (paths
  relativos reajustados a la nueva ubicacion dentro de fn_registry).
- app.md: bump a 0.2.0, descripcion + arquitectura + comandos + gotchas reales.
- modulo Go conservado como github.com/enmanuel/agents (sin reescribir imports).

agents_and_robots queda archivado como museo de la era Matrix.
This commit is contained in:
agent
2026-06-07 11:50:13 +02:00
parent bb5b0e09b1
commit fc644ecd6e
308 changed files with 38829 additions and 474 deletions
+91
View File
@@ -0,0 +1,91 @@
package command
import (
"encoding/json"
"strings"
)
// ParseArgs converts a slice of raw arguments into structured ParsedArgs.
// Supports: positional args, key=value pairs, and quoted values like key="hello world".
// Pure function — no side effects.
func ParseArgs(args []string) ParsedArgs {
p := ParsedArgs{
Named: make(map[string]string),
Raw: args,
}
// First, rejoin args to handle quoted values that were split by Fields().
joined := strings.Join(args, " ")
tokens := tokenize(joined)
for _, tok := range tokens {
if idx := strings.IndexByte(tok, '='); idx > 0 {
key := tok[:idx]
val := tok[idx+1:]
// Strip surrounding quotes from value
val = stripQuotes(val)
p.Named[key] = val
} else {
p.Positional = append(p.Positional, tok)
}
}
return p
}
// ArgsToJSON converts a named args map to a JSON string for tools.Registry.Execute.
// Pure function.
func ArgsToJSON(named map[string]string) string {
if len(named) == 0 {
return ""
}
m := make(map[string]any, len(named))
for k, v := range named {
m[k] = v
}
b, _ := json.Marshal(m)
return string(b)
}
// tokenize splits a string respecting quoted values.
// e.g. `host=server1 command="uptime -a"` → ["host=server1", `command="uptime -a"`]
func tokenize(s string) []string {
var tokens []string
var current strings.Builder
inQuote := false
quoteChar := byte(0)
for i := 0; i < len(s); i++ {
ch := s[i]
switch {
case !inQuote && (ch == '"' || ch == '\''):
inQuote = true
quoteChar = ch
current.WriteByte(ch)
case inQuote && ch == quoteChar:
inQuote = false
current.WriteByte(ch)
case !inQuote && ch == ' ':
if current.Len() > 0 {
tokens = append(tokens, current.String())
current.Reset()
}
default:
current.WriteByte(ch)
}
}
if current.Len() > 0 {
tokens = append(tokens, current.String())
}
return tokens
}
// stripQuotes removes surrounding double or single quotes from a string.
func stripQuotes(s string) string {
if len(s) >= 2 {
if (s[0] == '"' && s[len(s)-1] == '"') || (s[0] == '\'' && s[len(s)-1] == '\'') {
return s[1 : len(s)-1]
}
}
return s
}