appostle-installer 0.0.21 → 0.0.22

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/dist/appostle.js CHANGED
@@ -3234,7 +3234,9 @@ var BrandEntrySchema = z10.object({
3234
3234
  variables: z10.array(BrandVariableSchema).optional().default([]),
3235
3235
  path: z10.string(),
3236
3236
  modifiedAt: z10.string(),
3237
- size: z10.number()
3237
+ size: z10.number(),
3238
+ /** Raw markdown body (frontmatter stripped). Optional, fed by the scanner. */
3239
+ body: z10.string().optional()
3238
3240
  });
3239
3241
  var BrandFrontmatterSchema = z10.object({
3240
3242
  description: z10.string().optional(),
@@ -3411,6 +3413,22 @@ var BrandGenerateWireframeResponseSchema = z10.object({
3411
3413
  error: z10.string().nullable()
3412
3414
  })
3413
3415
  });
3416
+ var BrandAnalyzePhotographyRequestSchema = z10.object({
3417
+ type: z10.literal("brands/analyze-photography"),
3418
+ requestId: z10.string(),
3419
+ workspaceRoot: z10.string(),
3420
+ brandPath: z10.string(),
3421
+ brief: z10.string(),
3422
+ referenceDescriptions: z10.array(z10.string()).optional()
3423
+ });
3424
+ var BrandAnalyzePhotographyResponseSchema = z10.object({
3425
+ type: z10.literal("brands/analyze-photography/response"),
3426
+ payload: z10.object({
3427
+ requestId: z10.string(),
3428
+ updatedCount: z10.number(),
3429
+ error: z10.string().nullable()
3430
+ })
3431
+ });
3414
3432
  var RightFontEntrySchema = z10.object({
3415
3433
  id: z10.string(),
3416
3434
  name: z10.string(),
@@ -5532,6 +5550,7 @@ var SessionInboundMessageSchema = z11.discriminatedUnion("type", [
5532
5550
  BrandGenerateLayoutRequestSchema,
5533
5551
  BrandLayoutQaNextRequestSchema,
5534
5552
  BrandGenerateWireframeRequestSchema,
5553
+ BrandAnalyzePhotographyRequestSchema,
5535
5554
  RightFontLibraryRequestSchema,
5536
5555
  GoogleFontsCatalogRequestSchema,
5537
5556
  GoogleFontsDownloadRequestSchema,
@@ -7168,6 +7187,7 @@ var SessionOutboundMessageSchema = z11.discriminatedUnion("type", [
7168
7187
  BrandGenerateLayoutResponseSchema,
7169
7188
  BrandLayoutQaNextResponseSchema,
7170
7189
  BrandGenerateWireframeResponseSchema,
7190
+ BrandAnalyzePhotographyResponseSchema,
7171
7191
  RightFontLibraryResponseSchema,
7172
7192
  GoogleFontsCatalogResponseSchema,
7173
7193
  GoogleFontsDownloadResponseSchema,
@@ -7377,7 +7397,7 @@ import { exec } from "node:child_process";
7377
7397
  import { promisify as promisify3 } from "util";
7378
7398
  import { join as join14, resolve as resolve9, sep as sep2 } from "path";
7379
7399
  import { homedir as homedir5, hostname as osHostname } from "node:os";
7380
- import { z as z39 } from "zod";
7400
+ import { z as z40 } from "zod";
7381
7401
 
7382
7402
  // ../server/src/server/persisted-config.ts
7383
7403
  import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "node:fs";
@@ -20727,6 +20747,12 @@ ${error.stack ?? ""}` : JSON.stringify(error);
20727
20747
  buildStructuredToolResult(server, tool4, output, input) {
20728
20748
  const normalizedServer = server.toLowerCase();
20729
20749
  const normalizedTool = tool4.toLowerCase();
20750
+ if (normalizedTool === "mcp__playwright__browser_take_screenshot" || normalizedTool === "browser_take_screenshot") {
20751
+ const imageOutput = this.tryInlinePlaywrightScreenshot(output, input);
20752
+ if (imageOutput) {
20753
+ return { output: imageOutput };
20754
+ }
20755
+ }
20730
20756
  if (normalizedServer.includes("bash") || normalizedServer.includes("shell") || normalizedServer.includes("command") || normalizedTool.includes("bash") || normalizedTool.includes("shell") || normalizedTool.includes("command") || input && (typeof input.command === "string" || Array.isArray(input.command))) {
20731
20757
  const command = this.extractCommandText(input ?? {}) ?? "command";
20732
20758
  return {
@@ -20768,8 +20794,46 @@ ${error.stack ?? ""}` : JSON.stringify(error);
20768
20794
  };
20769
20795
  }
20770
20796
  }
20797
+ if (normalizedServer === "playwright" && normalizedTool === "browser_take_screenshot") {
20798
+ const imageDetail = this.tryReadPlaywrightScreenshot(output, input);
20799
+ if (imageDetail) return imageDetail;
20800
+ }
20771
20801
  return void 0;
20772
20802
  }
20803
+ /**
20804
+ * Playwright MCP's `browser_take_screenshot` saves the image to a local file
20805
+ * and returns a markdown link (`[Screenshot of viewport](./file.png)`).
20806
+ * Extract the path, resolve it against the agent CWD, read the bytes, and
20807
+ * return an image ToolCallDetail so the client renders it inline.
20808
+ */
20809
+ tryReadPlaywrightScreenshot(output, input) {
20810
+ let filePath;
20811
+ if (input && typeof input.filename === "string") {
20812
+ filePath = input.filename;
20813
+ }
20814
+ if (!filePath) {
20815
+ const match = output.match(/\[Screenshot[^\]]*\]\(([^)]+)\)/i);
20816
+ if (match?.[1]) {
20817
+ filePath = match[1];
20818
+ }
20819
+ }
20820
+ if (!filePath) return void 0;
20821
+ const cwd = this.config.cwd;
20822
+ if (!cwd) return void 0;
20823
+ const abs = path9.isAbsolute(filePath) ? filePath : path9.resolve(cwd, filePath);
20824
+ try {
20825
+ const buf = fs4.readFileSync(abs);
20826
+ const ext = path9.extname(abs).toLowerCase();
20827
+ const mime = ext === ".jpeg" || ext === ".jpg" ? "image/jpeg" : "image/png";
20828
+ return {
20829
+ type: "image",
20830
+ toolName: "mcp__playwright__browser_take_screenshot",
20831
+ images: [{ mimeType: mime, data: buf.toString("base64") }]
20832
+ };
20833
+ } catch {
20834
+ return void 0;
20835
+ }
20836
+ }
20773
20837
  mapPartialEvent(event, options) {
20774
20838
  if (event.type === "content_block_start") {
20775
20839
  const block = isClaudeContentChunk2(event.content_block) ? event.content_block : null;
@@ -20942,6 +21006,44 @@ ${error.stack ?? ""}` : JSON.stringify(error);
20942
21006
  }
20943
21007
  return input;
20944
21008
  }
21009
+ /**
21010
+ * Playwright MCP returns `### Result\n- [Screenshot of viewport](./foo.png)`
21011
+ * and writes the file to disk instead of inlining the image. Resolve that
21012
+ * path against the agent cwd and turn the file into an Anthropic-style
21013
+ * image content block array, so downstream `extractImageToolDetail`
21014
+ * promotes the tool call to a renderable `image` detail.
21015
+ *
21016
+ * Returns `null` when the path cannot be resolved/read safely; the caller
21017
+ * then falls back to the default text output behavior.
21018
+ */
21019
+ tryInlinePlaywrightScreenshot(output, input) {
21020
+ const cwd = this.config.cwd;
21021
+ if (!cwd) return null;
21022
+ let relPath;
21023
+ if (input && typeof input.filename === "string" && input.filename.length > 0) {
21024
+ relPath = input.filename;
21025
+ } else {
21026
+ const match = output.match(/\[Screenshot[^\]]*\]\(([^)]+)\)/);
21027
+ if (match?.[1]) {
21028
+ relPath = match[1];
21029
+ }
21030
+ }
21031
+ if (!relPath) return null;
21032
+ const resolved = path9.resolve(cwd, relPath);
21033
+ const cwdReal = path9.resolve(cwd);
21034
+ if (!resolved.startsWith(cwdReal + path9.sep) && resolved !== cwdReal) {
21035
+ return null;
21036
+ }
21037
+ let buf;
21038
+ try {
21039
+ buf = fs4.readFileSync(resolved);
21040
+ } catch {
21041
+ return null;
21042
+ }
21043
+ const ext = path9.extname(resolved).toLowerCase();
21044
+ const mimeType = ext === ".jpg" || ext === ".jpeg" ? "image/jpeg" : ext === ".webp" ? "image/webp" : ext === ".gif" ? "image/gif" : "image/png";
21045
+ return [{ type: "image", mimeType, data: buf.toString("base64") }];
21046
+ }
20945
21047
  areToolInputsEqual(left, right) {
20946
21048
  if (!left) {
20947
21049
  return false;
@@ -34972,10 +35074,12 @@ async function readBrandsFromDir(scope, dir) {
34972
35074
  continue;
34973
35075
  }
34974
35076
  let parsed;
35077
+ let body = "";
34975
35078
  try {
34976
35079
  const text = await fs11.readFile(fullPath, "utf8");
34977
- const { rawFrontmatterLines, hadFrontmatter } = parseBrandFile(text);
35080
+ const { rawFrontmatterLines, body: parsedBody, hadFrontmatter } = parseBrandFile(text);
34978
35081
  parsed = hadFrontmatter ? parseFrontmatter2(rawFrontmatterLines) : { description: "", variables: [] };
35082
+ body = parsedBody;
34979
35083
  } catch {
34980
35084
  parsed = { description: "", variables: [] };
34981
35085
  }
@@ -34987,7 +35091,8 @@ async function readBrandsFromDir(scope, dir) {
34987
35091
  variables: parsed.variables,
34988
35092
  path: fullPath,
34989
35093
  modifiedAt: stat5.mtime.toISOString(),
34990
- size: stat5.size
35094
+ size: stat5.size,
35095
+ body
34991
35096
  });
34992
35097
  }
34993
35098
  results.sort((a, b) => a.name.localeCompare(b.name));
@@ -35426,11 +35531,132 @@ async function generateAndApplyBrandTokens(options) {
35426
35531
  return { generatedCount: acceptedUpdates.size };
35427
35532
  }
35428
35533
 
35534
+ // ../server/src/server/brand/photography-analyzer.ts
35535
+ import { z as z38 } from "zod";
35536
+ var PhotographyResponseSchema = z38.object({
35537
+ dna: z38.string().min(1),
35538
+ dials: z38.record(z38.string(), z38.string())
35539
+ });
35540
+ function buildPrompt3(args) {
35541
+ const dialLines = args.selectVars.map((v) => {
35542
+ const options = (v.options ?? []).join(", ");
35543
+ return `- ${v.key} (${v.label || v.key}): current="${v.value || "(unset)"}" options=[${options}]`;
35544
+ }).join("\n");
35545
+ const refSection = args.referenceDescriptions.length > 0 ? [
35546
+ "",
35547
+ "Reference image filenames/descriptions provided by the user:",
35548
+ ...args.referenceDescriptions.map((r) => `- ${r}`)
35549
+ ].join("\n") : "";
35550
+ return [
35551
+ "You are a photography director analyzing a brand's photographic identity.",
35552
+ "The user has provided a brief describing the visual direction they want.",
35553
+ "Your job is to:",
35554
+ "1. Write a rich, specific Style DNA (2-3 sentences describing the photographic",
35555
+ " identity in concrete visual terms \u2014 lighting quality, tonal mood, depth",
35556
+ " characteristics, color rendering. No marketing fluff.)",
35557
+ "2. Pre-dial every camera control to match that style direction.",
35558
+ " ONLY use values that appear in the options list for each dial.",
35559
+ "",
35560
+ "User brief:",
35561
+ args.brief,
35562
+ refSection,
35563
+ "",
35564
+ "Camera dials (key, current value, valid options):",
35565
+ dialLines,
35566
+ "",
35567
+ "Return JSON only with the shape:",
35568
+ '{ "dna": "Rich style DNA description...", "dials": { "key": "value", ... } }',
35569
+ "",
35570
+ "Rules:",
35571
+ "- The dna field must be a non-empty string, 2-3 sentences.",
35572
+ "- Every value in dials must be one of the listed options for that key.",
35573
+ "- Include ALL dial keys in dials, even if you keep the current value.",
35574
+ "- Do not invent new keys. Do not output anything outside the JSON."
35575
+ ].filter((line) => line !== "").join("\n");
35576
+ }
35577
+ async function analyzeAndApplyPhotographyStyle(options) {
35578
+ const { agentManager, workspaceRoot, brandPath, brief, referenceDescriptions, logger } = options;
35579
+ const brands = await listBrands({ workspaceRoot });
35580
+ const photoBrand = brands.find((b) => b.path === brandPath) ?? null;
35581
+ if (!photoBrand) {
35582
+ throw new Error(`Brand file not found at ${brandPath}`);
35583
+ }
35584
+ const allVars = photoBrand.variables;
35585
+ const selectVars = allVars.filter(
35586
+ (v) => v.type === "select" && v.options && v.options.length > 0
35587
+ );
35588
+ if (selectVars.length === 0) {
35589
+ throw new Error("No camera dials found in photography brand file");
35590
+ }
35591
+ const validOptions = /* @__PURE__ */ new Map();
35592
+ for (const v of selectVars) {
35593
+ validOptions.set(v.key, new Set(v.options ?? []));
35594
+ }
35595
+ const agentPrompt = buildPrompt3({
35596
+ brief,
35597
+ referenceDescriptions: referenceDescriptions ?? [],
35598
+ selectVars
35599
+ });
35600
+ let response;
35601
+ try {
35602
+ response = await generateStructuredAgentResponseWithFallback({
35603
+ manager: agentManager,
35604
+ cwd: workspaceRoot,
35605
+ prompt: agentPrompt,
35606
+ schema: PhotographyResponseSchema,
35607
+ schemaName: "PhotographyAnalysis",
35608
+ maxRetries: 2,
35609
+ providers: DEFAULT_STRUCTURED_GENERATION_PROVIDERS,
35610
+ agentConfigOverrides: {
35611
+ title: "Photography style analyzer",
35612
+ internal: true
35613
+ }
35614
+ });
35615
+ } catch (error) {
35616
+ if (error instanceof StructuredAgentResponseError || error instanceof StructuredAgentFallbackError) {
35617
+ logger.warn({ err: error, brandPath }, "Structured photography analysis failed");
35618
+ throw new Error("Photography analysis failed \u2014 the agent did not return valid JSON");
35619
+ }
35620
+ throw error;
35621
+ }
35622
+ const acceptedUpdates = /* @__PURE__ */ new Map();
35623
+ for (const [key, value] of Object.entries(response.dials)) {
35624
+ if (typeof value !== "string") continue;
35625
+ const trimmed = value.trim();
35626
+ const opts = validOptions.get(key);
35627
+ if (!opts) continue;
35628
+ if (!opts.has(trimmed)) continue;
35629
+ acceptedUpdates.set(key, trimmed);
35630
+ }
35631
+ acceptedUpdates.set("photo.dna", response.dna);
35632
+ acceptedUpdates.set("photo.brief", brief);
35633
+ const nextVariables = allVars.map((v) => {
35634
+ const update = acceptedUpdates.get(v.key);
35635
+ if (update === void 0) return v;
35636
+ return { ...v, value: update };
35637
+ });
35638
+ await writeBrandFrontmatter(
35639
+ {
35640
+ path: brandPath,
35641
+ frontmatter: {
35642
+ description: photoBrand.description,
35643
+ variables: nextVariables
35644
+ }
35645
+ },
35646
+ workspaceRoot
35647
+ );
35648
+ logger.info(
35649
+ { brandPath, updatedCount: acceptedUpdates.size },
35650
+ "photography-analyzer: applied style analysis"
35651
+ );
35652
+ return { updatedCount: acceptedUpdates.size };
35653
+ }
35654
+
35429
35655
  // ../server/src/server/brand/layout-generator.ts
35430
35656
  import { promises as fs12 } from "node:fs";
35431
35657
  import path20 from "node:path";
35432
35658
  import { fileURLToPath as fileURLToPath2 } from "node:url";
35433
- import { z as z38 } from "zod";
35659
+ import { z as z39 } from "zod";
35434
35660
  var QA_FILENAME = "layout-qa.md";
35435
35661
  var PROMPT_FILENAME = "layout-prompt.md";
35436
35662
  var MAX_LOOKUP_LEVELS = 10;
@@ -35465,34 +35691,34 @@ async function writeRoleFile(workspaceRoot, content) {
35465
35691
  await fs12.mkdir(path20.dirname(filePath), { recursive: true });
35466
35692
  await fs12.writeFile(filePath, content, "utf8");
35467
35693
  }
35468
- var QaNextResponseSchema = z38.object({
35469
- done: z38.boolean(),
35470
- question: z38.string().optional(),
35471
- options: z38.array(z38.string()).optional(),
35472
- roleDocument: z38.string().optional()
35473
- });
35474
- var RefinementResponseSchema = z38.object({
35475
- roleDocument: z38.string()
35476
- });
35477
- var WireframeBlockSchema = z38.object({
35478
- type: z38.enum(["headline", "subheadline", "text", "image", "cta", "spacer"]),
35479
- widthFraction: z38.number(),
35480
- heightVh: z38.number()
35481
- });
35482
- var WireframeSectionSchema = z38.object({
35483
- type: z38.enum(["hero", "features", "content", "cta", "footer", "divider"]),
35484
- widthMode: z38.enum(["full-bleed", "contained"]),
35485
- heightVh: z38.number(),
35486
- arrangement: z38.enum(["single-column", "split", "asymmetric-grid", "bento", "stacked"]),
35487
- blocks: z38.array(WireframeBlockSchema),
35488
- bg: z38.enum(["neutral", "alt", "accent", "image"]),
35489
- gapAfterVh: z38.number()
35490
- });
35491
- var WireframeDataSchema = z38.object({
35492
- viewport: z38.object({ width: z38.number(), height: z38.number() }),
35493
- maxWidth: z38.number(),
35494
- pageBg: z38.string(),
35495
- sections: z38.array(WireframeSectionSchema)
35694
+ var QaNextResponseSchema = z39.object({
35695
+ done: z39.boolean(),
35696
+ question: z39.string().optional(),
35697
+ options: z39.array(z39.string()).optional(),
35698
+ roleDocument: z39.string().optional()
35699
+ });
35700
+ var RefinementResponseSchema = z39.object({
35701
+ roleDocument: z39.string()
35702
+ });
35703
+ var WireframeBlockSchema = z39.object({
35704
+ type: z39.enum(["headline", "subheadline", "text", "image", "cta", "spacer"]),
35705
+ widthFraction: z39.number(),
35706
+ heightVh: z39.number()
35707
+ });
35708
+ var WireframeSectionSchema = z39.object({
35709
+ type: z39.enum(["hero", "features", "content", "cta", "footer", "divider"]),
35710
+ widthMode: z39.enum(["full-bleed", "contained"]),
35711
+ heightVh: z39.number(),
35712
+ arrangement: z39.enum(["single-column", "split", "asymmetric-grid", "bento", "stacked"]),
35713
+ blocks: z39.array(WireframeBlockSchema),
35714
+ bg: z39.enum(["neutral", "alt", "accent", "image"]),
35715
+ gapAfterVh: z39.number()
35716
+ });
35717
+ var WireframeDataSchema = z39.object({
35718
+ viewport: z39.object({ width: z39.number(), height: z39.number() }),
35719
+ maxWidth: z39.number(),
35720
+ pageBg: z39.string(),
35721
+ sections: z39.array(WireframeSectionSchema)
35496
35722
  });
35497
35723
  function buildFullBrandContext(allBrands) {
35498
35724
  const lines = [];
@@ -37167,7 +37393,7 @@ var MIN_STREAMING_SEGMENT_DURATION_MS = 1e3;
37167
37393
  var MIN_STREAMING_SEGMENT_BYTES = Math.round(
37168
37394
  PCM_BYTES_PER_MS * MIN_STREAMING_SEGMENT_DURATION_MS
37169
37395
  );
37170
- var AgentIdSchema2 = z39.string().uuid();
37396
+ var AgentIdSchema2 = z40.string().uuid();
37171
37397
  var VOICE_INTERRUPT_CONFIRMATION_MS = 500;
37172
37398
  var VoiceFeatureUnavailableError = class extends Error {
37173
37399
  constructor(context) {
@@ -38548,6 +38774,9 @@ var Session = class _Session {
38548
38774
  case "brands/generate-wireframe":
38549
38775
  await this.handleBrandGenerateWireframeRequest(msg);
38550
38776
  break;
38777
+ case "brands/analyze-photography":
38778
+ await this.handleBrandAnalyzePhotographyRequest(msg);
38779
+ break;
38551
38780
  case "rightfont/library":
38552
38781
  await this.handleRightFontLibraryRequest(msg);
38553
38782
  break;
@@ -40207,8 +40436,8 @@ var Session = class _Session {
40207
40436
  }
40208
40437
  async generateCommitMessage(cwd) {
40209
40438
  const files = await listUncommittedFiles(cwd);
40210
- const schema = z39.object({
40211
- message: z39.string().min(1).max(100).describe(
40439
+ const schema = z40.object({
40440
+ message: z40.string().min(1).max(100).describe(
40212
40441
  "Short feature-level summary, lowercase, imperative mood, no trailing period, no filename references."
40213
40442
  )
40214
40443
  });
@@ -40253,9 +40482,9 @@ var Session = class _Session {
40253
40482
  },
40254
40483
  { appostleHome: this.appostleHome }
40255
40484
  );
40256
- const schema = z39.object({
40257
- title: z39.string().min(1).max(72),
40258
- body: z39.string().min(1)
40485
+ const schema = z40.object({
40486
+ title: z40.string().min(1).max(72),
40487
+ body: z40.string().min(1)
40259
40488
  });
40260
40489
  const fileList = diff.structured && diff.structured.length > 0 ? [
40261
40490
  "Files changed:",
@@ -45747,6 +45976,38 @@ ${details}`.trim());
45747
45976
  });
45748
45977
  }
45749
45978
  }
45979
+ async handleBrandAnalyzePhotographyRequest(request) {
45980
+ const { requestId, workspaceRoot, brandPath, brief, referenceDescriptions } = request;
45981
+ try {
45982
+ const result = await analyzeAndApplyPhotographyStyle({
45983
+ agentManager: this.agentManager,
45984
+ workspaceRoot: expandTilde(workspaceRoot),
45985
+ brandPath: expandTilde(brandPath),
45986
+ brief,
45987
+ referenceDescriptions,
45988
+ logger: this.sessionLogger
45989
+ });
45990
+ this.emit({
45991
+ type: "brands/analyze-photography/response",
45992
+ payload: {
45993
+ requestId,
45994
+ updatedCount: result.updatedCount,
45995
+ error: null
45996
+ }
45997
+ });
45998
+ } catch (error) {
45999
+ const message = error instanceof Error ? error.message : String(error);
46000
+ this.sessionLogger.error({ err: error, brandPath }, "Failed to analyze photography style");
46001
+ this.emit({
46002
+ type: "brands/analyze-photography/response",
46003
+ payload: {
46004
+ requestId,
46005
+ updatedCount: 0,
46006
+ error: message
46007
+ }
46008
+ });
46009
+ }
46010
+ }
45750
46011
  async handleRightFontLibraryRequest(request) {
45751
46012
  const { requestId, libraryPath } = request;
45752
46013
  try {
@@ -46308,7 +46569,7 @@ import webpush from "web-push";
46308
46569
  import webpush2 from "web-push";
46309
46570
 
46310
46571
  // ../server/src/server/speech/providers/local/sherpa/model-catalog.ts
46311
- import { z as z40 } from "zod";
46572
+ import { z as z41 } from "zod";
46312
46573
  var SHERPA_ONNX_MODEL_CATALOG = {
46313
46574
  "zipformer-bilingual-zh-en-2023-02-20": {
46314
46575
  kind: "stt-online",
@@ -46401,7 +46662,7 @@ function buildAliasMap(modelIds) {
46401
46662
  }
46402
46663
  function createAliasedModelIdSchema(params) {
46403
46664
  const validIds = new Set(params.modelIds);
46404
- return z40.string().trim().toLowerCase().refine(
46665
+ return z41.string().trim().toLowerCase().refine(
46405
46666
  (value) => validIds.has(value) || Object.prototype.hasOwnProperty.call(params.aliases, value),
46406
46667
  {
46407
46668
  message: "Invalid model id"
@@ -46432,20 +46693,20 @@ import { v4 as uuidv410 } from "uuid";
46432
46693
  import { v4 as uuidv411 } from "uuid";
46433
46694
 
46434
46695
  // ../server/src/server/speech/providers/openai/config.ts
46435
- import { z as z41 } from "zod";
46696
+ import { z as z42 } from "zod";
46436
46697
  var DEFAULT_OPENAI_REALTIME_TRANSCRIPTION_MODEL = "gpt-4o-transcribe";
46437
46698
  var DEFAULT_OPENAI_TTS_MODEL = "tts-1";
46438
- var OpenAiTtsVoiceSchema = z41.enum(["alloy", "echo", "fable", "onyx", "nova", "shimmer"]);
46439
- var OpenAiTtsModelSchema = z41.enum(["tts-1", "tts-1-hd"]);
46440
- var NumberLikeSchema = z41.union([z41.number(), z41.string().trim().min(1)]);
46441
- var OptionalFiniteNumberSchema = NumberLikeSchema.pipe(z41.coerce.number().finite()).optional();
46442
- var OptionalTrimmedStringSchema = z41.string().trim().optional().transform((value) => value && value.length > 0 ? value : void 0);
46443
- var OpenAiSpeechResolutionSchema = z41.object({
46699
+ var OpenAiTtsVoiceSchema = z42.enum(["alloy", "echo", "fable", "onyx", "nova", "shimmer"]);
46700
+ var OpenAiTtsModelSchema = z42.enum(["tts-1", "tts-1-hd"]);
46701
+ var NumberLikeSchema = z42.union([z42.number(), z42.string().trim().min(1)]);
46702
+ var OptionalFiniteNumberSchema = NumberLikeSchema.pipe(z42.coerce.number().finite()).optional();
46703
+ var OptionalTrimmedStringSchema = z42.string().trim().optional().transform((value) => value && value.length > 0 ? value : void 0);
46704
+ var OpenAiSpeechResolutionSchema = z42.object({
46444
46705
  apiKey: OptionalTrimmedStringSchema,
46445
46706
  sttConfidenceThreshold: OptionalFiniteNumberSchema,
46446
46707
  sttModel: OptionalTrimmedStringSchema,
46447
- ttsVoice: z41.string().trim().toLowerCase().pipe(OpenAiTtsVoiceSchema).default("alloy"),
46448
- ttsModel: z41.string().trim().toLowerCase().pipe(OpenAiTtsModelSchema).default(DEFAULT_OPENAI_TTS_MODEL),
46708
+ ttsVoice: z42.string().trim().toLowerCase().pipe(OpenAiTtsVoiceSchema).default("alloy"),
46709
+ ttsModel: z42.string().trim().toLowerCase().pipe(OpenAiTtsModelSchema).default(DEFAULT_OPENAI_TTS_MODEL),
46449
46710
  realtimeTranscriptionModel: OptionalTrimmedStringSchema.default(
46450
46711
  DEFAULT_OPENAI_REALTIME_TRANSCRIPTION_MODEL
46451
46712
  )
@@ -46490,177 +46751,177 @@ import { v4 } from "uuid";
46490
46751
  import OpenAI2 from "openai";
46491
46752
 
46492
46753
  // ../server/src/server/agent/agent-storage.ts
46493
- import { z as z42 } from "zod";
46494
- var SERIALIZABLE_CONFIG_SCHEMA = z42.object({
46495
- title: z42.string().nullable().optional(),
46496
- modeId: z42.string().nullable().optional(),
46497
- model: z42.string().nullable().optional(),
46498
- thinkingOptionId: z42.string().nullable().optional(),
46499
- featureValues: z42.record(z42.unknown()).nullable().optional(),
46500
- extra: z42.record(z42.any()).nullable().optional(),
46501
- systemPrompt: z42.string().nullable().optional(),
46502
- mcpServers: z42.record(z42.any()).nullable().optional()
46754
+ import { z as z43 } from "zod";
46755
+ var SERIALIZABLE_CONFIG_SCHEMA = z43.object({
46756
+ title: z43.string().nullable().optional(),
46757
+ modeId: z43.string().nullable().optional(),
46758
+ model: z43.string().nullable().optional(),
46759
+ thinkingOptionId: z43.string().nullable().optional(),
46760
+ featureValues: z43.record(z43.unknown()).nullable().optional(),
46761
+ extra: z43.record(z43.any()).nullable().optional(),
46762
+ systemPrompt: z43.string().nullable().optional(),
46763
+ mcpServers: z43.record(z43.any()).nullable().optional()
46503
46764
  }).nullable().optional();
46504
- var PERSISTENCE_HANDLE_SCHEMA = z42.object({
46505
- provider: z42.string(),
46506
- sessionId: z42.string(),
46507
- nativeHandle: z42.any().optional(),
46508
- metadata: z42.record(z42.any()).optional()
46765
+ var PERSISTENCE_HANDLE_SCHEMA = z43.object({
46766
+ provider: z43.string(),
46767
+ sessionId: z43.string(),
46768
+ nativeHandle: z43.any().optional(),
46769
+ metadata: z43.record(z43.any()).optional()
46509
46770
  }).nullable().optional();
46510
- var STORED_AGENT_SCHEMA = z42.object({
46511
- id: z42.string(),
46512
- provider: z42.string(),
46513
- cwd: z42.string(),
46514
- createdAt: z42.string(),
46515
- updatedAt: z42.string(),
46516
- lastActivityAt: z42.string().optional(),
46517
- lastUserMessageAt: z42.string().nullable().optional(),
46518
- title: z42.string().nullable().optional(),
46519
- labels: z42.record(z42.string()).default({}),
46771
+ var STORED_AGENT_SCHEMA = z43.object({
46772
+ id: z43.string(),
46773
+ provider: z43.string(),
46774
+ cwd: z43.string(),
46775
+ createdAt: z43.string(),
46776
+ updatedAt: z43.string(),
46777
+ lastActivityAt: z43.string().optional(),
46778
+ lastUserMessageAt: z43.string().nullable().optional(),
46779
+ title: z43.string().nullable().optional(),
46780
+ labels: z43.record(z43.string()).default({}),
46520
46781
  lastStatus: AgentStatusSchema.default("closed"),
46521
- lastModeId: z42.string().nullable().optional(),
46782
+ lastModeId: z43.string().nullable().optional(),
46522
46783
  config: SERIALIZABLE_CONFIG_SCHEMA,
46523
- runtimeInfo: z42.object({
46524
- provider: z42.string(),
46525
- sessionId: z42.string().nullable(),
46526
- model: z42.string().nullable().optional(),
46527
- thinkingOptionId: z42.string().nullable().optional(),
46528
- modeId: z42.string().nullable().optional(),
46529
- extra: z42.record(z42.unknown()).optional()
46784
+ runtimeInfo: z43.object({
46785
+ provider: z43.string(),
46786
+ sessionId: z43.string().nullable(),
46787
+ model: z43.string().nullable().optional(),
46788
+ thinkingOptionId: z43.string().nullable().optional(),
46789
+ modeId: z43.string().nullable().optional(),
46790
+ extra: z43.record(z43.unknown()).optional()
46530
46791
  }).optional(),
46531
- features: z42.array(AgentFeatureSchema).optional(),
46792
+ features: z43.array(AgentFeatureSchema).optional(),
46532
46793
  persistence: PERSISTENCE_HANDLE_SCHEMA,
46533
- lastError: z42.string().nullable().optional(),
46534
- requiresAttention: z42.boolean().optional(),
46535
- attentionReason: z42.enum(["finished", "error", "permission"]).nullable().optional(),
46536
- attentionTimestamp: z42.string().nullable().optional(),
46537
- internal: z42.boolean().optional(),
46538
- archivedAt: z42.string().nullable().optional(),
46794
+ lastError: z43.string().nullable().optional(),
46795
+ requiresAttention: z43.boolean().optional(),
46796
+ attentionReason: z43.enum(["finished", "error", "permission"]).nullable().optional(),
46797
+ attentionTimestamp: z43.string().nullable().optional(),
46798
+ internal: z43.boolean().optional(),
46799
+ archivedAt: z43.string().nullable().optional(),
46539
46800
  // Fork lineage (optional for backward compat with pre-fork records).
46540
- parentAgentId: z42.string().optional(),
46541
- forkedFromMessageUuid: z42.string().optional(),
46801
+ parentAgentId: z43.string().optional(),
46802
+ forkedFromMessageUuid: z43.string().optional(),
46542
46803
  // Multi-tenant session isolation: the auth-server user-id that created
46543
46804
  // (and therefore owns) this agent + the additive ACL of other users
46544
46805
  // granted access. Both optional/null-default for backward compatibility
46545
46806
  // with pre-Phase-2c records — those load with `null` owner and stay
46546
46807
  // visible to every connecting user (matches today's single-tenant
46547
46808
  // behavior). Set on new agents at create time via Session.ownerUserId.
46548
- ownerUserId: z42.string().nullable().optional(),
46549
- sharedWithUserIds: z42.array(z42.string()).default([]),
46809
+ ownerUserId: z43.string().nullable().optional(),
46810
+ sharedWithUserIds: z43.array(z43.string()).default([]),
46550
46811
  // Owner's display username — needed on resume to route to the correct
46551
46812
  // `CLAUDE_CONFIG_DIR` via `ensureClaudeProfile(username)` for agents
46552
46813
  // created by a shared (non-owner) user. Without this, a resumed shared-
46553
46814
  // user agent would silently fall back to the daemon owner's Claude
46554
46815
  // profile/subscription. Optional — pre-Phase-3 records rehydrate without
46555
46816
  // per-user profile routing.
46556
- ownerUsername: z42.string().optional()
46817
+ ownerUsername: z43.string().optional()
46557
46818
  });
46558
46819
 
46559
46820
  // ../server/src/server/agent/mcp-server.ts
46560
46821
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
46561
- import { z as z43 } from "zod";
46562
- var TerminalSummarySchema = z43.object({
46563
- id: z43.string(),
46564
- name: z43.string(),
46565
- cwd: z43.string()
46822
+ import { z as z44 } from "zod";
46823
+ var TerminalSummarySchema = z44.object({
46824
+ id: z44.string(),
46825
+ name: z44.string(),
46826
+ cwd: z44.string()
46566
46827
  });
46567
- var WorktreeSummarySchema = z43.object({
46568
- path: z43.string(),
46569
- createdAt: z43.string(),
46570
- branchName: z43.string().optional(),
46571
- head: z43.string().optional()
46828
+ var WorktreeSummarySchema = z44.object({
46829
+ path: z44.string(),
46830
+ createdAt: z44.string(),
46831
+ branchName: z44.string().optional(),
46832
+ head: z44.string().optional()
46572
46833
  });
46573
46834
 
46574
46835
  // ../server/src/server/loop-service.ts
46575
- import { z as z44 } from "zod";
46836
+ import { z as z45 } from "zod";
46576
46837
  var MAX_VERIFY_OUTPUT_BYTES = 64 * 1024;
46577
- var LoopVerifyPromptSchema = z44.object({
46578
- passed: z44.boolean(),
46579
- reason: z44.string().min(1)
46580
- });
46581
- var LoopLogEntrySchema2 = z44.object({
46582
- seq: z44.number().int().positive(),
46583
- timestamp: z44.string(),
46584
- iteration: z44.number().int().positive().nullable(),
46585
- source: z44.enum(["loop", "worker", "verifier", "verify-check"]),
46586
- level: z44.enum(["info", "error"]),
46587
- text: z44.string()
46588
- });
46589
- var LoopVerifyCheckResultSchema2 = z44.object({
46590
- command: z44.string(),
46591
- exitCode: z44.number().int(),
46592
- passed: z44.boolean(),
46593
- stdout: z44.string(),
46594
- stderr: z44.string(),
46595
- startedAt: z44.string(),
46596
- completedAt: z44.string()
46597
- });
46598
- var LoopVerifyPromptResultSchema2 = z44.object({
46599
- passed: z44.boolean(),
46600
- reason: z44.string(),
46601
- verifierAgentId: z44.string().nullable(),
46602
- startedAt: z44.string(),
46603
- completedAt: z44.string()
46604
- });
46605
- var LoopIterationRecordSchema2 = z44.object({
46606
- index: z44.number().int().positive(),
46607
- workerAgentId: z44.string().nullable(),
46608
- workerStartedAt: z44.string(),
46609
- workerCompletedAt: z44.string().nullable(),
46610
- verifierAgentId: z44.string().nullable(),
46611
- status: z44.enum(["running", "succeeded", "failed", "stopped"]),
46612
- workerOutcome: z44.enum(["completed", "failed", "canceled"]).nullable(),
46613
- failureReason: z44.string().nullable(),
46614
- verifyChecks: z44.array(LoopVerifyCheckResultSchema2),
46838
+ var LoopVerifyPromptSchema = z45.object({
46839
+ passed: z45.boolean(),
46840
+ reason: z45.string().min(1)
46841
+ });
46842
+ var LoopLogEntrySchema2 = z45.object({
46843
+ seq: z45.number().int().positive(),
46844
+ timestamp: z45.string(),
46845
+ iteration: z45.number().int().positive().nullable(),
46846
+ source: z45.enum(["loop", "worker", "verifier", "verify-check"]),
46847
+ level: z45.enum(["info", "error"]),
46848
+ text: z45.string()
46849
+ });
46850
+ var LoopVerifyCheckResultSchema2 = z45.object({
46851
+ command: z45.string(),
46852
+ exitCode: z45.number().int(),
46853
+ passed: z45.boolean(),
46854
+ stdout: z45.string(),
46855
+ stderr: z45.string(),
46856
+ startedAt: z45.string(),
46857
+ completedAt: z45.string()
46858
+ });
46859
+ var LoopVerifyPromptResultSchema2 = z45.object({
46860
+ passed: z45.boolean(),
46861
+ reason: z45.string(),
46862
+ verifierAgentId: z45.string().nullable(),
46863
+ startedAt: z45.string(),
46864
+ completedAt: z45.string()
46865
+ });
46866
+ var LoopIterationRecordSchema2 = z45.object({
46867
+ index: z45.number().int().positive(),
46868
+ workerAgentId: z45.string().nullable(),
46869
+ workerStartedAt: z45.string(),
46870
+ workerCompletedAt: z45.string().nullable(),
46871
+ verifierAgentId: z45.string().nullable(),
46872
+ status: z45.enum(["running", "succeeded", "failed", "stopped"]),
46873
+ workerOutcome: z45.enum(["completed", "failed", "canceled"]).nullable(),
46874
+ failureReason: z45.string().nullable(),
46875
+ verifyChecks: z45.array(LoopVerifyCheckResultSchema2),
46615
46876
  verifyPrompt: LoopVerifyPromptResultSchema2.nullable()
46616
46877
  });
46617
- var LoopRecordSchema2 = z44.object({
46618
- id: z44.string(),
46619
- name: z44.string().nullable(),
46620
- prompt: z44.string(),
46621
- cwd: z44.string(),
46622
- provider: z44.string(),
46623
- model: z44.string().nullable(),
46624
- workerProvider: z44.string().nullable(),
46625
- workerModel: z44.string().nullable(),
46626
- verifierProvider: z44.string().nullable(),
46627
- verifierModel: z44.string().nullable(),
46628
- verifyPrompt: z44.string().nullable(),
46629
- verifyChecks: z44.array(z44.string()),
46630
- archive: z44.boolean(),
46631
- sleepMs: z44.number().int().nonnegative(),
46632
- maxIterations: z44.number().int().positive().nullable(),
46633
- maxTimeMs: z44.number().int().positive().nullable(),
46634
- status: z44.enum(["running", "succeeded", "failed", "stopped"]),
46635
- createdAt: z44.string(),
46636
- updatedAt: z44.string(),
46637
- startedAt: z44.string(),
46638
- completedAt: z44.string().nullable(),
46639
- stopRequestedAt: z44.string().nullable(),
46640
- iterations: z44.array(LoopIterationRecordSchema2),
46641
- logs: z44.array(LoopLogEntrySchema2),
46642
- nextLogSeq: z44.number().int().positive(),
46643
- activeIteration: z44.number().int().positive().nullable(),
46644
- activeWorkerAgentId: z44.string().nullable(),
46645
- activeVerifierAgentId: z44.string().nullable()
46646
- });
46647
- var StoredLoopsSchema = z44.array(LoopRecordSchema2);
46878
+ var LoopRecordSchema2 = z45.object({
46879
+ id: z45.string(),
46880
+ name: z45.string().nullable(),
46881
+ prompt: z45.string(),
46882
+ cwd: z45.string(),
46883
+ provider: z45.string(),
46884
+ model: z45.string().nullable(),
46885
+ workerProvider: z45.string().nullable(),
46886
+ workerModel: z45.string().nullable(),
46887
+ verifierProvider: z45.string().nullable(),
46888
+ verifierModel: z45.string().nullable(),
46889
+ verifyPrompt: z45.string().nullable(),
46890
+ verifyChecks: z45.array(z45.string()),
46891
+ archive: z45.boolean(),
46892
+ sleepMs: z45.number().int().nonnegative(),
46893
+ maxIterations: z45.number().int().positive().nullable(),
46894
+ maxTimeMs: z45.number().int().positive().nullable(),
46895
+ status: z45.enum(["running", "succeeded", "failed", "stopped"]),
46896
+ createdAt: z45.string(),
46897
+ updatedAt: z45.string(),
46898
+ startedAt: z45.string(),
46899
+ completedAt: z45.string().nullable(),
46900
+ stopRequestedAt: z45.string().nullable(),
46901
+ iterations: z45.array(LoopIterationRecordSchema2),
46902
+ logs: z45.array(LoopLogEntrySchema2),
46903
+ nextLogSeq: z45.number().int().positive(),
46904
+ activeIteration: z45.number().int().positive().nullable(),
46905
+ activeWorkerAgentId: z45.string().nullable(),
46906
+ activeVerifierAgentId: z45.string().nullable()
46907
+ });
46908
+ var StoredLoopsSchema = z45.array(LoopRecordSchema2);
46648
46909
 
46649
46910
  // ../server/src/server/quest/store.ts
46650
- import { z as z45 } from "zod";
46651
- var StoredQuestsSchema = z45.array(QuestRecordSchema);
46911
+ import { z as z46 } from "zod";
46912
+ var StoredQuestsSchema = z46.array(QuestRecordSchema);
46652
46913
 
46653
46914
  // ../server/src/server/quest/quest-metadata-generator.ts
46654
- import { z as z46 } from "zod";
46915
+ import { z as z47 } from "zod";
46655
46916
 
46656
46917
  // ../server/src/server/quest/orchestrator-mcp.ts
46657
46918
  import { createSdkMcpServer as createSdkMcpServer2, tool as tool3 } from "@anthropic-ai/claude-agent-sdk";
46658
- import { z as z47 } from "zod";
46919
+ import { z as z48 } from "zod";
46659
46920
  var HANDOFF_INPUT_SHAPE = {
46660
- rolePath: z47.string().min(1).describe(
46921
+ rolePath: z48.string().min(1).describe(
46661
46922
  "Absolute filesystem path to the role .md file the worker should adopt as its system prompt. Must be one of the role file paths listed in your team roster \u2014 do not invent paths."
46662
46923
  ),
46663
- task: z47.string().min(1).describe(
46924
+ task: z48.string().min(1).describe(
46664
46925
  "Concrete, self-contained instruction for the worker. The worker has its own toolbelt and reads the role at rolePath as its system prompt \u2014 write the task as a normal user message describing what to do, what inputs to read, and where to write outputs. Reference the hivemind doc by absolute path if relevant."
46665
46926
  )
46666
46927
  };
@@ -46715,13 +46976,13 @@ var execFileAsync3 = promisify4(execFile3);
46715
46976
  var MAX_VERIFY_OUTPUT_BYTES2 = 64 * 1024;
46716
46977
 
46717
46978
  // ../server/src/shared/connection-offer.ts
46718
- import { z as z48 } from "zod";
46719
- var ConnectionOfferV2Schema = z48.object({
46720
- v: z48.literal(2),
46721
- serverId: z48.string().min(1),
46722
- daemonPublicKeyB64: z48.string().min(1),
46723
- relay: z48.object({
46724
- endpoint: z48.string().min(1)
46979
+ import { z as z49 } from "zod";
46980
+ var ConnectionOfferV2Schema = z49.object({
46981
+ v: z49.literal(2),
46982
+ serverId: z49.string().min(1),
46983
+ daemonPublicKeyB64: z49.string().min(1),
46984
+ relay: z49.object({
46985
+ endpoint: z49.string().min(1)
46725
46986
  })
46726
46987
  });
46727
46988
 
@@ -46755,21 +47016,21 @@ function isRelayClientWebSocketUrl(url) {
46755
47016
 
46756
47017
  // ../server/src/server/config.ts
46757
47018
  import path22 from "node:path";
46758
- import { z as z52 } from "zod";
47019
+ import { z as z53 } from "zod";
46759
47020
 
46760
47021
  // ../server/src/server/speech/speech-config-resolver.ts
46761
- import { z as z51 } from "zod";
47022
+ import { z as z52 } from "zod";
46762
47023
 
46763
47024
  // ../server/src/server/speech/providers/local/config.ts
46764
47025
  import path21 from "node:path";
46765
- import { z as z49 } from "zod";
47026
+ import { z as z50 } from "zod";
46766
47027
  var DEFAULT_LOCAL_MODELS_SUBDIR = path21.join("models", "local-speech");
46767
- var NumberLikeSchema2 = z49.union([z49.number(), z49.string().trim().min(1)]);
46768
- var OptionalFiniteNumberSchema2 = NumberLikeSchema2.pipe(z49.coerce.number().finite()).optional();
46769
- var OptionalIntegerSchema = NumberLikeSchema2.pipe(z49.coerce.number().int()).optional();
46770
- var LocalSpeechResolutionSchema = z49.object({
46771
- includeProviderConfig: z49.boolean(),
46772
- modelsDir: z49.string().trim().min(1),
47028
+ var NumberLikeSchema2 = z50.union([z50.number(), z50.string().trim().min(1)]);
47029
+ var OptionalFiniteNumberSchema2 = NumberLikeSchema2.pipe(z50.coerce.number().finite()).optional();
47030
+ var OptionalIntegerSchema = NumberLikeSchema2.pipe(z50.coerce.number().int()).optional();
47031
+ var LocalSpeechResolutionSchema = z50.object({
47032
+ includeProviderConfig: z50.boolean(),
47033
+ modelsDir: z50.string().trim().min(1),
46773
47034
  dictationLocalSttModel: LocalSttModelIdSchema.default(DEFAULT_LOCAL_STT_MODEL),
46774
47035
  voiceLocalSttModel: LocalSttModelIdSchema.default(DEFAULT_LOCAL_STT_MODEL),
46775
47036
  voiceLocalTtsModel: LocalTtsModelIdSchema.default(DEFAULT_LOCAL_TTS_MODEL),
@@ -46825,17 +47086,17 @@ function resolveLocalSpeechConfig(params) {
46825
47086
  }
46826
47087
 
46827
47088
  // ../server/src/server/speech/speech-types.ts
46828
- import { z as z50 } from "zod";
46829
- var SpeechProviderIdSchema2 = z50.enum(["openai", "local"]);
46830
- var RequestedSpeechProviderSchema = z50.object({
47089
+ import { z as z51 } from "zod";
47090
+ var SpeechProviderIdSchema2 = z51.enum(["openai", "local"]);
47091
+ var RequestedSpeechProviderSchema = z51.object({
46831
47092
  provider: SpeechProviderIdSchema2,
46832
- explicit: z50.boolean(),
46833
- enabled: z50.boolean().optional()
47093
+ explicit: z51.boolean(),
47094
+ enabled: z51.boolean().optional()
46834
47095
  });
46835
47096
 
46836
47097
  // ../server/src/server/speech/speech-config-resolver.ts
46837
- var OptionalSpeechProviderSchema = z51.string().trim().toLowerCase().pipe(SpeechProviderIdSchema2).optional();
46838
- var OptionalBooleanFlagSchema = z51.union([z51.boolean(), z51.string().trim().toLowerCase()]).optional().transform((value) => {
47098
+ var OptionalSpeechProviderSchema = z52.string().trim().toLowerCase().pipe(SpeechProviderIdSchema2).optional();
47099
+ var OptionalBooleanFlagSchema = z52.union([z52.boolean(), z52.string().trim().toLowerCase()]).optional().transform((value) => {
46839
47100
  if (typeof value === "boolean") {
46840
47101
  return value;
46841
47102
  }
@@ -46850,7 +47111,7 @@ var OptionalBooleanFlagSchema = z51.union([z51.boolean(), z51.string().trim().to
46850
47111
  }
46851
47112
  return void 0;
46852
47113
  });
46853
- var RequestedSpeechProvidersSchema = z51.object({
47114
+ var RequestedSpeechProvidersSchema = z52.object({
46854
47115
  dictationStt: OptionalSpeechProviderSchema.default("local"),
46855
47116
  voiceTurnDetection: OptionalSpeechProviderSchema.default("local"),
46856
47117
  voiceStt: OptionalSpeechProviderSchema.default("local"),
@@ -46959,9 +47220,9 @@ function parseBooleanEnv(value) {
46959
47220
  }
46960
47221
  return void 0;
46961
47222
  }
46962
- var OptionalVoiceLlmProviderSchema = z52.union([z52.string(), z52.null(), z52.undefined()]).transform(
47223
+ var OptionalVoiceLlmProviderSchema = z53.union([z53.string(), z53.null(), z53.undefined()]).transform(
46963
47224
  (value) => typeof value === "string" ? value.trim().toLowerCase() : null
46964
- ).pipe(z52.union([AgentProviderSchema, z52.null()]));
47225
+ ).pipe(z53.union([AgentProviderSchema, z53.null()]));
46965
47226
  function parseOptionalVoiceLlmProvider(value) {
46966
47227
  const parsed = OptionalVoiceLlmProviderSchema.safeParse(value);
46967
47228
  return parsed.success ? parsed.data : null;
@@ -47335,6 +47596,9 @@ function createEncryptedTransport(base, daemonPublicKeyB64, logger, staticKeyPai
47335
47596
  throw new Error("Encrypted channel not ready");
47336
47597
  }
47337
47598
  void channel.send(normalizeTransportPayload(data)).catch((error) => {
47599
+ if (closed) {
47600
+ console.error("[relay-e2ee] send failed after transport close:", error);
47601
+ }
47338
47602
  emitError(error);
47339
47603
  });
47340
47604
  },
@@ -50937,6 +51201,20 @@ var DaemonClient = class {
50937
51201
  timeout: 12e4
50938
51202
  });
50939
51203
  }
51204
+ async brandsAnalyzePhotography(options) {
51205
+ return this.sendCorrelatedSessionRequest({
51206
+ requestId: options.requestId,
51207
+ message: {
51208
+ type: "brands/analyze-photography",
51209
+ workspaceRoot: options.workspaceRoot,
51210
+ brandPath: options.brandPath,
51211
+ brief: options.brief,
51212
+ ...options.referenceDescriptions ? { referenceDescriptions: options.referenceDescriptions } : {}
51213
+ },
51214
+ responseType: "brands/analyze-photography/response",
51215
+ timeout: 12e4
51216
+ });
51217
+ }
50940
51218
  onTerminalStreamEvent(handler) {
50941
51219
  this.terminalStreamListeners.add(handler);
50942
51220
  return () => {