githits 0.2.1 → 0.2.2

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.
@@ -6,7 +6,7 @@
6
6
  },
7
7
  "metadata": {
8
8
  "description": "GitHits plugins for Claude Code - code examples from global open source",
9
- "version": "0.2.1"
9
+ "version": "0.2.2"
10
10
  },
11
11
  "plugins": [
12
12
  {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "githits",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Code examples from global open source for developers and AI assistants",
5
5
  "author": {
6
6
  "name": "GitHits"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "githits",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Code examples from global open source for developers and AI assistants",
5
5
  "author": {
6
6
  "name": "GitHits"
package/GEMINI.md CHANGED
@@ -11,12 +11,12 @@ Find code examples from open source repositories.
11
11
  **Parameters:**
12
12
 
13
13
  - `query` (string, required) - natural language description of what you need
14
- - `language` (string, required) - programming language name (use `search_language` to verify)
14
+ - `language` (string, optional) - programming language name; omit it to let GitHits infer the language from the query
15
15
  - `license_mode` (string, optional) - one of `strict` (default), `yolo`, or `custom`
16
16
 
17
17
  ### search_language
18
18
 
19
- Look up supported programming language names. Use this before calling `get_example` to get the correct language identifier.
19
+ Look up supported programming language names. Use this before calling `get_example` only when you need to force a specific language and the exact name is uncertain.
20
20
 
21
21
  **Parameters:**
22
22
 
@@ -60,7 +60,7 @@ Do not use `get_example` for:
60
60
 
61
61
  ## How to Search Well
62
62
 
63
- - Call `search_language` first to confirm the correct language name before calling `get_example`
63
+ - Pass `language` only when you need to force a specific language; call `search_language` first if the exact language name is uncertain
64
64
  - Formulate queries as natural language questions (e.g., "How to stream responses with the Vercel AI SDK in Next.js")
65
65
  - Include specific error messages, library names, or API names when relevant
66
66
  - Keep queries focused: 3-4 technical terms maximum
@@ -6,16 +6,17 @@ description: Search for canonical code examples from open source via GitHits
6
6
 
7
7
  Search for code examples using GitHits for the query: "$ARGUMENTS"
8
8
 
9
- Use the GitHits MCP `get_example` tool with the user's query. The tool requires two
10
- parameters:
9
+ Use the GitHits MCP `get_example` tool with the user's query.
10
+
11
+ Required parameter:
11
12
 
12
13
  - **query**: The user's search query, formulated in natural language.
13
- - **language**: The programming language. If the language is unclear from
14
- context, use the `search_language` tool first to find the correct language
15
- name.
16
14
 
17
- Optional parameter:
15
+ Optional parameters:
18
16
 
17
+ - **language**: The programming language. Omit it to let GitHits infer the
18
+ language from the query. If you need to force a specific language and the
19
+ exact name is uncertain, use the `search_language` tool first.
19
20
  - **license_mode**: `"strict"` (default, excludes copyleft), `"yolo"` (all
20
21
  licenses), or `"custom"` (user's blocklist).
21
22
 
package/commands/help.md CHANGED
@@ -28,9 +28,9 @@ context summary:
28
28
  This plugin connects to the GitHits MCP server and always exposes three core tools:
29
29
 
30
30
  - **get_example** — Find code examples by describing what you need in natural
31
- language. Requires `query` and `language` parameters.
32
- - **search_language** — Look up supported programming language names before
33
- searching.
31
+ language. Requires `query`; `language` is optional and inferred when omitted.
32
+ - **search_language** — Look up supported programming language names when you
33
+ need to force a specific language.
34
34
  - **feedback** — Rate a search result to improve future quality.
35
35
 
36
36
  Additional indexed dependency/package tools such as `search`, `package_summary`,
@@ -8,16 +8,17 @@ Use GitHits example search for the query: "$ARGUMENTS"
8
8
 
9
9
  This slash command is the older alias for `/githits:example`.
10
10
 
11
- Use the GitHits MCP `get_example` tool with the user's query. The tool requires two
12
- parameters:
11
+ Use the GitHits MCP `get_example` tool with the user's query.
12
+
13
+ Required parameter:
13
14
 
14
15
  - **query**: The user's search query, formulated in natural language.
15
- - **language**: The programming language. If the language is unclear from
16
- context, use the `search_language` tool first to find the correct language
17
- name.
18
16
 
19
- Optional parameter:
17
+ Optional parameters:
20
18
 
19
+ - **language**: The programming language. Omit it to let GitHits infer the
20
+ language from the query. If you need to force a specific language and the
21
+ exact name is uncertain, use the `search_language` tool first.
21
22
  - **license_mode**: `"strict"` (default, excludes copyleft), `"yolo"` (all
22
23
  licenses), or `"custom"` (user's blocklist).
23
24
 
package/dist/cli.js CHANGED
@@ -41,11 +41,11 @@ import {
41
41
  setMcpClientVersionProvider,
42
42
  startTelemetrySpan,
43
43
  withTelemetrySpan
44
- } from "./shared/chunk-ykr7x8jp.js";
44
+ } from "./shared/chunk-ns1j9dan.js";
45
45
  import {
46
46
  __require,
47
47
  version
48
- } from "./shared/chunk-szjytcvw.js";
48
+ } from "./shared/chunk-g6ay6x9v.js";
49
49
 
50
50
  // src/cli.ts
51
51
  import { Command } from "commander";
@@ -4140,7 +4140,7 @@ grep run. --symbol-field hydrates enclosing symbol metadata (appears under each
4140
4140
  match in --verbose output; full payload in --json).`;
4141
4141
  function registerCodeGrepCommand(pkgCommand) {
4142
4142
  return pkgCommand.command("grep").summary("Deterministic text grep over indexed dependency source").description(PKG_GREP_DESCRIPTION).argument("[spec-or-pattern]", "Spec mode: package spec (e.g. npm:express). Repo mode (with --repo-url): the pattern.").argument("[pattern-or-prefix]", "Spec mode: the pattern. Repo mode: optional path-prefix.").argument("[path-prefix]", "Spec mode only: optional path-prefix. Ignored with --repo-url.").option("--repo-url <url>", "Repository URL addressing (requires --git-ref)").option("--git-ref <ref>", "Tag, commit, branch, or HEAD. Required with --repo-url.").option("--path <path>", "Exact file path to grep").option("--glob <glob>", "Glob scope (repeatable)", collectRepeatable, []).option("--ext <ext>", "Extension filter without leading dot (repeatable)", collectRepeatable, []).option("--regex", "Interpret the pattern as RE2 regex").option("--case-sensitive", "Enable ASCII case-sensitive matching").option("-C, --context <n>", "Context lines before and after each match (0-10)").option("-B, --before-context <n>", "Context lines before each match (0-10)").option("-A, --after-context <n>", "Context lines after each match (0-10)").option("--exclude-docs", "Skip files classified as documentation").option("--exclude-tests", "Skip files classified as tests").option("--limit <n>", "Max matches to return on this page (1-1000, default 50)").option("--per-file-limit <n>", "Cap matches per file within this page (0-1000, 0 = unlimited)").option("--cursor <cursor>", "Opaque nextCursor from a previous grep result").option("--symbol-field <field>", `Repeatable; surfaces in --json and under each --verbose match. ${GREP_REPO_SYMBOL_FIELDS_NOTE}`, collectRepeatable, []).option("--wait <ms>", `Indexing wait timeout (0-${MAX_WAIT_TIMEOUT_MS}, default ${DEFAULT_WAIT_TIMEOUT_MS})`).option("-v, --verbose", "Render grouped output with file headers").option("--json", "Emit the JSON envelope").action(async (arg1, arg2, arg3, options) => {
4143
- const { createContainer: createContainer2 } = await import("./shared/chunk-67qnnqby.js");
4143
+ const { createContainer: createContainer2 } = await import("./shared/chunk-4drb8s8v.js");
4144
4144
  const deps = await createContainer2();
4145
4145
  await pkgGrepAction(arg1, arg2, arg3, options, {
4146
4146
  codeNavigationService: deps.codeNavigationService,
@@ -4639,12 +4639,13 @@ var EXAMPLE_DESCRIPTION = `Get verified, canonical code examples from global ope
4639
4639
  For dependency, package, or repository source search, use \`githits search\` instead.
4640
4640
 
4641
4641
  Examples:
4642
+ githits example "how to use express middleware"
4642
4643
  githits example "how to use express middleware" --lang javascript
4643
4644
  githits example "async file reading" -l python --license yolo
4644
4645
  githits example "react hooks patterns" -l typescript --explain
4645
4646
  githits example "react hooks patterns" -l typescript --json`;
4646
4647
  function registerExampleCommand(program) {
4647
- program.command("example").summary("Get code examples from global open source").description(EXAMPLE_DESCRIPTION).argument("<query>", "Natural language example-search query").requiredOption("-l, --lang <language>", "Programming language").addOption(new Option("--license <mode>", "License filter mode").choices(["strict", "yolo", "custom"]).default(undefined)).option("--explain", "Include AI-generated explanation").option("--json", "Output as JSON for piping").action(async (query, options) => {
4648
+ program.command("example").summary("Get code examples from global open source").description(EXAMPLE_DESCRIPTION).argument("<query>", "Natural language example-search query").option("-l, --lang <language>", "Optional programming language; omitted values are inferred by GitHits").addOption(new Option("--license <mode>", "License filter mode").choices(["strict", "yolo", "custom"]).default(undefined)).option("--explain", "Include AI-generated explanation").option("--json", "Output as JSON for piping").action(async (query, options) => {
4648
4649
  try {
4649
4650
  const deps = await loadContainer();
4650
4651
  await exampleAction(query, options, deps);
@@ -4656,7 +4657,7 @@ function registerExampleCommand(program) {
4656
4657
  });
4657
4658
  }
4658
4659
  async function loadContainer() {
4659
- const { createContainer: createContainer2 } = await import("./shared/chunk-67qnnqby.js");
4660
+ const { createContainer: createContainer2 } = await import("./shared/chunk-4drb8s8v.js");
4660
4661
  return createContainer2();
4661
4662
  }
4662
4663
  // src/commands/feedback.ts
@@ -4706,6 +4707,62 @@ function registerFeedbackCommand(program) {
4706
4707
  });
4707
4708
  }
4708
4709
  // src/commands/init/setup-handlers.ts
4710
+ import {
4711
+ parse as parseJsonc,
4712
+ printParseErrorCode
4713
+ } from "jsonc-parser";
4714
+ function parseConfigObject(content) {
4715
+ let normalizedContent = content;
4716
+ if (normalizedContent.charCodeAt(0) === 65279) {
4717
+ normalizedContent = normalizedContent.slice(1);
4718
+ }
4719
+ const trimmed = normalizedContent.trim();
4720
+ if (trimmed === "") {
4721
+ return {
4722
+ format: "json",
4723
+ value: {}
4724
+ };
4725
+ }
4726
+ try {
4727
+ const parsed = JSON.parse(normalizedContent);
4728
+ if (!isPlainObject(parsed)) {
4729
+ return {
4730
+ format: "invalid",
4731
+ error: "Config file root is not a JSON object"
4732
+ };
4733
+ }
4734
+ return {
4735
+ format: "json",
4736
+ value: parsed
4737
+ };
4738
+ } catch (jsonError) {
4739
+ const parseErrors = [];
4740
+ const parsed = parseJsonc(normalizedContent, parseErrors, {
4741
+ allowTrailingComma: true,
4742
+ disallowComments: false,
4743
+ allowEmptyContent: false
4744
+ });
4745
+ if (parseErrors.length > 0) {
4746
+ const firstParseError = parseErrors[0];
4747
+ const strictErrorMessage = jsonError instanceof Error ? jsonError.message : String(jsonError);
4748
+ const jsoncDetail = firstParseError ? `${printParseErrorCode(firstParseError.error)} at offset ${firstParseError.offset}` : "Unknown parse error";
4749
+ return {
4750
+ format: "invalid",
4751
+ error: `Invalid JSON: ${strictErrorMessage}. JSONC parse error: ${jsoncDetail}`
4752
+ };
4753
+ }
4754
+ if (!isPlainObject(parsed)) {
4755
+ return {
4756
+ format: "invalid",
4757
+ error: "Config file root is not a JSON object"
4758
+ };
4759
+ }
4760
+ return {
4761
+ format: "jsonc",
4762
+ value: parsed
4763
+ };
4764
+ }
4765
+ }
4709
4766
  function isPlainObject(value) {
4710
4767
  return typeof value === "object" && value !== null && !Array.isArray(value);
4711
4768
  }
@@ -4814,29 +4871,14 @@ function getMatchingServerKeys(servers, serverName) {
4814
4871
  return Object.keys(servers).filter((key) => key.toLowerCase() === normalizedTarget);
4815
4872
  }
4816
4873
  function mergeServerConfig(existingContent, serversKey, serverName, serverConfig) {
4817
- let content = existingContent;
4818
- if (content.charCodeAt(0) === 65279) {
4819
- content = content.slice(1);
4820
- }
4821
- const trimmed = content.trim();
4822
- if (trimmed === "") {
4823
- content = "{}";
4824
- }
4825
- let config;
4826
- try {
4827
- config = JSON.parse(content);
4828
- } catch (err) {
4874
+ const parsedConfig = parseConfigObject(existingContent);
4875
+ if (parsedConfig.format === "invalid") {
4829
4876
  return {
4830
4877
  status: "parse_error",
4831
- error: `Invalid JSON: ${err instanceof Error ? err.message : String(err)}`
4832
- };
4833
- }
4834
- if (typeof config !== "object" || config === null || Array.isArray(config)) {
4835
- return {
4836
- status: "parse_error",
4837
- error: "Config file root is not a JSON object"
4878
+ error: parsedConfig.error
4838
4879
  };
4839
4880
  }
4881
+ const config = parsedConfig.value;
4840
4882
  if (!(serversKey in config)) {
4841
4883
  config[serversKey] = {};
4842
4884
  }
@@ -4875,23 +4917,12 @@ ${snippet}`;
4875
4917
  }
4876
4918
  async function isAlreadyConfigured(config, fs) {
4877
4919
  try {
4878
- let content;
4879
- try {
4880
- content = await fs.readFile(config.configPath);
4881
- } catch {
4882
- return false;
4883
- }
4884
- if (content.charCodeAt(0) === 65279) {
4885
- content = content.slice(1);
4886
- }
4887
- const trimmed = content.trim();
4888
- if (trimmed === "") {
4889
- return false;
4890
- }
4891
- const parsed = JSON.parse(trimmed);
4892
- if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
4920
+ const content = await fs.readFile(config.configPath);
4921
+ const parsedConfig = parseConfigObject(content);
4922
+ if (parsedConfig.format === "invalid") {
4893
4923
  return false;
4894
4924
  }
4925
+ const parsed = parsedConfig.value;
4895
4926
  const servers = parsed[config.serversKey];
4896
4927
  if (typeof servers !== "object" || servers === null || Array.isArray(servers)) {
4897
4928
  return false;
@@ -5049,6 +5080,32 @@ function getAppDataPath(fs, appName) {
5049
5080
  return fs.joinPath(home, ".config", appName);
5050
5081
  }
5051
5082
  }
5083
+ function getUserDataRoot(fs) {
5084
+ const home = fs.getHomeDir();
5085
+ switch (process.platform) {
5086
+ case "win32":
5087
+ return process.env.APPDATA ?? fs.joinPath(home, "AppData", "Roaming");
5088
+ case "darwin":
5089
+ return fs.joinPath(home, "Library", "Application Support");
5090
+ default:
5091
+ return process.env.XDG_DATA_HOME ?? fs.joinPath(home, ".local", "share");
5092
+ }
5093
+ }
5094
+ function getOpenCodeConfigDir(fs) {
5095
+ if (process.platform === "win32") {
5096
+ return fs.joinPath(getUserDataRoot(fs), "opencode");
5097
+ }
5098
+ return fs.joinPath(fs.getHomeDir(), ".config", "opencode");
5099
+ }
5100
+ function getOpenCodeDesktopDetectPaths(fs) {
5101
+ const userDataRoot = getUserDataRoot(fs);
5102
+ return [
5103
+ fs.joinPath(userDataRoot, "ai.opencode.desktop"),
5104
+ fs.joinPath(userDataRoot, "ai.opencode.desktop.beta"),
5105
+ fs.joinPath(userDataRoot, "ai.opencode.desktop.dev"),
5106
+ getOpenCodeConfigDir(fs)
5107
+ ];
5108
+ }
5052
5109
  async function isExecutableAvailable(exec, executable) {
5053
5110
  try {
5054
5111
  const lookupCommand = process.platform === "win32" ? "where" : "which";
@@ -5261,12 +5318,13 @@ var googleAntigravity = {
5261
5318
  var openCode = {
5262
5319
  name: "OpenCode",
5263
5320
  id: "opencode",
5264
- detectionMethod: "binary",
5321
+ detectionMethod: "hybrid",
5265
5322
  setupMethod: "config-file",
5323
+ detectPaths: (fs) => getOpenCodeDesktopDetectPaths(fs),
5266
5324
  detectBinary: async (exec) => isExecutableAvailable(exec, "opencode"),
5267
5325
  getSetupConfig: (fs) => ({
5268
5326
  method: "config-file",
5269
- configPath: process.platform === "win32" ? fs.joinPath(process.env.APPDATA ?? fs.joinPath(fs.getHomeDir(), "AppData", "Roaming"), "opencode", "opencode.json") : fs.joinPath(fs.getHomeDir(), ".config", "opencode", "opencode.json"),
5327
+ configPath: fs.joinPath(getOpenCodeConfigDir(fs), "opencode.json"),
5270
5328
  serversKey: "mcp",
5271
5329
  serverName: GITHITS_SERVER_NAME,
5272
5330
  serverConfig: {
@@ -5310,6 +5368,26 @@ async function scanAgents(definitions, fs, execService) {
5310
5368
  break;
5311
5369
  }
5312
5370
  }
5371
+ } else if (agent.detectionMethod === "hybrid") {
5372
+ let binaryDetected = false;
5373
+ let pathDetected = false;
5374
+ if (agent.detectBinary) {
5375
+ try {
5376
+ binaryDetected = await agent.detectBinary(execService);
5377
+ } catch {
5378
+ binaryDetected = false;
5379
+ }
5380
+ }
5381
+ if (!binaryDetected && agent.detectPaths) {
5382
+ const paths = agent.detectPaths(fs);
5383
+ for (const path of paths) {
5384
+ if (await fs.isDirectory(path)) {
5385
+ pathDetected = true;
5386
+ break;
5387
+ }
5388
+ }
5389
+ }
5390
+ detected = binaryDetected || pathDetected;
5313
5391
  }
5314
5392
  if (!detected) {
5315
5393
  result.notDetected.push(agent);
@@ -5880,7 +5958,7 @@ function createFeedbackTool(service) {
5880
5958
  import { z as z2 } from "zod";
5881
5959
  var schema2 = {
5882
5960
  query: z2.string().min(1).describe("Natural-language example-search query for canonical code examples."),
5883
- language: z2.string().min(1).describe("Programming language. Use search_language first if the exact name is uncertain."),
5961
+ language: z2.string().min(1).optional().describe("Optional programming language. If omitted, GitHits tries to infer it automatically. Use search_language first only when you need to force a specific language and the exact name is uncertain."),
5884
5962
  license_mode: z2.enum(["strict", "yolo", "custom"]).optional().describe("License filtering mode: strict (default), yolo, or custom.")
5885
5963
  };
5886
5964
  var DESCRIPTION2 = `Get verified, canonical code examples from global open source.
@@ -5970,10 +6048,6 @@ function invalidTargetResult(message) {
5970
6048
  }
5971
6049
 
5972
6050
  // src/tools/grep-repo.ts
5973
- var pathSelectorSchema = z4.object({
5974
- kind: z4.enum(["exact", "prefix", "glob"]),
5975
- value: z4.string()
5976
- });
5977
6051
  var schema3 = {
5978
6052
  target: codeTargetSchema,
5979
6053
  pattern: z4.string().describe(GREP_REPO_PATTERN_NOTE),
@@ -6873,7 +6947,7 @@ function createSearchStatusTool(service) {
6873
6947
  // src/commands/mcp-instructions.ts
6874
6948
  var CORE_BLOCK = `GitHits surfaces verified, canonical code examples from global open source. Use it when you're stuck, the user is frustrated by repeated failed attempts, you need up-to-date API usage, or the user mentions GitHits.
6875
6949
 
6876
- Workflow: call \`search_language\` first if the language name is uncertain call \`get_example\` with one focused question send \`feedback\` on the returned solution_id so quality improves. Each search addresses a single issue; reuse context from prior results before re-searching.`;
6950
+ Workflow: call \`get_example\` with one focused question, optionally passing \`language\` when the desired language is known; call \`search_language\` first only if you need to force a language and the exact name is uncertain. Send \`feedback\` on the returned solution_id so quality improves. Each search addresses a single issue; reuse context from prior results before re-searching.`;
6877
6951
  var PACKAGE_TOOLS_PREAMBLE = `Package tools work with third-party dependency source plus registry metadata. Use them when a stack trace points into a dependency, you need to verify how a library actually works, or you're evaluating whether to add or upgrade a package.
6878
6952
 
6879
6953
  Package spec: \`registry:name[@version]\`.`;
@@ -6936,28 +7010,34 @@ function buildMcpInstructions(deps) {
6936
7010
  // src/commands/mcp.ts
6937
7011
  function getMcpToolDefinitions(deps) {
6938
7012
  const tools = [
6939
- createGetExampleTool(deps.githitsService),
6940
- createSearchLanguageTool(deps.githitsService),
6941
- createFeedbackTool(deps.githitsService)
7013
+ eraseTool(createGetExampleTool(deps.githitsService)),
7014
+ eraseTool(createSearchLanguageTool(deps.githitsService)),
7015
+ eraseTool(createFeedbackTool(deps.githitsService))
6942
7016
  ];
6943
7017
  const gateOpen = isPackageToolsCapabilityOpen(deps);
6944
7018
  if (gateOpen && deps.codeNavigationService) {
6945
- tools.push(createSearchTool(deps.codeNavigationService));
6946
- tools.push(createSearchStatusTool(deps.codeNavigationService));
6947
- tools.push(createListFilesTool(deps.codeNavigationService));
6948
- tools.push(createReadFileTool(deps.codeNavigationService));
6949
- tools.push(createGrepRepoTool(deps.codeNavigationService));
7019
+ tools.push(eraseTool(createSearchTool(deps.codeNavigationService)));
7020
+ tools.push(eraseTool(createSearchStatusTool(deps.codeNavigationService)));
7021
+ tools.push(eraseTool(createListFilesTool(deps.codeNavigationService)));
7022
+ tools.push(eraseTool(createReadFileTool(deps.codeNavigationService)));
7023
+ tools.push(eraseTool(createGrepRepoTool(deps.codeNavigationService)));
6950
7024
  }
6951
7025
  if (gateOpen && deps.packageIntelligenceService) {
6952
- tools.push(createListPackageDocsTool(deps.packageIntelligenceService));
6953
- tools.push(createReadPackageDocTool(deps.packageIntelligenceService));
6954
- tools.push(createPackageSummaryTool(deps.packageIntelligenceService));
6955
- tools.push(createPackageVulnerabilitiesTool(deps.packageIntelligenceService));
6956
- tools.push(createPackageDependenciesTool(deps.packageIntelligenceService));
6957
- tools.push(createPackageChangelogTool(deps.packageIntelligenceService));
7026
+ tools.push(eraseTool(createListPackageDocsTool(deps.packageIntelligenceService)));
7027
+ tools.push(eraseTool(createReadPackageDocTool(deps.packageIntelligenceService)));
7028
+ tools.push(eraseTool(createPackageSummaryTool(deps.packageIntelligenceService)));
7029
+ tools.push(eraseTool(createPackageVulnerabilitiesTool(deps.packageIntelligenceService)));
7030
+ tools.push(eraseTool(createPackageDependenciesTool(deps.packageIntelligenceService)));
7031
+ tools.push(eraseTool(createPackageChangelogTool(deps.packageIntelligenceService)));
6958
7032
  }
6959
7033
  return tools;
6960
7034
  }
7035
+ function eraseTool(tool) {
7036
+ return {
7037
+ ...tool,
7038
+ handler: (args, extra) => tool.handler(args, extra)
7039
+ };
7040
+ }
6961
7041
  function createMcpServer(deps) {
6962
7042
  const server = new McpServer({
6963
7043
  name: "githits",
@@ -7571,11 +7651,11 @@ function requireSearchService(deps) {
7571
7651
  return deps.codeNavigationService;
7572
7652
  }
7573
7653
  async function loadContainer2() {
7574
- const { createContainer: createContainer2 } = await import("./shared/chunk-67qnnqby.js");
7654
+ const { createContainer: createContainer2 } = await import("./shared/chunk-4drb8s8v.js");
7575
7655
  return createContainer2();
7576
7656
  }
7577
7657
  async function loadStartupCodeNavigationRegistrationState() {
7578
- const { resolveStartupCodeNavigationRegistrationState: resolveStartupCodeNavigationRegistrationState2 } = await import("./shared/chunk-67qnnqby.js");
7658
+ const { resolveStartupCodeNavigationRegistrationState: resolveStartupCodeNavigationRegistrationState2 } = await import("./shared/chunk-4drb8s8v.js");
7579
7659
  return resolveStartupCodeNavigationRegistrationState2();
7580
7660
  }
7581
7661
  function parseTargetSpecs(specs) {
@@ -7929,7 +8009,7 @@ Getting started:
7929
8009
  githits init Set up MCP for your coding agents
7930
8010
  githits login Authenticate with your GitHits account
7931
8011
  githits mcp Show MCP setup instructions
7932
- githits example "query" -l python Get code examples
8012
+ githits example "query" Get code examples
7933
8013
 
7934
8014
  Learn more at https://githits.com
7935
8015
  Docs: https://app.githits.com/docs/
@@ -7943,7 +8023,6 @@ registerLanguagesCommand(program);
7943
8023
  registerFeedbackCommand(program);
7944
8024
  var argv = process.argv.slice(2);
7945
8025
  var registrationArgv = stripRootRegistrationOptions(argv);
7946
- var helpInvocation = isHelpInvocation(registrationArgv);
7947
8026
  var shouldLoadGatedHelpRegistration = needsGatedHelpRegistration(registrationArgv);
7948
8027
  var helpRegistrationOptions = shouldLoadGatedHelpRegistration ? await loadHelpRegistrationOptions(registrationArgv) : undefined;
7949
8028
  if (shouldEagerLoadSearchCommands(registrationArgv)) {
@@ -7989,7 +8068,7 @@ function isSearchHelpTarget(value) {
7989
8068
  return value === "search" || value === "search-status";
7990
8069
  }
7991
8070
  async function loadHelpRegistrationOptions(args) {
7992
- const { resolveStartupCodeNavigationRegistrationState: resolveStartupCodeNavigationRegistrationState2 } = await import("./shared/chunk-67qnnqby.js");
8071
+ const { resolveStartupCodeNavigationRegistrationState: resolveStartupCodeNavigationRegistrationState2 } = await import("./shared/chunk-4drb8s8v.js");
7993
8072
  const registrationState = await resolveStartupCodeNavigationRegistrationState2();
7994
8073
  return {
7995
8074
  capability: registrationState.capability,
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  version
3
- } from "./shared/chunk-szjytcvw.js";
3
+ } from "./shared/chunk-g6ay6x9v.js";
4
4
  export {
5
5
  version
6
6
  };
@@ -2,8 +2,8 @@ import {
2
2
  createContainer,
3
3
  resolveStartupCodeNavigationCapability,
4
4
  resolveStartupCodeNavigationRegistrationState
5
- } from "./chunk-ykr7x8jp.js";
6
- import"./chunk-szjytcvw.js";
5
+ } from "./chunk-ns1j9dan.js";
6
+ import"./chunk-g6ay6x9v.js";
7
7
  export {
8
8
  resolveStartupCodeNavigationRegistrationState,
9
9
  resolveStartupCodeNavigationCapability,
@@ -1,6 +1,6 @@
1
1
  import { createRequire } from "node:module";
2
2
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
3
3
  // package.json
4
- var version = "0.2.1";
4
+ var version = "0.2.2";
5
5
 
6
6
  export { __require, version };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  version
3
- } from "./chunk-szjytcvw.js";
3
+ } from "./chunk-g6ay6x9v.js";
4
4
 
5
5
  // src/services/auth-service.ts
6
6
  import { createServer } from "node:http";
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "githits",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Code examples from global open source for developers and AI assistants.",
5
5
  "mcpServers": {
6
6
  "githits": {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "githits",
3
3
  "description": "CLI companion for GitHits - code examples from global open source for developers and AI assistants",
4
- "version": "0.2.1",
4
+ "version": "0.2.2",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist",
@@ -72,6 +72,7 @@
72
72
  "@modelcontextprotocol/sdk": "^1.23.0",
73
73
  "@napi-rs/keyring": "^1.2.0",
74
74
  "commander": "^14.0.2",
75
+ "jsonc-parser": "^3.3.1",
75
76
  "open": "^11.0.0",
76
77
  "zod": "^4.1.13"
77
78
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "githits",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Code examples from global open source for developers and AI assistants",
5
5
  "author": {
6
6
  "name": "GitHits"
@@ -6,16 +6,17 @@ description: Search for canonical code examples from open source via GitHits
6
6
 
7
7
  Search for code examples using GitHits for the query: "$ARGUMENTS"
8
8
 
9
- Use the GitHits MCP `get_example` tool with the user's query. The tool requires two
10
- parameters:
9
+ Use the GitHits MCP `get_example` tool with the user's query.
10
+
11
+ Required parameter:
11
12
 
12
13
  - **query**: The user's search query, formulated in natural language.
13
- - **language**: The programming language. If the language is unclear from
14
- context, use the `search_language` tool first to find the correct language
15
- name.
16
14
 
17
- Optional parameter:
15
+ Optional parameters:
18
16
 
17
+ - **language**: The programming language. Omit it to let GitHits infer the
18
+ language from the query. If you need to force a specific language and the
19
+ exact name is uncertain, use the `search_language` tool first.
19
20
  - **license_mode**: `"strict"` (default, excludes copyleft), `"yolo"` (all
20
21
  licenses), or `"custom"` (user's blocklist).
21
22
 
@@ -28,9 +28,9 @@ context summary:
28
28
  This plugin connects to the GitHits MCP server and always exposes three core tools:
29
29
 
30
30
  - **get_example** — Find code examples by describing what you need in natural
31
- language. Requires `query` and `language` parameters.
32
- - **search_language** — Look up supported programming language names before
33
- searching.
31
+ language. Requires `query`; `language` is optional and inferred when omitted.
32
+ - **search_language** — Look up supported programming language names when you
33
+ need to force a specific language.
34
34
  - **feedback** — Rate a search result to improve future quality.
35
35
 
36
36
  Additional indexed dependency/package tools such as `search`, `package_summary`,
@@ -8,16 +8,17 @@ Use GitHits example search for the query: "$ARGUMENTS"
8
8
 
9
9
  This slash command is the older alias for `/githits:example`.
10
10
 
11
- Use the GitHits MCP `get_example` tool with the user's query. The tool requires two
12
- parameters:
11
+ Use the GitHits MCP `get_example` tool with the user's query.
12
+
13
+ Required parameter:
13
14
 
14
15
  - **query**: The user's search query, formulated in natural language.
15
- - **language**: The programming language. If the language is unclear from
16
- context, use the `search_language` tool first to find the correct language
17
- name.
18
16
 
19
- Optional parameter:
17
+ Optional parameters:
20
18
 
19
+ - **language**: The programming language. Omit it to let GitHits infer the
20
+ language from the query. If you need to force a specific language and the
21
+ exact name is uncertain, use the `search_language` tool first.
21
22
  - **license_mode**: `"strict"` (default, excludes copyleft), `"yolo"` (all
22
23
  licenses), or `"custom"` (user's blocklist).
23
24
 
@@ -28,7 +28,8 @@ Authentication:
28
28
  Guidelines:
29
29
 
30
30
  - Prefer existing search context if it already answers the problem.
31
- - Use `search_language` first when language naming is uncertain.
31
+ - Pass `language` only when you need to force a specific language; use
32
+ `search_language` first if the exact language name is uncertain.
32
33
  - Use `get_example` for one focused example-search question at a time.
33
34
  - When the task is about indexed dependency or repository internals and the
34
35
  capability-gated tools are available, prefer unified `search` instead of
@@ -28,7 +28,8 @@ Authentication:
28
28
  Guidelines:
29
29
 
30
30
  - Prefer existing search context if it already answers the problem.
31
- - Use `search_language` first when language naming is uncertain.
31
+ - Pass `language` only when you need to force a specific language; use
32
+ `search_language` first if the exact language name is uncertain.
32
33
  - Use `get_example` for one focused example-search question at a time.
33
34
  - When the task is about indexed dependency or repository internals and the
34
35
  capability-gated tools are available, prefer unified `search` instead of