dsh-plugin-effort-declare 0.1.2 → 0.1.3

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.
@@ -16,12 +16,13 @@ Canonical level names and `thinkingFormat` values follow `@deepseek-ai/dsh-llm-p
16
16
  | File | Role |
17
17
  | --- | --- |
18
18
  | [`catalog.ts`](./catalog.ts) | Canonical level order, `thinkingFormat` fallback list, `llm-pi-ai` / DeepSeek constants. |
19
- | [`efforts.ts`](./efforts.ts) | `reasoningEfforts` read/write, Off tri-state, validation (empty object / Off-only / unknown keys return an error code, never throw). |
19
+ | [`efforts.ts`](./efforts.ts) | `reasoningEfforts` read/write, Off tri-state (value mode stores `trim()`), validation (empty object / Off-only / unknown keys return an error code, never throw). |
20
20
  | [`presets.ts`](./presets.ts) | DeepSeek, OpenAI, and on/off presets; each states all three dialect keys; spread onto existing model rows and route `compat`. |
21
21
  | [`path-ops.ts`](./path-ops.ts) | Same one-level key diff as the official Models page; `buildSaveOps` uses `settingsPath` and only submits that route’s full `models` table and dirty `compat` keys. |
22
22
  | [`drafts.ts`](./drafts.ts) | User-layer drafts, dirty aligned with pathOps, post-save revision. On refresh, latest user-layer model membership wins; unsaved `reasoningEfforts` (including a cleared key) overlay by id; `compat` is a per-key 3-way merge. Conflict only when a locally dirty field also moved in originals (revision-only bumps and sibling-card saves do not warn). |
23
23
  | [`paths.ts`](./paths.ts) | Nested reads; clones of objects and model tables (non-object rows skipped). |
24
24
  | [`filter.ts`](./filter.ts) | Which routes are editable: hand-declared `llm-pi-ai` + openai-completions; skip catalog and official DeepSeek. |
25
25
  | [`validate.ts`](./validate.ts) | Per-row `reasoningEfforts` validation. |
26
+ | [`attribution.ts`](./attribution.ts) | Settings footer line: `version © year Stardust`. Start year is 2026; end year is the UTC year at pack time, not the user’s clock when DSH starts. |
26
27
 
27
28
  An **absent** field means default-off. Do not encode “undeclared” as `reasoningEfforts: false` — in official semantics `false` strips reasoning from a catalog model.
@@ -16,12 +16,13 @@
16
16
  | 文件 | 说明 |
17
17
  | --- | --- |
18
18
  | [`catalog.ts`](./catalog.ts) | 规范档位顺序、`thinkingFormat` 回退列表、`llm-pi-ai` / DeepSeek 相关常量。 |
19
- | [`efforts.ts`](./efforts.ts) | `reasoningEfforts` 读写、Off 三态、校验(空对象 / 只开 Off / 未知键返回错误码,不抛异常)。 |
19
+ | [`efforts.ts`](./efforts.ts) | `reasoningEfforts` 读写、Off 三态(value 模式写入 `trim()` 后的字符串)、校验(空对象 / 只开 Off / 未知键返回错误码,不抛异常)。 |
20
20
  | [`presets.ts`](./presets.ts) | DeepSeek、OpenAI、仅开/关三套预设;每套对三个方言键都表态;spread 到已有模型行与路由 `compat`。 |
21
21
  | [`path-ops.ts`](./path-ops.ts) | 与官方模型页相同的一层键 diff;`buildSaveOps` 使用 `settingsPath`,只提交该路由的 `models` 整表和有差异的 `compat` 键。 |
22
22
  | [`drafts.ts`](./drafts.ts) | 用户层草稿、dirty 与 pathOps 一致、保存后 revision。刷新时以最新用户层模型名单为成员真理,按 id 贴回未保存的 `reasoningEfforts`(含已清除=删键);`compat` 按键三路合并。冲突仅当本地脏字段的 originals 也变了(只 bump revision 或别的卡保存不报)。 |
23
23
  | [`paths.ts`](./paths.ts) | 嵌套读取、对象与模型表的 clone(非对象行跳过)。 |
24
24
  | [`filter.ts`](./filter.ts) | 哪些路由可编辑:手工 `llm-pi-ai` + openai-completions;排除 catalog 与官方 DeepSeek。 |
25
25
  | [`validate.ts`](./validate.ts) | 对单行 `reasoningEfforts` 调用校验。 |
26
+ | [`attribution.ts`](./attribution.ts) | 设置页页脚:`version © 年 Stardust`。首年写死 2026,结束年由打包时的 UTC 年注入,不是用户打开 DSH 的日期。 |
26
27
 
27
28
  **缺席字段**表示默认关闭。不要把「未声明」写成 `reasoningEfforts: false`——`false` 在官方语义里是从 catalog 模型上剥掉推理。
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Plugin footer attribution. Version and end-year are frozen into the client
3
+ * bundle at pack time; this module only formats the line.
4
+ */
5
+
6
+ /** First publication year (LICENSE). Not the user's wall clock. */
7
+ export const COPYRIGHT_FROM = 2026
8
+
9
+ export const COPYRIGHT_HOLDER = 'Stardust'
10
+
11
+ /**
12
+ * `0.1.2 © 2026 Stardust` or `0.1.2 © 2026–2027 Stardust`.
13
+ * Throws if version is empty or `to < from` — a bad stamp must not render.
14
+ */
15
+ export function formatAttribution(version: string, from: number, to: number): string {
16
+ if (version.trim() === '') {
17
+ throw new Error('plugin version must be a non-empty string')
18
+ }
19
+ if (!Number.isInteger(from) || !Number.isInteger(to) || to < from) {
20
+ throw new Error(`invalid copyright range: ${String(from)}\u2013${String(to)}`)
21
+ }
22
+ const years = to === from ? String(from) : `${String(from)}\u2013${String(to)}`
23
+ return `${version} \u00a9 ${years} ${COPYRIGHT_HOLDER}`
24
+ }
@@ -26,7 +26,10 @@ export function writeOff(
26
26
  const next: ReasoningEfforts = { ...efforts }
27
27
  delete next.off
28
28
  if (mode === 'empty') next.off = null
29
- else if (mode === 'value') next.off = value.trim().length > 0 ? value : 'none'
29
+ else if (mode === 'value') {
30
+ const trimmed = value.trim()
31
+ next.off = trimmed.length > 0 ? trimmed : 'none'
32
+ }
30
33
  return next
31
34
  }
32
35