@vectorasystems/cli 0.1.0 → 0.1.2

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/bin/vectora.js CHANGED
@@ -69,6 +69,15 @@ projects
69
69
  await m.show(id, opts);
70
70
  });
71
71
 
72
+ projects
73
+ .command('edit [id]')
74
+ .description('Edit project metadata (defaults to active project)')
75
+ .option('-n, --name <name>', 'New project name')
76
+ .action(async (id, opts) => {
77
+ const m = await import('../src/commands/projects.js');
78
+ await m.edit(id, opts);
79
+ });
80
+
72
81
  projects
73
82
  .command('select <id>')
74
83
  .description('Set active project')
@@ -139,6 +148,15 @@ artifacts
139
148
  await m.show(id, opts);
140
149
  });
141
150
 
151
+ artifacts
152
+ .command('download <id>')
153
+ .description('Download artifact content to a file')
154
+ .option('-o, --out <path>', 'Output file path (defaults to artifact filename in cwd)')
155
+ .action(async (id, opts) => {
156
+ const m = await import('../src/commands/artifacts.js');
157
+ await m.download(id, opts);
158
+ });
159
+
142
160
  // ── Usage ─────────────────────────────────────────────────────────────────────
143
161
  program
144
162
  .command('usage')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vectorasystems/cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Vectora CLI — AI-powered project orchestration",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,9 +1,11 @@
1
1
  // @vectora/cli — artifact commands
2
2
  import chalk from 'chalk';
3
- import { getProjectArtifacts, getArtifact } from '../lib/api-client.js';
3
+ import { writeFile } from 'node:fs/promises';
4
+ import { resolve } from 'node:path';
5
+ import { getProjectArtifacts, getArtifact, getArtifactDownloadUrl } from '../lib/api-client.js';
4
6
  import { getConfig, getConfigValue } from '../lib/config-store.js';
5
7
  import { handleError } from '../lib/errors.js';
6
- import { renderTable, renderJson, renderTime, warn, info } from '../lib/output.js';
8
+ import { renderTable, renderJson, renderTime, warn, info, success } from '../lib/output.js';
7
9
 
8
10
  /**
9
11
  * vectora artifacts list [--project <id>] [--type <type>]
@@ -86,3 +88,34 @@ export async function show(id, opts) {
86
88
  handleError(err);
87
89
  }
88
90
  }
91
+
92
+ /**
93
+ * vectora artifacts download <id> [--out <path>]
94
+ */
95
+ export async function download(id, opts) {
96
+ try {
97
+ if (!id) {
98
+ console.error(chalk.red('Error — artifact ID is required'));
99
+ process.exitCode = 1;
100
+ return;
101
+ }
102
+
103
+ // Get presigned URL + suggested filename from API
104
+ const { url, filename } = await getArtifactDownloadUrl(id);
105
+
106
+ const outPath = resolve(opts.out ?? filename);
107
+
108
+ // Fetch directly from R2 via presigned URL
109
+ const res = await fetch(url, { signal: AbortSignal.timeout(60_000) });
110
+ if (!res.ok) {
111
+ throw new Error(`Download failed: HTTP ${res.status}`);
112
+ }
113
+
114
+ const buffer = Buffer.from(await res.arrayBuffer());
115
+ await writeFile(outPath, buffer);
116
+
117
+ success(`Saved to ${chalk.bold(outPath)} ${chalk.dim(`(${(buffer.length / 1024).toFixed(1)} KB)`)}`);
118
+ } catch (err) {
119
+ handleError(err);
120
+ }
121
+ }
@@ -1,6 +1,6 @@
1
1
  // @vectora/cli — project commands
2
2
  import chalk from 'chalk';
3
- import { getProjects, createProject, getProject, deleteProject, getWorkspaces } from '../lib/api-client.js';
3
+ import { getProjects, createProject, getProject, patchProject, deleteProject, getWorkspaces } from '../lib/api-client.js';
4
4
  import { getConfig, setConfigValue, getConfigValue } from '../lib/config-store.js';
5
5
  import { handleError } from '../lib/errors.js';
6
6
  import { renderTable, renderJson, renderTime, success, info, warn } from '../lib/output.js';
@@ -137,6 +137,34 @@ export async function show(id, opts) {
137
137
  }
138
138
  }
139
139
 
140
+ /**
141
+ * vectora projects edit [<id>] --name <name>
142
+ */
143
+ export async function edit(id, opts) {
144
+ try {
145
+ const projectId = id ?? getConfigValue('defaultProject');
146
+ if (!projectId) {
147
+ warn('No project specified. Use --project <id> or select one with: vectora projects select <id>');
148
+ process.exitCode = 1;
149
+ return;
150
+ }
151
+
152
+ const updates = {};
153
+ if (opts.name !== undefined) updates.name = opts.name;
154
+
155
+ if (Object.keys(updates).length === 0) {
156
+ warn('Nothing to update. Use --name <name> to rename the project.');
157
+ process.exitCode = 1;
158
+ return;
159
+ }
160
+
161
+ const project = await patchProject(projectId, updates);
162
+ success(`Updated project ${chalk.bold(project.name)} ${chalk.dim(`(${project.id})`)}`);
163
+ } catch (err) {
164
+ handleError(err);
165
+ }
166
+ }
167
+
140
168
  /**
141
169
  * vectora projects select <id>
142
170
  */
@@ -121,6 +121,10 @@ export async function getArtifact(artifactId) {
121
121
  return res.artifact;
122
122
  }
123
123
 
124
+ export async function getArtifactDownloadUrl(artifactId) {
125
+ return authedFetch(`/v1/artifacts/${artifactId}/download`);
126
+ }
127
+
124
128
  // ─── Handoff ─────────────────────────────────────────────────────────────────
125
129
 
126
130
  export async function triggerHandoff(projectId, target) {