@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 +18 -0
- package/package.json +1 -1
- package/src/commands/artifacts.js +35 -2
- package/src/commands/projects.js +29 -1
- package/src/lib/api-client.js +4 -0
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,9 +1,11 @@
|
|
|
1
1
|
// @vectora/cli — artifact commands
|
|
2
2
|
import chalk from 'chalk';
|
|
3
|
-
import {
|
|
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
|
+
}
|
package/src/commands/projects.js
CHANGED
|
@@ -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
|
*/
|
package/src/lib/api-client.js
CHANGED
|
@@ -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) {
|