@norman-else/dsh-claude 0.1.11 → 0.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.d.mts CHANGED
@@ -3,28 +3,33 @@ import { EffortLevel, Options, Query, SDKControlGetContextUsageResponse, SDKUser
3
3
  import { SubprocessRuntime } from "@deepseek-ai/dsh-subprocess";
4
4
  import { Context } from "@deepseek-ai/cordis";
5
5
  import { Agent } from "@deepseek-ai/dsh-agent";
6
- import { CommandDefinition, CommandDescriptor } from "@deepseek-ai/dsh-commands";
6
+ import { CommandDescriptor } from "@deepseek-ai/dsh-commands";
7
7
  import { SessionEvent } from "@deepseek-ai/dsh-session";
8
8
  import { ApprovalService } from "@deepseek-ai/dsh-user-approval";
9
9
  import { UserQuestionService } from "@deepseek-ai/dsh-user-questions";
10
10
  //#region src/command-bridge.d.ts
11
11
  /**
12
- * Agent-scope command service contract. The commands service is unreachable
12
+ * Agent-scope command-directory contract. The commands service is unreachable
13
13
  * from the host plugin's view of `agent.ctx` ("without inject"), but the
14
- * preset route plugin runs INSIDE the agent's preset composition with
15
- * `commands` injected. Registrations made through the provided service land
16
- * in the agent's scope layer, which the command registry inherits into
17
- * `list(agent)` for exactly that agent — invisible to every other session.
14
+ * preset route plugin runs inside the agent's preset composition with
15
+ * `commands` injected. The Host reads only the exact agent's effective names
16
+ * for collision checks; Claude catalog entries are never registered there.
18
17
  */
19
18
  interface ClaudeAgentCommandService {
20
19
  list(agent: unknown): readonly Pick<CommandDescriptor, 'name'>[];
21
- register(definition: CommandDefinition): () => void;
22
20
  }
23
21
  declare module '@deepseek-ai/cordis' {
24
22
  interface Context {
25
23
  claudeCommands?: ClaudeAgentCommandService;
26
24
  }
27
25
  }
26
+ interface ClaudeCommandView {
27
+ publicName: string;
28
+ claudeName: string;
29
+ description: string;
30
+ hint?: string;
31
+ prefixed: boolean;
32
+ }
28
33
  //#endregion
29
34
  //#region src/events.d.ts
30
35
  type ClaudeActivityKind = 'status' | 'thinking' | 'tool-call' | 'tool-result' | 'permission' | 'question' | 'subagent' | 'usage' | 'warning' | 'error';
@@ -232,7 +237,7 @@ interface Config {
232
237
  maxProcesses?: number;
233
238
  }
234
239
  declare const Config: z<Config>;
235
- declare function mountClaudeMetadata(ctx: Context, supervisor: ClaudeSupervisor, agent: Agent, model: string, sidecar: ClaudeSidecarRepository, resolveCommands?: () => ClaudeAgentCommandService | undefined): (() => Promise<void>) | undefined;
240
+ declare function mountClaudeMetadata(ctx: Context, supervisor: ClaudeSupervisor, agent: Agent, model: string, sidecar: ClaudeSidecarRepository, publishCommands?: (commands: readonly ClaudeCommandView[]) => void, resolveCommands?: () => ClaudeAgentCommandService | undefined): (() => Promise<void>) | undefined;
236
241
  declare function installManagedPresetCompatibility(logger: Pick<Context['logger'], 'warn'>, install?: typeof ensureManagedPreset): Promise<'installed' | 'unchanged' | 'conflict'>;
237
242
  declare function apply(ctx: Context, config: Config): Promise<void>;
238
243
  //#endregion
package/lib/index.mjs CHANGED
@@ -1,14 +1,14 @@
1
1
  import { _ as CLAUDE_PROJECTION_PATH, a as latestClaudeTasks, c as normalizeTasksEvent, d as CLAUDE_ACTIVITY_EVENT, f as CLAUDE_CODE_PRESET_ID, g as CLAUDE_GLOBAL_SETTINGS_PATH, h as CLAUDE_DOCTOR_PATH, i as latestClaudeSessionBinding, l as redactText, m as CLAUDE_CODE_PROVIDER_IDS, n as currentClaudeActivityCursor, o as normalizeActivity, p as CLAUDE_CODE_PROVIDER, r as latestClaudeContextUsage, s as normalizeContextUsage, t as boundText, u as safeDetail, v as CLAUDE_UPDATE_CHECK_PATH, x as TASK_TOOL_NAMES, y as CLAUDE_UPDATE_PATH } from "./events-6xTApIQw.mjs";
2
- import { a as ClaudeCommandBridge, i as CLAUDE_COMMANDS_SERVICE, r as dynamicPresenterDefinition, t as CLAUDE_PRESENTER_NAMES } from "./presenters-BE6LPw2m.mjs";
2
+ import { a as projectClaudeCommands, i as CLAUDE_COMMANDS_SERVICE, r as dynamicPresenterDefinition, t as CLAUDE_PRESENTER_NAMES } from "./presenters-CtgkpzZo.mjs";
3
3
  import { a as resolveClaudeExecutable, n as ensureManagedPreset, o as runClaudeDoctor, t as ManagedPresetConflictError } from "./preset-installer-B0NrA4Hi.mjs";
4
4
  import z from "@deepseek-ai/schemastery";
5
- import { CallId, LlmAdapter, ReasoningEffortId, createToolResultMessage, createUserMessage } from "@deepseek-ai/dsh-llm";
6
5
  import { randomUUID } from "node:crypto";
7
6
  import { chmod, mkdir, opendir, readFile, realpath, rename, rm, writeFile } from "node:fs/promises";
8
7
  import { dirname, extname, join, resolve } from "node:path";
9
8
  import { dshHomePath, resolveDshHome } from "@deepseek-ai/dsh-home-paths";
10
9
  import { homedir } from "node:os";
11
10
  import { query } from "@anthropic-ai/claude-agent-sdk";
11
+ import { CallId, LlmAdapter, ReasoningEffortId, createToolResultMessage } from "@deepseek-ai/dsh-llm";
12
12
  import { EventEmitter } from "node:events";
13
13
  import { DSH_ENV_PREFIX, SENSITIVE_ENV_PATTERN } from "@deepseek-ai/dsh-subprocess";
14
14
  import { fileURLToPath } from "node:url";
@@ -2259,7 +2259,7 @@ function sessionIdFromUrl(rawUrl) {
2259
2259
  }
2260
2260
  }
2261
2261
  /** Register the browser-readable, credential-free sidecar projection endpoint. */
2262
- function registerClaudeProjectionRoute(ctx, sidecar, ownsSession) {
2262
+ function registerClaudeProjectionRoute(ctx, sidecar, ownsSession, commandsForSession = () => []) {
2263
2263
  ctx.effect(() => ctx.webServer.register({
2264
2264
  kind: "prefix",
2265
2265
  path: CLAUDE_PROJECTION_PATH,
@@ -2274,6 +2274,7 @@ function registerClaudeProjectionRoute(ctx, sidecar, ownsSession) {
2274
2274
  schemaVersion: projection.schemaVersion,
2275
2275
  revision: projection.revision,
2276
2276
  owned: ownsSession(sessionId),
2277
+ commands: commandsForSession(sessionId),
2277
2278
  activities: projection.activities,
2278
2279
  ...projection.contextUsage === void 0 ? {} : { contextUsage: projection.contextUsage },
2279
2280
  ...projection.tasks === void 0 ? {} : { tasks: projection.tasks }
@@ -2756,7 +2757,7 @@ const CATALOG_RETRY_MS = 5e3;
2756
2757
  const SCOPE_RETRY_MS = 500;
2757
2758
  const MAX_CATALOG_RETRIES = 3;
2758
2759
  const MAX_SCOPE_RETRIES = 24;
2759
- function mountClaudeMetadata(ctx, supervisor, agent, model, sidecar, resolveCommands = () => ctx.agentPresets.serviceFor(agent, CLAUDE_COMMANDS_SERVICE)) {
2760
+ function mountClaudeMetadata(ctx, supervisor, agent, model, sidecar, publishCommands = () => {}, resolveCommands = () => ctx.agentPresets.serviceFor(agent, CLAUDE_COMMANDS_SERVICE)) {
2760
2761
  if (ctx.agentPresets.composedPreset(agent.ctx) !== "claude") return void 0;
2761
2762
  let stopped = false;
2762
2763
  let pending = Promise.resolve();
@@ -2767,19 +2768,7 @@ function mountClaudeMetadata(ctx, supervisor, agent, model, sidecar, resolveComm
2767
2768
  commandScope = scoped;
2768
2769
  return scoped;
2769
2770
  };
2770
- const bridge = new ClaudeCommandBridge({
2771
- list: () => scopedCommands().list(agent),
2772
- register: (definition) => scopedCommands().register(definition),
2773
- forward: (receivingAgent, line) => {
2774
- receivingAgent.followup(createUserMessage({
2775
- content: [{
2776
- type: "text",
2777
- text: line
2778
- }],
2779
- source: { kind: "user" }
2780
- }));
2781
- }
2782
- });
2771
+ const commandTarget = { list: () => scopedCommands().list(agent) };
2783
2772
  const warn = (area, error) => {
2784
2773
  ctx.logger.warn(`dsh-claude: ${area} refresh failed for ${String(agent.id)}: ${error instanceof Error ? error.message : String(error)}`);
2785
2774
  };
@@ -2821,7 +2810,9 @@ function mountClaudeMetadata(ctx, supervisor, agent, model, sidecar, resolveComm
2821
2810
  }
2822
2811
  if (stopped || catalog === void 0) return;
2823
2812
  try {
2824
- diagnostic.registered = bridge.refresh(catalog).map((view) => view.publicName);
2813
+ const commands = projectClaudeCommands(catalog, commandTarget);
2814
+ publishCommands(commands);
2815
+ diagnostic.registered = commands.map((view) => view.publicName);
2825
2816
  if (!stopped) scopeRetries = 0;
2826
2817
  } catch (error) {
2827
2818
  diagnostic.lastError = error instanceof Error ? error.message : String(error);
@@ -2847,10 +2838,10 @@ function mountClaudeMetadata(ctx, supervisor, agent, model, sidecar, resolveComm
2847
2838
  refresh();
2848
2839
  return async () => {
2849
2840
  stopped = true;
2841
+ publishCommands([]);
2850
2842
  if (retryTimer !== void 0) clearTimeout(retryTimer);
2851
2843
  stopStatus();
2852
2844
  await pending;
2853
- bridge.dispose();
2854
2845
  };
2855
2846
  }, "dsh-claude: agent metadata bridge");
2856
2847
  }
@@ -2872,6 +2863,7 @@ async function apply(ctx, config) {
2872
2863
  maxProcesses: config.maxProcesses ?? 4
2873
2864
  };
2874
2865
  const sidecar = new ClaudeSidecarRepository();
2866
+ const commandCatalogs = /* @__PURE__ */ new Map();
2875
2867
  const supervisor = new ClaudeSupervisor({
2876
2868
  runtime: ctx.subprocess,
2877
2869
  approval: ctx.approval,
@@ -2891,7 +2883,11 @@ async function apply(ctx, config) {
2891
2883
  const MOUNT_RETRY_LIMIT = 50;
2892
2884
  const mount = (agent) => {
2893
2885
  if (mounted.has(agent)) return;
2894
- const dispose = mountClaudeMetadata(ctx, supervisor, agent, supervisorConfig.defaultModel, sidecar);
2886
+ const sessionId = agent.id;
2887
+ const dispose = mountClaudeMetadata(ctx, supervisor, agent, supervisorConfig.defaultModel, sidecar, (commands) => {
2888
+ if (commands.length === 0) commandCatalogs.delete(sessionId);
2889
+ else commandCatalogs.set(sessionId, commands);
2890
+ });
2895
2891
  if (dispose !== void 0) mounted.set(agent, dispose);
2896
2892
  pending.delete(agent);
2897
2893
  };
@@ -2951,7 +2947,7 @@ async function apply(ctx, config) {
2951
2947
  registerClaudeProjectionRoute(webCtx, sidecar, (sessionId) => {
2952
2948
  const agent = webCtx.agents.get(sessionId);
2953
2949
  return agent !== void 0 && webCtx.agentPresets.composedPreset(agent.ctx) === "claude";
2954
- });
2950
+ }, (sessionId) => commandCatalogs.get(sessionId) ?? []);
2955
2951
  });
2956
2952
  }
2957
2953
  //#endregion