@floless/app 0.6.3 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5489,7 +5489,7 @@ var require_thread_stream = __commonJS({
5489
5489
  var { version } = require_package();
5490
5490
  var { EventEmitter: EventEmitter2 } = require("events");
5491
5491
  var { Worker } = require("worker_threads");
5492
- var { join: join19 } = require("path");
5492
+ var { join: join20 } = 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"] || join19(__dirname, "lib", "worker.js");
5543
+ const toExecute = bundlerOverrides["thread-stream-worker"] || join20(__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: existsSync17 } = require("node:fs");
6009
+ var { existsSync: existsSync18 } = require("node:fs");
6010
6010
  var getCallers = require_caller();
6011
- var { join: join19, isAbsolute: isAbsolute2, sep: sep3 } = require("node:path");
6011
+ var { join: join20, 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) && !existsSync17(path);
6083
+ return isAbsolute2(path) && !existsSync18(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"] || join19(__dirname, "worker.js");
6164
+ target = bundlerOverrides["pino-worker"] || join20(__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"] || join19(__dirname, "worker.js");
6182
+ target = bundlerOverrides["pino-worker"] || join20(__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 join19(__dirname, "..", "file.js");
6205
+ return join20(__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 join19 = ",";
7185
+ let join20 = ",";
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
- join19 = `,
7199
+ join20 = `,
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 += join19;
7207
+ res += join20;
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 += `${join19}"... ${getItemCount(removedKeys)} not stringified"`;
7213
+ res += `${join20}"... ${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
- join19 = `,
7234
+ join20 = `,
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 = join19;
7248
+ separator = join20;
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 = join19;
7254
+ separator = join20;
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 join19 = ",";
7295
+ let join20 = ",";
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
- join19 = `,
7308
+ join20 = `,
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 += join19;
7316
+ res += join20;
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 += `${join19}"... ${getItemCount(removedKeys)} not stringified"`;
7322
+ res += `${join20}"... ${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
- join19 = `,
7335
+ join20 = `,
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 = join19;
7344
+ separator = join20;
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 join20 = `,
7402
+ const join21 = `,
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 += join20;
7409
+ res2 += join21;
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 += `${join20}"... ${getItemCount(removedKeys)} not stringified"`;
7415
+ res2 += `${join21}"... ${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 join19 = `,
7431
+ const join20 = `,
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, join19, maximumBreadth);
7437
+ res += stringifyTypedArray(value, join20, maximumBreadth);
7438
7438
  keys = keys.slice(value.length);
7439
7439
  maximumPropertiesToStringify -= value.length;
7440
- separator = join19;
7440
+ separator = join20;
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 = join19;
7451
+ separator = join20;
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 = join19;
7457
+ separator = join20;
7458
7458
  }
7459
7459
  if (separator !== "") {
7460
7460
  res = `
@@ -41991,7 +41991,7 @@ var require_send = __commonJS({
41991
41991
  var { parseTokenList } = require_parseTokenList();
41992
41992
  var { createHttpError } = require_createHttpError();
41993
41993
  var extname2 = path.extname;
41994
- var join19 = path.join;
41994
+ var join20 = path.join;
41995
41995
  var normalize2 = path.normalize;
41996
41996
  var resolve4 = path.resolve;
41997
41997
  var sep3 = path.sep;
@@ -42078,7 +42078,7 @@ var require_send = __commonJS({
42078
42078
  return { statusCode: 403 };
42079
42079
  }
42080
42080
  parts = path2.split(sep3);
42081
- path2 = normalize2(join19(root, path2));
42081
+ path2 = normalize2(join20(root, path2));
42082
42082
  } else {
42083
42083
  if (UP_PATH_REGEXP.test(path2)) {
42084
42084
  debug('malicious path "%s"', path2);
@@ -42361,7 +42361,7 @@ var require_send = __commonJS({
42361
42361
  let err;
42362
42362
  for (let i = 0; i < options.index.length; i++) {
42363
42363
  const index = options.index[i];
42364
- const p = join19(path2, index);
42364
+ const p = join20(path2, index);
42365
42365
  const { error, stat: stat4 } = await tryStat(p);
42366
42366
  if (error) {
42367
42367
  err = error;
@@ -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_path17 = require("node:path");
50831
- var import_node_os11 = require("node:os");
50832
- var import_node_fs18 = require("node:fs");
50830
+ var import_node_path18 = require("node:path");
50831
+ var import_node_os12 = require("node:os");
50832
+ var import_node_fs19 = require("node:fs");
50833
50833
  var import_node_child_process6 = require("node:child_process");
50834
50834
 
50835
50835
  // log.mjs
@@ -51127,6 +51127,24 @@ function listIntegrations() {
51127
51127
  }
51128
51128
  return out.sort((a, b) => a.name.localeCompare(b.name));
51129
51129
  }
51130
+ function mergeConnectables(base, live, displayName) {
51131
+ const have = new Set(base.map((i) => i.id));
51132
+ const extra = [];
51133
+ for (const c of live) {
51134
+ if (have.has(c.integration)) continue;
51135
+ const status = c.status === "valid" ? "connected" : c.status === "expired" ? "expired" : "disconnected";
51136
+ extra.push({
51137
+ id: c.integration,
51138
+ name: displayName(c.integration),
51139
+ vendor: null,
51140
+ agent: "first-party",
51141
+ network: [],
51142
+ status,
51143
+ expiresAt: c.expires_in_secs != null ? new Date(Date.now() + c.expires_in_secs * 1e3).toISOString() : null
51144
+ });
51145
+ }
51146
+ return [...base, ...extra].sort((a, b) => a.name.localeCompare(b.name));
51147
+ }
51130
51148
  function parseTrace(text) {
51131
51149
  return text.split(/\r?\n/).filter((l) => l.trim()).map((l) => {
51132
51150
  try {
@@ -51540,6 +51558,16 @@ function parseBuildOutput(stdout) {
51540
51558
  rawOutput: stdout.trim()
51541
51559
  };
51542
51560
  }
51561
+ function agentInstallArgv(id) {
51562
+ return ["agent", "install", assertId(id)];
51563
+ }
51564
+ function parseAgentInstallOutput(stdout) {
51565
+ const m = stdout.match(/✓\s+installed\s+(\S+)/);
51566
+ return { installed: m?.[1] ?? null };
51567
+ }
51568
+ function isAgentInstalled(agents, id) {
51569
+ return agents.some((a) => a.id === id);
51570
+ }
51543
51571
  var inFlightConnects = /* @__PURE__ */ new Map();
51544
51572
  function cancelAllConnects() {
51545
51573
  for (const cancel of inFlightConnects.values()) cancel();
@@ -51717,6 +51745,28 @@ var aware = {
51717
51745
  if (code !== 0) throw new AwareError(`aware app uninstall failed (exit ${code})`, { stdout, stderr });
51718
51746
  return { output: stdout.trim() };
51719
51747
  },
51748
+ /**
51749
+ * Install a first-party agent by registry id (`aware agent install <id>`). The
51750
+ * registry install pulls a large tarball (~200s observed) — far over runRaw's 60s
51751
+ * default — so use a generous timeout. NOT idempotent: it errors `conflict:
51752
+ * already installed` (exit 8) when the agent is present, so callers should prefer
51753
+ * `ensureAgentInstalled`. The token is NOT involved — only the agent manifest is fetched.
51754
+ */
51755
+ async agentInstall(id) {
51756
+ const { code, stdout, stderr } = await runRawWithEnv(agentInstallArgv(id), void 0, 6e5);
51757
+ if (code !== 0) throw new AwareError(`aware agent install ${id} failed (exit ${code})`, { stdout, stderr });
51758
+ return { ...parseAgentInstallOutput(stdout), output: stdout.trim() };
51759
+ },
51760
+ /**
51761
+ * Ensure agent <id> is installed, idempotently. Checks the installed list first
51762
+ * (cheap — an `agent list`) and only installs when absent, so it avoids both the
51763
+ * `conflict: already installed` error and the slow tarball pull on the common path.
51764
+ */
51765
+ async ensureAgentInstalled(id) {
51766
+ const agents = await this.agentList();
51767
+ if (isAgentInstalled(agents, id)) return { installed: id, output: "already installed" };
51768
+ return this.agentInstall(id);
51769
+ },
51720
51770
  /**
51721
51771
  * POST /api/run — installed ID. `run` ignores --json and prints
51722
51772
  * "✓ run complete; trace at <path>"; we parse the path and read the JSONL.
@@ -52258,7 +52308,7 @@ function appVersion() {
52258
52308
  return resolveVersion({
52259
52309
  isSea: isSea2(),
52260
52310
  sqVersionXml: readSqVersionXml(),
52261
- define: true ? "0.6.3" : void 0,
52311
+ define: true ? "0.7.0" : void 0,
52262
52312
  pkgVersion: readPkgVersion()
52263
52313
  });
52264
52314
  }
@@ -52268,7 +52318,64 @@ function resolveChannel(s) {
52268
52318
  return "dev";
52269
52319
  }
52270
52320
  function appChannel() {
52271
- return resolveChannel({ isSea: isSea2(), define: true ? "0.6.3" : void 0 });
52321
+ return resolveChannel({ isSea: isSea2(), define: true ? "0.7.0" : void 0 });
52322
+ }
52323
+
52324
+ // oauth-presets.ts
52325
+ var import_node_os6 = require("node:os");
52326
+ var import_node_path6 = require("node:path");
52327
+ var import_node_net = __toESM(require("node:net"), 1);
52328
+ var import_node_fs7 = require("node:fs");
52329
+ var MANAGED_HEADER = "# managed by floless.app - do not edit";
52330
+ var OAUTH_PRESETS = {
52331
+ "trimble-connect": {
52332
+ id: "trimble-connect",
52333
+ displayName: "Trimble Connect",
52334
+ clientId: process.env.FLOLESS_TRIMBLE_CLIENT_ID ?? "0a2444e4-f531-4a67-ab43-edc93ccff680",
52335
+ redirectUri: "http://localhost",
52336
+ callbackPort: 80
52337
+ }
52338
+ };
52339
+ function friendlyIntegrationName(id) {
52340
+ const preset = OAUTH_PRESETS[id];
52341
+ if (preset) return preset.displayName;
52342
+ const known = {
52343
+ "microsoft-365": "Microsoft 365",
52344
+ "google-workspace": "Google Workspace"
52345
+ };
52346
+ return known[id] ?? id.replace(/[-_]+/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
52347
+ }
52348
+ function managedProfileYaml(preset) {
52349
+ return [
52350
+ MANAGED_HEADER,
52351
+ `client_id: ${preset.clientId}`,
52352
+ `redirect_uri: ${preset.redirectUri}`,
52353
+ `callback_port: ${preset.callbackPort}`,
52354
+ ""
52355
+ ].join("\n");
52356
+ }
52357
+ function oauthDir() {
52358
+ 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");
52359
+ }
52360
+ function ensureManagedProfile(id) {
52361
+ const preset = OAUTH_PRESETS[id];
52362
+ if (!preset) return "not-managed";
52363
+ const dir = oauthDir();
52364
+ const file = (0, import_node_path6.join)(dir, `${id}.yaml`);
52365
+ const existing = (0, import_node_fs7.existsSync)(file) ? (0, import_node_fs7.readFileSync)(file, "utf8") : null;
52366
+ if (existing !== null && !existing.startsWith(MANAGED_HEADER)) return "skipped";
52367
+ const desired = managedProfileYaml(preset);
52368
+ if (existing === desired) return "unchanged";
52369
+ (0, import_node_fs7.mkdirSync)(dir, { recursive: true });
52370
+ (0, import_node_fs7.writeFileSync)(file, desired, "utf8");
52371
+ return "written";
52372
+ }
52373
+ function isPortBindable(port, host = "127.0.0.1") {
52374
+ return new Promise((resolve4) => {
52375
+ const srv = import_node_net.default.createServer();
52376
+ srv.once("error", () => resolve4(false));
52377
+ srv.listen(port, host, () => srv.close(() => resolve4(true)));
52378
+ });
52272
52379
  }
52273
52380
 
52274
52381
  // bake.ts
@@ -52343,16 +52450,16 @@ function buildPreview(m, sourceKind, sourceRef, stagedRef) {
52343
52450
  }
52344
52451
 
52345
52452
  // graft-manifest-reader.ts
52346
- var import_node_fs7 = require("node:fs");
52347
- var import_node_path6 = require("node:path");
52453
+ var import_node_fs8 = require("node:fs");
52454
+ var import_node_path7 = require("node:path");
52348
52455
  var import_yaml3 = __toESM(require_dist6(), 1);
52349
52456
  var asRecord2 = (v) => v && typeof v === "object" && !Array.isArray(v) ? v : {};
52350
52457
  function readStagedManifest(agentDir) {
52351
- const manifestPath = (0, import_node_path6.join)(agentDir, "manifest.yaml");
52352
- if (!(0, import_node_fs7.existsSync)(manifestPath)) return null;
52458
+ const manifestPath = (0, import_node_path7.join)(agentDir, "manifest.yaml");
52459
+ if (!(0, import_node_fs8.existsSync)(manifestPath)) return null;
52353
52460
  let doc;
52354
52461
  try {
52355
- doc = asRecord2((0, import_yaml3.parse)((0, import_node_fs7.readFileSync)(manifestPath, "utf8")));
52462
+ doc = asRecord2((0, import_yaml3.parse)((0, import_node_fs8.readFileSync)(manifestPath, "utf8")));
52356
52463
  } catch {
52357
52464
  return null;
52358
52465
  }
@@ -52382,10 +52489,10 @@ function readStagedManifest(agentDir) {
52382
52489
  }
52383
52490
  let skillCount = Array.isArray(doc.skills) ? doc.skills.length : 0;
52384
52491
  if (!skillCount) {
52385
- const skillsDir = (0, import_node_path6.join)(agentDir, "skills");
52386
- if ((0, import_node_fs7.existsSync)(skillsDir)) {
52492
+ const skillsDir = (0, import_node_path7.join)(agentDir, "skills");
52493
+ if ((0, import_node_fs8.existsSync)(skillsDir)) {
52387
52494
  try {
52388
- skillCount = (0, import_node_fs7.readdirSync)(skillsDir).filter((f) => f.endsWith(".md")).length;
52495
+ skillCount = (0, import_node_fs8.readdirSync)(skillsDir).filter((f) => f.endsWith(".md")).length;
52389
52496
  } catch {
52390
52497
  }
52391
52498
  }
@@ -52399,7 +52506,7 @@ function readStagedManifest(agentDir) {
52399
52506
  }
52400
52507
 
52401
52508
  // graft-stage-registry.ts
52402
- var import_node_fs8 = require("node:fs");
52509
+ var import_node_fs9 = require("node:fs");
52403
52510
  var TTL_MS = 30 * 60 * 1e3;
52404
52511
  var registry = /* @__PURE__ */ new Map();
52405
52512
  function registerStage(token, tempDir, agentId) {
@@ -52421,7 +52528,7 @@ function evict(token) {
52421
52528
  clearTimeout(e.timer);
52422
52529
  registry.delete(token);
52423
52530
  try {
52424
- (0, import_node_fs8.rmSync)(e.tempDir, { recursive: true, force: true });
52531
+ (0, import_node_fs9.rmSync)(e.tempDir, { recursive: true, force: true });
52425
52532
  } catch {
52426
52533
  }
52427
52534
  }
@@ -52430,8 +52537,8 @@ function clearAllStages() {
52430
52537
  }
52431
52538
 
52432
52539
  // graft-commit.ts
52433
- var import_node_fs9 = require("node:fs");
52434
- var import_node_path7 = require("node:path");
52540
+ var import_node_fs10 = require("node:fs");
52541
+ var import_node_path8 = require("node:path");
52435
52542
  var GraftCommitError = class extends Error {
52436
52543
  constructor(message, code) {
52437
52544
  super(message);
@@ -52441,34 +52548,34 @@ var GraftCommitError = class extends Error {
52441
52548
  code;
52442
52549
  };
52443
52550
  function commitStaged(tempDir, agentId, targetAgentsDir, force) {
52444
- const staged = (0, import_node_path7.join)(tempDir, "agents", agentId);
52445
- const target = (0, import_node_path7.join)(targetAgentsDir, agentId);
52446
- if ((0, import_node_fs9.existsSync)(target)) {
52551
+ const staged = (0, import_node_path8.join)(tempDir, "agents", agentId);
52552
+ const target = (0, import_node_path8.join)(targetAgentsDir, agentId);
52553
+ if ((0, import_node_fs10.existsSync)(target)) {
52447
52554
  if (!force) throw new GraftCommitError(`an agent named "${agentId}" is already installed`, "collision");
52448
- (0, import_node_fs9.rmSync)(target, { recursive: true, force: true });
52555
+ (0, import_node_fs10.rmSync)(target, { recursive: true, force: true });
52449
52556
  }
52450
- (0, import_node_fs9.mkdirSync)(targetAgentsDir, { recursive: true });
52557
+ (0, import_node_fs10.mkdirSync)(targetAgentsDir, { recursive: true });
52451
52558
  try {
52452
- (0, import_node_fs9.renameSync)(staged, target);
52559
+ (0, import_node_fs10.renameSync)(staged, target);
52453
52560
  } catch {
52454
- (0, import_node_fs9.cpSync)(staged, target, { recursive: true });
52561
+ (0, import_node_fs10.cpSync)(staged, target, { recursive: true });
52455
52562
  }
52456
- (0, import_node_fs9.rmSync)(tempDir, { recursive: true, force: true });
52563
+ (0, import_node_fs10.rmSync)(tempDir, { recursive: true, force: true });
52457
52564
  return { agentId };
52458
52565
  }
52459
52566
  function matchAssemblies(globOrDir) {
52460
52567
  let dir;
52461
52568
  let pattern;
52462
- if ((0, import_node_fs9.existsSync)(globOrDir) && (0, import_node_fs9.statSync)(globOrDir).isDirectory()) {
52569
+ if ((0, import_node_fs10.existsSync)(globOrDir) && (0, import_node_fs10.statSync)(globOrDir).isDirectory()) {
52463
52570
  dir = globOrDir;
52464
52571
  pattern = "*.dll";
52465
52572
  } else {
52466
- dir = (0, import_node_path7.dirname)(globOrDir);
52467
- pattern = (0, import_node_path7.basename)(globOrDir);
52573
+ dir = (0, import_node_path8.dirname)(globOrDir);
52574
+ pattern = (0, import_node_path8.basename)(globOrDir);
52468
52575
  }
52469
- if (!dir || !(0, import_node_fs9.existsSync)(dir) || !(0, import_node_fs9.statSync)(dir).isDirectory()) return [];
52576
+ if (!dir || !(0, import_node_fs10.existsSync)(dir) || !(0, import_node_fs10.statSync)(dir).isDirectory()) return [];
52470
52577
  const re = globToRegExp(pattern);
52471
- return (0, import_node_fs9.readdirSync)(dir).filter((f) => re.test(f)).sort();
52578
+ return (0, import_node_fs10.readdirSync)(dir).filter((f) => re.test(f)).sort();
52472
52579
  }
52473
52580
  function globToRegExp(p) {
52474
52581
  const esc = p.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".");
@@ -52477,24 +52584,24 @@ function globToRegExp(p) {
52477
52584
 
52478
52585
  // floless-store.ts
52479
52586
  var import_node_crypto3 = require("node:crypto");
52480
- var import_node_fs10 = require("node:fs");
52481
- var import_node_os6 = require("node:os");
52482
- var import_node_path8 = require("node:path");
52483
- var ROOT = process.env.FLOLESS_HOME ?? (0, import_node_path8.join)((0, import_node_os6.homedir)(), ".floless");
52484
- var TEMPLATES_FILE = (0, import_node_path8.join)(ROOT, "templates.json");
52485
- var REQUESTS_DIR = (0, import_node_path8.join)(ROOT, "requests");
52587
+ var import_node_fs11 = require("node:fs");
52588
+ var import_node_os7 = require("node:os");
52589
+ var import_node_path9 = require("node:path");
52590
+ var ROOT = process.env.FLOLESS_HOME ?? (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".floless");
52591
+ var TEMPLATES_FILE = (0, import_node_path9.join)(ROOT, "templates.json");
52592
+ var REQUESTS_DIR = (0, import_node_path9.join)(ROOT, "requests");
52486
52593
  function ensureRoot() {
52487
- if (!(0, import_node_fs10.existsSync)(ROOT)) (0, import_node_fs10.mkdirSync)(ROOT, { recursive: true });
52594
+ if (!(0, import_node_fs11.existsSync)(ROOT)) (0, import_node_fs11.mkdirSync)(ROOT, { recursive: true });
52488
52595
  }
52489
52596
  function withinRequestsDir(p) {
52490
- const base = (0, import_node_path8.resolve)(REQUESTS_DIR);
52491
- const full = (0, import_node_path8.resolve)(p);
52492
- return full === base || full.startsWith(base + import_node_path8.sep);
52597
+ const base = (0, import_node_path9.resolve)(REQUESTS_DIR);
52598
+ const full = (0, import_node_path9.resolve)(p);
52599
+ return full === base || full.startsWith(base + import_node_path9.sep);
52493
52600
  }
52494
52601
  function listTemplates() {
52495
- if (!(0, import_node_fs10.existsSync)(TEMPLATES_FILE)) return [];
52602
+ if (!(0, import_node_fs11.existsSync)(TEMPLATES_FILE)) return [];
52496
52603
  try {
52497
- const parsed = JSON.parse((0, import_node_fs10.readFileSync)(TEMPLATES_FILE, "utf8"));
52604
+ const parsed = JSON.parse((0, import_node_fs11.readFileSync)(TEMPLATES_FILE, "utf8"));
52498
52605
  return Array.isArray(parsed) ? parsed : [];
52499
52606
  } catch {
52500
52607
  return [];
@@ -52503,8 +52610,8 @@ function listTemplates() {
52503
52610
  function writeTemplates(list) {
52504
52611
  ensureRoot();
52505
52612
  const tmp = `${TEMPLATES_FILE}.${process.pid}.tmp`;
52506
- (0, import_node_fs10.writeFileSync)(tmp, JSON.stringify(list, null, 2));
52507
- (0, import_node_fs10.renameSync)(tmp, TEMPLATES_FILE);
52613
+ (0, import_node_fs11.writeFileSync)(tmp, JSON.stringify(list, null, 2));
52614
+ (0, import_node_fs11.renameSync)(tmp, TEMPLATES_FILE);
52508
52615
  }
52509
52616
  function addTemplate(input) {
52510
52617
  const tpl = {
@@ -52532,13 +52639,13 @@ function getTemplate(id) {
52532
52639
  }
52533
52640
  function addRequest(req, decoded = []) {
52534
52641
  ensureRoot();
52535
- if (!(0, import_node_fs10.existsSync)(REQUESTS_DIR)) (0, import_node_fs10.mkdirSync)(REQUESTS_DIR, { recursive: true });
52642
+ if (!(0, import_node_fs11.existsSync)(REQUESTS_DIR)) (0, import_node_fs11.mkdirSync)(REQUESTS_DIR, { recursive: true });
52536
52643
  const id = (0, import_node_crypto3.randomUUID)();
52537
52644
  const createdAt = (/* @__PURE__ */ new Date()).toISOString();
52538
52645
  const base = `${createdAt.replace(/[:.]/g, "-")}__${id}`;
52539
52646
  const snapshots = decoded.map((d, i) => {
52540
- const p = (0, import_node_path8.join)(REQUESTS_DIR, `${base}__snap${i + 1}.${d.ext}`);
52541
- (0, import_node_fs10.writeFileSync)(p, d.buf);
52647
+ const p = (0, import_node_path9.join)(REQUESTS_DIR, `${base}__snap${i + 1}.${d.ext}`);
52648
+ (0, import_node_fs11.writeFileSync)(p, d.buf);
52542
52649
  return p;
52543
52650
  });
52544
52651
  const full = {
@@ -52548,55 +52655,55 @@ function addRequest(req, decoded = []) {
52548
52655
  ...req,
52549
52656
  ...snapshots.length ? { snapshots } : {}
52550
52657
  };
52551
- (0, import_node_fs10.writeFileSync)((0, import_node_path8.join)(REQUESTS_DIR, `${base}.json`), JSON.stringify(full, null, 2));
52658
+ (0, import_node_fs11.writeFileSync)((0, import_node_path9.join)(REQUESTS_DIR, `${base}.json`), JSON.stringify(full, null, 2));
52552
52659
  return full;
52553
52660
  }
52554
52661
  function listRequests() {
52555
- if (!(0, import_node_fs10.existsSync)(REQUESTS_DIR)) return [];
52556
- return (0, import_node_fs10.readdirSync)(REQUESTS_DIR).filter((f) => f.endsWith(".json")).sort().map((f) => {
52662
+ if (!(0, import_node_fs11.existsSync)(REQUESTS_DIR)) return [];
52663
+ return (0, import_node_fs11.readdirSync)(REQUESTS_DIR).filter((f) => f.endsWith(".json")).sort().map((f) => {
52557
52664
  try {
52558
- return JSON.parse((0, import_node_fs10.readFileSync)((0, import_node_path8.join)(REQUESTS_DIR, f), "utf8"));
52665
+ return JSON.parse((0, import_node_fs11.readFileSync)((0, import_node_path9.join)(REQUESTS_DIR, f), "utf8"));
52559
52666
  } catch {
52560
52667
  return null;
52561
52668
  }
52562
52669
  }).filter((r) => r !== null);
52563
52670
  }
52564
52671
  function deleteRequest(id) {
52565
- if (!(0, import_node_fs10.existsSync)(REQUESTS_DIR)) return false;
52566
- const file = (0, import_node_fs10.readdirSync)(REQUESTS_DIR).find((f) => f.endsWith(`__${id}.json`));
52672
+ if (!(0, import_node_fs11.existsSync)(REQUESTS_DIR)) return false;
52673
+ const file = (0, import_node_fs11.readdirSync)(REQUESTS_DIR).find((f) => f.endsWith(`__${id}.json`));
52567
52674
  if (!file) return false;
52568
52675
  try {
52569
- const parsed = JSON.parse((0, import_node_fs10.readFileSync)((0, import_node_path8.join)(REQUESTS_DIR, file), "utf8"));
52676
+ const parsed = JSON.parse((0, import_node_fs11.readFileSync)((0, import_node_path9.join)(REQUESTS_DIR, file), "utf8"));
52570
52677
  for (const p of parsed.snapshots ?? []) {
52571
52678
  if (!withinRequestsDir(p)) continue;
52572
52679
  try {
52573
- (0, import_node_fs10.rmSync)(p);
52680
+ (0, import_node_fs11.rmSync)(p);
52574
52681
  } catch {
52575
52682
  }
52576
52683
  }
52577
52684
  } catch {
52578
52685
  }
52579
- (0, import_node_fs10.rmSync)((0, import_node_path8.join)(REQUESTS_DIR, file));
52686
+ (0, import_node_fs11.rmSync)((0, import_node_path9.join)(REQUESTS_DIR, file));
52580
52687
  return true;
52581
52688
  }
52582
52689
  function clearRequests() {
52583
- if (!(0, import_node_fs10.existsSync)(REQUESTS_DIR)) return 0;
52584
- const allFiles = (0, import_node_fs10.readdirSync)(REQUESTS_DIR);
52690
+ if (!(0, import_node_fs11.existsSync)(REQUESTS_DIR)) return 0;
52691
+ const allFiles = (0, import_node_fs11.readdirSync)(REQUESTS_DIR);
52585
52692
  const jsonFiles = allFiles.filter((f) => f.endsWith(".json"));
52586
52693
  for (const f of allFiles) {
52587
52694
  try {
52588
- (0, import_node_fs10.rmSync)((0, import_node_path8.join)(REQUESTS_DIR, f));
52695
+ (0, import_node_fs11.rmSync)((0, import_node_path9.join)(REQUESTS_DIR, f));
52589
52696
  } catch {
52590
52697
  }
52591
52698
  }
52592
52699
  return jsonFiles.length;
52593
52700
  }
52594
52701
  function snapshotPathFor(id, n) {
52595
- if (!(0, import_node_fs10.existsSync)(REQUESTS_DIR)) return null;
52596
- const file = (0, import_node_fs10.readdirSync)(REQUESTS_DIR).find((f) => f.endsWith(`__${id}.json`));
52702
+ if (!(0, import_node_fs11.existsSync)(REQUESTS_DIR)) return null;
52703
+ const file = (0, import_node_fs11.readdirSync)(REQUESTS_DIR).find((f) => f.endsWith(`__${id}.json`));
52597
52704
  if (!file) return null;
52598
52705
  try {
52599
- const parsed = JSON.parse((0, import_node_fs10.readFileSync)((0, import_node_path8.join)(REQUESTS_DIR, file), "utf8"));
52706
+ const parsed = JSON.parse((0, import_node_fs11.readFileSync)((0, import_node_path9.join)(REQUESTS_DIR, file), "utf8"));
52600
52707
  const cand = parsed.snapshots?.[n] ?? null;
52601
52708
  return cand && withinRequestsDir(cand) ? cand : null;
52602
52709
  } catch {
@@ -52630,8 +52737,8 @@ function decodeSnapshots(inputs) {
52630
52737
  }
52631
52738
 
52632
52739
  // routines.ts
52633
- var import_node_fs12 = require("node:fs");
52634
- var import_node_path10 = require("node:path");
52740
+ var import_node_fs13 = require("node:fs");
52741
+ var import_node_path11 = require("node:path");
52635
52742
 
52636
52743
  // sse.ts
52637
52744
  var clients = /* @__PURE__ */ new Set();
@@ -52668,11 +52775,11 @@ function clientCount() {
52668
52775
  }
52669
52776
 
52670
52777
  // trigger-sessions.ts
52671
- var import_node_fs11 = require("node:fs");
52672
- var import_node_os7 = require("node:os");
52673
- var import_node_path9 = require("node:path");
52778
+ var import_node_fs12 = require("node:fs");
52779
+ var import_node_os8 = require("node:os");
52780
+ var import_node_path10 = require("node:path");
52674
52781
  var import_yaml4 = __toESM(require_dist6(), 1);
52675
- var AGENTS_DIR2 = process.env.AWARE_HOME ? (0, import_node_path9.join)(process.env.AWARE_HOME, "agents") : (0, import_node_path9.join)((0, import_node_os7.homedir)(), ".aware", "agents");
52782
+ 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");
52676
52783
  function summarizeFire(data) {
52677
52784
  if (!data) return "event";
52678
52785
  const type = typeof data.type === "string" ? data.type : "";
@@ -52689,10 +52796,10 @@ function mapTriggerState(phase) {
52689
52796
  function isHostBacked(agent, agentsDir = AGENTS_DIR2) {
52690
52797
  const safe = (n) => !n.includes("/") && !n.includes("\\") && !n.includes("..");
52691
52798
  if (!safe(agent)) return false;
52692
- const manifestPath = (0, import_node_path9.join)(agentsDir, agent, "manifest.yaml");
52693
- if (!(0, import_node_fs11.existsSync)(manifestPath)) return false;
52799
+ const manifestPath = (0, import_node_path10.join)(agentsDir, agent, "manifest.yaml");
52800
+ if (!(0, import_node_fs12.existsSync)(manifestPath)) return false;
52694
52801
  try {
52695
- const doc = (0, import_yaml4.parse)((0, import_node_fs11.readFileSync)(manifestPath, "utf8"));
52802
+ const doc = (0, import_yaml4.parse)((0, import_node_fs12.readFileSync)(manifestPath, "utf8"));
52696
52803
  const transport = doc?.transport;
52697
52804
  return !!(transport && typeof transport === "object" && "cli" in transport);
52698
52805
  } catch {
@@ -52951,7 +53058,7 @@ var RoutineError = class extends Error {
52951
53058
  }
52952
53059
  status;
52953
53060
  };
52954
- var ROUTINES_FILE = (0, import_node_path10.join)(flolessRoot, "routines.json");
53061
+ var ROUTINES_FILE = (0, import_node_path11.join)(flolessRoot, "routines.json");
52955
53062
  var routines = [];
52956
53063
  var loaded = false;
52957
53064
  function ensureLoaded() {
@@ -52987,10 +53094,10 @@ function sanitizeRoutine(raw) {
52987
53094
  };
52988
53095
  }
52989
53096
  function loadFromDisk() {
52990
- if (!(0, import_node_fs12.existsSync)(ROUTINES_FILE)) return [];
53097
+ if (!(0, import_node_fs13.existsSync)(ROUTINES_FILE)) return [];
52991
53098
  let text;
52992
53099
  try {
52993
- text = (0, import_node_fs12.readFileSync)(ROUTINES_FILE, "utf8");
53100
+ text = (0, import_node_fs13.readFileSync)(ROUTINES_FILE, "utf8");
52994
53101
  } catch {
52995
53102
  return [];
52996
53103
  }
@@ -52999,17 +53106,17 @@ function loadFromDisk() {
52999
53106
  return Array.isArray(parsed) ? parsed.map(sanitizeRoutine).filter((r) => r !== null) : [];
53000
53107
  } catch {
53001
53108
  try {
53002
- (0, import_node_fs12.renameSync)(ROUTINES_FILE, `${ROUTINES_FILE}.corrupt-${Date.now()}`);
53109
+ (0, import_node_fs13.renameSync)(ROUTINES_FILE, `${ROUTINES_FILE}.corrupt-${Date.now()}`);
53003
53110
  } catch {
53004
53111
  }
53005
53112
  return [];
53006
53113
  }
53007
53114
  }
53008
53115
  function saveRoutines() {
53009
- if (!(0, import_node_fs12.existsSync)(flolessRoot)) (0, import_node_fs12.mkdirSync)(flolessRoot, { recursive: true });
53116
+ if (!(0, import_node_fs13.existsSync)(flolessRoot)) (0, import_node_fs13.mkdirSync)(flolessRoot, { recursive: true });
53010
53117
  const tmp = `${ROUTINES_FILE}.${process.pid}.tmp`;
53011
- (0, import_node_fs12.writeFileSync)(tmp, JSON.stringify(routines, null, 2));
53012
- (0, import_node_fs12.renameSync)(tmp, ROUTINES_FILE);
53118
+ (0, import_node_fs13.writeFileSync)(tmp, JSON.stringify(routines, null, 2));
53119
+ (0, import_node_fs13.renameSync)(tmp, ROUTINES_FILE);
53013
53120
  }
53014
53121
  function listRoutines() {
53015
53122
  ensureLoaded();
@@ -53399,9 +53506,9 @@ function isGatedAwareRoute(url, method) {
53399
53506
 
53400
53507
  // autostart.mjs
53401
53508
  var import_node_child_process3 = require("node:child_process");
53402
- var import_node_fs13 = require("node:fs");
53403
- var import_node_os8 = require("node:os");
53404
- var import_node_path11 = require("node:path");
53509
+ var import_node_fs14 = require("node:fs");
53510
+ var import_node_os9 = require("node:os");
53511
+ var import_node_path12 = require("node:path");
53405
53512
 
53406
53513
  // teardown.mjs
53407
53514
  var RUN_KEY = "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run";
@@ -53513,8 +53620,8 @@ function removeLegacyRunKey() {
53513
53620
  }
53514
53621
  function logLine(msg) {
53515
53622
  try {
53516
- (0, import_node_fs13.mkdirSync)(logDir(), { recursive: true });
53517
- (0, import_node_fs13.appendFileSync)(logFilePath(), `${(/* @__PURE__ */ new Date()).toISOString()} ${msg}
53623
+ (0, import_node_fs14.mkdirSync)(logDir(), { recursive: true });
53624
+ (0, import_node_fs14.appendFileSync)(logFilePath(), `${(/* @__PURE__ */ new Date()).toISOString()} ${msg}
53518
53625
  `);
53519
53626
  } catch {
53520
53627
  }
@@ -53522,8 +53629,8 @@ function logLine(msg) {
53522
53629
  function registerAutostart(exePath) {
53523
53630
  if (!isWin) return;
53524
53631
  const xml = buildAutostartTaskXml(exePath, currentUserId());
53525
- const tmp = (0, import_node_path11.join)((0, import_node_os8.tmpdir)(), `floless-autostart-${process.pid}-${Date.now()}.xml`);
53526
- (0, import_node_fs13.writeFileSync)(tmp, "\uFEFF" + xml, { encoding: "utf16le" });
53632
+ const tmp = (0, import_node_path12.join)((0, import_node_os9.tmpdir)(), `floless-autostart-${process.pid}-${Date.now()}.xml`);
53633
+ (0, import_node_fs14.writeFileSync)(tmp, "\uFEFF" + xml, { encoding: "utf16le" });
53527
53634
  try {
53528
53635
  (0, import_node_child_process3.execFileSync)("schtasks", ["/Create", "/TN", TASK_NAME, "/XML", tmp, "/F"], {
53529
53636
  stdio: ["ignore", "ignore", "ignore"],
@@ -53534,7 +53641,7 @@ function registerAutostart(exePath) {
53534
53641
  throw err;
53535
53642
  } finally {
53536
53643
  try {
53537
- (0, import_node_fs13.rmSync)(tmp, { force: true });
53644
+ (0, import_node_fs14.rmSync)(tmp, { force: true });
53538
53645
  } catch {
53539
53646
  }
53540
53647
  }
@@ -53569,10 +53676,10 @@ function unregisterAutostart() {
53569
53676
  // updater.ts
53570
53677
  var import_node_child_process4 = require("node:child_process");
53571
53678
  var import_node_crypto4 = require("node:crypto");
53572
- var import_node_fs14 = require("node:fs");
53679
+ var import_node_fs15 = require("node:fs");
53573
53680
  var import_node_stream = require("node:stream");
53574
53681
  var import_promises = require("node:stream/promises");
53575
- var import_node_path12 = require("node:path");
53682
+ var import_node_path13 = require("node:path");
53576
53683
  var CHANNEL = "win";
53577
53684
  var FEED_TIMEOUT_MS = 15e3;
53578
53685
  var DOWNLOAD_TIMEOUT_MS = 3e5;
@@ -53581,13 +53688,13 @@ function currentVersion() {
53581
53688
  return appVersion();
53582
53689
  }
53583
53690
  function installRoot() {
53584
- return (0, import_node_path12.dirname)((0, import_node_path12.dirname)(process.execPath));
53691
+ return (0, import_node_path13.dirname)((0, import_node_path13.dirname)(process.execPath));
53585
53692
  }
53586
53693
  function updateExePath() {
53587
- return (0, import_node_path12.join)(installRoot(), "Update.exe");
53694
+ return (0, import_node_path13.join)(installRoot(), "Update.exe");
53588
53695
  }
53589
53696
  function packagesDir() {
53590
- return (0, import_node_path12.join)(installRoot(), "packages");
53697
+ return (0, import_node_path13.join)(installRoot(), "packages");
53591
53698
  }
53592
53699
  function feedUrl() {
53593
53700
  const env2 = (process.env.FLOLESS_UPDATE_URL ?? "").trim().replace(/\/+$/, "");
@@ -53692,22 +53799,22 @@ async function checkForUpdate() {
53692
53799
  }
53693
53800
  async function sha1OfFile(path) {
53694
53801
  const hash = (0, import_node_crypto4.createHash)("sha1");
53695
- await (0, import_promises.pipeline)((0, import_node_fs14.createReadStream)(path), hash);
53802
+ await (0, import_promises.pipeline)((0, import_node_fs15.createReadStream)(path), hash);
53696
53803
  return hash.digest("hex").toUpperCase();
53697
53804
  }
53698
53805
  async function downloadPackage(asset) {
53699
53806
  if (!NUPKG_NAME.test(asset.FileName)) throw new Error(`refusing suspicious package name: ${asset.FileName}`);
53700
53807
  const want = asset.SHA1.toUpperCase();
53701
53808
  const dir = packagesDir();
53702
- (0, import_node_fs14.mkdirSync)(dir, { recursive: true });
53703
- const dest = (0, import_node_path12.join)(dir, asset.FileName);
53704
- if ((0, import_node_fs14.existsSync)(dest) && await sha1OfFile(dest) === want) return dest;
53809
+ (0, import_node_fs15.mkdirSync)(dir, { recursive: true });
53810
+ const dest = (0, import_node_path13.join)(dir, asset.FileName);
53811
+ if ((0, import_node_fs15.existsSync)(dest) && await sha1OfFile(dest) === want) return dest;
53705
53812
  const res = await authedFetch(`${feedUrl()}/${encodeURIComponent(asset.FileName)}`, {
53706
53813
  redirect: "follow",
53707
53814
  signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS)
53708
53815
  });
53709
53816
  if (!res.ok || !res.body) throw new Error(`download failed: HTTP ${res.status} for ${asset.FileName}`);
53710
- await (0, import_promises.pipeline)(import_node_stream.Readable.fromWeb(res.body), (0, import_node_fs14.createWriteStream)(dest));
53817
+ await (0, import_promises.pipeline)(import_node_stream.Readable.fromWeb(res.body), (0, import_node_fs15.createWriteStream)(dest));
53711
53818
  const got = await sha1OfFile(dest);
53712
53819
  if (got !== want) throw new Error(`SHA1 mismatch for ${asset.FileName}: feed=${want} got=${got}`);
53713
53820
  return dest;
@@ -53716,7 +53823,7 @@ async function applyUpdate(check, opts) {
53716
53823
  if (!check.supported) return { applied: false, message: check.reason ?? "auto-update not supported in this runtime" };
53717
53824
  if (!check.updateAvailable || !check.asset) return { applied: false, message: check.reason ?? "no update available" };
53718
53825
  const exe = updateExePath();
53719
- if (!(0, import_node_fs14.existsSync)(exe)) {
53826
+ if (!(0, import_node_fs15.existsSync)(exe)) {
53720
53827
  return { applied: false, message: `Update.exe not found at ${exe} \u2014 is this a Velopack install?` };
53721
53828
  }
53722
53829
  const pkg = await downloadPackage(check.asset);
@@ -53739,12 +53846,12 @@ async function applyUpdate(check, opts) {
53739
53846
 
53740
53847
  // launch.mjs
53741
53848
  var import_node_child_process5 = require("node:child_process");
53742
- var import_node_path13 = require("node:path");
53849
+ var import_node_path14 = require("node:path");
53743
53850
  var import_node_url = require("node:url");
53744
- var import_node_fs15 = require("node:fs");
53851
+ var import_node_fs16 = require("node:fs");
53745
53852
  var import_node_http = __toESM(require("node:http"), 1);
53746
53853
  var import_node_readline = require("node:readline");
53747
- var __dirname2 = (0, import_node_path13.dirname)((0, import_node_url.fileURLToPath)(__import_meta_url));
53854
+ var __dirname2 = (0, import_node_path14.dirname)((0, import_node_url.fileURLToPath)(__import_meta_url));
53748
53855
  var PORT = Number(process.env.PORT ?? 4317);
53749
53856
  var HEALTH_URL = `http://127.0.0.1:${PORT}/api/health`;
53750
53857
  var BROWSER_URL = `http://floless.localhost:${PORT}`;
@@ -53816,8 +53923,8 @@ async function waitHealthy(timeoutMs = 3e4) {
53816
53923
  function resolveServerStart() {
53817
53924
  const packaged = /flolessapp\.exe$/i.test(process.execPath);
53818
53925
  if (packaged) return { cmd: process.execPath, args: ["--serve"], shell: false };
53819
- const bundle = (0, import_node_path13.join)(__dirname2, "dist", "floless-server.cjs");
53820
- if ((0, import_node_fs15.existsSync)(bundle)) return { cmd: process.execPath, args: [bundle, "--serve"], shell: false };
53926
+ const bundle = (0, import_node_path14.join)(__dirname2, "dist", "floless-server.cjs");
53927
+ if ((0, import_node_fs16.existsSync)(bundle)) return { cmd: process.execPath, args: [bundle, "--serve"], shell: false };
53821
53928
  return { cmd: "npm", args: ["run", "start"], shell: isWin2 };
53822
53929
  }
53823
53930
  function startServerDetached() {
@@ -53965,8 +54072,8 @@ function taskkillArgs(pid, { tree = true } = {}) {
53965
54072
  }
53966
54073
  function killSupervisor({ tree = true } = {}) {
53967
54074
  if (!isWin2) return;
53968
- const isNpmChannel = /^node(\.exe)?$/i.test((0, import_node_path13.basename)(process.execPath));
53969
- const scriptMatch = isNpmChannel ? (0, import_node_path13.basename)((0, import_node_url.fileURLToPath)(__import_meta_url)) : void 0;
54075
+ const isNpmChannel = /^node(\.exe)?$/i.test((0, import_node_path14.basename)(process.execPath));
54076
+ const scriptMatch = isNpmChannel ? (0, import_node_path14.basename)((0, import_node_url.fileURLToPath)(__import_meta_url)) : void 0;
53970
54077
  const realExe = resolveRealInstallExe(process.execPath);
53971
54078
  const exeMatch = realExe === process.execPath ? process.execPath : [process.execPath, realExe];
53972
54079
  const pids = supervisorPidsToKill(enumerateProcesses(), process.pid, exeMatch, scriptMatch);
@@ -54131,7 +54238,7 @@ async function runAction(arg, flagArgv = [], selfVersion = null) {
54131
54238
  }
54132
54239
  await action(parseTeardownFlags(flagArgv));
54133
54240
  }
54134
- var entry = (0, import_node_path13.basename)(process.argv[1] ?? "").toLowerCase();
54241
+ var entry = (0, import_node_path14.basename)(process.argv[1] ?? "").toLowerCase();
54135
54242
  if (entry === "launch.mjs") {
54136
54243
  runAction(process.argv[2], process.argv.slice(3)).catch((e) => {
54137
54244
  log(`error: ${e?.message ?? e}`);
@@ -54205,9 +54312,9 @@ function awareUpgradeBlockReason(s) {
54205
54312
  }
54206
54313
 
54207
54314
  // skill-sync.ts
54208
- var import_node_fs16 = require("node:fs");
54209
- var import_node_os9 = require("node:os");
54210
- var import_node_path14 = require("node:path");
54315
+ var import_node_fs17 = require("node:fs");
54316
+ var import_node_os10 = require("node:os");
54317
+ var import_node_path15 = require("node:path");
54211
54318
  var import_node_url2 = require("node:url");
54212
54319
  var import_yaml5 = __toESM(require_dist6(), 1);
54213
54320
 
@@ -54228,30 +54335,30 @@ function selectShippedSkillNames(names) {
54228
54335
  }
54229
54336
 
54230
54337
  // skill-sync.ts
54231
- var __dirname3 = (0, import_node_path14.dirname)((0, import_node_url2.fileURLToPath)(__import_meta_url));
54338
+ var __dirname3 = (0, import_node_path15.dirname)((0, import_node_url2.fileURLToPath)(__import_meta_url));
54232
54339
  function bundledSkillsRoot() {
54233
54340
  const candidates = [
54234
- (0, import_node_path14.join)(__dirname3, "skills"),
54235
- (0, import_node_path14.join)((0, import_node_path14.dirname)(process.execPath), "skills"),
54236
- (0, import_node_path14.join)(__dirname3, "..", ".claude", "skills")
54341
+ (0, import_node_path15.join)(__dirname3, "skills"),
54342
+ (0, import_node_path15.join)((0, import_node_path15.dirname)(process.execPath), "skills"),
54343
+ (0, import_node_path15.join)(__dirname3, "..", ".claude", "skills")
54237
54344
  ];
54238
- return candidates.find((p) => (0, import_node_fs16.existsSync)(p)) ?? null;
54345
+ return candidates.find((p) => (0, import_node_fs17.existsSync)(p)) ?? null;
54239
54346
  }
54240
54347
  function targetConfigDirs() {
54241
54348
  const override = process.env.FLOLESS_SKILL_TARGETS;
54242
54349
  if (override) {
54243
54350
  return override.split(";").map((d) => d.trim()).filter(Boolean).map((dir) => ({ runtime: "custom", dir }));
54244
54351
  }
54245
- const home = (0, import_node_os9.homedir)();
54352
+ const home = (0, import_node_os10.homedir)();
54246
54353
  return [
54247
- { runtime: "claude", dir: (0, import_node_path14.join)(home, ".claude") },
54248
- { runtime: "codex", dir: (0, import_node_path14.join)(home, ".codex") },
54249
- { runtime: "opencode", dir: (0, import_node_path14.join)(home, ".opencode") }
54354
+ { runtime: "claude", dir: (0, import_node_path15.join)(home, ".claude") },
54355
+ { runtime: "codex", dir: (0, import_node_path15.join)(home, ".codex") },
54356
+ { runtime: "opencode", dir: (0, import_node_path15.join)(home, ".opencode") }
54250
54357
  ];
54251
54358
  }
54252
54359
  function skillVersion(skillMdPath) {
54253
54360
  try {
54254
- const text = (0, import_node_fs16.readFileSync)(skillMdPath, "utf8");
54361
+ const text = (0, import_node_fs17.readFileSync)(skillMdPath, "utf8");
54255
54362
  const m = /^---\r?\n([\s\S]*?)\r?\n---/.exec(text);
54256
54363
  if (!m || m[1] === void 0) return null;
54257
54364
  const fm = (0, import_yaml5.parse)(m[1]);
@@ -54291,21 +54398,21 @@ function decideAction(installed, bundled) {
54291
54398
  function bundledSkills(root) {
54292
54399
  let entries = [];
54293
54400
  try {
54294
- entries = selectShippedSkillNames((0, import_node_fs16.readdirSync)(root));
54401
+ entries = selectShippedSkillNames((0, import_node_fs17.readdirSync)(root));
54295
54402
  } catch {
54296
54403
  return [];
54297
54404
  }
54298
54405
  const out = [];
54299
54406
  for (const name of entries) {
54300
- const dir = (0, import_node_path14.join)(root, name);
54407
+ const dir = (0, import_node_path15.join)(root, name);
54301
54408
  let isDir = false;
54302
54409
  try {
54303
- isDir = (0, import_node_fs16.statSync)(dir).isDirectory();
54410
+ isDir = (0, import_node_fs17.statSync)(dir).isDirectory();
54304
54411
  } catch {
54305
54412
  isDir = false;
54306
54413
  }
54307
54414
  if (!isDir) continue;
54308
- const v = skillVersion((0, import_node_path14.join)(dir, "SKILL.md"));
54415
+ const v = skillVersion((0, import_node_path15.join)(dir, "SKILL.md"));
54309
54416
  if (!v) continue;
54310
54417
  out.push({ name, dir, version: v });
54311
54418
  }
@@ -54318,17 +54425,17 @@ function syncSkills() {
54318
54425
  const skills = bundledSkills(root);
54319
54426
  if (!skills.length) return results;
54320
54427
  for (const { runtime, dir: cfg } of targetConfigDirs()) {
54321
- if (!(0, import_node_fs16.existsSync)(cfg)) continue;
54322
- const skillsDir = (0, import_node_path14.join)(cfg, "skills");
54428
+ if (!(0, import_node_fs17.existsSync)(cfg)) continue;
54429
+ const skillsDir = (0, import_node_path15.join)(cfg, "skills");
54323
54430
  for (const s of skills) {
54324
- const dest = (0, import_node_path14.join)(skillsDir, s.name);
54325
- const installedMd = (0, import_node_path14.join)(dest, "SKILL.md");
54326
- const installed = (0, import_node_fs16.existsSync)(installedMd) ? skillVersion(installedMd) : null;
54431
+ const dest = (0, import_node_path15.join)(skillsDir, s.name);
54432
+ const installedMd = (0, import_node_path15.join)(dest, "SKILL.md");
54433
+ const installed = (0, import_node_fs17.existsSync)(installedMd) ? skillVersion(installedMd) : null;
54327
54434
  const action = decideAction(installed, s.version);
54328
54435
  if (action === "installed" || action === "updated") {
54329
54436
  try {
54330
- if (action === "updated") (0, import_node_fs16.rmSync)(dest, { recursive: true, force: true });
54331
- (0, import_node_fs16.cpSync)(s.dir, dest, { recursive: true });
54437
+ if (action === "updated") (0, import_node_fs17.rmSync)(dest, { recursive: true, force: true });
54438
+ (0, import_node_fs17.cpSync)(s.dir, dest, { recursive: true });
54332
54439
  results.push({ runtime, skill: s.name, action, from: installed, to: s.version });
54333
54440
  } catch {
54334
54441
  }
@@ -54341,9 +54448,9 @@ function syncSkills() {
54341
54448
  }
54342
54449
 
54343
54450
  // watch.ts
54344
- var import_node_os10 = require("node:os");
54345
- var import_node_path16 = require("node:path");
54346
- var import_node_fs17 = require("node:fs");
54451
+ var import_node_os11 = require("node:os");
54452
+ var import_node_path17 = require("node:path");
54453
+ var import_node_fs18 = require("node:fs");
54347
54454
 
54348
54455
  // node_modules/chokidar/esm/index.js
54349
54456
  var import_fs2 = require("fs");
@@ -54354,7 +54461,7 @@ var sysPath2 = __toESM(require("path"), 1);
54354
54461
  // node_modules/readdirp/esm/index.js
54355
54462
  var import_promises2 = require("node:fs/promises");
54356
54463
  var import_node_stream2 = require("node:stream");
54357
- var import_node_path15 = require("node:path");
54464
+ var import_node_path16 = require("node:path");
54358
54465
  var EntryTypes = {
54359
54466
  FILE_TYPE: "files",
54360
54467
  DIR_TYPE: "directories",
@@ -54429,7 +54536,7 @@ var ReaddirpStream = class extends import_node_stream2.Readable {
54429
54536
  this._wantsDir = type ? DIR_TYPES.has(type) : false;
54430
54537
  this._wantsFile = type ? FILE_TYPES.has(type) : false;
54431
54538
  this._wantsEverything = type === EntryTypes.EVERYTHING_TYPE;
54432
- this._root = (0, import_node_path15.resolve)(root);
54539
+ this._root = (0, import_node_path16.resolve)(root);
54433
54540
  this._isDirent = !opts.alwaysStat;
54434
54541
  this._statsProp = this._isDirent ? "dirent" : "stats";
54435
54542
  this._rdOptions = { encoding: "utf8", withFileTypes: this._isDirent };
@@ -54500,8 +54607,8 @@ var ReaddirpStream = class extends import_node_stream2.Readable {
54500
54607
  let entry2;
54501
54608
  const basename5 = this._isDirent ? dirent.name : dirent;
54502
54609
  try {
54503
- const fullPath = (0, import_node_path15.resolve)((0, import_node_path15.join)(path, basename5));
54504
- entry2 = { path: (0, import_node_path15.relative)(this._root, fullPath), fullPath, basename: basename5 };
54610
+ const fullPath = (0, import_node_path16.resolve)((0, import_node_path16.join)(path, basename5));
54611
+ entry2 = { path: (0, import_node_path16.relative)(this._root, fullPath), fullPath, basename: basename5 };
54505
54612
  entry2[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
54506
54613
  } catch (err) {
54507
54614
  this._onError(err);
@@ -54535,7 +54642,7 @@ var ReaddirpStream = class extends import_node_stream2.Readable {
54535
54642
  }
54536
54643
  if (entryRealPathStats.isDirectory()) {
54537
54644
  const len = entryRealPath.length;
54538
- if (full.startsWith(entryRealPath) && full.substr(len, 1) === import_node_path15.sep) {
54645
+ if (full.startsWith(entryRealPath) && full.substr(len, 1) === import_node_path16.sep) {
54539
54646
  const recursiveError = new Error(`Circular symlink detected: "${full}" points to "${entryRealPath}"`);
54540
54647
  recursiveError.code = RECURSIVE_ERROR_CODE;
54541
54648
  return this._onError(recursiveError);
@@ -56043,15 +56150,15 @@ function appIdFromLogPath(path) {
56043
56150
  return i >= 0 && parts[i + 1] ? parts[i + 1] : null;
56044
56151
  }
56045
56152
  function startWatcher() {
56046
- const awareDir = process.env.AWARE_HOME ?? (0, import_node_path16.join)((0, import_node_os10.homedir)(), ".aware");
56047
- const credentialsDir = (0, import_node_path16.join)(awareDir, "credentials");
56048
- if (!(0, import_node_fs17.existsSync)(credentialsDir)) {
56153
+ const awareDir = process.env.AWARE_HOME ?? (0, import_node_path17.join)((0, import_node_os11.homedir)(), ".aware");
56154
+ const credentialsDir = (0, import_node_path17.join)(awareDir, "credentials");
56155
+ if (!(0, import_node_fs18.existsSync)(credentialsDir)) {
56049
56156
  try {
56050
- (0, import_node_fs17.mkdirSync)(credentialsDir, { recursive: true });
56157
+ (0, import_node_fs18.mkdirSync)(credentialsDir, { recursive: true });
56051
56158
  } catch {
56052
56159
  }
56053
56160
  }
56054
- const targets = ["apps", "logs", "credentials"].map((d) => (0, import_node_path16.join)(awareDir, d)).filter((p) => (0, import_node_fs17.existsSync)(p));
56161
+ const targets = ["apps", "logs", "credentials"].map((d) => (0, import_node_path17.join)(awareDir, d)).filter((p) => (0, import_node_fs18.existsSync)(p));
56055
56162
  if (targets.length === 0) {
56056
56163
  return null;
56057
56164
  }
@@ -56063,11 +56170,11 @@ function startWatcher() {
56063
56170
  const isCredential = path.split(/[\\/]/).includes("credentials");
56064
56171
  const kind = isCredential ? "credential" : path.endsWith(".jsonl") ? "trace" : path.endsWith(".lock") ? "lock" : path.endsWith(".flo") || path.endsWith(".app") ? "source" : "file";
56065
56172
  broadcast({ type: "fs-change", kind, event, path });
56066
- if (kind === "trace" && event !== "unlink" && (0, import_node_fs17.existsSync)(path)) {
56173
+ if (kind === "trace" && event !== "unlink" && (0, import_node_fs18.existsSync)(path)) {
56067
56174
  const id = appIdFromLogPath(path);
56068
56175
  if (!id) return;
56069
56176
  try {
56070
- broadcast({ type: "trace-file", id, runId: path.split(import_node_path16.sep).pop()?.replace(/\.jsonl$/, "") ?? null, events: parseTrace((0, import_node_fs17.readFileSync)(path, "utf8")) });
56177
+ 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")) });
56071
56178
  } catch {
56072
56179
  }
56073
56180
  }
@@ -56076,10 +56183,10 @@ function startWatcher() {
56076
56183
  }
56077
56184
 
56078
56185
  // index.ts
56079
- var __dirname4 = (0, import_node_path17.dirname)((0, import_node_url3.fileURLToPath)(__import_meta_url));
56080
- var WEB_ROOT = [(0, import_node_path17.join)(__dirname4, "web"), (0, import_node_path17.join)((0, import_node_path17.dirname)(process.execPath), "web"), (0, import_node_path17.join)(__dirname4, "..", "web")].find(
56081
- (p) => (0, import_node_fs18.existsSync)(p)
56082
- ) ?? (0, import_node_path17.join)(__dirname4, "..", "web");
56186
+ var __dirname4 = (0, import_node_path18.dirname)((0, import_node_url3.fileURLToPath)(__import_meta_url));
56187
+ 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(
56188
+ (p) => (0, import_node_fs19.existsSync)(p)
56189
+ ) ?? (0, import_node_path18.join)(__dirname4, "..", "web");
56083
56190
  var PORT2 = Number(process.env.PORT ?? 4317);
56084
56191
  var HOST = "127.0.0.1";
56085
56192
  function extractReportHtml(events) {
@@ -56106,7 +56213,7 @@ function installCrashHandlers() {
56106
56213
  ${stack}
56107
56214
  `;
56108
56215
  try {
56109
- (0, import_node_fs18.appendFileSync)(logFilePath(), line);
56216
+ (0, import_node_fs19.appendFileSync)(logFilePath(), line);
56110
56217
  } catch {
56111
56218
  }
56112
56219
  if (process.stderr.isTTY) process.stderr.write(line);
@@ -56322,7 +56429,7 @@ async function startServer() {
56322
56429
  return { ok: true, agent };
56323
56430
  });
56324
56431
  app.get("/api/integrations", async () => {
56325
- const integrations = listIntegrations();
56432
+ let integrations = listIntegrations();
56326
56433
  try {
56327
56434
  const live = await aware.connectList();
56328
56435
  const byId = new Map(live.map((c) => [c.integration, c]));
@@ -56332,6 +56439,7 @@ async function startServer() {
56332
56439
  it.status = c.status === "valid" ? "connected" : c.status === "expired" ? "expired" : "disconnected";
56333
56440
  it.expiresAt = c.expires_in_secs != null ? new Date(Date.now() + c.expires_in_secs * 1e3).toISOString() : it.expiresAt;
56334
56441
  }
56442
+ integrations = mergeConnectables(integrations, live, friendlyIntegrationName);
56335
56443
  } catch (err) {
56336
56444
  app.log.warn({ err: String(err) }, "aware connect --list unavailable; using file-based status");
56337
56445
  }
@@ -56340,6 +56448,11 @@ async function startServer() {
56340
56448
  const DEFAULT_CONNECT_FLOW = {};
56341
56449
  app.post("/api/connect/:id", async (req) => {
56342
56450
  const id = req.params.id;
56451
+ try {
56452
+ ensureManagedProfile(id);
56453
+ } catch (err) {
56454
+ app.log.warn({ id, err: String(err) }, "ensureManagedProfile failed");
56455
+ }
56343
56456
  const requested = req.body?.flow;
56344
56457
  const flow = requested === "device-code" || requested === "oauth" ? requested : DEFAULT_CONNECT_FLOW[id] ?? "oauth";
56345
56458
  if (flow === "device-code") {
@@ -56350,13 +56463,29 @@ async function startServer() {
56350
56463
  });
56351
56464
  return { ok: true, id, flow, prompt };
56352
56465
  }
56466
+ const preset = OAUTH_PRESETS[id];
56467
+ if (preset && !await isPortBindable(preset.callbackPort)) {
56468
+ broadcast({
56469
+ type: "connect-result",
56470
+ id,
56471
+ status: "failed",
56472
+ error: `local port ${preset.callbackPort} is in use \u2014 close the program using it, then click Connect again`
56473
+ });
56474
+ return { ok: true, id, flow, started: false };
56475
+ }
56353
56476
  aware.connectOAuth(id, (result) => {
56477
+ const ok = result.status === "connected";
56354
56478
  broadcast({
56355
56479
  type: "connect-result",
56356
56480
  id,
56357
- status: result.status === "connected" ? "connected" : "failed",
56358
- error: result.status === "connected" ? null : "sign-in failed or was cancelled"
56481
+ status: ok ? "connected" : "failed",
56482
+ error: ok ? null : "sign-in failed or was cancelled"
56359
56483
  });
56484
+ if (ok && id === "trimble-connect") {
56485
+ aware.ensureAgentInstalled(id).catch(
56486
+ (err) => app.log.warn({ id, err: String(err) }, "ensureAgentInstalled after connect failed (non-fatal)")
56487
+ );
56488
+ }
56360
56489
  });
56361
56490
  return { ok: true, id, flow, started: true };
56362
56491
  });
@@ -56380,13 +56509,13 @@ async function startServer() {
56380
56509
  }
56381
56510
  const inputs = appData.inputs.map((i) => ({ name: i.name, type: i.type }));
56382
56511
  const baked = bakeFloSource(appData.source.text, inputs);
56383
- const tmpRoot = (0, import_node_fs18.mkdtempSync)((0, import_node_path17.join)((0, import_node_os11.tmpdir)(), "floless-bake-"));
56384
- const backupDir = (0, import_node_path17.join)(tmpRoot, `${id}-backup`);
56385
- const bakeDir = (0, import_node_path17.join)(tmpRoot, id);
56386
- (0, import_node_fs18.cpSync)(appDir(id), backupDir, { recursive: true });
56387
- (0, import_node_fs18.cpSync)(appDir(id), bakeDir, { recursive: true });
56512
+ const tmpRoot = (0, import_node_fs19.mkdtempSync)((0, import_node_path18.join)((0, import_node_os12.tmpdir)(), "floless-bake-"));
56513
+ const backupDir = (0, import_node_path18.join)(tmpRoot, `${id}-backup`);
56514
+ const bakeDir = (0, import_node_path18.join)(tmpRoot, id);
56515
+ (0, import_node_fs19.cpSync)(appDir(id), backupDir, { recursive: true });
56516
+ (0, import_node_fs19.cpSync)(appDir(id), bakeDir, { recursive: true });
56388
56517
  const floName = appData.source.path.split(/[\\/]/).pop();
56389
- (0, import_node_fs18.writeFileSync)((0, import_node_path17.join)(bakeDir, floName), baked);
56518
+ (0, import_node_fs19.writeFileSync)((0, import_node_path18.join)(bakeDir, floName), baked);
56390
56519
  let appInstalled = true;
56391
56520
  try {
56392
56521
  await aware.uninstall(id);
@@ -56408,17 +56537,17 @@ async function startServer() {
56408
56537
  throw installErr;
56409
56538
  }
56410
56539
  try {
56411
- await aware.compile((0, import_node_path17.join)(appDir(id), floName));
56540
+ await aware.compile((0, import_node_path18.join)(appDir(id), floName));
56412
56541
  } catch (compileErr) {
56413
56542
  app.log.warn({ id, compileErr: String(compileErr) }, "bake: post-install recompile failed (app baked but may need a manual Compile)");
56414
56543
  }
56415
56544
  broadcast({ type: "baked", id });
56416
56545
  return { ok: true, id, agent: id, inputs };
56417
56546
  } finally {
56418
- if (appInstalled) (0, import_node_fs18.rmSync)(tmpRoot, { recursive: true, force: true });
56547
+ if (appInstalled) (0, import_node_fs19.rmSync)(tmpRoot, { recursive: true, force: true });
56419
56548
  }
56420
56549
  });
56421
- const graftAgentsDir = () => (0, import_node_path17.join)((0, import_node_os11.homedir)(), ".aware", "agents");
56550
+ const graftAgentsDir = () => (0, import_node_path18.join)((0, import_node_os12.homedir)(), ".aware", "agents");
56422
56551
  app.post("/api/graft/match", async (req, reply) => {
56423
56552
  const { glob } = req.body ?? {};
56424
56553
  if (!glob) return reply.status(400).send({ ok: false, error: "glob required" });
@@ -56435,7 +56564,7 @@ async function startServer() {
56435
56564
  if (!sourceKind || !sourceRef) {
56436
56565
  return reply.status(400).send({ ok: false, error: "sourceKind and sourceRef required" });
56437
56566
  }
56438
- const tempHome = (0, import_node_fs18.mkdtempSync)((0, import_node_path17.join)((0, import_node_os11.tmpdir)(), "floless-graft-"));
56567
+ const tempHome = (0, import_node_fs19.mkdtempSync)((0, import_node_path18.join)((0, import_node_os12.tmpdir)(), "floless-graft-"));
56439
56568
  let result;
56440
56569
  try {
56441
56570
  result = await aware.build({
@@ -56448,19 +56577,19 @@ async function startServer() {
56448
56577
  awareHome: tempHome
56449
56578
  });
56450
56579
  } catch (err) {
56451
- (0, import_node_fs18.rmSync)(tempHome, { recursive: true, force: true });
56580
+ (0, import_node_fs19.rmSync)(tempHome, { recursive: true, force: true });
56452
56581
  const msg = err instanceof AwareError ? err.message : String(err?.message ?? err);
56453
56582
  return reply.status(422).send({ ok: false, error: msg });
56454
56583
  }
56455
56584
  const manifest = readStagedManifest(result.agentDir);
56456
56585
  if (!manifest) {
56457
- (0, import_node_fs18.rmSync)(tempHome, { recursive: true, force: true });
56586
+ (0, import_node_fs19.rmSync)(tempHome, { recursive: true, force: true });
56458
56587
  return reply.status(502).send({ ok: false, error: `build produced output at ${result.agentDir} but no manifest.yaml` });
56459
56588
  }
56460
56589
  const token = (0, import_node_crypto5.randomUUID)();
56461
56590
  registerStage(token, tempHome, result.agentId);
56462
56591
  const preview = buildPreview(manifest, sourceKind, sourceRef, token);
56463
- if ((0, import_node_fs18.existsSync)((0, import_node_path17.join)(graftAgentsDir(), result.agentId))) {
56592
+ if ((0, import_node_fs19.existsSync)((0, import_node_path18.join)(graftAgentsDir(), result.agentId))) {
56464
56593
  preview.warnings.unshift(`An agent named "${result.agentId}" is already installed \u2014 creating it will overwrite it.`);
56465
56594
  }
56466
56595
  return { ok: true, preview };
@@ -56479,7 +56608,7 @@ async function startServer() {
56479
56608
  registerStage(stagedRef, stage.tempDir, stage.agentId);
56480
56609
  return reply.status(409).send({ ok: false, error: err.message, agentId: stage.agentId, collision: true });
56481
56610
  }
56482
- (0, import_node_fs18.rmSync)(stage.tempDir, { recursive: true, force: true });
56611
+ (0, import_node_fs19.rmSync)(stage.tempDir, { recursive: true, force: true });
56483
56612
  throw err;
56484
56613
  }
56485
56614
  broadcast({ type: "grafted", id: stage.agentId });
@@ -56614,11 +56743,11 @@ async function startServer() {
56614
56743
  app.get("/api/requests/:id/snapshot/:n", async (req, reply) => {
56615
56744
  const n = Number.parseInt(req.params.n, 10);
56616
56745
  const p = Number.isInteger(n) ? snapshotPathFor(req.params.id, n) : null;
56617
- if (!p || !(0, import_node_fs18.existsSync)(p)) return reply.status(404).send({ ok: false, error: "snapshot not found" });
56746
+ if (!p || !(0, import_node_fs19.existsSync)(p)) return reply.status(404).send({ ok: false, error: "snapshot not found" });
56618
56747
  const ext = p.split(".").pop().toLowerCase();
56619
56748
  reply.header("Content-Type", ext === "png" ? "image/png" : ext === "webp" ? "image/webp" : "image/jpeg");
56620
56749
  reply.header("Cache-Control", "no-store");
56621
- return (0, import_node_fs18.readFileSync)(p);
56750
+ return (0, import_node_fs19.readFileSync)(p);
56622
56751
  });
56623
56752
  app.post(
56624
56753
  "/api/tweak",
package/dist/web/aware.js CHANGED
@@ -651,7 +651,12 @@
651
651
  function reportNodeId() {
652
652
  const app = currentId && apps.get(currentId);
653
653
  if (!app || !app.nodes.length) return null;
654
- // Qualify the app only if some node actually PRODUCES report HTML — its exec
654
+ // An html-report agent node renders report HTML — its `render` command returns
655
+ // an `html` field, which is exactly what extractReportHtml keys on. So it's a
656
+ // report producer regardless of exec code; prefer it directly as the viewer node.
657
+ const htmlReportNode = app.nodes.find((n) => n.agent === 'html-report');
658
+ if (htmlReportNode) return htmlReportNode.id;
659
+ // Otherwise, qualify the app only if some node actually PRODUCES report HTML — its exec
655
660
  // code returns an `html` field (the `data.result.html` extractReportHtml keys
656
661
  // on), or it forwards `{{ <node>.result.html }}` through its args (a
657
662
  // pass-through viewer). "any node has exec code" is NOT enough: a plain
@@ -2585,7 +2590,7 @@
2585
2590
  <div class="int-icon">${escapeHtml(VENDOR_ICON[i.vendor] || (i.name[0] || '?'))}</div>
2586
2591
  <div class="int-info">
2587
2592
  <div class="int-name">${escapeHtml(i.name)}</div>
2588
- <div class="int-kind">${escapeHtml(i.vendor || 'integration')} · agent <code>${escapeHtml(i.agent)}</code></div>
2593
+ <div class="int-kind">${i.agent === 'first-party' ? 'Built-in integration' : `${escapeHtml(i.vendor || 'integration')} · agent <code>${escapeHtml(i.agent)}</code>`}</div>
2589
2594
  <div class="int-scopes">${escapeHtml((i.network || []).join(' · ') || '—')}</div>
2590
2595
  <div class="int-meta">${escapeHtml(meta)}</div>
2591
2596
  <div class="int-row">
@@ -2636,6 +2641,10 @@
2636
2641
  if (slot) slot.innerHTML = 'Starting sign-in…';
2637
2642
  try {
2638
2643
  const res = await api(`/api/connect/${encodeURIComponent(id)}`, { method: 'POST', body });
2644
+ // A managed-preset pre-flight (e.g. port 80 already in use) refuses to start
2645
+ // and broadcasts the reason over SSE (connect-result). Clear the guard so the
2646
+ // user can retry after fixing it, and don't claim the browser opened.
2647
+ if (res && res.started === false) { connecting.delete(id); return; }
2639
2648
  if (slot) {
2640
2649
  if (res.flow === 'device-code' && res.prompt) {
2641
2650
  // Fallback flow: show the device code to enter at the verification URL.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@floless/app",
3
- "version": "0.6.3",
3
+ "version": "0.7.0",
4
4
  "type": "module",
5
5
  "description": "Thin localhost host for floless.app — serves web/ and shells the aware CLI. No engine, no LLM.",
6
6
  "bin": {