@toothfairyai/tfdesign 0.4.3 → 0.4.5

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.
@@ -9,8 +9,8 @@ import { execFile as execFile5, spawn as spawn3 } from "node:child_process";
9
9
  import { randomUUID as randomUUID5 } from "node:crypto";
10
10
  import { createRequire } from "node:module";
11
11
  import { fileURLToPath as fileURLToPath2 } from "node:url";
12
- import path28 from "node:path";
13
- import fs7 from "node:fs";
12
+ import path29 from "node:path";
13
+ import fs8 from "node:fs";
14
14
  import os4 from "node:os";
15
15
  import net2 from "node:net";
16
16
 
@@ -4022,7 +4022,7 @@ async function extractBrandFromUrl(url) {
4022
4022
  const trimmed = normalizeUrl(url ?? "");
4023
4023
  if (!trimmed) throw new Error("url is required");
4024
4024
  setDesignlangBrowsersPath();
4025
- const api = await import("designlang/api");
4025
+ const api = await import("./api-2ZCSAOJG.js");
4026
4026
  const design = await api.extract(trimmed);
4027
4027
  const extraction = mapDesignToExtraction(design, api.render, trimmed);
4028
4028
  extraction.images = await harvestImages(trimmed, extraction.ogImage);
@@ -6495,8 +6495,8 @@ function getErrorMap() {
6495
6495
 
6496
6496
  // node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
6497
6497
  var makeIssue = (params) => {
6498
- const { data, path: path29, errorMaps, issueData } = params;
6499
- const fullPath = [...path29, ...issueData.path || []];
6498
+ const { data, path: path30, errorMaps, issueData } = params;
6499
+ const fullPath = [...path30, ...issueData.path || []];
6500
6500
  const fullIssue = {
6501
6501
  ...issueData,
6502
6502
  path: fullPath
@@ -6612,11 +6612,11 @@ var errorUtil;
6612
6612
 
6613
6613
  // node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js
6614
6614
  var ParseInputLazyPath = class {
6615
- constructor(parent, value, path29, key) {
6615
+ constructor(parent, value, path30, key) {
6616
6616
  this._cachedPath = [];
6617
6617
  this.parent = parent;
6618
6618
  this.data = value;
6619
- this._path = path29;
6619
+ this._path = path30;
6620
6620
  this._key = key;
6621
6621
  }
6622
6622
  get path() {
@@ -14368,9 +14368,9 @@ function parseDeclarations(body) {
14368
14368
  return out;
14369
14369
  }
14370
14370
  function resolveFontSizePx(decls) {
14371
- const fs8 = findLastDecl(decls, "font-size");
14372
- if (!fs8) return null;
14373
- const m = /^(-?\d*\.?\d+)\s*(px|rem)\b/i.exec(fs8.value);
14371
+ const fs9 = findLastDecl(decls, "font-size");
14372
+ if (!fs9) return null;
14373
+ const m = /^(-?\d*\.?\d+)\s*(px|rem)\b/i.exec(fs9.value);
14374
14374
  if (!m) return null;
14375
14375
  const v = parseFloat(m[1]);
14376
14376
  const unit = m[2].toLowerCase();
@@ -16959,37 +16959,37 @@ function isPlainObject2(value) {
16959
16959
  const proto = Object.getPrototypeOf(value);
16960
16960
  return proto === Object.prototype || proto === null;
16961
16961
  }
16962
- function asString(value, path29, issues, max = MAX_SHORT_TEXT_LENGTH) {
16962
+ function asString(value, path30, issues, max = MAX_SHORT_TEXT_LENGTH) {
16963
16963
  if (typeof value !== "string") {
16964
- issues.push({ path: path29, message: `${path29} must be a string` });
16964
+ issues.push({ path: path30, message: `${path30} must be a string` });
16965
16965
  return void 0;
16966
16966
  }
16967
16967
  if (value.length === 0) {
16968
- issues.push({ path: path29, message: `${path29} is required` });
16968
+ issues.push({ path: path30, message: `${path30} is required` });
16969
16969
  }
16970
16970
  if (value.length > max) {
16971
- issues.push({ path: path29, message: `${path29} exceeds max length (${max})` });
16971
+ issues.push({ path: path30, message: `${path30} exceeds max length (${max})` });
16972
16972
  }
16973
16973
  return value;
16974
16974
  }
16975
- function asOptionalString(value, path29, issues, max = MAX_SHORT_TEXT_LENGTH) {
16975
+ function asOptionalString(value, path30, issues, max = MAX_SHORT_TEXT_LENGTH) {
16976
16976
  if (value === void 0) return void 0;
16977
- return asString(value, path29, issues, max);
16977
+ return asString(value, path30, issues, max);
16978
16978
  }
16979
- function asBoolean(value, path29, issues) {
16979
+ function asBoolean(value, path30, issues) {
16980
16980
  if (typeof value !== "boolean") {
16981
- issues.push({ path: path29, message: `${path29} must be a boolean` });
16981
+ issues.push({ path: path30, message: `${path30} must be a boolean` });
16982
16982
  return void 0;
16983
16983
  }
16984
16984
  return value;
16985
16985
  }
16986
- function asOptionalBoolean(value, path29, issues) {
16986
+ function asOptionalBoolean(value, path30, issues) {
16987
16987
  if (value === void 0) return void 0;
16988
- return asBoolean(value, path29, issues);
16988
+ return asBoolean(value, path30, issues);
16989
16989
  }
16990
- function validateEnum(value, allowed, path29, issues) {
16990
+ function validateEnum(value, allowed, path30, issues) {
16991
16991
  if (typeof value !== "string" || !allowed.has(value)) {
16992
- issues.push({ path: path29, message: `${path29} is not allowed` });
16992
+ issues.push({ path: path30, message: `${path30} is not allowed` });
16993
16993
  return void 0;
16994
16994
  }
16995
16995
  return value;
@@ -16998,26 +16998,26 @@ function isIsoDateString(value) {
16998
16998
  const time = Date.parse(value);
16999
16999
  return Number.isFinite(time) && new Date(time).toISOString() === value;
17000
17000
  }
17001
- function validateIsoDate(value, path29, issues) {
17002
- const text = asString(value, path29, issues, MAX_SHORT_TEXT_LENGTH);
17001
+ function validateIsoDate(value, path30, issues) {
17002
+ const text = asString(value, path30, issues, MAX_SHORT_TEXT_LENGTH);
17003
17003
  if (text !== void 0 && !isIsoDateString(text)) {
17004
- issues.push({ path: path29, message: `${path29} must be an ISO-8601 timestamp` });
17004
+ issues.push({ path: path30, message: `${path30} must be an ISO-8601 timestamp` });
17005
17005
  }
17006
17006
  return text;
17007
17007
  }
17008
- function validateRelativePath(value, path29, issues) {
17008
+ function validateRelativePath(value, path30, issues) {
17009
17009
  if (value.length > MAX_PATH_LENGTH) {
17010
- issues.push({ path: path29, message: `${path29} exceeds max length (${MAX_PATH_LENGTH})` });
17010
+ issues.push({ path: path30, message: `${path30} exceeds max length (${MAX_PATH_LENGTH})` });
17011
17011
  }
17012
17012
  if (value.includes("\0")) {
17013
- issues.push({ path: path29, message: `${path29} cannot contain null bytes` });
17013
+ issues.push({ path: path30, message: `${path30} cannot contain null bytes` });
17014
17014
  }
17015
17015
  const normalized = value.replace(/\\/g, "/");
17016
17016
  if (normalized.startsWith("/") || /^[A-Za-z]:/.test(normalized)) {
17017
- issues.push({ path: path29, message: `${path29} cannot be an absolute path` });
17017
+ issues.push({ path: path30, message: `${path30} cannot be an absolute path` });
17018
17018
  }
17019
17019
  if (normalized.split("/").some((part) => part === "..")) {
17020
- issues.push({ path: path29, message: `${path29} cannot contain path traversal` });
17020
+ issues.push({ path: path30, message: `${path30} cannot contain path traversal` });
17021
17021
  }
17022
17022
  }
17023
17023
  function validateNoDaemonOwnedFields(raw, issues) {
@@ -17027,17 +17027,17 @@ function validateNoDaemonOwnedFields(raw, issues) {
17027
17027
  }
17028
17028
  }
17029
17029
  }
17030
- function validateOnlyAllowedKeys(raw, allowed, path29, issues) {
17030
+ function validateOnlyAllowedKeys(raw, allowed, path30, issues) {
17031
17031
  for (const key of Object.keys(raw)) {
17032
17032
  if (!allowed.has(key)) {
17033
- issues.push({ path: `${path29}.${key}`, message: `${path29}.${key} is not allowed` });
17033
+ issues.push({ path: `${path30}.${key}`, message: `${path30}.${key} is not allowed` });
17034
17034
  }
17035
17035
  }
17036
17036
  }
17037
- function validateBoundedJsonInternal(value, path29, issues, depth) {
17037
+ function validateBoundedJsonInternal(value, path30, issues, depth) {
17038
17038
  if (value === null || typeof value === "boolean" || typeof value === "number") {
17039
17039
  if (typeof value === "number" && !Number.isFinite(value)) {
17040
- issues.push({ path: path29, message: `${path29} must be a finite number` });
17040
+ issues.push({ path: path30, message: `${path30} must be a finite number` });
17041
17041
  return false;
17042
17042
  }
17043
17043
  return true;
@@ -17045,8 +17045,8 @@ function validateBoundedJsonInternal(value, path29, issues, depth) {
17045
17045
  if (typeof value === "string") {
17046
17046
  if (value.length > LIVE_ARTIFACT_BOUNDED_JSON_CONSTRAINTS.maxStringLength) {
17047
17047
  issues.push({
17048
- path: path29,
17049
- message: `${path29} exceeds max string length (${LIVE_ARTIFACT_BOUNDED_JSON_CONSTRAINTS.maxStringLength})`
17048
+ path: path30,
17049
+ message: `${path30} exceeds max string length (${LIVE_ARTIFACT_BOUNDED_JSON_CONSTRAINTS.maxStringLength})`
17050
17050
  });
17051
17051
  return false;
17052
17052
  }
@@ -17054,128 +17054,128 @@ function validateBoundedJsonInternal(value, path29, issues, depth) {
17054
17054
  }
17055
17055
  if (Array.isArray(value)) {
17056
17056
  if (depth > LIVE_ARTIFACT_BOUNDED_JSON_CONSTRAINTS.maxDepth) {
17057
- issues.push({ path: path29, message: `${path29} exceeds max JSON depth (${LIVE_ARTIFACT_BOUNDED_JSON_CONSTRAINTS.maxDepth})` });
17057
+ issues.push({ path: path30, message: `${path30} exceeds max JSON depth (${LIVE_ARTIFACT_BOUNDED_JSON_CONSTRAINTS.maxDepth})` });
17058
17058
  return false;
17059
17059
  }
17060
17060
  if (value.length > LIVE_ARTIFACT_BOUNDED_JSON_CONSTRAINTS.maxArrayLength) {
17061
17061
  issues.push({
17062
- path: path29,
17063
- message: `${path29} exceeds max array length (${LIVE_ARTIFACT_BOUNDED_JSON_CONSTRAINTS.maxArrayLength})`
17062
+ path: path30,
17063
+ message: `${path30} exceeds max array length (${LIVE_ARTIFACT_BOUNDED_JSON_CONSTRAINTS.maxArrayLength})`
17064
17064
  });
17065
17065
  return false;
17066
17066
  }
17067
- return value.every((item, index) => validateBoundedJsonInternal(item, `${path29}.${index}`, issues, depth + 1));
17067
+ return value.every((item, index) => validateBoundedJsonInternal(item, `${path30}.${index}`, issues, depth + 1));
17068
17068
  }
17069
17069
  if (isPlainObject2(value)) {
17070
17070
  if (depth > LIVE_ARTIFACT_BOUNDED_JSON_CONSTRAINTS.maxDepth) {
17071
- issues.push({ path: path29, message: `${path29} exceeds max JSON depth (${LIVE_ARTIFACT_BOUNDED_JSON_CONSTRAINTS.maxDepth})` });
17071
+ issues.push({ path: path30, message: `${path30} exceeds max JSON depth (${LIVE_ARTIFACT_BOUNDED_JSON_CONSTRAINTS.maxDepth})` });
17072
17072
  return false;
17073
17073
  }
17074
17074
  const entries = Object.entries(value);
17075
17075
  if (entries.length > LIVE_ARTIFACT_BOUNDED_JSON_CONSTRAINTS.maxObjectKeys) {
17076
17076
  issues.push({
17077
- path: path29,
17078
- message: `${path29} exceeds max object keys (${LIVE_ARTIFACT_BOUNDED_JSON_CONSTRAINTS.maxObjectKeys})`
17077
+ path: path30,
17078
+ message: `${path30} exceeds max object keys (${LIVE_ARTIFACT_BOUNDED_JSON_CONSTRAINTS.maxObjectKeys})`
17079
17079
  });
17080
17080
  return false;
17081
17081
  }
17082
17082
  let valid = true;
17083
17083
  for (const [key, child] of entries) {
17084
17084
  if (FORBIDDEN_JSON_KEYS.has(key.toLowerCase())) {
17085
- issues.push({ path: `${path29}.${key}`, message: `${path29}.${key} uses a forbidden key` });
17085
+ issues.push({ path: `${path30}.${key}`, message: `${path30}.${key} uses a forbidden key` });
17086
17086
  valid = false;
17087
17087
  }
17088
- valid = validateBoundedJsonInternal(child, `${path29}.${key}`, issues, depth + 1) && valid;
17088
+ valid = validateBoundedJsonInternal(child, `${path30}.${key}`, issues, depth + 1) && valid;
17089
17089
  }
17090
17090
  return valid;
17091
17091
  }
17092
- issues.push({ path: path29, message: `${path29} must be JSON-serializable` });
17092
+ issues.push({ path: path30, message: `${path30} must be JSON-serializable` });
17093
17093
  return false;
17094
17094
  }
17095
- function validateBoundedJsonValue(value, path29 = "value") {
17095
+ function validateBoundedJsonValue(value, path30 = "value") {
17096
17096
  const issues = [];
17097
- if (validateBoundedJsonInternal(value, path29, issues, 1)) {
17097
+ if (validateBoundedJsonInternal(value, path30, issues, 1)) {
17098
17098
  const serialized = JSON.stringify(value);
17099
17099
  if (Buffer.byteLength(serialized, "utf8") <= LIVE_ARTIFACT_BOUNDED_JSON_CONSTRAINTS.maxSerializedBytes) {
17100
17100
  return ok(value);
17101
17101
  }
17102
17102
  issues.push({
17103
- path: path29,
17104
- message: `${path29} exceeds max serialized size (${LIVE_ARTIFACT_BOUNDED_JSON_CONSTRAINTS.maxSerializedBytes} bytes)`
17103
+ path: path30,
17104
+ message: `${path30} exceeds max serialized size (${LIVE_ARTIFACT_BOUNDED_JSON_CONSTRAINTS.maxSerializedBytes} bytes)`
17105
17105
  });
17106
17106
  }
17107
17107
  return fail(issues);
17108
17108
  }
17109
- function validateBoundedJsonObject(value, path29 = "value") {
17110
- const result = validateBoundedJsonValue(value, path29);
17109
+ function validateBoundedJsonObject(value, path30 = "value") {
17110
+ const result = validateBoundedJsonValue(value, path30);
17111
17111
  if (!result.ok) return result;
17112
17112
  if (!isPlainObject2(result.value)) {
17113
- return fail([{ path: path29, message: `${path29} must be a JSON object` }]);
17113
+ return fail([{ path: path30, message: `${path30} must be a JSON object` }]);
17114
17114
  }
17115
17115
  return ok(result.value);
17116
17116
  }
17117
- function validateSourceInputPaths(value, path29, issues) {
17117
+ function validateSourceInputPaths(value, path30, issues) {
17118
17118
  if (typeof value === "string") {
17119
- validateRelativePath(value, path29, issues);
17119
+ validateRelativePath(value, path30, issues);
17120
17120
  return;
17121
17121
  }
17122
17122
  if (Array.isArray(value)) {
17123
- value.forEach((item, index) => validateSourceInputPaths(item, `${path29}.${index}`, issues));
17123
+ value.forEach((item, index) => validateSourceInputPaths(item, `${path30}.${index}`, issues));
17124
17124
  return;
17125
17125
  }
17126
17126
  if (isPlainObject2(value)) {
17127
17127
  for (const [key, child] of Object.entries(value)) {
17128
- if (/path|file|glob|ref/i.test(key)) validateSourceInputPaths(child, `${path29}.${key}`, issues);
17128
+ if (/path|file|glob|ref/i.test(key)) validateSourceInputPaths(child, `${path30}.${key}`, issues);
17129
17129
  }
17130
17130
  }
17131
17131
  }
17132
- function validatePreview(value, path29, issues) {
17132
+ function validatePreview(value, path30, issues) {
17133
17133
  if (!isPlainObject2(value)) {
17134
- issues.push({ path: path29, message: `${path29} must be an object` });
17134
+ issues.push({ path: path30, message: `${path30} must be an object` });
17135
17135
  return void 0;
17136
17136
  }
17137
- const type = validateEnum(value.type, PREVIEW_TYPES, `${path29}.type`, issues);
17138
- const entry = asString(value.entry, `${path29}.entry`, issues, MAX_PATH_LENGTH);
17139
- if (entry !== void 0) validateRelativePath(entry, `${path29}.entry`, issues);
17137
+ const type = validateEnum(value.type, PREVIEW_TYPES, `${path30}.type`, issues);
17138
+ const entry = asString(value.entry, `${path30}.entry`, issues, MAX_PATH_LENGTH);
17139
+ if (entry !== void 0) validateRelativePath(entry, `${path30}.entry`, issues);
17140
17140
  if (type === void 0 || entry === void 0) return void 0;
17141
17141
  return { type, entry };
17142
17142
  }
17143
17143
  var SAFE_MAPPING_SEGMENT = /^[A-Za-z_][A-Za-z0-9_-]*$|^(?:0|[1-9][0-9]*)$/;
17144
17144
  var UNSAFE_MAPPING_SEGMENTS = /* @__PURE__ */ new Set(["__proto__", "prototype", "constructor"]);
17145
- function validateMappingPath(value, path29, issues) {
17145
+ function validateMappingPath(value, path30, issues) {
17146
17146
  const normalized = value.startsWith("$.") ? value.slice(2) : value;
17147
17147
  if (normalized.length === 0 || normalized.startsWith(".") || normalized.endsWith(".") || normalized.includes("..")) {
17148
- issues.push({ path: path29, message: `${path29} must be a dot-separated JSON path` });
17148
+ issues.push({ path: path30, message: `${path30} must be a dot-separated JSON path` });
17149
17149
  return;
17150
17150
  }
17151
17151
  for (const segment of normalized.split(".")) {
17152
17152
  if (!SAFE_MAPPING_SEGMENT.test(segment) || UNSAFE_MAPPING_SEGMENTS.has(segment)) {
17153
- issues.push({ path: path29, message: `${path29} contains unsupported JSON path segment: ${segment}` });
17153
+ issues.push({ path: path30, message: `${path30} contains unsupported JSON path segment: ${segment}` });
17154
17154
  return;
17155
17155
  }
17156
17156
  }
17157
17157
  }
17158
- function validateSource(value, path29, issues) {
17158
+ function validateSource(value, path30, issues) {
17159
17159
  if (!isPlainObject2(value)) {
17160
- issues.push({ path: path29, message: `${path29} must be an object` });
17160
+ issues.push({ path: path30, message: `${path30} must be an object` });
17161
17161
  return void 0;
17162
17162
  }
17163
- validateOnlyAllowedKeys(value, SOURCE_KEYS, path29, issues);
17164
- const type = validateEnum(value.type, SOURCE_TYPES, `${path29}.type`, issues);
17165
- const toolName = asOptionalString(value.toolName, `${path29}.toolName`, issues, MAX_ID_LENGTH);
17166
- const inputResult = validateBoundedJsonObject(value.input, `${path29}.input`);
17163
+ validateOnlyAllowedKeys(value, SOURCE_KEYS, path30, issues);
17164
+ const type = validateEnum(value.type, SOURCE_TYPES, `${path30}.type`, issues);
17165
+ const toolName = asOptionalString(value.toolName, `${path30}.toolName`, issues, MAX_ID_LENGTH);
17166
+ const inputResult = validateBoundedJsonObject(value.input, `${path30}.input`);
17167
17167
  if (!inputResult.ok) issues.push(...inputResult.issues);
17168
- else validateSourceInputPaths(inputResult.value, `${path29}.input`, issues);
17168
+ else validateSourceInputPaths(inputResult.value, `${path30}.input`, issues);
17169
17169
  let connector;
17170
17170
  if (value.connector !== void 0) {
17171
17171
  if (!isPlainObject2(value.connector)) {
17172
- issues.push({ path: `${path29}.connector`, message: `${path29}.connector must be an object` });
17172
+ issues.push({ path: `${path30}.connector`, message: `${path30}.connector must be an object` });
17173
17173
  } else {
17174
- validateOnlyAllowedKeys(value.connector, CONNECTOR_REFERENCE_KEYS, `${path29}.connector`, issues);
17175
- const connectorId = asString(value.connector.connectorId, `${path29}.connector.connectorId`, issues, MAX_ID_LENGTH);
17176
- const accountLabel = asOptionalString(value.connector.accountLabel, `${path29}.connector.accountLabel`, issues, MAX_SHORT_TEXT_LENGTH);
17177
- const connectorToolName = asString(value.connector.toolName, `${path29}.connector.toolName`, issues, MAX_ID_LENGTH);
17178
- const approvalPolicy = value.connector.approvalPolicy === void 0 ? void 0 : validateEnum(value.connector.approvalPolicy, CONNECTOR_APPROVAL_POLICIES, `${path29}.connector.approvalPolicy`, issues);
17174
+ validateOnlyAllowedKeys(value.connector, CONNECTOR_REFERENCE_KEYS, `${path30}.connector`, issues);
17175
+ const connectorId = asString(value.connector.connectorId, `${path30}.connector.connectorId`, issues, MAX_ID_LENGTH);
17176
+ const accountLabel = asOptionalString(value.connector.accountLabel, `${path30}.connector.accountLabel`, issues, MAX_SHORT_TEXT_LENGTH);
17177
+ const connectorToolName = asString(value.connector.toolName, `${path30}.connector.toolName`, issues, MAX_ID_LENGTH);
17178
+ const approvalPolicy = value.connector.approvalPolicy === void 0 ? void 0 : validateEnum(value.connector.approvalPolicy, CONNECTOR_APPROVAL_POLICIES, `${path30}.connector.approvalPolicy`, issues);
17179
17179
  if (connectorId !== void 0 && connectorToolName !== void 0) {
17180
17180
  const nextConnector = { connectorId, toolName: connectorToolName };
17181
17181
  if (accountLabel !== void 0) nextConnector.accountLabel = accountLabel;
@@ -17187,17 +17187,17 @@ function validateSource(value, path29, issues) {
17187
17187
  let outputMapping;
17188
17188
  if (value.outputMapping !== void 0) {
17189
17189
  if (!isPlainObject2(value.outputMapping)) {
17190
- issues.push({ path: `${path29}.outputMapping`, message: `${path29}.outputMapping must be an object` });
17190
+ issues.push({ path: `${path30}.outputMapping`, message: `${path30}.outputMapping must be an object` });
17191
17191
  } else {
17192
- validateOnlyAllowedKeys(value.outputMapping, OUTPUT_MAPPING_KEYS, `${path29}.outputMapping`, issues);
17192
+ validateOnlyAllowedKeys(value.outputMapping, OUTPUT_MAPPING_KEYS, `${path30}.outputMapping`, issues);
17193
17193
  const mapping = {};
17194
17194
  if (value.outputMapping.dataPaths !== void 0) {
17195
17195
  if (!Array.isArray(value.outputMapping.dataPaths) || value.outputMapping.dataPaths.length > MAX_MAPPING_PATHS) {
17196
- issues.push({ path: `${path29}.outputMapping.dataPaths`, message: `${path29}.outputMapping.dataPaths must be a bounded array` });
17196
+ issues.push({ path: `${path30}.outputMapping.dataPaths`, message: `${path30}.outputMapping.dataPaths must be a bounded array` });
17197
17197
  } else {
17198
17198
  mapping.dataPaths = [];
17199
17199
  value.outputMapping.dataPaths.forEach((item, index) => {
17200
- const itemPath = `${path29}.outputMapping.dataPaths.${index}`;
17200
+ const itemPath = `${path30}.outputMapping.dataPaths.${index}`;
17201
17201
  if (!isPlainObject2(item)) {
17202
17202
  issues.push({ path: itemPath, message: `${itemPath} must be an object` });
17203
17203
  return;
@@ -17211,21 +17211,21 @@ function validateSource(value, path29, issues) {
17211
17211
  }
17212
17212
  }
17213
17213
  if (value.outputMapping.transform !== void 0) {
17214
- const transform = validateEnum(value.outputMapping.transform, OUTPUT_TRANSFORMS, `${path29}.outputMapping.transform`, issues);
17214
+ const transform = validateEnum(value.outputMapping.transform, OUTPUT_TRANSFORMS, `${path30}.outputMapping.transform`, issues);
17215
17215
  if (transform !== void 0) mapping.transform = transform;
17216
17216
  }
17217
17217
  outputMapping = mapping;
17218
17218
  }
17219
17219
  }
17220
- const refreshPermission = validateEnum(value.refreshPermission, REFRESH_PERMISSIONS, `${path29}.refreshPermission`, issues);
17220
+ const refreshPermission = validateEnum(value.refreshPermission, REFRESH_PERMISSIONS, `${path30}.refreshPermission`, issues);
17221
17221
  if (type === "connector_tool" && connector === void 0) {
17222
- issues.push({ path: `${path29}.connector`, message: `${path29}.connector is required for connector_tool sources` });
17222
+ issues.push({ path: `${path30}.connector`, message: `${path30}.connector is required for connector_tool sources` });
17223
17223
  }
17224
17224
  if (type === "connector_tool" && toolName !== void 0 && connector !== void 0 && toolName !== connector.toolName) {
17225
- issues.push({ path: `${path29}.toolName`, message: `${path29}.toolName must match ${path29}.connector.toolName` });
17225
+ issues.push({ path: `${path30}.toolName`, message: `${path30}.toolName must match ${path30}.connector.toolName` });
17226
17226
  }
17227
17227
  if (type === "daemon_tool" && toolName === void 0) {
17228
- issues.push({ path: `${path29}.toolName`, message: `${path29}.toolName is required for daemon_tool sources` });
17228
+ issues.push({ path: `${path30}.toolName`, message: `${path30}.toolName is required for daemon_tool sources` });
17229
17229
  }
17230
17230
  if (type === void 0 || !inputResult.ok || refreshPermission === void 0) return void 0;
17231
17231
  const source = { type, input: inputResult.value, refreshPermission };
@@ -17234,24 +17234,24 @@ function validateSource(value, path29, issues) {
17234
17234
  if (outputMapping !== void 0) source.outputMapping = outputMapping;
17235
17235
  return source;
17236
17236
  }
17237
- function validateRefreshSourceMetadata(value, path29, issues) {
17237
+ function validateRefreshSourceMetadata(value, path30, issues) {
17238
17238
  if (!isPlainObject2(value)) {
17239
- issues.push({ path: path29, message: `${path29} must be an object` });
17239
+ issues.push({ path: path30, message: `${path30} must be an object` });
17240
17240
  return void 0;
17241
17241
  }
17242
- validateOnlyAllowedKeys(value, REFRESH_SOURCE_METADATA_KEYS, path29, issues);
17243
- const sourceType = validateEnum(value.sourceType, REFRESH_SOURCE_TYPES, `${path29}.sourceType`, issues);
17244
- const toolName = asOptionalString(value.toolName, `${path29}.toolName`, issues, MAX_ID_LENGTH);
17242
+ validateOnlyAllowedKeys(value, REFRESH_SOURCE_METADATA_KEYS, path30, issues);
17243
+ const sourceType = validateEnum(value.sourceType, REFRESH_SOURCE_TYPES, `${path30}.sourceType`, issues);
17244
+ const toolName = asOptionalString(value.toolName, `${path30}.toolName`, issues, MAX_ID_LENGTH);
17245
17245
  let connector;
17246
17246
  if (value.connector !== void 0) {
17247
17247
  if (!isPlainObject2(value.connector)) {
17248
- issues.push({ path: `${path29}.connector`, message: `${path29}.connector must be an object` });
17248
+ issues.push({ path: `${path30}.connector`, message: `${path30}.connector must be an object` });
17249
17249
  } else {
17250
- validateOnlyAllowedKeys(value.connector, CONNECTOR_REFERENCE_KEYS, `${path29}.connector`, issues);
17251
- const connectorId = asString(value.connector.connectorId, `${path29}.connector.connectorId`, issues, MAX_ID_LENGTH);
17252
- const accountLabel = asOptionalString(value.connector.accountLabel, `${path29}.connector.accountLabel`, issues, MAX_SHORT_TEXT_LENGTH);
17253
- const connectorToolName = asString(value.connector.toolName, `${path29}.connector.toolName`, issues, MAX_ID_LENGTH);
17254
- const approvalPolicy = value.connector.approvalPolicy === void 0 ? void 0 : validateEnum(value.connector.approvalPolicy, CONNECTOR_APPROVAL_POLICIES, `${path29}.connector.approvalPolicy`, issues);
17250
+ validateOnlyAllowedKeys(value.connector, CONNECTOR_REFERENCE_KEYS, `${path30}.connector`, issues);
17251
+ const connectorId = asString(value.connector.connectorId, `${path30}.connector.connectorId`, issues, MAX_ID_LENGTH);
17252
+ const accountLabel = asOptionalString(value.connector.accountLabel, `${path30}.connector.accountLabel`, issues, MAX_SHORT_TEXT_LENGTH);
17253
+ const connectorToolName = asString(value.connector.toolName, `${path30}.connector.toolName`, issues, MAX_ID_LENGTH);
17254
+ const approvalPolicy = value.connector.approvalPolicy === void 0 ? void 0 : validateEnum(value.connector.approvalPolicy, CONNECTOR_APPROVAL_POLICIES, `${path30}.connector.approvalPolicy`, issues);
17255
17255
  if (connectorId !== void 0 && connectorToolName !== void 0) {
17256
17256
  connector = { connectorId, toolName: connectorToolName };
17257
17257
  if (accountLabel !== void 0) connector.accountLabel = accountLabel;
@@ -17265,46 +17265,46 @@ function validateRefreshSourceMetadata(value, path29, issues) {
17265
17265
  if (connector !== void 0) source.connector = connector;
17266
17266
  return source;
17267
17267
  }
17268
- function validateRefreshErrorRecord(value, path29, issues) {
17268
+ function validateRefreshErrorRecord(value, path30, issues) {
17269
17269
  if (!isPlainObject2(value)) {
17270
- issues.push({ path: path29, message: `${path29} must be an object` });
17270
+ issues.push({ path: path30, message: `${path30} must be an object` });
17271
17271
  return void 0;
17272
17272
  }
17273
- const code = asOptionalString(value.code, `${path29}.code`, issues, MAX_REFRESH_ERROR_CODE_LENGTH);
17274
- const message = asString(value.message, `${path29}.message`, issues, MAX_REFRESH_ERROR_MESSAGE_LENGTH);
17275
- const errorPath = asOptionalString(value.path, `${path29}.path`, issues, MAX_PATH_LENGTH);
17273
+ const code = asOptionalString(value.code, `${path30}.code`, issues, MAX_REFRESH_ERROR_CODE_LENGTH);
17274
+ const message = asString(value.message, `${path30}.message`, issues, MAX_REFRESH_ERROR_MESSAGE_LENGTH);
17275
+ const errorPath = asOptionalString(value.path, `${path30}.path`, issues, MAX_PATH_LENGTH);
17276
17276
  if (message === void 0) return void 0;
17277
17277
  const record = { message };
17278
17278
  if (code !== void 0) record.code = code;
17279
17279
  if (errorPath !== void 0) record.path = errorPath;
17280
17280
  return record;
17281
17281
  }
17282
- function validateOptionalInteger(value, path29, issues, min, max) {
17282
+ function validateOptionalInteger(value, path30, issues, min, max) {
17283
17283
  if (value === void 0) return void 0;
17284
17284
  if (typeof value !== "number" || !Number.isInteger(value) || value < min || value > max) {
17285
- issues.push({ path: path29, message: `${path29} must be an integer between ${min} and ${max}` });
17285
+ issues.push({ path: path30, message: `${path30} must be an integer between ${min} and ${max}` });
17286
17286
  return void 0;
17287
17287
  }
17288
17288
  return value;
17289
17289
  }
17290
- function validateDocument(value, path29, issues) {
17290
+ function validateDocument(value, path30, issues) {
17291
17291
  if (!isPlainObject2(value)) {
17292
- issues.push({ path: path29, message: `${path29} must be an object` });
17292
+ issues.push({ path: path30, message: `${path30} must be an object` });
17293
17293
  return void 0;
17294
17294
  }
17295
- if (value.format !== "html_template_v1") issues.push({ path: `${path29}.format`, message: `${path29}.format must be html_template_v1` });
17296
- if (value.templatePath !== "template.html") issues.push({ path: `${path29}.templatePath`, message: `${path29}.templatePath must be template.html` });
17297
- if (value.generatedPreviewPath !== "index.html") issues.push({ path: `${path29}.generatedPreviewPath`, message: `${path29}.generatedPreviewPath must be index.html` });
17298
- if (value.dataPath !== "data.json") issues.push({ path: `${path29}.dataPath`, message: `${path29}.dataPath must be data.json` });
17299
- const dataJsonResult = validateBoundedJsonObject(value.dataJson, `${path29}.dataJson`);
17295
+ if (value.format !== "html_template_v1") issues.push({ path: `${path30}.format`, message: `${path30}.format must be html_template_v1` });
17296
+ if (value.templatePath !== "template.html") issues.push({ path: `${path30}.templatePath`, message: `${path30}.templatePath must be template.html` });
17297
+ if (value.generatedPreviewPath !== "index.html") issues.push({ path: `${path30}.generatedPreviewPath`, message: `${path30}.generatedPreviewPath must be index.html` });
17298
+ if (value.dataPath !== "data.json") issues.push({ path: `${path30}.dataPath`, message: `${path30}.dataPath must be data.json` });
17299
+ const dataJsonResult = validateBoundedJsonObject(value.dataJson, `${path30}.dataJson`);
17300
17300
  if (!dataJsonResult.ok) issues.push(...dataJsonResult.issues);
17301
17301
  let dataSchemaJson;
17302
17302
  if (value.dataSchemaJson !== void 0) {
17303
- const schemaResult = validateBoundedJsonObject(value.dataSchemaJson, `${path29}.dataSchemaJson`);
17303
+ const schemaResult = validateBoundedJsonObject(value.dataSchemaJson, `${path30}.dataSchemaJson`);
17304
17304
  if (schemaResult.ok) dataSchemaJson = schemaResult.value;
17305
17305
  else issues.push(...schemaResult.issues);
17306
17306
  }
17307
- const sourceJson = value.sourceJson === void 0 ? void 0 : validateSource(value.sourceJson, `${path29}.sourceJson`, issues);
17307
+ const sourceJson = value.sourceJson === void 0 ? void 0 : validateSource(value.sourceJson, `${path30}.sourceJson`, issues);
17308
17308
  if (value.format !== "html_template_v1" || value.templatePath !== "template.html" || value.generatedPreviewPath !== "index.html" || value.dataPath !== "data.json" || !dataJsonResult.ok) {
17309
17309
  return void 0;
17310
17310
  }
@@ -17319,24 +17319,24 @@ function validateDocument(value, path29, issues) {
17319
17319
  if (sourceJson !== void 0) document.sourceJson = sourceJson;
17320
17320
  return document;
17321
17321
  }
17322
- function validatePersistedLiveArtifact(value, path29 = "liveArtifact") {
17322
+ function validatePersistedLiveArtifact(value, path30 = "liveArtifact") {
17323
17323
  const issues = [];
17324
- if (!isPlainObject2(value)) return fail([{ path: path29, message: `${path29} must be an object` }]);
17325
- if (value.schemaVersion !== 1) issues.push({ path: `${path29}.schemaVersion`, message: `${path29}.schemaVersion must be 1` });
17326
- const id = asString(value.id, `${path29}.id`, issues, MAX_ID_LENGTH);
17327
- const projectId = asString(value.projectId, `${path29}.projectId`, issues, MAX_ID_LENGTH);
17328
- const sessionId = asOptionalString(value.sessionId, `${path29}.sessionId`, issues, MAX_ID_LENGTH);
17329
- const createdByRunId = asOptionalString(value.createdByRunId, `${path29}.createdByRunId`, issues, MAX_ID_LENGTH);
17330
- const title = asString(value.title, `${path29}.title`, issues, MAX_TITLE_LENGTH2);
17331
- const slug = asString(value.slug, `${path29}.slug`, issues, MAX_SLUG_LENGTH);
17332
- const status = validateEnum(value.status, LIVE_ARTIFACT_STATUSES, `${path29}.status`, issues);
17333
- const pinned = asBoolean(value.pinned, `${path29}.pinned`, issues);
17334
- const preview = validatePreview(value.preview, `${path29}.preview`, issues);
17335
- const refreshStatus = validateEnum(value.refreshStatus, LIVE_ARTIFACT_REFRESH_STATUSES, `${path29}.refreshStatus`, issues);
17336
- const createdAt = validateIsoDate(value.createdAt, `${path29}.createdAt`, issues);
17337
- const updatedAt = validateIsoDate(value.updatedAt, `${path29}.updatedAt`, issues);
17338
- const lastRefreshedAt = value.lastRefreshedAt === void 0 ? void 0 : validateIsoDate(value.lastRefreshedAt, `${path29}.lastRefreshedAt`, issues);
17339
- const document = validateDocument(value.document, `${path29}.document`, issues);
17324
+ if (!isPlainObject2(value)) return fail([{ path: path30, message: `${path30} must be an object` }]);
17325
+ if (value.schemaVersion !== 1) issues.push({ path: `${path30}.schemaVersion`, message: `${path30}.schemaVersion must be 1` });
17326
+ const id = asString(value.id, `${path30}.id`, issues, MAX_ID_LENGTH);
17327
+ const projectId = asString(value.projectId, `${path30}.projectId`, issues, MAX_ID_LENGTH);
17328
+ const sessionId = asOptionalString(value.sessionId, `${path30}.sessionId`, issues, MAX_ID_LENGTH);
17329
+ const createdByRunId = asOptionalString(value.createdByRunId, `${path30}.createdByRunId`, issues, MAX_ID_LENGTH);
17330
+ const title = asString(value.title, `${path30}.title`, issues, MAX_TITLE_LENGTH2);
17331
+ const slug = asString(value.slug, `${path30}.slug`, issues, MAX_SLUG_LENGTH);
17332
+ const status = validateEnum(value.status, LIVE_ARTIFACT_STATUSES, `${path30}.status`, issues);
17333
+ const pinned = asBoolean(value.pinned, `${path30}.pinned`, issues);
17334
+ const preview = validatePreview(value.preview, `${path30}.preview`, issues);
17335
+ const refreshStatus = validateEnum(value.refreshStatus, LIVE_ARTIFACT_REFRESH_STATUSES, `${path30}.refreshStatus`, issues);
17336
+ const createdAt = validateIsoDate(value.createdAt, `${path30}.createdAt`, issues);
17337
+ const updatedAt = validateIsoDate(value.updatedAt, `${path30}.updatedAt`, issues);
17338
+ const lastRefreshedAt = value.lastRefreshedAt === void 0 ? void 0 : validateIsoDate(value.lastRefreshedAt, `${path30}.lastRefreshedAt`, issues);
17339
+ const document = validateDocument(value.document, `${path30}.document`, issues);
17340
17340
  if (issues.length > 0 || id === void 0 || projectId === void 0 || title === void 0 || slug === void 0 || status === void 0 || pinned === void 0 || preview === void 0 || refreshStatus === void 0 || createdAt === void 0 || updatedAt === void 0 || document === void 0) {
17341
17341
  return fail(issues);
17342
17342
  }
@@ -17359,28 +17359,28 @@ function validatePersistedLiveArtifact(value, path29 = "liveArtifact") {
17359
17359
  if (lastRefreshedAt !== void 0) liveArtifact.lastRefreshedAt = lastRefreshedAt;
17360
17360
  return ok(liveArtifact);
17361
17361
  }
17362
- function validateLiveArtifactRefreshLogEntry(value, path29 = "refreshLogEntry") {
17362
+ function validateLiveArtifactRefreshLogEntry(value, path30 = "refreshLogEntry") {
17363
17363
  const issues = [];
17364
- if (!isPlainObject2(value)) return fail([{ path: path29, message: `${path29} must be an object` }]);
17365
- if (value.schemaVersion !== 1) issues.push({ path: `${path29}.schemaVersion`, message: `${path29}.schemaVersion must be 1` });
17366
- const projectId = asString(value.projectId, `${path29}.projectId`, issues, MAX_ID_LENGTH);
17367
- const artifactId = asString(value.artifactId, `${path29}.artifactId`, issues, MAX_ID_LENGTH);
17368
- const refreshId = asString(value.refreshId, `${path29}.refreshId`, issues, MAX_ID_LENGTH);
17369
- const sequence = validateOptionalInteger(value.sequence, `${path29}.sequence`, issues, 0, Number.MAX_SAFE_INTEGER);
17370
- const step = asString(value.step, `${path29}.step`, issues, MAX_REFRESH_STEP_LENGTH);
17371
- const status = validateEnum(value.status, REFRESH_STEP_STATUSES, `${path29}.status`, issues);
17372
- const startedAt = validateIsoDate(value.startedAt, `${path29}.startedAt`, issues);
17373
- const finishedAt = value.finishedAt === void 0 ? void 0 : validateIsoDate(value.finishedAt, `${path29}.finishedAt`, issues);
17374
- const durationMs2 = validateOptionalInteger(value.durationMs, `${path29}.durationMs`, issues, 0, Number.MAX_SAFE_INTEGER);
17375
- const source = value.source === void 0 ? void 0 : validateRefreshSourceMetadata(value.source, `${path29}.source`, issues);
17376
- const error = value.error === void 0 ? void 0 : validateRefreshErrorRecord(value.error, `${path29}.error`, issues);
17364
+ if (!isPlainObject2(value)) return fail([{ path: path30, message: `${path30} must be an object` }]);
17365
+ if (value.schemaVersion !== 1) issues.push({ path: `${path30}.schemaVersion`, message: `${path30}.schemaVersion must be 1` });
17366
+ const projectId = asString(value.projectId, `${path30}.projectId`, issues, MAX_ID_LENGTH);
17367
+ const artifactId = asString(value.artifactId, `${path30}.artifactId`, issues, MAX_ID_LENGTH);
17368
+ const refreshId = asString(value.refreshId, `${path30}.refreshId`, issues, MAX_ID_LENGTH);
17369
+ const sequence = validateOptionalInteger(value.sequence, `${path30}.sequence`, issues, 0, Number.MAX_SAFE_INTEGER);
17370
+ const step = asString(value.step, `${path30}.step`, issues, MAX_REFRESH_STEP_LENGTH);
17371
+ const status = validateEnum(value.status, REFRESH_STEP_STATUSES, `${path30}.status`, issues);
17372
+ const startedAt = validateIsoDate(value.startedAt, `${path30}.startedAt`, issues);
17373
+ const finishedAt = value.finishedAt === void 0 ? void 0 : validateIsoDate(value.finishedAt, `${path30}.finishedAt`, issues);
17374
+ const durationMs2 = validateOptionalInteger(value.durationMs, `${path30}.durationMs`, issues, 0, Number.MAX_SAFE_INTEGER);
17375
+ const source = value.source === void 0 ? void 0 : validateRefreshSourceMetadata(value.source, `${path30}.source`, issues);
17376
+ const error = value.error === void 0 ? void 0 : validateRefreshErrorRecord(value.error, `${path30}.error`, issues);
17377
17377
  let metadata;
17378
17378
  if (value.metadata !== void 0) {
17379
- const metadataResult = validateBoundedJsonObject(value.metadata, `${path29}.metadata`);
17379
+ const metadataResult = validateBoundedJsonObject(value.metadata, `${path30}.metadata`);
17380
17380
  if (metadataResult.ok) metadata = metadataResult.value;
17381
17381
  else issues.push(...metadataResult.issues);
17382
17382
  }
17383
- const createdAt = validateIsoDate(value.createdAt, `${path29}.createdAt`, issues);
17383
+ const createdAt = validateIsoDate(value.createdAt, `${path30}.createdAt`, issues);
17384
17384
  if (issues.length > 0 || projectId === void 0 || artifactId === void 0 || refreshId === void 0 || sequence === void 0 || step === void 0 || status === void 0 || startedAt === void 0 || createdAt === void 0) {
17385
17385
  return fail(issues);
17386
17386
  }
@@ -17402,17 +17402,17 @@ function validateLiveArtifactRefreshLogEntry(value, path29 = "refreshLogEntry")
17402
17402
  if (metadata !== void 0) entry.metadata = metadata;
17403
17403
  return ok(entry);
17404
17404
  }
17405
- function validateLiveArtifactCreateInput(value, path29 = "input") {
17405
+ function validateLiveArtifactCreateInput(value, path30 = "input") {
17406
17406
  const issues = [];
17407
- if (!isPlainObject2(value)) return fail([{ path: path29, message: `${path29} must be an object` }]);
17407
+ if (!isPlainObject2(value)) return fail([{ path: path30, message: `${path30} must be an object` }]);
17408
17408
  validateNoDaemonOwnedFields(value, issues);
17409
- const title = asString(value.title, `${path29}.title`, issues, MAX_TITLE_LENGTH2);
17410
- const slug = asOptionalString(value.slug, `${path29}.slug`, issues, MAX_SLUG_LENGTH);
17411
- const sessionId = asOptionalString(value.sessionId, `${path29}.sessionId`, issues, MAX_ID_LENGTH);
17412
- const pinned = asOptionalBoolean(value.pinned, `${path29}.pinned`, issues);
17413
- const status = value.status === void 0 ? void 0 : validateEnum(value.status, LIVE_ARTIFACT_STATUSES, `${path29}.status`, issues);
17414
- const preview = validatePreview(value.preview, `${path29}.preview`, issues);
17415
- const document = validateDocument(value.document, `${path29}.document`, issues);
17409
+ const title = asString(value.title, `${path30}.title`, issues, MAX_TITLE_LENGTH2);
17410
+ const slug = asOptionalString(value.slug, `${path30}.slug`, issues, MAX_SLUG_LENGTH);
17411
+ const sessionId = asOptionalString(value.sessionId, `${path30}.sessionId`, issues, MAX_ID_LENGTH);
17412
+ const pinned = asOptionalBoolean(value.pinned, `${path30}.pinned`, issues);
17413
+ const status = value.status === void 0 ? void 0 : validateEnum(value.status, LIVE_ARTIFACT_STATUSES, `${path30}.status`, issues);
17414
+ const preview = validatePreview(value.preview, `${path30}.preview`, issues);
17415
+ const document = validateDocument(value.document, `${path30}.document`, issues);
17416
17416
  if (issues.length > 0 || title === void 0 || preview === void 0 || document === void 0) return fail(issues);
17417
17417
  const input = { title, preview, document };
17418
17418
  if (slug !== void 0) input.slug = slug;
@@ -17421,16 +17421,16 @@ function validateLiveArtifactCreateInput(value, path29 = "input") {
17421
17421
  if (status !== void 0) input.status = status;
17422
17422
  return ok(input);
17423
17423
  }
17424
- function validateLiveArtifactUpdateInput(value, path29 = "input") {
17424
+ function validateLiveArtifactUpdateInput(value, path30 = "input") {
17425
17425
  const issues = [];
17426
- if (!isPlainObject2(value)) return fail([{ path: path29, message: `${path29} must be an object` }]);
17426
+ if (!isPlainObject2(value)) return fail([{ path: path30, message: `${path30} must be an object` }]);
17427
17427
  validateNoDaemonOwnedFields(value, issues);
17428
- const title = asOptionalString(value.title, `${path29}.title`, issues, MAX_TITLE_LENGTH2);
17429
- const slug = asOptionalString(value.slug, `${path29}.slug`, issues, MAX_SLUG_LENGTH);
17430
- const pinned = asOptionalBoolean(value.pinned, `${path29}.pinned`, issues);
17431
- const status = value.status === void 0 ? void 0 : validateEnum(value.status, LIVE_ARTIFACT_STATUSES, `${path29}.status`, issues);
17432
- const preview = value.preview === void 0 ? void 0 : validatePreview(value.preview, `${path29}.preview`, issues);
17433
- const document = value.document === void 0 ? void 0 : validateDocument(value.document, `${path29}.document`, issues);
17428
+ const title = asOptionalString(value.title, `${path30}.title`, issues, MAX_TITLE_LENGTH2);
17429
+ const slug = asOptionalString(value.slug, `${path30}.slug`, issues, MAX_SLUG_LENGTH);
17430
+ const pinned = asOptionalBoolean(value.pinned, `${path30}.pinned`, issues);
17431
+ const status = value.status === void 0 ? void 0 : validateEnum(value.status, LIVE_ARTIFACT_STATUSES, `${path30}.status`, issues);
17432
+ const preview = value.preview === void 0 ? void 0 : validatePreview(value.preview, `${path30}.preview`, issues);
17433
+ const document = value.document === void 0 ? void 0 : validateDocument(value.document, `${path30}.document`, issues);
17434
17434
  if (issues.length > 0) return fail(issues);
17435
17435
  const input = {};
17436
17436
  if (title !== void 0) input.title = title;
@@ -17464,9 +17464,9 @@ var LiveArtifactRefreshAbortError = class extends Error {
17464
17464
  if (options.step !== void 0) this.step = options.step;
17465
17465
  }
17466
17466
  };
17467
- function validateTimeoutMs(value, path29) {
17467
+ function validateTimeoutMs(value, path30) {
17468
17468
  if (!Number.isSafeInteger(value) || value < 1) {
17469
- throw new RangeError(`${path29} must be a positive safe integer`);
17469
+ throw new RangeError(`${path30} must be a positive safe integer`);
17470
17470
  }
17471
17471
  return value;
17472
17472
  }
@@ -17589,8 +17589,8 @@ function asBoundedRefreshOutput(value) {
17589
17589
  }
17590
17590
  var SAFE_MAPPING_SEGMENT2 = /^[A-Za-z_][A-Za-z0-9_-]*$|^(?:0|[1-9][0-9]*)$/;
17591
17591
  var UNSAFE_MAPPING_SEGMENTS2 = /* @__PURE__ */ new Set(["__proto__", "prototype", "constructor"]);
17592
- function parseMappingPath(path29, field) {
17593
- const normalized = path29.startsWith("$.") ? path29.slice(2) : path29;
17592
+ function parseMappingPath(path30, field) {
17593
+ const normalized = path30.startsWith("$.") ? path30.slice(2) : path30;
17594
17594
  if (normalized.length === 0 || normalized.startsWith(".") || normalized.endsWith(".") || normalized.includes("..")) {
17595
17595
  throw new Error(`${field} must be a dot-separated JSON path`);
17596
17596
  }
@@ -17605,9 +17605,9 @@ function parseMappingPath(path29, field) {
17605
17605
  function isJsonObject(value) {
17606
17606
  return value !== null && typeof value === "object" && !Array.isArray(value);
17607
17607
  }
17608
- function readMappedValue(root, path29) {
17608
+ function readMappedValue(root, path30) {
17609
17609
  let current = root;
17610
- for (const segment of parseMappingPath(path29, "outputMapping.dataPaths.from")) {
17610
+ for (const segment of parseMappingPath(path30, "outputMapping.dataPaths.from")) {
17611
17611
  if (Array.isArray(current)) {
17612
17612
  const index = Number(segment);
17613
17613
  if (!Number.isSafeInteger(index) || index < 0) throw new Error(`outputMapping.dataPaths.from array segment is invalid: ${segment}`);
@@ -17624,8 +17624,8 @@ function readMappedValue(root, path29) {
17624
17624
  function makeContainer(nextSegment) {
17625
17625
  return /^(?:0|[1-9][0-9]*)$/.test(nextSegment) ? [] : {};
17626
17626
  }
17627
- function writeMappedValue(root, path29, value) {
17628
- const segments = parseMappingPath(path29, "outputMapping.dataPaths.to");
17627
+ function writeMappedValue(root, path30, value) {
17628
+ const segments = parseMappingPath(path30, "outputMapping.dataPaths.to");
17629
17629
  let current = root;
17630
17630
  for (let index = 0; index < segments.length; index += 1) {
17631
17631
  const segment = segments[index];
@@ -18215,8 +18215,8 @@ function toSummary(artifact) {
18215
18215
  hasDocument: _document !== void 0
18216
18216
  };
18217
18217
  }
18218
- function validationError(path29, message) {
18219
- return new LiveArtifactStoreValidationError(message, [{ path: path29, message }]);
18218
+ function validationError(path30, message) {
18219
+ return new LiveArtifactStoreValidationError(message, [{ path: path30, message }]);
18220
18220
  }
18221
18221
  function toIsoDate(value) {
18222
18222
  return value instanceof Date ? value.toISOString() : value;
@@ -20447,8 +20447,8 @@ var ComposioConnectorProvider = class {
20447
20447
  }
20448
20448
  };
20449
20449
  }
20450
- async requestJson(path29, input) {
20451
- const response = await this.request(path29, input);
20450
+ async requestJson(path30, input) {
20451
+ const response = await this.request(path30, input);
20452
20452
  if (!response.ok) {
20453
20453
  const message = await getComposioErrorMessage(response);
20454
20454
  throw new ConnectorServiceError("CONNECTOR_EXECUTION_FAILED", message ?? `Composio request failed with HTTP ${response.status}`, response.status === 401 ? 401 : 502, { httpStatus: response.status });
@@ -20459,14 +20459,14 @@ var ComposioConnectorProvider = class {
20459
20459
  }
20460
20460
  return value;
20461
20461
  }
20462
- async request(path29, input) {
20462
+ async request(path30, input) {
20463
20463
  const apiKey = this.getApiKey();
20464
20464
  if (!apiKey) {
20465
20465
  throw new ConnectorServiceError("CONNECTOR_EXECUTION_FAILED", "Composio provider is not configured", 503, { setting: "apiKey" });
20466
20466
  }
20467
20467
  const timeout = AbortSignal.timeout(DEFAULT_COMPOSIO_TIMEOUT_MS);
20468
20468
  const signal = input.signal ? AbortSignal.any([input.signal, timeout]) : timeout;
20469
- return fetch(`${this.getBaseUrl().replace(/\/+$/, "")}${path29}`, {
20469
+ return fetch(`${this.getBaseUrl().replace(/\/+$/, "")}${path30}`, {
20470
20470
  method: input.method,
20471
20471
  headers: {
20472
20472
  accept: "application/json",
@@ -20779,45 +20779,45 @@ function runtimeSafetyForTool(tool) {
20779
20779
  if (classified.sideEffect !== "read" || classified.approval !== "auto") return classified;
20780
20780
  return tool.safety;
20781
20781
  }
20782
- function assertJsonSchemaMatches(value, schema, path29 = "input") {
20782
+ function assertJsonSchemaMatches(value, schema, path30 = "input") {
20783
20783
  if (schema === void 0) return;
20784
20784
  const type = schema.type;
20785
20785
  if (typeof type === "string") {
20786
20786
  const actualType = Array.isArray(value) ? "array" : value === null ? "null" : typeof value;
20787
20787
  if (type === "number") {
20788
- if (typeof value !== "number") throw new Error(`${path29} must be a number`);
20788
+ if (typeof value !== "number") throw new Error(`${path30} must be a number`);
20789
20789
  } else if (type === "integer") {
20790
- if (typeof value !== "number" || !Number.isInteger(value)) throw new Error(`${path29} must be an integer`);
20790
+ if (typeof value !== "number" || !Number.isInteger(value)) throw new Error(`${path30} must be an integer`);
20791
20791
  } else if (type !== actualType) {
20792
- throw new Error(`${path29} must be a ${type}`);
20792
+ throw new Error(`${path30} must be a ${type}`);
20793
20793
  }
20794
20794
  }
20795
20795
  if (type === "object") {
20796
- if (value === null || typeof value !== "object" || Array.isArray(value)) throw new Error(`${path29} must be an object`);
20796
+ if (value === null || typeof value !== "object" || Array.isArray(value)) throw new Error(`${path30} must be an object`);
20797
20797
  const objectValue = value;
20798
20798
  const required = Array.isArray(schema.required) ? schema.required.filter((item) => typeof item === "string") : [];
20799
20799
  for (const key of required) {
20800
- if (objectValue[key] === void 0) throw new Error(`${path29}.${key} is required by connector input schema`);
20800
+ if (objectValue[key] === void 0) throw new Error(`${path30}.${key} is required by connector input schema`);
20801
20801
  }
20802
20802
  const properties = schema.properties;
20803
20803
  const propertySchemas = properties !== null && typeof properties === "object" && !Array.isArray(properties) ? properties : {};
20804
20804
  if (schema.additionalProperties === false) {
20805
20805
  for (const key of Object.keys(objectValue)) {
20806
- if (propertySchemas[key] === void 0) throw new Error(`${path29}.${key} is not allowed by connector input schema`);
20806
+ if (propertySchemas[key] === void 0) throw new Error(`${path30}.${key} is not allowed by connector input schema`);
20807
20807
  }
20808
20808
  }
20809
20809
  for (const [key, childSchema] of Object.entries(propertySchemas)) {
20810
20810
  if (objectValue[key] !== void 0 && childSchema !== null && typeof childSchema === "object" && !Array.isArray(childSchema)) {
20811
- assertJsonSchemaMatches(objectValue[key], childSchema, `${path29}.${key}`);
20811
+ assertJsonSchemaMatches(objectValue[key], childSchema, `${path30}.${key}`);
20812
20812
  }
20813
20813
  }
20814
20814
  }
20815
20815
  if (type === "string" && typeof value === "string") {
20816
- if (typeof schema.maxLength === "number" && value.length > schema.maxLength) throw new Error(`${path29} exceeds connector input schema maxLength`);
20816
+ if (typeof schema.maxLength === "number" && value.length > schema.maxLength) throw new Error(`${path30} exceeds connector input schema maxLength`);
20817
20817
  }
20818
20818
  if ((type === "number" || type === "integer") && typeof value === "number") {
20819
- if (typeof schema.minimum === "number" && value < schema.minimum) throw new Error(`${path29} is below connector input schema minimum`);
20820
- if (typeof schema.maximum === "number" && value > schema.maximum) throw new Error(`${path29} exceeds connector input schema maximum`);
20819
+ if (typeof schema.minimum === "number" && value < schema.minimum) throw new Error(`${path30} is below connector input schema minimum`);
20820
+ if (typeof schema.maximum === "number" && value > schema.maximum) throw new Error(`${path30} exceeds connector input schema maximum`);
20821
20821
  }
20822
20822
  }
20823
20823
  function defaultConnectedAccountLabel(definition) {
@@ -22717,24 +22717,52 @@ function safeVercelProjectName(raw) {
22717
22717
  return String(raw).toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/^-+|-+$/g, "").slice(0, 80) || `od-${randomUUID4().slice(0, 8)}`;
22718
22718
  }
22719
22719
 
22720
+ // apps/daemon/src/layout.ts
22721
+ import fs7 from "node:fs";
22722
+ import path28 from "node:path";
22723
+ var REPO_DATA_DIR = ".od";
22724
+ var PACKAGE_DATA_DIR = ".tfdesign";
22725
+ function detectLayout(moduleDir) {
22726
+ const base = path28.basename(moduleDir);
22727
+ const daemonDir = base === "dist" || base === "src" ? path28.dirname(moduleDir) : moduleDir;
22728
+ const candidate = path28.resolve(daemonDir, "../..");
22729
+ const repo = fs7.existsSync(path28.join(candidate, "pnpm-workspace.yaml")) && fs7.existsSync(path28.join(candidate, "apps", "daemon"));
22730
+ return repo ? { root: candidate, repo: true } : { root: daemonDir, repo: false };
22731
+ }
22732
+ function defaultDataRoot(moduleDir, cwd = process.cwd()) {
22733
+ const layout = detectLayout(moduleDir);
22734
+ return path28.join(
22735
+ layout.repo ? layout.root : cwd,
22736
+ layout.repo ? REPO_DATA_DIR : PACKAGE_DATA_DIR
22737
+ );
22738
+ }
22739
+ function expandDataRoot(raw, cwd = process.cwd()) {
22740
+ if (raw.startsWith("~/"))
22741
+ return path28.join(process.env.HOME ?? "~", raw.slice(2));
22742
+ return path28.isAbsolute(raw) ? raw : path28.resolve(cwd, raw);
22743
+ }
22744
+ function resolveDataRoot(moduleDir, cwd = process.cwd()) {
22745
+ const raw = process.env.TFDESIGN_DATA_DIR || process.env.OD_DATA_DIR;
22746
+ return raw ? expandDataRoot(raw, cwd) : defaultDataRoot(moduleDir, cwd);
22747
+ }
22748
+
22720
22749
  // apps/daemon/src/server.ts
22721
22750
  var __filename = fileURLToPath2(import.meta.url);
22722
- var __dirname = path28.dirname(__filename);
22751
+ var __dirname = path29.dirname(__filename);
22723
22752
  var require2 = createRequire(import.meta.url);
22724
22753
  function resolveProjectRoot(moduleDir) {
22725
- const base = path28.basename(moduleDir);
22726
- const daemonDir = base === "dist" || base === "src" ? path28.dirname(moduleDir) : moduleDir;
22727
- return path28.resolve(daemonDir, "../..");
22754
+ return detectLayout(moduleDir).root;
22728
22755
  }
22729
22756
  function resolveDaemonCliPath() {
22730
22757
  try {
22731
22758
  const packageJsonPath = require2.resolve("@open-design/daemon/package.json");
22732
- return path28.join(path28.dirname(packageJsonPath), "dist", "cli.js");
22759
+ return path29.join(path29.dirname(packageJsonPath), "dist", "cli.js");
22733
22760
  } catch {
22734
- return path28.join(__dirname, "cli.js");
22761
+ return path29.join(__dirname, "cli.js");
22735
22762
  }
22736
22763
  }
22737
- var PROJECT_ROOT = resolveProjectRoot(__dirname);
22764
+ var LAYOUT = detectLayout(__dirname);
22765
+ var PROJECT_ROOT = LAYOUT.root;
22738
22766
  var RESOURCE_ROOT_ENV = "OD_RESOURCE_ROOT";
22739
22767
  function buildDeckWorkflowReminder(message, metadata) {
22740
22768
  if (!message || typeof message !== "string") return "";
@@ -22773,9 +22801,9 @@ function composeLiveInstructionPrompt({
22773
22801
  }
22774
22802
  function resolveCodexGeneratedImagesDir(agentId, metadata, env = process.env, homeDir = os4.homedir()) {
22775
22803
  if (!shouldRenderCodexImagegenOverride(agentId, metadata)) return null;
22776
- const rawCodexHome = typeof env?.CODEX_HOME === "string" && env.CODEX_HOME.trim().length > 0 ? env.CODEX_HOME.trim() : path28.join(homeDir, ".codex");
22777
- const codexHome = rawCodexHome.startsWith("~/") ? path28.join(homeDir, rawCodexHome.slice(2)) : rawCodexHome;
22778
- return path28.resolve(codexHome, "generated_images");
22804
+ const rawCodexHome = typeof env?.CODEX_HOME === "string" && env.CODEX_HOME.trim().length > 0 ? env.CODEX_HOME.trim() : path29.join(homeDir, ".codex");
22805
+ const codexHome = rawCodexHome.startsWith("~/") ? path29.join(homeDir, rawCodexHome.slice(2)) : rawCodexHome;
22806
+ return path29.resolve(codexHome, "generated_images");
22779
22807
  }
22780
22808
  function isMissingPathError(err) {
22781
22809
  return err && typeof err === "object" && "code" in err && err.code === "ENOENT";
@@ -22787,7 +22815,7 @@ function collectProtectedDirRoots(protectedDirs, {
22787
22815
  const roots = [];
22788
22816
  for (const raw of Array.isArray(protectedDirs) ? protectedDirs : []) {
22789
22817
  if (typeof raw !== "string" || raw.trim().length === 0) continue;
22790
- const resolved = path28.resolve(raw);
22818
+ const resolved = path29.resolve(raw);
22791
22819
  roots.push(resolved);
22792
22820
  try {
22793
22821
  const canonical = realpathSync2(resolved);
@@ -22806,16 +22834,16 @@ function findContainingProtectedRoot(candidate, protectedRoots) {
22806
22834
  }
22807
22835
  function validateCodexGeneratedImagesDir(codexGeneratedImagesDir, {
22808
22836
  protectedDirs = [],
22809
- mkdirSync: mkdirSync2 = fs7.mkdirSync,
22810
- lstatSync = fs7.lstatSync,
22811
- statSync: statSync3 = fs7.statSync,
22812
- realpathSync: realpathSync2 = fs7.realpathSync.native,
22837
+ mkdirSync: mkdirSync2 = fs8.mkdirSync,
22838
+ lstatSync = fs8.lstatSync,
22839
+ statSync: statSync3 = fs8.statSync,
22840
+ realpathSync: realpathSync2 = fs8.realpathSync.native,
22813
22841
  warn = console.warn
22814
22842
  } = {}) {
22815
22843
  if (typeof codexGeneratedImagesDir !== "string" || codexGeneratedImagesDir.trim().length === 0) {
22816
22844
  return null;
22817
22845
  }
22818
- const resolved = path28.resolve(codexGeneratedImagesDir);
22846
+ const resolved = path29.resolve(codexGeneratedImagesDir);
22819
22847
  const protectedRoots = collectProtectedDirRoots(protectedDirs, {
22820
22848
  realpathSync: realpathSync2,
22821
22849
  statSync: statSync3
@@ -22841,7 +22869,7 @@ function validateCodexGeneratedImagesDir(codexGeneratedImagesDir, {
22841
22869
  warnSkipped(`${resolved} is not a directory`);
22842
22870
  return null;
22843
22871
  }
22844
- const parent = path28.dirname(resolved);
22872
+ const parent = path29.dirname(resolved);
22845
22873
  const protectedParentRoot = findContainingProtectedRoot(
22846
22874
  parent,
22847
22875
  protectedRoots
@@ -22852,9 +22880,9 @@ function validateCodexGeneratedImagesDir(codexGeneratedImagesDir, {
22852
22880
  }
22853
22881
  mkdirSync2(parent, { recursive: true });
22854
22882
  const canonicalParent = realpathSync2(parent);
22855
- const canonicalCandidate = path28.join(
22883
+ const canonicalCandidate = path29.join(
22856
22884
  canonicalParent,
22857
- path28.basename(resolved)
22885
+ path29.basename(resolved)
22858
22886
  );
22859
22887
  const protectedCanonicalParentRoot = findContainingProtectedRoot(
22860
22888
  canonicalCandidate,
@@ -22898,13 +22926,10 @@ function resolveChatExtraAllowedDirs({
22898
22926
  brandGuidelinesDir,
22899
22927
  linkedDirs = [],
22900
22928
  codexGeneratedImagesDir,
22901
- existsSync: existsSync3 = fs7.existsSync
22929
+ existsSync: existsSync3 = fs8.existsSync
22902
22930
  }) {
22903
22931
  const isCodex = typeof agentId === "string" && agentId.trim().toLowerCase() === "codex";
22904
- const candidates = isCodex ? [codexGeneratedImagesDir] : [
22905
- brandGuidelinesDir,
22906
- ...Array.isArray(linkedDirs) ? linkedDirs : []
22907
- ];
22932
+ const candidates = isCodex ? [codexGeneratedImagesDir] : [brandGuidelinesDir, ...Array.isArray(linkedDirs) ? linkedDirs : []];
22908
22933
  return Array.from(
22909
22934
  new Set(
22910
22935
  candidates.filter(
@@ -23032,27 +23057,27 @@ function formatAttachmentPosition(position) {
23032
23057
  return `x=${position.x}, y=${position.y}, width=${position.width}, height=${position.height}`;
23033
23058
  }
23034
23059
  function isPathWithin(base, target) {
23035
- const relativePath = path28.relative(path28.resolve(base), path28.resolve(target));
23036
- return relativePath === "" || relativePath.length > 0 && !relativePath.startsWith("..") && !path28.isAbsolute(relativePath);
23060
+ const relativePath = path29.relative(path29.resolve(base), path29.resolve(target));
23061
+ return relativePath === "" || relativePath.length > 0 && !relativePath.startsWith("..") && !path29.isAbsolute(relativePath);
23037
23062
  }
23038
23063
  function resolveProcessResourcesPath() {
23039
23064
  if (typeof process.resourcesPath === "string" && process.resourcesPath.length > 0) {
23040
23065
  return process.resourcesPath;
23041
23066
  }
23042
- const resourcesMarker = `${path28.sep}Contents${path28.sep}Resources${path28.sep}`;
23067
+ const resourcesMarker = `${path29.sep}Contents${path29.sep}Resources${path29.sep}`;
23043
23068
  const markerIndex = process.execPath.indexOf(resourcesMarker);
23044
23069
  if (markerIndex !== -1) {
23045
23070
  return process.execPath.slice(0, markerIndex + resourcesMarker.length - 1);
23046
23071
  }
23047
23072
  const normalizedExecPath = process.execPath.toLowerCase();
23048
- const windowsResourceBinMarker = `${path28.sep}resources${path28.sep}open-design${path28.sep}bin${path28.sep}`.toLowerCase();
23073
+ const windowsResourceBinMarker = `${path29.sep}resources${path29.sep}open-design${path29.sep}bin${path29.sep}`.toLowerCase();
23049
23074
  const windowsMarkerIndex = normalizedExecPath.indexOf(
23050
23075
  windowsResourceBinMarker
23051
23076
  );
23052
23077
  if (windowsMarkerIndex !== -1) {
23053
23078
  return process.execPath.slice(
23054
23079
  0,
23055
- windowsMarkerIndex + `${path28.sep}resources`.length
23080
+ windowsMarkerIndex + `${path29.sep}resources`.length
23056
23081
  );
23057
23082
  }
23058
23083
  return null;
@@ -23062,8 +23087,8 @@ function resolveDaemonResourceRoot({
23062
23087
  safeBases = [PROJECT_ROOT, resolveProcessResourcesPath()]
23063
23088
  } = {}) {
23064
23089
  if (!configured || configured.length === 0) return null;
23065
- const resolved = path28.resolve(configured);
23066
- const normalizedSafeBases = safeBases.filter((base) => typeof base === "string" && base.length > 0).map((base) => path28.resolve(base));
23090
+ const resolved = path29.resolve(configured);
23091
+ const normalizedSafeBases = safeBases.filter((base) => typeof base === "string" && base.length > 0).map((base) => path29.resolve(base));
23067
23092
  if (!normalizedSafeBases.some((base) => isPathWithin(base, resolved))) {
23068
23093
  throw new Error(
23069
23094
  `${RESOURCE_ROOT_ENV} must be under the workspace root or app resources path`
@@ -23072,78 +23097,84 @@ function resolveDaemonResourceRoot({
23072
23097
  return resolved;
23073
23098
  }
23074
23099
  function resolveDaemonResourceDir(resourceRoot, segment, fallback) {
23075
- return resourceRoot ? path28.join(resourceRoot, segment) : fallback;
23100
+ return resourceRoot ? path29.join(resourceRoot, segment) : fallback;
23076
23101
  }
23077
23102
  var DAEMON_RESOURCE_ROOT = resolveDaemonResourceRoot();
23078
- var STATIC_DIR = path28.join(PROJECT_ROOT, "apps", "web", "out");
23103
+ var STATIC_DIR = path29.join(PROJECT_ROOT, "apps", "web", "out");
23079
23104
  var OD_BIN = resolveDaemonCliPath();
23080
23105
  var OD_NODE_BIN = process.execPath;
23081
23106
  var BRAND_GUIDELINES_DIR = resolveDaemonResourceDir(
23082
23107
  DAEMON_RESOURCE_ROOT,
23083
23108
  "brand-guidelines",
23084
- path28.join(PROJECT_ROOT, "brand-guidelines")
23109
+ path29.join(PROJECT_ROOT, "brand-guidelines")
23085
23110
  );
23086
23111
  var CRAFT_DIR = resolveDaemonResourceDir(
23087
23112
  DAEMON_RESOURCE_ROOT,
23088
23113
  "craft",
23089
- path28.join(PROJECT_ROOT, "craft")
23114
+ path29.join(PROJECT_ROOT, "craft")
23090
23115
  );
23091
23116
  var FRAMES_DIR = resolveDaemonResourceDir(
23092
23117
  DAEMON_RESOURCE_ROOT,
23093
23118
  "frames",
23094
- path28.join(PROJECT_ROOT, "assets", "frames")
23119
+ path29.join(PROJECT_ROOT, "assets", "frames")
23095
23120
  );
23096
23121
  var BUNDLED_PETS_DIR = resolveDaemonResourceDir(
23097
23122
  DAEMON_RESOURCE_ROOT,
23098
23123
  "community-pets",
23099
- path28.join(PROJECT_ROOT, "assets", "community-pets")
23124
+ path29.join(PROJECT_ROOT, "assets", "community-pets")
23100
23125
  );
23101
23126
  var PROMPT_TEMPLATES_DIR = resolveDaemonResourceDir(
23102
23127
  DAEMON_RESOURCE_ROOT,
23103
23128
  "prompt-templates",
23104
- path28.join(PROJECT_ROOT, "prompt-templates")
23129
+ path29.join(PROJECT_ROOT, "prompt-templates")
23105
23130
  );
23106
23131
  var PROMPT_TEMPLATE_ASSETS_DIR = resolveDaemonResourceDir(
23107
23132
  DAEMON_RESOURCE_ROOT,
23108
- path28.join("assets", "prompt-templates"),
23109
- path28.join(PROJECT_ROOT, "assets", "prompt-templates")
23133
+ path29.join("assets", "prompt-templates"),
23134
+ path29.join(PROJECT_ROOT, "assets", "prompt-templates")
23110
23135
  );
23111
23136
  function resolveDataDir(raw, projectRoot) {
23112
- if (!raw) return path28.join(projectRoot, ".od");
23113
- const expanded = raw.startsWith("~/") ? path28.join(os4.homedir(), raw.slice(2)) : raw;
23114
- const resolved = path28.isAbsolute(expanded) ? expanded : path28.resolve(projectRoot, expanded);
23137
+ if (!raw) return path29.join(projectRoot, ".od");
23138
+ const expanded = raw.startsWith("~/") ? path29.join(os4.homedir(), raw.slice(2)) : raw;
23139
+ const resolved = path29.isAbsolute(expanded) ? expanded : path29.resolve(projectRoot, expanded);
23115
23140
  try {
23116
- fs7.mkdirSync(resolved, { recursive: true });
23117
- fs7.accessSync(resolved, fs7.constants.W_OK);
23141
+ fs8.mkdirSync(resolved, { recursive: true });
23142
+ fs8.accessSync(resolved, fs8.constants.W_OK);
23118
23143
  } catch (err) {
23119
23144
  const e = err;
23120
23145
  throw new Error(`OD_DATA_DIR "${resolved}" is not writable: ${e.message}`);
23121
23146
  }
23122
23147
  return resolved;
23123
23148
  }
23124
- var RUNTIME_DATA_DIR = resolveDataDir(process.env.OD_DATA_DIR, PROJECT_ROOT);
23125
- var ARTIFACTS_DIR = path28.join(RUNTIME_DATA_DIR, "artifacts");
23126
- var DEFAULT_PROJECTS_DIR = path28.join(RUNTIME_DATA_DIR, "projects");
23127
- var USER_PROMPT_TEMPLATES_DIR = path28.join(
23149
+ var RUNTIME_DATA_DIR = resolveDataDir(
23150
+ process.env.TFDESIGN_DATA_DIR || process.env.OD_DATA_DIR || defaultDataRoot(__dirname),
23151
+ PROJECT_ROOT
23152
+ );
23153
+ function dataRoot() {
23154
+ return RUNTIME_DATA_DIR;
23155
+ }
23156
+ var ARTIFACTS_DIR = path29.join(RUNTIME_DATA_DIR, "artifacts");
23157
+ var DEFAULT_PROJECTS_DIR = path29.join(RUNTIME_DATA_DIR, "projects");
23158
+ var USER_PROMPT_TEMPLATES_DIR = path29.join(
23128
23159
  RUNTIME_DATA_DIR,
23129
23160
  "prompt-templates"
23130
23161
  );
23131
- var USER_BRAND_GUIDELINES_DIR = path28.join(
23162
+ var USER_BRAND_GUIDELINES_DIR = path29.join(
23132
23163
  RUNTIME_DATA_DIR,
23133
23164
  "brand-guidelines"
23134
23165
  );
23135
- var BRAND_ASSETS_DIR = path28.join(RUNTIME_DATA_DIR, "brand-assets");
23136
- fs7.mkdirSync(BRAND_ASSETS_DIR, { recursive: true });
23166
+ var BRAND_ASSETS_DIR = path29.join(RUNTIME_DATA_DIR, "brand-assets");
23167
+ fs8.mkdirSync(BRAND_ASSETS_DIR, { recursive: true });
23137
23168
  function resolveProjectsDir(dataDir) {
23138
- const overrideFile = path28.join(dataDir, "projects-dir.json");
23169
+ const overrideFile = path29.join(dataDir, "projects-dir.json");
23139
23170
  try {
23140
- const raw = fs7.readFileSync(overrideFile, "utf8");
23171
+ const raw = fs8.readFileSync(overrideFile, "utf8");
23141
23172
  const parsed = JSON.parse(raw);
23142
23173
  if (parsed && typeof parsed.projectsDir === "string" && parsed.projectsDir.trim()) {
23143
- const expanded = parsed.projectsDir.startsWith("~/") ? path28.join(os4.homedir(), parsed.projectsDir.slice(2)) : parsed.projectsDir;
23144
- const resolved = path28.isAbsolute(expanded) ? expanded : path28.resolve(dataDir, expanded);
23145
- fs7.mkdirSync(resolved, { recursive: true });
23146
- fs7.accessSync(resolved, fs7.constants.W_OK);
23174
+ const expanded = parsed.projectsDir.startsWith("~/") ? path29.join(os4.homedir(), parsed.projectsDir.slice(2)) : parsed.projectsDir;
23175
+ const resolved = path29.isAbsolute(expanded) ? expanded : path29.resolve(dataDir, expanded);
23176
+ fs8.mkdirSync(resolved, { recursive: true });
23177
+ fs8.accessSync(resolved, fs8.constants.W_OK);
23147
23178
  return resolved;
23148
23179
  }
23149
23180
  } catch {
@@ -23151,11 +23182,14 @@ function resolveProjectsDir(dataDir) {
23151
23182
  return DEFAULT_PROJECTS_DIR;
23152
23183
  }
23153
23184
  var PROJECTS_DIR = resolveProjectsDir(RUNTIME_DATA_DIR);
23154
- fs7.mkdirSync(PROJECTS_DIR, { recursive: true });
23155
- var PROJECTS_DIR_OVERRIDE_FILE = path28.join(RUNTIME_DATA_DIR, "projects-dir.json");
23156
- if (!fs7.existsSync(PROJECTS_DIR_OVERRIDE_FILE) && process.env.OD_FORCE_STORAGE_UNCONFIGURED !== "1") {
23185
+ fs8.mkdirSync(PROJECTS_DIR, { recursive: true });
23186
+ var PROJECTS_DIR_OVERRIDE_FILE = path29.join(
23187
+ RUNTIME_DATA_DIR,
23188
+ "projects-dir.json"
23189
+ );
23190
+ if (!fs8.existsSync(PROJECTS_DIR_OVERRIDE_FILE) && process.env.OD_FORCE_STORAGE_UNCONFIGURED !== "1") {
23157
23191
  try {
23158
- fs7.writeFileSync(
23192
+ fs8.writeFileSync(
23159
23193
  PROJECTS_DIR_OVERRIDE_FILE,
23160
23194
  JSON.stringify({ projectsDir: DEFAULT_PROJECTS_DIR }, null, 2),
23161
23195
  "utf8"
@@ -23518,9 +23552,9 @@ function openNativeFolderDialog() {
23518
23552
  function createSseErrorPayload(code, message, init = {}) {
23519
23553
  return { message, error: createCompatApiError(code, message, init) };
23520
23554
  }
23521
- var UPLOAD_DIR = path28.join(os4.tmpdir(), "od-uploads");
23522
- fs7.mkdirSync(UPLOAD_DIR, { recursive: true });
23523
- fs7.mkdirSync(ARTIFACTS_DIR, { recursive: true });
23555
+ var UPLOAD_DIR = path29.join(os4.tmpdir(), "od-uploads");
23556
+ fs8.mkdirSync(UPLOAD_DIR, { recursive: true });
23557
+ fs8.mkdirSync(ARTIFACTS_DIR, { recursive: true });
23524
23558
  var upload = multer({
23525
23559
  storage: multer.diskStorage({
23526
23560
  destination: UPLOAD_DIR,
@@ -23555,7 +23589,10 @@ var brandAssetUpload = multer({
23555
23589
  filename: (_req, file, cb) => {
23556
23590
  file.originalname = decodeMultipartFilename(file.originalname);
23557
23591
  const safe = sanitizeName(file.originalname);
23558
- cb(null, `${Date.now()}-${Math.random().toString(36).slice(2, 8)}-${safe}`);
23592
+ cb(
23593
+ null,
23594
+ `${Date.now()}-${Math.random().toString(36).slice(2, 8)}-${safe}`
23595
+ );
23559
23596
  }
23560
23597
  }),
23561
23598
  limits: { fileSize: 20 * 1024 * 1024 }
@@ -23792,12 +23829,16 @@ async function startServer({
23792
23829
  } catch (error) {
23793
23830
  console.warn("[od] Failed to reconcile projects from disk:", error);
23794
23831
  }
23795
- if (fs7.existsSync(STATIC_DIR)) {
23832
+ if (fs8.existsSync(STATIC_DIR)) {
23796
23833
  app.use(express.static(STATIC_DIR));
23797
23834
  }
23798
23835
  app.get("/api/health", async (_req, res) => {
23799
23836
  const versionInfo = await readCurrentAppVersionInfo();
23800
- res.json({ ok: true, version: versionInfo.version });
23837
+ res.json({
23838
+ ok: true,
23839
+ version: versionInfo.version,
23840
+ dataRoot: RUNTIME_DATA_DIR
23841
+ });
23801
23842
  });
23802
23843
  app.get("/api/version", async (_req, res) => {
23803
23844
  const version = await readCurrentAppVersionInfo();
@@ -23894,8 +23935,8 @@ async function startServer({
23894
23935
  } catch (err) {
23895
23936
  return sendApiError(res, 500, "CLI_RESOLVE_FAILED", String(err));
23896
23937
  }
23897
- const cliExists = fs7.existsSync(cliPath);
23898
- const nodeExists = fs7.existsSync(process.execPath);
23938
+ const cliExists = fs8.existsSync(cliPath);
23939
+ const nodeExists = fs8.existsSync(process.execPath);
23899
23940
  const hints = [];
23900
23941
  if (!cliExists) {
23901
23942
  hints.push(
@@ -24173,7 +24214,7 @@ async function startServer({
24173
24214
  return res.status(400).json({ error: "zip file required" });
24174
24215
  const originalName = req.file.originalname || "Claude Design export.zip";
24175
24216
  if (!/\.zip$/i.test(originalName)) {
24176
- fs7.promises.unlink(req.file.path).catch(() => {
24217
+ fs8.promises.unlink(req.file.path).catch(() => {
24177
24218
  });
24178
24219
  return res.status(400).json({ error: "expected a .zip file" });
24179
24220
  }
@@ -24184,7 +24225,7 @@ async function startServer({
24184
24225
  req.file.path,
24185
24226
  projectDir(PROJECTS_DIR, id)
24186
24227
  );
24187
- fs7.promises.unlink(req.file.path).catch(() => {
24228
+ fs8.promises.unlink(req.file.path).catch(() => {
24188
24229
  });
24189
24230
  const project = insertProject(db, {
24190
24231
  id,
@@ -24216,7 +24257,7 @@ async function startServer({
24216
24257
  files: imported.files
24217
24258
  });
24218
24259
  } catch (err) {
24219
- if (req.file?.path) fs7.promises.unlink(req.file.path).catch(() => {
24260
+ if (req.file?.path) fs8.promises.unlink(req.file.path).catch(() => {
24220
24261
  });
24221
24262
  res.status(400).json({ error: String(err) });
24222
24263
  }
@@ -24225,7 +24266,7 @@ async function startServer({
24225
24266
  app.post("/api/import/folder", async (req, res) => {
24226
24267
  try {
24227
24268
  const folderPath = typeof req.body?.folderPath === "string" ? req.body.folderPath : "";
24228
- if (!folderPath || !path28.isAbsolute(path28.normalize(folderPath))) {
24269
+ if (!folderPath || !path29.isAbsolute(path29.normalize(folderPath))) {
24229
24270
  return res.status(400).json({ error: "an absolute folderPath is required" });
24230
24271
  }
24231
24272
  const validated = validateProjectBaseDir(folderPath, {
@@ -24236,7 +24277,7 @@ async function startServer({
24236
24277
  return res.status(400).json({ error: validated.error });
24237
24278
  }
24238
24279
  const realSource = validated.baseDir;
24239
- if (PROJECTS_DIR && realSource.startsWith(PROJECTS_DIR + path28.sep)) {
24280
+ if (PROJECTS_DIR && realSource.startsWith(PROJECTS_DIR + path29.sep)) {
24240
24281
  reconcileProjectsFromDisk(db, PROJECTS_DIR);
24241
24282
  }
24242
24283
  const existing = findProjectByDir(db, realSource, PROJECTS_DIR);
@@ -24272,7 +24313,7 @@ async function startServer({
24272
24313
  });
24273
24314
  const id = randomId();
24274
24315
  const now = Date.now();
24275
- const baseName = path28.basename(realSource) || "Imported folder";
24316
+ const baseName = path29.basename(realSource) || "Imported folder";
24276
24317
  const project = insertProject(db, {
24277
24318
  id,
24278
24319
  name: baseName,
@@ -24731,7 +24772,10 @@ async function startServer({
24731
24772
  });
24732
24773
  app.get("/api/brand-guidelines", async (_req, res) => {
24733
24774
  try {
24734
- const systems = await listBrandGuidelines(BRAND_GUIDELINES_DIR, USER_BRAND_GUIDELINES_DIR);
24775
+ const systems = await listBrandGuidelines(
24776
+ BRAND_GUIDELINES_DIR,
24777
+ USER_BRAND_GUIDELINES_DIR
24778
+ );
24735
24779
  res.json({
24736
24780
  brandGuidelines: systems.map(({ body, ...rest }) => rest)
24737
24781
  });
@@ -24741,7 +24785,11 @@ async function startServer({
24741
24785
  });
24742
24786
  app.get("/api/brand-guidelines/:id", async (req, res) => {
24743
24787
  try {
24744
- const body = await readBrandGuideline(BRAND_GUIDELINES_DIR, USER_BRAND_GUIDELINES_DIR, req.params.id);
24788
+ const body = await readBrandGuideline(
24789
+ BRAND_GUIDELINES_DIR,
24790
+ USER_BRAND_GUIDELINES_DIR,
24791
+ req.params.id
24792
+ );
24745
24793
  if (body === null)
24746
24794
  return res.status(404).json({ error: "brand guideline not found" });
24747
24795
  res.json({ id: req.params.id, body });
@@ -24751,7 +24799,11 @@ async function startServer({
24751
24799
  });
24752
24800
  app.get("/api/brand-guidelines/:id/preview", async (req, res) => {
24753
24801
  try {
24754
- const body = await readBrandGuideline(BRAND_GUIDELINES_DIR, USER_BRAND_GUIDELINES_DIR, req.params.id);
24802
+ const body = await readBrandGuideline(
24803
+ BRAND_GUIDELINES_DIR,
24804
+ USER_BRAND_GUIDELINES_DIR,
24805
+ req.params.id
24806
+ );
24755
24807
  if (body === null)
24756
24808
  return res.status(404).type("text/plain").send("not found");
24757
24809
  const html = renderBrandGuidelinePreview(req.params.id, body);
@@ -24762,7 +24814,11 @@ async function startServer({
24762
24814
  });
24763
24815
  app.get("/api/brand-guidelines/:id/showcase", async (req, res) => {
24764
24816
  try {
24765
- const body = await readBrandGuideline(BRAND_GUIDELINES_DIR, USER_BRAND_GUIDELINES_DIR, req.params.id);
24817
+ const body = await readBrandGuideline(
24818
+ BRAND_GUIDELINES_DIR,
24819
+ USER_BRAND_GUIDELINES_DIR,
24820
+ req.params.id
24821
+ );
24766
24822
  if (body === null)
24767
24823
  return res.status(404).type("text/plain").send("not found");
24768
24824
  const html = renderBrandGuidelineShowcase(req.params.id, body);
@@ -24773,7 +24829,10 @@ async function startServer({
24773
24829
  });
24774
24830
  app.post("/api/brand-guidelines", async (req, res) => {
24775
24831
  try {
24776
- const created = await createUserBrandGuideline(USER_BRAND_GUIDELINES_DIR, req.body ?? {});
24832
+ const created = await createUserBrandGuideline(
24833
+ USER_BRAND_GUIDELINES_DIR,
24834
+ req.body ?? {}
24835
+ );
24777
24836
  res.status(201).json({ brandGuideline: created });
24778
24837
  } catch (err) {
24779
24838
  res.status(500).json({ error: String(err) });
@@ -24786,7 +24845,8 @@ async function startServer({
24786
24845
  req.params.id,
24787
24846
  req.body ?? {}
24788
24847
  );
24789
- if (!updated) return res.status(404).json({ error: "brand guideline not found" });
24848
+ if (!updated)
24849
+ return res.status(404).json({ error: "brand guideline not found" });
24790
24850
  res.json({ brandGuideline: updated });
24791
24851
  } catch (err) {
24792
24852
  res.status(500).json({ error: String(err) });
@@ -24794,8 +24854,12 @@ async function startServer({
24794
24854
  });
24795
24855
  app.delete("/api/brand-guidelines/:id", async (req, res) => {
24796
24856
  try {
24797
- const removed = await deleteUserBrandGuideline(USER_BRAND_GUIDELINES_DIR, req.params.id);
24798
- if (!removed) return res.status(404).json({ error: "brand guideline not found" });
24857
+ const removed = await deleteUserBrandGuideline(
24858
+ USER_BRAND_GUIDELINES_DIR,
24859
+ req.params.id
24860
+ );
24861
+ if (!removed)
24862
+ return res.status(404).json({ error: "brand guideline not found" });
24799
24863
  res.json({ ok: true });
24800
24864
  } catch (err) {
24801
24865
  res.status(500).json({ error: String(err) });
@@ -24821,7 +24885,9 @@ async function startServer({
24821
24885
  res.json(result);
24822
24886
  } catch (err) {
24823
24887
  const message = err instanceof Error ? err.message : String(err);
24824
- const status = /non-public|blocked|unsupported protocol|invalid url|not html|too many redirects|fetch failed/i.test(message) ? 422 : 500;
24888
+ const status = /non-public|blocked|unsupported protocol|invalid url|not html|too many redirects|fetch failed/i.test(
24889
+ message
24890
+ ) ? 422 : 500;
24825
24891
  res.status(status).json({ error: message });
24826
24892
  }
24827
24893
  });
@@ -24830,7 +24896,8 @@ async function startServer({
24830
24896
  const repo = typeof req.body?.repo === "string" ? req.body.repo.trim() : "";
24831
24897
  const url = typeof req.body?.url === "string" ? req.body.url.trim() : "";
24832
24898
  const target = repo || url;
24833
- if (!target) return res.status(400).json({ error: "repo or url is required" });
24899
+ if (!target)
24900
+ return res.status(400).json({ error: "repo or url is required" });
24834
24901
  const { id } = startGithubExtractionJob(target);
24835
24902
  res.status(202).json({ runId: id, status: "running" });
24836
24903
  } catch (err) {
@@ -24847,19 +24914,30 @@ async function startServer({
24847
24914
  const body = typeof req.body?.body === "string" ? req.body.body : "";
24848
24915
  const instruction = typeof req.body?.instruction === "string" ? req.body.instruction : "";
24849
24916
  const history = Array.isArray(req.body?.history) ? req.body.history.filter((h) => typeof h === "string") : [];
24850
- if (!body.trim()) return res.status(400).json({ error: "body is required" });
24851
- if (!instruction.trim()) return res.status(400).json({ error: "instruction is required" });
24917
+ if (!body.trim())
24918
+ return res.status(400).json({ error: "body is required" });
24919
+ if (!instruction.trim())
24920
+ return res.status(400).json({ error: "instruction is required" });
24852
24921
  const refined = await refineDesignMd(body, instruction, history);
24853
24922
  res.json({ body: refined });
24854
24923
  } catch (err) {
24855
24924
  res.status(500).json({ error: err instanceof Error ? err.message : String(err) });
24856
24925
  }
24857
24926
  });
24858
- app.post("/api/brand-guidelines/upload-image", brandAssetUpload.single("image"), (req, res) => {
24859
- const file = req.file;
24860
- if (!file) return res.status(400).json({ error: "image file is required" });
24861
- res.json({ url: `/brand-assets/${file.filename}`, name: file.originalname, size: file.size });
24862
- });
24927
+ app.post(
24928
+ "/api/brand-guidelines/upload-image",
24929
+ brandAssetUpload.single("image"),
24930
+ (req, res) => {
24931
+ const file = req.file;
24932
+ if (!file)
24933
+ return res.status(400).json({ error: "image file is required" });
24934
+ res.json({
24935
+ url: `/brand-assets/${file.filename}`,
24936
+ name: file.originalname,
24937
+ size: file.size
24938
+ });
24939
+ }
24940
+ );
24863
24941
  app.get("/api/brand-guidelines/:id/file", async (req, res) => {
24864
24942
  try {
24865
24943
  const file = await readBrandGuidelineFile(
@@ -24904,14 +24982,14 @@ async function startServer({
24904
24982
  }
24905
24983
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:T]/g, "-").slice(0, 19);
24906
24984
  const slug = sanitizeSlug(identifier || title || "artifact");
24907
- const dir = path28.join(ARTIFACTS_DIR, `${stamp}-${slug}`);
24908
- fs7.mkdirSync(dir, { recursive: true });
24909
- const file = path28.join(dir, "index.html");
24910
- fs7.writeFileSync(file, html, "utf8");
24985
+ const dir = path29.join(ARTIFACTS_DIR, `${stamp}-${slug}`);
24986
+ fs8.mkdirSync(dir, { recursive: true });
24987
+ const file = path29.join(dir, "index.html");
24988
+ fs8.writeFileSync(file, html, "utf8");
24911
24989
  const findings = lintArtifact(html);
24912
24990
  res.json({
24913
24991
  path: file,
24914
- url: `/artifacts/${path28.basename(dir)}/index.html`,
24992
+ url: `/artifacts/${path29.basename(dir)}/index.html`,
24915
24993
  lint: findings
24916
24994
  });
24917
24995
  } catch (err) {
@@ -25954,7 +26032,7 @@ async function startServer({
25954
26032
  const project = getProject(db, req.params.id);
25955
26033
  await ensureProject(PROJECTS_DIR, req.params.id, project?.metadata);
25956
26034
  if (req.file) {
25957
- const buf2 = await fs7.promises.readFile(req.file.path);
26035
+ const buf2 = await fs8.promises.readFile(req.file.path);
25958
26036
  const desiredName = sanitizeName(
25959
26037
  req.body?.name || req.file.originalname
25960
26038
  );
@@ -25965,7 +26043,7 @@ async function startServer({
25965
26043
  buf2,
25966
26044
  { metadata: project?.metadata }
25967
26045
  );
25968
- fs7.promises.unlink(req.file.path).catch(() => {
26046
+ fs8.promises.unlink(req.file.path).catch(() => {
25969
26047
  });
25970
26048
  const body2 = { file: meta2 };
25971
26049
  return res.json(body2);
@@ -26112,7 +26190,7 @@ async function startServer({
26112
26190
  res.json({
26113
26191
  projectsDir: PROJECTS_DIR,
26114
26192
  defaultProjectsDir: DEFAULT_PROJECTS_DIR,
26115
- configured: process.env.OD_FORCE_STORAGE_UNCONFIGURED === "1" ? false : fs7.existsSync(path28.join(RUNTIME_DATA_DIR, "projects-dir.json")),
26193
+ configured: process.env.OD_FORCE_STORAGE_UNCONFIGURED === "1" ? false : fs8.existsSync(path29.join(RUNTIME_DATA_DIR, "projects-dir.json")),
26116
26194
  // Whether the current location is still the DEFAULT. The daemon
26117
26195
  // records the default as the chosen location on first boot (see the
26118
26196
  // auto-write next to PROJECTS_DIR), so `configured` is true out of
@@ -26134,16 +26212,16 @@ async function startServer({
26134
26212
  if (typeof requested !== "string" || !requested.trim()) {
26135
26213
  return res.status(400).json({ error: "projectsDir is required" });
26136
26214
  }
26137
- const expanded = requested.startsWith("~/") ? path28.join(os4.homedir(), requested.slice(2)) : requested;
26138
- const resolved = path28.isAbsolute(expanded) ? expanded : path28.resolve(RUNTIME_DATA_DIR, expanded);
26215
+ const expanded = requested.startsWith("~/") ? path29.join(os4.homedir(), requested.slice(2)) : requested;
26216
+ const resolved = path29.isAbsolute(expanded) ? expanded : path29.resolve(RUNTIME_DATA_DIR, expanded);
26139
26217
  try {
26140
- fs7.mkdirSync(resolved, { recursive: true });
26141
- fs7.accessSync(resolved, fs7.constants.W_OK);
26218
+ fs8.mkdirSync(resolved, { recursive: true });
26219
+ fs8.accessSync(resolved, fs8.constants.W_OK);
26142
26220
  } catch (e) {
26143
26221
  return res.status(400).json({ error: `Path is not writable: ${e.message}` });
26144
26222
  }
26145
- const overrideFile = path28.join(RUNTIME_DATA_DIR, "projects-dir.json");
26146
- fs7.writeFileSync(
26223
+ const overrideFile = path29.join(RUNTIME_DATA_DIR, "projects-dir.json");
26224
+ fs8.writeFileSync(
26147
26225
  overrideFile,
26148
26226
  JSON.stringify({ projectsDir: requested }, null, 2),
26149
26227
  "utf8"
@@ -26153,18 +26231,18 @@ async function startServer({
26153
26231
  try {
26154
26232
  const migrateSources = [
26155
26233
  DEFAULT_PROJECTS_DIR,
26156
- path28.join(RUNTIME_DATA_DIR, "..", "tf-design-projects-backup")
26234
+ path29.join(RUNTIME_DATA_DIR, "..", "tf-design-projects-backup")
26157
26235
  ];
26158
26236
  let migrated = 0;
26159
26237
  for (const srcDir of migrateSources) {
26160
- if (!fs7.existsSync(srcDir)) continue;
26161
- const entries = fs7.readdirSync(srcDir, { withFileTypes: true });
26238
+ if (!fs8.existsSync(srcDir)) continue;
26239
+ const entries = fs8.readdirSync(srcDir, { withFileTypes: true });
26162
26240
  for (const entry of entries) {
26163
26241
  if (!entry.isDirectory()) continue;
26164
- const src = path28.join(srcDir, entry.name);
26165
- const dst = path28.join(PROJECTS_DIR, entry.name);
26166
- if (fs7.existsSync(dst)) continue;
26167
- fs7.cpSync(src, dst, { recursive: true });
26242
+ const src = path29.join(srcDir, entry.name);
26243
+ const dst = path29.join(PROJECTS_DIR, entry.name);
26244
+ if (fs8.existsSync(dst)) continue;
26245
+ fs8.cpSync(src, dst, { recursive: true });
26168
26246
  migrated++;
26169
26247
  }
26170
26248
  }
@@ -26212,18 +26290,18 @@ async function startServer({
26212
26290
  if (typeof target !== "string" || !target.trim()) {
26213
26291
  return res.status(400).json({ error: "targetDir is required" });
26214
26292
  }
26215
- const expanded = target.startsWith("~/") ? path28.join(os4.homedir(), target.slice(2)) : target;
26216
- const resolvedTarget = path28.isAbsolute(expanded) ? expanded : path28.resolve(RUNTIME_DATA_DIR, expanded);
26217
- fs7.mkdirSync(resolvedTarget, { recursive: true });
26293
+ const expanded = target.startsWith("~/") ? path29.join(os4.homedir(), target.slice(2)) : target;
26294
+ const resolvedTarget = path29.isAbsolute(expanded) ? expanded : path29.resolve(RUNTIME_DATA_DIR, expanded);
26295
+ fs8.mkdirSync(resolvedTarget, { recursive: true });
26218
26296
  const sourceDir = PROJECTS_DIR;
26219
26297
  let migrated = 0;
26220
- const entries = fs7.readdirSync(sourceDir, { withFileTypes: true });
26298
+ const entries = fs8.readdirSync(sourceDir, { withFileTypes: true });
26221
26299
  for (const entry of entries) {
26222
26300
  if (!entry.isDirectory()) continue;
26223
- const src = path28.join(sourceDir, entry.name);
26224
- const dst = path28.join(resolvedTarget, entry.name);
26225
- if (fs7.existsSync(dst)) continue;
26226
- fs7.cpSync(src, dst, { recursive: true });
26301
+ const src = path29.join(sourceDir, entry.name);
26302
+ const dst = path29.join(resolvedTarget, entry.name);
26303
+ if (fs8.existsSync(dst)) continue;
26304
+ fs8.cpSync(src, dst, { recursive: true });
26227
26305
  migrated++;
26228
26306
  }
26229
26307
  res.json({ migrated, targetDir: resolvedTarget });
@@ -26379,7 +26457,7 @@ async function startServer({
26379
26457
  const out = [];
26380
26458
  for (const f of incoming) {
26381
26459
  try {
26382
- const stat12 = await fs7.promises.stat(f.path);
26460
+ const stat12 = await fs8.promises.stat(f.path);
26383
26461
  out.push({
26384
26462
  name: f.filename,
26385
26463
  path: f.filename,
@@ -26411,10 +26489,17 @@ async function startServer({
26411
26489
  let brandGuidelineBody;
26412
26490
  let brandGuidelineTitle;
26413
26491
  if (effectiveBrandGuidelineId) {
26414
- const systems = await listBrandGuidelines(BRAND_GUIDELINES_DIR, USER_BRAND_GUIDELINES_DIR);
26492
+ const systems = await listBrandGuidelines(
26493
+ BRAND_GUIDELINES_DIR,
26494
+ USER_BRAND_GUIDELINES_DIR
26495
+ );
26415
26496
  const summary = systems.find((s) => s.id === effectiveBrandGuidelineId);
26416
26497
  brandGuidelineTitle = summary?.title;
26417
- brandGuidelineBody = await readBrandGuideline(BRAND_GUIDELINES_DIR, USER_BRAND_GUIDELINES_DIR, effectiveBrandGuidelineId) ?? void 0;
26498
+ brandGuidelineBody = await readBrandGuideline(
26499
+ BRAND_GUIDELINES_DIR,
26500
+ USER_BRAND_GUIDELINES_DIR,
26501
+ effectiveBrandGuidelineId
26502
+ ) ?? void 0;
26418
26503
  }
26419
26504
  const template = metadata?.kind === "template" && typeof metadata.templateId === "string" ? getTemplate(db, metadata.templateId) ?? void 0 : void 0;
26420
26505
  const prompt = composeSystemPrompt({
@@ -26487,13 +26572,13 @@ async function startServer({
26487
26572
  }
26488
26573
  if (run.cancelRequested || design.runs.isTerminal(run.status)) return;
26489
26574
  const safeImages = imagePaths.filter((p) => {
26490
- const resolved = path28.resolve(p);
26491
- return resolved.startsWith(UPLOAD_DIR + path28.sep) && fs7.existsSync(resolved);
26575
+ const resolved = path29.resolve(p);
26576
+ return resolved.startsWith(UPLOAD_DIR + path29.sep) && fs8.existsSync(resolved);
26492
26577
  });
26493
26578
  const safeAttachments = cwd ? (Array.isArray(attachments) ? attachments : []).filter((p) => typeof p === "string" && p.length > 0).filter((p) => {
26494
26579
  try {
26495
- const abs = path28.resolve(cwd, p);
26496
- return (abs === cwd || abs.startsWith(cwd + path28.sep)) && fs7.existsSync(abs);
26580
+ const abs = path29.resolve(cwd, p);
26581
+ return (abs === cwd || abs.startsWith(cwd + path29.sep)) && fs8.existsSync(abs);
26497
26582
  } catch {
26498
26583
  return false;
26499
26584
  }
@@ -26592,9 +26677,9 @@ Attached project files: ${safeAttachments.map((p) => `\`${p}\``).join(", ")}` :
26592
26677
  if (cwd && typeof cwd === "string") {
26593
26678
  for (const name of names) {
26594
26679
  try {
26595
- const abs = path28.resolve(cwd, name);
26596
- if (abs !== cwd && abs.startsWith(cwd + path28.sep)) {
26597
- const content = fs7.readFileSync(abs, "utf8");
26680
+ const abs = path29.resolve(cwd, name);
26681
+ if (abs !== cwd && abs.startsWith(cwd + path29.sep)) {
26682
+ const content = fs8.readFileSync(abs, "utf8");
26598
26683
  if (content.length <= MAX_PER_FILE && used + content.length <= MAX_TOTAL) {
26599
26684
  used += content.length;
26600
26685
  snapshot += `
@@ -26795,8 +26880,8 @@ ${safeImages.map((p) => `@${p}`).join(" ")}` : ""
26795
26880
  if (names.length === 0 || !cwd || typeof cwd !== "string") return {};
26796
26881
  const abs = names.map((n) => {
26797
26882
  try {
26798
- const resolved = path28.resolve(cwd, n);
26799
- if (resolved === cwd || !resolved.startsWith(cwd + path28.sep))
26883
+ const resolved = path29.resolve(cwd, n);
26884
+ if (resolved === cwd || !resolved.startsWith(cwd + path29.sep))
26800
26885
  return null;
26801
26886
  return resolved;
26802
26887
  } catch {
@@ -26804,7 +26889,7 @@ ${safeImages.map((p) => `@${p}`).join(" ")}` : ""
26804
26889
  }
26805
26890
  }).filter((p) => typeof p === "string");
26806
26891
  if (abs.length === 0) return {};
26807
- return { OD_MANUAL_EDIT_FILES: abs.join(path28.delimiter) };
26892
+ return { OD_MANUAL_EDIT_FILES: abs.join(path29.delimiter) };
26808
26893
  })();
26809
26894
  const env = {
26810
26895
  ...spawnEnvForAgent(
@@ -26876,7 +26961,7 @@ ${safeImages.map((p) => `@${p}`).join(" ")}` : ""
26876
26961
  } else {
26877
26962
  const critiqueRunId = run.id;
26878
26963
  const critiqueProjectKey = typeof projectId === "string" && projectId ? projectId : critiqueRunId;
26879
- const critiqueArtifactDir = path28.join(
26964
+ const critiqueArtifactDir = path29.join(
26880
26965
  ARTIFACTS_DIR,
26881
26966
  critiqueProjectKey,
26882
26967
  critiqueRunId
@@ -27126,10 +27211,10 @@ ${safeImages.map((p) => `@${p}`).join(" ")}` : ""
27126
27211
  }
27127
27212
  });
27128
27213
  };
27129
- const appendVersionedApiPath = (baseUrl, path29) => {
27214
+ const appendVersionedApiPath = (baseUrl, path30) => {
27130
27215
  const url = new URL(baseUrl);
27131
27216
  const trimmed = url.pathname.replace(/\/+$/, "");
27132
- url.pathname = /\/v\d+(\/|$)/.test(trimmed) ? `${trimmed}${path29}` : `${trimmed}/v1${path29}`;
27217
+ url.pathname = /\/v\d+(\/|$)/.test(trimmed) ? `${trimmed}${path30}` : `${trimmed}/v1${path30}`;
27133
27218
  return url.toString();
27134
27219
  };
27135
27220
  const collectSseFrame = (frame) => {
@@ -27653,6 +27738,8 @@ function isLocalSameOrigin(req, port) {
27653
27738
  }
27654
27739
 
27655
27740
  export {
27741
+ detectLayout,
27742
+ resolveDataRoot,
27656
27743
  resolveProjectRoot,
27657
27744
  resolveDaemonCliPath,
27658
27745
  composeLiveInstructionPrompt,
@@ -27664,6 +27751,7 @@ export {
27664
27751
  renderCommentAttachmentHint,
27665
27752
  resolveDaemonResourceRoot,
27666
27753
  resolveDataDir,
27754
+ dataRoot,
27667
27755
  resolveProjectsDir,
27668
27756
  SSE_KEEPALIVE_INTERVAL_MS,
27669
27757
  createAgentRuntimeEnv,