@deepseekharness-mobile/companion 0.0.0-stage → 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/LICENSE +21 -0
- package/README.md +25 -2
- package/cordis.patch.yml +20 -0
- package/dist/core/devices.d.ts +35 -0
- package/dist/core/devices.d.ts.map +1 -0
- package/dist/core/devices.js +90 -0
- package/dist/core/devices.js.map +1 -0
- package/dist/core/pairing.d.ts +21 -0
- package/dist/core/pairing.d.ts.map +1 -0
- package/dist/core/pairing.js +74 -0
- package/dist/core/pairing.js.map +1 -0
- package/dist/dsh/errors.d.ts +3 -0
- package/dist/dsh/errors.d.ts.map +1 -0
- package/dist/dsh/errors.js +15 -0
- package/dist/dsh/errors.js.map +1 -0
- package/dist/dsh/lifecycle.d.ts +37 -0
- package/dist/dsh/lifecycle.d.ts.map +1 -0
- package/dist/dsh/lifecycle.js +95 -0
- package/dist/dsh/lifecycle.js.map +1 -0
- package/dist/dsh/models.d.ts +39 -0
- package/dist/dsh/models.d.ts.map +1 -0
- package/dist/dsh/models.js +171 -0
- package/dist/dsh/models.js.map +1 -0
- package/dist/dsh/prompt.d.ts +8 -0
- package/dist/dsh/prompt.d.ts.map +1 -0
- package/dist/dsh/prompt.js +25 -0
- package/dist/dsh/prompt.js.map +1 -0
- package/dist/dsh/providers.d.ts +25 -0
- package/dist/dsh/providers.d.ts.map +1 -0
- package/dist/dsh/providers.js +315 -0
- package/dist/dsh/providers.js.map +1 -0
- package/dist/dsh/question-bridge.d.ts +25 -0
- package/dist/dsh/question-bridge.d.ts.map +1 -0
- package/dist/dsh/question-bridge.js +140 -0
- package/dist/dsh/question-bridge.js.map +1 -0
- package/dist/dsh/questions.d.ts +15 -0
- package/dist/dsh/questions.d.ts.map +1 -0
- package/dist/dsh/questions.js +126 -0
- package/dist/dsh/questions.js.map +1 -0
- package/dist/dsh/session-activity.d.ts +5 -0
- package/dist/dsh/session-activity.d.ts.map +1 -0
- package/dist/dsh/session-activity.js +100 -0
- package/dist/dsh/session-activity.js.map +1 -0
- package/dist/dsh/session-source.d.ts +19 -0
- package/dist/dsh/session-source.d.ts.map +1 -0
- package/dist/dsh/session-source.js +104 -0
- package/dist/dsh/session-source.js.map +1 -0
- package/dist/dsh/sessions.d.ts +10 -0
- package/dist/dsh/sessions.d.ts.map +1 -0
- package/dist/dsh/sessions.js +51 -0
- package/dist/dsh/sessions.js.map +1 -0
- package/dist/dsh/slash-commands.d.ts +15 -0
- package/dist/dsh/slash-commands.d.ts.map +1 -0
- package/dist/dsh/slash-commands.js +60 -0
- package/dist/dsh/slash-commands.js.map +1 -0
- package/dist/dsh/transcript.d.ts +28 -0
- package/dist/dsh/transcript.d.ts.map +1 -0
- package/dist/dsh/transcript.js +211 -0
- package/dist/dsh/transcript.js.map +1 -0
- package/dist/dsh/workspaces.d.ts +20 -0
- package/dist/dsh/workspaces.d.ts.map +1 -0
- package/dist/dsh/workspaces.js +123 -0
- package/dist/dsh/workspaces.js.map +1 -0
- package/dist/host-api.d.ts +148 -0
- package/dist/host-api.d.ts.map +1 -0
- package/dist/host-api.js +54 -0
- package/dist/host-api.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +268 -0
- package/dist/index.js.map +1 -0
- package/dist/log.d.ts +5 -0
- package/dist/log.d.ts.map +1 -0
- package/dist/log.js +40 -0
- package/dist/log.js.map +1 -0
- package/dist/open-browser.d.ts +3 -0
- package/dist/open-browser.d.ts.map +1 -0
- package/dist/open-browser.js +46 -0
- package/dist/open-browser.js.map +1 -0
- package/dist/pairing-message.d.ts +16 -0
- package/dist/pairing-message.d.ts.map +1 -0
- package/dist/pairing-message.js +38 -0
- package/dist/pairing-message.js.map +1 -0
- package/dist/persist/devices-file.d.ts +8 -0
- package/dist/persist/devices-file.d.ts.map +1 -0
- package/dist/persist/devices-file.js +47 -0
- package/dist/persist/devices-file.js.map +1 -0
- package/dist/probe.d.ts +25 -0
- package/dist/probe.d.ts.map +1 -0
- package/dist/probe.js +143 -0
- package/dist/probe.js.map +1 -0
- package/dist/public-origin.d.ts +11 -0
- package/dist/public-origin.d.ts.map +1 -0
- package/dist/public-origin.js +79 -0
- package/dist/public-origin.js.map +1 -0
- package/dist/qr-text.d.ts +2 -0
- package/dist/qr-text.d.ts.map +1 -0
- package/dist/qr-text.js +31 -0
- package/dist/qr-text.js.map +1 -0
- package/dist/routes/origin.d.ts +17 -0
- package/dist/routes/origin.d.ts.map +1 -0
- package/dist/routes/origin.js +85 -0
- package/dist/routes/origin.js.map +1 -0
- package/dist/routes/static.d.ts +9 -0
- package/dist/routes/static.d.ts.map +1 -0
- package/dist/routes/static.js +129 -0
- package/dist/routes/static.js.map +1 -0
- package/dist/routes/web-root.d.ts +2 -0
- package/dist/routes/web-root.d.ts.map +1 -0
- package/dist/routes/web-root.js +21 -0
- package/dist/routes/web-root.js.map +1 -0
- package/dist/server.d.ts +140 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +829 -0
- package/dist/server.js.map +1 -0
- package/dist/web/apple-touch-icon-precomposed.png +0 -0
- package/dist/web/apple-touch-icon.png +0 -0
- package/dist/web/assets/index-NOGXMIsS.js +65 -0
- package/dist/web/assets/index-NOGXMIsS.js.map +1 -0
- package/dist/web/assets/index-s7zoNGmx.css +1 -0
- package/dist/web/fonts/Montserrat-OFL.txt +93 -0
- package/dist/web/fonts/montserrat-medium.woff2 +0 -0
- package/dist/web/fonts/montserrat-regular.woff2 +0 -0
- package/dist/web/icon-192.png +0 -0
- package/dist/web/icon-512.png +0 -0
- package/dist/web/icon-maskable-512.png +0 -0
- package/dist/web/icon-maskable.svg +15 -0
- package/dist/web/icon.svg +6 -0
- package/dist/web/index.html +25 -0
- package/dist/web/manifest.webmanifest +37 -0
- package/package.json +60 -3
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { PROTOCOL_VERSION, newMessageId, } from '@deepseekharness-mobile/protocol';
|
|
2
|
+
import { toQuestionItem } from './questions.js';
|
|
3
|
+
function recordOf(value) {
|
|
4
|
+
return typeof value === 'object' && value !== null
|
|
5
|
+
? value
|
|
6
|
+
: undefined;
|
|
7
|
+
}
|
|
8
|
+
function sessionIdOf(request) {
|
|
9
|
+
const agent = recordOf(request['agent']);
|
|
10
|
+
const session = recordOf(agent?.['session']);
|
|
11
|
+
const id = session?.['id'];
|
|
12
|
+
return typeof id === 'string' && id.length > 0 ? id : undefined;
|
|
13
|
+
}
|
|
14
|
+
function itemsOf(request) {
|
|
15
|
+
const questions = request['questions'];
|
|
16
|
+
if (!Array.isArray(questions))
|
|
17
|
+
return [];
|
|
18
|
+
return questions.map(toQuestionItem).filter((item) => item !== undefined);
|
|
19
|
+
}
|
|
20
|
+
function pendingFrame(batch) {
|
|
21
|
+
return {
|
|
22
|
+
v: PROTOCOL_VERSION,
|
|
23
|
+
id: newMessageId(),
|
|
24
|
+
at: Date.now(),
|
|
25
|
+
type: 'question.pending',
|
|
26
|
+
question: batch,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function settledFrame(callId, sessionId) {
|
|
30
|
+
return {
|
|
31
|
+
v: PROTOCOL_VERSION,
|
|
32
|
+
id: newMessageId(),
|
|
33
|
+
at: Date.now(),
|
|
34
|
+
type: 'question.settled',
|
|
35
|
+
callId,
|
|
36
|
+
sessionId,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function completeAnswer(items, answers) {
|
|
40
|
+
const expected = new Set(items.map((item) => item.id));
|
|
41
|
+
const ids = answers.map((answer) => answer.id);
|
|
42
|
+
return (ids.length === expected.size &&
|
|
43
|
+
new Set(ids).size === ids.length &&
|
|
44
|
+
ids.every((id) => expected.has(id)));
|
|
45
|
+
}
|
|
46
|
+
export function createQuestionBridge(ctx, deps) {
|
|
47
|
+
const pending = new Map();
|
|
48
|
+
let off;
|
|
49
|
+
const handle = async (request, next) => {
|
|
50
|
+
const raw = recordOf(request);
|
|
51
|
+
if (!raw || deps.clients() === 0 || recordOf(raw['wait']))
|
|
52
|
+
return next();
|
|
53
|
+
const sessionId = sessionIdOf(raw);
|
|
54
|
+
const items = itemsOf(raw);
|
|
55
|
+
if (!sessionId || items.length === 0)
|
|
56
|
+
return next();
|
|
57
|
+
const session = sessionId;
|
|
58
|
+
const callId = `mobile-${newMessageId()}`;
|
|
59
|
+
const batch = {
|
|
60
|
+
callId,
|
|
61
|
+
sessionId: session,
|
|
62
|
+
state: 'open',
|
|
63
|
+
items,
|
|
64
|
+
createdAt: Date.now(),
|
|
65
|
+
};
|
|
66
|
+
const signal = raw['signal'];
|
|
67
|
+
return new Promise((resolve, reject) => {
|
|
68
|
+
let finished = false;
|
|
69
|
+
function onAbort() {
|
|
70
|
+
finish(undefined, new Error('The question was cancelled before the phone answered.'));
|
|
71
|
+
}
|
|
72
|
+
function finish(answer, error) {
|
|
73
|
+
if (finished)
|
|
74
|
+
return;
|
|
75
|
+
finished = true;
|
|
76
|
+
pending.delete(callId);
|
|
77
|
+
signal?.removeEventListener('abort', onAbort);
|
|
78
|
+
deps.push(settledFrame(callId, session));
|
|
79
|
+
if (answer)
|
|
80
|
+
resolve(answer);
|
|
81
|
+
else
|
|
82
|
+
reject(error ?? new Error('The question was cancelled before an answer arrived.'));
|
|
83
|
+
}
|
|
84
|
+
pending.set(callId, {
|
|
85
|
+
batch,
|
|
86
|
+
items,
|
|
87
|
+
resolve: (answer) => finish(answer),
|
|
88
|
+
abort: (error) => finish(undefined, error),
|
|
89
|
+
});
|
|
90
|
+
deps.push(pendingFrame(batch));
|
|
91
|
+
if (signal?.aborted) {
|
|
92
|
+
onAbort();
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
signal?.addEventListener('abort', onAbort);
|
|
96
|
+
void next().then((answer) => finish(answer), () => undefined);
|
|
97
|
+
});
|
|
98
|
+
};
|
|
99
|
+
const answer = (input) => {
|
|
100
|
+
const entry = pending.get(input.callId);
|
|
101
|
+
if (!entry)
|
|
102
|
+
return undefined;
|
|
103
|
+
if (!completeAnswer(entry.items, input.answers)) {
|
|
104
|
+
return {
|
|
105
|
+
ok: false,
|
|
106
|
+
code: 'bad-request',
|
|
107
|
+
message: 'The answer batch must name each question exactly once.',
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
pending.delete(input.callId);
|
|
111
|
+
entry.resolve({ answers: input.answers });
|
|
112
|
+
return { ok: true };
|
|
113
|
+
};
|
|
114
|
+
const on = ctx.on;
|
|
115
|
+
if (on) {
|
|
116
|
+
off = on.call(ctx, 'user-questions/request', handle, { prepend: true, global: true });
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
answer,
|
|
120
|
+
pendingBatches() {
|
|
121
|
+
return [...pending.values()].map((entry) => entry.batch);
|
|
122
|
+
},
|
|
123
|
+
counts() {
|
|
124
|
+
const counts = new Map();
|
|
125
|
+
for (const entry of pending.values()) {
|
|
126
|
+
counts.set(entry.batch.sessionId, (counts.get(entry.batch.sessionId) ?? 0) + 1);
|
|
127
|
+
}
|
|
128
|
+
return counts;
|
|
129
|
+
},
|
|
130
|
+
dispose() {
|
|
131
|
+
off?.();
|
|
132
|
+
off = undefined;
|
|
133
|
+
for (const entry of [...pending.values()]) {
|
|
134
|
+
entry.abort(new Error('The question bridge was disposed.'));
|
|
135
|
+
}
|
|
136
|
+
pending.clear();
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=question-bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"question-bridge.js","sourceRoot":"","sources":["../../src/dsh/question-bridge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { QuestionAnswerItem, QuestionBatch, QuestionItem } from '@deepseekharness-mobile/protocol';
|
|
2
|
+
import { type HostContext } from '../host-api.js';
|
|
3
|
+
export declare function toQuestionItem(raw: unknown): QuestionItem | undefined;
|
|
4
|
+
export declare function listPendingQuestions(ctx: HostContext): QuestionBatch[];
|
|
5
|
+
export interface AnswerOutcome {
|
|
6
|
+
ok: boolean;
|
|
7
|
+
code?: 'not-found' | 'bad-request' | 'internal';
|
|
8
|
+
message?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function answerQuestion(ctx: HostContext, input: {
|
|
11
|
+
callId: string;
|
|
12
|
+
sessionId: string;
|
|
13
|
+
answers: QuestionAnswerItem[];
|
|
14
|
+
}): AnswerOutcome;
|
|
15
|
+
//# sourceMappingURL=questions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"questions.d.ts","sourceRoot":"","sources":["../../src/dsh/questions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,aAAa,EACb,YAAY,EAEb,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAEL,KAAK,WAAW,EAGjB,MAAM,gBAAgB,CAAC;AA8BxB,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,YAAY,GAAG,SAAS,CAgCrE;AAkDD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,WAAW,GAAG,aAAa,EAAE,CAatE;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,CAAC,EAAE,WAAW,GAAG,aAAa,GAAG,UAAU,CAAC;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,cAAc,CAC5B,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,kBAAkB,EAAE,CAAA;CAAE,GAC1E,aAAa,CAiCf"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { service, } from '../host-api.js';
|
|
2
|
+
function asString(value, fallback = '') {
|
|
3
|
+
return typeof value === 'string' ? value : fallback;
|
|
4
|
+
}
|
|
5
|
+
export function toQuestionItem(raw) {
|
|
6
|
+
if (typeof raw !== 'object' || raw === null)
|
|
7
|
+
return undefined;
|
|
8
|
+
const item = raw;
|
|
9
|
+
const id = asString(item.id);
|
|
10
|
+
const text = asString(item.question);
|
|
11
|
+
if (!id)
|
|
12
|
+
return undefined;
|
|
13
|
+
const options = Array.isArray(item.options)
|
|
14
|
+
? item.options
|
|
15
|
+
.map((option) => {
|
|
16
|
+
if (typeof option !== 'object' || option === null)
|
|
17
|
+
return undefined;
|
|
18
|
+
const record = option;
|
|
19
|
+
const label = asString(record.label);
|
|
20
|
+
if (!label)
|
|
21
|
+
return undefined;
|
|
22
|
+
const description = asString(record.description);
|
|
23
|
+
return { label, ...(description ? { description } : {}) };
|
|
24
|
+
})
|
|
25
|
+
.filter((option) => option !== undefined)
|
|
26
|
+
: [];
|
|
27
|
+
const intent = asString(item.intent);
|
|
28
|
+
return {
|
|
29
|
+
id,
|
|
30
|
+
text,
|
|
31
|
+
...(asString(item.detail) ? { detail: asString(item.detail) } : {}),
|
|
32
|
+
...(asString(item.header) ? { header: asString(item.header) } : {}),
|
|
33
|
+
options,
|
|
34
|
+
multiSelect: item.multiSelect === true,
|
|
35
|
+
allowCustom: intent !== 'approval',
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function toBatch(raw, sessionId) {
|
|
39
|
+
if (typeof raw !== 'object' || raw === null)
|
|
40
|
+
return undefined;
|
|
41
|
+
const pending = raw;
|
|
42
|
+
const callId = asString(pending.callId);
|
|
43
|
+
if (!callId)
|
|
44
|
+
return undefined;
|
|
45
|
+
const items = Array.isArray(pending.questions)
|
|
46
|
+
? pending.questions
|
|
47
|
+
.map(toQuestionItem)
|
|
48
|
+
.filter((item) => item !== undefined)
|
|
49
|
+
: [];
|
|
50
|
+
if (items.length === 0)
|
|
51
|
+
return undefined;
|
|
52
|
+
const state = pending.state === 'continued' ? 'continued' : 'open';
|
|
53
|
+
return {
|
|
54
|
+
callId,
|
|
55
|
+
sessionId,
|
|
56
|
+
state,
|
|
57
|
+
items,
|
|
58
|
+
createdAt: 0,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function pendingOf(ctx, sessionId, projections) {
|
|
62
|
+
const sessions = service(ctx, 'sessions');
|
|
63
|
+
const session = sessions?.get(sessionId);
|
|
64
|
+
if (!session)
|
|
65
|
+
return [];
|
|
66
|
+
try {
|
|
67
|
+
const view = projections.snapshot(session).values['userQuestions'];
|
|
68
|
+
const active = view?.active;
|
|
69
|
+
if (!Array.isArray(active))
|
|
70
|
+
return [];
|
|
71
|
+
return active
|
|
72
|
+
.map((raw) => toBatch(raw, sessionId))
|
|
73
|
+
.filter((batch) => batch !== undefined);
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return [];
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
export function listPendingQuestions(ctx) {
|
|
80
|
+
const projections = service(ctx, 'sessionProjections');
|
|
81
|
+
const sessions = service(ctx, 'sessions');
|
|
82
|
+
if (!projections || !sessions)
|
|
83
|
+
return [];
|
|
84
|
+
let ids;
|
|
85
|
+
try {
|
|
86
|
+
ids = sessions.list().map((session) => session.id);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return [];
|
|
90
|
+
}
|
|
91
|
+
return ids.flatMap((id) => pendingOf(ctx, id, projections));
|
|
92
|
+
}
|
|
93
|
+
export function answerQuestion(ctx, input) {
|
|
94
|
+
const userQuestions = service(ctx, 'userQuestions');
|
|
95
|
+
if (!userQuestions) {
|
|
96
|
+
return {
|
|
97
|
+
ok: false,
|
|
98
|
+
code: 'internal',
|
|
99
|
+
message: 'The host does not expose the questions service.',
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
const agents = service(ctx, 'agents');
|
|
103
|
+
const agent = agents?.get(input.sessionId);
|
|
104
|
+
if (!agent) {
|
|
105
|
+
return {
|
|
106
|
+
ok: false,
|
|
107
|
+
code: 'not-found',
|
|
108
|
+
message: 'The session is not loaded on the host. Open it on the desktop and try again.',
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
try {
|
|
112
|
+
const accepted = userQuestions.answer(agent, input.callId, { answers: input.answers });
|
|
113
|
+
if (!accepted) {
|
|
114
|
+
return {
|
|
115
|
+
ok: false,
|
|
116
|
+
code: 'bad-request',
|
|
117
|
+
message: 'That question no longer accepts an answer: the desktop may have answered it.',
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
return { ok: true };
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
return { ok: false, code: 'bad-request', message: String(error) };
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=questions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"questions.js","sourceRoot":"","sources":["../../src/dsh/questions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { SessionActivity } from '@deepseekharness-mobile/protocol';
|
|
2
|
+
import { type HostContext } from '../host-api.js';
|
|
3
|
+
export declare function activityAvailable(ctx: HostContext): boolean;
|
|
4
|
+
export declare function readSessionActivity(ctx: HostContext, sessionId: string): Promise<SessionActivity>;
|
|
5
|
+
//# sourceMappingURL=session-activity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-activity.d.ts","sourceRoot":"","sources":["../../src/dsh/session-activity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIV,eAAe,EAChB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAEL,KAAK,WAAW,EAKjB,MAAM,gBAAgB,CAAC;AAKxB,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAK3D;AAuFD,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,WAAW,EAChB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,eAAe,CAAC,CAiB1B"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { service, } from '../host-api.js';
|
|
2
|
+
const MAX_SUBAGENTS = 20;
|
|
3
|
+
const MAX_TODOS = 8;
|
|
4
|
+
export function activityAvailable(ctx) {
|
|
5
|
+
return (Boolean(service(ctx, 'sessionProjections')) &&
|
|
6
|
+
Boolean(service(ctx, 'sessions')));
|
|
7
|
+
}
|
|
8
|
+
function isRecord(value) {
|
|
9
|
+
return typeof value === 'object' && value !== null;
|
|
10
|
+
}
|
|
11
|
+
function goalOf(value) {
|
|
12
|
+
if (!isRecord(value))
|
|
13
|
+
return undefined;
|
|
14
|
+
const goal = isRecord(value['goal']) ? value['goal'] : value;
|
|
15
|
+
const objective = typeof goal['objective'] === 'string' ? goal['objective'] : undefined;
|
|
16
|
+
const phase = typeof goal['phase'] === 'string' ? goal['phase'] : undefined;
|
|
17
|
+
if (!objective || !phase)
|
|
18
|
+
return undefined;
|
|
19
|
+
const roundsStarted = typeof value['roundsStarted'] === 'number' && value['roundsStarted'] >= 0
|
|
20
|
+
? value['roundsStarted']
|
|
21
|
+
: 0;
|
|
22
|
+
const maxRounds = typeof goal['maxGoalRounds'] === 'number' && goal['maxGoalRounds'] > 0
|
|
23
|
+
? goal['maxGoalRounds']
|
|
24
|
+
: undefined;
|
|
25
|
+
return { objective, phase, roundsStarted, ...(maxRounds ? { maxRounds } : {}) };
|
|
26
|
+
}
|
|
27
|
+
function todosOf(value) {
|
|
28
|
+
if (!Array.isArray(value) || value.length === 0)
|
|
29
|
+
return undefined;
|
|
30
|
+
const items = [];
|
|
31
|
+
for (const raw of value) {
|
|
32
|
+
if (!isRecord(raw) || typeof raw['content'] !== 'string')
|
|
33
|
+
continue;
|
|
34
|
+
const status = raw['status'];
|
|
35
|
+
if (status !== 'pending' && status !== 'in_progress' && status !== 'completed')
|
|
36
|
+
continue;
|
|
37
|
+
items.push({ content: raw['content'], status });
|
|
38
|
+
}
|
|
39
|
+
if (items.length === 0)
|
|
40
|
+
return undefined;
|
|
41
|
+
return {
|
|
42
|
+
open: items.filter((item) => item.status !== 'completed').length,
|
|
43
|
+
total: items.length,
|
|
44
|
+
items: items.slice(0, MAX_TODOS),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function planActiveOf(value) {
|
|
48
|
+
return isRecord(value) && value['active'] === true;
|
|
49
|
+
}
|
|
50
|
+
async function subagentsOf(ctx, sessionId) {
|
|
51
|
+
const subagents = service(ctx, 'subagents');
|
|
52
|
+
if (!subagents || typeof subagents.listDescendants !== 'function')
|
|
53
|
+
return [];
|
|
54
|
+
try {
|
|
55
|
+
const entries = await subagents.listDescendants(sessionId, new AbortController().signal);
|
|
56
|
+
const rows = entries
|
|
57
|
+
.filter((entry) => entry.kind === 'child')
|
|
58
|
+
.map((entry) => ({
|
|
59
|
+
id: entry.id,
|
|
60
|
+
...(typeof entry.label === 'string' && entry.label ? { label: entry.label } : {}),
|
|
61
|
+
activity: entry.activity === 'running' ? 'running' : 'inactive',
|
|
62
|
+
depth: typeof entry.depth === 'number' && entry.depth > 0 ? entry.depth : 1,
|
|
63
|
+
...(entry.hasChildren !== undefined ? { hasChildren: entry.hasChildren } : {}),
|
|
64
|
+
}));
|
|
65
|
+
rows.sort((left, right) => {
|
|
66
|
+
if (left.activity !== right.activity)
|
|
67
|
+
return left.activity === 'running' ? -1 : 1;
|
|
68
|
+
return left.depth - right.depth;
|
|
69
|
+
});
|
|
70
|
+
return rows.slice(0, MAX_SUBAGENTS);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return [];
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function snapshotOf(projections, session) {
|
|
77
|
+
try {
|
|
78
|
+
return projections.snapshot(session).values;
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
export async function readSessionActivity(ctx, sessionId) {
|
|
85
|
+
const projections = service(ctx, 'sessionProjections');
|
|
86
|
+
const sessions = service(ctx, 'sessions');
|
|
87
|
+
const session = sessions?.get(sessionId);
|
|
88
|
+
const values = session && projections ? snapshotOf(projections, session) : undefined;
|
|
89
|
+
const goal = goalOf(values?.['goal']);
|
|
90
|
+
const todos = todosOf(values?.['todos']);
|
|
91
|
+
const planActive = planActiveOf(values?.['plan']);
|
|
92
|
+
const subagents = await subagentsOf(ctx, sessionId);
|
|
93
|
+
return {
|
|
94
|
+
...(goal ? { goal } : {}),
|
|
95
|
+
subagents,
|
|
96
|
+
...(todos ? { todos } : {}),
|
|
97
|
+
...(planActive ? { planActive } : {}),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=session-activity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-activity.js","sourceRoot":"","sources":["../../src/dsh/session-activity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ModelSelection, SessionSummary as WireSession } from '@deepseekharness-mobile/protocol';
|
|
2
|
+
import { type HostContext } from '../host-api.js';
|
|
3
|
+
export interface SessionRecord {
|
|
4
|
+
id: string;
|
|
5
|
+
title: string;
|
|
6
|
+
updatedAt: number;
|
|
7
|
+
seq: number;
|
|
8
|
+
agentAvailable: boolean;
|
|
9
|
+
running: boolean;
|
|
10
|
+
pendingQuestions: number;
|
|
11
|
+
workspaceId?: string;
|
|
12
|
+
model?: ModelSelection;
|
|
13
|
+
archived?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare function listSessions(ctx: HostContext, options?: {
|
|
16
|
+
includeArchived?: boolean;
|
|
17
|
+
}): Promise<SessionRecord[]>;
|
|
18
|
+
export declare function toWireSession(record: SessionRecord): WireSession;
|
|
19
|
+
//# sourceMappingURL=session-source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-source.d.ts","sourceRoot":"","sources":["../../src/dsh/session-source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EAEd,cAAc,IAAI,WAAW,EAC9B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAEL,KAAK,WAAW,EAGjB,MAAM,gBAAgB,CAAC;AAIxB,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA4DD,wBAAsB,YAAY,CAChC,GAAG,EAAE,WAAW,EAChB,OAAO,GAAE;IAAE,eAAe,CAAC,EAAE,OAAO,CAAA;CAAO,GAC1C,OAAO,CAAC,aAAa,EAAE,CAAC,CAuD1B;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,WAAW,CAYhE"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { service, } from '../host-api.js';
|
|
2
|
+
import { listArchivedSessions, listWorkspaces } from './workspaces.js';
|
|
3
|
+
import { selectionOf } from './models.js';
|
|
4
|
+
const MAX_SESSIONS = 200;
|
|
5
|
+
function countPending(snapshot) {
|
|
6
|
+
if (typeof snapshot !== 'object' || snapshot === null)
|
|
7
|
+
return 0;
|
|
8
|
+
const active = snapshot.active;
|
|
9
|
+
return Array.isArray(active) ? active.length : 0;
|
|
10
|
+
}
|
|
11
|
+
function pendingFor(ctx, sessionId, projections) {
|
|
12
|
+
if (!projections)
|
|
13
|
+
return 0;
|
|
14
|
+
const sessions = service(ctx, 'sessions');
|
|
15
|
+
const session = sessions?.get(sessionId);
|
|
16
|
+
if (!session)
|
|
17
|
+
return 0;
|
|
18
|
+
try {
|
|
19
|
+
return countPending(projections.snapshot(session).values['userQuestions']);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return 0;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function modelFor(item) {
|
|
26
|
+
const snapshot = item.projections?.values?.['modelSelection'];
|
|
27
|
+
if (typeof snapshot !== 'object' || snapshot === null)
|
|
28
|
+
return undefined;
|
|
29
|
+
const record = snapshot;
|
|
30
|
+
return selectionOf(record['next']) ?? selectionOf(record['lastUsed']) ?? selectionOf(record);
|
|
31
|
+
}
|
|
32
|
+
function wireState(record) {
|
|
33
|
+
if (record.pendingQuestions > 0)
|
|
34
|
+
return 'waiting';
|
|
35
|
+
if (record.running)
|
|
36
|
+
return 'working';
|
|
37
|
+
return 'idle';
|
|
38
|
+
}
|
|
39
|
+
export async function listSessions(ctx, options = {}) {
|
|
40
|
+
const controller = service(ctx, 'sessionController');
|
|
41
|
+
if (!controller || typeof controller.list !== 'function')
|
|
42
|
+
return [];
|
|
43
|
+
const projections = service(ctx, 'sessionProjections');
|
|
44
|
+
let items;
|
|
45
|
+
try {
|
|
46
|
+
const result = await controller.list({}, new AbortController().signal);
|
|
47
|
+
items = result?.items ?? [];
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
const records = items
|
|
53
|
+
.slice(0, MAX_SESSIONS)
|
|
54
|
+
.map((item) => {
|
|
55
|
+
const id = typeof item.sessionId === 'string' ? item.sessionId : '';
|
|
56
|
+
const titleValue = item.projections?.values?.['title'];
|
|
57
|
+
const pendingQuestions = id ? pendingFor(ctx, id, projections) : 0;
|
|
58
|
+
const model = id ? modelFor(item) : undefined;
|
|
59
|
+
return {
|
|
60
|
+
id,
|
|
61
|
+
title: typeof titleValue === 'string' && titleValue.trim() ? titleValue.trim() : 'Untitled',
|
|
62
|
+
updatedAt: typeof item.updatedAt === 'number' ? item.updatedAt : 0,
|
|
63
|
+
seq: typeof item.projections?.asOfSeq === 'number' ? item.projections.asOfSeq : 0,
|
|
64
|
+
agentAvailable: item.agentAvailable === true,
|
|
65
|
+
running: item.running === true,
|
|
66
|
+
pendingQuestions,
|
|
67
|
+
...(model ? { model } : {}),
|
|
68
|
+
};
|
|
69
|
+
})
|
|
70
|
+
.filter((record) => record.id !== '');
|
|
71
|
+
try {
|
|
72
|
+
const workspaces = await listWorkspaces(ctx);
|
|
73
|
+
const folderOf = new Map();
|
|
74
|
+
for (const workspace of workspaces) {
|
|
75
|
+
for (const sessionId of workspace.sessionIds)
|
|
76
|
+
folderOf.set(sessionId, workspace.id);
|
|
77
|
+
}
|
|
78
|
+
for (const record of records) {
|
|
79
|
+
const folder = folderOf.get(record.id);
|
|
80
|
+
if (folder)
|
|
81
|
+
record.workspaceId = folder;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch { }
|
|
85
|
+
const archived = await listArchivedSessions(ctx).catch(() => new Set());
|
|
86
|
+
const visible = options.includeArchived === true
|
|
87
|
+
? records.map((record) => (archived.has(record.id) ? { ...record, archived: true } : record))
|
|
88
|
+
: records.filter((record) => !archived.has(record.id));
|
|
89
|
+
return visible.sort((a, b) => b.updatedAt - a.updatedAt);
|
|
90
|
+
}
|
|
91
|
+
export function toWireSession(record) {
|
|
92
|
+
return {
|
|
93
|
+
id: record.id,
|
|
94
|
+
title: record.title,
|
|
95
|
+
state: wireState(record),
|
|
96
|
+
updatedAt: record.updatedAt,
|
|
97
|
+
seq: record.seq,
|
|
98
|
+
pendingQuestions: record.pendingQuestions,
|
|
99
|
+
...(record.workspaceId ? { workspaceId: record.workspaceId } : {}),
|
|
100
|
+
...(record.model ? { model: record.model } : {}),
|
|
101
|
+
...(record.archived ? { archived: true } : {}),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=session-source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-source.js","sourceRoot":"","sources":["../../src/dsh/session-source.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type HostContext } from '../host-api.js';
|
|
2
|
+
export type SessionResolution = {
|
|
3
|
+
ok: true;
|
|
4
|
+
id: string;
|
|
5
|
+
} | {
|
|
6
|
+
ok: false;
|
|
7
|
+
error: string;
|
|
8
|
+
};
|
|
9
|
+
export declare function resolveSessionId(ctx: HostContext, raw: string): SessionResolution;
|
|
10
|
+
//# sourceMappingURL=sessions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../src/dsh/sessions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,WAAW,EAAwB,MAAM,gBAAgB,CAAC;AAEjF,MAAM,MAAM,iBAAiB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AASxF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,GAAG,iBAAiB,CA0CjF"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { service } from '../host-api.js';
|
|
2
|
+
function clean(raw) {
|
|
3
|
+
return raw
|
|
4
|
+
.replace(/[<>"'`]/g, '')
|
|
5
|
+
.replace(/\s+/g, '')
|
|
6
|
+
.trim();
|
|
7
|
+
}
|
|
8
|
+
export function resolveSessionId(ctx, raw) {
|
|
9
|
+
const wanted = clean(raw);
|
|
10
|
+
if (!wanted)
|
|
11
|
+
return { ok: false, error: 'Missing the session identifier.' };
|
|
12
|
+
const sessions = service(ctx, 'sessions');
|
|
13
|
+
if (!sessions)
|
|
14
|
+
return { ok: false, error: 'The sessions service is not available.' };
|
|
15
|
+
let ids;
|
|
16
|
+
try {
|
|
17
|
+
ids = sessions.list().map((session) => session.id);
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
return { ok: false, error: `Could not list the sessions: ${String(error)}` };
|
|
21
|
+
}
|
|
22
|
+
if (/^\d+$/.test(wanted)) {
|
|
23
|
+
const index = Number(wanted) - 1;
|
|
24
|
+
const chosen = ids[index];
|
|
25
|
+
if (chosen)
|
|
26
|
+
return { ok: true, id: chosen };
|
|
27
|
+
return {
|
|
28
|
+
ok: false,
|
|
29
|
+
error: `No session number ${wanted}. There are ${ids.length}:\n${ids.map((id, i) => `${i + 1}) ${id}`).join('\n')}`,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
if (ids.includes(wanted))
|
|
33
|
+
return { ok: true, id: wanted };
|
|
34
|
+
const prefixed = wanted.startsWith('session-') ? wanted : `session-${wanted}`;
|
|
35
|
+
if (ids.includes(prefixed))
|
|
36
|
+
return { ok: true, id: prefixed };
|
|
37
|
+
const matches = ids.filter((id) => id.includes(wanted));
|
|
38
|
+
if (matches.length === 1)
|
|
39
|
+
return { ok: true, id: matches[0] };
|
|
40
|
+
if (matches.length > 1) {
|
|
41
|
+
return {
|
|
42
|
+
ok: false,
|
|
43
|
+
error: `"${wanted}" is ambiguous and matches ${matches.length} sessions:\n${matches.join('\n')}`,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
ok: false,
|
|
48
|
+
error: `No session matches "${wanted}".\nLive sessions:\n${ids.join('\n') || '(none)'}`,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=sessions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/dsh/sessions.ts"],"names":[],"mappings":"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"}
|