@somacheck/vibecheck 0.6.10 → 0.6.12

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Sensie LLC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -9,13 +9,14 @@ Your agent has your context. It does not have your gut. This is the bridge.
9
9
 
10
10
  Fair. Here is what you need, without executing anything.
11
11
 
12
- **What the `link` command does.** `npx -y @somacheck/vibecheck@0.6.10 link <CODE> --client <CLIENT>`
12
+ **What the `link` command does.** `npx -y @somacheck/vibecheck@0.6.12 link <CODE> --client <CLIENT>`
13
13
  exchanges a short-lived pairing code, generated inside the SomaCheck iOS app, for
14
14
  a bearer token. It writes that token to `~/.sensie/config.json` with mode `0600`,
15
15
  offers to configure supported agent clients found on the computer, and checks the
16
16
  connection without printing the token. For Claude Code it also installs an
17
- inspectable user-scoped SomaCheck plugin that can wake the same open session when
18
- the phone result arrives. Setup is not reported ready until the
17
+ inspectable user-scoped SomaCheck plugin and registers the local MCP server as
18
+ a Channel so a phone result can enter the same open conversation as a new
19
+ event. Setup is not reported ready until the
19
20
  selected client has the exact pinned `vibecheck` MCP registration, the backend
20
21
  accepts protocol `5` / toolset `vibecheck-0.6`, and both status and context
21
22
  probes succeed. It contacts exactly one network host: the Supabase project below.
@@ -97,9 +98,9 @@ before the pairing code is redeemed.
97
98
  To configure or repair a client later:
98
99
 
99
100
  ```text
100
- npx -y @somacheck/vibecheck@0.6.10 setup codex
101
- npx -y @somacheck/vibecheck@0.6.10 setup claude
102
- npx -y @somacheck/vibecheck@0.6.10 doctor
101
+ npx -y @somacheck/vibecheck@0.6.12 setup codex
102
+ npx -y @somacheck/vibecheck@0.6.12 setup claude
103
+ npx -y @somacheck/vibecheck@0.6.12 doctor
103
104
  ```
104
105
 
105
106
  Manual registration remains available:
@@ -109,13 +110,25 @@ Manual registration remains available:
109
110
  "mcpServers": {
110
111
  "vibecheck": {
111
112
  "command": "npx",
112
- "args": ["-y", "@somacheck/vibecheck@0.6.10", "serve", "--client", "codex"]
113
+ "args": ["-y", "@somacheck/vibecheck@0.6.12", "serve", "--client", "codex"]
113
114
  }
114
115
  }
115
116
  }
116
117
  ```
117
118
 
118
- For Claude Code: `claude mcp add --scope user vibecheck -- npx -y @somacheck/vibecheck@0.6.10 serve --client claude`
119
+ For Claude Code: `claude mcp add --scope user vibecheck -- npx -y @somacheck/vibecheck@0.6.12 serve --client claude --channel`
120
+
121
+ Claude Channels are currently an Anthropic research preview. Until Anthropic
122
+ approves SomaCheck on its channel allowlist, start Claude Code with:
123
+
124
+ ```text
125
+ claude --dangerously-load-development-channels server:vibecheck
126
+ ```
127
+
128
+ Keep that Claude Code session open. Channel events are queued while Claude is
129
+ busy, but a closed session cannot receive them. Claude does not acknowledge
130
+ channel notifications, so retain the stable `live:<uuid>` request handle as a
131
+ manual recovery path.
119
132
 
120
133
  The link step writes only the bearer token in `~/.sensie/config.json`. The client
121
134
  setup step asks Codex or Claude to add the pinned MCP command to that client's own
@@ -177,6 +190,74 @@ npx skills add Sensie-agents/vibecheck --skill vibecheck
177
190
  The skill expects the `@somacheck/vibecheck` MCP server to already be linked as
178
191
  `vibecheck`. Installing the skill does not copy or replace the bearer token.
179
192
 
193
+ ## Agent reflection recipes
194
+
195
+ Give your agent a consented signal when words are the bottleneck. These recipes
196
+ combine SomaCheck with a named platform so a person can privately reflect on
197
+ their own wording, interpretation, study design, or listening choice:
198
+
199
+ - [Typeform + SomaCheck](recipes/typeform-research-reflection.md)
200
+ - [Dovetail + SomaCheck](recipes/dovetail-research-reflection.md)
201
+ - [Prolific + SomaCheck](recipes/prolific-research-reflection.md)
202
+ - [Maze + SomaCheck](recipes/maze-research-reflection.md)
203
+ - [Chattermill + SomaCheck](recipes/chattermill-research-reflection.md)
204
+ - [User Interviews + SomaCheck](recipes/user-interviews-research-reflection.md)
205
+ - [Sprig + SomaCheck](recipes/sprig-research-reflection.md)
206
+ - [Great Question + SomaCheck](recipes/great-question-research-reflection.md)
207
+ - [QuestionPro + SomaCheck](recipes/questionpro-research-reflection.md)
208
+ - [Spotify manual Studio/Kit bridge + SomaCheck](recipes/spotify-listening-reflection.md)
209
+
210
+ The research recipes are researcher-private, and the Spotify recipe is
211
+ listener-private. They do not assess respondents, participants, creators, or
212
+ other listeners; export individual readings; authorize platform changes; or use
213
+ SomaCheck for quality, truthfulness, eligibility, payment, employment, ranking,
214
+ or research validity. A reading is context for the phone holder's next choice;
215
+ the person remains the authority.
216
+
217
+ List the packaged experiences without connecting to either MCP server:
218
+
219
+ ```text
220
+ npx -y @somacheck/vibecheck recipes
221
+ ```
222
+
223
+ Print one experience's prerequisites, success condition, and exact starter
224
+ prompt:
225
+
226
+ ```text
227
+ npx -y @somacheck/vibecheck recipe typeform-research-reflection-v1
228
+ npx -y @somacheck/vibecheck recipe dovetail-research-reflection-v1
229
+ npx -y @somacheck/vibecheck recipe prolific-research-reflection-v1
230
+ npx -y @somacheck/vibecheck recipe user-interviews-research-reflection-v1
231
+ ```
232
+
233
+ Print only a copyable starter prompt for the read-only direct-MCP tests:
234
+
235
+ ```text
236
+ npx -y @somacheck/vibecheck recipes --id maze-research-reflection-v1 --format prompt
237
+ npx -y @somacheck/vibecheck recipes --id chattermill-research-reflection-v1 --format prompt
238
+ npx -y @somacheck/vibecheck recipes --id user-interviews-research-reflection-v1 --format prompt
239
+ ```
240
+
241
+ These commands only print guides. They do not install, connect, or authorize a
242
+ partner MCP server, call either MCP, or change partner-platform state. In every
243
+ recipe, the phone holder is the person reflecting on their own choice.
244
+
245
+ ### Private Studio pilot packet
246
+
247
+ [`recipes/studio-somacheck-context.md`](recipes/studio-somacheck-context.md) is
248
+ a reviewed, paste-only context packet for a private Studio by Spotify Labs
249
+ research-preview pilot. It is deliberately absent from `vibecheck recipes`: it
250
+ is not a connected or live recipe, a Studio skill, a Kit plugin, or native MCP.
251
+ Review the packet and run its focused contract test before any pilot:
252
+
253
+ ```text
254
+ node --import tsx --test test/studio-context-packet.test.ts
255
+ ```
256
+
257
+ Run that command from `packages/vibecheck` after `npm install`. Do not grant
258
+ Studio access to this repository or another directory. File access remains
259
+ blocked until the capability and revocation probe in the safety review passes.
260
+
180
261
  ## Tools
181
262
 
182
263
  | Tool | What it does |
@@ -207,14 +288,22 @@ cancellation stops result reads and preserves the backend request and
207
288
  idempotency key, but the cancelled MCP transport may suppress that pending
208
289
  response.
209
290
 
210
- Standard MCP cannot start a new agent turn after a tool call has ended. The
211
- Claude setup therefore installs a normal user-scoped plugin with an async
212
- `PostToolUse` hook. When `request_vibecheck` returns pending, that hook follows
213
- only the exact request and wakes the same open Claude Code session when the
214
- answer, expiry, or cancellation arrives. It passes the constrained result and
215
- opaque handle, never the statement or link token, and cannot create another
216
- phone request. No experimental launch flag is required. Restart Claude Code
217
- once after setup so it loads the plugin.
291
+ Claude Code is the primary local experience. Its registered stdio server
292
+ advertises Anthropic's experimental Channel capability. When
293
+ `request_vibecheck` returns pending, the same local server follows only that
294
+ exact request and emits one `notifications/claude/channel` event when the
295
+ answer, expiry, or cancellation arrives. Claude receives the constrained
296
+ result as conversation input and can continue without another user message.
297
+ The event contains the binary reading, confidence, lifecycle, and opaque
298
+ handle—never the statement, link token, raw motion, or an instruction that
299
+ turns the result into authorization.
300
+
301
+ The installed `PostToolUse` hook remains a compatibility fallback for an
302
+ ordinary non-channel registration. A channel-armed response marks its
303
+ continuation transport explicitly, and the hook abstains, so two watchers
304
+ cannot wake the same turn. During Anthropic's research preview, the channel
305
+ session must be launched with the command above; a closed or non-enabled
306
+ session may silently drop the event.
218
307
 
219
308
  Other standard MCP hosts retain the bounded tool response and stable-handle
220
309
  fallback until they provide an equivalent supported wake mechanism. This
@@ -223,7 +312,9 @@ pending response without that hook (including the hosted connector, which is
223
312
  stateless per request and never arms the watch) tells the agent the exact
224
313
  `request_id` and the person's expiry, and to call `get_vibecheck_result` again
225
314
  in about 15 seconds, repeating at that cadence until the state is answered or
226
- expired.
315
+ expired without ending the turn or asking the person whether to check. A
316
+ still-pending read of the same Live Ask repeats that instruction; the read does
317
+ not invent an expiry because the result endpoint does not return one.
227
318
 
228
319
  The 45-second whole-call deadline also covers the one create request. If that
229
320
  network request is aborted after an ambiguous commit, retry the exact same
@@ -10,7 +10,7 @@
10
10
  "name": "vibecheck",
11
11
  "source": "./plugins/vibecheck",
12
12
  "description": "Let Claude offer a vibecheck and continue when the phone result arrives.",
13
- "version": "0.6.10",
13
+ "version": "0.6.12",
14
14
  "author": {
15
15
  "name": "Sensie",
16
16
  "email": "agents@joinsensie.com"
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "vibecheck",
3
3
  "description": "Let Claude offer a SomaCheck vibecheck and continue when the phone result arrives.",
4
- "version": "0.6.10",
4
+ "version": "0.6.12",
5
5
  "author": {
6
6
  "name": "Sensie",
7
7
  "email": "agents@joinsensie.com"
8
8
  },
9
- "homepage": "https://github.com/sensie-app/Somacheck/tree/main/packages/vibecheck",
10
- "repository": "https://github.com/sensie-app/Somacheck",
11
- "license": "UNLICENSED",
9
+ "homepage": "https://github.com/Sensie-agents/vibecheck",
10
+ "repository": "https://github.com/Sensie-agents/vibecheck",
11
+ "license": "MIT",
12
12
  "keywords": ["vibecheck", "somacheck", "decision-support", "mcp"]
13
13
  }
@@ -7,7 +7,7 @@
7
7
  "hooks": [
8
8
  {
9
9
  "type": "command",
10
- "command": "npx -y @somacheck/vibecheck@0.6.10 claude-hook await-result",
10
+ "command": "npx -y @somacheck/vibecheck@0.6.12 claude-hook await-result",
11
11
  "asyncRewake": true,
12
12
  "timeout": 900
13
13
  }
@@ -21,6 +21,10 @@ export function parsePendingClaudeAsk(input) {
21
21
  const structured = record(response.structuredContent ?? response.structured_content ?? response);
22
22
  if (structured.state !== "pending" || typeof structured.request_id !== "string")
23
23
  return null;
24
+ // The channel-enabled local server already owns this exact result watch.
25
+ // Abstaining prevents the PostToolUse fallback from waking Claude twice.
26
+ if (structured.continuation_transport === "claude_channel")
27
+ return null;
24
28
  if (structured.delivery_state === "failed" || structured.delivery_state === "skipped")
25
29
  return null;
26
30
  const requestId = parseHandle(structured.request_id);
package/dist/cli.js CHANGED
@@ -3,13 +3,15 @@ import { homedir } from "node:os";
3
3
  import { createInterface } from "node:readline/promises";
4
4
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5
5
  import { SupabaseAgentApi } from "./api.js";
6
- import { clientDisplayName, detectInstalledClients, detectLegacyHostedRegistration, LocalCommandRunner, manualLegacyHostedRemoveCommand, manualRemoveCommand, manualSetupCommand, parseClientChoice, preflightClientPersistence, registerClient, singleNonInteractiveClientSelection, } from "./client-setup.js";
6
+ import { claudeChannelLaunchCommand, clientDisplayName, detectInstalledClients, detectLegacyHostedRegistration, LocalCommandRunner, manualLegacyHostedRemoveCommand, manualRemoveCommand, manualSetupCommand, parseClientChoice, preflightClientPersistence, registerClient, singleNonInteractiveClientSelection, } from "./client-setup.js";
7
7
  import { configureClaudeContinuationPlugin } from "./claude-plugin-setup.js";
8
8
  import { readConfig } from "./config.js";
9
9
  import { awaitClaudeVibecheckResult } from "./claude-hook.js";
10
10
  import { PACKAGE_SPEC, SUPABASE_PUBLISHABLE_KEY, SUPABASE_URL } from "./constants.js";
11
11
  import { LinkPersistenceError, NonInteractiveLinkError, linkAgent } from "./link.js";
12
12
  import { checkReadiness } from "./readiness.js";
13
+ import { formatRecipeDetail, formatRecipeList, formatRecipePrompt, getRecipeExperience } from "./recipes.js";
14
+ import { parseRuntimeMode } from "./runtime-mode.js";
13
15
  import { createVibecheckServer } from "./server.js";
14
16
  const api = new SupabaseAgentApi(SUPABASE_URL, SUPABASE_PUBLISHABLE_KEY);
15
17
  const runner = new LocalCommandRunner();
@@ -26,6 +28,10 @@ function usage() {
26
28
  " npx -y @somacheck/vibecheck link <CODE> [--client codex|claude|all|none]",
27
29
  " npx -y @somacheck/vibecheck setup <codex|claude|all>",
28
30
  " npx -y @somacheck/vibecheck doctor",
31
+ " npx -y @somacheck/vibecheck recipes",
32
+ " npx -y @somacheck/vibecheck recipes --id <id> --format prompt",
33
+ " npx -y @somacheck/vibecheck recipe <id>",
34
+ " npx -y @somacheck/vibecheck serve --client claude --channel",
29
35
  ].join("\n");
30
36
  }
31
37
  function parseLinkClient(args) {
@@ -42,11 +48,6 @@ function parseLinkClient(args) {
42
48
  return [];
43
49
  throw new Error(usage());
44
50
  }
45
- function parseServeClient(args) {
46
- if (args.length !== 3 || args[0] !== "serve" || args[1] !== "--client")
47
- return null;
48
- return args[2] === "codex" || args[2] === "claude" ? args[2] : null;
49
- }
50
51
  async function promptForClients(installed) {
51
52
  if (installed.length === 0)
52
53
  return [];
@@ -101,6 +102,7 @@ async function configureClients(clients) {
101
102
  throw new ClientPreflightError("Could not configure automatic SomaCheck results for Claude Code. No pairing code was used.");
102
103
  }
103
104
  output(`✓ Automatic Claude result continuation ${plugin.status === "installed" ? "was configured" : "is ready"}.`);
105
+ output(` Start Claude Code with SomaCheck Channels: ${claudeChannelLaunchCommand()}`);
104
106
  }
105
107
  }
106
108
  }
@@ -176,6 +178,7 @@ async function preflightLinkClients(clients, interactive) {
176
178
  ].join("\n"));
177
179
  }
178
180
  output("✓ Automatic Claude result continuation is ready before redeeming the pairing code.");
181
+ output(` Start Claude Code with SomaCheck Channels: ${claudeChannelLaunchCommand()}`);
179
182
  }
180
183
  }
181
184
  return selectedClients;
@@ -197,13 +200,15 @@ async function refreshRuntimeHealth(client) {
197
200
  context_probe_ok: true,
198
201
  });
199
202
  }
200
- async function startServer(runtimeClient) {
203
+ async function startServer(runtime) {
204
+ const runtimeClient = runtime?.client ?? null;
201
205
  const server = createVibecheckServer({
202
206
  api,
203
207
  loadToken: async () => (await readConfig(homedir(), runtimeClient ?? undefined)).token,
204
208
  identity: runtimeClient === null
205
209
  ? { kind: "legacy" }
206
210
  : { kind: "local", client_key: runtimeClient },
211
+ ...(runtime?.claudeChannel ? { claudeChannelWatch: {} } : {}),
207
212
  });
208
213
  await server.connect(new StdioServerTransport());
209
214
  if (runtimeClient !== null) {
@@ -228,6 +233,33 @@ async function main() {
228
233
  if (args.length === 2 && args[0] === "claude-hook" && args[1] === "await-result") {
229
234
  return runClaudeResultHook();
230
235
  }
236
+ if (args[0] === "recipes") {
237
+ if (args.length === 1) {
238
+ output(formatRecipeList());
239
+ return 0;
240
+ }
241
+ if (args.length === 5 && args[1] === "--id" && args[3] === "--format" && args[4] === "prompt") {
242
+ const recipe = getRecipeExperience(args[2]);
243
+ if (recipe === null) {
244
+ process.stderr.write(`Unknown recipe ID.\n\n${formatRecipeList()}\n`);
245
+ return 1;
246
+ }
247
+ output(formatRecipePrompt(recipe));
248
+ return 0;
249
+ }
250
+ throw new Error(usage());
251
+ }
252
+ if (args[0] === "recipe") {
253
+ if (args.length !== 2)
254
+ throw new Error(usage());
255
+ const recipe = getRecipeExperience(args[1]);
256
+ if (recipe === null) {
257
+ process.stderr.write(`Unknown recipe ID.\n\n${formatRecipeList()}\n`);
258
+ return 1;
259
+ }
260
+ output(formatRecipeDetail(recipe));
261
+ return 0;
262
+ }
231
263
  if (args[0] === "link") {
232
264
  if (args.length < 2)
233
265
  throw new Error(usage());
@@ -268,9 +300,9 @@ async function main() {
268
300
  throw new Error(usage());
269
301
  return (await runDoctor()) ? 0 : 2;
270
302
  }
271
- const runtimeClient = parseServeClient(args);
272
- if (runtimeClient !== null) {
273
- await startServer(runtimeClient);
303
+ const runtime = parseRuntimeMode(args);
304
+ if (runtime !== null) {
305
+ await startServer(runtime);
274
306
  return 0;
275
307
  }
276
308
  if (args.length !== 0)
@@ -26,7 +26,11 @@ export function clientDisplayName(client) {
26
26
  return client === "codex" ? "Codex / ChatGPT desktop" : "Claude Code";
27
27
  }
28
28
  function mcpServerArgs(client) {
29
- return ["-y", PACKAGE_SPEC, "serve", "--client", client];
29
+ const args = ["-y", PACKAGE_SPEC, "serve", "--client", client];
30
+ return client === "claude" ? [...args, "--channel"] : args;
31
+ }
32
+ export function claudeChannelLaunchCommand() {
33
+ return `claude --dangerously-load-development-channels server:${MCP_SERVER_NAME}`;
30
34
  }
31
35
  export function manualSetupCommand(client) {
32
36
  if (client === "codex") {
@@ -149,7 +153,9 @@ function isManagedSomaCheckRegistration(client, stdout) {
149
153
  || packageArg === "@somacheck/vibecheck@0.6.6"
150
154
  || packageArg === "@somacheck/vibecheck@0.6.7"
151
155
  || packageArg === "@somacheck/vibecheck@0.6.8"
152
- || packageArg === "@somacheck/vibecheck@0.6.9")
156
+ || packageArg === "@somacheck/vibecheck@0.6.9"
157
+ || packageArg === "@somacheck/vibecheck@0.6.10"
158
+ || packageArg === "@somacheck/vibecheck@0.6.11")
153
159
  && args.length === 5
154
160
  && args[0] === "-y"
155
161
  && args[1] === packageArg
package/dist/constants.js CHANGED
@@ -2,8 +2,9 @@
2
2
  export const SUPABASE_URL = "https://pbldcmniommltbdwuykk.supabase.co";
3
3
  export const SUPABASE_PUBLISHABLE_KEY = "sb_publishable_af-lUNI2FqEcb-oGy-4uxQ_cnm6kY85";
4
4
  export const PACKAGE_NAME = "@somacheck/vibecheck";
5
- export const PACKAGE_VERSION = "0.6.10";
5
+ export const PACKAGE_VERSION = "0.6.12";
6
6
  export const PACKAGE_SPEC = `${PACKAGE_NAME}@${PACKAGE_VERSION}`;
7
+ export const SOMACHECK_SETUP_URL = "https://testflight.apple.com/join/C4mAH3zz";
7
8
  export const MCP_SERVER_NAME = "vibecheck";
8
9
  export const LEGACY_HOSTED_MCP_SERVER_NAME = "somacheck";
9
10
  export const BACKEND_PROTOCOL_VERSION = 5;
package/dist/readiness.js CHANGED
@@ -3,7 +3,7 @@ import { join } from "node:path";
3
3
  import { readConfig } from "./config.js";
4
4
  import { SomaCheckCompatibilityError, SomaCheckHttpError } from "./api.js";
5
5
  import { clientDisplayName, clientRegistrationState, detectLegacyHostedRegistration, isClientInstalled, manualLegacyHostedRemoveCommand, manualRemoveCommand, manualSetupCommand, } from "./client-setup.js";
6
- import { BACKEND_PROTOCOL_VERSION, PACKAGE_VERSION } from "./constants.js";
6
+ import { BACKEND_PROTOCOL_VERSION, PACKAGE_VERSION, SOMACHECK_SETUP_URL } from "./constants.js";
7
7
  function vibecheckRegistrationCount(value) {
8
8
  if (!value || typeof value !== "object")
9
9
  return 0;
@@ -32,7 +32,7 @@ export async function checkReadiness(dependencies) {
32
32
  }
33
33
  catch {
34
34
  dependencies.output("✗ This computer is not linked to SomaCheck.");
35
- dependencies.output(" Install SomaCheck from the current TestFlight invitation: https://testflight.apple.com/join/C4mAH3zz");
35
+ dependencies.output(` Install SomaCheck from the current TestFlight invitation: ${SOMACHECK_SETUP_URL}`);
36
36
  dependencies.output(" Then open SomaCheck → Settings → Agent → Connect your agent and run the command shown there.");
37
37
  return {
38
38
  linked: false,
@@ -0,0 +1,191 @@
1
+ export const RECIPE_CATALOG = [
2
+ {
3
+ id: "typeform-research-reflection-v1",
4
+ title: "Typeform + SomaCheck Research Reflection",
5
+ guidePath: "recipes/typeform-research-reflection.md",
6
+ purpose: "Privately reflect on the researcher's own Typeform wording, structure, or launch readiness.",
7
+ phoneHolder: "The phone holder is the researcher reflecting on their own work, never a respondent or employee.",
8
+ prerequisites: [
9
+ "SomaCheck is ready on the researcher's iPhone and the vibecheck MCP is linked to that researcher's agent client.",
10
+ "The researcher has separately connected and authorized Typeform MCP for the correct account and data region; this command does not connect or authorize it.",
11
+ "The researcher can name one researcher-authored form, draft, or aggregate analytics view that does not require respondent rows, contacts, identifiers, or free-text answers.",
12
+ ],
13
+ starterPrompt: "Review the researcher-authored structure of my Typeform [FORM NAME OR ID] using only form structure, logic, and aggregate analytics—never respondent-level rows, contacts, identifiers, or free-text answers. Then help me privately reflect on my own wording or readiness with one optional SomaCheck vibecheck. If you propose a vibecheck, show me the exact first-person proposition and wait for my acceptance. Treat Aligned or Unaligned plus confidence as context, not truth or authorization. Do not write the reading to Typeform, and stop before any Typeform edit or publication until I separately approve the exact change.",
14
+ successCondition: "The researcher receives at most one optional signal about their own proposition and chooses the next step; no respondent data or SomaCheck result enters Typeform, and no Typeform state changes without separate explicit approval.",
15
+ },
16
+ {
17
+ id: "dovetail-research-reflection-v1",
18
+ title: "Dovetail + SomaCheck Research Reflection",
19
+ guidePath: "recipes/dovetail-research-reflection.md",
20
+ purpose: "Privately reflect on the researcher's own Dovetail planning document or evidence interpretation.",
21
+ phoneHolder: "The phone holder is the researcher reflecting on their own work, never a participant or employee.",
22
+ prerequisites: [
23
+ "SomaCheck is ready on the researcher's iPhone and the vibecheck MCP is linked to that researcher's agent client.",
24
+ "The researcher has separately connected and authorized Dovetail MCP for the intended workspace; this command does not connect or authorize it.",
25
+ "The researcher can name one researcher-authored, participant-free Dovetail brief, guide, plan, or de-identified synthesis.",
26
+ ],
27
+ starterPrompt: "Review only my researcher-authored Dovetail doc [DOC TITLE OR ID]. Do not open raw interviews, transcripts, recordings, highlights, contacts, identifiers, participant responses, or any broader workspace content. Separate what the document says from what you infer, then help me privately reflect on my own interpretation or next step with one optional SomaCheck vibecheck. If you propose a vibecheck, show me the exact first-person proposition and wait for my acceptance. Treat Aligned or Unaligned plus confidence as context, not truth or authorization. Keep the reading out of Dovetail, and do not create a comment or make another Dovetail change unless I separately approve its exact signal-free content.",
28
+ successCondition: "The researcher receives at most one optional signal about their own proposition and chooses the next step; no participant material or SomaCheck result enters the cross-MCP flow, and Dovetail changes require separate explicit approval.",
29
+ },
30
+ {
31
+ id: "prolific-research-reflection-v1",
32
+ title: "Prolific + SomaCheck Research Reflection",
33
+ guidePath: "recipes/prolific-research-reflection.md",
34
+ purpose: "Privately reflect on the researcher's own Prolific study or recruitment plan before formal review.",
35
+ phoneHolder: "The phone holder is the researcher reflecting on their own work, never a participant or employee.",
36
+ prerequisites: [
37
+ "SomaCheck is ready on the researcher's iPhone and the vibecheck MCP is linked to that researcher's agent client.",
38
+ "The researcher has separately installed, reviewed, pinned, and authorized the official Prolific MCP server; this command does not install, connect, or authorize it.",
39
+ "The researcher can name one researcher-owned workspace, project, or draft study without retrieving submissions, messages, participant identifiers, responses, or demographic exports.",
40
+ ],
41
+ starterPrompt: "Review my researcher-owned Prolific [WORKSPACE, PROJECT, OR DRAFT STUDY NAME OR ID] using only minimum study-planning information. Do not retrieve participant-level data or use a SomaCheck result for recruitment, filtering, eligibility, payment, quality, authenticity, or performance. Separate the study facts from your inferences, then help me privately reflect on my own plan or readiness with one optional SomaCheck vibecheck. If you propose a vibecheck, show me the exact first-person proposition and wait for my acceptance. Treat Aligned or Unaligned plus confidence as context, not truth or authorization. Do not create filters or studies, publish, spend money, or write the reading to Prolific.",
42
+ successCondition: "The researcher receives at most one optional signal about their own proposition and chooses the next step; no participant data or SomaCheck result enters Prolific, and the recipe creates no filter, study, publication, or spend.",
43
+ },
44
+ {
45
+ id: "maze-research-reflection-v1",
46
+ title: "Maze + SomaCheck Research Reflection",
47
+ guidePath: "recipes/maze-research-reflection.md",
48
+ purpose: "Privately reflect on the researcher's interpretation of one Maze study using metadata or one aggregate summary, with no Maze mutation.",
49
+ phoneHolder: "The phone holder is the researcher reflecting on their own interpretation plan, never a participant, respondent, tester, or employee.",
50
+ prerequisites: [
51
+ "SomaCheck is ready on the researcher's iPhone and the vibecheck MCP is linked to that researcher's agent client.",
52
+ "The product or integration owner has provisioned an organization-authorized Maze connection or partner sandbox at https://connect.maze.co/mcp; running this recipe does not ask the researcher to sign up, upgrade, administer access, or populate Maze data.",
53
+ "The provisioned workspace supplies one named existing study with safe metadata or an aggregate summary; if it does not, the Maze half remains untested and the researcher still receives a copy-ready plan.",
54
+ ],
55
+ starterPrompt: "Use Maze and SomaCheck to help me reflect on my own interpretation plan for one named Maze study. I am the researcher and I am holding the phone. The study is [STUDY NAME OR ID PROVIDED BY THE WORKSPACE OWNER]. Use only the preconfigured official hosted read-only Maze MCP at https://connect.maze.co/mcp. Read only that study's safe metadata or one aggregate summary. Do not retrieve transcripts, recordings, heatmaps, click maps, mission answers, participant identifiers, contact fields, demographic exports, free text, or row-level data. Label what Maze literally reports separately from your interpretation, then offer two defensible framings. Offer one short first-person proposition about my own interpretation plan and wait for my acceptance before any proactive SomaCheck ask. Treat Aligned or Unaligned plus confidence as context, not truth, diagnosis, authorization, or evidence about a participant. Ask what I choose in words. Keep the proposition, reading, confidence, and confirmation out of Maze. Do not create, edit, publish, delete, archive, export, share, tag, comment, or otherwise write to Maze. If the preconfigured connection or a safe runtime read is absent, label the Maze half untested, return a copy-ready interpretation plan, and tell the integration owner what capability is missing. Do not ask me to sign up, upgrade, administer access, or populate Maze data.",
56
+ successCondition: "The researcher receives at most one optional signal about their own proposition and states a typed choice after a real metadata or aggregate read from a preconfigured workspace; no participant data or SomaCheck output enters Maze, and the Maze workspace remains unchanged.",
57
+ },
58
+ {
59
+ id: "chattermill-research-reflection-v1",
60
+ title: "Chattermill + SomaCheck Research Reflection",
61
+ guidePath: "recipes/chattermill-research-reflection.md",
62
+ purpose: "Privately reflect on aggregate Chattermill metrics or generated highlights while excluding individual feedback and every write path.",
63
+ phoneHolder: "The phone holder is the researcher reflecting on their own interpretation, never a customer, respondent, participant, or employee.",
64
+ prerequisites: [
65
+ "SomaCheck is ready on the researcher's iPhone and the vibecheck MCP is linked to that researcher's agent client.",
66
+ "The product or integration owner has provisioned an organization-authorized Chattermill connection or partner sandbox at https://app.chattermill.com/mcp with mcp:read; running this recipe does not ask the researcher to sign up, purchase access, administer access, or populate Chattermill data.",
67
+ "The provisioned workspace supplies one named existing project for which get_metrics or generate_highlights is sufficient; get_feedback, search_observations, identifier-bearing attributes, and free text remain prohibited.",
68
+ ],
69
+ starterPrompt: "Use Chattermill and SomaCheck to help me reflect on my own interpretation of one named project's customer-feedback insights. I am the researcher and I am holding the phone. The project is [PROJECT NAME OR ID PROVIDED BY THE WORKSPACE OWNER]. Use only the preconfigured official hosted read-only Chattermill MCP at https://app.chattermill.com/mcp. Read only aggregate metrics with get_metrics or generated highlights with generate_highlights, plus the minimum discovery metadata needed to build that query. Never call get_feedback or search_observations, enumerate identifier-bearing attributes, or surface individual feedback, source quotes, respondent identifiers, contact fields, or free text. Label what the aggregate output literally reports separately from your interpretation, then offer two defensible interpretations. Offer one short first-person proposition about my own interpretation or next step and wait for my acceptance before any proactive SomaCheck ask. Treat Aligned or Unaligned plus confidence as context, not truth, diagnosis, authorization, or evidence about an individual customer. Ask what I choose in words. Keep the proposition, reading, confidence, and confirmation out of Chattermill. Do not create, edit, publish, delete, share, export, tag, comment, or otherwise write to Chattermill. If the preconfigured connection, mcp:read, or a safe aggregate runtime tool is absent, label the Chattermill half untested, return a copy-ready interpretation, and tell the integration owner what capability is missing. Do not ask me to sign up, purchase access, administer access, or populate Chattermill data.",
70
+ successCondition: "The researcher receives at most one optional signal about their own proposition and states a typed choice after a real aggregate or generated-summary read from a preconfigured workspace; no individual feedback or SomaCheck output enters the cross-MCP flow, and Chattermill remains unchanged.",
71
+ },
72
+ {
73
+ id: "user-interviews-research-reflection-v1",
74
+ title: "User Interviews + SomaCheck Research Reflection",
75
+ guidePath: "recipes/user-interviews-research-reflection.md",
76
+ purpose: "Privately reflect on the researcher's own User Interviews study framing and produce a copy-ready test-project plan without calling a platform mutation.",
77
+ phoneHolder: "The phone holder is the researcher reflecting on their own study direction, never a respondent, participant, candidate, or employee.",
78
+ prerequisites: [
79
+ "SomaCheck is ready on the researcher's iPhone and the vibecheck MCP is linked to that researcher's agent client.",
80
+ "The planning workflow requires no User Interviews account or connector because it calls no platform data or action tool.",
81
+ "For partner integration validation only, the product or integration owner may supply a preconfigured partner sandbox whose runtime capability list can be inspected without invoking a project, recruitment, participant-data, contact, publication, or spend tool; the researcher is never asked to request access or populate platform data.",
82
+ ],
83
+ starterPrompt: "Use User Interviews and SomaCheck to help me prepare one clearly named, participant-free test-project plan without changing User Interviews. I am the researcher and I am holding the phone. The study idea is [STUDY IDEA]. Work only from what I provide here. If a product or integration owner has supplied a preconfigured official User Interviews partner sandbox, you may inspect its capability names and schemas, but do not call any platform data or action tool. The planning workflow does not require me to sign up, request access, purchase a plan, or populate User Interviews data. Do not retrieve candidates, participants, screeners, responses, profiles, identifiers, messages, recordings, transcripts, session data, or other workspace data. Propose two neutral study framings and show the exact signal-free project copy. Then offer one short first-person proposition about my own preferred direction and wait for my acceptance before any proactive SomaCheck ask. Treat Aligned or Unaligned plus confidence as context, not truth, diagnosis, authorization, or evidence about another person. Ask what I choose in words. Keep the proposition, reading, confidence, and confirmation out of User Interviews. Return a copy-ready project payload only. Do not create, edit, recruit, invite, message, schedule, screen, launch, publish, attach incentives, spend, read participant data, or call a broader or undocumented tool.",
84
+ successCondition: "The researcher receives at most one optional signal about their own proposition and states a typed choice; the agent returns a copy-ready signal-free test-project plan, invokes no User Interviews data or action tool, and performs no recruitment, participant read, contact, mutation, launch, publication, incentive, payment, or spend.",
85
+ },
86
+ {
87
+ id: "sprig-research-reflection-v1",
88
+ title: "Sprig + SomaCheck Research Reflection",
89
+ guidePath: "recipes/sprig-research-reflection.md",
90
+ purpose: "Privately reflect on an owner-supplied, participant-free Sprig test artifact and return a copy-ready revision without changing Sprig.",
91
+ phoneHolder: "The phone holder is the researcher reflecting on their own study direction, never a respondent or employee.",
92
+ prerequisites: [
93
+ "SomaCheck is ready on the researcher's iPhone and the vibecheck MCP is linked to that researcher's agent client.",
94
+ "The product or integration owner has provisioned an organization-authorized Sprig connection or partner sandbox; this workflow does not ask the researcher to sign up, upgrade, purchase access, administer access, or populate Sprig data.",
95
+ "The owner supplies one clearly named, participant-free test artifact and a least-privilege runtime tool that can read only the artifact metadata and question text needed for the review.",
96
+ ],
97
+ starterPrompt: "Use Sprig and SomaCheck to help me privately reflect on one participant-free test artifact supplied by the product or integration owner. I am the researcher and I am holding the phone. The artifact is [TEST ARTIFACT NAME OR ID PROVIDED BY THE OWNER]. Use only the preconfigured Sprig partner sandbox or organization-authorized connection. Read only the minimum artifact metadata and question text needed for this review. Do not retrieve responses, themes, source quotes, respondent fields, identifiers, contact data, or PII. Offer two defensible wording directions, then offer one short first-person proposition about my own direction and wait for my acceptance before any proactive SomaCheck ask. After the check, use only the proposition, Aligned or Unaligned, and confidence together with our conversation context; exercise your judgment about the next conversational move and do not apply a fixed script to either result. I decide what the signal means and what happens next. Keep the proposition, reading, confidence, and confirmation out of Sprig. Return a copy-ready, signal-free revision only. Do not create, edit, publish, delete, share, archive, export, duplicate, target, distribute, launch, contact anyone, or otherwise write to Sprig. If the preconfigured connection or safe read tool is absent, label the Sprig half untested, work only from a participant-free brief I provide, and tell the integration owner what capability is missing. Do not ask me to sign up, upgrade, purchase access, administer access, or populate Sprig data.",
98
+ successCondition: "The researcher receives at most one optional signal about their own proposition, the agent retains judgment about the next conversational move, and the researcher receives a copy-ready signal-free revision after a narrow read of an owner-supplied participant-free test artifact; no research data or SomaCheck output crosses systems, and Sprig remains unchanged.",
99
+ },
100
+ {
101
+ id: "great-question-research-reflection-v1",
102
+ title: "Great Question + SomaCheck Research Reflection",
103
+ guidePath: "recipes/great-question-research-reflection.md",
104
+ purpose: "Privately reflect on a survey framing using one owner-provisioned, participant-free Great Question test artifact without changing Great Question.",
105
+ phoneHolder: "The phone holder is the researcher reflecting on their own study framing, never a candidate, participant, or employee.",
106
+ prerequisites: [
107
+ "SomaCheck is ready on the researcher's iPhone and the vibecheck MCP is linked to that researcher's agent client.",
108
+ "The product or integration owner has provisioned an organization-authorized Great Question connection or partner sandbox at https://greatquestion.co/api/mcp/v1 with PII hiding enabled; running this recipe does not ask the researcher to sign up, upgrade, purchase, administer access, or populate Great Question data.",
109
+ "The owner supplies one participant-free test study, and the client restricts the platform half to get_survey_study for that exact artifact; no discovery or mutation tool is approved.",
110
+ ],
111
+ starterPrompt: "Use Great Question and SomaCheck to help me reflect on a five-question test survey plan without changing Great Question. I am the researcher and I am holding the phone. The product or integration owner has provisioned a partner sandbox and named this participant-free test study: [TEST STUDY NAME OR ID]. Read only that study's safe title, purpose, and question structure with get_survey_study. Do not search or list the workspace, and do not read candidates, participants, screeners, responses, sessions, transcripts, recordings, highlights, insights, reels, or other workspace data. Propose two neutral study framings and show their exact questions. Then offer one short first-person proposition about my own preferred framing and wait for my acceptance before any proactive SomaCheck ask. Give the agent the Aligned or Unaligned result plus confidence as context and let it use that context with its judgment. Ask what I choose in words. Keep the proposition, reading, confidence, and my confirmation out of Great Question. Return a signal-free, copy-ready research plan only. Do not create, update, delete, recruit, invite, message, schedule, incentivize, launch, publish, or otherwise write to Great Question. Do not ask me to sign up, upgrade, purchase, administer access, or populate Great Question data.",
112
+ successCondition: "The researcher receives at most one optional signal, states a choice, and receives a copy-ready five-question plan; only get_survey_study reads the exact owner-supplied test artifact, Great Question remains unchanged, and no recruitment or participant data is accessed.",
113
+ },
114
+ {
115
+ id: "questionpro-research-reflection-v1",
116
+ title: "QuestionPro + SomaCheck Research Reflection",
117
+ guidePath: "recipes/questionpro-research-reflection.md",
118
+ purpose: "Privately compare questionnaire wording and return a copy-ready, non-distributed survey plan for a partner-owned evaluation.",
119
+ phoneHolder: "The phone holder is the researcher reflecting on their own questionnaire wording, never a respondent, audience member, or employee.",
120
+ prerequisites: [
121
+ "SomaCheck is ready on the researcher's iPhone and the vibecheck MCP is linked to that researcher's agent client.",
122
+ "A QuestionPro or integration owner supplies a partner-approved sandbox or schema fixture; the researcher is not asked to sign up, upgrade, or populate vendor data.",
123
+ "Any live discovery is limited to schemas at https://mcp.questionpro.com/surveybuilder, never a root or all-tools endpoint.",
124
+ ],
125
+ starterPrompt: "Use QuestionPro and SomaCheck to help me prepare a four-question, participant-free test-survey plan without changing QuestionPro. I am the researcher and I am holding the phone. The goal is [GOAL]. Work only from what I provide. If a product or integration owner supplied a preconfigured official QuestionPro partner sandbox, inspect only focused Survey Builder capability names and schemas; call no platform data or action tool. Do not ask me to sign up, upgrade, purchase access, administer access, or populate QuestionPro. Show two questionnaire framings, then offer one short first-person proposition about my own direction and wait for my acceptance before a proactive SomaCheck ask. Give Aligned or Unaligned plus confidence to the agent as context and let it use its judgment. Ask what I choose and return the exact signal-free survey definition. Do not create, edit, send, distribute, publish, recruit, launch, access responses, spend, or write the reading to QuestionPro.",
126
+ successCondition: "The researcher receives at most one optional signal, states a choice, and receives a copy-ready four-question plan; no QuestionPro data or action tool runs, and partner interoperability remains untested without a partner-owned sandbox.",
127
+ },
128
+ {
129
+ id: "spotify-listening-reflection-v1",
130
+ title: "Spotify Studio/Kit + SomaCheck Listening Reflection",
131
+ guidePath: "recipes/spotify-listening-reflection.md",
132
+ purpose: "Use one consented signal while choosing a next song or personal audio direction, while the listener keeps final control of every Spotify action.",
133
+ phoneHolder: "The phone holder is the listener reflecting on their own listening choice; the signal never assesses an artist, creator, or another listener.",
134
+ prerequisites: [
135
+ "SomaCheck is ready on the listener's iPhone and the vibecheck MCP is linked to the companion agent.",
136
+ "For the Studio pilot, the listener has access to Studio by Spotify Labs; direct third-party MCP attachment is not publicly documented, so the current Kit handoff is manual.",
137
+ "For automation outside Studio, use the separately reviewed local Spotify companion with an allowlisted Premium account and active device, or Spotify's official Save to Spotify skill for personal talk audio.",
138
+ ],
139
+ starterPrompt: "Kit, suggest one specific track based on my Spotify taste and what is playing, but do not change Spotify. I will ask my SomaCheck-capable companion to send exactly: ‘I want to hear this song next.’ Treat any result I choose to relay only as context—not emotion, cause, instruction, or authorization—and do not remember it as a stable preference. Then ask me whether to play the exact track and wait for my yes. If Kit cannot call SomaCheck directly, label this a manual bridge; do not claim a native MCP integration.",
140
+ successCondition: "The listener receives one signal about their own proposition, decides whether to share it, and separately confirms the exact Spotify action; both Aligned and Unaligned stop at the same human choice, with no automatic playback or emotional inference.",
141
+ },
142
+ ];
143
+ export function getRecipeExperience(id) {
144
+ return RECIPE_CATALOG.find((recipe) => recipe.id === id) ?? null;
145
+ }
146
+ export function formatRecipeList() {
147
+ const entries = RECIPE_CATALOG.map((recipe) => [
148
+ ` ${recipe.id}`,
149
+ ` ${recipe.title}`,
150
+ ` ${recipe.purpose}`,
151
+ ].join("\n"));
152
+ return [
153
+ "SomaCheck customer-testable recipes",
154
+ "",
155
+ ...entries,
156
+ "",
157
+ "These commands print prompt guides. They do not install, connect, or authorize a partner MCP server, call either MCP, or change partner-platform state.",
158
+ "In every recipe, the phone holder is the person reflecting on their own choice.",
159
+ "",
160
+ "Print one recipe:",
161
+ " npx -y @somacheck/vibecheck recipe <id>",
162
+ ].join("\n");
163
+ }
164
+ export function formatRecipeDetail(recipe) {
165
+ return [
166
+ recipe.title,
167
+ `Recipe ID: ${recipe.id}`,
168
+ `Packaged guide: ${recipe.guidePath}`,
169
+ "",
170
+ "Purpose:",
171
+ recipe.purpose,
172
+ "",
173
+ "Phone holder:",
174
+ recipe.phoneHolder,
175
+ "",
176
+ "Prerequisites:",
177
+ ...recipe.prerequisites.map((prerequisite, index) => `${index + 1}. ${prerequisite}`),
178
+ "",
179
+ "Starter prompt (copy exactly, replacing the bracketed scope):",
180
+ recipe.starterPrompt,
181
+ "",
182
+ "Success condition:",
183
+ recipe.successCondition,
184
+ "",
185
+ "This CLI command only prints this guide. It does not install, connect, or authorize a partner MCP server, call either MCP, or change partner-platform state.",
186
+ ].join("\n");
187
+ }
188
+ export function formatRecipePrompt(recipe) {
189
+ return recipe.starterPrompt;
190
+ }
191
+ //# sourceMappingURL=recipes.js.map