@norman-else/dsh-claude 0.1.10 → 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/client.js +289 -15
- package/lib/client.js.map +1 -1
- package/lib/index.d.mts +13 -8
- package/lib/index.mjs +24 -25
- package/lib/index.mjs.map +1 -1
- package/lib/{presenters-C8Yx_rNY.mjs → presenters-CtgkpzZo.mjs} +10 -57
- package/lib/presenters-CtgkpzZo.mjs.map +1 -0
- package/lib/preset-route.mjs +2 -5
- package/lib/preset-route.mjs.map +1 -1
- package/package.json +4 -1
- package/lib/presenters-C8Yx_rNY.mjs.map +0 -1
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 {
|
|
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
|
|
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
|
|
15
|
-
* `commands` injected.
|
|
16
|
-
*
|
|
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
|
|
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";
|
|
@@ -1345,6 +1345,7 @@ var ClaudeSupervisor = class {
|
|
|
1345
1345
|
}
|
|
1346
1346
|
async #handleMessage(entry, message) {
|
|
1347
1347
|
if (message.kind === "init") {
|
|
1348
|
+
const firstInitialization = !entry.initialized;
|
|
1348
1349
|
if (entry.expectedResume !== void 0 && message.sessionId !== entry.expectedResume) throw new ClaudeProtocolError(`Claude Code resumed unexpected session ${message.sessionId}; expected ${entry.expectedResume}`);
|
|
1349
1350
|
if (message.cwd !== entry.cwd) throw new ClaudeProtocolError(`Claude Code initialized in unexpected cwd ${message.cwd}; expected ${entry.cwd}`);
|
|
1350
1351
|
if (entry.initTimer !== void 0) {
|
|
@@ -1355,7 +1356,7 @@ var ClaudeSupervisor = class {
|
|
|
1355
1356
|
entry.claudeSessionId = message.sessionId;
|
|
1356
1357
|
entry.state = entry.active === void 0 ? "idle" : "running";
|
|
1357
1358
|
for (const waiter of entry.initWaiters.splice(0)) waiter(void 0);
|
|
1358
|
-
if (entry.tasks.size > 0) {
|
|
1359
|
+
if (firstInitialization && entry.tasks.size > 0) {
|
|
1359
1360
|
entry.tasks.clear();
|
|
1360
1361
|
await this.#flushTasksSnapshot(entry);
|
|
1361
1362
|
}
|
|
@@ -2258,7 +2259,7 @@ function sessionIdFromUrl(rawUrl) {
|
|
|
2258
2259
|
}
|
|
2259
2260
|
}
|
|
2260
2261
|
/** Register the browser-readable, credential-free sidecar projection endpoint. */
|
|
2261
|
-
function registerClaudeProjectionRoute(ctx, sidecar, ownsSession) {
|
|
2262
|
+
function registerClaudeProjectionRoute(ctx, sidecar, ownsSession, commandsForSession = () => []) {
|
|
2262
2263
|
ctx.effect(() => ctx.webServer.register({
|
|
2263
2264
|
kind: "prefix",
|
|
2264
2265
|
path: CLAUDE_PROJECTION_PATH,
|
|
@@ -2273,6 +2274,7 @@ function registerClaudeProjectionRoute(ctx, sidecar, ownsSession) {
|
|
|
2273
2274
|
schemaVersion: projection.schemaVersion,
|
|
2274
2275
|
revision: projection.revision,
|
|
2275
2276
|
owned: ownsSession(sessionId),
|
|
2277
|
+
commands: commandsForSession(sessionId),
|
|
2276
2278
|
activities: projection.activities,
|
|
2277
2279
|
...projection.contextUsage === void 0 ? {} : { contextUsage: projection.contextUsage },
|
|
2278
2280
|
...projection.tasks === void 0 ? {} : { tasks: projection.tasks }
|
|
@@ -2504,14 +2506,15 @@ async function updatePlugin(deps = {}) {
|
|
|
2504
2506
|
throw new Error(`DSH plugin update failed (${outcome.exitCode ?? outcome.signal ?? "unknown exit"}): ${safeMessage(detail)}`);
|
|
2505
2507
|
}
|
|
2506
2508
|
await verifyInstalledVersion(installation, latest);
|
|
2509
|
+
if (deps.requestRestart !== void 0) setTimeout(() => deps.requestRestart?.(), 100).unref?.();
|
|
2507
2510
|
return {
|
|
2508
2511
|
currentVersion: latest,
|
|
2509
2512
|
latestVersion: latest,
|
|
2510
2513
|
source: "registry",
|
|
2511
2514
|
state: "current",
|
|
2512
2515
|
canUpdate: false,
|
|
2513
|
-
restartRequired:
|
|
2514
|
-
message: "Update installed; restart DSH Desktop to load it"
|
|
2516
|
+
restartRequired: deps.requestRestart === void 0,
|
|
2517
|
+
message: deps.requestRestart === void 0 ? "Update installed; restart DSH Desktop to load it" : "Update installed; DSH Desktop is restarting to load it"
|
|
2515
2518
|
};
|
|
2516
2519
|
}
|
|
2517
2520
|
function registerClaudeUpdateRoutes(ctx, runtime, deps = {}) {
|
|
@@ -2754,7 +2757,7 @@ const CATALOG_RETRY_MS = 5e3;
|
|
|
2754
2757
|
const SCOPE_RETRY_MS = 500;
|
|
2755
2758
|
const MAX_CATALOG_RETRIES = 3;
|
|
2756
2759
|
const MAX_SCOPE_RETRIES = 24;
|
|
2757
|
-
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)) {
|
|
2758
2761
|
if (ctx.agentPresets.composedPreset(agent.ctx) !== "claude") return void 0;
|
|
2759
2762
|
let stopped = false;
|
|
2760
2763
|
let pending = Promise.resolve();
|
|
@@ -2765,19 +2768,7 @@ function mountClaudeMetadata(ctx, supervisor, agent, model, sidecar, resolveComm
|
|
|
2765
2768
|
commandScope = scoped;
|
|
2766
2769
|
return scoped;
|
|
2767
2770
|
};
|
|
2768
|
-
const
|
|
2769
|
-
list: () => scopedCommands().list(agent),
|
|
2770
|
-
register: (definition) => scopedCommands().register(definition),
|
|
2771
|
-
forward: (line) => {
|
|
2772
|
-
agent.followup(createUserMessage({
|
|
2773
|
-
content: [{
|
|
2774
|
-
type: "text",
|
|
2775
|
-
text: line
|
|
2776
|
-
}],
|
|
2777
|
-
source: { kind: "user" }
|
|
2778
|
-
}));
|
|
2779
|
-
}
|
|
2780
|
-
});
|
|
2771
|
+
const commandTarget = { list: () => scopedCommands().list(agent) };
|
|
2781
2772
|
const warn = (area, error) => {
|
|
2782
2773
|
ctx.logger.warn(`dsh-claude: ${area} refresh failed for ${String(agent.id)}: ${error instanceof Error ? error.message : String(error)}`);
|
|
2783
2774
|
};
|
|
@@ -2819,7 +2810,9 @@ function mountClaudeMetadata(ctx, supervisor, agent, model, sidecar, resolveComm
|
|
|
2819
2810
|
}
|
|
2820
2811
|
if (stopped || catalog === void 0) return;
|
|
2821
2812
|
try {
|
|
2822
|
-
|
|
2813
|
+
const commands = projectClaudeCommands(catalog, commandTarget);
|
|
2814
|
+
publishCommands(commands);
|
|
2815
|
+
diagnostic.registered = commands.map((view) => view.publicName);
|
|
2823
2816
|
if (!stopped) scopeRetries = 0;
|
|
2824
2817
|
} catch (error) {
|
|
2825
2818
|
diagnostic.lastError = error instanceof Error ? error.message : String(error);
|
|
@@ -2845,10 +2838,10 @@ function mountClaudeMetadata(ctx, supervisor, agent, model, sidecar, resolveComm
|
|
|
2845
2838
|
refresh();
|
|
2846
2839
|
return async () => {
|
|
2847
2840
|
stopped = true;
|
|
2841
|
+
publishCommands([]);
|
|
2848
2842
|
if (retryTimer !== void 0) clearTimeout(retryTimer);
|
|
2849
2843
|
stopStatus();
|
|
2850
2844
|
await pending;
|
|
2851
|
-
bridge.dispose();
|
|
2852
2845
|
};
|
|
2853
2846
|
}, "dsh-claude: agent metadata bridge");
|
|
2854
2847
|
}
|
|
@@ -2870,6 +2863,7 @@ async function apply(ctx, config) {
|
|
|
2870
2863
|
maxProcesses: config.maxProcesses ?? 4
|
|
2871
2864
|
};
|
|
2872
2865
|
const sidecar = new ClaudeSidecarRepository();
|
|
2866
|
+
const commandCatalogs = /* @__PURE__ */ new Map();
|
|
2873
2867
|
const supervisor = new ClaudeSupervisor({
|
|
2874
2868
|
runtime: ctx.subprocess,
|
|
2875
2869
|
approval: ctx.approval,
|
|
@@ -2889,7 +2883,11 @@ async function apply(ctx, config) {
|
|
|
2889
2883
|
const MOUNT_RETRY_LIMIT = 50;
|
|
2890
2884
|
const mount = (agent) => {
|
|
2891
2885
|
if (mounted.has(agent)) return;
|
|
2892
|
-
const
|
|
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
|
+
});
|
|
2893
2891
|
if (dispose !== void 0) mounted.set(agent, dispose);
|
|
2894
2892
|
pending.delete(agent);
|
|
2895
2893
|
};
|
|
@@ -2943,12 +2941,13 @@ async function apply(ctx, config) {
|
|
|
2943
2941
|
ctx.effect(() => () => supervisor.dispose(), "dsh-claude: process supervisor");
|
|
2944
2942
|
ctx.inject(["webServer"], (webCtx) => {
|
|
2945
2943
|
registerClaudeDoctorRoutes(webCtx, webCtx.subprocess, supervisor, supervisorConfig, resolutionError);
|
|
2946
|
-
|
|
2944
|
+
const desktopActions = webCtx.get("desktopActions");
|
|
2945
|
+
registerClaudeUpdateRoutes(webCtx, webCtx.subprocess, { ...typeof desktopActions?.requestRestart === "function" ? { requestRestart: desktopActions.requestRestart.bind(desktopActions) } : {} });
|
|
2947
2946
|
registerClaudeGlobalSettingsRoute(webCtx);
|
|
2948
2947
|
registerClaudeProjectionRoute(webCtx, sidecar, (sessionId) => {
|
|
2949
2948
|
const agent = webCtx.agents.get(sessionId);
|
|
2950
2949
|
return agent !== void 0 && webCtx.agentPresets.composedPreset(agent.ctx) === "claude";
|
|
2951
|
-
});
|
|
2950
|
+
}, (sessionId) => commandCatalogs.get(sessionId) ?? []);
|
|
2952
2951
|
});
|
|
2953
2952
|
}
|
|
2954
2953
|
//#endregion
|