@krischoichoi/channel-control 0.6.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.
Files changed (82) hide show
  1. package/README.md +67 -0
  2. package/lib/access/conversation-directory-store.d.ts +73 -0
  3. package/lib/access/conversation-directory-store.d.ts.map +1 -0
  4. package/lib/access/conversation-directory-store.js +66 -0
  5. package/lib/access/conversation-directory-store.js.map +1 -0
  6. package/lib/access/conversation-directory.d.ts +51 -0
  7. package/lib/access/conversation-directory.d.ts.map +1 -0
  8. package/lib/access/conversation-directory.js +118 -0
  9. package/lib/access/conversation-directory.js.map +1 -0
  10. package/lib/access/manager.d.ts +47 -0
  11. package/lib/access/manager.d.ts.map +1 -0
  12. package/lib/access/manager.js +124 -0
  13. package/lib/access/manager.js.map +1 -0
  14. package/lib/access/materialize.d.ts +33 -0
  15. package/lib/access/materialize.d.ts.map +1 -0
  16. package/lib/access/materialize.js +67 -0
  17. package/lib/access/materialize.js.map +1 -0
  18. package/lib/access/owner-claim.d.ts +91 -0
  19. package/lib/access/owner-claim.d.ts.map +1 -0
  20. package/lib/access/owner-claim.js +200 -0
  21. package/lib/access/owner-claim.js.map +1 -0
  22. package/lib/access/policy-store.d.ts +55 -0
  23. package/lib/access/policy-store.d.ts.map +1 -0
  24. package/lib/access/policy-store.js +88 -0
  25. package/lib/access/policy-store.js.map +1 -0
  26. package/lib/access/validation.d.ts +29 -0
  27. package/lib/access/validation.d.ts.map +1 -0
  28. package/lib/access/validation.js +89 -0
  29. package/lib/access/validation.js.map +1 -0
  30. package/lib/auth/sanitizer.d.ts +35 -0
  31. package/lib/auth/sanitizer.d.ts.map +1 -0
  32. package/lib/auth/sanitizer.js +52 -0
  33. package/lib/auth/sanitizer.js.map +1 -0
  34. package/lib/auth/session-manager.d.ts +38 -0
  35. package/lib/auth/session-manager.d.ts.map +1 -0
  36. package/lib/auth/session-manager.js +219 -0
  37. package/lib/auth/session-manager.js.map +1 -0
  38. package/lib/config.d.ts +20 -0
  39. package/lib/config.d.ts.map +1 -0
  40. package/lib/config.js +15 -0
  41. package/lib/config.js.map +1 -0
  42. package/lib/credentials/manager.d.ts +44 -0
  43. package/lib/credentials/manager.d.ts.map +1 -0
  44. package/lib/credentials/manager.js +24 -0
  45. package/lib/credentials/manager.js.map +1 -0
  46. package/lib/definitions/registry.d.ts +24 -0
  47. package/lib/definitions/registry.d.ts.map +1 -0
  48. package/lib/definitions/registry.js +59 -0
  49. package/lib/definitions/registry.js.map +1 -0
  50. package/lib/errors.d.ts +20 -0
  51. package/lib/errors.d.ts.map +1 -0
  52. package/lib/errors.js +45 -0
  53. package/lib/errors.js.map +1 -0
  54. package/lib/index.d.ts +31 -0
  55. package/lib/index.d.ts.map +1 -0
  56. package/lib/index.js +31 -0
  57. package/lib/index.js.map +1 -0
  58. package/lib/plugin.d.ts +20 -0
  59. package/lib/plugin.d.ts.map +1 -0
  60. package/lib/plugin.js +81 -0
  61. package/lib/plugin.js.map +1 -0
  62. package/lib/runtime/manager.d.ts +73 -0
  63. package/lib/runtime/manager.d.ts.map +1 -0
  64. package/lib/runtime/manager.js +277 -0
  65. package/lib/runtime/manager.js.map +1 -0
  66. package/lib/runtime/mount-handle.d.ts +11 -0
  67. package/lib/runtime/mount-handle.d.ts.map +1 -0
  68. package/lib/runtime/mount-handle.js +2 -0
  69. package/lib/runtime/mount-handle.js.map +1 -0
  70. package/lib/service.d.ts +180 -0
  71. package/lib/service.d.ts.map +1 -0
  72. package/lib/service.js +432 -0
  73. package/lib/service.js.map +1 -0
  74. package/lib/types.d.ts +370 -0
  75. package/lib/types.d.ts.map +1 -0
  76. package/lib/types.js +2 -0
  77. package/lib/types.js.map +1 -0
  78. package/lib/update-check.d.ts +128 -0
  79. package/lib/update-check.d.ts.map +1 -0
  80. package/lib/update-check.js +380 -0
  81. package/lib/update-check.js.map +1 -0
  82. package/package.json +47 -0
@@ -0,0 +1,277 @@
1
+ import { ChannelDefinitionRegistry } from '../definitions/registry.js';
2
+ const DEFAULT_ACCOUNT = 'main';
3
+ export class ChannelRuntimeManager {
4
+ mounts = new Map();
5
+ errors = new Map();
6
+ ctx;
7
+ registry;
8
+ credentials;
9
+ constructor(options) {
10
+ this.ctx = options.ctx;
11
+ this.registry = options.registry;
12
+ this.credentials = options.credentials;
13
+ }
14
+ key(channelId, accountId) {
15
+ return `${channelId}:${accountId ?? DEFAULT_ACCOUNT}`;
16
+ }
17
+ async start(channelId, accountId) {
18
+ const key = this.key(channelId, accountId);
19
+ const existing = this.mounts.get(key);
20
+ if (existing) {
21
+ await existing.handle.dispose();
22
+ this.mounts.delete(key);
23
+ }
24
+ const definition = this.registry.require(channelId);
25
+ const adapter = await definition.createAdapter();
26
+ try {
27
+ const { handle, settled } = this.mountTransactional(channelId, adapter);
28
+ await settled;
29
+ this.mounts.set(key, { handle, adapter });
30
+ this.errors.delete(key);
31
+ }
32
+ catch (error) {
33
+ // mountTransactional + core rollback already unregistered; record the
34
+ // error so status() can surface it. A partial mount is never stored.
35
+ this.errors.set(key, error instanceof Error ? error.message : String(error));
36
+ throw error;
37
+ }
38
+ }
39
+ async stop(channelId, accountId) {
40
+ const key = this.key(channelId, accountId);
41
+ const record = this.mounts.get(key);
42
+ if (!record) {
43
+ this.errors.delete(key);
44
+ return;
45
+ }
46
+ this.mounts.delete(key);
47
+ await record.handle.dispose();
48
+ this.errors.delete(key);
49
+ }
50
+ async restart(channelId, accountId, rollback) {
51
+ const key = this.key(channelId, accountId);
52
+ const existing = this.mounts.get(key);
53
+ const definition = this.registry.require(channelId);
54
+ let candidate;
55
+ try {
56
+ // Resolve credentials/build before touching the active connection.
57
+ candidate = await definition.createAdapter();
58
+ }
59
+ catch (error) {
60
+ try {
61
+ await rollback?.();
62
+ }
63
+ catch (recoveryError) {
64
+ this.errors.set(key, recoveryError instanceof Error ? recoveryError.message : String(recoveryError));
65
+ }
66
+ throw error;
67
+ }
68
+ if (existing) {
69
+ await existing.handle.dispose();
70
+ this.mounts.delete(key);
71
+ }
72
+ try {
73
+ await this.mount(key, channelId, candidate);
74
+ this.errors.delete(key);
75
+ }
76
+ catch (error) {
77
+ try {
78
+ // Restore setup before restarting the old instance: adapters retain a
79
+ // reference to their definition's mutable config snapshot.
80
+ await rollback?.();
81
+ if (existing)
82
+ await this.mount(key, channelId, existing.adapter);
83
+ }
84
+ catch (recoveryError) {
85
+ this.errors.set(key, recoveryError instanceof Error ? recoveryError.message : String(recoveryError));
86
+ }
87
+ throw error;
88
+ }
89
+ }
90
+ async status(channelId, accountId) {
91
+ const key = this.key(channelId, accountId);
92
+ const record = this.mounts.get(key);
93
+ const lastError = this.errors.get(key) ?? null;
94
+ if (!record) {
95
+ return {
96
+ mounted: false,
97
+ running: false,
98
+ connection: 'unknown',
99
+ health: null,
100
+ lastError,
101
+ };
102
+ }
103
+ let health = null;
104
+ if (record.adapter.getHealth) {
105
+ try {
106
+ health = (await record.adapter.getHealth()) ?? null;
107
+ }
108
+ catch {
109
+ health = null;
110
+ }
111
+ }
112
+ const connection = health?.connection === 'connected'
113
+ ? 'connected'
114
+ : health?.connection === 'disconnected'
115
+ ? 'disconnected'
116
+ : health?.status === 'down'
117
+ ? 'disconnected'
118
+ : health?.status === 'degraded'
119
+ ? 'degraded'
120
+ : 'unknown';
121
+ return {
122
+ mounted: true,
123
+ running: true,
124
+ connection,
125
+ health,
126
+ lastError,
127
+ };
128
+ }
129
+ isRunning(channelId, accountId) {
130
+ return this.mounts.has(this.key(channelId, accountId));
131
+ }
132
+ /**
133
+ * The currently mounted adapter for a channel (doc §43: the Weixin
134
+ * definition delegates beginAuth/pollAuth/submitAuthInput to the mounted
135
+ * adapter so the M1 auth flow itself is unchanged). Returns undefined when
136
+ * not mounted.
137
+ */
138
+ adapter(channelId, accountId) {
139
+ return this.mounts.get(this.key(channelId, accountId))?.adapter;
140
+ }
141
+ /**
142
+ * Auto-start ONE definition when it is registered (doc §27). Skips
143
+ * silently when autoStart is false or the channel is not configured; a
144
+ * failing start is logged and never thrown (registration must not crash
145
+ * the profile). Returns true when mounted.
146
+ */
147
+ async autoStartOne(channelId) {
148
+ const definition = this.registry.get(channelId);
149
+ if (!definition || !definition.enabled || definition.autoStart === false)
150
+ return false;
151
+ const logger = this.ctx.logger('channel-control');
152
+ try {
153
+ const configured = (await definition.getConfiguredState()).configured;
154
+ if (!configured) {
155
+ logger.info('[channel-control] \'' + channelId + '\' not configured; skipping autoStart');
156
+ return false;
157
+ }
158
+ await this.start(channelId);
159
+ logger.info('[channel-control] \'' + channelId + '\' auto-started');
160
+ return true;
161
+ }
162
+ catch (error) {
163
+ logger.error('[channel-control] \'' + channelId + '\' failed to auto-start', error);
164
+ return false;
165
+ }
166
+ }
167
+ /**
168
+ * Mount every enabled+configured registered definition (doc §25, §27).
169
+ * Unconfigured channels are skipped silently. A failing start is logged and
170
+ * never propagates, so an unconfigured/broken channel cannot crash the
171
+ * profile. Returns { started, skipped } counts.
172
+ */
173
+ async autoStartAll() {
174
+ let started = 0;
175
+ let skipped = 0;
176
+ let failed = 0;
177
+ const logger = this.ctx.logger('channel-control');
178
+ for (const definition of this.registry.list()) {
179
+ if (!definition.enabled || definition.autoStart === false) {
180
+ skipped += 1;
181
+ continue;
182
+ }
183
+ let configured = false;
184
+ try {
185
+ configured = (await definition.getConfiguredState()).configured;
186
+ }
187
+ catch (error) {
188
+ // A definition that cannot even describe its state must not crash the
189
+ // profile; treat it as skipped and log.
190
+ skipped += 1;
191
+ logger.warn(`[channel-control] definition '${definition.id}' could not report configured state; skipping autoStart`, error);
192
+ continue;
193
+ }
194
+ if (!configured) {
195
+ skipped += 1;
196
+ logger.info(`[channel-control] '${definition.id}' not configured; skipping autoStart`);
197
+ continue;
198
+ }
199
+ try {
200
+ await this.start(definition.id);
201
+ started += 1;
202
+ logger.info(`[channel-control] '${definition.id}' auto-started`);
203
+ }
204
+ catch (error) {
205
+ failed += 1;
206
+ logger.error(`[channel-control] '${definition.id}' failed to auto-start`, error);
207
+ }
208
+ }
209
+ return { started, skipped, failed };
210
+ }
211
+ /** Dispose and forget every mounted adapter. */
212
+ async stopAll() {
213
+ const keys = [...this.mounts.keys()];
214
+ for (const key of keys) {
215
+ const sep = key.indexOf(':');
216
+ const channelId = sep >= 0 ? key.slice(0, sep) : key;
217
+ const rawAccount = sep >= 0 ? key.slice(sep + 1) : undefined;
218
+ const accountId = rawAccount === DEFAULT_ACCOUNT ? undefined : rawAccount;
219
+ await this.stop(channelId, accountId);
220
+ }
221
+ }
222
+ mountTransactional(channelId, adapter) {
223
+ const createContext = (signal) => this.ctx.channels.createAdapterContext({ channelId, signal });
224
+ // Mirror channel-core's transactional mount on a Cordis effect so we can
225
+ // await startup and capture start errors, while still returning a
226
+ // ChannelMountHandle-shaped disposer stored in the mounts Map.
227
+ let resolveSettled;
228
+ let rejectSettled;
229
+ const settled = new Promise((resolve, reject) => {
230
+ resolveSettled = resolve;
231
+ rejectSettled = reject;
232
+ });
233
+ const dispose = this.ctx.effect(async () => {
234
+ const abort = new AbortController();
235
+ const unregister = this.ctx.channels.register(adapter);
236
+ try {
237
+ await adapter.start(createContext(abort.signal));
238
+ resolveSettled();
239
+ }
240
+ catch (error) {
241
+ abort.abort();
242
+ try {
243
+ await adapter.stop();
244
+ }
245
+ catch {
246
+ // Best-effort rollback of network resources.
247
+ }
248
+ unregister();
249
+ rejectSettled(error);
250
+ throw error;
251
+ }
252
+ return async () => {
253
+ abort.abort();
254
+ try {
255
+ await adapter.stop();
256
+ }
257
+ finally {
258
+ unregister();
259
+ }
260
+ };
261
+ });
262
+ const handle = { dispose: () => dispose() };
263
+ return { handle, settled };
264
+ }
265
+ async mount(key, channelId, adapter) {
266
+ try {
267
+ const { handle, settled } = this.mountTransactional(channelId, adapter);
268
+ await settled;
269
+ this.mounts.set(key, { handle, adapter });
270
+ }
271
+ catch (error) {
272
+ this.errors.set(key, error instanceof Error ? error.message : String(error));
273
+ throw error;
274
+ }
275
+ }
276
+ }
277
+ //# sourceMappingURL=manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/runtime/manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Re-export of the core [ChannelMountHandle] disposer.
3
+ *
4
+ * The type itself lives in @krischoichoi/channel-core (returned by
5
+ * mountChannelAdapter); this module keeps the plan's runtime/ directory shape
6
+ * (doc §12, §22) while re-exporting the canonical type. channel-control never
7
+ * re-implements lifecycle: it stores these handles in a Map keyed by
8
+ * channelId:accountId and calls dispose() on demand.
9
+ */
10
+ export type { ChannelMountHandle } from '@krischoichoi/channel-core';
11
+ //# sourceMappingURL=mount-handle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mount-handle.d.ts","sourceRoot":"","sources":["../../src/runtime/mount-handle.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=mount-handle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mount-handle.js","sourceRoot":"","sources":["../../src/runtime/mount-handle.ts"],"names":[],"mappings":""}
@@ -0,0 +1,180 @@
1
+ /**
2
+ * [ChannelControlService] — the universal Channel Control Plane mounted at
3
+ * ctx.channelControl (doc §12–§13, §33, §46).
4
+ *
5
+ * Owns the four sub-managers that later waves wire into:
6
+ * - definition registry (registration order)
7
+ * - credential access (thin wrappers over the injected structural seam)
8
+ * - interactive auth session lifecycle (AuthSessionManager)
9
+ * - runtime mount lifecycle (ChannelRuntimeManager)
10
+ *
11
+ * It is deliberately adapter-agnostic: every channel is driven through its
12
+ * [ChannelDefinition], never through a per-channel conditional.
13
+ *
14
+ * The credentials seam is structural ([CredentialSeam]) and injected, so this
15
+ * package carries no dependency on any concrete credentials implementation.
16
+ */
17
+ import { Service, type Context } from '@deepseek-ai/cordis';
18
+ import type { ChannelAccessPolicy, ChannelAdapter, ChannelEvent, ChannelStorage } from '@krischoichoi/channel-core';
19
+ import { ChannelDefinitionRegistry } from './definitions/registry.js';
20
+ import { CredentialManager, type CredentialSeam } from './credentials/manager.js';
21
+ import { AuthSessionManager } from './auth/session-manager.js';
22
+ import { ControlError } from './errors.js';
23
+ import { ChannelRuntimeManager } from './runtime/manager.js';
24
+ import { ChannelAccessManager } from './access/manager.js';
25
+ import { OwnerClaimSessionManager } from './access/owner-claim.js';
26
+ import { ConversationDirectory } from './access/conversation-directory.js';
27
+ import { type ConversationDirectoryStore } from './access/conversation-directory-store.js';
28
+ import { BundleUpdateChecker, type BundleUpdateStatus } from './update-check.js';
29
+ import { type ChannelAccessPolicyStore } from './access/policy-store.js';
30
+ import type { AuthBeginInput, AuthInput, ChannelAccessState, ChannelDefinition, ChannelSetupDescriptor, ChannelSetupInput, ChannelSetupResult, ChannelSummary, ConfiguredState, InternalAuthSession, PublicConversationIdentity, PublicOwnerClaimSession } from './types.js';
31
+ declare module '@deepseek-ai/cordis' {
32
+ interface Context {
33
+ channelControl: ChannelControlService;
34
+ }
35
+ }
36
+ export interface ChannelControlServiceOptions {
37
+ /** Optional registry; created fresh when omitted. */
38
+ registry?: ChannelDefinitionRegistry;
39
+ /** The injected credentials seam (structural). */
40
+ credentials: CredentialSeam;
41
+ /** Injectable clock for auth (ms since epoch). Defaults to Date.now. */
42
+ now?: () => number;
43
+ /**
44
+ * Optional access-policy store. Defaults to an in-memory store; the plugin
45
+ * wires the durable ChannelStorage-backed store over ctx.channels.resources.
46
+ */
47
+ accessStore?: ChannelAccessPolicyStore;
48
+ /**
49
+ * Optional conversation-identity directory store. Defaults to an in-memory
50
+ * store; the plugin wires the durable ChannelStorage-backed store over
51
+ * ctx.channels.resources.
52
+ */
53
+ conversationStore?: ConversationDirectoryStore;
54
+ /**
55
+ * Optional owner-identity resolver. Defaults to delegating to the registered
56
+ * definition's `resolveOwnerIdentity(accountId)` when present.
57
+ */
58
+ resolveOwnerIdentity?(channelId: string, accountId: string): Promise<string | undefined>;
59
+ /**
60
+ * Prompt-only bundle update check (npm dist-tags of @krischoichoi/dsh-channels).
61
+ * Defaults: enabled, 24h TTL, memory-only cache (the plugin wires the shared
62
+ * durable ChannelStorage).
63
+ */
64
+ updateCheck?: {
65
+ /** Installed bundle version; defaults to this package's lockstep version. */
66
+ currentVersion?: string;
67
+ enabled?: boolean;
68
+ intervalHours?: number;
69
+ storage?: () => ChannelStorage | undefined;
70
+ };
71
+ }
72
+ export declare class ChannelControlService extends Service {
73
+ readonly definitions: ChannelDefinitionRegistry;
74
+ readonly credentials: CredentialManager;
75
+ readonly auth: AuthSessionManager;
76
+ readonly runtime: ChannelRuntimeManager;
77
+ readonly access: ChannelAccessManager;
78
+ readonly ownerClaims: OwnerClaimSessionManager;
79
+ /** Human identifier ↔ canonical conversation id mapping (display only). */
80
+ readonly conversations: ConversationDirectory;
81
+ /** Prompt-only bundle update check (never installs anything). */
82
+ readonly updates: BundleUpdateChecker;
83
+ constructor(ctx: Context, options: ChannelControlServiceOptions);
84
+ /** Registry + runtime + configured state merged into per-channel rows. */
85
+ listChannels(): Promise<ChannelSummary[]>;
86
+ /** One merged row for a single registered channel, or a stable ChannelError. */
87
+ getChannel(channelId: string): Promise<ChannelSummary>;
88
+ /**
89
+ * Enable / disable a channel (doc §22, §25). Disabling persists the intent
90
+ * and stops the runtime; enabling persists the intent and — when the channel
91
+ * is configured — starts the runtime. Returns the latest merged summary.
92
+ */
93
+ setEnabled(channelId: string, enabled: boolean): Promise<ChannelSummary>;
94
+ /** Merge one definition's registry + runtime + configured state into a row. */
95
+ private summarize;
96
+ /** Access readiness for a channel, guarded so failures default safely. */
97
+ private accessReadiness;
98
+ getSetup(channelId: string): Promise<ChannelSetupDescriptor>;
99
+ getConfiguredState(channelId: string): Promise<ConfiguredState>;
100
+ /**
101
+ * Persist a non-secret config patch for a channel. Secret fields (names
102
+ * ending in Secret/secret/Token/token, or declared kind:'secret' in the
103
+ * setup descriptor) are rejected — secret values go only through
104
+ * credentials.set (doc §30–§31).
105
+ */
106
+ saveConfig(channelId: string, patch: Record<string, unknown>): Promise<void>;
107
+ /**
108
+ * Describe one credential field of a channel by its setup field name
109
+ * (doc §31). Resolves the field's credential ref from the setup descriptor
110
+ * and describes it via ctx.credentials — the value is never returned.
111
+ */
112
+ describeCredential(channelId: string, fieldName: string): Promise<{
113
+ configured: boolean;
114
+ writable: boolean;
115
+ source?: string;
116
+ }>;
117
+ /**
118
+ * Save one credential field of a channel by its setup field name (doc §31).
119
+ * The web layer sends only { field, value }; the control plane maps the
120
+ * field to its credential ref and calls ctx.credentials.set. The value is
121
+ * never echoed back.
122
+ */
123
+ saveCredential(channelId: string, fieldName: string, value: string): Promise<{
124
+ configured: boolean;
125
+ writable: boolean;
126
+ }>;
127
+ /**
128
+ * Save a complete setup form and make it effective immediately. The Web
129
+ * sends one user action; secret and non-secret fields still cross their
130
+ * dedicated storage seams on the host.
131
+ */
132
+ applySetup(channelId: string, input: ChannelSetupInput): Promise<ChannelSetupResult>;
133
+ /** Resolve a setup field of a channel or raise a stable error. */
134
+ private credentialField;
135
+ beginAuth(channelId: string, input: AuthBeginInput): Promise<import("./types.js").PublicAuthSession>;
136
+ pollAuth(sessionId: string): Promise<import("./types.js").PublicAuthStatus>;
137
+ submitAuthInput(sessionId: string, input: AuthInput): Promise<import("./types.js").PublicAuthStatus>;
138
+ cancelAuth(sessionId: string): Promise<void>;
139
+ /** Access state for a channel+account. */
140
+ getAccess(channelId: string, accountId?: string): Promise<ChannelAccessState>;
141
+ /** Validate + persist an access policy, returning the resulting state. */
142
+ saveAccess(channelId: string, policy: ChannelAccessPolicy, accountId?: string): Promise<ChannelAccessState>;
143
+ /** Begin a local owner-claim session. */
144
+ beginOwnerClaim(channelId: string, accountId?: string): PublicOwnerClaimSession;
145
+ /** Read an owner-claim session (throws CLAIM_EXPIRED / CLAIM_NOT_FOUND). */
146
+ getOwnerClaim(channelId: string, claimId: string): PublicOwnerClaimSession;
147
+ /**
148
+ * Confirm a candidate and persist the owner, then return the resulting
149
+ * access state for the channel+account.
150
+ */
151
+ confirmOwnerClaim(channelId: string, claimId: string): Promise<ChannelAccessState>;
152
+ /** Cancel an owner-claim session. */
153
+ cancelOwnerClaim(channelId: string, claimId: string): void;
154
+ /**
155
+ * Observed conversation identities for a channel+account, most recently seen
156
+ * first. Display/mapping metadata only — never authorization state.
157
+ */
158
+ listConversations(channelId: string, accountId?: string): Promise<PublicConversationIdentity[]>;
159
+ /**
160
+ * Resolve an optional human-facing identifier to its observed canonical
161
+ * identity. QQ's group selector uses the discovered canonical OpenID list
162
+ * directly and does not call this compatibility path.
163
+ */
164
+ findConversation(channelId: string, externalId: string, accountId?: string): Promise<PublicConversationIdentity | undefined>;
165
+ /**
166
+ * Observe a canonical event in the conversation directory under the active
167
+ * provider/application scope declared by its definition. The scope is opaque
168
+ * metadata only; it never reaches authorization or the Web DTO.
169
+ */
170
+ observeConversation(event: ChannelEvent): void;
171
+ /**
172
+ * Sanitized read-only update status for the web control plane and the
173
+ * channel `/version` command. Serves the cached snapshot immediately and
174
+ * refreshes in the background when stale — never blocks on the registry.
175
+ */
176
+ getUpdateStatus(): Promise<BundleUpdateStatus>;
177
+ }
178
+ export type { ChannelDefinition, ChannelAdapter, InternalAuthSession };
179
+ export { ControlError };
180
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}