feat(steps): the rail — a handler read top to bottom, forks and all
The reading the walk records now has a picture. `#/steps?…&view=order` draws the anchor, then its body: a box per step in the order the code writes them, a fork where the code forks with its arms side by side under the condition, a helper drawn where it is called, and an arm that answers, returns or throws ending there — so proshop's login reads *look the user up · if the password matches, sign a token inside the reply and answer 200 · otherwise 401*, which is what the code says and what a row of four boxes could not. - `program-model.ts` decides the words: the fork carries the decision once and its arms say only which side they are (WHEN / WHEN NOT), except a `switch`, whose arms each have a case to say, and a `try`, which says `on error` once. - `StepBox.svelte` is the box both readings draw — the canvas wraps it in handles, the rail lets it size to its words. Same look, same click, same double-click-to-start-here. - `StepsKey.svelte` is the key, floating over the canvas as before and last in the document on the rail, which scrolls and cannot have things sitting on it. - The reading travels in the URL (`view=order` / `view=tree`) and the summary offers both; without one, the answer's own default decides — the code's order for a handler or an endpoint, the tree for a screen. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01REFyW9hmNrxhwN5wxRoAkC
This commit is contained in:
co-authored by
Claude Opus 5
parent
b02e192ffa
commit
9acab0020f
@@ -58,7 +58,7 @@ function shape(block: WireBlock, indent = ''): string[] {
|
||||
out.push(...shape(arm.body, `${indent} `));
|
||||
}
|
||||
} else if (item.kind === 'block') {
|
||||
out.push(`${indent}${item.block} ${item.label}${item.again ? ' (again)' : ''}`);
|
||||
out.push(`${indent}${item.block}${item.via ? ` via ${item.via.name}` : item.by ? ` ${item.by}` : ''}${item.again ? ' (again)' : ''}`);
|
||||
out.push(...shape(item.body, `${indent} `));
|
||||
} else out.push(`${indent}cut ${item.why}`);
|
||||
}
|
||||
@@ -157,8 +157,9 @@ describe('buildProgram', () => {
|
||||
at('d', [g('kind: default', { form: 'case', branch })]),
|
||||
],
|
||||
});
|
||||
// The head says what is being decided on; each arm its own case.
|
||||
expect(shape(p!.root)).toEqual([
|
||||
"switch kind === 'a'",
|
||||
'switch kind',
|
||||
" arm kind === 'a'",
|
||||
' a',
|
||||
" arm kind === 'b'",
|
||||
@@ -224,14 +225,14 @@ describe('buildProgram', () => {
|
||||
const p = program({
|
||||
root: [at('now'), at('afterwards', [], { trigger: { kind: 'callback', name: 'then', of: null } })],
|
||||
});
|
||||
expect(shape(p!.root)).toEqual(['now', 'later later · then', ' afterwards']);
|
||||
expect(shape(p!.root)).toEqual(['now', 'later then', ' afterwards']);
|
||||
});
|
||||
|
||||
it('puts calls started together in one block', () => {
|
||||
const p = program({
|
||||
root: [at('a', [], { within: 'Promise.all' }), at('b', [], { within: 'Promise.all' }), at('c')],
|
||||
});
|
||||
expect(shape(p!.root)).toEqual(['together together', ' a inside Promise.all', ' b inside Promise.all', 'c']);
|
||||
expect(shape(p!.root)).toEqual(['together Promise.all', ' a inside Promise.all', ' b inside Promise.all', 'c']);
|
||||
});
|
||||
|
||||
it('closes a fork when the code leaves it', () => {
|
||||
|
||||
Reference in New Issue
Block a user