@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.
- package/.opencode/command/openteam.md +5 -5
- package/AGENTS.md +50 -35
- package/README.es.md +759 -0
- package/README.md +213 -480
- package/dist/capabilities/types.d.ts +1 -1
- package/dist/cli/consoleServe.d.ts.map +1 -1
- package/dist/cli.js +1123 -232
- package/dist/commands/frontierCatalog.d.ts +27 -0
- package/dist/commands/frontierCatalog.d.ts.map +1 -0
- package/dist/commands/graph.d.ts +65 -0
- package/dist/commands/graph.d.ts.map +1 -0
- package/dist/commands/orchestratorAgent.d.ts +2 -1
- package/dist/commands/orchestratorAgent.d.ts.map +1 -1
- package/dist/commands/setup.d.ts +3 -18
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/config/load.d.ts.map +1 -1
- package/dist/config/migrations.d.ts +27 -0
- package/dist/config/migrations.d.ts.map +1 -0
- package/dist/config/resolve.d.ts +34 -0
- package/dist/config/resolve.d.ts.map +1 -0
- package/dist/config/schema.d.ts +235 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/console/assets.d.ts +9 -0
- package/dist/console/assets.d.ts.map +1 -0
- package/dist/console/render.d.ts.map +1 -1
- package/dist/context/redaction.d.ts +48 -0
- package/dist/context/redaction.d.ts.map +1 -0
- package/dist/context/schema.d.ts +115 -0
- package/dist/context/schema.d.ts.map +1 -0
- package/dist/context/types.d.ts +8 -0
- package/dist/context/types.d.ts.map +1 -0
- package/dist/contract/opencode.d.ts +1 -1
- package/dist/contract/opencode.d.ts.map +1 -1
- package/dist/graph/events.d.ts +25 -0
- package/dist/graph/events.d.ts.map +1 -0
- package/dist/graph/ids.d.ts +5 -0
- package/dist/graph/ids.d.ts.map +1 -0
- package/dist/graph/planner.d.ts +15 -0
- package/dist/graph/planner.d.ts.map +1 -0
- package/dist/graph/policies.d.ts +34 -0
- package/dist/graph/policies.d.ts.map +1 -0
- package/dist/graph/privacyPolicy.d.ts +29 -0
- package/dist/graph/privacyPolicy.d.ts.map +1 -0
- package/dist/graph/reducer.d.ts +27 -0
- package/dist/graph/reducer.d.ts.map +1 -0
- package/dist/graph/replay.d.ts +20 -0
- package/dist/graph/replay.d.ts.map +1 -0
- package/dist/graph/reviewerPolicy.d.ts +27 -0
- package/dist/graph/reviewerPolicy.d.ts.map +1 -0
- package/dist/graph/schema.d.ts +220 -0
- package/dist/graph/schema.d.ts.map +1 -0
- package/dist/graph/types.d.ts +40 -0
- package/dist/graph/types.d.ts.map +1 -0
- package/dist/graph/validate.d.ts +19 -0
- package/dist/graph/validate.d.ts.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +873 -88
- package/dist/local/embeddings.d.ts +29 -0
- package/dist/local/embeddings.d.ts.map +1 -0
- package/dist/local/extractClient.d.ts +31 -0
- package/dist/local/extractClient.d.ts.map +1 -0
- package/dist/local/openai-compatible.d.ts +1 -0
- package/dist/local/openai-compatible.d.ts.map +1 -1
- package/dist/mcp/semanticRecall.d.ts +25 -0
- package/dist/mcp/semanticRecall.d.ts.map +1 -0
- package/dist/mcp/server.d.ts +22 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/memory/consolidate.d.ts +21 -0
- package/dist/memory/consolidate.d.ts.map +1 -0
- package/dist/memory/extract.d.ts +68 -0
- package/dist/memory/extract.d.ts.map +1 -0
- package/dist/memory/fold.d.ts +24 -0
- package/dist/memory/fold.d.ts.map +1 -0
- package/dist/memory/index.d.ts +18 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/inject.d.ts +29 -0
- package/dist/memory/inject.d.ts.map +1 -0
- package/dist/memory/log.d.ts +16 -0
- package/dist/memory/log.d.ts.map +1 -0
- package/dist/memory/merge.d.ts +38 -0
- package/dist/memory/merge.d.ts.map +1 -0
- package/dist/memory/rank.d.ts +32 -0
- package/dist/memory/rank.d.ts.map +1 -0
- package/dist/memory/recall.d.ts +30 -0
- package/dist/memory/recall.d.ts.map +1 -0
- package/dist/memory/temporal.d.ts +39 -0
- package/dist/memory/temporal.d.ts.map +1 -0
- package/dist/memory/types.d.ts +159 -0
- package/dist/memory/types.d.ts.map +1 -0
- package/dist/memory/vector.d.ts +18 -0
- package/dist/memory/vector.d.ts.map +1 -0
- package/dist/orchestrator/graphCancellation.d.ts +84 -0
- package/dist/orchestrator/graphCancellation.d.ts.map +1 -0
- package/dist/orchestrator/graphEffects.d.ts +63 -0
- package/dist/orchestrator/graphEffects.d.ts.map +1 -0
- package/dist/orchestrator/graphReview.d.ts +84 -0
- package/dist/orchestrator/graphReview.d.ts.map +1 -0
- package/dist/orchestrator/graphRuntime.d.ts +69 -0
- package/dist/orchestrator/graphRuntime.d.ts.map +1 -0
- package/dist/orchestrator/opencodeSessionAdapter.d.ts +117 -0
- package/dist/orchestrator/opencodeSessionAdapter.d.ts.map +1 -0
- package/dist/orchestrator/roles.d.ts +1 -1
- package/dist/orchestrator/roles.d.ts.map +1 -1
- package/dist/orchestrator/sdd.d.ts +38 -2
- package/dist/orchestrator/sdd.d.ts.map +1 -1
- package/dist/orchestrator/sddCompiler.d.ts +44 -0
- package/dist/orchestrator/sddCompiler.d.ts.map +1 -0
- package/dist/orchestrator/sessionReconciler.d.ts +74 -0
- package/dist/orchestrator/sessionReconciler.d.ts.map +1 -0
- package/dist/orchestrator/shadowComparator.d.ts +62 -0
- package/dist/orchestrator/shadowComparator.d.ts.map +1 -0
- package/dist/plugin/hooks.d.ts +13 -0
- package/dist/plugin/hooks.d.ts.map +1 -1
- package/dist/plugin/memoryInject.d.ts +25 -0
- package/dist/plugin/memoryInject.d.ts.map +1 -0
- package/dist/router/chooseModel.d.ts.map +1 -1
- package/dist/router/cost.d.ts +4 -0
- package/dist/router/cost.d.ts.map +1 -0
- package/dist/router/frontierBaseline.d.ts +13 -0
- package/dist/router/frontierBaseline.d.ts.map +1 -0
- package/dist/router/modelSelection.d.ts +18 -0
- package/dist/router/modelSelection.d.ts.map +1 -0
- package/dist/storage/graph/codec.d.ts +52 -0
- package/dist/storage/graph/codec.d.ts.map +1 -0
- package/dist/storage/graph/fsGraphJournal.d.ts +3 -0
- package/dist/storage/graph/fsGraphJournal.d.ts.map +1 -0
- package/dist/storage/graph/importLegacy.d.ts +62 -0
- package/dist/storage/graph/importLegacy.d.ts.map +1 -0
- package/dist/storage/graph/memoryGraphJournal.d.ts +11 -0
- package/dist/storage/graph/memoryGraphJournal.d.ts.map +1 -0
- package/dist/storage/graph/migrateLegacyBriefs.d.ts +32 -0
- package/dist/storage/graph/migrateLegacyBriefs.d.ts.map +1 -0
- package/dist/storage/graph/projections.d.ts +31 -0
- package/dist/storage/graph/projections.d.ts.map +1 -0
- package/dist/storage/graph/provider.d.ts +52 -0
- package/dist/storage/graph/provider.d.ts.map +1 -0
- package/dist/storage/graph/recovery.d.ts +38 -0
- package/dist/storage/graph/recovery.d.ts.map +1 -0
- package/dist/storage/graph/runRegistry.d.ts +17 -0
- package/dist/storage/graph/runRegistry.d.ts.map +1 -0
- package/dist/storage/graph/snapshot.d.ts +44 -0
- package/dist/storage/graph/snapshot.d.ts.map +1 -0
- package/dist/storage/graph/workspaceLease.d.ts +36 -0
- package/dist/storage/graph/workspaceLease.d.ts.map +1 -0
- package/dist/storage/graph/writer.d.ts +20 -0
- package/dist/storage/graph/writer.d.ts.map +1 -0
- package/dist/storage/index/memoryConsolidate.d.ts +24 -0
- package/dist/storage/index/memoryConsolidate.d.ts.map +1 -0
- package/dist/storage/index/memoryIndex.d.ts +52 -0
- package/dist/storage/index/memoryIndex.d.ts.map +1 -0
- package/dist/storage/index/memoryRecall.d.ts +23 -0
- package/dist/storage/index/memoryRecall.d.ts.map +1 -0
- package/dist/storage/index/memoryRuntime.d.ts +41 -0
- package/dist/storage/index/memoryRuntime.d.ts.map +1 -0
- package/dist/telemetry/events.d.ts +3 -1
- package/dist/telemetry/events.d.ts.map +1 -1
- package/dist/telemetry/graphProjection.d.ts +36 -0
- package/dist/telemetry/graphProjection.d.ts.map +1 -0
- package/dist/telemetry/hash.d.ts.map +1 -1
- package/dist/web/server.d.ts +4 -0
- package/dist/web/server.d.ts.map +1 -1
- package/package.json +14 -6
package/README.md
CHANGED
|
@@ -1,57 +1,79 @@
|
|
|
1
1
|
# openteam
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> 🌐 **Language / Idioma:** **English** (this document) · [Español](README.es.md)
|
|
4
4
|
|
|
5
|
-
|
|
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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
[](https://github.com/jmanuelcorral/openteam/actions/workflows/ci.yml)
|
|
8
|
+
[](https://www.npmjs.com/package/@jmanuelcorral/openteam)
|
|
9
|
+
[](LICENSE)
|
|
10
|
+
[](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
|
-
- [
|
|
13
|
-
- [
|
|
14
|
-
- [
|
|
15
|
-
- [
|
|
16
|
-
- [
|
|
17
|
-
- [
|
|
18
|
-
- [
|
|
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
|
-
- [
|
|
29
|
+
- [License](#license)
|
|
30
|
+
- [Acknowledgements](#acknowledgements)
|
|
31
|
+
|
|
32
|
+
## What it is and why it exists
|
|
22
33
|
|
|
23
|
-
|
|
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
|
-
|
|
36
|
+
The router keeps a privacy guarantee: with `privacyMode: "forceLocalOnSensitive"`, a task flagged as `privacySensitive` never escalates to frontier.
|
|
26
37
|
|
|
27
|
-
|
|
38
|
+
## Features
|
|
28
39
|
|
|
29
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
-
|
|
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
|
-
##
|
|
64
|
+
## Installation
|
|
51
65
|
|
|
52
|
-
|
|
66
|
+
The package is published as [`@jmanuelcorral/openteam`](https://www.npmjs.com/package/@jmanuelcorral/openteam). These are the supported installation paths:
|
|
53
67
|
|
|
54
|
-
|
|
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
|
-
|
|
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`
|
|
186
|
-
- `.opencode/openteam.json`:
|
|
187
|
-
- `.opencode/agent/openteam.md`:
|
|
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
|
-
#
|
|
191
|
-
bunx openteam setup
|
|
192
|
-
#
|
|
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
|
-
>
|
|
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
|
-
|
|
141
|
+
The wizard:
|
|
209
142
|
|
|
210
|
-
|
|
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
|
-
|
|
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
|
-
|
|
151
|
+
## The `openteam` agent
|
|
215
152
|
|
|
216
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
165
|
+
## Runtime commands
|
|
229
166
|
|
|
230
|
-
|
|
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
|
-
|
|
235
|
-
bun add -d @jmanuelcorral/openteam # (o: npm install -D @jmanuelcorral/openteam)
|
|
236
|
-
```
|
|
169
|
+
### 1. In-conversation tool
|
|
237
170
|
|
|
238
|
-
|
|
171
|
+
The plugin registers the `openteam` tool. Ask the agent to use it, or install the `/openteam` command. Actions:
|
|
239
172
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
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
|
-
|
|
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` **
|
|
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
|
-
>
|
|
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
|
-
|
|
199
|
+
The package exposes the `openteam` binary. With a global install:
|
|
367
200
|
|
|
368
201
|
```powershell
|
|
369
|
-
|
|
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>`
|
|
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
|
-
###
|
|
215
|
+
### See each agent's LLM: `openteam agents`
|
|
385
216
|
|
|
386
|
-
|
|
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
|
-
|
|
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 #
|
|
412
|
-
openteam yolo on #
|
|
413
|
-
openteam yolo off #
|
|
224
|
+
openteam yolo status # is it active?
|
|
225
|
+
openteam yolo on # enable YOLO
|
|
226
|
+
openteam yolo off # disable YOLO
|
|
414
227
|
```
|
|
415
228
|
|
|
416
|
-
|
|
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
|
|
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
|
-
###
|
|
233
|
+
### Frontier-only (no local runtime): `openteam local`
|
|
423
234
|
|
|
424
|
-
|
|
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 #
|
|
428
|
-
openteam local off #
|
|
429
|
-
openteam local on #
|
|
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
|
-
|
|
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
|
-
###
|
|
245
|
+
### Multi-session web Console: `openteam console` (alpha)
|
|
439
246
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 #
|
|
464
|
-
openteam console --open #
|
|
465
|
-
openteam console --status #
|
|
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
|
-
|
|
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
|
-
|
|
265
|
+
### Secure remote access: `openteam tunnel` (alpha)
|
|
492
266
|
|
|
493
|
-
|
|
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
|
-
|
|
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 #
|
|
502
|
-
openteam tunnel --terminal #
|
|
503
|
-
openteam tunnel --allow-anonymous --yes #
|
|
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
|
-
> **
|
|
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
|
-
###
|
|
280
|
+
### Team memory over MCP (read-only): `openteam mcp`
|
|
514
281
|
|
|
515
|
-
`openteam mcp`
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
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
|
-
-
|
|
615
|
-
- Coverage
|
|
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 .`
|
|
618
|
-
-
|
|
619
|
-
-
|
|
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
|
-
|
|
341
|
+
## Compatibility
|
|
622
342
|
|
|
623
|
-
|
|
343
|
+
See [docs/compatibility.md](docs/compatibility.md). Verified summary as of `2026-08-19`:
|
|
624
344
|
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
| Superficie | Versión / contrato |
|
|
345
|
+
| Surface | Version / contract |
|
|
628
346
|
| --- | --- |
|
|
629
|
-
| openteam | `0.1.
|
|
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
|
-
|
|
|
633
|
-
|
|
|
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
|
-
|
|
|
359
|
+
| Phase | Status | Deliverables |
|
|
638
360
|
| --- | --- | --- |
|
|
639
|
-
| 0. Scaffold/PoC |
|
|
640
|
-
| 1. Local registry + router
|
|
641
|
-
| 2.
|
|
642
|
-
| 3.
|
|
643
|
-
| 4.
|
|
644
|
-
| 5.
|
|
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
|
-
|
|
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
|
-
|
|
381
|
+
All trademarks and project names belong to their respective owners; the links above are provided for attribution and are not endorsements.
|