@prettier-ai/dsh-client-ui-schedule 0.1.2-alpha.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/LICENSE +21 -0
- package/README.i18n.yaml +6 -0
- package/README.md +109 -0
- package/README.zh.md +109 -0
- package/lib/client.js +290 -0
- package/lib/index.js +9 -0
- package/lib/invariant.js +13 -0
- package/lib/types/client/ScheduleCatalogAction.d.ts +16 -0
- package/lib/types/client/index.d.ts +14 -0
- package/lib/types/client/locales.d.ts +29 -0
- package/lib/types/index.d.ts +7 -0
- package/lib/types/invariant.d.ts +9 -0
- package/package.json +74 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 DeepSeek
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.i18n.yaml
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
|
2
|
+
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
|
+
# after editing either side, bring the other along and re-record with:
|
|
4
|
+
# pnpm run verify-translation-pairing --write packages/client/ui-schedule/README.md
|
|
5
|
+
README.md: 2d75746876daf453b01ff2e84b6e62ed018c205c
|
|
6
|
+
README.zh.md: 32925e73aed252189764c4eafc0f5ecc58bb2a08
|
package/README.md
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "The read-only Web catalog for active Schedule reminders, for users choosing the surface and maintainers of its projection, timing, and accessibility behavior."
|
|
3
|
+
kind: "package-reference"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# @deepseek-ai/dsh-client-ui-schedule
|
|
7
|
+
|
|
8
|
+
English | [中文](README.zh.md)
|
|
9
|
+
|
|
10
|
+
## Summary
|
|
11
|
+
|
|
12
|
+
This package renders a read-only catalog of the current Session's active Schedule reminders in the Web header. It reads the complete `schedule` projection and issues no RPC or mutation. The browser derives status, local time, relative time, and ordering without adding those presentation values to durable state. The shipped Web bundle keeps the plugin disabled until the explicit Schedule overlay enables both the Host Schedule services and this client row.
|
|
13
|
+
|
|
14
|
+
## Table of Contents
|
|
15
|
+
|
|
16
|
+
- [Use this package](#use-this-package)
|
|
17
|
+
- [Understand the implementation](#understand-the-implementation)
|
|
18
|
+
- [Further Exploration](#further-exploration)
|
|
19
|
+
- [Model Experience](#model-experience)
|
|
20
|
+
- [Known Limitations and Deferred Work](#known-limitations-and-deferred-work)
|
|
21
|
+
- [Dev Note](#dev-note)
|
|
22
|
+
|
|
23
|
+
-----
|
|
24
|
+
|
|
25
|
+
<a id="use-this-package"></a>
|
|
26
|
+
## Use this package
|
|
27
|
+
|
|
28
|
+
Enable the Schedule overlay before starting the Web Session that should expose reminders:
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
dsh web --patch apps/cli/config/examples/schedule/cordis.yml
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The shipped Web graph already resolves `@deepseek-ai/dsh-client-ui-schedule` through a disabled `ui-schedule` row; the overlay enables that row together with `@deepseek-ai/dsh-schedule`. The trigger appears only while the Session is successfully open and the projection contains at least one active record. Opening it shows overdue rows first, then future rows by target time, with exact ties preserving the projection's creation order.
|
|
35
|
+
|
|
36
|
+
### Read and dismiss the catalog
|
|
37
|
+
|
|
38
|
+
Each row shows the complete wrapping prompt, a separate Scheduled or Overdue status, localized Once or the largest exact whole unit for a repeating interval, browser-local target time, and browser-clock-relative time. Intervals are never rounded, and the three metadata fields wrap across lines instead of clipping valid large values. The 336px popover scrolls vertically when needed and exposes no Schedule id, raw UTC value, details, or action controls.
|
|
39
|
+
|
|
40
|
+
Only the native trigger button enters the tab order. Enter and Space use normal button activation; while focus remains on the trigger or catalog, Escape closes the popover and restores trigger focus; an outside pointer press dismisses it. If a live update removes the final record, the component closes and unmounts without moving focus to another header action. A failed Session open hides the trigger even when a tentative cached projection exists.
|
|
41
|
+
|
|
42
|
+
-----
|
|
43
|
+
|
|
44
|
+
<a id="understand-the-implementation"></a>
|
|
45
|
+
## Understand the implementation
|
|
46
|
+
|
|
47
|
+
<details>
|
|
48
|
+
<summary>Implementation internals — click to expand</summary>
|
|
49
|
+
|
|
50
|
+
The browser plugin contributes `schedule-catalog` to `conversation.session.header.actions` at order 10, after static Agent and Subagent context and before background Jobs. It reads `openState` through the standard Session hook and the complete value through `useProjection('schedule')`; popover visibility is its only local interaction state. Browser formatting uses the viewing locale, time zone, and clock, while durable Schedule records remain unchanged.
|
|
51
|
+
|
|
52
|
+
### Source map
|
|
53
|
+
|
|
54
|
+
| File | Role |
|
|
55
|
+
|---|---|
|
|
56
|
+
| [`src/client/index.ts`](src/client/index.ts) | Browser entry: locale registration and Session-header slot contribution |
|
|
57
|
+
| [`src/client/ScheduleCatalogAction.tsx`](src/client/ScheduleCatalogAction.tsx) | Visibility, ordering, formatting, popover, and keyboard behavior |
|
|
58
|
+
| [`src/client/locales.ts`](src/client/locales.ts) | English and Chinese catalog copy |
|
|
59
|
+
| [`src/index.ts`](src/index.ts) | Empty Host apply that keeps the optional browser feature addressable by Loader |
|
|
60
|
+
| [`src/invariant.ts`](src/invariant.ts) | Invariant companion; the package owns no mutable cross-plugin state |
|
|
61
|
+
|
|
62
|
+
The [durable Web Schedule Agent Note](../../../.agents/notes/implemented/feature/2026-08-05-durable-web-schedule.md) owns the active projection and opt-in presentation boundary; this package owns the catalog's timing and accessibility behavior.
|
|
63
|
+
|
|
64
|
+
</details>
|
|
65
|
+
|
|
66
|
+
-----
|
|
67
|
+
|
|
68
|
+
<a id="further-exploration"></a>
|
|
69
|
+
## Further Exploration
|
|
70
|
+
|
|
71
|
+
Read these pages when the catalog itself is not enough. They move from the browser presentation to the durable Schedule state and shared projection transport.
|
|
72
|
+
|
|
73
|
+
- [Schedule package](../../schedule/schedule/README.md) — creates, lists, cancels, and delivers the reminders shown here.
|
|
74
|
+
- [Schedule subsystem](../../../docs/subsystems/schedule.md) — durable record, transition, and delivery semantics.
|
|
75
|
+
- [Session projections subsystem](../../../docs/subsystems/session-projection.md) — the complete-value transport this package reads.
|
|
76
|
+
- [Client package map](../README.md) — adjacent browser UI packages.
|
|
77
|
+
|
|
78
|
+
-----
|
|
79
|
+
|
|
80
|
+
<a id="model-experience"></a>
|
|
81
|
+
## Model Experience
|
|
82
|
+
|
|
83
|
+
None, as this package renders a completed client projection for a human and never changes prompts, messages, schemas, streams, or tool results.
|
|
84
|
+
|
|
85
|
+
#### KV Cache effect
|
|
86
|
+
|
|
87
|
+
None; the package never assembles or sends provider requests.
|
|
88
|
+
|
|
89
|
+
## Known Limitations and Deferred Work
|
|
90
|
+
|
|
91
|
+
<a id="known-limitations-and-deferred-work"></a>
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
These limits define the current Schedule catalog. They are current package constraints, not a reminder-service comparison or a task backlog.
|
|
95
|
+
|
|
96
|
+
- **Active records only** — terminal delete and dispatch transitions remove rows; the ordinary transcript remains the only reminder-delivery history.
|
|
97
|
+
- **Browser-derived time** — local and relative labels use the viewing browser's current locale, time zone, and clock. They are presentation values, not durable Schedule facts.
|
|
98
|
+
- **Read-only surface** — creating and deleting reminders remain with the Schedule tools; the catalog has no mutation, retry, acknowledgement, toast, or delivery-receipt semantics.
|
|
99
|
+
- **Open Session required** — a failed open hides even a tentative cached value because strict Session replay remains authoritative.
|
|
100
|
+
|
|
101
|
+
<a id="dev-note"></a>
|
|
102
|
+
### Dev Note
|
|
103
|
+
|
|
104
|
+
<details>
|
|
105
|
+
<summary>Working context for maintainers — click to expand</summary>
|
|
106
|
+
|
|
107
|
+
None.
|
|
108
|
+
|
|
109
|
+
</details>
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "面向用户与维护者的活动 Schedule 提醒只读 Web 目录说明,用于选择该界面并理解其 projection、时间与无障碍行为。"
|
|
3
|
+
kind: "package-reference"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# @deepseek-ai/dsh-client-ui-schedule
|
|
7
|
+
|
|
8
|
+
[English](README.md) | 中文
|
|
9
|
+
|
|
10
|
+
## 概述
|
|
11
|
+
|
|
12
|
+
本包在 Web 会话头部渲染当前 Session 活动 Schedule 提醒的只读目录。它读取完整的 `schedule` projection,不发 RPC,也不执行 mutation。浏览器派生状态、本地时间、相对时间与排序,不把这些呈现值加入持久状态。随附 Web bundle 默认禁用该插件,只有显式 Schedule overlay 才会同时启用 Host Schedule 服务与此客户端 row。
|
|
13
|
+
|
|
14
|
+
## 目录
|
|
15
|
+
|
|
16
|
+
- [使用本包](#use-this-package)
|
|
17
|
+
- [理解实现](#understand-the-implementation)
|
|
18
|
+
- [进一步探索](#further-exploration)
|
|
19
|
+
- [模型体验](#model-experience)
|
|
20
|
+
- [已知限制与延期工作](#known-limitations-and-deferred-work)
|
|
21
|
+
- [开发备注](#dev-note)
|
|
22
|
+
|
|
23
|
+
-----
|
|
24
|
+
|
|
25
|
+
<a id="use-this-package"></a>
|
|
26
|
+
## 使用本包
|
|
27
|
+
|
|
28
|
+
在需要显示提醒的 Web Session 启动前启用 Schedule overlay:
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
dsh web --patch apps/cli/config/examples/schedule/cordis.yml
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
随附 Web graph 已通过 disabled 的 `ui-schedule` row 解析 `@deepseek-ai/dsh-client-ui-schedule`;overlay 会把该 row 与 `@deepseek-ai/dsh-schedule` 一起启用。只有 Session 已成功打开且 projection 至少包含一条活动记录时,触发器才会出现。打开目录后,逾期行在前,未来行再按目标时间排序;完全并列时保留 projection 的创建顺序。
|
|
35
|
+
|
|
36
|
+
### 阅读和关闭目录
|
|
37
|
+
|
|
38
|
+
每一行显示可完整换行的 prompt、独立的「等待中」或「已逾期」状态、本地化的「单次」或重复间隔可整除的最大完整单位、浏览器本地目标时间,以及按浏览器时钟派生的相对时间。间隔绝不舍入,三项元数据会按行换行,不会裁剪合法的大数值。336px 宽的弹层在需要时纵向滚动,不显示 Schedule id、原始 UTC 值、详情或操作控件。
|
|
39
|
+
|
|
40
|
+
只有原生触发按钮进入 Tab 顺序。Enter 与 Space 使用按钮的正常激活行为;焦点仍在触发器或目录内时,Escape 会关闭弹层并把焦点交还触发器;在外部按下指针也会关闭。若 live 更新移除最后一条记录,组件会关闭并卸载,但不会把焦点移到另一个会话头部动作。Session 打开失败时,即使存在暂定的缓存 projection,也会隐藏触发器。
|
|
41
|
+
|
|
42
|
+
-----
|
|
43
|
+
|
|
44
|
+
<a id="understand-the-implementation"></a>
|
|
45
|
+
## 理解实现
|
|
46
|
+
|
|
47
|
+
<details>
|
|
48
|
+
<summary>实现细节——点击展开</summary>
|
|
49
|
+
|
|
50
|
+
浏览器插件以顺序 10 向 `conversation.session.header.actions` 贡献 `schedule-catalog`,位于静态 Agent 与 Subagent 上下文之后、后台 Jobs 之前。它通过标准 Session hook 读取 `openState`,通过 `useProjection('schedule')` 读取完整值;弹层开合是它唯一的本地交互状态。浏览器格式化使用查看方的 locale、时区与时钟,持久 Schedule 记录保持不变。
|
|
51
|
+
|
|
52
|
+
### 源码地图
|
|
53
|
+
|
|
54
|
+
| 文件 | 职责 |
|
|
55
|
+
|---|---|
|
|
56
|
+
| [`src/client/index.ts`](src/client/index.ts) | 浏览器入口:注册 locale 并贡献 Session 头部 slot |
|
|
57
|
+
| [`src/client/ScheduleCatalogAction.tsx`](src/client/ScheduleCatalogAction.tsx) | 可见性、排序、格式化、弹层与键盘行为 |
|
|
58
|
+
| [`src/client/locales.ts`](src/client/locales.ts) | 中英文目录文案 |
|
|
59
|
+
| [`src/index.ts`](src/index.ts) | 空的 Host apply,使 Loader 可以寻址该可选浏览器功能 |
|
|
60
|
+
| [`src/invariant.ts`](src/invariant.ts) | 不变式伴生插件;本包不拥有可变跨插件状态 |
|
|
61
|
+
|
|
62
|
+
[持久 Web Schedule Agent Note](../../../.agents/notes/implemented/feature/2026-08-05-durable-web-schedule.zh.md)拥有活动 projection 与 opt-in 呈现边界;本包拥有目录的时间与无障碍行为。
|
|
63
|
+
|
|
64
|
+
</details>
|
|
65
|
+
|
|
66
|
+
-----
|
|
67
|
+
|
|
68
|
+
<a id="further-exploration"></a>
|
|
69
|
+
## 进一步探索
|
|
70
|
+
|
|
71
|
+
当目录本身不够用时阅读以下页面。它们从浏览器呈现逐步进入持久 Schedule 状态与共享 projection 传输。
|
|
72
|
+
|
|
73
|
+
- [Schedule 包](../../schedule/schedule/README.zh.md)——创建、列出、取消并交付这里显示的提醒。
|
|
74
|
+
- [Schedule 子系统](../../../docs/subsystems/schedule.zh.md)——持久记录、转换与交付语义。
|
|
75
|
+
- [会话投影子系统](../../../docs/subsystems/session-projection.zh.md)——本包读取的完整值传输。
|
|
76
|
+
- [客户端包映射](../README.zh.md)——相邻的浏览器 UI 包。
|
|
77
|
+
|
|
78
|
+
-----
|
|
79
|
+
|
|
80
|
+
<a id="model-experience"></a>
|
|
81
|
+
## 模型体验
|
|
82
|
+
|
|
83
|
+
无,因为本包只为人类渲染已经完成的客户端 projection,从不改变 prompt、消息、schema、流或工具结果。
|
|
84
|
+
|
|
85
|
+
#### KV Cache 影响
|
|
86
|
+
|
|
87
|
+
无;本包从不组装或发送 provider 请求。
|
|
88
|
+
|
|
89
|
+
## 已知限制与延期工作
|
|
90
|
+
|
|
91
|
+
<a id="known-limitations-and-deferred-work"></a>
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
这些限制界定当前 Schedule 目录。它们是当前包约束,不是提醒服务对比或任务积压。
|
|
95
|
+
|
|
96
|
+
- **仅含活动记录**——终结性的 delete 与 dispatch 转换会移除对应行;普通 transcript 仍是唯一的提醒交付历史。
|
|
97
|
+
- **浏览器派生时间**——本地时间与相对时间标签使用查看方浏览器当前的 locale、时区与时钟。它们是呈现值,不是持久 Schedule 事实。
|
|
98
|
+
- **只读界面**——创建与删除提醒仍由 Schedule 工具负责;目录没有 mutation、Retry、acknowledgement、Toast 或交付回执语义。
|
|
99
|
+
- **要求 Session 打开成功**——打开失败时,即使存在暂定缓存值也会隐藏,因为严格 Session 回放仍是权威。
|
|
100
|
+
|
|
101
|
+
<a id="dev-note"></a>
|
|
102
|
+
### 开发备注
|
|
103
|
+
|
|
104
|
+
<details>
|
|
105
|
+
<summary>维护者的工作上下文——点击展开</summary>
|
|
106
|
+
|
|
107
|
+
无。
|
|
108
|
+
|
|
109
|
+
</details>
|
package/lib/client.js
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
window.__ModuleLoader__.load({
|
|
2
|
+
id: "@prettier-ai/dsh-client-ui-schedule",
|
|
3
|
+
factory: (require) => {
|
|
4
|
+
var module = { exports: {} };
|
|
5
|
+
var exports = module.exports;
|
|
6
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
8
|
+
let react = require("react");
|
|
9
|
+
let _prettier_ai_dsh_client_ui_primitives = require("@prettier-ai/dsh-client-ui-primitives");
|
|
10
|
+
//#region \0dsh-css:/home/runner/work/dsh-publisher/dsh-publisher/upstream/packages/client/ui-schedule/src/client/ScheduleCatalogAction.module.css.mjs
|
|
11
|
+
const css = ".sRbB7a_root{position:relative}.sRbB7a_trigger{min-height:28px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:6px;align-items:center;gap:4px;padding:3px 2px;font-size:12px;line-height:18px;display:inline-flex}.sRbB7a_trigger:hover,.sRbB7a_trigger:focus-visible{color:var(--dsw-alias-label-secondary)}.sRbB7a_trigger svg{flex:none}.sRbB7a_trigger>svg:last-child{transition:transform .12s}.sRbB7a_triggerOpen{transform:rotate(180deg)}.sRbB7a_count{margin-left:2px}.sRbB7a_menu{z-index:100;box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-specific-menu);--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);width:336px;max-width:min(336px,100vw - 32px);max-height:min(420px,100vh - 140px);box-shadow:var(--dsw-shadow-lv3);border-radius:12px;flex-direction:column;gap:2px;margin:0;padding:4px;list-style:none;display:flex;position:absolute;top:calc(100% + 5px);right:0;overflow:auto}.sRbB7a_row{box-sizing:border-box;width:100%;min-height:54px;color:var(--dsw-alias-label-primary);border-radius:8px;flex-direction:column;flex-shrink:0;gap:3px;padding:8px 10px;display:flex}.sRbB7a_rowOverdue{background:var(--dsw-alias-state-warn-tertiary)}.sRbB7a_status{color:var(--dsw-alias-label-tertiary);align-items:center;gap:5px;font-size:11px;line-height:16px;display:inline-flex}.sRbB7a_statusDot{background:var(--dsw-alias-state-business-primary);border-radius:50%;flex:none;width:8px;height:8px}.sRbB7a_rowOverdue .sRbB7a_status{color:var(--dsw-alias-state-warn-label)}.sRbB7a_rowOverdue .sRbB7a_statusDot{background:var(--dsw-alias-state-warn-primary)}.sRbB7a_prompt{overflow-wrap:anywhere;white-space:normal;font-size:13px;line-height:18px}.sRbB7a_metadata{min-width:0;color:var(--dsw-alias-label-tertiary);flex-wrap:wrap;align-items:center;gap:5px;font-size:11px;line-height:16px;display:flex}.sRbB7a_relativeOverdue{color:var(--dsw-alias-state-warn-label)}";
|
|
12
|
+
const tagId = "@prettier-ai/dsh-client-ui-schedule/ScheduleCatalogAction.module.css";
|
|
13
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
14
|
+
const tag = document.createElement("style");
|
|
15
|
+
tag.dataset.plugin = "@prettier-ai/dsh-client-ui-schedule";
|
|
16
|
+
tag.dataset.pluginCss = tagId;
|
|
17
|
+
tag.textContent = css;
|
|
18
|
+
document.head.appendChild(tag);
|
|
19
|
+
}
|
|
20
|
+
var ScheduleCatalogAction_module_css_default = {
|
|
21
|
+
"count": "sRbB7a_count",
|
|
22
|
+
"menu": "sRbB7a_menu",
|
|
23
|
+
"metadata": "sRbB7a_metadata",
|
|
24
|
+
"prompt": "sRbB7a_prompt",
|
|
25
|
+
"relativeOverdue": "sRbB7a_relativeOverdue",
|
|
26
|
+
"root": "sRbB7a_root",
|
|
27
|
+
"row": "sRbB7a_row",
|
|
28
|
+
"rowOverdue": "sRbB7a_rowOverdue",
|
|
29
|
+
"status": "sRbB7a_status",
|
|
30
|
+
"statusDot": "sRbB7a_statusDot",
|
|
31
|
+
"trigger": "sRbB7a_trigger",
|
|
32
|
+
"triggerOpen": "sRbB7a_triggerOpen"
|
|
33
|
+
};
|
|
34
|
+
//#endregion
|
|
35
|
+
//#region lib/types/client/ScheduleCatalogAction.js
|
|
36
|
+
const EMPTY_RECORDS = [];
|
|
37
|
+
const SECOND_MS = 1e3;
|
|
38
|
+
const SECOND_UNIT = {
|
|
39
|
+
unit: "second",
|
|
40
|
+
seconds: 1
|
|
41
|
+
};
|
|
42
|
+
const UNIT_SECONDS = [
|
|
43
|
+
{
|
|
44
|
+
unit: "day",
|
|
45
|
+
seconds: 86400
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
unit: "hour",
|
|
49
|
+
seconds: 3600
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
unit: "minute",
|
|
53
|
+
seconds: 60
|
|
54
|
+
},
|
|
55
|
+
SECOND_UNIT
|
|
56
|
+
];
|
|
57
|
+
/** Localized unit word for one integral magnitude. */
|
|
58
|
+
function unitLabel(unit, value, t) {
|
|
59
|
+
const pair = {
|
|
60
|
+
day: ["unit.day.one", "unit.day.other"],
|
|
61
|
+
hour: ["unit.hour.one", "unit.hour.other"],
|
|
62
|
+
minute: ["unit.minute.one", "unit.minute.other"],
|
|
63
|
+
second: ["unit.second.one", "unit.second.other"]
|
|
64
|
+
}[unit];
|
|
65
|
+
return t(value === 1 ? pair[0] : pair[1], { count: value });
|
|
66
|
+
}
|
|
67
|
+
/** Pick the largest exact whole unit without rounding the durable interval. */
|
|
68
|
+
function formatScheduleFrequency(record, t) {
|
|
69
|
+
if (record.kind !== "every") return t("frequency.once");
|
|
70
|
+
let selected = SECOND_UNIT;
|
|
71
|
+
for (const candidate of UNIT_SECONDS) {
|
|
72
|
+
if (record.everySeconds % candidate.seconds !== 0) continue;
|
|
73
|
+
selected = candidate;
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
const value = record.everySeconds / selected.seconds;
|
|
77
|
+
return t("frequency.every", {
|
|
78
|
+
value,
|
|
79
|
+
unit: unitLabel(selected.unit, value, t)
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/** Format the durable UTC target in the browser's current locale and time zone. */
|
|
83
|
+
function formatScheduleLocalTime(scheduledAt, locale) {
|
|
84
|
+
return new Intl.DateTimeFormat(locale, {
|
|
85
|
+
dateStyle: "medium",
|
|
86
|
+
timeStyle: "short"
|
|
87
|
+
}).format(Date.parse(scheduledAt));
|
|
88
|
+
}
|
|
89
|
+
/** Human relative target using the largest natural clock unit. */
|
|
90
|
+
function formatScheduleRelative(scheduledAt, now, t) {
|
|
91
|
+
const difference = Date.parse(scheduledAt) - now;
|
|
92
|
+
if (difference === 0) return t("relative.now");
|
|
93
|
+
const absoluteSeconds = Math.abs(difference) / SECOND_MS;
|
|
94
|
+
const selected = UNIT_SECONDS.find((candidate) => absoluteSeconds >= candidate.seconds) ?? SECOND_UNIT;
|
|
95
|
+
const value = Math.max(1, difference > 0 ? Math.ceil(absoluteSeconds / selected.seconds) : Math.floor(absoluteSeconds / selected.seconds));
|
|
96
|
+
const unit = unitLabel(selected.unit, value, t);
|
|
97
|
+
return t(difference > 0 ? "relative.future" : "relative.overdue", {
|
|
98
|
+
value,
|
|
99
|
+
unit
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
/** Overdue records first, then ascending target time; exact ties stay stable. */
|
|
103
|
+
function orderScheduleRecords(records, now) {
|
|
104
|
+
return records.map((record, index) => ({
|
|
105
|
+
record,
|
|
106
|
+
index
|
|
107
|
+
})).sort((left, right) => {
|
|
108
|
+
const leftTime = Date.parse(left.record.scheduledAt);
|
|
109
|
+
const rightTime = Date.parse(right.record.scheduledAt);
|
|
110
|
+
const leftOverdue = leftTime <= now;
|
|
111
|
+
const rightOverdue = rightTime <= now;
|
|
112
|
+
if (leftOverdue !== rightOverdue) return Number(rightOverdue) - Number(leftOverdue);
|
|
113
|
+
return leftTime - rightTime || left.index - right.index;
|
|
114
|
+
}).map(({ record }) => record);
|
|
115
|
+
}
|
|
116
|
+
/** Read-only current-Session active reminder catalog. */
|
|
117
|
+
function ScheduleCatalogAction({ useSession, useProjection, t }) {
|
|
118
|
+
const openState = useSession((snapshot) => snapshot.openState);
|
|
119
|
+
const records = useProjection("schedule") ?? EMPTY_RECORDS;
|
|
120
|
+
const visible = openState === "open" && records.length > 0;
|
|
121
|
+
const [open, setOpen] = (0, react.useState)(false);
|
|
122
|
+
const [now, setNow] = (0, react.useState)(() => Date.now());
|
|
123
|
+
const rootRef = (0, react.useRef)(null);
|
|
124
|
+
const triggerRef = (0, react.useRef)(null);
|
|
125
|
+
(0, _prettier_ai_dsh_client_ui_primitives.useDismissOnOutsidePointer)(rootRef, open, setOpen);
|
|
126
|
+
(0, react.useEffect)(() => {
|
|
127
|
+
if (!open) return;
|
|
128
|
+
setNow(Date.now());
|
|
129
|
+
const timer = setInterval(() => {
|
|
130
|
+
setNow(Date.now());
|
|
131
|
+
}, SECOND_MS);
|
|
132
|
+
return () => {
|
|
133
|
+
clearInterval(timer);
|
|
134
|
+
};
|
|
135
|
+
}, [open]);
|
|
136
|
+
(0, react.useEffect)(() => {
|
|
137
|
+
if (visible || !open) return;
|
|
138
|
+
setOpen(false);
|
|
139
|
+
}, [visible, open]);
|
|
140
|
+
const rows = (0, react.useMemo)(() => orderScheduleRecords(records, now), [records, now]);
|
|
141
|
+
if (!visible) return null;
|
|
142
|
+
const countLabel = t(records.length === 1 ? "trigger.one" : "trigger.other", { count: records.length });
|
|
143
|
+
const toggleCatalog = () => {
|
|
144
|
+
setNow(Date.now());
|
|
145
|
+
setOpen((current) => !current);
|
|
146
|
+
};
|
|
147
|
+
const onKeyDown = (event) => {
|
|
148
|
+
if (event.key !== "Escape" || !open) return;
|
|
149
|
+
event.preventDefault();
|
|
150
|
+
setOpen(false);
|
|
151
|
+
triggerRef.current?.focus();
|
|
152
|
+
};
|
|
153
|
+
const trigger = (0, react_jsx_runtime.jsxs)("button", {
|
|
154
|
+
ref: triggerRef,
|
|
155
|
+
type: "button",
|
|
156
|
+
className: ScheduleCatalogAction_module_css_default.trigger,
|
|
157
|
+
"aria-expanded": open,
|
|
158
|
+
"aria-label": countLabel,
|
|
159
|
+
onClick: toggleCatalog,
|
|
160
|
+
children: [
|
|
161
|
+
(0, react_jsx_runtime.jsx)(_prettier_ai_dsh_client_ui_primitives.IconAlarmClockOutline16, { size: 14 }),
|
|
162
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
163
|
+
className: ScheduleCatalogAction_module_css_default.count,
|
|
164
|
+
children: countLabel
|
|
165
|
+
}),
|
|
166
|
+
(0, react_jsx_runtime.jsx)(_prettier_ai_dsh_client_ui_primitives.IconChevronDownOutline14, { className: open ? ScheduleCatalogAction_module_css_default.triggerOpen : void 0 })
|
|
167
|
+
]
|
|
168
|
+
});
|
|
169
|
+
const catalog = open ? (0, react_jsx_runtime.jsx)("ul", {
|
|
170
|
+
className: ScheduleCatalogAction_module_css_default.menu,
|
|
171
|
+
"aria-label": t("list.aria"),
|
|
172
|
+
children: rows.map((record) => {
|
|
173
|
+
const overdue = Date.parse(record.scheduledAt) <= now;
|
|
174
|
+
return (0, react_jsx_runtime.jsxs)("li", {
|
|
175
|
+
className: overdue ? `${ScheduleCatalogAction_module_css_default.row} ${ScheduleCatalogAction_module_css_default.rowOverdue}` : ScheduleCatalogAction_module_css_default.row,
|
|
176
|
+
children: [
|
|
177
|
+
(0, react_jsx_runtime.jsxs)("span", {
|
|
178
|
+
className: ScheduleCatalogAction_module_css_default.status,
|
|
179
|
+
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
180
|
+
className: ScheduleCatalogAction_module_css_default.statusDot,
|
|
181
|
+
"aria-hidden": "true"
|
|
182
|
+
}), (0, react_jsx_runtime.jsx)("span", { children: t(overdue ? "status.overdue" : "status.scheduled") })]
|
|
183
|
+
}),
|
|
184
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
185
|
+
className: ScheduleCatalogAction_module_css_default.prompt,
|
|
186
|
+
children: record.prompt
|
|
187
|
+
}),
|
|
188
|
+
(0, react_jsx_runtime.jsxs)("span", {
|
|
189
|
+
className: ScheduleCatalogAction_module_css_default.metadata,
|
|
190
|
+
children: [
|
|
191
|
+
(0, react_jsx_runtime.jsx)("span", { children: formatScheduleFrequency(record, t) }),
|
|
192
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
193
|
+
"aria-hidden": "true",
|
|
194
|
+
children: "·"
|
|
195
|
+
}),
|
|
196
|
+
(0, react_jsx_runtime.jsx)("span", { children: formatScheduleLocalTime(record.scheduledAt, document.documentElement.lang) }),
|
|
197
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
198
|
+
"aria-hidden": "true",
|
|
199
|
+
children: "·"
|
|
200
|
+
}),
|
|
201
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
202
|
+
className: overdue ? ScheduleCatalogAction_module_css_default.relativeOverdue : void 0,
|
|
203
|
+
children: formatScheduleRelative(record.scheduledAt, now, t)
|
|
204
|
+
})
|
|
205
|
+
]
|
|
206
|
+
})
|
|
207
|
+
]
|
|
208
|
+
}, record.id);
|
|
209
|
+
})
|
|
210
|
+
}) : null;
|
|
211
|
+
return (0, react_jsx_runtime.jsxs)("div", {
|
|
212
|
+
ref: rootRef,
|
|
213
|
+
className: ScheduleCatalogAction_module_css_default.root,
|
|
214
|
+
onKeyDown,
|
|
215
|
+
children: [trigger, catalog]
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
//#endregion
|
|
219
|
+
//#region lib/types/client/locales.js
|
|
220
|
+
/** `schedule.catalog` namespace dictionaries. */
|
|
221
|
+
/** Dictionary namespace owned by this plugin. */
|
|
222
|
+
const NS = "schedule.catalog";
|
|
223
|
+
/** Simplified Chinese dictionary (the key-set source of truth). */
|
|
224
|
+
const zh = {
|
|
225
|
+
"trigger.one": "{count} 个提醒",
|
|
226
|
+
"trigger.other": "{count} 个提醒",
|
|
227
|
+
"list.aria": "活动提醒",
|
|
228
|
+
"status.scheduled": "等待中",
|
|
229
|
+
"status.overdue": "已逾期",
|
|
230
|
+
"frequency.once": "单次",
|
|
231
|
+
"frequency.every": "{value}{unit}一次",
|
|
232
|
+
"unit.day.one": "天",
|
|
233
|
+
"unit.day.other": "天",
|
|
234
|
+
"unit.hour.one": "小时",
|
|
235
|
+
"unit.hour.other": "小时",
|
|
236
|
+
"unit.minute.one": "分钟",
|
|
237
|
+
"unit.minute.other": "分钟",
|
|
238
|
+
"unit.second.one": "秒",
|
|
239
|
+
"unit.second.other": "秒",
|
|
240
|
+
"relative.now": "现在到期",
|
|
241
|
+
"relative.future": "{value}{unit}后",
|
|
242
|
+
"relative.overdue": "已逾期 {value}{unit}"
|
|
243
|
+
};
|
|
244
|
+
/** English dictionary, key-identical to the Chinese source of truth. */
|
|
245
|
+
const en = {
|
|
246
|
+
"trigger.one": "{count} reminder",
|
|
247
|
+
"trigger.other": "{count} reminders",
|
|
248
|
+
"list.aria": "Active reminders",
|
|
249
|
+
"status.scheduled": "Scheduled",
|
|
250
|
+
"status.overdue": "Overdue",
|
|
251
|
+
"frequency.once": "Once",
|
|
252
|
+
"frequency.every": "Every {value} {unit}",
|
|
253
|
+
"unit.day.one": "day",
|
|
254
|
+
"unit.day.other": "days",
|
|
255
|
+
"unit.hour.one": "hour",
|
|
256
|
+
"unit.hour.other": "hours",
|
|
257
|
+
"unit.minute.one": "minute",
|
|
258
|
+
"unit.minute.other": "minutes",
|
|
259
|
+
"unit.second.one": "second",
|
|
260
|
+
"unit.second.other": "seconds",
|
|
261
|
+
"relative.now": "Due now",
|
|
262
|
+
"relative.future": "in {value} {unit}",
|
|
263
|
+
"relative.overdue": "{value} {unit} overdue"
|
|
264
|
+
};
|
|
265
|
+
//#endregion
|
|
266
|
+
//#region lib/types/client/index.js
|
|
267
|
+
/** Browser half of the read-only Schedule catalog. */
|
|
268
|
+
/** Required services for locale registration and header-slot contribution. */
|
|
269
|
+
const inject = ["slots", "locale"];
|
|
270
|
+
/** Register the dictionaries and Session-header catalog action. */
|
|
271
|
+
function apply(ctx) {
|
|
272
|
+
ctx.effect(() => ctx.locale.register(NS, {
|
|
273
|
+
zh,
|
|
274
|
+
en
|
|
275
|
+
}), "ui-schedule: dictionaries");
|
|
276
|
+
ctx.slots.inject("conversation.session.header.actions", () => ctx.slots.register({
|
|
277
|
+
name: "conversation.session.header.actions",
|
|
278
|
+
id: "schedule-catalog",
|
|
279
|
+
order: 10,
|
|
280
|
+
locale: NS
|
|
281
|
+
}, ScheduleCatalogAction));
|
|
282
|
+
}
|
|
283
|
+
//#endregion
|
|
284
|
+
exports.apply = apply;
|
|
285
|
+
exports.inject = inject;
|
|
286
|
+
return module.exports;
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
//# sourceMappingURL=client.js.map
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//#region lib/types/index.js
|
|
2
|
+
/**
|
|
3
|
+
* Read-only Schedule catalog plugin, node half. The empty apply keeps the
|
|
4
|
+
* optional browser feature addressable from the host-owned Loader overlay.
|
|
5
|
+
*/
|
|
6
|
+
/** Host plugin body — Schedule catalog behavior exists only in the browser entry. */
|
|
7
|
+
function apply() {}
|
|
8
|
+
//#endregion
|
|
9
|
+
export { apply };
|
package/lib/invariant.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region lib/types/invariant.js
|
|
2
|
+
/** Package-owned invariant companion for the read-only Schedule catalog. */
|
|
3
|
+
const PACKAGE_NAME = "@prettier-ai/dsh-client-ui-schedule";
|
|
4
|
+
/** Cordis companion plugin name. */
|
|
5
|
+
const name = "client-ui-schedule-invariant";
|
|
6
|
+
/** Service required before the companion can reserve package ownership. */
|
|
7
|
+
const inject = ["invariants"];
|
|
8
|
+
/** No runtime invariant: the package owns no mutable cross-plugin state. */
|
|
9
|
+
const install = () => {};
|
|
10
|
+
/** Register this package's invariant companion. */
|
|
11
|
+
const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
|
|
12
|
+
//#endregion
|
|
13
|
+
export { apply, inject, name };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ScheduleRecord } from '@prettier-ai/dsh-schedule/client';
|
|
2
|
+
import type { PropsLocale, PropsRuntime, TranslateNS } from '@prettier-ai/dsh-client-ui-slots';
|
|
3
|
+
import { NS } from './locales.ts';
|
|
4
|
+
/** Full props for the Session-header Schedule catalog action. */
|
|
5
|
+
export type ScheduleCatalogActionProps = PropsRuntime<'conversation.session.header.actions'> & PropsLocale<typeof NS>;
|
|
6
|
+
/** Pick the largest exact whole unit without rounding the durable interval. */
|
|
7
|
+
export declare function formatScheduleFrequency(record: ScheduleRecord, t: TranslateNS<typeof NS>): string;
|
|
8
|
+
/** Format the durable UTC target in the browser's current locale and time zone. */
|
|
9
|
+
export declare function formatScheduleLocalTime(scheduledAt: string, locale?: string): string;
|
|
10
|
+
/** Human relative target using the largest natural clock unit. */
|
|
11
|
+
export declare function formatScheduleRelative(scheduledAt: string, now: number, t: TranslateNS<typeof NS>): string;
|
|
12
|
+
/** Overdue records first, then ascending target time; exact ties stay stable. */
|
|
13
|
+
export declare function orderScheduleRecords(records: readonly ScheduleRecord[], now: number): ScheduleRecord[];
|
|
14
|
+
/** Read-only current-Session active reminder catalog. */
|
|
15
|
+
export declare function ScheduleCatalogAction({ useSession, useProjection, t }: ScheduleCatalogActionProps): import("react").JSX.Element | null;
|
|
16
|
+
//# sourceMappingURL=ScheduleCatalogAction.d.ts.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Browser half of the read-only Schedule catalog. */
|
|
2
|
+
import type { Context as ClientContext } from '@prettier-ai/cordis';
|
|
3
|
+
import { type ScheduleCatalogKey } from './locales.ts';
|
|
4
|
+
declare module '@prettier-ai/dsh-client-ui-slots' {
|
|
5
|
+
interface LocaleNamespaceMap {
|
|
6
|
+
/** Read-only active Schedule catalog copy. */
|
|
7
|
+
'schedule.catalog': ScheduleCatalogKey;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
/** Required services for locale registration and header-slot contribution. */
|
|
11
|
+
export declare const inject: string[];
|
|
12
|
+
/** Register the dictionaries and Session-header catalog action. */
|
|
13
|
+
export declare function apply(ctx: ClientContext): void;
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** `schedule.catalog` namespace dictionaries. */
|
|
2
|
+
/** Dictionary namespace owned by this plugin. */
|
|
3
|
+
export declare const NS = "schedule.catalog";
|
|
4
|
+
/** Simplified Chinese dictionary (the key-set source of truth). */
|
|
5
|
+
export declare const zh: {
|
|
6
|
+
readonly 'trigger.one': "{count} 个提醒";
|
|
7
|
+
readonly 'trigger.other': "{count} 个提醒";
|
|
8
|
+
readonly 'list.aria': "活动提醒";
|
|
9
|
+
readonly 'status.scheduled': "等待中";
|
|
10
|
+
readonly 'status.overdue': "已逾期";
|
|
11
|
+
readonly 'frequency.once': "单次";
|
|
12
|
+
readonly 'frequency.every': "{value}{unit}一次";
|
|
13
|
+
readonly 'unit.day.one': "天";
|
|
14
|
+
readonly 'unit.day.other': "天";
|
|
15
|
+
readonly 'unit.hour.one': "小时";
|
|
16
|
+
readonly 'unit.hour.other': "小时";
|
|
17
|
+
readonly 'unit.minute.one': "分钟";
|
|
18
|
+
readonly 'unit.minute.other': "分钟";
|
|
19
|
+
readonly 'unit.second.one': "秒";
|
|
20
|
+
readonly 'unit.second.other': "秒";
|
|
21
|
+
readonly 'relative.now': "现在到期";
|
|
22
|
+
readonly 'relative.future': "{value}{unit}后";
|
|
23
|
+
readonly 'relative.overdue': "已逾期 {value}{unit}";
|
|
24
|
+
};
|
|
25
|
+
/** English dictionary, key-identical to the Chinese source of truth. */
|
|
26
|
+
export declare const en: Record<ScheduleCatalogKey, string>;
|
|
27
|
+
/** Key domain of the Schedule catalog namespace. */
|
|
28
|
+
export type ScheduleCatalogKey = keyof typeof zh;
|
|
29
|
+
//# sourceMappingURL=locales.d.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read-only Schedule catalog plugin, node half. The empty apply keeps the
|
|
3
|
+
* optional browser feature addressable from the host-owned Loader overlay.
|
|
4
|
+
*/
|
|
5
|
+
/** Host plugin body — Schedule catalog behavior exists only in the browser entry. */
|
|
6
|
+
export declare function apply(): void;
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Package-owned invariant companion for the read-only Schedule catalog. */
|
|
2
|
+
import type { Context } from '@prettier-ai/cordis';
|
|
3
|
+
/** Cordis companion plugin name. */
|
|
4
|
+
export declare const name = "client-ui-schedule-invariant";
|
|
5
|
+
/** Service required before the companion can reserve package ownership. */
|
|
6
|
+
export declare const inject: string[];
|
|
7
|
+
/** Register this package's invariant companion. */
|
|
8
|
+
export declare const apply: (ctx: Context) => Promise<() => void>;
|
|
9
|
+
//# sourceMappingURL=invariant.d.ts.map
|
package/package.json
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@prettier-ai/dsh-client-ui-schedule",
|
|
3
|
+
"description": "Read-only active Schedule catalog in the Web Session header",
|
|
4
|
+
"version": "0.1.2-alpha.2",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "lib/index.js",
|
|
7
|
+
"types": "lib/types/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./lib/types/index.d.ts",
|
|
11
|
+
"default": "./lib/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./invariant": {
|
|
14
|
+
"types": "./lib/types/invariant.d.ts",
|
|
15
|
+
"default": "./lib/invariant.js"
|
|
16
|
+
},
|
|
17
|
+
"./client": {
|
|
18
|
+
"types": "./lib/types/client/index.d.ts",
|
|
19
|
+
"default": "./lib/client.js"
|
|
20
|
+
},
|
|
21
|
+
"./src/*": "./src/*",
|
|
22
|
+
"./package.json": "./package.json"
|
|
23
|
+
},
|
|
24
|
+
"dsh": {
|
|
25
|
+
"client": {
|
|
26
|
+
"inject": [
|
|
27
|
+
"@prettier-ai/dsh-client-locale",
|
|
28
|
+
"@prettier-ai/dsh-client-ui-conversation",
|
|
29
|
+
"@prettier-ai/dsh-client-ui-primitives"
|
|
30
|
+
],
|
|
31
|
+
"platform": "web"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "git+https://github.com/deepseek-ai/deepseek-harness.git",
|
|
38
|
+
"directory": "packages/client/ui-schedule"
|
|
39
|
+
},
|
|
40
|
+
"publishConfig": {
|
|
41
|
+
"access": "public"
|
|
42
|
+
},
|
|
43
|
+
"peerDependencies": {
|
|
44
|
+
"@prettier-ai/cordis": "^4.0.2"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@testing-library/react": "^16.1.0",
|
|
48
|
+
"@types/react": "~18.3.1",
|
|
49
|
+
"react": "^18.2.0",
|
|
50
|
+
"react-dom": "^18.2.0",
|
|
51
|
+
"@prettier-ai/dsh-api-session-controller": "^0.1.2-alpha.2",
|
|
52
|
+
"@prettier-ai/dsh-client-locale": "^0.1.2-alpha.2",
|
|
53
|
+
"@prettier-ai/dsh-client-ui-conversation": "^0.1.2-alpha.2",
|
|
54
|
+
"@prettier-ai/dsh-client-ui-renderer": "^0.1.2-alpha.2",
|
|
55
|
+
"@prettier-ai/dsh-client-ui-primitives": "^0.1.2-alpha.2",
|
|
56
|
+
"@prettier-ai/dsh-client-test-runtime": "^0.1.2-alpha.2",
|
|
57
|
+
"@prettier-ai/dsh-client-ui-session": "^0.1.2-alpha.2",
|
|
58
|
+
"@prettier-ai/dsh-client-ui-slots": "^0.1.2-alpha.2",
|
|
59
|
+
"@prettier-ai/dsh-schedule": "^0.1.2-alpha.2",
|
|
60
|
+
"@prettier-ai/dsh-invariants": "^0.1.2-alpha.2",
|
|
61
|
+
"@prettier-ai/dsh-session": "^0.1.2-alpha.2",
|
|
62
|
+
"@prettier-ai/cordis": "^4.0.2"
|
|
63
|
+
},
|
|
64
|
+
"files": [
|
|
65
|
+
"lib/index.js",
|
|
66
|
+
"lib/invariant.js",
|
|
67
|
+
"lib/client.js",
|
|
68
|
+
"lib/types/**/*.d.ts"
|
|
69
|
+
],
|
|
70
|
+
"scripts": {
|
|
71
|
+
"bundle": "tsdown",
|
|
72
|
+
"watch": "tsdown --watch"
|
|
73
|
+
}
|
|
74
|
+
}
|