githits 0.3.0 → 0.3.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/dist/cli.js +938 -231
- package/dist/index.js +1 -1
- package/dist/shared/{chunk-1gqfte6e.js → chunk-rwcs5gyy.js} +2 -2
- package/dist/shared/{chunk-gxya097b.js → chunk-w5kw8sef.js} +1 -1
- package/dist/shared/{chunk-5mk9k2gv.js → chunk-zarrkzvq.js} +424 -10
- package/gemini-extension.json +1 -1
- package/package.json +1 -1
- package/plugins/claude/.claude-plugin/plugin.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
AuthConfigError,
|
|
4
|
+
AuthStorageLockTimeoutError,
|
|
4
5
|
AuthStoragePolicyError,
|
|
5
6
|
AuthenticationError,
|
|
6
7
|
CLIENT_UPDATE_REQUIRED_REASON,
|
|
@@ -48,15 +49,59 @@ import {
|
|
|
48
49
|
shouldRunUpdateCheck,
|
|
49
50
|
startTelemetrySpan,
|
|
50
51
|
withTelemetrySpan
|
|
51
|
-
} from "./shared/chunk-
|
|
52
|
+
} from "./shared/chunk-zarrkzvq.js";
|
|
52
53
|
import {
|
|
53
54
|
__require,
|
|
54
55
|
version
|
|
55
|
-
} from "./shared/chunk-
|
|
56
|
+
} from "./shared/chunk-w5kw8sef.js";
|
|
56
57
|
|
|
57
58
|
// src/cli.ts
|
|
58
59
|
import { Command } from "commander";
|
|
59
60
|
|
|
61
|
+
// src/shared/require-auth.ts
|
|
62
|
+
class AuthRequiredError extends Error {
|
|
63
|
+
constructor(message) {
|
|
64
|
+
super(message);
|
|
65
|
+
this.name = "AuthRequiredError";
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function requireAuth(deps, context) {
|
|
69
|
+
if (deps.hasValidToken)
|
|
70
|
+
return;
|
|
71
|
+
const suffix = context ? ` ${context}` : "";
|
|
72
|
+
console.log(`Authentication required${suffix}.
|
|
73
|
+
`);
|
|
74
|
+
if (deps.mcpUrl !== "https://mcp.githits.com") {
|
|
75
|
+
console.log(` Environment: ${deps.mcpUrl}`);
|
|
76
|
+
console.log(` You're using a custom environment.
|
|
77
|
+
`);
|
|
78
|
+
}
|
|
79
|
+
console.log("To authenticate:");
|
|
80
|
+
console.log(` githits login
|
|
81
|
+
`);
|
|
82
|
+
console.log("Or set GITHITS_API_TOKEN environment variable.");
|
|
83
|
+
console.log(`
|
|
84
|
+
Need help? support@githits.com`);
|
|
85
|
+
throw new AuthRequiredError(`Authentication required${suffix}`);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// src/cli/errors.ts
|
|
89
|
+
function handleCliError(error, deps) {
|
|
90
|
+
if (error instanceof AuthRequiredError) {
|
|
91
|
+
deps.exit(1);
|
|
92
|
+
}
|
|
93
|
+
if (isUserFacingError(error)) {
|
|
94
|
+
deps.stderr.write(`${error.message}
|
|
95
|
+
|
|
96
|
+
`);
|
|
97
|
+
deps.exit(1);
|
|
98
|
+
}
|
|
99
|
+
throw error;
|
|
100
|
+
}
|
|
101
|
+
function isUserFacingError(error) {
|
|
102
|
+
return error instanceof AuthConfigError || error instanceof AuthStorageLockTimeoutError || error instanceof AuthStoragePolicyError;
|
|
103
|
+
}
|
|
104
|
+
|
|
60
105
|
// src/cli/update-check.ts
|
|
61
106
|
function startUpdateCheckTask(service) {
|
|
62
107
|
const controller = new AbortController;
|
|
@@ -440,6 +485,12 @@ function knownSymbolCategoryList() {
|
|
|
440
485
|
function toFileIntent(intent) {
|
|
441
486
|
return intent ? fileIntentMap[intent] : undefined;
|
|
442
487
|
}
|
|
488
|
+
function isKnownFileIntent(value) {
|
|
489
|
+
return value in fileIntentMap;
|
|
490
|
+
}
|
|
491
|
+
function knownFileIntentList() {
|
|
492
|
+
return Object.keys(fileIntentMap);
|
|
493
|
+
}
|
|
443
494
|
// src/shared/code-navigation-error-map.ts
|
|
444
495
|
function mapCodeNavigationError(error2) {
|
|
445
496
|
const mapped = classify(error2);
|
|
@@ -522,7 +573,8 @@ function classify(error2) {
|
|
|
522
573
|
return {
|
|
523
574
|
code: "AUTH_REQUIRED",
|
|
524
575
|
message: error2.message,
|
|
525
|
-
retryable: false
|
|
576
|
+
retryable: false,
|
|
577
|
+
details: { action: "Run `githits login`, then retry this tool call." }
|
|
526
578
|
};
|
|
527
579
|
}
|
|
528
580
|
if (error2 instanceof CodeNavigationNetworkError) {
|
|
@@ -618,23 +670,6 @@ function isInvalidArgumentError(error2) {
|
|
|
618
670
|
return false;
|
|
619
671
|
return error2.name.startsWith("Invalid") || error2.name.startsWith("Unsupported");
|
|
620
672
|
}
|
|
621
|
-
// src/shared/docs-follow-up.ts
|
|
622
|
-
function lowerDocSourceKind(value) {
|
|
623
|
-
switch (value) {
|
|
624
|
-
case "CRAWLED":
|
|
625
|
-
return "crawled";
|
|
626
|
-
case "REPOSITORY":
|
|
627
|
-
return "repo";
|
|
628
|
-
default:
|
|
629
|
-
return;
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
// src/shared/extract-solution-id.ts
|
|
633
|
-
var SOLUTION_URL_RE = /solutions\/([0-9a-fA-F-]{36})/;
|
|
634
|
-
function extractSolutionId(markdown) {
|
|
635
|
-
const match = SOLUTION_URL_RE.exec(markdown);
|
|
636
|
-
return match?.[1];
|
|
637
|
-
}
|
|
638
673
|
// src/shared/package-spec.ts
|
|
639
674
|
var KNOWN_REGISTRIES = [
|
|
640
675
|
"npm",
|
|
@@ -709,6 +744,112 @@ function isKnownRegistry(value) {
|
|
|
709
744
|
return KNOWN_REGISTRIES.includes(value);
|
|
710
745
|
}
|
|
711
746
|
|
|
747
|
+
// src/shared/code-navigation-target.ts
|
|
748
|
+
function parseCodeNavigationTargetSpec(spec) {
|
|
749
|
+
const trimmed = spec.trim();
|
|
750
|
+
if (trimmed.length === 0) {
|
|
751
|
+
throw new InvalidArgumentError("Target spec cannot be empty.");
|
|
752
|
+
}
|
|
753
|
+
if (trimmed.startsWith("http://") || trimmed.startsWith("https://")) {
|
|
754
|
+
return parseRepoTarget(trimmed);
|
|
755
|
+
}
|
|
756
|
+
const parsed = parsePackageSpec(trimmed);
|
|
757
|
+
return {
|
|
758
|
+
registry: toCodeNavigationRegistry(parsed.registry),
|
|
759
|
+
packageName: parsed.name,
|
|
760
|
+
version: parsed.version
|
|
761
|
+
};
|
|
762
|
+
}
|
|
763
|
+
function parseRepoTarget(spec) {
|
|
764
|
+
const hashIndex = spec.lastIndexOf("#");
|
|
765
|
+
if (hashIndex === -1) {
|
|
766
|
+
return { repoUrl: spec, gitRef: "HEAD" };
|
|
767
|
+
}
|
|
768
|
+
const repoUrl = spec.slice(0, hashIndex);
|
|
769
|
+
const gitRef = spec.slice(hashIndex + 1);
|
|
770
|
+
if (!repoUrl || !gitRef) {
|
|
771
|
+
throw new InvalidArgumentError("Repository target must be a full URL with optional #gitRef suffix.");
|
|
772
|
+
}
|
|
773
|
+
return { repoUrl, gitRef };
|
|
774
|
+
}
|
|
775
|
+
// src/shared/docs-follow-up.ts
|
|
776
|
+
function lowerDocSourceKind(value) {
|
|
777
|
+
switch (value) {
|
|
778
|
+
case "CRAWLED":
|
|
779
|
+
return "crawled";
|
|
780
|
+
case "REPOSITORY":
|
|
781
|
+
return "repo";
|
|
782
|
+
default:
|
|
783
|
+
return;
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
// src/shared/extract-solution-id.ts
|
|
787
|
+
var SOLUTION_URL_RE = /solutions\/([0-9a-fA-F-]{36})/;
|
|
788
|
+
function extractSolutionId(markdown) {
|
|
789
|
+
const match = SOLUTION_URL_RE.exec(markdown);
|
|
790
|
+
return match?.[1];
|
|
791
|
+
}
|
|
792
|
+
// src/shared/follow-up-command-text.ts
|
|
793
|
+
function buildSearchHitFollowUpCommand(hit) {
|
|
794
|
+
const loc = hit.locator;
|
|
795
|
+
if (loc.pageId) {
|
|
796
|
+
return buildDocsReadCommand(loc.pageId, loc.startLine, loc.endLine);
|
|
797
|
+
}
|
|
798
|
+
if (loc.filePath) {
|
|
799
|
+
return buildCodeReadCommand({
|
|
800
|
+
registry: loc.registry,
|
|
801
|
+
packageName: loc.packageName,
|
|
802
|
+
version: loc.version,
|
|
803
|
+
repoUrl: loc.repoUrl,
|
|
804
|
+
gitRef: loc.gitRef,
|
|
805
|
+
filePath: loc.filePath,
|
|
806
|
+
startLine: loc.startLine,
|
|
807
|
+
endLine: loc.endLine
|
|
808
|
+
});
|
|
809
|
+
}
|
|
810
|
+
if (hit.type === "repository_code" || hit.type === "repository_symbol") {
|
|
811
|
+
return "follow-up unavailable: missing filePath";
|
|
812
|
+
}
|
|
813
|
+
if (loc.sourceUrl)
|
|
814
|
+
return loc.sourceUrl;
|
|
815
|
+
return "";
|
|
816
|
+
}
|
|
817
|
+
function buildDocsReadCommand(pageId, startLine, endLine) {
|
|
818
|
+
const parts = [`docs_read page_id=${quote(pageId)}`];
|
|
819
|
+
appendRange(parts, startLine, endLine);
|
|
820
|
+
return parts.join(" ");
|
|
821
|
+
}
|
|
822
|
+
function buildCodeReadCommand(input) {
|
|
823
|
+
if (!input.filePath)
|
|
824
|
+
return "follow-up unavailable: missing filePath";
|
|
825
|
+
const target = buildTargetSpec(input);
|
|
826
|
+
if (!target)
|
|
827
|
+
return "follow-up unavailable: missing target";
|
|
828
|
+
const parts = [
|
|
829
|
+
`code_read target=${quote(target)}`,
|
|
830
|
+
`path=${quote(input.filePath)}`
|
|
831
|
+
];
|
|
832
|
+
appendRange(parts, input.startLine, input.endLine);
|
|
833
|
+
return parts.join(" ");
|
|
834
|
+
}
|
|
835
|
+
function buildTargetSpec(input) {
|
|
836
|
+
if (input.repoUrl) {
|
|
837
|
+
return `${input.repoUrl}#${input.gitRef ?? "HEAD"}`;
|
|
838
|
+
}
|
|
839
|
+
if (input.registry && input.packageName) {
|
|
840
|
+
return `${input.registry}:${input.packageName}${input.version ? `@${input.version}` : ""}`;
|
|
841
|
+
}
|
|
842
|
+
return;
|
|
843
|
+
}
|
|
844
|
+
function appendRange(parts, startLine, endLine) {
|
|
845
|
+
if (typeof startLine === "number")
|
|
846
|
+
parts.push(`start_line=${startLine}`);
|
|
847
|
+
if (typeof endLine === "number")
|
|
848
|
+
parts.push(`end_line=${endLine}`);
|
|
849
|
+
}
|
|
850
|
+
function quote(value) {
|
|
851
|
+
return JSON.stringify(value);
|
|
852
|
+
}
|
|
712
853
|
// src/shared/grep-repo-request.ts
|
|
713
854
|
var PATTERN_MAX = 200;
|
|
714
855
|
var CONTEXT_MIN = 0;
|
|
@@ -1326,7 +1467,7 @@ function buildHeader(envelope) {
|
|
|
1326
1467
|
const parts = [
|
|
1327
1468
|
`code_grep${SEP}${envelope.totalMatches} match${envelope.totalMatches === 1 ? "" : "es"} in ${envelope.uniqueFilesMatched} file${envelope.uniqueFilesMatched === 1 ? "" : "s"}`
|
|
1328
1469
|
];
|
|
1329
|
-
parts.push(`pattern=${
|
|
1470
|
+
parts.push(`pattern=${quote2(envelope.pattern)}`);
|
|
1330
1471
|
const flags = [];
|
|
1331
1472
|
if (envelope.patternType === "regex")
|
|
1332
1473
|
flags.push("regex");
|
|
@@ -1345,9 +1486,9 @@ function buildFilterEcho(envelope) {
|
|
|
1345
1486
|
return "";
|
|
1346
1487
|
const parts = [];
|
|
1347
1488
|
if (filter.path)
|
|
1348
|
-
parts.push(`path=${
|
|
1489
|
+
parts.push(`path=${quote2(filter.path)}`);
|
|
1349
1490
|
if (filter.pathPrefix)
|
|
1350
|
-
parts.push(`path_prefix=${
|
|
1491
|
+
parts.push(`path_prefix=${quote2(filter.pathPrefix)}`);
|
|
1351
1492
|
if (filter.globs?.length)
|
|
1352
1493
|
parts.push(`globs=${filter.globs.join(",")}`);
|
|
1353
1494
|
if (filter.extensions?.length) {
|
|
@@ -1480,14 +1621,18 @@ function renderLine(line, gutterWidth, useContext) {
|
|
|
1480
1621
|
const sep = !useContext || line.isMatch ? ":" : "-";
|
|
1481
1622
|
return ` ${gutter}${sep} ${line.content}`;
|
|
1482
1623
|
}
|
|
1483
|
-
function
|
|
1624
|
+
function quote2(value) {
|
|
1484
1625
|
return value.includes('"') ? `'${value}'` : `"${value}"`;
|
|
1485
1626
|
}
|
|
1486
1627
|
// src/shared/language-filter.ts
|
|
1487
1628
|
var DEFAULT_LIMIT = 5;
|
|
1488
1629
|
function filterLanguages(languages, query, limit = DEFAULT_LIMIT) {
|
|
1489
1630
|
const lowerQuery = query.toLowerCase();
|
|
1490
|
-
return languages.filter((lang) => lang.name.toLowerCase().includes(lowerQuery) || lang.display_name.toLowerCase().includes(lowerQuery) || lang.aliases.some((a) => a.toLowerCase().includes(lowerQuery))).slice(0, limit).map(({ name, display_name }) => ({
|
|
1631
|
+
return languages.filter((lang) => lang.name.toLowerCase().includes(lowerQuery) || lang.display_name.toLowerCase().includes(lowerQuery) || lang.aliases.some((a) => a.toLowerCase().includes(lowerQuery))).slice(0, limit).map(({ name, display_name, aliases }) => ({
|
|
1632
|
+
name,
|
|
1633
|
+
display_name,
|
|
1634
|
+
aliases
|
|
1635
|
+
}));
|
|
1491
1636
|
}
|
|
1492
1637
|
// src/shared/list-files-text.ts
|
|
1493
1638
|
var SEP2 = " | ";
|
|
@@ -1505,7 +1650,7 @@ function renderListFilesText(envelope) {
|
|
|
1505
1650
|
}
|
|
1506
1651
|
if (envelope.hasMore) {
|
|
1507
1652
|
lines.push("");
|
|
1508
|
-
lines.push("More files available. Pass limit=N
|
|
1653
|
+
lines.push("More files available. Pass limit=N or refine the filter.");
|
|
1509
1654
|
}
|
|
1510
1655
|
if (envelope.hint) {
|
|
1511
1656
|
lines.push("");
|
|
@@ -1539,15 +1684,48 @@ function buildIdentity(envelope) {
|
|
|
1539
1684
|
}
|
|
1540
1685
|
function buildFilterEcho2(envelope) {
|
|
1541
1686
|
const parts = [];
|
|
1687
|
+
if (envelope.filter?.path) {
|
|
1688
|
+
parts.push(`path=${quote3(envelope.filter.path)}`);
|
|
1689
|
+
}
|
|
1542
1690
|
if (envelope.filter?.pathPrefix) {
|
|
1543
|
-
parts.push(`path_prefix=${
|
|
1691
|
+
parts.push(`path_prefix=${quote3(envelope.filter.pathPrefix)}`);
|
|
1692
|
+
}
|
|
1693
|
+
if (envelope.filter?.globs?.length) {
|
|
1694
|
+
parts.push(`globs=${envelope.filter.globs.join(",")}`);
|
|
1695
|
+
}
|
|
1696
|
+
if (envelope.filter?.extensions?.length) {
|
|
1697
|
+
parts.push(`exts=${envelope.filter.extensions.join(",")}`);
|
|
1698
|
+
}
|
|
1699
|
+
if (envelope.filter?.fileTypes?.length) {
|
|
1700
|
+
parts.push(`file_types=${envelope.filter.fileTypes.join(",")}`);
|
|
1701
|
+
}
|
|
1702
|
+
if (envelope.filter?.languages?.length) {
|
|
1703
|
+
parts.push(`languages=${envelope.filter.languages.join(",")}`);
|
|
1704
|
+
}
|
|
1705
|
+
if (envelope.filter?.fileIntent) {
|
|
1706
|
+
parts.push(`file_intent=${envelope.filter.fileIntent}`);
|
|
1707
|
+
}
|
|
1708
|
+
if (envelope.filter?.fileIntents?.length) {
|
|
1709
|
+
parts.push(`file_intents=${envelope.filter.fileIntents.join(",")}`);
|
|
1710
|
+
}
|
|
1711
|
+
if (envelope.filter?.excludeFileIntents?.length) {
|
|
1712
|
+
parts.push(`exclude_file_intents=${envelope.filter.excludeFileIntents.join(",")}`);
|
|
1713
|
+
}
|
|
1714
|
+
if (envelope.filter?.excludeDocFiles !== undefined) {
|
|
1715
|
+
parts.push(`exclude_doc_files=${String(envelope.filter.excludeDocFiles)}`);
|
|
1716
|
+
}
|
|
1717
|
+
if (envelope.filter?.excludeTestFiles !== undefined) {
|
|
1718
|
+
parts.push(`exclude_test_files=${String(envelope.filter.excludeTestFiles)}`);
|
|
1719
|
+
}
|
|
1720
|
+
if (envelope.filter?.includeHidden !== undefined) {
|
|
1721
|
+
parts.push(`include_hidden=${String(envelope.filter.includeHidden)}`);
|
|
1544
1722
|
}
|
|
1545
1723
|
if (envelope.filter?.limit !== undefined) {
|
|
1546
1724
|
parts.push(`limit=${envelope.filter.limit}`);
|
|
1547
1725
|
}
|
|
1548
1726
|
return parts.join(" ");
|
|
1549
1727
|
}
|
|
1550
|
-
function
|
|
1728
|
+
function quote3(value) {
|
|
1551
1729
|
return value.includes('"') ? `'${value}'` : `"${value}"`;
|
|
1552
1730
|
}
|
|
1553
1731
|
// src/shared/list-package-docs-request.ts
|
|
@@ -1647,8 +1825,6 @@ function buildListPackageDocsSuccessPayload(result, options) {
|
|
|
1647
1825
|
entry.requestedRef = page.requestedRef;
|
|
1648
1826
|
if (page.filePath)
|
|
1649
1827
|
entry.filePath = page.filePath;
|
|
1650
|
-
if (page.linkName)
|
|
1651
|
-
entry.linkName = page.linkName;
|
|
1652
1828
|
if (lastUpdatedAt)
|
|
1653
1829
|
entry.lastUpdatedAt = lastUpdatedAt;
|
|
1654
1830
|
return entry;
|
|
@@ -1736,6 +1912,51 @@ function formatPageMeta(page, useColors, verbose) {
|
|
|
1736
1912
|
}
|
|
1737
1913
|
return lines;
|
|
1738
1914
|
}
|
|
1915
|
+
// src/shared/list-package-docs-text.ts
|
|
1916
|
+
var SEP3 = " | ";
|
|
1917
|
+
function renderListPackageDocsText(envelope) {
|
|
1918
|
+
const lines = [];
|
|
1919
|
+
lines.push(buildHeader3(envelope));
|
|
1920
|
+
lines.push("");
|
|
1921
|
+
if (envelope.pages.length === 0) {
|
|
1922
|
+
lines.push("No documentation pages found.");
|
|
1923
|
+
return lines.join(`
|
|
1924
|
+
`);
|
|
1925
|
+
}
|
|
1926
|
+
for (const page of envelope.pages) {
|
|
1927
|
+
lines.push([
|
|
1928
|
+
page.pageId,
|
|
1929
|
+
page.title ?? "",
|
|
1930
|
+
page.sourceKind ?? "",
|
|
1931
|
+
page.sourceUrl ?? ""
|
|
1932
|
+
].join(SEP3));
|
|
1933
|
+
lines.push(` ${buildDocsReadCommand(page.pageId)}`);
|
|
1934
|
+
if (page.sourceKind === "repo" && page.repoUrl && page.filePath) {
|
|
1935
|
+
lines.push(` ${buildCodeReadCommand({
|
|
1936
|
+
repoUrl: page.repoUrl,
|
|
1937
|
+
gitRef: page.requestedRef ?? page.gitRef,
|
|
1938
|
+
filePath: page.filePath,
|
|
1939
|
+
startLine: 1,
|
|
1940
|
+
endLine: 150
|
|
1941
|
+
})}`);
|
|
1942
|
+
}
|
|
1943
|
+
}
|
|
1944
|
+
if (envelope.nextCursor) {
|
|
1945
|
+
lines.push("");
|
|
1946
|
+
lines.push(`More docs available. Pass after=${envelope.nextCursor}.`);
|
|
1947
|
+
}
|
|
1948
|
+
if (envelope.stale) {
|
|
1949
|
+
lines.push("");
|
|
1950
|
+
lines.push("Documentation may be stale.");
|
|
1951
|
+
}
|
|
1952
|
+
return lines.join(`
|
|
1953
|
+
`);
|
|
1954
|
+
}
|
|
1955
|
+
function buildHeader3(envelope) {
|
|
1956
|
+
const target = envelope.registry && envelope.name ? `${envelope.registry}:${envelope.name}${envelope.version ? `@${envelope.version}` : ""}` : "package docs";
|
|
1957
|
+
const suffix = envelope.total !== undefined ? `/${envelope.total}` : "";
|
|
1958
|
+
return `docs_list${SEP3}${target}${SEP3}${envelope.pages.length}${suffix} page${envelope.pages.length === 1 ? "" : "s"}`;
|
|
1959
|
+
}
|
|
1739
1960
|
// src/shared/package-dependencies-request.ts
|
|
1740
1961
|
class UnsupportedDependenciesRegistryError extends Error {
|
|
1741
1962
|
constructor(message) {
|
|
@@ -1784,6 +2005,7 @@ function buildPackageDependenciesParams(input) {
|
|
|
1784
2005
|
}
|
|
1785
2006
|
const version2 = normaliseVersion(input.version);
|
|
1786
2007
|
const canonicalLifecycles = resolveLifecycles(input.lifecycle);
|
|
2008
|
+
const wireLifecycles = canonicalLifecycles.filter((entry) => entry !== "runtime" && entry !== "all");
|
|
1787
2009
|
const maxDepth = input.maxDepth;
|
|
1788
2010
|
if (maxDepth !== undefined) {
|
|
1789
2011
|
if (!Number.isInteger(maxDepth) || maxDepth < 1 || maxDepth > 10) {
|
|
@@ -1792,13 +2014,14 @@ function buildPackageDependenciesParams(input) {
|
|
|
1792
2014
|
}
|
|
1793
2015
|
return {
|
|
1794
2016
|
canonicalLifecycles,
|
|
2017
|
+
wireLifecycles,
|
|
1795
2018
|
params: {
|
|
1796
2019
|
registry,
|
|
1797
2020
|
packageName: trimmedName,
|
|
1798
2021
|
version: version2,
|
|
1799
2022
|
includeTransitive: input.includeTransitive,
|
|
1800
2023
|
maxDepth,
|
|
1801
|
-
lifecycle:
|
|
2024
|
+
lifecycle: wireLifecycles.length > 0 ? wireLifecycles : undefined
|
|
1802
2025
|
}
|
|
1803
2026
|
};
|
|
1804
2027
|
}
|
|
@@ -1823,16 +2046,29 @@ function resolveLifecycles(raw) {
|
|
|
1823
2046
|
if (trimmed.length === 0)
|
|
1824
2047
|
continue;
|
|
1825
2048
|
const lower = trimmed.toLowerCase();
|
|
1826
|
-
if (!
|
|
1827
|
-
throw new InvalidPackageSpecError(`Unknown lifecycle '${trimmed}'. Expected one of: ${LIFECYCLES.join(", ")}.`);
|
|
2049
|
+
if (!isLifecycleInput(lower)) {
|
|
2050
|
+
throw new InvalidPackageSpecError(`Unknown lifecycle '${trimmed}'. Expected one of: ${LIFECYCLES.join(", ")}, all.`);
|
|
1828
2051
|
}
|
|
1829
2052
|
seen.add(lower);
|
|
1830
2053
|
}
|
|
1831
|
-
|
|
2054
|
+
if (seen.has("all") && seen.size > 1) {
|
|
2055
|
+
throw new InvalidPackageSpecError("lifecycle=all cannot be combined with other lifecycle values.");
|
|
2056
|
+
}
|
|
2057
|
+
return Array.from(seen).sort(lifecycleInputSort);
|
|
1832
2058
|
}
|
|
1833
2059
|
function isLifecycle(value) {
|
|
1834
2060
|
return LIFECYCLES.includes(value);
|
|
1835
2061
|
}
|
|
2062
|
+
function isLifecycleInput(value) {
|
|
2063
|
+
return value === "all" || isLifecycle(value);
|
|
2064
|
+
}
|
|
2065
|
+
function lifecycleInputSort(a, b) {
|
|
2066
|
+
if (a === "all")
|
|
2067
|
+
return b === "all" ? 0 : 1;
|
|
2068
|
+
if (b === "all")
|
|
2069
|
+
return -1;
|
|
2070
|
+
return LIFECYCLE_ORDER[a] - LIFECYCLE_ORDER[b];
|
|
2071
|
+
}
|
|
1836
2072
|
// src/shared/package-dependencies-response.ts
|
|
1837
2073
|
function buildPackageDependenciesSuccessPayload(report, options = {}) {
|
|
1838
2074
|
const pkg = report.package;
|
|
@@ -1854,10 +2090,16 @@ function buildPackageDependenciesSuccessPayload(report, options = {}) {
|
|
|
1854
2090
|
payload.runtime = { count: items.length, items };
|
|
1855
2091
|
}
|
|
1856
2092
|
const groupsInfo = report.dependencyGroups;
|
|
1857
|
-
if (groupsInfo !== undefined) {
|
|
1858
|
-
const groupItems = sortGroups(groupsInfo.groups.map(buildGroup))
|
|
2093
|
+
if (groupsInfo !== undefined && shouldEmitGroups(options.canonicalLifecycles)) {
|
|
2094
|
+
const groupItems = sortGroups(groupsInfo.groups.map(buildGroup).filter((group) => {
|
|
2095
|
+
if (!options.canonicalLifecycles)
|
|
2096
|
+
return false;
|
|
2097
|
+
if (options.canonicalLifecycles.includes("all"))
|
|
2098
|
+
return true;
|
|
2099
|
+
return options.canonicalLifecycles.includes(group.lifecycle);
|
|
2100
|
+
}));
|
|
1859
2101
|
const groupsBlock = { items: groupItems };
|
|
1860
|
-
if (groupsInfo.primaryGroup) {
|
|
2102
|
+
if (groupsInfo.primaryGroup && groupItems.some((group) => group.name === groupsInfo.primaryGroup)) {
|
|
1861
2103
|
groupsBlock.primaryGroup = groupsInfo.primaryGroup;
|
|
1862
2104
|
}
|
|
1863
2105
|
if (groupsInfo.environmentMarkers && groupsInfo.environmentMarkers.length > 0) {
|
|
@@ -1899,6 +2141,11 @@ function buildPackageDependenciesSuccessPayload(report, options = {}) {
|
|
|
1899
2141
|
}
|
|
1900
2142
|
return payload;
|
|
1901
2143
|
}
|
|
2144
|
+
function shouldEmitGroups(lifecycles) {
|
|
2145
|
+
if (!lifecycles || lifecycles.length === 0)
|
|
2146
|
+
return false;
|
|
2147
|
+
return lifecycles.some((entry) => entry !== "runtime");
|
|
2148
|
+
}
|
|
1902
2149
|
function projectEnvironmentMarker(marker) {
|
|
1903
2150
|
const out = {};
|
|
1904
2151
|
if (marker.type !== undefined)
|
|
@@ -2117,7 +2364,7 @@ function formatPackageDependenciesTerminal(report, options = {}) {
|
|
|
2117
2364
|
const verbose = options.verbose ?? false;
|
|
2118
2365
|
const payload = buildPackageDependenciesSuccessPayload(report, {
|
|
2119
2366
|
requestedVersion: options.requestedVersion,
|
|
2120
|
-
canonicalLifecycles: options.canonicalLifecycles,
|
|
2367
|
+
canonicalLifecycles: options.canonicalLifecycles ?? ["all"],
|
|
2121
2368
|
includeTransitive: options.includeTransitive,
|
|
2122
2369
|
maxDepth: options.maxDepth,
|
|
2123
2370
|
includeImporters: verbose
|
|
@@ -2126,7 +2373,7 @@ function formatPackageDependenciesTerminal(report, options = {}) {
|
|
|
2126
2373
|
const showGroups = options.showGroups ?? false;
|
|
2127
2374
|
const includeTransitive = options.includeTransitive ?? false;
|
|
2128
2375
|
const blocks = [];
|
|
2129
|
-
blocks.push(formatHeaderBlock(payload, useColors, showGroups));
|
|
2376
|
+
blocks.push(formatHeaderBlock(payload, useColors, showGroups, options));
|
|
2130
2377
|
if (includeTransitive) {
|
|
2131
2378
|
blocks.push(formatTransitiveDepsList(payload, verbose, useColors));
|
|
2132
2379
|
const issues = formatConflictsAndCycles(payload, verbose, useColors);
|
|
@@ -2143,7 +2390,7 @@ function formatPackageDependenciesTerminal(report, options = {}) {
|
|
|
2143
2390
|
`)}
|
|
2144
2391
|
`;
|
|
2145
2392
|
}
|
|
2146
|
-
function formatHeaderBlock(payload, useColors, showGroups) {
|
|
2393
|
+
function formatHeaderBlock(payload, useColors, showGroups, options) {
|
|
2147
2394
|
const name = colorize(payload.name, "bold", useColors);
|
|
2148
2395
|
const lines = [
|
|
2149
2396
|
`${name} @ ${payload.version} · ${payload.registry}`
|
|
@@ -2151,11 +2398,11 @@ function formatHeaderBlock(payload, useColors, showGroups) {
|
|
|
2151
2398
|
if (payload.requestedVersion) {
|
|
2152
2399
|
lines.push(dim(`(requested ${payload.requestedVersion})`, useColors));
|
|
2153
2400
|
}
|
|
2154
|
-
lines.push(formatSummaryRow(payload, useColors, showGroups));
|
|
2401
|
+
lines.push(formatSummaryRow(payload, useColors, showGroups, options));
|
|
2155
2402
|
return lines.join(`
|
|
2156
2403
|
`);
|
|
2157
2404
|
}
|
|
2158
|
-
function formatSummaryRow(payload, useColors, showGroups) {
|
|
2405
|
+
function formatSummaryRow(payload, useColors, showGroups, options) {
|
|
2159
2406
|
const countParts = [];
|
|
2160
2407
|
const runtimeCount = payload.runtime?.count ?? 0;
|
|
2161
2408
|
if (runtimeCount === 0) {
|
|
@@ -2192,7 +2439,7 @@ function formatSummaryRow(payload, useColors, showGroups) {
|
|
|
2192
2439
|
const hidden = collectHiddenGroupNames(payload);
|
|
2193
2440
|
if (hidden.length === 0)
|
|
2194
2441
|
return countLine;
|
|
2195
|
-
const hiddenLine = dim(`Hidden groups: ${hidden.join(", ")} — use --
|
|
2442
|
+
const hiddenLine = dim(`Hidden groups: ${hidden.join(", ")} — ${options.hiddenGroupsHint ?? "use --lifecycle all."}`, useColors);
|
|
2196
2443
|
return `${countLine}
|
|
2197
2444
|
${hiddenLine}`;
|
|
2198
2445
|
}
|
|
@@ -2483,7 +2730,8 @@ function classify2(error2) {
|
|
|
2483
2730
|
return {
|
|
2484
2731
|
code: "AUTH_REQUIRED",
|
|
2485
2732
|
message: error2.message,
|
|
2486
|
-
retryable: false
|
|
2733
|
+
retryable: false,
|
|
2734
|
+
details: { action: "Run `githits login`, then retry this tool call." }
|
|
2487
2735
|
};
|
|
2488
2736
|
}
|
|
2489
2737
|
if (error2 instanceof PackageIntelligenceNetworkError) {
|
|
@@ -3688,6 +3936,55 @@ function requirePositiveInteger(raw, label) {
|
|
|
3688
3936
|
}
|
|
3689
3937
|
return parsed;
|
|
3690
3938
|
}
|
|
3939
|
+
// src/shared/read-file-text.ts
|
|
3940
|
+
var SEP4 = " | ";
|
|
3941
|
+
function renderReadFileText(envelope) {
|
|
3942
|
+
const lines = [];
|
|
3943
|
+
lines.push(buildHeader4(envelope));
|
|
3944
|
+
lines.push("");
|
|
3945
|
+
if (envelope.isBinary) {
|
|
3946
|
+
lines.push("Binary file - cannot display as text.");
|
|
3947
|
+
} else if (envelope.content) {
|
|
3948
|
+
appendNumberedContent(lines, envelope.content, envelope.startLine ?? 1);
|
|
3949
|
+
} else {
|
|
3950
|
+
lines.push("(no content returned)");
|
|
3951
|
+
}
|
|
3952
|
+
if (envelope.hint) {
|
|
3953
|
+
lines.push("");
|
|
3954
|
+
lines.push(`hint: ${envelope.hint}`);
|
|
3955
|
+
}
|
|
3956
|
+
return lines.join(`
|
|
3957
|
+
`);
|
|
3958
|
+
}
|
|
3959
|
+
function buildHeader4(envelope) {
|
|
3960
|
+
const parts = [`code_read${SEP4}${envelope.path}`];
|
|
3961
|
+
if (envelope.language)
|
|
3962
|
+
parts.push(envelope.language);
|
|
3963
|
+
const range = buildRange(envelope);
|
|
3964
|
+
if (range)
|
|
3965
|
+
parts.push(range);
|
|
3966
|
+
return parts.join(SEP4);
|
|
3967
|
+
}
|
|
3968
|
+
function buildRange(envelope) {
|
|
3969
|
+
if (envelope.startLine !== undefined && envelope.endLine !== undefined) {
|
|
3970
|
+
return envelope.totalLines !== undefined ? `lines ${envelope.startLine}-${envelope.endLine}/${envelope.totalLines}` : `lines ${envelope.startLine}-${envelope.endLine}`;
|
|
3971
|
+
}
|
|
3972
|
+
if (envelope.totalLines !== undefined)
|
|
3973
|
+
return `${envelope.totalLines} lines`;
|
|
3974
|
+
return;
|
|
3975
|
+
}
|
|
3976
|
+
function appendNumberedContent(lines, content, startLine) {
|
|
3977
|
+
const bodyLines = content.split(`
|
|
3978
|
+
`);
|
|
3979
|
+
if (bodyLines.length > 0 && bodyLines[bodyLines.length - 1] === "") {
|
|
3980
|
+
bodyLines.pop();
|
|
3981
|
+
}
|
|
3982
|
+
const endLine = startLine + bodyLines.length - 1;
|
|
3983
|
+
const width = String(endLine).length;
|
|
3984
|
+
for (let i = 0;i < bodyLines.length; i += 1) {
|
|
3985
|
+
lines.push(`${String(startLine + i).padStart(width, " ")} ${bodyLines[i]}`);
|
|
3986
|
+
}
|
|
3987
|
+
}
|
|
3691
3988
|
// src/shared/read-package-doc-request.ts
|
|
3692
3989
|
function buildReadPackageDocParams(input) {
|
|
3693
3990
|
const pageId = input.pageId?.trim() ?? "";
|
|
@@ -3731,8 +4028,6 @@ function buildReadPackageDocSuccessPayload(result, requestedPageId, range) {
|
|
|
3731
4028
|
if (result.page?.breadcrumbs && result.page.breadcrumbs.length > 0) {
|
|
3732
4029
|
envelope.breadcrumbs = result.page.breadcrumbs;
|
|
3733
4030
|
}
|
|
3734
|
-
if (result.page?.linkName)
|
|
3735
|
-
envelope.linkName = result.page.linkName;
|
|
3736
4031
|
if (result.page?.lastUpdatedAt) {
|
|
3737
4032
|
envelope.lastUpdatedAt = toIsoDate(result.page.lastUpdatedAt) ?? undefined;
|
|
3738
4033
|
}
|
|
@@ -3781,7 +4076,7 @@ function formatReadPackageDocTerminal(envelope, options) {
|
|
|
3781
4076
|
return envelope.content ?? "";
|
|
3782
4077
|
}
|
|
3783
4078
|
const lines = [];
|
|
3784
|
-
lines.push(
|
|
4079
|
+
lines.push(buildHeader5(envelope, options.useColors));
|
|
3785
4080
|
lines.push(`pageId: ${envelope.pageId}`);
|
|
3786
4081
|
if (envelope.sourceUrl)
|
|
3787
4082
|
lines.push(`source: ${envelope.sourceUrl}`);
|
|
@@ -3801,37 +4096,49 @@ function formatReadPackageDocTerminal(envelope, options) {
|
|
|
3801
4096
|
`)}
|
|
3802
4097
|
`;
|
|
3803
4098
|
}
|
|
3804
|
-
function
|
|
4099
|
+
function buildHeader5(envelope, useColors) {
|
|
3805
4100
|
const badge = envelope.sourceKind === "repo" ? "[repo]" : "[crawled]";
|
|
3806
4101
|
const title = envelope.title ?? envelope.pageId;
|
|
3807
4102
|
const prefix = envelope.registry && envelope.name ? `${envelope.registry}:${envelope.name}${envelope.version ? `@${envelope.version}` : ""}` : "documentation";
|
|
3808
4103
|
return `${colorize(`${prefix} ${badge}`, "bold", useColors)}${title ? ` - ${title}` : ""}`;
|
|
3809
4104
|
}
|
|
3810
|
-
// src/shared/
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
4105
|
+
// src/shared/read-package-doc-text.ts
|
|
4106
|
+
var SEP5 = " | ";
|
|
4107
|
+
function renderReadPackageDocText(envelope) {
|
|
4108
|
+
const lines = [];
|
|
4109
|
+
lines.push(buildHeader6(envelope));
|
|
4110
|
+
if (envelope.sourceUrl)
|
|
4111
|
+
lines.push(`source: ${envelope.sourceUrl}`);
|
|
4112
|
+
if (envelope.filePath) {
|
|
4113
|
+
const ref = envelope.requestedRef ?? envelope.gitRef;
|
|
4114
|
+
lines.push(`file: ${envelope.filePath}${ref ? ` @ ${ref}` : ""}`);
|
|
3815
4115
|
}
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
`);
|
|
3823
|
-
if (deps.mcpUrl !== "https://mcp.githits.com") {
|
|
3824
|
-
console.log(` Environment: ${deps.mcpUrl}`);
|
|
3825
|
-
console.log(` You're using a custom environment.
|
|
3826
|
-
`);
|
|
4116
|
+
lines.push("");
|
|
4117
|
+
if (envelope.content)
|
|
4118
|
+
lines.push(envelope.content);
|
|
4119
|
+
if (envelope.hint) {
|
|
4120
|
+
lines.push("");
|
|
4121
|
+
lines.push(`hint: ${envelope.hint}`);
|
|
3827
4122
|
}
|
|
3828
|
-
|
|
3829
|
-
console.log(` githits login
|
|
4123
|
+
return lines.join(`
|
|
3830
4124
|
`);
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
4125
|
+
}
|
|
4126
|
+
function buildHeader6(envelope) {
|
|
4127
|
+
const parts = [`docs_read${SEP5}${envelope.pageId}`];
|
|
4128
|
+
if (envelope.title)
|
|
4129
|
+
parts.push(envelope.title);
|
|
4130
|
+
const range = buildRange2(envelope);
|
|
4131
|
+
if (range)
|
|
4132
|
+
parts.push(range);
|
|
4133
|
+
return parts.join(SEP5);
|
|
4134
|
+
}
|
|
4135
|
+
function buildRange2(envelope) {
|
|
4136
|
+
if (envelope.startLine !== undefined && envelope.endLine !== undefined) {
|
|
4137
|
+
return envelope.totalLines !== undefined ? `lines ${envelope.startLine}-${envelope.endLine}/${envelope.totalLines}` : `lines ${envelope.startLine}-${envelope.endLine}`;
|
|
4138
|
+
}
|
|
4139
|
+
if (envelope.totalLines !== undefined)
|
|
4140
|
+
return `${envelope.totalLines} lines`;
|
|
4141
|
+
return;
|
|
3835
4142
|
}
|
|
3836
4143
|
// src/shared/unified-search-request.ts
|
|
3837
4144
|
var DEFAULT_UNIFIED_SEARCH_LIMIT = 10;
|
|
@@ -4107,8 +4414,6 @@ function buildHitPayload(hit) {
|
|
|
4107
4414
|
payload.title = hit.title;
|
|
4108
4415
|
if (hit.summary)
|
|
4109
4416
|
payload.summary = hit.summary;
|
|
4110
|
-
if (typeof hit.score === "number")
|
|
4111
|
-
payload.score = hit.score;
|
|
4112
4417
|
const highlights = buildHighlights(hit.highlights);
|
|
4113
4418
|
if (highlights)
|
|
4114
4419
|
payload.highlights = highlights;
|
|
@@ -4275,49 +4580,17 @@ function assertSearchFollowUpInvariant(hit) {
|
|
|
4275
4580
|
throw new MalformedCodeNavigationResponseError("REPOSITORY_DOC search hit missing repo locator fields.");
|
|
4276
4581
|
}
|
|
4277
4582
|
}
|
|
4278
|
-
// src/shared/unified-search-target.ts
|
|
4279
|
-
function parseUnifiedSearchTargetSpec(spec) {
|
|
4280
|
-
const trimmed = spec.trim();
|
|
4281
|
-
if (trimmed.length === 0) {
|
|
4282
|
-
throw new InvalidArgumentError("Target spec cannot be empty.");
|
|
4283
|
-
}
|
|
4284
|
-
if (trimmed.startsWith("http://") || trimmed.startsWith("https://")) {
|
|
4285
|
-
return parseRepoTarget(trimmed);
|
|
4286
|
-
}
|
|
4287
|
-
const parsed = parsePackageSpec(trimmed);
|
|
4288
|
-
return {
|
|
4289
|
-
registry: toCodeNavigationRegistry(parsed.registry),
|
|
4290
|
-
packageName: parsed.name,
|
|
4291
|
-
version: parsed.version
|
|
4292
|
-
};
|
|
4293
|
-
}
|
|
4294
|
-
function parseRepoTarget(spec) {
|
|
4295
|
-
const hashIndex = spec.lastIndexOf("#");
|
|
4296
|
-
if (hashIndex === -1) {
|
|
4297
|
-
return { repoUrl: spec, gitRef: "HEAD" };
|
|
4298
|
-
}
|
|
4299
|
-
const repoUrl = spec.slice(0, hashIndex);
|
|
4300
|
-
const gitRef = spec.slice(hashIndex + 1);
|
|
4301
|
-
if (!repoUrl || !gitRef) {
|
|
4302
|
-
throw new InvalidArgumentError("Repository target must be a full URL with optional #gitRef suffix.");
|
|
4303
|
-
}
|
|
4304
|
-
return { repoUrl, gitRef };
|
|
4305
|
-
}
|
|
4306
4583
|
// src/shared/unified-search-text.ts
|
|
4307
4584
|
var SUMMARY_WRAP_WIDTH = 76;
|
|
4308
|
-
var
|
|
4585
|
+
var SEP6 = " | ";
|
|
4309
4586
|
function renderUnifiedSearchSuccess(payload) {
|
|
4310
4587
|
const lines = [];
|
|
4311
|
-
lines.push(
|
|
4588
|
+
lines.push(buildHeader7(payload));
|
|
4312
4589
|
lines.push("");
|
|
4313
4590
|
if (payload.results.length === 0) {
|
|
4314
4591
|
lines.push(payload.completed ? "No hits." : "No hits yet - indexing.");
|
|
4315
4592
|
} else {
|
|
4316
|
-
payload.results
|
|
4317
|
-
if (idx > 0)
|
|
4318
|
-
lines.push("");
|
|
4319
|
-
appendHit(lines, idx + 1, hit);
|
|
4320
|
-
});
|
|
4593
|
+
appendUnifiedSearchHits(lines, payload.results);
|
|
4321
4594
|
}
|
|
4322
4595
|
const trailer = buildTrailer2(payload);
|
|
4323
4596
|
if (trailer.length > 0) {
|
|
@@ -4330,7 +4603,7 @@ function renderUnifiedSearchSuccess(payload) {
|
|
|
4330
4603
|
}
|
|
4331
4604
|
function renderUnifiedSearchError(payload) {
|
|
4332
4605
|
const lines = [];
|
|
4333
|
-
const header = `search${
|
|
4606
|
+
const header = `search${SEP6}ERROR${SEP6}code=${payload.code}${payload.retryable ? `${SEP6}retryable` : ""}`;
|
|
4334
4607
|
lines.push(header);
|
|
4335
4608
|
lines.push(payload.error);
|
|
4336
4609
|
if (payload.details && Object.keys(payload.details).length > 0) {
|
|
@@ -4343,21 +4616,25 @@ function renderUnifiedSearchError(payload) {
|
|
|
4343
4616
|
return lines.join(`
|
|
4344
4617
|
`);
|
|
4345
4618
|
}
|
|
4346
|
-
function
|
|
4619
|
+
function buildHeader7(payload) {
|
|
4347
4620
|
const count = payload.results.length;
|
|
4348
4621
|
const status = payload.completed ? `${count} hit${count === 1 ? "" : "s"}` : `${count} partial`;
|
|
4349
|
-
const parts = [`search${
|
|
4350
|
-
parts.push(`query=${
|
|
4622
|
+
const parts = [`search${SEP6}${status}`];
|
|
4623
|
+
parts.push(`query=${quote4(payload.query.raw)}`);
|
|
4351
4624
|
if (!payload.completed) {
|
|
4352
4625
|
parts.push(`searchRef=${payload.searchRef}`);
|
|
4353
4626
|
}
|
|
4354
|
-
return parts.join(
|
|
4627
|
+
return parts.join(SEP6);
|
|
4628
|
+
}
|
|
4629
|
+
function appendUnifiedSearchHits(lines, hits) {
|
|
4630
|
+
hits.forEach((hit, idx) => {
|
|
4631
|
+
if (idx > 0)
|
|
4632
|
+
lines.push("");
|
|
4633
|
+
appendHit(lines, idx + 1, hit);
|
|
4634
|
+
});
|
|
4355
4635
|
}
|
|
4356
4636
|
function appendHit(lines, index, hit) {
|
|
4357
4637
|
const headerParts = [hit.target, shortType(hit.type)];
|
|
4358
|
-
if (typeof hit.score === "number") {
|
|
4359
|
-
headerParts.push(formatScore(hit.score));
|
|
4360
|
-
}
|
|
4361
4638
|
lines.push(`[${index}] ${headerParts.join(" ")}`);
|
|
4362
4639
|
const locator = buildLocatorLine(hit);
|
|
4363
4640
|
if (locator)
|
|
@@ -4387,6 +4664,15 @@ function shortType(type) {
|
|
|
4387
4664
|
}
|
|
4388
4665
|
function buildLocatorLine(hit) {
|
|
4389
4666
|
const loc = hit.locator;
|
|
4667
|
+
const followUp = buildSearchHitFollowUpCommand(hit);
|
|
4668
|
+
if (followUp) {
|
|
4669
|
+
const tail = [];
|
|
4670
|
+
if (loc.qualifiedPath)
|
|
4671
|
+
tail.push(loc.qualifiedPath);
|
|
4672
|
+
if (loc.kind)
|
|
4673
|
+
tail.push(loc.kind);
|
|
4674
|
+
return tail.length > 0 ? `${followUp} ${tail.join(SEP6)}` : followUp;
|
|
4675
|
+
}
|
|
4390
4676
|
if (loc.filePath) {
|
|
4391
4677
|
let line = `${loc.filePath}${formatLineRange(loc.startLine, loc.endLine)}`;
|
|
4392
4678
|
const tail = [];
|
|
@@ -4395,7 +4681,7 @@ function buildLocatorLine(hit) {
|
|
|
4395
4681
|
if (loc.kind)
|
|
4396
4682
|
tail.push(loc.kind);
|
|
4397
4683
|
if (tail.length > 0)
|
|
4398
|
-
line += ` ${tail.join(
|
|
4684
|
+
line += ` ${tail.join(SEP6)}`;
|
|
4399
4685
|
return line;
|
|
4400
4686
|
}
|
|
4401
4687
|
if (loc.pageId)
|
|
@@ -4411,9 +4697,6 @@ function formatLineRange(start, end) {
|
|
|
4411
4697
|
return `:${start}`;
|
|
4412
4698
|
return `:${start}-${end}`;
|
|
4413
4699
|
}
|
|
4414
|
-
function formatScore(score) {
|
|
4415
|
-
return score.toFixed(2);
|
|
4416
|
-
}
|
|
4417
4700
|
function buildTrailer2(payload) {
|
|
4418
4701
|
const lines = [];
|
|
4419
4702
|
if (payload.warnings && payload.warnings.length > 0) {
|
|
@@ -4457,9 +4740,9 @@ function formatSourceStatus(entry) {
|
|
|
4457
4740
|
}
|
|
4458
4741
|
if (entry.note)
|
|
4459
4742
|
parts.push(entry.note);
|
|
4460
|
-
return parts.join(
|
|
4743
|
+
return parts.join(SEP6);
|
|
4461
4744
|
}
|
|
4462
|
-
function
|
|
4745
|
+
function quote4(value) {
|
|
4463
4746
|
return value.includes('"') ? `'${value}'` : `"${value}"`;
|
|
4464
4747
|
}
|
|
4465
4748
|
function formatDetailValue(value) {
|
|
@@ -4491,6 +4774,89 @@ function wrapText2(text, width) {
|
|
|
4491
4774
|
}
|
|
4492
4775
|
return lines;
|
|
4493
4776
|
}
|
|
4777
|
+
|
|
4778
|
+
// src/shared/unified-search-status-text.ts
|
|
4779
|
+
var SEP7 = " | ";
|
|
4780
|
+
function renderUnifiedSearchStatusText(payload) {
|
|
4781
|
+
const lines = [];
|
|
4782
|
+
lines.push(buildHeader8(payload));
|
|
4783
|
+
if (!payload.completed && payload.progress) {
|
|
4784
|
+
lines.push(formatProgress(payload.progress));
|
|
4785
|
+
}
|
|
4786
|
+
const result = payload.result;
|
|
4787
|
+
if (result)
|
|
4788
|
+
appendResult(lines, result);
|
|
4789
|
+
if (!payload.completed) {
|
|
4790
|
+
lines.push(`next: call search_status search_ref=${quote5(payload.searchRef)}`);
|
|
4791
|
+
}
|
|
4792
|
+
return lines.join(`
|
|
4793
|
+
`);
|
|
4794
|
+
}
|
|
4795
|
+
function buildHeader8(payload) {
|
|
4796
|
+
const state = payload.completed ? "complete" : "indexing";
|
|
4797
|
+
const parts = [`search_status${SEP7}${state}`];
|
|
4798
|
+
if (payload.searchRef)
|
|
4799
|
+
parts.push(`searchRef=${payload.searchRef}`);
|
|
4800
|
+
return parts.join(SEP7);
|
|
4801
|
+
}
|
|
4802
|
+
function appendResult(lines, result) {
|
|
4803
|
+
lines.push("");
|
|
4804
|
+
if (result.warnings && result.warnings.length > 0) {
|
|
4805
|
+
lines.push("warnings:");
|
|
4806
|
+
for (const warning2 of result.warnings)
|
|
4807
|
+
lines.push(` - ${warning2}`);
|
|
4808
|
+
lines.push("");
|
|
4809
|
+
}
|
|
4810
|
+
if (result.results.length === 0) {
|
|
4811
|
+
lines.push("No hits.");
|
|
4812
|
+
} else {
|
|
4813
|
+
appendUnifiedSearchHits(lines, result.results);
|
|
4814
|
+
}
|
|
4815
|
+
if (result.hasMore) {
|
|
4816
|
+
const nextOffsetHint = typeof result.nextOffset === "number" ? ` Pass offset=${result.nextOffset} for the next page or limit=N to widen.` : " Pass limit=N to widen.";
|
|
4817
|
+
lines.push("");
|
|
4818
|
+
lines.push(`More hits available.${nextOffsetHint}`);
|
|
4819
|
+
}
|
|
4820
|
+
if (result.sourceStatus && result.sourceStatus.length > 0) {
|
|
4821
|
+
lines.push("");
|
|
4822
|
+
lines.push("source notes:");
|
|
4823
|
+
for (const entry of result.sourceStatus) {
|
|
4824
|
+
lines.push(` - ${formatSourceStatus2(entry)}`);
|
|
4825
|
+
}
|
|
4826
|
+
}
|
|
4827
|
+
}
|
|
4828
|
+
function formatSourceStatus2(entry) {
|
|
4829
|
+
const parts = [`${entry.source} (${entry.targetLabel})`];
|
|
4830
|
+
if (entry.indexingStatus)
|
|
4831
|
+
parts.push(`indexing=${entry.indexingStatus}`);
|
|
4832
|
+
if (entry.codeIndexState)
|
|
4833
|
+
parts.push(`codeIndex=${entry.codeIndexState}`);
|
|
4834
|
+
if (entry.ignoredFilters?.length) {
|
|
4835
|
+
parts.push(`ignored=${entry.ignoredFilters.join(",")}`);
|
|
4836
|
+
}
|
|
4837
|
+
if (entry.incompatibleFilters?.length) {
|
|
4838
|
+
parts.push(`incompatible=${entry.incompatibleFilters.join(",")}`);
|
|
4839
|
+
}
|
|
4840
|
+
if (entry.ignoredQueryFeatures?.length) {
|
|
4841
|
+
parts.push(`ignoredQuery=${entry.ignoredQueryFeatures.join(",")}`);
|
|
4842
|
+
}
|
|
4843
|
+
if (entry.incompatibleQueryFeatures?.length) {
|
|
4844
|
+
parts.push(`incompatibleQuery=${entry.incompatibleQueryFeatures.join(",")}`);
|
|
4845
|
+
}
|
|
4846
|
+
if (entry.note)
|
|
4847
|
+
parts.push(entry.note);
|
|
4848
|
+
return parts.join(SEP7);
|
|
4849
|
+
}
|
|
4850
|
+
function formatProgress(progress) {
|
|
4851
|
+
return `progress: ${progress.status}, ${progress.targetsReady}/${progress.targetsTotal} targets ready, ${progress.elapsedMs}ms elapsed`;
|
|
4852
|
+
}
|
|
4853
|
+
function quote5(value) {
|
|
4854
|
+
return JSON.stringify(value);
|
|
4855
|
+
}
|
|
4856
|
+
// src/shared/unified-search-target.ts
|
|
4857
|
+
function parseUnifiedSearchTargetSpec(spec) {
|
|
4858
|
+
return parseCodeNavigationTargetSpec(spec);
|
|
4859
|
+
}
|
|
4494
4860
|
// src/shared/list-files-request.ts
|
|
4495
4861
|
var LIMIT_MIN2 = 1;
|
|
4496
4862
|
var LIMIT_MAX2 = 1000;
|
|
@@ -4501,20 +4867,140 @@ function buildListFilesParams(input) {
|
|
|
4501
4867
|
const limitExplicit = input.limit !== undefined;
|
|
4502
4868
|
const limit = normaliseLimit(input.limit);
|
|
4503
4869
|
const waitTimeoutMs = normaliseWaitTimeoutMs(input.waitTimeoutMs);
|
|
4870
|
+
const path = normalizeOptionalNonEmpty2(input.path, "path");
|
|
4504
4871
|
const pathPrefix = normalisePathPrefix(input.pathPrefix);
|
|
4872
|
+
const globs = normalizeStringList2(input.globs, "globs");
|
|
4873
|
+
const extensions = normalizeExtensions2(input.extensions);
|
|
4874
|
+
const fileTypes = normalizeStringList2(input.fileTypes, "file_types");
|
|
4875
|
+
const languages = normalizeStringList2(input.languages, "languages");
|
|
4876
|
+
const { fileIntent, fileIntentEcho } = normalizeOptionalFileIntent(input.fileIntent, "file_intent");
|
|
4877
|
+
const fileIntents = normalizeFileIntentList(input.fileIntents, "file_intents");
|
|
4878
|
+
const excludeFileIntents = normalizeFileIntentList(input.excludeFileIntents, "exclude_file_intents");
|
|
4879
|
+
if (fileIntent && fileIntents.length > 0) {
|
|
4880
|
+
throw new InvalidPackageSpecError("`file_intent` cannot be combined with `file_intents`.");
|
|
4881
|
+
}
|
|
4882
|
+
const pathSelectors = buildPathSelectors2({ path, globs });
|
|
4883
|
+
const pathExplicit = path !== undefined;
|
|
4505
4884
|
const pathPrefixExplicit = pathPrefix !== undefined;
|
|
4885
|
+
const globsExplicit = globs.length > 0;
|
|
4506
4886
|
return {
|
|
4507
4887
|
params: {
|
|
4508
4888
|
target: input.target,
|
|
4889
|
+
pathSelectors,
|
|
4509
4890
|
pathPrefix,
|
|
4891
|
+
extensions: extensions.length > 0 ? extensions : undefined,
|
|
4892
|
+
fileTypes: fileTypes.length > 0 ? fileTypes : undefined,
|
|
4893
|
+
languages: languages.length > 0 ? languages : undefined,
|
|
4894
|
+
fileIntent,
|
|
4895
|
+
fileIntents: fileIntents.length > 0 ? fileIntents : undefined,
|
|
4896
|
+
excludeFileIntents: excludeFileIntents.length > 0 ? excludeFileIntents : undefined,
|
|
4897
|
+
excludeDocFiles: input.excludeDocFiles,
|
|
4898
|
+
excludeTestFiles: input.excludeTestFiles,
|
|
4899
|
+
includeHidden: input.includeHidden,
|
|
4510
4900
|
limit,
|
|
4511
4901
|
waitTimeoutMs
|
|
4512
4902
|
},
|
|
4513
4903
|
effectiveLimit: limit,
|
|
4514
4904
|
limitExplicit,
|
|
4515
|
-
|
|
4905
|
+
explicit: {
|
|
4906
|
+
path: pathExplicit,
|
|
4907
|
+
pathPrefix: pathPrefixExplicit,
|
|
4908
|
+
globs: globsExplicit,
|
|
4909
|
+
extensions: extensions.length > 0,
|
|
4910
|
+
fileTypes: fileTypes.length > 0,
|
|
4911
|
+
languages: languages.length > 0,
|
|
4912
|
+
fileIntent: fileIntent !== undefined,
|
|
4913
|
+
fileIntents: fileIntents.length > 0,
|
|
4914
|
+
excludeFileIntents: excludeFileIntents.length > 0,
|
|
4915
|
+
excludeDocFiles: input.excludeDocFiles !== undefined,
|
|
4916
|
+
excludeTestFiles: input.excludeTestFiles !== undefined,
|
|
4917
|
+
includeHidden: input.includeHidden !== undefined,
|
|
4918
|
+
limit: limitExplicit
|
|
4919
|
+
},
|
|
4920
|
+
filterEcho: {
|
|
4921
|
+
path,
|
|
4922
|
+
pathPrefix,
|
|
4923
|
+
globs: globsExplicit ? globs : undefined,
|
|
4924
|
+
extensions: extensions.length > 0 ? extensions : undefined,
|
|
4925
|
+
fileTypes: fileTypes.length > 0 ? fileTypes : undefined,
|
|
4926
|
+
languages: languages.length > 0 ? languages : undefined,
|
|
4927
|
+
fileIntent: fileIntentEcho,
|
|
4928
|
+
fileIntents: fileIntents.length > 0 ? fileIntents.map((intent) => intent.toLowerCase()) : undefined,
|
|
4929
|
+
excludeFileIntents: excludeFileIntents.length > 0 ? excludeFileIntents.map((intent) => intent.toLowerCase()) : undefined,
|
|
4930
|
+
excludeDocFiles: input.excludeDocFiles,
|
|
4931
|
+
excludeTestFiles: input.excludeTestFiles,
|
|
4932
|
+
includeHidden: input.includeHidden,
|
|
4933
|
+
limit: limitExplicit ? limit : undefined
|
|
4934
|
+
}
|
|
4516
4935
|
};
|
|
4517
4936
|
}
|
|
4937
|
+
function buildPathSelectors2(input) {
|
|
4938
|
+
const selectors = [];
|
|
4939
|
+
if (input.path)
|
|
4940
|
+
selectors.push({ kind: "EXACT", value: input.path });
|
|
4941
|
+
for (const glob of input.globs) {
|
|
4942
|
+
selectors.push({ kind: "GLOB", value: glob });
|
|
4943
|
+
}
|
|
4944
|
+
return selectors.length > 0 ? selectors : undefined;
|
|
4945
|
+
}
|
|
4946
|
+
function normalizeOptionalNonEmpty2(raw, field) {
|
|
4947
|
+
if (raw === undefined)
|
|
4948
|
+
return;
|
|
4949
|
+
const trimmed = raw.trim();
|
|
4950
|
+
if (trimmed.length === 0) {
|
|
4951
|
+
throw new InvalidPackageSpecError(`\`${field}\` cannot be empty when provided.`);
|
|
4952
|
+
}
|
|
4953
|
+
return trimmed;
|
|
4954
|
+
}
|
|
4955
|
+
function normalizeStringList2(raw, field) {
|
|
4956
|
+
if (!raw)
|
|
4957
|
+
return [];
|
|
4958
|
+
const values = [];
|
|
4959
|
+
for (const entry of raw) {
|
|
4960
|
+
const trimmed = entry.trim();
|
|
4961
|
+
if (trimmed.length === 0) {
|
|
4962
|
+
throw new InvalidPackageSpecError(`\`${field}\` entries cannot be empty.`);
|
|
4963
|
+
}
|
|
4964
|
+
values.push(trimmed);
|
|
4965
|
+
}
|
|
4966
|
+
return values;
|
|
4967
|
+
}
|
|
4968
|
+
function normalizeExtensions2(raw) {
|
|
4969
|
+
const values = normalizeStringList2(raw, "extensions");
|
|
4970
|
+
for (const value of values) {
|
|
4971
|
+
if (value.startsWith(".")) {
|
|
4972
|
+
throw new InvalidPackageSpecError("`extensions` values must not include a leading dot.");
|
|
4973
|
+
}
|
|
4974
|
+
}
|
|
4975
|
+
return values;
|
|
4976
|
+
}
|
|
4977
|
+
function normalizeOptionalFileIntent(raw, field) {
|
|
4978
|
+
if (raw === undefined)
|
|
4979
|
+
return {};
|
|
4980
|
+
const trimmed = raw.trim().toLowerCase();
|
|
4981
|
+
if (trimmed.length === 0) {
|
|
4982
|
+
throw new InvalidPackageSpecError(`\`${field}\` cannot be empty when provided.`);
|
|
4983
|
+
}
|
|
4984
|
+
if (!isKnownFileIntent(trimmed)) {
|
|
4985
|
+
throw new InvalidPackageSpecError(`\`${field}\` must be one of: ${knownFileIntentList().join(", ")}. Got ${raw}.`);
|
|
4986
|
+
}
|
|
4987
|
+
return {
|
|
4988
|
+
fileIntent: toFileIntent(trimmed),
|
|
4989
|
+
fileIntentEcho: trimmed
|
|
4990
|
+
};
|
|
4991
|
+
}
|
|
4992
|
+
function normalizeFileIntentList(raw, field) {
|
|
4993
|
+
const values = normalizeStringList2(raw, field);
|
|
4994
|
+
const intents = [];
|
|
4995
|
+
for (const value of values) {
|
|
4996
|
+
const lower = value.toLowerCase();
|
|
4997
|
+
if (!isKnownFileIntent(lower)) {
|
|
4998
|
+
throw new InvalidPackageSpecError(`\`${field}\` values must be one of: ${knownFileIntentList().join(", ")}. Got ${value}.`);
|
|
4999
|
+
}
|
|
5000
|
+
intents.push(toFileIntent(lower));
|
|
5001
|
+
}
|
|
5002
|
+
return intents;
|
|
5003
|
+
}
|
|
4518
5004
|
function normaliseLimit(raw) {
|
|
4519
5005
|
if (raw === undefined)
|
|
4520
5006
|
return LIMIT_DEFAULT2;
|
|
@@ -4593,10 +5079,43 @@ function projectResolution2(resolution) {
|
|
|
4593
5079
|
}
|
|
4594
5080
|
function buildFilterBlock2(options) {
|
|
4595
5081
|
const filter = {};
|
|
4596
|
-
if (options.
|
|
5082
|
+
if (options.explicit.path && options.path) {
|
|
5083
|
+
filter.path = options.path;
|
|
5084
|
+
}
|
|
5085
|
+
if (options.explicit.pathPrefix && options.pathPrefix) {
|
|
4597
5086
|
filter.pathPrefix = options.pathPrefix;
|
|
4598
5087
|
}
|
|
4599
|
-
if (options.
|
|
5088
|
+
if (options.explicit.globs && options.globs && options.globs.length > 0) {
|
|
5089
|
+
filter.globs = options.globs;
|
|
5090
|
+
}
|
|
5091
|
+
if (options.explicit.extensions && options.extensions && options.extensions.length > 0) {
|
|
5092
|
+
filter.extensions = options.extensions;
|
|
5093
|
+
}
|
|
5094
|
+
if (options.explicit.fileTypes && options.fileTypes && options.fileTypes.length > 0) {
|
|
5095
|
+
filter.fileTypes = options.fileTypes;
|
|
5096
|
+
}
|
|
5097
|
+
if (options.explicit.languages && options.languages && options.languages.length > 0) {
|
|
5098
|
+
filter.languages = options.languages;
|
|
5099
|
+
}
|
|
5100
|
+
if (options.explicit.fileIntent && options.fileIntent) {
|
|
5101
|
+
filter.fileIntent = options.fileIntent;
|
|
5102
|
+
}
|
|
5103
|
+
if (options.explicit.fileIntents && options.fileIntents && options.fileIntents.length > 0) {
|
|
5104
|
+
filter.fileIntents = options.fileIntents;
|
|
5105
|
+
}
|
|
5106
|
+
if (options.explicit.excludeFileIntents && options.excludeFileIntents && options.excludeFileIntents.length > 0) {
|
|
5107
|
+
filter.excludeFileIntents = options.excludeFileIntents;
|
|
5108
|
+
}
|
|
5109
|
+
if (options.explicit.excludeDocFiles) {
|
|
5110
|
+
filter.excludeDocFiles = options.excludeDocFiles;
|
|
5111
|
+
}
|
|
5112
|
+
if (options.explicit.excludeTestFiles) {
|
|
5113
|
+
filter.excludeTestFiles = options.excludeTestFiles;
|
|
5114
|
+
}
|
|
5115
|
+
if (options.explicit.includeHidden) {
|
|
5116
|
+
filter.includeHidden = options.includeHidden;
|
|
5117
|
+
}
|
|
5118
|
+
if (options.explicit.limit && options.limit !== undefined) {
|
|
4600
5119
|
filter.limit = options.limit;
|
|
4601
5120
|
}
|
|
4602
5121
|
return Object.keys(filter).length > 0 ? filter : undefined;
|
|
@@ -4848,9 +5367,19 @@ async function pkgFilesAction(firstArg, secondArg, options, deps) {
|
|
|
4848
5367
|
const target = resolveCliCodeNavTarget(spec, options);
|
|
4849
5368
|
const limit = parseIntCliOption(options.limit, "--limit", 1, 1000);
|
|
4850
5369
|
const wait = parseIntCliOption(options.wait, "--wait", 0, MAX_WAIT_TIMEOUT_MS);
|
|
4851
|
-
const build =
|
|
5370
|
+
const build = buildCliListFilesParams({
|
|
4852
5371
|
target,
|
|
5372
|
+
path: options.path,
|
|
4853
5373
|
pathPrefix,
|
|
5374
|
+
globs: options.glob,
|
|
5375
|
+
extensions: options.ext,
|
|
5376
|
+
fileTypes: options.fileType,
|
|
5377
|
+
languages: options.language,
|
|
5378
|
+
fileIntents: options.fileIntent,
|
|
5379
|
+
excludeFileIntents: options.excludeIntent,
|
|
5380
|
+
excludeDocFiles: options.excludeDocs,
|
|
5381
|
+
excludeTestFiles: options.excludeTests,
|
|
5382
|
+
includeHidden: options.hidden,
|
|
4854
5383
|
limit,
|
|
4855
5384
|
waitTimeoutMs: wait
|
|
4856
5385
|
});
|
|
@@ -4860,10 +5389,20 @@ async function pkgFilesAction(firstArg, secondArg, options, deps) {
|
|
|
4860
5389
|
name: target.packageName,
|
|
4861
5390
|
repoUrl: target.repoUrl,
|
|
4862
5391
|
gitRef: target.gitRef,
|
|
4863
|
-
|
|
4864
|
-
|
|
4865
|
-
|
|
4866
|
-
|
|
5392
|
+
path: build.filterEcho.path,
|
|
5393
|
+
pathPrefix: build.filterEcho.pathPrefix,
|
|
5394
|
+
globs: build.filterEcho.globs,
|
|
5395
|
+
extensions: build.filterEcho.extensions,
|
|
5396
|
+
fileTypes: build.filterEcho.fileTypes,
|
|
5397
|
+
languages: build.filterEcho.languages,
|
|
5398
|
+
fileIntent: build.filterEcho.fileIntent,
|
|
5399
|
+
fileIntents: build.filterEcho.fileIntents,
|
|
5400
|
+
excludeFileIntents: build.filterEcho.excludeFileIntents,
|
|
5401
|
+
excludeDocFiles: build.filterEcho.excludeDocFiles,
|
|
5402
|
+
excludeTestFiles: build.filterEcho.excludeTestFiles,
|
|
5403
|
+
includeHidden: build.filterEcho.includeHidden,
|
|
5404
|
+
limit: build.filterEcho.limit,
|
|
5405
|
+
explicit: build.explicit
|
|
4867
5406
|
});
|
|
4868
5407
|
if (options.json) {
|
|
4869
5408
|
console.log(JSON.stringify(payload));
|
|
@@ -4880,6 +5419,21 @@ async function pkgFilesAction(firstArg, secondArg, options, deps) {
|
|
|
4880
5419
|
handleCodeNavCommandError(error2, options.json ?? false, formatIndexingError);
|
|
4881
5420
|
}
|
|
4882
5421
|
}
|
|
5422
|
+
function collectRepeatable(value, previous) {
|
|
5423
|
+
return [...previous ?? [], value];
|
|
5424
|
+
}
|
|
5425
|
+
function buildCliListFilesParams(input) {
|
|
5426
|
+
try {
|
|
5427
|
+
return buildListFilesParams(input);
|
|
5428
|
+
} catch (error2) {
|
|
5429
|
+
if (!(error2 instanceof InvalidPackageSpecError))
|
|
5430
|
+
throw error2;
|
|
5431
|
+
const rewritten = error2.message.replace(/^`path`/, "`--path`").replace(/`globs`/g, "`--glob`").replace(/`extensions`/g, "`--ext`").replace(/`file_types`/g, "`--file-type`").replace(/`languages`/g, "`--language`").replace(/`file_intent`/g, "`--file-intent`").replace(/`file_intents`/g, "`--file-intent`").replace(/`exclude_file_intents`/g, "`--exclude-intent`").replace(/`path_prefix`/g, "`[path-prefix]`");
|
|
5432
|
+
if (rewritten === error2.message)
|
|
5433
|
+
throw error2;
|
|
5434
|
+
throw new InvalidPackageSpecError(rewritten);
|
|
5435
|
+
}
|
|
5436
|
+
}
|
|
4883
5437
|
var REGISTRY_SPEC_HINT = /^(npm|pypi|hex|crates|nuget|maven|zig|vcpkg|packagist):/i;
|
|
4884
5438
|
function resolvePositionals(firstArg, secondArg, hasRepoUrl) {
|
|
4885
5439
|
if (hasRepoUrl) {
|
|
@@ -4899,8 +5453,11 @@ fetch more. Returned paths feed directly into \`githits code read\`
|
|
|
4899
5453
|
and \`githits code grep\`.
|
|
4900
5454
|
|
|
4901
5455
|
[path-prefix] is a literal directory prefix (e.g. \`src/\` or
|
|
4902
|
-
\`lib/parser\`)
|
|
4903
|
-
|
|
5456
|
+
\`lib/parser\`). Use --path for exact-file selectors, repeatable
|
|
5457
|
+
--glob for glob selectors, and --ext / --file-type / --language /
|
|
5458
|
+
--file-intent to intersect further. Selectors ([path-prefix], --path,
|
|
5459
|
+
--glob) are OR-ed — a file matches if any selector matches. The other
|
|
5460
|
+
filters intersect on top.
|
|
4904
5461
|
|
|
4905
5462
|
Addressing: <spec> (registry:name[@version]) OR --repo-url <url>
|
|
4906
5463
|
--git-ref <ref>. Supported registries: npm, pypi, hex, crates,
|
|
@@ -4913,7 +5470,7 @@ On an INDEXING response, the dependency is being indexed on-demand
|
|
|
4913
5470
|
— retry with a longer --wait (up to 60000 ms) or pick one of the
|
|
4914
5471
|
already-indexed versions surfaced in the error detail.`;
|
|
4915
5472
|
function registerCodeFilesCommand(pkgCommand) {
|
|
4916
|
-
return pkgCommand.command("files").summary("List files in an indexed dependency").description(PKG_FILES_DESCRIPTION).argument("[spec-or-prefix]", "Spec mode: package spec (e.g. npm:express). Repo mode (with --repo-url): the path-prefix.").argument("[path-prefix]", "Spec mode only: literal directory prefix (not a glob). 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("--limit <n>", "Max entries (1-1000, default 200)").option("--wait <ms>", `Indexing wait timeout (0-${MAX_WAIT_TIMEOUT_MS}, default ${DEFAULT_WAIT_TIMEOUT_MS})`).option("-v, --verbose", "Annotate each path with language / file-type / byte size").option("--json", "Emit the JSON envelope").action(async (arg1, arg2, options) => {
|
|
5473
|
+
return pkgCommand.command("files").summary("List files in an indexed dependency").description(PKG_FILES_DESCRIPTION).argument("[spec-or-prefix]", "Spec mode: package spec (e.g. npm:express). Repo mode (with --repo-url): the path-prefix.").argument("[path-prefix]", "Spec mode only: literal directory prefix (not a glob). 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 selector").option("--glob <glob>", "Glob selector (repeatable)", collectRepeatable).option("--ext <ext>", "Extension filter without leading dot (repeatable)", collectRepeatable).option("--file-type <type>", "File type filter such as source or doc (repeatable)", collectRepeatable).option("--language <language>", "Language filter matching aigrep language names (repeatable)", collectRepeatable).option("--file-intent <intent>", "Inclusive file-intent filter. Repeat to include multiple intents: production, test, benchmark, example, generated, fixture, build, vendor", collectRepeatable).option("--exclude-intent <intent>", "Exclude these file intents after inclusive filtering (repeatable)", collectRepeatable).option("--exclude-docs", "Skip files classified as documentation").option("--exclude-tests", "Skip files classified as tests").option("--hidden", "Include dotfiles and dot-prefixed paths").option("--limit <n>", "Max entries (1-1000, default 200)").option("--wait <ms>", `Indexing wait timeout (0-${MAX_WAIT_TIMEOUT_MS}, default ${DEFAULT_WAIT_TIMEOUT_MS})`).option("-v, --verbose", "Annotate each path with language / file-type / byte size").option("--json", "Emit the JSON envelope").action(async (arg1, arg2, options) => {
|
|
4917
5474
|
const deps = await createContainer();
|
|
4918
5475
|
await pkgFilesAction(arg1, arg2, options, {
|
|
4919
5476
|
codeNavigationService: deps.codeNavigationService,
|
|
@@ -5020,7 +5577,7 @@ function resolvePositionals2(first, second, third, hasRepoUrl) {
|
|
|
5020
5577
|
}
|
|
5021
5578
|
return { spec: first, pattern: second, pathPrefix: third };
|
|
5022
5579
|
}
|
|
5023
|
-
function
|
|
5580
|
+
function collectRepeatable2(value, previous = []) {
|
|
5024
5581
|
return [...previous, value];
|
|
5025
5582
|
}
|
|
5026
5583
|
function buildCliGrepParams(input) {
|
|
@@ -5055,8 +5612,8 @@ for context, --verbose for grouped output, and --cursor to continue a paginated
|
|
|
5055
5612
|
grep run. --symbol-field hydrates enclosing symbol metadata (appears under each
|
|
5056
5613
|
match in --verbose output; full payload in --json).`;
|
|
5057
5614
|
function registerCodeGrepCommand(pkgCommand) {
|
|
5058
|
-
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)",
|
|
5059
|
-
const { createContainer: createContainer2 } = await import("./shared/chunk-
|
|
5615
|
+
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)", collectRepeatable2, []).option("--ext <ext>", "Extension filter without leading dot (repeatable)", collectRepeatable2, []).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}`, collectRepeatable2, []).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) => {
|
|
5616
|
+
const { createContainer: createContainer2 } = await import("./shared/chunk-rwcs5gyy.js");
|
|
5060
5617
|
const deps = await createContainer2();
|
|
5061
5618
|
await pkgGrepAction(arg1, arg2, arg3, options, {
|
|
5062
5619
|
codeNavigationService: deps.codeNavigationService,
|
|
@@ -5152,7 +5709,7 @@ function formatReadFileTerminal(envelope, options) {
|
|
|
5152
5709
|
function formatBinary(envelope, options, verbose) {
|
|
5153
5710
|
const sentinel = dim("Binary file — cannot display as text.", options.useColors);
|
|
5154
5711
|
if (verbose) {
|
|
5155
|
-
return `${
|
|
5712
|
+
return `${buildHeader9(envelope, options)}
|
|
5156
5713
|
|
|
5157
5714
|
${sentinel}
|
|
5158
5715
|
`;
|
|
@@ -5163,7 +5720,7 @@ ${sentinel}
|
|
|
5163
5720
|
function formatNoContent(envelope, options, verbose) {
|
|
5164
5721
|
const sentinel = dim("(no content returned)", options.useColors);
|
|
5165
5722
|
if (verbose) {
|
|
5166
|
-
return `${
|
|
5723
|
+
return `${buildHeader9(envelope, options)}
|
|
5167
5724
|
|
|
5168
5725
|
${sentinel}
|
|
5169
5726
|
`;
|
|
@@ -5173,7 +5730,7 @@ ${sentinel}
|
|
|
5173
5730
|
}
|
|
5174
5731
|
function formatVerboseBody(envelope, options) {
|
|
5175
5732
|
const lines = [];
|
|
5176
|
-
lines.push(
|
|
5733
|
+
lines.push(buildHeader9(envelope, options));
|
|
5177
5734
|
lines.push("");
|
|
5178
5735
|
const content = envelope.content ?? "";
|
|
5179
5736
|
const bodyLines = content.split(`
|
|
@@ -5197,7 +5754,7 @@ function formatVerboseBody(envelope, options) {
|
|
|
5197
5754
|
return lines.join(`
|
|
5198
5755
|
`);
|
|
5199
5756
|
}
|
|
5200
|
-
function
|
|
5757
|
+
function buildHeader9(envelope, options) {
|
|
5201
5758
|
const parts = [envelope.path];
|
|
5202
5759
|
if (envelope.language)
|
|
5203
5760
|
parts.push(envelope.language);
|
|
@@ -5575,7 +6132,7 @@ function registerExampleCommand(program) {
|
|
|
5575
6132
|
});
|
|
5576
6133
|
}
|
|
5577
6134
|
async function loadContainer() {
|
|
5578
|
-
const { createContainer: createContainer2 } = await import("./shared/chunk-
|
|
6135
|
+
const { createContainer: createContainer2 } = await import("./shared/chunk-rwcs5gyy.js");
|
|
5579
6136
|
return createContainer2();
|
|
5580
6137
|
}
|
|
5581
6138
|
// src/commands/feedback.ts
|
|
@@ -6364,14 +6921,11 @@ async function preflightAuthPersistence(authStorage, mcpUrl) {
|
|
|
6364
6921
|
createdAt: new Date(0).toISOString()
|
|
6365
6922
|
};
|
|
6366
6923
|
try {
|
|
6367
|
-
await authStorage.
|
|
6368
|
-
await authStorage.
|
|
6369
|
-
await authStorage.clearTokens(probeUrl);
|
|
6370
|
-
await authStorage.clearClient(probeUrl);
|
|
6924
|
+
await authStorage.saveAuthSession(probeUrl, probeClient, probeTokens);
|
|
6925
|
+
await authStorage.clearAuthSession(probeUrl);
|
|
6371
6926
|
return null;
|
|
6372
6927
|
} catch (error2) {
|
|
6373
|
-
await authStorage.
|
|
6374
|
-
await authStorage.clearClient(probeUrl).catch(() => {});
|
|
6928
|
+
await authStorage.clearAuthSession(probeUrl).catch(() => {});
|
|
6375
6929
|
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
6376
6930
|
return {
|
|
6377
6931
|
status: "failed",
|
|
@@ -6425,7 +6979,6 @@ async function loginFlow(options, deps) {
|
|
|
6425
6979
|
redirectUri,
|
|
6426
6980
|
registeredAt: new Date().toISOString()
|
|
6427
6981
|
};
|
|
6428
|
-
await authStorage.saveClient(mcpUrl, client);
|
|
6429
6982
|
}
|
|
6430
6983
|
port = options.port;
|
|
6431
6984
|
} else {
|
|
@@ -6447,7 +7000,6 @@ async function loginFlow(options, deps) {
|
|
|
6447
7000
|
redirectUri,
|
|
6448
7001
|
registeredAt: new Date().toISOString()
|
|
6449
7002
|
};
|
|
6450
|
-
await authStorage.saveClient(mcpUrl, client);
|
|
6451
7003
|
}
|
|
6452
7004
|
const { verifier, challenge, state } = authService.generatePkceParams();
|
|
6453
7005
|
const authUrl = authService.buildAuthUrl({
|
|
@@ -6512,7 +7064,7 @@ async function loginFlow(options, deps) {
|
|
|
6512
7064
|
};
|
|
6513
7065
|
}
|
|
6514
7066
|
const expiresAt = new Date(Date.now() + tokenResponse.expiresIn * 1000).toISOString();
|
|
6515
|
-
await authStorage.
|
|
7067
|
+
await authStorage.saveAuthSession(mcpUrl, client, {
|
|
6516
7068
|
accessToken: tokenResponse.accessToken,
|
|
6517
7069
|
refreshToken: tokenResponse.refreshToken,
|
|
6518
7070
|
expiresAt,
|
|
@@ -6762,7 +7314,11 @@ async function languagesAction(query, options, deps) {
|
|
|
6762
7314
|
requireAuth(deps);
|
|
6763
7315
|
try {
|
|
6764
7316
|
const allLanguages = await deps.githitsService.getLanguages();
|
|
6765
|
-
const displayList = query ? filterLanguages(allLanguages, query) : allLanguages.map(({ name, display_name }) => ({
|
|
7317
|
+
const displayList = query ? filterLanguages(allLanguages, query) : allLanguages.map(({ name, display_name, aliases }) => ({
|
|
7318
|
+
name,
|
|
7319
|
+
display_name,
|
|
7320
|
+
aliases
|
|
7321
|
+
}));
|
|
6766
7322
|
if (options.json) {
|
|
6767
7323
|
console.log(JSON.stringify(displayList));
|
|
6768
7324
|
} else if (query && displayList.length === 0) {
|
|
@@ -6803,17 +7359,7 @@ function registerLanguagesCommand(program) {
|
|
|
6803
7359
|
async function logoutAction(deps) {
|
|
6804
7360
|
const { authStorage, mcpUrl } = deps;
|
|
6805
7361
|
const auth = await authStorage.loadTokens(mcpUrl);
|
|
6806
|
-
|
|
6807
|
-
try {
|
|
6808
|
-
await authStorage.clearTokens(mcpUrl);
|
|
6809
|
-
} catch (error2) {
|
|
6810
|
-
firstError = error2;
|
|
6811
|
-
}
|
|
6812
|
-
try {
|
|
6813
|
-
await authStorage.clearClient(mcpUrl);
|
|
6814
|
-
} catch (error2) {
|
|
6815
|
-
firstError ??= error2;
|
|
6816
|
-
}
|
|
7362
|
+
await authStorage.clearAuthSession(mcpUrl);
|
|
6817
7363
|
if (!auth) {
|
|
6818
7364
|
console.log(`Not currently logged in.
|
|
6819
7365
|
`);
|
|
@@ -6823,8 +7369,6 @@ async function logoutAction(deps) {
|
|
|
6823
7369
|
`);
|
|
6824
7370
|
console.log(` Environment: ${mcpUrl}`);
|
|
6825
7371
|
}
|
|
6826
|
-
if (firstError)
|
|
6827
|
-
throw firstError;
|
|
6828
7372
|
}
|
|
6829
7373
|
var LOGOUT_DESCRIPTION = `Remove stored credentials.
|
|
6830
7374
|
|
|
@@ -6870,8 +7414,9 @@ function classify3(operation, error2) {
|
|
|
6870
7414
|
if (error2 instanceof AuthenticationError) {
|
|
6871
7415
|
return {
|
|
6872
7416
|
error: error2.message,
|
|
6873
|
-
code: "
|
|
6874
|
-
retryable: false
|
|
7417
|
+
code: "AUTH_REQUIRED",
|
|
7418
|
+
retryable: false,
|
|
7419
|
+
details: { action: "Run `githits login`, then retry this tool call." }
|
|
6875
7420
|
};
|
|
6876
7421
|
}
|
|
6877
7422
|
const message = error2 instanceof Error ? error2.message : "Unknown error";
|
|
@@ -6913,11 +7458,12 @@ import { z as z2 } from "zod";
|
|
|
6913
7458
|
var schema2 = {
|
|
6914
7459
|
query: z2.string().min(1).describe("Natural-language example-search query for canonical code examples."),
|
|
6915
7460
|
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."),
|
|
6916
|
-
license_mode: z2.enum(["strict", "yolo", "custom"]).optional().describe("License filtering mode: strict (default), yolo, or custom.")
|
|
7461
|
+
license_mode: z2.enum(["strict", "yolo", "custom"]).optional().describe("License filtering mode: strict (default), yolo, or custom."),
|
|
7462
|
+
format: z2.enum(["json", "text", "text-v1"]).optional().describe("Response format. Default `text-v1` returns markdown directly with a trailing `solution_id` line when available. Pass `json` for `{result, solution_id?}`.")
|
|
6917
7463
|
};
|
|
6918
7464
|
var DESCRIPTION2 = `Get verified, canonical code examples from global open source.
|
|
6919
7465
|
|
|
6920
|
-
|
|
7466
|
+
Default output is markdown, with a trailing \`solution_id: ...\` line when available. Pass \`format: "json"\` for \`{result, solution_id?}\`. Pass \`solution_id\` to \`feedback\` after using or rejecting the example. For searching indexed dependency and repository code/docs, use the unified \`search\` tool instead.`;
|
|
6921
7467
|
function createGetExampleTool(service) {
|
|
6922
7468
|
return {
|
|
6923
7469
|
name: "get_example",
|
|
@@ -6933,17 +7479,25 @@ function createGetExampleTool(service) {
|
|
|
6933
7479
|
});
|
|
6934
7480
|
const solutionId = extractSolutionId(markdown);
|
|
6935
7481
|
const payload = solutionId ? { result: markdown, solution_id: solutionId } : { result: markdown };
|
|
7482
|
+
if (isTextFormat(args.format)) {
|
|
7483
|
+
return textResult(solutionId ? `${markdown.trimEnd()}
|
|
7484
|
+
|
|
7485
|
+
solution_id: ${solutionId}` : markdown);
|
|
7486
|
+
}
|
|
6936
7487
|
return textResult(JSON.stringify(payload));
|
|
6937
7488
|
});
|
|
6938
7489
|
}
|
|
6939
7490
|
};
|
|
6940
7491
|
}
|
|
7492
|
+
function isTextFormat(format) {
|
|
7493
|
+
return format === undefined || format === "text" || format === "text-v1";
|
|
7494
|
+
}
|
|
6941
7495
|
// src/tools/grep-repo.ts
|
|
6942
7496
|
import { z as z4 } from "zod";
|
|
6943
7497
|
|
|
6944
7498
|
// src/tools/code-navigation-shared.ts
|
|
6945
7499
|
import { z as z3 } from "zod";
|
|
6946
|
-
var
|
|
7500
|
+
var structuredCodeTargetSchema = z3.object({
|
|
6947
7501
|
registry: z3.enum([
|
|
6948
7502
|
"npm",
|
|
6949
7503
|
"pypi",
|
|
@@ -6960,7 +7514,18 @@ var codeTargetSchema = z3.object({
|
|
|
6960
7514
|
repo_url: z3.string().optional().describe("Repository URL (GitHub). Required for repo scope. Example: https://github.com/expressjs/express"),
|
|
6961
7515
|
git_ref: z3.string().optional().describe("Git ref - tag, branch, or commit. Required with repo_url. Use HEAD for latest.")
|
|
6962
7516
|
}).describe("Target: provide registry + package_name (package scope) or repo_url + git_ref (repo scope).");
|
|
7517
|
+
var codeTargetSchema = z3.union([
|
|
7518
|
+
structuredCodeTargetSchema,
|
|
7519
|
+
z3.string().min(1).describe("Compact target string. Package: `npm:react@18.2.0`. Repository: `https://github.com/facebook/react#HEAD` (git ref suffix optional, defaults to HEAD).")
|
|
7520
|
+
]);
|
|
6963
7521
|
function resolveCodeTarget(target) {
|
|
7522
|
+
if (typeof target === "string") {
|
|
7523
|
+
try {
|
|
7524
|
+
return parseCodeNavigationTargetSpec(target);
|
|
7525
|
+
} catch (error2) {
|
|
7526
|
+
return mappedInvalidTargetResult(error2);
|
|
7527
|
+
}
|
|
7528
|
+
}
|
|
6964
7529
|
const hasPackageTarget = Boolean(target.registry || target.package_name);
|
|
6965
7530
|
const hasRepoTarget = Boolean(target.repo_url || target.git_ref);
|
|
6966
7531
|
if (hasPackageTarget && hasRepoTarget) {
|
|
@@ -6993,6 +7558,15 @@ function resolveCodeTarget(target) {
|
|
|
6993
7558
|
gitRef: target.git_ref
|
|
6994
7559
|
};
|
|
6995
7560
|
}
|
|
7561
|
+
function mappedInvalidTargetResult(error2) {
|
|
7562
|
+
const mapped = mapCodeNavigationError(error2);
|
|
7563
|
+
return errorResult(JSON.stringify({
|
|
7564
|
+
error: mapped.message,
|
|
7565
|
+
code: mapped.code,
|
|
7566
|
+
retryable: mapped.retryable ?? false,
|
|
7567
|
+
...mapped.details ? { details: mapped.details } : {}
|
|
7568
|
+
}));
|
|
7569
|
+
}
|
|
6996
7570
|
function invalidTargetResult(message) {
|
|
6997
7571
|
return errorResult(JSON.stringify({
|
|
6998
7572
|
error: message,
|
|
@@ -7079,7 +7653,7 @@ function createGrepRepoTool(service) {
|
|
|
7079
7653
|
excludeTestFiles: build.params.excludeTestFiles,
|
|
7080
7654
|
explicit: build.explicit
|
|
7081
7655
|
});
|
|
7082
|
-
if (
|
|
7656
|
+
if (isTextFormat2(args.format)) {
|
|
7083
7657
|
return textResult(renderGrepRepoText(payload));
|
|
7084
7658
|
}
|
|
7085
7659
|
return textResult(JSON.stringify(payload));
|
|
@@ -7095,19 +7669,30 @@ function createGrepRepoTool(service) {
|
|
|
7095
7669
|
}
|
|
7096
7670
|
};
|
|
7097
7671
|
}
|
|
7098
|
-
function
|
|
7672
|
+
function isTextFormat2(format) {
|
|
7099
7673
|
return format === undefined || format === "text" || format === "text-v1";
|
|
7100
7674
|
}
|
|
7101
7675
|
// src/tools/list-files.ts
|
|
7102
7676
|
import { z as z5 } from "zod";
|
|
7103
7677
|
var schema4 = {
|
|
7104
7678
|
target: codeTargetSchema,
|
|
7105
|
-
|
|
7679
|
+
path: z5.string().optional().describe("Exact target-relative file path to include. When combined with `path_prefix` or `globs`, files matching any selector are returned."),
|
|
7680
|
+
path_prefix: z5.string().optional().describe("Literal directory prefix to filter by (e.g. `src/` or `lib/parser`). NOT a glob. OR-ed with `path` and `globs` when combined."),
|
|
7681
|
+
globs: z5.array(z5.string()).optional().describe("Repeatable glob selectors with real glob semantics (e.g. `src/**/*.ts`). OR-ed with `path` and `path_prefix`."),
|
|
7682
|
+
extensions: z5.array(z5.string()).optional().describe("File extensions to include, without a leading dot."),
|
|
7683
|
+
file_types: z5.array(z5.string()).optional().describe("File type filters to include, matching aigrep file_type values such as `source` or `doc`."),
|
|
7684
|
+
languages: z5.array(z5.string()).optional().describe("Language filters to include, matching aigrep language names."),
|
|
7685
|
+
file_intent: z5.string().optional().describe(`Single inclusive file-intent filter. Cannot be combined with \`file_intents\`. Valid values: ${knownFileIntentList().join(", ")}.`),
|
|
7686
|
+
file_intents: z5.array(z5.string()).optional().describe(`Inclusive file-intent filters. Cannot be combined with \`file_intent\`. Valid values: ${knownFileIntentList().join(", ")}.`),
|
|
7687
|
+
exclude_file_intents: z5.array(z5.string()).optional().describe(`Exclude these file intents after inclusive intent filtering. Valid values: ${knownFileIntentList().join(", ")}.`),
|
|
7688
|
+
exclude_doc_files: z5.boolean().optional(),
|
|
7689
|
+
exclude_test_files: z5.boolean().optional(),
|
|
7690
|
+
include_hidden: z5.boolean().optional(),
|
|
7106
7691
|
limit: z5.number().optional().describe("Max entries to return (1–1000, default 200). Out-of-range values return an `INVALID_ARGUMENT` envelope."),
|
|
7107
7692
|
wait_timeout_ms: z5.number().optional().describe("Max milliseconds to wait for indexing (0–60000, default 20000). On an `INDEXING` error envelope, retry with a longer timeout or pass a version from `details.availableVersions`."),
|
|
7108
7693
|
format: z5.enum(["json", "text", "text-v1"]).optional().describe('Response format. Default `text-v1` — compact paths-only listing tuned for agent context efficiency. Pass `format: "json"` for the structured envelope. `text` is an alias for `text-v1`. Errors stay JSON-formatted in either mode for now.')
|
|
7109
7694
|
};
|
|
7110
|
-
var DESCRIPTION4 = "List files in an indexed dependency. Default response is a compact " + 'paths-only listing (`format: "text-v1"`); pass `format: "json"` ' + "for the structured envelope `{total, hasMore, files: [{path, name, " + "language, fileType, byteSize}], resolution, indexedVersion}`. " + "Address via `target.registry` + `target.package_name` (package " + "scope) or `target.repo_url` + `target.git_ref` (repo scope), " + "mutually exclusive.
|
|
7695
|
+
var DESCRIPTION4 = "List files in an indexed dependency. Default response is a compact " + 'paths-only listing (`format: "text-v1"`); pass `format: "json"` ' + "for the structured envelope `{total, hasMore, files: [{path, name, " + "language, fileType, byteSize}], resolution, indexedVersion}`. " + "Address via `target.registry` + `target.package_name` (package " + "scope) or `target.repo_url` + `target.git_ref` (repo scope), " + "mutually exclusive. Narrow with `path`, `path_prefix`, `globs`, " + "`extensions`, `file_types`, `languages`, or file-intent filters. " + "The returned paths feed directly into `code_read` and help scope " + "`code_grep`. Returns an `INDEXING` error envelope when the " + "dependency is being indexed on-demand — retry with a longer " + "`wait_timeout_ms` or use a version from `details.availableVersions`.";
|
|
7111
7696
|
function createListFilesTool(service) {
|
|
7112
7697
|
return {
|
|
7113
7698
|
name: "code_files",
|
|
@@ -7121,7 +7706,18 @@ function createListFilesTool(service) {
|
|
|
7121
7706
|
try {
|
|
7122
7707
|
const build = buildListFilesParams({
|
|
7123
7708
|
target,
|
|
7709
|
+
path: args.path,
|
|
7124
7710
|
pathPrefix: args.path_prefix,
|
|
7711
|
+
globs: args.globs,
|
|
7712
|
+
extensions: args.extensions,
|
|
7713
|
+
fileTypes: args.file_types,
|
|
7714
|
+
languages: args.languages,
|
|
7715
|
+
fileIntent: args.file_intent,
|
|
7716
|
+
fileIntents: args.file_intents,
|
|
7717
|
+
excludeFileIntents: args.exclude_file_intents,
|
|
7718
|
+
excludeDocFiles: args.exclude_doc_files,
|
|
7719
|
+
excludeTestFiles: args.exclude_test_files,
|
|
7720
|
+
includeHidden: args.include_hidden,
|
|
7125
7721
|
limit: args.limit,
|
|
7126
7722
|
waitTimeoutMs: args.wait_timeout_ms
|
|
7127
7723
|
});
|
|
@@ -7131,12 +7727,22 @@ function createListFilesTool(service) {
|
|
|
7131
7727
|
name: target.packageName,
|
|
7132
7728
|
repoUrl: target.repoUrl,
|
|
7133
7729
|
gitRef: target.gitRef,
|
|
7134
|
-
|
|
7135
|
-
|
|
7136
|
-
|
|
7137
|
-
|
|
7730
|
+
path: build.filterEcho.path,
|
|
7731
|
+
pathPrefix: build.filterEcho.pathPrefix,
|
|
7732
|
+
globs: build.filterEcho.globs,
|
|
7733
|
+
extensions: build.filterEcho.extensions,
|
|
7734
|
+
fileTypes: build.filterEcho.fileTypes,
|
|
7735
|
+
languages: build.filterEcho.languages,
|
|
7736
|
+
fileIntent: build.filterEcho.fileIntent,
|
|
7737
|
+
fileIntents: build.filterEcho.fileIntents,
|
|
7738
|
+
excludeFileIntents: build.filterEcho.excludeFileIntents,
|
|
7739
|
+
excludeDocFiles: build.filterEcho.excludeDocFiles,
|
|
7740
|
+
excludeTestFiles: build.filterEcho.excludeTestFiles,
|
|
7741
|
+
includeHidden: build.filterEcho.includeHidden,
|
|
7742
|
+
limit: build.filterEcho.limit,
|
|
7743
|
+
explicit: build.explicit
|
|
7138
7744
|
});
|
|
7139
|
-
if (
|
|
7745
|
+
if (isTextFormat3(args.format)) {
|
|
7140
7746
|
return textResult(renderListFilesText(payload));
|
|
7141
7747
|
}
|
|
7142
7748
|
return textResult(JSON.stringify(payload));
|
|
@@ -7152,7 +7758,7 @@ function createListFilesTool(service) {
|
|
|
7152
7758
|
}
|
|
7153
7759
|
};
|
|
7154
7760
|
}
|
|
7155
|
-
function
|
|
7761
|
+
function isTextFormat3(format) {
|
|
7156
7762
|
return format === undefined || format === "text" || format === "text-v1";
|
|
7157
7763
|
}
|
|
7158
7764
|
// src/tools/list-package-docs.ts
|
|
@@ -7162,7 +7768,8 @@ var schema5 = {
|
|
|
7162
7768
|
package_name: z6.string().describe("Package name (scoped names ok: @types/node)."),
|
|
7163
7769
|
version: z6.string().optional().describe("Optional package version."),
|
|
7164
7770
|
limit: z6.number().optional().describe("Max pages to return (1-500, default 100)."),
|
|
7165
|
-
after: z6.string().optional().describe("Pagination cursor from a prior response.")
|
|
7771
|
+
after: z6.string().optional().describe("Pagination cursor from a prior response."),
|
|
7772
|
+
format: z6.enum(["json", "text", "text-v1"]).optional().describe('Response format. Default `text-v1` — compact page list with ready-to-call `docs_read` follow-ups. Pass `format: "json"` for the structured envelope.')
|
|
7166
7773
|
};
|
|
7167
7774
|
var DESCRIPTION5 = "List mixed package documentation pages from hosted docs and repository-backed docs. " + "Every entry includes a stable `pageId`, `sourceKind` (`crawled` or `repo`), and source URL; repo-backed entries also expose `repoUrl` / `gitRef` / `filePath` for exact file reads. " + "Pass a returned `pageId` to `docs_read`. Use this to browse before reading a full page.";
|
|
7168
7775
|
function createListPackageDocsTool(service) {
|
|
@@ -7187,6 +7794,9 @@ function createListPackageDocsTool(service) {
|
|
|
7187
7794
|
limit: build.params.limit,
|
|
7188
7795
|
after: build.params.after
|
|
7189
7796
|
});
|
|
7797
|
+
if (isTextFormat4(args.format)) {
|
|
7798
|
+
return textResult(renderListPackageDocsText(payload));
|
|
7799
|
+
}
|
|
7190
7800
|
return textResult(JSON.stringify(payload));
|
|
7191
7801
|
} catch (error2) {
|
|
7192
7802
|
const mapped = mapPackageIntelligenceError(error2);
|
|
@@ -7200,6 +7810,9 @@ function createListPackageDocsTool(service) {
|
|
|
7200
7810
|
}
|
|
7201
7811
|
};
|
|
7202
7812
|
}
|
|
7813
|
+
function isTextFormat4(format) {
|
|
7814
|
+
return format === undefined || format === "text" || format === "text-v1";
|
|
7815
|
+
}
|
|
7203
7816
|
// src/tools/package-changelog.ts
|
|
7204
7817
|
import { z as z7 } from "zod";
|
|
7205
7818
|
|
|
@@ -7318,17 +7931,15 @@ function buildPackageChangelogSuccessPayload(report, options) {
|
|
|
7318
7931
|
}
|
|
7319
7932
|
return lean;
|
|
7320
7933
|
});
|
|
7321
|
-
if (report.source == null) {
|
|
7322
|
-
throw new Error("Changelog envelope builder received a null source — should have been promoted to NOT_FOUND at the service boundary.");
|
|
7323
|
-
}
|
|
7324
7934
|
const envelope = {
|
|
7325
|
-
source: report.source,
|
|
7326
7935
|
mode: options.mode,
|
|
7327
7936
|
entries: {
|
|
7328
7937
|
count: items.length,
|
|
7329
7938
|
items
|
|
7330
7939
|
}
|
|
7331
7940
|
};
|
|
7941
|
+
if (report.source)
|
|
7942
|
+
envelope.source = report.source;
|
|
7332
7943
|
if (options.registry)
|
|
7333
7944
|
envelope.registry = options.registry;
|
|
7334
7945
|
if (options.name)
|
|
@@ -7402,12 +8013,12 @@ function appendBodyLines(lines, body, options) {
|
|
|
7402
8013
|
}
|
|
7403
8014
|
const hidden = bodyLines.length - visible.length;
|
|
7404
8015
|
if (hidden > 0) {
|
|
7405
|
-
lines.push(` ${dim(`… (+${hidden} more line${hidden === 1 ? "" : "s"} — use --verbose for the full body)`, options.useColors)}`);
|
|
8016
|
+
lines.push(` ${dim(`… (+${hidden} more line${hidden === 1 ? "" : "s"} — ${options.fullBodyHint ?? "use --verbose for the full body"})`, options.useColors)}`);
|
|
7406
8017
|
}
|
|
7407
8018
|
}
|
|
7408
8019
|
function buildSummaryLine(envelope, options) {
|
|
7409
8020
|
const identity = envelope.registry && envelope.name ? `${envelope.name} · ${envelope.registry}` : envelope.repoUrl ?? "(unknown)";
|
|
7410
|
-
const sourceLabel = humanizeSource(envelope.source);
|
|
8021
|
+
const sourceLabel = envelope.source ? humanizeSource(envelope.source) : "package versions";
|
|
7411
8022
|
const modeLabel = envelope.mode === "range" ? rangeLabel(envelope) : latestLabel(envelope);
|
|
7412
8023
|
const countLabel = `${envelope.entries.count} ${plural2("entry", "entries", envelope.entries.count)}`;
|
|
7413
8024
|
const parts = [identity, `source: ${sourceLabel}`, modeLabel, countLabel];
|
|
@@ -7474,9 +8085,10 @@ var schema6 = {
|
|
|
7474
8085
|
to_version: z7.string().optional().describe("End of range / latest-mode cap. Works in either mode. Defaults to latest on the wire. Tag-style `v`-prefixed inputs are rejected."),
|
|
7475
8086
|
limit: z7.number().optional().describe("Latest-mode cap on entry count (1–50, default 10). Rejected with `INVALID_ARGUMENT` when `from_version` is also set or when out of range."),
|
|
7476
8087
|
git_ref: z7.string().optional().describe("Git branch or tag for CHANGELOG.md source (no effect on GitHub Releases or HexDocs). Defaults to the repository's default branch."),
|
|
7477
|
-
include_bodies: z7.boolean().optional().describe("When false, each entry in `entries.items[]` omits its `body` field. Default true. Set false when you only need the version / date / URL timeline — drops 10 KB+ per entry on large release notes.")
|
|
8088
|
+
include_bodies: z7.boolean().optional().describe("When false, each entry in `entries.items[]` omits its `body` field. Default true. Set false when you only need the version / date / URL timeline — drops 10 KB+ per entry on large release notes."),
|
|
8089
|
+
format: z7.enum(["json", "text", "text-v1"]).optional().describe("Response format. Default `text-v1` is compact for agents. Pass `json` for the structured envelope.")
|
|
7478
8090
|
};
|
|
7479
|
-
var DESCRIPTION6 = "Release notes for a package or GitHub repo, newest-first. Default " + "latest mode returns the ten most recent entries (`limit` 1–50). " + "With `from_version`, returns every entry in the " + "`[from_version, to_version]` range (range mode, no count cap). " + "Address via `registry` + `package_name` or `repo_url` (mutually " + 'exclusive). Response
|
|
8091
|
+
var DESCRIPTION6 = "Release notes for a package or GitHub repo, newest-first. Default " + "latest mode returns the ten most recent entries (`limit` 1–50). " + "With `from_version`, returns every entry in the " + "`[from_version, to_version]` range (range mode, no count cap). " + "Address via `registry` + `package_name` or `repo_url` (mutually " + 'exclusive). Response includes optional `source` (`"releases"` / ' + '`"changelog_file"` / `"hexdocs"`) when a concrete changelog source ' + 'exists, `mode` (`"latest"` or `"range"`), ' + 'and entries with markdown body previews. Pass `format: "json"` ' + "for the structured envelope with full markdown bodies. Set " + "`include_bodies: false` for a version / date / URL timeline only. " + "Package-version entries without changelog text succeed with `source` " + "omitted; no-source plus no entries returns `NOT_FOUND`. Supports npm, " + "PyPI, Hex, Crates, vcpkg, Zig, NuGet, Maven, Packagist.";
|
|
7480
8092
|
function createPackageChangelogTool(service) {
|
|
7481
8093
|
return {
|
|
7482
8094
|
name: "pkg_changelog",
|
|
@@ -7507,6 +8119,13 @@ function createPackageChangelogTool(service) {
|
|
|
7507
8119
|
limit: params.limit,
|
|
7508
8120
|
gitRef: params.gitRef
|
|
7509
8121
|
});
|
|
8122
|
+
if (isTextFormat5(args.format)) {
|
|
8123
|
+
return textResult(formatPackageChangelogTerminal(payload, {
|
|
8124
|
+
useColors: false,
|
|
8125
|
+
verbose: false,
|
|
8126
|
+
fullBodyHint: 'pass format="json" for full bodies'
|
|
8127
|
+
}).trimEnd());
|
|
8128
|
+
}
|
|
7510
8129
|
return textResult(JSON.stringify(payload));
|
|
7511
8130
|
} catch (error2) {
|
|
7512
8131
|
const mapped = mapPackageIntelligenceError(error2);
|
|
@@ -7528,18 +8147,22 @@ function createPackageChangelogTool(service) {
|
|
|
7528
8147
|
}
|
|
7529
8148
|
};
|
|
7530
8149
|
}
|
|
8150
|
+
function isTextFormat5(format) {
|
|
8151
|
+
return format === undefined || format === "text" || format === "text-v1";
|
|
8152
|
+
}
|
|
7531
8153
|
// src/tools/package-dependencies.ts
|
|
7532
8154
|
import { z as z8 } from "zod";
|
|
7533
8155
|
var schema7 = {
|
|
7534
8156
|
registry: z8.string().describe("Package registry. Dependency data is available on npm, pypi, hex, crates, vcpkg, and zig."),
|
|
7535
8157
|
package_name: z8.string().describe("Package name (scoped names ok: @types/node)."),
|
|
7536
8158
|
version: z8.string().optional().describe("Specific version to inspect. Defaults to latest when omitted. Tag-style inputs with a leading `v` (for example `v4.18.0`) are rejected — pass the canonical version (`4.18.0`)."),
|
|
7537
|
-
lifecycle: z8.union([z8.string(), z8.array(z8.string())]).optional().describe(
|
|
8159
|
+
lifecycle: z8.union([z8.string(), z8.array(z8.string())]).optional().describe("Lifecycle breadth. Omit for runtime-only. Use `runtime` for explicit runtime-only, a concrete non-runtime lifecycle (`development`, `build`, `peer`, `optional`) for runtime plus matching groups, or `all` for runtime plus all available groups. Accepts a single value, a comma-separated string, or an array; `all` cannot be combined with other values. Uppercase is tolerated."),
|
|
7538
8160
|
include_transitive: z8.boolean().optional().describe("When true the response gains a `transitive` block with aggregate counts (`edges`, `uniquePackages`), the preprocessed `packages[]` list (each `{name, version}` — the complete install footprint), plus typed `conflicts[]` (`{name, requiredVersions}`) and `circularDependencies[]` (`{cycle: string[]}`) when the backend reported any. Off by default."),
|
|
7539
8161
|
include_importers: z8.boolean().optional().describe("Requires `include_transitive: true`. When true, each entry in `transitive.packages[]` also carries an `importers` array — every upstream package that pulls it in, with that importer's own resolved version and the constraint it declared. Off by default because adding provenance roughly quadruples the envelope size on heavy graphs. Turn on when you need to trace why a specific transitive dep is present."),
|
|
7540
|
-
max_depth: z8.number().int().min(1).max(10).optional().describe("Cap the transitive traversal at this depth (1–10). Omit to get the backend's full graph. Requires `include_transitive: true` — passing `max_depth` without the transitive flag is rejected with `INVALID_ARGUMENT`.")
|
|
8162
|
+
max_depth: z8.number().int().min(1).max(10).optional().describe("Cap the transitive traversal at this depth (1–10). Omit to get the backend's full graph. Requires `include_transitive: true` — passing `max_depth` without the transitive flag is rejected with `INVALID_ARGUMENT`."),
|
|
8163
|
+
format: z8.enum(["json", "text", "text-v1"]).optional().describe("Response format. Default `text-v1` is compact for agents. Pass `json` for the structured envelope.")
|
|
7541
8164
|
};
|
|
7542
|
-
var DESCRIPTION7 = "Analyze a package's dependency graph.
|
|
8165
|
+
var DESCRIPTION7 = "Analyze a package's dependency graph. Default output is compact " + "text listing direct runtime dependencies with resolved versions; " + 'pass `format: "json"` for the structured envelope. Non-runtime ' + "groups are omitted by default for token efficiency. Use `lifecycle` " + "with a concrete value for runtime plus matching groups, or `all` " + "for runtime plus all available groups. Set " + "`include_transitive: true` to add a `transitive` block with the " + "full install footprint, conflict detection, and circular-" + "dependency flags; layer `include_importers: true` on top when you " + "also need per-package provenance. Supports npm, PyPI, Hex, Crates, " + "vcpkg, and Zig.";
|
|
7543
8166
|
function createPackageDependenciesTool(service) {
|
|
7544
8167
|
return {
|
|
7545
8168
|
name: "pkg_deps",
|
|
@@ -7571,6 +8194,18 @@ function createPackageDependenciesTool(service) {
|
|
|
7571
8194
|
maxDepth: args.max_depth,
|
|
7572
8195
|
includeImporters: args.include_importers ?? false
|
|
7573
8196
|
});
|
|
8197
|
+
if (isTextFormat6(args.format)) {
|
|
8198
|
+
const textLifecycles = canonicalLifecycles.length > 0 ? canonicalLifecycles : ["all"];
|
|
8199
|
+
return textResult(formatPackageDependenciesTerminal(report, {
|
|
8200
|
+
useColors: false,
|
|
8201
|
+
requestedVersion: args.version,
|
|
8202
|
+
canonicalLifecycles: textLifecycles,
|
|
8203
|
+
includeTransitive: args.include_transitive,
|
|
8204
|
+
maxDepth: args.max_depth,
|
|
8205
|
+
showGroups: canonicalLifecycles.length > 0 && !canonicalLifecycles.every((item) => item === "runtime"),
|
|
8206
|
+
hiddenGroupsHint: 'pass lifecycle="all".'
|
|
8207
|
+
}).trimEnd());
|
|
8208
|
+
}
|
|
7574
8209
|
return textResult(JSON.stringify(payload));
|
|
7575
8210
|
} catch (error2) {
|
|
7576
8211
|
const mapped = mapPackageIntelligenceError(error2);
|
|
@@ -7592,13 +8227,17 @@ function createPackageDependenciesTool(service) {
|
|
|
7592
8227
|
}
|
|
7593
8228
|
};
|
|
7594
8229
|
}
|
|
8230
|
+
function isTextFormat6(format) {
|
|
8231
|
+
return format === undefined || format === "text" || format === "text-v1";
|
|
8232
|
+
}
|
|
7595
8233
|
// src/tools/package-summary.ts
|
|
7596
8234
|
import { z as z9 } from "zod";
|
|
7597
8235
|
var schema8 = {
|
|
7598
8236
|
registry: z9.string().describe("Package registry. One of: npm, pypi, hex, crates, nuget, maven, zig, vcpkg, packagist."),
|
|
7599
|
-
package_name: z9.string().describe("Package name (scoped names ok: @types/node).")
|
|
8237
|
+
package_name: z9.string().describe("Package name (scoped names ok: @types/node)."),
|
|
8238
|
+
format: z9.enum(["json", "text", "text-v1"]).optional().describe("Response format. Default `text-v1` is compact for agents. Pass `json` for the structured envelope.")
|
|
7600
8239
|
};
|
|
7601
|
-
var DESCRIPTION8 = "Get a package overview — latest version, license, description, " + "repository, downloads, GitHub stars, install command, recent " + "changes, and a count of known vulnerabilities. Use before " + "recommending a package or to orient on what a dependency is. " + "Works across npm, PyPI, Hex, Crates, NuGet, Maven, Packagist, " + "vcpkg, and Zig. Always returns data for the latest published " + "version.";
|
|
8240
|
+
var DESCRIPTION8 = "Get a package overview — latest version, license, description, " + "repository, downloads, GitHub stars, install command, recent " + "changes, and a count of known vulnerabilities. Use before " + "recommending a package or to orient on what a dependency is. " + 'Default output is compact text; pass `format: "json"` for the ' + "structured envelope. " + "Works across npm, PyPI, Hex, Crates, NuGet, Maven, Packagist, " + "vcpkg, and Zig. Always returns data for the latest published " + "version.";
|
|
7602
8241
|
function createPackageSummaryTool(service) {
|
|
7603
8242
|
return {
|
|
7604
8243
|
name: "pkg_info",
|
|
@@ -7613,6 +8252,11 @@ function createPackageSummaryTool(service) {
|
|
|
7613
8252
|
});
|
|
7614
8253
|
const summary = await service.packageSummary(params);
|
|
7615
8254
|
const payload = buildPackageSummarySuccessPayload(summary);
|
|
8255
|
+
if (isTextFormat7(args.format)) {
|
|
8256
|
+
return textResult(formatPackageSummaryTerminal(summary, {
|
|
8257
|
+
useColors: false
|
|
8258
|
+
}).trimEnd());
|
|
8259
|
+
}
|
|
7616
8260
|
return textResult(JSON.stringify(payload));
|
|
7617
8261
|
} catch (error2) {
|
|
7618
8262
|
const mapped = mapPackageIntelligenceError(error2);
|
|
@@ -7634,6 +8278,9 @@ function createPackageSummaryTool(service) {
|
|
|
7634
8278
|
}
|
|
7635
8279
|
};
|
|
7636
8280
|
}
|
|
8281
|
+
function isTextFormat7(format) {
|
|
8282
|
+
return format === undefined || format === "text" || format === "text-v1";
|
|
8283
|
+
}
|
|
7637
8284
|
// src/tools/package-vulnerabilities.ts
|
|
7638
8285
|
import { z as z10 } from "zod";
|
|
7639
8286
|
var schema9 = {
|
|
@@ -7641,9 +8288,10 @@ var schema9 = {
|
|
|
7641
8288
|
package_name: z10.string().describe("Package name (scoped names ok: @types/node)."),
|
|
7642
8289
|
version: z10.string().optional().describe("Specific version to check. Defaults to latest when omitted."),
|
|
7643
8290
|
min_severity: z10.string().optional().describe("Only return advisories at or above this severity (`low`, `medium`, `high`, `critical`; uppercase tolerated). Omit to see all, including null-severity advisories."),
|
|
7644
|
-
include_withdrawn: z10.boolean().optional().describe("Include retracted advisories (default: false).")
|
|
8291
|
+
include_withdrawn: z10.boolean().optional().describe("Include retracted advisories (default: false)."),
|
|
8292
|
+
format: z10.enum(["json", "text", "text-v1"]).optional().describe("Response format. Default `text-v1` is compact for agents. Pass `json` for the structured envelope.")
|
|
7645
8293
|
};
|
|
7646
|
-
var DESCRIPTION9 = "Check known vulnerabilities for a package on npm, PyPI, Hex, or " + "Crates (other registries are not yet supported for vulnerability " + "data). Returns a count summary, each advisory with OSV ID, " + "severity, affected ranges, and fix versions. Malicious-package advisories surface in a separate " + "bucket. Pass `version` to inspect a specific release; otherwise " + "the latest is checked. Use `min_severity` to filter to a threshold " + "(`low`, `medium`, `high`, `critical`) and `include_withdrawn` to " + "also see retracted advisories.";
|
|
8294
|
+
var DESCRIPTION9 = "Check known vulnerabilities for a package on npm, PyPI, Hex, or " + "Crates (other registries are not yet supported for vulnerability " + "data). Returns a count summary, each advisory with OSV ID, " + "severity, affected ranges, and fix versions. Malicious-package advisories surface in a separate " + "bucket. Pass `version` to inspect a specific release; otherwise " + "the latest is checked. Use `min_severity` to filter to a threshold " + "(`low`, `medium`, `high`, `critical`) and `include_withdrawn` to " + "also see retracted advisories. Default output is compact text; " + 'pass `format: "json"` for the structured envelope.';
|
|
7647
8295
|
function createPackageVulnerabilitiesTool(service) {
|
|
7648
8296
|
return {
|
|
7649
8297
|
name: "pkg_vulns",
|
|
@@ -7663,6 +8311,12 @@ function createPackageVulnerabilitiesTool(service) {
|
|
|
7663
8311
|
const payload = buildPackageVulnerabilitiesSuccessPayload(report, {
|
|
7664
8312
|
requestedVersion: args.version
|
|
7665
8313
|
});
|
|
8314
|
+
if (isTextFormat8(args.format)) {
|
|
8315
|
+
return textResult(formatPackageVulnerabilitiesTerminal(report, {
|
|
8316
|
+
useColors: false,
|
|
8317
|
+
requestedVersion: args.version
|
|
8318
|
+
}).trimEnd());
|
|
8319
|
+
}
|
|
7666
8320
|
return textResult(JSON.stringify(payload));
|
|
7667
8321
|
} catch (error2) {
|
|
7668
8322
|
const mapped = mapPackageIntelligenceError(error2);
|
|
@@ -7684,6 +8338,9 @@ function createPackageVulnerabilitiesTool(service) {
|
|
|
7684
8338
|
}
|
|
7685
8339
|
};
|
|
7686
8340
|
}
|
|
8341
|
+
function isTextFormat8(format) {
|
|
8342
|
+
return format === undefined || format === "text" || format === "text-v1";
|
|
8343
|
+
}
|
|
7687
8344
|
// src/tools/read-file.ts
|
|
7688
8345
|
import { z as z11 } from "zod";
|
|
7689
8346
|
var MCP_READ_MAX_SPAN = 150;
|
|
@@ -7692,7 +8349,8 @@ var schema10 = {
|
|
|
7692
8349
|
path: z11.string().describe("Path to the file. Package addressing: package-relative. Repo addressing: repo-relative. This is the same `path` key that `code_files` emits for each entry, so chaining needs no renaming."),
|
|
7693
8350
|
start_line: z11.number().optional().describe(`Starting line (1-indexed). Omit to start at line 1. The MCP surface caps any single read at ${MCP_READ_MAX_SPAN} lines — pick a focused window from your prior \`search\` / \`code_grep\` hit.`),
|
|
7694
8351
|
end_line: z11.number().optional().describe(`Ending line (inclusive). Must be ≥ \`start_line\` when both are set. Omitting it implies \`start_line + ${MCP_READ_MAX_SPAN - 1}\` because the MCP surface caps each read at ${MCP_READ_MAX_SPAN} lines.`),
|
|
7695
|
-
wait_timeout_ms: z11.number().optional().describe("Max milliseconds to wait for indexing (0–60000, default 20000). On an `INDEXING` error envelope, retry with a longer timeout or pass a version from `details.availableVersions`.")
|
|
8352
|
+
wait_timeout_ms: z11.number().optional().describe("Max milliseconds to wait for indexing (0–60000, default 20000). On an `INDEXING` error envelope, retry with a longer timeout or pass a version from `details.availableVersions`."),
|
|
8353
|
+
format: z11.enum(["json", "text", "text-v1"]).optional().describe('Response format. Default `text-v1` — line-numbered source content. Pass `format: "json"` for the structured envelope.')
|
|
7696
8354
|
};
|
|
7697
8355
|
var DESCRIPTION10 = "Read a file from an indexed dependency. **MCP cap: " + `${MCP_READ_MAX_SPAN} lines per call** — broader requests (or no ` + `range) silently truncate to the first ${MCP_READ_MAX_SPAN} lines ` + "from your start, with a `hint` describing what was returned vs. " + "requested. Pick a focused window from a `search` / `code_grep` " + "match. Response: `{path, language, totalLines, startLine, endLine, " + "content, isBinary, hint?}`. Binary files set `isBinary: true` and " + "omit `content`. Pass the same `path` emitted by `code_files`. " + "Address via `target.registry` + `target.package_name` (package " + "scope) or `target.repo_url` + `target.git_ref` (repo scope), " + "mutually exclusive. On `INDEXING` retry with a longer " + "`wait_timeout_ms`. On `NOT_FOUND` / `FILE_NOT_FOUND` call " + "`code_files` to discover the actual path.";
|
|
7698
8356
|
function deriveBoundedRange(startLine, endLine) {
|
|
@@ -7744,6 +8402,9 @@ function createReadFileTool(service) {
|
|
|
7744
8402
|
if (shouldEmitCappedHint(bounded, payload)) {
|
|
7745
8403
|
payload.hint = buildCappedHint(payload, args.start_line, args.end_line);
|
|
7746
8404
|
}
|
|
8405
|
+
if (isTextFormat9(args.format)) {
|
|
8406
|
+
return textResult(renderReadFileText(payload));
|
|
8407
|
+
}
|
|
7747
8408
|
return textResult(JSON.stringify(payload));
|
|
7748
8409
|
} catch (error2) {
|
|
7749
8410
|
const mapped = mapCodeNavigationError(error2);
|
|
@@ -7757,6 +8418,9 @@ function createReadFileTool(service) {
|
|
|
7757
8418
|
}
|
|
7758
8419
|
};
|
|
7759
8420
|
}
|
|
8421
|
+
function isTextFormat9(format) {
|
|
8422
|
+
return format === undefined || format === "text" || format === "text-v1";
|
|
8423
|
+
}
|
|
7760
8424
|
function shouldEmitCappedHint(bounded, payload) {
|
|
7761
8425
|
if (!bounded.capped)
|
|
7762
8426
|
return false;
|
|
@@ -7786,10 +8450,12 @@ function describeRequest(originalStart, originalEnd) {
|
|
|
7786
8450
|
}
|
|
7787
8451
|
// src/tools/read-package-doc.ts
|
|
7788
8452
|
import { z as z12 } from "zod";
|
|
8453
|
+
var MCP_DOC_READ_MAX_SPAN = 150;
|
|
7789
8454
|
var schema11 = {
|
|
7790
8455
|
page_id: z12.string().describe("Documentation page ID from `docs_list` or `search` results. Pass through unchanged; repo-backed IDs are snapshot-pinned."),
|
|
7791
8456
|
start_line: z12.number().optional().describe("Starting line (1-indexed). Omit for the full page. Use with `end_line` to bound how much content the tool returns when a page is large."),
|
|
7792
|
-
end_line: z12.number().optional().describe("Ending line (inclusive). Omit for end of page. Must be ≥ `start_line` when both are set.")
|
|
8457
|
+
end_line: z12.number().optional().describe("Ending line (inclusive). Omit for end of page. Must be ≥ `start_line` when both are set."),
|
|
8458
|
+
format: z12.enum(["json", "text", "text-v1"]).optional().describe('Response format. Default `text-v1` — raw markdown content capped to 150 lines by default. Pass `format: "json"` for the structured envelope; explicit ranges still slice JSON content.')
|
|
7793
8459
|
};
|
|
7794
8460
|
var DESCRIPTION11 = "Read a documentation page by page ID. Works for both hosted/crawled docs and repository-backed docs. " + "Pass `start_line` / `end_line` to fetch only a slice when a page is too long — response carries `totalLines` so you can target the next slice. " + "Repo-backed results additionally include exact file follow-up metadata for `code_read`.";
|
|
7795
8461
|
function createReadPackageDocTool(service) {
|
|
@@ -7802,8 +8468,14 @@ function createReadPackageDocTool(service) {
|
|
|
7802
8468
|
try {
|
|
7803
8469
|
const build = buildReadPackageDocParams({ pageId: args.page_id });
|
|
7804
8470
|
const result = await service.readPackageDoc(build.params);
|
|
7805
|
-
const
|
|
7806
|
-
const
|
|
8471
|
+
const textMode = isTextFormat10(args.format);
|
|
8472
|
+
const range = buildRange3(args, textMode);
|
|
8473
|
+
const payload = buildReadPackageDocSuccessPayload(result, build.params.pageId, range?.range);
|
|
8474
|
+
if (range?.hint && payload.endLine !== undefined) {
|
|
8475
|
+
payload.hint = range.hint(payload);
|
|
8476
|
+
}
|
|
8477
|
+
if (textMode)
|
|
8478
|
+
return textResult(renderReadPackageDocText(payload));
|
|
7807
8479
|
return textResult(JSON.stringify(payload));
|
|
7808
8480
|
} catch (error2) {
|
|
7809
8481
|
const mapped = mapPackageIntelligenceError(error2);
|
|
@@ -7817,6 +8489,22 @@ function createReadPackageDocTool(service) {
|
|
|
7817
8489
|
}
|
|
7818
8490
|
};
|
|
7819
8491
|
}
|
|
8492
|
+
function isTextFormat10(format) {
|
|
8493
|
+
return format === undefined || format === "text" || format === "text-v1";
|
|
8494
|
+
}
|
|
8495
|
+
function buildRange3(args, textMode) {
|
|
8496
|
+
if (textMode) {
|
|
8497
|
+
const startLine = args.start_line ?? 1;
|
|
8498
|
+
const requestedEnd = args.end_line ?? startLine + MCP_DOC_READ_MAX_SPAN - 1;
|
|
8499
|
+
const endLine = Math.min(requestedEnd, startLine + MCP_DOC_READ_MAX_SPAN - 1);
|
|
8500
|
+
const wasClamped = requestedEnd > endLine;
|
|
8501
|
+
return {
|
|
8502
|
+
range: { startLine, endLine },
|
|
8503
|
+
hint: wasClamped ? (payload) => `Returned lines ${payload.startLine}-${payload.endLine}${payload.totalLines !== undefined ? `/${payload.totalLines}` : ""} (MCP text cap: ${MCP_DOC_READ_MAX_SPAN} lines per call; you requested lines ${startLine}-${requestedEnd}).` : undefined
|
|
8504
|
+
};
|
|
8505
|
+
}
|
|
8506
|
+
return args.start_line !== undefined || args.end_line !== undefined ? { range: { startLine: args.start_line, endLine: args.end_line } } : undefined;
|
|
8507
|
+
}
|
|
7820
8508
|
// src/tools/search.ts
|
|
7821
8509
|
import { z as z13 } from "zod";
|
|
7822
8510
|
var schema12 = {
|
|
@@ -7911,13 +8599,13 @@ function createSearchTool(service) {
|
|
|
7911
8599
|
});
|
|
7912
8600
|
const outcome = await service.search(built.params);
|
|
7913
8601
|
const payload = buildUnifiedSearchSuccessPayload(built.params, built.rawQuery, built.compiledQuery, outcome);
|
|
7914
|
-
if (
|
|
8602
|
+
if (isTextFormat11(args.format)) {
|
|
7915
8603
|
return textResult(renderUnifiedSearchSuccess(payload));
|
|
7916
8604
|
}
|
|
7917
8605
|
return textResult(JSON.stringify(payload));
|
|
7918
8606
|
} catch (error2) {
|
|
7919
8607
|
const payload = buildUnifiedSearchErrorPayload(error2);
|
|
7920
|
-
if (
|
|
8608
|
+
if (isTextFormat11(args.format)) {
|
|
7921
8609
|
return errorResult(renderUnifiedSearchError(payload));
|
|
7922
8610
|
}
|
|
7923
8611
|
return errorResult(JSON.stringify(payload));
|
|
@@ -7928,15 +8616,16 @@ function createSearchTool(service) {
|
|
|
7928
8616
|
function isResolvedCodeTarget(target) {
|
|
7929
8617
|
return !("content" in target);
|
|
7930
8618
|
}
|
|
7931
|
-
function
|
|
8619
|
+
function isTextFormat11(format) {
|
|
7932
8620
|
return format === undefined || format === "text" || format === "text-v1";
|
|
7933
8621
|
}
|
|
7934
8622
|
// src/tools/search-language.ts
|
|
7935
8623
|
import { z as z14 } from "zod";
|
|
7936
8624
|
var schema13 = {
|
|
7937
|
-
query: z14.string().min(1).describe('Language name or partial name to search for (e.g., "python", "type", "java")')
|
|
8625
|
+
query: z14.string().min(1).describe('Language name or partial name to search for (e.g., "python", "type", "java")'),
|
|
8626
|
+
format: z14.enum(["json", "text", "text-v1"]).optional().describe("Response format. Default `text-v1` returns one language per line. Pass `json` for the structured array.")
|
|
7938
8627
|
};
|
|
7939
|
-
var DESCRIPTION13 = `Find the correct language name for \`get_example\` when it is uncertain. Returns up to 5 matching languages by name, display name, or alias.`;
|
|
8628
|
+
var DESCRIPTION13 = `Find the correct language name for \`get_example\` when it is uncertain. Returns up to 5 matching languages by name, display name, or alias. Default output is one language per line; pass \`format: "json"\` for the structured array.`;
|
|
7940
8629
|
function createSearchLanguageTool(service) {
|
|
7941
8630
|
return {
|
|
7942
8631
|
name: "search_language",
|
|
@@ -7946,15 +8635,32 @@ function createSearchLanguageTool(service) {
|
|
|
7946
8635
|
return withErrorHandling("search languages", async () => {
|
|
7947
8636
|
const allLanguages = await service.getLanguages();
|
|
7948
8637
|
const result = filterLanguages(allLanguages, args.query);
|
|
8638
|
+
if (isTextFormat12(args.format)) {
|
|
8639
|
+
return textResult(renderLanguageMatches(result));
|
|
8640
|
+
}
|
|
7949
8641
|
return textResult(JSON.stringify(result));
|
|
7950
8642
|
});
|
|
7951
8643
|
}
|
|
7952
8644
|
};
|
|
7953
8645
|
}
|
|
8646
|
+
function isTextFormat12(format) {
|
|
8647
|
+
return format === undefined || format === "text" || format === "text-v1";
|
|
8648
|
+
}
|
|
8649
|
+
function renderLanguageMatches(matches) {
|
|
8650
|
+
if (matches.length === 0)
|
|
8651
|
+
return "No matching languages.";
|
|
8652
|
+
return matches.map((match) => {
|
|
8653
|
+
const label = match.display_name ? `${match.name} (${match.display_name})` : match.name;
|
|
8654
|
+
const aliases = match.aliases?.length ? ` aliases: ${match.aliases.join(", ")}` : "";
|
|
8655
|
+
return `${label}${aliases}`;
|
|
8656
|
+
}).join(`
|
|
8657
|
+
`);
|
|
8658
|
+
}
|
|
7954
8659
|
// src/tools/search-status.ts
|
|
7955
8660
|
import { z as z15 } from "zod";
|
|
7956
8661
|
var schema14 = {
|
|
7957
|
-
search_ref: z15.string().min(1).describe("Search reference returned by search.")
|
|
8662
|
+
search_ref: z15.string().min(1).describe("Search reference returned by search."),
|
|
8663
|
+
format: z15.enum(["json", "text", "text-v1"]).optional().describe('Response format. Default `text-v1` — compact line-oriented output matching `search`. Pass `format: "json"` for the structured envelope.')
|
|
7958
8664
|
};
|
|
7959
8665
|
var DESCRIPTION14 = "Check progress, fetch partial hits when the original request used allow_partial_results: true, or fetch final results for a prior unified search. " + "Pass the search_ref returned by `search` when the original request did not complete within the wait window.";
|
|
7960
8666
|
function createSearchStatusTool(service) {
|
|
@@ -7967,6 +8673,9 @@ function createSearchStatusTool(service) {
|
|
|
7967
8673
|
try {
|
|
7968
8674
|
const outcome = await service.searchStatus(args.search_ref);
|
|
7969
8675
|
const payload = buildUnifiedSearchStatusPayload(outcome);
|
|
8676
|
+
if (isTextFormat13(args.format)) {
|
|
8677
|
+
return textResult(renderUnifiedSearchStatusText(payload));
|
|
8678
|
+
}
|
|
7970
8679
|
return textResult(JSON.stringify(payload));
|
|
7971
8680
|
} catch (error2) {
|
|
7972
8681
|
return errorResult(JSON.stringify(buildUnifiedSearchErrorPayload(error2)));
|
|
@@ -7974,25 +8683,28 @@ function createSearchStatusTool(service) {
|
|
|
7974
8683
|
}
|
|
7975
8684
|
};
|
|
7976
8685
|
}
|
|
8686
|
+
function isTextFormat13(format) {
|
|
8687
|
+
return format === undefined || format === "text" || format === "text-v1";
|
|
8688
|
+
}
|
|
7977
8689
|
// src/commands/mcp-instructions.ts
|
|
7978
|
-
var CORE_BLOCK = `GitHits provides verified, canonical code examples from global open source. Use it when you're stuck, repeated attempts failed, you need up-to-date API usage, the question is comparative across OSS projects (e.g. "how does X vs Y handle Z"), the answer requires reading how a real codebase implements a feature, or the user mentions GitHits.
|
|
8690
|
+
var CORE_BLOCK = `GitHits provides verified, canonical code examples from global open source. Use it for global solution synthesis and canonical examples when you're stuck, repeated attempts failed, you need up-to-date API usage, the question is comparative across OSS projects (e.g. "how does X vs Y handle Z"), the answer requires reading how a real codebase implements a feature, or the user mentions GitHits.
|
|
7979
8691
|
|
|
7980
|
-
Example workflow: call \`get_example\` with one focused question; pass \`language\` only when you know the exact language name, otherwise call \`search_language\` first.
|
|
8692
|
+
Example workflow: call \`get_example\` with one focused question; pass \`language\` only when you know the exact language name, otherwise call \`search_language\` first. Default output is markdown with a trailing \`solution_id\`; send \`feedback\` on that solution_id. Reuse prior results before searching again. For dependency-specific grounding, use package-scoped \`search\` before global \`get_example\`.`;
|
|
7981
8693
|
var PACKAGE_TOOLS_PREAMBLE = `Indexed package/source tools inspect third-party dependency source, docs, and registry metadata. Use them when a stack trace points into a dependency, you need to verify how a library works, or you're evaluating whether to add or upgrade a package.
|
|
7982
8694
|
|
|
7983
|
-
Package spec: \`registry:name[@version]
|
|
7984
|
-
var PKG_INFO_BULLET =
|
|
8695
|
+
Package spec: \`registry:name[@version]\`. Default outputs are compact \`text-v1\` for agent context efficiency; pass \`format: "json"\` only when you need structured fields for programmatic parsing.`;
|
|
8696
|
+
var PKG_INFO_BULLET = '- `pkg_info` — compact package overview: latest version, license, downloads, quickstart, and active advisory count. Pass `format: "json"` for the structured envelope.';
|
|
7985
8697
|
var DOCS_LIST_BULLET = "- `docs_list` — browse hosted and repository-backed package docs. Entries include stable pageIds, source URLs, and repo-file follow-up metadata when available.";
|
|
7986
8698
|
var DOCS_READ_BULLET = "- `docs_read` — read a documentation page by pageId. Works for both hosted docs and repo-backed docs.";
|
|
7987
|
-
var PKG_VULNS_BULLET =
|
|
7988
|
-
var PKG_DEPS_BULLET =
|
|
7989
|
-
var PKG_CHANGELOG_BULLET =
|
|
7990
|
-
var SEARCH_BULLET = '- `search` — unified search across indexed dependency code, docs, and symbols. Omit `sources` for AUTO. Default output is compact `text-v1
|
|
8699
|
+
var PKG_VULNS_BULLET = '- `pkg_vulns` — compact known CVE / OSV advisory summary for npm, PyPI, Hex, or Crates packages, optionally pinned to `version`. Filter with `min_severity`; include retracted advisories with `include_withdrawn`. Pass `format: "json"` for per-advisory structured fields.';
|
|
8700
|
+
var PKG_DEPS_BULLET = '- `pkg_deps` — compact direct runtime deps by default. Use `lifecycle: "runtime"` for explicit runtime-only, a concrete lifecycle for runtime plus matching non-runtime deps, or `lifecycle: "all"` for all groups. Use `include_transitive` for the full graph and `include_importers` for provenance. Pass `format: "json"` for the structured envelope.';
|
|
8701
|
+
var PKG_CHANGELOG_BULLET = '- `pkg_changelog` — compact release notes for a package or GitHub repo, newest-first. Default latest mode returns recent entries with markdown body previews; `from_version` switches to range mode. Set `include_bodies: false` for a compact timeline or pass `format: "json"` for full bodies.';
|
|
8702
|
+
var SEARCH_BULLET = '- `search` — unified search across indexed dependency code, docs, and symbols. Omit `sources` for AUTO. Use `sources:["code"]` for implementation/examples/tests text, `sources:["symbol"]` for precise API/entity lookup, and `sources:["docs"]` for guides/reference/changelogs. Default output is compact `text-v1` with ready-to-call follow-up arguments; pass `format: "json"` for structured locators, highlights, and source status. Complete by default; opt into partial hits with `allow_partial_results: true`. Incomplete responses carry a `searchRef`.';
|
|
7991
8703
|
var SEARCH_STATUS_BULLET = "- `search_status` — follow up a prior `search` by `searchRef` to check progress, fetch partial hits, or fetch final results.";
|
|
7992
|
-
var CODE_FILES_BULLET = '- `code_files` — list files in an indexed dependency.
|
|
8704
|
+
var CODE_FILES_BULLET = '- `code_files` — list files in an indexed dependency. `path`, `path_prefix`, and `globs` are OR-ed selectors; extensions, language, file type, and file-intent filters intersect on top. Returned paths feed into `code_read` and help scope `code_grep`; pass `format: "json"` for language/type/size metadata.';
|
|
7993
8705
|
var CODE_READ_BULLET = "- `code_read` — read a dependency file by `path`. **MCP cap: 150 lines per call**; choose focused `start_line` / `end_line` windows from `search` or `code_grep`. Binary files set `isBinary: true` and omit `content`. On `FILE_NOT_FOUND` / `NOT_FOUND`, call `code_files` for the actual path.";
|
|
7994
8706
|
var CODE_GREP_BULLET = "- `code_grep` — deterministic text or regex grep over indexed source. Use it when you know the pattern; use `search` for discovery. Narrow with `path`, `path_prefix`, `globs`, or `extensions`. Each match's `path:line` chains into `code_read`.";
|
|
7995
|
-
var SEARCH_VS_SYMBOLS_TIP = '
|
|
8707
|
+
var SEARCH_VS_SYMBOLS_TIP = 'Use code-first grounding for behavioral claims: source, symbols, tests, examples, and call sites beat docs prose. Prefer unified `search` for indexed dependency and repository discovery; use `sources:["symbol"]` when you want symbol-shaped results. Prefer `get_example` for global canonical example retrieval after package-scoped grounding. Use `code_grep` for deterministic text matching and `code_read` for focused-window inspection of a known file.';
|
|
7996
8708
|
var REFERENCE_FIRST_TIP = "Strategy — reference-first, content-second. Locate symbols and lines with `search` / `code_grep` first, then read only the needed window with `code_read` using explicit `start_line` / `end_line` values, typically 80-150 lines around the match. The MCP `code_read` surface caps each call at 150 lines.";
|
|
7997
8709
|
var MULTI_TURN_TIP = '**Delegate multi-call work to a sub-agent.** Code-navigation work (`search`, `code_grep`, `code_read`, `code_files`) often takes 3-10 calls. For cross-project comparisons, codebase mapping, pattern surveys, or "how does X actually work" investigations, spawn a sub-task/sub-agent and ask for a compact synthesis. Do it inline only when the raw snippet belongs in the main conversation.';
|
|
7998
8710
|
function buildMcpInstructions(_deps) {
|
|
@@ -8283,12 +8995,12 @@ async function pkgDepsAction(spec, options, deps) {
|
|
|
8283
8995
|
console.log(JSON.stringify(payload));
|
|
8284
8996
|
return;
|
|
8285
8997
|
}
|
|
8286
|
-
const showGroups = (
|
|
8998
|
+
const showGroups = canonicalLifecycles.some((entry) => entry !== "runtime");
|
|
8287
8999
|
const output = formatPackageDependenciesTerminal(report, {
|
|
8288
9000
|
verbose: options.verbose,
|
|
8289
9001
|
useColors: shouldUseColors(),
|
|
8290
9002
|
requestedVersion: parsed.version,
|
|
8291
|
-
canonicalLifecycles,
|
|
9003
|
+
canonicalLifecycles: canonicalLifecycles.length > 0 ? canonicalLifecycles : undefined,
|
|
8292
9004
|
includeTransitive: options.transitive,
|
|
8293
9005
|
maxDepth: userDepth,
|
|
8294
9006
|
showGroups
|
|
@@ -8350,9 +9062,9 @@ function formatDepsTerminalError(mapped) {
|
|
|
8350
9062
|
`);
|
|
8351
9063
|
}
|
|
8352
9064
|
var PKG_DEPS_DESCRIPTION = `Analyze package dependencies. By default shows the flat list of
|
|
8353
|
-
direct runtime dependencies. Use --
|
|
9065
|
+
direct runtime dependencies. Use --lifecycle all for the structured view
|
|
8354
9066
|
(dev / peer / build / optional, plus registry-specific feature / TFM
|
|
8355
|
-
groups). --lifecycle
|
|
9067
|
+
groups). Concrete --lifecycle values include runtime plus matching groups.
|
|
8356
9068
|
--transitive opts into aggregate edge / unique-package counts,
|
|
8357
9069
|
conflict detection, and circular-dependency flags.
|
|
8358
9070
|
|
|
@@ -8360,7 +9072,7 @@ Package spec: <registry>:<name>[@<version>]. Supported registries:
|
|
|
8360
9072
|
npm, pypi, hex, crates, vcpkg, zig. Omit @<version> for the latest
|
|
8361
9073
|
release.`;
|
|
8362
9074
|
function registerPkgDepsCommand(pkgCommand) {
|
|
8363
|
-
return pkgCommand.command("deps").summary("Analyze dependencies for a package").description(PKG_DEPS_DESCRIPTION).argument("<spec>", "Package spec, e.g. npm:express or npm:express@4.18.0").option("-
|
|
9075
|
+
return pkgCommand.command("deps").summary("Analyze dependencies for a package").description(PKG_DEPS_DESCRIPTION).argument("<spec>", "Package spec, e.g. npm:express or npm:express@4.18.0").option("-l, --lifecycle <phases>", "Dependency lifecycle breadth (runtime, development, build, peer, optional, all; comma-separated for multi-select except all).").option("-t, --transitive", "Include aggregate transitive counts, conflicts, and circular dependencies").option("--depth <n>", "Cap transitive traversal depth (1-10). Omit for the full graph.").option("-v, --verbose", "Show conditionType / selectionMode / environmentConstraints metadata in the groups view").option("--json", "Emit the lean JSON envelope").action(async (spec, options) => {
|
|
8364
9076
|
const deps = await createContainer();
|
|
8365
9077
|
await pkgDepsAction(spec, options, {
|
|
8366
9078
|
packageIntelligenceService: deps.packageIntelligenceService,
|
|
@@ -8629,7 +9341,7 @@ Pass the searchRef returned by githits search when the initial request could
|
|
|
8629
9341
|
not complete within the wait window. This can return progress, partial hits when
|
|
8630
9342
|
the original request used --allow-partial, or final results.`;
|
|
8631
9343
|
function registerSearchCommand(program) {
|
|
8632
|
-
program.command("search").summary("Search indexed dependency and repository code, docs, and symbols").description(SEARCH_DESCRIPTION).argument("<query>", "Search query").requiredOption("--in <target>", "Search target: registry:name[@version] or https://github.com/org/repo[#ref]",
|
|
9344
|
+
program.command("search").summary("Search indexed dependency and repository code, docs, and symbols").description(SEARCH_DESCRIPTION).argument("<query>", "Search query").requiredOption("--in <target>", "Search target: registry:name[@version] or https://github.com/org/repo[#ref]", collectRepeatable3, []).addOption(new Option3("--source <source>", "Source to search (repeatable; default: auto)").choices(["docs", "code", "symbol"]).argParser((value, previous = []) => collectRepeatable3(value.toLowerCase(), previous)).default(undefined)).addOption(new Option3("--kind <kind>", "Precise symbol kind filter").choices([
|
|
8633
9345
|
...knownSymbolKindList()
|
|
8634
9346
|
])).addOption(new Option3("--category <category>", "Broad symbol category filter").choices([...knownSymbolCategoryList()])).option("--path-prefix <prefix>", "Repository path prefix filter").addOption(new Option3("--intent <intent>", "File intent filter (omit to search across all intents)").choices([
|
|
8635
9347
|
"production",
|
|
@@ -8663,7 +9375,7 @@ function requireSearchService(deps) {
|
|
|
8663
9375
|
return deps.codeNavigationService;
|
|
8664
9376
|
}
|
|
8665
9377
|
async function loadContainer2() {
|
|
8666
|
-
const { createContainer: createContainer2 } = await import("./shared/chunk-
|
|
9378
|
+
const { createContainer: createContainer2 } = await import("./shared/chunk-rwcs5gyy.js");
|
|
8667
9379
|
return createContainer2();
|
|
8668
9380
|
}
|
|
8669
9381
|
function parseTargetSpecs(specs) {
|
|
@@ -8720,7 +9432,7 @@ function parseWaitMs(value) {
|
|
|
8720
9432
|
}
|
|
8721
9433
|
return seconds * 1000;
|
|
8722
9434
|
}
|
|
8723
|
-
function
|
|
9435
|
+
function collectRepeatable3(value, previous) {
|
|
8724
9436
|
return [...previous, value];
|
|
8725
9437
|
}
|
|
8726
9438
|
function handleSearchError(error2, json, context = "search") {
|
|
@@ -9072,15 +9784,10 @@ registerAuthStatusCommand(authCommand);
|
|
|
9072
9784
|
try {
|
|
9073
9785
|
await runWithUpdateCheckFlush(() => withTelemetrySpan("cli.parse", () => program.parseAsync()), updateCheckTask, { stderr: process.stderr, requiredUpdateRefreshTask });
|
|
9074
9786
|
} catch (error2) {
|
|
9075
|
-
|
|
9076
|
-
|
|
9077
|
-
|
|
9078
|
-
|
|
9079
|
-
}
|
|
9080
|
-
throw error2;
|
|
9081
|
-
}
|
|
9082
|
-
function isUserFacingError(error2) {
|
|
9083
|
-
return error2 instanceof AuthConfigError || error2 instanceof AuthStoragePolicyError;
|
|
9787
|
+
handleCliError(error2, {
|
|
9788
|
+
stderr: process.stderr,
|
|
9789
|
+
exit: process.exit
|
|
9790
|
+
});
|
|
9084
9791
|
}
|
|
9085
9792
|
function stripRootRegistrationOptions(args) {
|
|
9086
9793
|
return args.filter((arg) => arg !== "--no-color");
|