md-annotator-opencode 0.5.8 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/annotator.html +627 -441
  2. package/dist/index.js +137 -35
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -42,7 +42,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
42
42
  // ../../node_modules/depd/index.js
43
43
  var require_depd = __commonJS({
44
44
  "../../node_modules/depd/index.js"(exports, module) {
45
- var relative2 = __require("path").relative;
45
+ var relative3 = __require("path").relative;
46
46
  module.exports = depd;
47
47
  var basePath = process.cwd();
48
48
  function containsNamespace(str, namespace) {
@@ -234,7 +234,7 @@ var require_depd = __commonJS({
234
234
  return formatted;
235
235
  }
236
236
  function formatLocation(callSite) {
237
- return relative2(basePath, callSite[0]) + ":" + callSite[1] + ":" + callSite[2];
237
+ return relative3(basePath, callSite[0]) + ":" + callSite[1] + ":" + callSite[2];
238
238
  }
239
239
  function getStack() {
240
240
  var limit = Error.stackTraceLimit;
@@ -19262,7 +19262,7 @@ var require_view = __commonJS({
19262
19262
  var dirname4 = path2.dirname;
19263
19263
  var basename = path2.basename;
19264
19264
  var extname2 = path2.extname;
19265
- var join3 = path2.join;
19265
+ var join4 = path2.join;
19266
19266
  var resolve3 = path2.resolve;
19267
19267
  module.exports = View;
19268
19268
  function View(name, options) {
@@ -19310,12 +19310,12 @@ var require_view = __commonJS({
19310
19310
  };
19311
19311
  View.prototype.resolve = function resolve4(dir2, file) {
19312
19312
  var ext = this.ext;
19313
- var path3 = join3(dir2, file);
19313
+ var path3 = join4(dir2, file);
19314
19314
  var stat = tryStat(path3);
19315
19315
  if (stat && stat.isFile()) {
19316
19316
  return path3;
19317
19317
  }
19318
- path3 = join3(dir2, basename(file, ext), "index" + ext);
19318
+ path3 = join4(dir2, basename(file, ext), "index" + ext);
19319
19319
  stat = tryStat(path3);
19320
19320
  if (stat && stat.isFile()) {
19321
19321
  return path3;
@@ -20372,7 +20372,7 @@ var require_send = __commonJS({
20372
20372
  var Stream = __require("stream");
20373
20373
  var util = __require("util");
20374
20374
  var extname2 = path2.extname;
20375
- var join3 = path2.join;
20375
+ var join4 = path2.join;
20376
20376
  var normalize = path2.normalize;
20377
20377
  var resolve3 = path2.resolve;
20378
20378
  var sep = path2.sep;
@@ -20591,7 +20591,7 @@ var require_send = __commonJS({
20591
20591
  return res;
20592
20592
  }
20593
20593
  parts = path3.split(sep);
20594
- path3 = normalize(join3(root, path3));
20594
+ path3 = normalize(join4(root, path3));
20595
20595
  } else {
20596
20596
  if (UP_PATH_REGEXP.test(path3)) {
20597
20597
  debug('malicious path "%s"', path3);
@@ -20726,7 +20726,7 @@ var require_send = __commonJS({
20726
20726
  if (err) return self.onStatError(err);
20727
20727
  return self.error(404);
20728
20728
  }
20729
- var p = join3(path3, self._index[i]);
20729
+ var p = join4(path3, self._index[i]);
20730
20730
  debug('stat "%s"', p);
20731
20731
  fs6.stat(p, function(err2, stat) {
20732
20732
  if (err2) return next(err2);
@@ -26930,7 +26930,7 @@ var require_portfinder = __commonJS({
26930
26930
  // index.ts
26931
26931
  import { tool } from "@opencode-ai/plugin";
26932
26932
  import { readFileSync } from "fs";
26933
- import { dirname as dirname3, join as join2 } from "path";
26933
+ import { dirname as dirname3, join as join3 } from "path";
26934
26934
  import { fileURLToPath as fileURLToPath3 } from "url";
26935
26935
 
26936
26936
  // ../../server/annotator.js
@@ -26940,7 +26940,7 @@ var import_portfinder = __toESM(require_portfinder(), 1);
26940
26940
  import { existsSync } from "fs";
26941
26941
  import { createHash as createHash2 } from "crypto";
26942
26942
  import { fileURLToPath } from "url";
26943
- import { dirname as dirname2, join } from "path";
26943
+ import { dirname as dirname2, join as join2 } from "path";
26944
26944
 
26945
26945
  // ../../server/config.js
26946
26946
  var DEFAULT_PORT = 3e3;
@@ -26965,17 +26965,33 @@ function getHeartbeatTimeoutMs() {
26965
26965
  }
26966
26966
  return DEFAULT_HEARTBEAT_TIMEOUT_MS;
26967
26967
  }
26968
+ function getPlantumlServerUrl() {
26969
+ const envUrl = process.env.PLANTUML_SERVER_URL;
26970
+ if (envUrl) {
26971
+ return envUrl.replace(/\/+$/, "");
26972
+ }
26973
+ return "https://www.plantuml.com/plantuml";
26974
+ }
26975
+ function getKrokiServerUrl() {
26976
+ const envUrl = process.env.KROKI_SERVER_URL;
26977
+ if (envUrl) {
26978
+ return envUrl.replace(/\/+$/, "");
26979
+ }
26980
+ return "https://kroki.io";
26981
+ }
26968
26982
  var config = {
26969
26983
  port: getServerPort(),
26970
26984
  browser: process.env.MD_ANNOTATOR_BROWSER || null,
26971
26985
  heartbeatTimeoutMs: getHeartbeatTimeoutMs(),
26972
26986
  forceExitTimeoutMs: 5e3,
26973
- jsonLimit: "10mb"
26987
+ jsonLimit: "10mb",
26988
+ plantumlServerUrl: getPlantumlServerUrl(),
26989
+ krokiServerUrl: getKrokiServerUrl()
26974
26990
  };
26975
26991
 
26976
26992
  // ../../server/routes.js
26977
26993
  var import_express = __toESM(require_express2(), 1);
26978
- import { relative, resolve as resolve2, dirname, isAbsolute } from "path";
26994
+ import { relative as relative2, resolve as resolve2, dirname, isAbsolute } from "path";
26979
26995
  import { createHash } from "crypto";
26980
26996
 
26981
26997
  // ../../server/file.js
@@ -27028,16 +27044,37 @@ function formatAnnotation(ann, block, heading) {
27028
27044
  `;
27029
27045
  } else {
27030
27046
  output2 += `> ${(ann.text ?? "").replace(/\n/g, "\n> ")}
27047
+ `;
27048
+ }
27049
+ return output2 + "\n";
27050
+ }
27051
+ if (ann.targetType === "pinpoint") {
27052
+ const isDeletion = ann.type === "DELETION";
27053
+ const label = isDeletion ? "Remove block" : "Comment on block";
27054
+ let output2 = `${heading} ${label} (Line ${blockStartLine})
27055
+ `;
27056
+ const preview = ((block == null ? void 0 : block.content) || ann.originalText || "").slice(0, 200);
27057
+ output2 += `\`\`\`
27058
+ ${preview}
27059
+ \`\`\`
27060
+ `;
27061
+ if (isDeletion) {
27062
+ output2 += `> User wants this block removed from the document.
27063
+ `;
27064
+ } else {
27065
+ output2 += `> ${(ann.text ?? "").replace(/\n/g, "\n> ")}
27031
27066
  `;
27032
27067
  }
27033
27068
  return output2 + "\n";
27034
27069
  }
27035
27070
  if (ann.targetType === "diagram") {
27036
27071
  const isDeletion = ann.type === "DELETION";
27037
- const label = isDeletion ? "Remove Mermaid diagram" : "Comment on Mermaid diagram";
27072
+ const diagramLang = (block == null ? void 0 : block.language) === "plantuml" ? "PlantUML" : "Mermaid";
27073
+ const fence = (block == null ? void 0 : block.language) === "plantuml" ? "plantuml" : "mermaid";
27074
+ const label = isDeletion ? `Remove ${diagramLang} diagram` : `Comment on ${diagramLang} diagram`;
27038
27075
  let output2 = `${heading} ${label} (Line ${blockStartLine})
27039
27076
  `;
27040
- output2 += `\`\`\`mermaid
27077
+ output2 += `\`\`\`${fence}
27041
27078
  ${(block == null ? void 0 : block.content) || ann.originalText}
27042
27079
  \`\`\`
27043
27080
  `;
@@ -27074,7 +27111,7 @@ ${ann.originalText}
27074
27111
  ${ann.originalText}
27075
27112
  \`\`\`
27076
27113
  `;
27077
- output += `> ${ann.text.replace(/\n/g, "\n> ")}
27114
+ output += `> ${(ann.text ?? "").replace(/\n/g, "\n> ")}
27078
27115
  `;
27079
27116
  } else if (ann.type === "INSERTION") {
27080
27117
  output += `Insert text (${lineRef})
@@ -27084,7 +27121,7 @@ ${ann.originalText}
27084
27121
  `;
27085
27122
  }
27086
27123
  output += `\`\`\`
27087
- ${ann.text}
27124
+ ${ann.text ?? ""}
27088
27125
  \`\`\`
27089
27126
  `;
27090
27127
  output += `> User wants this text inserted at this point in the document.
@@ -27182,6 +27219,63 @@ function exportFeedback(annotations, blocks) {
27182
27219
  return output;
27183
27220
  }
27184
27221
 
27222
+ // ../../server/workspace.js
27223
+ import { execFile } from "child_process";
27224
+ import { readdir } from "fs/promises";
27225
+ import { relative, join } from "path";
27226
+ var MAX_FILES = 5e3;
27227
+ var EXCLUDE_DIRS = /* @__PURE__ */ new Set([
27228
+ "node_modules",
27229
+ ".git",
27230
+ "dist",
27231
+ "build",
27232
+ "coverage",
27233
+ "__pycache__",
27234
+ ".next",
27235
+ ".cache",
27236
+ ".turbo",
27237
+ ".output"
27238
+ ]);
27239
+ function gitListFiles(cwd) {
27240
+ return new Promise((resolve3, reject2) => {
27241
+ execFile("git", ["ls-files"], { cwd, maxBuffer: 10 * 1024 * 1024, timeout: 1e4 }, (err, stdout) => {
27242
+ if (err) {
27243
+ return reject2(err);
27244
+ }
27245
+ const files = stdout.split("\n").filter(Boolean);
27246
+ resolve3(files.slice(0, MAX_FILES));
27247
+ });
27248
+ });
27249
+ }
27250
+ async function fallbackListFiles(cwd) {
27251
+ const entries = await readdir(cwd, { recursive: true, withFileTypes: true });
27252
+ const files = [];
27253
+ for (const entry of entries) {
27254
+ if (!entry.isFile()) {
27255
+ continue;
27256
+ }
27257
+ const parentPath = entry.parentPath || entry.path;
27258
+ const rel = relative(cwd, join(parentPath, entry.name));
27259
+ const parts = rel.split("/");
27260
+ if (parts.some((p) => EXCLUDE_DIRS.has(p))) {
27261
+ continue;
27262
+ }
27263
+ files.push(rel);
27264
+ if (files.length >= MAX_FILES) {
27265
+ break;
27266
+ }
27267
+ }
27268
+ return files.sort();
27269
+ }
27270
+ async function listWorkspaceFiles() {
27271
+ const cwd = process.cwd();
27272
+ try {
27273
+ return await gitListFiles(cwd);
27274
+ } catch {
27275
+ return await fallbackListFiles(cwd);
27276
+ }
27277
+ }
27278
+
27185
27279
  // ../../server/routes.js
27186
27280
  function success(data) {
27187
27281
  return { success: true, data };
@@ -27191,12 +27285,20 @@ function failure(error) {
27191
27285
  }
27192
27286
  function createApiRouter(filePaths, resolveDecision, origin = "cli", stores = []) {
27193
27287
  const router = (0, import_express.Router)();
27288
+ router.get("/api/workspace/files", async (_req, res) => {
27289
+ try {
27290
+ const files = await listWorkspaceFiles();
27291
+ res.json(success({ files }));
27292
+ } catch (error) {
27293
+ res.status(500).json(failure(error.message));
27294
+ }
27295
+ });
27194
27296
  router.get("/api/files", async (_req, res) => {
27195
27297
  try {
27196
27298
  const files = await Promise.all(
27197
27299
  stores.map(async (store, index2) => {
27198
27300
  const content = await readMarkdownFile(store.absolutePath);
27199
- const relativePath = relative(process.cwd(), store.absolutePath) || store.absolutePath;
27301
+ const relativePath = relative2(process.cwd(), store.absolutePath) || store.absolutePath;
27200
27302
  const currentHash = createHash("sha256").update(content).digest("hex");
27201
27303
  return {
27202
27304
  index: index2,
@@ -27207,7 +27309,7 @@ function createApiRouter(filePaths, resolveDecision, origin = "cli", stores = []
27207
27309
  };
27208
27310
  })
27209
27311
  );
27210
- res.json(success({ files, origin }));
27312
+ res.json(success({ files, origin, config: { plantumlServerUrl: config.plantumlServerUrl, krokiServerUrl: config.krokiServerUrl } }));
27211
27313
  } catch (error) {
27212
27314
  res.status(500).json(failure(error.message));
27213
27315
  }
@@ -27216,7 +27318,7 @@ function createApiRouter(filePaths, resolveDecision, origin = "cli", stores = []
27216
27318
  var _a;
27217
27319
  try {
27218
27320
  const content = await readMarkdownFile(filePaths[0]);
27219
- const relativePath = relative(process.cwd(), filePaths[0]) || filePaths[0];
27321
+ const relativePath = relative2(process.cwd(), filePaths[0]) || filePaths[0];
27220
27322
  res.json(success({
27221
27323
  content,
27222
27324
  path: relativePath,
@@ -27235,7 +27337,7 @@ function createApiRouter(filePaths, resolveDecision, origin = "cli", stores = []
27235
27337
  }
27236
27338
  const referenceDir = relativeTo ? dirname(resolve2(baseDir, relativeTo)) : dirname(filePaths[0]);
27237
27339
  const absolutePath = resolve2(referenceDir, requestedPath);
27238
- const rel = relative(baseDir, absolutePath);
27340
+ const rel = relative2(baseDir, absolutePath);
27239
27341
  if (rel.startsWith("..") || rel === "" || isAbsolute(rel)) {
27240
27342
  return res.status(403).json(failure("Access denied: path outside project directory"));
27241
27343
  }
@@ -27245,7 +27347,7 @@ function createApiRouter(filePaths, resolveDecision, origin = "cli", stores = []
27245
27347
  try {
27246
27348
  const content = await readMarkdownFile(absolutePath);
27247
27349
  const contentHash = createHash("sha256").update(content).digest("hex");
27248
- const relativePath = relative(baseDir, absolutePath) || absolutePath;
27350
+ const relativePath = relative2(baseDir, absolutePath) || absolutePath;
27249
27351
  let fileIndex = stores.findIndex((s) => s.absolutePath === absolutePath);
27250
27352
  if (fileIndex === -1) {
27251
27353
  stores.push({ absolutePath, contentHash, annotations: [] });
@@ -27414,7 +27516,7 @@ function parseMarkdownToBlocks(markdown) {
27414
27516
  });
27415
27517
  continue;
27416
27518
  }
27417
- if (trimmed === "---" || trimmed === "***") {
27519
+ if (/^([-*_])\s*(\1\s*){2,}$/.test(trimmed)) {
27418
27520
  flush();
27419
27521
  blocks.push({
27420
27522
  id: `block-${currentId++}`,
@@ -27666,8 +27768,8 @@ function findBlockForLine(blocks, line) {
27666
27768
 
27667
27769
  // ../../server/annotator.js
27668
27770
  var __dirname = dirname2(fileURLToPath(import.meta.url));
27669
- var DIST_PATH = join(__dirname, "..", "client", "dist");
27670
- var DEV_PATH = join(__dirname, "..", "client");
27771
+ var DIST_PATH = join2(__dirname, "..", "client", "dist");
27772
+ var DEV_PATH = join2(__dirname, "..", "client");
27671
27773
  function resolveNotesForFile(feedbackNotes, fileIndex, content) {
27672
27774
  if (!Array.isArray(feedbackNotes) || fileIndex !== 0) {
27673
27775
  return [];
@@ -27916,13 +28018,13 @@ function defineLazyProperty(object, propertyName, valueGetter) {
27916
28018
  // ../../node_modules/default-browser/index.js
27917
28019
  import { promisify as promisify4 } from "util";
27918
28020
  import process6 from "process";
27919
- import { execFile as execFile4 } from "child_process";
28021
+ import { execFile as execFile5 } from "child_process";
27920
28022
 
27921
28023
  // ../../node_modules/default-browser-id/index.js
27922
28024
  import { promisify } from "util";
27923
28025
  import process4 from "process";
27924
- import { execFile } from "child_process";
27925
- var execFileAsync = promisify(execFile);
28026
+ import { execFile as execFile2 } from "child_process";
28027
+ var execFileAsync = promisify(execFile2);
27926
28028
  async function defaultBrowserId() {
27927
28029
  if (process4.platform !== "darwin") {
27928
28030
  throw new Error("macOS only");
@@ -27939,8 +28041,8 @@ async function defaultBrowserId() {
27939
28041
  // ../../node_modules/run-applescript/index.js
27940
28042
  import process5 from "process";
27941
28043
  import { promisify as promisify2 } from "util";
27942
- import { execFile as execFile2, execFileSync } from "child_process";
27943
- var execFileAsync2 = promisify2(execFile2);
28044
+ import { execFile as execFile3, execFileSync } from "child_process";
28045
+ var execFileAsync2 = promisify2(execFile3);
27944
28046
  async function runAppleScript(script, { humanReadableOutput = true, signal } = {}) {
27945
28047
  if (process5.platform !== "darwin") {
27946
28048
  throw new Error("macOS only");
@@ -27962,8 +28064,8 @@ tell application "System Events" to get value of property list item "CFBundleNam
27962
28064
 
27963
28065
  // ../../node_modules/default-browser/windows.js
27964
28066
  import { promisify as promisify3 } from "util";
27965
- import { execFile as execFile3 } from "child_process";
27966
- var execFileAsync3 = promisify3(execFile3);
28067
+ import { execFile as execFile4 } from "child_process";
28068
+ var execFileAsync3 = promisify3(execFile4);
27967
28069
  var windowsBrowserProgIds = {
27968
28070
  MSEdgeHTM: { name: "Edge", id: "com.microsoft.edge" },
27969
28071
  // The missing `L` is correct.
@@ -28006,7 +28108,7 @@ async function defaultBrowser(_execFileAsync = execFileAsync3) {
28006
28108
  }
28007
28109
 
28008
28110
  // ../../node_modules/default-browser/index.js
28009
- var execFileAsync4 = promisify4(execFile4);
28111
+ var execFileAsync4 = promisify4(execFile5);
28010
28112
  var titleize = (string) => string.toLowerCase().replaceAll(/(?:^|\s|-)\S/g, (x) => x.toUpperCase());
28011
28113
  async function defaultBrowser2() {
28012
28114
  if (process6.platform === "darwin") {
@@ -28027,7 +28129,7 @@ async function defaultBrowser2() {
28027
28129
  }
28028
28130
 
28029
28131
  // ../../node_modules/open/index.js
28030
- var execFile5 = promisify5(childProcess.execFile);
28132
+ var execFile6 = promisify5(childProcess.execFile);
28031
28133
  var __dirname2 = path.dirname(fileURLToPath2(import.meta.url));
28032
28134
  var localXdgOpenPath = path.join(__dirname2, "xdg-open");
28033
28135
  var { platform, arch } = process7;
@@ -28035,7 +28137,7 @@ async function getWindowsDefaultBrowserFromWsl() {
28035
28137
  const powershellPath = await powerShellPath();
28036
28138
  const rawCommand = String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`;
28037
28139
  const encodedCommand = Buffer2.from(rawCommand, "utf16le").toString("base64");
28038
- const { stdout } = await execFile5(
28140
+ const { stdout } = await execFile6(
28039
28141
  powershellPath,
28040
28142
  [
28041
28143
  "-NoProfile",
@@ -28294,7 +28396,7 @@ async function openBrowser(url) {
28294
28396
 
28295
28397
  // index.ts
28296
28398
  var __dirname3 = dirname3(fileURLToPath3(import.meta.url));
28297
- var htmlContent = readFileSync(join2(__dirname3, "..", "annotator.html"), "utf-8");
28399
+ var htmlContent = readFileSync(join3(__dirname3, "..", "annotator.html"), "utf-8");
28298
28400
  var sleep = (ms) => new Promise((resolve3) => setTimeout(resolve3, ms));
28299
28401
  var MdAnnotatorPlugin = async (ctx) => {
28300
28402
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "md-annotator-opencode",
3
- "version": "0.5.8",
3
+ "version": "0.7.0",
4
4
  "description": "OpenCode plugin for interactive markdown annotation",
5
5
  "license": "MIT",
6
6
  "type": "module",