@cubeai/dsh-feishu-channels 0.0.0-stage → 0.2.0
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 +201 -0
- package/NOTICE +15 -0
- package/README.md +56 -2
- package/client.js +4189 -0
- package/cordis.patch.yml +4 -0
- package/docs/coexistence.md +112 -0
- package/docs/dsh-feishu-channels-plan.md +1406 -0
- package/docs/ui-revamp-plan.md +263 -0
- package/docs/verification.md +120 -0
- package/icon.svg +17 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +76 -4
- package/src/channels/connection-state.js +12 -0
- package/src/channels/diagnostics.js +77 -0
- package/src/channels/factory.js +20 -0
- package/src/channels/feishu-app.js +267 -0
- package/src/channels/feishu.js +399 -0
- package/src/channels/media.js +9 -0
- package/src/channels/meta.js +24 -0
- package/src/channels/qr/feishu.js +84 -0
- package/src/channels/qr/hub.js +229 -0
- package/src/channels/qr/render.js +8 -0
- package/src/channels/qr/shared.js +50 -0
- package/src/engine/abort.js +35 -0
- package/src/engine/access.js +23 -0
- package/src/engine/agent-options.js +19 -0
- package/src/engine/approval.js +70 -0
- package/src/engine/assistant-settings.js +38 -0
- package/src/engine/assistant-text.js +11 -0
- package/src/engine/atomic-file.js +45 -0
- package/src/engine/chat-commands.js +752 -0
- package/src/engine/choice-delivery.js +20 -0
- package/src/engine/choices.js +103 -0
- package/src/engine/command-locale.js +70 -0
- package/src/engine/command-messages.js +434 -0
- package/src/engine/command-permissions.js +38 -0
- package/src/engine/command-replies.js +59 -0
- package/src/engine/credentials.js +54 -0
- package/src/engine/deferred-delivery.js +260 -0
- package/src/engine/delivery-history.js +39 -0
- package/src/engine/file-delivery.js +215 -0
- package/src/engine/file-input.js +52 -0
- package/src/engine/file-log.js +25 -0
- package/src/engine/gateway.js +1337 -0
- package/src/engine/image-input.js +31 -0
- package/src/engine/json-state.js +25 -0
- package/src/engine/keyed-queue.js +20 -0
- package/src/engine/merge.js +56 -0
- package/src/engine/message-progress.js +274 -0
- package/src/engine/question.js +201 -0
- package/src/engine/quiet-logger.js +25 -0
- package/src/engine/reply-stream.js +86 -0
- package/src/engine/router.js +713 -0
- package/src/engine/secure-file.js +8 -0
- package/src/engine/seen-store.js +43 -0
- package/src/engine/session-export.js +64 -0
- package/src/engine/session-history.js +30 -0
- package/src/engine/session-id.js +62 -0
- package/src/engine/session-store.js +109 -0
- package/src/engine/session-title.js +29 -0
- package/src/engine/split.js +291 -0
- package/src/engine/workspace-path.js +9 -0
- package/src/index.js +62 -0
- package/src/manager.js +1325 -0
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# Sidebar coexistence with dsh-im-connect
|
|
2
|
+
|
|
3
|
+
This document is the maintenance contract for the shared "任务 | 频道 | 飞书频道" tab bar.
|
|
4
|
+
|
|
5
|
+
## Why a contract is needed
|
|
6
|
+
|
|
7
|
+
DSH has no official sidebar-tab slot. `sidebar.workspaces` is a single slot owned by
|
|
8
|
+
`@deepseek-ai/dsh-client-ui-workspace`. `dsh-im-connect` wraps that component and
|
|
9
|
+
attaches a private **Registry v1** (`component.__dshNativeTabs`). Other plugins can insert
|
|
10
|
+
tabs into that registry without modifying `dsh-im-connect`.
|
|
11
|
+
|
|
12
|
+
`@cubeai/dsh-feishu-channels` implements the same registry contract. Either plugin may be
|
|
13
|
+
the wrapper ("host"); the other one inserts its tab.
|
|
14
|
+
|
|
15
|
+
## Registry v1
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
interface SidebarTabRegistryV1 {
|
|
19
|
+
version: 1
|
|
20
|
+
officialTree: React.ComponentType<any>
|
|
21
|
+
sessionFilters: Array<(sessionId: string) => boolean>
|
|
22
|
+
sessionOpeners: Array<{ id: string, order?: number, matchSession(id: string): boolean, open(id: string, hostOpen?: (id: string) => void): void }>
|
|
23
|
+
getTabs(): Tab[]
|
|
24
|
+
getRevision(): number
|
|
25
|
+
subscribe(listener: () => void): () => void
|
|
26
|
+
insert(tab: Tab): () => void
|
|
27
|
+
addSessionFilter(filter: (id: string) => boolean): () => void
|
|
28
|
+
addSessionOpener(opener: SessionOpener): () => void
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Discovery rules (compatible with `dsh-im-connect@1.0.12`):
|
|
33
|
+
|
|
34
|
+
1. Read `sidebar.workspaces` occupants.
|
|
35
|
+
2. If `occupant.component.__dshNativeTabs` is a valid v1 registry, insert a tab; do not wrap.
|
|
36
|
+
3. Else if the component is already wrapped by an unknown host, leave it untouched.
|
|
37
|
+
4. Else wrap the official component and attach a registry to the wrapper function.
|
|
38
|
+
|
|
39
|
+
Wrapper markers:
|
|
40
|
+
|
|
41
|
+
- `__dshNativeTabHost = true`
|
|
42
|
+
- `__dshNativeTabWrapped = true`
|
|
43
|
+
- `__dshNativeTabOriginal = originalComponent`
|
|
44
|
+
- `__dshNativeTabOwner = 'im-connect' | 'feishu-channel'`
|
|
45
|
+
- `__dfcTabHost = true` (new plugin only)
|
|
46
|
+
|
|
47
|
+
Coordination event: `window.dispatchEvent(new Event('dsh-native-sidebar-change'))`.
|
|
48
|
+
|
|
49
|
+
## Tabs
|
|
50
|
+
|
|
51
|
+
| Plugin | id | order | Label |
|
|
52
|
+
|---|---|---:|---|
|
|
53
|
+
| dsh-im-connect | `channels` | 20 | 频道 / Channels |
|
|
54
|
+
| dsh-feishu-channels | `feishu` | 30 | 飞书频道 / Feishu |
|
|
55
|
+
|
|
56
|
+
Tasks is the fixed first tab. Sorted result:
|
|
57
|
+
|
|
58
|
+
```text
|
|
59
|
+
任务 | 频道 | 飞书频道
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
When only one plugin is installed, the other tab is absent.
|
|
63
|
+
|
|
64
|
+
## Session visibility
|
|
65
|
+
|
|
66
|
+
- Feishu sessions use `dfc:`; im-connect sessions use `im:`.
|
|
67
|
+
- Each plugin adds a session filter to the shared registry so its own sessions do not appear
|
|
68
|
+
in the Tasks tree.
|
|
69
|
+
- A session id never matches both prefixes.
|
|
70
|
+
- Do not share `sessions.json`, `channels.json`, credentials, or state directories.
|
|
71
|
+
|
|
72
|
+
## Lifecycle
|
|
73
|
+
|
|
74
|
+
| Event | Behavior |
|
|
75
|
+
|---|---|
|
|
76
|
+
| New plugin loads after im-connect | Insert `feishu` into im-connect's registry |
|
|
77
|
+
| im-connect loads after new plugin | im-connect detects the new registry and inserts `channels` |
|
|
78
|
+
| New plugin unloads, im-connect remains | Remove own tab/filter; if own wrapper, restore official component and dispatch change event; im-connect re-wraps |
|
|
79
|
+
| im-connect unloads, new plugin remains | im-connect removes its tab/restores; new plugin re-wraps on change event |
|
|
80
|
+
| Both disabled | Official sidebar |
|
|
81
|
+
| Page refresh | Deterministic re-evaluation from the bundle order |
|
|
82
|
+
|
|
83
|
+
All disposers must be idempotent and remove only their own tab/filter/opener.
|
|
84
|
+
|
|
85
|
+
## Known limitations
|
|
86
|
+
|
|
87
|
+
- Registry v1 is a private convention, not a DSH public API. A future im-connect release may
|
|
88
|
+
change it; the new plugin degrades to the official sidebar rather than fighting it.
|
|
89
|
+
- Codex UI sidebars (`sidebar.channels`) are not wrapped by v1.
|
|
90
|
+
- Two plugins must not use the same Feishu App ID at the same time; Feishu long-connection
|
|
91
|
+
events are delivered to one connection.
|
|
92
|
+
- **Uninstall order:** because both plugins share the single `sidebar.workspaces` slot and
|
|
93
|
+
one wraps the other, uninstalling `dsh-im-connect` while the new plugin is active can be
|
|
94
|
+
rejected by DSH's `bundle-in-use` guard. Disable `@cubeai/dsh-feishu-channels` first, then
|
|
95
|
+
uninstall `dsh-im-connect`; the new plugin can be re-enabled afterwards (it falls back to
|
|
96
|
+
the official sidebar and shows `任务 | 飞书频道`). This is a UI-wrapper/runtime coupling,
|
|
97
|
+
not an npm dependency: neither package imports the other, and their Host state, APIs,
|
|
98
|
+
credentials, and sessions are separate.
|
|
99
|
+
|
|
100
|
+
## Verification matrix
|
|
101
|
+
|
|
102
|
+
| Scenario | Expected |
|
|
103
|
+
|---|---|
|
|
104
|
+
| new plugin only | 任务 \| 飞书频道 |
|
|
105
|
+
| im-connect only | 任务 \| 频道 |
|
|
106
|
+
| im-connect first, new plugin second | 任务 \| 频道 \| 飞书频道 |
|
|
107
|
+
| new plugin first, im-connect second | 任务 \| 频道 \| 飞书频道 |
|
|
108
|
+
| disable new plugin | 任务 \| 频道 |
|
|
109
|
+
| disable im-connect | 任务 \| 飞书频道 |
|
|
110
|
+
| uninstall either | Disable the other plugin first if DSH reports `bundle-in-use`; then uninstall, then re-enable |
|
|
111
|
+
| refresh | Same as before refresh |
|
|
112
|
+
| reload client | No duplicate tabs |
|