@keywaysh/cli 0.0.18 → 0.0.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.
Files changed (2) hide show
  1. package/dist/cli.js +130 -32
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -69,7 +69,7 @@ var INTERNAL_POSTHOG_HOST = "https://eu.i.posthog.com";
69
69
  // package.json
70
70
  var package_default = {
71
71
  name: "@keywaysh/cli",
72
- version: "0.0.18",
72
+ version: "0.0.20",
73
73
  description: "One link to all your secrets",
74
74
  type: "module",
75
75
  bin: {
@@ -216,16 +216,13 @@ async function handleResponse(response) {
216
216
  if (contentType.includes("application/json")) {
217
217
  try {
218
218
  const error = JSON.parse(text);
219
- const errorCode = error.error || error.title || "http_error";
220
- const errorMessage = error.message || error.detail || `HTTP ${response.status}`;
221
- const upgradeUrl = error.upgrade_url || error.upgradeUrl;
222
- throw new APIError(response.status, errorCode, errorMessage, upgradeUrl);
219
+ throw new APIError(response.status, error.title || "Error", error.detail || `HTTP ${response.status}`, error.upgradeUrl);
223
220
  } catch (e) {
224
221
  if (e instanceof APIError) throw e;
225
- throw new APIError(response.status, "http_error", text || `HTTP ${response.status}`);
222
+ throw new APIError(response.status, "Error", text || `HTTP ${response.status}`);
226
223
  }
227
224
  }
228
- throw new APIError(response.status, "http_error", text || `HTTP ${response.status}`);
225
+ throw new APIError(response.status, "Error", text || `HTTP ${response.status}`);
229
226
  }
230
227
  if (!text) {
231
228
  return {};
@@ -553,7 +550,8 @@ var AnalyticsEvents = {
553
550
  CLI_DOCTOR: "cli_doctor",
554
551
  CLI_CONNECT: "cli_connect",
555
552
  CLI_DISCONNECT: "cli_disconnect",
556
- CLI_SYNC: "cli_sync"
553
+ CLI_SYNC: "cli_sync",
554
+ CLI_FEEDBACK: "cli_feedback"
557
555
  };
558
556
 
559
557
  // src/cmds/login.ts
@@ -1759,14 +1757,66 @@ async function disconnectCommand(provider, options = {}) {
1759
1757
  import pc8 from "picocolors";
1760
1758
  import prompts7 from "prompts";
1761
1759
  function findMatchingProject(projects, repoFullName) {
1760
+ const repoFullNameLower = repoFullName.toLowerCase();
1762
1761
  const repoName = repoFullName.split("/")[1]?.toLowerCase();
1763
1762
  if (!repoName) return void 0;
1764
- const exact = projects.find((p) => p.name.toLowerCase() === repoName);
1765
- if (exact) return exact;
1766
- const partial = projects.filter(
1763
+ const linkedMatch = projects.find(
1764
+ (p) => p.linkedRepo?.toLowerCase() === repoFullNameLower
1765
+ );
1766
+ if (linkedMatch) {
1767
+ return { project: linkedMatch, matchType: "linked_repo" };
1768
+ }
1769
+ const exactNameMatch = projects.find((p) => p.name.toLowerCase() === repoName);
1770
+ if (exactNameMatch) {
1771
+ return { project: exactNameMatch, matchType: "exact_name" };
1772
+ }
1773
+ const partialMatches = projects.filter(
1767
1774
  (p) => p.name.toLowerCase().includes(repoName) || repoName.includes(p.name.toLowerCase())
1768
1775
  );
1769
- return partial.length === 1 ? partial[0] : void 0;
1776
+ if (partialMatches.length === 1) {
1777
+ return { project: partialMatches[0], matchType: "partial_name" };
1778
+ }
1779
+ return void 0;
1780
+ }
1781
+ function projectMatchesRepo(project, repoFullName) {
1782
+ const repoFullNameLower = repoFullName.toLowerCase();
1783
+ const repoName = repoFullName.split("/")[1]?.toLowerCase();
1784
+ if (project.linkedRepo?.toLowerCase() === repoFullNameLower) {
1785
+ return true;
1786
+ }
1787
+ if (repoName && project.name.toLowerCase() === repoName) {
1788
+ return true;
1789
+ }
1790
+ return false;
1791
+ }
1792
+ async function promptProjectSelection(projects, repoFullName) {
1793
+ const repoName = repoFullName.split("/")[1]?.toLowerCase() || "";
1794
+ const choices = projects.map((p) => {
1795
+ let title = p.name;
1796
+ const badges = [];
1797
+ if (p.linkedRepo?.toLowerCase() === repoFullName.toLowerCase()) {
1798
+ badges.push(pc8.green("\u2190 linked"));
1799
+ } else if (p.name.toLowerCase() === repoName) {
1800
+ badges.push(pc8.green("\u2190 same name"));
1801
+ } else if (p.linkedRepo) {
1802
+ badges.push(pc8.gray(`\u2192 ${p.linkedRepo}`));
1803
+ }
1804
+ if (badges.length > 0) {
1805
+ title = `${p.name} ${badges.join(" ")}`;
1806
+ }
1807
+ return { title, value: p.id };
1808
+ });
1809
+ const { projectChoice } = await prompts7({
1810
+ type: "select",
1811
+ name: "projectChoice",
1812
+ message: "Select a project:",
1813
+ choices
1814
+ });
1815
+ if (!projectChoice) {
1816
+ console.log(pc8.gray("Cancelled."));
1817
+ process.exit(0);
1818
+ }
1819
+ return projects.find((p) => p.id === projectChoice);
1770
1820
  }
1771
1821
  async function syncCommand(provider, options = {}) {
1772
1822
  try {
@@ -1807,43 +1857,91 @@ async function syncCommand(provider, options = {}) {
1807
1857
  process.exit(1);
1808
1858
  }
1809
1859
  selectedProject = found;
1860
+ if (!projectMatchesRepo(selectedProject, repoFullName)) {
1861
+ console.log("");
1862
+ console.log(pc8.yellow("\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\u2510"));
1863
+ console.log(pc8.yellow("\u2502 \u26A0\uFE0F WARNING: Project does not match current repository \u2502"));
1864
+ console.log(pc8.yellow("\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\u2518"));
1865
+ console.log(pc8.yellow(` Current repo: ${repoFullName}`));
1866
+ console.log(pc8.yellow(` Selected project: ${selectedProject.name}`));
1867
+ if (selectedProject.linkedRepo) {
1868
+ console.log(pc8.yellow(` Project linked to: ${selectedProject.linkedRepo}`));
1869
+ }
1870
+ console.log("");
1871
+ }
1810
1872
  } else {
1811
1873
  const autoMatch = findMatchingProject(projects, repoFullName);
1812
- if (autoMatch && projects.length > 1) {
1813
- console.log(pc8.gray(`Detected project: ${autoMatch.name}`));
1874
+ if (autoMatch && (autoMatch.matchType === "linked_repo" || autoMatch.matchType === "exact_name")) {
1875
+ selectedProject = autoMatch.project;
1876
+ const matchReason = autoMatch.matchType === "linked_repo" ? `linked to ${repoFullName}` : "exact name match";
1877
+ console.log(pc8.green(`\u2713 Auto-selected project: ${selectedProject.name} (${matchReason})`));
1878
+ } else if (autoMatch && autoMatch.matchType === "partial_name") {
1879
+ console.log(pc8.yellow(`Detected project: ${autoMatch.project.name} (partial match)`));
1814
1880
  const { useDetected } = await prompts7({
1815
1881
  type: "confirm",
1816
1882
  name: "useDetected",
1817
- message: `Use ${autoMatch.name}?`,
1883
+ message: `Use ${autoMatch.project.name}?`,
1818
1884
  initial: true
1819
1885
  });
1820
1886
  if (useDetected) {
1821
- selectedProject = autoMatch;
1887
+ selectedProject = autoMatch.project;
1822
1888
  } else {
1823
- const { projectChoice } = await prompts7({
1824
- type: "select",
1825
- name: "projectChoice",
1826
- message: "Select a project:",
1827
- choices: projects.map((p) => ({ title: p.name, value: p.id }))
1828
- });
1829
- selectedProject = projects.find((p) => p.id === projectChoice);
1889
+ selectedProject = await promptProjectSelection(projects, repoFullName);
1830
1890
  }
1831
- } else if (autoMatch) {
1832
- selectedProject = autoMatch;
1833
1891
  } else if (projects.length === 1) {
1834
1892
  selectedProject = projects[0];
1893
+ if (!projectMatchesRepo(selectedProject, repoFullName)) {
1894
+ console.log("");
1895
+ console.log(pc8.yellow("\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\u2510"));
1896
+ console.log(pc8.yellow("\u2502 \u26A0\uFE0F WARNING: Project does not match current repository \u2502"));
1897
+ console.log(pc8.yellow("\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\u2518"));
1898
+ console.log(pc8.yellow(` Current repo: ${repoFullName}`));
1899
+ console.log(pc8.yellow(` Only project: ${selectedProject.name}`));
1900
+ if (selectedProject.linkedRepo) {
1901
+ console.log(pc8.yellow(` Project linked to: ${selectedProject.linkedRepo}`));
1902
+ }
1903
+ console.log("");
1904
+ const { continueAnyway } = await prompts7({
1905
+ type: "confirm",
1906
+ name: "continueAnyway",
1907
+ message: "Continue anyway?",
1908
+ initial: false
1909
+ });
1910
+ if (!continueAnyway) {
1911
+ console.log(pc8.gray("Cancelled."));
1912
+ process.exit(0);
1913
+ }
1914
+ }
1835
1915
  } else {
1836
- const { projectChoice } = await prompts7({
1837
- type: "select",
1838
- name: "projectChoice",
1839
- message: "Select a project:",
1840
- choices: projects.map((p) => ({ title: p.name, value: p.id }))
1916
+ console.log(pc8.yellow(`
1917
+ \u26A0\uFE0F No matching project found for ${repoFullName}`));
1918
+ console.log(pc8.gray("Select a project manually:\n"));
1919
+ selectedProject = await promptProjectSelection(projects, repoFullName);
1920
+ }
1921
+ }
1922
+ if (!options.project && !projectMatchesRepo(selectedProject, repoFullName)) {
1923
+ const autoMatch = findMatchingProject(projects, repoFullName);
1924
+ if (autoMatch && autoMatch.project.id !== selectedProject.id) {
1925
+ console.log("");
1926
+ console.log(pc8.yellow("\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\u2510"));
1927
+ console.log(pc8.yellow("\u2502 \u26A0\uFE0F WARNING: You selected a different project \u2502"));
1928
+ console.log(pc8.yellow("\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\u2518"));
1929
+ console.log(pc8.yellow(` Current repo: ${repoFullName}`));
1930
+ console.log(pc8.yellow(` Selected project: ${selectedProject.name}`));
1931
+ if (selectedProject.linkedRepo) {
1932
+ console.log(pc8.yellow(` Project linked to: ${selectedProject.linkedRepo}`));
1933
+ }
1934
+ console.log("");
1935
+ const { continueAnyway } = await prompts7({
1936
+ type: "confirm",
1937
+ name: "continueAnyway",
1938
+ message: "Are you sure you want to sync with this project?",
1939
+ initial: false
1841
1940
  });
1842
- if (!projectChoice) {
1941
+ if (!continueAnyway) {
1843
1942
  console.log(pc8.gray("Cancelled."));
1844
1943
  process.exit(0);
1845
1944
  }
1846
- selectedProject = projects.find((p) => p.id === projectChoice);
1847
1945
  }
1848
1946
  }
1849
1947
  const keywayEnv = options.environment || "production";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@keywaysh/cli",
3
- "version": "0.0.18",
3
+ "version": "0.0.20",
4
4
  "description": "One link to all your secrets",
5
5
  "type": "module",
6
6
  "bin": {