dsh-connect 0.6.7 → 0.7.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.
@@ -0,0 +1,162 @@
1
+ /**
2
+ * Persistent chat-level scheduled reminders.
3
+ *
4
+ * `/remind 10分钟 提醒我喝水` stores a reminder in `stateDir/reminders.json`
5
+ * (same pattern as the binding store) and a lightweight loop in the connect
6
+ * service delivers it when it comes due — across process restarts, without
7
+ * waking the agent or spending model tokens. This is separate from the DSH
8
+ * agent's own in-session `schedule` tool (which requires the plugin mounted
9
+ * in the profile and only lives while the session does).
10
+ * @module dsh-connect/scheduler
11
+ */
12
+ import { randomUUID } from "node:crypto";
13
+ import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
14
+ import { dirname, resolve } from "node:path";
15
+ /**
16
+ * Parse a `/remind` time expression into an epoch ms.
17
+ * Supported forms (relative or clock time):
18
+ * - `10分钟` / `10m` / `10` → minutes from now
19
+ * - `2小时` / `2h` → hours from now
20
+ * - `14:30` → today at 14:30 (tomorrow if already past)
21
+ * Returns `undefined` when the expression is not recognized.
22
+ */
23
+ export function parseRemindTime(arg, now = Date.now()) {
24
+ const s = arg.trim().toLowerCase();
25
+ if (s === "")
26
+ return undefined;
27
+ // Relative minutes: "10", "10m", "10分钟", "10 分"
28
+ const minutes = s.match(/^(\d+)\s*(m|分钟|分)?$/);
29
+ if (minutes !== null) {
30
+ const value = Number(minutes[1]);
31
+ if (!Number.isFinite(value) || value <= 0)
32
+ return undefined;
33
+ return now + value * 60_000;
34
+ }
35
+ // Relative hours: "2h", "2小时", "2 小时"
36
+ const hours = s.match(/^(\d+)\s*(h|小时|时)$/);
37
+ if (hours !== null) {
38
+ const value = Number(hours[1]);
39
+ if (!Number.isFinite(value) || value <= 0)
40
+ return undefined;
41
+ return now + value * 3_600_000;
42
+ }
43
+ // Clock time: "14:30" (or "9:05") — today, or tomorrow when already past.
44
+ const clock = s.match(/^(\d{1,2}):(\d{2})$/);
45
+ if (clock !== null) {
46
+ const hour = Number(clock[1]);
47
+ const minute = Number(clock[2]);
48
+ if (hour > 23 || minute > 59)
49
+ return undefined;
50
+ const at = new Date(now);
51
+ at.setHours(hour, minute, 0, 0);
52
+ if (at.getTime() <= now)
53
+ at.setDate(at.getDate() + 1);
54
+ return at.getTime();
55
+ }
56
+ return undefined;
57
+ }
58
+ /** Human-readable display of a due time, in the user-facing language. */
59
+ export function formatRemindAt(dueAt, language = "zh", now = Date.now()) {
60
+ const date = new Date(dueAt);
61
+ const today = new Date(now);
62
+ // Local-time components so the render is identical on every host timezone.
63
+ const time = `${String(date.getHours()).padStart(2, "0")}:${String(date.getMinutes()).padStart(2, "0")}`;
64
+ if (date.toDateString() === today.toDateString())
65
+ return time;
66
+ const locale = language === "en" ? "en-US" : "zh-CN";
67
+ const day = date.toLocaleDateString(locale, { month: "numeric", day: "numeric" });
68
+ return `${day} ${time}`;
69
+ }
70
+ function isRecord(value) {
71
+ return typeof value === "object" && value !== null;
72
+ }
73
+ /** JSON-file reminder store (best-effort persistence, live in-memory truth). */
74
+ export class ReminderStore {
75
+ file;
76
+ reminders = [];
77
+ constructor(stateDir) {
78
+ const dir = stateDir ?? process.env.DSH_CONNECT_STATE_DIR ?? ".dsh-connect";
79
+ this.file = resolve(dir, "reminders.json");
80
+ this.load();
81
+ }
82
+ /** All reminders, nearest-due first. */
83
+ list() {
84
+ return [...this.reminders].sort((a, b) => a.dueAt - b.dueAt);
85
+ }
86
+ /** Reminders bound to one chat, nearest-due first. */
87
+ listFor(channel, chatKey) {
88
+ return this.reminders
89
+ .filter((r) => r.channel === channel && r.chatKey === chatKey)
90
+ .sort((a, b) => a.dueAt - b.dueAt);
91
+ }
92
+ /** Reminders that have come due and were not yet fired. */
93
+ due(now = Date.now()) {
94
+ return this.reminders.filter((r) => r.fired !== true && r.dueAt <= now);
95
+ }
96
+ add(input) {
97
+ const reminder = {
98
+ ...input,
99
+ id: randomUUID(),
100
+ createdAt: Date.now(),
101
+ };
102
+ this.reminders.push(reminder);
103
+ this.save();
104
+ return reminder;
105
+ }
106
+ remove(id) {
107
+ const before = this.reminders.length;
108
+ this.reminders = this.reminders.filter((r) => r.id !== id);
109
+ if (this.reminders.length !== before) {
110
+ this.save();
111
+ return true;
112
+ }
113
+ return false;
114
+ }
115
+ markFired(id) {
116
+ const reminder = this.reminders.find((r) => r.id === id);
117
+ if (reminder === undefined || reminder.fired === true)
118
+ return;
119
+ reminder.fired = true;
120
+ this.save();
121
+ }
122
+ load() {
123
+ try {
124
+ const raw = readFileSync(this.file, "utf8");
125
+ const parsed = JSON.parse(raw);
126
+ if (!Array.isArray(parsed))
127
+ return;
128
+ const out = [];
129
+ for (const item of parsed) {
130
+ if (!isRecord(item))
131
+ continue;
132
+ if (typeof item.channel !== "string" || typeof item.chatKey !== "string")
133
+ continue;
134
+ out.push({
135
+ id: typeof item.id === "string" ? item.id : randomUUID(),
136
+ channel: item.channel,
137
+ chatKey: item.chatKey,
138
+ chatType: item.chatType === "group" ? "group" : "p2p",
139
+ text: typeof item.text === "string" ? item.text : "",
140
+ dueAt: typeof item.dueAt === "number" ? item.dueAt : 0,
141
+ createdAt: typeof item.createdAt === "number" ? item.createdAt : Date.now(),
142
+ ownerKey: typeof item.ownerKey === "string" ? item.ownerKey : "",
143
+ ...(item.fired === true ? { fired: true } : {}),
144
+ });
145
+ }
146
+ this.reminders = out;
147
+ }
148
+ catch {
149
+ // Missing or corrupt file: start empty.
150
+ }
151
+ }
152
+ save() {
153
+ try {
154
+ mkdirSync(dirname(this.file), { recursive: true });
155
+ writeFileSync(this.file, JSON.stringify(this.reminders, null, 2), "utf8");
156
+ }
157
+ catch {
158
+ // Persistence is best-effort; live reminders still fire in-memory.
159
+ }
160
+ }
161
+ }
162
+ //# sourceMappingURL=scheduler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"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"}
package/lib/service.d.ts CHANGED
@@ -7,14 +7,24 @@ import { Service, type Context } from "@deepseek-ai/cordis";
7
7
  import type { ChannelAdapter, InboundMessage } from "./types.js";
8
8
  import { type ConnectConfig, type ResolvedConnectConfig } from "./runner.js";
9
9
  import { BindingStore } from "./binding.js";
10
+ import { ReminderStore } from "./scheduler.js";
10
11
  export declare class ConnectService extends Service {
11
12
  readonly config: ResolvedConnectConfig;
12
13
  private readonly adapters;
13
14
  private readonly runners;
14
15
  private readonly bindings;
15
16
  private readonly interaction;
17
+ /** Sliding-window duplicate guard for re-delivered inbound events. */
18
+ private readonly dedup;
19
+ /** Persistent chat-level reminders (`/remind`) + the delivery loop. */
20
+ readonly reminders: ReminderStore;
21
+ private reminderTimer?;
16
22
  private workspacesRegistered;
17
23
  constructor(ctx: Context, config?: ConnectConfig | null);
24
+ /** Poll the reminder store and deliver anything that has come due. */
25
+ private startReminderLoop;
26
+ /** Deliver every due reminder and mark it fired (kept unfired on failure to retry). */
27
+ private fireDueReminders;
18
28
  /** Expose the binding store so adapters (e.g. connect-web) can monitor mirror sessions. */
19
29
  get bindingStore(): BindingStore;
20
30
  /**
@@ -44,10 +54,27 @@ export declare class ConnectService extends Service {
44
54
  isChatAllowed(channel: string, chatKey: string, senderKey: string): boolean;
45
55
  /** Entry point every adapter forwards normalized messages into. */
46
56
  handleInbound(msg: InboundMessage): Promise<void>;
57
+ /**
58
+ * Route a message to the runner of its (channel, chatKey) pair, creating
59
+ * the runner lazily. Also used to replay queued mirror-lock messages into
60
+ * the runner of their own channel instead of whichever runner released
61
+ * the lock.
62
+ */
63
+ private routeInbound;
47
64
  /**
48
65
  * Proactive push for work arrangement: goals/jobs/schedule hooks call this to
49
66
  * deliver progress or completion notices back to a bound chat.
50
67
  */
51
68
  notify(channel: string, chatKey: string, chatType: "p2p" | "group", markdown: string): Promise<void>;
69
+ /**
70
+ * Broadcast a message to every bound chat. Admin-gated: requires a
71
+ * non-empty `allowUsers` and a sender listed in it. Returns how many
72
+ * chats received the message; per-chat delivery failures are skipped.
73
+ */
74
+ broadcast(senderKey: string, markdown: string): Promise<{
75
+ ok: boolean;
76
+ reason?: "disabled" | "not-admin";
77
+ count?: number;
78
+ }>;
52
79
  }
53
80
  //# sourceMappingURL=service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAG5D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,EAAqC,KAAK,aAAa,EAAE,KAAK,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAChH,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAiD5C,qBAAa,cAAe,SAAQ,OAAO;IACzC,QAAQ,CAAC,MAAM,EAAE,qBAAqB,CAAC;IACvC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqC;IAC9D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;IAC1D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoB;IAChD,OAAO,CAAC,oBAAoB,CAAS;gBAEzB,GAAG,EAAE,OAAO,EAAE,MAAM,GAAE,aAAa,GAAG,IAAS;IA2B3D,2FAA2F;IAC3F,IAAI,YAAY,IAAI,YAAY,CAE/B;IAED;;;;;;;;;;;;OAYG;IACG,0BAA0B,IAAI,OAAO,CAAC,IAAI,CAAC;IAmDjD,2EAA2E;IAC3E,eAAe,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAgB9C,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAIlD,mFAAmF;IACnF,SAAS,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO;IAIvC;;;;OAIG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAO3E,mEAAmE;IAC7D,aAAa,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAwCvD;;;OAGG;IACG,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,GAAG,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAK3G"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAG5D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,EAAqC,KAAK,aAAa,EAAE,KAAK,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAChH,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAI5C,OAAO,EAAE,aAAa,EAA0B,MAAM,gBAAgB,CAAC;AAwDvE,qBAAa,cAAe,SAAQ,OAAO;IACzC,QAAQ,CAAC,MAAM,EAAE,qBAAqB,CAAC;IACvC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqC;IAC9D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;IAC1D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoB;IAChD,sEAAsE;IACtE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAsB;IAC5C,uEAAuE;IACvE,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;IAClC,OAAO,CAAC,aAAa,CAAC,CAAiB;IACvC,OAAO,CAAC,oBAAoB,CAAS;gBAEzB,GAAG,EAAE,OAAO,EAAE,MAAM,GAAE,aAAa,GAAG,IAAS;IA6B3D,sEAAsE;IACtE,OAAO,CAAC,iBAAiB;IAkBzB,uFAAuF;YACzE,gBAAgB;IAiB9B,2FAA2F;IAC3F,IAAI,YAAY,IAAI,YAAY,CAE/B;IAED;;;;;;;;;;;;OAYG;IACG,0BAA0B,IAAI,OAAO,CAAC,IAAI,CAAC;IAmDjD,2EAA2E;IAC3E,eAAe,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAmB9C,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAIlD,mFAAmF;IACnF,SAAS,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO;IAIvC;;;;OAIG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAO3E,mEAAmE;IAC7D,aAAa,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAgCvD;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IAuBpB;;;OAGG;IACG,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,GAAG,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM1G;;;;OAIG;IACG,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,UAAU,GAAG,WAAW,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAoBlI"}
package/lib/service.js CHANGED
@@ -9,6 +9,10 @@ import { basename, join, dirname } from "node:path";
9
9
  import { AgentRunner, resolveConnectConfig } from "./runner.js";
10
10
  import { BindingStore } from "./binding.js";
11
11
  import { InteractionBridge } from "./interaction.js";
12
+ import { InboundDedup } from "./dedup.js";
13
+ import { withOutboundRetry } from "./retry.js";
14
+ import { ReminderStore } from "./scheduler.js";
15
+ import { messages } from "./i18n.js";
12
16
  /** Load shared configuration from project root or current directory. */
13
17
  function loadSharedConfig() {
14
18
  const candidates = [
@@ -31,12 +35,23 @@ function loadSharedConfig() {
31
35
  function runnerKey(channel, chatKey) {
32
36
  return `${channel}\u0000${chatKey}`;
33
37
  }
38
+ /**
39
+ * Bounded retry for outbound delivery. Attempts are cheap; a few extra calls
40
+ * on a permanent failure are preferable to silently dropping a message on a
41
+ * transient one. streamText is deliberately excluded (see withOutboundRetry).
42
+ */
43
+ const OUTBOUND_RETRY = { attempts: 3, baseDelayMs: 250, maxDelayMs: 2000 };
34
44
  export class ConnectService extends Service {
35
45
  config;
36
46
  adapters = new Map();
37
47
  runners = new Map();
38
48
  bindings;
39
49
  interaction;
50
+ /** Sliding-window duplicate guard for re-delivered inbound events. */
51
+ dedup = new InboundDedup();
52
+ /** Persistent chat-level reminders (`/remind`) + the delivery loop. */
53
+ reminders;
54
+ reminderTimer;
40
55
  workspacesRegistered = false;
41
56
  constructor(ctx, config = {}) {
42
57
  super(ctx, "connect");
@@ -60,6 +75,43 @@ export class ConnectService extends Service {
60
75
  this.config = resolveConnectConfig(mergedConfig);
61
76
  this.bindings = new BindingStore(this.config.stateDir);
62
77
  this.interaction = new InteractionBridge(ctx, this.adapters, this.bindings, this.config);
78
+ this.reminders = new ReminderStore(this.config.stateDir);
79
+ this.startReminderLoop();
80
+ }
81
+ /** Poll the reminder store and deliver anything that has come due. */
82
+ startReminderLoop() {
83
+ const CHECK_MS = 15_000;
84
+ const timer = setInterval(() => {
85
+ void this.fireDueReminders().catch((error) => {
86
+ this.ctx.logger?.error?.(`connect: reminder tick failed: ${String(error)}`);
87
+ });
88
+ }, CHECK_MS);
89
+ timer.unref?.();
90
+ this.reminderTimer = timer;
91
+ try {
92
+ // Cast: cordis Context.on is typed to a fixed event map; "dispose" is the
93
+ // generic lifecycle event the host emits on teardown.
94
+ this.ctx.on?.("dispose", () => clearInterval(timer));
95
+ }
96
+ catch {
97
+ // Host without the lifecycle event: the unref'd timer dies with the process.
98
+ }
99
+ }
100
+ /** Deliver every due reminder and mark it fired (kept unfired on failure to retry). */
101
+ async fireDueReminders() {
102
+ const t = messages(this.config.language);
103
+ for (const reminder of this.reminders.due()) {
104
+ const adapter = this.adapters.get(reminder.channel);
105
+ if (adapter === undefined)
106
+ continue;
107
+ try {
108
+ await adapter.sendText({ chatKey: reminder.chatKey, chatType: reminder.chatType }, t.reminderFired(reminder.text));
109
+ this.reminders.markFired(reminder.id);
110
+ }
111
+ catch (error) {
112
+ this.ctx.logger?.warn?.(`connect: reminder delivery failed (${reminder.channel}/${reminder.chatKey}): ${String(error)}`);
113
+ }
114
+ }
63
115
  }
64
116
  /** Expose the binding store so adapters (e.g. connect-web) can monitor mirror sessions. */
65
117
  get bindingStore() {
@@ -139,8 +191,11 @@ export class ConnectService extends Service {
139
191
  if (this.adapters.has(adapter.id)) {
140
192
  throw new Error(`connect: channel "${adapter.id}" is already registered`);
141
193
  }
142
- this.adapters.set(adapter.id, adapter);
143
- adapter.onInbound((msg) => {
194
+ // Wrap outbound delivery with bounded retry so transient channel failures
195
+ // (network blips, 429/5xx) don't silently drop user-visible messages.
196
+ const wrapped = withOutboundRetry(adapter, OUTBOUND_RETRY);
197
+ this.adapters.set(adapter.id, wrapped);
198
+ wrapped.onInbound((msg) => {
144
199
  void this.handleInbound(msg).catch((error) => {
145
200
  // Inbound handling runs detached; surface failures instead of letting
146
201
  // them become silent unhandled rejections.
@@ -175,6 +230,12 @@ export class ConnectService extends Service {
175
230
  const adapter = this.adapters.get(msg.channel);
176
231
  if (adapter === undefined)
177
232
  return;
233
+ // Channel SDKs can re-deliver the same event after a reconnect; skip the
234
+ // duplicate so the user's message is not queued twice.
235
+ if (this.dedup.isDuplicate(msg.channel, msg.chatKey, msg.replyRef)) {
236
+ this.ctx.logger?.warn?.(`connect: dropped duplicate inbound (${msg.channel}/${msg.chatKey} msg=${msg.replyRef})`);
237
+ return;
238
+ }
178
239
  // A question (ask_user_question) is waiting on this chat: plain text is
179
240
  // the user's answer. Commands (starting with "/") still go to the runner
180
241
  // so /stop etc. keep working while the agent waits.
@@ -189,10 +250,22 @@ export class ConnectService extends Service {
189
250
  // workspace exists before a new session is created and attached to it
190
251
  // (the registry flag makes subsequent calls a no-op).
191
252
  await this.ensureWorkspacesRegistered();
253
+ this.routeInbound(msg);
254
+ }
255
+ /**
256
+ * Route a message to the runner of its (channel, chatKey) pair, creating
257
+ * the runner lazily. Also used to replay queued mirror-lock messages into
258
+ * the runner of their own channel instead of whichever runner released
259
+ * the lock.
260
+ */
261
+ routeInbound(msg) {
192
262
  const key = runnerKey(msg.channel, msg.chatKey);
193
263
  let runner = this.runners.get(key);
194
264
  if (runner === undefined) {
195
- runner = new AgentRunner(this.ctx, this.config, msg.channel, msg.chatKey, msg.chatType, adapter, this.bindings, this.adapters);
265
+ const adapter = this.adapters.get(msg.channel);
266
+ if (adapter === undefined)
267
+ return;
268
+ runner = new AgentRunner(this.ctx, this.config, msg.channel, msg.chatKey, msg.chatType, adapter, this.bindings, this.adapters, (m) => this.routeInbound(m), this.reminders);
196
269
  this.runners.set(key, runner);
197
270
  }
198
271
  runner.enqueue(msg);
@@ -207,5 +280,35 @@ export class ConnectService extends Service {
207
280
  return;
208
281
  await adapter.sendText({ chatKey, chatType }, markdown);
209
282
  }
283
+ /**
284
+ * Broadcast a message to every bound chat. Admin-gated: requires a
285
+ * non-empty `allowUsers` and a sender listed in it. Returns how many
286
+ * chats received the message; per-chat delivery failures are skipped.
287
+ */
288
+ async broadcast(senderKey, markdown) {
289
+ if (this.config.allowUsers.length === 0)
290
+ return { ok: false, reason: "disabled" };
291
+ if (!this.config.allowUsers.includes(senderKey))
292
+ return { ok: false, reason: "not-admin" };
293
+ let count = 0;
294
+ const seen = new Set();
295
+ for (const binding of this.bindings.list()) {
296
+ const key = `${binding.channel}\u0000${binding.chatKey}`;
297
+ if (seen.has(key))
298
+ continue;
299
+ seen.add(key);
300
+ const adapter = this.adapters.get(binding.channel);
301
+ if (adapter === undefined)
302
+ continue;
303
+ try {
304
+ await adapter.sendText({ chatKey: binding.chatKey, chatType: binding.chatType }, markdown);
305
+ count += 1;
306
+ }
307
+ catch (error) {
308
+ this.ctx.logger?.warn?.(`connect: broadcast skipped (${binding.channel}/${binding.chatKey}): ${String(error)}`);
309
+ }
310
+ }
311
+ return { ok: true, count };
312
+ }
210
313
  }
211
314
  //# sourceMappingURL=service.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
package/lib/types.d.ts CHANGED
@@ -115,6 +115,14 @@ export interface ChannelAdapter {
115
115
  sendText(target: OutboundTarget, text: string): Promise<void>;
116
116
  /** Deliver a status/summary card. */
117
117
  sendCard(target: OutboundTarget, card: SummaryCard): Promise<void>;
118
+ /**
119
+ * Deliver a local file (image / document / audio / video) to the chat.
120
+ * Optional: channels without file support omit it, and the runner falls
121
+ * back to sending the file's path as text.
122
+ */
123
+ sendFile?(target: OutboundTarget, filePath: string, options?: {
124
+ filename?: string;
125
+ }): Promise<void>;
118
126
  /**
119
127
  * Stream `chunks` into one progressively-updated reply. Resolves when the
120
128
  * producer is exhausted (`chunks` ends) and the adapter has finalized it.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-connect",
3
- "version": "0.6.7",
3
+ "version": "0.7.0",
4
4
  "description": "Channel-agnostic messaging bridge core for DeepSeek Harness (DSH): binds chat channels to DSH agents, streams replies, and pushes work summaries",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",