@plannotator/opencode 0.19.23 → 0.19.24

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
@@ -42498,9 +42498,9 @@ var Thread = class {
42498
42498
  stderrChunks.push(data);
42499
42499
  });
42500
42500
  }
42501
- const exitPromise = new Promise((resolve5) => {
42501
+ const exitPromise = new Promise((resolve6) => {
42502
42502
  child.once("exit", (code, signal) => {
42503
- resolve5({ code, signal });
42503
+ resolve6({ code, signal });
42504
42504
  });
42505
42505
  });
42506
42506
  const rl2 = readline.createInterface({
@@ -43021,8 +43021,8 @@ class PiProcess {
43021
43021
  }
43022
43022
  sendAndWait(command) {
43023
43023
  const id = `req_${++this.nextId}`;
43024
- return new Promise((resolve5, reject) => {
43025
- this.pendingRequests.set(id, { resolve: resolve5, reject });
43024
+ return new Promise((resolve6, reject) => {
43025
+ this.pendingRequests.set(id, { resolve: resolve6, reject });
43026
43026
  this.send({ ...command, id });
43027
43027
  });
43028
43028
  }
@@ -43167,15 +43167,15 @@ var init_pi_sdk = __esm(() => {
43167
43167
  }
43168
43168
  const effectivePrompt = buildEffectivePrompt(prompt, this.config.systemPrompt, this._firstQuerySent);
43169
43169
  const queue = [];
43170
- let resolve5 = null;
43170
+ let resolve6 = null;
43171
43171
  let done = false;
43172
43172
  const push = (msg) => {
43173
43173
  queue.push(msg);
43174
- resolve5?.();
43174
+ resolve6?.();
43175
43175
  };
43176
43176
  const finish = () => {
43177
43177
  done = true;
43178
- resolve5?.();
43178
+ resolve6?.();
43179
43179
  };
43180
43180
  const unsubscribe = this.process.onEvent((event) => {
43181
43181
  const mapped = mapPiEvent(event, this.id);
@@ -43207,9 +43207,9 @@ var init_pi_sdk = __esm(() => {
43207
43207
  yield queue.shift();
43208
43208
  } else {
43209
43209
  await new Promise((r9) => {
43210
- resolve5 = r9;
43210
+ resolve6 = r9;
43211
43211
  });
43212
- resolve5 = null;
43212
+ resolve6 = null;
43213
43213
  }
43214
43214
  }
43215
43215
  } finally {
@@ -43245,7 +43245,7 @@ var init_types_gen = () => {};
43245
43245
  // ../../node_modules/.bun/@opencode-ai+sdk@1.3.5/node_modules/@opencode-ai/sdk/dist/gen/core/serverSentEvents.gen.js
43246
43246
  var createSseClient = ({ onSseError, onSseEvent, responseTransformer, responseValidator, sseDefaultRetryDelay, sseMaxRetryAttempts, sseMaxRetryDelay, sseSleepFn, url, ...options }) => {
43247
43247
  let lastEventId;
43248
- const sleep = sseSleepFn ?? ((ms) => new Promise((resolve5) => setTimeout(resolve5, ms)));
43248
+ const sleep = sseSleepFn ?? ((ms) => new Promise((resolve6) => setTimeout(resolve6, ms)));
43249
43249
  const createStream = async function* () {
43250
43250
  let retryDelay = sseDefaultRetryDelay ?? 3000;
43251
43251
  let attempt = 0;
@@ -44646,7 +44646,7 @@ async function createOpencodeServer(options) {
44646
44646
  OPENCODE_CONFIG_CONTENT: JSON.stringify(options.config ?? {})
44647
44647
  }
44648
44648
  });
44649
- const url = await new Promise((resolve5, reject) => {
44649
+ const url = await new Promise((resolve6, reject) => {
44650
44650
  const id = setTimeout(() => {
44651
44651
  reject(new Error(`Timeout waiting for server to start after ${options.timeout}ms`));
44652
44652
  }, options.timeout);
@@ -44662,7 +44662,7 @@ async function createOpencodeServer(options) {
44662
44662
  throw new Error(`Failed to parse server url from output: ${line}`);
44663
44663
  }
44664
44664
  clearTimeout(id);
44665
- resolve5(match[1]);
44665
+ resolve6(match[1]);
44666
44666
  return;
44667
44667
  }
44668
44668
  }
@@ -45160,9 +45160,25 @@ var init_opencode_sdk = __esm(() => {
45160
45160
  // index.ts
45161
45161
  import { tool } from "@opencode-ai/plugin";
45162
45162
  import { existsSync as existsSync11, mkdirSync as mkdirSync8, readFileSync as readFileSync7, unlinkSync as unlinkSync3, writeFileSync as writeFileSync5 } from "fs";
45163
- import { homedir as homedir9 } from "os";
45164
45163
  import path4 from "path";
45165
45164
 
45165
+ // ../../packages/shared/data-dir.ts
45166
+ import { homedir } from "os";
45167
+ import { join, resolve } from "path";
45168
+ function getPlannotatorDataDir() {
45169
+ const envDir = process.env.PLANNOTATOR_DATA_DIR?.trim();
45170
+ if (!envDir) {
45171
+ return join(homedir(), ".plannotator");
45172
+ }
45173
+ const home = homedir();
45174
+ if (envDir === "~")
45175
+ return home;
45176
+ if (envDir.startsWith("~/") || envDir.startsWith("~\\")) {
45177
+ return join(home, envDir.slice(2));
45178
+ }
45179
+ return resolve(envDir);
45180
+ }
45181
+
45166
45182
  // ../../packages/server/remote.ts
45167
45183
  var DEFAULT_REMOTE_PORT = 19432;
45168
45184
  var LOOPBACK_HOST = "127.0.0.1";
@@ -45235,7 +45251,7 @@ async function openEditorDiff(oldPath, newPath) {
45235
45251
 
45236
45252
  // ../../packages/server/integrations.ts
45237
45253
  var {$: $2 } = globalThis.Bun;
45238
- import { join as join3 } from "path";
45254
+ import { join as join4 } from "path";
45239
45255
  import { mkdirSync, existsSync as existsSync3, statSync } from "fs";
45240
45256
 
45241
45257
  // ../../packages/server/project.ts
@@ -45291,18 +45307,18 @@ async function detectProjectName() {
45291
45307
 
45292
45308
  // ../../packages/shared/integrations-common.ts
45293
45309
  import { existsSync, readFileSync } from "fs";
45294
- import { join } from "path";
45310
+ import { join as join2 } from "path";
45295
45311
  function detectObsidianVaults() {
45296
45312
  try {
45297
45313
  const home = process.env.HOME || process.env.USERPROFILE || "";
45298
45314
  let configPath;
45299
45315
  if (process.platform === "darwin") {
45300
- configPath = join(home, "Library/Application Support/obsidian/obsidian.json");
45316
+ configPath = join2(home, "Library/Application Support/obsidian/obsidian.json");
45301
45317
  } else if (process.platform === "win32") {
45302
- const appData = process.env.APPDATA || join(home, "AppData/Roaming");
45303
- configPath = join(appData, "obsidian/obsidian.json");
45318
+ const appData = process.env.APPDATA || join2(home, "AppData/Roaming");
45319
+ configPath = join2(appData, "obsidian/obsidian.json");
45304
45320
  } else {
45305
- configPath = join(home, ".config/obsidian/obsidian.json");
45321
+ configPath = join2(home, ".config/obsidian/obsidian.json");
45306
45322
  }
45307
45323
  if (!existsSync(configPath)) {
45308
45324
  return [];
@@ -45415,8 +45431,8 @@ Last Edited: ${now}
45415
45431
  }
45416
45432
 
45417
45433
  // ../../packages/shared/resolve-file.ts
45418
- import { homedir } from "os";
45419
- import { isAbsolute, join as join2, resolve, win32 } from "path";
45434
+ import { homedir as homedir2 } from "os";
45435
+ import { isAbsolute, join as join3, resolve as resolve2, win32 } from "path";
45420
45436
  import { existsSync as existsSync2, readdirSync } from "fs";
45421
45437
 
45422
45438
  // ../../packages/shared/code-file.ts
@@ -45481,12 +45497,12 @@ function normalizeSeparators(input) {
45481
45497
  function stripTrailingSlashes(input) {
45482
45498
  return input.replace(/\/+$/, "");
45483
45499
  }
45484
- function expandHomePath(input, home = homedir()) {
45500
+ function expandHomePath(input, home = homedir2()) {
45485
45501
  if (input === "~") {
45486
45502
  return home;
45487
45503
  }
45488
45504
  if (input.startsWith("~/") || input.startsWith("~\\")) {
45489
- return join2(home, input.slice(2));
45505
+ return join3(home, input.slice(2));
45490
45506
  }
45491
45507
  return input;
45492
45508
  }
@@ -45532,7 +45548,7 @@ function resolveUserPath(input, baseDir = process.cwd(), platform = process.plat
45532
45548
  if (!normalizedInput) {
45533
45549
  return "";
45534
45550
  }
45535
- return isAbsoluteNormalizedUserPath(normalizedInput, platform) ? resolveAbsolutePath(normalizedInput, platform) : resolve(baseDir, normalizedInput);
45551
+ return isAbsoluteNormalizedUserPath(normalizedInput, platform) ? resolveAbsolutePath(normalizedInput, platform) : resolve2(baseDir, normalizedInput);
45536
45552
  }
45537
45553
  function normalizeComparablePath(input) {
45538
45554
  return stripTrailingSlashes(normalizeSeparators(resolveUserPath(input)));
@@ -45550,7 +45566,7 @@ function getLookupKey(input, isBareFilename) {
45550
45566
  return isBareFilename ? getLowercaseBasename(input) : input.toLowerCase();
45551
45567
  }
45552
45568
  function resolveAbsolutePath(input, platform = process.platform) {
45553
- return platform === "win32" || hasWindowsDriveLetter(input) ? win32.resolve(input) : resolve(input);
45569
+ return platform === "win32" || hasWindowsDriveLetter(input) ? win32.resolve(input) : resolve2(input);
45554
45570
  }
45555
45571
  function isSearchableMarkdownPath(input) {
45556
45572
  return MARKDOWN_PATH_REGEX.test(input.trim());
@@ -45572,10 +45588,10 @@ function walkFiles(dir, root, results, ignoredDirs, fileMatcher) {
45572
45588
  if (ignoredDirs.some((d) => d === entry.name + "/"))
45573
45589
  continue;
45574
45590
  try {
45575
- walkFiles(join2(dir, entry.name), root, results, ignoredDirs, fileMatcher);
45591
+ walkFiles(join3(dir, entry.name), root, results, ignoredDirs, fileMatcher);
45576
45592
  } catch {}
45577
45593
  } else if (entry.isFile() && fileMatcher(entry.name)) {
45578
- const relative = join2(dir, entry.name).slice(root.length + 1).replace(/\\/g, "/");
45594
+ const relative = join3(dir, entry.name).slice(root.length + 1).replace(/\\/g, "/");
45579
45595
  results.push(relative);
45580
45596
  }
45581
45597
  }
@@ -45626,12 +45642,12 @@ async function resolveCodeFile(input, projectRoot, baseDir) {
45626
45642
  }
45627
45643
  return { kind: "not_found", input: originalInput };
45628
45644
  }
45629
- const fromRoot = resolve(projectRoot, searchInput);
45645
+ const fromRoot = resolve2(projectRoot, searchInput);
45630
45646
  if (isWithinProjectRoot(fromRoot, projectRoot) && fileExists(fromRoot)) {
45631
45647
  return { kind: "found", path: fromRoot };
45632
45648
  }
45633
45649
  if (baseDir) {
45634
- const fromBase = resolve(baseDir, searchInput);
45650
+ const fromBase = resolve2(baseDir, searchInput);
45635
45651
  if (fileExists(fromBase)) {
45636
45652
  return { kind: "found", path: fromBase };
45637
45653
  }
@@ -45652,10 +45668,10 @@ async function resolveCodeFile(input, projectRoot, baseDir) {
45652
45668
  if (isBareFilename) {
45653
45669
  const base = fl.split("/").pop();
45654
45670
  if (base === target)
45655
- matches.push(resolve(projectRoot, f));
45671
+ matches.push(resolve2(projectRoot, f));
45656
45672
  } else {
45657
45673
  if (fl === target || fl.endsWith("/" + target)) {
45658
- matches.push(resolve(projectRoot, f));
45674
+ matches.push(resolve2(projectRoot, f));
45659
45675
  }
45660
45676
  }
45661
45677
  }
@@ -45682,7 +45698,7 @@ function resolveMarkdownFileCore(input, projectRoot) {
45682
45698
  }
45683
45699
  return { kind: "not_found", input };
45684
45700
  }
45685
- const fromRoot = resolve(projectRoot, searchInput);
45701
+ const fromRoot = resolve2(projectRoot, searchInput);
45686
45702
  if (isWithinProjectRoot(fromRoot, projectRoot) && fileExists(fromRoot)) {
45687
45703
  return { kind: "found", path: fromRoot };
45688
45704
  }
@@ -45693,7 +45709,7 @@ function resolveMarkdownFileCore(input, projectRoot) {
45693
45709
  const normalizedMatch = normalizeSeparators(match);
45694
45710
  const matchLookupKey = getLookupKey(normalizedMatch, isBareFilename);
45695
45711
  if (matchLookupKey === targetLookupKey) {
45696
- const full = resolve(projectRoot, normalizedMatch);
45712
+ const full = resolve2(projectRoot, normalizedMatch);
45697
45713
  if (isWithinProjectRoot(full, projectRoot)) {
45698
45714
  matches.push(full);
45699
45715
  }
@@ -45747,7 +45763,7 @@ function hasMarkdownFiles(dirPath, excludedDirs = IGNORED_DIRS, extensions = /\.
45747
45763
  if (entry.isDirectory()) {
45748
45764
  if (excludedDirs.some((d) => d === entry.name + "/"))
45749
45765
  continue;
45750
- if (walk(join2(dir, entry.name)))
45766
+ if (walk(join3(dir, entry.name)))
45751
45767
  return true;
45752
45768
  } else if (entry.isFile() && extensions.test(entry.name)) {
45753
45769
  return true;
@@ -45818,12 +45834,12 @@ async function saveToObsidian(config) {
45818
45834
  };
45819
45835
  }
45820
45836
  const folderName = folder.trim() || "plannotator";
45821
- const targetFolder = join3(normalizedVault, folderName);
45837
+ const targetFolder = join4(normalizedVault, folderName);
45822
45838
  if (!existsSync3(targetFolder)) {
45823
45839
  mkdirSync(targetFolder, { recursive: true });
45824
45840
  }
45825
45841
  const filename = generateFilename(plan, config.filenameFormat, config.filenameSeparator);
45826
- const filePath = join3(targetFolder, filename);
45842
+ const filePath = join4(targetFolder, filename);
45827
45843
  const tags = await extractTags(plan);
45828
45844
  const frontmatter = generateFrontmatter(tags);
45829
45845
  const content = `${frontmatter}
@@ -45879,15 +45895,15 @@ ${plan}`;
45879
45895
  }
45880
45896
 
45881
45897
  // ../../packages/shared/storage.ts
45882
- import { homedir as homedir2 } from "os";
45883
- import { join as join4, resolve as resolve2, sep } from "path";
45898
+ import { join as join5, resolve as resolve3, sep } from "path";
45884
45899
  import { mkdirSync as mkdirSync2, writeFileSync, readFileSync as readFileSync2, readdirSync as readdirSync2, statSync as statSync2, existsSync as existsSync4 } from "fs";
45900
+ var DATA_DIR = getPlannotatorDataDir();
45885
45901
  function getPlanDir(customPath) {
45886
45902
  let planDir;
45887
45903
  if (customPath?.trim()) {
45888
45904
  planDir = resolveUserPath(customPath);
45889
45905
  } else {
45890
- planDir = join4(homedir2(), ".plannotator", "plans");
45906
+ planDir = join5(DATA_DIR, "plans");
45891
45907
  }
45892
45908
  mkdirSync2(planDir, { recursive: true });
45893
45909
  return planDir;
@@ -45906,13 +45922,13 @@ function generateSlug(plan) {
45906
45922
  }
45907
45923
  function saveAnnotations(slug, annotationsContent, customPath) {
45908
45924
  const planDir = getPlanDir(customPath);
45909
- const filePath = join4(planDir, `${slug}.annotations.md`);
45925
+ const filePath = join5(planDir, `${slug}.annotations.md`);
45910
45926
  writeFileSync(filePath, annotationsContent, "utf-8");
45911
45927
  return filePath;
45912
45928
  }
45913
45929
  function saveFinalSnapshot(slug, status, plan, annotations, customPath) {
45914
45930
  const planDir = getPlanDir(customPath);
45915
- const filePath = join4(planDir, `${slug}-${status}.md`);
45931
+ const filePath = join5(planDir, `${slug}-${status}.md`);
45916
45932
  let content = plan;
45917
45933
  if (annotations && annotations !== "No changes detected.") {
45918
45934
  content += `
@@ -45956,7 +45972,7 @@ function listArchivedPlans(customPath) {
45956
45972
  if (!parsed)
45957
45973
  continue;
45958
45974
  try {
45959
- const stat = statSync2(join4(planDir, entry));
45975
+ const stat = statSync2(join5(planDir, entry));
45960
45976
  parsed.size = stat.size;
45961
45977
  parsed.timestamp = stat.mtime.toISOString();
45962
45978
  } catch {}
@@ -45969,7 +45985,7 @@ function listArchivedPlans(customPath) {
45969
45985
  }
45970
45986
  function readArchivedPlan(filename, customPath) {
45971
45987
  const planDir = getPlanDir(customPath);
45972
- const filePath = resolve2(planDir, filename);
45988
+ const filePath = resolve3(planDir, filename);
45973
45989
  if (!filePath.startsWith(planDir + sep))
45974
45990
  return null;
45975
45991
  try {
@@ -45979,7 +45995,7 @@ function readArchivedPlan(filename, customPath) {
45979
45995
  }
45980
45996
  }
45981
45997
  function getHistoryDir(project, slug) {
45982
- const historyDir = join4(homedir2(), ".plannotator", "history", project, slug);
45998
+ const historyDir = join5(DATA_DIR, "history", project, slug);
45983
45999
  mkdirSync2(historyDir, { recursive: true });
45984
46000
  return historyDir;
45985
46001
  }
@@ -46004,7 +46020,7 @@ function saveToHistory(project, slug, plan) {
46004
46020
  const historyDir = getHistoryDir(project, slug);
46005
46021
  const nextVersion = getNextVersionNumber(historyDir);
46006
46022
  if (nextVersion > 1) {
46007
- const latestPath = join4(historyDir, `${String(nextVersion - 1).padStart(3, "0")}.md`);
46023
+ const latestPath = join5(historyDir, `${String(nextVersion - 1).padStart(3, "0")}.md`);
46008
46024
  try {
46009
46025
  const existing = readFileSync2(latestPath, "utf-8");
46010
46026
  if (existing === plan) {
@@ -46013,14 +46029,14 @@ function saveToHistory(project, slug, plan) {
46013
46029
  } catch {}
46014
46030
  }
46015
46031
  const fileName = `${String(nextVersion).padStart(3, "0")}.md`;
46016
- const filePath = join4(historyDir, fileName);
46032
+ const filePath = join5(historyDir, fileName);
46017
46033
  writeFileSync(filePath, plan, "utf-8");
46018
46034
  return { version: nextVersion, path: filePath, isNew: true };
46019
46035
  }
46020
46036
  function getPlanVersion(project, slug, version) {
46021
- const historyDir = join4(homedir2(), ".plannotator", "history", project, slug);
46037
+ const historyDir = join5(DATA_DIR, "history", project, slug);
46022
46038
  const fileName = `${String(version).padStart(3, "0")}.md`;
46023
- const filePath = join4(historyDir, fileName);
46039
+ const filePath = join5(historyDir, fileName);
46024
46040
  try {
46025
46041
  return readFileSync2(filePath, "utf-8");
46026
46042
  } catch {
@@ -46028,13 +46044,13 @@ function getPlanVersion(project, slug, version) {
46028
46044
  }
46029
46045
  }
46030
46046
  function getPlanVersionPath(project, slug, version) {
46031
- const historyDir = join4(homedir2(), ".plannotator", "history", project, slug);
46047
+ const historyDir = join5(DATA_DIR, "history", project, slug);
46032
46048
  const fileName = `${String(version).padStart(3, "0")}.md`;
46033
- const filePath = join4(historyDir, fileName);
46049
+ const filePath = join5(historyDir, fileName);
46034
46050
  return existsSync4(filePath) ? filePath : null;
46035
46051
  }
46036
46052
  function getVersionCount(project, slug) {
46037
- const historyDir = join4(homedir2(), ".plannotator", "history", project, slug);
46053
+ const historyDir = join5(DATA_DIR, "history", project, slug);
46038
46054
  try {
46039
46055
  const entries = readdirSync2(historyDir);
46040
46056
  return entries.filter((e) => /^\d+\.md$/.test(e)).length;
@@ -46043,7 +46059,7 @@ function getVersionCount(project, slug) {
46043
46059
  }
46044
46060
  }
46045
46061
  function listVersions(project, slug) {
46046
- const historyDir = join4(homedir2(), ".plannotator", "history", project, slug);
46062
+ const historyDir = join5(DATA_DIR, "history", project, slug);
46047
46063
  try {
46048
46064
  const entries = readdirSync2(historyDir);
46049
46065
  const versions = [];
@@ -46051,7 +46067,7 @@ function listVersions(project, slug) {
46051
46067
  const match = entry.match(/^(\d+)\.md$/);
46052
46068
  if (match) {
46053
46069
  const version = parseInt(match[1], 10);
46054
- const filePath = join4(historyDir, entry);
46070
+ const filePath = join5(historyDir, entry);
46055
46071
  try {
46056
46072
  const stat = statSync2(filePath);
46057
46073
  versions.push({ version, timestamp: stat.mtime.toISOString() });
@@ -46154,8 +46170,7 @@ async function getRepoInfo() {
46154
46170
  }
46155
46171
 
46156
46172
  // ../../packages/shared/config.ts
46157
- import { homedir as homedir3 } from "os";
46158
- import { join as join5 } from "path";
46173
+ import { join as join6 } from "path";
46159
46174
  import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync3, existsSync as existsSync5 } from "fs";
46160
46175
  import { execSync } from "child_process";
46161
46176
  var PROMPT_SECTIONS = ["review", "plan", "annotate"];
@@ -46176,8 +46191,8 @@ function mergePromptConfig(current, partial) {
46176
46191
  }
46177
46192
  return result;
46178
46193
  }
46179
- var CONFIG_DIR = join5(homedir3(), ".plannotator");
46180
- var CONFIG_PATH = join5(CONFIG_DIR, "config.json");
46194
+ var CONFIG_DIR = getPlannotatorDataDir();
46195
+ var CONFIG_PATH = join6(CONFIG_DIR, "config.json");
46181
46196
  function loadConfig() {
46182
46197
  try {
46183
46198
  if (!existsSync5(CONFIG_PATH))
@@ -46246,11 +46261,11 @@ function resolveUseJina(cliNoJina, config) {
46246
46261
  return true;
46247
46262
  }
46248
46263
  // ../../packages/shared/improvement-hooks.ts
46249
- import { homedir as homedir4 } from "os";
46250
- import { join as join6 } from "path";
46264
+ import { join as join7 } from "path";
46251
46265
  import { readFileSync as readFileSync4, statSync as statSync3 } from "fs";
46252
- var HOOKS_BASE_DIR = join6(homedir4(), ".plannotator", "hooks");
46253
- var LEGACY_BASE_DIR = join6(homedir4(), ".plannotator");
46266
+ var DATA_DIR2 = getPlannotatorDataDir();
46267
+ var HOOKS_BASE_DIR = join7(DATA_DIR2, "hooks");
46268
+ var LEGACY_BASE_DIR = DATA_DIR2;
46254
46269
  var MAX_FILE_SIZE = 50 * 1024;
46255
46270
  var KNOWN_HOOKS = {
46256
46271
  "enterplanmode-improve": {
@@ -46262,7 +46277,7 @@ function getImprovementHookExpectedPath(hookName) {
46262
46277
  const entry = KNOWN_HOOKS[hookName];
46263
46278
  if (!entry)
46264
46279
  return null;
46265
- return join6(HOOKS_BASE_DIR, entry.path);
46280
+ return join7(HOOKS_BASE_DIR, entry.path);
46266
46281
  }
46267
46282
  function fileExists2(path) {
46268
46283
  try {
@@ -46289,11 +46304,11 @@ function readImprovementHook(hookName) {
46289
46304
  const entry = KNOWN_HOOKS[hookName];
46290
46305
  if (!entry)
46291
46306
  return null;
46292
- const newPath = join6(HOOKS_BASE_DIR, entry.path);
46307
+ const newPath = join7(HOOKS_BASE_DIR, entry.path);
46293
46308
  if (fileExists2(newPath)) {
46294
46309
  return tryReadHookFile(newPath, hookName);
46295
46310
  }
46296
- const legacyFilePath = join6(LEGACY_BASE_DIR, entry.legacyPath);
46311
+ const legacyFilePath = join7(LEGACY_BASE_DIR, entry.legacyPath);
46297
46312
  return tryReadHookFile(legacyFilePath, hookName);
46298
46313
  }
46299
46314
 
@@ -46362,14 +46377,15 @@ Other extras
46362
46377
  Plain prose is always fine. The point is: prefer code-file links over copy-pasted snippets, and reach for callouts or tables when structure makes the plan easier to scan.`;
46363
46378
 
46364
46379
  // ../../packages/server/shared-handlers.ts
46365
- import { mkdirSync as mkdirSync5 } from "fs";
46380
+ import { appendFileSync, mkdirSync as mkdirSync5 } from "fs";
46381
+ import { dirname } from "path";
46366
46382
 
46367
46383
  // ../../packages/server/browser.ts
46368
46384
  var {$: $4 } = globalThis.Bun;
46369
46385
  import os from "os";
46370
46386
  import path from "path";
46371
46387
  import fs from "fs";
46372
- var IPC_REGISTRY = path.join(os.homedir(), ".plannotator", "vscode-ipc.json");
46388
+ var IPC_REGISTRY = path.join(getPlannotatorDataDir(), "vscode-ipc.json");
46373
46389
  var NOOP_BROWSER_VALUES = new Set(["true", "false", "none", ":", "0", "1"]);
46374
46390
  function isNoOpBrowserSentinel(value) {
46375
46391
  if (!value)
@@ -46465,7 +46481,7 @@ async function openBrowser(url, options) {
46465
46481
  }
46466
46482
 
46467
46483
  // ../../packages/server/image.ts
46468
- import { resolve as resolve3, join as join7 } from "path";
46484
+ import { resolve as resolve4, join as join8 } from "path";
46469
46485
  import { tmpdir } from "os";
46470
46486
  var ALLOWED_IMAGE_EXTENSIONS = new Set([
46471
46487
  "png",
@@ -46480,7 +46496,7 @@ var ALLOWED_IMAGE_EXTENSIONS = new Set([
46480
46496
  "tif",
46481
46497
  "avif"
46482
46498
  ]);
46483
- var UPLOAD_DIR = join7(tmpdir(), "plannotator");
46499
+ var UPLOAD_DIR = join8(tmpdir(), "plannotator");
46484
46500
  function getExtension(filePath) {
46485
46501
  const lastDot = filePath.lastIndexOf(".");
46486
46502
  if (lastDot === -1)
@@ -46491,7 +46507,7 @@ function hasImageExtension(filePath) {
46491
46507
  return ALLOWED_IMAGE_EXTENSIONS.has(getExtension(filePath));
46492
46508
  }
46493
46509
  function validateImagePath(rawPath) {
46494
- const resolved = resolve3(rawPath);
46510
+ const resolved = resolve4(rawPath);
46495
46511
  if (!hasImageExtension(resolved)) {
46496
46512
  return {
46497
46513
  valid: false,
@@ -46514,12 +46530,11 @@ function validateUploadExtension(fileName) {
46514
46530
  }
46515
46531
 
46516
46532
  // ../../packages/shared/draft.ts
46517
- import { homedir as homedir5 } from "os";
46518
- import { join as join8 } from "path";
46533
+ import { join as join9 } from "path";
46519
46534
  import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync3, readFileSync as readFileSync5, unlinkSync, existsSync as existsSync6 } from "fs";
46520
46535
  import { createHash } from "crypto";
46521
46536
  function getDraftDir() {
46522
- const dir = join8(homedir5(), ".plannotator", "drafts");
46537
+ const dir = join9(getPlannotatorDataDir(), "drafts");
46523
46538
  mkdirSync4(dir, { recursive: true });
46524
46539
  return dir;
46525
46540
  }
@@ -46528,10 +46543,10 @@ function contentHash(content) {
46528
46543
  }
46529
46544
  function saveDraft(key, data) {
46530
46545
  const dir = getDraftDir();
46531
- writeFileSync3(join8(dir, `${key}.json`), JSON.stringify(data), "utf-8");
46546
+ writeFileSync3(join9(dir, `${key}.json`), JSON.stringify(data), "utf-8");
46532
46547
  }
46533
46548
  function loadDraft(key) {
46534
- const filePath = join8(getDraftDir(), `${key}.json`);
46549
+ const filePath = join9(getDraftDir(), `${key}.json`);
46535
46550
  try {
46536
46551
  if (!existsSync6(filePath))
46537
46552
  return null;
@@ -46541,7 +46556,7 @@ function loadDraft(key) {
46541
46556
  }
46542
46557
  }
46543
46558
  function deleteDraft(key) {
46544
- const filePath = join8(getDraftDir(), `${key}.json`);
46559
+ const filePath = join9(getDraftDir(), `${key}.json`);
46545
46560
  try {
46546
46561
  if (existsSync6(filePath))
46547
46562
  unlinkSync(filePath);
@@ -46646,13 +46661,30 @@ function handleFavicon() {
46646
46661
  headers: { "Content-Type": "image/svg+xml", "Cache-Control": "public, max-age=86400" }
46647
46662
  });
46648
46663
  }
46649
- async function handleServerReady(url, isRemote, _port) {
46650
- await openBrowser(url, { isRemote });
46664
+ function writeServerReadyMetadata(readyFile, metadata) {
46665
+ mkdirSync5(dirname(readyFile), { recursive: true });
46666
+ appendFileSync(readyFile, `${JSON.stringify(metadata)}
46667
+ `, "utf8");
46668
+ }
46669
+ async function handleServerReady(url, isRemote, port, options = {}) {
46670
+ const readyFile = options.readyFile ?? process.env.PLANNOTATOR_READY_FILE;
46671
+ if (readyFile) {
46672
+ try {
46673
+ writeServerReadyMetadata(readyFile, { url, isRemote, port });
46674
+ } catch (error) {
46675
+ if (options.readyFile)
46676
+ throw error;
46677
+ }
46678
+ }
46679
+ const skipBrowserOpen = options.skipBrowserOpen ?? process.env.PLANNOTATOR_SKIP_BROWSER_OPEN === "1";
46680
+ if (skipBrowserOpen)
46681
+ return;
46682
+ await (options.openBrowser ?? openBrowser)(url, { isRemote });
46651
46683
  }
46652
46684
 
46653
46685
  // ../../packages/server/reference-handlers.ts
46654
46686
  import { existsSync as existsSync7, statSync as statSync4 } from "fs";
46655
- import { resolve as resolve4 } from "path";
46687
+ import { resolve as resolve5 } from "path";
46656
46688
 
46657
46689
  // ../../packages/shared/reference-common.ts
46658
46690
  var FILE_BROWSER_EXCLUDED = [
@@ -47359,14 +47391,14 @@ function process2(parentNode) {
47359
47391
  } else if (node.nodeType === 1) {
47360
47392
  replacement = replacementForNode.call(self2, node);
47361
47393
  }
47362
- return join9(output, replacement);
47394
+ return join10(output, replacement);
47363
47395
  }, "");
47364
47396
  }
47365
47397
  function postProcess(output) {
47366
47398
  var self2 = this;
47367
47399
  this.rules.forEach(function(rule) {
47368
47400
  if (typeof rule.append === "function") {
47369
- output = join9(output, rule.append(self2.options));
47401
+ output = join10(output, rule.append(self2.options));
47370
47402
  }
47371
47403
  });
47372
47404
  return output.replace(/^[\t\r\n]+/, "").replace(/[\t\r\n\s]+$/, "");
@@ -47379,7 +47411,7 @@ function replacementForNode(node) {
47379
47411
  content = content.trim();
47380
47412
  return whitespace.leading + rule.replacement(content, node, this.options) + whitespace.trailing;
47381
47413
  }
47382
- function join9(output, replacement) {
47414
+ function join10(output, replacement) {
47383
47415
  var s1 = trimTrailingNewlines(output);
47384
47416
  var s2 = trimLeadingNewlines(replacement);
47385
47417
  var nls = Math.max(output.length - s1.length, replacement.length - s2.length);
@@ -61294,7 +61326,7 @@ async function handleObsidianDoc(req) {
61294
61326
  return Response.json({ error: "Only markdown files are supported" }, { status: 400 });
61295
61327
  }
61296
61328
  const resolvedVault = resolveUserPath(vaultPath);
61297
- let resolvedFile = resolve4(resolvedVault, filePath);
61329
+ let resolvedFile = resolve5(resolvedVault, filePath);
61298
61330
  if (!existsSync7(resolvedFile) && !filePath.includes("/")) {
61299
61331
  const glob = new Bun.Glob(`**/${filePath}`);
61300
61332
  const matches2 = [];
@@ -61304,7 +61336,7 @@ async function handleObsidianDoc(req) {
61304
61336
  })) {
61305
61337
  if (match.includes(".obsidian/") || match.includes(".trash/"))
61306
61338
  continue;
61307
- matches2.push(resolve4(resolvedVault, match));
61339
+ matches2.push(resolve5(resolvedVault, match));
61308
61340
  }
61309
61341
  if (matches2.length === 1) {
61310
61342
  resolvedFile = matches2[0];
@@ -62112,8 +62144,8 @@ async function startPlannotatorServer(options) {
62112
62144
  if (mode === "archive") {
62113
62145
  archivePlans = listArchivedPlans(customPlanPath ?? undefined);
62114
62146
  initialArchivePlan = archivePlans.length > 0 ? readArchivedPlan(archivePlans[0].filename, customPlanPath ?? undefined) ?? "" : "";
62115
- donePromise = new Promise((resolve5) => {
62116
- resolveDone = resolve5;
62147
+ donePromise = new Promise((resolve6) => {
62148
+ resolveDone = resolve6;
62117
62149
  });
62118
62150
  }
62119
62151
  const draftKey = mode !== "archive" ? contentHash(plan) : "";
@@ -62140,8 +62172,8 @@ async function startPlannotatorServer(options) {
62140
62172
  totalVersions: getVersionCount(project, slug),
62141
62173
  project
62142
62174
  };
62143
- decisionPromise = new Promise((resolve5) => {
62144
- resolveDecision = resolve5;
62175
+ decisionPromise = new Promise((resolve6) => {
62176
+ resolveDecision = resolve6;
62145
62177
  });
62146
62178
  } else {
62147
62179
  decisionPromise = new Promise(() => {});
@@ -62977,7 +63009,7 @@ function parseP4DiffType(diffType) {
62977
63009
  }
62978
63010
 
62979
63011
  // ../../packages/shared/vcs-core.ts
62980
- import { isAbsolute as isAbsolute2, relative, resolve as resolve5 } from "path";
63012
+ import { isAbsolute as isAbsolute2, relative, resolve as resolve6 } from "path";
62981
63013
 
62982
63014
  // ../../packages/shared/jj-core.ts
62983
63015
  import { basename as basename2 } from "path";
@@ -63305,7 +63337,7 @@ var JJ_DIFF_TYPES = new Set(["jj-current", "jj-last", "jj-line", "jj-evolog", "j
63305
63337
  function selectNearestProvider(candidates, cwd) {
63306
63338
  if (candidates.length === 0)
63307
63339
  return null;
63308
- const effectiveCwd = resolve5(cwd ?? process.cwd());
63340
+ const effectiveCwd = resolve6(cwd ?? process.cwd());
63309
63341
  const ranked = candidates.map((candidate) => ({
63310
63342
  ...candidate,
63311
63343
  rootDepth: candidate.root ? vcsRootDepth(candidate.root) : -1,
@@ -63320,11 +63352,11 @@ function selectNearestProvider(candidates, cwd) {
63320
63352
  return ranked[0]?.provider ?? null;
63321
63353
  }
63322
63354
  function isSameOrAncestor(root3, child) {
63323
- const relativePath = relative(resolve5(root3), child);
63355
+ const relativePath = relative(resolve6(root3), child);
63324
63356
  return relativePath === "" || !relativePath.startsWith("..") && !isAbsolute2(relativePath);
63325
63357
  }
63326
63358
  function vcsRootDepth(root3) {
63327
- return resolve5(root3).split(/[\\/]+/).filter(Boolean).length;
63359
+ return resolve6(root3).split(/[\\/]+/).filter(Boolean).length;
63328
63360
  }
63329
63361
  function createGitProvider(runtime) {
63330
63362
  return {
@@ -64719,17 +64751,18 @@ function createAgentJobHandler(options) {
64719
64751
  }
64720
64752
 
64721
64753
  // ../../packages/server/codex-review.ts
64722
- import { join as join10 } from "path";
64723
- import { homedir as homedir6, tmpdir as tmpdir2 } from "os";
64754
+ import { join as join11 } from "path";
64755
+ import { tmpdir as tmpdir2 } from "os";
64724
64756
  import { appendFile, mkdir, unlink, writeFile, readFile } from "fs/promises";
64725
64757
  import { existsSync as existsSync10 } from "fs";
64758
+ var DATA_DIR3 = getPlannotatorDataDir();
64726
64759
  var DEBUG_ENABLED = !!process.env.PLANNOTATOR_DEBUG;
64727
- var DEBUG_LOG_PATH = join10(homedir6(), ".plannotator", "codex-review-debug.log");
64760
+ var DEBUG_LOG_PATH = join11(DATA_DIR3, "codex-review-debug.log");
64728
64761
  async function debugLog(label, data) {
64729
64762
  if (!DEBUG_ENABLED)
64730
64763
  return;
64731
64764
  try {
64732
- await mkdir(join10(homedir6(), ".plannotator"), { recursive: true });
64765
+ await mkdir(DATA_DIR3, { recursive: true });
64733
64766
  const timestamp = new Date().toISOString();
64734
64767
  const line = data !== undefined ? `[${timestamp}] ${label}: ${typeof data === "string" ? data : JSON.stringify(data, null, 2)}
64735
64768
  ` : `[${timestamp}] ${label}
@@ -64778,8 +64811,8 @@ var CODEX_REVIEW_SCHEMA = JSON.stringify({
64778
64811
  required: ["findings", "overall_correctness", "overall_explanation", "overall_confidence_score"],
64779
64812
  additionalProperties: false
64780
64813
  });
64781
- var SCHEMA_DIR = join10(homedir6(), ".plannotator");
64782
- var SCHEMA_FILE = join10(SCHEMA_DIR, "codex-review-schema.json");
64814
+ var SCHEMA_DIR = DATA_DIR3;
64815
+ var SCHEMA_FILE = join11(SCHEMA_DIR, "codex-review-schema.json");
64783
64816
  var schemaMaterialized = false;
64784
64817
  async function ensureSchemaFile() {
64785
64818
  if (!schemaMaterialized) {
@@ -64875,7 +64908,7 @@ async function buildCodexCommand(options) {
64875
64908
  return command;
64876
64909
  }
64877
64910
  function generateOutputPath() {
64878
- return join10(tmpdir2(), `plannotator-codex-${crypto.randomUUID()}.json`);
64911
+ return join11(tmpdir2(), `plannotator-codex-${crypto.randomUUID()}.json`);
64879
64912
  }
64880
64913
  async function parseCodexOutput(outputPath) {
64881
64914
  await debugLog("PARSE_OUTPUT_START", { outputPath });
@@ -65064,8 +65097,8 @@ function shellQuote(value) {
65064
65097
  }
65065
65098
 
65066
65099
  // ../../packages/server/tour/tour-review.ts
65067
- import { join as join11 } from "path";
65068
- import { homedir as homedir7, tmpdir as tmpdir3 } from "os";
65100
+ import { join as join12 } from "path";
65101
+ import { tmpdir as tmpdir3 } from "os";
65069
65102
  import { mkdir as mkdir2, writeFile as writeFile2, readFile as readFile2, unlink as unlink2 } from "fs/promises";
65070
65103
  var TOUR_EMPTY_OUTPUT_ERROR = "Tour generation returned empty or malformed output";
65071
65104
  var TOUR_SCHEMA_JSON = JSON.stringify({
@@ -65459,8 +65492,8 @@ function buildTourClaudeCommand(prompt, model = "sonnet", effort) {
65459
65492
  stdinPrompt: prompt
65460
65493
  };
65461
65494
  }
65462
- var TOUR_SCHEMA_DIR = join11(homedir7(), ".plannotator");
65463
- var TOUR_SCHEMA_FILE = join11(TOUR_SCHEMA_DIR, "tour-schema.json");
65495
+ var TOUR_SCHEMA_DIR = getPlannotatorDataDir();
65496
+ var TOUR_SCHEMA_FILE = join12(TOUR_SCHEMA_DIR, "tour-schema.json");
65464
65497
  var tourSchemaMaterialized = false;
65465
65498
  async function ensureTourSchemaFile() {
65466
65499
  if (!tourSchemaMaterialized) {
@@ -65471,7 +65504,7 @@ async function ensureTourSchemaFile() {
65471
65504
  return TOUR_SCHEMA_FILE;
65472
65505
  }
65473
65506
  function generateTourOutputPath() {
65474
- return join11(tmpdir3(), `plannotator-tour-${crypto.randomUUID()}.json`);
65507
+ return join12(tmpdir3(), `plannotator-tour-${crypto.randomUUID()}.json`);
65475
65508
  }
65476
65509
  async function buildTourCodexCommand(options) {
65477
65510
  const { cwd, outputPath, prompt, model, reasoningEffort, fastMode } = options;
@@ -66144,8 +66177,7 @@ async function fetchGhPRList(runtime3, ref) {
66144
66177
  }
66145
66178
 
66146
66179
  // ../../packages/shared/pr-gitlab.ts
66147
- import { homedir as homedir8 } from "os";
66148
- import { join as join12 } from "path";
66180
+ import { join as join13 } from "path";
66149
66181
  import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync4 } from "fs";
66150
66182
  function encodeProject(projectPath) {
66151
66183
  return encodeURIComponent(projectPath);
@@ -66527,10 +66559,10 @@ async function submitGlMRReview(runtime3, ref, headSha, action, body3, fileComme
66527
66559
  const failed = results.map((r9, i4) => r9.status === "rejected" ? fileComments[i4] : null).filter((c3) => c3 !== null);
66528
66560
  let savedTo = null;
66529
66561
  try {
66530
- const dir = join12(homedir8(), ".plannotator", "failed-comments");
66562
+ const dir = join13(getPlannotatorDataDir(), "failed-comments");
66531
66563
  mkdirSync7(dir, { recursive: true });
66532
66564
  const slug = `${ref.host}-${ref.projectPath.replace(/\//g, "_")}-mr${ref.iid}-${Date.now()}`;
66533
- savedTo = join12(dir, `${slug}.json`);
66565
+ savedTo = join13(dir, `${slug}.json`);
66534
66566
  writeFileSync4(savedTo, JSON.stringify({ ref, headSha, baseSha, startSha, errors, failedComments: failed }, null, 2));
66535
66567
  } catch (writeErr) {
66536
66568
  console.error(`[plannotator] Failed to persist unposted comments: ${writeErr instanceof Error ? writeErr.message : String(writeErr)}`);
@@ -67183,8 +67215,8 @@ async function startReviewServer(options) {
67183
67215
  } catch {}
67184
67216
  }
67185
67217
  let resolveDecision;
67186
- const decisionPromise = new Promise((resolve6) => {
67187
- resolveDecision = resolve6;
67218
+ const decisionPromise = new Promise((resolve7) => {
67219
+ resolveDecision = resolve7;
67188
67220
  });
67189
67221
  let server2 = null;
67190
67222
  for (let attempt = 1;attempt <= MAX_RETRIES2; attempt++) {
@@ -67722,7 +67754,7 @@ async function startReviewServer(options) {
67722
67754
  }
67723
67755
 
67724
67756
  // ../../packages/server/annotate.ts
67725
- import { dirname, resolve as resolvePath2 } from "path";
67757
+ import { dirname as dirname2, resolve as resolvePath2 } from "path";
67726
67758
  var MAX_RETRIES3 = 5;
67727
67759
  var RETRY_DELAY_MS3 = 500;
67728
67760
  async function startAnnotateServer(options) {
@@ -67754,8 +67786,8 @@ async function startAnnotateServer(options) {
67754
67786
  const aiRuntime = await createAIRuntime();
67755
67787
  const repoInfo = await getRepoInfo();
67756
67788
  let resolveDecision;
67757
- const decisionPromise = new Promise((resolve6) => {
67758
- resolveDecision = resolve6;
67789
+ const decisionPromise = new Promise((resolve7) => {
67790
+ resolveDecision = resolve7;
67759
67791
  });
67760
67792
  let server2 = null;
67761
67793
  for (let attempt = 1;attempt <= MAX_RETRIES3; attempt++) {
@@ -67810,7 +67842,7 @@ async function startAnnotateServer(options) {
67810
67842
  if (url.pathname === "/api/doc" && req.method === "GET") {
67811
67843
  if (!url.searchParams.has("base") && !/^https?:\/\//i.test(filePath)) {
67812
67844
  const docUrl = new URL(req.url);
67813
- docUrl.searchParams.set("base", dirname(filePath));
67845
+ docUrl.searchParams.set("base", dirname2(filePath));
67814
67846
  return handleDoc(new Request(docUrl.toString()));
67815
67847
  }
67816
67848
  return handleDoc(req);
@@ -67933,6 +67965,7 @@ function resolveTemplate(template, vars) {
67933
67965
  }
67934
67966
  var PLAN_TOOL_NAMES = {
67935
67967
  "claude-code": "ExitPlanMode",
67968
+ amp: "ExitPlanMode",
67936
67969
  droid: "ExitPlanMode",
67937
67970
  opencode: "submit_plan",
67938
67971
  "copilot-cli": "exit_plan_mode",
@@ -68957,7 +68990,7 @@ function getReviewHtml() {
68957
68990
  var DEFAULT_PLAN_TIMEOUT_SECONDS = 345600;
68958
68991
  var MAX_PLAN_SIZE = 5 * 1024 * 1024;
68959
68992
  function getPlanBackingPath(project) {
68960
- return path4.join(homedir9(), ".plannotator", "active", project, "_active-plan.md");
68993
+ return path4.join(getPlannotatorDataDir(), "active", project, "_active-plan.md");
68961
68994
  }
68962
68995
  function applyEdits(existingLines, edits) {
68963
68996
  const sorted = [...edits].sort((a3, b3) => a3.start - b3.start);
@@ -69322,14 +69355,14 @@ Use /plannotator-last or /plannotator-annotate for manual review, or set workflo
69322
69355
  });
69323
69356
  const timeoutSeconds = getPlanTimeoutSeconds();
69324
69357
  const timeoutMs = timeoutSeconds === null ? null : timeoutSeconds * 1000;
69325
- const result = timeoutMs === null ? await server2.waitForDecision() : await new Promise((resolve6) => {
69326
- const timeoutId = setTimeout(() => resolve6({
69358
+ const result = timeoutMs === null ? await server2.waitForDecision() : await new Promise((resolve7) => {
69359
+ const timeoutId = setTimeout(() => resolve7({
69327
69360
  approved: false,
69328
69361
  feedback: `[Plannotator] No response within ${timeoutSeconds} seconds. Port released automatically. Please call submit_plan again.`
69329
69362
  }), timeoutMs);
69330
69363
  server2.waitForDecision().then((r9) => {
69331
69364
  clearTimeout(timeoutId);
69332
- resolve6(r9);
69365
+ resolve7(r9);
69333
69366
  });
69334
69367
  });
69335
69368
  await Bun.sleep(1500);