@deepseek-harness-tui/dsh-tui 0.11.2 → 0.12.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/README.md +21 -5
- package/bin/dsh-tui.js +30 -3
- package/cordis.patch.yml +24 -5
- package/guide/dsh-tui-guide/SKILL.md +37 -0
- package/guide/dsh-tui-guide/configuration.en.md +410 -0
- package/guide/dsh-tui-guide/configuration.md +349 -0
- package/guide/dsh-tui-guide/getting-started.en.md +398 -0
- package/guide/dsh-tui-guide/getting-started.md +397 -0
- package/guide/dsh-tui-guide/interaction.en.md +674 -0
- package/guide/dsh-tui-guide/interaction.md +747 -0
- package/guide/dsh-tui-guide/migrate.en.md +166 -0
- package/guide/dsh-tui-guide/migrate.md +132 -0
- package/guide/dsh-tui-guide/plugins.en.md +68 -0
- package/guide/dsh-tui-guide/plugins.md +56 -0
- package/guide/dsh-tui-guide/themes.en.md +192 -0
- package/guide/dsh-tui-guide/themes.md +185 -0
- package/guide/dsh-tui-guide/user-guide.en.md +608 -0
- package/guide/dsh-tui-guide/user-guide.md +586 -0
- package/guide/dsh-tui-guide/vscode.en.md +301 -0
- package/guide/dsh-tui-guide/vscode.md +272 -0
- package/lib/settings.json +5 -5
- package/lib/types/adapter/channel/ui-policy.d.ts +3 -2
- package/lib/types/adapter/channel/ui-policy.d.ts.map +1 -1
- package/lib/types/adapter/channel/ui-policy.js +4 -0
- package/lib/types/adapter/ports/channel-settings.d.ts +2 -1
- package/lib/types/adapter/ports/channel-settings.d.ts.map +1 -1
- package/lib/types/adapter/ports/channel-ui.d.ts +29 -2
- package/lib/types/adapter/ports/channel-ui.d.ts.map +1 -1
- package/lib/types/adapter/ports/channel-view.d.ts +43 -9
- package/lib/types/adapter/ports/channel-view.d.ts.map +1 -1
- package/lib/types/components/Chat/JobCard.d.ts +9 -0
- package/lib/types/components/Chat/JobCard.d.ts.map +1 -1
- package/lib/types/components/Chat/JobCard.js +42 -15
- package/lib/types/components/Chat/SubagentMessage.js +6 -6
- package/lib/types/components/JobsPanel.d.ts.map +1 -1
- package/lib/types/components/JobsPanel.js +80 -33
- package/lib/types/components/MessageList.js +3 -3
- package/lib/types/components/PresetPicker.d.ts +4 -0
- package/lib/types/components/PresetPicker.d.ts.map +1 -1
- package/lib/types/components/PresetPicker.js +5 -1
- package/lib/types/components/PromptInput.d.ts.map +1 -1
- package/lib/types/components/PromptInput.js +12 -1
- package/lib/types/components/StarPrompt.d.ts +6 -0
- package/lib/types/components/StarPrompt.d.ts.map +1 -1
- package/lib/types/components/StarPrompt.js +45 -0
- package/lib/types/components/SubagentCard.d.ts.map +1 -1
- package/lib/types/components/SubagentCard.js +8 -8
- package/lib/types/components/SubagentDetailScene.d.ts.map +1 -1
- package/lib/types/components/SubagentDetailScene.js +108 -10
- package/lib/types/components/WhaleGirl.d.ts +6 -0
- package/lib/types/components/WhaleGirl.d.ts.map +1 -1
- package/lib/types/components/WhaleGirl.js +18 -0
- package/lib/types/components/messages/AssistantThinkingMessage.js +4 -4
- package/lib/types/components/trajectory/MiniWake.d.ts +11 -1
- package/lib/types/components/trajectory/MiniWake.d.ts.map +1 -1
- package/lib/types/components/trajectory/MiniWake.js +9 -3
- package/lib/types/dsh-adapter/channel/external-commands.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/external-commands.js +8 -2
- package/lib/types/dsh-adapter/channel/job-projection.d.ts +1 -0
- package/lib/types/dsh-adapter/channel/job-projection.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/job-projection.js +88 -3
- package/lib/types/dsh-adapter/channel/mode-actions.d.ts +13 -0
- package/lib/types/dsh-adapter/channel/mode-actions.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/mode-actions.js +48 -7
- package/lib/types/dsh-adapter/channel/mode-permission-actions.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/mode-permission-actions.js +25 -9
- package/lib/types/dsh-adapter/channel/preferences.d.ts +1 -1
- package/lib/types/dsh-adapter/channel/preferences.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/preferences.js +17 -7
- package/lib/types/dsh-adapter/channel/state.d.ts +4 -2
- package/lib/types/dsh-adapter/channel/state.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/state.js +1 -1
- package/lib/types/dsh-adapter/channel/subagent-projection.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/subagent-projection.js +5 -0
- package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel.js +16 -1
- package/lib/types/dsh-adapter/contract.d.ts +5 -4
- package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
- package/lib/types/dsh-adapter/contract.js +9 -3
- package/lib/types/dsh-adapter/jobs.d.ts +82 -16
- package/lib/types/dsh-adapter/jobs.d.ts.map +1 -1
- package/lib/types/dsh-adapter/jobs.js +104 -9
- package/lib/types/dsh-adapter/oauth/bonus.d.ts +27 -0
- package/lib/types/dsh-adapter/oauth/bonus.d.ts.map +1 -0
- package/lib/types/dsh-adapter/oauth/bonus.js +69 -0
- package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/command.d.ts +2 -1
- package/lib/types/dsh-adapter/oauth/command.d.ts.map +1 -0
- package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/command.js +7 -4
- package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/credentials.d.ts +13 -10
- package/lib/types/dsh-adapter/oauth/credentials.d.ts.map +1 -0
- package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/credentials.js +61 -23
- package/lib/types/dsh-adapter/oauth/deepseek.d.ts +39 -0
- package/lib/types/dsh-adapter/oauth/deepseek.d.ts.map +1 -0
- package/lib/types/dsh-adapter/oauth/deepseek.js +189 -0
- package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/index.d.ts +24 -16
- package/lib/types/dsh-adapter/oauth/index.d.ts.map +1 -0
- package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/index.js +34 -20
- package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/interaction.d.ts +14 -12
- package/lib/types/dsh-adapter/oauth/interaction.d.ts.map +1 -0
- package/lib/types/dsh-adapter/oauth/interaction.js +283 -0
- package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/opener.d.ts +2 -1
- package/lib/types/dsh-adapter/oauth/opener.d.ts.map +1 -0
- package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/opener.js +1 -1
- package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/pi-ai.d.ts +10 -3
- package/lib/types/dsh-adapter/oauth/pi-ai.d.ts.map +1 -0
- package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/pi-ai.js +8 -3
- package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/profiles.d.ts +6 -3
- package/lib/types/dsh-adapter/oauth/profiles.d.ts.map +1 -0
- package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/profiles.js +11 -3
- package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/service.d.ts +14 -7
- package/lib/types/dsh-adapter/oauth/service.d.ts.map +1 -0
- package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/service.js +82 -17
- package/lib/types/dsh-adapter/plugin.d.ts +8 -1
- package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin.js +72 -12
- package/lib/types/dsh-adapter/presets.d.ts +6 -4
- package/lib/types/dsh-adapter/presets.d.ts.map +1 -1
- package/lib/types/dsh-adapter/presets.js +6 -4
- package/lib/types/dsh-adapter/providerWizard.d.ts.map +1 -1
- package/lib/types/dsh-adapter/providerWizard.js +6 -2
- package/lib/types/dsh-adapter/subagents.d.ts +1 -0
- package/lib/types/dsh-adapter/subagents.d.ts.map +1 -1
- package/lib/types/dsh-adapter/subagents.js +10 -1
- package/lib/types/i18n.d.ts +174 -18
- package/lib/types/i18n.d.ts.map +1 -1
- package/lib/types/i18n.js +53 -11
- package/lib/types/ink/components/App.d.ts.map +1 -1
- package/lib/types/ink/components/App.js +10 -1
- package/lib/types/ink/parse-keypress.d.ts +35 -0
- package/lib/types/ink/parse-keypress.d.ts.map +1 -1
- package/lib/types/ink/parse-keypress.js +611 -83
- package/lib/types/ink/terminal-querier.d.ts +25 -0
- package/lib/types/ink/terminal-querier.d.ts.map +1 -1
- package/lib/types/ink/terminal-querier.js +42 -0
- package/lib/types/ink/update-overflow-guard.d.ts +24 -0
- package/lib/types/ink/update-overflow-guard.d.ts.map +1 -1
- package/lib/types/ink/update-overflow-guard.js +25 -3
- package/lib/types/minimalUiMode.d.ts +19 -0
- package/lib/types/minimalUiMode.d.ts.map +1 -0
- package/lib/types/minimalUiMode.js +23 -0
- package/lib/types/oauth.d.ts +5 -10
- package/lib/types/oauth.d.ts.map +1 -1
- package/lib/types/oauth.js +5 -10
- package/lib/types/screens/Chat.d.ts +4 -1
- package/lib/types/screens/Chat.d.ts.map +1 -1
- package/lib/types/screens/Chat.js +27 -7
- package/lib/types/screens/StatusLine.d.ts +4 -0
- package/lib/types/screens/StatusLine.d.ts.map +1 -1
- package/lib/types/screens/StatusLine.js +12 -12
- package/lib/types/settings/definitions.js +4 -4
- package/lib/types/tips.d.ts.map +1 -1
- package/lib/types/tips.js +10 -4
- package/lib/types/update.js +2 -2
- package/lib/types/utils/pastedImagePath.d.ts +8 -0
- package/lib/types/utils/pastedImagePath.d.ts.map +1 -1
- package/lib/types/utils/pastedImagePath.js +29 -5
- package/package.json +111 -100
- package/presets/liangshen/agent.cordis.yml +4 -1
- package/presets/liangshen/preset.yml +1 -1
- package/lib/types/minimalMode.d.ts +0 -13
- package/lib/types/minimalMode.d.ts.map +0 -1
- package/lib/types/minimalMode.js +0 -17
- package/node_modules/@deepseek-harness-tui/dsh-auth/LICENSE +0 -21
- package/node_modules/@deepseek-harness-tui/dsh-auth/README.md +0 -143
- package/node_modules/@deepseek-harness-tui/dsh-auth/cordis.patch.yml +0 -11
- package/node_modules/@deepseek-harness-tui/dsh-auth/dsh-plugin.json +0 -44
- package/node_modules/@deepseek-harness-tui/dsh-auth/lib/interaction.js +0 -193
- package/node_modules/@deepseek-harness-tui/dsh-auth/package.json +0 -69
package/{node_modules/@deepseek-harness-tui/dsh-auth/lib → lib/types/dsh-adapter/oauth}/service.js
RENAMED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The `ctx.dshAuth` service: the programmatic surface over this
|
|
2
|
+
* The `ctx.dshAuth` service: the programmatic surface over this module's
|
|
3
3
|
* mounted OAuth routes. UIs (the dsh-tui /provider wizard, a web settings
|
|
4
4
|
* page) enumerate providers with masked sign-in state and drive login/logout
|
|
5
5
|
* without touching the credential file or the pi-ai flow objects; the `/auth`
|
|
6
6
|
* command in `command.ts` is a thin textual veneer over the same api.
|
|
7
7
|
*
|
|
8
|
-
* @module dsh-
|
|
8
|
+
* @module @deepseek-harness-tui/dsh-tui/oauth/service
|
|
9
9
|
*/
|
|
10
10
|
import { Service } from '@deepseek-ai/cordis';
|
|
11
11
|
import { asStoredCredential } from './credentials.js';
|
|
12
12
|
import { oauthOf } from './profiles.js';
|
|
13
13
|
import { QuestionBridge } from './interaction.js';
|
|
14
|
+
import { loginOAuth } from './pi-ai.js';
|
|
15
|
+
import { DEEPSEEK_ACCOUNT_PROVIDER, deepSeekClientMetadata, loginDeepSeekAccount, } from './deepseek.js';
|
|
16
|
+
import { WhaleCouponStore } from './bonus.js';
|
|
14
17
|
/**
|
|
15
18
|
* The constructed catalog provider one mounted route carries. 0.1.5 made
|
|
16
19
|
* `ResolvedPiAiProviderProfile.piProvider` optional (a stored route that
|
|
@@ -27,6 +30,7 @@ function mountedProvider(profile) {
|
|
|
27
30
|
/** Cordis service holder; `api` is set by the plugin's apply. */
|
|
28
31
|
export class DshAuthService extends Service {
|
|
29
32
|
api;
|
|
33
|
+
coupons = new WhaleCouponStore();
|
|
30
34
|
constructor(ctx) {
|
|
31
35
|
super(ctx, 'dshAuth');
|
|
32
36
|
}
|
|
@@ -56,9 +60,13 @@ async function chooseProvider(ask, candidates, signal) {
|
|
|
56
60
|
*/
|
|
57
61
|
export function createDshAuthApi(deps) {
|
|
58
62
|
const inflight = new Map();
|
|
63
|
+
const mountedIds = () => [
|
|
64
|
+
...deps.profiles.keys(),
|
|
65
|
+
...(deps.resolveDeepSeekAccount?.() === undefined ? [] : [DEEPSEEK_ACCOUNT_PROVIDER]),
|
|
66
|
+
];
|
|
59
67
|
const statusOf = async () => {
|
|
60
68
|
const described = new Map((await deps.store.describe()).map(row => [row.provider, row]));
|
|
61
|
-
|
|
69
|
+
const piAi = [...deps.profiles.entries()].map(([id, profile]) => {
|
|
62
70
|
const oauth = oauthOf(mountedProvider(profile));
|
|
63
71
|
const row = described.get(id);
|
|
64
72
|
return {
|
|
@@ -71,32 +79,55 @@ export function createDshAuthApi(deps) {
|
|
|
71
79
|
expired: row?.expired ?? false,
|
|
72
80
|
};
|
|
73
81
|
});
|
|
82
|
+
const account = deps.resolveDeepSeekAccount?.();
|
|
83
|
+
if (account === undefined)
|
|
84
|
+
return piAi;
|
|
85
|
+
const state = await account.getState();
|
|
86
|
+
return [{
|
|
87
|
+
provider: DEEPSEEK_ACCOUNT_PROVIDER,
|
|
88
|
+
label: 'DeepSeek Account',
|
|
89
|
+
oauthLabel: 'DeepSeek',
|
|
90
|
+
loginLabel: 'Sign in with DeepSeek',
|
|
91
|
+
signedIn: state.status === 'credential-stored',
|
|
92
|
+
expiresAt: undefined,
|
|
93
|
+
expired: false,
|
|
94
|
+
}, ...piAi];
|
|
74
95
|
};
|
|
75
96
|
const loginOne = async (provider, ask, signal) => {
|
|
76
97
|
const profile = deps.profiles.get(provider);
|
|
77
98
|
if (profile === undefined) {
|
|
78
|
-
throw new Error(`dsh-auth: unknown provider "${provider}" (mounted: ${
|
|
99
|
+
throw new Error(`dsh-auth: unknown provider "${provider}" (mounted: ${mountedIds().join(', ')})`);
|
|
79
100
|
}
|
|
80
101
|
const oauth = oauthOf(mountedProvider(profile));
|
|
81
102
|
const runAbort = new AbortController();
|
|
103
|
+
const forwardAbort = () => runAbort.abort(signal?.reason);
|
|
82
104
|
if (signal !== undefined) {
|
|
83
105
|
if (signal.aborted)
|
|
84
|
-
|
|
106
|
+
forwardAbort();
|
|
85
107
|
else
|
|
86
|
-
signal.addEventListener('abort',
|
|
108
|
+
signal.addEventListener('abort', forwardAbort, { once: true });
|
|
87
109
|
}
|
|
88
110
|
const bridge = new QuestionBridge(ask, runAbort);
|
|
89
111
|
try {
|
|
90
|
-
|
|
112
|
+
runAbort.signal.throwIfAborted();
|
|
113
|
+
const returned = await loginOAuth(oauth, bridge, {
|
|
114
|
+
// pi-ai 0.87.1's `openai` flow needs this on login. Older flows
|
|
115
|
+
// ignore the optional context, so the ID is created only on demand.
|
|
116
|
+
getDeviceId: () => deps.store.getOrCreateDeviceId(),
|
|
117
|
+
});
|
|
91
118
|
const normalized = asStoredCredential(returned);
|
|
92
119
|
if (normalized === undefined) {
|
|
93
120
|
throw new Error(`dsh-auth: the ${oauth.name} flow returned an unusable credential; nothing was stored`);
|
|
94
121
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
122
|
+
await deps.store.modify(provider, async () => {
|
|
123
|
+
// Logout may have cancelled the flow while this write waited for the file lock.
|
|
124
|
+
runAbort.signal.throwIfAborted();
|
|
125
|
+
return normalized;
|
|
126
|
+
});
|
|
127
|
+
return { provider, oauthLabel: oauth.name, expiresAt: normalized.expires };
|
|
98
128
|
}
|
|
99
129
|
finally {
|
|
130
|
+
signal?.removeEventListener('abort', forwardAbort);
|
|
100
131
|
await bridge.settle();
|
|
101
132
|
}
|
|
102
133
|
};
|
|
@@ -115,24 +146,58 @@ export function createDshAuthApi(deps) {
|
|
|
115
146
|
throw new Error('dsh-auth: every mounted provider is already signed in');
|
|
116
147
|
target = await chooseProvider(ask, candidates, signal);
|
|
117
148
|
}
|
|
118
|
-
else if (!
|
|
119
|
-
throw new Error(`dsh-auth: unknown provider "${target}" (mounted: ${
|
|
149
|
+
else if (!mountedIds().includes(target)) {
|
|
150
|
+
throw new Error(`dsh-auth: unknown provider "${target}" (mounted: ${mountedIds().join(', ')})`);
|
|
120
151
|
}
|
|
121
152
|
if (ask === undefined) {
|
|
122
153
|
throw new Error(`dsh-auth: signing in to "${target}" needs an interactive surface (run inside dsh-tui or the web client); `
|
|
123
154
|
+ 'this plugin refuses to assume a browser on this machine');
|
|
124
155
|
}
|
|
125
|
-
|
|
126
|
-
if (existing !== undefined) {
|
|
156
|
+
if (inflight.has(target)) {
|
|
127
157
|
throw new Error(`dsh-auth: a login for "${target}" is already running`);
|
|
128
158
|
}
|
|
129
|
-
const
|
|
130
|
-
|
|
159
|
+
const account = target === DEEPSEEK_ACCOUNT_PROVIDER ? deps.resolveDeepSeekAccount?.() : undefined;
|
|
160
|
+
if (target === DEEPSEEK_ACCOUNT_PROVIDER && account === undefined) {
|
|
161
|
+
throw new Error(`dsh-auth: provider "${target}" is no longer mounted`);
|
|
162
|
+
}
|
|
163
|
+
const cancellation = new AbortController();
|
|
164
|
+
const runSignal = signal === undefined ? cancellation.signal : AbortSignal.any([signal, cancellation.signal]);
|
|
165
|
+
inflight.set(target, cancellation);
|
|
166
|
+
const run = (account === undefined
|
|
167
|
+
? loginOne(target, ask, runSignal)
|
|
168
|
+
: (async () => {
|
|
169
|
+
runSignal.throwIfAborted();
|
|
170
|
+
const callbackOrigin = await deps.resolveCallbackOrigin?.();
|
|
171
|
+
runSignal.throwIfAborted();
|
|
172
|
+
if (callbackOrigin === undefined) {
|
|
173
|
+
throw new Error('DeepSeek sign-in needs an active Host webServer for the browser callback');
|
|
174
|
+
}
|
|
175
|
+
await loginDeepSeekAccount(account, callbackOrigin, ask, runSignal);
|
|
176
|
+
deps.coupons?.clear();
|
|
177
|
+
const getUnnotifiedBonuses = account.getUnnotifiedBonuses?.bind(account);
|
|
178
|
+
const ackBonusNotified = account.ackBonusNotified?.bind(account);
|
|
179
|
+
if (getUnnotifiedBonuses !== undefined && ackBonusNotified !== undefined) {
|
|
180
|
+
void deps.coupons?.refresh({ getUnnotifiedBonuses, ackBonusNotified });
|
|
181
|
+
}
|
|
182
|
+
return { provider: target, oauthLabel: 'DeepSeek', expiresAt: undefined };
|
|
183
|
+
})()).finally(() => { inflight.delete(target); });
|
|
131
184
|
return run;
|
|
132
185
|
},
|
|
133
186
|
logout: async (provider) => {
|
|
187
|
+
// A DeepSeek login may still be awaiting its callback listener, before
|
|
188
|
+
// the Host has an attempt to cancel. Abort it before Host sign-out.
|
|
189
|
+
inflight.get(provider)?.abort(new Error('Login cancelled'));
|
|
190
|
+
if (provider === DEEPSEEK_ACCOUNT_PROVIDER) {
|
|
191
|
+
const account = deps.resolveDeepSeekAccount?.();
|
|
192
|
+
if (account !== undefined) {
|
|
193
|
+
const existed = (await account.getState()).status === 'credential-stored';
|
|
194
|
+
await account.signOut(deepSeekClientMetadata());
|
|
195
|
+
deps.coupons?.clear();
|
|
196
|
+
return existed;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
134
199
|
if (!deps.profiles.has(provider)) {
|
|
135
|
-
throw new Error(`dsh-auth: unknown provider "${provider}" (mounted: ${
|
|
200
|
+
throw new Error(`dsh-auth: unknown provider "${provider}" (mounted: ${mountedIds().join(', ')})`);
|
|
136
201
|
}
|
|
137
202
|
const existed = (await deps.store.read(provider)) !== undefined;
|
|
138
203
|
await deps.store.delete(provider);
|
|
@@ -43,7 +43,14 @@ export declare function apply(ctx: Context, runtimeConfig: RuntimeConfig<Config>
|
|
|
43
43
|
export declare function createExitFunnel(deps: {
|
|
44
44
|
onUserExit: (error?: unknown) => void;
|
|
45
45
|
}): {
|
|
46
|
-
|
|
46
|
+
/**
|
|
47
|
+
* Settle the exit once.
|
|
48
|
+
* @returns true when this call ran the user-exit path (the funnel now owns
|
|
49
|
+
* the process), false when it was already settled or the tree is being
|
|
50
|
+
* torn down. A process-level crash backstop must fall back to Node's
|
|
51
|
+
* default crash on false instead of swallowing the error.
|
|
52
|
+
*/
|
|
53
|
+
handleExit: (error?: unknown) => boolean;
|
|
47
54
|
markTeardown: () => void;
|
|
48
55
|
};
|
|
49
56
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/plugin.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAe,MAAM,wBAAwB,CAAA;AAGhE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAGlD,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AACnC,OAAO,EAA+D,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/plugin.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAe,MAAM,wBAAwB,CAAA;AAGhE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAGlD,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AACnC,OAAO,EAA+D,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAyDtH,OAAO,EAAE,MAAM,EAAkC,MAAM,UAAU,CAAA;AAmCjE;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GAAG,MAAM,CAsBxF;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,yBAAyB,GAAG,eAAe,CAAA;AAErF,wBAAgB,kBAAkB,CAChC,WAAW,UAAgC,EAC3C,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,WAAW,CASb;AAED,wBAAsB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,CAAC,MAAM,CAAC,EAAE,WAAW,GAAE,OAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAw8CzH;AAmMD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IAAE,UAAU,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;CAAE,GAAG;IACjF;;;;;;OAMG;IACH,UAAU,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,OAAO,CAAA;IACxC,YAAY,EAAE,MAAM,IAAI,CAAA;CACzB,CAeA;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE;IACpC,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,KAAK,GAAG,SAAS,CAAA;IAC5B,YAAY,EAAE,KAAK,CAAA;CACpB,GAAG,OAAO,CAQV;AAgBD;;;GAGG;AACH,wBAAsB,UAAU,CAC9B,GAAG,EAAE,OAAO,EACZ,QAAQ,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC,GAAG,SAAS,EACxD,UAAU,EAAE,OAAO,EACnB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,IAAI,EAAE,MAAM,IAAI,GACf,OAAO,CAAC,IAAI,CAAC,CAmFf;AA4HD,gFAAgF;AAChF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAIrE"}
|
|
@@ -61,6 +61,7 @@ import instances from '../ink/instances.js';
|
|
|
61
61
|
import { cursorMove, DISABLE_KITTY_KEYBOARD, DISABLE_MODIFY_OTHER_KEYS, DISABLE_WIN32_INPUT_MODE } from '../ink/termio/csi.js';
|
|
62
62
|
import { DBP, DFE, DISABLE_MOUSE_TRACKING, EXIT_ALT_SCREEN, SHOW_CURSOR } from '../ink/termio/dec.js';
|
|
63
63
|
import { CLEAR_ITERM2_PROGRESS, CLEAR_TAB_STATUS, supportsTabStatus, wrapForMultiplexer } from '../ink/termio/osc.js';
|
|
64
|
+
import { fatalReasonForExit, registerProcessGuardFatalSink } from '../ink/update-overflow-guard.js';
|
|
64
65
|
/**
|
|
65
66
|
* Interactive TUI front door for DeepSeek Harness agents.
|
|
66
67
|
*
|
|
@@ -274,10 +275,10 @@ export async function apply(ctx, runtimeConfig, configOwner = ctx) {
|
|
|
274
275
|
const userQuestions = ctx.get('userQuestions') ?? new UserQuestionService(ctx);
|
|
275
276
|
ctx.plugin(toolAskUser);
|
|
276
277
|
// The host-level tool mount above is intentional for the TUI and for user
|
|
277
|
-
// presets, but the official Minimal preset is a
|
|
278
|
-
//
|
|
279
|
-
// final assembly boundary. Reading the session on every assembly also
|
|
280
|
-
// blank-session /preset switches and resumed sessions behave correctly.
|
|
278
|
+
// presets, but the official Minimal preset is a single-tool trajectory (one
|
|
279
|
+
// persistent shell: bash on POSIX, pwsh on Windows). Filter only that preset
|
|
280
|
+
// at the final assembly boundary. Reading the session on every assembly also
|
|
281
|
+
// makes blank-session /preset switches and resumed sessions behave correctly.
|
|
281
282
|
ctx.on('system-prompt/assemble', async (_assembly, context, next) => {
|
|
282
283
|
const assembled = await next();
|
|
283
284
|
const presetId = context.agent === undefined ? undefined : runningPresetOf(context.agent.session);
|
|
@@ -431,7 +432,20 @@ export async function apply(ctx, runtimeConfig, configOwner = ctx) {
|
|
|
431
432
|
// reads the same records. There is deliberately no rail-side "add a
|
|
432
433
|
// workspace" control any more: a terminal's launch directory is the whole
|
|
433
434
|
// registration story.
|
|
434
|
-
|
|
435
|
+
//
|
|
436
|
+
// A RESUMED session is accounted where its OWN header cwd lives, never
|
|
437
|
+
// where this terminal was launched. The launch directory can be an
|
|
438
|
+
// ANCESTOR of the resumed session's: launching in `~/projects` and
|
|
439
|
+
// resuming a session recorded in `~/projects/app` accounts the same
|
|
440
|
+
// session in both workspaces, and the next boot dies inside
|
|
441
|
+
// `validateStoredState` ("session ... is accounted by both workspace
|
|
442
|
+
// ..."), which leaves `workspaceRegistry` unactivated and the whole TUI
|
|
443
|
+
// pending forever. Ownership must therefore agree with the `cwd:` handed
|
|
444
|
+
// to `createChannel` below, which already prefers the persisted header.
|
|
445
|
+
// Fresh sessions record `meta.cwd` at creation, so the launch directory
|
|
446
|
+
// still registers through them.
|
|
447
|
+
const ownershipCwd = agent.session.header.cwd ?? meta.cwd;
|
|
448
|
+
const attached = await attachSessionToWorkspace(ctx, ownershipCwd, agent.session.id);
|
|
435
449
|
if (!attached) {
|
|
436
450
|
ctx.logger.warn(`dsh-tui: session "${agent.session.id}" has no workspace ownership because workspaceRegistry is not mounted`);
|
|
437
451
|
}
|
|
@@ -670,8 +684,9 @@ export async function apply(ctx, runtimeConfig, configOwner = ctx) {
|
|
|
670
684
|
// (undefined → daily), so cordis.yml stays decisive and junk lands on
|
|
671
685
|
// daily.
|
|
672
686
|
splashFont: Schema.string(),
|
|
673
|
-
// Minimal
|
|
674
|
-
//
|
|
687
|
+
// Minimal UI (极简界面, settings key `minimal` — never renamed): strips
|
|
688
|
+
// the header splash, emoji glyphs, and decorative colors; code highlight
|
|
689
|
+
// and tool colors stay. Unrelated to the kernel agent preset `minimal`.
|
|
675
690
|
minimal: Schema.boolean().default(false),
|
|
676
691
|
// No default on purpose: an unset `lang` keeps the field showing
|
|
677
692
|
// the effective language (see the section's format below) and lets
|
|
@@ -714,10 +729,12 @@ export async function apply(ctx, runtimeConfig, configOwner = ctx) {
|
|
|
714
729
|
return;
|
|
715
730
|
channel.setSplashFont(normalizeSplashFont(value.splashFont ?? config.splashFont));
|
|
716
731
|
};
|
|
717
|
-
const
|
|
732
|
+
const applyMinimalUi = (value) => {
|
|
718
733
|
if (shadow)
|
|
719
734
|
return;
|
|
720
|
-
|
|
735
|
+
// `value.minimal` is the persisted settings key (never renamed); the
|
|
736
|
+
// channel member is the minimal-UI flag, NOT the kernel preset.
|
|
737
|
+
channel.setMinimalUi(value.minimal ?? false);
|
|
721
738
|
};
|
|
722
739
|
// Renderer settings are resolved before mount; later edits wait for restart.
|
|
723
740
|
const applyRendererSettings = (value) => {
|
|
@@ -802,7 +819,7 @@ export async function apply(ctx, runtimeConfig, configOwner = ctx) {
|
|
|
802
819
|
applyWhaleIdle(next);
|
|
803
820
|
applyWhaleGirl(next);
|
|
804
821
|
applySplashFont(next);
|
|
805
|
-
|
|
822
|
+
applyMinimalUi(next);
|
|
806
823
|
applyLang(next);
|
|
807
824
|
applyDisplay(next);
|
|
808
825
|
applyEffortDefault(next);
|
|
@@ -1190,6 +1207,24 @@ export async function apply(ctx, runtimeConfig, configOwner = ctx) {
|
|
|
1190
1207
|
if (error !== undefined) {
|
|
1191
1208
|
const message = error instanceof Error ? error.message : String(error);
|
|
1192
1209
|
ctx.logger.error(`dsh-tui: exit after error: ${message}`);
|
|
1210
|
+
// A crash must leave the resume marker a clean exit would leave: the
|
|
1211
|
+
// launcher's next start (and its safe-mode retry) then reopens the
|
|
1212
|
+
// session the user was actually in instead of a blank one. Only the
|
|
1213
|
+
// resumable case writes — unlike the clean-exit branch below, a crash
|
|
1214
|
+
// never CLEARS a marker, so a session the user still has cannot be
|
|
1215
|
+
// dropped by a failure that happened before the first message landed.
|
|
1216
|
+
try {
|
|
1217
|
+
if (isExitResumable({
|
|
1218
|
+
pendingCount: channel.pending.length,
|
|
1219
|
+
liveAgent: ctx.agents.get(SessionId(channel.agentId)),
|
|
1220
|
+
startupAgent: agent,
|
|
1221
|
+
})) {
|
|
1222
|
+
writeResumeTarget(channel.agentId);
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
catch {
|
|
1226
|
+
// Resume persistence is best effort and must never block the exit.
|
|
1227
|
+
}
|
|
1193
1228
|
void finishExit(ctx, instance, bootedFullscreen, undefined, `dsh-tui crashed: ${message}`, () => disposeRootAndExit(ctx, 1));
|
|
1194
1229
|
return;
|
|
1195
1230
|
}
|
|
@@ -1250,6 +1285,25 @@ export async function apply(ctx, runtimeConfig, configOwner = ctx) {
|
|
|
1250
1285
|
},
|
|
1251
1286
|
});
|
|
1252
1287
|
const handleExit = funnel.handleExit;
|
|
1288
|
+
// Process-level crash backstop (see installNestedUpdateOverflowProcessGuard):
|
|
1289
|
+
// an uncaught exception or unhandled rejection that is NOT the React #185
|
|
1290
|
+
// overflow would otherwise take Node's default path and kill the process
|
|
1291
|
+
// before this funnel runs — no resume marker, no terminal restore, and the
|
|
1292
|
+
// launcher's "entered safe mode" prompt on what looks like a lost session.
|
|
1293
|
+
// Route it through the same teardown a fatal RENDER error uses: unmount,
|
|
1294
|
+
// `dsh-tui crashed: …`, dispose, exit 1. Fail loud stays intact — the funnel
|
|
1295
|
+
// returns false when it has already settled or the tree is being torn down
|
|
1296
|
+
// (host recompose), and the guard then rethrows to Node's default crash.
|
|
1297
|
+
// DSH_TUI_NO_185_PROCESS_GUARD=1 skips the guard entirely, leaving process
|
|
1298
|
+
// error policy to the host exactly as before.
|
|
1299
|
+
registerProcessGuardFatalSink((error, origin) => {
|
|
1300
|
+
// An undefined reason (`Promise.reject()`, `throw undefined`) must not reach
|
|
1301
|
+
// the funnel as-is: `error !== undefined` is what selects the crash path, so
|
|
1302
|
+
// a bare undefined would exit 0 while this sink claims the process.
|
|
1303
|
+
const fatal = fatalReasonForExit(error, origin);
|
|
1304
|
+
ctx.logger.error(`dsh-tui: fatal ${origin}: ${fatal instanceof Error ? fatal.message : String(fatal)}`);
|
|
1305
|
+
return handleExit(fatal);
|
|
1306
|
+
});
|
|
1253
1307
|
// External injection controller: Chat fills it with `{ append, submit }`
|
|
1254
1308
|
// every render; the injection socket (opened below) drives it. A ref rather
|
|
1255
1309
|
// than a prop callback so the socket handler always reaches the live Chat.
|
|
@@ -1289,6 +1343,7 @@ export async function apply(ctx, runtimeConfig, configOwner = ctx) {
|
|
|
1289
1343
|
// shortcuts). Soft-consumed: absent the row (stale patch, bare embed),
|
|
1290
1344
|
// Chat falls back to inert stores and no shortcut registry.
|
|
1291
1345
|
extensionDialogs: getHostDialogStore(ctx.get('tuiDialogs')),
|
|
1346
|
+
bonusNotices: ctx.get('dshAuth')?.coupons,
|
|
1292
1347
|
extensionStatus: getHostStatusStore(ctx.get('tuiStatus')),
|
|
1293
1348
|
// The working line's semantics belong to the dsh-working-activity plugin's
|
|
1294
1349
|
// session projection; this store is the read side of that seam, so the TUI
|
|
@@ -1445,6 +1500,10 @@ export async function apply(ctx, runtimeConfig, configOwner = ctx) {
|
|
|
1445
1500
|
ctx.effect(() => () => {
|
|
1446
1501
|
logMouseDebug('apply teardown');
|
|
1447
1502
|
funnel.markTeardown();
|
|
1503
|
+
// Drop the crash backstop with this mount: a torn-down funnel cannot own
|
|
1504
|
+
// the process, so a later fatal error falls back to Node's default crash
|
|
1505
|
+
// instead of reaching a disposed ctx.
|
|
1506
|
+
registerProcessGuardFatalSink(undefined);
|
|
1448
1507
|
rawChannel.releaseContributions();
|
|
1449
1508
|
instance?.unmount();
|
|
1450
1509
|
});
|
|
@@ -1648,11 +1707,12 @@ export function createExitFunnel(deps) {
|
|
|
1648
1707
|
},
|
|
1649
1708
|
handleExit: (error) => {
|
|
1650
1709
|
if (teardown)
|
|
1651
|
-
return;
|
|
1710
|
+
return false;
|
|
1652
1711
|
if (exited)
|
|
1653
|
-
return;
|
|
1712
|
+
return false;
|
|
1654
1713
|
exited = true;
|
|
1655
1714
|
deps.onUserExit(error);
|
|
1715
|
+
return true;
|
|
1656
1716
|
},
|
|
1657
1717
|
};
|
|
1658
1718
|
}
|
|
@@ -79,10 +79,12 @@ export declare function runningPresetOf(session: unknown): string | undefined;
|
|
|
79
79
|
*/
|
|
80
80
|
export declare function resolvePersistedRoute(ctx: Context, sessionId: SessionId): Promise<ModelRoute | undefined>;
|
|
81
81
|
/**
|
|
82
|
-
* Keep the official Minimal preset's model-facing
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
82
|
+
* Keep the official Minimal preset's model-facing catalog minimal. The preset
|
|
83
|
+
* itself declares exactly one persistent shell tool (bash on POSIX, pwsh on
|
|
84
|
+
* Windows), while the TUI mounts ask_user_question at the host layer so every
|
|
85
|
+
* other preset (including user presets) can use its questionnaire UI —
|
|
86
|
+
* that host-layer tool otherwise merges into Minimal's scoped catalog as an
|
|
87
|
+
* extra tool.
|
|
86
88
|
*
|
|
87
89
|
* This is a per-assembly filter rather than a startup-time decision because
|
|
88
90
|
* one TUI process can resume, create, or recompose sessions under different
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/presets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AACpE,OAAO,EAAsB,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAWtE,kEAAkE;AAClE,MAAM,WAAW,iBAAiB;IAChC,kFAAkF;IAClF,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,yEAAyE;IACzE,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,CAAA;CAC5B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAmBhG;AAED;;;;;;;;;GASG;AACH,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAW5G;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAGpE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAW/G;AAED
|
|
1
|
+
{"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/presets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAA;AACpE,OAAO,EAAsB,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAWtE,kEAAkE;AAClE,MAAM,WAAW,iBAAiB;IAChC,kFAAkF;IAClF,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,yEAAyE;IACzE,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,CAAA;CAC5B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAmBhG;AAED;;;;;;;;;GASG;AACH,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAW5G;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAGpE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAW/G;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,cAAc,CAM/G;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE;IAAE,GAAG,EAAE,OAAO,CAAA;CAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAKpG"}
|
|
@@ -120,10 +120,12 @@ export async function resolvePersistedRoute(ctx, sessionId) {
|
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
122
|
/**
|
|
123
|
-
* Keep the official Minimal preset's model-facing
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
123
|
+
* Keep the official Minimal preset's model-facing catalog minimal. The preset
|
|
124
|
+
* itself declares exactly one persistent shell tool (bash on POSIX, pwsh on
|
|
125
|
+
* Windows), while the TUI mounts ask_user_question at the host layer so every
|
|
126
|
+
* other preset (including user presets) can use its questionnaire UI —
|
|
127
|
+
* that host-layer tool otherwise merges into Minimal's scoped catalog as an
|
|
128
|
+
* extra tool.
|
|
127
129
|
*
|
|
128
130
|
* This is a per-assembly filter rather than a startup-time decision because
|
|
129
131
|
* one TUI process can resume, create, or recompose sessions under different
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"providerWizard.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/providerWizard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAsH,MAAM,sCAAsC,CAAA;AACjM,YAAY,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,aAAa,EAAE,cAAc,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAA;AAsBjM,OAAO,EAEL,KAAK,qBAAqB,EAE1B,KAAK,sBAAsB,EAC5B,MAAM,iCAAiC,CAAA;AACxC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAE9D,iFAAiF;AACjF,eAAO,MAAM,iBAAiB,QAAoC,CAAA;AAElE,2EAA2E;AAC3E,eAAO,MAAM,kBAAkB,2EAIrB,CAAA;AAEV;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAA;IAChC,QAAQ,CAAC,GAAG,EAAE,CACZ,OAAO,EAAE,sBAAsB,EAC/B,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAC3B,OAAO,CAAC,qBAAqB,CAAC,CAAA;IACnC,QAAQ,CAAC,MAAM,EAAE,CACf,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,KACtE,IAAI,CAAA;IACT,QAAQ,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,CAAA;IACrE,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAA;IAC/B,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CAC5E;AAED,MAAM,MAAM,qBAAqB,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,YAAY,GAAG,WAAW,GAAG,QAAQ,CAAA;AA4D3G;;;;;;;;;;;;GAYG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,qBAAqB,CAAC,CA8BhC;
|
|
1
|
+
{"version":3,"file":"providerWizard.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/providerWizard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAsH,MAAM,sCAAsC,CAAA;AACjM,YAAY,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,aAAa,EAAE,cAAc,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAA;AAsBjM,OAAO,EAEL,KAAK,qBAAqB,EAE1B,KAAK,sBAAsB,EAC5B,MAAM,iCAAiC,CAAA;AACxC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAE9D,iFAAiF;AACjF,eAAO,MAAM,iBAAiB,QAAoC,CAAA;AAElE,2EAA2E;AAC3E,eAAO,MAAM,kBAAkB,2EAIrB,CAAA;AAEV;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAA;IAChC,QAAQ,CAAC,GAAG,EAAE,CACZ,OAAO,EAAE,sBAAsB,EAC/B,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAC3B,OAAO,CAAC,qBAAqB,CAAC,CAAA;IACnC,QAAQ,CAAC,MAAM,EAAE,CACf,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,KACtE,IAAI,CAAA;IACT,QAAQ,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,CAAA;IACrE,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAA;IAC/B,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CAC5E;AAED,MAAM,MAAM,qBAAqB,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,YAAY,GAAG,WAAW,GAAG,QAAQ,CAAA;AA4D3G;;;;;;;;;;;;GAYG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,qBAAqB,CAAC,CA8BhC;AAw3BD,8DAA8D;AAC9D,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,QAAQ,GAAG,aAAa,CAAA;AACrE,MAAM,MAAM,qBAAqB,GAAG,SAAS,GAAG,QAAQ,GAAG,aAAa,CAAA;AACxE,MAAM,MAAM,oBAAoB,GAC5B,aAAa,GACb,qBAAqB,GACrB,gBAAgB,CAAA;AAEpB,qEAAqE;AACrE,MAAM,WAAW,cAAc;IAC7B;uEACmE;IACnE,QAAQ,CAAC,IAAI,EAAE,SAAS,kBAAkB,EAAE,CAAA;IAC5C,6EAA6E;IAC7E,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IACxC,8DAA8D;IAC9D,QAAQ,CAAC,OAAO,EAAE,qBAAqB,CAAA;IACvC,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAA;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,oBAAoB,CAAA;CACvC"}
|
|
@@ -817,7 +817,9 @@ function buildDeleteSummary(provider) {
|
|
|
817
817
|
/** Masked state line for one provider row in the OAuth pick question. */
|
|
818
818
|
function oauthStateDescription(status) {
|
|
819
819
|
if (status.signedIn) {
|
|
820
|
-
return
|
|
820
|
+
return status.expiresAt === undefined
|
|
821
|
+
? t('provider-oauth-state-in-no-expiry')
|
|
822
|
+
: t('provider-oauth-state-in', { time: new Date(status.expiresAt).toISOString() });
|
|
821
823
|
}
|
|
822
824
|
return status.expired
|
|
823
825
|
? t('provider-oauth-state-expired')
|
|
@@ -872,7 +874,9 @@ async function runOAuthWizard(deps, oauth) {
|
|
|
872
874
|
pushLocal('/provider', [
|
|
873
875
|
t('provider-line-oauth-provider', { provider: result.provider }),
|
|
874
876
|
t('provider-line-oauth-flow', { flow: result.oauthLabel }),
|
|
875
|
-
|
|
877
|
+
...(result.expiresAt === undefined
|
|
878
|
+
? []
|
|
879
|
+
: [t('provider-line-oauth-expires', { time: new Date(result.expiresAt).toISOString() })]),
|
|
876
880
|
t('provider-switch-hint'),
|
|
877
881
|
]);
|
|
878
882
|
notify(t('provider-oauth-login-ok', { provider: result.provider }), { color: 'success' });
|
|
@@ -32,6 +32,7 @@ export declare class SubagentActivityStore {
|
|
|
32
32
|
live?: boolean;
|
|
33
33
|
provider?: string;
|
|
34
34
|
model?: string;
|
|
35
|
+
mode?: 'one-shot' | 'continuable' | 'unknown';
|
|
35
36
|
}): void;
|
|
36
37
|
linkSession(agentId: string, session: unknown): void;
|
|
37
38
|
getSubagentIdBySession(session: unknown): string | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subagents.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/subagents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAGlE,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,aAAa,EAAsC,kBAAkB,EAAE,gBAAgB,EAAsB,MAAM,kCAAkC,CAAA;AACxM,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAA;AAMtL;gCACgC;AAChC,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,iBAAiB,EAAE,CAAA;IAC5B,QAAQ,EAAE,gBAAgB,CAAA;CAC3B;AAaD,qBAAa,qBAAqB;IAChC,OAAO,CAAC,MAAM,CAAmC;IACjD,OAAO,CAAC,cAAc,CAA6B;IACnD,OAAO,CAAC,SAAS,CAAwB;IACzC,OAAO,CAAC,OAAO,CAA2C;IAC1D,+DAA+D;IAC/D,OAAO,CAAC,WAAW,CAAuC;IAC1D,iDAAiD;IACjD,OAAO,CAAC,YAAY,CAAqB;IACzC,mDAAmD;IACnD,OAAO,CAAC,OAAO,CAA4B;IAE3C,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,QAAQ;IAOhB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,SAAa,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,GAAE,OAAO,CAAC,aAAa,CAAM,GAAG,IAAI;IAsD1G;;;;uDAImD;IACnD,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"subagents.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/subagents.ts"],"names":[],"mappings":"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"}
|
|
@@ -89,8 +89,16 @@ export class SubagentActivityStore {
|
|
|
89
89
|
* row running; an idle historical child shows as `unknown` (the parent log
|
|
90
90
|
* alone cannot prove how its last epoch ended). */
|
|
91
91
|
onDiscovered(agentId, info = {}) {
|
|
92
|
-
|
|
92
|
+
const existing = this.states.get(agentId);
|
|
93
|
+
if (existing !== undefined) {
|
|
94
|
+
// A bus edge usually created the row first; the durable catalog fact
|
|
95
|
+
// still carries the one thing the edge never knows — the mode.
|
|
96
|
+
if (info.mode !== undefined && existing.mode === undefined) {
|
|
97
|
+
existing.mode = info.mode;
|
|
98
|
+
this.notify();
|
|
99
|
+
}
|
|
93
100
|
return;
|
|
101
|
+
}
|
|
94
102
|
this.states.set(agentId, {
|
|
95
103
|
agentId,
|
|
96
104
|
description: info.label ?? `${info.provider ?? 'subagent'} task`,
|
|
@@ -99,6 +107,7 @@ export class SubagentActivityStore {
|
|
|
99
107
|
status: info.live ? 'running' : 'unknown',
|
|
100
108
|
startedAt: info.childCreatedAt ?? Date.now(),
|
|
101
109
|
sessionId: agentId,
|
|
110
|
+
...(info.mode === undefined ? {} : { mode: info.mode }),
|
|
102
111
|
output: [],
|
|
103
112
|
outputEvents: [],
|
|
104
113
|
toolCalls: [],
|