Skip to content

Commit b12129f

Browse files
authored
Update skill and agent (#609)
1 parent 46e0829 commit b12129f

9 files changed

Lines changed: 694 additions & 241 deletions

File tree

.github/workflows/pr.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: Pull Request
22

33
on:
44
pull_request:
5-
types: [opened, edited, reopened, synchronize]
5+
types: [opened, reopened, synchronize]
66
branches: [ main ]
77

88
permissions:

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,9 @@ tools/*
1616
/jscpd
1717
/tmp
1818
/.idea/
19+
20+
.kiro/*
21+
!.kiro/skills/
22+
!.kiro/skills/**
23+
!.kiro/steering/
24+
!.kiro/steering/**
Lines changed: 112 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
name: cfn-lsp-development
3-
description: >
4-
Development workflow for the CloudFormation Language Server. Guides agents through implementation, testing, and PR creation. Use when implementing features, fixing bugs, adding handlers/providers, or making changes to this repository.
3+
description: Development workflow for the AWS CloudFormation Language Server (this repository). Use when implementing features, fixing bugs, adding tests, or making any code change in cloudformation-languageserver. Covers planning, telemetry, build/lint/test verification, and PR conventions.
4+
license: Apache-2.0
55
---
66

77
# CFN LSP Development Workflow
@@ -10,10 +10,51 @@ description: >
1010

1111
These constraints apply to ALL changes in this repository:
1212

13-
- **No backwards-incompatible changes (hard rule)** — Never change or remove existing LSP protocol methods, request types, or response/return types. Additive changes only — breaking the wire contract breaks the already-shipped VS Code and JetBrains clients.
14-
- **Cross-platform** — All changes must work on macOS, Windows, and Linux
15-
- **No database locking** — Never lock LMDB or other shared resources; multiple concurrent LSP connections may exist
16-
- **Performance** — Handlers must respond quickly; avoid blocking the event loop or doing synchronous I/O in request paths. Use `npm run benchmark` to confirm changes haven't regressed latency.
13+
- **No backwards-incompatible changes (hard rule)** — Never change or remove existing LSP protocol methods, request
14+
types, or response/return types. Additive changes only — breaking the wire contract breaks the already-shipped VS Code
15+
and JetBrains clients.
16+
- **Cross-platform** — All changes must work on macOS, Linux, and Windows. The DataStore layer in particular has two
17+
persisted backends (LMDB on macOS / Linux, encrypted file store on Windows or when the `FileDb` feature flag is on);
18+
any persistence change must work against both. See `architecture.md`.
19+
- **No database locking** — Never hold long locks on LMDB or other shared resources; multiple concurrent LSP
20+
connections may exist.
21+
- **Performance** — Handlers must respond quickly; avoid blocking the event loop or doing synchronous I/O in request
22+
paths. Use `npm run benchmark` to confirm changes haven't regressed latency.
23+
24+
## Repository Layout
25+
26+
You are working inside the `cloudformation-languageserver` repo. Source lives in `src/`, tests mirror the source tree
27+
under `tst/`. See `.kiro/steering/structure.md` for directory-level guidance and `.kiro/steering/architecture.md` for
28+
the component / handler model.
29+
30+
## Scratch Files
31+
32+
Put scratch files, debug scripts, manual repro templates, ad-hoc benchmark scripts, and any other throwaway artifacts
33+
under `tmp/` at the repo root. `tmp/` (and `tmp-node-modules/`, `tmp-tst/`) is `.gitignore`d, so it will never be
34+
committed accidentally. Do **not** scatter scratch files across `src/`, `tst/`, or the workspace root.
35+
36+
## Code Quality
37+
38+
Hold every change in this repo to a senior-engineer standard. The full rule sets are bundled with this skill — read
39+
them when you write or modify code:
40+
41+
- Source code: [`references/source-code-rules.md`](references/source-code-rules.md) — naming, reuse, architecture,
42+
SOLID, immutability, error handling, null/thread safety, performance, dependency discipline, and public-API
43+
compatibility.
44+
- Test code: [`references/test-code-rules.md`](references/test-code-rules.md) — meaningful coverage, AAA structure,
45+
mock quality, determinism, behavior-not-implementation, edge / failure paths.
46+
47+
The two rules with the highest leverage in this repository:
48+
49+
- **Reuse `src/utils/` and `tst/utils/` before writing new helpers.** Search both directories first
50+
(`MockServerComponents`, `TemplateBuilder`, `MockContext`, `Expect`, `SchemaUtils`, `Delayer`, `Retry`,
51+
`AwsErrorMapper`, `PathUtils`, `String`, `TypeCheck`, etc.). If a needed helper doesn't exist, add it to the
52+
appropriate `utils/` directory rather than co-locating it in a feature folder, so the next caller can find it.
53+
- **Respect the layer model.** Handlers stay thin and delegate to a Component or Service (see `architecture.md`).
54+
Do not let handlers do AWS I/O, file I/O, or schema parsing directly.
55+
56+
Apply both rule sets even when the user doesn't mention "quality" or "best practices" — they are the contract for
57+
contributing to this repo.
1758

1859
## Developer Tools
1960

@@ -23,7 +64,8 @@ These constraints apply to ALL changes in this repository:
2364
npm run debug-tree -- --file <template.yaml|json>
2465
```
2566

26-
Runs `tools/debug_tree.ts` — builds a `SyntaxTree`, traverses every node, and emits `Context` objects at key positions. The fastest way to diagnose parse/context problems when working on completion, hover, or definition.
67+
Runs `tools/debug_tree.ts` — builds a `SyntaxTree`, traverses every node, and emits `Context` objects at key positions.
68+
The fastest way to diagnose parse / context problems when working on completion, hover, or definition.
2769

2870
### Benchmarking performance
2971

@@ -32,114 +74,104 @@ npm run benchmark # default run
3274
npm run benchmark -- --iterations 100 --templates ./tst/resources --output results.md
3375
```
3476

35-
Runs `tools/benchmark.ts` — measures syntax-tree creation and context-lookup latency across iterations. Use this to verify the Performance constraint above.
36-
37-
### Stability testing
38-
39-
```bash
40-
npm run test:stability
41-
```
42-
43-
Runs `tools/stability/` — long-running tests that exercise completion and hover under sustained load.
77+
Runs `tools/benchmark.ts` — measures syntax-tree creation and context-lookup latency across iterations. Use this to
78+
verify the Performance constraint above.
4479

4580
## Workflow
4681

4782
### Step 1: Research
4883

49-
Before making changes, locate or set up local workspaces for affected packages:
50-
51-
1. **Search parent directories** for existing checkouts:
52-
- Look for `cloudformation-languageserver/` in `../`, `../../`, etc.
53-
- Check `LOCAL_TESTING_SERVER_PATH` env var for an existing server bundle path
54-
55-
2. **If not found**, ask the user:
56-
- "Do you have a local checkout? If so, provide the path."
57-
- "Should I clone the repository?"
58-
59-
3. **Set up missing workspace:**
60-
- `git clone https://github.com/aws-cloudformation/cloudformation-languageserver.git`
61-
62-
Next, browse the source code.
63-
- Identify conventions: file naming, class structure, test patterns
64-
- Read files relevant to the task to understand wiring (imports, exports, registration)
65-
- Check `.kiro/steering/` for architecture guidance when needed
84+
Apply "Explore the Project Before Writing" from [`references/source-code-rules.md`](references/source-code-rules.md):
85+
read the relevant feature directory (`src/<feature>/`), its tests under `tst/`, and the shared helpers in
86+
`src/utils/` and `tst/utils/` before designing the change. Use `.kiro/steering/architecture.md` and
87+
`.kiro/steering/structure.md` when you need a map of where things live.
6688

6789
### Step 2: Plan
6890

6991
Before writing code:
7092

71-
1. Read the task requirements
72-
2. Identify affected source directories (see `structure.md` in steering)
73-
3. Create an implementation plan
74-
a. Create a markdown file at the workspace root: `./<feature-or-fix-name>-plan.md`
75-
The plan MUST include:
76-
- **Summary** — what is being implemented and why
77-
- **Affected packages** — which packages need changes
78-
- **Approach** — high-level design decisions
79-
- **Task checklist** — every discrete task as a checkbox item, ordered by execution sequence
80-
81-
4. Present the plan to the user and ask them to review it
82-
5. **STOP and wait for explicit user approval before writing any code**
83-
6. As tasks are completed, update the checklist in the plan file (check off items)
93+
1. Identify the affected source directories (see `structure.md`).
94+
2. Create an implementation plan as `tmp/<feature-or-fix-name>-plan.md` (under the gitignored `tmp/`), including:
95+
- **Summary** — what is being implemented and why
96+
- **Affected files / directories**
97+
- **Approach** — high-level design decisions and any tradeoffs
98+
- **Task checklist** — every discrete task as a checkbox item, ordered by execution sequence
99+
3. Present the plan to the user.
100+
4. **STOP and wait for explicit user approval before writing any code.**
101+
5. As tasks are completed, check off items in the plan file.
84102

85103
### Step 3: Implement
86104

87-
1. Create a local branch for your changes
88-
2. Write unit tests that define expected behavior (they should fail initially)
89-
3. Implement the minimum code to make tests pass
90-
4. Follow existing patterns in the relevant feature directory
91-
5. Refactor for clarity while keeping tests green
105+
1. Create a local branch for your changes.
106+
2. Write unit tests that define the expected behavior (they should fail initially).
107+
3. Implement the minimum code to make tests pass.
108+
4. Follow existing patterns in the relevant feature directory.
109+
5. Refactor for clarity while keeping tests green.
110+
111+
For new persisted state, decide whether it belongs in `PersistedStores` (survives editor restart) or as a non-persisted
112+
`MemoryStore`. See `src/datastore/DataStore.ts`.
92113

93114
### Step 4: Telemetry
94115

95-
Wire telemetry for new handlers using `ScopedTelemetry` public methods:
116+
Wire telemetry on new handlers and any code path you care about observing in production.
117+
118+
**Prefer the decorators in `src/telemetry/TelemetryDecorator.ts`** over direct `ScopedTelemetry` calls — they keep
119+
metric scopes consistent and avoid boilerplate:
96120

97121
```typescript
98-
// Measure duration + count + fault for a handler
99-
const result = await this.telemetry.measureAsync('HandlerName', async () => {
100-
/* handler logic */
101-
});
122+
import {Telemetry, Track} from '../telemetry/TelemetryDecorator';
123+
import {ScopedTelemetry} from '../telemetry/ScopedTelemetry';
124+
125+
@Telemetry({scope: 'CompletionRouter'})
126+
export class CompletionRouter {
127+
// Field is injected by @Telemetry — no constructor wiring needed
128+
private readonly telemetry!: ScopedTelemetry;
129+
130+
@Track({name: 'getCompletions', captureErrorAttributes: true})
131+
public async getCompletions(params: CompletionParams): Promise<CompletionItem[]> {
132+
/* handler logic */
133+
}
134+
}
135+
```
102136

103-
// Track execution with response tracking
104-
const result = this.telemetry.trackExecution('HandlerName', () => {
105-
/* handler logic */
106-
});
137+
`@Track` emits `{Name}.count`, `{Name}.duration`, and `{Name}.fault` for each invocation. Use `@Telemetry` once per
138+
class to bind a scope; use `@Track` on each method you want measured.
107139

108-
// Count-only (no duration)
109-
const result = await this.telemetry.countExecutionAsync('HandlerName', async () => {
110-
/* handler logic */
140+
Use the imperative `ScopedTelemetry` helpers only when you need to instrument something a decorator can't reach
141+
(an inline closure, a lambda, a non-class function). The available helpers are:
142+
143+
```typescript
144+
// Inline async — emits {Name}.count, {Name}.duration, {Name}.fault
145+
const result = await this.telemetry.measureAsync('Subtask', async () => {
146+
/* logic */
111147
});
112148
```
113149

114-
**Metrics emitted by these methods:**
115-
- `{Name}.count` — invocation count
116-
- `{Name}.duration` — response time (measure/trackExecution only)
117-
- `{Name}.fault` — unhandled exception
118-
119150
### Step 5: Verify
120151

121152
Before creating a PR, **all of these must pass**:
122153

123154
```bash
124-
npm run build # TypeScript compilation
125-
npm run lint # Linting (zero warnings)
126-
npm run test # Unit tests + coverage (thresholds: 88% statements, 82% branches, 90% functions, 88% lines)
155+
npm run build # TypeScript compilation
156+
npm run lint # Linting (zero warnings — `--max-warnings 0`)
157+
npm run test # Unit + integration + e2e + coverage
127158
```
128159

129-
Coverage runs automatically with `npm run test` (`coverage.enabled: true` in `vitest.config.ts`).
160+
Coverage runs automatically with `npm run test` and thresholds are enforced from `vitest.config.ts`.
161+
If you only need to run a subset while iterating: `npm run test:unit` or `npm run test:integration`.
162+
Use `npm run lint:fix` for auto-fixable lint violations.
130163

131164
### Step 6: Client-Side Changes
132165

133-
Some changes require corresponding updates in the editor clients (e.g., features that need UX work). See the client repositories for their own build/test/contribution guides:
166+
Some changes (new commands, new code lens actions, new UI surfaces) require corresponding updates in the editor
167+
clients. See the client repositories for their own build / test / contribution guides:
134168

135-
| Client | Repository | CloudFormation path |
136-
|--------|-----------|-------------------|
137-
| VS Code | [`aws/aws-toolkit-vscode`](https://github.com/aws/aws-toolkit-vscode) (branch: `master`) | `packages/core/src/awsService/cloudformation/` |
169+
| Client | Repository | CloudFormation path |
170+
|-----------|----------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------|
171+
| VS Code | [`aws/aws-toolkit-vscode`](https://github.com/aws/aws-toolkit-vscode) (branch: `master`) | `packages/core/src/awsService/cloudformation/` |
138172
| JetBrains | [`aws/aws-toolkit-jetbrains`](https://github.com/aws/aws-toolkit-jetbrains) (branch: `main`) | `plugins/toolkit/jetbrains-core/src/software/aws/toolkits/jetbrains/services/cfnlsp` |
139173

140174
### Step 7: PR
141175

142-
- Ensure new code has unit tests (and integration tests for handlers)
143-
- Confirm no breaking API changes
144-
- Confirm cross-platform compatibility (no platform-specific paths, no OS-specific APIs without fallbacks)
145-
- Note in PR description if client-side changes are also needed
176+
Re-read the **Constraints** section above and confirm none are violated. Note in the PR description if matching
177+
client-side changes are needed.

0 commit comments

Comments
 (0)