UNPKG

@fusedashlabs/ui9000-workspace

Version:

UI9000 workspace MCP. One tool, show_workspace, draws a chart from your table. Set TYPESAFE_API_KEY to let Jev choose the chart.

64 lines (63 loc) • 2.3 kB
/** * Frozen `_meta` keys for the chart App. * chart-app reads this contract. It does not invent keys. * * `_meta.trace` is the decision record. * `_meta.proposal` is optional and present only when an action is held. * `ui.resourceUri` stays `ui://ui9000/chart`. */ export const META_RESOURCE_URI = 'ui://ui9000/chart'; export const FROZEN_META_KEYS = ['_meta.trace', '_meta.proposal', 'ui.resourceUri']; const ROW_KEYS = new Set(['rows', 'data']); /** The object chart-app is allowed to read. Resource URI is not renamed. */ export function workspaceMeta(input) { return { ui: { resourceUri: input.resourceUri, visibility: ['model', 'app'], csp: input.csp, }, 'ui/resourceUri': input.resourceUri, chartType: input.chartType, dataUrl: input.dataUrl, chartId: input.chartId, ...(input.trace ? { trace: input.trace } : {}), ...(input.proposal ? { proposal: input.proposal } : {}), }; } const DECISION_KEYS = new Set(['trace', 'proposal', 'proposals']); /** * Drops dataset `rows` everywhere. * Drops a `data` array only inside a decision record (`trace`, `proposal`, `proposals`). * A `data` array on the tool result itself is left alone. */ export function omitRowArrays(value, insideDecision = false) { if (Array.isArray(value)) { return value.map((item) => omitRowArrays(item, insideDecision)); } if (!value || typeof value !== 'object') return value; const next = {}; for (const [key, child] of Object.entries(value)) { if (Array.isArray(child) && key === 'rows') continue; if (Array.isArray(child) && key === 'data' && insideDecision) continue; const childInside = insideDecision || DECISION_KEYS.has(key); next[key] = omitRowArrays(child, childInside); } return next; } export function containsRowArrays(value) { if (Array.isArray(value)) return value.some(containsRowArrays); if (!value || typeof value !== 'object') return false; for (const [key, child] of Object.entries(value)) { if (ROW_KEYS.has(key) && Array.isArray(child)) return true; if (containsRowArrays(child)) return true; } return false; }