@easysociable/cli 0.1.11 → 0.1.12

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
@@ -83,9 +83,10 @@ easysociable mcp serve --transport stdio
83
83
  |---------|---------|
84
84
  | `easysociable install [--yes] [--skills list]` | Install Skills + MCP |
85
85
  | `easysociable update [--yes] [--skills list]` | Update Skills + MCP |
86
- | `easysociable templates …` | Page Template drafts / catalog |
86
+ | `easysociable templates …` | Page Template drafts / catalog (`list --platform <p> --all` for a full platform catalog) |
87
87
  | `easysociable brands …` | Workspace Brands |
88
88
  | `easysociable slideshows …` | Slideshow Runs |
89
+ | `easysociable slideshows recommend --file contracts.json --seed <slug>` | Per-page template shortlist from Page Contracts (recent families demoted, gaps reported) |
89
90
  | `easysociable renders …` | Single-page final render jobs |
90
91
  | `easysociable mcp serve --transport stdio` | Unified MCP server |
91
92
 
@@ -16297,11 +16297,13 @@ function isRetryableStatus(status) {
16297
16297
  function sleep(ms) {
16298
16298
  return new Promise((resolve3) => setTimeout(resolve3, ms));
16299
16299
  }
16300
- var TemplateGatewayError, TemplateGatewayClient;
16300
+ var DEFAULT_TEMPLATE_PAGE_SIZE, MAX_TEMPLATE_PAGE_SIZE, TemplateGatewayError, TemplateGatewayClient;
16301
16301
  var init_client = __esm({
16302
16302
  "../../packages/template-gateway-client/src/client.ts"() {
16303
16303
  "use strict";
16304
16304
  init_src();
16305
+ DEFAULT_TEMPLATE_PAGE_SIZE = 20;
16306
+ MAX_TEMPLATE_PAGE_SIZE = 50;
16305
16307
  TemplateGatewayError = class extends Error {
16306
16308
  code;
16307
16309
  retryable;
@@ -16347,6 +16349,13 @@ var init_client = __esm({
16347
16349
  return response.json;
16348
16350
  }
16349
16351
  async listTemplates(query) {
16352
+ return (await this.listTemplatesPage(query)).templates;
16353
+ }
16354
+ /**
16355
+ * Same as listTemplates plus `nextCursor` so Agents know the catalog is paged.
16356
+ * Derived client-side (full page ⇒ maybe more) to keep the strict v1 envelope.
16357
+ */
16358
+ async listTemplatesPage(query) {
16350
16359
  const parsed = parseListTemplatesQuery(query ?? {});
16351
16360
  const params = new URLSearchParams();
16352
16361
  const appendList = (key, values) => {
@@ -16375,7 +16384,23 @@ var init_client = __esm({
16375
16384
  const qs = params.toString();
16376
16385
  const response = await this.request("GET", qs ? `/v1/templates?${qs}` : "/v1/templates");
16377
16386
  this.throwIfError(response.status, response.json);
16378
- return parseTemplateSummaryList(response.json);
16387
+ const templates = parseTemplateSummaryList(response.json);
16388
+ const limit = parsed.limit ?? DEFAULT_TEMPLATE_PAGE_SIZE;
16389
+ const offset = Number.parseInt(parsed.cursor ?? "0", 10) || 0;
16390
+ return { templates, nextCursor: templates.length >= limit ? String(offset + limit) : null };
16391
+ }
16392
+ /** Drain every page for a filtered query (platform catalogs are tens of templates). */
16393
+ async listAllTemplates(query) {
16394
+ const all = [];
16395
+ let cursor;
16396
+ for (let page = 0; page < 40; page += 1) {
16397
+ const result = await this.listTemplatesPage({ ...query, limit: MAX_TEMPLATE_PAGE_SIZE, cursor });
16398
+ all.push(...result.templates);
16399
+ if (!result.nextCursor)
16400
+ return all;
16401
+ cursor = result.nextCursor;
16402
+ }
16403
+ return all;
16379
16404
  }
16380
16405
  async getTemplate(templateId) {
16381
16406
  const response = await this.request("GET", `/v1/templates/${encodeURIComponent(templateId)}`);
@@ -16543,6 +16568,12 @@ var init_client = __esm({
16543
16568
  this.throwIfError(response.status, response.json);
16544
16569
  return parseSlideshowRun(response.json);
16545
16570
  }
16571
+ /** Per-page shortlist (hard filter → fit score → recent-family penalty → explore slot). Agent still picks. */
16572
+ async recommendSlideshowTemplates(input) {
16573
+ const response = await this.request("POST", "/v1/slideshow/template-recommendations", input);
16574
+ this.throwIfError(response.status, response.json);
16575
+ return response.json.data;
16576
+ }
16546
16577
  async listSlideshowRuns(query = {}) {
16547
16578
  const input = listSlideshowRunsQuerySchema.parse(query);
16548
16579
  const params = new URLSearchParams();
@@ -31720,7 +31751,7 @@ var init_src4 = __esm({
31720
31751
  {
31721
31752
  name: "list_templates",
31722
31753
  title: "List templates",
31723
- description: "List public template catalog summaries from Gateway (filterable; no AST)",
31754
+ description: "List public template catalog summaries from Gateway (filterable; no AST). Paged: follow nextCursor, or pass all=true with platforms to get the whole platform catalog before choosing. For Slideshow page choice prefer recommend_slideshow_templates.",
31724
31755
  effect: "read-only",
31725
31756
  inputSchema: {
31726
31757
  type: "object",
@@ -31734,11 +31765,13 @@ var init_src4 = __esm({
31734
31765
  requiresImage: { type: "boolean" },
31735
31766
  locale: { type: "string" },
31736
31767
  q: { type: "string" },
31737
- limit: { type: "number" }
31768
+ limit: { type: "number" },
31769
+ cursor: { type: "string" },
31770
+ all: { type: "boolean" }
31738
31771
  },
31739
31772
  additionalProperties: false
31740
31773
  },
31741
- outputSchema: { type: "object", properties: { templates: { type: "array" } } }
31774
+ outputSchema: { type: "object", properties: { templates: { type: "array" }, nextCursor: { type: ["string", "null"] } } }
31742
31775
  },
31743
31776
  {
31744
31777
  name: "get_template",
@@ -32057,7 +32090,7 @@ var init_src4 = __esm({
32057
32090
  };
32058
32091
  try {
32059
32092
  if (toolName === "list_templates") {
32060
- const templates = await this.client.listTemplates({
32093
+ const query = {
32061
32094
  platforms: args.platforms,
32062
32095
  roles: args.roles,
32063
32096
  contentFamily: args.contentFamily,
@@ -32066,10 +32099,16 @@ var init_src4 = __esm({
32066
32099
  canvasPreset: args.canvasPreset,
32067
32100
  requiresImage: typeof args.requiresImage === "boolean" ? args.requiresImage : void 0,
32068
32101
  locale: args.locale,
32069
- q: typeof args.q === "string" ? args.q : void 0,
32070
- limit: typeof args.limit === "number" ? args.limit : void 0
32102
+ q: typeof args.q === "string" ? args.q : void 0
32103
+ };
32104
+ if (args.all === true)
32105
+ return { ok: true, data: { templates: await this.client.listAllTemplates(query), nextCursor: null }, meta: meta4 };
32106
+ const page = await this.client.listTemplatesPage({
32107
+ ...query,
32108
+ limit: typeof args.limit === "number" ? args.limit : void 0,
32109
+ cursor: typeof args.cursor === "string" ? args.cursor : void 0
32071
32110
  });
32072
- return { ok: true, data: { templates }, meta: meta4 };
32111
+ return { ok: true, data: page, meta: meta4 };
32073
32112
  }
32074
32113
  if (toolName === "get_template") {
32075
32114
  const template = await this.client.getTemplate(String(args.templateId));
@@ -32277,6 +32316,7 @@ var init_src5 = __esm({
32277
32316
  objectSchema = { type: "object", properties: {}, additionalProperties: true };
32278
32317
  slideshowToolRegistry = [
32279
32318
  { name: "list_runs", title: "List slideshow runs", description: "List owner-scoped Slideshow Runs with optional filters.", effect: "read-only", inputSchema: { ...objectSchema, properties: { q: { type: "string" }, platform: { type: "string" }, profileId: { type: "string" }, brandProfileId: { type: "string" }, contentSlug: { type: "string" }, status: { type: "string" } } }, outputSchema: objectSchema },
32319
+ { name: "recommend_templates", title: "Recommend slideshow page templates", description: "Before create_run: send the Page Contracts (role, density, slotSummary per page) and get a shortlist per page with reasons. Recently used Layout Families are demoted and one unused family is always kept. Pick one templateId per page yourself; gaps list pages needing more templates.", effect: "read-only", inputSchema: { ...objectSchema, properties: { platform: { type: "string" }, canvasPreset: { type: "string" }, pages: { type: "array", items: { type: "object", properties: { role: { type: "string" }, density: { type: "string" }, slotSummary: { type: "object" }, requiresImage: { type: "boolean" } }, required: ["role"] } }, k: { type: "integer", minimum: 2, maximum: 5 }, seed: { type: "string" } }, required: ["platform", "pages"] }, outputSchema: objectSchema },
32280
32320
  { name: "create_run", title: "Create slideshow run", description: "Create an ADR-0026 Slideshow Run from a ContentPack.", effect: "local-write-job", inputSchema: { ...objectSchema, properties: { pack: { type: "object" }, brandId: { type: "string" }, brandProfileId: { type: "string" }, contentSlug: { type: "string" } }, required: ["pack"] }, outputSchema: objectSchema },
32281
32321
  { name: "get_run", title: "Get slideshow run", description: "Get an owner-scoped Slideshow Run.", effect: "read-only", inputSchema: { ...objectSchema, properties: { runId: { type: "string" } }, required: ["runId"] }, outputSchema: objectSchema },
32282
32322
  { name: "update_run", title: "Update slideshow run", description: "Edit page-instance slots/layout/style/decorations or presentation preference with optimistic revision.", effect: "local-write-job", inputSchema: { ...objectSchema, properties: { runId: { type: "string" }, pack: { type: "object" }, brandId: { type: "string" }, brandProfileId: { type: "string" }, contentSlug: { type: "string" }, baseRevision: { type: "integer", minimum: 1 }, pageIndex: { type: "integer", minimum: 0 }, slots: { type: "object" }, layout: { type: "object" }, style: { type: "object" }, decorations: { type: "array" } }, required: ["runId"] }, outputSchema: objectSchema },
@@ -32305,6 +32345,8 @@ var init_src5 = __esm({
32305
32345
  contentSlug: args.contentSlug,
32306
32346
  status: args.status
32307
32347
  }), meta: m };
32348
+ case "recommend_templates":
32349
+ return { ok: true, data: await this.client.recommendSlideshowTemplates({ platform: String(args.platform), pages: args.pages, canvasPreset: args.canvasPreset, k: args.k, seed: args.seed }), meta: m };
32308
32350
  case "create_run":
32309
32351
  return { ok: true, data: await this.client.createSlideshowRun({ pack: args.pack, brandId: args.brandId, brandProfileId: args.brandProfileId, contentSlug: args.contentSlug }), meta: m };
32310
32352
  case "get_run":
@@ -32376,6 +32418,7 @@ var init_src6 = __esm({
32376
32418
  };
32377
32419
  slideshowNames = {
32378
32420
  list_runs: "list_slideshow_runs",
32421
+ recommend_templates: "recommend_slideshow_templates",
32379
32422
  create_run: "create_slideshow_run",
32380
32423
  get_run: "get_slideshow_run",
32381
32424
  update_run: "update_slideshow_run",
@@ -33503,7 +33546,20 @@ function buildV1Cli() {
33503
33546
  jsonOption(images.command("search").requiredOption("--q <query>")).action(withClient(async (client, opts) => client.requestJson("GET", `/v1/images?q=${encodeURIComponent(String(opts.q))}`)));
33504
33547
  jsonOption(images.command("attest").requiredOption("--id <id>")).action(withClient(async (client, opts) => client.requestJson("POST", `/v1/images/${opts.id}/attest`, { accepted: true })));
33505
33548
  const templates = program.command("templates").description("Create and manage Page Template drafts");
33506
- jsonOption(templates.command("list")).action(withClient(async (client) => client.listTemplates()));
33549
+ jsonOption(templates.command("list").option("--platform <platform>", "tiktok | instagram | linkedin | threads | xiaohongshu").option("--canvas <preset>", "Canvas preset e.g. 9:16, 4:5").option("--role <role>", "Page role filter (weak tag)").option("--limit <n>", "Page size (max 50)").option("--cursor <cursor>", "Offset cursor from a previous page").option("--all", "Return every matching template (drains pages)")).action(withClient(async (client, opts) => {
33550
+ const query = {
33551
+ platforms: opts.platform ? [String(opts.platform)] : void 0,
33552
+ canvasPreset: opts.canvas ? String(opts.canvas) : void 0,
33553
+ roles: opts.role ? [String(opts.role)] : void 0
33554
+ };
33555
+ if (opts.all === true)
33556
+ return client.listAllTemplates(query);
33557
+ const page = await client.listTemplatesPage({ ...query, limit: opts.limit ? Number(opts.limit) : void 0, cursor: opts.cursor ? String(opts.cursor) : void 0 });
33558
+ if (page.nextCursor)
33559
+ process.stderr.write(`More templates: --cursor ${page.nextCursor} or --all
33560
+ `);
33561
+ return page.templates;
33562
+ }));
33507
33563
  jsonOption(templates.command("get").requiredOption("--id <id>")).action(withClient(async (client, opts) => client.getTemplate(String(opts.id))));
33508
33564
  jsonOption(templates.command("create-draft").requiredOption("--file <path>")).action(withClient(async (client, opts) => client.createDraft(JSON.parse(await readFile(String(opts.file), "utf8")))));
33509
33565
  jsonOption(templates.command("update-draft").requiredOption("--id <id>").requiredOption("--file <path>")).action(withClient(async (client, opts) => client.updateDraft(String(opts.id), JSON.parse(await readFile(String(opts.file), "utf8")))));
@@ -33531,6 +33587,10 @@ function buildV1Cli() {
33531
33587
  contentSlug: opts.contentSlug ? String(opts.contentSlug) : void 0,
33532
33588
  status: opts.status ? String(opts.status) : void 0
33533
33589
  })));
33590
+ jsonOption(slideshows.command("recommend").description("Shortlist Page Templates per page from Page Contracts JSON ({ platform, pages: [{ role, density?, slotSummary? }], seed? })").requiredOption("--file <path>").option("--seed <seed>", "Tie-break seed, e.g. the content slug")).action(withClient(async (client, opts) => {
33591
+ const input = JSON.parse(await readFile(String(opts.file), "utf8"));
33592
+ return client.recommendSlideshowTemplates(opts.seed ? { ...input, seed: String(opts.seed) } : input);
33593
+ }));
33534
33594
  jsonOption(slideshows.command("create").requiredOption("--file <path>").option("--allow-local-fixture", "Allow workspace_local fixture keys (dev only)")).action(withClient(async (client, opts) => {
33535
33595
  await assertHumanStudioIdentity(client, { allowLocalFixture: opts.allowLocalFixture === true });
33536
33596
  return client.createSlideshowRun({ pack: JSON.parse(await readFile(String(opts.file), "utf8")) });
@@ -33598,5 +33658,5 @@ async function runV1Cli(argv = process.argv) {
33598
33658
 
33599
33659
  // src/bin.ts
33600
33660
  var exitCode = await runV1Cli();
33601
- process.exit(exitCode);
33661
+ process.stdout.write("", () => process.exit(exitCode));
33602
33662
  //# sourceMappingURL=easysociable.js.map