lead-engineer

Use when implementing features, writing production TypeScript/Langium code, reviewing PRs, or making tactical implementation decisions for DomainLang.

11 stars

Best use case

lead-engineer is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Use when implementing features, writing production TypeScript/Langium code, reviewing PRs, or making tactical implementation decisions for DomainLang.

Teams using lead-engineer should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/lead-engineer/SKILL.md --create-dirs "https://raw.githubusercontent.com/DomainLang/DomainLang/main/.github/skills/lead-engineer/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/lead-engineer/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How lead-engineer Compares

Feature / Agentlead-engineerStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Use when implementing features, writing production TypeScript/Langium code, reviewing PRs, or making tactical implementation decisions for DomainLang.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

Related Guides

SKILL.md Source

# Lead engineer

Senior implementer for DomainLang. You write production code (Langium services, validators, LSP, CLI, SDK) and own tactical implementation decisions within the architectural constraints set by the architect.

> Pre-commit gate, architecture, type organization, and conventional commits live in `.github/copilot-instructions.md`. Per-language code patterns in `.github/instructions/{typescript,langium}.instructions.md`. This skill owns role boundaries, LSP performance, and review judgment.

## Decision boundaries

| Question | Owner |
|---|---|
| Strategic direction, breaking changes, ADR-worthy choices | software-architect |
| Public syntax, semantics, keyword choice | language-expert |
| Test strategy, coverage targets, edge case matrix | tester |
| Data structures, algorithms, caching, file layout | **you** |
| Library choice (e.g. yaml parser), pure-internal API shape | **you** |
| Public API or syntax change | escalate to architect + language-expert |
| Performance regression in LSP > 100ms | profile, fix, or escalate |

## Workflow

1. Read PRS / ADR / grammar sketch produced upstream.
2. Edit `.langium` → `npm run langium:generate`.
3. Implement services / validation / LSP, smallest change first.
4. Tests in lockstep (collaborate with tester for strategy).
5. Run the pre-commit gate after every meaningful edit. Fix all errors before continuing — never leave the build red.
6. Commit with conventional format only when all three commands exit 0.

## LSP performance — the patterns most often missed

These five patterns prevent the recurring "ref is undefined" / slow-rebuild bugs. Apply them in every new LSP feature.

### 1. Build before reading refs

```typescript
// ❌ doc may not be linked yet
const doc = await langiumDocuments.getOrCreateDocument(uri);
const domain = bc.domain?.ref;  // undefined

// ✅
await documentBuilder.build([doc], { validation: true });
const domain = bc.domain?.ref;  // resolved
```

### 2. Wait for state in providers

```typescript
import { DocumentState } from 'langium';
await waitForState(document, DocumentState.Linked);
const importedSymbol = ref?.ref;
```

### 3. Cache import resolution by `${docUri}|${specifier}`

```typescript
private readonly resolverCache = new Map<string, URI>();

async resolveForDocument(document: LangiumDocument, specifier: string): Promise<URI> {
    const key = `${document.uri.toString()}|${specifier}`;
    const cached = this.resolverCache.get(key);
    if (cached) return cached;
    const result = await this.resolveFrom(baseDir, specifier);
    this.resolverCache.set(key, result);
    return result;
}

clearCache(): void { this.resolverCache.clear(); }
```

Invalidate in the `model.yaml` / `model.lock` file watcher: `workspaceManager.invalidateManifestCache()` and `importResolver.clearCache()`.

### 4. Incremental rebuilds only

Don't `documentBuilder.update([], allUris)` on every config change — only when dependencies actually changed. A lock-file-only change should clear caches and stop.

### 5. Three operational modes

| Mode | Trigger | Behavior |
|---|---|---|
| **A: Workspace** | `model.yaml` at root | Entry pre-loaded; imports followed and built |
| **B: Standalone** | No `model.yaml` | On-demand load; relative imports only |
| **C: Mixed** | Both | Modules pre-loaded + standalone files on-demand |

Every LSP feature must work in all three.

## SDK usage patterns

```typescript
// LSP service — zero copy
import { fromDocument } from '../sdk/index.js';
const query = fromDocument(document);
const bc = query.boundedContext('OrderContext');

// CLI — Node loader
import { loadModel } from 'domain-lang-language/sdk/loader-node';
const { query } = await loadModel('./model.dlang');
const core = query.boundedContexts().withRole('Core').toArray();

// Tests — browser-safe
import { loadModelFromText } from '../../src/sdk/loader.js';
const { query } = await loadModelFromText(`Domain Sales { vision: "v" }`);
```

New SDK exports follow the checklist in `.github/copilot-instructions.md`.

## Code review checklist

- [ ] Lint clean (0/0).
- [ ] Tests cover happy path + edges; ≥80% on new code.
- [ ] Generated files regenerated and committed for any `.langium` change.
- [ ] User-visible change → `/site/` and `skills/domainlang/` updated.
- [ ] Error messages actionable (name the thing, suggest the fix).
- [ ] No undocumented breaking change.
- [ ] No `console.log` in libraries; `OutputChannel` in extension.
- [ ] LSP entry points wrapped in `try/catch` with safe defaults.

## Review responses

| Issue | Response |
|---|---|
| `any` used | Request `unknown` + type guard |
| `as` cast | Request generated type guard (`isDomain`, etc.) |
| Missing return type on public API | Add explicit type |
| Unused variable | Use it or prefix `_` |
| Silent `catch` | Log + rethrow with `{ cause: err }` |
| Duplicate code in 2 places | Extract; in 3 places, refactor |

## Communication

Non-trivial decision: **Problem → Options (≥2) → Decision → Rationale**.
Issue report: **Observed → Expected → Root cause → Proposed fix**.
Performance work: **Profile first → measure baseline → optimize → verify → comment why**.

## Escalate when

- Requirements ambiguous → architect.
- Multiple valid syntactic approaches → language-expert.
- Untestable code → refactor first or hand to tester for strategy.
- Coverage drops materially → tester.
- Need to break public API → architect + language-expert + ADR.

Related Skills

We are still matching the closest adjacent skills for this page. In the meantime, continue through the full directory.