githits 0.3.1 → 0.3.3
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 +1026 -184
- package/dist/index.js +1 -1
- package/dist/shared/{chunk-0s7mxdt3.js → chunk-2d202fpq.js} +237 -49
- package/dist/shared/{chunk-zg5dnven.js → chunk-b6avnx6d.js} +2 -2
- package/dist/shared/{chunk-m1xx8hzw.js → chunk-tze0rsay.js} +1 -1
- package/gemini-extension.json +1 -1
- package/package.json +3 -1
- package/plugins/claude/.claude-plugin/plugin.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -49,11 +49,11 @@ import {
|
|
|
49
49
|
shouldRunUpdateCheck,
|
|
50
50
|
startTelemetrySpan,
|
|
51
51
|
withTelemetrySpan
|
|
52
|
-
} from "./shared/chunk-
|
|
52
|
+
} from "./shared/chunk-2d202fpq.js";
|
|
53
53
|
import {
|
|
54
54
|
__require,
|
|
55
55
|
version
|
|
56
|
-
} from "./shared/chunk-
|
|
56
|
+
} from "./shared/chunk-tze0rsay.js";
|
|
57
57
|
|
|
58
58
|
// src/cli.ts
|
|
59
59
|
import { Command } from "commander";
|
|
@@ -485,6 +485,12 @@ function knownSymbolCategoryList() {
|
|
|
485
485
|
function toFileIntent(intent) {
|
|
486
486
|
return intent ? fileIntentMap[intent] : undefined;
|
|
487
487
|
}
|
|
488
|
+
function isKnownFileIntent(value) {
|
|
489
|
+
return value in fileIntentMap;
|
|
490
|
+
}
|
|
491
|
+
function knownFileIntentList() {
|
|
492
|
+
return Object.keys(fileIntentMap);
|
|
493
|
+
}
|
|
488
494
|
// src/shared/code-navigation-error-map.ts
|
|
489
495
|
function mapCodeNavigationError(error2) {
|
|
490
496
|
const mapped = classify(error2);
|
|
@@ -664,23 +670,6 @@ function isInvalidArgumentError(error2) {
|
|
|
664
670
|
return false;
|
|
665
671
|
return error2.name.startsWith("Invalid") || error2.name.startsWith("Unsupported");
|
|
666
672
|
}
|
|
667
|
-
// src/shared/docs-follow-up.ts
|
|
668
|
-
function lowerDocSourceKind(value) {
|
|
669
|
-
switch (value) {
|
|
670
|
-
case "CRAWLED":
|
|
671
|
-
return "crawled";
|
|
672
|
-
case "REPOSITORY":
|
|
673
|
-
return "repo";
|
|
674
|
-
default:
|
|
675
|
-
return;
|
|
676
|
-
}
|
|
677
|
-
}
|
|
678
|
-
// src/shared/extract-solution-id.ts
|
|
679
|
-
var SOLUTION_URL_RE = /solutions\/([0-9a-fA-F-]{36})/;
|
|
680
|
-
function extractSolutionId(markdown) {
|
|
681
|
-
const match = SOLUTION_URL_RE.exec(markdown);
|
|
682
|
-
return match?.[1];
|
|
683
|
-
}
|
|
684
673
|
// src/shared/package-spec.ts
|
|
685
674
|
var KNOWN_REGISTRIES = [
|
|
686
675
|
"npm",
|
|
@@ -755,6 +744,112 @@ function isKnownRegistry(value) {
|
|
|
755
744
|
return KNOWN_REGISTRIES.includes(value);
|
|
756
745
|
}
|
|
757
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
|
+
}
|
|
758
853
|
// src/shared/grep-repo-request.ts
|
|
759
854
|
var PATTERN_MAX = 200;
|
|
760
855
|
var CONTEXT_MIN = 0;
|
|
@@ -1372,7 +1467,7 @@ function buildHeader(envelope) {
|
|
|
1372
1467
|
const parts = [
|
|
1373
1468
|
`code_grep${SEP}${envelope.totalMatches} match${envelope.totalMatches === 1 ? "" : "es"} in ${envelope.uniqueFilesMatched} file${envelope.uniqueFilesMatched === 1 ? "" : "s"}`
|
|
1374
1469
|
];
|
|
1375
|
-
parts.push(`pattern=${
|
|
1470
|
+
parts.push(`pattern=${quote2(envelope.pattern)}`);
|
|
1376
1471
|
const flags = [];
|
|
1377
1472
|
if (envelope.patternType === "regex")
|
|
1378
1473
|
flags.push("regex");
|
|
@@ -1391,9 +1486,9 @@ function buildFilterEcho(envelope) {
|
|
|
1391
1486
|
return "";
|
|
1392
1487
|
const parts = [];
|
|
1393
1488
|
if (filter.path)
|
|
1394
|
-
parts.push(`path=${
|
|
1489
|
+
parts.push(`path=${quote2(filter.path)}`);
|
|
1395
1490
|
if (filter.pathPrefix)
|
|
1396
|
-
parts.push(`path_prefix=${
|
|
1491
|
+
parts.push(`path_prefix=${quote2(filter.pathPrefix)}`);
|
|
1397
1492
|
if (filter.globs?.length)
|
|
1398
1493
|
parts.push(`globs=${filter.globs.join(",")}`);
|
|
1399
1494
|
if (filter.extensions?.length) {
|
|
@@ -1526,14 +1621,18 @@ function renderLine(line, gutterWidth, useContext) {
|
|
|
1526
1621
|
const sep = !useContext || line.isMatch ? ":" : "-";
|
|
1527
1622
|
return ` ${gutter}${sep} ${line.content}`;
|
|
1528
1623
|
}
|
|
1529
|
-
function
|
|
1624
|
+
function quote2(value) {
|
|
1530
1625
|
return value.includes('"') ? `'${value}'` : `"${value}"`;
|
|
1531
1626
|
}
|
|
1532
1627
|
// src/shared/language-filter.ts
|
|
1533
1628
|
var DEFAULT_LIMIT = 5;
|
|
1534
1629
|
function filterLanguages(languages, query, limit = DEFAULT_LIMIT) {
|
|
1535
1630
|
const lowerQuery = query.toLowerCase();
|
|
1536
|
-
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
|
+
}));
|
|
1537
1636
|
}
|
|
1538
1637
|
// src/shared/list-files-text.ts
|
|
1539
1638
|
var SEP2 = " | ";
|
|
@@ -1551,7 +1650,7 @@ function renderListFilesText(envelope) {
|
|
|
1551
1650
|
}
|
|
1552
1651
|
if (envelope.hasMore) {
|
|
1553
1652
|
lines.push("");
|
|
1554
|
-
lines.push("More files available. Pass limit=N
|
|
1653
|
+
lines.push("More files available. Pass limit=N or refine the filter.");
|
|
1555
1654
|
}
|
|
1556
1655
|
if (envelope.hint) {
|
|
1557
1656
|
lines.push("");
|
|
@@ -1585,15 +1684,48 @@ function buildIdentity(envelope) {
|
|
|
1585
1684
|
}
|
|
1586
1685
|
function buildFilterEcho2(envelope) {
|
|
1587
1686
|
const parts = [];
|
|
1687
|
+
if (envelope.filter?.path) {
|
|
1688
|
+
parts.push(`path=${quote3(envelope.filter.path)}`);
|
|
1689
|
+
}
|
|
1588
1690
|
if (envelope.filter?.pathPrefix) {
|
|
1589
|
-
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)}`);
|
|
1590
1722
|
}
|
|
1591
1723
|
if (envelope.filter?.limit !== undefined) {
|
|
1592
1724
|
parts.push(`limit=${envelope.filter.limit}`);
|
|
1593
1725
|
}
|
|
1594
1726
|
return parts.join(" ");
|
|
1595
1727
|
}
|
|
1596
|
-
function
|
|
1728
|
+
function quote3(value) {
|
|
1597
1729
|
return value.includes('"') ? `'${value}'` : `"${value}"`;
|
|
1598
1730
|
}
|
|
1599
1731
|
// src/shared/list-package-docs-request.ts
|
|
@@ -1693,8 +1825,6 @@ function buildListPackageDocsSuccessPayload(result, options) {
|
|
|
1693
1825
|
entry.requestedRef = page.requestedRef;
|
|
1694
1826
|
if (page.filePath)
|
|
1695
1827
|
entry.filePath = page.filePath;
|
|
1696
|
-
if (page.linkName)
|
|
1697
|
-
entry.linkName = page.linkName;
|
|
1698
1828
|
if (lastUpdatedAt)
|
|
1699
1829
|
entry.lastUpdatedAt = lastUpdatedAt;
|
|
1700
1830
|
return entry;
|
|
@@ -1782,6 +1912,51 @@ function formatPageMeta(page, useColors, verbose) {
|
|
|
1782
1912
|
}
|
|
1783
1913
|
return lines;
|
|
1784
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
|
+
}
|
|
1785
1960
|
// src/shared/package-dependencies-request.ts
|
|
1786
1961
|
class UnsupportedDependenciesRegistryError extends Error {
|
|
1787
1962
|
constructor(message) {
|
|
@@ -1830,6 +2005,7 @@ function buildPackageDependenciesParams(input) {
|
|
|
1830
2005
|
}
|
|
1831
2006
|
const version2 = normaliseVersion(input.version);
|
|
1832
2007
|
const canonicalLifecycles = resolveLifecycles(input.lifecycle);
|
|
2008
|
+
const wireLifecycles = canonicalLifecycles.filter((entry) => entry !== "runtime" && entry !== "all");
|
|
1833
2009
|
const maxDepth = input.maxDepth;
|
|
1834
2010
|
if (maxDepth !== undefined) {
|
|
1835
2011
|
if (!Number.isInteger(maxDepth) || maxDepth < 1 || maxDepth > 10) {
|
|
@@ -1838,13 +2014,14 @@ function buildPackageDependenciesParams(input) {
|
|
|
1838
2014
|
}
|
|
1839
2015
|
return {
|
|
1840
2016
|
canonicalLifecycles,
|
|
2017
|
+
wireLifecycles,
|
|
1841
2018
|
params: {
|
|
1842
2019
|
registry,
|
|
1843
2020
|
packageName: trimmedName,
|
|
1844
2021
|
version: version2,
|
|
1845
2022
|
includeTransitive: input.includeTransitive,
|
|
1846
2023
|
maxDepth,
|
|
1847
|
-
lifecycle:
|
|
2024
|
+
lifecycle: wireLifecycles.length > 0 ? wireLifecycles : undefined
|
|
1848
2025
|
}
|
|
1849
2026
|
};
|
|
1850
2027
|
}
|
|
@@ -1869,16 +2046,29 @@ function resolveLifecycles(raw) {
|
|
|
1869
2046
|
if (trimmed.length === 0)
|
|
1870
2047
|
continue;
|
|
1871
2048
|
const lower = trimmed.toLowerCase();
|
|
1872
|
-
if (!
|
|
1873
|
-
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.`);
|
|
1874
2051
|
}
|
|
1875
2052
|
seen.add(lower);
|
|
1876
2053
|
}
|
|
1877
|
-
|
|
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);
|
|
1878
2058
|
}
|
|
1879
2059
|
function isLifecycle(value) {
|
|
1880
2060
|
return LIFECYCLES.includes(value);
|
|
1881
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
|
+
}
|
|
1882
2072
|
// src/shared/package-dependencies-response.ts
|
|
1883
2073
|
function buildPackageDependenciesSuccessPayload(report, options = {}) {
|
|
1884
2074
|
const pkg = report.package;
|
|
@@ -1900,10 +2090,16 @@ function buildPackageDependenciesSuccessPayload(report, options = {}) {
|
|
|
1900
2090
|
payload.runtime = { count: items.length, items };
|
|
1901
2091
|
}
|
|
1902
2092
|
const groupsInfo = report.dependencyGroups;
|
|
1903
|
-
if (groupsInfo !== undefined) {
|
|
1904
|
-
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
|
+
}));
|
|
1905
2101
|
const groupsBlock = { items: groupItems };
|
|
1906
|
-
if (groupsInfo.primaryGroup) {
|
|
2102
|
+
if (groupsInfo.primaryGroup && groupItems.some((group) => group.name === groupsInfo.primaryGroup)) {
|
|
1907
2103
|
groupsBlock.primaryGroup = groupsInfo.primaryGroup;
|
|
1908
2104
|
}
|
|
1909
2105
|
if (groupsInfo.environmentMarkers && groupsInfo.environmentMarkers.length > 0) {
|
|
@@ -1945,6 +2141,11 @@ function buildPackageDependenciesSuccessPayload(report, options = {}) {
|
|
|
1945
2141
|
}
|
|
1946
2142
|
return payload;
|
|
1947
2143
|
}
|
|
2144
|
+
function shouldEmitGroups(lifecycles) {
|
|
2145
|
+
if (!lifecycles || lifecycles.length === 0)
|
|
2146
|
+
return false;
|
|
2147
|
+
return lifecycles.some((entry) => entry !== "runtime");
|
|
2148
|
+
}
|
|
1948
2149
|
function projectEnvironmentMarker(marker) {
|
|
1949
2150
|
const out = {};
|
|
1950
2151
|
if (marker.type !== undefined)
|
|
@@ -2163,7 +2364,7 @@ function formatPackageDependenciesTerminal(report, options = {}) {
|
|
|
2163
2364
|
const verbose = options.verbose ?? false;
|
|
2164
2365
|
const payload = buildPackageDependenciesSuccessPayload(report, {
|
|
2165
2366
|
requestedVersion: options.requestedVersion,
|
|
2166
|
-
canonicalLifecycles: options.canonicalLifecycles,
|
|
2367
|
+
canonicalLifecycles: options.canonicalLifecycles ?? ["all"],
|
|
2167
2368
|
includeTransitive: options.includeTransitive,
|
|
2168
2369
|
maxDepth: options.maxDepth,
|
|
2169
2370
|
includeImporters: verbose
|
|
@@ -2172,7 +2373,7 @@ function formatPackageDependenciesTerminal(report, options = {}) {
|
|
|
2172
2373
|
const showGroups = options.showGroups ?? false;
|
|
2173
2374
|
const includeTransitive = options.includeTransitive ?? false;
|
|
2174
2375
|
const blocks = [];
|
|
2175
|
-
blocks.push(formatHeaderBlock(payload, useColors, showGroups));
|
|
2376
|
+
blocks.push(formatHeaderBlock(payload, useColors, showGroups, options));
|
|
2176
2377
|
if (includeTransitive) {
|
|
2177
2378
|
blocks.push(formatTransitiveDepsList(payload, verbose, useColors));
|
|
2178
2379
|
const issues = formatConflictsAndCycles(payload, verbose, useColors);
|
|
@@ -2189,7 +2390,7 @@ function formatPackageDependenciesTerminal(report, options = {}) {
|
|
|
2189
2390
|
`)}
|
|
2190
2391
|
`;
|
|
2191
2392
|
}
|
|
2192
|
-
function formatHeaderBlock(payload, useColors, showGroups) {
|
|
2393
|
+
function formatHeaderBlock(payload, useColors, showGroups, options) {
|
|
2193
2394
|
const name = colorize(payload.name, "bold", useColors);
|
|
2194
2395
|
const lines = [
|
|
2195
2396
|
`${name} @ ${payload.version} · ${payload.registry}`
|
|
@@ -2197,11 +2398,11 @@ function formatHeaderBlock(payload, useColors, showGroups) {
|
|
|
2197
2398
|
if (payload.requestedVersion) {
|
|
2198
2399
|
lines.push(dim(`(requested ${payload.requestedVersion})`, useColors));
|
|
2199
2400
|
}
|
|
2200
|
-
lines.push(formatSummaryRow(payload, useColors, showGroups));
|
|
2401
|
+
lines.push(formatSummaryRow(payload, useColors, showGroups, options));
|
|
2201
2402
|
return lines.join(`
|
|
2202
2403
|
`);
|
|
2203
2404
|
}
|
|
2204
|
-
function formatSummaryRow(payload, useColors, showGroups) {
|
|
2405
|
+
function formatSummaryRow(payload, useColors, showGroups, options) {
|
|
2205
2406
|
const countParts = [];
|
|
2206
2407
|
const runtimeCount = payload.runtime?.count ?? 0;
|
|
2207
2408
|
if (runtimeCount === 0) {
|
|
@@ -2238,7 +2439,7 @@ function formatSummaryRow(payload, useColors, showGroups) {
|
|
|
2238
2439
|
const hidden = collectHiddenGroupNames(payload);
|
|
2239
2440
|
if (hidden.length === 0)
|
|
2240
2441
|
return countLine;
|
|
2241
|
-
const hiddenLine = dim(`Hidden groups: ${hidden.join(", ")} — use --
|
|
2442
|
+
const hiddenLine = dim(`Hidden groups: ${hidden.join(", ")} — ${options.hiddenGroupsHint ?? "use --lifecycle all."}`, useColors);
|
|
2242
2443
|
return `${countLine}
|
|
2243
2444
|
${hiddenLine}`;
|
|
2244
2445
|
}
|
|
@@ -3735,6 +3936,55 @@ function requirePositiveInteger(raw, label) {
|
|
|
3735
3936
|
}
|
|
3736
3937
|
return parsed;
|
|
3737
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
|
+
}
|
|
3738
3988
|
// src/shared/read-package-doc-request.ts
|
|
3739
3989
|
function buildReadPackageDocParams(input) {
|
|
3740
3990
|
const pageId = input.pageId?.trim() ?? "";
|
|
@@ -3778,8 +4028,6 @@ function buildReadPackageDocSuccessPayload(result, requestedPageId, range) {
|
|
|
3778
4028
|
if (result.page?.breadcrumbs && result.page.breadcrumbs.length > 0) {
|
|
3779
4029
|
envelope.breadcrumbs = result.page.breadcrumbs;
|
|
3780
4030
|
}
|
|
3781
|
-
if (result.page?.linkName)
|
|
3782
|
-
envelope.linkName = result.page.linkName;
|
|
3783
4031
|
if (result.page?.lastUpdatedAt) {
|
|
3784
4032
|
envelope.lastUpdatedAt = toIsoDate(result.page.lastUpdatedAt) ?? undefined;
|
|
3785
4033
|
}
|
|
@@ -3828,7 +4076,7 @@ function formatReadPackageDocTerminal(envelope, options) {
|
|
|
3828
4076
|
return envelope.content ?? "";
|
|
3829
4077
|
}
|
|
3830
4078
|
const lines = [];
|
|
3831
|
-
lines.push(
|
|
4079
|
+
lines.push(buildHeader5(envelope, options.useColors));
|
|
3832
4080
|
lines.push(`pageId: ${envelope.pageId}`);
|
|
3833
4081
|
if (envelope.sourceUrl)
|
|
3834
4082
|
lines.push(`source: ${envelope.sourceUrl}`);
|
|
@@ -3848,12 +4096,171 @@ function formatReadPackageDocTerminal(envelope, options) {
|
|
|
3848
4096
|
`)}
|
|
3849
4097
|
`;
|
|
3850
4098
|
}
|
|
3851
|
-
function
|
|
4099
|
+
function buildHeader5(envelope, useColors) {
|
|
3852
4100
|
const badge = envelope.sourceKind === "repo" ? "[repo]" : "[crawled]";
|
|
3853
4101
|
const title = envelope.title ?? envelope.pageId;
|
|
3854
4102
|
const prefix = envelope.registry && envelope.name ? `${envelope.registry}:${envelope.name}${envelope.version ? `@${envelope.version}` : ""}` : "documentation";
|
|
3855
4103
|
return `${colorize(`${prefix} ${badge}`, "bold", useColors)}${title ? ` - ${title}` : ""}`;
|
|
3856
4104
|
}
|
|
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}` : ""}`);
|
|
4115
|
+
}
|
|
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}`);
|
|
4122
|
+
}
|
|
4123
|
+
return lines.join(`
|
|
4124
|
+
`);
|
|
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;
|
|
4142
|
+
}
|
|
4143
|
+
// src/shared/auto-login.ts
|
|
4144
|
+
var AUTO_LOGIN_ELIGIBLE_COMMANDS = new Set([
|
|
4145
|
+
"init",
|
|
4146
|
+
"example",
|
|
4147
|
+
"languages",
|
|
4148
|
+
"feedback",
|
|
4149
|
+
"search",
|
|
4150
|
+
"search-status",
|
|
4151
|
+
"code files",
|
|
4152
|
+
"code read",
|
|
4153
|
+
"code grep",
|
|
4154
|
+
"docs list",
|
|
4155
|
+
"docs read",
|
|
4156
|
+
"pkg info",
|
|
4157
|
+
"pkg vulns",
|
|
4158
|
+
"pkg deps",
|
|
4159
|
+
"pkg changelog"
|
|
4160
|
+
]);
|
|
4161
|
+
function getCommandPath(command) {
|
|
4162
|
+
const names = [];
|
|
4163
|
+
let current = command;
|
|
4164
|
+
while (current) {
|
|
4165
|
+
const name = current.name();
|
|
4166
|
+
if (name && name !== "githits") {
|
|
4167
|
+
names.unshift(name);
|
|
4168
|
+
}
|
|
4169
|
+
current = current.parent ?? null;
|
|
4170
|
+
}
|
|
4171
|
+
return names;
|
|
4172
|
+
}
|
|
4173
|
+
function isAutoLoginEligibleCommand(command, runtime = {
|
|
4174
|
+
stdinIsTTY: Boolean(process.stdin.isTTY),
|
|
4175
|
+
stdoutIsTTY: Boolean(process.stdout.isTTY)
|
|
4176
|
+
}) {
|
|
4177
|
+
const commandPath = getCommandPath(command).join(" ");
|
|
4178
|
+
if (commandPath === "init" && command.opts().skipLogin === true) {
|
|
4179
|
+
return false;
|
|
4180
|
+
}
|
|
4181
|
+
if (!AUTO_LOGIN_ELIGIBLE_COMMANDS.has(commandPath)) {
|
|
4182
|
+
return false;
|
|
4183
|
+
}
|
|
4184
|
+
if (!runtime.stdinIsTTY || !runtime.stdoutIsTTY) {
|
|
4185
|
+
return false;
|
|
4186
|
+
}
|
|
4187
|
+
return true;
|
|
4188
|
+
}
|
|
4189
|
+
async function maybeAutoLoginBeforeCommand(command, deps) {
|
|
4190
|
+
if (!isAutoLoginEligibleCommand(command, {
|
|
4191
|
+
stdinIsTTY: deps.stdinIsTTY ?? Boolean(process.stdin.isTTY),
|
|
4192
|
+
stdoutIsTTY: deps.stdoutIsTTY ?? Boolean(process.stdout.isTTY)
|
|
4193
|
+
})) {
|
|
4194
|
+
return { status: "skipped" };
|
|
4195
|
+
}
|
|
4196
|
+
const container = await deps.createContainer();
|
|
4197
|
+
if (container.hasValidToken) {
|
|
4198
|
+
return { status: "already-authenticated" };
|
|
4199
|
+
}
|
|
4200
|
+
const result = await deps.loginFlow({}, container);
|
|
4201
|
+
switch (result.status) {
|
|
4202
|
+
case "success":
|
|
4203
|
+
return { status: "authenticated", message: result.message };
|
|
4204
|
+
case "already_authenticated":
|
|
4205
|
+
return { status: "already-authenticated", message: result.message };
|
|
4206
|
+
case "failed":
|
|
4207
|
+
return { status: "failed", message: result.message };
|
|
4208
|
+
}
|
|
4209
|
+
}
|
|
4210
|
+
|
|
4211
|
+
// src/shared/root-cli-pre-action.ts
|
|
4212
|
+
function createRootCliPreAction(deps) {
|
|
4213
|
+
return async (thisCommand, actionCommand) => {
|
|
4214
|
+
if (thisCommand.opts().color === false) {
|
|
4215
|
+
process.env.NO_COLOR = "1";
|
|
4216
|
+
}
|
|
4217
|
+
const command = actionCommand ?? thisCommand;
|
|
4218
|
+
const authResult = await maybeAutoLoginBeforeCommand(command, {
|
|
4219
|
+
...deps,
|
|
4220
|
+
stdinIsTTY: deps.stdinIsTTY,
|
|
4221
|
+
stdoutIsTTY: deps.stdoutIsTTY
|
|
4222
|
+
});
|
|
4223
|
+
if (authResult.status === "authenticated") {
|
|
4224
|
+
const continuationMessage = getPostLoginContinuationMessage(command);
|
|
4225
|
+
if (continuationMessage) {
|
|
4226
|
+
console.error(continuationMessage);
|
|
4227
|
+
}
|
|
4228
|
+
}
|
|
4229
|
+
if (authResult.status !== "failed") {
|
|
4230
|
+
return;
|
|
4231
|
+
}
|
|
4232
|
+
console.error(`${authResult.message}
|
|
4233
|
+
`);
|
|
4234
|
+
console.error("Run `githits login` to try again.");
|
|
4235
|
+
(deps.exit ?? process.exit)(1);
|
|
4236
|
+
};
|
|
4237
|
+
}
|
|
4238
|
+
function getPostLoginContinuationMessage(command) {
|
|
4239
|
+
switch (getCommandPath(command).join(" ")) {
|
|
4240
|
+
case "init":
|
|
4241
|
+
return "Authentication complete. Continuing setup...";
|
|
4242
|
+
case "example":
|
|
4243
|
+
return "Authentication complete. Running example search...";
|
|
4244
|
+
case "languages":
|
|
4245
|
+
return "Authentication complete. Loading supported languages...";
|
|
4246
|
+
case "feedback":
|
|
4247
|
+
return "Authentication complete. Submitting feedback...";
|
|
4248
|
+
case "search":
|
|
4249
|
+
case "search-status":
|
|
4250
|
+
case "code files":
|
|
4251
|
+
case "code read":
|
|
4252
|
+
case "code grep":
|
|
4253
|
+
case "docs list":
|
|
4254
|
+
case "docs read":
|
|
4255
|
+
case "pkg info":
|
|
4256
|
+
case "pkg vulns":
|
|
4257
|
+
case "pkg deps":
|
|
4258
|
+
case "pkg changelog":
|
|
4259
|
+
return "Authentication complete. Running command...";
|
|
4260
|
+
default:
|
|
4261
|
+
return;
|
|
4262
|
+
}
|
|
4263
|
+
}
|
|
3857
4264
|
// src/shared/unified-search-request.ts
|
|
3858
4265
|
var DEFAULT_UNIFIED_SEARCH_LIMIT = 10;
|
|
3859
4266
|
function buildUnifiedSearchParams(input) {
|
|
@@ -4128,8 +4535,6 @@ function buildHitPayload(hit) {
|
|
|
4128
4535
|
payload.title = hit.title;
|
|
4129
4536
|
if (hit.summary)
|
|
4130
4537
|
payload.summary = hit.summary;
|
|
4131
|
-
if (typeof hit.score === "number")
|
|
4132
|
-
payload.score = hit.score;
|
|
4133
4538
|
const highlights = buildHighlights(hit.highlights);
|
|
4134
4539
|
if (highlights)
|
|
4135
4540
|
payload.highlights = highlights;
|
|
@@ -4296,49 +4701,17 @@ function assertSearchFollowUpInvariant(hit) {
|
|
|
4296
4701
|
throw new MalformedCodeNavigationResponseError("REPOSITORY_DOC search hit missing repo locator fields.");
|
|
4297
4702
|
}
|
|
4298
4703
|
}
|
|
4299
|
-
// src/shared/unified-search-target.ts
|
|
4300
|
-
function parseUnifiedSearchTargetSpec(spec) {
|
|
4301
|
-
const trimmed = spec.trim();
|
|
4302
|
-
if (trimmed.length === 0) {
|
|
4303
|
-
throw new InvalidArgumentError("Target spec cannot be empty.");
|
|
4304
|
-
}
|
|
4305
|
-
if (trimmed.startsWith("http://") || trimmed.startsWith("https://")) {
|
|
4306
|
-
return parseRepoTarget(trimmed);
|
|
4307
|
-
}
|
|
4308
|
-
const parsed = parsePackageSpec(trimmed);
|
|
4309
|
-
return {
|
|
4310
|
-
registry: toCodeNavigationRegistry(parsed.registry),
|
|
4311
|
-
packageName: parsed.name,
|
|
4312
|
-
version: parsed.version
|
|
4313
|
-
};
|
|
4314
|
-
}
|
|
4315
|
-
function parseRepoTarget(spec) {
|
|
4316
|
-
const hashIndex = spec.lastIndexOf("#");
|
|
4317
|
-
if (hashIndex === -1) {
|
|
4318
|
-
return { repoUrl: spec, gitRef: "HEAD" };
|
|
4319
|
-
}
|
|
4320
|
-
const repoUrl = spec.slice(0, hashIndex);
|
|
4321
|
-
const gitRef = spec.slice(hashIndex + 1);
|
|
4322
|
-
if (!repoUrl || !gitRef) {
|
|
4323
|
-
throw new InvalidArgumentError("Repository target must be a full URL with optional #gitRef suffix.");
|
|
4324
|
-
}
|
|
4325
|
-
return { repoUrl, gitRef };
|
|
4326
|
-
}
|
|
4327
4704
|
// src/shared/unified-search-text.ts
|
|
4328
4705
|
var SUMMARY_WRAP_WIDTH = 76;
|
|
4329
|
-
var
|
|
4706
|
+
var SEP6 = " | ";
|
|
4330
4707
|
function renderUnifiedSearchSuccess(payload) {
|
|
4331
4708
|
const lines = [];
|
|
4332
|
-
lines.push(
|
|
4709
|
+
lines.push(buildHeader7(payload));
|
|
4333
4710
|
lines.push("");
|
|
4334
4711
|
if (payload.results.length === 0) {
|
|
4335
4712
|
lines.push(payload.completed ? "No hits." : "No hits yet - indexing.");
|
|
4336
4713
|
} else {
|
|
4337
|
-
payload.results
|
|
4338
|
-
if (idx > 0)
|
|
4339
|
-
lines.push("");
|
|
4340
|
-
appendHit(lines, idx + 1, hit);
|
|
4341
|
-
});
|
|
4714
|
+
appendUnifiedSearchHits(lines, payload.results);
|
|
4342
4715
|
}
|
|
4343
4716
|
const trailer = buildTrailer2(payload);
|
|
4344
4717
|
if (trailer.length > 0) {
|
|
@@ -4351,7 +4724,7 @@ function renderUnifiedSearchSuccess(payload) {
|
|
|
4351
4724
|
}
|
|
4352
4725
|
function renderUnifiedSearchError(payload) {
|
|
4353
4726
|
const lines = [];
|
|
4354
|
-
const header = `search${
|
|
4727
|
+
const header = `search${SEP6}ERROR${SEP6}code=${payload.code}${payload.retryable ? `${SEP6}retryable` : ""}`;
|
|
4355
4728
|
lines.push(header);
|
|
4356
4729
|
lines.push(payload.error);
|
|
4357
4730
|
if (payload.details && Object.keys(payload.details).length > 0) {
|
|
@@ -4364,21 +4737,25 @@ function renderUnifiedSearchError(payload) {
|
|
|
4364
4737
|
return lines.join(`
|
|
4365
4738
|
`);
|
|
4366
4739
|
}
|
|
4367
|
-
function
|
|
4740
|
+
function buildHeader7(payload) {
|
|
4368
4741
|
const count = payload.results.length;
|
|
4369
4742
|
const status = payload.completed ? `${count} hit${count === 1 ? "" : "s"}` : `${count} partial`;
|
|
4370
|
-
const parts = [`search${
|
|
4371
|
-
parts.push(`query=${
|
|
4743
|
+
const parts = [`search${SEP6}${status}`];
|
|
4744
|
+
parts.push(`query=${quote4(payload.query.raw)}`);
|
|
4372
4745
|
if (!payload.completed) {
|
|
4373
4746
|
parts.push(`searchRef=${payload.searchRef}`);
|
|
4374
4747
|
}
|
|
4375
|
-
return parts.join(
|
|
4748
|
+
return parts.join(SEP6);
|
|
4749
|
+
}
|
|
4750
|
+
function appendUnifiedSearchHits(lines, hits) {
|
|
4751
|
+
hits.forEach((hit, idx) => {
|
|
4752
|
+
if (idx > 0)
|
|
4753
|
+
lines.push("");
|
|
4754
|
+
appendHit(lines, idx + 1, hit);
|
|
4755
|
+
});
|
|
4376
4756
|
}
|
|
4377
4757
|
function appendHit(lines, index, hit) {
|
|
4378
4758
|
const headerParts = [hit.target, shortType(hit.type)];
|
|
4379
|
-
if (typeof hit.score === "number") {
|
|
4380
|
-
headerParts.push(formatScore(hit.score));
|
|
4381
|
-
}
|
|
4382
4759
|
lines.push(`[${index}] ${headerParts.join(" ")}`);
|
|
4383
4760
|
const locator = buildLocatorLine(hit);
|
|
4384
4761
|
if (locator)
|
|
@@ -4408,6 +4785,15 @@ function shortType(type) {
|
|
|
4408
4785
|
}
|
|
4409
4786
|
function buildLocatorLine(hit) {
|
|
4410
4787
|
const loc = hit.locator;
|
|
4788
|
+
const followUp = buildSearchHitFollowUpCommand(hit);
|
|
4789
|
+
if (followUp) {
|
|
4790
|
+
const tail = [];
|
|
4791
|
+
if (loc.qualifiedPath)
|
|
4792
|
+
tail.push(loc.qualifiedPath);
|
|
4793
|
+
if (loc.kind)
|
|
4794
|
+
tail.push(loc.kind);
|
|
4795
|
+
return tail.length > 0 ? `${followUp} ${tail.join(SEP6)}` : followUp;
|
|
4796
|
+
}
|
|
4411
4797
|
if (loc.filePath) {
|
|
4412
4798
|
let line = `${loc.filePath}${formatLineRange(loc.startLine, loc.endLine)}`;
|
|
4413
4799
|
const tail = [];
|
|
@@ -4416,7 +4802,7 @@ function buildLocatorLine(hit) {
|
|
|
4416
4802
|
if (loc.kind)
|
|
4417
4803
|
tail.push(loc.kind);
|
|
4418
4804
|
if (tail.length > 0)
|
|
4419
|
-
line += ` ${tail.join(
|
|
4805
|
+
line += ` ${tail.join(SEP6)}`;
|
|
4420
4806
|
return line;
|
|
4421
4807
|
}
|
|
4422
4808
|
if (loc.pageId)
|
|
@@ -4432,9 +4818,6 @@ function formatLineRange(start, end) {
|
|
|
4432
4818
|
return `:${start}`;
|
|
4433
4819
|
return `:${start}-${end}`;
|
|
4434
4820
|
}
|
|
4435
|
-
function formatScore(score) {
|
|
4436
|
-
return score.toFixed(2);
|
|
4437
|
-
}
|
|
4438
4821
|
function buildTrailer2(payload) {
|
|
4439
4822
|
const lines = [];
|
|
4440
4823
|
if (payload.warnings && payload.warnings.length > 0) {
|
|
@@ -4478,9 +4861,9 @@ function formatSourceStatus(entry) {
|
|
|
4478
4861
|
}
|
|
4479
4862
|
if (entry.note)
|
|
4480
4863
|
parts.push(entry.note);
|
|
4481
|
-
return parts.join(
|
|
4864
|
+
return parts.join(SEP6);
|
|
4482
4865
|
}
|
|
4483
|
-
function
|
|
4866
|
+
function quote4(value) {
|
|
4484
4867
|
return value.includes('"') ? `'${value}'` : `"${value}"`;
|
|
4485
4868
|
}
|
|
4486
4869
|
function formatDetailValue(value) {
|
|
@@ -4512,6 +4895,89 @@ function wrapText2(text, width) {
|
|
|
4512
4895
|
}
|
|
4513
4896
|
return lines;
|
|
4514
4897
|
}
|
|
4898
|
+
|
|
4899
|
+
// src/shared/unified-search-status-text.ts
|
|
4900
|
+
var SEP7 = " | ";
|
|
4901
|
+
function renderUnifiedSearchStatusText(payload) {
|
|
4902
|
+
const lines = [];
|
|
4903
|
+
lines.push(buildHeader8(payload));
|
|
4904
|
+
if (!payload.completed && payload.progress) {
|
|
4905
|
+
lines.push(formatProgress(payload.progress));
|
|
4906
|
+
}
|
|
4907
|
+
const result = payload.result;
|
|
4908
|
+
if (result)
|
|
4909
|
+
appendResult(lines, result);
|
|
4910
|
+
if (!payload.completed) {
|
|
4911
|
+
lines.push(`next: call search_status search_ref=${quote5(payload.searchRef)}`);
|
|
4912
|
+
}
|
|
4913
|
+
return lines.join(`
|
|
4914
|
+
`);
|
|
4915
|
+
}
|
|
4916
|
+
function buildHeader8(payload) {
|
|
4917
|
+
const state = payload.completed ? "complete" : "indexing";
|
|
4918
|
+
const parts = [`search_status${SEP7}${state}`];
|
|
4919
|
+
if (payload.searchRef)
|
|
4920
|
+
parts.push(`searchRef=${payload.searchRef}`);
|
|
4921
|
+
return parts.join(SEP7);
|
|
4922
|
+
}
|
|
4923
|
+
function appendResult(lines, result) {
|
|
4924
|
+
lines.push("");
|
|
4925
|
+
if (result.warnings && result.warnings.length > 0) {
|
|
4926
|
+
lines.push("warnings:");
|
|
4927
|
+
for (const warning2 of result.warnings)
|
|
4928
|
+
lines.push(` - ${warning2}`);
|
|
4929
|
+
lines.push("");
|
|
4930
|
+
}
|
|
4931
|
+
if (result.results.length === 0) {
|
|
4932
|
+
lines.push("No hits.");
|
|
4933
|
+
} else {
|
|
4934
|
+
appendUnifiedSearchHits(lines, result.results);
|
|
4935
|
+
}
|
|
4936
|
+
if (result.hasMore) {
|
|
4937
|
+
const nextOffsetHint = typeof result.nextOffset === "number" ? ` Pass offset=${result.nextOffset} for the next page or limit=N to widen.` : " Pass limit=N to widen.";
|
|
4938
|
+
lines.push("");
|
|
4939
|
+
lines.push(`More hits available.${nextOffsetHint}`);
|
|
4940
|
+
}
|
|
4941
|
+
if (result.sourceStatus && result.sourceStatus.length > 0) {
|
|
4942
|
+
lines.push("");
|
|
4943
|
+
lines.push("source notes:");
|
|
4944
|
+
for (const entry of result.sourceStatus) {
|
|
4945
|
+
lines.push(` - ${formatSourceStatus2(entry)}`);
|
|
4946
|
+
}
|
|
4947
|
+
}
|
|
4948
|
+
}
|
|
4949
|
+
function formatSourceStatus2(entry) {
|
|
4950
|
+
const parts = [`${entry.source} (${entry.targetLabel})`];
|
|
4951
|
+
if (entry.indexingStatus)
|
|
4952
|
+
parts.push(`indexing=${entry.indexingStatus}`);
|
|
4953
|
+
if (entry.codeIndexState)
|
|
4954
|
+
parts.push(`codeIndex=${entry.codeIndexState}`);
|
|
4955
|
+
if (entry.ignoredFilters?.length) {
|
|
4956
|
+
parts.push(`ignored=${entry.ignoredFilters.join(",")}`);
|
|
4957
|
+
}
|
|
4958
|
+
if (entry.incompatibleFilters?.length) {
|
|
4959
|
+
parts.push(`incompatible=${entry.incompatibleFilters.join(",")}`);
|
|
4960
|
+
}
|
|
4961
|
+
if (entry.ignoredQueryFeatures?.length) {
|
|
4962
|
+
parts.push(`ignoredQuery=${entry.ignoredQueryFeatures.join(",")}`);
|
|
4963
|
+
}
|
|
4964
|
+
if (entry.incompatibleQueryFeatures?.length) {
|
|
4965
|
+
parts.push(`incompatibleQuery=${entry.incompatibleQueryFeatures.join(",")}`);
|
|
4966
|
+
}
|
|
4967
|
+
if (entry.note)
|
|
4968
|
+
parts.push(entry.note);
|
|
4969
|
+
return parts.join(SEP7);
|
|
4970
|
+
}
|
|
4971
|
+
function formatProgress(progress) {
|
|
4972
|
+
return `progress: ${progress.status}, ${progress.targetsReady}/${progress.targetsTotal} targets ready, ${progress.elapsedMs}ms elapsed`;
|
|
4973
|
+
}
|
|
4974
|
+
function quote5(value) {
|
|
4975
|
+
return JSON.stringify(value);
|
|
4976
|
+
}
|
|
4977
|
+
// src/shared/unified-search-target.ts
|
|
4978
|
+
function parseUnifiedSearchTargetSpec(spec) {
|
|
4979
|
+
return parseCodeNavigationTargetSpec(spec);
|
|
4980
|
+
}
|
|
4515
4981
|
// src/shared/list-files-request.ts
|
|
4516
4982
|
var LIMIT_MIN2 = 1;
|
|
4517
4983
|
var LIMIT_MAX2 = 1000;
|
|
@@ -4522,20 +4988,140 @@ function buildListFilesParams(input) {
|
|
|
4522
4988
|
const limitExplicit = input.limit !== undefined;
|
|
4523
4989
|
const limit = normaliseLimit(input.limit);
|
|
4524
4990
|
const waitTimeoutMs = normaliseWaitTimeoutMs(input.waitTimeoutMs);
|
|
4991
|
+
const path = normalizeOptionalNonEmpty2(input.path, "path");
|
|
4525
4992
|
const pathPrefix = normalisePathPrefix(input.pathPrefix);
|
|
4993
|
+
const globs = normalizeStringList2(input.globs, "globs");
|
|
4994
|
+
const extensions = normalizeExtensions2(input.extensions);
|
|
4995
|
+
const fileTypes = normalizeStringList2(input.fileTypes, "file_types");
|
|
4996
|
+
const languages = normalizeStringList2(input.languages, "languages");
|
|
4997
|
+
const { fileIntent, fileIntentEcho } = normalizeOptionalFileIntent(input.fileIntent, "file_intent");
|
|
4998
|
+
const fileIntents = normalizeFileIntentList(input.fileIntents, "file_intents");
|
|
4999
|
+
const excludeFileIntents = normalizeFileIntentList(input.excludeFileIntents, "exclude_file_intents");
|
|
5000
|
+
if (fileIntent && fileIntents.length > 0) {
|
|
5001
|
+
throw new InvalidPackageSpecError("`file_intent` cannot be combined with `file_intents`.");
|
|
5002
|
+
}
|
|
5003
|
+
const pathSelectors = buildPathSelectors2({ path, globs });
|
|
5004
|
+
const pathExplicit = path !== undefined;
|
|
4526
5005
|
const pathPrefixExplicit = pathPrefix !== undefined;
|
|
5006
|
+
const globsExplicit = globs.length > 0;
|
|
4527
5007
|
return {
|
|
4528
5008
|
params: {
|
|
4529
5009
|
target: input.target,
|
|
5010
|
+
pathSelectors,
|
|
4530
5011
|
pathPrefix,
|
|
5012
|
+
extensions: extensions.length > 0 ? extensions : undefined,
|
|
5013
|
+
fileTypes: fileTypes.length > 0 ? fileTypes : undefined,
|
|
5014
|
+
languages: languages.length > 0 ? languages : undefined,
|
|
5015
|
+
fileIntent,
|
|
5016
|
+
fileIntents: fileIntents.length > 0 ? fileIntents : undefined,
|
|
5017
|
+
excludeFileIntents: excludeFileIntents.length > 0 ? excludeFileIntents : undefined,
|
|
5018
|
+
excludeDocFiles: input.excludeDocFiles,
|
|
5019
|
+
excludeTestFiles: input.excludeTestFiles,
|
|
5020
|
+
includeHidden: input.includeHidden,
|
|
4531
5021
|
limit,
|
|
4532
5022
|
waitTimeoutMs
|
|
4533
5023
|
},
|
|
4534
5024
|
effectiveLimit: limit,
|
|
4535
5025
|
limitExplicit,
|
|
4536
|
-
|
|
5026
|
+
explicit: {
|
|
5027
|
+
path: pathExplicit,
|
|
5028
|
+
pathPrefix: pathPrefixExplicit,
|
|
5029
|
+
globs: globsExplicit,
|
|
5030
|
+
extensions: extensions.length > 0,
|
|
5031
|
+
fileTypes: fileTypes.length > 0,
|
|
5032
|
+
languages: languages.length > 0,
|
|
5033
|
+
fileIntent: fileIntent !== undefined,
|
|
5034
|
+
fileIntents: fileIntents.length > 0,
|
|
5035
|
+
excludeFileIntents: excludeFileIntents.length > 0,
|
|
5036
|
+
excludeDocFiles: input.excludeDocFiles !== undefined,
|
|
5037
|
+
excludeTestFiles: input.excludeTestFiles !== undefined,
|
|
5038
|
+
includeHidden: input.includeHidden !== undefined,
|
|
5039
|
+
limit: limitExplicit
|
|
5040
|
+
},
|
|
5041
|
+
filterEcho: {
|
|
5042
|
+
path,
|
|
5043
|
+
pathPrefix,
|
|
5044
|
+
globs: globsExplicit ? globs : undefined,
|
|
5045
|
+
extensions: extensions.length > 0 ? extensions : undefined,
|
|
5046
|
+
fileTypes: fileTypes.length > 0 ? fileTypes : undefined,
|
|
5047
|
+
languages: languages.length > 0 ? languages : undefined,
|
|
5048
|
+
fileIntent: fileIntentEcho,
|
|
5049
|
+
fileIntents: fileIntents.length > 0 ? fileIntents.map((intent) => intent.toLowerCase()) : undefined,
|
|
5050
|
+
excludeFileIntents: excludeFileIntents.length > 0 ? excludeFileIntents.map((intent) => intent.toLowerCase()) : undefined,
|
|
5051
|
+
excludeDocFiles: input.excludeDocFiles,
|
|
5052
|
+
excludeTestFiles: input.excludeTestFiles,
|
|
5053
|
+
includeHidden: input.includeHidden,
|
|
5054
|
+
limit: limitExplicit ? limit : undefined
|
|
5055
|
+
}
|
|
4537
5056
|
};
|
|
4538
5057
|
}
|
|
5058
|
+
function buildPathSelectors2(input) {
|
|
5059
|
+
const selectors = [];
|
|
5060
|
+
if (input.path)
|
|
5061
|
+
selectors.push({ kind: "EXACT", value: input.path });
|
|
5062
|
+
for (const glob of input.globs) {
|
|
5063
|
+
selectors.push({ kind: "GLOB", value: glob });
|
|
5064
|
+
}
|
|
5065
|
+
return selectors.length > 0 ? selectors : undefined;
|
|
5066
|
+
}
|
|
5067
|
+
function normalizeOptionalNonEmpty2(raw, field) {
|
|
5068
|
+
if (raw === undefined)
|
|
5069
|
+
return;
|
|
5070
|
+
const trimmed = raw.trim();
|
|
5071
|
+
if (trimmed.length === 0) {
|
|
5072
|
+
throw new InvalidPackageSpecError(`\`${field}\` cannot be empty when provided.`);
|
|
5073
|
+
}
|
|
5074
|
+
return trimmed;
|
|
5075
|
+
}
|
|
5076
|
+
function normalizeStringList2(raw, field) {
|
|
5077
|
+
if (!raw)
|
|
5078
|
+
return [];
|
|
5079
|
+
const values = [];
|
|
5080
|
+
for (const entry of raw) {
|
|
5081
|
+
const trimmed = entry.trim();
|
|
5082
|
+
if (trimmed.length === 0) {
|
|
5083
|
+
throw new InvalidPackageSpecError(`\`${field}\` entries cannot be empty.`);
|
|
5084
|
+
}
|
|
5085
|
+
values.push(trimmed);
|
|
5086
|
+
}
|
|
5087
|
+
return values;
|
|
5088
|
+
}
|
|
5089
|
+
function normalizeExtensions2(raw) {
|
|
5090
|
+
const values = normalizeStringList2(raw, "extensions");
|
|
5091
|
+
for (const value of values) {
|
|
5092
|
+
if (value.startsWith(".")) {
|
|
5093
|
+
throw new InvalidPackageSpecError("`extensions` values must not include a leading dot.");
|
|
5094
|
+
}
|
|
5095
|
+
}
|
|
5096
|
+
return values;
|
|
5097
|
+
}
|
|
5098
|
+
function normalizeOptionalFileIntent(raw, field) {
|
|
5099
|
+
if (raw === undefined)
|
|
5100
|
+
return {};
|
|
5101
|
+
const trimmed = raw.trim().toLowerCase();
|
|
5102
|
+
if (trimmed.length === 0) {
|
|
5103
|
+
throw new InvalidPackageSpecError(`\`${field}\` cannot be empty when provided.`);
|
|
5104
|
+
}
|
|
5105
|
+
if (!isKnownFileIntent(trimmed)) {
|
|
5106
|
+
throw new InvalidPackageSpecError(`\`${field}\` must be one of: ${knownFileIntentList().join(", ")}. Got ${raw}.`);
|
|
5107
|
+
}
|
|
5108
|
+
return {
|
|
5109
|
+
fileIntent: toFileIntent(trimmed),
|
|
5110
|
+
fileIntentEcho: trimmed
|
|
5111
|
+
};
|
|
5112
|
+
}
|
|
5113
|
+
function normalizeFileIntentList(raw, field) {
|
|
5114
|
+
const values = normalizeStringList2(raw, field);
|
|
5115
|
+
const intents = [];
|
|
5116
|
+
for (const value of values) {
|
|
5117
|
+
const lower = value.toLowerCase();
|
|
5118
|
+
if (!isKnownFileIntent(lower)) {
|
|
5119
|
+
throw new InvalidPackageSpecError(`\`${field}\` values must be one of: ${knownFileIntentList().join(", ")}. Got ${value}.`);
|
|
5120
|
+
}
|
|
5121
|
+
intents.push(toFileIntent(lower));
|
|
5122
|
+
}
|
|
5123
|
+
return intents;
|
|
5124
|
+
}
|
|
4539
5125
|
function normaliseLimit(raw) {
|
|
4540
5126
|
if (raw === undefined)
|
|
4541
5127
|
return LIMIT_DEFAULT2;
|
|
@@ -4614,10 +5200,43 @@ function projectResolution2(resolution) {
|
|
|
4614
5200
|
}
|
|
4615
5201
|
function buildFilterBlock2(options) {
|
|
4616
5202
|
const filter = {};
|
|
4617
|
-
if (options.
|
|
5203
|
+
if (options.explicit.path && options.path) {
|
|
5204
|
+
filter.path = options.path;
|
|
5205
|
+
}
|
|
5206
|
+
if (options.explicit.pathPrefix && options.pathPrefix) {
|
|
4618
5207
|
filter.pathPrefix = options.pathPrefix;
|
|
4619
5208
|
}
|
|
4620
|
-
if (options.
|
|
5209
|
+
if (options.explicit.globs && options.globs && options.globs.length > 0) {
|
|
5210
|
+
filter.globs = options.globs;
|
|
5211
|
+
}
|
|
5212
|
+
if (options.explicit.extensions && options.extensions && options.extensions.length > 0) {
|
|
5213
|
+
filter.extensions = options.extensions;
|
|
5214
|
+
}
|
|
5215
|
+
if (options.explicit.fileTypes && options.fileTypes && options.fileTypes.length > 0) {
|
|
5216
|
+
filter.fileTypes = options.fileTypes;
|
|
5217
|
+
}
|
|
5218
|
+
if (options.explicit.languages && options.languages && options.languages.length > 0) {
|
|
5219
|
+
filter.languages = options.languages;
|
|
5220
|
+
}
|
|
5221
|
+
if (options.explicit.fileIntent && options.fileIntent) {
|
|
5222
|
+
filter.fileIntent = options.fileIntent;
|
|
5223
|
+
}
|
|
5224
|
+
if (options.explicit.fileIntents && options.fileIntents && options.fileIntents.length > 0) {
|
|
5225
|
+
filter.fileIntents = options.fileIntents;
|
|
5226
|
+
}
|
|
5227
|
+
if (options.explicit.excludeFileIntents && options.excludeFileIntents && options.excludeFileIntents.length > 0) {
|
|
5228
|
+
filter.excludeFileIntents = options.excludeFileIntents;
|
|
5229
|
+
}
|
|
5230
|
+
if (options.explicit.excludeDocFiles) {
|
|
5231
|
+
filter.excludeDocFiles = options.excludeDocFiles;
|
|
5232
|
+
}
|
|
5233
|
+
if (options.explicit.excludeTestFiles) {
|
|
5234
|
+
filter.excludeTestFiles = options.excludeTestFiles;
|
|
5235
|
+
}
|
|
5236
|
+
if (options.explicit.includeHidden) {
|
|
5237
|
+
filter.includeHidden = options.includeHidden;
|
|
5238
|
+
}
|
|
5239
|
+
if (options.explicit.limit && options.limit !== undefined) {
|
|
4621
5240
|
filter.limit = options.limit;
|
|
4622
5241
|
}
|
|
4623
5242
|
return Object.keys(filter).length > 0 ? filter : undefined;
|
|
@@ -4869,9 +5488,19 @@ async function pkgFilesAction(firstArg, secondArg, options, deps) {
|
|
|
4869
5488
|
const target = resolveCliCodeNavTarget(spec, options);
|
|
4870
5489
|
const limit = parseIntCliOption(options.limit, "--limit", 1, 1000);
|
|
4871
5490
|
const wait = parseIntCliOption(options.wait, "--wait", 0, MAX_WAIT_TIMEOUT_MS);
|
|
4872
|
-
const build =
|
|
5491
|
+
const build = buildCliListFilesParams({
|
|
4873
5492
|
target,
|
|
5493
|
+
path: options.path,
|
|
4874
5494
|
pathPrefix,
|
|
5495
|
+
globs: options.glob,
|
|
5496
|
+
extensions: options.ext,
|
|
5497
|
+
fileTypes: options.fileType,
|
|
5498
|
+
languages: options.language,
|
|
5499
|
+
fileIntents: options.fileIntent,
|
|
5500
|
+
excludeFileIntents: options.excludeIntent,
|
|
5501
|
+
excludeDocFiles: options.excludeDocs,
|
|
5502
|
+
excludeTestFiles: options.excludeTests,
|
|
5503
|
+
includeHidden: options.hidden,
|
|
4875
5504
|
limit,
|
|
4876
5505
|
waitTimeoutMs: wait
|
|
4877
5506
|
});
|
|
@@ -4881,10 +5510,20 @@ async function pkgFilesAction(firstArg, secondArg, options, deps) {
|
|
|
4881
5510
|
name: target.packageName,
|
|
4882
5511
|
repoUrl: target.repoUrl,
|
|
4883
5512
|
gitRef: target.gitRef,
|
|
4884
|
-
|
|
4885
|
-
|
|
4886
|
-
|
|
4887
|
-
|
|
5513
|
+
path: build.filterEcho.path,
|
|
5514
|
+
pathPrefix: build.filterEcho.pathPrefix,
|
|
5515
|
+
globs: build.filterEcho.globs,
|
|
5516
|
+
extensions: build.filterEcho.extensions,
|
|
5517
|
+
fileTypes: build.filterEcho.fileTypes,
|
|
5518
|
+
languages: build.filterEcho.languages,
|
|
5519
|
+
fileIntent: build.filterEcho.fileIntent,
|
|
5520
|
+
fileIntents: build.filterEcho.fileIntents,
|
|
5521
|
+
excludeFileIntents: build.filterEcho.excludeFileIntents,
|
|
5522
|
+
excludeDocFiles: build.filterEcho.excludeDocFiles,
|
|
5523
|
+
excludeTestFiles: build.filterEcho.excludeTestFiles,
|
|
5524
|
+
includeHidden: build.filterEcho.includeHidden,
|
|
5525
|
+
limit: build.filterEcho.limit,
|
|
5526
|
+
explicit: build.explicit
|
|
4888
5527
|
});
|
|
4889
5528
|
if (options.json) {
|
|
4890
5529
|
console.log(JSON.stringify(payload));
|
|
@@ -4901,6 +5540,21 @@ async function pkgFilesAction(firstArg, secondArg, options, deps) {
|
|
|
4901
5540
|
handleCodeNavCommandError(error2, options.json ?? false, formatIndexingError);
|
|
4902
5541
|
}
|
|
4903
5542
|
}
|
|
5543
|
+
function collectRepeatable(value, previous) {
|
|
5544
|
+
return [...previous ?? [], value];
|
|
5545
|
+
}
|
|
5546
|
+
function buildCliListFilesParams(input) {
|
|
5547
|
+
try {
|
|
5548
|
+
return buildListFilesParams(input);
|
|
5549
|
+
} catch (error2) {
|
|
5550
|
+
if (!(error2 instanceof InvalidPackageSpecError))
|
|
5551
|
+
throw error2;
|
|
5552
|
+
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]`");
|
|
5553
|
+
if (rewritten === error2.message)
|
|
5554
|
+
throw error2;
|
|
5555
|
+
throw new InvalidPackageSpecError(rewritten);
|
|
5556
|
+
}
|
|
5557
|
+
}
|
|
4904
5558
|
var REGISTRY_SPEC_HINT = /^(npm|pypi|hex|crates|nuget|maven|zig|vcpkg|packagist):/i;
|
|
4905
5559
|
function resolvePositionals(firstArg, secondArg, hasRepoUrl) {
|
|
4906
5560
|
if (hasRepoUrl) {
|
|
@@ -4920,8 +5574,11 @@ fetch more. Returned paths feed directly into \`githits code read\`
|
|
|
4920
5574
|
and \`githits code grep\`.
|
|
4921
5575
|
|
|
4922
5576
|
[path-prefix] is a literal directory prefix (e.g. \`src/\` or
|
|
4923
|
-
\`lib/parser\`)
|
|
4924
|
-
|
|
5577
|
+
\`lib/parser\`). Use --path for exact-file selectors, repeatable
|
|
5578
|
+
--glob for glob selectors, and --ext / --file-type / --language /
|
|
5579
|
+
--file-intent to intersect further. Selectors ([path-prefix], --path,
|
|
5580
|
+
--glob) are OR-ed — a file matches if any selector matches. The other
|
|
5581
|
+
filters intersect on top.
|
|
4925
5582
|
|
|
4926
5583
|
Addressing: <spec> (registry:name[@version]) OR --repo-url <url>
|
|
4927
5584
|
--git-ref <ref>. Supported registries: npm, pypi, hex, crates,
|
|
@@ -4934,7 +5591,7 @@ On an INDEXING response, the dependency is being indexed on-demand
|
|
|
4934
5591
|
— retry with a longer --wait (up to 60000 ms) or pick one of the
|
|
4935
5592
|
already-indexed versions surfaced in the error detail.`;
|
|
4936
5593
|
function registerCodeFilesCommand(pkgCommand) {
|
|
4937
|
-
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) => {
|
|
5594
|
+
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) => {
|
|
4938
5595
|
const deps = await createContainer();
|
|
4939
5596
|
await pkgFilesAction(arg1, arg2, options, {
|
|
4940
5597
|
codeNavigationService: deps.codeNavigationService,
|
|
@@ -5041,7 +5698,7 @@ function resolvePositionals2(first, second, third, hasRepoUrl) {
|
|
|
5041
5698
|
}
|
|
5042
5699
|
return { spec: first, pattern: second, pathPrefix: third };
|
|
5043
5700
|
}
|
|
5044
|
-
function
|
|
5701
|
+
function collectRepeatable2(value, previous = []) {
|
|
5045
5702
|
return [...previous, value];
|
|
5046
5703
|
}
|
|
5047
5704
|
function buildCliGrepParams(input) {
|
|
@@ -5076,8 +5733,8 @@ for context, --verbose for grouped output, and --cursor to continue a paginated
|
|
|
5076
5733
|
grep run. --symbol-field hydrates enclosing symbol metadata (appears under each
|
|
5077
5734
|
match in --verbose output; full payload in --json).`;
|
|
5078
5735
|
function registerCodeGrepCommand(pkgCommand) {
|
|
5079
|
-
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)",
|
|
5080
|
-
const { createContainer: createContainer2 } = await import("./shared/chunk-
|
|
5736
|
+
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) => {
|
|
5737
|
+
const { createContainer: createContainer2 } = await import("./shared/chunk-b6avnx6d.js");
|
|
5081
5738
|
const deps = await createContainer2();
|
|
5082
5739
|
await pkgGrepAction(arg1, arg2, arg3, options, {
|
|
5083
5740
|
codeNavigationService: deps.codeNavigationService,
|
|
@@ -5173,7 +5830,7 @@ function formatReadFileTerminal(envelope, options) {
|
|
|
5173
5830
|
function formatBinary(envelope, options, verbose) {
|
|
5174
5831
|
const sentinel = dim("Binary file — cannot display as text.", options.useColors);
|
|
5175
5832
|
if (verbose) {
|
|
5176
|
-
return `${
|
|
5833
|
+
return `${buildHeader9(envelope, options)}
|
|
5177
5834
|
|
|
5178
5835
|
${sentinel}
|
|
5179
5836
|
`;
|
|
@@ -5184,7 +5841,7 @@ ${sentinel}
|
|
|
5184
5841
|
function formatNoContent(envelope, options, verbose) {
|
|
5185
5842
|
const sentinel = dim("(no content returned)", options.useColors);
|
|
5186
5843
|
if (verbose) {
|
|
5187
|
-
return `${
|
|
5844
|
+
return `${buildHeader9(envelope, options)}
|
|
5188
5845
|
|
|
5189
5846
|
${sentinel}
|
|
5190
5847
|
`;
|
|
@@ -5194,7 +5851,7 @@ ${sentinel}
|
|
|
5194
5851
|
}
|
|
5195
5852
|
function formatVerboseBody(envelope, options) {
|
|
5196
5853
|
const lines = [];
|
|
5197
|
-
lines.push(
|
|
5854
|
+
lines.push(buildHeader9(envelope, options));
|
|
5198
5855
|
lines.push("");
|
|
5199
5856
|
const content = envelope.content ?? "";
|
|
5200
5857
|
const bodyLines = content.split(`
|
|
@@ -5218,7 +5875,7 @@ function formatVerboseBody(envelope, options) {
|
|
|
5218
5875
|
return lines.join(`
|
|
5219
5876
|
`);
|
|
5220
5877
|
}
|
|
5221
|
-
function
|
|
5878
|
+
function buildHeader9(envelope, options) {
|
|
5222
5879
|
const parts = [envelope.path];
|
|
5223
5880
|
if (envelope.language)
|
|
5224
5881
|
parts.push(envelope.language);
|
|
@@ -5596,7 +6253,7 @@ function registerExampleCommand(program) {
|
|
|
5596
6253
|
});
|
|
5597
6254
|
}
|
|
5598
6255
|
async function loadContainer() {
|
|
5599
|
-
const { createContainer: createContainer2 } = await import("./shared/chunk-
|
|
6256
|
+
const { createContainer: createContainer2 } = await import("./shared/chunk-b6avnx6d.js");
|
|
5600
6257
|
return createContainer2();
|
|
5601
6258
|
}
|
|
5602
6259
|
// src/commands/feedback.ts
|
|
@@ -6366,6 +7023,16 @@ class ExitPromptError extends Error {
|
|
|
6366
7023
|
name = "ExitPromptError";
|
|
6367
7024
|
}
|
|
6368
7025
|
// src/commands/login.ts
|
|
7026
|
+
var stdoutLoginOutput = {
|
|
7027
|
+
write: (message) => {
|
|
7028
|
+
console.log(message);
|
|
7029
|
+
}
|
|
7030
|
+
};
|
|
7031
|
+
var stderrLoginOutput = {
|
|
7032
|
+
write: (message) => {
|
|
7033
|
+
console.error(message);
|
|
7034
|
+
}
|
|
7035
|
+
};
|
|
6369
7036
|
var TIMEOUT_MS = 5 * 60 * 1000;
|
|
6370
7037
|
function randomPort() {
|
|
6371
7038
|
return Math.floor(Math.random() * 2000) + 8000;
|
|
@@ -6397,7 +7064,7 @@ async function preflightAuthPersistence(authStorage, mcpUrl) {
|
|
|
6397
7064
|
};
|
|
6398
7065
|
}
|
|
6399
7066
|
}
|
|
6400
|
-
async function loginFlow(options, deps) {
|
|
7067
|
+
async function loginFlow(options, deps, output = stdoutLoginOutput) {
|
|
6401
7068
|
const { authService, authStorage, browserService, mcpUrl } = deps;
|
|
6402
7069
|
if (options.port !== undefined && (Number.isNaN(options.port) || options.port < 1 || options.port > 65535)) {
|
|
6403
7070
|
return {
|
|
@@ -6411,10 +7078,10 @@ async function loginFlow(options, deps) {
|
|
|
6411
7078
|
if (!isExpired) {
|
|
6412
7079
|
return { status: "already_authenticated", message: "Already logged in." };
|
|
6413
7080
|
}
|
|
6414
|
-
|
|
7081
|
+
output.write(`Token expired. Starting new login...
|
|
6415
7082
|
`);
|
|
6416
7083
|
} else if (existing && options.force) {
|
|
6417
|
-
|
|
7084
|
+
output.write(`Re-authenticating (--force flag)...
|
|
6418
7085
|
`);
|
|
6419
7086
|
}
|
|
6420
7087
|
if (!existing) {
|
|
@@ -6423,7 +7090,7 @@ async function loginFlow(options, deps) {
|
|
|
6423
7090
|
const persistenceError = await preflightAuthPersistence(authStorage, mcpUrl);
|
|
6424
7091
|
if (persistenceError)
|
|
6425
7092
|
return persistenceError;
|
|
6426
|
-
|
|
7093
|
+
output.write("Discovering OAuth endpoints...");
|
|
6427
7094
|
const metadata = await authService.discoverEndpoints(mcpUrl);
|
|
6428
7095
|
let client = await authStorage.loadClient(mcpUrl);
|
|
6429
7096
|
let port;
|
|
@@ -6432,7 +7099,7 @@ async function loginFlow(options, deps) {
|
|
|
6432
7099
|
if (options.port) {
|
|
6433
7100
|
redirectUri = `http://127.0.0.1:${options.port}/callback`;
|
|
6434
7101
|
if (redirectUri !== client.redirectUri) {
|
|
6435
|
-
|
|
7102
|
+
output.write("Registering CLI client with new port...");
|
|
6436
7103
|
const registration = await authService.registerClient({
|
|
6437
7104
|
registrationEndpoint: metadata.registrationEndpoint,
|
|
6438
7105
|
redirectUri
|
|
@@ -6453,7 +7120,7 @@ async function loginFlow(options, deps) {
|
|
|
6453
7120
|
} else {
|
|
6454
7121
|
port = options.port ?? randomPort();
|
|
6455
7122
|
redirectUri = `http://127.0.0.1:${port}/callback`;
|
|
6456
|
-
|
|
7123
|
+
output.write("Registering CLI client...");
|
|
6457
7124
|
const registration = await authService.registerClient({
|
|
6458
7125
|
registrationEndpoint: metadata.registrationEndpoint,
|
|
6459
7126
|
redirectUri
|
|
@@ -6475,15 +7142,15 @@ async function loginFlow(options, deps) {
|
|
|
6475
7142
|
});
|
|
6476
7143
|
const serverPromise = authService.startCallbackServer(port, state);
|
|
6477
7144
|
if (options.browser === false) {
|
|
6478
|
-
|
|
7145
|
+
output.write(`Open this URL in your browser:
|
|
6479
7146
|
`);
|
|
6480
|
-
|
|
7147
|
+
output.write(` ${authUrl}
|
|
6481
7148
|
`);
|
|
6482
7149
|
} else {
|
|
6483
|
-
|
|
7150
|
+
output.write("Opening browser...");
|
|
6484
7151
|
await browserService.open(authUrl);
|
|
6485
7152
|
}
|
|
6486
|
-
|
|
7153
|
+
output.write(`Waiting for authentication...
|
|
6487
7154
|
`);
|
|
6488
7155
|
let timeoutId;
|
|
6489
7156
|
const timeoutPromise = new Promise((_, reject) => {
|
|
@@ -6541,7 +7208,7 @@ async function loginFlow(options, deps) {
|
|
|
6541
7208
|
};
|
|
6542
7209
|
}
|
|
6543
7210
|
async function loginAction(options, deps) {
|
|
6544
|
-
const result = await loginFlow(options, deps);
|
|
7211
|
+
const result = await loginFlow(options, deps, stdoutLoginOutput);
|
|
6545
7212
|
if (result.status === "already_authenticated") {
|
|
6546
7213
|
console.log(`Already logged in.
|
|
6547
7214
|
`);
|
|
@@ -6778,7 +7445,11 @@ async function languagesAction(query, options, deps) {
|
|
|
6778
7445
|
requireAuth(deps);
|
|
6779
7446
|
try {
|
|
6780
7447
|
const allLanguages = await deps.githitsService.getLanguages();
|
|
6781
|
-
const displayList = query ? filterLanguages(allLanguages, query) : allLanguages.map(({ name, display_name }) => ({
|
|
7448
|
+
const displayList = query ? filterLanguages(allLanguages, query) : allLanguages.map(({ name, display_name, aliases }) => ({
|
|
7449
|
+
name,
|
|
7450
|
+
display_name,
|
|
7451
|
+
aliases
|
|
7452
|
+
}));
|
|
6782
7453
|
if (options.json) {
|
|
6783
7454
|
console.log(JSON.stringify(displayList));
|
|
6784
7455
|
} else if (query && displayList.length === 0) {
|
|
@@ -6918,11 +7589,12 @@ import { z as z2 } from "zod";
|
|
|
6918
7589
|
var schema2 = {
|
|
6919
7590
|
query: z2.string().min(1).describe("Natural-language example-search query for canonical code examples."),
|
|
6920
7591
|
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."),
|
|
6921
|
-
license_mode: z2.enum(["strict", "yolo", "custom"]).optional().describe("License filtering mode: strict (default), yolo, or custom.")
|
|
7592
|
+
license_mode: z2.enum(["strict", "yolo", "custom"]).optional().describe("License filtering mode: strict (default), yolo, or custom."),
|
|
7593
|
+
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?}`.")
|
|
6922
7594
|
};
|
|
6923
7595
|
var DESCRIPTION2 = `Get verified, canonical code examples from global open source.
|
|
6924
7596
|
|
|
6925
|
-
|
|
7597
|
+
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.`;
|
|
6926
7598
|
function createGetExampleTool(service) {
|
|
6927
7599
|
return {
|
|
6928
7600
|
name: "get_example",
|
|
@@ -6938,17 +7610,25 @@ function createGetExampleTool(service) {
|
|
|
6938
7610
|
});
|
|
6939
7611
|
const solutionId = extractSolutionId(markdown);
|
|
6940
7612
|
const payload = solutionId ? { result: markdown, solution_id: solutionId } : { result: markdown };
|
|
7613
|
+
if (isTextFormat(args.format)) {
|
|
7614
|
+
return textResult(solutionId ? `${markdown.trimEnd()}
|
|
7615
|
+
|
|
7616
|
+
solution_id: ${solutionId}` : markdown);
|
|
7617
|
+
}
|
|
6941
7618
|
return textResult(JSON.stringify(payload));
|
|
6942
7619
|
});
|
|
6943
7620
|
}
|
|
6944
7621
|
};
|
|
6945
7622
|
}
|
|
7623
|
+
function isTextFormat(format) {
|
|
7624
|
+
return format === undefined || format === "text" || format === "text-v1";
|
|
7625
|
+
}
|
|
6946
7626
|
// src/tools/grep-repo.ts
|
|
6947
7627
|
import { z as z4 } from "zod";
|
|
6948
7628
|
|
|
6949
7629
|
// src/tools/code-navigation-shared.ts
|
|
6950
7630
|
import { z as z3 } from "zod";
|
|
6951
|
-
var
|
|
7631
|
+
var structuredCodeTargetSchema = z3.object({
|
|
6952
7632
|
registry: z3.enum([
|
|
6953
7633
|
"npm",
|
|
6954
7634
|
"pypi",
|
|
@@ -6965,7 +7645,18 @@ var codeTargetSchema = z3.object({
|
|
|
6965
7645
|
repo_url: z3.string().optional().describe("Repository URL (GitHub). Required for repo scope. Example: https://github.com/expressjs/express"),
|
|
6966
7646
|
git_ref: z3.string().optional().describe("Git ref - tag, branch, or commit. Required with repo_url. Use HEAD for latest.")
|
|
6967
7647
|
}).describe("Target: provide registry + package_name (package scope) or repo_url + git_ref (repo scope).");
|
|
7648
|
+
var codeTargetSchema = z3.union([
|
|
7649
|
+
structuredCodeTargetSchema,
|
|
7650
|
+
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).")
|
|
7651
|
+
]);
|
|
6968
7652
|
function resolveCodeTarget(target) {
|
|
7653
|
+
if (typeof target === "string") {
|
|
7654
|
+
try {
|
|
7655
|
+
return parseCodeNavigationTargetSpec(target);
|
|
7656
|
+
} catch (error2) {
|
|
7657
|
+
return mappedInvalidTargetResult(error2);
|
|
7658
|
+
}
|
|
7659
|
+
}
|
|
6969
7660
|
const hasPackageTarget = Boolean(target.registry || target.package_name);
|
|
6970
7661
|
const hasRepoTarget = Boolean(target.repo_url || target.git_ref);
|
|
6971
7662
|
if (hasPackageTarget && hasRepoTarget) {
|
|
@@ -6998,6 +7689,15 @@ function resolveCodeTarget(target) {
|
|
|
6998
7689
|
gitRef: target.git_ref
|
|
6999
7690
|
};
|
|
7000
7691
|
}
|
|
7692
|
+
function mappedInvalidTargetResult(error2) {
|
|
7693
|
+
const mapped = mapCodeNavigationError(error2);
|
|
7694
|
+
return errorResult(JSON.stringify({
|
|
7695
|
+
error: mapped.message,
|
|
7696
|
+
code: mapped.code,
|
|
7697
|
+
retryable: mapped.retryable ?? false,
|
|
7698
|
+
...mapped.details ? { details: mapped.details } : {}
|
|
7699
|
+
}));
|
|
7700
|
+
}
|
|
7001
7701
|
function invalidTargetResult(message) {
|
|
7002
7702
|
return errorResult(JSON.stringify({
|
|
7003
7703
|
error: message,
|
|
@@ -7084,7 +7784,7 @@ function createGrepRepoTool(service) {
|
|
|
7084
7784
|
excludeTestFiles: build.params.excludeTestFiles,
|
|
7085
7785
|
explicit: build.explicit
|
|
7086
7786
|
});
|
|
7087
|
-
if (
|
|
7787
|
+
if (isTextFormat2(args.format)) {
|
|
7088
7788
|
return textResult(renderGrepRepoText(payload));
|
|
7089
7789
|
}
|
|
7090
7790
|
return textResult(JSON.stringify(payload));
|
|
@@ -7100,19 +7800,30 @@ function createGrepRepoTool(service) {
|
|
|
7100
7800
|
}
|
|
7101
7801
|
};
|
|
7102
7802
|
}
|
|
7103
|
-
function
|
|
7803
|
+
function isTextFormat2(format) {
|
|
7104
7804
|
return format === undefined || format === "text" || format === "text-v1";
|
|
7105
7805
|
}
|
|
7106
7806
|
// src/tools/list-files.ts
|
|
7107
7807
|
import { z as z5 } from "zod";
|
|
7108
7808
|
var schema4 = {
|
|
7109
7809
|
target: codeTargetSchema,
|
|
7110
|
-
|
|
7810
|
+
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."),
|
|
7811
|
+
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."),
|
|
7812
|
+
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`."),
|
|
7813
|
+
extensions: z5.array(z5.string()).optional().describe("File extensions to include, without a leading dot."),
|
|
7814
|
+
file_types: z5.array(z5.string()).optional().describe("File type filters to include, matching aigrep file_type values such as `source` or `doc`."),
|
|
7815
|
+
languages: z5.array(z5.string()).optional().describe("Language filters to include, matching aigrep language names."),
|
|
7816
|
+
file_intent: z5.string().optional().describe(`Single inclusive file-intent filter. Cannot be combined with \`file_intents\`. Valid values: ${knownFileIntentList().join(", ")}.`),
|
|
7817
|
+
file_intents: z5.array(z5.string()).optional().describe(`Inclusive file-intent filters. Cannot be combined with \`file_intent\`. Valid values: ${knownFileIntentList().join(", ")}.`),
|
|
7818
|
+
exclude_file_intents: z5.array(z5.string()).optional().describe(`Exclude these file intents after inclusive intent filtering. Valid values: ${knownFileIntentList().join(", ")}.`),
|
|
7819
|
+
exclude_doc_files: z5.boolean().optional(),
|
|
7820
|
+
exclude_test_files: z5.boolean().optional(),
|
|
7821
|
+
include_hidden: z5.boolean().optional(),
|
|
7111
7822
|
limit: z5.number().optional().describe("Max entries to return (1–1000, default 200). Out-of-range values return an `INVALID_ARGUMENT` envelope."),
|
|
7112
7823
|
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`."),
|
|
7113
7824
|
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.')
|
|
7114
7825
|
};
|
|
7115
|
-
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.
|
|
7826
|
+
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`.";
|
|
7116
7827
|
function createListFilesTool(service) {
|
|
7117
7828
|
return {
|
|
7118
7829
|
name: "code_files",
|
|
@@ -7126,7 +7837,18 @@ function createListFilesTool(service) {
|
|
|
7126
7837
|
try {
|
|
7127
7838
|
const build = buildListFilesParams({
|
|
7128
7839
|
target,
|
|
7840
|
+
path: args.path,
|
|
7129
7841
|
pathPrefix: args.path_prefix,
|
|
7842
|
+
globs: args.globs,
|
|
7843
|
+
extensions: args.extensions,
|
|
7844
|
+
fileTypes: args.file_types,
|
|
7845
|
+
languages: args.languages,
|
|
7846
|
+
fileIntent: args.file_intent,
|
|
7847
|
+
fileIntents: args.file_intents,
|
|
7848
|
+
excludeFileIntents: args.exclude_file_intents,
|
|
7849
|
+
excludeDocFiles: args.exclude_doc_files,
|
|
7850
|
+
excludeTestFiles: args.exclude_test_files,
|
|
7851
|
+
includeHidden: args.include_hidden,
|
|
7130
7852
|
limit: args.limit,
|
|
7131
7853
|
waitTimeoutMs: args.wait_timeout_ms
|
|
7132
7854
|
});
|
|
@@ -7136,12 +7858,22 @@ function createListFilesTool(service) {
|
|
|
7136
7858
|
name: target.packageName,
|
|
7137
7859
|
repoUrl: target.repoUrl,
|
|
7138
7860
|
gitRef: target.gitRef,
|
|
7139
|
-
|
|
7140
|
-
|
|
7141
|
-
|
|
7142
|
-
|
|
7861
|
+
path: build.filterEcho.path,
|
|
7862
|
+
pathPrefix: build.filterEcho.pathPrefix,
|
|
7863
|
+
globs: build.filterEcho.globs,
|
|
7864
|
+
extensions: build.filterEcho.extensions,
|
|
7865
|
+
fileTypes: build.filterEcho.fileTypes,
|
|
7866
|
+
languages: build.filterEcho.languages,
|
|
7867
|
+
fileIntent: build.filterEcho.fileIntent,
|
|
7868
|
+
fileIntents: build.filterEcho.fileIntents,
|
|
7869
|
+
excludeFileIntents: build.filterEcho.excludeFileIntents,
|
|
7870
|
+
excludeDocFiles: build.filterEcho.excludeDocFiles,
|
|
7871
|
+
excludeTestFiles: build.filterEcho.excludeTestFiles,
|
|
7872
|
+
includeHidden: build.filterEcho.includeHidden,
|
|
7873
|
+
limit: build.filterEcho.limit,
|
|
7874
|
+
explicit: build.explicit
|
|
7143
7875
|
});
|
|
7144
|
-
if (
|
|
7876
|
+
if (isTextFormat3(args.format)) {
|
|
7145
7877
|
return textResult(renderListFilesText(payload));
|
|
7146
7878
|
}
|
|
7147
7879
|
return textResult(JSON.stringify(payload));
|
|
@@ -7157,7 +7889,7 @@ function createListFilesTool(service) {
|
|
|
7157
7889
|
}
|
|
7158
7890
|
};
|
|
7159
7891
|
}
|
|
7160
|
-
function
|
|
7892
|
+
function isTextFormat3(format) {
|
|
7161
7893
|
return format === undefined || format === "text" || format === "text-v1";
|
|
7162
7894
|
}
|
|
7163
7895
|
// src/tools/list-package-docs.ts
|
|
@@ -7167,7 +7899,8 @@ var schema5 = {
|
|
|
7167
7899
|
package_name: z6.string().describe("Package name (scoped names ok: @types/node)."),
|
|
7168
7900
|
version: z6.string().optional().describe("Optional package version."),
|
|
7169
7901
|
limit: z6.number().optional().describe("Max pages to return (1-500, default 100)."),
|
|
7170
|
-
after: z6.string().optional().describe("Pagination cursor from a prior response.")
|
|
7902
|
+
after: z6.string().optional().describe("Pagination cursor from a prior response."),
|
|
7903
|
+
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.')
|
|
7171
7904
|
};
|
|
7172
7905
|
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.";
|
|
7173
7906
|
function createListPackageDocsTool(service) {
|
|
@@ -7192,6 +7925,9 @@ function createListPackageDocsTool(service) {
|
|
|
7192
7925
|
limit: build.params.limit,
|
|
7193
7926
|
after: build.params.after
|
|
7194
7927
|
});
|
|
7928
|
+
if (isTextFormat4(args.format)) {
|
|
7929
|
+
return textResult(renderListPackageDocsText(payload));
|
|
7930
|
+
}
|
|
7195
7931
|
return textResult(JSON.stringify(payload));
|
|
7196
7932
|
} catch (error2) {
|
|
7197
7933
|
const mapped = mapPackageIntelligenceError(error2);
|
|
@@ -7205,6 +7941,9 @@ function createListPackageDocsTool(service) {
|
|
|
7205
7941
|
}
|
|
7206
7942
|
};
|
|
7207
7943
|
}
|
|
7944
|
+
function isTextFormat4(format) {
|
|
7945
|
+
return format === undefined || format === "text" || format === "text-v1";
|
|
7946
|
+
}
|
|
7208
7947
|
// src/tools/package-changelog.ts
|
|
7209
7948
|
import { z as z7 } from "zod";
|
|
7210
7949
|
|
|
@@ -7405,7 +8144,7 @@ function appendBodyLines(lines, body, options) {
|
|
|
7405
8144
|
}
|
|
7406
8145
|
const hidden = bodyLines.length - visible.length;
|
|
7407
8146
|
if (hidden > 0) {
|
|
7408
|
-
lines.push(` ${dim(`… (+${hidden} more line${hidden === 1 ? "" : "s"} — use --verbose for the full body)`, options.useColors)}`);
|
|
8147
|
+
lines.push(` ${dim(`… (+${hidden} more line${hidden === 1 ? "" : "s"} — ${options.fullBodyHint ?? "use --verbose for the full body"})`, options.useColors)}`);
|
|
7409
8148
|
}
|
|
7410
8149
|
}
|
|
7411
8150
|
function buildSummaryLine(envelope, options) {
|
|
@@ -7477,9 +8216,10 @@ var schema6 = {
|
|
|
7477
8216
|
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."),
|
|
7478
8217
|
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."),
|
|
7479
8218
|
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."),
|
|
7480
|
-
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.")
|
|
8219
|
+
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."),
|
|
8220
|
+
format: z7.enum(["json", "text", "text-v1"]).optional().describe("Response format. Default `text-v1` is compact for agents. Pass `json` for the structured envelope.")
|
|
7481
8221
|
};
|
|
7482
|
-
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"`), ' +
|
|
8222
|
+
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.";
|
|
7483
8223
|
function createPackageChangelogTool(service) {
|
|
7484
8224
|
return {
|
|
7485
8225
|
name: "pkg_changelog",
|
|
@@ -7510,6 +8250,13 @@ function createPackageChangelogTool(service) {
|
|
|
7510
8250
|
limit: params.limit,
|
|
7511
8251
|
gitRef: params.gitRef
|
|
7512
8252
|
});
|
|
8253
|
+
if (isTextFormat5(args.format)) {
|
|
8254
|
+
return textResult(formatPackageChangelogTerminal(payload, {
|
|
8255
|
+
useColors: false,
|
|
8256
|
+
verbose: false,
|
|
8257
|
+
fullBodyHint: 'pass format="json" for full bodies'
|
|
8258
|
+
}).trimEnd());
|
|
8259
|
+
}
|
|
7513
8260
|
return textResult(JSON.stringify(payload));
|
|
7514
8261
|
} catch (error2) {
|
|
7515
8262
|
const mapped = mapPackageIntelligenceError(error2);
|
|
@@ -7531,18 +8278,22 @@ function createPackageChangelogTool(service) {
|
|
|
7531
8278
|
}
|
|
7532
8279
|
};
|
|
7533
8280
|
}
|
|
8281
|
+
function isTextFormat5(format) {
|
|
8282
|
+
return format === undefined || format === "text" || format === "text-v1";
|
|
8283
|
+
}
|
|
7534
8284
|
// src/tools/package-dependencies.ts
|
|
7535
8285
|
import { z as z8 } from "zod";
|
|
7536
8286
|
var schema7 = {
|
|
7537
8287
|
registry: z8.string().describe("Package registry. Dependency data is available on npm, pypi, hex, crates, vcpkg, and zig."),
|
|
7538
8288
|
package_name: z8.string().describe("Package name (scoped names ok: @types/node)."),
|
|
7539
8289
|
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`)."),
|
|
7540
|
-
lifecycle: z8.union([z8.string(), z8.array(z8.string())]).optional().describe(
|
|
8290
|
+
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."),
|
|
7541
8291
|
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."),
|
|
7542
8292
|
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."),
|
|
7543
|
-
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`.")
|
|
8293
|
+
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`."),
|
|
8294
|
+
format: z8.enum(["json", "text", "text-v1"]).optional().describe("Response format. Default `text-v1` is compact for agents. Pass `json` for the structured envelope.")
|
|
7544
8295
|
};
|
|
7545
|
-
var DESCRIPTION7 = "Analyze a package's dependency graph.
|
|
8296
|
+
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.";
|
|
7546
8297
|
function createPackageDependenciesTool(service) {
|
|
7547
8298
|
return {
|
|
7548
8299
|
name: "pkg_deps",
|
|
@@ -7574,6 +8325,18 @@ function createPackageDependenciesTool(service) {
|
|
|
7574
8325
|
maxDepth: args.max_depth,
|
|
7575
8326
|
includeImporters: args.include_importers ?? false
|
|
7576
8327
|
});
|
|
8328
|
+
if (isTextFormat6(args.format)) {
|
|
8329
|
+
const textLifecycles = canonicalLifecycles.length > 0 ? canonicalLifecycles : ["all"];
|
|
8330
|
+
return textResult(formatPackageDependenciesTerminal(report, {
|
|
8331
|
+
useColors: false,
|
|
8332
|
+
requestedVersion: args.version,
|
|
8333
|
+
canonicalLifecycles: textLifecycles,
|
|
8334
|
+
includeTransitive: args.include_transitive,
|
|
8335
|
+
maxDepth: args.max_depth,
|
|
8336
|
+
showGroups: canonicalLifecycles.length > 0 && !canonicalLifecycles.every((item) => item === "runtime"),
|
|
8337
|
+
hiddenGroupsHint: 'pass lifecycle="all".'
|
|
8338
|
+
}).trimEnd());
|
|
8339
|
+
}
|
|
7577
8340
|
return textResult(JSON.stringify(payload));
|
|
7578
8341
|
} catch (error2) {
|
|
7579
8342
|
const mapped = mapPackageIntelligenceError(error2);
|
|
@@ -7595,13 +8358,17 @@ function createPackageDependenciesTool(service) {
|
|
|
7595
8358
|
}
|
|
7596
8359
|
};
|
|
7597
8360
|
}
|
|
8361
|
+
function isTextFormat6(format) {
|
|
8362
|
+
return format === undefined || format === "text" || format === "text-v1";
|
|
8363
|
+
}
|
|
7598
8364
|
// src/tools/package-summary.ts
|
|
7599
8365
|
import { z as z9 } from "zod";
|
|
7600
8366
|
var schema8 = {
|
|
7601
8367
|
registry: z9.string().describe("Package registry. One of: npm, pypi, hex, crates, nuget, maven, zig, vcpkg, packagist."),
|
|
7602
|
-
package_name: z9.string().describe("Package name (scoped names ok: @types/node).")
|
|
8368
|
+
package_name: z9.string().describe("Package name (scoped names ok: @types/node)."),
|
|
8369
|
+
format: z9.enum(["json", "text", "text-v1"]).optional().describe("Response format. Default `text-v1` is compact for agents. Pass `json` for the structured envelope.")
|
|
7603
8370
|
};
|
|
7604
|
-
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.";
|
|
8371
|
+
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.";
|
|
7605
8372
|
function createPackageSummaryTool(service) {
|
|
7606
8373
|
return {
|
|
7607
8374
|
name: "pkg_info",
|
|
@@ -7616,6 +8383,11 @@ function createPackageSummaryTool(service) {
|
|
|
7616
8383
|
});
|
|
7617
8384
|
const summary = await service.packageSummary(params);
|
|
7618
8385
|
const payload = buildPackageSummarySuccessPayload(summary);
|
|
8386
|
+
if (isTextFormat7(args.format)) {
|
|
8387
|
+
return textResult(formatPackageSummaryTerminal(summary, {
|
|
8388
|
+
useColors: false
|
|
8389
|
+
}).trimEnd());
|
|
8390
|
+
}
|
|
7619
8391
|
return textResult(JSON.stringify(payload));
|
|
7620
8392
|
} catch (error2) {
|
|
7621
8393
|
const mapped = mapPackageIntelligenceError(error2);
|
|
@@ -7637,6 +8409,9 @@ function createPackageSummaryTool(service) {
|
|
|
7637
8409
|
}
|
|
7638
8410
|
};
|
|
7639
8411
|
}
|
|
8412
|
+
function isTextFormat7(format) {
|
|
8413
|
+
return format === undefined || format === "text" || format === "text-v1";
|
|
8414
|
+
}
|
|
7640
8415
|
// src/tools/package-vulnerabilities.ts
|
|
7641
8416
|
import { z as z10 } from "zod";
|
|
7642
8417
|
var schema9 = {
|
|
@@ -7644,9 +8419,10 @@ var schema9 = {
|
|
|
7644
8419
|
package_name: z10.string().describe("Package name (scoped names ok: @types/node)."),
|
|
7645
8420
|
version: z10.string().optional().describe("Specific version to check. Defaults to latest when omitted."),
|
|
7646
8421
|
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."),
|
|
7647
|
-
include_withdrawn: z10.boolean().optional().describe("Include retracted advisories (default: false).")
|
|
8422
|
+
include_withdrawn: z10.boolean().optional().describe("Include retracted advisories (default: false)."),
|
|
8423
|
+
format: z10.enum(["json", "text", "text-v1"]).optional().describe("Response format. Default `text-v1` is compact for agents. Pass `json` for the structured envelope.")
|
|
7648
8424
|
};
|
|
7649
|
-
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.";
|
|
8425
|
+
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.';
|
|
7650
8426
|
function createPackageVulnerabilitiesTool(service) {
|
|
7651
8427
|
return {
|
|
7652
8428
|
name: "pkg_vulns",
|
|
@@ -7666,6 +8442,12 @@ function createPackageVulnerabilitiesTool(service) {
|
|
|
7666
8442
|
const payload = buildPackageVulnerabilitiesSuccessPayload(report, {
|
|
7667
8443
|
requestedVersion: args.version
|
|
7668
8444
|
});
|
|
8445
|
+
if (isTextFormat8(args.format)) {
|
|
8446
|
+
return textResult(formatPackageVulnerabilitiesTerminal(report, {
|
|
8447
|
+
useColors: false,
|
|
8448
|
+
requestedVersion: args.version
|
|
8449
|
+
}).trimEnd());
|
|
8450
|
+
}
|
|
7669
8451
|
return textResult(JSON.stringify(payload));
|
|
7670
8452
|
} catch (error2) {
|
|
7671
8453
|
const mapped = mapPackageIntelligenceError(error2);
|
|
@@ -7687,6 +8469,9 @@ function createPackageVulnerabilitiesTool(service) {
|
|
|
7687
8469
|
}
|
|
7688
8470
|
};
|
|
7689
8471
|
}
|
|
8472
|
+
function isTextFormat8(format) {
|
|
8473
|
+
return format === undefined || format === "text" || format === "text-v1";
|
|
8474
|
+
}
|
|
7690
8475
|
// src/tools/read-file.ts
|
|
7691
8476
|
import { z as z11 } from "zod";
|
|
7692
8477
|
var MCP_READ_MAX_SPAN = 150;
|
|
@@ -7695,7 +8480,8 @@ var schema10 = {
|
|
|
7695
8480
|
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."),
|
|
7696
8481
|
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.`),
|
|
7697
8482
|
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.`),
|
|
7698
|
-
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`.")
|
|
8483
|
+
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`."),
|
|
8484
|
+
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.')
|
|
7699
8485
|
};
|
|
7700
8486
|
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.";
|
|
7701
8487
|
function deriveBoundedRange(startLine, endLine) {
|
|
@@ -7747,6 +8533,9 @@ function createReadFileTool(service) {
|
|
|
7747
8533
|
if (shouldEmitCappedHint(bounded, payload)) {
|
|
7748
8534
|
payload.hint = buildCappedHint(payload, args.start_line, args.end_line);
|
|
7749
8535
|
}
|
|
8536
|
+
if (isTextFormat9(args.format)) {
|
|
8537
|
+
return textResult(renderReadFileText(payload));
|
|
8538
|
+
}
|
|
7750
8539
|
return textResult(JSON.stringify(payload));
|
|
7751
8540
|
} catch (error2) {
|
|
7752
8541
|
const mapped = mapCodeNavigationError(error2);
|
|
@@ -7760,6 +8549,9 @@ function createReadFileTool(service) {
|
|
|
7760
8549
|
}
|
|
7761
8550
|
};
|
|
7762
8551
|
}
|
|
8552
|
+
function isTextFormat9(format) {
|
|
8553
|
+
return format === undefined || format === "text" || format === "text-v1";
|
|
8554
|
+
}
|
|
7763
8555
|
function shouldEmitCappedHint(bounded, payload) {
|
|
7764
8556
|
if (!bounded.capped)
|
|
7765
8557
|
return false;
|
|
@@ -7789,10 +8581,12 @@ function describeRequest(originalStart, originalEnd) {
|
|
|
7789
8581
|
}
|
|
7790
8582
|
// src/tools/read-package-doc.ts
|
|
7791
8583
|
import { z as z12 } from "zod";
|
|
8584
|
+
var MCP_DOC_READ_MAX_SPAN = 150;
|
|
7792
8585
|
var schema11 = {
|
|
7793
8586
|
page_id: z12.string().describe("Documentation page ID from `docs_list` or `search` results. Pass through unchanged; repo-backed IDs are snapshot-pinned."),
|
|
7794
8587
|
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."),
|
|
7795
|
-
end_line: z12.number().optional().describe("Ending line (inclusive). Omit for end of page. Must be ≥ `start_line` when both are set.")
|
|
8588
|
+
end_line: z12.number().optional().describe("Ending line (inclusive). Omit for end of page. Must be ≥ `start_line` when both are set."),
|
|
8589
|
+
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.')
|
|
7796
8590
|
};
|
|
7797
8591
|
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`.";
|
|
7798
8592
|
function createReadPackageDocTool(service) {
|
|
@@ -7805,8 +8599,14 @@ function createReadPackageDocTool(service) {
|
|
|
7805
8599
|
try {
|
|
7806
8600
|
const build = buildReadPackageDocParams({ pageId: args.page_id });
|
|
7807
8601
|
const result = await service.readPackageDoc(build.params);
|
|
7808
|
-
const
|
|
7809
|
-
const
|
|
8602
|
+
const textMode = isTextFormat10(args.format);
|
|
8603
|
+
const range = buildRange3(args, textMode);
|
|
8604
|
+
const payload = buildReadPackageDocSuccessPayload(result, build.params.pageId, range?.range);
|
|
8605
|
+
if (range?.hint && payload.endLine !== undefined) {
|
|
8606
|
+
payload.hint = range.hint(payload);
|
|
8607
|
+
}
|
|
8608
|
+
if (textMode)
|
|
8609
|
+
return textResult(renderReadPackageDocText(payload));
|
|
7810
8610
|
return textResult(JSON.stringify(payload));
|
|
7811
8611
|
} catch (error2) {
|
|
7812
8612
|
const mapped = mapPackageIntelligenceError(error2);
|
|
@@ -7820,6 +8620,22 @@ function createReadPackageDocTool(service) {
|
|
|
7820
8620
|
}
|
|
7821
8621
|
};
|
|
7822
8622
|
}
|
|
8623
|
+
function isTextFormat10(format) {
|
|
8624
|
+
return format === undefined || format === "text" || format === "text-v1";
|
|
8625
|
+
}
|
|
8626
|
+
function buildRange3(args, textMode) {
|
|
8627
|
+
if (textMode) {
|
|
8628
|
+
const startLine = args.start_line ?? 1;
|
|
8629
|
+
const requestedEnd = args.end_line ?? startLine + MCP_DOC_READ_MAX_SPAN - 1;
|
|
8630
|
+
const endLine = Math.min(requestedEnd, startLine + MCP_DOC_READ_MAX_SPAN - 1);
|
|
8631
|
+
const wasClamped = requestedEnd > endLine;
|
|
8632
|
+
return {
|
|
8633
|
+
range: { startLine, endLine },
|
|
8634
|
+
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
|
|
8635
|
+
};
|
|
8636
|
+
}
|
|
8637
|
+
return args.start_line !== undefined || args.end_line !== undefined ? { range: { startLine: args.start_line, endLine: args.end_line } } : undefined;
|
|
8638
|
+
}
|
|
7823
8639
|
// src/tools/search.ts
|
|
7824
8640
|
import { z as z13 } from "zod";
|
|
7825
8641
|
var schema12 = {
|
|
@@ -7914,13 +8730,13 @@ function createSearchTool(service) {
|
|
|
7914
8730
|
});
|
|
7915
8731
|
const outcome = await service.search(built.params);
|
|
7916
8732
|
const payload = buildUnifiedSearchSuccessPayload(built.params, built.rawQuery, built.compiledQuery, outcome);
|
|
7917
|
-
if (
|
|
8733
|
+
if (isTextFormat11(args.format)) {
|
|
7918
8734
|
return textResult(renderUnifiedSearchSuccess(payload));
|
|
7919
8735
|
}
|
|
7920
8736
|
return textResult(JSON.stringify(payload));
|
|
7921
8737
|
} catch (error2) {
|
|
7922
8738
|
const payload = buildUnifiedSearchErrorPayload(error2);
|
|
7923
|
-
if (
|
|
8739
|
+
if (isTextFormat11(args.format)) {
|
|
7924
8740
|
return errorResult(renderUnifiedSearchError(payload));
|
|
7925
8741
|
}
|
|
7926
8742
|
return errorResult(JSON.stringify(payload));
|
|
@@ -7931,15 +8747,16 @@ function createSearchTool(service) {
|
|
|
7931
8747
|
function isResolvedCodeTarget(target) {
|
|
7932
8748
|
return !("content" in target);
|
|
7933
8749
|
}
|
|
7934
|
-
function
|
|
8750
|
+
function isTextFormat11(format) {
|
|
7935
8751
|
return format === undefined || format === "text" || format === "text-v1";
|
|
7936
8752
|
}
|
|
7937
8753
|
// src/tools/search-language.ts
|
|
7938
8754
|
import { z as z14 } from "zod";
|
|
7939
8755
|
var schema13 = {
|
|
7940
|
-
query: z14.string().min(1).describe('Language name or partial name to search for (e.g., "python", "type", "java")')
|
|
8756
|
+
query: z14.string().min(1).describe('Language name or partial name to search for (e.g., "python", "type", "java")'),
|
|
8757
|
+
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.")
|
|
7941
8758
|
};
|
|
7942
|
-
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.`;
|
|
8759
|
+
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.`;
|
|
7943
8760
|
function createSearchLanguageTool(service) {
|
|
7944
8761
|
return {
|
|
7945
8762
|
name: "search_language",
|
|
@@ -7949,15 +8766,32 @@ function createSearchLanguageTool(service) {
|
|
|
7949
8766
|
return withErrorHandling("search languages", async () => {
|
|
7950
8767
|
const allLanguages = await service.getLanguages();
|
|
7951
8768
|
const result = filterLanguages(allLanguages, args.query);
|
|
8769
|
+
if (isTextFormat12(args.format)) {
|
|
8770
|
+
return textResult(renderLanguageMatches(result));
|
|
8771
|
+
}
|
|
7952
8772
|
return textResult(JSON.stringify(result));
|
|
7953
8773
|
});
|
|
7954
8774
|
}
|
|
7955
8775
|
};
|
|
7956
8776
|
}
|
|
8777
|
+
function isTextFormat12(format) {
|
|
8778
|
+
return format === undefined || format === "text" || format === "text-v1";
|
|
8779
|
+
}
|
|
8780
|
+
function renderLanguageMatches(matches) {
|
|
8781
|
+
if (matches.length === 0)
|
|
8782
|
+
return "No matching languages.";
|
|
8783
|
+
return matches.map((match) => {
|
|
8784
|
+
const label = match.display_name ? `${match.name} (${match.display_name})` : match.name;
|
|
8785
|
+
const aliases = match.aliases?.length ? ` aliases: ${match.aliases.join(", ")}` : "";
|
|
8786
|
+
return `${label}${aliases}`;
|
|
8787
|
+
}).join(`
|
|
8788
|
+
`);
|
|
8789
|
+
}
|
|
7957
8790
|
// src/tools/search-status.ts
|
|
7958
8791
|
import { z as z15 } from "zod";
|
|
7959
8792
|
var schema14 = {
|
|
7960
|
-
search_ref: z15.string().min(1).describe("Search reference returned by search.")
|
|
8793
|
+
search_ref: z15.string().min(1).describe("Search reference returned by search."),
|
|
8794
|
+
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.')
|
|
7961
8795
|
};
|
|
7962
8796
|
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.";
|
|
7963
8797
|
function createSearchStatusTool(service) {
|
|
@@ -7970,6 +8804,9 @@ function createSearchStatusTool(service) {
|
|
|
7970
8804
|
try {
|
|
7971
8805
|
const outcome = await service.searchStatus(args.search_ref);
|
|
7972
8806
|
const payload = buildUnifiedSearchStatusPayload(outcome);
|
|
8807
|
+
if (isTextFormat13(args.format)) {
|
|
8808
|
+
return textResult(renderUnifiedSearchStatusText(payload));
|
|
8809
|
+
}
|
|
7973
8810
|
return textResult(JSON.stringify(payload));
|
|
7974
8811
|
} catch (error2) {
|
|
7975
8812
|
return errorResult(JSON.stringify(buildUnifiedSearchErrorPayload(error2)));
|
|
@@ -7977,25 +8814,28 @@ function createSearchStatusTool(service) {
|
|
|
7977
8814
|
}
|
|
7978
8815
|
};
|
|
7979
8816
|
}
|
|
8817
|
+
function isTextFormat13(format) {
|
|
8818
|
+
return format === undefined || format === "text" || format === "text-v1";
|
|
8819
|
+
}
|
|
7980
8820
|
// src/commands/mcp-instructions.ts
|
|
7981
|
-
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.
|
|
8821
|
+
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.
|
|
7982
8822
|
|
|
7983
|
-
Example workflow: call \`get_example\` with one focused question; pass \`language\` only when you know the exact language name, otherwise call \`search_language\` first.
|
|
8823
|
+
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\`.`;
|
|
7984
8824
|
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.
|
|
7985
8825
|
|
|
7986
|
-
Package spec: \`registry:name[@version]
|
|
7987
|
-
var PKG_INFO_BULLET =
|
|
8826
|
+
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.`;
|
|
8827
|
+
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.';
|
|
7988
8828
|
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.";
|
|
7989
8829
|
var DOCS_READ_BULLET = "- `docs_read` — read a documentation page by pageId. Works for both hosted docs and repo-backed docs.";
|
|
7990
|
-
var PKG_VULNS_BULLET =
|
|
7991
|
-
var PKG_DEPS_BULLET =
|
|
7992
|
-
var PKG_CHANGELOG_BULLET =
|
|
7993
|
-
var SEARCH_BULLET = '- `search` — unified search across indexed dependency code, docs, and symbols. Omit `sources` for AUTO. Default output is compact `text-v1
|
|
8830
|
+
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.';
|
|
8831
|
+
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.';
|
|
8832
|
+
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.';
|
|
8833
|
+
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`.';
|
|
7994
8834
|
var SEARCH_STATUS_BULLET = "- `search_status` — follow up a prior `search` by `searchRef` to check progress, fetch partial hits, or fetch final results.";
|
|
7995
|
-
var CODE_FILES_BULLET = '- `code_files` — list files in an indexed dependency.
|
|
8835
|
+
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.';
|
|
7996
8836
|
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.";
|
|
7997
8837
|
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`.";
|
|
7998
|
-
var SEARCH_VS_SYMBOLS_TIP = '
|
|
8838
|
+
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.';
|
|
7999
8839
|
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.";
|
|
8000
8840
|
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.';
|
|
8001
8841
|
function buildMcpInstructions(_deps) {
|
|
@@ -8286,12 +9126,12 @@ async function pkgDepsAction(spec, options, deps) {
|
|
|
8286
9126
|
console.log(JSON.stringify(payload));
|
|
8287
9127
|
return;
|
|
8288
9128
|
}
|
|
8289
|
-
const showGroups = (
|
|
9129
|
+
const showGroups = canonicalLifecycles.some((entry) => entry !== "runtime");
|
|
8290
9130
|
const output = formatPackageDependenciesTerminal(report, {
|
|
8291
9131
|
verbose: options.verbose,
|
|
8292
9132
|
useColors: shouldUseColors(),
|
|
8293
9133
|
requestedVersion: parsed.version,
|
|
8294
|
-
canonicalLifecycles,
|
|
9134
|
+
canonicalLifecycles: canonicalLifecycles.length > 0 ? canonicalLifecycles : undefined,
|
|
8295
9135
|
includeTransitive: options.transitive,
|
|
8296
9136
|
maxDepth: userDepth,
|
|
8297
9137
|
showGroups
|
|
@@ -8353,9 +9193,9 @@ function formatDepsTerminalError(mapped) {
|
|
|
8353
9193
|
`);
|
|
8354
9194
|
}
|
|
8355
9195
|
var PKG_DEPS_DESCRIPTION = `Analyze package dependencies. By default shows the flat list of
|
|
8356
|
-
direct runtime dependencies. Use --
|
|
9196
|
+
direct runtime dependencies. Use --lifecycle all for the structured view
|
|
8357
9197
|
(dev / peer / build / optional, plus registry-specific feature / TFM
|
|
8358
|
-
groups). --lifecycle
|
|
9198
|
+
groups). Concrete --lifecycle values include runtime plus matching groups.
|
|
8359
9199
|
--transitive opts into aggregate edge / unique-package counts,
|
|
8360
9200
|
conflict detection, and circular-dependency flags.
|
|
8361
9201
|
|
|
@@ -8363,7 +9203,7 @@ Package spec: <registry>:<name>[@<version>]. Supported registries:
|
|
|
8363
9203
|
npm, pypi, hex, crates, vcpkg, zig. Omit @<version> for the latest
|
|
8364
9204
|
release.`;
|
|
8365
9205
|
function registerPkgDepsCommand(pkgCommand) {
|
|
8366
|
-
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("-
|
|
9206
|
+
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) => {
|
|
8367
9207
|
const deps = await createContainer();
|
|
8368
9208
|
await pkgDepsAction(spec, options, {
|
|
8369
9209
|
packageIntelligenceService: deps.packageIntelligenceService,
|
|
@@ -8632,7 +9472,7 @@ Pass the searchRef returned by githits search when the initial request could
|
|
|
8632
9472
|
not complete within the wait window. This can return progress, partial hits when
|
|
8633
9473
|
the original request used --allow-partial, or final results.`;
|
|
8634
9474
|
function registerSearchCommand(program) {
|
|
8635
|
-
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]",
|
|
9475
|
+
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([
|
|
8636
9476
|
...knownSymbolKindList()
|
|
8637
9477
|
])).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([
|
|
8638
9478
|
"production",
|
|
@@ -8666,7 +9506,7 @@ function requireSearchService(deps) {
|
|
|
8666
9506
|
return deps.codeNavigationService;
|
|
8667
9507
|
}
|
|
8668
9508
|
async function loadContainer2() {
|
|
8669
|
-
const { createContainer: createContainer2 } = await import("./shared/chunk-
|
|
9509
|
+
const { createContainer: createContainer2 } = await import("./shared/chunk-b6avnx6d.js");
|
|
8670
9510
|
return createContainer2();
|
|
8671
9511
|
}
|
|
8672
9512
|
function parseTargetSpecs(specs) {
|
|
@@ -8723,7 +9563,7 @@ function parseWaitMs(value) {
|
|
|
8723
9563
|
}
|
|
8724
9564
|
return seconds * 1000;
|
|
8725
9565
|
}
|
|
8726
|
-
function
|
|
9566
|
+
function collectRepeatable3(value, previous) {
|
|
8727
9567
|
return [...previous, value];
|
|
8728
9568
|
}
|
|
8729
9569
|
function handleSearchError(error2, json, context = "search") {
|
|
@@ -9032,12 +9872,14 @@ if (isTelemetryEnabled()) {
|
|
|
9032
9872
|
flushTelemetry(exitCode);
|
|
9033
9873
|
});
|
|
9034
9874
|
}
|
|
9035
|
-
|
|
9036
|
-
|
|
9037
|
-
|
|
9038
|
-
|
|
9875
|
+
var rootCliPreAction = createRootCliPreAction({
|
|
9876
|
+
createContainer,
|
|
9877
|
+
loginFlow: (options, deps) => loginFlow(options, deps, stderrLoginOutput)
|
|
9878
|
+
});
|
|
9879
|
+
program.name("githits").description("Code examples from global open source for your AI assistant").version(version).option("--no-color", "Disable colored output").hook("preAction", async (thisCommand, actionCommand) => {
|
|
9039
9880
|
const command = actionCommand ?? thisCommand;
|
|
9040
9881
|
commandSpans.set(command, startTelemetrySpan(getTelemetryCommandName(command)));
|
|
9882
|
+
await rootCliPreAction(thisCommand, actionCommand);
|
|
9041
9883
|
}).hook("postAction", (_thisCommand, actionCommand) => {
|
|
9042
9884
|
endTelemetrySpan(commandSpans.get(actionCommand));
|
|
9043
9885
|
}).addHelpText("after", `
|