Skip to content

Commit f09caac

Browse files
authored
Merge pull request #4 from posit-dev/merge/1.104.0
Update Copilot for 1.104
2 parents b87121e + 7d7d253 commit f09caac

File tree

794 files changed

+86813
-15776
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

794 files changed

+86813
-15776
lines changed

.esbuild.ts

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ const baseNodeBuildOptions = {
4848
mainFields: ["module", "main"], // needed for jsonc-parser,
4949
define: {
5050
'process.env.APPLICATIONINSIGHTS_CONFIGURATION_CONTENT': '"{}"'
51-
}
51+
},
5252
} satisfies esbuild.BuildOptions;
5353

5454
const nodeExtHostTestGlobs = [
@@ -68,7 +68,7 @@ const testBundlePlugin: esbuild.Plugin = {
6868
return { path: path.resolve(args.path) };
6969
});
7070
build.onLoad({ filter: /[\/\\]test-extension\.ts$/ }, async args => {
71-
let files = await glob(nodeExtHostTestGlobs, { cwd: REPO_ROOT, posix: true });
71+
let files = await glob(nodeExtHostTestGlobs, { cwd: REPO_ROOT, posix: true, ignore: ['src/extension/completions-core/**/*'] });
7272
files = files.map(f => path.posix.relative('src', f));
7373
if (files.length === 0) {
7474
throw new Error('No extension tests found');
@@ -98,7 +98,7 @@ const sanityTestBundlePlugin: esbuild.Plugin = {
9898
return { path: path.resolve(args.path) };
9999
});
100100
build.onLoad({ filter: /[\/\\]sanity-test-extension\.ts$/ }, async args => {
101-
let files = await glob(nodeExtHostSanityTestGlobs, { cwd: REPO_ROOT, posix: true });
101+
let files = await glob(nodeExtHostSanityTestGlobs, { cwd: REPO_ROOT, posix: true, ignore: ['src/extension/completions-core/**/*'] });
102102
files = files.map(f => path.posix.relative('src', f));
103103
if (files.length === 0) {
104104
throw new Error('No extension tests found');
@@ -114,6 +114,23 @@ const sanityTestBundlePlugin: esbuild.Plugin = {
114114
}
115115
};
116116

117+
const importMetaPlugin: esbuild.Plugin = {
118+
name: 'claudeCodeImportMetaPlugin',
119+
setup(build) {
120+
// Handle import.meta.url in @anthropic-ai/claude-code package
121+
build.onLoad({ filter: /node_modules[\/\\]@anthropic-ai[\/\\]claude-code[\/\\].*\.mjs$/ }, async (args) => {
122+
const contents = await fs.promises.readFile(args.path, 'utf8');
123+
return {
124+
contents: contents.replace(
125+
/import\.meta\.url/g,
126+
'require("url").pathToFileURL(__filename).href'
127+
),
128+
loader: 'js'
129+
};
130+
});
131+
}
132+
};
133+
117134
const shimVsCodeTypesPlugin: esbuild.Plugin = {
118135
name: 'shimVsCodeTypesPlugin',
119136
setup(build) {
@@ -160,7 +177,7 @@ const nodeExtHostBuildOptions = {
160177
{ in: './src/sanity-test-extension.ts', out: 'sanity-test-extension' },
161178
],
162179
loader: { '.ps1': 'text' },
163-
plugins: [testBundlePlugin, sanityTestBundlePlugin],
180+
plugins: [testBundlePlugin, sanityTestBundlePlugin, importMetaPlugin],
164181
external: [
165182
...baseNodeBuildOptions.external,
166183
'vscode'
@@ -221,7 +238,7 @@ const nodeSimulationWorkbenchUIBuildOptions = {
221238
'child_process',
222239
'http',
223240
'assert',
224-
]
241+
],
225242
} satisfies esbuild.BuildOptions;
226243

227244
async function typeScriptServerPluginPackageJsonInstall(): Promise<void> {
@@ -326,6 +343,7 @@ async function main() {
326343
`**/*.w.json`,
327344
'**/*.sqlite',
328345
'**/*.sqlite-journal',
346+
'test/aml/out/**'
329347
]
330348
});
331349
rebuild();

.eslint-ignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ test/simulation/fixtures/**
1010
test/scenarios/**
1111
.simulation/**
1212
.eslintplugin/**
13+
chat-lib/**
1314

1415
# ignore vs
1516
src/util/vs/**
@@ -26,3 +27,6 @@ src/extension/typescriptContext/serverPlugin/dist/**
2627

2728
# Ignore Built test-extension
2829
.vscode/extensions/test-extension/dist/**
30+
31+
# Ignore completions-core
32+
src/extension/completions-core/**

.github/copilot-instructions.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,19 @@ This is the **GitHub Copilot Chat** extension for Visual Studio Code - a VS Code
2323
- **Vitest**: Unit testing framework
2424
- **Python**: For notebooks integration and ML evaluation scripts
2525

26+
## Validating changes
27+
28+
You MUST check compilation output before running ANY script or declaring work complete!
29+
30+
1. **ALWAYS** check the `start-watch-tasks` watch task output for compilation errors
31+
2. **NEVER** use the `compile` task as a way to check if everything is working properly
32+
3. **FIX** all compilation errors before moving forward
33+
34+
### TypeScript compilation steps
35+
- Monitor the `start-watch-tasks` task outputs for real-time compilation errors as you make changes
36+
- This task runs `npm: watch:tsc-extension`,`npm: watch:tsc-extension-web`, `npm: watch:tsc-simulation-workbench`, and `npm: watch:esbuild` to incrementally compile the project
37+
- Start the task if it's not already running in the background
38+
2639
## Project Architecture
2740

2841
### Top-Level Directory Structure
@@ -319,3 +332,7 @@ The extension uses numerous proposed VS Code APIs for advanced functionality:
319332
- **Configuration**: Modify `package.json` contributions for VS Code integration
320333

321334
This extension is a complex, multi-layered system that provides comprehensive AI assistance within VS Code. Understanding the service architecture, contribution system, and separation between platform and extension layers is crucial for making effective changes.
335+
336+
## Best Practices
337+
- Use services and dependency injection whenever possible instead of using node or vscode APIs directly. For example, use `IFileService` instead of node's `fs`.
338+
- Always use the URI type instead of using string file paths. There are many helpers available for working with URIs.
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
---
2+
applyTo: '**/*.tsx'
3+
description: Prompt-TSX coding guidelines
4+
---
5+
6+
Guidelines for TSX files using [prompt-tsx](https://github.com/microsoft/vscode-prompt-tsx) focusing on specific patterns and token budget management for AI prompt engineering.
7+
8+
## Component Structure
9+
10+
### Base Pattern
11+
- Extend `PromptElement<Props>` or `PromptElement<Props, State>` for all prompt components
12+
- Props interfaces must extend `BasePromptElementProps`
13+
14+
```tsx
15+
interface MyPromptProps extends BasePromptElementProps {
16+
readonly userQuery: string;
17+
}
18+
19+
class MyPrompt extends PromptElement<MyPromptProps> {
20+
render() {
21+
return (
22+
<>
23+
<SystemMessage priority={1000}>...</SystemMessage>
24+
<UserMessage priority={900}>{this.props.userQuery}</UserMessage>
25+
</>
26+
);
27+
}
28+
}
29+
```
30+
31+
### Async Components
32+
- The `render` method can be async for components that need to perform async operations
33+
- All async work should be done directly in the `render` method
34+
35+
```tsx
36+
class FileContextPrompt extends PromptElement<FileContextProps> {
37+
async render() {
38+
const fileContent = await readFileAsync(this.props.filePath);
39+
return (
40+
<>
41+
<SystemMessage priority={1000}>File content:</SystemMessage>
42+
<UserMessage priority={900}>{fileContent}</UserMessage>
43+
</>
44+
);
45+
}
46+
}
47+
```
48+
49+
## Prompt-Specific JSX
50+
51+
### Line Breaks
52+
- **CRITICAL**: Use `<br />` for line breaks - newlines are NOT preserved in JSX
53+
- Never rely on whitespace or string literal newlines
54+
55+
```tsx
56+
// ✅ Correct
57+
<SystemMessage>
58+
You are an AI assistant.<br />
59+
Follow these guidelines.<br />
60+
</SystemMessage>
61+
62+
// ❌ Wrong - newlines will be collapsed
63+
<SystemMessage>
64+
You are an AI assistant.
65+
Follow these guidelines.
66+
</SystemMessage>
67+
```
68+
69+
## Priority System
70+
71+
### Priority Values
72+
- Higher numbers = higher priority (like z-index)
73+
- Use consistent ranges:
74+
- System messages: 1000
75+
- User queries: 900
76+
- Recent history: 700-800
77+
- Context/attachments: 600-700
78+
- Background info: 0-500
79+
80+
```tsx
81+
<SystemMessage priority={1000}>...</SystemMessage>
82+
<UserMessage priority={900}>{query}</UserMessage>
83+
<HistoryMessages priority={700} />
84+
<ContextualData priority={500} />
85+
```
86+
87+
### Flex Properties for Token Budget
88+
- `flexGrow={1}` - expand to fill remaining token space
89+
- `flexReserve` - reserve tokens before rendering
90+
- `passPriority` - pass-through containers that don't affect child priorities
91+
92+
```tsx
93+
<FileContext priority={70} flexGrow={1} files={this.props.files} />
94+
<History passPriority older={0} newer={80} flexGrow={2} flexReserve="/5" />
95+
```
96+
97+
## Content Handling
98+
99+
### TextChunk for Truncation
100+
- Use `TextChunk` for content that may exceed token budget
101+
- Set `breakOn` patterns for intelligent truncation
102+
103+
```tsx
104+
<TextChunk breakOnWhitespace priority={100}>
105+
{longUserQuery}
106+
</TextChunk>
107+
108+
<TextChunk breakOn=" " priority={80}>
109+
{documentContent}
110+
</TextChunk>
111+
```
112+
113+
### Tag Component for Structured Content
114+
- Use `Tag` for XML-like structured content with attributes
115+
- Validates tag names and properly formats attributes
116+
117+
```tsx
118+
<Tag name="attachments" attrs={{ id: variableName, type: "file" }}>
119+
{content}
120+
</Tag>
121+
```
122+
123+
## References and Metadata
124+
125+
### Prompt References
126+
- Use `<references>` for tracking variable usage
127+
- Use `<meta>` for metadata that survives pruning
128+
129+
```tsx
130+
<references value={[new PromptReference({ variableName })]} />
131+
<meta value={new ToolResultMetadata(id, result)} />
132+
```
133+
134+
### Keep-With Pattern
135+
- Use `useKeepWith()` for content that should be pruned together
136+
137+
```tsx
138+
const KeepWith = useKeepWith();
139+
return (
140+
<>
141+
<KeepWith priority={2}>
142+
<ToolCallRequest>...</ToolCallRequest>
143+
</KeepWith>
144+
<KeepWith priority={1}>
145+
<ToolCallResponse>...</ToolCallResponse>
146+
</KeepWith>
147+
</>
148+
);
149+
```
150+
151+
## Token Budget Management
152+
153+
### Sizing-Aware Rendering
154+
- Use `PromptSizing` parameter for budget-aware content generation
155+
- Implement cooperative token usage
156+
157+
```tsx
158+
async render(sizing: PromptSizing): Promise<PromptPiece> {
159+
const content = await this.generateContent(sizing.tokenBudget);
160+
return <>{content}</>;
161+
}
162+
```
163+
164+
### Performance
165+
- Avoid expensive work in `render` methods when possible
166+
- Cache computations when appropriate
167+
- Use async `render` for all async operations
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
applyTo: '**/*.spec.ts'
3+
description: Vitest unit testing guidelines
4+
---
5+
6+
Guidelines for writing unit tests using Vitest. These tests are `*.spec.ts`
7+
8+
## Best Practices
9+
10+
- Use proper mocks when possible rather than ad-hoc objects injected as dependencies. For example, call `createExtensionUnitTestingServices` to get some mock services, and `IInstantiationService` to create instances with those mocks.
11+
- If there is no preexisting implementation of a service that is appropriate to reuse in the test, then you can create a simple mock or stub implementation.
12+
- Avoid casting to `any` whenever possible.
13+
- When asked to write new tests, add tests for things that are interesting and nontrivial. Don't add a test that just verifies that a setter/getter work.
14+
- Prefer the runTests tool to run tests over a terminal command.

.github/workflows/pr.yml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ jobs:
8989
python-version: '3.12'
9090
architecture: 'x64'
9191

92+
- name: Setup .NET
93+
uses: actions/setup-dotnet@v4
94+
with:
95+
dotnet-version: '10.0'
96+
9297
- name: Install setuptools
9398
run: pip install setuptools
9499

@@ -116,9 +121,6 @@ jobs:
116121
mkdir -p .build/build_cache
117122
tar -czf .build/build_cache/cache.tgz --files-from .build/build_cache_list.txt
118123
119-
- name: Install dotnet cli
120-
run: npm run setup:dotnet
121-
122124
- name: TypeScript type checking
123125
run: npm run typecheck
124126

@@ -171,6 +173,11 @@ jobs:
171173
python-version: '3.12'
172174
architecture: 'x64'
173175

176+
- name: Setup .NET
177+
uses: actions/setup-dotnet@v4
178+
with:
179+
dotnet-version: '10.0'
180+
174181
- name: Install setuptools
175182
run: pip install setuptools
176183

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,4 @@ coverage/
4545
test/simulation/cache/_base.sqlite
4646

4747
test/aml/out
48+
src/extension/completions-core

.mocha-multi-reporters.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
const path = require('path');
6+
7+
// In CI, the name of the NPM command that was run is used to generate a unique
8+
// filename for the JUnit report. The name we give it is then used as the test
9+
// bundle name in DataDog.
10+
const commandToBundleName = {
11+
isolatedProxyTests: 'IsolatedProxy',
12+
reverseProxyTests: 'ReverseProxy',
13+
test: 'LSPClient',
14+
'test:agent': 'Agent',
15+
'test:lib': 'Lib',
16+
'test:lib-e2e': 'LibEndToEnd',
17+
};
18+
19+
const config = {
20+
reporterEnabled: 'spec',
21+
};
22+
23+
if (process.env.CI) {
24+
const bundleName = commandToBundleName[process.env.npm_lifecycle_event] || 'Unit';
25+
config.reporterEnabled += ', mocha-junit-reporter';
26+
config.mochaJunitReporterReporterOptions = {
27+
testCaseSwitchClassnameAndName: true,
28+
testsuitesTitle: `Copilot ${bundleName} Tests`,
29+
mochaFile: path.resolve(__dirname, `test-results-${bundleName}.xml`),
30+
};
31+
}
32+
33+
module.exports = config;

0 commit comments

Comments
 (0)