pi-interview 0.4.5 → 0.5.2

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/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # Interview Tool
6
6
 
7
- A custom tool for pi-agent that opens a web-based form to gather user responses to clarification questions.
7
+ A custom tool for pi-agent that opens an interactive form to gather user responses to clarification questions. On macOS, uses [Glimpse](https://github.com/hazat/glimpse) to render in a native WKWebView window; falls back to a browser tab on other platforms.
8
8
 
9
9
  https://github.com/user-attachments/assets/52285bd9-956e-4020-aca5-9fbd82916934
10
10
 
@@ -18,10 +18,14 @@ Restart pi to load the extension.
18
18
 
19
19
  **Requirements:**
20
20
  - pi-agent v0.35.0 or later (extensions API)
21
+ - For native macOS window: `pi install npm:glimpseui` (optional, falls back to browser if not installed)
21
22
 
22
23
  ## Features
23
24
 
24
- - **Question Types**: Single-select, multi-select, text input, and image upload
25
+ - **Question Types**: Single-select, multi-select, text input, image upload, and info panels
26
+ - **Rich Media**: Embed images, Chart.js charts, Mermaid diagrams, tables, and HTML in questions
27
+ - **Pre-selection**: Recommended options show a "Recommended" badge and are pre-checked on load
28
+ - **Conviction & Weight**: Control recommendation strength (`conviction`) and visual prominence (`weight`)
25
29
  - **"Other" Option**: Single/multi select questions support custom text input
26
30
  - **Per-Question Attachments**: Attach images to any question via button, paste, or drag & drop
27
31
  - **Keyboard Navigation**: Full keyboard support with arrow keys, Tab, Enter
@@ -40,7 +44,7 @@ Restart pi to load the extension.
40
44
 
41
45
  ```
42
46
  ┌─────────┐ ┌──────────────────────────────────────────┐ ┌─────────┐
43
- │ Agent │ │ Browser Form │ │ Agent │
47
+ │ Agent │ │ Glimpse / Browser Form │ │ Agent │
44
48
  │ invokes ├─────►│ ├─────►│receives │
45
49
  │interview│ │ answer → answer → attach img → answer │ │responses│
46
50
  └─────────┘ │ ↑ │ └─────────┘
@@ -49,7 +53,7 @@ Restart pi to load the extension.
49
53
  ```
50
54
 
51
55
  **Lifecycle:**
52
- 1. Agent calls `interview()` → local server starts → browser opens form
56
+ 1. Agent calls `interview()` → local server starts → Glimpse window opens (macOS) or browser tab (elsewhere)
53
57
  2. User answers at their own pace; each change auto-saves and resets the timeout
54
58
  3. Session ends via:
55
59
  - **Submit** (`⌘+Enter`) → responses returned to agent
@@ -59,7 +63,7 @@ Restart pi to load the extension.
59
63
 
60
64
  **Timeout behavior:** The countdown (visible in corner) resets on any activity - typing, clicking, or mouse movement. When it expires, an overlay appears giving the user a chance to continue. Progress is never lost thanks to localStorage auto-save.
61
65
 
62
- **Multi-agent behavior:** When multiple agents run interviews simultaneously, only the first auto-opens the browser. Subsequent interviews are queued and shown as a URL in the tool output, preventing focus stealing. Active interviews also surface a top-right toast with a dropdown to open queued sessions. A session status bar at the top of each form shows the project path, git branch, and session ID for easy identification.
66
+ **Multi-agent behavior:** When multiple agents run interviews simultaneously, only the first auto-opens the window. Subsequent interviews are queued and shown as a URL in the tool output, preventing focus stealing. Active interviews also surface a top-right toast with a dropdown to open queued sessions. A session status bar at the top of each form shows the project path, git branch, and session ID for easy identification.
63
67
 
64
68
  ## Usage
65
69
 
@@ -79,14 +83,22 @@ await interview({
79
83
  ```json
80
84
  {
81
85
  "title": "Project Setup",
82
- "description": "Optional description text",
86
+ "description": "Review my suggestions and adjust as needed.",
83
87
  "questions": [
88
+ {
89
+ "id": "context",
90
+ "type": "info",
91
+ "question": "Architecture context",
92
+ "context": "This project needs SSR and edge deployment support."
93
+ },
84
94
  {
85
95
  "id": "framework",
86
96
  "type": "single",
87
97
  "question": "Which framework?",
88
98
  "options": ["React", "Vue", "Svelte"],
89
- "recommended": "React"
99
+ "recommended": "React",
100
+ "conviction": "strong",
101
+ "weight": "critical"
90
102
  },
91
103
  {
92
104
  "id": "features",
@@ -96,6 +108,14 @@ await interview({
96
108
  "options": ["Auth", "Database", "API"],
97
109
  "recommended": ["Auth", "Database"]
98
110
  },
111
+ {
112
+ "id": "indent",
113
+ "type": "single",
114
+ "question": "Indent style?",
115
+ "options": ["Tabs", "Spaces (2)", "Spaces (4)"],
116
+ "recommended": "Spaces (2)",
117
+ "weight": "minor"
118
+ },
99
119
  {
100
120
  "id": "notes",
101
121
  "type": "text",
@@ -115,12 +135,15 @@ await interview({
115
135
  | Field | Type | Description |
116
136
  |-------|------|-------------|
117
137
  | `id` | string | Unique identifier |
118
- | `type` | string | `single`, `multi`, `text`, or `image` |
138
+ | `type` | string | `single`, `multi`, `text`, `image`, or `info` |
119
139
  | `question` | string | Question text |
120
140
  | `options` | string[] or object[] | Choices (required for single/multi). Can be strings or `{ label, code? }` objects |
121
- | `recommended` | string or string[] | Highlighted option(s) with `*` indicator |
141
+ | `recommended` | string or string[] | Shows "Recommended" badge and pre-selects option(s) |
142
+ | `conviction` | string | `"strong"` or `"slight"`. Slight opts out of pre-selection. Requires `recommended` |
143
+ | `weight` | string | `"critical"` (prominent card) or `"minor"` (compact card) |
122
144
  | `context` | string | Help text shown below question |
123
145
  | `codeBlock` | object | Code block displayed below question text |
146
+ | `media` | object or object[] | Media content: image, chart, mermaid, table, or html |
124
147
 
125
148
  ### Code Blocks
126
149
 
@@ -182,6 +205,64 @@ Questions and options can include code blocks for displaying code snippets, diff
182
205
 
183
206
  Line numbers are shown when `file` or `lines` is specified. Diff syntax (`+`/`-` lines) is automatically styled when `lang` is "diff".
184
207
 
208
+ ### Info Panels
209
+
210
+ Use `type: "info"` for non-interactive context panels. They display a title, context text, and optional media but have no input — they're skipped during keyboard navigation and excluded from responses.
211
+
212
+ ```json
213
+ {
214
+ "id": "overview",
215
+ "type": "info",
216
+ "question": "Architecture Overview",
217
+ "context": "The system uses a microservices architecture with three main services.",
218
+ "media": { "type": "mermaid", "mermaid": "graph LR\n A[API] --> B[Auth]\n A --> C[Data]" }
219
+ }
220
+ ```
221
+
222
+ ### Media Blocks
223
+
224
+ Questions can embed media via the `media` field (single object or array). Supported types:
225
+
226
+ | Type | Fields | Description |
227
+ |------|--------|-------------|
228
+ | `image` | `src`, `alt?`, `caption?` | Image (local path, URL, or data URI) |
229
+ | `table` | `table: { headers, rows, highlights? }`, `caption?` | Data table with optional row highlighting |
230
+ | `chart` | `chart: { type, data, options? }`, `caption?` | Chart.js chart (bar, line, pie, etc.) |
231
+ | `mermaid` | `mermaid: "graph LR\n..."`, `caption?` | Mermaid diagram |
232
+ | `html` | `html: "<div>...</div>"`, `caption?` | Raw HTML content |
233
+
234
+ All media types support `position`: `"above"` (default), `"below"`, or `"side"` (two-column layout).
235
+
236
+ ```json
237
+ {
238
+ "id": "db-choice",
239
+ "type": "single",
240
+ "question": "Which database?",
241
+ "media": {
242
+ "type": "table",
243
+ "table": {
244
+ "headers": ["Database", "Latency", "Cost"],
245
+ "rows": [["PostgreSQL", "~5ms", "$50/mo"], ["DynamoDB", "~2ms", "$80/mo"]],
246
+ "highlights": [0]
247
+ },
248
+ "caption": "Benchmark results from staging"
249
+ },
250
+ "options": ["PostgreSQL", "DynamoDB"],
251
+ "recommended": "PostgreSQL"
252
+ }
253
+ ```
254
+
255
+ ### Conviction & Weight
256
+
257
+ **Conviction** controls how strongly a recommendation is presented:
258
+ - Omitted (default): shows "Recommended" badge, pre-selects the option
259
+ - `"strong"`: same as default (use when very confident)
260
+ - `"slight"`: shows "Recommended" badge but does NOT pre-select (use when unsure)
261
+
262
+ **Weight** controls visual prominence:
263
+ - `"critical"`: thick accent border, tinted background — for decisions that matter most
264
+ - `"minor"`: compact card with smaller text and padding — for low-stakes preferences
265
+
185
266
  ## Keyboard Shortcuts
186
267
 
187
268
  | Key | Action |
@@ -240,7 +321,7 @@ The interview form supports light/dark themes with automatic OS detection and us
240
321
  | Theme | Description |
241
322
  |-------|-------------|
242
323
  | `default` | Monospace, IDE-inspired aesthetic |
243
- | `tufte` | Serif fonts (Cormorant Garamond), book-like feel |
324
+ | `tufte` | Serif fonts (Instrument Serif), book-like feel |
244
325
 
245
326
  ### Theme Modes
246
327
 
package/form/index.html CHANGED
@@ -4,6 +4,9 @@
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Interview</title>
7
+ <link rel="preconnect" href="https://fonts.googleapis.com">
8
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
9
+ <link href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700&family=Space+Mono:wght@400;700&family=Instrument+Serif&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
7
10
  <link rel="stylesheet" href="/styles.css?session=__SESSION_TOKEN__">
8
11
  <link rel="stylesheet" href="/theme-light.css?session=__SESSION_TOKEN__" data-theme-link="light" media="(prefers-color-scheme: light)">
9
12
  <link rel="stylesheet" href="/theme-dark.css?session=__SESSION_TOKEN__" data-theme-link="dark" media="(prefers-color-scheme: dark)">
@@ -57,9 +60,8 @@
57
60
  <span class="shortcut-label">Cancel</span>
58
61
  </div>
59
62
  <div class="shortcut-divider"></div>
60
- <div class="shortcut recommended-hint">
61
- <span class="shortcut-keys"><span class="star">*</span></span>
62
- <span class="shortcut-label">Recommended</span>
63
+ <div class="shortcut">
64
+ <span class="recommended-pill">Recommended</span>
63
65
  </div>
64
66
  <div class="shortcut hidden" data-theme-shortcut>
65
67
  <span class="shortcut-keys" data-theme-keys></span>
@@ -115,6 +117,7 @@
115
117
  <div id="save-toast" class="save-toast hidden" aria-live="polite"></div>
116
118
  </main>
117
119
 
120
+ <!-- __CDN_SCRIPTS__ -->
118
121
  <script>
119
122
  window.__INTERVIEW_DATA__ = /* __INTERVIEW_DATA_PLACEHOLDER__ */;
120
123
  </script>