@ishlabs/cli 0.8.1 → 0.8.3
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 +323 -21
- package/dist/auth.d.ts +17 -1
- package/dist/auth.js +62 -9
- package/dist/commands/ask.d.ts +5 -0
- package/dist/commands/ask.js +722 -0
- package/dist/commands/config.js +25 -1
- package/dist/commands/docs.d.ts +17 -0
- package/dist/commands/docs.js +147 -0
- package/dist/commands/init.d.ts +16 -0
- package/dist/commands/init.js +182 -0
- package/dist/commands/iteration.d.ts +5 -1
- package/dist/commands/iteration.js +243 -31
- package/dist/commands/profile.d.ts +5 -0
- package/dist/commands/profile.js +313 -0
- package/dist/commands/source.d.ts +10 -0
- package/dist/commands/source.js +78 -0
- package/dist/commands/study-run.d.ts +11 -0
- package/dist/commands/study-run.js +552 -0
- package/dist/commands/study-tester.d.ts +8 -0
- package/dist/commands/study-tester.js +149 -0
- package/dist/commands/study.js +145 -70
- package/dist/commands/workspace.js +193 -7
- package/dist/config.d.ts +3 -1
- package/dist/config.js +10 -10
- package/dist/connect.d.ts +4 -1
- package/dist/connect.js +127 -94
- package/dist/index.js +82 -34
- package/dist/lib/alias-store.d.ts +3 -0
- package/dist/lib/alias-store.js +9 -7
- package/dist/lib/api-client.d.ts +9 -6
- package/dist/lib/api-client.js +87 -26
- package/dist/lib/ask-questions.d.ts +9 -0
- package/dist/lib/ask-questions.js +35 -0
- package/dist/lib/ask-variants.d.ts +48 -0
- package/dist/lib/ask-variants.js +236 -0
- package/dist/lib/auth.d.ts +1 -1
- package/dist/lib/auth.js +24 -8
- package/dist/lib/colors.d.ts +30 -0
- package/dist/lib/colors.js +48 -0
- package/dist/lib/command-helpers.d.ts +74 -0
- package/dist/lib/command-helpers.js +232 -6
- package/dist/lib/docs.d.ts +32 -0
- package/dist/lib/docs.js +930 -0
- package/dist/lib/local-sim/browser.d.ts +0 -1
- package/dist/lib/local-sim/browser.js +0 -2
- package/dist/lib/local-sim/install.d.ts +2 -12
- package/dist/lib/local-sim/install.js +22 -30
- package/dist/lib/output.d.ts +25 -3
- package/dist/lib/output.js +465 -20
- package/dist/lib/paths.d.ts +14 -0
- package/dist/lib/paths.js +36 -0
- package/dist/lib/profile-sources.d.ts +55 -0
- package/dist/lib/profile-sources.js +157 -0
- package/dist/lib/site-access.d.ts +80 -0
- package/dist/lib/site-access.js +188 -0
- package/dist/lib/skill-content.d.ts +31 -0
- package/dist/lib/skill-content.js +462 -0
- package/dist/lib/study-inputs.d.ts +20 -0
- package/dist/lib/study-inputs.js +72 -0
- package/dist/lib/types.d.ts +207 -9
- package/dist/lib/types.js +7 -0
- package/dist/lib/upload.js +2 -2
- package/dist/upgrade.js +11 -1
- package/package.json +3 -2
- package/dist/commands/simulation.d.ts +0 -10
- package/dist/commands/simulation.js +0 -647
- package/dist/commands/tester-profile.d.ts +0 -5
- package/dist/commands/tester-profile.js +0 -109
- package/dist/commands/tester.d.ts +0 -5
- package/dist/commands/tester.js +0 -73
package/dist/lib/types.d.ts
CHANGED
|
@@ -23,6 +23,37 @@ export interface ProductUpdateInput {
|
|
|
23
23
|
color?: string;
|
|
24
24
|
base_url?: string;
|
|
25
25
|
}
|
|
26
|
+
export type SecretScope = "agent" | "project";
|
|
27
|
+
export type SecretVariableType = "secret" | "variable";
|
|
28
|
+
export interface Secret {
|
|
29
|
+
id: string;
|
|
30
|
+
product_id: string;
|
|
31
|
+
key: string;
|
|
32
|
+
description?: string | null;
|
|
33
|
+
scope: SecretScope;
|
|
34
|
+
variable_type: SecretVariableType;
|
|
35
|
+
expires_at?: string | null;
|
|
36
|
+
created_at: string;
|
|
37
|
+
updated_at: string;
|
|
38
|
+
}
|
|
39
|
+
export interface SecretCreateInput {
|
|
40
|
+
key: string;
|
|
41
|
+
value: string;
|
|
42
|
+
description?: string;
|
|
43
|
+
scope: SecretScope;
|
|
44
|
+
variable_type: SecretVariableType;
|
|
45
|
+
expires_at?: string | null;
|
|
46
|
+
}
|
|
47
|
+
export interface SecretUpdateInput {
|
|
48
|
+
value?: string;
|
|
49
|
+
description?: string;
|
|
50
|
+
scope?: SecretScope;
|
|
51
|
+
variable_type?: SecretVariableType;
|
|
52
|
+
expires_at?: string | null;
|
|
53
|
+
}
|
|
54
|
+
export interface SecretBatchCreateInput {
|
|
55
|
+
secrets: SecretCreateInput[];
|
|
56
|
+
}
|
|
26
57
|
export interface Assignment {
|
|
27
58
|
id?: string;
|
|
28
59
|
name: string;
|
|
@@ -108,6 +139,49 @@ export interface TesterProfile {
|
|
|
108
139
|
name: string;
|
|
109
140
|
[key: string]: unknown;
|
|
110
141
|
}
|
|
142
|
+
export type SourceKind = "text_file" | "audio" | "image";
|
|
143
|
+
export type SourceStatus = "pending_upload" | "uploaded" | "transcribing" | "processed" | "failed";
|
|
144
|
+
export interface AudienceSource {
|
|
145
|
+
id: string;
|
|
146
|
+
product_id: string;
|
|
147
|
+
kind: SourceKind;
|
|
148
|
+
status: SourceStatus;
|
|
149
|
+
original_filename: string;
|
|
150
|
+
content_type: string;
|
|
151
|
+
extracted_text_length?: number | null;
|
|
152
|
+
error?: string | null;
|
|
153
|
+
created_at: string;
|
|
154
|
+
}
|
|
155
|
+
export interface InitiateSourceUploadResponse {
|
|
156
|
+
source_id: string;
|
|
157
|
+
signed_url: string;
|
|
158
|
+
upload_token: string;
|
|
159
|
+
}
|
|
160
|
+
export interface ProposeCountResponse {
|
|
161
|
+
proposed_count: number;
|
|
162
|
+
rationale: string;
|
|
163
|
+
}
|
|
164
|
+
export interface GenerateAudienceRequest {
|
|
165
|
+
product_id: string;
|
|
166
|
+
description?: string;
|
|
167
|
+
source_upload_ids?: string[];
|
|
168
|
+
count?: number;
|
|
169
|
+
}
|
|
170
|
+
export interface GeneratedProfile {
|
|
171
|
+
id: string;
|
|
172
|
+
name: string;
|
|
173
|
+
type: "ai" | "human";
|
|
174
|
+
bio?: string | null;
|
|
175
|
+
date_of_birth?: string | null;
|
|
176
|
+
gender?: "male" | "female" | "non-binary" | null;
|
|
177
|
+
country?: string | null;
|
|
178
|
+
city?: string | null;
|
|
179
|
+
occupation?: string | null;
|
|
180
|
+
tech_savviness?: string | null;
|
|
181
|
+
product_id?: string | null;
|
|
182
|
+
custom_field_values?: Record<string, unknown>;
|
|
183
|
+
[key: string]: unknown;
|
|
184
|
+
}
|
|
111
185
|
export interface Tester {
|
|
112
186
|
id: string;
|
|
113
187
|
iteration_id: string;
|
|
@@ -139,15 +213,6 @@ export interface SimulationStartResponse {
|
|
|
139
213
|
export interface SimulationBatchStartResponse {
|
|
140
214
|
results: SimulationStartResponse[];
|
|
141
215
|
}
|
|
142
|
-
export interface MediaSimulationStartInput {
|
|
143
|
-
product_id: string;
|
|
144
|
-
study_id: string;
|
|
145
|
-
tester_id: string;
|
|
146
|
-
config_id: string;
|
|
147
|
-
max_interactions?: number;
|
|
148
|
-
language?: string;
|
|
149
|
-
config_overrides?: Record<string, unknown>;
|
|
150
|
-
}
|
|
151
216
|
export interface MediaBatchStartResponse {
|
|
152
217
|
results: SimulationStartResponse[];
|
|
153
218
|
}
|
|
@@ -177,3 +242,136 @@ export interface SimulationConfig {
|
|
|
177
242
|
created_at: string;
|
|
178
243
|
updated_at: string;
|
|
179
244
|
}
|
|
245
|
+
export type AskVariantKind = "image" | "text" | "audio" | "video" | "document";
|
|
246
|
+
export declare const ASK_VARIANT_KINDS: AskVariantKind[];
|
|
247
|
+
export type AskRoundStatus = "running" | "completed" | "errored";
|
|
248
|
+
export type AskResponseStatus = "pending" | "completed" | "errored";
|
|
249
|
+
export interface AskVariant {
|
|
250
|
+
id: string;
|
|
251
|
+
kind: AskVariantKind;
|
|
252
|
+
label?: string | null;
|
|
253
|
+
/** File path on write, public URL on read for media kinds; literal text for kind="text". */
|
|
254
|
+
content: string;
|
|
255
|
+
}
|
|
256
|
+
export interface AskVariantInput {
|
|
257
|
+
id?: string;
|
|
258
|
+
kind: AskVariantKind;
|
|
259
|
+
label?: string;
|
|
260
|
+
content: string;
|
|
261
|
+
}
|
|
262
|
+
export interface InterviewAnswer {
|
|
263
|
+
question_id: string;
|
|
264
|
+
answer: unknown;
|
|
265
|
+
rationale?: string;
|
|
266
|
+
}
|
|
267
|
+
export interface AskRoundInput {
|
|
268
|
+
prompt: string;
|
|
269
|
+
variants?: AskVariantInput[];
|
|
270
|
+
wants_pick?: boolean;
|
|
271
|
+
wants_ratings?: boolean;
|
|
272
|
+
questions?: InterviewQuestion[];
|
|
273
|
+
}
|
|
274
|
+
export interface AskCreateInput {
|
|
275
|
+
name: string;
|
|
276
|
+
description?: string;
|
|
277
|
+
language?: string;
|
|
278
|
+
tester_profile_ids: string[];
|
|
279
|
+
first_round: AskRoundInput;
|
|
280
|
+
}
|
|
281
|
+
export interface AskUpdateInput {
|
|
282
|
+
name?: string;
|
|
283
|
+
description?: string;
|
|
284
|
+
is_archived?: boolean;
|
|
285
|
+
}
|
|
286
|
+
export interface AddTestersInput {
|
|
287
|
+
tester_profile_ids: string[];
|
|
288
|
+
round_id: string;
|
|
289
|
+
backfill_prior_rounds?: boolean;
|
|
290
|
+
}
|
|
291
|
+
export interface AddRoundQuestionsInput {
|
|
292
|
+
questions: InterviewQuestion[];
|
|
293
|
+
}
|
|
294
|
+
export interface AskAudienceTester {
|
|
295
|
+
id: string;
|
|
296
|
+
ask_id?: string;
|
|
297
|
+
tester_profile_id?: string;
|
|
298
|
+
tester_profile?: Record<string, unknown> | null;
|
|
299
|
+
instance_name?: string;
|
|
300
|
+
status?: string;
|
|
301
|
+
[key: string]: unknown;
|
|
302
|
+
}
|
|
303
|
+
export interface AskResponseModel {
|
|
304
|
+
id: string;
|
|
305
|
+
ask_round_id: string;
|
|
306
|
+
tester_id: string;
|
|
307
|
+
comment?: string | null;
|
|
308
|
+
variant_pick_id?: string | null;
|
|
309
|
+
pick_confidence?: number | null;
|
|
310
|
+
variant_ratings?: Record<string, number> | null;
|
|
311
|
+
question_answers?: InterviewAnswer[] | null;
|
|
312
|
+
status: AskResponseStatus;
|
|
313
|
+
created_at: string;
|
|
314
|
+
}
|
|
315
|
+
export interface AskRoundSummary {
|
|
316
|
+
id?: string;
|
|
317
|
+
comment?: string;
|
|
318
|
+
[key: string]: unknown;
|
|
319
|
+
}
|
|
320
|
+
export interface AskRound {
|
|
321
|
+
id: string;
|
|
322
|
+
ask_id: string;
|
|
323
|
+
order_index: number;
|
|
324
|
+
prompt: string;
|
|
325
|
+
variants: AskVariant[];
|
|
326
|
+
wants_pick: boolean;
|
|
327
|
+
wants_ratings: boolean;
|
|
328
|
+
questions: InterviewQuestion[];
|
|
329
|
+
responses: AskResponseModel[];
|
|
330
|
+
summary?: AskRoundSummary | null;
|
|
331
|
+
status: AskRoundStatus;
|
|
332
|
+
created_at: string;
|
|
333
|
+
completed_at?: string | null;
|
|
334
|
+
}
|
|
335
|
+
export interface Ask {
|
|
336
|
+
id: string;
|
|
337
|
+
product_id: string;
|
|
338
|
+
name: string;
|
|
339
|
+
description?: string | null;
|
|
340
|
+
is_archived: boolean;
|
|
341
|
+
testers: AskAudienceTester[];
|
|
342
|
+
rounds: AskRound[];
|
|
343
|
+
created_at: string;
|
|
344
|
+
updated_at: string;
|
|
345
|
+
created_by?: string | null;
|
|
346
|
+
}
|
|
347
|
+
export interface AskListItem {
|
|
348
|
+
id: string;
|
|
349
|
+
product_id: string;
|
|
350
|
+
name: string;
|
|
351
|
+
description?: string | null;
|
|
352
|
+
is_archived: boolean;
|
|
353
|
+
audience_count: number;
|
|
354
|
+
round_count: number;
|
|
355
|
+
last_round_at?: string | null;
|
|
356
|
+
created_at: string;
|
|
357
|
+
updated_at: string;
|
|
358
|
+
created_by?: string | null;
|
|
359
|
+
}
|
|
360
|
+
export interface AskVariantUploadItemInput {
|
|
361
|
+
content_type: string;
|
|
362
|
+
file_size_bytes?: number;
|
|
363
|
+
}
|
|
364
|
+
export interface AskVariantUploadInput {
|
|
365
|
+
items: AskVariantUploadItemInput[];
|
|
366
|
+
}
|
|
367
|
+
export interface AskVariantUploadResult {
|
|
368
|
+
upload_info: {
|
|
369
|
+
signed_upload_url: string;
|
|
370
|
+
file_path: string;
|
|
371
|
+
expires_in_seconds: number;
|
|
372
|
+
};
|
|
373
|
+
content_url: string;
|
|
374
|
+
}
|
|
375
|
+
export interface AskVariantUploadResponse {
|
|
376
|
+
items: AskVariantUploadResult[];
|
|
377
|
+
}
|
package/dist/lib/types.js
CHANGED
|
@@ -10,3 +10,10 @@ export const VALID_CONTENT_TYPES = {
|
|
|
10
10
|
image: ["product", "photography", "infographic", "artwork", "interface", "social_post", "ad"],
|
|
11
11
|
document: ["deck", "presentation", "report", "brochure", "guide"],
|
|
12
12
|
};
|
|
13
|
+
export const ASK_VARIANT_KINDS = [
|
|
14
|
+
"image",
|
|
15
|
+
"text",
|
|
16
|
+
"audio",
|
|
17
|
+
"video",
|
|
18
|
+
"document",
|
|
19
|
+
];
|
package/dist/lib/upload.js
CHANGED
|
@@ -109,7 +109,7 @@ export async function uploadStudyContent(client, studyId, filePath, opts) {
|
|
|
109
109
|
process.stderr.write(msg); };
|
|
110
110
|
// Step 1: Request a signed upload URL from the backend
|
|
111
111
|
log(`Uploading ${name} (${sizeMB} MB)...`);
|
|
112
|
-
const uploadResp = await client.post(`/studies/${studyId}/content/upload`, { content_type: mime, file_size_bytes: size });
|
|
112
|
+
const uploadResp = await client.post(`/studies/${studyId}/content/upload`, { content_type: mime, file_size_bytes: size }, { timeout: 60_000 });
|
|
113
113
|
// Step 2: PUT the raw file bytes to the signed URL
|
|
114
114
|
const fileBuffer = await readFile(resolved);
|
|
115
115
|
const putResp = await fetch(uploadResp.upload_info.signed_upload_url, {
|
|
@@ -129,7 +129,7 @@ export async function uploadStudyContent(client, studyId, filePath, opts) {
|
|
|
129
129
|
await client.put(`/studies/${studyId}/content/upload/complete`, {
|
|
130
130
|
file_path: uploadResp.upload_info.file_path,
|
|
131
131
|
is_uploaded: true,
|
|
132
|
-
});
|
|
132
|
+
}, { timeout: 60_000 });
|
|
133
133
|
log(" done.\n");
|
|
134
134
|
return uploadResp.content_url;
|
|
135
135
|
}
|
package/dist/upgrade.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createWriteStream, renameSync, unlinkSync, chmodSync } from "node:fs";
|
|
2
|
-
import { join, dirname } from "node:path";
|
|
2
|
+
import { join, dirname, basename } from "node:path";
|
|
3
3
|
import { pipeline } from "node:stream/promises";
|
|
4
4
|
import { Readable } from "node:stream";
|
|
5
5
|
const BASE_URL = "https://ishlabs.io";
|
|
@@ -25,6 +25,16 @@ async function getLatestVersion() {
|
|
|
25
25
|
return data.version;
|
|
26
26
|
}
|
|
27
27
|
export async function upgrade(currentVersion, targetVersion) {
|
|
28
|
+
// Detect npm-linked / npm-installed-globally CLI: process.execPath is `node`, not the ish binary.
|
|
29
|
+
const execBase = basename(process.execPath).toLowerCase();
|
|
30
|
+
const looksLikeNode = execBase === "node" || execBase === "node.exe";
|
|
31
|
+
// Also detect when our script is running under a node_modules directory (npm install -g symlinks here).
|
|
32
|
+
const scriptUrl = import.meta.url;
|
|
33
|
+
const runningFromNodeModules = scriptUrl.includes("/node_modules/");
|
|
34
|
+
if (looksLikeNode || runningFromNodeModules) {
|
|
35
|
+
throw new Error("Cannot self-upgrade an npm-installed CLI (would overwrite the node binary). " +
|
|
36
|
+
"Run `npm install -g @ishlabs/cli@latest` instead.");
|
|
37
|
+
}
|
|
28
38
|
if (targetVersion && !/^\d+\.\d+\.\d+/.test(targetVersion)) {
|
|
29
39
|
throw new Error(`Invalid version format: ${targetVersion}`);
|
|
30
40
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ishlabs/cli",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.3",
|
|
4
4
|
"description": "The command-line interface for Ish",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"build": "tsc",
|
|
11
|
-
"
|
|
11
|
+
"patch:playwright": "node scripts/patch-playwright-core.mjs",
|
|
12
|
+
"build:binary": "npm run patch:playwright && bun build --compile --external chromium-bidi --external electron src/index.ts --outfile ish",
|
|
12
13
|
"dev": "tsc --watch",
|
|
13
14
|
"prepublishOnly": "npm run build"
|
|
14
15
|
},
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ish simulation — Run, monitor, and cancel simulations.
|
|
3
|
-
*
|
|
4
|
-
* Primary command: `ish simulation run` — orchestrates the full flow:
|
|
5
|
-
* 1. Creates iteration (if not provided)
|
|
6
|
-
* 2. Creates testers from profiles
|
|
7
|
-
* 3. Starts simulations (interactive or media, based on study modality)
|
|
8
|
-
*/
|
|
9
|
-
import type { Command } from "commander";
|
|
10
|
-
export declare function registerSimulationCommands(program: Command): void;
|