@aiwayds/dsh-tui-pi 2.18.2 → 2.20.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 +12 -43
- package/README.zh-CN.md +11 -42
- package/lib/agents.js +67 -52
- package/lib/agents.js.map +1 -1
- package/lib/ask-user.d.ts +122 -3
- package/lib/ask-user.js +335 -41
- package/lib/ask-user.js.map +1 -1
- package/lib/attachments.js +8 -3
- package/lib/attachments.js.map +1 -1
- package/lib/btw.d.ts +4 -2
- package/lib/btw.js +22 -16
- package/lib/btw.js.map +1 -1
- package/lib/custom-provider.js +34 -28
- package/lib/custom-provider.js.map +1 -1
- package/lib/footer.d.ts +9 -8
- package/lib/footer.js +36 -18
- package/lib/footer.js.map +1 -1
- package/lib/hard-exit.d.ts +36 -0
- package/lib/hard-exit.js +64 -0
- package/lib/hard-exit.js.map +1 -0
- package/lib/history-fork.d.ts +2 -2
- package/lib/history-fork.js +12 -9
- package/lib/history-fork.js.map +1 -1
- package/lib/history-turns.d.ts +4 -2
- package/lib/history-turns.js +7 -3
- package/lib/history-turns.js.map +1 -1
- package/lib/history.js +57 -45
- package/lib/history.js.map +1 -1
- package/lib/hotkeys.js +44 -33
- package/lib/hotkeys.js.map +1 -1
- package/lib/i18n/index.d.ts +54 -0
- package/lib/i18n/index.js +98 -0
- package/lib/i18n/index.js.map +1 -0
- package/lib/i18n/registry.d.ts +65 -0
- package/lib/i18n/registry.js +129 -0
- package/lib/i18n/registry.js.map +1 -0
- package/lib/index.js +219 -109
- package/lib/index.js.map +1 -1
- package/lib/language-ask.d.ts +98 -0
- package/lib/language-ask.js +118 -0
- package/lib/language-ask.js.map +1 -0
- package/lib/live-widgets.js +9 -8
- package/lib/live-widgets.js.map +1 -1
- package/lib/login.js +5 -4
- package/lib/login.js.map +1 -1
- package/lib/messages.d.ts +0 -4
- package/lib/messages.js +14 -15
- package/lib/messages.js.map +1 -1
- package/lib/model-profiles.js +32 -20
- package/lib/model-profiles.js.map +1 -1
- package/lib/panels.js +18 -17
- package/lib/panels.js.map +1 -1
- package/lib/preflight-projcache.js +9 -3
- package/lib/preflight-projcache.js.map +1 -1
- package/lib/preset-dialog.d.ts +3 -3
- package/lib/preset-dialog.js +20 -17
- package/lib/preset-dialog.js.map +1 -1
- package/lib/provider-catalog.d.ts +23 -7
- package/lib/provider-catalog.js +90 -68
- package/lib/provider-catalog.js.map +1 -1
- package/lib/queue-panel.d.ts +2 -2
- package/lib/queue-panel.js +13 -9
- package/lib/queue-panel.js.map +1 -1
- package/lib/repair-dialog.d.ts +4 -4
- package/lib/repair-dialog.js +23 -16
- package/lib/repair-dialog.js.map +1 -1
- package/lib/route-dialog.d.ts +3 -3
- package/lib/route-dialog.js +20 -14
- package/lib/route-dialog.js.map +1 -1
- package/lib/selectors.d.ts +15 -1
- package/lib/selectors.js +57 -23
- package/lib/selectors.js.map +1 -1
- package/lib/sessions.d.ts +47 -14
- package/lib/sessions.js +162 -53
- package/lib/sessions.js.map +1 -1
- package/lib/settings.d.ts +68 -9
- package/lib/settings.js +327 -78
- package/lib/settings.js.map +1 -1
- package/lib/skills-manager.js +27 -21
- package/lib/skills-manager.js.map +1 -1
- package/lib/skills.js +5 -4
- package/lib/skills.js.map +1 -1
- package/lib/startup-info.js +9 -3
- package/lib/startup-info.js.map +1 -1
- package/lib/steer-flow.d.ts +14 -4
- package/lib/steer-flow.js +24 -9
- package/lib/steer-flow.js.map +1 -1
- package/lib/stop-dialog.d.ts +2 -2
- package/lib/stop-dialog.js +16 -12
- package/lib/stop-dialog.js.map +1 -1
- package/lib/subagent-viewer.d.ts +3 -8
- package/lib/subagent-viewer.js +38 -62
- package/lib/subagent-viewer.js.map +1 -1
- package/lib/theme-preview.js +12 -11
- package/lib/theme-preview.js.map +1 -1
- package/lib/theme-settings.d.ts +44 -2
- package/lib/theme-settings.js +97 -54
- package/lib/theme-settings.js.map +1 -1
- package/lib/tui.js +2 -1
- package/lib/tui.js.map +1 -1
- package/locales/en.json +646 -0
- package/locales/ja.json +646 -0
- package/locales/ko.json +646 -0
- package/locales/zh-CN.json +646 -0
- package/package.json +2 -1
- package/skills/dsh-tui-pi-config/SKILL.md +14 -4
package/lib/provider-catalog.js
CHANGED
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
* that pi-ai does not ship just sets `catalogRoute: false` plus its
|
|
27
27
|
* `api`/`baseURL`/`models` — no TUI change needed.
|
|
28
28
|
*/
|
|
29
|
+
import { t } from "./i18n/index.js";
|
|
29
30
|
/**
|
|
30
31
|
* The built-in provider directory the Add-provider picker offers — mirrors
|
|
31
32
|
* the web Models directory: every installed llm-pi-ai catalog route that
|
|
@@ -34,49 +35,73 @@
|
|
|
34
35
|
* the credential. At runtime the add flow prefers the live directory (see
|
|
35
36
|
* `directoryProviderEntries`); this list is the static fallback and the
|
|
36
37
|
* friendly name/hint source.
|
|
38
|
+
*
|
|
39
|
+
* `hint` carries an i18n KEY (module data must not freeze a language at
|
|
40
|
+
* import time); render sites resolve it with `t(entry.hint)` — see
|
|
41
|
+
* `directoryProviderEntries` for the resolving-clone pattern. `name` stays a
|
|
42
|
+
* literal: provider names are proper nouns.
|
|
37
43
|
*/
|
|
38
44
|
export const PROVIDER_CATALOG = [
|
|
39
|
-
{ id: 'amazon-bedrock', name: 'Amazon Bedrock', hint: '
|
|
40
|
-
{ id: 'ant-ling', name: 'Ant Ling', hint: '
|
|
41
|
-
{ id: 'anthropic', name: 'Anthropic', hint: '
|
|
42
|
-
{ id: 'azure-openai-responses', name: 'Azure OpenAI', hint: '
|
|
43
|
-
{ id: 'cerebras', name: 'Cerebras', hint: '
|
|
44
|
-
{ id: 'cloudflare-ai-gateway', name: 'Cloudflare AI Gateway', hint: '
|
|
45
|
-
{ id: 'cloudflare-workers-ai', name: 'Cloudflare Workers AI', hint: '
|
|
46
|
-
{ id: 'deepseek', name: 'DeepSeek', hint: '
|
|
47
|
-
{ id: 'fireworks', name: 'Fireworks', hint: '
|
|
48
|
-
{ id: 'github-copilot', name: 'GitHub Copilot', hint: '
|
|
49
|
-
{ id: 'google', name: 'Google Gemini', hint: '
|
|
50
|
-
{ id: 'google-vertex', name: 'Google Vertex AI', hint: '
|
|
51
|
-
{ id: 'groq', name: 'Groq', hint: '
|
|
52
|
-
{ id: 'huggingface', name: 'Hugging Face', hint: '
|
|
53
|
-
{ id: 'kimi-coding', name: 'Kimi For Coding', hint: '
|
|
54
|
-
{ id: 'minimax', name: 'MiniMax', hint: '
|
|
55
|
-
{ id: 'minimax-cn', name: 'MiniMax CN', hint: '
|
|
56
|
-
{ id: 'mistral', name: 'Mistral', hint: '
|
|
57
|
-
{ id: 'moonshotai', name: 'Moonshot AI', hint: '
|
|
58
|
-
{ id: 'moonshotai-cn', name: 'Moonshot AI CN', hint: '
|
|
59
|
-
{ id: 'nvidia', name: 'NVIDIA', hint: '
|
|
60
|
-
{ id: 'openai', name: 'OpenAI', hint: '
|
|
61
|
-
{ id: 'opencode-go', name: 'OpenCode Go', hint: '
|
|
62
|
-
{ id: 'opencode', name: 'OpenCode Zen', hint: '
|
|
63
|
-
{ id: 'openrouter', name: 'OpenRouter', hint: '
|
|
64
|
-
{ id: 'qwen-token-plan', name: 'Qwen Token Plan', hint: '
|
|
65
|
-
{ id: 'qwen-token-plan-cn', name: 'Qwen Token Plan CN', hint: '
|
|
66
|
-
{ id: 'together', name: 'Together AI', hint: '
|
|
67
|
-
{ id: 'vercel-ai-gateway', name: 'Vercel AI Gateway', hint: '
|
|
68
|
-
{ id: 'xiaomi', name: 'Xiaomi', hint: '
|
|
69
|
-
{ id: 'xiaomi-token-plan-ams', name: 'Xiaomi Token Plan AMS', hint: '
|
|
70
|
-
{ id: 'xiaomi-token-plan-cn', name: 'Xiaomi Token Plan CN', hint: '
|
|
71
|
-
{ id: 'xiaomi-token-plan-sgp', name: 'Xiaomi Token Plan SGP', hint: '
|
|
72
|
-
{ id: 'zai', name: 'Z.AI', hint: '
|
|
73
|
-
{ id: 'zai-coding-cn', name: 'Z.AI Coding CN', hint: '
|
|
74
|
-
{ id: 'xai', name: 'xAI', hint: '
|
|
45
|
+
{ id: 'amazon-bedrock', name: 'Amazon Bedrock', hint: 'provcatalog.hint.aws', catalogRoute: true },
|
|
46
|
+
{ id: 'ant-ling', name: 'Ant Ling', hint: 'provcatalog.hint.apiKey', catalogRoute: true },
|
|
47
|
+
{ id: 'anthropic', name: 'Anthropic', hint: 'provcatalog.hint.apiKey', catalogRoute: true },
|
|
48
|
+
{ id: 'azure-openai-responses', name: 'Azure OpenAI', hint: 'provcatalog.hint.apiKey', catalogRoute: true },
|
|
49
|
+
{ id: 'cerebras', name: 'Cerebras', hint: 'provcatalog.hint.apiKey', catalogRoute: true },
|
|
50
|
+
{ id: 'cloudflare-ai-gateway', name: 'Cloudflare AI Gateway', hint: 'provcatalog.hint.apiKey', catalogRoute: true },
|
|
51
|
+
{ id: 'cloudflare-workers-ai', name: 'Cloudflare Workers AI', hint: 'provcatalog.hint.apiKey', catalogRoute: true },
|
|
52
|
+
{ id: 'deepseek', name: 'DeepSeek', hint: 'provcatalog.hint.apiKey', catalogRoute: true },
|
|
53
|
+
{ id: 'fireworks', name: 'Fireworks', hint: 'provcatalog.hint.apiKey', catalogRoute: true },
|
|
54
|
+
{ id: 'github-copilot', name: 'GitHub Copilot', hint: 'provcatalog.hint.copilot', catalogRoute: true },
|
|
55
|
+
{ id: 'google', name: 'Google Gemini', hint: 'provcatalog.hint.apiKey', catalogRoute: true },
|
|
56
|
+
{ id: 'google-vertex', name: 'Google Vertex AI', hint: 'provcatalog.hint.googleCloud', catalogRoute: true },
|
|
57
|
+
{ id: 'groq', name: 'Groq', hint: 'provcatalog.hint.apiKey', catalogRoute: true },
|
|
58
|
+
{ id: 'huggingface', name: 'Hugging Face', hint: 'provcatalog.hint.huggingface', catalogRoute: true },
|
|
59
|
+
{ id: 'kimi-coding', name: 'Kimi For Coding', hint: 'provcatalog.hint.apiKey', catalogRoute: true },
|
|
60
|
+
{ id: 'minimax', name: 'MiniMax', hint: 'provcatalog.hint.apiKey', catalogRoute: true },
|
|
61
|
+
{ id: 'minimax-cn', name: 'MiniMax CN', hint: 'provcatalog.hint.apiKey', catalogRoute: true },
|
|
62
|
+
{ id: 'mistral', name: 'Mistral', hint: 'provcatalog.hint.apiKey', catalogRoute: true },
|
|
63
|
+
{ id: 'moonshotai', name: 'Moonshot AI', hint: 'provcatalog.hint.apiKey', catalogRoute: true },
|
|
64
|
+
{ id: 'moonshotai-cn', name: 'Moonshot AI CN', hint: 'provcatalog.hint.apiKey', catalogRoute: true },
|
|
65
|
+
{ id: 'nvidia', name: 'NVIDIA', hint: 'provcatalog.hint.apiKey', catalogRoute: true },
|
|
66
|
+
{ id: 'openai', name: 'OpenAI', hint: 'provcatalog.hint.apiKey', catalogRoute: true },
|
|
67
|
+
{ id: 'opencode-go', name: 'OpenCode Go', hint: 'provcatalog.hint.apiKey.gateway', catalogRoute: true },
|
|
68
|
+
{ id: 'opencode', name: 'OpenCode Zen', hint: 'provcatalog.hint.apiKey', catalogRoute: true },
|
|
69
|
+
{ id: 'openrouter', name: 'OpenRouter', hint: 'provcatalog.hint.apiKey', catalogRoute: true },
|
|
70
|
+
{ id: 'qwen-token-plan', name: 'Qwen Token Plan', hint: 'provcatalog.hint.apiKey', catalogRoute: true },
|
|
71
|
+
{ id: 'qwen-token-plan-cn', name: 'Qwen Token Plan CN', hint: 'provcatalog.hint.apiKey', catalogRoute: true },
|
|
72
|
+
{ id: 'together', name: 'Together AI', hint: 'provcatalog.hint.apiKey', catalogRoute: true },
|
|
73
|
+
{ id: 'vercel-ai-gateway', name: 'Vercel AI Gateway', hint: 'provcatalog.hint.apiKey', catalogRoute: true },
|
|
74
|
+
{ id: 'xiaomi', name: 'Xiaomi', hint: 'provcatalog.hint.apiKey', catalogRoute: true },
|
|
75
|
+
{ id: 'xiaomi-token-plan-ams', name: 'Xiaomi Token Plan AMS', hint: 'provcatalog.hint.apiKey', catalogRoute: true },
|
|
76
|
+
{ id: 'xiaomi-token-plan-cn', name: 'Xiaomi Token Plan CN', hint: 'provcatalog.hint.apiKey', catalogRoute: true },
|
|
77
|
+
{ id: 'xiaomi-token-plan-sgp', name: 'Xiaomi Token Plan SGP', hint: 'provcatalog.hint.apiKey', catalogRoute: true },
|
|
78
|
+
{ id: 'zai', name: 'Z.AI', hint: 'provcatalog.hint.apiKey', catalogRoute: true },
|
|
79
|
+
{ id: 'zai-coding-cn', name: 'Z.AI Coding CN', hint: 'provcatalog.hint.apiKey', catalogRoute: true },
|
|
80
|
+
{ id: 'xai', name: 'xAI', hint: 'provcatalog.hint.apiKey', catalogRoute: true },
|
|
75
81
|
];
|
|
76
82
|
/** One directory entry by route key, or `undefined` for an unknown route. */
|
|
77
83
|
export function catalogEntry(id) {
|
|
78
84
|
return PROVIDER_CATALOG.find(entry => entry.id === id);
|
|
79
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Resolve one entry's hint to display text. The static catalog's hint fields
|
|
88
|
+
* carry i18n KEYS (module data must not freeze a language at import time);
|
|
89
|
+
* this switch enumerates them as literal t() call sites — which is also what
|
|
90
|
+
* the i18n coverage guard matches against. Anything else (an already-resolved
|
|
91
|
+
* hint from a runtime-built entry) passes through `t()` unchanged, since a
|
|
92
|
+
* non-key falls back to itself.
|
|
93
|
+
*/
|
|
94
|
+
export function resolveCatalogHint(hint) {
|
|
95
|
+
switch (hint) {
|
|
96
|
+
case 'provcatalog.hint.apiKey': return t('provcatalog.hint.apiKey');
|
|
97
|
+
case 'provcatalog.hint.aws': return t('provcatalog.hint.aws');
|
|
98
|
+
case 'provcatalog.hint.copilot': return t('provcatalog.hint.copilot');
|
|
99
|
+
case 'provcatalog.hint.googleCloud': return t('provcatalog.hint.googleCloud');
|
|
100
|
+
case 'provcatalog.hint.huggingface': return t('provcatalog.hint.huggingface');
|
|
101
|
+
case 'provcatalog.hint.apiKey.gateway': return t('provcatalog.hint.apiKey.gateway');
|
|
102
|
+
default: return t(hint);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
80
105
|
/**
|
|
81
106
|
* Derive the conventional credential reference for a provider route — the
|
|
82
107
|
* same convention the web Models page uses: the route key uppercased with
|
|
@@ -125,11 +150,19 @@ export function unconfiguredCatalogEntries(configured) {
|
|
|
125
150
|
export function directoryProviderEntries(directory, configured) {
|
|
126
151
|
return directory
|
|
127
152
|
.filter(entry => !configured.has(entry.provider) && entry.declared !== true)
|
|
128
|
-
.map(entry =>
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
153
|
+
.map(entry => {
|
|
154
|
+
// Known route: clone the static entry with the hint RESOLVED (the
|
|
155
|
+
// static table carries hint keys; picker rows display text). Unknown
|
|
156
|
+
// route: the route key names itself and the generic key hint.
|
|
157
|
+
const known = catalogEntry(entry.provider);
|
|
158
|
+
return known !== undefined
|
|
159
|
+
? { ...known, hint: resolveCatalogHint(known.hint) }
|
|
160
|
+
: {
|
|
161
|
+
id: entry.provider,
|
|
162
|
+
name: entry.provider,
|
|
163
|
+
hint: t('provcatalog.hint.apiKey'),
|
|
164
|
+
catalogRoute: true,
|
|
165
|
+
};
|
|
133
166
|
});
|
|
134
167
|
}
|
|
135
168
|
/**
|
|
@@ -137,44 +170,33 @@ export function directoryProviderEntries(directory, configured) {
|
|
|
137
170
|
* the environment lookup (`process.env`) and the (possibly undefined) profile
|
|
138
171
|
* read out of the llm-pi-ai descriptor, so nothing here touches services.
|
|
139
172
|
*
|
|
140
|
-
* The summary rule:
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
173
|
+
* The summary rule: the configured models' ids joined with ", " — one row per
|
|
174
|
+
* provider, so moving the selection up/down reads off that provider's own
|
|
175
|
+
* list. No models configured (a hand-declared route without a list, or the
|
|
176
|
+
* implicit `models: []` schema default on a catalog route) renders as an
|
|
177
|
+
* empty value column, never a count placeholder.
|
|
178
|
+
* The status rule: no `apiKeyEnv` means the route has no key address at all;
|
|
179
|
+
* otherwise the reference's presence in the supplied environment decides
|
|
180
|
+
* `API key set` vs `API key missing`.
|
|
146
181
|
*/
|
|
147
182
|
export function providerRowView(id, entry, profile, env) {
|
|
148
183
|
const p = (typeof profile === 'object' && profile !== null ? profile : undefined);
|
|
149
184
|
const displayName = p?.displayName;
|
|
150
185
|
const label = displayName !== undefined && displayName !== '' ? displayName : entry?.name ?? id;
|
|
151
|
-
const models = p?.models;
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
summary = typeof first === 'string' && first !== '' ? first : count;
|
|
157
|
-
}
|
|
158
|
-
else if (entry?.catalogRoute === true) {
|
|
159
|
-
// No models listed — including the implicit `models: []` that schema
|
|
160
|
-
// defaults put into every resolved profile: a catalog route serves the
|
|
161
|
-
// installed pi-ai catalog, so `catalog` beats a misleading `0 models`.
|
|
162
|
-
summary = 'catalog';
|
|
163
|
-
}
|
|
164
|
-
else {
|
|
165
|
-
// Hand-declared route (or unknown route key): nothing to serve without
|
|
166
|
-
// an explicit model list — `0 models` is the honest read here.
|
|
167
|
-
summary = '0 models';
|
|
168
|
-
}
|
|
186
|
+
const models = p?.models ?? [];
|
|
187
|
+
const summary = models
|
|
188
|
+
.map(model => (typeof model?.id === 'string' ? model.id : ''))
|
|
189
|
+
.filter(modelId => modelId !== '')
|
|
190
|
+
.join(', ');
|
|
169
191
|
const ref = p?.apiKeyEnv;
|
|
170
192
|
// Truthy presence: an empty-string env value means the key is not usable
|
|
171
193
|
// (the add flow merges 'stored', never ''). An unset/empty env var is
|
|
172
194
|
// 'missing', an undefined ref is 'not configured'.
|
|
173
195
|
const status = ref === undefined || ref === ''
|
|
174
|
-
? '
|
|
196
|
+
? t('provcatalog.status.notConfigured')
|
|
175
197
|
: env[ref]
|
|
176
|
-
? '
|
|
177
|
-
: '
|
|
198
|
+
? t('provcatalog.status.set')
|
|
199
|
+
: t('provcatalog.status.missing');
|
|
178
200
|
return { id, label, summary, status };
|
|
179
201
|
}
|
|
180
202
|
//# sourceMappingURL=provider-catalog.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider-catalog.js","sourceRoot":"","sources":["../src/provider-catalog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;
|
|
1
|
+
{"version":3,"file":"provider-catalog.js","sourceRoot":"","sources":["../src/provider-catalog.ts"],"names":[],"mappings":"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"}
|
package/lib/queue-panel.d.ts
CHANGED
|
@@ -24,9 +24,9 @@ import { type TuiTheme } from './theme/index.ts';
|
|
|
24
24
|
* leave the panel silently showing stale data.
|
|
25
25
|
*/
|
|
26
26
|
export declare const QUEUE_REFRESH_FAIL_THRESHOLD = 3;
|
|
27
|
-
/** The warning text raised once per failure streak at the threshold. */
|
|
27
|
+
/** The warning text raised once per failure streak at the threshold (en reference; the raise site resolves t()). */
|
|
28
28
|
export declare const QUEUE_REFRESH_FAILED_NOTICE = "Queue status refresh failed \u2014 the list below may be stale.";
|
|
29
|
-
/** Footer hint —
|
|
29
|
+
/** Footer hint — en literal kept for tests; the render site resolves t(). */
|
|
30
30
|
export declare const QUEUE_PANEL_FOOTER = "\u2191\u2193 select \u00B7 d remove \u00B7 s steer now \u00B7 Esc close";
|
|
31
31
|
/** Everything the panel needs from the outside — injectable for tests. */
|
|
32
32
|
export interface QueuePanelDeps {
|
package/lib/queue-panel.js
CHANGED
|
@@ -21,6 +21,7 @@ import { PanelHost, panelThemeFns } from "./panels.js";
|
|
|
21
21
|
import { normalizePreview } from "./sessions.js";
|
|
22
22
|
import { BOLD, RESET, ansiFg } from "./theme/index.js";
|
|
23
23
|
import { clipToWidth } from "./text.js";
|
|
24
|
+
import { t } from "./i18n/index.js";
|
|
24
25
|
/** Live-refresh interval while the panel is open (subagent viewer cadence). */
|
|
25
26
|
const QUEUE_TICK_MS = 300;
|
|
26
27
|
/**
|
|
@@ -29,15 +30,18 @@ const QUEUE_TICK_MS = 300;
|
|
|
29
30
|
* leave the panel silently showing stale data.
|
|
30
31
|
*/
|
|
31
32
|
export const QUEUE_REFRESH_FAIL_THRESHOLD = 3;
|
|
32
|
-
/** The warning text raised once per failure streak at the threshold. */
|
|
33
|
+
/** The warning text raised once per failure streak at the threshold (en reference; the raise site resolves t()). */
|
|
33
34
|
export const QUEUE_REFRESH_FAILED_NOTICE = 'Queue status refresh failed — the list below may be stale.';
|
|
34
35
|
/** Rows visible without scrolling; the overlay maxHeight slices the rest. */
|
|
35
36
|
const QUEUE_MAX_VISIBLE = 12;
|
|
36
|
-
/**
|
|
37
|
+
/**
|
|
38
|
+
* Target glyph + label per inbox boundary (badge vocabulary of the design).
|
|
39
|
+
* Resolved through t() per call so the active language applies (render-time).
|
|
40
|
+
*/
|
|
37
41
|
function targetLabel(target) {
|
|
38
|
-
return target === 'next-step' ? '
|
|
42
|
+
return target === 'next-step' ? t('queue.target.steer') : t('queue.target.queued');
|
|
39
43
|
}
|
|
40
|
-
/** Footer hint —
|
|
44
|
+
/** Footer hint — en literal kept for tests; the render site resolves t(). */
|
|
41
45
|
export const QUEUE_PANEL_FOOTER = '↑↓ select · d remove · s steer now · Esc close';
|
|
42
46
|
/**
|
|
43
47
|
* One rendered queue row: selection marker + route badge + preview.
|
|
@@ -106,8 +110,8 @@ export class PendingQueuePanel {
|
|
|
106
110
|
this.refreshFailures++;
|
|
107
111
|
if (this.refreshFailures >= QUEUE_REFRESH_FAIL_THRESHOLD && !this.refreshFailureReported) {
|
|
108
112
|
this.refreshFailureReported = true;
|
|
109
|
-
this.notice =
|
|
110
|
-
this.deps.onRefreshError?.(
|
|
113
|
+
this.notice = t('queue.refreshFailed');
|
|
114
|
+
this.deps.onRefreshError?.(t('queue.refreshFailed'));
|
|
111
115
|
this.requestRenderFn();
|
|
112
116
|
}
|
|
113
117
|
}
|
|
@@ -118,12 +122,12 @@ export class PendingQueuePanel {
|
|
|
118
122
|
const fns = panelThemeFns(this.theme);
|
|
119
123
|
const wrap = Math.max(2, width - 2);
|
|
120
124
|
const lines = [
|
|
121
|
-
fns.accent(BOLD + clipToWidth('
|
|
125
|
+
fns.accent(BOLD + clipToWidth(t('queue.title'), wrap) + RESET),
|
|
122
126
|
'',
|
|
123
127
|
];
|
|
124
128
|
const visible = this.items.slice(0, QUEUE_MAX_VISIBLE);
|
|
125
129
|
if (visible.length === 0) {
|
|
126
|
-
lines.push(fns.subtle(clipToWidth('
|
|
130
|
+
lines.push(fns.subtle(clipToWidth(t('queue.empty'), wrap)));
|
|
127
131
|
}
|
|
128
132
|
else {
|
|
129
133
|
for (let i = 0; i < visible.length; i++) {
|
|
@@ -136,7 +140,7 @@ export class PendingQueuePanel {
|
|
|
136
140
|
lines.push('');
|
|
137
141
|
if (this.notice !== undefined)
|
|
138
142
|
lines.push(fns.subtle(clipToWidth(this.notice, wrap)));
|
|
139
|
-
lines.push(fns.subtle(clipToWidth(
|
|
143
|
+
lines.push(fns.subtle(clipToWidth(t('queue.footer'), wrap)));
|
|
140
144
|
return lines;
|
|
141
145
|
}
|
|
142
146
|
handleInput(data) {
|
package/lib/queue-panel.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue-panel.js","sourceRoot":"","sources":["../src/queue-panel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,cAAc,EAA4B,MAAM,wBAAwB,CAAA;AACjF,OAAO,EAAE,yBAAyB,EAAkD,MAAM,iBAAiB,CAAA;AAC3G,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAiB,MAAM,kBAAkB,CAAA;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"queue-panel.js","sourceRoot":"","sources":["../src/queue-panel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,cAAc,EAA4B,MAAM,wBAAwB,CAAA;AACjF,OAAO,EAAE,yBAAyB,EAAkD,MAAM,iBAAiB,CAAA;AAC3G,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAiB,MAAM,kBAAkB,CAAA;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,EAAE,CAAC,EAAE,MAAM,iBAAiB,CAAA;AAEnC,+EAA+E;AAC/E,MAAM,aAAa,GAAG,GAAG,CAAA;AAEzB;;;;GAIG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,CAAA;AAE7C,oHAAoH;AACpH,MAAM,CAAC,MAAM,2BAA2B,GAAG,4DAA4D,CAAA;AAEvG,6EAA6E;AAC7E,MAAM,iBAAiB,GAAG,EAAE,CAAA;AAE5B;;;GAGG;AACH,SAAS,WAAW,CAAC,MAAiC;IACpD,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAA;AACpF,CAAC;AAED,6EAA6E;AAC7E,MAAM,CAAC,MAAM,kBAAkB,GAAG,gDAAgD,CAAA;AAkClF;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAuB,EAAE,QAAiB;IACjE,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAA;IACnC,OAAO,GAAG,MAAM,IAAI,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAA;AACjF,CAAC;AAED;;;;GAIG;AACH,MAAM,OAAO,iBAAiB;IACX,KAAK,CAAU;IACf,IAAI,CAAgB;IACpB,eAAe,CAAY;IACpC,KAAK,GAAiC,EAAE,CAAA;IACxC,QAAQ,GAAG,CAAC,CAAA;IACZ,MAAM,CAAoB;IAC1B,KAAK,CAA4C;IACjD,MAAM,GAAG,KAAK,CAAA;IACtB,oEAAoE;IAC5D,eAAe,GAAG,CAAC,CAAA;IAC3B,kEAAkE;IAC1D,sBAAsB,GAAG,KAAK,CAAA;IAEtC,YAAY,KAAe,EAAE,IAAoB,EAAE,aAAyB;QAC1E,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAClB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,eAAe,GAAG,aAAa,CAAA;QACpC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,SAAS,EAAE,CAAA;IAC/B,CAAC;IAED,UAAU,KAAU,CAAC;IAErB,OAAO;QACL,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC7B,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACzB,IAAI,CAAC,KAAK,GAAG,SAAS,CAAA;QACxB,CAAC;IACH,CAAC;IAED,wEAAwE;IACxE,YAAY;QACV,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;YAAE,OAAM;QACpC,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;YAC5B,IAAI,IAAI,CAAC,MAAM;gBAAE,OAAM;YACvB,IAAI,CAAC;gBACH,sEAAsE;gBACtE,IAAI,IAAI,CAAC,IAAI,CAAC,cAAc,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;oBAC1E,IAAI,CAAC,KAAK,EAAE,CAAA;oBACZ,OAAM;gBACR,CAAC;gBACD,IAAI,CAAC,OAAO,EAAE,CAAA;gBACd,oEAAoE;gBACpE,IAAI,CAAC,eAAe,GAAG,CAAC,CAAA;gBACxB,IAAI,CAAC,sBAAsB,GAAG,KAAK,CAAA;gBACnC,IAAI,CAAC,eAAe,EAAE,CAAA;YACxB,CAAC;YAAC,MAAM,CAAC;gBACP,8DAA8D;gBAC9D,iEAAiE;gBACjE,oEAAoE;gBACpE,iEAAiE;gBACjE,gDAAgD;gBAChD,IAAI,CAAC,eAAe,EAAE,CAAA;gBACtB,IAAI,IAAI,CAAC,eAAe,IAAI,4BAA4B,IAAI,CAAC,IAAI,CAAC,sBAAsB,EAAE,CAAC;oBACzF,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAA;oBAClC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,qBAAqB,CAAC,CAAA;oBACtC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAA;oBACpD,IAAI,CAAC,eAAe,EAAE,CAAA;gBACxB,CAAC;YACH,CAAC;QACH,CAAC,EAAE,aAAa,CAAC,CAAA;QACjB,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAA;IACtB,CAAC;IAED,MAAM,CAAC,KAAa;QAClB,MAAM,GAAG,GAAG,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAA;QACnC,MAAM,KAAK,GAAa;YACtB,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC;YAC9D,EAAE;SACH,CAAA;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAA;QACtD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;QAC7D,CAAC;aAAM,CAAC;YACN,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACxC,MAAM,GAAG,GAAG,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAE,EAAE,CAAC,KAAK,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAA;gBACzE,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,QAAQ;oBAC5B,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,GAAG,GAAG,KAAK;oBACxD,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;YACrB,CAAC;QACH,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACd,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;QACrF,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,cAAc,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;QAC5D,OAAO,KAAK,CAAA;IACd,CAAC;IAED,WAAW,CAAC,IAAY;QACtB,uEAAuE;QACvE,IAAI,CAAC,MAAM,GAAG,SAAS,CAAA;QACvB,MAAM,EAAE,GAAG,cAAc,EAAE,CAAA;QAC3B,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,mBAAmB,CAAC,EAAE,CAAC;YAC1C,IAAI,CAAC,KAAK,EAAE,CAAA;YACZ,OAAM;QACR,CAAC;QACD,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,eAAe,CAAC,IAAI,IAAI,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;YAC3D,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAA;YAClB,IAAI,CAAC,eAAe,EAAE,CAAA;YACtB,OAAM;QACR,CAAC;QACD,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,iBAAiB,CAAC,IAAI,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjF,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAA;YAClB,IAAI,CAAC,eAAe,EAAE,CAAA;YACtB,OAAM;QACR,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QACtC,IAAI,IAAI,KAAK,SAAS;YAAE,OAAM;QAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,CAAA;QAC9B,IAAI,GAAG,KAAK,GAAG;YAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAA;aAChD,IAAI,GAAG,KAAK,GAAG;YAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAA;IAC7D,CAAC;IAED,6EAA6E;IACrE,KAAK,CAAC,MAAyB;QACrC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,CAAA;QAC7B,IAAI,CAAC,MAAM,GAAG,yBAAyB,CAAC,MAAM,CAAC,CAAA;QAC/C,IAAI,CAAC,OAAO,EAAE,CAAA;QACd,IAAI,CAAC,eAAe,EAAE,CAAA;IACxB,CAAC;IAED,wEAAwE;IAChE,OAAO;QACb,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAA;QAClC,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACvC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QACpD,CAAC;IACH,CAAC;IAEO,KAAK;QACX,IAAI,IAAI,CAAC,MAAM;YAAE,OAAM;QACvB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAA;QAClB,IAAI,CAAC,OAAO,EAAE,CAAA;QACd,sEAAsE;QACtE,uEAAuE;QACvE,wEAAwE;QACxE,oBAAoB;QACpB,IAAI,CAAC,OAAO,EAAE,EAAE,CAAA;QAChB,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAA;IAC1B,CAAC;IAED,oEAAoE;IACpE,OAAO,CAAa;CACrB;AAED;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CACnC,GAAQ,EACR,KAAe,EACf,IAAoB;IAEpB,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;QAC3B,IAAI,OAAO,GAAG,KAAK,CAAA;QACnB,MAAM,MAAM,GAAG,GAAS,EAAE;YACxB,IAAI,OAAO;gBAAE,OAAM;YACnB,OAAO,GAAG,IAAI,CAAA;YACd,OAAO,EAAE,CAAA;QACX,CAAC,CAAA;QACD,qEAAqE;QACrE,oEAAoE;QACpE,uEAAuE;QACvE,MAAM,IAAI,GAAG,IAAI,SAAS,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE;YAC1C,KAAK,CAAC,OAAO,EAAE,CAAA;YACf,IAAI,CAAC,YAAY,EAAE,CAAA;YACnB,MAAM,EAAE,CAAA;QACV,CAAC,CAAC,CAAA;QACF,MAAM,MAAM,GAAG,GAAS,EAAE;YACxB,IAAI,CAAC,KAAK,EAAE,CAAA;YACZ,IAAI,CAAC,YAAY,EAAE,CAAA;YACnB,MAAM,EAAE,CAAA;QACV,CAAC,CAAA;QACD,MAAM,KAAK,GAAG,IAAI,iBAAiB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,CAAA;QAC3E,KAAK,CAAC,OAAO,GAAG,MAAM,CAAA;QACtB,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAA;QAC7C,IAAI,MAAM,KAAK,SAAS;YAAE,KAAK,CAAC,YAAY,EAAE,CAAA;IAChD,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
package/lib/repair-dialog.d.ts
CHANGED
|
@@ -18,15 +18,15 @@
|
|
|
18
18
|
import { type Component, type TUI } from '@earendil-works/pi-tui';
|
|
19
19
|
import { type TuiTheme } from './theme/index.ts';
|
|
20
20
|
/** The two choices in display order; index 0 is preselected. */
|
|
21
|
-
export declare
|
|
21
|
+
export declare function repairConfirmOptions(): ReadonlyArray<{
|
|
22
22
|
id: 'repair' | 'cancel';
|
|
23
23
|
title: string;
|
|
24
24
|
hint: string;
|
|
25
25
|
}>;
|
|
26
26
|
/** The fixed body copy (spec wording): what happened, what repair does, what is kept. */
|
|
27
|
-
export declare
|
|
28
|
-
/** Footer hint —
|
|
29
|
-
export declare
|
|
27
|
+
export declare function repairConfirmMessage(): string;
|
|
28
|
+
/** Footer hint — resolved per call so a live language switch repaints it. */
|
|
29
|
+
export declare function repairConfirmFooter(): string;
|
|
30
30
|
/** Pure dialog state: which row is highlighted, and the terminal outcome. */
|
|
31
31
|
export interface RepairConfirmState {
|
|
32
32
|
selected: number;
|
package/lib/repair-dialog.js
CHANGED
|
@@ -16,19 +16,25 @@
|
|
|
16
16
|
* through `restoreFocus`.
|
|
17
17
|
*/
|
|
18
18
|
import { getKeybindings } from '@earendil-works/pi-tui';
|
|
19
|
+
import { t } from "./i18n/index.js";
|
|
19
20
|
import { PanelHost, panelThemeFns } from "./panels.js";
|
|
20
21
|
import { BOLD, RESET, ansiFg } from "./theme/index.js";
|
|
21
22
|
import { clipToWidth, wrapText } from "./text.js";
|
|
22
23
|
/** The two choices in display order; index 0 is preselected. */
|
|
23
|
-
export
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
export function repairConfirmOptions() {
|
|
25
|
+
return [
|
|
26
|
+
{ id: 'repair', title: t('repair.option.repair'), hint: t('repair.option.repairHint') },
|
|
27
|
+
{ id: 'cancel', title: t('repair.option.cancel'), hint: t('repair.option.cancelHint') },
|
|
28
|
+
];
|
|
29
|
+
}
|
|
27
30
|
/** The fixed body copy (spec wording): what happened, what repair does, what is kept. */
|
|
28
|
-
export
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
export function repairConfirmMessage() {
|
|
32
|
+
return t('repair.confirm.body');
|
|
33
|
+
}
|
|
34
|
+
/** Footer hint — resolved per call so a live language switch repaints it. */
|
|
35
|
+
export function repairConfirmFooter() {
|
|
36
|
+
return t('repair.footer');
|
|
37
|
+
}
|
|
32
38
|
export function initialRepairConfirmState() {
|
|
33
39
|
return { selected: 0 };
|
|
34
40
|
}
|
|
@@ -48,14 +54,14 @@ export function updateRepairConfirm(state, data) {
|
|
|
48
54
|
return { ...state, selected: Math.max(0, state.selected - 1) };
|
|
49
55
|
}
|
|
50
56
|
if (kb.matches(data, 'tui.select.down')) {
|
|
51
|
-
return { ...state, selected: Math.min(
|
|
57
|
+
return { ...state, selected: Math.min(repairConfirmOptions().length - 1, state.selected + 1) };
|
|
52
58
|
}
|
|
53
59
|
// Digit direct-select (1-based): selects the row, Enter still confirms —
|
|
54
60
|
// same select-then-confirm split as the routing dialog.
|
|
55
61
|
const digit = /^([1-9])$/.exec(data);
|
|
56
62
|
if (digit !== null) {
|
|
57
63
|
const index = Number(digit[1]) - 1;
|
|
58
|
-
if (index <
|
|
64
|
+
if (index < repairConfirmOptions().length)
|
|
59
65
|
return { ...state, selected: index };
|
|
60
66
|
}
|
|
61
67
|
return state;
|
|
@@ -64,7 +70,7 @@ export function updateRepairConfirm(state, data) {
|
|
|
64
70
|
export function repairConfirmOutcome(state) {
|
|
65
71
|
if (state.settled !== 'confirm')
|
|
66
72
|
return undefined;
|
|
67
|
-
return
|
|
73
|
+
return repairConfirmOptions()[state.selected]?.id;
|
|
68
74
|
}
|
|
69
75
|
/**
|
|
70
76
|
* The framed overlay component. Renders the fixed body copy plus the two
|
|
@@ -88,12 +94,13 @@ export class RepairConfirmPanel {
|
|
|
88
94
|
// Word-wrap the body FIRST, then paint (iron rule: width math runs on
|
|
89
95
|
// plain text, ANSI goes on after clipping).
|
|
90
96
|
const lines = [
|
|
91
|
-
fns.accent(BOLD + clipToWidth('
|
|
92
|
-
...wrapText(
|
|
97
|
+
fns.accent(BOLD + clipToWidth(t('repair.confirm.title'), wrap) + RESET),
|
|
98
|
+
...wrapText(repairConfirmMessage(), wrap).map(segment => fns.muted(clipToWidth(segment, wrap))),
|
|
93
99
|
'',
|
|
94
100
|
];
|
|
95
|
-
|
|
96
|
-
|
|
101
|
+
const options = repairConfirmOptions();
|
|
102
|
+
for (let i = 0; i < options.length; i++) {
|
|
103
|
+
const option = options[i];
|
|
97
104
|
const marker = i === this.state.selected ? '▸' : ' ';
|
|
98
105
|
const row = clipToWidth(`${marker} ${i + 1}. ${option.title} — ${option.hint}`, wrap);
|
|
99
106
|
lines.push(i === this.state.selected
|
|
@@ -101,7 +108,7 @@ export class RepairConfirmPanel {
|
|
|
101
108
|
: fns.muted(row));
|
|
102
109
|
}
|
|
103
110
|
lines.push('');
|
|
104
|
-
lines.push(fns.subtle(clipToWidth(
|
|
111
|
+
lines.push(fns.subtle(clipToWidth(repairConfirmFooter(), wrap)));
|
|
105
112
|
return lines;
|
|
106
113
|
}
|
|
107
114
|
handleInput(data) {
|
package/lib/repair-dialog.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repair-dialog.js","sourceRoot":"","sources":["../src/repair-dialog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,cAAc,EAA4B,MAAM,wBAAwB,CAAA;AACjF,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACtD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAiB,MAAM,kBAAkB,CAAA;AACrE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAEjD,gEAAgE;AAChE,MAAM,
|
|
1
|
+
{"version":3,"file":"repair-dialog.js","sourceRoot":"","sources":["../src/repair-dialog.ts"],"names":[],"mappings":"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"}
|
package/lib/route-dialog.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ import { type Component, type TUI } from '@earendil-works/pi-tui';
|
|
|
18
18
|
import type { PromptRoute } from './steer-flow.ts';
|
|
19
19
|
import { type TuiTheme } from './theme/index.ts';
|
|
20
20
|
/** The two routing choices in display order (design §二.1). */
|
|
21
|
-
export declare
|
|
21
|
+
export declare function routeOptions(): ReadonlyArray<{
|
|
22
22
|
id: PromptRoute;
|
|
23
23
|
title: string;
|
|
24
24
|
hint: string;
|
|
@@ -40,8 +40,8 @@ export declare function initialRouteDialogState(): RouteDialogState;
|
|
|
40
40
|
export declare function updateRouteDialog(state: RouteDialogState, data: string): RouteDialogState;
|
|
41
41
|
/** Resolved dialog outcome: the chosen route, or undefined on cancel. */
|
|
42
42
|
export declare function routeDialogOutcome(state: RouteDialogState): PromptRoute | undefined;
|
|
43
|
-
/** Footer hint —
|
|
44
|
-
export declare
|
|
43
|
+
/** Footer hint — resolved per call so a live language switch repaints it. */
|
|
44
|
+
export declare function routeDialogFooter(): string;
|
|
45
45
|
/**
|
|
46
46
|
* The framed overlay component. Renders the draft preview plus the two
|
|
47
47
|
* option rows; every key goes through {@link updateRouteDialog}, and the
|
package/lib/route-dialog.js
CHANGED
|
@@ -15,15 +15,18 @@
|
|
|
15
15
|
* through `restoreFocus`.
|
|
16
16
|
*/
|
|
17
17
|
import { getKeybindings } from '@earendil-works/pi-tui';
|
|
18
|
+
import { t } from "./i18n/index.js";
|
|
18
19
|
import { PanelHost, panelThemeFns } from "./panels.js";
|
|
19
20
|
import { normalizePreview } from "./sessions.js";
|
|
20
21
|
import { BOLD, RESET, ansiFg } from "./theme/index.js";
|
|
21
22
|
import { clipToWidth } from "./text.js";
|
|
22
23
|
/** The two routing choices in display order (design §二.1). */
|
|
23
|
-
export
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
export function routeOptions() {
|
|
25
|
+
return [
|
|
26
|
+
{ id: 'followup', title: t('route.option.followup'), hint: t('route.option.followupHint') },
|
|
27
|
+
{ id: 'steer', title: t('route.option.steer'), hint: t('route.option.steerHint') },
|
|
28
|
+
];
|
|
29
|
+
}
|
|
27
30
|
export function initialRouteDialogState() {
|
|
28
31
|
return { selected: 0 };
|
|
29
32
|
}
|
|
@@ -43,14 +46,14 @@ export function updateRouteDialog(state, data) {
|
|
|
43
46
|
return { ...state, selected: Math.max(0, state.selected - 1) };
|
|
44
47
|
}
|
|
45
48
|
if (kb.matches(data, 'tui.select.down')) {
|
|
46
|
-
return { ...state, selected: Math.min(
|
|
49
|
+
return { ...state, selected: Math.min(routeOptions().length - 1, state.selected + 1) };
|
|
47
50
|
}
|
|
48
51
|
// Digit direct-select (1-based): selects the row, Enter still confirms —
|
|
49
52
|
// same select-then-confirm split as the design's "数字键选,Enter 确认".
|
|
50
53
|
const digit = /^([1-9])$/.exec(data);
|
|
51
54
|
if (digit !== null) {
|
|
52
55
|
const index = Number(digit[1]) - 1;
|
|
53
|
-
if (index <
|
|
56
|
+
if (index < routeOptions().length)
|
|
54
57
|
return { ...state, selected: index };
|
|
55
58
|
}
|
|
56
59
|
return state;
|
|
@@ -59,10 +62,12 @@ export function updateRouteDialog(state, data) {
|
|
|
59
62
|
export function routeDialogOutcome(state) {
|
|
60
63
|
if (state.settled !== 'confirm')
|
|
61
64
|
return undefined;
|
|
62
|
-
return
|
|
65
|
+
return routeOptions()[state.selected]?.id;
|
|
66
|
+
}
|
|
67
|
+
/** Footer hint — resolved per call so a live language switch repaints it. */
|
|
68
|
+
export function routeDialogFooter() {
|
|
69
|
+
return t('route.footer');
|
|
63
70
|
}
|
|
64
|
-
/** Footer hint — hardcoded like every other panel footer (English-only). */
|
|
65
|
-
export const ROUTE_DIALOG_FOOTER = '↑↓ select · 1/2 pick · Enter confirm · Esc cancel';
|
|
66
71
|
/**
|
|
67
72
|
* The framed overlay component. Renders the draft preview plus the two
|
|
68
73
|
* option rows; every key goes through {@link updateRouteDialog}, and the
|
|
@@ -89,12 +94,13 @@ export class RouteDialogPanel {
|
|
|
89
94
|
// overlay layout); the FULL raw text is what gets restored on Esc.
|
|
90
95
|
const preview = normalizePreview(this.draft, 400);
|
|
91
96
|
const lines = [
|
|
92
|
-
fns.accent(BOLD + clipToWidth('
|
|
93
|
-
fns.muted(clipToWidth(preview === '' ? '
|
|
97
|
+
fns.accent(BOLD + clipToWidth(t('route.title'), wrap) + RESET),
|
|
98
|
+
fns.muted(clipToWidth(preview === '' ? t('route.preview.empty') : preview, wrap)),
|
|
94
99
|
'',
|
|
95
100
|
];
|
|
96
|
-
|
|
97
|
-
|
|
101
|
+
const options = routeOptions();
|
|
102
|
+
for (let i = 0; i < options.length; i++) {
|
|
103
|
+
const option = options[i];
|
|
98
104
|
const marker = i === this.state.selected ? '▸' : ' ';
|
|
99
105
|
const row = clipToWidth(`${marker} ${i + 1}. ${option.title} — ${option.hint}`, wrap);
|
|
100
106
|
lines.push(i === this.state.selected
|
|
@@ -102,7 +108,7 @@ export class RouteDialogPanel {
|
|
|
102
108
|
: fns.muted(row));
|
|
103
109
|
}
|
|
104
110
|
lines.push('');
|
|
105
|
-
lines.push(fns.subtle(clipToWidth(
|
|
111
|
+
lines.push(fns.subtle(clipToWidth(routeDialogFooter(), wrap)));
|
|
106
112
|
return lines;
|
|
107
113
|
}
|
|
108
114
|
handleInput(data) {
|