@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.
52 lines (51 loc) • 1.69 kB
JavaScript
import { DATA_PROFILE_KEYS } from '../spec/data-profile.js';
/** What the host did with the decision. `held` and `rejected` are previews, not blocks. */
export const TRACE_OUTCOMES = ['rendered', 'held', 'rejected'];
/** Who picked the chart that was drawn. */
export const TRACE_CHOOSERS = ['jev', 'engine', 'named'];
/**
* Closed bands. `low` may run with the workspace. `held` is a preview until
* someone approves it. A spec cannot choose either value.
*/
export const TRACE_RISK_BANDS = ['low', 'held'];
/**
* Blank governance fields, before `governTrace` classifies catalog actions.
* An empty `risk` is "not classified yet", not "every action is low".
* `outcome: rendered` is only this blank default. A held action leaves `governTrace` as `held`.
*/
export function stage4TraceDefaults() {
return {
risk: [],
proposals: [],
proposal: null,
outcome: 'rendered',
};
}
export function closedProfile(profile) {
const next = {};
for (const key of DATA_PROFILE_KEYS) {
if (profile[key] !== undefined) {
next[key] = profile[key];
}
}
return next;
}
const ROW_KEYS = new Set(['rows', 'data']);
export function assertTraceHasNoRows(trace) {
walkForRows(trace);
}
function walkForRows(value) {
if (Array.isArray(value)) {
for (const item of value)
walkForRows(item);
return;
}
if (!value || typeof value !== 'object')
return;
for (const [key, child] of Object.entries(value)) {
if (ROW_KEYS.has(key) && Array.isArray(child)) {
throw new Error('trace must not contain rows');
}
walkForRows(child);
}
}