@k2b/cloud 0.24.0 → 0.26.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.
Files changed (53) hide show
  1. package/package.json +3 -2
  2. package/src/_internal/capabilities.ts +12 -0
  3. package/src/_internal/registry.ts +1 -0
  4. package/src/access/GroupCoverage.tsx +175 -0
  5. package/src/access/PermissionEditor.tsx +134 -93
  6. package/src/access/managers.ts +32 -0
  7. package/src/access/messages.ts +36 -0
  8. package/src/ai/approval-routes.ts +5 -5
  9. package/src/ai/capabilities.ts +34 -12
  10. package/src/ai/chat/blocks.tsx +86 -179
  11. package/src/ai/chat/builtin-tools.tsx +57 -30
  12. package/src/ai/chat/live-turn.browser-harness.tsx +37 -0
  13. package/src/ai/chat/message-actions.tsx +6 -2
  14. package/src/ai/chat/message-utils.ts +17 -14
  15. package/src/ai/chat/messages.ts +324 -2
  16. package/src/ai/chat/presentation.tsx +257 -103
  17. package/src/ai/chat/tool-groups.ts +55 -35
  18. package/src/ai/chat/turn-layout.ts +141 -0
  19. package/src/ai/chat/turn-view.tsx +609 -0
  20. package/src/ai/client/projection.ts +37 -6
  21. package/src/ai/executor.ts +38 -5
  22. package/src/ai/memory-learning.ts +7 -12
  23. package/src/ai/memory-workflow-evidence.ts +10 -2
  24. package/src/ai/migrate.ts +45 -2
  25. package/src/ai/model-access.ts +4 -2
  26. package/src/ai/prefs.ts +19 -5
  27. package/src/ai/projects.ts +5 -2
  28. package/src/ai/protocol.ts +20 -4
  29. package/src/ai/provider-fetch.ts +67 -15
  30. package/src/ai/provider-retry.ts +105 -0
  31. package/src/ai/quota-provider.ts +14 -5
  32. package/src/ai/skills.ts +5 -2
  33. package/src/ai/store.ts +108 -3
  34. package/src/ai/stream.ts +2 -0
  35. package/src/ai/timeline.ts +9 -11
  36. package/src/ai/turn-timing.ts +31 -3
  37. package/src/ai/types.ts +12 -2
  38. package/src/browser/FileChooser.tsx +600 -0
  39. package/src/browser/choose-files.browser-harness.tsx +32 -0
  40. package/src/browser/choose-files.tsx +70 -0
  41. package/src/browser/file-chooser-messages.ts +86 -0
  42. package/src/browser/file-providers.ts +217 -0
  43. package/src/browser/files.tsx +23 -0
  44. package/src/cli/admin/account-administration.ts +2 -2
  45. package/src/contracts/registry.ts +2 -0
  46. package/src/server/index.ts +1 -0
  47. package/src/server/services/access.ts +44 -11
  48. package/src/server/services/index.ts +1 -0
  49. package/src/shared/app-presentation.ts +10 -2
  50. package/src/ssr/platform-messages.ts +2 -2
  51. package/src/styles/effects.css +69 -0
  52. package/src/styles/file-chooser.css +169 -0
  53. package/src/styles/global.css +1 -0
@@ -11,7 +11,6 @@ const messages = i18n.define({
11
11
  tableCapped: "Showing the first 100 returned rows. The full tool result remains available in details.",
12
12
  tableMore: "More rows are available. Ask for the next page or open the result in the application.",
13
13
  assistantTurns: "Assistant turns",
14
- workSteps: "Work steps",
15
14
  surveyNoAnswer: "No answer",
16
15
  surveyNoAnswers: "No answers submitted.",
17
16
  toolCalls: "Tool calls",
@@ -21,10 +20,170 @@ const messages = i18n.define({
21
20
  createdPdf: "Created PDF",
22
21
  thinking: "Thinking",
23
22
  showReasoning: "Show reasoning",
23
+ reconnecting: "Reconnecting",
24
24
  byteRange: ({ start, end }: { start: string; end: string }) => `Bytes ${start}–${end}`,
25
+ worked: "Worked",
26
+ workedFor: ({ duration }: { duration: string }) => `Worked ${duration}`,
27
+ workedStopped: ({ duration }: { duration: string }) => (duration ? `Worked ${duration} · stopped` : "Stopped"),
28
+ workedInterrupted: ({ duration }: { duration: string }) => (duration ? `Worked ${duration} · interrupted` : "Interrupted"),
29
+ workedLabel: ({ duration, steps, ending }: { duration: string; steps: string; ending: "stopped" | "failed" | null }) =>
30
+ [duration ? `Worked ${duration}` : "Worked", ending === "stopped" ? "stopped" : ending === "failed" ? "interrupted" : "", steps]
31
+ .filter(Boolean)
32
+ .join(", "),
33
+ steps: ({ count }: { count: number }) => (count === 1 ? "1 step" : `${count} steps`),
34
+ waitingForApproval: "Waiting for your approval",
35
+ waitingForAnswer: "Waiting for your answer",
36
+ waitingSince: ({ duration }: { duration: string }) => `for ${duration}`,
37
+ durationSeconds: ({ seconds }: { seconds: number }) => `${seconds} s`,
38
+ durationMinutes: ({ minutes }: { minutes: number }) => `${minutes} min`,
39
+ durationHours: ({ hours, minutes }: { hours: number; minutes: number }) => (minutes ? `${hours} h ${minutes} min` : `${hours} h`),
40
+ durationSecondsLong: ({ seconds }: { seconds: number }) => (seconds === 1 ? "1 second" : `${seconds} seconds`),
41
+ durationMinutesLong: ({ minutes }: { minutes: number }) => (minutes === 1 ? "1 minute" : `${minutes} minutes`),
42
+ durationHoursLong: ({ hours, minutes }: { hours: number; minutes: number }) =>
43
+ [hours === 1 ? "1 hour" : `${hours} hours`, minutes ? (minutes === 1 ? "1 minute" : `${minutes} minutes`) : ""]
44
+ .filter(Boolean)
45
+ .join(" "),
46
+ stepThinking: "Thinking",
47
+ stepWriting: "Writing",
48
+ stepReading: ({ target }: { target: string }) => (target ? `Reading ${target}` : "Reading a file"),
49
+ stepListingFiles: "Looking through files",
50
+ stepViewingImage: "Looking at an image",
51
+ stepWritingFile: "Writing a file",
52
+ stepWritingCode: "Writing code",
53
+ stepRunningCode: "Running code",
54
+ stepCheckingApp: "Checking the app",
55
+ stepCode: "Working with code",
56
+ stepPlan: "Updating the working plan",
57
+ stepPdf: "Creating a PDF",
58
+ stepLoading: "Loading tools and guidance",
59
+ stepWeb: "Searching the web",
60
+ stepMemory: "Using memory",
61
+ stepCalculating: "Calculating",
62
+ stepUsingApp: ({ app }: { app: string }) => `Using ${app}`,
63
+ stepDeliveringFile: "Delivering a file",
64
+ stepPreparingView: "Preparing a view",
65
+ stepPreparingCard: "Preparing a card",
66
+ stepCompacting: "Summarizing the conversation",
67
+ stepTool: "Using a tool",
68
+ stepFailed: "failed",
69
+ stepRejected: "rejected",
70
+ stepWaiting: "waiting",
71
+ steered: "Conversation steered",
72
+ reasoning: "Reasoning",
73
+ groupPlan: "Updated working plan",
74
+ groupCode: "Worked with code",
75
+ groupCloud: "Used Cloud integration",
76
+ groupReadFiles: "Read files",
77
+ groupWriteFiles: "Wrote files",
78
+ groupPdf: "Created PDFs",
79
+ groupLoad: "Loaded tools and guidance",
80
+ groupWeb: "Searched the web",
81
+ groupMemory: "Used memory",
82
+ groupDelivered: "Delivered results",
83
+ groupTools: "Used tools",
84
+ groupFailed: ({ count }: { count: number }) => `${count} failed`,
85
+ groupRejected: ({ count }: { count: number }) => `${count} rejected`,
86
+ receiptDone: ({ title }: { title: string }) => `${title} done`,
87
+ receiptApproved: ({ title }: { title: string }) => `Approved: ${title}`,
88
+ approvalNeeded: ({ title }: { title: string }) => `Approval needed: ${title}`,
89
+ answerReady: "Answer ready",
90
+ receiptRejected: ({ title }: { title: string }) => `Rejected: ${title}`,
91
+ receiptFailed: ({ title }: { title: string }) => `Failed: ${title}`,
92
+ receiptNotRun: ({ title, stopped }: { title: string; stopped: boolean }) => `Not run: ${title}${stopped ? " · stopped" : ""}`,
93
+ workSteps: "Work steps",
25
94
  streamLoginRequired: "Your session has ended. Sign in again to continue this chat.",
26
95
  streamAccessDenied: "You no longer have access to this chat.",
27
96
  streamNotFound: "This chat is no longer available.",
97
+ assistant: "Assistant",
98
+ action: "Action",
99
+ approvalRequired: ({ title }: { title: string }) => `Approval required: ${title}`,
100
+ reject: "Reject",
101
+ approved: "Approved",
102
+ rejected: "Rejected",
103
+ alwaysApprove: "Always approve",
104
+ details: "Details",
105
+ hideDetails: "Hide details",
106
+ moreOptions: ({ title }: { title: string }) => `More options for ${title}`,
107
+ detailsFor: ({ title }: { title: string }) => `${title} details`,
108
+ linksFor: ({ title }: { title: string }) => `${title} links`,
109
+ contentOf: ({ label }: { label: string }) => `${label} content`,
110
+ approvalUnavailable: "Approval unavailable",
111
+ approvalFailed: "Could not submit. Try again.",
112
+ submitting: "Submitting",
113
+ submitted: "Submitted",
114
+ stoppingResponse: "Stopping response",
115
+ openIn: ({ app }: { app: string }) => `Open in ${app}`,
116
+ editIn: ({ app }: { app: string }) => `Edit in ${app}`,
117
+ statusIn: ({ app }: { app: string }) => `View status in ${app}`,
118
+ preview: "Preview",
119
+ download: "Download",
120
+ open: "Open",
121
+ edit: "Edit",
122
+ toolFailed: ({ title }: { title: string }) => `${title} failed`,
123
+ toolRejected: ({ title }: { title: string }) => `${title} was rejected`,
124
+ actionNotCompleted: "The action could not be completed.",
125
+ input: "Input",
126
+ response: "Response",
127
+ output: "Output",
128
+ toolInputOutput: "Tool input and output",
129
+ waiting: "Waiting",
130
+ failed: "Failed",
131
+ conversationSteered: "Conversation steered",
132
+ compacting: "Compacting context",
133
+ compacted: "Context compacted",
134
+ compactionSkipped: "Nothing to compact",
135
+ compactionFailed: "Compaction failed",
136
+ showCompaction: "Show compaction",
137
+ compactionSummary: "Older chat context was summarized into compact conversation memory.",
138
+ before: "Before",
139
+ after: "After",
140
+ textEditor: "Text editor",
141
+ preparingTextEditor: "Preparing text editor",
142
+ memory: "Memory",
143
+ usingMemory: "Using memory",
144
+ memoryNotUpdated: "Memory not updated",
145
+ remembered: "Remembered",
146
+ memoryUpdated: "Updated memory",
147
+ memoryForgotten: "Forgot memory",
148
+ memoriesSearched: "Searched memories",
149
+ memoriesListed: "Listed memories",
150
+ fileDownloadFailed: "File download failed",
151
+ fileNotImported: "The linked file could not be imported into this chat.",
152
+ tools: "Tools",
153
+ searchTools: ({ query }: { query: string }) => `Search tools: ${query}`,
154
+ found: ({ count, more }: { count: number; more?: boolean }) => `${count}${more ? "+" : ""} found`,
155
+ noTools: "No tools found.",
156
+ listApps: "List apps",
157
+ available: ({ count }: { count: number }) => `${count} available`,
158
+ noApps: "No capability apps available.",
159
+ loadTools: "Load tools",
160
+ loadedCount: ({ count }: { count: number }) => `${count} loaded`,
161
+ toolsLoaded: "Loaded",
162
+ toolsAlreadyLoaded: "Already loaded",
163
+ toolsMissing: "Missing",
164
+ toolsEvicted: "Evicted",
165
+ loadedSkill: ({ name }: { name: string }) => `Loaded skill ${name}`,
166
+ help: "Help",
167
+ searchHelp: ({ query }: { query: string }) => `Search help: ${query}`,
168
+ noHelp: "No Help articles found.",
169
+ readHelp: "Read help",
170
+ readHelpArticle: ({ title }: { title: string }) => `Read help: ${title}`,
171
+ articleNotFound: "Article not found",
172
+ searchProject: ({ query }: { query: string }) => `Search Project: ${query}`,
173
+ listProjectSources: "List Project sources",
174
+ noProjectSources: "No Project sources found.",
175
+ projectEntry: "Entry",
176
+ readProjectKnowledge: ({ title }: { title: string }) => `Read Project knowledge: ${title}`,
177
+ listFiles: ({ path }: { path: string }) => `List files: ${path}`,
178
+ noFiles: "No files found.",
179
+ file: "File",
180
+ wroteFile: "Wrote file",
181
+ readFile: ({ name }: { name: string }) => `Read file: ${name}`,
182
+ fileComplete: "complete",
183
+ fileMoreAvailable: "more available",
184
+ calculate: "Calculate",
185
+ inspectImage: ({ name }: { name: string }) => `Inspect image: ${name}`,
186
+ readResource: ({ ref }: { ref: string }) => `Read resource: ${ref}`,
28
187
  },
29
188
  de: {
30
189
  backgroundRun: "Hintergrundlauf",
@@ -35,7 +194,6 @@ const messages = i18n.define({
35
194
  "Die ersten 100 zurückgegebenen Zeilen werden angezeigt. Das vollständige Werkzeugergebnis bleibt in den Details verfügbar.",
36
195
  tableMore: "Weitere Zeilen sind verfügbar. Frage nach der nächsten Seite oder öffne das Ergebnis in der Anwendung.",
37
196
  assistantTurns: "Antwortdurchläufe",
38
- workSteps: "Arbeitsschritte",
39
197
  surveyNoAnswer: "Keine Antwort",
40
198
  surveyNoAnswers: "Keine Antworten abgegeben.",
41
199
  toolCalls: "Werkzeugaufrufe",
@@ -45,10 +203,174 @@ const messages = i18n.define({
45
203
  createdPdf: "PDF erstellt",
46
204
  thinking: "Denkt nach",
47
205
  showReasoning: "Denkprozess anzeigen",
206
+ reconnecting: "Verbindung wird wiederhergestellt",
48
207
  byteRange: ({ start, end }) => `Bytes ${start}–${end}`,
208
+ worked: "Gearbeitet",
209
+ workedFor: ({ duration }) => `${duration} gearbeitet`,
210
+ workedStopped: ({ duration }) => (duration ? `${duration} gearbeitet · gestoppt` : "Gestoppt"),
211
+ workedInterrupted: ({ duration }) => (duration ? `${duration} gearbeitet · abgebrochen` : "Abgebrochen"),
212
+ workedLabel: ({ duration, steps, ending }) =>
213
+ [
214
+ duration ? `${duration} gearbeitet` : "Gearbeitet",
215
+ ending === "stopped" ? "gestoppt" : ending === "failed" ? "abgebrochen" : "",
216
+ steps,
217
+ ]
218
+ .filter(Boolean)
219
+ .join(", "),
220
+ steps: ({ count }) => (count === 1 ? "1 Schritt" : `${count} Schritte`),
221
+ waitingForApproval: "Wartet auf deine Freigabe",
222
+ waitingForAnswer: "Wartet auf deine Antwort",
223
+ waitingSince: ({ duration }) => `seit ${duration}`,
224
+ durationSeconds: ({ seconds }) => `${seconds} s`,
225
+ durationMinutes: ({ minutes }) => `${minutes} Min.`,
226
+ durationHours: ({ hours, minutes }) => (minutes ? `${hours} Std. ${minutes} Min.` : `${hours} Std.`),
227
+ durationSecondsLong: ({ seconds }) => (seconds === 1 ? "1 Sekunde" : `${seconds} Sekunden`),
228
+ durationMinutesLong: ({ minutes }) => (minutes === 1 ? "1 Minute" : `${minutes} Minuten`),
229
+ durationHoursLong: ({ hours, minutes }) =>
230
+ [hours === 1 ? "1 Stunde" : `${hours} Stunden`, minutes ? (minutes === 1 ? "1 Minute" : `${minutes} Minuten`) : ""]
231
+ .filter(Boolean)
232
+ .join(" "),
233
+ stepThinking: "Denkt nach",
234
+ stepWriting: "Schreibt",
235
+ stepReading: ({ target }) => (target ? `Liest ${target}` : "Liest eine Datei"),
236
+ stepListingFiles: "Sieht Dateien durch",
237
+ stepViewingImage: "Sieht sich ein Bild an",
238
+ stepWritingFile: "Schreibt eine Datei",
239
+ stepWritingCode: "Schreibt Code",
240
+ stepRunningCode: "Führt Code aus",
241
+ stepCheckingApp: "Prüft die App",
242
+ stepCode: "Arbeitet mit Code",
243
+ stepPlan: "Aktualisiert den Arbeitsplan",
244
+ stepPdf: "Erstellt ein PDF",
245
+ stepLoading: "Lädt Werkzeuge und Wissen",
246
+ stepWeb: "Recherchiert im Web",
247
+ stepMemory: "Nutzt das Gedächtnis",
248
+ stepCalculating: "Rechnet",
249
+ stepUsingApp: ({ app }) => `Nutzt ${app}`,
250
+ stepDeliveringFile: "Stellt eine Datei bereit",
251
+ stepPreparingView: "Bereitet eine Ansicht vor",
252
+ stepPreparingCard: "Bereitet eine Karte vor",
253
+ stepCompacting: "Fasst das Gespräch zusammen",
254
+ stepTool: "Nutzt ein Werkzeug",
255
+ stepFailed: "fehlgeschlagen",
256
+ stepRejected: "abgelehnt",
257
+ stepWaiting: "wartet",
258
+ steered: "Richtung geändert",
259
+ reasoning: "Überlegungen",
260
+ groupPlan: "Arbeitsplan aktualisiert",
261
+ groupCode: "Mit Code gearbeitet",
262
+ groupCloud: "Cloud-Integration verwendet",
263
+ groupReadFiles: "Dateien gelesen",
264
+ groupWriteFiles: "Dateien geschrieben",
265
+ groupPdf: "PDFs erstellt",
266
+ groupLoad: "Werkzeuge und Wissen geladen",
267
+ groupWeb: "Im Web recherchiert",
268
+ groupMemory: "Gedächtnis genutzt",
269
+ groupDelivered: "Ergebnisse bereitgestellt",
270
+ groupTools: "Werkzeuge verwendet",
271
+ groupFailed: ({ count }) => `${count} fehlgeschlagen`,
272
+ groupRejected: ({ count }) => `${count} abgelehnt`,
273
+ receiptDone: ({ title }) => `${title} erledigt`,
274
+ receiptApproved: ({ title }) => `Freigegeben: ${title}`,
275
+ approvalNeeded: ({ title }) => `Freigabe nötig: ${title}`,
276
+ answerReady: "Antwort fertig",
277
+ receiptRejected: ({ title }) => `Abgelehnt: ${title}`,
278
+ receiptFailed: ({ title }) => `Fehlgeschlagen: ${title}`,
279
+ receiptNotRun: ({ title, stopped }) => `Nicht ausgeführt: ${title}${stopped ? " · gestoppt" : ""}`,
280
+ workSteps: "Arbeitsschritte",
49
281
  streamLoginRequired: "Deine Sitzung ist abgelaufen. Melde dich erneut an, um diesen Chat fortzusetzen.",
50
282
  streamAccessDenied: "Du hast keinen Zugriff mehr auf diesen Chat.",
51
283
  streamNotFound: "Dieser Chat ist nicht mehr verfügbar.",
284
+ assistant: "Assistent",
285
+ action: "Aktion",
286
+ approvalRequired: ({ title }) => `Freigabe erforderlich: ${title}`,
287
+ reject: "Ablehnen",
288
+ approved: "Freigegeben",
289
+ rejected: "Abgelehnt",
290
+ alwaysApprove: "Immer freigeben",
291
+ details: "Details",
292
+ hideDetails: "Details ausblenden",
293
+ moreOptions: ({ title }) => `Weitere Optionen für ${title}`,
294
+ detailsFor: ({ title }) => `Details zu ${title}`,
295
+ linksFor: ({ title }) => `Links zu ${title}`,
296
+ contentOf: ({ label }) => `Inhalt von ${label}`,
297
+ approvalUnavailable: "Freigabe nicht verfügbar",
298
+ approvalFailed: "Senden fehlgeschlagen. Versuche es erneut.",
299
+ submitting: "Wird gesendet",
300
+ submitted: "Gesendet",
301
+ stoppingResponse: "Antwort wird angehalten",
302
+ openIn: ({ app }) => `In ${app} öffnen`,
303
+ editIn: ({ app }) => `In ${app} bearbeiten`,
304
+ statusIn: ({ app }) => `Status in ${app} ansehen`,
305
+ preview: "Vorschau",
306
+ download: "Herunterladen",
307
+ open: "Öffnen",
308
+ edit: "Bearbeiten",
309
+ toolFailed: ({ title }) => `${title} fehlgeschlagen`,
310
+ toolRejected: ({ title }) => `${title} abgelehnt`,
311
+ actionNotCompleted: "Die Aktion konnte nicht abgeschlossen werden.",
312
+ input: "Eingabe",
313
+ response: "Antwort",
314
+ output: "Ausgabe",
315
+ toolInputOutput: "Werkzeug-Eingabe und -Ausgabe",
316
+ waiting: "Wartet",
317
+ failed: "Fehlgeschlagen",
318
+ conversationSteered: "Gesprächsrichtung angepasst",
319
+ compacting: "Kontext wird verdichtet",
320
+ compacted: "Kontext verdichtet",
321
+ compactionSkipped: "Nichts zu verdichten",
322
+ compactionFailed: "Verdichtung fehlgeschlagen",
323
+ showCompaction: "Verdichtung anzeigen",
324
+ compactionSummary: "Älterer Chatverlauf wurde zu einer kompakten Zusammenfassung verdichtet.",
325
+ before: "Vorher",
326
+ after: "Nachher",
327
+ textEditor: "Texteditor",
328
+ preparingTextEditor: "Texteditor wird vorbereitet",
329
+ memory: "Personalisierung",
330
+ usingMemory: "Personalisierung wird verwendet",
331
+ memoryNotUpdated: "Personalisierung nicht aktualisiert",
332
+ remembered: "Gemerkt",
333
+ memoryUpdated: "Personalisierung aktualisiert",
334
+ memoryForgotten: "Aus der Personalisierung entfernt",
335
+ memoriesSearched: "Personalisierung durchsucht",
336
+ memoriesListed: "Personalisierung angezeigt",
337
+ fileDownloadFailed: "Datei konnte nicht geladen werden",
338
+ fileNotImported: "Die verlinkte Datei konnte nicht in diesen Chat übernommen werden.",
339
+ tools: "Werkzeuge",
340
+ searchTools: ({ query }) => `Werkzeuge suchen: ${query}`,
341
+ found: ({ count, more }) => `${count}${more ? "+" : ""} gefunden`,
342
+ noTools: "Keine Werkzeuge gefunden.",
343
+ listApps: "Apps auflisten",
344
+ available: ({ count }) => `${count} verfügbar`,
345
+ noApps: "Keine Apps mit Capabilities verfügbar.",
346
+ loadTools: "Werkzeuge laden",
347
+ loadedCount: ({ count }) => `${count} geladen`,
348
+ toolsLoaded: "Geladen",
349
+ toolsAlreadyLoaded: "Bereits geladen",
350
+ toolsMissing: "Nicht gefunden",
351
+ toolsEvicted: "Entladen",
352
+ loadedSkill: ({ name }) => `Skill ${name} geladen`,
353
+ help: "Hilfe",
354
+ searchHelp: ({ query }) => `Hilfe durchsuchen: ${query}`,
355
+ noHelp: "Keine Hilfeartikel gefunden.",
356
+ readHelp: "Hilfe lesen",
357
+ readHelpArticle: ({ title }) => `Hilfe lesen: ${title}`,
358
+ articleNotFound: "Artikel nicht gefunden",
359
+ searchProject: ({ query }) => `Projekt durchsuchen: ${query}`,
360
+ listProjectSources: "Projektquellen auflisten",
361
+ noProjectSources: "Keine Projektquellen gefunden.",
362
+ projectEntry: "Eintrag",
363
+ readProjectKnowledge: ({ title }) => `Projektwissen lesen: ${title}`,
364
+ listFiles: ({ path }) => `Dateien auflisten: ${path}`,
365
+ noFiles: "Keine Dateien gefunden.",
366
+ file: "Datei",
367
+ wroteFile: "Datei geschrieben",
368
+ readFile: ({ name }) => `Datei lesen: ${name}`,
369
+ fileComplete: "vollständig",
370
+ fileMoreAvailable: "weitere verfügbar",
371
+ calculate: "Berechnen",
372
+ inspectImage: ({ name }) => `Bild prüfen: ${name}`,
373
+ readResource: ({ ref }) => `Ressource lesen: ${ref}`,
52
374
  },
53
375
  },
54
376
  });