@withone/cli 1.16.0 → 1.17.1

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.
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  loadFlow,
12
12
  resolveFlowPath,
13
13
  saveFlow
14
- } from "./chunk-SX2Y4HDW.js";
14
+ } from "./chunk-QW4MBV4F.js";
15
15
 
16
16
  // src/index.ts
17
17
  import { createRequire as createRequire2 } from "module";
@@ -19,9 +19,10 @@ import { Command } from "commander";
19
19
 
20
20
  // src/commands/init.ts
21
21
  import * as p3 from "@clack/prompts";
22
- import pc3 from "picocolors";
22
+ import pc2 from "picocolors";
23
+ import fs3 from "fs";
23
24
  import path3 from "path";
24
- import { spawn } from "child_process";
25
+ import os3 from "os";
25
26
  import { fileURLToPath } from "url";
26
27
 
27
28
  // src/lib/config.ts
@@ -530,122 +531,69 @@ function formatList(list) {
530
531
 
531
532
  // src/commands/init.ts
532
533
  import open2 from "open";
533
-
534
- // src/lib/table.ts
535
- import pc2 from "picocolors";
536
- function printTable(columns, rows) {
537
- if (rows.length === 0) return;
538
- const gap = " ";
539
- const indent = " ";
540
- const widths = columns.map((col) => {
541
- const headerLen = col.label.length;
542
- const maxValueLen = Math.max(...rows.map((row) => stripAnsi(row[col.key] || "").length));
543
- return Math.max(headerLen, maxValueLen);
544
- });
545
- const header = columns.map((col, i) => {
546
- const padded = col.align === "right" ? col.label.padStart(widths[i]) : col.label.padEnd(widths[i]);
547
- return pc2.dim(padded);
548
- }).join(gap);
549
- console.log(`${indent}${header}`);
550
- const separator = columns.map((_, i) => pc2.dim("\u2500".repeat(widths[i]))).join(gap);
551
- console.log(`${indent}${separator}`);
552
- for (const row of rows) {
553
- const line = columns.map((col, i) => {
554
- const raw = row[col.key] || "";
555
- const rawLen = stripAnsi(raw).length;
556
- const padding = widths[i] - rawLen;
557
- const colored = col.color ? col.color(raw) : raw;
558
- if (col.align === "right") {
559
- return " ".repeat(Math.max(0, padding)) + colored;
560
- }
561
- return colored + " ".repeat(Math.max(0, padding));
562
- }).join(gap);
563
- console.log(`${indent}${line}`);
564
- }
565
- }
566
- function stripAnsi(str) {
567
- return str.replace(/\x1b\[[0-9;]*m/g, "");
568
- }
569
-
570
- // src/commands/init.ts
571
534
  async function initCommand(options) {
572
535
  if (isAgentMode()) {
573
536
  error("This command requires interactive input. Run without --agent.");
574
537
  }
575
538
  const existingConfig = readConfig();
539
+ printBanner();
576
540
  if (existingConfig) {
577
- p3.intro(pc3.bgCyan(pc3.black(" One ")));
578
541
  await handleExistingConfig(existingConfig.apiKey, options);
579
542
  return;
580
543
  }
581
- printBanner();
582
544
  await freshSetup(options);
583
545
  }
584
546
  async function handleExistingConfig(apiKey, options) {
585
547
  const statuses = getAgentStatuses();
586
548
  const masked = maskApiKey(apiKey);
549
+ const skillInstalled = isSkillInstalled();
587
550
  console.log();
588
- console.log(` ${pc3.bold("Current Setup")}`);
589
- console.log(` ${pc3.dim("\u2500".repeat(42))}`);
590
- console.log(` ${pc3.dim("API Key:")} ${masked}`);
591
- console.log(` ${pc3.dim("Config:")} ${getConfigPath()}`);
592
- console.log();
593
- printTable(
594
- [
595
- { key: "agent", label: "Agent" },
596
- { key: "global", label: "Global" },
597
- { key: "project", label: "Project" }
598
- ],
599
- statuses.map((s) => ({
600
- agent: s.agent.name,
601
- global: !s.detected ? pc3.dim("-") : s.globalMcp ? pc3.green("\u25CF yes") : pc3.yellow("\u25CB no"),
602
- project: s.projectMcp === null ? pc3.dim("-") : s.projectMcp ? pc3.green("\u25CF yes") : pc3.yellow("\u25CB no")
603
- }))
604
- );
605
- const notDetected = statuses.filter((s) => !s.detected);
606
- if (notDetected.length > 0) {
607
- console.log(` ${pc3.dim("- = not detected on this machine")}`);
608
- }
551
+ console.log(` ${pc2.bold("Current Setup")}`);
552
+ console.log(` ${pc2.dim("\u2500".repeat(42))}`);
553
+ console.log(` ${pc2.dim("API Key:")} ${masked}`);
554
+ console.log(` ${pc2.dim("Skill:")} ${skillInstalled ? pc2.green("installed") : pc2.yellow("not installed")}`);
555
+ console.log(` ${pc2.dim("Config:")} ${getConfigPath()}`);
609
556
  const ac = getAccessControl();
610
557
  if (Object.keys(ac).length > 0) {
611
- console.log(` ${pc3.bold("Access Control")}`);
612
- console.log(` ${pc3.dim("\u2500".repeat(42))}`);
613
- if (ac.permissions) console.log(` ${pc3.dim("Permissions:")} ${ac.permissions}`);
614
- if (ac.connectionKeys) console.log(` ${pc3.dim("Connections:")} ${ac.connectionKeys.join(", ")}`);
615
- if (ac.actionIds) console.log(` ${pc3.dim("Action IDs:")} ${ac.actionIds.join(", ")}`);
616
- if (ac.knowledgeAgent) console.log(` ${pc3.dim("Knowledge only:")} yes`);
617
558
  console.log();
559
+ console.log(` ${pc2.bold("Access Control")}`);
560
+ console.log(` ${pc2.dim("\u2500".repeat(42))}`);
561
+ if (ac.permissions) console.log(` ${pc2.dim("Permissions:")} ${ac.permissions}`);
562
+ if (ac.connectionKeys) console.log(` ${pc2.dim("Connections:")} ${ac.connectionKeys.join(", ")}`);
563
+ if (ac.actionIds) console.log(` ${pc2.dim("Action IDs:")} ${ac.actionIds.join(", ")}`);
564
+ if (ac.knowledgeAgent) console.log(` ${pc2.dim("Knowledge only:")} yes`);
618
565
  }
566
+ console.log();
619
567
  const actionOptions = [];
620
568
  actionOptions.push({
621
- value: "update-key",
622
- label: "Update API key"
569
+ value: "install-skills",
570
+ label: skillInstalled ? "Update skill" : "Install skill",
571
+ hint: skillInstalled ? "reinstall latest version" : "recommended"
623
572
  });
624
573
  actionOptions.push({
625
- value: "install-skills",
626
- label: "Install/update skills"
574
+ value: "show-prompt",
575
+ label: "Show agent onboarding prompt",
576
+ hint: "copy-paste to your AI agent"
577
+ });
578
+ actionOptions.push({
579
+ value: "add-connection",
580
+ label: "Connect a platform",
581
+ hint: "add Gmail, Slack, Shopify, etc."
582
+ });
583
+ actionOptions.push({
584
+ value: "update-key",
585
+ label: "Update API key"
627
586
  });
628
- const agentsMissingGlobal = statuses.filter((s) => s.detected && !s.globalMcp);
629
- if (agentsMissingGlobal.length > 0) {
630
- actionOptions.push({
631
- value: "install-more",
632
- label: "Install MCP to more agents",
633
- hint: `${agentsMissingGlobal.map((s) => s.agent.name).join(", ")} (not recommended)`
634
- });
635
- }
636
- const agentsMissingProject = statuses.filter((s) => s.projectMcp === false);
637
- if (agentsMissingProject.length > 0) {
638
- actionOptions.push({
639
- value: "install-project",
640
- label: "Install MCP for this project",
641
- hint: `${agentsMissingProject.map((s) => s.agent.name).join(", ")} (not recommended)`
642
- });
643
- }
644
587
  actionOptions.push({
645
588
  value: "access-control",
646
589
  label: "Configure access control",
647
590
  hint: "permissions, connections, actions"
648
591
  });
592
+ actionOptions.push({
593
+ value: "install-mcp",
594
+ label: "Install MCP server",
595
+ hint: "not recommended \u2014 use skills instead"
596
+ });
649
597
  actionOptions.push({
650
598
  value: "start-fresh",
651
599
  label: "Start fresh (reconfigure everything)"
@@ -659,30 +607,34 @@ async function handleExistingConfig(apiKey, options) {
659
607
  return;
660
608
  }
661
609
  switch (action) {
662
- case "update-key":
663
- await handleUpdateKey(statuses);
664
- break;
665
610
  case "install-skills": {
666
- const success = await runSkillsInstall();
611
+ const success = await promptSkillInstall();
667
612
  if (success) {
668
- p3.outro("Skills installed successfully.");
613
+ printOnboardingPrompt();
614
+ p3.outro("Skill installed. Paste the prompt above to your AI agent.");
669
615
  } else {
670
- const __dirname2 = path3.dirname(fileURLToPath(import.meta.url));
671
- const skillsDir = path3.resolve(__dirname2, "..", "skills");
672
- p3.log.warn(`Skills installation failed. You can try manually: ${pc3.cyan(`npx skills add ${skillsDir}`)}`);
673
616
  p3.outro("Done.");
674
617
  }
675
618
  break;
676
619
  }
677
- case "install-more":
678
- await handleInstallMore(apiKey, agentsMissingGlobal);
620
+ case "show-prompt":
621
+ printOnboardingPrompt();
622
+ p3.outro("Paste the prompt above to your AI agent.");
623
+ break;
624
+ case "add-connection":
625
+ await promptConnectIntegrations(apiKey);
626
+ p3.outro("Done.");
679
627
  break;
680
- case "install-project":
681
- await handleInstallProject(apiKey, agentsMissingProject);
628
+ case "update-key":
629
+ await handleUpdateKey(statuses);
682
630
  break;
683
631
  case "access-control":
684
632
  await configCommand();
685
633
  break;
634
+ case "install-mcp":
635
+ await promptAndInstallMcp(apiKey, options);
636
+ p3.outro("Done.");
637
+ break;
686
638
  case "start-fresh":
687
639
  await freshSetup({ yes: true });
688
640
  break;
@@ -690,7 +642,7 @@ async function handleExistingConfig(apiKey, options) {
690
642
  }
691
643
  async function handleUpdateKey(statuses) {
692
644
  p3.note(`Get your API key at:
693
- ${pc3.cyan(getApiKeyUrl())}`, "API Key");
645
+ ${pc2.cyan(getApiKeyUrl())}`, "API Key");
694
646
  const openBrowser = await p3.confirm({
695
647
  message: "Open browser to get API key?",
696
648
  initialValue: true
@@ -751,108 +703,161 @@ ${pc3.cyan(getApiKeyUrl())}`, "API Key");
751
703
  }
752
704
  p3.outro("API key updated.");
753
705
  }
754
- async function handleInstallMore(apiKey, missing) {
755
- const ac = getAccessControl();
756
- if (missing.length === 1) {
757
- const agent = missing[0].agent;
758
- const confirm3 = await p3.confirm({
759
- message: `Install One MCP to ${agent.name}?`,
760
- initialValue: true
761
- });
762
- if (p3.isCancel(confirm3) || !confirm3) {
763
- p3.outro("No changes made.");
764
- return;
706
+ var SKILL_AGENTS = [
707
+ { id: "claude-code", name: "Claude Code", skillDir: ".claude/skills", primary: true },
708
+ { id: "claude-desktop", name: "Claude Desktop", skillDir: ".claude/skills", primary: true },
709
+ { id: "codex", name: "Codex", skillDir: ".codex/skills", primary: true },
710
+ { id: "cursor", name: "Cursor", skillDir: ".cursor/skills" },
711
+ { id: "windsurf", name: "Windsurf", skillDir: ".codeium/windsurf/skills" },
712
+ { id: "kiro", name: "Kiro", skillDir: ".kiro/skills" },
713
+ { id: "goose", name: "Goose", skillDir: ".config/goose/skills" },
714
+ { id: "amp", name: "Amp", skillDir: ".amp/skills" },
715
+ { id: "opencode", name: "OpenCode", skillDir: ".opencode/skills" },
716
+ { id: "roo", name: "Roo", skillDir: ".roo/skills" }
717
+ ];
718
+ var CANONICAL_SKILL_DIR = ".agents/skills";
719
+ function getSkillSourceDir() {
720
+ const __dirname2 = path3.dirname(fileURLToPath(import.meta.url));
721
+ return path3.resolve(__dirname2, "..", "skills", "one");
722
+ }
723
+ function getCanonicalSkillPath() {
724
+ return path3.join(os3.homedir(), CANONICAL_SKILL_DIR, "one");
725
+ }
726
+ function getAgentSkillPath(agent) {
727
+ return path3.join(os3.homedir(), agent.skillDir, "one");
728
+ }
729
+ function isSkillInstalled() {
730
+ return fs3.existsSync(path3.join(getCanonicalSkillPath(), "SKILL.md"));
731
+ }
732
+ function isSkillInstalledForAgent(agent) {
733
+ return fs3.existsSync(path3.join(getAgentSkillPath(agent), "SKILL.md"));
734
+ }
735
+ function copyDirSync(src, dest) {
736
+ fs3.mkdirSync(dest, { recursive: true });
737
+ for (const entry of fs3.readdirSync(src, { withFileTypes: true })) {
738
+ const srcPath = path3.join(src, entry.name);
739
+ const destPath = path3.join(dest, entry.name);
740
+ if (entry.isDirectory()) {
741
+ copyDirSync(srcPath, destPath);
742
+ } else {
743
+ fs3.copyFileSync(srcPath, destPath);
765
744
  }
766
- installMcpConfig(agent, apiKey, "global", ac);
767
- updateConfigAgents(agent.id);
768
- p3.log.success(`${agent.name}: MCP installed`);
769
- p3.outro("Done.");
770
- return;
771
745
  }
772
- const selected = await p3.multiselect({
773
- message: "Select agents to install MCP:",
774
- options: missing.map((s) => ({
775
- value: s.agent.id,
776
- label: s.agent.name
777
- }))
778
- });
779
- if (p3.isCancel(selected)) {
780
- p3.outro("No changes made.");
781
- return;
746
+ }
747
+ function installSkillForAgents(agentIds) {
748
+ const source = getSkillSourceDir();
749
+ const canonical = getCanonicalSkillPath();
750
+ const installed = [];
751
+ const failed = [];
752
+ if (!fs3.existsSync(path3.join(source, "SKILL.md"))) {
753
+ return { installed: [], failed: ["skill source not found"] };
782
754
  }
783
- const agents = missing.filter((s) => selected.includes(s.agent.id));
784
- for (const s of agents) {
785
- installMcpConfig(s.agent, apiKey, "global", ac);
786
- updateConfigAgents(s.agent.id);
787
- p3.log.success(`${s.agent.name}: MCP installed`);
755
+ try {
756
+ if (fs3.existsSync(canonical)) {
757
+ fs3.rmSync(canonical, { recursive: true });
758
+ }
759
+ copyDirSync(source, canonical);
760
+ } catch {
761
+ return { installed: [], failed: ["canonical copy"] };
788
762
  }
789
- p3.outro("Done.");
763
+ const seen = /* @__PURE__ */ new Map();
764
+ for (const id of agentIds) {
765
+ const agent = SKILL_AGENTS.find((a) => a.id === id);
766
+ if (!agent) continue;
767
+ const agentPath = getAgentSkillPath(agent);
768
+ if (seen.has(agentPath)) {
769
+ (seen.get(agentPath) ? installed : failed).push(agent.name);
770
+ continue;
771
+ }
772
+ try {
773
+ const agentSkillsDir = path3.dirname(agentPath);
774
+ fs3.mkdirSync(agentSkillsDir, { recursive: true });
775
+ try {
776
+ fs3.lstatSync(agentPath);
777
+ fs3.rmSync(agentPath, { recursive: true });
778
+ } catch {
779
+ }
780
+ const relative = path3.relative(agentSkillsDir, canonical);
781
+ fs3.symlinkSync(relative, agentPath);
782
+ installed.push(agent.name);
783
+ seen.set(agentPath, true);
784
+ } catch {
785
+ failed.push(agent.name);
786
+ seen.set(agentPath, false);
787
+ }
788
+ }
789
+ return { installed, failed };
790
790
  }
791
- async function handleInstallProject(apiKey, missing) {
792
- const ac = getAccessControl();
793
- if (missing.length === 1) {
794
- const agent = missing[0].agent;
795
- const confirm3 = await p3.confirm({
796
- message: `Install project-level MCP for ${agent.name}?`,
797
- initialValue: true
791
+ async function promptSkillInstall() {
792
+ const primaryAgents = SKILL_AGENTS.filter((a) => a.primary);
793
+ const otherAgents = SKILL_AGENTS.filter((a) => !a.primary);
794
+ const options = [
795
+ ...primaryAgents.map((a) => ({
796
+ value: a.id,
797
+ label: a.name,
798
+ hint: isSkillInstalledForAgent(a) ? pc2.green("installed") : void 0
799
+ })),
800
+ {
801
+ value: "_other",
802
+ label: "Other agents",
803
+ hint: otherAgents.map((a) => a.name).join(", ")
804
+ }
805
+ ];
806
+ const choice = await p3.multiselect({
807
+ message: "Install the One skill to:",
808
+ options,
809
+ initialValues: primaryAgents.map((a) => a.id)
810
+ });
811
+ if (p3.isCancel(choice)) {
812
+ return false;
813
+ }
814
+ let selectedIds = choice;
815
+ if (selectedIds.includes("_other")) {
816
+ selectedIds = selectedIds.filter((id) => id !== "_other");
817
+ const otherChoice = await p3.multiselect({
818
+ message: "Select additional agents:",
819
+ options: otherAgents.map((a) => ({
820
+ value: a.id,
821
+ label: a.name,
822
+ hint: isSkillInstalledForAgent(a) ? pc2.green("installed") : void 0
823
+ }))
798
824
  });
799
- if (p3.isCancel(confirm3) || !confirm3) {
800
- p3.outro("No changes made.");
801
- return;
825
+ if (!p3.isCancel(otherChoice)) {
826
+ selectedIds.push(...otherChoice);
802
827
  }
803
- installMcpConfig(agent, apiKey, "project", ac);
804
- const configPath = getAgentConfigPath(agent, "project");
805
- p3.log.success(`${agent.name}: ${configPath} created`);
806
- p3.note(
807
- pc3.yellow("Project config files can be committed to share with your team.\n") + pc3.yellow("Team members will need their own API key."),
808
- "Tip"
809
- );
810
- p3.outro("Done.");
811
- return;
812
828
  }
813
- const selected = await p3.multiselect({
814
- message: "Select agents for project-level MCP:",
815
- options: missing.map((s) => ({
816
- value: s.agent.id,
817
- label: s.agent.name
818
- }))
819
- });
820
- if (p3.isCancel(selected)) {
821
- p3.outro("No changes made.");
822
- return;
829
+ if (selectedIds.length === 0) {
830
+ p3.log.info("No agents selected.");
831
+ return false;
832
+ }
833
+ const spinner5 = p3.spinner();
834
+ spinner5.start("Installing skill...");
835
+ const { installed, failed } = installSkillForAgents(selectedIds);
836
+ spinner5.stop(installed.length > 0 ? "Skill installed" : "Installation failed");
837
+ for (const name of installed) {
838
+ p3.log.success(`${name}: ${pc2.green("\u2713")} skill installed`);
823
839
  }
824
- const agents = missing.filter((s) => selected.includes(s.agent.id));
825
- for (const s of agents) {
826
- installMcpConfig(s.agent, apiKey, "project", ac);
827
- const configPath = getAgentConfigPath(s.agent, "project");
828
- p3.log.success(`${s.agent.name}: ${configPath} created`);
840
+ for (const name of failed) {
841
+ p3.log.warn(`${name}: failed to install`);
829
842
  }
830
- p3.note(
831
- pc3.yellow("Project config files can be committed to share with your team.\n") + pc3.yellow("Team members will need their own API key."),
832
- "Tip"
833
- );
834
- p3.outro("Done.");
843
+ return installed.length > 0;
835
844
  }
836
- async function runSkillsInstall() {
837
- const __dirname2 = path3.dirname(fileURLToPath(import.meta.url));
838
- const skillsDir = path3.resolve(__dirname2, "..", "skills");
839
- return new Promise((resolve) => {
840
- const handler = () => {
841
- };
842
- process.on("SIGINT", handler);
843
- const child = spawn("npx", ["skills", "add", skillsDir], {
844
- stdio: "inherit",
845
- shell: true
846
- });
847
- child.on("close", (code) => {
848
- process.removeListener("SIGINT", handler);
849
- resolve(code === 0);
850
- });
851
- child.on("error", () => {
852
- process.removeListener("SIGINT", handler);
853
- resolve(false);
854
- });
855
- });
845
+ function printOnboardingPrompt() {
846
+ console.log();
847
+ console.log(pc2.bold(" Copy-paste this to your AI agent:"));
848
+ console.log();
849
+ console.log(pc2.cyan(" \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
850
+ console.log(pc2.cyan(" \u2502"));
851
+ console.log(pc2.cyan(" \u2502 The One CLI (`one`) is now installed on this machine. It"));
852
+ console.log(pc2.cyan(" \u2502 lets you interact with 250+ third-party platforms (Gmail,"));
853
+ console.log(pc2.cyan(" \u2502 Slack, Shopify, HubSpot, Stripe, GitHub, etc.) through"));
854
+ console.log(pc2.cyan(" \u2502 their APIs. Whenever you need to interact with any"));
855
+ console.log(pc2.cyan(" \u2502 third-party platform or external service, use the `one`"));
856
+ console.log(pc2.cyan(" \u2502 skill. Please save this to your project instructions or"));
857
+ console.log(pc2.cyan(" \u2502 memory so you remember it in future conversations."));
858
+ console.log(pc2.cyan(" \u2502"));
859
+ console.log(pc2.cyan(" \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
860
+ console.log();
856
861
  }
857
862
  async function promptAndInstallMcp(apiKey, options) {
858
863
  const allAgents = getAllAgents();
@@ -935,7 +940,7 @@ Project scope is supported by: ${supported}`,
935
940
  const allInstalled = [...projectAgents, ...nonProjectAgents];
936
941
  updateConfigAgentsList(allInstalled.map((a) => a.id));
937
942
  p3.note(
938
- pc3.yellow("Project config files can be committed to share with your team.\n") + pc3.yellow("Team members will need their own API key."),
943
+ pc2.yellow("Project config files can be committed to share with your team.\n") + pc2.yellow("Team members will need their own API key."),
939
944
  "Tip"
940
945
  );
941
946
  return;
@@ -952,7 +957,7 @@ Project scope is supported by: ${supported}`,
952
957
  }
953
958
  async function freshSetup(options) {
954
959
  p3.note(`Get your API key at:
955
- ${pc3.cyan(getApiKeyUrl())}`, "API Key");
960
+ ${pc2.cyan(getApiKeyUrl())}`, "API Key");
956
961
  const openBrowser = await p3.confirm({
957
962
  message: "Open browser to get API key?",
958
963
  initialValue: true
@@ -994,20 +999,7 @@ ${pc3.cyan(getApiKeyUrl())}`, "API Key");
994
999
  installedAgents: [],
995
1000
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
996
1001
  });
997
- const installSkills = await p3.confirm({
998
- message: "Install One skills to your AI agents? (recommended)",
999
- initialValue: true
1000
- });
1001
- if (!p3.isCancel(installSkills) && installSkills) {
1002
- const success = await runSkillsInstall();
1003
- if (success) {
1004
- p3.log.success("Skills installed successfully.");
1005
- } else {
1006
- const __dirname2 = path3.dirname(fileURLToPath(import.meta.url));
1007
- const skillsDir = path3.resolve(__dirname2, "..", "skills");
1008
- p3.log.warn(`Skills installation failed. You can try manually: ${pc3.cyan(`npx skills add ${skillsDir}`)}`);
1009
- }
1010
- }
1002
+ await promptSkillInstall();
1011
1003
  await promptConnectIntegrations(apiKey);
1012
1004
  const installMcp = await p3.confirm({
1013
1005
  message: "Install One MCP server to your AI agents? (not recommended)",
@@ -1017,29 +1009,26 @@ ${pc3.cyan(getApiKeyUrl())}`, "API Key");
1017
1009
  await promptAndInstallMcp(apiKey, options);
1018
1010
  }
1019
1011
  p3.note(
1020
- `Config saved to: ${pc3.dim(getConfigPath())}`,
1012
+ `Config saved to: ${pc2.dim(getConfigPath())}`,
1021
1013
  "Setup Complete"
1022
1014
  );
1023
- p3.note(
1024
- `Tell your agent to run ${pc3.cyan("one onboard")} to learn what it can do.`,
1025
- "Next Step"
1026
- );
1027
- p3.outro("Your AI agents now have access to One integrations!");
1015
+ printOnboardingPrompt();
1016
+ p3.outro("Done! Paste the prompt above to your AI agent.");
1028
1017
  }
1029
1018
  function printBanner() {
1030
1019
  console.log();
1031
- console.log(pc3.yellow(" \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"));
1032
- console.log(pc3.yellow(" \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"));
1033
- console.log(pc3.yellow(" \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 "));
1034
- console.log(pc3.yellow(" \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 "));
1035
- console.log(pc3.yellow(" \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 "));
1036
- console.log(pc3.yellow(" \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 "));
1037
- console.log(pc3.yellow(" \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 "));
1038
- console.log(pc3.yellow(" \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 "));
1039
- console.log(pc3.yellow(" \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"));
1040
- console.log(pc3.yellow(" \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"));
1020
+ console.log(pc2.yellow(" \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"));
1021
+ console.log(pc2.yellow(" \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"));
1022
+ console.log(pc2.yellow(" \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 "));
1023
+ console.log(pc2.yellow(" \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 "));
1024
+ console.log(pc2.yellow(" \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 "));
1025
+ console.log(pc2.yellow(" \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 "));
1026
+ console.log(pc2.yellow(" \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 "));
1027
+ console.log(pc2.yellow(" \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 "));
1028
+ console.log(pc2.yellow(" \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"));
1029
+ console.log(pc2.yellow(" \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"));
1041
1030
  console.log();
1042
- console.log(pc3.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"));
1031
+ console.log(pc2.dim(" I N F R A S T R U C T U R E F O R A G E N T S"));
1043
1032
  console.log();
1044
1033
  }
1045
1034
  var TOP_INTEGRATIONS = [
@@ -1084,13 +1073,13 @@ async function promptConnectIntegrations(apiKey) {
1084
1073
  } catch {
1085
1074
  p3.note("https://app.withone.ai/connections", "Open in browser");
1086
1075
  }
1087
- p3.log.info(`Connect from the dashboard, or use ${pc3.cyan("one add <platform>")}`);
1076
+ p3.log.info(`Connect from the dashboard, or use ${pc2.cyan("one add <platform>")}`);
1088
1077
  break;
1089
1078
  }
1090
1079
  const platform = choice;
1091
1080
  const integration = TOP_INTEGRATIONS.find((i) => i.value === platform);
1092
1081
  const label = integration?.label ?? platform;
1093
- p3.log.info(`Opening browser to connect ${pc3.cyan(label)}...`);
1082
+ p3.log.info(`Opening browser to connect ${pc2.cyan(label)}...`);
1094
1083
  try {
1095
1084
  await openConnectionPage(platform);
1096
1085
  } catch {
@@ -1103,13 +1092,13 @@ async function promptConnectIntegrations(apiKey) {
1103
1092
  try {
1104
1093
  await api.waitForConnection(platform, 5 * 60 * 1e3, 5e3);
1105
1094
  spinner5.stop(`${label} connected!`);
1106
- p3.log.success(`${pc3.green("\u2713")} ${label} is now available to your AI agents`);
1095
+ p3.log.success(`${pc2.green("\u2713")} ${label} is now available to your AI agents`);
1107
1096
  connected.push(platform);
1108
1097
  first = false;
1109
1098
  } catch (error2) {
1110
1099
  spinner5.stop("Connection timed out");
1111
1100
  if (error2 instanceof TimeoutError) {
1112
- p3.log.warn(`No worries. Connect later with: ${pc3.cyan(`one add ${platform}`)}`);
1101
+ p3.log.warn(`No worries. Connect later with: ${pc2.cyan(`one add ${platform}`)}`);
1113
1102
  }
1114
1103
  first = false;
1115
1104
  }
@@ -1123,14 +1112,6 @@ function maskApiKey(key) {
1123
1112
  if (key.length <= 12) return key.slice(0, 8) + "...";
1124
1113
  return key.slice(0, 8) + "..." + key.slice(-4);
1125
1114
  }
1126
- function updateConfigAgents(agentId) {
1127
- const config = readConfig();
1128
- if (!config) return;
1129
- if (!config.installedAgents.includes(agentId)) {
1130
- config.installedAgents.push(agentId);
1131
- writeConfig(config);
1132
- }
1133
- }
1134
1115
  function updateConfigAgentsList(agentIds) {
1135
1116
  const config = readConfig();
1136
1117
  if (!config) return;
@@ -1181,6 +1162,42 @@ function countMatchingChars(a, b) {
1181
1162
  return count;
1182
1163
  }
1183
1164
 
1165
+ // src/lib/table.ts
1166
+ import pc3 from "picocolors";
1167
+ function printTable(columns, rows) {
1168
+ if (rows.length === 0) return;
1169
+ const gap = " ";
1170
+ const indent = " ";
1171
+ const widths = columns.map((col) => {
1172
+ const headerLen = col.label.length;
1173
+ const maxValueLen = Math.max(...rows.map((row) => stripAnsi(row[col.key] || "").length));
1174
+ return Math.max(headerLen, maxValueLen);
1175
+ });
1176
+ const header = columns.map((col, i) => {
1177
+ const padded = col.align === "right" ? col.label.padStart(widths[i]) : col.label.padEnd(widths[i]);
1178
+ return pc3.dim(padded);
1179
+ }).join(gap);
1180
+ console.log(`${indent}${header}`);
1181
+ const separator = columns.map((_, i) => pc3.dim("\u2500".repeat(widths[i]))).join(gap);
1182
+ console.log(`${indent}${separator}`);
1183
+ for (const row of rows) {
1184
+ const line = columns.map((col, i) => {
1185
+ const raw = row[col.key] || "";
1186
+ const rawLen = stripAnsi(raw).length;
1187
+ const padding = widths[i] - rawLen;
1188
+ const colored = col.color ? col.color(raw) : raw;
1189
+ if (col.align === "right") {
1190
+ return " ".repeat(Math.max(0, padding)) + colored;
1191
+ }
1192
+ return colored + " ".repeat(Math.max(0, padding));
1193
+ }).join(gap);
1194
+ console.log(`${indent}${line}`);
1195
+ }
1196
+ }
1197
+ function stripAnsi(str) {
1198
+ return str.replace(/\x1b\[[0-9;]*m/g, "");
1199
+ }
1200
+
1184
1201
  // src/commands/connection.ts
1185
1202
  async function connectionAddCommand(platformArg) {
1186
1203
  if (isAgentMode()) {
@@ -2513,7 +2530,7 @@ function validateFlow(flow2) {
2513
2530
  }
2514
2531
 
2515
2532
  // src/commands/flow.ts
2516
- import fs3 from "fs";
2533
+ import fs4 from "fs";
2517
2534
  function getConfig2() {
2518
2535
  const apiKey = getApiKey();
2519
2536
  if (!apiKey) {
@@ -2571,7 +2588,7 @@ async function flowCreateCommand(key, options) {
2571
2588
  if (raw.startsWith("@")) {
2572
2589
  const filePath = raw.slice(1);
2573
2590
  try {
2574
- raw = fs3.readFileSync(filePath, "utf-8");
2591
+ raw = fs4.readFileSync(filePath, "utf-8");
2575
2592
  } catch (err) {
2576
2593
  error(`Cannot read file "${filePath}": ${err.message}`);
2577
2594
  }
@@ -2754,7 +2771,7 @@ async function flowValidateCommand(keyOrPath) {
2754
2771
  let flowData;
2755
2772
  try {
2756
2773
  const flowPath = resolveFlowPath(keyOrPath);
2757
- const content = fs3.readFileSync(flowPath, "utf-8");
2774
+ const content = fs4.readFileSync(flowPath, "utf-8");
2758
2775
  flowData = JSON.parse(content);
2759
2776
  } catch (err) {
2760
2777
  spinner5.stop("Validation failed");
@@ -3451,7 +3468,7 @@ Before using any feature, read its guide section first: \`one guide actions\`, \
3451
3468
 
3452
3469
  ## Features
3453
3470
 
3454
- ### 1. Actions \u2014 Execute API calls on 200+ platforms
3471
+ ### 1. Actions \u2014 Execute API calls on 250+ platforms
3455
3472
  Search for actions, read their docs, and execute them. This is the core workflow.
3456
3473
 
3457
3474
  **Quick start:**
@@ -3812,7 +3829,7 @@ function buildStep1() {
3812
3829
  nextCommand: "one onboard --step 2",
3813
3830
  message: `# One CLI \u2014 Agent Onboarding
3814
3831
 
3815
- You now have access to the One CLI. It connects you to 200+ platforms
3832
+ You now have access to the One CLI. It connects you to 250+ platforms
3816
3833
  (Gmail, Slack, Stripe, Notion, etc.) \u2014 you'll learn the details shortly.
3817
3834
 
3818
3835
  IMPORTANT: Your only task right now is to send the message below to the
@@ -3822,7 +3839,7 @@ Do not offer demos yet. Just send this message and wait for their reply:
3822
3839
  ---
3823
3840
 
3824
3841
  I just got access to the One CLI \u2014 it connects me to your platforms like
3825
- Gmail, Slack, Stripe, and 200+ others so I can work with them directly.
3842
+ Gmail, Slack, Stripe, and 250+ others so I can work with them directly.
3826
3843
  I'll show you what I can do in a moment.
3827
3844
 
3828
3845
  First, one quick setup step: right now only this conversation knows about
@@ -3851,7 +3868,7 @@ If they declined, skip this section.
3851
3868
  ## One CLI \u2014 Platform Integrations
3852
3869
 
3853
3870
  The One CLI (\`one\`) is installed and configured on this machine. It is a
3854
- command-line tool that gives AI agents the ability to interact with 200+
3871
+ command-line tool that gives AI agents the ability to interact with 250+
3855
3872
  third-party platforms (Gmail, Slack, Shopify, HubSpot, Stripe, GitHub,
3856
3873
  Notion, Salesforce, etc.) through a single, unified interface.
3857
3874
 
@@ -3946,7 +3963,7 @@ function buildStep3(connections) {
3946
3963
  The user can connect any of these popular platforms:
3947
3964
  Gmail, Google Calendar, Slack, Notion, Shopify, Stripe, HubSpot, GitHub,
3948
3965
  Salesforce, QuickBooks, Asana, Jira, Linear, Intercom, Zendesk, Twilio,
3949
- and 200+ more. Run \`one platforms\` for the full list.`);
3966
+ and 250+ more. Run \`one platforms\` for the full list.`);
3950
3967
  sections.push("## Onboarding complete!\n\nYou're all set. Use `one --agent guide` any time you need the full reference.");
3951
3968
  return {
3952
3969
  step: 3,
@@ -3977,7 +3994,7 @@ platform before you can start using actions. Suggest they run:
3977
3994
  one add slack
3978
3995
  one add <any-platform>
3979
3996
 
3980
- Run \`one platforms\` to see all 200+ available platforms.`;
3997
+ Run \`one platforms\` to see all 250+ available platforms.`;
3981
3998
  }
3982
3999
  const header = `## Current State
3983
4000
 
@@ -4037,20 +4054,23 @@ function buildWorkflowIdeas(connections) {
4037
4054
 
4038
4055
  // src/commands/update.ts
4039
4056
  import { createRequire } from "module";
4040
- import { spawn as spawn2 } from "child_process";
4057
+ import { spawn } from "child_process";
4041
4058
  import { readFileSync, writeFileSync, mkdirSync } from "fs";
4042
4059
  import { homedir } from "os";
4043
4060
  import { join } from "path";
4044
4061
  var require2 = createRequire(import.meta.url);
4045
4062
  var { version: currentVersion } = require2("../package.json");
4046
4063
  var CACHE_PATH = join(homedir(), ".one", "update-check.json");
4047
- var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
4048
- async function fetchLatestVersion() {
4064
+ var CHECK_INTERVAL_MS = 4 * 60 * 60 * 1e3;
4065
+ var AGE_GATE_MS = 30 * 60 * 1e3;
4066
+ async function fetchLatestVersionInfo() {
4049
4067
  try {
4050
- const res = await fetch("https://registry.npmjs.org/@withone/cli/latest");
4068
+ const res = await fetch("https://registry.npmjs.org/@withone/cli");
4051
4069
  if (!res.ok) return null;
4052
4070
  const data = await res.json();
4053
- return data.version;
4071
+ const latest = data["dist-tags"]?.latest;
4072
+ if (!latest) return null;
4073
+ return { version: latest, publishedAt: data.time?.[latest] ?? null };
4054
4074
  } catch {
4055
4075
  return null;
4056
4076
  }
@@ -4062,24 +4082,26 @@ function readCache() {
4062
4082
  return null;
4063
4083
  }
4064
4084
  }
4065
- function writeCache(latestVersion) {
4085
+ function writeCache(latestVersion, publishedAt) {
4066
4086
  try {
4067
4087
  mkdirSync(join(homedir(), ".one"), { recursive: true });
4068
- writeFileSync(CACHE_PATH, JSON.stringify({ lastCheck: Date.now(), latestVersion }));
4088
+ writeFileSync(CACHE_PATH, JSON.stringify({ lastCheck: Date.now(), latestVersion, publishedAt }));
4069
4089
  } catch {
4070
4090
  }
4071
4091
  }
4072
4092
  async function checkLatestVersion() {
4073
- const version2 = await fetchLatestVersion();
4074
- if (version2) writeCache(version2);
4075
- return version2;
4093
+ const info = await fetchLatestVersionInfo();
4094
+ if (info) writeCache(info.version, info.publishedAt);
4095
+ return info?.version ?? null;
4076
4096
  }
4077
4097
  async function checkLatestVersionCached() {
4078
4098
  const cache = readCache();
4079
4099
  if (cache && Date.now() - cache.lastCheck < CHECK_INTERVAL_MS) {
4080
- return cache.latestVersion;
4100
+ return { version: cache.latestVersion, publishedAt: cache.publishedAt ?? null };
4081
4101
  }
4082
- return checkLatestVersion();
4102
+ const info = await fetchLatestVersionInfo();
4103
+ if (info) writeCache(info.version, info.publishedAt);
4104
+ return info;
4083
4105
  }
4084
4106
  function getCurrentVersion() {
4085
4107
  return currentVersion;
@@ -4104,7 +4126,7 @@ async function updateCommand() {
4104
4126
  s.stop(`Update available: v${currentVersion} \u2192 v${latestVersion}`);
4105
4127
  console.log(`Updating @withone/cli: v${currentVersion} \u2192 v${latestVersion}...`);
4106
4128
  const code = await new Promise((resolve) => {
4107
- const child = spawn2("npm", ["install", "-g", "@withone/cli@latest", "--force"], {
4129
+ const child = spawn("npm", ["install", "-g", "@withone/cli@latest", "--force"], {
4108
4130
  stdio: isAgentMode() ? "pipe" : "inherit",
4109
4131
  shell: true
4110
4132
  });
@@ -4121,12 +4143,24 @@ async function updateCommand() {
4121
4143
  error("Update failed \u2014 try running: npm install -g @withone/cli@latest");
4122
4144
  }
4123
4145
  }
4146
+ function autoUpdate(targetVersion, publishedAt) {
4147
+ if (publishedAt) {
4148
+ const age = Date.now() - new Date(publishedAt).getTime();
4149
+ if (age < AGE_GATE_MS) return;
4150
+ }
4151
+ const child = spawn("npm", ["install", "-g", `@withone/cli@${targetVersion}`], {
4152
+ detached: true,
4153
+ stdio: "ignore",
4154
+ shell: true
4155
+ });
4156
+ child.unref();
4157
+ }
4124
4158
 
4125
4159
  // src/index.ts
4126
4160
  var require3 = createRequire2(import.meta.url);
4127
4161
  var { version } = require3("../package.json");
4128
4162
  var program = new Command();
4129
- program.name("one").option("--agent", "Machine-readable JSON output (no colors, spinners, or prompts)").description(`One CLI \u2014 Connect AI agents to 200+ platforms through one interface.
4163
+ program.name("one").option("--agent", "Machine-readable JSON output (no colors, spinners, or prompts)").description(`One CLI \u2014 Connect AI agents to 250+ platforms through one interface.
4130
4164
 
4131
4165
  Setup:
4132
4166
  one init Set up API key and install MCP server
@@ -4170,7 +4204,7 @@ program.name("one").option("--agent", "Machine-readable JSON output (no colors,
4170
4204
  -d '{"to":"j@example.com","subject":"Hello","body":"Hi!","connectionKey":"live::gmail::default::abc123"}'
4171
4205
 
4172
4206
  Platform names are always kebab-case (e.g. hub-spot, ship-station, google-calendar).
4173
- Run 'one platforms' to browse all 200+ available platforms.`).version(version);
4207
+ Run 'one platforms' to browse all 250+ available platforms.`).version(version);
4174
4208
  var updateCheckPromise;
4175
4209
  program.hook("preAction", (thisCommand) => {
4176
4210
  const opts = program.opts();
@@ -4184,18 +4218,11 @@ program.hook("preAction", (thisCommand) => {
4184
4218
  });
4185
4219
  program.hook("postAction", async () => {
4186
4220
  if (!updateCheckPromise) return;
4187
- const latestVersion = await updateCheckPromise;
4188
- if (!latestVersion) return;
4221
+ const info = await updateCheckPromise;
4222
+ if (!info) return;
4189
4223
  const current = getCurrentVersion();
4190
- if (current === latestVersion) return;
4191
- if (isAgentMode()) {
4192
- process.stderr.write(`
4193
- Update available: v${current} \u2192 v${latestVersion}. Run "one update" to upgrade.
4194
- `);
4195
- } else {
4196
- console.log(`
4197
- \x1B[33mUpdate available: v${current} \u2192 v${latestVersion}. Run \x1B[1mone update\x1B[22m to upgrade.\x1B[0m`);
4198
- }
4224
+ if (current === info.version) return;
4225
+ autoUpdate(info.version, info.publishedAt);
4199
4226
  });
4200
4227
  program.command("init").description("Set up One 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) => {
4201
4228
  await initCommand(options);