dsh-date-wrapper 0.1.1-beta.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.
@@ -0,0 +1,43 @@
1
+ # 変更履歴
2
+
3
+ このプロジェクトの注目すべき変更はすべてこのファイルに記録されています。
4
+ 形式は [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) に従い、このプロジェクトは [Semantic Versioning](https://semver.org/spec/v2.0.0.html) に準拠します。
5
+
6
+ - [English README](./README.md)
7
+ - [中文 README](./README.zh.md)
8
+ - [日本語 README](./README.ja.md)
9
+ - [한국어 README](./README.ko.md)
10
+ - [Installation guide](./INSTALL.md)
11
+ - [中文安装指南](./INSTALL.zh.md)
12
+ - [日本語インストールガイド](./INSTALL.ja.md)
13
+ - [한국어 설치 안내](./INSTALL.ko.md)
14
+ - [Changelog](./CHANGELOG.md)
15
+ - [日本語 changelog](./CHANGELOG.ja.md)
16
+ - [한국어 changelog](./CHANGELOG.ko.md)
17
+
18
+ ## 0.1.0 — 2026-09-08
19
+
20
+ 初回リリース。
21
+
22
+ ### 追加
23
+
24
+ - 現在の日付を動的なランタイムコンテキスト(`systemPrompt.context`)として登録するホスト側プラグイン。`Current date: 2026-09-08 Asia/Shanghai Tuesday` としてレンダリングされ、46文字、およそ12トークン、時刻は含みません。
25
+ - 単一の `insert` 行(`id: date-wrapper`、`config.timeZone: Asia/Shanghai`)を持つ `cordis.patch.yml` バンドルパッチ。
26
+ - 起動時に検証される `timeZone` 設定: 無効または解決不能な IANA ゾーンは、黙って UTC にフォールバックせず例外を投げます。
27
+ - フェイルソフトなテキストプロバイダ: レンダリング失敗時は空文字列を返すため、プロンプト組み立てがプラグインのせいで例外を投げることはありません。
28
+ - `node --test` による 18 個のアサーション: ゾーン投影、ゾーン境界をまたぐ曜日の正しさ、正確な形式と長さ、劣化、設定検証、および偽のコンテキストに対する登録コントラクト。
29
+ - ESLint 10 のフラット設定。`npm run verify` が lint + テストをゲートします。
30
+ - 実行時依存関係ゼロ、`@deepseek-ai/*` のインポートもゼロ。
31
+
32
+ ### ドキュメント
33
+
34
+ - `README.{md,zh,ja,ko}`、`INSTALL.{md,zh,ja,ko}`、`CHANGELOG.{md,ja,ko}`(相互リンクされた言語切り替え付き)。
35
+ - 0.1.0-rc.7 → 0.1.3-alpha.2 をカバーするバージョン互換性マトリクス。
36
+ - `docs/dsh-session-and-context-mechanics.md` — DSH がセッションを JSONL に変換し、リクエストを組み立てる仕組み(中国語)。
37
+ - `HANDOVER.md` — プロジェクトの引き継ぎと設計根拠(中国語)。
38
+
39
+ ### 注記
40
+
41
+ - `@deepseek-ai/dsh-time-context` との機能重複があります。両方をマウントしないでください。
42
+ - 設計上、設定パネルはありません — プラグイン行の有効化・非アクティブ化がスイッチです。
43
+ - ペルソナが `includeRuntimeContext: false` を設定している固定プロンプトのプリセットでは非アクティブです。
@@ -0,0 +1,43 @@
1
+ # 변경 이력
2
+
3
+ 이 프로젝트의 모든 주요 변경 사항을 이 파일에 기록합니다.
4
+ 형식은 [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)를 따르며, 이 프로젝트는 [Semantic Versioning](https://semver.org/spec/v2.0.0.html)을 준수합니다.
5
+
6
+ - [English README](./README.md)
7
+ - [中文 README](./README.zh.md)
8
+ - [日本語 README](./README.ja.md)
9
+ - [한국어 README](./README.ko.md)
10
+ - [Installation guide](./INSTALL.md)
11
+ - [中文安装指南](./INSTALL.zh.md)
12
+ - [日本語インストールガイド](./INSTALL.ja.md)
13
+ - [한국어 설치 안내](./INSTALL.ko.md)
14
+ - [Changelog](./CHANGELOG.md)
15
+ - [日本語 changelog](./CHANGELOG.ja.md)
16
+ - [한국어 changelog](./CHANGELOG.ko.md)
17
+
18
+ ## 0.1.0 — 2026-09-08
19
+
20
+ 최초 릴리스.
21
+
22
+ ### 추가
23
+
24
+ - 현재 날짜를 동적 런타임 컨텍스트(`systemPrompt.context`)로 등록하는 호스트 절반 플러그인으로, `Current date: 2026-09-08 Asia/Shanghai Tuesday` — 46 characters, 대략 12 tokens, 시각 없음 — 로 렌더링됩니다.
25
+ - 단일 `insert` 행(`id: date-wrapper`, `config.timeZone: Asia/Shanghai`)을 담은 `cordis.patch.yml` 번들 패치.
26
+ - 시작 시 검증되는 `timeZone` 설정: 잘못되었거나 해석할 수 없는 IANA 존은 UTC로 조용히 폴백하는 대신 예외를 던집니다.
27
+ - fail-soft 텍스트 프로바이더: 렌더 실패 시 빈 문자열을 반환하므로 프롬프트 조립이 이 플러그인 때문에 예외를 던지는 일이 없습니다.
28
+ - `node --test`를 통한 18 assertions: 존 투영, 존 경계를 넘는 요일 정확성, 정확한 형식과 길이, 성능 저하 시 동작, 설정 검증, 가짜 컨텍스트에 대한 등록 계약.
29
+ - ESLint 10 flat config; `npm run verify`가 lint + 테스트를 게이트합니다.
30
+ - 런타임 의존성 0건, `@deepseek-ai/*` 임포트 0건.
31
+
32
+ ### 문서
33
+
34
+ - 상호 링크된 언어 전환을 갖춘 `README.{md,zh,ja,ko}`, `INSTALL.{md,zh,ja,ko}`, `CHANGELOG.{md,ja,ko}`.
35
+ - 0.1.0-rc.7 → 0.1.3-alpha.2를 포괄하는 버전 호환성 매트릭스.
36
+ - `docs/dsh-session-and-context-mechanics.md` — DSH가 세션을 JSONL로 바꾸고 요청을 조립하는 방식(중국어).
37
+ - `HANDOVER.md` — 프로젝트 인수인계와 설계 근거(중국어).
38
+
39
+ ### 참고
40
+
41
+ - `@deepseek-ai/dsh-time-context`와 기능이 중복됩니다: 둘 다 마운트하지 마십시오.
42
+ - 설계상 설정 패널이 없습니다 — 플러그인 행을 활성화하거나 비활성화하는 것이 스위치입니다.
43
+ - 페르소나가 `includeRuntimeContext: false`를 설정한 고정 프롬프트 프리셋에서는 비활성입니다.
package/CHANGELOG.md ADDED
@@ -0,0 +1,53 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented in this file.
4
+ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
5
+
6
+ - [English README](./README.md)
7
+ - [中文 README](./README.zh.md)
8
+ - [日本語 README](./README.ja.md)
9
+ - [한국어 README](./README.ko.md)
10
+ - [Installation guide](./INSTALL.md)
11
+ - [中文安装指南](./INSTALL.zh.md)
12
+ - [日本語インストールガイド](./INSTALL.ja.md)
13
+ - [한국어 설치 안내](./INSTALL.ko.md)
14
+ - [Changelog](./CHANGELOG.md)
15
+ - [日本語 changelog](./CHANGELOG.ja.md)
16
+ - [한국어 changelog](./CHANGELOG.ko.md)
17
+
18
+ ## Unreleased
19
+
20
+ ### Changed
21
+
22
+ - **DSH dual-version support (0.1.0-rc.7 … 0.1.2-rc.1).** Documented the compatibility matrix in
23
+ the README (EN/ZH) and added `engines.dsh`. No code change: the plugin's only host contract,
24
+ `systemPrompt.context({ name, order, text })`, is signature- and semantics-identical between
25
+ `dsh-v0.1.1-rc.2` and `dsh-v0.1.2-rc.1`, and the plugin registers no settings namespace, reads
26
+ no session data and makes no RPC call.
27
+
28
+ ## 0.1.0 — 2026-09-08
29
+
30
+ First release.
31
+
32
+ ### Added
33
+
34
+ - Host-half plugin that registers the current date as a dynamic runtime context (`systemPrompt.context`), rendered as `Current date: 2026-09-08 Asia/Shanghai Tuesday` — 46 characters, roughly 12 tokens, no time of day.
35
+ - `cordis.patch.yml` bundle patch with a single `insert` row (`id: date-wrapper`, `config.timeZone: Asia/Shanghai`).
36
+ - `timeZone` configuration validated at startup: an invalid or unresolvable IANA zone throws instead of silently falling back to UTC.
37
+ - Fail-soft text provider: a render failure returns an empty string, so prompt assembly never throws on the plugin's behalf.
38
+ - 18 assertions via `node --test`: zone projection, weekday correctness across zone boundaries, exact format and length, degradation, config validation, and the registration contract against a fake context.
39
+ - ESLint 10 flat config; `npm run verify` gates lint + tests.
40
+ - Zero runtime dependencies and zero `@deepseek-ai/*` imports.
41
+
42
+ ### Documentation
43
+
44
+ - `README.{md,zh,ja,ko}`, `INSTALL.{md,zh,ja,ko}`, `CHANGELOG.{md,ja,ko}` with cross-linked language switches.
45
+ - Version-compatibility matrix covering 0.1.0-rc.7 → 0.1.3-alpha.2.
46
+ - `docs/dsh-session-and-context-mechanics.md` — how DSH turns sessions into JSONL and assembles requests (Chinese).
47
+ - `HANDOVER.md` — project handover and design rationale (Chinese).
48
+
49
+ ### Notes
50
+
51
+ - Functional overlap with `@deepseek-ai/dsh-time-context`: do not mount both.
52
+ - No settings panel by design — activating or deactivating the plugin row is the switch.
53
+ - Inactive under fixed-prompt presets whose persona sets `includeRuntimeContext: false`.
package/HANDOVER.md ADDED
@@ -0,0 +1,215 @@
1
+ # HANDOVER — dsh-date-wrapper
2
+
3
+ > 面向「下一个会话 / 下一个协作者」的交接文档。目标:15 分钟看懂全貌,30 分钟能改代码。
4
+ > 结构参照 `improve-dsh-plugins/02-handover-markdown-pattern.md` 的模板。
5
+
6
+ ---
7
+
8
+ ## 0. 一句话背景
9
+
10
+ `dsh-date-wrapper` 是一个 **DSH host 插件**:把当前日期注册为一条**动态运行上下文**,由平台并入自己那条「Current runtime context」快照消息,模型看到的是 `Current date: 2026-09-08 Asia/Shanghai Tuesday`。
11
+
12
+ - 仓库:https://github.com/drscrewdriver/dsh-date-wrapper(public,默认分支 `main`)
13
+ - npm:**未发布**(当前安装方式 = 本地路径 / GitHub 路径)
14
+ - 插件索引:未投稿 awesome-dsh-plugin
15
+ - 版本线:v0.1.0(首个版本)
16
+ - 源码规模:`src/` 2 文件 168 行,`tests/` 2 文件 18 条断言
17
+ - 已知状态:契约点 `systemPrompt.context()` 目前是**裸调用**(无运行时探测);0.1.2+ 只有静态验证,没有运行时验证
18
+ - 设计上的"不":不加载 `dsh-time-context`、不产生会话消息、不改系统提示词、不做面板开关、零运行时依赖
19
+
20
+ ---
21
+
22
+ ## 1. 项目目录
23
+
24
+ ```
25
+ dsh-date-wrapper/
26
+ ├── package.json # name/type:module/main/exports["."]/dsh.bundle.patch/files;零 dependencies
27
+ ├── cordis.patch.yml # bundle patch:一行 insert(id: date-wrapper, name: dsh-date-wrapper)
28
+ ├── eslint.config.mjs # ESLint 10 扁平配置(@eslint/js recommended + 收紧项)
29
+ ├── src/
30
+ │ ├── index.js # host 半:apply() 只做校验 + 注册,49 行
31
+ │ └── format.js # 纯函数层:时区解析/日期渲染/文本 provider/配置校验,119 行
32
+ ├── tests/
33
+ │ ├── format.test.mjs # 11 条:纯函数(时区投影、星期、格式与长度、降级、配置校验)
34
+ │ └── context.test.mjs # 7 条:伪 ctx 断言注册契约
35
+ ├── docs/
36
+ │ └── dsh-session-and-context-mechanics.md # 会话/JSONL/请求组装机制(中文,18 KB)
37
+ ├── README.{md,zh,ja,ko} # 四语说明
38
+ ├── INSTALL.{md,zh,ja,ko} # 四语安装指南
39
+ ├── CHANGELOG.{md,ja,ko} # 三语版本记录
40
+ ├── HANDOVER.md # 本文件(中文)
41
+ └── LICENSE # MIT
42
+ ```
43
+
44
+ 外部相关位置:
45
+
46
+ - 计划产物:`E:\test\rewrite-agently\.agents\plans\dsh-date-wrapper\`(spec / findings / checklist / tasks)
47
+ - 本机安装位置:`C:\Users\joshua\.dsh\profiles\web\node_modules\<包名>\`
48
+ - profile 装配:`C:\Users\joshua\.dsh\profiles\web\package.json` 的 `dependencies` + `dsh.profile.bundles`
49
+ - 用户 patch 层:`C:\Users\joshua\.dsh\profiles\web\cordis.patch.yml`(顶层 YAML 数组)
50
+
51
+ ---
52
+
53
+ ## 2. DSH 契约点
54
+
55
+ | 类别 | 契约 | 值 / 位置 |
56
+ |---|---|---|
57
+ | 服务 | `systemPrompt` | `ctx.inject(['systemPrompt'], (scope) => …)` 建立子 fiber |
58
+ | API | `systemPrompt.context({ name, order, text })` | 返回**就是** Cordis effect disposer(`dsh-system-prompt:198`) |
59
+ | 条目名 | `date-wrapper:date` | 同名重复注册会抛错 |
60
+ | 排序位 | `order: 116` | 已占用:110 `sandbox:policy`、115 `approval:policy`、120 `subagent:delegation` |
61
+ | 文本 | `text: string \| ((ctx) => string)` | 我们传函数 → 每次组装取当下日期 |
62
+ | 平台消费 | `RuntimeContextProjection.project()` 按文本去重 + `surfaceOp: 'append'` | 同一天 0 条额外事件;跨天追加一条新快照 |
63
+ | 请求头 | `headerEquals` 比较 config + 全量 `system` + 全量 tool schema | 动 `system` 会失效整段前缀缓存 → 所以**不能**用 section/variable 注入 |
64
+ | preset 开关 | `includeRuntimeContext` / `suppressRuntimeContext` | 设 `false` 的 fixed-prompt preset 会丢弃 `contexts` |
65
+ | 装配 | `package.json` 的 `dsh.bundle.patch` → `cordis.patch.yml` 顶层数组 | `insert` 不带 patch 级 `id` → 落在 profile 根(宿主面) |
66
+ | **未使用** | settings / slots / DOM / CSS token / locales 四语字典 | 本插件没有 client 半,界面上没有属于它的控件 |
67
+
68
+ 契约稳定性(静态比对,`npm pack` 解包后对比 `lib/types/index.d.ts` 与 `lib/index.js`):`0.1.0-rc.7` / `0.1.1-rc.2` / `0.1.2-rc.1` / `0.1.3-alpha.2` 四个版本的 `context()` 签名与实现**逐字一致**,`PromptContext` 恒为 `{name, order, text}`(**没有** `complete` 字段)。
69
+
70
+ ---
71
+
72
+ ## 3. 代码结构速查(以 v0.1.0 行号为参考)
73
+
74
+ | 文件 / 区域 | 内容 |
75
+ |---|---|
76
+ | `src/index.js` ~1-17 | 模块注释:为什么用运行上下文而不是消息、为什么不用插件级 `inject` |
77
+ | `src/index.js` ~20-30 | `name` / `CONTEXT_NAME` / `CONTEXT_ORDER` 常量 |
78
+ | `src/index.js` ~39-49 | `apply(ctx, config)`:`validateConfig` → `resolveZone` → `ctx.inject` → `systemPrompt.context` |
79
+ | `src/format.js` ~22-31 | `WEEKDAY_NAMES`(固定英文表,索引同 `getUTCDay()`) |
80
+ | `src/format.js` ~37 | `TEXT_LABEL = 'Current date: '`(想改文案只改这一处) |
81
+ | `src/format.js` ~46-63 | `resolveZone`:建 `Intl.DateTimeFormat`,用 `resolvedOptions().timeZone` 规范化时区名;失败抛错 |
82
+ | `src/format.js` ~73-80 | `renderDate`:`formatToParts` → Y/M/D,再 `Date.UTC(y,m-1,d).getUTCDay()` 求星期 |
83
+ | `src/format.js` ~93-101 | `createDateContextText`:返回 provider 闭包,每次调用 `Date.now()`;渲染失败返回 `''` |
84
+ | `src/format.js` ~110-119 | `validateConfig`:只认 `timeZone`(去空白),其余键忽略;非法值抛错 |
85
+ | `tests/context.test.mjs` ~19-49 | `makeCtx()` 伪 ctx:只实现 `inject(deps, cb)`,记录注册的条目 |
86
+
87
+ ---
88
+
89
+ ## 4. 重要设计原则(含历史教训)
90
+
91
+ 1. **注入点必须是运行上下文,不是消息**
92
+ - 理由:快照按文本去重 + 追加,同一天 0 条额外事件;每条消息事件 339 B 且每轮都写。
93
+ - 历史教训:第一版照抄 `dsh-time-context` 在 `agent/pre-step` 追加 `user/message`,实测 10 轮多出 ≈3.4 KB(findings D11 取代 D4/D5/D6)。
94
+
95
+ 2. **不改系统提示词的 section / variable**
96
+ - 理由:`headerEquals` 比较 `system`,日期一变就改写请求头,整段前缀缓存失效。
97
+ - 这是被明确否决的方案 C。
98
+
99
+ 3. **不加载也不过滤 `dsh-time-context`**
100
+ - 理由:Cordis 的 `prepend` 用 `unshift`,子 fiber 异步注册的监听器会跑到 wrapper 外侧,verbose 文本既看不到也删不掉(findings D1)。
101
+ - 结论:自包含 wrapper,绝不"包装"那个插件。
102
+
103
+ 4. **不导出插件级 `inject`**
104
+ - 理由:插件级 `inject` 会把 fiber 卡在 PENDING → 启动审计失败;`ctx.inject` 的等待语义等价,但服务缺失时只是不注册(findings D6)。
105
+ - 测试里有一条断言专门守这个:`'inject' in pluginModule === false`。
106
+
107
+ 5. **不设 `complete`**
108
+ - 理由:设了会顶掉整份系统提示词;`PromptContext` 结构里本来也没有该字段,但断言仍在。
109
+
110
+ 6. **文本 provider fail-soft,配置校验 fail-fast**
111
+ - provider 抛错会让**每一次请求**都失败 → 渲染失败返回 `''`(平台会过滤空文本)。
112
+ - 时区写错是配置错误 → 宁可启动失败,也不静默按 UTC 给出错误日期(findings D7)。
113
+
114
+ 7. **星期必须与日期同源**
115
+ - 跨时区边界时,北京 2026-09-08 00:30 是 Tuesday,而 UTC 同一刻还是 09-07 Monday。
116
+ - 做法:两者都从同一份 `formatToParts` 结果推出。
117
+
118
+ 8. **零 DSH import、零运行时依赖**
119
+ - 对齐 `improve-dsh-plugins/DSH-PLUGIN-COMPATIBILITY-GUIDE.md` 的核心原则:不 `import` 任何 DSH 内部包,DSH 升级不会因导出符号变化而炸。
120
+
121
+ 9. **不做面板开关**(用户决策,findings D10)
122
+ - 开关 = 插件行是否激活;DSH「设置 → 插件」页已只读显示启用状态。
123
+ - 本插件不导出 schemastery `Config`,所以配置不走宿主 schema 校验,校验全在 `validateConfig()` 里。
124
+
125
+ 10. **版本节奏**
126
+ - 0.1.x:文档、兼容性修补、契约点探测。
127
+ - 0.2.0:再考虑新功能(时分秒 / 自动跟随浏览器时区都属于会破坏去重优势的改动,需重新论证)。
128
+
129
+ ---
130
+
131
+ ## 5. 开发 / 发布流程
132
+
133
+ ### 开发
134
+
135
+ ```powershell
136
+ cd E:\test\rewrite-agently\mine-dsh-plugins\dsh-date-wrapper
137
+ npm install # 只装 devDependencies
138
+ npm run tdd # 监听模式
139
+ npm run verify # lint + 18 条断言,提交前必跑
140
+ ```
141
+
142
+ link 模式安装(改源码立即生效,无需重装):
143
+
144
+ ```powershell
145
+ dsh plugin --profile web add link:E:\test\rewrite-agently\mine-dsh-plugins\dsh-date-wrapper
146
+ ```
147
+
148
+ ### 发布(GitHub;npm 未启用)
149
+
150
+ 1. `npm run verify` 全绿。
151
+ 2. 同步更新 `README.{md,zh,ja,ko}` / `INSTALL.{md,zh,ja,ko}` / `CHANGELOG.{md,ja,ko}` + `package.json` 版本号(版本号必须与 CHANGELOG 首条一致)。
152
+ 3. `git add -A` → `git commit` → `git push origin main`。
153
+ 4. `git tag -a vX.Y.Z -m …` → `git push origin vX.Y.Z`。
154
+ 5. `gh release create vX.Y.Z --title … --notes …`。
155
+ 6. 若将来发 npm:`npm publish --access public` ← ⚠️ 必须带 `--access public`,然后 `npm view` 验证(注册表传播 2-3 分钟)。
156
+
157
+ ⚠️ `package.json` 的 `files` 白名单必须收录所有新增文档,否则 tarball 里缺文件(`npm pack --dry-run` 自查)。
158
+ ⚠️ bundle patch **不热重载**:改 `cordis.patch.yml` 或换版本后必须重启 `dsh web`。
159
+
160
+ ---
161
+
162
+ ## 6. 测试速查
163
+
164
+ - 全量:`npm test`(`node --test "tests/*.test.mjs"`)。
165
+ - 单文件:`node tests/format.test.mjs`(受限沙箱下最稳 —— 多文件模式会派生子进程,可能 `spawn EPERM`)。
166
+ - TDD:`npm run tdd`(`node --test --watch`)。
167
+ - 目前 18 条:`format.test.mjs` 11 条、`context.test.mjs` 7 条。
168
+
169
+ 改动注入逻辑时的回归清单:
170
+
171
+ 1. 日期不变 → 平台不追加新快照(同一天 0 条事件)。
172
+ 2. 跨天 → 追加一条新快照,旧快照保留,最新一条靠 supersedes 声明生效。
173
+ 3. 非法 `timeZone` → `apply` 抛错且**不注册**任何条目。
174
+ 4. 渲染失败 → provider 返回 `''`,不抛错。
175
+ 5. 跨时区边界 → 星期与日期不错位(`2026-09-07T16:30:00Z` → 北京 Tuesday / UTC Monday)。
176
+ 6. fixed-prompt preset(`includeRuntimeContext: false`)→ 条目被丢弃,属预期。
177
+
178
+ 目检清单:
179
+
180
+ - 新会话发一句话 → 运行上下文快照里出现 `Current date: …`(来源含 `system-prompt`)。
181
+ - profile patch 置 `disabled: true` → 后续会话不再出现该行(热生效)。
182
+ - `timeZone: UTC` 重启 → 日期按 UTC。
183
+ - 搜索会话日志 → 没有 `Time sampled` / `Elapsed since` / `Browser time zone`。
184
+
185
+ ---
186
+
187
+ ## 7. 待办 / 路线图
188
+
189
+ - **P0 契约点运行时探测**:给 `scope.systemPrompt.context` 加 `typeof` 检查 + `ctx.logger.warn` 降级,让 API 改名表现为"静默不注入"而不是"插件加载失败"(对齐兼容指南 §二)。
190
+ - **P1 运行时跨版本验证**:在 0.1.2-rc.1 / 0.1.3-alpha.2 各跑一次真实会话(目前只有静态比对)。
191
+ - **P2 面向社区发布**:npm publish、`.github/ISSUE_TEMPLATE`、投稿 awesome-dsh-plugin。
192
+ - **已否决**:设置面板开关(用户决策);用 section/variable 注入(前缀缓存);`prepend` 过滤 `dsh-time-context`(findings D1)。
193
+ - **未做且需重新论证**:时分秒粒度;自动跟随浏览器时区(两者都会让日期行每次请求都变化,从而破坏"按文本去重"的收益)。
194
+
195
+ ---
196
+
197
+ ## 8. 社区与 issue 现状
198
+
199
+ - 仓库:public,`main` 分支,首个提交 `8fe1713`。
200
+ - issue / PR:0。
201
+ - 贡献者:drscrewdriver。
202
+ - 未投稿 awesome-dsh-plugin;无 GitHub Actions / CI。
203
+
204
+ ---
205
+
206
+ ## 9. 计划产物与决策记录
207
+
208
+ > 以下四项在**本机工作区**(`E:\test\rewrite-agently\.agents\plans\`),**不在仓库里**,随工作区而非随包分发。
209
+
210
+ - `.agents/plans/dsh-date-wrapper/spec.md` — 需求、技术方案、决策记录、约束。
211
+ - `.agents/plans/dsh-date-wrapper/findings.md` — D1–D13:架构决策(D1 自包含、D2 bundle patch、D6 不声明 inject、D7 fail-fast、D10 开关语义、D11 注入点改运行上下文、D12 注册契约、D13 输出格式)+ 打包/工具链契约 + 风险。
212
+ - `.agents/plans/dsh-date-wrapper/checklist.md` — M1–M19 必过项、S1–S6 应过项、Non-Goals、未验证项(诚实声明)。
213
+ - `.agents/plans/dsh-date-wrapper/tasks.md` — Phase 0–6 与里程日志。
214
+
215
+ > 交接提示:`findings.md` 的 D11 与 `docs/dsh-session-and-context-mechanics.md` 是理解"为什么不用消息、不改系统提示词"的关键两处;只读 README 容易以为只是省 token,实际约束是**前缀缓存**与**日志重建不变量**。
package/INSTALL.ja.md ADDED
@@ -0,0 +1,115 @@
1
+ # インストールガイド(公式 DSH CLI)
2
+
3
+ - [English README](./README.md)
4
+ - [中文 README](./README.zh.md)
5
+ - [日本語 README](./README.ja.md)
6
+ - [한국어 README](./README.ko.md)
7
+ - [Installation guide](./INSTALL.md)
8
+ - [中文安装指南](./INSTALL.zh.md)
9
+ - [日本語インストールガイド](./INSTALL.ja.md)
10
+ - [한국어 설치 안내](./INSTALL.ko.md)
11
+ - [Changelog](./CHANGELOG.md)
12
+ - [日本語 changelog](./CHANGELOG.ja.md)
13
+ - [한국어 changelog](./CHANGELOG.ko.md)
14
+
15
+ ## 0. 前提条件
16
+
17
+ ```powershell
18
+ echo $env:DSH_HOME # usually C:\Users\<you>\.dsh
19
+ dsh --version # this guide was verified on 0.1.1-rc.2
20
+ pnpm --version # `dsh plugin` is a pnpm forwarder, so pnpm must be on PATH
21
+ ```
22
+
23
+ ## 1. インストール
24
+
25
+ **GitHub からインストール**することを推奨します(pnpm がパッケージを `node_modules` にコピーし、lockfile が正確なコミットを固定します):
26
+
27
+ ```powershell
28
+ dsh plugin --profile web add github:drscrewdriver/dsh-date-wrapper
29
+ ```
30
+
31
+ またはローカルディレクトリから(開発時):
32
+
33
+ ```powershell
34
+ dsh plugin --profile web add E:\test\rewrite-agently\mine-dsh-plugins\dsh-date-wrapper
35
+ ```
36
+
37
+ またはリンクモード(ソースの編集は再起動後に反映され、再インストールは不要):
38
+
39
+ ```powershell
40
+ dsh plugin --profile web add link:E:\test\rewrite-agently\mine-dsh-plugins\dsh-date-wrapper
41
+ ```
42
+
43
+ > ⚠️ ローカルの `file:` / `link:` インストールはプロファイルをそのパスに依存させます。ディレクトリが改名・削除されると、失効した依存を削除するまでプロファイル内の**あらゆる** pnpm 操作が `ENOENT` で失敗します —— 本パッケージが `dsh-time-wrapper` から改名されたときに実際に起きたことです。
44
+ > ⚠️ 相対パスが**現在のディレクトリ**を基準に解決されるのは、`.` または `..` で始まる場合だけです。
45
+ > `mine-dsh-plugins\dsh-date-wrapper` はプロファイルディレクトリ内で解決されるため見つかりません。絶対パスが最も安全です。
46
+
47
+ インストール成功の目印:
48
+
49
+ 1. pnpm が終了コード 0 で終わる。
50
+ 2. `C:\Users\<you>\.dsh\profiles\web\package.json` の `dependencies` に `dsh-date-wrapper` が並ぶ。
51
+ 3. 同じファイルの `dsh.profile.bundles` の末尾に `dsh-date-wrapper` が加わる(パッケージが `dsh.bundle.patch` を宣言しているため、自動的にレイヤー一覧に取り込まれます)。
52
+
53
+ ## 2. 再起動
54
+
55
+ ```powershell
56
+ # stop the running dsh web process, then start it again
57
+ dsh web
58
+ ```
59
+
60
+ その後、ブラウザのページを更新してください。
61
+
62
+ > バンドルパッチは**ホットリロードされません**。監視されるのはプロファイル / ホームのパッチレイヤーだけです。プラグイン自身の
63
+ > `cordis.patch.yml` の変更やプラグインのアップグレードには、常に再起動が必要です。
64
+
65
+ ## 3. 検証
66
+
67
+ 新しいセッションを開き、任意のメッセージを送信してください。日付は**ランタイムコンテキストスナップショット**にぶら下がります(セッション内では `system-prompt` を出自とする注入コンテキスト行として表示されます)。表示は次のとおりです:
68
+
69
+ ```
70
+ Current date: 2026-09-08 Asia/Shanghai Tuesday
71
+ ```
72
+
73
+ これは `Current date: ` + `<ISO date> <IANA zone> <English weekday>` で、46文字(約12トークン)、**時・分・秒はありません**。
74
+
75
+ コマンドラインからプラグイン自体を試すこともできます:
76
+
77
+ ```powershell
78
+ cd E:\test\rewrite-agently\mine-dsh-plugins\dsh-date-wrapper
79
+ node tests/format.test.mjs
80
+ node tests/context.test.mjs
81
+ ```
82
+
83
+ ## 4. トラブルシューティング
84
+
85
+ | 症状 | 原因と対処 |
86
+ |---------|---------------|
87
+ | 起動が `date-wrapper: 非法 IANA timeZone` で失敗する | `cordis.patch.yml` の `timeZone` が誤っています。これは**意図的なフェイルファスト**です。黙って UTC の誤った日付を出力するより、起動時に失敗するほうがよいからです |
88
+ | 起動が `duplicate loader entry id: date-wrapper` で失敗する | 組み立てツリーにすでにその id の行が存在します。重複を削除してください |
89
+ | インストール後に日付が出ない | ① `dsh-date-wrapper` が `dsh.profile.bundles` にあることを確認する。② 再起動してページを更新したことを確認する。③ **現在のプリセットが固定プロンプトのものでないことを確認する**(次の行) |
90
+ | 一部のプリセットで日付が出ない | そのプリセットのペルソナが `includeRuntimeContext: false` を設定しています(公式の `minimal` とローカルの `simple-reply` の両方がそう)。このようなプリセットは、後続のリスナーがプロンプト内容を追加することを明示的に禁止しているため、このプラグインのランタイムコンテキストは破棄されます — 想定どおりの挙動です |
91
+ | 日付が 1 日ずれる | `timeZone` が実際のゾーンと一致していません。ゾーン境界をまたぐと(例: 北京時間 00:30 = 前日 16:30 UTC)1 日の差として現れます |
92
+ | `Time sampled …` も表示される | 何らかのプリセットが `@deepseek-ai/dsh-time-context` を明示的にマウントしています。このプラグインはそれを読み込まず、フィルタもしません。両者は併用すべきではありません |
93
+ | プロファイル内のあらゆる pnpm 操作が `ENOENT: no such file or directory, open '…'` で失敗する | `file:` / `link:` 依存が存在しないパスを指しています(パッケージの改名、または tarball の削除)。まず `dsh plugin --profile web remove <名前>` で失効した依存を削除し、再インストールしてください。`github:` インストールにはこの失敗モードがありません |
94
+
95
+ ## 5. オン/オフ(パネルのトグルなし — 有効化そのものがスイッチ)
96
+
97
+ 自分のプロファイルパッチレイヤー — `C:\Users\<you>\.dsh\profiles\web\cordis.patch.yml` — で無効化・有効化します:
98
+
99
+ ```yaml
100
+ - id: date-wrapper
101
+ disabled: true # disabled; set back to false to restore
102
+ ```
103
+
104
+ - **ホット、再起動不要**: このファイルは Cordis HMR が監視しており、`disabled: true` はその行の fiber を破棄し、注入は即座に停止します。
105
+ - DSH 組み込みの **Settings → Plugins** ページは `enabled / disabled` を表示します(読み取り専用)。
106
+ - ファイルはトップレベルの YAML 配列でなければなりません。形式を崩すと**起動に失敗します**(fail-loud)。
107
+ - 完全な削除は `dsh plugin remove` を経由し(次のセクション)、**再起動が必要**です。
108
+
109
+ ## 6. アンインストール
110
+
111
+ ```powershell
112
+ dsh plugin --profile web remove dsh-date-wrapper
113
+ ```
114
+
115
+ dsh web を再起動してください。
package/INSTALL.ko.md ADDED
@@ -0,0 +1,115 @@
1
+ # 설치 안내(공식 DSH CLI)
2
+
3
+ - [English README](./README.md)
4
+ - [中文 README](./README.zh.md)
5
+ - [日本語 README](./README.ja.md)
6
+ - [한국어 README](./README.ko.md)
7
+ - [Installation guide](./INSTALL.md)
8
+ - [中文安装指南](./INSTALL.zh.md)
9
+ - [日本語インストールガイド](./INSTALL.ja.md)
10
+ - [한국어 설치 안내](./INSTALL.ko.md)
11
+ - [Changelog](./CHANGELOG.md)
12
+ - [日本語 changelog](./CHANGELOG.ja.md)
13
+ - [한국어 changelog](./CHANGELOG.ko.md)
14
+
15
+ ## 0. 사전 요구 사항
16
+
17
+ ```powershell
18
+ echo $env:DSH_HOME # usually C:\Users\<you>\.dsh
19
+ dsh --version # this guide was verified on 0.1.1-rc.2
20
+ pnpm --version # `dsh plugin` is a pnpm forwarder, so pnpm must be on PATH
21
+ ```
22
+
23
+ ## 1. 설치
24
+
25
+ **GitHub에서 설치**하는 것을 권장합니다(pnpm이 패키지를 `node_modules`로 복사하고, lockfile이 정확한 커밋을 고정합니다):
26
+
27
+ ```powershell
28
+ dsh plugin --profile web add github:drscrewdriver/dsh-date-wrapper
29
+ ```
30
+
31
+ 또는 로컬 디렉터리에서(개발 시):
32
+
33
+ ```powershell
34
+ dsh plugin --profile web add E:\test\rewrite-agently\mine-dsh-plugins\dsh-date-wrapper
35
+ ```
36
+
37
+ 또는 링크 모드(소스 수정은 재시작 후 반영되며 재설치가 필요 없습니다):
38
+
39
+ ```powershell
40
+ dsh plugin --profile web add link:E:\test\rewrite-agently\mine-dsh-plugins\dsh-date-wrapper
41
+ ```
42
+
43
+ > ⚠️ 로컬 `file:` / `link:` 설치는 프로필이 그 경로에 의존하게 만듭니다. 디렉터리가 이름이 바뀌거나 삭제되면, 만료된 의존성을 제거할 때까지 프로필의 **모든** pnpm 작업이 `ENOENT`로 실패합니다 — 이 패키지가 `dsh-time-wrapper`에서 개명되었을 때 실제로 일어난 일입니다.
44
+ > ⚠️ 상대 경로는 `.` 또는 `..`로 시작할 때만 **현재 디렉터리**를 기준으로 삼습니다;
45
+ > `mine-dsh-plugins\dsh-date-wrapper`는 프로필 디렉터리 안에서 해석되므로 찾지 못합니다. 절대 경로가 가장 안전합니다.
46
+
47
+ 설치 성공의 징후:
48
+
49
+ 1. pnpm이 코드 0으로 종료됩니다;
50
+ 2. `C:\Users\<you>\.dsh\profiles\web\package.json`의 `dependencies`에 `dsh-date-wrapper`가 나열됩니다;
51
+ 3. 같은 파일의 `dsh.profile.bundles` 끝에 `dsh-date-wrapper`가 추가됩니다(패키지가 `dsh.bundle.patch`를 선언하므로 레이어 목록에 자동으로 끌어들여집니다).
52
+
53
+ ## 2. 재시작
54
+
55
+ ```powershell
56
+ # stop the running dsh web process, then start it again
57
+ dsh web
58
+ ```
59
+
60
+ 그런 다음 브라우저 페이지를 새로 고치십시오.
61
+
62
+ > 번들 패치는 **핫 리로드되지 않습니다**: 프로필 / 홈 패치 레이어만 감시됩니다. 플러그인 자체의
63
+ > `cordis.patch.yml`을 바꾸거나 플러그인을 업그레이드하려면 항상 재시작이 필요합니다.
64
+
65
+ ## 3. 검증
66
+
67
+ 새 세션을 열고 아무 메시지나 보내십시오. 날짜가 **런타임 컨텍스트 스냅샷**에 얹히며(세션에는 `system-prompt`에서 온 주입된 컨텍스트 행으로 표시됩니다), 다음과 같습니다:
68
+
69
+ ```
70
+ Current date: 2026-09-08 Asia/Shanghai Tuesday
71
+ ```
72
+
73
+ 즉 `Current date: ` + `<ISO date> <IANA zone> <English weekday>`이고, 46 characters (~12 tokens)이며, **시·분·초는 없습니다**.
74
+
75
+ 명령줄에서 플러그인 자체를 실행해 볼 수도 있습니다:
76
+
77
+ ```powershell
78
+ cd E:\test\rewrite-agently\mine-dsh-plugins\dsh-date-wrapper
79
+ node tests/format.test.mjs
80
+ node tests/context.test.mjs
81
+ ```
82
+
83
+ ## 4. 문제 해결
84
+
85
+ | 증상 | 원인과 해결 |
86
+ |---------|---------------|
87
+ | `date-wrapper: 非法 IANA timeZone`과 함께 시작 실패 | `cordis.patch.yml`의 `timeZone`이 잘못되었습니다. 이는 **의도된 fail-fast**입니다: UTC로 조용히 잘못된 날짜를 내보내기보다 시작 시 실패하는 편이 낫습니다 |
88
+ | `duplicate loader entry id: date-wrapper`와 함께 시작 실패 | 조립 트리에 이미 그 id를 가진 행이 있습니다; 중복된 것을 삭제하십시오 |
89
+ | 설치 후 날짜가 없음 | ① `dsh-date-wrapper`가 `dsh.profile.bundles`에 있는지 확인합니다; ② 재시작하고 페이지를 새로 고쳤는지 확인합니다; ③ **현재 프리셋이 고정 프롬프트 프리셋이 아닌지 확인합니다**(다음 행) |
90
+ | 일부 프리셋에서 날짜가 없음 | 그 프리셋의 페르소나가 `includeRuntimeContext: false`를 설정합니다(공식 `minimal`과 로컬 `simple-reply` 모두 그렇게 합니다). 그런 프리셋은 이후 리스너가 프롬프트 콘텐츠를 추가하는 것을 명시적으로 금지하므로 이 플러그인의 런타임 컨텍스트가 버려집니다 — 정상 동작입니다 |
91
+ | 날짜가 하루 어긋남 | `timeZone`이 실제 존과 맞지 않습니다; 존 경계를 넘을 때(예: 베이징 00:30 = UTC 전날 16:30) 하루 차이로 나타납니다 |
92
+ | `Time sampled …`도 함께 보임 | 어떤 프리셋이 `@deepseek-ai/dsh-time-context`를 명시적으로 마운트한 것입니다. 이 플러그인은 이를 로드하지도 필터링하지도 않으며, 둘은 함께 사용해서는 안 됩니다 |
93
+ | 프로필의 모든 pnpm 작업이 `ENOENT: no such file or directory, open '…'`로 실패 | `file:` / `link:` 의존성이 더 이상 존재하지 않는 경로를 가리키고 있습니다(패키지 이름 변경 또는 tarball 삭제). 먼저 `dsh plugin --profile web remove <이름>`으로 만료된 의존성을 제거한 뒤 다시 설치하십시오. `github:` 설치는 이 실패 모드가 없습니다 |
94
+
95
+ ## 5. 켜기/끄기(패널 토글 없음 — 활성화가 스위치)
96
+
97
+ 자신의 프로필 패치 레이어 — `C:\Users\<you>\.dsh\profiles\web\cordis.patch.yml` — 에서 비활성화하거나 활성화하십시오:
98
+
99
+ ```yaml
100
+ - id: date-wrapper
101
+ disabled: true # disabled; set back to false to restore
102
+ ```
103
+
104
+ - **핫, 재시작 불필요**: 이 파일은 Cordis HMR이 감시하며, `disabled: true`는 그 행의 파이버를 폐기하고 주입이 즉시 멈춥니다.
105
+ - DSH 내장 **Settings → Plugins** 페이지는 `enabled / disabled`를 표시합니다(읽기 전용).
106
+ - 파일은 최상위 YAML 배열이어야 합니다; 형식을 망가뜨리면 **시작이 실패합니다**(fail-loud).
107
+ - 완전한 제거는 `dsh plugin remove`(다음 절)를 거치며 **재시작이 필요합니다**.
108
+
109
+ ## 6. 제거
110
+
111
+ ```powershell
112
+ dsh plugin --profile web remove dsh-date-wrapper
113
+ ```
114
+
115
+ dsh web을 재시작하십시오.