Skip to content

Commit 6b157f1

Browse files
authored
Add AGENTS.md (microsoft#5765)
* Add AGENTS.md * More explicit on new packages * Add `HUMAN.md` * Rename to 100/200/300 * Quote valibot * Use emoji * Rename Platform Level to Platform Complexity * Better formatting
1 parent f9d0970 commit 6b157f1

File tree

9 files changed

+174
-0
lines changed

9 files changed

+174
-0
lines changed

AGENTS.md

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# AGENTS.md for Bot Framework Web Chat
2+
3+
## Coding
4+
5+
### General
6+
7+
- Unless stated otherwise, avoid Node.js
8+
- Apply our latest coding style to every file changed
9+
- Avoid spaghetti code: on new feature with a similar existing feature, refactor existing one before writing new feature
10+
- This does not applies to test code
11+
- Avoid global pollution, do not modify `window` object
12+
- Markdown are always space-indented with 3 spaces
13+
- Use `/prettierrc.yml` to format
14+
- Sort names in property bags
15+
- Avoid one-use variable, inline them instead
16+
- More new lines to separate code with different responsibilities
17+
- Multiple lines of code that can run in random order, put them into a group, no need new line between them
18+
- Otherwise, lines of code that depends on each other in a specific order, separate them with new line
19+
- Prefer `&&` over if-statement if it is a oneliner
20+
- Importing relative file should always include file extension
21+
- Prefer truthy/false check like `!array.length` over `array.length === 0`
22+
- Prefer `numValue` over `valueCount` for "how many values are there"
23+
- Prefer uppercase for acronyms instead of Pascal case, e.g. `getURL()` over `getUrl()`
24+
- The only exception is `id`, e.g. `getId()` over `getID()`
25+
- Use fewer shorthands, only allow `min`, `max`, `num`
26+
27+
### Design
28+
29+
- Use immutability as much as possible, add `object.freeze()`
30+
- Follow W3C convention for API design
31+
- Extends `EventTarget` when eventing is needed, do not use Node.js `on`/`off`
32+
- Consider `IntersectionObserver`-like pattern for allow userland to subscribe to live changes
33+
- Allow ESNext code that is polyfilled by `core-js-pure` or `iter-fest` package
34+
35+
### Typing
36+
37+
- TypeScript is best-effort checking, use `valibot` for strict type checking
38+
- Use `valibot` for runtime type checker, never use `zod`
39+
- Assume all externally exported functions will receive unsafe/invalid input, always check with `valibot`
40+
- Avoid `any`
41+
- Avoid `as`, use `valibot` instead
42+
- If absolutely needed, use `satisifes X as Y` to make sure it is `X` before force casting to `Y`
43+
- Use as few `unknown` as possible
44+
- All optional properties must be `undefined`-able, i.e. use `value?: number | undefined` over `value?: number`
45+
- For functions exported outside of current file, make sure all arguments and return value are typed
46+
- If need to look inside the object to check for types, use `valibot`
47+
- E.g. `if (obj && typeof obj === 'object' && 'value' in obj && typeof obj.value === 'string')` should be replaced with `safeParse(object({ value: string }), obj).success`
48+
- Use `{ readonly value: string }` instead of `Readonly<{ value: string }>`
49+
- Use as much `readonly` as possible
50+
51+
### React template
52+
53+
```tsx
54+
import { reactNode, validateProps } from '@msinternal/botframework-webchat-react-valibot';
55+
import React from 'react';
56+
import { number, object, pipe, readonly } from 'valibot';
57+
58+
// Use valibot to validate props.
59+
const MyComponentPropsSchema = pipe(
60+
object({
61+
children: optional(reactNode())
62+
}),
63+
readonly()
64+
);
65+
66+
type MyComponentProps = InferInput<typeof MyComponentPropsSchema>;
67+
68+
// Use big function instead of arrow function.
69+
function MyComponent(props: MyComponentProps) {
70+
// Call `validateProps` to get a validated props.
71+
const { children } = validateProps(MyComponentPropsSchema, props);
72+
73+
// Use `<>` instead of `<Fragment>`.
74+
// Never export `children` by itself, always wrap with `<>`.
75+
return <>{children}</>;
76+
}
77+
78+
// Set `displayName`.
79+
MyComponent.displayName = 'MyComponent';
80+
81+
// Export as memoized/exotic component, export as default.
82+
export default memo(MyComponent);
83+
84+
// Export both schema and typing.
85+
export { MyComponentPropsSchema, type MyComponentProps };
86+
```
87+
88+
## Testing instructions
89+
90+
- Practice test-driven development
91+
- Build and run Docker to host WebDriver-controlled browser instances
92+
- Build container by `docker compose -f docker-compose-wsl2.yml build --build-arg REGISTRY=mcr.microsoft.com`
93+
- Start container by `docker compose -f docker-compose-wsl2.yml up --detach --scale chrome=2`
94+
- Run `curl http://localhost:4444/wd/hub/status` and wait until `.value.ready` become `true`
95+
- Run `npm test`, or `npm test -- --testPathPattern test-html-file.html` to focus on one
96+
- Test files are HTML files under `/__tests__/html2/`, they are not JS
97+
- Follow other HTML files under the same folder on how to write tests
98+
- Page conditions, page elements, and page objects can be found at `/packages/test/page-object/src/globals`
99+
- Use `expect` instead of `assert`
100+
- Use `@testduet/given-when-then` package instead of xUnit style `describe`/`before`/`test`/`after`
101+
- Prefer integration/end-to-end testing than unit testing
102+
- Use as realistic setup as possible, such as using `msw` than mocking calls
103+
104+
## PR instructions
105+
106+
- Run new test and all of them must be green
107+
- Run `npm run precommit` to make sure it pass all linting process
108+
- Add changelog entry to `CHANGELOG.md`, follow our existing format

HUMAN.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# HUMAN.md for Bot Framework Web Chat
2+
3+
## Coding
4+
5+
### Package management
6+
7+
- When adding dependencies, use `npm install`
8+
- Do not add it to workspace root
9+
- If it is an existing package, must use consistent version: either use existing version for the package or consider bumping every dependents to latest
10+
- Unless stated otherwise, avoid Node.js packages or polyfills
11+
- Use `ReadableStream`, `WritableStream`, `TransformStream`, instead of Node.js `buffer`
12+
- Use Web Cryptography instead of Node.js `crypto`
13+
- Do not use `fs`-like or `net`-like packages
14+
- Do not use any Browserify-like packages
15+
- Unless stated otherwise, verify newly added packages and transient packages must be either platform-neutral, browser-specific, or React-specific
16+
- Do not add external/publishing packages unless explicitly requested
17+
- Always prefix internal/non-publishing packages with `@msinternal/` to prevent package squatting
18+
19+
### Platform complexity level
20+
21+
This table list expect platform complexity in the running environment.
22+
23+
| Package family | Platform complexity | Neutral | React Native | Full Browser | React | Node.js |
24+
| ------------------------ | ------------------- | ------- | ------------ | ------------ | ----- | ------- |
25+
| `base` | 100 - Neutral ||||||
26+
| `core` | 100 - Neutral ||||||
27+
| `api` | 200 - React Native ||||||
28+
| `react-*` | 200 - React Native ||||||
29+
| `redux-*` | 200 - React Native ||||||
30+
| `component` | 300 - React (HTML) ||||||
31+
| `bundle` | 300 - React (HTML) ||||||
32+
| `fluent-theme`/`*-theme` | 300 - React (HTML) ||||||
33+
| `support` | 100 - Neutral ||||||
34+
35+
Descriptions of platform complexity:
36+
37+
- 100 - Neutral: JavaScript engine only, logic only, UI-agnostic, minimal
38+
- 200 - React Native: browser-like but not full browser, mobile app or web app
39+
- 300 - React (HTML): full browser, web app

packages/api-graph/AGENTS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# AGENTS.md
2+
3+
Refer to `/packages/api/AGENTS.md`.

packages/api-middleware/AGENTS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# AGENTS.md
2+
3+
Refer to `/packages/api/AGENTS.md`.

packages/api/AGENTS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# AGENTS.md
2+
3+
## Coding
4+
5+
- The code could run on React Native, no browser-specific technologies

packages/base/AGENTS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# AGENTS.md
2+
3+
## Coding
4+
5+
- Stay platform neutral, no browser technologies, no Node.js, no React

packages/core-debug-api/AGENTS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# AGENTS.md
2+
3+
Refer to `/packages/core/AGENTS.md`.

packages/core-graph/AGENTS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# AGENTS.md
2+
3+
Refer to `/packages/core/AGENTS.md`.

packages/core/AGENTS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# AGENTS.md
2+
3+
## Coding
4+
5+
- Stay platform neutral, no browser technologies, no Node.js, no React

0 commit comments

Comments
 (0)