quoxcli 0.5.0 → 0.6.1

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 (130) hide show
  1. package/CHANGELOG.md +65 -1
  2. package/lib/api/endpoints/admin.js +21 -0
  3. package/lib/api/endpoints/calendarq.js +8 -0
  4. package/lib/api/endpoints/governance.js +7 -0
  5. package/lib/api/endpoints/inboxq.js +39 -0
  6. package/lib/api/endpoints/index.js +4 -0
  7. package/lib/api/endpoints/lens.js +34 -0
  8. package/lib/api/endpoints/lucid.js +18 -0
  9. package/lib/api/endpoints/mcp.js +35 -0
  10. package/lib/api/endpoints/mon.js +6 -7
  11. package/lib/api/endpoints/notesq.js +2 -0
  12. package/lib/api/endpoints/quoxplan.js +51 -0
  13. package/lib/api/endpoints/v1.js +57 -0
  14. package/lib/commands/actions.js +51 -13
  15. package/lib/commands/admin.js +86 -0
  16. package/lib/commands/approvals.js +5 -1
  17. package/lib/commands/calendar.js +27 -0
  18. package/lib/commands/chat.js +1 -1
  19. package/lib/commands/contacts.js +2 -0
  20. package/lib/commands/fleet.js +164 -0
  21. package/lib/commands/fleetRecipe.js +174 -0
  22. package/lib/commands/lens.js +268 -0
  23. package/lib/commands/lucid.js +6 -0
  24. package/lib/commands/lucidGoals.js +423 -0
  25. package/lib/commands/mail.js +287 -7
  26. package/lib/commands/mcp.js +190 -0
  27. package/lib/commands/mon.js +14 -0
  28. package/lib/commands/monitoring.js +73 -1
  29. package/lib/commands/notesSeal.js +380 -22
  30. package/lib/commands/offload.js +51 -10
  31. package/lib/commands/plan.js +507 -54
  32. package/lib/commands/research.js +78 -0
  33. package/lib/commands/settings.js +7 -1
  34. package/lib/commands/volt.js +6 -1
  35. package/lib/commands/wazuh.js +74 -9
  36. package/lib/commands/wazuhIntake.js +55 -6
  37. package/lib/core/commandRegistrars.js +2 -0
  38. package/lib/core/config.js +14 -1
  39. package/lib/core/offload.js +83 -0
  40. package/lib/core/output.js +29 -4
  41. package/lib/core/selfUpdate.js +2 -0
  42. package/lib/core/version.js +15 -2
  43. package/lib/dragon/select.js +2 -2
  44. package/lib/quoxon/api.js +4 -0
  45. package/lib/quoxon/app.js +258 -49
  46. package/lib/quoxon/approvalsView.js +3 -1
  47. package/lib/quoxon/ask.js +4 -2
  48. package/lib/quoxon/bang.js +7 -1
  49. package/lib/quoxon/commandShort.js +1 -1
  50. package/lib/quoxon/commands.js +5 -5
  51. package/lib/quoxon/delegationDragon.js +49 -0
  52. package/lib/quoxon/dnd.js +47 -0
  53. package/lib/quoxon/dragonCompanion.js +24 -12
  54. package/lib/quoxon/events.js +12 -1
  55. package/lib/quoxon/extensions.js +2 -0
  56. package/lib/quoxon/foreignText.js +49 -0
  57. package/lib/quoxon/inboxView.js +5 -5
  58. package/lib/quoxon/launcher.js +2 -1
  59. package/lib/quoxon/loopCard.js +2 -1
  60. package/lib/quoxon/main.js +8 -2
  61. package/lib/quoxon/onboarding/dockerOffer.js +3 -1
  62. package/lib/quoxon/onboarding/view.js +1 -1
  63. package/lib/quoxon/render.js +5 -2
  64. package/lib/quoxon/resend.js +14 -0
  65. package/lib/quoxon/rows.js +3 -1
  66. package/lib/quoxon/secretShape.js +2 -0
  67. package/lib/quoxon/slash/broadcast.js +30 -6
  68. package/lib/quoxon/slash/broadcastRun.js +12 -6
  69. package/lib/quoxon/slash/cliLeaves.json +54 -0
  70. package/lib/quoxon/slash/dashboard.js +2 -0
  71. package/lib/quoxon/slash/listView.js +2 -1
  72. package/lib/quoxon/slash/palette.js +41 -0
  73. package/lib/quoxon/slash/paletteController.js +6 -2
  74. package/lib/quoxon/slash/restart.js +2 -0
  75. package/lib/quoxon/slotChat.js +7 -3
  76. package/lib/quoxon/slotRun.js +2 -0
  77. package/lib/quoxon/webPty.js +15 -0
  78. package/lib/quoxon/whatsnew.jsonl +7 -0
  79. package/lib/render/planBrief.js +614 -0
  80. package/lib/toolOutputShape.js +6 -3
  81. package/package.json +1 -1
  82. package/vendor/dragonlab/SOURCE +3 -3
  83. package/vendor/dragonlab/design/architect/v2/architect-master.svg +67 -0
  84. package/vendor/dragonlab/design/architect/v2/character.mjs +83 -0
  85. package/vendor/dragonlab/design/architect/v2/review.mjs +35 -0
  86. package/vendor/dragonlab/design/architect/v2/watch.mjs +56 -0
  87. package/vendor/dragonlab/design/archivist/v2/archivist-master.svg +77 -0
  88. package/vendor/dragonlab/design/archivist/v3/character.mjs +56 -0
  89. package/vendor/dragonlab/design/archivist/v4/character.mjs +46 -0
  90. package/vendor/dragonlab/design/archivist/v4/review.mjs +35 -0
  91. package/vendor/dragonlab/design/archivist/v4/watch.mjs +56 -0
  92. package/vendor/dragonlab/design/argus/v2/character.mjs +69 -0
  93. package/vendor/dragonlab/design/argus/v3/argus-master.svg +68 -0
  94. package/vendor/dragonlab/design/argus/v3/character.mjs +63 -0
  95. package/vendor/dragonlab/design/argus/v3/review.mjs +35 -0
  96. package/vendor/dragonlab/design/argus/v3/watch.mjs +56 -0
  97. package/vendor/dragonlab/design/daedalus/v2/character.mjs +49 -0
  98. package/vendor/dragonlab/design/daedalus/v3/daedalus-master.svg +65 -0
  99. package/vendor/dragonlab/design/daedalus/v4/character.mjs +47 -0
  100. package/vendor/dragonlab/design/daedalus/v5/character.mjs +66 -0
  101. package/vendor/dragonlab/design/daedalus/v6/character.mjs +32 -0
  102. package/vendor/dragonlab/design/daedalus/v6/review.mjs +35 -0
  103. package/vendor/dragonlab/design/daedalus/v6/watch.mjs +56 -0
  104. package/vendor/dragonlab/design/janus/v1/janus-master.svg +70 -0
  105. package/vendor/dragonlab/design/janus/v2/character.mjs +56 -0
  106. package/vendor/dragonlab/design/janus/v3/character.mjs +7 -0
  107. package/vendor/dragonlab/design/janus/v4/character.mjs +150 -0
  108. package/vendor/dragonlab/design/janus/v5/character.mjs +55 -0
  109. package/vendor/dragonlab/design/janus/v5/review.mjs +35 -0
  110. package/vendor/dragonlab/design/janus/v5/watch.mjs +56 -0
  111. package/vendor/dragonlab/design/roady/v1/roady-master.svg +67 -0
  112. package/vendor/dragonlab/design/roady/v2/character.mjs +69 -0
  113. package/vendor/dragonlab/design/roady/v3/character.mjs +91 -0
  114. package/vendor/dragonlab/design/roady/v3/review.mjs +35 -0
  115. package/vendor/dragonlab/design/roady/v3/watch.mjs +56 -0
  116. package/vendor/dragonlab/design/weaver/v3/weaver-master.svg +57 -0
  117. package/vendor/dragonlab/design/weaver/v4/character.mjs +56 -0
  118. package/vendor/dragonlab/design/weaver/v5/character.mjs +52 -0
  119. package/vendor/dragonlab/design/weaver/v6/character.mjs +88 -0
  120. package/vendor/dragonlab/design/weaver/v6/review.mjs +35 -0
  121. package/vendor/dragonlab/design/weaver/v6/watch.mjs +56 -0
  122. package/vendor/dragonlab/integration/companions-v1/architect.mjs +2 -0
  123. package/vendor/dragonlab/integration/companions-v1/archivist.mjs +2 -0
  124. package/vendor/dragonlab/integration/companions-v1/argus.mjs +2 -0
  125. package/vendor/dragonlab/integration/companions-v1/characters.mjs +86 -0
  126. package/vendor/dragonlab/integration/companions-v1/daedalus.mjs +2 -0
  127. package/vendor/dragonlab/integration/companions-v1/janus.mjs +2 -0
  128. package/vendor/dragonlab/integration/companions-v1/roady.mjs +2 -0
  129. package/vendor/dragonlab/integration/companions-v1/view.mjs +4 -1
  130. package/vendor/dragonlab/integration/companions-v1/weaver.mjs +2 -0
@@ -2,7 +2,8 @@
2
2
  * `quox offload` : run a heavy command on a pool worker VM and behave like running it locally.
3
3
  *
4
4
  * quox offload [--dir <path>] [--fresh] [--keep] [--cores N --memory-gb N --disk-gb N] -- <command...>
5
- * quox offload status
5
+ * quox offload status every configured worker's lease (EXPIRED / EXPIRING / OK) + the selected worker's dirs
6
+ * quox offload leases [--json] the same lease list, machine-readable for a timer
6
7
  * quox offload release
7
8
  *
8
9
  * Engine: lib/core/offload.js. The worker is leased through the human pool REST API
@@ -11,7 +12,10 @@
11
12
 
12
13
  import { printInfo } from '../core/output.js';
13
14
  import { makePoolRest } from '../core/vm.js';
14
- import { OffloadError, realDeps, runOffload, releaseWorker, workerStatus, resolveSyncDir, WORKER_NAME_RE } from '../core/offload.js';
15
+ import {
16
+ OffloadError, realDeps, runOffload, releaseWorker, workerStatus, resolveSyncDir, WORKER_NAME_RE,
17
+ allLeases, leaseWarnings, describeLease, LEASE_WARN_H, listWorkerNames,
18
+ } from '../core/offload.js';
15
19
 
16
20
  export function registerOffloadCommands(program, ctx, { deps: injected } = {}) {
17
21
  const { client, auth } = ctx;
@@ -26,6 +30,19 @@ export function registerOffloadCommands(program, ctx, { deps: injected } = {}) {
26
30
  }
27
31
  return name ? Object.assign(Object.create(Object.getPrototypeOf(d)), d, { worker: String(name) }) : d;
28
32
  };
33
+ // Leasing needs a human profile, so an agent can only warn: one stderr line per lease ending within LEASE_WARN_H.
34
+ const warn = (report) => { for (const l of leaseWarnings(report)) process.stderr.write(`offload: ${l}\n`); };
35
+ const leaseLines = (report) => {
36
+ const width = Math.max(7, ...report.leases.map((l) => l.worker.length));
37
+ const lines = [`offload workers (warn when a lease ends within ${LEASE_WARN_H}h; source: ${report.source})`];
38
+ for (const l of report.leases) {
39
+ const head = ` ${l.worker.padEnd(width)} `;
40
+ if (l.lease === 'NONE') { lines.push(`${head}no worker leased`); continue; }
41
+ lines.push(`${head}vm ${l.vmid} ${l.ip || '?'} pool ${l.pool_state} lease ${l.lease_expires_at || '?'} ${describeLease(l)}`);
42
+ }
43
+ if (report.pool_error) lines.push(` (pool status failed, expiry from the local state: ${report.pool_error})`);
44
+ return lines;
45
+ };
29
46
  const WORKER_HELP = 'use your own named worker (its own lease and size) instead of the shared one; or set QUOX_OFFLOAD_WORKER';
30
47
 
31
48
  const off = program
@@ -46,6 +63,7 @@ export function registerOffloadCommands(program, ctx, { deps: injected } = {}) {
46
63
  const cwd = process.cwd();
47
64
  try {
48
65
  const dir = resolveSyncDir(cwd, options.dir);
66
+ try { warn(await allLeases(base(), { live: false })); } catch { /* the warning never blocks a run */ }
49
67
  const code = await runOffload(mk(options), {
50
68
  dir, cwd, command, fresh: !!options.fresh, docker: !!options.docker,
51
69
  cores: options.cores, memoryGb: options.memoryGb, diskGb: options.diskGb,
@@ -59,16 +77,32 @@ export function registerOffloadCommands(program, ctx, { deps: injected } = {}) {
59
77
  });
60
78
 
61
79
  off.command('status')
62
- .description('Show your offload worker: vmid, ip, lease expiry, synced dirs')
80
+ .description('Show every offload worker lease (EXPIRED / EXPIRING / OK) and your worker: vmid, ip, synced dirs')
63
81
  .option('--worker <name>', WORKER_HELP)
64
82
  .action(async (options) => {
65
83
  auth.requireAuth();
66
- const s = await workerStatus(mk(options));
67
- if (json()) { console.log(JSON.stringify(s, null, 2)); return; }
68
- if (!s.worker) { printInfo('no offload worker leased (it is leased on the next `quox offload -- <command>`)'); return; }
69
- const w = s.worker;
70
- console.log(`worker ${w.vmid} ${w.ip || '?'} ${w.state} lessee ${w.lessee} lease expires ${w.lease_expires_at || '?'}`);
71
- for (const d of s.dirs) console.log(` synced ${d.local} -> ${d.remote} ${d.synced_at || ''}`);
84
+ // commander hands `status --worker x` to the parent offload command's --worker, so read both.
85
+ const s = await workerStatus(mk({ worker: options.worker ?? off.opts().worker }));
86
+ const report = await allLeases(base());
87
+ warn(report);
88
+ if (json()) { console.log(JSON.stringify({ ...s, leases: report.leases }, null, 2)); return; }
89
+ if (!s.worker) printInfo('this worker has no lease (a human profile leases it on the next `quox offload -- <command>`)');
90
+ else {
91
+ const w = s.worker;
92
+ console.log(`worker ${w.vmid} ${w.ip || '?'} ${w.state} lessee ${w.lessee} lease expires ${w.lease_expires_at || '?'}`);
93
+ for (const d of s.dirs) console.log(` synced ${d.local} -> ${d.remote} ${d.synced_at || ''}`);
94
+ }
95
+ for (const line of leaseLines(report)) console.log(line);
96
+ });
97
+
98
+ off.command('leases')
99
+ .description(`List every configured offload worker lease with EXPIRED / EXPIRING (within ${LEASE_WARN_H}h) / OK and the human renew command (read-only)`)
100
+ .action(async () => {
101
+ auth.requireAuth();
102
+ const report = await allLeases(base());
103
+ warn(report);
104
+ if (json()) { console.log(JSON.stringify(report, null, 2)); return; }
105
+ for (const line of leaseLines(report)) console.log(line);
72
106
  });
73
107
 
74
108
  off.command('release')
@@ -77,7 +111,14 @@ export function registerOffloadCommands(program, ctx, { deps: injected } = {}) {
77
111
  .action(async (options) => {
78
112
  auth.requireAuth();
79
113
  try {
80
- const vmid = await releaseWorker(mk(options));
114
+ // commander hands `release --worker x` to the parent offload command; reading only the subcommand's
115
+ // options released (destroyed) the SHARED default worker instead of x.
116
+ const d = mk({ worker: options.worker ?? off.opts().worker });
117
+ if (d.worker && !listWorkerNames(d).includes(d.worker)) {
118
+ const known = listWorkerNames(d).map((n) => n || 'default').join(', ') || 'none';
119
+ throw new OffloadError(`no offload worker named ${JSON.stringify(d.worker)} (configured: ${known}); nothing released`);
120
+ }
121
+ const vmid = await releaseWorker(d);
81
122
  if (json()) console.log(JSON.stringify({ released: vmid }));
82
123
  else printInfo(vmid ? `released worker ${vmid}` : 'no offload worker to release');
83
124
  } catch (e) {