xtra-cli 0.1.10 → 0.2.3

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.

Potentially problematic release.


This version of xtra-cli might be problematic. Click here for more details.

@@ -41,178 +41,249 @@ const commander_1 = require("commander");
41
41
  const chalk_1 = __importDefault(require("chalk"));
42
42
  const readline = __importStar(require("readline"));
43
43
  const api_1 = require("../lib/api");
44
+ const config_1 = require("../lib/config");
44
45
  const ENVS = ["development", "staging", "production"];
45
- // ─── Rendering ────────────────────────────────────────────────────────────────
46
- function clear() { process.stdout.write("\x1Bc"); }
47
- function renderHeader() {
48
- console.log(chalk_1.default.cyan("╔═══════════════════════════════════════════════════════════╗"));
49
- console.log(chalk_1.default.cyan("║") + chalk_1.default.bold.cyan(" 🔒 XtraSecurity — Interactive Shell ") + chalk_1.default.cyan("║"));
50
- console.log(chalk_1.default.cyan("╚═══════════════════════════════════════════════════════════╝"));
51
- console.log(chalk_1.default.gray(" ↑↓ Navigate • Enter Select • Tab Switch Panel • Q Quit\n"));
52
- }
53
- function renderList(title, items, selectedIdx, active) {
54
- const border = active ? chalk_1.default.cyan : chalk_1.default.gray;
55
- console.log(border(`┌─ ${title} ${"".repeat(Math.max(0, 28 - title.length))}┐`));
56
- items.forEach((item, i) => {
57
- const isSelected = i === selectedIdx;
58
- const icon = isSelected ? (active ? chalk_1.default.cyan("▶ ") : chalk_1.default.gray("▶ ")) : " ";
59
- const text = isSelected && active ? chalk_1.default.bold.cyan(item) : isSelected ? chalk_1.default.cyan(item) : chalk_1.default.white(item);
60
- console.log(border("│") + ` ${icon}${text}`.padEnd(30) + border("│"));
61
- });
62
- console.log(border(`└${"─".repeat(32)}┘`));
63
- }
64
- function renderSecrets(secrets, selectedIdx, active) {
65
- const border = active ? chalk_1.default.cyan : chalk_1.default.gray;
66
- const COLS = [36, 12, 20];
67
- const sep = "─".repeat(COLS[0]) + "┬" + "─".repeat(COLS[1]) + "┬" + "─".repeat(COLS[2]);
68
- console.log(border(`┌${sep}┐`));
69
- const header = [
70
- chalk_1.default.bold.yellow("KEY".padEnd(COLS[0])),
71
- chalk_1.default.bold.yellow("VALUE".padEnd(COLS[1])),
72
- chalk_1.default.bold.yellow("UPDATED".padEnd(COLS[2]))
73
- ].join(border("│"));
74
- console.log(border("│") + header + border("│"));
75
- console.log(border(`├${sep}┤`));
76
- if (secrets.length === 0) {
77
- console.log(border("│") + chalk_1.default.gray(" No secrets found.".padEnd(COLS[0] + COLS[1] + COLS[2] + 2)) + border("│"));
78
- }
79
- else {
80
- secrets.forEach((s, i) => {
81
- const isSelected = i === selectedIdx;
82
- const fmt = (t, w) => {
83
- const str = t.length > w - 2 ? t.slice(0, w - 5) + "..." : t;
84
- return isSelected && active ? chalk_1.default.bold.bgCyan.black(str.padEnd(w)) : isSelected ? chalk_1.default.cyan(str.padEnd(w)) : str.padEnd(w);
85
- };
86
- const row = [
87
- fmt(s.key, COLS[0]),
88
- fmt("*".repeat(8), COLS[1]),
89
- fmt(new Date(s.updatedAt).toLocaleDateString(), COLS[2]),
90
- ].join(border("│"));
91
- console.log(border("│") + row + border("│"));
92
- });
93
- }
94
- console.log(border(`└${"─".repeat(COLS[0])}┴${"─".repeat(COLS[1])}┴${"─".repeat(COLS[2])}┘`));
95
- }
96
- function renderStatus(msg) {
97
- console.log("\n" + chalk_1.default.gray(" ● ") + chalk_1.default.white(msg));
46
+ const ENV_COLORS = {
47
+ development: chalk_1.default.green,
48
+ staging: chalk_1.default.yellow,
49
+ production: chalk_1.default.red,
50
+ };
51
+ const W = process.stdout.columns || 120;
52
+ // ─── Box Drawing Helpers ─────────────────────────────────────────────────────
53
+ const B = {
54
+ tl: "╭", tr: "╮", bl: "╰", br: "╯",
55
+ h: "─", v: "│", x: "┼",
56
+ lt: "├", rt: "", tt: "┬", bt: "┴",
57
+ };
58
+ function hline(width, c = B.h) { return c.repeat(width); }
59
+ function box(title, lines, width, active) {
60
+ const border = active ? chalk_1.default.cyan : chalk_1.default.hex("#2d3a4d");
61
+ const inner = width - 2;
62
+ const pad = (s) => s.padEnd(inner).slice(0, inner);
63
+ const label = active
64
+ ? chalk_1.default.bold.cyan(` ${title} `)
65
+ : chalk_1.default.hex("#4a5568")(` ${title} `);
66
+ const titleLine = border(B.tl) + label + border(hline(inner - title.length - 2)) + border(B.tr);
67
+ const body = lines.map(l => border(B.v) + l.slice(0, inner).padEnd(inner) + border(B.v));
68
+ const foot = border(B.bl) + border(hline(inner)) + border(B.br);
69
+ return [titleLine, ...body, foot];
98
70
  }
99
- // ─── Main TUI Loop ────────────────────────────────────────────────────────────
71
+ function clear() { process.stdout.write("\x1B[H\x1B[2J\x1B[3J"); }
72
+ // ─── Main TUI ────────────────────────────────────────────────────────────────
100
73
  async function runUI() {
101
- let screen = "project";
74
+ let panel = "projects";
102
75
  let projects = [];
103
- let projectIdx = 0;
76
+ let projIdx = 0;
104
77
  let envIdx = 0;
105
78
  let secrets = [];
106
- let secretIdx = 0;
107
- let status = "Loading projects...";
79
+ let secIdx = 0;
80
+ let status = "Loading";
108
81
  let loading = false;
82
+ let showValues = false;
83
+ // ── Loaders ────────────────────────────────────────────────────────────────
109
84
  async function loadProjects() {
85
+ status = "Loading projects…";
86
+ draw();
110
87
  try {
111
- projects = await api_1.api.getProjects();
88
+ const raw = await api_1.api.getProjects();
89
+ projects = Array.isArray(raw) ? raw : raw.projects ?? [];
112
90
  status = projects.length > 0
113
- ? `Loaded ${projects.length} projects. Use ↑↓ and Enter to navigate.`
114
- : "No projects found. Try running `xtra login`.";
91
+ ? `${projects.length} project(s) found · ↑↓ navigate · Enter to load secrets`
92
+ : "No projects found. Run `xtra login` first.";
115
93
  }
116
94
  catch (e) {
117
- status = chalk_1.default.red(`Error: ${e.message}`);
95
+ status = chalk_1.default.red(`✗ ${e.message}`);
118
96
  }
119
97
  draw();
120
98
  }
121
99
  async function loadSecrets() {
122
- if (!projects[projectIdx])
100
+ if (!projects[projIdx])
123
101
  return;
124
102
  loading = true;
125
- status = `Fetching secrets for ${projects[projectIdx].name}/${ENVS[envIdx]}...`;
103
+ status = `Fetching secrets for ${chalk_1.default.cyan(projects[projIdx].name)} / ${ENV_COLORS[ENVS[envIdx]](ENVS[envIdx])}…`;
126
104
  draw();
127
105
  try {
128
- secrets = await api_1.api.getSecrets(projects[projectIdx].id, ENVS[envIdx]);
129
- secretIdx = 0;
130
- status = `${secrets.length} secret(s) loaded. Tab to switch panel, Q to quit.`;
106
+ const rc = (0, config_1.getRcConfig)();
107
+ const branch = rc.branch || "main";
108
+ const raw = await api_1.api.getSecrets(projects[projIdx].id, ENVS[envIdx], branch);
109
+ if (raw && typeof raw === "object" && !Array.isArray(raw)) {
110
+ secrets = Object.entries(raw).map(([key, value]) => ({
111
+ id: key, key, value: String(value), updatedAt: new Date().toISOString(),
112
+ }));
113
+ }
114
+ else if (Array.isArray(raw)) {
115
+ secrets = raw;
116
+ }
117
+ else {
118
+ secrets = [];
119
+ }
120
+ secIdx = 0;
121
+ status = secrets.length > 0
122
+ ? `${secrets.length} secret(s) · V toggle values · Tab switch panel · Q quit`
123
+ : "No secrets in this environment.";
131
124
  }
132
125
  catch (e) {
133
126
  secrets = [];
134
- status = chalk_1.default.red(`Error: ${e.message}`);
127
+ status = chalk_1.default.red(`✗ ${e.message}`);
135
128
  }
136
129
  loading = false;
137
130
  draw();
138
131
  }
132
+ // ── Render ─────────────────────────────────────────────────────────────────
139
133
  function draw() {
140
134
  clear();
141
- renderHeader();
142
- const projectNames = projects.map(p => p.name);
143
- renderList("PROJECTS", projectNames.length ? projectNames : ["(loading...)"], projectIdx, screen === "project");
135
+ // ── Header ──────────────────────────────────────────────────────────────
136
+ const appTitle = chalk_1.default.bold.cyan(" 🔒 XtraSecurity") + chalk_1.default.hex("#4a5a6b")(" — Interactive Secrets Shell");
137
+ const env = ENV_COLORS[ENVS[envIdx]] ? ENV_COLORS[ENVS[envIdx]](ENVS[envIdx]) : chalk_1.default.white(ENVS[envIdx]);
138
+ const crumb = projects[projIdx]
139
+ ? chalk_1.default.hex("#4a5568")(` ${projects[projIdx].name} `) + chalk_1.default.hex("#4a5568")("/") + chalk_1.default.hex("#4a5568")(` ${ENVS[envIdx]}`)
140
+ : chalk_1.default.hex("#4a5568")(" No project selected");
144
141
  console.log();
145
- renderList("ENVIRONMENT", ENVS, envIdx, screen === "env");
142
+ console.log(appTitle + chalk_1.default.hex("#2d3a4d")(" │") + crumb);
143
+ console.log(chalk_1.default.hex("#1e293b")(hline(W)));
146
144
  console.log();
145
+ // ── Left column: Projects (22 chr) + Env (22 chr) ─────────────────────
146
+ const LEFT_W = 26;
147
+ const RIGHT_W = W - LEFT_W - 3;
148
+ // Projects panel
149
+ const projLines = (projects.length > 0 ? projects : [{ id: "", name: "(loading…)" }]).map((p, i) => {
150
+ const active = i === projIdx;
151
+ const icon = active ? chalk_1.default.cyan("▶ ") : " ";
152
+ const name = active && panel === "projects"
153
+ ? chalk_1.default.bold.bgCyan.black(` ${p.name} `.padEnd(LEFT_W - 4))
154
+ : active
155
+ ? chalk_1.default.bold.cyan(p.name)
156
+ : chalk_1.default.hex("#6b7c93")(p.name);
157
+ return ` ${icon}${name}`;
158
+ });
159
+ const projBox = box("PROJECTS", projLines, LEFT_W, panel === "projects");
160
+ // Env panel
161
+ const envLines = ENVS.map((e, i) => {
162
+ const active = i === envIdx;
163
+ const icon = active ? chalk_1.default.cyan("▶ ") : " ";
164
+ const col = ENV_COLORS[e] ?? chalk_1.default.white;
165
+ const name = active && panel === "env"
166
+ ? chalk_1.default.bold.bgCyan.black(` ${e} `.padEnd(LEFT_W - 4))
167
+ : active
168
+ ? col.bold(e)
169
+ : chalk_1.default.hex("#6b7c93")(e);
170
+ return ` ${icon}${name}`;
171
+ });
172
+ const envBox = box("ENVIRONMENT", envLines, LEFT_W, panel === "env");
173
+ // Secrets panel
174
+ const KW = Math.floor((RIGHT_W - 3) * 0.45);
175
+ const VW = Math.floor((RIGHT_W - 3) * 0.35);
176
+ const DW = RIGHT_W - KW - VW - 4;
177
+ const secHeader = chalk_1.default.bold.hex("#64748b")("KEY".padEnd(KW)) + " " + chalk_1.default.bold.hex("#64748b")("VALUE".padEnd(VW)) + " " + chalk_1.default.bold.hex("#64748b")("UPDATED".padEnd(DW));
178
+ const divider = chalk_1.default.hex("#1e293b")(hline(KW) + " " + hline(VW) + " " + hline(DW));
179
+ let secLines;
147
180
  if (loading) {
148
- console.log(chalk_1.default.cyan(" ⠋ Loading secrets..."));
181
+ secLines = [` ${chalk_1.default.cyan("⠋")} Loading…`];
182
+ }
183
+ else if (secrets.length === 0) {
184
+ secLines = [` ${chalk_1.default.hex("#4a5568")("No secrets in this environment.")}`];
149
185
  }
150
186
  else {
151
- renderSecrets(secrets, secretIdx, screen === "secrets");
187
+ secLines = [" " + secHeader, " " + divider, ...secrets.map((s, i) => {
188
+ const sel = i === secIdx && panel === "secrets";
189
+ const key = s.key.padEnd(KW).slice(0, KW);
190
+ const val = showValues ? s.value.padEnd(VW).slice(0, VW) : "●".repeat(Math.min(8, VW)).padEnd(VW).slice(0, VW);
191
+ const dt = new Date(s.updatedAt).toLocaleDateString("en-GB", { day: "2-digit", month: "short" }).padEnd(DW);
192
+ if (sel) {
193
+ return chalk_1.default.bold.bgHex("#0e243e")(" ▶ " + chalk_1.default.cyan(key) + " " + chalk_1.default.greenBright(val) + " " + chalk_1.default.hex("#4a9eff")(dt) + " ");
194
+ }
195
+ return " " + chalk_1.default.white(key) + " " + chalk_1.default.hex("#4a5568")(val) + " " + chalk_1.default.hex("#374151")(dt);
196
+ })];
197
+ }
198
+ const secBox = box(`SECRETS (${secrets.length})`, secLines, RIGHT_W, panel === "secrets");
199
+ // ── Print side-by-side ────────────────────────────────────────────────
200
+ const leftPanel = [...projBox, ...["", ""], ...envBox];
201
+ const maxRows = Math.max(leftPanel.length, secBox.length);
202
+ const gap = chalk_1.default.hex("#1e293b")(" │ ");
203
+ for (let r = 0; r < maxRows; r++) {
204
+ const l = leftPanel[r] ?? " ".repeat(LEFT_W);
205
+ const rr = secBox[r] ?? " ".repeat(RIGHT_W);
206
+ console.log(l + gap + rr);
152
207
  }
153
- renderStatus(status);
208
+ // ── Footer ───────────────────────────────────────────────────────────
209
+ console.log();
210
+ console.log(chalk_1.default.hex("#1e293b")(hline(W)));
211
+ const keys = [
212
+ [chalk_1.default.hex("#64748b")("↑↓"), "Navigate"],
213
+ [chalk_1.default.hex("#64748b")("Enter"), "Select"],
214
+ [chalk_1.default.hex("#64748b")("Tab"), "Switch Panel"],
215
+ [chalk_1.default.hex("#64748b")("V"), showValues ? chalk_1.default.green("Hide values") : chalk_1.default.yellow("Show values")],
216
+ [chalk_1.default.hex("#64748b")("Q"), "Quit"],
217
+ ].map(([k, a]) => `${k} ${chalk_1.default.hex("#374151")(a)}`).join(chalk_1.default.hex("#1e293b")(" · "));
218
+ console.log(" " + keys);
219
+ console.log();
220
+ console.log(" " + (status || ""));
154
221
  }
155
- // Set up raw mode for keyboard input
222
+ // ── Keyboard ──────────────────────────────────────────────────────────────
156
223
  readline.emitKeypressEvents(process.stdin);
157
224
  if (process.stdin.isTTY)
158
225
  process.stdin.setRawMode(true);
159
- process.stdin.on("keypress", async (str, key) => {
226
+ process.stdin.on("keypress", async (_str, key) => {
160
227
  if (!key)
161
228
  return;
162
229
  // Quit
163
- if (str === "q" || str === "Q" || (key.ctrl && key.name === "c")) {
230
+ if (key.name === "q" || (key.ctrl && key.name === "c")) {
164
231
  if (process.stdin.isTTY)
165
232
  process.stdin.setRawMode(false);
166
233
  clear();
167
- console.log(chalk_1.default.cyan("Goodbye! 👋"));
234
+ console.log(chalk_1.default.cyan(" Goodbye! 👋\n"));
168
235
  process.exit(0);
169
236
  }
170
- // Tab to cycle panels
237
+ // Toggle secret values with V
238
+ if (key.name === "v") {
239
+ showValues = !showValues;
240
+ draw();
241
+ return;
242
+ }
243
+ // Tab cycle panels
171
244
  if (key.name === "tab") {
172
- screen = screen === "project" ? "env" : screen === "env" ? "secrets" : "project";
245
+ panel = panel === "projects" ? "env" : panel === "env" ? "secrets" : "projects";
173
246
  draw();
174
247
  return;
175
248
  }
176
- // Navigation based on active panel
177
- if (screen === "project") {
249
+ if (panel === "projects") {
178
250
  if (key.name === "up")
179
- projectIdx = Math.max(0, projectIdx - 1);
251
+ projIdx = Math.max(0, projIdx - 1);
180
252
  if (key.name === "down")
181
- projectIdx = Math.min(projects.length - 1, projectIdx + 1);
253
+ projIdx = Math.min(projects.length - 1, projIdx + 1);
182
254
  if (key.name === "return") {
183
- screen = "env";
184
- await loadSecrets();
255
+ panel = "env";
256
+ draw();
185
257
  return;
186
258
  }
187
259
  }
188
- if (screen === "env") {
260
+ if (panel === "env") {
189
261
  if (key.name === "up")
190
262
  envIdx = Math.max(0, envIdx - 1);
191
263
  if (key.name === "down")
192
264
  envIdx = Math.min(ENVS.length - 1, envIdx + 1);
193
265
  if (key.name === "return") {
194
- screen = "secrets";
266
+ panel = "secrets";
195
267
  await loadSecrets();
196
268
  return;
197
269
  }
198
270
  }
199
- if (screen === "secrets") {
271
+ if (panel === "secrets") {
200
272
  if (key.name === "up")
201
- secretIdx = Math.max(0, secretIdx - 1);
273
+ secIdx = Math.max(0, secIdx - 1);
202
274
  if (key.name === "down")
203
- secretIdx = Math.min(secrets.length - 1, secretIdx + 1);
275
+ secIdx = Math.min(secrets.length - 1, secIdx + 1);
204
276
  }
205
277
  draw();
206
278
  });
279
+ // ── Boot ──────────────────────────────────────────────────────────────────
207
280
  await loadProjects();
208
281
  if (projects.length > 0)
209
282
  await loadSecrets();
210
283
  else
211
284
  draw();
212
285
  }
213
- // ─── Commander Command ────────────────────────────────────────────────────────
286
+ // ─── Commander ───────────────────────────────────────────────────────────────
214
287
  exports.uiCommand = new commander_1.Command("ui")
215
- .description("Launch interactive TUI secrets dashboard (arrow keys to navigate, Q to quit)")
216
- .action(async () => {
217
- await runUI();
218
- });
288
+ .description("Launch interactive TUI secrets dashboard (arrow keys, Tab, Q to quit)")
289
+ .action(async () => { await runUI(); });
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.watchCommand = void 0;
7
7
  /**
8
- * watch.ts Live reload secrets in dev mode
8
+ * watch.ts — Live reload secrets in dev mode
9
9
  *
10
10
  * Polls XtraSecurity Cloud for secret changes at a configurable interval.
11
11
  * When a change is detected, restarts the child process with fresh secrets.
@@ -26,7 +26,7 @@ function hashSecrets(secrets) {
26
26
  }
27
27
  async function startProcess(command, args, secrets, useShell) {
28
28
  if (child) {
29
- process.stdout.write(chalk_1.default.yellow("\n [watch] Secret change detected restarting...\n"));
29
+ process.stdout.write(chalk_1.default.yellow("\n [watch] Secret change detected — restarting...\n"));
30
30
  child.kill("SIGTERM");
31
31
  // Give it 500ms to terminate gracefully
32
32
  await new Promise(r => setTimeout(r, 500));
@@ -50,7 +50,7 @@ async function startProcess(command, args, secrets, useShell) {
50
50
  });
51
51
  }
52
52
  exports.watchCommand = new commander_1.Command("watch")
53
- .description("Live reload auto-restart process when secrets change in cloud")
53
+ .description("Live reload — auto-restart process when secrets change in cloud")
54
54
  .option("-p, --project <id>", "Project ID")
55
55
  .option("-e, --env <environment>", "Environment", "development")
56
56
  .option("-b, --branch <branch>", "Branch", "main")
@@ -69,19 +69,19 @@ Examples:
69
69
  const envMap = { dev: "development", stg: "staging", prod: "production" };
70
70
  env = envMap[env] || env;
71
71
  if (!project)
72
- project = (0, config_1.getConfigValue)("project");
72
+ project = (0, config_1.getRcConfig)().project;
73
73
  if (!project) {
74
74
  console.error(chalk_1.default.red("Error: Project ID required. Use -p <id> or run 'xtra project set'."));
75
75
  process.exit(1);
76
76
  }
77
- // Block production watch too dangerous
77
+ // Block production watch — too dangerous
78
78
  if (env === "production") {
79
- console.error(chalk_1.default.red("xtra watch is not allowed in PRODUCTION for safety reasons."));
79
+ console.error(chalk_1.default.red("âš  xtra watch is not allowed in PRODUCTION for safety reasons."));
80
80
  console.error(chalk_1.default.gray(" Use xtra run for one-shot production injection."));
81
81
  process.exit(1);
82
82
  }
83
83
  const pollMs = Math.max(3, parseInt(interval)) * 1000;
84
- console.log(chalk_1.default.bold(`\n👁 xtra watch watching ${env}/${branch} (every ${interval}s)\n`));
84
+ console.log(chalk_1.default.bold(`\n👁 xtra watch — watching ${env}/${branch} (every ${interval}s)\n`));
85
85
  console.log(chalk_1.default.gray(` Press Ctrl+C to stop.\n`));
86
86
  // Graceful shutdown
87
87
  process.on("SIGINT", () => {
@@ -110,12 +110,12 @@ Examples:
110
110
  await startProcess(command, args, secrets, useShell);
111
111
  }
112
112
  else {
113
- process.stdout.write(chalk_1.default.gray(` [watch] ${new Date().toLocaleTimeString()} no changes\r`));
113
+ process.stdout.write(chalk_1.default.gray(` [watch] ${new Date().toLocaleTimeString()} — no changes\r`));
114
114
  }
115
115
  }
116
116
  catch (e) {
117
117
  process.stdout.write(chalk_1.default.yellow(`\n [watch] Poll failed: ${e.message}\n`));
118
- // Don't exit keep trying
118
+ // Don't exit — keep trying
119
119
  }
120
120
  }, pollMs);
121
121
  });
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getProjectConfig = exports.getAuthToken = exports.clearConfig = exports.setConfig = exports.getConfigValue = exports.getConfig = void 0;
6
+ exports.getRcConfig = exports.getProjectConfig = exports.getAuthToken = exports.clearConfig = exports.setConfig = exports.getConfigValue = exports.getConfig = void 0;
7
7
  const conf_1 = __importDefault(require("conf"));
8
8
  const PRODUCTION_API_URL = "https://xtra-security.vercel.app/api";
9
9
  const config = new conf_1.default({
@@ -47,3 +47,24 @@ const getProjectConfig = async () => {
47
47
  }
48
48
  };
49
49
  exports.getProjectConfig = getProjectConfig;
50
+ /**
51
+ * Reads .xtrarc from the current working directory.
52
+ * Returns project/env/branch with fallback to the global conf store.
53
+ * All commands should use this instead of calling getConfigValue() directly.
54
+ */
55
+ const getRcConfig = () => {
56
+ let rc = {};
57
+ try {
58
+ const rcPath = path_1.default.join(process.cwd(), ".xtrarc");
59
+ if (fs_1.default.existsSync(rcPath)) {
60
+ rc = JSON.parse(fs_1.default.readFileSync(rcPath, "utf-8"));
61
+ }
62
+ }
63
+ catch (_) { }
64
+ return {
65
+ project: rc.project || config.get("project") || "",
66
+ env: rc.env || config.get("env") || "development",
67
+ branch: rc.branch || config.get("branch") || "main",
68
+ };
69
+ };
70
+ exports.getRcConfig = getRcConfig;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xtra-cli",
3
- "version": "0.1.10",
3
+ "version": "0.2.3",
4
4
  "description": "CLI for XtraSecurity Platform",
5
5
  "main": "dist/index.js",
6
6
  "bin": {