dsh-tiddlywiki 0.3.0 → 0.3.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.md +1 -1
- package/lib/client.bundle.js +2186 -2173
- package/lib/client.js +2196 -2183
- package/lib/index.js +2436 -2424
- package/lib/index.js.map +1 -1
- package/package.json +79 -79
- package/src/client/styles.ts +20 -7
- package/src/host/routes.ts +16 -8
- package/src/index.ts +3 -1
package/package.json
CHANGED
|
@@ -1,79 +1,79 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "dsh-tiddlywiki",
|
|
3
|
-
"description": "TiddlyWiki 5 as the DSH persistent knowledge base: tiddlywiki_* agent tools (search/get/put/delete + git sync), a full TiddlyWiki editor embedded in the GUI center column, a floating quick-note widget in the chat area, and git-based sync with auto-commit. Mounts via the official dsh plugin system — no DSH source changes.",
|
|
4
|
-
"version": "0.3.
|
|
5
|
-
"type": "module",
|
|
6
|
-
"keywords": [
|
|
7
|
-
"dsh",
|
|
8
|
-
"dsh-plugin",
|
|
9
|
-
"tiddlywiki",
|
|
10
|
-
"knowledge-base",
|
|
11
|
-
"note-taking",
|
|
12
|
-
"notes",
|
|
13
|
-
"wiki",
|
|
14
|
-
"git-sync",
|
|
15
|
-
"agent-tools",
|
|
16
|
-
"plugin"
|
|
17
|
-
],
|
|
18
|
-
"author": {
|
|
19
|
-
"name": "bbqisbbq",
|
|
20
|
-
"url": "https://github.com/bbqisbbq"
|
|
21
|
-
},
|
|
22
|
-
"main": "lib/index.js",
|
|
23
|
-
"exports": {
|
|
24
|
-
".": "./lib/index.js",
|
|
25
|
-
"./client": "./lib/client.js",
|
|
26
|
-
"./package.json": "./package.json"
|
|
27
|
-
},
|
|
28
|
-
"dsh": {
|
|
29
|
-
"bundle": {
|
|
30
|
-
"patch": "./cordis.patch.yml"
|
|
31
|
-
},
|
|
32
|
-
"client": {
|
|
33
|
-
"inject": [
|
|
34
|
-
"slots"
|
|
35
|
-
],
|
|
36
|
-
"platform": "web"
|
|
37
|
-
}
|
|
38
|
-
},
|
|
39
|
-
"files": [
|
|
40
|
-
"lib/**/*.js",
|
|
41
|
-
"lib/**/*.js.map",
|
|
42
|
-
"src",
|
|
43
|
-
"cordis.patch.yml",
|
|
44
|
-
"LICENSE",
|
|
45
|
-
"README.md"
|
|
46
|
-
],
|
|
47
|
-
"license": "MIT",
|
|
48
|
-
"homepage": "https://github.com/bbqisbbq/dsh-tiddlywiki#readme",
|
|
49
|
-
"repository": {
|
|
50
|
-
"type": "git",
|
|
51
|
-
"url": "https://github.com/bbqisbbq/dsh-tiddlywiki.git"
|
|
52
|
-
},
|
|
53
|
-
"bugs": {
|
|
54
|
-
"url": "https://github.com/bbqisbbq/dsh-tiddlywiki/issues"
|
|
55
|
-
},
|
|
56
|
-
"engines": {
|
|
57
|
-
"node": ">=22"
|
|
58
|
-
},
|
|
59
|
-
"dependencies": {
|
|
60
|
-
"tiddlywiki": "^5.4.1"
|
|
61
|
-
},
|
|
62
|
-
"devDependencies": {
|
|
63
|
-
"@types/node": "^22.20.1",
|
|
64
|
-
"@types/react": "^19.1.0",
|
|
65
|
-
"react": "^19.1.0",
|
|
66
|
-
"tsdown": "0.22.2",
|
|
67
|
-
"tsx": "^4.19.2",
|
|
68
|
-
"typescript": "~5.7.2",
|
|
69
|
-
"unrun": "*"
|
|
70
|
-
},
|
|
71
|
-
"scripts": {
|
|
72
|
-
"build": "node scripts/clean-lib.mjs && npm run build:host && npm run build:client",
|
|
73
|
-
"build:host": "tsdown -c tsdown.host.config.ts",
|
|
74
|
-
"build:client": "tsdown -c tsdown.client.config.ts && node scripts/wrap-client.mjs",
|
|
75
|
-
"watch": "tsdown -c tsdown.host.config.ts --watch",
|
|
76
|
-
"typecheck": "tsc --noEmit",
|
|
77
|
-
"selftest": "node scripts/selftest.mjs"
|
|
78
|
-
}
|
|
79
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "dsh-tiddlywiki",
|
|
3
|
+
"description": "TiddlyWiki 5 as the DSH persistent knowledge base: tiddlywiki_* agent tools (search/get/put/delete + git sync), a full TiddlyWiki editor embedded in the GUI center column, a floating quick-note widget in the chat area, and git-based sync with auto-commit. Mounts via the official dsh plugin system — no DSH source changes.",
|
|
4
|
+
"version": "0.3.1",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"dsh",
|
|
8
|
+
"dsh-plugin",
|
|
9
|
+
"tiddlywiki",
|
|
10
|
+
"knowledge-base",
|
|
11
|
+
"note-taking",
|
|
12
|
+
"notes",
|
|
13
|
+
"wiki",
|
|
14
|
+
"git-sync",
|
|
15
|
+
"agent-tools",
|
|
16
|
+
"plugin"
|
|
17
|
+
],
|
|
18
|
+
"author": {
|
|
19
|
+
"name": "bbqisbbq",
|
|
20
|
+
"url": "https://github.com/bbqisbbq"
|
|
21
|
+
},
|
|
22
|
+
"main": "lib/index.js",
|
|
23
|
+
"exports": {
|
|
24
|
+
".": "./lib/index.js",
|
|
25
|
+
"./client": "./lib/client.js",
|
|
26
|
+
"./package.json": "./package.json"
|
|
27
|
+
},
|
|
28
|
+
"dsh": {
|
|
29
|
+
"bundle": {
|
|
30
|
+
"patch": "./cordis.patch.yml"
|
|
31
|
+
},
|
|
32
|
+
"client": {
|
|
33
|
+
"inject": [
|
|
34
|
+
"slots"
|
|
35
|
+
],
|
|
36
|
+
"platform": "web"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"lib/**/*.js",
|
|
41
|
+
"lib/**/*.js.map",
|
|
42
|
+
"src",
|
|
43
|
+
"cordis.patch.yml",
|
|
44
|
+
"LICENSE",
|
|
45
|
+
"README.md"
|
|
46
|
+
],
|
|
47
|
+
"license": "MIT",
|
|
48
|
+
"homepage": "https://github.com/bbqisbbq/dsh-tiddlywiki#readme",
|
|
49
|
+
"repository": {
|
|
50
|
+
"type": "git",
|
|
51
|
+
"url": "https://github.com/bbqisbbq/dsh-tiddlywiki.git"
|
|
52
|
+
},
|
|
53
|
+
"bugs": {
|
|
54
|
+
"url": "https://github.com/bbqisbbq/dsh-tiddlywiki/issues"
|
|
55
|
+
},
|
|
56
|
+
"engines": {
|
|
57
|
+
"node": ">=22"
|
|
58
|
+
},
|
|
59
|
+
"dependencies": {
|
|
60
|
+
"tiddlywiki": "^5.4.1"
|
|
61
|
+
},
|
|
62
|
+
"devDependencies": {
|
|
63
|
+
"@types/node": "^22.20.1",
|
|
64
|
+
"@types/react": "^19.1.0",
|
|
65
|
+
"react": "^19.1.0",
|
|
66
|
+
"tsdown": "0.22.2",
|
|
67
|
+
"tsx": "^4.19.2",
|
|
68
|
+
"typescript": "~5.7.2",
|
|
69
|
+
"unrun": "*"
|
|
70
|
+
},
|
|
71
|
+
"scripts": {
|
|
72
|
+
"build": "node scripts/clean-lib.mjs && npm run build:host && npm run build:client",
|
|
73
|
+
"build:host": "tsdown -c tsdown.host.config.ts",
|
|
74
|
+
"build:client": "tsdown -c tsdown.client.config.ts && node scripts/wrap-client.mjs",
|
|
75
|
+
"watch": "tsdown -c tsdown.host.config.ts --watch",
|
|
76
|
+
"typecheck": "tsc --noEmit",
|
|
77
|
+
"selftest": "node scripts/selftest.mjs"
|
|
78
|
+
}
|
|
79
|
+
}
|
package/src/client/styles.ts
CHANGED
|
@@ -95,9 +95,12 @@ html[data-dsh-tw-active] .dshDesktopConversationSurface > :not([data-dsh-tw-view
|
|
|
95
95
|
|
|
96
96
|
/* ── floating quick-note widget ────────────────────────────────
|
|
97
97
|
Positioned ABOVE the shutdown launcher FAB (fixed right:24 bottom:24,
|
|
98
|
-
z-index 900, 46px) and BELOW its confirm overlay (z-index 1000).
|
|
98
|
+
z-index 900, 46px) and BELOW its confirm overlay (z-index 1000).
|
|
99
|
+
Interactive overlays (the open card, the native-editor popup) sit ABOVE the
|
|
100
|
+
passive FAB column (sync/status, z-index 950) so those FABs never cover the
|
|
101
|
+
card's own bottom-right buttons. */
|
|
99
102
|
.dsh-tw-note {
|
|
100
|
-
position: fixed; right: 24px; bottom: 88px; z-index:
|
|
103
|
+
position: fixed; right: 24px; bottom: 88px; z-index: 980;
|
|
101
104
|
display: flex; flex-direction: column; align-items: flex-end; gap: 10px;
|
|
102
105
|
font-family: inherit;
|
|
103
106
|
}
|
|
@@ -108,11 +111,18 @@ html[data-dsh-tw-active] .dshDesktopConversationSurface > :not([data-dsh-tw-view
|
|
|
108
111
|
border-radius: 14px; box-shadow: var(--dsw-shadow-lv3, 0 8px 30px rgba(0,0,0,.22));
|
|
109
112
|
padding: 12px; display: flex; flex-direction: column; gap: 10px;
|
|
110
113
|
font-size: 13px;
|
|
114
|
+
backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
|
|
115
|
+
animation: dsh-tw-note-in 180ms ease;
|
|
111
116
|
}
|
|
112
117
|
.dsh-tw-note-card[hidden] { display: none; }
|
|
118
|
+
@keyframes dsh-tw-note-in {
|
|
119
|
+
from { opacity: 0; transform: translateY(8px) scale(.98); }
|
|
120
|
+
to { opacity: 1; transform: translateY(0) scale(1); }
|
|
121
|
+
}
|
|
113
122
|
.dsh-tw-note-head {
|
|
114
123
|
display: flex; align-items: center; gap: 8px;
|
|
115
|
-
font-size: 12px; font-weight: 600;
|
|
124
|
+
font-size: 12px; font-weight: 600; letter-spacing: .2px;
|
|
125
|
+
color: var(--dsw-alias-label-primary, #222);
|
|
116
126
|
}
|
|
117
127
|
.dsh-tw-note-head .dsh-tw-note-label { margin-right: auto; display: flex; align-items: center; gap: 6px; }
|
|
118
128
|
.dsh-tw-note-close {
|
|
@@ -196,23 +206,26 @@ html[data-dsh-tw-active] .dshDesktopConversationSurface > :not([data-dsh-tw-view
|
|
|
196
206
|
border: 1px solid var(--dsw-alias-border-l2, rgba(0,0,0,.18));
|
|
197
207
|
background: var(--dsw-alias-bg-layer-2, #fff); color: var(--dsw-alias-label-primary, #222);
|
|
198
208
|
font: inherit; font-size: 12px; padding: 6px 10px; border-radius: 8px; cursor: pointer;
|
|
199
|
-
transition: filter 120ms ease;
|
|
209
|
+
transition: filter 120ms ease, transform 80ms ease;
|
|
200
210
|
}
|
|
201
211
|
.dsh-tw-note-upload:hover { filter: brightness(.96); }
|
|
212
|
+
.dsh-tw-note-upload:active { transform: scale(.96); }
|
|
202
213
|
.dsh-tw-note-save {
|
|
203
214
|
border: 1px solid transparent; background: var(--dsw-alias-brand-primary, #3e63dd); color: #fff;
|
|
204
215
|
font: inherit; font-size: 12px; padding: 6px 16px; border-radius: 8px; cursor: pointer;
|
|
205
|
-
transition: filter 120ms ease;
|
|
216
|
+
transition: filter 120ms ease, transform 80ms ease;
|
|
206
217
|
}
|
|
207
218
|
.dsh-tw-note-save:hover:not(:disabled) { filter: brightness(1.08); }
|
|
219
|
+
.dsh-tw-note-save:active:not(:disabled) { transform: scale(.96); }
|
|
208
220
|
.dsh-tw-note-save:disabled { opacity: .55; cursor: default; }
|
|
209
221
|
.dsh-tw-note-edit {
|
|
210
222
|
border: 1px solid var(--dsw-alias-border-l2, rgba(0,0,0,.18));
|
|
211
223
|
background: var(--dsw-alias-bg-layer-2, #fff); color: var(--dsw-alias-label-primary, #222);
|
|
212
224
|
font: inherit; font-size: 12px; padding: 6px 10px; border-radius: 8px; cursor: pointer;
|
|
213
|
-
transition: filter 120ms ease;
|
|
225
|
+
transition: filter 120ms ease, transform 80ms ease;
|
|
214
226
|
}
|
|
215
227
|
.dsh-tw-note-edit:hover:not(:disabled) { filter: brightness(.96); }
|
|
228
|
+
.dsh-tw-note-edit:active:not(:disabled) { transform: scale(.96); }
|
|
216
229
|
.dsh-tw-note-edit:disabled { opacity: .55; cursor: default; }
|
|
217
230
|
/* ── Multi-tag chip editor (quick-note tags) ─────────────────────────────── */
|
|
218
231
|
.dsh-tw-note-tags { position: relative; flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
|
|
@@ -250,7 +263,7 @@ html[data-dsh-tw-active] .dshDesktopConversationSurface > :not([data-dsh-tw-view
|
|
|
250
263
|
background: var(--dsw-alias-bg-layer-2, #fff); color: var(--dsw-alias-label-primary, #222);
|
|
251
264
|
border: 1px solid var(--dsw-alias-border-l2, rgba(0,0,0,.2));
|
|
252
265
|
border-radius: 12px; box-shadow: 0 14px 44px rgba(0,0,0,.3);
|
|
253
|
-
z-index:
|
|
266
|
+
z-index: 990; font-family: inherit; font-size: 13px;
|
|
254
267
|
}
|
|
255
268
|
.dsh-tw-editor-bar {
|
|
256
269
|
display: flex; align-items: center; gap: 8px; flex: 0 0 auto;
|
package/src/host/routes.ts
CHANGED
|
@@ -33,6 +33,11 @@ const MAX_PROXY_BODY_BYTES = 16 * 1024 * 1024
|
|
|
33
33
|
/** Max uploaded file body. */
|
|
34
34
|
const MAX_UPLOAD_BYTES = 64 * 1024 * 1024
|
|
35
35
|
|
|
36
|
+
/** Tiddler type for quick-notes: Markdown, so the uploaded images/links and
|
|
37
|
+
* any Markdown in the note actually render in TW (a type-less tiddler is
|
|
38
|
+
* treated as plain wiki text and shows raw `![..]`/`[..]` instead). */
|
|
39
|
+
const NOTE_TYPE = 'text/markdown'
|
|
40
|
+
|
|
36
41
|
/** Structural webserver face (a subset of dsh-host-webserver). */
|
|
37
42
|
export interface WebServerFace {
|
|
38
43
|
register(route: { kind: 'exact' | 'prefix'; path: string; handler: (req: IncomingMessage, res: ServerResponse) => void }): () => void
|
|
@@ -125,10 +130,13 @@ function timestampTitle(date = new Date()): string {
|
|
|
125
130
|
|
|
126
131
|
/**
|
|
127
132
|
* Open a tiddler in TW's NATIVE editor: save the tiddler (when text is
|
|
128
|
-
* non-empty), reuse or create a DRAFT tiddler carrying
|
|
129
|
-
* (TW's story view renders drafts with the
|
|
130
|
-
* `isDraft && editTemplate`), and return the draft
|
|
131
|
-
* navigate the panel iframe to `#<draftTitle>`.
|
|
133
|
+
* non-empty) as Markdown, reuse or create a DRAFT tiddler carrying
|
|
134
|
+
* `draft.of`/`draft.title` (TW's story view renders drafts with the
|
|
135
|
+
* EditTemplate — list.js: `isDraft && editTemplate`), and return the draft
|
|
136
|
+
* title so the client can navigate the panel iframe to `#<draftTitle>`.
|
|
137
|
+
* The draft carries the same `text/markdown` type as the note so saving it in
|
|
138
|
+
* TW keeps Markdown (a draft without a matching type would overwrite the
|
|
139
|
+
* note's type back to plain wiki text).
|
|
132
140
|
*/
|
|
133
141
|
export async function openInTwEditor(
|
|
134
142
|
client: TiddlyWebClient,
|
|
@@ -137,7 +145,7 @@ export async function openInTwEditor(
|
|
|
137
145
|
tags: string[],
|
|
138
146
|
): Promise<{ title: string; draftTitle: string }> {
|
|
139
147
|
if (text.trim().length > 0) {
|
|
140
|
-
await client.put({ title, text, tags })
|
|
148
|
+
await client.put({ title, text, tags, type: NOTE_TYPE })
|
|
141
149
|
}
|
|
142
150
|
// Draft content: the provided text, else the existing tiddler's content.
|
|
143
151
|
let draftText = text
|
|
@@ -159,7 +167,7 @@ export async function openInTwEditor(
|
|
|
159
167
|
/* fall back to a fresh draft */
|
|
160
168
|
}
|
|
161
169
|
if (draftTitle === undefined) draftTitle = `Draft of "${title}" ${Date.now()}`
|
|
162
|
-
await client.put({ title: draftTitle, text: draftText, 'draft.of': title, 'draft.title': title, type:
|
|
170
|
+
await client.put({ title: draftTitle, text: draftText, 'draft.of': title, 'draft.title': title, type: NOTE_TYPE })
|
|
163
171
|
return { title, draftTitle }
|
|
164
172
|
}
|
|
165
173
|
|
|
@@ -206,9 +214,9 @@ export function registerRoutes(ctx: { webServer: WebServerFace }, deps: RouteDep
|
|
|
206
214
|
}
|
|
207
215
|
const title = typeof body.title === 'string' && body.title.trim().length > 0 ? body.title.trim() : timestampTitle()
|
|
208
216
|
const tags = resolveTags(body, deps.noteDefaults().tag)
|
|
209
|
-
await client.put({ title, text, tags })
|
|
217
|
+
await client.put({ title, text, tags, type: NOTE_TYPE })
|
|
210
218
|
deps.autoCommit()
|
|
211
|
-
json(res, { ok: true, title, tag: tags.join(' '), tags, text })
|
|
219
|
+
json(res, { ok: true, title, tag: tags.join(' '), tags, text, type: NOTE_TYPE })
|
|
212
220
|
} catch (err) {
|
|
213
221
|
json(res, { ok: false, error: err instanceof Error ? err.message : String(err) }, 500)
|
|
214
222
|
}
|
package/src/index.ts
CHANGED
|
@@ -152,7 +152,9 @@ const PROMPT_TEXT = `## TiddlyWiki 持久知识库
|
|
|
152
152
|
2. 收工 commit + push:\`tiddlywiki_git_sync action=sync\`(pull → commit → push)。
|
|
153
153
|
3. 插件会自动防抖 commit(默认 60s),手动同步用上面的工具。
|
|
154
154
|
|
|
155
|
-
把 wiki 当作长期记忆与知识沉淀的地方:会议纪要、决策记录、调研笔记、随手的想法都可存成独立 tiddler(tag 建议用 inbox/meeting/decision
|
|
155
|
+
把 wiki 当作长期记忆与知识沉淀的地方:会议纪要、决策记录、调研笔记、随手的想法都可存成独立 tiddler(tag 建议用 inbox/meeting/decision 等便于检索)。
|
|
156
|
+
|
|
157
|
+
用本插件自动创建笔记时,除了业务性 tag 外,请把「当前工作区(项目)的名字」也作为标签之一加上去(例如 \`tiddlywiki_put\` 的 tags 里带上当前 workspace 名),这样笔记能按项目归集、检索。`
|
|
156
158
|
|
|
157
159
|
/**
|
|
158
160
|
* Mount the host half.
|