@ignix-social/creator 0.1.1 → 0.1.2

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.
Files changed (3) hide show
  1. package/dist/cli.cjs +10 -7
  2. package/dist/core.cjs +118 -41
  3. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -21068,14 +21068,16 @@ var MCP_TOOL_INPUTS = {
21068
21068
  prompt: external_exports.string().trim().min(1).max(2e3),
21069
21069
  aspect: Aspect.optional(),
21070
21070
  referenceAssetId: AssetId2.optional(),
21071
- target: external_exports.enum(["auto", "local"]).optional()
21071
+ /** Where it runs: leave it out when only one way is possible; when two are, ask the person and pass their choice. */
21072
+ target: external_exports.enum(["auto", "local", "ignix", "boost"]).optional()
21072
21073
  }).strict(),
21073
21074
  make_video_clip: external_exports.object({
21074
21075
  prompt: external_exports.string().trim().min(1).max(900),
21075
21076
  imageAssetId: AssetId2.optional(),
21076
21077
  model: external_exports.enum(["wan", "minimax_h3"]).optional(),
21077
21078
  seconds: external_exports.number().int().min(2).max(10).optional(),
21078
- aspect: Aspect.optional()
21079
+ aspect: Aspect.optional(),
21080
+ target: external_exports.enum(["auto", "local", "ignix", "boost"]).optional()
21079
21081
  }).strict(),
21080
21082
  make_presenter: external_exports.object({
21081
21083
  /** The presenter's photo (a face looking at the camera). */
@@ -21089,7 +21091,8 @@ var MCP_TOOL_INPUTS = {
21089
21091
  /** The exact words of the audio: required for MiniMax H3 (it says them itself). */
21090
21092
  line: external_exports.string().trim().min(1).max(400).optional(),
21091
21093
  language: Language.optional(),
21092
- aspect: Aspect.optional()
21094
+ aspect: Aspect.optional(),
21095
+ target: external_exports.enum(["auto", "local", "ignix", "boost"]).optional()
21093
21096
  }).strict(),
21094
21097
  transcribe: external_exports.object({ assetId: AssetId2 }).strict(),
21095
21098
  find_faces: external_exports.object({ assetId: AssetId2 }).strict(),
@@ -21261,21 +21264,21 @@ var MCP_TOOL_META = {
21261
21264
  },
21262
21265
  make_image: {
21263
21266
  title: "Make an image",
21264
- description: "An image from your prompt (used as is). Made on this computer when it can; a paid route waits on the card (choose_route).",
21267
+ description: "An image from your prompt (used as is). Where it runs is priced before anything starts: with one possible way, the approval says where, its credits and roughly how long, and approving starts it; with two (e.g. free on this computer but slow, or Cloud Boost), it answers `needsChoice` with each way \u2014 tell the person and call again with `target`; with none, it says why (get_engines says what this computer can run).",
21265
21268
  readOnly: false,
21266
21269
  spend: "with_approval",
21267
21270
  openWorld: true
21268
21271
  },
21269
21272
  make_video_clip: {
21270
21273
  title: "Make a video clip",
21271
- description: "A short generated clip: a photo brought to life (`imageAssetId`, Wan or MiniMax H3) or text \u2192 video (MiniMax H3). This computer or Cloud Boost, chosen on the card (choose_route).",
21274
+ description: "A short generated clip: a photo brought to life (`imageAssetId`, Wan or MiniMax H3) or text \u2192 video (MiniMax H3). Where it runs is priced before anything starts: with one possible way, the approval says where, its credits and roughly how long, and approving starts it; with two (e.g. free on this computer but slow, or Cloud Boost), it answers `needsChoice` with each way \u2014 tell the person and call again with `target`; with none, it says why (get_engines says what this computer can run).",
21272
21275
  readOnly: false,
21273
21276
  spend: "with_approval",
21274
21277
  openWorld: true
21275
21278
  },
21276
21279
  make_presenter: {
21277
21280
  title: "Make a presenter",
21278
- description: "A talking presenter from a photo and ONE voice line (\u2264 8.5 s): InfiniteTalk lip-syncs the audio (default), or MiniMax H3 says `line` in that voice. For a longer script call it once per line and join the clips in Ignix Editor. This computer or Cloud Boost, chosen on the card (choose_route): a paid route or a photo of a real person waits for the person\u2019s approval there (needs_approval).",
21281
+ description: "A talking presenter from a photo and ONE voice line (\u2264 8.5 s): InfiniteTalk lip-syncs the audio (default), or MiniMax H3 says `line` in that voice. For a longer script call it once per line and join the clips in Ignix Editor. A photo of a real person also needs the person\u2019s consent in the same approval. Where it runs is priced before anything starts: with one possible way, the approval says where, its credits and roughly how long, and approving starts it; with two (e.g. free on this computer but slow, or Cloud Boost), it answers `needsChoice` with each way \u2014 tell the person and call again with `target`; with none, it says why (get_engines says what this computer can run).",
21279
21282
  readOnly: false,
21280
21283
  spend: "with_approval",
21281
21284
  openWorld: true
@@ -23605,7 +23608,7 @@ async function runService(paths, version2) {
23605
23608
  }
23606
23609
 
23607
23610
  // src/cli.ts
23608
- var VERSION = true ? "0.1.1" : "0.0.0-dev";
23611
+ var VERSION = true ? "0.1.2" : "0.0.0-dev";
23609
23612
  var HELP = `Ignix Creator ${VERSION} - generation tools for AI agents (ADR-0028/0029)
23610
23613
 
23611
23614
  ignix-creator login sign in to Ignix in your browser
package/dist/core.cjs CHANGED
@@ -22718,14 +22718,16 @@ var MCP_TOOL_INPUTS = {
22718
22718
  prompt: external_exports.string().trim().min(1).max(2e3),
22719
22719
  aspect: Aspect.optional(),
22720
22720
  referenceAssetId: AssetId2.optional(),
22721
- target: external_exports.enum(["auto", "local"]).optional()
22721
+ /** Where it runs: leave it out when only one way is possible; when two are, ask the person and pass their choice. */
22722
+ target: external_exports.enum(["auto", "local", "ignix", "boost"]).optional()
22722
22723
  }).strict(),
22723
22724
  make_video_clip: external_exports.object({
22724
22725
  prompt: external_exports.string().trim().min(1).max(900),
22725
22726
  imageAssetId: AssetId2.optional(),
22726
22727
  model: external_exports.enum(["wan", "minimax_h3"]).optional(),
22727
22728
  seconds: external_exports.number().int().min(2).max(10).optional(),
22728
- aspect: Aspect.optional()
22729
+ aspect: Aspect.optional(),
22730
+ target: external_exports.enum(["auto", "local", "ignix", "boost"]).optional()
22729
22731
  }).strict(),
22730
22732
  make_presenter: external_exports.object({
22731
22733
  /** The presenter's photo (a face looking at the camera). */
@@ -22739,7 +22741,8 @@ var MCP_TOOL_INPUTS = {
22739
22741
  /** The exact words of the audio: required for MiniMax H3 (it says them itself). */
22740
22742
  line: external_exports.string().trim().min(1).max(400).optional(),
22741
22743
  language: Language.optional(),
22742
- aspect: Aspect.optional()
22744
+ aspect: Aspect.optional(),
22745
+ target: external_exports.enum(["auto", "local", "ignix", "boost"]).optional()
22743
22746
  }).strict(),
22744
22747
  transcribe: external_exports.object({ assetId: AssetId2 }).strict(),
22745
22748
  find_faces: external_exports.object({ assetId: AssetId2 }).strict(),
@@ -22911,21 +22914,21 @@ var MCP_TOOL_META = {
22911
22914
  },
22912
22915
  make_image: {
22913
22916
  title: "Make an image",
22914
- description: "An image from your prompt (used as is). Made on this computer when it can; a paid route waits on the card (choose_route).",
22917
+ description: "An image from your prompt (used as is). Where it runs is priced before anything starts: with one possible way, the approval says where, its credits and roughly how long, and approving starts it; with two (e.g. free on this computer but slow, or Cloud Boost), it answers `needsChoice` with each way \u2014 tell the person and call again with `target`; with none, it says why (get_engines says what this computer can run).",
22915
22918
  readOnly: false,
22916
22919
  spend: "with_approval",
22917
22920
  openWorld: true
22918
22921
  },
22919
22922
  make_video_clip: {
22920
22923
  title: "Make a video clip",
22921
- description: "A short generated clip: a photo brought to life (`imageAssetId`, Wan or MiniMax H3) or text \u2192 video (MiniMax H3). This computer or Cloud Boost, chosen on the card (choose_route).",
22924
+ description: "A short generated clip: a photo brought to life (`imageAssetId`, Wan or MiniMax H3) or text \u2192 video (MiniMax H3). Where it runs is priced before anything starts: with one possible way, the approval says where, its credits and roughly how long, and approving starts it; with two (e.g. free on this computer but slow, or Cloud Boost), it answers `needsChoice` with each way \u2014 tell the person and call again with `target`; with none, it says why (get_engines says what this computer can run).",
22922
22925
  readOnly: false,
22923
22926
  spend: "with_approval",
22924
22927
  openWorld: true
22925
22928
  },
22926
22929
  make_presenter: {
22927
22930
  title: "Make a presenter",
22928
- description: "A talking presenter from a photo and ONE voice line (\u2264 8.5 s): InfiniteTalk lip-syncs the audio (default), or MiniMax H3 says `line` in that voice. For a longer script call it once per line and join the clips in Ignix Editor. This computer or Cloud Boost, chosen on the card (choose_route): a paid route or a photo of a real person waits for the person\u2019s approval there (needs_approval).",
22931
+ description: "A talking presenter from a photo and ONE voice line (\u2264 8.5 s): InfiniteTalk lip-syncs the audio (default), or MiniMax H3 says `line` in that voice. For a longer script call it once per line and join the clips in Ignix Editor. A photo of a real person also needs the person\u2019s consent in the same approval. Where it runs is priced before anything starts: with one possible way, the approval says where, its credits and roughly how long, and approving starts it; with two (e.g. free on this computer but slow, or Cloud Boost), it answers `needsChoice` with each way \u2014 tell the person and call again with `target`; with none, it says why (get_engines says what this computer can run).",
22929
22932
  readOnly: false,
22930
22933
  spend: "with_approval",
22931
22934
  openWorld: true
@@ -57846,6 +57849,9 @@ ${es ? "A partir de ahora lo sigo en cada v\xEDdeo, salvo que me pidas otra cosa
57846
57849
  const text2 = rec7.error === "not_set_up" ? final.caption ? reply2.notSetUp : reply2.notSetUpNoCopy : rec7.target === null && !rec7.error ? final.caption ? reply2.choose : reply2.chooseNoCopy : rec7.note === "allowance_exhausted" ? reply2.exhausted : final.caption ? reply2.started : reply2.startedNoCopy;
57847
57850
  return { jobId: rec7.jobId, text: text2, usedModel };
57848
57851
  },
57852
+ async quote(request2) {
57853
+ return perTarget(await deps.engine.plan(request2).catch(() => [])).map(routeOption);
57854
+ },
57849
57855
  async generate(g) {
57850
57856
  const rec7 = {
57851
57857
  jobId: newJobId(),
@@ -61236,7 +61242,10 @@ var EN2 = {
61236
61242
  acceptsH3Licence: "Accepts the MiniMax H3 Community License.",
61237
61243
  uploadToIgnix: (k, mb) => `Upload to Ignix (${k}, ${String(mb)} MB)`,
61238
61244
  toWorkspace: (n) => `To workspace \xAB${n}\xBB.`,
61239
- consentDetail: "Uses photos or videos of people: approving confirms they are you or consented."
61245
+ consentDetail: "Uses photos or videos of people: approving confirms they are you or consented.",
61246
+ whereLocal: (eta) => `On this computer, free${eta ? `, about ${eta}` : ""}.`,
61247
+ whereBoost: (eta) => `On Ignix Cloud Boost${eta ? `, about ${eta}` : ""}.`,
61248
+ whereIgnix: (eta) => `With Ignix AI${eta ? `, about ${eta}` : ""}.`
61240
61249
  };
61241
61250
  var ES2 = {
61242
61251
  piece: (k) => ({ reel: "reel", story: "historia", post: "publicaci\xF3n" })[k] ?? k,
@@ -61283,7 +61292,10 @@ var ES2 = {
61283
61292
  acceptsH3Licence: "Acepta la licencia comunitaria de MiniMax H3.",
61284
61293
  uploadToIgnix: (k, mb) => `Subir a Ignix (${k}, ${String(mb).replace(".", ",")} MB)`,
61285
61294
  toWorkspace: (n) => `Al espacio de trabajo \xAB${n}\xBB.`,
61286
- consentDetail: "Usa fotos o v\xEDdeos de personas: al aprobar confirmas que eres t\xFA o que han dado su consentimiento."
61295
+ consentDetail: "Usa fotos o v\xEDdeos de personas: al aprobar confirmas que eres t\xFA o que han dado su consentimiento.",
61296
+ whereLocal: (eta) => `En este ordenador, gratis${eta ? `, unos ${eta}` : ""}.`,
61297
+ whereBoost: (eta) => `En Cloud Boost de Ignix${eta ? `, unos ${eta}` : ""}.`,
61298
+ whereIgnix: (eta) => `Con la IA de Ignix${eta ? `, unos ${eta}` : ""}.`
61287
61299
  };
61288
61300
  var PT = {
61289
61301
  piece: (k) => ({ reel: "reel", story: "story", post: "post" })[k] ?? k,
@@ -61330,7 +61342,10 @@ var PT = {
61330
61342
  acceptsH3Licence: "Aceita a licen\xE7a comunit\xE1ria do MiniMax H3.",
61331
61343
  uploadToIgnix: (k, mb) => `Enviar para a Ignix (${k}, ${String(mb).replace(".", ",")} MB)`,
61332
61344
  toWorkspace: (n) => `Para o espa\xE7o de trabalho \xAB${n}\xBB.`,
61333
- consentDetail: "Usa fotos ou v\xEDdeos de pessoas: ao aprovar, voc\xEA confirma que \xE9 voc\xEA ou que elas consentiram."
61345
+ consentDetail: "Usa fotos ou v\xEDdeos de pessoas: ao aprovar, voc\xEA confirma que \xE9 voc\xEA ou que elas consentiram.",
61346
+ whereLocal: (eta) => `Neste computador, gr\xE1tis${eta ? `, cerca de ${eta}` : ""}.`,
61347
+ whereBoost: (eta) => `No Cloud Boost da Ignix${eta ? `, cerca de ${eta}` : ""}.`,
61348
+ whereIgnix: (eta) => `Com a IA da Ignix${eta ? `, cerca de ${eta}` : ""}.`
61334
61349
  };
61335
61350
  var FR = {
61336
61351
  piece: (k) => ({ reel: "reel", story: "story", post: "publication" })[k] ?? k,
@@ -61377,7 +61392,10 @@ var FR = {
61377
61392
  acceptsH3Licence: "Accepte la licence communautaire de MiniMax H3.",
61378
61393
  uploadToIgnix: (k, mb) => `Envoyer vers Ignix (${k}, ${String(mb).replace(".", ",")} Mo)`,
61379
61394
  toWorkspace: (n) => `Dans l\u2019espace de travail \xAB ${n} \xBB.`,
61380
- consentDetail: "Utilise des photos ou vid\xE9os de personnes : approuver confirme qu\u2019il s\u2019agit de vous ou qu\u2019elles ont consenti."
61395
+ consentDetail: "Utilise des photos ou vid\xE9os de personnes : approuver confirme qu\u2019il s\u2019agit de vous ou qu\u2019elles ont consenti.",
61396
+ whereLocal: (eta) => `Sur cet ordinateur, gratuit${eta ? `, environ ${eta}` : ""}.`,
61397
+ whereBoost: (eta) => `Sur Cloud Boost d\u2019Ignix${eta ? `, environ ${eta}` : ""}.`,
61398
+ whereIgnix: (eta) => `Avec l\u2019IA d\u2019Ignix${eta ? `, environ ${eta}` : ""}.`
61381
61399
  };
61382
61400
  var DE = {
61383
61401
  piece: (k) => ({ reel: "Reel", story: "Story", post: "Post" })[k] ?? k,
@@ -61424,12 +61442,19 @@ var DE = {
61424
61442
  acceptsH3Licence: "Akzeptiert die MiniMax H3 Community License.",
61425
61443
  uploadToIgnix: (k, mb) => `Zu Ignix hochladen (${k}, ${String(mb).replace(".", ",")} MB)`,
61426
61444
  toWorkspace: (n) => `In den Workspace \xAB${n}\xBB.`,
61427
- consentDetail: "Verwendet Fotos oder Videos von Personen: Mit der Genehmigung best\xE4tigst du, dass du es bist oder sie zugestimmt haben."
61445
+ consentDetail: "Verwendet Fotos oder Videos von Personen: Mit der Genehmigung best\xE4tigst du, dass du es bist oder sie zugestimmt haben.",
61446
+ whereLocal: (eta) => `Auf diesem Computer, kostenlos${eta ? `, etwa ${eta}` : ""}.`,
61447
+ whereBoost: (eta) => `Auf Ignix Cloud Boost${eta ? `, etwa ${eta}` : ""}.`,
61448
+ whereIgnix: (eta) => `Mit der Ignix-KI${eta ? `, etwa ${eta}` : ""}.`
61428
61449
  };
61429
61450
  var TEXTS = { en: EN2, es: ES2, pt: PT, fr: FR, de: DE };
61430
61451
  function approvalText(lang) {
61431
61452
  return TEXTS[lang];
61432
61453
  }
61454
+ function etaText(seconds) {
61455
+ if (!seconds || seconds <= 0) return null;
61456
+ return seconds < 90 ? `${String(Math.round(seconds))} s` : `${String(Math.round(seconds / 60))} min`;
61457
+ }
61433
61458
 
61434
61459
  // ../../packages/core/src/mcp/service.ts
61435
61460
  var ok2 = (data) => ({ status: "ok", data });
@@ -61569,7 +61594,9 @@ function createMcpService(deps) {
61569
61594
  tool: c.tool,
61570
61595
  kinds,
61571
61596
  title: opts.title,
61572
- details: [...opts.details ?? [], ...needConsent ? [T2.consentDetail] : []],
61597
+ // Consent is said by its kind (the dialog and the window both show it): a
61598
+ // detail line repeating it read twice (Fran, 2026-10-12).
61599
+ details: [...opts.details ?? []],
61573
61600
  credits,
61574
61601
  jobId: opts.jobId ?? null,
61575
61602
  paid: Boolean(opts.spend || opts.write || opts.download),
@@ -61588,6 +61615,45 @@ function createMcpService(deps) {
61588
61615
  message: `Waiting for the person to approve it in Ignix Creator on this computer (\xAB${opts.title.slice(0, 200)}\xBB). Tell them an approval is waiting; poll get_approval with this approvalId; nothing happens until they decide.`
61589
61616
  };
61590
61617
  }
61618
+ async function routed(c, o, start3) {
61619
+ const options2 = await deps.content.quote?.(o.request).catch(() => []) ?? [];
61620
+ const usable = options2.filter((x) => x.available);
61621
+ const wanted = o.target && o.target !== "auto" ? o.target : null;
61622
+ const way = (x) => ({
61623
+ target: x.target,
61624
+ available: x.available,
61625
+ reason: x.reason,
61626
+ estimateSeconds: x.estimateSeconds,
61627
+ credits: x.cost.unit === "none" ? 0 : x.cost.amount
61628
+ });
61629
+ const pick2 = wanted ? usable.find((x) => x.target === wanted) ?? null : usable.length === 1 ? usable[0] ?? null : null;
61630
+ if (!pick2) {
61631
+ if (!wanted && usable.length > 1)
61632
+ return ok2({
61633
+ needsChoice: true,
61634
+ ways: usable.map(way),
61635
+ message: "It can be made in more than one place. Tell the person each way \u2014 where (local = their computer, free; boost = Ignix Cloud Boost; ignix = Ignix AI), its credits and roughly how long \u2014 and call again with `target` set to their choice."
61636
+ });
61637
+ return err(
61638
+ "unavailable",
61639
+ `${wanted ? `It cannot be made on \xAB${wanted}\xBB here.` : "Nothing can make it here right now."} Ways and why: ${JSON.stringify(options2.map(way))}. get_engines says what this computer can run and what to install.`
61640
+ );
61641
+ }
61642
+ const credits = pick2.cost.unit === "none" ? null : pick2.cost.amount;
61643
+ const eta = etaText(pick2.estimateSeconds);
61644
+ const where = pick2.target === "local" ? T2.whereLocal(eta) : pick2.target === "boost" ? T2.whereBoost(eta) : T2.whereIgnix(eta);
61645
+ return gate(
61646
+ c,
61647
+ {
61648
+ spend: pick2.target !== "local",
61649
+ visual: o.visual,
61650
+ title: o.title,
61651
+ details: [where, ...o.details ?? []],
61652
+ credits
61653
+ },
61654
+ () => start3(pick2.target)
61655
+ );
61656
+ }
61591
61657
  async function start2(c, o) {
61592
61658
  let out;
61593
61659
  try {
@@ -62112,18 +62178,23 @@ function createMcpService(deps) {
62112
62178
  count: 1,
62113
62179
  references: ref ? [ref.id] : []
62114
62180
  };
62115
- return gate(c, { visual: ref ? [ref] : [], title: T2.makeImage }, async () => {
62116
- const jobId = await deps.content.generate?.({
62117
- request: request2,
62118
- aspect,
62119
- referenceAssetId: ref?.id ?? null,
62120
- headline: a.prompt.slice(0, 80),
62121
- preference: a.target === "local" ? "local" : "auto"
62122
- });
62123
- if (!jobId) return err("unavailable", "Image generation is not available here.");
62124
- deps.chat.showJob(jobId, `${c.client.name}: an image \u2014 \u201C${a.prompt.slice(0, 120)}\u201D`);
62125
- return ok2({ jobId, job: jobView(jobId) });
62126
- });
62181
+ const visual = ref ? [ref] : [];
62182
+ return routed(
62183
+ c,
62184
+ { request: request2, target: a.target, visual, title: T2.makeImage },
62185
+ async (target) => {
62186
+ const jobId = await deps.content.generate?.({
62187
+ request: request2,
62188
+ aspect,
62189
+ referenceAssetId: ref?.id ?? null,
62190
+ headline: a.prompt.slice(0, 80),
62191
+ preference: target
62192
+ });
62193
+ if (!jobId) return err("unavailable", "Image generation is not available here.");
62194
+ deps.chat.showJob(jobId, `${c.client.name}: an image \u2014 \u201C${a.prompt.slice(0, 120)}\u201D`);
62195
+ return ok2({ jobId, job: jobView(jobId) });
62196
+ }
62197
+ );
62127
62198
  },
62128
62199
  async make_video_clip(a, c) {
62129
62200
  const image = a.imageAssetId ? asset(a.imageAssetId) : null;
@@ -62143,13 +62214,14 @@ function createMcpService(deps) {
62143
62214
  aspect,
62144
62215
  ...a.model ? { model: a.model } : {}
62145
62216
  } : { kind: "video", prompt: a.prompt, aspect, durationSec: seconds, references: [] };
62146
- return gate(c, { visual: image ? [image] : [], title: T2.makeClip }, async () => {
62217
+ const visual = image ? [image] : [];
62218
+ return routed(c, { request: request2, target: a.target, visual, title: T2.makeClip }, async (target) => {
62147
62219
  const jobId = await deps.content.generate?.({
62148
62220
  request: request2,
62149
62221
  aspect,
62150
62222
  referenceAssetId: image?.id ?? null,
62151
62223
  headline: a.prompt.slice(0, 80),
62152
- preference: "auto"
62224
+ preference: target
62153
62225
  });
62154
62226
  if (!jobId) return err("unavailable", "Video generation is not available here.");
62155
62227
  deps.chat.showJob(jobId, `${c.client.name}: a video clip \u2014 \u201C${a.prompt.slice(0, 120)}\u201D`);
@@ -62184,21 +62256,26 @@ function createMcpService(deps) {
62184
62256
  aspect,
62185
62257
  ...h3 ? { model: "minimax_h3" } : {}
62186
62258
  };
62187
- return gate(c, { visual: [photo], title: T2.makePresenter }, async () => {
62188
- const jobId = await deps.content.generate?.({
62189
- request: request2,
62190
- aspect,
62191
- referenceAssetId: photo.id,
62192
- headline: (a.line ?? scene).slice(0, 80),
62193
- preference: "auto"
62194
- });
62195
- if (!jobId) return err("unavailable", "Presenters are not available here.");
62196
- deps.chat.showJob(
62197
- jobId,
62198
- `${c.client.name}: a presenter \u2014 \u201C${(a.line ?? scene).slice(0, 120)}\u201D`
62199
- );
62200
- return ok2({ jobId, job: jobView(jobId) });
62201
- });
62259
+ const visual = [photo];
62260
+ return routed(
62261
+ c,
62262
+ { request: request2, target: a.target, visual, title: T2.makePresenter },
62263
+ async (target) => {
62264
+ const jobId = await deps.content.generate?.({
62265
+ request: request2,
62266
+ aspect,
62267
+ referenceAssetId: photo.id,
62268
+ headline: (a.line ?? scene).slice(0, 80),
62269
+ preference: target
62270
+ });
62271
+ if (!jobId) return err("unavailable", "Presenters are not available here.");
62272
+ deps.chat.showJob(
62273
+ jobId,
62274
+ `${c.client.name}: a presenter \u2014 \u201C${(a.line ?? scene).slice(0, 120)}\u201D`
62275
+ );
62276
+ return ok2({ jobId, job: jobView(jobId) });
62277
+ }
62278
+ );
62202
62279
  },
62203
62280
  async transcribe(a) {
62204
62281
  const m = asset(a.assetId);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ignix-social/creator",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Ignix Creator: generation tools (presenters, photo → video, text → video, recast, dubbing) on this computer or Cloud Boost, driven by AI agents over MCP. Needs an active Ignix plan.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "commonjs",