pixelvault-cli 0.1.0 → 0.2.0
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 +30 -5
- package/dist/index.js +6 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
# pixelvault
|
|
1
|
+
# pixelvault-cli
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/pixelvault-cli)
|
|
4
|
+
[](https://github.com/pixelvault-dev/cli/actions/workflows/ci.yml)
|
|
2
5
|
|
|
3
6
|
CLI for [PixelVault](https://pixelvault.dev) — agent-first image hosting for developers and AI coding agents.
|
|
4
7
|
|
|
5
8
|
## Install
|
|
6
9
|
|
|
7
10
|
```bash
|
|
8
|
-
npm install -g pixelvault
|
|
11
|
+
npm install -g pixelvault-cli
|
|
9
12
|
```
|
|
10
13
|
|
|
11
14
|
Or use directly with `npx`:
|
|
12
15
|
|
|
13
16
|
```bash
|
|
14
|
-
npx pixelvault upload photo.jpg
|
|
17
|
+
npx pixelvault-cli upload photo.jpg
|
|
15
18
|
```
|
|
16
19
|
|
|
17
20
|
## Quick Start
|
|
@@ -30,6 +33,11 @@ pixelvault upload *.png --folder screenshots
|
|
|
30
33
|
# List your images
|
|
31
34
|
pixelvault list
|
|
32
35
|
|
|
36
|
+
# Get an image's URL, or download it (optionally transformed)
|
|
37
|
+
pixelvault get img_xyz # prints the CDN URL
|
|
38
|
+
pixelvault get img_xyz -o photo.png # download the original
|
|
39
|
+
pixelvault get img_xyz -o thumb.webp -t "w=400&fmt=webp" # download a transformed variant
|
|
40
|
+
|
|
33
41
|
# Delete an image
|
|
34
42
|
pixelvault delete img_xyz
|
|
35
43
|
```
|
|
@@ -46,7 +54,7 @@ The CLI is designed for AI coding agents. Output contract:
|
|
|
46
54
|
|
|
47
55
|
```bash
|
|
48
56
|
# In agent workflows
|
|
49
|
-
URL=$(npx pixelvault upload screenshot.png)
|
|
57
|
+
URL=$(npx pixelvault-cli upload screenshot.png)
|
|
50
58
|
echo "Uploaded to: $URL"
|
|
51
59
|
```
|
|
52
60
|
|
|
@@ -56,7 +64,7 @@ For CI/CD and headless agent usage:
|
|
|
56
64
|
|
|
57
65
|
```bash
|
|
58
66
|
export PIXELVAULT_API_KEY=pv_live_xxx
|
|
59
|
-
npx pixelvault upload build-output.png
|
|
67
|
+
npx pixelvault-cli upload build-output.png
|
|
60
68
|
```
|
|
61
69
|
|
|
62
70
|
## Commands
|
|
@@ -67,6 +75,7 @@ npx pixelvault upload build-output.png
|
|
|
67
75
|
| `login` | Log in to existing account |
|
|
68
76
|
| `upload <files...>` | Upload images (prints URLs to stdout) |
|
|
69
77
|
| `list` | List uploaded images |
|
|
78
|
+
| `get <id>` | Get an image's URL/metadata, or download it (optionally transformed) |
|
|
70
79
|
| `delete <id>` | Delete an image |
|
|
71
80
|
| `whoami` | Show current auth state |
|
|
72
81
|
| `config get\|set\|show` | Manage CLI configuration |
|
|
@@ -79,6 +88,22 @@ pixelvault upload *.png --folder icons # Bulk with folder
|
|
|
79
88
|
pixelvault upload shot.png --json # Full JSON response
|
|
80
89
|
```
|
|
81
90
|
|
|
91
|
+
### Get Options
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
pixelvault get img_xyz # print the CDN URL to stdout
|
|
95
|
+
pixelvault get img_xyz --json # full metadata
|
|
96
|
+
pixelvault get img_xyz -o photo.png # download the original to a file
|
|
97
|
+
pixelvault get img_xyz -o cut.png -t "segment=foreground" # download a transparent cut-out
|
|
98
|
+
pixelvault get img_xyz -t "w=400&fmt=webp" # just print the transformed URL
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Transform params (`-t`/`--transform`) are the same URL params documented at
|
|
102
|
+
<https://pixelvault.dev/docs#transforms> — resize (`w`/`h`/`fit`), format (`fmt`),
|
|
103
|
+
background removal (`segment=foreground`), effects (`blur`/`saturation`/`rotate`/…),
|
|
104
|
+
and watermark (`tile=img_logo.png` — another of your own images). Reserved
|
|
105
|
+
characters in values are percent-encoded for you (e.g. `background=#ffaa00`).
|
|
106
|
+
|
|
82
107
|
### List Options
|
|
83
108
|
|
|
84
109
|
```bash
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
var
|
|
2
|
-
`)}function
|
|
3
|
-
`)}function
|
|
4
|
-
`,{mode:384})}function
|
|
5
|
-
`||
|
|
6
|
-
`),
|
|
1
|
+
var Q=Object.defineProperty;var m=(e,o)=>()=>(e&&(o=e(e=0)),o);var g=(e,o)=>{for(var r in o)Q(e,r,{get:o[r],enumerable:!0})};var c,v=m(()=>{"use strict";c=class extends Error{exitCode;constructor(o,r=1){super(o),this.name="CliError",this.exitCode=r}}});function p(e){process.stdout.write(e+`
|
|
2
|
+
`)}function n(e){process.stderr.write(e+`
|
|
3
|
+
`)}function f(e){p(JSON.stringify(e,null,2))}var u=m(()=>{"use strict"});import{readFileSync as W,writeFileSync as Z,mkdirSync as ee}from"fs";import{join as A}from"path";import{homedir as te}from"os";function I(){return R}function y(){try{let e=W(R,"utf-8");return JSON.parse(e)}catch{return{}}}function oe(e){ee(S,{recursive:!0,mode:448}),Z(R,JSON.stringify(e,null,2)+`
|
|
4
|
+
`,{mode:384})}function w(e){let o=y();oe({...o,...e})}function E(){return process.env.PIXELVAULT_API_KEY||y().api_key}function L(){return process.env.PIXELVAULT_API_URL||y().api_url||re}function h(){let e=E();if(!e)throw new Error("Not authenticated. Run `pixelvault register` or `pixelvault login`, or set PIXELVAULT_API_KEY.");return e}var S,R,re,l=m(()=>{"use strict";S=A(te(),".pixelvault"),R=A(S,"config.json"),re="https://api.pixelvault.dev"});async function d(e){let r=`${L()}${e.path}`,t={...e.headers};e.auth&&(t.Authorization=`Bearer ${e.auth}`);let i;e.formData?i=e.formData:e.body&&(t["Content-Type"]="application/json",i=JSON.stringify(e.body));let s;try{s=await fetch(r,{method:e.method||"GET",headers:t,body:i})}catch(a){throw new c(`Network error: ${a instanceof Error?a.message:"Failed to connect"}`,1)}if(!s.ok){let a;try{a=await s.json()}catch{}let k=a?.error?.message||`HTTP ${s.status}: ${s.statusText}`;throw new c(k,1)}return await s.json()}var _=m(()=>{"use strict";l();v()});import{createInterface as ie}from"readline";function x(e){let o=ie({input:process.stdin,output:process.stderr});return new Promise(r=>{o.question(e,t=>{o.close(),r(t.trim())})})}async function j(e){return process.stdin.isTTY?new Promise(o=>{process.stderr.write(e),process.stdin.setRawMode(!0),process.stdin.resume(),process.stdin.setEncoding("utf-8");let r="",t=i=>{i===`
|
|
5
|
+
`||i==="\r"||i===""?(process.stdin.setRawMode(!1),process.stdin.pause(),process.stdin.removeListener("data",t),process.stderr.write(`
|
|
6
|
+
`),o(r)):i===""?(process.stdin.setRawMode(!1),process.exit(130)):i==="\x7F"||i==="\b"?r=r.slice(0,-1):r+=i};process.stdin.on("data",t)}):x(e)}var $=m(()=>{"use strict"});var O={};g(O,{default:()=>ae});import{defineCommand as ne}from"citty";var ae,T=m(()=>{"use strict";_();l();$();u();ae=ne({meta:{name:"register",description:"Create a new PixelVault account"},args:{email:{type:"string",description:"Email address"},password:{type:"string",description:"Password (min 8 characters)"}},async run({args:e}){let o=e.email||await x("Email: "),r=e.password||await j("Password: ");(!o||!r)&&(n("Email and password are required."),process.exit(1)),r.length<8&&(n("Password must be at least 8 characters."),process.exit(1)),n("Creating account...");let t=await d({method:"POST",path:"/v1/auth/register",body:{email:o,password:r}});w({api_key:t.data.default_project.api_keys.live,default_project:t.data.default_project.id,email:t.data.email}),n("Account created. API key saved to ~/.pixelvault/config.json"),n(`Email: ${t.data.email}`),n(`Project: ${t.data.default_project.id}`),t.data.email_verified||n("Check your email to verify your account before uploading.")}})});var q={};g(q,{default:()=>pe});import{defineCommand as se}from"citty";var pe,K=m(()=>{"use strict";_();l();$();u();pe=se({meta:{name:"login",description:"Log in to your PixelVault account"},args:{email:{type:"string",description:"Email address"},password:{type:"string",description:"Password"}},async run({args:e}){let o=e.email||await x("Email: "),r=e.password||await j("Password: ");(!o||!r)&&(n("Email and password are required."),process.exit(1)),n("Logging in...");let t=await d({method:"POST",path:"/v1/auth/login",body:{email:o,password:r}}),i=t.data.token,s;try{s=(await d({method:"GET",path:"/v1/projects",auth:i})).data[0]?.id}catch{}if(s){let a=await d({method:"POST",path:"/v1/auth/rotate-key",auth:i,body:{project_id:s}});w({api_key:a.data.api_key,default_project:s,email:t.data.email}),n("Logged in. API key saved to ~/.pixelvault/config.json"),n(`Email: ${t.data.email}`),n(`Project: ${s}`)}else n(`Logged in as ${t.data.email}.`),n("Could not auto-configure API key. Set PIXELVAULT_API_KEY manually."),w({email:t.data.email})}})});var U={};g(U,{default:()=>fe});import{defineCommand as de}from"citty";import{readFileSync as me}from"fs";import{basename as ce}from"path";var fe,F=m(()=>{"use strict";_();l();u();fe=de({meta:{name:"upload",description:"Upload one or more images"},args:{files:{type:"positional",description:"File path(s) to upload",required:!0},folder:{type:"string",description:"Folder to organize images in"},json:{type:"boolean",description:"Output full JSON response",default:!1}},async run({args:e}){let o=h(),r=Array.isArray(e.files)?e.files:[e.files],t=!1,i=[];for(let s of r)try{let a=me(s),k=ce(s),C=new FormData;C.append("file",new File([a],k)),e.folder&&C.append("folder",e.folder);let b=await d({method:"POST",path:"/v1/images",auth:o,formData:C});e.json?i.push(b.data):p(b.data.url)}catch(a){t=!0,n(`Failed to upload ${s}: ${a instanceof Error?a.message:String(a)}`)}e.json&&i.length>0&&f(i.length===1?i[0]:i),t&&process.exit(1)}})});var D={};g(D,{default:()=>ue});import{defineCommand as le}from"citty";var ue,N=m(()=>{"use strict";_();l();u();ue=le({meta:{name:"list",description:"List uploaded images"},args:{page:{type:"string",description:"Page number",default:"1"},"per-page":{type:"string",description:"Items per page (max 100)",default:"20"},json:{type:"boolean",description:"Output full JSON response",default:!1}},async run({args:e}){let o=h(),r=new URLSearchParams({page:e.page,per_page:e["per-page"]}),t=await d({path:`/v1/images?${r}`,auth:o});if(e.json)f(t);else for(let i of t.data)p(i.url)}})});var J={};g(J,{applyTransform:()=>G,default:()=>he});import{defineCommand as ge}from"citty";import{writeFileSync as ye}from"fs";function G(e,o){if(!o)return e;let r=o.trim().replace(/^[?&]+/,"");if(!r)return e;let t=new URLSearchParams(r).toString();return t?e.includes("?")?`${e}&${t}`:`${e}?${t}`:e}var he,V=m(()=>{"use strict";_();l();u();v();he=ge({meta:{name:"get",description:"Get an image's CDN URL or metadata, or download it \u2014 optionally transformed"},args:{id:{type:"positional",description:"Image ID (e.g. img_abc123)",required:!0},output:{type:"string",description:"Download the image to this file path",alias:"o"},transform:{type:"string",description:'Transform params to apply, e.g. "w=400&fmt=webp", "segment=foreground", "tile=img_logo.png"',alias:"t"},json:{type:"boolean",description:"Output full JSON metadata",default:!1}},async run({args:e}){let o=h(),r=await d({path:`/v1/images/${encodeURIComponent(e.id)}`,auth:o}),t=G(r.data.url,e.transform);if(e.output){let i=e.output,s;try{let a=await fetch(t);if(!a.ok)throw new c(`Failed to download image: HTTP ${a.status}`,1);s=await a.arrayBuffer()}catch(a){throw a instanceof c?a:new c(`Failed to download image: ${a instanceof Error?a.message:String(a)}`,1)}if(s.byteLength===0)throw new c("Downloaded 0 bytes \u2014 refusing to write an empty file",1);try{ye(i,Buffer.from(s))}catch(a){throw new c(`Failed to save ${i}: ${a instanceof Error?a.message:String(a)}`,1)}n(`Saved ${i}`),e.json?f(e.transform?{...r,transformed_url:t,output:i}:{...r,output:i}):p(t);return}e.json?f(e.transform?{...r,transformed_url:t}:r):p(t)}})});var B={};g(B,{default:()=>_e});import{defineCommand as we}from"citty";var _e,z=m(()=>{"use strict";_();l();_e=we({meta:{name:"delete",description:"Delete an image by ID"},args:{id:{type:"positional",description:"Image ID (e.g. img_abc123)",required:!0}},async run({args:e}){let o=h();await d({method:"DELETE",path:`/v1/images/${e.id}`,auth:o})}})});var M={};g(M,{default:()=>ve});import{defineCommand as xe}from"citty";var ve,X=m(()=>{"use strict";l();u();ve=xe({meta:{name:"whoami",description:"Show current authentication state"},args:{json:{type:"boolean",description:"Output as JSON",default:!1}},async run({args:e}){let o=y(),r=E();!r&&!o.email&&(n("Not authenticated. Run `pixelvault register` or `pixelvault login`."),process.exit(1));let t={email:o.email||"(unknown)",project:o.default_project||"(unknown)",api_key:r?`${r.slice(0,12)}...${r.slice(-4)}`:"(not set)",source:process.env.PIXELVAULT_API_KEY?"env":"config"};e.json?f(t):(p(`Email: ${t.email}`),p(`Project: ${t.project}`),p(`API Key: ${t.api_key} (${t.source})`))}})});var Y={};g(Y,{default:()=>Ce});import{defineCommand as P}from"citty";var je,Pe,ke,Ce,H=m(()=>{"use strict";l();u();je=P({meta:{name:"get",description:"Get a config value"},args:{key:{type:"positional",description:"Config key (api_key, default_project, email, api_url)",required:!0}},async run({args:e}){let r=y()[e.key];r===void 0&&(n(`Key "${e.key}" is not set.`),process.exit(1)),p(String(r))}}),Pe=P({meta:{name:"set",description:"Set a config value"},args:{key:{type:"positional",description:"Config key",required:!0},value:{type:"positional",description:"Config value",required:!0}},async run({args:e}){let o=["api_key","default_project","email","api_url"];o.includes(e.key)||(n(`Invalid key. Valid keys: ${o.join(", ")}`),process.exit(1)),w({[e.key]:e.value}),n(`Set ${e.key} = ${e.key==="api_key"?"***":e.value}`)}}),ke=P({meta:{name:"show",description:"Show all config values"},args:{json:{type:"boolean",description:"Output as JSON",default:!1}},async run({args:e}){let o=y();if(e.json)f(o);else{n(`Config: ${I()}`);for(let[r,t]of Object.entries(o)){let i=r==="api_key"&&t?`${t.slice(0,12)}...`:t;p(`${r} = ${i}`)}}}}),Ce=P({meta:{name:"config",description:"Manage CLI configuration"},subCommands:{get:je,set:Pe,show:ke}})});v();u();import{defineCommand as Re,runMain as Ee}from"citty";var $e=Re({meta:{name:"pixelvault",version:"0.2.0",description:"CLI for PixelVault \u2014 agent-first image hosting"},subCommands:{register:()=>Promise.resolve().then(()=>(T(),O)).then(e=>e.default),login:()=>Promise.resolve().then(()=>(K(),q)).then(e=>e.default),upload:()=>Promise.resolve().then(()=>(F(),U)).then(e=>e.default),list:()=>Promise.resolve().then(()=>(N(),D)).then(e=>e.default),get:()=>Promise.resolve().then(()=>(V(),J)).then(e=>e.default),delete:()=>Promise.resolve().then(()=>(z(),B)).then(e=>e.default),whoami:()=>Promise.resolve().then(()=>(X(),M)).then(e=>e.default),config:()=>Promise.resolve().then(()=>(H(),Y)).then(e=>e.default)}});Ee($e).catch(e=>{e instanceof c&&(n(`Error: ${e.message}`),process.exit(e.exitCode)),n(`Error: ${e instanceof Error?e.message:String(e)}`),process.exit(1)});
|
|
7
7
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/errors.ts","../src/lib/output.ts","../src/lib/config.ts","../src/lib/client.ts","../src/lib/prompt.ts","../src/commands/register.ts","../src/commands/login.ts","../src/commands/upload.ts","../src/commands/list.ts","../src/commands/delete.ts","../src/commands/whoami.ts","../src/commands/config.ts","../src/index.ts"],"sourcesContent":["export class CliError extends Error {\n exitCode: number;\n\n constructor(message: string, exitCode = 1) {\n super(message);\n this.name = \"CliError\";\n this.exitCode = exitCode;\n }\n}\n","/**\n * Write to stdout (for machine-parseable output — URLs, JSON).\n */\nexport function stdout(text: string): void {\n process.stdout.write(text + \"\\n\");\n}\n\n/**\n * Write to stderr (for human messages — prompts, progress, errors).\n */\nexport function stderr(text: string): void {\n process.stderr.write(text + \"\\n\");\n}\n\n/**\n * Output data as JSON to stdout.\n */\nexport function jsonOut(data: unknown): void {\n stdout(JSON.stringify(data, null, 2));\n}\n\n/**\n * Print an error message to stderr and exit.\n */\nexport function fatal(message: string, exitCode = 1): never {\n stderr(`Error: ${message}`);\n process.exit(exitCode);\n}\n","import { readFileSync, writeFileSync, mkdirSync, chmodSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\nexport interface Config {\n api_key?: string;\n default_project?: string;\n email?: string;\n api_url?: string;\n}\n\nconst CONFIG_DIR = join(homedir(), \".pixelvault\");\nconst CONFIG_FILE = join(CONFIG_DIR, \"config.json\");\nconst DEFAULT_API_URL = \"https://api.pixelvault.dev\";\n\nexport function getConfigPath(): string {\n return CONFIG_FILE;\n}\n\nexport function readConfig(): Config {\n try {\n const raw = readFileSync(CONFIG_FILE, \"utf-8\");\n return JSON.parse(raw) as Config;\n } catch {\n return {};\n }\n}\n\nexport function writeConfig(config: Config): void {\n mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });\n writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2) + \"\\n\", {\n mode: 0o600,\n });\n}\n\nexport function updateConfig(updates: Partial<Config>): void {\n const config = readConfig();\n writeConfig({ ...config, ...updates });\n}\n\nexport function getApiKey(): string | undefined {\n return process.env[\"PIXELVAULT_API_KEY\"] || readConfig().api_key;\n}\n\nexport function getApiUrl(): string {\n return (\n process.env[\"PIXELVAULT_API_URL\"] ||\n readConfig().api_url ||\n DEFAULT_API_URL\n );\n}\n\nexport function requireApiKey(): string {\n const key = getApiKey();\n if (!key) {\n throw new Error(\n \"Not authenticated. Run `pixelvault register` or `pixelvault login`, or set PIXELVAULT_API_KEY.\"\n );\n }\n return key;\n}\n","import { getApiUrl } from \"./config.js\";\nimport { CliError } from \"./errors.js\";\n\ninterface RequestOptions {\n method?: string;\n path: string;\n body?: unknown;\n headers?: Record<string, string>;\n formData?: FormData;\n}\n\ninterface ApiError {\n error: { code: string; message: string };\n}\n\nexport async function apiRequest<T>(\n options: RequestOptions & { auth?: string }\n): Promise<T> {\n const baseUrl = getApiUrl();\n const url = `${baseUrl}${options.path}`;\n\n const headers: Record<string, string> = { ...options.headers };\n\n if (options.auth) {\n headers[\"Authorization\"] = `Bearer ${options.auth}`;\n }\n\n let fetchBody: BodyInit | undefined;\n\n if (options.formData) {\n fetchBody = options.formData;\n } else if (options.body) {\n headers[\"Content-Type\"] = \"application/json\";\n fetchBody = JSON.stringify(options.body);\n }\n\n let res: Response;\n try {\n res = await fetch(url, {\n method: options.method || \"GET\",\n headers,\n body: fetchBody,\n });\n } catch (err) {\n throw new CliError(\n `Network error: ${err instanceof Error ? err.message : \"Failed to connect\"}`,\n 1\n );\n }\n\n if (!res.ok) {\n let errorBody: ApiError | undefined;\n try {\n errorBody = (await res.json()) as ApiError;\n } catch {\n // ignore parse failures\n }\n\n const message =\n errorBody?.error?.message || `HTTP ${res.status}: ${res.statusText}`;\n throw new CliError(message, 1);\n }\n\n return (await res.json()) as T;\n}\n","import { createInterface } from \"node:readline\";\n\n/**\n * Prompt the user for input via stderr (keeps stdout clean for agents).\n */\nexport function prompt(question: string): Promise<string> {\n const rl = createInterface({\n input: process.stdin,\n output: process.stderr,\n });\n\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\n/**\n * Prompt for a password (input is not echoed).\n * Uses raw mode to suppress echo when available, falls back to regular prompt.\n */\nexport async function promptPassword(question: string): Promise<string> {\n if (!process.stdin.isTTY) {\n return prompt(question);\n }\n\n return new Promise((resolve) => {\n process.stderr.write(question);\n process.stdin.setRawMode(true);\n process.stdin.resume();\n process.stdin.setEncoding(\"utf-8\");\n\n let password = \"\";\n\n const onData = (char: string) => {\n if (char === \"\\n\" || char === \"\\r\" || char === \"\\u0004\") {\n process.stdin.setRawMode(false);\n process.stdin.pause();\n process.stdin.removeListener(\"data\", onData);\n process.stderr.write(\"\\n\");\n resolve(password);\n } else if (char === \"\\u0003\") {\n // Ctrl+C\n process.stdin.setRawMode(false);\n process.exit(130);\n } else if (\n char === \"\\u007F\" ||\n char === \"\\b\"\n ) {\n // Backspace\n password = password.slice(0, -1);\n } else {\n password += char;\n }\n };\n\n process.stdin.on(\"data\", onData);\n });\n}\n","import { defineCommand } from \"citty\";\nimport { apiRequest } from \"../lib/client.js\";\nimport { updateConfig } from \"../lib/config.js\";\nimport { prompt, promptPassword } from \"../lib/prompt.js\";\nimport { stderr } from \"../lib/output.js\";\n\ninterface RegisterResponse {\n data: {\n account_id: string;\n email: string;\n email_verified: boolean;\n plan: string;\n default_project: {\n id: string;\n name: string;\n api_keys: { live: string };\n };\n };\n}\n\nexport default defineCommand({\n meta: {\n name: \"register\",\n description: \"Create a new PixelVault account\",\n },\n args: {\n email: {\n type: \"string\",\n description: \"Email address\",\n },\n password: {\n type: \"string\",\n description: \"Password (min 8 characters)\",\n },\n },\n async run({ args }) {\n const email = args.email || (await prompt(\"Email: \"));\n const password = args.password || (await promptPassword(\"Password: \"));\n\n if (!email || !password) {\n stderr(\"Email and password are required.\");\n process.exit(1);\n }\n\n if (password.length < 8) {\n stderr(\"Password must be at least 8 characters.\");\n process.exit(1);\n }\n\n stderr(\"Creating account...\");\n\n const res = await apiRequest<RegisterResponse>({\n method: \"POST\",\n path: \"/v1/auth/register\",\n body: { email, password },\n });\n\n updateConfig({\n api_key: res.data.default_project.api_keys.live,\n default_project: res.data.default_project.id,\n email: res.data.email,\n });\n\n stderr(`Account created. API key saved to ~/.pixelvault/config.json`);\n stderr(`Email: ${res.data.email}`);\n stderr(`Project: ${res.data.default_project.id}`);\n\n if (!res.data.email_verified) {\n stderr(\"Check your email to verify your account before uploading.\");\n }\n },\n});\n","import { defineCommand } from \"citty\";\nimport { apiRequest } from \"../lib/client.js\";\nimport { updateConfig, getApiUrl } from \"../lib/config.js\";\nimport { prompt, promptPassword } from \"../lib/prompt.js\";\nimport { stderr } from \"../lib/output.js\";\n\ninterface LoginResponse {\n data: {\n token: string;\n account_id: string;\n email: string;\n email_verified: boolean;\n };\n}\n\ninterface RotateKeyResponse {\n data: {\n key_id: string;\n api_key: string;\n project_id: string;\n environment: string;\n };\n}\n\ninterface ProjectsResponse {\n data: Array<{ id: string; name: string }>;\n}\n\nexport default defineCommand({\n meta: {\n name: \"login\",\n description: \"Log in to your PixelVault account\",\n },\n args: {\n email: {\n type: \"string\",\n description: \"Email address\",\n },\n password: {\n type: \"string\",\n description: \"Password\",\n },\n },\n async run({ args }) {\n const email = args.email || (await prompt(\"Email: \"));\n const password = args.password || (await promptPassword(\"Password: \"));\n\n if (!email || !password) {\n stderr(\"Email and password are required.\");\n process.exit(1);\n }\n\n stderr(\"Logging in...\");\n\n // Step 1: Login to get JWT\n const loginRes = await apiRequest<LoginResponse>({\n method: \"POST\",\n path: \"/v1/auth/login\",\n body: { email, password },\n });\n\n const token = loginRes.data.token;\n\n // Step 2: Get projects to find default project ID\n let projectId: string | undefined;\n try {\n const projectsRes = await apiRequest<ProjectsResponse>({\n method: \"GET\",\n path: \"/v1/projects\",\n auth: token,\n });\n projectId = projectsRes.data[0]?.id;\n } catch {\n // Projects endpoint may not exist yet — continue without project ID\n }\n\n // Step 3: Rotate key to get a fresh API key\n if (projectId) {\n const rotateRes = await apiRequest<RotateKeyResponse>({\n method: \"POST\",\n path: \"/v1/auth/rotate-key\",\n auth: token,\n body: { project_id: projectId },\n });\n\n updateConfig({\n api_key: rotateRes.data.api_key,\n default_project: projectId,\n email: loginRes.data.email,\n });\n\n stderr(`Logged in. API key saved to ~/.pixelvault/config.json`);\n stderr(`Email: ${loginRes.data.email}`);\n stderr(`Project: ${projectId}`);\n } else {\n // Fallback: save JWT for manual key setup\n stderr(`Logged in as ${loginRes.data.email}.`);\n stderr(\n `Could not auto-configure API key. Set PIXELVAULT_API_KEY manually.`\n );\n updateConfig({ email: loginRes.data.email });\n }\n },\n});\n","import { defineCommand } from \"citty\";\nimport { readFileSync } from \"node:fs\";\nimport { basename } from \"node:path\";\nimport { apiRequest } from \"../lib/client.js\";\nimport { requireApiKey } from \"../lib/config.js\";\nimport { stdout, stderr, jsonOut } from \"../lib/output.js\";\n\ninterface UploadResponse {\n data: {\n id: string;\n url: string;\n mime_type: string;\n size: number;\n filename: string;\n folder: string | null;\n created_at: string;\n };\n}\n\nexport default defineCommand({\n meta: {\n name: \"upload\",\n description: \"Upload one or more images\",\n },\n args: {\n files: {\n type: \"positional\",\n description: \"File path(s) to upload\",\n required: true,\n },\n folder: {\n type: \"string\",\n description: \"Folder to organize images in\",\n },\n json: {\n type: \"boolean\",\n description: \"Output full JSON response\",\n default: false,\n },\n },\n async run({ args }) {\n const apiKey = requireApiKey();\n\n // citty passes positional as a single string; we handle globs via shell expansion\n const files = Array.isArray(args.files) ? args.files : [args.files];\n let hadError = false;\n\n const results: UploadResponse[\"data\"][] = [];\n\n for (const filePath of files) {\n try {\n const buffer = readFileSync(filePath);\n const fileName = basename(filePath);\n\n const formData = new FormData();\n formData.append(\n \"file\",\n new File([buffer], fileName)\n );\n\n if (args.folder) {\n formData.append(\"folder\", args.folder);\n }\n\n const res = await apiRequest<UploadResponse>({\n method: \"POST\",\n path: \"/v1/images\",\n auth: apiKey,\n formData,\n });\n\n if (args.json) {\n results.push(res.data);\n } else {\n stdout(res.data.url);\n }\n } catch (err) {\n hadError = true;\n stderr(\n `Failed to upload ${filePath}: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n\n if (args.json && results.length > 0) {\n jsonOut(results.length === 1 ? results[0] : results);\n }\n\n if (hadError) {\n process.exit(1);\n }\n },\n});\n","import { defineCommand } from \"citty\";\nimport { apiRequest } from \"../lib/client.js\";\nimport { requireApiKey } from \"../lib/config.js\";\nimport { stdout, jsonOut } from \"../lib/output.js\";\n\ninterface ListResponse {\n data: Array<{\n id: string;\n url: string;\n mime_type: string;\n size: number;\n filename: string;\n folder: string | null;\n created_at: string;\n }>;\n meta: {\n total: number;\n page: number;\n per_page: number;\n };\n}\n\nexport default defineCommand({\n meta: {\n name: \"list\",\n description: \"List uploaded images\",\n },\n args: {\n page: {\n type: \"string\",\n description: \"Page number\",\n default: \"1\",\n },\n \"per-page\": {\n type: \"string\",\n description: \"Items per page (max 100)\",\n default: \"20\",\n },\n json: {\n type: \"boolean\",\n description: \"Output full JSON response\",\n default: false,\n },\n },\n async run({ args }) {\n const apiKey = requireApiKey();\n\n const params = new URLSearchParams({\n page: args.page,\n per_page: args[\"per-page\"],\n });\n\n const res = await apiRequest<ListResponse>({\n path: `/v1/images?${params}`,\n auth: apiKey,\n });\n\n if (args.json) {\n jsonOut(res);\n } else {\n for (const img of res.data) {\n stdout(img.url);\n }\n }\n },\n});\n","import { defineCommand } from \"citty\";\nimport { apiRequest } from \"../lib/client.js\";\nimport { requireApiKey } from \"../lib/config.js\";\nimport { stderr } from \"../lib/output.js\";\n\nexport default defineCommand({\n meta: {\n name: \"delete\",\n description: \"Delete an image by ID\",\n },\n args: {\n id: {\n type: \"positional\",\n description: \"Image ID (e.g. img_abc123)\",\n required: true,\n },\n },\n async run({ args }) {\n const apiKey = requireApiKey();\n\n await apiRequest<{ success: boolean }>({\n method: \"DELETE\",\n path: `/v1/images/${args.id}`,\n auth: apiKey,\n });\n\n // Silent on success (agent-friendly)\n },\n});\n","import { defineCommand } from \"citty\";\nimport { readConfig, getApiKey } from \"../lib/config.js\";\nimport { stdout, stderr, jsonOut } from \"../lib/output.js\";\n\nexport default defineCommand({\n meta: {\n name: \"whoami\",\n description: \"Show current authentication state\",\n },\n args: {\n json: {\n type: \"boolean\",\n description: \"Output as JSON\",\n default: false,\n },\n },\n async run({ args }) {\n const config = readConfig();\n const apiKey = getApiKey();\n\n if (!apiKey && !config.email) {\n stderr(\"Not authenticated. Run `pixelvault register` or `pixelvault login`.\");\n process.exit(1);\n }\n\n const info = {\n email: config.email || \"(unknown)\",\n project: config.default_project || \"(unknown)\",\n api_key: apiKey\n ? `${apiKey.slice(0, 12)}...${apiKey.slice(-4)}`\n : \"(not set)\",\n source: process.env[\"PIXELVAULT_API_KEY\"] ? \"env\" : \"config\",\n };\n\n if (args.json) {\n jsonOut(info);\n } else {\n stdout(`Email: ${info.email}`);\n stdout(`Project: ${info.project}`);\n stdout(`API Key: ${info.api_key} (${info.source})`);\n }\n },\n});\n","import { defineCommand } from \"citty\";\nimport { readConfig, updateConfig, getConfigPath } from \"../lib/config.js\";\nimport { stdout, stderr, jsonOut } from \"../lib/output.js\";\n\nconst configGet = defineCommand({\n meta: {\n name: \"get\",\n description: \"Get a config value\",\n },\n args: {\n key: {\n type: \"positional\",\n description: \"Config key (api_key, default_project, email, api_url)\",\n required: true,\n },\n },\n async run({ args }) {\n const config = readConfig();\n const value = config[args.key as keyof typeof config];\n\n if (value === undefined) {\n stderr(`Key \"${args.key}\" is not set.`);\n process.exit(1);\n }\n\n stdout(String(value));\n },\n});\n\nconst configSet = defineCommand({\n meta: {\n name: \"set\",\n description: \"Set a config value\",\n },\n args: {\n key: {\n type: \"positional\",\n description: \"Config key\",\n required: true,\n },\n value: {\n type: \"positional\",\n description: \"Config value\",\n required: true,\n },\n },\n async run({ args }) {\n const validKeys = [\"api_key\", \"default_project\", \"email\", \"api_url\"];\n if (!validKeys.includes(args.key)) {\n stderr(`Invalid key. Valid keys: ${validKeys.join(\", \")}`);\n process.exit(1);\n }\n\n updateConfig({ [args.key]: args.value });\n stderr(`Set ${args.key} = ${args.key === \"api_key\" ? \"***\" : args.value}`);\n },\n});\n\nconst configShow = defineCommand({\n meta: {\n name: \"show\",\n description: \"Show all config values\",\n },\n args: {\n json: {\n type: \"boolean\",\n description: \"Output as JSON\",\n default: false,\n },\n },\n async run({ args }) {\n const config = readConfig();\n\n if (args.json) {\n jsonOut(config);\n } else {\n stderr(`Config: ${getConfigPath()}`);\n for (const [key, value] of Object.entries(config)) {\n const display = key === \"api_key\" && value\n ? `${(value as string).slice(0, 12)}...`\n : value;\n stdout(`${key} = ${display}`);\n }\n }\n },\n});\n\nexport default defineCommand({\n meta: {\n name: \"config\",\n description: \"Manage CLI configuration\",\n },\n subCommands: {\n get: configGet,\n set: configSet,\n show: configShow,\n },\n});\n","import { defineCommand, runMain } from \"citty\";\nimport { CliError } from \"./lib/errors.js\";\nimport { stderr } from \"./lib/output.js\";\n\nconst main = defineCommand({\n meta: {\n name: \"pixelvault\",\n version: \"0.1.0\",\n description: \"CLI for PixelVault — agent-first image hosting\",\n },\n subCommands: {\n register: () => import(\"./commands/register.js\").then((m) => m.default),\n login: () => import(\"./commands/login.js\").then((m) => m.default),\n upload: () => import(\"./commands/upload.js\").then((m) => m.default),\n list: () => import(\"./commands/list.js\").then((m) => m.default),\n delete: () => import(\"./commands/delete.js\").then((m) => m.default),\n whoami: () => import(\"./commands/whoami.js\").then((m) => m.default),\n config: () => import(\"./commands/config.js\").then((m) => m.default),\n },\n});\n\nrunMain(main).catch((err: unknown) => {\n if (err instanceof CliError) {\n stderr(`Error: ${err.message}`);\n process.exit(err.exitCode);\n }\n stderr(`Error: ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n});\n"],"mappings":"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","names":["CliError","init_errors","__esmMin","message","exitCode","stdout","text","stderr","jsonOut","data","init_output","__esmMin","readFileSync","writeFileSync","mkdirSync","join","homedir","getConfigPath","CONFIG_FILE","readConfig","raw","writeConfig","config","CONFIG_DIR","updateConfig","updates","getApiKey","getApiUrl","DEFAULT_API_URL","requireApiKey","key","init_config","__esmMin","apiRequest","options","url","getApiUrl","headers","fetchBody","res","err","CliError","errorBody","message","init_client","__esmMin","init_config","init_errors","createInterface","prompt","question","rl","resolve","answer","promptPassword","password","onData","char","init_prompt","__esmMin","register_exports","__export","register_default","defineCommand","init_register","__esmMin","init_client","init_config","init_prompt","init_output","args","email","prompt","password","promptPassword","stderr","res","apiRequest","updateConfig","login_exports","__export","login_default","defineCommand","init_login","__esmMin","init_client","init_config","init_prompt","init_output","args","email","prompt","password","promptPassword","stderr","loginRes","apiRequest","token","projectId","rotateRes","updateConfig","upload_exports","__export","upload_default","defineCommand","readFileSync","basename","init_upload","__esmMin","init_client","init_config","init_output","args","apiKey","requireApiKey","files","hadError","results","filePath","buffer","fileName","formData","res","apiRequest","stdout","err","stderr","jsonOut","list_exports","__export","list_default","defineCommand","init_list","__esmMin","init_client","init_config","init_output","args","apiKey","requireApiKey","params","res","apiRequest","jsonOut","img","stdout","delete_exports","__export","delete_default","defineCommand","init_delete","__esmMin","init_client","init_config","args","apiKey","requireApiKey","apiRequest","whoami_exports","__export","whoami_default","defineCommand","init_whoami","__esmMin","init_config","init_output","args","config","readConfig","apiKey","getApiKey","stderr","info","jsonOut","stdout","config_exports","__export","config_default","defineCommand","configGet","configSet","configShow","init_config","__esmMin","init_output","args","value","readConfig","stderr","stdout","validKeys","updateConfig","config","jsonOut","getConfigPath","key","display","init_errors","init_output","defineCommand","runMain","main","m","err","CliError","stderr"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/errors.ts","../src/lib/output.ts","../src/lib/config.ts","../src/lib/client.ts","../src/lib/prompt.ts","../src/commands/register.ts","../src/commands/login.ts","../src/commands/upload.ts","../src/commands/list.ts","../src/commands/get.ts","../src/commands/delete.ts","../src/commands/whoami.ts","../src/commands/config.ts","../src/index.ts"],"sourcesContent":["export class CliError extends Error {\n exitCode: number;\n\n constructor(message: string, exitCode = 1) {\n super(message);\n this.name = \"CliError\";\n this.exitCode = exitCode;\n }\n}\n","/**\n * Write to stdout (for machine-parseable output — URLs, JSON).\n */\nexport function stdout(text: string): void {\n process.stdout.write(text + \"\\n\");\n}\n\n/**\n * Write to stderr (for human messages — prompts, progress, errors).\n */\nexport function stderr(text: string): void {\n process.stderr.write(text + \"\\n\");\n}\n\n/**\n * Output data as JSON to stdout.\n */\nexport function jsonOut(data: unknown): void {\n stdout(JSON.stringify(data, null, 2));\n}\n\n/**\n * Print an error message to stderr and exit.\n */\nexport function fatal(message: string, exitCode = 1): never {\n stderr(`Error: ${message}`);\n process.exit(exitCode);\n}\n","import { readFileSync, writeFileSync, mkdirSync, chmodSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\n\nexport interface Config {\n api_key?: string;\n default_project?: string;\n email?: string;\n api_url?: string;\n}\n\nconst CONFIG_DIR = join(homedir(), \".pixelvault\");\nconst CONFIG_FILE = join(CONFIG_DIR, \"config.json\");\nconst DEFAULT_API_URL = \"https://api.pixelvault.dev\";\n\nexport function getConfigPath(): string {\n return CONFIG_FILE;\n}\n\nexport function readConfig(): Config {\n try {\n const raw = readFileSync(CONFIG_FILE, \"utf-8\");\n return JSON.parse(raw) as Config;\n } catch {\n return {};\n }\n}\n\nexport function writeConfig(config: Config): void {\n mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });\n writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2) + \"\\n\", {\n mode: 0o600,\n });\n}\n\nexport function updateConfig(updates: Partial<Config>): void {\n const config = readConfig();\n writeConfig({ ...config, ...updates });\n}\n\nexport function getApiKey(): string | undefined {\n return process.env[\"PIXELVAULT_API_KEY\"] || readConfig().api_key;\n}\n\nexport function getApiUrl(): string {\n return (\n process.env[\"PIXELVAULT_API_URL\"] ||\n readConfig().api_url ||\n DEFAULT_API_URL\n );\n}\n\nexport function requireApiKey(): string {\n const key = getApiKey();\n if (!key) {\n throw new Error(\n \"Not authenticated. Run `pixelvault register` or `pixelvault login`, or set PIXELVAULT_API_KEY.\"\n );\n }\n return key;\n}\n","import { getApiUrl } from \"./config.js\";\nimport { CliError } from \"./errors.js\";\n\ninterface RequestOptions {\n method?: string;\n path: string;\n body?: unknown;\n headers?: Record<string, string>;\n formData?: FormData;\n}\n\ninterface ApiError {\n error: { code: string; message: string };\n}\n\nexport async function apiRequest<T>(\n options: RequestOptions & { auth?: string }\n): Promise<T> {\n const baseUrl = getApiUrl();\n const url = `${baseUrl}${options.path}`;\n\n const headers: Record<string, string> = { ...options.headers };\n\n if (options.auth) {\n headers[\"Authorization\"] = `Bearer ${options.auth}`;\n }\n\n let fetchBody: BodyInit | undefined;\n\n if (options.formData) {\n fetchBody = options.formData;\n } else if (options.body) {\n headers[\"Content-Type\"] = \"application/json\";\n fetchBody = JSON.stringify(options.body);\n }\n\n let res: Response;\n try {\n res = await fetch(url, {\n method: options.method || \"GET\",\n headers,\n body: fetchBody,\n });\n } catch (err) {\n throw new CliError(\n `Network error: ${err instanceof Error ? err.message : \"Failed to connect\"}`,\n 1\n );\n }\n\n if (!res.ok) {\n let errorBody: ApiError | undefined;\n try {\n errorBody = (await res.json()) as ApiError;\n } catch {\n // ignore parse failures\n }\n\n const message =\n errorBody?.error?.message || `HTTP ${res.status}: ${res.statusText}`;\n throw new CliError(message, 1);\n }\n\n return (await res.json()) as T;\n}\n","import { createInterface } from \"node:readline\";\n\n/**\n * Prompt the user for input via stderr (keeps stdout clean for agents).\n */\nexport function prompt(question: string): Promise<string> {\n const rl = createInterface({\n input: process.stdin,\n output: process.stderr,\n });\n\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\n/**\n * Prompt for a password (input is not echoed).\n * Uses raw mode to suppress echo when available, falls back to regular prompt.\n */\nexport async function promptPassword(question: string): Promise<string> {\n if (!process.stdin.isTTY) {\n return prompt(question);\n }\n\n return new Promise((resolve) => {\n process.stderr.write(question);\n process.stdin.setRawMode(true);\n process.stdin.resume();\n process.stdin.setEncoding(\"utf-8\");\n\n let password = \"\";\n\n const onData = (char: string) => {\n if (char === \"\\n\" || char === \"\\r\" || char === \"\\u0004\") {\n process.stdin.setRawMode(false);\n process.stdin.pause();\n process.stdin.removeListener(\"data\", onData);\n process.stderr.write(\"\\n\");\n resolve(password);\n } else if (char === \"\\u0003\") {\n // Ctrl+C\n process.stdin.setRawMode(false);\n process.exit(130);\n } else if (\n char === \"\\u007F\" ||\n char === \"\\b\"\n ) {\n // Backspace\n password = password.slice(0, -1);\n } else {\n password += char;\n }\n };\n\n process.stdin.on(\"data\", onData);\n });\n}\n","import { defineCommand } from \"citty\";\nimport { apiRequest } from \"../lib/client.js\";\nimport { updateConfig } from \"../lib/config.js\";\nimport { prompt, promptPassword } from \"../lib/prompt.js\";\nimport { stderr } from \"../lib/output.js\";\n\ninterface RegisterResponse {\n data: {\n account_id: string;\n email: string;\n email_verified: boolean;\n plan: string;\n default_project: {\n id: string;\n name: string;\n api_keys: { live: string };\n };\n };\n}\n\nexport default defineCommand({\n meta: {\n name: \"register\",\n description: \"Create a new PixelVault account\",\n },\n args: {\n email: {\n type: \"string\",\n description: \"Email address\",\n },\n password: {\n type: \"string\",\n description: \"Password (min 8 characters)\",\n },\n },\n async run({ args }) {\n const email = args.email || (await prompt(\"Email: \"));\n const password = args.password || (await promptPassword(\"Password: \"));\n\n if (!email || !password) {\n stderr(\"Email and password are required.\");\n process.exit(1);\n }\n\n if (password.length < 8) {\n stderr(\"Password must be at least 8 characters.\");\n process.exit(1);\n }\n\n stderr(\"Creating account...\");\n\n const res = await apiRequest<RegisterResponse>({\n method: \"POST\",\n path: \"/v1/auth/register\",\n body: { email, password },\n });\n\n updateConfig({\n api_key: res.data.default_project.api_keys.live,\n default_project: res.data.default_project.id,\n email: res.data.email,\n });\n\n stderr(`Account created. API key saved to ~/.pixelvault/config.json`);\n stderr(`Email: ${res.data.email}`);\n stderr(`Project: ${res.data.default_project.id}`);\n\n if (!res.data.email_verified) {\n stderr(\"Check your email to verify your account before uploading.\");\n }\n },\n});\n","import { defineCommand } from \"citty\";\nimport { apiRequest } from \"../lib/client.js\";\nimport { updateConfig, getApiUrl } from \"../lib/config.js\";\nimport { prompt, promptPassword } from \"../lib/prompt.js\";\nimport { stderr } from \"../lib/output.js\";\n\ninterface LoginResponse {\n data: {\n token: string;\n account_id: string;\n email: string;\n email_verified: boolean;\n };\n}\n\ninterface RotateKeyResponse {\n data: {\n key_id: string;\n api_key: string;\n project_id: string;\n environment: string;\n };\n}\n\ninterface ProjectsResponse {\n data: Array<{ id: string; name: string }>;\n}\n\nexport default defineCommand({\n meta: {\n name: \"login\",\n description: \"Log in to your PixelVault account\",\n },\n args: {\n email: {\n type: \"string\",\n description: \"Email address\",\n },\n password: {\n type: \"string\",\n description: \"Password\",\n },\n },\n async run({ args }) {\n const email = args.email || (await prompt(\"Email: \"));\n const password = args.password || (await promptPassword(\"Password: \"));\n\n if (!email || !password) {\n stderr(\"Email and password are required.\");\n process.exit(1);\n }\n\n stderr(\"Logging in...\");\n\n // Step 1: Login to get JWT\n const loginRes = await apiRequest<LoginResponse>({\n method: \"POST\",\n path: \"/v1/auth/login\",\n body: { email, password },\n });\n\n const token = loginRes.data.token;\n\n // Step 2: Get projects to find default project ID\n let projectId: string | undefined;\n try {\n const projectsRes = await apiRequest<ProjectsResponse>({\n method: \"GET\",\n path: \"/v1/projects\",\n auth: token,\n });\n projectId = projectsRes.data[0]?.id;\n } catch {\n // Projects endpoint may not exist yet — continue without project ID\n }\n\n // Step 3: Rotate key to get a fresh API key\n if (projectId) {\n const rotateRes = await apiRequest<RotateKeyResponse>({\n method: \"POST\",\n path: \"/v1/auth/rotate-key\",\n auth: token,\n body: { project_id: projectId },\n });\n\n updateConfig({\n api_key: rotateRes.data.api_key,\n default_project: projectId,\n email: loginRes.data.email,\n });\n\n stderr(`Logged in. API key saved to ~/.pixelvault/config.json`);\n stderr(`Email: ${loginRes.data.email}`);\n stderr(`Project: ${projectId}`);\n } else {\n // Fallback: save JWT for manual key setup\n stderr(`Logged in as ${loginRes.data.email}.`);\n stderr(\n `Could not auto-configure API key. Set PIXELVAULT_API_KEY manually.`\n );\n updateConfig({ email: loginRes.data.email });\n }\n },\n});\n","import { defineCommand } from \"citty\";\nimport { readFileSync } from \"node:fs\";\nimport { basename } from \"node:path\";\nimport { apiRequest } from \"../lib/client.js\";\nimport { requireApiKey } from \"../lib/config.js\";\nimport { stdout, stderr, jsonOut } from \"../lib/output.js\";\n\ninterface UploadResponse {\n data: {\n id: string;\n url: string;\n mime_type: string;\n size: number;\n filename: string;\n folder: string | null;\n created_at: string;\n };\n}\n\nexport default defineCommand({\n meta: {\n name: \"upload\",\n description: \"Upload one or more images\",\n },\n args: {\n files: {\n type: \"positional\",\n description: \"File path(s) to upload\",\n required: true,\n },\n folder: {\n type: \"string\",\n description: \"Folder to organize images in\",\n },\n json: {\n type: \"boolean\",\n description: \"Output full JSON response\",\n default: false,\n },\n },\n async run({ args }) {\n const apiKey = requireApiKey();\n\n // citty passes positional as a single string; we handle globs via shell expansion\n const files = Array.isArray(args.files) ? args.files : [args.files];\n let hadError = false;\n\n const results: UploadResponse[\"data\"][] = [];\n\n for (const filePath of files) {\n try {\n const buffer = readFileSync(filePath);\n const fileName = basename(filePath);\n\n const formData = new FormData();\n formData.append(\n \"file\",\n new File([buffer], fileName)\n );\n\n if (args.folder) {\n formData.append(\"folder\", args.folder);\n }\n\n const res = await apiRequest<UploadResponse>({\n method: \"POST\",\n path: \"/v1/images\",\n auth: apiKey,\n formData,\n });\n\n if (args.json) {\n results.push(res.data);\n } else {\n stdout(res.data.url);\n }\n } catch (err) {\n hadError = true;\n stderr(\n `Failed to upload ${filePath}: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n\n if (args.json && results.length > 0) {\n jsonOut(results.length === 1 ? results[0] : results);\n }\n\n if (hadError) {\n process.exit(1);\n }\n },\n});\n","import { defineCommand } from \"citty\";\nimport { apiRequest } from \"../lib/client.js\";\nimport { requireApiKey } from \"../lib/config.js\";\nimport { stdout, jsonOut } from \"../lib/output.js\";\n\ninterface ListResponse {\n data: Array<{\n id: string;\n url: string;\n mime_type: string;\n size: number;\n filename: string;\n folder: string | null;\n created_at: string;\n }>;\n meta: {\n total: number;\n page: number;\n per_page: number;\n };\n}\n\nexport default defineCommand({\n meta: {\n name: \"list\",\n description: \"List uploaded images\",\n },\n args: {\n page: {\n type: \"string\",\n description: \"Page number\",\n default: \"1\",\n },\n \"per-page\": {\n type: \"string\",\n description: \"Items per page (max 100)\",\n default: \"20\",\n },\n json: {\n type: \"boolean\",\n description: \"Output full JSON response\",\n default: false,\n },\n },\n async run({ args }) {\n const apiKey = requireApiKey();\n\n const params = new URLSearchParams({\n page: args.page,\n per_page: args[\"per-page\"],\n });\n\n const res = await apiRequest<ListResponse>({\n path: `/v1/images?${params}`,\n auth: apiKey,\n });\n\n if (args.json) {\n jsonOut(res);\n } else {\n for (const img of res.data) {\n stdout(img.url);\n }\n }\n },\n});\n","import { defineCommand } from \"citty\";\nimport { writeFileSync } from \"node:fs\";\nimport { apiRequest } from \"../lib/client.js\";\nimport { requireApiKey } from \"../lib/config.js\";\nimport { stdout, stderr, jsonOut } from \"../lib/output.js\";\nimport { CliError } from \"../lib/errors.js\";\n\ninterface GetResponse {\n data: {\n id: string;\n url: string;\n mime_type: string;\n size: number;\n filename: string;\n folder: string | null;\n created_at: string;\n };\n}\n\n/**\n * Append a transform query string to a CDN URL. Accepts params with or without a\n * leading `?`/`&` (e.g. `w=400&fmt=webp`, `?segment=foreground`). See the transform\n * docs: https://pixelvault.dev/docs#transforms\n *\n * The params are reserialized through URLSearchParams so reserved characters in\n * values are percent-encoded — without this a hex color like `background=#ffaa00`\n * would be parsed as a URL fragment and lost. Idempotent for already-encoded input.\n */\nexport function applyTransform(url: string, transform?: string): string {\n if (!transform) return url;\n const raw = transform.trim().replace(/^[?&]+/, \"\");\n if (!raw) return url;\n const params = new URLSearchParams(raw).toString();\n if (!params) return url;\n return url.includes(\"?\") ? `${url}&${params}` : `${url}?${params}`;\n}\n\nexport default defineCommand({\n meta: {\n name: \"get\",\n description:\n \"Get an image's CDN URL or metadata, or download it — optionally transformed\",\n },\n args: {\n id: {\n type: \"positional\",\n description: \"Image ID (e.g. img_abc123)\",\n required: true,\n },\n output: {\n type: \"string\",\n description: \"Download the image to this file path\",\n alias: \"o\",\n },\n transform: {\n type: \"string\",\n description:\n 'Transform params to apply, e.g. \"w=400&fmt=webp\", \"segment=foreground\", \"tile=img_logo.png\"',\n alias: \"t\",\n },\n json: {\n type: \"boolean\",\n description: \"Output full JSON metadata\",\n default: false,\n },\n },\n async run({ args }) {\n const apiKey = requireApiKey();\n\n const res = await apiRequest<GetResponse>({\n path: `/v1/images/${encodeURIComponent(args.id)}`,\n auth: apiKey,\n });\n\n const url = applyTransform(res.data.url, args.transform as string | undefined);\n\n // Download mode: fetch the (possibly transformed) bytes to disk.\n if (args.output) {\n const output = args.output as string;\n let bytes: ArrayBuffer;\n try {\n const dl = await fetch(url);\n if (!dl.ok) {\n throw new CliError(`Failed to download image: HTTP ${dl.status}`, 1);\n }\n bytes = await dl.arrayBuffer();\n } catch (err) {\n if (err instanceof CliError) throw err;\n throw new CliError(\n `Failed to download image: ${err instanceof Error ? err.message : String(err)}`,\n 1,\n );\n }\n // Refuse to write an empty file — a 200 with an empty/truncated body would\n // otherwise report success and leave a broken image that agents chain on.\n if (bytes.byteLength === 0) {\n throw new CliError(\"Downloaded 0 bytes — refusing to write an empty file\", 1);\n }\n try {\n writeFileSync(output, Buffer.from(bytes));\n } catch (err) {\n throw new CliError(\n `Failed to save ${output}: ${err instanceof Error ? err.message : String(err)}`,\n 1,\n );\n }\n stderr(`Saved ${output}`);\n // Honor --json even in download mode so a caller that always requests JSON\n // gets a stable stdout contract regardless of -o.\n if (args.json) {\n jsonOut(\n args.transform ? { ...res, transformed_url: url, output } : { ...res, output },\n );\n } else {\n stdout(url); // URL to stdout (machine-parseable), confirmation to stderr\n }\n return;\n }\n\n if (args.json) {\n // When a transform is applied there's no separate record for it, so surface\n // the resolved URL alongside the raw metadata.\n jsonOut(args.transform ? { ...res, transformed_url: url } : res);\n } else {\n stdout(url);\n }\n },\n});\n","import { defineCommand } from \"citty\";\nimport { apiRequest } from \"../lib/client.js\";\nimport { requireApiKey } from \"../lib/config.js\";\nimport { stderr } from \"../lib/output.js\";\n\nexport default defineCommand({\n meta: {\n name: \"delete\",\n description: \"Delete an image by ID\",\n },\n args: {\n id: {\n type: \"positional\",\n description: \"Image ID (e.g. img_abc123)\",\n required: true,\n },\n },\n async run({ args }) {\n const apiKey = requireApiKey();\n\n await apiRequest<{ success: boolean }>({\n method: \"DELETE\",\n path: `/v1/images/${args.id}`,\n auth: apiKey,\n });\n\n // Silent on success (agent-friendly)\n },\n});\n","import { defineCommand } from \"citty\";\nimport { readConfig, getApiKey } from \"../lib/config.js\";\nimport { stdout, stderr, jsonOut } from \"../lib/output.js\";\n\nexport default defineCommand({\n meta: {\n name: \"whoami\",\n description: \"Show current authentication state\",\n },\n args: {\n json: {\n type: \"boolean\",\n description: \"Output as JSON\",\n default: false,\n },\n },\n async run({ args }) {\n const config = readConfig();\n const apiKey = getApiKey();\n\n if (!apiKey && !config.email) {\n stderr(\"Not authenticated. Run `pixelvault register` or `pixelvault login`.\");\n process.exit(1);\n }\n\n const info = {\n email: config.email || \"(unknown)\",\n project: config.default_project || \"(unknown)\",\n api_key: apiKey\n ? `${apiKey.slice(0, 12)}...${apiKey.slice(-4)}`\n : \"(not set)\",\n source: process.env[\"PIXELVAULT_API_KEY\"] ? \"env\" : \"config\",\n };\n\n if (args.json) {\n jsonOut(info);\n } else {\n stdout(`Email: ${info.email}`);\n stdout(`Project: ${info.project}`);\n stdout(`API Key: ${info.api_key} (${info.source})`);\n }\n },\n});\n","import { defineCommand } from \"citty\";\nimport { readConfig, updateConfig, getConfigPath } from \"../lib/config.js\";\nimport { stdout, stderr, jsonOut } from \"../lib/output.js\";\n\nconst configGet = defineCommand({\n meta: {\n name: \"get\",\n description: \"Get a config value\",\n },\n args: {\n key: {\n type: \"positional\",\n description: \"Config key (api_key, default_project, email, api_url)\",\n required: true,\n },\n },\n async run({ args }) {\n const config = readConfig();\n const value = config[args.key as keyof typeof config];\n\n if (value === undefined) {\n stderr(`Key \"${args.key}\" is not set.`);\n process.exit(1);\n }\n\n stdout(String(value));\n },\n});\n\nconst configSet = defineCommand({\n meta: {\n name: \"set\",\n description: \"Set a config value\",\n },\n args: {\n key: {\n type: \"positional\",\n description: \"Config key\",\n required: true,\n },\n value: {\n type: \"positional\",\n description: \"Config value\",\n required: true,\n },\n },\n async run({ args }) {\n const validKeys = [\"api_key\", \"default_project\", \"email\", \"api_url\"];\n if (!validKeys.includes(args.key)) {\n stderr(`Invalid key. Valid keys: ${validKeys.join(\", \")}`);\n process.exit(1);\n }\n\n updateConfig({ [args.key]: args.value });\n stderr(`Set ${args.key} = ${args.key === \"api_key\" ? \"***\" : args.value}`);\n },\n});\n\nconst configShow = defineCommand({\n meta: {\n name: \"show\",\n description: \"Show all config values\",\n },\n args: {\n json: {\n type: \"boolean\",\n description: \"Output as JSON\",\n default: false,\n },\n },\n async run({ args }) {\n const config = readConfig();\n\n if (args.json) {\n jsonOut(config);\n } else {\n stderr(`Config: ${getConfigPath()}`);\n for (const [key, value] of Object.entries(config)) {\n const display = key === \"api_key\" && value\n ? `${(value as string).slice(0, 12)}...`\n : value;\n stdout(`${key} = ${display}`);\n }\n }\n },\n});\n\nexport default defineCommand({\n meta: {\n name: \"config\",\n description: \"Manage CLI configuration\",\n },\n subCommands: {\n get: configGet,\n set: configSet,\n show: configShow,\n },\n});\n","import { defineCommand, runMain } from \"citty\";\nimport { CliError } from \"./lib/errors.js\";\nimport { stderr } from \"./lib/output.js\";\n\nconst main = defineCommand({\n meta: {\n name: \"pixelvault\",\n version: \"0.2.0\",\n description: \"CLI for PixelVault — agent-first image hosting\",\n },\n subCommands: {\n register: () => import(\"./commands/register.js\").then((m) => m.default),\n login: () => import(\"./commands/login.js\").then((m) => m.default),\n upload: () => import(\"./commands/upload.js\").then((m) => m.default),\n list: () => import(\"./commands/list.js\").then((m) => m.default),\n get: () => import(\"./commands/get.js\").then((m) => m.default),\n delete: () => import(\"./commands/delete.js\").then((m) => m.default),\n whoami: () => import(\"./commands/whoami.js\").then((m) => m.default),\n config: () => import(\"./commands/config.js\").then((m) => m.default),\n },\n});\n\nrunMain(main).catch((err: unknown) => {\n if (err instanceof CliError) {\n stderr(`Error: ${err.message}`);\n process.exit(err.exitCode);\n }\n stderr(`Error: ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n});\n"],"mappings":"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","names":["CliError","init_errors","__esmMin","message","exitCode","stdout","text","stderr","jsonOut","data","init_output","__esmMin","readFileSync","writeFileSync","mkdirSync","join","homedir","getConfigPath","CONFIG_FILE","readConfig","raw","writeConfig","config","CONFIG_DIR","updateConfig","updates","getApiKey","getApiUrl","DEFAULT_API_URL","requireApiKey","key","init_config","__esmMin","apiRequest","options","url","getApiUrl","headers","fetchBody","res","err","CliError","errorBody","message","init_client","__esmMin","init_config","init_errors","createInterface","prompt","question","rl","resolve","answer","promptPassword","password","onData","char","init_prompt","__esmMin","register_exports","__export","register_default","defineCommand","init_register","__esmMin","init_client","init_config","init_prompt","init_output","args","email","prompt","password","promptPassword","stderr","res","apiRequest","updateConfig","login_exports","__export","login_default","defineCommand","init_login","__esmMin","init_client","init_config","init_prompt","init_output","args","email","prompt","password","promptPassword","stderr","loginRes","apiRequest","token","projectId","rotateRes","updateConfig","upload_exports","__export","upload_default","defineCommand","readFileSync","basename","init_upload","__esmMin","init_client","init_config","init_output","args","apiKey","requireApiKey","files","hadError","results","filePath","buffer","fileName","formData","res","apiRequest","stdout","err","stderr","jsonOut","list_exports","__export","list_default","defineCommand","init_list","__esmMin","init_client","init_config","init_output","args","apiKey","requireApiKey","params","res","apiRequest","jsonOut","img","stdout","get_exports","__export","applyTransform","get_default","defineCommand","writeFileSync","url","transform","raw","params","init_get","__esmMin","init_client","init_config","init_output","init_errors","args","apiKey","requireApiKey","res","apiRequest","output","bytes","dl","CliError","err","stderr","jsonOut","stdout","delete_exports","__export","delete_default","defineCommand","init_delete","__esmMin","init_client","init_config","args","apiKey","requireApiKey","apiRequest","whoami_exports","__export","whoami_default","defineCommand","init_whoami","__esmMin","init_config","init_output","args","config","readConfig","apiKey","getApiKey","stderr","info","jsonOut","stdout","config_exports","__export","config_default","defineCommand","configGet","configSet","configShow","init_config","__esmMin","init_output","args","value","readConfig","stderr","stdout","validKeys","updateConfig","config","jsonOut","getConfigPath","key","display","init_errors","init_output","defineCommand","runMain","main","m","err","CliError","stderr"]}
|