@remnic/plugin-openclaw 9.54.0 → 9.54.2

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/index.js CHANGED
@@ -5533,7 +5533,7 @@ function parseEnvironmentFile(body) {
5533
5533
  }
5534
5534
  return parsed;
5535
5535
  }
5536
- function readUnitEnvironment(unit, scope, readFile4, listDir) {
5536
+ function readUnitEnvironment(unit, scope, readFile3, listDir) {
5537
5537
  const directives = readEffectiveDirectives(unit);
5538
5538
  const merged = new Map(directives.env);
5539
5539
  for (const candidate of directives.envFiles) {
@@ -5542,7 +5542,7 @@ function readUnitEnvironment(unit, scope, readFile4, listDir) {
5542
5542
  const resolved = settleUnitValue(expandedFile);
5543
5543
  if (!path3.isAbsolute(resolved)) continue;
5544
5544
  for (const match of expandEnvironmentFilePattern(resolved, listDir)) {
5545
- const body = readFile4(match);
5545
+ const body = readFile3(match);
5546
5546
  if (body === void 0) continue;
5547
5547
  for (const [key, value] of parseEnvironmentFile(body)) merged.set(key, value);
5548
5548
  }
@@ -5582,8 +5582,8 @@ function defaultUnitFileReader(candidate) {
5582
5582
  return void 0;
5583
5583
  }
5584
5584
  }
5585
- function readUnitEnv(unit, name, scope, readFile4 = defaultUnitFileReader, listDir = defaultUnitDirLister) {
5586
- const systemdValue = readUnitEnvironment(unit, scope, readFile4, listDir).get(name);
5585
+ function readUnitEnv(unit, name, scope, readFile3 = defaultUnitFileReader, listDir = defaultUnitDirLister) {
5586
+ const systemdValue = readUnitEnvironment(unit, scope, readFile3, listDir).get(name);
5587
5587
  const systemd = systemdValue === void 0 ? null : [void 0, systemdValue];
5588
5588
  const launchdRaw = new RegExp(`<key>${name}</key>\\s*<string>([^<]*)</string>`).exec(unit);
5589
5589
  const launchd = launchdRaw === null ? null : [void 0, decodePlistString(launchdRaw[1] ?? "")];
@@ -5641,9 +5641,9 @@ function readUnitWorkingDirectory(unit) {
5641
5641
  if (raw === void 0 || raw === "") return void 0;
5642
5642
  return /^(["']).*\1$/.test(raw) ? raw.slice(1, -1) : raw;
5643
5643
  }
5644
- function readUnitCliOverrides(unit, scope, readFile4, listDir) {
5644
+ function readUnitCliOverrides(unit, scope, readFile3, listDir) {
5645
5645
  const tokens = [];
5646
- const environment = readUnitEnvironment(unit, scope, readFile4, listDir);
5646
+ const environment = readUnitEnvironment(unit, scope, readFile3, listDir);
5647
5647
  const substituteBraced = (token) => token.replace(
5648
5648
  /\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g,
5649
5649
  (match, name) => environment.get(name) ?? match
@@ -5706,12 +5706,12 @@ function readUnitCliOverrides(unit, scope, readFile4, listDir) {
5706
5706
  ...authToken === void 0 ? {} : { authToken }
5707
5707
  };
5708
5708
  }
5709
- function resolveUnitEndpoint(unit, scope, readFile4 = defaultUnitFileReader, listDir = defaultUnitDirLister) {
5710
- const cli = readUnitCliOverrides(unit, scope, readFile4, listDir);
5709
+ function resolveUnitEndpoint(unit, scope, readFile3 = defaultUnitFileReader, listDir = defaultUnitDirLister) {
5710
+ const cli = readUnitCliOverrides(unit, scope, readFile3, listDir);
5711
5711
  const envOverride = (primary, legacy) => {
5712
- const value = readUnitEnv(unit, primary, scope, readFile4, listDir);
5712
+ const value = readUnitEnv(unit, primary, scope, readFile3, listDir);
5713
5713
  if (value !== void 0) return value === "" ? void 0 : value;
5714
- const legacyValue = readUnitEnv(unit, legacy, scope, readFile4, listDir);
5714
+ const legacyValue = readUnitEnv(unit, legacy, scope, readFile3, listDir);
5715
5715
  return legacyValue === "" ? void 0 : legacyValue;
5716
5716
  };
5717
5717
  const host = cli.host ?? envOverride("REMNIC_HOST", "ENGRAM_HOST");
@@ -5719,17 +5719,17 @@ function resolveUnitEndpoint(unit, scope, readFile4 = defaultUnitFileReader, lis
5719
5719
  const authToken = cli.authToken ?? envOverride("REMNIC_AUTH_TOKEN", "ENGRAM_AUTH_TOKEN");
5720
5720
  const configFromCli = cli.configPath === void 0 ? {} : { configPath: cli.configPath };
5721
5721
  return {
5722
- ...resolveUnitConfigPathInner(unit, scope, readFile4, listDir),
5722
+ ...resolveUnitConfigPathInner(unit, scope, readFile3, listDir),
5723
5723
  ...configFromCli,
5724
5724
  ...host === void 0 ? {} : { host },
5725
5725
  ...port === void 0 ? {} : { port },
5726
5726
  ...authToken === void 0 ? {} : { authToken }
5727
5727
  };
5728
5728
  }
5729
- function resolveUnitConfigPathInner(unit, scope, readFile4, listDir) {
5729
+ function resolveUnitConfigPathInner(unit, scope, readFile3, listDir) {
5730
5730
  const workingDirectory = readUnitWorkingDirectory(unit);
5731
5731
  for (const name of ["REMNIC_CONFIG_PATH", "ENGRAM_CONFIG_PATH"]) {
5732
- const raw = readUnitEnv(unit, name, scope, readFile4, listDir);
5732
+ const raw = readUnitEnv(unit, name, scope, readFile3, listDir);
5733
5733
  if (raw === "") return {};
5734
5734
  if (raw === void 0) continue;
5735
5735
  const resolved = resolveAgainstWorkingDirectory(raw, workingDirectory, scope);
@@ -5739,7 +5739,7 @@ function resolveUnitConfigPathInner(unit, scope, readFile4, listDir) {
5739
5739
  if (workingDirectory !== void 0) {
5740
5740
  for (const name of ["remnic.config.json", "engram.config.json"]) {
5741
5741
  const candidate = resolveAgainstWorkingDirectory(name, workingDirectory, scope);
5742
- if (candidate !== void 0 && readFile4(candidate) !== void 0) {
5742
+ if (candidate !== void 0 && readFile3(candidate) !== void 0) {
5743
5743
  return { configPath: candidate };
5744
5744
  }
5745
5745
  }
@@ -6783,9 +6783,11 @@ function daemonTargetFor(bridge) {
6783
6783
  }
6784
6784
 
6785
6785
  // src/delegate-flush-plan-ingest.ts
6786
- import { lstat as lstat3, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
6786
+ import { constants } from "fs";
6787
+ import { lstat as lstat3, open, rename as rename2, unlink as unlink2, writeFile as writeFile2 } from "fs/promises";
6787
6788
  import path7 from "path";
6788
6789
  import { log as log4 } from "@remnic/core/logger";
6790
+ import { withHeldFileLock } from "@remnic/core/utils/serialize-mutations";
6789
6791
 
6790
6792
  // src/memory-flush-plan.ts
6791
6793
  var DEFAULT_MAX_TURN_CHARS = 8e3;
@@ -6806,71 +6808,300 @@ function buildMemoryFlushPlan(options) {
6806
6808
  };
6807
6809
  }
6808
6810
 
6811
+ // src/delegate-http.ts
6812
+ async function readJsonObject(res) {
6813
+ const parsed = await res.json().catch(() => null);
6814
+ return typeof parsed === "object" && parsed !== null ? parsed : null;
6815
+ }
6816
+ async function noteRefusal(res, serviceId, pathname, source) {
6817
+ await res.body?.cancel();
6818
+ if (res.status === 401 || res.status === 403) {
6819
+ reportDaemonAuthorizationFailure(serviceId, pathname, res.status, source);
6820
+ }
6821
+ return { status: res.status, body: null };
6822
+ }
6823
+ async function postJsonWithStatus(target, serviceId, pathname, body, timeoutMs) {
6824
+ const headers = { "Content-Type": "application/json" };
6825
+ const auth = target.resolveAuthToken();
6826
+ if (auth.token) headers.Authorization = `Bearer ${auth.token}`;
6827
+ const res = await fetch(daemonUrl(target, pathname), {
6828
+ method: "POST",
6829
+ headers,
6830
+ body: JSON.stringify(body),
6831
+ signal: AbortSignal.timeout(timeoutMs)
6832
+ });
6833
+ if (!res.ok) return noteRefusal(res, serviceId, pathname, auth.source);
6834
+ return { status: res.status, body: await readJsonObject(res) };
6835
+ }
6836
+ async function postJson(target, serviceId, pathname, body, timeoutMs) {
6837
+ const response = await postJsonWithStatus(target, serviceId, pathname, body, timeoutMs);
6838
+ if (response.status === 401 || response.status === 403) return null;
6839
+ if (response.status < 200 || response.status > 299) {
6840
+ throw new Error(`daemon ${pathname} responded ${response.status}`);
6841
+ }
6842
+ return response.body;
6843
+ }
6844
+ async function getJson(target, serviceId, pathname, timeoutMs) {
6845
+ const headers = {};
6846
+ const auth = target.resolveAuthToken();
6847
+ if (auth.token) headers.Authorization = `Bearer ${auth.token}`;
6848
+ const res = await fetch(daemonUrl(target, pathname), {
6849
+ headers,
6850
+ signal: AbortSignal.timeout(timeoutMs)
6851
+ });
6852
+ if (!res.ok) return noteRefusal(res, serviceId, pathname, auth.source);
6853
+ return { status: res.status, body: await readJsonObject(res) };
6854
+ }
6855
+
6809
6856
  // src/delegate-flush-plan-ingest.ts
6810
6857
  var MAX_OBSERVE_CHUNK_BYTES = 96 * 1024;
6811
6858
  var MIN_OBSERVE_CHUNK_BYTES = 4 * 1024;
6859
+ var LOCK_MAX_WAIT_MS = 5e3;
6860
+ var LOCK_STALE_MS = 6e4;
6861
+ var MAX_RECLAIM_PASSES = 4;
6812
6862
  async function ingestFlushPlanNotes(options) {
6813
6863
  if (options.workspaceDir === void 0) return;
6864
+ const workspaceDir = options.workspaceDir;
6814
6865
  const planPath = path7.join(
6815
- options.workspaceDir,
6866
+ workspaceDir,
6816
6867
  ...buildMemoryFlushPlan({ serviceId: options.serviceId }).relativePath.split("/")
6817
6868
  );
6818
- if (!await isLinkFreeUnder(options.workspaceDir, planPath)) {
6869
+ const paths = {
6870
+ plan: planPath,
6871
+ inflight: `${planPath}.inflight`,
6872
+ rotating: `${planPath}.rotating`,
6873
+ oversized: `${planPath}.oversized`,
6874
+ lock: `${planPath}.lock`
6875
+ };
6876
+ for (const candidate of [paths.plan, paths.inflight, paths.rotating, paths.oversized]) {
6877
+ if (await isLinkFreeUnder(workspaceDir, candidate)) continue;
6819
6878
  log4.warn(
6820
- `[${options.serviceId}] flush-plan ingestion skipped: ${planPath}, a parent, or the workspace root is a symlink`
6879
+ `[${options.serviceId}] flush-plan ingestion skipped: ${candidate}, a parent, or the workspace root is a symlink`
6821
6880
  );
6822
6881
  return;
6823
6882
  }
6824
- let pending = await readPlan(planPath);
6825
- if (pending === void 0 || pending.trim().length === 0) return;
6883
+ const lockWaitMs = Math.max(1, Math.min(LOCK_MAX_WAIT_MS, Math.floor(options.remainingTimeoutMs() / 2)));
6884
+ await withHeldFileLock(
6885
+ paths.lock,
6886
+ { staleMs: LOCK_STALE_MS, maxWaitMs: lockWaitMs },
6887
+ async (acquired, lock) => {
6888
+ if (!acquired) {
6889
+ log4.warn(
6890
+ `[${options.serviceId}] flush-plan ingestion skipped: another flush holds the lock; the notes drain on the next flush`
6891
+ );
6892
+ return;
6893
+ }
6894
+ for (const candidate of [paths.plan, paths.inflight, paths.rotating, paths.oversized]) {
6895
+ if (await isLinkFreeUnder(workspaceDir, candidate)) continue;
6896
+ log4.warn(
6897
+ `[${options.serviceId}] flush-plan ingestion skipped: ${candidate}, a parent, or the workspace root became a symlink`
6898
+ );
6899
+ return;
6900
+ }
6901
+ await ingestUnderLock(options, paths, lock);
6902
+ }
6903
+ );
6904
+ }
6905
+ async function ingestUnderLock(options, paths, lock) {
6826
6906
  let chunkBytes = MAX_OBSERVE_CHUNK_BYTES;
6827
- while (pending.trim().length > 0) {
6828
- const timeoutMs = options.remainingTimeoutMs();
6829
- if (timeoutMs <= 0) {
6907
+ for (let pass = 0; pass < MAX_RECLAIM_PASSES; pass++) {
6908
+ if (options.remainingTimeoutMs() <= 0) return;
6909
+ const claimed = await claimPendingNotes(paths, options.serviceId, lock);
6910
+ if (claimed === void 0) {
6830
6911
  log4.warn(
6831
- `[${options.serviceId}] flush-plan ingestion stopped: the caller's deadline is spent; the remainder drains on the next flush`
6912
+ `[${options.serviceId}] flush-plan lock was lost during recovery; its new owner drains the snapshot`
6832
6913
  );
6833
6914
  return;
6834
6915
  }
6835
- const [chunk] = chunkOnLineBoundaries(pending, chunkBytes);
6836
- if (chunk === void 0) return;
6837
- const accepted = await postJson(
6838
- options.target,
6839
- options.serviceId,
6840
- "/engram/v1/observe",
6841
- {
6842
- sessionKey: options.sessionKey,
6843
- messages: [{ role: "user", content: chunk }],
6844
- ...options.namespace === void 0 ? {} : { namespace: options.namespace }
6845
- },
6846
- timeoutMs
6847
- );
6848
- if (accepted === null) {
6849
- if (chunkBytes > MIN_OBSERVE_CHUNK_BYTES && chunkOnLineBoundaries(pending, chunkBytes).length > 1) {
6850
- chunkBytes = Math.max(MIN_OBSERVE_CHUNK_BYTES, Math.floor(chunkBytes / 2));
6851
- continue;
6916
+ if (claimed.trim().length === 0) {
6917
+ if (await lock.refresh()) await discard(paths.inflight);
6918
+ return;
6919
+ }
6920
+ let pending = claimed;
6921
+ let stop = false;
6922
+ let lockLost = false;
6923
+ try {
6924
+ while (pending.trim().length > 0) {
6925
+ const timeoutMs = options.remainingTimeoutMs();
6926
+ if (timeoutMs <= 0) {
6927
+ log4.warn(
6928
+ `[${options.serviceId}] flush-plan ingestion stopped: the caller's deadline is spent; the remainder drains on the next flush`
6929
+ );
6930
+ stop = true;
6931
+ return;
6932
+ }
6933
+ const [chunk] = chunkOnLineBoundaries(pending, chunkBytes);
6934
+ if (chunk === void 0) {
6935
+ stop = true;
6936
+ return;
6937
+ }
6938
+ const response = await postJsonWithStatus(
6939
+ options.target,
6940
+ options.serviceId,
6941
+ "/engram/v1/observe",
6942
+ {
6943
+ sessionKey: options.sessionKey,
6944
+ messages: [{ role: "user", content: chunk }],
6945
+ ...options.namespace === void 0 ? {} : { namespace: options.namespace }
6946
+ },
6947
+ timeoutMs
6948
+ );
6949
+ if (isRefusal(response.status)) {
6950
+ log4.warn(
6951
+ `[${options.serviceId}] flush-plan notes were refused by the daemon (${response.status}); keeping them for the next flush`
6952
+ );
6953
+ stop = true;
6954
+ return;
6955
+ }
6956
+ if (response.status === 413) {
6957
+ if (countLines(chunk) > 1) {
6958
+ chunkBytes = Math.max(1, Math.floor(chunkBytes / 2));
6959
+ continue;
6960
+ }
6961
+ pending = await quarantineOversizedLine(paths, pending, options.serviceId);
6962
+ chunkBytes = MAX_OBSERVE_CHUNK_BYTES;
6963
+ if (!await lock.refresh()) {
6964
+ log4.warn(
6965
+ `[${options.serviceId}] flush-plan lock was lost mid-flush; the snapshot is left to its new owner`
6966
+ );
6967
+ lockLost = true;
6968
+ stop = true;
6969
+ return;
6970
+ }
6971
+ await atomicWrite(paths.inflight, pending);
6972
+ continue;
6973
+ }
6974
+ if (response.status < 200 || response.status > 299) {
6975
+ stop = true;
6976
+ throw new Error(`daemon /engram/v1/observe responded ${response.status}`);
6977
+ }
6978
+ pending = pending.slice(chunk.length);
6979
+ if (!await lock.refresh()) {
6980
+ log4.warn(
6981
+ `[${options.serviceId}] flush-plan lock was lost mid-flush; the snapshot is left to its new owner`
6982
+ );
6983
+ lockLost = true;
6984
+ stop = true;
6985
+ return;
6986
+ }
6987
+ await atomicWrite(paths.inflight, pending);
6852
6988
  }
6853
- log4.warn(
6854
- `[${options.serviceId}] flush-plan notes were rejected by the daemon; keeping the remainder for the next flush`
6855
- );
6989
+ } finally {
6990
+ if (!lockLost && await lock.refresh()) {
6991
+ await releasePendingNotes(paths, pending, options.serviceId);
6992
+ } else if (!lockLost) {
6993
+ log4.warn(
6994
+ `[${options.serviceId}] flush-plan lock was lost before the snapshot could be updated; its new owner drains the remainder`
6995
+ );
6996
+ }
6997
+ }
6998
+ if (stop) return;
6999
+ }
7000
+ }
7001
+ function countLines(chunk) {
7002
+ const body = chunk.endsWith("\n") ? chunk.slice(0, -1) : chunk;
7003
+ if (body.length === 0) return chunk.length > 0 ? 1 : 0;
7004
+ return body.split("\n").length;
7005
+ }
7006
+ function isRefusal(status) {
7007
+ return status === 401 || status === 403 || status === 431;
7008
+ }
7009
+ async function claimPendingNotes(paths, serviceId, lock) {
7010
+ const recovery = await mergeRotatedIntoInflight(paths, lock);
7011
+ if (recovery === "lock-lost") return void 0;
7012
+ if (recovery === "recovered") {
7013
+ log4.warn(`[${serviceId}] recovered flush-plan notes left by an interrupted ingestion`);
7014
+ }
7015
+ if (!await lock.refresh()) return void 0;
7016
+ try {
7017
+ await rename2(paths.plan, paths.rotating);
7018
+ } catch (err) {
7019
+ if (err?.code !== "ENOENT") throw err;
7020
+ return await readIfPresent(paths.inflight) ?? "";
7021
+ }
7022
+ if (await mergeRotatedIntoInflight(paths, lock) === "lock-lost") return void 0;
7023
+ return await readIfPresent(paths.inflight) ?? "";
7024
+ }
7025
+ async function mergeRotatedIntoInflight(paths, lock) {
7026
+ const rotated = await readIfPresent(paths.rotating);
7027
+ if (rotated === void 0) return "nothing";
7028
+ const existing = await readIfPresent(paths.inflight) ?? "";
7029
+ let merged = `${existing}${rotated}`;
7030
+ if (merged.length > 0) {
7031
+ if (!await lock.refresh()) return "lock-lost";
7032
+ await atomicWrite(paths.inflight, merged);
7033
+ }
7034
+ const late = await readIfPresent(paths.rotating);
7035
+ if (late !== void 0 && late.length > rotated.length) {
7036
+ if (!await lock.refresh()) return "lock-lost";
7037
+ merged = `${existing}${late}`;
7038
+ await atomicWrite(paths.inflight, merged);
7039
+ }
7040
+ if (!await lock.refresh()) return "lock-lost";
7041
+ await discard(paths.rotating);
7042
+ return merged.length > 0 ? "recovered" : "nothing";
7043
+ }
7044
+ async function releasePendingNotes(paths, pending, serviceId) {
7045
+ try {
7046
+ if (pending.length === 0) {
7047
+ await discard(paths.inflight);
6856
7048
  return;
6857
7049
  }
6858
- pending = await commitAcceptedPrefix(planPath, chunk) ?? "";
7050
+ await atomicWrite(paths.inflight, pending);
7051
+ } catch (err) {
7052
+ log4.warn(
7053
+ `[${serviceId}] could not persist unsent flush-plan notes; the next ingestion recovers them: ${String(err)}`
7054
+ );
6859
7055
  }
6860
7056
  }
6861
- async function readPlan(planPath) {
7057
+ async function quarantineOversizedLine(paths, pending, serviceId) {
7058
+ const breakAt = pending.indexOf("\n");
7059
+ const line = breakAt === -1 ? pending : pending.slice(0, breakAt + 1);
7060
+ const rest = breakAt === -1 ? "" : pending.slice(breakAt + 1);
7061
+ const handle = await open(
7062
+ paths.oversized,
7063
+ constants.O_WRONLY | constants.O_CREAT | constants.O_APPEND | constants.O_NOFOLLOW,
7064
+ 384
7065
+ );
6862
7066
  try {
6863
- return await readFile2(planPath, "utf8");
6864
- } catch {
6865
- return void 0;
7067
+ await handle.writeFile(line.endsWith("\n") ? line : `${line}
7068
+ `, "utf8");
7069
+ } finally {
7070
+ await handle.close();
7071
+ }
7072
+ log4.warn(
7073
+ `[${serviceId}] a flush-plan note exceeds the daemon's body limit; moved it to ${paths.oversized} so the remaining notes can drain`
7074
+ );
7075
+ return rest;
7076
+ }
7077
+ async function readIfPresent(filePath) {
7078
+ let handle;
7079
+ try {
7080
+ handle = await open(filePath, constants.O_RDONLY | constants.O_NOFOLLOW);
7081
+ return await handle.readFile("utf8");
7082
+ } catch (err) {
7083
+ if (err?.code === "ENOENT") return void 0;
7084
+ throw err;
7085
+ } finally {
7086
+ await handle?.close();
7087
+ }
7088
+ }
7089
+ async function atomicWrite(filePath, content) {
7090
+ const tempPath = `${filePath}.tmp-${process.pid}-${Math.random().toString(36).slice(2, 10)}`;
7091
+ try {
7092
+ await writeFile2(tempPath, content, { encoding: "utf8", flag: "wx", mode: 384 });
7093
+ await rename2(tempPath, filePath);
7094
+ } catch (err) {
7095
+ await discard(tempPath);
7096
+ throw err;
6866
7097
  }
6867
7098
  }
6868
- async function commitAcceptedPrefix(planPath, accepted) {
6869
- const current = await readPlan(planPath);
6870
- if (current === void 0) return void 0;
6871
- const remainder = current.startsWith(accepted) ? current.slice(accepted.length) : current;
6872
- await writeFile2(planPath, remainder, "utf8");
6873
- return current.startsWith(accepted) ? remainder : void 0;
7099
+ async function discard(filePath) {
7100
+ try {
7101
+ await unlink2(filePath);
7102
+ } catch (err) {
7103
+ if (err?.code !== "ENOENT") throw err;
7104
+ }
6874
7105
  }
6875
7106
  function chunkOnLineBoundaries(text, limit) {
6876
7107
  if (Buffer.byteLength(text, "utf8") <= limit) return [text];
@@ -6931,7 +7162,7 @@ function extractTextContent(msg) {
6931
7162
  }
6932
7163
 
6933
7164
  // src/delegate-capability.ts
6934
- import { readFile as readFile3 } from "fs/promises";
7165
+ import { readFile as readFile2 } from "fs/promises";
6935
7166
  import { log as log5 } from "@remnic/core/logger";
6936
7167
  var HEALTH_CACHE_TTL_MS = 3e4;
6937
7168
  var SEARCH_CANDIDATE_CAP = 25e3;
@@ -7266,7 +7497,7 @@ function createDelegateMemoryCapability(options) {
7266
7497
  await requireLocalReadAuthorized("readFile", ["memory_get"]);
7267
7498
  const requestedPath = sharedScope().normalizeWorkspacePath(params.relPath);
7268
7499
  const absolutePath = await sharedScope().resolveReadablePath(params.relPath);
7269
- const allLines = (await readFile3(absolutePath, "utf8")).split(/\r?\n/);
7500
+ const allLines = (await readFile2(absolutePath, "utf8")).split(/\r?\n/);
7270
7501
  if (params.from !== void 0 && (!Number.isInteger(params.from) || params.from < 1)) {
7271
7502
  throw new Error(
7272
7503
  `memory read rejected (from must be a positive integer): ${String(params.from)}`
@@ -7410,52 +7641,6 @@ function registerDelegateMemoryCapability(api, options) {
7410
7641
 
7411
7642
  // src/delegate-runtime.ts
7412
7643
  var DELEGATE_BATCH_FLUSH_CACHE_TTL_MS = 3e4;
7413
- async function postJson(target, serviceId, pathname, body, timeoutMs) {
7414
- const headers = { "Content-Type": "application/json" };
7415
- const auth = target.resolveAuthToken();
7416
- if (auth.token) headers.Authorization = `Bearer ${auth.token}`;
7417
- const res = await fetch(daemonUrl(target, pathname), {
7418
- method: "POST",
7419
- headers,
7420
- body: JSON.stringify(body),
7421
- signal: AbortSignal.timeout(timeoutMs)
7422
- });
7423
- if (!res.ok) {
7424
- if (res.status === 401 || res.status === 403) {
7425
- const status = res.status === 401 ? 401 : 403;
7426
- await res.body?.cancel();
7427
- reportDaemonAuthorizationFailure(serviceId, pathname, status, auth.source);
7428
- return null;
7429
- }
7430
- throw new Error(`daemon ${pathname} responded ${res.status}`);
7431
- }
7432
- const parsed = await res.json().catch(() => null);
7433
- return typeof parsed === "object" && parsed !== null ? parsed : null;
7434
- }
7435
- async function getJson(target, serviceId, pathname, timeoutMs) {
7436
- const headers = {};
7437
- const auth = target.resolveAuthToken();
7438
- if (auth.token) headers.Authorization = `Bearer ${auth.token}`;
7439
- const res = await fetch(daemonUrl(target, pathname), {
7440
- headers,
7441
- signal: AbortSignal.timeout(timeoutMs)
7442
- });
7443
- if (!res.ok) {
7444
- if (res.status === 401 || res.status === 403) {
7445
- const status = res.status === 401 ? 401 : 403;
7446
- await res.body?.cancel();
7447
- reportDaemonAuthorizationFailure(serviceId, pathname, status, auth.source);
7448
- return { status: res.status, body: null };
7449
- }
7450
- await res.body?.cancel();
7451
- return { status: res.status, body: null };
7452
- }
7453
- const parsed = await res.json().catch(() => null);
7454
- return {
7455
- status: res.status,
7456
- body: typeof parsed === "object" && parsed !== null ? parsed : null
7457
- };
7458
- }
7459
7644
  function sessionKeyFrom(event, ctx) {
7460
7645
  const fromCtx = ctx?.sessionKey;
7461
7646
  if (typeof fromCtx === "string" && fromCtx.length > 0) return fromCtx;