@aiwg/cockpit 2026.7.23 → 2026.7.25
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.
- package/README.md +46 -7
- package/bridge/src/server.mjs +431 -6
- package/bridge/src/smoke.mjs +44 -3
- package/package.json +1 -1
- package/web/dist/assets/index-BTBL-9AY.js +312 -0
- package/web/dist/assets/index-CesGeDud.css +32 -0
- package/web/dist/index.html +2 -2
- package/web/src/App.test.tsx +34 -1
- package/web/src/components/Inventory.test.tsx +165 -0
- package/web/src/components/Inventory.tsx +176 -3
- package/web/src/components/LaunchInstanceModal.test.tsx +151 -1
- package/web/src/components/LaunchInstanceModal.tsx +193 -3
- package/web/src/components/Telemetry.tsx +17 -2
- package/web/src/runtimeContracts.fixtures.ts +230 -0
- package/web/src/runtimeContracts.test.ts +63 -0
- package/web/src/styles.css +7 -0
- package/web/src/types.ts +168 -2
- package/web/dist/assets/index-B0ea5aQ1.css +0 -32
- package/web/dist/assets/index-CYVukAJR.js +0 -312
package/bridge/src/smoke.mjs
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// Self-contained (own ports); no deps. Exits non-zero on failure.
|
|
3
3
|
import assert from 'node:assert/strict';
|
|
4
4
|
import { fileURLToPath } from 'node:url';
|
|
5
|
-
import { createExecutor } from '../../mock-executor/src/server.mjs';
|
|
6
|
-
import { createBridge, normalizeSessionRows } from './server.mjs';
|
|
5
|
+
import { createExecutor, DEFAULT_INSTANCE } from '../../mock-executor/src/server.mjs';
|
|
6
|
+
import { createBridge, localLibvirtFallbackAllowed, normalizeSessionRows } from './server.mjs';
|
|
7
7
|
|
|
8
8
|
const mock = createExecutor();
|
|
9
9
|
await new Promise((r) => mock.listen(0, '127.0.0.1', r));
|
|
@@ -34,6 +34,8 @@ try {
|
|
|
34
34
|
assert.equal(inv.instances.find((i) => i.transport?.mode === 'shared-secret')?.transport.trust, 'compatibility', 'legacy secret transport is compatibility posture');
|
|
35
35
|
const i0 = inv.instances[0];
|
|
36
36
|
for (const k of ['id', 'runtime', 'loadout', 'state', 'tenant', 'card_url', 'runtime_posture', 'host_daemon', 'transport', 'launch_context', 'session_backends']) assert.ok(k in i0, `field ${k}`);
|
|
37
|
+
assert.equal(i0.storage?.persistent, true, 'storage persistence surfaced');
|
|
38
|
+
assert.equal(i0.storage?.delete_on_destroy, true, 'storage delete-on-destroy surfaced');
|
|
37
39
|
assert.ok(['vm', 'container', 'host', 'wasm-edge'].includes(i0.runtime), 'runtime kind');
|
|
38
40
|
|
|
39
41
|
// A transient executor outage must not poison Bridge state or require a
|
|
@@ -101,6 +103,45 @@ try {
|
|
|
101
103
|
assert.ok(Array.isArray(lo.loadouts) && lo.loadouts.length >= 3, 'loadout catalog returned');
|
|
102
104
|
assert.ok(lo.loadouts.every((l) => typeof l.id === 'string' && typeof l.label === 'string'), 'loadouts carry id+label');
|
|
103
105
|
assert.ok(lo.loadouts.some((l) => l.id === 'security-audit'), 'catalog includes a non-default loadout');
|
|
106
|
+
const gpuLoadout = lo.loadouts.find((l) => l.id === 'gpu-vfio');
|
|
107
|
+
assert.ok(gpuLoadout?.runtime_options?.required_capabilities?.includes('device.vfio'), 'loadout runtime_options preserve VFIO requirement');
|
|
108
|
+
assert.ok(gpuLoadout?.compatibility?.[0]?.excluded_capabilities?.includes('instance.restore'), 'loadout compatibility preserves fast-start exclusion');
|
|
109
|
+
|
|
110
|
+
const caps = await (await f('/api/executor/capabilities')).json();
|
|
111
|
+
assert.ok(caps.runtime_providers?.providers?.some((p) => p.provider === 'cloud-hypervisor'), 'runtime providers discovered');
|
|
112
|
+
assert.ok(caps.runtime_providers.providers.find((p) => p.provider === 'cloud-hypervisor')?.capability_constraints?.[0]?.excludes?.includes('instance.restore'), 'provider VFIO constraint preserved');
|
|
113
|
+
const hostProvider = caps.runtime_providers.providers.find((p) => p.provider === 'host');
|
|
114
|
+
const dockerProvider = caps.runtime_providers.providers.find((p) => p.provider === 'docker');
|
|
115
|
+
assert.ok(hostProvider?.platforms?.includes('darwin/arm64'), 'Apple Silicon host runtime discovery is proxied');
|
|
116
|
+
assert.equal(hostProvider?.posture?.host_architecture, 'arm64', 'Apple Silicon host architecture is preserved');
|
|
117
|
+
assert.equal(dockerProvider?.engine, 'Docker Desktop', 'Docker Desktop runtime posture is proxied');
|
|
118
|
+
assert.equal(dockerProvider?.posture?.host_platform, 'darwin', 'Docker Desktop host platform is preserved');
|
|
119
|
+
assert.equal(localLibvirtFallbackAllowed('darwin', undefined), false, 'virsh fallback is not automatic on macOS');
|
|
120
|
+
assert.equal(localLibvirtFallbackAllowed('darwin', '1'), true, 'virsh fallback can be explicitly enabled for local development');
|
|
121
|
+
assert.equal(localLibvirtFallbackAllowed('linux', undefined), true, 'Linux bridge hosts retain local virsh fallback');
|
|
122
|
+
|
|
123
|
+
const vm = inv.instances.find((i) => i.provider === 'cloud-hypervisor');
|
|
124
|
+
assert.ok(vm, 'provider-aware VM inventory row present');
|
|
125
|
+
const fastStartAccepted = await (await f(`/api/instances/${encodeURIComponent(vm.id)}/snapshot`, {
|
|
126
|
+
method: 'POST',
|
|
127
|
+
headers: { 'content-type': 'application/json' },
|
|
128
|
+
body: JSON.stringify({ asset_ref: 'cockpit-smoke-snapshot' }),
|
|
129
|
+
})).json();
|
|
130
|
+
assert.ok(fastStartAccepted.id, 'fast-start proxy returns operation id');
|
|
131
|
+
const fastStartTerminal = await (await f(`/api/operations/${encodeURIComponent(fastStartAccepted.id)}`)).json();
|
|
132
|
+
assert.equal(fastStartTerminal.state, 'succeeded', 'fast-start operation reaches terminal state');
|
|
133
|
+
assert.equal(fastStartTerminal.result.provider, 'cloud-hypervisor', 'fast-start operation preserves provider');
|
|
134
|
+
|
|
135
|
+
const mcp = await (await f('/api/mcp/discovery')).json();
|
|
136
|
+
assert.equal(mcp.enabled, true, 'MCP discovery enabled');
|
|
137
|
+
assert.equal(mcp.endpoint?.path, '/mcp', 'MCP endpoint path surfaced');
|
|
138
|
+
assert.equal(mcp.endpoint?.mcp_session_id, false, 'MCP discovery is stateless/no session id');
|
|
139
|
+
assert.ok(mcp.tools.some((tool) => tool.name === 'list_sandboxes'), 'MCP tools surfaced');
|
|
140
|
+
assert.ok(mcp.resource_templates.some((template) => template.uriTemplate === 'sandbox://sessions/{session_id}/screen'), 'MCP resource templates surfaced');
|
|
141
|
+
assert.equal((await f('/api/mcp', { method: 'POST', body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'tools/list' }) })).status, 503, 'MCP proxy fail-closed without token file');
|
|
142
|
+
const gatedReconnect = await f(`/api/instances/${DEFAULT_INSTANCE}/reconnect`, { method: 'POST' });
|
|
143
|
+
assert.equal(gatedReconnect.status, 409, 'Docker reconnect fallback is gated unless local dev flag is set');
|
|
144
|
+
assert.equal((await gatedReconnect.json()).error, 'local_docker_fallback_disabled', 'Docker reconnect fallback error is explicit');
|
|
104
145
|
|
|
105
146
|
// registry binding: discover + show through the aiwg CLI (#1592)
|
|
106
147
|
const cap = await (await f("/api/capabilities?q=" + encodeURIComponent("deploy production") + "&limit=4")).json();
|
|
@@ -196,7 +237,7 @@ try {
|
|
|
196
237
|
assert.equal((await fetch(base + asset[1].replace(/^\.\//, '/'))).status, 200, 'built React bundle served');
|
|
197
238
|
}
|
|
198
239
|
|
|
199
|
-
console.log(`SMOKE OK — inventory(4) + running(${run.count}) + sessions(demo-shell) + registry(discover→${cap.results.length}) + contrib(${contrib.actions.length}) + shell(${shell})`);
|
|
240
|
+
console.log(`SMOKE OK — inventory(4) + running(${run.count}) + sessions(demo-shell) + mcp(${mcp.tools.length} tools) + registry(discover→${cap.results.length}) + contrib(${contrib.actions.length}) + shell(${shell})`);
|
|
200
241
|
} finally {
|
|
201
242
|
bridge.close();
|
|
202
243
|
mock.close();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiwg/cockpit",
|
|
3
|
-
"version": "2026.7.
|
|
3
|
+
"version": "2026.7.25",
|
|
4
4
|
"description": "AIWG Cockpit — UX-first control plane over AIWG + multi-stack agentic sessions. Opt-in, separately published; NOT shipped in the base aiwg npm package (guarded by test/smoke/cockpit-base-footprint.test.js).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|