Skip to content

Commit 94b849b

Browse files
committed
docs: document alpha.5 graph diagnostics (FlowDiagnosticMeta, flow-step-not-surfaced, orphaned-flow)
1 parent 50e3fb5 commit 94b849b

1 file changed

Lines changed: 60 additions & 1 deletion

File tree

docs/Inspect-Screen.md

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,40 @@ $.flow("signup").startsWith(email) // name is surfaced but not in any flow
183183
// Diagnostic: surfaced-node-not-in-any-flow for "Name"
184184
```
185185

186+
### `flow-step-not-surfaced`
187+
188+
- **Severity**: `warning`
189+
- **What it means**: A flow step references an ask or action node that is not included in any surface. The interaction path is defined but one of its steps would render nothing visible, making the flow incomplete.
190+
- **Triggers when**: A flow's `.startsWith()` or `.then()` references a node that is not in any `.surface().contains()`.
191+
- **Why per-flow and not deduplicated**: Unlike `ask-not-in-surface` / `action-not-in-surface` (which fire once per unsurfaced node), this diagnostic fires once per (flow, step) pair. If the same unsurfaced node appears in multiple flows, each one is reported so the author knows which flows are broken.
192+
- **Fix**: Add the missing node to a surface, or remove it from the flow step.
193+
194+
Example:
195+
196+
```ts
197+
const email = $.ask("Email", emailState)
198+
$.surface("main").contains() // email not surfaced
199+
$.flow("signup").startsWith(email) // flow-step-not-surfaced for "Email" in flow "signup"
200+
```
201+
202+
### `orphaned-flow`
203+
204+
- **Severity**: `warning`
205+
- **What it means**: A flow exists with one or more steps, but none of its steps reference a node that appears in any surface. The flow defines an interaction path that is entirely disconnected from the rendered UI.
206+
- **Triggers when**: A flow has at least one step, and every step references an ask or action that is not in any surface.
207+
- **Does not trigger for**: Empty flows (zero-step flows are not diagnosed, as they may be placeholders for future steps).
208+
- **Relationship to `flow-step-not-surfaced`**: `orphaned-flow` is a flow-level signal — it fires once per affected flow. The individual unsurfaced steps also each fire `flow-step-not-surfaced`. A flow with all-unsurfaced steps will produce both diagnostics.
209+
- **Fix**: Surface at least one node referenced by a flow step, or add the flow's steps to a surface.
210+
211+
Example:
212+
213+
```ts
214+
const email = $.ask("Email", emailState)
215+
const name = $.ask("Name", nameState)
216+
$.surface("main").contains() // no nodes surfaced
217+
$.flow("signup").startsWith(email).then(name) // orphaned-flow for "signup"
218+
```
219+
186220
### Diagnostic output format
187221

188222
Each diagnostic is a `GraphDiagnostic` object:
@@ -193,7 +227,8 @@ Each diagnostic is a `GraphDiagnostic` object:
193227
code: "secret-ask-not-private",
194228
message: "Secret ask should also be marked private.",
195229
nodeId: "ask_password",
196-
semanticNodeId: "ask:password"
230+
semanticNodeId: "ask:password",
231+
flow?: FlowDiagnosticMeta
197232
}
198233
```
199234

@@ -202,6 +237,30 @@ Each diagnostic is a `GraphDiagnostic` object:
202237
- `message`: human-readable explanation.
203238
- `nodeId` (optional): the internal node ID of the affected node.
204239
- `semanticNodeId` (optional): the semantic ID of the affected node, when applicable.
240+
- `flow` (optional): a `FlowDiagnosticMeta` object present on flow-scoped diagnostics (`flow-step-not-surfaced`, `orphaned-flow`).
241+
242+
### FlowDiagnosticMeta type
243+
244+
```ts
245+
type FlowDiagnosticMeta = {
246+
flowNodeId: string
247+
flowSemanticNodeId?: string
248+
}
249+
```
250+
251+
`FlowDiagnosticMeta` identifies the containing flow for a diagnostic:
252+
253+
| Field | Type | Description |
254+
|-------|------|-------------|
255+
| `flowNodeId` | `string` | Internal node ID of the flow |
256+
| `flowSemanticNodeId` | `string` (optional) | Semantic ID of the flow, populated by `inspectScreen()` |
257+
258+
Present on diagnostics where the issue is scoped to a specific flow:
259+
260+
| Diagnostic | `nodeId` / `semanticNodeId` | `flow` / `flow.flowNodeId` |
261+
|------------|----------------------------|---------------------------|
262+
| `flow-step-not-surfaced` | The unsurfaced ask or action step | The containing flow |
263+
| `orphaned-flow` | Undefined (no single node is at fault) | The orphaned flow |
205264
206265
## Development workflow
207266

0 commit comments

Comments
 (0)