pixelvault-cli 0.1.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/LICENSE +21 -0
- package/README.md +108 -0
- package/bin/pixelvault.mjs +2 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/package.json +46 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 PixelVault
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# pixelvault
|
|
2
|
+
|
|
3
|
+
CLI for [PixelVault](https://pixelvault.dev) — agent-first image hosting for developers and AI coding agents.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g pixelvault
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or use directly with `npx`:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx pixelvault upload photo.jpg
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Create an account
|
|
21
|
+
pixelvault register
|
|
22
|
+
|
|
23
|
+
# Upload an image — prints the URL to stdout
|
|
24
|
+
pixelvault upload screenshot.png
|
|
25
|
+
# https://img.pixelvault.dev/proj_abc/img_xyz.png
|
|
26
|
+
|
|
27
|
+
# Upload multiple images
|
|
28
|
+
pixelvault upload *.png --folder screenshots
|
|
29
|
+
|
|
30
|
+
# List your images
|
|
31
|
+
pixelvault list
|
|
32
|
+
|
|
33
|
+
# Delete an image
|
|
34
|
+
pixelvault delete img_xyz
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Agent Integration
|
|
38
|
+
|
|
39
|
+
The CLI is designed for AI coding agents. Output contract:
|
|
40
|
+
|
|
41
|
+
- `upload` prints **only the URL** to stdout
|
|
42
|
+
- `list` outputs one URL per line
|
|
43
|
+
- `delete` outputs nothing on success
|
|
44
|
+
- All human messages go to **stderr**
|
|
45
|
+
- `--json` flag for structured output
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# In agent workflows
|
|
49
|
+
URL=$(npx pixelvault upload screenshot.png)
|
|
50
|
+
echo "Uploaded to: $URL"
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Environment Variables
|
|
54
|
+
|
|
55
|
+
For CI/CD and headless agent usage:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
export PIXELVAULT_API_KEY=pv_live_xxx
|
|
59
|
+
npx pixelvault upload build-output.png
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Commands
|
|
63
|
+
|
|
64
|
+
| Command | Description |
|
|
65
|
+
|---------|-------------|
|
|
66
|
+
| `register` | Create a new account |
|
|
67
|
+
| `login` | Log in to existing account |
|
|
68
|
+
| `upload <files...>` | Upload images (prints URLs to stdout) |
|
|
69
|
+
| `list` | List uploaded images |
|
|
70
|
+
| `delete <id>` | Delete an image |
|
|
71
|
+
| `whoami` | Show current auth state |
|
|
72
|
+
| `config get\|set\|show` | Manage CLI configuration |
|
|
73
|
+
|
|
74
|
+
### Upload Options
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pixelvault upload photo.jpg # Single file
|
|
78
|
+
pixelvault upload *.png --folder icons # Bulk with folder
|
|
79
|
+
pixelvault upload shot.png --json # Full JSON response
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### List Options
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
pixelvault list # One URL per line
|
|
86
|
+
pixelvault list --json # Full JSON with metadata
|
|
87
|
+
pixelvault list --page 2 --per-page 50 # Pagination
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Configuration
|
|
91
|
+
|
|
92
|
+
Config is stored at `~/.pixelvault/config.json` (0600 permissions).
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
pixelvault config show # Show all config
|
|
96
|
+
pixelvault config set api_url http://localhost:8787 # Dev override
|
|
97
|
+
pixelvault config get api_key # Get a value
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
`PIXELVAULT_API_KEY` env var always takes precedence over the config file.
|
|
101
|
+
|
|
102
|
+
## Requirements
|
|
103
|
+
|
|
104
|
+
- Node.js 20+
|
|
105
|
+
|
|
106
|
+
## License
|
|
107
|
+
|
|
108
|
+
MIT
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
var z=Object.defineProperty;var p=(e,t)=>()=>(e&&(t=e(e=0)),t);var g=(e,t)=>{for(var i in t)z(e,i,{get:t[i],enumerable:!0})};var y,C=p(()=>{"use strict";y=class extends Error{exitCode;constructor(t,i=1){super(t),this.name="CliError",this.exitCode=i}}});function d(e){process.stdout.write(e+`
|
|
2
|
+
`)}function o(e){process.stderr.write(e+`
|
|
3
|
+
`)}function l(e){d(JSON.stringify(e,null,2))}var u=p(()=>{"use strict"});import{readFileSync as B,writeFileSync as H,mkdirSync as Q}from"fs";import{join as $}from"path";import{homedir as W}from"os";function L(){return R}function f(){try{let e=B(R,"utf-8");return JSON.parse(e)}catch{return{}}}function ee(e){Q(I,{recursive:!0,mode:448}),H(R,JSON.stringify(e,null,2)+`
|
|
4
|
+
`,{mode:384})}function h(e){let t=f();ee({...t,...e})}function E(){return process.env.PIXELVAULT_API_KEY||f().api_key}function S(){return process.env.PIXELVAULT_API_URL||f().api_url||Z}function w(){let e=E();if(!e)throw new Error("Not authenticated. Run `pixelvault register` or `pixelvault login`, or set PIXELVAULT_API_KEY.");return e}var I,R,Z,m=p(()=>{"use strict";I=$(W(),".pixelvault"),R=$(I,"config.json"),Z="https://api.pixelvault.dev"});async function c(e){let i=`${S()}${e.path}`,r={...e.headers};e.auth&&(r.Authorization=`Bearer ${e.auth}`);let n;e.formData?n=e.formData:e.body&&(r["Content-Type"]="application/json",n=JSON.stringify(e.body));let s;try{s=await fetch(i,{method:e.method||"GET",headers:r,body:n})}catch(a){throw new y(`Network error: ${a instanceof Error?a.message:"Failed to connect"}`,1)}if(!s.ok){let a;try{a=await s.json()}catch{}let j=a?.error?.message||`HTTP ${s.status}: ${s.statusText}`;throw new y(j,1)}return await s.json()}var _=p(()=>{"use strict";m();C()});import{createInterface as te}from"readline";function x(e){let t=te({input:process.stdin,output:process.stderr});return new Promise(i=>{t.question(e,r=>{t.close(),i(r.trim())})})}async function v(e){return process.stdin.isTTY?new Promise(t=>{process.stderr.write(e),process.stdin.setRawMode(!0),process.stdin.resume(),process.stdin.setEncoding("utf-8");let i="",r=n=>{n===`
|
|
5
|
+
`||n==="\r"||n===""?(process.stdin.setRawMode(!1),process.stdin.pause(),process.stdin.removeListener("data",r),process.stderr.write(`
|
|
6
|
+
`),t(i)):n===""?(process.stdin.setRawMode(!1),process.exit(130)):n==="\x7F"||n==="\b"?i=i.slice(0,-1):i+=n};process.stdin.on("data",r)}):x(e)}var A=p(()=>{"use strict"});var O={};g(O,{default:()=>ie});import{defineCommand as re}from"citty";var ie,T=p(()=>{"use strict";_();m();A();u();ie=re({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 t=e.email||await x("Email: "),i=e.password||await v("Password: ");(!t||!i)&&(o("Email and password are required."),process.exit(1)),i.length<8&&(o("Password must be at least 8 characters."),process.exit(1)),o("Creating account...");let r=await c({method:"POST",path:"/v1/auth/register",body:{email:t,password:i}});h({api_key:r.data.default_project.api_keys.live,default_project:r.data.default_project.id,email:r.data.email}),o("Account created. API key saved to ~/.pixelvault/config.json"),o(`Email: ${r.data.email}`),o(`Project: ${r.data.default_project.id}`),r.data.email_verified||o("Check your email to verify your account before uploading.")}})});var q={};g(q,{default:()=>ne});import{defineCommand as oe}from"citty";var ne,K=p(()=>{"use strict";_();m();A();u();ne=oe({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 t=e.email||await x("Email: "),i=e.password||await v("Password: ");(!t||!i)&&(o("Email and password are required."),process.exit(1)),o("Logging in...");let r=await c({method:"POST",path:"/v1/auth/login",body:{email:t,password:i}}),n=r.data.token,s;try{s=(await c({method:"GET",path:"/v1/projects",auth:n})).data[0]?.id}catch{}if(s){let a=await c({method:"POST",path:"/v1/auth/rotate-key",auth:n,body:{project_id:s}});h({api_key:a.data.api_key,default_project:s,email:r.data.email}),o("Logged in. API key saved to ~/.pixelvault/config.json"),o(`Email: ${r.data.email}`),o(`Project: ${s}`)}else o(`Logged in as ${r.data.email}.`),o("Could not auto-configure API key. Set PIXELVAULT_API_KEY manually."),h({email:r.data.email})}})});var U={};g(U,{default:()=>de});import{defineCommand as se}from"citty";import{readFileSync as ae}from"fs";import{basename as pe}from"path";var de,F=p(()=>{"use strict";_();m();u();de=se({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 t=w(),i=Array.isArray(e.files)?e.files:[e.files],r=!1,n=[];for(let s of i)try{let a=ae(s),j=pe(s),k=new FormData;k.append("file",new File([a],j)),e.folder&&k.append("folder",e.folder);let b=await c({method:"POST",path:"/v1/images",auth:t,formData:k});e.json?n.push(b.data):d(b.data.url)}catch(a){r=!0,o(`Failed to upload ${s}: ${a instanceof Error?a.message:String(a)}`)}e.json&&n.length>0&&l(n.length===1?n[0]:n),r&&process.exit(1)}})});var N={};g(N,{default:()=>me});import{defineCommand as ce}from"citty";var me,D=p(()=>{"use strict";_();m();u();me=ce({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 t=w(),i=new URLSearchParams({page:e.page,per_page:e["per-page"]}),r=await c({path:`/v1/images?${i}`,auth:t});if(e.json)l(r);else for(let n of r.data)d(n.url)}})});var V={};g(V,{default:()=>ue});import{defineCommand as le}from"citty";var ue,J=p(()=>{"use strict";_();m();ue=le({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 t=w();await c({method:"DELETE",path:`/v1/images/${e.id}`,auth:t})}})});var G={};g(G,{default:()=>ge});import{defineCommand as fe}from"citty";var ge,M=p(()=>{"use strict";m();u();ge=fe({meta:{name:"whoami",description:"Show current authentication state"},args:{json:{type:"boolean",description:"Output as JSON",default:!1}},async run({args:e}){let t=f(),i=E();!i&&!t.email&&(o("Not authenticated. Run `pixelvault register` or `pixelvault login`."),process.exit(1));let r={email:t.email||"(unknown)",project:t.default_project||"(unknown)",api_key:i?`${i.slice(0,12)}...${i.slice(-4)}`:"(not set)",source:process.env.PIXELVAULT_API_KEY?"env":"config"};e.json?l(r):(d(`Email: ${r.email}`),d(`Project: ${r.project}`),d(`API Key: ${r.api_key} (${r.source})`))}})});var X={};g(X,{default:()=>_e});import{defineCommand as P}from"citty";var ye,he,we,_e,Y=p(()=>{"use strict";m();u();ye=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 i=f()[e.key];i===void 0&&(o(`Key "${e.key}" is not set.`),process.exit(1)),d(String(i))}}),he=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 t=["api_key","default_project","email","api_url"];t.includes(e.key)||(o(`Invalid key. Valid keys: ${t.join(", ")}`),process.exit(1)),h({[e.key]:e.value}),o(`Set ${e.key} = ${e.key==="api_key"?"***":e.value}`)}}),we=P({meta:{name:"show",description:"Show all config values"},args:{json:{type:"boolean",description:"Output as JSON",default:!1}},async run({args:e}){let t=f();if(e.json)l(t);else{o(`Config: ${L()}`);for(let[i,r]of Object.entries(t)){let n=i==="api_key"&&r?`${r.slice(0,12)}...`:r;d(`${i} = ${n}`)}}}}),_e=P({meta:{name:"config",description:"Manage CLI configuration"},subCommands:{get:ye,set:he,show:we}})});C();u();import{defineCommand as xe,runMain as ve}from"citty";var Pe=xe({meta:{name:"pixelvault",version:"0.1.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(()=>(D(),N)).then(e=>e.default),delete:()=>Promise.resolve().then(()=>(J(),V)).then(e=>e.default),whoami:()=>Promise.resolve().then(()=>(M(),G)).then(e=>e.default),config:()=>Promise.resolve().then(()=>(Y(),X)).then(e=>e.default)}});ve(Pe).catch(e=>{e instanceof y&&(o(`Error: ${e.message}`),process.exit(e.exitCode)),o(`Error: ${e instanceof Error?e.message:String(e)}`),process.exit(1)});
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pixelvault-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "CLI for PixelVault — agent-first image hosting",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"pixelvault": "./bin/pixelvault.mjs"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin",
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsup",
|
|
15
|
+
"dev": "tsup --watch",
|
|
16
|
+
"typecheck": "tsc --noEmit",
|
|
17
|
+
"lint": "tsc --noEmit",
|
|
18
|
+
"test": "vitest run",
|
|
19
|
+
"test:watch": "vitest"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"pixelvault",
|
|
23
|
+
"image-hosting",
|
|
24
|
+
"cli",
|
|
25
|
+
"agent",
|
|
26
|
+
"upload"
|
|
27
|
+
],
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "https://github.com/pixelvault-dev/cli"
|
|
31
|
+
},
|
|
32
|
+
"author": "PixelVault",
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=20.0.0"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"citty": "^0.1.6"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@types/node": "^22.0.0",
|
|
42
|
+
"tsup": "^8.0.0",
|
|
43
|
+
"typescript": "^5.7.0",
|
|
44
|
+
"vitest": "^3.0.0"
|
|
45
|
+
}
|
|
46
|
+
}
|