argus-media-cli 0.1.0 → 0.1.1
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/README.md +80 -0
- package/dist/index.js +326 -139
- package/package.json +23 -5
package/README.md
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# argus-media-cli
|
|
2
|
+
|
|
3
|
+
CLI for [Argus](https://argus.build) — AI-native media asset management.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g argus-media-cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or run directly:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx argus-media-cli upload photo.jpg
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Setup
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
argus login
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Or set your API key as an environment variable:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
export ARGUS_API_KEY=ak_your_key_here
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Commands
|
|
30
|
+
|
|
31
|
+
### Upload
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
argus upload photo.jpg
|
|
35
|
+
argus upload hero.png --project campaign-q2 --tags hero,banner
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Search
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
argus search "sunset landscape"
|
|
42
|
+
argus search --project website --status ready --json
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### List
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
argus list
|
|
49
|
+
argus list --project website --limit 20
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Get
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
argus get <asset-id>
|
|
56
|
+
argus get abc12345 --json
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Login
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
argus login # Interactive prompt
|
|
63
|
+
argus login --key ak_xxx # Non-interactive
|
|
64
|
+
argus login --url http://localhost:8787 # Custom API URL
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Options
|
|
68
|
+
|
|
69
|
+
All commands support `--json` for structured JSON output.
|
|
70
|
+
|
|
71
|
+
## Environment Variables
|
|
72
|
+
|
|
73
|
+
| Variable | Description |
|
|
74
|
+
|---|---|
|
|
75
|
+
| `ARGUS_API_KEY` | API key (overrides saved config) |
|
|
76
|
+
| `ARGUS_BASE_URL` | API base URL (default: `https://argus.build`) |
|
|
77
|
+
|
|
78
|
+
## License
|
|
79
|
+
|
|
80
|
+
MIT
|
package/dist/index.js
CHANGED
|
@@ -1,180 +1,367 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import { join } from "path";
|
|
4
|
-
import { homedir } from "os";
|
|
5
|
-
|
|
2
|
+
import { readFile, writeFile, mkdir } from "node:fs/promises";
|
|
3
|
+
import { basename, extname, join } from "node:path";
|
|
4
|
+
import { homedir } from "node:os";
|
|
5
|
+
import * as readline from "node:readline";
|
|
6
|
+
// ─── Config ────────────────────────────────────────────────────────────────
|
|
6
7
|
const CONFIG_DIR = join(homedir(), ".argus");
|
|
7
8
|
const CONFIG_FILE = join(CONFIG_DIR, "config.json");
|
|
8
|
-
|
|
9
|
-
function loadConfig() {
|
|
9
|
+
async function loadConfig() {
|
|
10
10
|
try {
|
|
11
|
-
|
|
11
|
+
const data = await readFile(CONFIG_FILE, "utf-8");
|
|
12
|
+
return JSON.parse(data);
|
|
12
13
|
}
|
|
13
14
|
catch {
|
|
14
15
|
return {};
|
|
15
16
|
}
|
|
16
17
|
}
|
|
17
|
-
function saveConfig(config) {
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
async function saveConfig(config) {
|
|
19
|
+
await mkdir(CONFIG_DIR, { recursive: true });
|
|
20
|
+
await writeFile(CONFIG_FILE, JSON.stringify(config, null, 2) + "\n");
|
|
20
21
|
}
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
// ─── API Client ────────────────────────────────────────────────────────────
|
|
23
|
+
function getBaseUrl(config) {
|
|
24
|
+
return process.env.ARGUS_BASE_URL || config.baseUrl || "https://argus.build";
|
|
25
|
+
}
|
|
26
|
+
function getApiKey(config) {
|
|
27
|
+
const key = process.env.ARGUS_API_KEY || config.apiKey;
|
|
23
28
|
if (!key) {
|
|
24
|
-
console.error("No API key
|
|
25
|
-
console.error("
|
|
29
|
+
console.error("Error: No API key configured.");
|
|
30
|
+
console.error("Run `argus login` to authenticate, or set ARGUS_API_KEY.");
|
|
26
31
|
process.exit(1);
|
|
27
32
|
}
|
|
28
33
|
return key;
|
|
29
34
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const
|
|
35
|
+
async function apiRequest(config, method, path, body) {
|
|
36
|
+
const url = `${getBaseUrl(config)}${path}`;
|
|
37
|
+
const apiKey = getApiKey(config);
|
|
38
|
+
const opts = {
|
|
33
39
|
method,
|
|
34
40
|
headers: {
|
|
35
|
-
Authorization: `Bearer ${
|
|
41
|
+
Authorization: `Bearer ${apiKey}`,
|
|
36
42
|
...(body ? { "Content-Type": "application/json" } : {}),
|
|
37
43
|
},
|
|
38
44
|
...(body ? { body: JSON.stringify(body) } : {}),
|
|
39
|
-
}
|
|
40
|
-
const
|
|
45
|
+
};
|
|
46
|
+
const res = await fetch(url, opts);
|
|
41
47
|
if (!res.ok) {
|
|
42
|
-
const
|
|
43
|
-
|
|
48
|
+
const text = await res.text();
|
|
49
|
+
throw new Error(`API ${method} ${path} failed (${res.status}): ${text}`);
|
|
50
|
+
}
|
|
51
|
+
return res.json();
|
|
52
|
+
}
|
|
53
|
+
// ─── MIME Types ────────────────────────────────────────────────────────────
|
|
54
|
+
const MIME_TYPES = {
|
|
55
|
+
".jpg": "image/jpeg",
|
|
56
|
+
".jpeg": "image/jpeg",
|
|
57
|
+
".png": "image/png",
|
|
58
|
+
".gif": "image/gif",
|
|
59
|
+
".webp": "image/webp",
|
|
60
|
+
".svg": "image/svg+xml",
|
|
61
|
+
".mp4": "video/mp4",
|
|
62
|
+
".mov": "video/quicktime",
|
|
63
|
+
".webm": "video/webm",
|
|
64
|
+
".mp3": "audio/mpeg",
|
|
65
|
+
".wav": "audio/wav",
|
|
66
|
+
".pdf": "application/pdf",
|
|
67
|
+
};
|
|
68
|
+
// ─── Formatting ────────────────────────────────────────────────────────────
|
|
69
|
+
function formatBytes(bytes) {
|
|
70
|
+
if (bytes < 1024)
|
|
71
|
+
return `${bytes} B`;
|
|
72
|
+
if (bytes < 1024 * 1024)
|
|
73
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
74
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
75
|
+
}
|
|
76
|
+
function formatAssetRow(a) {
|
|
77
|
+
const status = a.status === "ready" ? "\x1b[32m●\x1b[0m" : a.status === "pending" ? "\x1b[33m●\x1b[0m" : "\x1b[31m●\x1b[0m";
|
|
78
|
+
const size = formatBytes(a.size || 0);
|
|
79
|
+
const project = a.project ? ` [${a.project}]` : "";
|
|
80
|
+
const tags = a.tags?.length ? ` (${a.tags.join(", ")})` : "";
|
|
81
|
+
return `${status} ${a.id.slice(0, 8)} ${a.filename} ${size}${project}${tags}`;
|
|
82
|
+
}
|
|
83
|
+
function formatAssetDetail(a) {
|
|
84
|
+
const lines = [
|
|
85
|
+
`\x1b[1m${a.filename}\x1b[0m`,
|
|
86
|
+
` ID: ${a.id}`,
|
|
87
|
+
` Status: ${a.status}`,
|
|
88
|
+
` Type: ${a.mimeType}`,
|
|
89
|
+
` Size: ${formatBytes(a.size || 0)}`,
|
|
90
|
+
];
|
|
91
|
+
if (a.project)
|
|
92
|
+
lines.push(` Project: ${a.project}`);
|
|
93
|
+
if (a.url)
|
|
94
|
+
lines.push(` URL: ${a.url}`);
|
|
95
|
+
if (a.tags?.length)
|
|
96
|
+
lines.push(` Tags: ${a.tags.join(", ")}`);
|
|
97
|
+
if (a.uploadedBy)
|
|
98
|
+
lines.push(` Uploader: ${a.uploadedBy}`);
|
|
99
|
+
if (a.uploadedAt)
|
|
100
|
+
lines.push(` Uploaded: ${a.uploadedAt}`);
|
|
101
|
+
if (a.analysis) {
|
|
102
|
+
lines.push(` \x1b[1mAnalysis:\x1b[0m`);
|
|
103
|
+
if (a.analysis.description)
|
|
104
|
+
lines.push(` ${a.analysis.description}`);
|
|
105
|
+
if (a.analysis.mood)
|
|
106
|
+
lines.push(` Mood: ${a.analysis.mood}`);
|
|
107
|
+
if (a.analysis.dominantColors?.length) {
|
|
108
|
+
const colors = a.analysis.dominantColors.map((c) => `${c.name} (${c.hex})`).join(", ");
|
|
109
|
+
lines.push(` Colors: ${colors}`);
|
|
110
|
+
}
|
|
111
|
+
if (a.analysis.useCases?.length)
|
|
112
|
+
lines.push(` Uses: ${a.analysis.useCases.join(", ")}`);
|
|
113
|
+
if (a.analysis.tags?.length)
|
|
114
|
+
lines.push(` Tags: ${a.analysis.tags.join(", ")}`);
|
|
115
|
+
}
|
|
116
|
+
return lines.join("\n");
|
|
117
|
+
}
|
|
118
|
+
// ─── Commands ──────────────────────────────────────────────────────────────
|
|
119
|
+
async function cmdLogin(args, flags) {
|
|
120
|
+
const config = await loadConfig();
|
|
121
|
+
if (flags.key) {
|
|
122
|
+
config.apiKey = flags.key;
|
|
123
|
+
await saveConfig(config);
|
|
124
|
+
console.log("API key saved to ~/.argus/config.json");
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
if (flags.url) {
|
|
128
|
+
config.baseUrl = flags.url;
|
|
129
|
+
await saveConfig(config);
|
|
130
|
+
console.log(`Base URL set to ${flags.url}`);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
134
|
+
const ask = (q) => new Promise((resolve) => rl.question(q, resolve));
|
|
135
|
+
console.log("Argus CLI Login");
|
|
136
|
+
console.log("Get your API key at https://argus.build/ui\n");
|
|
137
|
+
const key = await ask("API key: ");
|
|
138
|
+
rl.close();
|
|
139
|
+
if (!key.trim()) {
|
|
140
|
+
console.error("No key provided.");
|
|
141
|
+
process.exit(1);
|
|
142
|
+
}
|
|
143
|
+
config.apiKey = key.trim();
|
|
144
|
+
await saveConfig(config);
|
|
145
|
+
// Verify the key works
|
|
146
|
+
try {
|
|
147
|
+
const res = await apiRequest(config, "GET", "/usage");
|
|
148
|
+
console.log(`\nAuthenticated! Workspace tier: ${res.tier}`);
|
|
149
|
+
console.log(`Assets: ${res.assets?.used ?? 0}/${res.assets?.limit ?? "unlimited"}`);
|
|
150
|
+
}
|
|
151
|
+
catch (e) {
|
|
152
|
+
console.error(`\nWarning: Could not verify key — ${e.message}`);
|
|
153
|
+
console.log("Key saved anyway. Check it with `argus list`.");
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
async function cmdUpload(args, flags) {
|
|
157
|
+
const filePath = args[0];
|
|
158
|
+
if (!filePath) {
|
|
159
|
+
console.error("Usage: argus upload <file> [--project NAME] [--tags a,b,c]");
|
|
44
160
|
process.exit(1);
|
|
45
161
|
}
|
|
46
|
-
|
|
162
|
+
const config = await loadConfig();
|
|
163
|
+
const apiKey = getApiKey(config);
|
|
164
|
+
const baseUrl = getBaseUrl(config);
|
|
165
|
+
// Read file
|
|
166
|
+
const fileData = await readFile(filePath);
|
|
167
|
+
const fileName = basename(filePath);
|
|
168
|
+
const ext = extname(fileName).toLowerCase();
|
|
169
|
+
const mimeType = MIME_TYPES[ext] || "application/octet-stream";
|
|
170
|
+
// Build multipart form data
|
|
171
|
+
const blob = new Blob([fileData], { type: mimeType });
|
|
172
|
+
const form = new FormData();
|
|
173
|
+
form.append("file", blob, fileName);
|
|
174
|
+
if (flags.project)
|
|
175
|
+
form.append("project", flags.project);
|
|
176
|
+
if (flags.tags)
|
|
177
|
+
form.append("tags", flags.tags);
|
|
178
|
+
const res = await fetch(`${baseUrl}/assets/upload`, {
|
|
179
|
+
method: "POST",
|
|
180
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
181
|
+
body: form,
|
|
182
|
+
});
|
|
183
|
+
if (!res.ok) {
|
|
184
|
+
const text = await res.text();
|
|
185
|
+
throw new Error(`Upload failed (${res.status}): ${text}`);
|
|
186
|
+
}
|
|
187
|
+
const data = (await res.json());
|
|
188
|
+
const asset = data.asset;
|
|
189
|
+
if (flags.json) {
|
|
190
|
+
console.log(JSON.stringify(data, null, 2));
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
console.log(`Uploaded: ${asset.filename} (${asset.id})`);
|
|
194
|
+
console.log(`Status: ${asset.status}`);
|
|
195
|
+
if (asset.url)
|
|
196
|
+
console.log(`URL: ${asset.url}`);
|
|
197
|
+
}
|
|
47
198
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
199
|
+
async function cmdSearch(args, flags) {
|
|
200
|
+
const query = args.join(" ");
|
|
201
|
+
const config = await loadConfig();
|
|
202
|
+
const params = new URLSearchParams();
|
|
203
|
+
if (query)
|
|
204
|
+
params.set("q", query);
|
|
205
|
+
if (flags.project)
|
|
206
|
+
params.set("project", flags.project);
|
|
207
|
+
if (flags.status)
|
|
208
|
+
params.set("status", flags.status);
|
|
209
|
+
if (flags.tags)
|
|
210
|
+
params.set("tags", flags.tags);
|
|
211
|
+
if (flags.limit)
|
|
212
|
+
params.set("limit", flags.limit);
|
|
213
|
+
if (flags.offset)
|
|
214
|
+
params.set("offset", flags.offset);
|
|
215
|
+
const qs = params.toString();
|
|
216
|
+
const data = (await apiRequest(config, "GET", `/assets${qs ? `?${qs}` : ""}`));
|
|
217
|
+
if (flags.json) {
|
|
51
218
|
console.log(JSON.stringify(data, null, 2));
|
|
52
219
|
return;
|
|
53
220
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
221
|
+
if (!data.assets?.length) {
|
|
222
|
+
console.log("No assets found.");
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
console.log(`${data.total} asset${data.total === 1 ? "" : "s"} found:\n`);
|
|
226
|
+
for (const a of data.assets) {
|
|
227
|
+
console.log(formatAssetRow(a));
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
async function cmdList(_args, flags) {
|
|
231
|
+
return cmdSearch([], flags);
|
|
232
|
+
}
|
|
233
|
+
async function cmdGet(args, flags) {
|
|
234
|
+
const id = args[0];
|
|
235
|
+
if (!id) {
|
|
236
|
+
console.error("Usage: argus get <asset-id>");
|
|
237
|
+
process.exit(1);
|
|
238
|
+
}
|
|
239
|
+
const config = await loadConfig();
|
|
240
|
+
const data = (await apiRequest(config, "GET", `/assets/${id}`));
|
|
241
|
+
if (flags.json) {
|
|
61
242
|
console.log(JSON.stringify(data, null, 2));
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
console.log(formatAssetDetail(data.asset));
|
|
62
246
|
}
|
|
63
|
-
function
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
if (
|
|
74
|
-
console.log(`
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
const
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
console.error("Usage: argus login <api-key>");
|
|
89
|
-
process.exit(1);
|
|
90
|
-
}
|
|
91
|
-
saveConfig({ ...loadConfig(), apiKey: key });
|
|
92
|
-
console.log("API key saved to ~/.argus/config.json");
|
|
93
|
-
break;
|
|
94
|
-
}
|
|
95
|
-
case "upload": {
|
|
96
|
-
const file = rest[0];
|
|
97
|
-
const project = rest[1];
|
|
98
|
-
if (!file || !existsSync(file)) {
|
|
99
|
-
console.error("Usage: argus upload <file> [project]");
|
|
100
|
-
process.exit(1);
|
|
101
|
-
}
|
|
102
|
-
const { createReadStream, statSync } = await import("fs");
|
|
103
|
-
const { basename } = await import("path");
|
|
104
|
-
const fd = new FormData();
|
|
105
|
-
const bytes = readFileSync(file);
|
|
106
|
-
fd.append("file", new Blob([bytes]), basename(file));
|
|
107
|
-
if (project)
|
|
108
|
-
fd.append("project", project);
|
|
109
|
-
const res = await fetch(`${BASE_URL}/assets/upload`, {
|
|
110
|
-
method: "POST",
|
|
111
|
-
headers: { Authorization: `Bearer ${getApiKey()}` },
|
|
112
|
-
body: fd,
|
|
113
|
-
});
|
|
114
|
-
const data = await res.json().catch(() => ({}));
|
|
115
|
-
if (!res.ok) {
|
|
116
|
-
console.error(`Error: ${data.error || res.statusText}`);
|
|
117
|
-
process.exit(1);
|
|
118
|
-
}
|
|
119
|
-
output(data, jsonFlag);
|
|
120
|
-
break;
|
|
247
|
+
async function cmdUsage(_args, flags) {
|
|
248
|
+
const config = await loadConfig();
|
|
249
|
+
const data = (await apiRequest(config, "GET", "/usage"));
|
|
250
|
+
if (flags.json) {
|
|
251
|
+
console.log(JSON.stringify(data, null, 2));
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
console.log(`\x1b[1mWorkspace Usage\x1b[0m`);
|
|
255
|
+
console.log(` Tier: ${data.tier}`);
|
|
256
|
+
console.log(` Assets: ${data.assets?.used ?? 0} / ${data.assets?.limit ?? "unlimited"}`);
|
|
257
|
+
if (data.credits != null) {
|
|
258
|
+
console.log(` Credits: ${data.credits?.used ?? 0} / ${data.credits?.limit ?? "unlimited"}`);
|
|
259
|
+
}
|
|
260
|
+
if (data.storage != null) {
|
|
261
|
+
console.log(` Storage: ${data.storage?.used != null ? formatBytes(data.storage.used) : "0 B"} / ${data.storage?.limit != null ? formatBytes(data.storage.limit) : "unlimited"}`);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
function parseArgs(argv) {
|
|
265
|
+
const command = argv[0] || "help";
|
|
266
|
+
const flags = {};
|
|
267
|
+
const args = [];
|
|
268
|
+
for (let i = 1; i < argv.length; i++) {
|
|
269
|
+
const arg = argv[i];
|
|
270
|
+
if (arg === "--json") {
|
|
271
|
+
flags.json = true;
|
|
121
272
|
}
|
|
122
|
-
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
273
|
+
else if (arg.startsWith("--")) {
|
|
274
|
+
const key = arg.slice(2);
|
|
275
|
+
const next = argv[i + 1];
|
|
276
|
+
if (next && !next.startsWith("--")) {
|
|
277
|
+
flags[key] = next;
|
|
278
|
+
i++;
|
|
127
279
|
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
break;
|
|
131
|
-
}
|
|
132
|
-
case "list": {
|
|
133
|
-
const project = rest[0];
|
|
134
|
-
const qs = project ? `?project=${encodeURIComponent(project)}` : "";
|
|
135
|
-
const data = await api("GET", `/assets${qs}`);
|
|
136
|
-
output(data, jsonFlag);
|
|
137
|
-
break;
|
|
138
|
-
}
|
|
139
|
-
case "get": {
|
|
140
|
-
const id = rest[0];
|
|
141
|
-
if (!id) {
|
|
142
|
-
console.error("Usage: argus get <id>");
|
|
143
|
-
process.exit(1);
|
|
280
|
+
else {
|
|
281
|
+
flags[key] = true;
|
|
144
282
|
}
|
|
145
|
-
const data = await api("GET", `/assets/${id}`);
|
|
146
|
-
output(data, jsonFlag);
|
|
147
|
-
break;
|
|
148
283
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
output(data, jsonFlag);
|
|
152
|
-
break;
|
|
284
|
+
else {
|
|
285
|
+
args.push(arg);
|
|
153
286
|
}
|
|
154
|
-
|
|
155
|
-
|
|
287
|
+
}
|
|
288
|
+
return { command, args, flags };
|
|
289
|
+
}
|
|
290
|
+
function printHelp() {
|
|
291
|
+
console.log(`\x1b[1margus\x1b[0m — AI-native media asset management
|
|
292
|
+
|
|
293
|
+
\x1b[1mUsage:\x1b[0m
|
|
294
|
+
argus <command> [options]
|
|
295
|
+
|
|
296
|
+
\x1b[1mCommands:\x1b[0m
|
|
297
|
+
login Authenticate with Argus
|
|
298
|
+
upload <file> Upload a media file
|
|
299
|
+
search <query> Search assets by description, tags, mood
|
|
300
|
+
list List all assets
|
|
301
|
+
get <id> Get asset details and analysis
|
|
302
|
+
usage Show workspace usage and limits
|
|
303
|
+
|
|
304
|
+
\x1b[1mGlobal Options:\x1b[0m
|
|
305
|
+
--json Output raw JSON
|
|
156
306
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
search <query> Search assets by keyword
|
|
161
|
-
list [project] List assets
|
|
162
|
-
get <id> Get asset by ID
|
|
163
|
-
usage Show credit and asset usage
|
|
307
|
+
\x1b[1mUpload Options:\x1b[0m
|
|
308
|
+
--project NAME Assign to a project
|
|
309
|
+
--tags a,b,c Comma-separated tags
|
|
164
310
|
|
|
165
|
-
Options
|
|
166
|
-
--
|
|
311
|
+
\x1b[1mSearch/List Options:\x1b[0m
|
|
312
|
+
--project NAME Filter by project
|
|
313
|
+
--status STATUS Filter by status (pending, ready, error)
|
|
314
|
+
--tags a,b,c Filter by tags
|
|
315
|
+
--limit N Max results (default 50)
|
|
316
|
+
--offset N Pagination offset
|
|
167
317
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
318
|
+
\x1b[1mLogin Options:\x1b[0m
|
|
319
|
+
--key KEY Set API key non-interactively
|
|
320
|
+
--url URL Set custom API base URL
|
|
171
321
|
|
|
172
|
-
|
|
322
|
+
\x1b[1mEnvironment:\x1b[0m
|
|
323
|
+
ARGUS_API_KEY API key (overrides saved config)
|
|
324
|
+
ARGUS_BASE_URL API base URL (default: https://argus.build)
|
|
325
|
+
|
|
326
|
+
\x1b[1mExamples:\x1b[0m
|
|
327
|
+
argus login
|
|
328
|
+
argus upload photo.jpg --project campaign-q2 --tags hero,banner
|
|
329
|
+
argus search "sunset landscape" --json
|
|
330
|
+
argus list --project website --limit 20
|
|
331
|
+
argus get abc12345-def6-7890-abcd-ef1234567890
|
|
173
332
|
`);
|
|
174
|
-
|
|
333
|
+
}
|
|
334
|
+
// ─── Main ──────────────────────────────────────────────────────────────────
|
|
335
|
+
const COMMANDS = {
|
|
336
|
+
login: cmdLogin,
|
|
337
|
+
upload: cmdUpload,
|
|
338
|
+
search: cmdSearch,
|
|
339
|
+
list: cmdList,
|
|
340
|
+
get: cmdGet,
|
|
341
|
+
usage: cmdUsage,
|
|
342
|
+
};
|
|
343
|
+
async function main() {
|
|
344
|
+
const { command, args, flags } = parseArgs(process.argv.slice(2));
|
|
345
|
+
if (command === "help" || command === "--help" || command === "-h") {
|
|
346
|
+
printHelp();
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
if (command === "version" || command === "--version" || command === "-v") {
|
|
350
|
+
console.log("argus-media-cli 0.1.1");
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
const handler = COMMANDS[command];
|
|
354
|
+
if (!handler) {
|
|
355
|
+
console.error(`Unknown command: ${command}`);
|
|
356
|
+
console.error('Run "argus help" for usage.');
|
|
357
|
+
process.exit(1);
|
|
358
|
+
}
|
|
359
|
+
try {
|
|
360
|
+
await handler(args, flags);
|
|
361
|
+
}
|
|
362
|
+
catch (err) {
|
|
363
|
+
console.error(`Error: ${err.message}`);
|
|
364
|
+
process.exit(1);
|
|
175
365
|
}
|
|
176
366
|
}
|
|
177
|
-
main()
|
|
178
|
-
console.error(err.message || err);
|
|
179
|
-
process.exit(1);
|
|
180
|
-
});
|
|
367
|
+
main();
|
package/package.json
CHANGED
|
@@ -1,17 +1,33 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "argus-media-cli",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "CLI for Argus — AI-
|
|
5
|
-
"keywords": [
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "CLI for Argus — AI-native media asset management. Upload, search, analyze, and manage media assets from the terminal.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"argus",
|
|
7
|
+
"media",
|
|
8
|
+
"assets",
|
|
9
|
+
"ai",
|
|
10
|
+
"cli",
|
|
11
|
+
"upload",
|
|
12
|
+
"image",
|
|
13
|
+
"video"
|
|
14
|
+
],
|
|
6
15
|
"license": "MIT",
|
|
7
16
|
"author": "Brookfield Digital",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "https://github.com/brookfield-digital/argus"
|
|
20
|
+
},
|
|
8
21
|
"homepage": "https://argus.build",
|
|
9
22
|
"type": "module",
|
|
10
23
|
"bin": {
|
|
11
24
|
"argus": "./dist/index.js"
|
|
12
25
|
},
|
|
13
26
|
"main": "./dist/index.js",
|
|
14
|
-
"files": [
|
|
27
|
+
"files": [
|
|
28
|
+
"dist",
|
|
29
|
+
"README.md"
|
|
30
|
+
],
|
|
15
31
|
"scripts": {
|
|
16
32
|
"build": "tsc",
|
|
17
33
|
"prepublishOnly": "npm run build"
|
|
@@ -20,5 +36,7 @@
|
|
|
20
36
|
"@types/node": "^20.0.0",
|
|
21
37
|
"typescript": "^5.4.0"
|
|
22
38
|
},
|
|
23
|
-
"engines": {
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=18"
|
|
41
|
+
}
|
|
24
42
|
}
|