@dataimago/interview 0.2.0-alpha.0

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.
@@ -0,0 +1,225 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface Props$3 {
4
+ current: number;
5
+ total: number;
6
+ estimatedMinutesRemaining: number;
7
+ }
8
+ /**
9
+ * Linear progress indicator for the interview flow. Renders the
10
+ * "Question N of M" caption, the estimated minutes remaining, and a
11
+ * forest-700 fill bar at `(current / total) * 100%`.
12
+ *
13
+ * Iteration-1 visual identity (Phase B.2, 2026-05-06):
14
+ * stone-100 surface with stone-200 border; forest-700 fill bar; stone-700
15
+ * caption text. Pure-render component — no state-management dependency.
16
+ *
17
+ * Extracted from `apps/hub/src/components/interview/ProgressBar.tsx`
18
+ * during iteration-3-B.1 (2026-05-07). No prop API change.
19
+ */
20
+ declare function ProgressBar({ current, total, estimatedMinutesRemaining }: Props$3): react_jsx_runtime.JSX.Element;
21
+
22
+ /**
23
+ * @dataimago/interview — schema contract.
24
+ *
25
+ * The types in this file are the package's public contract. Consumers
26
+ * (apps/hub during the iteration-3-B.1 transition; dissertation-ai +
27
+ * sgpc-ai + rpkg-ai once they consume the package) populate the actual
28
+ * question content conforming to these shapes; the components in this
29
+ * package render whatever the consumer provides.
30
+ *
31
+ * Extracted from `apps/hub/src/lib/interview-questions.ts` (the
32
+ * `InterviewQuestion` + `QuestionInputType` definitions) and
33
+ * `apps/hub/src/lib/interview-store.ts` (the `InterviewAnswers`
34
+ * record) during iteration-3-B.1 (2026-05-07).
35
+ *
36
+ * Design authority: `dataimago-design/wiki/patterns/onboarding-interview.md`.
37
+ */
38
+ /**
39
+ * The set of input shapes the interview engine knows how to render.
40
+ *
41
+ * - `short-text` — single-line text field
42
+ * - `long-text` — multi-line textarea
43
+ * - `select` — single-choice radio group with `options[]`
44
+ * - `multi-select` — multi-choice checkbox group with `options[]`
45
+ * - `scale` — numeric slider 1–N (consumer specifies range via `options[]`
46
+ * labels; engine renders as a horizontal scale)
47
+ * - `list` — variable-length list of short-text items, bounded by `listRange`
48
+ */
49
+ type QuestionInputType = 'short-text' | 'long-text' | 'select' | 'multi-select' | 'scale' | 'list';
50
+ /**
51
+ * A single question in an interview flow. Consumers provide an array of
52
+ * these to drive the engine.
53
+ *
54
+ * The `generates` field is consumer-specific metadata (e.g.,
55
+ * "wiki/overview.md intro" or "CLAUDE.md project description") — the engine
56
+ * doesn't interpret it; it's preserved through the answer collection pipeline
57
+ * for the consumer's downstream generators (e.g., `@dataimago/onboarding-engine`).
58
+ */
59
+ interface InterviewQuestion {
60
+ /** Stable unique identifier; used as the answer-record key. */
61
+ id: string;
62
+ /** Render order (1-based, ascending). */
63
+ order: number;
64
+ /** The primary question prompt. */
65
+ prompt: string;
66
+ /** Optional secondary explanation shown below the prompt. */
67
+ subprompt?: string;
68
+ /** Optional concrete examples shown in a disclosure under the prompt. */
69
+ examples?: string[];
70
+ /** Which input shape to render. */
71
+ inputType: QuestionInputType;
72
+ /** Required for select / multi-select / scale; ignored for other types. */
73
+ options?: Array<{
74
+ value: string;
75
+ label: string;
76
+ description?: string;
77
+ }>;
78
+ /** Whether the consumer can advance without an answer. */
79
+ required: boolean;
80
+ /** Optional explanation shown when the user attempts to skip. */
81
+ skipConsequence?: string;
82
+ /**
83
+ * Consumer-specific metadata: which downstream artifacts (wiki pages,
84
+ * template placeholders) this answer populates. Engine-opaque; preserved
85
+ * through to the consumer's generator pipeline.
86
+ */
87
+ generates: string[];
88
+ /** Min/max items for `inputType: 'list'` questions; ignored otherwise. */
89
+ listRange?: {
90
+ min: number;
91
+ max: number;
92
+ };
93
+ }
94
+ /**
95
+ * The runtime answer record. Keys are `InterviewQuestion.id`; values are
96
+ * either the answer string (for short-text, long-text, select, scale) or
97
+ * an array of strings (for multi-select, list).
98
+ *
99
+ * Consumers manage their own state container (Zustand, Redux, server-side
100
+ * session, etc.) and pass the relevant slice into the components as props.
101
+ * The engine is state-management-agnostic.
102
+ */
103
+ type InterviewAnswers = Record<string, string | string[]>;
104
+
105
+ interface Props$2 {
106
+ question: InterviewQuestion;
107
+ /**
108
+ * The currently-saved answer for this question (from the consumer's
109
+ * state container). The component initializes its local form state
110
+ * from this value and re-syncs when the question id changes.
111
+ */
112
+ existingAnswer?: string | string[];
113
+ /**
114
+ * Called when the user submits a non-empty answer (or any answer if
115
+ * the question is `required: false`). The consumer is expected to
116
+ * persist the answer into its state container and then advance via
117
+ * `onNext`.
118
+ */
119
+ onAnswerSubmit: (questionId: string, value: string | string[]) => void;
120
+ /** Called after `onAnswerSubmit` to advance to the next question. */
121
+ onNext: () => void;
122
+ /** Called when the user clicks the Back button. */
123
+ onBack: () => void;
124
+ isFirst: boolean;
125
+ isLast: boolean;
126
+ }
127
+ /**
128
+ * Single question renderer. Handles all input types: short-text, long-text,
129
+ * select, multi-select, scale, list. Keyboard-navigable and screen-reader
130
+ * safe.
131
+ *
132
+ * **Decoupled from any state-management library.** The original
133
+ * apps/hub implementation imported `useInterviewStore` directly; this
134
+ * extracted version receives the existing answer + change handler as
135
+ * props, leaving the consumer free to use Zustand, Redux, useState,
136
+ * server-side session state, or any other approach.
137
+ *
138
+ * Iteration-1 visual identity (Phase B.2, 2026-05-06):
139
+ * Form input fields use stone-50 elevated surface + stone-200 default border
140
+ * + forest-700 focus border (interactive-primary focus indicator). Selected
141
+ * radio/checkbox option states use forest-700 border + forest-50 background.
142
+ * The examples disclosure has its border-l-2 frame preserved as
143
+ * border-copper-200 — same decorative-emphasis role as HeroSection's
144
+ * etymology box and ReviewSummary's "what happens next" callout, per
145
+ * iteration-1 §5.2's preserved-decorative-copper governance.
146
+ *
147
+ * Iteration-2 role-shift (2026-05-07): copper is no longer the brand-accent
148
+ * moral-weight scale (the brand accent moved to sky-blue accent-500 #1f618d).
149
+ * Copper survives as the "warm decorative framing on the editorial scale" —
150
+ * a distinct decorative palette, not subordinate to the brand accent. The
151
+ * border-copper-200 site below continues to serve its visual role (warm
152
+ * framing for examples-list editorial content); its semantic relationship
153
+ * to the brand accent is now zero. See wiki/decisions/iteration-2-blue-accent.md.
154
+ *
155
+ * Extracted from `apps/hub/src/components/interview/QuestionCard.tsx`
156
+ * during iteration-3-B.1 (2026-05-07). Decoupled from `useInterviewStore`.
157
+ */
158
+ declare function QuestionCard({ question, existingAnswer, onAnswerSubmit, onNext, onBack, isFirst, isLast, }: Props$2): react_jsx_runtime.JSX.Element;
159
+
160
+ interface Props$1 {
161
+ questions: InterviewQuestion[];
162
+ currentIndex: number;
163
+ /** Consumer's current answer record (read-only — engine doesn't write). */
164
+ answers: InterviewAnswers;
165
+ /** Called when the user clicks a sidebar item to jump to that question. */
166
+ onSelectQuestion: (index: number) => void;
167
+ }
168
+ /**
169
+ * Sidebar showing all answered questions. Clicking any returns to edit that
170
+ * question without losing later answers. Implements the wiki's pattern:
171
+ * "Edit any prior answer — a sidebar shows all answered questions."
172
+ *
173
+ * **Decoupled from any state-management library.** The original
174
+ * apps/hub implementation imported `useInterviewStore` directly; this
175
+ * extracted version receives the answers + jump handler as props.
176
+ *
177
+ * Iteration-1 visual identity (Phase B.2, 2026-05-06):
178
+ * Three item states with distinct token tiers:
179
+ * - current → forest-700 border + forest-50 bg (interactive primary)
180
+ * - answered → stone-200 border + stone-50 bg (default, hover stone-400)
181
+ * - unanswered → stone-200/50 + stone-50/50 (muted via opacity preservation)
182
+ *
183
+ * Extracted from `apps/hub/src/components/interview/AnswerSidebar.tsx`
184
+ * during iteration-3-B.1 (2026-05-07). Decoupled from `useInterviewStore`.
185
+ */
186
+ declare function AnswerSidebar({ questions, currentIndex, answers, onSelectQuestion }: Props$1): react_jsx_runtime.JSX.Element;
187
+
188
+ interface Props {
189
+ questions: InterviewQuestion[];
190
+ /** Consumer's current answer record (read-only — engine doesn't write). */
191
+ answers: InterviewAnswers;
192
+ onGenerate: () => void;
193
+ onEdit: (questionIndex: number) => void;
194
+ generating: boolean;
195
+ }
196
+ /**
197
+ * Final review screen — the penultimate step before generation.
198
+ * Shows all answers so the user can confirm ownership of the output before
199
+ * committing.
200
+ *
201
+ * **Decoupled from any state-management library.** The original
202
+ * apps/hub implementation imported `useInterviewStore` directly; this
203
+ * extracted version receives the answer record as a prop.
204
+ *
205
+ * Iteration-1 visual identity (Phase B.2, 2026-05-06):
206
+ * Editorial Josefin display family on the heading and the "What happens next"
207
+ * callout title. Stone-tier surfaces and content text throughout. The
208
+ * "What happens next" callout box preserves border-copper-300 + bg-copper-50 —
209
+ * iteration-1 §5.2's preserved-decorative-copper role applied to the
210
+ * informational/forward-looking callout, same pattern as HeroSection's
211
+ * etymology box.
212
+ *
213
+ * Iteration-2 role-shift (2026-05-07): copper is no longer subordinate to
214
+ * the brand accent (which moved to sky-blue accent-500 #1f618d). Copper is
215
+ * its own "warm decorative framing on the editorial scale" — distinct from
216
+ * the brand-accent role. The "What happens next" callout continues to serve
217
+ * its visual function (warm forward-looking framing); its semantic relation
218
+ * to the brand accent is now zero. See wiki/decisions/iteration-2-blue-accent.md.
219
+ *
220
+ * Extracted from `apps/hub/src/components/interview/ReviewSummary.tsx`
221
+ * during iteration-3-B.1 (2026-05-07). Decoupled from `useInterviewStore`.
222
+ */
223
+ declare function ReviewSummary({ questions, answers, onGenerate, onEdit, generating }: Props): react_jsx_runtime.JSX.Element;
224
+
225
+ export { AnswerSidebar, type InterviewAnswers, type InterviewQuestion, ProgressBar, QuestionCard, type QuestionInputType, ReviewSummary };
@@ -0,0 +1,225 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface Props$3 {
4
+ current: number;
5
+ total: number;
6
+ estimatedMinutesRemaining: number;
7
+ }
8
+ /**
9
+ * Linear progress indicator for the interview flow. Renders the
10
+ * "Question N of M" caption, the estimated minutes remaining, and a
11
+ * forest-700 fill bar at `(current / total) * 100%`.
12
+ *
13
+ * Iteration-1 visual identity (Phase B.2, 2026-05-06):
14
+ * stone-100 surface with stone-200 border; forest-700 fill bar; stone-700
15
+ * caption text. Pure-render component — no state-management dependency.
16
+ *
17
+ * Extracted from `apps/hub/src/components/interview/ProgressBar.tsx`
18
+ * during iteration-3-B.1 (2026-05-07). No prop API change.
19
+ */
20
+ declare function ProgressBar({ current, total, estimatedMinutesRemaining }: Props$3): react_jsx_runtime.JSX.Element;
21
+
22
+ /**
23
+ * @dataimago/interview — schema contract.
24
+ *
25
+ * The types in this file are the package's public contract. Consumers
26
+ * (apps/hub during the iteration-3-B.1 transition; dissertation-ai +
27
+ * sgpc-ai + rpkg-ai once they consume the package) populate the actual
28
+ * question content conforming to these shapes; the components in this
29
+ * package render whatever the consumer provides.
30
+ *
31
+ * Extracted from `apps/hub/src/lib/interview-questions.ts` (the
32
+ * `InterviewQuestion` + `QuestionInputType` definitions) and
33
+ * `apps/hub/src/lib/interview-store.ts` (the `InterviewAnswers`
34
+ * record) during iteration-3-B.1 (2026-05-07).
35
+ *
36
+ * Design authority: `dataimago-design/wiki/patterns/onboarding-interview.md`.
37
+ */
38
+ /**
39
+ * The set of input shapes the interview engine knows how to render.
40
+ *
41
+ * - `short-text` — single-line text field
42
+ * - `long-text` — multi-line textarea
43
+ * - `select` — single-choice radio group with `options[]`
44
+ * - `multi-select` — multi-choice checkbox group with `options[]`
45
+ * - `scale` — numeric slider 1–N (consumer specifies range via `options[]`
46
+ * labels; engine renders as a horizontal scale)
47
+ * - `list` — variable-length list of short-text items, bounded by `listRange`
48
+ */
49
+ type QuestionInputType = 'short-text' | 'long-text' | 'select' | 'multi-select' | 'scale' | 'list';
50
+ /**
51
+ * A single question in an interview flow. Consumers provide an array of
52
+ * these to drive the engine.
53
+ *
54
+ * The `generates` field is consumer-specific metadata (e.g.,
55
+ * "wiki/overview.md intro" or "CLAUDE.md project description") — the engine
56
+ * doesn't interpret it; it's preserved through the answer collection pipeline
57
+ * for the consumer's downstream generators (e.g., `@dataimago/onboarding-engine`).
58
+ */
59
+ interface InterviewQuestion {
60
+ /** Stable unique identifier; used as the answer-record key. */
61
+ id: string;
62
+ /** Render order (1-based, ascending). */
63
+ order: number;
64
+ /** The primary question prompt. */
65
+ prompt: string;
66
+ /** Optional secondary explanation shown below the prompt. */
67
+ subprompt?: string;
68
+ /** Optional concrete examples shown in a disclosure under the prompt. */
69
+ examples?: string[];
70
+ /** Which input shape to render. */
71
+ inputType: QuestionInputType;
72
+ /** Required for select / multi-select / scale; ignored for other types. */
73
+ options?: Array<{
74
+ value: string;
75
+ label: string;
76
+ description?: string;
77
+ }>;
78
+ /** Whether the consumer can advance without an answer. */
79
+ required: boolean;
80
+ /** Optional explanation shown when the user attempts to skip. */
81
+ skipConsequence?: string;
82
+ /**
83
+ * Consumer-specific metadata: which downstream artifacts (wiki pages,
84
+ * template placeholders) this answer populates. Engine-opaque; preserved
85
+ * through to the consumer's generator pipeline.
86
+ */
87
+ generates: string[];
88
+ /** Min/max items for `inputType: 'list'` questions; ignored otherwise. */
89
+ listRange?: {
90
+ min: number;
91
+ max: number;
92
+ };
93
+ }
94
+ /**
95
+ * The runtime answer record. Keys are `InterviewQuestion.id`; values are
96
+ * either the answer string (for short-text, long-text, select, scale) or
97
+ * an array of strings (for multi-select, list).
98
+ *
99
+ * Consumers manage their own state container (Zustand, Redux, server-side
100
+ * session, etc.) and pass the relevant slice into the components as props.
101
+ * The engine is state-management-agnostic.
102
+ */
103
+ type InterviewAnswers = Record<string, string | string[]>;
104
+
105
+ interface Props$2 {
106
+ question: InterviewQuestion;
107
+ /**
108
+ * The currently-saved answer for this question (from the consumer's
109
+ * state container). The component initializes its local form state
110
+ * from this value and re-syncs when the question id changes.
111
+ */
112
+ existingAnswer?: string | string[];
113
+ /**
114
+ * Called when the user submits a non-empty answer (or any answer if
115
+ * the question is `required: false`). The consumer is expected to
116
+ * persist the answer into its state container and then advance via
117
+ * `onNext`.
118
+ */
119
+ onAnswerSubmit: (questionId: string, value: string | string[]) => void;
120
+ /** Called after `onAnswerSubmit` to advance to the next question. */
121
+ onNext: () => void;
122
+ /** Called when the user clicks the Back button. */
123
+ onBack: () => void;
124
+ isFirst: boolean;
125
+ isLast: boolean;
126
+ }
127
+ /**
128
+ * Single question renderer. Handles all input types: short-text, long-text,
129
+ * select, multi-select, scale, list. Keyboard-navigable and screen-reader
130
+ * safe.
131
+ *
132
+ * **Decoupled from any state-management library.** The original
133
+ * apps/hub implementation imported `useInterviewStore` directly; this
134
+ * extracted version receives the existing answer + change handler as
135
+ * props, leaving the consumer free to use Zustand, Redux, useState,
136
+ * server-side session state, or any other approach.
137
+ *
138
+ * Iteration-1 visual identity (Phase B.2, 2026-05-06):
139
+ * Form input fields use stone-50 elevated surface + stone-200 default border
140
+ * + forest-700 focus border (interactive-primary focus indicator). Selected
141
+ * radio/checkbox option states use forest-700 border + forest-50 background.
142
+ * The examples disclosure has its border-l-2 frame preserved as
143
+ * border-copper-200 — same decorative-emphasis role as HeroSection's
144
+ * etymology box and ReviewSummary's "what happens next" callout, per
145
+ * iteration-1 §5.2's preserved-decorative-copper governance.
146
+ *
147
+ * Iteration-2 role-shift (2026-05-07): copper is no longer the brand-accent
148
+ * moral-weight scale (the brand accent moved to sky-blue accent-500 #1f618d).
149
+ * Copper survives as the "warm decorative framing on the editorial scale" —
150
+ * a distinct decorative palette, not subordinate to the brand accent. The
151
+ * border-copper-200 site below continues to serve its visual role (warm
152
+ * framing for examples-list editorial content); its semantic relationship
153
+ * to the brand accent is now zero. See wiki/decisions/iteration-2-blue-accent.md.
154
+ *
155
+ * Extracted from `apps/hub/src/components/interview/QuestionCard.tsx`
156
+ * during iteration-3-B.1 (2026-05-07). Decoupled from `useInterviewStore`.
157
+ */
158
+ declare function QuestionCard({ question, existingAnswer, onAnswerSubmit, onNext, onBack, isFirst, isLast, }: Props$2): react_jsx_runtime.JSX.Element;
159
+
160
+ interface Props$1 {
161
+ questions: InterviewQuestion[];
162
+ currentIndex: number;
163
+ /** Consumer's current answer record (read-only — engine doesn't write). */
164
+ answers: InterviewAnswers;
165
+ /** Called when the user clicks a sidebar item to jump to that question. */
166
+ onSelectQuestion: (index: number) => void;
167
+ }
168
+ /**
169
+ * Sidebar showing all answered questions. Clicking any returns to edit that
170
+ * question without losing later answers. Implements the wiki's pattern:
171
+ * "Edit any prior answer — a sidebar shows all answered questions."
172
+ *
173
+ * **Decoupled from any state-management library.** The original
174
+ * apps/hub implementation imported `useInterviewStore` directly; this
175
+ * extracted version receives the answers + jump handler as props.
176
+ *
177
+ * Iteration-1 visual identity (Phase B.2, 2026-05-06):
178
+ * Three item states with distinct token tiers:
179
+ * - current → forest-700 border + forest-50 bg (interactive primary)
180
+ * - answered → stone-200 border + stone-50 bg (default, hover stone-400)
181
+ * - unanswered → stone-200/50 + stone-50/50 (muted via opacity preservation)
182
+ *
183
+ * Extracted from `apps/hub/src/components/interview/AnswerSidebar.tsx`
184
+ * during iteration-3-B.1 (2026-05-07). Decoupled from `useInterviewStore`.
185
+ */
186
+ declare function AnswerSidebar({ questions, currentIndex, answers, onSelectQuestion }: Props$1): react_jsx_runtime.JSX.Element;
187
+
188
+ interface Props {
189
+ questions: InterviewQuestion[];
190
+ /** Consumer's current answer record (read-only — engine doesn't write). */
191
+ answers: InterviewAnswers;
192
+ onGenerate: () => void;
193
+ onEdit: (questionIndex: number) => void;
194
+ generating: boolean;
195
+ }
196
+ /**
197
+ * Final review screen — the penultimate step before generation.
198
+ * Shows all answers so the user can confirm ownership of the output before
199
+ * committing.
200
+ *
201
+ * **Decoupled from any state-management library.** The original
202
+ * apps/hub implementation imported `useInterviewStore` directly; this
203
+ * extracted version receives the answer record as a prop.
204
+ *
205
+ * Iteration-1 visual identity (Phase B.2, 2026-05-06):
206
+ * Editorial Josefin display family on the heading and the "What happens next"
207
+ * callout title. Stone-tier surfaces and content text throughout. The
208
+ * "What happens next" callout box preserves border-copper-300 + bg-copper-50 —
209
+ * iteration-1 §5.2's preserved-decorative-copper role applied to the
210
+ * informational/forward-looking callout, same pattern as HeroSection's
211
+ * etymology box.
212
+ *
213
+ * Iteration-2 role-shift (2026-05-07): copper is no longer subordinate to
214
+ * the brand accent (which moved to sky-blue accent-500 #1f618d). Copper is
215
+ * its own "warm decorative framing on the editorial scale" — distinct from
216
+ * the brand-accent role. The "What happens next" callout continues to serve
217
+ * its visual function (warm forward-looking framing); its semantic relation
218
+ * to the brand accent is now zero. See wiki/decisions/iteration-2-blue-accent.md.
219
+ *
220
+ * Extracted from `apps/hub/src/components/interview/ReviewSummary.tsx`
221
+ * during iteration-3-B.1 (2026-05-07). Decoupled from `useInterviewStore`.
222
+ */
223
+ declare function ReviewSummary({ questions, answers, onGenerate, onEdit, generating }: Props): react_jsx_runtime.JSX.Element;
224
+
225
+ export { AnswerSidebar, type InterviewAnswers, type InterviewQuestion, ProgressBar, QuestionCard, type QuestionInputType, ReviewSummary };