@arkvenai/cli 0.5.1 → 0.6.0
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/README.md +80 -242
- package/dist/befehle.js +138 -77
- package/dist/index.js +63 -334
- package/dist/projekt.js +121 -0
- package/dist/ruf.js +45 -0
- package/dist/uebertragen.js +185 -0
- package/dist/zugang.js +114 -0
- package/package.json +7 -39
- package/CHANGELOG.md +0 -105
- package/dist/agents.d.ts +0 -11
- package/dist/agents.d.ts.map +0 -1
- package/dist/agents.js +0 -76
- package/dist/agents.js.map +0 -1
- package/dist/auftrag.d.ts +0 -3
- package/dist/auftrag.d.ts.map +0 -1
- package/dist/auftrag.js +0 -45
- package/dist/auftrag.js.map +0 -1
- package/dist/bauplan.d.ts +0 -15
- package/dist/bauplan.d.ts.map +0 -1
- package/dist/bauplan.js +0 -219
- package/dist/bauplan.js.map +0 -1
- package/dist/befehle.d.ts +0 -12
- package/dist/befehle.d.ts.map +0 -1
- package/dist/befehle.js.map +0 -1
- package/dist/befund.d.ts +0 -21
- package/dist/befund.d.ts.map +0 -1
- package/dist/befund.js +0 -107
- package/dist/befund.js.map +0 -1
- package/dist/codeAblage.d.ts +0 -31
- package/dist/codeAblage.d.ts.map +0 -1
- package/dist/codeAblage.js +0 -80
- package/dist/codeAblage.js.map +0 -1
- package/dist/deklaration.d.ts +0 -3
- package/dist/deklaration.d.ts.map +0 -1
- package/dist/deklaration.js +0 -14
- package/dist/deklaration.js.map +0 -1
- package/dist/diff.d.ts +0 -10
- package/dist/diff.d.ts.map +0 -1
- package/dist/diff.js +0 -72
- package/dist/diff.js.map +0 -1
- package/dist/erkennung.d.ts +0 -26
- package/dist/erkennung.d.ts.map +0 -1
- package/dist/erkennung.js +0 -174
- package/dist/erkennung.js.map +0 -1
- package/dist/fix.d.ts +0 -26
- package/dist/fix.d.ts.map +0 -1
- package/dist/fix.js +0 -101
- package/dist/fix.js.map +0 -1
- package/dist/geteilt/bauplan/form.d.ts +0 -100
- package/dist/geteilt/bauplan/form.d.ts.map +0 -1
- package/dist/geteilt/bauplan/form.js +0 -21
- package/dist/geteilt/bauplan/form.js.map +0 -1
- package/dist/geteilt/bauplan/index.d.ts +0 -4
- package/dist/geteilt/bauplan/index.d.ts.map +0 -1
- package/dist/geteilt/bauplan/index.js +0 -4
- package/dist/geteilt/bauplan/index.js.map +0 -1
- package/dist/geteilt/bauplan/lesen.d.ts +0 -6
- package/dist/geteilt/bauplan/lesen.d.ts.map +0 -1
- package/dist/geteilt/bauplan/lesen.js +0 -344
- package/dist/geteilt/bauplan/lesen.js.map +0 -1
- package/dist/geteilt/bauplan/schreiben.d.ts +0 -3
- package/dist/geteilt/bauplan/schreiben.d.ts.map +0 -1
- package/dist/geteilt/bauplan/schreiben.js +0 -80
- package/dist/geteilt/bauplan/schreiben.js.map +0 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/init.d.ts +0 -28
- package/dist/init.d.ts.map +0 -1
- package/dist/init.js +0 -324
- package/dist/init.js.map +0 -1
- package/dist/login.d.ts +0 -45
- package/dist/login.d.ts.map +0 -1
- package/dist/login.js +0 -162
- package/dist/login.js.map +0 -1
- package/dist/mcp.d.ts +0 -18
- package/dist/mcp.d.ts.map +0 -1
- package/dist/mcp.js +0 -115
- package/dist/mcp.js.map +0 -1
- package/dist/neu.d.ts +0 -17
- package/dist/neu.d.ts.map +0 -1
- package/dist/neu.js +0 -118
- package/dist/neu.js.map +0 -1
- package/dist/npmrc.d.ts +0 -9
- package/dist/npmrc.d.ts.map +0 -1
- package/dist/npmrc.js +0 -49
- package/dist/npmrc.js.map +0 -1
- package/dist/projekte.d.ts +0 -23
- package/dist/projekte.d.ts.map +0 -1
- package/dist/projekte.js +0 -82
- package/dist/projekte.js.map +0 -1
- package/dist/pull.d.ts +0 -15
- package/dist/pull.d.ts.map +0 -1
- package/dist/pull.js +0 -301
- package/dist/pull.js.map +0 -1
- package/dist/push/bericht.d.ts +0 -8
- package/dist/push/bericht.d.ts.map +0 -1
- package/dist/push/bericht.js +0 -85
- package/dist/push/bericht.js.map +0 -1
- package/dist/push/form.d.ts +0 -67
- package/dist/push/form.d.ts.map +0 -1
- package/dist/push/form.js +0 -6
- package/dist/push/form.js.map +0 -1
- package/dist/push/medien.d.ts +0 -7
- package/dist/push/medien.d.ts.map +0 -1
- package/dist/push/medien.js +0 -154
- package/dist/push/medien.js.map +0 -1
- package/dist/push/sammeln.d.ts +0 -34
- package/dist/push/sammeln.d.ts.map +0 -1
- package/dist/push/sammeln.js +0 -112
- package/dist/push/sammeln.js.map +0 -1
- package/dist/push/verzeichnisse.d.ts +0 -40
- package/dist/push/verzeichnisse.d.ts.map +0 -1
- package/dist/push/verzeichnisse.js +0 -158
- package/dist/push/verzeichnisse.js.map +0 -1
- package/dist/push.d.ts +0 -8
- package/dist/push.d.ts.map +0 -1
- package/dist/push.js +0 -306
- package/dist/push.js.map +0 -1
- package/dist/starter.d.ts +0 -4
- package/dist/starter.d.ts.map +0 -1
- package/dist/starter.js +0 -587
- package/dist/starter.js.map +0 -1
- package/dist/tiefpruefung.d.ts +0 -39
- package/dist/tiefpruefung.d.ts.map +0 -1
- package/dist/tiefpruefung.js +0 -56
- package/dist/tiefpruefung.js.map +0 -1
- package/dist/vertrag.d.ts +0 -6
- package/dist/vertrag.d.ts.map +0 -1
- package/dist/vertrag.js +0 -267
- package/dist/vertrag.js.map +0 -1
- package/dist/vertragSpaet.d.ts +0 -4
- package/dist/vertragSpaet.d.ts.map +0 -1
- package/dist/vertragSpaet.js +0 -158
- package/dist/vertragSpaet.js.map +0 -1
- package/dist/vorlagen.d.ts +0 -7
- package/dist/vorlagen.d.ts.map +0 -1
- package/dist/vorlagen.js +0 -83
- package/dist/vorlagen.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @arkvenai/cli
|
|
2
2
|
|
|
3
|
-
Dein Arkven
|
|
3
|
+
Dein Arkven auf diesem Rechner: anmelden, Quelltext holen, ändern, zurückgeben, live schalten.
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
6
|
npm install -g @arkvenai/cli
|
|
@@ -11,294 +11,132 @@ Ohne Installation läuft jeder Befehl auch als `npx @arkvenai/cli <befehl>`.
|
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
14
|
-
##
|
|
14
|
+
## Ab 0.6.0: welcher Server
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
**0.6.0 spricht das heutige Arkven** unter `app.arkven.de`. Wer noch das alte System unter
|
|
17
|
+
`de.arkven.de` benutzt, bleibt auf `0.5.1` — die Wege dorthin heißen anders, und eine Fassung, die
|
|
18
|
+
beide bedient, bräuchte einen Schalter, der sich durch jeden Befehl zöge.
|
|
17
19
|
|
|
18
20
|
```bash
|
|
19
|
-
|
|
20
|
-
mkdir meine-app && cd meine-app
|
|
21
|
-
arkven pull # 2. zeigt deine Projekte, du wählst die Nummer
|
|
22
|
-
# 3. Änderungen machen: Editor, Agent, wie du willst
|
|
23
|
-
arkven push # 4. Vorschau ansehen und bestätigen
|
|
24
|
-
arkven push --deploy # 5. online stellen
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
**Schritt 2 sieht so aus:**
|
|
28
|
-
|
|
29
|
-
```
|
|
30
|
-
$ arkven pull
|
|
31
|
-
|
|
32
|
-
Dieser Ordner kennt noch kein Projekt. Deine Projekte:
|
|
33
|
-
|
|
34
|
-
1 Mein Laden live zuletzt 25.08.2026
|
|
35
|
-
sess_cf86fd83-6f68-45fa-8c9d-0399a3eb6caf
|
|
36
|
-
2 Touren-Planer zuletzt 20.08.2026
|
|
37
|
-
sess_9rxa9vk
|
|
38
|
-
|
|
39
|
-
Welches Projekt? [1-2] >
|
|
21
|
+
npm install -g @arkvenai/cli@0.5.1 # nur für de.arkven.de
|
|
40
22
|
```
|
|
41
23
|
|
|
42
|
-
Danach steht die Kennung in `arkven.json`, und jeder weitere `pull` und `push` in diesem Ordner
|
|
43
|
-
meint dieses Projekt. Ohne Rückfrage: `arkven pull --projekt=<kennung>`.
|
|
44
|
-
|
|
45
|
-
Von da an ist der Rundlauf immer derselbe: **ändern, `arkven push`, `arkven push --deploy`.**
|
|
46
|
-
|
|
47
24
|
---
|
|
48
25
|
|
|
49
|
-
##
|
|
26
|
+
## Der Rundlauf
|
|
50
27
|
|
|
51
28
|
```bash
|
|
52
|
-
arkven login
|
|
53
|
-
|
|
54
|
-
arkven init # 2. schreibt arkven.json
|
|
55
|
-
arkven push --name="Mein Tool" # 3. legt das Projekt in Arkven an
|
|
56
|
-
arkven push --deploy # 4. online stellen
|
|
57
|
-
```
|
|
29
|
+
arkven login # einmal je Rechner, du bestätigst im Browser
|
|
30
|
+
arkven status # welche Apps es gibt
|
|
58
31
|
|
|
59
|
-
|
|
60
|
-
|
|
32
|
+
mkdir meine-app && cd meine-app
|
|
33
|
+
arkven pull --app=lb1234abcd # zeigt erst, was käme
|
|
34
|
+
arkven pull --app=lb1234abcd --ja
|
|
61
35
|
|
|
62
|
-
|
|
63
|
-
schon erfüllt.
|
|
36
|
+
# ... ändern, wie du willst ...
|
|
64
37
|
|
|
65
|
-
|
|
38
|
+
arkven push # zeigt, was sich ändern würde
|
|
39
|
+
arkven push --ja # überträgt
|
|
40
|
+
arkven live --ja # schaltet live
|
|
41
|
+
```
|
|
66
42
|
|
|
67
|
-
|
|
43
|
+
Nach dem ersten `pull` steht die Zuordnung in `arkven.json`, und `push` weiß von selbst, welche App
|
|
44
|
+
gemeint ist.
|
|
68
45
|
|
|
69
|
-
|
|
70
|
-
|---|---|
|
|
71
|
-
| `arkven login` | Meldet diesen Rechner an deinem Arkven-Konto an |
|
|
72
|
-
| `arkven pull` | Holt ein Projekt aus Arkven in diesen Ordner |
|
|
73
|
-
| `arkven push` | Stellt deinen Stand zurück nach Arkven |
|
|
74
|
-
| `arkven push --deploy` | Rollt danach aus und zeigt den Lauf mit |
|
|
75
|
-
| `arkven init` | Erkennt, was dein Projekt mitbringt, und schreibt `arkven.json` |
|
|
76
|
-
| `arkven new <name>` | Legt ein neues Projekt an, das den Container-Vertrag schon erfüllt |
|
|
77
|
-
| `arkven check` | Prüft dein Projekt, so oft du willst |
|
|
78
|
-
| `arkven fix` | Übergibt die Befunde dem lokalen Claude Code und misst danach erneut |
|
|
79
|
-
| `arkven mcp` | Meldet `check`, `auftrag` und `pull` als MCP-Werkzeuge an |
|
|
80
|
-
|
|
81
|
-
`arkven help` zeigt dieselbe Übersicht mit allen Schaltern.
|
|
46
|
+
**Kein Befehl verändert etwas ohne `--ja`.** Ohne die Flagge siehst du nur, was passieren würde.
|
|
82
47
|
|
|
83
48
|
---
|
|
84
49
|
|
|
85
|
-
##
|
|
50
|
+
## Mehrere Umgebungen
|
|
86
51
|
|
|
87
52
|
```bash
|
|
88
|
-
arkven login
|
|
89
|
-
arkven login --server
|
|
90
|
-
arkven login --einfuegen # wenn dieser Rechner den Server nicht erreicht
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
Der Browser bestätigt, das Token landet im Benutzerverzeichnis (`~/.arkven/zugang.json`), nie im
|
|
94
|
-
Projekt. Die Standard-Adresse ist `app.arkven.de` und nicht `arkven.de`: unter der bloßen Domain
|
|
95
|
-
liegt die Marketing-Seite, die Anwendung samt API liegt unter `app.`.
|
|
96
|
-
|
|
97
|
-
`login` richtet auch den Paketbezug ein, danach funktioniert `npm install @arkvenai/base` in diesem
|
|
98
|
-
Projekt.
|
|
53
|
+
arkven login # heißt "produktion"
|
|
54
|
+
arkven login --server=https://app.s.arkven.de # heißt "staging"
|
|
99
55
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
arkven pull # zeigt deine Projekte und fragt, welches
|
|
104
|
-
arkven pull --projekt=<kennung> # ohne Rückfrage, für Skripte
|
|
105
|
-
arkven pull --yes # bestätigt die Vorschau ungesehen
|
|
106
|
-
arkven pull --nur-deklaration # ohne Code: Bauplan, Auftrag, Nachweis, Mail-Vorlagen
|
|
56
|
+
arkven umgebung # alle, die aktive mit *
|
|
57
|
+
arkven umgebung staging # umschalten
|
|
58
|
+
arkven status --umgebung=produktion # einmalig eine andere fragen
|
|
107
59
|
```
|
|
108
60
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
Wo Server und Oberfläche liegen, sagt das Projekt selbst: `pull` trägt seine `arkven.json` nach,
|
|
113
|
-
bevor er ablegt, und legt die genannten Ordner an. Damit bekommst du den Baum, den ein späterer
|
|
114
|
-
`push` wieder erwartet.
|
|
61
|
+
Beide Anmeldungen liegen nebeneinander in `~/.arkven/zugang.json`. Bis 0.5.1 war dort Platz für
|
|
62
|
+
genau eine, und ein Login gegen Staging warf den Produktionszugang weg.
|
|
115
63
|
|
|
116
|
-
|
|
117
|
-
|
|
64
|
+
Ein `arkven.json` kann seine Umgebung festhalten (`"umgebung": "staging"`), dann gilt für diesen
|
|
65
|
+
Ordner immer sie — auch wenn gerade eine andere aktiv ist.
|
|
118
66
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
```bash
|
|
122
|
-
arkven push # zeigt die Vorschau und fragt
|
|
123
|
-
arkven push --deploy # danach ausrollen und den Lauf mitlesen
|
|
124
|
-
arkven push --yes # bestätigt sie ungesehen (CI, Agenten)
|
|
125
|
-
arkven push --name="Mein Tool" # der Anzeigename beim ersten Mal
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
Die Reihenfolge ist die Aussage:
|
|
129
|
-
|
|
130
|
-
1. **Geprüft wird zuerst.** Was den Container-Vertrag nicht hält, wird benannt und nicht
|
|
131
|
-
übertragen. Die Gates der Plattform laufen dabei mit, dieselbe Prüfung wie beim Ausrollen.
|
|
132
|
-
2. **Gesammelt wird nur Quelltext.** Versteckte Einträge bleiben liegen, also auch `.env` und
|
|
133
|
-
`.git`: Zugangsdaten verlassen deinen Rechner nicht. Erzeugte Ordner (`node_modules`, `dist`,
|
|
134
|
-
`build`, `coverage`) ebenfalls nicht. Was ausgelassen wurde, sagt der Lauf mit Zahl.
|
|
135
|
-
3. **Vorschau vor dem Schreiben.**
|
|
67
|
+
---
|
|
136
68
|
|
|
137
|
-
|
|
138
|
-
Vorschau für „Rechnungstool" (sess_a8jan2i)
|
|
69
|
+
## Wenn ein Programm für dich arbeitet
|
|
139
70
|
|
|
140
|
-
|
|
141
|
-
3 aktualisiert (du hast sie geändert, Arkven nicht)
|
|
142
|
-
84 unberuehrt (in Arkven ändert sich daran nichts)
|
|
143
|
-
```
|
|
71
|
+
Läuft in diesem Ordner ein Agent, gib ihm einen Zugang, der **nicht** live schalten kann:
|
|
144
72
|
|
|
145
|
-
|
|
146
|
-
auch `--yes` löst keinen Konflikt auf: eine automatische Wahl würde eine der beiden Fassungen still
|
|
147
|
-
verlieren, und das sähe aus wie ein gelungener Push.
|
|
73
|
+
Arkven öffnen → **Zugänge** → **Zugang anlegen** → *Ansehen und Quelltext übertragen*.
|
|
148
74
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
75
|
+
Der darf holen und übertragen. Das Live-Schalten bleibt bei dir: du siehst dir den Stand in Arkven
|
|
76
|
+
an und entscheidest. Ein Zugang aus `arkven login` kann beides — den holst du dir für dich, nicht
|
|
77
|
+
für ein Programm.
|
|
152
78
|
|
|
153
|
-
|
|
154
|
-
|
|
79
|
+
| | ansehen | übertragen | live schalten |
|
|
80
|
+
|---|---|---|---|
|
|
81
|
+
| Zugang „Nur ansehen" (7 Tage) | ja | nein | nein |
|
|
82
|
+
| Zugang „übertragen" (1 Tag) | ja | ja | **nein** |
|
|
83
|
+
| `arkven login` (30 Tage) | ja | ja | ja |
|
|
155
84
|
|
|
156
|
-
|
|
85
|
+
---
|
|
157
86
|
|
|
158
|
-
|
|
159
|
-
der `package.json` der Projektwurzel, danach der Name der Wurzel selbst. Sagt keiner davon etwas
|
|
160
|
-
über das Projekt (`server`, `app`, `src` …), wird gefragt. Gibt es kein Terminal, bricht der Lauf ab
|
|
161
|
-
und nennt `--name` als Weg. Aus einem Ordnernamen wurde schon einmal ein Projekt namens „server".
|
|
87
|
+
## Was mitgeht und was nicht
|
|
162
88
|
|
|
163
|
-
|
|
89
|
+
`arkven push` schickt den Quelltext dieses Ordners. Draußen bleiben `node_modules`, `dist`, `build`,
|
|
90
|
+
`.git`, `.next`, `.cache`, `coverage` — und **`.env`**, weil dort Geheimnisse stehen. Eine
|
|
91
|
+
`.env.example` geht mit.
|
|
164
92
|
|
|
165
|
-
|
|
166
|
-
Frontend-Teil entstehen Vorschau und Frontend-Bau, der Server-Teil geht in den Container. Liegen
|
|
167
|
-
beide bei dir in eigenen Ordnern, sagt das `arkven.json`:
|
|
93
|
+
Bilder, Schriften und Videos gehen diesen Weg nicht; die Ausgabe sagt, wie viele übersprungen wurden.
|
|
168
94
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
"verzeichnisse": {
|
|
172
|
-
"server": "server", // geht in den Container
|
|
173
|
-
"frontend": "web" // wird die Vorschau
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
```
|
|
95
|
+
**Ein Push löscht nichts.** Was in Arkven liegt und nicht mitkommt, bleibt liegen — die Vorschau
|
|
96
|
+
sagt, wie viele das sind. Wer eine Datei loswerden will, entfernt sie in Arkven.
|
|
177
97
|
|
|
178
|
-
|
|
179
|
-
Baum. Mit der Angabe gilt:
|
|
180
|
-
|
|
181
|
-
- **Beide Bäume werden gesammelt**, jeder mit Pfaden relativ zu seinem Verzeichnis: aus
|
|
182
|
-
`web/src/App.tsx` wird `/src/App.tsx` in der App, aus `server/src/index.ts` wird `src/index.ts`
|
|
183
|
-
im Server-Quelltext. Der Bericht sagt vor dem Schreiben, welche Datei wohin geht.
|
|
184
|
-
- **Geprüft wird der Server-Teil**, nicht die Wurzel.
|
|
185
|
-
- **`arkven.json` reist mit dem Frontend-Teil.** Der Bau liest deine `mitgebracht`-Angaben dort;
|
|
186
|
-
ohne diesen Schritt käme deine eigene `tailwind.config.js` unter das Scaffold.
|
|
187
|
-
- **Was außerhalb beider Ordner liegt, kommt nicht mit** und wird beim Namen genannt. Braucht ein
|
|
188
|
-
Teil einen gemeinsamen `shared/`-Ordner, muss er innerhalb seines Verzeichnisses liegen.
|
|
189
|
-
|
|
190
|
-
Ein Verzeichnis, das es nicht gibt, bricht den Lauf ab, statt still auf „ein Baum" zurückzufallen:
|
|
191
|
-
genau dieser stille Rückfall hat am 2026-08-01 einen Express-Server in die Frontend-Vorschau
|
|
192
|
-
gelegt. Das Ergebnis war eine leere Seite und die Frage „wo ist mein Frontend?".
|
|
193
|
-
|
|
194
|
-
## `arkven init`
|
|
195
|
-
|
|
196
|
-
`init` liest, was da ist (`package.json`, Lockfile, eigener Server, `drizzle/`-Historie,
|
|
197
|
-
Build-Setup) und schreibt **eine** Datei: `arkven.json`.
|
|
198
|
-
|
|
199
|
-
```jsonc
|
|
200
|
-
{
|
|
201
|
-
"$schema": "https://app.arkven.de/schema/arkven.json",
|
|
202
|
-
"mitgebracht": {
|
|
203
|
-
"server": true, // Arkven ergänzt, es scaffoldet nicht
|
|
204
|
-
"frontendBuild": false, // tailwind/postcss/vite bleiben deine
|
|
205
|
-
"schema": true // deine Migrationen gewinnen
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
```
|
|
98
|
+
---
|
|
209
99
|
|
|
210
|
-
|
|
211
|
-
(Skript, CI, Pipe), bleibt das Feld aus der Datei heraus und der Lauf sagt, welches und warum. Ein
|
|
212
|
-
geratenes `server: true` hieße später: Arkven ergänzt einen Server, den es nie gab.
|
|
100
|
+
## Wenn etwas nicht geht
|
|
213
101
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
102
|
+
| Meldung | Was zu tun ist |
|
|
103
|
+
|---|---|
|
|
104
|
+
| „Auf diesem Rechner ist noch keine Umgebung angemeldet" | `arkven login` |
|
|
105
|
+
| „Der Zugang für … ist abgelaufen" | `arkven login --umgebung=<name>` |
|
|
106
|
+
| „Dieser Ordner gehört zu keiner App" | `arkven pull --app=<kennung>`, Kennungen zeigt `arkven status` |
|
|
107
|
+
| „Dieser Zugang darf Quelltext übertragen, aber nicht live schalten" | So ist er gemeint. Live schalten in Arkven, oder mit einem Zugang aus `arkven login` |
|
|
108
|
+
| „An dieser App arbeitet gerade der Agent" | Warten, bis der Lauf durch ist |
|
|
218
109
|
|
|
219
|
-
|
|
220
|
-
anderes sagt; der Unterschied wird benannt statt überschrieben. Ein zweiter Lauf ändert nichts, was
|
|
221
|
-
der erste richtig gemacht hat, und formatiert deine `package.json` nicht um.
|
|
110
|
+
---
|
|
222
111
|
|
|
223
|
-
##
|
|
112
|
+
## Alle Befehle
|
|
224
113
|
|
|
225
|
-
```bash
|
|
226
|
-
arkven new meine-app
|
|
227
|
-
cd meine-app && npm install
|
|
228
114
|
```
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
| Einstieg mit Härtungs-Prüfung beim Start | `src/index.ts` | Fällt ein Pflicht-Header beim Umbau heraus, bricht der Start ab, statt still ungehärtet zu laufen |
|
|
236
|
-
| Wächter gegen die laufende Datenbank | `src/schemaGate.ts` | Eine Migration kann mit Rückgabewert 0 enden, ohne dass das Schema steht |
|
|
237
|
-
| Eine Egress-Naht mit Host-Allowlist | `src/lib/egress.ts` | „Mit wem redet diese App?" hat genau eine Antwort |
|
|
238
|
-
| Härtung ohne Importe | `src/http/sicherheitsHeader.ts` | Läge sie im Einstieg, entstünde ein Import-Zyklus über die Middleware |
|
|
239
|
-
| Migration **und** Journal | `drizzle/` | Ohne Journal legt der Container das Schema neu an, statt zu migrieren |
|
|
240
|
-
| `tsx` und `drizzle-kit` in `dependencies` | `package.json` | Der Container installiert nur `dependencies` |
|
|
241
|
-
|
|
242
|
-
`arkven.json` entsteht dabei über dieselbe Erkennung wie bei `init`, nicht über eine zweite Regel.
|
|
243
|
-
|
|
244
|
-
**Es wird nie etwas überschrieben.** Liegt im Zielverzeichnis schon etwas, bricht der Lauf ab und
|
|
245
|
-
nennt beide Auswege (anderer Name oder `arkven init`). Ein leeres Verzeichnis darf er benutzen.
|
|
246
|
-
|
|
247
|
-
## `arkven check`
|
|
248
|
-
|
|
249
|
-
```bash
|
|
250
|
-
arkven check # lokal, in Sekunden
|
|
251
|
-
arkven check --tief # die Gates der Plattform laufen mit (braucht Anmeldung)
|
|
252
|
-
arkven check --json # stabile Regel-Kennungen, für Agenten
|
|
253
|
-
arkven check --sarif # SARIF 2.1.0 für GitHub Code-Scanning, VS Code und CI
|
|
115
|
+
arkven login [--server=<adresse>] [--umgebung=<name>]
|
|
116
|
+
arkven status [--umgebung=<name>]
|
|
117
|
+
arkven umgebung [<name>] [--weg=<name>]
|
|
118
|
+
arkven pull [--app=<kennung>] [--ja]
|
|
119
|
+
arkven push [--betreff="..."] [--ja]
|
|
120
|
+
arkven live [--ja]
|
|
254
121
|
```
|
|
255
122
|
|
|
256
|
-
|
|
123
|
+
`--umgebung=<name>` geht überall, wenn nicht die aktive gemeint ist.
|
|
257
124
|
|
|
258
|
-
|
|
259
|
-
|---|---|
|
|
260
|
-
| `arkven/ein-paket` | Das Verzeichnis ist ein Paket, kein Verbund aus mehreren |
|
|
261
|
-
| `arkven/einstieg` | `src/index.ts` ist der Einstiegspunkt |
|
|
262
|
-
| `arkven/port-aus-umgebung` | Der Port kommt aus `process.env.PORT` |
|
|
263
|
-
| `arkven/datenbank-aus-umgebung` | Die Verbindung kommt aus `process.env.DATABASE_URL` |
|
|
264
|
-
| `arkven/keine-workspaces` | Eine `package.json`, keine Workspace-Verweise |
|
|
265
|
-
| `arkven/importe-aufloesbar` | Jeder Import zeigt auf ein Paket, das im Container existiert |
|
|
266
|
-
| `arkven/laufzeit-tsx` · `arkven/laufzeit-drizzle-kit` | Beide stehen in `dependencies`, nicht in `devDependencies` |
|
|
267
|
-
| `arkven/schema-waechter` | `src/schemaGate.ts` prüft das Schema gegen die laufende Datenbank |
|
|
268
|
-
|
|
269
|
-
Dazu zwei Hinweise, die nicht blockieren: ein fehlendes Migrations-Journal
|
|
270
|
-
(`arkven/migrations-journal`) und fehlender Baustein-Bezug (`arkven/paketbezug`).
|
|
125
|
+
---
|
|
271
126
|
|
|
272
|
-
|
|
273
|
-
statt sieben: der Container macht genau ein Paket zur App, also ist erst zu klären, welches. Die
|
|
274
|
-
übrigen Punkte erscheinen als „nicht geprüft", nicht als verletzt. Der Ausweg nennt die Kandidaten.
|
|
127
|
+
## Für den Betrieb: veröffentlichen
|
|
275
128
|
|
|
276
|
-
|
|
129
|
+
Das Konto `arkvenai` steht auf `two-factor auth: auth-and-writes`, und es gibt kein
|
|
130
|
+
Authenticator-Programm. Deshalb geht das Veröffentlichen **nur aus einem echten
|
|
131
|
+
Konsolenfenster**: ohne stdin-TTY bietet npm den Browser-Weg gar nicht erst an und bricht mit
|
|
132
|
+
`EOTP` ab. Aus einer Werkzeug-Shell heraus also nie.
|
|
277
133
|
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
arkven auftrag # gibt nur die Arbeitsanweisung aus, ohne etwas zu tun
|
|
134
|
+
```powershell
|
|
135
|
+
Start-Process cmd.exe -ArgumentList '/k','cd /d C:\Users\Pflegehilfe\Desktop\Sortieren\Regugate\lean-builder\cli && npm run veroeffentlichen'
|
|
281
136
|
```
|
|
282
137
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
es erneut.
|
|
286
|
-
|
|
287
|
-
Die tragende Regel: **behoben ist nur, was der erneute Lauf misst.** Die Erfolgsmeldung des Agenten
|
|
288
|
-
zählt nichts. Bringt eine Runde keinen einzigen Punkt weiter, hört `fix` auf, statt dieselbe
|
|
289
|
-
Anweisung zu wiederholen. Es committet nichts und pusht nichts; die Änderungen liegen als `git diff`
|
|
290
|
-
zur Durchsicht. Ist kein `claude` installiert, sagt `fix` das und nennt den Weg.
|
|
291
|
-
|
|
292
|
-
---
|
|
293
|
-
|
|
294
|
-
## Rückgabewerte
|
|
295
|
-
|
|
296
|
-
| Befehl | `0` | `1` | `2` |
|
|
297
|
-
|---|---|---|---|
|
|
298
|
-
| `check` | alles gehalten | mindestens ein blockierender Punkt | nichts messbar |
|
|
299
|
-
| `init` | alles geklärt | etwas bleibt zu entscheiden | nichts messbar |
|
|
300
|
-
| `new` | angelegt und nachgemessen | abgebrochen, nichts angelegt | |
|
|
301
|
-
| `push` | übernommen | Befund oder Konflikt | nichts messbar |
|
|
138
|
+
**Sobald „Press ENTER to open in the browser" erscheint: ENTER im Fenster drücken**, nicht selbst
|
|
139
|
+
zum Browser wechseln. Genau daran ist der Lauf zu 0.5.0 gescheitert.
|
|
302
140
|
|
|
303
|
-
|
|
304
|
-
|
|
141
|
+
Danach gegenprüfen, und zwar mit Abstand: `npm view @arkvenai/cli version` liest aus einem CDN und
|
|
142
|
+
zeigt direkt nach dem Upload noch den alten Stand. Eine Minute warten, dann fragen.
|
package/dist/befehle.js
CHANGED
|
@@ -1,77 +1,138 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
{
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
import { spawn } from 'node:child_process';
|
|
3
|
+
import * as ablage from './zugang.js';
|
|
4
|
+
import { absage, neuesGeheimnis, ruf, schlafe } from './ruf.js';
|
|
5
|
+
const OK = { code: 0 };
|
|
6
|
+
const FEHLER = { code: 1 };
|
|
7
|
+
// ── login ────────────────────────────────────────────────────────────────────
|
|
8
|
+
function browserOeffnen(url) {
|
|
9
|
+
const [befehl, args] = process.platform === 'win32'
|
|
10
|
+
? ['cmd', ['/c', 'start', '', url]]
|
|
11
|
+
: process.platform === 'darwin'
|
|
12
|
+
? ['open', [url]]
|
|
13
|
+
: ['xdg-open', [url]];
|
|
14
|
+
try {
|
|
15
|
+
const p = spawn(befehl, args, { stdio: 'ignore', detached: true });
|
|
16
|
+
p.unref();
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export async function login(opts) {
|
|
24
|
+
const server = (opts.server ?? ablage.STANDARD_SERVER).replace(/\/+$/, '');
|
|
25
|
+
const name = opts.umgebung ?? ablage.namenVorschlag(server);
|
|
26
|
+
const { verifier, challenge } = neuesGeheimnis();
|
|
27
|
+
const start = await ruf(server, '/api/auth/cli/start', { koerper: { challenge, herkunft: `${os.hostname()} (${os.platform()})` } });
|
|
28
|
+
if (!start.ok) {
|
|
29
|
+
opts.sage(absage(start));
|
|
30
|
+
opts.sage(`Pruef die Adresse: ${server}`);
|
|
31
|
+
return FEHLER;
|
|
32
|
+
}
|
|
33
|
+
opts.sage('');
|
|
34
|
+
opts.sage(' Oeffne diese Seite, um dich anzumelden:');
|
|
35
|
+
opts.sage(` ${start.daten.url}`);
|
|
36
|
+
opts.sage('');
|
|
37
|
+
opts.sage(` Dort sollte dieser Code stehen: ${start.daten.code}`);
|
|
38
|
+
opts.sage('');
|
|
39
|
+
browserOeffnen(start.daten.url);
|
|
40
|
+
opts.sage(' Warte auf die Bestaetigung ...');
|
|
41
|
+
const bis = start.daten.laeuftAbAm;
|
|
42
|
+
const abstand = opts.warteMs ?? 2000;
|
|
43
|
+
while (Date.now() < bis) {
|
|
44
|
+
await schlafe(abstand);
|
|
45
|
+
const holen = await ruf(server, '/api/auth/cli/token', { koerper: { anfrage: start.daten.anfrage, verifier } });
|
|
46
|
+
// 202 heisst "noch niemand hat bestaetigt". Kein Fehler, sondern der Normalfall,
|
|
47
|
+
// solange der Mensch die Seite noch offen hat.
|
|
48
|
+
if (!holen.ok && holen.status === 202)
|
|
49
|
+
continue;
|
|
50
|
+
if (!holen.ok && holen.status === 0)
|
|
51
|
+
continue;
|
|
52
|
+
if (!holen.ok) {
|
|
53
|
+
opts.sage('');
|
|
54
|
+
opts.sage(absage(holen));
|
|
55
|
+
return FEHLER;
|
|
56
|
+
}
|
|
57
|
+
const wo = ablage.eintragen(ablage.lesen(), {
|
|
58
|
+
name,
|
|
59
|
+
server,
|
|
60
|
+
token: holen.daten.cliToken,
|
|
61
|
+
laeuftAbAm: holen.daten.laeuftAbAm.cli,
|
|
62
|
+
konto: holen.daten.konto,
|
|
63
|
+
teams: holen.daten.teams,
|
|
64
|
+
angemeldetAm: Date.now(),
|
|
65
|
+
});
|
|
66
|
+
const datei = ablage.schreiben(wo);
|
|
67
|
+
opts.sage('');
|
|
68
|
+
opts.sage(` Angemeldet als ${holen.daten.konto ?? 'dein Konto'} in "${name}".`);
|
|
69
|
+
opts.sage(` Der Zugang liegt in ${datei} und gilt 30 Tage.`);
|
|
70
|
+
opts.sage('');
|
|
71
|
+
return OK;
|
|
72
|
+
}
|
|
73
|
+
opts.sage('');
|
|
74
|
+
opts.sage('Es kam keine Bestaetigung an, und die Anmeldung ist abgelaufen.');
|
|
75
|
+
opts.sage('Fang sie neu an: arkven login');
|
|
76
|
+
return FEHLER;
|
|
77
|
+
}
|
|
78
|
+
// ── umgebung und status ──────────────────────────────────────────────────────
|
|
79
|
+
export function umgebung(opts) {
|
|
80
|
+
const wo = ablage.lesen();
|
|
81
|
+
if (opts.weg) {
|
|
82
|
+
if (!wo.umgebungen.some((u) => u.name === opts.weg)) {
|
|
83
|
+
opts.sage(`Eine Umgebung "${opts.weg}" ist hier nicht angemeldet.`);
|
|
84
|
+
return FEHLER;
|
|
85
|
+
}
|
|
86
|
+
ablage.schreiben(ablage.entfernen(wo, opts.weg));
|
|
87
|
+
opts.sage(`"${opts.weg}" ist weg. Der Token auf dem Server gilt weiter, bis du ihn dort entziehst.`);
|
|
88
|
+
return OK;
|
|
89
|
+
}
|
|
90
|
+
if (opts.name) {
|
|
91
|
+
if (!wo.umgebungen.some((u) => u.name === opts.name)) {
|
|
92
|
+
const da = wo.umgebungen.map((u) => u.name).join(', ');
|
|
93
|
+
opts.sage(`Eine Umgebung "${opts.name}" ist hier nicht angemeldet.`);
|
|
94
|
+
opts.sage(da ? `Angemeldet sind: ${da}.` : 'Melde dich an: arkven login');
|
|
95
|
+
return FEHLER;
|
|
96
|
+
}
|
|
97
|
+
ablage.schreiben({ ...wo, aktiv: opts.name });
|
|
98
|
+
opts.sage(`Aktiv ist jetzt "${opts.name}".`);
|
|
99
|
+
return OK;
|
|
100
|
+
}
|
|
101
|
+
if (wo.umgebungen.length === 0) {
|
|
102
|
+
opts.sage('Auf diesem Rechner ist noch keine Umgebung angemeldet.');
|
|
103
|
+
opts.sage('Melde dich an: arkven login');
|
|
104
|
+
return OK;
|
|
105
|
+
}
|
|
106
|
+
for (const u of wo.umgebungen) {
|
|
107
|
+
const marke = u.name === wo.aktiv ? '*' : ' ';
|
|
108
|
+
opts.sage(`${marke} ${u.name.padEnd(12)} ${u.server} ${ablage.restlaufzeit(u)}`);
|
|
109
|
+
}
|
|
110
|
+
return OK;
|
|
111
|
+
}
|
|
112
|
+
export async function status(opts) {
|
|
113
|
+
const wahl = ablage.waehlen(ablage.lesen(), opts.umgebung);
|
|
114
|
+
if (!wahl.ok) {
|
|
115
|
+
opts.sage(wahl.grund);
|
|
116
|
+
opts.sage(wahl.ausweg);
|
|
117
|
+
return FEHLER;
|
|
118
|
+
}
|
|
119
|
+
const u = wahl.umgebung;
|
|
120
|
+
opts.sage(`Umgebung ${u.name} (${u.server})`);
|
|
121
|
+
opts.sage(`Konto ${u.konto ?? 'unbekannt'}`);
|
|
122
|
+
opts.sage(`Zugang ${ablage.restlaufzeit(u)}`);
|
|
123
|
+
const apps = await ruf(u.server, '/api/cli/apps', { token: u.token });
|
|
124
|
+
if (!apps.ok) {
|
|
125
|
+
opts.sage('');
|
|
126
|
+
opts.sage(absage(apps));
|
|
127
|
+
return FEHLER;
|
|
128
|
+
}
|
|
129
|
+
opts.sage('');
|
|
130
|
+
if (apps.daten.apps.length === 0) {
|
|
131
|
+
opts.sage('Du hast dort noch keine App.');
|
|
132
|
+
return OK;
|
|
133
|
+
}
|
|
134
|
+
for (const a of apps.daten.apps) {
|
|
135
|
+
opts.sage(` ${a.id.padEnd(12)} ${a.name.padEnd(28)} ${a.live ? 'live' : a.status}`);
|
|
136
|
+
}
|
|
137
|
+
return OK;
|
|
138
|
+
}
|