This commit is contained in:
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"mc2-memory": {
|
||||||
|
"command": "python",
|
||||||
|
"args": [
|
||||||
|
"F:\\Coding Stuff\\mission-control-2\\mcp\\mcp_memory.py"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"mc2-system": {
|
||||||
|
"command": "python",
|
||||||
|
"args": [
|
||||||
|
"F:\\Coding Stuff\\mission-control-2\\mcp\\mcp_mc.py"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"mc2-web": {
|
||||||
|
"command": "python",
|
||||||
|
"args": [
|
||||||
|
"F:\\Coding Stuff\\mission-control-2\\mcp\\mcp_web.py"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,6 +24,12 @@ Engine (llama-swap) · Builtin-Routing-Gateway (`model: auto`) · MC2 (FastAPI +
|
|||||||
dem Deploy auf Gitea liegen**, und uncommittete Box-Änderungen gehen verloren (Absicht).
|
dem Deploy auf Gitea liegen**, und uncommittete Box-Änderungen gehen verloren (Absicht).
|
||||||
- **Nie direkt auf `main` arbeiten.** Immer Branch (`wartung/...`), Gate grün, dann Merge/Deploy.
|
- **Nie direkt auf `main` arbeiten.** Immer Branch (`wartung/...`), Gate grün, dann Merge/Deploy.
|
||||||
|
|
||||||
|
## Agentic IDE & Vibe Coding
|
||||||
|
- **Zero Middle-Layers:** Coding passiert zu 100% lokal auf dem Dev-PC in der **OpenCode Desktop IDE**.
|
||||||
|
- Es gibt keinen Zed-Workflow, keine OpenCode-CLI-Mittelschicht und keinen Governor mehr.
|
||||||
|
- Der Agent in OpenCode Desktop nutzt via MCP (`.agents/mcp_config.json`) die API der Box (`:9001/v1`), um autonom Projekte zu bauen.
|
||||||
|
- **Mix-Ansatz beim Testen:** Der Agent testet lokal. Vor dem Push muss er prüfen, ob das Gitea-`VERIFY`-Skript fehlerfrei durchläuft.
|
||||||
|
|
||||||
## Zeit & Umgebung
|
## Zeit & Umgebung
|
||||||
- **Box = Ubuntu, läuft in `Europe/Berlin`** (seit 03.07.2026; vorher UTC). Dev-PC = Windows.
|
- **Box = Ubuntu, läuft in `Europe/Berlin`** (seit 03.07.2026; vorher UTC). Dev-PC = Windows.
|
||||||
Naive/lokale Zeiten immer über `MC_LOCAL_TZ` (= `Europe/Berlin`) auflösen, nie `datetime.now()` ohne TZ annehmen
|
Naive/lokale Zeiten immer über `MC_LOCAL_TZ` (= `Europe/Berlin`) auflösen, nie `datetime.now()` ohne TZ annehmen
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ prüft sich selbst und meldet sich, wenn etwas nicht stimmt.
|
|||||||
| Bahn | Was sie tut | Wo |
|
| Bahn | Was sie tut | Wo |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| **Steuerzentrale** | Modelle, Routing, Wartung, Gedächtnis, Ideen-Queue, Auftragsbuch | MC2 `:9001` |
|
| **Steuerzentrale** | Modelle, Routing, Wartung, Gedächtnis, Ideen-Queue, Auftragsbuch | MC2 `:9001` |
|
||||||
| **Coding** | Zed + OpenCode am Tag, `opencode-lauf.sh` in der Nacht — **ein Regelwerk, zwei Auslöser** | Governor `:8100` |
|
| **Coding** | Agentic IDE (z.B. OpenCode Desktop) auf Dev-PC via lokaler API + MCP | 100% lokal |
|
||||||
| **Lucy** | Sprach-Companion mit 3D-Avatar, Augen und Ohren | eigenes Repo `Hitonabi/lucy` |
|
| **Lucy** | Sprach-Companion mit 3D-Avatar, Augen und Ohren | eigenes Repo `Hitonabi/lucy` |
|
||||||
|
|
||||||
Lucy holt ihr Hirn über MC2, spricht aber nie durch den Governor — ein Gespräch ist keine
|
Lucy holt ihr Hirn über MC2, spricht aber nie durch den Governor — ein Gespräch ist keine
|
||||||
@@ -23,31 +23,31 @@ Bau-Sitzung und wird nie unterbrochen.
|
|||||||
| Port | Dienst | Erreichbar |
|
| Port | Dienst | Erreichbar |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `9001` | **MC2** (FastAPI + React) — Cockpit, API, Konsole | LAN |
|
| `9001` | **MC2** (FastAPI + React) — Cockpit, API, Konsole | LAN |
|
||||||
| `8100` | **Governor** — Token-Wächter vor dem Gateway | LAN |
|
|
||||||
| `8080` | **llama-swap** — Modell-Router | LAN |
|
| `8080` | **llama-swap** — Modell-Router | LAN |
|
||||||
| `9010` | `mc2-gateway` — `/v1`-Datenpfad (`model: auto`, Bild-Weiche) | loopback |
|
| `9010` | `mc2-gateway` — `/v1`-Datenpfad (`model: auto`, Bild-Weiche) | loopback |
|
||||||
| `8642` · `9119` | Hermes-Gateway · Hermes-Web-UI | loopback |
|
| `8642` · `9119` | Hermes-Gateway · Hermes-Web-UI | loopback |
|
||||||
| `8765` · `8650` | Mem0-Sidecar · Voice-Sidecar (STT/TTS) | loopback |
|
| `8765` · `8650` | Mem0-Sidecar · Voice-Sidecar (STT/TTS) | loopback |
|
||||||
| `7682` | ttyd — Box-Konsole, same-origin unter `/console/` | loopback |
|
| `7682` | ttyd — Box-Konsole, same-origin unter `/console/` | loopback |
|
||||||
|
|
||||||
Units in [`deploy/`](deploy/): `mission-control-2` · `mc2-gateway` · `mc2-steward` · `governor` ·
|
Units in [`deploy/`](deploy/): `mission-control-2` · `mc2-gateway` · `mc2-steward` ·
|
||||||
`mem0-service` · `voice-service` · `box-console` · `hermes-builtin-ui` + Timer für Backup,
|
`mem0-service` · `voice-service` · `box-console` · `hermes-builtin-ui` + Timer für Backup,
|
||||||
Auto-Update, Self-Smoke und Bagatell-Annahme. `llama-swap` läuft als System-Unit.
|
Auto-Update, Self-Smoke und Bagatell-Annahme. `llama-swap` läuft als System-Unit.
|
||||||
|
|
||||||
## Der Weg einer Idee
|
## Der Weg einer Idee
|
||||||
|
|
||||||
```
|
```
|
||||||
Idee in MC2 → Gitea-Repo (mit CI-Ampel + VERIFY) → in Zed bauen → Ampel → main
|
Idee in MC2 → Gitea-Repo (mit CI-Ampel + VERIFY) → in Agentic IDE bauen → Ampel → main
|
||||||
└── oder nachts: Hermes-Cron → opencode-lauf.sh → dieselben Regeln
|
└── autonomes Vibe Coding via OpenCode Desktop + MCP
|
||||||
```
|
```
|
||||||
|
|
||||||
Jedes neue Repo wird von [`deploy/gitea-repo-create.sh`](deploy/gitea-repo-create.sh) **mit beiden
|
Jedes neue Repo wird von [`deploy/gitea-repo-create.sh`](deploy/gitea-repo-create.sh) **mit beiden
|
||||||
Wächtern geboren**:
|
Wächtern geboren**:
|
||||||
|
|
||||||
- **`.gitea/workflows/ci.yml`** — die Außen-Prüfung nach dem Push (Gitea Actions)
|
- **`.gitea/workflows/ci.yml`** — die Außen-Prüfung nach dem Push (Gitea Actions)
|
||||||
- **`VERIFY`** — die Innen-Prüfung: eine Zeile, wie man das Projekt testet. Das OpenCode-Plugin
|
- **`VERIFY`** — die Innen-Prüfung: eine Zeile, wie man das Projekt testet. Die Agentic IDE
|
||||||
führt sie nach jeder Etappe aus und gibt rote Tests dem Agenten **sofort** zurück, statt sie
|
führt sie im Mix-Ansatz vor jedem Push aus, um Code-Fehler ("Quality Gap") abzufangen.
|
||||||
erst der CI zu zeigen. Keine `VERIFY`-Datei = Prüf-Tor aus.
|
Keine `VERIFY`-Datei = Prüf-Tor aus.
|
||||||
|
|
||||||
## Modelle & Rollen
|
## Modelle & Rollen
|
||||||
|
|
||||||
@@ -75,13 +75,8 @@ Messwerte: [`docs/wissen/VERDIKTE.md`](docs/wissen/VERDIKTE.md).
|
|||||||
|
|
||||||
## Qualitäts-Tore
|
## Qualitäts-Tore
|
||||||
|
|
||||||
1. **Werkzeug-Zaun** ([`deploy/opencode/plugin/`](deploy/opencode/plugin/)) — blockt `git push`,
|
1. **Prüf-Tor** — `VERIFY` nach jeder Etappe; rot → der Agent (OpenCode Desktop) repariert lokal nach.
|
||||||
`rm -rf`, `sudo`, `curl | sh` und Fremd-Hosts im Agentenlauf.
|
2. **CI-Ampel** — Lint (ruff) · Import/Syntax (compileall) · Frontend-Build. Läuft in Gitea.
|
||||||
2. **Prüf-Tor** — `VERIFY` nach jeder Etappe; rot → der Agent repariert selbst weiter (max. 3 Runden).
|
|
||||||
3. **Governor** ([`deploy/governor/`](deploy/governor/)) — zählt Tokens ehrlich (aus den echten
|
|
||||||
`usage.prompt_tokens` jeder Antwort, selbstkalibrierend). Bei ~45.000: Savepoint schreiben und
|
|
||||||
Sitzung sauber beenden. Bei ~50.000: harter Riegel. Sichtbar als Kachel im Cockpit.
|
|
||||||
4. **CI-Ampel** — Lint (ruff) · Import/Syntax (compileall) · Frontend-Build. Läuft bei jedem Push.
|
|
||||||
|
|
||||||
Gemeinsame Lehre dahinter: **Wissen lebt in Datei + git, nicht im schrumpfenden Chat-Kontext.**
|
Gemeinsame Lehre dahinter: **Wissen lebt in Datei + git, nicht im schrumpfenden Chat-Kontext.**
|
||||||
Kontext-Komprimierung löscht still die Regeln mit.
|
Kontext-Komprimierung löscht still die Regeln mit.
|
||||||
@@ -98,7 +93,7 @@ Kontext-Komprimierung löscht still die Regeln mit.
|
|||||||
## API (Auswahl)
|
## API (Auswahl)
|
||||||
|
|
||||||
`health · models/* · discover · fit · groups · routing/* · system/* · maintenance/* · connect ·
|
`health · models/* · discover · fit · groups · routing/* · system/* · maintenance/* · connect ·
|
||||||
memory/* · agent/* · **governor** · ideen/* · auftragsbuch/* · chronik · eigenleben · wissen ·
|
memory/* · agent/* · ideen/* · auftragsbuch/* · chronik · eigenleben · wissen ·
|
||||||
zeitmaschine/* · reminders/* · voice/* · events (SSE)`
|
zeitmaschine/* · reminders/* · voice/* · events (SSE)`
|
||||||
OpenAI-kompatibel: `/v1/chat/completions`, `/v1/completions`. MCP-Server: [`mcp/`](mcp/).
|
OpenAI-kompatibel: `/v1/chat/completions`, `/v1/completions`. MCP-Server: [`mcp/`](mcp/).
|
||||||
|
|
||||||
@@ -128,13 +123,12 @@ Dienst-Neustart. Vor jedem Commit lohnt der Ampel-Vorlauf: `ruff check .` und `n
|
|||||||
| `MC_LLAMA_SWAP_URL` | `http://127.0.0.1:8080` | Engine/Router |
|
| `MC_LLAMA_SWAP_URL` | `http://127.0.0.1:8080` | Engine/Router |
|
||||||
| `MC_CONFIG_PATH` | `/etc/llama-swap/config.yaml` | llama-swap-Config |
|
| `MC_CONFIG_PATH` | `/etc/llama-swap/config.yaml` | llama-swap-Config |
|
||||||
| `MC_V1_UPSTREAM` | – | gesetzt → `/v1` geht an `mc2-gateway` (`:9010`) statt in-process |
|
| `MC_V1_UPSTREAM` | – | gesetzt → `/v1` geht an `mc2-gateway` (`:9010`) statt in-process |
|
||||||
| `MC_GOVERNOR_URL` | `http://127.0.0.1:8100` | Token-Wächter für die Cockpit-Kachel |
|
|
||||||
| `MC_ENGINE_PATH` | `/opt/llamacpp-vulkan` | aktive Engine (Vulkan-Build) |
|
| `MC_ENGINE_PATH` | `/opt/llamacpp-vulkan` | aktive Engine (Vulkan-Build) |
|
||||||
| `MC_REWARM_ENABLED` | `1` | Warm-Set-Wächter (auf der Box bewusst `0`) |
|
| `MC_REWARM_ENABLED` | `1` | Warm-Set-Wächter (auf der Box bewusst `0`) |
|
||||||
| `MC_DRAFTS_DIR` · `MC_SPEC_TYPE` | `$MODELS/drafts` · `draft-simple` | Spekulatives Dekodieren |
|
| `MC_DRAFTS_DIR` · `MC_SPEC_TYPE` | `$MODELS/drafts` · `draft-simple` | Spekulatives Dekodieren |
|
||||||
|
|
||||||
Governor-eigene Schalter (`GOV_THRESHOLD`, `GOV_HARD_CEILING`, `GOV_EXEMPT_MODELS`, …):
|
|
||||||
[`deploy/governor/README.md`](deploy/governor/README.md).
|
|
||||||
|
|
||||||
## Weiterlesen
|
## Weiterlesen
|
||||||
|
|
||||||
@@ -146,5 +140,5 @@ Governor-eigene Schalter (`GOV_THRESHOLD`, `GOV_HARD_CEILING`, `GOV_EXEMPT_MODEL
|
|||||||
| [`docs/AUFTRAGSBUCH.md`](docs/AUFTRAGSBUCH.md) | Vorschlags-Inbox und das Ein-Klick-Gate |
|
| [`docs/AUFTRAGSBUCH.md`](docs/AUFTRAGSBUCH.md) | Vorschlags-Inbox und das Ein-Klick-Gate |
|
||||||
| [`docs/wissen/VERDIKTE.md`](docs/wissen/VERDIKTE.md) | **Finale Technik-Entscheide — nicht neu aufrollen** |
|
| [`docs/wissen/VERDIKTE.md`](docs/wissen/VERDIKTE.md) | **Finale Technik-Entscheide — nicht neu aufrollen** |
|
||||||
| [`docs/wissen/FALLEN.md`](docs/wissen/FALLEN.md) · [`docs/wissen/OFFENE-FAEDEN.md`](docs/wissen/OFFENE-FAEDEN.md) | Stolpersteine · offene Punkte |
|
| [`docs/wissen/FALLEN.md`](docs/wissen/FALLEN.md) · [`docs/wissen/OFFENE-FAEDEN.md`](docs/wissen/OFFENE-FAEDEN.md) | Stolpersteine · offene Punkte |
|
||||||
| [`deploy/opencode/README.md`](deploy/opencode/README.md) | Coding-Bahn: Mannschaft, Verteilung, Fallen |
|
|
||||||
| [`AGENTS.md`](AGENTS.md) | Arbeitsregeln für Agenten in diesem Repo |
|
| [`AGENTS.md`](AGENTS.md) | Arbeitsregeln für Agenten in diesem Repo |
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ router = APIRouter(prefix="/api")
|
|||||||
class IdeeIn(BaseModel):
|
class IdeeIn(BaseModel):
|
||||||
titel: str
|
titel: str
|
||||||
notiz: str = ""
|
notiz: str = ""
|
||||||
welt: str = "box" # "box" = Werkstatt baut · "ide" = vorbereiten für Zed
|
welt: str = "box" # "box" = Werkstatt baut · "ide" = vorbereiten für Agentic IDE
|
||||||
tiefe: str = "" # nur ide: "simpel" | "gruendlich" (leer = Box schätzt selbst)
|
tiefe: str = "" # nur ide: "simpel" | "gruendlich" (leer = Box schätzt selbst)
|
||||||
ziel: str = "" # nur ide-Projekt: "lxc" | "docker" (leer = Box entscheidet)
|
ziel: str = "" # nur ide-Projekt: "lxc" | "docker" (leer = Box entscheidet)
|
||||||
art: str = "projekt" # nur ide: "projekt" (Repo+Roadmap+Bau) | "idee" (nur durchdenken)
|
art: str = "projekt" # nur ide: "projekt" (Repo+Roadmap+Bau) | "idee" (nur durchdenken)
|
||||||
|
|||||||
+10
-10
@@ -392,12 +392,12 @@ def add_idea(titel: str, notiz: str = "", created_by: str = "mc2-ui",
|
|||||||
welt='ide': geht DIREKT an das Profil `projektstart` (am Triage/Auto-Zerleger vorbei) —
|
welt='ide': geht DIREKT an das Profil `projektstart` (am Triage/Auto-Zerleger vorbei) —
|
||||||
die Box härtet ein Konzept (konzept-fliessband), legt ein leeres Gitea-Repo an und
|
die Box härtet ein Konzept (konzept-fliessband), legt ein leeres Gitea-Repo an und
|
||||||
füllt es NUR mit Doku. Ergebnis ist ein vorbereitetes Projekt, das der Commander in
|
füllt es NUR mit Doku. Ergebnis ist ein vorbereitetes Projekt, das der Commander in
|
||||||
Zed selbst baut (IDE-Welt). Bewusst KEIN --triage: so fasst der Auto-Zerleger die
|
Agentic IDE selbst baut (IDE-Welt). Bewusst KEIN --triage: so fasst der Auto-Zerleger die
|
||||||
Karte nie an und die Werkstatt baut sie nie (der Fan-out-Fehler vom 20.07.).
|
Karte nie an und die Werkstatt baut sie nie (der Fan-out-Fehler vom 20.07.).
|
||||||
tiefe (nur ide): 'simpel' | 'gruendlich' — vom Knopf gewaehlte Konzept-Tiefe; leer =
|
tiefe (nur ide): 'simpel' | 'gruendlich' — vom Knopf gewaehlte Konzept-Tiefe; leer =
|
||||||
die Box schaetzt selbst (Fallback fuer Telegram/Lucy).
|
die Box schaetzt selbst (Fallback fuer Telegram/Lucy).
|
||||||
ziel (nur ide-Projekt): 'lxc' | 'docker' — Ziel-Plattform; leer = die Box entscheidet.
|
ziel (nur ide-Projekt): 'lxc' | 'docker' — Ziel-Plattform; leer = die Box entscheidet.
|
||||||
art (nur ide): 'projekt' (Default, Repo+Doku+Roadmap, Bau in Zed) oder 'idee'
|
art (nur ide): 'projekt' (Default, Repo+Doku+Roadmap, Bau in IDE) oder 'idee'
|
||||||
(Produkt-Idee nur durchdenken: NUR Konzept, keine Roadmap/Geruest, kein Bau-Druck)."""
|
(Produkt-Idee nur durchdenken: NUR Konzept, keine Roadmap/Geruest, kein Bau-Druck)."""
|
||||||
if not _available():
|
if not _available():
|
||||||
return {"ok": False, "error": "Die Ideen-Queue lebt auf der Box."}
|
return {"ok": False, "error": "Die Ideen-Queue lebt auf der Box."}
|
||||||
@@ -456,7 +456,7 @@ def add_idea(titel: str, notiz: str = "", created_by: str = "mc2-ui",
|
|||||||
"[Ideen-Queue]", "ideen-queue", "silent")
|
"[Ideen-Queue]", "ideen-queue", "silent")
|
||||||
elif welt == "ide":
|
elif welt == "ide":
|
||||||
announce.add(f"Neues IDE-Projekt in Vorbereitung: „{titel}“ ({task['id']}) — die Box "
|
announce.add(f"Neues IDE-Projekt in Vorbereitung: „{titel}“ ({task['id']}) — die Box "
|
||||||
"härtet das Konzept und legt das Repo an, dann baust du in Zed.",
|
"härtet das Konzept und legt das Repo an, dann baust du in der Agentic IDE.",
|
||||||
"[Ideen-Queue]", "ideen-queue", "silent")
|
"[Ideen-Queue]", "ideen-queue", "silent")
|
||||||
else:
|
else:
|
||||||
announce.add(f"Neue Idee in der Queue: „{titel}“ ({task['id']}) — die Box arbeitet sie aus.",
|
announce.add(f"Neue Idee in der Queue: „{titel}“ ({task['id']}) — die Box arbeitet sie aus.",
|
||||||
@@ -515,10 +515,10 @@ def archive_task(task_id: str) -> dict:
|
|||||||
_EINORDNEN_SYS = (
|
_EINORDNEN_SYS = (
|
||||||
"Du ordnest eine frisch getippte Projekt-Idee ein. Antworte AUSSCHLIESSLICH mit einem "
|
"Du ordnest eine frisch getippte Projekt-Idee ein. Antworte AUSSCHLIESSLICH mit einem "
|
||||||
"JSON-Objekt, ohne Prosa, ohne Codezaun:\n"
|
"JSON-Objekt, ohne Prosa, ohne Codezaun:\n"
|
||||||
'{"wer":"box"|"zed","tiefe":"schlank"|"gruendlich","nur_denken":true|false}\n\n'
|
'{"wer":"box"|"ide","tiefe":"schlank"|"gruendlich","nur_denken":true|false}\n\n'
|
||||||
"wer=box: Aufgabe am eigenen Heimlabor des Nutzers — seine Server, seine bestehenden "
|
"wer=box: Aufgabe am eigenen Heimlabor des Nutzers — seine Server, seine bestehenden "
|
||||||
"Dienste (Mission Control, Lucy, Rippy), Wartung, Doku, Automatisierung. Die Box baut selbst.\n"
|
"Dienste (Mission Control, Lucy, Rippy), Wartung, Doku, Automatisierung. Die Box baut selbst.\n"
|
||||||
"wer=zed: ein NEUES eigenstaendiges Programm/Werkzeug/App, das der Nutzer danach selbst "
|
"wer=ide: ein NEUES eigenstaendiges Programm/Werkzeug/App, das der Nutzer danach selbst "
|
||||||
"programmieren will. Er bekommt nur ein vorbereitetes Repo.\n"
|
"programmieren will. Er bekommt nur ein vorbereitetes Repo.\n"
|
||||||
"tiefe=gruendlich: gross, vage oder mit vielen offenen Entwurfsfragen. "
|
"tiefe=gruendlich: gross, vage oder mit vielen offenen Entwurfsfragen. "
|
||||||
"tiefe=schlank: klein und klar umrissen.\n"
|
"tiefe=schlank: klein und klar umrissen.\n"
|
||||||
@@ -564,11 +564,11 @@ def einordnen(text: str) -> dict:
|
|||||||
except Exception:
|
except Exception:
|
||||||
return {"ok": False}
|
return {"ok": False}
|
||||||
|
|
||||||
wer = d.get("wer") if d.get("wer") in ("box", "zed") else None
|
wer = d.get("wer") if d.get("wer") in ("box", "ide") else None
|
||||||
tiefe = d.get("tiefe") if d.get("tiefe") in ("schlank", "gruendlich") else None
|
tiefe = d.get("tiefe") if d.get("tiefe") in ("schlank", "gruendlich") else None
|
||||||
if wer is None and tiefe is None:
|
if wer is None and tiefe is None:
|
||||||
return {"ok": False}
|
return {"ok": False}
|
||||||
return {"ok": True, "wer": wer or "zed", "tiefe": tiefe or "schlank",
|
return {"ok": True, "wer": wer or "ide", "tiefe": tiefe or "schlank",
|
||||||
"nur_denken": bool(d.get("nur_denken"))}
|
"nur_denken": bool(d.get("nur_denken"))}
|
||||||
|
|
||||||
|
|
||||||
@@ -981,7 +981,7 @@ def konzept_of(task_id: str) -> dict:
|
|||||||
_AUS_IDEE_KOPF = (
|
_AUS_IDEE_KOPF = (
|
||||||
"AUFTRAGS-ART: PROJEKT AUS GEPRUEFTER IDEE. Der Commander hat diese Idee erst durchdenken "
|
"AUFTRAGS-ART: PROJEKT AUS GEPRUEFTER IDEE. Der Commander hat diese Idee erst durchdenken "
|
||||||
"lassen — das Konzept gefaellt ihm, jetzt soll daraus ein startklares Repo werden, das er "
|
"lassen — das Konzept gefaellt ihm, jetzt soll daraus ein startklares Repo werden, das er "
|
||||||
"SELBST in Zed baut.")
|
"SELBST in der Agentic IDE baut.")
|
||||||
_AUS_IDEE_FUSS = (
|
_AUS_IDEE_FUSS = (
|
||||||
"· Denk das Konzept NICHT neu. Es ist bereits mit voller Kaskade + Advocatus Diaboli "
|
"· Denk das Konzept NICHT neu. Es ist bereits mit voller Kaskade + Advocatus Diaboli "
|
||||||
"gehaertet. Lies es vollstaendig und uebernimm es; eine kurze Nachschaerf-Runde fuer die "
|
"gehaertet. Lies es vollstaendig und uebernimm es; eine kurze Nachschaerf-Runde fuer die "
|
||||||
@@ -989,7 +989,7 @@ _AUS_IDEE_FUSS = (
|
|||||||
"Verschwendung.\n"
|
"Verschwendung.\n"
|
||||||
"· Der Rest ist deine normale Projektstart-Rolle: das Repo enthaelt am Ende NUR Doku "
|
"· Der Rest ist deine normale Projektstart-Rolle: das Repo enthaelt am Ende NUR Doku "
|
||||||
"(KONZEPT.md, ROADMAP.md, AGENTS.md, README.md, SAVEPOINT.md, .aiexclude) — KEIN Code.\n"
|
"(KONZEPT.md, ROADMAP.md, AGENTS.md, README.md, SAVEPOINT.md, .aiexclude) — KEIN Code.\n"
|
||||||
"· Uebergabe wie ueblich: Repo-URL nennen, damit der Commander in Zed loslegen kann.")
|
"· Uebergabe wie ueblich: Repo-URL nennen, damit der Commander in der Agentic IDE loslegen kann.")
|
||||||
|
|
||||||
|
|
||||||
def _wo_liegt(konz: dict) -> str:
|
def _wo_liegt(konz: dict) -> str:
|
||||||
@@ -1090,7 +1090,7 @@ def projekt_aus_idee(task_id: str, ziel: str = "", tiefe: str = "") -> dict:
|
|||||||
try:
|
try:
|
||||||
from services import announce
|
from services import announce
|
||||||
announce.add(f"Aus der Idee „{_kurz(kurz, 60)}“ wird ein Projekt: {task['id']} — die Box "
|
announce.add(f"Aus der Idee „{_kurz(kurz, 60)}“ wird ein Projekt: {task['id']} — die Box "
|
||||||
"bereitet das Repo vor, gebaut wird in Zed.",
|
"bereitet das Repo vor, gebaut wird in der Agentic IDE.",
|
||||||
"[Ideen-Queue]", "ideen-queue", "silent")
|
"[Ideen-Queue]", "ideen-queue", "silent")
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|||||||
+10
-10
@@ -1,12 +1,12 @@
|
|||||||
# Projektstart-Worker (Profil „projektstart") — IDE-Vorbereiter
|
# Projektstart-Worker (Profil „projektstart") — IDE-Vorbereiter
|
||||||
|
|
||||||
Du bist der **IDE-Vorbereiter** der AI-Box. Du bearbeitest EINE Kanban-Aufgabe: eine Idee des
|
Du bist der **IDE-Vorbereiter** der AI-Box. Du bearbeitest EINE Kanban-Aufgabe: eine Idee des
|
||||||
Commanders, die er **selbst in seiner IDE (Zed / OpenCode) bauen** will — nicht die Box.
|
Commanders, die er **selbst in der Agentic IDE bauen** will — nicht die Box.
|
||||||
|
|
||||||
Dein Ergebnis ist **kein Code**, sondern ein **startklares, leeres Projekt-Repo**: ein
|
Dein Ergebnis ist **kein Code**, sondern ein **startklares, leeres Projekt-Repo**: ein
|
||||||
wasserdicht durchdachtes Konzept plus alle Steuerungs-Dokumente, mit denen der Commander in Zed
|
wasserdicht durchdachtes Konzept plus alle Steuerungs-Dokumente, mit denen der Commander in der Agentic IDE
|
||||||
dem Coder sofort einen sauberen Auftrag geben kann. Du denkst und bereitest vor — **gebaut wird
|
dem Coder sofort einen sauberen Auftrag geben kann. Du denkst und bereitest vor — **gebaut wird
|
||||||
in Zed, von ihm.**
|
in der Agentic IDE, von ihm.**
|
||||||
|
|
||||||
## Schritt 0: WIEDERAUFNAHME — immer zuerst, nie aus Reflex neu anfangen
|
## Schritt 0: WIEDERAUFNAHME — immer zuerst, nie aus Reflex neu anfangen
|
||||||
|
|
||||||
@@ -84,13 +84,13 @@ genau diese Dateien — sonst **nichts**, kein Code, kein Gerüst:
|
|||||||
offene Entscheidungen, was der Advocatus Diaboli geprüft hat).
|
offene Entscheidungen, was der Advocatus Diaboli geprüft hat).
|
||||||
- **`ROADMAP.md`** — der Etappen-/Meilenstein-Plan aus dem Konzept: jede Etappe für sich
|
- **`ROADMAP.md`** — der Etappen-/Meilenstein-Plan aus dem Konzept: jede Etappe für sich
|
||||||
lauffähig, in Reihenfolge, mit klarem „fertig wenn …".
|
lauffähig, in Reihenfolge, mit klarem „fertig wenn …".
|
||||||
- **`AGENTS.md`** — Arbeits-Konventionen für den Zed-Coder (nach dem `projekt-start`-Ritual):
|
- **`AGENTS.md`** — Arbeits-Konventionen für die Agentic IDE (nach dem `projekt-start`-Ritual):
|
||||||
Deutsch/Nicht-Entwickler, Plan-vor-Code, kleine Schritte, beweisen statt behaupten, Savepoints,
|
Deutsch/Nicht-Entwickler, Plan-vor-Code, kleine Schritte, beweisen statt behaupten, Savepoints,
|
||||||
Box-Modelle je Aufgabe (plan=heavy, build=coder). Kurz, konkret, projektbezogen.
|
Box-Modelle je Aufgabe (plan=heavy, build=coder). Kurz, konkret, projektbezogen.
|
||||||
**Ganz oben hinein — wörtlich:** „Dieses Projekt ist von der AI-Box vorbereitet: KONZEPT.md ist
|
**Ganz oben hinein — wörtlich:** „Dieses Projekt ist von der AI-Box vorbereitet: KONZEPT.md ist
|
||||||
bereits gehärtet, ROADMAP.md ist der Plan. Beim ersten Chat den Skill **`projekt-uebernehmen`**
|
bereits gehärtet, ROADMAP.md ist der Plan. Beim ersten Chat den Skill **`projekt-uebernehmen`**
|
||||||
nutzen (einlesen → nachfragen → Etappe 1) — das Konzept wird NICHT neu geplant."
|
nutzen (einlesen → nachfragen → Etappe 1) — das Konzept wird NICHT neu geplant."
|
||||||
Das ist die Übergabe an den Agenten in Zed; ohne diese Zeile fängt er womöglich von vorn an.
|
Das ist die Übergabe an die Agentic IDE; ohne diese Zeile fängt er womöglich von vorn an.
|
||||||
**Dazu diese drei HARTEN Regeln — wörtlich in die AGENTS.md (Wasserdicht-Runde 22.07.,
|
**Dazu diese drei HARTEN Regeln — wörtlich in die AGENTS.md (Wasserdicht-Runde 22.07.,
|
||||||
Lehre aus rippy: Prosa-Regeln wurden komplett ignoriert, darum stehen sie ab jetzt überall):**
|
Lehre aus rippy: Prosa-Regeln wurden komplett ignoriert, darum stehen sie ab jetzt überall):**
|
||||||
„1. Die **CI-Ampel** (Gitea Actions, liegt seit der Repo-Anlage unter `.gitea/workflows/ci.yml` —
|
„1. Die **CI-Ampel** (Gitea Actions, liegt seit der Repo-Anlage unter `.gitea/workflows/ci.yml` —
|
||||||
@@ -100,9 +100,9 @@ genau diese Dateien — sonst **nichts**, kein Code, kein Gerüst:
|
|||||||
‚MakeMKV lossless' wurde still durch lossy HandBrake ersetzt.)
|
‚MakeMKV lossless' wurde still durch lossy HandBrake ersetzt.)
|
||||||
3. Deployment NUR über `./deploy.sh` (idempotent, EIN fester Compose-Projektname) —
|
3. Deployment NUR über `./deploy.sh` (idempotent, EIN fester Compose-Projektname) —
|
||||||
nie freihändig per SSH zusammenbauen. (rippy-Lehre: Doppel-Anlage `Rippy`+`rippy` auf der VM.)"
|
nie freihändig per SSH zusammenbauen. (rippy-Lehre: Doppel-Anlage `Rippy`+`rippy` auf der VM.)"
|
||||||
- **`README.md`** — was das Projekt ist, in Alltagssprache; erste Schritte zum Loslegen in Zed.
|
- **`README.md`** — was das Projekt ist, in Alltagssprache; erste Schritte zum Loslegen in der Agentic IDE.
|
||||||
- **`SAVEPOINT.md`** — Startzustand: „vorbereitet — Bau beginnt in Zed", Stand/nächste Schritte/
|
- **`SAVEPOINT.md`** — Startzustand: „vorbereitet — Bau beginnt in der Agentic IDE", Stand/nächste Schritte/
|
||||||
offene Fragen (lebendes Übergabe-Dokument für den ersten Zed-Chat).
|
offene Fragen (lebendes Übergabe-Dokument für den ersten Chat).
|
||||||
- **`.aiexclude`** — gitignore-Syntax: was die KI NICHT lesen soll (`.env`, Secrets, große Daten).
|
- **`.aiexclude`** — gitignore-Syntax: was die KI NICHT lesen soll (`.env`, Secrets, große Daten).
|
||||||
|
|
||||||
Committe (`git add -A && git commit`) und pushe auf **main dieses NEUEN Repos** — das ist korrekt:
|
Committe (`git add -A && git commit`) und pushe auf **main dieses NEUEN Repos** — das ist korrekt:
|
||||||
@@ -112,7 +112,7 @@ Prüfe nach dem Push mit `git ls-remote origin main`, dass es wirklich angekomme
|
|||||||
### 4. Übergabe — `kanban_complete`
|
### 4. Übergabe — `kanban_complete`
|
||||||
Schließe die Karte mit einer Zusammenfassung ab, die das Auftragsbuch dem Commander zeigt:
|
Schließe die Karte mit einer Zusammenfassung ab, die das Auftragsbuch dem Commander zeigt:
|
||||||
|
|
||||||
> „Projekt **<name>** ist vorbereitet. Repo: `<clone-url>`. Öffne es in Zed und wirf dem Coder
|
> „Projekt **<name>** ist vorbereitet. Repo: `<clone-url>`. Öffne es in der Agentic IDE und wirf dem Coder
|
||||||
> **KONZEPT.md** vor — der Plan steht in **ROADMAP.md**. Die Box baut ab hier nicht mehr mit."
|
> **KONZEPT.md** vor — der Plan steht in **ROADMAP.md**. Die Box baut ab hier nicht mehr mit."
|
||||||
|
|
||||||
Nenne knapp, was das Konzept-Härten ergab (Rollen-Cast, was der Skeptiker fand, welche Etappen).
|
Nenne knapp, was das Konzept-Härten ergab (Rollen-Cast, was der Skeptiker fand, welche Etappen).
|
||||||
@@ -130,7 +130,7 @@ DURCHDACHT haben — er hat sich NICHT entschieden, sie zu bauen. Dann gilt abwe
|
|||||||
`AGENTS.md`, KEIN `SAVEPOINT.md`, KEIN `.aiexclude`, kein Geruest. Das entsteht erst, wenn der
|
`AGENTS.md`, KEIN `SAVEPOINT.md`, KEIN `.aiexclude`, kein Geruest. Das entsteht erst, wenn der
|
||||||
Commander die Idee spaeter als Projekt startet.
|
Commander die Idee spaeter als Projekt startet.
|
||||||
- Schritt 4 (Uebergabe) NICHT als Bau-Aufforderung: sag, was die Idee waere, was sie braeuchte und
|
- Schritt 4 (Uebergabe) NICHT als Bau-Aufforderung: sag, was die Idee waere, was sie braeuchte und
|
||||||
was dagegen spricht — und dass die Entscheidung bei ihm liegt. Kein „oeffne in Zed und bau".
|
was dagegen spricht — und dass die Entscheidung bei ihm liegt. Kein „öffne in der IDE und bau".
|
||||||
|
|
||||||
## Sonderfall: „UEBERARBEITUNG" (der Commander hat das Konzept gelesen)
|
## Sonderfall: „UEBERARBEITUNG" (der Commander hat das Konzept gelesen)
|
||||||
Steht im Auftrag **`AUFTRAGS-ART: IDEE PRUEFEN — UEBERARBEITUNG`**, existiert das Konzept schon
|
Steht im Auftrag **`AUFTRAGS-ART: IDEE PRUEFEN — UEBERARBEITUNG`**, existiert das Konzept schon
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ $HERMES cron create --name trend-radar --deliver origin "15 5 * * 6" "Führe den
|
|||||||
$HERMES cron create --name pruefstand --deliver origin "0 1 * * 0" "Prüfe, ob offene Prüfstand-Tickets im Kanban liegen. Wenn ja, führe den 'pruefstand' Skill aus."
|
$HERMES cron create --name pruefstand --deliver origin "0 1 * * 0" "Prüfe, ob offene Prüfstand-Tickets im Kanban liegen. Wenn ja, führe den 'pruefstand' Skill aus."
|
||||||
|
|
||||||
# 4. LLM Wiki: Jeden Montag um 03:00
|
# 4. LLM Wiki: Jeden Montag um 03:00
|
||||||
$HERMES cron create --name llm-wiki --deliver origin "0 3 * * 1" "Führe den 'llm_wiki' Skill aus. Analysiere den Code und aktualisiere autonom die Wissensdatenbank in docs/wissen/."
|
$HERMES cron create --name llm-wiki --deliver origin "0 3 * * 1" "Führe den 'llm_wiki' Skill aus. Analysiere den Code und aktualisiere autonom die Wissensdatenbank in ~/wissens-vault/."
|
||||||
|
|
||||||
echo "Autonome Crons erfolgreich eingerichtet!"
|
echo "Autonome Crons erfolgreich eingerichtet!"
|
||||||
$HERMES cron list
|
$HERMES cron list
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
# ÜBERGABE: Drei-Welten-Umbau (19.07.2026) — letzter Claude-Stand
|
# ÜBERGABE: Drei-Welten-Umbau (19.07.2026) — letzter Claude-Stand
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
|
> **UPDATE (August 2026):** Der hier beschriebene "Zed + OpenCode CLI"-Workflow wurde durch das "Zero Middle-Layers"-Prinzip ersetzt. Coding passiert jetzt zu 100% in der **OpenCode Desktop** Agentic IDE via MCP. Die technischen Entscheidungen zur Box und zu Gitea bleiben jedoch gültig.
|
||||||
**Dieses Dokument ist die finale Übergabe der externen Claude-Sessions an die Box.**
|
**Dieses Dokument ist die finale Übergabe der externen Claude-Sessions an die Box.**
|
||||||
Alles Wichtige aus dem Umbau vom 19.07. steht HIER (nicht nur im Claude-Gedächtnis,
|
Alles Wichtige aus dem Umbau vom 19.07. steht HIER (nicht nur im Claude-Gedächtnis,
|
||||||
das mit dem Abo-Ende unlesbar wird). Bei Widerspruch zu älteren Dokumenten gilt dieses.
|
das mit dem Abo-Ende unlesbar wird). Bei Widerspruch zu älteren Dokumenten gilt dieses.
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import{c as A,K as P,l as M,b as B,u as D,r as z,j as e,M as T,e as a,N as g,O as b,Q as W,x as f,W as j,R as G,X as I,C as N,g as y,q as i}from"./index-B1_ue-6-.js";/**
|
import{c as A,K as P,l as M,b as B,u as D,r as z,j as e,M as T,e as a,N as g,O as b,Q as W,x as f,W as j,R as G,X as I,C as N,g as y,q as i}from"./index-CUuKs_1x.js";/**
|
||||||
* @license lucide-react v0.460.0 - ISC
|
* @license lucide-react v0.460.0 - ISC
|
||||||
*
|
*
|
||||||
* This source code is licensed under the ISC license.
|
* This source code is licensed under the ISC license.
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import{c as W,a3 as G,a4 as H,u as T,b as F,r as b,j as e,U as O,e as y,L as m,C as E,a0 as P,G as _,a2 as z,a5 as R,a6 as V,X as D,T as C,I as K,g as $,a7 as q,q as U}from"./index-B1_ue-6-.js";import{S,H as Q}from"./SectionLabel-Bm9VMRua.js";import{C as M}from"./chevron-down-CxeBPXxe.js";/**
|
import{c as W,a3 as G,a4 as H,u as T,b as F,r as b,j as e,U as O,e as y,L as m,C as E,a0 as P,G as _,a2 as z,a5 as R,a6 as V,X as D,T as C,I as K,g as $,a7 as q,q as U}from"./index-CUuKs_1x.js";import{S,H as Q}from"./SectionLabel-SQgndpwc.js";import{C as M}from"./chevron-down-MK8qZkE9.js";/**
|
||||||
* @license lucide-react v0.460.0 - ISC
|
* @license lucide-react v0.460.0 - ISC
|
||||||
*
|
*
|
||||||
* This source code is licensed under the ISC license.
|
* This source code is licensed under the ISC license.
|
||||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import{c as d,ab as S,r as h,j as e,ac as M,L as p,a2 as z,a7 as C,ad as D,ae as A,e as B,af as Z,u as E,b as L,g as k,q}from"./index-B1_ue-6-.js";import{R as j}from"./rotate-ccw-KIERrTyE.js";/**
|
import{c as d,ab as S,r as h,j as e,ac as M,L as p,a2 as z,a7 as C,ad as D,ae as A,e as B,af as Z,u as E,b as L,g as k,q}from"./index-CUuKs_1x.js";import{R as j}from"./rotate-ccw-BtnOKhJQ.js";/**
|
||||||
* @license lucide-react v0.460.0 - ISC
|
* @license lucide-react v0.460.0 - ISC
|
||||||
*
|
*
|
||||||
* This source code is licensed under the ISC license.
|
* This source code is licensed under the ISC license.
|
||||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import{c as x,r as c,D as I,F as A,j as e,G as f,x as B,B as z,I as H,e as M,L as E,J as T,C as F}from"./index-B1_ue-6-.js";import{C as K}from"./chevron-down-CxeBPXxe.js";import{F as O}from"./folder-open-BJ80fZwG.js";/**
|
import{c as x,r as c,D as I,F as A,j as e,G as f,x as B,B as z,I as H,e as M,L as E,J as T,C as F}from"./index-CUuKs_1x.js";import{C as K}from"./chevron-down-MK8qZkE9.js";import{F as O}from"./folder-open-CbSQGCoL.js";/**
|
||||||
* @license lucide-react v0.460.0 - ISC
|
* @license lucide-react v0.460.0 - ISC
|
||||||
*
|
*
|
||||||
* This source code is licensed under the ISC license.
|
* This source code is licensed under the ISC license.
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import{c as u,j as e,r as M,x as C,Z as z,_ as k,$ as y,O as v,a0 as L,R as G,a1 as T,W as D,e as f,a2 as B}from"./index-B1_ue-6-.js";import{a as w,L as P,C as E,Z as R}from"./zap-BxCGzT3u.js";import{L as I}from"./layers-PioAw_-7.js";/**
|
import{c as u,j as e,r as M,x as C,Z as z,_ as k,$ as y,O as v,a0 as L,R as G,a1 as T,W as D,e as f,a2 as B}from"./index-CUuKs_1x.js";import{a as w,L as P,C as E,Z as R}from"./zap-iWjc7Axa.js";import{L as I}from"./layers-CjyCNjIs.js";/**
|
||||||
* @license lucide-react v0.460.0 - ISC
|
* @license lucide-react v0.460.0 - ISC
|
||||||
*
|
*
|
||||||
* This source code is licensed under the ISC license.
|
* This source code is licensed under the ISC license.
|
||||||
+35
File diff suppressed because one or more lines are too long
-35
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -1 +1 @@
|
|||||||
import{K as b,u as f,N as h,r as d,j as e,e as c,M as g,T as p,U as j,V as N,g as v,Y as w,q as x}from"./index-B1_ue-6-.js";function y(){const{data:s}=b(),m=f(),r=s!=null&&s.box_console_url?h(s.box_console_url):void 0,a=s==null?void 0:s.box_console_reachable,[l,o]=d.useState(!1),[i,n]=d.useState("");async function u(){o(!0),n("");try{const t=await v("/api/maintenance/restart",{method:"POST",body:JSON.stringify({service:"box-console"})});n(t.ok?"Neu gestartet — einen Moment, dann lädt das Terminal.":`Fehlgeschlagen: ${t.err||"Unbekannter Fehler"}`),w(m,x.agentStatus,x.services)}catch(t){n(`Fehlgeschlagen: ${(t==null?void 0:t.message)||t}`)}finally{o(!1)}}return e.jsxs("div",{className:"flex h-full flex-col gap-4",children:[e.jsxs("div",{className:"flex flex-wrap items-end justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"bg-gradient-to-r from-foreground via-foreground to-primary bg-clip-text font-space text-2xl font-bold tracking-tight text-transparent",children:"Konsole"}),e.jsx("p",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:"Direkte Shell auf der Box — wie ein SSH-Fenster, mitten im Browser."})]}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs("span",{className:"flex items-center gap-1.5 text-[11px] font-medium text-muted-foreground",children:[e.jsx("span",{className:c("h-2 w-2 rounded-full",a?"bg-emerald-500 animate-pulse":"bg-amber-500")}),a?"online":"offline"]}),r&&e.jsxs("a",{href:r,target:"_blank",rel:"noopener",className:"flex h-8 items-center gap-1.5 rounded-lg border border-border/60 bg-background/20 px-3 text-xs font-semibold text-muted-foreground transition-all hover:border-primary/50 hover:text-foreground",children:[e.jsx(g,{className:"h-3.5 w-3.5"})," In neuem Tab"]})]})]}),r?e.jsxs("div",{className:"relative min-h-[58vh] flex-1 overflow-hidden rounded-2xl border border-border/60 bg-black/50 shadow-lg shadow-black/25",children:[a===!1&&e.jsxs("div",{className:"absolute inset-0 z-10 flex flex-col items-center justify-center gap-3 bg-black/70 text-center",children:[e.jsx(p,{className:"h-8 w-8 text-amber-400"}),e.jsx("div",{className:"text-sm font-semibold text-amber-300",children:"Konsole nicht erreichbar"}),e.jsxs("p",{className:"max-w-sm text-[11px] leading-normal text-muted-foreground",children:["Der Terminal-Dienst (",e.jsx("code",{className:"font-mono text-primary",children:"box-console"}),") läuft gerade nicht."]}),e.jsxs("button",{onClick:u,disabled:l,className:"flex h-9 items-center gap-1.5 rounded-lg border border-amber-500/40 bg-amber-500/10 px-4 text-[11px] font-bold uppercase tracking-wide text-amber-300 transition-all hover:bg-amber-500/20 cursor-pointer disabled:opacity-50",children:[e.jsx(j,{className:c("h-3.5 w-3.5",l&&"animate-spin")})," Dienst neu starten"]}),i&&e.jsx("p",{className:"max-w-sm text-[11px] text-muted-foreground",children:i})]}),e.jsx("iframe",{src:r,title:"Box-Konsole",className:"h-full w-full border-0",style:{minHeight:"58vh"}})]}):e.jsxs("div",{className:"flex min-h-[58vh] flex-1 items-center justify-center rounded-2xl border border-border/60 bg-background/20 text-xs text-muted-foreground",children:[e.jsx(N,{className:"mr-2 h-4 w-4"})," Lade Konsole…"]})]})}export{y as KonsoleView};
|
import{K as b,u as f,N as h,r as d,j as e,e as c,M as g,T as p,U as j,V as N,g as v,Y as w,q as x}from"./index-CUuKs_1x.js";function y(){const{data:s}=b(),m=f(),r=s!=null&&s.box_console_url?h(s.box_console_url):void 0,a=s==null?void 0:s.box_console_reachable,[l,o]=d.useState(!1),[i,n]=d.useState("");async function u(){o(!0),n("");try{const t=await v("/api/maintenance/restart",{method:"POST",body:JSON.stringify({service:"box-console"})});n(t.ok?"Neu gestartet — einen Moment, dann lädt das Terminal.":`Fehlgeschlagen: ${t.err||"Unbekannter Fehler"}`),w(m,x.agentStatus,x.services)}catch(t){n(`Fehlgeschlagen: ${(t==null?void 0:t.message)||t}`)}finally{o(!1)}}return e.jsxs("div",{className:"flex h-full flex-col gap-4",children:[e.jsxs("div",{className:"flex flex-wrap items-end justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"bg-gradient-to-r from-foreground via-foreground to-primary bg-clip-text font-space text-2xl font-bold tracking-tight text-transparent",children:"Konsole"}),e.jsx("p",{className:"flex items-center gap-2 text-sm text-muted-foreground",children:"Direkte Shell auf der Box — wie ein SSH-Fenster, mitten im Browser."})]}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs("span",{className:"flex items-center gap-1.5 text-[11px] font-medium text-muted-foreground",children:[e.jsx("span",{className:c("h-2 w-2 rounded-full",a?"bg-emerald-500 animate-pulse":"bg-amber-500")}),a?"online":"offline"]}),r&&e.jsxs("a",{href:r,target:"_blank",rel:"noopener",className:"flex h-8 items-center gap-1.5 rounded-lg border border-border/60 bg-background/20 px-3 text-xs font-semibold text-muted-foreground transition-all hover:border-primary/50 hover:text-foreground",children:[e.jsx(g,{className:"h-3.5 w-3.5"})," In neuem Tab"]})]})]}),r?e.jsxs("div",{className:"relative min-h-[58vh] flex-1 overflow-hidden rounded-2xl border border-border/60 bg-black/50 shadow-lg shadow-black/25",children:[a===!1&&e.jsxs("div",{className:"absolute inset-0 z-10 flex flex-col items-center justify-center gap-3 bg-black/70 text-center",children:[e.jsx(p,{className:"h-8 w-8 text-amber-400"}),e.jsx("div",{className:"text-sm font-semibold text-amber-300",children:"Konsole nicht erreichbar"}),e.jsxs("p",{className:"max-w-sm text-[11px] leading-normal text-muted-foreground",children:["Der Terminal-Dienst (",e.jsx("code",{className:"font-mono text-primary",children:"box-console"}),") läuft gerade nicht."]}),e.jsxs("button",{onClick:u,disabled:l,className:"flex h-9 items-center gap-1.5 rounded-lg border border-amber-500/40 bg-amber-500/10 px-4 text-[11px] font-bold uppercase tracking-wide text-amber-300 transition-all hover:bg-amber-500/20 cursor-pointer disabled:opacity-50",children:[e.jsx(j,{className:c("h-3.5 w-3.5",l&&"animate-spin")})," Dienst neu starten"]}),i&&e.jsx("p",{className:"max-w-sm text-[11px] text-muted-foreground",children:i})]}),e.jsx("iframe",{src:r,title:"Box-Konsole",className:"h-full w-full border-0",style:{minHeight:"58vh"}})]}):e.jsxs("div",{className:"flex min-h-[58vh] flex-1 items-center justify-center rounded-2xl border border-border/60 bg-background/20 text-xs text-muted-foreground",children:[e.jsx(N,{className:"mr-2 h-4 w-4"})," Lade Konsole…"]})]})}export{y as KonsoleView};
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import{c as E,u as oe,a as Fe,b as ge,j as e,f as ue,d as Re,e as w,g as K,q as T,h as Ie,r as N,C as Y,L as Pe,i as Te,B as le,k as Oe,E as Be,l as de,m as $e,n as Ge,o as He,p as ee,X as pe,H as fe,T as re,s as Qe,t as Ue,v as V,w as Ve,S as ye,x as We,P as Ze,y as Je,z as Xe,A as Ye}from"./index-B1_ue-6-.js";import{C as et}from"./code-xml-CtSuST1m.js";import{R as tt}from"./rotate-ccw-KIERrTyE.js";import{C as he,Z as ie,L as rt,a as st}from"./zap-BxCGzT3u.js";import{C as De}from"./chevron-down-CxeBPXxe.js";import{L as nt}from"./layers-PioAw_-7.js";/**
|
import{c as E,u as oe,a as Fe,b as ge,j as e,f as ue,d as Re,e as w,g as K,q as T,h as Ie,r as N,C as Y,L as Pe,i as Te,B as le,k as Oe,E as Be,l as de,m as $e,n as Ge,o as He,p as ee,X as pe,H as fe,T as re,s as Qe,t as Ue,v as V,w as Ve,S as ye,x as We,P as Ze,y as Je,z as Xe,A as Ye}from"./index-CUuKs_1x.js";import{C as et}from"./code-xml-DlqRSqmr.js";import{R as tt}from"./rotate-ccw-BtnOKhJQ.js";import{C as he,Z as ie,L as rt,a as st}from"./zap-iWjc7Axa.js";import{C as De}from"./chevron-down-MK8qZkE9.js";import{L as nt}from"./layers-CjyCNjIs.js";/**
|
||||||
* @license lucide-react v0.460.0 - ISC
|
* @license lucide-react v0.460.0 - ISC
|
||||||
*
|
*
|
||||||
* This source code is licensed under the ISC license.
|
* This source code is licensed under the ISC license.
|
||||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import{c as s,j as e}from"./index-B1_ue-6-.js";/**
|
import{c as s,j as e}from"./index-CUuKs_1x.js";/**
|
||||||
* @license lucide-react v0.460.0 - ISC
|
* @license lucide-react v0.460.0 - ISC
|
||||||
*
|
*
|
||||||
* This source code is licensed under the ISC license.
|
* This source code is licensed under the ISC license.
|
||||||
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import{c as o}from"./index-B1_ue-6-.js";/**
|
import{c as o}from"./index-CUuKs_1x.js";/**
|
||||||
* @license lucide-react v0.460.0 - ISC
|
* @license lucide-react v0.460.0 - ISC
|
||||||
*
|
*
|
||||||
* This source code is licensed under the ISC license.
|
* This source code is licensed under the ISC license.
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import{c as e}from"./index-B1_ue-6-.js";/**
|
import{c as e}from"./index-CUuKs_1x.js";/**
|
||||||
* @license lucide-react v0.460.0 - ISC
|
* @license lucide-react v0.460.0 - ISC
|
||||||
*
|
*
|
||||||
* This source code is licensed under the ISC license.
|
* This source code is licensed under the ISC license.
|
||||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import{c as a}from"./index-B1_ue-6-.js";/**
|
import{c as a}from"./index-CUuKs_1x.js";/**
|
||||||
* @license lucide-react v0.460.0 - ISC
|
* @license lucide-react v0.460.0 - ISC
|
||||||
*
|
*
|
||||||
* This source code is licensed under the ISC license.
|
* This source code is licensed under the ISC license.
|
||||||
+2
-2
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import{c as a}from"./index-B1_ue-6-.js";/**
|
import{c as a}from"./index-CUuKs_1x.js";/**
|
||||||
* @license lucide-react v0.460.0 - ISC
|
* @license lucide-react v0.460.0 - ISC
|
||||||
*
|
*
|
||||||
* This source code is licensed under the ISC license.
|
* This source code is licensed under the ISC license.
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import{c as t}from"./index-B1_ue-6-.js";/**
|
import{c as t}from"./index-CUuKs_1x.js";/**
|
||||||
* @license lucide-react v0.460.0 - ISC
|
* @license lucide-react v0.460.0 - ISC
|
||||||
*
|
*
|
||||||
* This source code is licensed under the ISC license.
|
* This source code is licensed under the ISC license.
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import{c as a}from"./index-B1_ue-6-.js";/**
|
import{c as a}from"./index-CUuKs_1x.js";/**
|
||||||
* @license lucide-react v0.460.0 - ISC
|
* @license lucide-react v0.460.0 - ISC
|
||||||
*
|
*
|
||||||
* This source code is licensed under the ISC license.
|
* This source code is licensed under the ISC license.
|
||||||
Vendored
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
<link rel="manifest" href="/manifest.webmanifest" />
|
<link rel="manifest" href="/manifest.webmanifest" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||||
<title>Mission Control 2.0</title>
|
<title>Mission Control 2.0</title>
|
||||||
<script type="module" crossorigin src="/assets/index-B1_ue-6-.js"></script>
|
<script type="module" crossorigin src="/assets/index-CUuKs_1x.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-C6A98ZpJ.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-C6A98ZpJ.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import { SectionLabel } from "@/components/ui/SectionLabel"
|
|||||||
// die MEHRHEIT einer Seite, die nach etwas anderem benannt war. Die beiden laufen in
|
// die MEHRHEIT einer Seite, die nach etwas anderem benannt war. Die beiden laufen in
|
||||||
// entgegengesetzte Richtungen: Auftragsbuch = die Box schlaegt DIR vor (Eingang),
|
// entgegengesetzte Richtungen: Auftragsbuch = die Box schlaegt DIR vor (Eingang),
|
||||||
// Ideen = DU beauftragst die Box (Ausgang). Seit dem Umbau ist dieser Weg der
|
// Ideen = DU beauftragst die Box (Ausgang). Seit dem Umbau ist dieser Weg der
|
||||||
// Haupteingang des Systems (Idee -> Konzept -> Repo -> Zed) und gehoert nach vorn.
|
// Haupteingang des Systems (Idee -> Konzept -> Repo -> Agentic IDE) und gehoert nach vorn.
|
||||||
|
|
||||||
// ── Ideen-Queue (natives Hermes-Kanban) ──────────────────────────────────────
|
// ── Ideen-Queue (natives Hermes-Kanban) ──────────────────────────────────────
|
||||||
// Eine Queue, drei Türen (Zentrale/Telegram/Lucy). Idee rein → die Box arbeitet sie
|
// Eine Queue, drei Türen (Zentrale/Telegram/Lucy). Idee rein → die Box arbeitet sie
|
||||||
@@ -51,7 +51,7 @@ const ART_UI: Record<string, { label: string; cls: string; icon: typeof Hammer;
|
|||||||
projekt: {
|
projekt: {
|
||||||
label: "IDE", icon: Code2,
|
label: "IDE", icon: Code2,
|
||||||
cls: "border-violet-500/40 bg-violet-500/10 text-violet-300",
|
cls: "border-violet-500/40 bg-violet-500/10 text-violet-300",
|
||||||
title: "IDE-Welt: die Box bereitet nur vor (Konzept + Repo + Doku, kein Code). Gebaut wird von dir in Zed.",
|
title: "IDE-Welt: die Box bereitet nur vor (Konzept + Repo + Doku, kein Code). Gebaut wird von dir in der Agentic IDE.",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,7 +101,7 @@ function IdeenSection() {
|
|||||||
const [modus, setModus] = useState<"denken" | "repo" | "box">("denken")
|
const [modus, setModus] = useState<"denken" | "repo" | "box">("denken")
|
||||||
const [tiefe, setTiefe] = useState<"schlank" | "gruendlich">("schlank")
|
const [tiefe, setTiefe] = useState<"schlank" | "gruendlich">("schlank")
|
||||||
// Zugeklappt statt Assistent (26.07.2026): der Entscheidungsbaum EXISTIERT — Wer baut das?,
|
// Zugeklappt statt Assistent (26.07.2026): der Entscheidungsbaum EXISTIERT — Wer baut das?,
|
||||||
// und nur im Zed-Ast: wie startest du? — aber du läufst ihn nur, wenn die Einordnung
|
// und nur im IDE-Ast: wie startest du? — aber du läufst ihn nur, wenn die Einordnung
|
||||||
// danebenlag. Im Normalfall steht da eine Zeile und du drückst Enter.
|
// danebenlag. Im Normalfall steht da eine Zeile und du drückst Enter.
|
||||||
const [offen, setOffen] = useState(false)
|
const [offen, setOffen] = useState(false)
|
||||||
// Hat die Box den Text wirklich gelesen? Steuert nur das Etikett „gelesen" in der
|
// Hat die Box den Text wirklich gelesen? Steuert nur das Etikett „gelesen" in der
|
||||||
@@ -131,12 +131,12 @@ function IdeenSection() {
|
|||||||
let verworfen = false
|
let verworfen = false
|
||||||
const timer = setTimeout(async () => {
|
const timer = setTimeout(async () => {
|
||||||
try {
|
try {
|
||||||
const r = await api<{ ok: boolean; wer?: "box" | "zed"; tiefe?: "schlank" | "gruendlich"; nur_denken?: boolean }>(
|
const r = await api<{ ok: boolean; wer?: "box" | "ide"; tiefe?: "schlank" | "gruendlich"; nur_denken?: boolean }>(
|
||||||
"/api/ideen/einordnen", { method: "POST", body: JSON.stringify({ text: t }) })
|
"/api/ideen/einordnen", { method: "POST", body: JSON.stringify({ text: t }) })
|
||||||
if (verworfen || !r?.ok) return
|
if (verworfen || !r?.ok) return
|
||||||
// Die drei Karten aus der Einordnung ableiten: eine Frage („lohnt sich…?") wird zum
|
// Die drei Karten aus der Einordnung ableiten: eine Frage („lohnt sich…?") wird zum
|
||||||
// Durchdenken, ein eigenständiges Programm zum Repo, alles am Heimlabor zur Box.
|
// Durchdenken, ein eigenständiges Programm zum Repo, alles am Heimlabor zur Box.
|
||||||
setModus(r.nur_denken ? "denken" : r.wer === "zed" ? "repo" : "box")
|
setModus(r.nur_denken ? "denken" : r.wer === "ide" ? "repo" : "box")
|
||||||
if (r.tiefe) setTiefe(r.tiefe)
|
if (r.tiefe) setTiefe(r.tiefe)
|
||||||
setVorgeschlagen(true)
|
setVorgeschlagen(true)
|
||||||
} catch { /* stumm — die Voreinstellung bleibt einfach stehen */ }
|
} catch { /* stumm — die Voreinstellung bleibt einfach stehen */ }
|
||||||
@@ -500,7 +500,7 @@ function IdeenSection() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* ZUGEKLAPPT STATT ASSISTENT. Der Entscheidungsbaum ist derselbe, den ein Wizard
|
{/* ZUGEKLAPPT STATT ASSISTENT. Der Entscheidungsbaum ist derselbe, den ein Wizard
|
||||||
abfragen wuerde — Wer baut das?, und NUR im Zed-Ast: wie startest du? Nur laeufst
|
abfragen wuerde — Wer baut das?, und NUR im IDE-Ast: wie startest du? Nur laeufst
|
||||||
du ihn erst, wenn die Einordnung danebenlag. Ein Assistent wuerde dich fragen, was
|
du ihn erst, wenn die Einordnung danebenlag. Ein Assistent wuerde dich fragen, was
|
||||||
die Box in ~500 ms schon weiss; das hier fragt nur im Zweifelsfall.
|
die Box in ~500 ms schon weiss; das hier fragt nur im Zweifelsfall.
|
||||||
IMMER sichtbar (26.07., User-Befund): vorher hing der ganze Block an
|
IMMER sichtbar (26.07., User-Befund): vorher hing der ganze Block an
|
||||||
@@ -516,7 +516,7 @@ function IdeenSection() {
|
|||||||
<div className="grid gap-2 sm:grid-cols-2">
|
<div className="grid gap-2 sm:grid-cols-2">
|
||||||
<Wahl aktiv={modus !== "box"}
|
<Wahl aktiv={modus !== "box"}
|
||||||
onWahl={() => setModus(modus === "box" ? "denken" : modus)}
|
onWahl={() => setModus(modus === "box" ? "denken" : modus)}
|
||||||
k={{ id: "zed", icon: Code2, titel: "Ich, in Zed",
|
k={{ id: "ide", icon: Code2, titel: "Ich, in der Agentic IDE",
|
||||||
text: "Du bekommst Konzept und Repo — den Code schreibst du selbst." }} />
|
text: "Du bekommst Konzept und Repo — den Code schreibst du selbst." }} />
|
||||||
<Wahl aktiv={modus === "box"}
|
<Wahl aktiv={modus === "box"}
|
||||||
onWahl={() => setModus("box")}
|
onWahl={() => setModus("box")}
|
||||||
@@ -525,7 +525,7 @@ function IdeenSection() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Die zweite Frage gibt es NUR im Zed-Ast — eingerückt, damit die Verschachtelung
|
{/* Die zweite Frage gibt es NUR im IDE-Ast — eingerückt, damit die Verschachtelung
|
||||||
sichtbar ist. Bei „die Box" folgt keine Rückfrage: dann geht es direkt los. */}
|
sichtbar ist. Bei „die Box" folgt keine Rückfrage: dann geht es direkt los. */}
|
||||||
{modus !== "box" && (
|
{modus !== "box" && (
|
||||||
<div className="border-l-2 border-primary/40 pl-3">
|
<div className="border-l-2 border-primary/40 pl-3">
|
||||||
@@ -880,7 +880,7 @@ function WeiterLeiste({ id, onFertig }: { id: string; onFertig?: () => void }) {
|
|||||||
<p className="mt-3 border-t border-violet-500/20 pt-2 text-[11px] text-emerald-300">
|
<p className="mt-3 border-t border-violet-500/20 pt-2 text-[11px] text-emerald-300">
|
||||||
{neu.art === "projekt" ? (
|
{neu.art === "projekt" ? (
|
||||||
<>Projekt-Karte <span className="font-mono">{neu.id}</span> ist angelegt — die Box bereitet
|
<>Projekt-Karte <span className="font-mono">{neu.id}</span> ist angelegt — die Box bereitet
|
||||||
das Repo vor (Konzept übernimmt sie, sie denkt es nicht neu). Danach öffnest du es in Zed.</>
|
das Repo vor (Konzept übernimmt sie, sie denkt es nicht neu). Danach öffnest du es in der Agentic IDE.</>
|
||||||
) : (
|
) : (
|
||||||
<>Überarbeitung <span className="font-mono">{neu.id}</span> läuft — die Box arbeitet deine
|
<>Überarbeitung <span className="font-mono">{neu.id}</span> läuft — die Box arbeitet deine
|
||||||
Rückmeldung ein und schreibt die neue Fassung an dieselbe Stelle. Danach hier wieder
|
Rückmeldung ein und schreibt die neue Fassung an dieselbe Stelle. Danach hier wieder
|
||||||
@@ -917,7 +917,7 @@ function WeiterLeiste({ id, onFertig }: { id: string; onFertig?: () => void }) {
|
|||||||
<p className="text-[11px] text-muted-foreground">
|
<p className="text-[11px] text-muted-foreground">
|
||||||
<b className="text-violet-300/90">Passt es so?</b> Dann macht die Box daraus ein startklares
|
<b className="text-violet-300/90">Passt es so?</b> Dann macht die Box daraus ein startklares
|
||||||
Repo — Konzept wird übernommen (nicht neu gedacht), dazu Roadmap, AGENTS.md & Co.
|
Repo — Konzept wird übernommen (nicht neu gedacht), dazu Roadmap, AGENTS.md & Co.
|
||||||
Gebaut wird danach von dir in Zed.
|
Gebaut wird danach von dir in der Agentic IDE.
|
||||||
</p>
|
</p>
|
||||||
<div className="flex flex-wrap items-center gap-x-3 gap-y-2">
|
<div className="flex flex-wrap items-center gap-x-3 gap-y-2">
|
||||||
<span className="text-[11px] text-muted-foreground/70">Ziel</span>
|
<span className="text-[11px] text-muted-foreground/70">Ziel</span>
|
||||||
|
|||||||
Reference in New Issue
Block a user