@aopslabs/aops 0.3.22 → 0.3.24

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 (42) hide show
  1. package/agent-assets-release/agent-assets/core/{47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a → 647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09}/files/user-guides/docman.md +45 -0
  2. package/agent-assets-release/agent-assets/core/{47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a → 647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09}/manifest.json +5 -5
  3. package/agent-assets-release/agent-assets/inventory.json +5 -5
  4. package/agent-assets-release/agent-assets/projection.json +1 -1
  5. package/agent-assets-release/agent-assets-release.json +36 -36
  6. package/agent-assets-release/agent-assets-release.sigstore.json +25 -26
  7. package/assets/agent-assets/core/user-guides/docman.md +45 -0
  8. package/dist/commands/doc.js +561 -32
  9. package/dist/commands/global-update.js +447 -22
  10. package/dist/lib/agent-assets/native-fs.js +2 -2
  11. package/dist/lib/community-cockpit-lifecycle.js +95 -1
  12. package/dist/lib/community-native-lifecycle.js +54 -1
  13. package/native/bin/darwin-arm64/aops-agent-assets-fs +0 -0
  14. package/native/bin/darwin-x64/aops-agent-assets-fs +0 -0
  15. package/native/bin/linux-arm64/aops-agent-assets-fs +0 -0
  16. package/native/bin/linux-x64/aops-agent-assets-fs +0 -0
  17. package/native/bin/win32-x64/aops-agent-assets-fs.exe +0 -0
  18. package/native/manifest.json +6 -6
  19. package/native/qualifications/win32-x64.json +2 -2
  20. package/native/tui/darwin-arm64/aops-tui +0 -0
  21. package/native/tui/win32-x64/aops-tui.exe +0 -0
  22. package/package.json +7 -7
  23. /package/agent-assets-release/agent-assets/core/{47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a → 647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09}/files/SKILL.md +0 -0
  24. /package/agent-assets-release/agent-assets/core/{47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a → 647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09}/files/references/agentspace/SKILL.md +0 -0
  25. /package/agent-assets-release/agent-assets/core/{47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a → 647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09}/files/references/aops-cli-core/SKILL.md +0 -0
  26. /package/agent-assets-release/agent-assets/core/{47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a → 647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09}/files/references/chatv3/SKILL.md +0 -0
  27. /package/agent-assets-release/agent-assets/core/{47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a → 647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09}/files/references/collaborative-work/SKILL.md +0 -0
  28. /package/agent-assets-release/agent-assets/core/{47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a → 647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09}/files/references/discuss/SKILL.md +0 -0
  29. /package/agent-assets-release/agent-assets/core/{47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a → 647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09}/files/references/docman/SKILL.md +0 -0
  30. /package/agent-assets-release/agent-assets/core/{47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a → 647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09}/files/references/mission/SKILL.md +0 -0
  31. /package/agent-assets-release/agent-assets/core/{47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a → 647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09}/files/references/projectman/SKILL.md +0 -0
  32. /package/agent-assets-release/agent-assets/core/{47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a → 647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09}/files/references/sys/SKILL.md +0 -0
  33. /package/agent-assets-release/agent-assets/core/{47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a → 647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09}/files/references/view/SKILL.md +0 -0
  34. /package/agent-assets-release/agent-assets/core/{47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a → 647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09}/files/references/working-disciplines/SKILL.md +0 -0
  35. /package/agent-assets-release/agent-assets/core/{47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a → 647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09}/files/user-guides/agent-assets.md +0 -0
  36. /package/agent-assets-release/agent-assets/core/{47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a → 647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09}/files/user-guides/agentspace.md +0 -0
  37. /package/agent-assets-release/agent-assets/core/{47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a → 647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09}/files/user-guides/aops-cli.md +0 -0
  38. /package/agent-assets-release/agent-assets/core/{47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a → 647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09}/files/user-guides/aops-system.md +0 -0
  39. /package/agent-assets-release/agent-assets/core/{47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a → 647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09}/files/user-guides/chatv3.md +0 -0
  40. /package/agent-assets-release/agent-assets/core/{47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a → 647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09}/files/user-guides/projectman.md +0 -0
  41. /package/agent-assets-release/agent-assets/core/{47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a → 647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09}/files/user-guides/sys.md +0 -0
  42. /package/agent-assets-release/agent-assets/core/{47516047e20f49d9df0f9c63f3ce98e96ee5b788baf13edf48613a2667edca3a → 647c6e84fbc48f9a36945d81660f4d2a5241f58a53a18054365bfc16868b0f09}/files/user-guides/working-disciplines.md +0 -0
@@ -205,6 +205,71 @@ function terminalObservation(record, observedAt, disappeared = false) {
205
205
  signal: record.signal ?? null,
206
206
  };
207
207
  }
208
+ export const COCKPIT_PID_START_TOLERANCE_MS = 300_000;
209
+ export function classifyTerminalCockpitPids(params) {
210
+ if (params.identityPresent) {
211
+ return { stale: false, reason: 'community_cockpit_terminal_identity_file_present', findings: [] };
212
+ }
213
+ if (params.livePids.length === 0) {
214
+ return { stale: false, reason: 'community_cockpit_terminal_no_live_pid', findings: [] };
215
+ }
216
+ const recordedStart = Date.parse(params.record.startedAt);
217
+ if (!Number.isFinite(recordedStart)) {
218
+ return { stale: false, reason: 'community_cockpit_pid_record_start_unparsable', findings: [] };
219
+ }
220
+ const tolerance = params.startToleranceMs ?? COCKPIT_PID_START_TOLERANCE_MS;
221
+ const findings = [];
222
+ let blocked = null;
223
+ for (const { pid, role } of params.livePids) {
224
+ let inspection;
225
+ try {
226
+ inspection = params.inspect(pid);
227
+ }
228
+ catch (error) {
229
+ inspection = {
230
+ outcome: 'undetermined',
231
+ pid,
232
+ reason: error instanceof Error ? error.message : 'community_cockpit_pid_inspection_threw',
233
+ };
234
+ }
235
+ if (inspection.outcome === 'absent') {
236
+ findings.push({ pid, role, outcome: 'absent', disagreedOn: ['identity', 'start-time', 'host-entry'], reason: null });
237
+ continue;
238
+ }
239
+ if (inspection.outcome === 'undetermined') {
240
+ findings.push({ pid, role, outcome: 'undetermined', disagreedOn: [], reason: inspection.reason });
241
+ blocked ??= `community_cockpit_pid_inspection_undetermined:${pid}:${inspection.reason}`;
242
+ continue;
243
+ }
244
+ const observedStart = Date.parse(inspection.startedAt);
245
+ if (!Number.isFinite(observedStart)) {
246
+ findings.push({ pid, role, outcome: 'inspected', disagreedOn: [], reason: 'start_time_unparsable' });
247
+ blocked ??= `community_cockpit_pid_start_time_unparsable:${pid}`;
248
+ continue;
249
+ }
250
+ if (inspection.command.trim() === '') {
251
+ findings.push({ pid, role, outcome: 'inspected', disagreedOn: [], reason: 'command_unavailable' });
252
+ blocked ??= `community_cockpit_pid_command_unavailable:${pid}`;
253
+ continue;
254
+ }
255
+ const disagreedOn = ['identity'];
256
+ if (Math.abs(observedStart - recordedStart) > tolerance)
257
+ disagreedOn.push('start-time');
258
+ if (!commandNamesHostEntry(inspection.command, params.record.hostEntry))
259
+ disagreedOn.push('host-entry');
260
+ findings.push({ pid, role, outcome: 'inspected', disagreedOn, reason: null });
261
+ if (disagreedOn.length !== 3) {
262
+ blocked ??= `community_cockpit_pid_may_be_owned:${pid}:${disagreedOn.join('+')}`;
263
+ }
264
+ }
265
+ if (blocked)
266
+ return { stale: false, reason: blocked, findings };
267
+ return { stale: true, reason: 'community_cockpit_terminal_record_pid_reused', findings };
268
+ }
269
+ function commandNamesHostEntry(command, hostEntry) {
270
+ const normalise = (value) => value.split('\\').join('/').toLowerCase();
271
+ return normalise(command).includes(normalise(hostEntry));
272
+ }
208
273
  async function observeCockpit(params) {
209
274
  const record = params.processRecord;
210
275
  const identityPresent = existsSync(params.paths.identityPath);
@@ -254,11 +319,40 @@ async function observeCockpit(params) {
254
319
  terminalObservation: terminalObservation(record, record.updatedAt),
255
320
  };
256
321
  }
322
+ const observation = terminalObservation(record, record.updatedAt);
323
+ const verdict = observation.classification === 'clean-exit'
324
+ ? classifyTerminalCockpitPids({
325
+ record,
326
+ identityPresent,
327
+ livePids: [
328
+ ...(supervisorAlive ? [{ pid: record.pid, role: 'supervisor' }] : []),
329
+ ...(hostAlive && hostPid ? [{ pid: hostPid, role: 'host' }] : []),
330
+ ],
331
+ inspect: params.runtime.inspectProcess ?? ((pid) => ({
332
+ outcome: 'undetermined',
333
+ pid,
334
+ reason: 'community_cockpit_pid_inspection_unavailable',
335
+ })),
336
+ })
337
+ : {
338
+ stale: false,
339
+ reason: `community_cockpit_terminal_record_with_live_or_unowned_process:${observation.classification}`,
340
+ findings: [],
341
+ };
342
+ if (verdict.stale) {
343
+ return {
344
+ ...base,
345
+ runtimeState: 'stopped', recoverable: true, process: record, identity,
346
+ supervisorAlive, hostAlive, health: 'not-checked',
347
+ reason: verdict.reason,
348
+ terminalObservation: observation,
349
+ };
350
+ }
257
351
  return {
258
352
  ...base,
259
353
  runtimeState: 'identity-conflict', recoverable: false, process: record, identity,
260
354
  supervisorAlive, hostAlive, health: 'not-checked',
261
- reason: 'community_cockpit_terminal_record_with_live_or_unowned_process',
355
+ reason: verdict.reason,
262
356
  terminalObservation: null,
263
357
  };
264
358
  }
@@ -1,5 +1,5 @@
1
1
  import { createHash, randomBytes, randomUUID } from 'node:crypto';
2
- import { spawn } from 'node:child_process';
2
+ import { spawn, spawnSync } from 'node:child_process';
3
3
  import { createRequire } from 'node:module';
4
4
  import { closeSync, existsSync, fsyncSync, lstatSync, mkdirSync, openSync, readdirSync, readSync, readFileSync, realpathSync, renameSync, rmSync, writeFileSync, } from 'node:fs';
5
5
  import path from 'node:path';
@@ -68,6 +68,56 @@ const PACKAGE_BUILD_PATHS = Object.freeze({
68
68
  handlerEntry: 'build/handler.js',
69
69
  cockpitIndex: 'cockpit/index.html',
70
70
  });
71
+ export function inspectHostProcess(pid, execute = (command, args) => {
72
+ const result = spawnSync(command, args, { encoding: 'utf8', windowsHide: true, timeout: 5_000 });
73
+ if (result.error)
74
+ throw result.error;
75
+ return { status: result.status, stdout: result.stdout ?? '', stderr: result.stderr ?? '' };
76
+ }, platform = process.platform) {
77
+ if (!Number.isSafeInteger(pid) || pid < 1) {
78
+ return { outcome: 'undetermined', pid, reason: 'pid_not_inspectable' };
79
+ }
80
+ try {
81
+ if (platform === 'win32') {
82
+ const result = execute('powershell.exe', [
83
+ '-NoProfile', '-NonInteractive', '-Command',
84
+ `$p = Get-CimInstance Win32_Process -Filter "ProcessId=${pid}" -ErrorAction Stop; ` +
85
+ 'if ($null -eq $p) { exit 3 }; ' +
86
+ '"{0}`t{1}" -f $p.CreationDate.ToString("o"), $p.CommandLine',
87
+ ]);
88
+ if (result.status === 3)
89
+ return { outcome: 'absent', pid };
90
+ if (result.status !== 0) {
91
+ return { outcome: 'undetermined', pid, reason: `process_query_failed:${result.status ?? 'no_status'}` };
92
+ }
93
+ const [startedAt, ...rest] = result.stdout.trim().split('\t');
94
+ if (!startedAt)
95
+ return { outcome: 'undetermined', pid, reason: 'process_query_empty' };
96
+ return { outcome: 'inspected', pid, startedAt, command: rest.join('\t').trim() };
97
+ }
98
+ const result = execute('ps', ['-o', 'lstart=,args=', '-p', String(pid)]);
99
+ if (result.status === 1 && result.stdout.trim() === '')
100
+ return { outcome: 'absent', pid };
101
+ if (result.status !== 0) {
102
+ return { outcome: 'undetermined', pid, reason: `process_query_failed:${result.status ?? 'no_status'}` };
103
+ }
104
+ const line = result.stdout.split('\n')[0]?.trim() ?? '';
105
+ if (line === '')
106
+ return { outcome: 'absent', pid };
107
+ const fields = line.split(/\s+/u);
108
+ if (fields.length < 6)
109
+ return { outcome: 'undetermined', pid, reason: 'process_query_unparsable' };
110
+ const startedAt = fields.slice(0, 5).join(' ');
111
+ return { outcome: 'inspected', pid, startedAt, command: fields.slice(5).join(' ') };
112
+ }
113
+ catch (error) {
114
+ return {
115
+ outcome: 'undetermined',
116
+ pid,
117
+ reason: error instanceof Error ? `process_query_threw:${error.message.slice(0, 80)}` : 'process_query_threw',
118
+ };
119
+ }
120
+ }
71
121
  function sha256(content) {
72
122
  return `sha256:${createHash('sha256').update(content).digest('hex')}`;
73
123
  }
@@ -1437,6 +1487,9 @@ export const communityNativeRuntime = {
1437
1487
  return Boolean(error && typeof error === 'object' && 'code' in error && error.code === 'EPERM');
1438
1488
  }
1439
1489
  },
1490
+ inspectProcess(pid) {
1491
+ return inspectHostProcess(pid);
1492
+ },
1440
1493
  sleep: (milliseconds, signal) => new Promise((resolve, reject) => {
1441
1494
  if (signal?.aborted) {
1442
1495
  reject(new Error('community_operation_aborted'));
@@ -6,7 +6,7 @@
6
6
  "platform": "darwin",
7
7
  "architecture": "arm64",
8
8
  "relativePath": "bin/darwin-arm64/aops-agent-assets-fs",
9
- "sha256": "c10dfde3b28f8c6c4d5fbc885fc6fa626763b961580e1676af6692342b2c11db",
9
+ "sha256": "aeff0f83ff7c53f1651ccee44d857f03c5a41846f30302433ade0f3705ae0940",
10
10
  "capabilityClass": "macos-exclusive-durable-v1",
11
11
  "qualification": null
12
12
  },
@@ -14,7 +14,7 @@
14
14
  "platform": "darwin",
15
15
  "architecture": "x64",
16
16
  "relativePath": "bin/darwin-x64/aops-agent-assets-fs",
17
- "sha256": "92cb610782d9d53a2ca43ccf8ffbcef2dd03ec684ce19f2252e3a55eda45e22a",
17
+ "sha256": "d04f3e6ae34c2711cf1cf6bb8a6d5edb669cf4aed4c21e315b23e9d78a0799ef",
18
18
  "capabilityClass": "macos-exclusive-durable-v1",
19
19
  "qualification": null
20
20
  },
@@ -22,7 +22,7 @@
22
22
  "platform": "linux",
23
23
  "architecture": "arm64",
24
24
  "relativePath": "bin/linux-arm64/aops-agent-assets-fs",
25
- "sha256": "8e8457f64e9552a3094a910f3e2214ff2e309b8d2b4754af6fe30fd7fd674ff4",
25
+ "sha256": "4af380c99012b8e847570cb140c70c44c4dcdcee11c17cc5cb2bb8493b82dc8c",
26
26
  "capabilityClass": "linux-posix-durable-v1",
27
27
  "qualification": null
28
28
  },
@@ -30,7 +30,7 @@
30
30
  "platform": "linux",
31
31
  "architecture": "x64",
32
32
  "relativePath": "bin/linux-x64/aops-agent-assets-fs",
33
- "sha256": "a313faedbbb5e4ebd570750ce567ab7e42b23077a8ddf60a4c61ba24965dc01c",
33
+ "sha256": "1c36cd295f0fcfdfd4192748413483b099ac4299e0f770a982846b8915fba31d",
34
34
  "capabilityClass": "linux-posix-durable-v1",
35
35
  "qualification": null
36
36
  },
@@ -38,11 +38,11 @@
38
38
  "platform": "win32",
39
39
  "architecture": "x64",
40
40
  "relativePath": "bin/win32-x64/aops-agent-assets-fs.exe",
41
- "sha256": "f7b0fa243092c5c7fbcddf13ab7e6601566dd8f40078667d262c2a70588dd443",
41
+ "sha256": "c1fcf2fe3689550f1552bdb60a064a9ac0c9e30cba4d9eb7c52140ee14794778",
42
42
  "capabilityClass": "windows-ntfs-crash-recoverable-v1",
43
43
  "qualification": {
44
44
  "relativePath": "qualifications/win32-x64.json",
45
- "sha256": "e6c9581ab34629b19a376c5cf3fb675e36ee34403ef64ec4f43c715533c45249"
45
+ "sha256": "ef348d39e5c9e229b21274d00f779dbe9e8fd7bdbc27cb5c797191bb1294a5ae"
46
46
  }
47
47
  }
48
48
  ]
@@ -3,11 +3,11 @@
3
3
  "status": "qualified",
4
4
  "platform": "win32",
5
5
  "architecture": "x64",
6
- "osBuild": "10.0.26100",
6
+ "osBuild": "10.0.26200",
7
7
  "filesystem": "NTFS",
8
8
  "primitiveProfile": "windows-createfile-flush-movefileex-v1",
9
9
  "capabilityClass": "windows-ntfs-crash-recoverable-v1",
10
- "evidenceSha256": "4d353324b943a237459b60429128c1bd19ae5e15e86c833a1cd9a20180eca9e3",
10
+ "evidenceSha256": "d58ca525d9e4a57c111747e1912e4d74266c712b127cfb9857b7d9d2beb5d3c1",
11
11
  "crashInjectionPoints": [
12
12
  "authority-history",
13
13
  "authority-current",
Binary file
Binary file
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@aopslabs/aops",
3
- "version": "0.3.22",
3
+ "version": "0.3.24",
4
4
  "type": "module",
5
5
  "description": "AOPS CLI and terminal setup application.",
6
- "aopsDockerServerVersion": "0.2.16",
6
+ "aopsDockerServerVersion": "0.2.17",
7
7
  "license": "SEE LICENSE IN LICENSE",
8
8
  "repository": {
9
9
  "type": "git",
@@ -44,7 +44,7 @@
44
44
  "test:commercial-performance": "node --test test/commercial-performance.test.mjs",
45
45
  "test:package-identity": "node --test test/package-identity.test.mjs test/npm-tar-entry-mode.test.mjs",
46
46
  "test:tui-launcher": "node --test test/tui-launcher.test.mjs",
47
- "test:global-update": "node --test test/global-update.test.mjs test/cli-error-format.test.mjs",
47
+ "test:global-update": "pnpm run build && node --test test/global-update.test.mjs test/cli-error-format.test.mjs",
48
48
  "test:global-update-public-bridge": "node scripts/verify-global-update-public-bridge.mjs",
49
49
  "test:skill-discovery": "node --test test/skill-discovery.test.mjs",
50
50
  "test:target-auth": "node --test test/target-auth.test.mjs test/device-login.test.mjs",
@@ -62,17 +62,17 @@
62
62
  },
63
63
  "dependencies": {
64
64
  "@aopslabs/aops-agent-runtime": "0.1.0",
65
- "@aopslabs/aops-server": "0.2.16",
65
+ "@aopslabs/aops-server": "0.2.18",
66
66
  "@aopslabs/artifact-trust-contracts": "0.3.1",
67
67
  "@aopslabs/cli-kit": "0.1.0",
68
- "@aopslabs/aops-host-registration": "0.2.1",
68
+ "@aopslabs/aops-host-registration": "0.2.2",
69
69
  "@aopslabs/aops-pg-bootstrap": "0.2.3",
70
- "@aopslabs/aops-runtime-config": "0.2.1",
70
+ "@aopslabs/aops-runtime-config": "0.2.2",
71
71
  "@sigstore/bundle": "4.0.0",
72
72
  "@sigstore/protobuf-specs": "0.5.1",
73
73
  "@sigstore/tuf": "4.0.2",
74
74
  "@sigstore/verify": "3.1.1",
75
- "@aopslabs/api-client": "0.2.1",
75
+ "@aopslabs/api-client": "0.2.2",
76
76
  "@aopslabs/domain-product-client-chatv3": "0.4.1",
77
77
  "@aopslabs/xf-cli-ui": "0.2.0",
78
78
  "commander": "14.0.3",