dsh-calendar 0.9.2 → 0.9.4
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/CHANGELOG.md +130 -116
- package/LICENSE +21 -21
- package/README.en.md +222 -216
- package/README.md +256 -250
- package/cordis.patch.yml +23 -23
- package/lib/client.js +31 -27
- package/lib/config.d.ts +2 -2
- package/lib/web.js +5 -3
- package/package.json +80 -80
package/lib/client.js
CHANGED
|
@@ -152,7 +152,7 @@ const UI = {
|
|
|
152
152
|
"state.notConfigured": "还没配置 CalDAV 账号",
|
|
153
153
|
"state.notConfiguredHint": "点击“连接设置”,选择日历服务并填写账号信息,测试连接后保存即可。也可以先查看示例,了解日历的用法。",
|
|
154
154
|
"state.readonly": "只读",
|
|
155
|
-
"demo.banner": "示例日历为只读,可以切换视图和查看详情。点击「退出示例」后连接自己的日历,即可创建和修改日程。",
|
|
155
|
+
"demo.banner": "示例日历为只读,可以切换视图和查看详情。点击「退出示例」后连接自己的日历,即可创建和修改日程。",
|
|
156
156
|
"field.summary": "标题", "field.date": "日期", "field.start": "开始", "field.end": "结束",
|
|
157
157
|
"field.allDay": "全天", "field.location": "地点", "field.description": "备注",
|
|
158
158
|
"field.repeat": "重复", "field.uid": "事件 uid", "field.when": "时间", "field.duration": "时长",
|
|
@@ -194,7 +194,7 @@ const UI = {
|
|
|
194
194
|
"conn.refreshToken": "refreshToken",
|
|
195
195
|
"conn.tokenUrl": "令牌地址(可留空)",
|
|
196
196
|
"conn.proxyUrl": "代理地址(可留空)",
|
|
197
|
-
"conn.keep": "
|
|
197
|
+
"conn.keep": "已配置,留空不改",
|
|
198
198
|
"conn.test": "测试连接",
|
|
199
199
|
"conn.testing": "正在连接…",
|
|
200
200
|
"conn.save": "保存并启用",
|
|
@@ -247,7 +247,7 @@ const UI = {
|
|
|
247
247
|
"state.notConfigured": "No CalDAV account configured yet",
|
|
248
248
|
"state.notConfiguredHint": "Open Connection settings, choose your calendar service and enter your account details, then test and save the connection. You can also explore the sample calendar first.",
|
|
249
249
|
"state.readonly": "read-only",
|
|
250
|
-
"demo.banner": "This sample calendar is read-only. Switch views and open event details. Exit the sample and connect your calendar to create or edit events.",
|
|
250
|
+
"demo.banner": "This sample calendar is read-only. Switch views and open event details. Exit the sample and connect your calendar to create or edit events.",
|
|
251
251
|
"field.summary": "Title", "field.date": "Date", "field.start": "Start", "field.end": "End",
|
|
252
252
|
"field.allDay": "All day", "field.location": "Location", "field.description": "Notes",
|
|
253
253
|
"field.repeat": "Repeats", "field.uid": "Event uid", "field.when": "When", "field.duration": "Duration",
|
|
@@ -289,7 +289,7 @@ const UI = {
|
|
|
289
289
|
"conn.refreshToken": "refreshToken",
|
|
290
290
|
"conn.tokenUrl": "Token URL (optional)",
|
|
291
291
|
"conn.proxyUrl": "Proxy URL (optional)",
|
|
292
|
-
"conn.keep": "
|
|
292
|
+
"conn.keep": "configured — leave blank to keep",
|
|
293
293
|
"conn.test": "Test connection",
|
|
294
294
|
"conn.testing": "Connecting…",
|
|
295
295
|
"conn.save": "Save and enable",
|
|
@@ -1119,12 +1119,12 @@ function demoEvents() {
|
|
|
1119
1119
|
const at = (offset, hour, minute) => { const d = addDays(base, offset); d.setHours(hour, minute || 0, 0, 0); return isoOf(d); };
|
|
1120
1120
|
const dateOnly = (offset) => { const d = addDays(base, offset); return dayKey(d); };
|
|
1121
1121
|
return [
|
|
1122
|
-
{ uid: "demo://allday", summary: "📦 项目上线日", start: dateOnly(0), end: dateOnly(1), allDay: true, description: "确认发布说明并完成上线检查", location: "线上", isOccurrence: false },
|
|
1123
|
-
{ uid: "demo://review", summary: "产品评审会", start: at(0, 10, 0), end: at(0, 11, 0), allDay: false, location: "会议室 A", description: "议程:体验反馈与本周计划", isOccurrence: false },
|
|
1122
|
+
{ uid: "demo://allday", summary: "📦 项目上线日", start: dateOnly(0), end: dateOnly(1), allDay: true, description: "确认发布说明并完成上线检查", location: "线上", isOccurrence: false },
|
|
1123
|
+
{ uid: "demo://review", summary: "产品评审会", start: at(0, 10, 0), end: at(0, 11, 0), allDay: false, location: "会议室 A", description: "议程:体验反馈与本周计划", isOccurrence: false },
|
|
1124
1124
|
{ uid: "demo://one-on-one", summary: "1:1 同步", start: at(0, 15, 0), end: at(0, 15, 30), allDay: false, location: "线上", isOccurrence: false },
|
|
1125
1125
|
{ uid: "demo://standup", summary: "每周站会", start: at(1, 9, 30), end: at(1, 9, 50), allDay: false, rrule: "FREQ=WEEKLY;COUNT=6", location: "线上", isOccurrence: false },
|
|
1126
1126
|
{ uid: "demo://standup@2", summary: "每周站会", start: at(8, 9, 30), end: at(8, 9, 50), allDay: false, location: "线上", isOccurrence: true, seriesStart: at(1, 9, 30) },
|
|
1127
|
-
{ uid: "demo://sync", summary: "与同事同步", start: at(2, 16, 0), end: at(2, 16, 30), allDay: false, location: "线上", description: "同步进度与下一步安排", isOccurrence: false }
|
|
1127
|
+
{ uid: "demo://sync", summary: "与同事同步", start: at(2, 16, 0), end: at(2, 16, 30), allDay: false, location: "线上", description: "同步进度与下一步安排", isOccurrence: false }
|
|
1128
1128
|
];
|
|
1129
1129
|
}
|
|
1130
1130
|
|
|
@@ -1305,8 +1305,8 @@ function EventForm(props) {
|
|
|
1305
1305
|
|
|
1306
1306
|
// ───────────────────────────── 详情抽屉 ─────────────────────────────
|
|
1307
1307
|
|
|
1308
|
-
function EventDrawer(props) {
|
|
1309
|
-
const { event, onClose, onEdit, onDelete, busy, confirmDelete, setConfirmDelete, events, readOnly } = props;
|
|
1308
|
+
function EventDrawer(props) {
|
|
1309
|
+
const { event, onClose, onEdit, onDelete, busy, confirmDelete, setConfirmDelete, events, readOnly } = props;
|
|
1310
1310
|
const [copied, setCopied] = useState(false);
|
|
1311
1311
|
const seriesCount = event.isOccurrence ? events.filter((e) => e.seriesStart === event.seriesStart).length : 0;
|
|
1312
1312
|
return h("div", { className: "dshc-overlay", onMouseDown: (e) => { if (e.target === e.currentTarget) onClose(); } }, [
|
|
@@ -1333,9 +1333,9 @@ function EventDrawer(props) {
|
|
|
1333
1333
|
h(Btn, { key: "copy", onClick: async () => { const ok = await copyText(event.uid); if (ok) { setCopied(true); setTimeout(() => setCopied(false), 1600); } } }, copied ? t("action.copied") : t("action.copy")),
|
|
1334
1334
|
h("span", { className: "dshc-spacer" }),
|
|
1335
1335
|
confirmDelete
|
|
1336
|
-
? h(Btn, { key: "confirm", variant: "primary", disabled: busy === true || readOnly === true, onClick: () => onDelete(event) }, t("action.confirmDelete"))
|
|
1337
|
-
: h(Btn, { key: "delete", variant: "danger", onClick: () => setConfirmDelete(true), disabled: busy === true || readOnly === true }, t("action.delete")),
|
|
1338
|
-
h(Btn, { key: "edit", variant: "outline", onClick: () => onEdit(event), disabled: busy === true || readOnly === true }, t("action.edit"))
|
|
1336
|
+
? h(Btn, { key: "confirm", variant: "primary", disabled: busy === true || readOnly === true, onClick: () => onDelete(event) }, t("action.confirmDelete"))
|
|
1337
|
+
: h(Btn, { key: "delete", variant: "danger", onClick: () => setConfirmDelete(true), disabled: busy === true || readOnly === true }, t("action.delete")),
|
|
1338
|
+
h(Btn, { key: "edit", variant: "outline", onClick: () => onEdit(event), disabled: busy === true || readOnly === true }, t("action.edit"))
|
|
1339
1339
|
]),
|
|
1340
1340
|
confirmDelete ? h("div", { className: "dshc-sub", style: { textAlign: "right", marginTop: "6px" } }, t("confirm.delete", { name: event.summary })) : null
|
|
1341
1341
|
])
|
|
@@ -1410,7 +1410,10 @@ function ConnectionForm(props) {
|
|
|
1410
1410
|
const [busy, setBusy] = useState("");
|
|
1411
1411
|
const [result, setResult] = useState(null);
|
|
1412
1412
|
const maySave = connection === null || connection.settingsAvailable !== false;
|
|
1413
|
-
const patch = (fields) =>
|
|
1413
|
+
const patch = (fields) => {
|
|
1414
|
+
setForm((prev) => Object.assign({}, prev, fields));
|
|
1415
|
+
setResult(null);
|
|
1416
|
+
};
|
|
1414
1417
|
const visible = PROVIDER_FIELDS[form.provider] || [];
|
|
1415
1418
|
const payload = () => {
|
|
1416
1419
|
const out = {};
|
|
@@ -1423,6 +1426,7 @@ function ConnectionForm(props) {
|
|
|
1423
1426
|
}
|
|
1424
1427
|
if (form.provider !== "") out.provider = form.provider;
|
|
1425
1428
|
if (form.provider === "google") out.authMethod = "oauth";
|
|
1429
|
+
else if (form.provider !== "" && connection && form.provider !== connection.provider) out.authMethod = "basic";
|
|
1426
1430
|
return out;
|
|
1427
1431
|
};
|
|
1428
1432
|
const test = async () => {
|
|
@@ -1756,8 +1760,8 @@ function CalendarPanel(props) {
|
|
|
1756
1760
|
};
|
|
1757
1761
|
|
|
1758
1762
|
/** 改期入口:重复日程先问一句(拖动会移动整个系列,这是语义雷区,不能悄悄做)。 */
|
|
1759
|
-
const reschedule = (event, range) => {
|
|
1760
|
-
if (demo === true) { notify(t("demo.banner")); return; }
|
|
1763
|
+
const reschedule = (event, range) => {
|
|
1764
|
+
if (demo === true) { notify(t("demo.banner")); return; }
|
|
1761
1765
|
// 重复日程暂不支持拖动改期:CalDAV 里整个系列是一个对象,而 update 只能改 master 的
|
|
1762
1766
|
// DTSTART —— 把「这次实例的目标时间」发过去等于**重锚系列起点**(早于它的实例全丢、
|
|
1763
1767
|
// COUNT/UNTIL 语义被改,撤销也回不到原系列)。评审实测过,这里必须先挡住。
|
|
@@ -1789,8 +1793,8 @@ function CalendarPanel(props) {
|
|
|
1789
1793
|
const title = view === "week" ? formatWeekTitle(anchor) : view === "agenda" ? t("view.agenda") : formatMonthTitle(anchor);
|
|
1790
1794
|
const step = (delta) => setAnchor((current) => (view === "week" ? addDays(current, delta * 7) : addMonthShift(current, delta)));
|
|
1791
1795
|
|
|
1792
|
-
const submit = async (form) => {
|
|
1793
|
-
if (demo === true) { setFormError(t("demo.banner")); return; }
|
|
1796
|
+
const submit = async (form) => {
|
|
1797
|
+
if (demo === true) { setFormError(t("demo.banner")); return; }
|
|
1794
1798
|
setBusy(true);
|
|
1795
1799
|
setFormError(null);
|
|
1796
1800
|
try {
|
|
@@ -1808,8 +1812,8 @@ function CalendarPanel(props) {
|
|
|
1808
1812
|
}
|
|
1809
1813
|
};
|
|
1810
1814
|
|
|
1811
|
-
const remove = async (event) => {
|
|
1812
|
-
if (demo === true) { notify(t("demo.banner")); return; }
|
|
1815
|
+
const remove = async (event) => {
|
|
1816
|
+
if (demo === true) { notify(t("demo.banner")); return; }
|
|
1813
1817
|
setBusy(true);
|
|
1814
1818
|
try {
|
|
1815
1819
|
await api("delete", { uid: event.uid });
|
|
@@ -1839,7 +1843,7 @@ function CalendarPanel(props) {
|
|
|
1839
1843
|
demo === true
|
|
1840
1844
|
? h(Btn, { key: "exitdemo", onClick: () => setDemo(false) }, t("action.exitDemo"))
|
|
1841
1845
|
: h(Btn, { key: "reload", onClick: reload }, t("action.refresh")),
|
|
1842
|
-
h(Btn, { key: "new", variant: "primary", disabled: demo === true, onClick: () => setDraft(draftAt(anchor)) }, t("action.new"))
|
|
1846
|
+
h(Btn, { key: "new", variant: "primary", disabled: demo === true, onClick: () => setDraft(draftAt(anchor)) }, t("action.new"))
|
|
1843
1847
|
]);
|
|
1844
1848
|
|
|
1845
1849
|
const body = () => {
|
|
@@ -1857,16 +1861,16 @@ function CalendarPanel(props) {
|
|
|
1857
1861
|
if (data.loading === true && data.events.length === 0) {
|
|
1858
1862
|
return h("div", { className: "dshc-grid" }, Array.from({ length: 14 }, (_, i) => h("div", { className: "dshc-skel", key: i })));
|
|
1859
1863
|
}
|
|
1860
|
-
if (view === "week") return h(WeekView, { anchor, events: visibleEvents, onPick: openEvent, onCreateAt: createAt, onReschedule: demo === true ? undefined : reschedule });
|
|
1864
|
+
if (view === "week") return h(WeekView, { anchor, events: visibleEvents, onPick: openEvent, onCreateAt: createAt, onReschedule: demo === true ? undefined : reschedule });
|
|
1861
1865
|
if (view === "agenda") return h(AgendaView, { events: visibleEvents, onPick: openEvent, onCreateAt: createAt });
|
|
1862
1866
|
return h(MonthView, { anchor, events: visibleEvents, onPick: openEvent, onCreateAt: createAt });
|
|
1863
1867
|
};
|
|
1864
1868
|
|
|
1865
1869
|
const openEvent = (event) => { setConfirmDelete(false); setSelected(event); };
|
|
1866
|
-
const createAt = (day, hour) => {
|
|
1867
|
-
if (demo === true) { notify(t("demo.banner")); return; }
|
|
1868
|
-
setDraft(draftAt(day, hour));
|
|
1869
|
-
};
|
|
1870
|
+
const createAt = (day, hour) => {
|
|
1871
|
+
if (demo === true) { notify(t("demo.banner")); return; }
|
|
1872
|
+
setDraft(draftAt(day, hour));
|
|
1873
|
+
};
|
|
1870
1874
|
|
|
1871
1875
|
return h("div", { ref: rootRef, className: "dshc-root" }, [
|
|
1872
1876
|
h("div", { className: "dshc-shell" }, [
|
|
@@ -1893,8 +1897,8 @@ function CalendarPanel(props) {
|
|
|
1893
1897
|
])
|
|
1894
1898
|
]),
|
|
1895
1899
|
selected !== null
|
|
1896
|
-
? h(EventDrawer, {
|
|
1897
|
-
readOnly: demo === true,
|
|
1900
|
+
? h(EventDrawer, {
|
|
1901
|
+
readOnly: demo === true,
|
|
1898
1902
|
event: selected,
|
|
1899
1903
|
events: data.events,
|
|
1900
1904
|
busy,
|
package/lib/config.d.ts
CHANGED
|
@@ -44,8 +44,8 @@ export interface CalendarConfig {
|
|
|
44
44
|
calendar?: string;
|
|
45
45
|
/**
|
|
46
46
|
* HTTP 代理地址,如 http://127.0.0.1:7890。
|
|
47
|
-
*
|
|
48
|
-
*
|
|
47
|
+
* 当前网络无法直连时可填本地代理客户端的端口;可直连时留空即可。
|
|
48
|
+
* 插件只把本插件的请求路由到该代理,不影响其他插件。
|
|
49
49
|
*/
|
|
50
50
|
proxyUrl?: string;
|
|
51
51
|
}
|
package/lib/web.js
CHANGED
|
@@ -248,6 +248,8 @@ export class CalendarSettingsBackend {
|
|
|
248
248
|
const resolved = effective[key];
|
|
249
249
|
return typeof resolved === 'string' ? resolved : '';
|
|
250
250
|
};
|
|
251
|
+
const env = this.options.env ?? process.env;
|
|
252
|
+
const hasCredential = (key, envKey) => text(key).trim() !== '' || (typeof env[envKey] === 'string' && env[envKey].trim() !== '');
|
|
251
253
|
return {
|
|
252
254
|
configured,
|
|
253
255
|
...(reason !== undefined ? { reason } : {}),
|
|
@@ -266,9 +268,9 @@ export class CalendarSettingsBackend {
|
|
|
266
268
|
clientId: text('clientId'),
|
|
267
269
|
tokenUrl: text('tokenUrl'),
|
|
268
270
|
proxyUrl: text('proxyUrl'),
|
|
269
|
-
hasPassword:
|
|
270
|
-
hasClientSecret:
|
|
271
|
-
hasRefreshToken:
|
|
271
|
+
hasPassword: hasCredential('password', 'DSH_CALENDAR_PASSWORD'),
|
|
272
|
+
hasClientSecret: hasCredential('clientSecret', 'DSH_CALENDAR_CLIENT_SECRET'),
|
|
273
|
+
hasRefreshToken: hasCredential('refreshToken', 'DSH_CALENDAR_REFRESH_TOKEN'),
|
|
272
274
|
};
|
|
273
275
|
}
|
|
274
276
|
/** 兼容旧动作名:status 就是连接摘要。 */
|
package/package.json
CHANGED
|
@@ -1,80 +1,80 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "dsh-calendar",
|
|
3
|
-
"version": "0.9.
|
|
4
|
-
"description": "DSH 日历插件:可视化周/月视图、拖拽改期与 CalDAV 日程管理,支持 Google OAuth2、iCloud、Nextcloud。",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "lib/index.js",
|
|
7
|
-
"types": "lib/index.d.ts",
|
|
8
|
-
"exports": {
|
|
9
|
-
".": {
|
|
10
|
-
"types": "./lib/index.d.ts",
|
|
11
|
-
"default": "./lib/index.js"
|
|
12
|
-
},
|
|
13
|
-
"./client": "./lib/client.js",
|
|
14
|
-
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
15
|
-
"./package.json": "./package.json"
|
|
16
|
-
},
|
|
17
|
-
"files": [
|
|
18
|
-
"lib",
|
|
19
|
-
"scripts",
|
|
20
|
-
"cordis.patch.yml",
|
|
21
|
-
"README.md",
|
|
22
|
-
"README.en.md",
|
|
23
|
-
"CHANGELOG.md"
|
|
24
|
-
],
|
|
25
|
-
"scripts": {
|
|
26
|
-
"build": "tsc -p tsconfig.json",
|
|
27
|
-
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
28
|
-
"test": "pnpm run build && node --test \"test/*.test.mjs\"",
|
|
29
|
-
"prepublishOnly": "pnpm run build"
|
|
30
|
-
},
|
|
31
|
-
"dsh": {
|
|
32
|
-
"bundle": {
|
|
33
|
-
"patch": "./cordis.patch.yml"
|
|
34
|
-
},
|
|
35
|
-
"client": {
|
|
36
|
-
"inject": [
|
|
37
|
-
"@deepseek-ai/dsh-client-ui-settings"
|
|
38
|
-
],
|
|
39
|
-
"platform": "web"
|
|
40
|
-
}
|
|
41
|
-
},
|
|
42
|
-
"keywords": [
|
|
43
|
-
"dsh",
|
|
44
|
-
"deepseek-harness",
|
|
45
|
-
"dsh-plugin",
|
|
46
|
-
"plugin",
|
|
47
|
-
"calendar",
|
|
48
|
-
"caldav",
|
|
49
|
-
"ical"
|
|
50
|
-
],
|
|
51
|
-
"license": "MIT",
|
|
52
|
-
"engines": {
|
|
53
|
-
"node": "^22.19.0 || >=24.0.0"
|
|
54
|
-
},
|
|
55
|
-
"dependencies": {
|
|
56
|
-
"@deepseek-ai/schemastery": "^3.18.3",
|
|
57
|
-
"ical.js": "^2.1.0",
|
|
58
|
-
"schemastery": "^3.18.0",
|
|
59
|
-
"tsdav": "^2.3.1",
|
|
60
|
-
"undici": "^8.
|
|
61
|
-
"yaml": "^2.9.1"
|
|
62
|
-
},
|
|
63
|
-
"devDependencies": {
|
|
64
|
-
"@types/node": "^24.0.0",
|
|
65
|
-
"jsdom": "^30.1.0",
|
|
66
|
-
"react": "^19.3.0",
|
|
67
|
-
"react-dom": "^19.3.0",
|
|
68
|
-
"typescript": "^5.6.0"
|
|
69
|
-
},
|
|
70
|
-
"repository": {
|
|
71
|
-
"type": "git",
|
|
72
|
-
"url": "git+https://github.com/STARDUSTLC666/dsh-calendar.git"
|
|
73
|
-
},
|
|
74
|
-
"bugs": {
|
|
75
|
-
"url": "https://github.com/STARDUSTLC666/dsh-calendar/issues"
|
|
76
|
-
},
|
|
77
|
-
"homepage": "https://github.com/STARDUSTLC666/dsh-calendar#readme",
|
|
78
|
-
"author": "stardustlc",
|
|
79
|
-
"packageManager": "pnpm@11.7.0"
|
|
80
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "dsh-calendar",
|
|
3
|
+
"version": "0.9.4",
|
|
4
|
+
"description": "DSH 日历插件:可视化周/月视图、拖拽改期与 CalDAV 日程管理,支持 Google OAuth2、iCloud、Nextcloud。",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "lib/index.js",
|
|
7
|
+
"types": "lib/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./lib/index.d.ts",
|
|
11
|
+
"default": "./lib/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./client": "./lib/client.js",
|
|
14
|
+
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
15
|
+
"./package.json": "./package.json"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"lib",
|
|
19
|
+
"scripts",
|
|
20
|
+
"cordis.patch.yml",
|
|
21
|
+
"README.md",
|
|
22
|
+
"README.en.md",
|
|
23
|
+
"CHANGELOG.md"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsc -p tsconfig.json",
|
|
27
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
28
|
+
"test": "pnpm run build && node --test \"test/*.test.mjs\"",
|
|
29
|
+
"prepublishOnly": "pnpm run build"
|
|
30
|
+
},
|
|
31
|
+
"dsh": {
|
|
32
|
+
"bundle": {
|
|
33
|
+
"patch": "./cordis.patch.yml"
|
|
34
|
+
},
|
|
35
|
+
"client": {
|
|
36
|
+
"inject": [
|
|
37
|
+
"@deepseek-ai/dsh-client-ui-settings"
|
|
38
|
+
],
|
|
39
|
+
"platform": "web"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"keywords": [
|
|
43
|
+
"dsh",
|
|
44
|
+
"deepseek-harness",
|
|
45
|
+
"dsh-plugin",
|
|
46
|
+
"plugin",
|
|
47
|
+
"calendar",
|
|
48
|
+
"caldav",
|
|
49
|
+
"ical"
|
|
50
|
+
],
|
|
51
|
+
"license": "MIT",
|
|
52
|
+
"engines": {
|
|
53
|
+
"node": "^22.19.0 || >=24.0.0"
|
|
54
|
+
},
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"@deepseek-ai/schemastery": "^3.18.3",
|
|
57
|
+
"ical.js": "^2.1.0",
|
|
58
|
+
"schemastery": "^3.18.0",
|
|
59
|
+
"tsdav": "^2.3.1",
|
|
60
|
+
"undici": "^8.11.2",
|
|
61
|
+
"yaml": "^2.9.1"
|
|
62
|
+
},
|
|
63
|
+
"devDependencies": {
|
|
64
|
+
"@types/node": "^24.0.0",
|
|
65
|
+
"jsdom": "^30.1.0",
|
|
66
|
+
"react": "^19.3.0",
|
|
67
|
+
"react-dom": "^19.3.0",
|
|
68
|
+
"typescript": "^5.6.0"
|
|
69
|
+
},
|
|
70
|
+
"repository": {
|
|
71
|
+
"type": "git",
|
|
72
|
+
"url": "git+https://github.com/STARDUSTLC666/dsh-calendar.git"
|
|
73
|
+
},
|
|
74
|
+
"bugs": {
|
|
75
|
+
"url": "https://github.com/STARDUSTLC666/dsh-calendar/issues"
|
|
76
|
+
},
|
|
77
|
+
"homepage": "https://github.com/STARDUSTLC666/dsh-calendar#readme",
|
|
78
|
+
"author": "stardustlc",
|
|
79
|
+
"packageManager": "pnpm@11.7.0"
|
|
80
|
+
}
|