@audienti/cli 0.1.37 → 0.1.38

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/CHANGELOG.md CHANGED
@@ -4,6 +4,12 @@ All notable changes to the Audienti CLI are documented here.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.1.38] - 2026-08-24
8
+
9
+ ### Added
10
+
11
+ - Add `audienti tools humanize --file <path>` with optional tone and language controls, plain-text output for shell redirection, and normalized JSON output through the authenticated Audienti API.
12
+
7
13
  ## [0.1.37] - 2026-08-23
8
14
 
9
15
  ### Added
package/README.md CHANGED
@@ -174,12 +174,22 @@ audienti analytics users --user me --window 30d
174
174
  audienti analytics visibility --window 24h --user me
175
175
  audienti analytics content --window week
176
176
  audienti tools list
177
+ audienti tools humanize --file draft.txt --tone professional --language English
177
178
  audienti tools linkedin-review --url https://www.linkedin.com/in/example --icp <icp_id>
178
179
  audienti tools linkedin-review reports
179
180
  audienti tools linkedin-review show <rprt_id>
180
181
  audienti tools linkedin-review status <rprt_id>
181
182
  ```
182
183
 
184
+ To humanize arbitrary text without exposing the underlying provider key, pass a
185
+ UTF-8 file. Plain output contains only the transformed text, so it can be
186
+ redirected directly to another file:
187
+
188
+ ```bash
189
+ audienti tools humanize --file draft.txt --tone professional > revised.txt
190
+ audienti tools humanize --file draft.txt --language English --json
191
+ ```
192
+
183
193
  To let an agent or operator check whether the local CLI is behind the latest
184
194
  published package:
185
195
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@audienti/cli",
3
- "version": "0.1.37",
3
+ "version": "0.1.38",
4
4
  "description": "Agent-first command-line client for Audienti.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -120,6 +120,7 @@ audienti analytics stages --window 30d
120
120
  audienti analytics visibility --window 24h --user me --json
121
121
  audienti analytics content --window week --json
122
122
  audienti tools list --json
123
+ audienti tools humanize --file draft.txt --tone professional --json
123
124
  audienti tools linkedin-review --url https://www.linkedin.com/in/example --icp <icp_id> --json
124
125
  audienti tools linkedin-review reports --json
125
126
  audienti tools linkedin-review show <rprt_id> --json
package/src/api-client.js CHANGED
@@ -614,6 +614,13 @@ export class AudientiClient {
614
614
  return this.requestJson(accountPath(accountId, ["tools", "linkedin-review", "reports", reportId]));
615
615
  }
616
616
 
617
+ humanizeText(accountId, body) {
618
+ return this.requestJson(accountPath(accountId, ["tools", "humanize"]), {
619
+ method: "POST",
620
+ body: { humanization: body }
621
+ });
622
+ }
623
+
617
624
  operatorQueue(accountId, query = {}) {
618
625
  return this.requestJson(accountPath(accountId, ["operator"], query));
619
626
  }
package/src/cli.js CHANGED
@@ -112,6 +112,7 @@ const ANALYTICS_DASHBOARD_USAGE = "Usage: audienti analytics dashboard [--cohort
112
112
  const ANALYTICS_STAGES_USAGE = "Usage: audienti analytics stages [--interval weekly|monthly] [--cohort-start YYYY-MM-DD --cohort-end YYYY-MM-DD] [--play-tag <tag>] [--motion <motn_id>] [--list <list_id>] [--offer <offr_id>] [--icp <icp_id>] [--user <account_user_id|email|name|me>] [--json] [--account <acct_id>]";
113
113
  const ANALYTICS_COHORT_LIST_USAGE = "Usage: audienti analytics cohorts create-list --name <text> --start YYYY-MM-DD --end YYYY-MM-DD [--event connection_request_sent] [--user <account_user_id|email|name|me>] [--note-mode <any|with_note|blank>] [--motion <motn_id>] [--offer <offr_id>] [--icp <icp_id>] [--play-tag <tag>] [--json] [--account <acct_id>]";
114
114
  const TOOLS_LIST_USAGE = "Usage: audienti tools list [--json]";
115
+ const TOOLS_HUMANIZE_USAGE = "Usage: audienti tools humanize --file <path> [--tone <professional|academic|blog|casual|creative|scientific|technical>] [--language <language>] [--json] [--account <acct_id>]";
115
116
  const TOOLS_LINKEDIN_REVIEW_USAGE = "Usage: audienti tools linkedin-review --url <linkedin_url> [--icp <icp_id>] [--json] [--account <acct_id>]";
116
117
  const TOOLS_LINKEDIN_REVIEW_REPORTS_USAGE = "Usage: audienti tools linkedin-review reports [--limit <n>] [--json] [--account <acct_id>]";
117
118
  const TOOLS_LINKEDIN_REVIEW_SHOW_USAGE = "Usage: audienti tools linkedin-review show <rprt_id> [--json] [--account <acct_id>]";
@@ -299,6 +300,7 @@ async function dispatch(argv, context) {
299
300
  if (normalizedResource === "writer" && action === "test-run") return writerTestRun(rest, context, { accountOverride });
300
301
  if (normalizedResource === "tools" && action === "list") return toolsList(rest, context);
301
302
  if (normalizedResource === "tools" && action === "get") return toolsGet(rest, context, { accountOverride });
303
+ if (normalizedResource === "tools" && action === "humanize") return toolsHumanize(rest, context, { accountOverride });
302
304
  if (normalizedResource === "tools" && action === "linkedin-review") return toolsLinkedinReview(rest, context, { accountOverride });
303
305
  if (normalizedResource === "operator" && action === "failed-drafts") return operatorFailedDrafts(rest, context, { accountOverride });
304
306
  if (normalizedResource === "operator" && action === "queue") return operatorQueue(rest, context, { accountOverride });
@@ -2977,6 +2979,36 @@ async function toolsList(args, context) {
2977
2979
  renderToolsList(payload.tools, context);
2978
2980
  }
2979
2981
 
2982
+ async function toolsHumanize(args, context, { accountOverride } = {}) {
2983
+ const { values, positionals } = parseCommandArgs(args, {
2984
+ ...jsonOptions(),
2985
+ file: { type: "string" },
2986
+ tone: { type: "string" },
2987
+ language: { type: "string" }
2988
+ });
2989
+
2990
+ if (positionals.length > 0 || !values.file) {
2991
+ throw new CommandError(TOOLS_HUMANIZE_USAGE);
2992
+ }
2993
+
2994
+ const text = await readHumanizerFile(values.file);
2995
+ const { client, accountId } = await requireAccountContext(context, { accountOverride });
2996
+ const payload = await client.humanizeText(accountId, {
2997
+ text,
2998
+ tone: values.tone,
2999
+ language: values.language
3000
+ });
3001
+
3002
+ if (values.json) return writeJson(context.stdout, payload);
3003
+
3004
+ const humanizedText = String(payload?.humanized_text || "");
3005
+ if (!humanizedText.trim()) {
3006
+ throw new CommandError("The humanizer response did not include humanized_text.");
3007
+ }
3008
+ context.stdout.write(humanizedText);
3009
+ if (!humanizedText.endsWith("\n")) context.stdout.write("\n");
3010
+ }
3011
+
2980
3012
  async function toolsLinkedinReviewReports(args, context, { accountOverride } = {}) {
2981
3013
  const { values, positionals } = parseCommandArgs(args, {
2982
3014
  ...jsonOptions(),
@@ -4128,6 +4160,26 @@ async function readJsonPayload(filePath) {
4128
4160
  }
4129
4161
  }
4130
4162
 
4163
+ async function readHumanizerFile(filePath) {
4164
+ let bytes;
4165
+ try {
4166
+ bytes = await readFile(filePath);
4167
+ } catch (error) {
4168
+ throw new CommandError(`Could not read humanizer file ${filePath}: ${error.message}`);
4169
+ }
4170
+
4171
+ let contents;
4172
+ try {
4173
+ contents = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
4174
+ } catch {
4175
+ throw new CommandError(`Humanizer file ${filePath} must be valid UTF-8 text.`);
4176
+ }
4177
+
4178
+ if (!contents.trim()) throw new CommandError("Humanizer file cannot be blank.");
4179
+
4180
+ return contents;
4181
+ }
4182
+
4131
4183
  async function readProspectImportBatchFile(filePath) {
4132
4184
  let contents;
4133
4185
  try {
@@ -5531,6 +5583,13 @@ function availableTools() {
5531
5583
  reports_command: null,
5532
5584
  status_command: null
5533
5585
  },
5586
+ {
5587
+ id: "humanize",
5588
+ command: "audienti tools humanize --file <path> [--tone <tone>] [--language <language>]",
5589
+ description: "Humanize arbitrary text from a UTF-8 file and print the transformed result.",
5590
+ reports_command: null,
5591
+ status_command: null
5592
+ },
5534
5593
  {
5535
5594
  id: "linkedin-review",
5536
5595
  command: "audienti tools linkedin-review --url <linkedin_url> [--icp <icp_id>]",
@@ -6724,6 +6783,7 @@ const HELP_TOPICS = new Map([
6724
6783
  " audienti tools list",
6725
6784
  " audienti tools get email --url <linkedin_url>",
6726
6785
  " audienti tools get phone --url <linkedin_url>",
6786
+ " audienti tools humanize --file <path>",
6727
6787
  " audienti tools linkedin-review --url <linkedin_url> [--icp <icp_id>]",
6728
6788
  " audienti tools linkedin-review reports",
6729
6789
  " audienti tools linkedin-review show <rprt_id>",
@@ -9198,6 +9258,7 @@ const HELP_TOPICS = new Map([
9198
9258
  "Usage:",
9199
9259
  " audienti tools list [--json]",
9200
9260
  " audienti tools get <email|phone> --url <linkedin_url> [--json]",
9261
+ " audienti tools humanize --file <path> [--tone <tone>] [--language <language>] [--json]",
9201
9262
  " audienti tools linkedin-review --url <linkedin_url> [--icp <icp_id>] [--json]",
9202
9263
  " audienti tools linkedin-review reports [--limit <n>] [--json]",
9203
9264
  " audienti tools linkedin-review show <rprt_id> [--json]",
@@ -9208,6 +9269,7 @@ const HELP_TOPICS = new Map([
9208
9269
  "Commands:",
9209
9270
  " audienti tools list Show available CLI tools and the report commands they support.",
9210
9271
  " audienti tools get Run a LinkedIn URL through the existing import and contact-enrichment pipeline, then return the first selected email or phone.",
9272
+ " audienti tools humanize Humanize arbitrary UTF-8 text and print the result.",
9211
9273
  " audienti tools linkedin-review Queue a LinkedIn personal profile authority review and ICP-fit positioning blueprint.",
9212
9274
  " audienti tools linkedin-review reports List recent LinkedIn Review reports for the active account.",
9213
9275
  " audienti tools linkedin-review show View the completed report content in the terminal.",
@@ -9254,6 +9316,28 @@ const HELP_TOPICS = new Map([
9254
9316
  " JSON: { kind, url, found, value, import_id, status, ready, prospect, pipeline }"
9255
9317
  ].join("\n")],
9256
9318
 
9319
+ ["tools humanize", [
9320
+ "Usage:",
9321
+ ` ${TOOLS_HUMANIZE_USAGE.slice("Usage: ".length)}`,
9322
+ "",
9323
+ "Status: implemented",
9324
+ "",
9325
+ "Purpose:",
9326
+ " Sends arbitrary UTF-8 text to Audienti's server-side humanizer without exposing the provider key.",
9327
+ "",
9328
+ "Options:",
9329
+ " --file <path> Required UTF-8 text file",
9330
+ " --tone <professional|academic|blog|casual|creative|scientific|technical>",
9331
+ " --language <name> Optional language hint, for example English",
9332
+ "",
9333
+ "Output:",
9334
+ " Plain text: only the humanized text, suitable for redirecting to a file",
9335
+ " JSON: { humanized_text, id, input_words }",
9336
+ "",
9337
+ "API:",
9338
+ " POST /api/v1/accounts/:account_id/tools/humanize.json"
9339
+ ].join("\n")],
9340
+
9257
9341
  ["tools linkedin-review", [
9258
9342
  "Usage:",
9259
9343
  " audienti tools linkedin-review --url <linkedin_url> [--icp <icp_id>] [--json] [--account <acct_id>]",