@oddessentials/agent-guild 0.34.0 → 0.36.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.
@@ -1,4 +1,6 @@
1
1
  const STATES = { pending: 'Not checked', not_found: 'Not found', unavailable: 'Runtime unavailable', failed: 'Probe failed' };
2
+ const DESIGN_STATES = { pending: 'Not checked', not_found: 'Not found', on_path: 'On PATH', not_on_path: 'Not on PATH', failed: 'Probe failed' };
3
+ const DOCKER_STATES = { pending: 'Not checked', running: 'Running', stopped: 'Not running', denied: 'No access', remote: 'Not checked', not_found: 'Not found', failed: 'Probe failed' };
2
4
  const PIN_STATES = { configured: 'Configured', unreadable: 'Unreadable', invalid: 'Invalid' };
3
5
  const SCOPES = [
4
6
  ['manager', 'Manager', 'Manager environment'],
@@ -9,6 +11,37 @@ const SCOPES = [
9
11
 
10
12
  export function runtimeValue(row) { return row.status === 'ok' ? row.version : STATES[row.status] || 'Probe failed'; }
11
13
 
14
+ export function designValue(row) {
15
+ const state = DESIGN_STATES[row.status] || DESIGN_STATES.failed;
16
+ if (!row.version) return state;
17
+ return row.status === 'not_on_path' ? `${row.version} · Not on PATH` : row.version;
18
+ }
19
+
20
+ export function formatMemory(bytes) { return `${(bytes / 1024 ** 3).toFixed(1)} GB`; }
21
+
22
+ // Label, value and detail lines for each System row.
23
+ export function systemRows(system) {
24
+ const rows = [];
25
+ const wsl = system.wsl;
26
+ rows.push({ label: 'OS', value: system.os, details: [wsl && `WSL ${wsl.version}${wsl.distro ? ` · ${wsl.distro}` : ''}`, system.osDetail] });
27
+ rows.push({ label: 'Architecture', value: system.hostArch ? `${system.arch} · emulated on ${system.hostArch}` : system.arch, details: [] });
28
+ rows.push({ label: 'CPU', value: `${system.cpu.threads} threads`, details: [system.cpu.model] });
29
+ rows.push({ label: 'Memory', value: formatMemory(system.memory), details: [wsl && 'Memory of the WSL virtual machine, set in .wslconfig. Windows can have more.'] });
30
+ if (wsl) rows.push({ label: 'Windows interop', value: wsl.interop ? 'On' : 'Off', details: [!wsl.interop && 'Agents cannot run Windows programs from this distribution.'] });
31
+ if (Array.isArray(system.wslDistributions)) {
32
+ const list = system.wslDistributions;
33
+ rows.push({
34
+ label: 'WSL', value: !list.length ? 'None installed' : list.length === 1 ? '1 distribution' : `${list.length} distributions`,
35
+ details: list.map((item) => `${item.name}${item.version ? ` · WSL ${item.version}` : ''}${item.default ? ' · default' : ''}`),
36
+ });
37
+ }
38
+ return rows.map((row) => ({ ...row, details: row.details.filter(Boolean) }));
39
+ }
40
+
41
+ export function dockerValue(docker) {
42
+ return docker.status === 'running' && docker.version ? docker.version : DOCKER_STATES[docker.status] || DOCKER_STATES.failed;
43
+ }
44
+
12
45
  export function createEnvironmentUI({
13
46
  api, onAuthError, isAuthError = () => false, document = globalThis.document,
14
47
  workingFolder = () => '', sessions = () => [],
@@ -36,11 +69,16 @@ export function createEnvironmentUI({
36
69
  : !manager ? 'Not checked' : !found.length ? 'No runtime versions verified' : 'Manager environment';
37
70
  }
38
71
 
39
- function rowElement(row) {
72
+ function rowHead(label, value) {
40
73
  const node = element('section', undefined, 'environment-row');
41
74
  const head = element('div', undefined, 'environment-row-head');
42
- head.append(element('strong', row.label), element('span', runtimeValue(row)));
75
+ head.append(element('strong', label), element('span', value));
43
76
  node.append(head);
77
+ return node;
78
+ }
79
+
80
+ function rowElement(row) {
81
+ const node = rowHead(row.label, runtimeValue(row));
44
82
  if (row.command) node.append(element('p', `Command: ${row.command}`, 'environment-detail'));
45
83
  if (row.path) node.append(element('code', row.path, 'environment-path'));
46
84
  const detail = row.detail || (row.status === 'not_found' ? 'No executable was found on the manager’s PATH.' : '');
@@ -54,11 +92,37 @@ export function createEnvironmentUI({
54
92
  return node;
55
93
  }
56
94
 
95
+ function designElement(row) {
96
+ const node = rowHead(row.label, designValue(row));
97
+ if (row.command) node.append(element('p', `Command: ${row.command}`, 'environment-detail'));
98
+ if (row.path) node.append(element('code', row.path, 'environment-path'));
99
+ if (row.status === 'not_on_path') node.append(element('p', 'Installed outside PATH. Agents can run it once its folder is on PATH.', 'environment-detail'));
100
+ if (row.detail) node.append(element('p', row.detail, 'environment-detail'));
101
+ return node;
102
+ }
103
+
104
+ function systemElement(row) {
105
+ const node = rowHead(row.label, row.value);
106
+ for (const detail of row.details) node.append(element('p', detail, 'environment-detail'));
107
+ return node;
108
+ }
109
+
110
+ function dockerElement(docker) {
111
+ const node = rowHead('Docker Engine', dockerValue(docker));
112
+ if (docker.platform) node.append(element('p', docker.platform, 'environment-detail'));
113
+ if (docker.os) node.append(element('p', `${docker.os}${docker.arch ? `/${docker.arch}` : ''}${docker.wsl2 ? ' · runs in WSL 2' : ''}`, 'environment-detail'));
114
+ if (docker.context) node.append(element('p', `Context: ${docker.context}`, 'environment-detail'));
115
+ if (docker.endpoint) node.append(element('code', docker.endpoint, 'environment-path'));
116
+ if (docker.detail) node.append(element('p', docker.detail, 'environment-detail'));
117
+ if (docker.status !== 'pending') {
118
+ node.append(element('p', docker.cli ? 'Command: docker' : 'The docker command is not on PATH.', 'environment-detail'));
119
+ if (docker.cli) node.append(element('code', docker.cli, 'environment-path'));
120
+ }
121
+ return node;
122
+ }
123
+
57
124
  function pinElement(row) {
58
- const node = element('section', undefined, 'environment-row');
59
- const head = element('div', undefined, 'environment-row-head');
60
- head.append(element('strong', row.label), element('span', PIN_STATES[row.status] || 'Invalid'));
61
- node.append(head);
125
+ const node = rowHead(row.label, PIN_STATES[row.status] || 'Invalid');
62
126
  node.append(element('p', row.source, 'environment-detail'));
63
127
  if (row.version) node.append(element('code', row.version, 'environment-path'));
64
128
  if (row.detail) node.append(element('p', row.detail, 'environment-detail'));
@@ -143,6 +207,18 @@ export function createEnvironmentUI({
143
207
  $('environment-tools-note').hidden = !showTools;
144
208
  $('environment-tools').hidden = !showTools;
145
209
  $('environment-tools-empty').hidden = !showTools;
210
+ $('environment-runtimes-heading').textContent = scope === 'project' ? 'Version pins' : 'Runtimes';
211
+ $('environment-runtimes-heading').hidden = scope === 'session' && data?.availability === 'unavailable';
212
+ for (const id of ['environment-design-heading', 'environment-design-note', 'environment-design']) $(id).hidden = !showTools;
213
+ $('environment-design').replaceChildren(...(showTools ? data?.designTools || [] : []).map(designElement));
214
+ const docker = showTools && data?.docker ? data.docker : null;
215
+ $('environment-docker-heading').hidden = !docker;
216
+ $('environment-docker').hidden = !docker;
217
+ $('environment-docker').replaceChildren(...(docker ? [dockerElement(docker)] : []));
218
+ const system = scope === 'manager' && data?.system ? data.system : null;
219
+ $('environment-system-heading').hidden = !system;
220
+ $('environment-system').hidden = !system;
221
+ $('environment-system').replaceChildren(...(system ? systemRows(system).map(systemElement) : []));
146
222
  if (scope === 'project' && data && folder === projectFolder) {
147
223
  $('environment-runtimes').hidden = true;
148
224
  $('environment-runtimes').replaceChildren();
@@ -157,8 +233,8 @@ export function createEnvironmentUI({
157
233
  }
158
234
  if (showTools) {
159
235
  $('environment-tools').replaceChildren(...tools.map((tool) => {
160
- const node = element('section', undefined, 'environment-row');
161
- node.append(element('strong', `${tool.label} · Detected`), element('code', tool.path, 'environment-path'));
236
+ const node = rowHead(tool.label, 'Detected');
237
+ node.append(element('code', tool.path, 'environment-path'));
162
238
  return node;
163
239
  }));
164
240
  $('environment-tools-empty').hidden = Boolean(tools.length);
package/web/index.html CHANGED
@@ -400,12 +400,20 @@
400
400
  <select id="environment-session" hidden></select>
401
401
  <p id="environment-status" class="environment-detail" role="status"></p>
402
402
  <button id="environment-refresh" class="btn" type="button">Refresh</button>
403
+ <h3 id="environment-system-heading" hidden>System</h3>
404
+ <div id="environment-system" hidden></div>
405
+ <h3 id="environment-runtimes-heading">Runtimes</h3>
403
406
  <div id="environment-runtimes"></div>
404
407
  <div id="environment-pins" hidden></div>
405
408
  <h3 id="environment-tools-heading">Detected tools</h3>
406
409
  <p id="environment-tools-note" class="environment-detail">Presence only. Activation and the runtimes these tools manage are not checked.</p>
407
410
  <div id="environment-tools"></div>
408
411
  <p id="environment-tools-empty" class="environment-detail"></p>
412
+ <h3 id="environment-design-heading">Design tools</h3>
413
+ <p id="environment-design-note" class="environment-detail">Agents can run a tool only when it is on PATH. A version is read only from the tool's own program.</p>
414
+ <div id="environment-design"></div>
415
+ <h3 id="environment-docker-heading">Docker</h3>
416
+ <div id="environment-docker"></div>
409
417
  <p id="environment-manager-node" class="environment-detail"></p>
410
418
  </div>
411
419
  </dialog>
@@ -529,7 +537,7 @@
529
537
 
530
538
  <template id="provider-template">
531
539
  <article class="provider" role="listitem">
532
- <span class="card-art" aria-hidden="true"></span>
540
+ <span class="card-art" aria-hidden="true"><span class="spent-veil"></span></span>
533
541
  <div class="provider-head">
534
542
  <span class="provider-icon"></span>
535
543
  <span class="provider-text">
package/web/styles.css CHANGED
@@ -153,6 +153,16 @@ main { max-width: calc(1200px + var(--dock-space, 0px)); margin: 0 auto; padding
153
153
  .account-chip.unsigned { border-style: dashed; }
154
154
  .provider .usage { display: grid; gap: 4px; }
155
155
  .provider .usage:empty { display: none; }
156
+ /* Spent portrait: the art stills and a danger wash sits inside the frame. The card stays usable. */
157
+ .provider .spent-veil {
158
+ position: absolute; inset: 0; z-index: 1; pointer-events: none; opacity: 0;
159
+ background:
160
+ radial-gradient(ellipse at 50% 42%, transparent 28%, color-mix(in srgb, var(--danger) 46%, transparent) 100%),
161
+ linear-gradient(to top, rgba(0, 0, 0, 0.55), transparent 52%);
162
+ transition: opacity 0.4s var(--ease);
163
+ }
164
+ .provider.spent .card-art::before { filter: grayscale(1) brightness(0.82); }
165
+ .provider.spent .spent-veil { opacity: 1; }
156
166
  .environment-summary { min-width: 0; font-size: .78rem; }
157
167
  .environment-open { padding: 0; border: 0; background: none; color: var(--accent); font: inherit; cursor: pointer; text-align: left; }
158
168
  .environment-open:hover { text-decoration: underline; }
@@ -1054,6 +1064,7 @@ a.btn.github-out::after {
1054
1064
  .btn.voice[aria-pressed="true"]::before { animation: none; }
1055
1065
  .drag-handle, .session-grid::before, .session-grid.reordering::before,
1056
1066
  .session-grid > .session-card.dragging, .session-grid > .session-card.settling { transition: none; }
1067
+ .provider .spent-veil { transition: none; }
1057
1068
  }
1058
1069
 
1059
1070
  @media (max-width: 640px) {