dsh-advisor 0.1.0 → 0.1.1

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.i18n.yaml CHANGED
@@ -3,5 +3,5 @@
3
3
  # editing either side, bring the other along and re-record with:
4
4
  # git hash-object README.md
5
5
  # git hash-object README.zh.md
6
- README.md: 9c49bb1959b760bce4db030d92ca5efd57f0cbe7
7
- README.zh.md: e4db627807e12277ab0e516b445ccb35138ba6a9
6
+ README.md: c0096d75da8f4c6e528b24a5bf3cdce6722f0358
7
+ README.zh.md: 6b7c4425bb81764d4bc47a6dc417b7e352fc3769
package/README.md CHANGED
@@ -13,10 +13,10 @@ model are required), and injects severity-ranked advice (nit / concern /
13
13
  blocker) back into the session — without polluting or recursively reviewing
14
14
  itself.
15
15
 
16
- Install with a single command (pnpm ≥ 10 needs one build-allow step — see [Install](#install)):
16
+ Install with a single command:
17
17
 
18
18
  ```sh
19
- dsh plugin --profile web add github:btspoony/dsh-advisor # <name> = your profile name; pin a commit with #<sha>
19
+ dsh plugin --profile web add dsh-advisor # <name> = your profile name
20
20
  ```
21
21
 
22
22
  **Advisory only.** The advisor never approves or rejects the primary agent's
@@ -27,21 +27,18 @@ policy) so it can never stall or pollute the primary loop.
27
27
 
28
28
  ## Install
29
29
 
30
- ### One-line git install
30
+ ### One-line registry install
31
31
 
32
32
  ```sh
33
- dsh plugin --profile web add github:btspoony/dsh-advisor # <name> = your profile name; pin a commit with #<sha>
33
+ dsh plugin --profile web add dsh-advisor # <name> = your profile name
34
34
  ```
35
35
 
36
- A git install fetches **sources, not built artifacts**, so the bundle builds
37
- itself on install (`prepare` self-build). pnpm 10 blocks a git dependency's
38
- `prepare` by default: the first
39
- `add` fails with `ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED`, and pnpm prints the
40
- exact package key allow the build in the profile's `pnpm-workspace.yaml`
41
- (`onlyBuiltDependencies: [dsh-advisor]`, or run `dsh plugin --profile web
42
- approve-builds`), then re-run the `add`. Treat that allowance as permission to
43
- execute the package's code on your machine at install time, and pin a commit
44
- (`#<sha>`) so a later push cannot silently change what runs.
36
+ A registry install fetches the published tarball, which ships the built
37
+ artifacts (`lib/` + `cordis.patch.yml`), so no `prepare` build or build
38
+ permission is needed. Runtime dependencies (`@deepseek-ai/cordis`, `@deepseek-ai/schemastery`,
39
+ and the `@deepseek-ai/dsh-*` peers) are declared as peerDependencies and resolve
40
+ through the dsh installation's flat profile module fallback no extra install
41
+ step. Pin an exact version (`dsh-advisor@0.1.0`) for reproducible installs.
45
42
 
46
43
  ### Local directory install (recommended for development / verification)
47
44
 
@@ -280,7 +277,7 @@ bin-less cordis shim at `node_modules/@deepseek-ai/cordis` answers the scoped
280
277
  name and resolves to the vendored files, because the real packages type and
281
278
  run against the vendored build and module identity requires dev-time
282
279
  `import '@deepseek-ai/cordis'` to resolve to the same files. The public
283
- devDependencies (`schemastery`, `react`, …) resolve from the npm registry as
280
+ devDependencies (`@deepseek-ai/schemastery`, `react`, …) resolve from the npm registry as
284
281
  usual.
285
282
 
286
283
  `prepack` runs `pnpm build`; `prepare` runs the link farm and the build, so
package/README.zh.md CHANGED
@@ -8,23 +8,23 @@
8
8
 
9
9
  一个移植 omp「advisor」子系统的独立 dsh 插件组合包:一个按会话运行的评审模型,观察主会话 transcript,用显式配置的模型(provider 与 model 均为必填)评审每个已完成的 stepped turn,并把按严重度排序的建议(nit / concern / blocker)注入回会话 —— 不污染主循环,也不递归地评审自己。
10
10
 
11
- 一条命令即可安装(pnpm ≥ 10 需要一次构建放行步骤 —— 见[安装](#安装)):
11
+ 一条命令即可安装:
12
12
 
13
13
  ```sh
14
- dsh plugin --profile web add github:btspoony/dsh-advisor # <name> = 你的 profile 名;用 #<sha> 钉住 commit
14
+ dsh plugin --profile web add dsh-advisor # <name> = 你的 profile
15
15
  ```
16
16
 
17
17
  **仅作建议。** advisor 从不批准或否决主 agent 的动作,也绝不会像主 agent 那样发出命令。每条送达的消息都是自我描述的 advisory 内容;一个行为异常的评审者会被端到端约束(emission guard、immuneTurns 冷却、failure policy),因此它永远不会卡住或污染主循环。
18
18
 
19
19
  ## 安装
20
20
 
21
- ### 一条命令的 git 安装
21
+ ### 一条命令的 registry 安装
22
22
 
23
23
  ```sh
24
- dsh plugin --profile web add github:btspoony/dsh-advisor # <name> = 你的 profile 名;用 #<sha> 钉住 commit
24
+ dsh plugin --profile web add dsh-advisor # <name> = 你的 profile
25
25
  ```
26
26
 
27
- git 安装拉取的是**源码而非构建产物**,因此组合包会在安装时自行构建(`prepare` 自建)。pnpm 10 默认拦截 git 依赖的 `prepare`:第一次 `add` 会报 `ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED`,pnpm 会打印出确切的包 key —— profile `pnpm-workspace.yaml` 中放行构建(`onlyBuiltDependencies: [dsh-advisor]`,或运行 `dsh plugin --profile web approve-builds`),然后重新执行 `add`。请把这次放行当作它本来的样子:允许该包的代码在安装时于你的机器上执行;并钉住 commit(`#<sha>`),这样之后的 push 无法悄悄改变实际运行的代码。
27
+ registry 安装拉取的是已发布的 tarball,其中自带构建产物(`lib/` + `cordis.patch.yml`),因此不会运行 `prepare` 构建,也无需构建放行。运行时依赖(`@deepseek-ai/cordis`、`@deepseek-ai/schemastery` `@deepseek-ai/dsh-*` peers)声明为 peerDependencies,由 dsh 安装的扁平 profile module fallback 解析——无需额外安装步骤。需要可复现安装时用 `dsh-advisor@0.1.0` 钉住精确版本。
28
28
 
29
29
  ### 本地目录安装(推荐用于开发 / 验证)
30
30
 
@@ -149,7 +149,7 @@ pnpm pack # build + produce dsh-advisor-0.0.1.tgz
149
149
 
150
150
  Windows 上链接农场的目录条目以 junction 创建(无需特权),但 cordis shim 的文件条目使用文件符号链接,需要开启[开发者模式](https://learn.microsoft.com/windows/apps/get-started/enable-your-device-for-development)(或以管理员 shell 运行)——请先开启再执行 `pnpm install`。Windows 没有 `HOME`,脚本回退到 `USERPROFILE` 解析 dsh 源码树。
151
151
 
152
- 内置 `cordis` 框架声明为 scoped peer `@deepseek-ai/cordis: ^4.0.1-rc.1`(范围必须带精确的发布 tag —— 带 prerelease 的 comparator 只匹配同 `[major, minor, patch]` tuple,`^4.0.0-rc.7` 永远不匹配 vendored 的 `4.0.1-rc.1`);安装后链接农场的无 bin cordis shim 位于 `node_modules/@deepseek-ai/cordis`,以 scoped 名应答并解析到 vendored 文件,因为真实包是对着 vendored 构建类型化/运行的,模块身份要求开发期的 `import '@deepseek-ai/cordis'` 解析到同一份文件。其余公开 devDependencies(`schemastery`、`react` 等)照常从 npm registry 解析。
152
+ 内置 `cordis` 框架声明为 scoped peer `@deepseek-ai/cordis: ^4.0.1-rc.1`(范围必须带精确的发布 tag —— 带 prerelease 的 comparator 只匹配同 `[major, minor, patch]` tuple,`^4.0.0-rc.7` 永远不匹配 vendored 的 `4.0.1-rc.1`);安装后链接农场的无 bin cordis shim 位于 `node_modules/@deepseek-ai/cordis`,以 scoped 名应答并解析到 vendored 文件,因为真实包是对着 vendored 构建类型化/运行的,模块身份要求开发期的 `import '@deepseek-ai/cordis'` 解析到同一份文件。其余公开 devDependencies(`@deepseek-ai/schemastery`、`react` 等)照常从 npm registry 解析。
153
153
 
154
154
  `prepack` 运行 `pnpm build`;`prepare` 运行链接农场与构建,因此 `pnpm pack` 会构建两次(每个生命周期一次)——这是为保持 git 安装可构建而接受的取舍。没有 `postinstall` 步骤:tarball 安装已带构建产物,完全跳过构建。
155
155
 
package/lib/client.js CHANGED
@@ -35,7 +35,7 @@ var import_dsh_client_web_react = require("@deepseek-ai/dsh-client-web-react");
35
35
  var import_react = require("react");
36
36
  var import_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
37
37
 
38
- var css = `.fgpdlq_card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;list-style:none;transition:border-color .16s,background .16s}.fgpdlq_card:hover{border-color:var(--dsw-alias-label-dimmed)}.fgpdlq_cardOpen{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}.fgpdlq_header{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}.fgpdlq_header:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}.fgpdlq_headText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.fgpdlq_name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}.fgpdlq_description{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}.fgpdlq_chevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}.fgpdlq_chevronOpen{transform:rotate(180deg)}.fgpdlq_body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}.fgpdlq_readOnly{color:var(--dsw-alias-label-tertiary);margin:12px 0 0;font-size:12px;line-height:1.5}.fgpdlq_pending{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.fgpdlq_footer{border-top:1px solid var(--dsw-alias-border-l2);justify-content:flex-end;align-items:center;gap:8px;padding:12px 0 4px;display:flex}.fgpdlq_failed{min-width:0;color:var(--dsw-alias-label-error);flex:1;margin:0;font-size:12px;line-height:1.5}.fgpdlq_discard,.fgpdlq_save{appearance:none;font:inherit;cursor:pointer;border:1px solid #0000;border-radius:8px;padding:5px 14px;font-size:13px;line-height:1.5}.fgpdlq_discard{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:0 0}.fgpdlq_discard:hover:not(:disabled){color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed)}.fgpdlq_save{background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3)}.fgpdlq_discard:disabled,.fgpdlq_save:disabled{opacity:.4;cursor:default}.fgpdlq_discard:focus-visible,.fgpdlq_save:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}.fgpdlq_notice{color:var(--dsw-alias-state-warn-label);margin:12px 0 0;font-size:12px;line-height:18px}.fgpdlq_savedNotice{color:var(--dsw-alias-state-success-primary);margin:12px 0 0;font-size:12px;line-height:18px}.fgpdlq_error{color:var(--dsw-alias-state-error-primary);margin:12px 0 0;font-size:12px;line-height:18px}.fgpdlq_form{flex-direction:column;gap:12px;padding:12px 0 0;display:flex}.fgpdlq_checkboxRow{align-items:center;gap:8px;display:flex}.fgpdlq_checkLabel{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:500;line-height:22px}.fgpdlq_checkbox{width:16px;height:16px;accent-color:var(--dsw-alias-brand-primary);cursor:pointer;margin:0}.fgpdlq_checkbox:disabled{opacity:.4;cursor:default}.fgpdlq_checkbox:focus-visible{outline:2px solid var(--dsw-alias-border-l3);outline-offset:2px}.fgpdlq_fieldset{border:none;flex-direction:column;gap:12px;margin:0;padding:0;display:flex}.fgpdlq_field{flex-direction:column;gap:6px;display:flex}.fgpdlq_fieldLabel{color:var(--dsw-alias-label-secondary);align-items:center;gap:10px;font-size:12px;font-weight:500;line-height:18px;display:inline-flex}.fgpdlq_input{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);width:100%;height:32px;font:inherit;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 10px;font-size:14px;line-height:22px}select.fgpdlq_input{cursor:pointer;max-width:240px}.fgpdlq_input:focus{border-color:var(--dsw-alias-brand-primary);outline:none}.fgpdlq_input::placeholder{color:var(--dsw-alias-label-dimmed)}.fgpdlq_input:disabled{opacity:.6;cursor:default}.fgpdlq_selectInput{appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' stroke='%2381858C' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");background-position:right 12px center;background-repeat:no-repeat;background-size:12px 12px;padding-right:32px}.fgpdlq_textarea{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);width:100%;min-height:96px;font:inherit;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);resize:vertical;border-radius:8px;padding:8px 10px;font-size:14px;line-height:22px}.fgpdlq_textarea:focus{border-color:var(--dsw-alias-brand-primary);outline:none}.fgpdlq_textarea:disabled{opacity:.6;cursor:default}.fgpdlq_numberFields{grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px;display:grid}.fgpdlq_hint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:18px}.fgpdlq_warnHint{color:var(--dsw-alias-state-warn-label);margin:0;font-size:12px;line-height:18px}`;
38
+ var css = `.kPHV8a_card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;list-style:none;transition:border-color .16s,background .16s}.kPHV8a_card:hover{border-color:var(--dsw-alias-label-dimmed)}.kPHV8a_cardOpen{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}.kPHV8a_header{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}.kPHV8a_header:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}.kPHV8a_headText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.kPHV8a_name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}.kPHV8a_description{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}.kPHV8a_chevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}.kPHV8a_chevronOpen{transform:rotate(180deg)}.kPHV8a_body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}.kPHV8a_readOnly{color:var(--dsw-alias-label-tertiary);margin:12px 0 0;font-size:12px;line-height:1.5}.kPHV8a_pending{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.kPHV8a_footer{border-top:1px solid var(--dsw-alias-border-l2);justify-content:flex-end;align-items:center;gap:8px;padding:12px 0 4px;display:flex}.kPHV8a_failed{min-width:0;color:var(--dsw-alias-label-error);flex:1;margin:0;font-size:12px;line-height:1.5}.kPHV8a_discard,.kPHV8a_save{appearance:none;font:inherit;cursor:pointer;border:1px solid #0000;border-radius:8px;padding:5px 14px;font-size:13px;line-height:1.5}.kPHV8a_discard{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:0 0}.kPHV8a_discard:hover:not(:disabled){color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-dimmed)}.kPHV8a_save{background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3)}.kPHV8a_discard:disabled,.kPHV8a_save:disabled{opacity:.4;cursor:default}.kPHV8a_discard:focus-visible,.kPHV8a_save:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}.kPHV8a_notice{color:var(--dsw-alias-state-warn-label);margin:12px 0 0;font-size:12px;line-height:18px}.kPHV8a_savedNotice{color:var(--dsw-alias-state-success-primary);margin:12px 0 0;font-size:12px;line-height:18px}.kPHV8a_error{color:var(--dsw-alias-state-error-primary);margin:12px 0 0;font-size:12px;line-height:18px}.kPHV8a_form{flex-direction:column;gap:12px;padding:12px 0 0;display:flex}.kPHV8a_checkboxRow{align-items:center;gap:8px;display:flex}.kPHV8a_checkLabel{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:500;line-height:22px}.kPHV8a_checkbox{width:16px;height:16px;accent-color:var(--dsw-alias-brand-primary);cursor:pointer;margin:0}.kPHV8a_checkbox:disabled{opacity:.4;cursor:default}.kPHV8a_checkbox:focus-visible{outline:2px solid var(--dsw-alias-border-l3);outline-offset:2px}.kPHV8a_fieldset{border:none;flex-direction:column;gap:12px;margin:0;padding:0;display:flex}.kPHV8a_field{flex-direction:column;gap:6px;display:flex}.kPHV8a_fieldLabel{color:var(--dsw-alias-label-secondary);align-items:center;gap:10px;font-size:12px;font-weight:500;line-height:18px;display:inline-flex}.kPHV8a_input{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);width:100%;height:32px;font:inherit;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 10px;font-size:14px;line-height:22px}select.kPHV8a_input{cursor:pointer;max-width:240px}.kPHV8a_input:focus{border-color:var(--dsw-alias-brand-primary);outline:none}.kPHV8a_input::placeholder{color:var(--dsw-alias-label-dimmed)}.kPHV8a_input:disabled{opacity:.6;cursor:default}.kPHV8a_selectInput{appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' stroke='%2381858C' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");background-position:right 12px center;background-repeat:no-repeat;background-size:12px 12px;padding-right:32px}.kPHV8a_textarea{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);width:100%;min-height:96px;font:inherit;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);resize:vertical;border-radius:8px;padding:8px 10px;font-size:14px;line-height:22px}.kPHV8a_textarea:focus{border-color:var(--dsw-alias-brand-primary);outline:none}.kPHV8a_textarea:disabled{opacity:.6;cursor:default}.kPHV8a_numberFields{grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px;display:grid}.kPHV8a_hint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:18px}.kPHV8a_warnHint{color:var(--dsw-alias-state-warn-label);margin:0;font-size:12px;line-height:18px}`;
39
39
  var tagId = "dsh-advisor/advisor-card.module.css";
40
40
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
41
41
  const tag = document.createElement("style");
@@ -44,7 +44,7 @@ if (typeof document !== "undefined" && document.querySelector("style[data-plugin
44
44
  tag.textContent = css;
45
45
  document.head.appendChild(tag);
46
46
  }
47
- var advisor_card_module_css_default = { "body": "fgpdlq_body", "card": "fgpdlq_card", "cardOpen": "fgpdlq_cardOpen", "checkLabel": "fgpdlq_checkLabel", "checkbox": "fgpdlq_checkbox", "checkboxRow": "fgpdlq_checkboxRow", "chevron": "fgpdlq_chevron", "chevronOpen": "fgpdlq_chevronOpen", "description": "fgpdlq_description", "discard": "fgpdlq_discard", "error": "fgpdlq_error", "failed": "fgpdlq_failed", "field": "fgpdlq_field", "fieldLabel": "fgpdlq_fieldLabel", "fieldset": "fgpdlq_fieldset", "footer": "fgpdlq_footer", "form": "fgpdlq_form", "headText": "fgpdlq_headText", "header": "fgpdlq_header", "hint": "fgpdlq_hint", "input": "fgpdlq_input", "name": "fgpdlq_name", "notice": "fgpdlq_notice", "numberFields": "fgpdlq_numberFields", "pending": "fgpdlq_pending", "readOnly": "fgpdlq_readOnly", "save": "fgpdlq_save", "savedNotice": "fgpdlq_savedNotice", "selectInput": "fgpdlq_selectInput", "textarea": "fgpdlq_textarea", "warnHint": "fgpdlq_warnHint" };
47
+ var advisor_card_module_css_default = { "body": "kPHV8a_body", "card": "kPHV8a_card", "cardOpen": "kPHV8a_cardOpen", "checkLabel": "kPHV8a_checkLabel", "checkbox": "kPHV8a_checkbox", "checkboxRow": "kPHV8a_checkboxRow", "chevron": "kPHV8a_chevron", "chevronOpen": "kPHV8a_chevronOpen", "description": "kPHV8a_description", "discard": "kPHV8a_discard", "error": "kPHV8a_error", "failed": "kPHV8a_failed", "field": "kPHV8a_field", "fieldLabel": "kPHV8a_fieldLabel", "fieldset": "kPHV8a_fieldset", "footer": "kPHV8a_footer", "form": "kPHV8a_form", "headText": "kPHV8a_headText", "header": "kPHV8a_header", "hint": "kPHV8a_hint", "input": "kPHV8a_input", "name": "kPHV8a_name", "notice": "kPHV8a_notice", "numberFields": "kPHV8a_numberFields", "pending": "kPHV8a_pending", "readOnly": "kPHV8a_readOnly", "save": "kPHV8a_save", "savedNotice": "kPHV8a_savedNotice", "selectInput": "kPHV8a_selectInput", "textarea": "kPHV8a_textarea", "warnHint": "kPHV8a_warnHint" };
48
48
 
49
49
  // src/client/advisor-card.tsx
50
50
  var import_jsx_runtime = require("react/jsx-runtime");
package/lib/config.d.ts CHANGED
@@ -11,7 +11,7 @@
11
11
  *
12
12
  * @module dsh-advisor/config
13
13
  */
14
- import z from 'schemastery';
14
+ import z from '@deepseek-ai/schemastery';
15
15
  /** Raw plugin row config after Loader defaults — spec §5.1. */
16
16
  export interface AdvisorConfig {
17
17
  /** Master switch; default false. */
package/lib/config.js CHANGED
@@ -11,7 +11,7 @@
11
11
  *
12
12
  * @module dsh-advisor/config
13
13
  */
14
- import z from 'schemastery';
14
+ import z from '@deepseek-ai/schemastery';
15
15
  /**
16
16
  * Complete configuration key set for strict unknown-key rejection. The
17
17
  * schemastery object resolver merges unknown keys by default (strict flag is
package/lib/config.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,CAAC,MAAM,aAAa,CAAA;AA8B3B;;;;;GAKG;AACH,MAAM,WAAW,GAAwB,IAAI,GAAG,CAAC;IAC/C,SAAS;IACT,UAAU;IACV,OAAO;IACP,cAAc;IACd,aAAa;IACb,kBAAkB;CACnB,CAAC,CAAA;AAEF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7B,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IACnC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IACpC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IACjD,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CACxD,CAAC,CAAA;AAEF,SAAS,gBAAgB,CAAC,KAAyB;IACjD,2EAA2E;IAC3E,2EAA2E;IAC3E,kEAAkE;IAClE,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAA;AAC7D,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAAC,GAAY;IAC/C,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAClE,MAAM,IAAI,SAAS,CAAC,mDAAmD,CAAC,CAAA;IAC1E,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACnC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,oCAAoC,GAAG,GAAG,CAAC,CAAA;QAC7D,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;IAC1B,wEAAwE;IACxE,yEAAyE;IACzE,yDAAyD;IACzD,MAAM,UAAU,GAAkB;QAChC,GAAG,MAAM;QACT,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,SAAS;QACtC,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,SAAS;KACjC,CAAA;IACD,IAAI,CAAC,UAAU,CAAC,OAAO;QAAE,OAAO,UAAU,CAAA;IAC1C,MAAM,OAAO,GAAa,EAAE,CAAA;IAC5B,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IACpE,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IAC9D,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,UAAU,CAAA;IAC3C,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,KAAK,CAAC;QACzC,CAAC,CAAC,mFAAmF;QACrF,CAAC,CAAC,eAAe,OAAO,CAAC,CAAC,CAAC,qDAAqD,CAAA;IAClF,OAAO,EAAE,GAAG,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,CAAA;AAC1D,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,CAAC,MAAM,0BAA0B,CAAA;AA8BxC;;;;;GAKG;AACH,MAAM,WAAW,GAAwB,IAAI,GAAG,CAAC;IAC/C,SAAS;IACT,UAAU;IACV,OAAO;IACP,cAAc;IACd,aAAa;IACb,kBAAkB;CACnB,CAAC,CAAA;AAEF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7B,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IACnC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IACpC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IACjD,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CACxD,CAAC,CAAA;AAEF,SAAS,gBAAgB,CAAC,KAAyB;IACjD,2EAA2E;IAC3E,2EAA2E;IAC3E,kEAAkE;IAClE,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAA;AAC7D,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAAC,GAAY;IAC/C,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAClE,MAAM,IAAI,SAAS,CAAC,mDAAmD,CAAC,CAAA;IAC1E,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACnC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,oCAAoC,GAAG,GAAG,CAAC,CAAA;QAC7D,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;IAC1B,wEAAwE;IACxE,yEAAyE;IACzE,yDAAyD;IACzD,MAAM,UAAU,GAAkB;QAChC,GAAG,MAAM;QACT,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,SAAS;QACtC,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,SAAS;KACjC,CAAA;IACD,IAAI,CAAC,UAAU,CAAC,OAAO;QAAE,OAAO,UAAU,CAAA;IAC1C,MAAM,OAAO,GAAa,EAAE,CAAA;IAC5B,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IACpE,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IAC9D,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,UAAU,CAAA;IAC3C,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,KAAK,CAAC;QACzC,CAAC,CAAC,mFAAmF;QACrF,CAAC,CAAC,eAAe,OAAO,CAAC,CAAC,CAAC,qDAAqD,CAAA;IAClF,OAAO,EAAE,GAAG,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,CAAA;AAC1D,CAAC"}
package/package.json CHANGED
@@ -1,8 +1,12 @@
1
1
  {
2
2
  "name": "dsh-advisor",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "type": "module",
5
5
  "description": "dsh plugin bundle porting the omp advisor subsystem: a per-session reviewer model that observes the primary transcript and injects severity-ranked advice (nit/concern/blocker).",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/omdsh-dev/dsh-advisor"
9
+ },
6
10
  "keywords": [
7
11
  "dsh",
8
12
  "dsh-plugin"
@@ -66,7 +70,7 @@
66
70
  "@deepseek-ai/dsh-typert-protocol": "^0.1.0-rc.6",
67
71
  "@deepseek-ai/dsh-typert-registry": "^0.1.0-rc.6",
68
72
  "react": "^18.2.0",
69
- "schemastery": "^3.18.0"
73
+ "@deepseek-ai/schemastery": "^3.18.1"
70
74
  },
71
75
  "devDependencies": {
72
76
  "@testing-library/dom": "^10.4.1",
@@ -79,7 +83,6 @@
79
83
  "lightningcss": "^1.33.0",
80
84
  "react": "^18.3.1",
81
85
  "react-dom": "^18.3.1",
82
- "schemastery": "^3.18.0",
83
86
  "typescript": "^5.6.0",
84
87
  "vitest": "^3.0.0"
85
88
  },
@@ -0,0 +1,190 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Release-prep version helper (plan dsh-advisor-ci-release, task 2 + 4):
4
+ * resolves the target version — explicit `X.Y.Z` / `X.Y.Z-prerelease`
5
+ * argument (e.g. 0.1.1-alpha.1) or an auto patch bump from package.json —
6
+ * refuses already-released versions (existing `v<version>` git tag), bumps
7
+ * package.json, inserts the `## [<version>]` section into CHANGELOG.md (from
8
+ * the same git-log notes the workflows use; keeps existing sections, no-op
9
+ * when already present), and prints `VERSION=<version>` for the workflow to
10
+ * capture. Node built-ins only, no new dependencies.
11
+ *
12
+ * Usage:
13
+ * node scripts/prepare-release.mjs # auto patch bump
14
+ * node scripts/prepare-release.mjs 0.2.0 # explicit version
15
+ * node scripts/prepare-release.mjs 0.1.1-alpha.1 # explicit prerelease
16
+ *
17
+ * Exit codes: 0 = bumped and printed VERSION; 1 = rejected (unparseable
18
+ * version, existing tag, unparseable current package.json version, or
19
+ * CHANGELOG.md write error).
20
+ */
21
+
22
+ import { execFileSync } from 'node:child_process'
23
+ import { readFileSync, writeFileSync } from 'node:fs'
24
+ import { dirname, join } from 'node:path'
25
+ import { fileURLToPath } from 'node:url'
26
+
27
+ const REPO_ROOT = join(dirname(fileURLToPath(import.meta.url)), '..')
28
+ const PKG_PATH = join(REPO_ROOT, 'package.json')
29
+ const CHANGELOG_PATH = join(REPO_ROOT, 'CHANGELOG.md')
30
+ const CHANGELOG_HEADER =
31
+ '# Changelog\n\nAll notable changes to dsh-advisor are documented here. Generated from git log by the release-prep workflow.\n'
32
+
33
+ /**
34
+ * Parse X.Y.Z or X.Y.Z[-prerelease] (numeric parts; optional prerelease
35
+ * suffix); null when not parseable. The suffix character set matches the
36
+ * workflows' guard regex `[0-9A-Za-z.-]+` (keep-simple: no leading-zero or
37
+ * empty-identifier rules), with one tightening: the suffix MUST contain at
38
+ * least one digit, so `0.1.1-alpha.1` / `0.1.1-rc.2` parse but `0.1.1-alpha`
39
+ * (no numeric identifier) and `0.1.1-` (empty suffix) are rejected. Returns
40
+ * { major, minor, patch, prerelease? } — prerelease is the raw suffix text
41
+ * (e.g. 'alpha.1') when present, undefined for formal versions.
42
+ */
43
+ function parseVersion(value) {
44
+ const match = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]*[0-9][0-9A-Za-z.-]*))?$/.exec(value)
45
+ if (!match) return null
46
+ return {
47
+ major: Number(match[1]),
48
+ minor: Number(match[2]),
49
+ patch: Number(match[3]),
50
+ prerelease: match[4] === undefined ? undefined : match[4],
51
+ }
52
+ }
53
+
54
+ const pkg = JSON.parse(readFileSync(PKG_PATH, 'utf8'))
55
+
56
+ let target
57
+ if (process.argv[2] !== undefined) {
58
+ target = parseVersion(process.argv[2])
59
+ if (target === null) {
60
+ console.error(`Error: invalid version "${process.argv[2]}". Expected X.Y.Z or X.Y.Z-prerelease (e.g. 0.2.0, 0.1.1-alpha.1).`)
61
+ process.exit(1)
62
+ }
63
+ } else {
64
+ const current = parseVersion(pkg.version)
65
+ if (current === null) {
66
+ console.error(`Error: cannot parse current package.json version "${pkg.version}".`)
67
+ process.exit(1)
68
+ }
69
+ // Auto patch bump: bump the numeric patch part and DROP any prerelease
70
+ // suffix (a prerelease base 0.1.1-alpha.1 with no explicit arg -> 0.1.2,
71
+ // i.e. the next formal patch after the 0.1.1 line). An explicit prerelease
72
+ // argument is the way to prepare another prerelease (e.g. 0.1.1-alpha.2).
73
+ target = { major: current.major, minor: current.minor, patch: current.patch + 1 }
74
+ }
75
+
76
+ const version =
77
+ target.prerelease === undefined
78
+ ? `${target.major}.${target.minor}.${target.patch}`
79
+ : `${target.major}.${target.minor}.${target.patch}-${target.prerelease}`
80
+
81
+ // Reject already-released versions: `git rev-parse v<version>` succeeds iff
82
+ // the tag exists. Works unchanged for prerelease tags (v0.1.1-alpha.1 is a
83
+ // plain tag name). Run from REPO_ROOT so the check is cwd-independent.
84
+ try {
85
+ execFileSync('git', ['rev-parse', `v${version}`], { cwd: REPO_ROOT, stdio: 'ignore' })
86
+ console.error(`Error: tag v${version} already exists — this version is already released.`)
87
+ process.exit(1)
88
+ } catch {
89
+ // Tag absent → OK to prepare.
90
+ }
91
+
92
+ pkg.version = version
93
+ // Preserve repo formatting: 2-space indent + trailing newline. The version
94
+ // line must be the only diff (verified by `git diff package.json` in the
95
+ // dry-run validation).
96
+ writeFileSync(PKG_PATH, `${JSON.stringify(pkg, null, 2)}\n`, 'utf8')
97
+
98
+ /**
99
+ * Release notes since the previous release: first-parent commit subjects
100
+ * between the nearest ancestor tag of HEAD and HEAD. Same snippet the
101
+ * workflows use for the PR body — the CHANGELOG section and the PR body
102
+ * stay consistent. When no ancestor tag exists yet, the notes span the full
103
+ * first-parent history. Do NOT use "v$VERSION^": the version string is not a
104
+ * git ref — the bump commit is not tagged yet.
105
+ */
106
+ function collectReleaseNotes() {
107
+ let prevTag = ''
108
+ try {
109
+ prevTag = execFileSync('git', ['describe', '--tags', '--abbrev=0', 'HEAD'], {
110
+ cwd: REPO_ROOT,
111
+ encoding: 'utf8',
112
+ stdio: ['ignore', 'pipe', 'ignore'],
113
+ }).trim()
114
+ } catch {
115
+ // No ancestor tag yet → full history.
116
+ }
117
+ const range = prevTag === '' ? 'HEAD' : `${prevTag}..HEAD`
118
+ return execFileSync('git', ['log', '--oneline', '--first-parent', range], {
119
+ cwd: REPO_ROOT,
120
+ encoding: 'utf8',
121
+ stdio: ['ignore', 'pipe', 'ignore'],
122
+ }).trim()
123
+ }
124
+
125
+ /**
126
+ * Insert a `## [<version>] - <YYYY-MM-DD>` section under the `# Changelog`
127
+ * header, above the existing sections, from the same git-log notes the
128
+ * workflows use. Preserves all existing sections; no-op when the section for
129
+ * this version already exists (idempotent re-runs must not duplicate it);
130
+ * write failures exit 1.
131
+ */
132
+ function updateChangelog(version) {
133
+ let content
134
+ try {
135
+ content = readFileSync(CHANGELOG_PATH, 'utf8')
136
+ } catch {
137
+ content = CHANGELOG_HEADER
138
+ }
139
+ // A 0-byte CHANGELOG.md (e.g. manual truncation) is treated as missing:
140
+ // an empty file must still bootstrap with the standard header, otherwise
141
+ // the new section would land at the top with leading blank lines and no
142
+ // `# Changelog` header.
143
+ if (content === '') {
144
+ content = CHANGELOG_HEADER
145
+ }
146
+
147
+ if (content.includes(`## [${version}]`)) {
148
+ return
149
+ }
150
+
151
+ const notes = collectReleaseNotes()
152
+ const sectionHeader = `## [${version}] - ${new Date().toISOString().slice(0, 10)}`
153
+ const sectionBody =
154
+ notes === ''
155
+ ? 'No commits between releases.'
156
+ : notes
157
+ .split('\n')
158
+ .map((line) => `- ${line}`)
159
+ .join('\n')
160
+ // The section's own trailing `\n` plus the inserted `\n` below form the
161
+ // blank-line separator between the new section and the existing sections.
162
+ const section = `${sectionHeader}\n\n${sectionBody}\n`
163
+
164
+ // Insert on the first `## [` section header via string slice: everything
165
+ // at and below the insertion point — including the file's exact trailing
166
+ // newline — is preserved byte-for-byte. (A split('\n')/splice/join('\n')
167
+ // round-trip would re-normalize line breaks and could alter the tail, e.g.
168
+ // appending a trailing newline that was not in the source file.)
169
+ const firstSectionMatch = /^## \[/m.exec(content)
170
+ const firstSectionIdx = firstSectionMatch === null ? -1 : firstSectionMatch.index
171
+ let next
172
+ if (firstSectionIdx === -1) {
173
+ // No sections yet — append the new section after the header block,
174
+ // keeping the file's own trailing-newline state.
175
+ next = content.endsWith('\n') ? `${content}\n${section}` : `${content}\n\n${section}`
176
+ } else {
177
+ next = `${content.slice(0, firstSectionIdx)}${section}\n${content.slice(firstSectionIdx)}`
178
+ }
179
+
180
+ try {
181
+ writeFileSync(CHANGELOG_PATH, next, 'utf8')
182
+ } catch (error) {
183
+ console.error(`Error: cannot write ${CHANGELOG_PATH}: ${error.message}`)
184
+ process.exit(1)
185
+ }
186
+ }
187
+
188
+ updateChangelog(version)
189
+
190
+ console.log(`VERSION=${version}`)