agent-remnote 1.3.1 → 1.3.3

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
@@ -43209,6 +43209,10 @@ var mapErrorCause = /* @__PURE__ */ dual(2, (self, f) => matchCauseEffect(self,
43209
43209
  onSuccess: succeed
43210
43210
  }));
43211
43211
  var negate = (self) => map12(self, (b) => !b);
43212
+ var option = (self) => matchEffect(self, {
43213
+ onFailure: () => succeed(none2()),
43214
+ onSuccess: (a) => succeed(some2(a))
43215
+ });
43212
43216
  var orElseFail = /* @__PURE__ */ dual(2, (self, evaluate2) => orElse2(self, () => failSync(evaluate2)));
43213
43217
  var patchFiberRefs = (patch11) => updateFiberRefs((fiberId2, fiberRefs3) => pipe(patch11, patch9(fiberId2, fiberRefs3)));
43214
43218
  var promise = (evaluate2) => evaluate2.length >= 1 ? async_((resolve, signal) => {
@@ -47914,13 +47918,13 @@ var exponential2 = (baseInput, factor = 2) => {
47914
47918
  var fixed2 = (intervalInput) => {
47915
47919
  const interval = decode(intervalInput);
47916
47920
  const intervalMillis = toMillis(interval);
47917
- return makeWithState([none2(), 0], (now, _, [option, n]) => sync(() => {
47918
- switch (option._tag) {
47921
+ return makeWithState([none2(), 0], (now, _, [option2, n]) => sync(() => {
47922
+ switch (option2._tag) {
47919
47923
  case "None": {
47920
47924
  return [[some2([now, now + intervalMillis]), n + 1], n, continueWith2(after2(now + intervalMillis))];
47921
47925
  }
47922
47926
  case "Some": {
47923
- const [startMillis, lastRun] = option.value;
47927
+ const [startMillis, lastRun] = option2.value;
47924
47928
  const runningBehind = now > lastRun + intervalMillis;
47925
47929
  const boundary = equals(interval, zero) ? interval : millis(intervalMillis - (now - startMillis) % intervalMillis);
47926
47930
  const sleepTime = equals(boundary, zero) ? interval : boundary;
@@ -48041,7 +48045,7 @@ var repeat_combined = /* @__PURE__ */ dual(2, (self, options) => {
48041
48045
  });
48042
48046
  var repeatOrElse_Effect = /* @__PURE__ */ dual(3, (self, schedule, orElse4) => flatMap7(driver(schedule), (driver2) => matchEffect(self, {
48043
48047
  onFailure: (error3) => orElse4(error3, none2()),
48044
- onSuccess: (value) => repeatOrElseEffectLoop(provideServiceEffect(self, CurrentIterationMetadata, get10(driver2.iterationMeta)), driver2, (error3, option) => provideServiceEffect(orElse4(error3, option), CurrentIterationMetadata, get10(driver2.iterationMeta)), value)
48048
+ onSuccess: (value) => repeatOrElseEffectLoop(provideServiceEffect(self, CurrentIterationMetadata, get10(driver2.iterationMeta)), driver2, (error3, option2) => provideServiceEffect(orElse4(error3, option2), CurrentIterationMetadata, get10(driver2.iterationMeta)), value)
48045
48049
  })));
48046
48050
  var repeatOrElseEffectLoop = (self, driver2, orElse4, value) => matchEffect(driver2.next(value), {
48047
48051
  onFailure: () => orDie(driver2.last),
@@ -48364,6 +48368,7 @@ var provide2 = effect_provide;
48364
48368
  var provideService2 = provideService;
48365
48369
  var provideServiceEffect2 = provideServiceEffect;
48366
48370
  var serviceOption2 = serviceOption;
48371
+ var option2 = option;
48367
48372
  var either3 = either2;
48368
48373
  var exit2 = exit;
48369
48374
  var intoDeferred2 = intoDeferred;
@@ -55481,7 +55486,7 @@ var orElseIf = /* @__PURE__ */ dual(2, (self, options) => {
55481
55486
  fallback.condition = options.if;
55482
55487
  return fallback;
55483
55488
  });
55484
- var option2 = (self) => {
55489
+ var option3 = (self) => {
55485
55490
  return pipe(self, map24(some2), orElseIf({
55486
55491
  orElse: () => succeed17(none2()),
55487
55492
  if: isMissingDataOnly2
@@ -55595,7 +55600,7 @@ var integer2 = integer;
55595
55600
  var duration3 = duration2;
55596
55601
  var isConfig2 = isConfig;
55597
55602
  var map25 = map24;
55598
- var option3 = option2;
55603
+ var option4 = option3;
55599
55604
  var string5 = string4;
55600
55605
  var validate3 = validate2;
55601
55606
  var withDefault2 = withDefault;
@@ -61444,7 +61449,7 @@ var validateInternal = (self, value6, config2) => {
61444
61449
  }
61445
61450
  }
61446
61451
  };
61447
- var attempt = (option5, typeName, parse5) => orElseFail2(option5, () => `${typeName} options do not have a default value`).pipe(flatMap9((value6) => orElseFail2(parse5(value6), () => `'${value6}' is not a ${typeName}`)));
61452
+ var attempt = (option6, typeName, parse5) => orElseFail2(option6, () => `${typeName} options do not have a default value`).pipe(flatMap9((value6) => orElseFail2(parse5(value6), () => `'${value6}' is not a ${typeName}`)));
61448
61453
  var validatePathExistence = (path, shouldPathExist, pathExists) => {
61449
61454
  if (shouldPathExist === "no" && pathExists) {
61450
61455
  return fail8(`Path '${path}' must not exist`);
@@ -62313,14 +62318,14 @@ var boolean7 = (name, options3) => {
62313
62318
  ...defaultBooleanOptions,
62314
62319
  ...options3
62315
62320
  };
62316
- const option5 = makeSingle(name, aliases, boolean5(some2(ifPresent)));
62321
+ const option6 = makeSingle(name, aliases, boolean5(some2(ifPresent)));
62317
62322
  if (isNonEmptyReadonlyArray(negationNames)) {
62318
62323
  const head5 = headNonEmpty(negationNames);
62319
62324
  const tail = tailNonEmpty(negationNames);
62320
62325
  const negationOption = makeSingle(head5, tail, boolean5(some2(!ifPresent)));
62321
- return withDefault4(orElse13(option5, negationOption), !ifPresent);
62326
+ return withDefault4(orElse13(option6, negationOption), !ifPresent);
62322
62327
  }
62323
- return withDefault4(option5, !ifPresent);
62328
+ return withDefault4(option6, !ifPresent);
62324
62329
  };
62325
62330
  var choice4 = (name, choices) => {
62326
62331
  const primitive2 = choice2(map5(choices, (choice5) => [choice5, choice5]));
@@ -62861,7 +62866,7 @@ var wizardInternal3 = (self, config2) => {
62861
62866
  return select({
62862
62867
  message: toAnsiText(message).trimEnd(),
62863
62868
  choices
62864
- }).pipe(flatMap9((option5) => wizardInternal3(option5, config2)));
62869
+ }).pipe(flatMap9((option6) => wizardInternal3(option6, config2)));
62865
62870
  }
62866
62871
  case "Variadic": {
62867
62872
  const repeatHelp = p("How many times should this argument be repeated?");
@@ -63510,11 +63515,12 @@ var map34 = map32;
63510
63515
  var optional5 = optional4;
63511
63516
  var repeated5 = repeated4;
63512
63517
  var withDefault5 = withDefault4;
63518
+ var withDescription5 = withDescription4;
63513
63519
 
63514
63520
  // ../../node_modules/@effect/cli/dist/esm/internal/commandDirective.js
63515
- var builtIn = (option5) => ({
63521
+ var builtIn = (option6) => ({
63516
63522
  _tag: "BuiltIn",
63517
- option: option5
63523
+ option: option6
63518
63524
  });
63519
63525
  var userDefined = (leftover2, value6) => ({
63520
63526
  _tag: "UserDefined",
@@ -63570,7 +63576,7 @@ var mapEffect7 = /* @__PURE__ */ dual(2, (self, f) => {
63570
63576
  return op;
63571
63577
  });
63572
63578
  var parse7 = /* @__PURE__ */ dual(3, (self, args2, config2) => parseInternal2(self, args2, config2));
63573
- var withDescription5 = /* @__PURE__ */ dual(2, (self, help) => withDescriptionInternal(self, help));
63579
+ var withDescription6 = /* @__PURE__ */ dual(2, (self, help) => withDescriptionInternal(self, help));
63574
63580
  var withSubcommands = /* @__PURE__ */ dual(2, (self, subcommands) => {
63575
63581
  const op = Object.create(proto23);
63576
63582
  op._tag = "Subcommands";
@@ -64033,7 +64039,7 @@ var getFishCompletionsInternal = (self, executable) => traverseCommand(self, emp
64033
64039
  const options3 = isStandard(info2.command) ? all10([builtIns, info2.command.options]) : builtIns;
64034
64040
  const optionsCompletions = getFishCompletions3(options3);
64035
64041
  const argsCompletions = isStandard(info2.command) ? getFishCompletions2(info2.command.args) : empty2();
64036
- const rootCompletions = (conditionals2) => pipe(map5(optionsCompletions, (option5) => pipe(baseTemplate, appendAll(conditionals2), append(option5), join(" "))), appendAll(map5(argsCompletions, (option5) => pipe(baseTemplate, appendAll(conditionals2), append(option5), join(" ")))));
64042
+ const rootCompletions = (conditionals2) => pipe(map5(optionsCompletions, (option6) => pipe(baseTemplate, appendAll(conditionals2), append(option6), join(" "))), appendAll(map5(argsCompletions, (option6) => pipe(baseTemplate, appendAll(conditionals2), append(option6), join(" ")))));
64037
64043
  const subcommandCompletions = (conditionals2) => map5(info2.subcommands, ([name, subcommand]) => {
64038
64044
  const description = getShortDescription3(subcommand);
64039
64045
  return pipe(baseTemplate, appendAll(conditionals2), appendAll(make4("-f", "-a", `"${name}"`)), appendAll(description.length === 0 ? empty2() : make4("-d", `'${description}'`)), join(" "));
@@ -64276,7 +64282,7 @@ __export(exports_Command, {
64276
64282
  wizard: () => wizard6,
64277
64283
  withSubcommands: () => withSubcommands3,
64278
64284
  withHandler: () => withHandler2,
64279
- withDescription: () => withDescription7,
64285
+ withDescription: () => withDescription8,
64280
64286
  transformHandler: () => transformHandler2,
64281
64287
  run: () => run8,
64282
64288
  provideSync: () => provideSync2,
@@ -64447,7 +64453,7 @@ var provideSync = /* @__PURE__ */ dual(3, (self, tag4, f) => makeDerive(self, {
64447
64453
  return provideService2(self2, tag4, service2);
64448
64454
  }
64449
64455
  }));
64450
- var withDescription6 = /* @__PURE__ */ dual(2, (self, help) => mapDescriptor(self, withDescription5(help)));
64456
+ var withDescription7 = /* @__PURE__ */ dual(2, (self, help) => mapDescriptor(self, withDescription6(help)));
64451
64457
  var withSubcommands2 = /* @__PURE__ */ dual(2, (self, subcommands) => {
64452
64458
  const command = withSubcommands(self.descriptor, map5(subcommands, (_) => [_.tag, _.descriptor]));
64453
64459
  const subcommandMap = reduce(subcommands, new Map, (handlers, subcommand) => {
@@ -64497,7 +64503,7 @@ var provideEffect2 = provideEffect;
64497
64503
  var provideEffectDiscard2 = provideEffectDiscard;
64498
64504
  var provideSync2 = provideSync;
64499
64505
  var transformHandler2 = transformHandler;
64500
- var withDescription7 = withDescription6;
64506
+ var withDescription8 = withDescription7;
64501
64507
  var withHandler2 = withHandler;
64502
64508
  var withSubcommands3 = withSubcommands2;
64503
64509
  var wizard6 = wizard5;
@@ -70636,11 +70642,11 @@ var config2 = /* @__PURE__ */ all8({
70636
70642
  runnerAddress: /* @__PURE__ */ all8({
70637
70643
  host: string5("host").pipe(withDefault2(defaultRunnerAddress.host), withDescription2("The hostname or IP address of the runner.")),
70638
70644
  port: integer2("port").pipe(withDefault2(defaultRunnerAddress.port), withDescription2("The port used for inter-runner communication."))
70639
- }).pipe(/* @__PURE__ */ map25((options6) => RunnerAddress.make(options6)), option3),
70645
+ }).pipe(/* @__PURE__ */ map25((options6) => RunnerAddress.make(options6)), option4),
70640
70646
  runnerListenAddress: /* @__PURE__ */ all8({
70641
70647
  host: string5("listenHost").pipe(withDescription2("The host to listen on.")),
70642
70648
  port: integer2("listenPort").pipe(withDefault2(defaultRunnerAddress.port), withDescription2("The port to listen on."))
70643
- }).pipe(/* @__PURE__ */ map25((options6) => RunnerAddress.make(options6)), option3),
70649
+ }).pipe(/* @__PURE__ */ map25((options6) => RunnerAddress.make(options6)), option4),
70644
70650
  runnerShardWeight: /* @__PURE__ */ integer2("runnerShardWeight").pipe(/* @__PURE__ */ withDefault2(defaults.runnerShardWeight)),
70645
70651
  shardGroups: /* @__PURE__ */ array5(string5("shardGroups")).pipe(/* @__PURE__ */ withDefault2(["default"]), /* @__PURE__ */ withDescription2("The shard groups that are assigned to this runner.")),
70646
70652
  shardsPerGroup: /* @__PURE__ */ integer2("shardsPerGroup").pipe(/* @__PURE__ */ withDefault2(defaults.shardsPerGroup), /* @__PURE__ */ withDescription2("The number of shards to allocate per shard group.")),
@@ -73914,7 +73920,7 @@ var platformRunnerImpl = /* @__PURE__ */ PlatformRunner2.of({
73914
73920
  }
73915
73921
  });
73916
73922
  // src/main.ts
73917
- import { readFileSync as readFileSync2 } from "node:fs";
73923
+ import { readFileSync as readFileSync4 } from "node:fs";
73918
73924
  import { format as format10 } from "node:util";
73919
73925
 
73920
73926
  // src/services/UserConfigFile.ts
@@ -76530,6 +76536,18 @@ function readAppliedMigrations(db) {
76530
76536
  return new Map;
76531
76537
  }
76532
76538
  }
76539
+ function readStoreSchemaStatus(db) {
76540
+ const applied = readAppliedMigrations(db);
76541
+ const currentUserVersion = readUserVersion(db);
76542
+ const appliedVersions = Array.from(applied.keys()).sort((a, b) => a - b);
76543
+ const latestAppliedVersion = appliedVersions.length > 0 ? appliedVersions[appliedVersions.length - 1] : 0;
76544
+ return {
76545
+ current_user_version: currentUserVersion,
76546
+ latest_supported_version: LATEST_USER_VERSION,
76547
+ applied_migrations: applied.size,
76548
+ latest_applied_version: latestAppliedVersion
76549
+ };
76550
+ }
76533
76551
  function ensureMigrationRecorded(db, migration9, appliedAt, appVersion) {
76534
76552
  const existing = db.prepare(`SELECT name, checksum FROM store_migrations WHERE version=?`).get(migration9.version);
76535
76553
  if (existing) {
@@ -76869,10 +76887,10 @@ var OP_CATALOG = {
76869
76887
  op_type: "create_rem",
76870
76888
  aliases: ["rem.create"],
76871
76889
  payload: {
76872
- required: ["parent_id"],
76873
- optional: ["text", "tags", "is_document", "position", "client_temp_id"]
76890
+ required: [],
76891
+ optional: ["parent_id", "standalone", "text", "tags", "is_document", "position", "client_temp_id"]
76874
76892
  },
76875
- description: "Create a Rem (parent required).",
76893
+ description: "Create a Rem (either parent_id or standalone=true required).",
76876
76894
  id_fields: ["parent_id", "tags[]"]
76877
76895
  },
76878
76896
  create_portal: {
@@ -76905,8 +76923,11 @@ var OP_CATALOG = {
76905
76923
  move_rem: {
76906
76924
  op_type: "move_rem",
76907
76925
  aliases: ["rem.move"],
76908
- payload: { required: ["rem_id", "new_parent_id"], optional: ["position"] },
76909
- description: "Move a Rem to a new parent.",
76926
+ payload: {
76927
+ required: ["rem_id"],
76928
+ optional: ["new_parent_id", "standalone", "position", "is_document", "leave_portal"]
76929
+ },
76930
+ description: "Move a Rem to a new parent or to standalone top-level placement.",
76910
76931
  id_fields: ["rem_id", "new_parent_id"]
76911
76932
  },
76912
76933
  delete_rem: {
@@ -78999,6 +79020,7 @@ function toWsBridgeClient(client) {
78999
79020
  remoteAddr: client.remoteAddr,
79000
79021
  userAgent: client.userAgent,
79001
79022
  readyState: client.readyState,
79023
+ runtime: client.runtime,
79002
79024
  selection: client.selection,
79003
79025
  uiContext: client.uiContext
79004
79026
  };
@@ -79059,6 +79081,10 @@ function buildClientsSnapshot(params3) {
79059
79081
 
79060
79082
  // src/lib/wsBridgeCore.ts
79061
79083
  var STATE_WRITE_TIMER_ID = "state-write";
79084
+ function normalizeRuntimeNumber(value8) {
79085
+ const parsed = Number(value8 ?? 0);
79086
+ return Number.isFinite(parsed) && parsed >= 0 ? Math.floor(parsed) : 0;
79087
+ }
79062
79088
  function newClientState(params3) {
79063
79089
  return {
79064
79090
  connId: params3.connId,
@@ -79317,10 +79343,20 @@ function makeWsBridgeCore(params3) {
79317
79343
  const protocolVersionRaw = typeof msg?.protocolVersion === "number" ? msg.protocolVersion : typeof msg?.protocol_version === "number" ? msg.protocol_version : undefined;
79318
79344
  const protocolVersion = typeof protocolVersionRaw === "number" && Number.isFinite(protocolVersionRaw) && protocolVersionRaw > 0 ? Math.floor(protocolVersionRaw) : undefined;
79319
79345
  const capabilities = msg?.capabilities && typeof msg.capabilities === "object" ? msg.capabilities : {};
79346
+ const runtime6 = msg?.runtime && typeof msg.runtime === "object" ? {
79347
+ name: typeof msg.runtime.name === "string" ? msg.runtime.name : "unknown",
79348
+ version: typeof msg.runtime.version === "string" ? msg.runtime.version : "0.0.0",
79349
+ build_id: typeof msg.runtime.build_id === "string" ? msg.runtime.build_id : "unknown",
79350
+ built_at: normalizeRuntimeNumber(msg.runtime.built_at),
79351
+ source_stamp: normalizeRuntimeNumber(msg.runtime.source_stamp),
79352
+ mode: typeof msg.runtime.mode === "string" ? msg.runtime.mode : undefined
79353
+ } : undefined;
79320
79354
  client.clientType = clientType || client.clientType;
79321
79355
  client.clientInstanceId = clientInstanceIdRaw ? clientInstanceIdRaw : null;
79322
79356
  if (protocolVersion)
79323
79357
  client.protocolVersion = protocolVersion;
79358
+ if (runtime6)
79359
+ client.runtime = runtime6;
79324
79360
  client.capabilities = {
79325
79361
  control: !!capabilities?.control,
79326
79362
  worker: !!capabilities?.worker,
@@ -79338,6 +79374,7 @@ function makeWsBridgeCore(params3) {
79338
79374
  connId: event.connId,
79339
79375
  clientType: client.clientType ?? null,
79340
79376
  protocolVersion: client.protocolVersion ?? null,
79377
+ runtime: client.runtime ?? null,
79341
79378
  capabilities: client.capabilities ?? null
79342
79379
  }
79343
79380
  });
@@ -91113,7 +91150,7 @@ var WsClientLive = succeed10(WsClient, {
91113
91150
  });
91114
91151
 
91115
91152
  // src/commands/ws/_shared.ts
91116
- import path17 from "node:path";
91153
+ import path18 from "node:path";
91117
91154
 
91118
91155
  // src/services/Process.ts
91119
91156
  import { spawn as spawn3 } from "node:child_process";
@@ -91205,6 +91242,121 @@ var ProcessLive = succeed10(Process, {
91205
91242
  })
91206
91243
  });
91207
91244
 
91245
+ // src/lib/runtimeBuildInfo.ts
91246
+ import { createHash as createHash3 } from "node:crypto";
91247
+ import { existsSync as existsSync2, readFileSync as readFileSync2, readdirSync, statSync } from "node:fs";
91248
+ import path17 from "node:path";
91249
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
91250
+ function packageInfo() {
91251
+ try {
91252
+ const raw4 = readFileSync2(new URL("../../package.json", import.meta.url), "utf8");
91253
+ const parsed = JSON.parse(raw4);
91254
+ const name = typeof parsed?.name === "string" && parsed.name.trim() ? parsed.name.trim() : "agent-remnote";
91255
+ const version = typeof parsed?.version === "string" && parsed.version.trim() ? parsed.version.trim() : "0.0.0";
91256
+ return { name, version };
91257
+ } catch {
91258
+ return { name: "agent-remnote", version: "0.0.0" };
91259
+ }
91260
+ }
91261
+ function fileMtimeMs(targetPath) {
91262
+ try {
91263
+ return Math.floor(statSync(targetPath).mtimeMs);
91264
+ } catch {
91265
+ return 0;
91266
+ }
91267
+ }
91268
+ function latestMtimeMs(dirPath) {
91269
+ if (!existsSync2(dirPath))
91270
+ return 0;
91271
+ let max7 = 0;
91272
+ const stack = [dirPath];
91273
+ while (stack.length > 0) {
91274
+ const current2 = stack.pop();
91275
+ let entries2 = [];
91276
+ try {
91277
+ entries2 = readdirSync(current2);
91278
+ } catch {
91279
+ continue;
91280
+ }
91281
+ for (const entry of entries2) {
91282
+ const full = path17.join(current2, entry);
91283
+ let st;
91284
+ try {
91285
+ st = statSync(full);
91286
+ } catch {
91287
+ continue;
91288
+ }
91289
+ if (st.isDirectory()) {
91290
+ stack.push(full);
91291
+ } else if (st.isFile()) {
91292
+ max7 = Math.max(max7, Math.floor(st.mtimeMs));
91293
+ }
91294
+ }
91295
+ }
91296
+ return max7;
91297
+ }
91298
+ function detectMode() {
91299
+ const url2 = import.meta.url;
91300
+ if (url2.includes("/src/"))
91301
+ return "src";
91302
+ if (url2.includes("/dist/"))
91303
+ return "dist";
91304
+ return "unknown";
91305
+ }
91306
+ function computeDefaultBuildInfo() {
91307
+ const pkg = packageInfo();
91308
+ const mode = detectMode();
91309
+ const srcDir = new URL("../", import.meta.url);
91310
+ const packageJson = new URL("../../package.json", import.meta.url);
91311
+ const sourceStamp = Math.max(latestMtimeMs(fileURLToPath2(srcDir)), fileMtimeMs(fileURLToPath2(packageJson)));
91312
+ const buildIdInput = `${pkg.name}
91313
+ ${pkg.version}
91314
+ ${mode}
91315
+ ${sourceStamp}`;
91316
+ const buildId = createHash3("sha256").update(buildIdInput).digest("hex").slice(0, 12);
91317
+ return {
91318
+ name: pkg.name,
91319
+ version: pkg.version,
91320
+ build_id: `${pkg.version}:${buildId}`,
91321
+ built_at: sourceStamp || Date.now(),
91322
+ source_stamp: sourceStamp || Date.now(),
91323
+ mode
91324
+ };
91325
+ }
91326
+ var cached4;
91327
+ function parseEnvNumber(raw4, fallback) {
91328
+ const parsed = Number(raw4);
91329
+ return Number.isFinite(parsed) ? parsed : fallback;
91330
+ }
91331
+ function currentRuntimeBuildInfo() {
91332
+ if (cached4)
91333
+ return cached4;
91334
+ const defaultInfo = computeDefaultBuildInfo();
91335
+ cached4 = {
91336
+ name: process.env.AGENT_REMNOTE_NAME?.trim() || defaultInfo.name,
91337
+ version: process.env.AGENT_REMNOTE_VERSION?.trim() || defaultInfo.version,
91338
+ build_id: process.env.AGENT_REMNOTE_BUILD_ID?.trim() || defaultInfo.build_id,
91339
+ built_at: parseEnvNumber(process.env.AGENT_REMNOTE_BUILD_AT, defaultInfo.built_at),
91340
+ source_stamp: parseEnvNumber(process.env.AGENT_REMNOTE_SOURCE_STAMP, defaultInfo.source_stamp),
91341
+ mode: process.env.AGENT_REMNOTE_BUILD_MODE === "src" || process.env.AGENT_REMNOTE_BUILD_MODE === "dist" || process.env.AGENT_REMNOTE_BUILD_MODE === "unknown" ? process.env.AGENT_REMNOTE_BUILD_MODE : defaultInfo.mode
91342
+ };
91343
+ return cached4;
91344
+ }
91345
+ function runtimeVersionWarnings(params3) {
91346
+ const warnings = [];
91347
+ const compare2 = (label, other) => {
91348
+ if (!other)
91349
+ return;
91350
+ if (other.build_id !== params3.current.build_id) {
91351
+ warnings.push(`${label} build mismatch: current=${params3.current.build_id} live=${other.build_id}`);
91352
+ }
91353
+ };
91354
+ compare2("daemon", params3.daemon);
91355
+ compare2("plugin", params3.plugin);
91356
+ compare2("api", params3.api);
91357
+ return warnings;
91358
+ }
91359
+
91208
91360
  // src/commands/ws/_shared.ts
91209
91361
  var WS_HEALTH_TIMEOUT_MS = 2000;
91210
91362
  var WS_START_WAIT_DEFAULT_MS = 15000;
@@ -91244,6 +91396,7 @@ function supervisorCommandLine(params3) {
91244
91396
  function toPidFileValue(params3) {
91245
91397
  return {
91246
91398
  pid: params3.pid,
91399
+ build: currentRuntimeBuildInfo(),
91247
91400
  started_at: params3.startedAt,
91248
91401
  ws_url: params3.wsUrl,
91249
91402
  log_file: params3.logFile,
@@ -91294,7 +91447,7 @@ function toInitialSupervisorState(now2) {
91294
91447
  };
91295
91448
  }
91296
91449
  function defaultStateFilePathFromPidFile(pidFilePath) {
91297
- return path17.join(path17.dirname(pidFilePath), "ws.state.json");
91450
+ return path18.join(path18.dirname(pidFilePath), "ws.state.json");
91298
91451
  }
91299
91452
  function startWsSupervisor(params3) {
91300
91453
  return gen2(function* () {
@@ -91409,6 +91562,21 @@ var doctorCommand = exports_Command.make("doctor", {}, () => gen2(function* () {
91409
91562
  const hasContents = !!db.prepare(`SELECT 1 FROM sqlite_master WHERE type='table' AND name='remsContents' LIMIT 1`).get();
91410
91563
  return { has_search_index: hasSearchInfos && hasContents };
91411
91564
  }).pipe(either3);
91565
+ const schema2 = yield* try_3({
91566
+ try: () => {
91567
+ const db = openStoreDb(cfg.storeDb);
91568
+ try {
91569
+ return readStoreSchemaStatus(db);
91570
+ } finally {
91571
+ db.close();
91572
+ }
91573
+ },
91574
+ catch: (error4) => new CliError({
91575
+ code: "DB_UNAVAILABLE",
91576
+ message: `Failed to read store schema: ${String(error4?.message || error4)}`,
91577
+ exitCode: 1
91578
+ })
91579
+ }).pipe(either3);
91412
91580
  const wsHealth = yield* ws.health({ url: cfg.wsUrl, timeoutMs: WS_HEALTH_TIMEOUT_MS }).pipe(either3);
91413
91581
  const wsClients = yield* ws.queryClients({ url: cfg.wsUrl, timeoutMs: WS_HEALTH_TIMEOUT_MS }).pipe(either3);
91414
91582
  const pidFilePath = daemonFiles.defaultPidFile();
@@ -91420,6 +91588,8 @@ var doctorCommand = exports_Command.make("doctor", {}, () => gen2(function* () {
91420
91588
  queue: {
91421
91589
  ok: queueStats2._tag === "Right",
91422
91590
  db_path: cfg.storeDb,
91591
+ schema: schema2._tag === "Right" ? schema2.right : undefined,
91592
+ schema_error: schema2._tag === "Left" ? schema2.left.message : undefined,
91423
91593
  writable: storeDbWritable.ok,
91424
91594
  writable_reason: storeDbWritable.reason,
91425
91595
  stats: queueStats2._tag === "Right" ? queueStats2.right : undefined,
@@ -91469,6 +91639,10 @@ var doctorCommand = exports_Command.make("doctor", {}, () => gen2(function* () {
91469
91639
  `- overall_ok: ${overallOk}`,
91470
91640
  `- queue_ok: ${data.queue.ok}`,
91471
91641
  `- store_db: ${data.queue.db_path}`,
91642
+ `- store_schema_current_user_version: ${data.queue.schema?.current_user_version ?? ""}`,
91643
+ `- store_schema_latest_supported_version: ${data.queue.schema?.latest_supported_version ?? ""}`,
91644
+ `- store_schema_applied_migrations: ${data.queue.schema?.applied_migrations ?? ""}`,
91645
+ `- store_schema_error: ${data.queue.schema_error ?? ""}`,
91472
91646
  `- remnote_db_ok: ${data.remnote_db.ok}`,
91473
91647
  `- remnote_db: ${data.remnote_db.db_path ?? ""}`,
91474
91648
  `- remnote_db_resolution: ${data.remnote_db.resolution ?? ""}`,
@@ -91802,24 +91976,24 @@ var wsLogsCommand = exports_Command.make("logs", {
91802
91976
  }).pipe(catchAll2(writeFailure)));
91803
91977
 
91804
91978
  // src/commands/ws/restart.ts
91805
- import path19 from "node:path";
91979
+ import path20 from "node:path";
91806
91980
 
91807
91981
  // src/lib/statuslineArtifacts.ts
91808
91982
  import { promises as fs13 } from "node:fs";
91809
91983
 
91810
91984
  // src/services/StatusLineFile.ts
91811
91985
  import { promises as fs12 } from "node:fs";
91812
- import path18 from "node:path";
91986
+ import path19 from "node:path";
91813
91987
  class StatusLineFile extends Tag2("StatusLineFile")() {
91814
91988
  }
91815
91989
  function defaultTextFile() {
91816
- return path18.join(homeDir(), ".agent-remnote", "status-line.txt");
91990
+ return path19.join(homeDir(), ".agent-remnote", "status-line.txt");
91817
91991
  }
91818
91992
  function defaultJsonFile() {
91819
- return path18.join(homeDir(), ".agent-remnote", "status-line.json");
91993
+ return path19.join(homeDir(), ".agent-remnote", "status-line.json");
91820
91994
  }
91821
91995
  function ensureDir6(p3) {
91822
- return fs12.mkdir(path18.dirname(p3), { recursive: true }).then(() => {
91996
+ return fs12.mkdir(path19.dirname(p3), { recursive: true }).then(() => {
91823
91997
  return;
91824
91998
  });
91825
91999
  }
@@ -91932,7 +92106,7 @@ var wsRestartCommand = exports_Command.make("restart", {
91932
92106
  const pidFilePath = resolveUserFilePath(pidFile4 ?? daemonFiles.defaultPidFile());
91933
92107
  const existing = yield* daemonFiles.readPidFile(pidFilePath);
91934
92108
  let stopResult = { stopped: true, pid_file: pidFilePath };
91935
- const stateFilePath = resolveUserFilePath(existing?.state_file ?? path19.join(path19.dirname(pidFilePath), "ws.state.json"));
92109
+ const stateFilePath = resolveUserFilePath(existing?.state_file ?? path20.join(path20.dirname(pidFilePath), "ws.state.json"));
91936
92110
  if (existing) {
91937
92111
  const alive = yield* proc.isPidRunning(existing.pid);
91938
92112
  if (!alive) {
@@ -92004,10 +92178,10 @@ function safeJsonParse2(text14) {
92004
92178
  }
92005
92179
  }
92006
92180
  var WsBridgeServerLive = succeed10(WsBridgeServer, {
92007
- listen: ({ port: port3, path: path20, host }) => acquireRelease2(gen2(function* () {
92181
+ listen: ({ port: port3, path: path21, host }) => acquireRelease2(gen2(function* () {
92008
92182
  const events = yield* unbounded5();
92009
92183
  const sockets = new Map;
92010
- const wss = new import_websocket_server.default({ port: port3, host, path: path20 });
92184
+ const wss = new import_websocket_server.default({ port: port3, host, path: path21 });
92011
92185
  wss.on("connection", (ws, req) => {
92012
92186
  const connId = randomUUID4();
92013
92187
  const remoteAddr = safeStringHeader(req?.socket?.remoteAddress);
@@ -92041,7 +92215,7 @@ var WsBridgeServerLive = succeed10(WsBridgeServer, {
92041
92215
  });
92042
92216
  const handle = {
92043
92217
  events,
92044
- serverInfo: { port: port3, path: path20 },
92218
+ serverInfo: { port: port3, path: path21 },
92045
92219
  sendText: (connId, text14) => sync3(() => {
92046
92220
  const ws = sockets.get(connId);
92047
92221
  if (!ws)
@@ -92103,17 +92277,17 @@ var WsBridgeServerLive = succeed10(WsBridgeServer, {
92103
92277
  code: "WS_UNAVAILABLE",
92104
92278
  message: "Failed to start ws bridge server",
92105
92279
  exitCode: 1,
92106
- details: { error: String(error4?.message || error4), port: port3, path: path20, host }
92280
+ details: { error: String(error4?.message || error4), port: port3, path: path21, host }
92107
92281
  }))))
92108
92282
  });
92109
92283
 
92110
92284
  // src/services/WsBridgeStateFile.ts
92111
92285
  import { promises as fs14 } from "node:fs";
92112
- import path20 from "node:path";
92286
+ import path21 from "node:path";
92113
92287
  class WsBridgeStateFile extends Tag2("WsBridgeStateFile")() {
92114
92288
  }
92115
92289
  async function ensureDir7(filePath) {
92116
- await fs14.mkdir(path20.dirname(filePath), { recursive: true });
92290
+ await fs14.mkdir(path21.dirname(filePath), { recursive: true });
92117
92291
  }
92118
92292
  async function writeTextAtomic2(filePath, content) {
92119
92293
  await ensureDir7(filePath);
@@ -92526,7 +92700,7 @@ function runWsBridgeRuntime(params3) {
92526
92700
  const heartbeatIntervalMs = params3.heartbeatIntervalMs ?? 30000;
92527
92701
  const core = makeWsBridgeCore({
92528
92702
  config: {
92529
- serverInfo: server.serverInfo,
92703
+ serverInfo: { ...server.serverInfo, runtime: currentRuntimeBuildInfo() },
92530
92704
  queueDbPath: cfg.storeDb,
92531
92705
  stateFileEnabled: !cfg.wsStateFile.disabled,
92532
92706
  stateWriteMinIntervalMs: STATE_FILE_MIN_INTERVAL_MS,
@@ -92665,18 +92839,18 @@ function parseWsUrl(url2) {
92665
92839
  }
92666
92840
  const port3 = u.port ? Number(u.port) : u.protocol === "wss:" ? 443 : 80;
92667
92841
  const host = u.hostname && u.hostname.length > 0 ? u.hostname : "localhost";
92668
- const path21 = u.pathname && u.pathname.length > 0 ? u.pathname : "/ws";
92842
+ const path22 = u.pathname && u.pathname.length > 0 ? u.pathname : "/ws";
92669
92843
  if (!Number.isFinite(port3) || port3 <= 0) {
92670
92844
  throw new CliError({ code: "INVALID_ARGS", message: `Invalid wsUrl port: ${url2}`, exitCode: 2 });
92671
92845
  }
92672
- if (!path21.startsWith("/")) {
92846
+ if (!path22.startsWith("/")) {
92673
92847
  throw new CliError({ code: "INVALID_ARGS", message: `Invalid wsUrl path: ${url2}`, exitCode: 2 });
92674
92848
  }
92675
- return { host, port: port3, path: path21 };
92849
+ return { host, port: port3, path: path22 };
92676
92850
  }
92677
92851
  var wsServeCommand = exports_Command.make("serve", {}, () => gen2(function* () {
92678
92852
  const cfg = yield* AppConfig;
92679
- const { host, port: port3, path: path21 } = yield* try_3({
92853
+ const { host, port: port3, path: path22 } = yield* try_3({
92680
92854
  try: () => parseWsUrl(cfg.wsUrl),
92681
92855
  catch: (e) => isCliError(e) ? e : new CliError({
92682
92856
  code: "INVALID_ARGS",
@@ -92685,7 +92859,7 @@ var wsServeCommand = exports_Command.make("serve", {}, () => gen2(function* () {
92685
92859
  details: { ws_url: cfg.wsUrl, error: String(e?.message || e) }
92686
92860
  })
92687
92861
  });
92688
- yield* runWsBridgeRuntime({ host, port: port3, path: path21 });
92862
+ yield* runWsBridgeRuntime({ host, port: port3, path: path22 });
92689
92863
  }).pipe(catchAll2(writeFailure)));
92690
92864
 
92691
92865
  // src/commands/ws/start.ts
@@ -92701,14 +92875,14 @@ function parseWsUrl2(url2) {
92701
92875
  }
92702
92876
  const port3 = u.port ? Number(u.port) : u.protocol === "wss:" ? 443 : 80;
92703
92877
  const host = u.hostname && u.hostname.length > 0 ? u.hostname : "localhost";
92704
- const path21 = u.pathname && u.pathname.length > 0 ? u.pathname : "/ws";
92878
+ const path22 = u.pathname && u.pathname.length > 0 ? u.pathname : "/ws";
92705
92879
  if (!Number.isFinite(port3) || port3 <= 0) {
92706
92880
  throw new CliError({ code: "INVALID_ARGS", message: `Invalid wsUrl port: ${url2}`, exitCode: 2 });
92707
92881
  }
92708
- if (!path21.startsWith("/")) {
92882
+ if (!path22.startsWith("/")) {
92709
92883
  throw new CliError({ code: "INVALID_ARGS", message: `Invalid wsUrl path: ${url2}`, exitCode: 2 });
92710
92884
  }
92711
- return { host, port: port3, path: path21 };
92885
+ return { host, port: port3, path: path22 };
92712
92886
  }
92713
92887
  var pidFile4 = text9("pid-file").pipe(optional5, map34(optionToUndefined4));
92714
92888
  var logFile3 = text9("log-file").pipe(optional5, map34(optionToUndefined4));
@@ -92720,7 +92894,7 @@ var wsStartCommand = exports_Command.make("start", {
92720
92894
  }, ({ foreground, wait, pidFile: pidFile5, logFile: logFile4 }) => gen2(function* () {
92721
92895
  const cfg = yield* AppConfig;
92722
92896
  if (foreground) {
92723
- const { host, port: port3, path: path21 } = yield* try_3({
92897
+ const { host, port: port3, path: path22 } = yield* try_3({
92724
92898
  try: () => parseWsUrl2(cfg.wsUrl),
92725
92899
  catch: (e) => isCliError(e) ? e : new CliError({
92726
92900
  code: "INVALID_ARGS",
@@ -92729,7 +92903,7 @@ var wsStartCommand = exports_Command.make("start", {
92729
92903
  details: { ws_url: cfg.wsUrl, error: String(e?.message || e) }
92730
92904
  })
92731
92905
  });
92732
- yield* runWsBridgeRuntime({ host, port: port3, path: path21 });
92906
+ yield* runWsBridgeRuntime({ host, port: port3, path: path22 });
92733
92907
  return;
92734
92908
  }
92735
92909
  const result = yield* startWsSupervisor({ waitMs: wait, pidFile: pidFile5, logFile: logFile4 });
@@ -92744,7 +92918,110 @@ var wsStartCommand = exports_Command.make("start", {
92744
92918
  }).pipe(catchAll2(writeFailure)));
92745
92919
 
92746
92920
  // src/commands/ws/status.ts
92747
- import path21 from "node:path";
92921
+ import path24 from "node:path";
92922
+
92923
+ // src/lib/pluginBuildInfo.ts
92924
+ import { readFileSync as readFileSync3 } from "node:fs";
92925
+ import path23 from "node:path";
92926
+
92927
+ // src/lib/pluginArtifacts.ts
92928
+ import { existsSync as existsSync3, statSync as statSync2 } from "node:fs";
92929
+ import path22 from "node:path";
92930
+ import { fileURLToPath as fileURLToPath3 } from "node:url";
92931
+ function currentDir(moduleUrl) {
92932
+ return path22.dirname(fileURLToPath3(moduleUrl));
92933
+ }
92934
+ function isDirectory(targetPath) {
92935
+ try {
92936
+ return statSync2(targetPath).isDirectory();
92937
+ } catch {
92938
+ return false;
92939
+ }
92940
+ }
92941
+ function isFile(targetPath) {
92942
+ try {
92943
+ return statSync2(targetPath).isFile();
92944
+ } catch {
92945
+ return false;
92946
+ }
92947
+ }
92948
+ function distCandidates(moduleUrl) {
92949
+ const dir2 = currentDir(moduleUrl);
92950
+ return [
92951
+ path22.resolve(dir2, "../../plugin-artifacts/dist"),
92952
+ path22.resolve(dir2, "../plugin-artifacts/dist"),
92953
+ path22.resolve(dir2, "../../../plugin/dist"),
92954
+ path22.resolve(dir2, "../../plugin/dist")
92955
+ ];
92956
+ }
92957
+ function validateDistPath(targetPath) {
92958
+ return isDirectory(targetPath) && existsSync3(path22.join(targetPath, "manifest.json"));
92959
+ }
92960
+ function hasBuildInfo(targetPath) {
92961
+ return isFile(path22.join(targetPath, "build-info.json"));
92962
+ }
92963
+ function resolvePluginDistPath(moduleUrl = import.meta.url) {
92964
+ for (const candidate of distCandidates(moduleUrl)) {
92965
+ if (validateDistPath(candidate) && hasBuildInfo(candidate))
92966
+ return candidate;
92967
+ }
92968
+ for (const candidate of distCandidates(moduleUrl)) {
92969
+ if (validateDistPath(candidate))
92970
+ return candidate;
92971
+ }
92972
+ throw new CliError({
92973
+ code: "DEPENDENCY_MISSING",
92974
+ message: "Plugin build artifacts are unavailable",
92975
+ exitCode: 1,
92976
+ details: { candidates: distCandidates(moduleUrl) },
92977
+ hint: [
92978
+ "Run npm run build --workspace @remnote/plugin in the repository checkout",
92979
+ "Or install a packaged agent-remnote release that includes plugin artifacts"
92980
+ ]
92981
+ });
92982
+ }
92983
+
92984
+ // src/lib/pluginBuildInfo.ts
92985
+ function readPluginDistBuildInfo(distPath) {
92986
+ const normalized = typeof distPath === "string" ? distPath.trim() : "";
92987
+ if (!normalized)
92988
+ return null;
92989
+ const target2 = path23.join(normalized, "build-info.json");
92990
+ try {
92991
+ const raw4 = readFileSync3(target2, "utf8");
92992
+ const parsed = JSON.parse(raw4);
92993
+ if (typeof parsed?.name === "string" && typeof parsed?.version === "string" && typeof parsed?.build_id === "string" && typeof parsed?.built_at === "number" && typeof parsed?.source_stamp === "number") {
92994
+ return {
92995
+ name: parsed.name,
92996
+ version: parsed.version,
92997
+ build_id: parsed.build_id,
92998
+ built_at: parsed.built_at,
92999
+ source_stamp: parsed.source_stamp,
93000
+ mode: parsed.mode === "src" || parsed.mode === "dist" || parsed.mode === "unknown" ? parsed.mode : "dist"
93001
+ };
93002
+ }
93003
+ } catch {}
93004
+ return null;
93005
+ }
93006
+ function currentExpectedPluginBuildInfo() {
93007
+ try {
93008
+ const dist = resolvePluginDistPath();
93009
+ return readPluginDistBuildInfo(dist);
93010
+ } catch {
93011
+ return null;
93012
+ }
93013
+ }
93014
+ function pluginBuildWarnings(params3) {
93015
+ if (!params3.expected || !params3.live)
93016
+ return [];
93017
+ if (params3.expected.build_id === params3.live.build_id)
93018
+ return [];
93019
+ return [
93020
+ `plugin build mismatch: expected=${params3.expected.build_id} live=${params3.live.build_id}`
93021
+ ];
93022
+ }
93023
+
93024
+ // src/commands/ws/status.ts
92748
93025
  function optionToUndefined5(opt) {
92749
93026
  return isSome2(opt) ? opt.value : undefined;
92750
93027
  }
@@ -92763,14 +93040,14 @@ var wsStatusCommand = exports_Command.make("status", { pidFile: pidFile5 }, ({ p
92763
93040
  if (!alive) {
92764
93041
  const stalePidInfo = pidInfo;
92765
93042
  yield* daemonFiles.deletePidFile(pidFilePath);
92766
- const staleStateFilePath = resolveUserFilePath(pidInfo.state_file ?? path21.join(path21.dirname(pidFilePath), "ws.state.json"));
93043
+ const staleStateFilePath = resolveUserFilePath(pidInfo.state_file ?? path24.join(path24.dirname(pidFilePath), "ws.state.json"));
92767
93044
  yield* supervisorState.deleteStateFile(staleStateFilePath);
92768
93045
  selfHealCleanup = yield* cleanupStatuslineArtifacts(resolveStatuslineArtifactPaths({ cfg, pidInfo: stalePidInfo }));
92769
93046
  yield* sync3(() => refreshTmuxStatusLine());
92770
93047
  pidInfo = undefined;
92771
93048
  }
92772
93049
  }
92773
- const stateFilePath = resolveUserFilePath(pidInfo?.state_file ?? path21.join(path21.dirname(pidFilePath), "ws.state.json"));
93050
+ const stateFilePath = resolveUserFilePath(pidInfo?.state_file ?? path24.join(path24.dirname(pidFilePath), "ws.state.json"));
92774
93051
  const state = yield* supervisorState.readStateFile(stateFilePath);
92775
93052
  const mode = pidInfo ? pidInfo.mode ?? "legacy" : "supervisor";
92776
93053
  const supervisorPid = pidInfo?.pid;
@@ -92780,10 +93057,23 @@ var wsStatusCommand = exports_Command.make("status", { pidFile: pidFile5 }, ({ p
92780
93057
  const childStartedAt = pidInfo?.child_started_at;
92781
93058
  const health = yield* ws.health({ url: cfg.wsUrl, timeoutMs: WS_HEALTH_TIMEOUT_MS }).pipe(either3);
92782
93059
  const clientsRes = yield* ws.queryClients({ url: cfg.wsUrl, timeoutMs: WS_HEALTH_TIMEOUT_MS }).pipe(either3);
93060
+ const activeWorkerRuntime = isRight2(clientsRes) && typeof clientsRes.right.activeWorkerConnId === "string" ? clientsRes.right.clients.find((client) => client.connId === clientsRes.right.activeWorkerConnId)?.runtime ?? null : null;
93061
+ const warnings = [
93062
+ ...runtimeVersionWarnings({
93063
+ current: currentRuntimeBuildInfo(),
93064
+ daemon: pidInfo?.build
93065
+ }),
93066
+ ...pluginBuildWarnings({
93067
+ expected: currentExpectedPluginBuildInfo(),
93068
+ live: activeWorkerRuntime
93069
+ })
93070
+ ];
92783
93071
  const data = {
93072
+ runtime: currentRuntimeBuildInfo(),
92784
93073
  service: {
92785
93074
  running: supervisorRunning,
92786
93075
  pid: supervisorPid,
93076
+ build: pidInfo?.build ?? null,
92787
93077
  pid_file: pidFilePath,
92788
93078
  started_at: pidInfo?.started_at,
92789
93079
  log_file: pidInfo?.log_file,
@@ -92800,8 +93090,15 @@ var wsStatusCommand = exports_Command.make("status", { pidFile: pidFile5 }, ({ p
92800
93090
  error: isLeft2(health) ? health.left.message : undefined
92801
93091
  },
92802
93092
  active_worker_conn_id: isRight2(clientsRes) ? clientsRes.right.activeWorkerConnId ?? null : null,
92803
- clients: isRight2(clientsRes) ? clientsRes.right.clients : []
93093
+ clients: isRight2(clientsRes) ? clientsRes.right.clients : [],
93094
+ warnings
92804
93095
  };
93096
+ if (data.service.running && !data.service.build) {
93097
+ data.warnings.push("daemon pid metadata has no build info; restart the daemon to refresh runtime metadata");
93098
+ }
93099
+ if (data.active_worker_conn_id && !data.clients.find((client) => client.connId === data.active_worker_conn_id)?.runtime) {
93100
+ data.warnings.push("active worker did not report runtime metadata; reload the RemNote plugin");
93101
+ }
92805
93102
  const md = [
92806
93103
  `- service_running: ${data.service.running}`,
92807
93104
  `- pid: ${data.service.pid ?? ""}`,
@@ -92933,7 +93230,7 @@ var wsStatusLineCommand = exports_Command.make("status-line", { stateFile, stale
92933
93230
  }).pipe(catchAll2(writeFailure)));
92934
93231
 
92935
93232
  // src/commands/ws/stop.ts
92936
- import path22 from "node:path";
93233
+ import path25 from "node:path";
92937
93234
  function optionToUndefined7(opt) {
92938
93235
  return isSome2(opt) ? opt.value : undefined;
92939
93236
  }
@@ -92961,7 +93258,7 @@ var wsStopCommand = exports_Command.make("stop", { force: boolean8("force"), pid
92961
93258
  });
92962
93259
  return;
92963
93260
  }
92964
- const stateFilePath = resolveUserFilePath(existing.state_file ?? path22.join(path22.dirname(pidFilePath), "ws.state.json"));
93261
+ const stateFilePath = resolveUserFilePath(existing.state_file ?? path25.join(path25.dirname(pidFilePath), "ws.state.json"));
92965
93262
  const alive = yield* proc.isPidRunning(existing.pid);
92966
93263
  if (!alive) {
92967
93264
  yield* daemonFiles.deletePidFile(pidFilePath);
@@ -93156,7 +93453,7 @@ var ChildProcessLive = succeed10(ChildProcess2, {
93156
93453
 
93157
93454
  // src/services/LogWriter.ts
93158
93455
  import { promises as fs16 } from "node:fs";
93159
- import path23 from "node:path";
93456
+ import path26 from "node:path";
93160
93457
  class LogWriterFactory extends Tag2("LogWriterFactory")() {
93161
93458
  }
93162
93459
  function sanitizePositiveInt(value8, fallback) {
@@ -93168,7 +93465,7 @@ function sanitizeMaxBytes(value8, fallback) {
93168
93465
  return Number.isFinite(value8) && value8 > 0 ? Math.floor(value8) : fallback;
93169
93466
  }
93170
93467
  async function ensureDir8(filePath) {
93171
- await fs16.mkdir(path23.dirname(filePath), { recursive: true });
93468
+ await fs16.mkdir(path26.dirname(filePath), { recursive: true });
93172
93469
  }
93173
93470
  async function safeStat(filePath) {
93174
93471
  try {
@@ -93181,15 +93478,15 @@ async function safeStat(filePath) {
93181
93478
  async function rotateFiles(filePath, keep) {
93182
93479
  if (keep <= 0)
93183
93480
  return;
93184
- const dir2 = path23.dirname(filePath);
93185
- const base = path23.basename(filePath);
93481
+ const dir2 = path26.dirname(filePath);
93482
+ const base = path26.basename(filePath);
93186
93483
  let entries2 = [];
93187
93484
  try {
93188
93485
  entries2 = await fs16.readdir(dir2);
93189
93486
  } catch {
93190
93487
  return;
93191
93488
  }
93192
- const rotated = entries2.filter((name) => name.startsWith(`${base}.`)).map((name) => path23.join(dir2, name)).sort().reverse();
93489
+ const rotated = entries2.filter((name) => name.startsWith(`${base}.`)).map((name) => path26.join(dir2, name)).sort().reverse();
93193
93490
  for (const p3 of rotated.slice(keep)) {
93194
93491
  try {
93195
93492
  await fs16.unlink(p3);
@@ -93294,6 +93591,7 @@ function makePidFileValue(params3) {
93294
93591
  return {
93295
93592
  mode: "supervisor",
93296
93593
  pid: params3.supervisorPid,
93594
+ build: currentRuntimeBuildInfo(),
93297
93595
  child_pid: params3.childPid,
93298
93596
  child_started_at: params3.childStartedAt,
93299
93597
  started_at: params3.supervisorStartedAt,
@@ -94160,18 +94458,28 @@ var ACTIONS = {
94160
94458
  aliasRefAllowlist: ["parent_id"],
94161
94459
  compile: ({ input, aliasTempId }) => {
94162
94460
  const parent_id = input.parent_id;
94461
+ const standalone = input.standalone === true;
94163
94462
  const text14 = input.text;
94164
- if (typeof parent_id !== "string" || !parent_id.trim()) {
94165
- throw new Error("write.bullet requires input.parent_id");
94463
+ if (standalone && typeof parent_id === "string" && parent_id.trim()) {
94464
+ throw new Error("write.bullet does not allow input.parent_id when input.standalone=true");
94465
+ }
94466
+ if (!standalone && (typeof parent_id !== "string" || !parent_id.trim())) {
94467
+ throw new Error("write.bullet requires input.parent_id unless input.standalone=true");
94166
94468
  }
94167
94469
  if (typeof text14 !== "string") {
94168
94470
  throw new Error("write.bullet requires input.text");
94169
94471
  }
94170
- const payload = { parent_id, text: text14 };
94472
+ const payload = { text: text14 };
94473
+ if (standalone)
94474
+ payload.standalone = true;
94475
+ else
94476
+ payload.parent_id = parent_id;
94171
94477
  if (input.is_document === true)
94172
94478
  payload.is_document = true;
94173
94479
  if (Array.isArray(input.tags))
94174
94480
  payload.tags = input.tags;
94481
+ if (typeof input.position === "number")
94482
+ payload.position = input.position;
94175
94483
  if (aliasTempId)
94176
94484
  payload.client_temp_id = aliasTempId;
94177
94485
  return { ops: [{ type: "create_rem", payload }] };
@@ -94322,9 +94630,9 @@ var ACTIONS = {
94322
94630
  },
94323
94631
  "portal.create": {
94324
94632
  opType: "create_portal",
94325
- supportsAs: false,
94633
+ supportsAs: true,
94326
94634
  aliasRefAllowlist: ["parent_id", "target_rem_id"],
94327
- compile: ({ input }) => {
94635
+ compile: ({ input, aliasTempId }) => {
94328
94636
  const parent_id = input.parent_id;
94329
94637
  const target_rem_id = input.target_rem_id;
94330
94638
  if (typeof parent_id !== "string" || !parent_id.trim()) {
@@ -94336,6 +94644,8 @@ var ACTIONS = {
94336
94644
  const payload = { parent_id, target_rem_id };
94337
94645
  if (typeof input.position === "number")
94338
94646
  payload.position = input.position;
94647
+ if (aliasTempId)
94648
+ payload.client_temp_id = aliasTempId;
94339
94649
  return { ops: [{ type: "create_portal", payload }] };
94340
94650
  }
94341
94651
  },
@@ -94415,6 +94725,37 @@ var ACTIONS = {
94415
94725
  return { ops: [{ type: "update_text", payload }] };
94416
94726
  }
94417
94727
  },
94728
+ "rem.move": {
94729
+ opType: "move_rem",
94730
+ supportsAs: false,
94731
+ aliasRefAllowlist: ["rem_id", "new_parent_id"],
94732
+ compile: ({ input }) => {
94733
+ const rem_id = input.rem_id;
94734
+ const new_parent_id = input.new_parent_id;
94735
+ const standalone = input.standalone === true;
94736
+ if (typeof rem_id !== "string" || !rem_id.trim()) {
94737
+ throw new Error("rem.move requires input.rem_id");
94738
+ }
94739
+ if (standalone && typeof new_parent_id === "string" && new_parent_id.trim()) {
94740
+ throw new Error("rem.move does not allow input.new_parent_id when input.standalone=true");
94741
+ }
94742
+ if (!standalone && (typeof new_parent_id !== "string" || !new_parent_id.trim())) {
94743
+ throw new Error("rem.move requires input.new_parent_id unless input.standalone=true");
94744
+ }
94745
+ const payload = { rem_id };
94746
+ if (standalone)
94747
+ payload.standalone = true;
94748
+ else
94749
+ payload.new_parent_id = new_parent_id;
94750
+ if (typeof input.position === "number")
94751
+ payload.position = input.position;
94752
+ if (input.is_document === true)
94753
+ payload.is_document = true;
94754
+ if (input.leave_portal === true)
94755
+ payload.leave_portal = true;
94756
+ return { ops: [{ type: "move_rem", payload }] };
94757
+ }
94758
+ },
94418
94759
  "replace.block": {
94419
94760
  opType: "replace_selection_with_markdown",
94420
94761
  supportsAs: false,
@@ -94886,6 +95227,8 @@ function assertOpsNoOrphanCreates(ops) {
94886
95227
  }
94887
95228
  if (!OP_TYPES_REQUIRE_PARENT_ID.has(op.type))
94888
95229
  continue;
95230
+ if (op.type === "create_rem" && op.payload?.standalone === true)
95231
+ continue;
94889
95232
  const parentId = readParentIdFromPayload(op.payload);
94890
95233
  if (parentId)
94891
95234
  continue;
@@ -95005,7 +95348,7 @@ function normalizeOps(rawOps) {
95005
95348
 
95006
95349
  // src/services/RefResolver.ts
95007
95350
  import { homedir } from "node:os";
95008
- import path24 from "node:path";
95351
+ import path27 from "node:path";
95009
95352
 
95010
95353
  // src/lib/workspaceResolver.ts
95011
95354
  import fs18 from "node:fs";
@@ -95456,8 +95799,8 @@ function normalizeDbPathInput(dbPath) {
95456
95799
  const raw4 = typeof dbPath === "string" ? dbPath.trim() : "";
95457
95800
  if (!raw4)
95458
95801
  return;
95459
- const expanded = raw4 === "~" ? homedir() : raw4.startsWith("~/") || raw4.startsWith("~\\") ? path24.join(homedir(), raw4.slice(2)) : raw4;
95460
- return path24.resolve(path24.normalize(expanded));
95802
+ const expanded = raw4 === "~" ? homedir() : raw4.startsWith("~/") || raw4.startsWith("~\\") ? path27.join(homedir(), raw4.slice(2)) : raw4;
95803
+ return path27.resolve(path27.normalize(expanded));
95461
95804
  }
95462
95805
  var RefResolverLive = succeed10(RefResolver, {
95463
95806
  resolve: (ref, options6) => gen2(function* () {
@@ -95551,8 +95894,8 @@ function resolveRefsInPayload(params3) {
95551
95894
  const out = structuredClone(params3.payload);
95552
95895
  const resolvedRefCache = new Map;
95553
95896
  const idPaths = idFieldPathsForOpType(params3.opType);
95554
- for (const path25 of idPaths) {
95555
- const tokens = parsePathTokens(path25);
95897
+ for (const path28 of idPaths) {
95898
+ const tokens = parsePathTokens(path28);
95556
95899
  if (tokens.length === 0)
95557
95900
  continue;
95558
95901
  const leaves = collectLeafValues(out, tokens);
@@ -95564,9 +95907,9 @@ function resolveRefsInPayload(params3) {
95564
95907
  const refValue = leaf.trim();
95565
95908
  if (!shouldResolveRef(refValue))
95566
95909
  return leaf;
95567
- const cached4 = resolvedRefCache.get(refValue);
95568
- if (cached4)
95569
- return cached4;
95910
+ const cached5 = resolvedRefCache.get(refValue);
95911
+ if (cached5)
95912
+ return cached5;
95570
95913
  const resolved = yield* refs.resolve(refValue);
95571
95914
  resolvedRefCache.set(refValue, resolved);
95572
95915
  return resolved;
@@ -96398,13 +96741,16 @@ function collectApiHealthUseCase(params3) {
96398
96741
  const clientsRes = yield* ws.queryClients({ url: cfg.wsUrl, timeoutMs: 2000 }).pipe(either3);
96399
96742
  const queueStats2 = yield* queue.stats({ dbPath: cfg.storeDb }).pipe(either3);
96400
96743
  return {
96401
- api: { running: true, healthy: true, pid: params3.pid, startedAt: params3.startedAt },
96744
+ runtime: currentRuntimeBuildInfo(),
96745
+ api: { running: true, healthy: true, pid: params3.pid, startedAt: params3.startedAt, build: currentRuntimeBuildInfo() },
96402
96746
  daemon: {
96403
96747
  running: wsHealth._tag === "Right",
96404
96748
  healthy: wsHealth._tag === "Right",
96405
- wsUrl: cfg.wsUrl
96749
+ wsUrl: cfg.wsUrl,
96750
+ build: null
96406
96751
  },
96407
96752
  activeWorkerConnId: clientsRes._tag === "Right" ? clientsRes.right.activeWorkerConnId ?? null : null,
96753
+ clients: clientsRes._tag === "Right" ? clientsRes.right.clients : [],
96408
96754
  queue: queueStats2._tag === "Right" ? {
96409
96755
  available: true,
96410
96756
  pending: queueStats2.right.pending ?? 0,
@@ -96432,6 +96778,22 @@ function collectApiStatusUseCase(params3) {
96432
96778
  const queueReady = health.queue?.available === true;
96433
96779
  const writeReady = queueReady && pluginRpcReady;
96434
96780
  const bindingSource = workspaceResolution.bindingSource ?? (cfg.remnoteDb ? "config" : workspaceResolution.source === "unresolved" ? undefined : workspaceResolution.source);
96781
+ const activeWorkerRuntime = typeof health.activeWorkerConnId === "string" && Array.isArray(health?.clients) ? health.clients.find((client) => client.connId === health.activeWorkerConnId)?.runtime ?? null : null;
96782
+ const warnings = [
96783
+ ...runtimeVersionWarnings({
96784
+ current: currentRuntimeBuildInfo()
96785
+ }),
96786
+ ...pluginBuildWarnings({
96787
+ expected: currentExpectedPluginBuildInfo(),
96788
+ live: activeWorkerRuntime
96789
+ })
96790
+ ];
96791
+ if (health.api?.running === true && !health?.api?.build) {
96792
+ warnings.push("host api state has no build info; restart the api service to refresh runtime metadata");
96793
+ }
96794
+ if (health.activeWorkerConnId && !activeWorkerRuntime) {
96795
+ warnings.push("active worker did not report runtime metadata; reload the RemNote plugin");
96796
+ }
96435
96797
  return {
96436
96798
  ...health,
96437
96799
  capabilities: {
@@ -96451,7 +96813,11 @@ function collectApiStatusUseCase(params3) {
96451
96813
  },
96452
96814
  plugin: {
96453
96815
  ws_healthy: health.daemon.healthy,
96454
- active_worker_conn_id: health.activeWorkerConnId
96816
+ active_worker_conn_id: health.activeWorkerConnId,
96817
+ active_worker: health.activeWorkerConnId ? {
96818
+ conn_id: health.activeWorkerConnId,
96819
+ runtime: activeWorkerRuntime
96820
+ } : null
96455
96821
  },
96456
96822
  write: {
96457
96823
  daemon_ready: health.daemon.healthy,
@@ -96459,7 +96825,8 @@ function collectApiStatusUseCase(params3) {
96459
96825
  worker_ready: pluginRpcReady
96460
96826
  },
96461
96827
  uiContext,
96462
- selection
96828
+ selection,
96829
+ warnings
96463
96830
  };
96464
96831
  });
96465
96832
  }
@@ -97636,11 +98003,11 @@ var applyCommand = exports_Command.make("apply", {
97636
98003
 
97637
98004
  // src/services/ApiDaemonFiles.ts
97638
98005
  import { promises as fs19 } from "node:fs";
97639
- import path25 from "node:path";
98006
+ import path28 from "node:path";
97640
98007
  class ApiDaemonFiles extends Tag2("ApiDaemonFiles")() {
97641
98008
  }
97642
98009
  function ensureDir9(p3) {
97643
- return fs19.mkdir(path25.dirname(p3), { recursive: true }).then(() => {
98010
+ return fs19.mkdir(path28.dirname(p3), { recursive: true }).then(() => {
97644
98011
  return;
97645
98012
  });
97646
98013
  }
@@ -97648,19 +98015,19 @@ function defaultPidFile2() {
97648
98015
  const envPidFile = process.env.REMNOTE_API_PID_FILE;
97649
98016
  if (typeof envPidFile === "string" && envPidFile.trim())
97650
98017
  return resolveUserFilePath(envPidFile);
97651
- return path25.join(homeDir(), ".agent-remnote", "api.pid");
98018
+ return path28.join(homeDir(), ".agent-remnote", "api.pid");
97652
98019
  }
97653
98020
  function defaultLogFile2() {
97654
98021
  const envLogFile = process.env.REMNOTE_API_LOG_FILE;
97655
98022
  if (typeof envLogFile === "string" && envLogFile.trim())
97656
98023
  return resolveUserFilePath(envLogFile);
97657
- return path25.join(homeDir(), ".agent-remnote", "api.log");
98024
+ return path28.join(homeDir(), ".agent-remnote", "api.log");
97658
98025
  }
97659
98026
  function defaultStateFile2() {
97660
98027
  const envStateFile = process.env.REMNOTE_API_STATE_FILE;
97661
98028
  if (typeof envStateFile === "string" && envStateFile.trim())
97662
98029
  return resolveUserFilePath(envStateFile);
97663
- return path25.join(homeDir(), ".agent-remnote", "api.state.json");
98030
+ return path28.join(homeDir(), ".agent-remnote", "api.state.json");
97664
98031
  }
97665
98032
  function parseJson2(raw4, filePath) {
97666
98033
  try {
@@ -97806,6 +98173,7 @@ function childCommandLine2(params3) {
97806
98173
  function toPidFileValue2(params3) {
97807
98174
  return {
97808
98175
  pid: params3.pid,
98176
+ build: currentRuntimeBuildInfo(),
97809
98177
  started_at: params3.startedAt,
97810
98178
  host: params3.host,
97811
98179
  port: params3.port,
@@ -98513,6 +98881,7 @@ function runHttpApiRuntime(params3) {
98513
98881
  yield* apiFiles.writeStateFile(stateFilePath, {
98514
98882
  running: true,
98515
98883
  pid: process.pid,
98884
+ build: currentRuntimeBuildInfo(),
98516
98885
  host: host3,
98517
98886
  port: actualPort,
98518
98887
  basePath: basePath2,
@@ -98610,9 +98979,11 @@ var apiStatusCommand = exports_Command.make("status", { pidFile: pidFile12, stat
98610
98979
  const health = yield* api.health({ baseUrl: localBaseUrl, timeoutMs: API_HEALTH_TIMEOUT_MS }).pipe(either3);
98611
98980
  const status2 = yield* api.status({ baseUrl: localBaseUrl, timeoutMs: API_HEALTH_TIMEOUT_MS }).pipe(either3);
98612
98981
  const data = {
98982
+ runtime: currentRuntimeBuildInfo(),
98613
98983
  service: {
98614
98984
  running: running4,
98615
98985
  pid: pid ?? null,
98986
+ build: pidInfo?.build ?? state?.build ?? null,
98616
98987
  pid_file: pidFilePath,
98617
98988
  log_file: pidInfo?.log_file ?? cfg.apiLogFile ?? apiFiles.defaultLogFile(),
98618
98989
  state_file: pidInfo?.state_file ?? stateFilePath,
@@ -98625,7 +98996,16 @@ var apiStatusCommand = exports_Command.make("status", { pidFile: pidFile12, stat
98625
98996
  base_path: basePath2,
98626
98997
  status: status2._tag === "Right" ? status2.right : null,
98627
98998
  error: health._tag === "Left" ? health.left.message : undefined
98628
- }
98999
+ },
99000
+ warnings: status2._tag === "Right" ? runtimeVersionWarnings({
99001
+ current: currentRuntimeBuildInfo(),
99002
+ api: pidInfo?.build ?? state?.build ?? null,
99003
+ daemon: status2.right?.daemon?.build ?? null,
99004
+ plugin: status2.right?.plugin?.active_worker?.runtime ?? null
99005
+ }) : runtimeVersionWarnings({
99006
+ current: currentRuntimeBuildInfo(),
99007
+ api: pidInfo?.build ?? state?.build ?? null
99008
+ })
98629
99009
  };
98630
99010
  const md = [
98631
99011
  `- service_running: ${data.service.running}`,
@@ -99502,11 +99882,11 @@ function waitForPluginServerHealth(baseUrl, waitMs, timeoutMs3) {
99502
99882
 
99503
99883
  // src/services/PluginServerFiles.ts
99504
99884
  import { promises as fs20 } from "node:fs";
99505
- import path26 from "node:path";
99885
+ import path29 from "node:path";
99506
99886
  class PluginServerFiles extends Tag2("PluginServerFiles")() {
99507
99887
  }
99508
99888
  function ensureDir10(p3) {
99509
- return fs20.mkdir(path26.dirname(p3), { recursive: true }).then(() => {
99889
+ return fs20.mkdir(path29.dirname(p3), { recursive: true }).then(() => {
99510
99890
  return;
99511
99891
  });
99512
99892
  }
@@ -99514,19 +99894,19 @@ function defaultPidFile3() {
99514
99894
  const envPidFile = process.env.REMNOTE_PLUGIN_SERVER_PID_FILE;
99515
99895
  if (typeof envPidFile === "string" && envPidFile.trim())
99516
99896
  return resolveUserFilePath(envPidFile);
99517
- return path26.join(homeDir(), ".agent-remnote", "plugin-server.pid");
99897
+ return path29.join(homeDir(), ".agent-remnote", "plugin-server.pid");
99518
99898
  }
99519
99899
  function defaultLogFile3() {
99520
99900
  const envLogFile = process.env.REMNOTE_PLUGIN_SERVER_LOG_FILE;
99521
99901
  if (typeof envLogFile === "string" && envLogFile.trim())
99522
99902
  return resolveUserFilePath(envLogFile);
99523
- return path26.join(homeDir(), ".agent-remnote", "plugin-server.log");
99903
+ return path29.join(homeDir(), ".agent-remnote", "plugin-server.log");
99524
99904
  }
99525
99905
  function defaultStateFile3() {
99526
99906
  const envStateFile = process.env.REMNOTE_PLUGIN_SERVER_STATE_FILE;
99527
99907
  if (typeof envStateFile === "string" && envStateFile.trim())
99528
99908
  return resolveUserFilePath(envStateFile);
99529
- return path26.join(homeDir(), ".agent-remnote", "plugin-server.state.json");
99909
+ return path29.join(homeDir(), ".agent-remnote", "plugin-server.state.json");
99530
99910
  }
99531
99911
  function parseJson3(raw4, filePath) {
99532
99912
  try {
@@ -99674,6 +100054,7 @@ function childCommandLine3(params3) {
99674
100054
  function toPidFileValue3(params3) {
99675
100055
  return {
99676
100056
  pid: params3.pid,
100057
+ build: currentRuntimeBuildInfo(),
99677
100058
  started_at: params3.startedAt,
99678
100059
  host: params3.host,
99679
100060
  port: params3.port,
@@ -99978,55 +100359,12 @@ var pluginSearchCommand = exports_Command.make("search", { query: text9("query")
99978
100359
  `) });
99979
100360
  }).pipe(catchAll2(writeFailure)));
99980
100361
 
99981
- // src/lib/pluginArtifacts.ts
99982
- import { existsSync as existsSync2, statSync } from "node:fs";
99983
- import path27 from "node:path";
99984
- import { fileURLToPath as fileURLToPath2 } from "node:url";
99985
- function currentDir(moduleUrl) {
99986
- return path27.dirname(fileURLToPath2(moduleUrl));
99987
- }
99988
- function isDirectory(targetPath) {
99989
- try {
99990
- return statSync(targetPath).isDirectory();
99991
- } catch {
99992
- return false;
99993
- }
99994
- }
99995
- function distCandidates(moduleUrl) {
99996
- const dir2 = currentDir(moduleUrl);
99997
- return [
99998
- path27.resolve(dir2, "../../plugin-artifacts/dist"),
99999
- path27.resolve(dir2, "../plugin-artifacts/dist"),
100000
- path27.resolve(dir2, "../../../plugin/dist"),
100001
- path27.resolve(dir2, "../../plugin/dist")
100002
- ];
100003
- }
100004
- function validateDistPath(targetPath) {
100005
- return isDirectory(targetPath) && existsSync2(path27.join(targetPath, "manifest.json"));
100006
- }
100007
- function resolvePluginDistPath(moduleUrl = import.meta.url) {
100008
- for (const candidate of distCandidates(moduleUrl)) {
100009
- if (validateDistPath(candidate))
100010
- return candidate;
100011
- }
100012
- throw new CliError({
100013
- code: "DEPENDENCY_MISSING",
100014
- message: "Plugin build artifacts are unavailable",
100015
- exitCode: 1,
100016
- details: { candidates: distCandidates(moduleUrl) },
100017
- hint: [
100018
- "Run npm run build --workspace @remnote/plugin in the repository checkout",
100019
- "Or install a packaged agent-remnote release that includes plugin artifacts"
100020
- ]
100021
- });
100022
- }
100023
-
100024
100362
  // src/runtime/plugin-static/runPluginStaticRuntime.ts
100025
100363
  import { createServer as createServer2 } from "node:http";
100026
100364
 
100027
100365
  // src/lib/pluginStaticFiles.ts
100028
100366
  import { promises as fs21 } from "node:fs";
100029
- import path28 from "node:path";
100367
+ import path30 from "node:path";
100030
100368
  var CONTENT_TYPES = new Map([
100031
100369
  [".css", "text/css; charset=utf-8"],
100032
100370
  [".html", "text/html; charset=utf-8"],
@@ -100036,7 +100374,7 @@ var CONTENT_TYPES = new Map([
100036
100374
  [".txt", "text/plain; charset=utf-8"]
100037
100375
  ]);
100038
100376
  function contentTypeFor(filePath) {
100039
- return CONTENT_TYPES.get(path28.extname(filePath).toLowerCase()) ?? "application/octet-stream";
100377
+ return CONTENT_TYPES.get(path30.extname(filePath).toLowerCase()) ?? "application/octet-stream";
100040
100378
  }
100041
100379
  function normalizeAssetPath(pathname) {
100042
100380
  let decoded;
@@ -100046,7 +100384,7 @@ function normalizeAssetPath(pathname) {
100046
100384
  return null;
100047
100385
  }
100048
100386
  const raw4 = decoded === "/" ? "index.html" : decoded.replace(/^\/+/, "");
100049
- const normalized = path28.posix.normalize(raw4);
100387
+ const normalized = path30.posix.normalize(raw4);
100050
100388
  if (!normalized || normalized === "." || normalized.startsWith("../") || normalized === "..")
100051
100389
  return null;
100052
100390
  return normalized;
@@ -100060,8 +100398,8 @@ async function readPluginStaticAsset(params3) {
100060
100398
  if (!relativePath) {
100061
100399
  return { ok: false, statusCode: 404, message: "Not found" };
100062
100400
  }
100063
- const filePath = path28.resolve(params3.distPath, relativePath);
100064
- if (filePath !== params3.distPath && !filePath.startsWith(`${params3.distPath}${path28.sep}`)) {
100401
+ const filePath = path30.resolve(params3.distPath, relativePath);
100402
+ if (filePath !== params3.distPath && !filePath.startsWith(`${params3.distPath}${path30.sep}`)) {
100065
100403
  return { ok: false, statusCode: 404, message: "Not found" };
100066
100404
  }
100067
100405
  try {
@@ -100219,6 +100557,8 @@ var pluginServeCommand = exports_Command.make("serve", { host: host7, port: port
100219
100557
  yield* files.writeStateFile(stateFilePath, {
100220
100558
  running: true,
100221
100559
  pid: process.pid,
100560
+ build: currentRuntimeBuildInfo(),
100561
+ plugin_build: readPluginDistBuildInfo(distPath2) ?? undefined,
100222
100562
  host: host9,
100223
100563
  port: port11,
100224
100564
  startedAt: Date.now(),
@@ -100292,10 +100632,29 @@ function getPluginStatus(params3) {
100292
100632
  const port11 = pidInfo?.port ?? state?.port ?? PLUGIN_SERVER_DEFAULT_PORT;
100293
100633
  const baseUrl = pluginServerLocalBaseUrl(host9, port11);
100294
100634
  const health = yield* checkPluginServerHealth(baseUrl, PLUGIN_SERVER_HEALTH_TIMEOUT_MS).pipe(either3);
100635
+ const runtime6 = currentRuntimeBuildInfo();
100636
+ const serviceBuild = pidInfo?.build ?? state?.build ?? null;
100637
+ const pluginBuild = state?.plugin_build ?? null;
100638
+ const warnings = [];
100639
+ if (serviceBuild && serviceBuild.build_id !== runtime6.build_id) {
100640
+ warnings.push(`plugin server process build mismatch: current=${runtime6.build_id} live=${serviceBuild.build_id}`);
100641
+ }
100642
+ const expectedPluginBuild = currentExpectedPluginBuildInfo();
100643
+ if (expectedPluginBuild && pluginBuild && pluginBuild.build_id !== expectedPluginBuild.build_id) {
100644
+ warnings.push(`served plugin build mismatch: expected=${expectedPluginBuild.build_id} live=${pluginBuild.build_id}`);
100645
+ }
100646
+ if (running4 && !serviceBuild) {
100647
+ warnings.push("plugin server pid/state metadata has no build info; restart plugin server to refresh runtime metadata");
100648
+ }
100649
+ if (running4 && !pluginBuild) {
100650
+ warnings.push("served plugin artifact build info is unavailable; rebuild plugin artifacts and restart plugin server");
100651
+ }
100295
100652
  return {
100653
+ runtime: runtime6,
100296
100654
  service: {
100297
100655
  running: running4,
100298
100656
  pid: pid ?? null,
100657
+ build: serviceBuild,
100299
100658
  pid_file: params3.pidFilePath,
100300
100659
  log_file: pidInfo?.log_file ?? files.defaultLogFile(),
100301
100660
  state_file: effectiveStateFilePath,
@@ -100308,8 +100667,10 @@ function getPluginStatus(params3) {
100308
100667
  host: host9,
100309
100668
  port: port11,
100310
100669
  dist_path: state?.distPath ?? "",
100670
+ build: pluginBuild,
100311
100671
  error: health._tag === "Left" ? health.left.message : undefined
100312
- }
100672
+ },
100673
+ warnings: warnings.length > 0 ? warnings : undefined
100313
100674
  };
100314
100675
  });
100315
100676
  }
@@ -101091,6 +101452,237 @@ function compileTableValueOps(params3) {
101091
101452
  return ops;
101092
101453
  }
101093
101454
 
101455
+ // src/commands/write/_refValue.ts
101456
+ function invalidArgs(message2, details) {
101457
+ return new CliError({
101458
+ code: "INVALID_ARGS",
101459
+ message: message2,
101460
+ exitCode: 2,
101461
+ details
101462
+ });
101463
+ }
101464
+ function normalizeRefValue(raw4) {
101465
+ const trimmed2 = raw4.trim();
101466
+ const link3 = tryParseRemnoteLink(trimmed2);
101467
+ if (link3?.remId)
101468
+ return link3.remId;
101469
+ return trimmed2;
101470
+ }
101471
+ function looksLikeRefValue(raw4) {
101472
+ const value8 = raw4.trim();
101473
+ if (!value8)
101474
+ return false;
101475
+ if (value8.startsWith("remnote://") || value8.startsWith("http://") || value8.startsWith("https://"))
101476
+ return true;
101477
+ const idx = value8.indexOf(":");
101478
+ if (idx <= 0)
101479
+ return false;
101480
+ const prefix2 = value8.slice(0, idx).trim().toLowerCase();
101481
+ return prefix2 === "id" || prefix2 === "page" || prefix2 === "title" || prefix2 === "daily";
101482
+ }
101483
+ function resolveRefValue(raw4) {
101484
+ return gen2(function* () {
101485
+ const normalized = normalizeRefValue(raw4);
101486
+ if (!normalized) {
101487
+ return yield* fail8(invalidArgs(`Invalid ref value: ${raw4}`));
101488
+ }
101489
+ if (!looksLikeRefValue(raw4))
101490
+ return normalized;
101491
+ const refs = yield* RefResolver;
101492
+ return yield* refs.resolve(raw4);
101493
+ });
101494
+ }
101495
+
101496
+ // src/commands/write/_placementSpec.ts
101497
+ function invalidArgs2(message2, details) {
101498
+ return new CliError({
101499
+ code: "INVALID_ARGS",
101500
+ message: message2,
101501
+ exitCode: 2,
101502
+ details
101503
+ });
101504
+ }
101505
+ function invalidPlacementSpec(optionName, raw4) {
101506
+ return new CliError({
101507
+ code: "INVALID_ARGS",
101508
+ message: `Invalid ${optionName} placement spec: ${raw4}`,
101509
+ exitCode: 2,
101510
+ details: { option: optionName, value: raw4 },
101511
+ hint: [
101512
+ `Examples: ${optionName} standalone`,
101513
+ `Examples: ${optionName} parent:id:P1`,
101514
+ `Examples: ${optionName} parent[2]:id:P1`,
101515
+ `Examples: ${optionName} before:id:R1`,
101516
+ `Examples: ${optionName} after:id:R1`
101517
+ ]
101518
+ });
101519
+ }
101520
+ function parsePlacementSpec(raw4, options6) {
101521
+ return gen2(function* () {
101522
+ const optionName = options6?.optionName ?? "--at";
101523
+ const allowStandalone = options6?.allowStandalone !== false;
101524
+ const text15 = raw4.trim();
101525
+ if (!text15) {
101526
+ return yield* fail8(invalidArgs2(`${optionName} requires a placement spec`, { option: optionName, value: raw4 }));
101527
+ }
101528
+ if (text15 === "standalone") {
101529
+ if (!allowStandalone) {
101530
+ return yield* fail8(invalidArgs2(`${optionName} does not allow standalone placement`, { option: optionName, value: raw4 }));
101531
+ }
101532
+ return { kind: "standalone" };
101533
+ }
101534
+ const parentMatch = /^parent(?:\[(\d+)\])?:(.+)$/.exec(text15);
101535
+ if (parentMatch) {
101536
+ const positionText = parentMatch[1];
101537
+ const parentRef = normalizeRefValue(parentMatch[2] ?? "");
101538
+ if (!parentRef) {
101539
+ return yield* fail8(invalidPlacementSpec(optionName, raw4));
101540
+ }
101541
+ const parsedPosition = positionText === undefined ? undefined : Number.parseInt(positionText, 10);
101542
+ if (positionText !== undefined && (parsedPosition === undefined || !Number.isFinite(parsedPosition) || parsedPosition < 0)) {
101543
+ return yield* fail8(invalidPlacementSpec(optionName, raw4));
101544
+ }
101545
+ const position3 = parsedPosition;
101546
+ return {
101547
+ kind: "parent",
101548
+ parentRef,
101549
+ ...position3 !== undefined ? { position: position3 } : {}
101550
+ };
101551
+ }
101552
+ const beforeMatch = /^before:(.+)$/.exec(text15);
101553
+ if (beforeMatch) {
101554
+ const anchorRef = normalizeRefValue(beforeMatch[1] ?? "");
101555
+ if (!anchorRef) {
101556
+ return yield* fail8(invalidPlacementSpec(optionName, raw4));
101557
+ }
101558
+ return { kind: "before", anchorRef };
101559
+ }
101560
+ const afterMatch = /^after:(.+)$/.exec(text15);
101561
+ if (afterMatch) {
101562
+ const anchorRef = normalizeRefValue(afterMatch[1] ?? "");
101563
+ if (!anchorRef) {
101564
+ return yield* fail8(invalidPlacementSpec(optionName, raw4));
101565
+ }
101566
+ return { kind: "after", anchorRef };
101567
+ }
101568
+ return yield* fail8(invalidPlacementSpec(optionName, raw4));
101569
+ });
101570
+ }
101571
+ function fetchRemLayouts(db, ids3) {
101572
+ const unique = Array.from(new Set(ids3.map((id3) => String(id3 ?? "").trim()).filter(Boolean)));
101573
+ if (unique.length === 0)
101574
+ return new Map;
101575
+ const placeholders = unique.map(() => "?").join(",");
101576
+ const stmt = db.prepare(`SELECT _id AS id,
101577
+ json_extract(doc, '$.parent') AS parentId,
101578
+ json_extract(doc, '$.f') AS sortKey
101579
+ FROM quanta
101580
+ WHERE _id IN (${placeholders})`);
101581
+ const rows = stmt.all(...unique);
101582
+ const out = new Map;
101583
+ for (const row of rows) {
101584
+ const id3 = String(row.id ?? "").trim();
101585
+ if (!id3)
101586
+ continue;
101587
+ out.set(id3, {
101588
+ id: id3,
101589
+ parentId: typeof row.parentId === "string" && row.parentId.trim() ? row.parentId.trim() : null,
101590
+ sortKey: typeof row.sortKey === "string" && row.sortKey.trim() ? row.sortKey.trim() : null
101591
+ });
101592
+ }
101593
+ return out;
101594
+ }
101595
+ function listSiblingOrder(db, parentId) {
101596
+ const stmt = db.prepare(`SELECT _id AS id
101597
+ FROM quanta
101598
+ WHERE json_extract(doc, '$.parent') = ?
101599
+ ORDER BY json_extract(doc, '$.f')`);
101600
+ const rows = stmt.all(parentId);
101601
+ return rows.map((row) => String(row.id ?? "").trim()).filter(Boolean);
101602
+ }
101603
+ function resolveLocalDbPath() {
101604
+ return gen2(function* () {
101605
+ yield* failInRemoteMode({
101606
+ command: "write placement resolution",
101607
+ reason: "this path still reads local RemNote hierarchy metadata to resolve before/after placement"
101608
+ });
101609
+ const cfg = yield* AppConfig;
101610
+ if (cfg.remnoteDb)
101611
+ return cfg.remnoteDb;
101612
+ const workspace = yield* resolveWorkspaceSnapshot({}).pipe(catchAll2(() => succeed8(undefined)));
101613
+ const dbPath = workspace?.resolved ? workspace.dbPath : undefined;
101614
+ if (dbPath)
101615
+ return dbPath;
101616
+ return yield* fail8(new CliError({
101617
+ code: "WORKSPACE_UNRESOLVED",
101618
+ message: "Workspace is unresolved for write placement resolution",
101619
+ exitCode: 1
101620
+ }));
101621
+ });
101622
+ }
101623
+ function resolveAnchorPlacement(params3) {
101624
+ return gen2(function* () {
101625
+ const remDb = yield* RemDb;
101626
+ const dbPath = yield* resolveLocalDbPath();
101627
+ const anchorId = yield* resolveRefValue(params3.anchorRef);
101628
+ const layouts = yield* remDb.withDb(dbPath, async (db) => fetchRemLayouts(db, [anchorId])).pipe(map17((result) => result.result));
101629
+ const layout = layouts.get(anchorId);
101630
+ if (!layout) {
101631
+ return yield* fail8(invalidArgs2(`Anchor Rem not found: ${params3.anchorRef}`, { anchor_ref: params3.anchorRef }));
101632
+ }
101633
+ if (!layout.parentId) {
101634
+ return yield* fail8(invalidArgs2("Anchor-relative placement requires an anchor with a parent (top-level anchors are unsupported)", {
101635
+ anchor_ref: params3.anchorRef,
101636
+ anchor_id: anchorId
101637
+ }));
101638
+ }
101639
+ const siblingOrder = yield* remDb.withDb(dbPath, async (db) => listSiblingOrder(db, layout.parentId)).pipe(map17((result) => result.result));
101640
+ const index = siblingOrder.indexOf(anchorId);
101641
+ if (index < 0) {
101642
+ return yield* fail8(invalidArgs2("Failed to resolve anchor sibling position", {
101643
+ anchor_ref: params3.anchorRef,
101644
+ anchor_id: anchorId
101645
+ }));
101646
+ }
101647
+ return {
101648
+ parentId: layout.parentId,
101649
+ position: index + params3.offset
101650
+ };
101651
+ });
101652
+ }
101653
+ function resolvePlacementSpec(spec) {
101654
+ return gen2(function* () {
101655
+ switch (spec.kind) {
101656
+ case "standalone":
101657
+ return { kind: "standalone" };
101658
+ case "parent":
101659
+ return {
101660
+ kind: "parent",
101661
+ parentId: yield* resolveRefValue(spec.parentRef),
101662
+ ...spec.position !== undefined ? { position: spec.position } : {}
101663
+ };
101664
+ case "before": {
101665
+ const resolved = yield* resolveAnchorPlacement({ anchorRef: spec.anchorRef, offset: 0 });
101666
+ return { kind: "before", parentId: resolved.parentId, position: resolved.position };
101667
+ }
101668
+ case "after": {
101669
+ const resolved = yield* resolveAnchorPlacement({ anchorRef: spec.anchorRef, offset: 1 });
101670
+ return { kind: "after", parentId: resolved.parentId, position: resolved.position };
101671
+ }
101672
+ }
101673
+ });
101674
+ }
101675
+ function resolveTreePlacementSpec(spec, options6) {
101676
+ return gen2(function* () {
101677
+ const optionName = options6?.optionName ?? "--at";
101678
+ const resolved = yield* resolvePlacementSpec(spec);
101679
+ if (resolved.kind === "standalone") {
101680
+ return yield* fail8(invalidArgs2(`${optionName} does not allow standalone placement`, { option: optionName }));
101681
+ }
101682
+ return resolved;
101683
+ });
101684
+ }
101685
+
101094
101686
  // src/commands/write/_shared.ts
101095
101687
  function optionToUndefined43(opt) {
101096
101688
  return isSome2(opt) ? opt.value : undefined;
@@ -101110,6 +101702,71 @@ var writeCommonOptions = {
101110
101702
  idempotencyKey: readOptionalText3("idempotency-key"),
101111
101703
  meta: readOptionalText3("meta")
101112
101704
  };
101705
+ function invalidArgs3(message2, details) {
101706
+ return new CliError({
101707
+ code: "INVALID_ARGS",
101708
+ message: message2,
101709
+ exitCode: 2,
101710
+ details
101711
+ });
101712
+ }
101713
+ function normalizeOptionalText2(raw4) {
101714
+ const trimmed2 = typeof raw4 === "string" ? raw4.trim() : "";
101715
+ return trimmed2 ? trimmed2 : undefined;
101716
+ }
101717
+ function normalizeString2(value8) {
101718
+ return typeof value8 === "string" ? value8.trim() : "";
101719
+ }
101720
+ function requireStableSiblingRange(params3) {
101721
+ return gen2(function* () {
101722
+ const remDb = yield* RemDb;
101723
+ const dbPath = yield* resolveLocalDbPath();
101724
+ const layouts = yield* remDb.withDb(dbPath, async (db) => fetchRemLayouts(db, params3.remIds)).pipe(map17((result) => result.result));
101725
+ const entries2 = params3.remIds.map((id3) => layouts.get(id3)).filter((value8) => Boolean(value8));
101726
+ if (entries2.length !== params3.remIds.length) {
101727
+ return yield* fail8(invalidArgs3(params3.missingMessage, {
101728
+ expected: params3.remIds.length,
101729
+ resolved: entries2.length
101730
+ }));
101731
+ }
101732
+ const parentIds = Array.from(new Set(entries2.map((entry) => entry.parentId).filter((value8) => Boolean(value8))));
101733
+ if (parentIds.length !== 1) {
101734
+ return yield* fail8(invalidArgs3(params3.mismatchMessage, {
101735
+ parent_count: parentIds.length
101736
+ }));
101737
+ }
101738
+ const siblingOrder = yield* remDb.withDb(dbPath, async (db) => listSiblingOrder(db, parentIds[0])).pipe(map17((result) => result.result));
101739
+ const indexed = entries2.map((entry) => ({ id: entry.id, index: siblingOrder.indexOf(entry.id) })).sort((a, b) => a.index - b.index);
101740
+ const first3 = indexed[0];
101741
+ if (!first3 || first3.index < 0) {
101742
+ return yield* fail8(invalidArgs3("Failed to resolve sibling placement"));
101743
+ }
101744
+ for (let offset3 = 0;offset3 < indexed.length; offset3 += 1) {
101745
+ const current2 = indexed[offset3];
101746
+ if (current2.index !== first3.index + offset3) {
101747
+ return yield* fail8(invalidArgs3(params3.mismatchMessage, {
101748
+ actual_positions: indexed.map((item) => item.index)
101749
+ }));
101750
+ }
101751
+ }
101752
+ return {
101753
+ orderedRemIds: indexed.map((item) => item.id),
101754
+ parentId: parentIds[0],
101755
+ position: first3.index
101756
+ };
101757
+ });
101758
+ }
101759
+ function resolveCreateDestinationTitle(params3) {
101760
+ return gen2(function* () {
101761
+ const destinationTitle = params3.explicitTitle ?? params3.inferredTitle;
101762
+ if (destinationTitle)
101763
+ return destinationTitle;
101764
+ if (params3.sourceKind === "explicit_from") {
101765
+ return yield* fail8(invalidArgs3(params3.sourceCount > 1 ? "rem create with multiple --from values requires --title" : "rem create could not infer a title from the single --from Rem; pass --title explicitly"));
101766
+ }
101767
+ return yield* fail8(invalidArgs3(params3.sourceCount > 1 ? "rem create --from-selection with multiple selected roots requires --title" : "rem create --from-selection could not infer a title from the single selected Rem; pass --title explicitly"));
101768
+ });
101769
+ }
101113
101770
 
101114
101771
  // src/commands/write/powerup/apply.ts
101115
101772
  var dispatchMode = choice5("dispatch-mode", ["serial", "conflict_parallel"]).pipe(optional5, map34(optionToUndefined43));
@@ -103094,186 +103751,36 @@ var readResolveRefCommand = exports_Command.make("resolve-ref", {
103094
103751
  yield* writeSuccess({ data: result, md: result.markdown ?? "" });
103095
103752
  }).pipe(catchAll2(writeFailure)));
103096
103753
 
103097
- // src/commands/write/rem/create.ts
103098
- function normalizeRemIdInput2(raw4) {
103099
- const trimmed2 = raw4.trim();
103100
- const link3 = tryParseRemnoteLink(trimmed2);
103101
- if (link3?.remId)
103102
- return link3.remId;
103103
- return trimmed2;
103104
- }
103105
- var tag8 = text9("tag").pipe(repeated5);
103106
- var writeRemCreateCommand = exports_Command.make("create", {
103107
- parent: text9("parent").pipe(optional5, map34(optionToUndefined43)),
103108
- ref: text9("ref").pipe(optional5, map34(optionToUndefined43)),
103109
- text: text9("text").pipe(optional5, map34(optionToUndefined43)),
103110
- isDocument: boolean8("is-document"),
103111
- tag: tag8,
103112
- position: integer7("position").pipe(optional5, map34(optionToUndefined43)),
103113
- clientTempId: text9("client-temp-id").pipe(optional5, map34(optionToUndefined43)),
103114
- forceText: boolean8("force-text"),
103115
- notify: writeCommonOptions.notify,
103116
- ensureDaemon: writeCommonOptions.ensureDaemon,
103117
- wait: writeCommonOptions.wait,
103118
- timeoutMs: writeCommonOptions.timeoutMs,
103119
- pollMs: writeCommonOptions.pollMs,
103120
- dryRun: writeCommonOptions.dryRun,
103121
- priority: writeCommonOptions.priority,
103122
- clientId: writeCommonOptions.clientId,
103123
- idempotencyKey: writeCommonOptions.idempotencyKey,
103124
- meta: writeCommonOptions.meta
103125
- }, ({
103126
- parent,
103127
- ref: ref3,
103128
- text: text16,
103129
- isDocument,
103130
- tag: tag9,
103131
- position: position3,
103132
- clientTempId,
103133
- forceText: forceText2,
103134
- notify: notify3,
103135
- ensureDaemon: ensureDaemon5,
103136
- wait: wait3,
103137
- timeoutMs: timeoutMs4,
103138
- pollMs: pollMs3,
103139
- dryRun,
103140
- priority: priority3,
103141
- clientId: clientId3,
103142
- idempotencyKey: idempotencyKey3,
103143
- meta
103144
- }) => gen2(function* () {
103145
- if (!wait3 && (timeoutMs4 !== undefined || pollMs3 !== undefined)) {
103146
- return yield* fail8(new CliError({
103147
- code: "INVALID_ARGS",
103148
- message: "Use --wait to enable --timeout-ms/--poll-ms",
103149
- exitCode: 2
103150
- }));
103151
- }
103152
- if (dryRun && wait3) {
103153
- return yield* fail8(new CliError({
103154
- code: "INVALID_ARGS",
103155
- message: "--wait is not compatible with --dry-run",
103156
- exitCode: 2
103157
- }));
103158
- }
103159
- if (parent && ref3) {
103160
- return yield* fail8(new CliError({
103161
- code: "INVALID_ARGS",
103162
- message: "Choose only one of --parent or --ref",
103163
- exitCode: 2
103164
- }));
103165
- }
103166
- if (!parent && !ref3) {
103167
- return yield* fail8(new CliError({
103168
- code: "INVALID_ARGS",
103169
- message: "You must provide --parent or --ref",
103170
- exitCode: 2
103171
- }));
103172
- }
103173
- if (position3 !== undefined && (!Number.isFinite(position3) || position3 < 0)) {
103174
- return yield* fail8(new CliError({
103175
- code: "INVALID_ARGS",
103176
- message: "--position must be a non-negative integer",
103177
- exitCode: 2,
103178
- details: { position: position3 }
103179
- }));
103180
- }
103181
- const cfg = yield* AppConfig;
103182
- const refs = yield* RefResolver;
103183
- const payloadSvc = yield* Payload;
103184
- const resolvedRef = ref3 ?? "";
103185
- const parentId = typeof parent === "string" ? normalizeRemIdInput2(parent) : dryRun ? normalizeRemIdInput2(resolvedRef) : yield* refs.resolve(resolvedRef);
103186
- const tags2 = Array.isArray(tag9) ? tag9.map(normalizeRemIdInput2).filter(Boolean) : [];
103187
- const remClientTempId = clientTempId ? String(clientTempId).trim() : makeTempId();
103188
- const textValue = text16 !== undefined ? trimBoundaryBlankLines(text16) : undefined;
103189
- if (textValue && !forceText2 && looksLikeStructuredMarkdown2(textValue)) {
103190
- return yield* fail8(new CliError({
103191
- code: "INVALID_ARGS",
103192
- message: "Input passed to --text looks like structured Markdown. Use rem children append --rem <parentRemId> --markdown ... instead, or pass --force-text to keep it literal.",
103193
- exitCode: 2
103194
- }));
103195
- }
103196
- const payload2 = {
103197
- parentId,
103198
- clientTempId: remClientTempId
103199
- };
103200
- if (textValue !== undefined)
103201
- payload2.text = textValue;
103202
- if (isDocument)
103203
- payload2.isDocument = true;
103204
- if (tags2.length > 0)
103205
- payload2.tags = tags2;
103206
- if (position3 !== undefined)
103207
- payload2.position = position3;
103208
- const op2 = yield* try_3({
103209
- try: () => normalizeOp({ type: "create_rem", payload: payload2 }, payloadSvc.normalizeKeys),
103210
- catch: (e) => isCliError(e) ? e : new CliError({
103211
- code: "INVALID_PAYLOAD",
103212
- message: "Failed to generate op",
103213
- exitCode: 2,
103214
- details: { error: String(e?.message || e) }
103215
- })
103216
- });
103217
- const metaValue = meta ? yield* payloadSvc.readJson(meta) : undefined;
103218
- if (dryRun) {
103219
- yield* writeSuccess({
103220
- data: {
103221
- dry_run: true,
103222
- rem_client_temp_id: remClientTempId,
103223
- ops: [op2],
103224
- meta: metaValue ? payloadSvc.normalizeKeys(metaValue) : undefined
103225
- },
103226
- md: `- dry_run: true
103227
- - op: create_rem
103228
- - rem_client_temp_id: ${remClientTempId}
103229
- `
103230
- });
103231
- return;
103232
- }
103233
- const data = yield* enqueueOps({
103234
- ops: [op2],
103235
- priority: priority3,
103236
- clientId: clientId3,
103237
- idempotencyKey: idempotencyKey3,
103238
- meta: metaValue,
103239
- notify: notify3,
103240
- ensureDaemon: ensureDaemon5
103754
+ // src/commands/write/_portalStrategy.ts
103755
+ function invalidArgs4(message2, details) {
103756
+ return new CliError({
103757
+ code: "INVALID_ARGS",
103758
+ message: message2,
103759
+ exitCode: 2,
103760
+ details
103241
103761
  });
103242
- const waited = wait3 ? yield* waitForTxn({ txnId: data.txn_id, timeoutMs: timeoutMs4, pollMs: pollMs3 }) : null;
103243
- const queue = yield* Queue;
103244
- const created = waited && waited.is_success === true ? yield* gen2(function* () {
103245
- let idMap = Array.isArray(waited?.id_map) ? waited.id_map : [];
103246
- if (idMap.length === 0) {
103247
- const inspected = yield* queue.inspect({ dbPath: cfg.storeDb, txnId: data.txn_id }).pipe(catchAll2(() => succeed8({ id_map: [] })));
103248
- idMap = Array.isArray(inspected?.id_map) ? inspected.id_map : [];
103762
+ }
103763
+ function parsePortalStrategy(raw4) {
103764
+ return gen2(function* () {
103765
+ const text16 = typeof raw4 === "string" ? raw4.trim() : "";
103766
+ if (!text16)
103767
+ return { kind: "none" };
103768
+ if (text16 === "in-place")
103769
+ return { kind: "in_place" };
103770
+ if (!text16.startsWith("at:")) {
103771
+ return yield* fail8(invalidArgs4(`Invalid --portal strategy: ${raw4}`, { option: "--portal", value: raw4 }));
103249
103772
  }
103250
- const match24 = idMap.find((r) => String(r?.client_temp_id ?? "") === remClientTempId);
103251
- const remoteId = match24?.remote_id ? String(match24.remote_id) : "";
103252
- return remoteId ? { rem_id: remoteId, id_map: idMap } : { id_map: idMap };
103253
- }) : {};
103254
- const out = waited ? { ...data, ...waited, rem_client_temp_id: remClientTempId, ...created } : { ...data, rem_client_temp_id: remClientTempId };
103255
- yield* writeSuccess({
103256
- data: out,
103257
- ids: [data.txn_id, ...data.op_ids],
103258
- md: [
103259
- `- txn_id: ${data.txn_id}`,
103260
- `- op_ids: ${data.op_ids.length}`,
103261
- `- notified: ${data.notified}`,
103262
- `- sent: ${data.sent ?? ""}`,
103263
- `- rem_client_temp_id: ${remClientTempId}`,
103264
- ...waited ? [`- status: ${waited.status}`, `- elapsed_ms: ${waited.elapsed_ms}`] : []
103265
- ].join(`
103266
- `)
103773
+ const placement = yield* parsePlacementSpec(text16.slice(3), {
103774
+ optionName: "--portal",
103775
+ allowStandalone: false
103776
+ });
103777
+ return { kind: "at", placement };
103267
103778
  });
103268
- }).pipe(catchAll2(writeFailure)));
103779
+ }
103269
103780
 
103270
103781
  // src/commands/write/rem/children/common.ts
103271
- function normalizeRemIdInput3(raw4) {
103272
- const trimmed2 = raw4.trim();
103273
- const link3 = tryParseRemnoteLink(trimmed2);
103274
- if (link3?.remId)
103275
- return link3.remId;
103276
- return trimmed2;
103782
+ function resolveSubjectRemId(raw4) {
103783
+ return resolveRefValue(raw4);
103277
103784
  }
103278
103785
  function ensureWaitArgs(params3) {
103279
103786
  return gen2(function* () {
@@ -103449,9 +103956,720 @@ function extractReplaceBackupSummary(txnDetail) {
103449
103956
  };
103450
103957
  }
103451
103958
 
103959
+ // src/commands/write/rem/_promotion.ts
103960
+ var DURABLE_TARGET_ALIAS = "durable_target";
103961
+ var PORTAL_REM_ALIAS = "portal_rem";
103962
+ function truncateText3(value8, maxLength) {
103963
+ const normalized = value8.replace(/\s+/g, " ").trim();
103964
+ if (!normalized)
103965
+ return "";
103966
+ if (normalized.length <= maxLength)
103967
+ return normalized;
103968
+ return `${normalized.slice(0, maxLength)}...`;
103969
+ }
103970
+ function pickTitle3(kt, ke, r) {
103971
+ const combined = [kt, ke].map(normalizeString2).filter(Boolean).join(" | ");
103972
+ const raw4 = combined || normalizeString2(r);
103973
+ if (!raw4)
103974
+ return "";
103975
+ const normalized = raw4.replace(/\s+/g, " ").trim();
103976
+ const title = normalized.split(/\n| - |——|。|!|?|\.|: /)[0]?.trim() || normalized;
103977
+ return truncateText3(title, 80);
103978
+ }
103979
+ function fetchRemTitleMap3(db, ids4) {
103980
+ const unique = Array.from(new Set(ids4.map((id5) => String(id5 ?? "").trim()).filter(Boolean)));
103981
+ if (unique.length === 0)
103982
+ return new Map;
103983
+ const placeholders = unique.map(() => "?").join(",");
103984
+ const stmt = db.prepare(`SELECT id,
103985
+ json_extract(doc, '$.kt') AS kt,
103986
+ json_extract(doc, '$.ke') AS ke,
103987
+ json_extract(doc, '$.r') AS r
103988
+ FROM remsSearchInfos
103989
+ WHERE id IN (${placeholders})`);
103990
+ const rows = stmt.all(...unique);
103991
+ const map39 = new Map;
103992
+ for (const row of rows) {
103993
+ const id5 = String(row.id ?? "").trim();
103994
+ if (!id5)
103995
+ continue;
103996
+ map39.set(id5, pickTitle3(row.kt, row.ke, row.r));
103997
+ }
103998
+ return map39;
103999
+ }
104000
+ function readSingleRemTitle(params3) {
104001
+ return gen2(function* () {
104002
+ const ids4 = Array.from(new Set(params3.ids.map((id5) => String(id5 ?? "").trim()).filter(Boolean)));
104003
+ if (ids4.length !== 1)
104004
+ return;
104005
+ const selectionTitle = normalizeOptionalText2(params3.selectionTitle);
104006
+ if (selectionTitle)
104007
+ return selectionTitle;
104008
+ const cfg = yield* AppConfig;
104009
+ if (cfg.apiBaseUrl)
104010
+ return;
104011
+ const remDb = yield* RemDb;
104012
+ const workspace = cfg.remnoteDb ? undefined : yield* resolveWorkspaceSnapshot({}).pipe(catchAll2(() => succeed8(undefined)));
104013
+ const dbPath = cfg.remnoteDb ?? (workspace?.resolved ? workspace.dbPath : undefined);
104014
+ if (!dbPath)
104015
+ return;
104016
+ const titleMap = yield* remDb.withDb(dbPath, async (db) => fetchRemTitleMap3(db, ids4)).pipe(map17((value8) => value8.result), catchAll2(() => succeed8(new Map)));
104017
+ return normalizeOptionalText2(titleMap.get(ids4[0]));
104018
+ });
104019
+ }
104020
+ function convertPortalAtPlacement(strategy) {
104021
+ return gen2(function* () {
104022
+ if (strategy.kind !== "at" || strategy.placement.kind === "standalone") {
104023
+ return yield* fail8(invalidArgs3("Invalid --portal strategy", { portal: strategy }));
104024
+ }
104025
+ switch (strategy.placement.kind) {
104026
+ case "parent":
104027
+ return { kind: "parent", parentRef: strategy.placement.parentRef };
104028
+ case "before":
104029
+ return { kind: "before", anchorRef: strategy.placement.anchorRef };
104030
+ case "after":
104031
+ return { kind: "after", anchorRef: strategy.placement.anchorRef };
104032
+ }
104033
+ });
104034
+ }
104035
+ function convertMovePortalPlacement(strategy) {
104036
+ return gen2(function* () {
104037
+ if (strategy.kind === "none")
104038
+ return { kind: "none" };
104039
+ if (strategy.kind === "in_place")
104040
+ return { kind: "in_place_single_rem" };
104041
+ const converted = yield* convertPortalAtPlacement(strategy);
104042
+ return converted;
104043
+ });
104044
+ }
104045
+ function normalizeExplicitFromSource(params3) {
104046
+ return gen2(function* () {
104047
+ const uniqueRemIds = Array.from(new Set(params3.remIds.map((id5) => String(id5 ?? "").trim()).filter(Boolean)));
104048
+ if (uniqueRemIds.length === 0) {
104049
+ return { orderedRemIds: [] };
104050
+ }
104051
+ if (params3.requireInPlaceRange) {
104052
+ const range3 = yield* requireStableSiblingRange({
104053
+ remIds: uniqueRemIds,
104054
+ missingMessage: "Explicit --from refs could not be fully resolved from the local RemNote DB",
104055
+ mismatchMessage: "Explicit --from refs must resolve to contiguous sibling Rems under the same parent for --portal in-place"
104056
+ });
104057
+ return {
104058
+ orderedRemIds: range3.orderedRemIds,
104059
+ inPlaceRange: range3
104060
+ };
104061
+ }
104062
+ const maybeRange = yield* requireStableSiblingRange({
104063
+ remIds: uniqueRemIds,
104064
+ missingMessage: "Explicit --from refs could not be fully resolved from the local RemNote DB",
104065
+ mismatchMessage: "Explicit --from refs are not one contiguous sibling range under the same parent"
104066
+ }).pipe(option2);
104067
+ if (maybeRange._tag === "Some") {
104068
+ return { orderedRemIds: maybeRange.value.orderedRemIds };
104069
+ }
104070
+ return { orderedRemIds: uniqueRemIds };
104071
+ });
104072
+ }
104073
+ function addResolvedPlacementToInput(input, placement) {
104074
+ if (placement.kind === "standalone") {
104075
+ input.standalone = true;
104076
+ return;
104077
+ }
104078
+ if (typeof placement.parentId === "string" && placement.parentId.trim()) {
104079
+ input.parent_id = placement.parentId;
104080
+ }
104081
+ if (typeof placement.position === "number") {
104082
+ input.position = placement.position;
104083
+ }
104084
+ }
104085
+ function normalizeCreatePromotionIntent(args2) {
104086
+ return gen2(function* () {
104087
+ const contentPlacement = yield* gen2(function* () {
104088
+ return yield* parsePlacementSpec(args2.at, { optionName: "--at" });
104089
+ });
104090
+ const portalStrategy = yield* parsePortalStrategy(args2.portal);
104091
+ const textValue = args2.text !== undefined ? trimBoundaryBlankLines(args2.text) : undefined;
104092
+ const hasTextSource = textValue !== undefined;
104093
+ const hasMarkdownSource = normalizeOptionalText2(args2.markdown) !== undefined;
104094
+ const resolvedExplicitFrom = yield* forEach9(args2.from, (value8) => resolveRefValue(value8));
104095
+ const hasExplicitFrom = resolvedExplicitFrom.length > 0;
104096
+ const hasSelectionSource = args2.fromSelection === true;
104097
+ const sourceCount = (hasTextSource ? 1 : 0) + (hasMarkdownSource ? 1 : 0) + (hasExplicitFrom ? 1 : 0) + (hasSelectionSource ? 1 : 0);
104098
+ if (sourceCount > 1) {
104099
+ return yield* fail8(invalidArgs3("Choose exactly one content source: --text, --markdown, repeated --from, or --from-selection"));
104100
+ }
104101
+ if (sourceCount === 0) {
104102
+ return yield* fail8(invalidArgs3("You must provide one content source: --text, --markdown, repeated --from, or --from-selection"));
104103
+ }
104104
+ const title = normalizeOptionalText2(args2.title);
104105
+ if (hasMarkdownSource && !title) {
104106
+ return yield* fail8(invalidArgs3("rem create --markdown requires --title"));
104107
+ }
104108
+ if (hasSelectionSource && (hasTextSource || hasMarkdownSource || hasExplicitFrom)) {
104109
+ return yield* fail8(invalidArgs3("--from-selection cannot be combined with --text, --markdown, or explicit --from"));
104110
+ }
104111
+ if (hasTextSource && textValue && !args2.forceText && looksLikeStructuredMarkdown2(textValue)) {
104112
+ return yield* fail8(invalidArgs3("Input passed to --text looks like structured Markdown. Use --markdown instead, or pass --force-text to keep it literal."));
104113
+ }
104114
+ if (portalStrategy.kind === "in_place" && (hasTextSource || hasMarkdownSource)) {
104115
+ return yield* fail8(invalidArgs3("--portal in-place is only supported with --from-selection or repeated --from"));
104116
+ }
104117
+ const tags2 = yield* forEach9(args2.tag, (value8) => resolveRefValue(value8)).pipe(map17((values5) => values5.filter(Boolean)));
104118
+ if (hasMarkdownSource) {
104119
+ const markdown2 = yield* readMarkdownArg(args2.markdown);
104120
+ const portalPlacement2 = portalStrategy.kind === "none" ? { kind: "none" } : yield* convertPortalAtPlacement(portalStrategy);
104121
+ return {
104122
+ source: { kind: "markdown", markdown: markdown2 },
104123
+ contentPlacement,
104124
+ portalPlacement: portalPlacement2,
104125
+ destinationTitle: title,
104126
+ isDocument: args2.isDocument,
104127
+ tags: tags2,
104128
+ hasBodyTextChild: false
104129
+ };
104130
+ }
104131
+ if (hasSelectionSource) {
104132
+ const resolvedSelection = yield* resolveCurrentSelectionRemIds({});
104133
+ const selectionRange = yield* requireStableSiblingRange({
104134
+ remIds: resolvedSelection.rem_ids,
104135
+ missingMessage: "Current selection could not be fully resolved from the local RemNote DB",
104136
+ mismatchMessage: "Current selection must resolve to contiguous sibling Rems under the same parent"
104137
+ });
104138
+ const inferredTitle = !title ? yield* readSingleRemTitle({
104139
+ ids: selectionRange.orderedRemIds,
104140
+ selectionTitle: selectionRange.orderedRemIds.length === 1 && String(resolvedSelection?.selection?.current?.id ?? "").trim() === selectionRange.orderedRemIds[0] ? normalizeOptionalText2(String(resolvedSelection?.selection?.current?.title ?? "")) : undefined
104141
+ }) : undefined;
104142
+ const destinationTitle = yield* resolveCreateDestinationTitle({
104143
+ explicitTitle: title,
104144
+ inferredTitle,
104145
+ sourceKind: "selection",
104146
+ sourceCount: selectionRange.orderedRemIds.length
104147
+ });
104148
+ const portalPlacement2 = portalStrategy.kind === "in_place" ? {
104149
+ kind: "in_place_selection_range",
104150
+ parentId: selectionRange.parentId,
104151
+ position: selectionRange.position
104152
+ } : portalStrategy.kind === "none" ? { kind: "none" } : yield* convertPortalAtPlacement(portalStrategy);
104153
+ return {
104154
+ source: { kind: "targets", remIds: selectionRange.orderedRemIds, sourceOrigin: "selection" },
104155
+ contentPlacement,
104156
+ portalPlacement: portalPlacement2,
104157
+ destinationTitle,
104158
+ isDocument: args2.isDocument,
104159
+ tags: tags2,
104160
+ hasBodyTextChild: false
104161
+ };
104162
+ }
104163
+ if (hasExplicitFrom) {
104164
+ const explicitSource = yield* normalizeExplicitFromSource({
104165
+ remIds: resolvedExplicitFrom,
104166
+ requireInPlaceRange: portalStrategy.kind === "in_place"
104167
+ });
104168
+ const inferredTitle = !title ? yield* readSingleRemTitle({ ids: explicitSource.orderedRemIds }) : undefined;
104169
+ const destinationTitle = yield* resolveCreateDestinationTitle({
104170
+ explicitTitle: title,
104171
+ inferredTitle,
104172
+ sourceKind: "explicit_from",
104173
+ sourceCount: explicitSource.orderedRemIds.length
104174
+ });
104175
+ const portalPlacement2 = portalStrategy.kind === "in_place" ? {
104176
+ kind: "in_place_selection_range",
104177
+ parentId: explicitSource.inPlaceRange.parentId,
104178
+ position: explicitSource.inPlaceRange.position
104179
+ } : portalStrategy.kind === "none" ? { kind: "none" } : yield* convertPortalAtPlacement(portalStrategy);
104180
+ return {
104181
+ source: { kind: "targets", remIds: explicitSource.orderedRemIds, sourceOrigin: "explicit_from" },
104182
+ contentPlacement,
104183
+ portalPlacement: portalPlacement2,
104184
+ destinationTitle,
104185
+ isDocument: args2.isDocument,
104186
+ tags: tags2,
104187
+ hasBodyTextChild: false
104188
+ };
104189
+ }
104190
+ const normalizedText = textValue ?? "";
104191
+ const portalPlacement = portalStrategy.kind === "none" ? { kind: "none" } : yield* convertPortalAtPlacement(portalStrategy);
104192
+ return {
104193
+ source: { kind: "text", text: normalizedText },
104194
+ contentPlacement,
104195
+ portalPlacement,
104196
+ destinationTitle: title ?? normalizedText,
104197
+ isDocument: args2.isDocument,
104198
+ tags: tags2,
104199
+ hasBodyTextChild: Boolean(title)
104200
+ };
104201
+ });
104202
+ }
104203
+ function buildCreatePromotionActions(intent) {
104204
+ return gen2(function* () {
104205
+ const resolvedContentPlacement = yield* resolvePlacementSpec(intent.contentPlacement);
104206
+ const destinationInput = {
104207
+ text: intent.destinationTitle,
104208
+ ...intent.isDocument ? { is_document: true } : {},
104209
+ ...intent.tags.length > 0 ? { tags: intent.tags } : {}
104210
+ };
104211
+ addResolvedPlacementToInput(destinationInput, resolvedContentPlacement);
104212
+ const actions = [
104213
+ {
104214
+ as: DURABLE_TARGET_ALIAS,
104215
+ action: "write.bullet",
104216
+ input: destinationInput
104217
+ }
104218
+ ];
104219
+ if (intent.source.kind === "markdown") {
104220
+ actions.push({
104221
+ action: "rem.children.append",
104222
+ input: {
104223
+ rem_id: `@${DURABLE_TARGET_ALIAS}`,
104224
+ markdown: intent.source.markdown
104225
+ }
104226
+ });
104227
+ }
104228
+ if (intent.source.kind === "text" && intent.hasBodyTextChild) {
104229
+ actions.push({
104230
+ action: "write.bullet",
104231
+ input: {
104232
+ parent_id: `@${DURABLE_TARGET_ALIAS}`,
104233
+ text: intent.source.text
104234
+ }
104235
+ });
104236
+ }
104237
+ if (intent.source.kind === "targets") {
104238
+ for (const remId of intent.source.remIds) {
104239
+ actions.push({
104240
+ action: "rem.move",
104241
+ input: {
104242
+ rem_id: remId,
104243
+ new_parent_id: `@${DURABLE_TARGET_ALIAS}`
104244
+ }
104245
+ });
104246
+ }
104247
+ }
104248
+ switch (intent.portalPlacement.kind) {
104249
+ case "none":
104250
+ break;
104251
+ case "parent":
104252
+ actions.push({
104253
+ as: PORTAL_REM_ALIAS,
104254
+ action: "portal.create",
104255
+ input: {
104256
+ parent_id: yield* resolveRefValue(intent.portalPlacement.parentRef),
104257
+ target_rem_id: `@${DURABLE_TARGET_ALIAS}`
104258
+ }
104259
+ });
104260
+ break;
104261
+ case "before": {
104262
+ const resolved = yield* resolvePlacementSpec({ kind: "before", anchorRef: intent.portalPlacement.anchorRef });
104263
+ if (resolved.kind === "standalone") {
104264
+ return yield* fail8(invalidArgs3("Invalid portal placement"));
104265
+ }
104266
+ actions.push({
104267
+ as: PORTAL_REM_ALIAS,
104268
+ action: "portal.create",
104269
+ input: {
104270
+ parent_id: resolved.parentId,
104271
+ position: resolved.position,
104272
+ target_rem_id: `@${DURABLE_TARGET_ALIAS}`
104273
+ }
104274
+ });
104275
+ break;
104276
+ }
104277
+ case "after": {
104278
+ const resolved = yield* resolvePlacementSpec({ kind: "after", anchorRef: intent.portalPlacement.anchorRef });
104279
+ if (resolved.kind === "standalone") {
104280
+ return yield* fail8(invalidArgs3("Invalid portal placement"));
104281
+ }
104282
+ actions.push({
104283
+ as: PORTAL_REM_ALIAS,
104284
+ action: "portal.create",
104285
+ input: {
104286
+ parent_id: resolved.parentId,
104287
+ position: resolved.position,
104288
+ target_rem_id: `@${DURABLE_TARGET_ALIAS}`
104289
+ }
104290
+ });
104291
+ break;
104292
+ }
104293
+ case "in_place_selection_range":
104294
+ actions.push({
104295
+ as: PORTAL_REM_ALIAS,
104296
+ action: "portal.create",
104297
+ input: {
104298
+ parent_id: intent.portalPlacement.parentId,
104299
+ position: intent.portalPlacement.position,
104300
+ target_rem_id: `@${DURABLE_TARGET_ALIAS}`
104301
+ }
104302
+ });
104303
+ break;
104304
+ }
104305
+ return actions;
104306
+ });
104307
+ }
104308
+ function normalizeMovePromotionIntent(args2) {
104309
+ return gen2(function* () {
104310
+ const contentPlacement = yield* gen2(function* () {
104311
+ return yield* parsePlacementSpec(args2.at, { optionName: "--at" });
104312
+ });
104313
+ const portalPlacement = yield* parsePortalStrategy(args2.portal).pipe(flatMap9(convertMovePortalPlacement));
104314
+ return {
104315
+ remId: yield* resolveRefValue(args2.subject),
104316
+ contentPlacement,
104317
+ isDocument: args2.isDocument,
104318
+ portalPlacement
104319
+ };
104320
+ });
104321
+ }
104322
+ function buildMovePromotionActions(intent) {
104323
+ return gen2(function* () {
104324
+ const resolvedContentPlacement = yield* resolvePlacementSpec(intent.contentPlacement);
104325
+ const moveInput = {
104326
+ rem_id: intent.remId,
104327
+ ...intent.isDocument ? { is_document: true } : {},
104328
+ ...intent.portalPlacement.kind === "in_place_single_rem" ? { leave_portal: true } : {}
104329
+ };
104330
+ if (resolvedContentPlacement.kind === "standalone") {
104331
+ moveInput.standalone = true;
104332
+ } else {
104333
+ moveInput.new_parent_id = resolvedContentPlacement.parentId;
104334
+ if (resolvedContentPlacement.position !== undefined) {
104335
+ moveInput.position = resolvedContentPlacement.position;
104336
+ }
104337
+ }
104338
+ const actions = [
104339
+ {
104340
+ action: "rem.move",
104341
+ input: moveInput
104342
+ }
104343
+ ];
104344
+ switch (intent.portalPlacement.kind) {
104345
+ case "none":
104346
+ case "in_place_single_rem":
104347
+ break;
104348
+ case "parent":
104349
+ actions.push({
104350
+ as: PORTAL_REM_ALIAS,
104351
+ action: "portal.create",
104352
+ input: {
104353
+ parent_id: yield* resolveRefValue(intent.portalPlacement.parentRef),
104354
+ target_rem_id: intent.remId
104355
+ }
104356
+ });
104357
+ break;
104358
+ case "before": {
104359
+ const resolved = yield* resolvePlacementSpec({ kind: "before", anchorRef: intent.portalPlacement.anchorRef });
104360
+ if (resolved.kind === "standalone") {
104361
+ return yield* fail8(invalidArgs3("Invalid portal placement"));
104362
+ }
104363
+ actions.push({
104364
+ as: PORTAL_REM_ALIAS,
104365
+ action: "portal.create",
104366
+ input: {
104367
+ parent_id: resolved.parentId,
104368
+ position: resolved.position,
104369
+ target_rem_id: intent.remId
104370
+ }
104371
+ });
104372
+ break;
104373
+ }
104374
+ case "after": {
104375
+ const resolved = yield* resolvePlacementSpec({ kind: "after", anchorRef: intent.portalPlacement.anchorRef });
104376
+ if (resolved.kind === "standalone") {
104377
+ return yield* fail8(invalidArgs3("Invalid portal placement"));
104378
+ }
104379
+ actions.push({
104380
+ as: PORTAL_REM_ALIAS,
104381
+ action: "portal.create",
104382
+ input: {
104383
+ parent_id: resolved.parentId,
104384
+ position: resolved.position,
104385
+ target_rem_id: intent.remId
104386
+ }
104387
+ });
104388
+ break;
104389
+ }
104390
+ }
104391
+ return actions;
104392
+ });
104393
+ }
104394
+
104395
+ // src/commands/write/rem/create.ts
104396
+ function findRemoteId(idMap, clientTempId) {
104397
+ if (!clientTempId || !Array.isArray(idMap))
104398
+ return;
104399
+ const match24 = idMap.find((entry) => String(entry?.client_temp_id ?? "") === clientTempId);
104400
+ const remoteId = typeof match24?.remote_id === "string" ? match24.remote_id.trim() : "";
104401
+ return remoteId || undefined;
104402
+ }
104403
+ function parseResultJson2(raw4) {
104404
+ const resultJson = raw4?.result_json;
104405
+ if (typeof resultJson === "string" && resultJson.trim()) {
104406
+ try {
104407
+ return JSON.parse(resultJson);
104408
+ } catch {}
104409
+ }
104410
+ return null;
104411
+ }
104412
+ function replaceStringRecursive(value8, from, to) {
104413
+ if (typeof value8 === "string")
104414
+ return value8 === from ? to : value8;
104415
+ if (Array.isArray(value8))
104416
+ return value8.map((item) => replaceStringRecursive(item, from, to));
104417
+ if (!value8 || typeof value8 !== "object")
104418
+ return value8;
104419
+ const out = {};
104420
+ for (const [key, entry] of Object.entries(value8)) {
104421
+ out[key] = replaceStringRecursive(entry, from, to);
104422
+ }
104423
+ return out;
104424
+ }
104425
+ function remapDurableTargetTempId(params3) {
104426
+ const nextTempId = normalizeString2(params3.nextTempId);
104427
+ if (!nextTempId || !params3.compiled.aliasMap || typeof params3.compiled.aliasMap !== "object")
104428
+ return params3.compiled;
104429
+ const aliasMap = params3.compiled.aliasMap;
104430
+ const current2 = normalizeString2(aliasMap[DURABLE_TARGET_ALIAS]);
104431
+ if (!current2 || current2 === nextTempId)
104432
+ return params3.compiled;
104433
+ return {
104434
+ kind: params3.compiled.kind,
104435
+ ops: replaceStringRecursive(params3.compiled.ops, current2, nextTempId),
104436
+ aliasMap: {
104437
+ ...aliasMap,
104438
+ [DURABLE_TARGET_ALIAS]: nextTempId
104439
+ }
104440
+ };
104441
+ }
104442
+ function buildPartialCreateReceipt(params3) {
104443
+ const idMap = Array.isArray(params3.detail?.id_map) ? params3.detail.id_map : [];
104444
+ const remId = findRemoteId(idMap, params3.remClientTempId);
104445
+ if (!remId)
104446
+ return;
104447
+ const ops = Array.isArray(params3.detail?.ops) ? params3.detail.ops : [];
104448
+ const nonPortalFailed = ops.some((op2) => String(op2?.type ?? "") !== "create_portal" && String(op2?.status ?? "") !== "succeeded");
104449
+ const portalOp = ops.find((op2) => String(op2?.type ?? "") === "create_portal");
104450
+ const portalFailed = portalOp && String(portalOp?.status ?? "") !== "succeeded";
104451
+ if (nonPortalFailed || !portalFailed)
104452
+ return;
104453
+ const portalResult = parseResultJson2(portalOp?.result);
104454
+ const portalError = normalizeString2(portalResult?.error) || normalizeString2(portalOp?.result?.error_message) || "portal insertion failed after durable target creation";
104455
+ const portalRemId = findRemoteId(idMap, params3.portalClientTempId);
104456
+ return {
104457
+ partial_success: true,
104458
+ txn_id: params3.txnId,
104459
+ op_ids: ops.map((op2) => String(op2?.op_id ?? "")).filter(Boolean),
104460
+ status: "partial_success",
104461
+ id_map: idMap,
104462
+ ...params3.remClientTempId ? { rem_client_temp_id: params3.remClientTempId } : {},
104463
+ ...params3.portalClientTempId ? { portal_client_temp_id: params3.portalClientTempId } : {},
104464
+ rem_id: remId,
104465
+ durable_target: {
104466
+ rem_id: remId,
104467
+ is_document: params3.intent.isDocument,
104468
+ placement_kind: params3.intent.contentPlacement.kind
104469
+ },
104470
+ source_context: {
104471
+ source_kind: params3.intent.source.kind,
104472
+ ...params3.intent.source.kind === "targets" ? { source_origin: params3.intent.source.sourceOrigin } : {}
104473
+ },
104474
+ portal: {
104475
+ requested: params3.intent.portalPlacement.kind !== "none",
104476
+ created: false,
104477
+ ...portalRemId ? { rem_id: portalRemId } : {},
104478
+ ...params3.intent.portalPlacement.kind !== "none" ? { placement_kind: params3.intent.portalPlacement.kind } : {}
104479
+ },
104480
+ warnings: [portalError],
104481
+ nextActions: [`agent-remnote queue inspect --txn ${params3.txnId}`]
104482
+ };
104483
+ }
104484
+ var tag8 = text9("tag").pipe(repeated5);
104485
+ var writeRemCreateCommand = exports_Command.make("create", {
104486
+ at: text9("at").pipe(withDescription5("Examples: standalone, parent:id:P1, parent[2]:id:P1, before:id:R1, after:id:R1.")),
104487
+ title: readOptionalText3("title"),
104488
+ text: readOptionalText3("text"),
104489
+ markdown: readOptionalText3("markdown"),
104490
+ from: text9("from").pipe(repeated5, withDescription5("Advanced path: combine repeated --from with --portal in-place only for one contiguous sibling range under one parent.")),
104491
+ fromSelection: boolean8("from-selection").pipe(withDescription5("Preferred default for --portal in-place when the current UI selection already matches the intended source range.")),
104492
+ portal: readOptionalText3("portal").pipe(withDescription5("Use in-place for original-slot backfill, or at:<placement-spec> for explicit portal placement.")),
104493
+ isDocument: boolean8("is-document"),
104494
+ tag: tag8,
104495
+ clientTempId: readOptionalText3("client-temp-id"),
104496
+ forceText: boolean8("force-text"),
104497
+ notify: writeCommonOptions.notify,
104498
+ ensureDaemon: writeCommonOptions.ensureDaemon,
104499
+ wait: writeCommonOptions.wait,
104500
+ timeoutMs: writeCommonOptions.timeoutMs,
104501
+ pollMs: writeCommonOptions.pollMs,
104502
+ dryRun: writeCommonOptions.dryRun,
104503
+ priority: writeCommonOptions.priority,
104504
+ clientId: writeCommonOptions.clientId,
104505
+ idempotencyKey: writeCommonOptions.idempotencyKey,
104506
+ meta: writeCommonOptions.meta
104507
+ }, ({
104508
+ at,
104509
+ title,
104510
+ text: text16,
104511
+ markdown: markdown2,
104512
+ from,
104513
+ fromSelection,
104514
+ portal,
104515
+ isDocument,
104516
+ tag: tag9,
104517
+ clientTempId,
104518
+ forceText: forceText2,
104519
+ notify: notify3,
104520
+ ensureDaemon: ensureDaemon5,
104521
+ wait: wait3,
104522
+ timeoutMs: timeoutMs4,
104523
+ pollMs: pollMs3,
104524
+ dryRun,
104525
+ priority: priority3,
104526
+ clientId: clientId3,
104527
+ idempotencyKey: idempotencyKey3,
104528
+ meta
104529
+ }) => gen2(function* () {
104530
+ yield* ensureWaitArgs({ wait: wait3, timeoutMs: timeoutMs4, pollMs: pollMs3, dryRun });
104531
+ const payloadSvc = yield* Payload;
104532
+ const intent = yield* normalizeCreatePromotionIntent({
104533
+ at,
104534
+ text: text16,
104535
+ markdown: markdown2,
104536
+ from,
104537
+ fromSelection,
104538
+ title,
104539
+ isDocument,
104540
+ tag: tag9,
104541
+ forceText: forceText2,
104542
+ portal
104543
+ });
104544
+ const actions = yield* buildCreatePromotionActions(intent);
104545
+ const metaValue = meta ? yield* payloadSvc.readJson(meta) : undefined;
104546
+ const body = {
104547
+ version: 1,
104548
+ kind: "actions",
104549
+ actions,
104550
+ ...priority3 !== undefined ? { priority: priority3 } : {},
104551
+ ...clientId3 ? { client_id: clientId3 } : {},
104552
+ ...idempotencyKey3 ? { idempotency_key: idempotencyKey3 } : {},
104553
+ ...metaValue !== undefined ? { meta: metaValue } : {},
104554
+ notify: notify3,
104555
+ ensure_daemon: ensureDaemon5
104556
+ };
104557
+ const compiledBase = yield* dryRunEnvelope(body);
104558
+ const compiled = remapDurableTargetTempId({ compiled: compiledBase, nextTempId: clientTempId });
104559
+ const aliasMap = compiled.aliasMap && typeof compiled.aliasMap === "object" ? compiled.aliasMap : undefined;
104560
+ const remClientTempId = aliasMap?.[DURABLE_TARGET_ALIAS];
104561
+ const portalClientTempId = aliasMap?.[PORTAL_REM_ALIAS];
104562
+ if (dryRun) {
104563
+ yield* writeSuccess({
104564
+ data: {
104565
+ dry_run: true,
104566
+ kind: compiled.kind,
104567
+ rem_client_temp_id: remClientTempId,
104568
+ ...portalClientTempId ? { portal_client_temp_id: portalClientTempId } : {},
104569
+ ops: compiled.ops,
104570
+ alias_map: aliasMap,
104571
+ meta: metaValue ? payloadSvc.normalizeKeys(metaValue) : undefined
104572
+ },
104573
+ md: [
104574
+ "- dry_run: true",
104575
+ "- kind: actions",
104576
+ ...remClientTempId ? [`- rem_client_temp_id: ${remClientTempId}`] : []
104577
+ ].join(`
104578
+ `)
104579
+ });
104580
+ return;
104581
+ }
104582
+ const submitBody = {
104583
+ version: 1,
104584
+ kind: "ops",
104585
+ ops: compiled.ops,
104586
+ ...priority3 !== undefined ? { priority: priority3 } : {},
104587
+ ...clientId3 ? { client_id: clientId3 } : {},
104588
+ ...idempotencyKey3 ? { idempotency_key: idempotencyKey3 } : {},
104589
+ ...metaValue !== undefined ? { meta: metaValue } : {},
104590
+ notify: notify3,
104591
+ ensure_daemon: ensureDaemon5
104592
+ };
104593
+ const submitted = yield* submitActionEnvelope({
104594
+ body: submitBody,
104595
+ wait: wait3,
104596
+ timeoutMs: timeoutMs4,
104597
+ pollMs: pollMs3
104598
+ }).pipe(either3);
104599
+ if (submitted._tag === "Left") {
104600
+ const txnId = String(submitted.left?.details?.txn_id ?? "").trim();
104601
+ if (wait3 && txnId) {
104602
+ const detail = yield* loadTxnDetail({ txnId }).pipe(catchAll2(() => succeed8(null)));
104603
+ const partial2 = detail ? buildPartialCreateReceipt({
104604
+ txnId,
104605
+ detail,
104606
+ remClientTempId,
104607
+ portalClientTempId,
104608
+ intent
104609
+ }) : undefined;
104610
+ if (partial2) {
104611
+ yield* writeSuccess({
104612
+ data: partial2,
104613
+ ids: [txnId, ...Array.isArray(partial2.op_ids) ? partial2.op_ids : []],
104614
+ md: [
104615
+ `- txn_id: ${txnId}`,
104616
+ "- status: partial_success",
104617
+ ...remClientTempId ? [`- rem_client_temp_id: ${remClientTempId}`] : [],
104618
+ ...portalClientTempId ? [`- portal_client_temp_id: ${portalClientTempId}`] : []
104619
+ ].join(`
104620
+ `)
104621
+ });
104622
+ return;
104623
+ }
104624
+ }
104625
+ return yield* fail8(submitted.left);
104626
+ }
104627
+ const out = submitted.right;
104628
+ const remId = findRemoteId(out?.id_map, remClientTempId);
104629
+ const portalRemId = findRemoteId(out?.id_map, portalClientTempId);
104630
+ const enriched = {
104631
+ ...out,
104632
+ rem_client_temp_id: remClientTempId,
104633
+ ...portalClientTempId ? { portal_client_temp_id: portalClientTempId } : {},
104634
+ ...remId ? { rem_id: remId } : {},
104635
+ ...portalRemId ? { portal_rem_id: portalRemId } : {},
104636
+ ...remId ? {
104637
+ durable_target: {
104638
+ rem_id: remId,
104639
+ is_document: intent.isDocument,
104640
+ placement_kind: intent.contentPlacement.kind
104641
+ }
104642
+ } : {},
104643
+ source_context: {
104644
+ source_kind: intent.source.kind,
104645
+ ...intent.source.kind === "targets" ? { source_origin: intent.source.sourceOrigin } : {}
104646
+ },
104647
+ portal: {
104648
+ requested: intent.portalPlacement.kind !== "none",
104649
+ created: Boolean(portalRemId),
104650
+ ...portalRemId ? { rem_id: portalRemId } : {},
104651
+ ...intent.portalPlacement.kind !== "none" ? { placement_kind: intent.portalPlacement.kind } : {}
104652
+ }
104653
+ };
104654
+ yield* writeSuccess({
104655
+ data: enriched,
104656
+ ids: Array.isArray(out?.op_ids) ? [out.txn_id, ...out.op_ids] : [out.txn_id],
104657
+ md: [
104658
+ `- txn_id: ${out.txn_id}`,
104659
+ `- op_ids: ${Array.isArray(out.op_ids) ? out.op_ids.length : ""}`,
104660
+ `- notified: ${out.notified}`,
104661
+ `- sent: ${out.sent ?? ""}`,
104662
+ ...remClientTempId ? [`- rem_client_temp_id: ${remClientTempId}`] : [],
104663
+ ...portalClientTempId ? [`- portal_client_temp_id: ${portalClientTempId}`] : [],
104664
+ ...out.status ? [`- status: ${out.status}`, `- elapsed_ms: ${out.elapsed_ms ?? ""}`] : []
104665
+ ].join(`
104666
+ `)
104667
+ });
104668
+ }).pipe(catchAll2(writeFailure))).pipe(exports_Command.withDescription("Create a new durable subject from text, markdown, explicit refs, or the current selection."));
104669
+
103452
104670
  // src/commands/write/rem/children/append.ts
103453
104671
  var writeRemChildrenAppendCommand = exports_Command.make("append", {
103454
- rem: text9("rem"),
104672
+ subject: text9("subject"),
103455
104673
  markdown: text9("markdown"),
103456
104674
  notify: writeCommonOptions.notify,
103457
104675
  ensureDaemon: writeCommonOptions.ensureDaemon,
@@ -103463,9 +104681,9 @@ var writeRemChildrenAppendCommand = exports_Command.make("append", {
103463
104681
  clientId: writeCommonOptions.clientId,
103464
104682
  idempotencyKey: writeCommonOptions.idempotencyKey,
103465
104683
  meta: writeCommonOptions.meta
103466
- }, ({ rem, markdown: markdown2, notify: notify3, ensureDaemon: ensureDaemon5, wait: wait3, timeoutMs: timeoutMs4, pollMs: pollMs3, dryRun, priority: priority3, clientId: clientId3, idempotencyKey: idempotencyKey3, meta }) => gen2(function* () {
104684
+ }, ({ subject, markdown: markdown2, notify: notify3, ensureDaemon: ensureDaemon5, wait: wait3, timeoutMs: timeoutMs4, pollMs: pollMs3, dryRun, priority: priority3, clientId: clientId3, idempotencyKey: idempotencyKey3, meta }) => gen2(function* () {
103467
104685
  yield* ensureWaitArgs({ wait: wait3, timeoutMs: timeoutMs4, pollMs: pollMs3, dryRun });
103468
- const remId = normalizeRemIdInput3(rem);
104686
+ const remId = yield* resolveSubjectRemId(subject);
103469
104687
  const markdownValue = yield* readMarkdownArg(markdown2);
103470
104688
  const body = yield* buildActionEnvelope({
103471
104689
  action: "rem.children.append",
@@ -103506,7 +104724,7 @@ var writeRemChildrenAppendCommand = exports_Command.make("append", {
103506
104724
 
103507
104725
  // src/commands/write/rem/children/clear.ts
103508
104726
  var writeRemChildrenClearCommand = exports_Command.make("clear", {
103509
- rem: text9("rem"),
104727
+ subject: text9("subject"),
103510
104728
  notify: writeCommonOptions.notify,
103511
104729
  ensureDaemon: writeCommonOptions.ensureDaemon,
103512
104730
  wait: writeCommonOptions.wait,
@@ -103517,9 +104735,9 @@ var writeRemChildrenClearCommand = exports_Command.make("clear", {
103517
104735
  clientId: writeCommonOptions.clientId,
103518
104736
  idempotencyKey: writeCommonOptions.idempotencyKey,
103519
104737
  meta: writeCommonOptions.meta
103520
- }, ({ rem, notify: notify3, ensureDaemon: ensureDaemon5, wait: wait3, timeoutMs: timeoutMs4, pollMs: pollMs3, dryRun, priority: priority3, clientId: clientId3, idempotencyKey: idempotencyKey3, meta }) => gen2(function* () {
104738
+ }, ({ subject, notify: notify3, ensureDaemon: ensureDaemon5, wait: wait3, timeoutMs: timeoutMs4, pollMs: pollMs3, dryRun, priority: priority3, clientId: clientId3, idempotencyKey: idempotencyKey3, meta }) => gen2(function* () {
103521
104739
  yield* ensureWaitArgs({ wait: wait3, timeoutMs: timeoutMs4, pollMs: pollMs3, dryRun });
103522
- const remId = normalizeRemIdInput3(rem);
104740
+ const remId = yield* resolveSubjectRemId(subject);
103523
104741
  const body = yield* buildActionEnvelope({
103524
104742
  action: "rem.children.clear",
103525
104743
  remId,
@@ -103558,7 +104776,7 @@ var writeRemChildrenClearCommand = exports_Command.make("clear", {
103558
104776
 
103559
104777
  // src/commands/write/rem/children/prepend.ts
103560
104778
  var writeRemChildrenPrependCommand = exports_Command.make("prepend", {
103561
- rem: text9("rem"),
104779
+ subject: text9("subject"),
103562
104780
  markdown: text9("markdown"),
103563
104781
  notify: writeCommonOptions.notify,
103564
104782
  ensureDaemon: writeCommonOptions.ensureDaemon,
@@ -103570,9 +104788,9 @@ var writeRemChildrenPrependCommand = exports_Command.make("prepend", {
103570
104788
  clientId: writeCommonOptions.clientId,
103571
104789
  idempotencyKey: writeCommonOptions.idempotencyKey,
103572
104790
  meta: writeCommonOptions.meta
103573
- }, ({ rem, markdown: markdown2, notify: notify3, ensureDaemon: ensureDaemon5, wait: wait3, timeoutMs: timeoutMs4, pollMs: pollMs3, dryRun, priority: priority3, clientId: clientId3, idempotencyKey: idempotencyKey3, meta }) => gen2(function* () {
104791
+ }, ({ subject, markdown: markdown2, notify: notify3, ensureDaemon: ensureDaemon5, wait: wait3, timeoutMs: timeoutMs4, pollMs: pollMs3, dryRun, priority: priority3, clientId: clientId3, idempotencyKey: idempotencyKey3, meta }) => gen2(function* () {
103574
104792
  yield* ensureWaitArgs({ wait: wait3, timeoutMs: timeoutMs4, pollMs: pollMs3, dryRun });
103575
- const remId = normalizeRemIdInput3(rem);
104793
+ const remId = yield* resolveSubjectRemId(subject);
103576
104794
  const markdownValue = yield* readMarkdownArg(markdown2);
103577
104795
  const body = yield* buildActionEnvelope({
103578
104796
  action: "rem.children.prepend",
@@ -103616,7 +104834,7 @@ function optionToUndefined53(opt) {
103616
104834
  return isSome2(opt) ? opt.value : undefined;
103617
104835
  }
103618
104836
  var writeRemChildrenReplaceCommand = exports_Command.make("replace", {
103619
- rem: text9("rem").pipe(optional5, map34(optionToUndefined53)),
104837
+ subject: text9("subject").pipe(optional5, map34(optionToUndefined53)),
103620
104838
  selection: boolean8("selection"),
103621
104839
  stateFile: text9("state-file").pipe(optional5, map34(optionToUndefined53)),
103622
104840
  staleMs: integer7("stale-ms").pipe(optional5, map34(optionToUndefined53)),
@@ -103634,7 +104852,7 @@ var writeRemChildrenReplaceCommand = exports_Command.make("replace", {
103634
104852
  idempotencyKey: writeCommonOptions.idempotencyKey,
103635
104853
  meta: writeCommonOptions.meta
103636
104854
  }, ({
103637
- rem,
104855
+ subject,
103638
104856
  selection,
103639
104857
  stateFile: stateFile24,
103640
104858
  staleMs: staleMs11,
@@ -103653,18 +104871,18 @@ var writeRemChildrenReplaceCommand = exports_Command.make("replace", {
103653
104871
  meta
103654
104872
  }) => gen2(function* () {
103655
104873
  yield* ensureWaitArgs({ wait: wait3, timeoutMs: timeoutMs4, pollMs: pollMs3, dryRun });
103656
- const hasRem = typeof rem === "string" && rem.trim().length > 0;
103657
- const targetCount = Number(hasRem) + Number(selection === true);
104874
+ const hasSubject = typeof subject === "string" && subject.trim().length > 0;
104875
+ const targetCount = Number(hasSubject) + Number(selection === true);
103658
104876
  if (targetCount !== 1) {
103659
104877
  return yield* fail8(new CliError({
103660
104878
  code: "INVALID_ARGS",
103661
- message: "Provide exactly one target via --rem or --selection",
104879
+ message: "Provide exactly one target via --subject or --selection",
103662
104880
  exitCode: 2
103663
104881
  }));
103664
104882
  }
103665
104883
  const target2 = selection ? yield* resolveCurrentSelectionRemId({ stateFile: stateFile24, staleMs: staleMs11 }) : {
103666
- source: "rem",
103667
- rem_id: normalizeRemIdInput3(String(rem))
104884
+ source: "subject",
104885
+ rem_id: yield* resolveSubjectRemId(String(subject))
103668
104886
  };
103669
104887
  const remId = target2.rem_id;
103670
104888
  const markdownValue = yield* readMarkdownArg(markdown2);
@@ -103731,7 +104949,7 @@ function optionToUndefined54(opt) {
103731
104949
  return isSome2(opt) ? opt.value : undefined;
103732
104950
  }
103733
104951
  var writeRemDeleteCommand = exports_Command.make("delete", {
103734
- rem: text9("rem"),
104952
+ subject: text9("subject"),
103735
104953
  maxDeleteSubtreeNodes: integer7("max-delete-subtree-nodes").pipe(optional5, map34(optionToUndefined54)),
103736
104954
  notify: writeCommonOptions.notify,
103737
104955
  ensureDaemon: writeCommonOptions.ensureDaemon,
@@ -103744,7 +104962,7 @@ var writeRemDeleteCommand = exports_Command.make("delete", {
103744
104962
  idempotencyKey: writeCommonOptions.idempotencyKey,
103745
104963
  meta: writeCommonOptions.meta
103746
104964
  }, ({
103747
- rem,
104965
+ subject,
103748
104966
  maxDeleteSubtreeNodes,
103749
104967
  notify: notify3,
103750
104968
  ensureDaemon: ensureDaemon5,
@@ -103779,11 +104997,12 @@ var writeRemDeleteCommand = exports_Command.make("delete", {
103779
104997
  }));
103780
104998
  }
103781
104999
  const payloadSvc = yield* Payload;
105000
+ const remId = yield* resolveRefValue(subject);
103782
105001
  const op2 = yield* try_3({
103783
105002
  try: () => normalizeOp({
103784
105003
  type: "delete_rem",
103785
105004
  payload: {
103786
- remId: rem,
105005
+ remId,
103787
105006
  ...maxDeleteSubtreeNodes !== undefined ? { maxDeleteSubtreeNodes } : {}
103788
105007
  }
103789
105008
  }, payloadSvc.normalizeKeys),
@@ -103800,7 +105019,7 @@ var writeRemDeleteCommand = exports_Command.make("delete", {
103800
105019
  data: { dry_run: true, ops: [op2], meta: metaValue ? payloadSvc.normalizeKeys(metaValue) : undefined },
103801
105020
  md: `- dry_run: true
103802
105021
  - op: delete_rem
103803
- - rem_id: ${rem}
105022
+ - rem_id: ${remId}
103804
105023
  `
103805
105024
  });
103806
105025
  return;
@@ -103831,18 +105050,27 @@ var writeRemDeleteCommand = exports_Command.make("delete", {
103831
105050
  }).pipe(catchAll2(writeFailure)));
103832
105051
 
103833
105052
  // src/commands/write/rem/move.ts
103834
- function normalizeRemIdInput4(raw4) {
103835
- const trimmed2 = raw4.trim();
103836
- const link3 = tryParseRemnoteLink(trimmed2);
103837
- if (link3?.remId)
103838
- return link3.remId;
103839
- return trimmed2;
105053
+ function parseResultJson3(raw4) {
105054
+ const resultJson = raw4?.result_json;
105055
+ if (typeof resultJson === "string" && resultJson.trim()) {
105056
+ try {
105057
+ return JSON.parse(resultJson);
105058
+ } catch {}
105059
+ }
105060
+ return null;
105061
+ }
105062
+ function findRemoteId2(idMap, clientTempId) {
105063
+ if (!clientTempId || !Array.isArray(idMap))
105064
+ return;
105065
+ const match24 = idMap.find((entry) => String(entry?.client_temp_id ?? "") === clientTempId);
105066
+ const remoteId = typeof match24?.remote_id === "string" ? match24.remote_id.trim() : "";
105067
+ return remoteId || undefined;
103840
105068
  }
103841
105069
  var writeRemMoveCommand = exports_Command.make("move", {
103842
- rem: text9("rem"),
103843
- parent: text9("parent").pipe(optional5, map34(optionToUndefined43)),
103844
- ref: text9("ref").pipe(optional5, map34(optionToUndefined43)),
103845
- position: integer7("position").pipe(optional5, map34(optionToUndefined43)),
105070
+ subject: text9("subject").pipe(withDescription5("Existing durable subject to relocate.")),
105071
+ at: text9("at").pipe(withDescription5("Examples: standalone, parent:id:P1, parent[2]:id:P1, before:id:R1, after:id:R1.")),
105072
+ portal: readOptionalText3("portal").pipe(withDescription5("Use in-place to leave a portal at the original location, or at:<placement-spec> for explicit portal placement.")),
105073
+ isDocument: boolean8("is-document"),
103846
105074
  notify: writeCommonOptions.notify,
103847
105075
  ensureDaemon: writeCommonOptions.ensureDaemon,
103848
105076
  wait: writeCommonOptions.wait,
@@ -103854,10 +105082,10 @@ var writeRemMoveCommand = exports_Command.make("move", {
103854
105082
  idempotencyKey: writeCommonOptions.idempotencyKey,
103855
105083
  meta: writeCommonOptions.meta
103856
105084
  }, ({
103857
- rem,
103858
- parent,
103859
- ref: ref3,
103860
- position: position3,
105085
+ subject,
105086
+ at,
105087
+ portal,
105088
+ isDocument,
103861
105089
  notify: notify3,
103862
105090
  ensureDaemon: ensureDaemon5,
103863
105091
  wait: wait3,
@@ -103869,72 +105097,282 @@ var writeRemMoveCommand = exports_Command.make("move", {
103869
105097
  idempotencyKey: idempotencyKey3,
103870
105098
  meta
103871
105099
  }) => gen2(function* () {
103872
- if (!wait3 && (timeoutMs4 !== undefined || pollMs3 !== undefined)) {
105100
+ yield* ensureWaitArgs({ wait: wait3, timeoutMs: timeoutMs4, pollMs: pollMs3, dryRun });
105101
+ const payloadSvc = yield* Payload;
105102
+ const metaValue = meta ? yield* payloadSvc.readJson(meta) : undefined;
105103
+ const intent = yield* normalizeMovePromotionIntent({
105104
+ subject,
105105
+ at,
105106
+ isDocument,
105107
+ portal
105108
+ });
105109
+ const actions = yield* buildMovePromotionActions(intent);
105110
+ const body = {
105111
+ version: 1,
105112
+ kind: "actions",
105113
+ actions,
105114
+ ...priority3 !== undefined ? { priority: priority3 } : {},
105115
+ ...clientId3 ? { client_id: clientId3 } : {},
105116
+ ...idempotencyKey3 ? { idempotency_key: idempotencyKey3 } : {},
105117
+ ...metaValue !== undefined ? { meta: metaValue } : {},
105118
+ notify: notify3,
105119
+ ensure_daemon: ensureDaemon5
105120
+ };
105121
+ if (dryRun) {
105122
+ const compiled = yield* dryRunEnvelope(body);
105123
+ yield* writeSuccess({
105124
+ data: {
105125
+ dry_run: true,
105126
+ kind: compiled.kind,
105127
+ ops: compiled.ops,
105128
+ alias_map: compiled.aliasMap,
105129
+ meta: metaValue ? payloadSvc.normalizeKeys(metaValue) : undefined
105130
+ },
105131
+ md: `- dry_run: true
105132
+ - action: rem.move
105133
+ - rem_id: ${intent.remId}
105134
+ `
105135
+ });
105136
+ return;
105137
+ }
105138
+ const out = yield* submitActionEnvelope({
105139
+ body,
105140
+ wait: wait3,
105141
+ timeoutMs: timeoutMs4,
105142
+ pollMs: pollMs3
105143
+ });
105144
+ const detail = wait3 && typeof out?.txn_id === "string" ? yield* loadTxnDetail({ txnId: String(out.txn_id) }).pipe(catchAll2(() => succeed8(null))) : null;
105145
+ const aliasMap = detail?.alias_map && typeof detail.alias_map === "object" ? detail.alias_map : out?.alias_map && typeof out.alias_map === "object" ? out.alias_map : undefined;
105146
+ const portalClientTempId = aliasMap?.[PORTAL_REM_ALIAS];
105147
+ const idMap = Array.isArray(detail?.id_map) ? detail.id_map : Array.isArray(out?.id_map) ? out.id_map : [];
105148
+ const portalRemId = findRemoteId2(idMap, portalClientTempId);
105149
+ const moveOp = Array.isArray(detail?.ops) ? detail.ops.find((op2) => String(op2?.type ?? "").trim() === "move_rem") : Array.isArray(out?.ops) ? out.ops.find((op2) => String(op2?.type ?? "").trim() === "move_rem") : null;
105150
+ const moveResult = parseResultJson3(moveOp?.result);
105151
+ const warnings = [
105152
+ ...Array.isArray(out?.warnings) ? out.warnings : [],
105153
+ ...Array.isArray(moveResult?.warnings) ? moveResult.warnings : []
105154
+ ];
105155
+ const nextActions = [
105156
+ ...Array.isArray(out?.nextActions) ? out.nextActions : [],
105157
+ ...Array.isArray(moveResult?.nextActions) ? moveResult.nextActions : []
105158
+ ];
105159
+ const inPlacePortalId = typeof moveResult?.portal_id === "string" && moveResult.portal_id.trim() ? moveResult.portal_id.trim() : undefined;
105160
+ const portalPlacementKind = intent.portalPlacement.kind === "none" ? undefined : intent.portalPlacement.kind;
105161
+ const portalCreated = intent.portalPlacement.kind === "in_place_single_rem" ? moveResult?.portal_created === true : Boolean(portalRemId);
105162
+ const effectivePortalRemId = intent.portalPlacement.kind === "in_place_single_rem" ? inPlacePortalId : portalRemId;
105163
+ const enriched = {
105164
+ ...out,
105165
+ rem_id: intent.remId,
105166
+ durable_target: {
105167
+ rem_id: intent.remId,
105168
+ is_document: intent.isDocument,
105169
+ placement_kind: intent.contentPlacement.kind
105170
+ },
105171
+ source_context: {
105172
+ source_kind: "targets",
105173
+ source_origin: "move_single_rem",
105174
+ ...typeof moveResult?.source_parent_id === "string" && moveResult.source_parent_id.trim() ? { parent_id: moveResult.source_parent_id.trim() } : {}
105175
+ },
105176
+ portal: {
105177
+ requested: intent.portalPlacement.kind !== "none",
105178
+ created: portalCreated,
105179
+ ...effectivePortalRemId ? { rem_id: effectivePortalRemId } : {},
105180
+ ...portalPlacementKind ? { placement_kind: portalPlacementKind } : {}
105181
+ },
105182
+ ...warnings.length > 0 ? { warnings } : {},
105183
+ ...nextActions.length > 0 ? { nextActions } : {}
105184
+ };
105185
+ yield* writeSuccess({
105186
+ data: enriched,
105187
+ ids: Array.isArray(out?.op_ids) ? [out.txn_id, ...out.op_ids] : [out.txn_id],
105188
+ md: [
105189
+ `- txn_id: ${out.txn_id}`,
105190
+ `- op_ids: ${Array.isArray(out.op_ids) ? out.op_ids.length : ""}`,
105191
+ `- notified: ${out.notified}`,
105192
+ `- sent: ${out.sent ?? ""}`,
105193
+ ...out.status ? [`- status: ${out.status}`, `- elapsed_ms: ${out.elapsed_ms ?? ""}`] : []
105194
+ ].join(`
105195
+ `)
105196
+ });
105197
+ }).pipe(catchAll2(writeFailure))).pipe(exports_Command.withDescription("Move an existing durable subject to a new placement, optionally leaving a portal behind."));
105198
+
105199
+ // src/commands/write/_subjectOptions.ts
105200
+ var subjectOption = text9("subject");
105201
+ var optionalSubjectOption = text9("subject").pipe(optional5, map34(optionToUndefined43));
105202
+ var repeatedSubjectOption = text9("subject").pipe(repeated5);
105203
+
105204
+ // src/commands/write/rem/replace.ts
105205
+ var writeRemReplaceCommand = exports_Command.make("replace", {
105206
+ subject: repeatedSubjectOption,
105207
+ selection: boolean8("selection"),
105208
+ stateFile: text9("state-file").pipe(optional5, map34(optionToUndefined43)),
105209
+ staleMs: integer7("stale-ms").pipe(optional5, map34(optionToUndefined43)),
105210
+ surface: choice5("surface", ["children", "self"]),
105211
+ markdown: text9("markdown"),
105212
+ assert: choice5("assert", ["single-root", "preserve-anchor", "no-literal-bullet"]).pipe(repeated5),
105213
+ notify: writeCommonOptions.notify,
105214
+ ensureDaemon: writeCommonOptions.ensureDaemon,
105215
+ wait: writeCommonOptions.wait,
105216
+ timeoutMs: writeCommonOptions.timeoutMs,
105217
+ pollMs: writeCommonOptions.pollMs,
105218
+ dryRun: writeCommonOptions.dryRun,
105219
+ priority: writeCommonOptions.priority,
105220
+ clientId: writeCommonOptions.clientId,
105221
+ idempotencyKey: writeCommonOptions.idempotencyKey,
105222
+ meta: writeCommonOptions.meta
105223
+ }, ({
105224
+ subject,
105225
+ selection,
105226
+ stateFile: stateFile24,
105227
+ staleMs: staleMs11,
105228
+ surface,
105229
+ markdown: markdown2,
105230
+ assert: assert2,
105231
+ notify: notify3,
105232
+ ensureDaemon: ensureDaemon5,
105233
+ wait: wait3,
105234
+ timeoutMs: timeoutMs4,
105235
+ pollMs: pollMs3,
105236
+ dryRun,
105237
+ priority: priority3,
105238
+ clientId: clientId3,
105239
+ idempotencyKey: idempotencyKey3,
105240
+ meta
105241
+ }) => gen2(function* () {
105242
+ yield* ensureWaitArgs({ wait: wait3, timeoutMs: timeoutMs4, pollMs: pollMs3, dryRun });
105243
+ const explicitIds = yield* forEach9(subject, (value8) => resolveRefValue(value8)).pipe(map17((ids4) => ids4.filter(Boolean)));
105244
+ if (explicitIds.length === 0 && !selection || explicitIds.length > 0 && selection) {
103873
105245
  return yield* fail8(new CliError({
103874
105246
  code: "INVALID_ARGS",
103875
- message: "Use --wait to enable --timeout-ms/--poll-ms",
105247
+ message: "Provide exactly one target selector via repeated --subject or --selection",
103876
105248
  exitCode: 2
103877
105249
  }));
103878
105250
  }
103879
- if (dryRun && wait3) {
105251
+ const target2 = explicitIds.length > 0 ? {
105252
+ source: "explicit",
105253
+ rem_ids: Array.from(new Set(explicitIds))
105254
+ } : yield* resolveCurrentSelectionRemIds({ stateFile: stateFile24, staleMs: staleMs11 });
105255
+ if (surface === "children" && target2.rem_ids.length !== 1) {
103880
105256
  return yield* fail8(new CliError({
103881
105257
  code: "INVALID_ARGS",
103882
- message: "--wait is not compatible with --dry-run",
103883
- exitCode: 2
105258
+ message: "rem replace --surface children requires exactly one target Rem",
105259
+ exitCode: 2,
105260
+ details: { surface, target: target2 }
103884
105261
  }));
103885
105262
  }
103886
- if (parent && ref3) {
105263
+ const assertions = assert2;
105264
+ if (surface === "self" && assertions.includes("preserve-anchor")) {
103887
105265
  return yield* fail8(new CliError({
103888
105266
  code: "INVALID_ARGS",
103889
- message: "Choose only one of --parent or --ref",
105267
+ message: "rem replace --surface=self does not support --assert preserve-anchor",
103890
105268
  exitCode: 2
103891
105269
  }));
103892
105270
  }
103893
- if (!parent && !ref3) {
105271
+ const markdownValue = yield* readMarkdownArg(markdown2);
105272
+ const body = yield* buildActionEnvelope({
105273
+ action: "rem.replace",
105274
+ remId: target2.rem_ids[0] ?? "",
105275
+ input: {
105276
+ surface,
105277
+ rem_ids: target2.rem_ids,
105278
+ markdown: markdownValue,
105279
+ ...assertions.length > 0 ? { assertions } : {}
105280
+ },
105281
+ priority: priority3,
105282
+ clientId: clientId3,
105283
+ idempotencyKey: idempotencyKey3,
105284
+ metaSpec: meta,
105285
+ notify: notify3,
105286
+ ensureDaemon: ensureDaemon5
105287
+ });
105288
+ if (dryRun) {
105289
+ const compiled = yield* dryRunEnvelope(body);
105290
+ yield* writeSuccess({
105291
+ data: { dry_run: true, target: { source: target2.source, rem_ids: target2.rem_ids }, ...compiled },
105292
+ md: `- dry_run: true
105293
+ - action: rem.replace
105294
+ - surface: ${surface}
105295
+ - targets: ${target2.rem_ids.length}
105296
+ `
105297
+ });
105298
+ return;
105299
+ }
105300
+ const data = yield* submitActionEnvelope({ body, wait: wait3, timeoutMs: timeoutMs4, pollMs: pollMs3 });
105301
+ yield* writeSuccess({
105302
+ data,
105303
+ ids: [data.txn_id, ...Array.isArray(data.op_ids) ? data.op_ids : []],
105304
+ md: [
105305
+ `- txn_id: ${data.txn_id}`,
105306
+ `- op_ids: ${Array.isArray(data.op_ids) ? data.op_ids.length : ""}`,
105307
+ `- notified: ${data.notified}`,
105308
+ `- sent: ${data.sent ?? ""}`,
105309
+ ...data.status ? [`- status: ${data.status}`, `- elapsed_ms: ${data.elapsed_ms ?? ""}`] : []
105310
+ ].join(`
105311
+ `)
105312
+ });
105313
+ }).pipe(catchAll2(writeFailure)));
105314
+
105315
+ // src/commands/write/tag/index.ts
105316
+ var writeTagAddCommand = exports_Command.make("add", {
105317
+ tag: text9("tag").pipe(repeated5, withDescription5("Tag endpoint. May be repeated.")),
105318
+ to: text9("to").pipe(repeated5, withDescription5("Rem endpoint. May be repeated.")),
105319
+ notify: writeCommonOptions.notify,
105320
+ ensureDaemon: writeCommonOptions.ensureDaemon,
105321
+ wait: writeCommonOptions.wait,
105322
+ timeoutMs: writeCommonOptions.timeoutMs,
105323
+ pollMs: writeCommonOptions.pollMs,
105324
+ dryRun: writeCommonOptions.dryRun,
105325
+ priority: writeCommonOptions.priority,
105326
+ clientId: writeCommonOptions.clientId,
105327
+ idempotencyKey: writeCommonOptions.idempotencyKey,
105328
+ meta: writeCommonOptions.meta
105329
+ }, ({ tag: tag9, to, notify: notify3, ensureDaemon: ensureDaemon5, wait: wait3, timeoutMs: timeoutMs4, pollMs: pollMs3, dryRun, priority: priority3, clientId: clientId3, idempotencyKey: idempotencyKey3, meta }) => gen2(function* () {
105330
+ if (!wait3 && (timeoutMs4 !== undefined || pollMs3 !== undefined)) {
103894
105331
  return yield* fail8(new CliError({
103895
105332
  code: "INVALID_ARGS",
103896
- message: "You must provide --parent or --ref",
105333
+ message: "Use --wait to enable --timeout-ms/--poll-ms",
103897
105334
  exitCode: 2
103898
105335
  }));
103899
105336
  }
103900
- if (position3 !== undefined && (!Number.isFinite(position3) || position3 < 0)) {
105337
+ if (dryRun && wait3) {
103901
105338
  return yield* fail8(new CliError({
103902
105339
  code: "INVALID_ARGS",
103903
- message: "--position must be a non-negative integer",
103904
- exitCode: 2,
103905
- details: { position: position3 }
105340
+ message: "--wait is not compatible with --dry-run",
105341
+ exitCode: 2
103906
105342
  }));
103907
105343
  }
103908
- const refs = yield* RefResolver;
103909
105344
  const payloadSvc = yield* Payload;
103910
- const remId = normalizeRemIdInput4(rem);
103911
- const resolvedRef = ref3 ?? "";
103912
- const parentId = typeof parent === "string" ? normalizeRemIdInput4(parent) : dryRun ? resolvedRef : yield* refs.resolve(resolvedRef);
103913
- const payload2 = { remId, newParentId: parentId };
103914
- if (position3 !== undefined)
103915
- payload2.position = position3;
103916
- const op2 = yield* try_3({
103917
- try: () => normalizeOp({ type: "move_rem", payload: payload2 }, payloadSvc.normalizeKeys),
105345
+ if (tag9.length === 0 || to.length === 0) {
105346
+ return yield* fail8(new CliError({
105347
+ code: "INVALID_ARGS",
105348
+ message: "tag add requires at least one --tag and at least one --to",
105349
+ exitCode: 2
105350
+ }));
105351
+ }
105352
+ const tagIds = yield* forEach9(tag9, (value8) => resolveRefValue(value8));
105353
+ const remIds = yield* forEach9(to, (value8) => resolveRefValue(value8));
105354
+ const ops = yield* forEach9(tagIds, (tagId) => forEach9(remIds, (remId) => try_3({
105355
+ try: () => normalizeOp({ type: "add_tag", payload: { remId, tagId } }, payloadSvc.normalizeKeys),
103918
105356
  catch: (e) => isCliError(e) ? e : new CliError({
103919
105357
  code: "INVALID_PAYLOAD",
103920
105358
  message: "Failed to generate op",
103921
105359
  exitCode: 2,
103922
105360
  details: { error: String(e?.message || e) }
103923
105361
  })
103924
- });
105362
+ }))).pipe(map17((rows) => rows.flat()));
103925
105363
  const metaValue = meta ? yield* payloadSvc.readJson(meta) : undefined;
103926
105364
  if (dryRun) {
103927
105365
  yield* writeSuccess({
103928
- data: { dry_run: true, ops: [op2], meta: metaValue ? payloadSvc.normalizeKeys(metaValue) : undefined },
105366
+ data: { dry_run: true, ops, meta: metaValue ? payloadSvc.normalizeKeys(metaValue) : undefined },
103929
105367
  md: `- dry_run: true
103930
- - op: move_rem
103931
- - rem_id: ${remId}
105368
+ - op: add_tag
105369
+ - relations: ${ops.length}
103932
105370
  `
103933
105371
  });
103934
105372
  return;
103935
105373
  }
103936
105374
  const data = yield* enqueueOps({
103937
- ops: [op2],
105375
+ ops,
103938
105376
  priority: priority3,
103939
105377
  clientId: clientId3,
103940
105378
  idempotencyKey: idempotencyKey3,
@@ -103956,17 +105394,11 @@ var writeRemMoveCommand = exports_Command.make("move", {
103956
105394
  ].join(`
103957
105395
  `)
103958
105396
  });
103959
- }).pipe(catchAll2(writeFailure)));
103960
-
103961
- // src/commands/write/rem/replace.ts
103962
- var writeRemReplaceCommand = exports_Command.make("replace", {
103963
- rem: text9("rem").pipe(repeated5),
103964
- selection: boolean8("selection"),
103965
- stateFile: text9("state-file").pipe(optional5, map34(optionToUndefined43)),
103966
- staleMs: integer7("stale-ms").pipe(optional5, map34(optionToUndefined43)),
103967
- surface: choice5("surface", ["children", "self"]),
103968
- markdown: text9("markdown"),
103969
- assert: choice5("assert", ["single-root", "preserve-anchor", "no-literal-bullet"]).pipe(repeated5),
105397
+ }).pipe(catchAll2(writeFailure))).pipe(exports_Command.withDescription("Relation write. Repeated --tag and repeated --to expand as a cross-product, not pairwise."));
105398
+ var writeTagRemoveCommand = exports_Command.make("remove", {
105399
+ tag: text9("tag").pipe(repeated5, withDescription5("Tag endpoint. May be repeated.")),
105400
+ to: text9("to").pipe(repeated5, withDescription5("Rem endpoint. May be repeated.")),
105401
+ removeProperties: boolean8("remove-properties").pipe(optional5, map34(optionToUndefined43)),
103970
105402
  notify: writeCommonOptions.notify,
103971
105403
  ensureDaemon: writeCommonOptions.ensureDaemon,
103972
105404
  wait: writeCommonOptions.wait,
@@ -103978,13 +105410,9 @@ var writeRemReplaceCommand = exports_Command.make("replace", {
103978
105410
  idempotencyKey: writeCommonOptions.idempotencyKey,
103979
105411
  meta: writeCommonOptions.meta
103980
105412
  }, ({
103981
- rem,
103982
- selection,
103983
- stateFile: stateFile24,
103984
- staleMs: staleMs11,
103985
- surface,
103986
- markdown: markdown2,
103987
- assert: assert2,
105413
+ tag: tag9,
105414
+ to,
105415
+ removeProperties,
103988
105416
  notify: notify3,
103989
105417
  ensureDaemon: ensureDaemon5,
103990
105418
  wait: wait3,
@@ -103996,101 +105424,6 @@ var writeRemReplaceCommand = exports_Command.make("replace", {
103996
105424
  idempotencyKey: idempotencyKey3,
103997
105425
  meta
103998
105426
  }) => gen2(function* () {
103999
- yield* ensureWaitArgs({ wait: wait3, timeoutMs: timeoutMs4, pollMs: pollMs3, dryRun });
104000
- const explicitIds = rem.map(normalizeRemIdInput3).filter(Boolean);
104001
- if (explicitIds.length === 0 && !selection || explicitIds.length > 0 && selection) {
104002
- return yield* fail8(new CliError({
104003
- code: "INVALID_ARGS",
104004
- message: "Provide exactly one target selector via repeated --rem or --selection",
104005
- exitCode: 2
104006
- }));
104007
- }
104008
- const target2 = explicitIds.length > 0 ? {
104009
- source: "explicit",
104010
- rem_ids: Array.from(new Set(explicitIds))
104011
- } : yield* resolveCurrentSelectionRemIds({ stateFile: stateFile24, staleMs: staleMs11 });
104012
- if (surface === "children" && target2.rem_ids.length !== 1) {
104013
- return yield* fail8(new CliError({
104014
- code: "INVALID_ARGS",
104015
- message: "rem replace --surface children requires exactly one target Rem",
104016
- exitCode: 2,
104017
- details: { surface, target: target2 }
104018
- }));
104019
- }
104020
- const assertions = assert2;
104021
- if (surface === "self" && assertions.includes("preserve-anchor")) {
104022
- return yield* fail8(new CliError({
104023
- code: "INVALID_ARGS",
104024
- message: "rem replace --surface=self does not support --assert preserve-anchor",
104025
- exitCode: 2
104026
- }));
104027
- }
104028
- const markdownValue = yield* readMarkdownArg(markdown2);
104029
- const body = yield* buildActionEnvelope({
104030
- action: "rem.replace",
104031
- remId: target2.rem_ids[0] ?? "",
104032
- input: {
104033
- surface,
104034
- rem_ids: target2.rem_ids,
104035
- markdown: markdownValue,
104036
- ...assertions.length > 0 ? { assertions } : {}
104037
- },
104038
- priority: priority3,
104039
- clientId: clientId3,
104040
- idempotencyKey: idempotencyKey3,
104041
- metaSpec: meta,
104042
- notify: notify3,
104043
- ensureDaemon: ensureDaemon5
104044
- });
104045
- if (dryRun) {
104046
- const compiled = yield* dryRunEnvelope(body);
104047
- yield* writeSuccess({
104048
- data: { dry_run: true, target: { source: target2.source, rem_ids: target2.rem_ids }, ...compiled },
104049
- md: `- dry_run: true
104050
- - action: rem.replace
104051
- - surface: ${surface}
104052
- - targets: ${target2.rem_ids.length}
104053
- `
104054
- });
104055
- return;
104056
- }
104057
- const data = yield* submitActionEnvelope({ body, wait: wait3, timeoutMs: timeoutMs4, pollMs: pollMs3 });
104058
- yield* writeSuccess({
104059
- data,
104060
- ids: [data.txn_id, ...Array.isArray(data.op_ids) ? data.op_ids : []],
104061
- md: [
104062
- `- txn_id: ${data.txn_id}`,
104063
- `- op_ids: ${Array.isArray(data.op_ids) ? data.op_ids.length : ""}`,
104064
- `- notified: ${data.notified}`,
104065
- `- sent: ${data.sent ?? ""}`,
104066
- ...data.status ? [`- status: ${data.status}`, `- elapsed_ms: ${data.elapsed_ms ?? ""}`] : []
104067
- ].join(`
104068
- `)
104069
- });
104070
- }).pipe(catchAll2(writeFailure)));
104071
-
104072
- // src/commands/write/tag/index.ts
104073
- function normalizeRemIdInput5(raw4) {
104074
- const trimmed2 = raw4.trim();
104075
- const link3 = tryParseRemnoteLink(trimmed2);
104076
- if (link3?.remId)
104077
- return link3.remId;
104078
- return trimmed2;
104079
- }
104080
- var writeTagAddCommand = exports_Command.make("add", {
104081
- rem: text9("rem"),
104082
- tag: text9("tag"),
104083
- notify: writeCommonOptions.notify,
104084
- ensureDaemon: writeCommonOptions.ensureDaemon,
104085
- wait: writeCommonOptions.wait,
104086
- timeoutMs: writeCommonOptions.timeoutMs,
104087
- pollMs: writeCommonOptions.pollMs,
104088
- dryRun: writeCommonOptions.dryRun,
104089
- priority: writeCommonOptions.priority,
104090
- clientId: writeCommonOptions.clientId,
104091
- idempotencyKey: writeCommonOptions.idempotencyKey,
104092
- meta: writeCommonOptions.meta
104093
- }, ({ rem, tag: tag9, notify: notify3, ensureDaemon: ensureDaemon5, wait: wait3, timeoutMs: timeoutMs4, pollMs: pollMs3, dryRun, priority: priority3, clientId: clientId3, idempotencyKey: idempotencyKey3, meta }) => gen2(function* () {
104094
105427
  if (!wait3 && (timeoutMs4 !== undefined || pollMs3 !== undefined)) {
104095
105428
  return yield* fail8(new CliError({
104096
105429
  code: "INVALID_ARGS",
@@ -104106,125 +105439,42 @@ var writeTagAddCommand = exports_Command.make("add", {
104106
105439
  }));
104107
105440
  }
104108
105441
  const payloadSvc = yield* Payload;
104109
- const remId = normalizeRemIdInput5(rem);
104110
- const tagId = normalizeRemIdInput5(tag9);
104111
- const op2 = yield* try_3({
104112
- try: () => normalizeOp({ type: "add_tag", payload: { remId, tagId } }, payloadSvc.normalizeKeys),
104113
- catch: (e) => isCliError(e) ? e : new CliError({
104114
- code: "INVALID_PAYLOAD",
104115
- message: "Failed to generate op",
104116
- exitCode: 2,
104117
- details: { error: String(e?.message || e) }
104118
- })
104119
- });
104120
- const metaValue = meta ? yield* payloadSvc.readJson(meta) : undefined;
104121
- if (dryRun) {
104122
- yield* writeSuccess({
104123
- data: { dry_run: true, ops: [op2], meta: metaValue ? payloadSvc.normalizeKeys(metaValue) : undefined },
104124
- md: `- dry_run: true
104125
- - op: add_tag
104126
- - rem_id: ${remId}
104127
- - tag_id: ${tagId}
104128
- `
104129
- });
104130
- return;
104131
- }
104132
- const data = yield* enqueueOps({
104133
- ops: [op2],
104134
- priority: priority3,
104135
- clientId: clientId3,
104136
- idempotencyKey: idempotencyKey3,
104137
- meta: metaValue,
104138
- notify: notify3,
104139
- ensureDaemon: ensureDaemon5
104140
- });
104141
- const waited = wait3 ? yield* waitForTxn({ txnId: data.txn_id, timeoutMs: timeoutMs4, pollMs: pollMs3 }) : null;
104142
- const out = waited ? { ...data, ...waited } : data;
104143
- yield* writeSuccess({
104144
- data: out,
104145
- ids: [data.txn_id, ...data.op_ids],
104146
- md: [
104147
- `- txn_id: ${data.txn_id}`,
104148
- `- op_ids: ${data.op_ids.length}`,
104149
- `- notified: ${data.notified}`,
104150
- `- sent: ${data.sent ?? ""}`,
104151
- ...waited ? [`- status: ${waited.status}`, `- elapsed_ms: ${waited.elapsed_ms}`] : []
104152
- ].join(`
104153
- `)
104154
- });
104155
- }).pipe(catchAll2(writeFailure)));
104156
- var writeTagRemoveCommand = exports_Command.make("remove", {
104157
- rem: text9("rem"),
104158
- tag: text9("tag"),
104159
- removeProperties: boolean8("remove-properties").pipe(optional5, map34(optionToUndefined43)),
104160
- notify: writeCommonOptions.notify,
104161
- ensureDaemon: writeCommonOptions.ensureDaemon,
104162
- wait: writeCommonOptions.wait,
104163
- timeoutMs: writeCommonOptions.timeoutMs,
104164
- pollMs: writeCommonOptions.pollMs,
104165
- dryRun: writeCommonOptions.dryRun,
104166
- priority: writeCommonOptions.priority,
104167
- clientId: writeCommonOptions.clientId,
104168
- idempotencyKey: writeCommonOptions.idempotencyKey,
104169
- meta: writeCommonOptions.meta
104170
- }, ({
104171
- rem,
104172
- tag: tag9,
104173
- removeProperties,
104174
- notify: notify3,
104175
- ensureDaemon: ensureDaemon5,
104176
- wait: wait3,
104177
- timeoutMs: timeoutMs4,
104178
- pollMs: pollMs3,
104179
- dryRun,
104180
- priority: priority3,
104181
- clientId: clientId3,
104182
- idempotencyKey: idempotencyKey3,
104183
- meta
104184
- }) => gen2(function* () {
104185
- if (!wait3 && (timeoutMs4 !== undefined || pollMs3 !== undefined)) {
104186
- return yield* fail8(new CliError({
104187
- code: "INVALID_ARGS",
104188
- message: "Use --wait to enable --timeout-ms/--poll-ms",
104189
- exitCode: 2
104190
- }));
104191
- }
104192
- if (dryRun && wait3) {
105442
+ if (tag9.length === 0 || to.length === 0) {
104193
105443
  return yield* fail8(new CliError({
104194
105444
  code: "INVALID_ARGS",
104195
- message: "--wait is not compatible with --dry-run",
105445
+ message: "tag remove requires at least one --tag and at least one --to",
104196
105446
  exitCode: 2
104197
105447
  }));
104198
105448
  }
104199
- const payloadSvc = yield* Payload;
104200
- const remId = normalizeRemIdInput5(rem);
104201
- const tagId = normalizeRemIdInput5(tag9);
104202
- const payload2 = { remId, tagId };
104203
- if (removeProperties !== undefined)
104204
- payload2.removeProperties = removeProperties;
104205
- const op2 = yield* try_3({
104206
- try: () => normalizeOp({ type: "remove_tag", payload: payload2 }, payloadSvc.normalizeKeys),
104207
- catch: (e) => isCliError(e) ? e : new CliError({
104208
- code: "INVALID_PAYLOAD",
104209
- message: "Failed to generate op",
104210
- exitCode: 2,
104211
- details: { error: String(e?.message || e) }
104212
- })
104213
- });
105449
+ const tagIds = yield* forEach9(tag9, (value8) => resolveRefValue(value8));
105450
+ const remIds = yield* forEach9(to, (value8) => resolveRefValue(value8));
105451
+ const ops = yield* forEach9(tagIds, (tagId) => forEach9(remIds, (remId) => {
105452
+ const payload2 = { remId, tagId };
105453
+ if (removeProperties !== undefined)
105454
+ payload2.removeProperties = removeProperties;
105455
+ return try_3({
105456
+ try: () => normalizeOp({ type: "remove_tag", payload: payload2 }, payloadSvc.normalizeKeys),
105457
+ catch: (e) => isCliError(e) ? e : new CliError({
105458
+ code: "INVALID_PAYLOAD",
105459
+ message: "Failed to generate op",
105460
+ exitCode: 2,
105461
+ details: { error: String(e?.message || e) }
105462
+ })
105463
+ });
105464
+ })).pipe(map17((rows) => rows.flat()));
104214
105465
  const metaValue = meta ? yield* payloadSvc.readJson(meta) : undefined;
104215
105466
  if (dryRun) {
104216
105467
  yield* writeSuccess({
104217
- data: { dry_run: true, ops: [op2], meta: metaValue ? payloadSvc.normalizeKeys(metaValue) : undefined },
105468
+ data: { dry_run: true, ops, meta: metaValue ? payloadSvc.normalizeKeys(metaValue) : undefined },
104218
105469
  md: `- dry_run: true
104219
105470
  - op: remove_tag
104220
- - rem_id: ${remId}
104221
- - tag_id: ${tagId}
105471
+ - relations: ${ops.length}
104222
105472
  `
104223
105473
  });
104224
105474
  return;
104225
105475
  }
104226
105476
  const data = yield* enqueueOps({
104227
- ops: [op2],
105477
+ ops,
104228
105478
  priority: priority3,
104229
105479
  clientId: clientId3,
104230
105480
  idempotencyKey: idempotencyKey3,
@@ -104246,22 +105496,15 @@ var writeTagRemoveCommand = exports_Command.make("remove", {
104246
105496
  ].join(`
104247
105497
  `)
104248
105498
  });
104249
- }).pipe(catchAll2(writeFailure)));
105499
+ }).pipe(catchAll2(writeFailure))).pipe(exports_Command.withDescription("Relation write. Repeated --tag and repeated --to expand as a cross-product, not pairwise."));
104250
105500
  var writeTagCommand = exports_Command.make("tag", {}).pipe(exports_Command.withSubcommands([writeTagAddCommand, writeTagRemoveCommand]));
104251
105501
 
104252
105502
  // src/commands/write/rem/tag/index.ts
104253
105503
  var writeRemTagCommand = exports_Command.make("tag", {}).pipe(exports_Command.withSubcommands([writeTagAddCommand, writeTagRemoveCommand]));
104254
105504
 
104255
105505
  // src/commands/write/rem/text.ts
104256
- function normalizeRemIdInput6(raw4) {
104257
- const trimmed2 = raw4.trim();
104258
- const link3 = tryParseRemnoteLink(trimmed2);
104259
- if (link3?.remId)
104260
- return link3.remId;
104261
- return trimmed2;
104262
- }
104263
105506
  var writeRemSetTextCommand = exports_Command.make("set-text", {
104264
- rem: text9("rem"),
105507
+ subject: text9("subject"),
104265
105508
  text: text9("text"),
104266
105509
  notify: writeCommonOptions.notify,
104267
105510
  ensureDaemon: writeCommonOptions.ensureDaemon,
@@ -104273,7 +105516,7 @@ var writeRemSetTextCommand = exports_Command.make("set-text", {
104273
105516
  clientId: writeCommonOptions.clientId,
104274
105517
  idempotencyKey: writeCommonOptions.idempotencyKey,
104275
105518
  meta: writeCommonOptions.meta
104276
- }, ({ rem, text: text16, notify: notify3, ensureDaemon: ensureDaemon5, wait: wait3, timeoutMs: timeoutMs4, pollMs: pollMs3, dryRun, priority: priority3, clientId: clientId3, idempotencyKey: idempotencyKey3, meta }) => gen2(function* () {
105519
+ }, ({ subject, text: text16, notify: notify3, ensureDaemon: ensureDaemon5, wait: wait3, timeoutMs: timeoutMs4, pollMs: pollMs3, dryRun, priority: priority3, clientId: clientId3, idempotencyKey: idempotencyKey3, meta }) => gen2(function* () {
104277
105520
  if (!wait3 && (timeoutMs4 !== undefined || pollMs3 !== undefined)) {
104278
105521
  return yield* fail8(new CliError({
104279
105522
  code: "INVALID_ARGS",
@@ -104293,7 +105536,7 @@ var writeRemSetTextCommand = exports_Command.make("set-text", {
104293
105536
  reason: "this command enqueues writes to the local queue/store without a HostApiClient branch"
104294
105537
  });
104295
105538
  const payloadSvc = yield* Payload;
104296
- const remId = normalizeRemIdInput6(rem);
105539
+ const remId = yield* resolveRefValue(subject);
104297
105540
  const textValue = trimBoundaryBlankLines(text16);
104298
105541
  const op2 = yield* try_3({
104299
105542
  try: () => normalizeOp({ type: "update_text", payload: { remId, text: textValue } }, payloadSvc.normalizeKeys),
@@ -105014,7 +106257,7 @@ var readSearchCommand = exports_Command.make("search", {
105014
106257
  var searchCommand = readSearchCommand;
105015
106258
 
105016
106259
  // src/commands/write/table/create.ts
105017
- function normalizeRemIdInput7(raw4) {
106260
+ function normalizeRemIdInput2(raw4) {
105018
106261
  const trimmed2 = raw4.trim();
105019
106262
  const link3 = tryParseRemnoteLink(trimmed2);
105020
106263
  if (link3?.remId)
@@ -105093,7 +106336,7 @@ var writeTableCreateCommand = exports_Command.make("create", {
105093
106336
  const cfg = yield* AppConfig;
105094
106337
  const refs = yield* RefResolver;
105095
106338
  const payloadSvc = yield* Payload;
105096
- const tableTagId = normalizeRemIdInput7(tableTag);
106339
+ const tableTagId = normalizeRemIdInput2(tableTag);
105097
106340
  if (!tableTagId) {
105098
106341
  return yield* fail8(new CliError({
105099
106342
  code: "INVALID_ARGS",
@@ -105102,7 +106345,7 @@ var writeTableCreateCommand = exports_Command.make("create", {
105102
106345
  }));
105103
106346
  }
105104
106347
  const resolvedRef = ref5 ?? "";
105105
- const parentId2 = typeof parent === "string" ? normalizeRemIdInput7(parent) : dryRun ? resolvedRef : yield* refs.resolve(resolvedRef);
106348
+ const parentId2 = typeof parent === "string" ? normalizeRemIdInput2(parent) : dryRun ? resolvedRef : yield* refs.resolve(resolvedRef);
105106
106349
  const tableClientTempId = clientTempId ? String(clientTempId).trim() : makeTempId();
105107
106350
  const op2 = yield* try_3({
105108
106351
  try: () => normalizeOp({
@@ -106796,30 +108039,10 @@ var readTopicCommand = exports_Command.make("topic", {}).pipe(exports_Command.wi
106796
108039
  var topicCommand = readTopicCommand;
106797
108040
 
106798
108041
  // src/commands/write/portal/create.ts
106799
- function normalizeRemIdInput8(raw4) {
106800
- const trimmed2 = raw4.trim();
106801
- const link3 = tryParseRemnoteLink(trimmed2);
106802
- if (link3?.remId)
106803
- return link3.remId;
106804
- return trimmed2;
106805
- }
106806
- function looksLikeRef(raw4) {
106807
- const s = raw4.trim();
106808
- if (!s)
106809
- return false;
106810
- if (s.startsWith("remnote://") || s.startsWith("http://") || s.startsWith("https://"))
106811
- return true;
106812
- const idx = s.indexOf(":");
106813
- if (idx <= 0)
106814
- return false;
106815
- const prefix2 = s.slice(0, idx).trim().toLowerCase();
106816
- return prefix2 === "id" || prefix2 === "page" || prefix2 === "title" || prefix2 === "daily";
106817
- }
106818
108042
  var writePortalCreateCommand = exports_Command.make("create", {
106819
- parent: text9("parent"),
106820
- target: text9("target"),
106821
- position: integer7("position").pipe(optional5, map34(optionToUndefined43)),
106822
- clientTempId: text9("client-temp-id").pipe(optional5, map34(optionToUndefined43)),
108043
+ to: text9("to").pipe(withDescription5("Target Rem that the portal should point to.")),
108044
+ at: text9("at").pipe(withDescription5("Examples: parent:id:P1, parent[2]:id:P1, before:id:R1, after:id:R1. standalone is invalid for portal placement.")),
108045
+ clientTempId: readOptionalText3("client-temp-id"),
106823
108046
  notify: writeCommonOptions.notify,
106824
108047
  ensureDaemon: writeCommonOptions.ensureDaemon,
106825
108048
  wait: writeCommonOptions.wait,
@@ -106830,22 +108053,7 @@ var writePortalCreateCommand = exports_Command.make("create", {
106830
108053
  clientId: writeCommonOptions.clientId,
106831
108054
  idempotencyKey: writeCommonOptions.idempotencyKey,
106832
108055
  meta: writeCommonOptions.meta
106833
- }, ({
106834
- parent,
106835
- target: target2,
106836
- position: position3,
106837
- clientTempId,
106838
- notify: notify5,
106839
- ensureDaemon: ensureDaemon7,
106840
- wait: wait5,
106841
- timeoutMs: timeoutMs7,
106842
- pollMs: pollMs5,
106843
- dryRun,
106844
- priority: priority5,
106845
- clientId: clientId5,
106846
- idempotencyKey: idempotencyKey5,
106847
- meta
106848
- }) => gen2(function* () {
108056
+ }, ({ to, at, clientTempId, notify: notify5, ensureDaemon: ensureDaemon7, wait: wait5, timeoutMs: timeoutMs7, pollMs: pollMs5, dryRun, priority: priority5, clientId: clientId5, idempotencyKey: idempotencyKey5, meta }) => gen2(function* () {
106849
108057
  if (!wait5 && (timeoutMs7 !== undefined || pollMs5 !== undefined)) {
106850
108058
  return yield* fail8(new CliError({
106851
108059
  code: "INVALID_ARGS",
@@ -106860,43 +108068,19 @@ var writePortalCreateCommand = exports_Command.make("create", {
106860
108068
  exitCode: 2
106861
108069
  }));
106862
108070
  }
106863
- if (position3 !== undefined && (!Number.isFinite(position3) || position3 < 0)) {
106864
- return yield* fail8(new CliError({
106865
- code: "INVALID_ARGS",
106866
- message: "--position must be a non-negative integer",
106867
- exitCode: 2,
106868
- details: { position: position3 }
106869
- }));
106870
- }
108071
+ const placementSpec = yield* parsePlacementSpec(at, { optionName: "--at", allowStandalone: false });
108072
+ const resolvedPlacement = yield* resolveTreePlacementSpec(placementSpec, { optionName: "--at" });
108073
+ const targetRemId = yield* resolveRefValue(to);
106871
108074
  const cfg = yield* AppConfig;
106872
- const refs = yield* RefResolver;
106873
108075
  const payloadSvc = yield* Payload;
106874
- const parentIdInput = parent;
106875
- const targetIdInput = target2;
106876
- const parentId2 = looksLikeRef(parentIdInput) && !dryRun ? yield* refs.resolve(parentIdInput) : normalizeRemIdInput8(parentIdInput);
106877
- const targetRemId = looksLikeRef(targetIdInput) && !dryRun ? yield* refs.resolve(targetIdInput) : normalizeRemIdInput8(targetIdInput);
106878
- if (!parentId2) {
106879
- return yield* fail8(new CliError({
106880
- code: "INVALID_ARGS",
106881
- message: "Missing --parent",
106882
- exitCode: 2
106883
- }));
106884
- }
106885
- if (!targetRemId) {
106886
- return yield* fail8(new CliError({
106887
- code: "INVALID_ARGS",
106888
- message: "Missing --target",
106889
- exitCode: 2
106890
- }));
106891
- }
106892
- const portalClientTempId = clientTempId ? String(clientTempId).trim() : makeTempId();
108076
+ const portalClientTempId = clientTempId?.trim() || makeTempId();
106893
108077
  const op2 = yield* try_3({
106894
108078
  try: () => normalizeOp({
106895
108079
  type: "create_portal",
106896
108080
  payload: {
106897
- parentId: parentId2,
108081
+ parentId: resolvedPlacement.parentId,
106898
108082
  targetRemId,
106899
- ...position3 !== undefined ? { position: position3 } : {},
108083
+ ...resolvedPlacement.position !== undefined ? { position: resolvedPlacement.position } : {},
106900
108084
  clientTempId: portalClientTempId
106901
108085
  }
106902
108086
  }, payloadSvc.normalizeKeys),
@@ -106958,7 +108142,7 @@ var writePortalCreateCommand = exports_Command.make("create", {
106958
108142
  ].join(`
106959
108143
  `)
106960
108144
  });
106961
- }).pipe(catchAll2(writeFailure)));
108145
+ }).pipe(catchAll2(writeFailure))).pipe(exports_Command.withDescription("Create one portal relation by pointing at a target Rem and inserting the portal into the tree."));
106962
108146
 
106963
108147
  // src/commands/write/portal/index.ts
106964
108148
  var writePortalCommand = exports_Command.make("portal", {}).pipe(exports_Command.withSubcommands([writePortalCreateCommand]));
@@ -107024,7 +108208,7 @@ var stackEnsureCommand = exports_Command.make("ensure", {
107024
108208
  }).pipe(catchAll2(writeFailure)));
107025
108209
 
107026
108210
  // src/commands/stack/status.ts
107027
- import path29 from "node:path";
108211
+ import path31 from "node:path";
107028
108212
  var stackStatusCommand = exports_Command.make("status", {}, () => gen2(function* () {
107029
108213
  const cfg = yield* AppConfig;
107030
108214
  const daemonFiles = yield* DaemonFiles;
@@ -107045,11 +108229,14 @@ var stackStatusCommand = exports_Command.make("status", {}, () => gen2(function*
107045
108229
  const apiBaseUrl = apiLocalBaseUrl(apiPidInfo?.port ?? cfg.apiPort ?? 3000, apiBasePath);
107046
108230
  const apiStatus = yield* api.status({ baseUrl: apiBaseUrl, timeoutMs: 2000 }).pipe(either3);
107047
108231
  const queueStats2 = yield* queue.stats({ dbPath: cfg.storeDb }).pipe(either3);
107048
- const stateFilePath = resolveUserFilePath(daemonPidInfo?.state_file ?? path29.join(path29.dirname(daemonPidFile), "ws.state.json"));
108232
+ const stateFilePath = resolveUserFilePath(daemonPidInfo?.state_file ?? path31.join(path31.dirname(daemonPidFile), "ws.state.json"));
108233
+ const activeWorkerRuntime = clients._tag === "Right" && typeof clients.right.activeWorkerConnId === "string" ? clients.right.clients.find((client) => client.connId === clients.right.activeWorkerConnId)?.runtime ?? null : null;
107049
108234
  const data = {
108235
+ runtime: currentRuntimeBuildInfo(),
107050
108236
  daemon: {
107051
108237
  running: daemonRunning,
107052
108238
  pid: daemonPidInfo?.pid ?? null,
108239
+ build: daemonPidInfo?.build ?? null,
107053
108240
  pid_file: daemonPidFile,
107054
108241
  ws_url: cfg.wsUrl,
107055
108242
  healthy: wsHealth._tag === "Right",
@@ -107058,6 +108245,7 @@ var stackStatusCommand = exports_Command.make("status", {}, () => gen2(function*
107058
108245
  api: {
107059
108246
  running: apiRunning,
107060
108247
  pid: apiPidInfo?.pid ?? null,
108248
+ build: apiPidInfo?.build ?? null,
107061
108249
  pid_file: apiPidFile,
107062
108250
  base_url: apiBaseUrl,
107063
108251
  base_path: apiBasePath,
@@ -107065,7 +108253,19 @@ var stackStatusCommand = exports_Command.make("status", {}, () => gen2(function*
107065
108253
  status: apiStatus._tag === "Right" ? apiStatus.right : null
107066
108254
  },
107067
108255
  active_worker_conn_id: clients._tag === "Right" ? clients.right.activeWorkerConnId ?? null : null,
107068
- queue: queueStats2._tag === "Right" ? queueStats2.right : null
108256
+ active_worker: clients._tag === "Right" && typeof clients.right.activeWorkerConnId === "string" ? clients.right.clients.find((client) => client.connId === clients.right.activeWorkerConnId) ?? null : null,
108257
+ queue: queueStats2._tag === "Right" ? queueStats2.right : null,
108258
+ warnings: [
108259
+ ...runtimeVersionWarnings({
108260
+ current: currentRuntimeBuildInfo(),
108261
+ daemon: daemonPidInfo?.build ?? null,
108262
+ api: apiPidInfo?.build ?? null
108263
+ }),
108264
+ ...pluginBuildWarnings({
108265
+ expected: currentExpectedPluginBuildInfo(),
108266
+ live: activeWorkerRuntime
108267
+ })
108268
+ ]
107069
108269
  };
107070
108270
  const md = [
107071
108271
  `- daemon_running: ${data.daemon.running}`,
@@ -107091,7 +108291,7 @@ var stackStatusCommand = exports_Command.make("status", {}, () => gen2(function*
107091
108291
  }).pipe(catchAll2(writeFailure)));
107092
108292
 
107093
108293
  // src/commands/stack/stop.ts
107094
- import path30 from "node:path";
108294
+ import path32 from "node:path";
107095
108295
  var stackStopCommand = exports_Command.make("stop", {}, () => gen2(function* () {
107096
108296
  const apiFiles = yield* ApiDaemonFiles;
107097
108297
  const daemonFiles = yield* DaemonFiles;
@@ -107128,7 +108328,7 @@ var stackStopCommand = exports_Command.make("stop", {}, () => gen2(function* ()
107128
108328
  }
107129
108329
  }
107130
108330
  yield* daemonFiles.deletePidFile(daemonPidFile).pipe(catchAll2(() => _void));
107131
- yield* supervisorState.deleteStateFile(resolveUserFilePath(daemonPidInfo?.state_file ?? path30.join(path30.dirname(daemonPidFile), "ws.state.json"))).pipe(catchAll2(() => _void));
108331
+ yield* supervisorState.deleteStateFile(resolveUserFilePath(daemonPidInfo?.state_file ?? path32.join(path32.dirname(daemonPidFile), "ws.state.json"))).pipe(catchAll2(() => _void));
107132
108332
  yield* writeSuccess({
107133
108333
  data: { stopped: true, api_stopped: apiStopped, daemon_stopped: daemonStopped },
107134
108334
  md: `- stopped: true
@@ -107305,7 +108505,7 @@ function buildCliEnvConfigProvider(params3) {
107305
108505
  // src/main.ts
107306
108506
  function packageVersion() {
107307
108507
  try {
107308
- const raw4 = readFileSync2(new URL("../package.json", import.meta.url), "utf8");
108508
+ const raw4 = readFileSync4(new URL("../package.json", import.meta.url), "utf8");
107309
108509
  const parsed = JSON.parse(raw4);
107310
108510
  if (typeof parsed?.version === "string" && parsed.version.length > 0)
107311
108511
  return parsed.version;
@@ -107315,6 +108515,17 @@ function packageVersion() {
107315
108515
  var version = packageVersion();
107316
108516
  if (!process.env.AGENT_REMNOTE_VERSION)
107317
108517
  process.env.AGENT_REMNOTE_VERSION = version;
108518
+ var buildInfo = currentRuntimeBuildInfo();
108519
+ if (!process.env.AGENT_REMNOTE_NAME)
108520
+ process.env.AGENT_REMNOTE_NAME = buildInfo.name;
108521
+ if (!process.env.AGENT_REMNOTE_BUILD_ID)
108522
+ process.env.AGENT_REMNOTE_BUILD_ID = buildInfo.build_id;
108523
+ if (!process.env.AGENT_REMNOTE_BUILD_AT)
108524
+ process.env.AGENT_REMNOTE_BUILD_AT = String(buildInfo.built_at);
108525
+ if (!process.env.AGENT_REMNOTE_SOURCE_STAMP)
108526
+ process.env.AGENT_REMNOTE_SOURCE_STAMP = String(buildInfo.source_stamp);
108527
+ if (!process.env.AGENT_REMNOTE_BUILD_MODE)
108528
+ process.env.AGENT_REMNOTE_BUILD_MODE = buildInfo.mode;
107318
108529
  var cli = exports_Command.run(rootCommand, {
107319
108530
  name: "agent-remnote",
107320
108531
  version