@trendify/cli 0.1.6 → 0.1.7

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/app.d.ts CHANGED
@@ -1,6 +1,14 @@
1
+ import { type CliUpdateCheckResult } from './cli-update-service.js';
1
2
  export type AppProps = {
2
3
  readonly appVersion: string;
3
4
  readonly initialInput: string;
5
+ readonly initialNotification?: string | null;
6
+ readonly initialNotificationTone?: NotificationTone;
7
+ readonly onSelfUpdate: (update: Extract<CliUpdateCheckResult, {
8
+ status: 'available';
9
+ }>) => void | Promise<void>;
4
10
  };
5
- export declare function App({ appVersion, initialInput }: AppProps): import("react/jsx-runtime").JSX.Element;
11
+ type NotificationTone = 'error' | 'info' | 'success';
12
+ export declare function App({ appVersion, initialInput, initialNotification, initialNotificationTone, onSelfUpdate, }: AppProps): import("react/jsx-runtime").JSX.Element;
13
+ export {};
6
14
  //# sourceMappingURL=app.d.ts.map
package/dist/app.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.tsx"],"names":[],"mappings":"AAiBA,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B,CAAC;AAkHF,wBAAgB,GAAG,CAAC,EAAE,UAAU,EAAE,YAAY,EAAE,EAAE,QAAQ,2CA+czD"}
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.tsx"],"names":[],"mappings":"AAYA,OAAO,EAAqB,KAAK,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAMvF,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7C,QAAQ,CAAC,uBAAuB,CAAC,EAAE,gBAAgB,CAAC;IACpD,QAAQ,CAAC,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,oBAAoB,EAAE;QAAE,MAAM,EAAE,WAAW,CAAA;KAAE,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjH,CAAC;AA6DF,KAAK,gBAAgB,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;AAyFrD,wBAAgB,GAAG,CAAC,EAClB,UAAU,EACV,YAAY,EACZ,mBAA0B,EAC1B,uBAAmC,EACnC,YAAY,GACb,EAAE,QAAQ,2CAmfV"}
package/dist/app.js CHANGED
@@ -6,6 +6,7 @@ import { getUserDisplayName } from './modules/auth/auth-user.js';
6
6
  import { getAuthBootstrapResult, } from './modules/auth/auth-service.js';
7
7
  import { LoginPage } from './modules/auth/page/login-page.js';
8
8
  import { ProfilePage } from './modules/profile/page/profile-page.js';
9
+ import { checkForCliUpdate } from './cli-update-service.js';
9
10
  import { ActionMenuPage } from './shared/components/action-menu-page.js';
10
11
  import { AppMenu } from './shared/template/app-menu.js';
11
12
  import { AppShell } from './shared/template/app-shell.js';
@@ -105,14 +106,46 @@ function getWelcomeTitle(user) {
105
106
  }
106
107
  return 'Bem-vindo de volta. 👋';
107
108
  }
108
- export function App({ appVersion, initialInput }) {
109
+ function buildMenuItems(cliUpdate) {
110
+ if (cliUpdate.status !== 'available') {
111
+ return MENU_ITEMS;
112
+ }
113
+ const [discoveryItem, profileItem, logoutItem, exitItem] = MENU_ITEMS;
114
+ if (!discoveryItem || !profileItem || !logoutItem || !exitItem) {
115
+ return MENU_ITEMS;
116
+ }
117
+ return [
118
+ discoveryItem,
119
+ profileItem,
120
+ {
121
+ id: 'update-cli',
122
+ titulo: `Atualizar CLI para v${cliUpdate.latestVersion}`,
123
+ comando: 'atualizar-cli',
124
+ aliases: ['update', 'upgrade', 'atualizar', 'atualizar-cli', 'Atualizar CLI'],
125
+ descricao: `Instala a versao ${cliUpdate.latestVersion} do CLI e reinicia a aplicacao.`,
126
+ palavrasChave: [
127
+ 'versao',
128
+ 'nova versao',
129
+ 'ultima versao',
130
+ 'npm',
131
+ 'upgrade',
132
+ 'update',
133
+ 'atualizacao',
134
+ 'atualizar',
135
+ ],
136
+ },
137
+ logoutItem,
138
+ exitItem,
139
+ ];
140
+ }
141
+ export function App({ appVersion, initialInput, initialNotification = null, initialNotificationTone = 'success', onSelfUpdate, }) {
109
142
  const { exit } = useApp();
110
143
  const authBootstrap = useMemo(() => getAuthBootstrapResult(), []);
111
144
  const authService = authBootstrap.ok ? authBootstrap.authService : null;
112
145
  const sessionStorageFilePath = authService?.getSessionStorageFilePath() ?? '~/.trendify/auth/storage.json';
113
146
  const [screen, setScreen] = useState('menu');
114
- const [notification, setNotification] = useState(null);
115
- const [notificationTone, setNotificationTone] = useState('success');
147
+ const [notification, setNotification] = useState(initialNotification);
148
+ const [notificationTone, setNotificationTone] = useState(initialNotificationTone);
116
149
  const [menuKey, setMenuKey] = useState(0);
117
150
  const [authStatus, setAuthStatus] = useState(authBootstrap.ok ? 'booting' : 'config-error');
118
151
  const [authUser, setAuthUser] = useState(null);
@@ -123,6 +156,12 @@ export function App({ appVersion, initialInput }) {
123
156
  const [authBusy, setAuthBusy] = useState(false);
124
157
  const [logoutSelectionIndex, setLogoutSelectionIndex] = useState(0);
125
158
  const [workspaceSelectionIndex, setWorkspaceSelectionIndex] = useState(0);
159
+ const [cliUpdate, setCliUpdate] = useState({
160
+ currentVersion: appVersion,
161
+ packageName: '@trendify/cli',
162
+ status: 'checking',
163
+ });
164
+ const menuItems = useMemo(() => buildMenuItems(cliUpdate), [cliUpdate]);
126
165
  function resetAuthenticatedContext() {
127
166
  setAuthUser(null);
128
167
  setAvailableWorkspaces([]);
@@ -199,6 +238,20 @@ export function App({ appVersion, initialInput }) {
199
238
  void handleWorkspaceSelection();
200
239
  }
201
240
  });
241
+ useEffect(() => {
242
+ let active = true;
243
+ const checkUpdates = async () => {
244
+ const result = await checkForCliUpdate(appVersion);
245
+ if (!active) {
246
+ return;
247
+ }
248
+ setCliUpdate(result);
249
+ };
250
+ void checkUpdates();
251
+ return () => {
252
+ active = false;
253
+ };
254
+ }, [appVersion]);
202
255
  useEffect(() => {
203
256
  if (!authService) {
204
257
  return;
@@ -362,30 +415,34 @@ export function App({ appVersion, initialInput }) {
362
415
  if (screen === 'confirm-logout') {
363
416
  return (_jsx(AppShell, { appVersion: appVersion, title: "Confirmar encerramento de sessao", subtitle: `Voce esta autenticado como ${getAuthenticatedUserLabel(authUser)} em ${getActiveWorkspaceLabel(activeWorkspace)}.`, notification: notification, notificationTone: notificationTone, children: _jsx(ActionMenuPage, { title: "Tem certeza que deseja encerrar a sessao atual?", subtitle: "Se confirmar, a CLI vai remover a sessao salva localmente e pedir login novamente.", options: LOGOUT_OPTIONS, selectedIndex: logoutSelectionIndex, hintText: "Use as setas para navegar. Enter confirma. Esc volta ao menu." }) }));
364
417
  }
365
- return (_jsx(AppShell, { appVersion: appVersion, title: getWelcomeTitle(authUser), subtitle: `Workspace: ${getActiveWorkspaceLabel(activeWorkspace)}\n\nUse a barra para abrir os comandos.`, notification: notification, notificationTone: notificationTone, children: _jsx(AppMenu, { initialInput: menuKey === 0 ? initialInput : '', items: MENU_ITEMS, onInputChange: () => {
366
- if (notification) {
367
- setNotification(null);
368
- }
369
- }, onSelect: (item) => {
370
- if (item.id === 'logout') {
371
- setNotification(null);
372
- setNotificationTone('info');
373
- setLogoutSelectionIndex(0);
374
- setScreen('confirm-logout');
375
- return;
376
- }
377
- if (item.id === 'profile') {
418
+ return (_jsxs(AppShell, { appVersion: appVersion, title: getWelcomeTitle(authUser), subtitle: `Workspace: ${getActiveWorkspaceLabel(activeWorkspace)}\n\nUse a barra para abrir os comandos.`, notification: notification, notificationTone: notificationTone, children: [cliUpdate.status === 'available' ? (_jsxs(Text, { color: "yellowBright", children: ["Nova versao disponivel: v", cliUpdate.latestVersion, ". Abra o menu com / e escolha \"Atualizar CLI\"."] })) : null, _jsx(AppMenu, { initialInput: menuKey === 0 ? initialInput : '', items: menuItems, onInputChange: () => {
419
+ if (notification) {
420
+ setNotification(null);
421
+ }
422
+ }, onSelect: (item) => {
423
+ if (item.id === 'update-cli' && cliUpdate.status === 'available') {
424
+ void onSelfUpdate(cliUpdate);
425
+ return;
426
+ }
427
+ if (item.id === 'logout') {
428
+ setNotification(null);
429
+ setNotificationTone('info');
430
+ setLogoutSelectionIndex(0);
431
+ setScreen('confirm-logout');
432
+ return;
433
+ }
434
+ if (item.id === 'profile') {
435
+ setNotification(null);
436
+ setNotificationTone('success');
437
+ setScreen('profile');
438
+ return;
439
+ }
440
+ if (item.id === 'exit') {
441
+ exit();
442
+ return;
443
+ }
378
444
  setNotification(null);
379
445
  setNotificationTone('success');
380
- setScreen('profile');
381
- return;
382
- }
383
- if (item.id === 'exit') {
384
- exit();
385
- return;
386
- }
387
- setNotification(null);
388
- setNotificationTone('success');
389
- setScreen('discovery');
390
- } }, menuKey) }));
446
+ setScreen('discovery');
447
+ } }, menuKey)] }));
391
448
  }
@@ -0,0 +1,29 @@
1
+ export type CliUpdateCheckResult = {
2
+ readonly currentVersion: string;
3
+ readonly packageName: string;
4
+ readonly status: 'checking';
5
+ } | {
6
+ readonly currentVersion: string;
7
+ readonly latestVersion: string;
8
+ readonly packageName: string;
9
+ readonly status: 'available';
10
+ } | {
11
+ readonly currentVersion: string;
12
+ readonly latestVersion: string;
13
+ readonly packageName: string;
14
+ readonly status: 'current';
15
+ } | {
16
+ readonly currentVersion: string;
17
+ readonly message: string;
18
+ readonly packageName: string;
19
+ readonly status: 'error';
20
+ };
21
+ export type CliSelfUpdateResult = {
22
+ readonly ok: true;
23
+ } | {
24
+ readonly error: string;
25
+ readonly ok: false;
26
+ };
27
+ export declare function checkForCliUpdate(currentVersion: string): Promise<CliUpdateCheckResult>;
28
+ export declare function runCliSelfUpdate(packageName: string, latestVersion: string): Promise<CliSelfUpdateResult>;
29
+ //# sourceMappingURL=cli-update-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-update-service.d.ts","sourceRoot":"","sources":["../src/cli-update-service.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,oBAAoB,GAC5B;IACE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;CAC7B,GACD;IACE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC9B,GACD;IACE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;CAC5B,GACD;IACE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEN,MAAM,MAAM,mBAAmB,GAC3B;IACE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;CACnB,GACD;IACE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;CACpB,CAAC;AA4MN,wBAAsB,iBAAiB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA6B7F;AAED,wBAAsB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAwB/G"}
@@ -0,0 +1,206 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { spawn } from 'node:child_process';
3
+ const DEFAULT_PACKAGE_NAME = '@trendify/cli';
4
+ const VERSION_PATTERN = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?$/u;
5
+ function getPackageManifestPath() {
6
+ return new URL('../package.json', import.meta.url);
7
+ }
8
+ function getNpmCommand() {
9
+ return process.platform === 'win32' ? 'npm.cmd' : 'npm';
10
+ }
11
+ function toErrorMessage(error) {
12
+ if (error instanceof Error && error.message.trim()) {
13
+ return error.message;
14
+ }
15
+ return 'Nao foi possivel concluir a operacao.';
16
+ }
17
+ function readInstalledPackageMetadata() {
18
+ try {
19
+ const manifestContents = readFileSync(getPackageManifestPath(), 'utf8');
20
+ const manifest = JSON.parse(manifestContents);
21
+ const packageName = typeof manifest.name === 'string' && manifest.name.trim().length > 0
22
+ ? manifest.name.trim()
23
+ : DEFAULT_PACKAGE_NAME;
24
+ return { packageName };
25
+ }
26
+ catch {
27
+ return { packageName: DEFAULT_PACKAGE_NAME };
28
+ }
29
+ }
30
+ function parseVersion(version) {
31
+ const match = VERSION_PATTERN.exec(version.trim());
32
+ if (!match) {
33
+ return null;
34
+ }
35
+ const [, major, minor, patch, prerelease] = match;
36
+ if (!major || !minor || !patch) {
37
+ return null;
38
+ }
39
+ return {
40
+ major: Number.parseInt(major, 10),
41
+ minor: Number.parseInt(minor, 10),
42
+ patch: Number.parseInt(patch, 10),
43
+ prerelease: prerelease ?? null,
44
+ };
45
+ }
46
+ function compareVersions(left, right) {
47
+ const parsedLeft = parseVersion(left);
48
+ const parsedRight = parseVersion(right);
49
+ if (!parsedLeft || !parsedRight) {
50
+ return left.localeCompare(right, undefined, { numeric: true, sensitivity: 'base' });
51
+ }
52
+ if (parsedLeft.major !== parsedRight.major) {
53
+ return parsedLeft.major - parsedRight.major;
54
+ }
55
+ if (parsedLeft.minor !== parsedRight.minor) {
56
+ return parsedLeft.minor - parsedRight.minor;
57
+ }
58
+ if (parsedLeft.patch !== parsedRight.patch) {
59
+ return parsedLeft.patch - parsedRight.patch;
60
+ }
61
+ if (parsedLeft.prerelease === parsedRight.prerelease) {
62
+ return 0;
63
+ }
64
+ if (parsedLeft.prerelease === null) {
65
+ return 1;
66
+ }
67
+ if (parsedRight.prerelease === null) {
68
+ return -1;
69
+ }
70
+ return parsedLeft.prerelease.localeCompare(parsedRight.prerelease, undefined, {
71
+ numeric: true,
72
+ sensitivity: 'base',
73
+ });
74
+ }
75
+ function runCommand(command, args) {
76
+ return new Promise((resolve, reject) => {
77
+ const child = spawn(command, [...args], {
78
+ env: process.env,
79
+ stdio: ['ignore', 'pipe', 'pipe'],
80
+ });
81
+ let stdout = '';
82
+ let stderr = '';
83
+ child.stdout.on('data', (chunk) => {
84
+ stdout += chunk.toString();
85
+ });
86
+ child.stderr.on('data', (chunk) => {
87
+ stderr += chunk.toString();
88
+ });
89
+ child.on('error', (error) => {
90
+ reject(error);
91
+ });
92
+ child.on('close', (code) => {
93
+ resolve({
94
+ code: code ?? 1,
95
+ stderr,
96
+ stdout,
97
+ });
98
+ });
99
+ });
100
+ }
101
+ async function fetchLatestPublishedVersion(packageName) {
102
+ const commandResult = await runCommand(getNpmCommand(), ['view', packageName, 'version', '--json', '--silent']);
103
+ if (commandResult.code !== 0) {
104
+ const message = commandResult.stderr.trim() || commandResult.stdout.trim() || 'Falha ao consultar o npm.';
105
+ throw new Error(message);
106
+ }
107
+ const stdout = commandResult.stdout.trim();
108
+ if (!stdout) {
109
+ throw new Error('O npm nao retornou a versao publicada mais recente.');
110
+ }
111
+ try {
112
+ const parsedOutput = JSON.parse(stdout);
113
+ if (typeof parsedOutput === 'string' && parsedOutput.trim()) {
114
+ return parsedOutput.trim();
115
+ }
116
+ }
117
+ catch {
118
+ if (stdout) {
119
+ return stdout.replace(/^"+|"+$/gu, '').trim();
120
+ }
121
+ }
122
+ throw new Error('Nao foi possivel interpretar a versao publicada retornada pelo npm.');
123
+ }
124
+ async function runCommandWithInheritedStdio(command, args) {
125
+ return new Promise((resolve, reject) => {
126
+ const child = spawn(command, [...args], {
127
+ env: process.env,
128
+ stdio: 'inherit',
129
+ });
130
+ child.on('error', (error) => {
131
+ reject(error);
132
+ });
133
+ child.on('close', (code) => {
134
+ resolve(code ?? 1);
135
+ });
136
+ });
137
+ }
138
+ async function restartCli() {
139
+ const entrypoint = process.argv[1];
140
+ if (!entrypoint) {
141
+ throw new Error('Nao foi possivel identificar o entrypoint atual da CLI para reiniciar o processo.');
142
+ }
143
+ await new Promise((resolve, reject) => {
144
+ const child = spawn(process.execPath, [...process.execArgv, entrypoint, ...process.argv.slice(2)], {
145
+ env: process.env,
146
+ stdio: 'inherit',
147
+ });
148
+ child.on('error', (error) => {
149
+ reject(error);
150
+ });
151
+ child.on('spawn', () => {
152
+ resolve();
153
+ });
154
+ });
155
+ }
156
+ export async function checkForCliUpdate(currentVersion) {
157
+ const { packageName } = readInstalledPackageMetadata();
158
+ try {
159
+ const latestVersion = await fetchLatestPublishedVersion(packageName);
160
+ if (compareVersions(latestVersion, currentVersion) > 0) {
161
+ return {
162
+ currentVersion,
163
+ latestVersion,
164
+ packageName,
165
+ status: 'available',
166
+ };
167
+ }
168
+ return {
169
+ currentVersion,
170
+ latestVersion,
171
+ packageName,
172
+ status: 'current',
173
+ };
174
+ }
175
+ catch (error) {
176
+ return {
177
+ currentVersion,
178
+ message: toErrorMessage(error),
179
+ packageName,
180
+ status: 'error',
181
+ };
182
+ }
183
+ }
184
+ export async function runCliSelfUpdate(packageName, latestVersion) {
185
+ try {
186
+ const exitCode = await runCommandWithInheritedStdio(getNpmCommand(), [
187
+ 'install',
188
+ '--global',
189
+ `${packageName}@${latestVersion}`,
190
+ ]);
191
+ if (exitCode !== 0) {
192
+ return {
193
+ error: `O npm encerrou a atualizacao com codigo ${exitCode}.`,
194
+ ok: false,
195
+ };
196
+ }
197
+ await restartCli();
198
+ return { ok: true };
199
+ }
200
+ catch (error) {
201
+ return {
202
+ error: toErrorMessage(error),
203
+ ok: false,
204
+ };
205
+ }
206
+ }
package/dist/cli.js CHANGED
@@ -2,6 +2,7 @@
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { render } from 'ink';
4
4
  import { App } from './app.js';
5
+ import { runCliSelfUpdate } from './cli-update-service.js';
5
6
  import { APP_VERSION } from './version.js';
6
7
  const args = process.argv.slice(2);
7
8
  const initialInput = args
@@ -25,4 +26,26 @@ if (args.includes('--version') || args.includes('-v')) {
25
26
  process.exit(0);
26
27
  }
27
28
  console.clear();
28
- render(_jsx(App, { appVersion: APP_VERSION, initialInput: initialInput }));
29
+ let appInstance;
30
+ function mountApp(feedback = null) {
31
+ appInstance = render(_jsx(App, { appVersion: APP_VERSION, initialInput: initialInput, initialNotification: feedback?.message ?? null, initialNotificationTone: feedback?.tone ?? 'success', onSelfUpdate: async (update) => {
32
+ appInstance.unmount();
33
+ console.clear();
34
+ process.stdout.write([
35
+ `Atualizando o CLI de v${update.currentVersion} para v${update.latestVersion}.`,
36
+ `Pacote npm: ${update.packageName}`,
37
+ '',
38
+ ].join('\n'));
39
+ const result = await runCliSelfUpdate(update.packageName, update.latestVersion);
40
+ if (result.ok) {
41
+ process.exit(0);
42
+ }
43
+ process.stdout.write(`\nFalha ao atualizar automaticamente: ${result.error}\n`);
44
+ process.stdout.write('A CLI atual continuara disponivel.\n');
45
+ mountApp({
46
+ message: `Nao foi possivel atualizar a CLI automaticamente. ${result.error}`,
47
+ tone: 'error',
48
+ });
49
+ } }));
50
+ }
51
+ mountApp();
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const APP_VERSION = "0.1.6";
1
+ export declare const APP_VERSION = "0.1.7";
2
2
  //# sourceMappingURL=version.d.ts.map
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const APP_VERSION = '0.1.6';
1
+ export const APP_VERSION = '0.1.7';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trendify/cli",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "CLI do Trendify para descoberta de temas e fluxos de conta.",
5
5
  "type": "module",
6
6
  "main": "dist/cli.js",