mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-11-14 10:39:32 +01:00
fix(story-mode): no celebration when the turn is not a clean finish
From review round 8: "Mission complete!" with confetti and cheering helpers sat over balloons saying the page will not work as opened, a helper's tests have not run, or a problem is left. The final panel is now calm (no confetti, a neutral robot) whenever work was still out at the turn's end, nothing worked, or Claude's last words name an open problem (`page.openNote`: a key point about something wrong, not done, not checked or not fixed); the last of these reads "Done, with a catch". Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
faca7571e2
commit
88040c997d
17 files changed
+80
-7
No files matched your search
+15
-4
@@ -275,9 +275,14 @@ export function balloonText(text: string): string {
|
||||
* expected, a correction of an earlier warning. WEAK: a bare negation ("I didn't push"), kept only when
|
||||
* nothing strong is there.
|
||||
*/
|
||||
/** The open-problem part of a key point: something wrong, not done, not checked, or still out. */
|
||||
const OPEN_PROBLEM = new RegExp(
|
||||
String.raw`\b(problem|known (issue|quirk)s?|quirks?|caveat|limitation|heads up|warning|not yet|haven't|have not|never|unfixed|left (open|unfixed|out)|still (fails?|failing|broken|missing|open|running|working)|must be (served|run)|(won't|doesn't|does not|will not) (work|fix)|(isn't|is not|not) fixed|can't tell|isn't (confirmed|committed|pushed|tested|done|checked)|not (checked|tested|verified|confirmed|committed|pushed|opened))\b`,
|
||||
'i'
|
||||
);
|
||||
const KEY_POINT_STRONG = new RegExp(
|
||||
[
|
||||
String.raw`\b(problem|known (issue|quirk)s?|quirks?|caveat|limitation|heads up|warning|not yet|haven't|have not|never|unfixed|left (open|unfixed|out)|still (fails?|failing|broken|missing|open|running|working)|must be (served|run)|(won't|doesn't|does not|will not) work|can't tell|isn't (confirmed|committed|pushed|tested|done|checked)|not (checked|tested|verified|confirmed|committed|pushed|opened))\b`,
|
||||
OPEN_PROBLEM.source,
|
||||
String.raw`\b(as you (asked|expected|said|wanted|suggested)|you asked|your (--?[\w-]+|request|option|flag|change))\b`,
|
||||
String.raw`\b(out of date|looked too early|turned out|was wrong)\b`,
|
||||
].join('|'),
|
||||
@@ -1991,7 +1996,7 @@ const REPORT_TALK: Partial<Record<StoryPanelKind, RegExp>> = {
|
||||
};
|
||||
const ANNOUNCES = /\b(I'll|I will|let me|let's|I'm going to|next,? I|now I)\b/i;
|
||||
|
||||
function groupPanels(events: StoryEvent[]): { panels: DraftPanel[]; trailingSay?: string } {
|
||||
function groupPanels(events: StoryEvent[]): { panels: DraftPanel[]; trailingSay?: string; openNote?: boolean } {
|
||||
const panels: DraftPanel[] = [];
|
||||
let pendingSay: string | undefined;
|
||||
let lastSaid: StoryEvent | undefined;
|
||||
@@ -2037,7 +2042,12 @@ function groupPanels(events: StoryEvent[]): { panels: DraftPanel[]; trailingSay?
|
||||
pendingSay = undefined;
|
||||
});
|
||||
// The closing words keep a caveat that follows them ("Nothing is committed: this is no git repo.").
|
||||
return { panels, trailingSay: lastSaid !== undefined ? closingText(lastSaid.label, lastSaid.keyPoints) : pendingSay };
|
||||
return {
|
||||
panels,
|
||||
trailingSay: lastSaid !== undefined ? closingText(lastSaid.label, lastSaid.keyPoints) : pendingSay,
|
||||
// Claude's last words name an open problem: the final panel is not a celebration.
|
||||
openNote: !!lastSaid?.keyPoints?.some((k) => OPEN_PROBLEM.test(k)),
|
||||
};
|
||||
}
|
||||
|
||||
/** Fix → check → fix → check (4 panels or more) is one "loop" panel: try, test, repeat. */
|
||||
@@ -2611,7 +2621,7 @@ export function buildStoryPage(turn: StoryTurn): StoryPage {
|
||||
if (todos) e.todos = todos;
|
||||
}
|
||||
|
||||
const { panels: grouped, trailingSay } = groupPanels(events);
|
||||
const { panels: grouped, trailingSay, openNote } = groupPanels(events);
|
||||
const room = STORY_LIMITS.panelsPerPage - (turn.ended ? 1 : 0);
|
||||
const drafts = capPanels(collapseLoops(grouped), room);
|
||||
const panels = drafts.map((d, i) => decorate(d, events, turn, i));
|
||||
@@ -2628,6 +2638,7 @@ export function buildStoryPage(turn: StoryTurn): StoryPage {
|
||||
// The advisor is a second opinion, not a helper that does work.
|
||||
helpers: events.filter((e) => e.helper && e.tool !== 'Advisor' && e.intent !== 'prompt').length,
|
||||
helpersRunning: events.filter((e) => e.helper?.running).length,
|
||||
...(openNote && turn.ended && !turn.interrupted ? { openNote: true } : {}),
|
||||
...(events.some((e) => e.finishedLater && e.intent !== 'prompt')
|
||||
? { finishedLater: events.filter((e) => e.finishedLater && e.intent !== 'prompt').length }
|
||||
: {}),
|
||||
|
||||
@@ -210,6 +210,8 @@ export interface StoryPage extends StoryTurnSummary {
|
||||
helpersRunning: number;
|
||||
/** Helpers and background commands of this turn that finished only after it ended. */
|
||||
finishedLater?: number;
|
||||
/** Claude's last words name an open problem or something not done or checked: no clean finish. */
|
||||
openNote?: boolean;
|
||||
/** Every tool call of the turn failed (a blocked command, nothing that worked): no celebration. */
|
||||
noneWorked?: boolean;
|
||||
}
|
||||
|
||||
@@ -1436,7 +1436,14 @@ const StoryArt = (() => {
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (p.page.noneWorked) {
|
||||
// Not a clean finish (nothing worked, work still out, or Claude named an open problem): no party.
|
||||
const calm =
|
||||
p.page.noneWorked ||
|
||||
p.page.helpersRunning ||
|
||||
p.page.finishedLater ||
|
||||
p.page.openNote ||
|
||||
p.page.events.some((e) => e.running && !e.helper);
|
||||
if (calm) {
|
||||
agent(ctx, ax, 250, { frame: f, scale: sc, mood: 'neutral', l: [-34, -48], r: [34, -48] });
|
||||
return;
|
||||
}
|
||||
@@ -2484,7 +2491,9 @@ Object.assign(CodemanApp.prototype, {
|
||||
: page.helpersRunning || page.finishedLater || page.events.some((e) => e.running && !e.helper)
|
||||
? // Work was still out when the turn ended (and maybe still is): not a clean finish.
|
||||
'Done for now'
|
||||
: 'Mission complete!';
|
||||
: page.openNote
|
||||
? 'Done, with a catch'
|
||||
: 'Mission complete!';
|
||||
const chips = rt.splash.querySelector('.story-chips');
|
||||
const items = [];
|
||||
if (page.durationMs !== undefined) items.push({ text: this._storyDuration(page.durationMs) });
|
||||
|
||||
Reference in new issue
Block a user