openfox 2.0.18 → 2.0.20

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.
@@ -21,7 +21,7 @@ import {
21
21
  tokenFromPassword,
22
22
  verifyPassword,
23
23
  workflowExists
24
- } from "./chunk-MPSOO6KF.js";
24
+ } from "./chunk-T67KB6ZS.js";
25
25
  import {
26
26
  agentExists,
27
27
  createToolRegistry,
@@ -61,7 +61,7 @@ import {
61
61
  setMcpTools,
62
62
  setNotifyMcpServersChanged,
63
63
  skillExists
64
- } from "./chunk-FCSFHRKI.js";
64
+ } from "./chunk-TVQTTZYW.js";
65
65
  import {
66
66
  getProject
67
67
  } from "./chunk-O4TED6AJ.js";
@@ -101,7 +101,7 @@ import {
101
101
  updateSessionMetadata,
102
102
  updateSessionProvider,
103
103
  updateSessionRunning
104
- } from "./chunk-SYG2ENUQ.js";
104
+ } from "./chunk-YBWY4DKY.js";
105
105
  import {
106
106
  createContextStateMessage
107
107
  } from "./chunk-F4PMNP7S.js";
@@ -141,18 +141,19 @@ import {
141
141
  import express from "express";
142
142
  import cors from "cors";
143
143
  import { createServer as createHttpServer } from "http";
144
- import { fileURLToPath as fileURLToPath3 } from "url";
145
- import { dirname as dirname4, resolve as resolve2, join as join5 } from "path";
144
+ import { fileURLToPath as fileURLToPath4 } from "url";
145
+ import { dirname as dirname5, resolve as resolve3, join as join5 } from "path";
146
146
  import { readFile } from "fs/promises";
147
147
  import { createServer as createViteServer } from "vite";
148
148
 
149
149
  // src/server/llm/mock.ts
150
150
  import { setTimeout as sleep } from "timers/promises";
151
+
152
+ // src/server/llm/mock-rules.ts
151
153
  var RULES = [
152
- // -------------------------------------------------------------------------
154
+ // ---------------------------------------------------------------------------
153
155
  // Session Metadata Tools (criteria, todos, review_findings)
154
- // -------------------------------------------------------------------------
155
- // Multi-criteria: ID "crit-a": "First" and ID "crit-b": "Second"
156
+ // ---------------------------------------------------------------------------
156
157
  {
157
158
  match: /ID\s*["']([a-z0-9-]+)["']:\s*["']([^"']+)["'][\s\S]*ID\s*["']([a-z0-9-]+)["']:\s*["']([^"']+)["']/i,
158
159
  tools: [
@@ -161,13 +162,11 @@ var RULES = [
161
162
  ],
162
163
  response: "Added both criteria."
163
164
  },
164
- // Single criterion: "Add criterion ID "test-1" with description "The tests pass""
165
165
  {
166
166
  match: /Add criterion ID\s*["']([a-z0-9-]+)["']\s*with description\s*["']([^"']+)["'][\s\S]*/i,
167
167
  tools: [{ name: "session_metadata", arguments: { action: "add", key: "criteria", id: "$1", description: "$2" } }],
168
168
  response: "Added the criterion."
169
169
  },
170
- // Single criterion: ID "test-1" with/: description "The tests pass"
171
170
  {
172
171
  match: /ID\s*["']([a-z0-9-]+)["'].*description\s*["']([^"']+)["']/i,
173
172
  tools: [{ name: "session_metadata", arguments: { action: "add", key: "criteria", id: "$1", description: "$2" } }],
@@ -204,7 +203,6 @@ var RULES = [
204
203
  ],
205
204
  response: "Added the criterion."
206
205
  },
207
- // Propose acceptance criteria (for planning prompts)
208
206
  {
209
207
  match: /propose acceptance criteria/i,
210
208
  tools: [
@@ -229,13 +227,11 @@ var RULES = [
229
227
  ],
230
228
  response: "Added criteria for the multiply function."
231
229
  },
232
- // Single criterion: ID "test-1": "The tests pass" (colon format)
233
230
  {
234
231
  match: /ID\s*["']([a-z0-9-]+)["']\s*:\s*["']([^"']+)["']/i,
235
232
  tools: [{ name: "session_metadata", arguments: { action: "add", key: "criteria", id: "$1", description: "$2" } }],
236
233
  response: "Added the criterion."
237
234
  },
238
- // session_metadata to mark criteria as completed (natural language)
239
235
  {
240
236
  match: /session_metadata.*(?:mark|status.*completed).*["']([a-z0-9-]+)["']/i,
241
237
  tools: [
@@ -243,7 +239,6 @@ var RULES = [
243
239
  ],
244
240
  response: "Marked criterion as complete."
245
241
  },
246
- // session_metadata to mark criteria as completed (explicit args)
247
242
  {
248
243
  match: /session_metadata.*action\s*["']update["'].*key\s*["']criteria["'].*id\s*["']([a-z0-9-]+)["'].*status\s*["']completed["']/i,
249
244
  tools: [
@@ -251,13 +246,11 @@ var RULES = [
251
246
  ],
252
247
  response: "Marked criterion as complete."
253
248
  },
254
- // session_metadata to mark criteria as passed
255
249
  {
256
250
  match: /session_metadata.*action\s*["']update["'].*key\s*["']criteria["'].*id\s*["']([a-z0-9-]+)["'].*status\s*["']passed["']/i,
257
251
  tools: [{ name: "session_metadata", arguments: { action: "update", key: "criteria", id: "$1", status: "passed" } }],
258
252
  response: "Criterion passed."
259
253
  },
260
- // session_metadata to mark criteria as failed
261
254
  {
262
255
  match: /session_metadata.*action\s*["']update["'].*key\s*["']criteria["'].*id\s*["']([a-z0-9-]+)["'].*status\s*["']failed["']/i,
263
256
  tools: [
@@ -268,13 +261,11 @@ var RULES = [
268
261
  ],
269
262
  response: "Criterion failed."
270
263
  },
271
- // get criteria via session_metadata
272
264
  {
273
265
  match: /get_criteria|show.*criteria|list.*criteria/i,
274
266
  tools: [{ name: "session_metadata", arguments: { action: "get", key: "criteria" } }],
275
267
  response: "Here are the current criteria."
276
268
  },
277
- // Update criterion via session_metadata
278
269
  {
279
270
  match: /session_metadata.*action\s*["']update["'].*description/i,
280
271
  tools: [
@@ -285,21 +276,16 @@ var RULES = [
285
276
  ],
286
277
  response: "Updated the criterion."
287
278
  },
288
- // Remove criterion via session_metadata
289
279
  {
290
280
  match: /session_metadata.*action\s*["']remove["']/i,
291
281
  tools: [{ name: "session_metadata", arguments: { action: "remove", key: "criteria", id: "0" } }],
292
282
  response: "Removed the criterion."
293
283
  },
294
- // Generic add criterion via session_metadata
295
284
  {
296
285
  match: /add.*criterion/i,
297
286
  tools: [{ name: "session_metadata", arguments: { action: "add", key: "criteria", description: "Test criterion" } }],
298
287
  response: "Added the criterion."
299
288
  },
300
- // -------------------------------------------------------------------------
301
- // Session Metadata Tools
302
- // -------------------------------------------------------------------------
303
289
  {
304
290
  match: /session_metadata.*action\s*["']add["'].*key\s*["']criteria["'].*description\s*["']([^"']+)["']/i,
305
291
  tools: [{ name: "session_metadata", arguments: { action: "add", key: "criteria", description: "$1" } }],
@@ -327,9 +313,6 @@ var RULES = [
327
313
  ],
328
314
  response: "Criterion failed."
329
315
  },
330
- // -------------------------------------------------------------------------
331
- // File Read Tools
332
- // -------------------------------------------------------------------------
333
316
  {
334
317
  match: /read.*src\/math\.ts.*offset|offset.*src\/math\.ts/i,
335
318
  tools: [{ name: "read_file", arguments: { path: "src/math.ts", offset: 5 } }],
@@ -375,9 +358,6 @@ var RULES = [
375
358
  tools: [{ name: "read_file", arguments: { path: "src/index.ts" } }],
376
359
  response: "Read the file."
377
360
  },
378
- // -------------------------------------------------------------------------
379
- // Glob Tool
380
- // -------------------------------------------------------------------------
381
361
  {
382
362
  match: /glob.*\*\*\/\*\.ts|recursive.*typescript/i,
383
363
  tools: [{ name: "glob", arguments: { pattern: "**/*.ts" } }],
@@ -398,9 +378,6 @@ var RULES = [
398
378
  tools: [{ name: "glob", arguments: { pattern: "**/*" } }],
399
379
  response: "Found files."
400
380
  },
401
- // -------------------------------------------------------------------------
402
- // Grep Tool
403
- // -------------------------------------------------------------------------
404
381
  {
405
382
  match: /grep.*XYZNONEXISTENT|search.*XYZNONEXISTENT/i,
406
383
  tools: [{ name: "grep", arguments: { pattern: "XYZNONEXISTENT123", path: "." } }],
@@ -426,10 +403,6 @@ var RULES = [
426
403
  tools: [{ name: "grep", arguments: { pattern: "export", path: "." } }],
427
404
  response: "Searched for pattern."
428
405
  },
429
- // -------------------------------------------------------------------------
430
- // Write Tool
431
- // -------------------------------------------------------------------------
432
- // Path security test rules - writing outside /tmp (requires confirmation)
433
406
  {
434
407
  match: /write.*\/home\/test\/approved/i,
435
408
  tools: [{ name: "write_file", arguments: { path: "/home/test/approved.txt", content: "approved" } }],
@@ -495,9 +468,6 @@ var RULES = [
495
468
  tools: [{ name: "write_file", arguments: { path: "src/newfile.ts", content: "export const x = 1" } }],
496
469
  response: "Created file."
497
470
  },
498
- // -------------------------------------------------------------------------
499
- // Edit Tool
500
- // -------------------------------------------------------------------------
501
471
  {
502
472
  match: /without reading.*edit_file|edit_file.*without reading/i,
503
473
  tools: [{ name: "edit_file", arguments: { path: "src/math.ts", old_string: "function", new_string: "const" } }],
@@ -541,9 +511,6 @@ var RULES = [
541
511
  ],
542
512
  response: "Edited the file."
543
513
  },
544
- // -------------------------------------------------------------------------
545
- // Shell/Command Tool
546
- // -------------------------------------------------------------------------
547
514
  {
548
515
  match: /run.*echo.*first.*sleep.*second/i,
549
516
  tools: [{ name: "run_command", arguments: { command: 'echo "first" && sleep 0.2 && echo "second"' } }],
@@ -622,27 +589,16 @@ var RULES = [
622
589
  tools: [{ name: "run_command", arguments: { command: 'echo "test"' } }],
623
590
  response: "Executed the command."
624
591
  },
625
- // -------------------------------------------------------------------------
626
- // Todo Tool
627
- // -------------------------------------------------------------------------
628
592
  {
629
593
  match: /todo_write.*Read files.*Make changes/i,
630
594
  tools: [
631
595
  {
632
596
  name: "session_metadata",
633
- arguments: {
634
- action: "add",
635
- key: "todos",
636
- description: "Read files"
637
- }
597
+ arguments: { action: "add", key: "todos", description: "Read files" }
638
598
  },
639
599
  {
640
600
  name: "session_metadata",
641
- arguments: {
642
- action: "add",
643
- key: "todos",
644
- description: "Make changes"
645
- }
601
+ arguments: { action: "add", key: "todos", description: "Make changes" }
646
602
  }
647
603
  ],
648
604
  response: "Created todo list."
@@ -652,18 +608,11 @@ var RULES = [
652
608
  tools: [
653
609
  {
654
610
  name: "session_metadata",
655
- arguments: {
656
- action: "add",
657
- key: "todos",
658
- description: "Test task"
659
- }
611
+ arguments: { action: "add", key: "todos", description: "Test task" }
660
612
  }
661
613
  ],
662
614
  response: "Created todo list."
663
615
  },
664
- // -------------------------------------------------------------------------
665
- // Mode/Context
666
- // -------------------------------------------------------------------------
667
616
  {
668
617
  match: /think.*step.*step/i,
669
618
  tools: [],
@@ -674,10 +623,6 @@ var RULES = [
674
623
  tools: [],
675
624
  response: "Here is a detailed explanation of the topic. TypeScript is a statically typed superset of JavaScript that adds optional type annotations. It provides better tooling, catches errors at compile time, and makes code more maintainable."
676
625
  },
677
- // -------------------------------------------------------------------------
678
- // Ask User Tool
679
- // -------------------------------------------------------------------------
680
- // Specific type rules must come before generic ask rules
681
626
  {
682
627
  match: /confirm.*question/i,
683
628
  tools: [{ name: "ask_user", arguments: { question: "Do you approve?", type: "confirm" } }],
@@ -707,9 +652,6 @@ var RULES = [
707
652
  tools: [{ name: "ask_user", arguments: { question: "Should I proceed with this action?" } }],
708
653
  response: "I asked for confirmation."
709
654
  },
710
- // -------------------------------------------------------------------------
711
- // Default Responses (no tools)
712
- // -------------------------------------------------------------------------
713
655
  {
714
656
  match: /hello|hi there|introduce yourself/i,
715
657
  tools: [],
@@ -735,15 +677,14 @@ var RULES = [
735
677
  tools: [],
736
678
  response: "TypeScript is a strongly typed programming language that builds on JavaScript."
737
679
  },
738
- // -------------------------------------------------------------------------
739
- // Fallback
740
- // -------------------------------------------------------------------------
741
680
  {
742
681
  match: /.*/,
743
682
  tools: [],
744
683
  response: "I understand. Let me help you with that."
745
684
  }
746
685
  ];
686
+
687
+ // src/server/llm/mock.ts
747
688
  function matchRule(prompt) {
748
689
  for (const rule of RULES) {
749
690
  const match = prompt.match(rule.match);
@@ -1903,19 +1844,19 @@ var LspServer = class {
1903
1844
  */
1904
1845
  async getDiagnosticsWithWait(path, timeoutMs = DIAGNOSTIC_WAIT_MS) {
1905
1846
  if (this.openDocuments.has(path)) {
1906
- return new Promise((resolve3) => {
1847
+ return new Promise((resolve4) => {
1907
1848
  const existing = this.diagnostics.get(path);
1908
1849
  if (existing !== void 0) {
1909
1850
  setTimeout(() => {
1910
- resolve3(this.diagnostics.get(path) ?? []);
1851
+ resolve4(this.diagnostics.get(path) ?? []);
1911
1852
  }, 100);
1912
1853
  return;
1913
1854
  }
1914
1855
  const timeout = setTimeout(() => {
1915
1856
  this.pendingDiagnostics.delete(path);
1916
- resolve3(this.diagnostics.get(path) ?? []);
1857
+ resolve4(this.diagnostics.get(path) ?? []);
1917
1858
  }, timeoutMs);
1918
- this.pendingDiagnostics.set(path, { resolve: resolve3, timeout });
1859
+ this.pendingDiagnostics.set(path, { resolve: resolve4, timeout });
1919
1860
  });
1920
1861
  }
1921
1862
  return this.diagnostics.get(path) ?? [];
@@ -2000,459 +1941,12 @@ async function which(command, workdir) {
2000
1941
 
2001
1942
  // src/server/lsp/languages.ts
2002
1943
  import { extname as extname2, basename } from "path";
2003
- var LANGUAGES = [
2004
- // JavaScript/TypeScript ecosystem
2005
- {
2006
- id: "typescript",
2007
- name: "TypeScript",
2008
- extensions: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"],
2009
- serverCommand: "typescript-language-server",
2010
- serverArgs: ["--stdio"],
2011
- rootPatterns: ["tsconfig.json", "jsconfig.json", "package.json"],
2012
- languageIds: {
2013
- ".ts": "typescript",
2014
- ".tsx": "typescriptreact",
2015
- ".js": "javascript",
2016
- ".jsx": "javascriptreact",
2017
- ".mjs": "javascript",
2018
- ".cjs": "javascript"
2019
- }
2020
- },
2021
- // Python
2022
- {
2023
- id: "python",
2024
- name: "Python",
2025
- extensions: [".py", ".pyi", ".pyw"],
2026
- serverCommand: "pyright-langserver",
2027
- serverArgs: ["--stdio"],
2028
- rootPatterns: ["pyproject.toml", "setup.py", "requirements.txt", "Pipfile"]
2029
- },
2030
- // Rust
2031
- {
2032
- id: "rust",
2033
- name: "Rust",
2034
- extensions: [".rs"],
2035
- serverCommand: "rust-analyzer",
2036
- serverArgs: [],
2037
- rootPatterns: ["Cargo.toml"]
2038
- },
2039
- // Go
2040
- {
2041
- id: "go",
2042
- name: "Go",
2043
- extensions: [".go"],
2044
- serverCommand: "gopls",
2045
- serverArgs: ["serve"],
2046
- rootPatterns: ["go.mod", "go.sum"]
2047
- },
2048
- // C/C++
2049
- {
2050
- id: "cpp",
2051
- name: "C/C++",
2052
- extensions: [".c", ".cpp", ".cc", ".cxx", ".h", ".hpp", ".hxx", ".hh"],
2053
- serverCommand: "clangd",
2054
- serverArgs: ["--background-index"],
2055
- rootPatterns: ["compile_commands.json", "CMakeLists.txt", ".clangd", "Makefile"]
2056
- },
2057
- // Zig
2058
- {
2059
- id: "zig",
2060
- name: "Zig",
2061
- extensions: [".zig"],
2062
- serverCommand: "zls",
2063
- serverArgs: [],
2064
- rootPatterns: ["build.zig", "build.zig.zon"]
2065
- },
2066
- // Lua
2067
- {
2068
- id: "lua",
2069
- name: "Lua",
2070
- extensions: [".lua"],
2071
- serverCommand: "lua-language-server",
2072
- serverArgs: [],
2073
- rootPatterns: [".luarc.json", ".luarc.jsonc", ".luacheckrc"]
2074
- },
2075
- // Ruby
2076
- {
2077
- id: "ruby",
2078
- name: "Ruby",
2079
- extensions: [".rb", ".rake", ".gemspec"],
2080
- serverCommand: "solargraph",
2081
- serverArgs: ["stdio"],
2082
- rootPatterns: ["Gemfile", ".ruby-version"]
2083
- },
2084
- // Elixir
2085
- {
2086
- id: "elixir",
2087
- name: "Elixir",
2088
- extensions: [".ex", ".exs"],
2089
- serverCommand: "elixir-ls",
2090
- serverArgs: [],
2091
- rootPatterns: ["mix.exs"]
2092
- },
2093
- // Haskell
2094
- {
2095
- id: "haskell",
2096
- name: "Haskell",
2097
- extensions: [".hs", ".lhs"],
2098
- serverCommand: "haskell-language-server-wrapper",
2099
- serverArgs: ["--lsp"],
2100
- rootPatterns: ["stack.yaml", "cabal.project", "*.cabal"]
2101
- },
2102
- // OCaml
2103
- {
2104
- id: "ocaml",
2105
- name: "OCaml",
2106
- extensions: [".ml", ".mli"],
2107
- serverCommand: "ocamllsp",
2108
- serverArgs: [],
2109
- rootPatterns: ["dune-project", "dune", "*.opam"]
2110
- },
2111
- // Scala
2112
- {
2113
- id: "scala",
2114
- name: "Scala",
2115
- extensions: [".scala", ".sc"],
2116
- serverCommand: "metals",
2117
- serverArgs: [],
2118
- rootPatterns: ["build.sbt", "build.sc", ".metals"]
2119
- },
2120
- // Kotlin
2121
- {
2122
- id: "kotlin",
2123
- name: "Kotlin",
2124
- extensions: [".kt", ".kts"],
2125
- serverCommand: "kotlin-language-server",
2126
- serverArgs: [],
2127
- rootPatterns: ["build.gradle.kts", "build.gradle", "settings.gradle.kts"]
2128
- },
2129
- // Java
2130
- {
2131
- id: "java",
2132
- name: "Java",
2133
- extensions: [".java"],
2134
- serverCommand: "jdtls",
2135
- serverArgs: [],
2136
- rootPatterns: ["pom.xml", "build.gradle", ".project"]
2137
- },
2138
- // C#
2139
- {
2140
- id: "csharp",
2141
- name: "C#",
2142
- extensions: [".cs", ".csx"],
2143
- serverCommand: "OmniSharp",
2144
- serverArgs: ["-lsp"],
2145
- rootPatterns: ["*.csproj", "*.sln"]
2146
- },
2147
- // Swift
2148
- {
2149
- id: "swift",
2150
- name: "Swift",
2151
- extensions: [".swift"],
2152
- serverCommand: "sourcekit-lsp",
2153
- serverArgs: [],
2154
- rootPatterns: ["Package.swift", "*.xcodeproj", "*.xcworkspace"]
2155
- },
2156
- // PHP
2157
- {
2158
- id: "php",
2159
- name: "PHP",
2160
- extensions: [".php", ".phtml"],
2161
- serverCommand: "phpactor",
2162
- serverArgs: ["language-server"],
2163
- rootPatterns: ["composer.json", "phpunit.xml"]
2164
- },
2165
- // YAML
2166
- {
2167
- id: "yaml",
2168
- name: "YAML",
2169
- extensions: [".yaml", ".yml"],
2170
- serverCommand: "yaml-language-server",
2171
- serverArgs: ["--stdio"],
2172
- rootPatterns: []
2173
- },
2174
- // JSON
2175
- {
2176
- id: "json",
2177
- name: "JSON",
2178
- extensions: [".json", ".jsonc"],
2179
- serverCommand: "vscode-json-language-server",
2180
- serverArgs: ["--stdio"],
2181
- rootPatterns: []
2182
- },
2183
- // HTML
2184
- {
2185
- id: "html",
2186
- name: "HTML",
2187
- extensions: [".html", ".htm", ".xhtml"],
2188
- serverCommand: "vscode-html-language-server",
2189
- serverArgs: ["--stdio"],
2190
- rootPatterns: []
2191
- },
2192
- // CSS
2193
- {
2194
- id: "css",
2195
- name: "CSS",
2196
- extensions: [".css", ".scss", ".sass", ".less"],
2197
- serverCommand: "vscode-css-language-server",
2198
- serverArgs: ["--stdio"],
2199
- rootPatterns: []
2200
- },
2201
- // Vue
2202
- {
2203
- id: "vue",
2204
- name: "Vue",
2205
- extensions: [".vue"],
2206
- serverCommand: "vue-language-server",
2207
- serverArgs: ["--stdio"],
2208
- rootPatterns: ["vite.config.ts", "vite.config.js", "vue.config.js"]
2209
- },
2210
- // Svelte
2211
- {
2212
- id: "svelte",
2213
- name: "Svelte",
2214
- extensions: [".svelte"],
2215
- serverCommand: "svelteserver",
2216
- serverArgs: ["--stdio"],
2217
- rootPatterns: ["svelte.config.js", "svelte.config.ts"]
2218
- },
2219
- // Terraform
2220
- {
2221
- id: "terraform",
2222
- name: "Terraform",
2223
- extensions: [".tf", ".tfvars"],
2224
- serverCommand: "terraform-ls",
2225
- serverArgs: ["serve"],
2226
- rootPatterns: [".terraform", "main.tf"]
2227
- },
2228
- // Dockerfile
2229
- {
2230
- id: "dockerfile",
2231
- name: "Docker",
2232
- extensions: [],
2233
- // Uses filename matching
2234
- serverCommand: "docker-langserver",
2235
- serverArgs: ["--stdio"],
2236
- rootPatterns: ["Dockerfile", "docker-compose.yml"]
2237
- },
2238
- // Bash/Shell
2239
- {
2240
- id: "bash",
2241
- name: "Bash",
2242
- extensions: [".sh", ".bash", ".zsh"],
2243
- serverCommand: "bash-language-server",
2244
- serverArgs: ["start"],
2245
- rootPatterns: []
2246
- },
2247
- // SQL
2248
- {
2249
- id: "sql",
2250
- name: "SQL",
2251
- extensions: [".sql"],
2252
- serverCommand: "sql-language-server",
2253
- serverArgs: ["up", "--method", "stdio"],
2254
- rootPatterns: [],
2255
- installHint: "npm install -g sql-language-server"
2256
- },
2257
- // GraphQL
2258
- {
2259
- id: "graphql",
2260
- name: "GraphQL",
2261
- extensions: [".graphql", ".gql"],
2262
- serverCommand: "graphql-lsp",
2263
- serverArgs: ["server", "-m", "stream"],
2264
- rootPatterns: [".graphqlrc", ".graphqlrc.yml", ".graphqlrc.json", "graphql.config.js"]
2265
- },
2266
- // Nix
2267
- {
2268
- id: "nix",
2269
- name: "Nix",
2270
- extensions: [".nix"],
2271
- serverCommand: "nil",
2272
- serverArgs: [],
2273
- rootPatterns: ["flake.nix", "default.nix", "shell.nix"]
2274
- },
2275
- // Gleam
2276
- {
2277
- id: "gleam",
2278
- name: "Gleam",
2279
- extensions: [".gleam"],
2280
- serverCommand: "gleam",
2281
- serverArgs: ["lsp"],
2282
- rootPatterns: ["gleam.toml"]
2283
- },
2284
- // Elm
2285
- {
2286
- id: "elm",
2287
- name: "Elm",
2288
- extensions: [".elm"],
2289
- serverCommand: "elm-language-server",
2290
- serverArgs: [],
2291
- rootPatterns: ["elm.json"]
2292
- },
2293
- // Dart
2294
- {
2295
- id: "dart",
2296
- name: "Dart",
2297
- extensions: [".dart"],
2298
- serverCommand: "dart",
2299
- serverArgs: ["language-server", "--protocol=lsp"],
2300
- rootPatterns: ["pubspec.yaml"]
2301
- },
2302
- // Julia
2303
- {
2304
- id: "julia",
2305
- name: "Julia",
2306
- extensions: [".jl"],
2307
- serverCommand: "julia",
2308
- serverArgs: ["--startup-file=no", "--history-file=no", "-e", "using LanguageServer; runserver()"],
2309
- rootPatterns: ["Project.toml"]
2310
- },
2311
- // R
2312
- {
2313
- id: "r",
2314
- name: "R",
2315
- extensions: [".r", ".R", ".rmd", ".Rmd"],
2316
- serverCommand: "R",
2317
- serverArgs: ["--slave", "-e", "languageserver::run()"],
2318
- rootPatterns: ["DESCRIPTION", ".Rproj"]
2319
- },
2320
- // Clojure
2321
- {
2322
- id: "clojure",
2323
- name: "Clojure",
2324
- extensions: [".clj", ".cljs", ".cljc", ".edn"],
2325
- serverCommand: "clojure-lsp",
2326
- serverArgs: [],
2327
- rootPatterns: ["deps.edn", "project.clj", "shadow-cljs.edn"]
2328
- },
2329
- // Nim
2330
- {
2331
- id: "nim",
2332
- name: "Nim",
2333
- extensions: [".nim", ".nims"],
2334
- serverCommand: "nimlsp",
2335
- serverArgs: [],
2336
- rootPatterns: ["*.nimble"]
2337
- },
2338
- // V
2339
- {
2340
- id: "vlang",
2341
- name: "V",
2342
- extensions: [".v", ".vv"],
2343
- serverCommand: "vls",
2344
- serverArgs: [],
2345
- rootPatterns: ["v.mod"]
2346
- },
2347
- // Crystal
2348
- {
2349
- id: "crystal",
2350
- name: "Crystal",
2351
- extensions: [".cr"],
2352
- serverCommand: "crystalline",
2353
- serverArgs: [],
2354
- rootPatterns: ["shard.yml"]
2355
- },
2356
- // D
2357
- {
2358
- id: "d",
2359
- name: "D",
2360
- extensions: [".d"],
2361
- serverCommand: "serve-d",
2362
- serverArgs: [],
2363
- rootPatterns: ["dub.json", "dub.sdl"]
2364
- },
2365
- // Erlang
2366
- {
2367
- id: "erlang",
2368
- name: "Erlang",
2369
- extensions: [".erl", ".hrl"],
2370
- serverCommand: "erlang_ls",
2371
- serverArgs: [],
2372
- rootPatterns: ["rebar.config", "erlang.mk"]
2373
- },
2374
- // F#
2375
- {
2376
- id: "fsharp",
2377
- name: "F#",
2378
- extensions: [".fs", ".fsx", ".fsi"],
2379
- serverCommand: "fsautocomplete",
2380
- serverArgs: ["--adaptive-lsp-server-enabled"],
2381
- rootPatterns: ["*.fsproj"]
2382
- },
2383
- // Fortran
2384
- {
2385
- id: "fortran",
2386
- name: "Fortran",
2387
- extensions: [".f", ".f90", ".f95", ".f03", ".f08"],
2388
- serverCommand: "fortls",
2389
- serverArgs: [],
2390
- rootPatterns: []
2391
- },
2392
- // LaTeX
2393
- {
2394
- id: "latex",
2395
- name: "LaTeX",
2396
- extensions: [".tex", ".bib"],
2397
- serverCommand: "texlab",
2398
- serverArgs: [],
2399
- rootPatterns: ["*.tex"]
2400
- },
2401
- // Markdown
2402
- {
2403
- id: "markdown",
2404
- name: "Markdown",
2405
- extensions: [".md", ".markdown"],
2406
- serverCommand: "marksman",
2407
- serverArgs: [],
2408
- rootPatterns: []
2409
- },
2410
- // TOML
2411
- {
2412
- id: "toml",
2413
- name: "TOML",
2414
- extensions: [".toml"],
2415
- serverCommand: "taplo",
2416
- serverArgs: ["lsp", "stdio"],
2417
- rootPatterns: []
2418
- },
2419
- // Protobuf
2420
- {
2421
- id: "protobuf",
2422
- name: "Protocol Buffers",
2423
- extensions: [".proto"],
2424
- serverCommand: "bufls",
2425
- serverArgs: ["serve"],
2426
- rootPatterns: ["buf.yaml", "buf.gen.yaml"]
2427
- },
2428
- // Assembly (various)
2429
- {
2430
- id: "asm",
2431
- name: "Assembly",
2432
- extensions: [".asm", ".s", ".S"],
2433
- serverCommand: "asm-lsp",
2434
- serverArgs: [],
2435
- rootPatterns: []
2436
- },
2437
- // CMake
2438
- {
2439
- id: "cmake",
2440
- name: "CMake",
2441
- extensions: [".cmake"],
2442
- serverCommand: "cmake-language-server",
2443
- serverArgs: [],
2444
- rootPatterns: ["CMakeLists.txt"]
2445
- },
2446
- // Perl
2447
- {
2448
- id: "perl",
2449
- name: "Perl",
2450
- extensions: [".pl", ".pm"],
2451
- serverCommand: "pls",
2452
- serverArgs: [],
2453
- rootPatterns: ["cpanfile", "Makefile.PL"]
2454
- }
2455
- ];
1944
+ import { readFileSync } from "fs";
1945
+ import { fileURLToPath as fileURLToPath2 } from "url";
1946
+ import { dirname as dirname2, resolve } from "path";
1947
+ var __dirname2 = dirname2(fileURLToPath2(import.meta.url));
1948
+ var languagesJson = JSON.parse(readFileSync(resolve(__dirname2, "languages.json"), "utf-8"));
1949
+ var LANGUAGES = languagesJson;
2456
1950
  var extensionToLanguage = /* @__PURE__ */ new Map();
2457
1951
  for (const lang of LANGUAGES) {
2458
1952
  for (const ext of lang.extensions) {
@@ -3588,10 +3082,10 @@ function createSkillRoutes(configDir, projectDir) {
3588
3082
 
3589
3083
  // src/server/commands/registry.ts
3590
3084
  import { writeFile, mkdir, unlink } from "fs/promises";
3591
- import { join as join3, dirname as dirname2 } from "path";
3592
- import { fileURLToPath as fileURLToPath2 } from "url";
3085
+ import { join as join3, dirname as dirname3 } from "path";
3086
+ import { fileURLToPath as fileURLToPath3 } from "url";
3593
3087
  import matter from "gray-matter";
3594
- var __bundleDir = dirname2(fileURLToPath2(import.meta.url));
3088
+ var __bundleDir = dirname3(fileURLToPath3(import.meta.url));
3595
3089
  var DEFAULTS_DIR = join3(__bundleDir, "defaults");
3596
3090
  var DEFAULTS_DIR_ALT = join3(__bundleDir, "command-defaults");
3597
3091
  var COMMAND_EXTENSION = ".command.md";
@@ -3910,20 +3404,20 @@ function createTerminalRoutes() {
3910
3404
  // src/server/routes/directories.ts
3911
3405
  import { Router as Router5 } from "express";
3912
3406
  import { readdir } from "fs/promises";
3913
- import { resolve, join as join4, dirname as dirname3, basename as basename2 } from "path";
3407
+ import { resolve as resolve2, join as join4, dirname as dirname4, basename as basename2 } from "path";
3914
3408
  function createDirectoryRoutes() {
3915
3409
  const router = Router5();
3916
3410
  const DEFAULT_BASE_PATH = process.cwd();
3917
3411
  router.get("/", async (req, res) => {
3918
3412
  const path = req.query["path"] || DEFAULT_BASE_PATH;
3919
3413
  try {
3920
- const resolvedPath = resolve(path);
3414
+ const resolvedPath = resolve2(path);
3921
3415
  const entries = await readdir(resolvedPath, { withFileTypes: true });
3922
3416
  const directories = entries.filter((entry) => entry.isDirectory()).map((entry) => ({
3923
3417
  name: entry.name,
3924
3418
  path: join4(resolvedPath, entry.name)
3925
3419
  })).sort((a, b) => a.name.localeCompare(b.name));
3926
- const parent = dirname3(resolvedPath);
3420
+ const parent = dirname4(resolvedPath);
3927
3421
  const hasParent = parent !== resolvedPath;
3928
3422
  res.json({
3929
3423
  current: resolvedPath,
@@ -3949,7 +3443,7 @@ import { Router as Router6 } from "express";
3949
3443
  import { spawn as spawn2 } from "child_process";
3950
3444
 
3951
3445
  // src/constants.ts
3952
- var VERSION = "2.0.18";
3446
+ var VERSION = "2.0.20";
3953
3447
 
3954
3448
  // src/server/routes/auto-update.ts
3955
3449
  var updateInProgress = false;
@@ -3972,7 +3466,7 @@ function createAutoUpdateRoutes(options = {}) {
3972
3466
  const isService = isRunningAsService();
3973
3467
  const current = VERSION;
3974
3468
  try {
3975
- const latest = await new Promise((resolve3, reject) => {
3469
+ const latest = await new Promise((resolve4, reject) => {
3976
3470
  const child = spawn2("npm", ["view", "openfox", "version"], {
3977
3471
  stdio: ["ignore", "pipe", "pipe"]
3978
3472
  });
@@ -3982,7 +3476,7 @@ function createAutoUpdateRoutes(options = {}) {
3982
3476
  });
3983
3477
  child.on("close", (code) => {
3984
3478
  if (code === 0) {
3985
- resolve3(stdout.trim());
3479
+ resolve4(stdout.trim());
3986
3480
  } else {
3987
3481
  reject(new Error(`npm view exited with code ${code}`));
3988
3482
  }
@@ -4025,9 +3519,9 @@ function createAutoUpdateRoutes(options = {}) {
4025
3519
  const timeout = setTimeout(() => {
4026
3520
  child.kill();
4027
3521
  }, UPDATE_TIMEOUT);
4028
- const exitCode = await new Promise((resolve3) => {
4029
- child.on("close", resolve3);
4030
- child.on("error", () => resolve3(1));
3522
+ const exitCode = await new Promise((resolve4) => {
3523
+ child.on("close", resolve4);
3524
+ child.on("error", () => resolve4(1));
4031
3525
  });
4032
3526
  clearTimeout(timeout);
4033
3527
  if (exitCode === 0) {
@@ -4064,7 +3558,7 @@ function createAutoUpdateRoutes(options = {}) {
4064
3558
  }
4065
3559
 
4066
3560
  // src/server/index.ts
4067
- var __dirname2 = dirname4(fileURLToPath3(import.meta.url));
3561
+ var __dirname3 = dirname5(fileURLToPath4(import.meta.url));
4068
3562
  async function createServerHandle(config4) {
4069
3563
  setRuntimeConfig(config4);
4070
3564
  setLogLevel(config4.logging?.level ?? void 0, config4.mode);
@@ -4129,7 +3623,7 @@ async function createServerHandle(config4) {
4129
3623
  setMcpTools(mcpTools);
4130
3624
  logger.info("MCP tools registered", { count: mcpTools.length });
4131
3625
  }
4132
- const { signalMcpReady } = await import("./server-IZL6UZEZ.js");
3626
+ const { signalMcpReady } = await import("./server-CN7ML6XN.js");
4133
3627
  signalMcpReady();
4134
3628
  });
4135
3629
  const app = express();
@@ -4287,7 +3781,7 @@ async function createServerHandle(config4) {
4287
3781
  res.json({ project });
4288
3782
  });
4289
3783
  app.get("/api/sessions", async (req, res) => {
4290
- const { getRecentUserPromptsForSession } = await import("./events-4K52FKPR.js");
3784
+ const { getRecentUserPromptsForSession } = await import("./events-JKPHAR5W.js");
4291
3785
  const projectId = req.query["projectId"];
4292
3786
  const limit = Math.min(parseInt(req.query["limit"]) || 20, 100);
4293
3787
  const offset = parseInt(req.query["offset"]) || 0;
@@ -4320,9 +3814,9 @@ async function createServerHandle(config4) {
4320
3814
  res.status(201).json({ session });
4321
3815
  });
4322
3816
  app.get("/api/sessions/:id", async (req, res) => {
4323
- const { getEventStore: getEventStore2 } = await import("./events-4K52FKPR.js");
4324
- const { buildMessagesFromStoredEvents } = await import("./folding-QIBNKYA6.js");
4325
- const { getPendingQuestionsForSession } = await import("./tools-QTEXQQ7Z.js");
3817
+ const { getEventStore: getEventStore2 } = await import("./events-JKPHAR5W.js");
3818
+ const { buildMessagesFromStoredEvents } = await import("./folding-PI67HWBR.js");
3819
+ const { getPendingQuestionsForSession } = await import("./tools-ZUOBYTVD.js");
4326
3820
  const session = sessionManager.getSession(req.params.id);
4327
3821
  if (!session) {
4328
3822
  return res.status(404).json({ error: "Session not found" });
@@ -4353,8 +3847,8 @@ async function createServerHandle(config4) {
4353
3847
  res.json({ success: true });
4354
3848
  });
4355
3849
  app.post("/api/sessions/:id/provider", async (req, res) => {
4356
- const { getEventStore: getEventStore2 } = await import("./events-4K52FKPR.js");
4357
- const { buildMessagesFromStoredEvents } = await import("./folding-QIBNKYA6.js");
3850
+ const { getEventStore: getEventStore2 } = await import("./events-JKPHAR5W.js");
3851
+ const { buildMessagesFromStoredEvents } = await import("./folding-PI67HWBR.js");
4358
3852
  const sessionId = req.params.id;
4359
3853
  const session = sessionManager.getSession(sessionId);
4360
3854
  if (!session) {
@@ -4396,8 +3890,8 @@ async function createServerHandle(config4) {
4396
3890
  res.json({ success: true });
4397
3891
  });
4398
3892
  app.put("/api/sessions/:id/mode", async (req, res) => {
4399
- const { getEventStore: getEventStore2 } = await import("./events-4K52FKPR.js");
4400
- const { buildMessagesFromStoredEvents } = await import("./folding-QIBNKYA6.js");
3893
+ const { getEventStore: getEventStore2 } = await import("./events-JKPHAR5W.js");
3894
+ const { buildMessagesFromStoredEvents } = await import("./folding-PI67HWBR.js");
4401
3895
  const sessionId = req.params.id;
4402
3896
  const session = sessionManager.getSession(sessionId);
4403
3897
  if (!session) {
@@ -4453,15 +3947,15 @@ async function createServerHandle(config4) {
4453
3947
  if (!callId || approved === void 0) {
4454
3948
  return res.status(400).json({ error: "callId and approved are required" });
4455
3949
  }
4456
- const { providePathConfirmation } = await import("./tools-QTEXQQ7Z.js");
3950
+ const { providePathConfirmation } = await import("./tools-ZUOBYTVD.js");
4457
3951
  const result = providePathConfirmation(callId, approved, alwaysAllow);
4458
3952
  if (!result.found) {
4459
3953
  return res.status(404).json({ error: "No pending path confirmation with that ID" });
4460
3954
  }
4461
- const { getEventStore: getEventStore2 } = await import("./events-4K52FKPR.js");
4462
- const { buildMessagesFromStoredEvents, foldPendingConfirmations } = await import("./folding-QIBNKYA6.js");
3955
+ const { getEventStore: getEventStore2 } = await import("./events-JKPHAR5W.js");
3956
+ const { buildMessagesFromStoredEvents, foldPendingConfirmations } = await import("./folding-PI67HWBR.js");
4463
3957
  const { createSessionStateMessage } = await import("./protocol-BKNLAEPJ.js");
4464
- const { getPendingQuestionsForSession } = await import("./tools-QTEXQQ7Z.js");
3958
+ const { getPendingQuestionsForSession } = await import("./tools-ZUOBYTVD.js");
4465
3959
  const eventStore = getEventStore2();
4466
3960
  const events = eventStore.getEvents(sessionId);
4467
3961
  const messages = buildMessagesFromStoredEvents(events);
@@ -4482,7 +3976,7 @@ async function createServerHandle(config4) {
4482
3976
  if (!skip && typeof answer !== "string") {
4483
3977
  return res.status(400).json({ error: "answer is required when not skipping" });
4484
3978
  }
4485
- const { provideAnswer } = await import("./tools-QTEXQQ7Z.js");
3979
+ const { provideAnswer } = await import("./tools-ZUOBYTVD.js");
4486
3980
  const found = provideAnswer(callId, answer ?? "", skip ?? false);
4487
3981
  if (!found) {
4488
3982
  return res.status(404).json({ error: "No pending question with that ID" });
@@ -4518,15 +4012,15 @@ async function createServerHandle(config4) {
4518
4012
  if (!session) {
4519
4013
  return res.status(404).json({ error: "Session not found" });
4520
4014
  }
4521
- const { stopSessionExecution } = await import("./chat-handler-Z2C4372A.js");
4522
- const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-QTEXQQ7Z.js");
4015
+ const { stopSessionExecution } = await import("./chat-handler-KNDSH5WR.js");
4016
+ const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-ZUOBYTVD.js");
4523
4017
  const queuedMessages = sessionManager.getQueueState(sessionId);
4524
4018
  sessionManager.clearMessageQueue(sessionId);
4525
4019
  stopSessionExecution(sessionId, sessionManager);
4526
4020
  abortSession(sessionId);
4527
4021
  cancelQuestionsForSession(sessionId, "Session stopped by user");
4528
4022
  cancelPathConfirmationsForSession(sessionId, "Session stopped by user");
4529
- const eventStore = (await import("./events-4K52FKPR.js")).getEventStore();
4023
+ const eventStore = (await import("./events-JKPHAR5W.js")).getEventStore();
4530
4024
  eventStore.append(sessionId, { type: "running.changed", data: { isRunning: false } });
4531
4025
  res.json({ success: true, queuedMessages });
4532
4026
  });
@@ -4540,7 +4034,7 @@ async function createServerHandle(config4) {
4540
4034
  if (typeof messageIndex !== "number" || messageIndex < 0) {
4541
4035
  return res.status(400).json({ error: "messageIndex must be a non-negative number" });
4542
4036
  }
4543
- const { truncateSessionMessages } = await import("./events-4K52FKPR.js");
4037
+ const { truncateSessionMessages } = await import("./events-JKPHAR5W.js");
4544
4038
  truncateSessionMessages(sessionId, messageIndex);
4545
4039
  res.json({ success: true });
4546
4040
  });
@@ -4558,7 +4052,7 @@ async function createServerHandle(config4) {
4558
4052
  if (!msg) {
4559
4053
  return res.status(400).json({ error: "Message not found at this index" });
4560
4054
  }
4561
- const { truncateSessionMessages } = await import("./events-4K52FKPR.js");
4055
+ const { truncateSessionMessages } = await import("./events-JKPHAR5W.js");
4562
4056
  truncateSessionMessages(sessionId, messageIndex - 1);
4563
4057
  sessionManager.queueMessage(sessionId, "asap", msg.content, msg.attachments, msg.messageKind);
4564
4058
  res.json({ success: true });
@@ -4962,7 +4456,7 @@ async function createServerHandle(config4) {
4962
4456
  });
4963
4457
  async function rebuildMcpTools() {
4964
4458
  const { createMcpTools: createMcpTools2 } = await import("./tool-adapter-B7QP6NLA.js");
4965
- const { setMcpTools: setMcpTools2 } = await import("./tools-QTEXQQ7Z.js");
4459
+ const { setMcpTools: setMcpTools2 } = await import("./tools-ZUOBYTVD.js");
4966
4460
  const mcpTools = createMcpTools2(mcpManager);
4967
4461
  setMcpTools2(mcpTools);
4968
4462
  }
@@ -5146,14 +4640,14 @@ async function createServerHandle(config4) {
5146
4640
  await getCurrentBranch(req, res);
5147
4641
  });
5148
4642
  app.use("/api/directories", createDirectoryRoutes());
5149
- const webDir = resolve2(__dirname2, "../../web");
4643
+ const webDir = resolve3(__dirname3, "../../web");
5150
4644
  const isDev = config4.mode === "development";
5151
4645
  let viteServer;
5152
4646
  if (isDev) {
5153
4647
  logger.info("Dev mode: using Vite middleware");
5154
4648
  viteServer = await createViteServer({
5155
4649
  root: webDir,
5156
- configFile: resolve2(__dirname2, "../../web/vite.config.ts"),
4650
+ configFile: resolve3(__dirname3, "../../web/vite.config.ts"),
5157
4651
  server: { middlewareMode: true },
5158
4652
  appType: "spa",
5159
4653
  logLevel: "warn"
@@ -5205,7 +4699,7 @@ async function createServerHandle(config4) {
5205
4699
  logger.info("Vite middleware ready", { port: config4.server.port });
5206
4700
  }
5207
4701
  if (!isDev) {
5208
- const distWebDir = resolve2(__dirname2, "web");
4702
+ const distWebDir = resolve3(__dirname3, "web");
5209
4703
  app.use(
5210
4704
  "/assets",
5211
4705
  express.static(join5(distWebDir, "assets"), {
@@ -5274,7 +4768,7 @@ async function createServerHandle(config4) {
5274
4768
  const state = sessionManager.getContextState(sessionId);
5275
4769
  wssExports.broadcastForSession(sessionId, createContextStateMessage(state));
5276
4770
  });
5277
- const { QueueProcessor } = await import("./processor-GUUAJ24C.js");
4771
+ const { QueueProcessor } = await import("./processor-DKAYI3PV.js");
5278
4772
  const queueProcessor = new QueueProcessor({
5279
4773
  sessionManager,
5280
4774
  providerManager,
@@ -5296,7 +4790,7 @@ async function createServerHandle(config4) {
5296
4790
  return {
5297
4791
  httpServer,
5298
4792
  ctx: { config: config4, sessionManager, llmClient: getLLMClient(), toolRegistry, providerManager },
5299
- start: (port) => new Promise((resolve3, reject) => {
4793
+ start: (port) => new Promise((resolve4, reject) => {
5300
4794
  const listenPort = port ?? config4.server.port;
5301
4795
  const host = config4.server.host;
5302
4796
  httpServer.listen(listenPort, host, () => {
@@ -5306,11 +4800,11 @@ async function createServerHandle(config4) {
5306
4800
  logger.info(`OpenFox server running at http://${host}:${actualPort}`);
5307
4801
  logger.info(`WebSocket available at ws://${host}:${actualPort}/ws`);
5308
4802
  logger.info(`LLM backend: ${client.getBackend()}, model: ${client.getModel()}, url: ${config4.llm.baseUrl}`);
5309
- resolve3({ port: actualPort });
4803
+ resolve4({ port: actualPort });
5310
4804
  });
5311
4805
  httpServer.on("error", reject);
5312
4806
  }),
5313
- close: () => new Promise((resolve3) => {
4807
+ close: () => new Promise((resolve4) => {
5314
4808
  logger.info("Shutting down...");
5315
4809
  void (async () => {
5316
4810
  await devServerManager.stopAll();
@@ -5324,7 +4818,7 @@ async function createServerHandle(config4) {
5324
4818
  client.terminate();
5325
4819
  }
5326
4820
  wss.close();
5327
- httpServer.close(() => resolve3());
4821
+ httpServer.close(() => resolve4());
5328
4822
  })();
5329
4823
  })
5330
4824
  };
@@ -5349,4 +4843,4 @@ export {
5349
4843
  createServerHandle,
5350
4844
  createServer
5351
4845
  };
5352
- //# sourceMappingURL=chunk-FERQPF5N.js.map
4846
+ //# sourceMappingURL=chunk-3QQ4QKAU.js.map