@amdahl/cli 0.3.6 → 0.3.7

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
@@ -503,6 +503,33 @@ nothing. `--site <origin>` sends both requests to another origin, for
503
503
  example a local copy of the site (`--site http://localhost:6782`). The
504
504
  origin must be `https`; `http` is allowed only for localhost.
505
505
 
506
+ ## Feedback link
507
+
508
+ Without `--json`, `amdahl optimize` ends each run with its run id:
509
+
510
+ ```
511
+ Run: 3f2c8a1e-...
512
+ ```
513
+
514
+ Under `--json` the run id is in `result.run_id` and nothing extra prints.
515
+
516
+ Amdahl staff can opt in to a feedback link after the run id. The link opens the
517
+ run's internal page in the Amdahl console, which only staff can see. It is off
518
+ by default. To turn it on:
519
+
520
+ - Set `"feedbackLink": true` at the top level of the config file
521
+ (`${XDG_CONFIG_HOME:-~/.config}/amdahl/config.json`, or
522
+ `%APPDATA%\amdahl\config.json` on Windows).
523
+ - Or set `AMDAHL_FEEDBACK_LINK=1` for one command or shell.
524
+ `AMDAHL_FEEDBACK_LINK=0` turns it off even when the config turns it on.
525
+
526
+ The link uses the console for your API host (see
527
+ [Targeting staging](#targeting-staging)).
528
+
529
+ Every request to the Amdahl API sends the headers
530
+ `X-Amdahl-Client: cli/<version>` and `User-Agent: amdahl-cli/<version>`, so
531
+ Amdahl can tell which runs came from the CLI. The headers are only labels. It never changes what a credential can do.
532
+
506
533
  ## Targeting staging
507
534
 
508
535
  ```sh
package/dist/amdahl.js CHANGED
@@ -8022,7 +8022,14 @@ Global options:
8022
8022
  -v, --version Show the version
8023
8023
  `;
8024
8024
 
8025
+ // src/version.ts
8026
+ var VERSION = "0.3.7";
8027
+
8025
8028
  // src/api.ts
8029
+ var CLIENT_HEADER = {
8030
+ "X-Amdahl-Client": `cli/${VERSION}`,
8031
+ "User-Agent": `amdahl-cli/${VERSION}`
8032
+ };
8026
8033
  var AmdahlApiError = class extends Error {
8027
8034
  constructor(message2, statusCode, path, responseBody, errorCode) {
8028
8035
  super(message2);
@@ -8110,7 +8117,7 @@ function createAmdahlClient(config) {
8110
8117
  const { baseUrl, token } = config;
8111
8118
  async function request(path, options = {}) {
8112
8119
  const { method = "GET", body, headers = {} } = options;
8113
- const allHeaders = { ...headers, Authorization: `Bearer ${token}` };
8120
+ const allHeaders = { ...headers, ...CLIENT_HEADER, Authorization: `Bearer ${token}` };
8114
8121
  if (body && !allHeaders["Content-Type"]) allHeaders["Content-Type"] = "application/json";
8115
8122
  const response = await fetch(`${baseUrl}${path}`, {
8116
8123
  method,
@@ -8177,7 +8184,8 @@ function loadConfig(io) {
8177
8184
  return {
8178
8185
  version: 1,
8179
8186
  default_profile: typeof parsed.default_profile === "string" ? parsed.default_profile : null,
8180
- profiles: parsed.profiles && typeof parsed.profiles === "object" ? parsed.profiles : {}
8187
+ profiles: parsed.profiles && typeof parsed.profiles === "object" ? parsed.profiles : {},
8188
+ ...typeof parsed.feedbackLink === "boolean" ? { feedbackLink: parsed.feedbackLink } : {}
8181
8189
  };
8182
8190
  } catch {
8183
8191
  return emptyConfig();
@@ -8199,6 +8207,12 @@ function saveConfig(io, config) {
8199
8207
  function selectedProfileName(io, config, flag) {
8200
8208
  return flag || io.env.AMDAHL_PROFILE || config.default_profile || null;
8201
8209
  }
8210
+ function feedbackLinkOn(io, config) {
8211
+ const env = io.env.AMDAHL_FEEDBACK_LINK?.trim().toLowerCase();
8212
+ if (env === "0" || env === "false" || env === "off") return false;
8213
+ if (env === "1" || env === "true" || env === "on") return true;
8214
+ return config.feedbackLink ?? false;
8215
+ }
8202
8216
 
8203
8217
  // src/oauth.ts
8204
8218
  import { createHash, randomBytes } from "crypto";
@@ -8213,7 +8227,7 @@ function createPkce() {
8213
8227
  }
8214
8228
  async function send(url, init) {
8215
8229
  try {
8216
- return await fetch(url, init);
8230
+ return await fetch(url, { ...init, headers: { ...init?.headers, ...CLIENT_HEADER } });
8217
8231
  } catch (err) {
8218
8232
  const message2 = err instanceof Error ? err.message : String(err);
8219
8233
  throw new CliError("network_error", `Could not reach ${new URL(url).host}: ${message2}`, EXIT.network, NETWORK_HINT);
@@ -9961,6 +9975,13 @@ function whatAmdahlDid(result) {
9961
9975
  const kept = new Set([...lines].sort((a, b) => a.rank - b.rank).slice(0, MAX_LINES));
9962
9976
  return lines.filter((l) => kept.has(l)).map((l) => l.line);
9963
9977
  }
9978
+ function feedbackLines(ctx, result) {
9979
+ const runId = text(result.run_id);
9980
+ if (!runId) return [];
9981
+ if (!feedbackLinkOn(ctx.io, ctx.config)) return [`Run: ${runId}`];
9982
+ const url = `${consoleUrlFor(ctx.io, ctx.apiUrl)}/admin/optimizer/runs/${encodeURIComponent(runId)}`;
9983
+ return [`Run: ${runId}`, `Feedback: ${url}`];
9984
+ }
9964
9985
  var PASTE_PROMPT = "Paste an email or LinkedIn message, then press Enter on an empty line:";
9965
9986
  var VERSION_RULE = "\u2500\u2500 Amdahl's version \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500";
9966
9987
  function nextTimeLine(ctx) {
@@ -10033,7 +10054,7 @@ ${nextTimeLine(ctx)}`);
10033
10054
  if (result.unchanged === true) out.info("No rewrite beat your draft; it is returned unchanged.");
10034
10055
  out.result({}, String(result.message ?? ""));
10035
10056
  const did = whatAmdahlDid(result);
10036
- out.info([...did, nextTimeLine(ctx)].join("\n"));
10057
+ out.info([...did, ...feedbackLines(ctx, result), nextTimeLine(ctx)].join("\n"));
10037
10058
  return EXIT.ok;
10038
10059
  }
10039
10060
  async function optimize(ctx, args) {
@@ -10079,8 +10100,8 @@ async function optimize(ctx, args) {
10079
10100
  if (result.unchanged === true) out.info("No rewrite beat your draft; it is returned unchanged.");
10080
10101
  else if (typeof result.summary === "string") out.info(result.summary);
10081
10102
  out.result({}, String(result.message ?? ""));
10082
- const did = whatAmdahlDid(result);
10083
- if (did.length) out.info(did.join("\n"));
10103
+ const lines = [...whatAmdahlDid(result), ...feedbackLines(ctx, result)];
10104
+ if (lines.length) out.info(lines.join("\n"));
10084
10105
  }
10085
10106
  }
10086
10107
  if (out.json) out.result(results.length === 1 ? results[0] : results);
@@ -11008,9 +11029,6 @@ async function workspaceUse(ctx, args) {
11008
11029
  return EXIT.ok;
11009
11030
  }
11010
11031
 
11011
- // src/version.ts
11012
- var VERSION = "0.3.6";
11013
-
11014
11032
  // src/main.ts
11015
11033
  var COMMANDS = {
11016
11034
  login: (ctx) => login(ctx),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amdahl/cli",
3
- "version": "0.3.6",
3
+ "version": "0.3.7",
4
4
  "type": "module",
5
5
  "description": "The amdahl command line: sign in, check setup, optimize messages, manage API keys, connect MCP clients.",
6
6
  "license": "Apache-2.0",