@unoverse-platform/studio 0.1.45 → 0.1.47

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,10 +1,14 @@
1
1
  # Playbook: Templates (MCP apps)
2
2
 
3
- **Read first:** `docs/design/templates.md` (layouts + manifest-as-envelope) +
4
- `docs/design/state.md` (the state model). Deep law: `UNOVERSE_STATE_MODEL.md` §5
5
- (the six rules), `UNOVERSE_LAYERS.md`. Everything in the component playbook (closed
6
- vocabulary, tokens, scale steps) applies here too. **Study the exemplar before
7
- writing**: `rx/sab/templates/sab-chat-layout` is the canonical State Model v2 template.
3
+ **Read first:** [design/templates](https://docs.unoverse.ai/design/templates.md)
4
+ (layouts + manifest-as-envelope) +
5
+ [design/state](https://docs.unoverse.ai/design/state.md) (the state model). Deep law:
6
+ [UNOVERSE_STATE_MODEL](https://docs.unoverse.ai/unoverse/UNOVERSE_STATE_MODEL.md) §5
7
+ (the six rules), [UNOVERSE_LAYERS](https://docs.unoverse.ai/unoverse/UNOVERSE_LAYERS.md).
8
+ Everything in the component playbook (closed vocabulary, tokens, scale steps) applies
9
+ here too. **Study an exemplar before writing**: read the closest installed template
10
+ through Studio's MCP (`listDefinitions` kind `template` → `readDefinition`); the
11
+ canonical manifest tree is inlined below. (Monorepo: `design/sab/templates/sab-chat-layout`.)
8
12
 
9
13
  ## THE model: the component drives; the template reacts by name
10
14
 
@@ -23,7 +27,7 @@ template knows it = a base substate or template state.**
23
27
 
24
28
  ## The manifest states tree: one declaration, everything follows
25
29
 
26
- The canonical shape (`rx/sab/templates/sab-chat-layout/manifest.yaml`):
30
+ The canonical shape (a chat layout: a base arrangement plus a reaction ladder):
27
31
 
28
32
  ```yaml
29
33
  states:
@@ -64,7 +68,7 @@ states:
64
68
  ## The anatomy: manifest-only (NO `<name>.yaml` envelope)
65
69
 
66
70
  ```
67
- apps/unoverse/rx/<project>/templates/<name>/
71
+ design/<project>/templates/<name>/
68
72
  manifest.yaml # THE ENVELOPE: the whole app contract, incl. the states tree
69
73
  layouts/ # the ARRANGEMENTS: one per state that owns one (same-name default)
70
74
  main.yaml # the base: the core alone
@@ -84,7 +88,8 @@ ComponentSlot selecting the matching view.
84
88
 
85
89
  Required: `name` · `description` (what it IS, ≤120) · `whenToUse` (utterance-shaped: the
86
90
  USER's words; findIntent ranks on it, the OPENING words carry the ranking; disqualify by
87
- property, never by naming siblings; full contract: docs/design/05 §Naming) ·
91
+ property, never by naming siblings; full contract:
92
+ [design/templates](https://docs.unoverse.ai/design/templates.md) §Naming) ·
88
93
  `category` · `defaultState: "template"` (the app-level LOAD state, a protocol field,
89
94
  nothing to do with component views) · `inputSchema` · `layout` (the BASE layout name) ·
90
95
  `states` (the tree above) · `binding` (`workflow` + `trigger`: the app OWNS its
@@ -154,7 +159,7 @@ template states by name exactly as in chat. Audio is never wired in a definition
154
159
 
155
160
  ## New project?
156
161
 
157
- `rx/<project>/` = `templates/` + optional `components/` (project-private microapps;
162
+ `design/<project>/` = `templates/` + optional `components/` (project-private microapps;
158
163
  names unique within the project and never shadowing a marketplace name; two projects
159
164
  may share a name, each addressed `<org>/<name>`) + `styles/` holding ONLY the org's
160
165
  overrides (the foundation cascades per token; the theme file is the one you copy
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: unoverse-prompt-component
3
- description: Build or audit a PROMPT component (a briefed, AI-filled Unoverse component) in rx/. Use when adding brief tags, deciding which props an agent may fill, debugging a part the agent never fills or fills wrongly, or checking what a component's MCP tool schema actually contains. Covers the traps that silently discard an authored brief.
3
+ description: Build or audit a PROMPT component (a briefed, AI-filled Unoverse component) in design/. Use when adding brief tags, deciding which props an agent may fill, debugging a part the agent never fills or fills wrongly, or checking what a component's MCP tool schema actually contains. Covers the traps that silently discard an authored brief.
4
4
  ---
5
5
 
6
6
  # Prompt components: the parts an agent fills
7
7
 
8
- A prompt component is an ordinary `rx/` component whose bound nodes carry `brief` tags.
8
+ A prompt component is an ordinary `design/` component whose bound nodes carry `brief` tags.
9
9
  The platform compiles those tags into the component's **MCP tool schema**, and that schema
10
10
  is the only instruction channel: no side-channel prompt, no per-component agent skill.
11
11
  `unoverse-create` covers authoring components in general; this skill is about the briefs.
@@ -19,19 +19,23 @@ one you wrote.
19
19
 
20
20
  ## Step 1 (do this first, and again at the end): compile the schema
21
21
 
22
+ In the **platform monorepo**, run the bundled compiler from the repo root (it resolves
23
+ `@unoverse-platform/base`):
24
+
22
25
  ```bash
23
26
  cp .claude/skills/unoverse-prompt-component/verify.ts ./verify.tmp.ts
24
27
  npx tsx verify.tmp.ts <org>/<component> # e.g. better-alpha/deal-page
25
28
  rm -f verify.tmp.ts
26
29
  ```
27
30
 
28
- It must run from the repo root (it resolves `@unoverse-platform/base`). It prints every
29
- part the agent can fill, its description, and its limits. Read that output, not the YAML.
30
-
31
- Then, always: `node -e "import('./packages/base/src/lint/rx/index.mjs').then(m=>{const r=m.lintDefinitions();console.log(r.problems.length);r.problems.forEach(p=>console.log(p.level,p.file,p.msg))})"`
31
+ It prints every part the agent can fill, its description, and its limits. Read that
32
+ output, not the YAML. Then run the design lint
33
+ (`node -e "import('./packages/base/src/lint/design/index.mjs').then(m=>{const r=m.lintDefinitions();console.log(r.problems.length);r.problems.forEach(p=>console.log(p.level,p.file,p.msg))})"`).
32
34
 
33
- The linter catches two of the five traps below by name. Read what it says rather than
34
- silencing it.
35
+ In a **Studio developer workspace**, the same linter runs as Studio's publish lint (or
36
+ the authoring MCP's `lintProject` tool); it catches two of the five traps below by
37
+ name. Read what it says rather than silencing it, and always do the final proof in
38
+ Step 6: one real fill.
35
39
 
36
40
  ---
37
41
 
@@ -73,8 +77,9 @@ are briefed or neither is.
73
77
 
74
78
  ## Step 3: put the brief on the node that BINDS the field
75
79
 
76
- This is the rule from the rulebook (docs/design/CLAUDE.md §3) and it is where authored
77
- briefs go to die.
80
+ This is the rule from the rulebook
81
+ ([design/CLAUDE.md](https://docs.unoverse.ai/design/CLAUDE.md) §3) and it is where
82
+ authored briefs go to die.
78
83
 
79
84
  ```yaml
80
85
  # COMPILES
@@ -114,7 +119,7 @@ silence it. Move them to the `Each`.
114
119
 
115
120
  ### Trap 3: a briefed atom drags a collection into the schema
116
121
 
117
- Briefs are collected from the **expanded** tree (`packages/base/src/markdown/collect.ts`).
122
+ Briefs are collected from the **expanded** tree (the platform's brief collector).
118
123
  An `Each` is recorded whenever its template has briefed fields, whether or not the `Ref`
119
124
  itself carries a brief.
120
125
 
@@ -135,8 +140,8 @@ each other.
135
140
  ### Trap 5: counts that are layout, not preference
136
141
 
137
142
  If a strip renders `columns: "4"`, then `minItems: 4, maxItems: 4`. Note that `minItems`
138
- is **guidance only**: the compiler appends it to the description and never gates on it
139
- (`server/src/mcp/briefSchema.ts`). `maxItems` and `maxLength` are hard. A count that is
143
+ is **guidance only**: the schema compiler appends it to the description and never gates
144
+ on it. `maxItems` and `maxLength` are hard. A count that is
140
145
  genuinely structural cannot be enforced by the schema alone, so say so in the description.
141
146
 
142
147
  ---
@@ -159,18 +164,18 @@ abbreviate and never substitute characters. Say so in the page-level brief.
159
164
  ## Step 5: the workflow door
160
165
 
161
166
  If the component is filled by an agent inside a workflow rather than in chat, read
162
- `docs/unoverse/UNOVERSE_MCP_TEMPLATE_PROTOCOL.md` §The workflow door. The load-bearing law:
167
+ `UNOVERSE_MCP_TEMPLATE_PROTOCOL.md` §The workflow door (platform spec; in the monorepo
168
+ at `docs/unoverse/`). The load-bearing law:
163
169
  **a blank part is a valid final state.** A part the source does not cover stays blank, the
164
170
  `visibleWhen` guards render around it, and the page is complete. Gaps are orientation on
165
- the first read, never standing debt. This is implemented in
166
- `server/src/runtime/components/executor/briefService.ts`; a component that fights it burns
167
- every turn to `maxTurns` and returns an empty text output.
171
+ the first read, never standing debt. The platform's brief service implements this; a
172
+ component that fights it burns every turn to `maxTurns` and returns an empty text output.
168
173
 
169
174
  ### The agent node's system prompt stays ROLE-ONLY
170
175
 
171
176
  The service port already delivers everything else when the agent connects: the fill
172
- protocol (`briefService.ts` `getSchema.instructions` — survey once, batch fills, blanks
173
- are finished, stop when done — folded into the agent's system prompt by MCPServiceRouter),
177
+ protocol (the brief service's `getSchema` instructions: survey once, batch fills, blanks
178
+ are finished, stop when done; folded into the agent's system prompt by the service router),
174
179
  the content rules (each part's compiled brief), and the grounding law (injected into the
175
180
  schema description). A workflow agent's system prompt therefore carries ONE line of role
176
181
  ("You fill the page from this run's documents; the service's instructions and each part's