@isaacthoman/pulpo 0.56.0 → 0.58.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 CHANGED
@@ -10,6 +10,7 @@ pulpo auth 2fa status
10
10
  pulpo auth 2fa setup
11
11
  pulpo auth 2fa confirm
12
12
  pulpo settings export --output pulpo-settings.json
13
+ pulpo icon upload ./acme.svg --name Acme --mode monochrome
13
14
  ```
14
15
 
15
16
  Use `pulpo help` or `pulpo <command> --help` for the complete command reference.
@@ -21,7 +22,7 @@ canonical [Lucide](https://lucide.dev/icons/) name. Discover available names wit
21
22
  sent. Add `--json` for stable `{ "name": "..." }` rows in scripts.
22
23
 
23
24
  The major command groups are `context`, `auth`, `token`, `instance`, `settings`,
24
- `provider`, `lab`, `model`, `user`, `usage`, `audit`, `workspace`, `banner`,
25
+ `provider`, `lab`, `icon`, `model`, `user`, `usage`, `audit`, `workspace`, `banner`,
25
26
  `job`, `export`, and `backup`. There is intentionally no restore command.
26
27
 
27
28
  Human-readable tables are the default. `--json` reserves stdout for stable JSON;
package/dist/index.js CHANGED
@@ -16462,6 +16462,13 @@ var responseSnapshotSchema = external_exports.object({
16462
16462
  updatedAt: isoDateSchema
16463
16463
  });
16464
16464
  var embeddedResponseSnapshotSchema = responseSnapshotSchema.omit({ output: true });
16465
+ var catalogIconModeSchema = external_exports.enum(["original", "monochrome"]);
16466
+ var catalogIconReferenceSchema = external_exports.object({
16467
+ id: idSchema,
16468
+ mode: catalogIconModeSchema,
16469
+ lightUrl: external_exports.string().startsWith("/api/catalog-icons/"),
16470
+ darkUrl: external_exports.string().startsWith("/api/catalog-icons/")
16471
+ });
16465
16472
  var modelSchema = external_exports.object({
16466
16473
  id: external_exports.string().min(1).max(120),
16467
16474
  upstreamModelId: external_exports.string().min(1).max(200),
@@ -16470,6 +16477,8 @@ var modelSchema = external_exports.object({
16470
16477
  enabled: external_exports.boolean(),
16471
16478
  visible: external_exports.boolean(),
16472
16479
  logo: external_exports.string().nullable(),
16480
+ customIconId: idSchema.nullable().optional(),
16481
+ customIcon: catalogIconReferenceSchema.nullable().optional(),
16473
16482
  executionMode: executionModeSchema,
16474
16483
  contextWindow: external_exports.number().int().positive(),
16475
16484
  maxOutputTokens: external_exports.number().int().positive(),
@@ -16549,6 +16558,7 @@ var createModelSchema = external_exports.object({
16549
16558
  enabled: external_exports.boolean().default(true),
16550
16559
  visible: external_exports.boolean().default(true),
16551
16560
  logo: external_exports.string().max(120).nullable().default(null),
16561
+ customIconId: idSchema.nullable().default(null),
16552
16562
  systemPrompt: external_exports.string().max(1e5).default(""),
16553
16563
  agentEnabled: external_exports.boolean().default(false),
16554
16564
  agentInstructions: external_exports.string().max(1e5).default(""),
@@ -17037,6 +17047,28 @@ var PulpoManagementClient = class {
17037
17047
  }
17038
17048
  return body;
17039
17049
  }
17050
+ async upload(path, input) {
17051
+ const form = new FormData();
17052
+ for (const [name, value] of Object.entries(input.fields ?? {}))
17053
+ form.append(name, value);
17054
+ const copy = new ArrayBuffer(input.bytes.byteLength);
17055
+ new Uint8Array(copy).set(input.bytes);
17056
+ form.append("file", new Blob([copy], { type: input.contentType }), input.filename);
17057
+ const headers = new Headers();
17058
+ if (this.token)
17059
+ headers.set("authorization", `Bearer ${this.token}`);
17060
+ const response = await this.fetchImpl(new URL(path, `${this.baseUrl.replace(/\/+$/, "")}/`), {
17061
+ method: "POST",
17062
+ headers,
17063
+ body: form,
17064
+ signal: AbortSignal.timeout(input.timeoutMs ?? 3e4)
17065
+ });
17066
+ const body = await response.json().catch(() => void 0);
17067
+ if (!response.ok) {
17068
+ throw new ManagementApiError(response.status, body?.error?.code ?? "upload_failed", body?.error?.message ?? `Upload failed (${response.status})`, body);
17069
+ }
17070
+ return body;
17071
+ }
17040
17072
  async download(path, timeoutMs = 3e5) {
17041
17073
  const headers = new Headers();
17042
17074
  if (this.token)
@@ -17385,15 +17417,20 @@ async function confirmExact(io, expected, yes, json2) {
17385
17417
  }
17386
17418
 
17387
17419
  // src/index.ts
17388
- var CLI_VERSION = true ? "0.56.0" : "0.1.0";
17420
+ var CLI_VERSION = true ? "0.58.0" : "0.1.0";
17389
17421
  var CLI_BUNDLED = true;
17390
17422
  var commandIo = /* @__PURE__ */ new WeakMap();
17391
17423
  var commandClientFactory = /* @__PURE__ */ new WeakMap();
17424
+ function catalogIconContentType(filename) {
17425
+ const extension = /\.([^.]+)$/.exec(filename)?.[1]?.toLowerCase();
17426
+ return extension === "png" ? "image/png" : extension === "jpg" || extension === "jpeg" ? "image/jpeg" : extension === "webp" ? "image/webp" : extension === "svg" ? "image/svg+xml" : null;
17427
+ }
17392
17428
  var COMMAND_CAPABILITIES = {
17393
17429
  token: "managementTokens",
17394
17430
  settings: "settings",
17395
17431
  provider: "catalog",
17396
17432
  lab: "catalog",
17433
+ icon: "catalogIcons",
17397
17434
  model: "catalog",
17398
17435
  user: "users",
17399
17436
  usage: "usage",
@@ -17835,6 +17872,25 @@ function createProgram(io = processIo, dependencies = {}) {
17835
17872
  const { client } = await clientFor(command);
17836
17873
  emit(io, command, await client.request(`/api/management/v1/labs/${encodeURIComponent(id)}/models/order`, { method: "PUT", body: await jsonFile(options.file) }));
17837
17874
  });
17875
+ const icon = registerFileCrud(program, io, {
17876
+ name: "icon",
17877
+ pluralPath: "/api/management/v1/catalog-icons",
17878
+ create: false
17879
+ });
17880
+ icon.command("upload <path>").option("-n, --name <name>", "library name; defaults to the filename").option("-m, --mode <mode>", "original or monochrome", "original").action(async (path, options, command) => {
17881
+ const mode = external_exports.enum(["original", "monochrome"]).parse(options.mode);
17882
+ const filename = basename(path);
17883
+ const contentType = catalogIconContentType(filename);
17884
+ if (!contentType) throw new Error("Icon files must be PNG, JPEG, WebP, or SVG");
17885
+ const bytes = new Uint8Array(await readFile2(path));
17886
+ const { client } = await clientFor(command);
17887
+ emit(io, command, await client.upload("/api/management/v1/catalog-icons", {
17888
+ bytes,
17889
+ filename,
17890
+ contentType,
17891
+ fields: { name: options.name ?? filename.replace(/\.[^.]+$/, ""), mode }
17892
+ }));
17893
+ });
17838
17894
  const model = registerFileCrud(program, io, {
17839
17895
  name: "model",
17840
17896
  pluralPath: "/api/management/v1/models",
@@ -17973,6 +18029,7 @@ async function main(argv = process.argv, io = processIo) {
17973
18029
  }
17974
18030
  if (CLI_BUNDLED || process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) void main();
17975
18031
  export {
18032
+ catalogIconContentType,
17976
18033
  createProgram,
17977
18034
  main,
17978
18035
  preflightModelBody
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@isaacthoman/pulpo",
3
- "version": "0.56.0",
3
+ "version": "0.58.0",
4
4
  "description": "Operator-first command-line client for Pulpo",
5
5
  "type": "module",
6
6
  "bin": {