@jmanuelcorral/openteam 0.1.38 → 0.1.41

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.
Files changed (162) hide show
  1. package/.opencode/command/openteam.md +5 -5
  2. package/AGENTS.md +50 -35
  3. package/README.es.md +759 -0
  4. package/README.md +213 -480
  5. package/dist/capabilities/types.d.ts +1 -1
  6. package/dist/cli/consoleServe.d.ts.map +1 -1
  7. package/dist/cli.js +1123 -232
  8. package/dist/commands/frontierCatalog.d.ts +27 -0
  9. package/dist/commands/frontierCatalog.d.ts.map +1 -0
  10. package/dist/commands/graph.d.ts +65 -0
  11. package/dist/commands/graph.d.ts.map +1 -0
  12. package/dist/commands/orchestratorAgent.d.ts +2 -1
  13. package/dist/commands/orchestratorAgent.d.ts.map +1 -1
  14. package/dist/commands/setup.d.ts +3 -18
  15. package/dist/commands/setup.d.ts.map +1 -1
  16. package/dist/config/load.d.ts.map +1 -1
  17. package/dist/config/migrations.d.ts +27 -0
  18. package/dist/config/migrations.d.ts.map +1 -0
  19. package/dist/config/resolve.d.ts +34 -0
  20. package/dist/config/resolve.d.ts.map +1 -0
  21. package/dist/config/schema.d.ts +235 -0
  22. package/dist/config/schema.d.ts.map +1 -1
  23. package/dist/console/assets.d.ts +9 -0
  24. package/dist/console/assets.d.ts.map +1 -0
  25. package/dist/console/render.d.ts.map +1 -1
  26. package/dist/context/redaction.d.ts +48 -0
  27. package/dist/context/redaction.d.ts.map +1 -0
  28. package/dist/context/schema.d.ts +115 -0
  29. package/dist/context/schema.d.ts.map +1 -0
  30. package/dist/context/types.d.ts +8 -0
  31. package/dist/context/types.d.ts.map +1 -0
  32. package/dist/contract/opencode.d.ts +1 -1
  33. package/dist/contract/opencode.d.ts.map +1 -1
  34. package/dist/graph/events.d.ts +25 -0
  35. package/dist/graph/events.d.ts.map +1 -0
  36. package/dist/graph/ids.d.ts +5 -0
  37. package/dist/graph/ids.d.ts.map +1 -0
  38. package/dist/graph/planner.d.ts +15 -0
  39. package/dist/graph/planner.d.ts.map +1 -0
  40. package/dist/graph/policies.d.ts +34 -0
  41. package/dist/graph/policies.d.ts.map +1 -0
  42. package/dist/graph/privacyPolicy.d.ts +29 -0
  43. package/dist/graph/privacyPolicy.d.ts.map +1 -0
  44. package/dist/graph/reducer.d.ts +27 -0
  45. package/dist/graph/reducer.d.ts.map +1 -0
  46. package/dist/graph/replay.d.ts +20 -0
  47. package/dist/graph/replay.d.ts.map +1 -0
  48. package/dist/graph/reviewerPolicy.d.ts +27 -0
  49. package/dist/graph/reviewerPolicy.d.ts.map +1 -0
  50. package/dist/graph/schema.d.ts +220 -0
  51. package/dist/graph/schema.d.ts.map +1 -0
  52. package/dist/graph/types.d.ts +40 -0
  53. package/dist/graph/types.d.ts.map +1 -0
  54. package/dist/graph/validate.d.ts +19 -0
  55. package/dist/graph/validate.d.ts.map +1 -0
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +873 -88
  58. package/dist/local/embeddings.d.ts +29 -0
  59. package/dist/local/embeddings.d.ts.map +1 -0
  60. package/dist/local/extractClient.d.ts +31 -0
  61. package/dist/local/extractClient.d.ts.map +1 -0
  62. package/dist/local/openai-compatible.d.ts +1 -0
  63. package/dist/local/openai-compatible.d.ts.map +1 -1
  64. package/dist/mcp/semanticRecall.d.ts +25 -0
  65. package/dist/mcp/semanticRecall.d.ts.map +1 -0
  66. package/dist/mcp/server.d.ts +22 -0
  67. package/dist/mcp/server.d.ts.map +1 -1
  68. package/dist/memory/consolidate.d.ts +21 -0
  69. package/dist/memory/consolidate.d.ts.map +1 -0
  70. package/dist/memory/extract.d.ts +68 -0
  71. package/dist/memory/extract.d.ts.map +1 -0
  72. package/dist/memory/fold.d.ts +24 -0
  73. package/dist/memory/fold.d.ts.map +1 -0
  74. package/dist/memory/index.d.ts +18 -0
  75. package/dist/memory/index.d.ts.map +1 -0
  76. package/dist/memory/inject.d.ts +29 -0
  77. package/dist/memory/inject.d.ts.map +1 -0
  78. package/dist/memory/log.d.ts +16 -0
  79. package/dist/memory/log.d.ts.map +1 -0
  80. package/dist/memory/merge.d.ts +38 -0
  81. package/dist/memory/merge.d.ts.map +1 -0
  82. package/dist/memory/rank.d.ts +32 -0
  83. package/dist/memory/rank.d.ts.map +1 -0
  84. package/dist/memory/recall.d.ts +30 -0
  85. package/dist/memory/recall.d.ts.map +1 -0
  86. package/dist/memory/temporal.d.ts +39 -0
  87. package/dist/memory/temporal.d.ts.map +1 -0
  88. package/dist/memory/types.d.ts +159 -0
  89. package/dist/memory/types.d.ts.map +1 -0
  90. package/dist/memory/vector.d.ts +18 -0
  91. package/dist/memory/vector.d.ts.map +1 -0
  92. package/dist/orchestrator/graphCancellation.d.ts +84 -0
  93. package/dist/orchestrator/graphCancellation.d.ts.map +1 -0
  94. package/dist/orchestrator/graphEffects.d.ts +63 -0
  95. package/dist/orchestrator/graphEffects.d.ts.map +1 -0
  96. package/dist/orchestrator/graphReview.d.ts +84 -0
  97. package/dist/orchestrator/graphReview.d.ts.map +1 -0
  98. package/dist/orchestrator/graphRuntime.d.ts +69 -0
  99. package/dist/orchestrator/graphRuntime.d.ts.map +1 -0
  100. package/dist/orchestrator/opencodeSessionAdapter.d.ts +117 -0
  101. package/dist/orchestrator/opencodeSessionAdapter.d.ts.map +1 -0
  102. package/dist/orchestrator/roles.d.ts +1 -1
  103. package/dist/orchestrator/roles.d.ts.map +1 -1
  104. package/dist/orchestrator/sdd.d.ts +38 -2
  105. package/dist/orchestrator/sdd.d.ts.map +1 -1
  106. package/dist/orchestrator/sddCompiler.d.ts +44 -0
  107. package/dist/orchestrator/sddCompiler.d.ts.map +1 -0
  108. package/dist/orchestrator/sessionReconciler.d.ts +74 -0
  109. package/dist/orchestrator/sessionReconciler.d.ts.map +1 -0
  110. package/dist/orchestrator/shadowComparator.d.ts +62 -0
  111. package/dist/orchestrator/shadowComparator.d.ts.map +1 -0
  112. package/dist/plugin/hooks.d.ts +13 -0
  113. package/dist/plugin/hooks.d.ts.map +1 -1
  114. package/dist/plugin/memoryInject.d.ts +25 -0
  115. package/dist/plugin/memoryInject.d.ts.map +1 -0
  116. package/dist/router/chooseModel.d.ts.map +1 -1
  117. package/dist/router/cost.d.ts +4 -0
  118. package/dist/router/cost.d.ts.map +1 -0
  119. package/dist/router/frontierBaseline.d.ts +13 -0
  120. package/dist/router/frontierBaseline.d.ts.map +1 -0
  121. package/dist/router/modelSelection.d.ts +18 -0
  122. package/dist/router/modelSelection.d.ts.map +1 -0
  123. package/dist/storage/graph/codec.d.ts +52 -0
  124. package/dist/storage/graph/codec.d.ts.map +1 -0
  125. package/dist/storage/graph/fsGraphJournal.d.ts +3 -0
  126. package/dist/storage/graph/fsGraphJournal.d.ts.map +1 -0
  127. package/dist/storage/graph/importLegacy.d.ts +62 -0
  128. package/dist/storage/graph/importLegacy.d.ts.map +1 -0
  129. package/dist/storage/graph/memoryGraphJournal.d.ts +11 -0
  130. package/dist/storage/graph/memoryGraphJournal.d.ts.map +1 -0
  131. package/dist/storage/graph/migrateLegacyBriefs.d.ts +32 -0
  132. package/dist/storage/graph/migrateLegacyBriefs.d.ts.map +1 -0
  133. package/dist/storage/graph/projections.d.ts +31 -0
  134. package/dist/storage/graph/projections.d.ts.map +1 -0
  135. package/dist/storage/graph/provider.d.ts +52 -0
  136. package/dist/storage/graph/provider.d.ts.map +1 -0
  137. package/dist/storage/graph/recovery.d.ts +38 -0
  138. package/dist/storage/graph/recovery.d.ts.map +1 -0
  139. package/dist/storage/graph/runRegistry.d.ts +17 -0
  140. package/dist/storage/graph/runRegistry.d.ts.map +1 -0
  141. package/dist/storage/graph/snapshot.d.ts +44 -0
  142. package/dist/storage/graph/snapshot.d.ts.map +1 -0
  143. package/dist/storage/graph/workspaceLease.d.ts +36 -0
  144. package/dist/storage/graph/workspaceLease.d.ts.map +1 -0
  145. package/dist/storage/graph/writer.d.ts +20 -0
  146. package/dist/storage/graph/writer.d.ts.map +1 -0
  147. package/dist/storage/index/memoryConsolidate.d.ts +24 -0
  148. package/dist/storage/index/memoryConsolidate.d.ts.map +1 -0
  149. package/dist/storage/index/memoryIndex.d.ts +52 -0
  150. package/dist/storage/index/memoryIndex.d.ts.map +1 -0
  151. package/dist/storage/index/memoryRecall.d.ts +23 -0
  152. package/dist/storage/index/memoryRecall.d.ts.map +1 -0
  153. package/dist/storage/index/memoryRuntime.d.ts +41 -0
  154. package/dist/storage/index/memoryRuntime.d.ts.map +1 -0
  155. package/dist/telemetry/events.d.ts +3 -1
  156. package/dist/telemetry/events.d.ts.map +1 -1
  157. package/dist/telemetry/graphProjection.d.ts +36 -0
  158. package/dist/telemetry/graphProjection.d.ts.map +1 -0
  159. package/dist/telemetry/hash.d.ts.map +1 -1
  160. package/dist/web/server.d.ts +4 -0
  161. package/dist/web/server.d.ts.map +1 -1
  162. package/package.json +14 -6
package/README.md CHANGED
@@ -1,57 +1,79 @@
1
1
  # openteam
2
2
 
3
- **openteam — plugin de opencode con routing coste-consciente local-first, fallback FRONTIER cheapest-capable y orquestación multiagente tipo Squad.**
3
+ > 🌐 **Language / Idioma:** **English** (this document) · [Español](README.es.md)
4
4
 
5
- ## Tabla de contenidos
5
+ **openteam — a cost-aware, local-first routing plugin for [opencode](https://opencode.ai) with cheapest-capable FRONTIER fallback and on-demand multi-agent orchestration.**
6
6
 
7
- - [Qué es y por qué existe](#qué-es-y-por-qué-existe)
8
- - [Características](#características)
9
- - [Requisitos](#requisitos)
10
- - [Instalación](#instalación)
7
+ [![CI](https://github.com/jmanuelcorral/openteam/actions/workflows/ci.yml/badge.svg)](https://github.com/jmanuelcorral/openteam/actions/workflows/ci.yml)
8
+ [![npm](https://img.shields.io/npm/v/@jmanuelcorral/openteam.svg)](https://www.npmjs.com/package/@jmanuelcorral/openteam)
9
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
10
+ [![Runtime: Bun](https://img.shields.io/badge/toolchain-bun%201.3.14-black.svg)](https://bun.sh)
11
+
12
+ > 📖 **Documentation site:** <https://jmanuelcorral.github.io/openteam/> (also available in [Español](https://jmanuelcorral.github.io/openteam/es/))
13
+
14
+ ## Table of contents
15
+
16
+ - [What it is and why it exists](#what-it-is-and-why-it-exists)
17
+ - [Features](#features)
18
+ - [Requirements](#requirements)
19
+ - [Installation](#installation)
11
20
  - [Quickstart: `openteam setup`](#quickstart-openteam-setup)
12
- - [Probar en otra máquina](#probar-en-otra-máquina)
13
- - [Actualizar openteam](#actualizar-openteam)
14
- - [Configuración](#configuración)
15
- - [Uso](#uso)
16
- - [Ejemplos en Windows](#ejemplos-en-windows)
17
- - [Privacidad](#privacidad)
18
- - [Calidad](#calidad)
19
- - [Compatibilidad](#compatibilidad)
21
+ - [The `openteam` agent](#the-openteam-agent)
22
+ - [Runtime commands](#runtime-commands)
23
+ - [Configuration](#configuration)
24
+ - [Privacy](#privacy)
25
+ - [Quality](#quality)
26
+ - [Compatibility](#compatibility)
27
+ - [Contributing](#contributing)
20
28
  - [Roadmap](#roadmap)
21
- - [Licencia](#licencia)
29
+ - [License](#license)
30
+ - [Acknowledgements](#acknowledgements)
31
+
32
+ ## What it is and why it exists
22
33
 
23
- ## Qué es y por qué existe
34
+ openteam adds a routing and orchestration layer to opencode to **save frontier tokens and cost without sacrificing quality or privacy**. The default strategy is **local-first**: trivial tasks, summaries, simple docs and small diffs try local runtimes first; architecture, security, multi-file refactors, critical tool calling and ambiguous debugging escalate to **cheapest-capable FRONTIER**.
24
35
 
25
- openteam añade a opencode una capa de routing y orquestación para ahorrar tokens y coste frontier sin perder calidad ni privacidad. La estrategia por defecto es **local-first**: tareas triviales, resúmenes, documentación sencilla y diffs pequeños intentan usar runtimes locales; tareas de arquitectura, seguridad, refactors multiarchivo, tool calling crítico o debugging ambiguo escalan a **FRONTIER cheapest-capable**.
36
+ The router keeps a privacy guarantee: with `privacyMode: "forceLocalOnSensitive"`, a task flagged as `privacySensitive` never escalates to frontier.
26
37
 
27
- El router mantiene una garantía de privacidad: con `privacyMode: "forceLocalOnSensitive"`, una tarea marcada como `privacySensitive` no escala a frontier.
38
+ ## Features
28
39
 
29
- ## Características
40
+ - Per-turn routing from the `chat.message` hook, mutating `output.message.model` before opencode persists the message.
41
+ - Registration of OpenAI-compatible local runtimes: **Ollama**, **LM Studio** and **Foundry Local**.
42
+ - Local JSON classifier with a deterministic heuristic fallback.
43
+ - Capability profiles from [Models.dev](https://models.dev), with cache and a curated fallback when the catalog is unavailable.
44
+ - **Cheapest-capable** frontier selection by blended cost `0.75 * inputUSD + 0.25 * outputUSD`.
45
+ - Budgets per session, per month and per frontier tokens per session.
46
+ - Hash-only `CostRecord` JSONL telemetry: stores `promptHash`, cost/decision metrics — **never raw prompts**.
47
+ - Multi-agent orchestration with `runRoleTask` / `runRoleTasks`, SDK child sessions and an explicit model in `client.session.prompt({ body: { model } })`.
48
+ - Local availability refresh at startup and on `session.created` / `session.idle` events.
49
+ - A local web **Console** aggregating every opencode session (cost, tokens, tool calls, routing, decisions) — redacted, loopback-only. **(alpha — see note below)**
50
+ - A read-only **MCP server** exposing aggregated team memory, plus opt-in semantic recall.
30
51
 
31
- - Routing por turno desde el hook `chat.message`, mutando `output.message.model` antes de que opencode persista el mensaje.
32
- - Registro de runtimes locales OpenAI-compatible: Ollama, LM Studio y Foundry Local.
33
- - Clasificador local JSON con fallback heurístico determinista.
34
- - Perfiles de capacidad desde Models.dev, con cache y fallback curado cuando el catálogo no está disponible.
35
- - Selección frontier **cheapest-capable** por coste blended `0.75 * inputUSD + 0.25 * outputUSD`.
36
- - Presupuestos por sesión, mes y tokens frontier por sesión.
37
- - Telemetría `CostRecord` JSONL hash-only: guarda `promptHash`, métricas de coste y decisión, nunca prompts crudos.
38
- - Orquestación Squad con `runRoleTask` / `runRoleTasks`, subsesiones SDK y modelo explícito en `client.session.prompt({ body: { model } })`.
39
- - Refresh de disponibilidad local al arrancar y en eventos `session.created` / `session.idle`.
52
+ ## Requirements
40
53
 
41
- ## Requisitos
54
+ - opencode compatible with `@opencode-ai/plugin` `1.17.13`.
55
+ - [Bun](https://bun.sh) `1.3.14` for reproducible installs, development, and tests.
56
+ - Node.js `^22.22.2 || ^24.15.0 || >=26.0.0` for the published CLI/plugin.
57
+ - Optional local runtimes:
58
+ - Ollama at `http://localhost:11434/v1`.
59
+ - LM Studio at `http://localhost:1234/v1`.
60
+ - Foundry Local with a dynamic port discovered via CLI on Windows.
42
61
 
43
- - opencode compatible con `@opencode-ai/plugin` `1.17.13`.
44
- - Bun `>=1.3` para desarrollo y tests.
45
- - Runtimes locales opcionales:
46
- - Ollama en `http://localhost:11434/v1`.
47
- - LM Studio en `http://localhost:1234/v1`.
48
- - Foundry Local con puerto dinámico descubierto por CLI en Windows.
62
+ > Local runtimes are **optional**. You can run openteam **frontier-only**, or point it at an Ollama / LM Studio running on **another machine on your LAN**.
49
63
 
50
- ## Instalación
64
+ ## Installation
51
65
 
52
- ### Opción A: paquete npm
66
+ The package is published as [`@jmanuelcorral/openteam`](https://www.npmjs.com/package/@jmanuelcorral/openteam). These are the supported installation paths:
53
67
 
54
- El paquete se publica como `@jmanuelcorral/openteam`. opencode instala los plugins declarados en el array `plugin` de `opencode.json`; basta con referenciar el nombre del paquete:
68
+ | Need | Supported method |
69
+ | --- | --- |
70
+ | Load the plugin in opencode | Add `@jmanuelcorral/openteam` to the `plugin` array in `opencode.json`. opencode resolves the package; no global CLI install is required. |
71
+ | Run setup once | `bunx --package @jmanuelcorral/openteam@latest openteam setup` |
72
+ | Keep the `openteam` CLI on `PATH` | `bun add --global @jmanuelcorral/openteam@latest`, then `openteam setup` |
73
+
74
+ Global installation with npm is **not supported**. Bun is the only supported package installer. Node.js runs the published CLI/plugin within the declared engine range; npm is limited to maintainer-only `pack`, Trusted Publishing, and `link:local` operations.
75
+
76
+ For direct opencode loading, reference the package name:
55
77
 
56
78
  ```jsonc
57
79
  {
@@ -65,17 +87,11 @@ El paquete se publica como `@jmanuelcorral/openteam`. opencode instala los plugi
65
87
  "baseline": {
66
88
  "mode": "auto",
67
89
  "pinnedModel": null,
68
- "hardDefault": {
69
- "providerID": "anthropic",
70
- "modelID": "claude-sonnet-4-5"
71
- }
90
+ "hardDefault": { "providerID": "anthropic", "modelID": "claude-sonnet-4-5" }
72
91
  },
73
92
  "router": {
74
93
  "mode": "balanced",
75
- "localDefault": {
76
- "providerID": "ollama",
77
- "modelID": "qwen3:8b"
78
- },
94
+ "localDefault": { "providerID": "ollama", "modelID": "qwen3:8b" },
79
95
  "trivialPromptMaxChars": 280,
80
96
  "frontierPromptMinChars": 2000
81
97
  },
@@ -85,19 +101,7 @@ El paquete se publica como `@jmanuelcorral/openteam`. opencode instala los plugi
85
101
  "id": "ollama",
86
102
  "enabled": true,
87
103
  "baseURL": "http://localhost:11434/v1",
88
- "defaultModel": {
89
- "providerID": "ollama",
90
- "modelID": "qwen3:8b"
91
- }
92
- },
93
- {
94
- "id": "lmstudio",
95
- "enabled": true,
96
- "baseURL": "http://localhost:1234/v1",
97
- "defaultModel": {
98
- "providerID": "lmstudio",
99
- "modelID": "qwen2.5-coder-local"
100
- }
104
+ "defaultModel": { "providerID": "ollama", "modelID": "qwen3:8b" }
101
105
  }
102
106
  ]
103
107
  },
@@ -108,246 +112,75 @@ El paquete se publica como `@jmanuelcorral/openteam`. opencode instala los plugi
108
112
  "hardStopOnBudgetExhaustion": false
109
113
  },
110
114
  "privacyMode": "forceLocalOnSensitive",
111
- "telemetry": {
112
- "enabled": true,
113
- "path": ".opencode/openteam-telemetry.jsonl"
114
- }
115
- }
116
- ]
117
- ],
118
- "provider": {
119
- "ollama": {
120
- "npm": "@ai-sdk/openai-compatible",
121
- "name": "Ollama (local)",
122
- "options": {
123
- "baseURL": "http://localhost:11434/v1",
124
- "apiKey": "ollama",
125
- "chunkTimeout": 60000
126
- },
127
- "models": {
128
- "qwen3:8b": {
129
- "name": "Qwen3 8B (Ollama)",
130
- "tool_call": true,
131
- "limit": { "context": 32768, "output": 8192 }
132
- }
133
- }
134
- },
135
- "lmstudio": {
136
- "npm": "@ai-sdk/openai-compatible",
137
- "name": "LM Studio (local)",
138
- "options": {
139
- "baseURL": "http://localhost:1234/v1",
140
- "apiKey": "lm-studio"
141
- },
142
- "models": {
143
- "qwen2.5-coder-local": {
144
- "name": "Qwen2.5 Coder Local",
145
- "tool_call": true,
146
- "limit": { "context": 32768, "output": 8192 }
147
- }
148
- }
149
- }
150
- }
151
- }
152
- ```
153
-
154
- ### Opción B: ruta de desarrollo
155
-
156
- Durante desarrollo puedes cargar un plugin local desde `.opencode/plugins/openteam.ts`:
157
-
158
- ```jsonc
159
- {
160
- "$schema": "https://opencode.ai/config.json",
161
- "plugin": [
162
- [
163
- "./.opencode/plugins/openteam.ts",
164
- {
165
- "router": {
166
- "mode": "balanced",
167
- "localDefault": {
168
- "providerID": "ollama",
169
- "modelID": "qwen3:8b"
170
- }
171
- },
172
- "telemetry": {
173
- "path": ".opencode/openteam-telemetry.jsonl"
174
- }
115
+ "telemetry": { "enabled": true, "path": ".opencode/openteam-telemetry.jsonl" }
175
116
  }
176
117
  ]
177
118
  ]
178
119
  }
179
120
  ```
180
121
 
122
+ The fastest way to get a repository ready is the interactive `openteam setup` command (below), which generates this configuration for you.
123
+
181
124
  ## Quickstart: `openteam setup`
182
125
 
183
- La forma más rápida de dejar un repositorio listo para opencode + openteam es el comando interactivo `openteam setup`. Detecta los runtimes locales instalados (Ollama, LM Studio, Foundry Local) —que son **opcionales**: puedes usar openteam **solo con frontier**, o apuntar a un Ollama/LM Studio que corra en **otra máquina de la red local**—, te deja elegir los modelos locales y el modelo **frontier baseline** (ordenados de más barato-capaz a más caro), y genera tres ficheros:
126
+ `openteam setup` detects the installed local runtimes (Ollama, LM Studio, Foundry Local — all optional), lets you pick the local models and the **frontier baseline** model (sorted cheapest-capable first), and writes three files:
184
127
 
185
- - `opencode.json` en la raíz: declara el plugin `@jmanuelcorral/openteam`, los `provider` locales OpenAI-compatible, el `model` frontier y el `small_model` local.
186
- - `.opencode/openteam.json`: la configuración runtime validada de openteam (baseline, routing, runtimes locales y privacidad).
187
- - `.opencode/agent/openteam.md`: el **agente primario `openteam`** (estilo Squad), visible en el Tab-switcher.
128
+ - `opencode.json` at the repo root: declares the `@jmanuelcorral/openteam` plugin, the OpenAI-compatible local `provider`s, the frontier `model` and the local `small_model`.
129
+ - `.opencode/openteam.json`: openteam's validated runtime configuration (baseline, routing, local runtimes and privacy).
130
+ - `.opencode/agent/openteam.md`: the **primary `openteam` agent**, visible in the Tab switcher.
188
131
 
189
132
  ```powershell
190
- # Con el paquete instalado como dependencia del proyecto
191
- bunx openteam setup
192
- # o, si lo tienes global
133
+ # One-off, without a global install
134
+ bunx --package @jmanuelcorral/openteam@latest openteam setup
135
+ # Or, after the supported global Bun install
193
136
  openteam setup
194
137
  ```
195
138
 
196
- > El antiguo comando `openteam init` sigue funcionando como **alias obsoleto** de `openteam setup`.
197
-
198
- El asistente:
199
-
200
- 1. Sondea los runtimes locales y marca los detectados.
201
- 2. Te deja habilitar runtimes (o **ninguno**: puedes usar openteam **solo con modelos frontier**) y, por cada runtime que habilites, elegir si corre **en esta máquina** o **en otra máquina de la red local** (introduciendo su URL, p. ej. `http://192.168.1.50:11434/v1`); luego eliges el modelo por defecto de cada uno (o lo escribes si no se detectan modelos).
202
- 3. Ofrece el modelo frontier baseline a partir del **catálogo completo de [Models.dev](https://models.dev)** que openteam ya integra: una lista rápida con los más **baratos-capaces primero** (incluidos los **gratuitos**, etiquetados como `gratis`), una opción **«Ver todos los modelos por proveedor…»** para navegar el catálogo completo, y **«Otro (custom)»** para escribir un `provider/model`. Si el catálogo no se puede cargar (offline), cae a la lista curada.
203
- 4. Pregunta el modo de routing (`balanced`/`economy`/`quality`), la política de privacidad y si quieres activar el **modo YOLO** (auto-aprobar permisos de opencode). Si no habilitas ningún runtime local, avisa de que estás en **modo solo frontier** y recomienda `consentBeforeFrontier` (porque `forceLocalOnSensitive` no tendría destino local).
204
- 5. Si ya existe `opencode.json` o `.opencode/openteam.json`, pide confirmación antes de sobrescribir.
205
-
206
- Tras `setup`, autentica el provider frontier (`opencode auth login`), asegúrate de que tu runtime local (en esta máquina o en la red) esté accesible si lo habilitaste, y abre opencode en el repositorio: openteam enruta local-first automáticamente. Puedes reajustar el baseline después con `openteam baseline set <provider/model>` o `openteam baseline auto`.
139
+ > The old `openteam init` command still works as a **deprecated alias** of `openteam setup`.
207
140
 
208
- ### El agente `openteam` (estilo Squad)
141
+ The wizard:
209
142
 
210
- `openteam setup` genera un único **agente primario** llamado `openteam` (`.opencode/agent/openteam.md`). Pulsa **Tab** en opencode para seleccionarlo: así sabes explícitamente que estás en modo openteam, mientras el plugin sigue optimizando el modelo por debajo.
143
+ 1. Probes local runtimes and marks the detected ones.
144
+ 2. Lets you enable runtimes (or **none** — frontier-only) and, per enabled runtime, choose whether it runs **on this machine** or **on another machine on the LAN** (by entering its URL, e.g. `http://192.168.1.50:11434/v1`), then pick each default model.
145
+ 3. Offers the frontier baseline from the **full [Models.dev](https://models.dev) catalog** that openteam integrates: a quick list with the **cheapest-capable first** (including **free** models, tagged `free`), a "Browse all models by provider…" option, and "Other (custom)" to type a `provider/model`. If the catalog can't be loaded (offline), it falls back to the curated list.
146
+ 4. Asks for the routing mode (`balanced` / `economy` / `quality`), the privacy policy, and whether to enable **YOLO mode** (auto-approve opencode permissions). If you enable no local runtime, it warns you are in **frontier-only mode** and recommends `consentBeforeFrontier`.
147
+ 5. If `opencode.json` or `.opencode/openteam.json` already exist, it asks for confirmation before overwriting.
211
148
 
212
- Ese orquestador funciona al estilo [Squad](https://bradygaster.github.io/squad/): **no trae subagentes precreados**. En **cada petición** su primera acción es comprobar si ya existe equipo (`.opencode/openteam-roster.md` + subagentes en `.opencode/agent/`). Si **existe**, reparte el trabajo entre los especialistas adecuados; si **no existe**, entiende las tareas que implica tu petición, diseña el equipo mínimo y **lo crea a demanda** —sin que tengas que pedírselo explícitamente— antes de pasarle esas tareas (escribiendo `.opencode/agent/<nombre>.md` con `mode: subagent`), reutilizando los existentes antes de crear nuevos. Los roles mecánicos/bulk se dejan enrutar a modelos locales y solo se escala a frontier para arquitectura, seguridad o debugging ambiguo.
149
+ After `setup`, authenticate the frontier provider (`opencode auth login`), make sure your local runtime is reachable if you enabled one, and open opencode in the repo: openteam routes local-first automatically. Re-tune the baseline later with `openteam baseline set <provider/model>` or `openteam baseline auto`.
213
150
 
214
- Como Squad, el equipo tiene **identidad temática**: el orquestador elige (o te pregunta) un **universo** y nombra a cada agente con un personaje de ese universo, registrando el reparto en `.opencode/openteam-roster.md` (fuera de `.opencode/agent/`, para que opencode no lo cargue como un agente fantasma) para que los nombres **persistan** entre sesiones. Además de los roles específicos del proyecto, contempla tres **roles estándar** creados a demanda:
151
+ ## The `openteam` agent
215
152
 
216
- - **scribe** — memoria silenciosa: registra decisiones y aprendizajes en `.opencode/openteam-decisions.md` sin tocar el código (modelo local).
217
- - **ralph** — automatización y triage: monitoriza el trabajo pendiente, lo prioriza, coordina la ejecución y **escala al humano** ante bloqueos o aprobaciones.
218
- - **guardian** — seguridad y privacidad: **detecta y enmascara datos sensibles** (PII, secretos, API keys, tokens) antes de que salgan a frontier y hace revisión de seguridad; corre siempre en local y respeta `forceLocalOnSensitive`.
153
+ `openteam setup` generates a single **primary agent** named `openteam`. Press **Tab** in opencode to select it: you explicitly know you are in openteam mode while the plugin keeps optimizing the model underneath.
219
154
 
220
- Antes de delegar, el orquestador **planifica dependencias y paraleliza**: descompone la petición en tareas, y como opencode ejecuta en paralelo todas las llamadas `task` emitidas en un mismo turno (Vercel AI SDK), lanza a la vez las tareas independientes y secuencia por olas solo las que dependen de un resultado previo. El trabajo que colisiona sobre los mismos ficheros se separa en olas distintas para evitar conflictos.
155
+ That orchestrator ships **no pre-created subagents**. On **every request** its first action is to check whether a team already exists (`.opencode/openteam-roster.md` + subagents in `.opencode/agent/`). If it does, it hands work to the right specialists; if not, it understands the tasks your request implies, designs the minimal team and **creates it on demand** (writing `.opencode/agent/<name>.md` with `mode: subagent`), reusing existing agents before creating new ones. Mechanical/bulk roles are left to route to local models; only architecture, security or ambiguous debugging escalate to frontier. (This on-demand, themed-team model is inspired by [Squad](https://bradygaster.github.io/squad/) — see [Acknowledgements](#acknowledgements).)
221
156
 
222
- En la **lista de tareas** (`todowrite`, la que ves en el todo general de opencode) cada entrada lleva **visible el responsable**. opencode no tiene un campo de "agente" en sus todos (solo `content`/`status`/`priority`, y la lista es por sesión), así que el orquestador usa una convención en el texto: prefija cada tarea con el nombre del casting, p. ej. `[@Basher] Implementar el router` o `[@openteam] Sintetizar resultados`. Así, de un vistazo, sabes quién es responsable de cada tarea.
157
+ The team has a **themed identity**: the orchestrator picks (or asks for) a **universe** and names each agent after a character, recording the cast in `.opencode/openteam-roster.md` so names **persist** across sessions. Besides project-specific roles, it plans three **standard roles** created on demand:
223
158
 
224
- ## Probar en otra máquina
159
+ - **scribe** — silent memory: logs decisions and learnings to `.opencode/openteam-decisions.md` without touching code (local model).
160
+ - **ralph** — automation and triage: monitors the backlog, prioritizes, coordinates execution and **escalates to the human** on blockers or approvals.
161
+ - **guardian** — security and privacy: **detects and masks sensitive data** (PII, secrets, API keys, tokens) before it reaches frontier; always runs locally and respects `forceLocalOnSensitive`.
225
162
 
226
- Para instalar y probar openteam en otro equipo que ya tenga [opencode](https://opencode.ai) y [Bun](https://bun.sh):
163
+ Before delegating, the orchestrator **plans dependencies and parallelizes**: it splits the request into tasks and, since opencode runs all `task` calls emitted in a single turn in parallel (Vercel AI SDK), it launches independent tasks together and sequences only the dependent ones into waves. Work that collides on the same files is separated into distinct waves to avoid conflicts. In the **todo list** each entry shows the responsible agent via a name prefix, e.g. `[@Basher] Implement the router`.
227
164
 
228
- 1. **Instala el paquete.** Global o como dependencia de desarrollo del repo que quieras usar:
165
+ ## Runtime commands
229
166
 
230
- ```powershell
231
- # Opción global (deja el comando `openteam` en el PATH)
232
- npm install -g @jmanuelcorral/openteam
167
+ openteam exposes commands to inspect and change routing without editing JSON by hand, over three equivalent surfaces.
233
168
 
234
- # …o como dependencia de desarrollo del proyecto
235
- bun add -d @jmanuelcorral/openteam # (o: npm install -D @jmanuelcorral/openteam)
236
- ```
169
+ ### 1. In-conversation tool
237
170
 
238
- 2. **Inicializa el repositorio** donde vayas a trabajar. Genera `opencode.json`, `.opencode/openteam.json` y `.opencode/agent/openteam.md`:
171
+ The plugin registers the `openteam` tool. Ask the agent to use it, or install the `/openteam` command. Actions:
239
172
 
240
- ```powershell
241
- cd C:\ruta\a\tu\repo
242
- openteam setup # global
243
- # …o, si lo instalaste como dependencia del proyecto:
244
- bunx openteam setup
245
- ```
173
+ - `show` — show the effective baseline.
174
+ - `set` (with `model` as `provider/model`) — pin the baseline (`pinned` mode).
175
+ - `auto` — return to cheapest-capable (`auto` mode).
176
+ - `doctor` — diagnostics for local runtimes, privacy and telemetry.
177
+ - `report` — cost and savings summary from telemetry.
246
178
 
247
- El asistente detecta Ollama / LM Studio / Foundry Local, te deja elegir los modelos locales (locales o en otra máquina de la red) o **ninguno** para funcionar solo con frontier, y el frontier baseline, y escribe la configuración.
248
-
249
- 3. **Autentica el provider frontier** que hayas elegido:
250
-
251
- ```powershell
252
- opencode auth login
253
- ```
254
-
255
- 4. **Arranca tu runtime local** si lo habilitaste y no estaba activo (p. ej. `ollama serve`, o abre LM Studio / Foundry Local). Si apuntaste a un runtime en **otra máquina de la red**, asegúrate de que sea accesible desde este equipo (host expuesto y puerto abierto); para Ollama esto normalmente implica arrancarlo con `OLLAMA_HOST=0.0.0.0 ollama serve` en la máquina remota. Si configuraste **solo frontier**, sáltate este paso.
256
-
257
- 5. **Abre opencode en el repo**, pulsa **Tab** y elige el agente `openteam`. Dale el primer prompt: creará el equipo de subagentes a demanda y enrutará local-first automáticamente.
258
-
259
- Comprueba el estado con `openteam doctor` (runtimes + config) y el ahorro con `openteam report`.
260
-
261
- ## Actualizar openteam
262
-
263
- openteam se publica en npm de forma continua; cada push a `master` publica un nuevo patch. Para traer la última versión:
264
-
265
- ```powershell
266
- # Instalación global
267
- npm install -g @jmanuelcorral/openteam@latest
268
-
269
- # Dependencia de desarrollo del proyecto
270
- bun add -d @jmanuelcorral/openteam@latest # (o: npm install -D @jmanuelcorral/openteam@latest)
271
- ```
272
-
273
- Comprobar versiones:
274
-
275
- ```powershell
276
- npm view @jmanuelcorral/openteam version # última publicada en npm
277
- npm ls -g @jmanuelcorral/openteam # instalada globalmente (o `npm ls …` en el repo)
278
- ```
279
-
280
- Notas al actualizar:
281
-
282
- - **No necesitas volver a ejecutar `openteam setup`** para actualizar el plugin: opencode resuelve el paquete `@jmanuelcorral/openteam` declarado en `opencode.json` a la versión instalada. Reinicia opencode para que recargue el plugin.
283
- - Vuelve a ejecutar `openteam setup` **solo** si quieres regenerar la configuración (cambiar runtimes, modelos o baseline). Pedirá confirmación antes de sobrescribir `opencode.json`, `.opencode/openteam.json` o `.opencode/agent/openteam.md`; **no toca los subagentes** que el orquestador haya creado a demanda.
284
- - Ajustes puntuales sin reinit: `openteam baseline set <provider/model>` o `openteam baseline auto`.
285
-
286
- ## Configuración
287
-
288
- La configuración runtime canónica vive en `.opencode/openteam.json`; este repositorio incluye `.opencode/openteam.example.json` como ejemplo completo. La forma validada por Zod es la de `src/config/schema.ts`. `telemetry` es una opción del plugin leída por `src/index.ts`, no parte del objeto `OpenTeamConfig` persistido.
289
-
290
- | Key | Tipo | Default | Descripción |
291
- | --- | --- | --- | --- |
292
- | `baseline.mode` | `"auto" \| "pinned"` | `"auto"` | En `auto`, usa perfiles frontier cheapest-capable cuando se pasan al router; en `pinned`, usa `baseline.pinnedModel` si existe. |
293
- | `baseline.pinnedModel` | `ModelRef \| null` | `null` | Modelo frontier fijado explícitamente. `ModelRef` usa `{ "providerID": string, "modelID": string }`. |
294
- | `baseline.hardDefault` | `ModelRef` | `{ "providerID": "anthropic", "modelID": "claude-sonnet-4-5" }` | Fallback frontier si no hay perfiles cheapest-capable o pin válido. |
295
- | `router.mode` | `"economy" \| "balanced" \| "quality"` | `"balanced"` | Modo de routing validado y reservado para política. |
296
- | `router.localDefault` | `ModelRef` | `{ "providerID": "ollama", "modelID": "qwen3:8b" }` | Modelo local principal. |
297
- | `router.trivialPromptMaxChars` | `number` entero positivo | `280` | Prompts sin código hasta este tamaño prefieren local. |
298
- | `router.frontierPromptMinChars` | `number` entero positivo | `2000` | Prompts desde este tamaño se tratan como candidatos a frontier si no aplican guards. |
299
- | `local.runtimes` | `LocalRuntime[]` | Ollama enabled en `http://localhost:11434/v1` con `qwen3:8b` | Lista mínima de un runtime local. |
300
- | `local.runtimes[].id` | `"ollama" \| "lmstudio" \| "foundry-local"` | requerido | Runtime local. |
301
- | `local.runtimes[].enabled` | `boolean` | `true` | Habilita o deshabilita ese runtime. |
302
- | `local.runtimes[].baseURL` | URL opcional | según runtime/config | Endpoint OpenAI-compatible `/v1`; Foundry Local puede omitirlo si usa discovery. |
303
- | `local.runtimes[].discovery` | `"cli" \| "sdk" \| "manual"` opcional | sin default por item | Discovery de Foundry Local; el registry usa CLI si está configurado y no es `manual`. |
304
- | `local.runtimes[].defaultModel` | `ModelRef` | requerido | Modelo por defecto de ese runtime. |
305
- | `budgets.sessionUSD` | `number` positivo opcional | sin límite | Presupuesto frontier por sesión. |
306
- | `budgets.monthlyUSD` | `number` positivo opcional | sin límite | Presupuesto frontier mensual. |
307
- | `budgets.frontierTokensPerSession` | `number` entero positivo opcional | sin límite | Límite de tokens frontier por sesión. |
308
- | `budgets.hardStopOnBudgetExhaustion` | `boolean` | `false` | Si es `true`, agotar presupuesto devuelve `blockFrontier`; si es `false`, fuerza local. |
309
- | `privacyMode` | `"forceLocalOnSensitive" \| "consentBeforeFrontier" \| "off"` | `"forceLocalOnSensitive"` | Política de privacidad para tareas sensibles. |
310
- | `telemetry.enabled` | `boolean` plugin option | `true` | Activa/desactiva escritura JSONL. |
311
- | `telemetry.path` | `string` plugin option | `.opencode/openteam-telemetry.jsonl` | Ruta del log `CostRecord` JSONL. |
312
-
313
- ## Uso
314
-
315
- En cada turno, openteam deriva señales del prompt (`promptChars`, `hasCode`, `privacySensitive`, `requiresTools` y override de modelo si existe), ejecuta `chooseModel` y asigna `output.message.model`.
316
-
317
- La orquestación Squad usa roles estáticos y subsesiones opencode:
318
-
319
- | Rol | Agent opencode | Tier base | Política |
320
- | --- | --- | --- | --- |
321
- | `rusty` | `architect` | `hard` | Arquitectura y decisiones de alto riesgo; frontier auto. |
322
- | `livingston` | `integration` | `moderate` | Integración TS/opencode; tool calling por defecto. |
323
- | `yen` | `local-runtime` | `moderate` | Runtimes locales; local-first con fallback frontier. |
324
- | `basher` | `routing-cost` | `moderate` | Router, coste y presupuesto; local-first. |
325
- | `scribe` | `scribe` | `trivial` | Documentación y resúmenes; local-first. |
326
- | `linus` | `tester` | `simple` | Tests y contratos; local-first con tools. |
327
-
328
- `runRoleTask` ejecuta una subsesión; `runRoleTasks` ejecuta varias con `batchID`. Los roles con `destructive` o `multiFileEdit` elevan el tier antes de elegir modelo.
329
-
330
- Para ver ahorro y decisiones, revisa el JSONL de telemetría. Campos clave: `promptHash`, `promptChars`, `tier`, `routeKind`, `selected`, `rationale`, `estimatedCostUSD`, `baselineCostUSD`, `estimatedSavingsUSD`, `budgetAction`, `tokensIn` y `tokensOut`.
331
-
332
- ## Comandos runtime
333
-
334
- openteam expone comandos para inspeccionar y cambiar el routing sin editar JSON a mano. Hay tres superficies equivalentes:
335
-
336
- ### 1. Tool en la conversación
337
-
338
- El plugin registra la herramienta `openteam`. Pídele al agente que la use, o instala el comando `/openteam` (ver más abajo). Acciones:
339
-
340
- - `show` — muestra el baseline efectivo.
341
- - `set` (con `model` en formato `provider/model`) — fija el baseline (modo `pinned`).
342
- - `auto` — vuelve a cheapest-capable (modo `auto`).
343
- - `doctor` — diagnóstico de runtimes locales, privacidad y telemetría.
344
- - `report` — resumen de coste y ahorro desde la telemetría.
345
-
346
- Los cambios de `set`/`auto` se persisten en `.opencode/openteam.json` y aplican en el siguiente arranque del plugin.
179
+ `set` / `auto` changes are persisted to `.opencode/openteam.json` and apply on the next plugin start.
347
180
 
348
181
  ### 2. Slash command `/openteam`
349
182
 
350
- `openteam setup` **genera automáticamente** `.opencode/command/openteam.md`, así que el comando `/openteam` aparece en opencode sin pasos manuales. (Si vienes de una versión anterior, vuelve a ejecutar `openteam setup` para crearlo, o cópialo a mano a tu proyecto o a `~/.config/opencode/command/`.) Después:
183
+ `openteam setup` **automatically generates** `.opencode/command/openteam.md`, so `/openteam` appears in opencode with no manual steps:
351
184
 
352
185
  ```text
353
186
  /openteam baseline show
@@ -359,14 +192,14 @@ Los cambios de `set`/`auto` se persisten en `.opencode/openteam.json` y aplican
359
192
  /openteam report
360
193
  ```
361
194
 
362
- > ¿No ves `/openteam` en opencode? Asegúrate de que existe `.opencode/command/openteam.md` (lo crea `openteam setup`) y **reinicia/recarga opencode** para que descubra el comando.
195
+ > Don't see `/openteam`? Make sure `.opencode/command/openteam.md` exists (created by `openteam setup`) and **restart/reload opencode** to discover it.
363
196
 
364
197
  ### 3. CLI (`bin`)
365
198
 
366
- El paquete expone el binario `openteam`. Con instalación global:
199
+ The package exposes the `openteam` binary. With a global install:
367
200
 
368
201
  ```powershell
369
- npm i -g @jmanuelcorral/openteam
202
+ bun add --global @jmanuelcorral/openteam@latest
370
203
  openteam baseline show
371
204
  openteam baseline set openai/gpt-5-mini
372
205
  openteam doctor --config .opencode/openteam.json
@@ -374,275 +207,175 @@ openteam agents
374
207
  openteam console
375
208
  openteam report --telemetry .opencode/openteam-telemetry.jsonl
376
209
  openteam yolo status
377
- openteam yolo on
378
210
  openteam local status
379
- openteam local off
380
211
  ```
381
212
 
382
- Flags: `--config <path>` y `--telemetry <path>` sobrescriben las rutas por defecto; `--opencode <path>` apunta el comando `yolo` a un `opencode.json` concreto.
213
+ Flags: `--config <path>` and `--telemetry <path>` override the default paths; `--opencode <path>` points the `yolo` command at a specific `opencode.json`.
383
214
 
384
- ### Ver el LLM de cada agente: `openteam agents`
215
+ ### See each agent's LLM: `openteam agents`
385
216
 
386
- Lista los agentes de `.opencode/agent/` indicando **qué LLM usa cada uno**: si es **local** (Ollama/LM Studio/Foundry, sin coste de tokens) o **frontier** (consume tu suscripción), y el **proveedor** (Anthropic, OpenAI, GitHub Copilot, Google…). Los agentes sin `model` propio **heredan** el default de `opencode.json` (que openteam enruta local-first por mensaje).
387
-
388
- ```powershell
389
- openteam agents
390
- ```
391
-
392
- ```text
393
- openteam agents — LLM por agente:
394
-
395
- ● openteam [primary ] frontier · Anthropic (consume tu suscripción) (anthropic/claude-sonnet-4-5)
396
- ○ basher [subagent] local · Ollama (sin coste de tokens) (ollama/qwen3:8b)
397
- ○ scribe [subagent] hereda default → frontier · Anthropic (consume tu suscripción) · openteam enruta local-first por mensaje
398
-
399
- Default de opencode.json: anthropic/claude-sonnet-4-5 (frontier · Anthropic)
400
- Leyenda: ● primary · ○ subagent · local = sin coste de tokens · frontier = consume tu suscripción.
401
- ```
402
-
403
- También está disponible **dentro de opencode**: pídele a openteam la lista de agentes y ejecutará la acción `agents` de su herramienta de comandos.
217
+ Lists the agents in `.opencode/agent/`, showing **which LLM each one uses**: whether it is **local** (Ollama/LM Studio/Foundry, no token cost) or **frontier** (consumes your subscription), and the provider. Agents without their own `model` **inherit** the `opencode.json` default (which openteam routes local-first per message).
404
218
 
219
+ ### YOLO mode (auto-approve permissions)
405
220
 
406
- ### Modo YOLO (auto-aprobar permisos)
407
-
408
- El **modo YOLO** hace que opencode auto-apruebe **todos** los permisos (equivale al flag nativo `opencode --auto`, pero persistente). Escribe la regla global `permission: { "*": "allow" }` en `opencode.json` y **regenera el agente `openteam`** (`.opencode/agent/openteam.md`) con el mismo comodín, conservando el resto de tu configuración:
221
+ **YOLO mode** makes opencode auto-approve **all** permissions (like the native `opencode --auto` flag, but persistent). It writes the global rule `permission: { "*": "allow" }` to `opencode.json` and **regenerates the `openteam` agent** with the same wildcard:
409
222
 
410
223
  ```powershell
411
- openteam yolo status # ¿está activo?
412
- openteam yolo on # activa YOLO
413
- openteam yolo off # desactiva YOLO
224
+ openteam yolo status # is it active?
225
+ openteam yolo on # enable YOLO
226
+ openteam yolo off # disable YOLO
414
227
  ```
415
228
 
416
- También puedes activarlo durante `openteam setup` (te lo pregunta), o al vuelo con `opencode --auto` sin tocar la config.
417
-
418
- > **Importante: el permiso del agente anula al global.** opencode fusiona el permiso del frontmatter de cada agente **después** del global y gana la última regla que casa; por eso `openteam yolo on/off` regenera `.opencode/agent/openteam.md` para que su `permission` coincida con el estado YOLO. Sin esto, un `bash: ask`/`external_directory: deny` en el agente seguiría pidiendo confirmación aunque el global fuese `"*": allow`. Tras cambiar el modo, **reinicia o recarga opencode** para que los agentes tomen los nuevos permisos, y crea los subagentes con el mismo comodín cuando YOLO esté activo (el orquestador ya lo hace).
229
+ > **The agent permission overrides the global one.** opencode merges each agent's frontmatter permission **after** the global one and the last matching rule wins, so `openteam yolo on/off` regenerates `.opencode/agent/openteam.md` to keep its `permission` in sync. After changing mode, **restart or reload opencode**.
419
230
 
420
- > **YOLO no desactiva la privacidad de openteam.** Solo afecta a las aprobaciones de permisos de opencode; con `privacyMode: "forceLocalOnSensitive"`, los prompts sensibles siguen sin salir a frontier. Úsalo solo en entornos de confianza: auto-aprueba también `bash`, escrituras y accesos fuera del workspace (salvo reglas `deny` explícitas).
231
+ > **YOLO does not disable openteam privacy.** It only affects opencode permission approvals; with `privacyMode: "forceLocalOnSensitive"`, sensitive prompts still never leave for frontier. Use it only in trusted environments.
421
232
 
422
- ### Solo frontier (sin runtime local): `openteam local`
233
+ ### Frontier-only (no local runtime): `openteam local`
423
234
 
424
- Si **no tienes ningún runtime local** (Ollama/LM Studio/Foundry Local) o prefieres no usarlo, puedes forzar que openteam enrute **siempre a modelos frontier**. `openteam setup` ya activa este modo automáticamente cuando no habilitas ningún runtime, pero puedes alternarlo en cualquier momento sin repetir el setup:
235
+ If you have **no local runtime** or prefer not to use one, you can force openteam to route **always to frontier models**:
425
236
 
426
237
  ```powershell
427
- openteam local status # ¿local-first o solo frontier? + runtimes configurados
428
- openteam local off # solo frontier (desactiva el routing local-first)
429
- openteam local on # vuelve al routing local-first
238
+ openteam local status # local-first or frontier-only? + configured runtimes
239
+ openteam local off # frontier-only (disable local-first routing)
240
+ openteam local on # back to local-first routing
430
241
  ```
431
242
 
432
- Esto persiste el flag `router.frontierOnly` en `.opencode/openteam.json`. Con `frontierOnly` activo, el router escoge el **frontier cheapest-capable** en lugar de la heurística local-first, pero **respeta la privacidad, los presupuestos y los overrides explícitos por tarea**: los prompts sensibles con `forceLocalOnSensitive` no salen a frontier, y `local off` degrada esa política a `consentBeforeFrontier` (imposible forzar local sin runtime) informándote del cambio.
433
-
434
- ### Modo desatendido: `openteam loop` (patrón Ralph) 🎯 *(diseño)*
435
-
436
- Segundo modo de operación: un **bucle externo** que invoca `opencode run` contra un backlog persistente hasta vaciarlo, con contexto fresco por iteración y topes de seguridad (presupuesto, máx. iteraciones, sin-progreso). Complementa al orquestador interactivo, no lo sustituye. Consulta el diseño y los ejemplos en **[docs/loop.md](docs/loop.md)**.
243
+ This persists the `router.frontierOnly` flag in `.opencode/openteam.json`. With `frontierOnly` active the router picks the **cheapest-capable frontier**, but still **respects privacy, budgets and explicit per-task overrides**. Sensitive prompts with `forceLocalOnSensitive` don't leave for frontier; `local off` degrades that policy to `consentBeforeFrontier` (local can't be forced without a runtime) and tells you about the change.
437
244
 
438
- ### Console web multi-sesión (se lanza desde la CLI)
245
+ ### Multi-session web Console: `openteam console` (alpha)
439
246
 
440
- openteam expone una **Console web local** que **lanzas tú desde la CLI** con
441
- `openteam console`.
442
- Agrega **todas** las sesiones de opencode a la vez: puedes tener varias pestañas
443
- de opencode abiertas y todas aparecen en la **misma** Console, con una pestaña por
444
- sesión (más "Todas"), porque cada plugin **escribe eventos redactados** en logs
445
- JSONL por sesión y la Console los vigila (`fs.watch`) y **agrega**.
247
+ > ⚠️ **Alpha — not finished.** The Console (and the `tunnel` command below) is an
248
+ > early, experimental feature that may still be **reworked or rebuilt**, with
249
+ > breaking changes to its UI, endpoints, config (`console` block) and event
250
+ > format. The routing, budgets, telemetry and memory core are stable; the web
251
+ > surface is not yet. Use it for local observation, not as a stable API.
446
252
 
447
- Muestra en vivo: **coste y tokens reales por mensaje** (input/output/reasoning/
448
- cache), **toolcalls con duración** y ok/fallo, ruteo reciente (coste/ahorro y
449
- modelo elegido, **solo hashes de prompt, nunca el texto**), **decisiones** de los
450
- agentes (scribe) y **reuniones** (batches multi-agente del orquestador), progreso
451
- del backlog del loop, el equipo de agentes (LLM local/frontier de cada uno) y
452
- últimos commits. Se actualiza por **SSE** (con *polling* de respaldo).
253
+ openteam exposes a **local web Console** you launch from the CLI with `openteam console`. It aggregates **all** opencode sessions at once (one tab per session, plus "All"), because each plugin **writes redacted events** to per-session JSONL logs that the Console watches (`fs.watch`) and aggregates.
453
254
 
454
- Cada pestaña de sesión incluye además una **vista "Sesión"**: una consola por la
455
- que puedes **ver la salida en vivo** (SSE) y **enviar prompts** o **responder
456
- permisos** a esa sesión de opencode, autenticada con un **token efímero** por
457
- arranque. Opcionalmente, con el flag `terminal.pty`, una **vista "Terminal"** abre
458
- una **shell real** en el workspace vía la API de PTY de opencode (sin `node-pty`).
459
-
460
- Lánzala contra el repo actual; escucha en loopback y corre hasta **Ctrl+C**:
255
+ It shows live: **real cost and tokens per message** (input/output/reasoning/cache), **tool calls with duration** and ok/fail, recent routing (cost/savings and chosen model — **prompt hashes only, never text**), agent **decisions** (scribe) and **meetings** (multi-agent batches), loop backlog progress, the agent team and latest commits. It updates over **SSE** (with polling fallback).
461
256
 
462
257
  ```powershell
463
- openteam console # imprime la URL y sirve la Console multi-sesión
464
- openteam console --open # además abre el navegador
465
- openteam console --status # solo imprime la config (no lanza el servidor)
466
- ```
467
-
468
- Las sesiones se leen de:
469
-
470
- ```text
471
- .opencode/openteam/sessions/*.jsonl
258
+ openteam console # print the URL and serve the multi-session Console
259
+ openteam console --open # also open the browser
260
+ openteam console --status # print the config only (don't launch the server)
472
261
  ```
473
262
 
474
- Puedes ajustar host/puerto y la terminal en `.opencode/openteam.json` (bloque
475
- `console`):
476
-
477
- ```json
478
- {
479
- "console": {
480
- "host": "127.0.0.1",
481
- "port": 4599,
482
- "autoPortFallback": true,
483
- "refreshMs": 2000,
484
- "recentRoutes": 50,
485
- "openBrowser": false,
486
- "terminal": { "enabled": true, "pty": false }
487
- }
488
- }
489
- ```
263
+ > **Security**: the server listens **on loopback only** (`127.0.0.1`/`localhost`, Zod-validated) and **never exposes prompts** (only `promptHash`), tool-call args or message content — only counters, costs and redacted summaries. The "Session"/"Terminal" view requires the ephemeral token.
490
264
 
491
- > **Seguridad**: el servidor escucha **solo en loopback** (`127.0.0.1`/`localhost`, validado por Zod) y **nunca expone prompts** (solo `promptHash`), args de toolcall ni contenido de mensajes: solo contadores, costes y resúmenes redactados. La vista "Sesión"/"Terminal" exige el token efímero. Si el puerto está ocupado y `autoPortFallback` es `true`, prueba el siguiente libre.
265
+ ### Secure remote access: `openteam tunnel` (alpha)
492
266
 
493
- ### Acceso remoto seguro: `openteam tunnel`
267
+ > ⚠️ **Alpha — not finished.** Like the Console, `tunnel` is experimental and may
268
+ > be reworked or rebuilt. Treat its flags and behavior as unstable.
494
269
 
495
- Para acceder a la Console (y, opcionalmente, operar la terminal) **desde fuera**,
496
- `openteam tunnel` la expone vía **Microsoft Dev Tunnels** en lugar de bindear a
497
- `0.0.0.0`. Comprueba que `devtunnel` esté instalado y con sesión iniciada,
498
- hospeda el puerto de la Console e imprime la URL pública hasta **Ctrl+C**:
270
+ To reach the Console (and optionally operate the terminal) **from outside**, `openteam tunnel` exposes it via **Microsoft Dev Tunnels** instead of binding to `0.0.0.0`:
499
271
 
500
272
  ```powershell
501
- openteam tunnel # expone solo la Console (observación), autenticado
502
- openteam tunnel --terminal # además expone opencode para la terminal remota
503
- openteam tunnel --allow-anonymous --yes # túnel anónimo (requiere doble confirmación)
273
+ openteam tunnel # expose only the Console (observation), authenticated
274
+ openteam tunnel --terminal # also expose opencode for the remote terminal
275
+ openteam tunnel --allow-anonymous --yes # anonymous tunnel (requires double confirmation)
504
276
  ```
505
277
 
506
- > **Seguridad del túnel**: autenticado por defecto. La **terminal remota** exige
507
- > `OPENCODE_SERVER_PASSWORD` definido; sin ella, `--terminal` se ignora y solo se
508
- > expone la Console (observación). El túnel **anónimo** requiere `--yes` (doble
509
- > confirmación) y avisa de que opencode puede ejecutar comandos y editar ficheros.
510
- > Instala devtunnel con `winget install Microsoft.devtunnel` e inicia sesión con
511
- > `devtunnel user login`.
278
+ > **Tunnel security**: authenticated by default. The **remote terminal** requires `OPENCODE_SERVER_PASSWORD` to be set; without it, `--terminal` is ignored. Install devtunnel with `winget install Microsoft.devtunnel` and sign in with `devtunnel user login`.
512
279
 
513
- ### Memoria del equipo por MCP (solo lectura): `openteam mcp`
280
+ ### Team memory over MCP (read-only): `openteam mcp`
514
281
 
515
- `openteam mcp` arranca un **servidor MCP de solo lectura** (JSON-RPC 2.0 sobre
516
- stdio, sin dependencias) que expone la memoria del equipo agregada desde los
517
- eventos por sesión para que agentes/herramientas la consulten. Se apoya en el
518
- mismo `StorageProvider` que la Console y **nunca** expone prompts crudos, solo el
519
- estado ya redactado. Tools disponibles: `list_decisions` (filtrable por
520
- `agent`/`tag`), `list_meetings`, `list_sessions` y `cost_summary` (coste/tokens
521
- reales + ahorro estimado vs baseline all-frontier).
282
+ `openteam mcp` starts a **read-only MCP server** (JSON-RPC 2.0 over stdio, no dependencies) that exposes the team memory aggregated from per-session events. It uses the same `StorageProvider` as the Console and **never** exposes raw prompts. Tools: `list_decisions` (filterable by `agent`/`tag`), `list_meetings`, `list_sessions` and `cost_summary`.
522
283
 
523
- Regístralo en `opencode.json` como cualquier MCP server local:
284
+ Register it in `opencode.json` like any local MCP server:
524
285
 
525
286
  ```json
526
287
  {
527
288
  "mcp": {
528
- "openteam-memory": {
529
- "type": "local",
530
- "command": ["openteam", "mcp"]
531
- }
289
+ "openteam-memory": { "type": "local", "command": ["openteam", "mcp"] }
532
290
  }
533
291
  }
534
292
  ```
535
293
 
294
+ Opt-in **semantic recall** (`recall_facts`, `recall_preferences`, `similar_tasks`) is available via the `memory.semantic` block in `.opencode/openteam.json`; queries are embedded **locally** (never leave for frontier). See [docs/architecture.md](docs/architecture.md) and the Spanish [README.es.md](README.es.md) for full details.
536
295
 
296
+ ## Configuration
537
297
 
538
- ### Ollama
539
-
540
- ```powershell
541
- ollama serve
542
- ollama pull qwen3:8b
543
- Invoke-RestMethod -Uri "http://localhost:11434/v1/models" -Method Get
544
- ```
545
-
546
- ### LM Studio
547
-
548
- 1. Abre LM Studio.
549
- 2. Carga un modelo compatible.
550
- 3. Activa el servidor local OpenAI-compatible en el puerto `1234`.
551
-
552
- ```powershell
553
- Invoke-RestMethod -Uri "http://localhost:1234/v1/models" -Method Get
554
- ```
555
-
556
- ### Foundry Local
298
+ The canonical runtime configuration lives in `.opencode/openteam.json`; this repo ships `.opencode/openteam.example.json` as a complete example. The Zod-validated shape is in `src/config/schema.ts`. `telemetry` is a plugin option read by `src/index.ts`, not part of the persisted `OpenTeamConfig`.
557
299
 
558
- ```powershell
559
- foundry service status
560
- ```
561
-
562
- openteam extrae el puerto de la salida del CLI y normaliza el endpoint a `http://localhost:<PORT>/v1`.
563
-
564
- ### Telemetría
565
-
566
- ```powershell
567
- $telemetryPath = "C:\gitrepos\openteam\.opencode\openteam-telemetry.jsonl"
568
- Get-Content -Path $telemetryPath -Tail 5
569
- ```
570
-
571
- ### Verificación local
572
-
573
- ```powershell
574
- Set-Location -Path "C:\gitrepos\openteam"
575
- bun test
576
- bun run typecheck
577
- bun run lint
578
- bun run format:check
579
- # Cuando el empaquetado de Fase 4 exponga el script:
580
- bun run build
581
- ```
582
-
583
- ### Desarrollo local en modo dev (sin registry)
584
-
585
- Para que la CLI global `openteam` y opencode usen la build local de este repo en
586
- lugar de la versión publicada (sin pasar por ningún registry), se enlaza el
587
- paquete con un symlink global:
588
-
589
- ```powershell
590
- Set-Location -Path "C:\gitrepos\openteam"
591
- bun run link:local # = bun run build && npm link
592
- ```
593
-
594
- `npm link` crea un enlace global (junction/symlink) hacia este repo, así que tras
595
- cada `bun run build` la CLI global refleja el código local.
596
-
597
- Un hook `pre-push` versionado (`.githooks/pre-push`) ejecuta `bun run link:local`
598
- automáticamente antes de cada `git push`, manteniendo la instalación local al día.
599
- El hook se activa vía `core.hooksPath=.githooks`, que el script `prepare` configura
600
- automáticamente al ejecutar `bun install` en el repo. Es best-effort: si el build o
601
- el link fallan, avisa pero **no bloquea** el push.
602
-
603
- ## Privacidad
604
-
605
- Con `privacyMode: "forceLocalOnSensitive"`, si `TaskSignals.privacySensitive` es `true`, `chooseModel` usa local y no permite fallback frontier. Si no hay local utilizable, la decisión conserva la ruta local y registra la razón en `rationale`.
606
-
607
- La telemetría usa `hashPrompt`, actualmente `fnv1a32:<hash>`, y no serializa el prompt completo.
608
-
609
- ## Calidad
610
-
611
- Gates no negociables:
300
+ | Key | Type | Default | Description |
301
+ | --- | --- | --- | --- |
302
+ | `baseline.mode` | `"auto" \| "pinned"` | `"auto"` | In `auto`, uses cheapest-capable frontier profiles when passed to the router; in `pinned`, uses `baseline.pinnedModel` if set. |
303
+ | `baseline.pinnedModel` | `ModelRef \| null` | `null` | Explicitly pinned frontier model. `ModelRef` is `{ "providerID": string, "modelID": string }`. |
304
+ | `baseline.hardDefault` | `ModelRef` | `{ "providerID": "anthropic", "modelID": "claude-sonnet-4-5" }` | Frontier fallback when there are no cheapest-capable profiles or a valid pin. |
305
+ | `router.mode` | `"economy" \| "balanced" \| "quality"` | `"balanced"` | Validated routing mode reserved for policy. |
306
+ | `router.localDefault` | `ModelRef` | `{ "providerID": "ollama", "modelID": "qwen3:8b" }` | Primary local model. |
307
+ | `router.trivialPromptMaxChars` | positive integer | `280` | Code-free prompts up to this size prefer local. |
308
+ | `router.frontierPromptMinChars` | positive integer | `2000` | Prompts from this size are frontier candidates if no guards apply. |
309
+ | `local.runtimes` | `LocalRuntime[]` | Ollama enabled at `http://localhost:11434/v1` with `qwen3:8b` | Minimal list of one local runtime. |
310
+ | `local.runtimes[].id` | `"ollama" \| "lmstudio" \| "foundry-local"` | required | Local runtime. |
311
+ | `local.runtimes[].enabled` | `boolean` | `true` | Enable or disable that runtime. |
312
+ | `local.runtimes[].baseURL` | optional URL | per runtime/config | OpenAI-compatible `/v1` endpoint; Foundry Local may omit it when using discovery. |
313
+ | `local.runtimes[].discovery` | `"cli" \| "sdk" \| "manual"` optional | none per item | Foundry Local discovery; the registry uses CLI when configured and not `manual`. |
314
+ | `local.runtimes[].defaultModel` | `ModelRef` | required | Default model for that runtime. |
315
+ | `budgets.sessionUSD` | positive number, optional | unlimited | Frontier budget per session. |
316
+ | `budgets.monthlyUSD` | positive number, optional | unlimited | Monthly frontier budget. |
317
+ | `budgets.frontierTokensPerSession` | positive integer, optional | unlimited | Frontier token limit per session. |
318
+ | `budgets.hardStopOnBudgetExhaustion` | `boolean` | `false` | If `true`, an exhausted budget returns `blockFrontier`; if `false`, it forces local. |
319
+ | `privacyMode` | `"forceLocalOnSensitive" \| "consentBeforeFrontier" \| "off"` | `"forceLocalOnSensitive"` | Privacy policy for sensitive tasks. |
320
+ | `telemetry.enabled` | `boolean` (plugin option) | `true` | Enable/disable JSONL writing. |
321
+ | `telemetry.path` | `string` (plugin option) | `.opencode/openteam-telemetry.jsonl` | Path of the `CostRecord` JSONL log. |
322
+
323
+ ## Privacy
324
+
325
+ With `privacyMode: "forceLocalOnSensitive"`, if `TaskSignals.privacySensitive` is `true`, `chooseModel` uses local and does not allow frontier fallback. If no usable local runtime exists, the decision keeps the local route and records the reason in `rationale`.
326
+
327
+ Telemetry uses `hashPrompt` (currently `fnv1a32:<hash>`) and never serializes the full prompt. See [SECURITY.md](SECURITY.md) for the full privacy stance and how to report vulnerabilities.
328
+
329
+ ## Quality
330
+
331
+ Non-negotiable gates (see [docs/testing-and-quality.md](docs/testing-and-quality.md)):
612
332
 
613
333
  - `bun test`
614
- - Coverage global: líneas `>= 85%`, branches `>= 80%`.
615
- - Coverage de `src/router/**`: `100%` lines, branches, statements y functions.
334
+ - Global coverage: lines `>= 85%`, branches `>= 80%`.
335
+ - Coverage of `src/router/**` and `src/memory/**`: `100%` lines and functions (enforced by `bun run coverage:check`).
616
336
  - `bun run typecheck`
617
- - `biome check .` o `bun run lint` + `bun run format:check`
618
- - Test de determinismo del router.
619
- - Tests de contrato si cambian hooks opencode, agents, comandos, providers o SDK.
337
+ - `biome check .` (or `bun run lint` + `bun run format:check`)
338
+ - Router determinism test.
339
+ - Contract tests when opencode hooks, agents, commands, providers or the SDK change.
620
340
 
621
- Estado actual de Fases 0-3: **202 tests verdes**.
341
+ ## Compatibility
622
342
 
623
- ## Compatibilidad
343
+ See [docs/compatibility.md](docs/compatibility.md). Verified summary as of `2026-08-19`:
624
344
 
625
- Consulta [docs/compatibility.md](docs/compatibility.md). Resumen verificado el `2026-07-06`:
626
-
627
- | Superficie | Versión / contrato |
345
+ | Surface | Version / contract |
628
346
  | --- | --- |
629
- | openteam | `0.1.0` para Fase 4 npm + docs |
347
+ | openteam | `0.1.41`; current package version |
630
348
  | `@opencode-ai/plugin` | `1.17.13` |
631
349
  | `@opencode-ai/sdk` | `1.17.13` |
632
- | Hook de routing | `chat.message`; no `chat.params` para cambiar modelo |
633
- | Subsesiones | `client.session.create` + `client.session.prompt({ body: { model } })` |
350
+ | Routing hook | `chat.message`; not `chat.params` for model changes |
351
+ | Child sessions | `client.session.create` + `client.session.prompt({ body: { model } })` |
352
+
353
+ ## Contributing
354
+
355
+ Contributions are welcome. Please read [CONTRIBUTING.md](CONTRIBUTING.md) for the development setup (Bun), the non-negotiable quality gates, the module boundaries (`router/` is pure — no I/O, clock, randomness or logging) and the pull-request process. By participating you agree to abide by our [Code of Conduct](CODE_OF_CONDUCT.md).
634
356
 
635
357
  ## Roadmap
636
358
 
637
- | Fase | Estado | Entregables |
359
+ | Phase | Status | Deliverables |
638
360
  | --- | --- | --- |
639
- | 0. Scaffold/PoC | Hecha | TS/Bun, plugin mínimo, hook `chat.message`. |
640
- | 1. Local registry + router heurístico | Hecha | Ollama/LM Studio/Foundry, probes y `chooseModel` determinista. |
641
- | 2. Clasificador + perfiles + presupuesto + telemetría | Hecha | Clasificador local, `ModelCapabilityProfile`, budgets y `CostRecord`. |
642
- | 3. Orquestación multiagente | Hecha | Coordinator, roles, child sessions y permisos. |
643
- | 4. Empaquetado npm + docs | Hecha | Package exportable, README, ejemplos Windows y matriz de compatibilidad. |
644
- | 5. Comandos runtime | Hecha | `baseline show/set/auto`, `doctor` y `report` vía tool, `/openteam` y CLI `bin`. |
361
+ | 0. Scaffold / PoC | Done | TS/Bun, minimal plugin, `chat.message` hook. |
362
+ | 1. Local registry + heuristic router | Done | Ollama/LM Studio/Foundry, probes and deterministic `chooseModel`. |
363
+ | 2. Classifier + profiles + budget + telemetry | Done | Local classifier, `ModelCapabilityProfile`, budgets and `CostRecord`. |
364
+ | 3. Multi-agent orchestration | Done | Coordinator, roles, child sessions and permissions. |
365
+ | 4. npm packaging + docs | Done | Exportable package, README, Windows examples and compatibility matrix. |
366
+ | 5. Runtime commands | Done | `baseline show/set/auto`, `doctor` and `report` via tool, `/openteam` and CLI `bin`. |
367
+ | 6. Web Console + MCP memory | Done (Console/tunnel **alpha**) | Multi-session Console and `tunnel` are experimental and may be reworked; read-only MCP server and semantic recall are stable. |
368
+
369
+ ## License
370
+
371
+ [MIT](LICENSE) © Jose Manuel Corral ([@jmanuelcorral](https://github.com/jmanuelcorral)).
372
+
373
+ ## Acknowledgements
374
+
375
+ openteam stands on the shoulders of prior work. These projects shaped its design — we took inspiration from them, adapted the ideas to opencode and reimplemented them from scratch in TypeScript:
645
376
 
646
- ## Licencia
377
+ - **[Squad](https://bradygaster.github.io/squad/)** ([bradygaster/squad](https://github.com/bradygaster/squad)) — the on-demand, themed multi-agent team model: a single orchestrator that casts specialist subagents as the work requires them. It inspired openteam's `openteam` orchestrator agent and the team/roster convention.
378
+ - **[Superpowers](https://github.com/obra/superpowers)** by Jesse Vincent — a composable, skill-driven methodology for coding agents. It inspired openteam's skill-based agent conventions and the spec-first / subagent-driven workflow.
379
+ - **[agent-memory-dotnet](https://github.com/joslat/agent-memory-dotnet)** by José Luis Latorre — a semantic long-term memory model for agents. It inspired openteam's memory subsystem (extract → rank → consolidate → recall) with local-first, hash-redacted storage.
647
380
 
648
- MIT. Consulta [LICENSE](LICENSE).
381
+ All trademarks and project names belong to their respective owners; the links above are provided for attribution and are not endorsements.