Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 62 additions & 7 deletions src/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { confirm, detectPlatforms, allPlatformIds, log, promptLine, warn, type P
import { getVersion } from "./version.js";
import { runUpdate } from "./update.js";
import { renderCliHelpBlock } from "./skillify-spec.js";
import { canOfferInstallScan, runInstallScan, formatScanResult } from "./install-scan.js";

const AUTH_SUBCOMMANDS = new Set([
"whoami",
Expand Down Expand Up @@ -178,14 +179,68 @@ async function runAuthGate(args: string[]): Promise<void> {
return;
}

// Install-time value-show: when the guards pass (claude CLI present,
// prior sessions on disk, no manifest yet, TTY attached), offer to
// scan the user's recent sessions for repeatable mistakes BEFORE
// showing the abstract sign-in pitch. A real insight from their own
// work converts on "keep this skill across machines" better than the
// generic "shared memory" copy.
//
// Every failure path (declined, timed out, no insight emitted)
// returns null and we fall through to the existing unlock copy β€” the
// install never dead-ends on a scan failure.
let foundInsight: { skill_name: string } | null = null;
if (canOfferInstallScan()) {
// Don't claim "Hivemind installed" here β€” runAuthGate runs BEFORE
// the per-platform installers, so the assistant install hasn't
// actually happened yet. Codex PR #198 P3 flagged the earlier
// wording as misleading status output.
log("");
log("🐝 Want me to scan your recent Claude Code sessions for repeatable mistakes?");
log("Takes 2-4 minutes. Scans 10 sessions in parallel using your Claude Code subscription.");
log("");
const scanOk = await confirm("Scan now?", true);
if (scanOk) {
log("");
log("Scanning your 10 most-recent sessions (up to 5 min). Be patient β€” haiku is running in the background.");
const { insight, skillsCount } = await runInstallScan();
log("");
if (insight && insight.insight && insight.insight.trim().length > 0) {
log(formatScanResult(insight));
foundInsight = { skill_name: insight.skill_name };
} else if (skillsCount > 0) {
// Codex PR #198 P3: don't lie about "no patterns found" when
// mine-local actually wrote skills to disk. They just lacked
// a banner-quality one-liner. The skills are real and the
// user benefits from them on next SessionStart even without
// the install-time banner.
log(`Mined ${skillsCount} skill${skillsCount === 1 ? "" : "s"} locally β€” they'll be available in your next claude session.`);
log("(No banner-quality insight to surface here β€” the gate is conservative on what gets the top-line.)");
} else {
log("No repeatable patterns found in this scan. (That's OK β€” the gate is conservative.)");
}
}
}

log("");
log("🐝 One more step to unlock Hivemind");
log("");
log("To enable shared memory and auto-learning across your agents,");
log("we need to sign you in. Your traces will be securely stored in");
log("your private Hivemind, so all your agents can recall them.");
log("");
log("You can later connect your own cloud storage like S3/GCS/Azure Blob.");
if (foundInsight) {
// Insight-aware sign-in pitch: lead with the concrete value the
// user just saw rather than the generic "shared memory" framing.
// Skill name is kebab-case-validated upstream by mine-local's
// assertValidSkillName, so it's safe to interpolate inline.
log("🐝 Sign in to keep this skill across machines and share it with your team.");
log("");
log(`Without sign-in, \`${foundInsight.skill_name}\` lives only on this machine and`);
log("won't follow you to a new laptop or be shared with teammates who'd benefit.");
} else {
log("🐝 One more step to unlock Hivemind");
log("");
log("To enable shared memory and auto-learning across your agents,");
log("we need to sign you in. Your traces will be securely stored in");
log("your private Hivemind, so all your agents can recall them.");
log("");
log("You can later connect your own cloud storage like S3/GCS/Azure Blob.");
}
log("");
const yes = await confirm("Sign in now?", true);

Expand Down
Loading