dsh-embedded-workbench 0.9.1 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en-US.md +60 -60
- package/README.md +49 -48
- package/lib/client.js +56 -1
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +45 -42
- package/skills/keil-mdk-build/SKILL.md +2 -2
- package/src/client.js +56 -1
package/README.en-US.md
CHANGED
|
@@ -4,11 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
[](https://github.com/hashgraph-online/hol-guard)
|
|
6
6
|
|
|
7
|
-
Embedded C/C++ firmware toolbox
|
|
8
|
-
storage, Keil MDK (AC5/AC6), ARMCLANG, HardFault triage, state machines,
|
|
9
|
-
architecture principles, LVGL patterns, and claim fact-checking.
|
|
7
|
+
Embedded C/C++ firmware toolbox: 4 agents and 8 skills covering FreeRTOS, ISR, NVM storage, Keil MDK (AC5/AC6), ARMCLANG, HardFault triage, state machines, architecture principles, and LVGL patterns.
|
|
10
8
|
|
|
11
|
-
**Cross-platform
|
|
9
|
+
**Cross-platform**: works with Claude Code, Codex CLI, Cursor, Kimi CLI, OpenCode, ZCode, and DeepSeek Harness (dsh). Built on the [Agent Skills](https://agentskills.io) open standard.
|
|
12
10
|
|
|
13
11
|
## Components
|
|
14
12
|
|
|
@@ -31,16 +29,16 @@ architecture principles, LVGL patterns, and claim fact-checking.
|
|
|
31
29
|
| `keil-mdk-build` | UV4 CLI, ARM Compiler 5/6, .map analysis, merge/packaging, build diagnostics |
|
|
32
30
|
| `c-cpp-dev` | Code generation, style, memory layout, refactoring for C/C++ |
|
|
33
31
|
| `state-machine-design` | State models, retries, timeouts, transition gates, implementation patterns |
|
|
34
|
-
| `hardfault-triage` | Processor exception triage
|
|
35
|
-
| `fact-check` | Claim-check fallback: verifies API names, file paths, enum values, counts, and mechanism feasibility against the codebase
|
|
32
|
+
| `hardfault-triage` | Processor exception triage: fault registers, stack frames, PC-to-source, root-cause classification |
|
|
33
|
+
| `fact-check` | Claim-check fallback: verifies API names, file paths, enum values, counts, and mechanism feasibility against the codebase. Used by the Plan Verification Gate when logicprobe is not installed. |
|
|
36
34
|
|
|
37
|
-
`logicprobe` (design-doc
|
|
35
|
+
`logicprobe` (design-doc and plan claim verification) was **split out into its own plugin**. See [Other Plugins Recommended](#other-plugins-recommended). When it is not installed, the Plan Verification Gate falls back to this plugin's built-in `fact-check` skill. Only behavioral and model claims degrade to manual confirmation.
|
|
38
36
|
|
|
39
|
-
> The skill content is mostly distilled from the author's personal embedded
|
|
37
|
+
> The skill content is mostly distilled from the author's personal embedded and firmware engineering experience, based on real-world pitfalls and engineering constraints rather than generic model output.
|
|
40
38
|
|
|
41
39
|
### Deep References
|
|
42
40
|
|
|
43
|
-
`embedded-firmware-dev`, `debug-methodology`, `state-machine-design`, and `c-cpp-dev` include in-depth reference material and code examples.
|
|
41
|
+
`embedded-firmware-dev`, `debug-methodology`, `state-machine-design`, and `c-cpp-dev` include in-depth reference material and code examples. The material covers 12 architecture principles, embedded patterns (GIF timer safety, state latches, async lifecycle), LVGL pitfalls, a 7-round iterative debugging case study, state machine implementation patterns, and embedded C specifics (volatile MMIO, linker sections, ISR wrappers).
|
|
44
42
|
|
|
45
43
|
## Installation
|
|
46
44
|
|
|
@@ -58,7 +56,7 @@ Add the marketplace to **Claude Code**'s `~/.claude/settings.json`:
|
|
|
58
56
|
}
|
|
59
57
|
```
|
|
60
58
|
|
|
61
|
-
Then install from CLI:
|
|
59
|
+
Then install from the CLI:
|
|
62
60
|
|
|
63
61
|
```bash
|
|
64
62
|
claude plugin install embedded-workbench@embedded-workbench
|
|
@@ -70,7 +68,7 @@ claude plugin install embedded-workbench@embedded-workbench
|
|
|
70
68
|
git clone https://github.com/AmethystLuna/embedded-workbench.git ~/.claude/plugins/dev/embedded-workbench
|
|
71
69
|
```
|
|
72
70
|
|
|
73
|
-
Then enable in `~/.claude/settings.json`:
|
|
71
|
+
Then enable it in `~/.claude/settings.json`:
|
|
74
72
|
|
|
75
73
|
```json
|
|
76
74
|
{
|
|
@@ -82,11 +80,13 @@ Then enable in `~/.claude/settings.json`:
|
|
|
82
80
|
|
|
83
81
|
## DeepSeek Harness (dsh)
|
|
84
82
|
|
|
85
|
-
Native dsh support ships as a cordis plugin bundle at the repository root
|
|
83
|
+
Native dsh support ships as a cordis plugin bundle at the repository root, declared by `dsh.bundle` in the root `package.json`.
|
|
86
84
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
85
|
+
The bundle does three things:
|
|
86
|
+
|
|
87
|
+
1. **Registers the skills.** They follow the Agent Skills open standard and are discovered as-is by dsh's `skill-filesystem` provider. No extra code.
|
|
88
|
+
2. **Injects the gate.** The first model step of every agent session receives a **trimmed** first-step gate: the Plan Verification Gate plus the context-budget rule. The `enabled` key controls it, and it is on by default. This is the dsh counterpart of the Claude `SessionStart` hook. For why the 1% Rule and the Red Flags table left the payload, see [Design trade-offs and feedback](#design-trade-offs-and-feedback).
|
|
89
|
+
3. **Registers the catalog entry.** The model-visible catalog entry (`cordis_inspect`) is always registered. The 4 custom agents are intentionally not ported, because dsh's native subagent tooling already covers parallel multi-agent work.
|
|
90
90
|
|
|
91
91
|
Install (native bundle, recommended):
|
|
92
92
|
|
|
@@ -99,37 +99,37 @@ dsh plugin --profile web add "github:AmethystLuna/embedded-workbench"
|
|
|
99
99
|
npx -p @deepseek-ai/dsh dsh plugin --profile web add dsh-embedded-workbench
|
|
100
100
|
```
|
|
101
101
|
|
|
102
|
-
Restart the profile
|
|
102
|
+
Restart the profile afterwards. `dsh --profile web --dump-config` must show the `id: embedded-workbench` row with `enabled: true`. More options (plain skill copy, project-level install) are in [`.dsh/INSTALL.md`](.dsh/INSTALL.md).
|
|
103
103
|
|
|
104
|
-
>
|
|
104
|
+
> Package name note: the npm package is `dsh-embedded-workbench`, with no scope. In the web profile's `package.json`, both the dependency key and the `dsh.profile.bundles` entry must use that name. On a mismatch the dsh loader cannot find `node_modules/dsh-embedded-workbench` and the boot fails.
|
|
105
105
|
|
|
106
106
|
## Usage
|
|
107
107
|
|
|
108
108
|
Skills load on demand and do not depend on injection:
|
|
109
109
|
|
|
110
|
-
- Invoke `Skill("embedded-workbench")` for the workflow and engineering policies
|
|
111
|
-
- Domain skills activate automatically when their `Use when` description matches your task
|
|
112
|
-
- The agent proactively suggests verification, adversarial probing, and parallel subagents when it detects state machines, behavioral claims, or multi-module tasks
|
|
113
|
-
- No manual CLAUDE.md configuration required
|
|
110
|
+
- Invoke `Skill("embedded-workbench")` for the workflow and engineering policies. It picks a light or full path by risk, and does not force fixed stages.
|
|
111
|
+
- Domain skills activate automatically when their `Use when` description matches your task. NOT clauses prevent false triggers, so a formatting-only task does not load `c-cpp-dev`.
|
|
112
|
+
- The agent proactively suggests verification, adversarial probing, and parallel subagents when it detects state machines, behavioral claims, or multi-module tasks.
|
|
113
|
+
- No manual `CLAUDE.md` configuration is required.
|
|
114
114
|
|
|
115
|
-
The plugin also folds a **trimmed** gate
|
|
115
|
+
The plugin also folds a **trimmed** gate of about 400 tokens into the first model step. It carries just two things. The first is the Plan Verification Gate. The second is the context-budget rule: never guess a readout you cannot see, and when a large step shows no signal, ask the user to decide. Set `enabled: false` to drop the gate entirely.
|
|
116
116
|
|
|
117
117
|
## Design trade-offs and feedback
|
|
118
118
|
|
|
119
|
-
This revision walks back an earlier decision on the evidence
|
|
119
|
+
This revision walks back an earlier decision on the evidence. The reasoning is below, and it is open to challenge.
|
|
120
120
|
|
|
121
|
-
**Background.** We checked the official documentation for all 8 supported harnesses one by one
|
|
121
|
+
**Background.** We checked the official documentation for all 8 supported harnesses, one by one, and read the source for Codex CLI. One assumption did not survive: **7 of the 8 expose no context-budget readout to the model at all**. Those 7 are Claude Code, Copilot CLI, Cursor, OpenCode, Kimi CLI, ZCode and dsh, and they show token figures only in the user's interface. Only Codex has a `get_context_remaining` tool, and it is off by default. Asking the model to judge "do I have budget to delegate?" therefore had nothing to stand on.
|
|
122
122
|
|
|
123
123
|
**So we changed two things.**
|
|
124
124
|
|
|
125
|
-
1. **Cost is now managed by trimming, not by switching injection off.** The first-step gate carries only two things
|
|
126
|
-
2. **The verification gate stays; the enforcement scaffolding goes.** The 1% Rule and the 9-row Red Flags table left the **injected payload
|
|
125
|
+
1. **Cost is now managed by trimming, not by switching injection off.** The first-step gate carries only two things. The first is the **Plan Verification Gate**: verify, or tell the user you did not. The second is a **context-budget rule**: never guess a readout, and when a large step shows no signal, ask the user to decide. The payload went from ~1,400 tokens to ~400, measured at −72% on the Claude side and −58% on the dsh side. It is on by default.
|
|
126
|
+
2. **The verification gate stays; the enforcement scaffolding goes.** The 1% Rule and the 9-row Red Flags table left the **injected payload**. They are enforcement, and reported experience shows capable models follow that kind of prompt pressure literally. The result is rigid phases, unnecessary questions, and six or seven agents on a five-line task at 10–15× overhead. See [obra/superpowers#1120](https://github.com/obra/superpowers/issues/1120), [openai/codex#22005](https://github.com/openai/codex/issues/22005) and [#20366](https://github.com/openai/codex/issues/20366). The full table still lives in `Skill("embedded-workbench")`: the discipline is available on request rather than applied to everyone by default. Workflow selection likewise moved from a fixed agent chain to **risk-proportional** paths.
|
|
127
127
|
|
|
128
|
-
**Deliberately kept.** The Plan Verification Gate is intact
|
|
128
|
+
**Deliberately kept.** The Plan Verification Gate is intact. Its fallback chain is logicprobe, then the built-in `fact-check` when logicprobe is not installed, then telling the user if you used neither. Following [Superpowers Lite](https://github.com/BB-84C/superpowers-lite), safety, permission and **verification** gates are the kind to keep. Process ceremony is the kind to scale back.
|
|
129
129
|
|
|
130
|
-
**Known uncertainty.** These budget interfaces change fast and we checked once, on 2026-09-25. Every cell a vendor does not document is marked `UNVERIFIED` in [`platform-tool-mapping.md`](skills/embedded-workbench/references/platform-tool-mapping.md) rather than filled in by analogy.
|
|
130
|
+
**Known uncertainty.** These budget interfaces change fast, and we checked once, on 2026-09-25. Every cell a vendor does not document is marked `UNVERIFIED` in [`platform-tool-mapping.md`](skills/embedded-workbench/references/platform-tool-mapping.md), rather than filled in by analogy.
|
|
131
131
|
|
|
132
|
-
**Disagree?** These are judgement calls, not settled facts
|
|
132
|
+
**Disagree?** These are judgement calls, not settled facts, especially "the Red Flags table leaves the payload" and "the gate is on by default". Open an [issue](https://github.com/AmethystLuna/embedded-workbench/issues) with the model tier, harness and counter-example you are working with. We would rather adjust on evidence.
|
|
133
133
|
|
|
134
134
|
## Codex CLI
|
|
135
135
|
|
|
@@ -151,7 +151,7 @@ Or manually:
|
|
|
151
151
|
git clone https://github.com/AmethystLuna/embedded-workbench.git ~/.codex/plugins/embedded-workbench
|
|
152
152
|
```
|
|
153
153
|
|
|
154
|
-
Skills are invoked with `$skill-name` (e.g. `$debug-methodology`) or
|
|
154
|
+
Skills are invoked with `$skill-name` (e.g. `$debug-methodology`), or selected automatically by Codex from the task context.
|
|
155
155
|
|
|
156
156
|
## Cursor
|
|
157
157
|
|
|
@@ -184,7 +184,7 @@ Skills are invoked with `/skill:<name>` (e.g. `/skill:debug-methodology`).
|
|
|
184
184
|
|
|
185
185
|
## OpenCode
|
|
186
186
|
|
|
187
|
-
Skills are auto-discovered from `.claude/skills/` and `.codex/skills/` paths. Add to your `opencode.json`:
|
|
187
|
+
Skills are auto-discovered from `.claude/skills/` and `.codex/skills/` paths. Add this to your `opencode.json`:
|
|
188
188
|
|
|
189
189
|
```json
|
|
190
190
|
{
|
|
@@ -192,38 +192,38 @@ Skills are auto-discovered from `.claude/skills/` and `.codex/skills/` paths. Ad
|
|
|
192
192
|
}
|
|
193
193
|
```
|
|
194
194
|
|
|
195
|
-
Or install
|
|
195
|
+
Or install through `skop`, which consumes the Claude marketplace manifest. See `.opencode/INSTALL.md`.
|
|
196
196
|
|
|
197
197
|
## ZCode (Z.AI)
|
|
198
198
|
|
|
199
|
-
ZCode 3.0+ follows the Agent Skills standard.
|
|
199
|
+
ZCode 3.0+ follows the Agent Skills standard. It has no plugin marketplace, so copy the skills yourself:
|
|
200
200
|
|
|
201
201
|
```bash
|
|
202
202
|
git clone https://github.com/AmethystLuna/embedded-workbench.git
|
|
203
203
|
cp -r embedded-workbench/skills/* .zcode/skills/
|
|
204
204
|
```
|
|
205
205
|
|
|
206
|
-
Skills are invoked with `$skill-name`. ZCode also auto-discovers from `.claude/skills/` and `.codex/skills/`. See `.zcode/INSTALL.md
|
|
206
|
+
Skills are invoked with `$skill-name`. ZCode also auto-discovers from `.claude/skills/` and `.codex/skills/`. See `.zcode/INSTALL.md`.
|
|
207
207
|
|
|
208
208
|
## Requirements
|
|
209
209
|
|
|
210
|
-
- Claude Code v2.1+ / Codex CLI latest / Cursor 2.5+ / Kimi CLI latest / OpenCode latest / ZCode 3.0+
|
|
211
|
-
- DeepSeek Harness (dsh): dev preview
|
|
212
|
-
- The Web Plugins-page "Gate injection" switch requires **dsh ≥ 0.1.7-alpha.1
|
|
213
|
-
- No external dependencies
|
|
210
|
+
- Host: Claude Code v2.1+ / Codex CLI latest / Cursor 2.5+ / Kimi CLI latest / OpenCode latest / ZCode 3.0+
|
|
211
|
+
- DeepSeek Harness (dsh): dev preview, declared support for `>= 0.1.0-rc.7`. The latest round measured install, mount, boot and uninstall on 0.2.1-alpha.1. The earlier round measured 0.1.5-rc.2 through 0.2.0-rc.2. Per-release evidence is in [DSH-COMPATIBILITY.md](DSH-COMPATIBILITY.md).
|
|
212
|
+
- The Web Plugins-page "Gate injection" switch requires **dsh ≥ 0.1.7-alpha.1**, because its settings service must be able to project live fields. On older dsh the plugin and its 8 skills still load and still inject. The switch is simply absent, with no error.
|
|
213
|
+
- No external dependencies.
|
|
214
214
|
|
|
215
215
|
## Configuration
|
|
216
216
|
|
|
217
|
-
In DeepSeek Harness
|
|
217
|
+
In DeepSeek Harness the bundle accepts a small configuration object:
|
|
218
218
|
|
|
219
219
|
| Key | Type | Default | Description |
|
|
220
220
|
|---|---|---|---|
|
|
221
|
-
| `enabled` | boolean | `true` | Set to `false` to drop the first-step gate injection entirely
|
|
221
|
+
| `enabled` | boolean | `true` | Set to `false` to drop the first-step gate injection entirely. Skill registration is unaffected. |
|
|
222
222
|
| `gateContent` | string | built-in gate text | Override the text injected into the first model step. |
|
|
223
223
|
|
|
224
|
-
The switch is editable live in the dsh Web GUI: sidebar **Plugins** → this plugin's card → "Gate injection". It takes effect without a profile restart and controls only the injected text
|
|
224
|
+
The switch is editable live in the dsh Web GUI: sidebar **Plugins** → this plugin's card → "Gate injection". It takes effect without a profile restart, and it controls only the injected text. Turning it off leaves all eight skills registered. The same card also carries a coarser row switch: turning that one off unmounts the whole row, so the skills and this switch disappear together. Persistent overrides still go through the profile patch below.
|
|
225
225
|
|
|
226
|
-
To
|
|
226
|
+
To override the row by id, edit your profile's `cordis.patch.yml`. The example below customises the gate text:
|
|
227
227
|
|
|
228
228
|
```yaml
|
|
229
229
|
- insert:
|
|
@@ -237,23 +237,23 @@ To change it, override the row by id in your profile's `cordis.patch.yml` (the e
|
|
|
237
237
|
|
|
238
238
|
## Uninstall
|
|
239
239
|
|
|
240
|
-
- If you installed through the DSH plugin manager, remove the `embedded-workbench` plugin from the target profile
|
|
241
|
-
- If you copied `skills/*` manually, delete the copied skill directories from `~/.agents/skills/` or the project `.dsh/skills/`.
|
|
240
|
+
- If you installed through the DSH plugin manager, remove the `embedded-workbench` plugin from the target profile with the same manager.
|
|
241
|
+
- If you copied `skills/*` manually, delete the copied skill directories from `~/.agents/skills/` or the project's `.dsh/skills/`.
|
|
242
242
|
- If you added the bundle as a `cordis.patch.yml` row, remove the row with `id: embedded-workbench` from the profile patch and restart DSH.
|
|
243
243
|
|
|
244
244
|
## Permissions & Data
|
|
245
245
|
|
|
246
246
|
- The plugin runtime reads only the `skills/` directory shipped inside the package, in order to register skills through DSH's standard filesystem skill provider.
|
|
247
247
|
- It injects the configured gate text into the first model step of a session.
|
|
248
|
-
- It does not read credentials, open network connections, or
|
|
248
|
+
- It does not read credentials, open network connections, or touch user data outside the DSH session context.
|
|
249
249
|
- When the skills are actually used, the model may read project files as directed by the user, just like any other coding skill.
|
|
250
250
|
|
|
251
251
|
## Troubleshooting
|
|
252
252
|
|
|
253
|
-
- Skills not visible in DSH: confirm
|
|
254
|
-
- Gate not injected: check that `enabled` is not `false
|
|
255
|
-
- Plugin manager rejects installation: make sure `@deepseek-ai/*` packages are declared as `peerDependencies`, not regular `dependencies`.
|
|
256
|
-
- After manual copy
|
|
253
|
+
- Skills not visible in DSH: confirm the DSH version supports `ctx.skills` and Agent Skills discovery, then restart the profile.
|
|
254
|
+
- Gate not injected: check that `enabled` is not `false`, and that the row id `embedded-workbench` is present in the active profile patch.
|
|
255
|
+
- Plugin manager rejects the installation: make sure the `@deepseek-ai/*` packages are declared as `peerDependencies`, not as regular `dependencies`.
|
|
256
|
+
- After a manual copy DSH still does not see the skills: install the native bundle instead (`dsh plugin add "github:AmethystLuna/embedded-workbench"`).
|
|
257
257
|
|
|
258
258
|
## Development
|
|
259
259
|
|
|
@@ -263,7 +263,7 @@ npm run typecheck
|
|
|
263
263
|
npm run build
|
|
264
264
|
```
|
|
265
265
|
|
|
266
|
-
Run the DSH skills registration test and trigger tests:
|
|
266
|
+
Run the DSH skills registration test and the trigger tests:
|
|
267
267
|
|
|
268
268
|
```bash
|
|
269
269
|
node tests/dsh-skills-registration.test.mjs
|
|
@@ -280,19 +280,19 @@ To report a security vulnerability, do **not** open a public issue. Use the priv
|
|
|
280
280
|
|
|
281
281
|
| Plugin | Description |
|
|
282
282
|
|--------|-------------|
|
|
283
|
-
| [logicprobe](https://github.com/AmethystLuna/logicprobe) | Claim-verification skill: checks every verifiable claim in design docs, architecture specs, and refactoring plans against the codebase,
|
|
284
|
-
| [superpowers](https://github.com/obra/superpowers) | The original agent discipline engine
|
|
283
|
+
| [logicprobe](https://github.com/AmethystLuna/logicprobe) | Claim-verification skill: checks every verifiable claim in design docs, architecture specs, and refactoring plans against the codebase, and escalates behavioral claims to executable-model verification. It was split out of this plugin. The Plan Verification Gate prefers it, and falls back to the built-in `fact-check` skill when it is not installed. Install with `claude plugin install logicprobe@logicprobe`, or on dsh with `dsh plugin --profile <name> add dsh-logicprobe`. |
|
|
284
|
+
| [superpowers](https://github.com/obra/superpowers) | The original agent discipline engine: skill loading enforcement, Red Flags, subagent-driven development. Many of this plugin's agent-compliance patterns (1% Rule, Red Flags, `<SUBAGENT-STOP>`, instruction priority) were adapted from Superpowers. |
|
|
285
285
|
|
|
286
286
|
## Acknowledgments
|
|
287
287
|
|
|
288
|
-
This plugin's agent-compliance architecture is adapted from [Superpowers](https://github.com/obra/superpowers) by Jesse Vincent (MIT License).
|
|
288
|
+
This plugin's agent-compliance architecture is adapted from [Superpowers](https://github.com/obra/superpowers) by Jesse Vincent (MIT License). These patterns were especially influential:
|
|
289
289
|
|
|
290
|
-
- **1% Rule
|
|
291
|
-
- **Red Flags table
|
|
292
|
-
- **`<SUBAGENT-STOP
|
|
293
|
-
- **Instruction Priority
|
|
294
|
-
- **Skill Types
|
|
295
|
-
- **Session-start hook injection pattern
|
|
296
|
-
- **Trigger test framework
|
|
290
|
+
- **1% Rule**: agents resist loading skills and need extreme language to overcome that bias
|
|
291
|
+
- **Red Flags table**: enumerating agent rationalizations to short-circuit them
|
|
292
|
+
- **`<SUBAGENT-STOP>`**: preventing subagents from re-loading bootstrap context
|
|
293
|
+
- **Instruction Priority**: user > skills > system prompt hierarchy
|
|
294
|
+
- **Skill Types**: Rigid vs Flexible classification
|
|
295
|
+
- **Session-start hook injection pattern**: injecting capability context at session start
|
|
296
|
+
- **Trigger test framework**: `tests/skill-triggering/` structure and methodology
|
|
297
297
|
|
|
298
298
|
Superpowers is a general-purpose development plugin. Embedded Workbench applies the same discipline patterns to the embedded C/C++ domain.
|
package/README.md
CHANGED
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
<p align="center"><a href="README.en-US.md">English</a> · <strong>中文</strong></p>
|
|
4
4
|
|
|
5
|
-
嵌入式 C/C++
|
|
6
|
-
MDK(AC5/AC6)、ARMCLANG、HardFault 分析、状态机、架构原则、LVGL 陷阱。
|
|
5
|
+
嵌入式 C/C++ 固件开发工具箱:4 个代理、8 个技能,覆盖 FreeRTOS、中断、NVM 存储、Keil MDK(AC5/AC6)、ARMCLANG、HardFault 分析、状态机、架构原则与 LVGL 陷阱。
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
**跨平台**:支持 Claude Code、Codex CLI、Cursor、Kimi CLI、OpenCode、ZCode、DeepSeek Harness (dsh)。基于 [Agent Skills](https://agentskills.io) 开放标准构建。
|
|
9
8
|
|
|
10
9
|
## 组件
|
|
11
10
|
|
|
@@ -28,16 +27,16 @@ MDK(AC5/AC6)、ARMCLANG、HardFault 分析、状态机、架构原则、LVGL
|
|
|
28
27
|
| `keil-mdk-build` | UV4 CLI、ARM Compiler 5/6、.map 分析、合并打包、构建诊断 |
|
|
29
28
|
| `c-cpp-dev` | C/C++ 代码生成、风格、内存布局、重构 |
|
|
30
29
|
| `state-machine-design` | 状态模型、重试、超时、转换门控、实现模式 |
|
|
31
|
-
| `hardfault-triage` |
|
|
32
|
-
| `fact-check` | 声称核查回退:逐条对照代码库核实 API
|
|
30
|
+
| `hardfault-triage` | 处理器异常分类:故障寄存器、栈帧、PC 定位源码、根因分类 |
|
|
31
|
+
| `fact-check` | 声称核查回退:逐条对照代码库核实 API 名、文件路径、枚举值、数量与机制可行性。logicprobe 未安装时由 Plan Verification Gate 使用 |
|
|
33
32
|
|
|
34
|
-
`logicprobe
|
|
33
|
+
`logicprobe`(文档与计划声称核查技能)**已拆分为独立插件**,见下方[其他插件推荐](#其他插件推荐)。未安装时,Plan Verification Gate 回退到本插件自带的 `fact-check` 技能。只有行为与模型类声称会降级为人工确认。
|
|
35
34
|
|
|
36
|
-
>
|
|
35
|
+
> 技能内容大多来自作者个人嵌入式与固件开发的工作经验,按实际工程踩坑与约束沉淀,而非泛泛的模型生成内容。
|
|
37
36
|
|
|
38
37
|
### 深度参考
|
|
39
38
|
|
|
40
|
-
`embedded-firmware-dev`、`debug-methodology`、`state-machine-design`、`c-cpp-dev`
|
|
39
|
+
`embedded-firmware-dev`、`debug-methodology`、`state-machine-design`、`c-cpp-dev` 包含深度参考或代码示例。内容包括 12 条架构原则、嵌入式模式(GIF 定时器安全、状态锁存、异步生命周期)、LVGL 陷阱、7 轮迭代调试案例研究、状态机实现模式,以及嵌入式 C 专项(volatile MMIO、链接器段、ISR 安全路径)。
|
|
41
40
|
|
|
42
41
|
## 安装
|
|
43
42
|
|
|
@@ -79,11 +78,13 @@ git clone https://github.com/AmethystLuna/embedded-workbench.git ~/.claude/plugi
|
|
|
79
78
|
|
|
80
79
|
## DeepSeek Harness (dsh)
|
|
81
80
|
|
|
82
|
-
原生 dsh 支持以 cordis 插件 bundle
|
|
81
|
+
原生 dsh 支持以 cordis 插件 bundle 的形式提供,位于**仓库根**,由根 `package.json` 声明。
|
|
83
82
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
83
|
+
这个 bundle 做三件事:
|
|
84
|
+
|
|
85
|
+
1. **注册技能。** 技能遵循 Agent Skills 开放标准,由 dsh 的 `skill-filesystem` provider 原样发现,不需要额外代码。
|
|
86
|
+
2. **注入门禁。** 每个 agent 会话的第一个模型步骤会收到一段**精简后**的首步门禁,内容是 Plan Verification Gate 加上下文预算规则。它由 `enabled` 控制,默认开启。这是 Claude `SessionStart` hook 在 dsh 上的对应物。载荷里为什么不再有 1% Rule 和 Red Flags,见[设计取舍与反馈](#设计取舍与反馈)。
|
|
87
|
+
3. **注册目录条目。** 模型可见的目录条目(`cordis_inspect`)始终注册。4 个自定义 agent 有意不移植,因为 dsh 原生的 subagent 工具已经覆盖并行多 agent 工作。
|
|
87
88
|
|
|
88
89
|
安装(原生 bundle,推荐):
|
|
89
90
|
|
|
@@ -96,37 +97,37 @@ dsh plugin --profile web add "github:AmethystLuna/embedded-workbench"
|
|
|
96
97
|
npx -p @deepseek-ai/dsh dsh plugin --profile web add dsh-embedded-workbench
|
|
97
98
|
```
|
|
98
99
|
|
|
99
|
-
|
|
100
|
+
装完重启 profile。运行 `dsh --profile web --dump-config` 应看到 `id: embedded-workbench` 且 `enabled: true`。更多方式(纯技能拷贝、项目级等)见 [`.dsh/INSTALL.md`](.dsh/INSTALL.md)。
|
|
100
101
|
|
|
101
|
-
> DSH 安装注意:npm 包名为 `dsh-embedded-workbench
|
|
102
|
+
> DSH 安装注意:npm 包名为 `dsh-embedded-workbench`,没有 scope。在 web profile 的 `package.json` 中,依赖键与 `dsh.profile.bundles` 必须都写 `dsh-embedded-workbench`。写错时 dsh 加载器找不到 `node_modules/dsh-embedded-workbench`,启动会失败。
|
|
102
103
|
|
|
103
104
|
## 使用
|
|
104
105
|
|
|
105
106
|
技能按需加载,不依赖注入:
|
|
106
107
|
|
|
107
|
-
- 调用 `Skill("embedded-workbench")`
|
|
108
|
-
- 领域技能在任务匹配其 `Use when`
|
|
109
|
-
- Agent
|
|
110
|
-
- 无需手动配置 CLAUDE.md
|
|
108
|
+
- 调用 `Skill("embedded-workbench")` 加载工作流与工程策略。技能内部按风险比例选择轻量或完整路径,不强制固定阶段。
|
|
109
|
+
- 领域技能在任务匹配其 `Use when` 描述时自动激活。描述里的 NOT 子句用于防止误触发,例如纯格式化不会加载 `c-cpp-dev`。
|
|
110
|
+
- Agent 在检测到状态机、行为声称或多模块任务时,主动建议验证、对抗探测和并行子代理。
|
|
111
|
+
- 无需手动配置 `CLAUDE.md`。
|
|
111
112
|
|
|
112
|
-
|
|
113
|
+
插件还会在会话首个模型步骤注入一段**精简**门禁,约 400 token。它只含两件事。第一件是 Plan Verification Gate。第二件是上下文预算规则:看不到读数就不要猜;工作量大且无信号时问用户,由用户决断。设 `enabled: false` 可完全关闭。
|
|
113
114
|
|
|
114
115
|
## 设计取舍与反馈
|
|
115
116
|
|
|
116
|
-
|
|
117
|
+
这一版做了一次**基于证据的回退**。理由写在下面,欢迎质疑。
|
|
117
118
|
|
|
118
|
-
**背景**:我们逐个核对了 8 个受支持 harness
|
|
119
|
+
**背景**:我们逐个核对了 8 个受支持 harness 的官方文档,Codex 还对照了源码。这次核对推翻了一个此前想当然的前提:**8 家里有 7 家根本不向模型暴露任何上下文预算读数**。这 7 家是 Claude Code、Copilot CLI、Cursor、OpenCode、Kimi CLI、ZCode 和 dsh,它们只把 token 数给用户界面。只有 Codex 提供一个 `get_context_remaining` 工具,而且默认关闭。也就是说,"让模型按预算自行判断要不要委派或切窗口"这件事本身没有依据。
|
|
119
120
|
|
|
120
121
|
**因此分两步处理**:
|
|
121
122
|
|
|
122
|
-
1. **不再用"关掉注入"控制成本,改为"瘦身"
|
|
123
|
-
2.
|
|
123
|
+
1. **不再用"关掉注入"控制成本,改为"瘦身"。** 首步门禁现在只保留两块。第一块是 **Plan Verification Gate**:未核查就必须告诉用户,不许静默跳过。第二块是**上下文预算规则**:看不到读数就不要猜;工作量大且无信号时问用户。载荷从约 1,400 token 降到约 400 token,实测 Claude 侧降 72%,dsh 侧降 58%。它现在默认开启。
|
|
124
|
+
2. **验证门禁保留,强制执行脚手架退场。** 原来的 1% Rule 与 9 行 Red Flags 表从**注入载荷**中移除。它们属于"强制纪律",而社区实证显示这类提示会被能力较强的模型字面执行,产生僵硬阶段、多余提问,以及五行任务拉起六七个 agent 的 10–15× 开销。相关反馈见 [obra/superpowers#1120](https://github.com/obra/superpowers/issues/1120)、[openai/codex#22005](https://github.com/openai/codex/issues/22005)、[#20366](https://github.com/openai/codex/issues/20366)。完整表格仍保留在 `Skill("embedded-workbench")` 正文里:需要纪律时纪律还在,只是不再对所有人默认施压。工作流选择也从固定 agent 串场改为**按风险比例**。
|
|
124
125
|
|
|
125
|
-
**有意保留的**:Plan Verification Gate
|
|
126
|
+
**有意保留的**:Plan Verification Gate 的语义没有削弱。它的回退链是 logicprobe → 未安装则用内置 `fact-check` → 两者都没用就必须告知用户。按 [Superpowers Lite](https://github.com/BB-84C/superpowers-lite) 的原则,安全、权限与**验证**门禁属于应当保留的一类,按比例裁掉的应该是流程仪式。
|
|
126
127
|
|
|
127
|
-
**已知的不确定**:各 harness 的预算接口变动很快,我们只在 2026-09-25
|
|
128
|
+
**已知的不确定**:各 harness 的预算接口变动很快,我们只在 2026-09-25 核对过一次。[`platform-tool-mapping.md`](skills/embedded-workbench/references/platform-tool-mapping.md) 里凡厂商未公开的格子都明确标为 `UNVERIFIED`,没有靠类比填空。
|
|
128
129
|
|
|
129
|
-
**有不同意见?**
|
|
130
|
+
**有不同意见?** 这些取舍是可讨论的判断,不是定论,尤其是"Red Flags 从载荷退场"和"门禁默认开"两条。欢迎到 [Issues](https://github.com/AmethystLuna/embedded-workbench/issues) 提出。写清你用的模型档位、harness 和反例,我们倾向按证据调整。
|
|
130
131
|
|
|
131
132
|
## Codex CLI
|
|
132
133
|
|
|
@@ -193,7 +194,7 @@ git clone https://github.com/AmethystLuna/embedded-workbench.git ~/.kimi/plugins
|
|
|
193
194
|
|
|
194
195
|
## ZCode(智谱 Z.AI)
|
|
195
196
|
|
|
196
|
-
ZCode 3.0+ 遵循 Agent Skills
|
|
197
|
+
ZCode 3.0+ 遵循 Agent Skills 标准。它没有插件商店,手动复制技能到 `.zcode/skills/`:
|
|
197
198
|
|
|
198
199
|
```bash
|
|
199
200
|
git clone https://github.com/AmethystLuna/embedded-workbench.git
|
|
@@ -204,10 +205,10 @@ cp -r embedded-workbench/skills/* .zcode/skills/
|
|
|
204
205
|
|
|
205
206
|
## 依赖
|
|
206
207
|
|
|
207
|
-
- Claude Code v2.1+ / Codex CLI 最新版 / Cursor 2.5+ / Kimi CLI 最新版 / OpenCode 最新版 / ZCode 3.0+
|
|
208
|
-
- DeepSeek Harness (dsh)
|
|
209
|
-
- Web 端的「Gate 注入」开关需要 **dsh ≥ 0.1.7-alpha.1
|
|
210
|
-
-
|
|
208
|
+
- 宿主:Claude Code v2.1+ / Codex CLI 最新版 / Cursor 2.5+ / Kimi CLI 最新版 / OpenCode 最新版 / ZCode 3.0+
|
|
209
|
+
- DeepSeek Harness (dsh):dev preview,声明支持 `>= 0.1.0-rc.7`。最新一轮在 0.2.1-alpha.1 上实测了安装、挂载、启动与卸载;更早一轮实测覆盖 0.1.5-rc.2 到 0.2.0-rc.2。逐版本证据见 [DSH-COMPATIBILITY.md](DSH-COMPATIBILITY.md)。
|
|
210
|
+
- Web 端的「Gate 注入」开关需要 **dsh ≥ 0.1.7-alpha.1**,因为设置服务必须能投影即时字段。更早的 dsh 上插件与 8 个技能照常加载、照常注入,只是开关不出现,也不报错。
|
|
211
|
+
- 无外部依赖。
|
|
211
212
|
|
|
212
213
|
## 配置
|
|
213
214
|
|
|
@@ -218,7 +219,7 @@ cp -r embedded-workbench/skills/* .zcode/skills/
|
|
|
218
219
|
| `enabled` | boolean | `true` | 设为 `false` 可完全关闭首步 Gate 注入;技能注册不受影响。 |
|
|
219
220
|
| `gateContent` | string | 内置 gate 文本 | 覆盖注入到首轮模型上下文中的文本。 |
|
|
220
221
|
|
|
221
|
-
在 dsh Web GUI 里可以直接改这个开关:侧边栏 **插件** → 本插件卡片 → 「Gate 注入」。它实时生效,不必重启 profile
|
|
222
|
+
在 dsh Web GUI 里可以直接改这个开关:侧边栏 **插件** → 本插件卡片 → 「Gate 注入」。它实时生效,不必重启 profile。它只管注入的那段文本:关掉后 8 个技能照常注册。同一张卡片上还有一个更粗粒度的行开关,关掉它会整行卸载插件,技能和这个开关一起消失。要持久化覆盖,仍按下面的 profile patch 写。
|
|
222
223
|
|
|
223
224
|
在 profile 的 `cordis.patch.yml` 中按 row id 覆盖(下面的例子自定义 Gate 文本):
|
|
224
225
|
|
|
@@ -234,20 +235,20 @@ cp -r embedded-workbench/skills/* .zcode/skills/
|
|
|
234
235
|
|
|
235
236
|
## 卸载
|
|
236
237
|
|
|
237
|
-
-
|
|
238
|
-
-
|
|
239
|
-
-
|
|
238
|
+
- 通过 DSH 插件管理器安装的,用同一管理器从目标 profile 中移除 `embedded-workbench`。
|
|
239
|
+
- 手动复制过 `skills/*` 的,删除 `~/.agents/skills/` 或项目 `.dsh/skills/` 下的对应目录。
|
|
240
|
+
- 通过 `cordis.patch.yml` 添加的,删除 profile patch 中 `id: embedded-workbench` 的行,并重启 DSH。
|
|
240
241
|
|
|
241
242
|
## 权限与数据
|
|
242
243
|
|
|
243
244
|
- 插件运行时只读取包内自带的 `skills/` 目录,用于通过 DSH 标准 filesystem skill provider 注册技能。
|
|
244
245
|
- 它会在会话首轮向模型上下文注入配置好的 gate 文本。
|
|
245
|
-
-
|
|
246
|
+
- 它不读取凭据,不发起网络连接,也不访问 DSH 会话上下文之外的用户数据。
|
|
246
247
|
- 实际使用技能时,模型会像使用其他编码技能一样,按用户指示读取项目文件。
|
|
247
248
|
|
|
248
249
|
## 故障排查
|
|
249
250
|
|
|
250
|
-
- 技能在 DSH 中不可见:确认 DSH 版本支持 `ctx.skills`
|
|
251
|
+
- 技能在 DSH 中不可见:确认 DSH 版本支持 `ctx.skills` 与 Agent Skills 发现,并在安装后重启 profile。
|
|
251
252
|
- Gate 未注入:检查 `enabled` 是否为 `false`,以及 profile patch 中是否存在 `id: embedded-workbench` 的行。
|
|
252
253
|
- 插件管理器拒绝安装:确认 `@deepseek-ai/*` 包声明在 `peerDependencies` 中,而不是 `dependencies`。
|
|
253
254
|
- 手动复制后 DSH 仍看不到技能:改用原生 bundle 安装(`dsh plugin add "github:AmethystLuna/embedded-workbench"`)。
|
|
@@ -277,19 +278,19 @@ bash tests/skill-triggering/run-all.sh
|
|
|
277
278
|
|
|
278
279
|
| 插件 | 简介 |
|
|
279
280
|
|------|------|
|
|
280
|
-
| [logicprobe](https://github.com/AmethystLuna/logicprobe) |
|
|
281
|
-
| [superpowers](https://github.com/obra/superpowers) | 原始 agent
|
|
281
|
+
| [logicprobe](https://github.com/AmethystLuna/logicprobe) | 声称核查技能:逐条核验设计文档、架构规格、重构计划中的可验证声称与代码库是否一致,行为类声称升级为可执行模型验证。它自本插件拆分而来。Plan Verification Gate 优先使用它,未安装时回退到内置 `fact-check` 技能。安装:Claude 侧 `claude plugin install logicprobe@logicprobe`;dsh 侧 `dsh plugin --profile <name> add dsh-logicprobe`。 |
|
|
282
|
+
| [superpowers](https://github.com/obra/superpowers) | 原始 agent 纪律引擎:技能加载强制、Red Flags、子代理驱动开发。本插件的多项 agent 合规模式(1% Rule、Red Flags、`<SUBAGENT-STOP>`、指令优先级)均借鉴自 Superpowers。 |
|
|
282
283
|
|
|
283
284
|
## 致谢
|
|
284
285
|
|
|
285
|
-
本插件的 agent 合规架构借鉴自 Jesse Vincent 的 [Superpowers](https://github.com/obra/superpowers)(MIT License
|
|
286
|
+
本插件的 agent 合规架构借鉴自 Jesse Vincent 的 [Superpowers](https://github.com/obra/superpowers)(MIT License)。以下设计模式尤其有启发:
|
|
286
287
|
|
|
287
|
-
- **1% Rule
|
|
288
|
-
- **Red Flags
|
|
289
|
-
- **`<SUBAGENT-STOP
|
|
290
|
-
-
|
|
291
|
-
-
|
|
292
|
-
-
|
|
293
|
-
-
|
|
288
|
+
- **1% Rule**:agent 会抗拒加载技能,需要极端语言突破这种偏见
|
|
289
|
+
- **Red Flags 表**:枚举 agent 的合理化借口,以预先阻断
|
|
290
|
+
- **`<SUBAGENT-STOP>`**:阻止子代理重复加载引导上下文
|
|
291
|
+
- **指令优先级**:用户 > 技能 > 系统提示的分层架构
|
|
292
|
+
- **技能类型**:Rigid 与 Flexible 的分类体系
|
|
293
|
+
- **会话启动注入模式**:在会话启动时注入能力上下文的 hook 机制
|
|
294
|
+
- **触发测试框架**:`tests/skill-triggering/` 的结构和方法论
|
|
294
295
|
|
|
295
|
-
Superpowers 是通用开发插件。Embedded Workbench
|
|
296
|
+
Superpowers 是通用开发插件。Embedded Workbench 把相同的纪律模式应用到嵌入式 C/C++ 领域。
|
package/lib/client.js
CHANGED
|
@@ -30,7 +30,61 @@ window.__ModuleLoader__.load({
|
|
|
30
30
|
id: 'dsh-embedded-workbench',
|
|
31
31
|
factory: (require) => {
|
|
32
32
|
const React = require('react')
|
|
33
|
-
|
|
33
|
+
// The host's Switch and Button, vendored. A plain-JS client bundle must not
|
|
34
|
+
// require a Harness Client package: it changes without notice, we get no type
|
|
35
|
+
// check, and a throw blanks this slot entry. Markup, classes, token usage and
|
|
36
|
+
// the aria behaviour follow the host primitive; classes carry our own prefix.
|
|
37
|
+
const CONTROLS_CSS = [
|
|
38
|
+
'.ew-switch { box-sizing: border-box; position: relative; flex: 0 0 auto; width: 36px; height: 20px; padding: 2px; border: 0; border-radius: 999px; corner-shape: round; background: var(--dsw-alias-border-l3); cursor: pointer; }',
|
|
39
|
+
".ew-switch[aria-checked='true'] { background: var(--dsw-alias-brand-primary); }",
|
|
40
|
+
'.ew-switch:disabled { cursor: default; opacity: 0.5; }',
|
|
41
|
+
'.ew-switch:focus-visible { outline: var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary)); outline-offset: 2px; }',
|
|
42
|
+
'.ew-switch-thumb { display: block; width: 16px; height: 16px; border-radius: 50%; corner-shape: round; background: var(--dsw-alias-label-primary-foreground); transition: transform 120ms ease; }',
|
|
43
|
+
".ew-switch[aria-checked='false'] .ew-switch-thumb { background: var(--dsw-alias-switch-thumb); }",
|
|
44
|
+
".ew-switch[aria-checked='true'] .ew-switch-thumb { transform: translateX(16px); }",
|
|
45
|
+
'.ew-btn { box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; gap: 4px; border: none; border-radius: var(--dsw-radius-md); cursor: pointer; font-size: 14px; line-height: 22px; color: var(--dsw-alias-label-primary); background: transparent; padding: 0 14px; }',
|
|
46
|
+
'.ew-btn:disabled { cursor: not-allowed; opacity: 0.4; }',
|
|
47
|
+
'.ew-btn-sm { height: 28px; font-size: 12px; line-height: 18px; padding: 0 10px; border-radius: var(--dsw-radius-sm); }',
|
|
48
|
+
'.ew-btn-outline { border: 0.5px solid var(--dsw-alias-border-l3); background: transparent; }',
|
|
49
|
+
'.ew-btn-outline:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); }',
|
|
50
|
+
].join('\n')
|
|
51
|
+
|
|
52
|
+
/** Rendered inside the component tree, so unmounting removes the styles. */
|
|
53
|
+
function Controls() {
|
|
54
|
+
return React.createElement('style', null, CONTROLS_CSS)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function Switch(props) {
|
|
58
|
+
return React.createElement(
|
|
59
|
+
'button',
|
|
60
|
+
{
|
|
61
|
+
type: 'button',
|
|
62
|
+
role: 'switch',
|
|
63
|
+
'aria-checked': props.checked === true,
|
|
64
|
+
'aria-label': props.label,
|
|
65
|
+
className: 'ew-switch',
|
|
66
|
+
disabled: props.disabled === true,
|
|
67
|
+
onClick: () => {
|
|
68
|
+
if (props.disabled !== true) props.onChange(!(props.checked === true))
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
React.createElement('span', { className: 'ew-switch-thumb' }),
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
Switch.displayName = 'dsh-embedded-workbench:Switch'
|
|
76
|
+
Button.displayName = 'dsh-embedded-workbench:Button'
|
|
77
|
+
|
|
78
|
+
function Button(props) {
|
|
79
|
+
const classes = ['ew-btn']
|
|
80
|
+
if (props.size === 'sm') classes.push('ew-btn-sm')
|
|
81
|
+
if (props.variant === 'outline') classes.push('ew-btn-outline')
|
|
82
|
+
return React.createElement(
|
|
83
|
+
'button',
|
|
84
|
+
{ type: 'button', className: classes.join(' '), disabled: props.disabled === true, onClick: props.onClick },
|
|
85
|
+
props.children,
|
|
86
|
+
)
|
|
87
|
+
}
|
|
34
88
|
|
|
35
89
|
/** Settings namespace: the Loader entry id this bundle's patch declares. */
|
|
36
90
|
const NS = 'embedded-workbench'
|
|
@@ -122,6 +176,7 @@ window.__ModuleLoader__.load({
|
|
|
122
176
|
const locked = state.writable !== true || pending
|
|
123
177
|
|
|
124
178
|
const children = [
|
|
179
|
+
React.createElement(Controls, { key: 'styles' }),
|
|
125
180
|
React.createElement('h4', { key: 'title', style: TITLE }, t('title')),
|
|
126
181
|
React.createElement('div', { key: 'row', style: ROW }, [
|
|
127
182
|
React.createElement('span', { key: 'label', style: LABEL }, t('label')),
|
package/locale/en.json
ADDED
package/locale/zh.json
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-embedded-workbench",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.2",
|
|
4
4
|
"description": "Embedded C/C++ firmware development toolbox — 4 agents, 8 skills covering FreeRTOS, ISR, NVM storage, Keil MDK, ARMCLANG, HardFault, state machines, architecture, LVGL patterns, and claim fact-checking. Ships a native DeepSeek Harness (dsh) bundle that folds a short gate — the Plan Verification Gate plus a context-budget rule — into the first model step.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -12,13 +12,15 @@
|
|
|
12
12
|
},
|
|
13
13
|
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
14
14
|
"./client": "./lib/client.js",
|
|
15
|
-
"./package.json": "./package.json"
|
|
15
|
+
"./package.json": "./package.json",
|
|
16
|
+
"./locale/*.json": "./locale/*.json"
|
|
16
17
|
},
|
|
17
18
|
"files": [
|
|
18
19
|
"lib",
|
|
19
20
|
"src",
|
|
20
21
|
"skills",
|
|
21
|
-
"cordis.patch.yml"
|
|
22
|
+
"cordis.patch.yml",
|
|
23
|
+
"locale"
|
|
22
24
|
],
|
|
23
25
|
"engines": {
|
|
24
26
|
"node": ">=20"
|
|
@@ -41,32 +43,34 @@
|
|
|
41
43
|
]
|
|
42
44
|
},
|
|
43
45
|
"compatibility": {
|
|
44
|
-
"dsh": "^0.1.0-rc.7 || ^0.1.1-rc.1 || ^0.1.2-alpha.2 || ^0.1.2-alpha.3 || ^0.1.2-alpha.4 || ^0.1.2-alpha.5 || ^0.1.2-rc.1 || ^0.1.3-alpha.1 || ^0.1.3-alpha.2 || ^0.1.5-alpha.1 || ^0.1.5-rc.1 || ^0.1.5-alpha.2 || ^0.1.5-rc.2 || ^0.1.5-rc.3 || ^0.1.6-alpha.1 || ^0.1.6-alpha.2 || ^0.1.7-alpha.1 || ^0.1.7-alpha.2 || ^0.1.7-rc.1 || ^0.1.7-rc.2 || ^0.2.0-rc.1",
|
|
46
|
+
"dsh": "^0.1.0-rc.7 || ^0.1.1-rc.1 || ^0.1.2-alpha.2 || ^0.1.2-alpha.3 || ^0.1.2-alpha.4 || ^0.1.2-alpha.5 || ^0.1.2-rc.1 || ^0.1.3-alpha.1 || ^0.1.3-alpha.2 || ^0.1.5-alpha.1 || ^0.1.5-rc.1 || ^0.1.5-alpha.2 || ^0.1.5-rc.2 || ^0.1.5-rc.3 || ^0.1.6-alpha.1 || ^0.1.6-alpha.2 || ^0.1.7-alpha.1 || ^0.1.7-alpha.2 || ^0.1.7-rc.1 || ^0.1.7-rc.2 || ^0.2.0-rc.1 || ^0.2.1-alpha.1 || ^0.2.1-alpha.2",
|
|
45
47
|
"dshReleases": {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
48
|
+
"0.1.0-rc.7": "compatible",
|
|
49
|
+
"0.1.0-rc.8": "compatible",
|
|
50
|
+
"0.1.1-rc.1": "compatible",
|
|
51
|
+
"0.1.1-rc.2": "compatible",
|
|
52
|
+
"0.1.2-alpha.2": "compatible",
|
|
53
|
+
"0.1.2-alpha.3": "compatible",
|
|
54
|
+
"0.1.2-alpha.4": "compatible",
|
|
55
|
+
"0.1.2-alpha.5": "compatible",
|
|
56
|
+
"0.1.2-rc.1": "compatible",
|
|
57
|
+
"0.1.3-alpha.1": "compatible",
|
|
58
|
+
"0.1.3-alpha.2": "compatible",
|
|
59
|
+
"0.1.5-alpha.1": "compatible",
|
|
60
|
+
"0.1.5-alpha.2": "compatible",
|
|
61
|
+
"0.1.5-rc.1": "compatible",
|
|
62
|
+
"0.1.5-rc.2": "compatible",
|
|
63
|
+
"0.1.5-rc.3": "compatible",
|
|
64
|
+
"0.1.6-alpha.1": "compatible",
|
|
65
|
+
"0.1.6-alpha.2": "compatible",
|
|
66
|
+
"0.1.7-alpha.1": "compatible",
|
|
67
|
+
"0.1.7-alpha.2": "compatible",
|
|
68
|
+
"0.1.7-rc.1": "compatible",
|
|
69
|
+
"0.1.7-rc.2": "compatible",
|
|
70
|
+
"0.2.0-rc.1": "compatible",
|
|
71
|
+
"0.2.0-rc.2": "compatible",
|
|
72
|
+
"0.2.1-alpha.1": "compatible",
|
|
73
|
+
"0.2.1-alpha.2": "compatible"
|
|
70
74
|
},
|
|
71
75
|
"profiles": [
|
|
72
76
|
"headless",
|
|
@@ -81,25 +85,24 @@
|
|
|
81
85
|
},
|
|
82
86
|
"peerDependencies": {
|
|
83
87
|
"@deepseek-ai/cordis": "^4.0.4",
|
|
84
|
-
"@deepseek-ai/dsh-agent": "^0.1.0-rc.6 || ^0.2.0-rc.1",
|
|
85
|
-
"@deepseek-ai/dsh-llm": "^0.1.0-rc.6 || ^0.2.0-rc.1",
|
|
86
|
-
"@deepseek-ai/dsh-session": "^0.1.0-rc.6 || ^0.2.0-rc.1",
|
|
87
|
-
"@deepseek-ai/dsh-skill-filesystem": "^0.1.0-rc.8 || ^0.2.0-rc.1",
|
|
88
|
+
"@deepseek-ai/dsh-agent": "^0.1.0-rc.6 || ^0.2.0-rc.1 || ^0.2.1-alpha.1 || ^0.2.1-alpha.2",
|
|
89
|
+
"@deepseek-ai/dsh-llm": "^0.1.0-rc.6 || ^0.2.0-rc.1 || ^0.2.1-alpha.1 || ^0.2.1-alpha.2",
|
|
90
|
+
"@deepseek-ai/dsh-session": "^0.1.0-rc.6 || ^0.2.0-rc.1 || ^0.2.1-alpha.1 || ^0.2.1-alpha.2",
|
|
91
|
+
"@deepseek-ai/dsh-skill-filesystem": "^0.1.0-rc.8 || ^0.2.0-rc.1 || ^0.2.1-alpha.1 || ^0.2.1-alpha.2",
|
|
88
92
|
"@deepseek-ai/schemastery": "^3.18.4"
|
|
89
93
|
},
|
|
90
94
|
"devDependencies": {
|
|
91
95
|
"@deepseek-ai/cordis": "^4.0.4",
|
|
92
|
-
"@deepseek-ai/dsh-agent": "^0.
|
|
93
|
-
"@deepseek-ai/dsh-cordis-host-runner": "^0.
|
|
94
|
-
"@deepseek-ai/dsh-home-paths": "^0.
|
|
95
|
-
"@deepseek-ai/dsh-llm": "^0.
|
|
96
|
-
"@deepseek-ai/dsh-scope": "^0.
|
|
97
|
-
"@deepseek-ai/dsh-session": "^0.
|
|
98
|
-
"@deepseek-ai/dsh-skill": "^0.
|
|
99
|
-
"@deepseek-ai/dsh-skill-filesystem": "^0.
|
|
100
|
-
"@deepseek-ai/dsh-timeout": "^0.0.1-rc.1",
|
|
96
|
+
"@deepseek-ai/dsh-agent": "^0.2.0-rc.2",
|
|
97
|
+
"@deepseek-ai/dsh-cordis-host-runner": "^0.2.0-rc.2",
|
|
98
|
+
"@deepseek-ai/dsh-home-paths": "^0.2.0-rc.2",
|
|
99
|
+
"@deepseek-ai/dsh-llm": "^0.2.0-rc.2",
|
|
100
|
+
"@deepseek-ai/dsh-scope": "^0.2.0-rc.2",
|
|
101
|
+
"@deepseek-ai/dsh-session": "^0.2.0-rc.2",
|
|
102
|
+
"@deepseek-ai/dsh-skill": "^0.2.0-rc.2",
|
|
103
|
+
"@deepseek-ai/dsh-skill-filesystem": "^0.2.0-rc.2",
|
|
101
104
|
"@deepseek-ai/schemastery": "^3.18.4",
|
|
102
|
-
"@types/node": "^26.6.
|
|
105
|
+
"@types/node": "^26.6.3",
|
|
103
106
|
"typescript": "^7.0.2"
|
|
104
107
|
},
|
|
105
108
|
"author": {
|
|
@@ -13,7 +13,7 @@ Patterns for building embedded firmware with Keil MDK. Covers both ARM Compiler
|
|
|
13
13
|
|
|
14
14
|
## UV4 CLI Build (Authoritative)
|
|
15
15
|
|
|
16
|
-
UV4.exe batch mode is the canonical build path.
|
|
16
|
+
UV4.exe batch mode is the canonical build path. A CI reimplementation is possible but may miss include paths.
|
|
17
17
|
|
|
18
18
|
```powershell
|
|
19
19
|
<Keil>\UV4\UV4.exe -b project.uvprojx -t TargetName -j0 -o <log_path>
|
|
@@ -145,7 +145,7 @@ A full Keil build has 5 stages:
|
|
|
145
145
|
4. **Post-build (fromelf)** — `fromelf --bin objects/app.axf → application.bin`
|
|
146
146
|
5. **Post-build (merge)** — Merge application BIN + filesystem + bootloader into flash image
|
|
147
147
|
|
|
148
|
-
If bypassing UV4 (CI build), all 5 stages must be replicated
|
|
148
|
+
If bypassing UV4 (CI build), all 5 stages must be replicated explicitly.
|
|
149
149
|
|
|
150
150
|
## Merge / Packaging
|
|
151
151
|
|
package/src/client.js
CHANGED
|
@@ -30,7 +30,61 @@ window.__ModuleLoader__.load({
|
|
|
30
30
|
id: 'dsh-embedded-workbench',
|
|
31
31
|
factory: (require) => {
|
|
32
32
|
const React = require('react')
|
|
33
|
-
|
|
33
|
+
// The host's Switch and Button, vendored. A plain-JS client bundle must not
|
|
34
|
+
// require a Harness Client package: it changes without notice, we get no type
|
|
35
|
+
// check, and a throw blanks this slot entry. Markup, classes, token usage and
|
|
36
|
+
// the aria behaviour follow the host primitive; classes carry our own prefix.
|
|
37
|
+
const CONTROLS_CSS = [
|
|
38
|
+
'.ew-switch { box-sizing: border-box; position: relative; flex: 0 0 auto; width: 36px; height: 20px; padding: 2px; border: 0; border-radius: 999px; corner-shape: round; background: var(--dsw-alias-border-l3); cursor: pointer; }',
|
|
39
|
+
".ew-switch[aria-checked='true'] { background: var(--dsw-alias-brand-primary); }",
|
|
40
|
+
'.ew-switch:disabled { cursor: default; opacity: 0.5; }',
|
|
41
|
+
'.ew-switch:focus-visible { outline: var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary)); outline-offset: 2px; }',
|
|
42
|
+
'.ew-switch-thumb { display: block; width: 16px; height: 16px; border-radius: 50%; corner-shape: round; background: var(--dsw-alias-label-primary-foreground); transition: transform 120ms ease; }',
|
|
43
|
+
".ew-switch[aria-checked='false'] .ew-switch-thumb { background: var(--dsw-alias-switch-thumb); }",
|
|
44
|
+
".ew-switch[aria-checked='true'] .ew-switch-thumb { transform: translateX(16px); }",
|
|
45
|
+
'.ew-btn { box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; gap: 4px; border: none; border-radius: var(--dsw-radius-md); cursor: pointer; font-size: 14px; line-height: 22px; color: var(--dsw-alias-label-primary); background: transparent; padding: 0 14px; }',
|
|
46
|
+
'.ew-btn:disabled { cursor: not-allowed; opacity: 0.4; }',
|
|
47
|
+
'.ew-btn-sm { height: 28px; font-size: 12px; line-height: 18px; padding: 0 10px; border-radius: var(--dsw-radius-sm); }',
|
|
48
|
+
'.ew-btn-outline { border: 0.5px solid var(--dsw-alias-border-l3); background: transparent; }',
|
|
49
|
+
'.ew-btn-outline:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); }',
|
|
50
|
+
].join('\n')
|
|
51
|
+
|
|
52
|
+
/** Rendered inside the component tree, so unmounting removes the styles. */
|
|
53
|
+
function Controls() {
|
|
54
|
+
return React.createElement('style', null, CONTROLS_CSS)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function Switch(props) {
|
|
58
|
+
return React.createElement(
|
|
59
|
+
'button',
|
|
60
|
+
{
|
|
61
|
+
type: 'button',
|
|
62
|
+
role: 'switch',
|
|
63
|
+
'aria-checked': props.checked === true,
|
|
64
|
+
'aria-label': props.label,
|
|
65
|
+
className: 'ew-switch',
|
|
66
|
+
disabled: props.disabled === true,
|
|
67
|
+
onClick: () => {
|
|
68
|
+
if (props.disabled !== true) props.onChange(!(props.checked === true))
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
React.createElement('span', { className: 'ew-switch-thumb' }),
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
Switch.displayName = 'dsh-embedded-workbench:Switch'
|
|
76
|
+
Button.displayName = 'dsh-embedded-workbench:Button'
|
|
77
|
+
|
|
78
|
+
function Button(props) {
|
|
79
|
+
const classes = ['ew-btn']
|
|
80
|
+
if (props.size === 'sm') classes.push('ew-btn-sm')
|
|
81
|
+
if (props.variant === 'outline') classes.push('ew-btn-outline')
|
|
82
|
+
return React.createElement(
|
|
83
|
+
'button',
|
|
84
|
+
{ type: 'button', className: classes.join(' '), disabled: props.disabled === true, onClick: props.onClick },
|
|
85
|
+
props.children,
|
|
86
|
+
)
|
|
87
|
+
}
|
|
34
88
|
|
|
35
89
|
/** Settings namespace: the Loader entry id this bundle's patch declares. */
|
|
36
90
|
const NS = 'embedded-workbench'
|
|
@@ -122,6 +176,7 @@ window.__ModuleLoader__.load({
|
|
|
122
176
|
const locked = state.writable !== true || pending
|
|
123
177
|
|
|
124
178
|
const children = [
|
|
179
|
+
React.createElement(Controls, { key: 'styles' }),
|
|
125
180
|
React.createElement('h4', { key: 'title', style: TITLE }, t('title')),
|
|
126
181
|
React.createElement('div', { key: 'row', style: ROW }, [
|
|
127
182
|
React.createElement('span', { key: 'label', style: LABEL }, t('label')),
|