@mirage-cli/contentdynamite-cli 1.0.0 → 1.1.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 +1 -1
- package/dist/bin.js +3 -3
- package/dist/client.d.ts +1 -1
- package/dist/{index-b00ea6js.js → index-3v4effdk.js} +81 -60
- package/dist/index.js +7 -7
- package/dist/version.d.ts +1 -1
- package/dist/wire.d.ts +8 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -37,7 +37,7 @@ Or pass a token per call: `--token ved_xxx` or `VE_DYNAMITE_TOKEN=ved_xxx`. Prec
|
|
|
37
37
|
| `icp` | `show`, `export`, `regenerate`, `update` |
|
|
38
38
|
| `categories` | `list`, `add` |
|
|
39
39
|
| `design-system` | `show`, `set <profile-id> <zip>`, `rescan`, `clear` |
|
|
40
|
-
| `articles` | `write`, `research-prompt`, `get`, `list`, `watch`, `update`, `delete`, `download`, `export`, `parts`, `reject`, `revisions`, `provenance-audit`, `clean-provenance`, `embed-audit`, `strip-embeds` |
|
|
40
|
+
| `articles` | `write`, `research-prompt`, `get`, `list`, `watch`, `update`, `delete`, `download`, `export-docs`, `export`, `parts`, `reject`, `revisions`, `provenance-audit`, `clean-provenance`, `embed-audit`, `strip-embeds` |
|
|
41
41
|
| `revisions` | `list`, `get`, `watch`, `verdict` |
|
|
42
42
|
| `batches` | `create`, `list`, `get`, `watch`, `delete` |
|
|
43
43
|
| `gbp` | `write`, `batch`, `list`, `get`, `watch`, `update`, `regenerate`, `delete`, `image-options` |
|
package/dist/bin.js
CHANGED
package/dist/client.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export declare class ApiClient {
|
|
|
13
13
|
content: Uint8Array;
|
|
14
14
|
filename: string | null;
|
|
15
15
|
}>;
|
|
16
|
-
post<T = unknown>(path: string, body?: unknown, params?: Params): Promise<T>;
|
|
16
|
+
post<T = unknown>(path: string, body?: unknown, params?: Params, timeoutMs?: number): Promise<T>;
|
|
17
17
|
postForm<T = unknown>(path: string, file: Blob, filename: string, params?: Params): Promise<T>;
|
|
18
18
|
put<T = unknown>(path: string, body?: unknown): Promise<T>;
|
|
19
19
|
patch<T = unknown>(path: string, body?: unknown): Promise<T>;
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
// src/version.ts
|
|
2
|
-
var VERSION = "1.0.0";
|
|
3
|
-
|
|
4
1
|
// src/program.ts
|
|
5
2
|
import { Command, CommanderError as CommanderError2, Option as Option4 } from "commander";
|
|
6
3
|
|
|
@@ -217,45 +214,45 @@ function cleanTableSources(sources) {
|
|
|
217
214
|
return pairs.length > 0 ? Object.fromEntries(pairs) : null;
|
|
218
215
|
}
|
|
219
216
|
function normaliseJobItem(item) {
|
|
220
|
-
const
|
|
221
|
-
if (
|
|
222
|
-
const cleaned = cleanList(
|
|
223
|
-
|
|
217
|
+
const out = { ...item, extra_guidelines: blankToNull(item.extra_guidelines), image_guideline: blankToNull(item.image_guideline) };
|
|
218
|
+
if (out.internal_links !== null) {
|
|
219
|
+
const cleaned = cleanList(out.internal_links);
|
|
220
|
+
out.internal_links = cleaned.length > 0 ? cleaned : null;
|
|
224
221
|
}
|
|
225
|
-
if (
|
|
226
|
-
const cleaned = cleanList(
|
|
222
|
+
if (out.external_links !== null) {
|
|
223
|
+
const cleaned = cleanList(out.external_links);
|
|
227
224
|
if (cleaned.length > 5)
|
|
228
225
|
return "external_links: maximum 5 URLs allowed";
|
|
229
226
|
const invalid = cleaned.find((url) => !isHttpUrl(url));
|
|
230
227
|
if (invalid !== undefined)
|
|
231
228
|
return `external_links: '${invalid}' is not an http(s) URL`;
|
|
232
|
-
|
|
229
|
+
out.external_links = cleaned.length > 0 ? cleaned : null;
|
|
233
230
|
}
|
|
234
|
-
if (
|
|
235
|
-
const cleaned = cleanList(
|
|
231
|
+
if (out.competitor_links !== null) {
|
|
232
|
+
const cleaned = cleanList(out.competitor_links);
|
|
236
233
|
if (cleaned.length > 3)
|
|
237
234
|
return "competitor_links: maximum 3 URLs allowed";
|
|
238
|
-
|
|
235
|
+
out.competitor_links = cleaned.length > 0 ? cleaned : null;
|
|
239
236
|
}
|
|
240
|
-
|
|
241
|
-
if (
|
|
237
|
+
out.listicle_research = blankToNull(out.listicle_research);
|
|
238
|
+
if (out.article_type === "listicle" && !out.listicle_research)
|
|
242
239
|
return "listicle_research is required when article_type is 'listicle'";
|
|
243
|
-
if (
|
|
240
|
+
if (out.item_count !== null && !(out.item_count >= 3 && out.item_count <= 10))
|
|
244
241
|
return "item_count must be between 3 and 10";
|
|
245
|
-
|
|
246
|
-
if (
|
|
247
|
-
const cleaned = cleanList(
|
|
242
|
+
out.brand_facts = blankToNull(out.brand_facts);
|
|
243
|
+
if (out.allowed_competitors !== null) {
|
|
244
|
+
const cleaned = cleanList(out.allowed_competitors);
|
|
248
245
|
if (cleaned.length > 12)
|
|
249
246
|
return "allowed_competitors: maximum 12 names allowed";
|
|
250
|
-
|
|
247
|
+
out.allowed_competitors = cleaned.length > 0 ? cleaned : null;
|
|
251
248
|
}
|
|
252
|
-
if (
|
|
253
|
-
const sources = cleanTableSources(
|
|
249
|
+
if (out.table_sources !== null) {
|
|
250
|
+
const sources = cleanTableSources(out.table_sources);
|
|
254
251
|
if (typeof sources === "string")
|
|
255
252
|
return sources;
|
|
256
|
-
|
|
253
|
+
out.table_sources = sources;
|
|
257
254
|
}
|
|
258
|
-
return
|
|
255
|
+
return out;
|
|
259
256
|
}
|
|
260
257
|
var articleDto = articleJobItem.transform((item, context) => {
|
|
261
258
|
const normalised = normaliseJobItem(item);
|
|
@@ -309,24 +306,24 @@ var gbpPostJobItem = z3.object({
|
|
|
309
306
|
var TEXT_FIELDS = ["topic", "location", "facts", "guidelines", "image_url", "image_guideline"];
|
|
310
307
|
var isHttpUrl2 = (url) => /^https?:\/\//.test(url.toLowerCase());
|
|
311
308
|
function normaliseGbpJob(item) {
|
|
312
|
-
const
|
|
309
|
+
const out = { ...item };
|
|
313
310
|
for (const field of TEXT_FIELDS) {
|
|
314
|
-
const value =
|
|
311
|
+
const value = out[field];
|
|
315
312
|
if (value !== null)
|
|
316
|
-
|
|
313
|
+
out[field] = value.trim() || null;
|
|
317
314
|
}
|
|
318
|
-
if (!
|
|
315
|
+
if (!out.topic && out.article_id === null)
|
|
319
316
|
return "a post needs either a topic or an article_id to repurpose";
|
|
320
|
-
const mode =
|
|
321
|
-
if (mode === "supplied" && !
|
|
317
|
+
const mode = out.image_mode ?? (out.image_url ? "supplied" : out.article_id !== null ? "article" : "generate");
|
|
318
|
+
if (mode === "supplied" && !out.image_url)
|
|
322
319
|
return "image_mode 'supplied' needs an image_url";
|
|
323
|
-
if (mode === "article" &&
|
|
320
|
+
if (mode === "article" && out.article_id === null)
|
|
324
321
|
return "image_mode 'article' needs an article_id to take the image from";
|
|
325
|
-
if (
|
|
326
|
-
return `image_url: '${
|
|
327
|
-
if (
|
|
322
|
+
if (out.image_url && !isHttpUrl2(out.image_url))
|
|
323
|
+
return `image_url: '${out.image_url}' is not an http(s) URL`;
|
|
324
|
+
if (out.image_guideline && mode !== "generate")
|
|
328
325
|
return "image_guideline only applies when image_mode is 'generate'";
|
|
329
|
-
return { ...
|
|
326
|
+
return { ...out, image_mode: mode };
|
|
330
327
|
}
|
|
331
328
|
var gbpPostDto = gbpPostJobItem.transform((item, context) => {
|
|
332
329
|
const normalised = normaliseGbpJob(item);
|
|
@@ -348,16 +345,16 @@ var updateGbpPostDto = z3.object({
|
|
|
348
345
|
else if (dto.image_url != null && dto.image_url.trim() && !isHttpUrl2(dto.image_url.trim())) {
|
|
349
346
|
context.addIssue({ code: "custom", message: `Value error, image_url: '${dto.image_url.trim()}' is not an http(s) URL` });
|
|
350
347
|
} else {
|
|
351
|
-
const
|
|
348
|
+
const out = {};
|
|
352
349
|
if (dto.content != null)
|
|
353
|
-
|
|
350
|
+
out.content = dto.content;
|
|
354
351
|
if (dto.status != null)
|
|
355
|
-
|
|
352
|
+
out.status = dto.status;
|
|
356
353
|
if (dto.topic !== undefined)
|
|
357
|
-
|
|
354
|
+
out.topic = dto.topic;
|
|
358
355
|
if (dto.image_url !== undefined)
|
|
359
|
-
|
|
360
|
-
return
|
|
356
|
+
out.image_url = dto.image_url?.trim() || null;
|
|
357
|
+
return out;
|
|
361
358
|
}
|
|
362
359
|
return z3.NEVER;
|
|
363
360
|
});
|
|
@@ -426,7 +423,7 @@ function quote(value) {
|
|
|
426
423
|
function toCsv(jobs, required, optional) {
|
|
427
424
|
const columns = [...required, ...optional.filter((field) => jobs.some((job) => job[field] != null))];
|
|
428
425
|
const lines = [columns, ...jobs.map((job) => columns.map((column) => cell(job[column])))];
|
|
429
|
-
return lines.map((
|
|
426
|
+
return lines.map((line) => line.map(quote).join(",") + `
|
|
430
427
|
`).join("");
|
|
431
428
|
}
|
|
432
429
|
var ARTICLE_REQUIRED = ["company_profile_id", "search_query", "primary_keywords"];
|
|
@@ -534,8 +531,8 @@ function parseCsv(text) {
|
|
|
534
531
|
return;
|
|
535
532
|
}
|
|
536
533
|
};
|
|
537
|
-
for (const
|
|
538
|
-
for (const character of
|
|
534
|
+
for (const line of text.match(/[^\n]*\n|[^\n]+$/g) ?? []) {
|
|
535
|
+
for (const character of line)
|
|
539
536
|
process2(character);
|
|
540
537
|
process2(EOL);
|
|
541
538
|
if (state === "start_record")
|
|
@@ -741,6 +738,11 @@ function registerArticles(program, cli) {
|
|
|
741
738
|
const target = await downloadDocument(cli, `content-writing/article/${articleId}/export`, options.format, options.output, `article-${articleId}`);
|
|
742
739
|
err(`exported article ${articleId} to ${target}`);
|
|
743
740
|
});
|
|
741
|
+
articles.command("export-docs").description("Export a finished article to a Google Doc in your connected Google Drive (free); Dynamite then tracks the writer's edits and QA comments on it").argument("<ID>", "Article id", integer).option("--replace", "Overwrite the existing doc with the current article instead of linking to it").action(async (articleId, options) => {
|
|
742
|
+
const res = await cli.client().post(`content-writing/article/${articleId}/export-to-docs`, undefined, { replace: options.replace ? "true" : undefined });
|
|
743
|
+
err(`${res.created ? "exported" : options.replace ? "replaced" : "already exported"} article ${articleId} to ${res.folder_path}`);
|
|
744
|
+
out(res);
|
|
745
|
+
});
|
|
744
746
|
articles.command("get").description("Show one article (slim {article_id, status} shape until the article completes)").argument("<ID>", "Article id", integer).action(async (articleId) => out(await cli.client().get(`content-writing/article/${articleId}`)));
|
|
745
747
|
articles.command("list").description("List articles, newest first").option("--page <page>", "Page number", integer, 1).option("--limit <limit>", "Page size (max 100)", integer, 10).option("--company <name>", "Filter by exact company name").option("--status <status>", "Filter by status: pending, success, failed").option("--batch-id <id>", "Filter by batch id", integer).action(async (options) => {
|
|
746
748
|
const status = wireStatus(options.status);
|
|
@@ -896,6 +898,10 @@ function describeDetail(text) {
|
|
|
896
898
|
return detail;
|
|
897
899
|
if (Array.isArray(detail))
|
|
898
900
|
return detail.map((item) => `${(item.loc ?? []).slice(1).join(".")}: ${item.msg}`).join("; ");
|
|
901
|
+
if (detail && typeof detail === "object" && typeof detail.msg === "string") {
|
|
902
|
+
const { msg, authorize_url: url } = detail;
|
|
903
|
+
return typeof url === "string" && url ? `${msg} Open this link to connect: ${url}` : msg;
|
|
904
|
+
}
|
|
899
905
|
return null;
|
|
900
906
|
} catch {
|
|
901
907
|
return null;
|
|
@@ -924,8 +930,8 @@ class ApiClient {
|
|
|
924
930
|
const filename = /filename="([^"]+)"/.exec(response.headers.get("content-disposition") ?? "")?.[1] ?? null;
|
|
925
931
|
return { content: new Uint8Array(await response.arrayBuffer()), filename };
|
|
926
932
|
}
|
|
927
|
-
post(path, body, params) {
|
|
928
|
-
return this.json("POST", path, { body, params });
|
|
933
|
+
post(path, body, params, timeoutMs) {
|
|
934
|
+
return this.json("POST", path, { body, params, timeoutMs });
|
|
929
935
|
}
|
|
930
936
|
postForm(path, file, filename, params) {
|
|
931
937
|
const form = new FormData;
|
|
@@ -944,14 +950,15 @@ class ApiClient {
|
|
|
944
950
|
async json(method, path, payload) {
|
|
945
951
|
return await (await this.request(method, path, payload)).json();
|
|
946
952
|
}
|
|
947
|
-
async request(method, path, { params, body, form }) {
|
|
953
|
+
async request(method, path, { params, body, form, timeoutMs }) {
|
|
948
954
|
const headers = this.token ? { Authorization: `Bearer ${this.token}` } : {};
|
|
949
955
|
let content = form;
|
|
950
956
|
if (!form && method !== "GET" && method !== "DELETE") {
|
|
951
957
|
headers["Content-Type"] = "application/json";
|
|
952
958
|
content = body == null ? undefined : JSON.stringify(body);
|
|
953
959
|
}
|
|
954
|
-
const
|
|
960
|
+
const limit = timeoutMs ? { signal: AbortSignal.timeout(timeoutMs), timeout: false } : {};
|
|
961
|
+
const response = await fetch(this.url(path, params), { method, headers, body: content, redirect: "manual", ...limit });
|
|
955
962
|
if (!response.ok)
|
|
956
963
|
throw await apiError(response);
|
|
957
964
|
return response;
|
|
@@ -1187,7 +1194,7 @@ function registerBatches(program, cli) {
|
|
|
1187
1194
|
if (!cli.mount) {
|
|
1188
1195
|
batches.command("watch").description("Poll a batch until every article is completed or failed").argument("<ID>", "Batch id", integer).option("--interval <seconds>", "Seconds between polls", decimal, 10).option("--timeout <seconds>", "Give up after this many seconds", decimal).action(async (batchId, options) => {
|
|
1189
1196
|
const client = cli.client();
|
|
1190
|
-
const settled = (
|
|
1197
|
+
const settled = (batch) => batch.completed_articles + batch.failed_articles;
|
|
1191
1198
|
const batch = await watchLoop({
|
|
1192
1199
|
interval: options.interval,
|
|
1193
1200
|
timeout: options.timeout,
|
|
@@ -1210,6 +1217,7 @@ function registerBatches(program, cli) {
|
|
|
1210
1217
|
|
|
1211
1218
|
// src/commands/evals.ts
|
|
1212
1219
|
var DEFAULT_THRESHOLD = 7;
|
|
1220
|
+
var JUDGED_QA_TIMEOUT_MS = 20 * 60 * 1000;
|
|
1213
1221
|
var ORIGIN_ORDER = ["copy", "inputs", "age", "blocked"];
|
|
1214
1222
|
var articleIds = (value, previous = []) => [...previous, integer(value)];
|
|
1215
1223
|
function originLine(lost) {
|
|
@@ -1249,6 +1257,17 @@ function printPart(name, part) {
|
|
|
1249
1257
|
for (const skipped of part.skipped)
|
|
1250
1258
|
line(` skipped: ${skipped}`);
|
|
1251
1259
|
}
|
|
1260
|
+
function printFormat(format) {
|
|
1261
|
+
line(` format ${format.format} code checks failing ${format.code.length}${format.rubric ? ` rubric ${format.rubric.passed}/${format.rubric.asked} passed` : ""}`);
|
|
1262
|
+
for (const failure of format.code)
|
|
1263
|
+
line(` - code ${failure.check.padEnd(24)} ${(failure.part ?? "-").padEnd(10)} ${failure.message}`);
|
|
1264
|
+
for (const failure of format.rubric?.failures ?? [])
|
|
1265
|
+
line(` - judge ${failure.check.padEnd(24)} ${(failure.part ?? "-").padEnd(10)} ${failure.message}`);
|
|
1266
|
+
if (format.rubric_error)
|
|
1267
|
+
err(` rubric did not run: ${format.rubric_error}`);
|
|
1268
|
+
for (const note of format.notes)
|
|
1269
|
+
line(` note: ${note}`);
|
|
1270
|
+
}
|
|
1252
1271
|
function printReport(articleId, res) {
|
|
1253
1272
|
const { content, image } = res.report;
|
|
1254
1273
|
const blended = content.score_with_model ?? content.score;
|
|
@@ -1271,10 +1290,12 @@ function printReport(articleId, res) {
|
|
|
1271
1290
|
printPart("craft", content.craft);
|
|
1272
1291
|
if (image)
|
|
1273
1292
|
printPart("image", image);
|
|
1293
|
+
if (res.report.format)
|
|
1294
|
+
printFormat(res.report.format);
|
|
1274
1295
|
}
|
|
1275
1296
|
function registerEvals(program, cli) {
|
|
1276
1297
|
const evals = program.command("evals").description("Score finished articles against the deterministic quality checks");
|
|
1277
|
-
evals.command("run").description("Score one or more articles. Free: no model is called.").argument("[ID...]", "Article ids. Omit with --all.", articleIds).option("--all", "Score every shipped article").option("--company <name>", "Only this company's articles (with --all)").option("--no-images", "Skip the per image fetch").option("--judge", "Also run the model judge.
|
|
1298
|
+
evals.command("run").description("Score one or more articles. Free: no model is called.").argument("[ID...]", "Article ids. Omit with --all.", articleIds).option("--all", "Score every shipped article").option("--company <name>", "Only this company's articles (with --all)").option("--no-images", "Skip the per image fetch").option("--judge", "Also run the model judge, and the format rubric on an article written in a format. Each costs a model call per article.").option("--store", "Keep the result on article.qa_report (the default)").option("--no-store", "Score without keeping the result").option("--threshold <score>", "Exit 1 if any article scores below this", decimal, DEFAULT_THRESHOLD).option("--limit <limit>", "Page size for --all", integer, 200).option("--json", "Emit the full report instead of a summary").action(async (ids, options) => {
|
|
1278
1299
|
const articles = ids ?? [];
|
|
1279
1300
|
if (options.all && articles.length > 0)
|
|
1280
1301
|
throw new Error("pass article ids or --all, not both");
|
|
@@ -1297,16 +1318,13 @@ function registerEvals(program, cli) {
|
|
|
1297
1318
|
const rows = [];
|
|
1298
1319
|
try {
|
|
1299
1320
|
for (const articleId of articles) {
|
|
1300
|
-
const res = await client.post(`content-writing/article/${articleId}/qa`, undefined, {
|
|
1301
|
-
model_checks: options.judge ? "true" : "false",
|
|
1302
|
-
store: options.store === false ? "false" : "true"
|
|
1303
|
-
});
|
|
1321
|
+
const res = await client.post(`content-writing/article/${articleId}/qa`, undefined, { model_checks: options.judge ? "true" : "false", store: options.store === false ? "false" : "true" }, options.judge ? JUDGED_QA_TIMEOUT_MS : undefined);
|
|
1304
1322
|
rows.push({ article_id: articleId, score: res.score, report: res.report });
|
|
1305
1323
|
if (!options.json)
|
|
1306
1324
|
printReport(articleId, res);
|
|
1307
1325
|
}
|
|
1308
1326
|
} finally {
|
|
1309
|
-
cli.billed(rows.filter((row) => row.report.content.judge).length);
|
|
1327
|
+
cli.billed(rows.filter((row) => row.report.content.judge).length + rows.filter((row) => row.report.format?.rubric).length);
|
|
1310
1328
|
}
|
|
1311
1329
|
if (options.json)
|
|
1312
1330
|
out(rows);
|
|
@@ -2122,9 +2140,12 @@ function cliFor(program, { mount = false, reportCost }) {
|
|
|
2122
2140
|
return cli;
|
|
2123
2141
|
}
|
|
2124
2142
|
|
|
2143
|
+
// src/version.ts
|
|
2144
|
+
var VERSION2 = "1.1.0";
|
|
2145
|
+
|
|
2125
2146
|
// src/program.ts
|
|
2126
|
-
function
|
|
2127
|
-
const program = new Command("ve-dynamite").description("Content Dynamite — content pipeline CLI").version(
|
|
2147
|
+
function buildProgram2(options = {}) {
|
|
2148
|
+
const program = new Command("ve-dynamite").description("Content Dynamite — content pipeline CLI").version(VERSION2, "-V, --version", "Print the version and exit").option("--token <token>", "Access token override (or set VE_DYNAMITE_TOKEN env)").addOption(new Option4("--pretty", "Has no effect: output is always indented JSON. Kept so older scripts still run").hideHelp());
|
|
2128
2149
|
if (!options.mount)
|
|
2129
2150
|
program.option("--url <url>", "API base URL (or set VE_DYNAMITE_API_URL env)");
|
|
2130
2151
|
program.exitOverride().configureOutput({ writeOut: (text) => io.stdout(text), writeErr: (text) => io.stderr(text) }).showHelpAfterError("(add --help for additional information)");
|
|
@@ -2143,9 +2164,9 @@ function buildProgram(options = {}) {
|
|
|
2143
2164
|
registerUpload(program, cli);
|
|
2144
2165
|
return program;
|
|
2145
2166
|
}
|
|
2146
|
-
async function
|
|
2167
|
+
async function run2(argv, options = {}) {
|
|
2147
2168
|
try {
|
|
2148
|
-
await
|
|
2169
|
+
await buildProgram2(options).parseAsync(argv, { from: "user" });
|
|
2149
2170
|
return 0;
|
|
2150
2171
|
} catch (error) {
|
|
2151
2172
|
if (error instanceof CommanderError2)
|
|
@@ -2155,4 +2176,4 @@ async function run(argv, options = {}) {
|
|
|
2155
2176
|
}
|
|
2156
2177
|
}
|
|
2157
2178
|
|
|
2158
|
-
export {
|
|
2179
|
+
export { VERSION2, buildProgram2, run2 };
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
} from "./index-
|
|
2
|
+
VERSION2,
|
|
3
|
+
buildProgram2,
|
|
4
|
+
run2
|
|
5
|
+
} from "./index-3v4effdk.js";
|
|
6
6
|
export {
|
|
7
|
-
|
|
8
|
-
buildProgram,
|
|
9
|
-
|
|
7
|
+
VERSION2 as VERSION,
|
|
8
|
+
buildProgram2 as buildProgram,
|
|
9
|
+
run2 as run
|
|
10
10
|
};
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "1.
|
|
1
|
+
export declare const VERSION = "1.1.0";
|
package/dist/wire.d.ts
CHANGED
|
@@ -24,8 +24,13 @@ export type CompanyProfileResponseDto = { id: number; company_name: string; webs
|
|
|
24
24
|
type JsonObject = { [key: string]: unknown };
|
|
25
25
|
type OwnerSummary = { username: string; profile: null | string };
|
|
26
26
|
export type ArticleDoneRes = { article_id: number; status: 'success'; title: string; slug: string; meta_description: null | string; h1: null | string; intro: null | string; body: null | string; faqs: null | string; feat_image: null | string; is_internal_link_set: boolean; article_type: null | 'listicle'; video_url: null | string; video_status: null | 'pending' | 'done' | 'failed'; interactive_type: null | 'quiz' | 'game' | 'calculator' | 'chart'; interactive_status: null | 'pending' | 'done' | 'failed' | 'skipped'; interactive_payload: null | JsonObject; interactive_embed: null | string; gbp_content: null | string; gbp_image_url: null | string; gbp_status: null | 'pending' | 'done' | 'failed'; provenance_report: null | JsonObject; dewatermark_status: null | 'done' | 'failed' | 'skipped'; created_at: string; owner: null | OwnerSummary; gdoc_url: null | string; company_name: string };
|
|
27
|
+
export type ArticleGdocRes = { gdoc_id: string; gdoc_url: string; created: boolean; folder_path: string };
|
|
27
28
|
export type ArticlePendingRes = { article_id: number; status: 'pending' | 'failed' };
|
|
28
|
-
|
|
29
|
+
type CheckSource = 'code' | 'jev' | 'judge';
|
|
30
|
+
type ReportedFailure = { source: CheckSource; check: string; part: null | string; message: string };
|
|
31
|
+
type RubricScore = { asked: number; passed: number; failures: ReportedFailure[] };
|
|
32
|
+
type FormatEval = { format: 'listicle' | 'how-to' | 'answer' | 'explainer' | 'comparison' | 'troubleshooting' | 'cost'; code: ReportedFailure[]; rubric: null | RubricScore; rubric_error: null | string; notes: string[] };
|
|
33
|
+
export type ArticleQaRes = { article_id: number; score: number; stored: boolean; report: { image: null; score: number; notes: string[]; format?: undefined | FormatEval; article_id: null | number; title: null | string; article_type: null | string; company: string; content: { score_with_model: number; weights_applied: { code: number; model: number }; judge: null | { scores: Record<'answers_the_search' | 'helpful' | 'first_hand' | 'client_trust' | 'structure' | 'anti_slop' | 'faq_consistent' | 'specific_reader', number>; total: number; ceiling: number; score: number; verdict: string; violations: string[]; strengths: string[]; top_fixes: string[]; model: string; body_trimmed: boolean; thresholds: { pass_total: number; min_dimension: number; min_anti_slop: number } }; judge_error: null | string; score: number; blended: boolean; weights: { compliance: number; craft: number }; compliance: { name: string; budget: number; score: number; trusted: boolean; deductions: { points: number; code: string; origin: string; message: string; evidence: string }[]; skipped: string[] }; craft: { name: string; budget: number; score: number; trusted: boolean; deductions: { points: number; code: string; origin: string; message: string; evidence: string }[]; skipped: string[] } }; weights: { content: number; image: number }; model_checks: boolean } | { image: { scaled_score: number; name: string; budget: number; score: number; trusted: boolean; deductions: { points: number; code: string; origin: string; message: string; evidence: string }[]; skipped: string[] }; score: number; notes: string[]; format?: undefined | FormatEval; article_id: null | number; title: null | string; article_type: null | string; company: string; content: { score_with_model: number; weights_applied: { code: number; model: number }; judge: null | { scores: Record<'answers_the_search' | 'helpful' | 'first_hand' | 'client_trust' | 'structure' | 'anti_slop' | 'faq_consistent' | 'specific_reader', number>; total: number; ceiling: number; score: number; verdict: string; violations: string[]; strengths: string[]; top_fixes: string[]; model: string; body_trimmed: boolean; thresholds: { pass_total: number; min_dimension: number; min_anti_slop: number } }; judge_error: null | string; score: number; blended: boolean; weights: { compliance: number; craft: number }; compliance: { name: string; budget: number; score: number; trusted: boolean; deductions: { points: number; code: string; origin: string; message: string; evidence: string }[]; skipped: string[] }; craft: { name: string; budget: number; score: number; trusted: boolean; deductions: { points: number; code: string; origin: string; message: string; evidence: string }[]; skipped: string[] } }; weights: { content: number; image: number }; model_checks: boolean } };
|
|
29
34
|
export type BatchRes = { batch_id: number; name: string; total_articles: number; completed_articles: number; failed_articles: number; created_at: string };
|
|
30
35
|
export type BatchWriteRes = { msg: string; batch_id: number; article_ids: number[]; total: number };
|
|
31
36
|
type CarrierCounts = { [key: string]: number };
|
|
@@ -56,8 +61,8 @@ type FaqContent = { html: string };
|
|
|
56
61
|
type VideoContent = { url: string };
|
|
57
62
|
type InteractiveContent = { type: 'quiz' | 'game' | 'calculator' | 'chart'; payload: JsonObject };
|
|
58
63
|
type PartContent = IntroContent | SectionContent | ImageContent | FaqContent | VideoContent | InteractiveContent;
|
|
59
|
-
export type RevisionDetailRes = { refused_report: null | JsonObject; replacement_report: null | JsonObject; revision_id: number; article_id: null | number; company_profile_id: null | number; part: 'intro' | 'section' | 'image' | 'feat_image' | 'faq' | 'video' | 'interactive'; index: null | number; target: null | '
|
|
60
|
-
export type RevisionRes = { revision_id: number; article_id: null | number; company_profile_id: null | number; part: 'intro' | 'section' | 'image' | 'feat_image' | 'faq' | 'video' | 'interactive'; index: null | number; target: null | '
|
|
64
|
+
export type RevisionDetailRes = { refused_report: null | JsonObject; replacement_report: null | JsonObject; revision_id: number; article_id: null | number; company_profile_id: null | number; part: 'intro' | 'section' | 'image' | 'feat_image' | 'faq' | 'video' | 'interactive'; index: null | number; target: null | 'answer' | 'section' | 'heading' | 'passage' | 'question'; text: null | string; reason: null | string; status: 'pending' | 'failed' | 'ready'; error: null | string; refused: PartContent; replacement: null | IntroContent | SectionContent | ImageContent | FaqContent | VideoContent | InteractiveContent; refused_score: null | number; replacement_score: null | number; verdict: null | 'better' | 'same' | 'worse'; verdict_note: null | string; applied: boolean; created_at: string; ready_at: null | string; decided_at: null | string };
|
|
65
|
+
export type RevisionRes = { revision_id: number; article_id: null | number; company_profile_id: null | number; part: 'intro' | 'section' | 'image' | 'feat_image' | 'faq' | 'video' | 'interactive'; index: null | number; target: null | 'answer' | 'section' | 'heading' | 'passage' | 'question'; text: null | string; reason: null | string; status: 'pending' | 'failed' | 'ready'; error: null | string; refused: PartContent; replacement: null | IntroContent | SectionContent | ImageContent | FaqContent | VideoContent | InteractiveContent; refused_score: null | number; replacement_score: null | number; verdict: null | 'better' | 'same' | 'worse'; verdict_note: null | string; applied: boolean; created_at: string; ready_at: null | string; decided_at: null | string };
|
|
61
66
|
export type VerdictRes = { revision: RevisionRes; applied: boolean; msg: string };
|
|
62
67
|
export type SetRoleRes = { msg: string; user: UserRes };
|
|
63
68
|
export type UserRes = { user_id: number; full_name: string; username: string; email: string; profile: null | string; role: 'admin' | 'normal'; is_verified: boolean; created_at: string };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mirage-cli/contentdynamite-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "The Content Dynamite CLI (ve-dynamite): SEO articles, Google Business Profile posts, BOFU landing pages, company profiles, ICP, design systems, revisions and featured images over the Content Dynamite API.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|