@invizi/cli 0.1.3 → 0.1.5

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/invizi.js CHANGED
@@ -20,6 +20,9 @@ Run invizi --help after login for the remote command list.
20
20
  `);
21
21
  }
22
22
  async function executeProtocol(args, authHeader) {
23
+ // Handle --json flag: output structured result instead of text
24
+ const jsonMode = args.includes('--json');
25
+ const serverArgs = args.filter(a => a !== '--json');
23
26
  const apiUrl = getApiUrl();
24
27
  const res = await fetch(`${apiUrl}/cli/v1/execute`, {
25
28
  method: 'POST',
@@ -27,7 +30,7 @@ async function executeProtocol(args, authHeader) {
27
30
  'Content-Type': 'application/json',
28
31
  Authorization: authHeader,
29
32
  },
30
- body: JSON.stringify({ argv: args }),
33
+ body: JSON.stringify({ argv: serverArgs }),
31
34
  });
32
35
  if (res.status === 404) {
33
36
  return { handled: false, exitCode: 0 };
@@ -41,10 +44,14 @@ async function executeProtocol(args, authHeader) {
41
44
  console.error('Invalid protocol response from server');
42
45
  return { handled: true, exitCode: 1 };
43
46
  }
44
- if (typeof output.text === 'string' && output.text.length > 0) {
47
+ // --json flag: output structured result instead of text
48
+ if (jsonMode && output.result !== undefined) {
49
+ process.stdout.write(`${JSON.stringify(output.result, null, 2)}\n`);
50
+ }
51
+ else if (typeof output.text === 'string' && output.text.length > 0) {
45
52
  process.stdout.write(`${output.text}${output.text.endsWith('\n') ? '' : '\n'}`);
46
53
  }
47
- if (!output.text && output.result !== undefined) {
54
+ else if (output.result !== undefined) {
48
55
  process.stdout.write(`${JSON.stringify(output.result, null, 2)}\n`);
49
56
  }
50
57
  if (output.error?.message) {
@@ -96,6 +103,15 @@ async function executeRemote(args, options = {}) {
96
103
  export async function main(rawArgs = process.argv.slice(2)) {
97
104
  const args = rawArgs;
98
105
  const command = args[0];
106
+ // First-run: if no config exists and user isn't running setup/version/config, prompt
107
+ if (command && !['setup', 'version', 'config', '--version', '-v', '--help', '-h'].includes(command)) {
108
+ const config = loadConfig();
109
+ if (!config.apiUrl) {
110
+ console.log('First run detected. Running setup...\n');
111
+ await setup([]);
112
+ console.log('');
113
+ }
114
+ }
99
115
  if (!command || command === '--help' || command === '-h') {
100
116
  showLocalHelp();
101
117
  const header = await getAuthorizationHeader();
package/dist/setup.js CHANGED
@@ -89,6 +89,16 @@ export async function setup(args) {
89
89
  }
90
90
  const skills = (await listRes.json());
91
91
  for (const name of skills) {
92
+ const skillPath = join(skillsDir, name, 'SKILL.md');
93
+ const exists = existsSync(skillPath);
94
+ if (exists) {
95
+ console.log(` [exists] ${name} — overwrite? (y/n) `);
96
+ const answer = await promptYN();
97
+ if (!answer) {
98
+ console.log(` [skip] ${name}`);
99
+ continue;
100
+ }
101
+ }
92
102
  const res = await fetch(`${SKILLS_URL}/${name}/SKILL.md`);
93
103
  if (!res.ok) {
94
104
  console.error(` [x] ${name} (download failed)`);
@@ -98,7 +108,7 @@ export async function setup(args) {
98
108
  if (!dryRun) {
99
109
  const dir = join(skillsDir, name);
100
110
  mkdirSync(dir, { recursive: true });
101
- writeFileSync(join(dir, 'SKILL.md'), content);
111
+ writeFileSync(skillPath, content);
102
112
  }
103
113
  console.log(` [ok] ${name}`);
104
114
  }
@@ -107,8 +117,27 @@ export async function setup(args) {
107
117
  console.log('Dry run complete. No files written.');
108
118
  }
109
119
  else {
110
- console.log(`Installed ${skills.length} skills to ${skillsDir}`);
120
+ console.log(`Skills installed to ${skillsDir}`);
111
121
  console.log('Try /invizi-trade in your AI tool.');
112
122
  }
113
123
  return 0;
114
124
  }
125
+ function promptYN() {
126
+ return new Promise(resolve => {
127
+ const { stdin, stdout } = process;
128
+ if (!stdin.isTTY) {
129
+ // Non-interactive (CI, piped) — don't overwrite by default
130
+ resolve(false);
131
+ return;
132
+ }
133
+ stdin.setRawMode(true);
134
+ stdin.resume();
135
+ stdin.once('data', (data) => {
136
+ stdin.setRawMode(false);
137
+ stdin.pause();
138
+ const key = data.toString().toLowerCase();
139
+ stdout.write(key === 'y' ? 'yes\n' : 'no\n');
140
+ resolve(key === 'y');
141
+ });
142
+ });
143
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@invizi/cli",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Invizi CLI",
5
5
  "type": "module",
6
6
  "bin": {