@vanadium-23/dsh-ping 0.1.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/DESIGN.md +168 -0
- package/LICENSE +21 -0
- package/README.md +161 -0
- package/bin/dsh-ping.mjs +8 -0
- package/cordis.patch.yml +8 -0
- package/lib/channels-CpGxdbPv.js +426 -0
- package/lib/index.js +421 -0
- package/lib/smoke.js +65 -0
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/lib/types/channels.d.ts +109 -0
- package/lib/types/channels.d.ts.map +1 -0
- package/lib/types/channels.js +204 -0
- package/lib/types/channels.js.map +1 -0
- package/lib/types/decide.d.ts +110 -0
- package/lib/types/decide.d.ts.map +1 -0
- package/lib/types/decide.js +145 -0
- package/lib/types/decide.js.map +1 -0
- package/lib/types/defaults.d.ts +64 -0
- package/lib/types/defaults.d.ts.map +1 -0
- package/lib/types/defaults.js +51 -0
- package/lib/types/defaults.js.map +1 -0
- package/lib/types/index.d.ts +36 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index.js +330 -0
- package/lib/types/index.js.map +1 -0
- package/lib/types/protocol.d.ts +122 -0
- package/lib/types/protocol.d.ts.map +1 -0
- package/lib/types/protocol.js +107 -0
- package/lib/types/protocol.js.map +1 -0
- package/lib/types/smoke.d.ts +17 -0
- package/lib/types/smoke.d.ts.map +1 -0
- package/lib/types/smoke.js +66 -0
- package/lib/types/smoke.js.map +1 -0
- package/package.json +66 -0
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-ping — desktop notifications for DeepSeek Harness.
|
|
3
|
+
*
|
|
4
|
+
* Watches four host moments and tells a human about them: a turn finished, an
|
|
5
|
+
* agent errored, an approval is pending, or the agent asked a question. The
|
|
6
|
+
* delivery is a Windows toast (plus a console line and an optional webhook).
|
|
7
|
+
*
|
|
8
|
+
* The plugin is host-only and imports exactly one `@deepseek-ai/*` module —
|
|
9
|
+
* `schemastery`, the configuration schema library — at runtime. It has no
|
|
10
|
+
* browser half, so it cannot affect what the Web client loads, and no
|
|
11
|
+
* `dsh-*` internals, so renaming one cannot break it.
|
|
12
|
+
* @module dsh-ping
|
|
13
|
+
*/
|
|
14
|
+
import z from '@deepseek-ai/schemastery';
|
|
15
|
+
import { buildNotice, shouldNotify } from "./decide.js";
|
|
16
|
+
import { DEFAULTS, resolveConfig } from "./defaults.js";
|
|
17
|
+
import { sendConsole, sendToast, sendWebhook } from "./channels.js";
|
|
18
|
+
import { agentKey, cwdOf, errorText, isRootAgent, sessionKey, textOfMessage, } from "./protocol.js";
|
|
19
|
+
/** Stable Cordis plugin name. */
|
|
20
|
+
export const name = 'dsh-ping';
|
|
21
|
+
/** No service is required: every host fact is read optionally. */
|
|
22
|
+
export const inject = [];
|
|
23
|
+
/**
|
|
24
|
+
* The configuration schema.
|
|
25
|
+
*
|
|
26
|
+
* Every default is written twice on purpose — once here so the loader can
|
|
27
|
+
* validate and fill a partial user config, and once in `defaults.ts` so the
|
|
28
|
+
* dependency-free smoke test shares the same values.
|
|
29
|
+
*/
|
|
30
|
+
export const Config = z.object({
|
|
31
|
+
enabled: z.boolean().default(DEFAULTS.enabled),
|
|
32
|
+
notifyOn: z.object({
|
|
33
|
+
done: z.boolean().default(DEFAULTS.notifyOn.done),
|
|
34
|
+
error: z.boolean().default(DEFAULTS.notifyOn.error),
|
|
35
|
+
approval: z.boolean().default(DEFAULTS.notifyOn.approval),
|
|
36
|
+
question: z.boolean().default(DEFAULTS.notifyOn.question),
|
|
37
|
+
}).default(DEFAULTS.notifyOn),
|
|
38
|
+
rootsOnly: z.boolean().default(DEFAULTS.rootsOnly),
|
|
39
|
+
cooldownMs: z.natural().default(DEFAULTS.cooldownMs),
|
|
40
|
+
minTurnDurationMs: z.natural().default(DEFAULTS.minTurnDurationMs),
|
|
41
|
+
channels: z.object({
|
|
42
|
+
toast: z.boolean().default(DEFAULTS.channels.toast),
|
|
43
|
+
console: z.boolean().default(DEFAULTS.channels.console),
|
|
44
|
+
webhook: z.boolean().default(DEFAULTS.channels.webhook),
|
|
45
|
+
}).default(DEFAULTS.channels),
|
|
46
|
+
webhookUrl: z.string().default(DEFAULTS.webhookUrl),
|
|
47
|
+
webhookTimeoutMs: z.natural().default(DEFAULTS.webhookTimeoutMs),
|
|
48
|
+
url: z.string().default(DEFAULTS.url),
|
|
49
|
+
maxBodyChars: z.natural().default(DEFAULTS.maxBodyChars),
|
|
50
|
+
toastAppId: z.string().default(DEFAULTS.toastAppId),
|
|
51
|
+
toastSoundDone: z.string().default(DEFAULTS.toastSoundDone),
|
|
52
|
+
toastSoundAttention: z.string().default(DEFAULTS.toastSoundAttention),
|
|
53
|
+
powershellPath: z.string().default(DEFAULTS.powershellPath),
|
|
54
|
+
titles: z.object({
|
|
55
|
+
done: z.string().default(DEFAULTS.titles.done),
|
|
56
|
+
error: z.string().default(DEFAULTS.titles.error),
|
|
57
|
+
approval: z.string().default(DEFAULTS.titles.approval),
|
|
58
|
+
question: z.string().default(DEFAULTS.titles.question),
|
|
59
|
+
}).default(DEFAULTS.titles),
|
|
60
|
+
debug: z.boolean().default(DEFAULTS.debug),
|
|
61
|
+
});
|
|
62
|
+
export { DEFAULTS, resolveConfig } from "./defaults.js";
|
|
63
|
+
/** Most recently rendered assistant text, keyed by session. */
|
|
64
|
+
const ASSISTANT_CACHE_LIMIT = 64;
|
|
65
|
+
/**
|
|
66
|
+
* Register the notification plugin.
|
|
67
|
+
* @param ctx - the plugin context.
|
|
68
|
+
* @param config - resolved plugin configuration.
|
|
69
|
+
*/
|
|
70
|
+
export function apply(ctx, config) {
|
|
71
|
+
const cfg = resolveConfig(config);
|
|
72
|
+
const host = ctx;
|
|
73
|
+
const log = (line) => { process.stderr.write(`[dsh-ping] ${line}\n`); };
|
|
74
|
+
if (!cfg.enabled) {
|
|
75
|
+
log('disabled by configuration');
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const limits = {
|
|
79
|
+
enabled: cfg.enabled,
|
|
80
|
+
kinds: { ...cfg.notifyOn },
|
|
81
|
+
rootsOnly: cfg.rootsOnly,
|
|
82
|
+
cooldownMs: cfg.cooldownMs,
|
|
83
|
+
minTurnDurationMs: cfg.minTurnDurationMs,
|
|
84
|
+
maxBodyChars: cfg.maxBodyChars,
|
|
85
|
+
};
|
|
86
|
+
const turns = new Map();
|
|
87
|
+
const lastNotified = new Map();
|
|
88
|
+
const lastAssistant = new Map();
|
|
89
|
+
/** The URL a toast click opens. */
|
|
90
|
+
const clickUrl = () => {
|
|
91
|
+
if (cfg.url !== '')
|
|
92
|
+
return cfg.url;
|
|
93
|
+
const server = host.get('webServer');
|
|
94
|
+
const port = server?.port;
|
|
95
|
+
if (typeof port !== 'number' || port <= 0)
|
|
96
|
+
return '';
|
|
97
|
+
const bound = typeof server?.host === 'string' ? server.host : '';
|
|
98
|
+
const address = bound === '0.0.0.0' || bound === '' ? '127.0.0.1' : bound;
|
|
99
|
+
return `http://${address}:${String(port)}/`;
|
|
100
|
+
};
|
|
101
|
+
/** The host's title for a session, when a title service is mounted. */
|
|
102
|
+
const titleOf = (session) => {
|
|
103
|
+
// Guarded on its own: a title projection that throws (an unknown session
|
|
104
|
+
// shape, a provider mid-rebuild) must cost the title, not the notice.
|
|
105
|
+
try {
|
|
106
|
+
const service = host.get('sessionTitle');
|
|
107
|
+
const title = service?.get(session)?.title;
|
|
108
|
+
return typeof title === 'string' ? title : '';
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
return '';
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
const toastDelivery = (attention) => ({
|
|
115
|
+
appId: cfg.toastAppId,
|
|
116
|
+
url: clickUrl(),
|
|
117
|
+
sound: attention ? cfg.toastSoundAttention : cfg.toastSoundDone,
|
|
118
|
+
long: attention,
|
|
119
|
+
...(cfg.powershellPath === '' ? {} : { powershellPath: cfg.powershellPath }),
|
|
120
|
+
});
|
|
121
|
+
/**
|
|
122
|
+
* Apply the rate limits, render the notice, and hand it to the channels.
|
|
123
|
+
* @param fact - what happened.
|
|
124
|
+
* @param isRoot - whether the agent owns its session.
|
|
125
|
+
*/
|
|
126
|
+
const deliver = (fact, isRoot) => {
|
|
127
|
+
const now = Date.now();
|
|
128
|
+
const key = `${fact.sessionId}:${fact.kind}`;
|
|
129
|
+
const lastNotifiedAt = lastNotified.get(key);
|
|
130
|
+
const verdict = shouldNotify({
|
|
131
|
+
fact,
|
|
132
|
+
limits,
|
|
133
|
+
isRoot,
|
|
134
|
+
...(lastNotifiedAt === undefined ? {} : { lastNotifiedAt }),
|
|
135
|
+
now,
|
|
136
|
+
});
|
|
137
|
+
if (!verdict.notify) {
|
|
138
|
+
if (cfg.debug)
|
|
139
|
+
log(`suppressed ${fact.kind} (${verdict.reason})`);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
lastNotified.set(key, now);
|
|
143
|
+
const notice = buildNotice(fact, cfg.titles, cfg.maxBodyChars);
|
|
144
|
+
if (cfg.channels.console)
|
|
145
|
+
sendConsole(notice, log);
|
|
146
|
+
if (cfg.channels.toast) {
|
|
147
|
+
const attention = fact.kind === 'approval' || fact.kind === 'question';
|
|
148
|
+
sendToast(notice, toastDelivery(attention), log);
|
|
149
|
+
}
|
|
150
|
+
if (cfg.channels.webhook && cfg.webhookUrl !== '') {
|
|
151
|
+
void sendWebhook({ kind: fact.kind, title: notice.title, lines: notice.lines, sessionId: fact.sessionId, at: new Date(now).toISOString() }, cfg.webhookUrl, cfg.webhookTimeoutMs, log);
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
/** Identity used for bookkeeping and rate limiting. */
|
|
155
|
+
const identityOf = (agent) => {
|
|
156
|
+
const key = agentKey(agent);
|
|
157
|
+
const sessionId = sessionKey(agent?.session) || key;
|
|
158
|
+
return { key, sessionId };
|
|
159
|
+
};
|
|
160
|
+
const onStatus = (payload) => {
|
|
161
|
+
const agent = payload.agent;
|
|
162
|
+
const { key, sessionId } = identityOf(agent);
|
|
163
|
+
if (key === '')
|
|
164
|
+
return;
|
|
165
|
+
if (payload.status === 'running') {
|
|
166
|
+
turns.set(key, { startedAt: Date.now(), sawError: false, reported: false });
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (payload.status !== 'idle')
|
|
170
|
+
return;
|
|
171
|
+
const turn = turns.get(key);
|
|
172
|
+
turns.delete(key);
|
|
173
|
+
if (turn === undefined)
|
|
174
|
+
return;
|
|
175
|
+
// An error already raised its own notice for this turn.
|
|
176
|
+
if (turn.sawError && turn.reported)
|
|
177
|
+
return;
|
|
178
|
+
const cwd = cwdOf(agent?.session);
|
|
179
|
+
deliver({
|
|
180
|
+
kind: 'done',
|
|
181
|
+
sessionId,
|
|
182
|
+
sessionTitle: titleOf(agent?.session),
|
|
183
|
+
cwd,
|
|
184
|
+
...(lastAssistant.has(sessionId) ? { detail: lastAssistant.get(sessionId) } : {}),
|
|
185
|
+
durationMs: Date.now() - turn.startedAt,
|
|
186
|
+
}, isRootAgent(agent));
|
|
187
|
+
};
|
|
188
|
+
const onError = (payload) => {
|
|
189
|
+
const agent = payload.agent;
|
|
190
|
+
const { key, sessionId } = identityOf(agent);
|
|
191
|
+
const turn = turns.get(key);
|
|
192
|
+
if (turn !== undefined) {
|
|
193
|
+
turn.sawError = true;
|
|
194
|
+
turn.reported = true;
|
|
195
|
+
}
|
|
196
|
+
deliver({
|
|
197
|
+
kind: 'error',
|
|
198
|
+
sessionId,
|
|
199
|
+
sessionTitle: titleOf(agent?.session),
|
|
200
|
+
cwd: cwdOf(agent?.session),
|
|
201
|
+
detail: errorText(payload.error),
|
|
202
|
+
}, isRootAgent(agent));
|
|
203
|
+
};
|
|
204
|
+
const onApproval = (payload) => {
|
|
205
|
+
const agent = payload.agent;
|
|
206
|
+
const { sessionId } = identityOf(agent);
|
|
207
|
+
const toolName = typeof payload.toolName === 'string' ? payload.toolName : '';
|
|
208
|
+
const reason = typeof payload.reason === 'string' ? payload.reason : '';
|
|
209
|
+
deliver({
|
|
210
|
+
kind: 'approval',
|
|
211
|
+
sessionId,
|
|
212
|
+
sessionTitle: titleOf(agent?.session),
|
|
213
|
+
cwd: cwdOf(agent?.session),
|
|
214
|
+
detail: [toolName, reason].filter(part => part !== '').join(' — '),
|
|
215
|
+
}, isRootAgent(agent));
|
|
216
|
+
};
|
|
217
|
+
const onQuestion = (payload) => {
|
|
218
|
+
const agent = payload.agent;
|
|
219
|
+
const { sessionId } = identityOf(agent);
|
|
220
|
+
const items = Array.isArray(payload.questions) ? payload.questions : [];
|
|
221
|
+
const first = items[0];
|
|
222
|
+
const text = typeof first?.question === 'string' ? first.question : '';
|
|
223
|
+
deliver({
|
|
224
|
+
kind: 'question',
|
|
225
|
+
sessionId,
|
|
226
|
+
sessionTitle: titleOf(agent?.session),
|
|
227
|
+
cwd: cwdOf(agent?.session),
|
|
228
|
+
detail: items.length > 1 ? `${text}(共 ${String(items.length)} 个问题)` : text,
|
|
229
|
+
}, isRootAgent(agent));
|
|
230
|
+
};
|
|
231
|
+
/** Keep the last assistant text so a completion notice can quote it. */
|
|
232
|
+
const rememberAssistant = (session, event) => {
|
|
233
|
+
if (event.type !== 'assistant/message')
|
|
234
|
+
return;
|
|
235
|
+
const id = sessionKey(session);
|
|
236
|
+
if (id === '')
|
|
237
|
+
return;
|
|
238
|
+
const text = textOfMessage(event.data?.message);
|
|
239
|
+
if (text.trim() === '')
|
|
240
|
+
return;
|
|
241
|
+
lastAssistant.delete(id);
|
|
242
|
+
lastAssistant.set(id, text);
|
|
243
|
+
while (lastAssistant.size > ASSISTANT_CACHE_LIMIT) {
|
|
244
|
+
const oldest = lastAssistant.keys().next().value;
|
|
245
|
+
if (oldest === undefined)
|
|
246
|
+
break;
|
|
247
|
+
lastAssistant.delete(oldest);
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
/** Run a handler without ever letting it reach the caller. */
|
|
251
|
+
const guard = (label, run) => {
|
|
252
|
+
try {
|
|
253
|
+
run();
|
|
254
|
+
}
|
|
255
|
+
catch (error) {
|
|
256
|
+
log(`${label} handler failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
host.on('agent/status', (payload) => { guard('agent/status', () => { onStatus(payload); }); });
|
|
260
|
+
host.on('agent/error', (payload) => { guard('agent/error', () => { onError(payload); }); });
|
|
261
|
+
host.on('session/event', (session, event) => {
|
|
262
|
+
guard('session/event', () => { rememberAssistant(session, event); });
|
|
263
|
+
});
|
|
264
|
+
// Both are waterfalls: notifying must not change who answers them, so the
|
|
265
|
+
// listener always delegates — and prepends, because an answerer registered
|
|
266
|
+
// earlier would otherwise claim the request before this plugin ever saw it.
|
|
267
|
+
host.on('approval/request', (payload, next) => {
|
|
268
|
+
guard('approval/request', () => { onApproval(payload); });
|
|
269
|
+
return next();
|
|
270
|
+
}, { prepend: true });
|
|
271
|
+
host.on('user-questions/request', (payload, next) => {
|
|
272
|
+
guard('user-questions/request', () => { onQuestion(payload); });
|
|
273
|
+
return next();
|
|
274
|
+
}, { prepend: true });
|
|
275
|
+
/**
|
|
276
|
+
* Register a self-test tool so the channel can be verified from inside a
|
|
277
|
+
* session, without a terminal and without waiting for a real turn to end.
|
|
278
|
+
*/
|
|
279
|
+
const registerTestTool = (scope) => {
|
|
280
|
+
const tools = scope.get('tools');
|
|
281
|
+
if (tools === undefined || typeof tools.register !== 'function')
|
|
282
|
+
return;
|
|
283
|
+
tools.register({
|
|
284
|
+
name: 'dsh_ping_test',
|
|
285
|
+
description: 'Send a test desktop notification through dsh-ping and report which channels accepted it. Use this to '
|
|
286
|
+
+ 'verify that turn-completion and attention notifications will actually reach the user, or when the user '
|
|
287
|
+
+ 'asks whether notifications work.',
|
|
288
|
+
parameters: {
|
|
289
|
+
type: 'object',
|
|
290
|
+
properties: {
|
|
291
|
+
text: { type: 'string', description: 'Optional body text for the test notification.' },
|
|
292
|
+
},
|
|
293
|
+
required: [],
|
|
294
|
+
},
|
|
295
|
+
output: {
|
|
296
|
+
schema: { type: 'string' },
|
|
297
|
+
render: (_args, value) => [{ type: 'text', text: String(value) }],
|
|
298
|
+
},
|
|
299
|
+
async execute(args) {
|
|
300
|
+
const text = typeof args?.text === 'string' && args.text.trim() !== ''
|
|
301
|
+
? args.text
|
|
302
|
+
: '这是一条 dsh-ping 自检通知,看到它就说明通知链路是通的。';
|
|
303
|
+
const notice = buildNotice({ kind: 'done', sessionId: 'self-test', sessionTitle: 'dsh-ping 自检', detail: text }, cfg.titles, cfg.maxBodyChars);
|
|
304
|
+
const accepted = [];
|
|
305
|
+
if (cfg.channels.console) {
|
|
306
|
+
sendConsole(notice, log);
|
|
307
|
+
accepted.push('console');
|
|
308
|
+
}
|
|
309
|
+
if (cfg.channels.toast) {
|
|
310
|
+
accepted.push(sendToast(notice, toastDelivery(false), log) ? 'toast' : 'toast(不可用)');
|
|
311
|
+
}
|
|
312
|
+
if (cfg.channels.webhook && cfg.webhookUrl !== '') {
|
|
313
|
+
accepted.push('webhook');
|
|
314
|
+
await sendWebhook({ kind: 'test', title: notice.title, lines: notice.lines, sessionId: 'self-test', at: new Date().toISOString() }, cfg.webhookUrl, cfg.webhookTimeoutMs, log);
|
|
315
|
+
}
|
|
316
|
+
return `dsh-ping 自检:已通过 ${accepted.join(' + ') || '(无可用通道)'} 发送「${notice.title}」`;
|
|
317
|
+
},
|
|
318
|
+
});
|
|
319
|
+
};
|
|
320
|
+
if (typeof host.inject === 'function')
|
|
321
|
+
host.inject(['tools'], registerTestTool);
|
|
322
|
+
else
|
|
323
|
+
registerTestTool(host);
|
|
324
|
+
const enabled = Object.entries(cfg.channels)
|
|
325
|
+
.filter(([, on]) => on)
|
|
326
|
+
.map(([channel]) => channel)
|
|
327
|
+
.join('+');
|
|
328
|
+
log(`ready — channels=${enabled} rootsOnly=${String(cfg.rootsOnly)} cooldown=${String(cfg.cooldownMs)}ms`);
|
|
329
|
+
}
|
|
330
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local, structural views of the host facts this plugin consumes.
|
|
3
|
+
*
|
|
4
|
+
* Nothing here imports a `@deepseek-ai/dsh-*` package. That is deliberate and
|
|
5
|
+
* is the whole compatibility story: an out-of-tree plugin that named an
|
|
6
|
+
* internal package broke on this machine when `@deepseek-ai/dsh-client-runtime`
|
|
7
|
+
* was renamed, so this one only ever reaches the host through shapes it
|
|
8
|
+
* declares itself, and treats every field as optional.
|
|
9
|
+
* @module dsh-ping/protocol
|
|
10
|
+
*/
|
|
11
|
+
/** The subset of a cordis `Context` this plugin uses. */
|
|
12
|
+
export interface LooseContext {
|
|
13
|
+
on(name: string, listener: (...args: any[]) => any, options?: {
|
|
14
|
+
prepend?: boolean;
|
|
15
|
+
}): unknown;
|
|
16
|
+
get<T = unknown>(name: string): T | undefined;
|
|
17
|
+
inject?(names: string[], callback: (scope: LooseContext) => void): unknown;
|
|
18
|
+
}
|
|
19
|
+
/** A session as far as notifications are concerned. */
|
|
20
|
+
export interface SessionLike {
|
|
21
|
+
id?: unknown;
|
|
22
|
+
cwd?: unknown;
|
|
23
|
+
}
|
|
24
|
+
/** An agent as far as notifications are concerned. */
|
|
25
|
+
export interface AgentLike {
|
|
26
|
+
id?: unknown;
|
|
27
|
+
session?: SessionLike;
|
|
28
|
+
/** Present on subagents; absent on the root agent that owns a session. */
|
|
29
|
+
parentAgent?: unknown;
|
|
30
|
+
options?: {
|
|
31
|
+
origin?: unknown;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/** `agent/status` payload. */
|
|
35
|
+
export interface AgentStatusPayload {
|
|
36
|
+
agent?: AgentLike;
|
|
37
|
+
status?: unknown;
|
|
38
|
+
}
|
|
39
|
+
/** `agent/error` payload. */
|
|
40
|
+
export interface AgentErrorPayload {
|
|
41
|
+
agent?: AgentLike;
|
|
42
|
+
error?: unknown;
|
|
43
|
+
}
|
|
44
|
+
/** `approval/request` payload. */
|
|
45
|
+
export interface ApprovalRequestPayload {
|
|
46
|
+
agent?: AgentLike;
|
|
47
|
+
toolName?: unknown;
|
|
48
|
+
reason?: unknown;
|
|
49
|
+
}
|
|
50
|
+
/** One question inside a `user-questions/request` payload. */
|
|
51
|
+
export interface QuestionItem {
|
|
52
|
+
id?: unknown;
|
|
53
|
+
question?: unknown;
|
|
54
|
+
header?: unknown;
|
|
55
|
+
}
|
|
56
|
+
/** `user-questions/request` payload. */
|
|
57
|
+
export interface UserQuestionPayload {
|
|
58
|
+
agent?: AgentLike;
|
|
59
|
+
questions?: unknown;
|
|
60
|
+
}
|
|
61
|
+
/** One durable session event, narrowed to the fields used here. */
|
|
62
|
+
export interface SessionEventLike {
|
|
63
|
+
type?: unknown;
|
|
64
|
+
data?: {
|
|
65
|
+
message?: unknown;
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/** `ctx.sessionTitle` service. */
|
|
69
|
+
export interface SessionTitleLike {
|
|
70
|
+
get(session: unknown): {
|
|
71
|
+
title?: unknown;
|
|
72
|
+
} | undefined;
|
|
73
|
+
}
|
|
74
|
+
/** `ctx.webServer` service. */
|
|
75
|
+
export interface WebServerLike {
|
|
76
|
+
port?: unknown;
|
|
77
|
+
host?: unknown;
|
|
78
|
+
}
|
|
79
|
+
/** `ctx.tools` service. */
|
|
80
|
+
export interface ToolsLike {
|
|
81
|
+
register(tool: unknown): unknown;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Narrow an unknown thrown value to a one-line message.
|
|
85
|
+
* @param error - the thrown value.
|
|
86
|
+
* @returns a single-line description.
|
|
87
|
+
*/
|
|
88
|
+
export declare function errorText(error: unknown): string;
|
|
89
|
+
/**
|
|
90
|
+
* Extract the visible text of an assistant message.
|
|
91
|
+
* @param message - an unknown message value.
|
|
92
|
+
* @returns concatenated text blocks, or an empty string.
|
|
93
|
+
*/
|
|
94
|
+
export declare function textOfMessage(message: unknown): string;
|
|
95
|
+
/**
|
|
96
|
+
* Whether an agent owns its session outright (the root agent) rather than
|
|
97
|
+
* being a delegated subagent.
|
|
98
|
+
* @param agent - the agent to classify.
|
|
99
|
+
* @returns true for the root agent.
|
|
100
|
+
*/
|
|
101
|
+
export declare function isRootAgent(agent: AgentLike | undefined): boolean;
|
|
102
|
+
/**
|
|
103
|
+
* Stable identity for one agent, used as the bookkeeping key.
|
|
104
|
+
* @param agent - the agent to identify.
|
|
105
|
+
* @returns the agent id, its session id, or an empty string.
|
|
106
|
+
*/
|
|
107
|
+
export declare function agentKey(agent: AgentLike | undefined): string;
|
|
108
|
+
/**
|
|
109
|
+
* Stable identity for one session.
|
|
110
|
+
* @param session - the session to identify.
|
|
111
|
+
* @returns the session id, or an empty string.
|
|
112
|
+
*/
|
|
113
|
+
export declare function sessionKey(session: unknown): string;
|
|
114
|
+
/**
|
|
115
|
+
* Read the working directory recorded on a session or agent.
|
|
116
|
+
* @param value - a session-like value.
|
|
117
|
+
* @returns the cwd, or an empty string.
|
|
118
|
+
*/
|
|
119
|
+
export declare function cwdOf(value: {
|
|
120
|
+
cwd?: unknown;
|
|
121
|
+
} | undefined): string;
|
|
122
|
+
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/protocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local, structural views of the host facts this plugin consumes.
|
|
3
|
+
*
|
|
4
|
+
* Nothing here imports a `@deepseek-ai/dsh-*` package. That is deliberate and
|
|
5
|
+
* is the whole compatibility story: an out-of-tree plugin that named an
|
|
6
|
+
* internal package broke on this machine when `@deepseek-ai/dsh-client-runtime`
|
|
7
|
+
* was renamed, so this one only ever reaches the host through shapes it
|
|
8
|
+
* declares itself, and treats every field as optional.
|
|
9
|
+
* @module dsh-ping/protocol
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Narrow an unknown thrown value to a one-line message.
|
|
13
|
+
* @param error - the thrown value.
|
|
14
|
+
* @returns a single-line description.
|
|
15
|
+
*/
|
|
16
|
+
export function errorText(error) {
|
|
17
|
+
if (error === undefined || error === null)
|
|
18
|
+
return '';
|
|
19
|
+
if (typeof error === 'string')
|
|
20
|
+
return error;
|
|
21
|
+
if (error instanceof Error)
|
|
22
|
+
return error.message;
|
|
23
|
+
const message = error.message;
|
|
24
|
+
if (typeof message === 'string')
|
|
25
|
+
return message;
|
|
26
|
+
try {
|
|
27
|
+
return JSON.stringify(error);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return String(error);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Extract the visible text of an assistant message.
|
|
35
|
+
* @param message - an unknown message value.
|
|
36
|
+
* @returns concatenated text blocks, or an empty string.
|
|
37
|
+
*/
|
|
38
|
+
export function textOfMessage(message) {
|
|
39
|
+
if (typeof message !== 'object' || message === null)
|
|
40
|
+
return '';
|
|
41
|
+
const content = message.content;
|
|
42
|
+
if (typeof content === 'string')
|
|
43
|
+
return content;
|
|
44
|
+
if (!Array.isArray(content))
|
|
45
|
+
return '';
|
|
46
|
+
const parts = [];
|
|
47
|
+
for (const block of content) {
|
|
48
|
+
if (typeof block !== 'object' || block === null)
|
|
49
|
+
continue;
|
|
50
|
+
const candidate = block;
|
|
51
|
+
if (candidate.type === 'text' && typeof candidate.text === 'string')
|
|
52
|
+
parts.push(candidate.text);
|
|
53
|
+
}
|
|
54
|
+
return parts.join('\n');
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Whether an agent owns its session outright (the root agent) rather than
|
|
58
|
+
* being a delegated subagent.
|
|
59
|
+
* @param agent - the agent to classify.
|
|
60
|
+
* @returns true for the root agent.
|
|
61
|
+
*/
|
|
62
|
+
export function isRootAgent(agent) {
|
|
63
|
+
if (agent === undefined)
|
|
64
|
+
return true;
|
|
65
|
+
if (agent.parentAgent !== undefined && agent.parentAgent !== null)
|
|
66
|
+
return false;
|
|
67
|
+
return agent.options?.origin !== 'subagent';
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Stable identity for one agent, used as the bookkeeping key.
|
|
71
|
+
* @param agent - the agent to identify.
|
|
72
|
+
* @returns the agent id, its session id, or an empty string.
|
|
73
|
+
*/
|
|
74
|
+
export function agentKey(agent) {
|
|
75
|
+
const id = agent?.id;
|
|
76
|
+
if (typeof id === 'string' && id.length > 0)
|
|
77
|
+
return id;
|
|
78
|
+
if (typeof id === 'number')
|
|
79
|
+
return String(id);
|
|
80
|
+
const sessionId = agent?.session?.id;
|
|
81
|
+
if (typeof sessionId === 'string' && sessionId.length > 0)
|
|
82
|
+
return sessionId;
|
|
83
|
+
return '';
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Stable identity for one session.
|
|
87
|
+
* @param session - the session to identify.
|
|
88
|
+
* @returns the session id, or an empty string.
|
|
89
|
+
*/
|
|
90
|
+
export function sessionKey(session) {
|
|
91
|
+
const id = session?.id;
|
|
92
|
+
if (typeof id === 'string' && id.length > 0)
|
|
93
|
+
return id;
|
|
94
|
+
if (typeof id === 'number')
|
|
95
|
+
return String(id);
|
|
96
|
+
return '';
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Read the working directory recorded on a session or agent.
|
|
100
|
+
* @param value - a session-like value.
|
|
101
|
+
* @returns the cwd, or an empty string.
|
|
102
|
+
*/
|
|
103
|
+
export function cwdOf(value) {
|
|
104
|
+
const cwd = value?.cwd;
|
|
105
|
+
return typeof cwd === 'string' ? cwd : '';
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/protocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standalone toast smoke test — no harness required.
|
|
3
|
+
*
|
|
4
|
+
* `node lib/smoke.js [text]` raises one real Windows toast with the exact code
|
|
5
|
+
* path the plugin uses, which is how the notification channel gets verified on
|
|
6
|
+
* a machine without starting a session.
|
|
7
|
+
* @module dsh-ping/smoke
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Raise one test toast.
|
|
11
|
+
* @param argv - words appended to the default body text.
|
|
12
|
+
* @returns the process exit code.
|
|
13
|
+
*/
|
|
14
|
+
export declare function runSmoke(argv: readonly string[]): number;
|
|
15
|
+
/** The configured default headings, exported for the CLI banner. */
|
|
16
|
+
export declare const SMOKE_TITLES: import("./decide.ts").NotifyTitles;
|
|
17
|
+
//# sourceMappingURL=smoke.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smoke.d.ts","sourceRoot":"","sources":["../../src/smoke.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CA2BxD;AAED,oEAAoE;AACpE,eAAO,MAAM,YAAY,oCAAkB,CAAA"}
|