DAY 02작업 2일째
위젯에서 답하고 메시지를 보내게 했다
질문 답장은 앱 질문 창과 경주를 붙이고, 메시지는 위젯이 들고 있다가 작업이 끝나면 넘겨 취소도 되게 했다.
보기만 하는 위젯으로는 반쪽이었다
세션이 질문을 하고 기다리면 코어가 보라색으로 바뀌는데, 정작 답하려면 앱을 열어 그 세션을 찾아야 했다. 짧은 지시 하나를 보낼 때도 마찬가지였다. 위젯 안에서 질문에 답하고, 세션에 메시지를 보낼 수 있어야 했다.
질문은 앱 질문 창과 경주를 붙였다
Claude가 선택지 질문을 하면 엔진은 AskUserQuestion 도구를 부르고 앱에 질문 창을 띄운다. 플러그인은 이 도구 호출에 훅을 걸어 질문 내용을 세션 파일로 내보내고, 두 가지를 동시에 기다린다. 앱 질문 창의 답(next(e))과 위젯이 쓴 답 파일이다. 먼저 온 쪽이 이긴다.
const first = await Promise.race([fromApp, fromWidget])
if (first.via === 'widget' && first.answers) {
return { result: { questions: raw, answers: first.answers } } as never
}
return (await fromApp).r
위젯이 이기면 훅이 그 답으로 도구 호출을 끝낸다. 앱 쪽이 먼저 답하면 위젯의 대기는 그 신호를 보고 멈춘다. 그래서 어느 쪽에서 답해도 된다.
메시지는 위젯이 들고 있다

세션을 누르면 패널 옆에 채팅 카드가 열린다. 보낸 메시지는 플러그인이 $.prompt.submit({ text, asUser: true })로 세션에 넣는다. 최근 대화는 $.session.messages()로 읽어 파일로 내보내는데, 대화가 길면 매번 읽기 부담스러워서 채팅 카드가 열려 있을 때만 읽는다. 위젯이 카드를 연 동안 2초마다 감시 파일을 고쳐 쓰고, 플러그인은 그 파일이 최근에 바뀐 세션만 대화를 내보낸다.
여러 개를 미리 보내도 하나씩 넘어간다. 앞의 메시지로 세션이 다시 일을 시작하면 나머지는 그 작업이 끝날 때까지 다시 기다린다. 넘긴 직후 세션 상태가 아직 작업 중으로 바뀌기 전이라 다음 메시지가 연달아 넘어가는 일이 있어서, 넘긴 뒤 4초는 다음 메시지를 붙잡아 둔다.
감수한 것
위젯에서 보낸 메시지는 사람이 입력한 것처럼 들어가지만, 대화 기록에는 플러그인이 보낸 것으로 남는다. 대기 중인 메시지는 위젯 메모리에만 있어서 위젯을 다시 띄우면 사라진다.