@clickraft/cli 0.1.5 → 0.1.6
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/CHANGELOG.md +2 -2
- package/README.md +13 -0
- package/dist/cli.js +41 -5
- package/dist/cli.js.map +1 -1
- package/dist/index.js +41 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
## [0.1.
|
|
1
|
+
## [0.1.6](https://github.com/clickraft/cli/compare/v0.1.5...v0.1.6) (2026-05-23)
|
|
2
2
|
|
|
3
3
|
### Bug Fixes
|
|
4
4
|
|
|
5
|
-
* **
|
|
5
|
+
* **client:** support Cloudflare Access service tokens via env vars ([4141f21](https://github.com/clickraft/cli/commit/4141f21a3c53f5795fef41f3bd876670563968f1))
|
|
6
6
|
|
|
7
7
|
# Changelog
|
|
8
8
|
|
package/README.md
CHANGED
|
@@ -21,6 +21,19 @@ clickraft generate create --prompt "a serene mountain landscape at dawn"
|
|
|
21
21
|
|
|
22
22
|
Full documentation: [docs.clickraft.ai/cli](https://docs.clickraft.ai/cli) _(coming soon)_
|
|
23
23
|
|
|
24
|
+
## Connecting to staging
|
|
25
|
+
|
|
26
|
+
The staging API (`https://staging.clickraft.ai/api/agents/v1`) sits behind Cloudflare Access Zero Trust. To authenticate non-interactively, create a service token in the Cloudflare Zero Trust dashboard (**Access → Service Auth → Service Tokens**), then export both halves before invoking the CLI:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
export CLOUDFLARE_ACCESS_CLIENT_ID="<client-id>.access"
|
|
30
|
+
export CLOUDFLARE_ACCESS_CLIENT_SECRET="<client-secret>"
|
|
31
|
+
|
|
32
|
+
clickraft tokens list --profile staging
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Both env vars must be set together — if only one is set the CLI exits with a configuration error. Production usage (the default) does not require these env vars.
|
|
36
|
+
|
|
24
37
|
## Use with AI coding agents
|
|
25
38
|
|
|
26
39
|
The Clickraft CLI is designed to work with Claude Code, Cursor, Codex, and other AI coding agents. Install the skills package for your agent:
|
package/dist/cli.js
CHANGED
|
@@ -529,6 +529,10 @@ var ApiClient = class {
|
|
|
529
529
|
if (this.options.accessToken) {
|
|
530
530
|
h.authorization = `Bearer ${this.options.accessToken}`;
|
|
531
531
|
}
|
|
532
|
+
if (this.options.cloudflareAccess) {
|
|
533
|
+
h["cf-access-client-id"] = this.options.cloudflareAccess.clientId;
|
|
534
|
+
h["cf-access-client-secret"] = this.options.cloudflareAccess.clientSecret;
|
|
535
|
+
}
|
|
532
536
|
if (opts.body !== void 0 && opts.method !== "GET" && opts.method !== "DELETE") {
|
|
533
537
|
h["content-type"] = "application/json";
|
|
534
538
|
}
|
|
@@ -1173,8 +1177,11 @@ var TOKEN_ENV_VAR = "CLICKRAFT_TOKEN";
|
|
|
1173
1177
|
var PROFILE_ENV_VAR = "CLICKRAFT_PROFILE";
|
|
1174
1178
|
var API_BASE_URL_ENV_VAR = "CLICKRAFT_API_BASE_URL";
|
|
1175
1179
|
var TELEMETRY_DISABLE_ENV_VAR = "CLICKRAFT_DISABLE_TELEMETRY";
|
|
1180
|
+
var CLOUDFLARE_ACCESS_CLIENT_ID_ENV_VAR = "CLOUDFLARE_ACCESS_CLIENT_ID";
|
|
1181
|
+
var CLOUDFLARE_ACCESS_CLIENT_SECRET_ENV_VAR = "CLOUDFLARE_ACCESS_CLIENT_SECRET";
|
|
1176
1182
|
async function loadConfig(options = {}) {
|
|
1177
1183
|
const env = options.env ?? process.env;
|
|
1184
|
+
const cloudflareAccess = loadCloudflareAccess(env);
|
|
1178
1185
|
const flagToken = trim(options.flagToken);
|
|
1179
1186
|
const envToken = trim(env[TOKEN_ENV_VAR]);
|
|
1180
1187
|
const flagProfile = trim(options.flagProfile);
|
|
@@ -1204,9 +1211,26 @@ async function loadConfig(options = {}) {
|
|
|
1204
1211
|
return {
|
|
1205
1212
|
accessToken: tokenFromFlagOrEnv ?? fileAccessToken ?? null,
|
|
1206
1213
|
profileName: profileName ?? fileProfileName ?? DEFAULT_PROFILE_NAME,
|
|
1207
|
-
apiBaseUrl: apiBaseFromFlagOrEnv ?? fileApiBaseUrl ?? DEFAULT_API_BASE_URL
|
|
1214
|
+
apiBaseUrl: apiBaseFromFlagOrEnv ?? fileApiBaseUrl ?? DEFAULT_API_BASE_URL,
|
|
1215
|
+
cloudflareAccess
|
|
1208
1216
|
};
|
|
1209
1217
|
}
|
|
1218
|
+
function loadCloudflareAccess(env) {
|
|
1219
|
+
const clientId = trim(env[CLOUDFLARE_ACCESS_CLIENT_ID_ENV_VAR]);
|
|
1220
|
+
const clientSecret = trim(env[CLOUDFLARE_ACCESS_CLIENT_SECRET_ENV_VAR]);
|
|
1221
|
+
if (clientId && clientSecret) {
|
|
1222
|
+
return { clientId, clientSecret };
|
|
1223
|
+
}
|
|
1224
|
+
if (!clientId && !clientSecret) {
|
|
1225
|
+
return null;
|
|
1226
|
+
}
|
|
1227
|
+
const onlySet = clientId ? CLOUDFLARE_ACCESS_CLIENT_ID_ENV_VAR : CLOUDFLARE_ACCESS_CLIENT_SECRET_ENV_VAR;
|
|
1228
|
+
throw new ApiError(
|
|
1229
|
+
"INPUT_INVALID_FORMAT",
|
|
1230
|
+
`${CLOUDFLARE_ACCESS_CLIENT_ID_ENV_VAR} and ${CLOUDFLARE_ACCESS_CLIENT_SECRET_ENV_VAR} must both be set, or neither. Got only ${onlySet}.`,
|
|
1231
|
+
{ retryable: false }
|
|
1232
|
+
);
|
|
1233
|
+
}
|
|
1210
1234
|
function trim(value) {
|
|
1211
1235
|
if (value === void 0) return void 0;
|
|
1212
1236
|
const t = value.trim();
|
|
@@ -1300,7 +1324,8 @@ async function buildClient(opts) {
|
|
|
1300
1324
|
return new ApiClient({
|
|
1301
1325
|
apiBaseUrl: cfg.apiBaseUrl,
|
|
1302
1326
|
accessToken: cfg.accessToken,
|
|
1303
|
-
signal: opts.signal
|
|
1327
|
+
signal: opts.signal,
|
|
1328
|
+
cloudflareAccess: cfg.cloudflareAccess
|
|
1304
1329
|
});
|
|
1305
1330
|
}
|
|
1306
1331
|
async function postAssetMetadata(args) {
|
|
@@ -1466,7 +1491,8 @@ async function buildGenerateClient(opts) {
|
|
|
1466
1491
|
return new ApiClient({
|
|
1467
1492
|
apiBaseUrl: cfg.apiBaseUrl,
|
|
1468
1493
|
accessToken: cfg.accessToken,
|
|
1469
|
-
signal: opts.signal
|
|
1494
|
+
signal: opts.signal,
|
|
1495
|
+
cloudflareAccess: cfg.cloudflareAccess
|
|
1470
1496
|
});
|
|
1471
1497
|
}
|
|
1472
1498
|
function isUrlLike(value) {
|
|
@@ -2073,7 +2099,12 @@ async function logout(options) {
|
|
|
2073
2099
|
let serverRevoked = false;
|
|
2074
2100
|
let revokeFailureMessage;
|
|
2075
2101
|
if (options.revoke) {
|
|
2076
|
-
const factory = options.apiClientFactory ?? ((apiBaseUrl, accessToken) => new ApiClient({
|
|
2102
|
+
const factory = options.apiClientFactory ?? ((apiBaseUrl, accessToken) => new ApiClient({
|
|
2103
|
+
apiBaseUrl,
|
|
2104
|
+
accessToken,
|
|
2105
|
+
signal: options.signal,
|
|
2106
|
+
cloudflareAccess: config.cloudflareAccess
|
|
2107
|
+
}));
|
|
2077
2108
|
const client = factory(profile.apiBaseUrl, profile.accessToken);
|
|
2078
2109
|
try {
|
|
2079
2110
|
await client.request({
|
|
@@ -2198,7 +2229,12 @@ async function listTokens(options) {
|
|
|
2198
2229
|
if (!config.accessToken) {
|
|
2199
2230
|
throw new AuthError("AUTH_TOKEN_MISSING", `Not authenticated. Run \`clickraft login\` first.`);
|
|
2200
2231
|
}
|
|
2201
|
-
const factory = options.apiClientFactory ?? ((apiBaseUrl, accessToken) => new ApiClient({
|
|
2232
|
+
const factory = options.apiClientFactory ?? ((apiBaseUrl, accessToken) => new ApiClient({
|
|
2233
|
+
apiBaseUrl,
|
|
2234
|
+
accessToken,
|
|
2235
|
+
signal: options.signal,
|
|
2236
|
+
cloudflareAccess: config.cloudflareAccess
|
|
2237
|
+
}));
|
|
2202
2238
|
const client = factory(config.apiBaseUrl, config.accessToken);
|
|
2203
2239
|
const data = await client.request({
|
|
2204
2240
|
method: "GET",
|