dsh-code 0.9.1 → 1.0.1
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.en.md +278 -249
- package/README.md +131 -102
- package/bin/deepseek.mjs +100 -6
- package/cordis.patch.yml +36 -1
- package/lib/index.mjs +3055 -819
- package/lib/startup.mjs +21 -11
- package/lib/{theme-BEi4i_aN.mjs → theme-DCT8Y2xf.mjs} +13 -9
- package/lib/types/app.d.ts +84 -16
- package/lib/types/attachments.d.ts +20 -0
- package/lib/types/authorization-panel.d.ts +22 -0
- package/lib/types/authorization.d.ts +36 -0
- package/lib/types/editor.d.ts +6 -0
- package/lib/types/fork.d.ts +8 -0
- package/lib/types/git-workflow.d.ts +23 -0
- package/lib/types/index.d.ts +6 -0
- package/lib/types/kernel-panels.d.ts +39 -0
- package/lib/types/keyboard.d.ts +41 -0
- package/lib/types/mentions.d.ts +30 -38
- package/lib/types/models.d.ts +3 -1
- package/lib/types/permissions.d.ts +4 -14
- package/lib/types/presets.d.ts +5 -20
- package/lib/types/provider-settings.d.ts +16 -0
- package/lib/types/render/animations.d.ts +10 -39
- package/lib/types/render/editor.d.ts +137 -0
- package/lib/types/render/export.d.ts +1 -1
- package/lib/types/render/lines.d.ts +6 -2
- package/lib/types/render/markdown.d.ts +3 -1
- package/lib/types/render/projection.d.ts +29 -3
- package/lib/types/render/status.d.ts +6 -13
- package/lib/types/session-directory.d.ts +1 -3
- package/lib/types/startup.d.ts +14 -11
- package/lib/types/store.d.ts +11 -9
- package/lib/types/subagents.d.ts +3 -3
- package/lib/types/theme.d.ts +14 -1
- package/lib/types/version.d.ts +15 -2
- package/package.json +159 -141
- package/src/app.ts +1490 -663
- package/src/attachments.ts +128 -0
- package/src/authorization-panel.ts +285 -0
- package/src/authorization.ts +147 -0
- package/src/editor.ts +51 -0
- package/src/fork.ts +31 -0
- package/src/git-workflow.ts +87 -0
- package/src/index.ts +1523 -1374
- package/src/internals.ts +14 -1
- package/src/kernel-panels.ts +914 -798
- package/src/keyboard.ts +126 -0
- package/src/mentions.ts +78 -117
- package/src/models.ts +20 -14
- package/src/permissions.ts +5 -13
- package/src/presets.ts +6 -22
- package/src/provider-settings.ts +95 -1
- package/src/render/animations.ts +420 -450
- package/src/render/editor.ts +398 -0
- package/src/render/export.ts +79 -79
- package/src/render/lines.ts +342 -236
- package/src/render/markdown.ts +99 -26
- package/src/render/projection.ts +106 -19
- package/src/render/status.ts +713 -650
- package/src/render/text.ts +150 -150
- package/src/render/tool-detail.ts +3 -1
- package/src/session-directory.ts +4 -4
- package/src/startup.ts +136 -119
- package/src/store.ts +23 -11
- package/src/subagents.ts +13 -5
- package/src/theme.ts +214 -206
- package/src/version.ts +58 -1
package/src/provider-settings.ts
CHANGED
|
@@ -129,6 +129,28 @@ function profileRefOf(profile: unknown): string | undefined {
|
|
|
129
129
|
return typeof ref === 'string' && ref.length > 0 ? ref : undefined
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
+
/** Extract only fields the terminal can round-trip without touching provider-specific extras. */
|
|
133
|
+
function configurationOf(profile: unknown): ProviderConfiguration {
|
|
134
|
+
if (typeof profile !== 'object' || profile === null) return { models: [] }
|
|
135
|
+
const record = profile as Record<string, unknown>
|
|
136
|
+
const source = Array.isArray(record.models) ? record.models : []
|
|
137
|
+
const models = source.flatMap((value): ProviderModelSettings[] => {
|
|
138
|
+
if (typeof value !== 'object' || value === null) return []
|
|
139
|
+
const entry = value as Record<string, unknown>
|
|
140
|
+
if (typeof entry.id !== 'string' || entry.id.trim() === '') return []
|
|
141
|
+
return [{
|
|
142
|
+
id: entry.id,
|
|
143
|
+
...(typeof entry.name === 'string' && entry.name.trim() !== '' ? { name: entry.name } : {}),
|
|
144
|
+
...(typeof entry.contextWindow === 'number' && Number.isFinite(entry.contextWindow) ? { contextWindow: entry.contextWindow } : {}),
|
|
145
|
+
...(typeof entry.maxTokens === 'number' && Number.isFinite(entry.maxTokens) ? { maxTokens: entry.maxTokens } : {}),
|
|
146
|
+
}]
|
|
147
|
+
})
|
|
148
|
+
return {
|
|
149
|
+
...(typeof record.baseURL === 'string' && record.baseURL.trim() !== '' ? { baseURL: record.baseURL } : {}),
|
|
150
|
+
models,
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
132
154
|
/* ------------------------------------------------------------------ *
|
|
133
155
|
* Exported contracts.
|
|
134
156
|
* ------------------------------------------------------------------ */
|
|
@@ -166,6 +188,20 @@ export type ProviderCredentialView =
|
|
|
166
188
|
| ({ readonly kind: 'facts' } & ProviderCredentialFacts)
|
|
167
189
|
| { readonly kind: 'error'; readonly message: string }
|
|
168
190
|
|
|
191
|
+
/** One explicit model enabled for a provider profile. */
|
|
192
|
+
export interface ProviderModelSettings {
|
|
193
|
+
readonly id: string
|
|
194
|
+
readonly name?: string
|
|
195
|
+
readonly contextWindow?: number
|
|
196
|
+
readonly maxTokens?: number
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/** The small, portable subset of a provider profile the terminal edits. */
|
|
200
|
+
export interface ProviderConfiguration {
|
|
201
|
+
readonly baseURL?: string
|
|
202
|
+
readonly models: readonly ProviderModelSettings[]
|
|
203
|
+
}
|
|
204
|
+
|
|
169
205
|
/**
|
|
170
206
|
* One provider row in the TUI provider-management panel: the configurable
|
|
171
207
|
* directory entry joined with its settings profile and credential facts.
|
|
@@ -195,6 +231,8 @@ export interface ProviderTargetView {
|
|
|
195
231
|
readonly suggestedRef: string
|
|
196
232
|
/** Credential facts, a bounded describe error, or undefined when there is no ref to describe. */
|
|
197
233
|
readonly credential: ProviderCredentialView | undefined
|
|
234
|
+
/** Endpoint and explicit model overrides visible to the provider editor. */
|
|
235
|
+
readonly configuration: ProviderConfiguration
|
|
198
236
|
/** The owning adapter reports this route as hand-declared (absent when it draws no distinction). */
|
|
199
237
|
readonly declared?: boolean
|
|
200
238
|
}
|
|
@@ -211,7 +249,7 @@ export interface ProviderSettingsDirectory {
|
|
|
211
249
|
|
|
212
250
|
/** Events that invalidate the official Models provider/settings/credential join. */
|
|
213
251
|
const PROVIDER_SETTINGS_EVENTS = [
|
|
214
|
-
'credentials/updated',
|
|
252
|
+
'credentials/reference-updated',
|
|
215
253
|
'settings/document-updated',
|
|
216
254
|
'llm/adapters-updated',
|
|
217
255
|
] as const
|
|
@@ -339,6 +377,7 @@ export async function loadProviderSettings(ctx: Context): Promise<ProviderSettin
|
|
|
339
377
|
settingsRevision: namespace?.revision ?? 0,
|
|
340
378
|
configured,
|
|
341
379
|
removable,
|
|
380
|
+
configuration: configurationOf(profile),
|
|
342
381
|
...credentialRef === undefined ? {} : { credentialRef },
|
|
343
382
|
suggestedRef: deriveCredentialRef(base.provider),
|
|
344
383
|
...base.declared === undefined ? {} : { declared: base.declared },
|
|
@@ -441,6 +480,61 @@ export async function saveProviderCredential(ctx: Context, target: ProviderTarge
|
|
|
441
480
|
}
|
|
442
481
|
}
|
|
443
482
|
|
|
483
|
+
/** Save the endpoint and an explicit model allow-list without rebuilding the profile. */
|
|
484
|
+
export async function saveProviderConfiguration(
|
|
485
|
+
ctx: Context,
|
|
486
|
+
target: ProviderTargetView,
|
|
487
|
+
configuration: ProviderConfiguration,
|
|
488
|
+
): Promise<void> {
|
|
489
|
+
if (target.settingsNs.length === 0) {
|
|
490
|
+
throw new ProviderSettingsError(`provider "${target.provider}" has no managed settings namespace; configure it in settings.yaml`)
|
|
491
|
+
}
|
|
492
|
+
const settings = ctx.get('settings') as SettingsFace | undefined
|
|
493
|
+
if (settings === undefined || settings.writable !== true) {
|
|
494
|
+
throw new ProviderSettingsError('settings are read-only; provider configuration cannot be changed here')
|
|
495
|
+
}
|
|
496
|
+
const baseURL = configuration.baseURL?.trim()
|
|
497
|
+
if (baseURL !== undefined && baseURL !== '') {
|
|
498
|
+
try {
|
|
499
|
+
const parsed = new URL(baseURL)
|
|
500
|
+
if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') throw new Error('unsupported protocol')
|
|
501
|
+
} catch {
|
|
502
|
+
throw new ProviderSettingsError('base URL must be an absolute http or https URL')
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
const seen = new Set<string>()
|
|
506
|
+
const models = configuration.models.map((model) => {
|
|
507
|
+
const id = model.id.trim()
|
|
508
|
+
if (id === '' || seen.has(id)) throw new ProviderSettingsError('each selected model must have a unique non-empty id')
|
|
509
|
+
seen.add(id)
|
|
510
|
+
for (const [label, value] of [['context window', model.contextWindow], ['output window', model.maxTokens]] as const) {
|
|
511
|
+
if (value !== undefined && (!Number.isSafeInteger(value) || value <= 0)) {
|
|
512
|
+
throw new ProviderSettingsError(`${label} must be a positive integer`)
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
return {
|
|
516
|
+
id,
|
|
517
|
+
...(model.name === undefined || model.name.trim() === '' ? {} : { name: model.name.trim() }),
|
|
518
|
+
...(model.contextWindow === undefined ? {} : { contextWindow: model.contextWindow }),
|
|
519
|
+
...(model.maxTokens === undefined ? {} : { maxTokens: model.maxTokens }),
|
|
520
|
+
}
|
|
521
|
+
})
|
|
522
|
+
const root = target.settingsPath
|
|
523
|
+
const ops: SettingsPathOpFace[] = [
|
|
524
|
+
baseURL === undefined || baseURL === ''
|
|
525
|
+
? { op: 'unset', path: [...root, 'baseURL'] }
|
|
526
|
+
: { op: 'set', path: [...root, 'baseURL'], value: baseURL },
|
|
527
|
+
// An explicit empty list is deliberate: it prevents a provider's shipped
|
|
528
|
+
// catalog from silently becoming the active selection.
|
|
529
|
+
{ op: 'set', path: [...root, 'models'], value: models },
|
|
530
|
+
]
|
|
531
|
+
try {
|
|
532
|
+
await settings.mutate(target.settingsNs, ops, target.settingsRevision)
|
|
533
|
+
} catch (error) {
|
|
534
|
+
throw new ProviderSettingsError(singleLine(messageOf(error)))
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
|
|
444
538
|
/**
|
|
445
539
|
* Remove the currently named credential without touching the provider
|
|
446
540
|
* profile. Only the resolved profile's own reference is unset; a dormant or
|