wity-cli 0.1.0 → 0.1.1

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/dist/cli.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { t as version } from "./package-7FOUqcPO.mjs";
3
- import { C as cost, E as painter, F as CliError, I as EXIT, M as KEYS_PAGE, O as shouldColor, P as resolveBaseURL, S as cleanBlock, T as ms, a as checkStateLength, d as readStdin, f as findKey, g as checkKey, h as checkHealth, i as askFileSchema, j as writeJson, k as spinner, l as readHidden, m as openStore, n as sendGenerate, o as describeIssues, p as keyPrefix, r as sendSystemOne, u as readState, x as clean, y as refusedHint } from "./send-CGXuVi9Z.mjs";
4
- import { a as scoreQuestion, c as codeLangs, d as printCode, f as systemOneTs, i as pickField, l as curl, n as choiceQuestion, o as renderAnswer, r as noulQuestion, s as renderFooter, t as ask, u as generateTs } from "./questions-eZ01WB1q.mjs";
2
+ import { t as version } from "./package-m9GoQGcx.mjs";
3
+ import { A as spinner, C as cleanBlock, D as painter, E as ms, I as resolveBaseURL, L as CliError, M as writeJson, N as KEYS_PAGE, R as EXIT, S as clean, _ as checkKey, a as checkStateLength, b as refusedHint, d as readStdin, f as findKey, g as checkHealth, h as openStore, i as askFileSchema, k as shouldColor, l as readHidden, m as moveKey, n as sendGenerate, o as describeIssues, p as keyPrefix, r as sendSystemOne, u as readState, w as cost } from "./send-xVjyr_dj.mjs";
4
+ import { a as scoreQuestion, c as codeLangs, d as printCode, f as systemOneTs, i as pickField, l as curl, n as choiceQuestion, o as renderAnswer, r as noulQuestion, s as renderFooter, t as ask, u as generateTs } from "./questions-Djd7w1yM.mjs";
5
5
  import { Command, CommanderError, InvalidArgumentError, Option } from "commander";
6
6
  import { readFile, stat } from "node:fs/promises";
7
7
  import { parse } from "yaml";
@@ -21,7 +21,7 @@ const envWarning = (ctx, text) => {
21
21
  if (ctx.io.env.WITY_API_KEY?.trim()) ctx.io.stderr.write(` ${ctx.err("yellow", "▲")} ${text}\n\n`);
22
22
  };
23
23
  /** Shown only when it isn't the usual address, so people notice they're pointed somewhere else. */
24
- const addressLine = (ctx) => ctx.baseURL === "https://wity-proxy-production-2c33.up.railway.app" ? "" : ` ${ctx.err("dim", "API".padEnd(9))} ${ctx.baseURL}\n`;
24
+ const addressLine = (ctx) => ctx.baseURL === "https://api.wity.alphanimble.com" ? "" : ` ${ctx.err("dim", "API".padEnd(9))} ${ctx.baseURL}\n`;
25
25
  const when = (iso) => new Date(iso).toLocaleString("en-GB", {
26
26
  dateStyle: "medium",
27
27
  timeStyle: "short"
@@ -77,7 +77,7 @@ const removeKey = async (ctx) => {
77
77
  const p = ctx.err;
78
78
  const store = await ctx.store();
79
79
  if (!await store.delete(ctx.baseURL)) {
80
- io.stderr.write(`\n There's no saved key on this computer${ctx.baseURL === "https://wity-proxy-production-2c33.up.railway.app" ? "" : ` for ${ctx.baseURL}`}.\n\n`);
80
+ io.stderr.write(`\n There's no saved key on this computer${ctx.baseURL === "https://api.wity.alphanimble.com" ? "" : ` for ${ctx.baseURL}`}.\n\n`);
81
81
  envWarning(ctx, "WITY_API_KEY is set in this shell, so commands keep using it. Remove it with: unset WITY_API_KEY");
82
82
  return EXIT.ok;
83
83
  }
@@ -232,7 +232,7 @@ const doctor = async (ctx, opts) => {
232
232
  show({
233
233
  name: "API address",
234
234
  state: "ok",
235
- detail: ctx.baseURL === "https://wity-proxy-production-2c33.up.railway.app" ? ctx.baseURL : `${ctx.baseURL} (custom)`
235
+ detail: ctx.baseURL === "https://api.wity.alphanimble.com" ? ctx.baseURL : `${ctx.baseURL} (custom)`
236
236
  });
237
237
  show(await attempt("Key storage", async () => {
238
238
  return {
@@ -375,6 +375,16 @@ const generate = async (ctx, instructions, flags) => {
375
375
  };
376
376
  //#endregion
377
377
  //#region src/context.ts
378
+ /**
379
+ * Opens the store and, on the default address, moves a key saved under the old one.
380
+ * The notice goes to stderr, so stdout stays clean for JSON and for `wity mcp serve`.
381
+ */
382
+ const openAndMove = async (io, baseURL) => {
383
+ const store = await openStore(io.env);
384
+ if (baseURL === "https://api.wity.alphanimble.com" && await moveKey(store, "https://wity-proxy-production-2c33.up.railway.app", baseURL)) io.stderr.write(`[wity] Notice: the Wity API has moved to ${baseURL}.\n[wity] Your saved API key was moved to the new address. No action is needed.
385
+ `);
386
+ return store;
387
+ };
378
388
  const makeCtx = (io, baseUrlFlag) => {
379
389
  const baseURL = resolveBaseURL(baseUrlFlag, io.env);
380
390
  let opened;
@@ -382,7 +392,7 @@ const makeCtx = (io, baseUrlFlag) => {
382
392
  io,
383
393
  baseURL,
384
394
  store: () => {
385
- opened ??= openStore(io.env);
395
+ opened ??= openAndMove(io, baseURL);
386
396
  return opened;
387
397
  },
388
398
  out: painter(shouldColor(io.env, io.stdout)),
@@ -425,7 +435,7 @@ const main = async (argv, io) => {
425
435
  outputError: (text, write) => write(text.replace(/wity_[\w-]{16,}/g, "wity_…"))
426
436
  }).exitOverride().action(async () => {
427
437
  if (!io.stdin.isTTY || !io.stdout.isTTY) program.help();
428
- const { playground } = await import("./playground-Cn7EIrd7.mjs");
438
+ const { playground } = await import("./playground-pvc9-JRy.mjs");
429
439
  code = await playground(ctx(), "");
430
440
  });
431
441
  const setHint = "Run `wity api-key set <key>`, or `wity api-key set` to paste it at a hidden prompt.";
@@ -468,11 +478,11 @@ const main = async (argv, io) => {
468
478
  });
469
479
  program.command("playground").description("try questions live in the terminal (also: wity with no arguments)").option("-t, --text <text>", "start with this text").option("--file <path>", "start with the text of this file").action(async (opts) => {
470
480
  const text = opts.text !== void 0 || opts.file !== void 0 ? await readState(opts, io) : "";
471
- const { playground } = await import("./playground-Cn7EIrd7.mjs");
481
+ const { playground } = await import("./playground-pvc9-JRy.mjs");
472
482
  code = await playground(ctx(), text);
473
483
  });
474
484
  program.command("mcp").description("run Wity as an MCP server for AI agents").command("serve").description("serve Wity's tools over stdio, for Claude Code, Claude Desktop, Cursor and others").option("--max-spend <usd>", "stop paid calls after this many dollars in one session", number).action(async (opts) => {
475
- const { serveMcp } = await import("./mcp-DnqXX8ba.mjs");
485
+ const { serveMcp } = await import("./mcp-CWnSbpgj.mjs");
476
486
  code = await serveMcp(ctx(), opts);
477
487
  });
478
488
  try {
@@ -1,5 +1,5 @@
1
- import { t as version } from "./package-7FOUqcPO.mjs";
2
- import { C as cost, D as pct, F as CliError, I as EXIT, N as PRICE_PER_MILLION_INPUT_USD, _ as explain, a as checkStateLength, c as MAX_STATE_CHARS, s as questionSchema, t as requireKey, v as makeClient, x as clean } from "./send-CGXuVi9Z.mjs";
1
+ import { t as version } from "./package-m9GoQGcx.mjs";
2
+ import { F as PRICE_PER_MILLION_INPUT_USD, L as CliError, O as pct, R as EXIT, S as clean, a as checkStateLength, c as MAX_STATE_CHARS, s as questionSchema, t as requireKey, v as explain, w as cost, y as makeClient } from "./send-xVjyr_dj.mjs";
3
3
  import { z } from "zod";
4
4
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
5
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
@@ -1,4 +1,4 @@
1
1
  //#region package.json
2
- var version = "0.1.0";
2
+ var version = "0.1.1";
3
3
  //#endregion
4
4
  export { version as t };
@@ -1,5 +1,5 @@
1
- import { C as cost, E as painter, F as CliError, I as EXIT, O as shouldColor, S as cleanBlock, _ as explain, a as checkStateLength, p as keyPrefix, t as requireKey, v as makeClient, x as clean } from "./send-CGXuVi9Z.mjs";
2
- import { a as scoreQuestion, f as systemOneTs, n as choiceQuestion, o as renderAnswer, r as noulQuestion, s as renderFooter } from "./questions-eZ01WB1q.mjs";
1
+ import { C as cleanBlock, D as painter, L as CliError, R as EXIT, S as clean, a as checkStateLength, k as shouldColor, p as keyPrefix, t as requireKey, v as explain, w as cost, y as makeClient } from "./send-xVjyr_dj.mjs";
2
+ import { a as scoreQuestion, f as systemOneTs, n as choiceQuestion, o as renderAnswer, r as noulQuestion, s as renderFooter } from "./questions-Djd7w1yM.mjs";
3
3
  import { Box, Text, render, useAnimation, useApp, useInput, usePaste, useWindowSize } from "ink";
4
4
  import { useEffect, useRef, useState } from "react";
5
5
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -1,4 +1,4 @@
1
- import { A as truncate, B as score, C as cost, D as pct, F as CliError, I as EXIT, R as choice, T as ms, b as bar, j as writeJson, r as sendSystemOne, u as readState, w as decimal, x as clean, z as noul } from "./send-CGXuVi9Z.mjs";
1
+ import { B as choice, E as ms, H as score, L as CliError, M as writeJson, O as pct, R as EXIT, S as clean, T as decimal, V as noul, j as truncate, r as sendSystemOne, u as readState, w as cost, x as bar } from "./send-xVjyr_dj.mjs";
2
2
  //#region src/code.ts
3
3
  /** A string as a JavaScript literal. JSON's escaping is valid JavaScript, and safe for any text. */
4
4
  const str = (value) => JSON.stringify(value);
@@ -16,7 +16,7 @@ const builder = (question, indent) => {
16
16
  const inline = `[${levels.join(", ")}]`;
17
17
  return inline.length <= 80 ? `score(${str(question.instructions)}, ${inline})` : `score(${str(question.instructions)}, [\n${levels.map((level) => `${indent} ${level},`).join("\n")}\n${indent}])`;
18
18
  };
19
- const clientLine = (baseURL) => baseURL === "https://wity-proxy-production-2c33.up.railway.app" ? "const client = new WityClient(); // reads WITY_API_KEY" : `const client = new WityClient({ baseURL: ${str(baseURL)} }); // reads WITY_API_KEY`;
19
+ const clientLine = (baseURL) => baseURL === "https://api.wity.alphanimble.com" ? "const client = new WityClient(); // reads WITY_API_KEY" : `const client = new WityClient({ baseURL: ${str(baseURL)} }); // reads WITY_API_KEY`;
20
20
  const systemOneTs = (request, baseURL) => {
21
21
  const types = [...new Set(Object.values(request.questions).map((q) => q.type))].sort();
22
22
  const questions = Object.entries(request.questions).map(([name, question]) => ` ${prop(name)}: ${builder(question, " ")},`).join("\n");
@@ -196,7 +196,7 @@ const sleep = (ms, signal) => new Promise((resolve, reject) => {
196
196
  * If it ever moves: change this line, bump the version and publish.
197
197
  * Until users update, they can set WITY_BASE_URL or the `baseURL` option.
198
198
  */
199
- const DEFAULT_BASE_URL = "https://wity-proxy-production-2c33.up.railway.app";
199
+ const DEFAULT_BASE_URL = "https://api.wity.alphanimble.com";
200
200
  /** Extra time on top of `max_latency_ms` for the network and Wity's own work. */
201
201
  const LATENCY_MARGIN_MS = 1e4;
202
202
  /** The longest delay `setTimeout` accepts. A longer one fires at once. */
@@ -307,7 +307,7 @@ var WityClient = class {
307
307
  if (!apiKey) throw new WityError("No API key found. Set the WITY_API_KEY environment variable, or pass apiKey to WityClient.");
308
308
  if (!KEY_PATTERN.test(apiKey)) throw new WityError("The API key contains spaces or unusual characters. Check WITY_API_KEY.");
309
309
  this.#apiKey = apiKey;
310
- this.baseURL = checkBaseURL(options.baseURL ?? readEnv("WITY_BASE_URL") ?? "https://wity-proxy-production-2c33.up.railway.app");
310
+ this.baseURL = checkBaseURL(options.baseURL ?? readEnv("WITY_BASE_URL") ?? "https://api.wity.alphanimble.com");
311
311
  this.timeoutMs = options.timeoutMs ?? 6e4;
312
312
  if (!Number.isFinite(this.timeoutMs) || this.timeoutMs <= 0 || this.timeoutMs > MAX_TIMER_MS) throw new WityError(`timeoutMs must be a positive number of milliseconds, at most ${MAX_TIMER_MS}.`);
313
313
  this.maxRetries = options.maxRetries ?? 2;
@@ -522,6 +522,12 @@ var CliError = class extends Error {
522
522
  const CONSOLE_URL = "https://wity.alphanimble.com";
523
523
  const KEYS_PAGE = `${CONSOLE_URL}/console/keys`;
524
524
  const BILLING_PAGE = `${CONSOLE_URL}/console/billing`;
525
+ /**
526
+ * Where the API lived before it moved to api.wity.alphanimble.com (SDK 0.1.1).
527
+ * Keys saved by CLI 0.1.0 are filed under it, so they're moved to the new address on first use.
528
+ * Both addresses reach the same server, so moving the key doesn't send it anywhere new.
529
+ */
530
+ const OLD_BASE_URL = "https://wity-proxy-production-2c33.up.railway.app";
525
531
  /** Dollars per million input tokens, from wity.alphanimble.com/pricing. Output and thinking are free. */
526
532
  const PRICE_PER_MILLION_INPUT_USD = .042;
527
533
  /**
@@ -530,7 +536,7 @@ const PRICE_PER_MILLION_INPUT_USD = .042;
530
536
  * The SDK does the full check (https only, no user or password) when the client is made.
531
537
  */
532
538
  const resolveBaseURL = (flag, env) => {
533
- const raw = flag?.trim() || env.WITY_BASE_URL?.trim() || "https://wity-proxy-production-2c33.up.railway.app";
539
+ const raw = flag?.trim() || env.WITY_BASE_URL?.trim() || "https://api.wity.alphanimble.com";
534
540
  let url;
535
541
  try {
536
542
  url = new URL(raw);
@@ -853,6 +859,21 @@ const openStore = async (env) => {
853
859
  if (wanted === "keychain") throw new CliError("No working keychain was found on this machine.", EXIT.auth, "Unset WITY_CREDENTIAL_STORE to save the key in a private file instead.");
854
860
  return fileStore(env);
855
861
  };
862
+ /**
863
+ * Moves the key saved under `from` to `to`, unless `to` already has one. `true` if a key was moved.
864
+ * The new entry is written before the old one is removed, so a failure never loses the key.
865
+ */
866
+ const moveKey = async (store, from, to) => {
867
+ if (from === to || await store.get(to)) return false;
868
+ const old = await store.get(from);
869
+ if (!old) return false;
870
+ await store.set({
871
+ ...old,
872
+ baseURL: to
873
+ });
874
+ await store.delete(from);
875
+ return true;
876
+ };
856
877
  /** WITY_API_KEY wins over a saved key, like in the SDK. `wity api-key show` says which one is in use. */
857
878
  const findKey = async (baseURL, env, store) => {
858
879
  const fromEnv = env.WITY_API_KEY?.trim();
@@ -1049,4 +1070,4 @@ const sendGenerate = async (ctx, request) => {
1049
1070
  }
1050
1071
  };
1051
1072
  //#endregion
1052
- export { truncate as A, score as B, cost as C, pct as D, painter as E, CliError as F, EXIT as I, DEFAULT_BASE_URL as L, KEYS_PAGE as M, PRICE_PER_MILLION_INPUT_USD as N, shouldColor as O, resolveBaseURL as P, choice as R, cleanBlock as S, ms as T, explain as _, checkStateLength as a, bar as b, MAX_STATE_CHARS as c, readStdin as d, findKey as f, checkKey as g, checkHealth as h, askFileSchema as i, writeJson as j, spinner as k, readHidden as l, openStore as m, sendGenerate as n, describeIssues as o, keyPrefix as p, sendSystemOne as r, questionSchema as s, requireKey as t, readState as u, makeClient as v, decimal as w, clean as x, refusedHint as y, noul as z };
1073
+ export { spinner as A, choice as B, cleanBlock as C, painter as D, ms as E, PRICE_PER_MILLION_INPUT_USD as F, score as H, resolveBaseURL as I, CliError as L, writeJson as M, KEYS_PAGE as N, pct as O, OLD_BASE_URL as P, EXIT as R, clean as S, decimal as T, noul as V, checkKey as _, checkStateLength as a, refusedHint as b, MAX_STATE_CHARS as c, readStdin as d, findKey as f, checkHealth as g, openStore as h, askFileSchema as i, truncate as j, shouldColor as k, readHidden as l, moveKey as m, sendGenerate as n, describeIssues as o, keyPrefix as p, sendSystemOne as r, questionSchema as s, requireKey as t, readState as u, explain as v, cost as w, bar as x, makeClient as y, DEFAULT_BASE_URL as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wity-cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Command-line tool for Wity, the typed-decision API",
5
5
  "homepage": "https://wity.alphanimble.com",
6
6
  "repository": {
@@ -10,7 +10,7 @@
10
10
  "license": "Apache-2.0",
11
11
  "type": "module",
12
12
  "bin": {
13
- "wity": "./dist/cli.mjs"
13
+ "wity": "dist/cli.mjs"
14
14
  },
15
15
  "files": [
16
16
  "dist",
@@ -45,6 +45,6 @@
45
45
  "tsdown": "^0.23.0",
46
46
  "typescript": "^6.0.3",
47
47
  "vitest": "^5.0.2",
48
- "wity-sdk": "^0.1.0"
48
+ "wity-sdk": "^0.1.1"
49
49
  }
50
50
  }