pair-mode 0.3.0 → 0.4.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 (53) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.codex-plugin/plugin.json +2 -8
  3. package/README.md +71 -12
  4. package/assets/duck-appalled-banner-sprite.png +0 -0
  5. package/assets/duck-appalled-banner-v2-sprite.png +0 -0
  6. package/assets/duck-appalled-banner-v2.gif +0 -0
  7. package/assets/duck-appalled-sprite.png +0 -0
  8. package/assets/duck-appalled.gif +0 -0
  9. package/assets/duck-before-main.png +0 -0
  10. package/assets/duck.png +0 -0
  11. package/assets/favicon.png +0 -0
  12. package/assets/syntax/clojure.yaml +36 -0
  13. package/assets/syntax/cmake.yaml +41 -0
  14. package/assets/syntax/crystal.yaml +71 -0
  15. package/assets/syntax/csharp.yaml +51 -0
  16. package/assets/syntax/dart.yaml +45 -0
  17. package/assets/syntax/elm.yaml +38 -0
  18. package/assets/syntax/erb.yaml +42 -0
  19. package/assets/syntax/erlang.yaml +45 -0
  20. package/assets/syntax/fsharp.yaml +48 -0
  21. package/assets/syntax/graphql.yaml +47 -0
  22. package/assets/syntax/groovy.yaml +111 -0
  23. package/assets/syntax/haml.yaml +16 -0
  24. package/assets/syntax/haskell.yaml +52 -0
  25. package/assets/syntax/ini.yaml +23 -0
  26. package/assets/syntax/java.yaml +36 -0
  27. package/assets/syntax/julia.yaml +56 -0
  28. package/assets/syntax/kotlin.yaml +65 -0
  29. package/assets/syntax/makefile.yaml +37 -0
  30. package/assets/syntax/nginx.yaml +22 -0
  31. package/assets/syntax/nim.yaml +27 -0
  32. package/assets/syntax/nix.yaml +32 -0
  33. package/assets/syntax/objc.yaml +60 -0
  34. package/assets/syntax/ocaml.yaml +43 -0
  35. package/assets/syntax/perl.yaml +58 -0
  36. package/assets/syntax/php.yaml +60 -0
  37. package/assets/syntax/r.yaml +30 -0
  38. package/assets/syntax/scala.yaml +32 -0
  39. package/assets/syntax/svelte.yaml +27 -0
  40. package/assets/syntax/swift.yaml +102 -0
  41. package/assets/syntax/vue.yaml +63 -0
  42. package/assets/syntax/xml.yaml +37 -0
  43. package/assets/syntax/zig.yaml +52 -0
  44. package/dist/claude-code.js +463 -150
  45. package/dist/cli.js +1534 -459
  46. package/dist/codex.js +811 -394
  47. package/dist/opencode.js +455 -143
  48. package/dist/pair-tui.js +177 -27
  49. package/dist/pi.js +510 -156
  50. package/package.json +16 -17
  51. package/skills/toggle/SKILL.md +24 -0
  52. package/commands/pair.md +0 -18
  53. package/skills/pair/SKILL.md +0 -20
package/dist/pair-tui.js CHANGED
@@ -1835,59 +1835,205 @@ function paint(options) {
1835
1835
  }
1836
1836
 
1837
1837
  // src/editors/languages.ts
1838
- import { extname } from "node:path";
1839
- var LANGS = {
1838
+ import { openSync, readSync, closeSync } from "node:fs";
1839
+ import { basename as basename2, extname } from "node:path";
1840
+ var EXTENSIONS = {
1840
1841
  ".go": "go",
1841
1842
  ".rb": "ruby",
1842
1843
  ".rake": "ruby",
1844
+ ".gemspec": "ruby",
1845
+ ".ru": "ruby",
1846
+ ".erb": "erb",
1847
+ ".haml": "haml",
1843
1848
  ".ts": "typescript",
1844
- ".tsx": "typescript",
1849
+ ".mts": "typescript",
1850
+ ".cts": "typescript",
1851
+ ".tsx": "tsx",
1845
1852
  ".js": "javascript",
1846
- ".jsx": "javascript",
1847
1853
  ".mjs": "javascript",
1848
- ".py": "python3",
1854
+ ".cjs": "javascript",
1855
+ ".jsx": "jsx",
1856
+ ".vue": "vue",
1857
+ ".svelte": "svelte",
1858
+ ".astro": "astro",
1859
+ ".py": "python",
1860
+ ".pyi": "python",
1849
1861
  ".ex": "elixir",
1850
1862
  ".exs": "elixir",
1863
+ ".heex": "elixir",
1864
+ ".erl": "erlang",
1865
+ ".hrl": "erlang",
1851
1866
  ".rs": "rust",
1852
- ".sh": "sh",
1853
- ".bash": "sh",
1854
- ".fish": "fish",
1867
+ ".sh": "shellscript",
1868
+ ".bash": "shellscript",
1869
+ ".ksh": "shellscript",
1855
1870
  ".zsh": "zsh",
1871
+ ".fish": "fish",
1872
+ ".ps1": "powershell",
1873
+ ".psm1": "powershell",
1874
+ ".bat": "bat",
1875
+ ".cmd": "bat",
1856
1876
  ".sql": "sql",
1857
1877
  ".json": "json",
1878
+ ".jsonc": "jsonc",
1879
+ ".json5": "json5",
1858
1880
  ".tf": "terraform",
1881
+ ".tfvars": "terraform",
1882
+ ".hcl": "hcl",
1859
1883
  ".proto": "proto",
1860
- ".dockerfile": "dockerfile",
1884
+ ".dockerfile": "docker",
1861
1885
  ".toml": "toml",
1862
1886
  ".yaml": "yaml",
1863
1887
  ".yml": "yaml",
1888
+ ".ini": "ini",
1889
+ ".cfg": "ini",
1890
+ ".properties": "properties",
1891
+ ".env": "dotenv",
1864
1892
  ".md": "markdown",
1893
+ ".markdown": "markdown",
1894
+ ".mdx": "mdx",
1865
1895
  ".css": "css",
1896
+ ".scss": "scss",
1897
+ ".sass": "sass",
1898
+ ".less": "less",
1899
+ ".styl": "stylus",
1866
1900
  ".html": "html",
1867
- ".erb": "html",
1901
+ ".htm": "html",
1902
+ ".xml": "xml",
1903
+ ".xsl": "xml",
1904
+ ".svg": "xml",
1868
1905
  ".lua": "lua",
1869
1906
  ".c": "c",
1870
- ".h": "c"
1907
+ ".h": "c",
1908
+ ".cc": "cpp",
1909
+ ".cpp": "cpp",
1910
+ ".cxx": "cpp",
1911
+ ".hpp": "cpp",
1912
+ ".hh": "cpp",
1913
+ ".cs": "csharp",
1914
+ ".java": "java",
1915
+ ".kt": "kotlin",
1916
+ ".kts": "kotlin",
1917
+ ".swift": "swift",
1918
+ ".m": "objective-c",
1919
+ ".mm": "objective-c",
1920
+ ".php": "php",
1921
+ ".pl": "perl",
1922
+ ".pm": "perl",
1923
+ ".scala": "scala",
1924
+ ".sc": "scala",
1925
+ ".clj": "clojure",
1926
+ ".cljs": "clojure",
1927
+ ".cljc": "clojure",
1928
+ ".hs": "haskell",
1929
+ ".nix": "nix",
1930
+ ".r": "r",
1931
+ ".jl": "julia",
1932
+ ".zig": "zig",
1933
+ ".nim": "nim",
1934
+ ".dart": "dart",
1935
+ ".groovy": "groovy",
1936
+ ".gradle": "groovy",
1937
+ ".cr": "crystal",
1938
+ ".ml": "ocaml",
1939
+ ".mli": "ocaml",
1940
+ ".fs": "fsharp",
1941
+ ".fsx": "fsharp",
1942
+ ".elm": "elm",
1943
+ ".graphql": "graphql",
1944
+ ".gql": "graphql",
1945
+ ".prisma": "prisma",
1946
+ ".sol": "solidity",
1947
+ ".vim": "viml",
1948
+ ".diff": "diff",
1949
+ ".patch": "diff",
1950
+ ".tex": "latex",
1951
+ ".wgsl": "wgsl",
1952
+ ".glsl": "glsl",
1953
+ ".cue": "cue"
1871
1954
  };
1872
- function syntaxName(sourcePath) {
1873
- const ext = extname(sourcePath).toLowerCase();
1874
- return LANGS[ext] ?? null;
1875
- }
1876
- var SHIKI_TRANSLATIONS = {
1877
- python3: "python",
1878
- sh: "shellscript",
1879
- zsh: "shellscript",
1880
- fish: "fish",
1881
- proto: "proto",
1955
+ var FILENAMES = {
1956
+ gemfile: "ruby",
1957
+ rakefile: "ruby",
1958
+ capfile: "ruby",
1959
+ vagrantfile: "ruby",
1960
+ guardfile: "ruby",
1961
+ podfile: "ruby",
1962
+ fastfile: "ruby",
1963
+ appfile: "ruby",
1964
+ brewfile: "ruby",
1965
+ "config.ru": "ruby",
1882
1966
  dockerfile: "docker",
1883
- terraform: "terraform"
1967
+ containerfile: "docker",
1968
+ makefile: "make",
1969
+ gnumakefile: "make",
1970
+ "cmakelists.txt": "cmake",
1971
+ "cargo.lock": "toml",
1972
+ "gemfile.lock": "toml",
1973
+ ".babelrc": "json",
1974
+ ".eslintrc": "json",
1975
+ ".prettierrc": "json",
1976
+ ".env": "dotenv",
1977
+ ".gitconfig": "ini",
1978
+ ".editorconfig": "ini",
1979
+ "nginx.conf": "nginx",
1980
+ "pnpm-workspace.yaml": "yaml"
1884
1981
  };
1885
- function shikiLanguage(sourcePath) {
1886
- const name = syntaxName(sourcePath);
1887
- if (name === null) {
1982
+ var SHEBANGS = [
1983
+ { pattern: /^#!.*\/(env\s+)?ruby(\s|$)/, id: "ruby" },
1984
+ { pattern: /^#!.*\/(env\s+)?python[\d.]*(\s|$)/, id: "python" },
1985
+ { pattern: /^#!.*\/(env\s+)?(node|bun|deno)(\s|$)/, id: "javascript" },
1986
+ { pattern: /^#!.*\/(env\s+)?(bash|sh|ksh|dash)(\s|$)/, id: "shellscript" },
1987
+ { pattern: /^#!.*\/(env\s+)?zsh(\s|$)/, id: "zsh" },
1988
+ { pattern: /^#!.*\/(env\s+)?fish(\s|$)/, id: "fish" },
1989
+ { pattern: /^#!.*\/(env\s+)?perl(\s|$)/, id: "perl" },
1990
+ { pattern: /^#!.*\/(env\s+)?php(\s|$)/, id: "php" },
1991
+ { pattern: /^#!.*\/(env\s+)?(elixir|iex)(\s|$)/, id: "elixir" },
1992
+ { pattern: /^#!.*\/(env\s+)?lua(\s|$)/, id: "lua" },
1993
+ { pattern: /^#!.*\/(env\s+)?Rscript(\s|$)/, id: "r" },
1994
+ { pattern: /^#!.*\/(env\s+)?pwsh(\s|$)/, id: "powershell" }
1995
+ ];
1996
+ var FIRST_LINE_BYTES = 256;
1997
+ function firstLine(sourcePath) {
1998
+ let handle = null;
1999
+ try {
2000
+ handle = openSync(sourcePath, "r");
2001
+ const buffer = Buffer.alloc(FIRST_LINE_BYTES);
2002
+ const read = readSync(handle, buffer, 0, FIRST_LINE_BYTES, 0);
2003
+ const text = buffer.toString("utf-8", 0, read);
2004
+ const newline = text.indexOf("\n");
2005
+ return newline === -1 ? text : text.slice(0, newline);
2006
+ } catch {
2007
+ return null;
2008
+ } finally {
2009
+ if (handle !== null) {
2010
+ try {
2011
+ closeSync(handle);
2012
+ } catch {
2013
+ }
2014
+ }
2015
+ }
2016
+ }
2017
+ function shebangLanguage(sourcePath) {
2018
+ const line = firstLine(sourcePath);
2019
+ if (line === null || !line.startsWith("#!")) {
1888
2020
  return null;
1889
2021
  }
1890
- return SHIKI_TRANSLATIONS[name] ?? name;
2022
+ return SHEBANGS.find((rule) => rule.pattern.test(line))?.id ?? null;
2023
+ }
2024
+ function detectLanguage(sourcePath) {
2025
+ const name = basename2(sourcePath).toLowerCase();
2026
+ const ext = extname(name);
2027
+ if (ext !== "" && EXTENSIONS[ext] !== void 0) {
2028
+ return EXTENSIONS[ext];
2029
+ }
2030
+ if (FILENAMES[name] !== void 0) {
2031
+ return FILENAMES[name];
2032
+ }
2033
+ return shebangLanguage(sourcePath);
2034
+ }
2035
+ function shikiLanguage(sourcePath) {
2036
+ return detectLanguage(sourcePath);
1891
2037
  }
1892
2038
 
1893
2039
  // src/tui/syntax/syntax.ts
@@ -2096,6 +2242,7 @@ function splitInput(chunk) {
2096
2242
 
2097
2243
  // src/tui/notes/notes.ts
2098
2244
  import { writeFileSync } from "node:fs";
2245
+ var OWNER_ONLY_FILE = 384;
2099
2246
  function rangeOf(selection) {
2100
2247
  const reversed = selection.anchorRow > selection.headRow || selection.anchorRow === selection.headRow && selection.anchorColumn > selection.headColumn;
2101
2248
  if (!reversed) {
@@ -2166,7 +2313,10 @@ function toQuestions(notes) {
2166
2313
  }
2167
2314
  function writeResult(path, notes) {
2168
2315
  try {
2169
- writeFileSync(path, JSON.stringify({ questions: toQuestions(notes) }, null, 2), "utf-8");
2316
+ writeFileSync(path, JSON.stringify({ questions: toQuestions(notes) }, null, 2), {
2317
+ encoding: "utf-8",
2318
+ mode: OWNER_ONLY_FILE
2319
+ });
2170
2320
  } catch {
2171
2321
  return;
2172
2322
  }