@letterstory/cli 0.177.36 → 0.177.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/lib/cli.mjs CHANGED
@@ -88,7 +88,7 @@ import {
88
88
  import { fetchParkedSections, withoutParked } from "./parked.mjs";
89
89
 
90
90
  // Matches cli/package.json; publish-cli.yml rewrites both to the published version.
91
- export const VERSION = "0.177.36";
91
+ export const VERSION = "0.177.38";
92
92
 
93
93
  /** The exit code for a gate refusal (CARD_REQUIRED, PAYMENT_FAILED, OUT_OF_TOKENS): 1 is a plain error. */
94
94
  export const EXIT_PAYMENT_REQUIRED = 3;
@@ -97,6 +97,8 @@ export const EXIT_PAYMENT_REQUIRED = 3;
97
97
  // can't accidentally swallow the id as --json's value. Every `type: "bool"` flag (and its
98
98
  // `negate` spelling) in a command's ARGS map must be listed; boolean-flags.test.ts enforces it.
99
99
  export const BOOLEAN_FLAGS = new Set([
100
+ // Models material: retain a request for attachments before preparing it.
101
+ "stage-only",
100
102
  // visits export: only the people or companies who fit the ICP, or only those who don't.
101
103
  "icp",
102
104
  "not-icp",
@@ -2093,7 +2095,13 @@ Models (your own writing models, each trained on writing you give it so it write
2093
2095
  Budget: the most one training run may cost (default $100)
2094
2096
  models show <id> Its links, its training and what it cost
2095
2097
  models upload <id> <file-or-folder>… Import files, folders or ZIPs without training
2096
- models material <id> "<material or request>" Paste material or find original sources
2098
+ models material <id> "<material or request>" [--stage-only] [--request <id>] [--from-request <id>]
2099
+ Prepare material; --stage-only creates a request for uploads
2100
+ models material-show <id> <request-id> [--selection <id>] [--offset <n>]
2101
+ Read progress and selected original text
2102
+ models material-review <id> <request-id> [<selection-id>…] [--cancel]
2103
+ Accept this request, or cancel it; never trains
2104
+ models material-history <id> [--offset <n>] Earlier material requests
2097
2105
  models add <id> <url>… [--train] Links to pieces of your writing; --train starts training
2098
2106
  models find <id> "<the writing to find>" [--max <n>] Letter finds the links and proposes them
2099
2107
  models confirm <id> [<link-id>…] [--keep-rest] [--no-train]
@@ -52,13 +52,31 @@ export const ARGS = {
52
52
  },
53
53
  import_writing_model_files: {
54
54
  model_id: modelId,
55
+ request_id: "request",
55
56
  files: { internal: "models upload <id> <file-or-folder>…; 3 MB batches" },
56
57
  },
57
58
  ingest_writing_model_material: {
58
59
  model_id: modelId,
60
+ request_id: "request",
61
+ from_request_id: "from-request",
62
+ stage: { flag: "stage-only", type: "bool" },
59
63
  text: { value: (flags, positionals) => positionals.slice(1).join(" ") },
60
64
  documents: { internal: "extract_document then generic mcp call" },
61
65
  },
66
+ list_writing_model_material: { model_id: modelId, offset: { flag: "offset", type: "num" } },
67
+ get_writing_model_material: {
68
+ model_id: modelId,
69
+ request_id: { positional: 1, required: true, label: "request-id" },
70
+ offset: { flag: "offset", type: "num" },
71
+ selection_id: "selection",
72
+ },
73
+ review_writing_model_material: {
74
+ model_id: modelId,
75
+ request_id: { positional: 1, required: true, label: "request-id" },
76
+ action: { value: (flags) => (flags.cancel ? "cancel" : "accept") },
77
+ accept: { value: (flags, p) => rest(2)(flags, p) ?? "all" },
78
+ exclude: { internal: "generic mcp call" },
79
+ },
62
80
  add_writing_model_texts: {
63
81
  model_id: modelId,
64
82
  documents: {
@@ -166,7 +184,11 @@ export async function cmdModels(ctx) {
166
184
  bytes += file.size;
167
185
  batch.push({ filename: file.filename, content_base64: readFileSync(file.path).toString("base64") });
168
186
  }
169
- result = await next.client.callTool("import_writing_model_files", { model_id: id, files: batch });
187
+ result = await next.client.callTool("import_writing_model_files", {
188
+ model_id: id,
189
+ files: batch,
190
+ ...(flagStr(next.flags.request) ? { request_id: flagStr(next.flags.request) } : {}),
191
+ });
170
192
  added += result.added;
171
193
  issues.push(...result.issues);
172
194
  uploads.splice(0, batch.length);
@@ -176,6 +198,17 @@ export async function cmdModels(ctx) {
176
198
  );
177
199
  return issues.length ? 1 : 0;
178
200
  }
201
+ case "material-review":
202
+ printResult(next.io, next.flags, await call(next, "review_writing_model_material"), (r) =>
203
+ JSON.stringify(r)
204
+ );
205
+ return 0;
206
+ case "material-history":
207
+ printResult(next.io, next.flags, await call(next, "list_writing_model_material"), (r) => JSON.stringify(r));
208
+ return 0;
209
+ case "material-show":
210
+ printResult(next.io, next.flags, await call(next, "get_writing_model_material"), (r) => JSON.stringify(r));
211
+ return 0;
179
212
  case "material": {
180
213
  refuseUnknownFlags(next, ARGS.ingest_writing_model_material, []);
181
214
  return modelShow(next, await call(next, "ingest_writing_model_material"));
@@ -5,7 +5,7 @@
5
5
  //
6
6
  // letterstory vary list [--status running]
7
7
  // letterstory vary create --page https://acme.com/pricing [--name "Pricing headline"] [--goals-file goals.json]
8
- // letterstory vary launch [--brief "Test the hero button"] [--page https://acme.com/] [--name <n>]
8
+ // letterstory vary launch [--brief "Test the hero button"] [--page https://acme.com/] [--name <n>] [--draft]
9
9
  // made, given a challenger Letter writes from the page, and started (Ideas' A/B test row)
10
10
  // letterstory vary get <id>
11
11
  // letterstory vary page <id> the page's blocks, as a change's tag/before/occurrence
@@ -84,6 +84,8 @@ export const ARGS = {
84
84
  page_url: "page",
85
85
  site_id: "site",
86
86
  name: "name",
87
+ // --draft: make the test and its challenger, leave it for a person to start (start false).
88
+ start: { flag: "start", type: "bool", negate: "draft" },
87
89
  },
88
90
  ship_variational_winner: {
89
91
  variational_id: variationalId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@letterstory/cli",
3
- "version": "0.177.36",
3
+ "version": "0.177.38",
4
4
  "description": "Spin up and manage Letter phantom blogs from your terminal.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",