@floless/app 0.43.0 → 0.45.1

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.
@@ -5489,7 +5489,7 @@ var require_thread_stream = __commonJS({
5489
5489
  var { version } = require_package();
5490
5490
  var { EventEmitter: EventEmitter2 } = require("events");
5491
5491
  var { Worker } = require("worker_threads");
5492
- var { join: join28 } = require("path");
5492
+ var { join: join29 } = require("path");
5493
5493
  var { pathToFileURL } = require("url");
5494
5494
  var { wait } = require_wait();
5495
5495
  var {
@@ -5540,7 +5540,7 @@ var require_thread_stream = __commonJS({
5540
5540
  function createWorker(stream, opts) {
5541
5541
  const { filename, workerData } = opts;
5542
5542
  const bundlerOverrides = "__bundlerPathsOverrides" in globalThis ? globalThis.__bundlerPathsOverrides : {};
5543
- const toExecute = bundlerOverrides["thread-stream-worker"] || join28(__dirname, "lib", "worker.js");
5543
+ const toExecute = bundlerOverrides["thread-stream-worker"] || join29(__dirname, "lib", "worker.js");
5544
5544
  const worker = new Worker(toExecute, {
5545
5545
  ...opts.workerOpts,
5546
5546
  name: opts.workerOpts?.name || "thread-stream",
@@ -6006,10 +6006,10 @@ var require_transport = __commonJS({
6006
6006
  "node_modules/pino/lib/transport.js"(exports2, module2) {
6007
6007
  "use strict";
6008
6008
  var { createRequire: createRequire4 } = require("module");
6009
- var { existsSync: existsSync24 } = require("node:fs");
6009
+ var { existsSync: existsSync25 } = require("node:fs");
6010
6010
  var getCallers = require_caller();
6011
- var { join: join28, isAbsolute: isAbsolute2, sep: sep4 } = require("node:path");
6012
- var { fileURLToPath: fileURLToPath5 } = require("node:url");
6011
+ var { join: join29, isAbsolute: isAbsolute2, sep: sep4 } = require("node:path");
6012
+ var { fileURLToPath: fileURLToPath6 } = require("node:url");
6013
6013
  var sleep = require_atomic_sleep();
6014
6014
  var onExit = require_on_exit_leak_free();
6015
6015
  var ThreadStream = require_thread_stream();
@@ -6075,12 +6075,12 @@ var require_transport = __commonJS({
6075
6075
  let path = unquoted;
6076
6076
  if (path.startsWith("file://")) {
6077
6077
  try {
6078
- path = fileURLToPath5(path);
6078
+ path = fileURLToPath6(path);
6079
6079
  } catch {
6080
6080
  return false;
6081
6081
  }
6082
6082
  }
6083
- return isAbsolute2(path) && !existsSync24(path);
6083
+ return isAbsolute2(path) && !existsSync25(path);
6084
6084
  }
6085
6085
  function stripQuotes(value) {
6086
6086
  const first = value[0];
@@ -6161,7 +6161,7 @@ var require_transport = __commonJS({
6161
6161
  throw new Error("only one of target or targets can be specified");
6162
6162
  }
6163
6163
  if (targets) {
6164
- target = bundlerOverrides["pino-worker"] || join28(__dirname, "worker.js");
6164
+ target = bundlerOverrides["pino-worker"] || join29(__dirname, "worker.js");
6165
6165
  options.targets = targets.filter((dest) => dest.target).map((dest) => {
6166
6166
  return {
6167
6167
  ...dest,
@@ -6179,7 +6179,7 @@ var require_transport = __commonJS({
6179
6179
  });
6180
6180
  });
6181
6181
  } else if (pipeline2) {
6182
- target = bundlerOverrides["pino-worker"] || join28(__dirname, "worker.js");
6182
+ target = bundlerOverrides["pino-worker"] || join29(__dirname, "worker.js");
6183
6183
  options.pipelines = [pipeline2.map((dest) => {
6184
6184
  return {
6185
6185
  ...dest,
@@ -6202,7 +6202,7 @@ var require_transport = __commonJS({
6202
6202
  return origin;
6203
6203
  }
6204
6204
  if (origin === "pino/file") {
6205
- return join28(__dirname, "..", "file.js");
6205
+ return join29(__dirname, "..", "file.js");
6206
6206
  }
6207
6207
  let fixTarget2;
6208
6208
  for (const filePath of callers) {
@@ -7182,7 +7182,7 @@ var require_safe_stable_stringify = __commonJS({
7182
7182
  return circularValue;
7183
7183
  }
7184
7184
  let res = "";
7185
- let join28 = ",";
7185
+ let join29 = ",";
7186
7186
  const originalIndentation = indentation;
7187
7187
  if (Array.isArray(value)) {
7188
7188
  if (value.length === 0) {
@@ -7196,7 +7196,7 @@ var require_safe_stable_stringify = __commonJS({
7196
7196
  indentation += spacer;
7197
7197
  res += `
7198
7198
  ${indentation}`;
7199
- join28 = `,
7199
+ join29 = `,
7200
7200
  ${indentation}`;
7201
7201
  }
7202
7202
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
@@ -7204,13 +7204,13 @@ ${indentation}`;
7204
7204
  for (; i < maximumValuesToStringify - 1; i++) {
7205
7205
  const tmp2 = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
7206
7206
  res += tmp2 !== void 0 ? tmp2 : "null";
7207
- res += join28;
7207
+ res += join29;
7208
7208
  }
7209
7209
  const tmp = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
7210
7210
  res += tmp !== void 0 ? tmp : "null";
7211
7211
  if (value.length - 1 > maximumBreadth) {
7212
7212
  const removedKeys = value.length - maximumBreadth - 1;
7213
- res += `${join28}"... ${getItemCount(removedKeys)} not stringified"`;
7213
+ res += `${join29}"... ${getItemCount(removedKeys)} not stringified"`;
7214
7214
  }
7215
7215
  if (spacer !== "") {
7216
7216
  res += `
@@ -7231,7 +7231,7 @@ ${originalIndentation}`;
7231
7231
  let separator = "";
7232
7232
  if (spacer !== "") {
7233
7233
  indentation += spacer;
7234
- join28 = `,
7234
+ join29 = `,
7235
7235
  ${indentation}`;
7236
7236
  whitespace = " ";
7237
7237
  }
@@ -7245,13 +7245,13 @@ ${indentation}`;
7245
7245
  const tmp = stringifyFnReplacer(key2, value, stack, replacer, spacer, indentation);
7246
7246
  if (tmp !== void 0) {
7247
7247
  res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
7248
- separator = join28;
7248
+ separator = join29;
7249
7249
  }
7250
7250
  }
7251
7251
  if (keyLength > maximumBreadth) {
7252
7252
  const removedKeys = keyLength - maximumBreadth;
7253
7253
  res += `${separator}"...":${whitespace}"${getItemCount(removedKeys)} not stringified"`;
7254
- separator = join28;
7254
+ separator = join29;
7255
7255
  }
7256
7256
  if (spacer !== "" && separator.length > 1) {
7257
7257
  res = `
@@ -7292,7 +7292,7 @@ ${originalIndentation}`;
7292
7292
  }
7293
7293
  const originalIndentation = indentation;
7294
7294
  let res = "";
7295
- let join28 = ",";
7295
+ let join29 = ",";
7296
7296
  if (Array.isArray(value)) {
7297
7297
  if (value.length === 0) {
7298
7298
  return "[]";
@@ -7305,7 +7305,7 @@ ${originalIndentation}`;
7305
7305
  indentation += spacer;
7306
7306
  res += `
7307
7307
  ${indentation}`;
7308
- join28 = `,
7308
+ join29 = `,
7309
7309
  ${indentation}`;
7310
7310
  }
7311
7311
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
@@ -7313,13 +7313,13 @@ ${indentation}`;
7313
7313
  for (; i < maximumValuesToStringify - 1; i++) {
7314
7314
  const tmp2 = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
7315
7315
  res += tmp2 !== void 0 ? tmp2 : "null";
7316
- res += join28;
7316
+ res += join29;
7317
7317
  }
7318
7318
  const tmp = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
7319
7319
  res += tmp !== void 0 ? tmp : "null";
7320
7320
  if (value.length - 1 > maximumBreadth) {
7321
7321
  const removedKeys = value.length - maximumBreadth - 1;
7322
- res += `${join28}"... ${getItemCount(removedKeys)} not stringified"`;
7322
+ res += `${join29}"... ${getItemCount(removedKeys)} not stringified"`;
7323
7323
  }
7324
7324
  if (spacer !== "") {
7325
7325
  res += `
@@ -7332,7 +7332,7 @@ ${originalIndentation}`;
7332
7332
  let whitespace = "";
7333
7333
  if (spacer !== "") {
7334
7334
  indentation += spacer;
7335
- join28 = `,
7335
+ join29 = `,
7336
7336
  ${indentation}`;
7337
7337
  whitespace = " ";
7338
7338
  }
@@ -7341,7 +7341,7 @@ ${indentation}`;
7341
7341
  const tmp = stringifyArrayReplacer(key2, value[key2], stack, replacer, spacer, indentation);
7342
7342
  if (tmp !== void 0) {
7343
7343
  res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
7344
- separator = join28;
7344
+ separator = join29;
7345
7345
  }
7346
7346
  }
7347
7347
  if (spacer !== "" && separator.length > 1) {
@@ -7399,20 +7399,20 @@ ${originalIndentation}`;
7399
7399
  indentation += spacer;
7400
7400
  let res2 = `
7401
7401
  ${indentation}`;
7402
- const join29 = `,
7402
+ const join30 = `,
7403
7403
  ${indentation}`;
7404
7404
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
7405
7405
  let i = 0;
7406
7406
  for (; i < maximumValuesToStringify - 1; i++) {
7407
7407
  const tmp2 = stringifyIndent(String(i), value[i], stack, spacer, indentation);
7408
7408
  res2 += tmp2 !== void 0 ? tmp2 : "null";
7409
- res2 += join29;
7409
+ res2 += join30;
7410
7410
  }
7411
7411
  const tmp = stringifyIndent(String(i), value[i], stack, spacer, indentation);
7412
7412
  res2 += tmp !== void 0 ? tmp : "null";
7413
7413
  if (value.length - 1 > maximumBreadth) {
7414
7414
  const removedKeys = value.length - maximumBreadth - 1;
7415
- res2 += `${join29}"... ${getItemCount(removedKeys)} not stringified"`;
7415
+ res2 += `${join30}"... ${getItemCount(removedKeys)} not stringified"`;
7416
7416
  }
7417
7417
  res2 += `
7418
7418
  ${originalIndentation}`;
@@ -7428,16 +7428,16 @@ ${originalIndentation}`;
7428
7428
  return '"[Object]"';
7429
7429
  }
7430
7430
  indentation += spacer;
7431
- const join28 = `,
7431
+ const join29 = `,
7432
7432
  ${indentation}`;
7433
7433
  let res = "";
7434
7434
  let separator = "";
7435
7435
  let maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
7436
7436
  if (isTypedArrayWithEntries(value)) {
7437
- res += stringifyTypedArray(value, join28, maximumBreadth);
7437
+ res += stringifyTypedArray(value, join29, maximumBreadth);
7438
7438
  keys = keys.slice(value.length);
7439
7439
  maximumPropertiesToStringify -= value.length;
7440
- separator = join28;
7440
+ separator = join29;
7441
7441
  }
7442
7442
  if (deterministic) {
7443
7443
  keys = sort(keys, comparator);
@@ -7448,13 +7448,13 @@ ${indentation}`;
7448
7448
  const tmp = stringifyIndent(key2, value[key2], stack, spacer, indentation);
7449
7449
  if (tmp !== void 0) {
7450
7450
  res += `${separator}${strEscape(key2)}: ${tmp}`;
7451
- separator = join28;
7451
+ separator = join29;
7452
7452
  }
7453
7453
  }
7454
7454
  if (keyLength > maximumBreadth) {
7455
7455
  const removedKeys = keyLength - maximumBreadth;
7456
7456
  res += `${separator}"...": "${getItemCount(removedKeys)} not stringified"`;
7457
- separator = join28;
7457
+ separator = join29;
7458
7458
  }
7459
7459
  if (separator !== "") {
7460
7460
  res = `
@@ -41991,7 +41991,7 @@ var require_send = __commonJS({
41991
41991
  var { parseTokenList } = require_parseTokenList();
41992
41992
  var { createHttpError } = require_createHttpError();
41993
41993
  var extname2 = path.extname;
41994
- var join28 = path.join;
41994
+ var join29 = path.join;
41995
41995
  var normalize2 = path.normalize;
41996
41996
  var resolve6 = path.resolve;
41997
41997
  var sep4 = path.sep;
@@ -42078,7 +42078,7 @@ var require_send = __commonJS({
42078
42078
  return { statusCode: 403 };
42079
42079
  }
42080
42080
  parts = path2.split(sep4);
42081
- path2 = normalize2(join28(root, path2));
42081
+ path2 = normalize2(join29(root, path2));
42082
42082
  } else {
42083
42083
  if (UP_PATH_REGEXP.test(path2)) {
42084
42084
  debug('malicious path "%s"', path2);
@@ -42361,7 +42361,7 @@ var require_send = __commonJS({
42361
42361
  let err;
42362
42362
  for (let i = 0; i < options.index.length; i++) {
42363
42363
  const index = options.index[i];
42364
- const p = join28(path2, index);
42364
+ const p = join29(path2, index);
42365
42365
  const { error, stat: stat4 } = await tryStat(p);
42366
42366
  if (error) {
42367
42367
  err = error;
@@ -43011,7 +43011,7 @@ var require_static = __commonJS({
43011
43011
  "node_modules/@fastify/static/index.js"(exports2, module2) {
43012
43012
  "use strict";
43013
43013
  var path = require("node:path");
43014
- var { fileURLToPath: fileURLToPath5 } = require("node:url");
43014
+ var { fileURLToPath: fileURLToPath6 } = require("node:url");
43015
43015
  var { statSync: statSync8 } = require("node:fs");
43016
43016
  var { glob } = require_commonjs6();
43017
43017
  var fp = require_plugin2();
@@ -43145,8 +43145,8 @@ var require_static = __commonJS({
43145
43145
  }
43146
43146
  }
43147
43147
  }
43148
- for (const [dirname11, rootPath] of indexDirs.entries()) {
43149
- const pathname = dirname11 + (dirname11.endsWith("/") ? "" : "/");
43148
+ for (const [dirname12, rootPath] of indexDirs.entries()) {
43149
+ const pathname = dirname12 + (dirname12.endsWith("/") ? "" : "/");
43150
43150
  const file = "/" + pathname.replace(prefix, "");
43151
43151
  setUpHeadAndGet(routeOpts, pathname, file, rootPath);
43152
43152
  if (opts.redirect === true) {
@@ -43330,13 +43330,13 @@ var require_static = __commonJS({
43330
43330
  return root;
43331
43331
  }
43332
43332
  if (root instanceof URL && root.protocol === "file:") {
43333
- return fileURLToPath5(root);
43333
+ return fileURLToPath6(root);
43334
43334
  }
43335
43335
  if (Array.isArray(root)) {
43336
43336
  const result = [];
43337
43337
  for (let i = 0, il = root.length; i < il; ++i) {
43338
43338
  if (root[i] instanceof URL && root[i].protocol === "file:") {
43339
- result.push(fileURLToPath5(root[i]));
43339
+ result.push(fileURLToPath6(root[i]));
43340
43340
  } else {
43341
43341
  result.push(root[i]);
43342
43342
  }
@@ -50826,10 +50826,10 @@ var import_node_child_process9 = require("node:child_process");
50826
50826
  var import_node_readline2 = require("node:readline");
50827
50827
 
50828
50828
  // index.ts
50829
- var import_node_url4 = require("node:url");
50830
- var import_node_path26 = require("node:path");
50831
- var import_node_os18 = require("node:os");
50832
- var import_node_fs28 = require("node:fs");
50829
+ var import_node_url5 = require("node:url");
50830
+ var import_node_path27 = require("node:path");
50831
+ var import_node_os19 = require("node:os");
50832
+ var import_node_fs29 = require("node:fs");
50833
50833
  var import_node_child_process7 = require("node:child_process");
50834
50834
 
50835
50835
  // log.mjs
@@ -52856,7 +52856,7 @@ function appVersion() {
52856
52856
  return resolveVersion({
52857
52857
  isSea: isSea2(),
52858
52858
  sqVersionXml: readSqVersionXml(),
52859
- define: true ? "0.43.0" : void 0,
52859
+ define: true ? "0.45.1" : void 0,
52860
52860
  pkgVersion: readPkgVersion()
52861
52861
  });
52862
52862
  }
@@ -52866,14 +52866,111 @@ function resolveChannel(s) {
52866
52866
  return "dev";
52867
52867
  }
52868
52868
  function appChannel() {
52869
- return resolveChannel({ isSea: isSea2(), define: true ? "0.43.0" : void 0 });
52869
+ return resolveChannel({ isSea: isSea2(), define: true ? "0.45.1" : void 0 });
52870
52870
  }
52871
52871
 
52872
- // oauth-presets.ts
52872
+ // workflow-update.ts
52873
+ var import_node_fs8 = require("node:fs");
52873
52874
  var import_node_os7 = require("node:os");
52874
52875
  var import_node_path7 = require("node:path");
52876
+ var import_node_url = require("node:url");
52877
+ var import_yaml2 = __toESM(require_dist6(), 1);
52878
+ var here = (0, import_node_path7.dirname)((0, import_node_url.fileURLToPath)(__import_meta_url));
52879
+ function compareSemver(a, b) {
52880
+ const pa = String(a).split(".");
52881
+ const pb = String(b).split(".");
52882
+ for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
52883
+ const na = Number.parseInt(pa[i] ?? "0", 10) || 0;
52884
+ const nb = Number.parseInt(pb[i] ?? "0", 10) || 0;
52885
+ if (na !== nb) return na > nb ? 1 : -1;
52886
+ }
52887
+ return 0;
52888
+ }
52889
+ function changelogSince(changelog, installed) {
52890
+ return (changelog ?? []).filter((e) => e && compareSemver(String(e.version), installed) > 0);
52891
+ }
52892
+ function detectUpdates(installed, templates) {
52893
+ const out = [];
52894
+ for (const t of templates) {
52895
+ if (t.publisher !== "floless") continue;
52896
+ const iv = installed[t.id];
52897
+ if (iv == null) continue;
52898
+ if (compareSemver(t.version, iv) <= 0) continue;
52899
+ out.push({
52900
+ id: t.id,
52901
+ installed: iv,
52902
+ available: t.version,
52903
+ module: t.module,
52904
+ changelog: changelogSince(t.changelog, iv)
52905
+ });
52906
+ }
52907
+ return out;
52908
+ }
52909
+ function readTemplateMeta(path) {
52910
+ const doc2 = (0, import_yaml2.parse)((0, import_node_fs8.readFileSync)(path, "utf8")) ?? {};
52911
+ return {
52912
+ id: String(doc2.app ?? ""),
52913
+ version: doc2.version != null ? String(doc2.version) : "0.0.0",
52914
+ publisher: typeof doc2.publisher === "string" ? doc2.publisher : void 0,
52915
+ module: typeof doc2.module === "string" ? doc2.module : void 0,
52916
+ changelog: Array.isArray(doc2.changelog) ? doc2.changelog : void 0,
52917
+ path
52918
+ };
52919
+ }
52920
+ function templatePaths(roots) {
52921
+ const envDir = process.env.FLOLESS_TEMPLATES_DIR;
52922
+ const flatDirs = roots ?? [
52923
+ ...envDir ? [envDir] : [],
52924
+ (0, import_node_path7.join)(here, "templates"),
52925
+ // bundled: dist/templates beside the cjs
52926
+ (0, import_node_path7.join)(here, "dist", "templates"),
52927
+ // dev: the built bundle at server/dist
52928
+ (0, import_node_path7.join)((0, import_node_path7.dirname)(process.execPath), "templates")
52929
+ // SEA exe
52930
+ ];
52931
+ for (const d of flatDirs) {
52932
+ if (!(0, import_node_fs8.existsSync)(d)) continue;
52933
+ const flos = (0, import_node_fs8.readdirSync)(d).filter((f) => f.endsWith(".flo"));
52934
+ if (flos.length) return flos.map((f) => (0, import_node_path7.join)(d, f));
52935
+ }
52936
+ for (const demos of [(0, import_node_path7.join)(here, "..", "demos"), (0, import_node_path7.join)(here, "..", "..", "demos")]) {
52937
+ if (!(0, import_node_fs8.existsSync)(demos)) continue;
52938
+ const out = [];
52939
+ for (const dir of (0, import_node_fs8.readdirSync)(demos)) {
52940
+ try {
52941
+ for (const f of (0, import_node_fs8.readdirSync)((0, import_node_path7.join)(demos, dir))) if (f.endsWith(".flo")) out.push((0, import_node_path7.join)(demos, dir, f));
52942
+ } catch {
52943
+ }
52944
+ }
52945
+ return out;
52946
+ }
52947
+ return [];
52948
+ }
52949
+ function loadTemplates(roots) {
52950
+ const out = [];
52951
+ for (const p of templatePaths(roots)) {
52952
+ try {
52953
+ out.push(readTemplateMeta(p));
52954
+ } catch (e) {
52955
+ console.warn(`workflow-update: skipping unreadable template ${p}: ${e instanceof Error ? e.message : e}`);
52956
+ }
52957
+ }
52958
+ return out;
52959
+ }
52960
+ function backupDir(id, version, ts) {
52961
+ const root = process.env.FLOLESS_HOME ?? (0, import_node_path7.join)((0, import_node_os7.homedir)(), ".floless");
52962
+ const safe = (s) => {
52963
+ const c = String(s).replace(/[^0-9A-Za-z._-]/g, "_");
52964
+ return /^\.+$/.test(c) ? "_" : c || "_";
52965
+ };
52966
+ return (0, import_node_path7.join)(root, "app-backups", safe(id), `${safe(version)}-${ts}`);
52967
+ }
52968
+
52969
+ // oauth-presets.ts
52970
+ var import_node_os8 = require("node:os");
52971
+ var import_node_path8 = require("node:path");
52875
52972
  var import_node_net = __toESM(require("node:net"), 1);
52876
- var import_node_fs8 = require("node:fs");
52973
+ var import_node_fs9 = require("node:fs");
52877
52974
  var MANAGED_HEADER = "# managed by floless.app - do not edit";
52878
52975
  var OAUTH_PRESETS = {
52879
52976
  "trimble-connect": {
@@ -52903,7 +53000,7 @@ function managedProfileYaml(preset) {
52903
53000
  ].join("\n");
52904
53001
  }
52905
53002
  function oauthDir() {
52906
- return process.env.AWARE_HOME ? (0, import_node_path7.join)(process.env.AWARE_HOME, "oauth") : (0, import_node_path7.join)((0, import_node_os7.homedir)(), ".aware", "oauth");
53003
+ return process.env.AWARE_HOME ? (0, import_node_path8.join)(process.env.AWARE_HOME, "oauth") : (0, import_node_path8.join)((0, import_node_os8.homedir)(), ".aware", "oauth");
52907
53004
  }
52908
53005
  function isUpgradableLegacyProfile(existing, preset) {
52909
53006
  if (existing.startsWith(MANAGED_HEADER)) return false;
@@ -52917,15 +53014,15 @@ function ensureManagedProfile(id) {
52917
53014
  const preset = OAUTH_PRESETS[id];
52918
53015
  if (!preset) return "not-managed";
52919
53016
  const dir = oauthDir();
52920
- const file = (0, import_node_path7.join)(dir, `${id}.yaml`);
52921
- const existing = (0, import_node_fs8.existsSync)(file) ? (0, import_node_fs8.readFileSync)(file, "utf8") : null;
53017
+ const file = (0, import_node_path8.join)(dir, `${id}.yaml`);
53018
+ const existing = (0, import_node_fs9.existsSync)(file) ? (0, import_node_fs9.readFileSync)(file, "utf8") : null;
52922
53019
  if (existing !== null && !existing.startsWith(MANAGED_HEADER) && !isUpgradableLegacyProfile(existing, preset)) {
52923
53020
  return "skipped";
52924
53021
  }
52925
53022
  const desired = managedProfileYaml(preset);
52926
53023
  if (existing === desired) return "unchanged";
52927
- (0, import_node_fs8.mkdirSync)(dir, { recursive: true });
52928
- (0, import_node_fs8.writeFileSync)(file, desired, "utf8");
53024
+ (0, import_node_fs9.mkdirSync)(dir, { recursive: true });
53025
+ (0, import_node_fs9.writeFileSync)(file, desired, "utf8");
52929
53026
  return "written";
52930
53027
  }
52931
53028
  function isPortBindable(port, host = "127.0.0.1") {
@@ -52937,7 +53034,7 @@ function isPortBindable(port, host = "127.0.0.1") {
52937
53034
  }
52938
53035
 
52939
53036
  // bake.ts
52940
- var import_yaml2 = __toESM(require_dist6(), 1);
53037
+ var import_yaml3 = __toESM(require_dist6(), 1);
52941
53038
  function buildExposedCommands(inputs) {
52942
53039
  const runInputs = {};
52943
53040
  for (const inp of inputs) {
@@ -52954,7 +53051,7 @@ function buildExposedCommands(inputs) {
52954
53051
  };
52955
53052
  }
52956
53053
  function bakeFloSource(source, inputs) {
52957
- const doc2 = (0, import_yaml2.parseDocument)(source);
53054
+ const doc2 = (0, import_yaml3.parseDocument)(source);
52958
53055
  if (doc2.errors.length > 0) {
52959
53056
  throw new Error(`bake: source is not valid YAML: ${doc2.errors[0]?.message ?? "parse error"}`);
52960
53057
  }
@@ -53118,16 +53215,16 @@ function extractReportHtml(events, appId) {
53118
53215
  }
53119
53216
 
53120
53217
  // steel-output-path.ts
53121
- var import_node_path8 = require("node:path");
53122
- var import_node_os8 = require("node:os");
53123
- var import_node_fs9 = require("node:fs");
53218
+ var import_node_path9 = require("node:path");
53219
+ var import_node_os9 = require("node:os");
53220
+ var import_node_fs10 = require("node:fs");
53124
53221
  function steelIfcRunInputs(id, inputs) {
53125
53222
  if (id !== "steel-to-ifc") return inputs;
53126
53223
  const op = inputs?.output_path;
53127
53224
  if (op != null && op !== "" && op !== "steel-from-drawings.ifc") return inputs;
53128
- const dl = (0, import_node_path8.join)((0, import_node_os8.homedir)(), "Downloads");
53129
- const dir = (0, import_node_fs9.existsSync)(dl) ? dl : (0, import_node_os8.homedir)();
53130
- return { ...inputs ?? {}, output_path: (0, import_node_path8.join)(dir, "steel-from-drawings.ifc") };
53225
+ const dl = (0, import_node_path9.join)((0, import_node_os9.homedir)(), "Downloads");
53226
+ const dir = (0, import_node_fs10.existsSync)(dl) ? dl : (0, import_node_os9.homedir)();
53227
+ return { ...inputs ?? {}, output_path: (0, import_node_path9.join)(dir, "steel-from-drawings.ifc") };
53131
53228
  }
53132
53229
 
53133
53230
  // index.ts
@@ -53175,16 +53272,16 @@ function buildPreview(m, sourceKind, sourceRef, stagedRef) {
53175
53272
  }
53176
53273
 
53177
53274
  // graft-manifest-reader.ts
53178
- var import_node_fs10 = require("node:fs");
53179
- var import_node_path9 = require("node:path");
53180
- var import_yaml3 = __toESM(require_dist6(), 1);
53275
+ var import_node_fs11 = require("node:fs");
53276
+ var import_node_path10 = require("node:path");
53277
+ var import_yaml4 = __toESM(require_dist6(), 1);
53181
53278
  var asRecord2 = (v) => v && typeof v === "object" && !Array.isArray(v) ? v : {};
53182
53279
  function readStagedManifest(agentDir) {
53183
- const manifestPath = (0, import_node_path9.join)(agentDir, "manifest.yaml");
53184
- if (!(0, import_node_fs10.existsSync)(manifestPath)) return null;
53280
+ const manifestPath = (0, import_node_path10.join)(agentDir, "manifest.yaml");
53281
+ if (!(0, import_node_fs11.existsSync)(manifestPath)) return null;
53185
53282
  let doc2;
53186
53283
  try {
53187
- doc2 = asRecord2((0, import_yaml3.parse)((0, import_node_fs10.readFileSync)(manifestPath, "utf8")));
53284
+ doc2 = asRecord2((0, import_yaml4.parse)((0, import_node_fs11.readFileSync)(manifestPath, "utf8")));
53188
53285
  } catch {
53189
53286
  return null;
53190
53287
  }
@@ -53214,10 +53311,10 @@ function readStagedManifest(agentDir) {
53214
53311
  }
53215
53312
  let skillCount = Array.isArray(doc2.skills) ? doc2.skills.length : 0;
53216
53313
  if (!skillCount) {
53217
- const skillsDir = (0, import_node_path9.join)(agentDir, "skills");
53218
- if ((0, import_node_fs10.existsSync)(skillsDir)) {
53314
+ const skillsDir = (0, import_node_path10.join)(agentDir, "skills");
53315
+ if ((0, import_node_fs11.existsSync)(skillsDir)) {
53219
53316
  try {
53220
- skillCount = (0, import_node_fs10.readdirSync)(skillsDir).filter((f) => f.endsWith(".md")).length;
53317
+ skillCount = (0, import_node_fs11.readdirSync)(skillsDir).filter((f) => f.endsWith(".md")).length;
53221
53318
  } catch {
53222
53319
  }
53223
53320
  }
@@ -53231,7 +53328,7 @@ function readStagedManifest(agentDir) {
53231
53328
  }
53232
53329
 
53233
53330
  // graft-stage-registry.ts
53234
- var import_node_fs11 = require("node:fs");
53331
+ var import_node_fs12 = require("node:fs");
53235
53332
  var TTL_MS = 30 * 60 * 1e3;
53236
53333
  var registry = /* @__PURE__ */ new Map();
53237
53334
  function registerStage(token, tempDir, agentId) {
@@ -53253,7 +53350,7 @@ function evict(token) {
53253
53350
  clearTimeout(e.timer);
53254
53351
  registry.delete(token);
53255
53352
  try {
53256
- (0, import_node_fs11.rmSync)(e.tempDir, { recursive: true, force: true });
53353
+ (0, import_node_fs12.rmSync)(e.tempDir, { recursive: true, force: true });
53257
53354
  } catch {
53258
53355
  }
53259
53356
  }
@@ -53262,8 +53359,8 @@ function clearAllStages() {
53262
53359
  }
53263
53360
 
53264
53361
  // graft-commit.ts
53265
- var import_node_fs12 = require("node:fs");
53266
- var import_node_path10 = require("node:path");
53362
+ var import_node_fs13 = require("node:fs");
53363
+ var import_node_path11 = require("node:path");
53267
53364
  var GraftCommitError = class extends Error {
53268
53365
  constructor(message, code) {
53269
53366
  super(message);
@@ -53273,34 +53370,34 @@ var GraftCommitError = class extends Error {
53273
53370
  code;
53274
53371
  };
53275
53372
  function commitStaged(tempDir, agentId, targetAgentsDir, force) {
53276
- const staged = (0, import_node_path10.join)(tempDir, "agents", agentId);
53277
- const target = (0, import_node_path10.join)(targetAgentsDir, agentId);
53278
- if ((0, import_node_fs12.existsSync)(target)) {
53373
+ const staged = (0, import_node_path11.join)(tempDir, "agents", agentId);
53374
+ const target = (0, import_node_path11.join)(targetAgentsDir, agentId);
53375
+ if ((0, import_node_fs13.existsSync)(target)) {
53279
53376
  if (!force) throw new GraftCommitError(`an agent named "${agentId}" is already installed`, "collision");
53280
- (0, import_node_fs12.rmSync)(target, { recursive: true, force: true });
53377
+ (0, import_node_fs13.rmSync)(target, { recursive: true, force: true });
53281
53378
  }
53282
- (0, import_node_fs12.mkdirSync)(targetAgentsDir, { recursive: true });
53379
+ (0, import_node_fs13.mkdirSync)(targetAgentsDir, { recursive: true });
53283
53380
  try {
53284
- (0, import_node_fs12.renameSync)(staged, target);
53381
+ (0, import_node_fs13.renameSync)(staged, target);
53285
53382
  } catch {
53286
- (0, import_node_fs12.cpSync)(staged, target, { recursive: true });
53383
+ (0, import_node_fs13.cpSync)(staged, target, { recursive: true });
53287
53384
  }
53288
- (0, import_node_fs12.rmSync)(tempDir, { recursive: true, force: true });
53385
+ (0, import_node_fs13.rmSync)(tempDir, { recursive: true, force: true });
53289
53386
  return { agentId };
53290
53387
  }
53291
53388
  function matchAssemblies(globOrDir) {
53292
53389
  let dir;
53293
53390
  let pattern;
53294
- if ((0, import_node_fs12.existsSync)(globOrDir) && (0, import_node_fs12.statSync)(globOrDir).isDirectory()) {
53391
+ if ((0, import_node_fs13.existsSync)(globOrDir) && (0, import_node_fs13.statSync)(globOrDir).isDirectory()) {
53295
53392
  dir = globOrDir;
53296
53393
  pattern = "*.dll";
53297
53394
  } else {
53298
- dir = (0, import_node_path10.dirname)(globOrDir);
53299
- pattern = (0, import_node_path10.basename)(globOrDir);
53395
+ dir = (0, import_node_path11.dirname)(globOrDir);
53396
+ pattern = (0, import_node_path11.basename)(globOrDir);
53300
53397
  }
53301
- if (!dir || !(0, import_node_fs12.existsSync)(dir) || !(0, import_node_fs12.statSync)(dir).isDirectory()) return [];
53398
+ if (!dir || !(0, import_node_fs13.existsSync)(dir) || !(0, import_node_fs13.statSync)(dir).isDirectory()) return [];
53302
53399
  const re = globToRegExp(pattern);
53303
- return (0, import_node_fs12.readdirSync)(dir).filter((f) => re.test(f)).sort();
53400
+ return (0, import_node_fs13.readdirSync)(dir).filter((f) => re.test(f)).sort();
53304
53401
  }
53305
53402
  function globToRegExp(p) {
53306
53403
  const esc2 = p.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".");
@@ -53309,24 +53406,24 @@ function globToRegExp(p) {
53309
53406
 
53310
53407
  // floless-store.ts
53311
53408
  var import_node_crypto4 = require("node:crypto");
53312
- var import_node_fs13 = require("node:fs");
53313
- var import_node_os9 = require("node:os");
53314
- var import_node_path11 = require("node:path");
53315
- var ROOT2 = process.env.FLOLESS_HOME ?? (0, import_node_path11.join)((0, import_node_os9.homedir)(), ".floless");
53316
- var TEMPLATES_FILE = (0, import_node_path11.join)(ROOT2, "templates.json");
53317
- var REQUESTS_DIR = (0, import_node_path11.join)(ROOT2, "requests");
53409
+ var import_node_fs14 = require("node:fs");
53410
+ var import_node_os10 = require("node:os");
53411
+ var import_node_path12 = require("node:path");
53412
+ var ROOT2 = process.env.FLOLESS_HOME ?? (0, import_node_path12.join)((0, import_node_os10.homedir)(), ".floless");
53413
+ var TEMPLATES_FILE = (0, import_node_path12.join)(ROOT2, "templates.json");
53414
+ var REQUESTS_DIR = (0, import_node_path12.join)(ROOT2, "requests");
53318
53415
  function ensureRoot() {
53319
- if (!(0, import_node_fs13.existsSync)(ROOT2)) (0, import_node_fs13.mkdirSync)(ROOT2, { recursive: true });
53416
+ if (!(0, import_node_fs14.existsSync)(ROOT2)) (0, import_node_fs14.mkdirSync)(ROOT2, { recursive: true });
53320
53417
  }
53321
53418
  function withinRequestsDir(p) {
53322
- const base = (0, import_node_path11.resolve)(REQUESTS_DIR);
53323
- const full = (0, import_node_path11.resolve)(p);
53324
- return full === base || full.startsWith(base + import_node_path11.sep);
53419
+ const base = (0, import_node_path12.resolve)(REQUESTS_DIR);
53420
+ const full = (0, import_node_path12.resolve)(p);
53421
+ return full === base || full.startsWith(base + import_node_path12.sep);
53325
53422
  }
53326
53423
  function listTemplates() {
53327
- if (!(0, import_node_fs13.existsSync)(TEMPLATES_FILE)) return [];
53424
+ if (!(0, import_node_fs14.existsSync)(TEMPLATES_FILE)) return [];
53328
53425
  try {
53329
- const parsed = JSON.parse((0, import_node_fs13.readFileSync)(TEMPLATES_FILE, "utf8"));
53426
+ const parsed = JSON.parse((0, import_node_fs14.readFileSync)(TEMPLATES_FILE, "utf8"));
53330
53427
  return Array.isArray(parsed) ? parsed : [];
53331
53428
  } catch {
53332
53429
  return [];
@@ -53335,8 +53432,8 @@ function listTemplates() {
53335
53432
  function writeTemplates(list) {
53336
53433
  ensureRoot();
53337
53434
  const tmp = `${TEMPLATES_FILE}.${process.pid}.tmp`;
53338
- (0, import_node_fs13.writeFileSync)(tmp, JSON.stringify(list, null, 2));
53339
- (0, import_node_fs13.renameSync)(tmp, TEMPLATES_FILE);
53435
+ (0, import_node_fs14.writeFileSync)(tmp, JSON.stringify(list, null, 2));
53436
+ (0, import_node_fs14.renameSync)(tmp, TEMPLATES_FILE);
53340
53437
  }
53341
53438
  function addTemplate(input) {
53342
53439
  const list = listTemplates();
@@ -53381,13 +53478,13 @@ function updateTemplate(id, patch) {
53381
53478
  }
53382
53479
  function addRequest(req, decoded = []) {
53383
53480
  ensureRoot();
53384
- if (!(0, import_node_fs13.existsSync)(REQUESTS_DIR)) (0, import_node_fs13.mkdirSync)(REQUESTS_DIR, { recursive: true });
53481
+ if (!(0, import_node_fs14.existsSync)(REQUESTS_DIR)) (0, import_node_fs14.mkdirSync)(REQUESTS_DIR, { recursive: true });
53385
53482
  const id = (0, import_node_crypto4.randomUUID)();
53386
53483
  const createdAt = (/* @__PURE__ */ new Date()).toISOString();
53387
53484
  const base = `${createdAt.replace(/[:.]/g, "-")}__${id}`;
53388
53485
  const snapshots = decoded.map((d, i) => {
53389
- const p = (0, import_node_path11.join)(REQUESTS_DIR, `${base}__snap${i + 1}.${d.ext}`);
53390
- (0, import_node_fs13.writeFileSync)(p, d.buf);
53486
+ const p = (0, import_node_path12.join)(REQUESTS_DIR, `${base}__snap${i + 1}.${d.ext}`);
53487
+ (0, import_node_fs14.writeFileSync)(p, d.buf);
53391
53488
  return p;
53392
53489
  });
53393
53490
  const full = {
@@ -53397,55 +53494,55 @@ function addRequest(req, decoded = []) {
53397
53494
  ...req,
53398
53495
  ...snapshots.length ? { snapshots } : {}
53399
53496
  };
53400
- (0, import_node_fs13.writeFileSync)((0, import_node_path11.join)(REQUESTS_DIR, `${base}.json`), JSON.stringify(full, null, 2));
53497
+ (0, import_node_fs14.writeFileSync)((0, import_node_path12.join)(REQUESTS_DIR, `${base}.json`), JSON.stringify(full, null, 2));
53401
53498
  return full;
53402
53499
  }
53403
53500
  function listRequests() {
53404
- if (!(0, import_node_fs13.existsSync)(REQUESTS_DIR)) return [];
53405
- return (0, import_node_fs13.readdirSync)(REQUESTS_DIR).filter((f) => f.endsWith(".json")).sort().map((f) => {
53501
+ if (!(0, import_node_fs14.existsSync)(REQUESTS_DIR)) return [];
53502
+ return (0, import_node_fs14.readdirSync)(REQUESTS_DIR).filter((f) => f.endsWith(".json")).sort().map((f) => {
53406
53503
  try {
53407
- return JSON.parse((0, import_node_fs13.readFileSync)((0, import_node_path11.join)(REQUESTS_DIR, f), "utf8"));
53504
+ return JSON.parse((0, import_node_fs14.readFileSync)((0, import_node_path12.join)(REQUESTS_DIR, f), "utf8"));
53408
53505
  } catch {
53409
53506
  return null;
53410
53507
  }
53411
53508
  }).filter((r) => r !== null);
53412
53509
  }
53413
53510
  function deleteRequest(id) {
53414
- if (!(0, import_node_fs13.existsSync)(REQUESTS_DIR)) return false;
53415
- const file = (0, import_node_fs13.readdirSync)(REQUESTS_DIR).find((f) => f.endsWith(`__${id}.json`));
53511
+ if (!(0, import_node_fs14.existsSync)(REQUESTS_DIR)) return false;
53512
+ const file = (0, import_node_fs14.readdirSync)(REQUESTS_DIR).find((f) => f.endsWith(`__${id}.json`));
53416
53513
  if (!file) return false;
53417
53514
  try {
53418
- const parsed = JSON.parse((0, import_node_fs13.readFileSync)((0, import_node_path11.join)(REQUESTS_DIR, file), "utf8"));
53515
+ const parsed = JSON.parse((0, import_node_fs14.readFileSync)((0, import_node_path12.join)(REQUESTS_DIR, file), "utf8"));
53419
53516
  for (const p of parsed.snapshots ?? []) {
53420
53517
  if (!withinRequestsDir(p)) continue;
53421
53518
  try {
53422
- (0, import_node_fs13.rmSync)(p);
53519
+ (0, import_node_fs14.rmSync)(p);
53423
53520
  } catch {
53424
53521
  }
53425
53522
  }
53426
53523
  } catch {
53427
53524
  }
53428
- (0, import_node_fs13.rmSync)((0, import_node_path11.join)(REQUESTS_DIR, file));
53525
+ (0, import_node_fs14.rmSync)((0, import_node_path12.join)(REQUESTS_DIR, file));
53429
53526
  return true;
53430
53527
  }
53431
53528
  function clearRequests() {
53432
- if (!(0, import_node_fs13.existsSync)(REQUESTS_DIR)) return 0;
53433
- const allFiles = (0, import_node_fs13.readdirSync)(REQUESTS_DIR);
53529
+ if (!(0, import_node_fs14.existsSync)(REQUESTS_DIR)) return 0;
53530
+ const allFiles = (0, import_node_fs14.readdirSync)(REQUESTS_DIR);
53434
53531
  const jsonFiles = allFiles.filter((f) => f.endsWith(".json"));
53435
53532
  for (const f of allFiles) {
53436
53533
  try {
53437
- (0, import_node_fs13.rmSync)((0, import_node_path11.join)(REQUESTS_DIR, f));
53534
+ (0, import_node_fs14.rmSync)((0, import_node_path12.join)(REQUESTS_DIR, f));
53438
53535
  } catch {
53439
53536
  }
53440
53537
  }
53441
53538
  return jsonFiles.length;
53442
53539
  }
53443
53540
  function snapshotPathFor(id, n) {
53444
- if (!(0, import_node_fs13.existsSync)(REQUESTS_DIR)) return null;
53445
- const file = (0, import_node_fs13.readdirSync)(REQUESTS_DIR).find((f) => f.endsWith(`__${id}.json`));
53541
+ if (!(0, import_node_fs14.existsSync)(REQUESTS_DIR)) return null;
53542
+ const file = (0, import_node_fs14.readdirSync)(REQUESTS_DIR).find((f) => f.endsWith(`__${id}.json`));
53446
53543
  if (!file) return null;
53447
53544
  try {
53448
- const parsed = JSON.parse((0, import_node_fs13.readFileSync)((0, import_node_path11.join)(REQUESTS_DIR, file), "utf8"));
53545
+ const parsed = JSON.parse((0, import_node_fs14.readFileSync)((0, import_node_path12.join)(REQUESTS_DIR, file), "utf8"));
53449
53546
  const cand = parsed.snapshots?.[n] ?? null;
53450
53547
  return cand && withinRequestsDir(cand) ? cand : null;
53451
53548
  } catch {
@@ -53482,15 +53579,15 @@ function decodeSnapshots(inputs) {
53482
53579
 
53483
53580
  // visual-input-store.ts
53484
53581
  var import_node_crypto5 = require("node:crypto");
53485
- var import_node_fs14 = require("node:fs");
53486
- var import_node_os10 = require("node:os");
53487
- var import_node_path12 = require("node:path");
53582
+ var import_node_fs15 = require("node:fs");
53583
+ var import_node_os11 = require("node:os");
53584
+ var import_node_path13 = require("node:path");
53488
53585
  var MAX_BYTES3 = 25 * 1024 * 1024;
53489
53586
  var VisualInputError = class extends Error {
53490
53587
  };
53491
53588
  function inputsDir() {
53492
- const root = process.env.FLOLESS_HOME ?? (0, import_node_path12.join)((0, import_node_os10.homedir)(), ".floless");
53493
- return (0, import_node_path12.join)(root, "inputs");
53589
+ const root = process.env.FLOLESS_HOME ?? (0, import_node_path13.join)((0, import_node_os11.homedir)(), ".floless");
53590
+ return (0, import_node_path13.join)(root, "inputs");
53494
53591
  }
53495
53592
  function sniffExt2(buf) {
53496
53593
  if (buf.length >= 8 && buf[0] === 137 && buf[1] === 80 && buf[2] === 78 && buf[3] === 71) return "png";
@@ -53502,7 +53599,7 @@ function sniffExt2(buf) {
53502
53599
  var RESERVED = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\..*)?$/i;
53503
53600
  function safeSegment(s) {
53504
53601
  if (!s || s === "." || s.includes("..")) return false;
53505
- if (s.includes("/") || s.includes("\\") || s.includes(import_node_path12.sep)) return false;
53602
+ if (s.includes("/") || s.includes("\\") || s.includes(import_node_path13.sep)) return false;
53506
53603
  for (let i = 0; i < s.length; i++) {
53507
53604
  const c = s.charCodeAt(i);
53508
53605
  if (c < 32 || c === 58) return false;
@@ -53520,51 +53617,51 @@ function storeVisualInput(appId, dataUrl) {
53520
53617
  const ext = sniffExt2(buf);
53521
53618
  if (!ext) throw new VisualInputError("visual input must be PNG, JPEG, WebP, or PDF");
53522
53619
  const sha2562 = (0, import_node_crypto5.createHash)("sha256").update(buf).digest("hex");
53523
- const dir = (0, import_node_path12.join)(inputsDir(), appId);
53524
- const path = (0, import_node_path12.join)(dir, `${sha2562}.${ext}`);
53525
- const root = (0, import_node_path12.resolve)(inputsDir());
53526
- const target = (0, import_node_path12.resolve)(path);
53527
- if (target !== root && !target.startsWith(root + import_node_path12.sep)) {
53620
+ const dir = (0, import_node_path13.join)(inputsDir(), appId);
53621
+ const path = (0, import_node_path13.join)(dir, `${sha2562}.${ext}`);
53622
+ const root = (0, import_node_path13.resolve)(inputsDir());
53623
+ const target = (0, import_node_path13.resolve)(path);
53624
+ if (target !== root && !target.startsWith(root + import_node_path13.sep)) {
53528
53625
  throw new VisualInputError("refusing to write outside the inputs root");
53529
53626
  }
53530
- (0, import_node_fs14.mkdirSync)(dir, { recursive: true });
53531
- if (!(0, import_node_fs14.existsSync)(path)) {
53627
+ (0, import_node_fs15.mkdirSync)(dir, { recursive: true });
53628
+ if (!(0, import_node_fs15.existsSync)(path)) {
53532
53629
  const tmp = `${path}.tmp`;
53533
- (0, import_node_fs14.writeFileSync)(tmp, buf);
53534
- (0, import_node_fs14.renameSync)(tmp, path);
53630
+ (0, import_node_fs15.writeFileSync)(tmp, buf);
53631
+ (0, import_node_fs15.renameSync)(tmp, path);
53535
53632
  }
53536
- return { path, ext, bytes: (0, import_node_fs14.statSync)(path).size, sha256: sha2562 };
53633
+ return { path, ext, bytes: (0, import_node_fs15.statSync)(path).size, sha256: sha2562 };
53537
53634
  }
53538
53635
  function renameVisualInputs(oldId, newId) {
53539
53636
  if (!safeSegment(oldId) || !safeSegment(newId)) throw new VisualInputError("invalid app id");
53540
- const from = (0, import_node_path12.join)(inputsDir(), oldId);
53541
- if (!(0, import_node_fs14.existsSync)(from)) return;
53542
- const to = (0, import_node_path12.join)(inputsDir(), newId);
53543
- if ((0, import_node_fs14.existsSync)(to)) (0, import_node_fs14.rmSync)(to, { recursive: true, force: true });
53544
- (0, import_node_fs14.mkdirSync)(inputsDir(), { recursive: true });
53545
- (0, import_node_fs14.renameSync)(from, to);
53637
+ const from = (0, import_node_path13.join)(inputsDir(), oldId);
53638
+ if (!(0, import_node_fs15.existsSync)(from)) return;
53639
+ const to = (0, import_node_path13.join)(inputsDir(), newId);
53640
+ if ((0, import_node_fs15.existsSync)(to)) (0, import_node_fs15.rmSync)(to, { recursive: true, force: true });
53641
+ (0, import_node_fs15.mkdirSync)(inputsDir(), { recursive: true });
53642
+ (0, import_node_fs15.renameSync)(from, to);
53546
53643
  }
53547
53644
  function copyVisualInputs(srcId, newId) {
53548
53645
  if (!safeSegment(srcId) || !safeSegment(newId)) throw new VisualInputError("invalid app id");
53549
- const from = (0, import_node_path12.join)(inputsDir(), srcId);
53550
- if (!(0, import_node_fs14.existsSync)(from)) return;
53551
- (0, import_node_fs14.cpSync)(from, (0, import_node_path12.join)(inputsDir(), newId), { recursive: true });
53646
+ const from = (0, import_node_path13.join)(inputsDir(), srcId);
53647
+ if (!(0, import_node_fs15.existsSync)(from)) return;
53648
+ (0, import_node_fs15.cpSync)(from, (0, import_node_path13.join)(inputsDir(), newId), { recursive: true });
53552
53649
  }
53553
53650
  function deleteVisualInputs(id) {
53554
53651
  if (!safeSegment(id)) throw new VisualInputError("invalid app id");
53555
- const dir = (0, import_node_path12.join)(inputsDir(), id);
53556
- if ((0, import_node_fs14.existsSync)(dir)) (0, import_node_fs14.rmSync)(dir, { recursive: true, force: true });
53652
+ const dir = (0, import_node_path13.join)(inputsDir(), id);
53653
+ if ((0, import_node_fs15.existsSync)(dir)) (0, import_node_fs15.rmSync)(dir, { recursive: true, force: true });
53557
53654
  }
53558
53655
 
53559
53656
  // contract-store.ts
53560
- var import_node_fs16 = require("node:fs");
53561
- var import_node_path14 = require("node:path");
53562
- var import_node_os11 = require("node:os");
53657
+ var import_node_fs17 = require("node:fs");
53658
+ var import_node_path15 = require("node:path");
53659
+ var import_node_os12 = require("node:os");
53563
53660
 
53564
53661
  // contract-schema.ts
53565
- var import_node_fs15 = require("node:fs");
53566
- var import_node_path13 = require("node:path");
53567
- var import_node_url = require("node:url");
53662
+ var import_node_fs16 = require("node:fs");
53663
+ var import_node_path14 = require("node:path");
53664
+ var import_node_url2 = require("node:url");
53568
53665
  function validate(doc2, schema) {
53569
53666
  const errors = [];
53570
53667
  walk(doc2, schema, schema, "$", errors);
@@ -53664,16 +53761,16 @@ function walk(value, node, root, path, errors) {
53664
53761
  var _cached = null;
53665
53762
  function loadSteelTakeoffSchema() {
53666
53763
  if (_cached) return _cached;
53667
- const here = (0, import_node_path13.dirname)((0, import_node_url.fileURLToPath)(__import_meta_url));
53764
+ const here2 = (0, import_node_path14.dirname)((0, import_node_url2.fileURLToPath)(__import_meta_url));
53668
53765
  const candidates = [
53669
- (0, import_node_path13.join)(here, "..", "schemas", "steel.takeoff.v1.schema.json"),
53766
+ (0, import_node_path14.join)(here2, "..", "schemas", "steel.takeoff.v1.schema.json"),
53670
53767
  // dev: server/ next to schemas/
53671
- (0, import_node_path13.join)(here, "schemas", "steel.takeoff.v1.schema.json")
53768
+ (0, import_node_path14.join)(here2, "schemas", "steel.takeoff.v1.schema.json")
53672
53769
  // bundled: dist/ holds ./schemas
53673
53770
  ];
53674
53771
  for (const p of candidates) {
53675
53772
  try {
53676
- const text = (0, import_node_fs15.readFileSync)(p, "utf8");
53773
+ const text = (0, import_node_fs16.readFileSync)(p, "utf8");
53677
53774
  _cached = JSON.parse(text);
53678
53775
  return _cached;
53679
53776
  } catch (err) {
@@ -53689,20 +53786,20 @@ function validateSteelTakeoff(doc2) {
53689
53786
  // contract-store.ts
53690
53787
  var ContractError = class extends Error {
53691
53788
  };
53692
- var ROOT3 = process.env.FLOLESS_HOME ?? (0, import_node_path14.join)((0, import_node_os11.homedir)(), ".floless");
53693
- var DIR = (0, import_node_path14.join)(ROOT3, "contracts");
53789
+ var ROOT3 = process.env.FLOLESS_HOME ?? (0, import_node_path15.join)((0, import_node_os12.homedir)(), ".floless");
53790
+ var DIR = (0, import_node_path15.join)(ROOT3, "contracts");
53694
53791
  function safeId(appId) {
53695
53792
  if (!/^[a-z0-9][a-z0-9._-]*$/i.test(appId)) throw new ContractError(`invalid appId: ${appId}`);
53696
53793
  return appId;
53697
53794
  }
53698
53795
  function contractPath(appId) {
53699
- return (0, import_node_path14.join)(DIR, `${safeId(appId)}.json`);
53796
+ return (0, import_node_path15.join)(DIR, `${safeId(appId)}.json`);
53700
53797
  }
53701
53798
  function readContract(appId) {
53702
53799
  const p = contractPath(appId);
53703
- if (!(0, import_node_fs16.existsSync)(p)) return null;
53800
+ if (!(0, import_node_fs17.existsSync)(p)) return null;
53704
53801
  try {
53705
- return JSON.parse((0, import_node_fs16.readFileSync)(p, "utf8"));
53802
+ return JSON.parse((0, import_node_fs17.readFileSync)(p, "utf8"));
53706
53803
  } catch (e) {
53707
53804
  console.warn(`readContract: ignoring unreadable contract at ${p}: ${e instanceof Error ? e.message : e}`);
53708
53805
  return null;
@@ -53715,8 +53812,8 @@ function writeContract(appId, doc2) {
53715
53812
  const first = res.errors.slice(0, 5).map((e) => `${e.path}: ${e.message}`).join("; ");
53716
53813
  throw new ContractError(`contract failed schema validation \u2014 ${first}`);
53717
53814
  }
53718
- if (!(0, import_node_fs16.existsSync)(DIR)) (0, import_node_fs16.mkdirSync)(DIR, { recursive: true });
53719
- (0, import_node_fs16.writeFileSync)(p, JSON.stringify(doc2));
53815
+ if (!(0, import_node_fs17.existsSync)(DIR)) (0, import_node_fs17.mkdirSync)(DIR, { recursive: true });
53816
+ (0, import_node_fs17.writeFileSync)(p, JSON.stringify(doc2));
53720
53817
  }
53721
53818
 
53722
53819
  // contract-resolve.ts
@@ -53738,21 +53835,22 @@ function readContractForApp(appId, readAppFn = readApp) {
53738
53835
  }
53739
53836
 
53740
53837
  // contract-bake.ts
53741
- var import_node_fs17 = require("node:fs");
53742
- var import_yaml4 = __toESM(require_dist6(), 1);
53838
+ var import_node_fs18 = require("node:fs");
53839
+ var import_yaml5 = __toESM(require_dist6(), 1);
53743
53840
  function bakeContractIntoApp(sourcePath, contract) {
53744
- const doc2 = (0, import_yaml4.parseDocument)((0, import_node_fs17.readFileSync)(sourcePath, "utf8"));
53841
+ const doc2 = (0, import_yaml5.parseDocument)((0, import_node_fs18.readFileSync)(sourcePath, "utf8"));
53745
53842
  if (doc2.errors.length > 0) {
53746
53843
  throw new Error(`contract bake: source is not valid YAML: ${doc2.errors[0]?.message ?? "parse error"}`);
53747
53844
  }
53748
53845
  const seq = doc2.get("nodes");
53749
- const items = (0, import_yaml4.isSeq)(seq) ? seq.items : [];
53750
- const nodeOf = (it) => (0, import_yaml4.isMap)(it) ? it.toJSON() : null;
53846
+ const items = (0, import_yaml5.isSeq)(seq) ? seq.items : [];
53847
+ const nodeOf = (it) => (0, import_yaml5.isMap)(it) ? it.toJSON() : null;
53751
53848
  let idx = items.findIndex((it) => nodeOf(it)?.config?.contract === contract.type);
53752
53849
  if (idx < 0) idx = items.findIndex((it) => nodeOf(it)?.agent === "steel-takeoff-us");
53753
53850
  if (idx < 0) throw new Error("no contract-emitting node to bake the contract into");
53754
53851
  doc2.setIn(["nodes", idx, "config", "contract"], contract.type);
53755
53852
  const baked = { ...contract };
53853
+ delete baked.dims3d;
53756
53854
  if (Array.isArray(contract.plans)) {
53757
53855
  baked.plans = contract.plans.map((p) => {
53758
53856
  if (p && typeof p === "object") {
@@ -53770,7 +53868,7 @@ function bakeContractIntoApp(sourcePath, contract) {
53770
53868
  baked.filter = { ...filter, page };
53771
53869
  }
53772
53870
  doc2.setIn(["nodes", idx, "config", "takeoff"], baked);
53773
- (0, import_node_fs17.writeFileSync)(sourcePath, doc2.toString());
53871
+ (0, import_node_fs18.writeFileSync)(sourcePath, doc2.toString());
53774
53872
  }
53775
53873
 
53776
53874
  // contract-to-scene.ts
@@ -53867,37 +53965,37 @@ function contractToScene(contractInput) {
53867
53965
  }
53868
53966
 
53869
53967
  // scene-bake.ts
53870
- var import_node_fs18 = require("node:fs");
53871
- var import_node_path15 = require("node:path");
53872
- var import_yaml5 = __toESM(require_dist6(), 1);
53968
+ var import_node_fs19 = require("node:fs");
53969
+ var import_node_path16 = require("node:path");
53970
+ var import_yaml6 = __toESM(require_dist6(), 1);
53873
53971
  function bakeSceneIntoApp(sourcePath, scene, agent = "viewer-3d") {
53874
- const doc2 = (0, import_yaml5.parseDocument)((0, import_node_fs18.readFileSync)(sourcePath, "utf8"));
53972
+ const doc2 = (0, import_yaml6.parseDocument)((0, import_node_fs19.readFileSync)(sourcePath, "utf8"));
53875
53973
  if (doc2.errors.length > 0) {
53876
53974
  throw new Error(`scene bake: source is not valid YAML: ${doc2.errors[0]?.message ?? "parse error"}`);
53877
53975
  }
53878
53976
  const seq = doc2.get("nodes");
53879
- const items = (0, import_yaml5.isSeq)(seq) ? seq.items : [];
53880
- const idx = items.findIndex((it) => ((0, import_yaml5.isMap)(it) ? it.toJSON() : null)?.agent === agent);
53977
+ const items = (0, import_yaml6.isSeq)(seq) ? seq.items : [];
53978
+ const idx = items.findIndex((it) => ((0, import_yaml6.isMap)(it) ? it.toJSON() : null)?.agent === agent);
53881
53979
  if (idx < 0) throw new Error(`no ${agent} render node to bake the scene into`);
53882
53980
  doc2.setIn(["nodes", idx, "config", "scene"], scene);
53883
- (0, import_node_fs18.writeFileSync)(sourcePath, doc2.toString());
53981
+ (0, import_node_fs19.writeFileSync)(sourcePath, doc2.toString());
53884
53982
  }
53885
53983
  function bakeNodeConfigById(sourcePath, nodeId, patch) {
53886
- const doc2 = (0, import_yaml5.parseDocument)((0, import_node_fs18.readFileSync)(sourcePath, "utf8"));
53984
+ const doc2 = (0, import_yaml6.parseDocument)((0, import_node_fs19.readFileSync)(sourcePath, "utf8"));
53887
53985
  if (doc2.errors.length > 0) {
53888
53986
  throw new Error(`node bake: source is not valid YAML: ${doc2.errors[0]?.message ?? "parse error"}`);
53889
53987
  }
53890
53988
  const seq = doc2.get("nodes");
53891
- const items = (0, import_yaml5.isSeq)(seq) ? seq.items : [];
53892
- const idx = items.findIndex((it) => ((0, import_yaml5.isMap)(it) ? it.toJSON() : null)?.id === nodeId);
53989
+ const items = (0, import_yaml6.isSeq)(seq) ? seq.items : [];
53990
+ const idx = items.findIndex((it) => ((0, import_yaml6.isMap)(it) ? it.toJSON() : null)?.id === nodeId);
53893
53991
  if (idx < 0) throw new Error(`no node with id "${nodeId}"`);
53894
53992
  for (const [key, value] of Object.entries(patch)) doc2.setIn(["nodes", idx, "config", key], value);
53895
- (0, import_node_fs18.writeFileSync)(sourcePath, doc2.toString());
53993
+ (0, import_node_fs19.writeFileSync)(sourcePath, doc2.toString());
53896
53994
  }
53897
53995
  function writeViewer3dApp(dir, appId, scene) {
53898
- (0, import_node_fs18.mkdirSync)(dir, { recursive: true });
53899
- const flo = (0, import_node_path15.join)(dir, `${appId}.flo`);
53900
- (0, import_node_fs18.writeFileSync)(flo, [
53996
+ (0, import_node_fs19.mkdirSync)(dir, { recursive: true });
53997
+ const flo = (0, import_node_path16.join)(dir, `${appId}.flo`);
53998
+ (0, import_node_fs19.writeFileSync)(flo, [
53901
53999
  `app: ${appId}`,
53902
54000
  "version: 0.1.0",
53903
54001
  "display-name: Steel 3D",
@@ -53918,9 +54016,9 @@ function writeViewer3dApp(dir, appId, scene) {
53918
54016
  return flo;
53919
54017
  }
53920
54018
  function writeIfcApp(dir, appId, scene, outputPath) {
53921
- (0, import_node_fs18.mkdirSync)(dir, { recursive: true });
53922
- const flo = (0, import_node_path15.join)(dir, `${appId}.flo`);
53923
- (0, import_node_fs18.writeFileSync)(flo, [
54019
+ (0, import_node_fs19.mkdirSync)(dir, { recursive: true });
54020
+ const flo = (0, import_node_path16.join)(dir, `${appId}.flo`);
54021
+ (0, import_node_fs19.writeFileSync)(flo, [
53924
54022
  `app: ${appId}`,
53925
54023
  "version: 0.1.0",
53926
54024
  "display-name: Steel IFC",
@@ -53943,9 +54041,9 @@ function writeIfcApp(dir, appId, scene, outputPath) {
53943
54041
  return flo;
53944
54042
  }
53945
54043
  function writeTeklaApp(dir, appId, scene, teklaVersion = "2026.0") {
53946
- (0, import_node_fs18.mkdirSync)(dir, { recursive: true });
53947
- const flo = (0, import_node_path15.join)(dir, `${appId}.flo`);
53948
- (0, import_node_fs18.writeFileSync)(flo, [
54044
+ (0, import_node_fs19.mkdirSync)(dir, { recursive: true });
54045
+ const flo = (0, import_node_path16.join)(dir, `${appId}.flo`);
54046
+ (0, import_node_fs19.writeFileSync)(flo, [
53949
54047
  `app: ${appId}`,
53950
54048
  "version: 0.1.0",
53951
54049
  "display-name: Steel to Tekla",
@@ -54322,13 +54420,13 @@ function scoreContract2(contractInput) {
54322
54420
  }
54323
54421
 
54324
54422
  // app-lifecycle.ts
54325
- var import_node_fs21 = require("node:fs");
54326
- var import_node_os13 = require("node:os");
54327
- var import_node_path18 = require("node:path");
54423
+ var import_node_fs22 = require("node:fs");
54424
+ var import_node_os14 = require("node:os");
54425
+ var import_node_path19 = require("node:path");
54328
54426
 
54329
54427
  // routines.ts
54330
- var import_node_fs20 = require("node:fs");
54331
- var import_node_path17 = require("node:path");
54428
+ var import_node_fs21 = require("node:fs");
54429
+ var import_node_path18 = require("node:path");
54332
54430
 
54333
54431
  // sse.ts
54334
54432
  var clients = /* @__PURE__ */ new Set();
@@ -54365,11 +54463,11 @@ function clientCount() {
54365
54463
  }
54366
54464
 
54367
54465
  // trigger-sessions.ts
54368
- var import_node_fs19 = require("node:fs");
54369
- var import_node_os12 = require("node:os");
54370
- var import_node_path16 = require("node:path");
54371
- var import_yaml6 = __toESM(require_dist6(), 1);
54372
- var AGENTS_DIR2 = process.env.AWARE_HOME ? (0, import_node_path16.join)(process.env.AWARE_HOME, "agents") : (0, import_node_path16.join)((0, import_node_os12.homedir)(), ".aware", "agents");
54466
+ var import_node_fs20 = require("node:fs");
54467
+ var import_node_os13 = require("node:os");
54468
+ var import_node_path17 = require("node:path");
54469
+ var import_yaml7 = __toESM(require_dist6(), 1);
54470
+ var AGENTS_DIR2 = process.env.AWARE_HOME ? (0, import_node_path17.join)(process.env.AWARE_HOME, "agents") : (0, import_node_path17.join)((0, import_node_os13.homedir)(), ".aware", "agents");
54373
54471
  function summarizeFire(data) {
54374
54472
  if (!data) return "event";
54375
54473
  const type = typeof data.type === "string" ? data.type : "";
@@ -54386,10 +54484,10 @@ function mapTriggerState(phase) {
54386
54484
  function isHostBacked(agent, agentsDir = AGENTS_DIR2) {
54387
54485
  const safe = (n) => !n.includes("/") && !n.includes("\\") && !n.includes("..");
54388
54486
  if (!safe(agent)) return false;
54389
- const manifestPath = (0, import_node_path16.join)(agentsDir, agent, "manifest.yaml");
54390
- if (!(0, import_node_fs19.existsSync)(manifestPath)) return false;
54487
+ const manifestPath = (0, import_node_path17.join)(agentsDir, agent, "manifest.yaml");
54488
+ if (!(0, import_node_fs20.existsSync)(manifestPath)) return false;
54391
54489
  try {
54392
- const doc2 = (0, import_yaml6.parse)((0, import_node_fs19.readFileSync)(manifestPath, "utf8"));
54490
+ const doc2 = (0, import_yaml7.parse)((0, import_node_fs20.readFileSync)(manifestPath, "utf8"));
54393
54491
  const transport = doc2?.transport;
54394
54492
  return !!(transport && typeof transport === "object" && "cli" in transport);
54395
54493
  } catch {
@@ -54674,7 +54772,7 @@ var RoutineError = class extends Error {
54674
54772
  }
54675
54773
  status;
54676
54774
  };
54677
- var ROUTINES_FILE = (0, import_node_path17.join)(flolessRoot, "routines.json");
54775
+ var ROUTINES_FILE = (0, import_node_path18.join)(flolessRoot, "routines.json");
54678
54776
  var routines = [];
54679
54777
  var loaded = false;
54680
54778
  function ensureLoaded() {
@@ -54710,10 +54808,10 @@ function sanitizeRoutine(raw) {
54710
54808
  };
54711
54809
  }
54712
54810
  function loadFromDisk() {
54713
- if (!(0, import_node_fs20.existsSync)(ROUTINES_FILE)) return [];
54811
+ if (!(0, import_node_fs21.existsSync)(ROUTINES_FILE)) return [];
54714
54812
  let text;
54715
54813
  try {
54716
- text = (0, import_node_fs20.readFileSync)(ROUTINES_FILE, "utf8");
54814
+ text = (0, import_node_fs21.readFileSync)(ROUTINES_FILE, "utf8");
54717
54815
  } catch {
54718
54816
  return [];
54719
54817
  }
@@ -54722,17 +54820,17 @@ function loadFromDisk() {
54722
54820
  return Array.isArray(parsed) ? parsed.map(sanitizeRoutine).filter((r) => r !== null) : [];
54723
54821
  } catch {
54724
54822
  try {
54725
- (0, import_node_fs20.renameSync)(ROUTINES_FILE, `${ROUTINES_FILE}.corrupt-${Date.now()}`);
54823
+ (0, import_node_fs21.renameSync)(ROUTINES_FILE, `${ROUTINES_FILE}.corrupt-${Date.now()}`);
54726
54824
  } catch {
54727
54825
  }
54728
54826
  return [];
54729
54827
  }
54730
54828
  }
54731
54829
  function saveRoutines() {
54732
- if (!(0, import_node_fs20.existsSync)(flolessRoot)) (0, import_node_fs20.mkdirSync)(flolessRoot, { recursive: true });
54830
+ if (!(0, import_node_fs21.existsSync)(flolessRoot)) (0, import_node_fs21.mkdirSync)(flolessRoot, { recursive: true });
54733
54831
  const tmp = `${ROUTINES_FILE}.${process.pid}.tmp`;
54734
- (0, import_node_fs20.writeFileSync)(tmp, JSON.stringify(routines, null, 2));
54735
- (0, import_node_fs20.renameSync)(tmp, ROUTINES_FILE);
54832
+ (0, import_node_fs21.writeFileSync)(tmp, JSON.stringify(routines, null, 2));
54833
+ (0, import_node_fs21.renameSync)(tmp, ROUTINES_FILE);
54736
54834
  }
54737
54835
  function listRoutines() {
54738
54836
  ensureLoaded();
@@ -55140,13 +55238,13 @@ var AppLifecycleError = class extends Error {
55140
55238
  }
55141
55239
  };
55142
55240
  function appsDir() {
55143
- return process.env.AWARE_HOME ? (0, import_node_path18.join)(process.env.AWARE_HOME, "apps") : (0, import_node_path18.join)((0, import_node_os13.homedir)(), ".aware", "apps");
55241
+ return process.env.AWARE_HOME ? (0, import_node_path19.join)(process.env.AWARE_HOME, "apps") : (0, import_node_path19.join)((0, import_node_os14.homedir)(), ".aware", "apps");
55144
55242
  }
55145
55243
  function appDirPath(id) {
55146
- return (0, import_node_path18.join)(appsDir(), id);
55244
+ return (0, import_node_path19.join)(appsDir(), id);
55147
55245
  }
55148
55246
  function appInstalled(id) {
55149
- return APP_ID3.test(id) && (0, import_node_fs21.existsSync)(appDirPath(id));
55247
+ return APP_ID3.test(id) && (0, import_node_fs22.existsSync)(appDirPath(id));
55150
55248
  }
55151
55249
  function logCascade(what, e) {
55152
55250
  console.error(`[app-lifecycle] cascade step failed (${what}):`, e instanceof Error ? e.message : e);
@@ -55247,9 +55345,9 @@ function isGatedAwareRoute(url, method) {
55247
55345
 
55248
55346
  // autostart.mjs
55249
55347
  var import_node_child_process4 = require("node:child_process");
55250
- var import_node_fs22 = require("node:fs");
55251
- var import_node_os14 = require("node:os");
55252
- var import_node_path19 = require("node:path");
55348
+ var import_node_fs23 = require("node:fs");
55349
+ var import_node_os15 = require("node:os");
55350
+ var import_node_path20 = require("node:path");
55253
55351
 
55254
55352
  // teardown.mjs
55255
55353
  var RUN_KEY = "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run";
@@ -55361,8 +55459,8 @@ function removeLegacyRunKey() {
55361
55459
  }
55362
55460
  function logLine(msg) {
55363
55461
  try {
55364
- (0, import_node_fs22.mkdirSync)(logDir(), { recursive: true });
55365
- (0, import_node_fs22.appendFileSync)(logFilePath(), `${(/* @__PURE__ */ new Date()).toISOString()} ${msg}
55462
+ (0, import_node_fs23.mkdirSync)(logDir(), { recursive: true });
55463
+ (0, import_node_fs23.appendFileSync)(logFilePath(), `${(/* @__PURE__ */ new Date()).toISOString()} ${msg}
55366
55464
  `);
55367
55465
  } catch {
55368
55466
  }
@@ -55370,8 +55468,8 @@ function logLine(msg) {
55370
55468
  function registerAutostart(exePath) {
55371
55469
  if (!isWin) return;
55372
55470
  const xml = buildAutostartTaskXml(exePath, currentUserId());
55373
- const tmp = (0, import_node_path19.join)((0, import_node_os14.tmpdir)(), `floless-autostart-${process.pid}-${Date.now()}.xml`);
55374
- (0, import_node_fs22.writeFileSync)(tmp, "\uFEFF" + xml, { encoding: "utf16le" });
55471
+ const tmp = (0, import_node_path20.join)((0, import_node_os15.tmpdir)(), `floless-autostart-${process.pid}-${Date.now()}.xml`);
55472
+ (0, import_node_fs23.writeFileSync)(tmp, "\uFEFF" + xml, { encoding: "utf16le" });
55375
55473
  try {
55376
55474
  (0, import_node_child_process4.execFileSync)("schtasks", ["/Create", "/TN", TASK_NAME, "/XML", tmp, "/F"], {
55377
55475
  stdio: ["ignore", "ignore", "ignore"],
@@ -55382,7 +55480,7 @@ function registerAutostart(exePath) {
55382
55480
  throw err;
55383
55481
  } finally {
55384
55482
  try {
55385
- (0, import_node_fs22.rmSync)(tmp, { force: true });
55483
+ (0, import_node_fs23.rmSync)(tmp, { force: true });
55386
55484
  } catch {
55387
55485
  }
55388
55486
  }
@@ -55417,26 +55515,26 @@ function unregisterAutostart() {
55417
55515
  // updater.ts
55418
55516
  var import_node_child_process5 = require("node:child_process");
55419
55517
  var import_node_crypto6 = require("node:crypto");
55420
- var import_node_fs24 = require("node:fs");
55518
+ var import_node_fs25 = require("node:fs");
55421
55519
  var import_node_stream = require("node:stream");
55422
55520
  var import_promises = require("node:stream/promises");
55423
- var import_node_path21 = require("node:path");
55521
+ var import_node_path22 = require("node:path");
55424
55522
 
55425
55523
  // post-update-marker.mjs
55426
- var import_node_fs23 = require("node:fs");
55427
- var import_node_os15 = require("node:os");
55428
- var import_node_path20 = require("node:path");
55524
+ var import_node_fs24 = require("node:fs");
55525
+ var import_node_os16 = require("node:os");
55526
+ var import_node_path21 = require("node:path");
55429
55527
  var FRESH_MS = 12e4;
55430
55528
  function markerPath() {
55431
55529
  const override = (process.env.FLOLESS_POST_UPDATE_MARKER ?? "").trim();
55432
55530
  if (override) return override;
55433
- const root = process.env.FLOLESS_HOME ?? (0, import_node_path20.join)((0, import_node_os15.homedir)(), ".floless");
55434
- return (0, import_node_path20.join)(root, ".post-update");
55531
+ const root = process.env.FLOLESS_HOME ?? (0, import_node_path21.join)((0, import_node_os16.homedir)(), ".floless");
55532
+ return (0, import_node_path21.join)(root, ".post-update");
55435
55533
  }
55436
55534
  function legacyMarkerPath() {
55437
55535
  if ((process.env.FLOLESS_POST_UPDATE_MARKER ?? "").trim()) return null;
55438
55536
  try {
55439
- return (0, import_node_path20.join)((0, import_node_path20.dirname)((0, import_node_path20.dirname)(process.execPath)), ".floless-post-update");
55537
+ return (0, import_node_path21.join)((0, import_node_path21.dirname)((0, import_node_path21.dirname)(process.execPath)), ".floless-post-update");
55440
55538
  } catch {
55441
55539
  return null;
55442
55540
  }
@@ -55446,7 +55544,7 @@ function writePostUpdateMarker() {
55446
55544
  for (const p of [markerPath(), legacyMarkerPath()]) {
55447
55545
  if (!p) continue;
55448
55546
  try {
55449
- (0, import_node_fs23.writeFileSync)(p, (/* @__PURE__ */ new Date()).toISOString());
55547
+ (0, import_node_fs24.writeFileSync)(p, (/* @__PURE__ */ new Date()).toISOString());
55450
55548
  wrote = true;
55451
55549
  } catch {
55452
55550
  }
@@ -55458,9 +55556,9 @@ function consumePostUpdateMarker() {
55458
55556
  for (const p of [markerPath(), legacyMarkerPath()]) {
55459
55557
  if (!p) continue;
55460
55558
  try {
55461
- if (!(0, import_node_fs23.existsSync)(p)) continue;
55462
- const ageMs = Date.now() - (0, import_node_fs23.statSync)(p).mtimeMs;
55463
- (0, import_node_fs23.rmSync)(p, { force: true });
55559
+ if (!(0, import_node_fs24.existsSync)(p)) continue;
55560
+ const ageMs = Date.now() - (0, import_node_fs24.statSync)(p).mtimeMs;
55561
+ (0, import_node_fs24.rmSync)(p, { force: true });
55464
55562
  if (ageMs < FRESH_MS) fresh = true;
55465
55563
  } catch {
55466
55564
  }
@@ -55477,13 +55575,13 @@ function currentVersion() {
55477
55575
  return appVersion();
55478
55576
  }
55479
55577
  function installRoot() {
55480
- return (0, import_node_path21.dirname)((0, import_node_path21.dirname)(process.execPath));
55578
+ return (0, import_node_path22.dirname)((0, import_node_path22.dirname)(process.execPath));
55481
55579
  }
55482
55580
  function updateExePath() {
55483
- return (0, import_node_path21.join)(installRoot(), "Update.exe");
55581
+ return (0, import_node_path22.join)(installRoot(), "Update.exe");
55484
55582
  }
55485
55583
  function packagesDir() {
55486
- return (0, import_node_path21.join)(installRoot(), "packages");
55584
+ return (0, import_node_path22.join)(installRoot(), "packages");
55487
55585
  }
55488
55586
  function feedUrl() {
55489
55587
  const env2 = (process.env.FLOLESS_UPDATE_URL ?? "").trim().replace(/\/+$/, "");
@@ -55576,22 +55674,22 @@ async function checkForUpdate() {
55576
55674
  }
55577
55675
  async function sha1OfFile(path) {
55578
55676
  const hash = (0, import_node_crypto6.createHash)("sha1");
55579
- await (0, import_promises.pipeline)((0, import_node_fs24.createReadStream)(path), hash);
55677
+ await (0, import_promises.pipeline)((0, import_node_fs25.createReadStream)(path), hash);
55580
55678
  return hash.digest("hex").toUpperCase();
55581
55679
  }
55582
55680
  async function downloadPackage(asset) {
55583
55681
  if (!NUPKG_NAME.test(asset.FileName)) throw new Error(`refusing suspicious package name: ${asset.FileName}`);
55584
55682
  const want = asset.SHA1.toUpperCase();
55585
55683
  const dir = packagesDir();
55586
- (0, import_node_fs24.mkdirSync)(dir, { recursive: true });
55587
- const dest = (0, import_node_path21.join)(dir, asset.FileName);
55588
- if ((0, import_node_fs24.existsSync)(dest) && await sha1OfFile(dest) === want) return dest;
55684
+ (0, import_node_fs25.mkdirSync)(dir, { recursive: true });
55685
+ const dest = (0, import_node_path22.join)(dir, asset.FileName);
55686
+ if ((0, import_node_fs25.existsSync)(dest) && await sha1OfFile(dest) === want) return dest;
55589
55687
  const res = await authedFetch(`${feedUrl()}/${encodeURIComponent(asset.FileName)}`, {
55590
55688
  redirect: "follow",
55591
55689
  signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS)
55592
55690
  });
55593
55691
  if (!res.ok || !res.body) throw new Error(`download failed: HTTP ${res.status} for ${asset.FileName}`);
55594
- await (0, import_promises.pipeline)(import_node_stream.Readable.fromWeb(res.body), (0, import_node_fs24.createWriteStream)(dest));
55692
+ await (0, import_promises.pipeline)(import_node_stream.Readable.fromWeb(res.body), (0, import_node_fs25.createWriteStream)(dest));
55595
55693
  const got = await sha1OfFile(dest);
55596
55694
  if (got !== want) throw new Error(`SHA1 mismatch for ${asset.FileName}: feed=${want} got=${got}`);
55597
55695
  return dest;
@@ -55600,7 +55698,7 @@ async function applyUpdate(check, opts) {
55600
55698
  if (!check.supported) return { applied: false, message: check.reason ?? "auto-update not supported in this runtime" };
55601
55699
  if (!check.updateAvailable || !check.asset) return { applied: false, message: check.reason ?? "no update available" };
55602
55700
  const exe = updateExePath();
55603
- if (!(0, import_node_fs24.existsSync)(exe)) {
55701
+ if (!(0, import_node_fs25.existsSync)(exe)) {
55604
55702
  return { applied: false, message: `Update.exe not found at ${exe} \u2014 is this a Velopack install?` };
55605
55703
  }
55606
55704
  const pkg = await downloadPackage(check.asset);
@@ -55840,12 +55938,12 @@ function isTraceCorrupt(events) {
55840
55938
 
55841
55939
  // launch.mjs
55842
55940
  var import_node_child_process6 = require("node:child_process");
55843
- var import_node_path22 = require("node:path");
55844
- var import_node_url2 = require("node:url");
55845
- var import_node_fs25 = require("node:fs");
55941
+ var import_node_path23 = require("node:path");
55942
+ var import_node_url3 = require("node:url");
55943
+ var import_node_fs26 = require("node:fs");
55846
55944
  var import_node_http = __toESM(require("node:http"), 1);
55847
55945
  var import_node_readline = require("node:readline");
55848
- var __dirname2 = (0, import_node_path22.dirname)((0, import_node_url2.fileURLToPath)(__import_meta_url));
55946
+ var __dirname2 = (0, import_node_path23.dirname)((0, import_node_url3.fileURLToPath)(__import_meta_url));
55849
55947
  var PORT = Number(process.env.PORT ?? 4317);
55850
55948
  var HEALTH_URL = `http://127.0.0.1:${PORT}/api/health`;
55851
55949
  var BROWSER_URL = `http://floless.localhost:${PORT}`;
@@ -55917,8 +56015,8 @@ async function waitHealthy(timeoutMs = 3e4) {
55917
56015
  function resolveServerStart() {
55918
56016
  const packaged = /flolessapp\.exe$/i.test(process.execPath);
55919
56017
  if (packaged) return { cmd: process.execPath, args: ["--serve"], shell: false };
55920
- const bundle = (0, import_node_path22.join)(__dirname2, "dist", "floless-server.cjs");
55921
- if ((0, import_node_fs25.existsSync)(bundle)) return { cmd: process.execPath, args: [bundle, "--serve"], shell: false };
56018
+ const bundle = (0, import_node_path23.join)(__dirname2, "dist", "floless-server.cjs");
56019
+ if ((0, import_node_fs26.existsSync)(bundle)) return { cmd: process.execPath, args: [bundle, "--serve"], shell: false };
55922
56020
  return { cmd: "npm", args: ["run", "start"], shell: isWin2 };
55923
56021
  }
55924
56022
  function startServerDetached() {
@@ -56071,8 +56169,8 @@ function taskkillArgs(pid, { tree = true } = {}) {
56071
56169
  }
56072
56170
  function killSupervisor({ tree = true } = {}) {
56073
56171
  if (!isWin2) return;
56074
- const isNpmChannel = /^node(\.exe)?$/i.test((0, import_node_path22.basename)(process.execPath));
56075
- const scriptMatch = isNpmChannel ? (0, import_node_path22.basename)((0, import_node_url2.fileURLToPath)(__import_meta_url)) : void 0;
56172
+ const isNpmChannel = /^node(\.exe)?$/i.test((0, import_node_path23.basename)(process.execPath));
56173
+ const scriptMatch = isNpmChannel ? (0, import_node_path23.basename)((0, import_node_url3.fileURLToPath)(__import_meta_url)) : void 0;
56076
56174
  const realExe = resolveRealInstallExe(process.execPath);
56077
56175
  const exeMatch = realExe === process.execPath ? process.execPath : [process.execPath, realExe];
56078
56176
  const pids = supervisorPidsToKill(enumerateProcesses(), process.pid, exeMatch, scriptMatch);
@@ -56237,7 +56335,7 @@ async function runAction(arg, flagArgv = [], selfVersion = null) {
56237
56335
  }
56238
56336
  await action(parseTeardownFlags(flagArgv));
56239
56337
  }
56240
- var entry = (0, import_node_path22.basename)(process.argv[1] ?? "").toLowerCase();
56338
+ var entry = (0, import_node_path23.basename)(process.argv[1] ?? "").toLowerCase();
56241
56339
  if (entry === "launch.mjs") {
56242
56340
  runAction(process.argv[2], process.argv.slice(3)).catch((e) => {
56243
56341
  log(`error: ${e?.message ?? e}`);
@@ -56311,11 +56409,11 @@ function awareUpgradeBlockReason(s) {
56311
56409
  }
56312
56410
 
56313
56411
  // skill-sync.ts
56314
- var import_node_fs26 = require("node:fs");
56315
- var import_node_os16 = require("node:os");
56316
- var import_node_path23 = require("node:path");
56317
- var import_node_url3 = require("node:url");
56318
- var import_yaml7 = __toESM(require_dist6(), 1);
56412
+ var import_node_fs27 = require("node:fs");
56413
+ var import_node_os17 = require("node:os");
56414
+ var import_node_path24 = require("node:path");
56415
+ var import_node_url4 = require("node:url");
56416
+ var import_yaml8 = __toESM(require_dist6(), 1);
56319
56417
 
56320
56418
  // build/ship-skills.mjs
56321
56419
  var PRODUCT_SKILLS = [
@@ -56348,33 +56446,33 @@ function selectShippedSkillNames(names) {
56348
56446
  }
56349
56447
 
56350
56448
  // skill-sync.ts
56351
- var __dirname3 = (0, import_node_path23.dirname)((0, import_node_url3.fileURLToPath)(__import_meta_url));
56449
+ var __dirname3 = (0, import_node_path24.dirname)((0, import_node_url4.fileURLToPath)(__import_meta_url));
56352
56450
  function bundledSkillsRoot() {
56353
56451
  const candidates = [
56354
- (0, import_node_path23.join)(__dirname3, "skills"),
56355
- (0, import_node_path23.join)((0, import_node_path23.dirname)(process.execPath), "skills"),
56356
- (0, import_node_path23.join)(__dirname3, "..", ".claude", "skills")
56452
+ (0, import_node_path24.join)(__dirname3, "skills"),
56453
+ (0, import_node_path24.join)((0, import_node_path24.dirname)(process.execPath), "skills"),
56454
+ (0, import_node_path24.join)(__dirname3, "..", ".claude", "skills")
56357
56455
  ];
56358
- return candidates.find((p) => (0, import_node_fs26.existsSync)(p)) ?? null;
56456
+ return candidates.find((p) => (0, import_node_fs27.existsSync)(p)) ?? null;
56359
56457
  }
56360
56458
  function targetConfigDirs() {
56361
56459
  const override = process.env.FLOLESS_SKILL_TARGETS;
56362
56460
  if (override) {
56363
56461
  return override.split(";").map((d) => d.trim()).filter(Boolean).map((dir) => ({ runtime: "custom", dir }));
56364
56462
  }
56365
- const home = (0, import_node_os16.homedir)();
56463
+ const home = (0, import_node_os17.homedir)();
56366
56464
  return [
56367
- { runtime: "claude", dir: (0, import_node_path23.join)(home, ".claude") },
56368
- { runtime: "codex", dir: (0, import_node_path23.join)(home, ".codex") },
56369
- { runtime: "opencode", dir: (0, import_node_path23.join)(home, ".opencode") }
56465
+ { runtime: "claude", dir: (0, import_node_path24.join)(home, ".claude") },
56466
+ { runtime: "codex", dir: (0, import_node_path24.join)(home, ".codex") },
56467
+ { runtime: "opencode", dir: (0, import_node_path24.join)(home, ".opencode") }
56370
56468
  ];
56371
56469
  }
56372
56470
  function skillVersion(skillMdPath) {
56373
56471
  try {
56374
- const text = (0, import_node_fs26.readFileSync)(skillMdPath, "utf8");
56472
+ const text = (0, import_node_fs27.readFileSync)(skillMdPath, "utf8");
56375
56473
  const m = /^---\r?\n([\s\S]*?)\r?\n---/.exec(text);
56376
56474
  if (!m || m[1] === void 0) return null;
56377
- const fm = (0, import_yaml7.parse)(m[1]);
56475
+ const fm = (0, import_yaml8.parse)(m[1]);
56378
56476
  const meta = fm?.metadata;
56379
56477
  const v = meta?.version;
56380
56478
  return typeof v === "string" || typeof v === "number" ? String(v) : null;
@@ -56411,21 +56509,21 @@ function decideAction(installed, bundled) {
56411
56509
  function bundledSkills(root) {
56412
56510
  let entries = [];
56413
56511
  try {
56414
- entries = selectShippedSkillNames((0, import_node_fs26.readdirSync)(root));
56512
+ entries = selectShippedSkillNames((0, import_node_fs27.readdirSync)(root));
56415
56513
  } catch {
56416
56514
  return [];
56417
56515
  }
56418
56516
  const out = [];
56419
56517
  for (const name of entries) {
56420
- const dir = (0, import_node_path23.join)(root, name);
56518
+ const dir = (0, import_node_path24.join)(root, name);
56421
56519
  let isDir = false;
56422
56520
  try {
56423
- isDir = (0, import_node_fs26.statSync)(dir).isDirectory();
56521
+ isDir = (0, import_node_fs27.statSync)(dir).isDirectory();
56424
56522
  } catch {
56425
56523
  isDir = false;
56426
56524
  }
56427
56525
  if (!isDir) continue;
56428
- const v = skillVersion((0, import_node_path23.join)(dir, "SKILL.md"));
56526
+ const v = skillVersion((0, import_node_path24.join)(dir, "SKILL.md"));
56429
56527
  if (!v) continue;
56430
56528
  out.push({ name, dir, version: v });
56431
56529
  }
@@ -56438,17 +56536,17 @@ function syncSkills() {
56438
56536
  const skills = bundledSkills(root);
56439
56537
  if (!skills.length) return results;
56440
56538
  for (const { runtime, dir: cfg } of targetConfigDirs()) {
56441
- if (!(0, import_node_fs26.existsSync)(cfg)) continue;
56442
- const skillsDir = (0, import_node_path23.join)(cfg, "skills");
56539
+ if (!(0, import_node_fs27.existsSync)(cfg)) continue;
56540
+ const skillsDir = (0, import_node_path24.join)(cfg, "skills");
56443
56541
  for (const s of skills) {
56444
- const dest = (0, import_node_path23.join)(skillsDir, s.name);
56445
- const installedMd = (0, import_node_path23.join)(dest, "SKILL.md");
56446
- const installed = (0, import_node_fs26.existsSync)(installedMd) ? skillVersion(installedMd) : null;
56542
+ const dest = (0, import_node_path24.join)(skillsDir, s.name);
56543
+ const installedMd = (0, import_node_path24.join)(dest, "SKILL.md");
56544
+ const installed = (0, import_node_fs27.existsSync)(installedMd) ? skillVersion(installedMd) : null;
56447
56545
  const action = decideAction(installed, s.version);
56448
56546
  if (action === "installed" || action === "updated") {
56449
56547
  try {
56450
- if (action === "updated") (0, import_node_fs26.rmSync)(dest, { recursive: true, force: true });
56451
- (0, import_node_fs26.cpSync)(s.dir, dest, { recursive: true });
56548
+ if (action === "updated") (0, import_node_fs27.rmSync)(dest, { recursive: true, force: true });
56549
+ (0, import_node_fs27.cpSync)(s.dir, dest, { recursive: true });
56452
56550
  results.push({ runtime, skill: s.name, action, from: installed, to: s.version });
56453
56551
  } catch {
56454
56552
  }
@@ -56461,9 +56559,9 @@ function syncSkills() {
56461
56559
  }
56462
56560
 
56463
56561
  // watch.ts
56464
- var import_node_os17 = require("node:os");
56465
- var import_node_path25 = require("node:path");
56466
- var import_node_fs27 = require("node:fs");
56562
+ var import_node_os18 = require("node:os");
56563
+ var import_node_path26 = require("node:path");
56564
+ var import_node_fs28 = require("node:fs");
56467
56565
 
56468
56566
  // node_modules/chokidar/esm/index.js
56469
56567
  var import_fs2 = require("fs");
@@ -56474,7 +56572,7 @@ var sysPath2 = __toESM(require("path"), 1);
56474
56572
  // node_modules/readdirp/esm/index.js
56475
56573
  var import_promises2 = require("node:fs/promises");
56476
56574
  var import_node_stream2 = require("node:stream");
56477
- var import_node_path24 = require("node:path");
56575
+ var import_node_path25 = require("node:path");
56478
56576
  var EntryTypes = {
56479
56577
  FILE_TYPE: "files",
56480
56578
  DIR_TYPE: "directories",
@@ -56549,7 +56647,7 @@ var ReaddirpStream = class extends import_node_stream2.Readable {
56549
56647
  this._wantsDir = type ? DIR_TYPES.has(type) : false;
56550
56648
  this._wantsFile = type ? FILE_TYPES.has(type) : false;
56551
56649
  this._wantsEverything = type === EntryTypes.EVERYTHING_TYPE;
56552
- this._root = (0, import_node_path24.resolve)(root);
56650
+ this._root = (0, import_node_path25.resolve)(root);
56553
56651
  this._isDirent = !opts.alwaysStat;
56554
56652
  this._statsProp = this._isDirent ? "dirent" : "stats";
56555
56653
  this._rdOptions = { encoding: "utf8", withFileTypes: this._isDirent };
@@ -56620,8 +56718,8 @@ var ReaddirpStream = class extends import_node_stream2.Readable {
56620
56718
  let entry2;
56621
56719
  const basename5 = this._isDirent ? dirent.name : dirent;
56622
56720
  try {
56623
- const fullPath = (0, import_node_path24.resolve)((0, import_node_path24.join)(path, basename5));
56624
- entry2 = { path: (0, import_node_path24.relative)(this._root, fullPath), fullPath, basename: basename5 };
56721
+ const fullPath = (0, import_node_path25.resolve)((0, import_node_path25.join)(path, basename5));
56722
+ entry2 = { path: (0, import_node_path25.relative)(this._root, fullPath), fullPath, basename: basename5 };
56625
56723
  entry2[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
56626
56724
  } catch (err) {
56627
56725
  this._onError(err);
@@ -56655,7 +56753,7 @@ var ReaddirpStream = class extends import_node_stream2.Readable {
56655
56753
  }
56656
56754
  if (entryRealPathStats.isDirectory()) {
56657
56755
  const len2 = entryRealPath.length;
56658
- if (full.startsWith(entryRealPath) && full.substr(len2, 1) === import_node_path24.sep) {
56756
+ if (full.startsWith(entryRealPath) && full.substr(len2, 1) === import_node_path25.sep) {
56659
56757
  const recursiveError = new Error(`Circular symlink detected: "${full}" points to "${entryRealPath}"`);
56660
56758
  recursiveError.code = RECURSIVE_ERROR_CODE;
56661
56759
  return this._onError(recursiveError);
@@ -57194,9 +57292,9 @@ var NodeFsHandler = class {
57194
57292
  if (this.fsw.closed) {
57195
57293
  return;
57196
57294
  }
57197
- const dirname11 = sysPath.dirname(file);
57295
+ const dirname12 = sysPath.dirname(file);
57198
57296
  const basename5 = sysPath.basename(file);
57199
- const parent = this.fsw._getWatchedDir(dirname11);
57297
+ const parent = this.fsw._getWatchedDir(dirname12);
57200
57298
  let prevStats = stats;
57201
57299
  if (parent.has(basename5))
57202
57300
  return;
@@ -57223,7 +57321,7 @@ var NodeFsHandler = class {
57223
57321
  prevStats = newStats2;
57224
57322
  }
57225
57323
  } catch (error) {
57226
- this.fsw._remove(dirname11, basename5);
57324
+ this.fsw._remove(dirname12, basename5);
57227
57325
  }
57228
57326
  } else if (parent.has(basename5)) {
57229
57327
  const at = newStats.atimeMs;
@@ -58163,33 +58261,33 @@ function appIdFromLogPath(path) {
58163
58261
  return i >= 0 && parts[i + 1] ? parts[i + 1] : null;
58164
58262
  }
58165
58263
  function samePath(a, b) {
58166
- const ra = (0, import_node_path25.resolve)(a);
58167
- const rb = (0, import_node_path25.resolve)(b);
58264
+ const ra = (0, import_node_path26.resolve)(a);
58265
+ const rb = (0, import_node_path26.resolve)(b);
58168
58266
  return process.platform === "win32" ? ra.toLowerCase() === rb.toLowerCase() : ra === rb;
58169
58267
  }
58170
58268
  function underDir(path, dir) {
58171
- const rp = (0, import_node_path25.resolve)(path);
58172
- const rd = (0, import_node_path25.resolve)(dir);
58269
+ const rp = (0, import_node_path26.resolve)(path);
58270
+ const rd = (0, import_node_path26.resolve)(dir);
58173
58271
  const [p, d] = process.platform === "win32" ? [rp.toLowerCase(), rd.toLowerCase()] : [rp, rd];
58174
- return p === d || p.startsWith(d + import_node_path25.sep);
58272
+ return p === d || p.startsWith(d + import_node_path26.sep);
58175
58273
  }
58176
58274
  function startWatcher() {
58177
- const awareDir = process.env.AWARE_HOME ?? (0, import_node_path25.join)((0, import_node_os17.homedir)(), ".aware");
58178
- const credentialsDir = (0, import_node_path25.join)(awareDir, "credentials");
58179
- if (!(0, import_node_fs27.existsSync)(credentialsDir)) {
58275
+ const awareDir = process.env.AWARE_HOME ?? (0, import_node_path26.join)((0, import_node_os18.homedir)(), ".aware");
58276
+ const credentialsDir = (0, import_node_path26.join)(awareDir, "credentials");
58277
+ if (!(0, import_node_fs28.existsSync)(credentialsDir)) {
58180
58278
  try {
58181
- (0, import_node_fs27.mkdirSync)(credentialsDir, { recursive: true });
58279
+ (0, import_node_fs28.mkdirSync)(credentialsDir, { recursive: true });
58182
58280
  } catch {
58183
58281
  }
58184
58282
  }
58185
- if (!(0, import_node_fs27.existsSync)(uiDir)) {
58283
+ if (!(0, import_node_fs28.existsSync)(uiDir)) {
58186
58284
  try {
58187
- (0, import_node_fs27.mkdirSync)(uiDir, { recursive: true });
58285
+ (0, import_node_fs28.mkdirSync)(uiDir, { recursive: true });
58188
58286
  } catch {
58189
58287
  }
58190
58288
  }
58191
- const targets = ["apps", "logs", "credentials"].map((d) => (0, import_node_path25.join)(awareDir, d)).filter((p) => (0, import_node_fs27.existsSync)(p));
58192
- if ((0, import_node_fs27.existsSync)(uiDir)) targets.push(uiDir);
58289
+ const targets = ["apps", "logs", "credentials"].map((d) => (0, import_node_path26.join)(awareDir, d)).filter((p) => (0, import_node_fs28.existsSync)(p));
58290
+ if ((0, import_node_fs28.existsSync)(uiDir)) targets.push(uiDir);
58193
58291
  if (targets.length === 0) {
58194
58292
  return null;
58195
58293
  }
@@ -58218,11 +58316,11 @@ function startWatcher() {
58218
58316
  const isCredential = path.split(/[\\/]/).includes("credentials");
58219
58317
  const kind = isCredential ? "credential" : path.endsWith(".jsonl") ? "trace" : path.endsWith(".lock") ? "lock" : path.endsWith(".flo") || path.endsWith(".app") ? "source" : "file";
58220
58318
  broadcast({ type: "fs-change", kind, event, path });
58221
- if (kind === "trace" && event !== "unlink" && (0, import_node_fs27.existsSync)(path)) {
58319
+ if (kind === "trace" && event !== "unlink" && (0, import_node_fs28.existsSync)(path)) {
58222
58320
  const id = appIdFromLogPath(path);
58223
58321
  if (!id) return;
58224
58322
  try {
58225
- broadcast({ type: "trace-file", id, runId: path.split(import_node_path25.sep).pop()?.replace(/\.jsonl$/, "") ?? null, events: parseTrace((0, import_node_fs27.readFileSync)(path, "utf8")) });
58323
+ broadcast({ type: "trace-file", id, runId: path.split(import_node_path26.sep).pop()?.replace(/\.jsonl$/, "") ?? null, events: parseTrace((0, import_node_fs28.readFileSync)(path, "utf8")) });
58226
58324
  } catch {
58227
58325
  }
58228
58326
  }
@@ -58231,10 +58329,10 @@ function startWatcher() {
58231
58329
  }
58232
58330
 
58233
58331
  // index.ts
58234
- var __dirname4 = (0, import_node_path26.dirname)((0, import_node_url4.fileURLToPath)(__import_meta_url));
58235
- var WEB_ROOT = [(0, import_node_path26.join)(__dirname4, "web"), (0, import_node_path26.join)((0, import_node_path26.dirname)(process.execPath), "web"), (0, import_node_path26.join)(__dirname4, "..", "web")].find(
58236
- (p) => (0, import_node_fs28.existsSync)(p)
58237
- ) ?? (0, import_node_path26.join)(__dirname4, "..", "web");
58332
+ var __dirname4 = (0, import_node_path27.dirname)((0, import_node_url5.fileURLToPath)(__import_meta_url));
58333
+ var WEB_ROOT = [(0, import_node_path27.join)(__dirname4, "web"), (0, import_node_path27.join)((0, import_node_path27.dirname)(process.execPath), "web"), (0, import_node_path27.join)(__dirname4, "..", "web")].find(
58334
+ (p) => (0, import_node_fs29.existsSync)(p)
58335
+ ) ?? (0, import_node_path27.join)(__dirname4, "..", "web");
58238
58336
  var PORT2 = Number(process.env.PORT ?? 4317);
58239
58337
  var HOST = "127.0.0.1";
58240
58338
  var crashHandlersInstalled = false;
@@ -58250,7 +58348,7 @@ function installCrashHandlers() {
58250
58348
  ${stack}
58251
58349
  `;
58252
58350
  try {
58253
- (0, import_node_fs28.appendFileSync)(logFilePath(), line);
58351
+ (0, import_node_fs29.appendFileSync)(logFilePath(), line);
58254
58352
  } catch {
58255
58353
  }
58256
58354
  if (process.stderr.isTTY) process.stderr.write(line);
@@ -58515,6 +58613,73 @@ async function startServer() {
58515
58613
  const apps = await aware.list();
58516
58614
  return { ok: true, apps: apps.map((a) => ({ ...a, provider: appProvider(a.id), baked: appBaked(a.id) })) };
58517
58615
  });
58616
+ app.get("/api/workflows/updates", async () => {
58617
+ const apps = await aware.list();
58618
+ const installed = {};
58619
+ for (const a of apps) {
58620
+ try {
58621
+ installed[a.id] = readApp(a.id).version;
58622
+ } catch {
58623
+ }
58624
+ }
58625
+ return { ok: true, updates: detectUpdates(installed, loadTemplates()) };
58626
+ });
58627
+ const _wfUpdating = /* @__PURE__ */ new Set();
58628
+ app.post("/api/workflows/:id/update", async (req, reply) => {
58629
+ const id = req.params.id;
58630
+ const t = loadTemplates().find((x) => x.id === id);
58631
+ if (!t) return reply.status(404).send({ ok: false, error: `no bundled template for "${id}"`, code: "no-template" });
58632
+ if (t.publisher !== "floless") return reply.status(400).send({ ok: false, error: `"${id}" is not a FloLess-published workflow`, code: "not-published" });
58633
+ if (_wfUpdating.has(id)) return reply.status(409).send({ ok: false, error: `an update for "${id}" is already in progress`, code: "in-progress" });
58634
+ let fromVersion;
58635
+ let srcPath;
58636
+ let appDirPath2;
58637
+ try {
58638
+ const a = readApp(id);
58639
+ fromVersion = a.version;
58640
+ srcPath = a.source.path;
58641
+ appDirPath2 = appDir(id);
58642
+ } catch {
58643
+ return reply.status(404).send({ ok: false, error: `"${id}" is not installed`, code: "not-installed" });
58644
+ }
58645
+ if (compareSemver(t.version, fromVersion) <= 0) {
58646
+ return reply.status(409).send({ ok: false, error: `"${id}" is already at ${fromVersion}`, code: "up-to-date" });
58647
+ }
58648
+ const contract = readContract(id);
58649
+ if (contract == null && (0, import_node_fs29.existsSync)(contractPath(id))) {
58650
+ return reply.status(409).send({ ok: false, error: `"${id}"'s saved data is unreadable \u2014 open it in the editor and re-save before updating`, code: "contract-corrupt" });
58651
+ }
58652
+ if (contract != null) {
58653
+ const v = validateSteelTakeoff(contract);
58654
+ if (!v.valid) return reply.status(409).send({ ok: false, error: `"${id}"'s saved data is invalid \u2014 re-save it in the editor before updating`, code: "contract-invalid" });
58655
+ }
58656
+ _wfUpdating.add(id);
58657
+ const bdir = backupDir(id, fromVersion, Date.now());
58658
+ try {
58659
+ (0, import_node_fs29.mkdirSync)((0, import_node_path27.dirname)(bdir), { recursive: true });
58660
+ (0, import_node_fs29.cpSync)(appDirPath2, bdir, { recursive: true });
58661
+ (0, import_node_fs29.cpSync)(t.path, srcPath);
58662
+ if (contract != null) {
58663
+ bakeContractIntoApp(srcPath, contract);
58664
+ bakeDownstream(srcPath, contract);
58665
+ }
58666
+ await aware.compile(srcPath);
58667
+ broadcast({ type: "apps-changed", id });
58668
+ return { ok: true, id, fromVersion, toVersion: t.version, backupPath: bdir };
58669
+ } catch (e) {
58670
+ const msg = e instanceof Error ? e.message : String(e);
58671
+ try {
58672
+ (0, import_node_fs29.rmSync)(appDirPath2, { recursive: true, force: true });
58673
+ (0, import_node_fs29.cpSync)(bdir, appDirPath2, { recursive: true });
58674
+ } catch (re) {
58675
+ const rmsg = re instanceof Error ? re.message : String(re);
58676
+ return reply.status(500).send({ ok: false, error: `update failed (${msg}) AND rollback failed (${rmsg}) \u2014 restore manually from ${bdir}`, code: "rollback-failed", backupPath: bdir });
58677
+ }
58678
+ return reply.status(500).send({ ok: false, error: `update failed (rolled back to ${fromVersion}): ${msg}`, code: "update-failed" });
58679
+ } finally {
58680
+ _wfUpdating.delete(id);
58681
+ }
58682
+ });
58518
58683
  app.get("/api/agents", async () => {
58519
58684
  const agents = await aware.agentList();
58520
58685
  return { ok: true, agents };
@@ -58777,7 +58942,7 @@ async function startServer() {
58777
58942
  }
58778
58943
  const companionId = `${req.params.appId}-ifc`;
58779
58944
  const filename = `${req.params.appId}.ifc`;
58780
- const outPath = (0, import_node_path26.join)(appPath(companionId), filename);
58945
+ const outPath = (0, import_node_path27.join)(appPath(companionId), filename);
58781
58946
  let flo;
58782
58947
  try {
58783
58948
  flo = writeIfcApp(appPath(companionId), companionId, scene, outPath);
@@ -58800,8 +58965,8 @@ async function startServer() {
58800
58965
  }
58801
58966
  throw e;
58802
58967
  }
58803
- if (!(0, import_node_fs28.existsSync)(outPath)) return reply.send({ ok: false, error: "the IFC export produced no file" });
58804
- const content = (0, import_node_fs28.readFileSync)(outPath, "utf8");
58968
+ if (!(0, import_node_fs29.existsSync)(outPath)) return reply.send({ ok: false, error: "the IFC export produced no file" });
58969
+ const content = (0, import_node_fs29.readFileSync)(outPath, "utf8");
58805
58970
  broadcast({ type: "apps-changed" });
58806
58971
  return { ok: true, filename, content, bytes: Buffer.byteLength(content), skipped };
58807
58972
  });
@@ -58950,11 +59115,11 @@ async function startServer() {
58950
59115
  if (appExists(id)) {
58951
59116
  return reply.status(409).send({ ok: false, error: `a workflow named "${id}" is already installed \u2014 remove it first, or rename the file's app: id`, code: "exists", id });
58952
59117
  }
58953
- const stageRoot = (0, import_node_fs28.mkdtempSync)((0, import_node_path26.join)((0, import_node_os18.tmpdir)(), "floless-import-"));
59118
+ const stageRoot = (0, import_node_fs29.mkdtempSync)((0, import_node_path27.join)((0, import_node_os19.tmpdir)(), "floless-import-"));
58954
59119
  try {
58955
- const stageDir = (0, import_node_path26.join)(stageRoot, id);
58956
- (0, import_node_fs28.mkdirSync)(stageDir);
58957
- (0, import_node_fs28.writeFileSync)((0, import_node_path26.join)(stageDir, `${id}.flo`), content);
59120
+ const stageDir = (0, import_node_path27.join)(stageRoot, id);
59121
+ (0, import_node_fs29.mkdirSync)(stageDir);
59122
+ (0, import_node_fs29.writeFileSync)((0, import_node_path27.join)(stageDir, `${id}.flo`), content);
58958
59123
  await aware.install(stageDir);
58959
59124
  } catch (err) {
58960
59125
  try {
@@ -58964,7 +59129,7 @@ async function startServer() {
58964
59129
  const msg = err instanceof AwareError ? err.message : String(err?.message ?? err);
58965
59130
  return reply.status(502).send({ ok: false, error: `import failed: ${msg}` });
58966
59131
  } finally {
58967
- (0, import_node_fs28.rmSync)(stageRoot, { recursive: true, force: true });
59132
+ (0, import_node_fs29.rmSync)(stageRoot, { recursive: true, force: true });
58968
59133
  }
58969
59134
  broadcast({ type: "apps-changed", id });
58970
59135
  return { ok: true, id };
@@ -58978,13 +59143,13 @@ async function startServer() {
58978
59143
  }
58979
59144
  const inputs = appData.inputs.map((i) => ({ name: i.name, type: i.type }));
58980
59145
  const baked = bakeFloSource(appData.source.text, inputs);
58981
- const tmpRoot = (0, import_node_fs28.mkdtempSync)((0, import_node_path26.join)((0, import_node_os18.tmpdir)(), "floless-bake-"));
58982
- const backupDir = (0, import_node_path26.join)(tmpRoot, `${id}-backup`);
58983
- const bakeDir = (0, import_node_path26.join)(tmpRoot, id);
58984
- (0, import_node_fs28.cpSync)(appDir(id), backupDir, { recursive: true });
58985
- (0, import_node_fs28.cpSync)(appDir(id), bakeDir, { recursive: true });
59146
+ const tmpRoot = (0, import_node_fs29.mkdtempSync)((0, import_node_path27.join)((0, import_node_os19.tmpdir)(), "floless-bake-"));
59147
+ const backupDir2 = (0, import_node_path27.join)(tmpRoot, `${id}-backup`);
59148
+ const bakeDir = (0, import_node_path27.join)(tmpRoot, id);
59149
+ (0, import_node_fs29.cpSync)(appDir(id), backupDir2, { recursive: true });
59150
+ (0, import_node_fs29.cpSync)(appDir(id), bakeDir, { recursive: true });
58986
59151
  const floName = appData.source.path.split(/[\\/]/).pop();
58987
- (0, import_node_fs28.writeFileSync)((0, import_node_path26.join)(bakeDir, floName), baked);
59152
+ (0, import_node_fs29.writeFileSync)((0, import_node_path27.join)(bakeDir, floName), baked);
58988
59153
  let appInstalled2 = true;
58989
59154
  try {
58990
59155
  await aware.uninstall(id);
@@ -58994,29 +59159,29 @@ async function startServer() {
58994
59159
  appInstalled2 = true;
58995
59160
  } catch (installErr) {
58996
59161
  try {
58997
- await aware.install(backupDir);
59162
+ await aware.install(backupDir2);
58998
59163
  appInstalled2 = true;
58999
59164
  } catch (restoreErr) {
59000
59165
  app.log.error({ id, tmpRoot, restoreErr: String(restoreErr) }, "bake: install AND restore failed \u2014 app uninstalled; backup retained");
59001
59166
  return reply.status(502).send({
59002
59167
  ok: false,
59003
- error: `bake failed and the app could not be restored \u2014 its source is backed up at ${backupDir}. Reinstall it from there with: aware app install "${backupDir}"`
59168
+ error: `bake failed and the app could not be restored \u2014 its source is backed up at ${backupDir2}. Reinstall it from there with: aware app install "${backupDir2}"`
59004
59169
  });
59005
59170
  }
59006
59171
  throw installErr;
59007
59172
  }
59008
59173
  try {
59009
- await aware.compile((0, import_node_path26.join)(appDir(id), floName));
59174
+ await aware.compile((0, import_node_path27.join)(appDir(id), floName));
59010
59175
  } catch (compileErr) {
59011
59176
  app.log.warn({ id, compileErr: String(compileErr) }, "bake: post-install recompile failed (app baked but may need a manual Compile)");
59012
59177
  }
59013
59178
  broadcast({ type: "baked", id });
59014
59179
  return { ok: true, id, agent: id, inputs };
59015
59180
  } finally {
59016
- if (appInstalled2) (0, import_node_fs28.rmSync)(tmpRoot, { recursive: true, force: true });
59181
+ if (appInstalled2) (0, import_node_fs29.rmSync)(tmpRoot, { recursive: true, force: true });
59017
59182
  }
59018
59183
  });
59019
- const graftAgentsDir = () => (0, import_node_path26.join)((0, import_node_os18.homedir)(), ".aware", "agents");
59184
+ const graftAgentsDir = () => (0, import_node_path27.join)((0, import_node_os19.homedir)(), ".aware", "agents");
59020
59185
  app.post("/api/graft/match", async (req, reply) => {
59021
59186
  const { glob } = req.body ?? {};
59022
59187
  if (!glob) return reply.status(400).send({ ok: false, error: "glob required" });
@@ -59033,7 +59198,7 @@ async function startServer() {
59033
59198
  if (!sourceKind || !sourceRef) {
59034
59199
  return reply.status(400).send({ ok: false, error: "sourceKind and sourceRef required" });
59035
59200
  }
59036
- const tempHome = (0, import_node_fs28.mkdtempSync)((0, import_node_path26.join)((0, import_node_os18.tmpdir)(), "floless-graft-"));
59201
+ const tempHome = (0, import_node_fs29.mkdtempSync)((0, import_node_path27.join)((0, import_node_os19.tmpdir)(), "floless-graft-"));
59037
59202
  let result;
59038
59203
  try {
59039
59204
  result = await aware.build({
@@ -59046,19 +59211,19 @@ async function startServer() {
59046
59211
  awareHome: tempHome
59047
59212
  });
59048
59213
  } catch (err) {
59049
- (0, import_node_fs28.rmSync)(tempHome, { recursive: true, force: true });
59214
+ (0, import_node_fs29.rmSync)(tempHome, { recursive: true, force: true });
59050
59215
  const msg = err instanceof AwareError ? err.message : String(err?.message ?? err);
59051
59216
  return reply.status(422).send({ ok: false, error: msg });
59052
59217
  }
59053
59218
  const manifest = readStagedManifest(result.agentDir);
59054
59219
  if (!manifest) {
59055
- (0, import_node_fs28.rmSync)(tempHome, { recursive: true, force: true });
59220
+ (0, import_node_fs29.rmSync)(tempHome, { recursive: true, force: true });
59056
59221
  return reply.status(502).send({ ok: false, error: `build produced output at ${result.agentDir} but no manifest.yaml` });
59057
59222
  }
59058
59223
  const token = (0, import_node_crypto7.randomUUID)();
59059
59224
  registerStage(token, tempHome, result.agentId);
59060
59225
  const preview = buildPreview(manifest, sourceKind, sourceRef, token);
59061
- if ((0, import_node_fs28.existsSync)((0, import_node_path26.join)(graftAgentsDir(), result.agentId))) {
59226
+ if ((0, import_node_fs29.existsSync)((0, import_node_path27.join)(graftAgentsDir(), result.agentId))) {
59062
59227
  preview.warnings.unshift(`An agent named "${result.agentId}" is already installed \u2014 creating it will overwrite it.`);
59063
59228
  }
59064
59229
  return { ok: true, preview };
@@ -59077,7 +59242,7 @@ async function startServer() {
59077
59242
  registerStage(stagedRef, stage.tempDir, stage.agentId);
59078
59243
  return reply.status(409).send({ ok: false, error: err.message, agentId: stage.agentId, collision: true });
59079
59244
  }
59080
- (0, import_node_fs28.rmSync)(stage.tempDir, { recursive: true, force: true });
59245
+ (0, import_node_fs29.rmSync)(stage.tempDir, { recursive: true, force: true });
59081
59246
  throw err;
59082
59247
  }
59083
59248
  broadcast({ type: "grafted", id: stage.agentId });
@@ -59310,11 +59475,11 @@ async function startServer() {
59310
59475
  app.get("/api/requests/:id/snapshot/:n", async (req, reply) => {
59311
59476
  const n = Number.parseInt(req.params.n, 10);
59312
59477
  const p = Number.isInteger(n) ? snapshotPathFor(req.params.id, n) : null;
59313
- if (!p || !(0, import_node_fs28.existsSync)(p)) return reply.status(404).send({ ok: false, error: "snapshot not found" });
59478
+ if (!p || !(0, import_node_fs29.existsSync)(p)) return reply.status(404).send({ ok: false, error: "snapshot not found" });
59314
59479
  const ext = p.split(".").pop().toLowerCase();
59315
59480
  reply.header("Content-Type", ext === "png" ? "image/png" : ext === "webp" ? "image/webp" : ext === "pdf" ? "application/pdf" : "image/jpeg");
59316
59481
  reply.header("Cache-Control", "no-store");
59317
- return (0, import_node_fs28.readFileSync)(p);
59482
+ return (0, import_node_fs29.readFileSync)(p);
59318
59483
  });
59319
59484
  app.post(
59320
59485
  "/api/tweak",
@@ -59464,7 +59629,7 @@ async function startServer() {
59464
59629
  warn(`last-run-status:${ref} \u2014 trace exists but couldn't be parsed (corrupt/truncated)`);
59465
59630
  let finishedAt2 = null;
59466
59631
  try {
59467
- finishedAt2 = (0, import_node_fs28.statSync)(latest.path).mtime.toISOString();
59632
+ finishedAt2 = (0, import_node_fs29.statSync)(latest.path).mtime.toISOString();
59468
59633
  } catch {
59469
59634
  finishedAt2 = null;
59470
59635
  }
@@ -59474,7 +59639,7 @@ async function startServer() {
59474
59639
  let finishedAt = typeof runEnd?.ts === "string" ? runEnd.ts : null;
59475
59640
  if (!finishedAt) {
59476
59641
  try {
59477
- finishedAt = (0, import_node_fs28.statSync)(latest.path).mtime.toISOString();
59642
+ finishedAt = (0, import_node_fs29.statSync)(latest.path).mtime.toISOString();
59478
59643
  } catch {
59479
59644
  finishedAt = null;
59480
59645
  }