@unoverse-platform/studio 0.1.5 → 0.1.7
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/package.json
CHANGED
|
@@ -9,7 +9,7 @@ import { UnoverseComponent, type ResolvedTheme } from "@unoverse/sdk";
|
|
|
9
9
|
import { client, authedFetch, hasSourceAccess } from "studio-host";
|
|
10
10
|
import { SourceView } from "./SourceView";
|
|
11
11
|
import { stateActivation } from "./states";
|
|
12
|
-
import { usePersistentState
|
|
12
|
+
import { usePersistentState } from "studio-host";
|
|
13
13
|
|
|
14
14
|
const CHAT_ID = "demo";
|
|
15
15
|
|
|
@@ -31,7 +31,8 @@ interface ComponentDef {
|
|
|
31
31
|
whenToUse?: string;
|
|
32
32
|
category?: string;
|
|
33
33
|
/** Spatial-CAPABLE: the component folder carries a manifest.json (server-projected).
|
|
34
|
-
*
|
|
34
|
+
* Capability, not activation: a capable component can be put on a workflow's map from
|
|
35
|
+
* Canvas's Content Library. It gates the Meta panel here, nothing more. */
|
|
35
36
|
spatial?: boolean;
|
|
36
37
|
props?: Record<string, PropDef>;
|
|
37
38
|
/** The node's input prop keys, derived server-side (= the node's configSchema).
|
|
@@ -56,7 +57,6 @@ const VIEWPORTS: { id: string; label: string; w: number | null }[] = [
|
|
|
56
57
|
|
|
57
58
|
export function ComponentsView({ theme, org = "all" }: { theme: ResolvedTheme; org?: string }) {
|
|
58
59
|
const store = useMemo(() => new ComponentStore(), []);
|
|
59
|
-
const spatial = useRegistryToggles("component");
|
|
60
60
|
const [components, setComponents] = useState<ComponentDef[]>([]);
|
|
61
61
|
const [selected, setSelected] = usePersistentState<string | null>("wb:components:selected", null);
|
|
62
62
|
const [values, setValues] = useState<Record<string, unknown>>({}); // typed values → store/render
|
|
@@ -500,7 +500,11 @@ export function ComponentsView({ theme, org = "all" }: { theme: ResolvedTheme; o
|
|
|
500
500
|
{/* Spatial toggle — ONLY for spatial-capable components (manifest.json present).
|
|
501
501
|
Same two-level model as templates/skills: this is Level 1 (workbench
|
|
502
502
|
eligibility); the Content Engine's per-workflow toggle is Level 2. */}
|
|
503
|
-
{
|
|
503
|
+
{/* NO SPATIAL TOGGLE HERE. It wrote `plugin_state.enabled`, which the spatial catalogue
|
|
504
|
+
deliberately IGNORES (`routeRegistrySpatial`): published IS available. What is actually
|
|
505
|
+
on a map is the PER-WORKFLOW row, switched in Canvas's Content Library — spatial is
|
|
506
|
+
unique to each workflow, and this screen has no workflow. A control that reads as the
|
|
507
|
+
answer to "is this in spatial?" while writing where nothing reads is worse than none. */}
|
|
504
508
|
{current?.spatial && (
|
|
505
509
|
<button
|
|
506
510
|
onClick={() => setMetaOpen((o) => !o)}
|
package/screens/SkillsView.tsx
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { useEffect, useState } from "react";
|
|
13
13
|
import { fetchUnoverse } from "studio-host";
|
|
14
|
-
import { usePersistentState
|
|
14
|
+
import { usePersistentState } from "studio-host";
|
|
15
15
|
import { IdentityHeader } from "./IdentityHeader";
|
|
16
16
|
|
|
17
17
|
interface SkillSummary {
|
|
@@ -37,7 +37,6 @@ export function SkillsView() {
|
|
|
37
37
|
const [detail, setDetail] = useState<SkillDetail | null>(null);
|
|
38
38
|
const [loadingDetail, setLoadingDetail] = useState(false);
|
|
39
39
|
const [error, setError] = useState<string | null>(null);
|
|
40
|
-
const spatial = useRegistryToggles("skill");
|
|
41
40
|
|
|
42
41
|
// Load the library list once.
|
|
43
42
|
useEffect(() => {
|
|
@@ -108,7 +107,6 @@ export function SkillsView() {
|
|
|
108
107
|
}`}
|
|
109
108
|
>
|
|
110
109
|
<div className="flex items-center gap-1.5 text-sm font-medium">
|
|
111
|
-
{spatial.isEnabled(s.name) && <span className="h-1.5 w-1.5 rounded-full bg-emerald-400" title="Spatial on" />}
|
|
112
110
|
{s.name}
|
|
113
111
|
</div>
|
|
114
112
|
<div className="truncate text-[11px] text-gray-500">{s.description}</div>
|
|
@@ -130,9 +128,8 @@ export function SkillsView() {
|
|
|
130
128
|
version={detail?.version}
|
|
131
129
|
description={detail?.description}
|
|
132
130
|
whenToUse={detail?.whenToUse}
|
|
133
|
-
right={<ToggleSwitch on={spatial.isEnabled(selected)} onClick={() => spatial.toggle(selected)} label="Spatial" />}
|
|
134
131
|
/>
|
|
135
|
-
<p className="mb-3 text-[11px] text-gray-500">
|
|
132
|
+
<p className="mb-3 text-[11px] text-gray-500">Whether this skill is on a map is switched per workflow, in Canvas’s Content Library: spatial is unique to each workflow.</p>
|
|
136
133
|
|
|
137
134
|
{detail?.triggers && detail.triggers.length > 0 && (
|
|
138
135
|
<div className="mb-5 flex flex-wrap gap-1.5">
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { useCallback, useEffect, useMemo, useState, useSyncExternalStore } from "react";
|
|
11
11
|
import { useAuth } from "react-oidc-context";
|
|
12
|
-
import { usePersistentState
|
|
12
|
+
import { usePersistentState } from "studio-host";
|
|
13
13
|
import { ComponentStore } from "@unoverse/sdk";
|
|
14
14
|
import { StreamedUnoverseTemplate, useUnoverseConnection, computeAppWidth, resolveActiveLayout, type ResolvedTheme, type UseVoiceServiceConfig } from "@unoverse/sdk";
|
|
15
15
|
import { NativeAppHost } from "./NativeAppHost";
|
|
@@ -166,7 +166,6 @@ export function TemplatesView({
|
|
|
166
166
|
useCallback((cb) => store.subscribe(cb), [store]),
|
|
167
167
|
useCallback(() => store.getVersion(), [store]),
|
|
168
168
|
);
|
|
169
|
-
const spatial = useRegistryToggles("template");
|
|
170
169
|
const [seeded, setSeeded] = useState<string[]>([]);
|
|
171
170
|
const [metaOpen, setMetaOpen] = usePersistentState<boolean>("wb:templates:meta", false); // MCP details panel
|
|
172
171
|
const [copiedUri, setCopiedUri] = useState(false);
|
|
@@ -636,7 +635,11 @@ export function TemplatesView({
|
|
|
636
635
|
})}
|
|
637
636
|
</div>
|
|
638
637
|
)}
|
|
639
|
-
{
|
|
638
|
+
{/* NO SPATIAL TOGGLE HERE. It wrote `plugin_state.enabled`, which the spatial catalogue
|
|
639
|
+
deliberately IGNORES (`routeRegistrySpatial`): published IS available. What is actually
|
|
640
|
+
on a map is the PER-WORKFLOW row, switched in Canvas's Content Library — spatial is
|
|
641
|
+
unique to each workflow, and this screen has no workflow. A control that reads as the
|
|
642
|
+
answer to "is this in spatial?" while writing where nothing reads is worse than none. */}
|
|
640
643
|
{selected && (
|
|
641
644
|
<button
|
|
642
645
|
onClick={() => setMetaOpen((o) => !o)}
|
|
@@ -71,6 +71,11 @@ export interface UnoverseNode {
|
|
|
71
71
|
userData?: Record<string, unknown>;
|
|
72
72
|
/** Icon: the served glyph NAME (literal) — or bind a data field via `bind.name`. */
|
|
73
73
|
icon?: string;
|
|
74
|
+
/** Icon: the same literal under the key a `Ref`'s `with` writes. An atom binds `name`, and
|
|
75
|
+
* `applyLiterals` replaces that bind with a literal of the SAME key — so a Ref-supplied
|
|
76
|
+
* glyph arrives as `name`, never as `icon`. Declared because the renderer reads it; it was
|
|
77
|
+
* read without being declared, which typechecked nowhere until Studio's config was fixed. */
|
|
78
|
+
name?: string;
|
|
74
79
|
/** Disable the element (Input/Button) when this data field is truthy; the node's
|
|
75
80
|
* `style.disabled` is merged while disabled. */
|
|
76
81
|
disabledWhen?: string;
|
|
@@ -147,9 +147,13 @@ export function renderNode(
|
|
|
147
147
|
// be authored without it: the data carries no ordinal, and a template cannot count.
|
|
148
148
|
// `index` is 0-based for logic, `position` 1-based because that is what a reader sees.
|
|
149
149
|
// The item's own fields always win, so data that carries either name is untouched.
|
|
150
|
+
// AN ARRAY ITEM IS THE VALUE. `typeof [] === "object"`, so an array took the spread
|
|
151
|
+
// branch and its INDICES became scope keys ({0: "London", 1: "+44…"}) while `value` was
|
|
152
|
+
// never set. A nested Each bound to `value` — a table's row of cells — then found
|
|
153
|
+
// nothing, and every table rendered its headers over empty rows.
|
|
150
154
|
const scopeOf = (item: unknown, i: number): Record<string, unknown> => {
|
|
151
155
|
const base = { index: i, position: i + 1 };
|
|
152
|
-
return item != null && typeof item === "object"
|
|
156
|
+
return item != null && typeof item === "object" && !Array.isArray(item)
|
|
153
157
|
? { ...base, ...(item as Record<string, unknown>) }
|
|
154
158
|
: { ...base, value: item };
|
|
155
159
|
};
|