@piut/cli 3.0.0 → 3.1.0

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/cli.js +126 -12
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -332,9 +332,21 @@ async function setupCommand(options) {
332
332
  console.log(dim(" Get a key at https://piut.com/dashboard/keys"));
333
333
  process.exit(1);
334
334
  }
335
- const { slug, displayName } = validationResult;
336
- console.log(success(` \u2714 Authenticated as ${displayName} (${slug})`));
335
+ const { slug, displayName, status } = validationResult;
336
+ console.log(success(` \u2714 Authenticated as ${displayName}${slug ? ` (${slug})` : ""}`));
337
337
  console.log();
338
+ if (status === "no_brain") {
339
+ console.log(warning(" You haven\u2019t built a brain yet."));
340
+ console.log(dim(" Run ") + brand("piut build") + dim(" first, then ") + brand("piut deploy") + dim(" to publish it."));
341
+ console.log();
342
+ return;
343
+ }
344
+ if (status === "unpublished") {
345
+ console.log(warning(" Your brain is built but not deployed yet."));
346
+ console.log(dim(" Run ") + brand("piut deploy") + dim(" to publish your MCP server, then re-run setup."));
347
+ console.log();
348
+ return;
349
+ }
338
350
  const detected = [];
339
351
  const toolFilter = options.tool;
340
352
  for (const tool of TOOLS) {
@@ -882,7 +894,8 @@ async function resolveApiKey(keyOption) {
882
894
  console.log(dim(" Get a key at https://piut.com/dashboard/keys"));
883
895
  process.exit(1);
884
896
  }
885
- console.log(success(` \u2713 Connected as ${result.displayName} (${result.slug})`));
897
+ const label = result.slug ? `${result.displayName} (${result.slug})` : result.displayName;
898
+ console.log(success(` \u2713 Connected as ${label}`));
886
899
  updateStore({ apiKey });
887
900
  return apiKey;
888
901
  }
@@ -905,7 +918,8 @@ async function resolveApiKeyWithResult(keyOption) {
905
918
  console.log(dim(" Get a key at https://piut.com/dashboard/keys"));
906
919
  process.exit(1);
907
920
  }
908
- console.log(success(` \u2713 Connected as ${result.displayName} (${result.slug})`));
921
+ const label = result.slug ? `${result.displayName} (${result.slug})` : result.displayName;
922
+ console.log(success(` \u2713 Connected as ${label}`));
909
923
  updateStore({ apiKey });
910
924
  return { apiKey, ...result };
911
925
  }
@@ -983,7 +997,14 @@ import { confirm as confirm3 } from "@inquirer/prompts";
983
997
  import chalk5 from "chalk";
984
998
  async function deployCommand(options) {
985
999
  banner();
986
- const { apiKey, slug, serverUrl } = await resolveApiKeyWithResult(options.key);
1000
+ const { apiKey, slug, serverUrl, status } = await resolveApiKeyWithResult(options.key);
1001
+ if (status === "no_brain") {
1002
+ console.log();
1003
+ console.log(warning(" You haven\u2019t built a brain yet."));
1004
+ console.log(dim(" Run ") + brand("piut build") + dim(" first to create your brain, then deploy."));
1005
+ console.log();
1006
+ return;
1007
+ }
987
1008
  console.log();
988
1009
  console.log(dim(" Your brain will be published as an MCP server at:"));
989
1010
  console.log(` ${brand(serverUrl)}`);
@@ -1354,7 +1375,7 @@ async function disconnectCommand(options) {
1354
1375
  }
1355
1376
 
1356
1377
  // src/commands/interactive.ts
1357
- import { select as select2 } from "@inquirer/prompts";
1378
+ import { select as select2, confirm as confirm6 } from "@inquirer/prompts";
1358
1379
  import chalk6 from "chalk";
1359
1380
  import { password as password3 } from "@inquirer/prompts";
1360
1381
  async function authenticate() {
@@ -1363,8 +1384,8 @@ async function authenticate() {
1363
1384
  if (apiKey) {
1364
1385
  try {
1365
1386
  const result2 = await validateKey(apiKey);
1366
- console.log(success(` Connected as ${result2.displayName} (${result2.slug})`));
1367
- return apiKey;
1387
+ console.log(success(` Connected as ${result2.displayName}`));
1388
+ return { apiKey, validation: result2 };
1368
1389
  } catch {
1369
1390
  console.log(dim(" Saved key expired. Please re-authenticate."));
1370
1391
  apiKey = void 0;
@@ -1388,14 +1409,48 @@ async function authenticate() {
1388
1409
  console.log(dim(" Get a key at https://piut.com/dashboard/keys"));
1389
1410
  process.exit(1);
1390
1411
  }
1391
- console.log(success(` \u2713 Connected as ${result.displayName} (${result.slug})`));
1412
+ console.log(success(` \u2713 Connected as ${result.displayName}`));
1392
1413
  updateStore({ apiKey });
1393
- return apiKey;
1414
+ return { apiKey, validation: result };
1394
1415
  }
1395
1416
  async function interactiveMenu() {
1396
1417
  banner();
1397
- const apiKey = await authenticate();
1418
+ const { apiKey, validation } = await authenticate();
1398
1419
  console.log();
1420
+ if (validation.status === "no_brain") {
1421
+ console.log(warning(" You haven\u2019t built a brain yet."));
1422
+ console.log(dim(" Your brain is how AI tools learn about you \u2014 your projects, preferences, and context."));
1423
+ console.log();
1424
+ const wantBuild = await confirm6({
1425
+ message: "Build your brain now?",
1426
+ default: true
1427
+ });
1428
+ if (wantBuild) {
1429
+ await buildCommand({ key: apiKey });
1430
+ } else {
1431
+ console.log();
1432
+ console.log(dim(" You can build your brain anytime with: ") + brand("piut build"));
1433
+ console.log();
1434
+ }
1435
+ return;
1436
+ }
1437
+ if (validation.status === "unpublished") {
1438
+ console.log(warning(" Your brain is built but not deployed yet."));
1439
+ console.log(dim(" Deploy it to make your MCP server live so AI tools can read your brain."));
1440
+ console.log();
1441
+ const wantDeploy = await confirm6({
1442
+ message: "Deploy your brain now?",
1443
+ default: true
1444
+ });
1445
+ if (wantDeploy) {
1446
+ await deployCommand({ key: apiKey });
1447
+ } else {
1448
+ console.log();
1449
+ console.log(dim(" You can deploy anytime with: ") + brand("piut deploy"));
1450
+ console.log();
1451
+ }
1452
+ return;
1453
+ }
1399
1454
  const action = await select2({
1400
1455
  message: "What would you like to do?",
1401
1456
  choices: [
@@ -1425,9 +1480,68 @@ async function interactiveMenu() {
1425
1480
  }
1426
1481
  }
1427
1482
 
1483
+ // src/lib/update-check.ts
1484
+ import { execFile } from "child_process";
1485
+ import chalk7 from "chalk";
1486
+ import { confirm as confirm7 } from "@inquirer/prompts";
1487
+ var PACKAGE_NAME = "@piut/cli";
1488
+ async function getLatestVersion() {
1489
+ try {
1490
+ const res = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}/latest`);
1491
+ if (!res.ok) return null;
1492
+ const data = await res.json();
1493
+ return data.version ?? null;
1494
+ } catch {
1495
+ return null;
1496
+ }
1497
+ }
1498
+ function isNewer(current, latest) {
1499
+ const [cMaj, cMin, cPat] = current.split(".").map(Number);
1500
+ const [lMaj, lMin, lPat] = latest.split(".").map(Number);
1501
+ if (lMaj !== cMaj) return lMaj > cMaj;
1502
+ if (lMin !== cMin) return lMin > cMin;
1503
+ return lPat > cPat;
1504
+ }
1505
+ function runUpdate() {
1506
+ return new Promise((resolve) => {
1507
+ execFile("npm", ["install", "-g", `${PACKAGE_NAME}@latest`], { timeout: 6e4 }, (err) => {
1508
+ resolve(!err);
1509
+ });
1510
+ });
1511
+ }
1512
+ async function checkForUpdate(currentVersion) {
1513
+ const latest = await getLatestVersion();
1514
+ if (!latest || !isNewer(currentVersion, latest)) return;
1515
+ console.log();
1516
+ console.log(brand(" Update available!") + dim(` ${currentVersion} \u2192 ${latest}`));
1517
+ console.log(dim(` Run ${chalk7.bold(`npm install -g ${PACKAGE_NAME}@latest`)} to update`));
1518
+ console.log();
1519
+ try {
1520
+ const shouldUpdate = await confirm7({
1521
+ message: `Update to v${latest} now?`,
1522
+ default: true
1523
+ });
1524
+ if (shouldUpdate) {
1525
+ console.log(dim(" Updating..."));
1526
+ const ok = await runUpdate();
1527
+ if (ok) {
1528
+ console.log(chalk7.green(` \u2713 Updated to v${latest}`));
1529
+ console.log(dim(" Restart the CLI to use the new version."));
1530
+ process.exit(0);
1531
+ } else {
1532
+ console.log(chalk7.yellow(` Could not auto-update. Run manually:`));
1533
+ console.log(chalk7.bold(` npm install -g ${PACKAGE_NAME}@latest`));
1534
+ console.log();
1535
+ }
1536
+ }
1537
+ } catch {
1538
+ }
1539
+ }
1540
+
1428
1541
  // src/cli.ts
1542
+ var VERSION = "3.1.0";
1429
1543
  var program = new Command();
1430
- program.name("piut").description("Build your AI brain instantly. Deploy it as an MCP server. Connect it to every project.").version("3.0.0").action(interactiveMenu);
1544
+ program.name("piut").description("Build your AI brain instantly. Deploy it as an MCP server. Connect it to every project.").version(VERSION).hook("preAction", () => checkForUpdate(VERSION)).action(interactiveMenu);
1431
1545
  program.command("build").description("Build or rebuild your brain from your files").option("-k, --key <key>", "API key").option("--folders <paths>", "Comma-separated folder paths to scan").action(buildCommand);
1432
1546
  program.command("deploy").description("Publish your MCP server (requires paid account)").option("-k, --key <key>", "API key").option("-y, --yes", "Skip confirmation prompts").action(deployCommand);
1433
1547
  program.command("connect").description("Add brain references to project config files").option("-k, --key <key>", "API key").option("-y, --yes", "Skip interactive prompts").option("--folders <paths>", "Comma-separated folder paths to scan").action(connectCommand);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@piut/cli",
3
- "version": "3.0.0",
3
+ "version": "3.1.0",
4
4
  "description": "Build your AI brain instantly. Deploy it as an MCP server. Connect it to every project.",
5
5
  "type": "module",
6
6
  "bin": {