@chengzhao-dev/dsh-cpp-workflow 0.6.6 → 0.6.7
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.md +4 -2
- package/README.md +4 -2
- package/lib/client.js +90 -22
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -19,13 +19,13 @@ The exception material follows the C++ Core Guidelines' Error handling section a
|
|
|
19
19
|
Pinned npm install:
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
-
dsh plugin --profile web add npm:@chengzhao-dev/dsh-cpp-workflow@0.6.
|
|
22
|
+
dsh plugin --profile web add npm:@chengzhao-dev/dsh-cpp-workflow@0.6.7
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
The matching Git tag:
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
|
-
dsh plugin --profile web add github:chengzhao-dev/dsh-cpp-workflow#v0.6.
|
|
28
|
+
dsh plugin --profile web add github:chengzhao-dev/dsh-cpp-workflow#v0.6.7
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
The desktop app owns the `desktop` profile. If the command-line `add` is rejected, add the plugin in the app settings and use the same pinned npm version. A Git tag install uses the prebuilt `lib/` committed in the repository and runs no build on the target machine; the package has no install script that needs approval.
|
|
@@ -34,6 +34,8 @@ The desktop app owns the `desktop` profile. If the command-line `add` is rejecte
|
|
|
34
34
|
|
|
35
35
|
The plugin page's "C++ Workflow" card is the only entry point and manages file-header tags only: `@file` is always the file name, `@brief` is written by default, and `@author`, `@date`, `@copyright`, `@version` stay off and are written only when they hold a non-empty value; `@param` is required for every parameter; `@return` is written by default but may be omitted when the condition is self-evident; `@throws` only when the function throws. The preview follows the switches, saving takes effect on the next skill read, and existing sources are never rewritten. Settings navigation no longer duplicates the form.
|
|
36
36
|
|
|
37
|
+
If the page still reports that it is not connected to a configuration form after an upgrade, the window is still running the previous client bundle: restart DeepSeek Harness or select "Reload page" on the plugin page. The page retries the connection while open and switches to the editable form as soon as the host serves it; reinstalling is unnecessary. Discard changes, Restore defaults and Save are separate: discard returns to the last value read from the host, restore fills the draft, and only Save writes it.
|
|
38
|
+
|
|
37
39
|
## Workspace gate
|
|
38
40
|
|
|
39
41
|
Only one condition must hold before either skill appears: walking up from the current directory to the Git root, the path contains `.agents/skills/cpp-workflow-project/SKILL.md`.
|
package/README.md
CHANGED
|
@@ -19,13 +19,13 @@
|
|
|
19
19
|
npm 安装钉死版本:
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
-
dsh plugin --profile web add npm:@chengzhao-dev/dsh-cpp-workflow@0.6.
|
|
22
|
+
dsh plugin --profile web add npm:@chengzhao-dev/dsh-cpp-workflow@0.6.7
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
同版本的 Git 标签:
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
|
-
dsh plugin --profile web add github:chengzhao-dev/dsh-cpp-workflow#v0.6.
|
|
28
|
+
dsh plugin --profile web add github:chengzhao-dev/dsh-cpp-workflow#v0.6.7
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
桌面应用独占 `desktop` profile。命令行 `add` 被拒绝时,在应用设置里添加插件,地址填同一个 npm 版本。Git 标签安装使用仓库内已构建的 `lib/`,不在目标机器上重新构建;包内也不含需要授权执行的安装脚本。
|
|
@@ -34,6 +34,8 @@ dsh plugin --profile web add github:chengzhao-dev/dsh-cpp-workflow#v0.6.6
|
|
|
34
34
|
|
|
35
35
|
插件页的「C++ 工程流程」是唯一入口,只管文件头标签:`@file` 固定为文件名,`@brief` 默认写出,`@author`、`@date`、`@copyright`、`@version` 默认关闭且只在填了非空值时才写出;有参数就要求 `@param`,有返回值默认要求 `@return`(成立条件自明时可省),会抛才要求 `@throws`。预览随开关即时更新,保存后下一次读取技能即生效,已有源码不会被改写。设置导航不再重复放一份。
|
|
36
36
|
|
|
37
|
+
升级插件后如果这一页仍显示“暂时没有连到配置表单”,说明当前窗口还挂着旧的前端产物:重启 DeepSeek Harness,或在插件页点“重新载入页面”。页面会在打开后自动重试连接,拿到表单就切换为可编辑,不需要重装插件。保存、撤销修改与恢复默认值分三个按钮:撤销只回到最近一次读到的值,恢复默认值只填草稿,点保存才写盘。
|
|
38
|
+
|
|
37
39
|
## 工作区门禁
|
|
38
40
|
|
|
39
41
|
一个会话里只需要满足一件事,技能就会出现:从当前目录向上、停在 git 根,沿途有 `.agents/skills/cpp-workflow-project/SKILL.md`。
|
package/lib/client.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// 由 scripts/building-client.mjs 生成,请改 src/comment-policy.ts 与 src/client
|
|
1
|
+
// 由 scripts/building-client.mjs 生成,请改 src/comment-policy.ts 与 src/client/*.js。
|
|
2
2
|
window.__ModuleLoader__.load({
|
|
3
3
|
id: "@chengzhao-dev/dsh-cpp-workflow",
|
|
4
4
|
factory: (require) => {
|
|
@@ -237,14 +237,18 @@ const STRINGS = {
|
|
|
237
237
|
preview: '预览',
|
|
238
238
|
previewHint: '按当前开关生成,文件名用占位符表示。',
|
|
239
239
|
save: '保存',
|
|
240
|
-
reset: '
|
|
240
|
+
reset: '撤销修改',
|
|
241
|
+
defaults: '恢复默认值',
|
|
242
|
+
restored: '已填入内置默认值,点“保存”后生效。',
|
|
241
243
|
saved: '已保存,下一次读取技能时生效。',
|
|
242
|
-
rejected: '
|
|
244
|
+
rejected: '保存被拒绝:配置可能已在别处修改。请先撤销修改,再重新编辑。',
|
|
243
245
|
unsaved: '有未保存的改动',
|
|
244
246
|
loading: '正在读取配置…',
|
|
245
247
|
unavailable: '这个部署没有提供这份配置。',
|
|
246
248
|
unreadable: '当前账户不能修改这份配置。',
|
|
247
|
-
readOnly: '
|
|
249
|
+
readOnly: '这个页面暂时没有连到配置表单,下面的值是内置默认值。重启 DeepSeek Harness 后重新打开本页即可编辑。',
|
|
250
|
+
reload: '重新载入页面',
|
|
251
|
+
noService: '(configForms 服务未连接)',
|
|
248
252
|
fixed: '跟随文件名',
|
|
249
253
|
fixedHint: '值由实际文件决定,不写进配置。',
|
|
250
254
|
emptyValue: '留空则由文件自己写',
|
|
@@ -273,14 +277,18 @@ const STRINGS = {
|
|
|
273
277
|
preview: 'Preview',
|
|
274
278
|
previewHint: 'Generated from the switches above; the file name is a placeholder.',
|
|
275
279
|
save: 'Save',
|
|
276
|
-
reset: '
|
|
280
|
+
reset: 'Discard changes',
|
|
281
|
+
defaults: 'Restore defaults',
|
|
282
|
+
restored: 'Built-in defaults are filled in; select Save to apply them.',
|
|
277
283
|
saved: 'Saved; the next skill read uses it.',
|
|
278
|
-
rejected: 'The host rejected the save: the config changed elsewhere.
|
|
284
|
+
rejected: 'The host rejected the save: the config changed elsewhere. Discard your changes and edit again.',
|
|
279
285
|
unsaved: 'Unsaved changes',
|
|
280
286
|
loading: 'Reading configuration…',
|
|
281
287
|
unavailable: 'This deployment does not serve this configuration.',
|
|
282
288
|
unreadable: 'This account cannot edit the configuration.',
|
|
283
|
-
readOnly: 'This
|
|
289
|
+
readOnly: 'This page is not connected to a configuration form yet; the values below are built-in defaults. Restart DeepSeek Harness, then reopen this page to edit.',
|
|
290
|
+
reload: 'Reload page',
|
|
291
|
+
noService: ' (the configForms service is not connected)',
|
|
284
292
|
fixed: 'Follows the file name',
|
|
285
293
|
fixedHint: 'Derived from the file itself, never stored in the config.',
|
|
286
294
|
emptyValue: 'Leave empty and each file writes its own',
|
|
@@ -357,6 +365,9 @@ const CSS = `
|
|
|
357
365
|
.dcw-status{flex:1 1 200px;margin:0;color:var(--dcw-muted);font-size:12px}
|
|
358
366
|
.dcw-status[data-tone="warn"]{color:var(--dcw-danger)}
|
|
359
367
|
.dcw-status[data-tone="ok"]{color:var(--dsw-alias-state-success-primary,#1a7f37)}
|
|
368
|
+
.dcw-note-code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:11px;opacity:.8;margin-left:6px}
|
|
369
|
+
.dcw-note-action{margin-left:auto;flex:none;padding:3px 10px;border:1px solid currentColor;border-radius:6px;background:transparent;color:inherit;font:inherit;font-size:11.5px;cursor:pointer;white-space:nowrap}
|
|
370
|
+
.dcw-note-action:hover{background:var(--dcw-bg1)}
|
|
360
371
|
@media (max-width:640px){.dcw-row{grid-template-columns:1fr;gap:4px}.dcw-row-label{padding-top:0}.dcw-flags{grid-template-columns:1fr}.dcw-flag:nth-child(2){border-top:1px solid var(--dcw-border)}}
|
|
361
372
|
`
|
|
362
373
|
|
|
@@ -521,10 +532,21 @@ function useFormSnapshot(form) {
|
|
|
521
532
|
return snapshot
|
|
522
533
|
}
|
|
523
534
|
|
|
535
|
+
// 配置卡片本身:状态机、保存/撤销/恢复默认值,以及组合包条目里的挂点。
|
|
536
|
+
// 分片按 scripts/building-client.mjs 的模块表顺序拼接:shell → text → styles →
|
|
537
|
+
// widgets → form-state → 本文件。分片共享同一个工厂作用域,不要各自 require。
|
|
538
|
+
|
|
539
|
+
// 宿主组合包 cordis.patch.yml 插入的 profile 条目 id;设置服务按它定位表单。
|
|
540
|
+
const ENTRY_ID = 'cpp-workflow'
|
|
541
|
+
// configForms 可能晚于本插件挂载;页面在首次绘制后短暂重试,拿不到再给手动恢复入口。
|
|
542
|
+
const FORM_RETRY_MS = 500
|
|
543
|
+
const MAX_FORM_RETRIES = 20
|
|
544
|
+
|
|
524
545
|
function ConfigPage(props) {
|
|
525
546
|
const s = t()
|
|
526
547
|
ensureStyles()
|
|
527
|
-
|
|
548
|
+
// form 由挂点注入;resolveForm 兜住“服务晚到”的部署,拿到后下一次绘制自动接上。
|
|
549
|
+
const form = props.form || (typeof props.resolveForm === 'function' ? props.resolveForm() : undefined)
|
|
528
550
|
const state = useFormSnapshot(form)
|
|
529
551
|
const initial = React.useMemo(() => normalizeConfig(state.value), [])
|
|
530
552
|
const [draft, setDraft] = React.useState(initial)
|
|
@@ -533,11 +555,13 @@ function ConfigPage(props) {
|
|
|
533
555
|
const [busy, setBusy] = React.useState(false)
|
|
534
556
|
const [message, setMessage] = React.useState('')
|
|
535
557
|
const [tone, setTone] = React.useState('')
|
|
558
|
+
const [attempt, setAttempt] = React.useState(0)
|
|
536
559
|
const revision = state.revision
|
|
537
560
|
// 快照只有 status / writable / revision;旧版本多出来的 mode 字段已不存在,
|
|
538
561
|
// 再按它判断会把所有可写表单误判成只读。
|
|
539
|
-
const ready = Boolean(state.status === 'ready' && state.writable)
|
|
562
|
+
const ready = Boolean(form && state.status === 'ready' && state.writable)
|
|
540
563
|
const status = state.status
|
|
564
|
+
const missing = !form
|
|
541
565
|
|
|
542
566
|
React.useEffect(() => {
|
|
543
567
|
if (dirty || state.status !== 'ready') return
|
|
@@ -546,6 +570,12 @@ function ConfigPage(props) {
|
|
|
546
570
|
setDraft(next)
|
|
547
571
|
}, [revision, status, dirty, form, state.value])
|
|
548
572
|
|
|
573
|
+
React.useEffect(() => {
|
|
574
|
+
if (form || attempt >= MAX_FORM_RETRIES || typeof setTimeout !== 'function') return undefined
|
|
575
|
+
const timer = setTimeout(() => setAttempt((value) => value + 1), FORM_RETRY_MS)
|
|
576
|
+
return () => clearTimeout(timer)
|
|
577
|
+
}, [form, attempt])
|
|
578
|
+
|
|
549
579
|
const update = (patch) => {
|
|
550
580
|
setDraft((current) => ({ ...current, ...patch }))
|
|
551
581
|
setDirty(true)
|
|
@@ -553,6 +583,7 @@ function ConfigPage(props) {
|
|
|
553
583
|
setTone('')
|
|
554
584
|
}
|
|
555
585
|
|
|
586
|
+
// 撤销:回到最近一次从宿主读到的值,不写盘。
|
|
556
587
|
const reset = () => {
|
|
557
588
|
setDraft(base)
|
|
558
589
|
setDirty(false)
|
|
@@ -560,6 +591,20 @@ function ConfigPage(props) {
|
|
|
560
591
|
setTone('')
|
|
561
592
|
}
|
|
562
593
|
|
|
594
|
+
// 恢复默认值:只填进草稿,点“保存”后才写盘,避免误触直接覆盖已保存的配置。
|
|
595
|
+
const restoreDefaults = () => {
|
|
596
|
+
setDraft(normalizeConfig(DEFAULT_CONFIG))
|
|
597
|
+
setDirty(true)
|
|
598
|
+
setMessage(s.restored)
|
|
599
|
+
setTone('')
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
const reload = () => {
|
|
603
|
+
if (typeof window !== 'undefined' && window.location && typeof window.location.reload === 'function') {
|
|
604
|
+
window.location.reload()
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
|
|
563
608
|
const save = async () => {
|
|
564
609
|
if (!ready || busy) return
|
|
565
610
|
const operations = diffOperations(draft, base)
|
|
@@ -573,6 +618,9 @@ function ConfigPage(props) {
|
|
|
573
618
|
setMessage(s.saved)
|
|
574
619
|
setTone('ok')
|
|
575
620
|
} else {
|
|
621
|
+
// 被拒时宿主已刷新镜像;把基准对齐到新快照,撤销才不会回到过期值。
|
|
622
|
+
const fresh = snapshotOf(form)
|
|
623
|
+
if (fresh && fresh.status === 'ready') setBase(normalizeConfig(fresh.value))
|
|
576
624
|
setMessage(s.rejected)
|
|
577
625
|
setTone('warn')
|
|
578
626
|
}
|
|
@@ -597,12 +645,22 @@ function ConfigPage(props) {
|
|
|
597
645
|
h('h3', { className: 'dcw-title' }, s.title),
|
|
598
646
|
h('p', { className: 'dcw-lede' }, s.intro),
|
|
599
647
|
),
|
|
600
|
-
|
|
648
|
+
missing
|
|
601
649
|
? h(
|
|
602
650
|
'div',
|
|
603
|
-
{ className: 'dcw-note', role: 'status' },
|
|
651
|
+
{ className: 'dcw-note', role: 'status', 'data-tone': 'warn' },
|
|
604
652
|
h('span', { className: 'dcw-note-dot' }),
|
|
605
|
-
h(
|
|
653
|
+
h(
|
|
654
|
+
'span',
|
|
655
|
+
null,
|
|
656
|
+
s.readOnly,
|
|
657
|
+
props.hasService === false ? h('span', { className: 'dcw-note-code' }, s.noService) : null,
|
|
658
|
+
),
|
|
659
|
+
h(
|
|
660
|
+
'button',
|
|
661
|
+
{ type: 'button', className: 'dcw-note-action', onClick: reload },
|
|
662
|
+
s.reload,
|
|
663
|
+
),
|
|
606
664
|
)
|
|
607
665
|
: null,
|
|
608
666
|
editable && !ready && status !== 'missing'
|
|
@@ -704,24 +762,31 @@ function ConfigPage(props) {
|
|
|
704
762
|
),
|
|
705
763
|
h('button', { type: 'button', className: 'dcw-btn', onClick: reset, disabled: busy || !dirty }, s.reset),
|
|
706
764
|
h(
|
|
707
|
-
'
|
|
708
|
-
{ className: 'dcw-
|
|
709
|
-
|
|
765
|
+
'button',
|
|
766
|
+
{ type: 'button', className: 'dcw-btn', onClick: restoreDefaults, disabled: busy || !ready },
|
|
767
|
+
s.defaults,
|
|
710
768
|
),
|
|
769
|
+
h('p', { className: 'dcw-status', role: 'status', 'data-tone': tone }, message || (dirty ? s.unsaved : '')),
|
|
711
770
|
)
|
|
712
771
|
: null,
|
|
713
772
|
)
|
|
714
773
|
}
|
|
715
774
|
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
function page(ownerProps, form) {
|
|
720
|
-
return h(ConfigPage, { ...(ownerProps || {}), form })
|
|
775
|
+
function page(ownerProps, form, resolveForm, hasService) {
|
|
776
|
+
return h(ConfigPage, { ...(ownerProps || {}), form, resolveForm, hasService })
|
|
721
777
|
}
|
|
722
778
|
|
|
723
779
|
function apply(ctx) {
|
|
724
|
-
|
|
780
|
+
// 每次取表单都重新查询服务:宿主可能在本插件之后才挂载 configForms。
|
|
781
|
+
const resolveForm = () => {
|
|
782
|
+
if (!ctx.configForms || typeof ctx.configForms.get !== 'function') return undefined
|
|
783
|
+
try {
|
|
784
|
+
return ctx.configForms.get(ENTRY_ID)
|
|
785
|
+
} catch {
|
|
786
|
+
return undefined
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
const hasService = Boolean(ctx.configForms && typeof ctx.configForms.get === 'function')
|
|
725
790
|
const mount = () =>
|
|
726
791
|
ctx.slots.inject('plugins.bundle.config', () =>
|
|
727
792
|
ctx.slots.register(
|
|
@@ -730,7 +795,10 @@ function apply(ctx) {
|
|
|
730
795
|
key: PACKAGE_NAME,
|
|
731
796
|
label: () => t().nav,
|
|
732
797
|
},
|
|
733
|
-
(ownerProps) =>
|
|
798
|
+
(ownerProps) =>
|
|
799
|
+
ownerProps && ownerProps.view === 'summary'
|
|
800
|
+
? null
|
|
801
|
+
: page(ownerProps, undefined, resolveForm, hasService),
|
|
734
802
|
),
|
|
735
803
|
)
|
|
736
804
|
if (ctx.configForms && typeof ctx.configForms.whileServed === 'function') {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chengzhao-dev/dsh-cpp-workflow",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.7",
|
|
4
4
|
"description": "写 C++ 源码、配 CMake、用 Clang 构建;头文件用 /// Doxygen 文档注释,函数体用 // 分段说明,文件头标签可在设置里改。 · Write C++ sources, configure CMake, and build with Clang; /// Doxygen on declarations, // section notes in bodies, and configurable file-header tags.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|