@plannotator/opencode 0.28.34 → 0.28.35

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/embedded.js CHANGED
@@ -4333,8 +4333,38 @@ var init_config2 = __esm(() => {
4333
4333
  init_config();
4334
4334
  });
4335
4335
 
4336
+ // ../../packages/core/update-exit-codes.ts
4337
+ var UPDATE_EXIT_CHECKSUM_MISMATCH = 113, UPDATE_EXIT_DOWNLOAD_FAILED = 75;
4338
+
4339
+ // ../../packages/server/update-log.ts
4340
+ import { readFileSync as readFileSync4 } from "fs";
4341
+ function stagingFailureIn(text) {
4342
+ const at = text.lastIndexOf(UPDATE_STAGING_PREFIX);
4343
+ if (at === -1)
4344
+ return null;
4345
+ const line = text.slice(at + UPDATE_STAGING_PREFIX.length).split(`
4346
+ `)[0];
4347
+ return line.replace(/; nothing was changed\s*$/, "").trim() || null;
4348
+ }
4349
+ function lastRunLog(logPath) {
4350
+ let text;
4351
+ try {
4352
+ text = readFileSync4(logPath, "utf-8").slice(-65536);
4353
+ } catch {
4354
+ return "";
4355
+ }
4356
+ const END = "] update: install.sh exited";
4357
+ const last = text.lastIndexOf(END);
4358
+ if (last === -1)
4359
+ return "";
4360
+ const previous = last === 0 ? -1 : text.lastIndexOf(END, last - 1);
4361
+ return text.slice(previous === -1 ? 0 : previous + END.length, last);
4362
+ }
4363
+ var UPDATE_STAGING_PREFIX = "update: could not prepare the update: ";
4364
+ var init_update_log = () => {};
4365
+
4336
4366
  // ../../packages/shared/update-check.ts
4337
- import { appendFileSync, mkdirSync as mkdirSync4, readFileSync as readFileSync4, renameSync as renameSync2, statSync as statSync4, unlinkSync as unlinkSync2, writeFileSync as writeFileSync3 } from "fs";
4367
+ import { appendFileSync, mkdirSync as mkdirSync4, readFileSync as readFileSync5, renameSync as renameSync2, statSync as statSync4, unlinkSync as unlinkSync2, writeFileSync as writeFileSync3 } from "fs";
4338
4368
  import { join as join7 } from "path";
4339
4369
  function parseStableVersion(value) {
4340
4370
  if (typeof value !== "string")
@@ -4374,7 +4404,7 @@ function updateCheckPaths(dataDir = getPlannotatorDataDir()) {
4374
4404
  }
4375
4405
  function readUpdateStateFile(path) {
4376
4406
  try {
4377
- const raw = JSON.parse(readFileSync4(path, "utf-8"));
4407
+ const raw = JSON.parse(readFileSync5(path, "utf-8"));
4378
4408
  return raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
4379
4409
  } catch {
4380
4410
  return {};
@@ -4537,7 +4567,7 @@ function readInstallFlags(dataDir) {
4537
4567
  const path = join7(dataDir ?? getPlannotatorDataDir(), "install-flags.json");
4538
4568
  let text;
4539
4569
  try {
4540
- text = readFileSync4(path, "utf-8");
4570
+ text = readFileSync5(path, "utf-8");
4541
4571
  } catch {
4542
4572
  return { flags: [], problem: "no install-flags.json; running the installer with default flags" };
4543
4573
  }
@@ -4655,7 +4685,7 @@ import { join as join8 } from "path";
4655
4685
  import {
4656
4686
  mkdirSync as mkdirSync5,
4657
4687
  writeFileSync as writeFileSync4,
4658
- readFileSync as readFileSync5,
4688
+ readFileSync as readFileSync6,
4659
4689
  readdirSync as readdirSync3,
4660
4690
  renameSync as renameSync3,
4661
4691
  unlinkSync as unlinkSync3,
@@ -4682,7 +4712,7 @@ function listLiveSessions() {
4682
4712
  if (!entry.endsWith(".json"))
4683
4713
  continue;
4684
4714
  try {
4685
- const data = JSON.parse(readFileSync5(join8(dir, entry), "utf-8"));
4715
+ const data = JSON.parse(readFileSync6(join8(dir, entry), "utf-8"));
4686
4716
  if (typeof data?.pid === "number" && isAlive(data.pid))
4687
4717
  live.push(data);
4688
4718
  } catch {}
@@ -4699,7 +4729,7 @@ import {
4699
4729
  closeSync as closeSync2,
4700
4730
  linkSync,
4701
4731
  openSync as openSync2,
4702
- readFileSync as readFileSync6,
4732
+ readFileSync as readFileSync7,
4703
4733
  readlinkSync,
4704
4734
  realpathSync as realpathSync2,
4705
4735
  renameSync as renameSync4,
@@ -4741,7 +4771,17 @@ function deriveAutoUpdateNotice(state, result, currentVersion, logPath) {
4741
4771
  return { id, kind: "updated", version, releaseUrl: releaseUrlFor(version) };
4742
4772
  }
4743
4773
  if (result && result.version.replace(/^v/, "") === version && result.exitCode !== 0) {
4744
- return { id, kind: "failed", version, releaseUrl: releaseUrlFor(version), logPath };
4774
+ if (result.exitCode === UPDATE_PREPARE_FAILED && pending.by !== "person")
4775
+ return;
4776
+ const reason = result.exitCode === UPDATE_CHECKSUM_MISMATCH ? "mismatch" : result.exitCode === UPDATE_PREPARE_FAILED ? stagingFailureIn(lastRunLog(logPath)) ? "prepare" : "download" : undefined;
4777
+ return {
4778
+ id: reason === "mismatch" ? `${version}@mismatch` : id,
4779
+ kind: "failed",
4780
+ version,
4781
+ releaseUrl: releaseUrlFor(version),
4782
+ logPath,
4783
+ ...reason && { reason }
4784
+ };
4745
4785
  }
4746
4786
  return;
4747
4787
  }
@@ -4767,7 +4807,7 @@ function isManagedBinary(execPath, platform = process.platform, env = process.en
4767
4807
  }
4768
4808
  function readJson(path) {
4769
4809
  try {
4770
- return JSON.parse(readFileSync6(path, "utf-8"));
4810
+ return JSON.parse(readFileSync7(path, "utf-8"));
4771
4811
  } catch {
4772
4812
  return null;
4773
4813
  }
@@ -4800,7 +4840,7 @@ function parseUpdateLockHolder(content) {
4800
4840
  }
4801
4841
  function readTrimmed(path) {
4802
4842
  try {
4803
- return readFileSync6(path, "utf-8").trim();
4843
+ return readFileSync7(path, "utf-8").trim();
4804
4844
  } catch {
4805
4845
  return "";
4806
4846
  }
@@ -4840,7 +4880,7 @@ function removeJudgedLock(lockPath, judged) {
4840
4880
  }
4841
4881
  let same = false;
4842
4882
  try {
4843
- same = statSync5(aside).ino === judged.ino && readFileSync6(aside, "utf-8") === judged.content;
4883
+ same = statSync5(aside).ino === judged.ino && readFileSync7(aside, "utf-8") === judged.content;
4844
4884
  } catch {}
4845
4885
  if (!same) {
4846
4886
  try {
@@ -4855,7 +4895,7 @@ function removeJudgedLock(lockPath, judged) {
4855
4895
  function readLock(lockPath) {
4856
4896
  try {
4857
4897
  const stat = statSync5(lockPath);
4858
- return { ino: stat.ino, mtimeMs: stat.mtimeMs, content: readFileSync6(lockPath, "utf-8") };
4898
+ return { ino: stat.ino, mtimeMs: stat.mtimeMs, content: readFileSync7(lockPath, "utf-8") };
4859
4899
  } catch {
4860
4900
  return null;
4861
4901
  }
@@ -4978,8 +5018,14 @@ function installScriptUrl(platform, env = process.env) {
4978
5018
  return raw;
4979
5019
  return platform === "win32" ? INSTALL_PS1_URL : INSTALL_SH_URL;
4980
5020
  }
5021
+ function updatePrepareInvocation(main = typeof Bun !== "undefined" ? Bun.main : process.argv[1] ?? "") {
5022
+ const normalized = main.replace(/\\/g, "/");
5023
+ const compiled = normalized.startsWith("/$bunfs/") || /^\/?[A-Za-z]:\/(?:\$bunfs|~BUN)\//i.test(normalized);
5024
+ return { binary: process.execPath, entry: compiled ? "" : main };
5025
+ }
4981
5026
  function installerEnv(launch) {
4982
5027
  const { file, args, env: commandEnv } = installerCommand(launch.platform, launch.flags);
5028
+ const prepare = launch.prepare ?? updatePrepareInvocation();
4983
5029
  return {
4984
5030
  file,
4985
5031
  args,
@@ -4989,6 +5035,8 @@ function installerEnv(launch) {
4989
5035
  PLANNOTATOR_UPDATE_RESULT: launch.resultPath,
4990
5036
  PLANNOTATOR_UPDATE_LOCK: launch.lockPath,
4991
5037
  PLANNOTATOR_UPDATE_SCRIPT_URL: installScriptUrl(launch.platform),
5038
+ PLANNOTATOR_UPDATE_BINARY: prepare.binary,
5039
+ PLANNOTATOR_UPDATE_ENTRY: prepare.entry,
4992
5040
  ...commandEnv
4993
5041
  }
4994
5042
  };
@@ -5117,7 +5165,7 @@ function handleUpdateRoute(req, url, ctx) {
5117
5165
  return Response.json({ error: refused[result.outcome] ?? "The update could not start.", code: `update_${result.outcome.replace(/-/g, "_")}` }, { status: 409 });
5118
5166
  })();
5119
5167
  }
5120
- var AUTO_UPDATE_INTERVAL_MS, AUTO_UPDATE_LOCK_STALE_MS, UPDATE_LOCK_HANDOFF_MS = 5000, POSIX_WRAPPER = `
5168
+ var AUTO_UPDATE_INTERVAL_MS, UPDATE_PREPARE_FAILED, UPDATE_CHECKSUM_MISMATCH, AUTO_UPDATE_LOCK_STALE_MS, UPDATE_LOCK_HANDOFF_MS = 5000, POSIX_WRAPPER = `
5121
5169
  # Detached (auto-update, Update now): the lock names this wrapper's process
5122
5170
  # group (it leads it, so the installer and its children are in it) and this
5123
5171
  # machine, so an install that is gone shows as failed at once instead of
@@ -5126,31 +5174,68 @@ var AUTO_UPDATE_INTERVAL_MS, AUTO_UPDATE_LOCK_STALE_MS, UPDATE_LOCK_HANDOFF_MS =
5126
5174
  if [ "\${PLANNOTATOR_UPDATE_DETACHED:-}" = 1 ]; then
5127
5175
  printf 'pid=%s group=%s host=%s boot=%s pidns=%s\\n' "$$" "$$" "$(uname -n 2>/dev/null)" "$(cat /proc/sys/kernel/random/boot_id 2>/dev/null)" "$(readlink /proc/$$/ns/pid 2>/dev/null)" > "$PLANNOTATOR_UPDATE_LOCK"
5128
5176
  fi
5129
- tmp=$(mktemp "\${TMPDIR:-/tmp}/plannotator-install.XXXXXX") || exit 1
5177
+ update_dir=""
5130
5178
  code=1
5179
+ cleanup() {
5180
+ [ -n "$update_dir" ] && rm -rf "$update_dir"
5181
+ }
5182
+ record() {
5183
+ printf '{"version":"%s","exitCode":%d}\\n' "$PLANNOTATOR_UPDATE_VERSION" "$1" > "$PLANNOTATOR_UPDATE_RESULT.tmp" && mv -f "$PLANNOTATOR_UPDATE_RESULT.tmp" "$PLANNOTATOR_UPDATE_RESULT"
5184
+ }
5131
5185
  # Interrupted (Ctrl-C on plannotator update, a TERM): record 130 and release
5132
5186
  # the lock now, so the next update does not wait an hour for a stale lock.
5133
5187
  on_signal() {
5134
5188
  trap '' INT TERM HUP
5135
- rm -f "$tmp"
5136
- printf '{"version":"%s","exitCode":130}\\n' "$PLANNOTATOR_UPDATE_VERSION" > "$PLANNOTATOR_UPDATE_RESULT.tmp" && mv -f "$PLANNOTATOR_UPDATE_RESULT.tmp" "$PLANNOTATOR_UPDATE_RESULT"
5189
+ cleanup
5190
+ record 130
5137
5191
  echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] update: interrupted"
5138
5192
  rm -f "$PLANNOTATOR_UPDATE_LOCK"
5139
5193
  exit 130
5140
5194
  }
5141
5195
  trap on_signal INT TERM HUP
5142
- if curl -fsSL --connect-timeout 30 --speed-limit 1 --speed-time 60 "$PLANNOTATOR_UPDATE_SCRIPT_URL" -o "$tmp"; then
5143
- bash "$tmp" --version "$PLANNOTATOR_UPDATE_VERSION" --non-interactive "$@" </dev/null
5196
+ if [ -n "$PLANNOTATOR_UPDATE_ENTRY" ]; then
5197
+ prepared=$("$PLANNOTATOR_UPDATE_BINARY" "$PLANNOTATOR_UPDATE_ENTRY" update-prepare "$PLANNOTATOR_UPDATE_VERSION" </dev/null) || prepared=""
5198
+ else
5199
+ prepared=$("$PLANNOTATOR_UPDATE_BINARY" update-prepare "$PLANNOTATOR_UPDATE_VERSION" </dev/null) || prepared=""
5200
+ fi
5201
+ # Used (and later removed) only when it is an absolute path on one line whose
5202
+ # last part is plannotator-update-* (a case pattern's * crosses slashes, so
5203
+ # the last part is checked on its own).
5204
+ case "$prepared" in
5205
+ *"
5206
+ "*|*/) ;;
5207
+ /*) case "\${prepared##*/}" in
5208
+ plannotator-update-?*) update_dir="$prepared" ;;
5209
+ esac ;;
5210
+ esac
5211
+ if [ -n "$update_dir" ] && [ -f "$update_dir/install.sh" ]; then
5212
+ # Written only when NODE_EXTRA_CA_CERTS is set: curl's own roots plus that
5213
+ # certificate, so install.sh's curl trusts what Plannotator's fetch did.
5214
+ if [ -f "$update_dir/curl-ca-bundle.pem" ]; then
5215
+ export CURL_CA_BUNDLE="$update_dir/curl-ca-bundle.pem"
5216
+ fi
5217
+ PLANNOTATOR_EXPECTED_SHA256=$(cat "$update_dir/expected-sha256" 2>/dev/null) PLANNOTATOR_UPDATE_MISMATCH_FILE="$update_dir/checksum-mismatch" bash "$update_dir/install.sh" --version "$PLANNOTATOR_UPDATE_VERSION" --non-interactive "$@" </dev/null
5144
5218
  code=$?
5219
+ # A mismatch is only what install.sh's pin check marked as one.
5220
+ if [ -f "$update_dir/checksum-mismatch" ]; then
5221
+ code=113
5222
+ elif [ "$code" -eq 113 ]; then
5223
+ code=1
5224
+ fi
5145
5225
  else
5146
- echo "update: could not download $PLANNOTATOR_UPDATE_SCRIPT_URL"
5226
+ code=75
5227
+ # update-prepare already said why (download, certificate, temp folder).
5228
+ echo "update: nothing ran; nothing was changed"
5147
5229
  fi
5148
- rm -f "$tmp"
5149
- printf '{"version":"%s","exitCode":%d}\\n' "$PLANNOTATOR_UPDATE_VERSION" "$code" > "$PLANNOTATOR_UPDATE_RESULT.tmp" && mv -f "$PLANNOTATOR_UPDATE_RESULT.tmp" "$PLANNOTATOR_UPDATE_RESULT"
5230
+ cleanup
5231
+ # The log line first: a reader that sees the new result also finds this run's
5232
+ # part of update.log (deriveAutoUpdateNotice tells "prepare" from "download" there).
5150
5233
  echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] update: install.sh exited $code"
5234
+ record "$code"
5151
5235
  rm -f "$PLANNOTATOR_UPDATE_LOCK"
5152
5236
  `, POWERSHELL_ALLOWED_FLAGS, POWERSHELL_WRAPPER, noticeVersion;
5153
5237
  var init_auto_update = __esm(() => {
5238
+ init_update_log();
5154
5239
  init_data_dir();
5155
5240
  init_config();
5156
5241
  init_update_check();
@@ -5158,6 +5243,8 @@ var init_auto_update = __esm(() => {
5158
5243
  init_sessions();
5159
5244
  init_update_check();
5160
5245
  AUTO_UPDATE_INTERVAL_MS = 24 * 60 * 60 * 1000;
5246
+ UPDATE_PREPARE_FAILED = UPDATE_EXIT_DOWNLOAD_FAILED;
5247
+ UPDATE_CHECKSUM_MISMATCH = UPDATE_EXIT_CHECKSUM_MISMATCH;
5161
5248
  AUTO_UPDATE_LOCK_STALE_MS = 60 * 60 * 1000;
5162
5249
  POWERSHELL_ALLOWED_FLAGS = Object.values(INSTALL_FLAG_SPELLINGS).map((s) => `'${s.powershell}'`).join(",");
5163
5250
  POWERSHELL_WRAPPER = `
@@ -5665,7 +5752,7 @@ var init_feedback_archive = __esm(() => {
5665
5752
 
5666
5753
  // ../../packages/shared/improvement-hooks.ts
5667
5754
  import { join as join11 } from "path";
5668
- import { readFileSync as readFileSync7, statSync as statSync6 } from "fs";
5755
+ import { readFileSync as readFileSync8, statSync as statSync6 } from "fs";
5669
5756
  function hooksBaseDir() {
5670
5757
  return join11(getPlannotatorDataDir(), "hooks");
5671
5758
  }
@@ -5688,7 +5775,7 @@ function tryReadHookFile(filePath, hookName) {
5688
5775
  const stat = statSync6(filePath);
5689
5776
  if (!stat.isFile() || stat.size === 0 || stat.size > MAX_FILE_SIZE)
5690
5777
  return null;
5691
- const content = readFileSync7(filePath, "utf-8").trim();
5778
+ const content = readFileSync8(filePath, "utf-8").trim();
5692
5779
  if (!content)
5693
5780
  return null;
5694
5781
  return { content, hookName, filePath };
@@ -6713,7 +6800,7 @@ var init_image = __esm(() => {
6713
6800
 
6714
6801
  // ../../packages/shared/draft.ts
6715
6802
  import { join as join13 } from "path";
6716
- import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync7, readFileSync as readFileSync8, renameSync as renameSync5, unlinkSync as unlinkSync5, existsSync as existsSync9 } from "fs";
6803
+ import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync7, readFileSync as readFileSync9, renameSync as renameSync5, unlinkSync as unlinkSync5, existsSync as existsSync9 } from "fs";
6717
6804
  import { createHash } from "crypto";
6718
6805
  function getDraftDir() {
6719
6806
  const dir = join13(getPlannotatorDataDir(), "drafts");
@@ -6737,7 +6824,7 @@ function readTombstoneGeneration(key) {
6737
6824
  try {
6738
6825
  if (!existsSync9(filePath))
6739
6826
  return null;
6740
- const parsed = JSON.parse(readFileSync8(filePath, "utf-8"));
6827
+ const parsed = JSON.parse(readFileSync9(filePath, "utf-8"));
6741
6828
  return readGeneration(parsed.draftGeneration);
6742
6829
  } catch {
6743
6830
  return null;
@@ -6751,7 +6838,7 @@ function readStoredDraftGeneration(key) {
6751
6838
  try {
6752
6839
  if (!existsSync9(filePath))
6753
6840
  return null;
6754
- const parsed = JSON.parse(readFileSync8(filePath, "utf-8"));
6841
+ const parsed = JSON.parse(readFileSync9(filePath, "utf-8"));
6755
6842
  return readGeneration(parsed.draftGeneration);
6756
6843
  } catch {
6757
6844
  return null;
@@ -6799,7 +6886,7 @@ function loadDraft(key) {
6799
6886
  try {
6800
6887
  if (!existsSync9(filePath))
6801
6888
  return null;
6802
- const draft = JSON.parse(readFileSync8(filePath, "utf-8"));
6889
+ const draft = JSON.parse(readFileSync9(filePath, "utf-8"));
6803
6890
  const draftGeneration = readGeneration(draft.draftGeneration);
6804
6891
  const deletedGeneration = readTombstoneGeneration(key);
6805
6892
  if (draftGeneration !== null && deletedGeneration !== null && draftGeneration <= deletedGeneration) {
@@ -6887,7 +6974,7 @@ import {
6887
6974
  mkdirSync as mkdirSync8,
6888
6975
  openSync as openSync3,
6889
6976
  readdirSync as readdirSync4,
6890
- readFileSync as readFileSync9,
6977
+ readFileSync as readFileSync10,
6891
6978
  readSync,
6892
6979
  realpathSync as realpathSync3,
6893
6980
  statSync as statSync7,
@@ -7131,7 +7218,7 @@ function readCuratedSkillNames() {
7131
7218
  return null;
7132
7219
  let parsed;
7133
7220
  try {
7134
- parsed = JSON.parse(readFileSync9(path, "utf-8"));
7221
+ parsed = JSON.parse(readFileSync10(path, "utf-8"));
7135
7222
  } catch (err) {
7136
7223
  console.error(`[plannotator] Ignoring malformed review-skills.json: ${err instanceof Error ? err.message : String(err)}`);
7137
7224
  return null;
@@ -7177,7 +7264,7 @@ function enableReviewSkill(name) {
7177
7264
  function resolveSkillProfile(skill) {
7178
7265
  let raw;
7179
7266
  try {
7180
- raw = readFileSync9(skill.skillMdPath, "utf-8");
7267
+ raw = readFileSync10(skill.skillMdPath, "utf-8");
7181
7268
  } catch (err) {
7182
7269
  console.error(`[plannotator] Skipping review skill ${skill.name}: could not read ${skill.skillMdPath}: ${err instanceof Error ? err.message : String(err)}`);
7183
7270
  return null;
@@ -7686,7 +7773,7 @@ var init_file_browser_files = __esm(() => {
7686
7773
 
7687
7774
  // ../../packages/shared/workspace-status.ts
7688
7775
  import { spawn as spawn3, spawnSync as spawnSync2 } from "child_process";
7689
- import { readFileSync as readFileSync10, realpathSync as realpathSync4, statSync as statSync8 } from "fs";
7776
+ import { readFileSync as readFileSync11, realpathSync as realpathSync4, statSync as statSync8 } from "fs";
7690
7777
  import { readFile, realpath, stat } from "fs/promises";
7691
7778
  import { isAbsolute as isAbsolute3, relative, resolve as resolve5 } from "path";
7692
7779
  function getGitTimeoutMs() {
@@ -8071,7 +8158,7 @@ function getGitMetadataWatchPaths(cwd) {
8071
8158
  return [];
8072
8159
  let currentRefPath = null;
8073
8160
  try {
8074
- const head = readFileSync10(resolve5(repo.gitDir, "HEAD"), "utf8").trim();
8161
+ const head = readFileSync11(resolve5(repo.gitDir, "HEAD"), "utf8").trim();
8075
8162
  if (head.startsWith("ref: ")) {
8076
8163
  const refsRoot = resolve5(repo.gitCommonDir, "refs");
8077
8164
  const candidate = resolve5(repo.gitCommonDir, head.slice("ref: ".length).trim());
@@ -8104,7 +8191,7 @@ var init_workspace_status = __esm(() => {
8104
8191
  });
8105
8192
 
8106
8193
  // ../../packages/shared/doc-resolve.ts
8107
- import { readFileSync as readFileSync11, realpathSync as realpathSync5, statSync as statSync9 } from "fs";
8194
+ import { readFileSync as readFileSync12, realpathSync as realpathSync5, statSync as statSync9 } from "fs";
8108
8195
  import { basename, dirname as dirname2, join as join16, posix as posix2 } from "path";
8109
8196
  function getAllowedRootPaths(options) {
8110
8197
  const rawRoots = options?.rootPaths?.length ? options.rootPaths : [options?.rootPath ?? process.cwd()];
@@ -8174,7 +8261,7 @@ function readPlanFile(planFilePath, plan) {
8174
8261
  const stat = statSync9(path);
8175
8262
  if (!stat.isFile() || stat.size > MAX_ANNOTATABLE_FILE_BYTES)
8176
8263
  return null;
8177
- if (readFileSync11(path, "utf8").trimEnd() !== plan.trimEnd())
8264
+ if (readFileSync12(path, "utf8").trimEnd() !== plan.trimEnd())
8178
8265
  return null;
8179
8266
  const real = realpathSync5(path);
8180
8267
  return { path: real, dir: dirname2(real), targets: planLinkTargets(plan) };
@@ -25419,7 +25506,7 @@ import {
25419
25506
  existsSync as existsSync11,
25420
25507
  linkSync as linkSync2,
25421
25508
  realpathSync as realpathSync6,
25422
- readFileSync as readFileSync12,
25509
+ readFileSync as readFileSync13,
25423
25510
  renameSync as renameSync6,
25424
25511
  statSync as statSync10,
25425
25512
  unlinkSync as unlinkSync6,
@@ -25455,7 +25542,7 @@ function applySourceEolPolicy(text, eol) {
25455
25542
  return normalized;
25456
25543
  }
25457
25544
  function readSourceFileSnapshot(filePath) {
25458
- const bytes = readFileSync12(filePath);
25545
+ const bytes = readFileSync13(filePath);
25459
25546
  const stat = statSync10(filePath);
25460
25547
  const text = bytes.toString("utf8");
25461
25548
  return {
@@ -47827,7 +47914,7 @@ var init_chokidar = __esm(() => {
47827
47914
  });
47828
47915
 
47829
47916
  // ../../packages/shared/file-browser-watch-core.ts
47830
- import { readFileSync as readFileSync13, watch as nodeFsWatch, statSync as statSync12 } from "fs";
47917
+ import { readFileSync as readFileSync14, watch as nodeFsWatch, statSync as statSync12 } from "fs";
47831
47918
  import { lstat as lstat3, readdir as readdir5, stat as stat5 } from "fs/promises";
47832
47919
  import { dirname as dirname6, join as join21, relative as relative4, resolve as resolve9, sep as sep2 } from "path";
47833
47920
  function directoryWatchLimitFor(maxUserWatches) {
@@ -47842,7 +47929,7 @@ function defaultDirectoryWatchLimit() {
47842
47929
  let allowance = null;
47843
47930
  if (process.platform === "linux") {
47844
47931
  try {
47845
- allowance = Number.parseInt(readFileSync13("/proc/sys/fs/inotify/max_user_watches", "utf8").trim(), 10);
47932
+ allowance = Number.parseInt(readFileSync14("/proc/sys/fs/inotify/max_user_watches", "utf8").trim(), 10);
47846
47933
  } catch {
47847
47934
  allowance = null;
47848
47935
  }
@@ -89734,7 +89821,7 @@ var init_review_core = __esm(() => {
89734
89821
  });
89735
89822
 
89736
89823
  // ../../packages/shared/package-changes-service.ts
89737
- import { readFileSync as readFileSync15, statSync as statSync16 } from "fs";
89824
+ import { readFileSync as readFileSync16, statSync as statSync16 } from "fs";
89738
89825
  import { dirname as dirname9, join as join24, parse as parsePath } from "path";
89739
89826
  function settingsNames(env) {
89740
89827
  const names = [
@@ -89806,7 +89893,7 @@ function readLocalSettingsFile(path) {
89806
89893
  return { kind: "unreadable", reason: "not a file" };
89807
89894
  if (st.size > SETTINGS_MAX_BYTES)
89808
89895
  return { kind: "unreadable", reason: "too large" };
89809
- return { kind: "ok", text: readFileSync15(path, "utf-8") };
89896
+ return { kind: "ok", text: readFileSync16(path, "utf-8") };
89810
89897
  } catch (err) {
89811
89898
  const code = err?.code;
89812
89899
  if (code === "ENOENT" || code === "ENOTDIR")
@@ -95587,7 +95674,7 @@ import {
95587
95674
  closeSync as closeSync5,
95588
95675
  mkdirSync as mkdirSync12,
95589
95676
  openSync as openSync5,
95590
- readFileSync as readFileSync16,
95677
+ readFileSync as readFileSync17,
95591
95678
  rmSync as rmSync3,
95592
95679
  statSync as statSync17,
95593
95680
  writeFileSync as writeFileSync10
@@ -95598,7 +95685,7 @@ function hasErrorCode(error, code) {
95598
95685
  }
95599
95686
  function removeOwnedLock(lockPath, token) {
95600
95687
  try {
95601
- if (readFileSync16(lockPath, "utf8") === token)
95688
+ if (readFileSync17(lockPath, "utf8") === token)
95602
95689
  rmSync3(lockPath, { force: true });
95603
95690
  } catch {}
95604
95691
  }
@@ -95936,7 +96023,7 @@ var init_call_flow_types = __esm(() => {
95936
96023
 
95937
96024
  // ../../packages/shared/call-flow.ts
95938
96025
  import { createHash as createHash5 } from "crypto";
95939
- import { chmodSync as chmodSync2, cpSync, existsSync as existsSync17, mkdirSync as mkdirSync13, readFileSync as readFileSync17, readdirSync as readdirSync6, renameSync as renameSync8, rmSync as rmSync4, statSync as statSync18, writeFileSync as writeFileSync11 } from "fs";
96026
+ import { chmodSync as chmodSync2, cpSync, existsSync as existsSync17, mkdirSync as mkdirSync13, readFileSync as readFileSync18, readdirSync as readdirSync6, renameSync as renameSync8, rmSync as rmSync4, statSync as statSync18, writeFileSync as writeFileSync11 } from "fs";
95940
96027
  import { mkdtemp as mkdtemp2 } from "fs/promises";
95941
96028
  import { tmpdir as tmpdir4 } from "os";
95942
96029
  import { basename as basename8, dirname as dirname11, isAbsolute as isAbsolute9, join as join28 } from "path";
@@ -95957,7 +96044,7 @@ function getLanguageLockMarker(runtimeDir, id) {
95957
96044
  }
95958
96045
  function packHasCommittedLock(runtimeDir, id) {
95959
96046
  try {
95960
- const installed = JSON.parse(readFileSync17(getLanguageLockMarker(runtimeDir, id), "utf8"));
96047
+ const installed = JSON.parse(readFileSync18(getLanguageLockMarker(runtimeDir, id), "utf8"));
95961
96048
  return JSON.stringify(installed) === JSON.stringify(CALL_FLOW_PACK_LOCKS[id]);
95962
96049
  } catch {
95963
96050
  return false;
@@ -95965,7 +96052,7 @@ function packHasCommittedLock(runtimeDir, id) {
95965
96052
  }
95966
96053
  function installDirHasCommittedPackLock(installDir, id) {
95967
96054
  try {
95968
- const installed = JSON.parse(readFileSync17(join28(installDir, "package-lock.json"), "utf8"));
96055
+ const installed = JSON.parse(readFileSync18(join28(installDir, "package-lock.json"), "utf8"));
95969
96056
  return JSON.stringify(installed) === JSON.stringify(CALL_FLOW_PACK_LOCKS[id]);
95970
96057
  } catch {
95971
96058
  return false;
@@ -95981,7 +96068,7 @@ function isLanguageInstalled(runtimeDir, language, managed) {
95981
96068
  }
95982
96069
  function readPackageVersion(packageRoot) {
95983
96070
  try {
95984
- const parsed = JSON.parse(readFileSync17(join28(packageRoot, "package.json"), "utf8"));
96071
+ const parsed = JSON.parse(readFileSync18(join28(packageRoot, "package.json"), "utf8"));
95985
96072
  return typeof parsed.version === "string" ? parsed.version : null;
95986
96073
  } catch {
95987
96074
  return null;
@@ -95997,7 +96084,7 @@ function runtimeJson(value) {
95997
96084
  }
95998
96085
  function hasCommittedRuntimeLock(runtimeDir) {
95999
96086
  try {
96000
- const lock = JSON.parse(readFileSync17(join28(runtimeDir, "package-lock.json"), "utf8"));
96087
+ const lock = JSON.parse(readFileSync18(join28(runtimeDir, "package-lock.json"), "utf8"));
96001
96088
  return JSON.stringify(lock) === JSON.stringify(package_lock_default);
96002
96089
  } catch {
96003
96090
  return false;
@@ -96069,7 +96156,7 @@ async function resolveCallFlowRuntime() {
96069
96156
  }
96070
96157
  if (!override) {
96071
96158
  const revisionPath = join28(runtimeDir, ".calldiff-revision");
96072
- const installedRevision = existsSync17(revisionPath) ? readFileSync17(revisionPath, "utf8").trim() : "";
96159
+ const installedRevision = existsSync17(revisionPath) ? readFileSync18(revisionPath, "utf8").trim() : "";
96073
96160
  if (installedRevision !== CALLDIFF_COMMIT) {
96074
96161
  return { ok: false, reason: "revision-mismatch", message: "The managed Call flow core is stale and needs reinstalling." };
96075
96162
  }
@@ -96294,7 +96381,7 @@ function pruneCallFlowNativePackage(packageRoot) {
96294
96381
  if (entry.isDirectory())
96295
96382
  collectBuiltAddons(path);
96296
96383
  else if (entry.isFile() && entry.name.endsWith(".node")) {
96297
- builtAddons.push({ name: basename8(path), bytes: readFileSync17(path) });
96384
+ builtAddons.push({ name: basename8(path), bytes: readFileSync18(path) });
96298
96385
  }
96299
96386
  }
96300
96387
  };
@@ -97933,7 +98020,7 @@ var init_review_draft = __esm(() => {
97933
98020
 
97934
98021
  // ../../packages/shared/review-progress.ts
97935
98022
  import { createHash as createHash6, randomUUID as randomUUID2 } from "crypto";
97936
- import { mkdirSync as mkdirSync14, readFileSync as readFileSync18, realpathSync as realpathSync8, renameSync as renameSync9, unlinkSync as unlinkSync8, writeFileSync as writeFileSync12 } from "fs";
98023
+ import { mkdirSync as mkdirSync14, readFileSync as readFileSync19, realpathSync as realpathSync8, renameSync as renameSync9, unlinkSync as unlinkSync8, writeFileSync as writeFileSync12 } from "fs";
97937
98024
  import { join as join29, resolve as resolve14 } from "path";
97938
98025
  function reviewFileFingerprints(patch, identities) {
97939
98026
  const result = Object.create(null);
@@ -98001,7 +98088,7 @@ function loadReviewProgress(snapshot, platformViewed = []) {
98001
98088
  for (const [path, fingerprint] of Object.entries(snapshot.fingerprints)) {
98002
98089
  let record;
98003
98090
  try {
98004
- const value = JSON.parse(readFileSync18(recordPath(snapshot, path), "utf8"));
98091
+ const value = JSON.parse(readFileSync19(recordPath(snapshot, path), "utf8"));
98005
98092
  if (value?.v === 1 && value.path === path && typeof value.fingerprint === "string" && typeof value.viewed === "boolean" && typeof value.suppressed === "boolean")
98006
98093
  record = value;
98007
98094
  } catch {}
@@ -99397,7 +99484,7 @@ var init_guide2 = __esm(() => {
99397
99484
  });
99398
99485
 
99399
99486
  // ../../packages/shared/guide-instructions-store.ts
99400
- import { mkdirSync as mkdirSync15, readFileSync as readFileSync19, unlinkSync as unlinkSync9, writeFileSync as writeFileSync13 } from "fs";
99487
+ import { mkdirSync as mkdirSync15, readFileSync as readFileSync20, unlinkSync as unlinkSync9, writeFileSync as writeFileSync13 } from "fs";
99401
99488
  import { dirname as dirname13, join as join31 } from "path";
99402
99489
  function instructionsPath() {
99403
99490
  return join31(getPlannotatorDataDir(), "guide-instructions.md");
@@ -99408,7 +99495,7 @@ function bound(value) {
99408
99495
  }
99409
99496
  function readGuideInstructions() {
99410
99497
  try {
99411
- return bound(readFileSync19(instructionsPath(), "utf8"));
99498
+ return bound(readFileSync20(instructionsPath(), "utf8"));
99412
99499
  } catch {
99413
99500
  return "";
99414
99501
  }
@@ -104632,7 +104719,7 @@ var init_guide_share = __esm(() => {
104632
104719
 
104633
104720
  // ../../packages/shared/guide-store.ts
104634
104721
  import { join as join37, resolve as resolve15, basename as basename10 } from "path";
104635
- import { mkdirSync as mkdirSync18, writeFileSync as writeFileSync16, readFileSync as readFileSync20, readdirSync as readdirSync7, renameSync as renameSync10, unlinkSync as unlinkSync10, existsSync as existsSync20 } from "fs";
104722
+ import { mkdirSync as mkdirSync18, writeFileSync as writeFileSync16, readFileSync as readFileSync21, readdirSync as readdirSync7, renameSync as renameSync10, unlinkSync as unlinkSync10, existsSync as existsSync20 } from "fs";
104636
104723
  import { createHash as createHash7 } from "crypto";
104637
104724
  function sanitizeKeySegment(segment) {
104638
104725
  const cleaned = segment.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^[.\-]+|[.\-]+$/g, "");
@@ -104808,7 +104895,7 @@ function loadGuidePatch(repoKey, envelope) {
104808
104895
  const filePath = join37(guidesDir(repoKey), envelope.review.patchFile);
104809
104896
  if (!existsSync20(filePath))
104810
104897
  return null;
104811
- return readFileSync20(filePath, "utf-8");
104898
+ return readFileSync21(filePath, "utf-8");
104812
104899
  } catch {
104813
104900
  return null;
104814
104901
  }
@@ -104842,7 +104929,7 @@ function loadGuide(repoKey, id) {
104842
104929
  const filePath = guidePath(repoKey, id);
104843
104930
  if (!existsSync20(filePath))
104844
104931
  return null;
104845
- return parseEnvelope(readFileSync20(filePath, "utf-8"));
104932
+ return parseEnvelope(readFileSync21(filePath, "utf-8"));
104846
104933
  } catch {
104847
104934
  return null;
104848
104935
  }
@@ -114041,7 +114128,7 @@ var init_html_assets = __esm(() => {
114041
114128
  });
114042
114129
 
114043
114130
  // ../../packages/shared/html-assets-node.ts
114044
- import { existsSync as existsSync21, readFileSync as readFileSync21, realpathSync as realpathSync10, statSync as statSync20 } from "fs";
114131
+ import { existsSync as existsSync21, readFileSync as readFileSync22, realpathSync as realpathSync10, statSync as statSync20 } from "fs";
114045
114132
  import { dirname as dirname17, isAbsolute as isAbsolute10, relative as relative8, resolve as resolvePath3, posix as pathPosix2, sep as sep4 } from "path";
114046
114133
  function htmlAssetContext(htmlFilePath, folderPath) {
114047
114134
  const directory = dirname17(resolvePath3(htmlFilePath));
@@ -114092,7 +114179,7 @@ function inlineHtmlLocalAssets(html, htmlFilePath, folderPath) {
114092
114179
  const stat = statSync20(resolved);
114093
114180
  if (!stat.isFile() || stat.size > MAX_HTML_ASSET_BYTES)
114094
114181
  return null;
114095
- let bytes = readFileSync21(resolved);
114182
+ let bytes = readFileSync22(resolved);
114096
114183
  if (contentType.startsWith("text/css") && !activeCss.has(assetPath)) {
114097
114184
  activeCss.add(assetPath);
114098
114185
  try {
@@ -119463,7 +119550,7 @@ function shutdown() {
119463
119550
  var init_agent_terminal_node_sidecar = () => {};
119464
119551
 
119465
119552
  // ../../packages/server/agent-terminal-runtime.ts
119466
- import { existsSync as existsSync24, mkdirSync as mkdirSync19, readFileSync as readFileSync23, writeFileSync as writeFileSync17 } from "fs";
119553
+ import { existsSync as existsSync24, mkdirSync as mkdirSync19, readFileSync as readFileSync24, writeFileSync as writeFileSync17 } from "fs";
119467
119554
  import { join as join39 } from "path";
119468
119555
  import { fileURLToPath } from "url";
119469
119556
  function getAgentTerminalManagedRuntimeDir(dataDir = getPlannotatorDataDir()) {
@@ -119568,7 +119655,7 @@ function readInstalledWebTuiVersion(runtimeDir) {
119568
119655
  if (!existsSync24(packageJsonPath))
119569
119656
  return null;
119570
119657
  try {
119571
- const parsed = JSON.parse(readFileSync23(packageJsonPath, "utf8"));
119658
+ const parsed = JSON.parse(readFileSync24(packageJsonPath, "utf8"));
119572
119659
  return typeof parsed.version === "string" ? parsed.version : null;
119573
119660
  } catch {
119574
119661
  return null;
@@ -121398,7 +121485,7 @@ var init_annotate_bundle = () => {};
121398
121485
  import { existsSync as existsSync25 } from "fs";
121399
121486
  import { dirname as dirname20, resolve as resolvePath6 } from "path";
121400
121487
  import { randomBytes as randomBytes2 } from "crypto";
121401
- import { readFileSync as readFileSync24 } from "fs";
121488
+ import { readFileSync as readFileSync25 } from "fs";
121402
121489
  function runGuardedShutdown(steps, closeListener, log = (message, error) => console.error(message, error)) {
121403
121490
  try {
121404
121491
  for (const [name, dispose] of steps) {
@@ -121484,7 +121571,7 @@ async function startAnnotateServer(options) {
121484
121571
  if (file.renderAs === "html" || !isAnnotatableTextPath2(file.path))
121485
121572
  continue;
121486
121573
  try {
121487
- computeFolderAnnotateHistory(file.path, readFileSync24(file.path, "utf-8"));
121574
+ computeFolderAnnotateHistory(file.path, readFileSync25(file.path, "utf-8"));
121488
121575
  } catch {}
121489
121576
  }
121490
121577
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plannotator/opencode",
3
- "version": "0.28.34",
3
+ "version": "0.28.35",
4
4
  "type": "module",
5
5
  "description": "Plannotator plugin for OpenCode - interactive plan review with visual annotation",
6
6
  "author": "backnotprop",
@@ -50,7 +50,7 @@
50
50
  "@opencode-ai/plugin": "1.19.3",
51
51
  "@opencode/plugin": "2.0.32",
52
52
  "@plannotator/ai": "0.0.1",
53
- "@plannotator/server": "0.28.34",
53
+ "@plannotator/server": "0.28.35",
54
54
  "@plannotator/shared": "0.0.1"
55
55
  },
56
56
  "engines": {