@ishlabs/cli 0.23.1 → 0.24.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/dist/commands/ask.js +4 -4
- package/dist/commands/iteration.js +25 -3
- package/dist/commands/study-share.d.ts +18 -0
- package/dist/commands/study-share.js +117 -0
- package/dist/commands/study.js +54 -7
- package/dist/commands/workspace.js +4 -1
- package/dist/connect.d.ts +4 -2
- package/dist/connect.js +151 -11
- package/dist/index.js +63 -6
- package/dist/lib/ask-questions.d.ts +15 -5
- package/dist/lib/ask-questions.js +34 -11
- package/dist/lib/auth.d.ts +1 -0
- package/dist/lib/auth.js +7 -1
- package/dist/lib/command-helpers.js +33 -5
- package/dist/lib/docs.js +140 -8
- package/dist/lib/output.js +8 -1
- package/dist/lib/reverse-proxy.d.ts +19 -0
- package/dist/lib/reverse-proxy.js +87 -0
- package/dist/lib/reverse-proxy.test.d.ts +10 -0
- package/dist/lib/reverse-proxy.test.js +149 -0
- package/dist/lib/segmentation.d.ts +31 -0
- package/dist/lib/segmentation.js +105 -0
- package/dist/lib/skill-content.js +76 -4
- package/dist/lib/types.d.ts +2 -0
- package/package.json +3 -1
|
@@ -207,6 +207,10 @@ The most common multi-turn question: "user wants to change X — re-use the exis
|
|
|
207
207
|
|
|
208
208
|
When in doubt: side-by-side comparison usually beats in-place edits. Ids are cheap; result history isn't.
|
|
209
209
|
|
|
210
|
+
## Sharing results (no-login link)
|
|
211
|
+
|
|
212
|
+
To hand a study to someone **without an ish account** — a prospect, a stakeholder — create a public share link. \`ish study share [study]\` prints a no-login \`share_url\` to the web viewer (summary, key insights, participant journeys, interactive frames, segment breakdowns). \`ish study share --list\` lists your links; \`ish study unshare <token>\` revokes one (takes the **raw token**, not a study id/alias). \`--expires <days>\` auto-expires the link. Brand the link by setting a workspace logo first: \`ish workspace update <id> --logo <url>\` — the logo shows on the shared page. Share **after** the study has run + been analyzed, so the viewer renders the summary + insights. Deep dive: \`ish docs get-page concepts/sharing\`. (CLI-only — the MCP has no share tool yet.)
|
|
213
|
+
|
|
210
214
|
## Pitfalls
|
|
211
215
|
|
|
212
216
|
- **Cold start on free plan**: \`workspace_create\` returns \`usage_limit_reached\` at the free-plan cap (1 workspace). Always inspect with \`workspace_list\` first. **MCP-only recipe** (no \`--ensure\` available): \`workspace_list\` → if non-empty, use the first; if empty, \`workspace_create\`; if \`workspace_create\` returns \`usage_limit_reached\`, re-call \`workspace_list\` (a workspace exists you didn't see — possibly created by another session). **CLI shortcut**: \`ish workspace create --name <name> --ensure\` is idempotent by name.
|
|
@@ -222,9 +226,10 @@ When in doubt: side-by-side comparison usually beats in-place edits. Ids are che
|
|
|
222
226
|
- **No per-page/per-timestamp scoping for media**: there's no "evaluate just slide 14" or "react to seconds 0-30" API. State the focus explicitly in the \`assignment\` text, or pre-stitch the artifact (e.g. replace one slide locally, upload as a new iteration).
|
|
223
227
|
- **\`study get --json\` participants live at the top level**, not nested under \`iterations[*].participants\`. The backend split made \`/studies/{id}\` lite (metadata + iteration shells, no participant graph) and added \`/studies/{id}/participants\`; the CLI joins them so \`study get --json\` carries a flat \`participants[]\` with \`iteration_id\` on each row. Read \`.participants[]\`, not \`.iterations[].participants[]\`.
|
|
224
228
|
- **All destructive deletes require \`--yes\` in non-TTY mode**: \`ish workspace delete\`, \`study delete\`, \`ask delete\`, \`person delete\`, \`source delete\`, \`chat endpoint delete\`. In \`--json\` mode (or any piped/non-TTY invocation), omitting \`--yes\` refuses with \`error_kind: "ConfirmationRequired"\` + an \`example\` field showing the same command with \`--yes\` appended. \`workspace delete\` is the highest-blast-radius: it removes ALL nested studies, asks, people, secrets, configs, sources, and chat endpoints — the prompt names them explicitly.
|
|
225
|
-
- **\`ish login\` is idempotent**: with a
|
|
229
|
+
- **\`ish login\` is idempotent**: with a saved token that is unexpired *and* still accepted by the API, \`ish login\` short-circuits with "Already logged in" and **does not open a new browser tab**. If the token is unexpired but the server rejects it (revoked, rotated signing key, or minted against the wrong env — e.g. a dev-Supabase token while calling the prod api), it re-runs the browser flow instead of falsely reporting success. Use \`--force\` (or \`-f\`) only when actually switching accounts.
|
|
226
230
|
- **\`ish person create\` accepts inline flags** (mirrors \`person update\`): the file-only API (\`--file <path>\`) is preserved as an escape hatch but the common path is \`ish person create --name "X" --type ai --country US ...\` — \`--type\` defaults to \`ai\` when \`--file\` is omitted. See \`ish person create --help\` for the full inline-flag set including \`--household\` (MECE rule applies) and \`--accessibility-profile\`.
|
|
227
231
|
- **\`ish status\` now surfaces \`chat_endpoint\`** alongside \`workspace\`/\`study\`/\`ask\`. Stale or orphan active refs get a \`warning\` + \`hint\` field on the affected ref (instead of silently dropping the \`name\`). On \`workspace use <other>\`, the CLI cascade-clears \`study\`/\`ask\`/\`chat_endpoint\` (they belong to the previous workspace).
|
|
232
|
+
- **Share link URL host ≠ API host**: \`ish study share\` prints the backend-built \`share_url\` (the web frontend host). Use it verbatim — never reconstruct the URL from the API host or app URL; they differ. \`ish study unshare\` takes the **raw token** (from \`study share\` / \`study share --list\`), not a study id or alias.
|
|
228
233
|
|
|
229
234
|
## When in doubt
|
|
230
235
|
|
|
@@ -259,14 +264,22 @@ ish person generate \\
|
|
|
259
264
|
# 4. Define the study + iteration A in one call (one-shot path).
|
|
260
265
|
# The same shape works for image (--image-urls), video / audio /
|
|
261
266
|
# document (--content-url <url>), and chat (--endpoint <id>).
|
|
267
|
+
# For text/media you can also pass --segmentation-json (+ email-styling
|
|
268
|
+
# --content-html/--sender-name/--sender-email/--featured-image-url) here,
|
|
269
|
+
# so a single SEGMENTED iteration is one call — no separate iteration
|
|
270
|
+
# create (which would leave an empty A + a redundant B).
|
|
271
|
+
# Segments are SEMANTIC sections, not paragraphs: group related paragraphs
|
|
272
|
+
# into a few coherent sections (a long article is usually 3-6 sections, not
|
|
273
|
+
# one per paragraph). The CLI errors on a missing label and warns on
|
|
274
|
+
# one-section-per-paragraph.
|
|
262
275
|
ish study create --name "Onboarding UX" --modality interactive \\
|
|
263
276
|
--url https://example.com --screen-format desktop \\
|
|
264
277
|
--assignment "Sign up:Complete the signup flow" \\
|
|
265
278
|
--question "How easy was it?"
|
|
266
279
|
ish study use s-…
|
|
267
280
|
|
|
268
|
-
# (Optional) add a
|
|
269
|
-
# ish iteration create --url https://example.com/v2
|
|
281
|
+
# (Optional) add a SECOND iteration only when you actually want to A/B:
|
|
282
|
+
# ish iteration create --url https://example.com/v2 # auto-named "B" (next letter), not "CLI <date>"
|
|
270
283
|
|
|
271
284
|
# 6. Run, blocking until done
|
|
272
285
|
ish study run --all --wait
|
|
@@ -302,6 +315,59 @@ ish study get s-… # human: "✓ Add to cart 4/5 (80%)" p
|
|
|
302
315
|
ish study get s-… --json --verbose # step_completion[] incl. sample_failures[].participant_id
|
|
303
316
|
\`\`\`
|
|
304
317
|
|
|
318
|
+
### Rich question types (slider, likert, choice, number)
|
|
319
|
+
|
|
320
|
+
\`--question\` makes simple text questions only. For \`slider\`, \`likert\`,
|
|
321
|
+
\`single-choice\`, \`multiple-choice\`, \`number\`, or \`timing: "before"\`, use
|
|
322
|
+
\`--questionnaire\` — which takes **inline JSON, an @file, or a path** (no temp
|
|
323
|
+
file required). \`--question\` and \`--questionnaire\` are mutually exclusive.
|
|
324
|
+
|
|
325
|
+
\`\`\`bash
|
|
326
|
+
ish study create --name "Pricing page" --modality interactive --url https://example.com \\
|
|
327
|
+
--assignment "React:Look around as you normally would" \\
|
|
328
|
+
--questionnaire '[
|
|
329
|
+
{"question":"What do you think this does?","type":"text","timing":"after"},
|
|
330
|
+
{"question":"How easy was it to understand?","type":"slider","min":0,"max":10},
|
|
331
|
+
{"question":"How strongly do you agree it is for you?","type":"likert",
|
|
332
|
+
"labels":["Strongly disagree","Disagree","Neutral","Agree","Strongly agree"]},
|
|
333
|
+
{"question":"Which fits best?","type":"single-choice","options":["A","B","C"]},
|
|
334
|
+
{"question":"How many seats would you need?","type":"number"}
|
|
335
|
+
]'
|
|
336
|
+
# @file and path forms also work: --questionnaire @/tmp/q.json | ./q.json
|
|
337
|
+
\`\`\`
|
|
338
|
+
|
|
339
|
+
\`slider\` takes \`min\`/\`max\`(/\`step\`); \`likert\` takes \`labels\`;
|
|
340
|
+
\`single-choice\`/\`multiple-choice\` take \`options\`. The CLI tolerates
|
|
341
|
+
underscored type spellings (\`single_choice\`); the backend validates the shape.
|
|
342
|
+
Same input forms on \`ish ask … --questions\`. See \`ish docs get-page concepts/questionnaire\`.
|
|
343
|
+
|
|
344
|
+
### 1b. Share the results with someone (no-login link)
|
|
345
|
+
|
|
346
|
+
Goal: hand the finished study to a prospect or stakeholder who has no ish
|
|
347
|
+
account. Run + analyze first so the public viewer renders the summary.
|
|
348
|
+
|
|
349
|
+
\`\`\`bash
|
|
350
|
+
# (optional) brand the workspace — the logo shows on the shared page
|
|
351
|
+
ish workspace update w-… --logo https://logo.clearbit.com/acme.com
|
|
352
|
+
|
|
353
|
+
# generate the AI summary + key insights (needs ≥5 completed participants)
|
|
354
|
+
ish study analyze s-… --wait
|
|
355
|
+
|
|
356
|
+
# create the public, no-login link — the printed share_url is the deliverable
|
|
357
|
+
ish study share s-…
|
|
358
|
+
# → https://<frontend>/share/study/Hk9_… (paste into an email)
|
|
359
|
+
|
|
360
|
+
ish study share s-… --expires 30 # auto-expire in 30 days
|
|
361
|
+
ish study share s-… --json # { token, share_url, expires_at, created_at, id }
|
|
362
|
+
|
|
363
|
+
# manage links
|
|
364
|
+
ish study share --list # all your links: token, study, expires, revoked
|
|
365
|
+
ish study unshare Hk9_… --yes # revoke by RAW TOKEN — URL stops working
|
|
366
|
+
\`\`\`
|
|
367
|
+
|
|
368
|
+
The \`share_url\` host is the web frontend (built server-side) — use it
|
|
369
|
+
verbatim; don't reconstruct it. Deep dive: \`ish docs get-page concepts/sharing\`.
|
|
370
|
+
|
|
305
371
|
## 2. Quick A/B ask with image variants
|
|
306
372
|
|
|
307
373
|
Goal: ship 30 simulated reactions to two hero images, with a "which do
|
|
@@ -1035,6 +1101,12 @@ table, projection shapes, and the defensive null-handling rules.
|
|
|
1035
1101
|
- For \`ask\` write-paths (update/archive/wait/add-questions/add-people),
|
|
1036
1102
|
default JSON is compact (changed fields + alias). Pass \`--verbose\` for
|
|
1037
1103
|
the full Ask payload.
|
|
1104
|
+
- The \`ish study create\`/\`update --json\` echo always shows
|
|
1105
|
+
\`assignments\` and \`interview_questions\` — \`[]\` when the study has
|
|
1106
|
+
none, never dropped. Trust it: an empty \`assignments\` means you
|
|
1107
|
+
genuinely created a study with no assignment (add one before
|
|
1108
|
+
\`study run\`, or it fails with "Study has no assignments"); you don't
|
|
1109
|
+
need a follow-up \`study get --verbose\` to tell "none" from "stripped".
|
|
1038
1110
|
- \`person generate --json\` returns \`{job: {id, status, person_ids},
|
|
1039
1111
|
profiles: [...]}\`; each person is the lean person shape with its
|
|
1040
1112
|
evidence-grounded \`scenarios\` attached (\`--no-scenarios\` to omit,
|
|
@@ -1127,7 +1199,7 @@ ish <command> --help
|
|
|
1127
1199
|
| \`mcp\` | Wire the hosted ish MCP server into local AI | guides/mcp-add |
|
|
1128
1200
|
| | clients (Cursor, VS Code, Claude Code, | |
|
|
1129
1201
|
| | Claude Desktop, Windsurf). Idempotent. | |
|
|
1130
|
-
| \`login\` | Browser-based auth. Idempotent: short-circuits
|
|
1202
|
+
| \`login\` | Browser-based auth. Idempotent: short-circuits only when the saved token is unexpired AND server-accepted. \`--force\` to switch accounts. | — |
|
|
1131
1203
|
| \`logout\` | Clear saved credentials | — |
|
|
1132
1204
|
| \`status\` | Show active session (user, workspace, | concepts/active-context |
|
|
1133
1205
|
| | study, ask, token validity) — alias \`whoami\` | |
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -22,6 +22,8 @@ export interface ProductUpdateInput {
|
|
|
22
22
|
description?: string;
|
|
23
23
|
color?: string;
|
|
24
24
|
base_url?: string;
|
|
25
|
+
/** External logo image URL — backend sets `logo.path` directly (feeds product_logo_url on shared study links). */
|
|
26
|
+
logo_url?: string;
|
|
25
27
|
}
|
|
26
28
|
export type SecretScope = "agent" | "project";
|
|
27
29
|
export type SecretVariableType = "secret" | "variable";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ishlabs/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
4
4
|
"description": "The command-line interface for ish",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -45,9 +45,11 @@
|
|
|
45
45
|
"@sentry/bun": "^10.13.0",
|
|
46
46
|
"@sentry/node": "^10.13.0",
|
|
47
47
|
"commander": "^13.0.0",
|
|
48
|
+
"http-proxy": "^1.18.1",
|
|
48
49
|
"playwright-core": "^1.58.2"
|
|
49
50
|
},
|
|
50
51
|
"devDependencies": {
|
|
52
|
+
"@types/http-proxy": "^1.17.17",
|
|
51
53
|
"@types/node": "^22.0.0",
|
|
52
54
|
"typescript": "^5.7.0"
|
|
53
55
|
}
|