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.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.plugin/plugin.json +1 -1
- package/GEMINI.md +3 -3
- package/commands/example.md +7 -6
- package/commands/help.md +3 -3
- package/commands/search.md +7 -6
- package/dist/cli.js +145 -66
- package/dist/index.js +1 -1
- package/dist/shared/{chunk-67qnnqby.js → chunk-4drb8s8v.js} +2 -2
- package/dist/shared/{chunk-szjytcvw.js → chunk-g6ay6x9v.js} +1 -1
- package/dist/shared/{chunk-ykr7x8jp.js → chunk-ns1j9dan.js} +1 -1
- package/gemini-extension.json +1 -1
- package/package.json +2 -1
- package/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/plugins/claude/commands/example.md +7 -6
- package/plugins/claude/commands/help.md +3 -3
- package/plugins/claude/commands/search.md +7 -6
- package/plugins/claude/skills/search/SKILL.md +2 -1
- package/skills/search/SKILL.md +2 -1
package/.plugin/plugin.json
CHANGED
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,
|
|
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
|
|
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
|
-
-
|
|
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
|
package/commands/example.md
CHANGED
|
@@ -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.
|
|
10
|
-
|
|
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
|
|
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
|
|
32
|
-
- **search_language** — Look up supported programming language names
|
|
33
|
-
|
|
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`,
|
package/commands/search.md
CHANGED
|
@@ -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.
|
|
12
|
-
|
|
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
|
|
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-
|
|
44
|
+
} from "./shared/chunk-ns1j9dan.js";
|
|
45
45
|
import {
|
|
46
46
|
__require,
|
|
47
47
|
version
|
|
48
|
-
} from "./shared/chunk-
|
|
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-
|
|
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").
|
|
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-
|
|
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
|
-
|
|
4818
|
-
if (
|
|
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:
|
|
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
|
-
|
|
4879
|
-
|
|
4880
|
-
|
|
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: "
|
|
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:
|
|
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("
|
|
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 \`
|
|
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-
|
|
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-
|
|
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"
|
|
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-
|
|
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
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
createContainer,
|
|
3
3
|
resolveStartupCodeNavigationCapability,
|
|
4
4
|
resolveStartupCodeNavigationRegistrationState
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import"./chunk-
|
|
5
|
+
} from "./chunk-ns1j9dan.js";
|
|
6
|
+
import"./chunk-g6ay6x9v.js";
|
|
7
7
|
export {
|
|
8
8
|
resolveStartupCodeNavigationRegistrationState,
|
|
9
9
|
resolveStartupCodeNavigationCapability,
|
package/gemini-extension.json
CHANGED
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.
|
|
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
|
},
|
|
@@ -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.
|
|
10
|
-
|
|
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
|
|
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
|
|
32
|
-
- **search_language** — Look up supported programming language names
|
|
33
|
-
|
|
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.
|
|
12
|
-
|
|
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
|
|
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
|
-
-
|
|
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
|
package/skills/search/SKILL.md
CHANGED
|
@@ -28,7 +28,8 @@ Authentication:
|
|
|
28
28
|
Guidelines:
|
|
29
29
|
|
|
30
30
|
- Prefer existing search context if it already answers the problem.
|
|
31
|
-
-
|
|
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
|