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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,7 +7,7 @@ import { IconChevronDownOutlineMedium } from './icons.js';
7
7
  // the block carries no runtime identity to share.
8
8
  import { ProviderAuthBlock, } from '@khorsheed/dsh-local-agent/src/client/ProviderAuthBlock.tsx';
9
9
  import { AuthStatusDot } from '@khorsheed/dsh-local-agent/src/client/AuthStatusDot.tsx';
10
- import { publishAuthStatus, useHarnessAuthStatus } from '@khorsheed/dsh-local-agent/src/client/auth-status.ts';
10
+ import { publishAuthStatus, useHarnessAuthStatus, usePublishedAuthStatus } from '@khorsheed/dsh-local-agent/src/client/auth-status.ts';
11
11
  import { ModelListSection } from '@khorsheed/dsh-local-agent/src/client/ModelListSection.tsx';
12
12
  import css from './SettingsCard.module.css';
13
13
  /**
@@ -47,6 +47,10 @@ function useCardState(active, useSettings, scope, endpointAuth) {
47
47
  const endpointLoading = !endpointUnavailable && endpointState === null;
48
48
  const apiKeyConfigured = endpointState !== null && endpointState !== 'unavailable' && endpointState.apiKeySet;
49
49
  const authTokenConfigured = endpointState !== null && endpointState !== 'unavailable' && endpointState.authTokenSet;
50
+ // A login or logout elsewhere in the card (the auth block) changes what
51
+ // the store holds — logout deletes the saved key: re-read, or the form
52
+ // keeps saying 已配置 for a key that is gone.
53
+ const authPublished = usePublishedAuthStatus('claude-code');
50
54
  useEffect(() => {
51
55
  if (!active || endpointAuth === undefined)
52
56
  return;
@@ -55,11 +59,15 @@ function useCardState(active, useSettings, scope, endpointAuth) {
55
59
  setEndpointState(state ?? 'unavailable'); }, () => { if (!stale)
56
60
  setEndpointState('unavailable'); });
57
61
  return () => { stale = true; };
58
- }, [active, endpointAuth, endpointSaved]);
62
+ }, [active, endpointAuth, endpointSaved, authPublished]);
59
63
  const write = (field, value) => {
60
64
  setSaved(false);
61
65
  setError(false);
62
- void scope.set(field, value).then(() => { setSaved(true); }, () => { setError(true); });
66
+ // The host answers a refused write with `false` (ConfigForm), not a rejection.
67
+ void scope.set(field, value).then((accepted) => { if (accepted === false)
68
+ setError(true);
69
+ else
70
+ setSaved(true); }, () => { setError(true); });
63
71
  };
64
72
  // The credential save: one `configureEndpoint` call carrying only the
65
73
  // dirty fields (a blank draft clears its field); the answer is the
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Generated by scripts/sync-icon-artwork.mts from @deepseek-ai/dsh-client-ui-primitives
3
- * (v0.1.7-rc.1, harness 46a7f68b09) — do not edit by hand. The 0.1.5 and rc.1 host lines
3
+ * (v0.2.1-rc.1, harness 1600d8a1e1) — do not edit by hand. The 0.1.5 and rc.1 host lines
4
4
  * share no icon export name, so the rc.1 artwork is inlined here: pure SVG,
5
5
  * no host runtime identity, identical on every line. Re-run the generator
6
6
  * after adding an icon import or bumping the harness checkout.
@@ -1,4 +1,4 @@
1
- import { bindSettingsScope } from '@khorsheed/dsh-local-agent/src/client/settings-scope.ts';
1
+ import { bindCardSettingsScope } from '@khorsheed/dsh-local-agent/src/client/settings-scope.ts';
2
2
  /**
3
3
  * Local-agent-claude-code plugin, browser half: the claude-code settings card
4
4
  * — a section of the family core's「本机 Agent 委派」family card on the
@@ -44,7 +44,7 @@ export const inject = ['slots', 'remote', 'remote.commands', 'locale'];
44
44
  export function apply(ctx) {
45
45
  ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'local-agent-claude-code: dictionaries');
46
46
  const t = ctx.locale.bind(NS);
47
- const scope = bindSettingsScope(ctx, 'local-agent-claude-code');
47
+ const scope = bindCardSettingsScope(ctx, 'claude-code', 'local-agent-claude-code');
48
48
  // The auth block's copy lives in the family core's dictionary; binding is
49
49
  // stable per namespace and late dictionary registration still resolves.
50
50
  const authT = ctx.locale.bind('local-agent');
@@ -186,6 +186,22 @@ function servedEfforts(effort) {
186
186
  .filter(level => effort[level]?.supported === true);
187
187
  return levels.length === 0 ? undefined : levels;
188
188
  }
189
+ /**
190
+ * The effort block's home in a served-model entry. Anthropic's current
191
+ * /v1/models shape nests it under `capabilities.effort` (verified against the
192
+ * openproxy relay 2026-10-22: `capabilities.effort.<level>.supported`); the
193
+ * flat top-level `effort` the parser was written against still wins when
194
+ * present, so either shape answers.
195
+ */
196
+ function servedEffortsOf(record) {
197
+ const direct = servedEfforts(record['effort']);
198
+ if (direct !== undefined)
199
+ return direct;
200
+ const capabilities = record['capabilities'];
201
+ if (typeof capabilities !== 'object' || capabilities === null)
202
+ return undefined;
203
+ return servedEfforts(capabilities['effort']);
204
+ }
189
205
  /**
190
206
  * `GET <baseUrl>/v1/models` with the resolved credential's auth header(s) —
191
207
  * the token-free endpoint probe shared by the `/claude-code check` verdict
@@ -231,7 +247,7 @@ export async function fetchEndpointModels(endpoint, fetchImpl, signal) {
231
247
  const record = entry;
232
248
  if (typeof record.id !== 'string' || record.id === '')
233
249
  continue;
234
- const efforts = servedEfforts(record.effort);
250
+ const efforts = servedEffortsOf(record);
235
251
  models.push({
236
252
  id: record.id,
237
253
  ...typeof record.display_name === 'string' && record.display_name !== '' ? { displayName: record.display_name } : {},
@@ -42,7 +42,7 @@ export const inject = ['localAgent', 'subagents', 'subprocess', 'settings'];
42
42
  * behavior byte-identical.
43
43
  */
44
44
  const SETTINGS_FIELDS = {
45
- live: z.boolean().default(false),
45
+ live: z.boolean().default(true),
46
46
  liveMirrorGranularity: z.union([z.const('event'), z.const('token')]).default('token'),
47
47
  model: z.string(),
48
48
  recentModels: z.array(z.string()).default([]),
@@ -109,7 +109,7 @@ export function apply(ctx, config) {
109
109
  const model = vol(config.model);
110
110
  const recentModels = vol(config.recentModels);
111
111
  return {
112
- live: vol(config.live) ?? false,
112
+ live: vol(config.live) ?? true,
113
113
  liveMirrorGranularity: vol(config.liveMirrorGranularity) ?? 'token',
114
114
  ...model === undefined ? {} : { model },
115
115
  ...recentModels === undefined ? {} : { recentModels },
@@ -123,6 +123,8 @@ export function apply(ctx, config) {
123
123
  }
124
124
  const face = settingsFace(ctx, {
125
125
  namespace: CLAUDE_SETTINGS_NAMESPACE,
126
+ // Card writes live in the harness's own store (card-settings.ts), never the profile patch.
127
+ harness: 'claude-code',
126
128
  legacySchema: CLAUDE_SETTINGS_SCHEMA,
127
129
  legacyBase,
128
130
  read: readSettings,
@@ -16,11 +16,6 @@ export declare const DEFAULT_LIVE_CHANNEL_RETRY_MS: number;
16
16
  export declare const DEFAULT_SNAPSHOT_MIN_INTERVAL_MS = 50;
17
17
  /** Default minimum text growth between one streaming kind's snapshot messages. */
18
18
  export declare const DEFAULT_SNAPSHOT_MIN_CHARS = 0;
19
- /**
20
- * The stream-json channel could not come up (spawn failure or the first
21
- * turn's init never arrived). The provider catches exactly this and falls
22
- * back to the exec one-shot; any other error is a real round failure.
23
- */
24
19
  export declare class LiveChannelUnavailableError extends Error {
25
20
  constructor(message: string);
26
21
  }