@ishlabs/cli 0.17.6 → 0.18.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.
- package/README.md +54 -54
- package/dist/commands/ask.d.ts +4 -4
- package/dist/commands/ask.js +66 -66
- package/dist/commands/chat.js +10 -10
- package/dist/commands/config.js +1 -1
- package/dist/commands/docs.js +1 -1
- package/dist/commands/iteration.js +57 -57
- package/dist/commands/mcp.d.ts +23 -0
- package/dist/commands/mcp.js +676 -0
- package/dist/commands/person.d.ts +5 -0
- package/dist/commands/{profile.js → person.js} +197 -162
- package/dist/commands/source.d.ts +6 -2
- package/dist/commands/source.js +35 -30
- package/dist/commands/study-analyze.d.ts +1 -1
- package/dist/commands/study-analyze.js +3 -3
- package/dist/commands/study-participant.d.ts +8 -0
- package/dist/commands/{study-tester.js → study-participant.js} +50 -50
- package/dist/commands/study-run.d.ts +6 -6
- package/dist/commands/study-run.js +295 -271
- package/dist/commands/study.js +89 -66
- package/dist/commands/workspace.js +13 -13
- package/dist/connect.js +5 -5
- package/dist/index.js +6 -4
- package/dist/lib/accessibility-profile.d.ts +1 -1
- package/dist/lib/accessibility-profile.js +1 -1
- package/dist/lib/alias-hydrate.js +4 -4
- package/dist/lib/alias-store.d.ts +5 -5
- package/dist/lib/alias-store.js +8 -8
- package/dist/lib/api-client.d.ts +1 -1
- package/dist/lib/api-client.js +1 -1
- package/dist/lib/billing.d.ts +11 -11
- package/dist/lib/billing.js +16 -16
- package/dist/lib/chat-endpoint-templates.js +1 -1
- package/dist/lib/command-helpers.d.ts +18 -18
- package/dist/lib/command-helpers.js +83 -53
- package/dist/lib/docs.js +560 -386
- package/dist/lib/enums.d.ts +2 -2
- package/dist/lib/enums.js +2 -2
- package/dist/lib/local-sim/browser.d.ts +1 -1
- package/dist/lib/local-sim/browser.js +1 -1
- package/dist/lib/local-sim/debug-report.d.ts +2 -2
- package/dist/lib/local-sim/debug-report.js +3 -3
- package/dist/lib/local-sim/loop.d.ts +5 -5
- package/dist/lib/local-sim/loop.js +38 -38
- package/dist/lib/local-sim/types.d.ts +12 -12
- package/dist/lib/mcp-clients.d.ts +51 -0
- package/dist/lib/mcp-clients.js +175 -0
- package/dist/lib/modality.d.ts +10 -10
- package/dist/lib/modality.js +46 -46
- package/dist/lib/observability.d.ts +11 -0
- package/dist/lib/observability.js +16 -3
- package/dist/lib/output.d.ts +13 -12
- package/dist/lib/output.js +244 -184
- package/dist/lib/profile-sources.d.ts +64 -16
- package/dist/lib/profile-sources.js +91 -30
- package/dist/lib/skill-content.js +215 -168
- package/dist/lib/study-events.d.ts +3 -3
- package/dist/lib/study-events.js +1 -1
- package/dist/lib/study-inputs.d.ts +11 -1
- package/dist/lib/study-inputs.js +68 -17
- package/dist/lib/types.d.ts +105 -34
- package/package.json +1 -1
- package/dist/commands/profile.d.ts +0 -5
- package/dist/commands/study-tester.d.ts +0 -8
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SSE consumer for the backend's per-study event stream.
|
|
3
3
|
*
|
|
4
|
-
* Used by `study run --wait` to wake up the poll loop as soon as a
|
|
4
|
+
* Used by `study run --wait` to wake up the poll loop as soon as a participant
|
|
5
5
|
* status / interaction event arrives, instead of waiting for the next poll
|
|
6
6
|
* tick. The canonical truth source remains `GET /studies/{id}` — SSE here
|
|
7
7
|
* only shortens the latency between a backend event and the next status
|
|
@@ -26,11 +26,11 @@ export interface StudyEvent {
|
|
|
26
26
|
type: string;
|
|
27
27
|
study_id: string;
|
|
28
28
|
iteration_id?: string | null;
|
|
29
|
-
|
|
29
|
+
participant_id?: string | null;
|
|
30
30
|
interaction_id?: string | null;
|
|
31
31
|
frame_id?: string | null;
|
|
32
32
|
frame_version_id?: string | null;
|
|
33
|
-
|
|
33
|
+
participant_status?: string | null;
|
|
34
34
|
ts: string;
|
|
35
35
|
seq: number;
|
|
36
36
|
payload?: unknown;
|
package/dist/lib/study-events.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SSE consumer for the backend's per-study event stream.
|
|
3
3
|
*
|
|
4
|
-
* Used by `study run --wait` to wake up the poll loop as soon as a
|
|
4
|
+
* Used by `study run --wait` to wake up the poll loop as soon as a participant
|
|
5
5
|
* status / interaction event arrives, instead of waiting for the next poll
|
|
6
6
|
* tick. The canonical truth source remains `GET /studies/{id}` — SSE here
|
|
7
7
|
* only shortens the latency between a backend event and the next status
|
|
@@ -3,13 +3,23 @@
|
|
|
3
3
|
* flags. Mirrors the loose validation style of `src/lib/ask-questions.ts`.
|
|
4
4
|
*/
|
|
5
5
|
import type { Assignment, InterviewQuestion } from "./types.js";
|
|
6
|
+
/**
|
|
7
|
+
* Validate a parsed array of assignment objects. Shared by the
|
|
8
|
+
* `--assignments-file` and inline `--assignments` paths so both enforce the
|
|
9
|
+
* same shape: each entry needs a non-empty `name` + `instructions`, and an
|
|
10
|
+
* optional `steps` checklist (validated against backend bounds). Response-only
|
|
11
|
+
* keys like `id` / `step_completion` are tolerated and passed through so a
|
|
12
|
+
* `study get --json` payload round-trips back into a create.
|
|
13
|
+
*/
|
|
14
|
+
export declare function validateAssignmentsArray(parsed: unknown, label: string): Assignment[];
|
|
6
15
|
/**
|
|
7
16
|
* Parse `"Name:Instructions"`. Splits on the first `:`, so colons inside
|
|
8
17
|
* the instructions text are preserved.
|
|
9
18
|
*/
|
|
10
19
|
export declare function parseAssignment(value: string): Assignment;
|
|
11
20
|
/**
|
|
12
|
-
* Read a JSON file containing an array of `{name, instructions}`
|
|
21
|
+
* Read a JSON file containing an array of `{name, instructions, steps?}`
|
|
22
|
+
* entries. `steps` is an optional checklist of `{name, description?}` actions.
|
|
13
23
|
*/
|
|
14
24
|
export declare function loadAssignmentsFile(filePath: string): Assignment[];
|
|
15
25
|
/**
|
package/dist/lib/study-inputs.js
CHANGED
|
@@ -4,6 +4,71 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { readFileSync } from "node:fs";
|
|
6
6
|
import { resolve as resolvePath } from "node:path";
|
|
7
|
+
const STEP_NAME_MAX = 80;
|
|
8
|
+
const STEP_DESC_MAX = 500;
|
|
9
|
+
/**
|
|
10
|
+
* Validate an optional `steps` checklist on one assignment. Mirrors the
|
|
11
|
+
* backend bounds (`AssignmentStep`: name 1–80, description ≤500) so authors get
|
|
12
|
+
* a local error instead of a 422. Returns the cleaned step list.
|
|
13
|
+
*/
|
|
14
|
+
function validateSteps(raw, label) {
|
|
15
|
+
if (!Array.isArray(raw)) {
|
|
16
|
+
throw new Error(`${label}.steps must be an array of {name, description?} objects.`);
|
|
17
|
+
}
|
|
18
|
+
return raw.map((entry, j) => {
|
|
19
|
+
const s = entry;
|
|
20
|
+
if (!s || typeof s !== "object") {
|
|
21
|
+
throw new Error(`${label}.steps[${j}] must be an object with a name.`);
|
|
22
|
+
}
|
|
23
|
+
if (typeof s.name !== "string" || !s.name.trim()) {
|
|
24
|
+
throw new Error(`${label}.steps[${j}].name must be a non-empty string.`);
|
|
25
|
+
}
|
|
26
|
+
if (s.name.length > STEP_NAME_MAX) {
|
|
27
|
+
throw new Error(`${label}.steps[${j}].name must be ≤${STEP_NAME_MAX} characters.`);
|
|
28
|
+
}
|
|
29
|
+
if (s.description !== undefined && s.description !== null) {
|
|
30
|
+
if (typeof s.description !== "string") {
|
|
31
|
+
throw new Error(`${label}.steps[${j}].description must be a string.`);
|
|
32
|
+
}
|
|
33
|
+
if (s.description.length > STEP_DESC_MAX) {
|
|
34
|
+
throw new Error(`${label}.steps[${j}].description must be ≤${STEP_DESC_MAX} characters.`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const step = { name: s.name };
|
|
38
|
+
if (typeof s.description === "string")
|
|
39
|
+
step.description = s.description;
|
|
40
|
+
return step;
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Validate a parsed array of assignment objects. Shared by the
|
|
45
|
+
* `--assignments-file` and inline `--assignments` paths so both enforce the
|
|
46
|
+
* same shape: each entry needs a non-empty `name` + `instructions`, and an
|
|
47
|
+
* optional `steps` checklist (validated against backend bounds). Response-only
|
|
48
|
+
* keys like `id` / `step_completion` are tolerated and passed through so a
|
|
49
|
+
* `study get --json` payload round-trips back into a create.
|
|
50
|
+
*/
|
|
51
|
+
export function validateAssignmentsArray(parsed, label) {
|
|
52
|
+
if (!Array.isArray(parsed) || parsed.length === 0) {
|
|
53
|
+
throw new Error(`${label} must be a non-empty JSON array.`);
|
|
54
|
+
}
|
|
55
|
+
for (let i = 0; i < parsed.length; i++) {
|
|
56
|
+
const a = parsed[i];
|
|
57
|
+
if (!a || typeof a !== "object") {
|
|
58
|
+
throw new Error(`assignments[${i}] must be an object with name + instructions.`);
|
|
59
|
+
}
|
|
60
|
+
if (typeof a.name !== "string" || !a.name.trim()) {
|
|
61
|
+
throw new Error(`assignments[${i}].name must be a non-empty string.`);
|
|
62
|
+
}
|
|
63
|
+
if (typeof a.instructions !== "string" || !a.instructions.trim()) {
|
|
64
|
+
throw new Error(`assignments[${i}].instructions must be a non-empty string.`);
|
|
65
|
+
}
|
|
66
|
+
if (a.steps !== undefined && a.steps !== null) {
|
|
67
|
+
a.steps = validateSteps(a.steps, `assignments[${i}]`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return parsed;
|
|
71
|
+
}
|
|
7
72
|
/**
|
|
8
73
|
* Parse `"Name:Instructions"`. Splits on the first `:`, so colons inside
|
|
9
74
|
* the instructions text are preserved.
|
|
@@ -24,7 +89,8 @@ export function parseAssignment(value) {
|
|
|
24
89
|
return { name, instructions };
|
|
25
90
|
}
|
|
26
91
|
/**
|
|
27
|
-
* Read a JSON file containing an array of `{name, instructions}`
|
|
92
|
+
* Read a JSON file containing an array of `{name, instructions, steps?}`
|
|
93
|
+
* entries. `steps` is an optional checklist of `{name, description?}` actions.
|
|
28
94
|
*/
|
|
29
95
|
export function loadAssignmentsFile(filePath) {
|
|
30
96
|
let raw;
|
|
@@ -41,22 +107,7 @@ export function loadAssignmentsFile(filePath) {
|
|
|
41
107
|
catch {
|
|
42
108
|
throw new Error(`Invalid JSON in assignments file: ${filePath}`);
|
|
43
109
|
}
|
|
44
|
-
|
|
45
|
-
throw new Error(`Assignments file must be a non-empty JSON array: ${filePath}`);
|
|
46
|
-
}
|
|
47
|
-
for (let i = 0; i < parsed.length; i++) {
|
|
48
|
-
const a = parsed[i];
|
|
49
|
-
if (!a || typeof a !== "object") {
|
|
50
|
-
throw new Error(`assignments[${i}] must be an object with name + instructions.`);
|
|
51
|
-
}
|
|
52
|
-
if (typeof a.name !== "string" || !a.name.trim()) {
|
|
53
|
-
throw new Error(`assignments[${i}].name must be a non-empty string.`);
|
|
54
|
-
}
|
|
55
|
-
if (typeof a.instructions !== "string" || !a.instructions.trim()) {
|
|
56
|
-
throw new Error(`assignments[${i}].instructions must be a non-empty string.`);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return parsed;
|
|
110
|
+
return validateAssignmentsArray(parsed, `Assignments file ${filePath}`);
|
|
60
111
|
}
|
|
61
112
|
/**
|
|
62
113
|
* Parse a plain question text into a default text-typed, after-timed
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -54,10 +54,46 @@ export interface SecretUpdateInput {
|
|
|
54
54
|
export interface SecretBatchCreateInput {
|
|
55
55
|
secrets: SecretCreateInput[];
|
|
56
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* One atomic, author-supplied action inside an assignment's checklist
|
|
59
|
+
* (e.g. "Add to cart"). Authored via the JSON forms of `study create/update`
|
|
60
|
+
* (`--assignments-file` / `--assignments`) — only for `interactive` and
|
|
61
|
+
* `external_chatbot chat` modalities; the backend rejects steps elsewhere.
|
|
62
|
+
*/
|
|
63
|
+
export interface AssignmentStep {
|
|
64
|
+
/** Response-only server slug (e.g. "add-to-cart"); omitted on write. */
|
|
65
|
+
id?: string;
|
|
66
|
+
/** 1–80 chars. */
|
|
67
|
+
name: string;
|
|
68
|
+
/** ≤500 chars. */
|
|
69
|
+
description?: string;
|
|
70
|
+
}
|
|
71
|
+
/** One sampled participant who failed a step, with the verifier's reason. */
|
|
72
|
+
export interface SampleFailure {
|
|
73
|
+
participant_id: string;
|
|
74
|
+
reason: string;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Response-only per-step completion rollup, populated by the backend after a
|
|
78
|
+
* run grades each step per participant. Ignored on write.
|
|
79
|
+
*/
|
|
80
|
+
export interface StepCompletion {
|
|
81
|
+
step_id: string;
|
|
82
|
+
name: string;
|
|
83
|
+
description?: string;
|
|
84
|
+
total: number;
|
|
85
|
+
passed: number;
|
|
86
|
+
rate?: number | null;
|
|
87
|
+
sample_failures?: SampleFailure[];
|
|
88
|
+
}
|
|
57
89
|
export interface Assignment {
|
|
58
90
|
id?: string;
|
|
59
91
|
name: string;
|
|
60
92
|
instructions: string;
|
|
93
|
+
/** Optional checklist authored on write; resolved with `id` on read. */
|
|
94
|
+
steps?: AssignmentStep[];
|
|
95
|
+
/** Response-only completion rollup; ignored on write. */
|
|
96
|
+
step_completion?: StepCompletion[];
|
|
61
97
|
}
|
|
62
98
|
export interface InterviewQuestion {
|
|
63
99
|
id?: string;
|
|
@@ -119,7 +155,7 @@ export interface Iteration {
|
|
|
119
155
|
description?: string;
|
|
120
156
|
label?: string;
|
|
121
157
|
details?: Record<string, unknown>;
|
|
122
|
-
|
|
158
|
+
participants?: Participant[];
|
|
123
159
|
created_at: string;
|
|
124
160
|
updated_at: string;
|
|
125
161
|
}
|
|
@@ -134,39 +170,75 @@ export interface IterationUpdateInput {
|
|
|
134
170
|
details?: Record<string, unknown>;
|
|
135
171
|
label?: string;
|
|
136
172
|
}
|
|
137
|
-
export interface
|
|
173
|
+
export interface Person {
|
|
138
174
|
id: string;
|
|
139
175
|
name: string;
|
|
140
176
|
[key: string]: unknown;
|
|
141
177
|
}
|
|
142
|
-
export type
|
|
143
|
-
export type
|
|
144
|
-
|
|
178
|
+
export type AttachmentKind = "text_file" | "audio" | "image";
|
|
179
|
+
export type AttachmentStatus = "pending_upload" | "uploaded" | "transcribing" | "processing" | "processed" | "failed";
|
|
180
|
+
/** How a file relates to a participant profile (`identity` is reserved). */
|
|
181
|
+
export type AttachmentRelation = "seed" | "attached";
|
|
182
|
+
/** Single attachment row returned by GET /people/attachments/{id}. */
|
|
183
|
+
export interface Attachment {
|
|
145
184
|
id: string;
|
|
146
185
|
product_id: string;
|
|
147
|
-
kind:
|
|
148
|
-
status:
|
|
149
|
-
|
|
186
|
+
kind: AttachmentKind;
|
|
187
|
+
status: AttachmentStatus;
|
|
188
|
+
file_name: string;
|
|
150
189
|
content_type: string;
|
|
190
|
+
file_size_bytes?: number | null;
|
|
151
191
|
extracted_text_length?: number | null;
|
|
192
|
+
description?: string | null;
|
|
152
193
|
error?: string | null;
|
|
194
|
+
relations: AttachmentRelation[];
|
|
153
195
|
created_at: string;
|
|
154
196
|
}
|
|
155
|
-
export interface
|
|
156
|
-
|
|
197
|
+
export interface InitiateAttachmentUploadResponse {
|
|
198
|
+
attachment_id: string;
|
|
157
199
|
signed_url: string;
|
|
158
200
|
upload_token: string;
|
|
159
201
|
}
|
|
202
|
+
export type SourceKind = AttachmentKind;
|
|
203
|
+
export type SourceStatus = AttachmentStatus;
|
|
204
|
+
export type PersonSource = Attachment;
|
|
205
|
+
export type InitiateSourceUploadResponse = InitiateAttachmentUploadResponse;
|
|
160
206
|
export interface ProposeCountResponse {
|
|
161
207
|
proposed_count: number;
|
|
162
208
|
rationale: string;
|
|
163
209
|
}
|
|
164
|
-
export interface
|
|
210
|
+
export interface GeneratePeopleRequest {
|
|
165
211
|
product_id: string;
|
|
166
212
|
description?: string;
|
|
167
213
|
source_upload_ids?: string[];
|
|
168
214
|
count?: number;
|
|
169
215
|
}
|
|
216
|
+
export type GenerationJobStatus = "queued" | "processing" | "completed" | "failed";
|
|
217
|
+
export interface CreateGenerationJobRequest {
|
|
218
|
+
product_id: string;
|
|
219
|
+
description?: string;
|
|
220
|
+
source_upload_ids?: string[];
|
|
221
|
+
count?: number;
|
|
222
|
+
}
|
|
223
|
+
export interface GenerationJob {
|
|
224
|
+
id: string;
|
|
225
|
+
status: GenerationJobStatus;
|
|
226
|
+
progress_message: string | null;
|
|
227
|
+
person_ids: string[];
|
|
228
|
+
error: string | null;
|
|
229
|
+
created_at: string;
|
|
230
|
+
updated_at: string;
|
|
231
|
+
}
|
|
232
|
+
/** One scenario the job grounded in a real reaction (GET /people/{id}/scenarios). */
|
|
233
|
+
export interface ProfileScenario {
|
|
234
|
+
source: string;
|
|
235
|
+
scenario_prompt: string;
|
|
236
|
+
text: string;
|
|
237
|
+
raw_response?: {
|
|
238
|
+
evidence_quote?: string;
|
|
239
|
+
} & Record<string, unknown>;
|
|
240
|
+
[key: string]: unknown;
|
|
241
|
+
}
|
|
170
242
|
export interface GeneratedProfile {
|
|
171
243
|
id: string;
|
|
172
244
|
name: string;
|
|
@@ -243,30 +315,30 @@ export interface EvidenceTraceResponse {
|
|
|
243
315
|
raw_response: Record<string, unknown> | null;
|
|
244
316
|
created_at: string;
|
|
245
317
|
}
|
|
246
|
-
export interface
|
|
318
|
+
export interface Participant {
|
|
247
319
|
id: string;
|
|
248
320
|
iteration_id: string;
|
|
249
|
-
|
|
321
|
+
person_id: string;
|
|
250
322
|
instance_name?: string;
|
|
251
323
|
instance_number?: number;
|
|
252
324
|
status: string;
|
|
253
325
|
language?: string;
|
|
254
326
|
platform?: string;
|
|
255
|
-
|
|
327
|
+
participant_type?: string;
|
|
256
328
|
viewport_width?: number;
|
|
257
329
|
viewport_height?: number;
|
|
258
330
|
created_at: string;
|
|
259
331
|
}
|
|
260
|
-
export interface
|
|
261
|
-
|
|
332
|
+
export interface ParticipantCreateInput {
|
|
333
|
+
person_id: string;
|
|
262
334
|
instance_name?: string;
|
|
263
335
|
status?: string;
|
|
264
336
|
language?: string;
|
|
265
337
|
platform?: string;
|
|
266
|
-
|
|
338
|
+
participant_type?: string;
|
|
267
339
|
}
|
|
268
340
|
export interface SimulationStartResponse {
|
|
269
|
-
|
|
341
|
+
participant_id: string;
|
|
270
342
|
study_id: string;
|
|
271
343
|
job_id: string | null;
|
|
272
344
|
message: string;
|
|
@@ -296,7 +368,6 @@ export interface SimulationConfig {
|
|
|
296
368
|
id: string;
|
|
297
369
|
name: string;
|
|
298
370
|
model_settings?: Record<string, unknown>;
|
|
299
|
-
simulation_settings?: Record<string, unknown>;
|
|
300
371
|
prompts?: Record<string, unknown>;
|
|
301
372
|
outputs?: Record<string, unknown>;
|
|
302
373
|
source_type?: string;
|
|
@@ -329,14 +400,14 @@ export interface InterviewAnswer {
|
|
|
329
400
|
/**
|
|
330
401
|
* Pattern B — drill-in subset for a follow-up ask round.
|
|
331
402
|
*
|
|
332
|
-
* Filters the new round's
|
|
403
|
+
* Filters the new round's participants to those who picked
|
|
333
404
|
* `picked_variant_id` on the 1-indexed prior `round`. Mirrors the
|
|
334
|
-
* backend's `
|
|
405
|
+
* backend's `ParticipantSubset` model. Only valid on follow-up rounds —
|
|
335
406
|
* round 1 has no prior round to filter against. The backend rejects
|
|
336
407
|
* unresolvable subsets with a 422 carrying
|
|
337
|
-
* `error_kind: "
|
|
408
|
+
* `error_kind: "participant_subset_invalid"`.
|
|
338
409
|
*/
|
|
339
|
-
export interface
|
|
410
|
+
export interface ParticipantSubset {
|
|
340
411
|
round: number;
|
|
341
412
|
picked_variant_id: string;
|
|
342
413
|
}
|
|
@@ -346,13 +417,13 @@ export interface AskRoundInput {
|
|
|
346
417
|
wants_pick?: boolean;
|
|
347
418
|
wants_ratings?: boolean;
|
|
348
419
|
questions?: InterviewQuestion[];
|
|
349
|
-
|
|
420
|
+
participant_subset?: ParticipantSubset;
|
|
350
421
|
}
|
|
351
422
|
export interface AskCreateInput {
|
|
352
423
|
name: string;
|
|
353
424
|
description?: string;
|
|
354
425
|
language?: string;
|
|
355
|
-
|
|
426
|
+
person_ids: string[];
|
|
356
427
|
first_round: AskRoundInput;
|
|
357
428
|
dispatch?: boolean;
|
|
358
429
|
}
|
|
@@ -361,20 +432,20 @@ export interface AskUpdateInput {
|
|
|
361
432
|
description?: string;
|
|
362
433
|
is_archived?: boolean;
|
|
363
434
|
}
|
|
364
|
-
export interface
|
|
365
|
-
|
|
366
|
-
|
|
435
|
+
export interface AddPeopleInput {
|
|
436
|
+
person_ids: string[];
|
|
437
|
+
dispatch_into_round_id: string;
|
|
367
438
|
backfill_prior_rounds?: boolean;
|
|
368
439
|
}
|
|
369
440
|
export interface AddRoundQuestionsInput {
|
|
370
441
|
questions: InterviewQuestion[];
|
|
371
442
|
redispatch_all?: boolean;
|
|
372
443
|
}
|
|
373
|
-
export interface
|
|
444
|
+
export interface AskParticipant {
|
|
374
445
|
id: string;
|
|
375
446
|
ask_id?: string;
|
|
376
|
-
|
|
377
|
-
|
|
447
|
+
person_id?: string;
|
|
448
|
+
person?: Record<string, unknown> | null;
|
|
378
449
|
instance_name?: string;
|
|
379
450
|
status?: string;
|
|
380
451
|
[key: string]: unknown;
|
|
@@ -382,7 +453,7 @@ export interface AskAudienceTester {
|
|
|
382
453
|
export interface AskResponseModel {
|
|
383
454
|
id: string;
|
|
384
455
|
ask_round_id: string;
|
|
385
|
-
|
|
456
|
+
participant_id: string;
|
|
386
457
|
comment?: string | null;
|
|
387
458
|
variant_pick_id?: string | null;
|
|
388
459
|
pick_confidence?: number | null;
|
|
@@ -418,7 +489,7 @@ export interface Ask {
|
|
|
418
489
|
description?: string | null;
|
|
419
490
|
is_archived: boolean;
|
|
420
491
|
status?: AskStatus;
|
|
421
|
-
|
|
492
|
+
participants: AskParticipant[];
|
|
422
493
|
rounds: AskRound[];
|
|
423
494
|
created_at: string;
|
|
424
495
|
updated_at: string;
|
|
@@ -431,7 +502,7 @@ export interface AskListItem {
|
|
|
431
502
|
description?: string | null;
|
|
432
503
|
is_archived: boolean;
|
|
433
504
|
status?: AskStatus;
|
|
434
|
-
|
|
505
|
+
participant_count: number;
|
|
435
506
|
round_count: number;
|
|
436
507
|
last_round_at?: string | null;
|
|
437
508
|
created_at: string;
|
package/package.json
CHANGED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ish study tester — Inspect and manage testers (low-level; usually
|
|
3
|
-
* created via `ish study run`).
|
|
4
|
-
*
|
|
5
|
-
* Default action: `ish study tester <id>` shows tester details and results.
|
|
6
|
-
*/
|
|
7
|
-
import type { Command } from "commander";
|
|
8
|
-
export declare function attachStudyTesterCommands(study: Command): void;
|