@pi9/ask 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi9/ask",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Preview-rich, replayable Pi questions with multi-select and comments.",
5
5
  "license": "MIT",
6
6
  "author": "Chase Cummings <chaseecummings@gmail.com>",
package/src/component.ts CHANGED
@@ -34,6 +34,7 @@ import {
34
34
  type ViewportOverflow,
35
35
  } from "./viewport.js";
36
36
  import type { Ask, AskAnswer } from "./domain.js";
37
+ import { CHECKED_BOX, EMPTY_BOX } from "./glyphs.js";
37
38
 
38
39
  const FRAME_WIDE_PREVIEW = true; // Set to false to compare the same layout without its outer frame.
39
40
 
@@ -368,36 +369,37 @@ export class AskComponent implements Component, Focusable {
368
369
  addWrappedWithPrefix(lines, prefix, styled, width);
369
370
  };
370
371
 
372
+ const multiple = this.questionnaireState.config.allowMultiple;
371
373
  let focus: FocusRange | undefined;
372
374
  for (const [index, row] of this.questionnaireState.rows.entries()) {
373
375
  if (row.kind === "submit") continue;
374
376
  const selected = this.questionnaireState.highlightedRow === index;
375
377
  const start = lines.length;
376
378
  const marker = selected ? this.config.theme.fg("accent", "┃ ") : " ";
379
+ const checked = row.kind === "option"
380
+ ? this.questionnaireState.checked.has(row.index)
381
+ : this.questionnaireState.freeformChecked;
382
+ const checkboxColor = checked ? "success" : selected ? "text" : "muted";
383
+ const checkbox = multiple
384
+ ? `${this.config.theme.fg(checkboxColor, checked ? CHECKED_BOX : EMPTY_BOX)} `
385
+ : "";
377
386
 
378
387
  if (row.kind === "option") {
379
388
  const source = row.option;
380
- const checked = this.questionnaireState.checked.has(row.index);
381
- const badge = this.questionnaireState.config.allowMultiple && checked
382
- ? this.config.theme.fg("success", " [selected]")
383
- : "";
384
389
  const comment = this.questionnaireState.comments.has(row.index)
385
390
  ? this.config.theme.fg("warning", " ✎")
386
391
  : "";
387
- addPrefixed(marker, `${source.label}${badge}${comment}`, selected ? "accent" : "text");
388
- if (source.description) addPrefixed(" ", source.description, "muted");
392
+ addPrefixed(`${marker}${checkbox}`, `${source.label}${comment}`, selected ? "accent" : "text");
393
+ if (source.description) addPrefixed(multiple ? " " : " ", source.description, "muted");
389
394
  if (selected) {
390
395
  const commentText = this.questionnaireState.comments.get(row.index);
391
- if (commentText) addPrefixed(" ", `✎ ${commentText}`, "dim");
396
+ if (commentText) addPrefixed(multiple ? " " : " ", `✎ ${commentText}`, "dim");
392
397
  }
393
398
  } else {
394
- const badge = this.questionnaireState.config.allowMultiple && this.questionnaireState.freeformChecked
395
- ? this.config.theme.fg("success", " [selected]")
396
- : "";
397
399
  const suffix = this.questionnaireState.freeformDraft
398
400
  ? ` — ${this.questionnaireState.freeformDraft}`
399
401
  : "";
400
- addPrefixed(marker, `Type a response…${suffix}${badge}`, selected ? "accent" : "text");
402
+ addPrefixed(`${marker}${checkbox}`, `Type a response…${suffix}`, selected ? "accent" : "text");
401
403
  }
402
404
  if (selected) focus = { start, end: lines.length };
403
405
  afterRow?.(row);
package/src/index.ts CHANGED
@@ -159,7 +159,7 @@ export default function askExtension(pi: ExtensionAPI) {
159
159
  try {
160
160
  const answer = await launchQuestionnaire(ctx, resolution.ask, deadline.signal);
161
161
  if (!answer) return;
162
- const message = buildAskReplayMessage(resolution.toolCallId, answer);
162
+ const message = buildAskReplayMessage(resolution.toolCallId, resolution.ask, answer);
163
163
  pi.sendMessage(message, { triggerTurn: true, deliverAs: "followUp" });
164
164
  applyRevision(message.details.toolCallId, message.details.answer);
165
165
  replayState = { status: "dispatched", details: message.details };
package/src/session.ts CHANGED
@@ -9,6 +9,7 @@ import {
9
9
  AskAnsweredDetailsSchema,
10
10
  AskParamsSchema,
11
11
  answerMatchesAsk,
12
+ formatAskAnswer,
12
13
  normalizeAsk,
13
14
  parseAskReplayDetails,
14
15
  type Ask,
@@ -48,7 +49,7 @@ type AskSummaryPayload = {
48
49
 
49
50
  export type AskReplayMessage = {
50
51
  customType: typeof ASK_REPLAY_CUSTOM_TYPE;
51
- content: "";
52
+ content: string;
52
53
  display: false;
53
54
  details: AskReplayDetails;
54
55
  };
@@ -60,10 +61,10 @@ export type AskReplayResolution =
60
61
  reason: "no-entry" | "not-assistant" | "not-ask" | "multiple-tool-calls" | "mixed-tools" | "invalid-arguments";
61
62
  };
62
63
 
63
- export function buildAskReplayMessage(toolCallId: string, answer: AskAnswer): AskReplayMessage {
64
+ export function buildAskReplayMessage(toolCallId: string, ask: Ask, answer: AskAnswer): AskReplayMessage {
64
65
  return {
65
66
  customType: ASK_REPLAY_CUSTOM_TYPE,
66
- content: "",
67
+ content: formatAskAnswer(ask, answer),
67
68
  display: false,
68
69
  details: { toolCallId, answer },
69
70
  };