In the DSH development workflow, code generated by agents requires immediate validation. Manual checking is inefficient and can easily miss details. dsh-syntax-checker provides a syntax checking and automatic repair solution based on Tree-sitter and Ruff, supporting JS/TS/YAML/Python.
Installation and Activation¶
The plugin is published to npm (scoped package @kiwifruit/dsh-syntax-checker). When installing, you must specify the --profile parameter.
dsh plugin --profile web add @kiwifruit/dsh-syntax-checker@0.1.0
Installation notes:
1. pnpm 24-hour cooldown limit: Bare package names that resolve to latest are subject to this limit. If you need to install immediately after a release, use an exact version number (for example, @0.1.0); exact versions are automatically exempt from the cooldown period.
2. Git source: git install pulls source code rather than build artifacts. This package includes a prepare script, but pnpm >=10 refuses to run prepare for git dependencies by default. If you install using github:, you must allow it in pnpm-workspace.yaml:
allowBuilds:
dsh-syntax-checker: true
Or use the npm package directly.
The activation chain after installation is: dsh plugin runs pnpm add to install the package, then reconciles dsh.profile.bundles against the installed state. At startup, the bundle layer reads cordis.patch.yml and participates in composition. After adding or removing a bundle, restart the DSH process.
Core Features¶
The plugin is implemented with the following engines and rules:
- Bracket matching: Supports matching
(),[],{}, and brackets inside string literals. - Invisible characters: Detects hidden characters such as zero-width spaces, BOM, and bidirectional control characters.
- Syntax errors: Parses JS/TS/YAML with
web-tree-sitterand Python withruff. - Trailing whitespace: Checks using general rules.
- YAML-specific checks: Detects duplicate keys and indentation errors caused by tab characters.
- Automatic repair: Uses Ruff’s
fix.editsand the edit applier, iterating until fixes converge.
Usage Examples¶
The plugin supports two modes of operation: DSH plugin mode and standalone mode.
1. Using It as a DSH Plugin¶
After installation, the model can invoke it through the syntax_check tool, and other plugins can call the syntaxChecker service.
Confirm the tool list with the model:
dsh --profile web --dump-config | tail -20
Tool invocation parameters:
* filePath: file path
* sourceText: source text
* language?: language identifier (optional)
* fix?: whether to apply automatic repairs (optional)
2. Standalone HTTP Service¶
npm install
npm run build
npm start # 生产:node dist/api/server.js
npm run dev # 开发:tsx src/api/server.ts
Main interfaces provided:
| Method | Path | Purpose |
|---|---|---|
| GET | /health |
Health check (including a ruff availability probe) |
| POST | /api/v1/lint |
Single-file syntax checking |
| POST | /api/v1/lint/batch |
Batch checking |
| POST | /api/v1/fix |
Automatic repair, returning repaired source code |
3. Embedding as a Library¶
Import it directly in a Node.js project:
import { createSyntaxChecker } from '@kiwifruit/dsh-syntax-checker';
const checker = createSyntaxChecker(undefined, {
timeoutMs: 30_000,
maxRetries: 2,
policies: { timeout: true, retry: true, observation: true },
});
const result = await checker.lint({
filePath: 'a.py',
sourceText: 'import os\nimport os\n',
});
Configuration¶
Configure plugin parameters in cordis.yml. Note: The config field replaces the entire value, not a deep merge; when overriding it, provide the full object.
| Field | Type | Default | Description |
|---|---|---|---|
timeoutMs |
number | 30000 |
Timeout for a single check (milliseconds); can be overridden per call |
maxRetries |
number | 2 |
Number of retries for transient backend failures |
verbose |
boolean | false |
Whether to log successful events |
policies.timeout |
boolean | true |
Enable the associated timeout policy |
policies.retry |
boolean | true |
Enable the associated retry policy |
policies.observation |
boolean | true |
Enable the associated observation policy |
Notes¶
- Permission risk: Installing a plugin is equivalent to running third-party code. Review the source code before installation, and test unfamiliar plugins in an isolated environment.
- Cordis configuration: After installation, you no longer need to add an entry for this plugin to
cordis.patch.yml; the installation process registers it automatically. - Windows paths: When extracting a path from a
file://URL, usefileURLToPath; otherwise, path errors may occur.