dsh-manage-session 0.5.7 → 2.0.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.
Files changed (67) hide show
  1. package/CHANGELOG.ja.md +33 -229
  2. package/CHANGELOG.ko.md +33 -229
  3. package/CHANGELOG.md +33 -363
  4. package/INSTALL.ja.md +164 -164
  5. package/INSTALL.ko.md +164 -164
  6. package/INSTALL.md +164 -164
  7. package/INSTALL.zh.md +164 -164
  8. package/LICENSE +21 -21
  9. package/README.en.md +41 -46
  10. package/README.ja.md +33 -57
  11. package/README.ko.md +32 -55
  12. package/README.md +64 -64
  13. package/cordis.patch.yml +19 -16
  14. package/dsh.plugin.json +4 -4
  15. package/lib/client.js +661 -3082
  16. package/lib/index.d.ts +79 -970
  17. package/lib/index.js +249 -2669
  18. package/locale/de.json +2 -2
  19. package/locale/en.json +2 -2
  20. package/locale/es.json +2 -2
  21. package/locale/fr.json +2 -2
  22. package/locale/it.json +2 -2
  23. package/locale/ja.json +2 -2
  24. package/locale/ko.json +2 -2
  25. package/locale/ru.json +2 -2
  26. package/locale/zh.json +2 -2
  27. package/package.json +15 -25
  28. package/screenshots.json +3 -3
  29. package/src/client/bridge-scope.ts +202 -213
  30. package/src/client/card.tsx +154 -154
  31. package/src/client/health-panel.tsx +49 -49
  32. package/src/client/host-api.ts +72 -6
  33. package/src/client/index.ts +594 -503
  34. package/src/client/locales.ts +893 -893
  35. package/src/client/manage-locales.ts +178 -0
  36. package/src/client/{search/manage.tsx → manage.tsx} +430 -404
  37. package/src/client/panel.tsx +131 -129
  38. package/src/client/session-menu-legacy.ts +2 -3
  39. package/src/client/session-menu.tsx +5 -5
  40. package/src/config.ts +43 -99
  41. package/src/host/health/attribution.ts +118 -118
  42. package/src/host/health/lossless.ts +128 -128
  43. package/src/host/health/repair.ts +2 -2
  44. package/src/host/health/source-kind.ts +350 -350
  45. package/src/host/history/archive-source.ts +250 -250
  46. package/src/host/history/archive.ts +249 -249
  47. package/src/host/history/favorites.ts +71 -71
  48. package/src/host/history/purge.ts +370 -370
  49. package/src/host/history/tombstones.ts +3 -3
  50. package/src/host/registry/archive-registry.ts +317 -317
  51. package/src/host/settings-bridge.ts +222 -264
  52. package/src/index.ts +66 -694
  53. package/src/client/search/card.tsx +0 -563
  54. package/src/client/search/host-api.ts +0 -213
  55. package/src/client/search/locales.ts +0 -861
  56. package/src/client/search/locate.ts +0 -330
  57. package/src/client/search/panel.tsx +0 -940
  58. package/src/client/search/platform.ts +0 -136
  59. package/src/host/index/archive-source.ts +0 -90
  60. package/src/host/index/drs-source.ts +0 -211
  61. package/src/host/index/engine.ts +0 -699
  62. package/src/host/index/extract.ts +0 -272
  63. package/src/host/index/peers.ts +0 -62
  64. package/src/host/index/rebuild.ts +0 -432
  65. package/src/host/index/schema.ts +0 -136
  66. package/src/host/index/snapshot.ts +0 -135
  67. package/src/host/index/sync.ts +0 -413
@@ -1,213 +0,0 @@
1
- /**
2
- * Client-side helpers and structural mirrors shared by the search panel and
3
- * the settings card. Everything talks to the host through the fenced
4
- * `/switch-search/api` route; no official package is value-imported.
5
- */
6
-
7
- /** Fetch timeout for one host call (long for import: the body can be large). */
8
- const FETCH_TIMEOUT = 10_000
9
-
10
- /** POST a JSON body to a fenced switch-search API method (items shape). */
11
- export function callHost<T>(method: string, body: unknown): Promise<{ ok: boolean; items: T[]; error?: string }> {
12
- const controller = typeof AbortController === 'undefined' ? undefined : new AbortController()
13
- const timer = controller !== undefined && typeof setTimeout === 'function'
14
- ? setTimeout(() => { controller.abort() }, FETCH_TIMEOUT)
15
- : undefined
16
- return fetch(`/switch-search/api/${method}`, {
17
- method: 'POST',
18
- headers: { 'content-type': 'application/json' },
19
- body: JSON.stringify(body),
20
- signal: controller?.signal,
21
- })
22
- .then((res) => (res.ok ? res.json() : Promise.reject(new Error(`HTTP ${res.status}`))))
23
- .then((data: unknown) => {
24
- const record = data as { ok?: boolean; items?: T[]; error?: string }
25
- if (record && record.ok === true && Array.isArray(record.items)) {
26
- return { ok: true, items: record.items }
27
- }
28
- return { ok: false, items: [], error: record?.error ?? '请求失败' }
29
- })
30
- .catch((err: unknown) => ({
31
- ok: false,
32
- items: [],
33
- error: err instanceof DOMException && err.name === 'AbortError' ? '请求超时' : String(err instanceof Error ? err.message : err),
34
- }))
35
- .finally(() => {
36
- if (timer !== undefined) clearTimeout(timer)
37
- })
38
- }
39
-
40
- /** POST a body to a fenced switch-search API method, returning the whole record. */
41
- export function callHostAny<T>(method: string, body: unknown, timeout = FETCH_TIMEOUT): Promise<Partial<T> & { ok: boolean; error?: string }> {
42
- const controller = typeof AbortController === 'undefined' ? undefined : new AbortController()
43
- const timer = typeof setTimeout === 'function'
44
- ? setTimeout(() => { controller?.abort() }, timeout)
45
- : undefined
46
- return fetch(`/switch-search/api/${method}`, {
47
- method: 'POST',
48
- headers: { 'content-type': 'application/json' },
49
- body: typeof body === 'string' ? body : JSON.stringify(body),
50
- signal: controller?.signal,
51
- })
52
- .then((res) => (res.ok ? res.json() : Promise.reject(new Error(`HTTP ${res.status}`))))
53
- .catch((err: unknown) => ({
54
- ok: false,
55
- error: err instanceof DOMException && err.name === 'AbortError' ? '请求超时' : String(err instanceof Error ? err.message : err),
56
- }))
57
- .finally(() => {
58
- if (timer !== undefined) clearTimeout(timer)
59
- })
60
- }
61
-
62
- /** One session listed for the title-search corpus. */
63
- export interface HostSessionItem {
64
- sessionId: string
65
- title: string
66
- cwd: string
67
- updatedAt: number
68
- /**
69
- * 归档标记(R1 合表语义)。旧宿主半缺省该字段时按 undefined 处理——
70
- * 归档筛选 chip 对 undefined 行按「活跃」对待,与旧数据形状兼容。
71
- */
72
- archived?: boolean
73
- }
74
-
75
- /**
76
- * One content-search hit (session-level: title + strongest snippet).
77
- * `time` belongs to the strongest matching document; `updatedAt` is the
78
- * session-level clock and is what recency ordering keys on. Both ship so the
79
- * panel can re-sort locally without another round-trip.
80
- */
81
- export interface HostContentHit {
82
- sessionId: string
83
- title: string
84
- snippet: string
85
- seq: number
86
- type: string
87
- time: number
88
- updatedAt: number
89
- }
90
-
91
- /** Result ordering accepted by the host `content-search` method. */
92
- export type HostSortMode = 'relevance' | 'time'
93
-
94
- /** Host watermark-sync state (subset used here). */
95
- export interface HostSyncState {
96
- state: string
97
- indexed: number
98
- total: number
99
- updated: number
100
- lastSyncAt: number
101
- failures: { sessionId: string; error: string }[]
102
- }
103
-
104
- /** Host rebuild ("整理") state (subset used here). */
105
- export interface HostRebuildState {
106
- state: string
107
- done: number
108
- total: number
109
- error?: string
110
- }
111
-
112
- /** Host independent-index status (subset used here). */
113
- export interface HostIndexStatus {
114
- ok: boolean
115
- available: boolean
116
- reason?: string
117
- dir?: string
118
- archives?: string[]
119
- archivedSessions?: number
120
- /**
121
- * Resolution state of the peer plugin that owns archiving. Absent on an
122
- * older host half — treated as `unknown`, which renders the neutral hint.
123
- */
124
- steward?: 'installed' | 'missing' | 'unknown'
125
- /**
126
- * 直接删除入口开关(功能①,管家 session-steward.directDelete):true 时
127
- * 面板结果行渲染行内删除按钮。旧宿主半无此字段 = undefined = 不渲染。
128
- */
129
- directDelete?: boolean
130
- sync?: HostSyncState
131
- rebuild?: HostRebuildState
132
- error?: string
133
- }
134
-
135
- /**
136
- * POST to the STEWARD fenced route (`/session-steward/api`) — the batch
137
- * management console (archive / unarchive / purge) rides the steward subdomain,
138
- * per the merged package's route contract (session-* methods stay there).
139
- */
140
- export function callSteward<T>(method: string, body: unknown, timeout = FETCH_TIMEOUT): Promise<Partial<T> & { ok: boolean; error?: string }> {
141
- const controller = typeof AbortController === 'undefined' ? undefined : new AbortController()
142
- const timer = typeof setTimeout === 'function'
143
- ? setTimeout(() => { controller?.abort() }, timeout)
144
- : undefined
145
- return fetch(`/session-steward/api/${method}`, {
146
- method: 'POST',
147
- headers: { 'content-type': 'application/json' },
148
- body: JSON.stringify(body),
149
- signal: controller?.signal,
150
- })
151
- .then((res) => (res.ok ? res.json() : Promise.reject(new Error(`HTTP ${res.status}`))))
152
- .catch((err: unknown) => ({
153
- ok: false,
154
- error: err instanceof DOMException && err.name === 'AbortError' ? '请求超时' : String(err instanceof Error ? err.message : err),
155
- }))
156
- .finally(() => {
157
- if (timer !== undefined) clearTimeout(timer)
158
- })
159
- }
160
-
161
- /** Trigger a browser download of the index snapshot from the host route. */
162
- export async function downloadSnapshot(): Promise<void> {
163
- const res = await fetch('/switch-search/api/index-export', { method: 'POST' })
164
- if (!res.ok) throw new Error(`HTTP ${res.status}`)
165
- const blob = await res.blob()
166
- const url = URL.createObjectURL(blob)
167
- const anchor = document.createElement('a')
168
- anchor.href = url
169
- anchor.download = `switch-search-snapshot-${new Date().toISOString().slice(0, 10)}.jsonl`
170
- anchor.click()
171
- URL.revokeObjectURL(url)
172
- }
173
-
174
- /**
175
- * The client sessions service face. Host lines before 0.1.7 exposed session
176
- * navigation here as `open`; the 0.1.7 contract dropped it ("navigation
177
- * belongs to view owners") — kept only as the legacy fallback of
178
- * `openSessionThrough`.
179
- */
180
- export interface SwitchSessionsService {
181
- open(id: string): void
182
- }
183
-
184
- /**
185
- * The client ui-workspace face: session navigation has been owned by this
186
- * service since host 0.1.7 (`openSession`; `SessionTarget = SessionId |
187
- * SubagentAddress`, so a bare session id is accepted).
188
- */
189
- export interface SwitchUiWorkspaceService {
190
- openSession(target: string): void
191
- }
192
-
193
- /**
194
- * Open a session from a search hit through whichever face the running host
195
- * offers: `uiWorkspace.openSession` first (0.1.7+), the pre-0.1.7
196
- * `sessions.open` as fallback. Neither present → silent no-op: a host line
197
- * this package does not target must not crash the panel.
198
- *
199
- * The service names are resolved through `get` at call time, not captured at
200
- * apply time: this plugin applies before the session-controller / ui-workspace
201
- * client modules in the load order, so an eager lookup captures `undefined`
202
- * and every result click silently no-ops. Both are root-context singletons,
203
- * so by the time a user clicks a hit they are always mounted.
204
- */
205
- export function openSessionThrough(get: (name: string) => unknown, sessionId: string): void {
206
- const uiWorkspace = get('uiWorkspace') as SwitchUiWorkspaceService | undefined
207
- if (uiWorkspace !== undefined && typeof uiWorkspace.openSession === 'function') {
208
- uiWorkspace.openSession(sessionId)
209
- return
210
- }
211
- const sessions = get('sessions') as SwitchSessionsService | undefined
212
- if (sessions !== undefined && typeof sessions.open === 'function') sessions.open(sessionId)
213
- }