@whisperr/wizard 0.1.8 → 0.1.10

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.
Files changed (2) hide show
  1. package/dist/index.js +69 -13
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -6,7 +6,13 @@ import * as p from "@clack/prompts";
6
6
 
7
7
  // src/core/config.ts
8
8
  var DEFAULT_API_BASE = "https://api.whisperr.net";
9
- var DEFAULT_MODEL = "claude-sonnet-4-6";
9
+ var DEFAULT_MODEL = "claude-opus-4-8";
10
+ var DEFAULT_EFFORT = "low";
11
+ var EFFORT_LEVELS = ["low", "medium", "high", "xhigh", "max"];
12
+ function resolveEffort() {
13
+ const raw = (process.env.WHISPERR_WIZARD_EFFORT ?? "").toLowerCase();
14
+ return EFFORT_LEVELS.includes(raw) ? raw : DEFAULT_EFFORT;
15
+ }
10
16
  function resolveConfig(flags = {}) {
11
17
  const apiBaseUrl = (flags.apiBaseUrl ?? process.env.WHISPERR_WIZARD_API_BASE ?? DEFAULT_API_BASE).replace(/\/+$/, "");
12
18
  const llmBaseUrl = (process.env.WHISPERR_WIZARD_LLM_BASE ?? `${apiBaseUrl}/wizard/llm`).replace(/\/+$/, "");
@@ -18,6 +24,7 @@ function resolveConfig(flags = {}) {
18
24
  apiBaseUrl,
19
25
  llmBaseUrl,
20
26
  model: flags.model ?? process.env.WHISPERR_WIZARD_MODEL ?? DEFAULT_MODEL,
27
+ effort: resolveEffort(),
21
28
  maxTurns: Number(process.env.WHISPERR_WIZARD_MAX_TURNS ?? 55),
22
29
  directAnthropicKey,
23
30
  offline
@@ -988,6 +995,33 @@ in the code. You will NOT find everything \u2014 some events live server-side or
988
995
  aren't in this codebase at all. That is expected and fine. Get what is here, get
989
996
  it right, report the rest. Know exactly what you're doing; never hunt blindly.
990
997
 
998
+ WHO COUNTS AS "THE USER" \u2014 decide this BEFORE you place anything:
999
+ Whisperr models churn for the product's END USERS: the customers/consumers who
1000
+ use the app and could leave. identify() and EVERY event must key to that person.
1001
+ Internal actors are NOT the user and must never be instrumented \u2014 doing so fills
1002
+ the churn model with the wrong people and is a serious miss:
1003
+ admins \xB7 staff \xB7 operators \xB7 support / back-office agents \xB7 superusers \xB7
1004
+ sellers/merchants/partners (unless the product is FOR them) \xB7 CMS / management
1005
+ / admin-panel consoles.
1006
+ Real apps usually have SEVERAL auth/identity paths. Before wiring identify(),
1007
+ enumerate them (grep for login / signup / register / authenticate / session
1008
+ handlers) and pick the END-USER one. Treat any of these in a path, route,
1009
+ namespace, class, guard, model, or table name as a strong "WRONG subject \u2014 skip
1010
+ it" signal:
1011
+ admin \xB7 adminpanel \xB7 backoffice \xB7 internal \xB7 staff \xB7 operator \xB7 seller \xB7
1012
+ merchant \xB7 partner \xB7 cms \xB7 manage/management \xB7 console \xB7 dashboard \xB7 support \xB7
1013
+ superuser \xB7 a dedicated admin guard/middleware (e.g. Laravel \`auth:admin\`) or
1014
+ a separate Admin/Staff user model or table.
1015
+ If the only auth you can see sits on such a path, the real end-user auth is
1016
+ almost certainly elsewhere (a customer-facing API, the mobile backend, an SSO
1017
+ callback) \u2014 keep looking instead of settling for it. Only treat an operator as
1018
+ the user when the product itself is genuinely for operators (an internal tool).
1019
+
1020
+ CONSISTENCY CHECK: identify() and the signup/login events (e.g. account_created)
1021
+ describe the SAME person, so they belong on the SAME surface. If you wired
1022
+ account_created into one controller and are about to put identify() in a
1023
+ different one, stop \u2014 that's the tell you've split the subject. Co-locate them.
1024
+
991
1025
  Every step costs time and the user is watching. Work FAST and DECISIVELY.
992
1026
 
993
1027
  EFFICIENCY \u2014 non-negotiable:
@@ -1003,6 +1037,10 @@ DECISIVENESS:
1003
1037
  - If you can't find a clear place for something within ~2 searches, STOP looking.
1004
1038
  Leave a one-line \`// TODO(whisperr): ...\` only if an obvious spot exists,
1005
1039
  otherwise just note it as a follow-up. Do not keep hunting.
1040
+ - ONE exception: choosing the correct user/subject (see WHO COUNTS AS "THE
1041
+ USER") is worth a few extra searches. Do not grab the first thing named
1042
+ "login" \u2014 confirm it's the end-user path first. Getting the subject wrong is
1043
+ far more costly than a missed event.
1006
1044
 
1007
1045
  PROPERTY CAPTURE (this is the craft):
1008
1046
  - For each event you place, look at what's in scope AT THAT CALL SITE \u2014 function
@@ -1018,6 +1056,9 @@ CORRECTNESS:
1018
1056
  - Match the app's existing conventions (imports, state management, file layout).
1019
1057
  - Use the EXACT snake_case event names given. Never invent or rename events.
1020
1058
  - Only place an event where you're confident the user action truly happens.
1059
+ - Before writing a call, confirm the id in scope is the END-USER's \u2014 not an
1060
+ admin/staff/operator/seller id. An admin acting on a user's behalf is still an
1061
+ admin action; instrument where the end user themselves acts.
1021
1062
 
1022
1063
  FINAL SUMMARY (this is shown verbatim to a non-technical customer in a
1023
1064
  dashboard \u2014 write for a human, not a changelog):
@@ -1115,12 +1156,18 @@ async function runIntegrationAgent(opts) {
1115
1156
  "Do exactly these, then stop:",
1116
1157
  `1. Add the Whisperr SDK dependency and install it (${playbook.packageRef}).`,
1117
1158
  "2. Initialize it once at app startup with the key + base URL below.",
1118
- "3. Wire identify() at the PRIMARY place the user becomes authenticated",
1119
- " (after a successful login) and on session restore at app startup; call",
1120
- " reset() on logout. Do NOT enumerate every auth method \u2014 one primary",
1121
- " login path plus session restore is enough. Keep channels minimal: pass",
1122
- " email if it's readily at hand; phone/push are optional, skip them if not",
1123
- " obvious. Do not go hunting through every auth file.",
1159
+ "3. Wire identify() for the END USER \u2014 the paying customer/consumer, NEVER an",
1160
+ ' admin, staff, operator, seller, or partner (see WHO COUNTS AS "THE USER"',
1161
+ " in your instructions). This app likely has several auth paths: enumerate",
1162
+ " them first (grep login/signup/register/authenticate) and instrument the",
1163
+ ' end-user one \u2014 do NOT just take the first thing named "login". A path',
1164
+ " under admin/backoffice/staff/seller/cms is the wrong subject. Sanity",
1165
+ " check: identify() belongs on the SAME surface as account_created \u2014 if",
1166
+ " they'd land in different controllers, you've picked the wrong login.",
1167
+ " Wire it at the primary end-user login success and on session restore at",
1168
+ " startup; call reset() on logout. One end-user login path plus session",
1169
+ " restore is enough. Keep channels minimal: email if readily at hand;",
1170
+ " phone/push optional.",
1124
1171
  "",
1125
1172
  "This is a real app \u2014 be quick and decisive, aim to finish in ~15 steps.",
1126
1173
  "Do NOT instrument product events yet \u2014 that is a separate step. Do not run",
@@ -1135,6 +1182,7 @@ async function runIntegrationAgent(opts) {
1135
1182
  systemPrompt: systemPrompt9,
1136
1183
  repoPath,
1137
1184
  model: config.model,
1185
+ effort: config.effort,
1138
1186
  maxTurns: 35,
1139
1187
  progress
1140
1188
  });
@@ -1149,10 +1197,12 @@ ${core.summary}`);
1149
1197
  "initialized, and identify() is wired. Now instrument the product events",
1150
1198
  "below with track().",
1151
1199
  "",
1152
- "Work in importance order. Place each event at its real call site and",
1153
- "attach the properties you can source from what's in scope there (see the",
1154
- "property-capture rule in your instructions). Skip fast when an event has",
1155
- "no clear client-side trigger \u2014 spend steps placing events, not exploring.",
1200
+ "Work in importance order. Place each event at the real call site where the",
1201
+ "END USER performs the action (not an admin/staff path \u2014 see WHO COUNTS AS",
1202
+ `"THE USER"), and attach the properties you can source from what's in scope`,
1203
+ "there (see the property-capture rule). These events describe the same",
1204
+ "person identify() did, so they live on the same end-user surface. Skip fast",
1205
+ "when an event has no clear trigger here \u2014 spend steps placing, not exploring.",
1156
1206
  "Stop once the events that clearly exist in this app are wired.",
1157
1207
  "",
1158
1208
  "----- EVENTS -----",
@@ -1164,6 +1214,7 @@ ${core.summary}`);
1164
1214
  systemPrompt: systemPrompt9,
1165
1215
  repoPath,
1166
1216
  model: config.model,
1217
+ effort: config.effort,
1167
1218
  maxTurns: config.maxTurns,
1168
1219
  progress
1169
1220
  });
@@ -1181,7 +1232,7 @@ ${events.summary}`);
1181
1232
  };
1182
1233
  }
1183
1234
  async function runPass(opts) {
1184
- const { prompt, systemPrompt: systemPrompt9, repoPath, model, maxTurns, progress } = opts;
1235
+ const { prompt, systemPrompt: systemPrompt9, repoPath, model, effort, maxTurns, progress } = opts;
1185
1236
  let summary = "";
1186
1237
  let costUsd = 0;
1187
1238
  let ok = false;
@@ -1192,6 +1243,11 @@ async function runPass(opts) {
1192
1243
  model,
1193
1244
  cwd: repoPath,
1194
1245
  systemPrompt: systemPrompt9,
1246
+ // Adaptive thinking (Claude decides depth per step) + an explicit effort
1247
+ // level. Sonnet 4.6 supports both; we set them rather than rely on SDK
1248
+ // defaults so the behavior is pinned regardless of SDK version.
1249
+ thinking: { type: "adaptive" },
1250
+ effort,
1195
1251
  allowedTools: ["Read", "Edit", "Write", "Bash", "Glob", "Grep"],
1196
1252
  permissionMode: "bypassPermissions",
1197
1253
  maxTurns,
@@ -1771,7 +1827,7 @@ async function main() {
1771
1827
  return;
1772
1828
  }
1773
1829
  if ("version" in parsed) {
1774
- console.log("0.1.8");
1830
+ console.log("0.1.10");
1775
1831
  return;
1776
1832
  }
1777
1833
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@whisperr/wizard",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "Whisperr Wizard — one command to integrate the Whisperr SDK into your app. Authenticates with your onboarded account and uses an AI coding agent to wire up identify() and your business events automatically.",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,