@khorsheed/dsh-local-agent-claude-code 0.2.0-rc.1 → 0.2.0-rc.3

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.
@@ -22,12 +22,16 @@ import type { Session } from '@deepseek-ai/dsh-session';
22
22
  import type { SubprocessHandle, SubprocessSpawnSpec } from '@deepseek-ai/dsh-subprocess';
23
23
  import type { DelegationExecTarget, LocalAgentToolCalls } from '@khorsheed/dsh-local-agent/types';
24
24
  import type { ClaudeLiveDriver } from './live-driver.ts';
25
+ import type { ClaudeEndpointAuth } from './endpoint-auth.ts';
25
26
  /** Default POSIX grace between subprocess termination tiers. */
26
27
  export declare const DEFAULT_DISPOSE_GRACE_MS = 3000;
27
28
  /**
28
29
  * Auth-shaped failure signatures in claude's result error or stderr: the
29
- * endpoint rejected the credential (401/403, revoked token). Narrow on
30
- * purpose — matched against provider-controlled error strings only.
30
+ * endpoint rejected the credential (401/403, revoked key). Matches the CLI's
31
+ * own phrasing ("Failed to authenticate. API Error: 401 …", the
32
+ * `authentication_failed` error tag) plus the relay phrasings seen in the
33
+ * wild ("invalid x-api-key" and friends). Narrow on purpose — matched against
34
+ * provider-controlled error strings only.
31
35
  */
32
36
  export declare const CLAUDE_AUTH_FAILURE: RegExp;
33
37
  /**
@@ -62,7 +66,7 @@ export declare function claudeCliVersion(ctx: Context, homeDir: string): Promise
62
66
  export declare class ClaudeCliProvider implements SubagentProvider {
63
67
  private readonly ctx;
64
68
  private readonly permissionMode;
65
- private readonly baseUrl?;
69
+ private readonly endpoint?;
66
70
  private readonly live?;
67
71
  private readonly model?;
68
72
  readonly name = "claude-local";
@@ -73,6 +77,11 @@ export declare class ClaudeCliProvider implements SubagentProvider {
73
77
  * generation's driver per member (the settings toggle swaps generations;
74
78
  * a resolver may return undefined to steer one member's round to exec
75
79
  * while a retiring generation still hosts it).
80
+ * @param endpoint - resolver for the round's endpoint credential (endpoint-auth.ts:
81
+ * the scope's endpoint-auth.json over the plugin config triple), read PER
82
+ * ROUND against the round's scoped home, so a key rotation or a profile
83
+ * edit takes effect on the next delegation without a reload. Absent, no
84
+ * `ANTHROPIC_*` variables reach the child at all.
76
85
  * @param model - resolver for the member's effective model, read PER ROUND
77
86
  * so a settings-card write or a composer switch takes effect on the next
78
87
  * delegation without a reload. Receives the member (the child session id)
@@ -81,7 +90,7 @@ export declare class ClaudeCliProvider implements SubagentProvider {
81
90
  * resolver not passed), the delegation's own model still rides, exactly
82
91
  * as before the key existed.
83
92
  */
84
- constructor(ctx: Context, permissionMode?: 'skip' | 'normal', baseUrl?: string | undefined, live?: ClaudeLiveDriver | ((childSessionId: string) => ClaudeLiveDriver | undefined) | undefined, model?: ((childSessionId: string, delegationModel?: string) => string | undefined) | undefined);
93
+ constructor(ctx: Context, permissionMode?: 'skip' | 'normal', endpoint?: ((homeDir: string) => Promise<ClaudeEndpointAuth>) | undefined, live?: ClaudeLiveDriver | ((childSessionId: string) => ClaudeLiveDriver | undefined) | undefined, model?: ((childSessionId: string, delegationModel?: string) => string | undefined) | undefined);
85
94
  /** Resolve the live driver for one round's member, if live is on for it. */
86
95
  private liveDriver;
87
96
  /** The round's model fragment for the exec spawn spec (see {@link resolveRoundModel}). */
@@ -17,19 +17,22 @@
17
17
  import { randomUUID } from 'node:crypto';
18
18
  import { createAssistantMessage, createToolResultMessage, createUserMessage } from '@deepseek-ai/dsh-llm';
19
19
  import { SessionId } from '@deepseek-ai/dsh-session';
20
- import { NO_START_CAPABILITIES, settleRunResult, subprocessRunHandle, } from '@deepseek-ai/dsh-subagent';
20
+ import { NO_START_CAPABILITIES, SUBAGENT_DESCRIPTOR_VERSION, settleRunResult, subprocessRunHandle, } from '@deepseek-ai/dsh-subagent';
21
21
  import { assertResumeCwdUnchanged, assertResumeScopeUnchanged, resolveRoundModel, containerExecSpawn, containerScopedHome, delegationEnv, establishSubagentCatalogChild, persistChildSession, probeCliVersion, resolveChildCwd, subagentDelegationLabel, } from '@khorsheed/dsh-local-agent';
22
22
  import { MEMBER_BRIDGE_SOCKET_ENV, MEMBER_BRIDGE_TOKEN_ENV } from '@khorsheed/dsh-local-agent/types';
23
23
  import { LiveChannelUnavailableError } from './live-driver.js';
24
- import { syncClaudeCredentialFile } from './records.js';
24
+ import { endpointAuthEnv } from './endpoint-auth.js';
25
25
  /** Default POSIX grace between subprocess termination tiers. */
26
26
  export const DEFAULT_DISPOSE_GRACE_MS = 3_000;
27
27
  /**
28
28
  * Auth-shaped failure signatures in claude's result error or stderr: the
29
- * endpoint rejected the credential (401/403, revoked token). Narrow on
30
- * purpose — matched against provider-controlled error strings only.
29
+ * endpoint rejected the credential (401/403, revoked key). Matches the CLI's
30
+ * own phrasing ("Failed to authenticate. API Error: 401 …", the
31
+ * `authentication_failed` error tag) plus the relay phrasings seen in the
32
+ * wild ("invalid x-api-key" and friends). Narrow on purpose — matched against
33
+ * provider-controlled error strings only.
31
34
  */
32
- export const CLAUDE_AUTH_FAILURE = /failed to authenticate|authentication_failed|oauth access token/i;
35
+ export const CLAUDE_AUTH_FAILURE = /failed to authenticate|authentication_failed|oauth access token|invalid (x-api-key|api key|authentication token)|api error: 40[13]/i;
33
36
  /** Register one member run with the channel; see {@link ClaudeMemberRunHandle}. */
34
37
  export function registerClaudeMemberRun(ctx, childSessionId, parentSessionId) {
35
38
  const registry = ctx.localAgent;
@@ -119,7 +122,7 @@ export function claudeCliVersion(ctx, homeDir) {
119
122
  export class ClaudeCliProvider {
120
123
  ctx;
121
124
  permissionMode;
122
- baseUrl;
125
+ endpoint;
123
126
  live;
124
127
  model;
125
128
  name = 'claude-local';
@@ -130,6 +133,11 @@ export class ClaudeCliProvider {
130
133
  * generation's driver per member (the settings toggle swaps generations;
131
134
  * a resolver may return undefined to steer one member's round to exec
132
135
  * while a retiring generation still hosts it).
136
+ * @param endpoint - resolver for the round's endpoint credential (endpoint-auth.ts:
137
+ * the scope's endpoint-auth.json over the plugin config triple), read PER
138
+ * ROUND against the round's scoped home, so a key rotation or a profile
139
+ * edit takes effect on the next delegation without a reload. Absent, no
140
+ * `ANTHROPIC_*` variables reach the child at all.
133
141
  * @param model - resolver for the member's effective model, read PER ROUND
134
142
  * so a settings-card write or a composer switch takes effect on the next
135
143
  * delegation without a reload. Receives the member (the child session id)
@@ -138,10 +146,10 @@ export class ClaudeCliProvider {
138
146
  * resolver not passed), the delegation's own model still rides, exactly
139
147
  * as before the key existed.
140
148
  */
141
- constructor(ctx, permissionMode = 'skip', baseUrl, live, model) {
149
+ constructor(ctx, permissionMode = 'skip', endpoint, live, model) {
142
150
  this.ctx = ctx;
143
151
  this.permissionMode = permissionMode;
144
- this.baseUrl = baseUrl;
152
+ this.endpoint = endpoint;
145
153
  this.live = live;
146
154
  this.model = model;
147
155
  }
@@ -168,8 +176,8 @@ export class ClaudeCliProvider {
168
176
  // The scoped home this round runs against: the staged intent's scope
169
177
  // names a sibling directory under the homes root, absent means the
170
178
  // default one — the directory every round used before scopes existed.
171
- // claude's keychain item is keyed by the config directory's path, so a
172
- // named scope gets its own credential item for free.
179
+ // A named scope's endpoint-auth.json overrides the deployment credential
180
+ // for its rounds (endpoint-auth.ts).
173
181
  const scope = intent?.scope;
174
182
  const homeDir = this.ctx.localAgent.homeDir('claude-code', scope);
175
183
  // The effective cwd: the caller's override (the staged intent's `cwd`,
@@ -209,7 +217,7 @@ export class ClaudeCliProvider {
209
217
  ...record?.configurationLock === undefined ? {} : { configurationLock: record.configurationLock },
210
218
  }, configuration => this.startClaudeResume(request, intent, cwd, homeDir, exec, scope, record?.model, configuration), request.signal, intent?.onAdmitted);
211
219
  }
212
- const childSessionId = SessionId(intent?.preparedMemberId ?? randomUUID());
220
+ const childSessionId = SessionId(intent?.preparedMemberId ?? intent?.childSessionId ?? randomUUID());
213
221
  if (typeof this.ctx.localAgent.withMemberConfigurationRound !== 'function') {
214
222
  if (intent?.effort !== undefined)
215
223
  throw new Error('Claude effort requires the configuration admission core');
@@ -242,14 +250,20 @@ export class ClaudeCliProvider {
242
250
  },
243
251
  });
244
252
  const harness = this.ctx.localAgent.get('claude-code');
245
- const label = subagentDelegationLabel(harness?.displayName ?? 'Claude Code', request.descriptor.label);
253
+ // Host 0.2.1 no longer resolves a descriptor onto the request (the
254
+ // runtime's one-shot snapshot is gone), so the provider stamps the same
255
+ // payload itself; the activation spec's required label arrives as the
256
+ // empty string when the caller named none.
257
+ const label = subagentDelegationLabel(harness?.displayName ?? 'Claude Code', request.label || undefined);
246
258
  childSession.append('subagent/descriptor', {
247
- ...request.descriptor,
259
+ version: SUBAGENT_DESCRIPTOR_VERSION,
260
+ mode: 'one-shot',
261
+ provider: this.name,
248
262
  label,
249
263
  });
250
- // The official runtime appends the parent-side subagent/catalog
251
- // discovery row only for in-process children (run.localAgent); this run
252
- // is remote, so the provider appends it here — once per child, where
264
+ // The 0.2.1 manager appends the parent-side subagent/catalog discovery
265
+ // row only for parent-delivered children; the family runs caller
266
+ // delivery, so the provider appends it here — once per child, where
253
267
  // the descriptor lands. A failure degrades to the warn below; a missing
254
268
  // row never blocks the delegation.
255
269
  establishSubagentCatalogChild(request.parent.session, childSession.header, label);
@@ -262,12 +276,12 @@ export class ClaudeCliProvider {
262
276
  catch (error) {
263
277
  this.ctx.logger.warn(`subagent-claude: subagent session record failed: ${error instanceof Error ? error.message : String(error)}`);
264
278
  }
265
- // Resolve the effective endpoint once per run: the cordis Config field
266
- // wins, else the host environment's ANTHROPIC_BASE_URL (a STARTUP-time
267
- // snapshot — a long-running dsh process does not see later shell exports),
268
- // else the CLI's own default. Log it (without the key) so a failing
269
- // delegation reports which endpoint it actually used.
270
- const effectiveBaseUrl = this.baseUrl ?? process.env.ANTHROPIC_BASE_URL;
279
+ // Resolve the effective endpoint once per run: the scope's
280
+ // endpoint-auth.json over the plugin config triple (endpoint-auth.ts).
281
+ // Logged WITHOUT the key so a failing delegation reports which endpoint
282
+ // it actually used.
283
+ const endpoint = await this.endpoint?.(homeDir);
284
+ const effectiveBaseUrl = endpoint?.baseUrl;
271
285
  this.ctx.logger.info(`subagent-claude: delegating via ${effectiveBaseUrl ?? 'claude default endpoint'}`);
272
286
  // Live driver: the round goes to the member's resident stream-json
273
287
  // process. A channel that fails at spawn falls through to the exec
@@ -276,6 +290,14 @@ export class ClaudeCliProvider {
276
290
  // a resident stream-json process on the HOST, which is the transport the
277
291
  // target exists to replace.
278
292
  const live = exec === undefined ? this.liveDriver(runId) : undefined;
293
+ // The round's model, computed once: the configuration admission's
294
+ // resolution wins, else the family's order (session override, the
295
+ // delegation's own model, the scope's curated list / settings key).
296
+ // Whatever it is — explicit or followed — the first round STAMPS it into
297
+ // the delegation record: the member is bound to this model from then on,
298
+ // and a later edit of the curated list moves the default only for NEW
299
+ // members, never underneath a conversation (its cache lineage included).
300
+ const round = configuration?.resolved ?? this.roundModel(runId, requestedModel);
279
301
  if (live !== undefined && childSession !== undefined && !live.disabled) {
280
302
  // The member-bound live driver receives this exact scoped home.
281
303
  try {
@@ -303,9 +325,9 @@ export class ClaudeCliProvider {
303
325
  cwd,
304
326
  // …and its scoped home anchors the resume-scope check.
305
327
  ...scope === undefined ? {} : { scope },
306
- // The model this delegation asked for: every resume round reads
307
- // it back from here instead of the caller restating it.
308
- ...requestedModel === undefined ? {} : { model: requestedModel },
328
+ // The model the member is BOUND to (see `round` above): every
329
+ // resume round re-requests it from here.
330
+ ...round.model === undefined ? {} : { model: round.model },
309
331
  });
310
332
  },
311
333
  });
@@ -327,12 +349,12 @@ export class ClaudeCliProvider {
327
349
  cwd,
328
350
  env: delegationEnv({
329
351
  CLAUDE_CONFIG_DIR: homeDir,
330
- ...this.baseUrl === undefined ? {} : { ANTHROPIC_BASE_URL: this.baseUrl },
352
+ ...endpointAuthEnv(endpoint),
331
353
  }),
332
354
  ...exec === undefined ? {} : { exec },
333
355
  endpointLabel: effectiveBaseUrl,
334
356
  permissionMode: this.permissionMode,
335
- ...(configuration?.resolved ?? this.roundModel(runId, requestedModel)),
357
+ ...round,
336
358
  ...configuration === undefined ? {} : { controlled: true },
337
359
  disposeGraceMs: DEFAULT_DISPOSE_GRACE_MS,
338
360
  spawn: spec => this.ctx.subprocess.spawn(spec),
@@ -360,8 +382,9 @@ export class ClaudeCliProvider {
360
382
  cwd,
361
383
  // …and its scoped home anchors the resume-scope check.
362
384
  ...scope === undefined ? {} : { scope },
363
- // The model this delegation asked for (see the live branch).
364
- ...requestedModel === undefined ? {} : { model: requestedModel },
385
+ // The model the member is BOUND to (see `round` above; the exec
386
+ // spawn below runs this same value).
387
+ ...round.model === undefined ? {} : { model: round.model },
365
388
  });
366
389
  },
367
390
  // Every settled round reports its observed model and usage through the
@@ -426,7 +449,8 @@ export class ClaudeCliProvider {
426
449
  this.ctx.logger.warn(`subagent-claude: live driver unavailable, using the exec one-shot: ${error.message}`);
427
450
  }
428
451
  }
429
- const effectiveBaseUrl = this.baseUrl ?? process.env.ANTHROPIC_BASE_URL;
452
+ const endpoint = await this.endpoint?.(homeDir);
453
+ const effectiveBaseUrl = endpoint?.baseUrl;
430
454
  this.ctx.logger.info(`subagent-claude: resuming via ${effectiveBaseUrl ?? 'claude default endpoint'}`);
431
455
  // Member channel: register the resume round (same child session, fresh
432
456
  // per-run token) before the spawn.
@@ -438,7 +462,7 @@ export class ClaudeCliProvider {
438
462
  cwd,
439
463
  env: delegationEnv({
440
464
  CLAUDE_CONFIG_DIR: homeDir,
441
- ...this.baseUrl === undefined ? {} : { ANTHROPIC_BASE_URL: this.baseUrl },
465
+ ...endpointAuthEnv(endpoint),
442
466
  }),
443
467
  ...exec === undefined ? {} : { exec },
444
468
  endpointLabel: effectiveBaseUrl,
@@ -1025,20 +1049,6 @@ export async function startClaudeCliRun(request, spec) {
1025
1049
  if (request.signal.aborted) {
1026
1050
  throw new Error('subagent-claude: request was aborted before the CLI started');
1027
1051
  }
1028
- // Credential reconcile before EVERY spawn: claude 2.1.236 reads
1029
- // .credentials.json at runtime while login/refresh write the keychain, so
1030
- // the login watch's sync alone leaves a rotated grant stale at spawn time
1031
- // (the live driver's spawnRuntime does the same). Best-effort: a missing
1032
- // grant fails the run with the CLI's own auth error, not here.
1033
- // NOTE the directory: on a container round this is still the HOST scoped
1034
- // home (the in-container path only replaces it in the `docker exec -e`
1035
- // forwarding), and the unit is about to read that same file through the
1036
- // bind mount — which is why the reconcile is newer-wins rather than a
1037
- // mirror. See `syncClaudeCredentialFile`.
1038
- const configDir = spec.env['CLAUDE_CONFIG_DIR'];
1039
- if (configDir !== undefined) {
1040
- await syncClaudeCredentialFile(configDir, message => { spec.ctx?.logger.warn(message); }).catch(() => false);
1041
- }
1042
1052
  const turn = spec.resume?.turn ?? 1;
1043
1053
  // The member bridge flags ride every argv variant (skip and normal
1044
1054
  // permission modes alike): --allowedTools is redundant under
@@ -1221,10 +1231,12 @@ export async function startClaudeCliRun(request, spec) {
1221
1231
  return mirrorClaudeAfterExit(spec, task, turn, output, liveMirror);
1222
1232
  }, () => { });
1223
1233
  return Promise.resolve(subprocessRunHandle({
1224
- // A session-backed run's id is the child session id (the seam's local-run
1225
- // contract), so the tool's resume self-description names the same handle
1226
- // the delegation registry records.
1227
- id: spec.childSession?.id ?? SessionId(randomUUID()),
1234
+ // Host 0.2.1: the published run id is a fresh PER-EXECUTION identity —
1235
+ // the activation manager rejects a run id naming a live Session (the
1236
+ // mirrored child session is exactly that), and resume rounds reuse the
1237
+ // child session id. The durable child identity the family tracks rides
1238
+ // the staged intent instead (spec.childSession.id == its childSessionId).
1239
+ id: SessionId(randomUUID()),
1228
1240
  result,
1229
1241
  signal: request.signal,
1230
1242
  onAbort,
@@ -1,8 +1,6 @@
1
- import type { HarnessModelPickerInput } from '@khorsheed/dsh-local-agent/client';
2
- import type { ReactNode } from 'react';
3
1
  import type { SettingsScope } from '@khorsheed/dsh-local-agent/src/client/settings-scope.ts';
4
2
  import type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
5
- import type { LocalAgentModelInfo } from '@khorsheed/dsh-local-agent/types';
3
+ import type { LocalAgentModelDirectory, LocalAgentEndpointAuthFields, LocalAgentEndpointAuthState } from '@khorsheed/dsh-local-agent/types';
6
4
  import { type ProviderAuthBlockProps, type ProviderAuthInjected } from '@khorsheed/dsh-local-agent/src/client/ProviderAuthBlock.tsx';
7
5
  import { NS } from './locales.ts';
8
6
  /** The `local-agent-claude-code` settings namespace section the card edits. */
@@ -22,7 +20,6 @@ export interface ClaudeLiveSettings {
22
20
  }
23
21
  /** Injected face of the claude-code settings card. */
24
22
  export interface ClaudeCodeSettingsCardInjected {
25
- renderModelPicker?: ((props: HarnessModelPickerInput) => ReactNode) | undefined;
26
23
  /** Bound settings scope for the local-agent-claude-code namespace. */
27
24
  scope: SettingsScope<ClaudeLiveSettings>;
28
25
  /** The auth block's query/command faces, backed by the family core Remote. */
@@ -30,34 +27,78 @@ export interface ClaudeCodeSettingsCardInjected {
30
27
  /** Translate bound to the family core's `local-agent` namespace (the auth block's copy lives there). */
31
28
  authT: ProviderAuthBlockProps['t'];
32
29
  /**
33
- * The harness's memberless model surface (the family gateway's
34
- * `harnessModel` Remote): the inherited default the unset field displays
35
- * and the menu's choice vocabulary. Absent on a core that predates the
36
- * model broker — the card then keeps the bare free-text input exactly as
37
- * before brokers existed.
30
+ * The harness's curated model list (the family gateway's
31
+ * `modelList`/`configureModelList` Remotes): the editor's ordered
32
+ * shortlist — its first entry is the default model. Absent on a core that
33
+ * predates the Remotes — the card then hides the editor.
38
34
  */
39
- modelInfo?: () => Promise<LocalAgentModelInfo | null | undefined>;
35
+ modelList?: {
36
+ read(): Promise<readonly string[] | null | undefined>;
37
+ write(models: readonly string[]): Promise<readonly string[] | null | undefined>;
38
+ };
39
+ /**
40
+ * The endpoint's served model catalog (the family gateway's
41
+ * `modelDirectory` Remote): the add dialog's candidate vocabulary. Absent
42
+ * on a core that predates the Remote — the dialog then shows its reason.
43
+ */
44
+ modelDirectory?: (refresh?: boolean) => Promise<LocalAgentModelDirectory | null | undefined>;
45
+ /**
46
+ * The harness's endpoint verification (the family gateway's `checkEndpoint`
47
+ * Remote): a token-free probe of the SAVED endpoint, answered as verdict
48
+ * text. Absent on a core that predates the Remote — the card then hides
49
+ * the verify button.
50
+ */
51
+ checkEndpoint?: () => Promise<string | null | undefined>;
52
+ /**
53
+ * The harness's endpoint credential face (the family gateway's
54
+ * `endpointAuth`/`configureEndpoint` Remotes): the card's credential form
55
+ * reads and writes the harness's OWN credential store through it — never
56
+ * the settings scope, so no key ever lands in the profile patch document.
57
+ * Absent on a core that predates the Remotes — the card then hides the
58
+ * form. `write` answers the post-write resolved state.
59
+ */
60
+ endpointAuth?: {
61
+ read(): Promise<LocalAgentEndpointAuthState | null | undefined>;
62
+ write(fields: LocalAgentEndpointAuthFields): Promise<LocalAgentEndpointAuthState | null | undefined>;
63
+ };
40
64
  hooks: {
41
65
  /** The same scope as a hooks source, so the card reacts to external writes. */
42
66
  settings: SettingsScope<ClaudeLiveSettings>;
43
67
  };
44
68
  }
45
69
  /**
46
- * Full props of the 0.1.5 settings.plugin.item card entry. The removed slot's
47
- * owner share was intentionally empty and its root scope delivered the global
48
- * seats; the structural type below is exact about the one seat the auth block
49
- * consumes (the slot name is gone from the alpha.2 SlotMap, so the
50
- * registration goes through a duck-typed narrow — see client/index.ts).
70
+ * Full props of the retired 0.1.5 settings.plugin.item card. The host removed
71
+ * that seat and client/index.ts no longer registers the component — the live
72
+ * settings surface is the plugins.item entry built on the BundleConfig
73
+ * component below; this export remains for the component spec and direct
74
+ * composers. The removed slot's owner share was intentionally empty and its
75
+ * root scope delivered the global seats; the structural type below is exact
76
+ * about the one seat the auth block consumes.
51
77
  */
52
78
  export type ClaudeCodeSettingsCardProps = InjectFace<ClaudeCodeSettingsCardInjected> & PropsLocale<typeof NS> & {
53
79
  /** The standing root-scope global seat (ui-session's merge), delivered to the 0.1.5 card by the renderer. */
54
80
  useSessions: ProviderAuthBlockProps['useSessions'];
55
81
  };
56
- /** Full props of the alpha.2 plugins.bundle.config entry (owner prop `view`). */
57
- export type ClaudeCodeBundleConfigProps = PropsRuntime<'plugins.bundle.config'> & InjectFace<ClaudeCodeSettingsCardInjected> & PropsLocale<typeof NS>;
82
+ /** Full props of the plugins.item entry (owner prop `view`). */
83
+ export type ClaudeCodeBundleConfigProps = PropsRuntime<'plugins.item'> & InjectFace<ClaudeCodeSettingsCardInjected> & PropsLocale<typeof NS>;
84
+ /**
85
+ * Full props of the harness's section inside the core's「本机 Agent 委派」
86
+ * family card: the same inject face minus the slot-owner share, plus the one
87
+ * global seat the body consumes, forwarded by the family card (the section
88
+ * render bypasses the slot runtime, so its remaining standard seats are not
89
+ * fabricable here and are deliberately absent).
90
+ */
91
+ export type ClaudeCodeCardSectionProps = InjectFace<ClaudeCodeSettingsCardInjected> & PropsLocale<typeof NS> & {
92
+ /** Whether the section is currently expanded (the family card mounts the body only while it is). */
93
+ readonly active: boolean;
94
+ /** The standing root-scope global seat (ui-session's merge), forwarded by the family card. */
95
+ readonly useSessions: ProviderAuthBlockProps['useSessions'];
96
+ };
58
97
  /**
59
- * The claude-code harness settings card in the 0.1.5 plugin configuration
60
- * tab: the same collapsible chrome the official plugin cards use,
98
+ * The claude-code harness settings card of the retired 0.1.5 plugin
99
+ * configuration tab (no longer registered; the live surface is the
100
+ * plugins.item entry below): the same collapsible chrome the official plugin
101
+ * cards use,
61
102
  * re-implemented locally (the bundle-purity gate forbids value-importing the
62
103
  * official chrome — the context-guard pattern), with the at-a-glance
63
104
  * credential dot in the header. Explanation copy lives in hover/focus bubbles
@@ -67,12 +108,22 @@ export type ClaudeCodeBundleConfigProps = PropsRuntime<'plugins.bundle.config'>
67
108
  */
68
109
  export declare function ClaudeCodeSettingsCard(props: ClaudeCodeSettingsCardProps): import("react").JSX.Element;
69
110
  /**
70
- * The bundle's configuration on the alpha.2 Plugins page
71
- * (`plugins.bundle.config`, keyed by package name): the page draws the title,
72
- * the icon, and the crumb itself, so the entry renders the one-liner for the
73
- * `summary` view and the bare form — with its own save control — for `page`.
111
+ * The provider's card on the Plugins page (the `plugins.item` entry
112
+ * client/index.ts registers while the Host serves the namespace AND the core
113
+ * predates the family card): the page
114
+ * draws the title, the icon, and the crumb itself, so the entry renders the
115
+ * one-liner for the `summary` view and the bare form — with its own save
116
+ * control — for `page`.
74
117
  * @param props - the owner view, the injected scope/auth faces, and copy.
75
118
  * @returns the entry.
76
119
  */
77
- export declare function ClaudeCodeBundleConfig({ view, useSettings, scope, auth, authT, renderModelPicker, modelInfo, useSessions, t }: ClaudeCodeBundleConfigProps): import("react").JSX.Element;
120
+ export declare function ClaudeCodeBundleConfig({ view, useSettings, scope, auth, authT, modelList, modelDirectory, checkEndpoint, endpointAuth, useSessions, t }: ClaudeCodeBundleConfigProps): import("react").JSX.Element;
121
+ /**
122
+ * The harness's section inside the core's「本机 Agent 委派」family card: the
123
+ * same useCardState + CardBody the plugins.item page view renders — the
124
+ * collapsible chrome belongs to the family card now.
125
+ * @param props - the injected scope/auth faces, the forwarded session seat, and copy.
126
+ * @returns the section body.
127
+ */
128
+ export declare function ClaudeCodeCardSection({ active, useSettings, scope, auth, authT, modelList, modelDirectory, checkEndpoint, endpointAuth, useSessions, t }: ClaudeCodeCardSectionProps): import("react").JSX.Element;
78
129
  //# sourceMappingURL=SettingsCard.d.ts.map