oh-my-opencode 5.0.0-beta.23 → 5.0.0-beta.25

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 (142) hide show
  1. package/dist/cli/index.js +141 -184
  2. package/dist/cli-node/index.js +141 -184
  3. package/dist/index.js +1508 -1567
  4. package/dist/skills/debugging/SKILL.md +0 -2
  5. package/dist/skills/debugging/references/methodology/00-setup.md +0 -12
  6. package/dist/skills/debugging/references/methodology/02-investigate.md +0 -21
  7. package/dist/skills/debugging/references/runtimes/go.md +1 -15
  8. package/dist/skills/debugging/references/runtimes/native-binary.md +0 -38
  9. package/dist/skills/debugging/references/runtimes/node.md +0 -25
  10. package/dist/skills/debugging/references/runtimes/python.md +0 -13
  11. package/dist/skills/debugging/references/runtimes/rust.md +0 -41
  12. package/dist/tools/delegate-task/types.d.ts +0 -3
  13. package/dist/tui.js +0 -25
  14. package/package.json +15 -18
  15. package/packages/lsp-core/src/index.ts +0 -1
  16. package/packages/lsp-core/src/lsp/client-wrapper.ts +5 -25
  17. package/packages/lsp-core/src/lsp/client.ts +0 -26
  18. package/packages/lsp-core/src/lsp/connection.ts +0 -16
  19. package/packages/lsp-core/src/lsp/constants.ts +0 -1
  20. package/packages/lsp-core/src/lsp/manager.ts +1 -34
  21. package/packages/lsp-core/src/lsp/server-definitions.ts +0 -29
  22. package/packages/lsp-core/src/lsp/server-installation.ts +27 -200
  23. package/packages/lsp-core/src/lsp/server-resolution.ts +5 -18
  24. package/packages/lsp-core/src/lsp/transport.ts +0 -9
  25. package/packages/lsp-core/src/lsp/types.ts +0 -8
  26. package/packages/lsp-core/src/tool-surface.test.ts +1 -13
  27. package/packages/lsp-core/src/tools/definitions.ts +0 -14
  28. package/packages/lsp-core/src/tools/index.ts +0 -1
  29. package/packages/lsp-core/src/tools/types.ts +0 -10
  30. package/packages/lsp-daemon/dist/cli.js +144 -432
  31. package/packages/lsp-daemon/dist/client.d.ts +0 -10
  32. package/packages/lsp-daemon/dist/client.js +107 -401
  33. package/packages/lsp-daemon/dist/daemon-client.d.ts +0 -1
  34. package/packages/lsp-daemon/dist/daemon-client.js +0 -3
  35. package/packages/lsp-daemon/dist/index.js +107 -395
  36. package/packages/lsp-tools-mcp/dist/cli.js +99 -384
  37. package/packages/lsp-tools-mcp/dist/lsp/manager.js +0 -53
  38. package/packages/lsp-tools-mcp/dist/mcp.js +99 -384
  39. package/packages/lsp-tools-mcp/dist/tools.js +99 -385
  40. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  41. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +2 -2
  42. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  43. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  44. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +35 -69
  45. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +2 -21
  46. package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
  47. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  48. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  49. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  50. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  51. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  52. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  53. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +3 -3
  54. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +121 -404
  55. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  56. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  57. package/packages/omo-codex/plugin/components/rules/dist/cli.js +3 -3
  58. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  59. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  60. package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +3 -3
  61. package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +4 -4
  62. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  63. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  64. package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +15 -30
  65. package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +15 -30
  66. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  67. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  68. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  69. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  70. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +2 -2
  71. package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
  72. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
  73. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  74. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  75. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  76. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  77. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
  78. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  79. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  80. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  81. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  82. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  83. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  84. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  85. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  86. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  87. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
  88. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  89. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  90. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
  91. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  92. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-ulw-execute-continuation.json +1 -1
  93. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  94. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  95. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  96. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  97. package/packages/omo-codex/plugin/model-catalog.json +3 -3
  98. package/packages/omo-codex/plugin/package-lock.json +13 -13
  99. package/packages/omo-codex/plugin/package.json +1 -1
  100. package/packages/omo-codex/plugin/scripts/migrate-codex-config/catalog.mjs +3 -3
  101. package/packages/omo-codex/plugin/skills/debugging/SKILL.md +0 -2
  102. package/packages/omo-codex/plugin/skills/debugging/references/methodology/00-setup.md +0 -12
  103. package/packages/omo-codex/plugin/skills/debugging/references/methodology/02-investigate.md +0 -21
  104. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/go.md +1 -15
  105. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/native-binary.md +0 -38
  106. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/node.md +0 -25
  107. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/python.md +0 -13
  108. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/rust.md +0 -41
  109. package/packages/omo-codex/plugin/test/aggregate-model-catalog.test.mjs +1 -1
  110. package/packages/omo-codex/plugin/test/auto-update.test.mjs +2 -2
  111. package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +8 -8
  112. package/packages/omo-codex/scripts/install-config-reasoning.test.mjs +2 -2
  113. package/packages/omo-codex/scripts/install-dist/install-local.mjs +23 -38
  114. package/packages/shared-skills/skills/debugging/SKILL.md +0 -2
  115. package/packages/shared-skills/skills/debugging/references/methodology/00-setup.md +0 -12
  116. package/packages/shared-skills/skills/debugging/references/methodology/02-investigate.md +0 -21
  117. package/packages/shared-skills/skills/debugging/references/runtimes/go.md +1 -15
  118. package/packages/shared-skills/skills/debugging/references/runtimes/native-binary.md +0 -38
  119. package/packages/shared-skills/skills/debugging/references/runtimes/node.md +0 -25
  120. package/packages/shared-skills/skills/debugging/references/runtimes/python.md +0 -13
  121. package/packages/shared-skills/skills/debugging/references/runtimes/rust.md +0 -41
  122. package/dist/skills/debugging/references/scripts/dap.mjs +0 -267
  123. package/dist/skills/debugging/references/scripts/dap.test.ts +0 -86
  124. package/dist/skills/debugging/references/scripts/fixture-adapter.mjs +0 -59
  125. package/dist/skills/debugging/references/tools/dap.md +0 -103
  126. package/dist/skills/debugging/references/tools/frida.md +0 -193
  127. package/packages/lsp-core/src/lsp/format-document.test.ts +0 -143
  128. package/packages/lsp-core/src/lsp/format-document.ts +0 -90
  129. package/packages/lsp-core/src/lsp/manager-max-clients.test.ts +0 -151
  130. package/packages/lsp-core/src/lsp/server-installation.test.ts +0 -376
  131. package/packages/lsp-core/src/lsp/server-resolution-local-binary.test.ts +0 -170
  132. package/packages/lsp-core/src/tools/format.test.ts +0 -56
  133. package/packages/lsp-core/src/tools/format.ts +0 -56
  134. package/packages/omo-codex/plugin/skills/debugging/references/scripts/dap.mjs +0 -267
  135. package/packages/omo-codex/plugin/skills/debugging/references/scripts/fixture-adapter.mjs +0 -59
  136. package/packages/omo-codex/plugin/skills/debugging/references/tools/dap.md +0 -103
  137. package/packages/omo-codex/plugin/skills/debugging/references/tools/frida.md +0 -193
  138. package/packages/shared-skills/skills/debugging/references/scripts/dap.mjs +0 -267
  139. package/packages/shared-skills/skills/debugging/references/scripts/dap.test.ts +0 -86
  140. package/packages/shared-skills/skills/debugging/references/scripts/fixture-adapter.mjs +0 -59
  141. package/packages/shared-skills/skills/debugging/references/tools/dap.md +0 -103
  142. package/packages/shared-skills/skills/debugging/references/tools/frida.md +0 -193
@@ -311,7 +311,7 @@ function createIdleTimer(idleTimeoutMs, log, onTimeout) {
311
311
  }
312
312
  // ../lsp-core/src/lsp/client-wrapper.ts
313
313
  import { existsSync as existsSync10, realpathSync as realpathSync5, statSync as statSync3 } from "node:fs";
314
- import { basename as basename3, dirname as dirname8, join as join5, resolve as resolve8 } from "node:path";
314
+ import { basename as basename3, dirname as dirname7, join as join5, resolve as resolve7 } from "node:path";
315
315
 
316
316
  // ../lsp-core/src/request-context.ts
317
317
  import { AsyncLocalStorage } from "node:async_hooks";
@@ -593,7 +593,6 @@ var DEFAULT_MAX_DIRECTORY_FILES = 50;
593
593
  var REQUEST_TIMEOUT_MS = 15000;
594
594
  var INIT_TIMEOUT_MS = 60000;
595
595
  var IDLE_TIMEOUT_MS = 5 * 60000;
596
- var MAX_RESIDENT_CLIENTS = 6;
597
596
  var REAPER_INTERVAL_MS = 60000;
598
597
  var STOP_HARD_KILL_TIMEOUT_MS = 5000;
599
598
  var STOP_SIGKILL_GRACE_MS = 1000;
@@ -1119,7 +1118,6 @@ class LspClientTransport {
1119
1118
  this.diagnosticsStore = new Map;
1120
1119
  this.workspaceApplyEditHandler = null;
1121
1120
  this.diagnosticPullSupported = false;
1122
- this.documentFormattingSupported = false;
1123
1121
  this.requestTimeoutMs = timeouts.requestTimeoutMs ?? REQUEST_TIMEOUT_MS;
1124
1122
  this.initializeTimeoutMs = timeouts.initializeTimeoutMs ?? INIT_TIMEOUT_MS;
1125
1123
  }
@@ -1141,12 +1139,6 @@ class LspClientTransport {
1141
1139
  isDiagnosticPullSupported() {
1142
1140
  return this.diagnosticPullSupported;
1143
1141
  }
1144
- setDocumentFormattingSupported(supported) {
1145
- this.documentFormattingSupported = supported;
1146
- }
1147
- isDocumentFormattingSupported() {
1148
- return this.documentFormattingSupported;
1149
- }
1150
1142
  handlePublishDiagnostics(params) {
1151
1143
  this.diagnosticsStore.set(params.uri, [...params.diagnostics]);
1152
1144
  }
@@ -1360,14 +1352,6 @@ function supportsDiagnosticPull(capabilities) {
1360
1352
  return false;
1361
1353
  return Object.hasOwn(capabilities, "diagnosticProvider");
1362
1354
  }
1363
- function supportsDocumentFormatting(capabilities) {
1364
- if (capabilities === undefined)
1365
- return false;
1366
- const provider = capabilities.documentFormattingProvider;
1367
- if (provider === undefined || provider === null || provider === false)
1368
- return false;
1369
- return provider === true || typeof provider === "object";
1370
- }
1371
1355
 
1372
1356
  class LspClientConnection extends LspClientTransport {
1373
1357
  async initialize() {
@@ -1384,7 +1368,6 @@ class LspClientConnection extends LspClientTransport {
1384
1368
  references: {},
1385
1369
  documentSymbol: { hierarchicalDocumentSymbolSupport: true },
1386
1370
  publishDiagnostics: {},
1387
- formatting: { dynamicRegistration: false },
1388
1371
  rename: {
1389
1372
  prepareSupport: true,
1390
1373
  prepareSupportDefaultBehavior: 1
@@ -1426,7 +1409,6 @@ class LspClientConnection extends LspClientTransport {
1426
1409
  initializationOptions: this.server.initialization
1427
1410
  }, { timeoutMs: this.initializeTimeoutMs });
1428
1411
  this.setDiagnosticPullSupported(supportsDiagnosticPull(result?.capabilities));
1429
- this.setDocumentFormattingSupported(supportsDocumentFormatting(result?.capabilities));
1430
1412
  await this.sendNotification("initialized", {});
1431
1413
  await this.sendNotification("workspace/didChangeConfiguration", {
1432
1414
  settings: { json: { validate: { enable: true } } }
@@ -3011,18 +2993,6 @@ class LspClient extends LspClientConnection {
3011
2993
  textDocument: { uri: pathToFileURL3(absPath).href }
3012
2994
  }, options);
3013
2995
  }
3014
- async formatDocument(filePath, options, signal) {
3015
- if (!this.isDocumentFormattingSupported())
3016
- return null;
3017
- const absPath = this.resolveWorkspacePath(filePath);
3018
- await this.openFile(absPath);
3019
- const requestOptions = signal === undefined ? {} : { signal };
3020
- const edits = await this.sendRequest("textDocument/formatting", {
3021
- textDocument: { uri: pathToFileURL3(absPath).href },
3022
- options
3023
- }, requestOptions);
3024
- return edits ?? [];
3025
- }
3026
2996
  async workspaceSymbols(query, signal) {
3027
2997
  const options = signal === undefined ? {} : { signal };
3028
2998
  return this.sendRequest("workspace/symbol", { query }, options);
@@ -3275,7 +3245,6 @@ class LspManager {
3275
3245
  this.disposed = false;
3276
3246
  this.idleTimeoutMs = options.idleTimeoutMs ?? IDLE_TIMEOUT_MS;
3277
3247
  this.initTimeoutMs = options.initTimeoutMs ?? INIT_TIMEOUT_MS;
3278
- this.maxResidentClients = options.maxResidentClients ?? MAX_RESIDENT_CLIENTS;
3279
3248
  this.reaperIntervalMs = options.reaperIntervalMs ?? REAPER_INTERVAL_MS;
3280
3249
  this.clientFactory = options.clientFactory ?? ((root, server2) => new LspClient(root, server2));
3281
3250
  this.now = options.now ?? (() => Date.now());
@@ -3309,26 +3278,6 @@ class LspManager {
3309
3278
  }
3310
3279
  }
3311
3280
  }
3312
- evictForAdmission() {
3313
- while (this.clients.size >= this.maxResidentClients) {
3314
- const victim = this.leastRecentlyUsedIdleClient();
3315
- if (!victim)
3316
- return;
3317
- this.clients.delete(victim.key);
3318
- stopClientBestEffort(victim.managed.client);
3319
- }
3320
- }
3321
- leastRecentlyUsedIdleClient() {
3322
- let candidate = null;
3323
- for (const [key, managed] of this.clients) {
3324
- if (managed.refCount > 0 || managed.pendingWaiters > 0 || managed.isInitializing)
3325
- continue;
3326
- if (candidate === null || managed.lastUsedAt < candidate.managed.lastUsedAt) {
3327
- candidate = { key, managed };
3328
- }
3329
- }
3330
- return candidate;
3331
- }
3332
3281
  async tryDeleteIfOrphaned(key, managed) {
3333
3282
  if (managed.refCount === 0 && managed.pendingWaiters === 0 && !managed.isInitializing && this.clients.get(key) === managed) {
3334
3283
  this.clients.delete(key);
@@ -3375,7 +3324,6 @@ class LspManager {
3375
3324
  managed.lastUsedAt = this.now();
3376
3325
  return managed.client;
3377
3326
  }
3378
- this.evictForAdmission();
3379
3327
  const client = this.clientFactory(root, server2);
3380
3328
  const initStartedAt = this.now();
3381
3329
  const initPromise = (async () => {
@@ -3438,7 +3386,6 @@ class LspManager {
3438
3386
  const key = this.getKey(root, server2.id);
3439
3387
  if (this.clients.has(key))
3440
3388
  return;
3441
- this.evictForAdmission();
3442
3389
  const client = this.clientFactory(root, server2);
3443
3390
  const initStartedAt = this.now();
3444
3391
  const initPromise = (async () => {
@@ -3564,6 +3511,57 @@ function nearestExistingAncestor(directory) {
3564
3511
  return current;
3565
3512
  }
3566
3513
 
3514
+ // ../lsp-core/src/lsp/server-install-state.ts
3515
+ import { existsSync as existsSync7, mkdirSync, readFileSync as readFileSync3, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
3516
+ import { dirname as dirname6 } from "node:path";
3517
+ function getInstallDecisionsPath() {
3518
+ return lspRequestContext().installDecisionsPath;
3519
+ }
3520
+ function loadInstallDecisions() {
3521
+ const path = getInstallDecisionsPath();
3522
+ if (!existsSync7(path))
3523
+ return {};
3524
+ try {
3525
+ const parsed = JSON.parse(readFileSync3(path, "utf8"));
3526
+ return isInstallDecisions(parsed) ? parsed : {};
3527
+ } catch {
3528
+ return {};
3529
+ }
3530
+ }
3531
+ function loadInstallDecision(serverId) {
3532
+ return loadInstallDecisions()[serverId];
3533
+ }
3534
+ function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
3535
+ const decisions = loadInstallDecisions();
3536
+ decisions[serverId] = { decision, decidedAt };
3537
+ writeInstallDecisions(decisions);
3538
+ }
3539
+ function isInstallDecision(value) {
3540
+ return value === "declined" || value === "allowed";
3541
+ }
3542
+ function writeInstallDecisions(decisions) {
3543
+ const path = getInstallDecisionsPath();
3544
+ mkdirSync(dirname6(path), { recursive: true });
3545
+ const tmpPath = `${path}.tmp`;
3546
+ writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
3547
+ `, "utf8");
3548
+ renameSync2(tmpPath, path);
3549
+ }
3550
+ function isInstallDecisions(value) {
3551
+ return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
3552
+ }
3553
+ function isInstallDecisionRecord(value) {
3554
+ if (!isRecord5(value))
3555
+ return false;
3556
+ return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
3557
+ }
3558
+ function isRecord5(value) {
3559
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3560
+ }
3561
+
3562
+ // ../lsp-core/src/lsp/config-loader.ts
3563
+ import { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
3564
+
3567
3565
  // ../lsp-core/src/lsp/server-definitions.ts
3568
3566
  var LSP_INSTALL_HINTS = {
3569
3567
  typescript: "npm install -g typescript-language-server typescript",
@@ -3609,26 +3607,6 @@ var LSP_INSTALL_HINTS = {
3609
3607
  julials: `julia -e 'using Pkg; Pkg.add("LanguageServer")'`,
3610
3608
  razor: "Razor runs through the Roslyn language server (cohosting). " + "Install: dotnet tool install -g roslyn-language-server --prerelease (requires v5.8.0+). See https://github.com/dotnet/razor"
3611
3609
  };
3612
- var LSP_LOCAL_INSTALL_HINTS = {
3613
- typescript: "bun add -d typescript-language-server typescript",
3614
- vue: "bun add -d @vue/language-server",
3615
- eslint: "bun add -d vscode-langservers-extracted",
3616
- oxlint: "bun add -d oxlint",
3617
- biome: "bun add -d @biomejs/biome",
3618
- svelte: "bun add -d svelte-language-server",
3619
- astro: "bun add -d @astrojs/language-server",
3620
- bash: "bun add -d bash-language-server",
3621
- "bash-ls": "bun add -d bash-language-server",
3622
- "yaml-ls": "bun add -d yaml-language-server",
3623
- php: "bun add -d intelephense",
3624
- prisma: "bun add -d prisma",
3625
- dockerfile: "bun add -d dockerfile-language-server-nodejs",
3626
- pyright: "uv add --dev pyright",
3627
- basedpyright: "uv add --dev basedpyright",
3628
- ruff: "uv add --dev ruff",
3629
- ty: "uv add --dev ty",
3630
- "ruby-lsp": "bundle add ruby-lsp --group development"
3631
- };
3632
3610
  var BUILTIN_SERVERS = {
3633
3611
  typescript: {
3634
3612
  command: ["typescript-language-server", "--stdio"],
@@ -3731,56 +3709,7 @@ var BUILTIN_SERVERS = {
3731
3709
  }
3732
3710
  };
3733
3711
 
3734
- // ../lsp-core/src/lsp/server-install-state.ts
3735
- import { existsSync as existsSync7, mkdirSync, readFileSync as readFileSync3, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
3736
- import { dirname as dirname6 } from "node:path";
3737
- function getInstallDecisionsPath() {
3738
- return lspRequestContext().installDecisionsPath;
3739
- }
3740
- function loadInstallDecisions() {
3741
- const path = getInstallDecisionsPath();
3742
- if (!existsSync7(path))
3743
- return {};
3744
- try {
3745
- const parsed = JSON.parse(readFileSync3(path, "utf8"));
3746
- return isInstallDecisions(parsed) ? parsed : {};
3747
- } catch {
3748
- return {};
3749
- }
3750
- }
3751
- function loadInstallDecision(serverId) {
3752
- return loadInstallDecisions()[serverId];
3753
- }
3754
- function recordInstallDecision(serverId, decision, decidedAt = new Date().toISOString()) {
3755
- const decisions = loadInstallDecisions();
3756
- decisions[serverId] = { decision, decidedAt };
3757
- writeInstallDecisions(decisions);
3758
- }
3759
- function isInstallDecision(value) {
3760
- return value === "declined" || value === "allowed";
3761
- }
3762
- function writeInstallDecisions(decisions) {
3763
- const path = getInstallDecisionsPath();
3764
- mkdirSync(dirname6(path), { recursive: true });
3765
- const tmpPath = `${path}.tmp`;
3766
- writeFileSync2(tmpPath, `${JSON.stringify(decisions, null, 2)}
3767
- `, "utf8");
3768
- renameSync2(tmpPath, path);
3769
- }
3770
- function isInstallDecisions(value) {
3771
- return isRecord5(value) && Object.values(value).every(isInstallDecisionRecord);
3772
- }
3773
- function isInstallDecisionRecord(value) {
3774
- if (!isRecord5(value))
3775
- return false;
3776
- return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
3777
- }
3778
- function isRecord5(value) {
3779
- return typeof value === "object" && value !== null && !Array.isArray(value);
3780
- }
3781
-
3782
3712
  // ../lsp-core/src/lsp/config-loader.ts
3783
- import { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
3784
3713
  function getProjectConfigPaths() {
3785
3714
  return lspRequestContext().projectConfigPaths;
3786
3715
  }
@@ -3977,154 +3906,53 @@ function getDisabledServerIds() {
3977
3906
 
3978
3907
  // ../lsp-core/src/lsp/server-installation.ts
3979
3908
  import { existsSync as existsSync9 } from "node:fs";
3980
- import { delimiter as delimiter3, dirname as dirname7, isAbsolute as isAbsolute3, join as join4, resolve as resolve7 } from "node:path";
3981
- var LOCAL_BIN_RULES = [
3982
- {
3983
- markers: ["package.json", "bun.lock", "bun.lockb", "package-lock.json", "yarn.lock", "pnpm-lock.yaml"],
3984
- binDirs: [join4("node_modules", ".bin")]
3985
- },
3986
- {
3987
- markers: [
3988
- "pyproject.toml",
3989
- "ty.toml",
3990
- "requirements.txt",
3991
- "setup.py",
3992
- "setup.cfg",
3993
- "Pipfile",
3994
- "pyrightconfig.json",
3995
- "ruff.toml",
3996
- ".ruff.toml"
3997
- ],
3998
- binDirs: [
3999
- join4(".venv", "bin"),
4000
- join4(".venv", "Scripts"),
4001
- join4("venv", "bin"),
4002
- join4("venv", "Scripts"),
4003
- join4(".env", "bin"),
4004
- join4(".env", "Scripts")
4005
- ]
4006
- },
4007
- {
4008
- markers: ["Gemfile", "Gemfile.lock"],
4009
- binDirs: [join4("vendor", "bundle", "bin"), "bin"]
4010
- },
4011
- {
4012
- markers: ["go.mod", "go.sum", "go.work"],
4013
- binDirs: ["bin"]
4014
- }
4015
- ];
4016
- var resolutionCache = new Map;
4017
- var probeCount = 0;
4018
- function probe(path) {
4019
- probeCount += 1;
4020
- return existsSync9(path);
4021
- }
4022
- function executableSuffixes(platform, pathExt) {
4023
- if (platform !== "win32")
4024
- return [""];
4025
- const configured = pathExt ?? process.env["PATHEXT"] ?? "";
4026
- const systemExts = configured.split(";").filter((entry) => entry.length > 0).map((entry) => entry.toLowerCase());
4027
- return [...new Set(["", ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
4028
- }
4029
- function probeWithSuffixes(directory, command, suffixes) {
4030
- for (const suffix of suffixes) {
4031
- const candidate = join4(directory, command + suffix);
4032
- if (probe(candidate))
4033
- return candidate;
3909
+ import { delimiter as delimiter3, join as join4 } from "node:path";
3910
+ function isServerInstalled(command, _workingDirectory) {
3911
+ if (command.length === 0)
3912
+ return false;
3913
+ const [cmd] = command;
3914
+ if (!cmd)
3915
+ return false;
3916
+ if (cmd.includes("/") || cmd.includes("\\")) {
3917
+ if (existsSync9(cmd))
3918
+ return true;
4034
3919
  }
4035
- return null;
4036
- }
4037
- function resolveLocal(command, workingDirectory, suffixes, stopAt) {
4038
- const boundary = stopAt === undefined ? undefined : resolve7(stopAt);
4039
- let current = resolve7(workingDirectory);
4040
- while (true) {
4041
- for (const rule of LOCAL_BIN_RULES) {
4042
- if (!rule.markers.some((marker) => probe(join4(current, marker))))
4043
- continue;
4044
- for (const binDir of rule.binDirs) {
4045
- const found = probeWithSuffixes(join4(current, binDir), command, suffixes);
4046
- if (found !== null)
4047
- return found;
4048
- }
3920
+ const isWindows = process.platform === "win32";
3921
+ let exts = [""];
3922
+ if (isWindows) {
3923
+ const pathExt = process.env["PATHEXT"] ?? "";
3924
+ if (pathExt) {
3925
+ const systemExts = pathExt.split(";").filter(Boolean);
3926
+ exts = [...new Set([...exts, ...systemExts, ".exe", ".cmd", ".bat", ".ps1"])];
3927
+ } else {
3928
+ exts = ["", ".exe", ".cmd", ".bat", ".ps1"];
4049
3929
  }
4050
- if (probe(join4(current, ".git")))
4051
- return null;
4052
- if (boundary !== undefined && current === boundary)
4053
- return null;
4054
- const parent = dirname7(current);
4055
- if (parent === current)
4056
- return null;
4057
- current = parent;
4058
3930
  }
4059
- }
4060
- function resolveFromPath(command, suffixes, platform, pathEnvOverride) {
4061
- let pathEnv = pathEnvOverride ?? process.env["PATH"] ?? "";
4062
- if (platform === "win32" && !pathEnv) {
3931
+ let pathEnv = process.env["PATH"] ?? "";
3932
+ if (isWindows && !pathEnv) {
4063
3933
  pathEnv = process.env["Path"] ?? "";
4064
3934
  }
4065
- for (const entry of pathEnv.split(delimiter3)) {
4066
- if (entry.length === 0)
4067
- continue;
4068
- const found = probeWithSuffixes(entry, command, suffixes);
4069
- if (found !== null)
4070
- return found;
3935
+ const paths = pathEnv.split(delimiter3);
3936
+ for (const p of paths) {
3937
+ for (const suffix of exts) {
3938
+ if (existsSync9(join4(p, cmd + suffix))) {
3939
+ return true;
3940
+ }
3941
+ }
4071
3942
  }
4072
- return null;
4073
- }
4074
- function resolveServerBinary(command, workingDirectory, options = {}) {
4075
- if (command.length === 0)
4076
- return null;
4077
- const [cmd] = command;
4078
- if (cmd === undefined || cmd.length === 0)
4079
- return null;
4080
- const platform = options.platform ?? process.platform;
4081
- const suffixes = executableSuffixes(platform, options.pathExt);
4082
- if (cmd.includes("/") || cmd.includes("\\")) {
4083
- const explicit = isAbsolute3(cmd) ? cmd : resolve7(workingDirectory ?? process.cwd(), cmd);
4084
- return probe(explicit) ? explicit : null;
4085
- }
4086
- const cacheKey = JSON.stringify([
4087
- workingDirectory ?? "",
4088
- cmd,
4089
- platform,
4090
- options.stopAt ?? "",
4091
- options.pathExt ?? "",
4092
- options.pathEnv ?? process.env["PATH"] ?? ""
4093
- ]);
4094
- const cached = resolutionCache.get(cacheKey);
4095
- if (cached !== undefined)
4096
- return cached;
4097
- let resolved = null;
4098
- if (workingDirectory !== undefined && workingDirectory.length > 0) {
4099
- resolved = resolveLocal(cmd, workingDirectory, suffixes, options.stopAt);
4100
- }
4101
- resolved ??= resolveFromPath(cmd, suffixes, platform, options.pathEnv);
4102
- if (resolved === null && cmd === "node")
4103
- resolved = cmd;
4104
- resolutionCache.set(cacheKey, resolved);
4105
- return resolved;
4106
- }
4107
- function isServerInstalled(command, workingDirectory, options = {}) {
4108
- if (command.length === 0)
4109
- return false;
4110
- return resolveServerBinary(command, workingDirectory, options) !== null;
3943
+ if (cmd === "node")
3944
+ return true;
3945
+ return false;
4111
3946
  }
4112
3947
 
4113
3948
  // ../lsp-core/src/lsp/server-resolution.ts
4114
- function withResolvedCommand(command, binaryPath) {
4115
- return [binaryPath, ...command.slice(1)];
4116
- }
4117
3949
  function findServerForExtension(ext) {
4118
3950
  const servers = getMergedServers();
4119
- const workingDirectory = contextCwd();
4120
3951
  for (const server2 of servers) {
4121
- if (!server2.extensions.includes(ext))
4122
- continue;
4123
- const binaryPath = resolveServerBinary(server2.command, workingDirectory);
4124
- if (binaryPath !== null) {
3952
+ if (server2.extensions.includes(ext) && isServerInstalled(server2.command)) {
4125
3953
  const resolvedServer = {
4126
3954
  id: server2.id,
4127
- command: withResolvedCommand(server2.command, binaryPath),
3955
+ command: server2.command,
4128
3956
  extensions: server2.extensions,
4129
3957
  priority: server2.priority
4130
3958
  };
@@ -4171,7 +3999,6 @@ function findServerForExtension(ext) {
4171
3999
  function getAllServers() {
4172
4000
  const servers = getMergedServers();
4173
4001
  const disabled = getDisabledServerIds();
4174
- const workingDirectory = contextCwd();
4175
4002
  const result = [];
4176
4003
  const seen = new Set;
4177
4004
  for (const server2 of servers) {
@@ -4179,7 +4006,7 @@ function getAllServers() {
4179
4006
  continue;
4180
4007
  result.push({
4181
4008
  id: server2.id,
4182
- installed: isServerInstalled(server2.command, workingDirectory),
4009
+ installed: isServerInstalled(server2.command),
4183
4010
  extensions: server2.extensions,
4184
4011
  disabled: false,
4185
4012
  source: server2.source,
@@ -4193,7 +4020,7 @@ function getAllServers() {
4193
4020
  const builtin = BUILTIN_SERVERS[id];
4194
4021
  result.push({
4195
4022
  id,
4196
- installed: builtin ? isServerInstalled(builtin.command, workingDirectory) : false,
4023
+ installed: builtin ? isServerInstalled(builtin.command) : false,
4197
4024
  extensions: builtin?.extensions ?? [],
4198
4025
  disabled: true,
4199
4026
  source: "disabled",
@@ -4216,7 +4043,7 @@ function findWorkspaceRoot(filePath) {
4216
4043
  const abs = resolveReadablePathInsideContext(filePath);
4217
4044
  let dir = abs;
4218
4045
  if (!isDirectoryPath(dir)) {
4219
- dir = dirname8(dir);
4046
+ dir = dirname7(dir);
4220
4047
  }
4221
4048
  if (!isPathInside(cwd, abs))
4222
4049
  return findWorkspaceRootOutsideContext(dir);
@@ -4232,13 +4059,13 @@ function findWorkspaceRoot(filePath) {
4232
4059
  }
4233
4060
  if (dir === cwd)
4234
4061
  break;
4235
- dir = dirname8(dir);
4062
+ dir = dirname7(dir);
4236
4063
  }
4237
4064
  return fallbackRoot;
4238
4065
  }
4239
4066
  function resolveReadablePathInsideContext(filePath) {
4240
4067
  const cwd = contextCwd();
4241
- const abs = resolve8(cwd, filePath);
4068
+ const abs = resolve7(cwd, filePath);
4242
4069
  if (isPathInside(cwd, abs))
4243
4070
  return abs;
4244
4071
  const rebased = rebaseThroughCanonicalAncestor(abs, cwd);
@@ -4264,7 +4091,7 @@ function rebaseThroughCanonicalAncestor(path, cwd) {
4264
4091
  if (isPathInside(cwd, canonical))
4265
4092
  return suffix.length === 0 ? canonical : join5(canonical, ...suffix);
4266
4093
  }
4267
- const parent = dirname8(current);
4094
+ const parent = dirname7(current);
4268
4095
  if (parent === current)
4269
4096
  return;
4270
4097
  suffix.unshift(basename3(current));
@@ -4287,7 +4114,7 @@ function nearestExistingDirectoryInsideContext(directory, cwd) {
4287
4114
  return canonical;
4288
4115
  if (current === cwd)
4289
4116
  return;
4290
- current = dirname8(current);
4117
+ current = dirname7(current);
4291
4118
  }
4292
4119
  return;
4293
4120
  }
@@ -4314,19 +4141,6 @@ function formatServerLookupError(result) {
4314
4141
  ].join(`
4315
4142
  `);
4316
4143
  }
4317
- function formatInstallOptions(serverId, installHint) {
4318
- const localHint = LSP_LOCAL_INSTALL_HINTS[serverId];
4319
- if (localHint === undefined) {
4320
- return ["To install, run:", ` ${installHint}`];
4321
- }
4322
- return [
4323
- "To install in THIS repository (preferred — no global install needed):",
4324
- ` ${localHint}`,
4325
- "",
4326
- "Or install it globally:",
4327
- ` ${installHint}`
4328
- ];
4329
- }
4330
4144
  function formatNotInstalled(result) {
4331
4145
  const { server: server2, installHint } = result;
4332
4146
  const extensions = server2.extensions.join(", ");
@@ -4341,19 +4155,19 @@ function formatNotInstalled(result) {
4341
4155
  `Command not found: ${server2.command[0]}`,
4342
4156
  ""
4343
4157
  ];
4344
- const installOptions = formatInstallOptions(server2.id, installHint);
4345
4158
  if (decision === "allowed") {
4346
4159
  return [
4347
4160
  ...header,
4348
4161
  "The user has pre-authorized LSP installation. Run the install command, then retry this tool:",
4349
- ...installOptions.slice(1)
4162
+ ` ${installHint}`
4350
4163
  ].join(`
4351
4164
  `);
4352
4165
  }
4353
4166
  if (!context.capabilities.installDecisionTool) {
4354
4167
  return [
4355
4168
  ...header,
4356
- ...installOptions,
4169
+ "To install, run:",
4170
+ ` ${installHint}`,
4357
4171
  "",
4358
4172
  "ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
4359
4173
  "Install-decision recording is unavailable in this harness; proceed without LSP if the user declines."
@@ -4362,7 +4176,8 @@ function formatNotInstalled(result) {
4362
4176
  }
4363
4177
  return [
4364
4178
  ...header,
4365
- ...installOptions,
4179
+ "To install, run:",
4180
+ ` ${installHint}`,
4366
4181
  "",
4367
4182
  "ACTION REQUIRED — ASK THE USER whether to install this LSP server.",
4368
4183
  "- If the user agrees: run the install command above, then retry this tool.",
@@ -4418,7 +4233,7 @@ async function withLspClient(filePath, fn, toolName, options = {}) {
4418
4233
 
4419
4234
  // ../lsp-core/src/lsp/directory-diagnostics.ts
4420
4235
  import { existsSync as existsSync11, lstatSync as lstatSync4, readdirSync as readdirSync3 } from "node:fs";
4421
- import { join as join6, resolve as resolve9 } from "node:path";
4236
+ import { join as join6, resolve as resolve8 } from "node:path";
4422
4237
 
4423
4238
  // ../lsp-core/src/lsp/formatters.ts
4424
4239
  import { fileURLToPath as fileURLToPath2 } from "node:url";
@@ -4573,7 +4388,7 @@ async function aggregateDiagnosticsForDirectory(directory, extension, severity,
4573
4388
  if (!extension.startsWith(".")) {
4574
4389
  throw new LspInvalidPathError(`Extension must start with a dot (e.g., ".ts", not "${extension}"). Use ".${extension}" instead.`);
4575
4390
  }
4576
- const absDir = resolve9(options.workspaceRoot ?? contextCwd(), directory);
4391
+ const absDir = resolve8(options.workspaceRoot ?? contextCwd(), directory);
4577
4392
  if (!existsSync11(absDir)) {
4578
4393
  throw new LspInvalidPathError(`Directory does not exist: ${absDir}`);
4579
4394
  }
@@ -4930,96 +4745,6 @@ async function executeLspDiagnostics(params, signal) {
4930
4745
  throw error;
4931
4746
  }
4932
4747
  }
4933
- // ../lsp-core/src/lsp/format-document.ts
4934
- import { readFileSync as readFileSync5, renameSync as renameSync3, unlinkSync, writeFileSync as writeFileSync3 } from "node:fs";
4935
- var DEFAULT_FORMATTING_OPTIONS = {
4936
- tabSize: 4,
4937
- insertSpaces: false,
4938
- trimTrailingWhitespace: true,
4939
- insertFinalNewline: true,
4940
- trimFinalNewlines: true
4941
- };
4942
- var UNCHANGED = { status: "unchanged", linesAdded: 0, linesRemoved: 0 };
4943
- async function formatDocumentWithClient(client, filePath, options = {}) {
4944
- const edits = await client.formatDocument(filePath, options.formattingOptions ?? DEFAULT_FORMATTING_OPTIONS, options.signal);
4945
- if (edits === null)
4946
- return { status: "unavailable", reason: "capability_not_advertised" };
4947
- if (edits.length === 0)
4948
- return UNCHANGED;
4949
- const before = readFileSync5(filePath, "utf-8");
4950
- const normalized = normalizeTextEdits(before, edits, 0);
4951
- if (normalized.text === before)
4952
- return UNCHANGED;
4953
- writeAtomically(filePath, normalized.text);
4954
- await client.openFile(filePath);
4955
- return {
4956
- status: "formatted",
4957
- ...lineDelta(normalized.edits)
4958
- };
4959
- }
4960
- function lineDelta(edits) {
4961
- let linesAdded = 0;
4962
- let linesRemoved = 0;
4963
- for (const edit of edits) {
4964
- linesRemoved += edit.range.end.line - edit.range.start.line + 1;
4965
- linesAdded += edit.newText.split(`
4966
- `).length;
4967
- }
4968
- return { linesAdded, linesRemoved };
4969
- }
4970
- function writeAtomically(filePath, content) {
4971
- const tempPath = `${filePath}.omo-format.tmp`;
4972
- writeFileSync3(tempPath, content, "utf-8");
4973
- try {
4974
- renameSync3(tempPath, filePath);
4975
- } catch (error) {
4976
- try {
4977
- unlinkSync(tempPath);
4978
- } catch {}
4979
- throw error;
4980
- }
4981
- }
4982
-
4983
- // ../lsp-core/src/tools/format.ts
4984
- async function executeLspFormat(params, signal) {
4985
- const filePath = requireString(params, "filePath");
4986
- try {
4987
- const result = await withLspClient(filePath, async (client, _workspaceRoot, resolvedFilePath) => formatDocumentWithClient(client, resolvedFilePath, signal === undefined ? {} : { signal }), "format", clientOptions(signal));
4988
- return text(describeResult(filePath, result), formatDetails(filePath, result));
4989
- } catch (error) {
4990
- const missingDependency = missingDependencyResult(error, {
4991
- filePath,
4992
- status: "unavailable",
4993
- reason: "server_unavailable",
4994
- linesAdded: 0,
4995
- linesRemoved: 0
4996
- });
4997
- if (missingDependency)
4998
- return missingDependency;
4999
- throw error;
5000
- }
5001
- }
5002
- function formatDetails(filePath, result) {
5003
- if (result.status === "unavailable") {
5004
- return { filePath, status: "unavailable", reason: result.reason, linesAdded: 0, linesRemoved: 0 };
5005
- }
5006
- return {
5007
- filePath,
5008
- status: result.status,
5009
- linesAdded: result.linesAdded,
5010
- linesRemoved: result.linesRemoved
5011
- };
5012
- }
5013
- function describeResult(filePath, result) {
5014
- if (result.status === "unavailable") {
5015
- return `Formatting unavailable for ${filePath}: the language server does not advertise documentFormattingProvider.`;
5016
- }
5017
- if (result.status === "unchanged") {
5018
- return `Already formatted: ${filePath}`;
5019
- }
5020
- return `Formatted ${filePath} (+${result.linesAdded}/-${result.linesRemoved} lines)`;
5021
- }
5022
-
5023
4748
  // ../lsp-core/src/tools/install-decision.ts
5024
4749
  async function executeLspInstallDecision(params) {
5025
4750
  const serverId = requireString(params, "server_id");
@@ -5352,16 +5077,6 @@ var LSP_MCP_TOOLS = [
5352
5077
  }, ["filePath", "line", "character", "newName"]),
5353
5078
  execute: executeLspRename
5354
5079
  },
5355
- {
5356
- name: "format",
5357
- aliases: ["lsp_format"],
5358
- title: "LSP Format",
5359
- description: "Format a source file with its language server and write the returned edits to disk.",
5360
- inputSchema: objectSchema({
5361
- filePath: { type: "string", description: "Source file path to format." }
5362
- }, ["filePath"]),
5363
- execute: executeLspFormat
5364
- },
5365
5080
  {
5366
5081
  name: "install_decision",
5367
5082
  aliases: ["lsp_install_decision"],