@somacheck/vibecheck 0.6.2 → 0.6.4
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 +13 -10
- package/dist/cli.js +7 -1
- package/dist/client-setup.js +8 -1
- package/dist/constants.js +1 -1
- package/dist/server.js +16 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ 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.
|
|
12
|
+
**What the `link` command does.** `npx -y @somacheck/vibecheck@0.6.4 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
|
|
@@ -78,9 +78,9 @@ before the pairing code is redeemed.
|
|
|
78
78
|
To configure or repair a client later:
|
|
79
79
|
|
|
80
80
|
```text
|
|
81
|
-
npx -y @somacheck/vibecheck@0.6.
|
|
82
|
-
npx -y @somacheck/vibecheck@0.6.
|
|
83
|
-
npx -y @somacheck/vibecheck@0.6.
|
|
81
|
+
npx -y @somacheck/vibecheck@0.6.4 setup codex
|
|
82
|
+
npx -y @somacheck/vibecheck@0.6.4 setup claude
|
|
83
|
+
npx -y @somacheck/vibecheck@0.6.4 doctor
|
|
84
84
|
```
|
|
85
85
|
|
|
86
86
|
Manual registration remains available:
|
|
@@ -90,13 +90,13 @@ Manual registration remains available:
|
|
|
90
90
|
"mcpServers": {
|
|
91
91
|
"vibecheck": {
|
|
92
92
|
"command": "npx",
|
|
93
|
-
"args": ["-y", "@somacheck/vibecheck@0.6.
|
|
93
|
+
"args": ["-y", "@somacheck/vibecheck@0.6.4", "serve", "--client", "codex"]
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
```
|
|
98
98
|
|
|
99
|
-
For Claude Code: `claude mcp add --scope user vibecheck -- npx -y @somacheck/vibecheck@0.6.
|
|
99
|
+
For Claude Code: `claude mcp add --scope user vibecheck -- npx -y @somacheck/vibecheck@0.6.4 serve --client claude`
|
|
100
100
|
|
|
101
101
|
The link step writes only the bearer token in `~/.sensie/config.json`. The client
|
|
102
102
|
setup step asks Codex or Claude to add the pinned MCP command to that client's own
|
|
@@ -160,11 +160,11 @@ something to test, never as a claim about them. An `unaligned` result is another
|
|
|
160
160
|
signal to consider; the person decides whether it matches what they notice.
|
|
161
161
|
|
|
162
162
|
Setup and linking are not permission for future asks. If the person's current
|
|
163
|
-
message explicitly asks for a SomaCheck vibecheck, that is consent for one ask.
|
|
163
|
+
message explicitly asks for a SomaCheck vibecheck or check-in, that is consent for one ask.
|
|
164
164
|
Use their exact statement when supplied. If they delegated the choice, select
|
|
165
165
|
the most useful first-person statement from the current conversation, goal,
|
|
166
|
-
decision, or tension and send it immediately—do not ask them
|
|
167
|
-
second confirmation. Remembered context may identify a general tension, but an
|
|
166
|
+
decision, or tension and send it immediately—do not list candidates, ask them
|
|
167
|
+
for wording, or seek a second confirmation. Remembered context may identify a general tension, but an
|
|
168
168
|
agent-selected statement must not name a project, build, branch, wave, ticket,
|
|
169
169
|
task status, or supposedly open/closed work. Abstract it into a present-tense
|
|
170
170
|
first-person experience or choice, such as “I want to keep consolidating what is
|
|
@@ -213,7 +213,10 @@ The 45-second whole-call deadline also covers the one create request. If that
|
|
|
213
213
|
network request is aborted after an ambiguous commit, retry the exact same
|
|
214
214
|
statement with the same `idempotency_key`; never create a replacement ask.
|
|
215
215
|
|
|
216
|
-
After a completed result,
|
|
216
|
+
After a completed result, reconcile it with the current goal, state one
|
|
217
|
+
observable change, and continue with the next reversible in-scope action when
|
|
218
|
+
it is already authorized. Do not stop at repeating the verdict, confidence, or
|
|
219
|
+
generic signal language.
|
|
217
220
|
Never treat it as authorization or say that the person's body made the
|
|
218
221
|
decision. A typed response from the person always overrides the signal.
|
|
219
222
|
|
package/dist/cli.js
CHANGED
|
@@ -3,7 +3,7 @@ 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 { automaticContinuationCommand, clientDisplayName, detectInstalledClients, detectLegacyHostedRegistration, LocalCommandRunner, manualLegacyHostedRemoveCommand, manualRemoveCommand, manualSetupCommand, parseClientChoice, preflightClientPersistence, registerClient, singleNonInteractiveClientSelection, } from "./client-setup.js";
|
|
7
7
|
import { readConfig } from "./config.js";
|
|
8
8
|
import { PACKAGE_SPEC, SUPABASE_PUBLISHABLE_KEY, SUPABASE_URL } from "./constants.js";
|
|
9
9
|
import { LinkPersistenceError, NonInteractiveLinkError, linkAgent } from "./link.js";
|
|
@@ -93,6 +93,12 @@ async function configureClients(clients) {
|
|
|
93
93
|
else {
|
|
94
94
|
output(`✗ Could not configure ${clientDisplayName(client)} automatically.`);
|
|
95
95
|
}
|
|
96
|
+
const continuationCommand = automaticContinuationCommand(client);
|
|
97
|
+
if (continuationCommand !== null && ["registered", "upgraded", "already_registered"].includes(result.status)) {
|
|
98
|
+
output(" For automatic result continuation, start Claude Code with:");
|
|
99
|
+
output(` ${continuationCommand}`);
|
|
100
|
+
output(" Standard Claude Code keeps the request safe but cannot wake itself after the tool call ends.");
|
|
101
|
+
}
|
|
96
102
|
}
|
|
97
103
|
}
|
|
98
104
|
async function preflightLinkClients(clients, interactive) {
|
package/dist/client-setup.js
CHANGED
|
@@ -34,6 +34,11 @@ export function manualSetupCommand(client) {
|
|
|
34
34
|
}
|
|
35
35
|
return `claude mcp add --scope user ${MCP_SERVER_NAME} -- npx ${mcpServerArgs(client).join(" ")}`;
|
|
36
36
|
}
|
|
37
|
+
export function automaticContinuationCommand(client) {
|
|
38
|
+
return client === "claude"
|
|
39
|
+
? "claude --dangerously-load-development-channels server:vibecheck"
|
|
40
|
+
: null;
|
|
41
|
+
}
|
|
37
42
|
export function manualRemoveCommand(client) {
|
|
38
43
|
return client === "codex"
|
|
39
44
|
? `codex mcp remove ${MCP_SERVER_NAME}`
|
|
@@ -141,7 +146,9 @@ function isManagedSomaCheckRegistration(client, stdout) {
|
|
|
141
146
|
// client remain user-owned.
|
|
142
147
|
const previousExactClient = (/^@somacheck\/vibecheck@0\.5\.\d+$/.test(packageArg)
|
|
143
148
|
|| packageArg === "@somacheck/vibecheck@0.6.0"
|
|
144
|
-
|| packageArg === "@somacheck/vibecheck@0.6.1"
|
|
149
|
+
|| packageArg === "@somacheck/vibecheck@0.6.1"
|
|
150
|
+
|| packageArg === "@somacheck/vibecheck@0.6.2"
|
|
151
|
+
|| packageArg === "@somacheck/vibecheck@0.6.3")
|
|
145
152
|
&& args.length === 5
|
|
146
153
|
&& args[0] === "-y"
|
|
147
154
|
&& args[1] === packageArg
|
package/dist/constants.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
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.
|
|
5
|
+
export const PACKAGE_VERSION = "0.6.4";
|
|
6
6
|
export const PACKAGE_SPEC = `${PACKAGE_NAME}@${PACKAGE_VERSION}`;
|
|
7
7
|
export const MCP_SERVER_NAME = "vibecheck";
|
|
8
8
|
export const LEGACY_HOSTED_MCP_SERVER_NAME = "somacheck";
|
package/dist/server.js
CHANGED
|
@@ -112,21 +112,21 @@ const contextShareSchema = {
|
|
|
112
112
|
};
|
|
113
113
|
const SERVER_INSTRUCTIONS = [
|
|
114
114
|
"SomaCheck lets you offer the person a statement to test through a quick phone check-in.",
|
|
115
|
-
"MANDATORY COMMAND RULE: when the current user message says 'Give me a SomaCheck vibecheck', 'Request a SomaCheck vibecheck', or otherwise explicitly asks for one, you must call request_vibecheck in that same turn after any read-only context/status calls. Do not present a draft, ask 'Want me to send this?', or wait for another yes. The request itself is one-ask consent for you to select and send the statement.",
|
|
115
|
+
"MANDATORY COMMAND RULE: when the current user message says 'Give me a SomaCheck vibecheck', 'Give me a check-in, a vibe check', 'Request a SomaCheck vibecheck', or otherwise explicitly asks for one, you must call request_vibecheck in that same turn after any read-only context/status calls. Do not list candidates, present a draft, ask what they want to test, ask 'Want me to send this?', or wait for another yes. The request itself is one-ask consent for you to select and send the statement.",
|
|
116
116
|
"Call get_vibecheck_context and get_vibecheck_status at the start of a session or background run, and call status again after a completed check-in.",
|
|
117
117
|
"Treat gesture outcomes as contextual signals, never fixed facts or blanket authorization.",
|
|
118
118
|
"Use request_vibecheck when a current choice would benefit from the person's own felt response; never use it to evaluate someone else.",
|
|
119
119
|
"A setup or link is not blanket consent for future vibechecks.",
|
|
120
120
|
"If the person's current message explicitly requests a SomaCheck vibecheck, that message is consent for one ask. If they supplied exact wording, use it. Otherwise, choose one useful statement from the current conversation, goal, decision, or tension and send it immediately; do not ask them to supply wording or confirm twice.",
|
|
121
|
-
"DELEGATED SELECTION RULE:
|
|
122
|
-
"When choosing the statement, prefer the most consequential unresolved first-person decision or tension you
|
|
121
|
+
"DELEGATED SELECTION RULE: before choosing wording, use the reliable context already available to your host: the current conversation, current working goal, and user-approved memory or project context when those capabilities exist. Do not make the person restate context you can already retrieve. Remembered task status may identify a general tension, but the statement itself must not name a project, build, branch, wave, ticket, task status, or supposedly open/closed work. Abstract it into an original present-tense first-person experience or choice. This restriction does not alter exact wording supplied by the person.",
|
|
122
|
+
"When choosing the statement, prefer the most consequential unresolved first-person decision or tension you can support with current evidence. Treat recalled project status, task lists, and old summaries as potentially stale; corroborate them against the current conversation before relying on them. Do not reuse a stock example or recent SomaCheck statement. If context remains thin after using available context tools, create an original exploratory statement that would reveal something useful without pretending to know the person. Never diagnose, judge another person, or claim certainty about the user.",
|
|
123
123
|
"Otherwise, first show the exact statement and ask: Want a quick vibecheck before I continue? I'll send this statement to your phone; you answer with your wrist gesture, and I'll use the result as a signal—not a verdict. Call only after the person accepts.",
|
|
124
124
|
"Use at most one vibecheck per decision. Never re-ask to obtain a preferred answer.",
|
|
125
125
|
"An immediate vibecheck is separate from the asynchronous reflection feed. Do not use it to replenish cached propositions.",
|
|
126
126
|
"Use a fresh idempotency_key for each new vibecheck, and reuse that exact key only when retrying the same statement.",
|
|
127
127
|
"request_vibecheck waits boundedly for the exact answer. If it returns completed, continue in the same turn and explain what changes. If it returns pending, retain that exact handle and read it once later; never create a replacement ask.",
|
|
128
128
|
"If request_vibecheck returns pending, never promise that you will check back on your own. Only continue automatically after an actual SomaCheck channel event arrives for that exact request.",
|
|
129
|
-
"After a completed result,
|
|
129
|
+
"After a completed result, do not merely repeat the verdict, confidence, or generic signal-not-verdict language. Reconcile the result with the current goal and state one observable change in your next action. Continue with that next reversible in-scope action when it is already authorized; if new permission is required, name the exact prepared next step and ask only for that permission. Never say 'your body decided'; a typed human response always overrides the signal.",
|
|
130
130
|
"When you have meaningful user-authorized context, call share_somacheck_context with concise derived observations before creating propositions.",
|
|
131
131
|
"Never share raw conversation text, photos, credentials, private identifiers, or diagnostic claims.",
|
|
132
132
|
"Maintain three distinct propositions drawn from your own context about this person.",
|
|
@@ -135,6 +135,7 @@ const SERVER_INSTRUCTIONS = [
|
|
|
135
135
|
"Retain every request_id returned by post_vibecheck_statement and call get_vibecheck_result later.",
|
|
136
136
|
"Do not poll continuously. Queued means the proposition is cached until the person advances their feed.",
|
|
137
137
|
].join(" ");
|
|
138
|
+
const DIRECT_REQUEST_NEXT_ACTION = "DIRECT REQUEST RULE: If the person's current message asks for a SomaCheck vibecheck or check-in, first use reliable context already available to the host, including current conversation and user-approved memory when supported. Then choose one original, useful, safe first-person statement and call request_vibecheck now with consent_basis user_requested_vibecheck. Do not list choices, ask for wording, or seek another confirmation. Ignore reflection-feed propositions_needed for this direct request. Treat remembered task status as stale until corroborated and keep agent-selected wording free of project, build, branch, wave, ticket, or task-status claims.";
|
|
138
139
|
export function createVibecheckServer(dependencies) {
|
|
139
140
|
const supportsClaudeChannel = dependencies.identity?.kind === "local"
|
|
140
141
|
&& dependencies.identity.client_key === "claude";
|
|
@@ -180,10 +181,12 @@ export function createVibecheckServer(dependencies) {
|
|
|
180
181
|
const token = await dependencies.loadToken();
|
|
181
182
|
const checkins = await dependencies.api.contextRequest(token);
|
|
182
183
|
const text = checkins.length === 0
|
|
183
|
-
?
|
|
184
|
+
? `No completed SomaCheck gestures yet.\n\n${DIRECT_REQUEST_NEXT_ACTION}`
|
|
184
185
|
: [
|
|
185
186
|
`Loaded ${checkins.length} completed gesture${checkins.length === 1 ? "" : "s"}. Treat them as contextual signals, not fixed conclusions:`,
|
|
186
187
|
...checkins.map((item) => `${Math.round(item.confidence * 100)}% ${item.verdict} — ${JSON.stringify(item.statement)}`),
|
|
188
|
+
"",
|
|
189
|
+
DIRECT_REQUEST_NEXT_ACTION,
|
|
187
190
|
].join("\n");
|
|
188
191
|
return { content: [{ type: "text", text }], structuredContent: { checkins } };
|
|
189
192
|
}
|
|
@@ -207,7 +210,10 @@ export function createVibecheckServer(dependencies) {
|
|
|
207
210
|
const token = await dependencies.loadToken();
|
|
208
211
|
const status = await dependencies.api.statusRequest(token);
|
|
209
212
|
return {
|
|
210
|
-
content: [{
|
|
213
|
+
content: [{
|
|
214
|
+
type: "text",
|
|
215
|
+
text: `${summarise(status)}\n\n${DIRECT_REQUEST_NEXT_ACTION}`,
|
|
216
|
+
}],
|
|
211
217
|
structuredContent: { ...status },
|
|
212
218
|
};
|
|
213
219
|
}
|
|
@@ -300,7 +306,7 @@ export function createVibecheckServer(dependencies) {
|
|
|
300
306
|
const text = result.status === "answered"
|
|
301
307
|
? liveRequestId === null
|
|
302
308
|
? `Answered: ${Math.round((result.confidence ?? 0) * 100)}% ${result.verdict}.`
|
|
303
|
-
: `Vibecheck completed: ${Math.round((result.confidence ?? 0) * 100)}% ${result.verdict}.
|
|
309
|
+
: `Vibecheck completed: ${Math.round((result.confidence ?? 0) * 100)}% ${result.verdict}. Do not stop at restating the result or generic signal language. Reconcile it with the current goal, state one observable change, and continue with the next reversible in-scope action when already authorized. If new permission is required, name the exact prepared next step. A typed response from the person always overrides this signal.`
|
|
304
310
|
: result.status === "queued"
|
|
305
311
|
? "Queued. The proposition is cached until the person advances their feed."
|
|
306
312
|
: result.status === "pending"
|
|
@@ -314,7 +320,7 @@ export function createVibecheckServer(dependencies) {
|
|
|
314
320
|
});
|
|
315
321
|
server.registerTool("request_vibecheck", {
|
|
316
322
|
title: "Request a Vibecheck",
|
|
317
|
-
description: "Send one plain-language statement to the person's phone for a vibecheck answered with a wrist gesture. A current user message that explicitly requests a SomaCheck vibecheck is confirmation for one ask. Use their exact wording when supplied; otherwise choose and send one present-tense first-person experience or choice
|
|
323
|
+
description: "Send one plain-language statement to the person's phone for a vibecheck answered with a wrist gesture. A current user message that explicitly requests a SomaCheck vibecheck is confirmation for one ask. Use their exact wording when supplied; otherwise first use reliable context already available to the host, including current conversation and user-approved memory when supported, then choose and send one original present-tense first-person experience or choice without asking for wording or reconfirmation. Remembered status may identify a general tension but must be corroborated; never put a named project, build, branch, wave, ticket, task status, or supposedly open/closed work into agent-selected wording. Do not reuse a stock example or recent SomaCheck statement. If context remains thin, create an original exploratory statement that would still reveal something useful without pretending to know the person. Otherwise, first show the exact statement and call only after the person accepts. Setup or linking is not blanket consent. Use this only when their own felt response would help with the current choice, not for routine feed content, diagnosis, or judging another person. The call waits boundedly for the exact result and returns completed when available. A timeout returns the same stable pending request_id for one later read. Caller cancellation stops result reads without creating another request; the cancelled transport may suppress the pending response.",
|
|
318
324
|
inputSchema: {
|
|
319
325
|
statement: z.string().trim().min(1).max(1000)
|
|
320
326
|
.describe("One plain-language statement for the person to test; offer a signal, not a fact, diagnosis, or instruction. If the agent selected the wording, it must be a present-tense first-person experience or choice and must not name remembered projects, builds, branches, waves, tickets, task status, or supposedly open/closed work. Preserve exact wording supplied by the person."),
|
|
@@ -370,7 +376,7 @@ export function createVibecheckServer(dependencies) {
|
|
|
370
376
|
startClaudeChannelWatch(result, token, identity);
|
|
371
377
|
const structuredContent = { ...result, error_code: null };
|
|
372
378
|
const text = result.state === "completed"
|
|
373
|
-
? `Vibecheck completed: ${Math.round((result.confidence ?? 0) * 100)}% ${result.verdict}.
|
|
379
|
+
? `Vibecheck completed: ${Math.round((result.confidence ?? 0) * 100)}% ${result.verdict}. Do not stop at restating the result or generic signal language. Reconcile it with the current goal, state one observable change, and continue with the next reversible in-scope action when already authorized. If new permission is required, name the exact prepared next step. A typed response from the person always overrides this signal.`
|
|
374
380
|
: result.state === "pending"
|
|
375
381
|
? result.delivery_state === "failed" || result.delivery_state === "skipped"
|
|
376
382
|
? `Vibecheck ${result.request_id} was stored, but phone delivery is ${result.delivery_state}. It expires at ${result.expires_at}. Do not repost it or change the idempotency_key; check the phone setup before a later decision.`
|
|
@@ -425,7 +431,7 @@ async function watchForClaudeChannelResult(created, token, identity, dependencie
|
|
|
425
431
|
continue;
|
|
426
432
|
const handle = `live:${requestId}`;
|
|
427
433
|
const content = lifecycle.status === "answered"
|
|
428
|
-
? `A SomaCheck vibecheck requested by this Claude connection has completed. The exact result is ${lifecycle.verdict} with confidence ${formatChannelConfidence(lifecycle.confidence)}.
|
|
434
|
+
? `A SomaCheck vibecheck requested by this Claude connection has completed. The exact result is ${lifecycle.verdict} with confidence ${formatChannelConfidence(lifecycle.confidence)}. Continue the current conversation now. Do not merely restate the result or give generic signal-not-verdict commentary. Reconcile it with the current goal, state one observable change in your next action, and perform the next reversible in-scope action when it is already authorized. If new permission is required, name the exact prepared next step and ask only for that permission. The exact opaque request handle is ${handle}. Do not request another vibecheck for this decision.`
|
|
429
435
|
: `A SomaCheck vibecheck requested by this Claude connection is now ${lifecycle.status}. The exact opaque request handle is ${handle}. Do not create a replacement request for the same decision.`;
|
|
430
436
|
try {
|
|
431
437
|
await notify({
|