Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions cli/src/commands/code-search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,7 @@ export function registerCodeSearchCommand(program: Command, context: CliContext)
.option('--json', 'Output raw JSON instead of formatted text.')
.action(async (query: string, options: CodeSearchCommandOptions) => {
const endpoint = resolveEndpoint(program.opts<{ endpoint?: string }>().endpoint, context.env);
const client = context.createClient({
endpoint,
clientName: 'mslearn',
clientVersion: context.version,
});
const client = context.createClient({ endpoint });

try {
const payload = await client.searchCodeSamples(query, options.language);
Expand Down
8 changes: 2 additions & 6 deletions cli/src/commands/doctor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,13 @@ export function registerDoctorCommand(program: Command, context: CliContext): vo
async function runDoctorChecks(endpoint: string, context: CliContext): Promise<DoctorReport> {
const runtimeVersion = process.versions.node;
const runtimeSupported = Number.parseInt(runtimeVersion.split('.')[0] ?? '0', 10) >= 22;
const reachability = await probeEndpoint(endpoint, context.fetchImpl);
const reachability = await probeEndpoint(endpoint);
const errors: string[] = [];
const tools: DoctorReport['tools'] = {};
let connected = false;
let discovered = false;

const client = context.createClient({
endpoint,
clientName: 'mslearn',
clientVersion: context.version,
});
const client = context.createClient({ endpoint });

try {
const mapping = await client.getToolMapping(true);
Expand Down
6 changes: 1 addition & 5 deletions cli/src/commands/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,7 @@ export function registerFetchCommand(program: Command, context: CliContext): voi
.action(async (url: string, options: FetchCommandOptions) => {
const endpoint = resolveEndpoint(program.opts<{ endpoint?: string }>().endpoint, context.env);
const normalizedUrl = normalizeUrl(url);
const client = context.createClient({
endpoint,
clientName: 'mslearn',
clientVersion: context.version,
});
const client = context.createClient({ endpoint });

try {
const markdown = await client.fetchDocument(normalizedUrl);
Expand Down
6 changes: 1 addition & 5 deletions cli/src/commands/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,7 @@ export function registerSearchCommand(program: Command, context: CliContext): vo
.option('--json', 'Output raw JSON instead of formatted text.')
.action(async (query: string, options: SearchCommandOptions) => {
const endpoint = resolveEndpoint(program.opts<{ endpoint?: string }>().endpoint, context.env);
const client = context.createClient({
endpoint,
clientName: 'mslearn',
clientVersion: context.version,
});
const client = context.createClient({ endpoint });

try {
const payload = await client.searchDocs(query);
Expand Down
8 changes: 5 additions & 3 deletions cli/src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ export interface CliContext {
version: string;
writeOut: (value: string) => void;
writeErr: (value: string) => void;
fetchImpl: typeof fetch;
createClient: (options: LearnClientOptions) => LearnCliClientLike;
}

Expand All @@ -19,7 +18,10 @@ export function createDefaultContext(version: string): CliContext {
writeErr: (value) => {
process.stderr.write(value);
},
fetchImpl: globalThis.fetch.bind(globalThis) as typeof fetch,
createClient: (options) => createLearnCliClient(options),
createClient: (options) =>
createLearnCliClient({
clientVersion: version,
...options,
}),
};
}
8 changes: 2 additions & 6 deletions cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,8 @@ export function createProgram(context: CliContext): Command {
.addOption(new Option('--endpoint <url>', 'Override the Learn MCP endpoint for this command.').hideHelp())
.showHelpAfterError()
.configureOutput({
writeOut: (value) => {
context.writeOut(value);
},
writeErr: (value) => {
context.writeErr(value);
},
writeOut: context.writeOut,
writeErr: context.writeErr,
outputError: (value, write) => {
write(value);
},
Expand Down
6 changes: 4 additions & 2 deletions cli/src/mcp/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { OperationError } from '../utils/errors.js';
import { createFileLearnSessionCacheStore, type LearnSessionCacheStore } from './cache.js';
import { discoverLearnTools, type DiscoveredLearnTools, type ListedTool } from './tool-discovery.js';

const DEFAULT_CLIENT_NAME = 'learn-cli';

export interface LearnClientOptions {
endpoint: string;
clientName?: string;
Expand Down Expand Up @@ -43,7 +45,7 @@ interface TransportLike {
close(): Promise<void>;
}

export async function probeEndpoint(endpoint: string, fetchImpl: typeof fetch): Promise<ReachabilityReport> {
export async function probeEndpoint(endpoint: string, fetchImpl: typeof fetch = globalThis.fetch): Promise<ReachabilityReport> {
try {
const response = await fetchImpl(endpoint, {
method: 'GET',
Expand Down Expand Up @@ -271,7 +273,7 @@ class LearnCliClient implements LearnCliClientLike {
private createDefaultSdkClient(): SdkClientLike {
return new Client(
{
name: this.options.clientName ?? 'mslearn',
name: this.options.clientName ?? DEFAULT_CLIENT_NAME,
version: this.options.clientVersion ?? '0.1.0',
},
{
Expand Down
1 change: 0 additions & 1 deletion cli/test/unit/cli.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ function createTestContext(client: LearnCliClientLike): {
writeErr: (value) => {
stderr.push(value);
},
fetchImpl: vi.fn(async () => new Response(null, { status: 405 })) as unknown as typeof fetch,
createClient: () => client,
},
stdout,
Expand Down
4 changes: 2 additions & 2 deletions skills/microsoft-code-reference/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ For simple lookups, step 1 alone may suffice. For complex API usage, complete al

## CLI Alternative

If the Learn MCP server is not available, use the `mslearn` CLI via Bash instead:
If the Learn MCP server is not available, use the `mslearn` CLI from the command line instead:

```bash
```sh
# Run directly (no install needed)
npx @microsoft/learn-cli search "BlobClient UploadAsync Azure.Storage.Blobs"

Expand Down
4 changes: 2 additions & 2 deletions skills/microsoft-docs/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ Fetch after search when:

## CLI Alternative

If the Learn MCP server is not available, use the `mslearn` CLI via Bash instead:
If the Learn MCP server is not available, use the `mslearn` CLI from the command line instead:

```bash
```sh
# Run directly (no install needed)
npx @microsoft/learn-cli search "azure functions timeout"

Expand Down
4 changes: 2 additions & 2 deletions skills/microsoft-skill-creator/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ skill-name/

### CLI Alternative

If the Learn MCP server is not available, use the `mslearn` CLI via Bash instead:
If the Learn MCP server is not available, use the `mslearn` CLI from the command line instead:

```bash
```sh
# Run directly (no install needed)
npx @microsoft/learn-cli search "semantic kernel overview"

Expand Down
Loading