docker-client-mx 1.35.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 (148) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +233 -0
  3. package/bin/docker-client-mx.js +42 -0
  4. package/build/icons/icon-1024.png +0 -0
  5. package/build/icons/icon-128.png +0 -0
  6. package/build/icons/icon-16.png +0 -0
  7. package/build/icons/icon-256.png +0 -0
  8. package/build/icons/icon-32.png +0 -0
  9. package/build/icons/icon-48.png +0 -0
  10. package/build/icons/icon-512.png +0 -0
  11. package/build/icons/icon-64.png +0 -0
  12. package/build/icons/icon.ico +0 -0
  13. package/build/icons/icon.iconset/icon_128x128.png +0 -0
  14. package/build/icons/icon.iconset/icon_128x128@2x.png +0 -0
  15. package/build/icons/icon.iconset/icon_16x16.png +0 -0
  16. package/build/icons/icon.iconset/icon_16x16@2x.png +0 -0
  17. package/build/icons/icon.iconset/icon_256x256.png +0 -0
  18. package/build/icons/icon.iconset/icon_256x256@2x.png +0 -0
  19. package/build/icons/icon.iconset/icon_32x32.png +0 -0
  20. package/build/icons/icon.iconset/icon_32x32@2x.png +0 -0
  21. package/build/icons/icon.iconset/icon_512x512.png +0 -0
  22. package/build/icons/icon.iconset/icon_512x512@2x.png +0 -0
  23. package/build/icons/icon.png +0 -0
  24. package/dist/docker-desktop-mx/browser/chunk-64WWLMUP.js +39 -0
  25. package/dist/docker-desktop-mx/browser/chunk-N4VBBC4W.js +1 -0
  26. package/dist/docker-desktop-mx/browser/favicon.ico +0 -0
  27. package/dist/docker-desktop-mx/browser/index.html +14 -0
  28. package/dist/docker-desktop-mx/browser/main-CTIRTSOI.js +5 -0
  29. package/dist/docker-desktop-mx/browser/styles-JS3HDDI4.css +1 -0
  30. package/dist-electron/api.js +10 -0
  31. package/dist-electron/api.js.map +1 -0
  32. package/dist-electron/assistant-key.js +70 -0
  33. package/dist-electron/assistant-key.js.map +1 -0
  34. package/dist-electron/assistant-models.js +19 -0
  35. package/dist-electron/assistant-models.js.map +1 -0
  36. package/dist-electron/assistant-tools.js +335 -0
  37. package/dist-electron/assistant-tools.js.map +1 -0
  38. package/dist-electron/assistant.js +302 -0
  39. package/dist-electron/assistant.js.map +1 -0
  40. package/dist-electron/attention.js +75 -0
  41. package/dist-electron/attention.js.map +1 -0
  42. package/dist-electron/channels.js +113 -0
  43. package/dist-electron/channels.js.map +1 -0
  44. package/dist-electron/compose-files.js +104 -0
  45. package/dist-electron/compose-files.js.map +1 -0
  46. package/dist-electron/compose.js +271 -0
  47. package/dist-electron/compose.js.map +1 -0
  48. package/dist-electron/container-events.js +188 -0
  49. package/dist-electron/container-events.js.map +1 -0
  50. package/dist-electron/containers.js +165 -0
  51. package/dist-electron/containers.js.map +1 -0
  52. package/dist-electron/context-menu.js +56 -0
  53. package/dist-electron/context-menu.js.map +1 -0
  54. package/dist-electron/contexts.js +346 -0
  55. package/dist-electron/contexts.js.map +1 -0
  56. package/dist-electron/crash.js +129 -0
  57. package/dist-electron/crash.js.map +1 -0
  58. package/dist-electron/diagnosis.js +338 -0
  59. package/dist-electron/diagnosis.js.map +1 -0
  60. package/dist-electron/docker-client.js +284 -0
  61. package/dist-electron/docker-client.js.map +1 -0
  62. package/dist-electron/engine.js +145 -0
  63. package/dist-electron/engine.js.map +1 -0
  64. package/dist-electron/event-store.js +146 -0
  65. package/dist-electron/event-store.js.map +1 -0
  66. package/dist-electron/events.js +132 -0
  67. package/dist-electron/events.js.map +1 -0
  68. package/dist-electron/exec.js +138 -0
  69. package/dist-electron/exec.js.map +1 -0
  70. package/dist-electron/files.js +407 -0
  71. package/dist-electron/files.js.map +1 -0
  72. package/dist-electron/health.js +92 -0
  73. package/dist-electron/health.js.map +1 -0
  74. package/dist-electron/host-overview.js +50 -0
  75. package/dist-electron/host-overview.js.map +1 -0
  76. package/dist-electron/host-shell.js +196 -0
  77. package/dist-electron/host-shell.js.map +1 -0
  78. package/dist-electron/i18n.js +58 -0
  79. package/dist-electron/i18n.js.map +1 -0
  80. package/dist-electron/image-history.js +87 -0
  81. package/dist-electron/image-history.js.map +1 -0
  82. package/dist-electron/images.js +141 -0
  83. package/dist-electron/images.js.map +1 -0
  84. package/dist-electron/ipc.js +783 -0
  85. package/dist-electron/ipc.js.map +1 -0
  86. package/dist-electron/links.js +46 -0
  87. package/dist-electron/links.js.map +1 -0
  88. package/dist-electron/logs.js +153 -0
  89. package/dist-electron/logs.js.map +1 -0
  90. package/dist-electron/main.js +494 -0
  91. package/dist-electron/main.js.map +1 -0
  92. package/dist-electron/merged-logs.js +127 -0
  93. package/dist-electron/merged-logs.js.map +1 -0
  94. package/dist-electron/navigation.js +37 -0
  95. package/dist-electron/navigation.js.map +1 -0
  96. package/dist-electron/ndjson.js +30 -0
  97. package/dist-electron/ndjson.js.map +1 -0
  98. package/dist-electron/networks.js +507 -0
  99. package/dist-electron/networks.js.map +1 -0
  100. package/dist-electron/port-conflicts.js +106 -0
  101. package/dist-electron/port-conflicts.js.map +1 -0
  102. package/dist-electron/preload.js +257 -0
  103. package/dist-electron/preload.js.map +1 -0
  104. package/dist-electron/pull.js +220 -0
  105. package/dist-electron/pull.js.map +1 -0
  106. package/dist-electron/redact.js +129 -0
  107. package/dist-electron/redact.js.map +1 -0
  108. package/dist-electron/registry-auth.js +150 -0
  109. package/dist-electron/registry-auth.js.map +1 -0
  110. package/dist-electron/renew.js +162 -0
  111. package/dist-electron/renew.js.map +1 -0
  112. package/dist-electron/restart-policy.js +58 -0
  113. package/dist-electron/restart-policy.js.map +1 -0
  114. package/dist-electron/run-command.js +146 -0
  115. package/dist-electron/run-command.js.map +1 -0
  116. package/dist-electron/run.js +151 -0
  117. package/dist-electron/run.js.map +1 -0
  118. package/dist-electron/self-update.js +163 -0
  119. package/dist-electron/self-update.js.map +1 -0
  120. package/dist-electron/servers.js +108 -0
  121. package/dist-electron/servers.js.map +1 -0
  122. package/dist-electron/settings.js +146 -0
  123. package/dist-electron/settings.js.map +1 -0
  124. package/dist-electron/ssh.js +574 -0
  125. package/dist-electron/ssh.js.map +1 -0
  126. package/dist-electron/stats.js +209 -0
  127. package/dist-electron/stats.js.map +1 -0
  128. package/dist-electron/streams.js +63 -0
  129. package/dist-electron/streams.js.map +1 -0
  130. package/dist-electron/system.js +123 -0
  131. package/dist-electron/system.js.map +1 -0
  132. package/dist-electron/terminal-transcript.js +55 -0
  133. package/dist-electron/terminal-transcript.js.map +1 -0
  134. package/dist-electron/updates.js +136 -0
  135. package/dist-electron/updates.js.map +1 -0
  136. package/dist-electron/volume-backup.js +203 -0
  137. package/dist-electron/volume-backup.js.map +1 -0
  138. package/dist-electron/volume-files.js +124 -0
  139. package/dist-electron/volume-files.js.map +1 -0
  140. package/dist-electron/volumes.js +253 -0
  141. package/dist-electron/volumes.js.map +1 -0
  142. package/dist-electron/wiring-watch.js +93 -0
  143. package/dist-electron/wiring-watch.js.map +1 -0
  144. package/dist-electron/wiring.js +71 -0
  145. package/dist-electron/wiring.js.map +1 -0
  146. package/dist-electron/wsl.js +167 -0
  147. package/dist-electron/wsl.js.map +1 -0
  148. package/package.json +125 -0
@@ -0,0 +1,209 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StatsWatcher = void 0;
4
+ exports.toCpuPercent = toCpuPercent;
5
+ exports.toMemoryBytes = toMemoryBytes;
6
+ exports.toNetworkCounters = toNetworkCounters;
7
+ exports.toNetworkRate = toNetworkRate;
8
+ exports.toContainerStats = toContainerStats;
9
+ const channels_1 = require("./channels");
10
+ const docker_client_1 = require("./docker-client");
11
+ const ndjson_1 = require("./ndjson");
12
+ /**
13
+ * Docker geeft cumulatieve tikken, geen percentage. Het percentage is het aandeel van de
14
+ * containertijd in de systeemtijd sinds de vorige meting, maal het aantal kernen — zo komt
15
+ * een container die twee kernen vol belast op 200% uit, net als in `docker stats`.
16
+ *
17
+ * Het eerste frame van een stream heeft precpu_stats op nul. Beide delta's zijn dan gewoon
18
+ * positief — het zijn de totalen sinds het opstarten — dus daar valt niet aan te zien dat er
19
+ * geen ijkpunt is; je krijgt een getal dat er plausibel uitziet en nergens op slaat. Vandaar
20
+ * dat we op precpu's systeemtijd zelf controleren en niet op de delta. `docker stats` slaat
21
+ * datzelfde eerste frame over.
22
+ */
23
+ function toCpuPercent(raw) {
24
+ const cpu = raw.cpu_stats;
25
+ const pre = raw.precpu_stats;
26
+ const previousSystem = pre?.system_cpu_usage ?? 0;
27
+ if (previousSystem <= 0) {
28
+ return 0;
29
+ }
30
+ const cpuDelta = (cpu?.cpu_usage?.total_usage ?? 0) - (pre?.cpu_usage?.total_usage ?? 0);
31
+ const systemDelta = (cpu?.system_cpu_usage ?? 0) - previousSystem;
32
+ if (cpuDelta <= 0 || systemDelta <= 0) {
33
+ return 0;
34
+ }
35
+ const cores = cpu?.online_cpus ?? cpu?.cpu_usage?.percpu_usage?.length ?? 1;
36
+ return (cpuDelta / systemDelta) * cores * 100;
37
+ }
38
+ /**
39
+ * `usage` telt de paginacache mee, en die kan een rustige container tientallen megabytes
40
+ * zwaarder laten lijken dan hij is. Docker trekt hem eraf: op cgroup v2 heet dat veld
41
+ * `inactive_file`, op v1 `cache`.
42
+ */
43
+ function toMemoryBytes(raw) {
44
+ const memory = raw.memory_stats;
45
+ const usage = memory?.usage ?? 0;
46
+ const cache = memory?.stats?.['inactive_file'] ?? memory?.stats?.['cache'] ?? 0;
47
+ return { used: Math.max(0, usage - cache), limit: memory?.limit ?? 0 };
48
+ }
49
+ const NO_TRAFFIC = { rxBytesPerSec: 0, txBytesPerSec: 0 };
50
+ /**
51
+ * De tellers uit een meting, opgeteld over alle interfaces, of `null` als er geen zijn.
52
+ *
53
+ * De tijd komt uit `read` en niet uit de klok hier: metingen kunnen vertraagd binnenkomen, en
54
+ * dan klopt de deling alleen met de tijd waarop Docker ze nam. `Date.parse` rondt de
55
+ * nanoseconden af op milliseconden; ruim genoeg bij een meting per seconde.
56
+ */
57
+ function toNetworkCounters(raw, fallbackNow = Date.now()) {
58
+ const interfaces = Object.values(raw.networks ?? {});
59
+ if (interfaces.length === 0) {
60
+ return null;
61
+ }
62
+ const parsed = raw.read === undefined ? Number.NaN : Date.parse(raw.read);
63
+ return {
64
+ t: Number.isFinite(parsed) ? parsed : fallbackNow,
65
+ rx: interfaces.reduce((total, entry) => total + (entry.rx_bytes ?? 0), 0),
66
+ tx: interfaces.reduce((total, entry) => total + (entry.tx_bytes ?? 0), 0),
67
+ };
68
+ }
69
+ /**
70
+ * Van twee standen van de tellers naar bytes per seconde.
71
+ *
72
+ * Docker geeft totalen, geen snelheid, en in tegenstelling tot de CPU zit de vorige stand er
73
+ * niet bij; die bewaart de watcher. Een teller die terugloopt is een herstarte container, geen
74
+ * negatief verkeer: dan tellen we die meting als nul in plaats van een diepe kuil te tekenen.
75
+ */
76
+ function toNetworkRate(previous, next) {
77
+ if (previous === undefined || next === null) {
78
+ return NO_TRAFFIC;
79
+ }
80
+ const seconds = (next.t - previous.t) / 1000;
81
+ if (seconds <= 0) {
82
+ return NO_TRAFFIC;
83
+ }
84
+ const rx = next.rx - previous.rx;
85
+ const tx = next.tx - previous.tx;
86
+ return {
87
+ rxBytesPerSec: rx < 0 ? 0 : rx / seconds,
88
+ txBytesPerSec: tx < 0 ? 0 : tx / seconds,
89
+ };
90
+ }
91
+ /** Eén meting zoals de renderer hem krijgt. */
92
+ function toContainerStats(id, raw, network = NO_TRAFFIC) {
93
+ const memory = toMemoryBytes(raw);
94
+ return { id, cpuPercent: toCpuPercent(raw), memoryBytes: memory.used, memoryLimitBytes: memory.limit, ...network };
95
+ }
96
+ const EMIT_INTERVAL_MS = 1000;
97
+ async function openViaDocker(id, onSample) {
98
+ const { docker } = (0, docker_client_1.getConnection)();
99
+ const stream = (await docker.getContainer(id).stats({ stream: true }));
100
+ const feed = (0, ndjson_1.ndjson)((value) => onSample(value));
101
+ stream.on('data', feed);
102
+ // Een stream valt weg als de container stopt. Dat is geen fout om te melden: de
103
+ // events-stream ververst de lijst en watch() sluit hem daarna netjes af.
104
+ stream.on('error', () => undefined);
105
+ return stream;
106
+ }
107
+ /**
108
+ * Houdt één stats-stream per container aan, precies voor de containers die in beeld zijn, en
109
+ * stuurt hooguit één keer per seconde een bundel naar het venster. Vaker heeft geen zin: dan
110
+ * flikkeren alleen de cijfers.
111
+ */
112
+ class StatsWatcher {
113
+ sender;
114
+ open;
115
+ streams = new Map();
116
+ latest = new Map();
117
+ /** De vorige stand van de netwerktellers per container; Docker geeft die niet mee. */
118
+ counters = new Map();
119
+ opening = new Set();
120
+ wanted = new Set();
121
+ timer = null;
122
+ stopped = false;
123
+ constructor(sender, open = openViaDocker) {
124
+ this.sender = sender;
125
+ this.open = open;
126
+ }
127
+ /** Laat de open streams overeenkomen met `ids`. Een lege lijst zet alles stil. */
128
+ async watch(ids) {
129
+ if (this.stopped) {
130
+ return;
131
+ }
132
+ this.wanted = new Set(ids);
133
+ this.closeUnwanted();
134
+ const toOpen = [...this.wanted].filter((id) => !this.streams.has(id) && !this.opening.has(id));
135
+ await Promise.all(toOpen.map((id) => this.openOne(id)));
136
+ this.syncTimer();
137
+ }
138
+ /** Alles dicht. Wordt aangeroepen als het venster verdwijnt. */
139
+ stop() {
140
+ this.stopped = true;
141
+ this.wanted = new Set();
142
+ this.closeUnwanted();
143
+ this.syncTimer();
144
+ }
145
+ async openOne(id) {
146
+ this.opening.add(id);
147
+ try {
148
+ const stream = await this.open(id, (raw) => this.record(id, raw));
149
+ // Tijdens het openen kan er alweer een watch() geweest zijn die deze container niet
150
+ // meer wil, of is het venster gesloten. Dan meteen weer dicht.
151
+ if (this.stopped || !this.wanted.has(id)) {
152
+ stream.destroy();
153
+ return;
154
+ }
155
+ this.streams.set(id, stream);
156
+ }
157
+ catch {
158
+ // De container is net weg of start nog op; de events-stream ververst de lijst wel.
159
+ }
160
+ finally {
161
+ this.opening.delete(id);
162
+ }
163
+ }
164
+ record(id, raw) {
165
+ const counters = toNetworkCounters(raw);
166
+ const rate = toNetworkRate(this.counters.get(id), counters);
167
+ if (counters === null) {
168
+ this.counters.delete(id);
169
+ }
170
+ else {
171
+ this.counters.set(id, counters);
172
+ }
173
+ this.latest.set(id, toContainerStats(id, raw, rate));
174
+ }
175
+ closeUnwanted() {
176
+ for (const [id, stream] of this.streams) {
177
+ if (!this.wanted.has(id)) {
178
+ stream.destroy();
179
+ this.streams.delete(id);
180
+ this.latest.delete(id);
181
+ this.counters.delete(id);
182
+ }
183
+ }
184
+ }
185
+ syncTimer() {
186
+ const shouldRun = !this.stopped && this.wanted.size > 0;
187
+ if (shouldRun && this.timer === null) {
188
+ this.timer = setInterval(() => this.emit(), EMIT_INTERVAL_MS);
189
+ // Een meetlus hoort het afsluiten van de app niet tegen te houden.
190
+ this.timer.unref();
191
+ }
192
+ if (!shouldRun && this.timer !== null) {
193
+ clearInterval(this.timer);
194
+ this.timer = null;
195
+ }
196
+ }
197
+ emit() {
198
+ if (this.sender.isDestroyed()) {
199
+ this.stop();
200
+ return;
201
+ }
202
+ const samples = [...this.latest.values()];
203
+ if (samples.length > 0) {
204
+ this.sender.send(channels_1.CHANNELS.containersStats, samples);
205
+ }
206
+ }
207
+ }
208
+ exports.StatsWatcher = StatsWatcher;
209
+ //# sourceMappingURL=stats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.js","sourceRoot":"","sources":["../electron/stats.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StreamRegistry = void 0;
4
+ /**
5
+ * De teller staat buiten de klasse, zodat ids uniek zijn over álle vensters heen. Per venster
6
+ * tellen zou 'exec-1' twee keer kunnen opleveren, en modules die hun sessie op dat id bijhouden
7
+ * — zoals exec.ts — zouden elkaars sessie overschrijven.
8
+ */
9
+ let nextId = 0;
10
+ class StreamRegistry {
11
+ sender;
12
+ open = new Map();
13
+ /** Ids die uitgegeven zijn maar waar nog geen stream bij hoort. */
14
+ reserved = new Set();
15
+ stopped = false;
16
+ constructor(sender) {
17
+ this.sender = sender;
18
+ }
19
+ /** Geeft een id uit voor een stream die nog opgezet wordt. */
20
+ reserve(prefix) {
21
+ nextId += 1;
22
+ const id = `${prefix}-${String(nextId)}`;
23
+ this.reserved.add(id);
24
+ return id;
25
+ }
26
+ /**
27
+ * Hangt de stream aan een eerder uitgegeven id. Is die intussen gesloten, dan gaat de
28
+ * stream meteen weer dicht en komt hij niet in de boekhouding.
29
+ */
30
+ attach(id, stream) {
31
+ if (this.stopped || !this.reserved.delete(id)) {
32
+ stream.destroy();
33
+ return;
34
+ }
35
+ this.open.set(id, stream);
36
+ }
37
+ /** Stuurt iets naar het venster, tenzij dat er niet meer is. */
38
+ send(channel, payload) {
39
+ if (this.stopped || this.sender.isDestroyed()) {
40
+ return;
41
+ }
42
+ this.sender.send(channel, payload);
43
+ }
44
+ close(id) {
45
+ this.reserved.delete(id);
46
+ this.open.get(id)?.destroy();
47
+ this.open.delete(id);
48
+ }
49
+ /** Alles dicht. Wordt aangeroepen als het venster verdwijnt. */
50
+ closeAll() {
51
+ this.stopped = true;
52
+ this.reserved.clear();
53
+ for (const stream of this.open.values()) {
54
+ stream.destroy();
55
+ }
56
+ this.open.clear();
57
+ }
58
+ get openCount() {
59
+ return this.open.size;
60
+ }
61
+ }
62
+ exports.StreamRegistry = StreamRegistry;
63
+ //# sourceMappingURL=streams.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streams.js","sourceRoot":"","sources":["../electron/streams.ts"],"names":[],"mappings":";;;AAqBA;;;;GAIG;AACH,IAAI,MAAM,GAAG,CAAC,CAAC;AAEf,MAAa,cAAc;IAOI;IALZ,IAAI,GAAG,IAAI,GAAG,EAAoB,CAAC;IACpD,mEAAmE;IAClD,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IACtC,OAAO,GAAG,KAAK,CAAC;IAExB,YAA6B,MAAoB;QAApB,WAAM,GAAN,MAAM,CAAc;IAAG,CAAC;IAErD,8DAA8D;IAC9D,OAAO,CAAC,MAAc;QAEpB,MAAM,IAAI,CAAC,CAAC;QAEZ,MAAM,EAAE,GAAG,GAAG,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAEzC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEtB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,EAAU,EAAE,MAAgB;QAEjC,IAAI,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;YAC9C,MAAM,CAAC,OAAO,EAAE,CAAC;YAEjB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IAC5B,CAAC;IAED,gEAAgE;IAChE,IAAI,CAAC,OAAe,EAAE,OAAgB;QAEpC,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC;YAC9C,OAAO;QACT,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,EAAU;QAEd,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACvB,CAAC;IAED,gEAAgE;IAChE,QAAQ;QAEN,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QAEtB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;YACxC,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;IACpB,CAAC;IAED,IAAI,SAAS;QAEX,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IACxB,CAAC;CACF;AAtED,wCAsEC"}
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PRUNE_ORDER = void 0;
4
+ exports.toDiskUsage = toDiskUsage;
5
+ exports.readDiskUsage = readDiskUsage;
6
+ exports.pruneBuildCache = pruneBuildCache;
7
+ exports.runPrunes = runPrunes;
8
+ exports.pruneSystem = pruneSystem;
9
+ const containers_1 = require("./containers");
10
+ const docker_client_1 = require("./docker-client");
11
+ const images_1 = require("./images");
12
+ const networks_1 = require("./networks");
13
+ const volumes_1 = require("./volumes");
14
+ const i18n_1 = require("./i18n");
15
+ function sum(values) {
16
+ return values.reduce((total, value) => total + value, 0);
17
+ }
18
+ function entry(kind, total, active, sizeBytes) {
19
+ return { kind, total, active, sizeBytes };
20
+ }
21
+ /**
22
+ * Vertaalt `/system/df` naar wat het dashboard toont.
23
+ *
24
+ * De groottes komen exact overeen met `docker system df`, en dat is geen toeval: voor images
25
+ * gebruiken we `LayersSize` en niet de som van de losse `Size`-velden. Die som telt gedeelde
26
+ * lagen bij elke image opnieuw mee en komt daardoor te hoog uit — hier 2,54 GB tegen de 2,47 GB
27
+ * die er werkelijk op schijf staat.
28
+ *
29
+ * Wat we bewust *niet* tonen is Docker's "RECLAIMABLE". Dat getal verrekent gedeelde lagen
30
+ * tussen images en build-cache-entries, en dat exact nabouwen is een eigen project. Een
31
+ * benadering van vrij te maken schijfruimte als feit presenteren is erger dan hem weglaten;
32
+ * het aantal ongebruikte items klopt wél, en dat is waar je op handelt.
33
+ */
34
+ function toDiskUsage(raw) {
35
+ const images = raw.Images ?? [];
36
+ const containers = raw.Containers ?? [];
37
+ const volumes = raw.Volumes ?? [];
38
+ const buildCache = raw.BuildCache ?? [];
39
+ const entries = [
40
+ entry('images', images.length, images.filter((image) => (image.Containers ?? 0) > 0).length, raw.LayersSize ?? 0),
41
+ entry('containers', containers.length, containers.filter((container) => container.State === 'running').length, sum(containers.map((container) => container.SizeRw ?? 0))),
42
+ entry('volumes', volumes.length, volumes.filter((volume) => (volume.UsageData?.RefCount ?? 0) > 0).length, sum(volumes.map((volume) => volume.UsageData?.Size ?? 0))),
43
+ entry('buildCache', buildCache.length, buildCache.filter((item) => item.InUse === true).length, sum(buildCache.map((item) => item.Size ?? 0))),
44
+ ];
45
+ return { entries, totalBytes: sum(entries.map((item) => item.sizeBytes)) };
46
+ }
47
+ /**
48
+ * Het schijfgebruik. Apart van alle lijsten omdat `/system/df` de hele opslag doorloopt en bij
49
+ * veel images seconden kan duren; het dashboard toont de rest al terwijl dit nog binnenkomt.
50
+ */
51
+ async function readDiskUsage() {
52
+ const { docker } = (0, docker_client_1.getConnection)();
53
+ return toDiskUsage((await docker.df()));
54
+ }
55
+ /**
56
+ * Gooit alle build cache weg die niet in gebruik is, zoals `docker builder prune -a`.
57
+ *
58
+ * Via de modem en niet via dockerode's `pruneBuilder()`: die stuurt zijn opties niet mee, en
59
+ * zonder `all` laat de daemon cache staan die `/system/df` wel als ongebruikt telt. Dan ruimt
60
+ * de dialoog minder op dan hij aankondigde.
61
+ */
62
+ async function pruneBuildCache() {
63
+ const { docker } = (0, docker_client_1.getConnection)();
64
+ try {
65
+ const raw = await new Promise((resolve, reject) => {
66
+ docker.modem.dial({ path: '/build/prune?', method: 'POST', options: { all: true }, statusCodes: { 200: true, 500: 'server error' } }, (err, data) => {
67
+ if (err !== null) {
68
+ reject(err);
69
+ }
70
+ else {
71
+ resolve(data ?? {});
72
+ }
73
+ });
74
+ });
75
+ return { ok: true, removed: raw.CachesDeleted?.length ?? 0, reclaimedBytes: raw.SpaceReclaimed ?? 0 };
76
+ }
77
+ catch (err) {
78
+ const reason = err instanceof Error ? err.message : String(err);
79
+ return { ok: false, problem: (0, i18n_1.t)({
80
+ en: `Prune failed: ${reason}`,
81
+ nl: `Opruimen mislukte: ${reason}`,
82
+ de: `Aufräumen fehlgeschlagen: ${reason}`,
83
+ fr: `Le nettoyage a échoué : ${reason}`,
84
+ es: `La limpieza ha fallado: ${reason}`,
85
+ }) };
86
+ }
87
+ }
88
+ /**
89
+ * De volgorde waarin opgeruimd wordt. Containers eerst: pas als die weg zijn, hangt er niets
90
+ * meer aan hun netwerken, volumes en images, en zou een andere volgorde die laten staan.
91
+ */
92
+ exports.PRUNE_ORDER = ['containers', 'networks', 'volumes', 'images', 'buildCache'];
93
+ /**
94
+ * Draait de gekozen stappen achter elkaar, in `PRUNE_ORDER`.
95
+ *
96
+ * Achter elkaar en niet tegelijk, om de reden hierboven. Een stap die mislukt geeft `ok: false`
97
+ * terug en de volgende gaat gewoon door: dat de volumes niet lukten is geen reden om de build
98
+ * cache te laten staan. Een stap die toch gooit, vangen we hier alsnog af.
99
+ */
100
+ async function runPrunes(selection, steps) {
101
+ const entries = [];
102
+ for (const kind of exports.PRUNE_ORDER.filter((candidate) => selection[candidate])) {
103
+ try {
104
+ entries.push({ kind, result: await steps[kind]() });
105
+ }
106
+ catch (err) {
107
+ entries.push({ kind, result: { ok: false, problem: err instanceof Error ? err.message : String(err) } });
108
+ }
109
+ }
110
+ return entries;
111
+ }
112
+ /** Ruimt op wat er in de dialoog is aangevinkt. */
113
+ function pruneSystem(selection) {
114
+ return runPrunes(selection, {
115
+ containers: containers_1.pruneContainers,
116
+ networks: networks_1.pruneNetworks,
117
+ // Alleen anonieme volumes: een volume met een naam heb je bewust aangemaakt.
118
+ volumes: () => (0, volumes_1.pruneVolumes)(false),
119
+ images: () => (0, images_1.pruneImages)(selection.allImages),
120
+ buildCache: pruneBuildCache,
121
+ });
122
+ }
123
+ //# sourceMappingURL=system.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system.js","sourceRoot":"","sources":["../electron/system.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TerminalTranscript = void 0;
4
+ const logs_1 = require("./logs");
5
+ const redact_1 = require("./redact");
6
+ /** Zoveel ruwe uitvoer bewaren we. Ruim een paar schermen, en een vaste bovengrens. */
7
+ const MAX_BYTES = 64 * 1024;
8
+ /**
9
+ * Wat de host-shell heeft laten zien, zodat Claude kan meelezen.
10
+ *
11
+ * Main ziet alle uitvoer al langskomen op weg naar xterm; hier bewaren we het staartje. Het
12
+ * wordt pas tekst als Claude erom vraagt: kleurcodes eruit, een regel die met `\r` werd
13
+ * overschreven alleen in zijn laatste vorm, en geheimen weggelaten zoals overal elders.
14
+ */
15
+ class TerminalTranscript {
16
+ raw = '';
17
+ append(chunk) {
18
+ this.raw += chunk;
19
+ if (this.raw.length > MAX_BYTES) {
20
+ this.raw = this.raw.slice(-MAX_BYTES);
21
+ }
22
+ }
23
+ /** De laatste regels als leesbare tekst, zonder geheimen. */
24
+ lines(count) {
25
+ const text = (0, logs_1.stripAnsi)(this.raw.replace(/\r\n/g, '\n'))
26
+ .split('\n')
27
+ .map(settleLine)
28
+ .join('\n')
29
+ .trimEnd();
30
+ return (0, redact_1.redactText)(text.split('\n').slice(-count).join('\n')).text;
31
+ }
32
+ }
33
+ exports.TerminalTranscript = TerminalTranscript;
34
+ /**
35
+ * Een regel zoals hij op het scherm stond: na een losse `\r` begint de cursor weer vooraan,
36
+ * en een backspace haalt het teken ervoor weg. Meer terminal-emulatie is niet nodig om te
37
+ * lezen wat er stond.
38
+ */
39
+ function settleLine(line) {
40
+ let result = '';
41
+ for (const part of line.split('\r')) {
42
+ result = part.length >= result.length ? part : part + result.slice(part.length);
43
+ }
44
+ let settled = '';
45
+ for (const char of result) {
46
+ if (char === '\b') {
47
+ settled = settled.slice(0, -1);
48
+ }
49
+ else if (char >= ' ' || char === '\t') {
50
+ settled += char;
51
+ }
52
+ }
53
+ return settled.trimEnd();
54
+ }
55
+ //# sourceMappingURL=terminal-transcript.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-transcript.js","sourceRoot":"","sources":["../electron/terminal-transcript.ts"],"names":[],"mappings":";;;AAAA,iCAAmC;AACnC,qCAAsC;AAEtC,uFAAuF;AACvF,MAAM,SAAS,GAAG,EAAE,GAAG,IAAI,CAAC;AAE5B;;;;;;GAMG;AACH,MAAa,kBAAkB;IAErB,GAAG,GAAG,EAAE,CAAC;IAEjB,MAAM,CAAC,KAAa;QAElB,IAAI,CAAC,GAAG,IAAI,KAAK,CAAC;QAElB,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,SAAS,EAAE,CAAC;YAChC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAED,6DAA6D;IAC7D,KAAK,CAAC,KAAa;QAEjB,MAAM,IAAI,GAAG,IAAA,gBAAS,EAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;aACpD,KAAK,CAAC,IAAI,CAAC;aACX,GAAG,CAAC,UAAU,CAAC;aACf,IAAI,CAAC,IAAI,CAAC;aACV,OAAO,EAAE,CAAC;QAEb,OAAO,IAAA,mBAAU,EAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACpE,CAAC;CACF;AAxBD,gDAwBC;AAED;;;;GAIG;AACH,SAAS,UAAU,CAAC,IAAY;IAE9B,IAAI,MAAM,GAAG,EAAE,CAAC;IAEhB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAClF,CAAC;IAED,IAAI,OAAO,GAAG,EAAE,CAAC;IAEjB,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAC1B,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAClB,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACjC,CAAC;aAAM,IAAI,IAAI,IAAI,GAAG,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YACxC,OAAO,IAAI,IAAI,CAAC;QAClB,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.clearUpdateCache = clearUpdateCache;
4
+ exports.toLocalTags = toLocalTags;
5
+ exports.classifyFailure = classifyFailure;
6
+ exports.checkTags = checkTags;
7
+ exports.checkImageUpdates = checkImageUpdates;
8
+ const docker_client_1 = require("./docker-client");
9
+ const registry_auth_1 = require("./registry-auth");
10
+ const i18n_1 = require("./i18n");
11
+ /**
12
+ * Of er van een image een nieuwere versie in de registry staat.
13
+ *
14
+ * De daemon vraagt het de registry zelf, via `/distribution/<naam>/json`: met zijn eigen
15
+ * proxy- en DNS-instellingen, en zonder dat deze app een registry-client hoeft te zijn. Wat
16
+ * terugkomt is de digest van het manifest achter de tag; staat die niet tussen de lokale
17
+ * `RepoDigests`, dan wijst de tag inmiddels naar iets anders.
18
+ *
19
+ * Elke controle is een verzoek aan de registry, en Docker Hub telt die. Daarom alleen als je
20
+ * erom vraagt, een paar tegelijk, en onthouden we de uitkomst een tijdje.
21
+ */
22
+ /** Zo lang geldt een uitkomst. Een tag verschuift niet elke minuut. */
23
+ const CACHE_MS = 10 * 60 * 1000;
24
+ /** Zoveel registry-verzoeken tegelijk. Meer maakt het nauwelijks sneller en de registry niet blijer. */
25
+ const CONCURRENCY = 4;
26
+ const cache = new Map();
27
+ /** Wist wat we wisten. Voor tests, en na een pull: dan klopt het oude antwoord niet meer. */
28
+ function clearUpdateCache(reference) {
29
+ if (reference === undefined) {
30
+ cache.clear();
31
+ }
32
+ else {
33
+ cache.delete(reference);
34
+ }
35
+ }
36
+ /** De lokale tags uit de imagelijst van de daemon, zonder `<none>`. */
37
+ function toLocalTags(images) {
38
+ return images.flatMap((image) => {
39
+ const digests = (image.RepoDigests ?? []).map((entry) => entry.slice(entry.indexOf('@') + 1));
40
+ return (image.RepoTags ?? []).filter((tag) => tag !== '<none>:<none>').map((reference) => ({ reference, digests }));
41
+ });
42
+ }
43
+ /**
44
+ * Een fout van de registry in een uitkomst. 401, 403 en 404 betekenen dat de registry deze
45
+ * naam niet kent of niet aan ons laat zien: lokaal gebouwd, of privé zonder inlog. Dat is geen
46
+ * fout om rood te maken; bij containerd-opslag heeft ook een zelfgebouwde image een digest.
47
+ */
48
+ function classifyFailure(reference, err) {
49
+ const status = err?.statusCode;
50
+ const text = (err instanceof Error ? err.message : String(err)).toLowerCase();
51
+ if (status === 401 || status === 403 || status === 404 || text.includes('denied') || text.includes('not found') || text.includes('unauthorized')) {
52
+ return {
53
+ reference,
54
+ state: 'unknown',
55
+ problem: (0, i18n_1.t)({
56
+ en: 'Not found in a registry: built locally, or private without a login.',
57
+ nl: 'Niet gevonden in een registry: lokaal gebouwd, of privé zonder inlog.',
58
+ de: 'Nicht in einer Registry gefunden: lokal gebaut, oder privat ohne Anmeldung.',
59
+ fr: 'Introuvable dans un registry : construite localement, ou privée sans connexion.',
60
+ es: 'No se ha encontrado en ningún registry: construida en local, o privada sin inicio de sesión.',
61
+ }),
62
+ };
63
+ }
64
+ if (text.includes('no such host') || text.includes('dial tcp') || text.includes('timeout') || text.includes('timed out')) {
65
+ return { reference, state: 'error', problem: (0, i18n_1.t)({
66
+ en: 'The registry cannot be reached.',
67
+ nl: 'De registry is niet bereikbaar.',
68
+ de: 'Die Registry ist nicht erreichbar.',
69
+ fr: 'Le registry est injoignable.',
70
+ es: 'No se puede contactar con el registry.',
71
+ }) };
72
+ }
73
+ const reason = err instanceof Error ? err.message : String(err);
74
+ return { reference, state: 'error', problem: (0, i18n_1.t)({
75
+ en: `Checking failed: ${reason}`,
76
+ nl: `Controleren mislukte: ${reason}`,
77
+ de: `Prüfen fehlgeschlagen: ${reason}`,
78
+ fr: `La vérification a échoué : ${reason}`,
79
+ es: `La comprobación ha fallado: ${reason}`,
80
+ }) };
81
+ }
82
+ async function checkOne(tag, deps) {
83
+ const cached = cache.get(tag.reference);
84
+ if (cached !== undefined && deps.now() - cached.at < CACHE_MS) {
85
+ return cached.result;
86
+ }
87
+ let result;
88
+ try {
89
+ const remote = await deps.remoteDigest(tag.reference, await deps.credentials(tag.reference));
90
+ result = { reference: tag.reference, state: tag.digests.includes(remote) ? 'current' : 'update' };
91
+ }
92
+ catch (err) {
93
+ result = classifyFailure(tag.reference, err);
94
+ }
95
+ cache.set(tag.reference, { at: deps.now(), result });
96
+ return result;
97
+ }
98
+ /** Controleert alle tags, hooguit `CONCURRENCY` tegelijk, in de volgorde waarin ze binnenkwamen. */
99
+ async function checkTags(tags, deps) {
100
+ const results = new Array(tags.length);
101
+ let next = 0;
102
+ async function worker() {
103
+ while (next < tags.length) {
104
+ const index = next;
105
+ next += 1;
106
+ results[index] = await checkOne(tags[index], deps);
107
+ }
108
+ }
109
+ await Promise.all(Array.from({ length: Math.min(CONCURRENCY, tags.length) }, () => worker()));
110
+ return results;
111
+ }
112
+ const dockerDeps = {
113
+ remoteDigest: async (reference, auth) => {
114
+ const { docker } = (0, docker_client_1.getConnection)();
115
+ const info = (await docker.getImage(reference).distribution(auth === null ? {} : { authconfig: auth }));
116
+ const digest = info.Descriptor?.digest;
117
+ if (typeof digest !== 'string') {
118
+ throw new Error((0, i18n_1.t)({
119
+ en: 'the registry returned no digest.',
120
+ nl: 'de registry gaf geen digest terug.',
121
+ de: 'die Registry hat keinen Digest zurückgegeben.',
122
+ fr: 'le registry n’a renvoyé aucun digest.',
123
+ es: 'el registry no ha devuelto ningún digest.',
124
+ }));
125
+ }
126
+ return digest;
127
+ },
128
+ credentials: (reference) => (0, registry_auth_1.credentialsFor)(reference),
129
+ now: () => Date.now(),
130
+ };
131
+ /** Alle getagde images op de daemon, gecontroleerd. */
132
+ async function checkImageUpdates(deps = dockerDeps) {
133
+ const { docker } = (0, docker_client_1.getConnection)();
134
+ return checkTags(toLocalTags(await docker.listImages()), deps);
135
+ }
136
+ //# sourceMappingURL=updates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"updates.js","sourceRoot":"","sources":["../electron/updates.ts"],"names":[],"mappings":"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"}