archive issue fix
Some checks failed
CI / check (push) Failing after 5m5s

This commit is contained in:
2026-09-10 19:29:39 +05:30
parent 6249e00a3a
commit f522b6508e
20 changed files with 2444 additions and 207 deletions

View File

@@ -45,6 +45,9 @@ export function resolveUiEdit({ question, ui }) {
page can actually hold — the same scope the visual editor's picker uses,
so the two can never disagree about what is addable here. */
page: ui.page,
/* The node this conversation last changed. Nothing is remembered inside the
matcher: continuity is a fact the caller holds and passes in. */
focus: ui.focus || null,
});
if (!match) return null;
@@ -155,8 +158,52 @@ export function resolveUiEdit({ question, ui }) {
followUp: [{ label: 'What is on this page?', prompt: 'What is on this page?' }],
};
case 'refused':
return { kind: 'ui-answer', doc: doc(text(match.message)) };
/**
* Understood, and not possible — with the reason and the way forward.
*
* A refusal that only says no leaves a person guessing at a vocabulary they
* cannot see. When the engine knows what this reading *could* be drawn as,
* it says so and offers the choices as chips, so "no, but here" costs one
* click rather than another round of guessing.
*/
case 'refused': {
const offered = match.alternatives || [];
return {
kind: 'ui-answer',
doc: offered.length
? doc(
text(match.message),
text(`It can be shown as: ${offered.map((o) => o.label).join(', ')}.`)
)
: doc(text(match.message)),
followUp: offered.slice(0, 3).map((option) => ({
label: option.label,
prompt: `Show ${match.node?.title || match.node?.label || 'it'} as a ${option.label}`,
})),
};
}
/**
* Every way this reading could honestly be drawn.
*
* The options are the registry's answer, not a suggestion: each is a
* component the application ships, each will draw this node's own figures,
* and choosing one produces exactly the operation `planReplace` would have
* produced from the same words. Nothing here is generated.
*/
case 'options':
return {
kind: 'ui-answer',
doc: doc(
text(`${match.subject} can be drawn these ways. Each one uses the same figures.`),
list(match.options.map((option) => `${option.label} — ${option.summary}`)),
note('Pick one to preview it. Nothing is saved until you apply.')
),
followUp: match.options.map((option) => ({
label: option.label,
prompt: `Show ${match.node.title || match.node.label} as a ${option.label}`,
})),
};
default:
return null;

View File

@@ -588,6 +588,10 @@ export function useConversation({
property of the page, not of the registry, and this is how
the conversation learns it. */
page: uiEditing.page || null,
/* What this session last changed, so "change it back" has an
"it". A node id and nothing else — see `focus` on the
editing provider. */
focus: uiEditing.focus || null,
}
: null,
}),