fix: rebase 2
This commit is contained in:
@@ -156,7 +156,7 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
slotInject: '',
|
||||
declaredBy: 'an entry in \'conversation.chat.node\' (client-ui-conversation), so it exists while that entry is mounted',
|
||||
occupants: [
|
||||
'client-ui-feedback FeedbackActions id \'feedback\'',
|
||||
'client-ui-message-feedback MessageFeedbackActions id \'feedback\'',
|
||||
],
|
||||
replaceRisk: 'none',
|
||||
example: 'return {\n inject: [\'slots\'],\n apply(ctx) {\n ctx.slots.inject(\'conversation.chat.assistant-actions\', () => ctx.slots.register(\n { name: \'conversation.chat.assistant-actions\', id: \'my-entry\', order: 100, label: \'My entry\' },\n () => React.createElement(\'div\', null, \'hello\'),\n ))\n },\n}',
|
||||
@@ -333,8 +333,8 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
declaredBy: 'an entry in \'conversation\' (client-ui-conversation), so it exists while that entry is mounted',
|
||||
occupants: [
|
||||
'client-ui-conversation ApprovalPanel',
|
||||
'client-ui-question QuestionComposer',
|
||||
'client-ui-subagent SubagentReadOnlyComposer',
|
||||
'client-ui-user-questions QuestionComposer',
|
||||
],
|
||||
replaceRisk: 'none',
|
||||
example: 'return {\n inject: [\'slots\'],\n apply(ctx) {\n ctx.slots.inject(\'conversation.composer\', () => ctx.slots.register(\n { name: \'conversation.composer\', select: owner => null },\n () => React.createElement(\'div\', null, \'hello\'),\n ))\n },\n}',
|
||||
@@ -531,8 +531,8 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
slotInject: '',
|
||||
declaredBy: 'an entry in \'conversation.hero.workspace\' (client-ui-workspace), so it exists while that entry is mounted',
|
||||
occupants: [
|
||||
'client-ui-directory-picker-browse BrowseDirectoryFlow',
|
||||
'client-ui-directory-picker-native NativeDirectoryFlow',
|
||||
'client-ui-directory-picker BrowseDirectoryFlow',
|
||||
],
|
||||
replaceRisk: 'shadows-shipped-ui',
|
||||
example: 'return {\n inject: [\'slots\'],\n apply(ctx) {\n ctx.slots.inject(\'conversation.hero.workspace.directoryFlow\', () => ctx.slots.register(\n { name: \'conversation.hero.workspace.directoryFlow\' },\n () => React.createElement(\'div\', null, \'hello\'),\n ))\n },\n}',
|
||||
@@ -669,7 +669,7 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
slotInject: '',
|
||||
declaredBy: 'an entry in \'conversation.composer.bar\' (client-ui-conversation), so it exists while that entry is mounted',
|
||||
occupants: [
|
||||
'client-ui-model ModelSelect',
|
||||
'client-ui-model-selection ModelSelect',
|
||||
],
|
||||
replaceRisk: 'shadows-shipped-ui',
|
||||
example: 'return {\n inject: [\'slots\'],\n apply(ctx) {\n ctx.slots.inject(\'conversation.input.model\', () => ctx.slots.register(\n { name: \'conversation.input.model\' },\n () => React.createElement(\'div\', null, \'hello\'),\n ))\n },\n}',
|
||||
@@ -679,8 +679,8 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
key: 'conversation.input.overlay',
|
||||
kind: 'list',
|
||||
scope: 'session',
|
||||
summary: 'The InputBar floating overlay anchor: MenuView (this package) and the popupSelect shell (ui-command) contribute list entries; each reads its own store and renders null while closed.',
|
||||
doc: 'The InputBar floating overlay anchor: MenuView (this package) and the\npopupSelect shell (ui-command) contribute list entries; each reads its\nown store and renders null while closed. Declared (children table) by\nui-conversation\'s composer entry; the anchor hides with the input\nunder a takeover.',
|
||||
summary: 'The InputBar floating overlay anchor: MenuView (this package) and the popupSelect shell (ui-commands) contribute list entries; each reads its own store and renders null while closed.',
|
||||
doc: 'The InputBar floating overlay anchor: MenuView (this package) and the\npopupSelect shell (ui-commands) contribute list entries; each reads its\nown store and renders null while closed. Declared (children table) by\nui-conversation\'s composer entry; the anchor hides with the input\nunder a takeover.',
|
||||
registerOptions: [
|
||||
{
|
||||
name: 'id',
|
||||
@@ -717,12 +717,12 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
slotInject: '',
|
||||
declaredBy: 'an entry in \'conversation\' (client-ui-conversation), so it exists while that entry is mounted',
|
||||
occupants: [
|
||||
'client-ui-command PopupSelectView id \'command-popup\'',
|
||||
'client-ui-slash MenuView id \'slash-menu\'',
|
||||
'client-ui-commands PopupSelectView id \'command-popup\'',
|
||||
'client-ui-input-trigger MenuView id \'slash-menu\'',
|
||||
],
|
||||
replaceRisk: 'none',
|
||||
example: 'return {\n inject: [\'slots\'],\n apply(ctx) {\n ctx.slots.inject(\'conversation.input.overlay\', () => ctx.slots.register(\n { name: \'conversation.input.overlay\', id: \'my-entry\', order: 100, label: \'My entry\' },\n () => React.createElement(\'div\', null, \'hello\'),\n ))\n },\n}',
|
||||
source: 'packages/client/ui-slash/src/client/slots.ts:24',
|
||||
source: 'packages/client/ui-input-trigger/src/client/slots.ts:24',
|
||||
},
|
||||
{
|
||||
key: 'conversation.input.plan',
|
||||
@@ -909,8 +909,8 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
declaredBy: 'an entry in \'conversation.session.header\' (client-ui-conversation), so it exists while that entry is mounted',
|
||||
occupants: [
|
||||
'client-ui-agent-preset AgentPresetLabel id \'agent-preset\'',
|
||||
'client-ui-jobs JobListAction id \'job-list\'',
|
||||
'client-ui-subagent SubagentCatalogAction id \'subagent-catalog\'',
|
||||
'client-ui-task TaskListAction id \'task-list\'',
|
||||
],
|
||||
replaceRisk: 'none',
|
||||
example: 'return {\n inject: [\'slots\'],\n apply(ctx) {\n ctx.slots.inject(\'conversation.session.header.actions\', () => ctx.slots.register(\n { name: \'conversation.session.header.actions\', id: \'my-entry\', order: 100, label: \'My entry\' },\n () => React.createElement(\'div\', null, \'hello\'),\n ))\n },\n}',
|
||||
@@ -960,7 +960,7 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
slotInject: '',
|
||||
declaredBy: 'an entry in \'conversation.session.header\' (client-ui-conversation), so it exists while that entry is mounted',
|
||||
occupants: [
|
||||
'session-export SessionExportHeader id \'session-export\'',
|
||||
'session-log-download SessionLogDownloadHeaderAction id \'session-log-download\'',
|
||||
],
|
||||
replaceRisk: 'none',
|
||||
example: 'return {\n inject: [\'slots\'],\n apply(ctx) {\n ctx.slots.inject(\'conversation.session.header.utilities\', () => ctx.slots.register(\n { name: \'conversation.session.header.utilities\', id: \'my-entry\', order: 100, label: \'My entry\' },\n () => React.createElement(\'div\', null, \'hello\'),\n ))\n },\n}',
|
||||
@@ -1187,7 +1187,7 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
'client-locale LanguageRow id \'language\'',
|
||||
'client-ui-agent-preset AgentPresetRow id \'agent-preset\'',
|
||||
'client-ui-conversation EnterBehaviorRow id \'composer-enter\'',
|
||||
'client-ui-permission PermissionRow id \'permission\'',
|
||||
'client-ui-permission-presets PermissionRow id \'permission\'',
|
||||
'client-ui-theme AppearanceRow id \'appearance\'',
|
||||
],
|
||||
replaceRisk: 'none',
|
||||
@@ -1259,8 +1259,8 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
slotInject: '',
|
||||
declaredBy: 'an entry in \'sidebar.settings\' (client-ui-settings-general), so it exists while that entry is mounted',
|
||||
occupants: [
|
||||
'client-ui-models DeepSeekOnboardingDialog id \'deepseek-official\'',
|
||||
'client-ui-settings-general WelcomeNotice id \'welcome-notice\'',
|
||||
'client-ui-settings-models DeepSeekOnboardingDialog id \'deepseek-official\'',
|
||||
],
|
||||
replaceRisk: 'none',
|
||||
example: 'return {\n inject: [\'slots\'],\n apply(ctx) {\n ctx.slots.inject(\'settings.onboarding\', () => ctx.slots.register(\n { name: \'settings.onboarding\', id: \'my-entry\', order: 100, label: \'My entry\' },\n () => React.createElement(\'div\', null, \'hello\'),\n ))\n },\n}',
|
||||
@@ -1303,15 +1303,15 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
keyDomain: '',
|
||||
hookContext: '',
|
||||
slotInject: '',
|
||||
declaredBy: 'an entry in \'settings.plugins.tab\' (client-ui-plugin-config), so it exists while that entry is mounted',
|
||||
declaredBy: 'an entry in \'settings.plugins.tab\' (client-ui-settings-plugins), so it exists while that entry is mounted',
|
||||
occupants: [
|
||||
'client-ui-plugin-config BashCard id \'bash\'',
|
||||
'client-ui-plugin-config AgentLoopCard id \'agent-loop\'',
|
||||
'client-ui-plugin-config WebSearchCard id \'web-search\'',
|
||||
'client-ui-settings-plugins BashCard id \'bash\'',
|
||||
'client-ui-settings-plugins AgentLoopCard id \'agent-loop\'',
|
||||
'client-ui-settings-plugins WebSearchCard id \'web-search\'',
|
||||
],
|
||||
replaceRisk: 'none',
|
||||
example: 'return {\n inject: [\'slots\'],\n apply(ctx) {\n ctx.slots.inject(\'settings.plugin.item\', () => ctx.slots.register(\n { name: \'settings.plugin.item\', id: \'my-entry\', order: 100, label: \'My entry\' },\n () => React.createElement(\'div\', null, \'hello\'),\n ))\n },\n}',
|
||||
source: 'packages/client/ui-plugin-config/src/client/slot-contract.ts:16',
|
||||
source: 'packages/client/ui-settings-plugins/src/client/slot-contract.ts:16',
|
||||
},
|
||||
{
|
||||
key: 'settings.plugins.tab',
|
||||
@@ -1350,10 +1350,10 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
keyDomain: '',
|
||||
hookContext: '',
|
||||
slotInject: '',
|
||||
declaredBy: 'an entry in \'settings.section\' (client-ui-plugin-config), so it exists while that entry is mounted',
|
||||
declaredBy: 'an entry in \'settings.section\' (client-ui-settings-plugins), so it exists while that entry is mounted',
|
||||
occupants: [
|
||||
'client-ui-plugin-config ConfigurablePluginsTab id \'configurable\'',
|
||||
'client-ui-plugins PluginSettingsSection id \'all\'',
|
||||
'client-ui-settings-plugin-inventory PluginInventorySettingsTab id \'all\'',
|
||||
'client-ui-settings-plugins ConfigurablePluginsTab id \'configurable\'',
|
||||
],
|
||||
replaceRisk: 'none',
|
||||
example: 'return {\n inject: [\'slots\'],\n apply(ctx) {\n ctx.slots.inject(\'settings.plugins.tab\', () => ctx.slots.register(\n { name: \'settings.plugins.tab\', id: \'my-entry\', order: 100, label: \'My entry\' },\n () => React.createElement(\'div\', null, \'hello\'),\n ))\n },\n}',
|
||||
@@ -1399,9 +1399,9 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
declaredBy: 'an entry in \'sidebar.settings\' (client-ui-settings-general), so it exists while that entry is mounted',
|
||||
occupants: [
|
||||
'client-ui-agent-preset AgentPresetSection id \'agent-presets\'',
|
||||
'client-ui-models ModelsSection id \'models\'',
|
||||
'client-ui-plugin-config PluginConfigSection id \'plugins\'',
|
||||
'client-ui-settings-general GeneralSection id \'general\'',
|
||||
'client-ui-settings-models ModelsSection id \'models\'',
|
||||
'client-ui-settings-plugins PluginsSettingsSection id \'plugins\'',
|
||||
],
|
||||
replaceRisk: 'none',
|
||||
example: 'return {\n inject: [\'slots\'],\n apply(ctx) {\n ctx.slots.inject(\'settings.section\', () => ctx.slots.register(\n { name: \'settings.section\', id: \'my-entry\', order: 100, label: \'My entry\' },\n () => React.createElement(\'div\', null, \'hello\'),\n ))\n },\n}',
|
||||
@@ -1617,8 +1617,8 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
slotInject: '',
|
||||
declaredBy: 'an entry in \'sidebar.workspaces\' (client-ui-workspace), so it exists while that entry is mounted',
|
||||
occupants: [
|
||||
'client-ui-directory-picker-browse BrowseDirectoryFlow',
|
||||
'client-ui-directory-picker-native NativeDirectoryFlow',
|
||||
'client-ui-directory-picker BrowseDirectoryFlow',
|
||||
],
|
||||
replaceRisk: 'shadows-shipped-ui',
|
||||
example: 'return {\n inject: [\'slots\'],\n apply(ctx) {\n ctx.slots.inject(\'sidebar.workspaces.directoryFlow\', () => ctx.slots.register(\n { name: \'sidebar.workspaces.directoryFlow\' },\n () => React.createElement(\'div\', null, \'hello\'),\n ))\n },\n}',
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/extensions/tool-cordis/README.md
|
||||
README.md: 839963b3b611f35389f8e4a424746ad0fcf5d02e
|
||||
README.zh.md: a4dd0686702c18fb329bdea42478ca74ca3a1502
|
||||
README.md: 396a844014328da8cfad57fa7728793b91a9aff7
|
||||
README.zh.md: b38a4b518a28f9af76ab22325606b8faa772c1c1
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,8 +14,6 @@ import type { Agent } from '@deepseek-ai/dsh-agent'
|
||||
import type {} from '@deepseek-ai/dsh-cordis-host-runner'
|
||||
import { EVENT_API, INHERITED_CTX_API, SERVICE_API, TYPE_API } from './api-catalog.ts'
|
||||
import type { EventApiEntry, InheritedApiEntry, ServiceApiEntry, ServiceApiMethod, TypeApiEntry } from './api-catalog.ts'
|
||||
import { CLIENT_NOTES, CLIENT_SLOT_API } from './client-catalog.ts'
|
||||
import type { ClientSlotEntry } from './client-catalog.ts'
|
||||
import { FiberState, STATE_LABELS } from './fiber-state.ts'
|
||||
|
||||
/** One live service joined with what the generated catalog knows about it. */
|
||||
@@ -332,72 +330,3 @@ export function describeEvents(events: readonly EventApiEntry[] = EVENT_API, nam
|
||||
lines.push('waterfall listeners receive a trailing next() and MUST call it to delegate — returning without next() short-circuits the chain.')
|
||||
return lines
|
||||
}
|
||||
|
||||
/** One slot's compact listing row: what it is, and whether registering costs shipped UI. */
|
||||
function slotSummaryLines(entry: ClientSlotEntry): string[] {
|
||||
const lines = [`- ${entry.key} [${entry.kind}, ${entry.scope}] — ${entry.summary}`]
|
||||
lines.push(entry.replaceRisk === 'shadows-shipped-ui'
|
||||
? ` OCCUPIED — registering here REPLACES: ${entry.occupants.join('; ')}`
|
||||
: ` additive${entry.occupants.length === 0 ? ' (no shipped entries)' : ` (beside: ${entry.occupants.join('; ')})`}`)
|
||||
return lines
|
||||
}
|
||||
|
||||
/** One slot's full teaching block: how to register, what arrives, what it costs. */
|
||||
function slotDetailLines(entry: ClientSlotEntry): string[] {
|
||||
const lines = [`- ${entry.key} [${entry.kind}, ${entry.scope}]`]
|
||||
for (const docLine of entry.doc.split('\n')) lines.push(` ${docLine}`)
|
||||
lines.push(` exists: ${entry.declaredBy}`)
|
||||
lines.push(entry.replaceRisk === 'shadows-shipped-ui'
|
||||
? ` OCCUPIED — registering here REPLACES: ${entry.occupants.join('; ')}`
|
||||
: ` additive${entry.occupants.length === 0 ? ' (no shipped entries)' : ` (beside: ${entry.occupants.join('; ')})`}`)
|
||||
if (entry.keyDomain !== '') lines.push(` key domain: ${entry.keyDomain}`)
|
||||
lines.push(` register options besides name:${entry.registerOptions.length === 0 ? ' none' : ''}`)
|
||||
for (const option of entry.registerOptions) {
|
||||
lines.push(` ${option.name} (${option.requirement}, ${option.type}) — ${option.doc}`)
|
||||
}
|
||||
lines.push(entry.ownerProps.length === 0
|
||||
? ' owner props: none — the owner supplies only the render site'
|
||||
: ' owner props (the shapes the owner passes down):')
|
||||
for (const declaration of entry.ownerProps) {
|
||||
for (const declLine of declaration.split('\n')) lines.push(` ${declLine}`)
|
||||
}
|
||||
if (entry.ownerPropsReferences.length > 0) {
|
||||
lines.push(` shapes those fields reference, not expanded here: ${entry.ownerPropsReferences.join(', ')}`
|
||||
+ ' — read the field as the contract above describes it rather than the whole shape')
|
||||
}
|
||||
lines.push(' framework props for this scope:')
|
||||
for (const prop of entry.standardProps) lines.push(` ${prop}`)
|
||||
if (entry.slotInject !== '') lines.push(` slot-level inject face every entry receives: ${entry.slotInject}`)
|
||||
if (entry.hookContext !== '') lines.push(` per-render-site hook context: ${entry.hookContext}`)
|
||||
lines.push(' minimal browser half:')
|
||||
for (const codeLine of entry.example.split('\n')) lines.push(` ${codeLine}`)
|
||||
return lines
|
||||
}
|
||||
|
||||
/**
|
||||
* The `client` section: the browser half's slot surface — every seat a dynamic
|
||||
* package can contribute UI into, whether taking it costs shipped UI, and (with
|
||||
* an exact `name`) the full register contract for one seat. Compile-time data
|
||||
* from the shipped web bundle, so it needs no live runtime.
|
||||
* @param slots - the generated slot catalog (injectable for tests).
|
||||
* @param notes - the cross-cutting registrant rules (injectable for tests).
|
||||
* @param name - exact slot key to expand; omitted for the compact catalog.
|
||||
* @returns the section lines.
|
||||
* @throws when `name` is not a catalogued slot key.
|
||||
*/
|
||||
export function describeClient(
|
||||
slots: readonly ClientSlotEntry[] = CLIENT_SLOT_API,
|
||||
notes: readonly string[] = CLIENT_NOTES,
|
||||
name?: string,
|
||||
): string[] {
|
||||
if (name !== undefined) {
|
||||
const entry = slots.find(candidate => candidate.key === name)
|
||||
if (!entry) throw new Error(`no catalogued client slot named "${name}"`)
|
||||
return slotDetailLines(entry)
|
||||
}
|
||||
const lines = slots.flatMap(entry => slotSummaryLines(entry))
|
||||
lines.push('how to contribute:')
|
||||
for (const note of notes) lines.push(`- ${note}`)
|
||||
lines.push('pass name:"<slot key>" with what:"client" for one slot\'s register options, owner/framework props, and a minimal browser half.')
|
||||
return lines
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ export type { CordisKey } from './locales.ts'
|
||||
|
||||
/** Required services for the two Tool cards, panel, Remote lifecycle, and Slash source. */
|
||||
export const inject = [
|
||||
'slots', 'locale', 'slash', 'remote', 'remote.dynamicCordisRunner', 'dynamicCordisRunner',
|
||||
'slots', 'locale', 'inputTriggers', 'remote', 'remote.dynamicCordisRunner', 'dynamicCordisRunner',
|
||||
]
|
||||
|
||||
/** Mount every Cordis browser surface over the shared Host inventory. */
|
||||
@@ -153,7 +153,7 @@ export function apply(ctx: ClientContext): void {
|
||||
subscribeLexicon(_session, listener) { return inventory.subscribe(listener) },
|
||||
onPick({ candidate }) { return { text: `@${candidate.name} ` } },
|
||||
}
|
||||
const slash = ctx.get('slash') as InputTriggerService
|
||||
const slash = ctx.get('inputTriggers') as InputTriggerService
|
||||
ctx.effect(() => slash.registerSource(source), 'ui-cordis: @pluginId source')
|
||||
|
||||
inventory.refresh()
|
||||
|
||||
Reference in New Issue
Block a user