behavior-wrapped 0.2.18 → 0.2.20

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.
@@ -6,14 +6,22 @@ const purple = "\x1b[38;2;141;92;255m";
6
6
  const reset = "\x1b[0m";
7
7
 
8
8
  export const remoteAnalysisConsentText = "Behavior Wrapped will send redacted excerpts from your session history to GPT-5.6 Luna via OpenRouter using zero-data-retention providers for analysis. OK to proceed?";
9
+ export const localOnlyAnalysisText = "Local-only analysis keeps all session data on this Mac. It uses deterministic statistics and a locally counted favorite phrase, but omits AI-judged interaction tone, usage topics, and instrumental workarounds. Those omissions leave leaderboard plots 2 and 3 incomplete, so the report will not be published or included in the leaderboard.";
9
10
 
10
- export async function requestRemoteAnalysisConsent({ input = process.stdin, output = process.stdout } = {}) {
11
+ export async function requestAnalysisMode({ input = process.stdin, output = process.stdout } = {}) {
11
12
  const prompt = createInterface({ input, output });
12
13
  try {
13
14
  const question = `${lime}◇${reset} Behavior Wrapped will send redacted excerpts from your session history to ${purple}${bright}GPT-5.6 Luna${reset} via OpenRouter using zero-data-retention providers for analysis. OK to proceed? ${bright}(Y/n)${reset} `;
14
15
  const answer = await prompt.question(question);
15
- return /^(?:|y|yes)$/i.test(answer.trim());
16
+ if (/^(?:|y|yes)$/i.test(answer.trim())) return "remote";
17
+ output.write(`\n${localOnlyAnalysisText}\n\n`);
18
+ const localAnswer = await prompt.question(`${lime}◇${reset} Proceed with local-only analysis? ${bright}(Y/n)${reset} `);
19
+ return /^(?:|y|yes)$/i.test(localAnswer.trim()) ? "local-only" : "cancel";
16
20
  } finally {
17
21
  prompt.close();
18
22
  }
19
23
  }
24
+
25
+ export async function requestRemoteAnalysisConsent(options) {
26
+ return await requestAnalysisMode(options) === "remote";
27
+ }
@@ -202,9 +202,9 @@ export function buildLocalPhraseCard(candidates) {
202
202
  if (!candidates.length) return null;
203
203
  return phraseCardFromSelection(candidates, candidates[0].candidate_id, {
204
204
  model: "Local deterministic selection",
205
- provider: "Local test mode",
205
+ provider: "Local deterministic analysis",
206
206
  latencyMs: 0,
207
- method: "Test mode selected the highest-ranked locally counted phrase without an LLM call.",
207
+ method: "Selected the highest-ranked locally counted phrase without an LLM call.",
208
208
  });
209
209
  }
210
210
 
@@ -25,7 +25,7 @@ function safeTurnCounts(value) {
25
25
  if (!Array.isArray(value)) return [];
26
26
  return value.slice(0, 10_000).flatMap((item) => {
27
27
  const turns = Number(item);
28
- return Number.isFinite(turns) && turns >= 0 && turns <= 1_000_000 ? [Math.round(turns)] : [];
28
+ return Number.isFinite(turns) && turns >= 1 && turns <= 1_000_000 ? [Math.round(turns)] : [];
29
29
  }).sort((left, right) => left - right);
30
30
  }
31
31