-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathargs.ts
More file actions
129 lines (117 loc) · 4.7 KB
/
Copy pathargs.ts
File metadata and controls
129 lines (117 loc) · 4.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import type { CreateOptions } from '../commands/create.js';
export type ParsedArgs =
| { kind: 'create'; options: CreateOptions }
| { kind: 'help' }
| { kind: 'version' }
| { kind: 'error'; message: string };
/**
* Hand-rolled argv parser — the CLI has one command and a handful of flags,
* which is not worth a runtime dependency. Supports `--flag value` and
* `--flag=value`, and `--ip` may repeat.
*/
export function parseArgs(argv: string[]): ParsedArgs {
const options: CreateOptions = {};
const positionals: string[] = [];
for (let i = 0; i < argv.length; i++) {
let arg = argv[i];
let inlineValue: string | undefined;
const eq = arg.indexOf('=');
if (arg.startsWith('--') && eq !== -1) {
inlineValue = arg.slice(eq + 1);
arg = arg.slice(0, eq);
}
const takeValue = (): string | { error: string } => {
if (inlineValue !== undefined) return inlineValue;
const next = argv[++i];
if (next === undefined || next.startsWith('-')) return { error: `${arg} requires a value` };
return next;
};
switch (arg) {
case '-h': case '--help':
return { kind: 'help' };
case '-V': case '--version':
return { kind: 'version' };
case '--ip': {
const v = takeValue();
if (typeof v !== 'string') return { kind: 'error', message: v.error };
options.ip = [...(options.ip ?? []), v];
break;
}
case '--email': {
const v = takeValue();
if (typeof v !== 'string') return { kind: 'error', message: v.error };
options.email = v;
break;
}
case '--api-host': {
const v = takeValue();
if (typeof v !== 'string') return { kind: 'error', message: v.error };
options.apiHost = v;
break;
}
case '--goal': {
const v = takeValue();
if (typeof v !== 'string') return { kind: 'error', message: v.error };
options.goal = v;
break;
}
case '--model': {
const v = takeValue();
if (typeof v !== 'string') return { kind: 'error', message: v.error };
options.model = v;
break;
}
case '--force':
options.force = true;
break;
case '--no-env':
options.env = false;
break;
case '--no-agent-metadata':
options.agentMetadata = false;
break;
case '--json':
options.json = true;
break;
default:
if (arg.startsWith('-')) return { kind: 'error', message: `Unknown option: ${arg}` };
positionals.push(arg);
}
}
// `create` is the default command; `claim` and `status` are planned.
if (positionals.length === 0 || (positionals.length === 1 && positionals[0] === 'create')) {
return { kind: 'create', options };
}
const unknown = positionals.find(p => p !== 'create') ?? positionals[1];
return { kind: 'error', message: `Unknown command: ${unknown}` };
}
export const HELP_TEXT = `One command, and your media is live on Cloudinary.
Usage: cloudinary-cloud [create] [options]
Commands:
create (default) provision a disposable Cloudinary cloud account — no
signup, no credentials needed. Writes CLOUDINARY_URL to
./.env and prints a claim URL a human can open later to
keep the account.
Options:
--ip <address> public IP allowed to view delivered media (repeatable,
max 3). Default: the server locks delivery to the
address the request came from; a warning is printed if
this machine's IP ends up outside the allow-list
--email <address> pre-fill the claim page with this email (never verified
at creation)
--goal <text> what you are building — sent as attribution alongside the
auto-detected agent framework and model
--model <name> the LLM model driving this session — sent as attribution.
Only needed when it cannot be auto-detected from the
environment, which is common
--force replace an existing CLOUDINARY_URL in ./.env
--no-env do not write ./.env — credentials are only printed
--no-agent-metadata do not send agent attribution fields
--json print the raw provisioning response as JSON
--api-host <url> override the Cloudinary API host (or set CLOUDINARY_API_HOST)
-V, --version print the version
-h, --help show this help
If you are an AI agent, pass --goal and --model so the cloud can be attributed
to what you are building. For example:
npx @cloudinary/cloud --goal "auto-crop and deliver product images" --model <your-model-id>
`;