agent-remnote 0.2.0 → 0.3.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.
package/dist/main.js CHANGED
@@ -73916,13 +73916,17 @@ var platformRunnerImpl = /* @__PURE__ */ PlatformRunner2.of({
73916
73916
  import { readFileSync as readFileSync2 } from "node:fs";
73917
73917
  import { format as format10 } from "node:util";
73918
73918
 
73919
+ // src/services/UserConfigFile.ts
73920
+ import { promises as fs4 } from "node:fs";
73921
+ import path7 from "node:path";
73922
+
73919
73923
  // src/services/AppConfig.ts
73920
73924
  class AppConfig extends Tag2("AppConfig")() {
73921
73925
  }
73922
73926
 
73923
- // src/services/DaemonFiles.ts
73924
- import { promises as fs } from "node:fs";
73925
- import path4 from "node:path";
73927
+ // src/services/Config.ts
73928
+ import fs3 from "node:fs";
73929
+ import path6 from "node:path";
73926
73930
 
73927
73931
  // src/services/Errors.ts
73928
73932
  class CliError extends TaggedError("CliError") {
@@ -73954,52 +73958,985 @@ function cliErrorFromValidationError(err) {
73954
73958
  exitCode: 2
73955
73959
  });
73956
73960
  }
73957
- function exitCodeFromExit(exit3) {
73958
- if (isSuccess(exit3))
73959
- return 0;
73960
- if (isInterruptedOnly2(exit3.cause))
73961
- return 0;
73962
- const failure = failureOption2(exit3.cause);
73963
- if (isSome2(failure)) {
73964
- const error4 = failure.value;
73965
- if (isCliError(error4))
73966
- return error4.exitCode;
73967
- if (isValidationError2(error4))
73968
- return 2;
73969
- }
73970
- return 1;
73961
+ function exitCodeFromExit(exit3) {
73962
+ if (isSuccess(exit3))
73963
+ return 0;
73964
+ if (isInterruptedOnly2(exit3.cause))
73965
+ return 0;
73966
+ const failure = failureOption2(exit3.cause);
73967
+ if (isSome2(failure)) {
73968
+ const error4 = failure.value;
73969
+ if (isCliError(error4))
73970
+ return error4.exitCode;
73971
+ if (isValidationError2(error4))
73972
+ return 2;
73973
+ }
73974
+ return 1;
73975
+ }
73976
+
73977
+ // src/lib/paths.ts
73978
+ import os from "node:os";
73979
+ import path3 from "node:path";
73980
+ function homeDir() {
73981
+ const h = os.homedir();
73982
+ if (typeof h === "string" && h.trim())
73983
+ return h;
73984
+ return process.env.HOME || process.env.USERPROFILE || ".";
73985
+ }
73986
+ function expandHome(targetPath) {
73987
+ const raw4 = targetPath.trim();
73988
+ if (!raw4.startsWith("~"))
73989
+ return raw4;
73990
+ const home = homeDir();
73991
+ if (raw4 === "~")
73992
+ return home;
73993
+ if (raw4.startsWith("~/") || raw4.startsWith("~\\")) {
73994
+ return path3.join(home, raw4.slice(2));
73995
+ }
73996
+ return raw4.replace(/^~(?=$|[\\/])/, home);
73997
+ }
73998
+ function resolveUserFilePath(filePath) {
73999
+ return path3.normalize(expandHome(filePath));
74000
+ }
74001
+
74002
+ // src/lib/wsState.ts
74003
+ import fs from "node:fs";
74004
+ import path4 from "node:path";
74005
+ function defaultStateFilePath() {
74006
+ return path4.join(homeDir(), ".agent-remnote", "ws.bridge.state.json");
74007
+ }
74008
+ function resolveStateFilePath(explicit) {
74009
+ if (explicit && explicit.trim())
74010
+ return { disabled: false, path: resolveUserFilePath(explicit) };
74011
+ const raw4 = String(process.env.REMNOTE_WS_STATE_FILE || process.env.WS_STATE_FILE || "").trim();
74012
+ if (raw4 === "0" || raw4.toLowerCase() === "false")
74013
+ return { disabled: true, path: defaultStateFilePath() };
74014
+ if (raw4)
74015
+ return { disabled: false, path: resolveUserFilePath(raw4) };
74016
+ return { disabled: false, path: defaultStateFilePath() };
74017
+ }
74018
+ function readJson(filePath) {
74019
+ try {
74020
+ const txt = fs.readFileSync(filePath, "utf8");
74021
+ return JSON.parse(txt);
74022
+ } catch {
74023
+ return null;
74024
+ }
74025
+ }
74026
+ function pickClient(clients, connId) {
74027
+ const target2 = (connId || "").trim();
74028
+ if (target2) {
74029
+ const found = clients.find((c) => c && typeof c === "object" && c.connId === target2);
74030
+ if (found)
74031
+ return found;
74032
+ }
74033
+ const active2 = clients.find((c) => c && typeof c === "object" && c.isActiveWorker === true);
74034
+ if (active2)
74035
+ return active2;
74036
+ let best = null;
74037
+ let bestScore = -1;
74038
+ for (const c of clients) {
74039
+ if (!c || typeof c !== "object")
74040
+ continue;
74041
+ const selAt = Number(c.selection?.updatedAt ?? 0);
74042
+ const ctxAt = Number(c.uiContext?.updatedAt ?? 0);
74043
+ const score = Math.max(selAt, ctxAt);
74044
+ if (score > bestScore) {
74045
+ bestScore = score;
74046
+ best = c;
74047
+ }
74048
+ }
74049
+ return best;
74050
+ }
74051
+ function resolveStaleMs(explicit) {
74052
+ if (typeof explicit === "number" && Number.isFinite(explicit) && explicit > 0)
74053
+ return Math.floor(explicit);
74054
+ const raw4 = process.env.REMNOTE_WS_STATE_STALE_MS || process.env.WS_STATE_STALE_MS;
74055
+ const n = Number(raw4);
74056
+ if (Number.isFinite(n) && n > 0)
74057
+ return Math.floor(n);
74058
+ return 60000;
74059
+ }
74060
+
74061
+ // src/lib/remnote.ts
74062
+ import fs2 from "node:fs";
74063
+ import path5 from "node:path";
74064
+ function tryParseRemnoteLink(input) {
74065
+ const raw4 = input.trim();
74066
+ let u;
74067
+ try {
74068
+ u = new URL(raw4);
74069
+ } catch {
74070
+ return;
74071
+ }
74072
+ if (u.protocol === "remnote:" && u.hostname === "w") {
74073
+ const parts2 = u.pathname.split("/").filter(Boolean);
74074
+ const workspaceId = parts2.length >= 1 ? parts2[0] : undefined;
74075
+ const remId = parts2.length >= 2 ? parts2[1] : undefined;
74076
+ if (workspaceId && remId) {
74077
+ return { workspaceId: workspaceId.trim(), remId: remId.trim() };
74078
+ }
74079
+ return;
74080
+ }
74081
+ if ((u.protocol === "https:" || u.protocol === "http:") && u.hostname.endsWith("remnote.com")) {
74082
+ const parts2 = u.pathname.split("/").filter(Boolean);
74083
+ if (parts2.length >= 3 && parts2[0] === "w") {
74084
+ const workspaceId = parts2[1];
74085
+ const remId = parts2[2];
74086
+ if (workspaceId && remId) {
74087
+ return { workspaceId: workspaceId.trim(), remId: remId.trim() };
74088
+ }
74089
+ }
74090
+ }
74091
+ return;
74092
+ }
74093
+ function tryParseRemnoteLinkFromRef(input) {
74094
+ const direct = tryParseRemnoteLink(input);
74095
+ if (direct)
74096
+ return direct;
74097
+ const raw4 = input.trim();
74098
+ const idx = raw4.indexOf(":");
74099
+ if (idx <= 0)
74100
+ return;
74101
+ const value8 = raw4.slice(idx + 1).trim();
74102
+ if (!value8)
74103
+ return;
74104
+ return tryParseRemnoteLink(value8);
74105
+ }
74106
+ function remnoteDbPathForWorkspaceId(workspaceId) {
74107
+ return path5.join(homeDir(), "remnote", `remnote-${workspaceId}`, "remnote.db");
74108
+ }
74109
+ function tryResolveRemnoteDbPathForWorkspaceIdSync(workspaceId) {
74110
+ const p3 = remnoteDbPathForWorkspaceId(workspaceId);
74111
+ try {
74112
+ return fs2.statSync(p3).isFile() ? p3 : undefined;
74113
+ } catch {
74114
+ return;
74115
+ }
74116
+ }
74117
+
74118
+ // src/services/Config.ts
74119
+ function defaultStoreDbPath() {
74120
+ return path6.join(homeDir(), ".agent-remnote", "store.sqlite");
74121
+ }
74122
+ function defaultUserConfigFilePath() {
74123
+ return path6.join(homeDir(), ".agent-remnote", "config.json");
74124
+ }
74125
+ function wsUrlFromPort(port3) {
74126
+ return `ws://localhost:${port3}/ws`;
74127
+ }
74128
+ function defaultWsStateFilePath() {
74129
+ return path6.join(homeDir(), ".agent-remnote", "ws.bridge.state.json");
74130
+ }
74131
+ function defaultStatusLineFilePath() {
74132
+ return path6.join(homeDir(), ".agent-remnote", "status-line.txt");
74133
+ }
74134
+ function defaultStatusLineJsonFilePath() {
74135
+ return path6.join(homeDir(), ".agent-remnote", "status-line.json");
74136
+ }
74137
+ function defaultApiPidFilePath() {
74138
+ return path6.join(homeDir(), ".agent-remnote", "api.pid");
74139
+ }
74140
+ function defaultApiLogFilePath() {
74141
+ return path6.join(homeDir(), ".agent-remnote", "api.log");
74142
+ }
74143
+ function defaultApiStateFilePath() {
74144
+ return path6.join(homeDir(), ".agent-remnote", "api.state.json");
74145
+ }
74146
+ var ROOT_BOOL_FLAGS = new Set(["--json", "--md", "--ids", "--quiet", "--debug"]);
74147
+ var BUILTIN_BOOL_FLAGS = new Set(["--help", "-h", "--wizard", "--version"]);
74148
+ var BUILTIN_VALUE_FLAGS = new Set(["--completions", "--log-level"]);
74149
+ var ROOT_VALUE_FLAGS = new Set([
74150
+ "--remnote-db",
74151
+ "--store-db",
74152
+ "--daemon-url",
74153
+ "--ws-port",
74154
+ "--repo",
74155
+ "--api-base-url",
74156
+ "--config-file",
74157
+ ...BUILTIN_VALUE_FLAGS
74158
+ ]);
74159
+ function isBooleanLiteralToken(token) {
74160
+ const v = token.trim().toLowerCase();
74161
+ return v === "true" || v === "false";
74162
+ }
74163
+ function splitFlagInlineValue(token) {
74164
+ if (!token.startsWith("--"))
74165
+ return { flag: token, inlineValue: null };
74166
+ const eq = token.indexOf("=");
74167
+ if (eq === -1)
74168
+ return { flag: token, inlineValue: null };
74169
+ return { flag: token.slice(0, eq), inlineValue: token.slice(eq + 1) };
74170
+ }
74171
+ function isConfigCommandInvocation(argv) {
74172
+ const tokens = argv.slice(2);
74173
+ let i = 0;
74174
+ while (i < tokens.length) {
74175
+ const raw4 = String(tokens[i] ?? "");
74176
+ if (!raw4)
74177
+ break;
74178
+ if (raw4 === "--") {
74179
+ i += 1;
74180
+ break;
74181
+ }
74182
+ if (!raw4.startsWith("-"))
74183
+ break;
74184
+ const { flag, inlineValue } = splitFlagInlineValue(raw4);
74185
+ if (ROOT_VALUE_FLAGS.has(flag)) {
74186
+ i += inlineValue !== null ? 1 : 2;
74187
+ continue;
74188
+ }
74189
+ if (ROOT_BOOL_FLAGS.has(flag) || BUILTIN_BOOL_FLAGS.has(flag)) {
74190
+ if (inlineValue !== null) {
74191
+ i += 1;
74192
+ continue;
74193
+ }
74194
+ const next4 = tokens[i + 1];
74195
+ if (typeof next4 === "string" && isBooleanLiteralToken(next4)) {
74196
+ i += 2;
74197
+ continue;
74198
+ }
74199
+ i += 1;
74200
+ continue;
74201
+ }
74202
+ break;
74203
+ }
74204
+ return tokens[i] === "config";
74205
+ }
74206
+ function normalizeApiBasePath(raw4) {
74207
+ const trimmed2 = raw4.trim();
74208
+ if (!trimmed2)
74209
+ return "/v1";
74210
+ return trimmed2.startsWith("/") ? trimmed2 : `/${trimmed2}`;
74211
+ }
74212
+ function normalizeApiBaseUrl(raw4) {
74213
+ const trimmed2 = raw4.trim();
74214
+ if (!trimmed2)
74215
+ return trimmed2;
74216
+ let parsed;
74217
+ try {
74218
+ parsed = new URL(trimmed2);
74219
+ } catch {
74220
+ throw new CliError({
74221
+ code: "INVALID_ARGS",
74222
+ message: `Invalid apiBaseUrl: ${trimmed2}`,
74223
+ exitCode: 2,
74224
+ details: { api_base_url: trimmed2 }
74225
+ });
74226
+ }
74227
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
74228
+ throw new CliError({
74229
+ code: "INVALID_ARGS",
74230
+ message: `apiBaseUrl protocol must be http/https: ${trimmed2}`,
74231
+ exitCode: 2,
74232
+ details: { api_base_url: trimmed2 }
74233
+ });
74234
+ }
74235
+ const normalized = trimmed2.replace(/\/+$/, "");
74236
+ return normalized;
74237
+ }
74238
+ function resolveWsStateFile(spec) {
74239
+ const raw4 = spec.trim();
74240
+ if (raw4 === "0" || raw4.toLowerCase() === "false") {
74241
+ return { disabled: true, path: defaultWsStateFilePath() };
74242
+ }
74243
+ if (raw4)
74244
+ return { disabled: false, path: resolveUserFilePath(raw4) };
74245
+ return { disabled: false, path: defaultWsStateFilePath() };
74246
+ }
74247
+ function inferRemnoteDbFromWsState(params3) {
74248
+ if (params3.wsStateFile.disabled)
74249
+ return;
74250
+ const state = readJson(params3.wsStateFile.path);
74251
+ if (!state)
74252
+ return;
74253
+ const now2 = Date.now();
74254
+ const updatedAt = Number(state.updatedAt ?? 0);
74255
+ const staleMs = params3.wsStateStaleMs;
74256
+ const stale = !Number.isFinite(updatedAt) || updatedAt <= 0 || now2 - updatedAt > staleMs;
74257
+ if (stale)
74258
+ return;
74259
+ const clients = Array.isArray(state.clients) ? state.clients : [];
74260
+ const activeConnIdRaw = typeof state.activeWorkerConnId === "string" ? state.activeWorkerConnId.trim() : "";
74261
+ const client = pickClient(clients, activeConnIdRaw || undefined);
74262
+ const kbIdRaw = typeof client?.uiContext?.kbId === "string" ? client.uiContext.kbId.trim() : "";
74263
+ if (!kbIdRaw)
74264
+ return;
74265
+ const dbPath = resolveUserFilePath(remnoteDbPathForWorkspaceId(kbIdRaw));
74266
+ try {
74267
+ return fs3.statSync(dbPath).isFile() ? dbPath : undefined;
74268
+ } catch {
74269
+ return;
74270
+ }
74271
+ }
74272
+ function pickFormat(raw4) {
74273
+ const json4 = raw4.json === true;
74274
+ const md = raw4.md === true;
74275
+ const ids3 = raw4.ids === true;
74276
+ const count4 = [json4, md, ids3].filter(Boolean).length;
74277
+ if (count4 > 1) {
74278
+ throw new CliError({
74279
+ code: "INVALID_ARGS",
74280
+ message: "Output format conflict: choose only one of --json/--md/--ids",
74281
+ exitCode: 2,
74282
+ details: { json: json4, md, ids: ids3 }
74283
+ });
74284
+ }
74285
+ if (json4)
74286
+ return "json";
74287
+ if (ids3)
74288
+ return "ids";
74289
+ return "md";
74290
+ }
74291
+ var rawConfigSpec = all8({
74292
+ json: boolean4("json").pipe(withDefault2(false)),
74293
+ md: boolean4("md").pipe(withDefault2(false)),
74294
+ ids: boolean4("ids").pipe(withDefault2(false)),
74295
+ quiet: boolean4("quiet").pipe(withDefault2(false)),
74296
+ debug: boolean4("debug").pipe(withDefault2(false)),
74297
+ configFile: string5("configFile").pipe(withDefault2(defaultUserConfigFilePath())),
74298
+ remnoteDb: string5("remnoteDb").pipe(withDefault2("")),
74299
+ storeDb: string5("storeDb").pipe(withDefault2(defaultStoreDbPath())),
74300
+ daemonUrl: string5("daemonUrl").pipe(withDefault2("")),
74301
+ wsPort: port2("wsPort").pipe(withDefault2(6789)),
74302
+ wsScheduler: boolean4("wsScheduler").pipe(withDefault2(true)),
74303
+ wsDispatchMaxBytes: integer2("wsDispatchMaxBytes").pipe(withDefault2(512000), validate3({
74304
+ message: "wsDispatchMaxBytes must be a positive integer",
74305
+ validation: (n) => Number.isFinite(n) && n > 0
74306
+ })),
74307
+ wsDispatchMaxOpBytes: integer2("wsDispatchMaxOpBytes").pipe(withDefault2(256000), validate3({
74308
+ message: "wsDispatchMaxOpBytes must be a positive integer",
74309
+ validation: (n) => Number.isFinite(n) && n > 0
74310
+ })),
74311
+ repo: string5("repo").pipe(withDefault2("")),
74312
+ wsStateFile: string5("wsStateFile").pipe(withDefault2("")),
74313
+ wsStateStaleMs: integer2("wsStateStaleMs").pipe(withDefault2(60000), validate3({
74314
+ message: "wsStateStaleMs must be a positive integer",
74315
+ validation: (n) => Number.isFinite(n) && n > 0
74316
+ })),
74317
+ tmuxRefresh: boolean4("tmuxRefresh").pipe(withDefault2(true)),
74318
+ tmuxRefreshMinIntervalMs: integer2("tmuxRefreshMinIntervalMs").pipe(withDefault2(250), validate3({
74319
+ message: "tmuxRefreshMinIntervalMs must be a positive integer",
74320
+ validation: (n) => Number.isFinite(n) && n > 0
74321
+ })),
74322
+ statusLineFile: string5("statusLineFile").pipe(withDefault2(defaultStatusLineFilePath())),
74323
+ statusLineMinIntervalMs: integer2("statusLineMinIntervalMs").pipe(withDefault2(250), validate3({
74324
+ message: "statusLineMinIntervalMs must be a positive integer",
74325
+ validation: (n) => Number.isFinite(n) && n > 0
74326
+ })),
74327
+ statusLineDebug: boolean4("statusLineDebug").pipe(withDefault2(false)),
74328
+ statusLineJsonFile: string5("statusLineJsonFile").pipe(withDefault2(defaultStatusLineJsonFilePath())),
74329
+ apiBaseUrl: string5("apiBaseUrl").pipe(withDefault2("")),
74330
+ apiHost: string5("apiHost").pipe(withDefault2("0.0.0.0")),
74331
+ apiPort: port2("apiPort").pipe(withDefault2(3000)),
74332
+ apiBasePath: string5("apiBasePath").pipe(withDefault2("/v1")),
74333
+ apiPidFile: string5("apiPidFile").pipe(withDefault2(defaultApiPidFilePath())),
74334
+ apiLogFile: string5("apiLogFile").pipe(withDefault2(defaultApiLogFilePath())),
74335
+ apiStateFile: string5("apiStateFile").pipe(withDefault2(defaultApiStateFilePath()))
74336
+ });
74337
+ function cliErrorFromConfigError(error4) {
74338
+ if (isInvalidData2(error4) || isMissingData2(error4)) {
74339
+ return new CliError({
74340
+ code: "INVALID_ARGS",
74341
+ message: error4.message || "Invalid configuration",
74342
+ exitCode: 2,
74343
+ details: { path: error4.path, op: error4._op }
74344
+ });
74345
+ }
74346
+ return new CliError({
74347
+ code: "INVALID_ARGS",
74348
+ message: error4.message || "Invalid configuration",
74349
+ exitCode: 2,
74350
+ details: { op: error4._op }
74351
+ });
74352
+ }
74353
+ function optionalTrimmed(s) {
74354
+ const t = s.trim();
74355
+ return t.length > 0 ? t : undefined;
74356
+ }
74357
+ function readUserConfigFile(configFile) {
74358
+ const file6 = resolveUserFilePath(configFile);
74359
+ let rawText = "";
74360
+ try {
74361
+ rawText = fs3.readFileSync(file6, "utf8");
74362
+ } catch (error4) {
74363
+ if (error4?.code === "ENOENT")
74364
+ return {};
74365
+ throw new CliError({
74366
+ code: "INVALID_ARGS",
74367
+ message: `Failed to read config file: ${file6}`,
74368
+ exitCode: 2,
74369
+ details: { config_file: file6, error: String(error4?.message || error4) }
74370
+ });
74371
+ }
74372
+ let parsed;
74373
+ try {
74374
+ parsed = JSON.parse(rawText);
74375
+ } catch (error4) {
74376
+ throw new CliError({
74377
+ code: "INVALID_ARGS",
74378
+ message: `Invalid JSON in config file: ${file6}`,
74379
+ exitCode: 2,
74380
+ details: { config_file: file6, error: String(error4?.message || error4) }
74381
+ });
74382
+ }
74383
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
74384
+ throw new CliError({
74385
+ code: "INVALID_ARGS",
74386
+ message: `Config file must contain a JSON object: ${file6}`,
74387
+ exitCode: 2,
74388
+ details: { config_file: file6 }
74389
+ });
74390
+ }
74391
+ const config3 = parsed;
74392
+ const api = config3.api;
74393
+ const nestedBaseUrl = api && typeof api === "object" && !Array.isArray(api) ? api.baseUrl : undefined;
74394
+ const apiBaseUrl = config3.apiBaseUrl ?? nestedBaseUrl;
74395
+ if (apiBaseUrl === undefined)
74396
+ return {};
74397
+ if (typeof apiBaseUrl !== "string") {
74398
+ throw new CliError({
74399
+ code: "INVALID_ARGS",
74400
+ message: `Config key apiBaseUrl must be a string: ${file6}`,
74401
+ exitCode: 2,
74402
+ details: { config_file: file6 }
74403
+ });
74404
+ }
74405
+ return { apiBaseUrl };
74406
+ }
74407
+ function resolveConfig() {
74408
+ return gen2(function* () {
74409
+ const raw4 = yield* rawConfigSpec;
74410
+ const configFile = resolveUserFilePath(raw4.configFile);
74411
+ const userConfigResult = yield* either3(try_3({
74412
+ try: () => readUserConfigFile(configFile),
74413
+ catch: (error4) => isCliError(error4) ? error4 : new CliError({
74414
+ code: "INVALID_ARGS",
74415
+ message: `Failed to load config file: ${configFile}`,
74416
+ exitCode: 2,
74417
+ details: { config_file: configFile, error: String(error4?.message || error4) }
74418
+ })
74419
+ }));
74420
+ const userConfig = userConfigResult._tag === "Right" ? userConfigResult.right : isConfigCommandInvocation(process.argv) ? {} : yield* fail8(userConfigResult.left);
74421
+ const wsStateFile = resolveWsStateFile(raw4.wsStateFile);
74422
+ const remnoteDb = optionalTrimmed(raw4.remnoteDb) ? resolveUserFilePath(raw4.remnoteDb) : inferRemnoteDbFromWsState({ wsStateFile, wsStateStaleMs: raw4.wsStateStaleMs }) || undefined;
74423
+ const storeDb = resolveUserFilePath(raw4.storeDb);
74424
+ const daemonUrl = optionalTrimmed(raw4.daemonUrl);
74425
+ const wsUrl = daemonUrl ? daemonUrl : wsUrlFromPort(raw4.wsPort);
74426
+ const format8 = yield* try_3({
74427
+ try: () => pickFormat(raw4),
74428
+ catch: (e) => isCliError(e) ? e : new CliError({
74429
+ code: "INVALID_ARGS",
74430
+ message: "Invalid output format flags",
74431
+ exitCode: 2,
74432
+ details: { error: String(e?.message || e) }
74433
+ })
74434
+ });
74435
+ const apiBaseUrlRaw = optionalTrimmed(raw4.apiBaseUrl) ?? optionalTrimmed(userConfig.apiBaseUrl ?? "");
74436
+ const apiBaseUrl = apiBaseUrlRaw ? normalizeApiBaseUrl(apiBaseUrlRaw) : undefined;
74437
+ return {
74438
+ format: format8,
74439
+ quiet: raw4.quiet,
74440
+ debug: raw4.debug,
74441
+ configFile,
74442
+ remnoteDb,
74443
+ storeDb,
74444
+ wsUrl,
74445
+ wsScheduler: raw4.wsScheduler,
74446
+ wsDispatchMaxBytes: raw4.wsDispatchMaxBytes,
74447
+ wsDispatchMaxOpBytes: raw4.wsDispatchMaxOpBytes,
74448
+ repo: optionalTrimmed(raw4.repo) ? resolveUserFilePath(raw4.repo) : undefined,
74449
+ wsStateFile,
74450
+ wsStateStaleMs: raw4.wsStateStaleMs,
74451
+ tmuxRefresh: raw4.tmuxRefresh,
74452
+ tmuxRefreshMinIntervalMs: raw4.tmuxRefreshMinIntervalMs,
74453
+ statusLineFile: resolveUserFilePath(raw4.statusLineFile),
74454
+ statusLineMinIntervalMs: raw4.statusLineMinIntervalMs,
74455
+ statusLineDebug: raw4.statusLineDebug,
74456
+ statusLineJsonFile: resolveUserFilePath(raw4.statusLineJsonFile),
74457
+ apiBaseUrl,
74458
+ apiHost: raw4.apiHost.trim() || "0.0.0.0",
74459
+ apiPort: raw4.apiPort,
74460
+ apiBasePath: normalizeApiBasePath(raw4.apiBasePath),
74461
+ apiPidFile: resolveUserFilePath(raw4.apiPidFile),
74462
+ apiLogFile: resolveUserFilePath(raw4.apiLogFile),
74463
+ apiStateFile: resolveUserFilePath(raw4.apiStateFile)
74464
+ };
74465
+ }).pipe(catchAll2((error4) => {
74466
+ if (isCliError(error4))
74467
+ return fail8(error4);
74468
+ if (isConfigError2(error4))
74469
+ return fail8(cliErrorFromConfigError(error4));
74470
+ return fail8(new CliError({
74471
+ code: "INTERNAL",
74472
+ message: "Failed to parse config",
74473
+ exitCode: 1,
74474
+ details: { error: String(error4?.message || error4) }
74475
+ }));
74476
+ }));
74477
+ }
74478
+
74479
+ // src/services/UserConfigFile.ts
74480
+ class UserConfigFile extends Tag2("UserConfigFile")() {
74481
+ }
74482
+ function canonicalKey(input) {
74483
+ const key = String(input ?? "").trim();
74484
+ if (!key) {
74485
+ throw new CliError({ code: "INVALID_ARGS", message: "Config key is required", exitCode: 2 });
74486
+ }
74487
+ if (key === "apiBaseUrl" || key === "api.baseUrl" || key === "api-base-url")
74488
+ return "apiBaseUrl";
74489
+ throw new CliError({ code: "INVALID_ARGS", message: `Unsupported config key: ${key}`, exitCode: 2 });
74490
+ }
74491
+ function isPlainObject(value8) {
74492
+ return typeof value8 === "object" && value8 !== null && !Array.isArray(value8);
74493
+ }
74494
+ function cloneDoc(doc) {
74495
+ return JSON.parse(JSON.stringify(doc));
74496
+ }
74497
+ function removeEmptyApiObject(doc) {
74498
+ const api = doc.api;
74499
+ if (!isPlainObject(api))
74500
+ return;
74501
+ if (Object.keys(api).length === 0)
74502
+ delete doc.api;
74503
+ }
74504
+ function readApiBaseUrl(doc) {
74505
+ const errors3 = [];
74506
+ const root = doc.apiBaseUrl;
74507
+ const api = doc.api;
74508
+ const nested4 = isPlainObject(api) ? api.baseUrl : undefined;
74509
+ const rootValue = root === undefined ? undefined : typeof root === "string" ? root : (errors3.push("Config key apiBaseUrl must be a string"), undefined);
74510
+ const nestedValue = nested4 === undefined ? undefined : typeof nested4 === "string" ? nested4 : (errors3.push("Config key api.baseUrl must be a string"), undefined);
74511
+ if (rootValue && nestedValue && rootValue !== nestedValue) {
74512
+ errors3.push("Config keys apiBaseUrl and api.baseUrl conflict");
74513
+ }
74514
+ return { value: rootValue ?? nestedValue, errors: errors3 };
74515
+ }
74516
+ function inspectDoc(configFile, exists3, doc) {
74517
+ const apiBaseUrl = readApiBaseUrl(doc);
74518
+ const unknownKeys = [];
74519
+ for (const key of Object.keys(doc)) {
74520
+ if (key === "apiBaseUrl")
74521
+ continue;
74522
+ if (key !== "api") {
74523
+ unknownKeys.push(key);
74524
+ continue;
74525
+ }
74526
+ const api = doc.api;
74527
+ if (!isPlainObject(api)) {
74528
+ continue;
74529
+ }
74530
+ for (const nestedKey of Object.keys(api)) {
74531
+ if (nestedKey === "baseUrl")
74532
+ continue;
74533
+ unknownKeys.push(`api.${nestedKey}`);
74534
+ }
74535
+ }
74536
+ return {
74537
+ configFile,
74538
+ exists: exists3,
74539
+ values: { apiBaseUrl: apiBaseUrl.value },
74540
+ unknownKeys,
74541
+ errors: apiBaseUrl.errors,
74542
+ valid: apiBaseUrl.errors.length === 0
74543
+ };
74544
+ }
74545
+ async function ensureDir(filePath) {
74546
+ await fs4.mkdir(path7.dirname(filePath), { recursive: true });
74547
+ }
74548
+ async function readDocDetailed(configFile) {
74549
+ const file6 = resolveUserFilePath(configFile);
74550
+ let rawText = "";
74551
+ try {
74552
+ rawText = await fs4.readFile(file6, "utf8");
74553
+ } catch (error4) {
74554
+ if (error4?.code === "ENOENT")
74555
+ return { ok: true, exists: false, configFile: file6, doc: {} };
74556
+ return {
74557
+ ok: false,
74558
+ exists: true,
74559
+ configFile: file6,
74560
+ errors: [`Failed to read config file: ${file6}`]
74561
+ };
74562
+ }
74563
+ let parsed;
74564
+ try {
74565
+ parsed = JSON.parse(rawText);
74566
+ } catch {
74567
+ return {
74568
+ ok: false,
74569
+ exists: true,
74570
+ configFile: file6,
74571
+ errors: [`Invalid JSON in config file: ${file6}`]
74572
+ };
74573
+ }
74574
+ if (!isPlainObject(parsed)) {
74575
+ return {
74576
+ ok: false,
74577
+ exists: true,
74578
+ configFile: file6,
74579
+ errors: [`Config file must contain a JSON object: ${file6}`]
74580
+ };
74581
+ }
74582
+ return { ok: true, exists: true, configFile: file6, doc: parsed };
74583
+ }
74584
+ function requireParsedDoc(parsed) {
74585
+ if (parsed.ok)
74586
+ return parsed;
74587
+ throw new CliError({
74588
+ code: "INVALID_ARGS",
74589
+ message: parsed.errors[0] || "Invalid config file",
74590
+ exitCode: 2,
74591
+ details: { config_file: parsed.configFile, errors: parsed.errors }
74592
+ });
74593
+ }
74594
+ async function writeDoc(configFile, doc) {
74595
+ const file6 = resolveUserFilePath(configFile);
74596
+ await ensureDir(file6);
74597
+ const tmp = `${file6}.tmp-${process.pid}-${Date.now()}`;
74598
+ await fs4.writeFile(tmp, `${JSON.stringify(doc, null, 2)}
74599
+ `, "utf8");
74600
+ await fs4.rename(tmp, file6);
74601
+ }
74602
+ async function deleteDoc(configFile) {
74603
+ await fs4.rm(resolveUserFilePath(configFile), { force: true });
74604
+ }
74605
+ function setApiBaseUrl(doc, value8) {
74606
+ const next4 = cloneDoc(doc);
74607
+ next4.apiBaseUrl = normalizeApiBaseUrl(value8);
74608
+ const api = next4.api;
74609
+ if (isPlainObject(api)) {
74610
+ delete api.baseUrl;
74611
+ removeEmptyApiObject(next4);
74612
+ }
74613
+ return next4;
74614
+ }
74615
+ function unsetApiBaseUrl(doc) {
74616
+ const next4 = cloneDoc(doc);
74617
+ let removed = false;
74618
+ if (Object.prototype.hasOwnProperty.call(next4, "apiBaseUrl")) {
74619
+ delete next4.apiBaseUrl;
74620
+ removed = true;
74621
+ }
74622
+ const api = next4.api;
74623
+ if (isPlainObject(api) && Object.prototype.hasOwnProperty.call(api, "baseUrl")) {
74624
+ delete api.baseUrl;
74625
+ removeEmptyApiObject(next4);
74626
+ removed = true;
74627
+ }
74628
+ return { next: next4, removed };
74629
+ }
74630
+ function isEmptyDoc(doc) {
74631
+ return Object.keys(doc).length === 0;
74632
+ }
74633
+ function toCliFailure(error4, message) {
74634
+ return isCliError(error4) ? error4 : new CliError({
74635
+ code: "INVALID_ARGS",
74636
+ message,
74637
+ exitCode: 2,
74638
+ details: { error: String(error4?.message || error4) }
74639
+ });
74640
+ }
74641
+ var UserConfigFileLive = succeed10(UserConfigFile, {
74642
+ path: () => gen2(function* () {
74643
+ const cfg = yield* AppConfig;
74644
+ return cfg.configFile;
74645
+ }),
74646
+ inspect: () => gen2(function* () {
74647
+ const cfg = yield* AppConfig;
74648
+ const parsed = yield* promise2(() => readDocDetailed(cfg.configFile));
74649
+ if (!parsed.ok) {
74650
+ return {
74651
+ configFile: parsed.configFile,
74652
+ exists: parsed.exists,
74653
+ values: {},
74654
+ unknownKeys: [],
74655
+ errors: parsed.errors,
74656
+ valid: false
74657
+ };
74658
+ }
74659
+ return inspectDoc(parsed.configFile, parsed.exists, parsed.doc);
74660
+ }),
74661
+ get: (key) => gen2(function* () {
74662
+ const targetKey = yield* try_3({
74663
+ try: () => canonicalKey(key),
74664
+ catch: (error4) => toCliFailure(error4, "Invalid config key")
74665
+ });
74666
+ const cfg = yield* AppConfig;
74667
+ const parsed = yield* promise2(() => readDocDetailed(cfg.configFile));
74668
+ const { configFile, doc } = yield* try_3({
74669
+ try: () => requireParsedDoc(parsed),
74670
+ catch: (error4) => toCliFailure(error4, "Invalid config file")
74671
+ });
74672
+ const inspection = inspectDoc(configFile, parsed.exists, doc);
74673
+ const value8 = targetKey === "apiBaseUrl" ? inspection.values.apiBaseUrl ?? null : null;
74674
+ return {
74675
+ configFile,
74676
+ key: targetKey,
74677
+ exists: value8 !== null,
74678
+ value: value8
74679
+ };
74680
+ }),
74681
+ set: (key, value8) => gen2(function* () {
74682
+ const targetKey = yield* try_3({
74683
+ try: () => canonicalKey(key),
74684
+ catch: (error4) => toCliFailure(error4, "Invalid config key")
74685
+ });
74686
+ const cfg = yield* AppConfig;
74687
+ const parsed = yield* promise2(() => readDocDetailed(cfg.configFile));
74688
+ const { configFile, doc } = yield* try_3({
74689
+ try: () => requireParsedDoc(parsed),
74690
+ catch: (error4) => toCliFailure(error4, "Invalid config file")
74691
+ });
74692
+ const next4 = targetKey === "apiBaseUrl" ? yield* try_3({
74693
+ try: () => setApiBaseUrl(doc, value8),
74694
+ catch: (error4) => toCliFailure(error4, "Invalid config value")
74695
+ }) : doc;
74696
+ yield* tryPromise2({
74697
+ try: async () => await writeDoc(configFile, next4),
74698
+ catch: (error4) => new CliError({
74699
+ code: "INTERNAL",
74700
+ message: "Failed to write config file",
74701
+ exitCode: 1,
74702
+ details: { config_file: configFile, error: String(error4?.message || error4) }
74703
+ })
74704
+ });
74705
+ return {
74706
+ configFile,
74707
+ key: targetKey,
74708
+ value: String(next4.apiBaseUrl ?? ""),
74709
+ changed: true
74710
+ };
74711
+ }),
74712
+ unset: (key) => gen2(function* () {
74713
+ const targetKey = yield* try_3({
74714
+ try: () => canonicalKey(key),
74715
+ catch: (error4) => toCliFailure(error4, "Invalid config key")
74716
+ });
74717
+ const cfg = yield* AppConfig;
74718
+ const parsed = yield* promise2(() => readDocDetailed(cfg.configFile));
74719
+ const { configFile, doc, exists: exists3 } = yield* try_3({
74720
+ try: () => requireParsedDoc(parsed),
74721
+ catch: (error4) => toCliFailure(error4, "Invalid config file")
74722
+ });
74723
+ if (!exists3) {
74724
+ return {
74725
+ configFile,
74726
+ key: targetKey,
74727
+ removed: false,
74728
+ fileDeleted: false
74729
+ };
74730
+ }
74731
+ const result = targetKey === "apiBaseUrl" ? unsetApiBaseUrl(doc) : { next: doc, removed: false };
74732
+ if (!result.removed) {
74733
+ return {
74734
+ configFile,
74735
+ key: targetKey,
74736
+ removed: false,
74737
+ fileDeleted: false
74738
+ };
74739
+ }
74740
+ if (isEmptyDoc(result.next)) {
74741
+ yield* tryPromise2({
74742
+ try: async () => await deleteDoc(configFile),
74743
+ catch: (error4) => new CliError({
74744
+ code: "INTERNAL",
74745
+ message: "Failed to delete config file",
74746
+ exitCode: 1,
74747
+ details: { config_file: configFile, error: String(error4?.message || error4) }
74748
+ })
74749
+ });
74750
+ return {
74751
+ configFile,
74752
+ key: targetKey,
74753
+ removed: true,
74754
+ fileDeleted: true
74755
+ };
74756
+ }
74757
+ yield* tryPromise2({
74758
+ try: async () => await writeDoc(configFile, result.next),
74759
+ catch: (error4) => new CliError({
74760
+ code: "INTERNAL",
74761
+ message: "Failed to write config file",
74762
+ exitCode: 1,
74763
+ details: { config_file: configFile, error: String(error4?.message || error4) }
74764
+ })
74765
+ });
74766
+ return {
74767
+ configFile,
74768
+ key: targetKey,
74769
+ removed: true,
74770
+ fileDeleted: false
74771
+ };
74772
+ })
74773
+ });
74774
+
74775
+ // src/services/Output.ts
74776
+ class Output extends Tag2("Output")() {
74777
+ }
74778
+ var OutputLive = succeed10(Output, {
74779
+ stdout: (text14) => sync3(() => {
74780
+ process.stdout.write(text14);
74781
+ }),
74782
+ stderr: (text14) => sync3(() => {
74783
+ process.stderr.write(text14);
74784
+ }),
74785
+ json: (value8) => sync3(() => {
74786
+ process.stdout.write(`${JSON.stringify(value8)}
74787
+ `);
74788
+ })
74789
+ });
74790
+
74791
+ // src/commands/_shared.ts
74792
+ function ensureTrailingNewline(text14) {
74793
+ return text14.endsWith(`
74794
+ `) ? text14 : `${text14}
74795
+ `;
74796
+ }
74797
+ function formatHumanErrorLine(message) {
74798
+ const trimmed2 = String(message ?? "").trim();
74799
+ if (!trimmed2)
74800
+ return "Error: Unknown error";
74801
+ return trimmed2.startsWith("Error:") ? trimmed2 : `Error: ${trimmed2}`;
74802
+ }
74803
+ function readStringArray(value8) {
74804
+ if (!Array.isArray(value8))
74805
+ return [];
74806
+ return value8.map((v) => String(v ?? "").trim()).filter(Boolean);
74807
+ }
74808
+ function writeSuccess(params3) {
74809
+ return gen2(function* () {
74810
+ const config3 = yield* AppConfig;
74811
+ const out = yield* Output;
74812
+ if (config3.format === "json") {
74813
+ yield* out.json(ok(params3.data));
74814
+ return;
74815
+ }
74816
+ if (config3.quiet)
74817
+ return;
74818
+ if (config3.format === "ids") {
74819
+ if (!params3.ids || params3.ids.length === 0) {
74820
+ return yield* fail8(new CliError({
74821
+ code: "INVALID_ARGS",
74822
+ message: "This command does not support --ids output",
74823
+ exitCode: 2
74824
+ }));
74825
+ }
74826
+ yield* out.stdout(`${params3.ids.join(`
74827
+ `)}
74828
+ `);
74829
+ return;
74830
+ }
74831
+ if (params3.data && typeof params3.data === "object") {
74832
+ const anyData = params3.data;
74833
+ const warnings = readStringArray(anyData?.warnings);
74834
+ const nextActions = readStringArray(anyData?.nextActions);
74835
+ if (warnings.length > 0) {
74836
+ yield* out.stderr(`Warnings:
74837
+ `);
74838
+ for (const w of warnings)
74839
+ yield* out.stderr(`- ${w}
74840
+ `);
74841
+ }
74842
+ if (nextActions.length > 0) {
74843
+ yield* out.stderr(`Next actions:
74844
+ `);
74845
+ for (const a of nextActions)
74846
+ yield* out.stderr(`- ${a}
74847
+ `);
74848
+ }
74849
+ }
74850
+ const md = params3.md ?? "";
74851
+ if (md.trim().length > 0) {
74852
+ yield* out.stdout(ensureTrailingNewline(md));
74853
+ }
74854
+ });
74855
+ }
74856
+ function writeFailure(error4) {
74857
+ return gen2(function* () {
74858
+ const config3 = yield* AppConfig;
74859
+ const out = yield* Output;
74860
+ if (config3.format === "json") {
74861
+ return yield* fail8(error4);
74862
+ }
74863
+ globalThis.__REMNOTE_CLI_ERROR_REPORTED__ = true;
74864
+ yield* out.stderr(ensureTrailingNewline(formatHumanErrorLine(error4.message)));
74865
+ if (config3.debug && error4.details !== undefined) {
74866
+ yield* out.stderr(`${JSON.stringify(error4.details, null, 2)}
74867
+ `);
74868
+ }
74869
+ if (error4.hint && error4.hint.length > 0) {
74870
+ yield* out.stderr(`Hint:
74871
+ `);
74872
+ for (const h of error4.hint) {
74873
+ yield* out.stderr(`- ${h}
74874
+ `);
74875
+ }
74876
+ }
74877
+ return yield* fail8(error4);
74878
+ });
73971
74879
  }
73972
74880
 
73973
- // src/lib/paths.ts
73974
- import os from "node:os";
73975
- import path3 from "node:path";
73976
- function homeDir() {
73977
- const h = os.homedir();
73978
- if (typeof h === "string" && h.trim())
73979
- return h;
73980
- return process.env.HOME || process.env.USERPROFILE || ".";
73981
- }
73982
- function expandHome(targetPath) {
73983
- const raw4 = targetPath.trim();
73984
- if (!raw4.startsWith("~"))
73985
- return raw4;
73986
- const home = homeDir();
73987
- if (raw4 === "~")
73988
- return home;
73989
- if (raw4.startsWith("~/") || raw4.startsWith("~\\")) {
73990
- return path3.join(home, raw4.slice(2));
73991
- }
73992
- return raw4.replace(/^~(?=$|[\\/])/, home);
73993
- }
73994
- function resolveUserFilePath(filePath) {
73995
- return path3.normalize(expandHome(filePath));
73996
- }
74881
+ // src/commands/config/get.ts
74882
+ var configGetCommand = exports_Command.make("get", { key: text9("key") }, ({ key }) => gen2(function* () {
74883
+ const userConfig = yield* UserConfigFile;
74884
+ const data = yield* userConfig.get(key);
74885
+ yield* writeSuccess({
74886
+ data: {
74887
+ config_file: data.configFile,
74888
+ key: data.key,
74889
+ exists: data.exists,
74890
+ value: data.value
74891
+ },
74892
+ md: data.value === null ? "" : `${data.value}
74893
+ `
74894
+ });
74895
+ }).pipe(catchAll2(writeFailure)));
74896
+
74897
+ // src/commands/config/list.ts
74898
+ var configListCommand = exports_Command.make("list", {}, () => gen2(function* () {
74899
+ const userConfig = yield* UserConfigFile;
74900
+ const inspection = yield* userConfig.inspect();
74901
+ const data = {
74902
+ config_file: inspection.configFile,
74903
+ exists: inspection.exists,
74904
+ valid: inspection.valid,
74905
+ values: inspection.values,
74906
+ unknown_keys: inspection.unknownKeys,
74907
+ errors: inspection.errors
74908
+ };
74909
+ const mdLines = [
74910
+ `- config_file: ${data.config_file}`,
74911
+ `- exists: ${data.exists}`,
74912
+ `- valid: ${data.valid}`,
74913
+ `- apiBaseUrl: ${data.values.apiBaseUrl ?? ""}`,
74914
+ `- unknown_keys: ${data.unknown_keys.join(", ")}`,
74915
+ `- errors: ${data.errors.join(" | ")}`
74916
+ ];
74917
+ yield* writeSuccess({ data, md: `${mdLines.join(`
74918
+ `)}
74919
+ ` });
74920
+ }).pipe(catchAll2(writeFailure)));
74921
+
74922
+ // src/commands/config/path.ts
74923
+ var configPathCommand = exports_Command.make("path", {}, () => gen2(function* () {
74924
+ const userConfig = yield* UserConfigFile;
74925
+ const configFile = yield* userConfig.path();
74926
+ yield* writeSuccess({
74927
+ data: { config_file: configFile },
74928
+ md: `${configFile}
74929
+ `
74930
+ });
74931
+ }).pipe(catchAll2(writeFailure)));
73997
74932
 
73998
74933
  // src/services/DaemonFiles.ts
74934
+ import { promises as fs5 } from "node:fs";
74935
+ import path8 from "node:path";
73999
74936
  class DaemonFiles extends Tag2("DaemonFiles")() {
74000
74937
  }
74001
- function ensureDir(p3) {
74002
- return fs.mkdir(path4.dirname(p3), { recursive: true }).then(() => {
74938
+ function ensureDir2(p3) {
74939
+ return fs5.mkdir(path8.dirname(p3), { recursive: true }).then(() => {
74003
74940
  return;
74004
74941
  });
74005
74942
  }
@@ -74007,19 +74944,19 @@ function defaultPidFile() {
74007
74944
  const envPidFile = process.env.REMNOTE_DAEMON_PID_FILE || process.env.DAEMON_PID_FILE;
74008
74945
  if (typeof envPidFile === "string" && envPidFile.trim())
74009
74946
  return resolveUserFilePath(envPidFile);
74010
- return path4.join(homeDir(), ".agent-remnote", "ws.pid");
74947
+ return path8.join(homeDir(), ".agent-remnote", "ws.pid");
74011
74948
  }
74012
74949
  function defaultLogFile() {
74013
74950
  const envLogFile = process.env.REMNOTE_DAEMON_LOG_FILE || process.env.DAEMON_LOG_FILE;
74014
74951
  if (typeof envLogFile === "string" && envLogFile.trim())
74015
74952
  return resolveUserFilePath(envLogFile);
74016
- return path4.join(homeDir(), ".agent-remnote", "ws.log");
74953
+ return path8.join(homeDir(), ".agent-remnote", "ws.log");
74017
74954
  }
74018
74955
  async function writeJsonAtomic(filePath, json4) {
74019
- await ensureDir(filePath);
74956
+ await ensureDir2(filePath);
74020
74957
  const tmp = `${filePath}.tmp-${process.pid}-${Date.now()}`;
74021
- await fs.writeFile(tmp, JSON.stringify(json4), "utf8");
74022
- await fs.rename(tmp, filePath);
74958
+ await fs5.writeFile(tmp, JSON.stringify(json4), "utf8");
74959
+ await fs5.rename(tmp, filePath);
74023
74960
  }
74024
74961
  var DaemonFilesLive = succeed10(DaemonFiles, {
74025
74962
  defaultPidFile: () => defaultPidFile(),
@@ -74027,7 +74964,7 @@ var DaemonFilesLive = succeed10(DaemonFiles, {
74027
74964
  readPidFile: (pidFilePath) => tryPromise2({
74028
74965
  try: async () => {
74029
74966
  try {
74030
- const raw4 = await fs.readFile(pidFilePath, "utf8");
74967
+ const raw4 = await fs5.readFile(pidFilePath, "utf8");
74031
74968
  const parsed = JSON.parse(raw4);
74032
74969
  return parsed;
74033
74970
  } catch (error4) {
@@ -74065,7 +75002,7 @@ var DaemonFilesLive = succeed10(DaemonFiles, {
74065
75002
  deletePidFile: (pidFilePath) => tryPromise2({
74066
75003
  try: async () => {
74067
75004
  try {
74068
- await fs.unlink(pidFilePath);
75005
+ await fs5.unlink(pidFilePath);
74069
75006
  } catch (error4) {
74070
75007
  if (error4?.code === "ENOENT")
74071
75008
  return;
@@ -74086,30 +75023,30 @@ var DaemonFilesLive = succeed10(DaemonFiles, {
74086
75023
  });
74087
75024
 
74088
75025
  // src/services/SupervisorState.ts
74089
- import { promises as fs2 } from "node:fs";
74090
- import path5 from "node:path";
75026
+ import { promises as fs6 } from "node:fs";
75027
+ import path9 from "node:path";
74091
75028
  class SupervisorState extends Tag2("SupervisorState")() {
74092
75029
  }
74093
- function ensureDir2(p3) {
74094
- return fs2.mkdir(path5.dirname(p3), { recursive: true }).then(() => {
75030
+ function ensureDir3(p3) {
75031
+ return fs6.mkdir(path9.dirname(p3), { recursive: true }).then(() => {
74095
75032
  return;
74096
75033
  });
74097
75034
  }
74098
75035
  function defaultStateFile() {
74099
- return path5.join(homeDir(), ".agent-remnote", "ws.state.json");
75036
+ return path9.join(homeDir(), ".agent-remnote", "ws.state.json");
74100
75037
  }
74101
75038
  async function writeJsonAtomic2(filePath, json4) {
74102
- await ensureDir2(filePath);
75039
+ await ensureDir3(filePath);
74103
75040
  const tmp = `${filePath}.tmp-${process.pid}-${Date.now()}`;
74104
- await fs2.writeFile(tmp, JSON.stringify(json4), "utf8");
74105
- await fs2.rename(tmp, filePath);
75041
+ await fs6.writeFile(tmp, JSON.stringify(json4), "utf8");
75042
+ await fs6.rename(tmp, filePath);
74106
75043
  }
74107
75044
  var SupervisorStateLive = succeed10(SupervisorState, {
74108
75045
  defaultStateFile: () => defaultStateFile(),
74109
75046
  readStateFile: (stateFilePath) => tryPromise2({
74110
75047
  try: async () => {
74111
75048
  try {
74112
- const raw4 = await fs2.readFile(stateFilePath, "utf8");
75049
+ const raw4 = await fs6.readFile(stateFilePath, "utf8");
74113
75050
  const parsed = JSON.parse(raw4);
74114
75051
  return parsed;
74115
75052
  } catch (error4) {
@@ -74117,161 +75054,55 @@ var SupervisorStateLive = succeed10(SupervisorState, {
74117
75054
  return;
74118
75055
  throw error4;
74119
75056
  }
74120
- },
74121
- catch: (error4) => {
74122
- if (isCliError(error4))
74123
- return error4;
74124
- return new CliError({
74125
- code: "INTERNAL",
74126
- message: "Failed to read supervisor state",
74127
- exitCode: 1,
74128
- details: { state_file: stateFilePath, error: String(error4?.message || error4) }
74129
- });
74130
- }
74131
- }),
74132
- writeStateFile: (stateFilePath, value8) => tryPromise2({
74133
- try: async () => {
74134
- await writeJsonAtomic2(stateFilePath, value8);
74135
- },
74136
- catch: (error4) => {
74137
- if (isCliError(error4))
74138
- return error4;
74139
- return new CliError({
74140
- code: "INTERNAL",
74141
- message: "Failed to write supervisor state",
74142
- exitCode: 1,
74143
- details: { state_file: stateFilePath, error: String(error4?.message || error4) }
74144
- });
74145
- }
74146
- }),
74147
- deleteStateFile: (stateFilePath) => tryPromise2({
74148
- try: async () => {
74149
- try {
74150
- await fs2.unlink(stateFilePath);
74151
- } catch (error4) {
74152
- if (error4?.code === "ENOENT")
74153
- return;
74154
- throw error4;
74155
- }
74156
- },
74157
- catch: (error4) => {
74158
- if (isCliError(error4))
74159
- return error4;
74160
- return new CliError({
74161
- code: "INTERNAL",
74162
- message: "Failed to delete supervisor state",
74163
- exitCode: 1,
74164
- details: { state_file: stateFilePath, error: String(error4?.message || error4) }
74165
- });
74166
- }
74167
- })
74168
- });
74169
-
74170
- // src/services/Output.ts
74171
- class Output extends Tag2("Output")() {
74172
- }
74173
- var OutputLive = succeed10(Output, {
74174
- stdout: (text14) => sync3(() => {
74175
- process.stdout.write(text14);
74176
- }),
74177
- stderr: (text14) => sync3(() => {
74178
- process.stderr.write(text14);
74179
- }),
74180
- json: (value8) => sync3(() => {
74181
- process.stdout.write(`${JSON.stringify(value8)}
74182
- `);
74183
- })
74184
- });
74185
-
74186
- // src/commands/_shared.ts
74187
- function ensureTrailingNewline(text14) {
74188
- return text14.endsWith(`
74189
- `) ? text14 : `${text14}
74190
- `;
74191
- }
74192
- function formatHumanErrorLine(message) {
74193
- const trimmed2 = String(message ?? "").trim();
74194
- if (!trimmed2)
74195
- return "Error: Unknown error";
74196
- return trimmed2.startsWith("Error:") ? trimmed2 : `Error: ${trimmed2}`;
74197
- }
74198
- function readStringArray(value8) {
74199
- if (!Array.isArray(value8))
74200
- return [];
74201
- return value8.map((v) => String(v ?? "").trim()).filter(Boolean);
74202
- }
74203
- function writeSuccess(params3) {
74204
- return gen2(function* () {
74205
- const config3 = yield* AppConfig;
74206
- const out = yield* Output;
74207
- if (config3.format === "json") {
74208
- yield* out.json(ok(params3.data));
74209
- return;
74210
- }
74211
- if (config3.quiet)
74212
- return;
74213
- if (config3.format === "ids") {
74214
- if (!params3.ids || params3.ids.length === 0) {
74215
- return yield* fail8(new CliError({
74216
- code: "INVALID_ARGS",
74217
- message: "This command does not support --ids output",
74218
- exitCode: 2
74219
- }));
74220
- }
74221
- yield* out.stdout(`${params3.ids.join(`
74222
- `)}
74223
- `);
74224
- return;
74225
- }
74226
- if (params3.data && typeof params3.data === "object") {
74227
- const anyData = params3.data;
74228
- const warnings = readStringArray(anyData?.warnings);
74229
- const nextActions = readStringArray(anyData?.nextActions);
74230
- if (warnings.length > 0) {
74231
- yield* out.stderr(`Warnings:
74232
- `);
74233
- for (const w of warnings)
74234
- yield* out.stderr(`- ${w}
74235
- `);
74236
- }
74237
- if (nextActions.length > 0) {
74238
- yield* out.stderr(`Next actions:
74239
- `);
74240
- for (const a of nextActions)
74241
- yield* out.stderr(`- ${a}
74242
- `);
74243
- }
74244
- }
74245
- const md = params3.md ?? "";
74246
- if (md.trim().length > 0) {
74247
- yield* out.stdout(ensureTrailingNewline(md));
74248
- }
74249
- });
74250
- }
74251
- function writeFailure(error4) {
74252
- return gen2(function* () {
74253
- const config3 = yield* AppConfig;
74254
- const out = yield* Output;
74255
- if (config3.format === "json") {
74256
- return yield* fail8(error4);
75057
+ },
75058
+ catch: (error4) => {
75059
+ if (isCliError(error4))
75060
+ return error4;
75061
+ return new CliError({
75062
+ code: "INTERNAL",
75063
+ message: "Failed to read supervisor state",
75064
+ exitCode: 1,
75065
+ details: { state_file: stateFilePath, error: String(error4?.message || error4) }
75066
+ });
74257
75067
  }
74258
- globalThis.__REMNOTE_CLI_ERROR_REPORTED__ = true;
74259
- yield* out.stderr(ensureTrailingNewline(formatHumanErrorLine(error4.message)));
74260
- if (config3.debug && error4.details !== undefined) {
74261
- yield* out.stderr(`${JSON.stringify(error4.details, null, 2)}
74262
- `);
75068
+ }),
75069
+ writeStateFile: (stateFilePath, value8) => tryPromise2({
75070
+ try: async () => {
75071
+ await writeJsonAtomic2(stateFilePath, value8);
75072
+ },
75073
+ catch: (error4) => {
75074
+ if (isCliError(error4))
75075
+ return error4;
75076
+ return new CliError({
75077
+ code: "INTERNAL",
75078
+ message: "Failed to write supervisor state",
75079
+ exitCode: 1,
75080
+ details: { state_file: stateFilePath, error: String(error4?.message || error4) }
75081
+ });
74263
75082
  }
74264
- if (error4.hint && error4.hint.length > 0) {
74265
- yield* out.stderr(`Hint:
74266
- `);
74267
- for (const h of error4.hint) {
74268
- yield* out.stderr(`- ${h}
74269
- `);
75083
+ }),
75084
+ deleteStateFile: (stateFilePath) => tryPromise2({
75085
+ try: async () => {
75086
+ try {
75087
+ await fs6.unlink(stateFilePath);
75088
+ } catch (error4) {
75089
+ if (error4?.code === "ENOENT")
75090
+ return;
75091
+ throw error4;
74270
75092
  }
75093
+ },
75094
+ catch: (error4) => {
75095
+ if (isCliError(error4))
75096
+ return error4;
75097
+ return new CliError({
75098
+ code: "INTERNAL",
75099
+ message: "Failed to delete supervisor state",
75100
+ exitCode: 1,
75101
+ details: { state_file: stateFilePath, error: String(error4?.message || error4) }
75102
+ });
74271
75103
  }
74272
- return yield* fail8(error4);
74273
- });
74274
- }
75104
+ })
75105
+ });
74275
75106
 
74276
75107
  // src/commands/config/print.ts
74277
75108
  var configPrintCommand = exports_Command.make("print", {}, () => gen2(function* () {
@@ -74285,6 +75116,7 @@ var configPrintCommand = exports_Command.make("print", {}, () => gen2(function*
74285
75116
  format: cfg.format,
74286
75117
  quiet: cfg.quiet,
74287
75118
  debug: cfg.debug,
75119
+ config_file: cfg.configFile,
74288
75120
  remnote_db: cfg.remnoteDb,
74289
75121
  store_db: cfg.storeDb,
74290
75122
  ws_url: cfg.wsUrl,
@@ -74299,6 +75131,13 @@ var configPrintCommand = exports_Command.make("print", {}, () => gen2(function*
74299
75131
  status_line_min_interval_ms: cfg.statusLineMinIntervalMs,
74300
75132
  status_line_debug: cfg.statusLineDebug,
74301
75133
  status_line_json_file: cfg.statusLineJsonFile,
75134
+ api_base_url: cfg.apiBaseUrl,
75135
+ api_host: cfg.apiHost,
75136
+ api_port: cfg.apiPort,
75137
+ api_base_path: cfg.apiBasePath,
75138
+ api_pid_file: cfg.apiPidFile,
75139
+ api_log_file: cfg.apiLogFile,
75140
+ api_state_file: cfg.apiStateFile,
74302
75141
  daemon_pid_file_default: daemonPidFile,
74303
75142
  daemon_log_file_default: daemonLogFile,
74304
75143
  supervisor_state_file_default: supervisorStateFile
@@ -74307,6 +75146,7 @@ var configPrintCommand = exports_Command.make("print", {}, () => gen2(function*
74307
75146
  `- format: ${data.format}`,
74308
75147
  `- quiet: ${data.quiet}`,
74309
75148
  `- debug: ${data.debug}`,
75149
+ `- config_file: ${data.config_file}`,
74310
75150
  `- remnote_db: ${data.remnote_db ?? ""}`,
74311
75151
  `- store_db: ${data.store_db}`,
74312
75152
  `- ws_url: ${data.ws_url}`,
@@ -74321,6 +75161,13 @@ var configPrintCommand = exports_Command.make("print", {}, () => gen2(function*
74321
75161
  `- status_line_min_interval_ms: ${data.status_line_min_interval_ms}`,
74322
75162
  `- status_line_debug: ${data.status_line_debug}`,
74323
75163
  `- status_line_json_file: ${data.status_line_json_file}`,
75164
+ `- api_base_url: ${data.api_base_url ?? ""}`,
75165
+ `- api_host: ${data.api_host ?? ""}`,
75166
+ `- api_port: ${data.api_port ?? ""}`,
75167
+ `- api_base_path: ${data.api_base_path ?? ""}`,
75168
+ `- api_pid_file: ${data.api_pid_file ?? ""}`,
75169
+ `- api_log_file: ${data.api_log_file ?? ""}`,
75170
+ `- api_state_file: ${data.api_state_file ?? ""}`,
74324
75171
  `- daemon_pid_file_default: ${data.daemon_pid_file_default}`,
74325
75172
  `- daemon_log_file_default: ${data.daemon_log_file_default}`,
74326
75173
  `- supervisor_state_file_default: ${data.supervisor_state_file_default}`
@@ -74329,38 +75176,102 @@ var configPrintCommand = exports_Command.make("print", {}, () => gen2(function*
74329
75176
  yield* writeSuccess({ data, md });
74330
75177
  }).pipe(catchAll2(writeFailure)));
74331
75178
 
75179
+ // src/commands/config/set.ts
75180
+ var configSetCommand = exports_Command.make("set", { key: text9("key"), value: text9("value") }, ({ key, value: value8 }) => gen2(function* () {
75181
+ const userConfig = yield* UserConfigFile;
75182
+ const data = yield* userConfig.set(key, value8);
75183
+ yield* writeSuccess({
75184
+ data: {
75185
+ config_file: data.configFile,
75186
+ key: data.key,
75187
+ value: data.value,
75188
+ changed: data.changed
75189
+ },
75190
+ md: `${data.key}=${data.value}
75191
+ `
75192
+ });
75193
+ }).pipe(catchAll2(writeFailure)));
75194
+
75195
+ // src/commands/config/unset.ts
75196
+ var configUnsetCommand = exports_Command.make("unset", { key: text9("key") }, ({ key }) => gen2(function* () {
75197
+ const userConfig = yield* UserConfigFile;
75198
+ const data = yield* userConfig.unset(key);
75199
+ yield* writeSuccess({
75200
+ data: {
75201
+ config_file: data.configFile,
75202
+ key: data.key,
75203
+ removed: data.removed,
75204
+ file_deleted: data.fileDeleted
75205
+ },
75206
+ md: `${data.key} removed=${data.removed}
75207
+ `
75208
+ });
75209
+ }).pipe(catchAll2(writeFailure)));
75210
+
75211
+ // src/commands/config/validate.ts
75212
+ var configValidateCommand = exports_Command.make("validate", {}, () => gen2(function* () {
75213
+ const userConfig = yield* UserConfigFile;
75214
+ const inspection = yield* userConfig.inspect();
75215
+ const data = {
75216
+ config_file: inspection.configFile,
75217
+ exists: inspection.exists,
75218
+ valid: inspection.valid,
75219
+ values: inspection.values,
75220
+ unknown_keys: inspection.unknownKeys,
75221
+ errors: inspection.errors
75222
+ };
75223
+ const mdLines = [
75224
+ `- config_file: ${data.config_file}`,
75225
+ `- exists: ${data.exists}`,
75226
+ `- valid: ${data.valid}`,
75227
+ `- unknown_keys: ${data.unknown_keys.join(", ")}`,
75228
+ `- errors: ${data.errors.join(" | ")}`
75229
+ ];
75230
+ yield* writeSuccess({ data, md: `${mdLines.join(`
75231
+ `)}
75232
+ ` });
75233
+ }).pipe(catchAll2(writeFailure)));
75234
+
74332
75235
  // src/commands/config/index.ts
74333
- var configCommand = exports_Command.make("config", {}).pipe(exports_Command.withSubcommands([configPrintCommand]));
75236
+ var configCommand = exports_Command.make("config", {}).pipe(exports_Command.withSubcommands([
75237
+ configPrintCommand,
75238
+ configPathCommand,
75239
+ configListCommand,
75240
+ configGetCommand,
75241
+ configSetCommand,
75242
+ configUnsetCommand,
75243
+ configValidateCommand
75244
+ ]));
74334
75245
 
74335
75246
  // src/services/FsAccess.ts
74336
- import { constants as FS_CONSTANTS, promises as fs3 } from "node:fs";
74337
- import path6 from "node:path";
75247
+ import { constants as FS_CONSTANTS, promises as fs7 } from "node:fs";
75248
+ import path10 from "node:path";
74338
75249
 
74339
75250
  class FsAccess extends Tag2("FsAccess")() {
74340
75251
  }
74341
75252
  async function canWritePath(filePath) {
74342
75253
  try {
74343
- await fs3.mkdir(path6.dirname(filePath), { recursive: true });
74344
- await fs3.access(path6.dirname(filePath), FS_CONSTANTS.W_OK);
75254
+ await fs7.mkdir(path10.dirname(filePath), { recursive: true });
75255
+ await fs7.access(path10.dirname(filePath), FS_CONSTANTS.W_OK);
74345
75256
  return true;
74346
75257
  } catch {
74347
75258
  return false;
74348
75259
  }
74349
75260
  }
74350
75261
  async function checkWritableFile(filePath) {
74351
- const dir2 = path6.dirname(filePath);
75262
+ const dir2 = path10.dirname(filePath);
74352
75263
  try {
74353
- await fs3.mkdir(dir2, { recursive: true });
75264
+ await fs7.mkdir(dir2, { recursive: true });
74354
75265
  } catch (e) {
74355
75266
  return { ok: false, reason: `failed_to_create_dir: ${String(e?.message || e)}` };
74356
75267
  }
74357
75268
  try {
74358
- await fs3.access(dir2, FS_CONSTANTS.W_OK);
75269
+ await fs7.access(dir2, FS_CONSTANTS.W_OK);
74359
75270
  } catch (e) {
74360
75271
  return { ok: false, reason: `dir_not_writable: ${String(e?.message || e)}` };
74361
75272
  }
74362
75273
  try {
74363
- await fs3.access(filePath, FS_CONSTANTS.W_OK);
75274
+ await fs7.access(filePath, FS_CONSTANTS.W_OK);
74364
75275
  return { ok: true };
74365
75276
  } catch {
74366
75277
  return { ok: true };
@@ -74369,7 +75280,7 @@ async function checkWritableFile(filePath) {
74369
75280
  var FsAccessLive = succeed10(FsAccess, {
74370
75281
  isFile: (filePath) => tryPromise2({
74371
75282
  try: async () => {
74372
- const st = await fs3.stat(filePath);
75283
+ const st = await fs7.stat(filePath);
74373
75284
  return st.isFile();
74374
75285
  },
74375
75286
  catch: (e) => e
@@ -74466,65 +75377,6 @@ function refreshTmuxStatusLine() {
74466
75377
  requestTmuxStatusLineRefresh("immediate");
74467
75378
  }
74468
75379
 
74469
- // src/lib/wsState.ts
74470
- import fs4 from "node:fs";
74471
- import path7 from "node:path";
74472
- function defaultStateFilePath() {
74473
- return path7.join(homeDir(), ".agent-remnote", "ws.bridge.state.json");
74474
- }
74475
- function resolveStateFilePath(explicit) {
74476
- if (explicit && explicit.trim())
74477
- return { disabled: false, path: resolveUserFilePath(explicit) };
74478
- const raw4 = String(process.env.REMNOTE_WS_STATE_FILE || process.env.WS_STATE_FILE || "").trim();
74479
- if (raw4 === "0" || raw4.toLowerCase() === "false")
74480
- return { disabled: true, path: defaultStateFilePath() };
74481
- if (raw4)
74482
- return { disabled: false, path: resolveUserFilePath(raw4) };
74483
- return { disabled: false, path: defaultStateFilePath() };
74484
- }
74485
- function readJson(filePath) {
74486
- try {
74487
- const txt = fs4.readFileSync(filePath, "utf8");
74488
- return JSON.parse(txt);
74489
- } catch {
74490
- return null;
74491
- }
74492
- }
74493
- function pickClient(clients, connId) {
74494
- const target2 = (connId || "").trim();
74495
- if (target2) {
74496
- const found = clients.find((c) => c && typeof c === "object" && c.connId === target2);
74497
- if (found)
74498
- return found;
74499
- }
74500
- const active2 = clients.find((c) => c && typeof c === "object" && c.isActiveWorker === true);
74501
- if (active2)
74502
- return active2;
74503
- let best = null;
74504
- let bestScore = -1;
74505
- for (const c of clients) {
74506
- if (!c || typeof c !== "object")
74507
- continue;
74508
- const selAt = Number(c.selection?.updatedAt ?? 0);
74509
- const ctxAt = Number(c.uiContext?.updatedAt ?? 0);
74510
- const score = Math.max(selAt, ctxAt);
74511
- if (score > bestScore) {
74512
- bestScore = score;
74513
- best = c;
74514
- }
74515
- }
74516
- return best;
74517
- }
74518
- function resolveStaleMs(explicit) {
74519
- if (typeof explicit === "number" && Number.isFinite(explicit) && explicit > 0)
74520
- return Math.floor(explicit);
74521
- const raw4 = process.env.REMNOTE_WS_STATE_STALE_MS || process.env.WS_STATE_STALE_MS;
74522
- const n = Number(raw4);
74523
- if (Number.isFinite(n) && n > 0)
74524
- return Math.floor(n);
74525
- return 60000;
74526
- }
74527
-
74528
75380
  // src/lib/wsBridgeNextActions.ts
74529
75381
  function buildDbFallbackNextAction(queryText) {
74530
75382
  const q = String(queryText || "").replace(/\s+/g, " ").trim();
@@ -74536,21 +75388,21 @@ function buildDbFallbackNextAction(queryText) {
74536
75388
  }
74537
75389
 
74538
75390
  // src/lib/wsDebug.ts
74539
- import fs5 from "node:fs";
74540
- import path8 from "node:path";
75391
+ import fs8 from "node:fs";
75392
+ import path11 from "node:path";
74541
75393
  function envDebug() {
74542
75394
  const v = (process.env.REMNOTE_WS_DEBUG || process.env.WS_DEBUG || "").toLowerCase();
74543
75395
  return v === "1" || v === "true";
74544
75396
  }
74545
75397
  function envLogFilePath(params3) {
74546
75398
  const p3 = process.env.REMNOTE_WS_LOGFILE || process.env.WS_LOGFILE || "";
74547
- const def = params3.debug ? path8.join(homeDir(), ".agent-remnote", "ws-debug.log") : "";
75399
+ const def = params3.debug ? path11.join(homeDir(), ".agent-remnote", "ws-debug.log") : "";
74548
75400
  const out = p3 && p3.trim() || def;
74549
75401
  if (!out)
74550
75402
  return;
74551
75403
  try {
74552
75404
  const resolved = resolveUserFilePath(out);
74553
- fs5.mkdirSync(path8.dirname(resolved), { recursive: true });
75405
+ fs8.mkdirSync(path11.dirname(resolved), { recursive: true });
74554
75406
  return resolved;
74555
75407
  } catch {
74556
75408
  return;
@@ -74582,19 +75434,19 @@ function wsLog(level, msg, ctx) {
74582
75434
  if (!LOG_FILE)
74583
75435
  return;
74584
75436
  try {
74585
- fs5.appendFileSync(LOG_FILE, `${new Date().toISOString()} ${line4}
75437
+ fs8.appendFileSync(LOG_FILE, `${new Date().toISOString()} ${line4}
74586
75438
  `);
74587
75439
  } catch {}
74588
75440
  }
74589
75441
 
74590
75442
  // src/internal/queue/db.ts
74591
- import path10 from "node:path";
75443
+ import path13 from "node:path";
74592
75444
 
74593
75445
  // src/internal/store/db.ts
74594
75446
  import Database from "better-sqlite3";
74595
75447
  import { createHash, randomUUID } from "node:crypto";
74596
75448
  import { constants as constants2, copyFileSync, existsSync, mkdirSync, readFileSync, rmSync } from "node:fs";
74597
- import path9 from "node:path";
75449
+ import path12 from "node:path";
74598
75450
 
74599
75451
  // src/internal/store/migrations/0001-baseline.ts
74600
75452
  var migration = {
@@ -74831,7 +75683,7 @@ CREATE TABLE IF NOT EXISTS queue_consumers (
74831
75683
  );
74832
75684
  `;
74833
75685
  function absoluteDefaultStorePath() {
74834
- return path9.join(homeDir(), ".agent-remnote", "store.sqlite");
75686
+ return path12.join(homeDir(), ".agent-remnote", "store.sqlite");
74835
75687
  }
74836
75688
  function defaultStorePath() {
74837
75689
  const env2 = process.env.REMNOTE_STORE_DB || process.env.STORE_DB;
@@ -74843,15 +75695,15 @@ function defaultLegacyQueuePath() {
74843
75695
  const env2 = process.env.REMNOTE_QUEUE_DB || process.env.QUEUE_DB;
74844
75696
  if (typeof env2 === "string" && env2.trim())
74845
75697
  return resolveUserFilePath(env2);
74846
- return path9.join(homeDir(), ".agent-remnote", "queue.sqlite");
75698
+ return path12.join(homeDir(), ".agent-remnote", "queue.sqlite");
74847
75699
  }
74848
- function ensureDir3(filePath) {
74849
- const dir2 = path9.dirname(filePath);
75700
+ function ensureDir4(filePath) {
75701
+ const dir2 = path12.dirname(filePath);
74850
75702
  mkdirSync(dir2, { recursive: true });
74851
75703
  }
74852
75704
  function openStoreDb(dbPath = defaultStorePath()) {
74853
75705
  const resolvedPath = resolveUserFilePath(dbPath);
74854
- ensureDir3(resolvedPath);
75706
+ ensureDir4(resolvedPath);
74855
75707
  maybeInitializeDefaultStoreFromLegacy(resolvedPath, { callerProvidedPath: dbPath });
74856
75708
  const db = new Database(resolvedPath);
74857
75709
  db.pragma("busy_timeout = 5000");
@@ -75176,7 +76028,7 @@ function maybeInitializeDefaultStoreFromLegacy(resolvedStorePath, params3) {
75176
76028
  if (!existsSync(legacyPath))
75177
76029
  return;
75178
76030
  const tmpPath = `${resolvedStorePath}.tmp.${process.pid}.${randomUUID()}`;
75179
- ensureDir3(tmpPath);
76031
+ ensureDir4(tmpPath);
75180
76032
  try {
75181
76033
  const source = new Database(legacyPath, { readonly: true });
75182
76034
  try {
@@ -75215,10 +76067,10 @@ function defaultQueuePath() {
75215
76067
  const env2 = process.env.REMNOTE_QUEUE_DB || process.env.QUEUE_DB;
75216
76068
  if (typeof env2 === "string" && env2.trim())
75217
76069
  return resolveUserFilePath(env2);
75218
- return path10.join(homeDir(), ".agent-remnote", "queue.sqlite");
76070
+ return path13.join(homeDir(), ".agent-remnote", "queue.sqlite");
75219
76071
  }
75220
- function ensureDir4(filePath) {
75221
- ensureDir3(filePath);
76072
+ function ensureDir5(filePath) {
76073
+ ensureDir4(filePath);
75222
76074
  }
75223
76075
  function queueErrorFromStoreSchema(dbPath, error4) {
75224
76076
  const code2 = error4.code === "STORE_SCHEMA_NEWER" ? "QUEUE_SCHEMA_NEWER" : error4.code === "STORE_SCHEMA_INVALID" ? "QUEUE_SCHEMA_INVALID" : "QUEUE_SCHEMA_UNKNOWN";
@@ -75231,7 +76083,7 @@ function queueErrorFromStoreSchema(dbPath, error4) {
75231
76083
  }
75232
76084
  function openQueueDb(dbPath = defaultQueuePath()) {
75233
76085
  const resolvedPath = resolveUserFilePath(dbPath);
75234
- ensureDir4(resolvedPath);
76086
+ ensureDir5(resolvedPath);
75235
76087
  try {
75236
76088
  return openStoreDb(resolvedPath);
75237
76089
  } catch (e) {
@@ -75523,18 +76375,18 @@ function getFirstString(payload, keys8) {
75523
76375
  }
75524
76376
  return null;
75525
76377
  }
75526
- function getFirstStringFromNested(payload, path11) {
76378
+ function getFirstStringFromNested(payload, path14) {
75527
76379
  let cur = payload;
75528
- for (const k of path11) {
76380
+ for (const k of path14) {
75529
76381
  if (!cur || typeof cur !== "object")
75530
76382
  return null;
75531
76383
  cur = cur[k];
75532
76384
  }
75533
76385
  return asNonEmptyString(cur);
75534
76386
  }
75535
- function getStringArrayFromNested(payload, path11) {
76387
+ function getStringArrayFromNested(payload, path14) {
75536
76388
  let cur = payload;
75537
- for (const k of path11) {
76389
+ for (const k of path14) {
75538
76390
  if (!cur || typeof cur !== "object")
75539
76391
  return [];
75540
76392
  cur = cur[k];
@@ -76647,38 +77499,38 @@ function idFieldPathsForOpType(opTypeRaw) {
76647
77499
  return Array.isArray(entry.id_fields) ? entry.id_fields : [];
76648
77500
  }
76649
77501
  // src/kernel/op-catalog/pathWalk.ts
76650
- function parsePathTokens(path11) {
76651
- return path11.split(".").map((part) => part.trim()).filter(Boolean).map((part) => {
77502
+ function parsePathTokens(path14) {
77503
+ return path14.split(".").map((part) => part.trim()).filter(Boolean).map((part) => {
76652
77504
  const isArray2 = part.endsWith("[]");
76653
77505
  const key = isArray2 ? part.slice(0, -2).trim() : part;
76654
77506
  return { key, isArray: isArray2 };
76655
77507
  }).filter((token) => token.key.length > 0);
76656
77508
  }
76657
- function collectLeafValues(value8, path11, idx = 0) {
76658
- if (idx >= path11.length)
77509
+ function collectLeafValues(value8, path14, idx = 0) {
77510
+ if (idx >= path14.length)
76659
77511
  return [value8];
76660
77512
  if (!value8 || typeof value8 !== "object")
76661
77513
  return [];
76662
- const token = path11[idx];
77514
+ const token = path14[idx];
76663
77515
  const next4 = value8[token.key];
76664
77516
  if (token.isArray) {
76665
77517
  if (!Array.isArray(next4))
76666
77518
  return [];
76667
77519
  const out = [];
76668
77520
  for (const item of next4) {
76669
- out.push(...collectLeafValues(item, path11, idx + 1));
77521
+ out.push(...collectLeafValues(item, path14, idx + 1));
76670
77522
  }
76671
77523
  return out;
76672
77524
  }
76673
- return collectLeafValues(next4, path11, idx + 1);
77525
+ return collectLeafValues(next4, path14, idx + 1);
76674
77526
  }
76675
- function mapLeafValuesInPlace(value8, path11, mapFn, idx = 0) {
76676
- if (idx >= path11.length)
77527
+ function mapLeafValuesInPlace(value8, path14, mapFn, idx = 0) {
77528
+ if (idx >= path14.length)
76677
77529
  return;
76678
77530
  if (!value8 || typeof value8 !== "object")
76679
77531
  return;
76680
- const token = path11[idx];
76681
- const isLeaf = idx === path11.length - 1;
77532
+ const token = path14[idx];
77533
+ const isLeaf = idx === path14.length - 1;
76682
77534
  if (token.isArray) {
76683
77535
  const next4 = value8[token.key];
76684
77536
  if (!Array.isArray(next4))
@@ -76688,7 +77540,7 @@ function mapLeafValuesInPlace(value8, path11, mapFn, idx = 0) {
76688
77540
  return;
76689
77541
  }
76690
77542
  for (const item of next4) {
76691
- mapLeafValuesInPlace(item, path11, mapFn, idx + 1);
77543
+ mapLeafValuesInPlace(item, path14, mapFn, idx + 1);
76692
77544
  }
76693
77545
  return;
76694
77546
  }
@@ -76696,7 +77548,7 @@ function mapLeafValuesInPlace(value8, path11, mapFn, idx = 0) {
76696
77548
  value8[token.key] = mapFn(value8[token.key]);
76697
77549
  return;
76698
77550
  }
76699
- mapLeafValuesInPlace(value8[token.key], path11, mapFn, idx + 1);
77551
+ mapLeafValuesInPlace(value8[token.key], path14, mapFn, idx + 1);
76700
77552
  }
76701
77553
 
76702
77554
  // src/kernel/op-catalog/substituteIds.ts
@@ -76718,8 +77570,8 @@ function collectTempIdsFromPayload(opTypeRaw, payload) {
76718
77570
  if (!payload || typeof payload !== "object")
76719
77571
  return [];
76720
77572
  const out = [];
76721
- for (const path11 of idFieldPathsForOpType(opTypeRaw)) {
76722
- const tokens = parsePathTokens(path11);
77573
+ for (const path14 of idFieldPathsForOpType(opTypeRaw)) {
77574
+ const tokens = parsePathTokens(path14);
76723
77575
  if (tokens.length === 0)
76724
77576
  continue;
76725
77577
  const values5 = collectLeafValues(payload, tokens);
@@ -76734,8 +77586,8 @@ function substituteTempIdsInPayload(opTypeRaw, payload, idMap) {
76734
77586
  if (!payload || typeof payload !== "object")
76735
77587
  return payload;
76736
77588
  const out = cloneJson(payload);
76737
- for (const path11 of idFieldPathsForOpType(opTypeRaw)) {
76738
- const tokens = parsePathTokens(path11);
77589
+ for (const path14 of idFieldPathsForOpType(opTypeRaw)) {
77590
+ const tokens = parsePathTokens(path14);
76739
77591
  if (tokens.length === 0)
76740
77592
  continue;
76741
77593
  mapLeafValuesInPlace(out, tokens, (value8) => {
@@ -78006,8 +78858,8 @@ function toWsBridgeClient2(client) {
78006
78858
  var GLOBAL_BRIDGE_KEY = Symbol.for("__REMNOTE_WS_BRIDGE__");
78007
78859
  // src/internal/remdb-tools/shared.ts
78008
78860
  import BetterSqlite3 from "better-sqlite3";
78009
- import { promises as fs6 } from "fs";
78010
- import path11 from "path";
78861
+ import { promises as fs9 } from "fs";
78862
+ import path14 from "path";
78011
78863
 
78012
78864
  // ../../node_modules/date-fns/constants.js
78013
78865
  var daysInYear = 365.2425;
@@ -79496,18 +80348,18 @@ async function withResolvedDatabase(dbPath, fn) {
79496
80348
  async function resolveDatabasePath(dbPath) {
79497
80349
  if (dbPath) {
79498
80350
  const expanded = expandHome2(dbPath.trim());
79499
- const stat3 = await fs6.stat(expanded);
80351
+ const stat3 = await fs9.stat(expanded);
79500
80352
  if (!stat3.isFile()) {
79501
80353
  throw new Error(`${expanded} is not a file`);
79502
80354
  }
79503
80355
  return {
79504
80356
  dbPath: expanded,
79505
80357
  source: "explicit",
79506
- baseDir: path11.dirname(expanded)
80358
+ baseDir: path14.dirname(expanded)
79507
80359
  };
79508
80360
  }
79509
- const baseDir = path11.join(homeDir(), REMNOTE_RELATIVE_DIR);
79510
- const entries2 = await fs6.readdir(baseDir, { withFileTypes: true }).catch(() => {
80361
+ const baseDir = path14.join(homeDir(), REMNOTE_RELATIVE_DIR);
80362
+ const entries2 = await fs9.readdir(baseDir, { withFileTypes: true }).catch(() => {
79511
80363
  throw new Error(`RemNote directory ${baseDir} not found – please specify dbPath manually`);
79512
80364
  });
79513
80365
  const candidates = [];
@@ -79520,9 +80372,9 @@ async function resolveDatabasePath(dbPath) {
79520
80372
  const isSecondary = SECONDARY_DIRS.has(entry.name);
79521
80373
  if (!isPrimary && !isSecondary)
79522
80374
  continue;
79523
- const candidatePath = path11.join(baseDir, entry.name, REMNOTE_DB_NAME);
80375
+ const candidatePath = path14.join(baseDir, entry.name, REMNOTE_DB_NAME);
79524
80376
  try {
79525
- const stat3 = await fs6.stat(candidatePath);
80377
+ const stat3 = await fs9.stat(candidatePath);
79526
80378
  candidates.push({
79527
80379
  dbPath: candidatePath,
79528
80380
  dirName: entry.name,
@@ -79553,18 +80405,18 @@ async function discoverBackups(basePath) {
79553
80405
  const backups = [];
79554
80406
  let entries2;
79555
80407
  try {
79556
- entries2 = await fs6.readdir(basePath, { withFileTypes: true });
80408
+ entries2 = await fs9.readdir(basePath, { withFileTypes: true });
79557
80409
  } catch (error4) {
79558
80410
  throw new Error(`Unable to read ${basePath}: ${String(error4)}`);
79559
80411
  }
79560
80412
  for (const entry of entries2) {
79561
80413
  if (!entry.isDirectory())
79562
80414
  continue;
79563
- const accountDir = path11.join(basePath, entry.name);
79564
- const backupDir = path11.join(accountDir, "backups");
80415
+ const accountDir = path14.join(basePath, entry.name);
80416
+ const backupDir = path14.join(accountDir, "backups");
79565
80417
  let backupFiles;
79566
80418
  try {
79567
- backupFiles = await fs6.readdir(backupDir, { withFileTypes: true });
80419
+ backupFiles = await fs9.readdir(backupDir, { withFileTypes: true });
79568
80420
  } catch {
79569
80421
  continue;
79570
80422
  }
@@ -79573,8 +80425,8 @@ async function discoverBackups(basePath) {
79573
80425
  continue;
79574
80426
  if (!file6.name.endsWith(".db") && !file6.name.endsWith(".db.zip"))
79575
80427
  continue;
79576
- const fullPath = path11.join(backupDir, file6.name);
79577
- const stat3 = await fs6.stat(fullPath);
80428
+ const fullPath = path14.join(backupDir, file6.name);
80429
+ const stat3 = await fs9.stat(fullPath);
79578
80430
  backups.push({
79579
80431
  accountDir: entry.name,
79580
80432
  file: file6.name,
@@ -79695,8 +80547,8 @@ function parseOrThrow(schema2, input, options6) {
79695
80547
  throw new Error(prefix2 + lines3.join("; "));
79696
80548
  }
79697
80549
  function formatZodIssueEN(issue) {
79698
- const path12 = issue.path && issue.path.length > 0 ? issue.path.join(".") : undefined;
79699
- const where = path12 ? `field ${path12}: ` : "";
80550
+ const path15 = issue.path && issue.path.length > 0 ? issue.path.join(".") : undefined;
80551
+ const where = path15 ? `field ${path15}: ` : "";
79700
80552
  switch (issue.code) {
79701
80553
  case "invalid_type": {
79702
80554
  const expected = toENType(issue.expected);
@@ -80148,8 +81000,8 @@ function getErrorMap() {
80148
81000
  return overrideErrorMap;
80149
81001
  }
80150
81002
  var makeIssue = (params3) => {
80151
- const { data, path: path12, errorMaps, issueData } = params3;
80152
- const fullPath = [...path12, ...issueData.path || []];
81003
+ const { data, path: path15, errorMaps, issueData } = params3;
81004
+ const fullPath = [...path15, ...issueData.path || []];
80153
81005
  const fullIssue = {
80154
81006
  ...issueData,
80155
81007
  path: fullPath
@@ -80277,11 +81129,11 @@ var _ZodEnum_cache;
80277
81129
  var _ZodNativeEnum_cache;
80278
81130
 
80279
81131
  class ParseInputLazyPath {
80280
- constructor(parent, value8, path12, key) {
81132
+ constructor(parent, value8, path15, key) {
80281
81133
  this._cachedPath = [];
80282
81134
  this.parent = parent;
80283
81135
  this.data = value8;
80284
- this._path = path12;
81136
+ this._path = path15;
80285
81137
  this._key = key;
80286
81138
  }
80287
81139
  get path() {
@@ -83658,7 +84510,7 @@ var z = /* @__PURE__ */ Object.freeze({
83658
84510
  });
83659
84511
 
83660
84512
  // src/internal/remdb-tools/listRemBackups.ts
83661
- import path12 from "node:path";
84513
+ import path15 from "node:path";
83662
84514
  var inputShape = {
83663
84515
  basePath: z.string().optional().describe("RemNote base directory (default: ~/remnote)"),
83664
84516
  limit: z.number().int().min(1).max(200).optional().describe("Max backups to return (default 50)")
@@ -83666,7 +84518,7 @@ var inputShape = {
83666
84518
  var listRemBackupsSchema = z.object(inputShape);
83667
84519
  async function executeListRemBackups(params3) {
83668
84520
  const parsed = parseOrThrow(listRemBackupsSchema, params3, { label: "list_rem_backups" });
83669
- const basePath = expandHome2(parsed.basePath ?? path12.join(homeDir(), REMNOTE_RELATIVE_DIR));
84521
+ const basePath = expandHome2(parsed.basePath ?? path15.join(homeDir(), REMNOTE_RELATIVE_DIR));
83670
84522
  const backups = await discoverBackups(basePath);
83671
84523
  const limit = parsed.limit ?? 50;
83672
84524
  return {
@@ -85416,10 +86268,10 @@ function fetchDocs(db, rootId, includeDescendants, maxDepth) {
85416
86268
  }
85417
86269
  return rows.map((row) => convertRow(row.id, row.doc));
85418
86270
  }
85419
- function collectReferences(value8, remId, path13, into3) {
86271
+ function collectReferences(value8, remId, path16, into3) {
85420
86272
  if (Array.isArray(value8)) {
85421
86273
  value8.forEach((item, index) => {
85422
- collectReferences(item, remId, [...path13, index], into3);
86274
+ collectReferences(item, remId, [...path16, index], into3);
85423
86275
  });
85424
86276
  return;
85425
86277
  }
@@ -85429,7 +86281,7 @@ function collectReferences(value8, remId, path13, into3) {
85429
86281
  into3.push({
85430
86282
  refId: maybeRef._id,
85431
86283
  remId,
85432
- path: formatPath2(path13),
86284
+ path: formatPath2(path16),
85433
86285
  tokenKind: classifyToken(maybeRef)
85434
86286
  });
85435
86287
  return;
@@ -85438,13 +86290,13 @@ function collectReferences(value8, remId, path13, into3) {
85438
86290
  into3.push({
85439
86291
  refId: maybeRef._id,
85440
86292
  remId,
85441
- path: formatPath2(path13),
86293
+ path: formatPath2(path16),
85442
86294
  tokenKind: classifyToken(maybeRef)
85443
86295
  });
85444
86296
  return;
85445
86297
  }
85446
86298
  for (const [key, child] of Object.entries(maybeRef)) {
85447
- collectReferences(child, remId, [...path13, key], into3);
86299
+ collectReferences(child, remId, [...path16, key], into3);
85448
86300
  }
85449
86301
  }
85450
86302
  }
@@ -85561,8 +86413,8 @@ function buildReferencesMarkdown(remId, guidance, outbound, inbound, includeInbo
85561
86413
  const tokenKind = Array.isArray(ref.tokenKinds) ? `type: ${formatTokenKinds(ref.tokenKinds)}` : "";
85562
86414
  const ancestor = ref.ancestor ? `, ancestor: ${ref.ancestor}` : "";
85563
86415
  const count4 = typeof ref.count === "number" ? `${ref.count} occurrences` : "";
85564
- const path13 = ref.occurrences ? ref.occurrences[0]?.path ?? null : ref.representativePath;
85565
- const samplePath = path13 ? `, sample path: ${path13}` : "";
86416
+ const path16 = ref.occurrences ? ref.occurrences[0]?.path ?? null : ref.representativePath;
86417
+ const samplePath = path16 ? `, sample path: ${path16}` : "";
85566
86418
  lines3.push(`- **${name}** (ID: ${ref.refId}, ${count4}${ancestor}${samplePath}${tokenKind ? `, ${tokenKind}` : ""})`);
85567
86419
  });
85568
86420
  }
@@ -89072,16 +89924,16 @@ var WsClientLive = succeed10(WsClient, {
89072
89924
  });
89073
89925
 
89074
89926
  // src/commands/ws/_shared.ts
89075
- import path14 from "node:path";
89927
+ import path17 from "node:path";
89076
89928
 
89077
89929
  // src/services/Process.ts
89078
89930
  import { spawn as spawn3 } from "node:child_process";
89079
- import fs7 from "node:fs";
89080
- import path13 from "node:path";
89931
+ import fs10 from "node:fs";
89932
+ import path16 from "node:path";
89081
89933
  class Process extends Tag2("Process")() {
89082
89934
  }
89083
89935
  function ensureDirSync(filePath) {
89084
- fs7.mkdirSync(path13.dirname(filePath), { recursive: true });
89936
+ fs10.mkdirSync(path16.dirname(filePath), { recursive: true });
89085
89937
  }
89086
89938
  var ProcessLive = succeed10(Process, {
89087
89939
  isPidRunning: (pid) => sync3(() => {
@@ -89099,7 +89951,7 @@ var ProcessLive = succeed10(Process, {
89099
89951
  spawnDetached: (params3) => try_3({
89100
89952
  try: () => {
89101
89953
  ensureDirSync(params3.logFile);
89102
- const fd = fs7.openSync(params3.logFile, "a");
89954
+ const fd = fs10.openSync(params3.logFile, "a");
89103
89955
  const child = spawn3(params3.command, [...params3.args], {
89104
89956
  cwd: params3.cwd,
89105
89957
  env: params3.env,
@@ -89253,7 +90105,7 @@ function toInitialSupervisorState(now2) {
89253
90105
  };
89254
90106
  }
89255
90107
  function defaultStateFilePathFromPidFile(pidFilePath) {
89256
- return path14.join(path14.dirname(pidFilePath), "ws.state.json");
90108
+ return path17.join(path17.dirname(pidFilePath), "ws.state.json");
89257
90109
  }
89258
90110
  function startWsSupervisor(params3) {
89259
90111
  return gen2(function* () {
@@ -89740,30 +90592,30 @@ var wsLogsCommand = exports_Command.make("logs", {
89740
90592
  }).pipe(catchAll2(writeFailure)));
89741
90593
 
89742
90594
  // src/commands/ws/restart.ts
89743
- import path16 from "node:path";
90595
+ import path19 from "node:path";
89744
90596
 
89745
90597
  // src/lib/statuslineArtifacts.ts
89746
- import { promises as fs9 } from "node:fs";
90598
+ import { promises as fs12 } from "node:fs";
89747
90599
 
89748
90600
  // src/services/StatusLineFile.ts
89749
- import { promises as fs8 } from "node:fs";
89750
- import path15 from "node:path";
90601
+ import { promises as fs11 } from "node:fs";
90602
+ import path18 from "node:path";
89751
90603
  class StatusLineFile extends Tag2("StatusLineFile")() {
89752
90604
  }
89753
90605
  function defaultTextFile() {
89754
- return path15.join(homeDir(), ".agent-remnote", "status-line.txt");
90606
+ return path18.join(homeDir(), ".agent-remnote", "status-line.txt");
89755
90607
  }
89756
90608
  function defaultJsonFile() {
89757
- return path15.join(homeDir(), ".agent-remnote", "status-line.json");
90609
+ return path18.join(homeDir(), ".agent-remnote", "status-line.json");
89758
90610
  }
89759
- function ensureDir5(p3) {
89760
- return fs8.mkdir(path15.dirname(p3), { recursive: true }).then(() => {
90611
+ function ensureDir6(p3) {
90612
+ return fs11.mkdir(path18.dirname(p3), { recursive: true }).then(() => {
89761
90613
  return;
89762
90614
  });
89763
90615
  }
89764
90616
  async function readFileOrEmpty(filePath) {
89765
90617
  try {
89766
- return await fs8.readFile(filePath, "utf8");
90618
+ return await fs11.readFile(filePath, "utf8");
89767
90619
  } catch (e) {
89768
90620
  if (e?.code === "ENOENT")
89769
90621
  return "";
@@ -89771,10 +90623,10 @@ async function readFileOrEmpty(filePath) {
89771
90623
  }
89772
90624
  }
89773
90625
  async function writeTextAtomic(filePath, content) {
89774
- await ensureDir5(filePath);
90626
+ await ensureDir6(filePath);
89775
90627
  const tmp = `${filePath}.tmp-${process.pid}-${Date.now()}`;
89776
- await fs8.writeFile(tmp, content, "utf8");
89777
- await fs8.rename(tmp, filePath);
90628
+ await fs11.writeFile(tmp, content, "utf8");
90629
+ await fs11.rename(tmp, filePath);
89778
90630
  }
89779
90631
  var StatusLineFileLive = succeed10(StatusLineFile, {
89780
90632
  defaultTextFile: () => defaultTextFile(),
@@ -89827,7 +90679,7 @@ function resolveStatuslineArtifactPaths(params3) {
89827
90679
  function deleteFileIfExists(filePath) {
89828
90680
  return promise2(async () => {
89829
90681
  try {
89830
- await fs9.unlink(filePath);
90682
+ await fs12.unlink(filePath);
89831
90683
  return { action: "deleted", file: filePath };
89832
90684
  } catch (e) {
89833
90685
  if (e?.code === "ENOENT")
@@ -89870,7 +90722,7 @@ var wsRestartCommand = exports_Command.make("restart", {
89870
90722
  const pidFilePath = resolveUserFilePath(pidFile4 ?? daemonFiles.defaultPidFile());
89871
90723
  const existing = yield* daemonFiles.readPidFile(pidFilePath);
89872
90724
  let stopResult = { stopped: true, pid_file: pidFilePath };
89873
- const stateFilePath = resolveUserFilePath(existing?.state_file ?? path16.join(path16.dirname(pidFilePath), "ws.state.json"));
90725
+ const stateFilePath = resolveUserFilePath(existing?.state_file ?? path19.join(path19.dirname(pidFilePath), "ws.state.json"));
89874
90726
  if (existing) {
89875
90727
  const alive = yield* proc.isPidRunning(existing.pid);
89876
90728
  if (!alive) {
@@ -89942,10 +90794,10 @@ function safeJsonParse2(text14) {
89942
90794
  }
89943
90795
  }
89944
90796
  var WsBridgeServerLive = succeed10(WsBridgeServer, {
89945
- listen: ({ port: port3, path: path17, host }) => acquireRelease2(gen2(function* () {
90797
+ listen: ({ port: port3, path: path20, host }) => acquireRelease2(gen2(function* () {
89946
90798
  const events = yield* unbounded5();
89947
90799
  const sockets = new Map;
89948
- const wss = new import_websocket_server.default({ port: port3, host, path: path17 });
90800
+ const wss = new import_websocket_server.default({ port: port3, host, path: path20 });
89949
90801
  wss.on("connection", (ws, req) => {
89950
90802
  const connId = randomUUID4();
89951
90803
  const remoteAddr = safeStringHeader(req?.socket?.remoteAddress);
@@ -89979,7 +90831,7 @@ var WsBridgeServerLive = succeed10(WsBridgeServer, {
89979
90831
  });
89980
90832
  const handle = {
89981
90833
  events,
89982
- serverInfo: { port: port3, path: path17 },
90834
+ serverInfo: { port: port3, path: path20 },
89983
90835
  sendText: (connId, text14) => sync3(() => {
89984
90836
  const ws = sockets.get(connId);
89985
90837
  if (!ws)
@@ -90041,23 +90893,23 @@ var WsBridgeServerLive = succeed10(WsBridgeServer, {
90041
90893
  code: "WS_UNAVAILABLE",
90042
90894
  message: "Failed to start ws bridge server",
90043
90895
  exitCode: 1,
90044
- details: { error: String(error4?.message || error4), port: port3, path: path17, host }
90896
+ details: { error: String(error4?.message || error4), port: port3, path: path20, host }
90045
90897
  }))))
90046
90898
  });
90047
90899
 
90048
90900
  // src/services/WsBridgeStateFile.ts
90049
- import { promises as fs10 } from "node:fs";
90050
- import path17 from "node:path";
90901
+ import { promises as fs13 } from "node:fs";
90902
+ import path20 from "node:path";
90051
90903
  class WsBridgeStateFile extends Tag2("WsBridgeStateFile")() {
90052
90904
  }
90053
- async function ensureDir6(filePath) {
90054
- await fs10.mkdir(path17.dirname(filePath), { recursive: true });
90905
+ async function ensureDir7(filePath) {
90906
+ await fs13.mkdir(path20.dirname(filePath), { recursive: true });
90055
90907
  }
90056
90908
  async function writeTextAtomic2(filePath, content) {
90057
- await ensureDir6(filePath);
90909
+ await ensureDir7(filePath);
90058
90910
  const tmp = `${filePath}.tmp-${process.pid}-${Date.now()}`;
90059
- await fs10.writeFile(tmp, content, "utf8");
90060
- await fs10.rename(tmp, filePath);
90911
+ await fs13.writeFile(tmp, content, "utf8");
90912
+ await fs13.rename(tmp, filePath);
90061
90913
  }
90062
90914
  var WsBridgeStateFileLive = succeed10(WsBridgeStateFile, {
90063
90915
  write: ({ filePath, json: json4 }) => tryPromise2({
@@ -90163,7 +91015,7 @@ var TmuxLive = scoped3(Tmux, gen2(function* () {
90163
91015
  }));
90164
91016
 
90165
91017
  // src/services/WsBridgeState.ts
90166
- import { promises as fs11 } from "node:fs";
91018
+ import { promises as fs14 } from "node:fs";
90167
91019
  class WsBridgeState extends Tag2("WsBridgeState")() {
90168
91020
  }
90169
91021
  function toNonNegativeInt3(value8) {
@@ -90189,7 +91041,7 @@ var WsBridgeStateLive = succeed10(WsBridgeState, {
90189
91041
  return { connection: "off", selection: { kind: "none" } };
90190
91042
  }
90191
91043
  const raw4 = yield* tryPromise2({
90192
- try: async () => await fs11.readFile(cfg.wsStateFile.path, "utf8"),
91044
+ try: async () => await fs14.readFile(cfg.wsStateFile.path, "utf8"),
90193
91045
  catch: (e) => {
90194
91046
  if (e?.code === "ENOENT")
90195
91047
  return null;
@@ -90602,18 +91454,18 @@ function parseWsUrl(url2) {
90602
91454
  }
90603
91455
  const port3 = u.port ? Number(u.port) : u.protocol === "wss:" ? 443 : 80;
90604
91456
  const host = u.hostname && u.hostname.length > 0 ? u.hostname : "localhost";
90605
- const path18 = u.pathname && u.pathname.length > 0 ? u.pathname : "/ws";
91457
+ const path21 = u.pathname && u.pathname.length > 0 ? u.pathname : "/ws";
90606
91458
  if (!Number.isFinite(port3) || port3 <= 0) {
90607
91459
  throw new CliError({ code: "INVALID_ARGS", message: `Invalid wsUrl port: ${url2}`, exitCode: 2 });
90608
91460
  }
90609
- if (!path18.startsWith("/")) {
91461
+ if (!path21.startsWith("/")) {
90610
91462
  throw new CliError({ code: "INVALID_ARGS", message: `Invalid wsUrl path: ${url2}`, exitCode: 2 });
90611
91463
  }
90612
- return { host, port: port3, path: path18 };
91464
+ return { host, port: port3, path: path21 };
90613
91465
  }
90614
91466
  var wsServeCommand = exports_Command.make("serve", {}, () => gen2(function* () {
90615
91467
  const cfg = yield* AppConfig;
90616
- const { host, port: port3, path: path18 } = yield* try_3({
91468
+ const { host, port: port3, path: path21 } = yield* try_3({
90617
91469
  try: () => parseWsUrl(cfg.wsUrl),
90618
91470
  catch: (e) => isCliError(e) ? e : new CliError({
90619
91471
  code: "INVALID_ARGS",
@@ -90622,7 +91474,7 @@ var wsServeCommand = exports_Command.make("serve", {}, () => gen2(function* () {
90622
91474
  details: { ws_url: cfg.wsUrl, error: String(e?.message || e) }
90623
91475
  })
90624
91476
  });
90625
- yield* runWsBridgeRuntime({ host, port: port3, path: path18 });
91477
+ yield* runWsBridgeRuntime({ host, port: port3, path: path21 });
90626
91478
  }).pipe(catchAll2(writeFailure)));
90627
91479
 
90628
91480
  // src/commands/ws/start.ts
@@ -90638,14 +91490,14 @@ function parseWsUrl2(url2) {
90638
91490
  }
90639
91491
  const port3 = u.port ? Number(u.port) : u.protocol === "wss:" ? 443 : 80;
90640
91492
  const host = u.hostname && u.hostname.length > 0 ? u.hostname : "localhost";
90641
- const path18 = u.pathname && u.pathname.length > 0 ? u.pathname : "/ws";
91493
+ const path21 = u.pathname && u.pathname.length > 0 ? u.pathname : "/ws";
90642
91494
  if (!Number.isFinite(port3) || port3 <= 0) {
90643
91495
  throw new CliError({ code: "INVALID_ARGS", message: `Invalid wsUrl port: ${url2}`, exitCode: 2 });
90644
91496
  }
90645
- if (!path18.startsWith("/")) {
91497
+ if (!path21.startsWith("/")) {
90646
91498
  throw new CliError({ code: "INVALID_ARGS", message: `Invalid wsUrl path: ${url2}`, exitCode: 2 });
90647
91499
  }
90648
- return { host, port: port3, path: path18 };
91500
+ return { host, port: port3, path: path21 };
90649
91501
  }
90650
91502
  var pidFile4 = text9("pid-file").pipe(optional5, map34(optionToUndefined4));
90651
91503
  var logFile3 = text9("log-file").pipe(optional5, map34(optionToUndefined4));
@@ -90657,7 +91509,7 @@ var wsStartCommand = exports_Command.make("start", {
90657
91509
  }, ({ foreground, wait, pidFile: pidFile5, logFile: logFile4 }) => gen2(function* () {
90658
91510
  const cfg = yield* AppConfig;
90659
91511
  if (foreground) {
90660
- const { host, port: port3, path: path18 } = yield* try_3({
91512
+ const { host, port: port3, path: path21 } = yield* try_3({
90661
91513
  try: () => parseWsUrl2(cfg.wsUrl),
90662
91514
  catch: (e) => isCliError(e) ? e : new CliError({
90663
91515
  code: "INVALID_ARGS",
@@ -90666,7 +91518,7 @@ var wsStartCommand = exports_Command.make("start", {
90666
91518
  details: { ws_url: cfg.wsUrl, error: String(e?.message || e) }
90667
91519
  })
90668
91520
  });
90669
- yield* runWsBridgeRuntime({ host, port: port3, path: path18 });
91521
+ yield* runWsBridgeRuntime({ host, port: port3, path: path21 });
90670
91522
  return;
90671
91523
  }
90672
91524
  const result = yield* startWsSupervisor({ waitMs: wait, pidFile: pidFile5, logFile: logFile4 });
@@ -90681,7 +91533,7 @@ var wsStartCommand = exports_Command.make("start", {
90681
91533
  }).pipe(catchAll2(writeFailure)));
90682
91534
 
90683
91535
  // src/commands/ws/status.ts
90684
- import path18 from "node:path";
91536
+ import path21 from "node:path";
90685
91537
  function optionToUndefined5(opt) {
90686
91538
  return isSome2(opt) ? opt.value : undefined;
90687
91539
  }
@@ -90700,14 +91552,14 @@ var wsStatusCommand = exports_Command.make("status", { pidFile: pidFile5 }, ({ p
90700
91552
  if (!alive) {
90701
91553
  const stalePidInfo = pidInfo;
90702
91554
  yield* daemonFiles.deletePidFile(pidFilePath);
90703
- const staleStateFilePath = resolveUserFilePath(pidInfo.state_file ?? path18.join(path18.dirname(pidFilePath), "ws.state.json"));
91555
+ const staleStateFilePath = resolveUserFilePath(pidInfo.state_file ?? path21.join(path21.dirname(pidFilePath), "ws.state.json"));
90704
91556
  yield* supervisorState.deleteStateFile(staleStateFilePath);
90705
91557
  selfHealCleanup = yield* cleanupStatuslineArtifacts(resolveStatuslineArtifactPaths({ cfg, pidInfo: stalePidInfo }));
90706
91558
  yield* sync3(() => refreshTmuxStatusLine());
90707
91559
  pidInfo = undefined;
90708
91560
  }
90709
91561
  }
90710
- const stateFilePath = resolveUserFilePath(pidInfo?.state_file ?? path18.join(path18.dirname(pidFilePath), "ws.state.json"));
91562
+ const stateFilePath = resolveUserFilePath(pidInfo?.state_file ?? path21.join(path21.dirname(pidFilePath), "ws.state.json"));
90711
91563
  const state = yield* supervisorState.readStateFile(stateFilePath);
90712
91564
  const mode = pidInfo ? pidInfo.mode ?? "legacy" : "supervisor";
90713
91565
  const supervisorPid = pidInfo?.pid;
@@ -90870,7 +91722,7 @@ var wsStatusLineCommand = exports_Command.make("status-line", { stateFile, stale
90870
91722
  }).pipe(catchAll2(writeFailure)));
90871
91723
 
90872
91724
  // src/commands/ws/stop.ts
90873
- import path19 from "node:path";
91725
+ import path22 from "node:path";
90874
91726
  function optionToUndefined7(opt) {
90875
91727
  return isSome2(opt) ? opt.value : undefined;
90876
91728
  }
@@ -90898,7 +91750,7 @@ var wsStopCommand = exports_Command.make("stop", { force: boolean8("force"), pid
90898
91750
  });
90899
91751
  return;
90900
91752
  }
90901
- const stateFilePath = resolveUserFilePath(existing.state_file ?? path19.join(path19.dirname(pidFilePath), "ws.state.json"));
91753
+ const stateFilePath = resolveUserFilePath(existing.state_file ?? path22.join(path22.dirname(pidFilePath), "ws.state.json"));
90902
91754
  const alive = yield* proc.isPidRunning(existing.pid);
90903
91755
  if (!alive) {
90904
91756
  yield* daemonFiles.deletePidFile(pidFilePath);
@@ -91092,8 +91944,8 @@ var ChildProcessLive = succeed10(ChildProcess2, {
91092
91944
  });
91093
91945
 
91094
91946
  // src/services/LogWriter.ts
91095
- import { promises as fs12 } from "node:fs";
91096
- import path20 from "node:path";
91947
+ import { promises as fs15 } from "node:fs";
91948
+ import path23 from "node:path";
91097
91949
  class LogWriterFactory extends Tag2("LogWriterFactory")() {
91098
91950
  }
91099
91951
  function sanitizePositiveInt(value8, fallback) {
@@ -91104,12 +91956,12 @@ function sanitizeMaxBytes(value8, fallback) {
91104
91956
  return null;
91105
91957
  return Number.isFinite(value8) && value8 > 0 ? Math.floor(value8) : fallback;
91106
91958
  }
91107
- async function ensureDir7(filePath) {
91108
- await fs12.mkdir(path20.dirname(filePath), { recursive: true });
91959
+ async function ensureDir8(filePath) {
91960
+ await fs15.mkdir(path23.dirname(filePath), { recursive: true });
91109
91961
  }
91110
91962
  async function safeStat(filePath) {
91111
91963
  try {
91112
- const s = await fs12.stat(filePath);
91964
+ const s = await fs15.stat(filePath);
91113
91965
  return { size: s.size };
91114
91966
  } catch {
91115
91967
  return;
@@ -91118,25 +91970,25 @@ async function safeStat(filePath) {
91118
91970
  async function rotateFiles(filePath, keep) {
91119
91971
  if (keep <= 0)
91120
91972
  return;
91121
- const dir2 = path20.dirname(filePath);
91122
- const base = path20.basename(filePath);
91973
+ const dir2 = path23.dirname(filePath);
91974
+ const base = path23.basename(filePath);
91123
91975
  let entries2 = [];
91124
91976
  try {
91125
- entries2 = await fs12.readdir(dir2);
91977
+ entries2 = await fs15.readdir(dir2);
91126
91978
  } catch {
91127
91979
  return;
91128
91980
  }
91129
- const rotated = entries2.filter((name) => name.startsWith(`${base}.`)).map((name) => path20.join(dir2, name)).sort().reverse();
91981
+ const rotated = entries2.filter((name) => name.startsWith(`${base}.`)).map((name) => path23.join(dir2, name)).sort().reverse();
91130
91982
  for (const p3 of rotated.slice(keep)) {
91131
91983
  try {
91132
- await fs12.unlink(p3);
91984
+ await fs15.unlink(p3);
91133
91985
  } catch {}
91134
91986
  }
91135
91987
  }
91136
91988
  async function createLogWriter(filePath, options6) {
91137
91989
  const maxBytes = sanitizeMaxBytes(options6.maxBytes, 20 * 1024 * 1024);
91138
91990
  const keep = sanitizePositiveInt(options6.keep, 5);
91139
- await ensureDir7(filePath);
91991
+ await ensureDir8(filePath);
91140
91992
  let currentSize = (await safeStat(filePath))?.size ?? 0;
91141
91993
  let handle;
91142
91994
  let closing = false;
@@ -91145,7 +91997,7 @@ async function createLogWriter(filePath, options6) {
91145
91997
  async function openIfNeeded() {
91146
91998
  if (handle)
91147
91999
  return handle;
91148
- handle = await fs12.open(filePath, "a");
92000
+ handle = await fs15.open(filePath, "a");
91149
92001
  return handle;
91150
92002
  }
91151
92003
  async function rotateIfNeeded(nextBytes) {
@@ -91159,7 +92011,7 @@ async function createLogWriter(filePath, options6) {
91159
92011
  handle = undefined;
91160
92012
  const rotatedPath = `${filePath}.${Date.now()}`;
91161
92013
  try {
91162
- await fs12.rename(filePath, rotatedPath);
92014
+ await fs15.rename(filePath, rotatedPath);
91163
92015
  } catch {}
91164
92016
  currentSize = 0;
91165
92017
  await rotateFiles(filePath, keep);
@@ -91567,7 +92419,7 @@ var dailySummaryCommand = exports_Command.make("summary", { days: days2, maxLine
91567
92419
  }).pipe(catchAll2(writeFailure)));
91568
92420
 
91569
92421
  // src/services/FileInput.ts
91570
- import { promises as fs13 } from "node:fs";
92422
+ import { promises as fs16 } from "node:fs";
91571
92423
  class FileInput extends Tag2("FileInput")() {
91572
92424
  }
91573
92425
  var DEFAULT_MAX_BYTES = 5 * 1024 * 1024;
@@ -91603,7 +92455,7 @@ async function readTextFromFilePath(pathSpec, maxBytes) {
91603
92455
  }
91604
92456
  const resolved = resolveUserFilePath(trimmed2);
91605
92457
  try {
91606
- const stat3 = await fs13.stat(resolved);
92458
+ const stat3 = await fs16.stat(resolved);
91607
92459
  if (!stat3.isFile()) {
91608
92460
  throw new CliError({ code: "INVALID_ARGS", message: `Not a file: ${resolved}`, exitCode: 2 });
91609
92461
  }
@@ -91615,7 +92467,7 @@ async function readTextFromFilePath(pathSpec, maxBytes) {
91615
92467
  details: { bytes: stat3.size, max_bytes: maxBytes, file: resolved }
91616
92468
  });
91617
92469
  }
91618
- return await fs13.readFile(resolved, "utf8");
92470
+ return await fs16.readFile(resolved, "utf8");
91619
92471
  } catch (error4) {
91620
92472
  if (isCliError(error4))
91621
92473
  throw error4;
@@ -91659,7 +92511,7 @@ var FileInputLive = succeed10(FileInput, {
91659
92511
  });
91660
92512
 
91661
92513
  // src/services/Payload.ts
91662
- import { promises as fs14 } from "node:fs";
92514
+ import { promises as fs17 } from "node:fs";
91663
92515
  class Payload extends Tag2("Payload")() {
91664
92516
  }
91665
92517
  var MAX_PAYLOAD_BYTES = 5 * 1024 * 1024;
@@ -91700,7 +92552,7 @@ async function readPayloadSpec(spec) {
91700
92552
  if (!filePath) {
91701
92553
  throw new CliError({ code: "INVALID_ARGS", message: "Payload file path cannot be empty", exitCode: 2 });
91702
92554
  }
91703
- return await fs14.readFile(filePath, "utf8");
92555
+ return await fs17.readFile(filePath, "utf8");
91704
92556
  }
91705
92557
  return spec;
91706
92558
  }
@@ -92496,86 +93348,29 @@ var dbRecentCommand = exports_Command.make("recent", {
92496
93348
  ids3.push(row.id);
92497
93349
  const marker = row.edited_after_create ? " (edited after creation)" : "";
92498
93350
  mdLines.push(`- \`${msToLocalStr(row.created_at)}\` ${row.preview} \`${row.id}\`${marker}`);
92499
- }
92500
- mdLines.push("");
92501
- }
92502
- }
92503
- }
92504
- const data = {
92505
- db_path: dbPath,
92506
- resolution: result.info.source,
92507
- days: d,
92508
- cutoff_ms: cutoffMs,
92509
- counts: result.result.counts,
92510
- items: result.result.items
92511
- };
92512
- yield* writeSuccess({ data, ids: ids3, md: mdLines.join(`
92513
- `).trimEnd() + `
92514
- ` });
92515
- }).pipe(catchAll2(writeFailure)));
92516
-
92517
- // src/commands/read/db/index.ts
92518
- var readDbCommand = exports_Command.make("db", {}).pipe(exports_Command.withSubcommands([dbBackupsCommand, dbRecentCommand]));
92519
-
92520
- // src/commands/db/index.ts
92521
- var dbCommand = readDbCommand;
92522
-
92523
- // src/lib/remnote.ts
92524
- import fs15 from "node:fs";
92525
- import path21 from "node:path";
92526
- function tryParseRemnoteLink(input) {
92527
- const raw4 = input.trim();
92528
- let u;
92529
- try {
92530
- u = new URL(raw4);
92531
- } catch {
92532
- return;
92533
- }
92534
- if (u.protocol === "remnote:" && u.hostname === "w") {
92535
- const parts2 = u.pathname.split("/").filter(Boolean);
92536
- const workspaceId = parts2.length >= 1 ? parts2[0] : undefined;
92537
- const remId = parts2.length >= 2 ? parts2[1] : undefined;
92538
- if (workspaceId && remId) {
92539
- return { workspaceId: workspaceId.trim(), remId: remId.trim() };
92540
- }
92541
- return;
92542
- }
92543
- if ((u.protocol === "https:" || u.protocol === "http:") && u.hostname.endsWith("remnote.com")) {
92544
- const parts2 = u.pathname.split("/").filter(Boolean);
92545
- if (parts2.length >= 3 && parts2[0] === "w") {
92546
- const workspaceId = parts2[1];
92547
- const remId = parts2[2];
92548
- if (workspaceId && remId) {
92549
- return { workspaceId: workspaceId.trim(), remId: remId.trim() };
92550
- }
92551
- }
92552
- }
92553
- return;
92554
- }
92555
- function tryParseRemnoteLinkFromRef(input) {
92556
- const direct = tryParseRemnoteLink(input);
92557
- if (direct)
92558
- return direct;
92559
- const raw4 = input.trim();
92560
- const idx = raw4.indexOf(":");
92561
- if (idx <= 0)
92562
- return;
92563
- const value8 = raw4.slice(idx + 1).trim();
92564
- if (!value8)
92565
- return;
92566
- return tryParseRemnoteLink(value8);
92567
- }
92568
- function remnoteDbPathForWorkspaceId(workspaceId) {
92569
- return path21.join(homeDir(), "remnote", `remnote-${workspaceId}`, "remnote.db");
92570
- }
92571
- function tryResolveRemnoteDbPathForWorkspaceIdSync(workspaceId) {
92572
- const p3 = remnoteDbPathForWorkspaceId(workspaceId);
92573
- try {
92574
- return fs15.statSync(p3).isFile() ? p3 : undefined;
92575
- } catch {
92576
- return;
93351
+ }
93352
+ mdLines.push("");
93353
+ }
93354
+ }
92577
93355
  }
92578
- }
93356
+ const data = {
93357
+ db_path: dbPath,
93358
+ resolution: result.info.source,
93359
+ days: d,
93360
+ cutoff_ms: cutoffMs,
93361
+ counts: result.result.counts,
93362
+ items: result.result.items
93363
+ };
93364
+ yield* writeSuccess({ data, ids: ids3, md: mdLines.join(`
93365
+ `).trimEnd() + `
93366
+ ` });
93367
+ }).pipe(catchAll2(writeFailure)));
93368
+
93369
+ // src/commands/read/db/index.ts
93370
+ var readDbCommand = exports_Command.make("db", {}).pipe(exports_Command.withSubcommands([dbBackupsCommand, dbRecentCommand]));
93371
+
93372
+ // src/commands/db/index.ts
93373
+ var dbCommand = readDbCommand;
92579
93374
 
92580
93375
  // src/services/RefResolver.ts
92581
93376
  class RefResolver extends Tag2("RefResolver")() {
@@ -93713,12 +94508,12 @@ var applyCommand = exports_Command.make("apply", {
93713
94508
  }).pipe(catchAll2(writeFailure)));
93714
94509
 
93715
94510
  // src/services/ApiDaemonFiles.ts
93716
- import { promises as fs16 } from "node:fs";
93717
- import path22 from "node:path";
94511
+ import { promises as fs18 } from "node:fs";
94512
+ import path24 from "node:path";
93718
94513
  class ApiDaemonFiles extends Tag2("ApiDaemonFiles")() {
93719
94514
  }
93720
- function ensureDir8(p3) {
93721
- return fs16.mkdir(path22.dirname(p3), { recursive: true }).then(() => {
94515
+ function ensureDir9(p3) {
94516
+ return fs18.mkdir(path24.dirname(p3), { recursive: true }).then(() => {
93722
94517
  return;
93723
94518
  });
93724
94519
  }
@@ -93726,19 +94521,19 @@ function defaultPidFile2() {
93726
94521
  const envPidFile = process.env.REMNOTE_API_PID_FILE;
93727
94522
  if (typeof envPidFile === "string" && envPidFile.trim())
93728
94523
  return resolveUserFilePath(envPidFile);
93729
- return path22.join(homeDir(), ".agent-remnote", "api.pid");
94524
+ return path24.join(homeDir(), ".agent-remnote", "api.pid");
93730
94525
  }
93731
94526
  function defaultLogFile2() {
93732
94527
  const envLogFile = process.env.REMNOTE_API_LOG_FILE;
93733
94528
  if (typeof envLogFile === "string" && envLogFile.trim())
93734
94529
  return resolveUserFilePath(envLogFile);
93735
- return path22.join(homeDir(), ".agent-remnote", "api.log");
94530
+ return path24.join(homeDir(), ".agent-remnote", "api.log");
93736
94531
  }
93737
94532
  function defaultStateFile2() {
93738
94533
  const envStateFile = process.env.REMNOTE_API_STATE_FILE;
93739
94534
  if (typeof envStateFile === "string" && envStateFile.trim())
93740
94535
  return resolveUserFilePath(envStateFile);
93741
- return path22.join(homeDir(), ".agent-remnote", "api.state.json");
94536
+ return path24.join(homeDir(), ".agent-remnote", "api.state.json");
93742
94537
  }
93743
94538
  function parseJson2(raw4, filePath) {
93744
94539
  try {
@@ -93759,7 +94554,7 @@ var ApiDaemonFilesLive = succeed10(ApiDaemonFiles, {
93759
94554
  readPidFile: (pidFilePath) => tryPromise2({
93760
94555
  try: async () => {
93761
94556
  const resolved = resolveUserFilePath(pidFilePath);
93762
- const raw4 = await fs16.readFile(resolved, "utf8");
94557
+ const raw4 = await fs18.readFile(resolved, "utf8");
93763
94558
  return parseJson2(raw4, resolved);
93764
94559
  },
93765
94560
  catch: (error4) => {
@@ -93783,8 +94578,8 @@ var ApiDaemonFilesLive = succeed10(ApiDaemonFiles, {
93783
94578
  writePidFile: (pidFilePath, value8) => tryPromise2({
93784
94579
  try: async () => {
93785
94580
  const resolved = resolveUserFilePath(pidFilePath);
93786
- await ensureDir8(resolved);
93787
- await fs16.writeFile(resolved, `${JSON.stringify(value8, null, 2)}
94581
+ await ensureDir9(resolved);
94582
+ await fs18.writeFile(resolved, `${JSON.stringify(value8, null, 2)}
93788
94583
  `, "utf8");
93789
94584
  },
93790
94585
  catch: (error4) => new CliError({
@@ -93797,7 +94592,7 @@ var ApiDaemonFilesLive = succeed10(ApiDaemonFiles, {
93797
94592
  deletePidFile: (pidFilePath) => tryPromise2({
93798
94593
  try: async () => {
93799
94594
  const resolved = resolveUserFilePath(pidFilePath);
93800
- await fs16.rm(resolved, { force: true });
94595
+ await fs18.rm(resolved, { force: true });
93801
94596
  },
93802
94597
  catch: (error4) => new CliError({
93803
94598
  code: "INTERNAL",
@@ -93809,7 +94604,7 @@ var ApiDaemonFilesLive = succeed10(ApiDaemonFiles, {
93809
94604
  readStateFile: (stateFilePath) => tryPromise2({
93810
94605
  try: async () => {
93811
94606
  const resolved = resolveUserFilePath(stateFilePath);
93812
- const raw4 = await fs16.readFile(resolved, "utf8");
94607
+ const raw4 = await fs18.readFile(resolved, "utf8");
93813
94608
  return parseJson2(raw4, resolved);
93814
94609
  },
93815
94610
  catch: (error4) => {
@@ -93833,8 +94628,8 @@ var ApiDaemonFilesLive = succeed10(ApiDaemonFiles, {
93833
94628
  writeStateFile: (stateFilePath, value8) => tryPromise2({
93834
94629
  try: async () => {
93835
94630
  const resolved = resolveUserFilePath(stateFilePath);
93836
- await ensureDir8(resolved);
93837
- await fs16.writeFile(resolved, `${JSON.stringify(value8, null, 2)}
94631
+ await ensureDir9(resolved);
94632
+ await fs18.writeFile(resolved, `${JSON.stringify(value8, null, 2)}
93838
94633
  `, "utf8");
93839
94634
  },
93840
94635
  catch: (error4) => new CliError({
@@ -93847,7 +94642,7 @@ var ApiDaemonFilesLive = succeed10(ApiDaemonFiles, {
93847
94642
  deleteStateFile: (stateFilePath) => tryPromise2({
93848
94643
  try: async () => {
93849
94644
  const resolved = resolveUserFilePath(stateFilePath);
93850
- await fs16.rm(resolved, { force: true });
94645
+ await fs18.rm(resolved, { force: true });
93851
94646
  },
93852
94647
  catch: (error4) => new CliError({
93853
94648
  code: "INTERNAL",
@@ -95873,8 +96668,8 @@ function resolveRefsInPayload(params3) {
95873
96668
  const out = structuredClone(params3.payload);
95874
96669
  const resolvedRefCache = new Map;
95875
96670
  const idPaths = idFieldPathsForOpType(params3.opType);
95876
- for (const path23 of idPaths) {
95877
- const tokens = parsePathTokens(path23);
96671
+ for (const path25 of idPaths) {
96672
+ const tokens = parsePathTokens(path25);
95878
96673
  if (tokens.length === 0)
95879
96674
  continue;
95880
96675
  const leaves = collectLeafValues(out, tokens);
@@ -102648,7 +103443,7 @@ var stackEnsureCommand = exports_Command.make("ensure", {
102648
103443
  }).pipe(catchAll2(writeFailure)));
102649
103444
 
102650
103445
  // src/commands/stack/status.ts
102651
- import path23 from "node:path";
103446
+ import path25 from "node:path";
102652
103447
  var stackStatusCommand = exports_Command.make("status", {}, () => gen2(function* () {
102653
103448
  const cfg = yield* AppConfig;
102654
103449
  const daemonFiles = yield* DaemonFiles;
@@ -102668,7 +103463,7 @@ var stackStatusCommand = exports_Command.make("status", {}, () => gen2(function*
102668
103463
  const apiBaseUrl = apiLocalBaseUrl(apiPidInfo?.port ?? cfg.apiPort ?? 3000);
102669
103464
  const apiStatus = yield* api.status({ baseUrl: apiBaseUrl, timeoutMs: 2000 }).pipe(either3);
102670
103465
  const queueStats2 = yield* queue.stats({ dbPath: cfg.storeDb }).pipe(either3);
102671
- const stateFilePath = resolveUserFilePath(daemonPidInfo?.state_file ?? path23.join(path23.dirname(daemonPidFile), "ws.state.json"));
103466
+ const stateFilePath = resolveUserFilePath(daemonPidInfo?.state_file ?? path25.join(path25.dirname(daemonPidFile), "ws.state.json"));
102672
103467
  const data = {
102673
103468
  daemon: {
102674
103469
  running: daemonRunning,
@@ -102706,7 +103501,7 @@ var stackStatusCommand = exports_Command.make("status", {}, () => gen2(function*
102706
103501
  }).pipe(catchAll2(writeFailure)));
102707
103502
 
102708
103503
  // src/commands/stack/stop.ts
102709
- import path24 from "node:path";
103504
+ import path26 from "node:path";
102710
103505
  var stackStopCommand = exports_Command.make("stop", {}, () => gen2(function* () {
102711
103506
  const apiFiles = yield* ApiDaemonFiles;
102712
103507
  const daemonFiles = yield* DaemonFiles;
@@ -102743,7 +103538,7 @@ var stackStopCommand = exports_Command.make("stop", {}, () => gen2(function* ()
102743
103538
  }
102744
103539
  }
102745
103540
  yield* daemonFiles.deletePidFile(daemonPidFile).pipe(catchAll2(() => _void));
102746
- yield* supervisorState.deleteStateFile(resolveUserFilePath(daemonPidInfo?.state_file ?? path24.join(path24.dirname(daemonPidFile), "ws.state.json"))).pipe(catchAll2(() => _void));
103541
+ yield* supervisorState.deleteStateFile(resolveUserFilePath(daemonPidInfo?.state_file ?? path26.join(path26.dirname(daemonPidFile), "ws.state.json"))).pipe(catchAll2(() => _void));
102747
103542
  yield* writeSuccess({
102748
103543
  data: { stopped: true, api_stopped: apiStopped, daemon_stopped: daemonStopped },
102749
103544
  md: `- stopped: true
@@ -102756,242 +103551,6 @@ var stackStopCommand = exports_Command.make("stop", {}, () => gen2(function* ()
102756
103551
  // src/commands/stack/index.ts
102757
103552
  var stackCommand = exports_Command.make("stack", {}).pipe(exports_Command.withSubcommands([stackEnsureCommand, stackStopCommand, stackStatusCommand]));
102758
103553
 
102759
- // src/services/Config.ts
102760
- import fs17 from "node:fs";
102761
- import path25 from "node:path";
102762
- function defaultStoreDbPath() {
102763
- return path25.join(homeDir(), ".agent-remnote", "store.sqlite");
102764
- }
102765
- function wsUrlFromPort(port7) {
102766
- return `ws://localhost:${port7}/ws`;
102767
- }
102768
- function defaultWsStateFilePath() {
102769
- return path25.join(homeDir(), ".agent-remnote", "ws.bridge.state.json");
102770
- }
102771
- function defaultStatusLineFilePath() {
102772
- return path25.join(homeDir(), ".agent-remnote", "status-line.txt");
102773
- }
102774
- function defaultStatusLineJsonFilePath() {
102775
- return path25.join(homeDir(), ".agent-remnote", "status-line.json");
102776
- }
102777
- function defaultApiPidFilePath() {
102778
- return path25.join(homeDir(), ".agent-remnote", "api.pid");
102779
- }
102780
- function defaultApiLogFilePath() {
102781
- return path25.join(homeDir(), ".agent-remnote", "api.log");
102782
- }
102783
- function defaultApiStateFilePath() {
102784
- return path25.join(homeDir(), ".agent-remnote", "api.state.json");
102785
- }
102786
- function normalizeApiBasePath(raw4) {
102787
- const trimmed2 = raw4.trim();
102788
- if (!trimmed2)
102789
- return "/v1";
102790
- return trimmed2.startsWith("/") ? trimmed2 : `/${trimmed2}`;
102791
- }
102792
- function normalizeApiBaseUrl(raw4) {
102793
- const trimmed2 = raw4.trim();
102794
- if (!trimmed2)
102795
- return trimmed2;
102796
- let parsed;
102797
- try {
102798
- parsed = new URL(trimmed2);
102799
- } catch {
102800
- throw new CliError({
102801
- code: "INVALID_ARGS",
102802
- message: `Invalid apiBaseUrl: ${trimmed2}`,
102803
- exitCode: 2,
102804
- details: { api_base_url: trimmed2 }
102805
- });
102806
- }
102807
- if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
102808
- throw new CliError({
102809
- code: "INVALID_ARGS",
102810
- message: `apiBaseUrl protocol must be http/https: ${trimmed2}`,
102811
- exitCode: 2,
102812
- details: { api_base_url: trimmed2 }
102813
- });
102814
- }
102815
- const normalized = trimmed2.replace(/\/+$/, "");
102816
- return normalized;
102817
- }
102818
- function resolveWsStateFile(spec) {
102819
- const raw4 = spec.trim();
102820
- if (raw4 === "0" || raw4.toLowerCase() === "false") {
102821
- return { disabled: true, path: defaultWsStateFilePath() };
102822
- }
102823
- if (raw4)
102824
- return { disabled: false, path: resolveUserFilePath(raw4) };
102825
- return { disabled: false, path: defaultWsStateFilePath() };
102826
- }
102827
- function inferRemnoteDbFromWsState(params3) {
102828
- if (params3.wsStateFile.disabled)
102829
- return;
102830
- const state = readJson(params3.wsStateFile.path);
102831
- if (!state)
102832
- return;
102833
- const now2 = Date.now();
102834
- const updatedAt = Number(state.updatedAt ?? 0);
102835
- const staleMs13 = params3.wsStateStaleMs;
102836
- const stale = !Number.isFinite(updatedAt) || updatedAt <= 0 || now2 - updatedAt > staleMs13;
102837
- if (stale)
102838
- return;
102839
- const clients = Array.isArray(state.clients) ? state.clients : [];
102840
- const activeConnIdRaw = typeof state.activeWorkerConnId === "string" ? state.activeWorkerConnId.trim() : "";
102841
- const client = pickClient(clients, activeConnIdRaw || undefined);
102842
- const kbIdRaw = typeof client?.uiContext?.kbId === "string" ? client.uiContext.kbId.trim() : "";
102843
- if (!kbIdRaw)
102844
- return;
102845
- const dbPath = resolveUserFilePath(remnoteDbPathForWorkspaceId(kbIdRaw));
102846
- try {
102847
- return fs17.statSync(dbPath).isFile() ? dbPath : undefined;
102848
- } catch {
102849
- return;
102850
- }
102851
- }
102852
- function pickFormat(raw4) {
102853
- const json4 = raw4.json === true;
102854
- const md = raw4.md === true;
102855
- const ids6 = raw4.ids === true;
102856
- const count4 = [json4, md, ids6].filter(Boolean).length;
102857
- if (count4 > 1) {
102858
- throw new CliError({
102859
- code: "INVALID_ARGS",
102860
- message: "Output format conflict: choose only one of --json/--md/--ids",
102861
- exitCode: 2,
102862
- details: { json: json4, md, ids: ids6 }
102863
- });
102864
- }
102865
- if (json4)
102866
- return "json";
102867
- if (ids6)
102868
- return "ids";
102869
- return "md";
102870
- }
102871
- var rawConfigSpec = all8({
102872
- json: boolean4("json").pipe(withDefault2(false)),
102873
- md: boolean4("md").pipe(withDefault2(false)),
102874
- ids: boolean4("ids").pipe(withDefault2(false)),
102875
- quiet: boolean4("quiet").pipe(withDefault2(false)),
102876
- debug: boolean4("debug").pipe(withDefault2(false)),
102877
- remnoteDb: string5("remnoteDb").pipe(withDefault2("")),
102878
- storeDb: string5("storeDb").pipe(withDefault2(defaultStoreDbPath())),
102879
- daemonUrl: string5("daemonUrl").pipe(withDefault2("")),
102880
- wsPort: port2("wsPort").pipe(withDefault2(6789)),
102881
- wsScheduler: boolean4("wsScheduler").pipe(withDefault2(true)),
102882
- wsDispatchMaxBytes: integer2("wsDispatchMaxBytes").pipe(withDefault2(512000), validate3({
102883
- message: "wsDispatchMaxBytes must be a positive integer",
102884
- validation: (n) => Number.isFinite(n) && n > 0
102885
- })),
102886
- wsDispatchMaxOpBytes: integer2("wsDispatchMaxOpBytes").pipe(withDefault2(256000), validate3({
102887
- message: "wsDispatchMaxOpBytes must be a positive integer",
102888
- validation: (n) => Number.isFinite(n) && n > 0
102889
- })),
102890
- repo: string5("repo").pipe(withDefault2("")),
102891
- wsStateFile: string5("wsStateFile").pipe(withDefault2("")),
102892
- wsStateStaleMs: integer2("wsStateStaleMs").pipe(withDefault2(60000), validate3({
102893
- message: "wsStateStaleMs must be a positive integer",
102894
- validation: (n) => Number.isFinite(n) && n > 0
102895
- })),
102896
- tmuxRefresh: boolean4("tmuxRefresh").pipe(withDefault2(true)),
102897
- tmuxRefreshMinIntervalMs: integer2("tmuxRefreshMinIntervalMs").pipe(withDefault2(250), validate3({
102898
- message: "tmuxRefreshMinIntervalMs must be a positive integer",
102899
- validation: (n) => Number.isFinite(n) && n > 0
102900
- })),
102901
- statusLineFile: string5("statusLineFile").pipe(withDefault2(defaultStatusLineFilePath())),
102902
- statusLineMinIntervalMs: integer2("statusLineMinIntervalMs").pipe(withDefault2(250), validate3({
102903
- message: "statusLineMinIntervalMs must be a positive integer",
102904
- validation: (n) => Number.isFinite(n) && n > 0
102905
- })),
102906
- statusLineDebug: boolean4("statusLineDebug").pipe(withDefault2(false)),
102907
- statusLineJsonFile: string5("statusLineJsonFile").pipe(withDefault2(defaultStatusLineJsonFilePath())),
102908
- apiBaseUrl: string5("apiBaseUrl").pipe(withDefault2("")),
102909
- apiHost: string5("apiHost").pipe(withDefault2("0.0.0.0")),
102910
- apiPort: port2("apiPort").pipe(withDefault2(3000)),
102911
- apiBasePath: string5("apiBasePath").pipe(withDefault2("/v1")),
102912
- apiPidFile: string5("apiPidFile").pipe(withDefault2(defaultApiPidFilePath())),
102913
- apiLogFile: string5("apiLogFile").pipe(withDefault2(defaultApiLogFilePath())),
102914
- apiStateFile: string5("apiStateFile").pipe(withDefault2(defaultApiStateFilePath()))
102915
- });
102916
- function cliErrorFromConfigError(error4) {
102917
- if (isInvalidData2(error4) || isMissingData2(error4)) {
102918
- return new CliError({
102919
- code: "INVALID_ARGS",
102920
- message: error4.message || "Invalid configuration",
102921
- exitCode: 2,
102922
- details: { path: error4.path, op: error4._op }
102923
- });
102924
- }
102925
- return new CliError({
102926
- code: "INVALID_ARGS",
102927
- message: error4.message || "Invalid configuration",
102928
- exitCode: 2,
102929
- details: { op: error4._op }
102930
- });
102931
- }
102932
- function optionalTrimmed(s) {
102933
- const t = s.trim();
102934
- return t.length > 0 ? t : undefined;
102935
- }
102936
- function resolveConfig() {
102937
- return gen2(function* () {
102938
- const raw4 = yield* rawConfigSpec;
102939
- const wsStateFile = resolveWsStateFile(raw4.wsStateFile);
102940
- const remnoteDb = optionalTrimmed(raw4.remnoteDb) ? resolveUserFilePath(raw4.remnoteDb) : inferRemnoteDbFromWsState({ wsStateFile, wsStateStaleMs: raw4.wsStateStaleMs }) || undefined;
102941
- const storeDb = resolveUserFilePath(raw4.storeDb);
102942
- const daemonUrl = optionalTrimmed(raw4.daemonUrl);
102943
- const wsUrl = daemonUrl ? daemonUrl : wsUrlFromPort(raw4.wsPort);
102944
- const format10 = yield* try_3({
102945
- try: () => pickFormat(raw4),
102946
- catch: (e) => isCliError(e) ? e : new CliError({
102947
- code: "INVALID_ARGS",
102948
- message: "Invalid output format flags",
102949
- exitCode: 2,
102950
- details: { error: String(e?.message || e) }
102951
- })
102952
- });
102953
- const apiBaseUrl = optionalTrimmed(raw4.apiBaseUrl) ? normalizeApiBaseUrl(raw4.apiBaseUrl) : undefined;
102954
- return {
102955
- format: format10,
102956
- quiet: raw4.quiet,
102957
- debug: raw4.debug,
102958
- remnoteDb,
102959
- storeDb,
102960
- wsUrl,
102961
- wsScheduler: raw4.wsScheduler,
102962
- wsDispatchMaxBytes: raw4.wsDispatchMaxBytes,
102963
- wsDispatchMaxOpBytes: raw4.wsDispatchMaxOpBytes,
102964
- repo: optionalTrimmed(raw4.repo) ? resolveUserFilePath(raw4.repo) : undefined,
102965
- wsStateFile,
102966
- wsStateStaleMs: raw4.wsStateStaleMs,
102967
- tmuxRefresh: raw4.tmuxRefresh,
102968
- tmuxRefreshMinIntervalMs: raw4.tmuxRefreshMinIntervalMs,
102969
- statusLineFile: resolveUserFilePath(raw4.statusLineFile),
102970
- statusLineMinIntervalMs: raw4.statusLineMinIntervalMs,
102971
- statusLineDebug: raw4.statusLineDebug,
102972
- statusLineJsonFile: resolveUserFilePath(raw4.statusLineJsonFile),
102973
- apiBaseUrl,
102974
- apiHost: raw4.apiHost.trim() || "0.0.0.0",
102975
- apiPort: raw4.apiPort,
102976
- apiBasePath: normalizeApiBasePath(raw4.apiBasePath),
102977
- apiPidFile: resolveUserFilePath(raw4.apiPidFile),
102978
- apiLogFile: resolveUserFilePath(raw4.apiLogFile),
102979
- apiStateFile: resolveUserFilePath(raw4.apiStateFile)
102980
- };
102981
- }).pipe(catchAll2((error4) => {
102982
- if (isCliError(error4))
102983
- return fail8(error4);
102984
- if (isConfigError2(error4))
102985
- return fail8(cliErrorFromConfigError(error4));
102986
- return fail8(new CliError({
102987
- code: "INTERNAL",
102988
- message: "Failed to parse config",
102989
- exitCode: 1,
102990
- details: { error: String(error4?.message || error4) }
102991
- }));
102992
- }));
102993
- }
102994
-
102995
103554
  // src/commands/index.ts
102996
103555
  function optionToUndefined51(opt) {
102997
103556
  return isSome2(opt) ? opt.value : undefined;
@@ -103002,10 +103561,11 @@ var daemonUrl = text9("daemon-url").pipe(optional5, map34(optionToUndefined51));
103002
103561
  var wsPort = integer7("ws-port").pipe(optional5, map34(optionToUndefined51));
103003
103562
  var repo = text9("repo").pipe(optional5, map34(optionToUndefined51));
103004
103563
  var apiBaseUrl = text9("api-base-url").pipe(optional5, map34(optionToUndefined51));
103564
+ var configFile = text9("config-file").pipe(optional5, map34(optionToUndefined51));
103005
103565
  var appConfigLive = effect(AppConfig, resolveConfig());
103006
103566
  var statusLineUpdaterLive = StatusLineUpdaterLive.pipe(provide3([appConfigLive, QueueLive, StatusLineFileLive, TmuxLive, WsBridgeStateLive]));
103007
103567
  var statusLineLive = StatusLineControllerLive.pipe(provide3(statusLineUpdaterLive), provide3(appConfigLive));
103008
- var servicesLive = mergeAll5(appConfigLive, OutputLive, FileInputLive, FsAccessLive, LogWriterFactoryLive, PayloadLive, DaemonFilesLive, ApiDaemonFilesLive, ProcessLive, ChildProcessLive, WsClientLive, HostApiClientLive, QueueLive, RefResolverLive, RemDbLive, StatusLineFileLive, SubprocessLive, SupervisorStateLive, WsBridgeServerLive, WsBridgeStateFileLive, statusLineLive);
103568
+ var servicesLive = mergeAll5(appConfigLive, OutputLive, FileInputLive, FsAccessLive, LogWriterFactoryLive, PayloadLive, DaemonFilesLive, ApiDaemonFilesLive, ProcessLive, ChildProcessLive, WsClientLive, HostApiClientLive, UserConfigFileLive, QueueLive, RefResolverLive, RemDbLive, StatusLineFileLive, SubprocessLive, SupervisorStateLive, WsBridgeServerLive, WsBridgeStateFileLive, statusLineLive);
103009
103569
  var rootCommand = exports_Command.make("agent-remnote", {
103010
103570
  json: boolean8("json"),
103011
103571
  md: boolean8("md"),
@@ -103017,7 +103577,8 @@ var rootCommand = exports_Command.make("agent-remnote", {
103017
103577
  daemonUrl,
103018
103578
  wsPort,
103019
103579
  repo,
103020
- apiBaseUrl
103580
+ apiBaseUrl,
103581
+ configFile
103021
103582
  }).pipe(exports_Command.withSubcommands([
103022
103583
  daemonCommand,
103023
103584
  apiCommand,
@@ -103119,6 +103680,9 @@ function buildCliEnvConfigProvider(params3) {
103119
103680
  const envApiBaseUrl = env2.REMNOTE_API_BASE_URL;
103120
103681
  if (typeof envApiBaseUrl === "string" && envApiBaseUrl.trim())
103121
103682
  map39.set("apiBaseUrl", envApiBaseUrl);
103683
+ const envConfigFile = env2.REMNOTE_CONFIG_FILE || env2.AGENT_REMNOTE_CONFIG_FILE;
103684
+ if (typeof envConfigFile === "string" && envConfigFile.trim())
103685
+ map39.set("configFile", envConfigFile);
103122
103686
  const envApiHost = env2.REMNOTE_API_HOST;
103123
103687
  if (typeof envApiHost === "string" && envApiHost.trim())
103124
103688
  map39.set("apiHost", envApiHost);
@@ -103215,17 +103779,18 @@ function buildCommandTree(desc) {
103215
103779
  }
103216
103780
  return { name, children: children2 };
103217
103781
  }
103218
- var ROOT_BOOL_FLAGS = new Set(["--json", "--md", "--ids", "--quiet", "--debug"]);
103219
- var BUILTIN_BOOL_FLAGS = new Set(["--help", "-h", "--wizard", "--version"]);
103220
- var BUILTIN_VALUE_FLAGS = new Set(["--completions", "--log-level"]);
103221
- var ROOT_VALUE_FLAGS = new Set([
103782
+ var ROOT_BOOL_FLAGS2 = new Set(["--json", "--md", "--ids", "--quiet", "--debug"]);
103783
+ var BUILTIN_BOOL_FLAGS2 = new Set(["--help", "-h", "--wizard", "--version"]);
103784
+ var BUILTIN_VALUE_FLAGS2 = new Set(["--completions", "--log-level"]);
103785
+ var ROOT_VALUE_FLAGS2 = new Set([
103222
103786
  "--remnote-db",
103223
103787
  "--store-db",
103224
103788
  "--daemon-url",
103225
103789
  "--ws-port",
103226
103790
  "--repo",
103227
103791
  "--api-base-url",
103228
- ...BUILTIN_VALUE_FLAGS
103792
+ "--config-file",
103793
+ ...BUILTIN_VALUE_FLAGS2
103229
103794
  ]);
103230
103795
  function parseRootConfigFromArgv(argv2) {
103231
103796
  const tokens = argv2.slice(2);
@@ -103239,8 +103804,8 @@ function parseRootConfigFromArgv(argv2) {
103239
103804
  break;
103240
103805
  if (!raw4.startsWith("-"))
103241
103806
  break;
103242
- const { flag, inlineValue } = splitFlagInlineValue(raw4);
103243
- if (ROOT_BOOL_FLAGS.has(flag)) {
103807
+ const { flag, inlineValue } = splitFlagInlineValue2(raw4);
103808
+ if (ROOT_BOOL_FLAGS2.has(flag)) {
103244
103809
  const key = flag.slice(2);
103245
103810
  if (inlineValue !== null) {
103246
103811
  out.set(key, inlineValue.trim().toLowerCase());
@@ -103248,7 +103813,7 @@ function parseRootConfigFromArgv(argv2) {
103248
103813
  continue;
103249
103814
  }
103250
103815
  const next4 = tokens[i + 1];
103251
- if (typeof next4 === "string" && isBooleanLiteralToken(next4)) {
103816
+ if (typeof next4 === "string" && isBooleanLiteralToken2(next4)) {
103252
103817
  out.set(key, next4.trim().toLowerCase());
103253
103818
  i += 2;
103254
103819
  continue;
@@ -103257,8 +103822,8 @@ function parseRootConfigFromArgv(argv2) {
103257
103822
  i += 1;
103258
103823
  continue;
103259
103824
  }
103260
- if (ROOT_VALUE_FLAGS.has(flag)) {
103261
- const key = flag === "--remnote-db" ? "remnoteDb" : flag === "--store-db" ? "storeDb" : flag === "--daemon-url" ? "daemonUrl" : flag === "--ws-port" ? "wsPort" : flag === "--repo" ? "repo" : flag === "--api-base-url" ? "apiBaseUrl" : null;
103825
+ if (ROOT_VALUE_FLAGS2.has(flag)) {
103826
+ const key = flag === "--remnote-db" ? "remnoteDb" : flag === "--store-db" ? "storeDb" : flag === "--daemon-url" ? "daemonUrl" : flag === "--ws-port" ? "wsPort" : flag === "--repo" ? "repo" : flag === "--api-base-url" ? "apiBaseUrl" : flag === "--config-file" ? "configFile" : null;
103262
103827
  if (inlineValue !== null) {
103263
103828
  if (key)
103264
103829
  out.set(key, inlineValue);
@@ -103273,13 +103838,13 @@ function parseRootConfigFromArgv(argv2) {
103273
103838
  i += 2;
103274
103839
  continue;
103275
103840
  }
103276
- if (BUILTIN_BOOL_FLAGS.has(flag)) {
103841
+ if (BUILTIN_BOOL_FLAGS2.has(flag)) {
103277
103842
  if (inlineValue !== null) {
103278
103843
  i += 1;
103279
103844
  continue;
103280
103845
  }
103281
103846
  const next4 = tokens[i + 1];
103282
- if (typeof next4 === "string" && isBooleanLiteralToken(next4)) {
103847
+ if (typeof next4 === "string" && isBooleanLiteralToken2(next4)) {
103283
103848
  i += 2;
103284
103849
  continue;
103285
103850
  }
@@ -103290,11 +103855,11 @@ function parseRootConfigFromArgv(argv2) {
103290
103855
  }
103291
103856
  return out;
103292
103857
  }
103293
- function isBooleanLiteralToken(token) {
103858
+ function isBooleanLiteralToken2(token) {
103294
103859
  const v = token.trim().toLowerCase();
103295
103860
  return v === "true" || v === "false";
103296
103861
  }
103297
- function splitFlagInlineValue(token) {
103862
+ function splitFlagInlineValue2(token) {
103298
103863
  if (!token.startsWith("--"))
103299
103864
  return { flag: token, inlineValue: null };
103300
103865
  const eq = token.indexOf("=");
@@ -103303,7 +103868,7 @@ function splitFlagInlineValue(token) {
103303
103868
  return { flag: token.slice(0, eq), inlineValue: token.slice(eq + 1) };
103304
103869
  }
103305
103870
  function isKnownRootFlag(flag) {
103306
- return ROOT_BOOL_FLAGS.has(flag) || ROOT_VALUE_FLAGS.has(flag) || BUILTIN_BOOL_FLAGS.has(flag);
103871
+ return ROOT_BOOL_FLAGS2.has(flag) || ROOT_VALUE_FLAGS2.has(flag) || BUILTIN_BOOL_FLAGS2.has(flag);
103307
103872
  }
103308
103873
  function consumeRootFlag(tokens, index) {
103309
103874
  const raw4 = String(tokens[index] ?? "");
@@ -103313,14 +103878,14 @@ function consumeRootFlag(tokens, index) {
103313
103878
  error: new CliError({ code: "INVALID_ARGS", message: "Received unknown argument: ''", exitCode: 2 })
103314
103879
  };
103315
103880
  }
103316
- const { flag, inlineValue } = splitFlagInlineValue(raw4);
103881
+ const { flag, inlineValue } = splitFlagInlineValue2(raw4);
103317
103882
  if (!isKnownRootFlag(flag)) {
103318
103883
  return {
103319
103884
  nextIndex: index + 1,
103320
103885
  error: new CliError({ code: "INVALID_ARGS", message: `Received unknown argument: '${raw4}'`, exitCode: 2 })
103321
103886
  };
103322
103887
  }
103323
- if (ROOT_VALUE_FLAGS.has(flag)) {
103888
+ if (ROOT_VALUE_FLAGS2.has(flag)) {
103324
103889
  if (inlineValue !== null)
103325
103890
  return { nextIndex: index + 1, error: null };
103326
103891
  if (index + 1 >= tokens.length) {
@@ -103335,8 +103900,8 @@ function consumeRootFlag(tokens, index) {
103335
103900
  }
103336
103901
  return { nextIndex: index + 2, error: null };
103337
103902
  }
103338
- if (ROOT_BOOL_FLAGS.has(flag) || BUILTIN_BOOL_FLAGS.has(flag)) {
103339
- if (inlineValue !== null && !isBooleanLiteralToken(inlineValue)) {
103903
+ if (ROOT_BOOL_FLAGS2.has(flag) || BUILTIN_BOOL_FLAGS2.has(flag)) {
103904
+ if (inlineValue !== null && !isBooleanLiteralToken2(inlineValue)) {
103340
103905
  return {
103341
103906
  nextIndex: index + 1,
103342
103907
  error: new CliError({
@@ -103349,7 +103914,7 @@ function consumeRootFlag(tokens, index) {
103349
103914
  if (inlineValue !== null)
103350
103915
  return { nextIndex: index + 1, error: null };
103351
103916
  const next4 = tokens[index + 1];
103352
- if (typeof next4 === "string" && isBooleanLiteralToken(next4))
103917
+ if (typeof next4 === "string" && isBooleanLiteralToken2(next4))
103353
103918
  return { nextIndex: index + 2, error: null };
103354
103919
  return { nextIndex: index + 1, error: null };
103355
103920
  }
@@ -103357,8 +103922,8 @@ function consumeRootFlag(tokens, index) {
103357
103922
  }
103358
103923
  function consumeBuiltInFlag(tokens, index) {
103359
103924
  const raw4 = String(tokens[index] ?? "");
103360
- const { flag, inlineValue } = splitFlagInlineValue(raw4);
103361
- if (BUILTIN_VALUE_FLAGS.has(flag)) {
103925
+ const { flag, inlineValue } = splitFlagInlineValue2(raw4);
103926
+ if (BUILTIN_VALUE_FLAGS2.has(flag)) {
103362
103927
  if (inlineValue !== null)
103363
103928
  return { ok: true, nextIndex: index + 1, error: null };
103364
103929
  if (index + 1 >= tokens.length) {
@@ -103374,8 +103939,8 @@ function consumeBuiltInFlag(tokens, index) {
103374
103939
  }
103375
103940
  return { ok: true, nextIndex: index + 2, error: null };
103376
103941
  }
103377
- if (BUILTIN_BOOL_FLAGS.has(flag)) {
103378
- if (inlineValue !== null && !isBooleanLiteralToken(inlineValue)) {
103942
+ if (BUILTIN_BOOL_FLAGS2.has(flag)) {
103943
+ if (inlineValue !== null && !isBooleanLiteralToken2(inlineValue)) {
103379
103944
  return {
103380
103945
  ok: true,
103381
103946
  nextIndex: index + 1,
@@ -103389,7 +103954,7 @@ function consumeBuiltInFlag(tokens, index) {
103389
103954
  if (inlineValue !== null)
103390
103955
  return { ok: true, nextIndex: index + 1, error: null };
103391
103956
  const next4 = tokens[index + 1];
103392
- if (typeof next4 === "string" && isBooleanLiteralToken(next4))
103957
+ if (typeof next4 === "string" && isBooleanLiteralToken2(next4))
103393
103958
  return { ok: true, nextIndex: index + 2, error: null };
103394
103959
  return { ok: true, nextIndex: index + 1, error: null };
103395
103960
  }
@@ -103442,8 +104007,8 @@ function strictCliPreflight(tree, argv2) {
103442
104007
  i = builtIn2.nextIndex;
103443
104008
  continue;
103444
104009
  }
103445
- const { flag } = splitFlagInlineValue(t);
103446
- if (isKnownRootFlag(flag) && !BUILTIN_BOOL_FLAGS.has(flag) && !BUILTIN_VALUE_FLAGS.has(flag)) {
104010
+ const { flag } = splitFlagInlineValue2(t);
104011
+ if (isKnownRootFlag(flag) && !BUILTIN_BOOL_FLAGS2.has(flag) && !BUILTIN_VALUE_FLAGS2.has(flag)) {
103447
104012
  return new CliError({
103448
104013
  code: "INVALID_ARGS",
103449
104014
  message: `Global option '${flag}' must be specified before the first subcommand`,
@@ -103652,7 +104217,7 @@ function strictCommandPreflightOrExit(argv2) {
103652
104217
  if (jsonRequested) {
103653
104218
  const tokens = argv2.slice(2);
103654
104219
  const outputBuiltins = new Set(["--help", "-h", "--version", "--wizard", "--completions"]);
103655
- const conflict = tokens.map((t) => splitFlagInlineValue(String(t)).flag).find((flag) => outputBuiltins.has(flag));
104220
+ const conflict = tokens.map((t) => splitFlagInlineValue2(String(t)).flag).find((flag) => outputBuiltins.has(flag));
103656
104221
  if (conflict) {
103657
104222
  const error5 = new CliError({
103658
104223
  code: "INVALID_ARGS",