fix: test/docs
This commit is contained in:
@@ -122,36 +122,36 @@ export const SERVICE_API: readonly ServiceApiEntry[] = [
|
||||
{
|
||||
signature: 'subscribe(fn: () => void): () => void',
|
||||
description: 'LocaleFace subscribe: notified on every snapshot change (locale switch or dictionary registration — registrations bump the revision so already rendered outlets pick up late-arriving dictionaries).',
|
||||
parameters: [{"name":"fn","description":"change callback."}],
|
||||
parameters: [{ name: 'fn', description: 'change callback.' }],
|
||||
returns: 'unsubscribe.',
|
||||
},
|
||||
{
|
||||
signature: 'setLocale(id: string): void',
|
||||
description: 'Switch the active locale — the only user preference write entry.',
|
||||
parameters: [{"name":"id","description":"a registered locale id; unknown ids throw."}],
|
||||
parameters: [{ name: 'id', description: 'a registered locale id; unknown ids throw.' }],
|
||||
},
|
||||
{
|
||||
signature: 'register<N extends keyof LocaleNamespaceMap & string>(ns: N, dicts: Record<LocaleId, LocaleDictOf<N>>): () => void',
|
||||
description: 'Register a declared namespace\'s dictionaries, all locales in one call — the typed form: each dictionary is checked against the namespace\'s LocaleNamespaceMap key union (a missing or extra key is a compile error), and every shipped locale is required (bilingual balance enforced at registration). Duplicate (ns, locale) throws (single occupant; a namespace\'s texts have one owner). Registration bumps the revision so mounted outlets pick up late-arriving dictionaries.',
|
||||
parameters: [{"name":"ns","description":"a namespace merged into LocaleNamespaceMap."},{"name":"dicts","description":"complete dictionaries keyed by locale id."}],
|
||||
parameters: [{ name: 'ns', description: 'a namespace merged into LocaleNamespaceMap.' }, { name: 'dicts', description: 'complete dictionaries keyed by locale id.' }],
|
||||
returns: 'disposer removing every locale registered by this call (idempotent).',
|
||||
},
|
||||
{
|
||||
signature: 'register(ns: string, locale: string, dict: LocaleDict): () => void',
|
||||
description: 'Single-locale untyped form for namespaces outside the merge table (dynamic composition, tests).',
|
||||
parameters: [{"name":"ns","description":"namespace."},{"name":"locale","description":"locale tag."},{"name":"dict","description":"dictionary."}],
|
||||
parameters: [{ name: 'ns', description: 'namespace.' }, { name: 'locale', description: 'locale tag.' }, { name: 'dict', description: 'dictionary.' }],
|
||||
returns: 'disposer (idempotent).',
|
||||
},
|
||||
{
|
||||
signature: 'bind<N extends keyof LocaleNamespaceMap & string>(ns: N): TranslateNS<N>',
|
||||
description: 'Bind a declared namespace to a translate function typed to its dictionary key union (plus the shared common vocabulary) — the same key domain the framework-injected `t` seat carries. The returned reference is stable per namespace (repeat binds return the same function), so it can ride inject surfaces without breaking memoization.',
|
||||
parameters: [{"name":"ns","description":"a namespace merged into LocaleNamespaceMap."}],
|
||||
parameters: [{ name: 'ns', description: 'a namespace merged into LocaleNamespaceMap.' }],
|
||||
returns: 'the typed translate function (reads the active locale at call time).',
|
||||
},
|
||||
{
|
||||
signature: 'bind(ns: string): Translate',
|
||||
description: 'Untyped form for namespaces outside the merge table (dynamic composition, tests).',
|
||||
parameters: [{"name":"ns","description":"namespace."}],
|
||||
parameters: [{ name: 'ns', description: 'namespace.' }],
|
||||
returns: 'the translate function.',
|
||||
},
|
||||
],
|
||||
@@ -164,47 +164,47 @@ export const SERVICE_API: readonly ServiceApiEntry[] = [
|
||||
{
|
||||
signature: 'open(id: SessionId): void',
|
||||
description: 'Select a session as current.',
|
||||
parameters: [{"name":"id","description":"session id (must exist in the list; unknown ids fail loud)."}],
|
||||
parameters: [{ name: 'id', description: 'session id (must exist in the list; unknown ids fail loud).' }],
|
||||
},
|
||||
{
|
||||
signature: 'openSubagent(address: SubagentAddress): void',
|
||||
description: 'Open a healthy catalog child through its exact direct-parent address.',
|
||||
parameters: [{"name":"address","description":"catalog-derived parent and child ids."}],
|
||||
parameters: [{ name: 'address', description: 'catalog-derived parent and child ids.' }],
|
||||
},
|
||||
{
|
||||
signature: 'setSubagentCatalogOpen(parentSessionId: SessionId, open: boolean): void',
|
||||
description: 'Mark whether a catalog menu is consuming live membership updates.',
|
||||
parameters: [{"name":"parentSessionId","description":"catalog owner."},{"name":"open","description":"current menu state."}],
|
||||
parameters: [{ name: 'parentSessionId', description: 'catalog owner.' }, { name: 'open', description: 'current menu state.' }],
|
||||
},
|
||||
{
|
||||
signature: 'refreshSubagents(parentSessionId: SessionId): Promise<void>',
|
||||
description: 'Refresh one direct-child catalog.',
|
||||
parameters: [{"name":"parentSessionId","description":"catalog owner."}],
|
||||
parameters: [{ name: 'parentSessionId', description: 'catalog owner.' }],
|
||||
returns: 'completion of the current or newly started refresh.',
|
||||
},
|
||||
{
|
||||
signature: 'search( query: string, signal: AbortSignal, ): Promise<RpcResult<{ items: SessionSearchResultItem[]; hasMore: boolean }>>',
|
||||
description: 'Search the Host\'s visible message-content index. Results stay request-local; the list snapshot remains the metadata authority.',
|
||||
parameters: [{"name":"query","description":"non-blank literal phrase."},{"name":"signal","description":"cancellation for a superseded search."}],
|
||||
parameters: [{ name: 'query', description: 'non-blank literal phrase.' }, { name: 'signal', description: 'cancellation for a superseded search.' }],
|
||||
returns: 'bounded results, or a business/transport error.',
|
||||
},
|
||||
{
|
||||
signature: 'fork(opts: { sessionId: SessionId; atSeq?: number; increaseTitle?: boolean }): Promise<SessionId>',
|
||||
description: 'Fork a session from a completed-turn prefix of the source; on resolution the child is in the list store and `open()` can target it.',
|
||||
parameters: [{"name":"opts","description":"source session id, the optional event seq anchoring the cut (the boundary is the first turn/end at or after it; an in-log anchor in an open turn is unavailable rather than clipped backward), and whether to increment an inherited durable title before resolving."}],
|
||||
parameters: [{ name: 'opts', description: 'source session id, the optional event seq anchoring the cut (the boundary is the first turn/end at or after it; an in-log anchor in an open turn is unavailable rather than clipped backward), and whether to increment an inherited durable title before resolving.' }],
|
||||
returns: 'the child session id.',
|
||||
throws: ["when the fork fails, or when a requested child-title rename fails after creation."],
|
||||
throws: ['when the fork fails, or when a requested child-title rename fails after creation.'],
|
||||
},
|
||||
{
|
||||
signature: 'scope(id: SessionId): AgentContext | undefined',
|
||||
description: 'Resolve an Agent-scoped context view (use-and-discard).',
|
||||
parameters: [{"name":"id","description":"session id."}],
|
||||
parameters: [{ name: 'id', description: 'session id.' }],
|
||||
returns: 'scoped ctx, or undefined for a session neither listed nor already scoped.',
|
||||
},
|
||||
{
|
||||
signature: 'binding(id: SessionId): SessionBinding | undefined',
|
||||
description: 'Resolve the stable session binding (scope-addressed assembly feed).',
|
||||
parameters: [{"name":"id","description":"session id."}],
|
||||
parameters: [{ name: 'id', description: 'session id.' }],
|
||||
returns: 'binding, or undefined for a session neither listed nor already scoped.',
|
||||
},
|
||||
],
|
||||
@@ -222,9 +222,9 @@ export const SERVICE_API: readonly ServiceApiEntry[] = [
|
||||
{
|
||||
signature: 'inject(key: keyof SlotMap & string, callback: () => SlotInjectionEffect): () => void',
|
||||
description: 'Install an effect for each declaration lifetime of a slot. The callback runs synchronously when the declaration already exists; otherwise it runs inside the declaring `register()` call after the declaration is committed. Collapse disposes the effect and a later declaration runs it again. Callback effects are synchronous disposers; iterable effects install transactionally and dispose in reverse order. The controller belongs to the caller\'s fiber, so plugin unload cancels a pending wait and removes any active contribution.',
|
||||
parameters: [{"name":"key","description":"declared SlotMap key to depend on."},{"name":"callback","description":"creates one disposer or an iterable of disposers."}],
|
||||
parameters: [{ name: 'key', description: 'declared SlotMap key to depend on.' }, { name: 'callback', description: 'creates one disposer or an iterable of disposers.' }],
|
||||
returns: 'idempotent disposer for the wait and active effect.',
|
||||
throws: ["callback setup failures synchronously when the slot is already declared."],
|
||||
throws: ['callback setup failures synchronously when the slot is already declared.'],
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -242,18 +242,18 @@ export const SERVICE_API: readonly ServiceApiEntry[] = [
|
||||
{
|
||||
signature: 'setTheme(id: string): void',
|
||||
description: 'Switch the theme preference — the only user preference write entry. Built-in preferences are written through the settings scope and every accepted value emits `theme/change`.',
|
||||
parameters: [{"name":"id","description":"a registered theme id or `system`; unknown ids throw."}],
|
||||
parameters: [{ name: 'id', description: 'a registered theme id or `system`; unknown ids throw.' }],
|
||||
},
|
||||
{
|
||||
signature: 'register(definition: ThemeDefinition): () => void',
|
||||
description: 'Register a theme. Duplicate id throws (single occupant per id; the built-in pair counts; `system` is a preference, not a registrable id).',
|
||||
parameters: [{"name":"definition","description":"theme id, colorScheme, and alias-token overrides."}],
|
||||
parameters: [{ name: 'definition', description: 'theme id, colorScheme, and alias-token overrides.' }],
|
||||
returns: 'disposer. Disposing the theme backing the active preference resets the preference to the default so the UI never keeps tokens of an unregistered theme.',
|
||||
},
|
||||
{
|
||||
signature: 'overrideTokens(source: string, tokens: ThemeTokenOverrides): () => void',
|
||||
description: 'Stack a token override layer on top of the active theme — the token-level analogue of slot shading: the base theme stays untouched, layers compose in seq order with later layers winning per-token, and removing a layer restores whatever it covered. Calling again with the same source replaces that source\'s whole layer and restacks it on top (effect re-registration semantics). Emits `theme/change` with the recomposed snapshot.',
|
||||
parameters: [{"name":"source","description":"layer identity; one layer per source (dynamic packages pass their package id — the façade pins it, so it also names the layer's origin for inspection)."},{"name":"tokens","description":"token-name → `{ light, dark }` value pairs. Validated at runtime (model-authored callers reach this boundary with untyped JS); a bare string value throws a teaching error."}],
|
||||
parameters: [{ name: 'source', description: 'layer identity; one layer per source (dynamic packages pass their package id — the façade pins it, so it also names the layer\'s origin for inspection).' }, { name: 'tokens', description: 'token-name → `{ light, dark }` value pairs. Validated at runtime (model-authored callers reach this boundary with untyped JS); a bare string value throws a teaching error.' }],
|
||||
returns: 'disposer removing exactly the layer this call created; a no-op once the source has re-overridden (the newer layer is not torn down).',
|
||||
},
|
||||
],
|
||||
@@ -303,18 +303,18 @@ export const SERVICE_API: readonly ServiceApiEntry[] = [
|
||||
{
|
||||
signature: 'connectWorkspace(workspaceId: WorkspaceId): Promise<SessionId>',
|
||||
description: 'Connect a Workspace to its reusable or freshly created blank session.',
|
||||
parameters: [{"name":"workspaceId","description":"target workspace."}],
|
||||
parameters: [{ name: 'workspaceId', description: 'target workspace.' }],
|
||||
returns: 'the connected session id.',
|
||||
},
|
||||
{
|
||||
signature: 'startSession(workspaceId?: WorkspaceId): void',
|
||||
description: 'The New Session flow: connect the target (or recent) Workspace and open the resulting session; failures surface on the session list state.',
|
||||
parameters: [{"name":"workspaceId","description":"explicit target; omitted uses the recency projection."}],
|
||||
description: 'The New Session flow: connect the explicit, current-Session, or recent Workspace and open the resulting session; failures surface on the session list state.',
|
||||
parameters: [{ name: 'workspaceId', description: 'explicit target; omitted inherits the current Session\'s Workspace before falling back to the recency projection.' }],
|
||||
},
|
||||
{
|
||||
signature: 'create(input: { path: string }): Promise<WorkspaceView>',
|
||||
description: 'Register an existing path as a Workspace.',
|
||||
parameters: [{"name":"input","description":"the Host create payload."}],
|
||||
parameters: [{ name: 'input', description: 'the Host create payload.' }],
|
||||
returns: 'the created or idempotently resolved Workspace.',
|
||||
},
|
||||
{
|
||||
@@ -326,41 +326,41 @@ export const SERVICE_API: readonly ServiceApiEntry[] = [
|
||||
{
|
||||
signature: 'listDirectory(path?: string, signal?: AbortSignal): Promise<DirectoryListing>',
|
||||
description: 'List one directory level through the Host\'s `browse` capability.',
|
||||
parameters: [{"name":"path","description":"absolute directory to list; absent lists the Host home directory."},{"name":"signal","description":"aborts the wire request (and the Host's scan) when the caller supersedes it."}],
|
||||
parameters: [{ name: 'path', description: 'absolute directory to list; absent lists the Host home directory.' }, { name: 'signal', description: 'aborts the wire request (and the Host\'s scan) when the caller supersedes it.' }],
|
||||
returns: 'the level\'s listing with breadcrumb ancestry.',
|
||||
},
|
||||
{
|
||||
signature: 'createDirectory(path: string, name: string): Promise<string>',
|
||||
description: 'Create one child directory through the Host\'s `browse` capability.',
|
||||
parameters: [{"name":"path","description":"absolute existing parent directory."},{"name":"name","description":"single non-blank path segment."}],
|
||||
parameters: [{ name: 'path', description: 'absolute existing parent directory.' }, { name: 'name', description: 'single non-blank path segment.' }],
|
||||
returns: 'the created directory\'s absolute path.',
|
||||
},
|
||||
{
|
||||
signature: 'openPath(path: string): Promise<void>',
|
||||
description: 'Open a filesystem path with the Host operating system\'s default application.',
|
||||
parameters: [{"name":"path","description":"absolute or host-resolvable path."}],
|
||||
parameters: [{ name: 'path', description: 'absolute or host-resolvable path.' }],
|
||||
},
|
||||
{
|
||||
signature: 'rename(workspaceId: WorkspaceId, title: string): Promise<WorkspaceView>',
|
||||
description: 'Rename a Workspace.',
|
||||
parameters: [{"name":"workspaceId","description":"target workspace."},{"name":"title","description":"the new display title."}],
|
||||
parameters: [{ name: 'workspaceId', description: 'target workspace.' }, { name: 'title', description: 'the new display title.' }],
|
||||
returns: 'the updated Workspace view.',
|
||||
},
|
||||
{
|
||||
signature: 'delete(workspaceId: WorkspaceId): Promise<void>',
|
||||
description: 'Delete a Workspace (its sessions fall back to the unaccounted group).',
|
||||
parameters: [{"name":"workspaceId","description":"target workspace."}],
|
||||
parameters: [{ name: 'workspaceId', description: 'target workspace.' }],
|
||||
},
|
||||
{
|
||||
signature: 'insertSessionBefore(workspaceId: WorkspaceId, sessionId: SessionId, beforeSessionId?: SessionId): Promise<WorkspaceView>',
|
||||
description: 'Move an accounted session within/into a Workspace\'s ordered list.',
|
||||
parameters: [{"name":"workspaceId","description":"target workspace."},{"name":"sessionId","description":"accounted session to move."},{"name":"beforeSessionId","description":"accounted anchor to insert before; omitted appends."}],
|
||||
parameters: [{ name: 'workspaceId', description: 'target workspace.' }, { name: 'sessionId', description: 'accounted session to move.' }, { name: 'beforeSessionId', description: 'accounted anchor to insert before; omitted appends.' }],
|
||||
returns: 'the updated Workspace view.',
|
||||
},
|
||||
{
|
||||
signature: 'archiveSession(sessionId: SessionId): Promise<void>',
|
||||
description: 'Archive a session into the registry-global set (hidden from grouping surfaces; session log and accounting slot remain). Archiving the current session clears the selection into the New Session view state.',
|
||||
parameters: [{"name":"sessionId","description":"session to archive."}],
|
||||
parameters: [{ name: 'sessionId', description: 'session to archive.' }],
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -382,7 +382,7 @@ export const EVENT_API: readonly EventApiEntry[] = [
|
||||
signature: '\'locale/change\'(snapshot: LocaleSnapshot): void',
|
||||
summary: 'The active locale switched.',
|
||||
description: 'The active locale switched. Dictionary registrations do NOT emit this event (listeners may re-register slots in response, and boot registers one namespace per package); continuous render refresh rides the LocaleFace revision instead.',
|
||||
parameters: [{"name":"snapshot","description":"Current immutable locale snapshot."}],
|
||||
parameters: [{ name: 'snapshot', description: 'Current immutable locale snapshot.' }],
|
||||
},
|
||||
{
|
||||
name: 'slots/changed',
|
||||
@@ -390,7 +390,7 @@ export const EVENT_API: readonly EventApiEntry[] = [
|
||||
signature: '\'slots/changed\'(key: string): void',
|
||||
summary: 'A slot\'s definition or registration set changed.',
|
||||
description: 'A slot\'s definition or registration set changed.',
|
||||
parameters: [{"name":"key","description":"the mutated SlotMap key."}],
|
||||
parameters: [{ name: 'key', description: 'the mutated SlotMap key.' }],
|
||||
},
|
||||
{
|
||||
name: 'theme/change',
|
||||
@@ -398,7 +398,7 @@ export const EVENT_API: readonly EventApiEntry[] = [
|
||||
signature: '\'theme/change\'(snapshot: ThemeSnapshot): void',
|
||||
summary: 'Theme state changed (preference switched, registry updated, or the OS color scheme changed while the preference is `system`).',
|
||||
description: 'Theme state changed (preference switched, registry updated, or the OS color scheme changed while the preference is `system`).',
|
||||
parameters: [{"name":"snapshot","description":"Current immutable theme snapshot."}],
|
||||
parameters: [{ name: 'snapshot', description: 'Current immutable theme snapshot.' }],
|
||||
},
|
||||
]
|
||||
|
||||
@@ -418,7 +418,7 @@ export const TYPE_API: readonly TypeApiEntry[] = [
|
||||
},
|
||||
{
|
||||
name: 'AssistantMessageNode',
|
||||
declaration: 'export interface AssistantMessageNode {\n kind: \'assistant\';\n seq: number;\n time: number;\n turn: number;\n step: number;\n blocks: readonly AssistantBlock[];\n usage?: unknown;\n provenance?: AssistantProvenanceView;\n requestConfig?: AssistantRequestConfig;\n timing?: AssistantTiming;\n interrupted?: true;\n}',
|
||||
declaration: 'export interface AssistantMessageNode {\n kind: \'assistant\';\n seq: number;\n messageId?: MessageId;\n time: number;\n turn: number;\n step: number;\n blocks: readonly AssistantBlock[];\n usage?: unknown;\n provenance?: AssistantProvenanceView;\n requestConfig?: AssistantRequestConfig;\n timing?: AssistantTiming;\n interrupted?: true;\n}',
|
||||
},
|
||||
{
|
||||
name: 'AssistantProvenanceView',
|
||||
@@ -510,7 +510,7 @@ export const TYPE_API: readonly TypeApiEntry[] = [
|
||||
},
|
||||
{
|
||||
name: 'ConversationNode',
|
||||
declaration: 'export type ConversationNode = UserMessageNode | AssistantMessageNode | SteeringMessageNode | ContextMessageNode | ModelRetryNode | TurnErrorNode | ToolResultNode | CommandNode | CompactionSummaryNode | UnknownSurfaceNode;',
|
||||
declaration: 'export type ConversationNode = UserMessageNode | AssistantMessageNode | SteeringMessageNode | ContextMessageNode | ModelRetryNode | TurnErrorNode | TurnMaxTokensNode | ToolResultNode | CommandNode | CompactionSummaryNode | UnknownSurfaceNode;',
|
||||
},
|
||||
{
|
||||
name: 'ConversationSnapshot',
|
||||
@@ -852,6 +852,10 @@ export const TYPE_API: readonly TypeApiEntry[] = [
|
||||
name: 'TurnLocation',
|
||||
declaration: 'export interface TurnLocation {\n readonly turn: number;\n readonly start: SessionEvent<\'turn/start\'> | undefined;\n readonly end: SessionEvent<\'turn/end\'> | undefined;\n readonly status: \'open\' | \'closed\' | \'unknown\';\n readonly steps: readonly StepLocation[];\n readonly data: ConversationLocationDataStore<ConversationTurnDataMap>;\n}',
|
||||
},
|
||||
{
|
||||
name: 'TurnMaxTokensNode',
|
||||
declaration: 'export interface TurnMaxTokensNode {\n kind: \'turn-max-tokens\';\n seq: number;\n time: number;\n turn: number;\n step: number;\n}',
|
||||
},
|
||||
{
|
||||
name: 'UnknownSurfaceNode',
|
||||
declaration: 'export interface UnknownSurfaceNode {\n kind: \'unknown\';\n seq: number;\n time: number;\n type: string;\n data: unknown;\n}',
|
||||
|
||||
@@ -140,7 +140,11 @@ declare module '@deepseek-ai/cordis' {
|
||||
}
|
||||
}
|
||||
|
||||
/** Provide the registry as a normal Client service. */
|
||||
/**
|
||||
* Provide the registry as a normal Client service.
|
||||
* @param ctx - Client Cordis context receiving the service.
|
||||
* @param registry - page-local inspect registry to publish.
|
||||
*/
|
||||
export function provideClientCordisInspect(ctx: Context, registry: ClientCordisInspectRegistry): void {
|
||||
ctx.provide('cordisInspect', registry)
|
||||
}
|
||||
|
||||
@@ -142,7 +142,10 @@ export class CordisRunOrchestrator {
|
||||
subscribe: fn => this.observe(fn),
|
||||
}
|
||||
|
||||
/** Register a Client activation request, starting it immediately when the Plugin is already authorized. */
|
||||
/**
|
||||
* Register a Client activation request, starting it immediately when the Plugin is already authorized.
|
||||
* @param request - forwarded approval and activation metadata.
|
||||
*/
|
||||
open(request: CordisRunRequest): void {
|
||||
this.requests.set(request.requestId, request)
|
||||
if (!request.requiresApproval) {
|
||||
@@ -238,7 +241,10 @@ export class CordisRunOrchestrator {
|
||||
if (changed) this.commit()
|
||||
}
|
||||
|
||||
/** Close an approval settled by another page or by cancellation. */
|
||||
/**
|
||||
* Close an approval settled by another page or by cancellation.
|
||||
* @param requestId - approval request that can no longer be answered here.
|
||||
*/
|
||||
close(requestId: ApprovalRequestId): void {
|
||||
const request = this.requests.get(requestId)
|
||||
if (request === undefined) return
|
||||
@@ -250,7 +256,11 @@ export class CordisRunOrchestrator {
|
||||
this.commit()
|
||||
}
|
||||
|
||||
/** Approve and execute one still-open model request. */
|
||||
/**
|
||||
* Approve and execute one still-open model request.
|
||||
* @param requestId - approval request to execute.
|
||||
* @param approveFutureVersions - whether this approval covers later Packages for the same Plugin.
|
||||
*/
|
||||
approve(requestId: ApprovalRequestId, approveFutureVersions: boolean): Promise<void> {
|
||||
const request = this.requests.get(requestId)
|
||||
if (request === undefined || !request.requiresApproval) return Promise.resolve()
|
||||
@@ -265,7 +275,10 @@ export class CordisRunOrchestrator {
|
||||
})
|
||||
}
|
||||
|
||||
/** Reject one still-open model request without executing either half. */
|
||||
/**
|
||||
* Reject one still-open model request without executing either half.
|
||||
* @param requestId - approval request to reject.
|
||||
*/
|
||||
async decline(requestId: ApprovalRequestId): Promise<void> {
|
||||
const request = this.requests.get(requestId)
|
||||
if (request === undefined || !request.requiresApproval) return
|
||||
@@ -277,7 +290,10 @@ export class CordisRunOrchestrator {
|
||||
await this.answer(requestId, { ok: false, reason: 'rejected' })
|
||||
}
|
||||
|
||||
/** Execute a direct panel run; the user gesture itself authorizes it. */
|
||||
/**
|
||||
* Execute a direct panel run; the user gesture itself authorizes it.
|
||||
* @param request - exact Package activation selected by the user.
|
||||
*/
|
||||
startUserRun(request: CordisUserRunRequest): Promise<void> {
|
||||
return this.orchestrate(request)
|
||||
}
|
||||
|
||||
@@ -67,7 +67,11 @@ export const CLIENT_BUILTIN_INSPECTION: readonly JsonValue[] = [
|
||||
},
|
||||
]
|
||||
|
||||
/** Construct the first-party Client provider registrations. */
|
||||
/**
|
||||
* Construct the first-party Client provider registrations.
|
||||
* @param ctx - Client context used for live Service-backed queries.
|
||||
* @returns registrations for static catalogs and live Client capabilities.
|
||||
*/
|
||||
export function clientInspectProviders(ctx: Context): ClientCordisInspectProviderRegistration[] {
|
||||
return [
|
||||
registration(
|
||||
|
||||
@@ -110,6 +110,58 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
example: 'return {\n inject: [\'slots\'],\n apply(ctx) {\n ctx.slots.inject(\'conversation\', () => ctx.slots.register(\n { name: \'conversation\' },\n () => React.createElement(\'div\', null, \'hello\'),\n ))\n },\n}',
|
||||
source: 'packages/client/ui-layout/src/client/index.ts:62',
|
||||
},
|
||||
{
|
||||
key: 'conversation.chat.assistant-actions',
|
||||
kind: 'list',
|
||||
scope: 'session',
|
||||
summary: 'Action strip attached to one finalized assistant message, rendered inside that message\'s IconActions row.',
|
||||
doc: 'Action strip attached to one finalized assistant message, rendered\ninside that message\'s IconActions row. The chat entry owns the render\nsite and passes the addressed message identity; contributors add\nper-message actions without importing the conversation implementation.\nEntries render by ascending `order`.',
|
||||
registerOptions: [
|
||||
{
|
||||
name: 'id',
|
||||
requirement: 'required',
|
||||
type: 'string',
|
||||
doc: 'Your cell key. Use an id of your own: a fresh id is added beside the shipped entries, while reusing a shipped id puts you in THAT cell and replaces it. Owners that filter by id address you by it.',
|
||||
},
|
||||
{
|
||||
name: 'order',
|
||||
requirement: 'optional',
|
||||
type: 'number',
|
||||
doc: 'Position among the entries, ascending (default 0).',
|
||||
},
|
||||
{
|
||||
name: 'label',
|
||||
requirement: 'optional',
|
||||
type: 'string | (() => string)',
|
||||
doc: 'Display text where the owner projects one (nav rows, tabs). A thunk is re-read on every projection, so localized text follows the active locale without re-registering.',
|
||||
},
|
||||
],
|
||||
ownerProps: [
|
||||
'/**\n * Owner currency of the assistant-message action strip: the durable identity\n * of the one finalized message the contributed actions address. Only finalized\n * messages reach this slot, so the id is always present.\n */\nexport interface AssistantActionOwnerProps {\n /** Stable identity carried from the `assistant/message` event. */\n messageId: MessageId\n}',
|
||||
],
|
||||
ownerPropsReferences: [
|
||||
'MessageId',
|
||||
],
|
||||
standardProps: [
|
||||
'useSessions: SnapshotSelectorHook<SessionListState>',
|
||||
'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
|
||||
'useSession: SnapshotSelectorHook<ConversationSnapshot>',
|
||||
'sessionId: SessionId',
|
||||
'useProjection: UseProjection',
|
||||
'useInput: SnapshotSelectorHook<InputState>',
|
||||
'inputActions: InputActions',
|
||||
],
|
||||
keyDomain: '',
|
||||
hookContext: '',
|
||||
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\'',
|
||||
],
|
||||
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}',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:109',
|
||||
},
|
||||
{
|
||||
key: 'conversation.chat.commandview',
|
||||
kind: 'keyed',
|
||||
@@ -147,7 +199,7 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
occupants: [],
|
||||
replaceRisk: 'none',
|
||||
example: 'return {\n inject: [\'slots\'],\n apply(ctx) {\n ctx.slots.inject(\'conversation.chat.commandview\', () => ctx.slots.register(\n { name: \'conversation.chat.commandview\', key: \'<one key the owner dispatches>\' },\n () => React.createElement(\'div\', null, \'hello\'),\n ))\n },\n}',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:88',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:94',
|
||||
},
|
||||
{
|
||||
key: 'conversation.chat.node',
|
||||
@@ -180,7 +232,7 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
'useInput: SnapshotSelectorHook<InputState>',
|
||||
'inputActions: InputActions',
|
||||
],
|
||||
keyDomain: 'fixed by the owner\'s key table { [Kind in ChatNodeKind]: { node: ChatNode<Kind> } }, already taken: assistant-step, command, command-input, compaction, context, manual-compaction, model-retry, steering, tool-call, turn-error, turn-tail, unknown, user, workflow-run',
|
||||
keyDomain: 'fixed by the owner\'s key table { [Kind in ChatNodeKind]: { node: ChatNode<Kind> } }, already taken: assistant-step, command, command-input, compaction, context, manual-compaction, model-retry, steering, tool-call, turn-error, turn-max-tokens, turn-tail, unknown, user, workflow-run',
|
||||
hookContext: 'string',
|
||||
slotInject: 'ChatNodeTurnDataInjected',
|
||||
declaredBy: 'an entry in \'conversation.view\' (client-ui-conversation), so it exists while that entry is mounted',
|
||||
@@ -194,6 +246,7 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
'client-ui-conversation CompactionNodeView key \'compaction\'',
|
||||
'client-ui-conversation RetryNodeView key \'model-retry\'',
|
||||
'client-ui-conversation TurnErrorNodeView key \'turn-error\'',
|
||||
'client-ui-conversation TurnMaxTokensNodeView key \'turn-max-tokens\'',
|
||||
'client-ui-conversation TurnTailNodeView key \'turn-tail\'',
|
||||
'client-ui-conversation UnknownNodeView key \'unknown\'',
|
||||
'client-ui-goal GoalCommandInputView key \'command-input\'',
|
||||
@@ -202,7 +255,7 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
],
|
||||
replaceRisk: 'shadows-shipped-ui',
|
||||
example: 'return {\n inject: [\'slots\'],\n apply(ctx) {\n ctx.slots.inject(\'conversation.chat.node\', () => ctx.slots.register(\n { name: \'conversation.chat.node\', key: \'<one key the owner dispatches>\' },\n () => React.createElement(\'div\', null, \'hello\'),\n ))\n },\n}',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:72',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:78',
|
||||
},
|
||||
{
|
||||
key: 'conversation.chat.turnTail',
|
||||
@@ -242,7 +295,7 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
],
|
||||
replaceRisk: 'none',
|
||||
example: 'return {\n inject: [\'slots\'],\n apply(ctx) {\n ctx.slots.inject(\'conversation.chat.turnTail\', () => ctx.slots.register(\n { name: \'conversation.chat.turnTail\', select: owner => null },\n () => React.createElement(\'div\', null, \'hello\'),\n ))\n },\n}',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:95',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:101',
|
||||
},
|
||||
{
|
||||
key: 'conversation.composer',
|
||||
@@ -285,7 +338,7 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
],
|
||||
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}',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:114',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:132',
|
||||
},
|
||||
{
|
||||
key: 'conversation.composer.bar',
|
||||
@@ -318,7 +371,7 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
],
|
||||
replaceRisk: 'shadows-shipped-ui',
|
||||
example: 'return {\n inject: [\'slots\'],\n apply(ctx) {\n ctx.slots.inject(\'conversation.composer.bar\', () => ctx.slots.register(\n { name: \'conversation.composer.bar\' },\n () => React.createElement(\'div\', null, \'hello\'),\n ))\n },\n}',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:183',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:201',
|
||||
},
|
||||
{
|
||||
key: 'conversation.composer.dock',
|
||||
@@ -371,7 +424,7 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
],
|
||||
replaceRisk: 'none',
|
||||
example: 'return {\n inject: [\'slots\'],\n apply(ctx) {\n ctx.slots.inject(\'conversation.composer.dock\', () => ctx.slots.register(\n { name: \'conversation.composer.dock\', id: \'my-entry\', order: 100, label: \'My entry\' },\n () => React.createElement(\'div\', null, \'hello\'),\n ))\n },\n}',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:152',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:170',
|
||||
},
|
||||
{
|
||||
key: 'conversation.details.tool',
|
||||
@@ -402,7 +455,7 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
],
|
||||
replaceRisk: 'shadows-shipped-ui',
|
||||
example: 'return {\n inject: [\'slots\'],\n apply(ctx) {\n ctx.slots.inject(\'conversation.details.tool\', () => ctx.slots.register(\n { name: \'conversation.details.tool\' },\n () => React.createElement(\'div\', null, \'hello\'),\n ))\n },\n}',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:106',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:124',
|
||||
},
|
||||
{
|
||||
key: 'conversation.hero.agentPreset',
|
||||
@@ -428,7 +481,7 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
],
|
||||
replaceRisk: 'shadows-shipped-ui',
|
||||
example: 'return {\n inject: [\'slots\'],\n apply(ctx) {\n ctx.slots.inject(\'conversation.hero.agentPreset\', () => ctx.slots.register(\n { name: \'conversation.hero.agentPreset\' },\n () => React.createElement(\'div\', null, \'hello\'),\n ))\n },\n}',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:127',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:145',
|
||||
},
|
||||
{
|
||||
key: 'conversation.hero.workspace',
|
||||
@@ -456,7 +509,7 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
],
|
||||
replaceRisk: 'shadows-shipped-ui',
|
||||
example: 'return {\n inject: [\'slots\'],\n apply(ctx) {\n ctx.slots.inject(\'conversation.hero.workspace\', () => ctx.slots.register(\n { name: \'conversation.hero.workspace\' },\n () => React.createElement(\'div\', null, \'hello\'),\n ))\n },\n}',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:121',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:139',
|
||||
},
|
||||
{
|
||||
key: 'conversation.hero.workspace.directoryFlow',
|
||||
@@ -538,7 +591,7 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
],
|
||||
replaceRisk: 'none',
|
||||
example: 'return {\n inject: [\'slots\'],\n apply(ctx) {\n ctx.slots.inject(\'conversation.input.dock\', () => ctx.slots.register(\n { name: \'conversation.input.dock\', id: \'my-entry\', order: 100, label: \'My entry\' },\n () => React.createElement(\'div\', null, \'hello\'),\n ))\n },\n}',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:143',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:161',
|
||||
},
|
||||
{
|
||||
key: 'conversation.input.left',
|
||||
@@ -589,7 +642,7 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
occupants: [],
|
||||
replaceRisk: 'none',
|
||||
example: 'return {\n inject: [\'slots\'],\n apply(ctx) {\n ctx.slots.inject(\'conversation.input.left\', () => ctx.slots.register(\n { name: \'conversation.input.left\', id: \'my-entry\', order: 100, label: \'My entry\' },\n () => React.createElement(\'div\', null, \'hello\'),\n ))\n },\n}',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:161',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:179',
|
||||
},
|
||||
{
|
||||
key: 'conversation.input.model',
|
||||
@@ -620,7 +673,7 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
],
|
||||
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}',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:203',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:221',
|
||||
},
|
||||
{
|
||||
key: 'conversation.input.overlay',
|
||||
@@ -700,7 +753,7 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
],
|
||||
replaceRisk: 'shadows-shipped-ui',
|
||||
example: 'return {\n inject: [\'slots\'],\n apply(ctx) {\n ctx.slots.inject(\'conversation.input.plan\', () => ctx.slots.register(\n { name: \'conversation.input.plan\' },\n () => React.createElement(\'div\', null, \'hello\'),\n ))\n },\n}',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:193',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:211',
|
||||
},
|
||||
{
|
||||
key: 'conversation.input.right',
|
||||
@@ -751,7 +804,7 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
occupants: [],
|
||||
replaceRisk: 'none',
|
||||
example: 'return {\n inject: [\'slots\'],\n apply(ctx) {\n ctx.slots.inject(\'conversation.input.right\', () => ctx.slots.register(\n { name: \'conversation.input.right\', id: \'my-entry\', order: 100, label: \'My entry\' },\n () => React.createElement(\'div\', null, \'hello\'),\n ))\n },\n}',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:169',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:187',
|
||||
},
|
||||
{
|
||||
key: 'conversation.session',
|
||||
@@ -780,7 +833,7 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
],
|
||||
replaceRisk: 'shadows-shipped-ui',
|
||||
example: 'return {\n inject: [\'slots\'],\n apply(ctx) {\n ctx.slots.inject(\'conversation.session\', () => ctx.slots.register(\n { name: \'conversation.session\' },\n () => React.createElement(\'div\', null, \'hello\'),\n ))\n },\n}',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:43',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:44',
|
||||
},
|
||||
{
|
||||
key: 'conversation.session.header',
|
||||
@@ -809,7 +862,7 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
],
|
||||
replaceRisk: 'shadows-shipped-ui',
|
||||
example: 'return {\n inject: [\'slots\'],\n apply(ctx) {\n ctx.slots.inject(\'conversation.session.header\', () => ctx.slots.register(\n { name: \'conversation.session.header\' },\n () => React.createElement(\'div\', null, \'hello\'),\n ))\n },\n}',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:51',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:52',
|
||||
},
|
||||
{
|
||||
key: 'conversation.session.header.actions',
|
||||
@@ -861,7 +914,57 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
],
|
||||
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}',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:62',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:63',
|
||||
},
|
||||
{
|
||||
key: 'conversation.session.header.utilities',
|
||||
kind: 'list',
|
||||
scope: 'session',
|
||||
summary: 'Right-aligned Session utilities kept outside the title-adjacent action group, so an optional utility cannot reorder session context or lineage.',
|
||||
doc: 'Right-aligned Session utilities kept outside the title-adjacent action\ngroup, so an optional utility cannot reorder session context or lineage.',
|
||||
registerOptions: [
|
||||
{
|
||||
name: 'id',
|
||||
requirement: 'required',
|
||||
type: 'string',
|
||||
doc: 'Your cell key. Use an id of your own: a fresh id is added beside the shipped entries, while reusing a shipped id puts you in THAT cell and replaces it. Owners that filter by id address you by it.',
|
||||
},
|
||||
{
|
||||
name: 'order',
|
||||
requirement: 'optional',
|
||||
type: 'number',
|
||||
doc: 'Position among the entries, ascending (default 0).',
|
||||
},
|
||||
{
|
||||
name: 'label',
|
||||
requirement: 'optional',
|
||||
type: 'string | (() => string)',
|
||||
doc: 'Display text where the owner projects one (nav rows, tabs). A thunk is re-read on every projection, so localized text follows the active locale without re-registering.',
|
||||
},
|
||||
],
|
||||
ownerProps: [
|
||||
'/** Header actions derive their state from the standard session/global kit. */\nexport interface ConversationHeaderActionOwnerProps {}',
|
||||
],
|
||||
ownerPropsReferences: [],
|
||||
standardProps: [
|
||||
'useSessions: SnapshotSelectorHook<SessionListState>',
|
||||
'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
|
||||
'useSession: SnapshotSelectorHook<ConversationSnapshot>',
|
||||
'sessionId: SessionId',
|
||||
'useProjection: UseProjection',
|
||||
'useInput: SnapshotSelectorHook<InputState>',
|
||||
'inputActions: InputActions',
|
||||
],
|
||||
keyDomain: '',
|
||||
hookContext: '',
|
||||
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\'',
|
||||
],
|
||||
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}',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:68',
|
||||
},
|
||||
{
|
||||
key: 'conversation.view',
|
||||
@@ -912,7 +1015,7 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
],
|
||||
replaceRisk: 'none',
|
||||
example: 'return {\n inject: [\'slots\'],\n apply(ctx) {\n ctx.slots.inject(\'conversation.view\', () => ctx.slots.register(\n { name: \'conversation.view\', id: \'my-entry\', order: 100, label: \'My entry\' },\n () => React.createElement(\'div\', null, \'hello\'),\n ))\n },\n}',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:70',
|
||||
source: 'packages/client/ui-conversation/src/client/contract/slots.ts:76',
|
||||
},
|
||||
{
|
||||
key: 'details',
|
||||
@@ -1089,7 +1192,7 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
],
|
||||
replaceRisk: 'none',
|
||||
example: 'return {\n inject: [\'slots\'],\n apply(ctx) {\n ctx.slots.inject(\'settings.general.item\', () => ctx.slots.register(\n { name: \'settings.general.item\', id: \'my-entry\', order: 100, label: \'My entry\' },\n () => React.createElement(\'div\', null, \'hello\'),\n ))\n },\n}',
|
||||
source: 'packages/client/ui-settings/src/client/contract/slots.ts:81',
|
||||
source: 'packages/client/ui-settings/src/client/contract/slots.ts:90',
|
||||
},
|
||||
{
|
||||
key: 'settings.header',
|
||||
@@ -1161,7 +1264,7 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
],
|
||||
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}',
|
||||
source: 'packages/client/ui-settings/src/client/contract/slots.ts:66',
|
||||
source: 'packages/client/ui-settings/src/client/contract/slots.ts:75',
|
||||
},
|
||||
{
|
||||
key: 'settings.plugin.item',
|
||||
@@ -1200,7 +1303,7 @@ 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.plugins.tab\' (client-ui-plugin-config), so it exists while that entry is mounted',
|
||||
occupants: [
|
||||
'client-ui-plugin-config BashCard id \'bash\'',
|
||||
'client-ui-plugin-config AgentLoopCard id \'agent-loop\'',
|
||||
@@ -1210,6 +1313,52 @@ export const CLIENT_SLOT_API: readonly ClientSlotEntry[] = [
|
||||
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',
|
||||
},
|
||||
{
|
||||
key: 'settings.plugins.tab',
|
||||
kind: 'list',
|
||||
scope: 'root',
|
||||
summary: 'One page inside the Plugins settings section.',
|
||||
doc: 'One page inside the Plugins settings section. The section owner renders\nlocalized entry labels as tabs and mounts each contribution inside its\ncorresponding tab panel. Options: `id` (tab key), `order` (tab order),\nand `label` (registrant-localized tab text). Declared at runtime by the\nfeature that owns the Plugins section; the type lives here so inventory\nand configuration plugins collaborate without depending on one another.',
|
||||
registerOptions: [
|
||||
{
|
||||
name: 'id',
|
||||
requirement: 'required',
|
||||
type: 'string',
|
||||
doc: 'Your cell key. Use an id of your own: a fresh id is added beside the shipped entries, while reusing a shipped id puts you in THAT cell and replaces it. Owners that filter by id address you by it.',
|
||||
},
|
||||
{
|
||||
name: 'order',
|
||||
requirement: 'optional',
|
||||
type: 'number',
|
||||
doc: 'Position among the entries, ascending (default 0).',
|
||||
},
|
||||
{
|
||||
name: 'label',
|
||||
requirement: 'optional',
|
||||
type: 'string | (() => string)',
|
||||
doc: 'Display text where the owner projects one (nav rows, tabs). A thunk is re-read on every projection, so localized text follows the active locale without re-registering.',
|
||||
},
|
||||
],
|
||||
ownerProps: [
|
||||
'/** Owner share of a Plugins tab (the section supplies nothing). */\nexport interface SettingsPluginsTabOwnerProps {\n /** Marker field: tab owner props are intentionally empty. */\n children?: never\n}',
|
||||
],
|
||||
ownerPropsReferences: [],
|
||||
standardProps: [
|
||||
'useSessions: SnapshotSelectorHook<SessionListState>',
|
||||
'useWorkspaces: SnapshotSelectorHook<import(\'./workspaces/service.ts\').WorkspaceListState>',
|
||||
],
|
||||
keyDomain: '',
|
||||
hookContext: '',
|
||||
slotInject: '',
|
||||
declaredBy: 'an entry in \'settings.section\' (client-ui-plugin-config), so it exists while that entry is mounted',
|
||||
occupants: [
|
||||
'client-ui-plugin-config ConfigurablePluginsTab id \'configurable\'',
|
||||
'client-ui-plugins PluginSettingsSection id \'all\'',
|
||||
],
|
||||
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}',
|
||||
source: 'packages/client/ui-settings/src/client/contract/slots.ts:62',
|
||||
},
|
||||
{
|
||||
key: 'settings.section',
|
||||
kind: 'list',
|
||||
|
||||
Reference in New Issue
Block a user