@floless/app 0.11.0 → 0.12.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.
@@ -294,41 +294,41 @@ var require_queue = __commonJS({
294
294
  queue2.drained = drained;
295
295
  return queue2;
296
296
  function push(value) {
297
- var p = new Promise(function(resolve4, reject) {
297
+ var p = new Promise(function(resolve5, reject) {
298
298
  pushCb(value, function(err, result) {
299
299
  if (err) {
300
300
  reject(err);
301
301
  return;
302
302
  }
303
- resolve4(result);
303
+ resolve5(result);
304
304
  });
305
305
  });
306
306
  p.catch(noop);
307
307
  return p;
308
308
  }
309
309
  function unshift(value) {
310
- var p = new Promise(function(resolve4, reject) {
310
+ var p = new Promise(function(resolve5, reject) {
311
311
  unshiftCb(value, function(err, result) {
312
312
  if (err) {
313
313
  reject(err);
314
314
  return;
315
315
  }
316
- resolve4(result);
316
+ resolve5(result);
317
317
  });
318
318
  });
319
319
  p.catch(noop);
320
320
  return p;
321
321
  }
322
322
  function drained() {
323
- var p = new Promise(function(resolve4) {
323
+ var p = new Promise(function(resolve5) {
324
324
  process.nextTick(function() {
325
325
  if (queue2.idle()) {
326
- resolve4();
326
+ resolve5();
327
327
  } else {
328
328
  var previousDrain = queue2.drain;
329
329
  queue2.drain = function() {
330
330
  if (typeof previousDrain === "function") previousDrain();
331
- resolve4();
331
+ resolve5();
332
332
  queue2.drain = previousDrain;
333
333
  };
334
334
  }
@@ -671,8 +671,8 @@ var require_create_promise = __commonJS({
671
671
  reject: null,
672
672
  promise: null
673
673
  };
674
- obj.promise = new Promise((resolve4, reject) => {
675
- obj.resolve = resolve4;
674
+ obj.promise = new Promise((resolve5, reject) => {
675
+ obj.resolve = resolve5;
676
676
  obj.reject = reject;
677
677
  });
678
678
  return obj;
@@ -941,11 +941,11 @@ var require_thenify = __commonJS({
941
941
  return;
942
942
  }
943
943
  debug("thenify");
944
- return (resolve4, reject) => {
944
+ return (resolve5, reject) => {
945
945
  const p = this._loadRegistered();
946
946
  return p.then(() => {
947
947
  this[kThenifyDoNotWrap] = true;
948
- return resolve4(this._server);
948
+ return resolve5(this._server);
949
949
  }, reject);
950
950
  };
951
951
  }
@@ -1082,12 +1082,12 @@ var require_boot = __commonJS({
1082
1082
  inherits(Boot, EE);
1083
1083
  if ("asyncDispose" in Symbol) {
1084
1084
  Boot.prototype[Symbol.asyncDispose] = function() {
1085
- return new Promise((resolve4, reject) => {
1085
+ return new Promise((resolve5, reject) => {
1086
1086
  this.close((err) => {
1087
1087
  if (err) {
1088
1088
  return reject(err);
1089
1089
  }
1090
- resolve4();
1090
+ resolve5();
1091
1091
  });
1092
1092
  });
1093
1093
  };
@@ -1234,12 +1234,12 @@ var require_boot = __commonJS({
1234
1234
  throw new AVV_ERR_CALLBACK_NOT_FN("close", typeof func);
1235
1235
  }
1236
1236
  } else {
1237
- promise = new Promise(function(resolve4, reject) {
1237
+ promise = new Promise(function(resolve5, reject) {
1238
1238
  func = function(err) {
1239
1239
  if (err) {
1240
1240
  return reject(err);
1241
1241
  }
1242
- resolve4();
1242
+ resolve5();
1243
1243
  };
1244
1244
  });
1245
1245
  }
@@ -1259,7 +1259,7 @@ var require_boot = __commonJS({
1259
1259
  queueMicrotask(this.start.bind(this));
1260
1260
  return;
1261
1261
  }
1262
- return new Promise((resolve4, reject) => {
1262
+ return new Promise((resolve5, reject) => {
1263
1263
  this._readyQ.push(readyPromiseCB);
1264
1264
  this.start();
1265
1265
  const relativeContext = this._current[0].server;
@@ -1267,7 +1267,7 @@ var require_boot = __commonJS({
1267
1267
  if (err) {
1268
1268
  reject(err);
1269
1269
  } else {
1270
- resolve4(relativeContext);
1270
+ resolve5(relativeContext);
1271
1271
  }
1272
1272
  process.nextTick(done);
1273
1273
  }
@@ -2542,8 +2542,8 @@ var require_promise = __commonJS({
2542
2542
  var { kTestInternals } = require_symbols2();
2543
2543
  function withResolvers() {
2544
2544
  let res, rej;
2545
- const promise = new Promise((resolve4, reject) => {
2546
- res = resolve4;
2545
+ const promise = new Promise((resolve5, reject) => {
2546
+ res = resolve5;
2547
2547
  rej = reject;
2548
2548
  });
2549
2549
  return { promise, resolve: res, reject: rej };
@@ -2642,15 +2642,15 @@ var require_server = __commonJS({
2642
2642
  if (cb === void 0) {
2643
2643
  const listening = listenPromise.call(this, server, listenOptions);
2644
2644
  return listening.then((address) => {
2645
- const { promise, resolve: resolve4 } = PonyPromise.withResolvers();
2645
+ const { promise, resolve: resolve5 } = PonyPromise.withResolvers();
2646
2646
  if (host === "localhost") {
2647
2647
  multipleBindings.call(this, server, httpHandler, options, listenOptions, () => {
2648
2648
  this[kState].listening = true;
2649
- resolve4(address);
2649
+ resolve5(address);
2650
2650
  onListenHookRunner(this);
2651
2651
  });
2652
2652
  } else {
2653
- resolve4(address);
2653
+ resolve5(address);
2654
2654
  onListenHookRunner(this);
2655
2655
  }
2656
2656
  return promise;
@@ -2777,7 +2777,7 @@ var require_server = __commonJS({
2777
2777
  }
2778
2778
  return this.ready().then(() => {
2779
2779
  if (this[kState].aborted) return;
2780
- const { promise, resolve: resolve4, reject } = PonyPromise.withResolvers();
2780
+ const { promise, resolve: resolve5, reject } = PonyPromise.withResolvers();
2781
2781
  const errEventHandler = (err) => {
2782
2782
  cleanup();
2783
2783
  this[kState].listening = false;
@@ -2786,7 +2786,7 @@ var require_server = __commonJS({
2786
2786
  const listeningEventHandler = () => {
2787
2787
  cleanup();
2788
2788
  this[kState].listening = true;
2789
- resolve4(logServerAddress.call(
2789
+ resolve5(logServerAddress.call(
2790
2790
  this,
2791
2791
  server,
2792
2792
  listenOptions.listenTextResolver || defaultResolveServerListeningText
@@ -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: join20 } = require("path");
5492
+ var { join: join22 } = 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"] || join20(__dirname, "lib", "worker.js");
5543
+ const toExecute = bundlerOverrides["thread-stream-worker"] || join22(__dirname, "lib", "worker.js");
5544
5544
  const worker = new Worker(toExecute, {
5545
5545
  ...opts.workerOpts,
5546
5546
  name: opts.workerOpts?.name || "thread-stream",
@@ -6006,9 +6006,9 @@ 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: existsSync18 } = require("node:fs");
6009
+ var { existsSync: existsSync20 } = require("node:fs");
6010
6010
  var getCallers = require_caller();
6011
- var { join: join20, isAbsolute: isAbsolute2, sep: sep3 } = require("node:path");
6011
+ var { join: join22, isAbsolute: isAbsolute2, sep: sep3 } = require("node:path");
6012
6012
  var { fileURLToPath: fileURLToPath4 } = require("node:url");
6013
6013
  var sleep = require_atomic_sleep();
6014
6014
  var onExit = require_on_exit_leak_free();
@@ -6080,7 +6080,7 @@ var require_transport = __commonJS({
6080
6080
  return false;
6081
6081
  }
6082
6082
  }
6083
- return isAbsolute2(path) && !existsSync18(path);
6083
+ return isAbsolute2(path) && !existsSync20(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"] || join20(__dirname, "worker.js");
6164
+ target = bundlerOverrides["pino-worker"] || join22(__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"] || join20(__dirname, "worker.js");
6182
+ target = bundlerOverrides["pino-worker"] || join22(__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 join20(__dirname, "..", "file.js");
6205
+ return join22(__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 join20 = ",";
7185
+ let join22 = ",";
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
- join20 = `,
7199
+ join22 = `,
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 += join20;
7207
+ res += join22;
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 += `${join20}"... ${getItemCount(removedKeys)} not stringified"`;
7213
+ res += `${join22}"... ${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
- join20 = `,
7234
+ join22 = `,
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 = join20;
7248
+ separator = join22;
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 = join20;
7254
+ separator = join22;
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 join20 = ",";
7295
+ let join22 = ",";
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
- join20 = `,
7308
+ join22 = `,
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 += join20;
7316
+ res += join22;
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 += `${join20}"... ${getItemCount(removedKeys)} not stringified"`;
7322
+ res += `${join22}"... ${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
- join20 = `,
7335
+ join22 = `,
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 = join20;
7344
+ separator = join22;
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 join21 = `,
7402
+ const join23 = `,
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 += join21;
7409
+ res2 += join23;
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 += `${join21}"... ${getItemCount(removedKeys)} not stringified"`;
7415
+ res2 += `${join23}"... ${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 join20 = `,
7431
+ const join22 = `,
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, join20, maximumBreadth);
7437
+ res += stringifyTypedArray(value, join22, maximumBreadth);
7438
7438
  keys = keys.slice(value.length);
7439
7439
  maximumPropertiesToStringify -= value.length;
7440
- separator = join20;
7440
+ separator = join22;
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 = join20;
7451
+ separator = join22;
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 = join20;
7457
+ separator = join22;
7458
7458
  }
7459
7459
  if (separator !== "") {
7460
7460
  res = `
@@ -15309,7 +15309,7 @@ var require_compile = __commonJS({
15309
15309
  const schOrFunc = root.refs[ref];
15310
15310
  if (schOrFunc)
15311
15311
  return schOrFunc;
15312
- let _sch = resolve4.call(this, root, ref);
15312
+ let _sch = resolve5.call(this, root, ref);
15313
15313
  if (_sch === void 0) {
15314
15314
  const schema = (_a = root.localRefs) === null || _a === void 0 ? void 0 : _a[ref];
15315
15315
  const { schemaId } = this.opts;
@@ -15336,7 +15336,7 @@ var require_compile = __commonJS({
15336
15336
  function sameSchemaEnv(s1, s2) {
15337
15337
  return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
15338
15338
  }
15339
- function resolve4(root, ref) {
15339
+ function resolve5(root, ref) {
15340
15340
  let sch;
15341
15341
  while (typeof (sch = this.refs[ref]) == "string")
15342
15342
  ref = sch;
@@ -15967,7 +15967,7 @@ var require_fast_uri = __commonJS({
15967
15967
  }
15968
15968
  return uri;
15969
15969
  }
15970
- function resolve4(baseURI, relativeURI, options) {
15970
+ function resolve5(baseURI, relativeURI, options) {
15971
15971
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
15972
15972
  const resolved = resolveComponent(parse(baseURI, schemelessOptions), parse(relativeURI, schemelessOptions), schemelessOptions, true);
15973
15973
  schemelessOptions.skipEscape = true;
@@ -16225,7 +16225,7 @@ var require_fast_uri = __commonJS({
16225
16225
  var fastUri = {
16226
16226
  SCHEMES,
16227
16227
  normalize: normalize2,
16228
- resolve: resolve4,
16228
+ resolve: resolve5,
16229
16229
  resolveComponent,
16230
16230
  equal,
16231
16231
  serialize,
@@ -32061,7 +32061,7 @@ var require_parse_url = __commonJS({
32061
32061
  var require_form_data = __commonJS({
32062
32062
  "node_modules/light-my-request/lib/form-data.js"(exports2, module2) {
32063
32063
  "use strict";
32064
- var { randomUUID: randomUUID4 } = require("node:crypto");
32064
+ var { randomUUID: randomUUID5 } = require("node:crypto");
32065
32065
  var { Readable: Readable3 } = require("node:stream");
32066
32066
  var textEncoder;
32067
32067
  function isFormDataLike(payload) {
@@ -32069,7 +32069,7 @@ var require_form_data = __commonJS({
32069
32069
  }
32070
32070
  function formDataToStream(formdata) {
32071
32071
  textEncoder = textEncoder ?? new TextEncoder();
32072
- const boundary = `----formdata-${randomUUID4()}`;
32072
+ const boundary = `----formdata-${randomUUID5()}`;
32073
32073
  const prefix = `--${boundary}\r
32074
32074
  Content-Disposition: form-data`;
32075
32075
  const escape2 = (str) => str.replace(/\n/g, "%0A").replace(/\r/g, "%0D").replace(/"/g, "%22");
@@ -33572,9 +33572,9 @@ var require_light_my_request = __commonJS({
33572
33572
  const res = new Response(req, callback);
33573
33573
  return makeRequest(dispatchFunc, server, req, res);
33574
33574
  } else {
33575
- return new Promise((resolve4, reject) => {
33575
+ return new Promise((resolve5, reject) => {
33576
33576
  const req = new RequestConstructor(options);
33577
- const res = new Response(req, resolve4, reject);
33577
+ const res = new Response(req, resolve5, reject);
33578
33578
  makeRequest(dispatchFunc, server, req, res);
33579
33579
  });
33580
33580
  }
@@ -37706,10 +37706,10 @@ var require_commonjs4 = __commonJS({
37706
37706
  * Return a void Promise that resolves once the stream ends.
37707
37707
  */
37708
37708
  async promise() {
37709
- return new Promise((resolve4, reject) => {
37709
+ return new Promise((resolve5, reject) => {
37710
37710
  this.on(DESTROYED, () => reject(new Error("stream destroyed")));
37711
37711
  this.on("error", (er) => reject(er));
37712
- this.on("end", () => resolve4());
37712
+ this.on("end", () => resolve5());
37713
37713
  });
37714
37714
  }
37715
37715
  /**
@@ -37733,7 +37733,7 @@ var require_commonjs4 = __commonJS({
37733
37733
  return Promise.resolve({ done: false, value: res });
37734
37734
  if (this[EOF])
37735
37735
  return stop();
37736
- let resolve4;
37736
+ let resolve5;
37737
37737
  let reject;
37738
37738
  const onerr = (er) => {
37739
37739
  this.off("data", ondata);
@@ -37747,19 +37747,19 @@ var require_commonjs4 = __commonJS({
37747
37747
  this.off("end", onend);
37748
37748
  this.off(DESTROYED, ondestroy);
37749
37749
  this.pause();
37750
- resolve4({ value, done: !!this[EOF] });
37750
+ resolve5({ value, done: !!this[EOF] });
37751
37751
  };
37752
37752
  const onend = () => {
37753
37753
  this.off("error", onerr);
37754
37754
  this.off("data", ondata);
37755
37755
  this.off(DESTROYED, ondestroy);
37756
37756
  stop();
37757
- resolve4({ done: true, value: void 0 });
37757
+ resolve5({ done: true, value: void 0 });
37758
37758
  };
37759
37759
  const ondestroy = () => onerr(new Error("stream destroyed"));
37760
37760
  return new Promise((res2, rej) => {
37761
37761
  reject = rej;
37762
- resolve4 = res2;
37762
+ resolve5 = res2;
37763
37763
  this.once(DESTROYED, ondestroy);
37764
37764
  this.once("error", onerr);
37765
37765
  this.once("end", onend);
@@ -38779,9 +38779,9 @@ var require_commonjs5 = __commonJS({
38779
38779
  if (this.#asyncReaddirInFlight) {
38780
38780
  await this.#asyncReaddirInFlight;
38781
38781
  } else {
38782
- let resolve4 = () => {
38782
+ let resolve5 = () => {
38783
38783
  };
38784
- this.#asyncReaddirInFlight = new Promise((res) => resolve4 = res);
38784
+ this.#asyncReaddirInFlight = new Promise((res) => resolve5 = res);
38785
38785
  try {
38786
38786
  for (const e of await this.#fs.promises.readdir(fullpath, {
38787
38787
  withFileTypes: true
@@ -38794,7 +38794,7 @@ var require_commonjs5 = __commonJS({
38794
38794
  children.provisional = 0;
38795
38795
  }
38796
38796
  this.#asyncReaddirInFlight = void 0;
38797
- resolve4();
38797
+ resolve5();
38798
38798
  }
38799
38799
  return children.slice(0, children.provisional);
38800
38800
  }
@@ -41991,9 +41991,9 @@ var require_send = __commonJS({
41991
41991
  var { parseTokenList } = require_parseTokenList();
41992
41992
  var { createHttpError } = require_createHttpError();
41993
41993
  var extname2 = path.extname;
41994
- var join20 = path.join;
41994
+ var join22 = path.join;
41995
41995
  var normalize2 = path.normalize;
41996
- var resolve4 = path.resolve;
41996
+ var resolve5 = path.resolve;
41997
41997
  var sep3 = path.sep;
41998
41998
  var Readable3 = stream.Readable;
41999
41999
  var BYTES_RANGE_REGEXP = /^ *bytes=/;
@@ -42040,7 +42040,7 @@ var require_send = __commonJS({
42040
42040
  const lastModified = options.lastModified !== void 0 ? Boolean(options.lastModified) : true;
42041
42041
  const maxage = normalizeMaxAge(options.maxAge ?? options.maxage);
42042
42042
  const maxContentRangeChunkSize = options.maxContentRangeChunkSize !== void 0 ? Number(options.maxContentRangeChunkSize) : null;
42043
- const root = options.root ? resolve4(options.root) : null;
42043
+ const root = options.root ? resolve5(options.root) : null;
42044
42044
  const highWaterMark = Number.isSafeInteger(options.highWaterMark) && options.highWaterMark > 0 ? options.highWaterMark : null;
42045
42045
  return {
42046
42046
  acceptRanges,
@@ -42078,14 +42078,14 @@ var require_send = __commonJS({
42078
42078
  return { statusCode: 403 };
42079
42079
  }
42080
42080
  parts = path2.split(sep3);
42081
- path2 = normalize2(join20(root, path2));
42081
+ path2 = normalize2(join22(root, path2));
42082
42082
  } else {
42083
42083
  if (UP_PATH_REGEXP.test(path2)) {
42084
42084
  debug('malicious path "%s"', path2);
42085
42085
  return { statusCode: 403 };
42086
42086
  }
42087
42087
  parts = normalize2(path2).split(sep3);
42088
- path2 = resolve4(path2);
42088
+ path2 = resolve5(path2);
42089
42089
  }
42090
42090
  return { path: path2, parts };
42091
42091
  }
@@ -42181,9 +42181,9 @@ var require_send = __commonJS({
42181
42181
  );
42182
42182
  }
42183
42183
  function tryStat(path2) {
42184
- return new Promise((resolve5) => {
42184
+ return new Promise((resolve6) => {
42185
42185
  fs.stat(path2, function onstat(error, stat4) {
42186
- resolve5({ error, stat: stat4 });
42186
+ resolve6({ error, stat: stat4 });
42187
42187
  });
42188
42188
  });
42189
42189
  }
@@ -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 = join20(path2, index);
42364
+ const p = join22(path2, index);
42365
42365
  const { error, stat: stat4 } = await tryStat(p);
42366
42366
  if (error) {
42367
42367
  err = error;
@@ -43012,7 +43012,7 @@ var require_static = __commonJS({
43012
43012
  "use strict";
43013
43013
  var path = require("node:path");
43014
43014
  var { fileURLToPath: fileURLToPath4 } = require("node:url");
43015
- var { statSync: statSync5 } = require("node:fs");
43015
+ var { statSync: statSync7 } = require("node:fs");
43016
43016
  var { glob } = require_commonjs6();
43017
43017
  var fp = require_plugin2();
43018
43018
  var send = require_send2();
@@ -43145,8 +43145,8 @@ var require_static = __commonJS({
43145
43145
  }
43146
43146
  }
43147
43147
  }
43148
- for (const [dirname9, rootPath] of indexDirs.entries()) {
43149
- const pathname = dirname9 + (dirname9.endsWith("/") ? "" : "/");
43148
+ for (const [dirname10, rootPath] of indexDirs.entries()) {
43149
+ const pathname = dirname10 + (dirname10.endsWith("/") ? "" : "/");
43150
43150
  const file = "/" + pathname.replace(prefix, "");
43151
43151
  setUpHeadAndGet(routeOpts, pathname, file, rootPath);
43152
43152
  if (opts.redirect === true) {
@@ -43375,7 +43375,7 @@ var require_static = __commonJS({
43375
43375
  }
43376
43376
  let pathStat;
43377
43377
  try {
43378
- pathStat = statSync5(rootPath);
43378
+ pathStat = statSync7(rootPath);
43379
43379
  } catch (e) {
43380
43380
  if (e.code === "ENOENT") {
43381
43381
  fastify.log.warn(`"root" path "${rootPath}" must exist`);
@@ -43399,7 +43399,7 @@ var require_static = __commonJS({
43399
43399
  return indexFiles.find((filename) => {
43400
43400
  const p = path.join(root, pathname, filename);
43401
43401
  try {
43402
- const stats = statSync5(p);
43402
+ const stats = statSync7(p);
43403
43403
  return !stats.isDirectory();
43404
43404
  } catch {
43405
43405
  return false;
@@ -50827,9 +50827,9 @@ var import_node_readline2 = require("node:readline");
50827
50827
 
50828
50828
  // index.ts
50829
50829
  var import_node_url3 = require("node:url");
50830
- var import_node_path18 = require("node:path");
50831
- var import_node_os12 = require("node:os");
50832
- var import_node_fs19 = require("node:fs");
50830
+ var import_node_path20 = require("node:path");
50831
+ var import_node_os13 = require("node:os");
50832
+ var import_node_fs21 = require("node:fs");
50833
50833
  var import_node_child_process6 = require("node:child_process");
50834
50834
 
50835
50835
  // log.mjs
@@ -50878,6 +50878,7 @@ var import_node_child_process = require("node:child_process");
50878
50878
  var import_node_fs4 = require("node:fs");
50879
50879
  var import_node_path3 = require("node:path");
50880
50880
  var import_node_os3 = require("node:os");
50881
+ var import_node_crypto2 = require("node:crypto");
50881
50882
  var import_node_module = require("node:module");
50882
50883
 
50883
50884
  // app-reader.ts
@@ -51183,6 +51184,12 @@ var AwareError = class extends Error {
51183
51184
  }
51184
51185
  detail;
51185
51186
  };
51187
+ var AwareUnsupportedError = class extends AwareError {
51188
+ constructor(message, detail) {
51189
+ super(message, detail);
51190
+ this.name = "AwareUnsupportedError";
51191
+ }
51192
+ };
51186
51193
  function resolveInvoker() {
51187
51194
  const envDir = process.env.AWARE_CLI_DIR;
51188
51195
  if (envDir && (0, import_node_fs4.existsSync)((0, import_node_path3.join)(envDir, "scripts/bin/aware.js"))) {
@@ -51225,7 +51232,7 @@ function runRaw(args, onSpawn) {
51225
51232
  if (bad !== void 0) throw new AwareError(`refusing to pass unsafe argument to shell: ${bad}`);
51226
51233
  }
51227
51234
  const argv = [...preArgs, ...args];
51228
- return new Promise((resolve4, reject) => {
51235
+ return new Promise((resolve5, reject) => {
51229
51236
  const child = (0, import_node_child_process.spawn)(bin, argv, { shell: invoker.shell, windowsHide: true });
51230
51237
  onSpawn?.(child);
51231
51238
  let stdout = "";
@@ -51243,7 +51250,7 @@ function runRaw(args, onSpawn) {
51243
51250
  });
51244
51251
  child.on("close", (code) => {
51245
51252
  clearTimeout(timer);
51246
- resolve4({ code: code ?? -1, stdout, stderr });
51253
+ resolve5({ code: code ?? -1, stdout, stderr });
51247
51254
  });
51248
51255
  });
51249
51256
  }
@@ -51257,7 +51264,7 @@ function runRawWithEnv(args, env2, timeoutMs) {
51257
51264
  }
51258
51265
  const argv = [...preArgs, ...args];
51259
51266
  const limit = timeoutMs ?? RUN_TIMEOUT_MS;
51260
- return new Promise((resolve4, reject) => {
51267
+ return new Promise((resolve5, reject) => {
51261
51268
  const child = (0, import_node_child_process.spawn)(bin, argv, { shell: invoker.shell, windowsHide: true, env: env2 ?? process.env });
51262
51269
  let stdout = "";
51263
51270
  let stderr = "";
@@ -51274,7 +51281,7 @@ function runRawWithEnv(args, env2, timeoutMs) {
51274
51281
  });
51275
51282
  child.on("close", (code) => {
51276
51283
  clearTimeout(timer);
51277
- resolve4({ code: code ?? -1, stdout, stderr });
51284
+ resolve5({ code: code ?? -1, stdout, stderr });
51278
51285
  });
51279
51286
  });
51280
51287
  }
@@ -51324,7 +51331,7 @@ async function execTekla(code, opts = {}) {
51324
51331
  args: opts.args ?? {}
51325
51332
  });
51326
51333
  const timeoutMs = opts.debug ? 15 * 6e4 : RUN_TIMEOUT_MS;
51327
- return new Promise((resolve4, reject) => {
51334
+ return new Promise((resolve5, reject) => {
51328
51335
  const child = (0, import_node_child_process.spawn)(bin, ["exec", "--version", version, "--json-stdin"], { windowsHide: true });
51329
51336
  let stdout = "";
51330
51337
  let stderr = "";
@@ -51352,7 +51359,7 @@ async function execTekla(code, opts = {}) {
51352
51359
  })
51353
51360
  );
51354
51361
  }
51355
- resolve4(parsed);
51362
+ resolve5(parsed);
51356
51363
  });
51357
51364
  child.stdin.write(payload);
51358
51365
  child.stdin.end();
@@ -51423,17 +51430,31 @@ function latestTracePath(id, logsRoot = LOGS_DIR) {
51423
51430
  }
51424
51431
  return best ? best.path : null;
51425
51432
  }
51426
- function readLatestTrace(id, logsRoot = LOGS_DIR) {
51433
+ function readTail(path, maxBytes) {
51434
+ const size = (0, import_node_fs4.statSync)(path).size;
51435
+ if (size <= maxBytes) return { text: (0, import_node_fs4.readFileSync)(path, "utf8"), truncated: false };
51436
+ const fd = (0, import_node_fs4.openSync)(path, "r");
51437
+ try {
51438
+ const buf = Buffer.alloc(maxBytes);
51439
+ const read = (0, import_node_fs4.readSync)(fd, buf, 0, maxBytes, size - maxBytes);
51440
+ const nl = buf.indexOf(10, 0);
51441
+ const start = nl >= 0 && nl + 1 <= read ? nl + 1 : 0;
51442
+ return { text: buf.subarray(start, read).toString("utf8"), truncated: true };
51443
+ } finally {
51444
+ (0, import_node_fs4.closeSync)(fd);
51445
+ }
51446
+ }
51447
+ function readLatestTrace(id, logsRoot = LOGS_DIR, maxBytes) {
51427
51448
  const p = latestTracePath(id, logsRoot);
51428
51449
  if (!p) return null;
51429
- let text;
51450
+ let read;
51430
51451
  try {
51431
- text = (0, import_node_fs4.readFileSync)(p, "utf8");
51452
+ read = maxBytes && maxBytes > 0 ? readTail(p, maxBytes) : { text: (0, import_node_fs4.readFileSync)(p, "utf8"), truncated: false };
51432
51453
  } catch {
51433
51454
  return null;
51434
51455
  }
51435
51456
  const runId = p.split(/[\\/]/).pop()?.replace(/\.jsonl$/, "") ?? "";
51436
- return { runId, path: p, text };
51457
+ return { runId, path: p, text: read.text, truncated: read.truncated };
51437
51458
  }
51438
51459
  function startTrigger(id, opts = {}) {
51439
51460
  assertId(id);
@@ -51611,6 +51632,19 @@ function parseAgentInstallOutput(stdout) {
51611
51632
  function isAgentInstalled(agents, id) {
51612
51633
  return agents.some((a) => a.id === id);
51613
51634
  }
51635
+ function agentInvokeArgv(agent, command, inputsRef) {
51636
+ assertId(agent);
51637
+ if (!APP_ID.test(command)) throw new AwareError(`invalid agent command: ${JSON.stringify(command)}`);
51638
+ const args = ["agent", "invoke", agent, command];
51639
+ if (inputsRef !== void 0) args.push("--inputs", inputsRef);
51640
+ return args;
51641
+ }
51642
+ function isInvokeUnsupported(detail) {
51643
+ if (!detail || typeof detail !== "object") return false;
51644
+ const d = detail;
51645
+ const text = [d.stdout, d.stderr].filter((s) => typeof s === "string").join("\n");
51646
+ return /unrecognized subcommand|unknown subcommand/i.test(text);
51647
+ }
51614
51648
  var inFlightConnects = /* @__PURE__ */ new Map();
51615
51649
  function cancelAllConnects() {
51616
51650
  for (const cancel of inFlightConnects.values()) cancel();
@@ -51623,7 +51657,7 @@ function connectDeviceCode(id, onEvent) {
51623
51657
  if (!bin) throw new AwareError("aware CLI invoker not resolved");
51624
51658
  inFlightConnects.get(id)?.();
51625
51659
  const argv = [...preArgs, "connect", id, "--device-code", "--json"];
51626
- return new Promise((resolve4, reject) => {
51660
+ return new Promise((resolve5, reject) => {
51627
51661
  const child = (0, import_node_child_process.spawn)(bin, argv, { shell: invoker.shell, windowsHide: true });
51628
51662
  let buf = "";
51629
51663
  let gotPrompt = false;
@@ -51649,7 +51683,7 @@ function connectDeviceCode(id, onEvent) {
51649
51683
  }
51650
51684
  if (!gotPrompt && obj.phase === "prompt" && typeof obj.user_code === "string") {
51651
51685
  gotPrompt = true;
51652
- resolve4({ prompt: obj, cancel });
51686
+ resolve5({ prompt: obj, cancel });
51653
51687
  } else {
51654
51688
  onEvent(obj);
51655
51689
  }
@@ -51733,6 +51767,43 @@ var aware = {
51733
51767
  const { data } = await runJson(["agent", "describe", assertId(id)]);
51734
51768
  return data;
51735
51769
  },
51770
+ /**
51771
+ * Invoke a BUILTIN agent command directly (`aware agent invoke <agent> <command>
51772
+ * --inputs @file --json`, CLI ≥ 0.63) and return the envelope's `data` — e.g.
51773
+ * `agentInvoke('ui','validate',{descriptor})` for Custom Panels validation.
51774
+ * Inputs always travel via a temp file (`--inputs @path`): inline JSON would trip
51775
+ * the shell-injection guard on the bare-PATH Windows fallback (quotes/braces are
51776
+ * SHELL_META) and a large descriptor could blow cmd.exe's argv limit. Throws
51777
+ * AwareUnsupportedError on a pre-0.63 CLI so callers can degrade ("update AWARE").
51778
+ */
51779
+ async agentInvoke(agent, command, inputs) {
51780
+ let inputsFile = null;
51781
+ try {
51782
+ let ref;
51783
+ if (inputs !== void 0) {
51784
+ inputsFile = (0, import_node_path3.join)((0, import_node_os3.tmpdir)(), `floless-agent-inputs-${(0, import_node_crypto2.randomUUID)()}.json`);
51785
+ (0, import_node_fs4.writeFileSync)(inputsFile, JSON.stringify(inputs));
51786
+ ref = `@${inputsFile}`;
51787
+ }
51788
+ const { data } = await runJson(agentInvokeArgv(agent, command, ref));
51789
+ return data;
51790
+ } catch (err) {
51791
+ if (err instanceof AwareError && isInvokeUnsupported(err.detail)) {
51792
+ throw new AwareUnsupportedError(
51793
+ `aware CLI does not support \`agent invoke\` (needs \u2265 0.63) \u2014 update AWARE`,
51794
+ err.detail
51795
+ );
51796
+ }
51797
+ throw err;
51798
+ } finally {
51799
+ if (inputsFile) {
51800
+ try {
51801
+ (0, import_node_fs4.rmSync)(inputsFile);
51802
+ } catch {
51803
+ }
51804
+ }
51805
+ }
51806
+ },
51736
51807
  /**
51737
51808
  * Graft: build an agent from a foreign source (`aware build agent --from-*`).
51738
51809
  * When `awareHome` is set the spawn writes into that staging dir (AWARE_HOME is
@@ -51875,6 +51946,170 @@ var aware = {
51875
51946
  connectList
51876
51947
  };
51877
51948
 
51949
+ // extensions-store.ts
51950
+ var import_node_fs5 = require("node:fs");
51951
+ var import_node_os4 = require("node:os");
51952
+ var import_node_path4 = require("node:path");
51953
+ var ROOT = process.env.FLOLESS_HOME ?? (0, import_node_path4.join)((0, import_node_os4.homedir)(), ".floless");
51954
+ var uiDir = (0, import_node_path4.join)(ROOT, "ui");
51955
+ var extensionsFile = (0, import_node_path4.join)(uiDir, "extensions.json");
51956
+ var HISTORY_DIR = (0, import_node_path4.join)(uiDir, "history");
51957
+ var HISTORY_KEEP = 20;
51958
+ function ensureUiDir() {
51959
+ if (!(0, import_node_fs5.existsSync)(uiDir)) (0, import_node_fs5.mkdirSync)(uiDir, { recursive: true });
51960
+ }
51961
+ function ensureHistoryDir() {
51962
+ if (!(0, import_node_fs5.existsSync)(HISTORY_DIR)) (0, import_node_fs5.mkdirSync)(HISTORY_DIR, { recursive: true });
51963
+ }
51964
+ function readExtensionsText() {
51965
+ try {
51966
+ return (0, import_node_fs5.readFileSync)(extensionsFile, "utf8");
51967
+ } catch {
51968
+ return null;
51969
+ }
51970
+ }
51971
+ function readExtensions() {
51972
+ const text = readExtensionsText();
51973
+ if (text === null) return null;
51974
+ try {
51975
+ const parsed = JSON.parse(text);
51976
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
51977
+ } catch {
51978
+ return null;
51979
+ }
51980
+ }
51981
+ function descriptorPanels(d) {
51982
+ if (!d || !Array.isArray(d.panels)) return [];
51983
+ return d.panels.filter((p) => !!p && typeof p === "object" && !Array.isArray(p));
51984
+ }
51985
+ function panelsCountOf(text) {
51986
+ try {
51987
+ const parsed = JSON.parse(text);
51988
+ return parsed && typeof parsed === "object" && Array.isArray(parsed.panels) ? parsed.panels.length : 0;
51989
+ } catch {
51990
+ return 0;
51991
+ }
51992
+ }
51993
+ function historyFileName(now) {
51994
+ const base = now.toISOString().replace(/[:.]/g, "-");
51995
+ let name = `${base}.json`;
51996
+ for (let i = 2; (0, import_node_fs5.existsSync)((0, import_node_path4.join)(HISTORY_DIR, name)); i++) name = `${base}-${i}.json`;
51997
+ return name;
51998
+ }
51999
+ function timestampFromName(file) {
52000
+ const m = /^(\d{4}-\d{2}-\d{2})T(\d{2})-(\d{2})-(\d{2})-(\d{3})Z(?:-\d+)?\.json$/.exec(file);
52001
+ return m ? `${m[1]}T${m[2]}:${m[3]}:${m[4]}.${m[5]}Z` : null;
52002
+ }
52003
+ function historyFiles() {
52004
+ if (!(0, import_node_fs5.existsSync)(HISTORY_DIR)) return [];
52005
+ try {
52006
+ return (0, import_node_fs5.readdirSync)(HISTORY_DIR).filter((f) => f.endsWith(".json")).sort();
52007
+ } catch {
52008
+ return [];
52009
+ }
52010
+ }
52011
+ function pruneHistory() {
52012
+ const files = historyFiles();
52013
+ for (const f of files.slice(0, Math.max(0, files.length - HISTORY_KEEP))) {
52014
+ try {
52015
+ (0, import_node_fs5.rmSync)((0, import_node_path4.join)(HISTORY_DIR, f));
52016
+ } catch {
52017
+ }
52018
+ }
52019
+ }
52020
+ function snapshotExtensions(content) {
52021
+ const text = content !== void 0 ? content : readExtensionsText();
52022
+ if (text === null) return null;
52023
+ const files = historyFiles();
52024
+ const newest = files[files.length - 1];
52025
+ if (newest) {
52026
+ try {
52027
+ if ((0, import_node_fs5.readFileSync)((0, import_node_path4.join)(HISTORY_DIR, newest), "utf8") === text) return (0, import_node_path4.join)(HISTORY_DIR, newest);
52028
+ } catch {
52029
+ }
52030
+ }
52031
+ ensureHistoryDir();
52032
+ const path = (0, import_node_path4.join)(HISTORY_DIR, historyFileName(/* @__PURE__ */ new Date()));
52033
+ const tmp = `${path}.${process.pid}.tmp`;
52034
+ (0, import_node_fs5.writeFileSync)(tmp, text);
52035
+ (0, import_node_fs5.renameSync)(tmp, path);
52036
+ pruneHistory();
52037
+ return path;
52038
+ }
52039
+ function listHistory() {
52040
+ return historyFiles().reverse().map((f) => {
52041
+ let ts = timestampFromName(f);
52042
+ if (!ts) {
52043
+ try {
52044
+ ts = (0, import_node_fs5.statSync)((0, import_node_path4.join)(HISTORY_DIR, f)).mtime.toISOString();
52045
+ } catch {
52046
+ ts = "";
52047
+ }
52048
+ }
52049
+ let count = 0;
52050
+ try {
52051
+ count = panelsCountOf((0, import_node_fs5.readFileSync)((0, import_node_path4.join)(HISTORY_DIR, f), "utf8"));
52052
+ } catch {
52053
+ }
52054
+ return { timestamp: ts ?? "", panelsCount: count };
52055
+ });
52056
+ }
52057
+ function writeExtensionsText(text) {
52058
+ ensureUiDir();
52059
+ const tmp = `${extensionsFile}.${process.pid}.tmp`;
52060
+ (0, import_node_fs5.writeFileSync)(tmp, text);
52061
+ (0, import_node_fs5.renameSync)(tmp, extensionsFile);
52062
+ }
52063
+ function undoExtensions() {
52064
+ const current = readExtensionsText();
52065
+ const files = historyFiles().reverse();
52066
+ let target = null;
52067
+ for (const f of files) {
52068
+ try {
52069
+ const text = (0, import_node_fs5.readFileSync)((0, import_node_path4.join)(HISTORY_DIR, f), "utf8");
52070
+ if (text !== current) {
52071
+ target = text;
52072
+ break;
52073
+ }
52074
+ } catch {
52075
+ }
52076
+ }
52077
+ if (target === null) return { restored: false, descriptor: readExtensions() };
52078
+ if (current !== null) snapshotExtensions(current);
52079
+ writeExtensionsText(target);
52080
+ return { restored: true, descriptor: readExtensions() };
52081
+ }
52082
+ function resetExtensions() {
52083
+ const current = readExtensionsText();
52084
+ if (current === null) return { reset: false };
52085
+ snapshotExtensions(current);
52086
+ try {
52087
+ (0, import_node_fs5.rmSync)(extensionsFile);
52088
+ } catch {
52089
+ }
52090
+ return { reset: true };
52091
+ }
52092
+
52093
+ // ui-validation.ts
52094
+ function isUiAgentMissing(err) {
52095
+ if (!(err instanceof AwareError)) return /not installed/i.test(String(err));
52096
+ const detail = err.detail ?? {};
52097
+ const stdout = typeof detail.stdout === "string" ? detail.stdout : "";
52098
+ const stderr = typeof detail.stderr === "string" ? detail.stderr : "";
52099
+ const text = `${err.message} ${stdout} ${stderr}`;
52100
+ return /not installed/i.test(text);
52101
+ }
52102
+ function classifyValidateError(err) {
52103
+ if (err instanceof AwareUnsupportedError) {
52104
+ return { valid: null, note: "aware CLI without ui agent \u2014 update AWARE" };
52105
+ }
52106
+ if (isUiAgentMissing(err)) {
52107
+ return { valid: null, note: "AWARE ui agent is installing \u2014 this validates itself in a moment", installing: true };
52108
+ }
52109
+ const msg = err instanceof Error ? err.message : String(err);
52110
+ return { valid: false, errors: [`Validation failed: ${msg}`], unexpected: true };
52111
+ }
52112
+
51878
52113
  // bootstrap.ts
51879
52114
  var VERSION_RE = /^\d+(\.\d+)*(-[0-9A-Za-z.-]+)?$/;
51880
52115
  function isValidVersion(v) {
@@ -51960,13 +52195,13 @@ function runBootstrap(deps) {
51960
52195
  }
51961
52196
 
51962
52197
  // licensing.ts
51963
- var import_node_fs5 = require("node:fs");
51964
- var import_node_path4 = require("node:path");
51965
- var import_node_os4 = require("node:os");
52198
+ var import_node_fs6 = require("node:fs");
52199
+ var import_node_path5 = require("node:path");
52200
+ var import_node_os5 = require("node:os");
51966
52201
  var import_node_child_process2 = require("node:child_process");
51967
- var import_node_crypto2 = require("node:crypto");
52202
+ var import_node_crypto3 = require("node:crypto");
51968
52203
  var import_node_module2 = require("node:module");
51969
- var import_node_os5 = require("node:os");
52204
+ var import_node_os6 = require("node:os");
51970
52205
  var ENVS = {
51971
52206
  production: { apiBase: "https://api.floless.io/api", webBase: "https://floless.io" },
51972
52207
  staging: { apiBase: "https://api.stage.floless.io/api", webBase: "https://stage.floless.io" }
@@ -52002,26 +52237,26 @@ function isSea() {
52002
52237
  }
52003
52238
  function storeDir() {
52004
52239
  if (process.env.FLOLESS_LICENSE_DIR) return process.env.FLOLESS_LICENSE_DIR;
52005
- if (isSea() && process.env.LOCALAPPDATA) return (0, import_node_path4.join)(process.env.LOCALAPPDATA, "FlolessApp-data");
52006
- return (0, import_node_path4.join)((0, import_node_os4.homedir)(), ".aware");
52240
+ if (isSea() && process.env.LOCALAPPDATA) return (0, import_node_path5.join)(process.env.LOCALAPPDATA, "FlolessApp-data");
52241
+ return (0, import_node_path5.join)((0, import_node_os5.homedir)(), ".aware");
52007
52242
  }
52008
- var tokenPath = () => (0, import_node_path4.join)(storeDir(), "floless-license.json");
52009
- var cachePath = () => (0, import_node_path4.join)(storeDir(), "floless-license-cache.json");
52243
+ var tokenPath = () => (0, import_node_path5.join)(storeDir(), "floless-license.json");
52244
+ var cachePath = () => (0, import_node_path5.join)(storeDir(), "floless-license-cache.json");
52010
52245
  var _migrated = false;
52011
52246
  function migrateLegacyStore() {
52012
52247
  if (_migrated) return;
52013
52248
  _migrated = true;
52014
52249
  if (process.env.FLOLESS_LICENSE_DIR || !(isSea() && process.env.LOCALAPPDATA)) return;
52015
- const oldDir = (0, import_node_path4.join)(process.env.LOCALAPPDATA, "FlolessApp");
52250
+ const oldDir = (0, import_node_path5.join)(process.env.LOCALAPPDATA, "FlolessApp");
52016
52251
  const newDir = storeDir();
52017
52252
  if (oldDir === newDir) return;
52018
52253
  for (const f of ["floless-license.json", "floless-license-cache.json", "floless-install-id"]) {
52019
52254
  try {
52020
- const oldP = (0, import_node_path4.join)(oldDir, f);
52021
- const newP = (0, import_node_path4.join)(newDir, f);
52022
- if ((0, import_node_fs5.existsSync)(oldP) && !(0, import_node_fs5.existsSync)(newP)) {
52023
- (0, import_node_fs5.mkdirSync)(newDir, { recursive: true });
52024
- (0, import_node_fs5.copyFileSync)(oldP, newP);
52255
+ const oldP = (0, import_node_path5.join)(oldDir, f);
52256
+ const newP = (0, import_node_path5.join)(newDir, f);
52257
+ if ((0, import_node_fs6.existsSync)(oldP) && !(0, import_node_fs6.existsSync)(newP)) {
52258
+ (0, import_node_fs6.mkdirSync)(newDir, { recursive: true });
52259
+ (0, import_node_fs6.copyFileSync)(oldP, newP);
52025
52260
  }
52026
52261
  } catch {
52027
52262
  }
@@ -52029,16 +52264,16 @@ function migrateLegacyStore() {
52029
52264
  }
52030
52265
  function readJson(path) {
52031
52266
  try {
52032
- return (0, import_node_fs5.existsSync)(path) ? JSON.parse((0, import_node_fs5.readFileSync)(path, "utf8")) : null;
52267
+ return (0, import_node_fs6.existsSync)(path) ? JSON.parse((0, import_node_fs6.readFileSync)(path, "utf8")) : null;
52033
52268
  } catch {
52034
52269
  return null;
52035
52270
  }
52036
52271
  }
52037
52272
  function writeJson(path, value) {
52038
- (0, import_node_fs5.mkdirSync)(storeDir(), { recursive: true });
52039
- (0, import_node_fs5.writeFileSync)(path, JSON.stringify(value, null, 2), "utf8");
52273
+ (0, import_node_fs6.mkdirSync)(storeDir(), { recursive: true });
52274
+ (0, import_node_fs6.writeFileSync)(path, JSON.stringify(value, null, 2), "utf8");
52040
52275
  try {
52041
- (0, import_node_fs5.chmodSync)(path, 384);
52276
+ (0, import_node_fs6.chmodSync)(path, 384);
52042
52277
  } catch {
52043
52278
  }
52044
52279
  }
@@ -52177,7 +52412,7 @@ async function ensureSeat(token) {
52177
52412
  const res = await fetch(`${env().apiBase}/seats/claim`, {
52178
52413
  method: "POST",
52179
52414
  headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
52180
- body: JSON.stringify({ device_fingerprint: installId(), device_name: (0, import_node_os5.hostname)(), os_version: `${process.platform} ${process.arch}` })
52415
+ body: JSON.stringify({ device_fingerprint: installId(), device_name: (0, import_node_os6.hostname)(), os_version: `${process.platform} ${process.arch}` })
52181
52416
  });
52182
52417
  if (!res.ok) return;
52183
52418
  const b = await res.json();
@@ -52198,7 +52433,7 @@ async function seatHeartbeat() {
52198
52433
  try {
52199
52434
  const token = await ensureFreshToken().catch(() => null);
52200
52435
  if (!token) return;
52201
- const hmac = (0, import_node_crypto2.createHmac)("sha256", seat.hmacSecret).update(seat.nonce).digest("hex");
52436
+ const hmac = (0, import_node_crypto3.createHmac)("sha256", seat.hmacSecret).update(seat.nonce).digest("hex");
52202
52437
  let res;
52203
52438
  try {
52204
52439
  res = await fetch(`${env().apiBase}/seats/heartbeat`, {
@@ -52268,7 +52503,7 @@ function logout() {
52268
52503
  resetSeat();
52269
52504
  for (const p of [tokenPath(), cachePath()]) {
52270
52505
  try {
52271
- (0, import_node_fs5.rmSync)(p, { force: true });
52506
+ (0, import_node_fs6.rmSync)(p, { force: true });
52272
52507
  } catch {
52273
52508
  }
52274
52509
  }
@@ -52292,7 +52527,7 @@ function openBrowser(url) {
52292
52527
  (0, import_node_child_process2.spawn)(cmd, args, opts).unref();
52293
52528
  }
52294
52529
  async function startLogin() {
52295
- const sessionId = (0, import_node_crypto2.randomUUID)();
52530
+ const sessionId = (0, import_node_crypto3.randomUUID)();
52296
52531
  const loginUrl = `${env().webBase}/login?desktop=true&session=${sessionId}&app=floless`;
52297
52532
  openBrowser(loginUrl);
52298
52533
  void pollDesktopStatus(sessionId).catch(() => {
@@ -52325,20 +52560,20 @@ async function pollDesktopStatus(sessionId, timeoutMs = 18e4) {
52325
52560
  return false;
52326
52561
  }
52327
52562
  function installId() {
52328
- const p = (0, import_node_path4.join)(storeDir(), "floless-install-id");
52563
+ const p = (0, import_node_path5.join)(storeDir(), "floless-install-id");
52329
52564
  const existing = readJson(p);
52330
52565
  if (typeof existing === "string" && existing.length >= 80 && existing.length <= 100) {
52331
52566
  return existing;
52332
52567
  }
52333
- const id = (0, import_node_crypto2.createHash)("sha512").update((0, import_node_crypto2.randomUUID)()).digest("base64");
52568
+ const id = (0, import_node_crypto3.createHash)("sha512").update((0, import_node_crypto3.randomUUID)()).digest("base64");
52334
52569
  writeJson(p, id);
52335
52570
  return id;
52336
52571
  }
52337
52572
 
52338
52573
  // version.ts
52339
52574
  var import_node_module3 = require("node:module");
52340
- var import_node_path5 = require("node:path");
52341
- var import_node_fs6 = require("node:fs");
52575
+ var import_node_path6 = require("node:path");
52576
+ var import_node_fs7 = require("node:fs");
52342
52577
  function resolveVersion(s) {
52343
52578
  if (s.isSea) {
52344
52579
  const m = s.sqVersionXml?.match(/<version>([^<]+)<\/version>/);
@@ -52357,8 +52592,8 @@ function isSea2() {
52357
52592
  }
52358
52593
  function readSqVersionXml() {
52359
52594
  try {
52360
- const sq = (0, import_node_path5.join)((0, import_node_path5.dirname)(process.execPath), "sq.version");
52361
- return (0, import_node_fs6.existsSync)(sq) ? (0, import_node_fs6.readFileSync)(sq, "utf8") : null;
52595
+ const sq = (0, import_node_path6.join)((0, import_node_path6.dirname)(process.execPath), "sq.version");
52596
+ return (0, import_node_fs7.existsSync)(sq) ? (0, import_node_fs7.readFileSync)(sq, "utf8") : null;
52362
52597
  } catch {
52363
52598
  return null;
52364
52599
  }
@@ -52374,7 +52609,7 @@ function appVersion() {
52374
52609
  return resolveVersion({
52375
52610
  isSea: isSea2(),
52376
52611
  sqVersionXml: readSqVersionXml(),
52377
- define: true ? "0.11.0" : void 0,
52612
+ define: true ? "0.12.1" : void 0,
52378
52613
  pkgVersion: readPkgVersion()
52379
52614
  });
52380
52615
  }
@@ -52384,14 +52619,14 @@ function resolveChannel(s) {
52384
52619
  return "dev";
52385
52620
  }
52386
52621
  function appChannel() {
52387
- return resolveChannel({ isSea: isSea2(), define: true ? "0.11.0" : void 0 });
52622
+ return resolveChannel({ isSea: isSea2(), define: true ? "0.12.1" : void 0 });
52388
52623
  }
52389
52624
 
52390
52625
  // oauth-presets.ts
52391
- var import_node_os6 = require("node:os");
52392
- var import_node_path6 = require("node:path");
52626
+ var import_node_os7 = require("node:os");
52627
+ var import_node_path7 = require("node:path");
52393
52628
  var import_node_net = __toESM(require("node:net"), 1);
52394
- var import_node_fs7 = require("node:fs");
52629
+ var import_node_fs8 = require("node:fs");
52395
52630
  var MANAGED_HEADER = "# managed by floless.app - do not edit";
52396
52631
  var OAUTH_PRESETS = {
52397
52632
  "trimble-connect": {
@@ -52421,7 +52656,7 @@ function managedProfileYaml(preset) {
52421
52656
  ].join("\n");
52422
52657
  }
52423
52658
  function oauthDir() {
52424
- return process.env.AWARE_HOME ? (0, import_node_path6.join)(process.env.AWARE_HOME, "oauth") : (0, import_node_path6.join)((0, import_node_os6.homedir)(), ".aware", "oauth");
52659
+ 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");
52425
52660
  }
52426
52661
  function isUpgradableLegacyProfile(existing, preset) {
52427
52662
  if (existing.startsWith(MANAGED_HEADER)) return false;
@@ -52435,22 +52670,22 @@ function ensureManagedProfile(id) {
52435
52670
  const preset = OAUTH_PRESETS[id];
52436
52671
  if (!preset) return "not-managed";
52437
52672
  const dir = oauthDir();
52438
- const file = (0, import_node_path6.join)(dir, `${id}.yaml`);
52439
- const existing = (0, import_node_fs7.existsSync)(file) ? (0, import_node_fs7.readFileSync)(file, "utf8") : null;
52673
+ const file = (0, import_node_path7.join)(dir, `${id}.yaml`);
52674
+ const existing = (0, import_node_fs8.existsSync)(file) ? (0, import_node_fs8.readFileSync)(file, "utf8") : null;
52440
52675
  if (existing !== null && !existing.startsWith(MANAGED_HEADER) && !isUpgradableLegacyProfile(existing, preset)) {
52441
52676
  return "skipped";
52442
52677
  }
52443
52678
  const desired = managedProfileYaml(preset);
52444
52679
  if (existing === desired) return "unchanged";
52445
- (0, import_node_fs7.mkdirSync)(dir, { recursive: true });
52446
- (0, import_node_fs7.writeFileSync)(file, desired, "utf8");
52680
+ (0, import_node_fs8.mkdirSync)(dir, { recursive: true });
52681
+ (0, import_node_fs8.writeFileSync)(file, desired, "utf8");
52447
52682
  return "written";
52448
52683
  }
52449
52684
  function isPortBindable(port, host = "127.0.0.1") {
52450
- return new Promise((resolve4) => {
52685
+ return new Promise((resolve5) => {
52451
52686
  const srv = import_node_net.default.createServer();
52452
- srv.once("error", () => resolve4(false));
52453
- srv.listen(port, host, () => srv.close(() => resolve4(true)));
52687
+ srv.once("error", () => resolve5(false));
52688
+ srv.listen(port, host, () => srv.close(() => resolve5(true)));
52454
52689
  });
52455
52690
  }
52456
52691
 
@@ -52521,7 +52756,7 @@ function withBadge(report, opts) {
52521
52756
  }
52522
52757
 
52523
52758
  // index.ts
52524
- var import_node_crypto5 = require("node:crypto");
52759
+ var import_node_crypto6 = require("node:crypto");
52525
52760
 
52526
52761
  // graft.ts
52527
52762
  var TEKLA_MARKER = "Recipe: Tekla model plug-in";
@@ -52565,16 +52800,16 @@ function buildPreview(m, sourceKind, sourceRef, stagedRef) {
52565
52800
  }
52566
52801
 
52567
52802
  // graft-manifest-reader.ts
52568
- var import_node_fs8 = require("node:fs");
52569
- var import_node_path7 = require("node:path");
52803
+ var import_node_fs9 = require("node:fs");
52804
+ var import_node_path8 = require("node:path");
52570
52805
  var import_yaml3 = __toESM(require_dist6(), 1);
52571
52806
  var asRecord2 = (v) => v && typeof v === "object" && !Array.isArray(v) ? v : {};
52572
52807
  function readStagedManifest(agentDir) {
52573
- const manifestPath = (0, import_node_path7.join)(agentDir, "manifest.yaml");
52574
- if (!(0, import_node_fs8.existsSync)(manifestPath)) return null;
52808
+ const manifestPath = (0, import_node_path8.join)(agentDir, "manifest.yaml");
52809
+ if (!(0, import_node_fs9.existsSync)(manifestPath)) return null;
52575
52810
  let doc;
52576
52811
  try {
52577
- doc = asRecord2((0, import_yaml3.parse)((0, import_node_fs8.readFileSync)(manifestPath, "utf8")));
52812
+ doc = asRecord2((0, import_yaml3.parse)((0, import_node_fs9.readFileSync)(manifestPath, "utf8")));
52578
52813
  } catch {
52579
52814
  return null;
52580
52815
  }
@@ -52604,10 +52839,10 @@ function readStagedManifest(agentDir) {
52604
52839
  }
52605
52840
  let skillCount = Array.isArray(doc.skills) ? doc.skills.length : 0;
52606
52841
  if (!skillCount) {
52607
- const skillsDir = (0, import_node_path7.join)(agentDir, "skills");
52608
- if ((0, import_node_fs8.existsSync)(skillsDir)) {
52842
+ const skillsDir = (0, import_node_path8.join)(agentDir, "skills");
52843
+ if ((0, import_node_fs9.existsSync)(skillsDir)) {
52609
52844
  try {
52610
- skillCount = (0, import_node_fs8.readdirSync)(skillsDir).filter((f) => f.endsWith(".md")).length;
52845
+ skillCount = (0, import_node_fs9.readdirSync)(skillsDir).filter((f) => f.endsWith(".md")).length;
52611
52846
  } catch {
52612
52847
  }
52613
52848
  }
@@ -52621,7 +52856,7 @@ function readStagedManifest(agentDir) {
52621
52856
  }
52622
52857
 
52623
52858
  // graft-stage-registry.ts
52624
- var import_node_fs9 = require("node:fs");
52859
+ var import_node_fs10 = require("node:fs");
52625
52860
  var TTL_MS = 30 * 60 * 1e3;
52626
52861
  var registry = /* @__PURE__ */ new Map();
52627
52862
  function registerStage(token, tempDir, agentId) {
@@ -52643,7 +52878,7 @@ function evict(token) {
52643
52878
  clearTimeout(e.timer);
52644
52879
  registry.delete(token);
52645
52880
  try {
52646
- (0, import_node_fs9.rmSync)(e.tempDir, { recursive: true, force: true });
52881
+ (0, import_node_fs10.rmSync)(e.tempDir, { recursive: true, force: true });
52647
52882
  } catch {
52648
52883
  }
52649
52884
  }
@@ -52652,8 +52887,8 @@ function clearAllStages() {
52652
52887
  }
52653
52888
 
52654
52889
  // graft-commit.ts
52655
- var import_node_fs10 = require("node:fs");
52656
- var import_node_path8 = require("node:path");
52890
+ var import_node_fs11 = require("node:fs");
52891
+ var import_node_path9 = require("node:path");
52657
52892
  var GraftCommitError = class extends Error {
52658
52893
  constructor(message, code) {
52659
52894
  super(message);
@@ -52663,34 +52898,34 @@ var GraftCommitError = class extends Error {
52663
52898
  code;
52664
52899
  };
52665
52900
  function commitStaged(tempDir, agentId, targetAgentsDir, force) {
52666
- const staged = (0, import_node_path8.join)(tempDir, "agents", agentId);
52667
- const target = (0, import_node_path8.join)(targetAgentsDir, agentId);
52668
- if ((0, import_node_fs10.existsSync)(target)) {
52901
+ const staged = (0, import_node_path9.join)(tempDir, "agents", agentId);
52902
+ const target = (0, import_node_path9.join)(targetAgentsDir, agentId);
52903
+ if ((0, import_node_fs11.existsSync)(target)) {
52669
52904
  if (!force) throw new GraftCommitError(`an agent named "${agentId}" is already installed`, "collision");
52670
- (0, import_node_fs10.rmSync)(target, { recursive: true, force: true });
52905
+ (0, import_node_fs11.rmSync)(target, { recursive: true, force: true });
52671
52906
  }
52672
- (0, import_node_fs10.mkdirSync)(targetAgentsDir, { recursive: true });
52907
+ (0, import_node_fs11.mkdirSync)(targetAgentsDir, { recursive: true });
52673
52908
  try {
52674
- (0, import_node_fs10.renameSync)(staged, target);
52909
+ (0, import_node_fs11.renameSync)(staged, target);
52675
52910
  } catch {
52676
- (0, import_node_fs10.cpSync)(staged, target, { recursive: true });
52911
+ (0, import_node_fs11.cpSync)(staged, target, { recursive: true });
52677
52912
  }
52678
- (0, import_node_fs10.rmSync)(tempDir, { recursive: true, force: true });
52913
+ (0, import_node_fs11.rmSync)(tempDir, { recursive: true, force: true });
52679
52914
  return { agentId };
52680
52915
  }
52681
52916
  function matchAssemblies(globOrDir) {
52682
52917
  let dir;
52683
52918
  let pattern;
52684
- if ((0, import_node_fs10.existsSync)(globOrDir) && (0, import_node_fs10.statSync)(globOrDir).isDirectory()) {
52919
+ if ((0, import_node_fs11.existsSync)(globOrDir) && (0, import_node_fs11.statSync)(globOrDir).isDirectory()) {
52685
52920
  dir = globOrDir;
52686
52921
  pattern = "*.dll";
52687
52922
  } else {
52688
- dir = (0, import_node_path8.dirname)(globOrDir);
52689
- pattern = (0, import_node_path8.basename)(globOrDir);
52923
+ dir = (0, import_node_path9.dirname)(globOrDir);
52924
+ pattern = (0, import_node_path9.basename)(globOrDir);
52690
52925
  }
52691
- if (!dir || !(0, import_node_fs10.existsSync)(dir) || !(0, import_node_fs10.statSync)(dir).isDirectory()) return [];
52926
+ if (!dir || !(0, import_node_fs11.existsSync)(dir) || !(0, import_node_fs11.statSync)(dir).isDirectory()) return [];
52692
52927
  const re = globToRegExp(pattern);
52693
- return (0, import_node_fs10.readdirSync)(dir).filter((f) => re.test(f)).sort();
52928
+ return (0, import_node_fs11.readdirSync)(dir).filter((f) => re.test(f)).sort();
52694
52929
  }
52695
52930
  function globToRegExp(p) {
52696
52931
  const esc = p.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".");
@@ -52698,25 +52933,25 @@ function globToRegExp(p) {
52698
52933
  }
52699
52934
 
52700
52935
  // floless-store.ts
52701
- var import_node_crypto3 = require("node:crypto");
52702
- var import_node_fs11 = require("node:fs");
52703
- var import_node_os7 = require("node:os");
52704
- var import_node_path9 = require("node:path");
52705
- var ROOT = process.env.FLOLESS_HOME ?? (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".floless");
52706
- var TEMPLATES_FILE = (0, import_node_path9.join)(ROOT, "templates.json");
52707
- var REQUESTS_DIR = (0, import_node_path9.join)(ROOT, "requests");
52936
+ var import_node_crypto4 = require("node:crypto");
52937
+ var import_node_fs12 = require("node:fs");
52938
+ var import_node_os8 = require("node:os");
52939
+ var import_node_path10 = require("node:path");
52940
+ var ROOT2 = process.env.FLOLESS_HOME ?? (0, import_node_path10.join)((0, import_node_os8.homedir)(), ".floless");
52941
+ var TEMPLATES_FILE = (0, import_node_path10.join)(ROOT2, "templates.json");
52942
+ var REQUESTS_DIR = (0, import_node_path10.join)(ROOT2, "requests");
52708
52943
  function ensureRoot() {
52709
- if (!(0, import_node_fs11.existsSync)(ROOT)) (0, import_node_fs11.mkdirSync)(ROOT, { recursive: true });
52944
+ if (!(0, import_node_fs12.existsSync)(ROOT2)) (0, import_node_fs12.mkdirSync)(ROOT2, { recursive: true });
52710
52945
  }
52711
52946
  function withinRequestsDir(p) {
52712
- const base = (0, import_node_path9.resolve)(REQUESTS_DIR);
52713
- const full = (0, import_node_path9.resolve)(p);
52714
- return full === base || full.startsWith(base + import_node_path9.sep);
52947
+ const base = (0, import_node_path10.resolve)(REQUESTS_DIR);
52948
+ const full = (0, import_node_path10.resolve)(p);
52949
+ return full === base || full.startsWith(base + import_node_path10.sep);
52715
52950
  }
52716
52951
  function listTemplates() {
52717
- if (!(0, import_node_fs11.existsSync)(TEMPLATES_FILE)) return [];
52952
+ if (!(0, import_node_fs12.existsSync)(TEMPLATES_FILE)) return [];
52718
52953
  try {
52719
- const parsed = JSON.parse((0, import_node_fs11.readFileSync)(TEMPLATES_FILE, "utf8"));
52954
+ const parsed = JSON.parse((0, import_node_fs12.readFileSync)(TEMPLATES_FILE, "utf8"));
52720
52955
  return Array.isArray(parsed) ? parsed : [];
52721
52956
  } catch {
52722
52957
  return [];
@@ -52725,19 +52960,25 @@ function listTemplates() {
52725
52960
  function writeTemplates(list) {
52726
52961
  ensureRoot();
52727
52962
  const tmp = `${TEMPLATES_FILE}.${process.pid}.tmp`;
52728
- (0, import_node_fs11.writeFileSync)(tmp, JSON.stringify(list, null, 2));
52729
- (0, import_node_fs11.renameSync)(tmp, TEMPLATES_FILE);
52963
+ (0, import_node_fs12.writeFileSync)(tmp, JSON.stringify(list, null, 2));
52964
+ (0, import_node_fs12.renameSync)(tmp, TEMPLATES_FILE);
52730
52965
  }
52731
52966
  function addTemplate(input) {
52967
+ const list = listTemplates();
52968
+ if (!input.source?.nodeId && input.node.agent != null && input.node.command != null) {
52969
+ const dup = list.find(
52970
+ (t) => !t.source?.nodeId && t.node.agent === input.node.agent && t.node.command === input.node.command && t.node.kind === input.node.kind
52971
+ );
52972
+ if (dup) return dup;
52973
+ }
52732
52974
  const tpl = {
52733
- id: (0, import_node_crypto3.randomUUID)(),
52975
+ id: (0, import_node_crypto4.randomUUID)(),
52734
52976
  name: input.name.trim(),
52735
52977
  category: (input.category || "Uncategorized").trim(),
52736
52978
  node: input.node,
52737
52979
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
52738
52980
  source: input.source
52739
52981
  };
52740
- const list = listTemplates();
52741
52982
  list.push(tpl);
52742
52983
  writeTemplates(list);
52743
52984
  return tpl;
@@ -52754,13 +52995,13 @@ function getTemplate(id) {
52754
52995
  }
52755
52996
  function addRequest(req, decoded = []) {
52756
52997
  ensureRoot();
52757
- if (!(0, import_node_fs11.existsSync)(REQUESTS_DIR)) (0, import_node_fs11.mkdirSync)(REQUESTS_DIR, { recursive: true });
52758
- const id = (0, import_node_crypto3.randomUUID)();
52998
+ if (!(0, import_node_fs12.existsSync)(REQUESTS_DIR)) (0, import_node_fs12.mkdirSync)(REQUESTS_DIR, { recursive: true });
52999
+ const id = (0, import_node_crypto4.randomUUID)();
52759
53000
  const createdAt = (/* @__PURE__ */ new Date()).toISOString();
52760
53001
  const base = `${createdAt.replace(/[:.]/g, "-")}__${id}`;
52761
53002
  const snapshots = decoded.map((d, i) => {
52762
- const p = (0, import_node_path9.join)(REQUESTS_DIR, `${base}__snap${i + 1}.${d.ext}`);
52763
- (0, import_node_fs11.writeFileSync)(p, d.buf);
53003
+ const p = (0, import_node_path10.join)(REQUESTS_DIR, `${base}__snap${i + 1}.${d.ext}`);
53004
+ (0, import_node_fs12.writeFileSync)(p, d.buf);
52764
53005
  return p;
52765
53006
  });
52766
53007
  const full = {
@@ -52770,62 +53011,62 @@ function addRequest(req, decoded = []) {
52770
53011
  ...req,
52771
53012
  ...snapshots.length ? { snapshots } : {}
52772
53013
  };
52773
- (0, import_node_fs11.writeFileSync)((0, import_node_path9.join)(REQUESTS_DIR, `${base}.json`), JSON.stringify(full, null, 2));
53014
+ (0, import_node_fs12.writeFileSync)((0, import_node_path10.join)(REQUESTS_DIR, `${base}.json`), JSON.stringify(full, null, 2));
52774
53015
  return full;
52775
53016
  }
52776
53017
  function listRequests() {
52777
- if (!(0, import_node_fs11.existsSync)(REQUESTS_DIR)) return [];
52778
- return (0, import_node_fs11.readdirSync)(REQUESTS_DIR).filter((f) => f.endsWith(".json")).sort().map((f) => {
53018
+ if (!(0, import_node_fs12.existsSync)(REQUESTS_DIR)) return [];
53019
+ return (0, import_node_fs12.readdirSync)(REQUESTS_DIR).filter((f) => f.endsWith(".json")).sort().map((f) => {
52779
53020
  try {
52780
- return JSON.parse((0, import_node_fs11.readFileSync)((0, import_node_path9.join)(REQUESTS_DIR, f), "utf8"));
53021
+ return JSON.parse((0, import_node_fs12.readFileSync)((0, import_node_path10.join)(REQUESTS_DIR, f), "utf8"));
52781
53022
  } catch {
52782
53023
  return null;
52783
53024
  }
52784
53025
  }).filter((r) => r !== null);
52785
53026
  }
52786
53027
  function deleteRequest(id) {
52787
- if (!(0, import_node_fs11.existsSync)(REQUESTS_DIR)) return false;
52788
- const file = (0, import_node_fs11.readdirSync)(REQUESTS_DIR).find((f) => f.endsWith(`__${id}.json`));
53028
+ if (!(0, import_node_fs12.existsSync)(REQUESTS_DIR)) return false;
53029
+ const file = (0, import_node_fs12.readdirSync)(REQUESTS_DIR).find((f) => f.endsWith(`__${id}.json`));
52789
53030
  if (!file) return false;
52790
53031
  try {
52791
- const parsed = JSON.parse((0, import_node_fs11.readFileSync)((0, import_node_path9.join)(REQUESTS_DIR, file), "utf8"));
53032
+ const parsed = JSON.parse((0, import_node_fs12.readFileSync)((0, import_node_path10.join)(REQUESTS_DIR, file), "utf8"));
52792
53033
  for (const p of parsed.snapshots ?? []) {
52793
53034
  if (!withinRequestsDir(p)) continue;
52794
53035
  try {
52795
- (0, import_node_fs11.rmSync)(p);
53036
+ (0, import_node_fs12.rmSync)(p);
52796
53037
  } catch {
52797
53038
  }
52798
53039
  }
52799
53040
  } catch {
52800
53041
  }
52801
- (0, import_node_fs11.rmSync)((0, import_node_path9.join)(REQUESTS_DIR, file));
53042
+ (0, import_node_fs12.rmSync)((0, import_node_path10.join)(REQUESTS_DIR, file));
52802
53043
  return true;
52803
53044
  }
52804
53045
  function clearRequests() {
52805
- if (!(0, import_node_fs11.existsSync)(REQUESTS_DIR)) return 0;
52806
- const allFiles = (0, import_node_fs11.readdirSync)(REQUESTS_DIR);
53046
+ if (!(0, import_node_fs12.existsSync)(REQUESTS_DIR)) return 0;
53047
+ const allFiles = (0, import_node_fs12.readdirSync)(REQUESTS_DIR);
52807
53048
  const jsonFiles = allFiles.filter((f) => f.endsWith(".json"));
52808
53049
  for (const f of allFiles) {
52809
53050
  try {
52810
- (0, import_node_fs11.rmSync)((0, import_node_path9.join)(REQUESTS_DIR, f));
53051
+ (0, import_node_fs12.rmSync)((0, import_node_path10.join)(REQUESTS_DIR, f));
52811
53052
  } catch {
52812
53053
  }
52813
53054
  }
52814
53055
  return jsonFiles.length;
52815
53056
  }
52816
53057
  function snapshotPathFor(id, n) {
52817
- if (!(0, import_node_fs11.existsSync)(REQUESTS_DIR)) return null;
52818
- const file = (0, import_node_fs11.readdirSync)(REQUESTS_DIR).find((f) => f.endsWith(`__${id}.json`));
53058
+ if (!(0, import_node_fs12.existsSync)(REQUESTS_DIR)) return null;
53059
+ const file = (0, import_node_fs12.readdirSync)(REQUESTS_DIR).find((f) => f.endsWith(`__${id}.json`));
52819
53060
  if (!file) return null;
52820
53061
  try {
52821
- const parsed = JSON.parse((0, import_node_fs11.readFileSync)((0, import_node_path9.join)(REQUESTS_DIR, file), "utf8"));
53062
+ const parsed = JSON.parse((0, import_node_fs12.readFileSync)((0, import_node_path10.join)(REQUESTS_DIR, file), "utf8"));
52822
53063
  const cand = parsed.snapshots?.[n] ?? null;
52823
53064
  return cand && withinRequestsDir(cand) ? cand : null;
52824
53065
  } catch {
52825
53066
  return null;
52826
53067
  }
52827
53068
  }
52828
- var flolessRoot = ROOT;
53069
+ var flolessRoot = ROOT2;
52829
53070
  var SnapshotError = class extends Error {
52830
53071
  };
52831
53072
  var MAX_SNAPSHOTS = 8;
@@ -52852,8 +53093,8 @@ function decodeSnapshots(inputs) {
52852
53093
  }
52853
53094
 
52854
53095
  // routines.ts
52855
- var import_node_fs13 = require("node:fs");
52856
- var import_node_path11 = require("node:path");
53096
+ var import_node_fs14 = require("node:fs");
53097
+ var import_node_path12 = require("node:path");
52857
53098
 
52858
53099
  // sse.ts
52859
53100
  var clients = /* @__PURE__ */ new Set();
@@ -52890,11 +53131,11 @@ function clientCount() {
52890
53131
  }
52891
53132
 
52892
53133
  // trigger-sessions.ts
52893
- var import_node_fs12 = require("node:fs");
52894
- var import_node_os8 = require("node:os");
52895
- var import_node_path10 = require("node:path");
53134
+ var import_node_fs13 = require("node:fs");
53135
+ var import_node_os9 = require("node:os");
53136
+ var import_node_path11 = require("node:path");
52896
53137
  var import_yaml4 = __toESM(require_dist6(), 1);
52897
- var AGENTS_DIR2 = process.env.AWARE_HOME ? (0, import_node_path10.join)(process.env.AWARE_HOME, "agents") : (0, import_node_path10.join)((0, import_node_os8.homedir)(), ".aware", "agents");
53138
+ var AGENTS_DIR2 = process.env.AWARE_HOME ? (0, import_node_path11.join)(process.env.AWARE_HOME, "agents") : (0, import_node_path11.join)((0, import_node_os9.homedir)(), ".aware", "agents");
52898
53139
  function summarizeFire(data) {
52899
53140
  if (!data) return "event";
52900
53141
  const type = typeof data.type === "string" ? data.type : "";
@@ -52911,10 +53152,10 @@ function mapTriggerState(phase) {
52911
53152
  function isHostBacked(agent, agentsDir = AGENTS_DIR2) {
52912
53153
  const safe = (n) => !n.includes("/") && !n.includes("\\") && !n.includes("..");
52913
53154
  if (!safe(agent)) return false;
52914
- const manifestPath = (0, import_node_path10.join)(agentsDir, agent, "manifest.yaml");
52915
- if (!(0, import_node_fs12.existsSync)(manifestPath)) return false;
53155
+ const manifestPath = (0, import_node_path11.join)(agentsDir, agent, "manifest.yaml");
53156
+ if (!(0, import_node_fs13.existsSync)(manifestPath)) return false;
52916
53157
  try {
52917
- const doc = (0, import_yaml4.parse)((0, import_node_fs12.readFileSync)(manifestPath, "utf8"));
53158
+ const doc = (0, import_yaml4.parse)((0, import_node_fs13.readFileSync)(manifestPath, "utf8"));
52918
53159
  const transport = doc?.transport;
52919
53160
  return !!(transport && typeof transport === "object" && "cli" in transport);
52920
53161
  } catch {
@@ -53173,7 +53414,7 @@ var RoutineError = class extends Error {
53173
53414
  }
53174
53415
  status;
53175
53416
  };
53176
- var ROUTINES_FILE = (0, import_node_path11.join)(flolessRoot, "routines.json");
53417
+ var ROUTINES_FILE = (0, import_node_path12.join)(flolessRoot, "routines.json");
53177
53418
  var routines = [];
53178
53419
  var loaded = false;
53179
53420
  function ensureLoaded() {
@@ -53209,10 +53450,10 @@ function sanitizeRoutine(raw) {
53209
53450
  };
53210
53451
  }
53211
53452
  function loadFromDisk() {
53212
- if (!(0, import_node_fs13.existsSync)(ROUTINES_FILE)) return [];
53453
+ if (!(0, import_node_fs14.existsSync)(ROUTINES_FILE)) return [];
53213
53454
  let text;
53214
53455
  try {
53215
- text = (0, import_node_fs13.readFileSync)(ROUTINES_FILE, "utf8");
53456
+ text = (0, import_node_fs14.readFileSync)(ROUTINES_FILE, "utf8");
53216
53457
  } catch {
53217
53458
  return [];
53218
53459
  }
@@ -53221,17 +53462,17 @@ function loadFromDisk() {
53221
53462
  return Array.isArray(parsed) ? parsed.map(sanitizeRoutine).filter((r) => r !== null) : [];
53222
53463
  } catch {
53223
53464
  try {
53224
- (0, import_node_fs13.renameSync)(ROUTINES_FILE, `${ROUTINES_FILE}.corrupt-${Date.now()}`);
53465
+ (0, import_node_fs14.renameSync)(ROUTINES_FILE, `${ROUTINES_FILE}.corrupt-${Date.now()}`);
53225
53466
  } catch {
53226
53467
  }
53227
53468
  return [];
53228
53469
  }
53229
53470
  }
53230
53471
  function saveRoutines() {
53231
- if (!(0, import_node_fs13.existsSync)(flolessRoot)) (0, import_node_fs13.mkdirSync)(flolessRoot, { recursive: true });
53472
+ if (!(0, import_node_fs14.existsSync)(flolessRoot)) (0, import_node_fs14.mkdirSync)(flolessRoot, { recursive: true });
53232
53473
  const tmp = `${ROUTINES_FILE}.${process.pid}.tmp`;
53233
- (0, import_node_fs13.writeFileSync)(tmp, JSON.stringify(routines, null, 2));
53234
- (0, import_node_fs13.renameSync)(tmp, ROUTINES_FILE);
53474
+ (0, import_node_fs14.writeFileSync)(tmp, JSON.stringify(routines, null, 2));
53475
+ (0, import_node_fs14.renameSync)(tmp, ROUTINES_FILE);
53235
53476
  }
53236
53477
  function listRoutines() {
53237
53478
  ensureLoaded();
@@ -53621,9 +53862,9 @@ function isGatedAwareRoute(url, method) {
53621
53862
 
53622
53863
  // autostart.mjs
53623
53864
  var import_node_child_process3 = require("node:child_process");
53624
- var import_node_fs14 = require("node:fs");
53625
- var import_node_os9 = require("node:os");
53626
- var import_node_path12 = require("node:path");
53865
+ var import_node_fs15 = require("node:fs");
53866
+ var import_node_os10 = require("node:os");
53867
+ var import_node_path13 = require("node:path");
53627
53868
 
53628
53869
  // teardown.mjs
53629
53870
  var RUN_KEY = "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run";
@@ -53735,8 +53976,8 @@ function removeLegacyRunKey() {
53735
53976
  }
53736
53977
  function logLine(msg) {
53737
53978
  try {
53738
- (0, import_node_fs14.mkdirSync)(logDir(), { recursive: true });
53739
- (0, import_node_fs14.appendFileSync)(logFilePath(), `${(/* @__PURE__ */ new Date()).toISOString()} ${msg}
53979
+ (0, import_node_fs15.mkdirSync)(logDir(), { recursive: true });
53980
+ (0, import_node_fs15.appendFileSync)(logFilePath(), `${(/* @__PURE__ */ new Date()).toISOString()} ${msg}
53740
53981
  `);
53741
53982
  } catch {
53742
53983
  }
@@ -53744,8 +53985,8 @@ function logLine(msg) {
53744
53985
  function registerAutostart(exePath) {
53745
53986
  if (!isWin) return;
53746
53987
  const xml = buildAutostartTaskXml(exePath, currentUserId());
53747
- const tmp = (0, import_node_path12.join)((0, import_node_os9.tmpdir)(), `floless-autostart-${process.pid}-${Date.now()}.xml`);
53748
- (0, import_node_fs14.writeFileSync)(tmp, "\uFEFF" + xml, { encoding: "utf16le" });
53988
+ const tmp = (0, import_node_path13.join)((0, import_node_os10.tmpdir)(), `floless-autostart-${process.pid}-${Date.now()}.xml`);
53989
+ (0, import_node_fs15.writeFileSync)(tmp, "\uFEFF" + xml, { encoding: "utf16le" });
53749
53990
  try {
53750
53991
  (0, import_node_child_process3.execFileSync)("schtasks", ["/Create", "/TN", TASK_NAME, "/XML", tmp, "/F"], {
53751
53992
  stdio: ["ignore", "ignore", "ignore"],
@@ -53756,7 +53997,7 @@ function registerAutostart(exePath) {
53756
53997
  throw err;
53757
53998
  } finally {
53758
53999
  try {
53759
- (0, import_node_fs14.rmSync)(tmp, { force: true });
54000
+ (0, import_node_fs15.rmSync)(tmp, { force: true });
53760
54001
  } catch {
53761
54002
  }
53762
54003
  }
@@ -53790,11 +54031,40 @@ function unregisterAutostart() {
53790
54031
 
53791
54032
  // updater.ts
53792
54033
  var import_node_child_process4 = require("node:child_process");
53793
- var import_node_crypto4 = require("node:crypto");
53794
- var import_node_fs15 = require("node:fs");
54034
+ var import_node_crypto5 = require("node:crypto");
54035
+ var import_node_fs17 = require("node:fs");
53795
54036
  var import_node_stream = require("node:stream");
53796
54037
  var import_promises = require("node:stream/promises");
53797
- var import_node_path13 = require("node:path");
54038
+ var import_node_path15 = require("node:path");
54039
+
54040
+ // post-update-marker.mjs
54041
+ var import_node_fs16 = require("node:fs");
54042
+ var import_node_path14 = require("node:path");
54043
+ function markerPath() {
54044
+ const override = (process.env.FLOLESS_POST_UPDATE_MARKER ?? "").trim();
54045
+ if (override) return override;
54046
+ return (0, import_node_path14.join)((0, import_node_path14.dirname)((0, import_node_path14.dirname)(process.execPath)), ".floless-post-update");
54047
+ }
54048
+ function writePostUpdateMarker() {
54049
+ try {
54050
+ (0, import_node_fs16.writeFileSync)(markerPath(), (/* @__PURE__ */ new Date()).toISOString());
54051
+ return true;
54052
+ } catch {
54053
+ return false;
54054
+ }
54055
+ }
54056
+ function consumePostUpdateMarker() {
54057
+ const p = markerPath();
54058
+ try {
54059
+ if (!(0, import_node_fs16.existsSync)(p)) return false;
54060
+ (0, import_node_fs16.rmSync)(p, { force: true });
54061
+ return true;
54062
+ } catch {
54063
+ return false;
54064
+ }
54065
+ }
54066
+
54067
+ // updater.ts
53798
54068
  var CHANNEL = "win";
53799
54069
  var FEED_TIMEOUT_MS = 15e3;
53800
54070
  var DOWNLOAD_TIMEOUT_MS = 3e5;
@@ -53803,13 +54073,13 @@ function currentVersion() {
53803
54073
  return appVersion();
53804
54074
  }
53805
54075
  function installRoot() {
53806
- return (0, import_node_path13.dirname)((0, import_node_path13.dirname)(process.execPath));
54076
+ return (0, import_node_path15.dirname)((0, import_node_path15.dirname)(process.execPath));
53807
54077
  }
53808
54078
  function updateExePath() {
53809
- return (0, import_node_path13.join)(installRoot(), "Update.exe");
54079
+ return (0, import_node_path15.join)(installRoot(), "Update.exe");
53810
54080
  }
53811
54081
  function packagesDir() {
53812
- return (0, import_node_path13.join)(installRoot(), "packages");
54082
+ return (0, import_node_path15.join)(installRoot(), "packages");
53813
54083
  }
53814
54084
  function feedUrl() {
53815
54085
  const env2 = (process.env.FLOLESS_UPDATE_URL ?? "").trim().replace(/\/+$/, "");
@@ -53901,23 +54171,23 @@ async function checkForUpdate() {
53901
54171
  return { supported: true, currentVersion: cur, updateAvailable: true, targetVersion: latest.Version, asset: latest };
53902
54172
  }
53903
54173
  async function sha1OfFile(path) {
53904
- const hash = (0, import_node_crypto4.createHash)("sha1");
53905
- await (0, import_promises.pipeline)((0, import_node_fs15.createReadStream)(path), hash);
54174
+ const hash = (0, import_node_crypto5.createHash)("sha1");
54175
+ await (0, import_promises.pipeline)((0, import_node_fs17.createReadStream)(path), hash);
53906
54176
  return hash.digest("hex").toUpperCase();
53907
54177
  }
53908
54178
  async function downloadPackage(asset) {
53909
54179
  if (!NUPKG_NAME.test(asset.FileName)) throw new Error(`refusing suspicious package name: ${asset.FileName}`);
53910
54180
  const want = asset.SHA1.toUpperCase();
53911
54181
  const dir = packagesDir();
53912
- (0, import_node_fs15.mkdirSync)(dir, { recursive: true });
53913
- const dest = (0, import_node_path13.join)(dir, asset.FileName);
53914
- if ((0, import_node_fs15.existsSync)(dest) && await sha1OfFile(dest) === want) return dest;
54182
+ (0, import_node_fs17.mkdirSync)(dir, { recursive: true });
54183
+ const dest = (0, import_node_path15.join)(dir, asset.FileName);
54184
+ if ((0, import_node_fs17.existsSync)(dest) && await sha1OfFile(dest) === want) return dest;
53915
54185
  const res = await authedFetch(`${feedUrl()}/${encodeURIComponent(asset.FileName)}`, {
53916
54186
  redirect: "follow",
53917
54187
  signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS)
53918
54188
  });
53919
54189
  if (!res.ok || !res.body) throw new Error(`download failed: HTTP ${res.status} for ${asset.FileName}`);
53920
- await (0, import_promises.pipeline)(import_node_stream.Readable.fromWeb(res.body), (0, import_node_fs15.createWriteStream)(dest));
54190
+ await (0, import_promises.pipeline)(import_node_stream.Readable.fromWeb(res.body), (0, import_node_fs17.createWriteStream)(dest));
53921
54191
  const got = await sha1OfFile(dest);
53922
54192
  if (got !== want) throw new Error(`SHA1 mismatch for ${asset.FileName}: feed=${want} got=${got}`);
53923
54193
  return dest;
@@ -53926,12 +54196,12 @@ async function applyUpdate(check, opts) {
53926
54196
  if (!check.supported) return { applied: false, message: check.reason ?? "auto-update not supported in this runtime" };
53927
54197
  if (!check.updateAvailable || !check.asset) return { applied: false, message: check.reason ?? "no update available" };
53928
54198
  const exe = updateExePath();
53929
- if (!(0, import_node_fs15.existsSync)(exe)) {
54199
+ if (!(0, import_node_fs17.existsSync)(exe)) {
53930
54200
  return { applied: false, message: `Update.exe not found at ${exe} \u2014 is this a Velopack install?` };
53931
54201
  }
53932
54202
  const pkg = await downloadPackage(check.asset);
53933
54203
  if (opts?.onBeforeApply) await opts.onBeforeApply();
53934
- await new Promise((resolve4, reject) => {
54204
+ await new Promise((resolve5, reject) => {
53935
54205
  const child = (0, import_node_child_process4.spawn)(exe, ["apply", "--package", pkg, "--waitPid", String(process.pid)], {
53936
54206
  cwd: installRoot(),
53937
54207
  detached: true,
@@ -53941,9 +54211,10 @@ async function applyUpdate(check, opts) {
53941
54211
  child.once("error", reject);
53942
54212
  child.once("spawn", () => {
53943
54213
  child.unref();
53944
- resolve4();
54214
+ resolve5();
53945
54215
  });
53946
54216
  });
54217
+ writePostUpdateMarker();
53947
54218
  return { applied: true, message: `updating to v${check.targetVersion}\u2026 the app will relaunch` };
53948
54219
  }
53949
54220
 
@@ -54127,15 +54398,19 @@ function summarizeRun(events) {
54127
54398
  }
54128
54399
  return { status, errorNodeId, errorMessage };
54129
54400
  }
54401
+ function isTraceCorrupt(events) {
54402
+ if (!events.length) return false;
54403
+ return events.every((e) => e.kind === "unparsed");
54404
+ }
54130
54405
 
54131
54406
  // launch.mjs
54132
54407
  var import_node_child_process5 = require("node:child_process");
54133
- var import_node_path14 = require("node:path");
54408
+ var import_node_path16 = require("node:path");
54134
54409
  var import_node_url = require("node:url");
54135
- var import_node_fs16 = require("node:fs");
54410
+ var import_node_fs18 = require("node:fs");
54136
54411
  var import_node_http = __toESM(require("node:http"), 1);
54137
54412
  var import_node_readline = require("node:readline");
54138
- var __dirname2 = (0, import_node_path14.dirname)((0, import_node_url.fileURLToPath)(__import_meta_url));
54413
+ var __dirname2 = (0, import_node_path16.dirname)((0, import_node_url.fileURLToPath)(__import_meta_url));
54139
54414
  var PORT = Number(process.env.PORT ?? 4317);
54140
54415
  var HEALTH_URL = `http://127.0.0.1:${PORT}/api/health`;
54141
54416
  var BROWSER_URL = `http://floless.localhost:${PORT}`;
@@ -54148,20 +54423,20 @@ var log = (m) => {
54148
54423
  }
54149
54424
  };
54150
54425
  function ping() {
54151
- return new Promise((resolve4) => {
54426
+ return new Promise((resolve5) => {
54152
54427
  const req = import_node_http.default.get(HEALTH_URL, { timeout: 1500 }, (res) => {
54153
54428
  res.resume();
54154
- resolve4(res.statusCode === 200);
54429
+ resolve5(res.statusCode === 200);
54155
54430
  });
54156
- req.on("error", () => resolve4(false));
54431
+ req.on("error", () => resolve5(false));
54157
54432
  req.on("timeout", () => {
54158
54433
  req.destroy();
54159
- resolve4(false);
54434
+ resolve5(false);
54160
54435
  });
54161
54436
  });
54162
54437
  }
54163
54438
  function probeVersion() {
54164
- return new Promise((resolve4) => {
54439
+ return new Promise((resolve5) => {
54165
54440
  const req = import_node_http.default.get(HEALTH_URL, { timeout: 1500 }, (res) => {
54166
54441
  let body = "";
54167
54442
  res.on("data", (c) => {
@@ -54169,16 +54444,16 @@ function probeVersion() {
54169
54444
  });
54170
54445
  res.on("end", () => {
54171
54446
  try {
54172
- resolve4(JSON.parse(body).appVersion || null);
54447
+ resolve5(JSON.parse(body).appVersion || null);
54173
54448
  } catch {
54174
- resolve4(null);
54449
+ resolve5(null);
54175
54450
  }
54176
54451
  });
54177
54452
  });
54178
- req.on("error", () => resolve4(null));
54453
+ req.on("error", () => resolve5(null));
54179
54454
  req.on("timeout", () => {
54180
54455
  req.destroy();
54181
- resolve4(null);
54456
+ resolve5(null);
54182
54457
  });
54183
54458
  });
54184
54459
  }
@@ -54207,8 +54482,8 @@ async function waitHealthy(timeoutMs = 3e4) {
54207
54482
  function resolveServerStart() {
54208
54483
  const packaged = /flolessapp\.exe$/i.test(process.execPath);
54209
54484
  if (packaged) return { cmd: process.execPath, args: ["--serve"], shell: false };
54210
- const bundle = (0, import_node_path14.join)(__dirname2, "dist", "floless-server.cjs");
54211
- if ((0, import_node_fs16.existsSync)(bundle)) return { cmd: process.execPath, args: [bundle, "--serve"], shell: false };
54485
+ const bundle = (0, import_node_path16.join)(__dirname2, "dist", "floless-server.cjs");
54486
+ if ((0, import_node_fs18.existsSync)(bundle)) return { cmd: process.execPath, args: [bundle, "--serve"], shell: false };
54212
54487
  return { cmd: "npm", args: ["run", "start"], shell: isWin2 };
54213
54488
  }
54214
54489
  function startServerDetached() {
@@ -54256,6 +54531,7 @@ async function ensureServerUp() {
54256
54531
  log("server up");
54257
54532
  }
54258
54533
  async function cmdOpen() {
54534
+ const postUpdate = consumePostUpdateMarker();
54259
54535
  if (await ping()) {
54260
54536
  const running = await probeVersion();
54261
54537
  if (shouldTakeOver(running, _selfVersion)) {
@@ -54264,11 +54540,15 @@ async function cmdOpen() {
54264
54540
  await new Promise((r) => setTimeout(r, 500));
54265
54541
  await ensureServerUp();
54266
54542
  } else {
54267
- log(`already running${running ? ` (v${running})` : ""} \u2014 opening browser`);
54543
+ log(`already running${running ? ` (v${running})` : ""}`);
54268
54544
  }
54269
54545
  } else {
54270
54546
  await ensureServerUp();
54271
54547
  }
54548
+ if (postUpdate) {
54549
+ log("post-update relaunch \u2014 server up; the existing tab reconnects via its health poll (no new tab)");
54550
+ return;
54551
+ }
54272
54552
  log(`opening ${BROWSER_URL}`);
54273
54553
  openBrowser2(BROWSER_URL);
54274
54554
  }
@@ -54356,8 +54636,8 @@ function taskkillArgs(pid, { tree = true } = {}) {
54356
54636
  }
54357
54637
  function killSupervisor({ tree = true } = {}) {
54358
54638
  if (!isWin2) return;
54359
- const isNpmChannel = /^node(\.exe)?$/i.test((0, import_node_path14.basename)(process.execPath));
54360
- const scriptMatch = isNpmChannel ? (0, import_node_path14.basename)((0, import_node_url.fileURLToPath)(__import_meta_url)) : void 0;
54639
+ const isNpmChannel = /^node(\.exe)?$/i.test((0, import_node_path16.basename)(process.execPath));
54640
+ const scriptMatch = isNpmChannel ? (0, import_node_path16.basename)((0, import_node_url.fileURLToPath)(__import_meta_url)) : void 0;
54361
54641
  const realExe = resolveRealInstallExe(process.execPath);
54362
54642
  const exeMatch = realExe === process.execPath ? process.execPath : [process.execPath, realExe];
54363
54643
  const pids = supervisorPidsToKill(enumerateProcesses(), process.pid, exeMatch, scriptMatch);
@@ -54390,15 +54670,15 @@ async function cmdRestart() {
54390
54670
  await cmdOpen();
54391
54671
  }
54392
54672
  function apiJson(path, method = "GET") {
54393
- return new Promise((resolve4, reject) => {
54673
+ return new Promise((resolve5, reject) => {
54394
54674
  const req = import_node_http.default.request(`http://127.0.0.1:${PORT}${path}`, { method, timeout: 5e3 }, (res) => {
54395
54675
  let body = "";
54396
54676
  res.on("data", (c) => body += c);
54397
54677
  res.on("end", () => {
54398
54678
  try {
54399
- resolve4(JSON.parse(body || "{}"));
54679
+ resolve5(JSON.parse(body || "{}"));
54400
54680
  } catch {
54401
- resolve4({});
54681
+ resolve5({});
54402
54682
  }
54403
54683
  });
54404
54684
  });
@@ -54464,11 +54744,11 @@ function removeRegistryFootprint() {
54464
54744
  }
54465
54745
  }
54466
54746
  function promptYesNo(question) {
54467
- return new Promise((resolve4) => {
54747
+ return new Promise((resolve5) => {
54468
54748
  const rl = (0, import_node_readline.createInterface)({ input: process.stdin, output: process.stdout });
54469
54749
  rl.question(`${question} `, (answer) => {
54470
54750
  rl.close();
54471
- resolve4(/^y(es)?$/i.test((answer ?? "").trim()));
54751
+ resolve5(/^y(es)?$/i.test((answer ?? "").trim()));
54472
54752
  });
54473
54753
  });
54474
54754
  }
@@ -54522,7 +54802,7 @@ async function runAction(arg, flagArgv = [], selfVersion = null) {
54522
54802
  }
54523
54803
  await action(parseTeardownFlags(flagArgv));
54524
54804
  }
54525
- var entry = (0, import_node_path14.basename)(process.argv[1] ?? "").toLowerCase();
54805
+ var entry = (0, import_node_path16.basename)(process.argv[1] ?? "").toLowerCase();
54526
54806
  if (entry === "launch.mjs") {
54527
54807
  runAction(process.argv[2], process.argv.slice(3)).catch((e) => {
54528
54808
  log(`error: ${e?.message ?? e}`);
@@ -54596,9 +54876,9 @@ function awareUpgradeBlockReason(s) {
54596
54876
  }
54597
54877
 
54598
54878
  // skill-sync.ts
54599
- var import_node_fs17 = require("node:fs");
54600
- var import_node_os10 = require("node:os");
54601
- var import_node_path15 = require("node:path");
54879
+ var import_node_fs19 = require("node:fs");
54880
+ var import_node_os11 = require("node:os");
54881
+ var import_node_path17 = require("node:path");
54602
54882
  var import_node_url2 = require("node:url");
54603
54883
  var import_yaml5 = __toESM(require_dist6(), 1);
54604
54884
 
@@ -54612,6 +54892,8 @@ var PRODUCT_SKILLS = [
54612
54892
  // file a diagnosed bug/idea/question to the private log via the floless.io relay
54613
54893
  "floless-app-routines",
54614
54894
  // author event-driven ("on trigger") routines
54895
+ "floless-app-ui",
54896
+ // compose Custom Panels (~/.floless/ui/extensions.json) for the Dashboard
54615
54897
  "floless-app-workflows"
54616
54898
  // author/run .flo workflows
54617
54899
  ];
@@ -54621,30 +54903,30 @@ function selectShippedSkillNames(names) {
54621
54903
  }
54622
54904
 
54623
54905
  // skill-sync.ts
54624
- var __dirname3 = (0, import_node_path15.dirname)((0, import_node_url2.fileURLToPath)(__import_meta_url));
54906
+ var __dirname3 = (0, import_node_path17.dirname)((0, import_node_url2.fileURLToPath)(__import_meta_url));
54625
54907
  function bundledSkillsRoot() {
54626
54908
  const candidates = [
54627
- (0, import_node_path15.join)(__dirname3, "skills"),
54628
- (0, import_node_path15.join)((0, import_node_path15.dirname)(process.execPath), "skills"),
54629
- (0, import_node_path15.join)(__dirname3, "..", ".claude", "skills")
54909
+ (0, import_node_path17.join)(__dirname3, "skills"),
54910
+ (0, import_node_path17.join)((0, import_node_path17.dirname)(process.execPath), "skills"),
54911
+ (0, import_node_path17.join)(__dirname3, "..", ".claude", "skills")
54630
54912
  ];
54631
- return candidates.find((p) => (0, import_node_fs17.existsSync)(p)) ?? null;
54913
+ return candidates.find((p) => (0, import_node_fs19.existsSync)(p)) ?? null;
54632
54914
  }
54633
54915
  function targetConfigDirs() {
54634
54916
  const override = process.env.FLOLESS_SKILL_TARGETS;
54635
54917
  if (override) {
54636
54918
  return override.split(";").map((d) => d.trim()).filter(Boolean).map((dir) => ({ runtime: "custom", dir }));
54637
54919
  }
54638
- const home = (0, import_node_os10.homedir)();
54920
+ const home = (0, import_node_os11.homedir)();
54639
54921
  return [
54640
- { runtime: "claude", dir: (0, import_node_path15.join)(home, ".claude") },
54641
- { runtime: "codex", dir: (0, import_node_path15.join)(home, ".codex") },
54642
- { runtime: "opencode", dir: (0, import_node_path15.join)(home, ".opencode") }
54922
+ { runtime: "claude", dir: (0, import_node_path17.join)(home, ".claude") },
54923
+ { runtime: "codex", dir: (0, import_node_path17.join)(home, ".codex") },
54924
+ { runtime: "opencode", dir: (0, import_node_path17.join)(home, ".opencode") }
54643
54925
  ];
54644
54926
  }
54645
54927
  function skillVersion(skillMdPath) {
54646
54928
  try {
54647
- const text = (0, import_node_fs17.readFileSync)(skillMdPath, "utf8");
54929
+ const text = (0, import_node_fs19.readFileSync)(skillMdPath, "utf8");
54648
54930
  const m = /^---\r?\n([\s\S]*?)\r?\n---/.exec(text);
54649
54931
  if (!m || m[1] === void 0) return null;
54650
54932
  const fm = (0, import_yaml5.parse)(m[1]);
@@ -54684,21 +54966,21 @@ function decideAction(installed, bundled) {
54684
54966
  function bundledSkills(root) {
54685
54967
  let entries = [];
54686
54968
  try {
54687
- entries = selectShippedSkillNames((0, import_node_fs17.readdirSync)(root));
54969
+ entries = selectShippedSkillNames((0, import_node_fs19.readdirSync)(root));
54688
54970
  } catch {
54689
54971
  return [];
54690
54972
  }
54691
54973
  const out = [];
54692
54974
  for (const name of entries) {
54693
- const dir = (0, import_node_path15.join)(root, name);
54975
+ const dir = (0, import_node_path17.join)(root, name);
54694
54976
  let isDir = false;
54695
54977
  try {
54696
- isDir = (0, import_node_fs17.statSync)(dir).isDirectory();
54978
+ isDir = (0, import_node_fs19.statSync)(dir).isDirectory();
54697
54979
  } catch {
54698
54980
  isDir = false;
54699
54981
  }
54700
54982
  if (!isDir) continue;
54701
- const v = skillVersion((0, import_node_path15.join)(dir, "SKILL.md"));
54983
+ const v = skillVersion((0, import_node_path17.join)(dir, "SKILL.md"));
54702
54984
  if (!v) continue;
54703
54985
  out.push({ name, dir, version: v });
54704
54986
  }
@@ -54711,17 +54993,17 @@ function syncSkills() {
54711
54993
  const skills = bundledSkills(root);
54712
54994
  if (!skills.length) return results;
54713
54995
  for (const { runtime, dir: cfg } of targetConfigDirs()) {
54714
- if (!(0, import_node_fs17.existsSync)(cfg)) continue;
54715
- const skillsDir = (0, import_node_path15.join)(cfg, "skills");
54996
+ if (!(0, import_node_fs19.existsSync)(cfg)) continue;
54997
+ const skillsDir = (0, import_node_path17.join)(cfg, "skills");
54716
54998
  for (const s of skills) {
54717
- const dest = (0, import_node_path15.join)(skillsDir, s.name);
54718
- const installedMd = (0, import_node_path15.join)(dest, "SKILL.md");
54719
- const installed = (0, import_node_fs17.existsSync)(installedMd) ? skillVersion(installedMd) : null;
54999
+ const dest = (0, import_node_path17.join)(skillsDir, s.name);
55000
+ const installedMd = (0, import_node_path17.join)(dest, "SKILL.md");
55001
+ const installed = (0, import_node_fs19.existsSync)(installedMd) ? skillVersion(installedMd) : null;
54720
55002
  const action = decideAction(installed, s.version);
54721
55003
  if (action === "installed" || action === "updated") {
54722
55004
  try {
54723
- if (action === "updated") (0, import_node_fs17.rmSync)(dest, { recursive: true, force: true });
54724
- (0, import_node_fs17.cpSync)(s.dir, dest, { recursive: true });
55005
+ if (action === "updated") (0, import_node_fs19.rmSync)(dest, { recursive: true, force: true });
55006
+ (0, import_node_fs19.cpSync)(s.dir, dest, { recursive: true });
54725
55007
  results.push({ runtime, skill: s.name, action, from: installed, to: s.version });
54726
55008
  } catch {
54727
55009
  }
@@ -54734,9 +55016,9 @@ function syncSkills() {
54734
55016
  }
54735
55017
 
54736
55018
  // watch.ts
54737
- var import_node_os11 = require("node:os");
54738
- var import_node_path17 = require("node:path");
54739
- var import_node_fs18 = require("node:fs");
55019
+ var import_node_os12 = require("node:os");
55020
+ var import_node_path19 = require("node:path");
55021
+ var import_node_fs20 = require("node:fs");
54740
55022
 
54741
55023
  // node_modules/chokidar/esm/index.js
54742
55024
  var import_fs2 = require("fs");
@@ -54747,7 +55029,7 @@ var sysPath2 = __toESM(require("path"), 1);
54747
55029
  // node_modules/readdirp/esm/index.js
54748
55030
  var import_promises2 = require("node:fs/promises");
54749
55031
  var import_node_stream2 = require("node:stream");
54750
- var import_node_path16 = require("node:path");
55032
+ var import_node_path18 = require("node:path");
54751
55033
  var EntryTypes = {
54752
55034
  FILE_TYPE: "files",
54753
55035
  DIR_TYPE: "directories",
@@ -54822,7 +55104,7 @@ var ReaddirpStream = class extends import_node_stream2.Readable {
54822
55104
  this._wantsDir = type ? DIR_TYPES.has(type) : false;
54823
55105
  this._wantsFile = type ? FILE_TYPES.has(type) : false;
54824
55106
  this._wantsEverything = type === EntryTypes.EVERYTHING_TYPE;
54825
- this._root = (0, import_node_path16.resolve)(root);
55107
+ this._root = (0, import_node_path18.resolve)(root);
54826
55108
  this._isDirent = !opts.alwaysStat;
54827
55109
  this._statsProp = this._isDirent ? "dirent" : "stats";
54828
55110
  this._rdOptions = { encoding: "utf8", withFileTypes: this._isDirent };
@@ -54893,8 +55175,8 @@ var ReaddirpStream = class extends import_node_stream2.Readable {
54893
55175
  let entry2;
54894
55176
  const basename5 = this._isDirent ? dirent.name : dirent;
54895
55177
  try {
54896
- const fullPath = (0, import_node_path16.resolve)((0, import_node_path16.join)(path, basename5));
54897
- entry2 = { path: (0, import_node_path16.relative)(this._root, fullPath), fullPath, basename: basename5 };
55178
+ const fullPath = (0, import_node_path18.resolve)((0, import_node_path18.join)(path, basename5));
55179
+ entry2 = { path: (0, import_node_path18.relative)(this._root, fullPath), fullPath, basename: basename5 };
54898
55180
  entry2[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
54899
55181
  } catch (err) {
54900
55182
  this._onError(err);
@@ -54928,7 +55210,7 @@ var ReaddirpStream = class extends import_node_stream2.Readable {
54928
55210
  }
54929
55211
  if (entryRealPathStats.isDirectory()) {
54930
55212
  const len = entryRealPath.length;
54931
- if (full.startsWith(entryRealPath) && full.substr(len, 1) === import_node_path16.sep) {
55213
+ if (full.startsWith(entryRealPath) && full.substr(len, 1) === import_node_path18.sep) {
54932
55214
  const recursiveError = new Error(`Circular symlink detected: "${full}" points to "${entryRealPath}"`);
54933
55215
  recursiveError.code = RECURSIVE_ERROR_CODE;
54934
55216
  return this._onError(recursiveError);
@@ -55467,9 +55749,9 @@ var NodeFsHandler = class {
55467
55749
  if (this.fsw.closed) {
55468
55750
  return;
55469
55751
  }
55470
- const dirname9 = sysPath.dirname(file);
55752
+ const dirname10 = sysPath.dirname(file);
55471
55753
  const basename5 = sysPath.basename(file);
55472
- const parent = this.fsw._getWatchedDir(dirname9);
55754
+ const parent = this.fsw._getWatchedDir(dirname10);
55473
55755
  let prevStats = stats;
55474
55756
  if (parent.has(basename5))
55475
55757
  return;
@@ -55496,7 +55778,7 @@ var NodeFsHandler = class {
55496
55778
  prevStats = newStats2;
55497
55779
  }
55498
55780
  } catch (error) {
55499
- this.fsw._remove(dirname9, basename5);
55781
+ this.fsw._remove(dirname10, basename5);
55500
55782
  }
55501
55783
  } else if (parent.has(basename5)) {
55502
55784
  const at = newStats.atimeMs;
@@ -55592,7 +55874,7 @@ var NodeFsHandler = class {
55592
55874
  this._addToNodeFs(path, initialAdd, wh, depth + 1);
55593
55875
  }
55594
55876
  }).on(EV.ERROR, this._boundHandleError);
55595
- return new Promise((resolve4, reject) => {
55877
+ return new Promise((resolve5, reject) => {
55596
55878
  if (!stream)
55597
55879
  return reject();
55598
55880
  stream.once(STR_END, () => {
@@ -55601,7 +55883,7 @@ var NodeFsHandler = class {
55601
55883
  return;
55602
55884
  }
55603
55885
  const wasThrottled = throttler ? throttler.clear() : false;
55604
- resolve4(void 0);
55886
+ resolve5(void 0);
55605
55887
  previous.getChildren().filter((item) => {
55606
55888
  return item !== directory && !current.has(item);
55607
55889
  }).forEach((item) => {
@@ -56435,16 +56717,34 @@ function appIdFromLogPath(path) {
56435
56717
  const i = parts.lastIndexOf("logs");
56436
56718
  return i >= 0 && parts[i + 1] ? parts[i + 1] : null;
56437
56719
  }
56720
+ function samePath(a, b) {
56721
+ const ra = (0, import_node_path19.resolve)(a);
56722
+ const rb = (0, import_node_path19.resolve)(b);
56723
+ return process.platform === "win32" ? ra.toLowerCase() === rb.toLowerCase() : ra === rb;
56724
+ }
56725
+ function underDir(path, dir) {
56726
+ const rp = (0, import_node_path19.resolve)(path);
56727
+ const rd = (0, import_node_path19.resolve)(dir);
56728
+ const [p, d] = process.platform === "win32" ? [rp.toLowerCase(), rd.toLowerCase()] : [rp, rd];
56729
+ return p === d || p.startsWith(d + import_node_path19.sep);
56730
+ }
56438
56731
  function startWatcher() {
56439
- const awareDir = process.env.AWARE_HOME ?? (0, import_node_path17.join)((0, import_node_os11.homedir)(), ".aware");
56440
- const credentialsDir = (0, import_node_path17.join)(awareDir, "credentials");
56441
- if (!(0, import_node_fs18.existsSync)(credentialsDir)) {
56732
+ const awareDir = process.env.AWARE_HOME ?? (0, import_node_path19.join)((0, import_node_os12.homedir)(), ".aware");
56733
+ const credentialsDir = (0, import_node_path19.join)(awareDir, "credentials");
56734
+ if (!(0, import_node_fs20.existsSync)(credentialsDir)) {
56442
56735
  try {
56443
- (0, import_node_fs18.mkdirSync)(credentialsDir, { recursive: true });
56736
+ (0, import_node_fs20.mkdirSync)(credentialsDir, { recursive: true });
56444
56737
  } catch {
56445
56738
  }
56446
56739
  }
56447
- const targets = ["apps", "logs", "credentials"].map((d) => (0, import_node_path17.join)(awareDir, d)).filter((p) => (0, import_node_fs18.existsSync)(p));
56740
+ if (!(0, import_node_fs20.existsSync)(uiDir)) {
56741
+ try {
56742
+ (0, import_node_fs20.mkdirSync)(uiDir, { recursive: true });
56743
+ } catch {
56744
+ }
56745
+ }
56746
+ const targets = ["apps", "logs", "credentials"].map((d) => (0, import_node_path19.join)(awareDir, d)).filter((p) => (0, import_node_fs20.existsSync)(p));
56747
+ if ((0, import_node_fs20.existsSync)(uiDir)) targets.push(uiDir);
56448
56748
  if (targets.length === 0) {
56449
56749
  return null;
56450
56750
  }
@@ -56452,15 +56752,33 @@ function startWatcher() {
56452
56752
  ignoreInitial: true,
56453
56753
  awaitWriteFinish: { stabilityThreshold: 150, pollInterval: 50 }
56454
56754
  });
56755
+ let lastExtContent = readExtensionsText();
56756
+ const handleExtensionsChange = () => {
56757
+ const next = readExtensionsText();
56758
+ if (next === lastExtContent) return;
56759
+ if (lastExtContent !== null) {
56760
+ try {
56761
+ snapshotExtensions(lastExtContent);
56762
+ } catch (err) {
56763
+ console.warn("[floless] failed to snapshot the previous extensions.json before a change (undo for this step is lost):", err);
56764
+ }
56765
+ }
56766
+ lastExtContent = next;
56767
+ broadcast({ type: "extensions-changed" });
56768
+ };
56455
56769
  watcher.on("all", (event, path) => {
56770
+ if (underDir(path, uiDir)) {
56771
+ if (samePath(path, extensionsFile)) handleExtensionsChange();
56772
+ return;
56773
+ }
56456
56774
  const isCredential = path.split(/[\\/]/).includes("credentials");
56457
56775
  const kind = isCredential ? "credential" : path.endsWith(".jsonl") ? "trace" : path.endsWith(".lock") ? "lock" : path.endsWith(".flo") || path.endsWith(".app") ? "source" : "file";
56458
56776
  broadcast({ type: "fs-change", kind, event, path });
56459
- if (kind === "trace" && event !== "unlink" && (0, import_node_fs18.existsSync)(path)) {
56777
+ if (kind === "trace" && event !== "unlink" && (0, import_node_fs20.existsSync)(path)) {
56460
56778
  const id = appIdFromLogPath(path);
56461
56779
  if (!id) return;
56462
56780
  try {
56463
- broadcast({ type: "trace-file", id, runId: path.split(import_node_path17.sep).pop()?.replace(/\.jsonl$/, "") ?? null, events: parseTrace((0, import_node_fs18.readFileSync)(path, "utf8")) });
56781
+ broadcast({ type: "trace-file", id, runId: path.split(import_node_path19.sep).pop()?.replace(/\.jsonl$/, "") ?? null, events: parseTrace((0, import_node_fs20.readFileSync)(path, "utf8")) });
56464
56782
  } catch {
56465
56783
  }
56466
56784
  }
@@ -56469,10 +56787,10 @@ function startWatcher() {
56469
56787
  }
56470
56788
 
56471
56789
  // index.ts
56472
- var __dirname4 = (0, import_node_path18.dirname)((0, import_node_url3.fileURLToPath)(__import_meta_url));
56473
- var WEB_ROOT = [(0, import_node_path18.join)(__dirname4, "web"), (0, import_node_path18.join)((0, import_node_path18.dirname)(process.execPath), "web"), (0, import_node_path18.join)(__dirname4, "..", "web")].find(
56474
- (p) => (0, import_node_fs19.existsSync)(p)
56475
- ) ?? (0, import_node_path18.join)(__dirname4, "..", "web");
56790
+ var __dirname4 = (0, import_node_path20.dirname)((0, import_node_url3.fileURLToPath)(__import_meta_url));
56791
+ var WEB_ROOT = [(0, import_node_path20.join)(__dirname4, "web"), (0, import_node_path20.join)((0, import_node_path20.dirname)(process.execPath), "web"), (0, import_node_path20.join)(__dirname4, "..", "web")].find(
56792
+ (p) => (0, import_node_fs21.existsSync)(p)
56793
+ ) ?? (0, import_node_path20.join)(__dirname4, "..", "web");
56476
56794
  var PORT2 = Number(process.env.PORT ?? 4317);
56477
56795
  var HOST = "127.0.0.1";
56478
56796
  function extractReportHtml(events) {
@@ -56499,7 +56817,7 @@ function installCrashHandlers() {
56499
56817
  ${stack}
56500
56818
  `;
56501
56819
  try {
56502
- (0, import_node_fs19.appendFileSync)(logFilePath(), line);
56820
+ (0, import_node_fs21.appendFileSync)(logFilePath(), line);
56503
56821
  } catch {
56504
56822
  }
56505
56823
  if (process.stderr.isTTY) process.stderr.write(line);
@@ -56542,7 +56860,7 @@ async function startServer() {
56542
56860
  };
56543
56861
  function installAwareGlobal(spec, onLine = () => {
56544
56862
  }) {
56545
- return new Promise((resolve4, reject) => {
56863
+ return new Promise((resolve5, reject) => {
56546
56864
  const child = (0, import_node_child_process6.spawn)("npm", ["i", "-g", `@aware-aeco/cli@${spec}`], { shell: isWin3, windowsHide: true });
56547
56865
  let stderrTail = "";
56548
56866
  let combinedTail = "";
@@ -56559,7 +56877,7 @@ async function startServer() {
56559
56877
  onLine(s.trimEnd());
56560
56878
  });
56561
56879
  child.on("error", (e) => reject(e));
56562
- child.on("close", (code) => code === 0 ? resolve4() : reject(new Error(`npm exited ${code}: ${stderrTail || combinedTail}`)));
56880
+ child.on("close", (code) => code === 0 ? resolve5() : reject(new Error(`npm exited ${code}: ${stderrTail || combinedTail}`)));
56563
56881
  });
56564
56882
  }
56565
56883
  const bootstrapDeps = {
@@ -56844,13 +57162,13 @@ async function startServer() {
56844
57162
  }
56845
57163
  const inputs = appData.inputs.map((i) => ({ name: i.name, type: i.type }));
56846
57164
  const baked = bakeFloSource(appData.source.text, inputs);
56847
- const tmpRoot = (0, import_node_fs19.mkdtempSync)((0, import_node_path18.join)((0, import_node_os12.tmpdir)(), "floless-bake-"));
56848
- const backupDir = (0, import_node_path18.join)(tmpRoot, `${id}-backup`);
56849
- const bakeDir = (0, import_node_path18.join)(tmpRoot, id);
56850
- (0, import_node_fs19.cpSync)(appDir(id), backupDir, { recursive: true });
56851
- (0, import_node_fs19.cpSync)(appDir(id), bakeDir, { recursive: true });
57165
+ const tmpRoot = (0, import_node_fs21.mkdtempSync)((0, import_node_path20.join)((0, import_node_os13.tmpdir)(), "floless-bake-"));
57166
+ const backupDir = (0, import_node_path20.join)(tmpRoot, `${id}-backup`);
57167
+ const bakeDir = (0, import_node_path20.join)(tmpRoot, id);
57168
+ (0, import_node_fs21.cpSync)(appDir(id), backupDir, { recursive: true });
57169
+ (0, import_node_fs21.cpSync)(appDir(id), bakeDir, { recursive: true });
56852
57170
  const floName = appData.source.path.split(/[\\/]/).pop();
56853
- (0, import_node_fs19.writeFileSync)((0, import_node_path18.join)(bakeDir, floName), baked);
57171
+ (0, import_node_fs21.writeFileSync)((0, import_node_path20.join)(bakeDir, floName), baked);
56854
57172
  let appInstalled = true;
56855
57173
  try {
56856
57174
  await aware.uninstall(id);
@@ -56872,17 +57190,17 @@ async function startServer() {
56872
57190
  throw installErr;
56873
57191
  }
56874
57192
  try {
56875
- await aware.compile((0, import_node_path18.join)(appDir(id), floName));
57193
+ await aware.compile((0, import_node_path20.join)(appDir(id), floName));
56876
57194
  } catch (compileErr) {
56877
57195
  app.log.warn({ id, compileErr: String(compileErr) }, "bake: post-install recompile failed (app baked but may need a manual Compile)");
56878
57196
  }
56879
57197
  broadcast({ type: "baked", id });
56880
57198
  return { ok: true, id, agent: id, inputs };
56881
57199
  } finally {
56882
- if (appInstalled) (0, import_node_fs19.rmSync)(tmpRoot, { recursive: true, force: true });
57200
+ if (appInstalled) (0, import_node_fs21.rmSync)(tmpRoot, { recursive: true, force: true });
56883
57201
  }
56884
57202
  });
56885
- const graftAgentsDir = () => (0, import_node_path18.join)((0, import_node_os12.homedir)(), ".aware", "agents");
57203
+ const graftAgentsDir = () => (0, import_node_path20.join)((0, import_node_os13.homedir)(), ".aware", "agents");
56886
57204
  app.post("/api/graft/match", async (req, reply) => {
56887
57205
  const { glob } = req.body ?? {};
56888
57206
  if (!glob) return reply.status(400).send({ ok: false, error: "glob required" });
@@ -56899,7 +57217,7 @@ async function startServer() {
56899
57217
  if (!sourceKind || !sourceRef) {
56900
57218
  return reply.status(400).send({ ok: false, error: "sourceKind and sourceRef required" });
56901
57219
  }
56902
- const tempHome = (0, import_node_fs19.mkdtempSync)((0, import_node_path18.join)((0, import_node_os12.tmpdir)(), "floless-graft-"));
57220
+ const tempHome = (0, import_node_fs21.mkdtempSync)((0, import_node_path20.join)((0, import_node_os13.tmpdir)(), "floless-graft-"));
56903
57221
  let result;
56904
57222
  try {
56905
57223
  result = await aware.build({
@@ -56912,19 +57230,19 @@ async function startServer() {
56912
57230
  awareHome: tempHome
56913
57231
  });
56914
57232
  } catch (err) {
56915
- (0, import_node_fs19.rmSync)(tempHome, { recursive: true, force: true });
57233
+ (0, import_node_fs21.rmSync)(tempHome, { recursive: true, force: true });
56916
57234
  const msg = err instanceof AwareError ? err.message : String(err?.message ?? err);
56917
57235
  return reply.status(422).send({ ok: false, error: msg });
56918
57236
  }
56919
57237
  const manifest = readStagedManifest(result.agentDir);
56920
57238
  if (!manifest) {
56921
- (0, import_node_fs19.rmSync)(tempHome, { recursive: true, force: true });
57239
+ (0, import_node_fs21.rmSync)(tempHome, { recursive: true, force: true });
56922
57240
  return reply.status(502).send({ ok: false, error: `build produced output at ${result.agentDir} but no manifest.yaml` });
56923
57241
  }
56924
- const token = (0, import_node_crypto5.randomUUID)();
57242
+ const token = (0, import_node_crypto6.randomUUID)();
56925
57243
  registerStage(token, tempHome, result.agentId);
56926
57244
  const preview = buildPreview(manifest, sourceKind, sourceRef, token);
56927
- if ((0, import_node_fs19.existsSync)((0, import_node_path18.join)(graftAgentsDir(), result.agentId))) {
57245
+ if ((0, import_node_fs21.existsSync)((0, import_node_path20.join)(graftAgentsDir(), result.agentId))) {
56928
57246
  preview.warnings.unshift(`An agent named "${result.agentId}" is already installed \u2014 creating it will overwrite it.`);
56929
57247
  }
56930
57248
  return { ok: true, preview };
@@ -56943,7 +57261,7 @@ async function startServer() {
56943
57261
  registerStage(stagedRef, stage.tempDir, stage.agentId);
56944
57262
  return reply.status(409).send({ ok: false, error: err.message, agentId: stage.agentId, collision: true });
56945
57263
  }
56946
- (0, import_node_fs19.rmSync)(stage.tempDir, { recursive: true, force: true });
57264
+ (0, import_node_fs21.rmSync)(stage.tempDir, { recursive: true, force: true });
56947
57265
  throw err;
56948
57266
  }
56949
57267
  broadcast({ type: "grafted", id: stage.agentId });
@@ -57117,11 +57435,11 @@ async function startServer() {
57117
57435
  app.get("/api/requests/:id/snapshot/:n", async (req, reply) => {
57118
57436
  const n = Number.parseInt(req.params.n, 10);
57119
57437
  const p = Number.isInteger(n) ? snapshotPathFor(req.params.id, n) : null;
57120
- if (!p || !(0, import_node_fs19.existsSync)(p)) return reply.status(404).send({ ok: false, error: "snapshot not found" });
57438
+ if (!p || !(0, import_node_fs21.existsSync)(p)) return reply.status(404).send({ ok: false, error: "snapshot not found" });
57121
57439
  const ext = p.split(".").pop().toLowerCase();
57122
57440
  reply.header("Content-Type", ext === "png" ? "image/png" : ext === "webp" ? "image/webp" : "image/jpeg");
57123
57441
  reply.header("Cache-Control", "no-store");
57124
- return (0, import_node_fs19.readFileSync)(p);
57442
+ return (0, import_node_fs21.readFileSync)(p);
57125
57443
  });
57126
57444
  app.post(
57127
57445
  "/api/tweak",
@@ -57161,6 +57479,158 @@ async function startServer() {
57161
57479
  broadcast({ type: "requests-changed" });
57162
57480
  return { ok: true, cleared };
57163
57481
  });
57482
+ const EXT_SOURCE_REF = /^[A-Za-z0-9._-]+$/;
57483
+ function pickRows(v) {
57484
+ const isRowArray = (x) => Array.isArray(x) && x.length > 0 && x.every((r) => !!r && typeof r === "object" && !Array.isArray(r));
57485
+ if (isRowArray(v)) return v;
57486
+ if (v && typeof v === "object") {
57487
+ for (const key of ["rows", "items", "data"]) {
57488
+ const inner = v[key];
57489
+ if (isRowArray(inner)) return inner;
57490
+ }
57491
+ }
57492
+ return null;
57493
+ }
57494
+ function extractRunRows(events) {
57495
+ let rows = null;
57496
+ for (const ev of events) {
57497
+ const data = ev.data;
57498
+ if (!data || typeof data !== "object") continue;
57499
+ const found = pickRows(data.result ?? data);
57500
+ if (found) rows = found;
57501
+ }
57502
+ return rows;
57503
+ }
57504
+ const EXT_TRACE_MAX_BYTES = 5 * 1024 * 1024;
57505
+ function resolveExtensionSource(source, warn = () => {
57506
+ }) {
57507
+ const sep3 = source.indexOf(":");
57508
+ if (sep3 <= 0) return void 0;
57509
+ const kind = source.slice(0, sep3);
57510
+ const ref = source.slice(sep3 + 1);
57511
+ if (!EXT_SOURCE_REF.test(ref)) return void 0;
57512
+ if (kind === "last-run-output") {
57513
+ const latest = readLatestTrace(ref, void 0, EXT_TRACE_MAX_BYTES);
57514
+ if (!latest) return void 0;
57515
+ const events = parseTrace(latest.text);
57516
+ if (!latest.truncated && isTraceCorrupt(events)) {
57517
+ warn(`last-run-output:${ref} \u2014 trace exists but couldn't be parsed (corrupt/truncated)`);
57518
+ return { appId: ref, runId: latest.runId, status: "unknown", rows: null, html: null, traceUnreadable: true };
57519
+ }
57520
+ return {
57521
+ appId: ref,
57522
+ runId: latest.runId,
57523
+ status: summarizeRun(events).status,
57524
+ rows: extractRunRows(events),
57525
+ html: withBadge(extractReportHtml(events))?.html ?? null
57526
+ };
57527
+ }
57528
+ if (kind === "last-run-status") {
57529
+ const latest = readLatestTrace(ref, void 0, EXT_TRACE_MAX_BYTES);
57530
+ if (!latest) return { appId: ref, status: "none", finishedAt: null, runId: null };
57531
+ const events = parseTrace(latest.text);
57532
+ if (!latest.truncated && isTraceCorrupt(events)) {
57533
+ warn(`last-run-status:${ref} \u2014 trace exists but couldn't be parsed (corrupt/truncated)`);
57534
+ let finishedAt2 = null;
57535
+ try {
57536
+ finishedAt2 = (0, import_node_fs21.statSync)(latest.path).mtime.toISOString();
57537
+ } catch {
57538
+ finishedAt2 = null;
57539
+ }
57540
+ return { appId: ref, status: "unknown", finishedAt: finishedAt2, runId: latest.runId, traceUnreadable: true };
57541
+ }
57542
+ const runEnd = [...events].reverse().find((e) => e.kind === "run-end");
57543
+ let finishedAt = typeof runEnd?.ts === "string" ? runEnd.ts : null;
57544
+ if (!finishedAt) {
57545
+ try {
57546
+ finishedAt = (0, import_node_fs21.statSync)(latest.path).mtime.toISOString();
57547
+ } catch {
57548
+ finishedAt = null;
57549
+ }
57550
+ }
57551
+ return { appId: ref, status: summarizeRun(events).status, finishedAt, runId: latest.runId };
57552
+ }
57553
+ if (kind === "routine-status") {
57554
+ const routines2 = listRoutines();
57555
+ const r = routines2.find((x) => x.id === ref) ?? routines2.find((x) => x.workflow === ref);
57556
+ if (!r) return void 0;
57557
+ return {
57558
+ id: r.id,
57559
+ name: r.name,
57560
+ workflow: r.workflow,
57561
+ kind: r.kind,
57562
+ enabled: r.enabled,
57563
+ nextFireAt: r.nextFireAt,
57564
+ lastRun: r.lastRun,
57565
+ broken: r.broken ?? null
57566
+ };
57567
+ }
57568
+ return void 0;
57569
+ }
57570
+ let uiAgentInstallKicked = false;
57571
+ let validationCache = null;
57572
+ app.get("/api/extensions", async () => {
57573
+ const descriptor = readExtensions();
57574
+ let validation = null;
57575
+ if (descriptor !== null) {
57576
+ const cacheKey = JSON.stringify(descriptor);
57577
+ if (validationCache && validationCache.key === cacheKey) {
57578
+ return finishExtensions(descriptor, validationCache.result);
57579
+ }
57580
+ try {
57581
+ validation = await aware.agentInvoke("ui", "validate", { descriptor }) ?? null;
57582
+ if (validation) validationCache = { key: cacheKey, result: validation };
57583
+ } catch (err) {
57584
+ const mapped = classifyValidateError(err);
57585
+ if (mapped.installing && !uiAgentInstallKicked) {
57586
+ uiAgentInstallKicked = true;
57587
+ aware.ensureAgentInstalled("ui").then(() => broadcast({ type: "extensions-changed" })).catch((e) => app.log.warn({ err: String(e) }, "ui agent auto-install failed"));
57588
+ }
57589
+ if (mapped.unexpected) app.log.warn({ err: String(err) }, "ui validate failed unexpectedly");
57590
+ validation = mapped;
57591
+ if (!mapped.installing && !mapped.unexpected) validationCache = { key: cacheKey, result: validation };
57592
+ }
57593
+ }
57594
+ return finishExtensions(descriptor, validation);
57595
+ });
57596
+ function finishExtensions(descriptor, validation) {
57597
+ const data = {};
57598
+ for (const panel of descriptorPanels(descriptor)) {
57599
+ const blocks = Array.isArray(panel.blocks) ? panel.blocks : [];
57600
+ for (const block of blocks) {
57601
+ if (!block || typeof block !== "object") continue;
57602
+ const b = block;
57603
+ if (b.type !== "table" && b.type !== "report") continue;
57604
+ const src = b.source;
57605
+ if (typeof src !== "string" || src in data) continue;
57606
+ try {
57607
+ const payload = resolveExtensionSource(src, (msg) => app.log.warn(msg));
57608
+ if (payload !== void 0) data[src] = payload;
57609
+ } catch {
57610
+ }
57611
+ }
57612
+ }
57613
+ return { ok: true, descriptor, validation, data };
57614
+ }
57615
+ app.post("/api/extensions/customize", async (req, reply) => {
57616
+ const instruction = typeof req.body?.instruction === "string" ? req.body.instruction.trim() : "";
57617
+ if (!instruction) return reply.status(400).send({ ok: false, error: "instruction required" });
57618
+ const panelId = typeof req.body?.panelId === "string" && req.body.panelId.trim() ? req.body.panelId.trim() : void 0;
57619
+ const request = addRequest({ type: "ui-customize", instruction, ...panelId ? { panelId } : {} });
57620
+ broadcast({ type: "request-added", request });
57621
+ return { ok: true, request };
57622
+ });
57623
+ app.post("/api/extensions/undo", async (_req, reply) => {
57624
+ const result = undoExtensions();
57625
+ if (!result.restored) return reply.send({ ok: false, error: "nothing to undo" });
57626
+ return { ok: true, descriptor: result.descriptor };
57627
+ });
57628
+ app.post("/api/extensions/reset", async (_req, reply) => {
57629
+ const result = resetExtensions();
57630
+ if (!result.reset) return reply.send({ ok: false, error: "nothing to reset \u2014 the dashboard is already the default" });
57631
+ return { ok: true, descriptor: null };
57632
+ });
57633
+ app.get("/api/extensions/history", async () => ({ ok: true, history: listHistory() }));
57164
57634
  app.get("/api/events", async (_req, reply) => {
57165
57635
  reply.hijack();
57166
57636
  reply.raw.writeHead(200, {
@@ -57226,11 +57696,11 @@ function unregisterProtocol() {
57226
57696
 
57227
57697
  // main.ts
57228
57698
  function promptYesNo2(question) {
57229
- return new Promise((resolve4) => {
57699
+ return new Promise((resolve5) => {
57230
57700
  const rl = (0, import_node_readline2.createInterface)({ input: process.stdin, output: process.stdout });
57231
57701
  rl.question(`${question} `, (answer) => {
57232
57702
  rl.close();
57233
- resolve4(/^y(es)?$/i.test((answer ?? "").trim()));
57703
+ resolve5(/^y(es)?$/i.test((answer ?? "").trim()));
57234
57704
  });
57235
57705
  });
57236
57706
  }