@duckmind/dm-windows-x64 0.63.4 → 0.63.9
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/dm.exe +0 -0
- package/extensions/.dm-extensions.json +236 -13
- package/extensions/dm-context/package.json +1 -1
- package/extensions/dm-context/skills/context-management/SKILL.md +173 -223
- package/extensions/dm-context/skills/context-management/references/development-and-troubleshooting.md +75 -0
- package/extensions/dm-context/skills/context-management/references/interleaved-async-work.md +143 -0
- package/extensions/dm-context/skills/context-management/references/planning-and-execution.md +81 -0
- package/extensions/dm-context/skills/context-management/references/repeated-items-and-batch-work.md +69 -0
- package/extensions/dm-context/skills/context-management/references/retry-branch-and-pivot.md +80 -0
- package/extensions/dm-context/skills/context-management/references/search-research-and-reading.md +103 -0
- package/extensions/dm-context/skills/context-management/references/task-switching-and-cleanup.md +73 -0
- package/extensions/dm-context/src/context.js +3 -2
- package/extensions/dm-context/src/index.js +168 -84
- package/extensions/dm-mcp-adapter/OAUTH.md +3 -0
- package/extensions/dm-mcp-adapter/THIRD_PARTY_NOTICES.md +4 -0
- package/extensions/dm-mcp-adapter/abort.js +35 -0
- package/extensions/dm-mcp-adapter/agent-dir.js +45 -0
- package/extensions/dm-mcp-adapter/agent-plugin-loader.js +349 -0
- package/extensions/dm-mcp-adapter/app-bridge.bundle.js +5843 -0
- package/extensions/dm-mcp-adapter/cli.js +354 -0
- package/extensions/dm-mcp-adapter/commands.js +619 -0
- package/extensions/dm-mcp-adapter/config.js +1060 -0
- package/extensions/dm-mcp-adapter/consent-manager.js +60 -0
- package/extensions/dm-mcp-adapter/direct-tools.js +544 -0
- package/extensions/dm-mcp-adapter/dist/agent-dir.js +45 -0
- package/extensions/dm-mcp-adapter/dist/agent-plugin-loader.js +349 -0
- package/extensions/dm-mcp-adapter/dist/config.js +1060 -0
- package/extensions/dm-mcp-adapter/dist/mcp-bearer-store.js +311 -0
- package/extensions/dm-mcp-adapter/dist/metadata-cache.js +285 -0
- package/extensions/dm-mcp-adapter/dist/package-mcp-loader.js +144 -0
- package/extensions/dm-mcp-adapter/dist/resource-tools.js +7 -0
- package/extensions/dm-mcp-adapter/dist/types.js +247 -0
- package/extensions/dm-mcp-adapter/dist/ui-app-bridge-helpers.js +36 -0
- package/extensions/dm-mcp-adapter/dist/ui-stream-types.js +58 -0
- package/extensions/dm-mcp-adapter/dist/ui-tool-visibility.js +26 -0
- package/extensions/dm-mcp-adapter/dist/utils.js +307 -0
- package/extensions/dm-mcp-adapter/elicitation-handler.js +306 -0
- package/extensions/dm-mcp-adapter/error-signal.js +16 -0
- package/extensions/dm-mcp-adapter/errors.js +225 -0
- package/extensions/dm-mcp-adapter/failure-backoff.js +19 -0
- package/extensions/dm-mcp-adapter/glimpse-ui.js +61 -0
- package/extensions/dm-mcp-adapter/host-html-template.js +464 -0
- package/extensions/dm-mcp-adapter/index.js +1079 -0
- package/extensions/dm-mcp-adapter/init.js +624 -0
- package/extensions/dm-mcp-adapter/json-schema-validator.js +53 -0
- package/extensions/dm-mcp-adapter/lifecycle.js +385 -0
- package/extensions/dm-mcp-adapter/logger.js +115 -0
- package/extensions/dm-mcp-adapter/mcp-auth-flow.js +824 -0
- package/extensions/dm-mcp-adapter/mcp-auth.js +732 -0
- package/extensions/dm-mcp-adapter/mcp-bearer-store.js +311 -0
- package/extensions/dm-mcp-adapter/mcp-callback-server.js +388 -0
- package/extensions/dm-mcp-adapter/mcp-code.js +291 -0
- package/extensions/dm-mcp-adapter/mcp-keyring-helper.cjs +88 -0
- package/extensions/dm-mcp-adapter/mcp-oauth-provider.js +490 -0
- package/extensions/dm-mcp-adapter/mcp-output-guard.js +386 -0
- package/extensions/dm-mcp-adapter/mcp-panel.js +951 -0
- package/extensions/dm-mcp-adapter/mcp-probe.js +151 -0
- package/extensions/dm-mcp-adapter/mcp-references.js +263 -0
- package/extensions/dm-mcp-adapter/mcp-script-worker.mjs +126 -0
- package/extensions/dm-mcp-adapter/mcp-setup-panel.js +578 -0
- package/extensions/dm-mcp-adapter/mcp-status.js +80 -0
- package/extensions/dm-mcp-adapter/mcp-trace.js +215 -0
- package/extensions/dm-mcp-adapter/metadata-cache.js +292 -0
- package/extensions/dm-mcp-adapter/namespace-tools.js +155 -0
- package/extensions/dm-mcp-adapter/npx-resolver.js +465 -0
- package/extensions/dm-mcp-adapter/oauth-handler.js +17 -0
- package/extensions/dm-mcp-adapter/oauth.js +17 -0
- package/extensions/dm-mcp-adapter/onboarding-state.js +62 -0
- package/extensions/dm-mcp-adapter/package-mcp-loader.js +144 -0
- package/extensions/dm-mcp-adapter/package.json +68 -0
- package/extensions/dm-mcp-adapter/panel-keys.js +26 -0
- package/extensions/dm-mcp-adapter/prompts.js +258 -0
- package/extensions/dm-mcp-adapter/proxy-modes.js +1336 -0
- package/extensions/dm-mcp-adapter/request-headers-command.js +293 -0
- package/extensions/dm-mcp-adapter/resource-tools.js +7 -0
- package/extensions/dm-mcp-adapter/runtime-owner.js +79 -0
- package/extensions/dm-mcp-adapter/sampling-handler.js +222 -0
- package/extensions/dm-mcp-adapter/sandbox-proxy-template.js +190 -0
- package/extensions/dm-mcp-adapter/search-ranking.js +198 -0
- package/extensions/dm-mcp-adapter/server-manager.js +1258 -0
- package/extensions/dm-mcp-adapter/session-recovery.js +82 -0
- package/extensions/dm-mcp-adapter/skills/mcp-scripting/SKILL.md +39 -0
- package/extensions/dm-mcp-adapter/state.js +0 -0
- package/extensions/dm-mcp-adapter/test-runner.mjs +18 -0
- package/extensions/dm-mcp-adapter/tool-approval.js +151 -0
- package/extensions/dm-mcp-adapter/tool-metadata.js +247 -0
- package/extensions/dm-mcp-adapter/tool-registrar.js +212 -0
- package/extensions/dm-mcp-adapter/tool-result-renderer.js +355 -0
- package/extensions/dm-mcp-adapter/ts-shape.js +157 -0
- package/extensions/dm-mcp-adapter/types.js +264 -0
- package/extensions/dm-mcp-adapter/ui-app-bridge-helpers.js +36 -0
- package/extensions/dm-mcp-adapter/ui-resource-handler.js +209 -0
- package/extensions/dm-mcp-adapter/ui-server.js +815 -0
- package/extensions/dm-mcp-adapter/ui-session.js +455 -0
- package/extensions/dm-mcp-adapter/ui-stream-types.js +58 -0
- package/extensions/dm-mcp-adapter/ui-tool-visibility.js +26 -0
- package/extensions/dm-mcp-adapter/unix-socket-transport.js +83 -0
- package/extensions/dm-mcp-adapter/utils.js +307 -0
- package/extensions/dm-skills-manager/THIRD_PARTY_NOTICES.md +27 -0
- package/extensions/dm-skills-manager/extensions/skills-manager/components.js +265 -0
- package/extensions/dm-skills-manager/extensions/skills-manager/constants.js +31 -0
- package/extensions/dm-skills-manager/extensions/skills-manager/creation-fallback.js +20 -0
- package/extensions/dm-skills-manager/extensions/skills-manager/creation.js +145 -0
- package/extensions/dm-skills-manager/extensions/skills-manager/dialog.js +738 -0
- package/extensions/dm-skills-manager/extensions/skills-manager/dm-ai-compat.js +15 -0
- package/extensions/dm-skills-manager/extensions/skills-manager/format.js +125 -0
- package/extensions/dm-skills-manager/extensions/skills-manager/glyphs.js +142 -0
- package/extensions/dm-skills-manager/extensions/skills-manager/layout.js +93 -0
- package/extensions/dm-skills-manager/extensions/skills-manager/paths.js +76 -0
- package/extensions/dm-skills-manager/extensions/skills-manager/registry.js +95 -0
- package/extensions/dm-skills-manager/extensions/skills-manager/settings.js +93 -0
- package/extensions/dm-skills-manager/extensions/skills-manager/startup.js +32 -0
- package/extensions/dm-skills-manager/extensions/skills-manager/toggle.js +54 -0
- package/extensions/dm-skills-manager/extensions/skills-manager/types.js +14 -0
- package/extensions/dm-skills-manager/extensions/skills-manager/ui.js +121 -0
- package/extensions/dm-skills-manager/extensions/skills-manager.js +111 -0
- package/extensions/dm-skills-manager/package.json +121 -0
- package/package.json +13 -1
- package/extensions/dm-localllm-provider/detect.test.js +0 -1051
- package/extensions/dm-localllm-provider/index.test.js +0 -149
- package/extensions/dm-localllm-provider/keychain.test.js +0 -61
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { formatModelLine, modelIdsChanged, modelsHeading, normalizeBaseUrl } from "./index.js";
|
|
3
|
-
describe("normalizeBaseUrl", () => {
|
|
4
|
-
it("appends /v1 when missing", () => {
|
|
5
|
-
expect(normalizeBaseUrl("http://localhost:8000")).toBe("http://localhost:8000/v1");
|
|
6
|
-
});
|
|
7
|
-
it("leaves an existing /v1 suffix alone", () => {
|
|
8
|
-
expect(normalizeBaseUrl("http://localhost:8000/v1")).toBe("http://localhost:8000/v1");
|
|
9
|
-
});
|
|
10
|
-
it("strips trailing slashes before checking the suffix", () => {
|
|
11
|
-
expect(normalizeBaseUrl("http://localhost:8000/v1/")).toBe("http://localhost:8000/v1");
|
|
12
|
-
expect(normalizeBaseUrl("http://localhost:8000/")).toBe("http://localhost:8000/v1");
|
|
13
|
-
});
|
|
14
|
-
it("defaults to http:// for a bare host:port with no scheme", () => {
|
|
15
|
-
expect(normalizeBaseUrl("localhost:11434")).toBe("http://localhost:11434/v1");
|
|
16
|
-
expect(normalizeBaseUrl("192.168.1.50:8000")).toBe("http://192.168.1.50:8000/v1");
|
|
17
|
-
});
|
|
18
|
-
it("preserves an explicit https:// scheme", () => {
|
|
19
|
-
expect(normalizeBaseUrl("https://my.server.com")).toBe("https://my.server.com/v1");
|
|
20
|
-
});
|
|
21
|
-
it("trims surrounding whitespace", () => {
|
|
22
|
-
expect(normalizeBaseUrl(" localhost:11434 ")).toBe("http://localhost:11434/v1");
|
|
23
|
-
});
|
|
24
|
-
});
|
|
25
|
-
describe("formatModelLine", () => {
|
|
26
|
-
it("formats context window and max tokens in k, with no capability tags", () => {
|
|
27
|
-
expect(formatModelLine({
|
|
28
|
-
id: "m1",
|
|
29
|
-
name: "some-model",
|
|
30
|
-
contextWindow: 65536,
|
|
31
|
-
maxTokens: 8192,
|
|
32
|
-
reasoning: false,
|
|
33
|
-
input: ["text"]
|
|
34
|
-
})).toBe(" • some-model (ctx 64k, max 8k)");
|
|
35
|
-
});
|
|
36
|
-
it("appends reasoning and vision tags when present", () => {
|
|
37
|
-
expect(formatModelLine({
|
|
38
|
-
id: "m1",
|
|
39
|
-
name: "vision-model",
|
|
40
|
-
contextWindow: 65536,
|
|
41
|
-
maxTokens: 8192,
|
|
42
|
-
reasoning: true,
|
|
43
|
-
input: ["text", "image"]
|
|
44
|
-
})).toBe(" • vision-model (ctx 64k, max 8k, reasoning, vision)");
|
|
45
|
-
});
|
|
46
|
-
it("shows sub-1024 windows without a k suffix", () => {
|
|
47
|
-
expect(formatModelLine({
|
|
48
|
-
id: "m1",
|
|
49
|
-
name: "tiny",
|
|
50
|
-
contextWindow: 512,
|
|
51
|
-
maxTokens: 256,
|
|
52
|
-
reasoning: false,
|
|
53
|
-
input: ["text"]
|
|
54
|
-
})).toBe(" • tiny (ctx 512, max 256)");
|
|
55
|
-
});
|
|
56
|
-
it("prefixes a checkmark when loaded is true", () => {
|
|
57
|
-
expect(formatModelLine({
|
|
58
|
-
id: "m1",
|
|
59
|
-
name: "m",
|
|
60
|
-
contextWindow: 4096,
|
|
61
|
-
maxTokens: 2048,
|
|
62
|
-
reasoning: false,
|
|
63
|
-
input: ["text"],
|
|
64
|
-
loaded: true
|
|
65
|
-
})).toBe(" • ✓ m (ctx 4k, max 2k)");
|
|
66
|
-
});
|
|
67
|
-
it("prefixes a hollow circle when loaded is false", () => {
|
|
68
|
-
expect(formatModelLine({
|
|
69
|
-
id: "m1",
|
|
70
|
-
name: "m",
|
|
71
|
-
contextWindow: 4096,
|
|
72
|
-
maxTokens: 2048,
|
|
73
|
-
reasoning: false,
|
|
74
|
-
input: ["text"],
|
|
75
|
-
loaded: false
|
|
76
|
-
})).toBe(" • ○ m (ctx 4k, max 2k)");
|
|
77
|
-
});
|
|
78
|
-
it("omits the loaded prefix entirely when loaded is unknown", () => {
|
|
79
|
-
expect(formatModelLine({
|
|
80
|
-
id: "m1",
|
|
81
|
-
name: "m",
|
|
82
|
-
contextWindow: 4096,
|
|
83
|
-
maxTokens: 2048,
|
|
84
|
-
reasoning: false,
|
|
85
|
-
input: ["text"]
|
|
86
|
-
})).toBe(" • m (ctx 4k, max 2k)");
|
|
87
|
-
});
|
|
88
|
-
it("shows size and quantization when present, in order before capability tags", () => {
|
|
89
|
-
expect(formatModelLine({
|
|
90
|
-
id: "m1",
|
|
91
|
-
name: "m",
|
|
92
|
-
contextWindow: 4096,
|
|
93
|
-
maxTokens: 2048,
|
|
94
|
-
reasoning: true,
|
|
95
|
-
input: ["text", "image"],
|
|
96
|
-
sizeBytes: 4912898304,
|
|
97
|
-
quantization: "Q4_K_M"
|
|
98
|
-
})).toBe(" • m (ctx 4k, max 2k, 4.6G, Q4_K_M, reasoning, vision)");
|
|
99
|
-
});
|
|
100
|
-
});
|
|
101
|
-
describe("modelIdsChanged", () => {
|
|
102
|
-
const baseModel = {
|
|
103
|
-
id: "m1",
|
|
104
|
-
name: "m1",
|
|
105
|
-
contextWindow: 4096,
|
|
106
|
-
maxTokens: 2048,
|
|
107
|
-
reasoning: false,
|
|
108
|
-
input: ["text"]
|
|
109
|
-
};
|
|
110
|
-
it("is false when the same single model is refreshed with new metadata", () => {
|
|
111
|
-
expect(modelIdsChanged([baseModel], [{ ...baseModel, contextWindow: 8192 }])).toBe(false);
|
|
112
|
-
});
|
|
113
|
-
it("is false when the same set of models comes back in a different order", () => {
|
|
114
|
-
const a = { ...baseModel, id: "a" };
|
|
115
|
-
const b = { ...baseModel, id: "b" };
|
|
116
|
-
expect(modelIdsChanged([a, b], [b, a])).toBe(false);
|
|
117
|
-
});
|
|
118
|
-
it("is true when the model count changes", () => {
|
|
119
|
-
const a = { ...baseModel, id: "a" };
|
|
120
|
-
const b = { ...baseModel, id: "b" };
|
|
121
|
-
expect(modelIdsChanged([a], [a, b])).toBe(true);
|
|
122
|
-
});
|
|
123
|
-
it("is true when a same-count refresh swaps in a different model id", () => {
|
|
124
|
-
const a = { ...baseModel, id: "a" };
|
|
125
|
-
const c = { ...baseModel, id: "c" };
|
|
126
|
-
expect(modelIdsChanged([a], [c])).toBe(true);
|
|
127
|
-
});
|
|
128
|
-
it("is false for two empty lists", () => {
|
|
129
|
-
expect(modelIdsChanged([], [])).toBe(false);
|
|
130
|
-
});
|
|
131
|
-
});
|
|
132
|
-
describe("modelsHeading", () => {
|
|
133
|
-
const baseModel = {
|
|
134
|
-
id: "m1",
|
|
135
|
-
name: "m1",
|
|
136
|
-
contextWindow: 4096,
|
|
137
|
-
maxTokens: 2048,
|
|
138
|
-
reasoning: false,
|
|
139
|
-
input: ["text"]
|
|
140
|
-
};
|
|
141
|
-
it("adds the loaded-state legend when at least one model reports it", () => {
|
|
142
|
-
expect(modelsHeading([{ ...baseModel, loaded: true }])).toBe("Models: (✓ = loaded in memory, ○ = will be loaded on first message)");
|
|
143
|
-
expect(modelsHeading([{ ...baseModel }, { ...baseModel, loaded: false }])).toBe("Models: (✓ = loaded in memory, ○ = will be loaded on first message)");
|
|
144
|
-
});
|
|
145
|
-
it("omits the legend when no model reports loaded state", () => {
|
|
146
|
-
expect(modelsHeading([baseModel])).toBe("Models:");
|
|
147
|
-
expect(modelsHeading([])).toBe("Models:");
|
|
148
|
-
});
|
|
149
|
-
});
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
2
|
-
const execFileCalls = [];
|
|
3
|
-
let nextShouldFail = false;
|
|
4
|
-
vi.mock("node:child_process", () => ({
|
|
5
|
-
execFile: (file, args, cb) => {
|
|
6
|
-
execFileCalls.push({ file, args });
|
|
7
|
-
if (nextShouldFail) {
|
|
8
|
-
cb(new Error("no such keychain item"));
|
|
9
|
-
} else {
|
|
10
|
-
cb(null, "", "");
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
}));
|
|
14
|
-
const { isDirectApiKey, keychainCommand, storeInKeychain, deleteFromKeychain } = await import("./keychain.js");
|
|
15
|
-
afterEach(() => {
|
|
16
|
-
execFileCalls.length = 0;
|
|
17
|
-
nextShouldFail = false;
|
|
18
|
-
});
|
|
19
|
-
describe("isDirectApiKey", () => {
|
|
20
|
-
it("treats a plain string as a direct key", () => {
|
|
21
|
-
expect(isDirectApiKey("sk-abc123")).toBe(true);
|
|
22
|
-
});
|
|
23
|
-
it("rejects empty, !command, and $ENV_VAR forms", () => {
|
|
24
|
-
expect(isDirectApiKey("")).toBe(false);
|
|
25
|
-
expect(isDirectApiKey("!security find-generic-password -w")).toBe(false);
|
|
26
|
-
expect(isDirectApiKey("$MY_API_KEY")).toBe(false);
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
describe("keychainCommand", () => {
|
|
30
|
-
it("formats a !security find-generic-password command for the given account", () => {
|
|
31
|
-
expect(keychainCommand("abc123")).toBe("!security find-generic-password -s 'dm-localllm-provider' -a 'abc123' -w");
|
|
32
|
-
});
|
|
33
|
-
});
|
|
34
|
-
describe("storeInKeychain", () => {
|
|
35
|
-
it("deletes any existing entry, then adds the key as a single argv element", async () => {
|
|
36
|
-
await storeInKeychain("abc123", "sk-with-a-'-quote-and-$(dangerous)-chars");
|
|
37
|
-
expect(execFileCalls).toHaveLength(2);
|
|
38
|
-
expect(execFileCalls[0]).toEqual({
|
|
39
|
-
file: "security",
|
|
40
|
-
args: ["delete-generic-password", "-s", "dm-localllm-provider", "-a", "abc123"]
|
|
41
|
-
});
|
|
42
|
-
expect(execFileCalls[1]).toEqual({
|
|
43
|
-
file: "security",
|
|
44
|
-
args: [
|
|
45
|
-
"add-generic-password",
|
|
46
|
-
"-s",
|
|
47
|
-
"dm-localllm-provider",
|
|
48
|
-
"-a",
|
|
49
|
-
"abc123",
|
|
50
|
-
"-w",
|
|
51
|
-
"sk-with-a-'-quote-and-$(dangerous)-chars"
|
|
52
|
-
]
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
describe("deleteFromKeychain", () => {
|
|
57
|
-
it("swallows errors when there is no existing entry", async () => {
|
|
58
|
-
nextShouldFail = true;
|
|
59
|
-
await expect(deleteFromKeychain("abc123")).resolves.toBeUndefined();
|
|
60
|
-
});
|
|
61
|
-
});
|