@picahq/cli 0.3.0 → 1.4.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/index.js +107 -12
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/index.ts
4
+ import { createRequire } from "module";
4
5
  import { Command } from "commander";
5
6
 
6
7
  // src/commands/init.ts
@@ -371,6 +372,9 @@ async function openApiKeyPage() {
371
372
  await open(getApiKeyUrl());
372
373
  }
373
374
 
375
+ // src/commands/init.ts
376
+ import open2 from "open";
377
+
374
378
  // src/lib/table.ts
375
379
  import pc from "picocolors";
376
380
  function printTable(columns, rows) {
@@ -409,12 +413,13 @@ function stripAnsi(str) {
409
413
 
410
414
  // src/commands/init.ts
411
415
  async function initCommand(options) {
412
- p.intro(pc2.bgCyan(pc2.black(" Pica ")));
413
416
  const existingConfig = readConfig();
414
417
  if (existingConfig) {
418
+ p.intro(pc2.bgCyan(pc2.black(" Pica ")));
415
419
  await handleExistingConfig(existingConfig.apiKey, options);
416
420
  return;
417
421
  }
422
+ printBanner();
418
423
  await freshSetup(options);
419
424
  }
420
425
  async function handleExistingConfig(apiKey, options) {
@@ -772,11 +777,10 @@ ${globalPaths}
772
777
 
773
778
  `;
774
779
  }
775
- summary += pc2.yellow("Note: Project config files can be committed to share with your team.\n") + pc2.yellow("Team members will need their own API key.\n\n") + `Next steps:
776
- ${pc2.cyan("pica add gmail")} - Connect Gmail
777
- ${pc2.cyan("pica platforms")} - See all 200+ integrations`;
780
+ summary += pc2.yellow("Note: Project config files can be committed to share with your team.\n") + pc2.yellow("Team members will need their own API key.");
778
781
  p.note(summary, "Setup Complete");
779
- p.outro("Pica MCP installed!");
782
+ await promptConnectIntegrations(apiKey);
783
+ p.outro("Your AI agents now have access to Pica integrations!");
780
784
  return;
781
785
  }
782
786
  const installedAgentIds = [];
@@ -793,16 +797,105 @@ ${globalPaths}
793
797
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
794
798
  });
795
799
  p.note(
796
- `Config saved to: ${pc2.dim(getConfigPath())}
797
-
798
- Next steps:
799
- ${pc2.cyan("pica add gmail")} - Connect Gmail
800
- ${pc2.cyan("pica platforms")} - See all 200+ integrations
801
- ${pc2.cyan("pica connection list")} - View your connections`,
800
+ `Config saved to: ${pc2.dim(getConfigPath())}`,
802
801
  "Setup Complete"
803
802
  );
803
+ await promptConnectIntegrations(apiKey);
804
804
  p.outro("Your AI agents now have access to Pica integrations!");
805
805
  }
806
+ function printBanner() {
807
+ console.log();
808
+ console.log(pc2.cyan(" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588"));
809
+ console.log(pc2.cyan(" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588"));
810
+ console.log(pc2.cyan(" \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588"));
811
+ console.log(pc2.cyan(" \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588"));
812
+ console.log(pc2.cyan(" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588"));
813
+ console.log(pc2.cyan(" \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588"));
814
+ console.log(pc2.cyan(" \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588"));
815
+ console.log(pc2.cyan(" \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588"));
816
+ console.log(pc2.cyan(" \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588"));
817
+ console.log(pc2.cyan(" \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588"));
818
+ console.log();
819
+ console.log(pc2.dim(" U N I V E R S A L I N T E G R A T I O N S F O R A I"));
820
+ console.log();
821
+ }
822
+ var TOP_INTEGRATIONS = [
823
+ { value: "gmail", label: "Gmail", hint: "Read and send emails" },
824
+ { value: "google-calendar", label: "Google Calendar", hint: "Manage events and schedules" },
825
+ { value: "notion", label: "Notion", hint: "Access pages, databases, and docs" }
826
+ ];
827
+ async function promptConnectIntegrations(apiKey) {
828
+ const api = new PicaApi(apiKey);
829
+ const connected = [];
830
+ try {
831
+ const existing = await api.listConnections();
832
+ for (const conn of existing) {
833
+ const match = TOP_INTEGRATIONS.find(
834
+ (i) => i.value === conn.platform.toLowerCase()
835
+ );
836
+ if (match) connected.push(match.value);
837
+ }
838
+ } catch {
839
+ }
840
+ let first = true;
841
+ while (true) {
842
+ const available = TOP_INTEGRATIONS.filter((i) => !connected.includes(i.value));
843
+ const options = [
844
+ ...available.map((i) => ({
845
+ value: i.value,
846
+ label: i.label,
847
+ hint: i.hint
848
+ })),
849
+ { value: "more", label: "Browse all 200+ platforms" },
850
+ { value: "skip", label: "Skip for now", hint: "you can always run pica add later" }
851
+ ];
852
+ const message = first ? "Connect your first integration?" : "Connect another?";
853
+ const choice = await p.select({ message, options });
854
+ if (p.isCancel(choice) || choice === "skip") {
855
+ break;
856
+ }
857
+ if (choice === "more") {
858
+ try {
859
+ await open2("https://app.picaos.com/connections");
860
+ p.log.info("Opened Pica dashboard in browser.");
861
+ } catch {
862
+ p.note("https://app.picaos.com/connections", "Open in browser");
863
+ }
864
+ p.log.info(`Connect from the dashboard, or use ${pc2.cyan("pica add <platform>")}`);
865
+ break;
866
+ }
867
+ const platform = choice;
868
+ const integration = TOP_INTEGRATIONS.find((i) => i.value === platform);
869
+ const label = integration?.label ?? platform;
870
+ p.log.info(`Opening browser to connect ${pc2.cyan(label)}...`);
871
+ try {
872
+ await openConnectionPage(platform);
873
+ } catch {
874
+ const url = getConnectionUrl(platform);
875
+ p.log.warn("Could not open browser automatically.");
876
+ p.note(url, "Open manually");
877
+ }
878
+ const spinner5 = p.spinner();
879
+ spinner5.start("Waiting for connection... (complete auth in browser)");
880
+ try {
881
+ await api.waitForConnection(platform, 5 * 60 * 1e3, 5e3);
882
+ spinner5.stop(`${label} connected!`);
883
+ p.log.success(`${pc2.green("\u2713")} ${label} is now available to your AI agents`);
884
+ connected.push(platform);
885
+ first = false;
886
+ } catch (error) {
887
+ spinner5.stop("Connection timed out");
888
+ if (error instanceof TimeoutError) {
889
+ p.log.warn(`No worries. Connect later with: ${pc2.cyan(`pica add ${platform}`)}`);
890
+ }
891
+ first = false;
892
+ }
893
+ if (TOP_INTEGRATIONS.every((i) => connected.includes(i.value))) {
894
+ p.log.success("All top integrations connected!");
895
+ break;
896
+ }
897
+ }
898
+ }
806
899
  function maskApiKey(key) {
807
900
  if (key.length <= 12) return key.slice(0, 8) + "...";
808
901
  return key.slice(0, 8) + "..." + key.slice(-4);
@@ -1398,8 +1491,10 @@ function formatResponse(data, indent = 2) {
1398
1491
  }
1399
1492
 
1400
1493
  // src/index.ts
1494
+ var require2 = createRequire(import.meta.url);
1495
+ var { version } = require2("../package.json");
1401
1496
  var program = new Command();
1402
- program.name("pica").description("CLI for managing Pica integrations").version("0.1.0");
1497
+ program.name("pica").description("CLI for managing Pica").version(version);
1403
1498
  program.command("init").description("Set up Pica and install MCP to your AI agents").option("-y, --yes", "Skip confirmations").option("-g, --global", "Install MCP globally (available in all projects)").option("-p, --project", "Install MCP for this project only (creates .mcp.json)").action(async (options) => {
1404
1499
  await initCommand(options);
1405
1500
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@picahq/cli",
3
- "version": "0.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "CLI for managing Pica",
5
5
  "type": "module",
6
6
  "files": [